diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..99000a4ee4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,14 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Please provide a code example or even better a test to reproduce the bug. diff --git a/.github/ISSUE_TEMPLATE/other-issue.md b/.github/ISSUE_TEMPLATE/other-issue.md new file mode 100644 index 0000000000..774bf32309 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/other-issue.md @@ -0,0 +1,10 @@ +--- +name: Other issue +about: Generic issue +title: '' +labels: '' +assignees: '' + +--- + +If you have a general question or seeking advice how to use something please create a new topic in our GitHub discussions forum: https://github.com/graphql-java/graphql-java/discussions. Thanks. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..01acd987aa --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,16 @@ +# GitHub Copilot Instructions + +## Code Style and Conventions + +- Don't use fully qualified names for Java, Kotlin, or Groovy. Instead, add imports. +- Don't use wildcard imports. Please import items one by one instead. You can disable wildcard imports in your IDE +- Follow the code style defined in `graphql-java-code-style.xml`. + +## Pull Request Review Guidelines + +### Testing +- If you add new functionality, or correct a bug, you must also write a test so we can ensure your code works in the future +- If your pull request includes a performance improvement, please check in a JMH test to verify this. We'll then run a test on our isolated performance environment to verify the results +- +### Breaking Changes +- Flag any breaking changes in public APIs so we can call this out in documentation diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..10ef831183 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/commit_performance_result.yml b/.github/workflows/commit_performance_result.yml new file mode 100644 index 0000000000..1f645574a2 --- /dev/null +++ b/.github/workflows/commit_performance_result.yml @@ -0,0 +1,39 @@ +name: Commit performance results into repo +on: + workflow_dispatch: + inputs: + sha: + description: 'the commit sha which was performance tested' + required: true + branch: + description: 'the branch which the results should be commited in' + required: false + default: 'master' + +permissions: + id-token: write # This is required for requesting the JWT + contents: write # This is required for pushing changes back to the repo +jobs: + commitPerformanceResults: + runs-on: ubuntu-latest + steps: + - uses: aws-actions/configure-aws-credentials@v5 + with: + role-to-assume: arn:aws:iam::637423498965:role/GitHubActionGrahQLJava + aws-region: "ap-southeast-2" + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.inputs.branch }} + - run: | + aws s3 cp s3://graphql-java-jmh-output/ ./performance-results --recursive --exclude "*" --include "*-${{ github.event.inputs.sha }}-jdk17.json" + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add performance-results/*-${{ github.event.inputs.sha }}-jdk17.json + if [ -z "$(git status --porcelain)" ]; then + echo "Performance results already present" + exit 0 + fi + git pull + git commit -m "Add performance results for commit ${{ github.event.inputs.sha }}" + git push + diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml new file mode 100644 index 0000000000..a466243107 --- /dev/null +++ b/.github/workflows/master.yml @@ -0,0 +1,52 @@ +name: Master Build and Publish +# For master push: Builds and publishes the development version to maven +on: + push: + branches: + - master +permissions: # For test summary bot + checks: write +jobs: + buildAndTest: + runs-on: ubuntu-latest + strategy: + matrix: + gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17', 'test -x testWithJava11 -x testWithJava17' ] + steps: + - uses: actions/checkout@v6 + - uses: gradle/actions/wrapper-validation@v5 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'corretto' + - name: build and test + run: ./gradlew ${{matrix.gradle-argument}} --info --stacktrace + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2.21.0 + if: always() + with: + files: | + **/build/test-results/test/TEST-*.xml + **/build/test-results/testWithJava11/TEST-*.xml + **/build/test-results/testWithJava17/TEST-*.xml + publishToMavenCentral: + needs: buildAndTest + runs-on: ubuntu-latest + env: + MAVEN_CENTRAL_USER: ${{ secrets.MAVEN_CENTRAL_USER }} + MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + MAVEN_CENTRAL_USER_NEW: ${{ secrets.MAVEN_CENTRAL_USER_NEW }} + MAVEN_CENTRAL_PASSWORD_NEW: ${{ secrets.MAVEN_CENTRAL_PASSWORD_NEW }} + MAVEN_CENTRAL_PGP_KEY: ${{ secrets.MAVEN_CENTRAL_PGP_KEY }} + + steps: + - uses: actions/checkout@v6 + - uses: gradle/actions/wrapper-validation@v5 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'corretto' + - name: publishToMavenCentral + run: ./gradlew assemble && ./gradlew check -x test -x testng --info && ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -x check --info --stacktrace diff --git a/.github/workflows/package.json b/.github/workflows/package.json new file mode 100644 index 0000000000..71ef804476 --- /dev/null +++ b/.github/workflows/package.json @@ -0,0 +1,14 @@ +{ + "name": "workflow-testrunner-tasksenqueuer", + "private": true, + "engines": { + "node": ">=12.0.0" + }, + "files": [ + "*.js" + ], + "dependencies": { + "@google-cloud/tasks": "^3.0.0", + "uuid": "^8.0.0" + } +} diff --git a/.github/workflows/publish_commit.yml b/.github/workflows/publish_commit.yml new file mode 100644 index 0000000000..7cabc69f30 --- /dev/null +++ b/.github/workflows/publish_commit.yml @@ -0,0 +1,22 @@ +name: Publish Commit SHA for performance testing +on: + pull_request_target: + types: + - closed + branches: + - master + paths-ignore: + - 'performance-results/**' +permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout +jobs: + publishCommit: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: aws-actions/configure-aws-credentials@v5 + with: + role-to-assume: arn:aws:iam::637423498965:role/GitHubActionGrahQLJava + aws-region: "ap-southeast-2" + - run: aws sns publish --topic-arn "arn:aws:sns:ap-southeast-2:637423498965:graphql-java-commits.fifo" --message $GITHUB_SHA --message-group-id "graphql-java-commits" diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000000..9e4a427b36 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,41 @@ +name: Pull Request Build +# For pull requests: builds and test +on: + push: + branches: + - '!master' + pull_request: + branches: + - master + - 23.x + - 22.x + - 21.x + - 20.x + - 19.x +permissions: # For test comment bot + checks: write + pull-requests: write +jobs: + buildAndTest: + runs-on: ubuntu-latest + strategy: + matrix: + gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17', 'test -x testWithJava11 -x testWithJava17' ] + steps: + - uses: actions/checkout@v6 + - uses: gradle/actions/wrapper-validation@v5 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'corretto' + - name: build and test + run: ./gradlew ${{matrix.gradle-argument}} --info --stacktrace + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2.21.0 + if: always() + with: + files: | + **/build/test-results/test/TEST-*.xml + **/build/test-results/testWithJava11/TEST-*.xml + **/build/test-results/testWithJava17/TEST-*.xml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..8eb18b440b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Manual Release Build +# Release builds +on: + workflow_dispatch: + inputs: + version: + description: 'the version to be released' + required: true + +jobs: + buildAndPublish: + runs-on: ubuntu-latest + env: + MAVEN_CENTRAL_PGP_KEY: ${{ secrets.MAVEN_CENTRAL_PGP_KEY }} + MAVEN_CENTRAL_USER: ${{ secrets.MAVEN_CENTRAL_USER }} + MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + MAVEN_CENTRAL_USER_NEW: ${{ secrets.MAVEN_CENTRAL_USER_NEW }} + MAVEN_CENTRAL_PASSWORD_NEW: ${{ secrets.MAVEN_CENTRAL_PASSWORD_NEW }} + RELEASE_VERSION: ${{ github.event.inputs.version }} + + steps: + - uses: actions/checkout@v6 + - uses: gradle/actions/wrapper-validation@v5 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'corretto' + - name: build test and publish + run: ./gradlew assemble && ./gradlew check --info && ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -x check --info --stacktrace diff --git a/.github/workflows/stale-pr-issue.yml b/.github/workflows/stale-pr-issue.yml new file mode 100644 index 0000000000..f65cba3339 --- /dev/null +++ b/.github/workflows/stale-pr-issue.yml @@ -0,0 +1,47 @@ +# Mark inactive issues and PRs as stale +# GitHub action based on https://github.com/actions/stale + +name: 'Close stale issues and PRs' +on: + schedule: + # Execute every day + - cron: '0 0 * * *' + +permissions: + actions: write + issues: write + pull-requests: write + +jobs: + close-pending: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v10 + with: + # GLOBAL ------------------------------------------------------------ + # Exempt any PRs or issues already added to a milestone + exempt-all-milestones: true + # Days until issues or pull requests are labelled as stale + days-before-stale: 60 + + # ISSUES ------------------------------------------------------------ + # Issues will be closed after 90 days of inactive (60 to mark as stale + 30 to close) + days-before-issue-close: 30 + stale-issue-message: > + Hello, this issue has been inactive for 60 days, so we're marking it as stale. + If you would like to continue this discussion, please comment within the next 30 days or we'll close the issue. + close-issue-message: > + Hello, as this issue has been inactive for 90 days, we're closing the issue. + If you would like to resume the discussion, please create a new issue. + exempt-issue-labels: keep-open + + # PULL REQUESTS ----------------------------------------------------- + # PRs will be closed after 90 days of inactive (60 to mark as stale + 30 to close) + days-before-pr-close: 30 + stale-pr-message: > + Hello, this pull request has been inactive for 60 days, so we're marking it as stale. + If you would like to continue working on this pull request, please make an update within the next 30 days, or we'll close the pull request. + close-pr-message: > + Hello, as this pull request has been inactive for 90 days, we're closing this pull request. + We always welcome contributions, and if you would like to continue, please open a new pull request. + exempt-pr-labels: keep-open diff --git a/.gitignore b/.gitignore index b8b0f75b1f..dad8d9885c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,6 @@ docs/_build/ \.classpath \.project \.settings/ -/.nb-gradle/ \ No newline at end of file +/.nb-gradle/ +gen +.DS_Store \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5836473768..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -sudo: required -services: - - docker -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ -script: - - ./travis-build.sh - diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index cd9d3382b0..5b3d4cc7f8 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -44,7 +44,7 @@ incident. This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.3.0, available at -[http://contributor-covenant.org/version/1/3/0/][version] +[https://contributor-covenant.org/version/1/3/0/][version] -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/3/0/ +[homepage]: https://contributor-covenant.org +[version]: https://contributor-covenant.org/version/1/3/0/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7b6c85c5b2..fb2fb04c52 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,27 +1,27 @@ Thanks for contributing to graphql-java! -Please be sure that you read the [Code of Conduct](CODE_OF_CONDUCT.md) before contributing to this project -and please create a new Issue and discuss first what your are planing todo for bigger changes. +Please be sure that you read the [Code of Conduct](CODE_OF_CONDUCT.md) before contributing to this project and please +create a new Issue and discuss first what you are planning to do for larger changes. The overall goal of graphql-java is to have a correct implementation of the [GraphQL Spec](https://github.com/facebook/graphql/) in a production ready way. In order to achieve that we have a strong focus on maintainability and high test coverage: -- We expect new or modified unit test for every change (written in [Spock](http://spockframework.org/)). +- We expect new or modified unit test for every change (written in [Spock](https://spockframework.org/)). -- Your code should should be formatted with our IntelliJ [graphql-java-code-style](graphql-java-code-style.xml). +- Your code should be formatted with our IntelliJ [graphql-java-code-style](graphql-java-code-style.xml). -- We don't add a new dependency to graphql-java: dependency conflicts will make adaption of graphql-java harder for users, +- We don't add a new dependency to graphql-java: dependency conflicts will make adaption of graphql-java harder for users, therefore we avoid adding any new dependency. - graphql-java has a strict focus on executing a GraphQL request, this means JSON parsing, http communication, databases access etc is out of scope. -If you have any question please open a Issue. +If you have any question please consider asking in our [Discussions](https://github.com/graphql-java/graphql-java/discussions). For bug reports or specific code related topics create a new issue. + +Thanks! -Thanks! - diff --git a/README.md b/README.md index 4af6a03803..e49b468625 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,25 @@ -# graphql-java +# GraphQL Java -[![Join the chat at https://gitter.im/graphql-java/graphql-java](https://badges.gitter.im/graphql-java/graphql-java.svg)](https://gitter.im/graphql-java/graphql-java?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +Discuss and ask questions in our Discussions: https://github.com/graphql-java/graphql-java/discussions -![logo](https://avatars1.githubusercontent.com/u/14289921?s=200&v=4) +This is a [GraphQL](https://github.com/graphql/graphql-spec) Java implementation. -This is a [GraphQL](https://github.com/facebook/graphql) Java implementation. - - -[![Build Status](https://travis-ci.org/graphql-java/graphql-java.svg?branch=master)](https://travis-ci.org/graphql-java/graphql-java) -[![Latest Release](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/) -[![Latest Dev Build](https://api.bintray.com/packages/andimarek/graphql-java/graphql-java/images/download.svg)](https://bintray.com/andimarek/graphql-java/graphql-java/_latestVersion) +Latest build in Maven central: https://repo1.maven.org/maven2/com/graphql-java/graphql-java/ +[![Build](https://github.com/graphql-java/graphql-java/actions/workflows/master.yml/badge.svg)](https://github.com/graphql-java/graphql-java/actions/workflows/master.yml) +[![Latest Release](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java?versionPrefix=24.)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/) +[![Latest Snapshot](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java?label=maven-central%20snapshot&versionPrefix=0)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/) +[![MIT licensed](https://img.shields.io/badge/license-MIT-green)](https://github.com/graphql-java/graphql-java/blob/master/LICENSE.md) ### Documentation -For details how to use `graphql-java` please look at the documentation: http://graphql-java.readthedocs.io/ +The GraphQL Java book, from the maintainers: [GraphQL with Java and Spring](https://leanpub.com/graphql-java/) + +See our tutorial for beginners: [Getting started with GraphQL Java and Spring Boot](https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/) -There is also an [out-of-date](https://github.com/graphql-java/graphql-java/issues/934) tutorial here : https://www.howtographql.com/graphql-java/0-introduction/ +For further details, please see the documentation: https://www.graphql-java.com/documentation/getting-started + +If you're looking to learn more, we (the maintainers) have written a book! [GraphQL with Java and Spring](https://leanpub.com/graphql-java) includes everything you need to know to build a production ready GraphQL service. The book is available on [Leanpub](https://leanpub.com/graphql-java) and [Amazon](https://www.amazon.com/GraphQL-Java-Spring-Andreas-Marek-ebook/dp/B0C96ZYWPF/). Please take a look at our [list of releases](https://github.com/graphql-java/graphql-java/releases) if you want to learn more about new releases and the changelog. @@ -24,19 +27,11 @@ Please take a look at our [list of releases](https://github.com/graphql-java/gra Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this project (commenting or opening PR/Issues etc) you are agreeing to follow this conduct, so please -take the time to read it. - - -### Acknowledgment - -This implementation is based on the [js reference implementation](https://github.com/graphql/graphql-js). -For example the StarWarSchema and the tests (among a lot of other things) are simply adapted to the Java world. +take the time to read it. ### License -graphql-java is licensed under the MIT License. See [LICENSE](LICENSE.md) for details. - Copyright (c) 2015, Andreas Marek and [Contributors](https://github.com/graphql-java/graphql-java/graphs/contributors) -[graphql-js License](https://github.com/graphql/graphql-js/blob/master/LICENSE) - +### Powered by +[![IntelliJ IDEA logo](https://resources.jetbrains.com/storage/products/company/brand/logos/IntelliJ_IDEA.svg)](https://jb.gg/OpenSourceSupport) diff --git a/README.zh_cn.md b/README.zh_cn.md index 1396e1e4d9..23ab0db543 100644 --- a/README.zh_cn.md +++ b/README.zh_cn.md @@ -1,40 +1,28 @@ -# graphql-java +# GraphQL Java -[![Join the chat at https://gitter.im/graphql-java/graphql-java](https://badges.gitter.im/graphql-java/graphql-java.svg)](https://gitter.im/graphql-java/graphql-java?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +请在 Discussions 进行问题讨论和寻求帮助:https://github.com/graphql-java/graphql-java/discussions -![logo](https://avatars1.githubusercontent.com/u/14289921?s=200&v=4) -This is a [GraphQL](https://github.com/facebook/graphql) Java implementation. - +该组件是 [GraphQL 规范](https://github.com/graphql/graphql-spec) 的 Java 实现。 -[![Build Status](https://travis-ci.org/graphql-java/graphql-java.svg?branch=master)](https://travis-ci.org/graphql-java/graphql-java) -[![Latest Release](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/) -[![Latest Dev Build](https://api.bintray.com/packages/andimarek/graphql-java/graphql-java/images/download.svg)](https://bintray.com/andimarek/graphql-java/graphql-java/_latestVersion) +[![Build](https://github.com/graphql-java/graphql-java/actions/workflows/master.yml/badge.svg)](https://github.com/graphql-java/graphql-java/actions/workflows/master.yml) +[![Latest Release](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java?versionPrefix=24.)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/) +[![Latest Snapshot](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java?label=maven-central%20snapshot&versionPrefix=0)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/) +[![MIT licensed](https://img.shields.io/badge/license-MIT-green)](https://github.com/graphql-java/graphql-java/blob/master/LICENSE.md) +### 文档 -## 文档 +入门教程:[Getting started with GraphQL Java and Spring Boot](https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/) -关于 `graphql-java` 的详细使用说明,请阅读: http://graphql-java.readthedocs.io/ +更多细节请参考`graphql-java`官方文档: https://www.graphql-java.com/documentation/getting-started -这也是个很好的教程 : https://www.howtographql.com/graphql-java/0-introduction/ +我们写了一本书: [GraphQL with Java and Spring](https://leanpub.com/graphql-java) -在 [发行版本列表](https://github.com/graphql-java/graphql-java/releases) 中,你可以看到最新版本和变更日志. +如果您想了解新版本更多的信息和变更日志请参阅[ releases 列表](https://github.com/graphql-java/graphql-java/releases)。 -### 编码行为约定 +### 行为规范 -请注意,本项目基于 [Contributor Code of Conduct](CODE_OF_CONDUCT.md) 协议来发行。 -贡献代码或其它给本项目, (commenting or opening PR/Issues etc) 即表示同意这个协议。 +请您注意该项目是与 [Contributor Code of Conduct](CODE_OF_CONDUCT.md) 一起发布的,通过提交 PR 或 Issues 参与该项目表示您已经同意遵守该准则,所以请您花时间仔细阅读它。 +### License -### 感谢 - -本框架是基于 [JS 参考实现](https://github.com/graphql/graphql-js),来开发的。 -如 StarWarSchema 和测试用例 (和其它很多方面) 是从它适配到 Java 的。 - -### 许可证 - -graphql-java 基于 MIT 许可证. 详见 [许可证](LICENSE.md) 。 - -Copyright (c) 2015, Andreas Marek 与 [贡献者们](https://github.com/graphql-java/graphql-java/graphs/contributors) - -[graphql-js 许可证](https://github.com/graphql/graphql-js/blob/master/LICENSE) - +Copyright (c) 2015, Andreas Marek and [贡献者们](https://github.com/graphql-java/graphql-java/graphs/contributors) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..455934a134 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +[GraphQL Java is the CVE Numbering Authority (CNA)](https://www.cve.org/PartnerInformation/ListofPartners/partner/graphql-java) for GraphQL Java, Java DataLoader, GraphQL Java Extended Scalars, and GraphQL Java Extended Validation. + +## Supported Versions + +As stated in our [Release Policy](https://www.graphql-java.com/blog/release-policy/), we will backport critical bugfixes and security fixes for versions dating back 18 months. These fixes will be backported depending on severity and demand. + +## Reporting a Vulnerability + +:rotating_light: To report a vulnerability, **DO NOT open a pull request or issue or GitHub discussion. DO NOT post publicly.** + +Instead, **report the vulnerability privately** via the Security tab on [graphql-java GitHub repository](https://github.com/graphql-java/graphql-java). See instructions at https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability diff --git a/additionallicenses/APACHE-LICENSE-2.0.txt b/additionallicenses/APACHE-LICENSE-2.0.txt new file mode 100644 index 0000000000..7a4a3ea242 --- /dev/null +++ b/additionallicenses/APACHE-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/bin/jmh.sh b/bin/jmh.sh new file mode 100755 index 0000000000..26aa5e9460 --- /dev/null +++ b/bin/jmh.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +BRANCH=$(git rev-parse --abbrev-ref HEAD) +JAR="build/libs/graphql-java-0.0.0-$BRANCH-SNAPSHOT-jmh.jar" +echo "build and then running jmh for $JAR" + +./gradlew clean jmhJar + +java -jar "$JAR" "$@" \ No newline at end of file diff --git a/build.gradle b/build.gradle index b829cb5469..a9276fe452 100644 --- a/build.gradle +++ b/build.gradle @@ -1,76 +1,298 @@ +import aQute.bnd.gradle.BundleTaskExtension +import net.ltgt.gradle.errorprone.CheckSeverity +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion + import java.text.SimpleDateFormat plugins { - id "com.jfrog.bintray" version "1.2" + id 'java' + id 'java-library' + id 'maven-publish' + id 'antlr' + id 'signing' + id "com.gradleup.shadow" version "9.0.0" + id "biz.aQute.bnd.builder" version "7.1.0" + id "io.github.gradle-nexus.publish-plugin" version "2.0.0" + id "groovy" + id "me.champeau.jmh" version "0.7.3" + id "net.ltgt.errorprone" version '4.3.0' + // + // Kotlin just for tests - not production code + id 'org.jetbrains.kotlin.jvm' version '2.2.21' } -apply plugin: 'java' -apply plugin: 'maven' -apply plugin: 'maven-publish' -apply plugin: 'antlr' -apply plugin: 'osgi' +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) // build on 21 - release on 11 + } +} -def getDevelopmentVersion() { - def output = new StringBuilder() - def error = new StringBuilder() - def gitShortHash = "git -C ${projectDir} rev-parse --short HEAD".execute() - gitShortHash.waitForProcessOutput(output, error) - def gitHash = output.toString().trim() - if (gitHash.isEmpty()) { - println "git hash is empty: error: ${error.toString()}" - throw new IllegalStateException("git hash could not be determined") +kotlin { + compilerOptions { + apiVersion = KotlinVersion.KOTLIN_2_0 + languageVersion = KotlinVersion.KOTLIN_2_0 + jvmTarget = JvmTarget.JVM_11 + javaParameters = true + freeCompilerArgs = [ + '-Xemit-jvm-type-annotations', + '-Xjspecify-annotations=strict', + ] } - new SimpleDateFormat('yyyy-MM-dd\'T\'HH-mm-ss').format(new Date()) + "-" + gitHash } +def makeDevelopmentVersion(parts) { + def version = String.join("-", parts) + println "created development version: $version" + return version +} + +def getDevelopmentVersion() { + def dateTime = new SimpleDateFormat('yyyy-MM-dd\'T\'HH-mm-ss').format(new Date()) + def gitCheckOutput = new StringBuilder() + def gitCheckError = new StringBuilder() + def gitCheck = ["git", "-C", projectDir.toString(), "rev-parse", "--is-inside-work-tree"].execute() + gitCheck.waitForProcessOutput(gitCheckOutput, gitCheckError) + def isGit = gitCheckOutput.toString().trim() + if (isGit != "true") { + return makeDevelopmentVersion(["0.0.0", dateTime, "no-git"]) + } + + // a default Github Action env variable set to 'true' + def isCi = Boolean.parseBoolean(System.env.CI) + if (isCi) { + def gitHashOutput = new StringBuilder() + def gitHashError = new StringBuilder() + def gitShortHash = ["git", "-C", projectDir.toString(), "rev-parse", "--short", "HEAD"].execute() + gitShortHash.waitForProcessOutput(gitHashOutput, gitHashError) + def gitHash = gitHashOutput.toString().trim() + if (gitHash.isEmpty()) { + println "git hash is empty: error: ${gitHashError.toString()}" + throw new IllegalStateException("git hash could not be determined") + } + + return makeDevelopmentVersion(["0.0.0", dateTime, gitHash]) + } + + def gitRevParseOutput = new StringBuilder() + def gitRevParseError = new StringBuilder() + def gitRevParse = ["git", "-C", projectDir.toString(), "rev-parse", "--abbrev-ref", "HEAD"].execute() + gitRevParse.waitForProcessOutput(gitRevParseOutput, gitRevParseError) + def branchName = gitRevParseOutput.toString().trim() + + return makeDevelopmentVersion(["0.0.0", branchName, "SNAPSHOT"]) +} -sourceCompatibility = 1.8 -targetCompatibility = 1.8 -def reactiveStreamsVersion = '1.0.2' -def slf4jVersion = '1.7.25' +def reactiveStreamsVersion = '1.0.3' def releaseVersion = System.env.RELEASE_VERSION +def antlrVersion = '4.13.2' // https://mvnrepository.com/artifact/org.antlr/antlr4-runtime +def guavaVersion = '32.1.2-jre' version = releaseVersion ? releaseVersion : getDevelopmentVersion() group = 'com.graphql-java' +gradle.buildFinished { buildResult -> + println "*******************************" + println "*" + if (buildResult.failure != null) { + println "* FAILURE - ${buildResult.failure}" + } else { + println "* SUCCESS" + } + println "* Version: $version" + println "*" + println "*******************************" +} repositories { mavenCentral() mavenLocal() } -apply plugin: 'groovy' - jar { from "LICENSE.md" from "src/main/antlr/Graphql.g4" from "src/main/antlr/GraphqlOperation.g4" from "src/main/antlr/GraphqlSDL.g4" from "src/main/antlr/GraphqlCommon.g4" + manifest { + attributes('Automatic-Module-Name': 'com.graphqljava') + } } dependencies { - compile 'org.antlr:antlr4-runtime:4.7.1' - compile 'org.slf4j:slf4j-api:' + slf4jVersion - compile 'com.graphql-java:java-dataloader:2.0.2' - compile 'org.reactivestreams:reactive-streams:' + reactiveStreamsVersion - antlr "org.antlr:antlr4:4.7.1" - testCompile group: 'junit', name: 'junit', version: '4.11' - testCompile 'org.spockframework:spock-core:1.1-groovy-2.4' - testCompile 'org.codehaus.groovy:groovy-all:2.4.13' - testCompile 'cglib:cglib-nodep:3.1' - testCompile 'org.objenesis:objenesis:2.1' - testCompile 'com.google.code.gson:gson:2.8.0' - testCompile 'org.eclipse.jetty:jetty-server:9.4.5.v20170502' - testCompile 'com.fasterxml.jackson.core:jackson-databind:2.8.8.1' - testCompile 'org.slf4j:slf4j-simple:' + slf4jVersion - testCompile 'org.awaitility:awaitility-groovy:3.0.0' - testCompile 'com.github.javafaker:javafaker:0.13' - - testCompile 'org.reactivestreams:reactive-streams-tck:' + reactiveStreamsVersion - testCompile "io.reactivex.rxjava2:rxjava:2.1.5" -} - -compileJava.source file("build/generated-src"), sourceSets.main.java + api 'com.graphql-java:java-dataloader:6.0.0' + api 'org.reactivestreams:reactive-streams:' + reactiveStreamsVersion + api "org.jspecify:jspecify:1.0.0" + + implementation 'org.antlr:antlr4-runtime:' + antlrVersion + implementation 'com.google.guava:guava:' + guavaVersion + + testImplementation 'org.junit.jupiter:junit-jupiter:5.14.1' + + testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0' + testImplementation 'net.bytebuddy:byte-buddy:1.18.1' + testImplementation 'org.objenesis:objenesis:3.4' + testImplementation 'org.apache.groovy:groovy:4.0.28"' + testImplementation 'org.apache.groovy:groovy-json:4.0.28' + testImplementation 'com.google.code.gson:gson:2.13.2' + testImplementation 'org.eclipse.jetty:jetty-server:11.0.26' + testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.20.1' + testImplementation 'org.awaitility:awaitility-groovy:4.3.0' + testImplementation 'com.github.javafaker:javafaker:1.0.2' + + testImplementation 'org.reactivestreams:reactive-streams-tck:' + reactiveStreamsVersion + testImplementation "io.reactivex.rxjava2:rxjava:2.2.21" + testImplementation "io.projectreactor:reactor-core:3.8.0" + + testImplementation 'org.testng:testng:7.11.0' // use for reactive streams test inheritance + testImplementation "com.tngtech.archunit:archunit-junit5:1.4.1" + testImplementation 'org.openjdk.jmh:jmh-core:1.37' // required for ArchUnit to check JMH tests + + // JUnit Platform launcher required for Gradle 9 + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.14.1' + + antlr 'org.antlr:antlr4:' + antlrVersion + + // this is needed for the idea jmh plugin to work correctly + jmh 'org.openjdk.jmh:jmh-core:1.37' + jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.37' + + // comment this in if you want to run JMH benchmarks from idea +// jmhAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.37' + + errorprone 'com.uber.nullaway:nullaway:0.12.10' + errorprone 'com.google.errorprone:error_prone_core:2.44.0' + + // just tests - no Kotlin otherwise + testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' +} + +shadowJar { + minimize() + archiveClassifier.set('') + configurations = [project.configurations.compileClasspath] + relocate('com.google.common', 'graphql.com.google.common') { + include 'com.google.common.collect.*' + include 'com.google.common.base.*' + include 'com.google.common.math.*' + include 'com.google.common.primitives.*' + } + relocate('org.antlr.v4.runtime', 'graphql.org.antlr.v4.runtime') + dependencies { + include(dependency('com.google.guava:guava:' + guavaVersion)) + include(dependency('org.antlr:antlr4-runtime:' + antlrVersion)) + } + from "LICENSE.md" + from "src/main/antlr/Graphql.g4" + from "src/main/antlr/GraphqlOperation.g4" + from "src/main/antlr/GraphqlSDL.g4" + from "src/main/antlr/GraphqlCommon.g4" + manifest { + attributes('Automatic-Module-Name': 'com.graphqljava') + } +} + +// Apply bnd to shadowJar task manually for Gradle 9 compatibility +tasks.named('shadowJar').configure { + // Get the BundleTaskExtension added by bnd plugin + def bundle = extensions.findByType(BundleTaskExtension) + if (bundle != null) { + //Configure bnd for shadowJar + // -exportcontents: graphql.* Adds all packages of graphql and below to the exported packages list + // -removeheaders: Private-Package Removes the MANIFEST.MF header Private-Package, which contains all the internal packages and + // also the repackaged packages like guava, which would be wrong after repackaging. + // Import-Package: Changes the imported packages header, to exclude guava and dependencies from the import list (! excludes packages) + // Guava was repackaged and included inside the jar, so we need to remove it. + // ANTLR was shaded, so we need to remove it. + // sun.misc is a JRE internal-only class that is not directly used by graphql-java. It was causing problems in libraries using graphql-java. + // The last ,* copies all the existing imports from the other dependencies, which is required. + bundle.bnd(''' +-exportcontents: graphql.* +-removeheaders: Private-Package +Import-Package: !android.os.*,!com.google.*,!org.checkerframework.*,!graphql.com.google.*,!org.antlr.*,!graphql.org.antlr.*,!sun.misc.*,org.jspecify.annotations;resolution:=optional,* +''') + } +} + +tasks.named('jmhJar') { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + from { + project.configurations.jmhRuntimeClasspath + .filter { it.exists() } + .collect { it.isDirectory() ? it : zipTree(it) } + } +} + + +task extractWithoutGuava(type: Copy) { + from({ zipTree({ "build/libs/graphql-java-${project.version}.jar" }) }) { + exclude('/com/**') + } + into layout.buildDirectory.dir("extract") +} + +extractWithoutGuava.dependsOn jar + +task buildNewJar(type: Jar) { + from layout.buildDirectory.dir("extract") + archiveFileName = "graphql-java-tmp.jar" + destinationDirectory = file("${project.buildDir}/libs") + manifest { + from file("build/extract/META-INF/MANIFEST.MF") + } + def projectVersion = version + doLast { + delete("build/libs/graphql-java-${projectVersion}.jar") + file("build/libs/graphql-java-tmp.jar").renameTo(file("build/libs/graphql-java-${projectVersion}.jar")) + } +} + +buildNewJar.dependsOn extractWithoutGuava + +shadowJar.finalizedBy extractWithoutGuava, buildNewJar + + +task testng(type: Test) { + useTestNG() +} +check.dependsOn testng + +compileJava { + options.compilerArgs += ["-parameters"] + source file("build/generated-src"), sourceSets.main.java + // Gradle 9 requires explicit task dependencies + mustRunAfter generateTestGrammarSource, generateJmhGrammarSource +} + +tasks.withType(GroovyCompile) { + // Options when compiling Java using the Groovy plugin. + // (Groovy itself defaults to UTF-8 for Groovy code) + options.encoding = 'UTF-8' + sourceCompatibility = '11' + targetCompatibility = '11' + groovyOptions.forkOptions.memoryMaximumSize = "4g" +} + +tasks.withType(JavaCompile) { + options.release = 11 + options.errorprone { + disableAllChecks = true + check("NullAway", CheckSeverity.ERROR) + // + // end state has us with this config turned on - eg all classes + // + //option("NullAway:AnnotatedPackages", "graphql") + option("NullAway:CustomContractAnnotations", "graphql.Contract") + option("NullAway:OnlyNullMarked", "true") + option("NullAway:JSpecifyMode", "true") + } + // Include to disable NullAway on test code + if (name.toLowerCase().contains("test")) { + options.errorprone { + disable("NullAway") + } + } +} generateGrammarSource { includes = ['Graphql.g4'] @@ -78,16 +300,20 @@ generateGrammarSource { arguments += ["-visitor"] outputDirectory = file("${project.buildDir}/generated-src/antlr/main/graphql/parser/antlr") } -generateGrammarSource.inputs.dir('src/main/antlr') +generateGrammarSource.inputs + .dir('src/main/antlr') + .withPropertyName('sourceDir') + .withPathSensitivity(PathSensitivity.RELATIVE) + task sourcesJar(type: Jar) { dependsOn classes - classifier 'sources' + archiveClassifier = 'sources' from sourceSets.main.allSource } task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' + archiveClassifier = 'javadoc' from javadoc.destinationDir } @@ -95,17 +321,124 @@ javadoc { options.encoding = 'UTF-8' } -artifacts { - archives sourcesJar - archives javadocJar +// Removed deprecated archives configuration in favor of direct assemble dependencies + +List failedTests = [] +Map testsAndTime = [:] +Map testClassesAndTime = [:] +int testCount = 0 +long testTime = 0L + +tasks.withType(Test) { + useJUnitPlatform() + testLogging { + events "FAILED", "SKIPPED" + exceptionFormat = "FULL" + } + + // Required for JMH ArchUnit tests + classpath += sourceSets.jmh.output + dependsOn "jmhClasses" + + afterTest { TestDescriptor descriptor, TestResult result -> + testCount++ + if (result.getFailedTestCount() > 0) { + failedTests.add(descriptor) + } + def ms = (int) (result.endTime - result.startTime) + testTime += ms + String className = descriptor.className ?: "unknown" + String name = className + "." + descriptor.displayName + if (ms > 500) { + testsAndTime[name] = ms + testClassesAndTime.compute(className) { k, v -> v == null ? ms : v + ms } + println "\tTest '$name' took ${ms}ms" + } + } +} + +tasks.register('testWithJava17', Test) { + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(17) + } + testClassesDirs = sourceSets.test.output.classesDirs + classpath = sourceSets.test.runtimeClasspath + classpath += sourceSets.jmh.output + dependsOn "jmhClasses" + + + dependsOn tasks.named('testClasses') + } +tasks.register('testWithJava11', Test) { + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(11) + } + testClassesDirs = sourceSets.test.output.classesDirs + classpath = sourceSets.test.runtimeClasspath + + dependsOn tasks.named('testClasses') + + classpath += sourceSets.jmh.output + dependsOn "jmhClasses" + +} + +test.dependsOn testWithJava17 +test.dependsOn testWithJava11 + + +/* + * The gradle.buildFinished callback is deprecated BUT there does not seem to be a decent alternative in gradle 7 + * So progress over perfection here + * + * See https://github.com/gradle/gradle/issues/20151 + */ +gradle.buildFinished { + println "\n\n" + println "============================" + println "$testCount tests run in $testTime ms" + println "============================" + if (!failedTests.isEmpty()) { + println "\n\n" + println "============================" + println "These are the test failures" + println "============================" + for (td in failedTests) { + println "${td.getClassName()}.${td.getDisplayName()}" + } + println "============================" + } + // slowest tests + println "\n\n" + println "============================" + println "Top 20 slowest test classes" + println "============================" + showTestResults(testClassesAndTime,20) { e -> + println "\tTest class ${e.key} took ${e.value}ms" + } + println "\n\n" + println "============================" + println "Top 50 slowest tests" + println "============================" + showTestResults(testsAndTime,50) { e -> + println "\tTest ${e.key} took ${e.value}ms" + } +} + +static private showTestResults(Map testMap, int limit, Closure closure) { + testMap.entrySet().stream() + .sorted { e1, e2 -> e2.getValue() - e1.getValue() } + .limit(limit) + .forEach(closure) +} + + allprojects { tasks.withType(Javadoc) { exclude('**/antlr/**') } - - } publishing { @@ -113,22 +446,25 @@ publishing { publications { graphqlJava(MavenPublication) { - version version + version = version from components.java artifact sourcesJar { - classifier "sources" + archiveClassifier = "sources" } artifact javadocJar { - classifier "javadoc" + archiveClassifier = "javadoc" } pom.withXml { - // The ANTLR-related code below--introdcued in `1ac98bf`--addresses an issue with + // Removing antlr4 below (introduced in `1ac98bf`) addresses an issue with // the Gradle ANTLR plugin. `1ac98bf` can be reverted and this comment removed once // that issue is fixed and Gradle upgraded. See https://goo.gl/L92KiF and https://goo.gl/FY0PVR. - Node pomNode = asNode() + // + // Removing antlr4-runtime and guava because the classes we want to use are "shaded" into the jar itself + // via the shadowJar task + def pomNode = asNode() pomNode.dependencies.'*'.findAll() { - it.artifactId.text() == 'antlr4' + it.artifactId.text() == 'antlr4' || it.artifactId.text() == 'antlr4-runtime' || it.artifactId.text() == 'guava' }.each() { it.parent().remove(it) } @@ -161,44 +497,36 @@ publishing { } } - -bintray { - user = System.env.BINTRAY_USER ?: project["bintray.user"] - key = System.env.BINTRAY_API_KEY ?: project["bintray.key"] - publications = ['graphqlJava'] - publish = true - pkg { - repo = 'graphql-java' - name = 'graphql-java' - desc = 'GraphQL in Java' - licenses = ['MIT'] - vcsUrl = 'https://github.com/graphql-java/graphql-java' - - version { - name = project.version - desc = project.description - released = new Date() - vcsTag = 'v' + project.version - gpg { - sign = true - } - mavenCentralSync { - sync = true - user = System.env.MAVEN_CENTRAL_USER - password = System.env.MAVEN_CENTRAL_PASSWORD - close = '1' - } +nexusPublishing { + repositories { + sonatype { + username = System.env.MAVEN_CENTRAL_USER_NEW + password = System.env.MAVEN_CENTRAL_PASSWORD_NEW + // https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#configuration + nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) + // GraphQL Java does not publish snapshots, but adding this URL for completeness + snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) } } } +signing { + setRequired { !project.hasProperty('publishToMavenLocal') } + def signingKey = System.env.MAVEN_CENTRAL_PGP_KEY + useInMemoryPgpKeys(signingKey, "") + sign publishing.publications +} + + // all publish tasks depend on the build task tasks.withType(PublishToMavenRepository) { dependsOn build } - -task wrapper(type: Wrapper) { - gradleVersion = '4.5.1' - distributionUrl = "https://services.gradle.org/distributions/gradle-${gradleVersion}-all.zip" +// Only publish Maven POM, disable default Gradle modules file +tasks.withType(GenerateModuleMetadata) { + enabled = false } + + + diff --git a/coding-guidelines.md b/coding-guidelines.md new file mode 100644 index 0000000000..cecd8b2c42 --- /dev/null +++ b/coding-guidelines.md @@ -0,0 +1,184 @@ +# GraphQL Java Coding guidelines used in GraphQL Java + + +## General principles + +- We prefer closer to zero dependencies. Don't bring in guava, apache-commons, spring-xxx, y or z however much some StringUtils method might be useful. Fewer dependencies makes graphql-java more applicable to everyone + +- We prefer staying out of the HTTP stack. We are the low level engine of running graphql queries. Other concerns such as JSON and HTTP are handled better by other layers + +- We prefer simple code to clever code. It should be readable with well named methods. Clever nested streams and lambdas are not our thing. + +- We prefer general to specific. So the code should be generally applicable to use cases, not highly specific to just some use cases, even if it takes more setup. + + +## more specific topics + +- Use `@Public` and `@Internal` to communicate what level of stability is supported. + +- Never make a class or method package private or protected: +make it public or private and use `@Internal` to communicate that the class can be changed without notice. +The user can decide itself about the risk when they use internal things. + +### Optional vs null +We have a mix of Optional and allowing null values because GraphQL Java was originally written in Java 6. + +We are aiming to not use Optional moving forward in order to be consistent overall. + +### Unit testing and dependencies +All tests are written in [Spock](https://spockframework.org). + +All new code has to have unit tests. + +The general pattern is that every method of every class is by default non static and that every dependency is an instance field with package private visibility +to allow for easy mocking in unit tests. The field should be annotated with `@VisibleForTesting`. + +Example: + +```java +public class Foo { + + @VisibleForTesting + Bar bar = new Bar(); + + + public void doSomething(){ + ... + } + +} + +``` + +### Static methods +Static methods are only allowed for methods which are very limited in functionality and don't have any dependencies. +Static methods imply that you never want to mock them. + +Typical examples are util methods like `GraphQLTypeUtil.isNonNull()` + +### "Util" class or not +Don't mix static and non static methods (except factory methods): +every class is either a general "Util" class with only static methods or a class with no static methods. + + +### Naming +Naming is a key element of readable source code. +Every variable and method should have a clear name. Single char variable names are never ok, except for index iterations. + +### Comments +Public APIs should be documented via JavaDoc. The JavaDoc should describe how and why this class/method should be used. It should not specify the details of the implementation. + +Internal APIs don't have JavaDoc and in general we avoid any form of comments when possible. + +### Methods over comments +Most comments inside a method can be refactored by creating a method and giving the method name the comment text. + +### Immutable and Builders +Every public data class should be: + +- Immutable +- having a Builder class +- having a `transform` method + + +Every data class should be immutable and contain a `public static class Builder {..}` with a static factory method `newFoo` (not `newBuilder`). + +The Builder methods are just named like the property (`Builder.foo(Foo foo)` not `Builder.setFoo(Foo foo)`). + +The class should also contain a `public Foo transform(Consumer builderConsumer)` to allow for easy copies with minimal effort. + +Private classes should follow the same design, but they don't have to. + +### Default Collections idiom + +The default pattern for using Set, Map and List is: +- `List fooList = new ArrayList<>()` +- `Set fooSet = new LinkedHashSet<>()` +- `Map fooMap = new LinkedHashMap<>()` + +By using the generic interface instead of using an implementation we are making sure we +don't rely on anything impl specific. +The default implementations for `Set` and `Map` should be the `LinkedHashSet` and `LinkedHashMap` +because it offers stable iteration order. + +### Stream API vs for, index loop etc +Using the Stream API is ok in general, but it must be kept simple. Stream maps inside +maps should be avoided and the inner logic should be refactored into a method. + +It is also ok to use the traditional for loop or other constructs: sometimes it is more readable than +the modern Stream API. The Stream API is not a replacement for all other loops/iterations. + + +### Maximum Indentation is two +One of the most important rules is to keep the number of indentations as low as possible. +In general the max number should be two. This means a for loop inside a condition is ok. +A condition inside a for loop inside a for loop is not. + +Extracting a method is the easy way out. + +### Early method exit +Exit the method early to avoid an indentation: + +```java +public void foo() { + if(cond) { + return; + } + ...do something +} +``` +is better than: + +```java +public void foo() { + if(!cond) { + ...do something + } +} +``` + +### Maximum line length and multi line statements + +We don't have a strict max line length. +But of course every statement should be limited. Not so much in terms of length but much more in terms +of what the statement does. + +If a statement is multiple lines long it should be broken down into the same indentation level. + +For example this is ok: +```java + return myMap + .entrySet() + .stream() + .map(entry -> mapEntry(entry)) + .collect(Collectors.toList()); +``` +This is not ok: +```java + return fooListOfList.stream().map( + fooList -> fooList.stream() + .sorted((x,y) -> sort(x,y)) + .map(foo -> foo.getMyProp()) + .collect(toList()) +``` +It has a lambda in streams in streams. The inside stream should be extracted to an extra method and each +method call should be on a new line: +```java + return fooListOfList + .stream() + .map(this::mapFooList) + .collect(toList()); +``` + +### Every class its own file: avoid inner classes and interfaces +Every class/interface should have its own file in general. +Inner classes are almost never ok (especially public ones). Every class should have its own file to make it easier to read and explore the code. + +### Use `graphql.Assert` instead of `Objects` +We maintain our own small set of Assert util methods. Don't use `Objects.requireNonNull` and others in order +to be consistent. + +### `FooEnvironment` method arguments for public API +Don't use specific arguments for interface methods but rather a `FooEnvironment` argument. This ensures future +backwards compatibility when new inputs are added. + diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 2d310507e7..0000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = python -msphinx -SPHINXPROJ = graphql-java -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/batching.rst b/docs/batching.rst deleted file mode 100644 index e64f07adcc..0000000000 --- a/docs/batching.rst +++ /dev/null @@ -1,264 +0,0 @@ -Using Dataloader -================ - -If you are using ``graphql``, you are likely to making queries on a graph of data (surprise surprise). But it's easy -to implement inefficient code with naive loading of a graph of data. - -Using ``java-dataloader`` will help you to make this a more efficient process by both caching and batching requests for that graph of data items. If ``dataloader`` -has seen a data item before, it will have cached the value and will return it without having to ask for it again. - -Imagine we have the StarWars query outlined below. It asks us to find a hero and their friend's names and their friend's friend's -names. It is likely that many of these people will be friends in common. - - -.. code-block:: graphql - - { - hero { - name - friends { - name - friends { - name - } - } - } - } - -The result of this query is displayed below. You can see that Han, Leia, Luke and R2-D2 are a tight knit bunch of friends and -share many friends in common. - -.. code-block:: json - - [ - hero: [ - name: 'R2-D2', - friends: [ - [ - name: 'Luke Skywalker', - friends: [ - [name: 'Han Solo'], - [name: 'Leia Organa'], - [name: 'C-3PO'], - [name: 'R2-D2'] - ] - ], - [ - name: 'Han Solo', - friends: [ - [name: 'Luke Skywalker'], - [name: 'Leia Organa'], - [name: 'R2-D2'] - ] - ], - [ - name: 'Leia Organa', - friends: [ - [name: 'Luke Skywalker'], - [name: 'Han Solo'], - [name: 'C-3PO'], - [name: 'R2-D2'] - ] - ] - ] - ] - ] - -A naive implementation would call a `DataFetcher` to retrieve a person object every time it was invoked. - -In this case it would be *15* calls over the network. Even though the group of people have a lot of common friends. -With `dataloader` you can make the `graphql` query much more efficient. - -As `graphql` descends each level of the query (e.g. as it processes `hero` and then `friends` and then for each their `friends`), -the data loader is called to "promise" to deliver a person object. At each level `dataloader.dispatch()` will be -called to fire off the batch requests for that part of the query. With caching turned on (the default) then -any previously returned person will be returned as-is for no cost. - -In the above example there are only *5* unique people mentioned but with caching and batching retrieval in place there will be only -*3* calls to the batch loader function. *3* calls over the network or to a database is much better than *15* calls, you will agree. - -If you use capabilities like `java.util.concurrent.CompletableFuture.supplyAsync()` then you can make it even more efficient by making the -the remote calls asynchronous to the rest of the query. This will make it even more timely since multiple calls can happen at once -if need be. - -Here is how you might put this in place: - - -.. code-block:: java - - // a batch loader function that will be called with N or more keys for batch loading - BatchLoader characterBatchLoader = new BatchLoader() { - @Override - public CompletionStage> load(List keys) { - // - // we use supplyAsync() of values here for maximum parellisation - // - return CompletableFuture.supplyAsync(() -> getCharacterDataViaBatchHTTPApi(keys)); - } - }; - - // a data loader for characters that points to the character batch loader - DataLoader characterDataLoader = new DataLoader<>(characterBatchLoader); - - // - // use this data loader in the data fetchers associated with characters and put them into - // the graphql schema (not shown) - // - DataFetcher heroDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - return characterDataLoader.load("2001"); // R2D2 - } - }; - - DataFetcher friendsDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - StarWarsCharacter starWarsCharacter = environment.getSource(); - List friendIds = starWarsCharacter.getFriendIds(); - return characterDataLoader.loadMany(friendIds); - } - }; - - // - // DataLoaderRegistry is a place to register all data loaders in that needs to be dispatched together - // in this case there is 1 but you can have many - // - DataLoaderRegistry registry = new DataLoaderRegistry(); - registry.register("character", characterDataLoader); - - // - // this instrumentation implementation will dispatch all the dataloaders - // as each level fo the graphql query is executed and hence make batched objects - // available to the query and the associated DataFetchers - // - DataLoaderDispatcherInstrumentation dispatcherInstrumentation - = new DataLoaderDispatcherInstrumentation(registry); - - // - // now build your graphql object and execute queries on it. - // the data loader will be invoked via the data fetchers on the - // schema fields - // - GraphQL graphQL = GraphQL.newGraphQL(buildSchema()) - .instrumentation(dispatcherInstrumentation) - .build(); - - -One thing to note is the above only works if you use `DataLoaderDispatcherInstrumentation` which makes sure `dataLoader.dispatch()` -is called. If this was not in place, then all the promises to data will never be dispatched ot the batch loader function -and hence nothing would ever resolve. - -Per Request Data Loaders -^^^^^^^^^^^^^^^^^^^^^^^^ - -If you are serving web requests then the data can be specific to the user requesting it. If you have user specific data then you will not want to -cache data meant for user A to then later give it to user B in a subsequent request. - -The scope of your DataLoader instances is important. You might want to create them per web request to -ensure data is only cached within that web request and no more. - -If your data can be shared across web requests then you might want to scope your data loaders so they survive -longer than the web request say. - -But if you are doing per request data loaders then creating a new set of ``GraphQL`` and ``DataLoader`` objects per -request is super cheap. It's the ``GraphQLSchema`` creation that can be expensive, especially if you are using graphql SDL parsing. - -Structure your code so that the schema is statically held, perhaps in a static variable or in a singleton IoC component but -build out a new ``GraphQL`` set of objects on each request. - - -.. code-block:: java - - GraphQLSchema staticSchema = staticSchema_Or_MayBeFrom_IoC_Injection(); - - DataLoaderRegistry registry = new DataLoaderRegistry(); - registry.register("character", getCharacterDataLoader()); - - DataLoaderDispatcherInstrumentation dispatcherInstrumentation - = new DataLoaderDispatcherInstrumentation(registry); - - GraphQL graphQL = GraphQL.newGraphQL(staticSchema) - .instrumentation(dispatcherInstrumentation) - .build(); - - graphQL.execute("{ helloworld }"); - - // you can now throw away the GraphQL and hence DataLoaderDispatcherInstrumentation - // and DataLoaderRegistry objects since they are really cheap to build per request - - -Async Calls On Your Batch Loader Function Only -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The data loader code pattern works by combining all the outstanding data loader calls into more efficient batch loading calls. - -graphql-java tracks what outstanding data loader calls have been made and it is its responsibility to call ``dispatch`` -in the background at the most optimal time, which is when all graphql fields have been examined and dispatched. - -However there is a code pattern that will cause your data loader calls to never complete and these *MUST* be avoided. This bad -pattern consists of making a an asynchronous off thread call to a ``DataLoader`` in your data fetcher. - -The following will not work (it will never complete). - -.. code-block:: java - - BatchLoader batchLoader = new BatchLoader() { - @Override - public CompletionStage> load(List keys) { - return CompletableFuture.completedFuture(getTheseCharacters(keys)); - } - }; - - DataLoader characterDataLoader = new DataLoader<>(batchLoader); - - DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - // - // Don't DO THIS! - // - return CompletableFuture.supplyAsync(() -> { - String argId = environment.getArgument("id"); - return characterDataLoader.load(argId); - }); - } - }; - -In the example above, the call to ``characterDataLoader.load(argId)`` can happen some time in the future on another thread. The graphql-java -engine has no way of knowing when it's good time to dispatch outstanding ``DataLoader`` calls and hence the data loader call might never complete -as expected and no results will be returned. - -Remember a data loader call is just a promise to actually get a value later when its an optimal time for all outstanding calls to be batched -together. The most optimal time is when the graphql field tree has been examined and all field values are currently dispatched. - -The following is how you can still have asynchronous code, by placing it into the ``BatchLoader`` itself. - -.. code-block:: java - - BatchLoader batchLoader = new BatchLoader() { - @Override - public CompletionStage> load(List keys) { - return CompletableFuture.supplyAsync(() -> getTheseCharacters(keys)); - } - }; - - DataLoader characterDataLoader = new DataLoader<>(batchLoader); - - DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - // - // This is OK - // - String argId = environment.getArgument("id"); - return characterDataLoader.load(argId); - } - }; - -Notice above the ``characterDataLoader.load(argId)`` returns immediately. This will enqueue the call for data until a later time when all -the graphql fields are dispatched. - -Then later when the ``DataLoader`` is dispatched, it's ``BatchLoader`` function is called. This code can be asynchronous so that if you have multiple batch loader -functions they all can run at once. In the code above ``CompletableFuture.supplyAsync(() -> getTheseCharacters(keys));`` will run the ``getTheseCharacters`` -method in another thread. \ No newline at end of file diff --git a/docs/concerns.rst b/docs/concerns.rst deleted file mode 100644 index c9e7a8defd..0000000000 --- a/docs/concerns.rst +++ /dev/null @@ -1,63 +0,0 @@ -Application concerns -==================== - -The graphql-java library concentrates on providing an engine for the execution of queries according to the specification. - -It does not concern itself about other high level application concerns such as the following : - -- Database access -- Caching data -- Data authorisation -- Data pagination -- HTTP transfer -- JSON encoding -- Code wiring via dependency injection - -You need to push these concerns into your business logic layers. - -The following are great links to read more about this - -- http://graphql.org/learn/serving-over-http/ -- http://graphql.org/learn/authorization/ -- http://graphql.org/learn/pagination/ -- http://graphql.org/learn/caching/ - -Context Objects -^^^^^^^^^^^^^^^ - -You can pass in a context object during query execution that will allow you to better invoke that business logic. - -For example the edge of your application could be performing user detection and you need that information inside the -graphql execution to perform authorisation. - -This made up example shows how you can pass yourself information to help execute your queries. - -.. code-block:: java - - // - // this could be code that authorises the user in some way and sets up enough context - // that can be used later inside data fetchers allowing them - // to do their job - // - UserContext contextForUser = YourGraphqlContextBuilder.getContextForUser(getCurrentUser()); - - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .context(contextForUser) - .build(); - - ExecutionResult executionResult = graphQL.execute(executionInput); - - // ... - // - // later you are able to use this context object when a data fetcher is invoked - // - - DataFetcher dataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - UserContext userCtx = environment.getContext(); - Long businessObjId = environment.getArgument("businessObjId"); - - return invokeBusinessLayerMethod(userCtx, businessObjId); - } - }; diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 8236edde41..0000000000 --- a/docs/conf.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# -# graphql-java documentation build configuration file, created by -# sphinx-quickstart on Wed Oct 4 19:10:27 2017. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'graphql-java' -copyright = u'2017, Brad Baker' -author = u'Brad Baker' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = u'current' -# The full version, including alpha/beta/rc tags. -release = u'current' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'java' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - 'donate.html', - ] -} - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'graphql-javadoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'graphql-java.tex', u'graphql-java Documentation', - u'Brad Baker', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'graphql-java', u'graphql-java Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'graphql-java', u'graphql-java Documentation', - author, 'graphql-java', 'One line description of project.', - 'Miscellaneous'), -] - -language = 'en' # language supported -locale_dirs = ['locale/'] # path is example but recommended. -gettext_compact = False # optional. \ No newline at end of file diff --git a/docs/contributions.rst b/docs/contributions.rst deleted file mode 100644 index 7621e60d21..0000000000 --- a/docs/contributions.rst +++ /dev/null @@ -1,43 +0,0 @@ -Contributions -============= - -Every contribution to make this project better is welcome: Thank you! - -In order to make this a pleasant as possible for everybody involved, here are some tips: - -* Respect the [Code of Conduct](#code-of-conduct) - -* Before opening an Issue to report a bug, please try the latest development version. It can happen that the problem is already solved. - -* Please use Markdown to format your comments properly. If you are not familiar with that: `Getting started with writing and formatting on GitHub `_ - -* For Pull Requests: - * Here are some `general tips `_ - - * Please be a as focused and clear as possible and don't mix concerns. This includes refactorings mixed with bug-fixes/features, see [Open Source Contribution Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html) - - * It would be good to add a automatic test. All tests are written in `Spock `_. - - -Build and test locally ----------------------- - -Just clone the repo and type - -.. code-block:: sh - - ./gradlew build - -In ``build/libs`` you will find the jar file. - -Running the tests: - -.. code-block:: sh - - ./gradlew test - -Installing in the local Maven repository: - -.. code-block:: sh - - ./gradlew install diff --git a/docs/defer.rst b/docs/defer.rst deleted file mode 100644 index 47ce1f911c..0000000000 --- a/docs/defer.rst +++ /dev/null @@ -1,121 +0,0 @@ -Deferred Execution -================== - -Often when executing a query you have two classes of data. The data you need immediately and the data that could arrive little bit later. - -For example imagine this query that gets data on a ``post`` and its ``comments`` and ``reviews``. - - -.. code-block:: graphql - - query { - post { - postText - comments { - commentText - } - reviews { - reviewText { - } - } - -In this form, you *must* wait for the ``comments`` and ``reviews`` data to be retrieved before you can send the ``post`` data back -to the client. All three data elements are bound to the one query - -A naive approach would be to make two queries to get the most important data first but there is now a better way. - -There is ``experimental`` support for deferred execution in graphql-java. - -.. code-block:: graphql - - query { - post { - postText - comments @defer { - commentText - } - reviews @defer { - reviewText { - } - } - -The ``@defer`` directive tells the engine to defer execution of those fields and deliver them later. The rest of the query is executed as -usual. There will be the usual ``ExecutionResult`` of initial data and then a ``org.reactivestreams.Publisher`` of the deferred data. - -In the query above, the ``post`` data will be send out in the initial result and then the comments and review data will be sent (in query order) -down a ``Publisher`` later. - -You execute your query as you would any other graphql query. The deferred results ``Publisher`` will be given to you via -the ``extensions`` map - - -.. code-block:: java - - GraphQLSchema schema = buildSchemaWithDirective(); - GraphQL graphQL = GraphQL.newGraphQL(schema).build(); - - // - // deferredQuery contains the query with @defer directives in it - // - ExecutionResult initialResult = graphQL.execute(ExecutionInput.newExecutionInput().query(deferredQuery).build()); - - // - // then initial results happen first, the deferred ones will begin AFTER these initial - // results have completed - // - sendResult(httpServletResponse, initialResult); - - Map extensions = initialResult.getExtensions(); - Publisher deferredResults = (Publisher) extensions.get(GraphQL.DEFERRED_RESULTS); - - // - // you subscribe to the deferred results like any other reactive stream - // - deferredResults.subscribe(new Subscriber() { - - Subscription subscription; - - @Override - public void onSubscribe(Subscription s) { - subscription = s; - // - // how many you request is up to you - subscription.request(10); - } - - @Override - public void onNext(ExecutionResult executionResult) { - // - // as each deferred result arrives, send it to where it needs to go - // - sendResult(httpServletResponse, executionResult); - subscription.request(10); - } - - @Override - public void onError(Throwable t) { - handleError(httpServletResponse, t); - } - - @Override - public void onComplete() { - completeResponse(httpServletResponse); - } - }); - -The above code subscribes to the deferred results and when each one arrives, sends it down to the client. - -You can see more details on reactive-streams code here http://www.reactive-streams.org/ - -``RxJava`` is a popular implementation of reactive-streams. Check out http://reactivex.io/intro.html to find out more -about creating Subscriptions. - -graphql-java only produces a stream of deferred results. It does not concern itself with sending these over the network on things -like web sockets and so on. That is important but not a concern of the base graphql-java library. Its up to you -to use whatever network mechanism (websockets / long poll / ....) to get results back to you clients. - -Also note that this capability is currently ``experimental`` and not defined by the official ``graphql`` specification. We reserve the -right to change it in a future release or if it enters the official specification. The graphql-java project -is keen to get feedback on this capability. - - diff --git a/docs/exceptions.rst b/docs/exceptions.rst deleted file mode 100644 index 5d5dcb7cb2..0000000000 --- a/docs/exceptions.rst +++ /dev/null @@ -1,61 +0,0 @@ -Runtime Exceptions -================== - - -Runtime exceptions can be thrown by the graphql engine if certain exceptional situations are encountered. The following -are a list of the exceptions that can be thrown all the way out of a ``graphql.execute(...)`` call. - -These are not graphql errors in execution but rather totally unacceptable conditions in which to execute a graphql query. - - - `graphql.schema.CoercingSerializeException` - - is thrown when a value cannot be serialised by a Scalar type, for example - a String value being coerced as an Int. - - - - `graphql.schema.CoercingParseValueException` - - is thrown when a value cannot be parsed by a Scalar type, for example - a String input value being parsed as an Int. - - - - `graphql.execution.UnresolvedTypeException` - - is thrown if a graphql.schema.TypeResolver` fails to provide a concrete - object type given a interface or union type. - - - - `graphql.execution.NonNullableValueCoercedAsNullException` - - is thrown if a non null variable argument is coerced as a - null value during execution. - - - - `graphql.execution.InputMapDefinesTooManyFieldsException` - - is thrown if a map used for an input type object contains - more keys than is defined in that input type. - - - - `graphql.schema.validation.InvalidSchemaException` - - is thrown if the schema is not valid when built via - graphql.schema.GraphQLSchema.Builder#build()` - - - `graphql.execution.UnknownOperationException` - -if multiple operations are defined in the query and -the operation name is missing or there is no matching operation name -contained in the GraphQL query. - - - `graphql.GraphQLException` - - is thrown as a general purpose runtime exception, for example if the code cant - access a named field when examining a POJO, it is analogous to a RuntimeException if you will. - - - - `graphql.AssertException` - - is thrown as a low level code assertion exception for truly unexpected code conditions, things we assert -should never happen in practice. - diff --git a/docs/execution.rst b/docs/execution.rst deleted file mode 100644 index 98756245da..0000000000 --- a/docs/execution.rst +++ /dev/null @@ -1,606 +0,0 @@ -Execution -========= - -Queries -------- - -To execute a query against a schema, build a new ``GraphQL`` object with the appropriate arguments and then -call ``execute()``. - -The result of a query is an ``ExecutionResult`` which is the query data and/or a list of errors. - -.. code-block:: java - - GraphQLSchema schema = GraphQLSchema.newSchema() - .query(queryType) - .build(); - - GraphQL graphQL = GraphQL.newGraphQL(schema) - .build(); - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query("query { hero { name } }") - .build(); - - ExecutionResult executionResult = graphQL.execute(executionInput); - - Object data = executionResult.getData(); - List errors = executionResult.getErrors(); - - -More complex query examples can be found in the `StarWars query tests `_ - - -Data Fetchers -------------- - -Each graphql field type has a ``graphql.schema.DataFetcher`` associated with it. Other graphql implementations often call this -type of code *resolvers**. - -Often you can rely on ``graphql.schema.PropertyDataFetcher`` to examine Java POJO objects to -provide field values from them. If your don't specify a data fetcher on a field, this is what will be used. - -However you will need to fetch your top level domain objects via your own custom data fetchers. This might involve making -a database call or contacting another system over HTTP say. - -``graphql-java`` is not opinionated about how you get your domain data objects, that is very much your concern. It is also not -opinionated on user authorisation to that data. You should push all that logic into your business logic layer code. - -A data fetcher might look like this: - -.. code-block:: java - - DataFetcher userDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - return fetchUserFromDatabase(environment.getArgument("userId")); - } - }; - -Each ``DataFetcher`` is passed a ``graphql.schema.DataFetchingEnvironment`` object which contains what field is being fetched, what -arguments have been supplied to the field and other information such as the field's parent object, the query root object or the query -context object. - -In the above example, the execution will wait for the data fetcher to return before moving on. You can make execution of -the ``DataFetcher`` asynchronous by returning a ``CompletionStage`` to data, that is explained more further down this page. - -Exceptions while fetching data ------------------------------- - -If an exception happens during the data fetcher call, then the execution strategy by default will make a -``graphql.ExceptionWhileDataFetching`` error and add it to the list of errors on the result. Remember graphql allows -partial results with errors. - -Here is the code for the standard behaviour. - -.. code-block:: java - - public class SimpleDataFetcherExceptionHandler implements DataFetcherExceptionHandler { - private static final Logger log = LoggerFactory.getLogger(SimpleDataFetcherExceptionHandler.class); - - @Override - public void accept(DataFetcherExceptionHandlerParameters handlerParameters) { - Throwable exception = handlerParameters.getException(); - SourceLocation sourceLocation = handlerParameters.getField().getSourceLocation(); - ExecutionPath path = handlerParameters.getPath(); - - ExceptionWhileDataFetching error = new ExceptionWhileDataFetching(path, exception, sourceLocation); - handlerParameters.getExecutionContext().addError(error); - log.warn(error.getMessage(), exception); - } - } - -If the exception you throw is itself a `GraphqlError` then it will transfer the message and custom extensions attributes from that exception -into the `ExceptionWhileDataFetching` object. This allows you to place your own custom attributes into the graphql error that is sent back -to the caller. - -For example imagine your data fetcher threw this exception. The `foo` and `fizz` attributes would be included in the resultant -graphql error. - -.. code-block:: java - - class CustomRuntimeException extends RuntimeException implements GraphQLError { - @Override - public Map getExtensions() { - Map customAttributes = new LinkedHashMap<>(); - customAttributes.put("foo", "bar"); - customAttributes.put("fizz", "whizz"); - return customAttributes; - } - - @Override - public List getLocations() { - return null; - } - - @Override - public ErrorType getErrorType() { - return ErrorType.DataFetchingException; - } - } - - -You can change this behaviour by creating your own ``graphql.execution.DataFetcherExceptionHandler`` exception handling code and -giving that to the execution strategy. - -For example the code above records the underlying exception and stack trace. Some people -may prefer not to see that in the output error list. So you can use this mechanism to change that -behaviour. - -.. code-block:: java - - DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { - @Override - public void accept(DataFetcherExceptionHandlerParameters handlerParameters) { - // - // do your custom handling here. The parameters have all you need - } - }; - ExecutionStrategy executionStrategy = new AsyncExecutionStrategy(handler); - -Returning data and errors -^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is also possible to return both data and multiple errors in a ``DataFetcher`` implementation by returning -`graphql.execution.DataFetcherResult` either directly or wrapped in a ``CompletableFuture`` instance for asynchronous -execution. This is a useful when your ``DataFetcher`` may need to retrieve data from multiple sources or from another -GraphQL resource. - -In this example, the ``DataFetcher`` retrieves a user from another GraphQL resource and returns its data and errors. - -.. code-block:: java - - DataFetcher userDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - Map response = fetchUserFromRemoteGraphQLResource(environment.getArgument("userId")); - List errors = ((List)response.get("errors")).stream() - .map(MyMapGraphQLError::new) - .collect(Collectors.toList()); - return new DataFetcherResult(response.get("data"), errors); - } - }; - -Serializing results to JSON ---------------------------- - -The most common way to call graphql is over HTTP and to expect a JSON response back. So you need to turn an -`graphql.ExecutionResult` into a JSON payload. - -A common way to do that is use a JSON serialisation library like Jackson or GSON. However exactly how they interpret the -data result is particular to them. For example `nulls` are important in graphql results and hence you must set up the json mappers -to include them. - -To ensure you get a JSON result that conforms 100% to the graphql spec, you should call `toSpecification` on the result and then -send that back as JSON. - -This will ensure that the result follows the specification outlined in http://facebook.github.io/graphql/#sec-Response - - -.. code-block:: java - - ExecutionResult executionResult = graphQL.execute(executionInput); - - Map toSpecificationResult = executionResult.toSpecification(); - - sendAsJson(toSpecificationResult); - - - -Mutations ---------- - -A good starting point to learn more about mutating data in graphql is `http://graphql.org/learn/queries/#mutations `_. - -In essence you need to define a ``GraphQLObjectType`` that takes arguments as input. Those arguments are what you can use to mutate your data store -via the data fetcher invoked. - -The mutation is invoked via a query like : - -.. code-block:: graphql - - mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { - createReview(episode: $ep, review: $review) { - stars - commentary - } - } - -You need to send in arguments during that mutation operation, in this case for the variables for ``$ep`` and ``$review`` - -You would create types like this to handle this mutation : - -.. code-block:: java - - GraphQLInputObjectType episodeType = GraphQLInputObjectType.newInputObject() - .name("Episode") - .field(newInputObjectField() - .name("episodeNumber") - .type(Scalars.GraphQLInt)) - .build(); - - GraphQLInputObjectType reviewInputType = GraphQLInputObjectType.newInputObject() - .name("ReviewInput") - .field(newInputObjectField() - .name("stars") - .type(Scalars.GraphQLString)) - .field(newInputObjectField() - .name("commentary") - .type(Scalars.GraphQLString)) - .build(); - - GraphQLObjectType reviewType = newObject() - .name("Review") - .field(newFieldDefinition() - .name("stars") - .type(GraphQLString)) - .field(newFieldDefinition() - .name("commentary") - .type(GraphQLString)) - .build(); - - GraphQLObjectType createReviewForEpisodeMutation = newObject() - .name("CreateReviewForEpisodeMutation") - .field(newFieldDefinition() - .name("createReview") - .type(reviewType) - .argument(newArgument() - .name("episode") - .type(episodeType) - ) - .argument(newArgument() - .name("review") - .type(reviewInputType) - ) - .dataFetcher(mutationDataFetcher()) - ) - .build(); - - GraphQLSchema schema = GraphQLSchema.newSchema() - .query(queryType) - .mutation(createReviewForEpisodeMutation) - .build(); - - -Notice that the input arguments are of type ``GraphQLInputObjectType``. This is important. Input arguments can ONLY be of that type -and you cannot use output types such as ``GraphQLObjectType``. Scalars types are consider both input and output types. - -The data fetcher here is responsible for executing the mutation and returning some sensible output values. - -.. code-block:: java - - private DataFetcher mutationDataFetcher() { - return new DataFetcher() { - @Override - public Review get(DataFetchingEnvironment environment) { - // - // The graphql specification dictates that input object arguments MUST - // be maps. You can convert them to POJOs inside the data fetcher if that - // suits your code better - // - // See http://facebook.github.io/graphql/October2016/#sec-Input-Objects - // - Map episodeInputMap = environment.getArgument("episode"); - Map reviewInputMap = environment.getArgument("review"); - - // - // in this case we have type safe Java objects to call our backing code with - // - EpisodeInput episodeInput = EpisodeInput.fromMap(episodeInputMap); - ReviewInput reviewInput = ReviewInput.fromMap(reviewInputMap); - - // make a call to your store to mutate your database - Review updatedReview = reviewStore().update(episodeInput, reviewInput); - - // this returns a new view of the data - return updatedReview; - } - }; - } - -Notice how it calls a data store to mutate the backing database and then returns a ``Review`` object that can be used as the output values -to the caller. - -Asynchronous Execution ----------------------- - -graphql-java uses fully asynchronous execution techniques when it executes queries. You can get the ``CompleteableFuture`` to results by calling -``executeAsync()`` like this - -.. code-block:: java - - GraphQL graphQL = buildSchema(); - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query("query { hero { name } }") - .build(); - - CompletableFuture promise = graphQL.executeAsync(executionInput); - - promise.thenAccept(executionResult -> { - // here you might send back the results as JSON over HTTP - encodeResultToJsonAndSendResponse(executionResult); - }); - - promise.join(); - -The use of ``CompletableFuture`` allows you to compose actions and functions that will be applied when the execution completes. The final -call to ``.join()`` waits for the execution to happen. - -In fact under the covers, the graphql-java engine uses asynchronous execution and makes the ``.execute()`` method appear synchronous by -calling join for you. So the following code is in fact the same. - -.. code-block:: java - - ExecutionResult executionResult = graphQL.execute(executionInput); - - // the above is equivalent to the following code (in long hand) - - CompletableFuture promise = graphQL.executeAsync(executionInput); - ExecutionResult executionResult2 = promise.join(); - - - -If a ``graphql.schema.DataFetcher`` returns a ``CompletableFuture`` object then this will be composed into the overall asynchronous -query execution. This means you can fire off a number of field fetching requests in parallel. Exactly what -threading strategy you use is up to your data fetcher code. - -The following code uses the standard Java ``java.util.concurrent.ForkJoinPool.commonPool()`` thread executor to supply values in another -thread. - -.. code-block:: java - - DataFetcher userDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - CompletableFuture userPromise = CompletableFuture.supplyAsync(() -> { - return fetchUserViaHttp(environment.getArgument("userId")); - }); - return userPromise; - } - }; - -The code above is written in long form. With Java 8 lambdas it can be written more succinctly as follows - -.. code-block:: java - - DataFetcher userDataFetcher = environment -> CompletableFuture.supplyAsync( - () -> fetchUserViaHttp(environment.getArgument("userId"))); - -The graphql-java engine ensures that all the ``CompletableFuture`` objects are composed together to provide an execution result -that follows the graphql specification. - -There is a helpful shortcut in graphql-java to create asynchronous data fetchers. -Use ``graphql.schema.AsyncDataFetcher.async(DataFetcher)`` to wrap a -``DataFetcher``. This can be used with static imports to produce more readable code. - -.. code-block:: java - - DataFetcher userDataFetcher = async(environment -> fetchUserViaHttp(environment.getArgument("userId"))); - -Execution Strategies --------------------- - -A class derived from ``graphql.execution.ExecutionStrategy`` is used to run a query or mutation. A number of different -strategies are provided with graphql-java and if you are really keen you can even write your own. - -You can wire in what execution strategy to use when you create the ``GraphQL`` object. - - -.. code-block:: java - - GraphQL.newGraphQL(schema) - .queryExecutionStrategy(new AsyncExecutionStrategy()) - .mutationExecutionStrategy(new AsyncSerialExecutionStrategy()) - .build(); - -In fact the code above is equivalent to the default settings and is a very sensible choice of execution -strategies for most cases. - -AsyncExecutionStrategy -^^^^^^^^^^^^^^^^^^^^^^ - -By default the "query" execution strategy is ``graphql.execution.AsyncExecutionStrategy`` which will dispatch -each field as ``CompleteableFuture`` objects and not care which ones complete first. This strategy allows for the most -performant execution. - -The data fetchers invoked can themselves return `CompletionStage`` values and this will create -fully asynchronous behaviour. - -So imagine a query as follows - -.. code-block:: graphql - - query { - hero { - enemies { - name - } - friends { - name - } - } - } - - -The ``AsyncExecutionStrategy`` is free to dispatch the *enemies* field at the same time as the *friends* field. It does not -have to do *enemies* first followed by *friends*, which would be less efficient. - -It will however assemble the results in order. The query result will follow the graphql specification and return object values -assembled in query field order. Only the execution of data fetching is free to be in any order. - -This behaviour is allowed in the graphql specification and in fact is actively encouraged http://facebook.github.io/graphql/#sec-Query -for read only queries. - -See `specification `_ for details. - - -AsyncSerialExecutionStrategy -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The graphql specification says that mutations MUST be executed serially and in the order in which the -query fields occur. - -So ``graphql.execution.AsyncSerialExecutionStrategy`` is used by default for mutations and will ensure that each -field is completed before it processes the next one and so forth. You can still return ``CompletionStage`` objects -in the mutation data fetchers, however they will be executed serially and will be completed before the next -mutation field data fetcher is dispatched. - -ExecutorServiceExecutionStrategy -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``graphql.execution.ExecutorServiceExecutionStrategy`` execution strategy will always dispatch each field -fetch in an asynchronous manner, using the executor you give it. It differs from ``AsyncExecutionStrategy`` in that -it does not rely on the data fetchers to be asynchronous but rather makes the field fetch invocation asynchronous by -submitting each field to the provided `java.util.concurrent.ExecutorService`. - -This behaviour makes it unsuitable to be used as a mutation execution strategy. - -.. code-block:: java - - ExecutorService executorService = new ThreadPoolExecutor( - 2, /* core pool size 2 thread */ - 2, /* max pool size 2 thread */ - 30, TimeUnit.SECONDS, - new LinkedBlockingQueue(), - new ThreadPoolExecutor.CallerRunsPolicy()); - - GraphQL graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) - .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(executorService)) - .mutationExecutionStrategy(new AsyncSerialExecutionStrategy()) - .build(); - - -SubscriptionExecutionStrategy -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Graphql subscriptions allows you to create stateful subscriptions to graphql data. You uses ``SubscriptionExecutionStrategy`` -as your execution strategy as it has the support for the reactive-streams APIs. - -See http://www.reactive-streams.org/ for more information on the reactive ``Publisher`` and ``Subscriber`` interfaces. - -Also see the page on subscriptions for more details on how to write a subscription based graphql service. - - -Limiting Field Visibility -------------------------- - -By default every fields defined in a `GraphqlSchema` is available. There are cases where you may want to restrict certain fields -depending on the user. - -You can do this by using a `graphql.schema.visibility.GraphqlFieldVisibility` implementation and attaching it to the schema. - -A simple `graphql.schema.visibility.BlockedFields` implementation based on fully qualified field name is provided. - -.. code-block:: java - - GraphqlFieldVisibility blockedFields = BlockedFields.newBlock() - .addPattern("Character.id") - .addPattern("Droid.appearsIn") - .addPattern(".*\\.hero") // it uses regular expressions - .build(); - - GraphQLSchema schema = GraphQLSchema.newSchema() - .query(StarWarsSchema.queryType) - .fieldVisibility(blockedFields) - .build(); - -There is also another implementation that prevents instrumentation from being able to be performed on your schema, if that is a requirement. - -Note that this puts your server in contravention of the graphql specification and expectations of most clients so use this with caution. - - -.. code-block:: java - - GraphQLSchema schema = GraphQLSchema.newSchema() - .query(StarWarsSchema.queryType) - .fieldVisibility(NoIntrospectionGraphqlFieldVisibility.NO_INTROSPECTION_FIELD_VISIBILITY) - .build(); - - -You can create your own derivation of `GraphqlFieldVisibility` to check what ever you need to do to work out what fields -should be visible or not. - -.. code-block:: java - - class CustomFieldVisibility implements GraphqlFieldVisibility { - - final YourUserAccessService userAccessService; - - CustomFieldVisibility(YourUserAccessService userAccessService) { - this.userAccessService = userAccessService; - } - - @Override - public List getFieldDefinitions(GraphQLFieldsContainer fieldsContainer) { - if ("AdminType".equals(fieldsContainer.getName())) { - if (!userAccessService.isAdminUser()) { - return Collections.emptyList(); - } - } - return fieldsContainer.getFieldDefinitions(); - } - - @Override - public GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsContainer, String fieldName) { - if ("AdminType".equals(fieldsContainer.getName())) { - if (!userAccessService.isAdminUser()) { - return null; - } - } - return fieldsContainer.getFieldDefinition(fieldName); - } - } - - -Query Caching -------------- - -Before the ``graphql-java`` engine executes a query it must be parsed and validated, and this process can be somewhat time consuming. - -To avoid the need for re-parse/validate the ``GraphQL.Builder`` allows an instance of ``PreparsedDocumentProvider`` to reuse ``Document`` instances. - -Please note that this does not cache the result of the query, only the parsed ``Document``. - -.. code-block:: java - - Cache cache = Caffeine.newBuilder().maximumSize(10_000).build(); (1) - GraphQL graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) - .preparsedDocumentProvider(cache::get) (2) - .build(); - - -1. Create an instance of preferred cache instance, here is `Caffeine `_ used as it is a high quality caching solution. The cache instance should be thread safe and shared. -2. The ``PreparsedDocumentProvider`` is a functional interface with only a get method and we can therefore pass a method reference that matches the signature into the builder. - - -In order to achieve high cache hit ration it is recommended that field arguments are passed in as variables instead of directly in the query. - -The following query: - -.. code-block:: json - - query HelloTo { - sayHello(to: "Me") { - greeting - } - } - -Should be rewritten as: - -.. code-block:: json - - query HelloTo($to: String!) { - sayHello(to: $to) { - greeting - } - } - -with variables: - -.. code-block:: json - - { - "to": "Me" - } - -The query is now reused regardless of variable values provided. - diff --git a/docs/getting_started.rst b/docs/getting_started.rst deleted file mode 100644 index 6a63098e66..0000000000 --- a/docs/getting_started.rst +++ /dev/null @@ -1,111 +0,0 @@ -Getting started -=============== - -``graphql-java`` requires at least Java 8. - - -How to use the latest release with Gradle ------------------------------------------ - -Make sure ``mavenCentral`` is among your repos: - -.. code-block:: groovy - - repositories { - mavenCentral() - } - - -Dependency: - -.. code-block:: groovy - - dependencies { - compile 'com.graphql-java:graphql-java:9.0' - } - - -How to use the latest release with Maven ----------------------------------------- - -Dependency: - -.. code-block:: xml - - - com.graphql-java - graphql-java - 9.0 - - - -Hello World ------------ - -This is the famous "hello world" in ``graphql-java``: - -.. literalinclude:: ../src/test/java/HelloWorld.java - :language: java - - -Using the latest development build ----------------------------------- - -The latest development build is available on Bintray. - -Please look at `Latest Build `_ for the -latest version value. - - -How to use the latest build with Gradle -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Add the repositories: - -.. code-block:: groovy - - repositories { - mavenCentral() - maven { url "http://dl.bintray.com/andimarek/graphql-java" } - } - - -Dependency: - -.. code-block:: groovy - - dependencies { - compile 'com.graphql-java:graphql-java:INSERT_LATEST_VERSION_HERE' - } - - - -How to use the latest build with Maven -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - -Add the repository: - -.. code-block:: xml - - - - false - - bintray-andimarek-graphql-java - bintray - http://dl.bintray.com/andimarek/graphql-java - - -Dependency: - -.. code-block:: xml - - - com.graphql-java - graphql-java - INSERT_LATEST_VERSION_HERE - - - - diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index b3a017be1a..0000000000 --- a/docs/index.rst +++ /dev/null @@ -1,65 +0,0 @@ -Welcome to graphql-java -======================= - -.. image:: https://avatars1.githubusercontent.com/u/14289921?s=200&v=4 - :align: center - :height: 100px - :alt: graphql-java-logo - - -This is a GraphQL Java implementation based on the `specification `_ -and the JavaScript `reference implementation `_. - - -**Status**: Version ``9.0`` is released. - -Make sure to check out the `awesome related projects `_ built on ``graphql-java``. - - - -Code of Conduct ---------------- - -Please note that this project is released with a `Contributor Code of Conduct `_. -By contributing to this project (commenting or opening PR/Issues etc) you are agreeing to follow this conduct, so please -take the time to read it. - - -Questions and discussions -------------------------- - -If you have a question or want to discuss anything else related to this project: - -* Feel free to open a new `Issue `_ - -* We have a public chat room (Gitter.im) for graphql-java: https://gitter.im/graphql-java/graphql-java - - -License -------- - -graphql-java is licensed under the MIT License. - - -.. toctree:: - :maxdepth: 1 - :caption: Documentation - - Home - getting_started - schema - execution - mapping - scalars - subscriptions - defer - exceptions - sdldirecives - batching - instrumentation - relay - logging - concerns - contributions - - diff --git a/docs/instrumentation.rst b/docs/instrumentation.rst deleted file mode 100644 index 984091fe06..0000000000 --- a/docs/instrumentation.rst +++ /dev/null @@ -1,261 +0,0 @@ -Instrumentation -=============== - - -The ``graphql.execution.instrumentation.Instrumentation`` interface allows you to inject code that can observe the -execution of a query and also change the runtime behaviour. - -The primary use case for this is to allow say performance monitoring and custom logging but it could be used for many different purposes. - -When you build the ``Graphql`` object you can specify what ``Instrumentation`` to use (if any). - - -.. code-block:: java - - GraphQL.newGraphQL(schema) - .instrumentation(new TracingInstrumentation()) - .build(); - -Custom Instrumentation ----------------------- - -An implementation of ``Instrumentation`` needs to implement the "begin" step methods that represent the execution of a graphql query. - -Each step must give back a non null ``graphql.execution.instrumentation.InstrumentationContext`` object which will be called back -when the step completes, and will be told that it succeeded or failed with a Throwable. - -The following is a basic custom ``Instrumentation`` that measures overall execution time and puts it into a stateful object. - -.. code-block:: java - - class CustomInstrumentationState implements InstrumentationState { - private Map anyStateYouLike = new HashMap<>(); - - void recordTiming(String key, long time) { - anyStateYouLike.put(key, time); - } - } - - class CustomInstrumentation extends SimpleInstrumentation { - @Override - public InstrumentationState createState() { - // - // instrumentation state is passed during each invocation of an Instrumentation method - // and allows you to put stateful data away and reference it during the query execution - // - return new CustomInstrumentationState(); - } - - @Override - public InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters) { - long startNanos = System.nanoTime(); - return new SimpleInstrumentationContext() { - @Override - public void onCompleted(ExecutionResult result, Throwable t) { - CustomInstrumentationState state = parameters.getInstrumentationState(); - state.recordTiming(parameters.getQuery(), System.nanoTime() - startNanos); - } - }; - } - - @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - // - // this allows you to intercept the data fetcher used to fetch a field and provide another one, perhaps - // that enforces certain behaviours or has certain side effects on the data - // - return dataFetcher; - } - - @Override - public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { - // - // this allows you to instrument the execution result some how. For example the Tracing support uses this to put - // the `extensions` map of data in place - // - return CompletableFuture.completedFuture(executionResult); - } - } - -Chaining Instrumentation ------------------------- - -You can combine multiple ``Instrumentation`` objects together using the ``graphql.execution.instrumentation.ChainedInstrumentation`` class which -accepts a list of ``Instrumentation`` objects and calls them in that defined order. - -.. code-block:: java - - List chainedList = new ArrayList<>(); - chainedList.add(new FooInstrumentation()); - chainedList.add(new BarInstrumentation()); - ChainedInstrumentation chainedInstrumentation = new ChainedInstrumentation(chainedList); - - GraphQL.newGraphQL(schema) - .instrumentation(chainedInstrumentation) - .build(); - - - -Apollo Tracing Instrumentation ------------------------------- - -``graphql.execution.instrumentation.tracing.TracingInstrumentation`` is an ``Instrumentation`` implementation that creates tracing information -about the query that is being executed. - -It follows the Apollo proposed tracing format defined at `https://github.com/apollographql/apollo-tracing `_ - -A detailed tracing map will be created and placed in the ``extensions`` section of the result. - -So given a query like - -.. code-block:: graphql - - query { - hero { - name - friends { - name - } - } - } - -It would return a result like - -.. code-block:: json - - { - "data": { - "hero": { - "name": "R2-D2", - "friends": [ - { - "name": "Luke Skywalker" - }, - { - "name": "Han Solo" - }, - { - "name": "Leia Organa" - } - ] - } - }, - "extensions": { - "tracing": { - "version": 1, - "startTime": "2017-08-14T23:13:39.362Z", - "endTime": "2017-08-14T23:13:39.497Z", - "duration": 135589186, - "execution": { - "resolvers": [ - { - "path": [ - "hero" - ], - "parentType": "Query", - "returnType": "Character", - "fieldName": "hero", - "startOffset": 105697585, - "duration": 79111240 - }, - { - "path": [ - "hero", - "name" - ], - "parentType": "Droid", - "returnType": "String", - "fieldName": "name", - "startOffset": 125010028, - "duration": 20213 - }, - { - "path": [ - "hero", - "friends" - ], - "parentType": "Droid", - "returnType": "[Character]", - "fieldName": "friends", - "startOffset": 133352819, - "duration": 7927560 - }, - { - "path": [ - "hero", - "friends", - 0, - "name" - ], - "parentType": "Human", - "returnType": "String", - "fieldName": "name", - "startOffset": 134105887, - "duration": 6783 - }, - { - "path": [ - "hero", - "friends", - 1, - "name" - ], - "parentType": "Human", - "returnType": "String", - "fieldName": "name", - "startOffset": 134725922, - "duration": 7016 - }, - { - "path": [ - "hero", - "friends", - 2, - "name" - ], - "parentType": "Human", - "returnType": "String", - "fieldName": "name", - "startOffset": 134875089, - "duration": 6342 - } - ] - } - } - } - } - -Field Validation Instrumentation --------------------------------- - -``graphql.execution.instrumentation.fieldvalidation.FieldValidationInstrumentation`` is an ``Instrumentation`` implementation that -can be used to validate fields and their arguments before query execution. If errors are returned during this process then -the query execution is aborted and the errors will be in the query result. - -You can make you own custom implementation of ``FieldValidation`` or you can use the ``SimpleFieldValidation`` class -to add simple per field checks rules. - - -.. code-block:: java - - ExecutionPath fieldPath = ExecutionPath.parse("/user"); - FieldValidation fieldValidation = new SimpleFieldValidation() - .addRule(fieldPath, new BiFunction>() { - @Override - public Optional apply(FieldAndArguments fieldAndArguments, FieldValidationEnvironment environment) { - String nameArg = fieldAndArguments.getFieldArgument("name"); - if (nameArg.length() > 255) { - return Optional.of(environment.mkError("Invalid user name", fieldAndArguments)); - } - return Optional.empty(); - } - }); - - FieldValidationInstrumentation instrumentation = new FieldValidationInstrumentation( - fieldValidation - ); - - GraphQL.newGraphQL(schema) - .instrumentation(instrumentation) - .build(); - diff --git a/docs/locale/en/LC_MESSAGES/batching.po b/docs/locale/en/LC_MESSAGES/batching.po deleted file mode 100644 index d704bf62ac..0000000000 --- a/docs/locale/en/LC_MESSAGES/batching.po +++ /dev/null @@ -1,150 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../batching.rst:2 -msgid "Using Dataloader" -msgstr "" - -#: ../../batching.rst:4 -msgid "" -"If you are using ``graphql``, you are likely to making queries on a graph" -" of data (surprise surprise). But its easy to implement inefficient code" -" with naive loading of a graph of data." -msgstr "" - -#: ../../batching.rst:7 -msgid "" -"Using ``java-dataloader`` will help you to make this a more efficient " -"process by both caching and batching requests for that graph of data " -"items. If ``dataloader`` has seen a data item before, it will have " -"cached the value and will return it without having to ask for it again." -msgstr "" - -#: ../../batching.rst:10 -msgid "" -"Imagine we have the StarWars query outlined below. It asks us to find a " -"hero and their friend's names and their friend's friend's names. It is " -"likely that many of these people will be friends in common." -msgstr "" - -#: ../../batching.rst:28 -msgid "" -"The result of this query is displayed below. You can see that Han, Leia, " -"Luke and R2-D2 are a tight knit bunch of friends and share many friends " -"in common." -msgstr "" - -#: ../../batching.rst:42 -msgid "" -"A naive implementation would called a `DataFetcher` to retrieved a person" -" object every time it was invoked." -msgstr "" - -#: ../../batching.rst:44 -msgid "" -"In this case it would be *15* calls over the network. Even though the " -"group of people have a lot of common friends. With `dataloader` you can " -"make the `graphql` query much more efficient." -msgstr "" - -#: ../../batching.rst:47 -msgid "" -"As `graphql` descends each level of the query ( eg as it processes `hero`" -" and then `friends` and then for each their `friends`), the data loader " -"is called to \"promise\" to deliver a person object. At each level " -"`dataloader.dispatch()` will be called to fire off the batch requests for" -" that part of the query. With caching turned on (the default) then any " -"previously returned person will be returned as is for no cost." -msgstr "" - -#: ../../batching.rst:52 -msgid "" -"In the above example there are only *5* unique people mentioned but with " -"caching and batching retrieval in place their will be only *3* calls to " -"the batch loader function. *3* calls over the network or to a database " -"is much better than *15* calls you will agree." -msgstr "" - -#: ../../batching.rst:55 -msgid "" -"If you use capabilities like " -"`java.util.concurrent.CompletableFuture.supplyAsync()` then you can make " -"it even more efficient by making the the remote calls asynchronous to the" -" rest of the query. This will make it even more timely since multiple " -"calls can happen at once if need be." -msgstr "" - -#: ../../batching.rst:59 -msgid "Here is how you might put this in place:" -msgstr "" - -#: ../../batching.rst:121 -msgid "```" -msgstr "" - -#: ../../batching.rst:123 -msgid "" -"One thing to note is the above only works if you use " -"`DataLoaderDispatcherInstrumentation` which makes sure " -"`dataLoader.dispatch()` is called. If this was not in place, then all " -"the promises to data will never be dispatched ot the batch loader " -"function and hence nothing would ever resolve." -msgstr "" - -#: ../../batching.rst:128 -msgid "Per Request Data Loaders" -msgstr "" - -#: ../../batching.rst:130 -msgid "" -"If you are serving web requests then the data can be specific to the user" -" requesting it. If you have user specific data then you will not want to " -"cache data meant for user A to then later give it to user B in a " -"subsequent request." -msgstr "" - -#: ../../batching.rst:133 -msgid "" -"The scope of your DataLoader instances is important. You might want to " -"create them per web request to ensure data is only cached within that web" -" request and no more." -msgstr "" - -#: ../../batching.rst:136 -msgid "" -"If your data can be shared across web requests then you might want to " -"scope your data loaders so they survive longer than the web request say." -msgstr "" - -#: ../../batching.rst:139 -msgid "" -"But if you are doing per request data loaders then creating a new set of " -"``GraphQL`` and ``DataLoader`` objects per request is super cheap. Its " -"the ``GraphQLSchema`` creation that can be expensive, especially if you " -"are using graphql SDL parsing." -msgstr "" - -#: ../../batching.rst:142 -msgid "" -"Structure your code so that the schema is statically held, perhaps in a " -"static variable or in a singleton IoC component but build out a new " -"``GraphQL`` set of objects on each request." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/concerns.po b/docs/locale/en/LC_MESSAGES/concerns.po deleted file mode 100644 index b2fe935694..0000000000 --- a/docs/locale/en/LC_MESSAGES/concerns.po +++ /dev/null @@ -1,111 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../concerns.rst:2 -msgid "Application concerns" -msgstr "" - -#: ../../concerns.rst:4 -msgid "" -"The graphql-java library concentrates on providing an engine for the " -"execution of queries according to the specification." -msgstr "" - -#: ../../concerns.rst:6 -msgid "" -"It does not concern itself about other high level application concerns " -"such as the following :" -msgstr "" - -#: ../../concerns.rst:8 -msgid "Database access" -msgstr "" - -#: ../../concerns.rst:9 -msgid "Caching data" -msgstr "" - -#: ../../concerns.rst:10 -msgid "Data authorisation" -msgstr "" - -#: ../../concerns.rst:11 -msgid "Data pagination" -msgstr "" - -#: ../../concerns.rst:12 -msgid "HTTP transfer" -msgstr "" - -#: ../../concerns.rst:13 -msgid "JSON endoding" -msgstr "" - -#: ../../concerns.rst:14 -msgid "Code wiring via dependency injection" -msgstr "" - -#: ../../concerns.rst:16 -msgid "You need to push these concerns into your business logic layers." -msgstr "" - -#: ../../concerns.rst:18 -msgid "The following are great links to read more about this" -msgstr "" - -#: ../../concerns.rst:20 -msgid "http://graphql.org/learn/serving-over-http/" -msgstr "" - -#: ../../concerns.rst:21 -msgid "http://graphql.org/learn/authorization/" -msgstr "" - -#: ../../concerns.rst:22 -msgid "http://graphql.org/learn/pagination/" -msgstr "" - -#: ../../concerns.rst:23 -msgid "http://graphql.org/learn/caching/" -msgstr "" - -#: ../../concerns.rst:26 -msgid "Context Objects" -msgstr "" - -#: ../../concerns.rst:28 -msgid "" -"You can pass in a context object during query execution that will allow " -"you to better invoke that business logic." -msgstr "" - -#: ../../concerns.rst:30 -msgid "" -"For example the edge of your application could be performing user " -"detection and you need that information inside the graphql execution to " -"perform authorisation." -msgstr "" - -#: ../../concerns.rst:33 -msgid "" -"This made up example shows how you can pass yourself information to help " -"execute your queries." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/contributions.po b/docs/locale/en/LC_MESSAGES/contributions.po deleted file mode 100644 index 87a461b9fd..0000000000 --- a/docs/locale/en/LC_MESSAGES/contributions.po +++ /dev/null @@ -1,92 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../contributions.rst:2 -msgid "Contributions" -msgstr "" - -#: ../../contributions.rst:4 -msgid "Every contribution to make this project better is welcome: Thank you!" -msgstr "" - -#: ../../contributions.rst:6 -msgid "" -"In order to make this a pleasant as possible for everybody involved, here" -" are some tips:" -msgstr "" - -#: ../../contributions.rst:8 -msgid "Respect the [Code of Conduct](#code-of-conduct)" -msgstr "" - -#: ../../contributions.rst:10 -msgid "" -"Before opening an Issue to report a bug, please try the latest " -"development version. It can happen that the problem is already solved." -msgstr "" - -#: ../../contributions.rst:12 -msgid "" -"Please use Markdown to format your comments properly. If you are not " -"familiar with that: `Getting started with writing and formatting on " -"GitHub `_" -msgstr "" - -#: ../../contributions.rst:14 -msgid "" -"For Pull Requests: * Here are some `general tips " -"`_" -msgstr "" - -#: ../../contributions.rst:17 -msgid "" -"Please be a as focused and clear as possible and don't mix concerns. " -"This includes refactorings mixed with bug-fixes/features, see [Open " -"Source Contribution " -"Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html)" -msgstr "" - -#: ../../contributions.rst:19 -msgid "" -"It would be good to add a automatic test. All tests are written in `Spock" -" `_." -msgstr "" - -#: ../../contributions.rst:23 -msgid "Build and test locally" -msgstr "" - -#: ../../contributions.rst:25 -msgid "Just clone the repo and type" -msgstr "" - -#: ../../contributions.rst:31 -msgid "In ``build/libs`` you will find the jar file." -msgstr "" - -#: ../../contributions.rst:33 -msgid "Running the tests:" -msgstr "" - -#: ../../contributions.rst:39 -msgid "Installing in the local Maven repository:" -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/exceptions.po b/docs/locale/en/LC_MESSAGES/exceptions.po deleted file mode 100644 index 7b1c0c2f0e..0000000000 --- a/docs/locale/en/LC_MESSAGES/exceptions.po +++ /dev/null @@ -1,125 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../exceptions.rst:2 -msgid "Runtime Exceptions" -msgstr "" - -#: ../../exceptions.rst:5 -msgid "" -"Runtime exceptions can be thrown by the graphql engine if certain " -"exceptional situations are encountered. The following are a list of the " -"exceptions that can be thrown all the way out of a " -"``graphql.execute(...)`` call." -msgstr "" - -#: ../../exceptions.rst:8 -msgid "" -"These are not graphql errors in execution but rather totally unacceptable" -" conditions in which to execute a graphql query." -msgstr "" - -#: ../../exceptions.rst:10 -msgid "`graphql.schema.CoercingSerializeException`" -msgstr "" - -#: ../../exceptions.rst:12 -msgid "" -"is thrown when a value cannot be serialised by a Scalar type, for example" -" a String value being coerced as an Int." -msgstr "" - -#: ../../exceptions.rst:16 -msgid "`graphql.schema.CoercingParseValueException`" -msgstr "" - -#: ../../exceptions.rst:18 -msgid "" -"is thrown when a value cannot be parsed by a Scalar type, for example a " -"String input value being parsed as an Int." -msgstr "" - -#: ../../exceptions.rst:22 -msgid "`graphql.execution.UnresolvedTypeException`" -msgstr "" - -#: ../../exceptions.rst:24 -msgid "" -"is thrown if a graphql.schema.TypeResolver` fails to provide a concrete " -"object type given a interface or union type." -msgstr "" - -#: ../../exceptions.rst:28 -msgid "`graphql.execution.NonNullableValueCoercedAsNullException`" -msgstr "" - -#: ../../exceptions.rst:30 -msgid "" -"is thrown if a non null variable argument is coerced as a null value " -"during execution." -msgstr "" - -#: ../../exceptions.rst:34 -msgid "`graphql.execution.InputMapDefinesTooManyFieldsException`" -msgstr "" - -#: ../../exceptions.rst:36 -msgid "" -"is thrown if a map used for an input type object contains more keys than " -"is defined in that input type." -msgstr "" - -#: ../../exceptions.rst:40 -msgid "`graphql.schema.validation.InvalidSchemaException`" -msgstr "" - -#: ../../exceptions.rst:44 -msgid "is thrown if the schema is not valid when built via" -msgstr "" - -#: ../../exceptions.rst:43 -msgid "graphql.schema.GraphQLSchema.Builder#build()`" -msgstr "" - -#: ../../exceptions.rst:46 -msgid "`graphql.GraphQLException`" -msgstr "" - -#: ../../exceptions.rst:48 -msgid "" -"is thrown as a general purpose runtime exception, for example if the code" -" cant access a named field when examining a POJO, it is analogous to a " -"RuntimeException if you will." -msgstr "" - -#: ../../exceptions.rst:52 -msgid "`graphql.AssertException`" -msgstr "" - -#: ../../exceptions.rst:54 -msgid "" -"is thrown as a low level code assertion exception for truly unexpected " -"code conditions, things we assert" -msgstr "" - -#: ../../exceptions.rst:55 -msgid "should never happen in practice." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/execution.po b/docs/locale/en/LC_MESSAGES/execution.po deleted file mode 100644 index cc4a2abfbe..0000000000 --- a/docs/locale/en/LC_MESSAGES/execution.po +++ /dev/null @@ -1,549 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../execution.rst:2 -msgid "Execution" -msgstr "" - -#: ../../execution.rst:5 -msgid "Queries" -msgstr "" - -#: ../../execution.rst:7 -msgid "" -"To execute a query against a schema, build a new ``GraphQL`` object with " -"the appropriate arguments and then call ``execute()``." -msgstr "" - -#: ../../execution.rst:10 -msgid "" -"The result of a query is an ``ExecutionResult`` which is the query data " -"and/or a list of errors." -msgstr "" - -#: ../../execution.rst:30 -msgid "" -"More complex query examples can be found in the `StarWars query tests " -"`_" -msgstr "" - -#: ../../execution.rst:34 -msgid "Data Fetchers" -msgstr "" - -#: ../../execution.rst:36 -msgid "" -"Each graphql field type has a ``graphql.schema.DataFetcher`` associated " -"with it. Other graphql implementations often call this type of code " -"*resolvers**." -msgstr "" - -#: ../../execution.rst:39 -msgid "" -"Often you can rely on ``graphql.schema.PropertyDataFetcher`` to examine " -"Java POJO objects to provide field values from them. If your don't " -"specify a data fetcher on a field, this is what will be used." -msgstr "" - -#: ../../execution.rst:42 -msgid "" -"However you will need to fetch your top level domain objects via your own" -" custom data fetchers. This might involve making a database call or " -"contacting another system over HTTP say." -msgstr "" - -#: ../../execution.rst:45 -msgid "" -"``graphql-java`` is not opinionated about how you get your domain data " -"objects, that is very much your concern. It is also not opinionated on " -"user authorisation to that data. You should push all that logic into " -"your business logic layer code." -msgstr "" - -#: ../../execution.rst:48 -msgid "A data fetcher might look like this:" -msgstr "" - -#: ../../execution.rst:59 -msgid "" -"Each ``DataFetcher`` is passed a " -"``graphql.schema.DataFetchingEnvironment`` object which contains what " -"field is being fetched, what arguments have been supplied to the field " -"and other information such as the field's parent object, the query root " -"object or the query context object." -msgstr "" - -#: ../../execution.rst:63 -msgid "" -"In the above example, the execution will wait for the data fetcher to " -"return before moving on. You can make execution of the ``DataFetcher`` " -"asynchronous by returning a ``CompletionStage`` to data, that is " -"explained more further down this page." -msgstr "" - -#: ../../execution.rst:67 -msgid "Exceptions while fetching data" -msgstr "" - -#: ../../execution.rst:69 -msgid "" -"If an exception happens during the data fetcher call, then the execution " -"strategy by default will make a ``graphql.ExceptionWhileDataFetching`` " -"error and add it to the list of errors on the result. Remember graphql " -"allows partial results with errors." -msgstr "" - -#: ../../execution.rst:73 -msgid "Here is the code for the standard behaviour." -msgstr "" - -#: ../../execution.rst:92 -msgid "" -"If the exception you throw is itself a `GraphqlError` then it will " -"transfer the message and custom extensions attributes from that exception" -" into the `ExceptionWhileDataFetching` object. This allows you to place " -"your own custom attributes into the graphql error that is sent back to " -"the caller." -msgstr "" - -#: ../../execution.rst:96 -msgid "" -"For example imagine your data fetcher threw this exception. The `foo` " -"and `fizz` attributes would be included in the resultant graphql error." -msgstr "" - -#: ../../execution.rst:122 -msgid "" -"You can change this behaviour by creating your own " -"``graphql.execution.DataFetcherExceptionHandler`` exception handling code" -" and giving that to the execution strategy." -msgstr "" - -#: ../../execution.rst:125 -msgid "" -"For example the code above records the underlying exception and stack " -"trace. Some people may prefer not to see that in the output error list." -" So you can use this mechanism to change that behaviour." -msgstr "" - -#: ../../execution.rst:141 -msgid "Serializing results to JSON" -msgstr "" - -#: ../../execution.rst:143 -msgid "" -"The most common way to call graphql is over HTTP and to expect a JSON " -"response back. So you need to turn an `graphql.ExecutionResult` into a " -"JSON payload." -msgstr "" - -#: ../../execution.rst:146 -msgid "" -"A common way to do that is use a JSON serialisation library like Jackson " -"or GSON. However exactly how they interpret the data result is " -"particular to them. For example `nulls` are important in graphql results" -" and hence you must set up the json mappers to include them." -msgstr "" - -#: ../../execution.rst:150 -msgid "" -"To ensure you get a JSON result that confirms 100% to the graphql spec, " -"you should call `toSpecification` on the result and then send that back " -"as JSON." -msgstr "" - -#: ../../execution.rst:153 -msgid "" -"This will ensure that the result follows the specification outlined in " -"http://facebook.github.io/graphql/#sec-Response" -msgstr "" - -#: ../../execution.rst:167 -msgid "Mutations" -msgstr "" - -#: ../../execution.rst:169 -msgid "" -"A good starting point to learn more about mutating data in graphql is " -"`http://graphql.org/learn/queries/#mutations " -"`_." -msgstr "" - -#: ../../execution.rst:171 -msgid "" -"In essence you need to define a ``GraphQLObjectType`` that takes " -"arguments as input. Those arguments are what you can use to mutate your " -"data store via the data fetcher invoked." -msgstr "" - -#: ../../execution.rst:174 -msgid "The mutation is invoked via a query like :" -msgstr "" - -#: ../../execution.rst:185 -msgid "" -"You need to send in arguments during that mutation operation, in this " -"case for the variables for ``$ep`` and ``$review``" -msgstr "" - -#: ../../execution.rst:187 -msgid "You would create types like this to handle this mutation :" -msgstr "" - -#: ../../execution.rst:241 -msgid "" -"Notice that the input arguments are of type ``GraphQLInputObjectType``. " -"This is important. Input arguments can ONLY be of that type and you " -"cannot use output types such as ``GraphQLObjectType``. Scalars types are" -" consider both input and output types." -msgstr "" - -#: ../../execution.rst:244 -msgid "" -"The data fetcher here is responsible for executing the mutation and " -"returning some sensible output values." -msgstr "" - -#: ../../execution.rst:277 -msgid "" -"Notice how it calls a data store to mutate the backing database and then " -"returns a ``Review`` object that can be used as the output values to the " -"caller." -msgstr "" - -#: ../../execution.rst:281 -msgid "Asynchronous Execution" -msgstr "" - -#: ../../execution.rst:283 -msgid "" -"graphql-java uses fully asynchronous execution techniques when it " -"executes queries. You can get the ``CompleteableFuture`` to results by " -"calling ``executeAsync()`` like this" -msgstr "" - -#: ../../execution.rst:302 -msgid "" -"The use of ``CompletableFuture`` allows you to compose actions and " -"functions that will be applied when the execution completes. The final " -"call to ``.join()`` waits for the execution to happen." -msgstr "" - -#: ../../execution.rst:305 -msgid "" -"In fact under the covers, the graphql-java engine uses asynchronous " -"execution and makes the ``.execute()`` method appear synchronous by " -"calling join for you. So the following code is in fact the same." -msgstr "" - -#: ../../execution.rst:319 -msgid "" -"If a ``graphql.schema.DataFetcher`` returns a ``CompletableFuture`` " -"object then this will be composed into the overall asynchronous query " -"execution. This means you can fire off a number of field fetching " -"requests in parallel. Exactly what threading strategy you use is up to " -"your data fetcher code." -msgstr "" - -#: ../../execution.rst:323 -msgid "" -"The following code uses the standard Java " -"``java.util.concurrent.ForkJoinPool.commonPool()`` thread executor to " -"supply values in another thread." -msgstr "" - -#: ../../execution.rst:338 -msgid "" -"The code above is written in long form. With Java 8 lambdas it can be " -"written more succinctly as follows" -msgstr "" - -#: ../../execution.rst:345 -msgid "" -"The graphql-java engine ensures that all the ``CompletableFuture`` " -"objects are composed together to provide an execution result that follows" -" the graphql specification." -msgstr "" - -#: ../../execution.rst:348 -msgid "" -"There is a helpful shortcut in graphql-java to create asynchronous data " -"fetchers. Use ``graphql.schema.AsyncDataFetcher.async(DataFetcher)`` " -"to wrap a ``DataFetcher``. This can be used with static imports to " -"produce more readable code." -msgstr "" - -#: ../../execution.rst:357 -msgid "Execution Strategies" -msgstr "" - -#: ../../execution.rst:359 -msgid "" -"A class derived from ``graphql.execution.ExecutionStrategy`` is used to " -"run a query or mutation. A number of different strategies are provided " -"with graphql-java and if you are really keen you can even write your own." -msgstr "" - -#: ../../execution.rst:362 -msgid "" -"You can wire in what execution strategy to use when you create the " -"``GraphQL`` object." -msgstr "" - -#: ../../execution.rst:372 -msgid "" -"In fact the code above is equivalent to the default settings and is a " -"very sensible choice of execution strategies for most cases." -msgstr "" - -#: ../../execution.rst:376 -msgid "AsyncExecutionStrategy" -msgstr "" - -#: ../../execution.rst:378 -msgid "" -"By default the \"query\" execution strategy is " -"``graphql.execution.AsyncExecutionStrategy`` which will dispatch each " -"field as ``CompleteableFuture`` objects and not care which ones complete " -"first. This strategy allows for the most performant execution." -msgstr "" - -#: ../../execution.rst:382 -msgid "" -"The data fetchers invoked can themselves return `CompletionStage`` values" -" and this will create fully asynchronous behaviour." -msgstr "" - -#: ../../execution.rst:385 -msgid "So imagine a query as follows" -msgstr "" - -#: ../../execution.rst:401 -msgid "" -"The ``AsyncExecutionStrategy`` is free to dispatch the *enemies* field at" -" the same time as the *friends* field. It does not have to do *enemies* " -"first followed by *friends*, which would be less efficient." -msgstr "" - -#: ../../execution.rst:404 -msgid "" -"It will however assemble the results in order. The query result will " -"follow the graphql specification and return object values assembled in " -"query field order. Only the execution of data fetching is free to be in " -"any order." -msgstr "" - -#: ../../execution.rst:407 -msgid "" -"This behaviour is allowed in the graphql specification and in fact is " -"actively encouraged http://facebook.github.io/graphql/#sec-Query for read" -" only queries." -msgstr "" - -#: ../../execution.rst:410 -msgid "" -"See `specification `_ for details." -msgstr "" - -#: ../../execution.rst:414 -msgid "AsyncSerialExecutionStrategy" -msgstr "" - -#: ../../execution.rst:416 -msgid "" -"The graphql specification says that mutations MUST be executed serially " -"and in the order in which the query fields occur." -msgstr "" - -#: ../../execution.rst:419 -msgid "" -"So ``graphql.execution.AsyncSerialExecutionStrategy`` is used by default " -"for mutations and will ensure that each field is completed before it " -"processes the next one and so forth. You can still return " -"``CompletionStage`` objects in the mutation data fetchers, however they " -"will be executed serially and will be completed before the next mutation " -"field data fetcher is dispatched." -msgstr "" - -#: ../../execution.rst:425 -msgid "ExecutorServiceExecutionStrategy" -msgstr "" - -#: ../../execution.rst:427 -msgid "" -"The ``graphql.execution.ExecutorServiceExecutionStrategy`` execution " -"strategy will always dispatch each field fetch in an asynchronous manner," -" using the executor you give it. It differs from " -"``AsyncExecutionStrategy`` in that it does not rely on the data fetchers " -"to be asynchronous but rather makes the field fetch invocation " -"asynchronous by submitting each field to the provided " -"`java.util.concurrent.ExecutorService`." -msgstr "" - -#: ../../execution.rst:432 -msgid "" -"This behaviour makes it unsuitable to be used as a mutation execution " -"strategy." -msgstr "" - -#: ../../execution.rst:450 -msgid "SubscriptionExecutionStrategy" -msgstr "" - -#: ../../execution.rst:452 -msgid "" -"Graphql subscriptions allows you to create stateful subscriptions to " -"graphql data. You uses ``SubscriptionExecutionStrategy`` as your " -"execution strategy as it has the support for the reactive-streams APIs." -msgstr "" - -#: ../../execution.rst:455 -msgid "" -"See http://www.reactive-streams.org/ for more information on the reactive" -" ``Publisher`` and ``Subscriber`` interfaces." -msgstr "" - -#: ../../execution.rst:457 -msgid "" -"Also see the page on subscriptions for more details on how to write a " -"subscription based graphql service." -msgstr "" - -#: ../../execution.rst:461 -msgid "BatchedExecutionStrategy" -msgstr "" - -#: ../../execution.rst:463 -msgid "" -"Alternatively, schemas with nested lists may benefit from using a " -"``graphql.execution.batched.BatchedExecutionStrategy`` and creating " -"batched DataFetchers with get() methods annotated @Batched." -msgstr "" - -#: ../../execution.rst:468 -msgid "" -"on how BatchedExecutionStrategy works here. Its a pretty special case " -"that I don't know how to explain properly" -msgstr "" - -#: ../../execution.rst:471 -msgid "Limiting Field Visibility" -msgstr "" - -#: ../../execution.rst:473 -msgid "" -"By default every fields defined in a `GraphqlSchema` is available. There" -" are cases where you may want to restrict certain fields depending on the" -" user." -msgstr "" - -#: ../../execution.rst:476 -msgid "" -"You can do this by using a " -"`graphql.schema.visibility.GraphqlFieldVisibility` implementation and " -"attaching it to the schema." -msgstr "" - -#: ../../execution.rst:478 -msgid "" -"A simple `graphql.schema.visibility.BlockedFields` implementation based " -"on fully qualified field name is provided." -msgstr "" - -#: ../../execution.rst:493 -msgid "" -"There is also another implementation that prevents instrumentation from " -"being able to be performed on your schema, if that is a requirement." -msgstr "" - -#: ../../execution.rst:495 -msgid "" -"Note that this puts your server in contravention of the graphql " -"specification and expectations of most clients so use this with caution." -msgstr "" - -#: ../../execution.rst:506 -msgid "" -"You can create your own derivation of `GraphqlFieldVisibility` to check " -"what ever you need to do to work out what fields should be visible or " -"not." -msgstr "" - -#: ../../execution.rst:542 -msgid "Query Caching" -msgstr "" - -#: ../../execution.rst:544 -msgid "" -"Before the ``graphql-java`` engine executes a query it must be parsed and" -" validated, and this process can be somewhat time consuming." -msgstr "" - -#: ../../execution.rst:546 -msgid "" -"To avoid the need for re-parse/validate the ``GraphQL.Builder`` allows an" -" instance of ``PreparsedDocumentProvider`` to reuse ``Document`` " -"instances." -msgstr "" - -#: ../../execution.rst:548 -msgid "" -"Please note that this does not cache the result of the query, only the " -"parsed ``Document``." -msgstr "" - -#: ../../execution.rst:558 -msgid "" -"Create an instance of preferred cache instance, here is `Caffeine " -"`_ used as it is a high quality " -"caching solution. The cache instance should be thread safe and shared." -msgstr "" - -#: ../../execution.rst:559 -msgid "" -"The ``PreparsedDocumentProvider`` is a functional interface with only a " -"get method and we can therefore pass a method reference that matches the " -"signature into the builder." -msgstr "" - -#: ../../execution.rst:562 -msgid "" -"In order to achieve high cache hit ration it is recommended that field " -"arguments are passed in as variables instead of directly in the query." -msgstr "" - -#: ../../execution.rst:564 -msgid "The following query:" -msgstr "" - -#: ../../execution.rst:574 -msgid "Should be rewritten as:" -msgstr "" - -#: ../../execution.rst:584 -msgid "with variables:" -msgstr "" - -#: ../../execution.rst:592 -msgid "The query is now reused regardless of variable values provided." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/getting_started.po b/docs/locale/en/LC_MESSAGES/getting_started.po deleted file mode 100644 index 060a1748e1..0000000000 --- a/docs/locale/en/LC_MESSAGES/getting_started.po +++ /dev/null @@ -1,83 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../getting_started.rst:2 -msgid "Getting started" -msgstr "" - -#: ../../getting_started.rst:4 -msgid "``graphql-java`` requires at least Java 8." -msgstr "" - -#: ../../getting_started.rst:8 -msgid "How to use the latest release with Gradle" -msgstr "" - -#: ../../getting_started.rst:10 -msgid "Make sure ``mavenCentral`` is among your repos:" -msgstr "" - -#: ../../getting_started.rst:19 ../../getting_started.rst:31 -#: ../../getting_started.rst:73 ../../getting_started.rst:100 -msgid "Dependency:" -msgstr "" - -#: ../../getting_started.rst:29 -msgid "How to use the latest release with Maven" -msgstr "" - -#: ../../getting_started.rst:43 -msgid "Hello World" -msgstr "" - -#: ../../getting_started.rst:45 -msgid "This is the famous \"hello world\" in ``graphql-java``:" -msgstr "" - -#: ../../getting_started.rst:52 -msgid "Using the latest development build" -msgstr "" - -#: ../../getting_started.rst:54 -msgid "The latest development build is available on Bintray." -msgstr "" - -#: ../../getting_started.rst:56 -msgid "" -"Please look at `Latest Build `_ for the latest version value." -msgstr "" - -#: ../../getting_started.rst:61 -msgid "How to use the latest build with Gradle" -msgstr "" - -#: ../../getting_started.rst:63 -msgid "Add the repositories:" -msgstr "" - -#: ../../getting_started.rst:84 -msgid "How to use the latest build with Maven" -msgstr "" - -#: ../../getting_started.rst:87 -msgid "Add the repository:" -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/index.po b/docs/locale/en/LC_MESSAGES/index.po deleted file mode 100644 index 77ba69debc..0000000000 --- a/docs/locale/en/LC_MESSAGES/index.po +++ /dev/null @@ -1,88 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../index.rst:2 -msgid "Welcome to graphql-java" -msgstr "" - -#: ../../index.rst:10 -msgid "" -"This is a GraphQL Java implementation based on the `specification " -"`_ and the JavaScript `reference " -"implementation `_." -msgstr "" - -#: ../../index.rst:14 -msgid "**Status**: Version ``6.0`` is released." -msgstr "" - -#: ../../index.rst:16 -msgid "" -"Make sure to check out the `awesome related projects `_ built on ``graphql-java``." -msgstr "" - -#: ../../index.rst:21 -msgid "Code of Conduct" -msgstr "" - -#: ../../index.rst:23 -msgid "" -"Please note that this project is released with a `Contributor Code of " -"Conduct `_. By contributing to this project " -"(commenting or opening PR/Issues etc) you are agreeing to follow this " -"conduct, so please take the time to read it." -msgstr "" - -#: ../../index.rst:29 -msgid "Questions and discussions" -msgstr "" - -#: ../../index.rst:31 -msgid "" -"If you have a question or want to discuss anything else related to this " -"project:" -msgstr "" - -#: ../../index.rst:33 -msgid "" -"Feel free to open a new `Issue `_" -msgstr "" - -#: ../../index.rst:35 -msgid "" -"We have a public chat room (Gitter.im) for graphql-java: " -"https://gitter.im/graphql-java/graphql-java" -msgstr "" - -#: ../../index.rst:39 -msgid "License" -msgstr "" - -#: ../../index.rst:41 -msgid "graphql-java is licensed under the MIT License." -msgstr "" - -#: ../../index.rst:44 -msgid "Documentation" -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/instrumentation.po b/docs/locale/en/LC_MESSAGES/instrumentation.po deleted file mode 100644 index 99ce24cd31..0000000000 --- a/docs/locale/en/LC_MESSAGES/instrumentation.po +++ /dev/null @@ -1,131 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../instrumentation.rst:2 -msgid "Instrumentation" -msgstr "" - -#: ../../instrumentation.rst:5 -msgid "" -"The ``graphql.execution.instrumentation.Instrumentation`` interface " -"allows you to inject code that can observe the execution of a query and " -"also change the runtime behaviour." -msgstr "" - -#: ../../instrumentation.rst:8 -msgid "" -"The primary use case for this is to allow say performance monitoring and " -"custom logging but it could be used for many different purposes." -msgstr "" - -#: ../../instrumentation.rst:10 -msgid "" -"When you build the ```Graphql`` object you can specify what " -"``Instrumentation`` to use (if any)." -msgstr "" - -#: ../../instrumentation.rst:20 -msgid "Custom Instrumentation" -msgstr "" - -#: ../../instrumentation.rst:22 -msgid "" -"An implementation of ``Instrumentation`` needs to implement the \"begin\"" -" step methods that represent the execution of a graphql query." -msgstr "" - -#: ../../instrumentation.rst:24 -msgid "" -"Each step must give back a non null " -"``graphql.execution.instrumentation.InstrumentationContext`` object which" -" will be called back when the step completes, and will be told that it " -"succeeded or failed with a Throwable." -msgstr "" - -#: ../../instrumentation.rst:27 -msgid "" -"The following is a basic custom ``Instrumentation`` that measures overall" -" execution time and puts it into a stateful object." -msgstr "" - -#: ../../instrumentation.rst:113 -msgid "Chaining Instrumentation" -msgstr "" - -#: ../../instrumentation.rst:115 -msgid "" -"You can combine multiple ``Instrumentation`` objects together using the " -"``graphql.execution.instrumentation.ChainedInstrumentation`` class which " -"accepts a list of ``Instrumentation`` objects and calls them in that " -"defined order." -msgstr "" - -#: ../../instrumentation.rst:132 -msgid "Apollo Tracing Instrumentation" -msgstr "" - -#: ../../instrumentation.rst:134 -msgid "" -"``graphql.execution.instrumentation.tracing.TracingInstrumentation`` is " -"an ``Instrumentation`` implementation that creates tracing information " -"about the query that is being executed." -msgstr "" - -#: ../../instrumentation.rst:137 -msgid "" -"It follows the Apollo proposed tracing format defined at " -"`https://github.com/apollographql/apollo-tracing " -"`_" -msgstr "" - -#: ../../instrumentation.rst:139 -msgid "" -"A detailed tracing map will be created and placed in the ``extensions`` " -"section of the result." -msgstr "" - -#: ../../instrumentation.rst:141 -msgid "So given a query like" -msgstr "" - -#: ../../instrumentation.rst:154 -msgid "It would return a result like" -msgstr "" - -#: ../../instrumentation.rst:261 -msgid "Field Validation Instrumentation" -msgstr "" - -#: ../../instrumentation.rst:263 -msgid "" -"``graphql.execution.instrumentation.fieldvalidation.FieldValidationInstrumentation``" -" is an ``Instrumentation`` implementation that can be used to validate " -"fields and their arguments before query execution. If errors are " -"returned during this process then the query execution is aborted and the " -"errors will be in the query result." -msgstr "" - -#: ../../instrumentation.rst:267 -msgid "" -"You can make you own custom implementation of ``FieldValidation`` or you " -"can use the ``SimpleFieldValidation`` class to add simple per field " -"checks rules." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/logging.po b/docs/locale/en/LC_MESSAGES/logging.po deleted file mode 100644 index 23c702a502..0000000000 --- a/docs/locale/en/LC_MESSAGES/logging.po +++ /dev/null @@ -1,31 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../logging.rst:2 -msgid "Logging" -msgstr "" - -#: ../../logging.rst:4 -msgid "" -"Logging is done with `SLF4J `_. Please have a look" -" at the `Manual `_ for details. The " -"``graphql-java`` root Logger name is ``graphql``." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/relay.po b/docs/locale/en/LC_MESSAGES/relay.po deleted file mode 100644 index 613ace5bae..0000000000 --- a/docs/locale/en/LC_MESSAGES/relay.po +++ /dev/null @@ -1,66 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../relay.rst:2 -msgid "Relay Support" -msgstr "" - -#: ../../relay.rst:5 -msgid "" -"Very basic support for `Relay `_ is " -"included." -msgstr "" - -#: ../../relay.rst:7 -msgid "" -"**Note**: Relay refers here to \"Relay Classic\", there is no support for" -" \"Relay Modern\"." -msgstr "" - -#: ../../relay.rst:9 -msgid "" -"Please look at https://github.com/graphql-java/todomvc-relay-java for a " -"full example project," -msgstr "" - -#: ../../relay.rst:11 -msgid "" -"Relay send queries to the GraphQL server as JSON containing a ``query`` " -"field and a ``variables`` field. The ``query`` field is a JSON string, " -"and the ``variables`` field is a map of variable definitions. A relay-" -"compatible server will need to parse this JSON and pass the ``query`` " -"string to this library as the query and the ``variables`` map as the " -"third argument to ``execute`` as shown below." -msgstr "" - -#: ../../relay.rst:37 -msgid "Apollo Support" -msgstr "" - -#: ../../relay.rst:39 -msgid "" -"There is no special support for `Apollo `_ included: Apollo works with any schema." -msgstr "" - -#: ../../relay.rst:41 -msgid "The Controller example shown above works with Apollo too." -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/schema.po b/docs/locale/en/LC_MESSAGES/schema.po deleted file mode 100644 index 5c3a2c06ab..0000000000 --- a/docs/locale/en/LC_MESSAGES/schema.po +++ /dev/null @@ -1,355 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../schema.rst:2 -msgid "Creating a schema" -msgstr "" - -#: ../../schema.rst:5 -msgid "" -"A schema defines your GraphQL API by defining each field that can be " -"queried or mutated." -msgstr "" - -#: ../../schema.rst:8 -msgid "" -"``graphql-java`` offers two different ways of defining the schema: " -"Programmatically as Java code or via a special graphql dsl (called SDL)." -msgstr "" - -#: ../../schema.rst:11 -msgid "" -"NOTE: SDL is not currently part of the `formal graphql spec " -"`_. The implementation in this library is based off the " -"`reference implementation `_. " -"However plenty of code out there is based on this SDL syntax and hence " -"you can be fairly confident that you are building on solid technology " -"ground." -msgstr "" - -#: ../../schema.rst:16 -msgid "If you are unsure which option to use we recommend the SDL." -msgstr "" - -#: ../../schema.rst:18 -msgid "SDL example:" -msgstr "" - -#: ../../schema.rst:27 -msgid "Java code example:" -msgstr "" - -#: ../../schema.rst:39 -msgid "DataFetcher and TypeResolver" -msgstr "" - -#: ../../schema.rst:41 -msgid "" -"A ``DataFetcher`` provides the data for a field (and changes something, " -"if it is a mutation)." -msgstr "" - -#: ../../schema.rst:43 -msgid "" -"Every field definition has a ``DataFetcher``. When one is not configured," -" a `PropertyDataFetcher `_" -" is used." -msgstr "" - -#: ../../schema.rst:46 -msgid "" -"``PropertyDataFetcher`` fetches data from ``Map`` and Java Beans. So when" -" the field name matches the Map key or the property name of the source " -"Object, no ``DataFetcher`` is needed." -msgstr "" - -#: ../../schema.rst:49 -msgid "" -"A ``TypeResolver`` helps ``graphql-java`` to decide which type a concrete" -" value belongs to. This is needed for ``Interface`` and ``Union``." -msgstr "" - -#: ../../schema.rst:52 -msgid "" -"For example imagine you have an ``Interface`` called *MagicUserType* " -"which resolves back to a series of Java classes called *Wizard*, *Witch* " -"and *Necromancer*. The type resolver is responsible for examining a " -"runtime object and deciding what ``GraphqlObjectType`` should be used to " -"represent it, and hence what data fetchers and fields will be invoked." -msgstr "" - -#: ../../schema.rst:75 -msgid "Creating a schema using the SDL" -msgstr "" - -#: ../../schema.rst:77 -msgid "" -"When defining a schema via SDL, you provide the needed ``DataFetcher`` s " -"and ``TypeResolver`` s when the executable schema is created." -msgstr "" - -#: ../../schema.rst:80 -msgid "" -"Take for example the following static schema definition file called " -"``starWarsSchema.graphqls``:" -msgstr "" - -#: ../../schema.rst:125 -msgid "" -"The static schema definition file ``starWarsSchema.graphqls`` contains " -"the field and type definitions, but you need a runtime wiring to make it " -"a truly executable schema." -msgstr "" - -#: ../../schema.rst:128 -msgid "" -"The runtime wiring contains ``DataFetcher`` s, ``TypeResolvers`` s and " -"custom ``Scalar`` s that are needed to make a fully executable schema." -msgstr "" - -#: ../../schema.rst:131 -msgid "You wire this together using this builder pattern:" -msgstr "" - -#: ../../schema.rst:161 -msgid "" -"Finally, you can generate an executable schema by combining the static " -"schema and the wiring together as shown in this example:" -msgstr "" - -#: ../../schema.rst:176 -msgid "" -"In addition to the builder style shown above, ``TypeResolver`` s and " -"``DataFetcher`` s can also be wired in using the ``WiringFactory`` " -"interface. This allows for a more dynamic runtime wiring since the SDL " -"definitions can be examined in order to decide what to wire in. You " -"could for example look at SDL directives, or some other aspect of the SDL" -" definition to help you decide what runtime to create." -msgstr "" - -#: ../../schema.rst:223 -msgid "Creating a schema programmatically" -msgstr "" - -#: ../../schema.rst:225 -msgid "" -"When the schema is created programmatically ``DataFetcher`` s and " -"``TypeResolver`` s are provided at type creation:" -msgstr "" - -#: ../../schema.rst:227 -msgid "Example:" -msgstr "" - -#: ../../schema.rst:249 -msgid "Types" -msgstr "" - -#: ../../schema.rst:251 -msgid "The GraphQL type system supports the following kind of types:" -msgstr "" - -#: ../../schema.rst:253 ../../schema.rst:263 -msgid "Scalar" -msgstr "" - -#: ../../schema.rst:254 ../../schema.rst:283 -msgid "Object" -msgstr "" - -#: ../../schema.rst:255 ../../schema.rst:313 -msgid "Interface" -msgstr "" - -#: ../../schema.rst:256 ../../schema.rst:339 -msgid "Union" -msgstr "" - -#: ../../schema.rst:257 -msgid "InputObject" -msgstr "" - -#: ../../schema.rst:258 ../../schema.rst:382 -msgid "Enum" -msgstr "" - -#: ../../schema.rst:265 -msgid "``graphql-java`` supports the following Scalars:" -msgstr "" - -#: ../../schema.rst:268 -msgid "``GraphQLString``" -msgstr "" - -#: ../../schema.rst:269 -msgid "``GraphQLBoolean``" -msgstr "" - -#: ../../schema.rst:270 -msgid "``GraphQLInt``" -msgstr "" - -#: ../../schema.rst:271 ../../schema.rst:276 -msgid "``GraphQLFloat``" -msgstr "" - -#: ../../schema.rst:272 -msgid "``GraphQLID``" -msgstr "" - -#: ../../schema.rst:273 -msgid "``GraphQLLong``" -msgstr "" - -#: ../../schema.rst:274 -msgid "``GraphQLShort``" -msgstr "" - -#: ../../schema.rst:275 -msgid "``GraphQLByte``" -msgstr "" - -#: ../../schema.rst:277 -msgid "``GraphQLBigDecimal``" -msgstr "" - -#: ../../schema.rst:278 -msgid "``GraphQLBigInteger``" -msgstr "" - -#: ../../schema.rst:285 ../../schema.rst:317 ../../schema.rst:341 -#: ../../schema.rst:384 ../../schema.rst:411 -msgid "SDL Example:" -msgstr "" - -#: ../../schema.rst:295 ../../schema.rst:325 ../../schema.rst:358 -#: ../../schema.rst:395 ../../schema.rst:420 -msgid "Java Example:" -msgstr "" - -#: ../../schema.rst:315 -msgid "Interfaces are abstract definitions of types." -msgstr "" - -#: ../../schema.rst:409 -msgid "ObjectInputType" -msgstr "" - -#: ../../schema.rst:433 -msgid "Type References (recursive types)" -msgstr "" - -#: ../../schema.rst:435 -msgid "" -"GraphQL supports recursive types: For example a ``Person`` can contain a " -"list of friends of the same type." -msgstr "" - -#: ../../schema.rst:437 -msgid "" -"To be able to declare such a type, ``graphql-java`` has a " -"``GraphQLTypeReference`` class." -msgstr "" - -#: ../../schema.rst:439 -msgid "" -"When the schema is created, the ``GraphQLTypeReference`` is replaced with" -" the actual real type Object." -msgstr "" - -#: ../../schema.rst:441 -msgid "For example:" -msgstr "" - -#: ../../schema.rst:452 -msgid "" -"When the schema is declared via SDL, no special handling of recursive " -"types is needed." -msgstr "" - -#: ../../schema.rst:455 -msgid "Modularising the Schema SDL" -msgstr "" - -#: ../../schema.rst:457 -msgid "" -"Having one large schema file is not always viable. You can modularise " -"you schema using two techniques." -msgstr "" - -#: ../../schema.rst:459 -msgid "" -"The first technique is to merge multiple Schema SDL files into one logic " -"unit. In the case below the schema has been split into multiple files " -"and merged all together just before schema generation." -msgstr "" - -#: ../../schema.rst:480 -msgid "" -"The Graphql SDL type system has another construct for modularising a " -"schema. You can use `type extensions` to add extra fields and interfaces" -" to a type." -msgstr "" - -#: ../../schema.rst:483 -msgid "Imagine you start with a type like this in one schema file." -msgstr "" - -#: ../../schema.rst:492 -msgid "Another part of your system can extend this type to add more shape to it." -msgstr "" - -#: ../../schema.rst:503 -msgid "" -"You can have as many extensions as you think sensible. They will be " -"combined in the order in which they are encountered. Duplicate fields " -"will be merged as one (however field re-definitions into new types are " -"not allowed)." -msgstr "" - -#: ../../schema.rst:514 -msgid "" -"With all these type extensions in place the `Human` type now looks like " -"this at runtime." -msgstr "" - -#: ../../schema.rst:526 -msgid "" -"This is especially useful at the top level. You can use extension types " -"to add new fields to the top level schema \"query\". Teams could " -"contribute \"sections\" on what is being offered as the total graphql " -"query." -msgstr "" - -#: ../../schema.rst:559 -msgid "Subscription Support" -msgstr "" - -#: ../../schema.rst:561 -msgid "" -"Subscriptions are not officially specified yet: ``graphql-java`` supports" -" currently a very basic implementation where you can define a " -"subscription in the schema with " -"``GraphQLSchema.Builder.subscription(...)``. This enables you to handle a" -" subscription request:" -msgstr "" - diff --git a/docs/locale/en/LC_MESSAGES/subscriptions.po b/docs/locale/en/LC_MESSAGES/subscriptions.po deleted file mode 100644 index 63e7d4a0b5..0000000000 --- a/docs/locale/en/LC_MESSAGES/subscriptions.po +++ /dev/null @@ -1,134 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-15 10:51+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../subscriptions.rst:2 -msgid "Subscriptions" -msgstr "" - -#: ../../subscriptions.rst:5 -msgid "Subscription Queries" -msgstr "" - -#: ../../subscriptions.rst:7 -msgid "" -"Graphql subscriptions allow you subscribe to a reactive source and as new" -" data arrives then a graphql query is applied over that data and the " -"results are passed on." -msgstr "" - -#: ../../subscriptions.rst:10 -msgid "" -"See http://graphql.org/blog/subscriptions-in-graphql-and-relay/ for more " -"general details on graphql subscriptions." -msgstr "" - -#: ../../subscriptions.rst:14 -msgid "" -"Imagine you have an stock market pricing service and you make a graphql " -"subscription to it like this" -msgstr "" - -#: ../../subscriptions.rst:27 -msgid "" -"graphql subscriptions allow a stream of ``ExecutionResult`` objects to be" -" sent down each time the stock price changes. The field selection set " -"will applied to the underlying data and are represented just like any " -"other graphql query." -msgstr "" - -#: ../../subscriptions.rst:31 -msgid "" -"What is special is that the initial result of a subscription query is a " -"reactive-streams ``Publisher`` object which you need to use to get the " -"future values." -msgstr "" - -#: ../../subscriptions.rst:34 -msgid "" -"You need to use ``SubscriptionExecutionStrategy`` as your execution " -"strategy as it has the support for the reactive-streams APIs." -msgstr "" - -#: ../../subscriptions.rst:47 -msgid "" -"The ``Publisher`` here is the publisher of a stream of " -"events. You need to subscribe to this with your processing code which " -"will look something like the following" -msgstr "" - -#: ../../subscriptions.rst:111 -msgid "" -"You are now writing reactive-streams code to consume a series of " -"``ExecutionResults``. You can see more details on reactive-streams code " -"here http://www.reactive-streams.org/" -msgstr "" - -#: ../../subscriptions.rst:114 -msgid "" -"``RxJava`` is a popular implementation of reactive-streams. Check out " -"http://reactivex.io/intro.html to find out more about creating Publishers" -" of data and Subscriptions to that data." -msgstr "" - -#: ../../subscriptions.rst:117 -msgid "" -"graphql-java only produces a stream of results. It does not concern " -"itself with sending these over the network on things like web sockets and" -" so on. That is important but not a concern of the base graphql-java " -"library." -msgstr "" - -#: ../../subscriptions.rst:120 -msgid "" -"We have put together a basic example of using websockets (backed by " -"Jetty) with a simulated stock price application that is built using " -"RxJava." -msgstr "" - -#: ../../subscriptions.rst:123 -msgid "" -"See https://github.com/graphql-java/graphql-java-subscription-example for" -" more detailed code on handling network concerns and the like." -msgstr "" - -#: ../../subscriptions.rst:128 -msgid "Subscription Data Fetchers" -msgstr "" - -#: ../../subscriptions.rst:130 -msgid "" -"The ``DataFetcher`` behind a subscription field is responsible for " -"creating the ``Publisher`` of data. The objects return by this Publisher" -" will be mapped over the graphql query as each arrives and then sent back" -" out as an execution result." -msgstr "" - -#: ../../subscriptions.rst:133 -msgid "You data fetcher is going to look something like this." -msgstr "" - -#: ../../subscriptions.rst:146 -msgid "" -"Now the exact details of how you get that stream of events is up to you " -"and you're reactive code. graphql-java gives you a way to map the " -"graphql query fields over that stream of objects just like a standard " -"graphql query." -msgstr "" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/batching.mo b/docs/locale/zh_CN/LC_MESSAGES/batching.mo deleted file mode 100644 index 2a9f65e752..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/batching.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/batching.po b/docs/locale/zh_CN/LC_MESSAGES/batching.po deleted file mode 100644 index 6c9bdfd542..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/batching.po +++ /dev/null @@ -1,158 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-14 18:16+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../batching.rst:2 -msgid "Using Dataloader" -msgstr "使用 Dataloader" - -#: ../../batching.rst:4 -msgid "" -"If you are using ``graphql``, you are likely to making queries on a graph" -" of data (surprise surprise). But its easy to implement inefficient code" -" with naive loading of a graph of data." -msgstr "使用 ``graphql``, 你很可能会去查询图结构的数据(graph of data ) (这可能是句废话). 如果用简单直接的方法去获取每个field的数据,可能会效率很低。" - -#: ../../batching.rst:7 -msgid "" -"Using ``java-dataloader`` will help you to make this a more efficient " -"process by both caching and batching requests for that graph of data " -"items. If ``dataloader`` has seen a data item before, it will have " -"cached the value and will return it without having to ask for it again." -msgstr "使用 ``java-dataloader`` 可以帮助你更有效地缓存和批量化数据加载操作。 ``dataloader``会缓存所有加载过的数据,使再次使用相同数据时,不需要再加载。 " - -#: ../../batching.rst:10 -msgid "" -"Imagine we have the StarWars query outlined below. It asks us to find a " -"hero and their friend's names and their friend's friend's names. It is " -"likely that many of these people will be friends in common." -msgstr "假设我们用以下的 StarWars 查询。这查询了一个英雄( hero)和他朋友的名字,和他朋友的朋友的名字。很多时候,他们有共同的朋友。" - -#: ../../batching.rst:28 -msgid "" -"The result of this query is displayed below. You can see that Han, Leia, " -"Luke and R2-D2 are a tight knit bunch of friends and share many friends " -"in common." -msgstr "下面是查询的结果。你可以看到,Han, Leia, Luke 和 R2-D2 是一群紧密的朋友。他们有很多共同的朋友。" - -#: ../../batching.rst:42 -msgid "" -"A naive implementation would called a `DataFetcher` to retrieved a person" -" object every time it was invoked." -msgstr "一个直接的实现是为每个人物对象(person object)调用一次 `DataFetcher` 去获取数据。" - -#: ../../batching.rst:44 -msgid "" -"In this case it would be *15* calls over the network. Even though the " -"group of people have a lot of common friends. With `dataloader` you can " -"make the `graphql` query much more efficient." -msgstr "这样你需要 *15* 次网络调用 。即使这群有有很多相同的朋友。使用 `dataloader` 可以让 `graphql` 查询更高效。" - -#: ../../batching.rst:47 -msgid "" -"As `graphql` descends each level of the query ( eg as it processes `hero`" -" and then `friends` and then for each their `friends`), the data loader " -"is called to \"promise\" to deliver a person object. At each level " -"`dataloader.dispatch()` will be called to fire off the batch requests for" -" that part of the query. With caching turned on (the default) then any " -"previously returned person will be returned as is for no cost." -msgstr "因 `graphql` 会批量化每个层级的查询。 ( 如先是 `hero` 之后是 `friends` 之后是他们的 `friends`), Data loader 返回了一个 \" 期约(promise)\",期约会返回一个 person object.(人物对象)。在查询的每个层级, `dataloader.dispatch()` 方法均会被调用一次,以获取真实的数据。当开启了缓存功能时 (默认开启),将直接返回之前加载过的 person,而不会再发起一次查询。" - -#: ../../batching.rst:52 -msgid "" -"In the above example there are only *5* unique people mentioned but with " -"caching and batching retrieval in place their will be only *3* calls to " -"the batch loader function. *3* calls over the network or to a database " -"is much better than *15* calls you will agree." -msgstr "上例中,共有 *5* 个独立的 people。但当缓存和批量化开启后,只发起了 *3* 次调用 batch loader 方法的查询操作。*3* 次网络或DB访问,当然比 *15* 次牛B多了。【译者补】" - -#: ../../batching.rst:55 -msgid "" -"If you use capabilities like " -"`java.util.concurrent.CompletableFuture.supplyAsync()` then you can make " -"it even more efficient by making the the remote calls asynchronous to the" -" rest of the query. This will make it even more timely since multiple " -"calls can happen at once if need be." -msgstr "如果你使用了如 `java.util.concurrent.CompletableFuture.supplyAsync()` 的异步程序方式 。多个field的远程加载数据就可以并发进行了。. 这可以让查询更快,因一次并发了多个远程调用。" - -#: ../../batching.rst:59 -msgid "Here is how you might put this in place:" -msgstr "下面就是示例代码:" - -#: ../../batching.rst:121 -msgid "```" -msgstr "" - -#: ../../batching.rst:123 -msgid "" -"One thing to note is the above only works if you use " -"`DataLoaderDispatcherInstrumentation` which makes sure " -"`dataLoader.dispatch()` is called. If this was not in place, then all " -"the promises to data will never be dispatched ot the batch loader " -"function and hence nothing would ever resolve." -msgstr "需要注意的是,只有你使用了 `DataLoaderDispatcherInstrumentation` ,上面说的才会生效。由它来调用 `dataLoader.dispatch()` 。不然,期约( promises ) 将不会被执行,就更不会有数据获取了。" - -#: ../../batching.rst:128 -msgid "Per Request Data Loaders" -msgstr "查询范围的 Data Loaders" - -#: ../../batching.rst:130 -msgid "" -"If you are serving web requests then the data can be specific to the user" -" requesting it. If you have user specific data then you will not want to " -"cache data meant for user A to then later give it to user B in a " -"subsequent request." -msgstr "对于 Web 请求,请求的结果可能会因不同用户而不同的。如果是特定用户的数据,你一定不希望用户A的数据,被用户B查询到。" - -#: ../../batching.rst:133 -msgid "" -"The scope of your DataLoader instances is important. You might want to " -"create them per web request to ensure data is only cached within that web" -" request and no more." -msgstr "所以 DataLoader 实例的范围很重要。这时,你需要对每个 Request 创建一个新的 DataLoader,来保证它只在当前请求中生效。" - -#: ../../batching.rst:136 -msgid "" -"If your data can be shared across web requests then you might want to " -"scope your data loaders so they survive longer than the web request say." -msgstr "如果你需要的是不同请求间共享数据,所以你会希望 DataLoader 的生命周期更长。" - -#: ../../batching.rst:139 -msgid "" -"But if you are doing per request data loaders then creating a new set of " -"``GraphQL`` and ``DataLoader`` objects per request is super cheap. Its " -"the ``GraphQLSchema`` creation that can be expensive, especially if you " -"are using graphql SDL parsing." -msgstr "但如用你用请求级的 data loaders ,为每个请求创建 ``GraphQL`` and ``DataLoader`` 是花费很少资源的。Its the ``GraphQLSchema`` creation that can be expensive, especially if you are using graphql SDL parsing." - -#: ../../batching.rst:142 -msgid "" -"Structure your code so that the schema is statically held, perhaps in a " -"static variable or in a singleton IoC component but build out a new " -"``GraphQL`` set of objects on each request." -msgstr "i在代码中静态引用 schema 。可以是静态变量或 IoC 单件组件。但每次处理请求时,都需要创建 ``GraphQL`` 对象。" - -#~ msgid "" -#~ "But if you are doing per request" -#~ " data loaders then creating a new " -#~ "set of ``GraphQL`` and ``DataLoader`` " -#~ "objects per request is super cheap. " -#~ "Its the ``GraphQLSchema`` creation that " -#~ "can be expensive, especially if you " -#~ "are using graphql IDL parsing." -#~ msgstr "" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/concerns.mo b/docs/locale/zh_CN/LC_MESSAGES/concerns.mo deleted file mode 100644 index a5c6f81521..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/concerns.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/concerns.po b/docs/locale/zh_CN/LC_MESSAGES/concerns.po deleted file mode 100644 index 9e97401f6e..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/concerns.po +++ /dev/null @@ -1,109 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../concerns.rst:2 -msgid "Application concerns" -msgstr "如何落地应用(Application concerns)" - -#: ../../concerns.rst:4 -msgid "" -"The graphql-java library concentrates on providing an engine for the " -"execution of queries according to the specification." -msgstr "graphql-java 引擎主要的关注点是按 GraphQL 规范来执行查询。" - -#: ../../concerns.rst:6 -msgid "" -"It does not concern itself about other high level application concerns " -"such as the following :" -msgstr "它本身不关注应用的其它方面,如:" - -#: ../../concerns.rst:8 -msgid "Database access" -msgstr "数据库访问" - -#: ../../concerns.rst:9 -msgid "Caching data" -msgstr "缓存数据" - -#: ../../concerns.rst:10 -msgid "Data authorisation" -msgstr "数据权限控制" - -#: ../../concerns.rst:11 -msgid "Data pagination" -msgstr "数据分页" - -#: ../../concerns.rst:12 -msgid "HTTP transfer" -msgstr "HTTP 转换" - -#: ../../concerns.rst:13 -msgid "JSON endoding" -msgstr "JSON 编码" - -#: ../../concerns.rst:14 -msgid "Code wiring via dependency injection" -msgstr "依赖注入的编程方法" - -#: ../../concerns.rst:16 -msgid "You need to push these concerns into your business logic layers." -msgstr "你需要在自己的业务逻辑层中实现这些。" - -#: ../../concerns.rst:18 -msgid "The following are great links to read more about this" -msgstr "下面是一些相关方案的介绍:" - -#: ../../concerns.rst:20 -msgid "http://graphql.org/learn/serving-over-http/" -msgstr "" - -#: ../../concerns.rst:21 -msgid "http://graphql.org/learn/authorization/" -msgstr "" - -#: ../../concerns.rst:22 -msgid "http://graphql.org/learn/pagination/" -msgstr "" - -#: ../../concerns.rst:23 -msgid "http://graphql.org/learn/caching/" -msgstr "" - -#: ../../concerns.rst:26 -msgid "Context Objects" -msgstr "上下文对象(Context Objects)" - -#: ../../concerns.rst:28 -msgid "" -"You can pass in a context object during query execution that will allow " -"you to better invoke that business logic." -msgstr "为更方便的业务调用,你可以在查询执行中加入Context Object。" - -#: ../../concerns.rst:30 -msgid "" -"For example the edge of your application could be performing user " -"detection and you need that information inside the graphql execution to " -"perform authorisation." -msgstr "例如,你的应用的边界模块可能会做用户识别,然后 GraphQL 查询执行时,你可以想做数据权限控制。" - -#: ../../concerns.rst:33 -msgid "" -"This made up example shows how you can pass yourself information to help " -"execute your queries." -msgstr "下面例子演示怎么向你的查询传递信息:" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/contributions.mo b/docs/locale/zh_CN/LC_MESSAGES/contributions.mo deleted file mode 100644 index 1367891d7e..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/contributions.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/contributions.po b/docs/locale/zh_CN/LC_MESSAGES/contributions.po deleted file mode 100644 index 6fab5ab5e2..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/contributions.po +++ /dev/null @@ -1,90 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../contributions.rst:2 -msgid "Contributions" -msgstr "贡献" - -#: ../../contributions.rst:4 -msgid "Every contribution to make this project better is welcome: Thank you!" -msgstr "所有的贡献都是欢迎的。谢谢!" - -#: ../../contributions.rst:6 -msgid "" -"In order to make this a pleasant as possible for everybody involved, here" -" are some tips:" -msgstr "为了让大家快乐贡献,以下是一些提示:" - -#: ../../contributions.rst:8 -msgid "Respect the [Code of Conduct](#code-of-conduct)" -msgstr "" - -#: ../../contributions.rst:10 -msgid "" -"Before opening an Issue to report a bug, please try the latest " -"development version. It can happen that the problem is already solved." -msgstr "" - -#: ../../contributions.rst:12 -msgid "" -"Please use Markdown to format your comments properly. If you are not " -"familiar with that: `Getting started with writing and formatting on " -"GitHub `_" -msgstr "" - -#: ../../contributions.rst:14 -msgid "" -"For Pull Requests: * Here are some `general tips " -"`_" -msgstr "" - -#: ../../contributions.rst:17 -msgid "" -"Please be a as focused and clear as possible and don't mix concerns. " -"This includes refactorings mixed with bug-fixes/features, see [Open " -"Source Contribution " -"Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html)" -msgstr "" - -#: ../../contributions.rst:19 -msgid "" -"It would be good to add a automatic test. All tests are written in `Spock" -" `_." -msgstr "" - -#: ../../contributions.rst:23 -msgid "Build and test locally" -msgstr "本地构建和测试" - -#: ../../contributions.rst:25 -msgid "Just clone the repo and type" -msgstr "" - -#: ../../contributions.rst:31 -msgid "In ``build/libs`` you will find the jar file." -msgstr "" - -#: ../../contributions.rst:33 -msgid "Running the tests:" -msgstr "" - -#: ../../contributions.rst:39 -msgid "Installing in the local Maven repository:" -msgstr "" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/exceptions.mo b/docs/locale/zh_CN/LC_MESSAGES/exceptions.mo deleted file mode 100644 index 6f4b912463..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/exceptions.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/exceptions.po b/docs/locale/zh_CN/LC_MESSAGES/exceptions.po deleted file mode 100644 index f22563f522..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/exceptions.po +++ /dev/null @@ -1,123 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../exceptions.rst:2 -msgid "Runtime Exceptions" -msgstr "运行期异常(Runtime Exceptions )" - -#: ../../exceptions.rst:5 -msgid "" -"Runtime exceptions can be thrown by the graphql engine if certain " -"exceptional situations are encountered. The following are a list of the " -"exceptions that can be thrown all the way out of a " -"``graphql.execute(...)`` call." -msgstr "在一些异常的情况下, graphql engine 有可能抛出 Runtime exceptions。下面是调用 ``graphql.execute(...)`` 期间可能出现的异常。" - -#: ../../exceptions.rst:8 -msgid "" -"These are not graphql errors in execution but rather totally unacceptable" -" conditions in which to execute a graphql query." -msgstr "他们不是执行 graphql 查询中发生的异常。 但还是不能被忽略。" - -#: ../../exceptions.rst:10 -msgid "`graphql.schema.CoercingSerializeException`" -msgstr "" - -#: ../../exceptions.rst:12 -msgid "" -"is thrown when a value cannot be serialised by a Scalar type, for example" -" a String value being coerced as an Int." -msgstr "发生这类型的异常,原因是序列化Scalar时出错。如 Int 字段获取到 String 值。" - -#: ../../exceptions.rst:16 -msgid "`graphql.schema.CoercingParseValueException`" -msgstr "" - -#: ../../exceptions.rst:18 -msgid "" -"is thrown when a value cannot be parsed by a Scalar type, for example a " -"String input value being parsed as an Int." -msgstr "发生这类型的异常,原因是解释输入的 Scalar 时出错 ,如 int 参数的实际输入值是一个 String。" - -#: ../../exceptions.rst:22 -msgid "`graphql.execution.UnresolvedTypeException`" -msgstr "" - -#: ../../exceptions.rst:24 -msgid "" -"is thrown if a graphql.schema.TypeResolver` fails to provide a concrete " -"object type given a interface or union type." -msgstr "当 graphql.schema.TypeResolver` 不能判断抽象对象( interface or union type) 的实际类型( concrete object type) 时发生这个异常。" - -#: ../../exceptions.rst:28 -msgid "`graphql.execution.NonNullableValueCoercedAsNullException`" -msgstr "" - -#: ../../exceptions.rst:30 -msgid "" -"is thrown if a non null variable argument is coerced as a null value " -"during execution." -msgstr "如果 个不允许为 null 的参数,被赋值为 null。会抛出上面异常。." - -#: ../../exceptions.rst:34 -msgid "`graphql.execution.InputMapDefinesTooManyFieldsException`" -msgstr "" - -#: ../../exceptions.rst:36 -msgid "" -"is thrown if a map used for an input type object contains more keys than " -"is defined in that input type." -msgstr "可以输入对象( input type object )包含了未在Schema中定义的field。就会发生上面异常。" - -#: ../../exceptions.rst:40 -msgid "`graphql.schema.validation.InvalidSchemaException`" -msgstr "" - -#: ../../exceptions.rst:44 -msgid "is thrown if the schema is not valid when built via" -msgstr "表示在运行下面函数时, Schema 校验失败。" - -#: ../../exceptions.rst:43 -msgid "graphql.schema.GraphQLSchema.Builder#build()`" -msgstr "" - -#: ../../exceptions.rst:46 -msgid "`graphql.GraphQLException`" -msgstr "" - -#: ../../exceptions.rst:48 -msgid "" -"is thrown as a general purpose runtime exception, for example if the code" -" cant access a named field when examining a POJO, it is analogous to a " -"RuntimeException if you will." -msgstr "这个是通用的异常。如不能访问 POJO 的 field。这可以等同于 RuntimeException。" - -#: ../../exceptions.rst:52 -msgid "`graphql.AssertException`" -msgstr "" - -#: ../../exceptions.rst:54 -msgid "" -"is thrown as a low level code assertion exception for truly unexpected " -"code conditions, things we assert" -msgstr "这是内部断言的预计外异常" - -#: ../../exceptions.rst:55 -msgid "should never happen in practice." -msgstr "事实上不应该发生【译注:如果抛出了,可能是框架有BUG了。】" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/execution.mo b/docs/locale/zh_CN/LC_MESSAGES/execution.mo deleted file mode 100644 index 9bdac7c47f..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/execution.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/execution.po b/docs/locale/zh_CN/LC_MESSAGES/execution.po deleted file mode 100644 index 77900fc780..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/execution.po +++ /dev/null @@ -1,547 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../execution.rst:2 -msgid "Execution" -msgstr "执行(Execution)" - -#: ../../execution.rst:5 -msgid "Queries" -msgstr "查询(Queries)" - -#: ../../execution.rst:7 -msgid "" -"To execute a query against a schema, build a new ``GraphQL`` object with " -"the appropriate arguments and then call ``execute()``." -msgstr "为了对 一个Schema 执行查询。需要先构造一个 ``GraphQL`` 对象,并带着一些参数去调用 ``execute()`` 方法." - -#: ../../execution.rst:10 -msgid "" -"The result of a query is an ``ExecutionResult`` which is the query data " -"and/or a list of errors." -msgstr "查询将返回一个 ``ExecutionResult`` 对象,其中包含查询的结果数据 (或出错时的错误信息集合)." - -#: ../../execution.rst:30 -msgid "" -"More complex query examples can be found in the `StarWars query tests " -"`_" -msgstr "更复杂的示例,可以看 `StarWars 查询测试用例 `_" - -#: ../../execution.rst:34 -msgid "Data Fetchers" -msgstr "" - -#: ../../execution.rst:36 -msgid "" -"Each graphql field type has a ``graphql.schema.DataFetcher`` associated " -"with it. Other graphql implementations often call this type of code " -"*resolvers**." -msgstr "每个graphql schema 中的field,都需要绑定相应的 ``graphql.schema.DataFetcher`` 以获取数据. 其它GraphQL的实现把这叫 *resolvers**." - -#: ../../execution.rst:39 -msgid "" -"Often you can rely on ``graphql.schema.PropertyDataFetcher`` to examine " -"Java POJO objects to provide field values from them. If your don't " -"specify a data fetcher on a field, this is what will be used." -msgstr "很多时候,你可以用默认的 ``graphql.schema.PropertyDataFetcher`` 去从 Java POJO 中自动提取数据到对应的 field. 如果你未为 field 指定 data fetcher 那么就默认使用它." - -#: ../../execution.rst:42 -msgid "" -"However you will need to fetch your top level domain objects via your own" -" custom data fetchers. This might involve making a database call or " -"contacting another system over HTTP say." -msgstr "但你最少需要为顶层的领域对象(domain objects) 编写 data fetchers. 其中可以会与database交互,或用HTTP与其它系统交互." - -#: ../../execution.rst:45 -msgid "" -"``graphql-java`` is not opinionated about how you get your domain data " -"objects, that is very much your concern. It is also not opinionated on " -"user authorisation to that data. You should push all that logic into " -"your business logic layer code." -msgstr "``graphql-java`` 不关心你如何获取你的业务数据,这是你的自己. 它也不关心你如果授权你的业务数据. 你应该在自己的业务逻辑层,去实现这些逻辑." - -#: ../../execution.rst:48 -msgid "A data fetcher might look like this:" -msgstr "简单 Data fetcher 示例:" - -#: ../../execution.rst:59 -msgid "" -"Each ``DataFetcher`` is passed a " -"``graphql.schema.DataFetchingEnvironment`` object which contains what " -"field is being fetched, what arguments have been supplied to the field " -"and other information such as the field's parent object, the query root " -"object or the query context object." -msgstr "框架在执行查询时。会调用上面的方法,其中的 ``graphql.schema.DataFetchingEnvironment`` 参数包括以下信息:被查询的 field、查询这个field时可能带上的查询参数、这个field的父数据对象(Source Object)、 查询的ROOT数据对象、查询执行上下文环境对象(query context object)." - -#: ../../execution.rst:63 -msgid "" -"In the above example, the execution will wait for the data fetcher to " -"return before moving on. You can make execution of the ``DataFetcher`` " -"asynchronous by returning a ``CompletionStage`` to data, that is " -"explained more further down this page." -msgstr "上面是同步获取数据的例子,执行引擎需要等待一个 data fetcher 返回数据才能继续下一个. 也可以通过编写异步的 ``DataFetcher`` ,异步地返回 ``CompletionStage`` 对象,在下文中将会说明使用方法." - -#: ../../execution.rst:67 -msgid "Exceptions while fetching data" -msgstr "当获取数据出现异常时" - -#: ../../execution.rst:69 -msgid "" -"If an exception happens during the data fetcher call, then the execution " -"strategy by default will make a ``graphql.ExceptionWhileDataFetching`` " -"error and add it to the list of errors on the result. Remember graphql " -"allows partial results with errors." -msgstr "如果异步是出现在调用 data fetcher 时, 默认的执行策略(execution strategy) 将生成一个 ``graphql.ExceptionWhileDataFetching`` 错误,并将其加入到查询结果的错误列表中. 请留意,GraphQL 在发生异常时,允许返回部分成功的数据,并将带上异常信息." - -#: ../../execution.rst:73 -msgid "Here is the code for the standard behaviour." -msgstr "下面是默认的异常行为处理逻辑." - -#: ../../execution.rst:92 -msgid "" -"If the exception you throw is itself a `GraphqlError` then it will " -"transfer the message and custom extensions attributes from that exception" -" into the `ExceptionWhileDataFetching` object. This allows you to place " -"your own custom attributes into the graphql error that is sent back to " -"the caller." -msgstr "如果你抛出的异常本身是 `GraphqlError` 类型,框架会把其中的消息 和 自定义扩展属性(custom extensions attributes)转换到 `ExceptionWhileDataFetching` 对象中. 这可以方便你把自己的错误信息,放到返回给调用者的 GraphQL 错误列表中." - -#: ../../execution.rst:96 -msgid "" -"For example imagine your data fetcher threw this exception. The `foo` " -"and `fizz` attributes would be included in the resultant graphql error." -msgstr "例如,你在 DataFetcher 中抛出了这个异常. 那么 `foo` and `fizz` 属性将会包含在返回给调用者的graphql查询错误中." - -#: ../../execution.rst:122 -msgid "" -"You can change this behaviour by creating your own " -"``graphql.execution.DataFetcherExceptionHandler`` exception handling code" -" and giving that to the execution strategy." -msgstr "你可以编写自己的 ``graphql.execution.DataFetcherExceptionHandler`` 来改变这些逻辑。只需要在执行策略(execution strategy)注册一下." - -#: ../../execution.rst:125 -msgid "" -"For example the code above records the underlying exception and stack " -"trace. Some people may prefer not to see that in the output error list." -" So you can use this mechanism to change that behaviour." -msgstr "例如,上面的代码记录了底层的异常和堆栈. 如果你不希望这些出现在输出的错误列表中。你可以用以下的方法去实现." - -#: ../../execution.rst:141 -msgid "Serializing results to JSON" -msgstr "序列化成 JSON" - -#: ../../execution.rst:143 -msgid "" -"The most common way to call graphql is over HTTP and to expect a JSON " -"response back. So you need to turn an `graphql.ExecutionResult` into a " -"JSON payload." -msgstr "通常,用 HTTP 方法去调用 graphql ,用 JSON 格式作为返回结果. 返回,需要把 `graphql.ExecutionResult` 对象转换为 JSON 格式包." - -#: ../../execution.rst:146 -msgid "" -"A common way to do that is use a JSON serialisation library like Jackson " -"or GSON. However exactly how they interpret the data result is " -"particular to them. For example `nulls` are important in graphql results" -" and hence you must set up the json mappers to include them." -msgstr "一般用 Jackson or GSON 去做 JSON 序列化. 但他们对结果数据的转换方法有一些不同点. 例如 JSON 的`nulls` 在 graphql 结果中的是有用的。所以必须在 json mappers 中设置需要它" - -#: ../../execution.rst:150 -msgid "" -"To ensure you get a JSON result that confirms 100% to the graphql spec, " -"you should call `toSpecification` on the result and then send that back " -"as JSON." -msgstr "为保证你返回的 JSON 结果 100% 合符 graphql 规范, 应该调用result对象的 `toSpecification` 方法,然后以 JSON格式 发送响应." - -#: ../../execution.rst:153 -msgid "" -"This will ensure that the result follows the specification outlined in " -"http://facebook.github.io/graphql/#sec-Response" -msgstr "这样就可以确保返回数据合符在 http://facebook.github.io/graphql/#sec-Response 中的规范" - -#: ../../execution.rst:167 -msgid "Mutations" -msgstr "更新(Mutations)" - -#: ../../execution.rst:169 -msgid "" -"A good starting point to learn more about mutating data in graphql is " -"`http://graphql.org/learn/queries/#mutations " -"`_." -msgstr "如果你不了解什么叫更新(Mutations),建议先阅读规范 `http://graphql.org/learn/queries/#mutations `_." - -#: ../../execution.rst:171 -msgid "" -"In essence you need to define a ``GraphQLObjectType`` that takes " -"arguments as input. Those arguments are what you can use to mutate your " -"data store via the data fetcher invoked." -msgstr "首先,你需要定义一个支持输入参数的 ``GraphQLObjectType`` . 在更新数据时,框架会带上这些参数去调用 data fetcher." - -#: ../../execution.rst:174 -msgid "The mutation is invoked via a query like :" -msgstr "下面是,GraphQL 更新语句的例子 :" - -#: ../../execution.rst:185 -msgid "" -"You need to send in arguments during that mutation operation, in this " -"case for the variables for ``$ep`` and ``$review``" -msgstr "修改操作是需要带输入参数的,上例中对应变量 ``$ep`` and ``$review``" - -#: ../../execution.rst:187 -msgid "You would create types like this to handle this mutation :" -msgstr "对应地,Schema 应该这么写【译注:以下是 Java 写法,你也可以用SDL写法】 :" - -#: ../../execution.rst:241 -msgid "" -"Notice that the input arguments are of type ``GraphQLInputObjectType``. " -"This is important. Input arguments can ONLY be of that type and you " -"cannot use output types such as ``GraphQLObjectType``. Scalars types are" -" consider both input and output types." -msgstr "注意,输入参数应该是 ``GraphQLInputObjectType`` 类型. 请留意. 对于修改操作,输入参数只能用这个类型(type),而不能用如 ``GraphQLObjectType``之类的输出类型(type). Scalars 类型(type) 可以用于输入和输出." - -#: ../../execution.rst:244 -msgid "" -"The data fetcher here is responsible for executing the mutation and " -"returning some sensible output values." -msgstr "对于更新操作,DataFetcher的职责是执行数据更新行返回执行结果." - -#: ../../execution.rst:277 -msgid "" -"Notice how it calls a data store to mutate the backing database and then " -"returns a ``Review`` object that can be used as the output values to the " -"caller." -msgstr "上面代码,先更新业务数据,然后返回 ``Review`` 对象给调用方." - -#: ../../execution.rst:281 -msgid "Asynchronous Execution" -msgstr "异步执行(Asynchronous Execution)" - -#: ../../execution.rst:283 -msgid "" -"graphql-java uses fully asynchronous execution techniques when it " -"executes queries. You can get the ``CompleteableFuture`` to results by " -"calling ``executeAsync()`` like this" -msgstr "graphql-java 是个全异步的执行引擎. 如下,调用 ``executeAsync()`` 后,返回 ``CompleteableFuture`` :" - -#: ../../execution.rst:302 -msgid "" -"The use of ``CompletableFuture`` allows you to compose actions and " -"functions that will be applied when the execution completes. The final " -"call to ``.join()`` waits for the execution to happen." -msgstr "使用 ``CompletableFuture`` 对象,你可以指定,在查询完成后,组合其它操作(action)或函数你的函数. 需要你需要同步等待执行结果 ,可以调用 ``.join()`` 方法." - -#: ../../execution.rst:305 -msgid "" -"In fact under the covers, the graphql-java engine uses asynchronous " -"execution and makes the ``.execute()`` method appear synchronous by " -"calling join for you. So the following code is in fact the same." -msgstr "graphql-java引擎内部是异步执行的,但你可以通过调用 join 方法变为同步等待. 下面是等效的代码:" - -#: ../../execution.rst:319 -msgid "" -"If a ``graphql.schema.DataFetcher`` returns a ``CompletableFuture`` " -"object then this will be composed into the overall asynchronous query " -"execution. This means you can fire off a number of field fetching " -"requests in parallel. Exactly what threading strategy you use is up to " -"your data fetcher code." -msgstr "如果你编写的 ``graphql.schema.DataFetcher`` 返回 ``CompletableFuture`` 对象,那么它会被糅合到整个异步查询中. 这样,你可以同时发起我个数据获取操作,让它们并行运行. 而由DataFetcher控制具体的线程并发策略." - -#: ../../execution.rst:323 -msgid "" -"The following code uses the standard Java " -"``java.util.concurrent.ForkJoinPool.commonPool()`` thread executor to " -"supply values in another thread." -msgstr "下面示例使用 ``java.util.concurrent.ForkJoinPool.commonPool()`` 并行执行器,用其它线程完成数据获取." - -#: ../../execution.rst:338 -msgid "" -"The code above is written in long form. With Java 8 lambdas it can be " -"written more succinctly as follows" -msgstr "上面是旧的写法,也可以用Java 8 lambdas 的写法:" - -#: ../../execution.rst:345 -msgid "" -"The graphql-java engine ensures that all the ``CompletableFuture`` " -"objects are composed together to provide an execution result that follows" -" the graphql specification." -msgstr "graphql-java 保证所有 ``CompletableFuture`` 对象组合,最后生成合符 graphql 规范的执行结果." - -#: ../../execution.rst:348 -msgid "" -"There is a helpful shortcut in graphql-java to create asynchronous data " -"fetchers. Use ``graphql.schema.AsyncDataFetcher.async(DataFetcher)`` " -"to wrap a ``DataFetcher``. This can be used with static imports to " -"produce more readable code." -msgstr "还有一个方法可以简化异步 data fetchers 的编写. 使用 ``graphql.schema.AsyncDataFetcher.async(DataFetcher)`` 去包装``DataFetcher``. 这样可以使用 static imports 来提高代码可读性." - -#: ../../execution.rst:357 -msgid "Execution Strategies" -msgstr "关于执行策略(Execution Strategies)" - -#: ../../execution.rst:359 -msgid "" -"A class derived from ``graphql.execution.ExecutionStrategy`` is used to " -"run a query or mutation. A number of different strategies are provided " -"with graphql-java and if you are really keen you can even write your own." -msgstr "在执行查询或更新数据时,引擎会使用实现了 ``graphql.execution.ExecutionStrategy``接口 的对象,来决定执行策略. graphql-java 中已经有几个现成的策略,但如果你需要,你可以写自己的。." - -#: ../../execution.rst:362 -msgid "" -"You can wire in what execution strategy to use when you create the " -"``GraphQL`` object." -msgstr "你可以这样给 ``GraphQL`` 对象绑定执行策略。" - -#: ../../execution.rst:372 -msgid "" -"In fact the code above is equivalent to the default settings and is a " -"very sensible choice of execution strategies for most cases." -msgstr "实际上,上面就是引擎默认的策略了。大部分情况下用它就够了。" - -#: ../../execution.rst:376 -msgid "AsyncExecutionStrategy" -msgstr "异步执行策略(AsyncExecutionStrategy)" - -#: ../../execution.rst:378 -msgid "" -"By default the \"query\" execution strategy is " -"``graphql.execution.AsyncExecutionStrategy`` which will dispatch each " -"field as ``CompleteableFuture`` objects and not care which ones complete " -"first. This strategy allows for the most performant execution." -msgstr "默认的查询 执行策略是 ``graphql.execution.AsyncExecutionStrategy`` ,它会把每个 field 返回视为 ``CompleteableFuture`` 。它并不会控制 filed 的获取顺序. 这个策略可以优化查询执行的性能." - -#: ../../execution.rst:382 -msgid "" -"The data fetchers invoked can themselves return `CompletionStage`` values" -" and this will create fully asynchronous behaviour." -msgstr "Data fetchers 返回 `CompletionStage`` 对象,就可以全异步执行整个查询了。" - -#: ../../execution.rst:385 -msgid "So imagine a query as follows" -msgstr "例如以下的查询:" - -#: ../../execution.rst:401 -msgid "" -"The ``AsyncExecutionStrategy`` is free to dispatch the *enemies* field at" -" the same time as the *friends* field. It does not have to do *enemies* " -"first followed by *friends*, which would be less efficient." -msgstr " ``AsyncExecutionStrategy`` 策略可能会同时发起获取 *enemies* field 和 *friends* field 的操作。. 而不需要先发获取 *enemies* 再获取 *friends*,那样效率更低。" - -#: ../../execution.rst:404 -msgid "" -"It will however assemble the results in order. The query result will " -"follow the graphql specification and return object values assembled in " -"query field order. Only the execution of data fetching is free to be in " -"any order." -msgstr "这个策略不会按顺序来集成结果数据。但查询结果会按GraphQL规范顺序来返回。只是数据获取的顺序不确定。" - -#: ../../execution.rst:407 -msgid "" -"This behaviour is allowed in the graphql specification and in fact is " -"actively encouraged http://facebook.github.io/graphql/#sec-Query for read" -" only queries." -msgstr "对于查询,这个策略是 graphql 规范 http://facebook.github.io/graphql/#sec-Query 允许和推荐的。" - -#: ../../execution.rst:410 -msgid "" -"See `specification `_ for details." -msgstr "详细见 `规范 `_ ." - -#: ../../execution.rst:414 -msgid "AsyncSerialExecutionStrategy" -msgstr "异步顺序执行策略(AsyncSerialExecutionStrategy)" - -#: ../../execution.rst:416 -msgid "" -"The graphql specification says that mutations MUST be executed serially " -"and in the order in which the query fields occur." -msgstr "Graphql 规范指出,修改操作(mutations)“必须”按照 field 的顺序来执行。" - -#: ../../execution.rst:419 -msgid "" -"So ``graphql.execution.AsyncSerialExecutionStrategy`` is used by default " -"for mutations and will ensure that each field is completed before it " -"processes the next one and so forth. You can still return " -"``CompletionStage`` objects in the mutation data fetchers, however they " -"will be executed serially and will be completed before the next mutation " -"field data fetcher is dispatched." -msgstr "所以,为了确保一个 field 一个 field 顺序地执行更新,更新操作(mutations)默认使用 ``graphql.execution.AsyncSerialExecutionStrategy`` 策略。你的 mutation Data Fetcher 仍然可以返回 ``CompletionStage`` 对象, 但它和其它 field 的是串行执行的。 " - -#: ../../execution.rst:425 -msgid "ExecutorServiceExecutionStrategy" -msgstr "基于执行器的执行策略:ExecutorServiceExecutionStrategy " - -#: ../../execution.rst:427 -msgid "" -"The ``graphql.execution.ExecutorServiceExecutionStrategy`` execution " -"strategy will always dispatch each field fetch in an asynchronous manner," -" using the executor you give it. It differs from " -"``AsyncExecutionStrategy`` in that it does not rely on the data fetchers " -"to be asynchronous but rather makes the field fetch invocation " -"asynchronous by submitting each field to the provided " -"`java.util.concurrent.ExecutorService`." -msgstr " ``graphql.execution.ExecutorServiceExecutionStrategy`` 执行策略,使用了指定的执行器(executor),来异步地执行数据获取任务。它与 ``AsyncExecutionStrategy`` 执行策略不同,它不依赖 data fetchers 去异步执行获取任务,它依赖于输入的 `java.util.concurrent.ExecutorService` 。" - -#: ../../execution.rst:432 -msgid "" -"This behaviour makes it unsuitable to be used as a mutation execution " -"strategy." -msgstr "因为这样,所以它不能用于更新(mutation)操作。" - -#: ../../execution.rst:450 -msgid "SubscriptionExecutionStrategy" -msgstr "订阅执行策略(SubscriptionExecutionStrategy)" - -#: ../../execution.rst:452 -msgid "" -"Graphql subscriptions allows you to create stateful subscriptions to " -"graphql data. You uses ``SubscriptionExecutionStrategy`` as your " -"execution strategy as it has the support for the reactive-streams APIs." -msgstr "Graphql 订阅(subscriptions) 使你可以对GraphQL 数据进行为状态的订阅。你可以使用 ``SubscriptionExecutionStrategy`` 执行策略,它支持 reactive-streams APIs。" - -#: ../../execution.rst:455 -msgid "" -"See http://www.reactive-streams.org/ for more information on the reactive" -" ``Publisher`` and ``Subscriber`` interfaces." -msgstr "阅读 http://www.reactive-streams.org/ 可以得到关于 ``Publisher`` 和 ``Subscriber`` 接口的更多信息。" - -#: ../../execution.rst:457 -msgid "" -"Also see the page on subscriptions for more details on how to write a " -"subscription based graphql service." -msgstr "也可以阅读subscriptions的文档,以了解如何编写基于支持订阅的 graphql 服务。" - -#: ../../execution.rst:461 -msgid "BatchedExecutionStrategy" -msgstr "批量化执行器(BatchedExecutionStrategy)" - -#: ../../execution.rst:463 -msgid "" -"Alternatively, schemas with nested lists may benefit from using a " -"``graphql.execution.batched.BatchedExecutionStrategy`` and creating " -"batched DataFetchers with get() methods annotated @Batched." -msgstr "对于有数组(list)field 的 schemas, 我们提供了 ``graphql.execution.batched.BatchedExecutionStrategy`` 策略。它可以批量化地调用标注了@Batched 的 DataFetchers 的 get() 方法。" - -#: ../../execution.rst:468 -msgid "" -"on how BatchedExecutionStrategy works here. Its a pretty special case " -"that I don't know how to explain properly" -msgstr "关于 BatchedExecutionStrategy 是如何工作的。它是如此的特别,让我不知道如何解释【译注:原文:Its a pretty special case that I don't know how to explain properly】" - -#: ../../execution.rst:471 -msgid "Limiting Field Visibility" -msgstr "控制字段的可见性" - -#: ../../execution.rst:473 -msgid "" -"By default every fields defined in a `GraphqlSchema` is available. There" -" are cases where you may want to restrict certain fields depending on the" -" user." -msgstr "所有 `GraphqlSchema` 的字段(field)默认都是可以访问的。但有时候,你可能想不同用户看到不同部分的字段。" - -#: ../../execution.rst:476 -msgid "" -"You can do this by using a " -"`graphql.schema.visibility.GraphqlFieldVisibility` implementation and " -"attaching it to the schema." -msgstr "你可以在schema 上绑定一个 `graphql.schema.visibility.GraphqlFieldVisibility` 对象。." - -#: ../../execution.rst:478 -msgid "" -"A simple `graphql.schema.visibility.BlockedFields` implementation based " -"on fully qualified field name is provided." -msgstr "框架提供了一个可以指定字段(field)名的实现,叫 `graphql.schema.visibility.BlockedFields`.." - -#: ../../execution.rst:493 -msgid "" -"There is also another implementation that prevents instrumentation from " -"being able to be performed on your schema, if that is a requirement." -msgstr "如果你需要,还有一个实现可以防止 instrumentation 拦截你的 schema。" - -#: ../../execution.rst:495 -msgid "" -"Note that this puts your server in contravention of the graphql " -"specification and expectations of most clients so use this with caution." -msgstr "请注意,这会使您的服务器违反graphql规范和大多数客户端的预期,因此请谨慎使用." - -#: ../../execution.rst:506 -msgid "" -"You can create your own derivation of `GraphqlFieldVisibility` to check " -"what ever you need to do to work out what fields should be visible or " -"not." -msgstr "你可以编写自己的 `GraphqlFieldVisibility` 来控制字段的可见性。" - -#: ../../execution.rst:542 -msgid "Query Caching" -msgstr "查询缓存(Query Caching)" - -#: ../../execution.rst:544 -msgid "" -"Before the ``graphql-java`` engine executes a query it must be parsed and" -" validated, and this process can be somewhat time consuming." -msgstr " ``graphql-java`` 引擎执行查询前,必须先对查询语句作解释和校验,有时这是比较耗时的。" - -#: ../../execution.rst:546 -msgid "" -"To avoid the need for re-parse/validate the ``GraphQL.Builder`` allows an" -" instance of ``PreparsedDocumentProvider`` to reuse ``Document`` " -"instances." -msgstr "为了避免重复的解释和校验。 ``GraphQL.Builder`` 可以使用``PreparsedDocumentProvider``去重用 ``Document`` 实例。" - -#: ../../execution.rst:548 -msgid "" -"Please note that this does not cache the result of the query, only the " -"parsed ``Document``." -msgstr "它不是缓存 查询结果,只是缓存解释过的文档( ``Document`` )。" - -#: ../../execution.rst:558 -msgid "" -"Create an instance of preferred cache instance, here is `Caffeine " -"`_ used as it is a high quality " -"caching solution. The cache instance should be thread safe and shared." -msgstr "创建你需要的缓存实例,本例子是使用的是 `Caffeine `_ 。它是个高质量的缓存解决方案。缓存实例应该是线程安全和可以线程间共享的。" - -#: ../../execution.rst:559 -msgid "" -"The ``PreparsedDocumentProvider`` is a functional interface with only a " -"get method and we can therefore pass a method reference that matches the " -"signature into the builder." -msgstr "``PreparsedDocumentProvider`` 是一个函式接口( functional interface),方法名是get。." - -#: ../../execution.rst:562 -msgid "" -"In order to achieve high cache hit ration it is recommended that field " -"arguments are passed in as variables instead of directly in the query." -msgstr "为提高缓存命中率,GraphQL 语句中的 field 参数(arguments)建议使用变量( variables)来表达,而不是直接把值写在语句中。" - -#: ../../execution.rst:564 -msgid "The following query:" -msgstr "下面的查询 :" - -#: ../../execution.rst:574 -msgid "Should be rewritten as:" -msgstr "应该写成:" - -#: ../../execution.rst:584 -msgid "with variables:" -msgstr "带上参数( variables):" - -#: ../../execution.rst:592 -msgid "The query is now reused regardless of variable values provided." -msgstr "这样,这不管查询的变量(variable)如何变化 ,查询解释也就可以重用。" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/getting_started.mo b/docs/locale/zh_CN/LC_MESSAGES/getting_started.mo deleted file mode 100644 index 4a57f8acb5..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/getting_started.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/getting_started.po b/docs/locale/zh_CN/LC_MESSAGES/getting_started.po deleted file mode 100644 index 3e81614261..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/getting_started.po +++ /dev/null @@ -1,81 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../getting_started.rst:2 -msgid "Getting started" -msgstr "入门" - -#: ../../getting_started.rst:4 -msgid "``graphql-java`` requires at least Java 8." -msgstr "``graphql-java`` 需要运行于 Java 8 或更高版本." - -#: ../../getting_started.rst:8 -msgid "How to use the latest release with Gradle" -msgstr "如何在 Gradle 中使用最新正式版本" - -#: ../../getting_started.rst:10 -msgid "Make sure ``mavenCentral`` is among your repos:" -msgstr "首先,保证 ``mavenCentral`` 在你的 repos 库列表中:" - -#: ../../getting_started.rst:19 ../../getting_started.rst:31 -#: ../../getting_started.rst:73 ../../getting_started.rst:100 -msgid "Dependency:" -msgstr "依赖:" - -#: ../../getting_started.rst:29 -msgid "How to use the latest release with Maven" -msgstr "如果在 Maven 中使用最新正式版本" - -#: ../../getting_started.rst:43 -msgid "Hello World" -msgstr "Hello World【译注:这个用不翻译了吧 :) 】" - -#: ../../getting_started.rst:45 -msgid "This is the famous \"hello world\" in ``graphql-java``:" -msgstr "下面就用 ``graphql-java`` 来实现经典的 \"hello world\" :" - -#: ../../getting_started.rst:52 -msgid "Using the latest development build" -msgstr "如何使用最新的开发中版本" - -#: ../../getting_started.rst:54 -msgid "The latest development build is available on Bintray." -msgstr "最近的开发中版本,可以在 Bintray 上获取." - -#: ../../getting_started.rst:56 -msgid "" -"Please look at `Latest Build `_ for the latest version value." -msgstr "可以从 `最新版本 `_ 中看到最新的版本号." - -#: ../../getting_started.rst:61 -msgid "How to use the latest build with Gradle" -msgstr "如果在 Gradle 中使用最新的开发中版本" - -#: ../../getting_started.rst:63 -msgid "Add the repositories:" -msgstr "增加 repositories:" - -#: ../../getting_started.rst:84 -msgid "How to use the latest build with Maven" -msgstr "如果在 Maven 中使用最新的开发中版本" - -#: ../../getting_started.rst:87 -msgid "Add the repository:" -msgstr "增加 repository:" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/index.mo b/docs/locale/zh_CN/LC_MESSAGES/index.mo deleted file mode 100644 index 1fa6910f13..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/index.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/index.po b/docs/locale/zh_CN/LC_MESSAGES/index.po deleted file mode 100644 index d4712b87ff..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/index.po +++ /dev/null @@ -1,89 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-14 18:16+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../index.rst:2 -msgid "Welcome to graphql-java" -msgstr "欢迎使用 graphql-java" - -#: ../../index.rst:10 -msgid "" -"This is a GraphQL Java implementation based on the `specification " -"`_ and the JavaScript `reference " -"implementation `_." -msgstr "这是一个用Java实现的GraphQL。基于 `GraphQL规范 `_ 和 `JavaScript参考实现 `_." - -#: ../../index.rst:14 -msgid "**Status**: Version ``6.0`` is released." -msgstr "" - -#: ../../index.rst:16 -msgid "" -"Make sure to check out the `awesome related projects `_ built on ``graphql-java``." -msgstr "强烈推荐你关注一下 基于 ``graphql-java`` 开发的 `相关项目 `_ ." - -#: ../../index.rst:21 -msgid "Code of Conduct" -msgstr "贡献或编码的行为规范" - -#: ../../index.rst:23 -msgid "" -"Please note that this project is released with a `Contributor Code of " -"Conduct `_. By contributing to this project " -"(commenting or opening PR/Issues etc) you are agreeing to follow this " -"conduct, so please take the time to read it." -msgstr "请注意,这个项目的发行条款,包括了 `贡献或编码的行为规范 `_为本项目作贡献(提交代码和问题等【译注原文:commenting or opening PR/Issues etc】)的同时,你即同意遵守这个行为规范,所以请你花时间认真阅读它." - -#: ../../index.rst:29 -msgid "Questions and discussions" -msgstr "问题与讨论" - -#: ../../index.rst:31 -msgid "" -"If you have a question or want to discuss anything else related to this " -"project:" -msgstr "如果你有问题或想讨论与本项目相关的事:" - -#: ../../index.rst:33 -msgid "" -"Feel free to open a new `Issue `_" -msgstr "请随时提出新 `Issue `_" - -#: ../../index.rst:35 -msgid "" -"We have a public chat room (Gitter.im) for graphql-java: " -"https://gitter.im/graphql-java/graphql-java" -msgstr "我们为graphql-java,准备了一个公开的聊天室 (Gitter.im) : https://gitter.im/graphql-java/graphql-java" - -#: ../../index.rst:39 -msgid "License" -msgstr "发行授权" - -#: ../../index.rst:41 -msgid "graphql-java is licensed under the MIT License." -msgstr "" - -#: ../../index.rst:44 -msgid "Documentation" -msgstr "文档" - -#~ msgid "**Status**: Version ``5.0.0`` is released." -#~ msgstr "" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/instrumentation.mo b/docs/locale/zh_CN/LC_MESSAGES/instrumentation.mo deleted file mode 100644 index f776b00e56..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/instrumentation.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/instrumentation.po b/docs/locale/zh_CN/LC_MESSAGES/instrumentation.po deleted file mode 100644 index a68c6bd7fd..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/instrumentation.po +++ /dev/null @@ -1,129 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../instrumentation.rst:2 -msgid "Instrumentation" -msgstr "拦截器Instrumentation" - -#: ../../instrumentation.rst:5 -msgid "" -"The ``graphql.execution.instrumentation.Instrumentation`` interface " -"allows you to inject code that can observe the execution of a query and " -"also change the runtime behaviour." -msgstr "通过实现 ``graphql.execution.instrumentation.Instrumentation`` 接口,你可以在执行查询的过程中注入定制代码。并可以修改运行期的行为。" - -#: ../../instrumentation.rst:8 -msgid "" -"The primary use case for this is to allow say performance monitoring and " -"custom logging but it could be used for many different purposes." -msgstr "它的主要用途是性能监控和定制日志,但也可以完成其它任务。" - -#: ../../instrumentation.rst:10 -msgid "" -"When you build the ```Graphql`` object you can specify what " -"``Instrumentation`` to use (if any)." -msgstr "当创建 ```Graphql`` 对象时,可以绑定相关的 ``Instrumentation`` 。" - -#: ../../instrumentation.rst:20 -msgid "Custom Instrumentation" -msgstr "定制拦截器(Custom Instrumentation)" - -#: ../../instrumentation.rst:22 -msgid "" -"An implementation of ``Instrumentation`` needs to implement the \"begin\"" -" step methods that represent the execution of a graphql query." -msgstr "要实现 ``Instrumentation`` ,需要实现多个 \"begin\" 开头的方法。这方法会在查询执行过程中,每一步骤开始前被调用。" - -#: ../../instrumentation.rst:24 -msgid "" -"Each step must give back a non null " -"``graphql.execution.instrumentation.InstrumentationContext`` object which" -" will be called back when the step completes, and will be told that it " -"succeeded or failed with a Throwable." -msgstr "所有回调方法,都应该返回 ``graphql.execution.instrumentation.InstrumentationContext`` 对象,这个对象会在本步骤完成时被回调用,回调用时会告知数据的获取结果,如果出错,可以获取 Throwable 对象。." - -#: ../../instrumentation.rst:27 -msgid "" -"The following is a basic custom ``Instrumentation`` that measures overall" -" execution time and puts it into a stateful object." -msgstr "下面是一个定制的 ``Instrumentation`` 。作用是测量执行时间。" - -#: ../../instrumentation.rst:113 -msgid "Chaining Instrumentation" -msgstr "链式拦截(Chaining Instrumentation)" - -#: ../../instrumentation.rst:115 -msgid "" -"You can combine multiple ``Instrumentation`` objects together using the " -"``graphql.execution.instrumentation.ChainedInstrumentation`` class which " -"accepts a list of ``Instrumentation`` objects and calls them in that " -"defined order." -msgstr "你可以用 ``graphql.execution.instrumentation.ChainedInstrumentation`` 把多个 ``Instrumentation`` 连接起来。这些 ``Instrumentation`` 对象会按顺序被调用。" - -#: ../../instrumentation.rst:132 -msgid "Apollo Tracing Instrumentation" -msgstr "Apollo跟踪与拦截( Tracing Instrumentation)" - -#: ../../instrumentation.rst:134 -msgid "" -"``graphql.execution.instrumentation.tracing.TracingInstrumentation`` is " -"an ``Instrumentation`` implementation that creates tracing information " -"about the query that is being executed." -msgstr "``graphql.execution.instrumentation.tracing.TracingInstrumentation`` 是一个可以收集跟踪信息的拦截器。" - -#: ../../instrumentation.rst:137 -msgid "" -"It follows the Apollo proposed tracing format defined at " -"`https://github.com/apollographql/apollo-tracing " -"`_" -msgstr "它按照 Apollo 跟踪格式 `https://github.com/apollographql/apollo-tracing `_ 来收集跟踪信息。" - -#: ../../instrumentation.rst:139 -msgid "" -"A detailed tracing map will be created and placed in the ``extensions`` " -"section of the result." -msgstr "详细的跟踪信息( tracing map)会放在查询结果的 ``extensions(扩展)`` 部分。" - -#: ../../instrumentation.rst:141 -msgid "So given a query like" -msgstr "如以下的查询:" - -#: ../../instrumentation.rst:154 -msgid "It would return a result like" -msgstr "会返回如下的结果:" - -#: ../../instrumentation.rst:261 -msgid "Field Validation Instrumentation" -msgstr "字段校验拦截器(Field Validation Instrumentation)" - -#: ../../instrumentation.rst:263 -msgid "" -"``graphql.execution.instrumentation.fieldvalidation.FieldValidationInstrumentation``" -" is an ``Instrumentation`` implementation that can be used to validate " -"fields and their arguments before query execution. If errors are " -"returned during this process then the query execution is aborted and the " -"errors will be in the query result." -msgstr "``graphql.execution.instrumentation.fieldvalidation.FieldValidationInstrumentation`` 拦截器,可以在执行查询前校验字段和字段参数。如果校验失败,查询将停止,并返回错误信息。" - -#: ../../instrumentation.rst:267 -msgid "" -"You can make you own custom implementation of ``FieldValidation`` or you " -"can use the ``SimpleFieldValidation`` class to add simple per field " -"checks rules." -msgstr "你可以编写自己的``FieldValidation`` 实现,或者直接用 ``SimpleFieldValidation`` 去为每个field定义校验逻辑。" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/logging.mo b/docs/locale/zh_CN/LC_MESSAGES/logging.mo deleted file mode 100644 index 64f4e53a0f..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/logging.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/logging.po b/docs/locale/zh_CN/LC_MESSAGES/logging.po deleted file mode 100644 index 3ac8dfb981..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/logging.po +++ /dev/null @@ -1,29 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../logging.rst:2 -msgid "Logging" -msgstr "日志(Logging)" - -#: ../../logging.rst:4 -msgid "" -"Logging is done with `SLF4J `_. Please have a look" -" at the `Manual `_ for details. The " -"``graphql-java`` root Logger name is ``graphql``." -msgstr "我们使用 `SLF4J `_ 来记录日志。详情可以见 `手册 `_ 。``graphql-java`` 的 root Logger 名字是 ``graphql``。" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/relay.mo b/docs/locale/zh_CN/LC_MESSAGES/relay.mo deleted file mode 100644 index c0040a5101..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/relay.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/relay.po b/docs/locale/zh_CN/LC_MESSAGES/relay.po deleted file mode 100644 index eeb316739f..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/relay.po +++ /dev/null @@ -1,64 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../relay.rst:2 -msgid "Relay Support" -msgstr "关于 Relay 支持" - -#: ../../relay.rst:5 -msgid "" -"Very basic support for `Relay `_ is " -"included." -msgstr "包含了一些基础的 `Relay `_ 特性的支持。" - -#: ../../relay.rst:7 -msgid "" -"**Note**: Relay refers here to \"Relay Classic\", there is no support for" -" \"Relay Modern\"." -msgstr "**注意**: 这里的 Relay 指 \"Relay Classic\", 暂不支持 \"Relay Modern\"." - -#: ../../relay.rst:9 -msgid "" -"Please look at https://github.com/graphql-java/todomvc-relay-java for a " -"full example project," -msgstr "完整的例子,见 https://github.com/graphql-java/todomvc-relay-java 。" - -#: ../../relay.rst:11 -msgid "" -"Relay send queries to the GraphQL server as JSON containing a ``query`` " -"field and a ``variables`` field. The ``query`` field is a JSON string, " -"and the ``variables`` field is a map of variable definitions. A relay-" -"compatible server will need to parse this JSON and pass the ``query`` " -"string to this library as the query and the ``variables`` map as the " -"third argument to ``execute`` as shown below." -msgstr "Relay 以 JSON 格式,向服务器发送 ``query`` 和 ``variables`` 两个字段。``query`` 字段是一个 JSON 格式的字符串, ``variables`` 字段是一个 变量定义( variable definitions) 的 map。relay 兼容的服务器,需要解释 JSON 然后传 ``query`` 字符串到本框架。包括 ``variables`` map 作为 ``execute`` 方法的第3个参数。如下:" - -#: ../../relay.rst:37 -msgid "Apollo Support" -msgstr "Apollo 支持" - -#: ../../relay.rst:39 -msgid "" -"There is no special support for `Apollo `_ included: Apollo works with any schema." -msgstr "没有为对接 `Apollo `_ 客户端做什么。因它兼容所有schema。" - -#: ../../relay.rst:41 -msgid "The Controller example shown above works with Apollo too." -msgstr "上面的 Controller 例子一样可以与 Apollo 客户端交互。" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/schema.mo b/docs/locale/zh_CN/LC_MESSAGES/schema.mo deleted file mode 100644 index 822d0c5b4b..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/schema.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/schema.po b/docs/locale/zh_CN/LC_MESSAGES/schema.po deleted file mode 100644 index 4e4c1bf152..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/schema.po +++ /dev/null @@ -1,475 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-14 18:16+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../schema.rst:2 -msgid "Creating a schema" -msgstr "创建Schema" - -#: ../../schema.rst:5 -msgid "" -"A schema defines your GraphQL API by defining each field that can be " -"queried or mutated." -msgstr "Schema的主要用途是定义所有可供查询的字段(field),它们最终组合成一套完整的GraphQL API." - -#: ../../schema.rst:8 -msgid "" -"``graphql-java`` offers two different ways of defining the schema: " -"Programmatically as Java code or via a special graphql dsl (called SDL)." -msgstr "“graphql-java”提供两种方法来定义Schema。用java代码来定义、用GraphQL SDL(即IDL)来定义。" - -#: ../../schema.rst:11 -msgid "" -"NOTE: SDL is not currently part of the `formal graphql spec " -"`_. The implementation in this library is based off the " -"`reference implementation `_. " -"However plenty of code out there is based on this SDL syntax and hence " -"you can be fairly confident that you are building on solid technology " -"ground." -msgstr "注意:SDL(IDL)现在还不是 `官方 graphql 规范 `_. 本GraphQL实现,是基于 `已有的JS参考实现 `_ 来开发的。但JS参考实现中的很多代码也是基于SDL(IDL)语法的,所以你可以认为这语法是可以长期使用的." - -#: ../../schema.rst:16 -msgid "If you are unsure which option to use we recommend the SDL." -msgstr "如果你不确认用“java代码”还是用“GraphQL SDL(即IDL)”来定义你的Schema,那么我们建议你用SDL(IDL)" - -#: ../../schema.rst:18 -msgid "SDL example:" -msgstr "" - -#: ../../schema.rst:27 -msgid "Java code example:" -msgstr "java代码例子:" - -#: ../../schema.rst:39 -msgid "DataFetcher and TypeResolver" -msgstr "DataFetcher 与 TypeResolver" - -#: ../../schema.rst:41 -msgid "" -"A ``DataFetcher`` provides the data for a field (and changes something, " -"if it is a mutation)." -msgstr "对象 ``DataFetcher`` 作用是获取字段(field)对应的数据;另外,在修改(mutation)操作时,可以更新数据" - -#: ../../schema.rst:43 -msgid "" -"Every field definition has a ``DataFetcher``. When one is not configured," -" a `PropertyDataFetcher `_" -" is used." -msgstr "每个字段都有自己的 ``DataFetcher``. 如果未为字段指定DataFetcher, 那么自动使用默认的 `PropertyDataFetcher `_ ." - -#: ../../schema.rst:46 -msgid "" -"``PropertyDataFetcher`` fetches data from ``Map`` and Java Beans. So when" -" the field name matches the Map key or the property name of the source " -"Object, no ``DataFetcher`` is needed." -msgstr "``PropertyDataFetcher`` 从 ``Map`` 和 Java Beans 中获取数据. 所以,当Schema中的field名,与Map中的key值,或 ``Source Object`` 中的 java bean 字段名相同时,不需要为field指定 ``DataFetcher``." - -#: ../../schema.rst:49 -msgid "" -"A ``TypeResolver`` helps ``graphql-java`` to decide which type a concrete" -" value belongs to. This is needed for ``Interface`` and ``Union``." -msgstr "对象 ``TypeResolver`` 帮助 ``graphql-java`` 判断数据的实际类型(type). 所以 ``Interface`` 和 ``Union`` 均需要指定关联的 ``TypeResolver(类型识别器)`` ." - -#: ../../schema.rst:52 -msgid "" -"For example imagine you have an ``Interface`` called *MagicUserType* " -"which resolves back to a series of Java classes called *Wizard*, *Witch* " -"and *Necromancer*. The type resolver is responsible for examining a " -"runtime object and deciding what ``GraphqlObjectType`` should be used to " -"represent it, and hence what data fetchers and fields will be invoked." -msgstr "例如,你有一个 ``Interface`` 叫 *MagicUserType* 它有可能是以下的具体类型(Type) *Wizard*, *Witch* and *Necromancer*. Type resolver(类型识别器) 的作用是在运行时识别出 ``GraphqlObjectType`` 的具体类型(Type)。后期具体类型下的field相关的 data fetcher被调用并获取数据." - -#: ../../schema.rst:75 -msgid "Creating a schema using the SDL" -msgstr "用 SDL 创建 Schema" - -#: ../../schema.rst:77 -msgid "" -"When defining a schema via SDL, you provide the needed ``DataFetcher`` s " -"and ``TypeResolver`` s when the executable schema is created." -msgstr "当使用SDL方法来开发时,你需要同时编写对应的 ``DataFetcher`` 和 ``TypeResolver``。" - -#: ../../schema.rst:80 -msgid "" -"Take for example the following static schema definition file called " -"``starWarsSchema.graphqls``:" -msgstr "很大的 Schema IDL 文件很难查看。" - -#: ../../schema.rst:125 -msgid "" -"The static schema definition file ``starWarsSchema.graphqls`` contains " -"the field and type definitions, but you need a runtime wiring to make it " -"a truly executable schema." -msgstr "由于Schema中只是指定了静态的字段和类型,你还需要把它绑定到java方法中。以让Schema可以运行起来" - -#: ../../schema.rst:128 -msgid "" -"The runtime wiring contains ``DataFetcher`` s, ``TypeResolvers`` s and " -"custom ``Scalar`` s that are needed to make a fully executable schema." -msgstr "这里的绑定,包括 ``DataFetcher`` , ``TypeResolvers`` 与自定义 ``Scalar``." - -#: ../../schema.rst:131 -msgid "You wire this together using this builder pattern:" -msgstr "用下页的Builder方法,就可以绑定Schema和Java程序" - -#: ../../schema.rst:161 -msgid "" -"Finally, you can generate an executable schema by combining the static " -"schema and the wiring together as shown in this example:" -msgstr "最后,你可以通过整合静态 Schema 和 绑定(wiring),而生成一个可以执行的 Schema。" - -#: ../../schema.rst:176 -msgid "" -"In addition to the builder style shown above, ``TypeResolver`` s and " -"``DataFetcher`` s can also be wired in using the ``WiringFactory`` " -"interface. This allows for a more dynamic runtime wiring since the SDL " -"definitions can be examined in order to decide what to wire in. You " -"could for example look at SDL directives, or some other aspect of the SDL" -" definition to help you decide what runtime to create." -msgstr "除了上面的 builder 风格, ``TypeResolver`` s 与 ``DataFetcher`` s 也可以通过 ``WiringFactory`` 接口绑定在一起。通过程序去分析 SDL ,就可以允许更自由的绑定。你可以 通过分析 SDL 声明, 或其它 SDL 定义去决定你的运行时逻辑。" - -#: ../../schema.rst:223 -msgid "Creating a schema programmatically" -msgstr "用代码方式创建 schema " - -#: ../../schema.rst:225 -msgid "" -"When the schema is created programmatically ``DataFetcher`` s and " -"``TypeResolver`` s are provided at type creation:" -msgstr "如果用程序方式来定义 Schema,在创建类型(type)的时候,你需要提供 ``DataFetcher`` and ``TypeResolver` 。" - -#: ../../schema.rst:227 -msgid "Example:" -msgstr "如:" - -#: ../../schema.rst:249 -msgid "Types" -msgstr "类型(Types)" - -#: ../../schema.rst:251 -msgid "The GraphQL type system supports the following kind of types:" -msgstr "GraphQL 类型系统支持以下类型" - -#: ../../schema.rst:253 ../../schema.rst:263 -msgid "Scalar" -msgstr "" - -#: ../../schema.rst:254 ../../schema.rst:283 -msgid "Object" -msgstr "" - -#: ../../schema.rst:255 ../../schema.rst:313 -msgid "Interface" -msgstr "" - -#: ../../schema.rst:256 ../../schema.rst:339 -msgid "Union" -msgstr "" - -#: ../../schema.rst:257 -msgid "InputObject" -msgstr "" - -#: ../../schema.rst:258 ../../schema.rst:382 -msgid "Enum" -msgstr "" - -#: ../../schema.rst:265 -msgid "``graphql-java`` supports the following Scalars:" -msgstr "``graphql-java`` 支持以下基本数据类型( Scalars)。" - -#: ../../schema.rst:268 -msgid "``GraphQLString``" -msgstr "" - -#: ../../schema.rst:269 -msgid "``GraphQLBoolean``" -msgstr "" - -#: ../../schema.rst:270 -msgid "``GraphQLInt``" -msgstr "" - -#: ../../schema.rst:271 ../../schema.rst:276 -msgid "``GraphQLFloat``" -msgstr "" - -#: ../../schema.rst:272 -msgid "``GraphQLID``" -msgstr "" - -#: ../../schema.rst:273 -msgid "``GraphQLLong``" -msgstr "" - -#: ../../schema.rst:274 -msgid "``GraphQLShort``" -msgstr "" - -#: ../../schema.rst:275 -msgid "``GraphQLByte``" -msgstr "" - -#: ../../schema.rst:277 -msgid "``GraphQLBigDecimal``" -msgstr "" - -#: ../../schema.rst:278 -msgid "``GraphQLBigInteger``" -msgstr "" - -#: ../../schema.rst:285 ../../schema.rst:317 ../../schema.rst:341 -#: ../../schema.rst:384 ../../schema.rst:411 -msgid "SDL Example:" -msgstr "" - -#: ../../schema.rst:295 ../../schema.rst:325 ../../schema.rst:358 -#: ../../schema.rst:395 ../../schema.rst:420 -msgid "Java Example:" -msgstr "Java 例子:" - -#: ../../schema.rst:315 -msgid "Interfaces are abstract definitions of types." -msgstr "" - -#: ../../schema.rst:409 -msgid "ObjectInputType" -msgstr "" - -#: ../../schema.rst:433 -msgid "Type References (recursive types)" -msgstr "类型引用 (Type References) (递归类型recursive types)" - -#: ../../schema.rst:435 -msgid "" -"GraphQL supports recursive types: For example a ``Person`` can contain a " -"list of friends of the same type." -msgstr "GraphQL 支持递归类型:如 ``Person(人)`` 可以包含很多朋友【译注:当然这些也是人类型的】" - -#: ../../schema.rst:437 -msgid "" -"To be able to declare such a type, ``graphql-java`` has a " -"``GraphQLTypeReference`` class." -msgstr "为了方便声明这种情况, ``graphql-java`` 有一个 ``GraphQLTypeReference`` 类。" - -#: ../../schema.rst:439 -msgid "" -"When the schema is created, the ``GraphQLTypeReference`` is replaced with" -" the actual real type Object." -msgstr "在实际的 Schema 创建时,``GraphQLTypeReference`` 会变为实际的类型。" - -#: ../../schema.rst:441 -msgid "For example:" -msgstr "例如:" - -#: ../../schema.rst:452 -msgid "" -"When the schema is declared via SDL, no special handling of recursive " -"types is needed." -msgstr "如果用SDL(ID L)来定义 Schema ,不需要特殊的处理。" - -#: ../../schema.rst:455 -msgid "Modularising the Schema SDL" -msgstr "Schema IDL的模块化" - -#: ../../schema.rst:457 -msgid "" -"Having one large schema file is not always viable. You can modularise " -"you schema using two techniques." -msgstr "很大的 Schema IDL 文件很难查看。所以我们有两种方法可以模块化 Schema。" - -#: ../../schema.rst:459 -msgid "" -"The first technique is to merge multiple Schema SDL files into one logic " -"unit. In the case below the schema has been split into multiple files " -"and merged all together just before schema generation." -msgstr "方法一是合并多个 Schema IDL 文件到一个逻辑单元( logic unit)。下面的例子是,在 Schema 生成前,合并多个独立的文件。" - -#: ../../schema.rst:480 -msgid "" -"The Graphql SDL type system has another construct for modularising a " -"schema. You can use `type extensions` to add extra fields and interfaces" -" to a type." -msgstr "Graphql IDL 还有其它方法去做模块化。你可以使用 `type extensions` 去为现有类型增加字段和 interface。" - -#: ../../schema.rst:483 -msgid "Imagine you start with a type like this in one schema file." -msgstr "例如,一开始,你有这样一个文件:" - -#: ../../schema.rst:492 -msgid "Another part of your system can extend this type to add more shape to it." -msgstr "你的系统的其它模块可以扩展这个类型:" - -#: ../../schema.rst:503 -msgid "" -"You can have as many extensions as you think sensible. They will be " -"combined in the order in which they are encountered. Duplicate fields " -"will be merged as one (however field re-definitions into new types are " -"not allowed)." -msgstr "你可以按你的需要去扩展。它们会以被发现的顺序组合起来。重复的字段会被合并(但重定义一个字段的类型是不允许的)。" - -#: ../../schema.rst:514 -msgid "" -"With all these type extensions in place the `Human` type now looks like " -"this at runtime." -msgstr "完成合并后的 `Human` 类型会是这样的:" - -#: ../../schema.rst:526 -msgid "" -"This is especially useful at the top level. You can use extension types " -"to add new fields to the top level schema \"query\". Teams could " -"contribute \"sections\" on what is being offered as the total graphql " -"query." -msgstr "这在顶层查询中特别有用。你可以用 extension types 去为顶层 \"query\" 增加字段每个团队可以提供自己的字段集,进而合成完整的查询。" - -#: ../../schema.rst:559 -msgid "Subscription Support" -msgstr "Subscription(订阅)的支持" - -#: ../../schema.rst:561 -msgid "" -"Subscriptions are not officially specified yet: ``graphql-java`` supports" -" currently a very basic implementation where you can define a " -"subscription in the schema with " -"``GraphQLSchema.Builder.subscription(...)``. This enables you to handle a" -" subscription request:" -msgstr "订阅功能还未在规范中: ``graphql-java`` 现在只支持简单的实现 ,你可以用 ``GraphQLSchema.Builder.subscription(...)`` 在 Schema 中定义订阅。这使你可以处理订阅请求。" - -#~ msgid "" -#~ "``graphql-java`` offers two different " -#~ "ways of defining the schema: " -#~ "Programmatically as Java code or via " -#~ "a special graphql dsl (called IDL)." -#~ msgstr "" - -#~ msgid "" -#~ "NOTE: IDL is not currently part of" -#~ " the `formal graphql spec " -#~ "`_. The " -#~ "implementation in this library is based" -#~ " off the `reference implementation " -#~ "`_. However " -#~ "plenty of code out there is based" -#~ " on this IDL syntax and hence " -#~ "you can be fairly confident that " -#~ "you are building on solid technology " -#~ "ground." -#~ msgstr "" - -#~ msgid "If you are unsure which option to use we recommend the IDL." -#~ msgstr "" - -#~ msgid "IDL example:" -#~ msgstr "" - -#~ msgid "" -#~ "For example imagine you have a " -#~ "``Interface`` called *MagicUserType* and it" -#~ " resolves back to a series of " -#~ "Java classes called perhaps *Wizard*, " -#~ "*Witch* and *Necromancer*. The type " -#~ "resolver is responsible for examining a" -#~ " runtime object and deciding what " -#~ "``GraphqlObjectType`` should be used to " -#~ "represent it and hence what data " -#~ "fetchers and fields will be invoked." -#~ msgstr "" - -#~ msgid "IDL" -#~ msgstr "" - -#~ msgid "" -#~ "When defining a schema via IDL, " -#~ "you provide the needed ``DataFetcher`` s " -#~ "and ``TypeResolver`` s when the schema is" -#~ " created:" -#~ msgstr "" - -#~ msgid "You could generate an executable schema via" -#~ msgstr "" - -#~ msgid "" -#~ "The static schema definition file has" -#~ " the field and type definitions but" -#~ " you need a runtime wiring to " -#~ "make it a truly executable schema." -#~ msgstr "" - -#~ msgid "" -#~ "The runtime wiring contains ``DataFetcher``s," -#~ " ``TypeResolvers``s and custom ``Scalar``s " -#~ "that are needed to make a fully" -#~ " executable schema." -#~ msgstr "" - -#~ msgid "" -#~ "There is a another way to wiring" -#~ " in type resolvers and data fetchers" -#~ " and that is via the " -#~ "``WiringFactory`` interface. This allow for" -#~ " a more dynamic runtime wiring since" -#~ " the IDL definitions can be examined" -#~ " in order to decide what to " -#~ "wire in. You could for example " -#~ "look at IDL directives to help you" -#~ " decide what runtime to create or " -#~ "some other aspect of the IDL " -#~ "definition." -#~ msgstr "" - -#~ msgid "Programmatically" -#~ msgstr "" - -#~ msgid "" -#~ "When the schema is created " -#~ "programmatically you provide the " -#~ "``DataFetcher`` and ``TypeResolver`` when the" -#~ " type is created:" -#~ msgstr "" - -#~ msgid "IDL Example:" -#~ msgstr "" - -#~ msgid "" -#~ "When the schema is declared via " -#~ "IDL, no special handling of recursive" -#~ " types is needed." -#~ msgstr "" - -#~ msgid "Modularising the Schema IDL" -#~ msgstr "" - -#~ msgid "" -#~ "The first technique is to merge " -#~ "multiple Schema IDL files into one " -#~ "logic unit. In the case below the" -#~ " schema has been split into multiple" -#~ " files and merged all together just" -#~ " before schema generation." -#~ msgstr "" - -#~ msgid "" -#~ "The Graphql IDL type system has " -#~ "another construct for modularising your " -#~ "schema. You can use `type extensions`" -#~ " to add extra fields and interfaces" -#~ " to a type." -#~ msgstr "" - diff --git a/docs/locale/zh_CN/LC_MESSAGES/subscriptions.mo b/docs/locale/zh_CN/LC_MESSAGES/subscriptions.mo deleted file mode 100644 index a073a27b63..0000000000 Binary files a/docs/locale/zh_CN/LC_MESSAGES/subscriptions.mo and /dev/null differ diff --git a/docs/locale/zh_CN/LC_MESSAGES/subscriptions.po b/docs/locale/zh_CN/LC_MESSAGES/subscriptions.po deleted file mode 100644 index b7dfa40778..0000000000 --- a/docs/locale/zh_CN/LC_MESSAGES/subscriptions.po +++ /dev/null @@ -1,132 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2017, Brad Baker -# This file is distributed under the same license as the graphql-java -# package. -# FIRST AUTHOR , 2017. -# -msgid "" -msgstr "Project-Id-Version: graphql-java current\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-11-11 19:21+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.5.1\n" - -#: ../../subscriptions.rst:2 -msgid "Subscriptions" -msgstr "订阅(Subscriptions)" - -#: ../../subscriptions.rst:5 -msgid "Subscription Queries" -msgstr "订阅查询(Subscription Queries)" - -#: ../../subscriptions.rst:7 -msgid "" -"Graphql subscriptions allow you subscribe to a reactive source and as new" -" data arrives then a graphql query is applied over that data and the " -"results are passed on." -msgstr "Graphql 订阅(subscriptions)使你可以让你订阅响应式数据源(reactive source) 。当有新数据时,会发送给订阅者。" - -#: ../../subscriptions.rst:10 -msgid "" -"See http://graphql.org/blog/subscriptions-in-graphql-and-relay/ for more " -"general details on graphql subscriptions." -msgstr "可以阅读 http://graphql.org/blog/subscriptions-in-graphql-and-relay/ 来了解订阅的背景知识。" - -#: ../../subscriptions.rst:14 -msgid "" -"Imagine you have an stock market pricing service and you make a graphql " -"subscription to it like this" -msgstr "假设你有一个股票服务。可以用这个 graphql 语句来订阅它的数据:" - -#: ../../subscriptions.rst:27 -msgid "" -"graphql subscriptions allow a stream of ``ExecutionResult`` objects to be" -" sent down each time the stock price changes. The field selection set " -"will applied to the underlying data and are represented just like any " -"other graphql query." -msgstr "股票价格变化时,graphql 订阅 可以把 ``ExecutionResult`` 对象以流的方式传送给订阅者。和其它 graphql 查询一样,只会发送指定的字段 。" - -#: ../../subscriptions.rst:31 -msgid "" -"What is special is that the initial result of a subscription query is a " -"reactive-streams ``Publisher`` object which you need to use to get the " -"future values." -msgstr "不同的是,一开始的查询结果是一个响应式流(reactive-streams) ``Publisher(流发布者)`` 对象。通过对象可以获取未来的数据。" - -#: ../../subscriptions.rst:34 -msgid "" -"You need to use ``SubscriptionExecutionStrategy`` as your execution " -"strategy as it has the support for the reactive-streams APIs." -msgstr "你需要使用 ``SubscriptionExecutionStrategy`` 策略作为执行策略(execution strategy)。因为它支持 reactive-streams APIs." - -#: ../../subscriptions.rst:47 -msgid "" -"The ``Publisher`` here is the publisher of a stream of " -"events. You need to subscribe to this with your processing code which " -"will look something like the following" -msgstr "这里的 ``Publisher`` 就是流事件的发布者【译注:原文 publisher of a stream of events】。你需要编写你自己的流处理代码,如:" - -#: ../../subscriptions.rst:111 -msgid "" -"You are now writing reactive-streams code to consume a series of " -"``ExecutionResults``. You can see more details on reactive-streams code " -"here http://www.reactive-streams.org/" -msgstr "需要编写 reactive-streams 代码去消费一源源不断的 ``ExecutionResults``。你可以在 http://www.reactive-streams.org/ 中看到更 reactive-streams 代码的编写细节。" - -#: ../../subscriptions.rst:114 -msgid "" -"``RxJava`` is a popular implementation of reactive-streams. Check out " -"http://reactivex.io/intro.html to find out more about creating Publishers" -" of data and Subscriptions to that data." -msgstr "``RxJava``是这个流行的 reactive-streams 实现。在 http://reactivex.io/intro.html 中可以看到更多创建Publishers 数据 和 Subscriptions 数据的细节。" - -#: ../../subscriptions.rst:117 -msgid "" -"graphql-java only produces a stream of results. It does not concern " -"itself with sending these over the network on things like web sockets and" -" so on. That is important but not a concern of the base graphql-java " -"library." -msgstr "graphql-java 只是产出一个流对象。它不关心如何在网络上用 web sockets 或其它手段发送流数据 。虽然这很重要,但不是作为基础 graphql-java 库应该做的。" - -#: ../../subscriptions.rst:120 -msgid "" -"We have put together a basic example of using websockets (backed by " -"Jetty) with a simulated stock price application that is built using " -"RxJava." -msgstr "我们编写了一个 websockets 的(基于 Jetty) 模拟股票报价的示例应用。它使用了 RxJava。" - -#: ../../subscriptions.rst:123 -msgid "" -"See https://github.com/graphql-java/graphql-java-subscription-example for" -" more detailed code on handling network concerns and the like." -msgstr "详见 https://github.com/graphql-java/graphql-java-subscription-example" - -#: ../../subscriptions.rst:128 -msgid "Subscription Data Fetchers" -msgstr "关于订阅服务的 Data Fetchers" - -#: ../../subscriptions.rst:130 -msgid "" -"The ``DataFetcher`` behind a subscription field is responsible for " -"creating the ``Publisher`` of data. The objects return by this Publisher" -" will be mapped over the graphql query as each arrives and then sent back" -" out as an execution result." -msgstr "订阅字段的 ``DataFetcher`` 的职责是生成一个 ``Publisher``。这个 Publisher 输出的每一个对象,将会通过 graphql 查询来映射。然后作为执行结果返回。" - -#: ../../subscriptions.rst:133 -msgid "You data fetcher is going to look something like this." -msgstr "你会像这样子去编写Data Fetcher:" - -#: ../../subscriptions.rst:146 -msgid "" -"Now the exact details of how you get that stream of events is up to you " -"and you're reactive code. graphql-java gives you a way to map the " -"graphql query fields over that stream of objects just like a standard " -"graphql query." -msgstr "如何获取流事件,就由你的 reactive code 来决定 了。graphql-java 会帮助你从流对象中获取 graphql 字段(fields)。像一般的 graphql 查询一样。" - diff --git a/docs/logging.rst b/docs/logging.rst deleted file mode 100644 index 520b8b3435..0000000000 --- a/docs/logging.rst +++ /dev/null @@ -1,5 +0,0 @@ -Logging -======= - -Logging is done with `SLF4J `_. Please have a look at the `Manual `_ for details. -The ``graphql-java`` root Logger name is ``graphql``. diff --git a/docs/mapping.rst b/docs/mapping.rst deleted file mode 100644 index 2d4663b9a6..0000000000 --- a/docs/mapping.rst +++ /dev/null @@ -1,205 +0,0 @@ -Mapping data -============ - -How graphql maps object data to types -------------------------------------- - -At its heart graphql is all about declaring a type schema and mapping that over backing runtime data. - -As the designer of the type schema, it is your challenge to get these elements to meet in the middle. - -For example imagine we want to have a graphql type schema as follows: - - -.. code-block:: graphql - - type Query { - products(match : String) : [Product] # a list of products - } - - type Product { - id : ID - name : String - description : String - cost : Float - tax : Float - } - -We could then run queries over this simple schema via a something like the following: - -.. code-block:: graphql - - query ProductQuery { - products(match : "Paper*") - { - id, name, cost, tax - } - } - -We will have a ``DataFetcher`` on the ``Query.products`` field that is responsible for finding a list of products that match -the argument passed in. - -Now imagine we have 3 downstream services. One that gets product information, one that gets product cost information and one that calculates -product tax information. - -graphql-java works by running data fetchers over objects for all that information and mapping that back to the types specified in the schema. - -Our challenge is to take these 3 sources of information and present them as one unified type. - -We could specify data fetchers on the ``cost`` and ``tax`` fields that does those calculations but this is more to maintain and likely to lead to -`N+1 performance problems`. - -We would be better to do all this work in the ``Query.products`` data fetcher and create a unified view of the data at that point. - -.. code-block:: java - - DataFetcher productsDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment env) { - String matchArg = env.getArgument("match"); - - List productInfo = getMatchingProducts(matchArg); - - List productCostInfo = getProductCosts(productInfo); - - List productTaxInfo = getProductTax(productInfo); - - return mapDataTogether(productInfo, productCostInfo, productTaxInfo); - } - }; - -So looking at the code above we have 3 types of information that need to be combined in a way such that a graphql query above can get access to -the fields ``id, name, cost, tax`` - -We have two ways to create this mapping. One is via using a not type safe ``List`` structure and one by creating a type safe ``List`` class that -encapsulates this unified data. - -The ``Map`` technique could look like this. - -.. code-block:: java - - private List mapDataTogetherViaMap(List productInfo, List productCostInfo, List productTaxInfo) { - List unifiedView = new ArrayList<>(); - for (int i = 0; i < productInfo.size(); i++) { - ProductInfo info = productInfo.get(i); - ProductCostInfo cost = productCostInfo.get(i); - ProductTaxInfo tax = productTaxInfo.get(i); - - Map objectMap = new HashMap<>(); - objectMap.put("id", info.getId()); - objectMap.put("name", info.getName()); - objectMap.put("description", info.getDescription()); - objectMap.put("cost", cost.getCost()); - objectMap.put("tax", tax.getTax()); - - unifiedView.add(objectMap); - } - return unifiedView; - } - -The more type safe ``DTO`` technique could look like this. - -.. code-block:: java - - class ProductDTO { - private final String id; - private final String name; - private final String description; - private final Float cost; - private final Float tax; - - public ProductDTO(String id, String name, String description, Float cost, Float tax) { - this.id = id; - this.name = name; - this.description = description; - this.cost = cost; - this.tax = tax; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public Float getCost() { - return cost; - } - - public Float getTax() { - return tax; - } - } - - private List mapDataTogetherViaDTO(List productInfo, List productCostInfo, List productTaxInfo) { - List unifiedView = new ArrayList<>(); - for (int i = 0; i < productInfo.size(); i++) { - ProductInfo info = productInfo.get(i); - ProductCostInfo cost = productCostInfo.get(i); - ProductTaxInfo tax = productTaxInfo.get(i); - - ProductDTO productDTO = new ProductDTO( - info.getId(), - info.getName(), - info.getDescription(), - cost.getCost(), - tax.getTax() - ); - unifiedView.add(productDTO); - } - return unifiedView; - } - -The graphql engine will now use that list of objects and run the query sub fields ``id, name, cost, tax`` over it. - -The default data fetcher in graphql-java is ``graphql.schema.PropertyDataFetcher`` which has both map support and POJO support. - -For every object in the list it will look for an ``id`` field, find it by name in a map or via a `getId()` getter method and that will be sent back in the graphql -response. It does that for every field in the query on that type. - -By creating a "unified view" at the higher level data fetcher, you have mapped between your runtime view of the data and the graphql schema view of the data. - -PropertyDataFetcher and data mapping ------------------------------------- - -As mentioned above ``graphql.schema.PropertyDataFetcher`` is the default data fetcher for fields in graphql-java and it will use standard patterns for fetching -object field values. - -It supports a ``Map`` approach and a ``POJO`` approach in a Java idiomatic way. By default it assumes that for a graphql field ``fieldX`` it can find a property -called ``fieldX``. - -However you may have small differences between your graphql schema naming and runtime object naming. For example imagine that ``Product.description`` is actually -represented as ``getDesc()` in the runtime backing Java object. - -If you are using SDL to specify your schema then you can use the ``@fetch`` directive to indicate this remapping. - -.. code-block:: graphql - - directive @fetch(from : String!) on FIELD_DEFINITION - - type Product { - id : ID - name : String - description : String @fetch(from:"desc") - cost : Float - tax : Float - } - -This will tell the ``graphql.schema.PropertyDataFetcher`` to use the property name ``desc`` when fetching data for the graphql field named ``description``. - -If you are hand coding your schema then you can just specify it directly by wiring in a field data fetcher. - -.. code-block:: java - - GraphQLFieldDefinition descriptionField = GraphQLFieldDefinition.newFieldDefinition() - .name("description") - .type(Scalars.GraphQLString) - .dataFetcher(PropertyDataFetcher.fetching("desc")) - .build(); - diff --git a/docs/readme.md b/docs/readme.md deleted file mode 100644 index 814468ba1d..0000000000 --- a/docs/readme.md +++ /dev/null @@ -1,24 +0,0 @@ - - To build the documentation locally do the following : - -``` - > pip install sphinx sphinx-autobuild - > cd docs - > make html -``` - - To build the other language(like Chinese version) documentation locally do the following : - -``` - > pip install sphinx sphinx-autobuild - > cd docs - > make -e SPHINXOPTS="-D language='zh_CN'" html -``` - - - This will create the output in _build/html so on Mac you should be able to - -``` -> open _build/html/index.html -``` - which will open a browser with the rendered documentation diff --git a/docs/relay.rst b/docs/relay.rst deleted file mode 100644 index 9cc1aac24c..0000000000 --- a/docs/relay.rst +++ /dev/null @@ -1,43 +0,0 @@ -Relay Support -============= - - -Very basic support for `Relay `_ is included. - -**Note**: Relay refers here to "Relay Classic", there is no support for "Relay Modern". - -Please look at https://github.com/graphql-java/todomvc-relay-java for a full example project, - -Relay send queries to the GraphQL server as JSON containing a ``query`` field and a ``variables`` field. The ``query`` field is a JSON string, -and the ``variables`` field is a map of variable definitions. A relay-compatible server will need to parse this JSON and pass the ``query`` -string to this library as the query and the ``variables`` map as the third argument to ``execute`` as shown below. - -.. code-block:: java - - @RequestMapping(value = "/graphql", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody - public Object executeOperation(@RequestBody Map body) { - String query = (String) body.get("query"); - Map variables = (Map) body.get("variables"); - if (variables == null) { - variables = new LinkedHashMap<>(); - } - ExecutionResult executionResult = graphql.execute(query, (Object) null, variables); - Map result = new LinkedHashMap<>(); - if (executionResult.getErrors().size() > 0) { - result.put("errors", executionResult.getErrors()); - log.error("Errors: {}", executionResult.getErrors()); - } - result.put("data", executionResult.getData()); - return result; - } - - -Apollo Support --------------- - -There is no special support for `Apollo `_ included: Apollo works with any schema. - -The Controller example shown above works with Apollo too. - - diff --git a/docs/scalars.rst b/docs/scalars.rst deleted file mode 100644 index a946474d0a..0000000000 --- a/docs/scalars.rst +++ /dev/null @@ -1,176 +0,0 @@ -Scalars in graphql -================== - -Scalars -------- - -The leaf nodes of the graphql type system are called scalars. Once you reach a scalar type you -cannot descend down any further into the type hierarchy. A scalar type is meant to represent -an indivisible value. - -The graphql specification says that all implementations must have the following scalar types. - -* String aka ``GraphQLString`` - A UTF‐8 character sequence. -* Boolean aka ``GraphQLBoolean`` - true or false. -* Int aka ``GraphQLInt`` - A signed 32‐bit integer. -* Float aka ``GraphQLFloat`` - A signed double-precision floating-point value. -* ID aka ``GraphQLID`` - A unique identifier which is serialized in the same way as a String; however, defining it as an ID signifies that it is not intended to be human‐readable. - -graphql-java adds the following scalar types which are useful in Java based systems - -* Long aka ``GraphQLLong`` - a java.lang.Long based scalar -* Short aka ``GraphQLShort`` - a java.lang.Short based scalar -* Byte aka ``GraphQLByte`` - a java.lang.Byte based scalar -* BigDecimal aka ``GraphQLBigDecimal`` - a java.math.BigDecimal based scalar -* BigInteger aka ``GraphQLBigInteger`` - a java.math.BigInteger based scalar - - -The class ``graphql.Scalars`` contains singleton instances of the provided scalar types - -Writing your Own Custom Scalars -------------------------------- - -You can write your own custom scalar implementations. In doing so you take on the responsibility for coercing values -at runtime, which we will explain in a moment. - -Imagine we decide we need to have an email scalar type. It will take email addresses as input and output. - -We would create a singleton ``graphql.schema.GraphQLScalarType`` instance for this like so. - -.. code-block:: java - - public static final GraphQLScalarType EMAIL = new GraphQLScalarType("email", "A custom scalar that handles emails", new Coercing() { - @Override - public Object serialize(Object dataFetcherResult) { - return serializeEmail(dataFetcherResult); - } - - @Override - public Object parseValue(Object input) { - return parseEmailFromVariable(input); - } - - @Override - public Object parseLiteral(Object input) { - return parseEmailFromAstLiteral(input); - } - }); - - -Coercing values ---------------- - -The real work in any custom scalar implementation is the ``graphql.schema.Coercing`` implementation. This is responsible for 3 functions - -* ``parseValue`` - takes a variable input object and converts into the Java runtime representation -* ``parseLiteral`` - takes an AST literal ``graphql.language.Value` as input and converts into the Java runtime representation -* ``serialize`` - takes a Java object and converts it into the output shape for that scalar - -So your custom scalar code has to handle 2 forms of input (parseValue / parseLiteral) and 1 form of output (serialize). - -Imagine this query, which uses variables, AST literals and outputs our scalar type ```email``. - -.. code-block:: graphql - - mutation Contact($mainContact: Email!) { - makeContact(mainContactEmail: $mainContact, backupContactEmail: "backup@company.com") { - id - mainContactEmail - } - } - -Our custom Email scalar will - -* be called via ``parseValue`` to convert the ``$mainContact`` variable value into a runtime object -* be called via ``parseLiteral`` to convert the AST ``graphql.language.StringValue`` "backup@company.com" into a runtime object -* be called via ``serialise`` to turn the runtime representation of mainContactEmail into a form ready for output - -Validation of input and output ------------------------------- - -The methods can validate that the received input makes sense. For example our email scalar will try to validate that the input -and output are indeed email addresses. - -The JavaDoc method contract of ``graphql.schema.Coercing`` says the following - -* The ``serialise`` MUST ONLY allow ``graphql.schema.CoercingSerializeException`` to be thrown from it. This indicates that the -value cannot be serialised into an appropriate form. You must not allow other runtime exceptions to escape this method to get -the normal graphql behaviour for validation. You MUST return a non null value - - -* The ``parseValue`` MUST ONLY allow ``graphql.schema.CoercingParseValueException`` to be thrown from it. This indicates that the -value cannot be parsed as input into an appropriate form. You must not allow other runtime exceptions to escape this method to get -the normal graphql behaviour for validation. You MUST return a non null value. - -* The ``parseLiteral`` MUST ONLY allow ``graphql.schema.CoercingParseLiteralException`` to be thrown from it. This indicates that the -AST value cannot be parsed as input into an appropriate form. You must not allow any runtime exceptions to escape this method to get -the normal graphql behaviour for validation. - -Some people try to rely on runtime exceptions for validation and hope that they come out as graphql errors. This is not the case. You -MUST follow the ``Coercing`` method contracts to allow the graphql-java engine to work according to the graphql specification on scalar types. - -Example implementation ----------------------- - -The following is a really rough implementation of our imagined ``email`` scalar type to show you how one might implement the ``Coercing`` methods -such a scalar. - -.. code-block:: java - - public static class EmailScalar { - - public static final GraphQLScalarType EMAIL = new GraphQLScalarType("email", "A custom scalar that handles emails", new Coercing() { - @Override - public Object serialize(Object dataFetcherResult) { - return serializeEmail(dataFetcherResult); - } - - @Override - public Object parseValue(Object input) { - return parseEmailFromVariable(input); - } - - @Override - public Object parseLiteral(Object input) { - return parseEmailFromAstLiteral(input); - } - }); - - - private static boolean looksLikeAnEmailAddress(String possibleEmailValue) { - // ps. I am not trying to replicate RFC-3696 clearly - return Pattern.matches("[A-Za-z0-9]@[.*]", possibleEmailValue); - } - - private static Object serializeEmail(Object dataFetcherResult) { - String possibleEmailValue = String.valueOf(dataFetcherResult); - if (looksLikeAnEmailAddress(possibleEmailValue)) { - return possibleEmailValue; - } else { - throw new CoercingSerializeException("Unable to serialize " + possibleEmailValue + " as an email address"); - } - } - - private static Object parseEmailFromVariable(Object input) { - if (input instanceof String) { - String possibleEmailValue = input.toString(); - if (looksLikeAnEmailAddress(possibleEmailValue)) { - return possibleEmailValue; - } - } - throw new CoercingParseValueException("Unable to parse variable value " + input + " as an email address"); - } - - private static Object parseEmailFromAstLiteral(Object input) { - if (input instanceof StringValue) { - String possibleEmailValue = ((StringValue) input).getValue(); - if (looksLikeAnEmailAddress(possibleEmailValue)) { - return possibleEmailValue; - } - } - throw new CoercingParseLiteralException( - "Value is not any email address : '" + String.valueOf(input) + "'" - ); - } - } - diff --git a/docs/schema.rst b/docs/schema.rst deleted file mode 100644 index b54128efda..0000000000 --- a/docs/schema.rst +++ /dev/null @@ -1,563 +0,0 @@ -Creating a schema -================= - - -A schema defines your GraphQL API by defining each field that can be queried or -mutated. - -``graphql-java`` offers two different ways of defining the schema: Programmatically as Java code or -via a special graphql dsl (called SDL). - -If you are unsure which option to use we recommend the SDL. - -SDL example: - -.. code-block:: graphql - - type Foo { - bar: String - } - - -Java code example: - -.. code-block:: java - - GraphQLObjectType fooType = newObject() - .name("Foo") - .field(newFieldDefinition() - .name("bar") - .type(GraphQLString)) - .build(); - -DataFetcher and TypeResolver ----------------------------- - -A ``DataFetcher`` provides the data for a field (and changes something, if it is a mutation). - -Every field definition has a ``DataFetcher``. When one is not configured, a -`PropertyDataFetcher `_ is used. - -``PropertyDataFetcher`` fetches data from ``Map`` and Java Beans. So when the field name matches the Map key or -the property name of the source Object, no ``DataFetcher`` is needed. - -A ``TypeResolver`` helps ``graphql-java`` to decide which type a concrete value belongs to. -This is needed for ``Interface`` and ``Union``. - -For example imagine you have an ``Interface`` called *MagicUserType* which resolves back to a series of Java classes -called *Wizard*, *Witch* and *Necromancer*. The type resolver is responsible for examining a runtime object and deciding -what ``GraphqlObjectType`` should be used to represent it, and hence what data fetchers and fields will be invoked. - -.. code-block:: java - - new TypeResolver() { - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment env) { - Object javaObject = env.getObject(); - if (javaObject instanceof Wizard) { - return env.getSchema().getObjectType("WizardType"); - } else if (javaObject instanceof Witch) { - return env.getSchema().getObjectType("WitchType"); - } else { - return env.getSchema().getObjectType("NecromancerType"); - } - } - }; - - - -Creating a schema using the SDL -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When defining a schema via SDL, you provide the needed ``DataFetcher`` s and ``TypeResolver`` s -when the executable schema is created. - -Take for example the following static schema definition file called ``starWarsSchema.graphqls``: - -.. code-block:: graphql - - schema { - query: QueryType - } - - type QueryType { - hero(episode: Episode): Character - human(id : String) : Human - droid(id: ID!): Droid - } - - - enum Episode { - NEWHOPE - EMPIRE - JEDI - } - - interface Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - } - - type Human implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - homePlanet: String - } - - type Droid implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - primaryFunction: String - } - - -The static schema definition file ``starWarsSchema.graphqls`` contains the field and type definitions, but you need a -runtime wiring to make it a truly executable schema. - -The runtime wiring contains ``DataFetcher`` s, ``TypeResolvers`` s and custom ``Scalar`` s that are needed to make a fully -executable schema. - -You wire this together using this builder pattern: - -.. code-block:: java - - RuntimeWiring buildRuntimeWiring() { - return RuntimeWiring.newRuntimeWiring() - .scalar(CustomScalar) - // this uses builder function lambda syntax - .type("QueryType", typeWiring -> typeWiring - .dataFetcher("hero", new StaticDataFetcher(StarWarsData.getArtoo())) - .dataFetcher("human", StarWarsData.getHumanDataFetcher()) - .dataFetcher("droid", StarWarsData.getDroidDataFetcher()) - ) - .type("Human", typeWiring -> typeWiring - .dataFetcher("friends", StarWarsData.getFriendsDataFetcher()) - ) - // you can use builder syntax if you don't like the lambda syntax - .type("Droid", typeWiring -> typeWiring - .dataFetcher("friends", StarWarsData.getFriendsDataFetcher()) - ) - // or full builder syntax if that takes your fancy - .type( - newTypeWiring("Character") - .typeResolver(StarWarsData.getCharacterTypeResolver()) - .build() - ) - .build(); - } - - -Finally, you can generate an executable schema by combining the static schema and the wiring together as shown in this -example: - -.. code-block:: java - - SchemaParser schemaParser = new SchemaParser(); - SchemaGenerator schemaGenerator = new SchemaGenerator(); - - File schemaFile = loadSchema("starWarsSchema.graphqls"); - - TypeDefinitionRegistry typeRegistry = schemaParser.parse(schemaFile); - RuntimeWiring wiring = buildRuntimeWiring(); - GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, wiring); - - -In addition to the builder style shown above, ``TypeResolver`` s and ``DataFetcher`` s can also be wired in using the -``WiringFactory`` interface. This allows for a more dynamic runtime wiring since the SDL definitions can be examined in -order to decide what to wire in. You could for example look at SDL directives, or some other aspect of the SDL -definition to help you decide what runtime to create. - -.. code-block:: java - - RuntimeWiring buildDynamicRuntimeWiring() { - WiringFactory dynamicWiringFactory = new WiringFactory() { - @Override - public boolean providesTypeResolver(TypeDefinitionRegistry registry, InterfaceTypeDefinition definition) { - return getDirective(definition,"specialMarker") != null; - } - - @Override - public boolean providesTypeResolver(TypeDefinitionRegistry registry, UnionTypeDefinition definition) { - return getDirective(definition,"specialMarker") != null; - } - - @Override - public TypeResolver getTypeResolver(TypeDefinitionRegistry registry, InterfaceTypeDefinition definition) { - Directive directive = getDirective(definition,"specialMarker"); - return createTypeResolver(definition,directive); - } - - @Override - public TypeResolver getTypeResolver(TypeDefinitionRegistry registry, UnionTypeDefinition definition) { - Directive directive = getDirective(definition,"specialMarker"); - return createTypeResolver(definition,directive); - } - - @Override - public boolean providesDataFetcher(TypeDefinitionRegistry registry, FieldDefinition definition) { - return getDirective(definition,"dataFetcher") != null; - } - - @Override - public DataFetcher getDataFetcher(TypeDefinitionRegistry registry, FieldDefinition definition) { - Directive directive = getDirective(definition, "dataFetcher"); - return createDataFetcher(definition,directive); - } - }; - return RuntimeWiring.newRuntimeWiring() - .wiringFactory(dynamicWiringFactory).build(); - } - -Creating a schema programmatically -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When the schema is created programmatically ``DataFetcher`` s and ``TypeResolver`` s are provided at type creation: - -Example: - -.. code-block:: java - - DataFetcher fooDataFetcher = environment -> { - // environment.getSource() is the value of the surrounding - // object. In this case described by objectType - Foo value = perhapsFromDatabase(); // Perhaps getting from a DB or whatever - return value; - } - - GraphQLObjectType objectType = newObject() - .name("ObjectType") - .field(newFieldDefinition() - .name("foo") - .type(GraphQLString) - .dataFetcher(fooDataFetcher)) - .build(); - - - -Types ------ - -The GraphQL type system supports the following kind of types: - -* Scalar -* Object -* Interface -* Union -* InputObject -* Enum - - - -Scalar -^^^^^^ - -``graphql-java`` supports the following Scalars: - - -* ``GraphQLString`` -* ``GraphQLBoolean`` -* ``GraphQLInt`` -* ``GraphQLFloat`` -* ``GraphQLID`` -* ``GraphQLLong`` -* ``GraphQLShort`` -* ``GraphQLByte`` -* ``GraphQLFloat`` -* ``GraphQLBigDecimal`` -* ``GraphQLBigInteger`` - - - -Object -^^^^^^ - -SDL Example: - -.. code-block:: graphql - - type SimpsonCharacter { - name: String - mainCharacter: Boolean - } - - -Java Example: - -.. code-block:: java - - GraphQLObjectType simpsonCharacter = newObject() - .name("SimpsonCharacter") - .description("A Simpson character") - .field(newFieldDefinition() - .name("name") - .description("The name of the character.") - .type(GraphQLString)) - .field(newFieldDefinition() - .name("mainCharacter") - .description("One of the main Simpson characters?") - .type(GraphQLBoolean)) - .build(); - -Interface -^^^^^^^^^ - -Interfaces are abstract definitions of types. - -SDL Example: - -.. code-block:: graphql - - interface ComicCharacter { - name: String; - } - -Java Example: - -.. code-block:: java - - GraphQLInterfaceType comicCharacter = newInterface() - .name("ComicCharacter") - .description("An abstract comic character.") - .field(newFieldDefinition() - .name("name") - .description("The name of the character.") - .type(GraphQLString)) - .build(); - -Union -^^^^^ - -SDL Example: - -.. code-block:: graphql - - type Cat { - name: String; - lives: Int; - } - - type Dog { - name: String; - bonesOwned: int; - } - - union Pet = Cat | Dog - - -Java Example: - -.. code-block:: java - - GraphQLUnionType PetType = newUnionType() - .name("Pet") - .possibleType(CatType) - .possibleType(DogType) - .typeResolver(new TypeResolver() { - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment env) { - if (env.getObject() instanceof Cat) { - return CatType; - } - if (env.getObject() instanceof Dog) { - return DogType; - } - return null; - } - }) - .build(); - - -Enum -^^^^ - -SDL Example: - -.. code-block:: graphql - - enum Color { - RED - GREEN - BLUE - } - - -Java Example: - -.. code-block:: java - - GraphQLEnumType colorEnum = newEnum() - .name("Color") - .description("Supported colors.") - .value("RED") - .value("GREEN") - .value("BLUE") - .build(); - - -ObjectInputType -^^^^^^^^^^^^^^^ - -SDL Example: - -.. code-block:: graphql - - input Character { - name: String - } - - -Java Example: - -.. code-block:: java - - GraphQLInputObjectType inputObjectType = newInputObject() - .name("inputObjectType") - .field(newInputObjectField() - .name("field") - .type(GraphQLString)) - .build(); - - -Type References (recursive types) ---------------------------------- - -GraphQL supports recursive types: For example a ``Person`` can contain a list of friends of the same type. - -To be able to declare such a type, ``graphql-java`` has a ``GraphQLTypeReference`` class. - -When the schema is created, the ``GraphQLTypeReference`` is replaced with the actual real type Object. - -For example: - -.. code-block:: java - - GraphQLObjectType person = newObject() - .name("Person") - .field(newFieldDefinition() - .name("friends") - .type(GraphQLList.list(GraphQLTypeReference.typeRef("Person")))) - .build(); - -When the schema is declared via SDL, no special handling of recursive types is needed. - -Modularising the Schema SDL ---------------------------- - -Having one large schema file is not always viable. You can modularise you schema using two techniques. - -The first technique is to merge multiple Schema SDL files into one logic unit. In the case below the schema has -been split into multiple files and merged all together just before schema generation. - -.. code-block:: java - - SchemaParser schemaParser = new SchemaParser(); - SchemaGenerator schemaGenerator = new SchemaGenerator(); - - File schemaFile1 = loadSchema("starWarsSchemaPart1.graphqls"); - File schemaFile2 = loadSchema("starWarsSchemaPart2.graphqls"); - File schemaFile3 = loadSchema("starWarsSchemaPart3.graphqls"); - - TypeDefinitionRegistry typeRegistry = new TypeDefinitionRegistry(); - - // each registry is merged into the main registry - typeRegistry.merge(schemaParser.parse(schemaFile1)); - typeRegistry.merge(schemaParser.parse(schemaFile2)); - typeRegistry.merge(schemaParser.parse(schemaFile3)); - - GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, buildRuntimeWiring()); - -The Graphql SDL type system has another construct for modularising a schema. You can use `type extensions` to add -extra fields and interfaces to a type. - -Imagine you start with a type like this in one schema file. - -.. code-block:: graphql - - type Human { - id: ID! - name: String! - } - -Another part of your system can extend this type to add more shape to it. - -.. code-block:: graphql - - extend type Human implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - } - -You can have as many extensions as you think sensible. They will be combined in the order -in which they are encountered. Duplicate fields will be merged as one (however field re-definitions -into new types are not allowed). - -.. code-block:: graphql - - extend type Human { - homePlanet: String - } - - -With all these type extensions in place the `Human` type now looks like this at runtime. - -.. code-block:: graphql - - type Human implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - homePlanet: String - } - -This is especially useful at the top level. You can use extension types to add new fields to the -top level schema "query". Teams could contribute "sections" on what is being offered as the total -graphql query. - - -.. code-block:: graphql - - schema { - query: CombinedQueryFromMultipleTeams - } - - type CombinedQueryFromMultipleTeams { - createdTimestamp: String - } - - # maybe the invoicing system team puts in this set of attributes - extend type CombinedQueryFromMultipleTeams { - invoicing: Invoicing - } - - # and the billing system team puts in this set of attributes - extend type CombinedQueryFromMultipleTeams { - billing: Billing - } - - # and so and so forth - extend type CombinedQueryFromMultipleTeams { - auditing: Auditing - } - - - -Subscription Support --------------------- - -Subscriptions are not officially specified yet: ``graphql-java`` supports currently a very basic implementation where you can define a subscription in the schema -with ``GraphQLSchema.Builder.subscription(...)``. This enables you to handle a subscription request: - -.. code-block:: graphql - - subscription foo { - # normal graphql query - } diff --git a/docs/sdldirectives.rst b/docs/sdldirectives.rst deleted file mode 100644 index aadbac395b..0000000000 --- a/docs/sdldirectives.rst +++ /dev/null @@ -1,311 +0,0 @@ -Schema Directives -================= - -Adding Behaviour ----------------- - -Schema Definition Language (SDL) allows you to define your graphql types in a declarative manner without using code. However you still need to wire in all the -logic that backs those types and their fields. - -Schema directives allow you to do this. You can place directives on SDL elements and then write the backing logic -once and have it apply in many places. - -This idea of "writing it once" is the key concept here. There is only code place where -logic needs to be written and it is then applied to all the places in the SDL that have a named directive. - -This is a more powerful model than wiring in 10-100s of data fetchers like you might -with the conventional runtime wiring. - -For example imagine you have a type like the following - - -.. code-block:: graphql - - type Employee - id : ID - name : String! - startDate : String! - salary : Float - } - - -Publishing ``salary`` information to every one who can see this employee's ``name`` might not be want you want. Rather you want some sort of access control -to be in place such that if your role is that of a manager, you can see salaries, otherwise you get no data back. - -Directives can help you declare this more easily. Our declaration above would become something like the following: - -.. code-block:: graphql - - directive @auth(role : String!) on FIELD_DEFINITION - - type Employee - id : ID - name : String! - startDate : String! - salary : Float @auth(role : "manager") - } - -So we have said that only people who have the role ``manager`` are authorised to see this field. We can now use this directive on ANY field -that needs manager role authorisation. - - -.. code-block:: graphql - - directive @auth(role : String!) on FIELD_DEFINITION - - type Employee - id : ID - name : String! - startDate : String! - salary : Float @auth(role : "manager") - } - - type Department { - id : ID - name : String - yearlyOperatingBudget : Float @auth(role : "manager") - monthlyMarketingBudget : Float @auth(role : "manager") - } - - -We now need to wire in the code that can handle any field with this ``@auth`` directive. We use ``graphql.schema.idl.SchemaDirectiveWiring`` to do this. - - -.. code-block:: java - - class AuthorisationDirective implements SchemaDirectiveWiring { - - @Override - public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment schemaDirectiveWiringEnv) { - String targetAuthRole = (String) schemaDirectiveWiringEnv.getDirective().getArgument("role").getValue(); - - GraphQLFieldDefinition field = schemaDirectiveWiringEnv.getElement(); - // - // build a data fetcher that first checks authorisation roles before then calling the original data fetcher - // - DataFetcher originalDataFetcher = field.getDataFetcher(); - DataFetcher authDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment dataFetchingEnvironment) { - Map contextMap = dataFetchingEnvironment.getContext(); - AuthorisationCtx authContext = (AuthorisationCtx) contextMap.get("authContext"); - - if (authContext.hasRole(targetAuthRole)) { - return originalDataFetcher.get(dataFetchingEnvironment); - } else { - return null; - } - } - }; - // - // now change the field definition to have the new authorising data fetcher - return field.transform(builder -> builder.dataFetcher(authDataFetcher)); - } - } - - // - // we wire this into the runtime by directive name - // - RuntimeWiring.newRuntimeWiring() - .directive("auth", new AuthorisationDirective()) - .build(); - -This has modified the ``GraphQLFieldDefinition`` so that its original data fetcher will ONLY be called if the current authorisation context -has the ``manager`` role. Exactly what mechanisms you use for authorisation is up to you. You could use Spring Security for example say, graphql-java doesnt -really care. - -You would provide this authorisation checker into the execution "context" object of the graphql input so it can then be accessed later in the -``DataFetchingEnvironment``. - -.. code-block:: java - - AuthorisationCtx authCtx = AuthorisationCtx.obtain(); - - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query(query) - .context(authCtx) - .build(); - - -Declaring Directives --------------------- - -In order to use a directive in SDL, the graphql specification requires that you MUST declare its shape before using it. Our ``@auth`` directive example above needs to be -declared like so before use. - -.. code-block:: graphql - - # This is a directive declaration - directive @auth(role : String!) on FIELD_DEFINITION - - type Employee - id : ID - - # and this is a usage of that declared directive - salary : Float @auth(role : "manager") - } - -The one exception to this is the ``@deprecated`` directive which is implicitly declared for you as follows : - - -.. code-block:: graphql - - directive @deprecated( reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE - -The valid SDL directive locations are as follows : - -.. code-block:: graphql - - SCHEMA, - SCALAR, - OBJECT, - FIELD_DEFINITION, - ARGUMENT_DEFINITION, - INTERFACE, - UNION, - ENUM, - ENUM_VALUE, - INPUT_OBJECT, - INPUT_FIELD_DEFINITION - - -Directives are commonly applied to fields definitions but as you can see there are a number of places they can be applied. - - - -Another Example - Date Formatting ---------------------------------- - -Date formatting is a cross cutting concern that we should only have to write once and apply it in many areas. - -The following demonstrates an example schema directive that can apply date formatting to fields that are ``LocaleDate`` objects. - -Whats great in this example is that it adds an extra ``format`` argument to each field that it is applied to. So the clients can -opt into what ever date formatting you provide per request. - -.. code-block:: graphql - - directive @dateFormat on FIELD_DEFINITION - - type Query { - dateField : String @dateFormat - } - -Then our runtime code could be : - -.. code-block:: java - - public static class DateFormatting implements SchemaDirectiveWiring { - @Override - public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment environment) { - GraphQLFieldDefinition field = environment.getElement(); - // - // DataFetcherFactories.wrapDataFetcher is a helper to wrap data fetchers so that CompletionStage is handled correctly - // along with POJOs - // - DataFetcher dataFetcher = DataFetcherFactories.wrapDataFetcher(field.getDataFetcher(), ((dataFetchingEnvironment, value) -> { - DateTimeFormatter dateTimeFormatter = buildFormatter(dataFetchingEnvironment.getArgument("format")); - if (value instanceof LocalDateTime) { - return dateTimeFormatter.format((LocalDateTime) value); - } - return value; - })); - - // - // This will extend the field by adding a new "format" argument to it for the date formatting - // which allows clients to opt into that as well as wrapping the base data fetcher so it - // performs the formatting over top of the base values. - // - return field.transform(builder -> builder - .argument(GraphQLArgument - .newArgument() - .name("format") - .type(Scalars.GraphQLString) - .defaultValue("dd-MM-YYYY") - ) - .dataFetcher(dataFetcher) - ); - } - - private DateTimeFormatter buildFormatter(String format) { - String dtFormat = format != null ? format : "dd-MM-YYYY"; - return DateTimeFormatter.ofPattern(dtFormat); - } - } - - static GraphQLSchema buildSchema() { - - String sdlSpec = "" + - "type Query {\n" + - " dateField : String @dateFormat \n" + - "}"; - - TypeDefinitionRegistry registry = new SchemaParser().parse(sdlSpec); - - RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() - .directive("dateFormat", new DateFormatting()) - .build(); - - return new SchemaGenerator().makeExecutableSchema(registry, runtimeWiring); - } - - public static void main(String[] args) { - GraphQLSchema schema = buildSchema(); - GraphQL graphql = GraphQL.newGraphQL(schema).build(); - - Map root = new HashMap<>(); - root.put("dateField", LocalDateTime.of(1969, 10, 8, 0, 0)); - - String query = "" + - "query {\n" + - " default : dateField \n" + - " usa : dateField(format : \"MM-dd-YYYY\") \n" + - "}"; - - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .root(root) - .query(query) - .build(); - - ExecutionResult executionResult = graphql.execute(executionInput); - Map data = executionResult.getData(); - - // data['default'] == '08-10-1969' - // data['usa'] == '10-08-1969' - } - -Notice the SDL definition did not have a ``format`` argument yet once the directive wiring is applied, it is added -to the field definition and hence clients can begin to use it. - -Please note that graphql-java does not ship with this implementation. It is merely provided here as -an example of what you could add yourself. - - -Chaining Behaviour ------------------- - -The directives are applied in the order they are encountered. For example imagine directives that changed the case of a field value. - -.. code-block:: graphql - - directive @uppercase on FIELD_DEFINITION - directive @lowercase on FIELD_DEFINITION - directive @mixedcase on FIELD_DEFINITION - directive @reversed on FIELD_DEFINITION - - type Query { - lowerCaseValue : String @uppercase - upperCaseValue : String @lowercase - mixedCaseValue : String @mixedcase - - # - # directives are applied in order hence this will be lower, then upper, then mixed then reversed - # - allTogetherNow : String @lowercase @uppercase @mixedcase @reversed - } - - -When the above was executed each directive would be applied one on top of the other. Each directive implementation should be careful -to preserve the previous data fetcher to retain behaviour (unless of course you mean to throw it away) - - diff --git a/docs/subscriptions.rst b/docs/subscriptions.rst deleted file mode 100644 index c6bc6b720f..0000000000 --- a/docs/subscriptions.rst +++ /dev/null @@ -1,148 +0,0 @@ -Subscriptions -============= - -Subscription Queries --------------------- - -Graphql subscriptions allow you subscribe to a reactive source and as new data arrives -then a graphql query is applied over that data and the results are passed on. - -See http://graphql.org/blog/subscriptions-in-graphql-and-relay/ for more general details on -graphql subscriptions. - - -Imagine you have an stock market pricing service and you make a graphql subscription to it like this - -.. code-block:: graphql - - subscription StockCodeSubscription { - stockQuotes(stockCode:"IBM") { - dateTime - stockCode - stockPrice - stockPriceChange - } - } - -graphql subscriptions allow a stream of ``ExecutionResult`` objects to be sent down each time the stock price -changes. The field selection set will applied to the underlying data and are represented just like any other -graphql query. - -What is special is that the initial result of a subscription query is a reactive-streams ``Publisher`` object which you -need to use to get the future values. - -You need to use ``SubscriptionExecutionStrategy`` as your execution strategy as it has the support for the reactive-streams APIs. - -.. code-block:: java - - GraphQL graphQL = GraphQL - .newGraphQL(schema) - .subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()) - .build(); - - ExecutionResult executionResult = graphQL.execute(query); - - Publisher stockPriceStream = executionResult.getData(); - -The ``Publisher`` here is the publisher of a stream of events. You need to subscribe to this with your processing -code which will look something like the following - - -.. code-block:: java - - GraphQL graphQL = GraphQL - .newGraphQL(schema) - .subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()) - .build(); - - String query = "" + - " subscription StockCodeSubscription {\n" + - " stockQuotes(stockCode:\"IBM') {\n" + - " dateTime\n" + - " stockCode\n" + - " stockPrice\n" + - " stockPriceChange\n" + - " }\n" + - " }\n"; - - ExecutionResult executionResult = graphQL.execute(query); - - Publisher stockPriceStream = executionResult.getData(); - - AtomicReference subscriptionRef = new AtomicReference<>(); - stockPriceStream.subscribe(new Subscriber() { - - @Override - public void onSubscribe(Subscription s) { - subscriptionRef.set(s); - s.request(1); - } - - @Override - public void onNext(ExecutionResult er) { - // - // process the next stock price - // - processStockPriceChange(er.getData()); - - // - // ask the publisher for one more item please - // - subscriptionRef.get().request(1); - } - - @Override - public void onError(Throwable t) { - // - // The upstream publishing data source has encountered an error - // and the subscription is now terminated. Real production code needs - // to decide on a error handling strategy. - // - } - - @Override - public void onComplete() { - // - // the subscription has completed. There is not more data - // - } - }); - -You are now writing reactive-streams code to consume a series of ``ExecutionResults``. You can see -more details on reactive-streams code here http://www.reactive-streams.org/ - -``RxJava`` is a popular implementation of reactive-streams. Check out http://reactivex.io/intro.html to find out more -about creating Publishers of data and Subscriptions to that data. - -graphql-java only produces a stream of results. It does not concern itself with sending these over the network on things -like web sockets and so on. That is important but not a concern of the base graphql-java library. - -We have put together a basic example of using websockets (backed by Jetty) with a simulated stock price application that -is built using RxJava. - -See https://github.com/graphql-java/graphql-java-subscription-example for more detailed code on handling network concerns and -the like. - - -Subscription Data Fetchers --------------------------- - -The ``DataFetcher`` behind a subscription field is responsible for creating the ``Publisher`` of data. The objects -return by this Publisher will be mapped over the graphql query as each arrives and then sent back out as an execution result. - -You data fetcher is going to look something like this. - - -.. code-block:: java - - DataFetcher> publisherDataFetcher = new DataFetcher>() { - @Override - public Publisher get(DataFetchingEnvironment environment) { - String stockCodeArg = environment.getArgument("stockCode"); - return buildPublisherForStockCode(stockCodeArg); - } - }; - -Now the exact details of how you get that stream of events is up to you and you're reactive code. graphql-java -gives you a way to map the graphql query fields over that stream of objects just like a standard graphql query. - diff --git a/gradle.properties b/gradle.properties index c30326b485..bf5eeb87f0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,10 @@ org.gradle.caching=true org.gradle.daemon=true org.gradle.parallel=true -org.gradle.jvmargs=-Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -bintray.user=DUMMY_USER -bintray.key=DUMMY_KEY \ No newline at end of file + +# Prevents the Kotlin stdlib being a POM dependency +# +# https://kotlinlang.org/docs/gradle-configure-project.html#dependency-on-the-standard-library +kotlin.stdlib.default.dependency=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 01b8bf6b1f..f8e1ee3125 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8941bfbbed..bad7c2462f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-all.zip diff --git a/gradlew b/gradlew index cccdd3d517..adff685a03 100755 --- a/gradlew +++ b/gradlew @@ -1,78 +1,128 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,92 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f9553162f1..e509b2dd8f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,93 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/performance-results/.gitkeep b/performance-results/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/performance-results/2024-11-28T01:53:48Z-1d50c655aaf1a907b65f39e2eba310f3463ba5d5-jdk17.json b/performance-results/2024-11-28T01:53:48Z-1d50c655aaf1a907b65f39e2eba310f3463ba5d5-jdk17.json new file mode 100644 index 0000000000..e038ff0fed --- /dev/null +++ b/performance-results/2024-11-28T01:53:48Z-1d50c655aaf1a907b65f39e2eba310f3463ba5d5-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4098507705676995, + "scoreError" : 0.0248935503366656, + "scoreConfidence" : [ + 3.384957220231034, + 3.434744320904365 + ], + "scorePercentiles" : { + "0.0" : 3.40519673991893, + "50.0" : 3.409982052692473, + "90.0" : 3.414242236966922, + "95.0" : 3.414242236966922, + "99.0" : 3.414242236966922, + "99.9" : 3.414242236966922, + "99.99" : 3.414242236966922, + "99.999" : 3.414242236966922, + "99.9999" : 3.414242236966922, + "100.0" : 3.414242236966922 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.411312710571647, + 3.414242236966922 + ], + [ + 3.40519673991893, + 3.4086513948132993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7231380231942457, + "scoreError" : 0.01856164149472618, + "scoreConfidence" : [ + 1.7045763816995194, + 1.741699664688972 + ], + "scorePercentiles" : { + "0.0" : 1.7201780646528506, + "50.0" : 1.722962619633562, + "90.0" : 1.7264487888570081, + "95.0" : 1.7264487888570081, + "99.0" : 1.7264487888570081, + "99.9" : 1.7264487888570081, + "99.99" : 1.7264487888570081, + "99.999" : 1.7264487888570081, + "99.9999" : 1.7264487888570081, + "100.0" : 1.7264487888570081 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7213864558761982, + 1.7264487888570081 + ], + [ + 1.7201780646528506, + 1.7245387833909256 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8669447004278835, + "scoreError" : 0.0033409895220654477, + "scoreConfidence" : [ + 0.8636037109058181, + 0.8702856899499489 + ], + "scorePercentiles" : { + "0.0" : 0.8663656186685549, + "50.0" : 0.8669349875468758, + "90.0" : 0.8675432079492276, + "95.0" : 0.8675432079492276, + "99.0" : 0.8675432079492276, + "99.9" : 0.8675432079492276, + "99.99" : 0.8675432079492276, + "99.999" : 0.8675432079492276, + "99.9999" : 0.8675432079492276, + "100.0" : 0.8675432079492276 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8675432079492276, + 0.8663656186685549 + ], + [ + 0.8667023944569926, + 0.867167580636759 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 42.926276842278895, + "scoreError" : 2.4191606861477783, + "scoreConfidence" : [ + 40.50711615613112, + 45.34543752842667 + ], + "scorePercentiles" : { + "0.0" : 40.61444079049615, + "50.0" : 42.970686811193, + "90.0" : 45.1302030720952, + "95.0" : 45.1302030720952, + "99.0" : 45.1302030720952, + "99.9" : 45.1302030720952, + "99.99" : 45.1302030720952, + "99.999" : 45.1302030720952, + "99.9999" : 45.1302030720952, + "100.0" : 45.1302030720952 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.40817053790828, + 43.939215333141064, + 45.1302030720952 + ], + [ + 42.18269950399568, + 40.61444079049615, + 41.31916000552604 + ], + [ + 42.799976301303936, + 42.970686811193, + 42.971939224850715 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022611135359511498, + "scoreError" : 5.924153810738151E-4, + "scoreConfidence" : [ + 0.022018719978437684, + 0.02320355074058531 + ], + "scorePercentiles" : { + "0.0" : 0.02192285936323851, + "50.0" : 0.022678289092760182, + "90.0" : 0.023260692930232557, + "95.0" : 0.023260692930232557, + "99.0" : 0.023260692930232557, + "99.9" : 0.023260692930232557, + "99.99" : 0.023260692930232557, + "99.999" : 0.023260692930232557, + "99.9999" : 0.023260692930232557, + "100.0" : 0.023260692930232557 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.022732881079545453, + 0.023260692930232557, + 0.022742364038636362 + ], + [ + 0.022468225233183856, + 0.022678289092760182, + 0.02192285936323851 + ], + [ + 0.022457287367713005, + 0.022713271950113377, + 0.02252434718018018 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-11-28T03:56:43Z-a3fcfcb843b2104f40e75940cea4ed03e6de12c0-jdk17.json b/performance-results/2024-11-28T03:56:43Z-a3fcfcb843b2104f40e75940cea4ed03e6de12c0-jdk17.json new file mode 100644 index 0000000000..f08161aec7 --- /dev/null +++ b/performance-results/2024-11-28T03:56:43Z-a3fcfcb843b2104f40e75940cea4ed03e6de12c0-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4102578842457145, + "scoreError" : 0.02449629894447283, + "scoreConfidence" : [ + 3.3857615853012417, + 3.4347541831901873 + ], + "scorePercentiles" : { + "0.0" : 3.4062196008890453, + "50.0" : 3.40974951823215, + "90.0" : 3.4153128996295132, + "95.0" : 3.4153128996295132, + "99.0" : 3.4153128996295132, + "99.9" : 3.4153128996295132, + "99.99" : 3.4153128996295132, + "99.999" : 3.4153128996295132, + "99.9999" : 3.4153128996295132, + "100.0" : 3.4153128996295132 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4062196008890453, + 3.409143970092387 + ], + [ + 3.4103550663719124, + 3.4153128996295132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.723628882965939, + "scoreError" : 0.01684992650921796, + "scoreConfidence" : [ + 1.706778956456721, + 1.7404788094751569 + ], + "scorePercentiles" : { + "0.0" : 1.720348242957288, + "50.0" : 1.7237243857120972, + "90.0" : 1.7267185174822728, + "95.0" : 1.7267185174822728, + "99.0" : 1.7267185174822728, + "99.9" : 1.7267185174822728, + "99.99" : 1.7267185174822728, + "99.999" : 1.7267185174822728, + "99.9999" : 1.7267185174822728, + "100.0" : 1.7267185174822728 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.720348242957288, + 1.7239130487239118 + ], + [ + 1.7235357227002823, + 1.7267185174822728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8675344687711203, + "scoreError" : 0.007218718093431595, + "scoreConfidence" : [ + 0.8603157506776887, + 0.8747531868645518 + ], + "scorePercentiles" : { + "0.0" : 0.8659004700112273, + "50.0" : 0.8679187802361048, + "90.0" : 0.8683998446010442, + "95.0" : 0.8683998446010442, + "99.0" : 0.8683998446010442, + "99.9" : 0.8683998446010442, + "99.99" : 0.8683998446010442, + "99.999" : 0.8683998446010442, + "99.9999" : 0.8683998446010442, + "100.0" : 0.8683998446010442 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8677972271860673, + 0.8680403332861423 + ], + [ + 0.8659004700112273, + 0.8683998446010442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 42.18911184050926, + "scoreError" : 0.9546618037946293, + "scoreConfidence" : [ + 41.234450036714634, + 43.14377364430389 + ], + "scorePercentiles" : { + "0.0" : 41.342744086435644, + "50.0" : 42.42040842447684, + "90.0" : 42.949395639087484, + "95.0" : 42.949395639087484, + "99.0" : 42.949395639087484, + "99.9" : 42.949395639087484, + "99.99" : 42.949395639087484, + "99.999" : 42.949395639087484, + "99.9999" : 42.949395639087484, + "100.0" : 42.949395639087484 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.949395639087484, + 42.43053158382356, + 42.77870012159051 + ], + [ + 42.10668734070957, + 42.47808802236617, + 42.42040842447684 + ], + [ + 41.342744086435644, + 41.459171410149246, + 41.736279935944374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022785715830115526, + "scoreError" : 7.765947574646602E-4, + "scoreConfidence" : [ + 0.022009121072650868, + 0.023562310587580185 + ], + "scorePercentiles" : { + "0.0" : 0.02206299895154185, + "50.0" : 0.022887831881006866, + "90.0" : 0.023311196390697675, + "95.0" : 0.023311196390697675, + "99.0" : 0.023311196390697675, + "99.9" : 0.023311196390697675, + "99.99" : 0.023311196390697675, + "99.999" : 0.023311196390697675, + "99.9999" : 0.023311196390697675, + "100.0" : 0.023311196390697675 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.022410095964205817, + 0.02206299895154185, + 0.022154066898230088 + ], + [ + 0.022887831881006866, + 0.022883768581235697, + 0.023030873466666667 + ], + [ + 0.02313581221939954, + 0.023311196390697675, + 0.023194798118055554 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-03T01:09:26Z-9d6e31e367f7b2929dd393a694dc05a0c5bb6e1a-jdk17.json b/performance-results/2024-12-03T01:09:26Z-9d6e31e367f7b2929dd393a694dc05a0c5bb6e1a-jdk17.json new file mode 100644 index 0000000000..cc3c0e1c6c --- /dev/null +++ b/performance-results/2024-12-03T01:09:26Z-9d6e31e367f7b2929dd393a694dc05a0c5bb6e1a-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.416195951743301, + "scoreError" : 0.026850420058968587, + "scoreConfidence" : [ + 3.3893455316843326, + 3.4430463718022697 + ], + "scorePercentiles" : { + "0.0" : 3.4104756625310313, + "50.0" : 3.417284846910124, + "90.0" : 3.4197384506219257, + "95.0" : 3.4197384506219257, + "99.0" : 3.4197384506219257, + "99.9" : 3.4197384506219257, + "99.99" : 3.4197384506219257, + "99.999" : 3.4197384506219257, + "99.9999" : 3.4197384506219257, + "100.0" : 3.4197384506219257 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.415843843944456, + 3.4197384506219257 + ], + [ + 3.4104756625310313, + 3.4187258498757913 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7230485586886197, + "scoreError" : 0.020087806386833534, + "scoreConfidence" : [ + 1.7029607523017862, + 1.7431363650754532 + ], + "scorePercentiles" : { + "0.0" : 1.7187149064375862, + "50.0" : 1.7237077757716905, + "90.0" : 1.726063776773511, + "95.0" : 1.726063776773511, + "99.0" : 1.726063776773511, + "99.9" : 1.726063776773511, + "99.99" : 1.726063776773511, + "99.999" : 1.726063776773511, + "99.9999" : 1.726063776773511, + "100.0" : 1.726063776773511 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7187149064375862, + 1.7240607327472357 + ], + [ + 1.7233548187961456, + 1.726063776773511 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8672591450106986, + "scoreError" : 0.0031722136235199333, + "scoreConfidence" : [ + 0.8640869313871786, + 0.8704313586342185 + ], + "scorePercentiles" : { + "0.0" : 0.8668100501731115, + "50.0" : 0.8671493032151358, + "90.0" : 0.8679279234394113, + "95.0" : 0.8679279234394113, + "99.0" : 0.8679279234394113, + "99.9" : 0.8679279234394113, + "99.99" : 0.8679279234394113, + "99.999" : 0.8679279234394113, + "99.9999" : 0.8679279234394113, + "100.0" : 0.8679279234394113 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8673072236763956, + 0.8668100501731115 + ], + [ + 0.866991382753876, + 0.8679279234394113 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 42.98710131013886, + "scoreError" : 1.2857923706741503, + "scoreConfidence" : [ + 41.70130893946471, + 44.27289368081301 + ], + "scorePercentiles" : { + "0.0" : 41.39140519888467, + "50.0" : 43.14941248747299, + "90.0" : 44.20711145156694, + "95.0" : 44.20711145156694, + "99.0" : 44.20711145156694, + "99.9" : 44.20711145156694, + "99.99" : 44.20711145156694, + "99.999" : 44.20711145156694, + "99.9999" : 44.20711145156694, + "100.0" : 44.20711145156694 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.20711145156694, + 43.20559444971562, + 43.38709980039055 + ], + [ + 42.65699183021884, + 43.40605138244976, + 42.67513011200432 + ], + [ + 43.14941248747299, + 42.80511507854605, + 41.39140519888467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022628376233754664, + "scoreError" : 0.0010121779437417262, + "scoreConfidence" : [ + 0.021616198290012937, + 0.02364055417749639 + ], + "scorePercentiles" : { + "0.0" : 0.02194287973464912, + "50.0" : 0.02243926284753363, + "90.0" : 0.023448793035128805, + "95.0" : 0.023448793035128805, + "99.0" : 0.023448793035128805, + "99.9" : 0.023448793035128805, + "99.99" : 0.023448793035128805, + "99.999" : 0.023448793035128805, + "99.9999" : 0.023448793035128805, + "100.0" : 0.023448793035128805 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02333720638927739, + 0.023367165808411215, + 0.023448793035128805 + ], + [ + 0.022580380595936794, + 0.022375214377232142, + 0.02243926284753363 + ], + [ + 0.022161285869469027, + 0.022003197446153845, + 0.02194287973464912 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-04T02:33:30Z-3e5c77ba3f27de559a65c42684fc7deb9dead263-jdk17.json b/performance-results/2024-12-04T02:33:30Z-3e5c77ba3f27de559a65c42684fc7deb9dead263-jdk17.json new file mode 100644 index 0000000000..2c04859665 --- /dev/null +++ b/performance-results/2024-12-04T02:33:30Z-3e5c77ba3f27de559a65c42684fc7deb9dead263-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4152001755669277, + "scoreError" : 0.021628843464137723, + "scoreConfidence" : [ + 3.39357133210279, + 3.4368290190310655 + ], + "scorePercentiles" : { + "0.0" : 3.4121139027546206, + "50.0" : 3.4144609174987552, + "90.0" : 3.419764964515579, + "95.0" : 3.419764964515579, + "99.0" : 3.419764964515579, + "99.9" : 3.419764964515579, + "99.99" : 3.419764964515579, + "99.999" : 3.419764964515579, + "99.9999" : 3.419764964515579, + "100.0" : 3.419764964515579 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4134232276246173, + 3.419764964515579 + ], + [ + 3.4121139027546206, + 3.415498607372893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7263020460260308, + "scoreError" : 0.019054912694287184, + "scoreConfidence" : [ + 1.7072471333317436, + 1.745356958720318 + ], + "scorePercentiles" : { + "0.0" : 1.7233094219683196, + "50.0" : 1.7257643130488556, + "90.0" : 1.7303701360380923, + "95.0" : 1.7303701360380923, + "99.0" : 1.7303701360380923, + "99.9" : 1.7303701360380923, + "99.99" : 1.7303701360380923, + "99.999" : 1.7303701360380923, + "99.9999" : 1.7303701360380923, + "100.0" : 1.7303701360380923 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7233094219683196, + 1.7257308147936137 + ], + [ + 1.7257978113040977, + 1.7303701360380923 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8680565422533224, + "scoreError" : 0.004144184933370064, + "scoreConfidence" : [ + 0.8639123573199523, + 0.8722007271866925 + ], + "scorePercentiles" : { + "0.0" : 0.8673780217192926, + "50.0" : 0.8680285063653239, + "90.0" : 0.8687911345633491, + "95.0" : 0.8687911345633491, + "99.0" : 0.8687911345633491, + "99.9" : 0.8687911345633491, + "99.99" : 0.8687911345633491, + "99.999" : 0.8687911345633491, + "99.9999" : 0.8687911345633491, + "100.0" : 0.8687911345633491 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8673780217192926, + 0.8687911345633491 + ], + [ + 0.8683692960924105, + 0.8676877166382374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 43.24510151191392, + "scoreError" : 1.658507364853044, + "scoreConfidence" : [ + 41.58659414706088, + 44.90360887676697 + ], + "scorePercentiles" : { + "0.0" : 41.770911843921056, + "50.0" : 43.48692947280641, + "90.0" : 44.42339392286783, + "95.0" : 44.42339392286783, + "99.0" : 44.42339392286783, + "99.9" : 44.42339392286783, + "99.99" : 44.42339392286783, + "99.999" : 44.42339392286783, + "99.9999" : 44.42339392286783, + "100.0" : 44.42339392286783 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.42339392286783, + 43.72390047070996, + 44.0283409955762 + ], + [ + 41.770911843921056, + 41.938385219028056, + 42.33876278427692 + ], + [ + 43.36311706281474, + 43.48692947280641, + 44.13217183522408 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022512762277781196, + "scoreError" : 5.112572288638061E-4, + "scoreConfidence" : [ + 0.02200150504891739, + 0.023024019506645003 + ], + "scorePercentiles" : { + "0.0" : 0.022083574353200883, + "50.0" : 0.022541668768018018, + "90.0" : 0.02301931708275862, + "95.0" : 0.02301931708275862, + "99.0" : 0.02301931708275862, + "99.9" : 0.02301931708275862, + "99.99" : 0.02301931708275862, + "99.999" : 0.02301931708275862, + "99.9999" : 0.02301931708275862, + "100.0" : 0.02301931708275862 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02301931708275862, + 0.02268371470068027, + 0.022794350806378132 + ], + [ + 0.02236791441517857, + 0.02244032732735426, + 0.022571994894144146 + ], + [ + 0.02211199815231788, + 0.022083574353200883, + 0.022541668768018018 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-05T21:56:29Z-08cf1702ce0c96ee0ed414ee8085a75696bc6cae-jdk17.json b/performance-results/2024-12-05T21:56:29Z-08cf1702ce0c96ee0ed414ee8085a75696bc6cae-jdk17.json new file mode 100644 index 0000000000..2eb4cb00ca --- /dev/null +++ b/performance-results/2024-12-05T21:56:29Z-08cf1702ce0c96ee0ed414ee8085a75696bc6cae-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.39947127955597, + "scoreError" : 0.04375139947714444, + "scoreConfidence" : [ + 3.3557198800788255, + 3.4432226790331146 + ], + "scorePercentiles" : { + "0.0" : 3.3932042357857095, + "50.0" : 3.398319202804707, + "90.0" : 3.4080424768287556, + "95.0" : 3.4080424768287556, + "99.0" : 3.4080424768287556, + "99.9" : 3.4080424768287556, + "99.99" : 3.4080424768287556, + "99.999" : 3.4080424768287556, + "99.9999" : 3.4080424768287556, + "100.0" : 3.4080424768287556 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3932042357857095, + 3.3949930686358667 + ], + [ + 3.4016453369735475, + 3.4080424768287556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7202643292853323, + "scoreError" : 0.010698822469557535, + "scoreConfidence" : [ + 1.709565506815775, + 1.7309631517548898 + ], + "scorePercentiles" : { + "0.0" : 1.7185075642902061, + "50.0" : 1.7200781357517012, + "90.0" : 1.722393481347721, + "95.0" : 1.722393481347721, + "99.0" : 1.722393481347721, + "99.9" : 1.722393481347721, + "99.99" : 1.722393481347721, + "99.999" : 1.722393481347721, + "99.9999" : 1.722393481347721, + "100.0" : 1.722393481347721 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7185075642902061, + 1.722393481347721 + ], + [ + 1.719561062814024, + 1.7205952086893783 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8654605738416737, + "scoreError" : 0.002206407164656894, + "scoreConfidence" : [ + 0.8632541666770168, + 0.8676669810063307 + ], + "scorePercentiles" : { + "0.0" : 0.8649842104508775, + "50.0" : 0.8655377996365867, + "90.0" : 0.8657824856426442, + "95.0" : 0.8657824856426442, + "99.0" : 0.8657824856426442, + "99.9" : 0.8657824856426442, + "99.99" : 0.8657824856426442, + "99.999" : 0.8657824856426442, + "99.9999" : 0.8657824856426442, + "100.0" : 0.8657824856426442 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8649842104508775, + 0.8654774880262567 + ], + [ + 0.8655981112469168, + 0.8657824856426442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 41.38406101685299, + "scoreError" : 0.6843156074743918, + "scoreConfidence" : [ + 40.6997454093786, + 42.06837662432738 + ], + "scorePercentiles" : { + "0.0" : 40.78923580225026, + "50.0" : 41.44125463453928, + "90.0" : 41.95496958011177, + "95.0" : 41.95496958011177, + "99.0" : 41.95496958011177, + "99.9" : 41.95496958011177, + "99.99" : 41.95496958011177, + "99.999" : 41.95496958011177, + "99.9999" : 41.95496958011177, + "100.0" : 41.95496958011177 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 40.90606757700961, + 41.44125463453928, + 41.95496958011177 + ], + [ + 41.86591295369653, + 41.48402929587195, + 41.624082377265175 + ], + [ + 41.04673717098326, + 41.34425975994901, + 40.78923580225026 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.024747128652428545, + "scoreError" : 8.316013168757033E-4, + "scoreConfidence" : [ + 0.02391552733555284, + 0.02557872996930425 + ], + "scorePercentiles" : { + "0.0" : 0.02395063935167464, + "50.0" : 0.024757809653465346, + "90.0" : 0.025461867081424935, + "95.0" : 0.025461867081424935, + "99.0" : 0.025461867081424935, + "99.9" : 0.025461867081424935, + "99.99" : 0.025461867081424935, + "99.999" : 0.025461867081424935, + "99.9999" : 0.025461867081424935, + "100.0" : 0.025461867081424935 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.024250484956416466, + 0.02482653333995037, + 0.024802851465346536 + ], + [ + 0.025461867081424935, + 0.02452199099754902, + 0.02545728996183206 + ], + [ + 0.02469469106419753, + 0.024757809653465346, + 0.02395063935167464 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-08T08:18:55Z-3d46b3737bf4f0c617425af4c63036a1336a7423-jdk17.json b/performance-results/2024-12-08T08:18:55Z-3d46b3737bf4f0c617425af4c63036a1336a7423-jdk17.json new file mode 100644 index 0000000000..d7d4143001 --- /dev/null +++ b/performance-results/2024-12-08T08:18:55Z-3d46b3737bf4f0c617425af4c63036a1336a7423-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4077902649261356, + "scoreError" : 0.011234878517476501, + "scoreConfidence" : [ + 3.396555386408659, + 3.419025143443612 + ], + "scorePercentiles" : { + "0.0" : 3.4053492910657934, + "50.0" : 3.408347201679087, + "90.0" : 3.4091173652805766, + "95.0" : 3.4091173652805766, + "99.0" : 3.4091173652805766, + "99.9" : 3.4091173652805766, + "99.99" : 3.4091173652805766, + "99.999" : 3.4091173652805766, + "99.9999" : 3.4091173652805766, + "100.0" : 3.4091173652805766 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4053492910657934, + 3.407743717137213 + ], + [ + 3.40895068622096, + 3.4091173652805766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7203127954265476, + "scoreError" : 0.013318600773962557, + "scoreConfidence" : [ + 1.706994194652585, + 1.73363139620051 + ], + "scorePercentiles" : { + "0.0" : 1.7175975018719172, + "50.0" : 1.7205913784095175, + "90.0" : 1.722470923015238, + "95.0" : 1.722470923015238, + "99.0" : 1.722470923015238, + "99.9" : 1.722470923015238, + "99.99" : 1.722470923015238, + "99.999" : 1.722470923015238, + "99.9999" : 1.722470923015238, + "100.0" : 1.722470923015238 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7211197986006654, + 1.722470923015238 + ], + [ + 1.7175975018719172, + 1.7200629582183695 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8650705897922965, + "scoreError" : 0.009557110836336062, + "scoreConfidence" : [ + 0.8555134789559604, + 0.8746277006286325 + ], + "scorePercentiles" : { + "0.0" : 0.8631902016341529, + "50.0" : 0.8653947483238336, + "90.0" : 0.8663026608873658, + "95.0" : 0.8663026608873658, + "99.0" : 0.8663026608873658, + "99.9" : 0.8663026608873658, + "99.99" : 0.8663026608873658, + "99.999" : 0.8663026608873658, + "99.9999" : 0.8663026608873658, + "100.0" : 0.8663026608873658 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8662003758298101, + 0.8663026608873658 + ], + [ + 0.8631902016341529, + 0.864589120817857 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 41.829882344445565, + "scoreError" : 2.1834707260014885, + "scoreConfidence" : [ + 39.64641161844408, + 44.01335307044705 + ], + "scorePercentiles" : { + "0.0" : 40.522546266756436, + "50.0" : 41.16019698230881, + "90.0" : 43.998564098060946, + "95.0" : 43.998564098060946, + "99.0" : 43.998564098060946, + "99.9" : 43.998564098060946, + "99.99" : 43.998564098060946, + "99.999" : 43.998564098060946, + "99.9999" : 43.998564098060946, + "100.0" : 43.998564098060946 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 40.99599155133248, + 41.10904513591438, + 41.16019698230881 + ], + [ + 40.92612743551148, + 41.19737129049191, + 40.522546266756436 + ], + [ + 43.20615819460214, + 43.998564098060946, + 43.3529401450314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.023323010576891567, + "scoreError" : 6.943879125023075E-4, + "scoreConfidence" : [ + 0.02262862266438926, + 0.024017398489393875 + ], + "scorePercentiles" : { + "0.0" : 0.02265938378280543, + "50.0" : 0.023499072201877934, + "90.0" : 0.02383227217142857, + "95.0" : 0.02383227217142857, + "99.0" : 0.02383227217142857, + "99.9" : 0.02383227217142857, + "99.99" : 0.02383227217142857, + "99.999" : 0.02383227217142857, + "99.9999" : 0.02383227217142857, + "100.0" : 0.02383227217142857 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.023499072201877934, + 0.023596047476415093, + 0.023534972790588235 + ], + [ + 0.022848023748858446, + 0.022876015378995435, + 0.02265938378280543 + ], + [ + 0.023485217551643192, + 0.023576090089411764, + 0.02383227217142857 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-08T22:54:25Z-46c03234896e2ffad02a5dbf704a721ea0717c67-jdk17.json b/performance-results/2024-12-08T22:54:25Z-46c03234896e2ffad02a5dbf704a721ea0717c67-jdk17.json new file mode 100644 index 0000000000..a13f68e381 --- /dev/null +++ b/performance-results/2024-12-08T22:54:25Z-46c03234896e2ffad02a5dbf704a721ea0717c67-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.424378627035124, + "scoreError" : 0.0240399263203179, + "scoreConfidence" : [ + 3.4003387007148063, + 3.448418553355442 + ], + "scorePercentiles" : { + "0.0" : 3.4207630701321463, + "50.0" : 3.4236022814383293, + "90.0" : 3.429546875131693, + "95.0" : 3.429546875131693, + "99.0" : 3.429546875131693, + "99.9" : 3.429546875131693, + "99.99" : 3.429546875131693, + "99.999" : 3.429546875131693, + "99.9999" : 3.429546875131693, + "100.0" : 3.429546875131693 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4230868615582297, + 3.429546875131693 + ], + [ + 3.4207630701321463, + 3.4241177013184285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7298687803269965, + "scoreError" : 0.010463124288060224, + "scoreConfidence" : [ + 1.7194056560389364, + 1.7403319046150567 + ], + "scorePercentiles" : { + "0.0" : 1.7280934234954237, + "50.0" : 1.7296979626163922, + "90.0" : 1.731985772579778, + "95.0" : 1.731985772579778, + "99.0" : 1.731985772579778, + "99.9" : 1.731985772579778, + "99.99" : 1.731985772579778, + "99.999" : 1.731985772579778, + "99.9999" : 1.731985772579778, + "100.0" : 1.731985772579778 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7294035761393258, + 1.731985772579778 + ], + [ + 1.7280934234954237, + 1.7299923490934583 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8701164779654085, + "scoreError" : 0.00395761298041778, + "scoreConfidence" : [ + 0.8661588649849907, + 0.8740740909458262 + ], + "scorePercentiles" : { + "0.0" : 0.869458088898, + "50.0" : 0.8701123859892204, + "90.0" : 0.8707830509851929, + "95.0" : 0.8707830509851929, + "99.0" : 0.8707830509851929, + "99.9" : 0.8707830509851929, + "99.99" : 0.8707830509851929, + "99.999" : 0.8707830509851929, + "99.9999" : 0.8707830509851929, + "100.0" : 0.8707830509851929 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8704641226465905, + 0.8707830509851929 + ], + [ + 0.869458088898, + 0.8697606493318503 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.78882381498855, + "scoreError" : 1.6789885454880027, + "scoreConfidence" : [ + 43.10983526950054, + 46.46781236047655 + ], + "scorePercentiles" : { + "0.0" : 43.649949104503946, + "50.0" : 44.40706804090582, + "90.0" : 46.08789493604563, + "95.0" : 46.08789493604563, + "99.0" : 46.08789493604563, + "99.9" : 46.08789493604563, + "99.99" : 46.08789493604563, + "99.999" : 46.08789493604563, + "99.9999" : 46.08789493604563, + "100.0" : 46.08789493604563 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 46.06557024270227, + 46.08789493604563, + 46.08198077042825 + ], + [ + 44.39265750328088, + 44.40706804090582, + 44.42821713852795 + ], + [ + 43.649949104503946, + 43.99180129638337, + 43.99427530211887 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02236314997162596, + "scoreError" : 7.931364759453877E-4, + "scoreConfidence" : [ + 0.021570013495680572, + 0.023156286447571346 + ], + "scorePercentiles" : { + "0.0" : 0.022002074795604395, + "50.0" : 0.022066712607929515, + "90.0" : 0.02300942944597701, + "95.0" : 0.02300942944597701, + "99.0" : 0.02300942944597701, + "99.9" : 0.02300942944597701, + "99.99" : 0.02300942944597701, + "99.999" : 0.02300942944597701, + "99.9999" : 0.02300942944597701, + "100.0" : 0.02300942944597701 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02299016895632184, + 0.02297587995642202, + 0.02300942944597701 + ], + [ + 0.02206858371585903, + 0.022066712607929515, + 0.022060007019823788 + ], + [ + 0.022002074795604395, + 0.022048064753303964, + 0.02204742849339207 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-09T02:45:13Z-35760dc9e50dc3ce35a046a5b272eda696c870d5-jdk17.json b/performance-results/2024-12-09T02:45:13Z-35760dc9e50dc3ce35a046a5b272eda696c870d5-jdk17.json new file mode 100644 index 0000000000..68ea673507 --- /dev/null +++ b/performance-results/2024-12-09T02:45:13Z-35760dc9e50dc3ce35a046a5b272eda696c870d5-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3995645247595654, + "scoreError" : 0.02987629044326602, + "scoreConfidence" : [ + 3.3696882343162993, + 3.4294408152028315 + ], + "scorePercentiles" : { + "0.0" : 3.393628753189234, + "50.0" : 3.400273375153123, + "90.0" : 3.404082595542781, + "95.0" : 3.404082595542781, + "99.0" : 3.404082595542781, + "99.9" : 3.404082595542781, + "99.99" : 3.404082595542781, + "99.999" : 3.404082595542781, + "99.9999" : 3.404082595542781, + "100.0" : 3.404082595542781 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.398339998248194, + 3.4022067520580523 + ], + [ + 3.393628753189234, + 3.404082595542781 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7205088090910943, + "scoreError" : 0.012083738709990733, + "scoreConfidence" : [ + 1.7084250703811035, + 1.732592547801085 + ], + "scorePercentiles" : { + "0.0" : 1.7181281468730438, + "50.0" : 1.7209360921738943, + "90.0" : 1.722034905143545, + "95.0" : 1.722034905143545, + "99.0" : 1.722034905143545, + "99.9" : 1.722034905143545, + "99.99" : 1.722034905143545, + "99.999" : 1.722034905143545, + "99.9999" : 1.722034905143545, + "100.0" : 1.722034905143545 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7181281468730438, + 1.722034905143545 + ], + [ + 1.7199044135030424, + 1.721967770844746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.864565745832372, + "scoreError" : 0.0026425774790852547, + "scoreConfidence" : [ + 0.8619231683532868, + 0.8672083233114573 + ], + "scorePercentiles" : { + "0.0" : 0.8642812220365862, + "50.0" : 0.8644122330769803, + "90.0" : 0.8651572951389412, + "95.0" : 0.8651572951389412, + "99.0" : 0.8651572951389412, + "99.9" : 0.8651572951389412, + "99.99" : 0.8651572951389412, + "99.999" : 0.8651572951389412, + "99.9999" : 0.8651572951389412, + "100.0" : 0.8651572951389412 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8642812220365862, + 0.8643034133675414 + ], + [ + 0.8645210527864192, + 0.8651572951389412 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 38.949218227332636, + "scoreError" : 1.5418956244161082, + "scoreConfidence" : [ + 37.40732260291653, + 40.49111385174874 + ], + "scorePercentiles" : { + "0.0" : 37.33301129092536, + "50.0" : 38.9146032107846, + "90.0" : 40.30890725487399, + "95.0" : 40.30890725487399, + "99.0" : 40.30890725487399, + "99.9" : 40.30890725487399, + "99.99" : 40.30890725487399, + "99.999" : 40.30890725487399, + "99.9999" : 40.30890725487399, + "100.0" : 40.30890725487399 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 39.64330498367299, + 39.921199062124764, + 40.30890725487399 + ], + [ + 37.33301129092536, + 38.286993705317236, + 38.383005751480006 + ], + [ + 39.07198320782333, + 38.9146032107846, + 38.6799555789915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.026043005372482237, + "scoreError" : 0.0013237341236282344, + "scoreConfidence" : [ + 0.024719271248854, + 0.027366739496110473 + ], + "scorePercentiles" : { + "0.0" : 0.024870349985111662, + "50.0" : 0.026153539485639688, + "90.0" : 0.026994492881401617, + "95.0" : 0.026994492881401617, + "99.0" : 0.026994492881401617, + "99.9" : 0.026994492881401617, + "99.99" : 0.026994492881401617, + "99.999" : 0.026994492881401617, + "99.9999" : 0.026994492881401617, + "100.0" : 0.026994492881401617 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.025874787736434108, + 0.026153539485639688, + 0.026638927933510637 + ], + [ + 0.02556267860714286, + 0.024960604900249376, + 0.024870349985111662 + ], + [ + 0.02643135141424802, + 0.026994492881401617, + 0.02690031540860215 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-17T03:02:43Z-9de9f06a7200cf98c69129730626f9a5f35f6e8d-jdk17.json b/performance-results/2024-12-17T03:02:43Z-9de9f06a7200cf98c69129730626f9a5f35f6e8d-jdk17.json new file mode 100644 index 0000000000..ccf4a784ae --- /dev/null +++ b/performance-results/2024-12-17T03:02:43Z-9de9f06a7200cf98c69129730626f9a5f35f6e8d-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4254834308373514, + "scoreError" : 0.015025400543458568, + "scoreConfidence" : [ + 3.410458030293893, + 3.44050883138081 + ], + "scorePercentiles" : { + "0.0" : 3.423328219387952, + "50.0" : 3.425552177730207, + "90.0" : 3.42750114850104, + "95.0" : 3.42750114850104, + "99.0" : 3.42750114850104, + "99.9" : 3.42750114850104, + "99.99" : 3.42750114850104, + "99.999" : 3.42750114850104, + "99.9999" : 3.42750114850104, + "100.0" : 3.42750114850104 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.423328219387952, + 3.42750114850104 + ], + [ + 3.4236164536870035, + 3.4274879017734112 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7302247645519597, + "scoreError" : 0.010033955510826632, + "scoreConfidence" : [ + 1.720190809041133, + 1.7402587200627864 + ], + "scorePercentiles" : { + "0.0" : 1.7288955727752675, + "50.0" : 1.7298209211776594, + "90.0" : 1.7323616430772524, + "95.0" : 1.7323616430772524, + "99.0" : 1.7323616430772524, + "99.9" : 1.7323616430772524, + "99.99" : 1.7323616430772524, + "99.999" : 1.7323616430772524, + "99.9999" : 1.7323616430772524, + "100.0" : 1.7323616430772524 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7292851672177052, + 1.7323616430772524 + ], + [ + 1.7288955727752675, + 1.7303566751376136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8700678921409488, + "scoreError" : 0.00713353924393665, + "scoreConfidence" : [ + 0.8629343528970121, + 0.8772014313848855 + ], + "scorePercentiles" : { + "0.0" : 0.8686670360707984, + "50.0" : 0.8701250932717297, + "90.0" : 0.8713543459495379, + "95.0" : 0.8713543459495379, + "99.0" : 0.8713543459495379, + "99.9" : 0.8713543459495379, + "99.99" : 0.8713543459495379, + "99.999" : 0.8713543459495379, + "99.9999" : 0.8713543459495379, + "100.0" : 0.8713543459495379 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8686670360707984, + 0.8702516506204957 + ], + [ + 0.8699985359229638, + 0.8713543459495379 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 45.32130915520371, + "scoreError" : 3.560055957159324, + "scoreConfidence" : [ + 41.761253198044386, + 48.88136511236303 + ], + "scorePercentiles" : { + "0.0" : 42.7537076662837, + "50.0" : 45.5422455784985, + "90.0" : 47.642633062453015, + "95.0" : 47.642633062453015, + "99.0" : 47.642633062453015, + "99.9" : 47.642633062453015, + "99.99" : 47.642633062453015, + "99.999" : 47.642633062453015, + "99.9999" : 47.642633062453015, + "100.0" : 47.642633062453015 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.7537076662837, + 42.76955088117818, + 42.768304606190554 + ], + [ + 47.63155598328764, + 47.64036553406184, + 47.642633062453015 + ], + [ + 45.624284346660495, + 45.519134738219414, + 45.5422455784985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022670557238933457, + "scoreError" : 9.94605572521605E-4, + "scoreConfidence" : [ + 0.02167595166641185, + 0.023665162811455063 + ], + "scorePercentiles" : { + "0.0" : 0.022023165004395603, + "50.0" : 0.022586484038374717, + "90.0" : 0.02347066886416862, + "95.0" : 0.02347066886416862, + "99.0" : 0.02347066886416862, + "99.9" : 0.02347066886416862, + "99.99" : 0.02347066886416862, + "99.999" : 0.02347066886416862, + "99.9999" : 0.02347066886416862, + "100.0" : 0.02347066886416862 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02347066886416862, + 0.023345283524475523, + 0.02333887996270396 + ], + [ + 0.02202807403964758, + 0.02202869620044053, + 0.022023165004395603 + ], + [ + 0.022632988674208144, + 0.022580774841986458, + 0.022586484038374717 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2024-12-26T02:48:37Z-d4b3b07df4d1edecfdcaaec4fb5adc54728f9574-jdk17.json b/performance-results/2024-12-26T02:48:37Z-d4b3b07df4d1edecfdcaaec4fb5adc54728f9574-jdk17.json new file mode 100644 index 0000000000..b1e6221354 --- /dev/null +++ b/performance-results/2024-12-26T02:48:37Z-d4b3b07df4d1edecfdcaaec4fb5adc54728f9574-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4183186208130487, + "scoreError" : 0.022246121905918532, + "scoreConfidence" : [ + 3.39607249890713, + 3.4405647427189674 + ], + "scorePercentiles" : { + "0.0" : 3.413848941434486, + "50.0" : 3.4190590718704748, + "90.0" : 3.42130739807676, + "95.0" : 3.42130739807676, + "99.0" : 3.42130739807676, + "99.9" : 3.42130739807676, + "99.99" : 3.42130739807676, + "99.999" : 3.42130739807676, + "99.9999" : 3.42130739807676, + "100.0" : 3.42130739807676 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4173936330209784, + 3.42130739807676 + ], + [ + 3.413848941434486, + 3.4207245107199706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7291357989986291, + "scoreError" : 0.015790087869288705, + "scoreConfidence" : [ + 1.7133457111293404, + 1.7449258868679178 + ], + "scorePercentiles" : { + "0.0" : 1.726553979052951, + "50.0" : 1.7288314425743558, + "90.0" : 1.7323263317928532, + "95.0" : 1.7323263317928532, + "99.0" : 1.7323263317928532, + "99.9" : 1.7323263317928532, + "99.99" : 1.7323263317928532, + "99.999" : 1.7323263317928532, + "99.9999" : 1.7323263317928532, + "100.0" : 1.7323263317928532 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.726553979052951, + 1.729495524499686 + ], + [ + 1.728167360649026, + 1.7323263317928532 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8694925783721111, + "scoreError" : 0.0043954381149764795, + "scoreConfidence" : [ + 0.8650971402571347, + 0.8738880164870876 + ], + "scorePercentiles" : { + "0.0" : 0.868936526115034, + "50.0" : 0.8692746681495762, + "90.0" : 0.8704844510742582, + "95.0" : 0.8704844510742582, + "99.0" : 0.8704844510742582, + "99.9" : 0.8704844510742582, + "99.99" : 0.8704844510742582, + "99.999" : 0.8704844510742582, + "99.9999" : 0.8704844510742582, + "100.0" : 0.8704844510742582 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.869270402780433, + 0.8692789335187193 + ], + [ + 0.868936526115034, + 0.8704844510742582 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.48605468306695, + "scoreError" : 2.5689013669187672, + "scoreConfidence" : [ + 41.91715331614819, + 47.05495604998572 + ], + "scorePercentiles" : { + "0.0" : 42.465270555590564, + "50.0" : 45.23859981991722, + "90.0" : 45.75807170958764, + "95.0" : 45.75807170958764, + "99.0" : 45.75807170958764, + "99.9" : 45.75807170958764, + "99.99" : 45.75807170958764, + "99.999" : 45.75807170958764, + "99.9999" : 45.75807170958764, + "100.0" : 45.75807170958764 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.465270555590564, + 42.465537157018524, + 42.47251210446258 + ], + [ + 45.75807170958764, + 45.73163472741838, + 45.73404569787986 + ], + [ + 45.23859981991722, + 45.22964511515073, + 45.279175260577084 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02247107156704055, + "scoreError" : 5.19834581792683E-4, + "scoreConfidence" : [ + 0.021951236985247865, + 0.022990906148833232 + ], + "scorePercentiles" : { + "0.0" : 0.02216260132522124, + "50.0" : 0.0223607604375, + "90.0" : 0.022881822034246574, + "95.0" : 0.022881822034246574, + "99.0" : 0.022881822034246574, + "99.9" : 0.022881822034246574, + "99.99" : 0.022881822034246574, + "99.999" : 0.022881822034246574, + "99.9999" : 0.022881822034246574, + "100.0" : 0.022881822034246574 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.022213481620842572, + 0.022176993237250555, + 0.02216260132522124 + ], + [ + 0.022881822034246574, + 0.022866326511415524, + 0.02286390547260274 + ], + [ + 0.02236220743526786, + 0.0223607604375, + 0.022351546029017857 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-03T23:05:41Z-74c62b6464504f3231805d928499e3faaeaddd2b-jdk17.json b/performance-results/2025-01-03T23:05:41Z-74c62b6464504f3231805d928499e3faaeaddd2b-jdk17.json new file mode 100644 index 0000000000..3e67765b46 --- /dev/null +++ b/performance-results/2025-01-03T23:05:41Z-74c62b6464504f3231805d928499e3faaeaddd2b-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4086383192028586, + "scoreError" : 0.05662927719471223, + "scoreConfidence" : [ + 3.3520090420081465, + 3.4652675963975708 + ], + "scorePercentiles" : { + "0.0" : 3.3989687508416133, + "50.0" : 3.4089573516309404, + "90.0" : 3.4176698227079405, + "95.0" : 3.4176698227079405, + "99.0" : 3.4176698227079405, + "99.9" : 3.4176698227079405, + "99.99" : 3.4176698227079405, + "99.999" : 3.4176698227079405, + "99.9999" : 3.4176698227079405, + "100.0" : 3.4176698227079405 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3989687508416133, + 3.4037075113574597 + ], + [ + 3.4176698227079405, + 3.414207191904421 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7247042514212518, + "scoreError" : 0.025577661073979848, + "scoreConfidence" : [ + 1.699126590347272, + 1.7502819124952316 + ], + "scorePercentiles" : { + "0.0" : 1.7199822553826223, + "50.0" : 1.7247603094085062, + "90.0" : 1.729314131485372, + "95.0" : 1.729314131485372, + "99.0" : 1.729314131485372, + "99.9" : 1.729314131485372, + "99.99" : 1.729314131485372, + "99.999" : 1.729314131485372, + "99.9999" : 1.729314131485372, + "100.0" : 1.729314131485372 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7199822553826223, + 1.7234475192789092 + ], + [ + 1.7260730995381033, + 1.729314131485372 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.866926795435834, + "scoreError" : 0.0024224565675789894, + "scoreConfidence" : [ + 0.864504338868255, + 0.869349252003413 + ], + "scorePercentiles" : { + "0.0" : 0.86643401727251, + "50.0" : 0.8670019062531722, + "90.0" : 0.8672693519644817, + "95.0" : 0.8672693519644817, + "99.0" : 0.8672693519644817, + "99.9" : 0.8672693519644817, + "99.99" : 0.8672693519644817, + "99.999" : 0.8672693519644817, + "99.9999" : 0.8672693519644817, + "100.0" : 0.8672693519644817 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8671602438844096, + 0.8672693519644817 + ], + [ + 0.86643401727251, + 0.8668435686219347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 43.19235624466463, + "scoreError" : 0.8357968532166162, + "scoreConfidence" : [ + 42.356559391448016, + 44.028153097881244 + ], + "scorePercentiles" : { + "0.0" : 42.558882497479054, + "50.0" : 43.37071116457182, + "90.0" : 43.74757796416252, + "95.0" : 43.74757796416252, + "99.0" : 43.74757796416252, + "99.9" : 43.74757796416252, + "99.99" : 43.74757796416252, + "99.999" : 43.74757796416252, + "99.9999" : 43.74757796416252, + "100.0" : 43.74757796416252 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 43.74757796416252, + 43.62853498940572, + 43.704103996118626 + ], + [ + 43.1493793660059, + 43.40285809714331, + 43.37071116457182 + ], + [ + 42.60127105164282, + 42.567887075451914, + 42.558882497479054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02386800728298746, + "scoreError" : 0.0012277527492095812, + "scoreConfidence" : [ + 0.022640254533777878, + 0.025095760032197042 + ], + "scorePercentiles" : { + "0.0" : 0.023171930243055555, + "50.0" : 0.023588256443396228, + "90.0" : 0.024856540679900743, + "95.0" : 0.024856540679900743, + "99.0" : 0.024856540679900743, + "99.9" : 0.024856540679900743, + "99.99" : 0.024856540679900743, + "99.999" : 0.024856540679900743, + "99.9999" : 0.024856540679900743, + "100.0" : 0.024856540679900743 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02369723180851064, + 0.023588256443396228, + 0.023394148107476635 + ], + [ + 0.024750938538271604, + 0.024856540679900743, + 0.024840508146401985 + ], + [ + 0.023294356925581395, + 0.023171930243055555, + 0.023218154654292344 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-06T22:51:09Z-9b4739e8f4dfc1f84a50807d8f4f511a9c84766b-jdk17.json b/performance-results/2025-01-06T22:51:09Z-9b4739e8f4dfc1f84a50807d8f4f511a9c84766b-jdk17.json new file mode 100644 index 0000000000..d5e2c28bc1 --- /dev/null +++ b/performance-results/2025-01-06T22:51:09Z-9b4739e8f4dfc1f84a50807d8f4f511a9c84766b-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3976951594270473, + "scoreError" : 0.021181351836786013, + "scoreConfidence" : [ + 3.3765138075902614, + 3.418876511263833 + ], + "scorePercentiles" : { + "0.0" : 3.394397211357331, + "50.0" : 3.3970764950011465, + "90.0" : 3.4022304363485647, + "95.0" : 3.4022304363485647, + "99.0" : 3.4022304363485647, + "99.9" : 3.4022304363485647, + "99.99" : 3.4022304363485647, + "99.999" : 3.4022304363485647, + "99.9999" : 3.4022304363485647, + "100.0" : 3.4022304363485647 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.396971687382568, + 3.4022304363485647 + ], + [ + 3.394397211357331, + 3.397181302619725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7206873716995075, + "scoreError" : 0.012165584639558507, + "scoreConfidence" : [ + 1.708521787059949, + 1.732852956339066 + ], + "scorePercentiles" : { + "0.0" : 1.7186421998985886, + "50.0" : 1.7205165660847093, + "90.0" : 1.723074154730023, + "95.0" : 1.723074154730023, + "99.0" : 1.723074154730023, + "99.9" : 1.723074154730023, + "99.99" : 1.723074154730023, + "99.999" : 1.723074154730023, + "99.9999" : 1.723074154730023, + "100.0" : 1.723074154730023 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7186421998985886, + 1.723074154730023 + ], + [ + 1.7199270052468307, + 1.7211061269225876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8652782291117496, + "scoreError" : 0.005814391511710975, + "scoreConfidence" : [ + 0.8594638376000386, + 0.8710926206234605 + ], + "scorePercentiles" : { + "0.0" : 0.8644150098784186, + "50.0" : 0.86521255834284, + "90.0" : 0.8662727898828995, + "95.0" : 0.8662727898828995, + "99.0" : 0.8662727898828995, + "99.9" : 0.8662727898828995, + "99.99" : 0.8662727898828995, + "99.999" : 0.8662727898828995, + "99.9999" : 0.8662727898828995, + "100.0" : 0.8662727898828995 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8644150098784186, + 0.8657981807853821 + ], + [ + 0.8646269359002979, + 0.8662727898828995 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 40.61285782239622, + "scoreError" : 0.6777927611228544, + "scoreConfidence" : [ + 39.93506506127337, + 41.290650583519074 + ], + "scorePercentiles" : { + "0.0" : 40.135983126980456, + "50.0" : 40.446192613931636, + "90.0" : 41.26053647129548, + "95.0" : 41.26053647129548, + "99.0" : 41.26053647129548, + "99.9" : 41.26053647129548, + "99.99" : 41.26053647129548, + "99.999" : 41.26053647129548, + "99.9999" : 41.26053647129548, + "100.0" : 41.26053647129548 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 40.42388748729046, + 40.135983126980456, + 40.446192613931636 + ], + [ + 41.26053647129548, + 40.93219516379605, + 41.0876293447744 + ], + [ + 40.692707622637776, + 40.36803370459829, + 40.168554866261466 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.024507084673500084, + "scoreError" : 7.918917887814012E-4, + "scoreConfidence" : [ + 0.023715192884718683, + 0.025298976462281485 + ], + "scorePercentiles" : { + "0.0" : 0.023988348623501198, + "50.0" : 0.02444568706097561, + "90.0" : 0.025114872824561405, + "95.0" : 0.025114872824561405, + "99.0" : 0.025114872824561405, + "99.9" : 0.025114872824561405, + "99.99" : 0.025114872824561405, + "99.999" : 0.025114872824561405, + "99.9999" : 0.025114872824561405, + "100.0" : 0.025114872824561405 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.025114872824561405, + 0.024194508417874395, + 0.02402947871942446 + ], + [ + 0.024717387565432097, + 0.02510975446115288, + 0.024928946002487563 + ], + [ + 0.024034778386091128, + 0.023988348623501198, + 0.02444568706097561 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-06T23:22:01Z-e0f6b66266fac13aeecaef1c2ef1b458828b6cc2-jdk17.json b/performance-results/2025-01-06T23:22:01Z-e0f6b66266fac13aeecaef1c2ef1b458828b6cc2-jdk17.json new file mode 100644 index 0000000000..13895b223c --- /dev/null +++ b/performance-results/2025-01-06T23:22:01Z-e0f6b66266fac13aeecaef1c2ef1b458828b6cc2-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4245773136105413, + "scoreError" : 0.01868185502277945, + "scoreConfidence" : [ + 3.4058954585877617, + 3.443259168633321 + ], + "scorePercentiles" : { + "0.0" : 3.4210483921283243, + "50.0" : 3.4245663949120306, + "90.0" : 3.428128072489781, + "95.0" : 3.428128072489781, + "99.0" : 3.428128072489781, + "99.9" : 3.428128072489781, + "99.99" : 3.428128072489781, + "99.999" : 3.428128072489781, + "99.9999" : 3.428128072489781, + "100.0" : 3.428128072489781 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4210483921283243, + 3.42448613335437 + ], + [ + 3.4246466564696907, + 3.428128072489781 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7286707595661703, + "scoreError" : 0.014432774965261578, + "scoreConfidence" : [ + 1.7142379846009088, + 1.7431035345314319 + ], + "scorePercentiles" : { + "0.0" : 1.726194463728229, + "50.0" : 1.7285915896476376, + "90.0" : 1.7313053952411779, + "95.0" : 1.7313053952411779, + "99.0" : 1.7313053952411779, + "99.9" : 1.7313053952411779, + "99.99" : 1.7313053952411779, + "99.999" : 1.7313053952411779, + "99.9999" : 1.7313053952411779, + "100.0" : 1.7313053952411779 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7276221767696878, + 1.7313053952411779 + ], + [ + 1.726194463728229, + 1.7295610025255874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8700555481313456, + "scoreError" : 0.005840168981869053, + "scoreConfidence" : [ + 0.8642153791494765, + 0.8758957171132146 + ], + "scorePercentiles" : { + "0.0" : 0.8693974925550426, + "50.0" : 0.869748144757817, + "90.0" : 0.8713284104547055, + "95.0" : 0.8713284104547055, + "99.0" : 0.8713284104547055, + "99.9" : 0.8713284104547055, + "99.99" : 0.8713284104547055, + "99.999" : 0.8713284104547055, + "99.9999" : 0.8713284104547055, + "100.0" : 0.8713284104547055 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.869425495170068, + 0.8700707943455662 + ], + [ + 0.8693974925550426, + 0.8713284104547055 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.80751344197212, + "scoreError" : 2.3026391744093355, + "scoreConfidence" : [ + 42.50487426756278, + 47.110152616381455 + ], + "scorePercentiles" : { + "0.0" : 43.41381117714613, + "50.0" : 44.272183388727214, + "90.0" : 46.594979535399496, + "95.0" : 46.594979535399496, + "99.0" : 46.594979535399496, + "99.9" : 46.594979535399496, + "99.99" : 46.594979535399496, + "99.999" : 46.594979535399496, + "99.9999" : 46.594979535399496, + "100.0" : 46.594979535399496 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 46.56945500132572, + 46.59220457904513, + 46.594979535399496 + ], + [ + 44.28270501315412, + 44.269073877323024, + 44.272183388727214 + ], + [ + 43.41381117714613, + 43.63753652329247, + 43.63567188233574 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022354977816848462, + "scoreError" : 0.0014391345634307308, + "scoreConfidence" : [ + 0.02091584325341773, + 0.023794112380279193 + ], + "scorePercentiles" : { + "0.0" : 0.02147898639699571, + "50.0" : 0.02210505130905077, + "90.0" : 0.023454101953161593, + "95.0" : 0.023454101953161593, + "99.0" : 0.023454101953161593, + "99.9" : 0.023454101953161593, + "99.99" : 0.023454101953161593, + "99.999" : 0.023454101953161593, + "99.9999" : 0.023454101953161593, + "100.0" : 0.023454101953161593 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02210505130905077, + 0.022098411260485652, + 0.02210520964679912 + ], + [ + 0.023454101953161593, + 0.023442564526932084, + 0.023437853107728338 + ], + [ + 0.0215884915625, + 0.021484130587982833, + 0.02147898639699571 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-21T21:47:01Z-1c9edf8ee7db8c7ba6142637799b0bb3b9d97540-jdk17.json b/performance-results/2025-01-21T21:47:01Z-1c9edf8ee7db8c7ba6142637799b0bb3b9d97540-jdk17.json new file mode 100644 index 0000000000..2eb0a8679e --- /dev/null +++ b/performance-results/2025-01-21T21:47:01Z-1c9edf8ee7db8c7ba6142637799b0bb3b9d97540-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.424149683933229, + "scoreError" : 0.006012078052582705, + "scoreConfidence" : [ + 3.4181376058806463, + 3.430161761985812 + ], + "scorePercentiles" : { + "0.0" : 3.422989050483065, + "50.0" : 3.4242682261724955, + "90.0" : 3.4250732329048588, + "95.0" : 3.4250732329048588, + "99.0" : 3.4250732329048588, + "99.9" : 3.4250732329048588, + "99.99" : 3.4250732329048588, + "99.999" : 3.4250732329048588, + "99.9999" : 3.4250732329048588, + "100.0" : 3.4250732329048588 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4238388779551903, + 3.4250732329048588 + ], + [ + 3.424697574389801, + 3.422989050483065 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.72855038217974, + "scoreError" : 0.01730574953804975, + "scoreConfidence" : [ + 1.7112446326416904, + 1.7458561317177899 + ], + "scorePercentiles" : { + "0.0" : 1.7255286788866957, + "50.0" : 1.7285983884604545, + "90.0" : 1.7314760729113563, + "95.0" : 1.7314760729113563, + "99.0" : 1.7314760729113563, + "99.9" : 1.7314760729113563, + "99.99" : 1.7314760729113563, + "99.999" : 1.7314760729113563, + "99.9999" : 1.7314760729113563, + "100.0" : 1.7314760729113563 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7255286788866957, + 1.729980675302766 + ], + [ + 1.727216101618143, + 1.7314760729113563 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8693640578908688, + "scoreError" : 0.0038641087706285395, + "scoreConfidence" : [ + 0.8654999491202402, + 0.8732281666614974 + ], + "scorePercentiles" : { + "0.0" : 0.868835145795416, + "50.0" : 0.8692360046799832, + "90.0" : 0.8701490764080931, + "95.0" : 0.8701490764080931, + "99.0" : 0.8701490764080931, + "99.9" : 0.8701490764080931, + "99.99" : 0.8701490764080931, + "99.999" : 0.8701490764080931, + "99.9999" : 0.8701490764080931, + "100.0" : 0.8701490764080931 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.868835145795416, + 0.8701490764080931 + ], + [ + 0.8695042632942258, + 0.8689677460657406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 41.223752010392595, + "scoreError" : 3.8144464636708864, + "scoreConfidence" : [ + 37.40930554672171, + 45.03819847406348 + ], + "scorePercentiles" : { + "0.0" : 38.2336896832272, + "50.0" : 40.18837813592528, + "90.0" : 44.30468594681641, + "95.0" : 44.30468594681641, + "99.0" : 44.30468594681641, + "99.9" : 44.30468594681641, + "99.99" : 44.30468594681641, + "99.999" : 44.30468594681641, + "99.9999" : 44.30468594681641, + "100.0" : 44.30468594681641 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 38.2336896832272, + 39.53191823714816, + 40.70619870358236 + ], + [ + 44.30468594681641, + 44.16707605948855, + 43.861664961843516 + ], + [ + 39.91624959318406, + 40.18837813592528, + 40.10390677231785 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.023235785904743733, + "scoreError" : 7.768693990131797E-4, + "scoreConfidence" : [ + 0.022458916505730554, + 0.024012655303756913 + ], + "scorePercentiles" : { + "0.0" : 0.022705058088435374, + "50.0" : 0.023171598224537036, + "90.0" : 0.024077781197115386, + "95.0" : 0.024077781197115386, + "99.0" : 0.024077781197115386, + "99.9" : 0.024077781197115386, + "99.99" : 0.024077781197115386, + "99.999" : 0.024077781197115386, + "99.9999" : 0.024077781197115386, + "100.0" : 0.024077781197115386 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.024077781197115386, + 0.023737192085308056, + 0.023171598224537036 + ], + [ + 0.02332228789044289, + 0.023445212770491802, + 0.02302199960229885 + ], + [ + 0.022924428318077804, + 0.022705058088435374, + 0.022716514965986395 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-22T03:36:34Z-e4d3a7176e2072ff6894cde18b4cf6229364bb47-jdk17.json b/performance-results/2025-01-22T03:36:34Z-e4d3a7176e2072ff6894cde18b4cf6229364bb47-jdk17.json new file mode 100644 index 0000000000..926032db22 --- /dev/null +++ b/performance-results/2025-01-22T03:36:34Z-e4d3a7176e2072ff6894cde18b4cf6229364bb47-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4237503712681403, + "scoreError" : 0.029687066333119228, + "scoreConfidence" : [ + 3.3940633049350213, + 3.4534374376012593 + ], + "scorePercentiles" : { + "0.0" : 3.419633132532349, + "50.0" : 3.4229857951413147, + "90.0" : 3.4293967622575843, + "95.0" : 3.4293967622575843, + "99.0" : 3.4293967622575843, + "99.9" : 3.4293967622575843, + "99.99" : 3.4293967622575843, + "99.999" : 3.4293967622575843, + "99.9999" : 3.4293967622575843, + "100.0" : 3.4293967622575843 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.419633132532349, + 3.425565998706806 + ], + [ + 3.4204055915758236, + 3.4293967622575843 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7296696232543467, + "scoreError" : 0.01459335969739169, + "scoreConfidence" : [ + 1.715076263556955, + 1.7442629829517384 + ], + "scorePercentiles" : { + "0.0" : 1.7270073570666922, + "50.0" : 1.729745390562144, + "90.0" : 1.732180354826406, + "95.0" : 1.732180354826406, + "99.0" : 1.732180354826406, + "99.9" : 1.732180354826406, + "99.99" : 1.732180354826406, + "99.999" : 1.732180354826406, + "99.9999" : 1.732180354826406, + "100.0" : 1.732180354826406 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7287713875849016, + 1.732180354826406 + ], + [ + 1.7270073570666922, + 1.7307193935393865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8696333686305204, + "scoreError" : 0.005541304741506886, + "scoreConfidence" : [ + 0.8640920638890135, + 0.8751746733720274 + ], + "scorePercentiles" : { + "0.0" : 0.8688071395118665, + "50.0" : 0.8696504293139969, + "90.0" : 0.8704254763822215, + "95.0" : 0.8704254763822215, + "99.0" : 0.8704254763822215, + "99.9" : 0.8704254763822215, + "99.99" : 0.8704254763822215, + "99.999" : 0.8704254763822215, + "99.9999" : 0.8704254763822215, + "100.0" : 0.8704254763822215 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8704254763822215, + 0.870319520460667 + ], + [ + 0.8688071395118665, + 0.8689813381673269 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.36501878810898, + "scoreError" : 1.0694255389554572, + "scoreConfidence" : [ + 43.29559324915353, + 45.43444432706444 + ], + "scorePercentiles" : { + "0.0" : 43.87862862432957, + "50.0" : 43.94274487526744, + "90.0" : 45.26941974191114, + "95.0" : 45.26941974191114, + "99.0" : 45.26941974191114, + "99.9" : 45.26941974191114, + "99.99" : 45.26941974191114, + "99.999" : 45.26941974191114, + "99.9999" : 45.26941974191114, + "100.0" : 45.26941974191114 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 43.89429547541287, + 43.94274487526744, + 43.92535377650392 + ], + [ + 45.175535730731454, + 45.175776703355886, + 45.26941974191114 + ], + [ + 44.1308230548884, + 43.87862862432957, + 43.892591110580156 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022229747564292305, + "scoreError" : 8.487147291876869E-4, + "scoreConfidence" : [ + 0.02138103283510462, + 0.02307846229347999 + ], + "scorePercentiles" : { + "0.0" : 0.021779635182608694, + "50.0" : 0.02198335262857143, + "90.0" : 0.022899222466819222, + "95.0" : 0.022899222466819222, + "99.0" : 0.022899222466819222, + "99.9" : 0.022899222466819222, + "99.99" : 0.022899222466819222, + "99.999" : 0.022899222466819222, + "99.9999" : 0.022899222466819222, + "100.0" : 0.022899222466819222 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.022899222466819222, + 0.022884819782608697, + 0.022899069610983983 + ], + [ + 0.021779635182608694, + 0.02181247005882353, + 0.021822282640522876 + ], + [ + 0.022003539923076923, + 0.021983335784615386, + 0.02198335262857143 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-22T23:12:51Z-b3fa90f639e0563a19b7e3fbda0da85b68aad6e9-jdk17.json b/performance-results/2025-01-22T23:12:51Z-b3fa90f639e0563a19b7e3fbda0da85b68aad6e9-jdk17.json new file mode 100644 index 0000000000..757c5e3692 --- /dev/null +++ b/performance-results/2025-01-22T23:12:51Z-b3fa90f639e0563a19b7e3fbda0da85b68aad6e9-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4105040447860073, + "scoreError" : 0.015189749299248573, + "scoreConfidence" : [ + 3.3953142954867586, + 3.425693794085256 + ], + "scorePercentiles" : { + "0.0" : 3.4073899492105153, + "50.0" : 3.4107651539923443, + "90.0" : 3.4130959219488255, + "95.0" : 3.4130959219488255, + "99.0" : 3.4130959219488255, + "99.9" : 3.4130959219488255, + "99.99" : 3.4130959219488255, + "99.999" : 3.4130959219488255, + "99.9999" : 3.4130959219488255, + "100.0" : 3.4130959219488255 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.410876097631111, + 3.4106542103535773 + ], + [ + 3.4073899492105153, + 3.4130959219488255 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.721583114673582, + "scoreError" : 0.006425157612156726, + "scoreConfidence" : [ + 1.7151579570614253, + 1.7280082722857388 + ], + "scorePercentiles" : { + "0.0" : 1.7207681098037457, + "50.0" : 1.7212982503350518, + "90.0" : 1.7229678482204793, + "95.0" : 1.7229678482204793, + "99.0" : 1.7229678482204793, + "99.9" : 1.7229678482204793, + "99.99" : 1.7229678482204793, + "99.999" : 1.7229678482204793, + "99.9999" : 1.7229678482204793, + "100.0" : 1.7229678482204793 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7216313296507169, + 1.7229678482204793 + ], + [ + 1.7207681098037457, + 1.7209651710193865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8657441060642906, + "scoreError" : 0.002785758573795765, + "scoreConfidence" : [ + 0.8629583474904948, + 0.8685298646380865 + ], + "scorePercentiles" : { + "0.0" : 0.8653771382765126, + "50.0" : 0.8656275904190045, + "90.0" : 0.8663441051426409, + "95.0" : 0.8663441051426409, + "99.0" : 0.8663441051426409, + "99.9" : 0.8663441051426409, + "99.99" : 0.8663441051426409, + "99.999" : 0.8663441051426409, + "99.9999" : 0.8663441051426409, + "100.0" : 0.8663441051426409 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8653771382765126, + 0.8654939424156864 + ], + [ + 0.8663441051426409, + 0.8657612384223224 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 41.17225098673794, + "scoreError" : 3.22722044059398, + "scoreConfidence" : [ + 37.94503054614396, + 44.399471427331925 + ], + "scorePercentiles" : { + "0.0" : 39.366693887369976, + "50.0" : 40.2648390876238, + "90.0" : 43.70997475241803, + "95.0" : 43.70997475241803, + "99.0" : 43.70997475241803, + "99.9" : 43.70997475241803, + "99.99" : 43.70997475241803, + "99.999" : 43.70997475241803, + "99.9999" : 43.70997475241803, + "100.0" : 43.70997475241803 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 43.69435426122478, + 43.70997475241803, + 43.68716268451894 + ], + [ + 40.14696818355368, + 40.364255215826645, + 40.2648390876238 + ], + [ + 39.366693887369976, + 39.60165914823881, + 39.714351659866864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02469539257718066, + "scoreError" : 8.108306476004372E-4, + "scoreConfidence" : [ + 0.023884561929580224, + 0.025506223224781098 + ], + "scorePercentiles" : { + "0.0" : 0.023942090337320573, + "50.0" : 0.024977390805486284, + "90.0" : 0.02509696658897243, + "95.0" : 0.02509696658897243, + "99.0" : 0.02509696658897243, + "99.9" : 0.02509696658897243, + "99.99" : 0.02509696658897243, + "99.999" : 0.02509696658897243, + "99.9999" : 0.02509696658897243, + "100.0" : 0.02509696658897243 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.023942090337320573, + 0.024220828239709443, + 0.024023169163069544 + ], + [ + 0.024977390805486284, + 0.024933186425373136, + 0.02502382824 + ], + [ + 0.024994583122194512, + 0.0250464902725, + 0.02509696658897243 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-23T23:55:34Z-2551254d88f6abb0cd6b9b66b53102915ec41ec2-jdk17.json b/performance-results/2025-01-23T23:55:34Z-2551254d88f6abb0cd6b9b66b53102915ec41ec2-jdk17.json new file mode 100644 index 0000000000..0bda0220f3 --- /dev/null +++ b/performance-results/2025-01-23T23:55:34Z-2551254d88f6abb0cd6b9b66b53102915ec41ec2-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4099306926639925, + "scoreError" : 0.02395335305028509, + "scoreConfidence" : [ + 3.3859773396137074, + 3.4338840457142776 + ], + "scorePercentiles" : { + "0.0" : 3.40582898025533, + "50.0" : 3.4096702375154466, + "90.0" : 3.414553315369746, + "95.0" : 3.414553315369746, + "99.0" : 3.414553315369746, + "99.9" : 3.414553315369746, + "99.99" : 3.414553315369746, + "99.999" : 3.414553315369746, + "99.9999" : 3.414553315369746, + "100.0" : 3.414553315369746 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.408467549843088, + 3.414553315369746 + ], + [ + 3.40582898025533, + 3.410872925187805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7232751528014894, + "scoreError" : 0.009671040518753964, + "scoreConfidence" : [ + 1.7136041122827355, + 1.7329461933202432 + ], + "scorePercentiles" : { + "0.0" : 1.7211199198884921, + "50.0" : 1.723842197697369, + "90.0" : 1.724296295922727, + "95.0" : 1.724296295922727, + "99.0" : 1.724296295922727, + "99.9" : 1.724296295922727, + "99.99" : 1.724296295922727, + "99.999" : 1.724296295922727, + "99.9999" : 1.724296295922727, + "100.0" : 1.724296295922727 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7211199198884921, + 1.723401385599165 + ], + [ + 1.7242830097955733, + 1.724296295922727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8670588236163693, + "scoreError" : 0.005759442186378244, + "scoreConfidence" : [ + 0.8612993814299911, + 0.8728182658027476 + ], + "scorePercentiles" : { + "0.0" : 0.8661195610548678, + "50.0" : 0.8670034186931103, + "90.0" : 0.868108896024389, + "95.0" : 0.868108896024389, + "99.0" : 0.868108896024389, + "99.9" : 0.868108896024389, + "99.99" : 0.868108896024389, + "99.999" : 0.868108896024389, + "99.9999" : 0.868108896024389, + "100.0" : 0.868108896024389 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8674462136623503, + 0.868108896024389 + ], + [ + 0.8661195610548678, + 0.8665606237238702 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 41.83462677585385, + "scoreError" : 1.920978041265327, + "scoreConfidence" : [ + 39.91364873458852, + 43.75560481711918 + ], + "scorePercentiles" : { + "0.0" : 40.19477434571843, + "50.0" : 42.437967904570684, + "90.0" : 42.93846254059917, + "95.0" : 42.93846254059917, + "99.0" : 42.93846254059917, + "99.9" : 42.93846254059917, + "99.99" : 42.93846254059917, + "99.999" : 42.93846254059917, + "99.9999" : 42.93846254059917, + "100.0" : 42.93846254059917 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.241582636916014, + 42.45421817350641, + 42.437967904570684 + ], + [ + 42.712603840570935, + 42.70835342137284, + 42.93846254059917 + ], + [ + 40.19477434571843, + 40.25337275926056, + 40.570305360169606 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.024205050051165463, + "scoreError" : 0.0013802366621486247, + "scoreConfidence" : [ + 0.02282481338901684, + 0.025585286713314087 + ], + "scorePercentiles" : { + "0.0" : 0.02336303003962704, + "50.0" : 0.023876212723150356, + "90.0" : 0.02530103744191919, + "95.0" : 0.02530103744191919, + "99.0" : 0.02530103744191919, + "99.9" : 0.02530103744191919, + "99.99" : 0.02530103744191919, + "99.999" : 0.02530103744191919, + "99.9999" : 0.02530103744191919, + "100.0" : 0.02530103744191919 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.024042493644230768, + 0.02386281233095238, + 0.023876212723150356 + ], + [ + 0.02336303003962704, + 0.02347626125117371, + 0.023449581548009368 + ], + [ + 0.02530103744191919, + 0.025278192126262627, + 0.025195829355163728 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-27T22:22:57Z-a66c24b4e98169967f6753bd6abebb1b15820fd5-jdk17.json b/performance-results/2025-01-27T22:22:57Z-a66c24b4e98169967f6753bd6abebb1b15820fd5-jdk17.json new file mode 100644 index 0000000000..4a8eef6b68 --- /dev/null +++ b/performance-results/2025-01-27T22:22:57Z-a66c24b4e98169967f6753bd6abebb1b15820fd5-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4060502209625665, + "scoreError" : 0.021580257949835764, + "scoreConfidence" : [ + 3.3844699630127306, + 3.4276304789124024 + ], + "scorePercentiles" : { + "0.0" : 3.401427352349789, + "50.0" : 3.4070054913200853, + "90.0" : 3.408762548860305, + "95.0" : 3.408762548860305, + "99.0" : 3.408762548860305, + "99.9" : 3.408762548860305, + "99.99" : 3.408762548860305, + "99.999" : 3.408762548860305, + "99.9999" : 3.408762548860305, + "100.0" : 3.408762548860305 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.401427352349789, + 3.408762548860305 + ], + [ + 3.4058002030403016, + 3.408210779599869 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7215522864016763, + "scoreError" : 0.005696764733470336, + "scoreConfidence" : [ + 1.715855521668206, + 1.7272490511351466 + ], + "scorePercentiles" : { + "0.0" : 1.7203910519779488, + "50.0" : 1.7217467656558114, + "90.0" : 1.722324562317134, + "95.0" : 1.722324562317134, + "99.0" : 1.722324562317134, + "99.9" : 1.722324562317134, + "99.99" : 1.722324562317134, + "99.999" : 1.722324562317134, + "99.9999" : 1.722324562317134, + "100.0" : 1.722324562317134 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7203910519779488, + 1.7221411217652358 + ], + [ + 1.721352409546387, + 1.722324562317134 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8646527287713972, + "scoreError" : 0.00856950365882502, + "scoreConfidence" : [ + 0.8560832251125722, + 0.8732222324302222 + ], + "scorePercentiles" : { + "0.0" : 0.8630999525475413, + "50.0" : 0.8646080545802135, + "90.0" : 0.8662948533776209, + "95.0" : 0.8662948533776209, + "99.0" : 0.8662948533776209, + "99.9" : 0.8662948533776209, + "99.99" : 0.8662948533776209, + "99.999" : 0.8662948533776209, + "99.9999" : 0.8662948533776209, + "100.0" : 0.8662948533776209 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8662948533776209, + 0.8648946418419918 + ], + [ + 0.8630999525475413, + 0.8643214673184352 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 41.571094678999174, + "scoreError" : 0.9886983334392854, + "scoreConfidence" : [ + 40.582396345559886, + 42.55979301243846 + ], + "scorePercentiles" : { + "0.0" : 40.64766694582536, + "50.0" : 41.79030375939435, + "90.0" : 42.290871079881434, + "95.0" : 42.290871079881434, + "99.0" : 42.290871079881434, + "99.9" : 42.290871079881434, + "99.99" : 42.290871079881434, + "99.999" : 42.290871079881434, + "99.9999" : 42.290871079881434, + "100.0" : 42.290871079881434 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.290871079881434, + 42.118215951762124, + 42.099304911006406 + ], + [ + 41.79030375939435, + 41.81089696054987, + 40.87654670117831 + ], + [ + 40.64766694582536, + 41.13077840122415, + 41.3752674001706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.024796778092981732, + "scoreError" : 0.0013904138007945043, + "scoreConfidence" : [ + 0.023406364292187228, + 0.026187191893776236 + ], + "scorePercentiles" : { + "0.0" : 0.023756459386255924, + "50.0" : 0.024653574322660098, + "90.0" : 0.02602229912987013, + "95.0" : 0.02602229912987013, + "99.0" : 0.02602229912987013, + "99.9" : 0.02602229912987013, + "99.99" : 0.02602229912987013, + "99.999" : 0.02602229912987013, + "99.9999" : 0.02602229912987013, + "100.0" : 0.02602229912987013 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.025637418092071613, + 0.02602229912987013, + 0.025694226674358975 + ], + [ + 0.02384663041190476, + 0.023756459386255924, + 0.02430528267961165 + ], + [ + 0.02434602874209246, + 0.024653574322660098, + 0.02490908339800995 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-27T22:43:23Z-b65ac4194c6302651a21ff3a1a78b0a99f4ba78e-jdk17.json b/performance-results/2025-01-27T22:43:23Z-b65ac4194c6302651a21ff3a1a78b0a99f4ba78e-jdk17.json new file mode 100644 index 0000000000..a3742d4745 --- /dev/null +++ b/performance-results/2025-01-27T22:43:23Z-b65ac4194c6302651a21ff3a1a78b0a99f4ba78e-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.408427127074759, + "scoreError" : 0.01925153848185639, + "scoreConfidence" : [ + 3.3891755885929022, + 3.4276786655566154 + ], + "scorePercentiles" : { + "0.0" : 3.4053449162452507, + "50.0" : 3.408406543484691, + "90.0" : 3.4115505050844046, + "95.0" : 3.4115505050844046, + "99.0" : 3.4115505050844046, + "99.9" : 3.4115505050844046, + "99.99" : 3.4115505050844046, + "99.999" : 3.4115505050844046, + "99.9999" : 3.4115505050844046, + "100.0" : 3.4115505050844046 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.406486845438764, + 3.4115505050844046 + ], + [ + 3.4053449162452507, + 3.4103262415306177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7257387687026013, + "scoreError" : 0.008473331075327967, + "scoreConfidence" : [ + 1.7172654376272734, + 1.7342120997779293 + ], + "scorePercentiles" : { + "0.0" : 1.72423397317898, + "50.0" : 1.7256529242770822, + "90.0" : 1.7274152530772604, + "95.0" : 1.7274152530772604, + "99.0" : 1.7274152530772604, + "99.9" : 1.7274152530772604, + "99.99" : 1.7274152530772604, + "99.999" : 1.7274152530772604, + "99.9999" : 1.7274152530772604, + "100.0" : 1.7274152530772604 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.72423397317898, + 1.7254679382487557 + ], + [ + 1.7274152530772604, + 1.725837910305409 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8665575040773247, + "scoreError" : 0.0029564407943501268, + "scoreConfidence" : [ + 0.8636010632829746, + 0.8695139448716748 + ], + "scorePercentiles" : { + "0.0" : 0.8661858451203391, + "50.0" : 0.8664480513236263, + "90.0" : 0.8671480685417073, + "95.0" : 0.8671480685417073, + "99.0" : 0.8671480685417073, + "99.9" : 0.8671480685417073, + "99.99" : 0.8671480685417073, + "99.999" : 0.8671480685417073, + "99.9999" : 0.8671480685417073, + "100.0" : 0.8671480685417073 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8666900187240116, + 0.8661858451203391 + ], + [ + 0.866206083923241, + 0.8671480685417073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 42.677382462593584, + "scoreError" : 1.2020700735328222, + "scoreConfidence" : [ + 41.47531238906076, + 43.87945253612641 + ], + "scorePercentiles" : { + "0.0" : 41.743276822691925, + "50.0" : 42.730073405675626, + "90.0" : 43.7290083381939, + "95.0" : 43.7290083381939, + "99.0" : 43.7290083381939, + "99.9" : 43.7290083381939, + "99.99" : 43.7290083381939, + "99.999" : 43.7290083381939, + "99.9999" : 43.7290083381939, + "100.0" : 43.7290083381939 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.865228348309664, + 43.30915071935464, + 42.23165861844071 + ], + [ + 42.730073405675626, + 43.7290083381939, + 43.44903173965612 + ], + [ + 41.924035090602636, + 42.11497908041706, + 41.743276822691925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.023553876284725203, + "scoreError" : 5.593054909302037E-4, + "scoreConfidence" : [ + 0.022994570793795, + 0.024113181775655405 + ], + "scorePercentiles" : { + "0.0" : 0.022851900970319635, + "50.0" : 0.02365095373995272, + "90.0" : 0.02389461776849642, + "95.0" : 0.02389461776849642, + "99.0" : 0.02389461776849642, + "99.9" : 0.02389461776849642, + "99.99" : 0.02389461776849642, + "99.999" : 0.02389461776849642, + "99.9999" : 0.02389461776849642, + "100.0" : 0.02389461776849642 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02344361818032787, + 0.023304230553488372, + 0.022851900970319635 + ], + [ + 0.023773622921615202, + 0.02389461776849642, + 0.02389178353699284 + ], + [ + 0.023707024319905214, + 0.02365095373995272, + 0.02346713457142857 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-01-28T23:02:55Z-ece8f57e9b04eb1d14a3555192bb626d8315bc71-jdk17.json b/performance-results/2025-01-28T23:02:55Z-ece8f57e9b04eb1d14a3555192bb626d8315bc71-jdk17.json new file mode 100644 index 0000000000..5ef4290df1 --- /dev/null +++ b/performance-results/2025-01-28T23:02:55Z-ece8f57e9b04eb1d14a3555192bb626d8315bc71-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.421774272094884, + "scoreError" : 0.02565110456140225, + "scoreConfidence" : [ + 3.396123167533482, + 3.447425376656286 + ], + "scorePercentiles" : { + "0.0" : 3.417929940473629, + "50.0" : 3.4209231454561904, + "90.0" : 3.427320856993527, + "95.0" : 3.427320856993527, + "99.0" : 3.427320856993527, + "99.9" : 3.427320856993527, + "99.99" : 3.427320856993527, + "99.999" : 3.427320856993527, + "99.9999" : 3.427320856993527, + "100.0" : 3.427320856993527 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.417929940473629, + 3.420549417579972 + ], + [ + 3.421296873332408, + 3.427320856993527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.72756042853176, + "scoreError" : 0.012153093372248453, + "scoreConfidence" : [ + 1.7154073351595116, + 1.7397135219040085 + ], + "scorePercentiles" : { + "0.0" : 1.7249582673227821, + "50.0" : 1.7279662835519356, + "90.0" : 1.7293508797003863, + "95.0" : 1.7293508797003863, + "99.0" : 1.7293508797003863, + "99.9" : 1.7293508797003863, + "99.99" : 1.7293508797003863, + "99.999" : 1.7293508797003863, + "99.9999" : 1.7293508797003863, + "100.0" : 1.7293508797003863 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7249582673227821, + 1.7283566391748764 + ], + [ + 1.727575927928995, + 1.7293508797003863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8700223920340285, + "scoreError" : 0.010218700290680633, + "scoreConfidence" : [ + 0.8598036917433479, + 0.8802410923247092 + ], + "scorePercentiles" : { + "0.0" : 0.8685012135337304, + "50.0" : 0.8698338176924882, + "90.0" : 0.8719207192174072, + "95.0" : 0.8719207192174072, + "99.0" : 0.8719207192174072, + "99.9" : 0.8719207192174072, + "99.99" : 0.8719207192174072, + "99.999" : 0.8719207192174072, + "99.9999" : 0.8719207192174072, + "100.0" : 0.8719207192174072 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8707036745599296, + 0.8719207192174072 + ], + [ + 0.8685012135337304, + 0.8689639608250469 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 45.339925200263075, + "scoreError" : 2.0723545765171996, + "scoreConfidence" : [ + 43.267570623745875, + 47.412279776780274 + ], + "scorePercentiles" : { + "0.0" : 43.81296578444052, + "50.0" : 45.38453023809995, + "90.0" : 46.800269388776904, + "95.0" : 46.800269388776904, + "99.0" : 46.800269388776904, + "99.9" : 46.800269388776904, + "99.99" : 46.800269388776904, + "99.999" : 46.800269388776904, + "99.9999" : 46.800269388776904, + "100.0" : 46.800269388776904 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 46.800269388776904, + 46.71346073074192, + 46.75431722626851 + ], + [ + 45.38453023809995, + 45.42450404274816, + 45.24527092665326 + ], + [ + 43.81296578444052, + 43.96259264756082, + 43.96141581707756 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022398155993954644, + "scoreError" : 6.89912700021175E-4, + "scoreConfidence" : [ + 0.02170824329393347, + 0.023088068693975818 + ], + "scorePercentiles" : { + "0.0" : 0.021928783170678336, + "50.0" : 0.02232751393080357, + "90.0" : 0.022923588995423343, + "95.0" : 0.022923588995423343, + "99.0" : 0.022923588995423343, + "99.9" : 0.022923588995423343, + "99.99" : 0.022923588995423343, + "99.999" : 0.022923588995423343, + "99.9999" : 0.022923588995423343, + "100.0" : 0.022923588995423343 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02240651148769575, + 0.02232751393080357, + 0.022318053033407573 + ], + [ + 0.022923588995423343, + 0.02292196304347826, + 0.022829846011389522 + ], + [ + 0.021928783170678336, + 0.02199617635824176, + 0.021930967914473683 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-02T22:32:54Z-559cbaccc777fd7e229f8071a8701412191d3867-jdk17.json b/performance-results/2025-02-02T22:32:54Z-559cbaccc777fd7e229f8071a8701412191d3867-jdk17.json new file mode 100644 index 0000000000..f13fb309be --- /dev/null +++ b/performance-results/2025-02-02T22:32:54Z-559cbaccc777fd7e229f8071a8701412191d3867-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.422004543886982, + "scoreError" : 0.037274354718148585, + "scoreConfidence" : [ + 3.3847301891688333, + 3.4592788986051306 + ], + "scorePercentiles" : { + "0.0" : 3.4150603098850625, + "50.0" : 3.4222557397499918, + "90.0" : 3.428446386162883, + "95.0" : 3.428446386162883, + "99.0" : 3.428446386162883, + "99.9" : 3.428446386162883, + "99.99" : 3.428446386162883, + "99.999" : 3.428446386162883, + "99.9999" : 3.428446386162883, + "100.0" : 3.428446386162883 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.424488689195108, + 3.428446386162883 + ], + [ + 3.4150603098850625, + 3.4200227903048757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7266312356699343, + "scoreError" : 0.01275265278475576, + "scoreConfidence" : [ + 1.7138785828851786, + 1.73938388845469 + ], + "scorePercentiles" : { + "0.0" : 1.7253973345774025, + "50.0" : 1.7257740764391891, + "90.0" : 1.7295794552239565, + "95.0" : 1.7295794552239565, + "99.0" : 1.7295794552239565, + "99.9" : 1.7295794552239565, + "99.99" : 1.7295794552239565, + "99.999" : 1.7295794552239565, + "99.9999" : 1.7295794552239565, + "100.0" : 1.7295794552239565 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.725774269697518, + 1.7295794552239565 + ], + [ + 1.7253973345774025, + 1.7257738831808604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8685221843173088, + "scoreError" : 0.0028393507308871763, + "scoreConfidence" : [ + 0.8656828335864216, + 0.8713615350481959 + ], + "scorePercentiles" : { + "0.0" : 0.8679815361027219, + "50.0" : 0.8685252892748702, + "90.0" : 0.8690566226167731, + "95.0" : 0.8690566226167731, + "99.0" : 0.8690566226167731, + "99.9" : 0.8690566226167731, + "99.99" : 0.8690566226167731, + "99.999" : 0.8690566226167731, + "99.9999" : 0.8690566226167731, + "100.0" : 0.8690566226167731 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8685503260697689, + 0.8690566226167731 + ], + [ + 0.8679815361027219, + 0.8685002524799714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 45.15939026975822, + "scoreError" : 3.2726275519079855, + "scoreConfidence" : [ + 41.88676271785023, + 48.43201782166621 + ], + "scorePercentiles" : { + "0.0" : 43.32162148701893, + "50.0" : 44.476019988835475, + "90.0" : 47.73912870583933, + "95.0" : 47.73912870583933, + "99.0" : 47.73912870583933, + "99.9" : 47.73912870583933, + "99.99" : 47.73912870583933, + "99.999" : 47.73912870583933, + "99.9999" : 47.73912870583933, + "100.0" : 47.73912870583933 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 47.73912870583933, + 47.64792793812885, + 47.641556164042235 + ], + [ + 44.3975721232082, + 44.48295546595411, + 44.476019988835475 + ], + [ + 43.328343957387034, + 43.32162148701893, + 43.39938659740977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02224196911386321, + "scoreError" : 5.718797688838376E-4, + "scoreConfidence" : [ + 0.021670089344979375, + 0.022813848882747047 + ], + "scorePercentiles" : { + "0.0" : 0.022001641415384614, + "50.0" : 0.022020313514285714, + "90.0" : 0.022701417299319727, + "95.0" : 0.022701417299319727, + "99.0" : 0.022701417299319727, + "99.9" : 0.022701417299319727, + "99.99" : 0.022701417299319727, + "99.999" : 0.022701417299319727, + "99.9999" : 0.022701417299319727, + "100.0" : 0.022701417299319727 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.022018342547252746, + 0.022017725931868133, + 0.02202387962197802 + ], + [ + 0.022001641415384614, + 0.022008949474725276, + 0.022020313514285714 + ], + [ + 0.022696075142857142, + 0.022689377077097506, + 0.022701417299319727 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-03T23:19:46Z-ee7382895dde50d5e203c473aaedbf2a8b1796a5-jdk17.json b/performance-results/2025-02-03T23:19:46Z-ee7382895dde50d5e203c473aaedbf2a8b1796a5-jdk17.json new file mode 100644 index 0000000000..1d6ace2390 --- /dev/null +++ b/performance-results/2025-02-03T23:19:46Z-ee7382895dde50d5e203c473aaedbf2a8b1796a5-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4002502019051217, + "scoreError" : 0.03940721118245434, + "scoreConfidence" : [ + 3.3608429907226673, + 3.439657413087576 + ], + "scorePercentiles" : { + "0.0" : 3.393090154110096, + "50.0" : 3.4002891548424987, + "90.0" : 3.4073323438253937, + "95.0" : 3.4073323438253937, + "99.0" : 3.4073323438253937, + "99.9" : 3.4073323438253937, + "99.99" : 3.4073323438253937, + "99.999" : 3.4073323438253937, + "99.9999" : 3.4073323438253937, + "100.0" : 3.4073323438253937 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.398037257321173, + 3.4073323438253937 + ], + [ + 3.393090154110096, + 3.402541052363824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7210546490132013, + "scoreError" : 0.012387317274444386, + "scoreConfidence" : [ + 1.7086673317387568, + 1.7334419662876457 + ], + "scorePercentiles" : { + "0.0" : 1.718746930977431, + "50.0" : 1.7210793200388954, + "90.0" : 1.7233130249975834, + "95.0" : 1.7233130249975834, + "99.0" : 1.7233130249975834, + "99.9" : 1.7233130249975834, + "99.99" : 1.7233130249975834, + "99.999" : 1.7233130249975834, + "99.9999" : 1.7233130249975834, + "100.0" : 1.7233130249975834 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7205329400600824, + 1.7233130249975834 + ], + [ + 1.718746930977431, + 1.7216257000177082 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.864706321488554, + "scoreError" : 0.0030292477814532876, + "scoreConfidence" : [ + 0.8616770737071007, + 0.8677355692700073 + ], + "scorePercentiles" : { + "0.0" : 0.8640312899876621, + "50.0" : 0.8648396757094557, + "90.0" : 0.865114644547642, + "95.0" : 0.865114644547642, + "99.0" : 0.865114644547642, + "99.9" : 0.865114644547642, + "99.99" : 0.865114644547642, + "99.999" : 0.865114644547642, + "99.9999" : 0.865114644547642, + "100.0" : 0.865114644547642 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8648141750571403, + 0.8648651763617712 + ], + [ + 0.8640312899876621, + 0.865114644547642 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 40.49237253367603, + "scoreError" : 1.4784498919336293, + "scoreConfidence" : [ + 39.013922641742404, + 41.97082242560966 + ], + "scorePercentiles" : { + "0.0" : 39.21798489494184, + "50.0" : 40.632274190391094, + "90.0" : 41.860872454143184, + "95.0" : 41.860872454143184, + "99.0" : 41.860872454143184, + "99.9" : 41.860872454143184, + "99.99" : 41.860872454143184, + "99.999" : 41.860872454143184, + "99.9999" : 41.860872454143184, + "100.0" : 41.860872454143184 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 40.632274190391094, + 39.21798489494184, + 40.52013138493316 + ], + [ + 41.860872454143184, + 41.10434763868566, + 41.21868290029448 + ], + [ + 40.698457638341345, + 39.81248540885506, + 39.36611629249843 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02505365998153623, + "scoreError" : 7.321224107054102E-4, + "scoreConfidence" : [ + 0.02432153757083082, + 0.02578578239224164 + ], + "scorePercentiles" : { + "0.0" : 0.024503543127139364, + "50.0" : 0.025069455263157896, + "90.0" : 0.025665329338461537, + "95.0" : 0.025665329338461537, + "99.0" : 0.025665329338461537, + "99.9" : 0.025665329338461537, + "99.99" : 0.025665329338461537, + "99.999" : 0.025665329338461537, + "99.9999" : 0.025665329338461537, + "100.0" : 0.025665329338461537 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.025069455263157896, + 0.02473229191111111, + 0.02461288542997543 + ], + [ + 0.025665329338461537, + 0.025577278539641944, + 0.025356023572151897 + ], + [ + 0.024503543127139364, + 0.024692934773399015, + 0.02527319787878788 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-04T22:18:16Z-83fb2f9750acdea86a5d42a99eacfe75343bdb6e-jdk17.json b/performance-results/2025-02-04T22:18:16Z-83fb2f9750acdea86a5d42a99eacfe75343bdb6e-jdk17.json new file mode 100644 index 0000000000..7a1d3a9afe --- /dev/null +++ b/performance-results/2025-02-04T22:18:16Z-83fb2f9750acdea86a5d42a99eacfe75343bdb6e-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.427046433766062, + "scoreError" : 0.04365548760091392, + "scoreConfidence" : [ + 3.383390946165148, + 3.470701921366976 + ], + "scorePercentiles" : { + "0.0" : 3.4187459374535316, + "50.0" : 3.4274414136872613, + "90.0" : 3.4345569702361933, + "95.0" : 3.4345569702361933, + "99.0" : 3.4345569702361933, + "99.9" : 3.4345569702361933, + "99.99" : 3.4345569702361933, + "99.999" : 3.4345569702361933, + "99.9999" : 3.4345569702361933, + "100.0" : 3.4345569702361933 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4187459374535316, + 3.425064288111735 + ], + [ + 3.429818539262788, + 3.4345569702361933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7279093977892266, + "scoreError" : 0.01145621864072765, + "scoreConfidence" : [ + 1.716453179148499, + 1.7393656164299542 + ], + "scorePercentiles" : { + "0.0" : 1.7260944011710606, + "50.0" : 1.7276465395017473, + "90.0" : 1.7302501109823514, + "95.0" : 1.7302501109823514, + "99.0" : 1.7302501109823514, + "99.9" : 1.7302501109823514, + "99.99" : 1.7302501109823514, + "99.999" : 1.7302501109823514, + "99.9999" : 1.7302501109823514, + "100.0" : 1.7302501109823514 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7271377249156863, + 1.7302501109823514 + ], + [ + 1.7260944011710606, + 1.728155354087808 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8699132212785552, + "scoreError" : 0.003846909616339744, + "scoreConfidence" : [ + 0.8660663116622155, + 0.8737601308948949 + ], + "scorePercentiles" : { + "0.0" : 0.8695145403196621, + "50.0" : 0.8696695386461242, + "90.0" : 0.8707992675023106, + "95.0" : 0.8707992675023106, + "99.0" : 0.8707992675023106, + "99.9" : 0.8707992675023106, + "99.99" : 0.8707992675023106, + "99.999" : 0.8707992675023106, + "99.9999" : 0.8707992675023106, + "100.0" : 0.8707992675023106 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8696838162153353, + 0.8707992675023106 + ], + [ + 0.8696552610769129, + 0.8695145403196621 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.49448131762865, + "scoreError" : 1.1498204083528643, + "scoreConfidence" : [ + 43.34466090927578, + 45.644301725981514 + ], + "scorePercentiles" : { + "0.0" : 43.9067707953283, + "50.0" : 44.18457675048271, + "90.0" : 45.430707798776275, + "95.0" : 45.430707798776275, + "99.0" : 45.430707798776275, + "99.9" : 45.430707798776275, + "99.99" : 45.430707798776275, + "99.999" : 45.430707798776275, + "99.9999" : 45.430707798776275, + "100.0" : 45.430707798776275 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.054179446201815, + 44.19728125286074, + 44.18457675048271 + ], + [ + 43.9067707953283, + 43.946569962393944, + 43.96958858794671 + ], + [ + 45.37186589053077, + 45.38879137413653, + 45.430707798776275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0223351247933896, + "scoreError" : 7.66788561808646E-4, + "scoreConfidence" : [ + 0.021568336231580953, + 0.023101913355198244 + ], + "scorePercentiles" : { + "0.0" : 0.021752088417391305, + "50.0" : 0.02243793969955157, + "90.0" : 0.022811016271070614, + "95.0" : 0.022811016271070614, + "99.0" : 0.022811016271070614, + "99.9" : 0.022811016271070614, + "99.99" : 0.022811016271070614, + "99.999" : 0.022811016271070614, + "99.9999" : 0.022811016271070614, + "100.0" : 0.022811016271070614 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.021754917986956522, + 0.021752088417391305, + 0.02177836983478261 + ], + [ + 0.02246497825560538, + 0.02243793969955157, + 0.02243549151569507 + ], + [ + 0.02279936298861048, + 0.022811016271070614, + 0.022781958170842824 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-05T03:30:40Z-43f8ace3d9fbada18046c602b0b205dc562e8aa7-jdk17.json b/performance-results/2025-02-05T03:30:40Z-43f8ace3d9fbada18046c602b0b205dc562e8aa7-jdk17.json new file mode 100644 index 0000000000..2a129ecd0c --- /dev/null +++ b/performance-results/2025-02-05T03:30:40Z-43f8ace3d9fbada18046c602b0b205dc562e8aa7-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.422693724848574, + "scoreError" : 0.034923902189520864, + "scoreConfidence" : [ + 3.387769822659053, + 3.4576176270380947 + ], + "scorePercentiles" : { + "0.0" : 3.4170249463534113, + "50.0" : 3.4220117595222, + "90.0" : 3.4297264339964837, + "95.0" : 3.4297264339964837, + "99.0" : 3.4297264339964837, + "99.9" : 3.4297264339964837, + "99.99" : 3.4297264339964837, + "99.999" : 3.4297264339964837, + "99.9999" : 3.4297264339964837, + "100.0" : 3.4297264339964837 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4236089548467903, + 3.4297264339964837 + ], + [ + 3.4170249463534113, + 3.42041456419761 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7300534439742297, + "scoreError" : 0.019032673370126152, + "scoreConfidence" : [ + 1.7110207706041036, + 1.7490861173443557 + ], + "scorePercentiles" : { + "0.0" : 1.7260690976473414, + "50.0" : 1.7304886524743175, + "90.0" : 1.733167373300942, + "95.0" : 1.733167373300942, + "99.0" : 1.733167373300942, + "99.9" : 1.733167373300942, + "99.99" : 1.733167373300942, + "99.999" : 1.733167373300942, + "99.9999" : 1.733167373300942, + "100.0" : 1.733167373300942 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7302956837792431, + 1.733167373300942 + ], + [ + 1.7260690976473414, + 1.7306816211693918 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8698987120372736, + "scoreError" : 0.00377581375645047, + "scoreConfidence" : [ + 0.8661228982808232, + 0.8736745257937241 + ], + "scorePercentiles" : { + "0.0" : 0.8690967971416474, + "50.0" : 0.8700294827105304, + "90.0" : 0.8704390855863859, + "95.0" : 0.8704390855863859, + "99.0" : 0.8704390855863859, + "99.9" : 0.8704390855863859, + "99.99" : 0.8704390855863859, + "99.999" : 0.8704390855863859, + "99.9999" : 0.8704390855863859, + "100.0" : 0.8704390855863859 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8701952932654208, + 0.8704390855863859 + ], + [ + 0.8690967971416474, + 0.8698636721556401 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.43585541369755, + "scoreError" : 2.21713038130226, + "scoreConfidence" : [ + 42.21872503239529, + 46.652985794999815 + ], + "scorePercentiles" : { + "0.0" : 42.70591352572246, + "50.0" : 44.91351616811866, + "90.0" : 45.698943042856044, + "95.0" : 45.698943042856044, + "99.0" : 45.698943042856044, + "99.9" : 45.698943042856044, + "99.99" : 45.698943042856044, + "99.999" : 45.698943042856044, + "99.9999" : 45.698943042856044, + "100.0" : 45.698943042856044 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.70591352572246, + 42.7354668083411, + 42.75134494654927 + ], + [ + 45.62264437022108, + 45.66645088612438, + 45.698943042856044 + ], + [ + 44.89908833299122, + 44.91351616811866, + 44.92933064235384 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022318768566288623, + "scoreError" : 4.839872571792104E-4, + "scoreConfidence" : [ + 0.021834781309109413, + 0.022802755823467833 + ], + "scorePercentiles" : { + "0.0" : 0.022101342944812363, + "50.0" : 0.022146305756637168, + "90.0" : 0.02271604529478458, + "95.0" : 0.02271604529478458, + "99.0" : 0.02271604529478458, + "99.9" : 0.02271604529478458, + "99.99" : 0.02271604529478458, + "99.999" : 0.02271604529478458, + "99.9999" : 0.02271604529478458, + "100.0" : 0.02271604529478458 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02210229688741722, + 0.022101342944812363, + 0.02212873989159292 + ], + [ + 0.022697511213151927, + 0.02269267171882086, + 0.02271604529478458 + ], + [ + 0.022146305756637168, + 0.02214712675884956, + 0.022136876630530974 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-05T05:02:49Z-d370d0b15b9a50bb15b4b1a494ca29164b68edb4-jdk17.json b/performance-results/2025-02-05T05:02:49Z-d370d0b15b9a50bb15b4b1a494ca29164b68edb4-jdk17.json new file mode 100644 index 0000000000..0ab2bd6f98 --- /dev/null +++ b/performance-results/2025-02-05T05:02:49Z-d370d0b15b9a50bb15b4b1a494ca29164b68edb4-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4042371393335316, + "scoreError" : 0.0446872583155137, + "scoreConfidence" : [ + 3.359549881018018, + 3.448924397649045 + ], + "scorePercentiles" : { + "0.0" : 3.394914893117686, + "50.0" : 3.4052290542625556, + "90.0" : 3.4115755556913285, + "95.0" : 3.4115755556913285, + "99.0" : 3.4115755556913285, + "99.9" : 3.4115755556913285, + "99.99" : 3.4115755556913285, + "99.999" : 3.4115755556913285, + "99.9999" : 3.4115755556913285, + "100.0" : 3.4115755556913285 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.394914893117686, + 3.40583895732733 + ], + [ + 3.404619151197781, + 3.4115755556913285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7184579763646566, + "scoreError" : 0.017984029000478307, + "scoreConfidence" : [ + 1.7004739473641783, + 1.7364420053651348 + ], + "scorePercentiles" : { + "0.0" : 1.7150109700481377, + "50.0" : 1.7185017101631561, + "90.0" : 1.721817515084177, + "95.0" : 1.721817515084177, + "99.0" : 1.721817515084177, + "99.9" : 1.721817515084177, + "99.99" : 1.721817515084177, + "99.999" : 1.721817515084177, + "99.9999" : 1.721817515084177, + "100.0" : 1.721817515084177 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7183229689238861, + 1.721817515084177 + ], + [ + 1.7150109700481377, + 1.718680451402426 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8644166678618949, + "scoreError" : 0.014273824793039343, + "scoreConfidence" : [ + 0.8501428430688556, + 0.8786904926549342 + ], + "scorePercentiles" : { + "0.0" : 0.8625013881061403, + "50.0" : 0.8640499230080323, + "90.0" : 0.8670654373253741, + "95.0" : 0.8670654373253741, + "99.0" : 0.8670654373253741, + "99.9" : 0.8670654373253741, + "99.99" : 0.8670654373253741, + "99.999" : 0.8670654373253741, + "99.9999" : 0.8670654373253741, + "100.0" : 0.8670654373253741 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8654071827075736, + 0.8670654373253741 + ], + [ + 0.8625013881061403, + 0.8626926633084911 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 40.107849203374485, + "scoreError" : 1.8613429979991036, + "scoreConfidence" : [ + 38.24650620537538, + 41.96919220137359 + ], + "scorePercentiles" : { + "0.0" : 38.957375193089185, + "50.0" : 39.87978038106594, + "90.0" : 42.106739336781644, + "95.0" : 42.106739336781644, + "99.0" : 42.106739336781644, + "99.9" : 42.106739336781644, + "99.99" : 42.106739336781644, + "99.999" : 42.106739336781644, + "99.9999" : 42.106739336781644, + "100.0" : 42.106739336781644 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 41.32311514586201, + 39.22873722502622, + 39.40093047378082 + ], + [ + 40.22868330630514, + 42.106739336781644, + 40.820245253788244 + ], + [ + 39.02503651467119, + 38.957375193089185, + 39.87978038106594 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02515763671701217, + "scoreError" : 4.5515478538928604E-4, + "scoreConfidence" : [ + 0.02470248193162288, + 0.025612791502401457 + ], + "scorePercentiles" : { + "0.0" : 0.024772995148514852, + "50.0" : 0.025168438949748743, + "90.0" : 0.02553268769132653, + "95.0" : 0.02553268769132653, + "99.0" : 0.02553268769132653, + "99.9" : 0.02553268769132653, + "99.99" : 0.02553268769132653, + "99.999" : 0.02553268769132653, + "99.9999" : 0.02553268769132653, + "100.0" : 0.02553268769132653 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.024772995148514852, + 0.024887766286069653, + 0.024896308708955223 + ], + [ + 0.02533403954177215, + 0.025328802524050634, + 0.025448840152671754 + ], + [ + 0.02504885145, + 0.025168438949748743, + 0.02553268769132653 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-06T03:25:19Z-b0546d74a3a1974caed0d87930b8867bdd487762-jdk17.json b/performance-results/2025-02-06T03:25:19Z-b0546d74a3a1974caed0d87930b8867bdd487762-jdk17.json new file mode 100644 index 0000000000..8d80b209f6 --- /dev/null +++ b/performance-results/2025-02-06T03:25:19Z-b0546d74a3a1974caed0d87930b8867bdd487762-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.402866252226364, + "scoreError" : 0.0421848378937494, + "scoreConfidence" : [ + 3.360681414332615, + 3.4450510901201135 + ], + "scorePercentiles" : { + "0.0" : 3.397928831896492, + "50.0" : 3.400671059467336, + "90.0" : 3.412194058074291, + "95.0" : 3.412194058074291, + "99.0" : 3.412194058074291, + "99.9" : 3.412194058074291, + "99.99" : 3.412194058074291, + "99.999" : 3.412194058074291, + "99.9999" : 3.412194058074291, + "100.0" : 3.412194058074291 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.397928831896492, + 3.402518546600235 + ], + [ + 3.3988235723344373, + 3.412194058074291 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.718488887939728, + "scoreError" : 0.01413215419536935, + "scoreConfidence" : [ + 1.7043567337443586, + 1.7326210421350974 + ], + "scorePercentiles" : { + "0.0" : 1.7167794743050087, + "50.0" : 1.717892436788207, + "90.0" : 1.7213912038774897, + "95.0" : 1.7213912038774897, + "99.0" : 1.7213912038774897, + "99.9" : 1.7213912038774897, + "99.99" : 1.7213912038774897, + "99.999" : 1.7213912038774897, + "99.9999" : 1.7213912038774897, + "100.0" : 1.7213912038774897 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7168220567730959, + 1.718962816803318 + ], + [ + 1.7167794743050087, + 1.7213912038774897 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8647181507551523, + "scoreError" : 0.007284417772818592, + "scoreConfidence" : [ + 0.8574337329823337, + 0.872002568527971 + ], + "scorePercentiles" : { + "0.0" : 0.8635274440152577, + "50.0" : 0.8646774530881736, + "90.0" : 0.8659902528290045, + "95.0" : 0.8659902528290045, + "99.0" : 0.8659902528290045, + "99.9" : 0.8659902528290045, + "99.99" : 0.8659902528290045, + "99.999" : 0.8659902528290045, + "99.9999" : 0.8659902528290045, + "100.0" : 0.8659902528290045 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8635274440152577, + 0.8640558078024131 + ], + [ + 0.8652990983739342, + 0.8659902528290045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 39.40515730294485, + "scoreError" : 1.4215726826153885, + "scoreConfidence" : [ + 37.98358462032946, + 40.82672998556024 + ], + "scorePercentiles" : { + "0.0" : 37.93581376773447, + "50.0" : 39.27752387686973, + "90.0" : 40.343217369362335, + "95.0" : 40.343217369362335, + "99.0" : 40.343217369362335, + "99.9" : 40.343217369362335, + "99.99" : 40.343217369362335, + "99.999" : 40.343217369362335, + "99.9999" : 40.343217369362335, + "100.0" : 40.343217369362335 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 40.06384938710178, + 40.17442301384987, + 40.259929376837086 + ], + [ + 39.27752387686973, + 38.714228572397936, + 37.93581376773447 + ], + [ + 40.343217369362335, + 38.96220507920764, + 38.91522528314284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02554874198958805, + "scoreError" : 0.0017688172917319394, + "scoreConfidence" : [ + 0.02377992469785611, + 0.02731755928131999 + ], + "scorePercentiles" : { + "0.0" : 0.024039496365384615, + "50.0" : 0.02525976276010101, + "90.0" : 0.027049900545945946, + "95.0" : 0.027049900545945946, + "99.0" : 0.027049900545945946, + "99.9" : 0.027049900545945946, + "99.99" : 0.027049900545945946, + "99.999" : 0.027049900545945946, + "99.9999" : 0.027049900545945946, + "100.0" : 0.027049900545945946 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.026940275467741935, + 0.02652689669230769, + 0.027049900545945946 + ], + [ + 0.025087918175438595, + 0.02502862981, + 0.024039496365384615 + ], + [ + 0.024630795724815725, + 0.02525976276010101, + 0.02537500236455696 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-06T03:54:13Z-3710e685f7643d3ed541078fb3be9ca7c4b3ffaa-jdk17.json b/performance-results/2025-02-06T03:54:13Z-3710e685f7643d3ed541078fb3be9ca7c4b3ffaa-jdk17.json new file mode 100644 index 0000000000..fab923472c --- /dev/null +++ b/performance-results/2025-02-06T03:54:13Z-3710e685f7643d3ed541078fb3be9ca7c4b3ffaa-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.40840468928762, + "scoreError" : 0.03172758838290947, + "scoreConfidence" : [ + 3.3766771009047103, + 3.4401322776705294 + ], + "scorePercentiles" : { + "0.0" : 3.401889288067258, + "50.0" : 3.4089583002614106, + "90.0" : 3.4138128685604006, + "95.0" : 3.4138128685604006, + "99.0" : 3.4138128685604006, + "99.9" : 3.4138128685604006, + "99.99" : 3.4138128685604006, + "99.999" : 3.4138128685604006, + "99.9999" : 3.4138128685604006, + "100.0" : 3.4138128685604006 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.408891511405186, + 3.4138128685604006 + ], + [ + 3.401889288067258, + 3.4090250891176357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7210007707040362, + "scoreError" : 0.017508545331382953, + "scoreConfidence" : [ + 1.7034922253726532, + 1.7385093160354192 + ], + "scorePercentiles" : { + "0.0" : 1.7180058125704887, + "50.0" : 1.721345212697952, + "90.0" : 1.7233068448497522, + "95.0" : 1.7233068448497522, + "99.0" : 1.7233068448497522, + "99.9" : 1.7233068448497522, + "99.99" : 1.7233068448497522, + "99.999" : 1.7233068448497522, + "99.9999" : 1.7233068448497522, + "100.0" : 1.7233068448497522 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7180058125704887, + 1.7194089020585175 + ], + [ + 1.7232815233373864, + 1.7233068448497522 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8643609823632786, + "scoreError" : 0.0161080169738309, + "scoreConfidence" : [ + 0.8482529653894477, + 0.8804689993371095 + ], + "scorePercentiles" : { + "0.0" : 0.8621131943188688, + "50.0" : 0.8639380343612875, + "90.0" : 0.8674546664116706, + "95.0" : 0.8674546664116706, + "99.0" : 0.8674546664116706, + "99.9" : 0.8674546664116706, + "99.99" : 0.8674546664116706, + "99.999" : 0.8674546664116706, + "99.9999" : 0.8674546664116706, + "100.0" : 0.8674546664116706 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8652908015543234, + 0.8674546664116706 + ], + [ + 0.8625852671682516, + 0.8621131943188688 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 42.13143739568395, + "scoreError" : 1.28997090052118, + "scoreConfidence" : [ + 40.84146649516277, + 43.421408296205136 + ], + "scorePercentiles" : { + "0.0" : 40.7091955299111, + "50.0" : 42.34700827507123, + "90.0" : 43.09494311870861, + "95.0" : 43.09494311870861, + "99.0" : 43.09494311870861, + "99.9" : 43.09494311870861, + "99.99" : 43.09494311870861, + "99.999" : 43.09494311870861, + "99.9999" : 43.09494311870861, + "100.0" : 43.09494311870861 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 40.7091955299111, + 41.54843086871625, + 42.4898195879411 + ], + [ + 42.34700827507123, + 43.09494311870861, + 41.772721481340994 + ], + [ + 41.69707756441562, + 43.0226619809692, + 42.5010781540815 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.023930444714706154, + "scoreError" : 8.884213123377579E-4, + "scoreConfidence" : [ + 0.023042023402368397, + 0.02481886602704391 + ], + "scorePercentiles" : { + "0.0" : 0.023008338947126436, + "50.0" : 0.024051551677884614, + "90.0" : 0.024526884235294116, + "95.0" : 0.024526884235294116, + "99.0" : 0.024526884235294116, + "99.9" : 0.024526884235294116, + "99.99" : 0.024526884235294116, + "99.999" : 0.024526884235294116, + "99.9999" : 0.024526884235294116, + "100.0" : 0.024526884235294116 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.024526884235294116, + 0.024363735328467154, + 0.023997522652278176 + ], + [ + 0.024367394362530412, + 0.024051551677884614, + 0.024217514585956418 + ], + [ + 0.023008338947126436, + 0.023298507360465116, + 0.02354255328235294 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-14T05:39:11Z-a8e00c32c112ccef5695b0427cdda006da887a37-jdk17.json b/performance-results/2025-02-14T05:39:11Z-a8e00c32c112ccef5695b0427cdda006da887a37-jdk17.json new file mode 100644 index 0000000000..5b3e1c6e47 --- /dev/null +++ b/performance-results/2025-02-14T05:39:11Z-a8e00c32c112ccef5695b0427cdda006da887a37-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.404357283980617, + "scoreError" : 0.03521914452873535, + "scoreConfidence" : [ + 3.3691381394518816, + 3.439576428509352 + ], + "scorePercentiles" : { + "0.0" : 3.3966817360964723, + "50.0" : 3.40558944367229, + "90.0" : 3.4095685124814152, + "95.0" : 3.4095685124814152, + "99.0" : 3.4095685124814152, + "99.9" : 3.4095685124814152, + "99.99" : 3.4095685124814152, + "99.999" : 3.4095685124814152, + "99.9999" : 3.4095685124814152, + "100.0" : 3.4095685124814152 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3966817360964723, + 3.4055314796534444 + ], + [ + 3.4056474076911356, + 3.4095685124814152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7178122106916855, + "scoreError" : 0.01023832001786633, + "scoreConfidence" : [ + 1.7075738906738192, + 1.728050530709552 + ], + "scorePercentiles" : { + "0.0" : 1.7160908939955062, + "50.0" : 1.7177309775482787, + "90.0" : 1.7196959936746783, + "95.0" : 1.7196959936746783, + "99.0" : 1.7196959936746783, + "99.9" : 1.7196959936746783, + "99.99" : 1.7196959936746783, + "99.999" : 1.7196959936746783, + "99.9999" : 1.7196959936746783, + "100.0" : 1.7196959936746783 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7170217100517866, + 1.7196959936746783 + ], + [ + 1.7160908939955062, + 1.718440245044771 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.864719378037384, + "scoreError" : 0.008385695422045172, + "scoreConfidence" : [ + 0.8563336826153388, + 0.8731050734594291 + ], + "scorePercentiles" : { + "0.0" : 0.8635028724987689, + "50.0" : 0.8645279250288825, + "90.0" : 0.8663187895930019, + "95.0" : 0.8663187895930019, + "99.0" : 0.8663187895930019, + "99.9" : 0.8663187895930019, + "99.99" : 0.8663187895930019, + "99.999" : 0.8663187895930019, + "99.9999" : 0.8663187895930019, + "100.0" : 0.8663187895930019 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8638420932589354, + 0.8663187895930019 + ], + [ + 0.8635028724987689, + 0.8652137567988297 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 38.68765878419774, + "scoreError" : 1.3595024579632389, + "scoreConfidence" : [ + 37.3281563262345, + 40.047161242160975 + ], + "scorePercentiles" : { + "0.0" : 37.6176212727424, + "50.0" : 38.91625003504807, + "90.0" : 39.96719044176991, + "95.0" : 39.96719044176991, + "99.0" : 39.96719044176991, + "99.9" : 39.96719044176991, + "99.99" : 39.96719044176991, + "99.999" : 39.96719044176991, + "99.9999" : 39.96719044176991, + "100.0" : 39.96719044176991 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 38.07023523961371, + 37.6176212727424, + 37.7109409706809 + ], + [ + 38.23620460941478, + 39.22998086295451, + 38.91625003504807 + ], + [ + 39.96719044176991, + 39.195550172304046, + 39.244955453251286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02482110118000495, + "scoreError" : 0.0012491594771989168, + "scoreConfidence" : [ + 0.023571941702806035, + 0.026070260657203866 + ], + "scorePercentiles" : { + "0.0" : 0.02395586482057416, + "50.0" : 0.0250229317475, + "90.0" : 0.025947926660621762, + "95.0" : 0.025947926660621762, + "99.0" : 0.025947926660621762, + "99.9" : 0.025947926660621762, + "99.99" : 0.025947926660621762, + "99.999" : 0.025947926660621762, + "99.9999" : 0.025947926660621762, + "100.0" : 0.025947926660621762 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02557740179539642, + 0.02512524028822055, + 0.025947926660621762 + ], + [ + 0.0250229317475, + 0.025267129606060607, + 0.024533764960784313 + ], + [ + 0.02395586482057416, + 0.023976613050239234, + 0.023983037690647482 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-15T06:20:41Z-2d740aad4b4e7264bdddbdfad1d38923544700db-jdk17.json b/performance-results/2025-02-15T06:20:41Z-2d740aad4b4e7264bdddbdfad1d38923544700db-jdk17.json new file mode 100644 index 0000000000..6ac543c4fb --- /dev/null +++ b/performance-results/2025-02-15T06:20:41Z-2d740aad4b4e7264bdddbdfad1d38923544700db-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4170644521395346, + "scoreError" : 0.06948104475705158, + "scoreConfidence" : [ + 3.347583407382483, + 3.486545496896586 + ], + "scorePercentiles" : { + "0.0" : 3.4066504834553046, + "50.0" : 3.4162868626402703, + "90.0" : 3.4290335998222927, + "95.0" : 3.4290335998222927, + "99.0" : 3.4290335998222927, + "99.9" : 3.4290335998222927, + "99.99" : 3.4290335998222927, + "99.999" : 3.4290335998222927, + "99.9999" : 3.4290335998222927, + "100.0" : 3.4290335998222927 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.423139355195289, + 3.4290335998222927 + ], + [ + 3.4066504834553046, + 3.4094343700852514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7299781307919717, + "scoreError" : 0.007857454898446732, + "scoreConfidence" : [ + 1.722120675893525, + 1.7378355856904184 + ], + "scorePercentiles" : { + "0.0" : 1.7289438396262016, + "50.0" : 1.7297098953749621, + "90.0" : 1.7315488927917617, + "95.0" : 1.7315488927917617, + "99.0" : 1.7315488927917617, + "99.9" : 1.7315488927917617, + "99.99" : 1.7315488927917617, + "99.999" : 1.7315488927917617, + "99.9999" : 1.7315488927917617, + "100.0" : 1.7315488927917617 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7290956274732558, + 1.7303241632766684 + ], + [ + 1.7289438396262016, + 1.7315488927917617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8697467791753941, + "scoreError" : 0.0028323725711086665, + "scoreConfidence" : [ + 0.8669144066042854, + 0.8725791517465028 + ], + "scorePercentiles" : { + "0.0" : 0.8692196616762735, + "50.0" : 0.869817331270005, + "90.0" : 0.8701327924852931, + "95.0" : 0.8701327924852931, + "99.0" : 0.8701327924852931, + "99.9" : 0.8701327924852931, + "99.99" : 0.8701327924852931, + "99.999" : 0.8701327924852931, + "99.9999" : 0.8701327924852931, + "100.0" : 0.8701327924852931 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8695531911766186, + 0.8700814713633914 + ], + [ + 0.8692196616762735, + 0.8701327924852931 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 45.0549346381212, + "scoreError" : 0.848757856193997, + "scoreConfidence" : [ + 44.206176781927205, + 45.9036924943152 + ], + "scorePercentiles" : { + "0.0" : 44.68208621438223, + "50.0" : 44.738282881112745, + "90.0" : 45.76180661959652, + "95.0" : 45.76180661959652, + "99.0" : 45.76180661959652, + "99.9" : 45.76180661959652, + "99.99" : 45.76180661959652, + "99.999" : 45.76180661959652, + "99.9999" : 45.76180661959652, + "100.0" : 45.76180661959652 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.756697510251236, + 44.738282881112745, + 44.68208621438223 + ], + [ + 44.73782098292451, + 44.695078879626514, + 44.70247575123757 + ], + [ + 45.698962720374276, + 45.72120018358523, + 45.76180661959652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022437348164506113, + "scoreError" : 9.210176860938199E-4, + "scoreConfidence" : [ + 0.021516330478412293, + 0.023358365850599933 + ], + "scorePercentiles" : { + "0.0" : 0.021832881671023964, + "50.0" : 0.022377403029082775, + "90.0" : 0.02315576094675926, + "95.0" : 0.02315576094675926, + "99.0" : 0.02315576094675926, + "99.9" : 0.02315576094675926, + "99.99" : 0.02315576094675926, + "99.999" : 0.02315576094675926, + "99.9999" : 0.02315576094675926, + "100.0" : 0.02315576094675926 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.021843250683406115, + 0.021832881671023964, + 0.02184149683187773 + ], + [ + 0.022377403029082775, + 0.022397466700223714, + 0.02235870547767857 + ], + [ + 0.022976684075688075, + 0.02315576094675926, + 0.023152484064814814 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-16T03:40:11Z-fc9c1336de7ab351d6cd6a68a43e8ee6b7876fb6-jdk17.json b/performance-results/2025-02-16T03:40:11Z-fc9c1336de7ab351d6cd6a68a43e8ee6b7876fb6-jdk17.json new file mode 100644 index 0000000000..40711a4f92 --- /dev/null +++ b/performance-results/2025-02-16T03:40:11Z-fc9c1336de7ab351d6cd6a68a43e8ee6b7876fb6-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4197378188044096, + "scoreError" : 0.04262561676864909, + "scoreConfidence" : [ + 3.3771122020357605, + 3.462363435573059 + ], + "scorePercentiles" : { + "0.0" : 3.4117117828701837, + "50.0" : 3.4198156241090585, + "90.0" : 3.4276082441293374, + "95.0" : 3.4276082441293374, + "99.0" : 3.4276082441293374, + "99.9" : 3.4276082441293374, + "99.99" : 3.4276082441293374, + "99.999" : 3.4276082441293374, + "99.9999" : 3.4276082441293374, + "100.0" : 3.4276082441293374 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.418372884463662, + 3.4276082441293374 + ], + [ + 3.4117117828701837, + 3.421258363754455 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.726255760607202, + "scoreError" : 0.0069887452082228844, + "scoreConfidence" : [ + 1.719267015398979, + 1.7332445058154249 + ], + "scorePercentiles" : { + "0.0" : 1.724942047136417, + "50.0" : 1.7262524899916596, + "90.0" : 1.7275760153090716, + "95.0" : 1.7275760153090716, + "99.0" : 1.7275760153090716, + "99.9" : 1.7275760153090716, + "99.99" : 1.7275760153090716, + "99.999" : 1.7275760153090716, + "99.9999" : 1.7275760153090716, + "100.0" : 1.7275760153090716 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7261109025806118, + 1.7263940774027073 + ], + [ + 1.724942047136417, + 1.7275760153090716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8695008952141935, + "scoreError" : 0.002839649770146112, + "scoreConfidence" : [ + 0.8666612454440474, + 0.8723405449843395 + ], + "scorePercentiles" : { + "0.0" : 0.8688932944831845, + "50.0" : 0.8695867203095606, + "90.0" : 0.8699368457544682, + "95.0" : 0.8699368457544682, + "99.0" : 0.8699368457544682, + "99.9" : 0.8699368457544682, + "99.99" : 0.8699368457544682, + "99.999" : 0.8699368457544682, + "99.9999" : 0.8699368457544682, + "100.0" : 0.8699368457544682 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8688932944831845, + 0.869534969252187 + ], + [ + 0.8699368457544682, + 0.8696384713669342 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.79340737680421, + "scoreError" : 1.1283373708302868, + "scoreConfidence" : [ + 43.665070005973924, + 45.9217447476345 + ], + "scorePercentiles" : { + "0.0" : 44.22709764883389, + "50.0" : 44.37852960081133, + "90.0" : 45.72777210141981, + "95.0" : 45.72777210141981, + "99.0" : 45.72777210141981, + "99.9" : 45.72777210141981, + "99.99" : 45.72777210141981, + "99.999" : 45.72777210141981, + "99.9999" : 45.72777210141981, + "100.0" : 45.72777210141981 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.37103141816148, + 44.37808732974959, + 44.43775470829123 + ], + [ + 45.68653293043291, + 45.63986315460877, + 45.72777210141981 + ], + [ + 44.37852960081133, + 44.29399749892893, + 44.22709764883389 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02254336100574041, + "scoreError" : 0.0014251861750202459, + "scoreConfidence" : [ + 0.021118174830720163, + 0.023968547180760656 + ], + "scorePercentiles" : { + "0.0" : 0.02140835029059829, + "50.0" : 0.022582479492099322, + "90.0" : 0.023531701548235293, + "95.0" : 0.023531701548235293, + "99.0" : 0.023531701548235293, + "99.9" : 0.023531701548235293, + "99.99" : 0.023531701548235293, + "99.999" : 0.023531701548235293, + "99.9999" : 0.023531701548235293, + "100.0" : 0.023531701548235293 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.023531701548235293, + 0.02344455574941452, + 0.023488433495305164 + ], + [ + 0.021671676398268398, + 0.02140835029059829, + 0.021538914713978494 + ], + [ + 0.022566439108108106, + 0.022657698255656108, + 0.022582479492099322 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-17T20:34:06Z-1c40027a308e3a8034e8f2e168d2697e979e5c1b-jdk17.json b/performance-results/2025-02-17T20:34:06Z-1c40027a308e3a8034e8f2e168d2697e979e5c1b-jdk17.json new file mode 100644 index 0000000000..808a4a5fce --- /dev/null +++ b/performance-results/2025-02-17T20:34:06Z-1c40027a308e3a8034e8f2e168d2697e979e5c1b-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4206088887895985, + "scoreError" : 0.013042699082723508, + "scoreConfidence" : [ + 3.4075661897068747, + 3.433651587872322 + ], + "scorePercentiles" : { + "0.0" : 3.417984980421843, + "50.0" : 3.4207956154691894, + "90.0" : 3.4228593437981725, + "95.0" : 3.4228593437981725, + "99.0" : 3.4228593437981725, + "99.9" : 3.4228593437981725, + "99.99" : 3.4228593437981725, + "99.999" : 3.4228593437981725, + "99.9999" : 3.4228593437981725, + "100.0" : 3.4228593437981725 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4211136575072607, + 3.4228593437981725 + ], + [ + 3.417984980421843, + 3.420477573431118 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7290954275461694, + "scoreError" : 0.014971146867698142, + "scoreConfidence" : [ + 1.7141242806784713, + 1.7440665744138675 + ], + "scorePercentiles" : { + "0.0" : 1.7268335612289947, + "50.0" : 1.728618007948021, + "90.0" : 1.732312133059641, + "95.0" : 1.732312133059641, + "99.0" : 1.732312133059641, + "99.9" : 1.732312133059641, + "99.99" : 1.732312133059641, + "99.999" : 1.732312133059641, + "99.9999" : 1.732312133059641, + "100.0" : 1.732312133059641 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7289210060678664, + 1.732312133059641 + ], + [ + 1.7268335612289947, + 1.7283150098281757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8691296924737124, + "scoreError" : 0.003217906230387458, + "scoreConfidence" : [ + 0.865911786243325, + 0.8723475987040998 + ], + "scorePercentiles" : { + "0.0" : 0.8685411985907953, + "50.0" : 0.8691692958613317, + "90.0" : 0.8696389795813908, + "95.0" : 0.8696389795813908, + "99.0" : 0.8696389795813908, + "99.9" : 0.8696389795813908, + "99.99" : 0.8696389795813908, + "99.999" : 0.8696389795813908, + "99.9999" : 0.8696389795813908, + "100.0" : 0.8696389795813908 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8685411985907953, + 0.8694292003590817 + ], + [ + 0.8689093913635819, + 0.8696389795813908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.00002592220759, + "scoreError" : 1.0169729471967608, + "scoreConfidence" : [ + 42.98305297501083, + 45.016998869404354 + ], + "scorePercentiles" : { + "0.0" : 43.190621895015134, + "50.0" : 44.339727784246385, + "90.0" : 44.49859689249208, + "95.0" : 44.49859689249208, + "99.0" : 44.49859689249208, + "99.9" : 44.49859689249208, + "99.99" : 44.49859689249208, + "99.999" : 44.49859689249208, + "99.9999" : 44.49859689249208, + "100.0" : 44.49859689249208 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.296203523003136, + 44.3675733423135, + 44.339727784246385 + ], + [ + 44.433477192763355, + 44.47220710306538, + 44.49859689249208 + ], + [ + 43.190621895015134, + 43.195083051862106, + 43.2067425151073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022014991133773334, + "scoreError" : 7.270139507733344E-4, + "scoreConfidence" : [ + 0.021287977183, + 0.022742005084546667 + ], + "scorePercentiles" : { + "0.0" : 0.02151436482795699, + "50.0" : 0.021798280185185186, + "90.0" : 0.02263859209276018, + "95.0" : 0.02263859209276018, + "99.0" : 0.02263859209276018, + "99.9" : 0.02263859209276018, + "99.99" : 0.02263859209276018, + "99.999" : 0.02263859209276018, + "99.9999" : 0.02263859209276018, + "100.0" : 0.02263859209276018 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02176385843695652, + 0.021756122958695653, + 0.021755845339130435 + ], + [ + 0.021798280185185186, + 0.021809013647058822, + 0.02151436482795699 + ], + [ + 0.02263859209276018, + 0.022552278957207208, + 0.02254656375900901 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-17T22:24:53Z-6669c2035a983b1641544c06517726c31fba6de8-jdk17.json b/performance-results/2025-02-17T22:24:53Z-6669c2035a983b1641544c06517726c31fba6de8-jdk17.json new file mode 100644 index 0000000000..be9f5a784b --- /dev/null +++ b/performance-results/2025-02-17T22:24:53Z-6669c2035a983b1641544c06517726c31fba6de8-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4242633766606025, + "scoreError" : 0.018975601014235673, + "scoreConfidence" : [ + 3.405287775646367, + 3.443238977674838 + ], + "scorePercentiles" : { + "0.0" : 3.4212131355295408, + "50.0" : 3.423987593935866, + "90.0" : 3.427865183241137, + "95.0" : 3.427865183241137, + "99.0" : 3.427865183241137, + "99.9" : 3.427865183241137, + "99.99" : 3.427865183241137, + "99.999" : 3.427865183241137, + "99.9999" : 3.427865183241137, + "100.0" : 3.427865183241137 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4212131355295408, + 3.427865183241137 + ], + [ + 3.4226761215874024, + 3.42529906628433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7297100885344647, + "scoreError" : 0.012575602193575109, + "scoreConfidence" : [ + 1.7171344863408897, + 1.7422856907280397 + ], + "scorePercentiles" : { + "0.0" : 1.7269537146749794, + "50.0" : 1.7301797508085786, + "90.0" : 1.7315271378457233, + "95.0" : 1.7315271378457233, + "99.0" : 1.7315271378457233, + "99.9" : 1.7315271378457233, + "99.99" : 1.7315271378457233, + "99.999" : 1.7315271378457233, + "99.9999" : 1.7315271378457233, + "100.0" : 1.7315271378457233 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7269537146749794, + 1.730283069142333 + ], + [ + 1.730076432474824, + 1.7315271378457233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8694133387568189, + "scoreError" : 8.350509859162894E-4, + "scoreConfidence" : [ + 0.8685782877709026, + 0.8702483897427352 + ], + "scorePercentiles" : { + "0.0" : 0.8692902387995611, + "50.0" : 0.8693866443860734, + "90.0" : 0.8695898274555681, + "95.0" : 0.8695898274555681, + "99.0" : 0.8695898274555681, + "99.9" : 0.8695898274555681, + "99.99" : 0.8695898274555681, + "99.999" : 0.8695898274555681, + "99.9999" : 0.8695898274555681, + "100.0" : 0.8695898274555681 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8693522182862535, + 0.8692902387995611 + ], + [ + 0.8695898274555681, + 0.8694210704858931 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 44.351621241143484, + "scoreError" : 0.5953242229423784, + "scoreConfidence" : [ + 43.7562970182011, + 44.946945464085864 + ], + "scorePercentiles" : { + "0.0" : 43.77066626511391, + "50.0" : 44.366053527100796, + "90.0" : 44.87096788250905, + "95.0" : 44.87096788250905, + "99.0" : 44.87096788250905, + "99.9" : 44.87096788250905, + "99.99" : 44.87096788250905, + "99.999" : 44.87096788250905, + "99.9999" : 44.87096788250905, + "100.0" : 44.87096788250905 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.297296748606456, + 44.397303245644636, + 44.366053527100796 + ], + [ + 44.0500241243553, + 44.05602909596345, + 43.77066626511391 + ], + [ + 44.87096788250905, + 44.68165375318243, + 44.674596527815304 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.022335216267832168, + "scoreError" : 5.743756954042363E-4, + "scoreConfidence" : [ + 0.02176084057242793, + 0.022909591963236404 + ], + "scorePercentiles" : { + "0.0" : 0.022069386140969163, + "50.0" : 0.02213912410619469, + "90.0" : 0.022815809872437358, + "95.0" : 0.022815809872437358, + "99.0" : 0.022815809872437358, + "99.9" : 0.022815809872437358, + "99.99" : 0.022815809872437358, + "99.999" : 0.022815809872437358, + "99.9999" : 0.022815809872437358, + "100.0" : 0.022815809872437358 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.02210124018763797, + 0.022075338872246695, + 0.022069386140969163 + ], + [ + 0.02275205906818182, + 0.022799795460136673, + 0.022815809872437358 + ], + [ + 0.022123397386313467, + 0.02213912410619469, + 0.02214079531637168 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-18T21:00:41Z-a38c75c4e4a155ab2d88dfb1304971e61ee32aed-jdk17.json b/performance-results/2025-02-18T21:00:41Z-a38c75c4e4a155ab2d88dfb1304971e61ee32aed-jdk17.json new file mode 100644 index 0000000000..260e44a4d4 --- /dev/null +++ b/performance-results/2025-02-18T21:00:41Z-a38c75c4e4a155ab2d88dfb1304971e61ee32aed-jdk17.json @@ -0,0 +1,287 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4115822946692296, + "scoreError" : 0.02374031077593178, + "scoreConfidence" : [ + 3.387841983893298, + 3.4353226054451613 + ], + "scorePercentiles" : { + "0.0" : 3.4079551742814718, + "50.0" : 3.4109733124928603, + "90.0" : 3.4164273794097273, + "95.0" : 3.4164273794097273, + "99.0" : 3.4164273794097273, + "99.9" : 3.4164273794097273, + "99.99" : 3.4164273794097273, + "99.999" : 3.4164273794097273, + "99.9999" : 3.4164273794097273, + "100.0" : 3.4164273794097273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4097245690943745, + 3.4164273794097273 + ], + [ + 3.4079551742814718, + 3.4122220558913456 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.722694825573204, + "scoreError" : 0.009524342266229335, + "scoreConfidence" : [ + 1.7131704833069747, + 1.7322191678394332 + ], + "scorePercentiles" : { + "0.0" : 1.7205165151963069, + "50.0" : 1.7232566846012491, + "90.0" : 1.7237494178940111, + "95.0" : 1.7237494178940111, + "99.0" : 1.7237494178940111, + "99.9" : 1.7237494178940111, + "99.99" : 1.7237494178940111, + "99.999" : 1.7237494178940111, + "99.9999" : 1.7237494178940111, + "100.0" : 1.7237494178940111 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7233762538651085, + 1.7237494178940111 + ], + [ + 1.7205165151963069, + 1.7231371153373898 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.866572515884187, + "scoreError" : 0.004874669836230257, + "scoreConfidence" : [ + 0.8616978460479567, + 0.8714471857204173 + ], + "scorePercentiles" : { + "0.0" : 0.8659772491632904, + "50.0" : 0.866317387084177, + "90.0" : 0.867678040205104, + "95.0" : 0.867678040205104, + "99.0" : 0.867678040205104, + "99.9" : 0.867678040205104, + "99.99" : 0.867678040205104, + "99.999" : 0.867678040205104, + "99.9999" : 0.867678040205104, + "100.0" : 0.867678040205104 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8663020308179187, + 0.867678040205104 + ], + [ + 0.8659772491632904, + 0.8663327433504354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 43.16581893791316, + "scoreError" : 2.066948947766819, + "scoreConfidence" : [ + 41.09886999014634, + 45.232767885679976 + ], + "scorePercentiles" : { + "0.0" : 41.47630378715374, + "50.0" : 43.19324157508737, + "90.0" : 45.10306662709041, + "95.0" : 45.10306662709041, + "99.0" : 45.10306662709041, + "99.9" : 45.10306662709041, + "99.99" : 45.10306662709041, + "99.999" : 45.10306662709041, + "99.9999" : 45.10306662709041, + "100.0" : 45.10306662709041 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 41.9283125770102, + 41.47630378715374, + 42.49340373619001 + ], + [ + 43.19324157508737, + 44.967595343521324, + 45.10306662709041 + ], + [ + 42.69787652122177, + 43.33871227400222, + 43.29385799994142 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02357816374013612, + "scoreError" : 6.853628187300454E-4, + "scoreConfidence" : [ + 0.022892800921406078, + 0.024263526558866166 + ], + "scorePercentiles" : { + "0.0" : 0.02294608312614679, + "50.0" : 0.023463286145199064, + "90.0" : 0.024420310319512195, + "95.0" : 0.024420310319512195, + "99.0" : 0.024420310319512195, + "99.9" : 0.024420310319512195, + "99.99" : 0.024420310319512195, + "99.999" : 0.024420310319512195, + "99.9999" : 0.024420310319512195, + "100.0" : 0.024420310319512195 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.023463286145199064, + 0.02341394538551402, + 0.023628221283018867 + ], + [ + 0.023451077770491803, + 0.02331047241395349, + 0.02294608312614679 + ], + [ + 0.024420310319512195, + 0.02383940636904762, + 0.023730670848341233 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-23T23:27:11Z-422035b18d79a8c2da519fa224d57b54328d21af-jdk17.json b/performance-results/2025-02-23T23:27:11Z-422035b18d79a8c2da519fa224d57b54328d21af-jdk17.json new file mode 100644 index 0000000000..42469cd673 --- /dev/null +++ b/performance-results/2025-02-23T23:27:11Z-422035b18d79a8c2da519fa224d57b54328d21af-jdk17.json @@ -0,0 +1,1657 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.407056046800354, + "scoreError" : 0.029918815472154754, + "scoreConfidence" : [ + 3.3771372313281995, + 3.4369748622725087 + ], + "scorePercentiles" : { + "0.0" : 3.4007909424708345, + "50.0" : 3.4082762103332733, + "90.0" : 3.410880824064036, + "95.0" : 3.410880824064036, + "99.0" : 3.410880824064036, + "99.9" : 3.410880824064036, + "99.99" : 3.410880824064036, + "99.999" : 3.410880824064036, + "99.9999" : 3.410880824064036, + "100.0" : 3.410880824064036 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4063459499983404, + 3.4102064706682067 + ], + [ + 3.4007909424708345, + 3.410880824064036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7237261899951235, + "scoreError" : 0.012279956940872572, + "scoreConfidence" : [ + 1.711446233054251, + 1.736006146935996 + ], + "scorePercentiles" : { + "0.0" : 1.7209620297907924, + "50.0" : 1.7243493101951046, + "90.0" : 1.725244109799492, + "95.0" : 1.725244109799492, + "99.0" : 1.725244109799492, + "99.9" : 1.725244109799492, + "99.99" : 1.725244109799492, + "99.999" : 1.725244109799492, + "99.9999" : 1.725244109799492, + "100.0" : 1.725244109799492 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7209620297907924, + 1.7245866091668745 + ], + [ + 1.7241120112233348, + 1.725244109799492 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8655072619557832, + "scoreError" : 0.0076541027379537704, + "scoreConfidence" : [ + 0.8578531592178295, + 0.873161364693737 + ], + "scorePercentiles" : { + "0.0" : 0.864075538285419, + "50.0" : 0.8655494103959934, + "90.0" : 0.866854688745727, + "95.0" : 0.866854688745727, + "99.0" : 0.866854688745727, + "99.9" : 0.866854688745727, + "99.99" : 0.866854688745727, + "99.999" : 0.866854688745727, + "99.9999" : 0.866854688745727, + "100.0" : 0.866854688745727 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8659617453318614, + 0.866854688745727 + ], + [ + 0.864075538285419, + 0.8651370754601254 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 26552.524153094724, + "scoreError" : 639.1805987554905, + "scoreConfidence" : [ + 25913.343554339233, + 27191.704751850215 + ], + "scorePercentiles" : { + "0.0" : 26180.44553092005, + "50.0" : 26356.254345436864, + "90.0" : 27200.80700737948, + "95.0" : 27200.80700737948, + "99.0" : 27200.80700737948, + "99.9" : 27200.80700737948, + "99.99" : 27200.80700737948, + "99.999" : 27200.80700737948, + "99.9999" : 27200.80700737948, + "100.0" : 27200.80700737948 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 26356.254345436864, + 26236.647378597983, + 26180.44553092005 + ], + [ + 27200.80700737948, + 26956.168602989936, + 26977.190532199587 + ], + [ + 26347.091494468492, + 26352.678896785805, + 26365.433589074324 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 52218.80958985782, + "scoreError" : 2879.5912049286203, + "scoreConfidence" : [ + 49339.2183849292, + 55098.40079478644 + ], + "scorePercentiles" : { + "0.0" : 50017.97044480345, + "50.0" : 52649.465625625206, + "90.0" : 53886.84577830227, + "95.0" : 53886.84577830227, + "99.0" : 53886.84577830227, + "99.9" : 53886.84577830227, + "99.99" : 53886.84577830227, + "99.999" : 53886.84577830227, + "99.9999" : 53886.84577830227, + "100.0" : 53886.84577830227 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 50017.97044480345, + 50035.0168865673, + 50041.48226304438 + ], + [ + 53885.89643819377, + 53886.84577830227, + 53842.27665966726 + ], + [ + 52989.15061916798, + 52621.18159334877, + 52649.465625625206 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 331112.89002765866, + "scoreError" : 9506.721360091407, + "scoreConfidence" : [ + 321606.16866756725, + 340619.6113877501 + ], + "scorePercentiles" : { + "0.0" : 324464.0961357516, + "50.0" : 330664.8458155606, + "90.0" : 337893.6958372753, + "95.0" : 337893.6958372753, + "99.0" : 337893.6958372753, + "99.9" : 337893.6958372753, + "99.99" : 337893.6958372753, + "99.999" : 337893.6958372753, + "99.9999" : 337893.6958372753, + "100.0" : 337893.6958372753 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 324886.30850199796, + 325013.14257856936, + 324464.0961357516 + ], + [ + 337864.1532146356, + 337893.6958372753, + 337731.1074636947 + ], + [ + 330875.09724060347, + 330623.5634608391, + 330664.8458155606 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 11427.622258229836, + "scoreError" : 324.31758374745107, + "scoreConfidence" : [ + 11103.304674482384, + 11751.939841977288 + ], + "scorePercentiles" : { + "0.0" : 11172.28876683924, + "50.0" : 11487.803492020093, + "90.0" : 11629.032201570599, + "95.0" : 11629.032201570599, + "99.0" : 11629.032201570599, + "99.9" : 11629.032201570599, + "99.99" : 11629.032201570599, + "99.999" : 11629.032201570599, + "99.9999" : 11629.032201570599, + "100.0" : 11629.032201570599 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 11483.757824638526, + 11487.803492020093, + 11492.811145806158 + ], + [ + 11191.473096017226, + 11179.267410675857, + 11172.28876683924 + ], + [ + 11629.032201570599, + 11611.247604627724, + 11600.918781873106 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 52007.73574828912, + "scoreError" : 2747.6709117774185, + "scoreConfidence" : [ + 49260.0648365117, + 54755.40666006653 + ], + "scorePercentiles" : { + "0.0" : 49772.18481171423, + "50.0" : 53028.99369495013, + "90.0" : 53201.20417305073, + "95.0" : 53201.20417305073, + "99.0" : 53201.20417305073, + "99.9" : 53201.20417305073, + "99.99" : 53201.20417305073, + "99.999" : 53201.20417305073, + "99.9999" : 53201.20417305073, + "100.0" : 53201.20417305073 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 53163.70150610576, + 53165.25671602116, + 53201.20417305073 + ], + [ + 49891.42993843483, + 49826.70391334243, + 49772.18481171423 + ], + [ + 53028.99369495013, + 53042.75352463799, + 52977.393456344726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 519817.1073999086, + "scoreError" : 22899.539550691738, + "scoreConfidence" : [ + 496917.56784921687, + 542716.6469506003 + ], + "scorePercentiles" : { + "0.0" : 501659.81840983196, + "50.0" : 522679.67015104793, + "90.0" : 534125.0044864605, + "95.0" : 534125.0044864605, + "99.0" : 534125.0044864605, + "99.9" : 534125.0044864605, + "99.99" : 534125.0044864605, + "99.999" : 534125.0044864605, + "99.9999" : 534125.0044864605, + "100.0" : 534125.0044864605 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 523641.3408210284, + 522679.67015104793, + 522124.72834542894 + ], + [ + 502553.2957435047, + 501659.81840983196, + 504259.8995058491 + ], + [ + 533653.9709696355, + 534125.0044864605, + 533656.2381663909 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 5611.061899727954, + "scoreError" : 199.0334455523655, + "scoreConfidence" : [ + 5412.028454175589, + 5810.09534528032 + ], + "scorePercentiles" : { + "0.0" : 5471.789355523734, + "50.0" : 5604.591856510667, + "90.0" : 5748.895040773562, + "95.0" : 5748.895040773562, + "99.0" : 5748.895040773562, + "99.9" : 5748.895040773562, + "99.99" : 5748.895040773562, + "99.999" : 5748.895040773562, + "99.9999" : 5748.895040773562, + "100.0" : 5748.895040773562 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 5748.895040773562, + 5747.524777559183, + 5743.206077045362 + ], + [ + 5477.598544947824, + 5471.789355523734, + 5472.026265965817 + ], + [ + 5632.66979088397, + 5604.591856510667, + 5601.255388341467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 23867.987814775624, + "scoreError" : 1536.3352111463519, + "scoreConfidence" : [ + 22331.65260362927, + 25404.323025921978 + ], + "scorePercentiles" : { + "0.0" : 22847.395096563116, + "50.0" : 23765.784316195237, + "90.0" : 24989.494894720796, + "95.0" : 24989.494894720796, + "99.0" : 24989.494894720796, + "99.9" : 24989.494894720796, + "99.99" : 24989.494894720796, + "99.999" : 24989.494894720796, + "99.9999" : 24989.494894720796, + "100.0" : 24989.494894720796 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 22877.390001349748, + 22847.395096563116, + 22865.330788454987 + ], + [ + 24989.494894720796, + 24966.94336075499, + 24946.11605536971 + ], + [ + 23819.37460549602, + 23734.06121407601, + 23765.784316195237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 245953.21356996294, + "scoreError" : 4056.5186707154076, + "scoreConfidence" : [ + 241896.69489924752, + 250009.73224067836 + ], + "scorePercentiles" : { + "0.0" : 243425.86234512305, + "50.0" : 245794.41238785794, + "90.0" : 249309.52607698445, + "95.0" : 249309.52607698445, + "99.0" : 249309.52607698445, + "99.9" : 249309.52607698445, + "99.99" : 249309.52607698445, + "99.999" : 249309.52607698445, + "99.9999" : 249309.52607698445, + "100.0" : 249309.52607698445 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 243425.86234512305, + 243637.14963699263, + 243514.4556080456 + ], + [ + 248570.7896895429, + 248742.11399646793, + 249309.52607698445 + ], + [ + 244261.41762536333, + 245794.41238785794, + 246323.19476328883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 23528.336167796446, + "scoreError" : 750.0966191948582, + "scoreConfidence" : [ + 22778.23954860159, + 24278.432786991303 + ], + "scorePercentiles" : { + "0.0" : 23042.671609256584, + "50.0" : 23441.3835416066, + "90.0" : 24124.690474984258, + "95.0" : 24124.690474984258, + "99.0" : 24124.690474984258, + "99.9" : 24124.690474984258, + "99.99" : 24124.690474984258, + "99.999" : 24124.690474984258, + "99.9999" : 24124.690474984258, + "100.0" : 24124.690474984258 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 23042.671609256584, + 23071.787075831264, + 23068.08098868525 + ], + [ + 24124.690474984258, + 24087.042072327695, + 24027.066119336283 + ], + [ + 23435.216268469587, + 23457.08735967048, + 23441.3835416066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 100895.67719469467, + "scoreError" : 5842.513427615709, + "scoreConfidence" : [ + 95053.16376707896, + 106738.19062231037 + ], + "scorePercentiles" : { + "0.0" : 96850.12681348907, + "50.0" : 100614.00032196075, + "90.0" : 105156.68496708658, + "95.0" : 105156.68496708658, + "99.0" : 105156.68496708658, + "99.9" : 105156.68496708658, + "99.99" : 105156.68496708658, + "99.999" : 105156.68496708658, + "99.9999" : 105156.68496708658, + "100.0" : 105156.68496708658 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 105156.68496708658, + 104941.96199051337, + 104970.59175361619 + ], + [ + 97318.89535506097, + 96869.54980481048, + 96850.12681348907 + ], + [ + 100614.00032196075, + 100570.34877055362, + 100768.93497516097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1043337.3049575173, + "scoreError" : 37779.596320040575, + "scoreConfidence" : [ + 1005557.7086374768, + 1081116.901277558 + ], + "scorePercentiles" : { + "0.0" : 1015703.2474101158, + "50.0" : 1047311.917897162, + "90.0" : 1070712.6724839401, + "95.0" : 1070712.6724839401, + "99.0" : 1070712.6724839401, + "99.9" : 1070712.6724839401, + "99.99" : 1070712.6724839401, + "99.999" : 1070712.6724839401, + "99.9999" : 1070712.6724839401, + "100.0" : 1070712.6724839401 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1015929.1653799269, + 1015703.2474101158, + 1015896.6107273466 + ], + [ + 1070712.6724839401, + 1065183.4569176696, + 1065792.1213897474 + ], + [ + 1048437.9009330119, + 1045068.6514787334, + 1047311.917897162 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 11315.216474771834, + "scoreError" : 172.02494354923866, + "scoreConfidence" : [ + 11143.191531222596, + 11487.241418321073 + ], + "scorePercentiles" : { + "0.0" : 11231.735644345008, + "50.0" : 11259.25251134355, + "90.0" : 11454.819931776112, + "95.0" : 11454.819931776112, + "99.0" : 11454.819931776112, + "99.9" : 11454.819931776112, + "99.99" : 11454.819931776112, + "99.999" : 11454.819931776112, + "99.9999" : 11454.819931776112, + "100.0" : 11454.819931776112 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 11454.819931776112, + 11443.821424852233, + 11452.087348576637 + ], + [ + 11232.920604413812, + 11233.837882043948, + 11231.735644345008 + ], + [ + 11250.457024921698, + 11259.25251134355, + 11278.015900673514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 45224.83568262534, + "scoreError" : 1048.5119689576616, + "scoreConfidence" : [ + 44176.323713667676, + 46273.347651583 + ], + "scorePercentiles" : { + "0.0" : 44360.472011143196, + "50.0" : 45531.788517051406, + "90.0" : 45783.9767695266, + "95.0" : 45783.9767695266, + "99.0" : 45783.9767695266, + "99.9" : 45783.9767695266, + "99.99" : 45783.9767695266, + "99.999" : 45783.9767695266, + "99.9999" : 45783.9767695266, + "100.0" : 45783.9767695266 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 45548.20796990221, + 45531.788517051406, + 45457.03387411303 + ], + [ + 44360.472011143196, + 44439.66910192999, + 44418.26749609125 + ], + [ + 45783.9767695266, + 45742.61839198232, + 45741.48701188804 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 443138.7335609501, + "scoreError" : 5074.984883957929, + "scoreConfidence" : [ + 438063.74867699214, + 448213.71844490804 + ], + "scorePercentiles" : { + "0.0" : 438853.1384122526, + "50.0" : 445095.7127915257, + "90.0" : 445728.84810126584, + "95.0" : 445728.84810126584, + "99.0" : 445728.84810126584, + "99.9" : 445728.84810126584, + "99.99" : 445728.84810126584, + "99.999" : 445728.84810126584, + "99.9999" : 445728.84810126584, + "100.0" : 445728.84810126584 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 439968.1464144303, + 438853.1384122526, + 438961.0512685453 + ], + [ + 443190.1281687644, + 445095.7127915257, + 445312.6153092577 + ], + [ + 445728.84810126584, + 445501.1878201987, + 445637.77376231004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 6503.243331074969, + "scoreError" : 155.88656306809895, + "scoreConfidence" : [ + 6347.35676800687, + 6659.129894143069 + ], + "scorePercentiles" : { + "0.0" : 6370.511738174869, + "50.0" : 6557.353963186129, + "90.0" : 6577.488689812577, + "95.0" : 6577.488689812577, + "99.0" : 6577.488689812577, + "99.9" : 6577.488689812577, + "99.99" : 6577.488689812577, + "99.999" : 6577.488689812577, + "99.9999" : 6577.488689812577, + "100.0" : 6577.488689812577 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6577.488689812577, + 6566.590325298333, + 6570.458516592181 + ], + [ + 6387.074046326138, + 6370.511738174869, + 6382.5923342190135 + ], + [ + 6565.003626463732, + 6552.1167396017545, + 6557.353963186129 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 11867.329269757813, + "scoreError" : 196.04260834659178, + "scoreConfidence" : [ + 11671.28666141122, + 12063.371878104404 + ], + "scorePercentiles" : { + "0.0" : 11746.292867513015, + "50.0" : 11825.349115238892, + "90.0" : 12015.450360638877, + "95.0" : 12015.450360638877, + "99.0" : 12015.450360638877, + "99.9" : 12015.450360638877, + "99.99" : 12015.450360638877, + "99.999" : 12015.450360638877, + "99.9999" : 12015.450360638877, + "100.0" : 12015.450360638877 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 11825.349115238892, + 11746.292867513015, + 11913.832032557713 + ], + [ + 11777.689927721174, + 11753.985844854053, + 11766.35859539635 + ], + [ + 11993.450327416647, + 12015.450360638877, + 12013.554356483579 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 71438.27038128191, + "scoreError" : 1509.9384867966066, + "scoreConfidence" : [ + 69928.33189448531, + 72948.20886807851 + ], + "scorePercentiles" : { + "0.0" : 70268.86934433256, + "50.0" : 71282.76049270073, + "90.0" : 72538.75318438996, + "95.0" : 72538.75318438996, + "99.0" : 72538.75318438996, + "99.9" : 72538.75318438996, + "99.99" : 72538.75318438996, + "99.999" : 72538.75318438996, + "99.9999" : 72538.75318438996, + "100.0" : 72538.75318438996 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 72530.55498821396, + 72538.75318438996, + 72388.19837707932 + ], + [ + 70782.79696911784, + 70401.48243162378, + 70268.86934433256 + ], + [ + 71727.89320604227, + 71023.12443803666, + 71282.76049270073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 6398709.275408815, + "scoreError" : 126183.5867819212, + "scoreConfidence" : [ + 6272525.688626894, + 6524892.8621907355 + ], + "scorePercentiles" : { + "0.0" : 6291085.297484277, + "50.0" : 6387188.439974457, + "90.0" : 6491328.1239454895, + "95.0" : 6491328.1239454895, + "99.0" : 6491328.1239454895, + "99.9" : 6491328.1239454895, + "99.99" : 6491328.1239454895, + "99.999" : 6491328.1239454895, + "99.9999" : 6491328.1239454895, + "100.0" : 6491328.1239454895 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6491328.1239454895, + 6488077.19001297, + 6481109.981205444 + ], + [ + 6354258.74841169, + 6291085.297484277, + 6310670.466246056 + ], + [ + 6387188.439974457, + 6403043.638924456, + 6381621.5924744895 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 6569576.793351535, + "scoreError" : 384954.5853160948, + "scoreConfidence" : [ + 6184622.20803544, + 6954531.378667629 + ], + "scorePercentiles" : { + "0.0" : 6265185.024420789, + "50.0" : 6650287.005984043, + "90.0" : 6793779.208559782, + "95.0" : 6793779.208559782, + "99.0" : 6793779.208559782, + "99.9" : 6793779.208559782, + "99.99" : 6793779.208559782, + "99.999" : 6793779.208559782, + "99.9999" : 6793779.208559782, + "100.0" : 6793779.208559782 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6282970.966080402, + 6269994.820689655, + 6265185.024420789 + ], + [ + 6747180.360755226, + 6789676.959945689, + 6793779.208559782 + ], + [ + 6643032.754316069, + 6684084.039412158, + 6650287.005984043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAbgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 6478658.767822663, + "scoreError" : 49069.54441114768, + "scoreConfidence" : [ + 6429589.223411515, + 6527728.312233811 + ], + "scorePercentiles" : { + "0.0" : 6437623.745817246, + "50.0" : 6485599.195849546, + "90.0" : 6526921.3568167, + "95.0" : 6526921.3568167, + "99.0" : 6526921.3568167, + "99.9" : 6526921.3568167, + "99.99" : 6526921.3568167, + "99.999" : 6526921.3568167, + "99.9999" : 6526921.3568167, + "100.0" : 6526921.3568167 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6526921.3568167, + 6492636.765736534, + 6506922.867924528 + ], + [ + 6437623.745817246, + 6472031.835058215, + 6450381.75177305 + ], + [ + 6449317.71308833, + 6486493.6783398185, + 6485599.195849546 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "2" + }, + "primaryMetric" : { + "score" : 6376575.1027172785, + "scoreError" : 194988.26138432373, + "scoreConfidence" : [ + 6181586.841332954, + 6571563.364101603 + ], + "scorePercentiles" : { + "0.0" : 6238185.0137157105, + "50.0" : 6369792.822929936, + "90.0" : 6524331.181343771, + "95.0" : 6524331.181343771, + "99.0" : 6524331.181343771, + "99.9" : 6524331.181343771, + "99.99" : 6524331.181343771, + "99.999" : 6524331.181343771, + "99.9999" : 6524331.181343771, + "100.0" : 6524331.181343771 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6524331.181343771, + 6523662.991519895, + 6487411.79766537 + ], + [ + 6369792.822929936, + 6368797.631444939, + 6379426.840561224 + ], + [ + 6244740.780274657, + 6252826.865, + 6238185.0137157105 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 6263376.655796844, + "scoreError" : 223312.4731747562, + "scoreConfidence" : [ + 6040064.182622087, + 6486689.1289716 + ], + "scorePercentiles" : { + "0.0" : 6147048.186846958, + "50.0" : 6200365.234345939, + "90.0" : 6453870.472258065, + "95.0" : 6453870.472258065, + "99.0" : 6453870.472258065, + "99.9" : 6453870.472258065, + "99.99" : 6453870.472258065, + "99.999" : 6453870.472258065, + "99.9999" : 6453870.472258065, + "100.0" : 6453870.472258065 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6441251.466194462, + 6418451.837075048, + 6453870.472258065 + ], + [ + 6147048.186846958, + 6148743.549477566, + 6159800.388546798 + ], + [ + 6202072.626782393, + 6200365.234345939, + 6198786.140644362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 6448861.512850301, + "scoreError" : 94674.30577495846, + "scoreConfidence" : [ + 6354187.207075343, + 6543535.81862526 + ], + "scorePercentiles" : { + "0.0" : 6392429.194249202, + "50.0" : 6421305.336970475, + "90.0" : 6533245.871325931, + "95.0" : 6533245.871325931, + "99.0" : 6533245.871325931, + "99.9" : 6533245.871325931, + "99.99" : 6533245.871325931, + "99.999" : 6533245.871325931, + "99.9999" : 6533245.871325931, + "100.0" : 6533245.871325931 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6533245.871325931, + 6506297.143786597, + 6526423.699282452 + ], + [ + 6392429.194249202, + 6431628.632154341, + 6403075.450704225 + ], + [ + 6411964.421794872, + 6413383.865384615, + 6421305.336970475 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-24T00:16:50Z-4f40d2eed6c54adcdfb8f67de1f7601ad3d5311a-jdk17.json b/performance-results/2025-02-24T00:16:50Z-4f40d2eed6c54adcdfb8f67de1f7601ad3d5311a-jdk17.json new file mode 100644 index 0000000000..45bd9b817a --- /dev/null +++ b/performance-results/2025-02-24T00:16:50Z-4f40d2eed6c54adcdfb8f67de1f7601ad3d5311a-jdk17.json @@ -0,0 +1,1161 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4274036884572663, + "scoreError" : 0.024762764818203227, + "scoreConfidence" : [ + 3.402640923639063, + 3.4521664532754697 + ], + "scorePercentiles" : { + "0.0" : 3.4228175390638214, + "50.0" : 3.427351229060756, + "90.0" : 3.4320947566437314, + "95.0" : 3.4320947566437314, + "99.0" : 3.4320947566437314, + "99.9" : 3.4320947566437314, + "99.99" : 3.4320947566437314, + "99.999" : 3.4320947566437314, + "99.9999" : 3.4320947566437314, + "100.0" : 3.4320947566437314 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4280617857617046, + 3.4320947566437314 + ], + [ + 3.4228175390638214, + 3.4266406723598073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7317595392033245, + "scoreError" : 0.007202794691721973, + "scoreConfidence" : [ + 1.7245567445116026, + 1.7389623338950464 + ], + "scorePercentiles" : { + "0.0" : 1.730142448238231, + "50.0" : 1.7321035723481373, + "90.0" : 1.7326885638787919, + "95.0" : 1.7326885638787919, + "99.0" : 1.7326885638787919, + "99.9" : 1.7326885638787919, + "99.99" : 1.7326885638787919, + "99.999" : 1.7326885638787919, + "99.9999" : 1.7326885638787919, + "100.0" : 1.7326885638787919 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7320245712018445, + 1.7326885638787919 + ], + [ + 1.730142448238231, + 1.7321825734944303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8696805774263187, + "scoreError" : 0.0034440948327385066, + "scoreConfidence" : [ + 0.8662364825935801, + 0.8731246722590572 + ], + "scorePercentiles" : { + "0.0" : 0.8691513855289171, + "50.0" : 0.8696254417977733, + "90.0" : 0.8703200405808109, + "95.0" : 0.8703200405808109, + "99.0" : 0.8703200405808109, + "99.9" : 0.8703200405808109, + "99.99" : 0.8703200405808109, + "99.999" : 0.8703200405808109, + "99.9999" : 0.8703200405808109, + "100.0" : 0.8703200405808109 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8699057612066945, + 0.8703200405808109 + ], + [ + 0.8693451223888521, + 0.8691513855289171 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 43.725382690111864, + "scoreError" : 1.2467483817498346, + "scoreConfidence" : [ + 42.47863430836203, + 44.972131071861696 + ], + "scorePercentiles" : { + "0.0" : 42.878972567778796, + "50.0" : 43.657222701719, + "90.0" : 44.64471078475697, + "95.0" : 44.64471078475697, + "99.0" : 44.64471078475697, + "99.9" : 44.64471078475697, + "99.99" : 44.64471078475697, + "99.999" : 44.64471078475697, + "99.9999" : 44.64471078475697, + "100.0" : 44.64471078475697 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.56080073698337, + 44.64471078475697, + 44.63330805860265 + ], + [ + 42.878972567778796, + 42.90726413527759, + 42.9272503303202 + ], + [ + 43.65377670524797, + 43.657222701719, + 43.66513819032023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 43.51101417312418, + "scoreError" : 1.3039758175367824, + "scoreConfidence" : [ + 42.2070383555874, + 44.81498999066096 + ], + "scorePercentiles" : { + "0.0" : 42.46074799798999, + "50.0" : 43.919897336473376, + "90.0" : 44.14038266172348, + "95.0" : 44.14038266172348, + "99.0" : 44.14038266172348, + "99.9" : 44.14038266172348, + "99.99" : 44.14038266172348, + "99.999" : 44.14038266172348, + "99.9999" : 44.14038266172348, + "100.0" : 44.14038266172348 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 44.13510746298949, + 44.11681928133372, + 44.14038266172348 + ], + [ + 43.89040451298183, + 43.94458681643863, + 43.919897336473376 + ], + [ + 42.46074799798999, + 42.48649199343833, + 42.50468949474879 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 0.05188249344848197, + "scoreError" : 0.0016286800311858416, + "scoreConfidence" : [ + 0.05025381341729613, + 0.05351117347966781 + ], + "scorePercentiles" : { + "0.0" : 0.05066552862050097, + "50.0" : 0.05210605107363002, + "90.0" : 0.052883179308193064, + "95.0" : 0.052883179308193064, + "99.0" : 0.052883179308193064, + "99.9" : 0.052883179308193064, + "99.99" : 0.052883179308193064, + "99.999" : 0.052883179308193064, + "99.9999" : 0.052883179308193064, + "100.0" : 0.052883179308193064 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.050668343981962356, + 0.05066552862050097, + 0.050671809669066786 + ], + [ + 0.0521102071869268, + 0.052101387525008334, + 0.05210605107363002 + ], + [ + 0.05288311202068758, + 0.052883179308193064, + 0.05285282165036177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33817752867976947, + "scoreError" : 0.01650232636616941, + "scoreConfidence" : [ + 0.3216752023136001, + 0.35467985504593885 + ], + "scorePercentiles" : { + "0.0" : 0.3254714952483239, + "50.0" : 0.3396426453267219, + "90.0" : 0.34879158770185903, + "95.0" : 0.34879158770185903, + "99.0" : 0.34879158770185903, + "99.9" : 0.34879158770185903, + "99.99" : 0.34879158770185903, + "99.999" : 0.34879158770185903, + "99.9999" : 0.34879158770185903, + "100.0" : 0.34879158770185903 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.34038622288028864, + 0.3396426453267219, + 0.3394560875084861 + ], + [ + 0.34879158770185903, + 0.34850733047569266, + 0.34845366375135023 + ], + [ + 0.3271867593901322, + 0.32570196583507033, + 0.3254714952483239 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 0.0527440308189436, + "scoreError" : 7.295368504205332E-4, + "scoreConfidence" : [ + 0.05201449396852306, + 0.05347356766936413 + ], + "scorePercentiles" : { + "0.0" : 0.05218023944147021, + "50.0" : 0.05290051550754614, + "90.0" : 0.053163110423544546, + "95.0" : 0.053163110423544546, + "99.0" : 0.053163110423544546, + "99.9" : 0.053163110423544546, + "99.99" : 0.053163110423544546, + "99.999" : 0.053163110423544546, + "99.9999" : 0.053163110423544546, + "100.0" : 0.053163110423544546 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0529105015846477, + 0.05289031704685492, + 0.05290051550754614 + ], + [ + 0.05218363736602064, + 0.052186375219179224, + 0.05218023944147021 + ], + [ + 0.053163110423544546, + 0.05316134911141944, + 0.053120231669809566 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.5202083735295633, + "scoreError" : 0.03190522031978566, + "scoreConfidence" : [ + 0.48830315320977763, + 0.552113593849349 + ], + "scorePercentiles" : { + "0.0" : 0.49537793248129985, + "50.0" : 0.5277170549868074, + "90.0" : 0.5377159787073879, + "95.0" : 0.5377159787073879, + "99.0" : 0.5377159787073879, + "99.9" : 0.5377159787073879, + "99.99" : 0.5377159787073879, + "99.999" : 0.5377159787073879, + "99.9999" : 0.5377159787073879, + "100.0" : 0.5377159787073879 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.5372063835947573, + 0.5372449502524981, + 0.5377159787073879 + ], + [ + 0.5277170549868074, + 0.5284748000845532, + 0.5269452361155021 + ], + [ + 0.49537793248129985, + 0.4955745880370682, + 0.4956184375061949 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 0.02330213170499937, + "scoreError" : 8.600355254300683E-4, + "scoreConfidence" : [ + 0.022442096179569302, + 0.02416216723042944 + ], + "scorePercentiles" : { + "0.0" : 0.022813897548678522, + "50.0" : 0.023125910827642506, + "90.0" : 0.02400309627284467, + "95.0" : 0.02400309627284467, + "99.0" : 0.02400309627284467, + "99.9" : 0.02400309627284467, + "99.99" : 0.02400309627284467, + "99.999" : 0.02400309627284467, + "99.9999" : 0.02400309627284467, + "100.0" : 0.02400309627284467 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.02400309627284467, + 0.02393782406913143, + 0.0239411025073199 + ], + [ + 0.023125910827642506, + 0.023130867757813513, + 0.02312172802480468 + ], + [ + 0.022815617882190817, + 0.022813897548678522, + 0.022829140454568284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.24497773765850908, + "scoreError" : 0.01858056660717018, + "scoreConfidence" : [ + 0.2263971710513389, + 0.2635583042656793 + ], + "scorePercentiles" : { + "0.0" : 0.23287860653905268, + "50.0" : 0.24373483102196009, + "90.0" : 0.2584875260545906, + "95.0" : 0.2584875260545906, + "99.0" : 0.2584875260545906, + "99.9" : 0.2584875260545906, + "99.99" : 0.2584875260545906, + "99.999" : 0.2584875260545906, + "99.9999" : 0.2584875260545906, + "100.0" : 0.2584875260545906 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.24291845883838997, + 0.24373483102196009, + 0.244542229520223 + ], + [ + 0.23289833480832828, + 0.232887405798789, + 0.23287860653905268 + ], + [ + 0.2583865650983128, + 0.2580656812469356, + 0.2584875260545906 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 0.10041460423244533, + "scoreError" : 0.00344695704530663, + "scoreConfidence" : [ + 0.0969676471871387, + 0.10386156127775197 + ], + "scorePercentiles" : { + "0.0" : 0.09789638518844836, + "50.0" : 0.09973601610715496, + "90.0" : 0.10319401726415289, + "95.0" : 0.10319401726415289, + "99.0" : 0.10319401726415289, + "99.9" : 0.10319401726415289, + "99.99" : 0.10319401726415289, + "99.999" : 0.10319401726415289, + "99.9999" : 0.10319401726415289, + "100.0" : 0.10319401726415289 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0997753193151546, + 0.09973601610715496, + 0.09968744761999701 + ], + [ + 0.10319401726415289, + 0.10292642249737541, + 0.10296189465122266 + ], + [ + 0.09890774312108085, + 0.09864619232742124, + 0.09789638518844836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.0159083973122576, + "scoreError" : 0.02939051680419365, + "scoreConfidence" : [ + 0.9865178805080639, + 1.0452989141164513 + ], + "scorePercentiles" : { + "0.0" : 1.0011459455400942, + "50.0" : 1.0057589681182741, + "90.0" : 1.0412337920874544, + "95.0" : 1.0412337920874544, + "99.0" : 1.0412337920874544, + "99.9" : 1.0412337920874544, + "99.99" : 1.0412337920874544, + "99.999" : 1.0412337920874544, + "99.9999" : 1.0412337920874544, + "100.0" : 1.0412337920874544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.009501218958207, + 1.005332541314837, + 1.0057589681182741 + ], + [ + 1.0412337920874544, + 1.0381442229834943, + 1.0374625426348547 + ], + [ + 1.003403861141768, + 1.0011924830313346, + 1.0011459455400942 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 0.04436857258557735, + "scoreError" : 0.001215658707935488, + "scoreConfidence" : [ + 0.04315291387764186, + 0.04558423129351284 + ], + "scorePercentiles" : { + "0.0" : 0.04356789100771141, + "50.0" : 0.04423132656897566, + "90.0" : 0.04526977572758838, + "95.0" : 0.04526977572758838, + "99.0" : 0.04526977572758838, + "99.9" : 0.04526977572758838, + "99.99" : 0.04526977572758838, + "99.999" : 0.04526977572758838, + "99.9999" : 0.04526977572758838, + "100.0" : 0.04526977572758838 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04427510071104736, + 0.04423132656897566, + 0.04421848874876743 + ], + [ + 0.043641449038373414, + 0.04356789100771141, + 0.04360398981424959 + ], + [ + 0.045260049685898945, + 0.04526977572758838, + 0.045249081967584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4358362930061064, + "scoreError" : 0.00755290990194395, + "scoreConfidence" : [ + 0.4282833831041624, + 0.44338920290805034 + ], + "scorePercentiles" : { + "0.0" : 0.4298716314477304, + "50.0" : 0.4364674297747905, + "90.0" : 0.44085744850996295, + "95.0" : 0.44085744850996295, + "99.0" : 0.44085744850996295, + "99.9" : 0.44085744850996295, + "99.99" : 0.44085744850996295, + "99.999" : 0.44085744850996295, + "99.9999" : 0.44085744850996295, + "100.0" : 0.44085744850996295 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4368088904953263, + 0.4364674297747905, + 0.43620555661694144 + ], + [ + 0.44085744850996295, + 0.4406312695747962, + 0.44042787976746234 + ], + [ + 0.43134281193926843, + 0.4299137189286789, + 0.4298716314477304 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 0.011722568660637263, + "scoreError" : 2.1956260875161603E-4, + "scoreConfidence" : [ + 0.011503006051885646, + 0.01194213126938888 + ], + "scorePercentiles" : { + "0.0" : 0.011542314397607535, + "50.0" : 0.011800895635252648, + "90.0" : 0.011824917085953011, + "95.0" : 0.011824917085953011, + "99.0" : 0.011824917085953011, + "99.9" : 0.011824917085953011, + "99.99" : 0.011824917085953011, + "99.999" : 0.011824917085953011, + "99.9999" : 0.011824917085953011, + "100.0" : 0.011824917085953011 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011550013690086382, + 0.011542314397607535, + 0.01155425209245146 + ], + [ + 0.011824917085953011, + 0.011808919938877789, + 0.01182250247441645 + ], + [ + 0.011800895635252648, + 0.01179528595810834, + 0.011804016672981744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0698523009710762, + "scoreError" : 0.0014210968304418292, + "scoreConfidence" : [ + 0.06843120414063437, + 0.07127339780151802 + ], + "scorePercentiles" : { + "0.0" : 0.06866273061342196, + "50.0" : 0.07006469910388363, + "90.0" : 0.07072980937157407, + "95.0" : 0.07072980937157407, + "99.0" : 0.07072980937157407, + "99.9" : 0.07072980937157407, + "99.99" : 0.07072980937157407, + "99.999" : 0.07072980937157407, + "99.9999" : 0.07072980937157407, + "100.0" : 0.07072980937157407 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.07070594901472782, + 0.07072980937157407, + 0.07066807764877146 + ], + [ + 0.06896519448563133, + 0.06874885908056566, + 0.06866273061342196 + ], + [ + 0.07010626623108039, + 0.07006469910388363, + 0.07001912319002941 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "10" + }, + "primaryMetric" : { + "score" : 2.2874525121049147E7, + "scoreError" : 920787.4900115487, + "scoreConfidence" : [ + 2.1953737631037597E7, + 2.3795312611060698E7 + ], + "scorePercentiles" : { + "0.0" : 2.240210304474273E7, + "50.0" : 2.2565303896396395E7, + "90.0" : 2.3641611439716313E7, + "95.0" : 2.3641611439716313E7, + "99.0" : 2.3641611439716313E7, + "99.9" : 2.3641611439716313E7, + "99.99" : 2.3641611439716313E7, + "99.999" : 2.3641611439716313E7, + "99.9999" : 2.3641611439716313E7, + "100.0" : 2.3641611439716313E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2.3641611439716313E7, + 2.359826475471698E7, + 2.3560848635294117E7 + ], + [ + 2.2503107015730336E7, + 2.2443770878923766E7, + 2.240210304474273E7 + ], + [ + 2.2591522221218962E7, + 2.25641942027027E7, + 2.2565303896396395E7 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 2.3047301492169302E7, + "scoreError" : 309261.7454961725, + "scoreConfidence" : [ + 2.273803974667313E7, + 2.3356563237665474E7 + ], + "scorePercentiles" : { + "0.0" : 2.284278906392694E7, + "50.0" : 2.2973325006880734E7, + "90.0" : 2.3301097169767443E7, + "95.0" : 2.3301097169767443E7, + "99.0" : 2.3301097169767443E7, + "99.9" : 2.3301097169767443E7, + "99.99" : 2.3301097169767443E7, + "99.999" : 2.3301097169767443E7, + "99.9999" : 2.3301097169767443E7, + "100.0" : 2.3301097169767443E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2.319061096064815E7, + 2.2973325006880734E7, + 2.2951058389908258E7 + ], + [ + 2.2868141162100457E7, + 2.2856062216894977E7, + 2.284278906392694E7 + ], + [ + 2.3301097169767443E7, + 2.323164748491879E7, + 2.3210981974477958E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-24T01:29:41Z-53fa9b53fcbe2b6804d82a3e24bd58c0f5e70c2d-jdk17.json b/performance-results/2025-02-24T01:29:41Z-53fa9b53fcbe2b6804d82a3e24bd58c0f5e70c2d-jdk17.json new file mode 100644 index 0000000000..94b24bdf8f --- /dev/null +++ b/performance-results/2025-02-24T01:29:41Z-53fa9b53fcbe2b6804d82a3e24bd58c0f5e70c2d-jdk17.json @@ -0,0 +1,665 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4240890205405137, + "scoreError" : 0.03936617511364664, + "scoreConfidence" : [ + 3.384722845426867, + 3.46345519565416 + ], + "scorePercentiles" : { + "0.0" : 3.416280112766159, + "50.0" : 3.424803993008525, + "90.0" : 3.4304679833788474, + "95.0" : 3.4304679833788474, + "99.0" : 3.4304679833788474, + "99.9" : 3.4304679833788474, + "99.99" : 3.4304679833788474, + "99.999" : 3.4304679833788474, + "99.9999" : 3.4304679833788474, + "100.0" : 3.4304679833788474 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4268828533900053, + 3.4304679833788474 + ], + [ + 3.416280112766159, + 3.4227251326270443 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7289182439981992, + "scoreError" : 0.009875088289429172, + "scoreConfidence" : [ + 1.71904315570877, + 1.7387933322876283 + ], + "scorePercentiles" : { + "0.0" : 1.7275909081867116, + "50.0" : 1.728819061863204, + "90.0" : 1.7304439440796775, + "95.0" : 1.7304439440796775, + "99.0" : 1.7304439440796775, + "99.9" : 1.7304439440796775, + "99.99" : 1.7304439440796775, + "99.999" : 1.7304439440796775, + "99.9999" : 1.7304439440796775, + "100.0" : 1.7304439440796775 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7300225473819377, + 1.7304439440796775 + ], + [ + 1.7275909081867116, + 1.7276155763444705 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8700132941789567, + "scoreError" : 0.0021170309298315024, + "scoreConfidence" : [ + 0.8678962632491252, + 0.8721303251087882 + ], + "scorePercentiles" : { + "0.0" : 0.8695372797886042, + "50.0" : 0.8701173884345118, + "90.0" : 0.870281120058199, + "95.0" : 0.870281120058199, + "99.0" : 0.870281120058199, + "99.9" : 0.870281120058199, + "99.99" : 0.870281120058199, + "99.999" : 0.870281120058199, + "99.9999" : 0.870281120058199, + "100.0" : 0.870281120058199 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8695372797886042, + 0.8700857738212587 + ], + [ + 0.8701490030477649, + 0.870281120058199 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 42.64160574403351, + "scoreError" : 1.3640765499826009, + "scoreConfidence" : [ + 41.27752919405091, + 44.00568229401611 + ], + "scorePercentiles" : { + "0.0" : 41.707744537786546, + "50.0" : 42.49634829304081, + "90.0" : 43.71206456211418, + "95.0" : 43.71206456211418, + "99.0" : 43.71206456211418, + "99.9" : 43.71206456211418, + "99.99" : 43.71206456211418, + "99.999" : 43.71206456211418, + "99.9999" : 43.71206456211418, + "100.0" : 43.71206456211418 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 41.707744537786546, + 41.77952555912812, + 41.87837244221971 + ], + [ + 43.71206456211418, + 43.60545355674085, + 43.60775354052616 + ], + [ + 42.50645826039412, + 42.48073094435115, + 42.49634829304081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.34440201171656104, + "scoreError" : 0.004486131561743835, + "scoreConfidence" : [ + 0.3399158801548172, + 0.34888814327830486 + ], + "scorePercentiles" : { + "0.0" : 0.34078550754813425, + "50.0" : 0.34573783564390664, + "90.0" : 0.3467770228517928, + "95.0" : 0.3467770228517928, + "99.0" : 0.3467770228517928, + "99.9" : 0.3467770228517928, + "99.99" : 0.3467770228517928, + "99.999" : 0.3467770228517928, + "99.9999" : 0.3467770228517928, + "100.0" : 0.3467770228517928 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3466564419717138, + 0.34573783564390664, + 0.3454683490862611 + ], + [ + 0.34078550754813425, + 0.341077951739427, + 0.3407947371183206 + ], + [ + 0.3467770228517928, + 0.3460057300532835, + 0.34631452943621 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.5108566930793287, + "scoreError" : 0.01673376640611887, + "scoreConfidence" : [ + 0.49412292667320984, + 0.5275904594854476 + ], + "scorePercentiles" : { + "0.0" : 0.4975432007562565, + "50.0" : 0.5133298237347295, + "90.0" : 0.5213933500521376, + "95.0" : 0.5213933500521376, + "99.0" : 0.5213933500521376, + "99.9" : 0.5213933500521376, + "99.99" : 0.5213933500521376, + "99.999" : 0.5213933500521376, + "99.9999" : 0.5213933500521376, + "100.0" : 0.5213933500521376 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.5133298237347295, + 0.5134748340521668, + 0.5125813436699128 + ], + [ + 0.49966809073648444, + 0.49803418884462153, + 0.4975432007562565 + ], + [ + 0.5213933500521376, + 0.5209760688200052, + 0.5207093370476439 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.22985229142533534, + "scoreError" : 0.009007513978974728, + "scoreConfidence" : [ + 0.2208447774463606, + 0.23885980540431007 + ], + "scorePercentiles" : { + "0.0" : 0.2246681499179978, + "50.0" : 0.2278689162375245, + "90.0" : 0.237023872223934, + "95.0" : 0.237023872223934, + "99.0" : 0.237023872223934, + "99.9" : 0.237023872223934, + "99.99" : 0.237023872223934, + "99.999" : 0.237023872223934, + "99.9999" : 0.237023872223934, + "100.0" : 0.237023872223934 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.2278689162375245, + 0.22774250177636074, + 0.22795436086986254 + ], + [ + 0.22517435144446196, + 0.2246681499179978, + 0.2248926582634313 + ], + [ + 0.237023872223934, + 0.23653219364223374, + 0.2368136184522118 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.0276159079256935, + "scoreError" : 0.03894493523763066, + "scoreConfidence" : [ + 0.9886709726880628, + 1.0665608431633242 + ], + "scorePercentiles" : { + "0.0" : 1.0002823356671335, + "50.0" : 1.0272291300328678, + "90.0" : 1.0546416500052727, + "95.0" : 1.0546416500052727, + "99.0" : 1.0546416500052727, + "99.9" : 1.0546416500052727, + "99.99" : 1.0546416500052727, + "99.999" : 1.0546416500052727, + "99.9999" : 1.0546416500052727, + "100.0" : 1.0546416500052727 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0546416500052727, + 1.054312120177103, + 1.0531231917649537 + ], + [ + 1.0005659335667834, + 1.0002823356671335, + 1.0008482301841473 + ], + [ + 1.0303489075829384, + 1.0272291300328678, + 1.0271916723500412 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.43364130483497326, + "scoreError" : 0.00832028889387276, + "scoreConfidence" : [ + 0.4253210159411005, + 0.441961593728846 + ], + "scorePercentiles" : { + "0.0" : 0.42869411788914136, + "50.0" : 0.43192799589686004, + "90.0" : 0.4409237714285714, + "95.0" : 0.4409237714285714, + "99.0" : 0.4409237714285714, + "99.9" : 0.4409237714285714, + "99.99" : 0.4409237714285714, + "99.999" : 0.4409237714285714, + "99.9999" : 0.4409237714285714, + "100.0" : 0.4409237714285714 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4409237714285714, + 0.4396748718839305, + 0.4388150212383167 + ], + [ + 0.4287206548915373, + 0.42869411788914136, + 0.4290466350609233 + ], + [ + 0.43398500785488003, + 0.43192799589686004, + 0.4309836673705986 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.07000095626907243, + "scoreError" : 0.0014089190015736848, + "scoreConfidence" : [ + 0.06859203726749875, + 0.07140987527064611 + ], + "scorePercentiles" : { + "0.0" : 0.06913664714503985, + "50.0" : 0.06945898296891062, + "90.0" : 0.07108060061981121, + "95.0" : 0.07108060061981121, + "99.0" : 0.07108060061981121, + "99.9" : 0.07108060061981121, + "99.99" : 0.07108060061981121, + "99.999" : 0.07108060061981121, + "99.9999" : 0.07108060061981121, + "100.0" : 0.07108060061981121 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.07108060061981121, + 0.06928036679298614, + 0.06945898296891062 + ], + [ + 0.0692402498563288, + 0.06913664714503985, + 0.06942358199868097 + ], + [ + 0.07097093614137184, + 0.0708561556971084, + 0.07056108520141402 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 2.315031757691618E7, + "scoreError" : 834203.297699478, + "scoreConfidence" : [ + 2.2316114279216703E7, + 2.3984520874615658E7 + ], + "scorePercentiles" : { + "0.0" : 2.251475790786517E7, + "50.0" : 2.3254453705336425E7, + "90.0" : 2.3667659647754136E7, + "95.0" : 2.3667659647754136E7, + "99.0" : 2.3667659647754136E7, + "99.9" : 2.3667659647754136E7, + "99.99" : 2.3667659647754136E7, + "99.999" : 2.3667659647754136E7, + "99.9999" : 2.3667659647754136E7, + "100.0" : 2.3667659647754136E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2.3667659647754136E7, + 2.3658213401891254E7, + 2.366260164066194E7 + ], + [ + 2.251475790786517E7, + 2.2533523272522524E7, + 2.2547165313063063E7 + ], + [ + 2.3254453705336425E7, + 2.32293066450116E7, + 2.3285176658139534E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-24T09:48:13Z-d229276fb3c4911f7a7e56bf28334808acb01ca3-jdk17.json b/performance-results/2025-02-24T09:48:13Z-d229276fb3c4911f7a7e56bf28334808acb01ca3-jdk17.json new file mode 100644 index 0000000000..30667dd796 --- /dev/null +++ b/performance-results/2025-02-24T09:48:13Z-d229276fb3c4911f7a7e56bf28334808acb01ca3-jdk17.json @@ -0,0 +1,665 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4022546195396735, + "scoreError" : 0.017482973489114994, + "scoreConfidence" : [ + 3.3847716460505586, + 3.4197375930287883 + ], + "scorePercentiles" : { + "0.0" : 3.3988796541507518, + "50.0" : 3.4023760846252484, + "90.0" : 3.4053866547574443, + "95.0" : 3.4053866547574443, + "99.0" : 3.4053866547574443, + "99.9" : 3.4053866547574443, + "99.99" : 3.4053866547574443, + "99.999" : 3.4053866547574443, + "99.9999" : 3.4053866547574443, + "100.0" : 3.4053866547574443 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.401772014494162, + 3.4029801547563348 + ], + [ + 3.3988796541507518, + 3.4053866547574443 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7196663533286398, + "scoreError" : 0.014536449828748476, + "scoreConfidence" : [ + 1.7051299034998912, + 1.7342028031573884 + ], + "scorePercentiles" : { + "0.0" : 1.7174594833968682, + "50.0" : 1.7194137156433158, + "90.0" : 1.722378498631059, + "95.0" : 1.722378498631059, + "99.0" : 1.722378498631059, + "99.9" : 1.722378498631059, + "99.99" : 1.722378498631059, + "99.999" : 1.722378498631059, + "99.9999" : 1.722378498631059, + "100.0" : 1.722378498631059 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7174594833968682, + 1.720602732042664 + ], + [ + 1.7182246992439676, + 1.722378498631059 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8642645143308028, + "scoreError" : 0.0034989436549679176, + "scoreConfidence" : [ + 0.8607655706758348, + 0.8677634579857707 + ], + "scorePercentiles" : { + "0.0" : 0.8635509397774016, + "50.0" : 0.8643195138315781, + "90.0" : 0.8648680898826532, + "95.0" : 0.8648680898826532, + "99.0" : 0.8648680898826532, + "99.9" : 0.8648680898826532, + "99.99" : 0.8648680898826532, + "99.999" : 0.8648680898826532, + "99.9999" : 0.8648680898826532, + "100.0" : 0.8648680898826532 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8643220007966118, + 0.8648680898826532 + ], + [ + 0.8635509397774016, + 0.8643170268665444 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 37.92108556259461, + "scoreError" : 2.1803773481991127, + "scoreConfidence" : [ + 35.7407082143955, + 40.10146291079373 + ], + "scorePercentiles" : { + "0.0" : 36.7907295161254, + "50.0" : 37.1257475248306, + "90.0" : 39.74442108757022, + "95.0" : 39.74442108757022, + "99.0" : 39.74442108757022, + "99.9" : 39.74442108757022, + "99.99" : 39.74442108757022, + "99.999" : 39.74442108757022, + "99.9999" : 39.74442108757022, + "100.0" : 39.74442108757022 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 37.093128965232616, + 37.108901583866064, + 36.7907295161254 + ], + [ + 37.1257475248306, + 37.04892454527629, + 37.19742750402842 + ], + [ + 39.464342600993746, + 39.74442108757022, + 39.716146735428204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.35038660216748957, + "scoreError" : 0.0036178241546157524, + "scoreConfidence" : [ + 0.3467687780128738, + 0.3540044263221053 + ], + "scorePercentiles" : { + "0.0" : 0.34693029758889854, + "50.0" : 0.3503044037760964, + "90.0" : 0.3537241296381451, + "95.0" : 0.3537241296381451, + "99.0" : 0.3537241296381451, + "99.9" : 0.3537241296381451, + "99.99" : 0.3537241296381451, + "99.999" : 0.3537241296381451, + "99.9999" : 0.3537241296381451, + "100.0" : 0.3537241296381451 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3537241296381451, + 0.3500387195211593, + 0.3499470267697799 + ], + [ + 0.35256384406839414, + 0.3510276912492541, + 0.35132210816792553 + ], + [ + 0.3503044037760964, + 0.34762119872775304, + 0.34693029758889854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.5133334808724517, + "scoreError" : 0.004854914945014691, + "scoreConfidence" : [ + 0.508478565927437, + 0.5181883958174663 + ], + "scorePercentiles" : { + "0.0" : 0.5105533991422883, + "50.0" : 0.5127151179697513, + "90.0" : 0.517916162773836, + "95.0" : 0.517916162773836, + "99.0" : 0.517916162773836, + "99.9" : 0.517916162773836, + "99.99" : 0.517916162773836, + "99.999" : 0.517916162773836, + "99.9999" : 0.517916162773836, + "100.0" : 0.517916162773836 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.5110045925907001, + 0.5107955352436409, + 0.5110505164554374 + ], + [ + 0.517916162773836, + 0.516407525690679, + 0.5166440658710477 + ], + [ + 0.5127151179697513, + 0.5129144121146844, + 0.5105533991422883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.24284745478312963, + "scoreError" : 0.01049551718919714, + "scoreConfidence" : [ + 0.2323519375939325, + 0.2533429719723268 + ], + "scorePercentiles" : { + "0.0" : 0.23525882779306936, + "50.0" : 0.24295487135881053, + "90.0" : 0.2516049401197605, + "95.0" : 0.2516049401197605, + "99.0" : 0.2516049401197605, + "99.9" : 0.2516049401197605, + "99.99" : 0.2516049401197605, + "99.999" : 0.2516049401197605, + "99.9999" : 0.2516049401197605, + "100.0" : 0.2516049401197605 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.24295487135881053, + 0.2430232010012394, + 0.2428598038468077 + ], + [ + 0.2492799530373657, + 0.24897829017801568, + 0.2516049401197605 + ], + [ + 0.23538877749270312, + 0.23627842822039505, + 0.23525882779306936 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.0144827414344384, + "scoreError" : 0.040590136169010034, + "scoreConfidence" : [ + 0.9738926052654283, + 1.0550728776034484 + ], + "scorePercentiles" : { + "0.0" : 0.9830720440381402, + "50.0" : 1.019898655109117, + "90.0" : 1.039894017988978, + "95.0" : 1.039894017988978, + "99.0" : 1.039894017988978, + "99.9" : 1.039894017988978, + "99.99" : 1.039894017988978, + "99.999" : 1.039894017988978, + "99.9999" : 1.039894017988978, + "100.0" : 1.039894017988978 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0388163423704166, + 1.0388171291160277, + 1.039894017988978 + ], + [ + 1.0213398724468954, + 1.019898655109117, + 1.0187678639095448 + ], + [ + 0.9838052153467781, + 0.9830720440381402, + 0.9859335325840481 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.43793185003198876, + "scoreError" : 0.007114234387317298, + "scoreConfidence" : [ + 0.43081761564467147, + 0.44504608441930604 + ], + "scorePercentiles" : { + "0.0" : 0.43224321594052556, + "50.0" : 0.4372556124786848, + "90.0" : 0.4434983154020134, + "95.0" : 0.4434983154020134, + "99.0" : 0.4434983154020134, + "99.9" : 0.4434983154020134, + "99.99" : 0.4434983154020134, + "99.999" : 0.4434983154020134, + "99.9999" : 0.4434983154020134, + "100.0" : 0.4434983154020134 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4380310428821726, + 0.43682558900100465, + 0.43433328165038004 + ], + [ + 0.44269590252324037, + 0.4434983154020134, + 0.44286145321287806 + ], + [ + 0.4372556124786848, + 0.43224321594052556, + 0.43364223719699924 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.07028972787073305, + "scoreError" : 5.179855389906926E-4, + "scoreConfidence" : [ + 0.06977174233174235, + 0.07080771340972375 + ], + "scorePercentiles" : { + "0.0" : 0.06970817791269919, + "50.0" : 0.07033018202533248, + "90.0" : 0.07068447294240719, + "95.0" : 0.07068447294240719, + "99.0" : 0.07068447294240719, + "99.9" : 0.07068447294240719, + "99.99" : 0.07068447294240719, + "99.999" : 0.07068447294240719, + "99.9999" : 0.07068447294240719, + "100.0" : 0.07068447294240719 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06994119092314256, + 0.06970817791269919, + 0.07017967310904319 + ], + [ + 0.07031189624963087, + 0.07056519143351092, + 0.07033018202533248 + ], + [ + 0.0705037038261691, + 0.07038306241466195, + 0.07068447294240719 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 2.6797161614550885E7, + "scoreError" : 1219300.8546828355, + "scoreConfidence" : [ + 2.5577860759868048E7, + 2.801646246923372E7 + ], + "scorePercentiles" : { + "0.0" : 2.616316707310705E7, + "50.0" : 2.6336108715789475E7, + "90.0" : 2.7772019864265926E7, + "95.0" : 2.7772019864265926E7, + "99.0" : 2.7772019864265926E7, + "99.9" : 2.7772019864265926E7, + "99.99" : 2.7772019864265926E7, + "99.999" : 2.7772019864265926E7, + "99.9999" : 2.7772019864265926E7, + "100.0" : 2.7772019864265926E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2.7772019864265926E7, + 2.770387028531856E7, + 2.7753106371191137E7 + ], + [ + 2.6267871010498688E7, + 2.616316707310705E7, + 2.6336108715789475E7 + ], + [ + 2.620666960209424E7, + 2.6275712790026248E7, + 2.6695928818666667E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-25T01:23:55Z-2f880f3c1b28bc9004d94aea79dd7609f3b3d513-jdk17.json b/performance-results/2025-02-25T01:23:55Z-2f880f3c1b28bc9004d94aea79dd7609f3b3d513-jdk17.json new file mode 100644 index 0000000000..9ff60cd618 --- /dev/null +++ b/performance-results/2025-02-25T01:23:55Z-2f880f3c1b28bc9004d94aea79dd7609f3b3d513-jdk17.json @@ -0,0 +1,665 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.404690960666666, + "scoreError" : 0.03044852968952923, + "scoreConfidence" : [ + 3.374242430977137, + 3.4351394903561956 + ], + "scorePercentiles" : { + "0.0" : 3.400213854643417, + "50.0" : 3.4045940175499285, + "90.0" : 3.4093619529233923, + "95.0" : 3.4093619529233923, + "99.0" : 3.4093619529233923, + "99.9" : 3.4093619529233923, + "99.99" : 3.4093619529233923, + "99.999" : 3.4093619529233923, + "99.9999" : 3.4093619529233923, + "100.0" : 3.4093619529233923 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4010779262103115, + 3.4093619529233923 + ], + [ + 3.400213854643417, + 3.4081101088895456 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7196934301008682, + "scoreError" : 0.009433261921329341, + "scoreConfidence" : [ + 1.7102601681795389, + 1.7291266920221975 + ], + "scorePercentiles" : { + "0.0" : 1.718360312679651, + "50.0" : 1.7193343356815178, + "90.0" : 1.7217447363607858, + "95.0" : 1.7217447363607858, + "99.0" : 1.7217447363607858, + "99.9" : 1.7217447363607858, + "99.99" : 1.7217447363607858, + "99.999" : 1.7217447363607858, + "99.9999" : 1.7217447363607858, + "100.0" : 1.7217447363607858 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.718360312679651, + 1.7196083418321035 + ], + [ + 1.7190603295309321, + 1.7217447363607858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8631208369410628, + "scoreError" : 0.013966265434022882, + "scoreConfidence" : [ + 0.8491545715070399, + 0.8770871023750857 + ], + "scorePercentiles" : { + "0.0" : 0.8611588039727823, + "50.0" : 0.8627513593861174, + "90.0" : 0.8658218250192341, + "95.0" : 0.8658218250192341, + "99.0" : 0.8658218250192341, + "99.9" : 0.8658218250192341, + "99.99" : 0.8658218250192341, + "99.999" : 0.8658218250192341, + "99.9999" : 0.8658218250192341, + "100.0" : 0.8658218250192341 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8611588039727823, + 0.8616121378539223 + ], + [ + 0.8638905809183123, + 0.8658218250192341 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 98.27096987223166, + "scoreError" : 2.5045477559708336, + "scoreConfidence" : [ + 95.76642211626083, + 100.7755176282025 + ], + "scorePercentiles" : { + "0.0" : 95.68051247255123, + "50.0" : 98.9270899531805, + "90.0" : 100.39260288227369, + "95.0" : 100.39260288227369, + "99.0" : 100.39260288227369, + "99.9" : 100.39260288227369, + "99.99" : 100.39260288227369, + "99.999" : 100.39260288227369, + "99.9999" : 100.39260288227369, + "100.0" : 100.39260288227369 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 98.94312506760458, + 96.69698833361956, + 95.68051247255123 + ], + [ + 97.34514063006868, + 98.9270899531805, + 99.06264023901753 + ], + [ + 97.87215469667093, + 99.5184745750984, + 100.39260288227369 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18459150246144512, + "scoreError" : 0.015563152229965621, + "scoreConfidence" : [ + 0.1690283502314795, + 0.20015465469141075 + ], + "scorePercentiles" : { + "0.0" : 0.17348002208344177, + "50.0" : 0.18480328357326337, + "90.0" : 0.195657021150046, + "95.0" : 0.195657021150046, + "99.0" : 0.195657021150046, + "99.9" : 0.195657021150046, + "99.99" : 0.195657021150046, + "99.999" : 0.195657021150046, + "99.9999" : 0.195657021150046, + "100.0" : 0.195657021150046 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17405713295854075, + 0.17348002208344177, + 0.17388261548225556 + ], + [ + 0.18486138387311446, + 0.18480328357326337, + 0.18468698899292665 + ], + [ + 0.195657021150046, + 0.19494815564263018, + 0.19494691839678735 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.34461395648434884, + "scoreError" : 0.018543995661311215, + "scoreConfidence" : [ + 0.32606996082303763, + 0.36315795214566005 + ], + "scorePercentiles" : { + "0.0" : 0.33486547773238684, + "50.0" : 0.33847169561685564, + "90.0" : 0.35935824540031625, + "95.0" : 0.35935824540031625, + "99.0" : 0.35935824540031625, + "99.9" : 0.35935824540031625, + "99.99" : 0.35935824540031625, + "99.999" : 0.35935824540031625, + "99.9999" : 0.35935824540031625, + "100.0" : 0.35935824540031625 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3397393252250722, + 0.33774711324259515, + 0.33847169561685564 + ], + [ + 0.33581736851472516, + 0.33486547773238684, + 0.33725926642385 + ], + [ + 0.3590065454676001, + 0.3592605707357379, + 0.35935824540031625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1662644528201741, + "scoreError" : 0.007041908485461542, + "scoreConfidence" : [ + 0.15922254433471256, + 0.17330636130563565 + ], + "scorePercentiles" : { + "0.0" : 0.16043068409991498, + "50.0" : 0.16863301156790664, + "90.0" : 0.16965664430646038, + "95.0" : 0.16965664430646038, + "99.0" : 0.16965664430646038, + "99.9" : 0.16965664430646038, + "99.99" : 0.16965664430646038, + "99.999" : 0.16965664430646038, + "99.9999" : 0.16965664430646038, + "100.0" : 0.16965664430646038 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16937442495172927, + 0.16863301156790664, + 0.16815488644694804 + ], + [ + 0.16933125113026398, + 0.16909790911243003, + 0.16965664430646038 + ], + [ + 0.16098464717719216, + 0.16071661658872122, + 0.16043068409991498 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3986439231800467, + "scoreError" : 0.00637091300263217, + "scoreConfidence" : [ + 0.39227301017741456, + 0.40501483618267886 + ], + "scorePercentiles" : { + "0.0" : 0.39420818677073477, + "50.0" : 0.3977881543754972, + "90.0" : 0.40496893557139385, + "95.0" : 0.40496893557139385, + "99.0" : 0.40496893557139385, + "99.9" : 0.40496893557139385, + "99.99" : 0.40496893557139385, + "99.999" : 0.40496893557139385, + "99.9999" : 0.40496893557139385, + "100.0" : 0.40496893557139385 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40496893557139385, + 0.39927211874151564, + 0.3992613548528766 + ], + [ + 0.40407144094710895, + 0.3971080157646031, + 0.3967713057451198 + ], + [ + 0.3977881543754972, + 0.3943457958515714, + 0.39420818677073477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16648713306207816, + "scoreError" : 0.005414247074119306, + "scoreConfidence" : [ + 0.16107288598795885, + 0.17190138013619746 + ], + "scorePercentiles" : { + "0.0" : 0.16283060862981355, + "50.0" : 0.16614479812261174, + "90.0" : 0.1708238147110572, + "95.0" : 0.1708238147110572, + "99.0" : 0.1708238147110572, + "99.9" : 0.1708238147110572, + "99.99" : 0.1708238147110572, + "99.999" : 0.1708238147110572, + "99.9999" : 0.1708238147110572, + "100.0" : 0.1708238147110572 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17022843914479283, + 0.1708238147110572, + 0.17013370232566052 + ], + [ + 0.16572026116929603, + 0.16614479812261174, + 0.16627377380576294 + ], + [ + 0.1633060520772095, + 0.16283060862981355, + 0.1629227475724992 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048708404283641024, + "scoreError" : 3.256900826240487E-4, + "scoreConfidence" : [ + 0.048382714201016974, + 0.049034094366265074 + ], + "scorePercentiles" : { + "0.0" : 0.04842643591134269, + "50.0" : 0.04864128523274478, + "90.0" : 0.04892708317962317, + "95.0" : 0.04892708317962317, + "99.0" : 0.04892708317962317, + "99.9" : 0.04892708317962317, + "99.99" : 0.04892708317962317, + "99.999" : 0.04892708317962317, + "99.9999" : 0.04892708317962317, + "100.0" : 0.04892708317962317 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.048913571263665044, + 0.04851722961938724, + 0.04856391890421869 + ], + [ + 0.04892708317962317, + 0.04887132461807626, + 0.04889490055397192 + ], + [ + 0.048619889269739404, + 0.04864128523274478, + 0.04842643591134269 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.0553918135524623E7, + "scoreError" : 679622.1646854198, + "scoreConfidence" : [ + 9874295.970839202, + 1.1233540300210044E7 + ], + "scorePercentiles" : { + "0.0" : 1.0047981846385542E7, + "50.0" : 1.0525982719242902E7, + "90.0" : 1.1121641787777778E7, + "95.0" : 1.1121641787777778E7, + "99.0" : 1.1121641787777778E7, + "99.9" : 1.1121641787777778E7, + "99.99" : 1.1121641787777778E7, + "99.999" : 1.1121641787777778E7, + "99.9999" : 1.1121641787777778E7, + "100.0" : 1.1121641787777778E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1.0205105657142857E7, + 1.0095831249243189E7, + 1.0047981846385542E7 + ], + [ + 1.0493827069254985E7, + 1.0525982719242902E7, + 1.0534360494736843E7 + ], + [ + 1.0856959726681128E7, + 1.1103572669256382E7, + 1.1121641787777778E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-26T21:08:56Z-6f33577a109177a85edb84a8f9d16c4662a8b867-jdk17.json b/performance-results/2025-02-26T21:08:56Z-6f33577a109177a85edb84a8f9d16c4662a8b867-jdk17.json new file mode 100644 index 0000000000..7955929f2c --- /dev/null +++ b/performance-results/2025-02-26T21:08:56Z-6f33577a109177a85edb84a8f9d16c4662a8b867-jdk17.json @@ -0,0 +1,665 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4146001038397236, + "scoreError" : 0.06330522138552402, + "scoreConfidence" : [ + 3.3512948824541997, + 3.4779053252252474 + ], + "scorePercentiles" : { + "0.0" : 3.406498306401554, + "50.0" : 3.4121721428099234, + "90.0" : 3.4275578233374935, + "95.0" : 3.4275578233374935, + "99.0" : 3.4275578233374935, + "99.9" : 3.4275578233374935, + "99.99" : 3.4275578233374935, + "99.999" : 3.4275578233374935, + "99.9999" : 3.4275578233374935, + "100.0" : 3.4275578233374935 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.406498306401554, + 3.4075577224157994 + ], + [ + 3.4167865632040475, + 3.4275578233374935 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.724084373375287, + "scoreError" : 0.009173345534947237, + "scoreConfidence" : [ + 1.7149110278403399, + 1.7332577189102343 + ], + "scorePercentiles" : { + "0.0" : 1.722132522557934, + "50.0" : 1.7244104377307181, + "90.0" : 1.725384095481778, + "95.0" : 1.725384095481778, + "99.0" : 1.725384095481778, + "99.9" : 1.725384095481778, + "99.99" : 1.725384095481778, + "99.999" : 1.725384095481778, + "99.9999" : 1.725384095481778, + "100.0" : 1.725384095481778 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7240017613168217, + 1.722132522557934 + ], + [ + 1.725384095481778, + 1.7248191141446145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8685933549611762, + "scoreError" : 0.0035669294749559304, + "scoreConfidence" : [ + 0.8650264254862202, + 0.8721602844361321 + ], + "scorePercentiles" : { + "0.0" : 0.8679462300764225, + "50.0" : 0.8686644140845527, + "90.0" : 0.8690983615991764, + "95.0" : 0.8690983615991764, + "99.0" : 0.8690983615991764, + "99.9" : 0.8690983615991764, + "99.99" : 0.8690983615991764, + "99.999" : 0.8690983615991764, + "99.9999" : 0.8690983615991764, + "100.0" : 0.8690983615991764 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8679462300764225, + 0.869003652537736 + ], + [ + 0.8683251756313696, + 0.8690983615991764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.03131562635369, + "scoreError" : 3.8131574268555535, + "scoreConfidence" : [ + 100.21815819949813, + 107.84447305320924 + ], + "scorePercentiles" : { + "0.0" : 101.2345222399038, + "50.0" : 104.32314641078156, + "90.0" : 107.1723185797236, + "95.0" : 107.1723185797236, + "99.0" : 107.1723185797236, + "99.9" : 107.1723185797236, + "99.99" : 107.1723185797236, + "99.999" : 107.1723185797236, + "99.9999" : 107.1723185797236, + "100.0" : 107.1723185797236 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 103.72396500224156, + 104.42774438643247, + 104.32314641078156 + ], + [ + 101.2345222399038, + 101.61710742984098, + 101.3750069855028 + ], + [ + 105.55519565109971, + 107.1723185797236, + 106.85283395165672 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18162770750824003, + "scoreError" : 0.006044886405865979, + "scoreConfidence" : [ + 0.17558282110237405, + 0.187672593914106 + ], + "scorePercentiles" : { + "0.0" : 0.17692104912957327, + "50.0" : 0.1825373323354933, + "90.0" : 0.18598964871298915, + "95.0" : 0.18598964871298915, + "99.0" : 0.18598964871298915, + "99.9" : 0.18598964871298915, + "99.99" : 0.18598964871298915, + "99.999" : 0.18598964871298915, + "99.9999" : 0.18598964871298915, + "100.0" : 0.18598964871298915 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18334443915809545, + 0.1825373323354933, + 0.1824438548310589 + ], + [ + 0.17756069605823863, + 0.17692104912957327, + 0.17704654118938443 + ], + [ + 0.18598964871298915, + 0.1859790866266203, + 0.18282671953270685 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33103155204854806, + "scoreError" : 0.010016052614272533, + "scoreConfidence" : [ + 0.32101549943427554, + 0.3410476046628206 + ], + "scorePercentiles" : { + "0.0" : 0.32390096534300705, + "50.0" : 0.33049450798109653, + "90.0" : 0.3382305706893053, + "95.0" : 0.3382305706893053, + "99.0" : 0.3382305706893053, + "99.9" : 0.3382305706893053, + "99.99" : 0.3382305706893053, + "99.999" : 0.3382305706893053, + "99.9999" : 0.3382305706893053, + "100.0" : 0.3382305706893053 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33280675099840257, + 0.33049450798109653, + 0.33046942586167016 + ], + [ + 0.3243713012325657, + 0.32400376565689293, + 0.32390096534300705 + ], + [ + 0.33713828767446563, + 0.3382305706893053, + 0.337868392999527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1651612001317232, + "scoreError" : 0.006671777327387482, + "scoreConfidence" : [ + 0.1584894228043357, + 0.1718329774591107 + ], + "scorePercentiles" : { + "0.0" : 0.15975479700305126, + "50.0" : 0.16664202561239794, + "90.0" : 0.16899561237008873, + "95.0" : 0.16899561237008873, + "99.0" : 0.16899561237008873, + "99.9" : 0.16899561237008873, + "99.99" : 0.16899561237008873, + "99.999" : 0.16899561237008873, + "99.9999" : 0.16899561237008873, + "100.0" : 0.16899561237008873 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1686909112378125, + 0.16899561237008873, + 0.16836642324398948 + ], + [ + 0.16008070533055868, + 0.16014325713828167, + 0.15975479700305126 + ], + [ + 0.16664202561239794, + 0.16726839185414402, + 0.16650867739518466 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39718276540797226, + "scoreError" : 0.010495068770156386, + "scoreConfidence" : [ + 0.3866876966378159, + 0.40767783417812864 + ], + "scorePercentiles" : { + "0.0" : 0.39033811225605, + "50.0" : 0.39952032495705325, + "90.0" : 0.4070250141641906, + "95.0" : 0.4070250141641906, + "99.0" : 0.4070250141641906, + "99.9" : 0.4070250141641906, + "99.99" : 0.4070250141641906, + "99.999" : 0.4070250141641906, + "99.9999" : 0.4070250141641906, + "100.0" : 0.4070250141641906 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39952032495705325, + 0.39207139022190857, + 0.39109308951896754 + ], + [ + 0.39983248678581423, + 0.39033811225605, + 0.3905832244180597 + ], + [ + 0.4070250141641906, + 0.40276224173345687, + 0.4014190046162492 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16230465175803965, + "scoreError" : 0.0039183994711270995, + "scoreConfidence" : [ + 0.15838625228691255, + 0.16622305122916675 + ], + "scorePercentiles" : { + "0.0" : 0.1597745644442314, + "50.0" : 0.16203763755975045, + "90.0" : 0.16624055238966004, + "95.0" : 0.16624055238966004, + "99.0" : 0.16624055238966004, + "99.9" : 0.16624055238966004, + "99.99" : 0.16624055238966004, + "99.999" : 0.16624055238966004, + "99.9999" : 0.16624055238966004, + "100.0" : 0.16624055238966004 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16624055238966004, + 0.16400418776547765, + 0.16484738292891996 + ], + [ + 0.15981138290051938, + 0.1598962359854178, + 0.1597745644442314 + ], + [ + 0.16191029436241175, + 0.16203763755975045, + 0.16221962748596827 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04763327336182691, + "scoreError" : 4.3904494906094033E-4, + "scoreConfidence" : [ + 0.04719422841276597, + 0.04807231831088785 + ], + "scorePercentiles" : { + "0.0" : 0.04727598728767486, + "50.0" : 0.04777726915010009, + "90.0" : 0.04794205962950889, + "95.0" : 0.04794205962950889, + "99.0" : 0.04794205962950889, + "99.9" : 0.04794205962950889, + "99.99" : 0.04794205962950889, + "99.999" : 0.04794205962950889, + "99.9999" : 0.04794205962950889, + "100.0" : 0.04794205962950889 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04788952776833304, + 0.047806814378185084, + 0.04777726915010009 + ], + [ + 0.04794205962950889, + 0.047515909017908475, + 0.0477935064352863 + ], + [ + 0.04729572183939576, + 0.04740266475004977, + 0.04727598728767486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9672020.973374372, + "scoreError" : 191105.9680058244, + "scoreConfidence" : [ + 9480915.005368548, + 9863126.941380197 + ], + "scorePercentiles" : { + "0.0" : 9516544.845861085, + "50.0" : 9728260.992217898, + "90.0" : 9787208.828767123, + "95.0" : 9787208.828767123, + "99.0" : 9787208.828767123, + "99.9" : 9787208.828767123, + "99.99" : 9787208.828767123, + "99.999" : 9787208.828767123, + "99.9999" : 9787208.828767123, + "100.0" : 9787208.828767123 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9773146.44921875, + 9744554.864654332, + 9751680.31871345 + ], + [ + 9787208.828767123, + 9728260.992217898, + 9688269.999031946 + ], + [ + 9516544.845861085, + 9527939.308571428, + 9530583.153333334 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-27T00:02:35Z-c2d1a3b7a277ffb797f13873463e4c5566e6e28c-jdk17.json b/performance-results/2025-02-27T00:02:35Z-c2d1a3b7a277ffb797f13873463e4c5566e6e28c-jdk17.json new file mode 100644 index 0000000000..93a667cc19 --- /dev/null +++ b/performance-results/2025-02-27T00:02:35Z-c2d1a3b7a277ffb797f13873463e4c5566e6e28c-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.417549733621442, + "scoreError" : 0.01110297891536587, + "scoreConfidence" : [ + 3.406446754706076, + 3.428652712536808 + ], + "scorePercentiles" : { + "0.0" : 3.415335793926578, + "50.0" : 3.4177333996326036, + "90.0" : 3.419396341293982, + "95.0" : 3.419396341293982, + "99.0" : 3.419396341293982, + "99.9" : 3.419396341293982, + "99.99" : 3.419396341293982, + "99.999" : 3.419396341293982, + "99.9999" : 3.419396341293982, + "100.0" : 3.419396341293982 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4172446969186234, + 3.419396341293982 + ], + [ + 3.415335793926578, + 3.4182221023465837 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7274036461599989, + "scoreError" : 0.006128573825496412, + "scoreConfidence" : [ + 1.7212750723345025, + 1.7335322199854952 + ], + "scorePercentiles" : { + "0.0" : 1.726368585774484, + "50.0" : 1.7273860309105475, + "90.0" : 1.728473937044416, + "95.0" : 1.728473937044416, + "99.0" : 1.728473937044416, + "99.9" : 1.728473937044416, + "99.99" : 1.728473937044416, + "99.999" : 1.728473937044416, + "99.9999" : 1.728473937044416, + "100.0" : 1.728473937044416 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.727876395518843, + 1.728473937044416 + ], + [ + 1.726895666302252, + 1.726368585774484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8696277675660219, + "scoreError" : 0.003731430116841793, + "scoreConfidence" : [ + 0.8658963374491802, + 0.8733591976828636 + ], + "scorePercentiles" : { + "0.0" : 0.8687745341041557, + "50.0" : 0.8698516605045905, + "90.0" : 0.8700332151507507, + "95.0" : 0.8700332151507507, + "99.0" : 0.8700332151507507, + "99.9" : 0.8700332151507507, + "99.99" : 0.8700332151507507, + "99.999" : 0.8700332151507507, + "99.9999" : 0.8700332151507507, + "100.0" : 0.8700332151507507 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8687745341041557, + 0.8697897336521034 + ], + [ + 0.8699135873570777, + 0.8700332151507507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 68564.59072017718, + "scoreError" : 3342.4151922036704, + "scoreConfidence" : [ + 65222.17552797351, + 71907.00591238085 + ], + "scorePercentiles" : { + "0.0" : 66365.38880921605, + "50.0" : 68390.3393489677, + "90.0" : 70982.41269147139, + "95.0" : 70982.41269147139, + "99.0" : 70982.41269147139, + "99.9" : 70982.41269147139, + "99.99" : 70982.41269147139, + "99.999" : 70982.41269147139, + "99.9999" : 70982.41269147139, + "100.0" : 70982.41269147139 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70921.10080429926, + 70971.54880272943, + 70982.41269147139 + ], + [ + 66391.38054980467, + 66403.4487675499, + 66365.38880921605 + ], + [ + 68121.9882924485, + 68390.3393489677, + 68533.7084151077 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 352.6073517068847, + "scoreError" : 14.226277593346195, + "scoreConfidence" : [ + 338.3810741135385, + 366.8336293002309 + ], + "scorePercentiles" : { + "0.0" : 340.9222360811488, + "50.0" : 357.0779004844468, + "90.0" : 360.2449960648248, + "95.0" : 360.2449960648248, + "99.0" : 360.2449960648248, + "99.9" : 360.2449960648248, + "99.99" : 360.2449960648248, + "99.999" : 360.2449960648248, + "99.9999" : 360.2449960648248, + "100.0" : 360.2449960648248 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.2449960648248, + 357.0779004844468, + 355.97632825052636 + ], + [ + 341.52235438044806, + 341.8721856208501, + 340.9222360811488 + ], + [ + 359.11797705900995, + 357.9689783725373, + 358.76320904817004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 43.22957453296144, + "scoreError" : 1.0524067752181139, + "scoreConfidence" : [ + 42.17716775774333, + 44.28198130817956 + ], + "scorePercentiles" : { + "0.0" : 42.491759424373676, + "50.0" : 43.16580648696909, + "90.0" : 43.99113632712106, + "95.0" : 43.99113632712106, + "99.0" : 43.99113632712106, + "99.9" : 43.99113632712106, + "99.99" : 43.99113632712106, + "99.999" : 43.99113632712106, + "99.9999" : 43.99113632712106, + "100.0" : 43.99113632712106 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 42.491759424373676, + 42.55520495290065, + 42.53175908126641 + ], + [ + 43.95321369840156, + 43.96024421025855, + 43.99113632712106 + ], + [ + 43.16580648696909, + 43.14083248198754, + 43.27621413337447 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014312895471575268, + "scoreError" : 3.590636914352757E-4, + "scoreConfidence" : [ + 0.013953831780139992, + 0.014671959163010543 + ], + "scorePercentiles" : { + "0.0" : 0.014156584854911, + "50.0" : 0.014173242913814926, + "90.0" : 0.014606530733984486, + "95.0" : 0.014606530733984486, + "99.0" : 0.014606530733984486, + "99.9" : 0.014606530733984486, + "99.99" : 0.014606530733984486, + "99.999" : 0.014606530733984486, + "99.9999" : 0.014606530733984486, + "100.0" : 0.014606530733984486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014172841730880705, + 0.014173242913814926, + 0.01419092347350018 + ], + [ + 0.014597928211176914, + 0.014606530733984486, + 0.014587914766734694 + ], + [ + 0.014156584854911, + 0.014164157074343924, + 0.014165935484830585 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.051780842346681, + "scoreError" : 0.010553840560371822, + "scoreConfidence" : [ + 1.0412270017863092, + 1.0623346829070528 + ], + "scorePercentiles" : { + "0.0" : 1.0440643342728886, + "50.0" : 1.0495260304334137, + "90.0" : 1.061504448100191, + "95.0" : 1.061504448100191, + "99.0" : 1.061504448100191, + "99.9" : 1.061504448100191, + "99.99" : 1.061504448100191, + "99.999" : 1.061504448100191, + "99.9999" : 1.061504448100191, + "100.0" : 1.061504448100191 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0475535410076464, + 1.0495260304334137, + 1.0485825257418475 + ], + [ + 1.0462639663109436, + 1.0440643342728886, + 1.051101247950389 + ], + [ + 1.061504448100191, + 1.0594869623900838, + 1.0579445249127262 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013025928893002378, + "scoreError" : 2.9233162577219546E-4, + "scoreConfidence" : [ + 0.012733597267230182, + 0.013318260518774574 + ], + "scorePercentiles" : { + "0.0" : 0.012845165675472241, + "50.0" : 0.013048059291336388, + "90.0" : 0.013116028007302832, + "95.0" : 0.013116028007302832, + "99.0" : 0.013116028007302832, + "99.9" : 0.013116028007302832, + "99.99" : 0.013116028007302832, + "99.999" : 0.013116028007302832, + "99.9999" : 0.013116028007302832, + "100.0" : 0.013116028007302832 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012845165675472241, + 0.012994237794150132, + 0.012995796729287742 + ], + [ + 0.013104023298416284, + 0.013100321853385034, + 0.013116028007302832 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6386671189948117, + "scoreError" : 0.23283007966411665, + "scoreConfidence" : [ + 3.405837039330695, + 3.871497198658928 + ], + "scorePercentiles" : { + "0.0" : 3.5593792142348755, + "50.0" : 3.638552702472288, + "90.0" : 3.717080251857355, + "95.0" : 3.717080251857355, + "99.0" : 3.717080251857355, + "99.9" : 3.717080251857355, + "99.99" : 3.717080251857355, + "99.999" : 3.717080251857355, + "99.9999" : 3.717080251857355, + "100.0" : 3.717080251857355 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.714684306607275, + 3.717080251857355, + 3.711503275222552 + ], + [ + 3.5593792142348755, + 3.5656021297220244, + 3.5637535363247865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.892068432953975, + "scoreError" : 0.009267708162824911, + "scoreConfidence" : [ + 2.8828007247911502, + 2.9013361411167997 + ], + "scorePercentiles" : { + "0.0" : 2.8829103447679447, + "50.0" : 2.8941400842013887, + "90.0" : 2.900774136600928, + "95.0" : 2.900774136600928, + "99.0" : 2.900774136600928, + "99.9" : 2.900774136600928, + "99.99" : 2.900774136600928, + "99.999" : 2.900774136600928, + "99.9999" : 2.900774136600928, + "100.0" : 2.900774136600928 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8909567751445087, + 2.900774136600928, + 2.895437655761436 + ], + [ + 2.8829103447679447, + 2.8853761220427003, + 2.8949296243125904 + ], + [ + 2.894673690593343, + 2.889417463160936, + 2.8941400842013887 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33691360853923774, + "scoreError" : 0.019185202933204835, + "scoreConfidence" : [ + 0.3177284056060329, + 0.3560988114724426 + ], + "scorePercentiles" : { + "0.0" : 0.3215903219063545, + "50.0" : 0.34066744595469256, + "90.0" : 0.3475835746411317, + "95.0" : 0.3475835746411317, + "99.0" : 0.3475835746411317, + "99.9" : 0.3475835746411317, + "99.99" : 0.3475835746411317, + "99.999" : 0.3475835746411317, + "99.9999" : 0.3475835746411317, + "100.0" : 0.3475835746411317 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3230329570048777, + 0.32178376835703715, + 0.3215903219063545 + ], + [ + 0.3474673598554602, + 0.3475835746411317, + 0.34700911492418196 + ], + [ + 0.34260209705711053, + 0.34066744595469256, + 0.3404858371522931 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.5147195619121575, + "scoreError" : 0.005365502061905538, + "scoreConfidence" : [ + 0.509354059850252, + 0.5200850639740631 + ], + "scorePercentiles" : { + "0.0" : 0.5095666566114649, + "50.0" : 0.5141572140359897, + "90.0" : 0.5199076203275279, + "95.0" : 0.5199076203275279, + "99.0" : 0.5199076203275279, + "99.9" : 0.5199076203275279, + "99.99" : 0.5199076203275279, + "99.999" : 0.5199076203275279, + "99.9999" : 0.5199076203275279, + "100.0" : 0.5199076203275279 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.5095666566114649, + 0.5120266715989965, + 0.5134771368864243 + ], + [ + 0.5141572140359897, + 0.5143587923053183, + 0.5136087965692568 + ], + [ + 0.5199076203275279, + 0.5176240380434782, + 0.5177491308309604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.2364564205155297, + "scoreError" : 0.005615719741969599, + "scoreConfidence" : [ + 0.23084070077356011, + 0.2420721402574993 + ], + "scorePercentiles" : { + "0.0" : 0.23106783016775267, + "50.0" : 0.23710881167014417, + "90.0" : 0.2401375854624916, + "95.0" : 0.2401375854624916, + "99.0" : 0.2401375854624916, + "99.9" : 0.2401375854624916, + "99.99" : 0.2401375854624916, + "99.999" : 0.2401375854624916, + "99.9999" : 0.2401375854624916, + "100.0" : 0.2401375854624916 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.2401375854624916, + 0.23965306583109663, + 0.2394539756961904 + ], + [ + 0.23547254910640703, + 0.23145445165023376, + 0.23106783016775267 + ], + [ + 0.23750379399610508, + 0.23710881167014417, + 0.23625572105934606 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.039934086864828, + "scoreError" : 0.014696474985303161, + "scoreConfidence" : [ + 1.0252376118795248, + 1.054630561850131 + ], + "scorePercentiles" : { + "0.0" : 1.0283595919794344, + "50.0" : 1.043634660857769, + "90.0" : 1.0487148862206377, + "95.0" : 1.0487148862206377, + "99.0" : 1.0487148862206377, + "99.9" : 1.0487148862206377, + "99.99" : 1.0487148862206377, + "99.999" : 1.0487148862206377, + "99.9999" : 1.0487148862206377, + "100.0" : 1.0487148862206377 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0287253541816685, + 1.0284066072603866, + 1.0283595919794344 + ], + [ + 1.0434719802796326, + 1.043634660857769, + 1.0443083778195488 + ], + [ + 1.0487148862206377, + 1.046657566509681, + 1.0471277566746937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.44161499542324184, + "scoreError" : 0.004366581579714742, + "scoreConfidence" : [ + 0.4372484138435271, + 0.4459815770029566 + ], + "scorePercentiles" : { + "0.0" : 0.43823696555501995, + "50.0" : 0.44111343381412377, + "90.0" : 0.44522993410800943, + "95.0" : 0.44522993410800943, + "99.0" : 0.44522993410800943, + "99.9" : 0.44522993410800943, + "99.99" : 0.44522993410800943, + "99.999" : 0.44522993410800943, + "99.9999" : 0.44522993410800943, + "100.0" : 0.44522993410800943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4385348860726188, + 0.43823696555501995, + 0.4400182119065429 + ], + [ + 0.44461083727547573, + 0.4443986759098787, + 0.44522993410800943 + ], + [ + 0.44149149507748003, + 0.44111343381412377, + 0.4409005190900273 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.07051290382076661, + "scoreError" : 0.0015072824781688767, + "scoreConfidence" : [ + 0.06900562134259773, + 0.07202018629893549 + ], + "scorePercentiles" : { + "0.0" : 0.06945675739875119, + "50.0" : 0.07009593459457186, + "90.0" : 0.07172936275867016, + "95.0" : 0.07172936275867016, + "99.0" : 0.07172936275867016, + "99.9" : 0.07172936275867016, + "99.99" : 0.07172936275867016, + "99.999" : 0.07172936275867016, + "99.9999" : 0.07172936275867016, + "100.0" : 0.07172936275867016 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.07009593459457186, + 0.07000790423051882, + 0.06975306674571898 + ], + [ + 0.07172936275867016, + 0.0716311333968454, + 0.07164192272864041 + ], + [ + 0.07030226510597912, + 0.0699977874272035, + 0.06945675739875119 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 2.2916434512089096E7, + "scoreError" : 334761.1993547782, + "scoreConfidence" : [ + 2.2581673312734317E7, + 2.3251195711443875E7 + ], + "scorePercentiles" : { + "0.0" : 2.2709041746031746E7, + "50.0" : 2.286806340410959E7, + "90.0" : 2.321051393039443E7, + "95.0" : 2.321051393039443E7, + "99.0" : 2.321051393039443E7, + "99.9" : 2.321051393039443E7, + "99.99" : 2.321051393039443E7, + "99.999" : 2.321051393039443E7, + "99.9999" : 2.321051393039443E7, + "100.0" : 2.321051393039443E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2.321051393039443E7, + 2.3181100655092593E7, + 2.310629179907621E7 + ], + [ + 2.2853278180365298E7, + 2.286806340410959E7, + 2.2868454625570778E7 + ], + [ + 2.2739949259090908E7, + 2.2709041746031746E7, + 2.2711217009070296E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-27T01:25:55Z-31804cdc79dd4fa2c8b6ddd9fac1a4168e510fc2-jdk17.json b/performance-results/2025-02-27T01:25:55Z-31804cdc79dd4fa2c8b6ddd9fac1a4168e510fc2-jdk17.json new file mode 100644 index 0000000000..e07aecac38 --- /dev/null +++ b/performance-results/2025-02-27T01:25:55Z-31804cdc79dd4fa2c8b6ddd9fac1a4168e510fc2-jdk17.json @@ -0,0 +1,413 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70219.54876920363, + "scoreError" : 877.051607001723, + "scoreConfidence" : [ + 69342.49716220191, + 71096.60037620534 + ], + "scorePercentiles" : { + "0.0" : 69373.1799451383, + "50.0" : 70346.02467738034, + "90.0" : 70806.15426297102, + "95.0" : 70806.15426297102, + "99.0" : 70806.15426297102, + "99.9" : 70806.15426297102, + "99.99" : 70806.15426297102, + "99.999" : 70806.15426297102, + "99.9999" : 70806.15426297102, + "100.0" : 70806.15426297102 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69518.78115218057, + 69373.1799451383, + 69976.66849523893 + ], + [ + 70806.15426297102, + 70725.87117127908, + 70610.372758707 + ], + [ + 70561.85379402456, + 70057.03266591279, + 70346.02467738034 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 346.9107894426578, + "scoreError" : 9.426249005233789, + "scoreConfidence" : [ + 337.484540437424, + 356.3370384478916 + ], + "scorePercentiles" : { + "0.0" : 338.26005679797504, + "50.0" : 347.03501349459947, + "90.0" : 354.57859781312527, + "95.0" : 354.57859781312527, + "99.0" : 354.57859781312527, + "99.9" : 354.57859781312527, + "99.99" : 354.57859781312527, + "99.999" : 354.57859781312527, + "99.9999" : 354.57859781312527, + "100.0" : 354.57859781312527 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 338.26005679797504, + 340.50631789283403, + 343.88528415142383 + ], + [ + 353.56875541193926, + 351.6138386462634, + 354.57859781312527 + ], + [ + 347.03976687575766, + 345.7094739000024, + 347.03501349459947 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014352362665403752, + "scoreError" : 2.98599213348489E-4, + "scoreConfidence" : [ + 0.014053763452055263, + 0.01465096187875224 + ], + "scorePercentiles" : { + "0.0" : 0.014157780336214879, + "50.0" : 0.014331860724752957, + "90.0" : 0.014639790268461288, + "95.0" : 0.014639790268461288, + "99.0" : 0.014639790268461288, + "99.9" : 0.014639790268461288, + "99.99" : 0.014639790268461288, + "99.999" : 0.014639790268461288, + "99.9999" : 0.014639790268461288, + "100.0" : 0.014639790268461288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014339939093238652, + 0.014331860724752957, + 0.014260492186764702 + ], + [ + 0.014538310723621276, + 0.014639790268461288, + 0.014531535512455552 + ], + [ + 0.014157780336214879, + 0.01420724729817084, + 0.014164307844953598 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.056255119077973, + "scoreError" : 0.07030724285344893, + "scoreConfidence" : [ + 0.9859478762245241, + 1.126562361931422 + ], + "scorePercentiles" : { + "0.0" : 1.0189330812022415, + "50.0" : 1.0329520149762446, + "90.0" : 1.1164261720250055, + "95.0" : 1.1164261720250055, + "99.0" : 1.1164261720250055, + "99.9" : 1.1164261720250055, + "99.99" : 1.1164261720250055, + "99.999" : 1.1164261720250055, + "99.9999" : 1.1164261720250055, + "100.0" : 1.1164261720250055 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0477812422210582, + 1.0329520149762446, + 1.0309344408823833 + ], + [ + 1.1030785476505625, + 1.1164261720250055, + 1.1125569858716209 + ], + [ + 1.0189330812022415, + 1.0217059660878447, + 1.0219276207847947 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013035694974636735, + "scoreError" : 3.80344969049074E-4, + "scoreConfidence" : [ + 0.01265535000558766, + 0.01341603994368581 + ], + "scorePercentiles" : { + "0.0" : 0.012849147604975074, + "50.0" : 0.013023318203321078, + "90.0" : 0.013215352230829614, + "95.0" : 0.013215352230829614, + "99.0" : 0.013215352230829614, + "99.9" : 0.013215352230829614, + "99.99" : 0.013215352230829614, + "99.999" : 0.013215352230829614, + "99.9999" : 0.013215352230829614, + "100.0" : 0.013215352230829614 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012849147604975074, + 0.012976139697715217, + 0.012952399375191043 + ], + [ + 0.013150634230182525, + 0.013215352230829614, + 0.013070496708926937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6779970045280823, + "scoreError" : 0.14690336575784563, + "scoreConfidence" : [ + 3.5310936387702365, + 3.824900370285928 + ], + "scorePercentiles" : { + "0.0" : 3.5989308258992807, + "50.0" : 3.6785783035306947, + "90.0" : 3.754549879129129, + "95.0" : 3.754549879129129, + "99.0" : 3.754549879129129, + "99.9" : 3.754549879129129, + "99.99" : 3.754549879129129, + "99.999" : 3.754549879129129, + "99.9999" : 3.754549879129129, + "100.0" : 3.754549879129129 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5989308258992807, + 3.658934260424287, + 3.6582162809070957 + ], + [ + 3.698222346637103, + 3.754549879129129, + 3.6991284341715978 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.884272532819487, + "scoreError" : 0.12828739230038708, + "scoreConfidence" : [ + 2.7559851405191, + 3.012559925119874 + ], + "scorePercentiles" : { + "0.0" : 2.7761082681099083, + "50.0" : 2.9086586077348064, + "90.0" : 3.0072171803968732, + "95.0" : 3.0072171803968732, + "99.0" : 3.0072171803968732, + "99.9" : 3.0072171803968732, + "99.99" : 3.0072171803968732, + "99.999" : 3.0072171803968732, + "99.9999" : 3.0072171803968732, + "100.0" : 3.0072171803968732 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9186964487890283, + 2.923129876972531, + 2.9086586077348064 + ], + [ + 2.897631711761298, + 2.927875331967213, + 3.0072171803968732 + ], + [ + 2.7761082681099083, + 2.8062966290684623, + 2.792838740575258 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-27T19:41:06Z-11211e11a54c35e1e9ffe9900e7ec7baad92d55c-jdk17.json b/performance-results/2025-02-27T19:41:06Z-11211e11a54c35e1e9ffe9900e7ec7baad92d55c-jdk17.json new file mode 100644 index 0000000000..34f194c1bf --- /dev/null +++ b/performance-results/2025-02-27T19:41:06Z-11211e11a54c35e1e9ffe9900e7ec7baad92d55c-jdk17.json @@ -0,0 +1,665 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.424204324807343, + "scoreError" : 0.05799769532538598, + "scoreConfidence" : [ + 3.366206629481957, + 3.482202020132729 + ], + "scorePercentiles" : { + "0.0" : 3.4159836041695884, + "50.0" : 3.4237277918290836, + "90.0" : 3.433378111401614, + "95.0" : 3.433378111401614, + "99.0" : 3.433378111401614, + "99.9" : 3.433378111401614, + "99.99" : 3.433378111401614, + "99.999" : 3.433378111401614, + "99.9999" : 3.433378111401614, + "100.0" : 3.433378111401614 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4159836041695884, + 3.417039358674823 + ], + [ + 3.430416224983344, + 3.433378111401614 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.728024357619412, + "scoreError" : 0.005667731146331268, + "scoreConfidence" : [ + 1.7223566264730807, + 1.7336920887657434 + ], + "scorePercentiles" : { + "0.0" : 1.7270563159253658, + "50.0" : 1.728063700679468, + "90.0" : 1.7289137131933463, + "95.0" : 1.7289137131933463, + "99.0" : 1.7289137131933463, + "99.9" : 1.7289137131933463, + "99.99" : 1.7289137131933463, + "99.999" : 1.7289137131933463, + "99.9999" : 1.7289137131933463, + "100.0" : 1.7289137131933463 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7286006804391694, + 1.7275267209197662 + ], + [ + 1.7270563159253658, + 1.7289137131933463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8687373037199976, + "scoreError" : 0.007828251353031416, + "scoreConfidence" : [ + 0.8609090523669661, + 0.876565555073029 + ], + "scorePercentiles" : { + "0.0" : 0.8677172931089318, + "50.0" : 0.8683724801432033, + "90.0" : 0.8704869614846519, + "95.0" : 0.8704869614846519, + "99.0" : 0.8704869614846519, + "99.9" : 0.8704869614846519, + "99.99" : 0.8704869614846519, + "99.999" : 0.8704869614846519, + "99.9999" : 0.8704869614846519, + "100.0" : 0.8704869614846519 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8677172931089318, + 0.8685043429446764 + ], + [ + 0.8682406173417304, + 0.8704869614846519 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.1436562038279, + "scoreError" : 5.6105425024585065, + "scoreConfidence" : [ + 101.5331137013694, + 112.7541987062864 + ], + "scorePercentiles" : { + "0.0" : 102.50973848385428, + "50.0" : 109.21468173090412, + "90.0" : 109.90699541456834, + "95.0" : 109.90699541456834, + "99.0" : 109.90699541456834, + "99.9" : 109.90699541456834, + "99.99" : 109.90699541456834, + "99.999" : 109.90699541456834, + "99.9999" : 109.90699541456834, + "100.0" : 109.90699541456834 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.21468173090412, + 109.27836917733696, + 109.90699541456834 + ], + [ + 102.50973848385428, + 102.60092263928637, + 103.01205226543857 + ], + [ + 108.97543715441627, + 109.36582665700297, + 109.4288823116432 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18715525560681903, + "scoreError" : 0.020286238893373214, + "scoreConfidence" : [ + 0.1668690167134458, + 0.20744149450019225 + ], + "scorePercentiles" : { + "0.0" : 0.17607753671162446, + "50.0" : 0.18194778879953422, + "90.0" : 0.20298734608748603, + "95.0" : 0.20298734608748603, + "99.0" : 0.20298734608748603, + "99.9" : 0.20298734608748603, + "99.99" : 0.20298734608748603, + "99.999" : 0.20298734608748603, + "99.9999" : 0.20298734608748603, + "100.0" : 0.20298734608748603 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18297718427167767, + 0.18194778879953422, + 0.18188762704619862 + ], + [ + 0.20298734608748603, + 0.2028440355780933, + 0.20278723644401184 + ], + [ + 0.1767823894427945, + 0.17607753671162446, + 0.1761061560799507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33746284165580004, + "scoreError" : 0.009801170575544799, + "scoreConfidence" : [ + 0.32766167108025523, + 0.34726401223134484 + ], + "scorePercentiles" : { + "0.0" : 0.33322743102299235, + "50.0" : 0.3339327810131232, + "90.0" : 0.3462359468891736, + "95.0" : 0.3462359468891736, + "99.0" : 0.3462359468891736, + "99.9" : 0.3462359468891736, + "99.99" : 0.3462359468891736, + "99.999" : 0.3462359468891736, + "99.9999" : 0.3462359468891736, + "100.0" : 0.3462359468891736 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3339327810131232, + 0.333327132728909, + 0.33331685544297046 + ], + [ + 0.3462359468891736, + 0.3447156930368838, + 0.34466495712562467 + ], + [ + 0.3342104271439075, + 0.3335343504986159, + 0.33322743102299235 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1626035761133484, + "scoreError" : 0.009923728597793184, + "scoreConfidence" : [ + 0.15267984751555522, + 0.1725273047111416 + ], + "scorePercentiles" : { + "0.0" : 0.15574798043857463, + "50.0" : 0.16241545803287208, + "90.0" : 0.16958445535789993, + "95.0" : 0.16958445535789993, + "99.0" : 0.16958445535789993, + "99.9" : 0.16958445535789993, + "99.99" : 0.16958445535789993, + "99.999" : 0.16958445535789993, + "99.9999" : 0.16958445535789993, + "100.0" : 0.16958445535789993 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16958445535789993, + 0.16957912419663904, + 0.16929908774632627 + ], + [ + 0.16241545803287208, + 0.16258103080849956, + 0.1624111286765303 + ], + [ + 0.15574798043857463, + 0.15582760495520062, + 0.1559863148075933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3948568791221134, + "scoreError" : 0.005118335017259271, + "scoreConfidence" : [ + 0.38973854410485415, + 0.3999752141393727 + ], + "scorePercentiles" : { + "0.0" : 0.39062994046875, + "50.0" : 0.3952583020829216, + "90.0" : 0.3990008796680498, + "95.0" : 0.3990008796680498, + "99.0" : 0.3990008796680498, + "99.9" : 0.3990008796680498, + "99.99" : 0.3990008796680498, + "99.999" : 0.3990008796680498, + "99.9999" : 0.3990008796680498, + "100.0" : 0.3990008796680498 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3913463903889802, + 0.39134656312123345, + 0.39062994046875 + ], + [ + 0.3974219333147876, + 0.3969439823363633, + 0.3966984339719941 + ], + [ + 0.3990008796680498, + 0.39506548674594083, + 0.3952583020829216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1610574826858421, + "scoreError" : 0.003752410557245631, + "scoreConfidence" : [ + 0.15730507212859648, + 0.16480989324308773 + ], + "scorePercentiles" : { + "0.0" : 0.15879246556679422, + "50.0" : 0.1602639839738453, + "90.0" : 0.16460379410070283, + "95.0" : 0.16460379410070283, + "99.0" : 0.16460379410070283, + "99.9" : 0.16460379410070283, + "99.99" : 0.16460379410070283, + "99.999" : 0.16460379410070283, + "99.9999" : 0.16460379410070283, + "100.0" : 0.16460379410070283 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15879246556679422, + 0.15922639871029376, + 0.1590539176116934 + ], + [ + 0.16016096425311105, + 0.1602639839738453, + 0.1603011353231598 + ], + [ + 0.16460379410070283, + 0.16316207262196117, + 0.1639526120110175 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04835155109742807, + "scoreError" : 0.0014775111568661589, + "scoreConfidence" : [ + 0.04687403994056191, + 0.04982906225429423 + ], + "scorePercentiles" : { + "0.0" : 0.047276101358698225, + "50.0" : 0.048217913343684, + "90.0" : 0.04951674853308905, + "95.0" : 0.04951674853308905, + "99.0" : 0.04951674853308905, + "99.9" : 0.04951674853308905, + "99.99" : 0.04951674853308905, + "99.999" : 0.04951674853308905, + "99.9999" : 0.04951674853308905, + "100.0" : 0.04951674853308905 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04951674853308905, + 0.04938211956247994, + 0.04941198198959399 + ], + [ + 0.04821848832645425, + 0.0481013592933039, + 0.048217913343684 + ], + [ + 0.04749393822546021, + 0.04754530924408902, + 0.047276101358698225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9625059.040573487, + "scoreError" : 219935.77309763603, + "scoreConfidence" : [ + 9405123.26747585, + 9844994.813671123 + ], + "scorePercentiles" : { + "0.0" : 9448406.368271954, + "50.0" : 9683659.49177154, + "90.0" : 9762830.43609756, + "95.0" : 9762830.43609756, + "99.0" : 9762830.43609756, + "99.9" : 9762830.43609756, + "99.99" : 9762830.43609756, + "99.999" : 9762830.43609756, + "99.9999" : 9762830.43609756, + "100.0" : 9762830.43609756 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9687952.249757987, + 9683659.49177154, + 9676237.632495165 + ], + [ + 9762830.43609756, + 9739261.683544304, + 9712223.050485438 + ], + [ + 9461725.996215705, + 9453234.456521738, + 9448406.368271954 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-28T00:03:05Z-c0366ce7f430d3ea6827a80a5dca1b7c43c3950e-jdk17.json b/performance-results/2025-02-28T00:03:05Z-c0366ce7f430d3ea6827a80a5dca1b7c43c3950e-jdk17.json new file mode 100644 index 0000000000..93b65412ac --- /dev/null +++ b/performance-results/2025-02-28T00:03:05Z-c0366ce7f430d3ea6827a80a5dca1b7c43c3950e-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4093139013067724, + "scoreError" : 0.021893836129409316, + "scoreConfidence" : [ + 3.387420065177363, + 3.4312077374361816 + ], + "scorePercentiles" : { + "0.0" : 3.404731404003703, + "50.0" : 3.409860333857129, + "90.0" : 3.412803533509129, + "95.0" : 3.412803533509129, + "99.0" : 3.412803533509129, + "99.9" : 3.412803533509129, + "99.99" : 3.412803533509129, + "99.999" : 3.412803533509129, + "99.9999" : 3.412803533509129, + "100.0" : 3.412803533509129 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.409284321996756, + 3.4104363457175024 + ], + [ + 3.404731404003703, + 3.412803533509129 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7182419922433345, + "scoreError" : 0.009837862041857262, + "scoreConfidence" : [ + 1.7084041302014772, + 1.7280798542851918 + ], + "scorePercentiles" : { + "0.0" : 1.7161595064751782, + "50.0" : 1.7186904440757775, + "90.0" : 1.719427574346604, + "95.0" : 1.719427574346604, + "99.0" : 1.719427574346604, + "99.9" : 1.719427574346604, + "99.99" : 1.719427574346604, + "99.999" : 1.719427574346604, + "99.9999" : 1.719427574346604, + "100.0" : 1.719427574346604 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.719427574346604, + 1.7193263365006115 + ], + [ + 1.7161595064751782, + 1.7180545516509436 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8656415344042727, + "scoreError" : 0.00216935852863811, + "scoreConfidence" : [ + 0.8634721758756346, + 0.8678108929329108 + ], + "scorePercentiles" : { + "0.0" : 0.8652472998061675, + "50.0" : 0.8656445886938953, + "90.0" : 0.8660296604231326, + "95.0" : 0.8660296604231326, + "99.0" : 0.8660296604231326, + "99.9" : 0.8660296604231326, + "99.99" : 0.8660296604231326, + "99.999" : 0.8660296604231326, + "99.9999" : 0.8660296604231326, + "100.0" : 0.8660296604231326 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8657711262503519, + 0.8655180511374387 + ], + [ + 0.8652472998061675, + 0.8660296604231326 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70249.89615163156, + "scoreError" : 184.9343928170246, + "scoreConfidence" : [ + 70064.96175881453, + 70434.83054444859 + ], + "scorePercentiles" : { + "0.0" : 70120.69035144885, + "50.0" : 70222.45600654616, + "90.0" : 70403.71718522921, + "95.0" : 70403.71718522921, + "99.0" : 70403.71718522921, + "99.9" : 70403.71718522921, + "99.99" : 70403.71718522921, + "99.999" : 70403.71718522921, + "99.9999" : 70403.71718522921, + "100.0" : 70403.71718522921 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70401.49822549731, + 70353.74617990099, + 70403.71718522921 + ], + [ + 70144.53735546515, + 70197.23574567295, + 70120.69035144885 + ], + [ + 70245.4038793827, + 70222.45600654616, + 70159.78043554082 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 324.1235870149517, + "scoreError" : 12.518422380833014, + "scoreConfidence" : [ + 311.6051646341187, + 336.64200939578467 + ], + "scorePercentiles" : { + "0.0" : 314.0885905749031, + "50.0" : 326.2222939474484, + "90.0" : 331.6432472176766, + "95.0" : 331.6432472176766, + "99.0" : 331.6432472176766, + "99.9" : 331.6432472176766, + "99.99" : 331.6432472176766, + "99.999" : 331.6432472176766, + "99.9999" : 331.6432472176766, + "100.0" : 331.6432472176766 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 325.97687376627675, + 327.32026111840463, + 331.126243086308 + ], + [ + 331.6432472176766, + 331.0286050083805, + 326.2222939474484 + ], + [ + 314.0885905749031, + 315.02124216928775, + 314.6849262458794 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.08364604746585, + "scoreError" : 1.343132091816652, + "scoreConfidence" : [ + 102.74051395564919, + 105.4267781392825 + ], + "scorePercentiles" : { + "0.0" : 103.10488102505084, + "50.0" : 103.9406500655117, + "90.0" : 105.49964296877762, + "95.0" : 105.49964296877762, + "99.0" : 105.49964296877762, + "99.9" : 105.49964296877762, + "99.99" : 105.49964296877762, + "99.999" : 105.49964296877762, + "99.9999" : 105.49964296877762, + "100.0" : 105.49964296877762 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 103.10488102505084, + 103.9406500655117, + 103.92876928971134 + ], + [ + 104.72044867134093, + 105.49964296877762, + 104.86104107178554 + ], + [ + 103.94586724796258, + 103.56578526150736, + 103.18572882554477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01420008079255139, + "scoreError" : 3.534476823480423E-5, + "scoreConfidence" : [ + 0.014164736024316586, + 0.014235425560786193 + ], + "scorePercentiles" : { + "0.0" : 0.01417365751768496, + "50.0" : 0.014199791465741986, + "90.0" : 0.014234270268654507, + "95.0" : 0.014234270268654507, + "99.0" : 0.014234270268654507, + "99.9" : 0.014234270268654507, + "99.99" : 0.014234270268654507, + "99.999" : 0.014234270268654507, + "99.9999" : 0.014234270268654507, + "100.0" : 0.014234270268654507 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014199791465741986, + 0.014212377463151328, + 0.014190600920106542 + ], + [ + 0.01422226798704651, + 0.014209003600516065, + 0.014234270268654507 + ], + [ + 0.01417841923080195, + 0.01418033867925866, + 0.01417365751768496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0020239600224718, + "scoreError" : 0.020447026162184023, + "scoreConfidence" : [ + 0.9815769338602878, + 1.022470986184656 + ], + "scorePercentiles" : { + "0.0" : 0.9786403171543204, + "50.0" : 1.0060794966800806, + "90.0" : 1.017381385757884, + "95.0" : 1.017381385757884, + "99.0" : 1.017381385757884, + "99.9" : 1.017381385757884, + "99.99" : 1.017381385757884, + "99.999" : 1.017381385757884, + "99.9999" : 1.017381385757884, + "100.0" : 1.017381385757884 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0114736057449176, + 1.017381385757884, + 1.0080577986090111 + ], + [ + 0.9922600353209644, + 0.9939197001590141, + 0.9989399211866946 + ], + [ + 1.0114633795893597, + 0.9786403171543204, + 1.0060794966800806 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013369104906817872, + "scoreError" : 5.803541797248806E-4, + "scoreConfidence" : [ + 0.012788750727092991, + 0.013949459086542753 + ], + "scorePercentiles" : { + "0.0" : 0.013171773939042702, + "50.0" : 0.013363062333361295, + "90.0" : 0.01359549083414451, + "95.0" : 0.01359549083414451, + "99.0" : 0.01359549083414451, + "99.9" : 0.01359549083414451, + "99.99" : 0.01359549083414451, + "99.999" : 0.01359549083414451, + "99.9999" : 0.01359549083414451, + "100.0" : 0.01359549083414451 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013539637246645636, + 0.01359549083414451, + 0.0135357767250224 + ], + [ + 0.013181602754351786, + 0.013171773939042702, + 0.013190347941700192 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8901509541468826, + "scoreError" : 0.03736323494833567, + "scoreConfidence" : [ + 3.852787719198547, + 3.927514189095218 + ], + "scorePercentiles" : { + "0.0" : 3.8659979497681607, + "50.0" : 3.8930672909390642, + "90.0" : 3.9019652425897036, + "95.0" : 3.9019652425897036, + "99.0" : 3.9019652425897036, + "99.9" : 3.9019652425897036, + "99.99" : 3.9019652425897036, + "99.999" : 3.9019652425897036, + "99.9999" : 3.9019652425897036, + "100.0" : 3.9019652425897036 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8659979497681607, + 3.9019652425897036, + 3.901129496099844 + ], + [ + 3.89117386848249, + 3.8949607133956388, + 3.8856784545454546 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9819383742313637, + "scoreError" : 0.05841787458508158, + "scoreConfidence" : [ + 2.923520499646282, + 3.0403562488164453 + ], + "scorePercentiles" : { + "0.0" : 2.9387547916544228, + "50.0" : 2.9656987298339264, + "90.0" : 3.033763831058538, + "95.0" : 3.033763831058538, + "99.0" : 3.033763831058538, + "99.9" : 3.033763831058538, + "99.99" : 3.033763831058538, + "99.999" : 3.033763831058538, + "99.9999" : 3.033763831058538, + "100.0" : 3.033763831058538 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.033763831058538, + 3.01548591046126, + 3.0099463171832683 + ], + [ + 3.007374973541792, + 2.9656987298339264, + 2.9656569952550416 + ], + [ + 2.9459099366715757, + 2.954853882422452, + 2.9387547916544228 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18768522962156822, + "scoreError" : 0.00834799006050313, + "scoreConfidence" : [ + 0.1793372395610651, + 0.19603321968207135 + ], + "scorePercentiles" : { + "0.0" : 0.18104723394586766, + "50.0" : 0.18936799948871383, + "90.0" : 0.19284200376034094, + "95.0" : 0.19284200376034094, + "99.0" : 0.19284200376034094, + "99.9" : 0.19284200376034094, + "99.99" : 0.19284200376034094, + "99.999" : 0.19284200376034094, + "99.9999" : 0.19284200376034094, + "100.0" : 0.19284200376034094 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19284200376034094, + 0.1923480044623966, + 0.19192666618685705 + ], + [ + 0.18179211868966896, + 0.18107432534810872, + 0.18104723394586766 + ], + [ + 0.18942655156084257, + 0.18934216315131777, + 0.18936799948871383 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.34058191618212075, + "scoreError" : 0.003858026612173194, + "scoreConfidence" : [ + 0.33672388956994753, + 0.34443994279429396 + ], + "scorePercentiles" : { + "0.0" : 0.33769021212939826, + "50.0" : 0.3407948157374591, + "90.0" : 0.3438218884686791, + "95.0" : 0.3438218884686791, + "99.0" : 0.3438218884686791, + "99.9" : 0.3438218884686791, + "99.99" : 0.3438218884686791, + "99.999" : 0.3438218884686791, + "99.9999" : 0.3438218884686791, + "100.0" : 0.3438218884686791 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33851800196337295, + 0.33776987850846085, + 0.33769021212939826 + ], + [ + 0.3438218884686791, + 0.34235571417322835, + 0.34216245375851095 + ], + [ + 0.3407948157374591, + 0.3426416534982526, + 0.33948262740172447 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16430571049586792, + "scoreError" : 0.006062912563558703, + "scoreConfidence" : [ + 0.15824279793230922, + 0.17036862305942663 + ], + "scorePercentiles" : { + "0.0" : 0.16106335164038718, + "50.0" : 0.16263530021629885, + "90.0" : 0.16930342624477288, + "95.0" : 0.16930342624477288, + "99.0" : 0.16930342624477288, + "99.9" : 0.16930342624477288, + "99.99" : 0.16930342624477288, + "99.999" : 0.16930342624477288, + "99.9999" : 0.16930342624477288, + "100.0" : 0.16930342624477288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16297191605553926, + 0.16218497714851035, + 0.16263530021629885 + ], + [ + 0.16139171223149298, + 0.16106335164038718, + 0.16137712693648334 + ], + [ + 0.16871034478279207, + 0.16911323920653443, + 0.16930342624477288 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4014406332579484, + "scoreError" : 0.0064106096443937105, + "scoreConfidence" : [ + 0.39503002361355466, + 0.4078512429023421 + ], + "scorePercentiles" : { + "0.0" : 0.39696473793267706, + "50.0" : 0.4002436985511887, + "90.0" : 0.40840316928040515, + "95.0" : 0.40840316928040515, + "99.0" : 0.40840316928040515, + "99.9" : 0.40840316928040515, + "99.99" : 0.40840316928040515, + "99.999" : 0.40840316928040515, + "99.9999" : 0.40840316928040515, + "100.0" : 0.40840316928040515 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39874033963317385, + 0.39796666401368935, + 0.39696473793267706 + ], + [ + 0.40840316928040515, + 0.4047517820860485, + 0.40437363024666395 + ], + [ + 0.40258169533011273, + 0.4002436985511887, + 0.3989399822475765 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1622603517749877, + "scoreError" : 0.0022710755266089396, + "scoreConfidence" : [ + 0.15998927624837878, + 0.16453142730159664 + ], + "scorePercentiles" : { + "0.0" : 0.16080216116998183, + "50.0" : 0.16173225106740846, + "90.0" : 0.1650935754874284, + "95.0" : 0.1650935754874284, + "99.0" : 0.1650935754874284, + "99.9" : 0.1650935754874284, + "99.99" : 0.1650935754874284, + "99.999" : 0.1650935754874284, + "99.9999" : 0.1650935754874284, + "100.0" : 0.1650935754874284 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16263024725569594, + 0.16173225106740846, + 0.16164135474485591 + ], + [ + 0.1650935754874284, + 0.1630933295387827, + 0.163012935448114 + ], + [ + 0.16125758538394555, + 0.16080216116998183, + 0.16107972587867658 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048687190219174316, + "scoreError" : 0.0012339357980707558, + "scoreConfidence" : [ + 0.04745325442110356, + 0.04992112601724507 + ], + "scorePercentiles" : { + "0.0" : 0.04793252728754254, + "50.0" : 0.048637015865141436, + "90.0" : 0.05031688491166984, + "95.0" : 0.05031688491166984, + "99.0" : 0.05031688491166984, + "99.9" : 0.05031688491166984, + "99.99" : 0.05031688491166984, + "99.999" : 0.05031688491166984, + "99.9999" : 0.05031688491166984, + "100.0" : 0.05031688491166984 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04793252728754254, + 0.04806552263605908, + 0.04803455098325536 + ], + [ + 0.05031688491166984, + 0.04888433324860193, + 0.048948174551274835 + ], + [ + 0.0489710829950295, + 0.048637015865141436, + 0.04839461949399433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9679679.952722099, + "scoreError" : 352471.94224217994, + "scoreConfidence" : [ + 9327208.01047992, + 1.0032151894964278E7 + ], + "scorePercentiles" : { + "0.0" : 9410322.933207903, + "50.0" : 9733389.864785992, + "90.0" : 9917231.136769079, + "95.0" : 9917231.136769079, + "99.0" : 9917231.136769079, + "99.9" : 9917231.136769079, + "99.99" : 9917231.136769079, + "99.999" : 9917231.136769079, + "99.9999" : 9917231.136769079, + "100.0" : 9917231.136769079 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9412682.519285042, + 9417082.15913371, + 9410322.933207903 + ], + [ + 9917231.136769079, + 9867065.872781064, + 9860209.638423646 + ], + [ + 9784028.08797654, + 9715107.362135923, + 9733389.864785992 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-28T01:21:28Z-233fcc4f8943e346ae4ff21e5561b85f426f535b-jdk17.json b/performance-results/2025-02-28T01:21:28Z-233fcc4f8943e346ae4ff21e5561b85f426f535b-jdk17.json new file mode 100644 index 0000000000..e6aa8705dc --- /dev/null +++ b/performance-results/2025-02-28T01:21:28Z-233fcc4f8943e346ae4ff21e5561b85f426f535b-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.425004188960926, + "scoreError" : 0.0174529961835408, + "scoreConfidence" : [ + 3.407551192777385, + 3.442457185144467 + ], + "scorePercentiles" : { + "0.0" : 3.4215569792394542, + "50.0" : 3.4251662860439884, + "90.0" : 3.4281272045162727, + "95.0" : 3.4281272045162727, + "99.0" : 3.4281272045162727, + "99.9" : 3.4281272045162727, + "99.99" : 3.4281272045162727, + "99.999" : 3.4281272045162727, + "99.9999" : 3.4281272045162727, + "100.0" : 3.4281272045162727 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4215569792394542, + 3.4281272045162727 + ], + [ + 3.4248539784419494, + 3.425478593646028 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7291184118820688, + "scoreError" : 0.004159502908174387, + "scoreConfidence" : [ + 1.7249589089738944, + 1.7332779147902433 + ], + "scorePercentiles" : { + "0.0" : 1.7284478976539939, + "50.0" : 1.7290384028345496, + "90.0" : 1.7299489442051819, + "95.0" : 1.7299489442051819, + "99.0" : 1.7299489442051819, + "99.9" : 1.7299489442051819, + "99.99" : 1.7299489442051819, + "99.999" : 1.7299489442051819, + "99.9999" : 1.7299489442051819, + "100.0" : 1.7299489442051819 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7288253003704586, + 1.7284478976539939 + ], + [ + 1.7292515052986406, + 1.7299489442051819 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8678256118833285, + "scoreError" : 0.006561550956313254, + "scoreConfidence" : [ + 0.8612640609270152, + 0.8743871628396418 + ], + "scorePercentiles" : { + "0.0" : 0.8668878985260587, + "50.0" : 0.8676384753786253, + "90.0" : 0.8691375982500048, + "95.0" : 0.8691375982500048, + "99.0" : 0.8691375982500048, + "99.9" : 0.8691375982500048, + "99.99" : 0.8691375982500048, + "99.999" : 0.8691375982500048, + "99.9999" : 0.8691375982500048, + "100.0" : 0.8691375982500048 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8691375982500048, + 0.8680980953764585 + ], + [ + 0.8671788553807921, + 0.8668878985260587 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69300.6801932766, + "scoreError" : 2948.965995832353, + "scoreConfidence" : [ + 66351.71419744425, + 72249.64618910894 + ], + "scorePercentiles" : { + "0.0" : 66905.52137361391, + "50.0" : 70369.64562102163, + "90.0" : 70576.55566451224, + "95.0" : 70576.55566451224, + "99.0" : 70576.55566451224, + "99.9" : 70576.55566451224, + "99.99" : 70576.55566451224, + "99.999" : 70576.55566451224, + "99.9999" : 70576.55566451224, + "100.0" : 70576.55566451224 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70569.49827302896, + 70524.63925300592, + 70576.55566451224 + ], + [ + 70423.57707233248, + 70351.35599478213, + 70369.64562102163 + ], + [ + 66905.52137361391, + 67030.73245789492, + 66954.59602929726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.52049772404257, + "scoreError" : 7.200395101991134, + "scoreConfidence" : [ + 342.3201026220514, + 356.7208928260337 + ], + "scorePercentiles" : { + "0.0" : 344.4032078203839, + "50.0" : 350.22761457137, + "90.0" : 356.6250203740414, + "95.0" : 356.6250203740414, + "99.0" : 356.6250203740414, + "99.9" : 356.6250203740414, + "99.99" : 356.6250203740414, + "99.999" : 356.6250203740414, + "99.9999" : 356.6250203740414, + "100.0" : 356.6250203740414 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 347.53019390364983, + 350.22761457137, + 351.764415757937 + ], + [ + 356.6250203740414, + 353.5611755887331, + 351.5199872665624 + ], + [ + 344.98688408164884, + 345.0659801520564, + 344.4032078203839 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.37242796876829, + "scoreError" : 6.922906797014581, + "scoreConfidence" : [ + 97.44952117175372, + 111.29533476578287 + ], + "scorePercentiles" : { + "0.0" : 99.71513007956918, + "50.0" : 103.72256768038186, + "90.0" : 109.56034934265045, + "95.0" : 109.56034934265045, + "99.0" : 109.56034934265045, + "99.9" : 109.56034934265045, + "99.99" : 109.56034934265045, + "99.999" : 109.56034934265045, + "99.9999" : 109.56034934265045, + "100.0" : 109.56034934265045 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 99.71513007956918, + 100.2024660758994, + 100.0292213935468 + ], + [ + 109.56034934265045, + 109.26460933508037, + 109.43978481861957 + ], + [ + 103.66061563143764, + 103.75710736172933, + 103.72256768038186 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014193070731641019, + "scoreError" : 1.3985027221844092E-4, + "scoreConfidence" : [ + 0.014053220459422578, + 0.01433292100385946 + ], + "scorePercentiles" : { + "0.0" : 0.014072886206629656, + "50.0" : 0.014221143006056711, + "90.0" : 0.014279952131259906, + "95.0" : 0.014279952131259906, + "99.0" : 0.014279952131259906, + "99.9" : 0.014279952131259906, + "99.99" : 0.014279952131259906, + "99.999" : 0.014279952131259906, + "99.9999" : 0.014279952131259906, + "100.0" : 0.014279952131259906 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014221143006056711, + 0.014226597827339501, + 0.01421779372490588 + ], + [ + 0.014279952131259906, + 0.014266136113009278, + 0.014266727080777242 + ], + [ + 0.014102687160922474, + 0.014083713333868507, + 0.014072886206629656 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0134086142929557, + "scoreError" : 0.016656611892461523, + "scoreConfidence" : [ + 0.9967520024004942, + 1.0300652261854173 + ], + "scorePercentiles" : { + "0.0" : 0.9993761009293495, + "50.0" : 1.0191509573015387, + "90.0" : 1.0243929557467732, + "95.0" : 1.0243929557467732, + "99.0" : 1.0243929557467732, + "99.9" : 1.0243929557467732, + "99.99" : 1.0243929557467732, + "99.999" : 1.0243929557467732, + "99.9999" : 1.0243929557467732, + "100.0" : 1.0243929557467732 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.020094274479804, + 1.0235628798362333, + 1.0243929557467732 + ], + [ + 1.0194230865443425, + 1.0093312450545013, + 1.0191509573015387 + ], + [ + 1.0041463041470027, + 0.9993761009293495, + 1.0011997245970568 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012999582896411559, + "scoreError" : 6.992813461278419E-4, + "scoreConfidence" : [ + 0.012300301550283717, + 0.0136988642425394 + ], + "scorePercentiles" : { + "0.0" : 0.01269426261526119, + "50.0" : 0.012976330358043518, + "90.0" : 0.013273546866330943, + "95.0" : 0.013273546866330943, + "99.0" : 0.013273546866330943, + "99.9" : 0.013273546866330943, + "99.99" : 0.013273546866330943, + "99.999" : 0.013273546866330943, + "99.9999" : 0.013273546866330943, + "100.0" : 0.013273546866330943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013119807961963936, + 0.013259157202067318, + 0.013273546866330943 + ], + [ + 0.01269426261526119, + 0.012817869978722859, + 0.0128328527541231 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.709114407689517, + "scoreError" : 0.05197450643726689, + "scoreConfidence" : [ + 3.65713990125225, + 3.7610889141267836 + ], + "scorePercentiles" : { + "0.0" : 3.6743841410727405, + "50.0" : 3.712563719022545, + "90.0" : 3.7299658426547353, + "95.0" : 3.7299658426547353, + "99.0" : 3.7299658426547353, + "99.9" : 3.7299658426547353, + "99.99" : 3.7299658426547353, + "99.999" : 3.7299658426547353, + "99.9999" : 3.7299658426547353, + "100.0" : 3.7299658426547353 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6743841410727405, + 3.7137454847809948, + 3.716191622585438 + ], + [ + 3.711381953264095, + 3.7299658426547353, + 3.7090174017790956 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.908876032349584, + "scoreError" : 0.06653523093807073, + "scoreConfidence" : [ + 2.8423408014115132, + 2.975411263287655 + ], + "scorePercentiles" : { + "0.0" : 2.859286373927959, + "50.0" : 2.9278416536885246, + "90.0" : 2.9591043917159765, + "95.0" : 2.9591043917159765, + "99.0" : 2.9591043917159765, + "99.9" : 2.9591043917159765, + "99.99" : 2.9591043917159765, + "99.999" : 2.9591043917159765, + "99.9999" : 2.9591043917159765, + "100.0" : 2.9591043917159765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.885501371609925, + 2.9278416536885246, + 2.932055654353562 + ], + [ + 2.859286373927959, + 2.8695159586800574, + 2.862702666571265 + ], + [ + 2.930786301201289, + 2.9591043917159765, + 2.953089919397697 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18940902420611713, + "scoreError" : 0.012623487496932687, + "scoreConfidence" : [ + 0.17678553670918445, + 0.2020325117030498 + ], + "scorePercentiles" : { + "0.0" : 0.17928718473233174, + "50.0" : 0.19351137820736097, + "90.0" : 0.19568663671408723, + "95.0" : 0.19568663671408723, + "99.0" : 0.19568663671408723, + "99.9" : 0.19568663671408723, + "99.99" : 0.19568663671408723, + "99.999" : 0.19568663671408723, + "99.9999" : 0.19568663671408723, + "100.0" : 0.19568663671408723 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19346425306635712, + 0.19351137820736097, + 0.19361049129736113 + ], + [ + 0.17968087045189113, + 0.1793736514501982, + 0.17928718473233174 + ], + [ + 0.19568663671408723, + 0.19518574770660108, + 0.19488100422886542 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3257654980395767, + "scoreError" : 0.003647712937679187, + "scoreConfidence" : [ + 0.32211778510189754, + 0.3294132109772559 + ], + "scorePercentiles" : { + "0.0" : 0.32280374912037185, + "50.0" : 0.32625077087955107, + "90.0" : 0.3281728269943885, + "95.0" : 0.3281728269943885, + "99.0" : 0.3281728269943885, + "99.9" : 0.3281728269943885, + "99.99" : 0.3281728269943885, + "99.999" : 0.3281728269943885, + "99.9999" : 0.3281728269943885, + "100.0" : 0.3281728269943885 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32630149026005806, + 0.32592821641353237, + 0.32625077087955107 + ], + [ + 0.32797510793348855, + 0.3279792810665442, + 0.3281728269943885 + ], + [ + 0.32311754786907493, + 0.32280374912037185, + 0.32336049181918125 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1664925346902736, + "scoreError" : 0.009505190969284327, + "scoreConfidence" : [ + 0.1569873437209893, + 0.17599772565955793 + ], + "scorePercentiles" : { + "0.0" : 0.1592184539071456, + "50.0" : 0.16805786182673724, + "90.0" : 0.1724910860888314, + "95.0" : 0.1724910860888314, + "99.0" : 0.1724910860888314, + "99.9" : 0.1724910860888314, + "99.99" : 0.1724910860888314, + "99.999" : 0.1724910860888314, + "99.9999" : 0.1724910860888314, + "100.0" : 0.1724910860888314 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15938114037995665, + 0.1594989847523047, + 0.1592184539071456 + ], + [ + 0.1676237910793007, + 0.1681097820327472, + 0.16805786182673724 + ], + [ + 0.1724910860888314, + 0.172039499939787, + 0.17201221220565216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38993431325865663, + "scoreError" : 0.009461256488847478, + "scoreConfidence" : [ + 0.38047305676980914, + 0.3993955697475041 + ], + "scorePercentiles" : { + "0.0" : 0.3824617474280032, + "50.0" : 0.39044726392847384, + "90.0" : 0.3966692765856174, + "95.0" : 0.3966692765856174, + "99.0" : 0.3966692765856174, + "99.9" : 0.3966692765856174, + "99.99" : 0.3966692765856174, + "99.999" : 0.3966692765856174, + "99.9999" : 0.3966692765856174, + "100.0" : 0.3966692765856174 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3966692765856174, + 0.39627204069583133, + 0.39586610612778084 + ], + [ + 0.3852658757945833, + 0.38265304564934566, + 0.3824617474280032 + ], + [ + 0.39087826020168853, + 0.39044726392847384, + 0.38889520291658564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1580856687466588, + "scoreError" : 0.00260313401060033, + "scoreConfidence" : [ + 0.15548253473605847, + 0.16068880275725914 + ], + "scorePercentiles" : { + "0.0" : 0.1561233264484099, + "50.0" : 0.15758299941695555, + "90.0" : 0.16031973716273626, + "95.0" : 0.16031973716273626, + "99.0" : 0.16031973716273626, + "99.9" : 0.16031973716273626, + "99.99" : 0.16031973716273626, + "99.999" : 0.16031973716273626, + "99.9999" : 0.16031973716273626, + "100.0" : 0.16031973716273626 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1595882914159871, + 0.16031973716273626, + 0.1598122411666001 + ], + [ + 0.15758299941695555, + 0.15727130698581449, + 0.15731520293229298 + ], + [ + 0.15852091390980425, + 0.1561233264484099, + 0.15623699928132861 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04749293708460388, + "scoreError" : 8.250305964143997E-4, + "scoreConfidence" : [ + 0.04666790648818948, + 0.04831796768101828 + ], + "scorePercentiles" : { + "0.0" : 0.046976803193438374, + "50.0" : 0.0473359307863807, + "90.0" : 0.048134309229621426, + "95.0" : 0.048134309229621426, + "99.0" : 0.048134309229621426, + "99.9" : 0.048134309229621426, + "99.99" : 0.048134309229621426, + "99.999" : 0.048134309229621426, + "99.9999" : 0.048134309229621426, + "100.0" : 0.048134309229621426 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04756417431092297, + 0.04726491346844633, + 0.0473359307863807 + ], + [ + 0.04698740704143291, + 0.046976803193438374, + 0.04701674583554701 + ], + [ + 0.04810798255151081, + 0.048134309229621426, + 0.048048167344134377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9524975.016775662, + "scoreError" : 289751.35326766694, + "scoreConfidence" : [ + 9235223.663507994, + 9814726.37004333 + ], + "scorePercentiles" : { + "0.0" : 9370765.244382022, + "50.0" : 9429927.322337417, + "90.0" : 9768079.684570312, + "95.0" : 9768079.684570312, + "99.0" : 9768079.684570312, + "99.9" : 9768079.684570312, + "99.99" : 9768079.684570312, + "99.999" : 9768079.684570312, + "99.9999" : 9768079.684570312, + "100.0" : 9768079.684570312 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9742250.733203506, + 9768079.684570312, + 9749335.159844054 + ], + [ + 9435293.098113207, + 9427336.44674835, + 9429927.322337417 + ], + [ + 9397928.663849765, + 9370765.244382022, + 9403858.79793233 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-02-28T05:10:58Z-77adc96ca0deeb4098d1ff1450312cf30d18e6a4-jdk17.json b/performance-results/2025-02-28T05:10:58Z-77adc96ca0deeb4098d1ff1450312cf30d18e6a4-jdk17.json new file mode 100644 index 0000000000..d7a3282577 --- /dev/null +++ b/performance-results/2025-02-28T05:10:58Z-77adc96ca0deeb4098d1ff1450312cf30d18e6a4-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4155242671178643, + "scoreError" : 0.021366874756141404, + "scoreConfidence" : [ + 3.394157392361723, + 3.4368911418740056 + ], + "scorePercentiles" : { + "0.0" : 3.4126757505658514, + "50.0" : 3.414666030565734, + "90.0" : 3.420089256774136, + "95.0" : 3.420089256774136, + "99.0" : 3.420089256774136, + "99.9" : 3.420089256774136, + "99.99" : 3.420089256774136, + "99.999" : 3.420089256774136, + "99.9999" : 3.420089256774136, + "100.0" : 3.420089256774136 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4157554002096697, + 3.413576660921798 + ], + [ + 3.4126757505658514, + 3.420089256774136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7256630448941475, + "scoreError" : 0.011635721260581646, + "scoreConfidence" : [ + 1.714027323633566, + 1.737298766154729 + ], + "scorePercentiles" : { + "0.0" : 1.723193635282295, + "50.0" : 1.725973087245099, + "90.0" : 1.7275123698040975, + "95.0" : 1.7275123698040975, + "99.0" : 1.7275123698040975, + "99.9" : 1.7275123698040975, + "99.99" : 1.7275123698040975, + "99.999" : 1.7275123698040975, + "99.9999" : 1.7275123698040975, + "100.0" : 1.7275123698040975 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7260644171569068, + 1.7275123698040975 + ], + [ + 1.723193635282295, + 1.7258817573332907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8674451074711825, + "scoreError" : 0.004249137348369588, + "scoreConfidence" : [ + 0.8631959701228129, + 0.8716942448195522 + ], + "scorePercentiles" : { + "0.0" : 0.8665786884079261, + "50.0" : 0.8675735756317964, + "90.0" : 0.8680545902132113, + "95.0" : 0.8680545902132113, + "99.0" : 0.8680545902132113, + "99.9" : 0.8680545902132113, + "99.99" : 0.8680545902132113, + "99.999" : 0.8680545902132113, + "99.9999" : 0.8680545902132113, + "100.0" : 0.8680545902132113 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8673071258039897, + 0.8680545902132113 + ], + [ + 0.8665786884079261, + 0.8678400254596029 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70504.76307379914, + "scoreError" : 624.3060851188214, + "scoreConfidence" : [ + 69880.45698868032, + 71129.06915891796 + ], + "scorePercentiles" : { + "0.0" : 69782.18803539468, + "50.0" : 70549.373916216, + "90.0" : 70890.4395602008, + "95.0" : 70890.4395602008, + "99.0" : 70890.4395602008, + "99.9" : 70890.4395602008, + "99.99" : 70890.4395602008, + "99.999" : 70890.4395602008, + "99.9999" : 70890.4395602008, + "100.0" : 70890.4395602008 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70810.01885219604, + 70549.373916216, + 70502.1469169721 + ], + [ + 70244.23636788203, + 69782.18803539468, + 70180.44548991376 + ], + [ + 70797.86184337315, + 70786.15668204376, + 70890.4395602008 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 344.1163493384629, + "scoreError" : 4.629038164553738, + "scoreConfidence" : [ + 339.4873111739092, + 348.7453875030166 + ], + "scorePercentiles" : { + "0.0" : 339.99341521153025, + "50.0" : 344.63463159856883, + "90.0" : 347.6493297625378, + "95.0" : 347.6493297625378, + "99.0" : 347.6493297625378, + "99.9" : 347.6493297625378, + "99.99" : 347.6493297625378, + "99.999" : 347.6493297625378, + "99.9999" : 347.6493297625378, + "100.0" : 347.6493297625378 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 342.65194830682475, + 343.2995607102032, + 339.99341521153025 + ], + [ + 345.1038421289899, + 347.6493297625378, + 346.38617001258297 + ], + [ + 344.63463159856883, + 340.37714261970393, + 346.9511036952247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.35398262068469, + "scoreError" : 3.698496186029317, + "scoreConfidence" : [ + 101.65548643465537, + 109.052478806714 + ], + "scorePercentiles" : { + "0.0" : 102.45147063371301, + "50.0" : 106.25917608524738, + "90.0" : 108.11542107904748, + "95.0" : 108.11542107904748, + "99.0" : 108.11542107904748, + "99.9" : 108.11542107904748, + "99.99" : 108.11542107904748, + "99.999" : 108.11542107904748, + "99.9999" : 108.11542107904748, + "100.0" : 108.11542107904748 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 102.66020454166096, + 102.45147063371301, + 102.92241228943182 + ], + [ + 106.7842668012313, + 107.62840877904392, + 108.11542107904748 + ], + [ + 104.88238605208642, + 106.25917608524738, + 106.48209732469995 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014213492598747074, + "scoreError" : 7.099203275016753E-5, + "scoreConfidence" : [ + 0.014142500565996906, + 0.014284484631497242 + ], + "scorePercentiles" : { + "0.0" : 0.014149042191943632, + "50.0" : 0.01422631078726077, + "90.0" : 0.014281189885095554, + "95.0" : 0.014281189885095554, + "99.0" : 0.014281189885095554, + "99.9" : 0.014281189885095554, + "99.99" : 0.014281189885095554, + "99.999" : 0.014281189885095554, + "99.9999" : 0.014281189885095554, + "100.0" : 0.014281189885095554 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014203040847456905, + 0.014155791548526187, + 0.014197787038719717 + ], + [ + 0.014244770724807378, + 0.014281189885095554, + 0.014236574419438972 + ], + [ + 0.014149042191943632, + 0.01422692594547454, + 0.01422631078726077 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0081913559861528, + "scoreError" : 0.016135465762877176, + "scoreConfidence" : [ + 0.9920558902232757, + 1.02432682174903 + ], + "scorePercentiles" : { + "0.0" : 0.9921777786486755, + "50.0" : 1.006073398390342, + "90.0" : 1.0239972782101168, + "95.0" : 1.0239972782101168, + "99.0" : 1.0239972782101168, + "99.9" : 1.0239972782101168, + "99.99" : 1.0239972782101168, + "99.999" : 1.0239972782101168, + "99.9999" : 1.0239972782101168, + "100.0" : 1.0239972782101168 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0142654561866127, + 1.01110784774037, + 1.0239972782101168 + ], + [ + 1.0051798572720876, + 1.004683809121961, + 1.0170640514593714 + ], + [ + 1.006073398390342, + 0.9921777786486755, + 0.9991727268458388 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01318987517952846, + "scoreError" : 8.277840973854652E-4, + "scoreConfidence" : [ + 0.012362091082142994, + 0.014017659276913926 + ], + "scorePercentiles" : { + "0.0" : 0.012867848170490049, + "50.0" : 0.013192078718330464, + "90.0" : 0.013497093532112692, + "95.0" : 0.013497093532112692, + "99.0" : 0.013497093532112692, + "99.9" : 0.013497093532112692, + "99.99" : 0.013497093532112692, + "99.999" : 0.013497093532112692, + "99.9999" : 0.013497093532112692, + "100.0" : 0.013497093532112692 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013497093532112692, + 0.01340318480504372, + 0.013467493731061882 + ], + [ + 0.012867848170490049, + 0.012922658206845218, + 0.012980972631617207 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6633665231890657, + "scoreError" : 0.06570786988662425, + "scoreConfidence" : [ + 3.5976586533024415, + 3.72907439307569 + ], + "scorePercentiles" : { + "0.0" : 3.635598972383721, + "50.0" : 3.6661064322808183, + "90.0" : 3.691381441328413, + "95.0" : 3.691381441328413, + "99.0" : 3.691381441328413, + "99.9" : 3.691381441328413, + "99.99" : 3.691381441328413, + "99.999" : 3.691381441328413, + "99.9999" : 3.691381441328413, + "100.0" : 3.691381441328413 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6367515265454546, + 3.6622488674963396, + 3.669963997065297 + ], + [ + 3.635598972383721, + 3.691381441328413, + 3.6842543343151695 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8219502049935965, + "scoreError" : 0.04334966840170217, + "scoreConfidence" : [ + 2.7786005365918944, + 2.8652998733952986 + ], + "scorePercentiles" : { + "0.0" : 2.784729027561247, + "50.0" : 2.8237416016374928, + "90.0" : 2.8593693684962838, + "95.0" : 2.8593693684962838, + "99.0" : 2.8593693684962838, + "99.9" : 2.8593693684962838, + "99.99" : 2.8593693684962838, + "99.999" : 2.8593693684962838, + "99.9999" : 2.8593693684962838, + "100.0" : 2.8593693684962838 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.787435985785953, + 2.784729027561247, + 2.8094674806179776 + ], + [ + 2.82518856299435, + 2.815962915259009, + 2.8237416016374928 + ], + [ + 2.8466063020210646, + 2.84505060056899, + 2.8593693684962838 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.181212277502675, + "scoreError" : 0.015454213970487527, + "scoreConfidence" : [ + 0.16575806353218747, + 0.1966664914731625 + ], + "scorePercentiles" : { + "0.0" : 0.17226614054882775, + "50.0" : 0.17801267326485928, + "90.0" : 0.19332841403908985, + "95.0" : 0.19332841403908985, + "99.0" : 0.19332841403908985, + "99.9" : 0.19332841403908985, + "99.99" : 0.19332841403908985, + "99.999" : 0.19332841403908985, + "99.9999" : 0.19332841403908985, + "100.0" : 0.19332841403908985 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19299061562807573, + 0.1928803875248327, + 0.19332841403908985 + ], + [ + 0.1729473925495486, + 0.17255121123285308, + 0.17226614054882775 + ], + [ + 0.1783403926418661, + 0.17801267326485928, + 0.17759327009412182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33635890077558334, + "scoreError" : 0.020346260493578534, + "scoreConfidence" : [ + 0.3160126402820048, + 0.35670516126916185 + ], + "scorePercentiles" : { + "0.0" : 0.3262282423501011, + "50.0" : 0.329679224705766, + "90.0" : 0.3527149473405756, + "95.0" : 0.3527149473405756, + "99.0" : 0.3527149473405756, + "99.9" : 0.3527149473405756, + "99.99" : 0.3527149473405756, + "99.999" : 0.3527149473405756, + "99.9999" : 0.3527149473405756, + "100.0" : 0.3527149473405756 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3524606698269482, + 0.3519048874305018, + 0.3527149473405756 + ], + [ + 0.3262282423501011, + 0.3267454162255767, + 0.32682386309562717 + ], + [ + 0.3311071462437506, + 0.3295657097614026, + 0.329679224705766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17155921178043101, + "scoreError" : 0.005706412048826315, + "scoreConfidence" : [ + 0.1658527997316047, + 0.17726562382925734 + ], + "scorePercentiles" : { + "0.0" : 0.16605277506932567, + "50.0" : 0.17356418499748338, + "90.0" : 0.17465667584183317, + "95.0" : 0.17465667584183317, + "99.0" : 0.17465667584183317, + "99.9" : 0.17465667584183317, + "99.99" : 0.17465667584183317, + "99.999" : 0.17465667584183317, + "99.9999" : 0.17465667584183317, + "100.0" : 0.17465667584183317 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16605277506932567, + 0.16713794880665864, + 0.16820257048424805 + ], + [ + 0.17374464774050072, + 0.1729026097653751, + 0.17465667584183317 + ], + [ + 0.17356418499748338, + 0.17366743593484074, + 0.17410405738361365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40108385604350244, + "scoreError" : 0.004093280443088559, + "scoreConfidence" : [ + 0.3969905756004139, + 0.405177136486591 + ], + "scorePercentiles" : { + "0.0" : 0.39789512596984045, + "50.0" : 0.40023563443528376, + "90.0" : 0.40471912991217773, + "95.0" : 0.40471912991217773, + "99.0" : 0.40471912991217773, + "99.9" : 0.40471912991217773, + "99.99" : 0.40471912991217773, + "99.999" : 0.40471912991217773, + "99.9999" : 0.40471912991217773, + "100.0" : 0.40471912991217773 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3998197200143931, + 0.40023563443528376, + 0.39970199716215676 + ], + [ + 0.40471912991217773, + 0.4044219175799733, + 0.40312262095376306 + ], + [ + 0.4008796912531067, + 0.3989588671108274, + 0.39789512596984045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16044247923562138, + "scoreError" : 0.0020666140587943618, + "scoreConfidence" : [ + 0.15837586517682703, + 0.16250909329441574 + ], + "scorePercentiles" : { + "0.0" : 0.15859480142732535, + "50.0" : 0.16041678557564285, + "90.0" : 0.16204565700350013, + "95.0" : 0.16204565700350013, + "99.0" : 0.16204565700350013, + "99.9" : 0.16204565700350013, + "99.99" : 0.16204565700350013, + "99.999" : 0.16204565700350013, + "99.9999" : 0.16204565700350013, + "100.0" : 0.16204565700350013 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16193803345532273, + 0.16144244192241253, + 0.16204565700350013 + ], + [ + 0.1603984048695987, + 0.16059771067465353, + 0.15952169556062468 + ], + [ + 0.16041678557564285, + 0.159026782631512, + 0.15859480142732535 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04701046030973298, + "scoreError" : 3.8555797178145215E-4, + "scoreConfidence" : [ + 0.046624902337951524, + 0.047396018281514435 + ], + "scorePercentiles" : { + "0.0" : 0.046712751198161415, + "50.0" : 0.04703237564786335, + "90.0" : 0.047322644024645324, + "95.0" : 0.047322644024645324, + "99.0" : 0.047322644024645324, + "99.9" : 0.047322644024645324, + "99.99" : 0.047322644024645324, + "99.999" : 0.047322644024645324, + "99.9999" : 0.047322644024645324, + "100.0" : 0.047322644024645324 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047322644024645324, + 0.047222791438623, + 0.04703237564786335 + ], + [ + 0.04725773195720389, + 0.04681896056968426, + 0.046712751198161415 + ], + [ + 0.04707274059969874, + 0.046928389102410685, + 0.04672575824930613 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9430758.342778, + "scoreError" : 263280.67197279376, + "scoreConfidence" : [ + 9167477.670805205, + 9694039.014750794 + ], + "scorePercentiles" : { + "0.0" : 9210703.829650093, + "50.0" : 9476646.130681818, + "90.0" : 9617267.366346154, + "95.0" : 9617267.366346154, + "99.0" : 9617267.366346154, + "99.9" : 9617267.366346154, + "99.99" : 9617267.366346154, + "99.999" : 9617267.366346154, + "99.9999" : 9617267.366346154, + "100.0" : 9617267.366346154 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9476646.130681818, + 9423476.688323917, + 9498627.851851853 + ], + [ + 9242939.773567468, + 9210703.829650093, + 9258214.512488436 + ], + [ + 9569795.895693779, + 9579153.036398467, + 9617267.366346154 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-02T21:33:18Z-c046e6fc09f17d3c382657e747c6023ba7f252a9-jdk17.json b/performance-results/2025-03-02T21:33:18Z-c046e6fc09f17d3c382657e747c6023ba7f252a9-jdk17.json new file mode 100644 index 0000000000..f52aae0279 --- /dev/null +++ b/performance-results/2025-03-02T21:33:18Z-c046e6fc09f17d3c382657e747c6023ba7f252a9-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.41828965785467, + "scoreError" : 0.03630562611823795, + "scoreConfidence" : [ + 3.3819840317364323, + 3.4545952839729077 + ], + "scorePercentiles" : { + "0.0" : 3.4122457287978434, + "50.0" : 3.417858050147738, + "90.0" : 3.4251968023253596, + "95.0" : 3.4251968023253596, + "99.0" : 3.4251968023253596, + "99.9" : 3.4251968023253596, + "99.99" : 3.4251968023253596, + "99.999" : 3.4251968023253596, + "99.9999" : 3.4251968023253596, + "100.0" : 3.4251968023253596 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4201038015672776, + 3.4251968023253596 + ], + [ + 3.4122457287978434, + 3.415612298728198 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7263085250284311, + "scoreError" : 0.007038612914019544, + "scoreConfidence" : [ + 1.7192699121144115, + 1.7333471379424508 + ], + "scorePercentiles" : { + "0.0" : 1.72514416466237, + "50.0" : 1.7262999109653892, + "90.0" : 1.727490113520576, + "95.0" : 1.727490113520576, + "99.0" : 1.727490113520576, + "99.9" : 1.727490113520576, + "99.99" : 1.727490113520576, + "99.999" : 1.727490113520576, + "99.9999" : 1.727490113520576, + "100.0" : 1.727490113520576 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.72514416466237, + 1.7256645954268708 + ], + [ + 1.727490113520576, + 1.7269352265039075 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.86899198118607, + "scoreError" : 0.0011975356626304622, + "scoreConfidence" : [ + 0.8677944455234395, + 0.8701895168487005 + ], + "scorePercentiles" : { + "0.0" : 0.8688009019274694, + "50.0" : 0.8689987999936732, + "90.0" : 0.8691694228294644, + "95.0" : 0.8691694228294644, + "99.0" : 0.8691694228294644, + "99.9" : 0.8691694228294644, + "99.99" : 0.8691694228294644, + "99.999" : 0.8691694228294644, + "99.9999" : 0.8691694228294644, + "100.0" : 0.8691694228294644 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8688666246158518, + 0.8691694228294644 + ], + [ + 0.8688009019274694, + 0.8691309753714946 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70232.01481354213, + "scoreError" : 1538.188912414745, + "scoreConfidence" : [ + 68693.82590112739, + 71770.20372595688 + ], + "scorePercentiles" : { + "0.0" : 68834.11719335812, + "50.0" : 70335.7912615769, + "90.0" : 71248.55268371207, + "95.0" : 71248.55268371207, + "99.0" : 71248.55268371207, + "99.9" : 71248.55268371207, + "99.99" : 71248.55268371207, + "99.999" : 71248.55268371207, + "99.9999" : 71248.55268371207, + "100.0" : 71248.55268371207 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70335.7912615769, + 70318.29869520647, + 70615.3482588539 + ], + [ + 68834.11719335812, + 69184.4699954476, + 69310.74272699936 + ], + [ + 71248.55268371207, + 71233.87557474103, + 71006.93693198367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 348.7358560146452, + "scoreError" : 9.45323495910323, + "scoreConfidence" : [ + 339.282621055542, + 358.1890909737484 + ], + "scorePercentiles" : { + "0.0" : 339.467589297965, + "50.0" : 351.0502196395492, + "90.0" : 355.2367532576896, + "95.0" : 355.2367532576896, + "99.0" : 355.2367532576896, + "99.9" : 355.2367532576896, + "99.99" : 355.2367532576896, + "99.999" : 355.2367532576896, + "99.9999" : 355.2367532576896, + "100.0" : 355.2367532576896 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 348.6266856905834, + 353.7210730850551, + 355.2367532576896 + ], + [ + 352.2086936648004, + 352.1941358313394, + 351.0502196395492 + ], + [ + 341.2831938162754, + 344.83435984855004, + 339.467589297965 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.8976425616819, + "scoreError" : 4.5235077479722525, + "scoreConfidence" : [ + 104.37413481370966, + 113.42115030965415 + ], + "scorePercentiles" : { + "0.0" : 105.13588070683821, + "50.0" : 109.84674602291123, + "90.0" : 111.53991107410427, + "95.0" : 111.53991107410427, + "99.0" : 111.53991107410427, + "99.9" : 111.53991107410427, + "99.99" : 111.53991107410427, + "99.999" : 111.53991107410427, + "99.9999" : 111.53991107410427, + "100.0" : 111.53991107410427 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.9271038747169, + 109.84674602291123, + 109.28821350660738 + ], + [ + 111.47146048588766, + 111.53978992907797, + 111.53991107410427 + ], + [ + 105.33613831237075, + 105.13588070683821, + 105.99353914262285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014151886837748762, + "scoreError" : 1.8201815515134884E-4, + "scoreConfidence" : [ + 0.013969868682597412, + 0.01433390499290011 + ], + "scorePercentiles" : { + "0.0" : 0.014046185393534612, + "50.0" : 0.014093099466441932, + "90.0" : 0.014298931872192083, + "95.0" : 0.014298931872192083, + "99.0" : 0.014298931872192083, + "99.9" : 0.014298931872192083, + "99.99" : 0.014298931872192083, + "99.999" : 0.014298931872192083, + "99.9999" : 0.014298931872192083, + "100.0" : 0.014298931872192083 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014065132065705843, + 0.014167577229310642, + 0.014048452400921006 + ], + [ + 0.014294062328473413, + 0.014270803594771241, + 0.014298931872192083 + ], + [ + 0.014093099466441932, + 0.01408273718838808, + 0.014046185393534612 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9825431540425588, + "scoreError" : 0.010821959248908594, + "scoreConfidence" : [ + 0.9717211947936502, + 0.9933651132914674 + ], + "scorePercentiles" : { + "0.0" : 0.9743582786438035, + "50.0" : 0.9813524897458542, + "90.0" : 0.993766748981417, + "95.0" : 0.993766748981417, + "99.0" : 0.993766748981417, + "99.9" : 0.993766748981417, + "99.99" : 0.993766748981417, + "99.999" : 0.993766748981417, + "99.9999" : 0.993766748981417, + "100.0" : 0.993766748981417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9828495155773955, + 0.978821331604189, + 0.9806014058638949 + ], + [ + 0.9832963547689282, + 0.9763275131309187, + 0.9813524897458542 + ], + [ + 0.9743582786438035, + 0.993766748981417, + 0.991514748066627 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01300260075448132, + "scoreError" : 8.023467513972726E-4, + "scoreConfidence" : [ + 0.012200254003084048, + 0.013804947505878594 + ], + "scorePercentiles" : { + "0.0" : 0.012720992199664173, + "50.0" : 0.012971484214673937, + "90.0" : 0.013335832962161846, + "95.0" : 0.013335832962161846, + "99.0" : 0.013335832962161846, + "99.9" : 0.013335832962161846, + "99.99" : 0.013335832962161846, + "99.999" : 0.013335832962161846, + "99.9999" : 0.013335832962161846, + "100.0" : 0.013335832962161846 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012720992199664173, + 0.012732649700408199, + 0.012790562874435309 + ], + [ + 0.013152405554912565, + 0.013283161235305837, + 0.013335832962161846 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.7915260479825292, + "scoreError" : 0.1983707891453185, + "scoreConfidence" : [ + 3.5931552588372107, + 3.989896837127848 + ], + "scorePercentiles" : { + "0.0" : 3.6699134086573735, + "50.0" : 3.7937304046584868, + "90.0" : 3.8893684937791604, + "95.0" : 3.8893684937791604, + "99.0" : 3.8893684937791604, + "99.9" : 3.8893684937791604, + "99.99" : 3.8893684937791604, + "99.999" : 3.8893684937791604, + "99.9999" : 3.8893684937791604, + "100.0" : 3.8893684937791604 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6699134086573735, + 3.7899163765151513, + 3.797544432801822 + ], + [ + 3.8893684937791604, + 3.7865034678274037, + 3.815910108314264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8929701553211618, + "scoreError" : 0.11108803922461892, + "scoreConfidence" : [ + 2.781882116096543, + 3.0040581945457805 + ], + "scorePercentiles" : { + "0.0" : 2.7998811998880178, + "50.0" : 2.9051692349695033, + "90.0" : 2.975505501636418, + "95.0" : 2.975505501636418, + "99.0" : 2.975505501636418, + "99.9" : 2.975505501636418, + "99.99" : 2.975505501636418, + "99.999" : 2.975505501636418, + "99.9999" : 2.975505501636418, + "100.0" : 2.975505501636418 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.975505501636418, + 2.9466927030053034, + 2.966848873331356 + ], + [ + 2.827787556969183, + 2.7998811998880178, + 2.8193454034395264 + ], + [ + 2.9229998939216832, + 2.9051692349695033, + 2.872501030729466 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17544947039487774, + "scoreError" : 0.0052488607290020655, + "scoreConfidence" : [ + 0.17020060966587566, + 0.1806983311238798 + ], + "scorePercentiles" : { + "0.0" : 0.17165985189508376, + "50.0" : 0.17549794610578778, + "90.0" : 0.179824128751506, + "95.0" : 0.179824128751506, + "99.0" : 0.179824128751506, + "99.9" : 0.179824128751506, + "99.99" : 0.179824128751506, + "99.999" : 0.179824128751506, + "99.9999" : 0.179824128751506, + "100.0" : 0.179824128751506 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17227370679942808, + 0.17183004900512044, + 0.17165985189508376 + ], + [ + 0.178551218915155, + 0.179824128751506, + 0.17882252447114783 + ], + [ + 0.17549794610578778, + 0.17569065722066057, + 0.17489515039001013 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3358209039887323, + "scoreError" : 0.015562757724852853, + "scoreConfidence" : [ + 0.3202581462638795, + 0.35138366171358515 + ], + "scorePercentiles" : { + "0.0" : 0.32385241021406136, + "50.0" : 0.3377909938186117, + "90.0" : 0.34700695846490165, + "95.0" : 0.34700695846490165, + "99.0" : 0.34700695846490165, + "99.9" : 0.34700695846490165, + "99.99" : 0.34700695846490165, + "99.999" : 0.34700695846490165, + "99.9999" : 0.34700695846490165, + "100.0" : 0.34700695846490165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32521056380487806, + 0.32385241021406136, + 0.32386125089060175 + ], + [ + 0.34700695846490165, + 0.34364055864059656, + 0.3447147407790417 + ], + [ + 0.3377909938186117, + 0.3400444924342888, + 0.336266166851609 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16134176687262286, + "scoreError" : 0.004812602207946651, + "scoreConfidence" : [ + 0.1565291646646762, + 0.16615436908056952 + ], + "scorePercentiles" : { + "0.0" : 0.1572061005313463, + "50.0" : 0.16288815610900265, + "90.0" : 0.16382506316962092, + "95.0" : 0.16382506316962092, + "99.0" : 0.16382506316962092, + "99.9" : 0.16382506316962092, + "99.99" : 0.16382506316962092, + "99.999" : 0.16382506316962092, + "99.9999" : 0.16382506316962092, + "100.0" : 0.16382506316962092 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15762173064859328, + 0.1578787331270425, + 0.1572061005313463 + ], + [ + 0.16345162815860875, + 0.16382506316962092, + 0.16329059359589823 + ], + [ + 0.1623845217751364, + 0.16352937473835688, + 0.16288815610900265 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39310674445864563, + "scoreError" : 0.010868598898243683, + "scoreConfidence" : [ + 0.3822381455604019, + 0.40397534335688934 + ], + "scorePercentiles" : { + "0.0" : 0.3862654843182696, + "50.0" : 0.3901732209129926, + "90.0" : 0.40193320541778865, + "95.0" : 0.40193320541778865, + "99.0" : 0.40193320541778865, + "99.9" : 0.40193320541778865, + "99.99" : 0.40193320541778865, + "99.999" : 0.40193320541778865, + "99.9999" : 0.40193320541778865, + "100.0" : 0.40193320541778865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3939431058893047, + 0.3866839318304849, + 0.3862654843182696 + ], + [ + 0.40193320541778865, + 0.4007557186022281, + 0.4009131120109044 + ], + [ + 0.3901732209129926, + 0.3883718215853043, + 0.38892109956053356 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15737170175876328, + "scoreError" : 8.129918877386329E-4, + "scoreConfidence" : [ + 0.15655870987102463, + 0.15818469364650192 + ], + "scorePercentiles" : { + "0.0" : 0.15657145389071553, + "50.0" : 0.157625196081522, + "90.0" : 0.1578368545250797, + "95.0" : 0.1578368545250797, + "99.0" : 0.1578368545250797, + "99.9" : 0.1578368545250797, + "99.99" : 0.1578368545250797, + "99.999" : 0.1578368545250797, + "99.9999" : 0.1578368545250797, + "100.0" : 0.1578368545250797 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.156874781762279, + 0.15678063731284786, + 0.15657145389071553 + ], + [ + 0.1575724023540905, + 0.157625196081522, + 0.1578368545250797 + ], + [ + 0.15765837165379157, + 0.15771490363839955, + 0.15771071461014383 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04741806749151767, + "scoreError" : 0.0014343819370443356, + "scoreConfidence" : [ + 0.04598368555447333, + 0.048852449428562005 + ], + "scorePercentiles" : { + "0.0" : 0.04673769655968555, + "50.0" : 0.04698499036351762, + "90.0" : 0.04928052339557369, + "95.0" : 0.04928052339557369, + "99.0" : 0.04928052339557369, + "99.9" : 0.04928052339557369, + "99.99" : 0.04928052339557369, + "99.999" : 0.04928052339557369, + "99.9999" : 0.04928052339557369, + "100.0" : 0.04928052339557369 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04682732774065455, + 0.046959641036477706, + 0.04698499036351762 + ], + [ + 0.04928052339557369, + 0.04791430007809917, + 0.048122328429744905 + ], + [ + 0.04700595427325117, + 0.04673769655968555, + 0.04692984554665465 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9288801.490699522, + "scoreError" : 154527.26504390594, + "scoreConfidence" : [ + 9134274.225655615, + 9443328.755743429 + ], + "scorePercentiles" : { + "0.0" : 9205640.332106715, + "50.0" : 9236812.06278855, + "90.0" : 9426756.017907634, + "95.0" : 9426756.017907634, + "99.0" : 9426756.017907634, + "99.9" : 9426756.017907634, + "99.99" : 9426756.017907634, + "99.999" : 9426756.017907634, + "99.9999" : 9426756.017907634, + "100.0" : 9426756.017907634 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9376145.139643861, + 9426756.017907634, + 9423155.61299435 + ], + [ + 9205640.332106715, + 9212345.915285451, + 9249796.383548982 + ], + [ + 9236065.98984303, + 9236812.06278855, + 9232495.962177122 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-06T06:12:18Z-2e1e0ebf65b788790763a974ce9e8aea4e4e558d-jdk17.json b/performance-results/2025-03-06T06:12:18Z-2e1e0ebf65b788790763a974ce9e8aea4e4e558d-jdk17.json new file mode 100644 index 0000000000..206936aaca --- /dev/null +++ b/performance-results/2025-03-06T06:12:18Z-2e1e0ebf65b788790763a974ce9e8aea4e4e558d-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4115082119150353, + "scoreError" : 0.02941825923097294, + "scoreConfidence" : [ + 3.3820899526840624, + 3.440926471146008 + ], + "scorePercentiles" : { + "0.0" : 3.4064825548916207, + "50.0" : 3.4113171297808074, + "90.0" : 3.4169160332069057, + "95.0" : 3.4169160332069057, + "99.0" : 3.4169160332069057, + "99.9" : 3.4169160332069057, + "99.99" : 3.4169160332069057, + "99.999" : 3.4169160332069057, + "99.9999" : 3.4169160332069057, + "100.0" : 3.4169160332069057 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4064825548916207, + 3.4093676160232755 + ], + [ + 3.413266643538339, + 3.4169160332069057 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7317113411285598, + "scoreError" : 0.012064473875984218, + "scoreConfidence" : [ + 1.7196468672525755, + 1.7437758150045441 + ], + "scorePercentiles" : { + "0.0" : 1.7292424938779714, + "50.0" : 1.7319358983574031, + "90.0" : 1.7337310739214618, + "95.0" : 1.7337310739214618, + "99.0" : 1.7337310739214618, + "99.9" : 1.7337310739214618, + "99.99" : 1.7337310739214618, + "99.999" : 1.7337310739214618, + "99.9999" : 1.7337310739214618, + "100.0" : 1.7337310739214618 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7292424938779714, + 1.731634581684259 + ], + [ + 1.7322372150305472, + 1.7337310739214618 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8690424200353214, + "scoreError" : 0.0036514138591921194, + "scoreConfidence" : [ + 0.8653910061761293, + 0.8726938338945135 + ], + "scorePercentiles" : { + "0.0" : 0.8685279670834416, + "50.0" : 0.8689007639611597, + "90.0" : 0.8698401851355247, + "95.0" : 0.8698401851355247, + "99.0" : 0.8698401851355247, + "99.9" : 0.8698401851355247, + "99.99" : 0.8698401851355247, + "99.999" : 0.8698401851355247, + "99.9999" : 0.8698401851355247, + "100.0" : 0.8698401851355247 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8688095069876479, + 0.8698401851355247 + ], + [ + 0.8685279670834416, + 0.8689920209346713 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 71003.00198373497, + "scoreError" : 226.15950652706366, + "scoreConfidence" : [ + 70776.8424772079, + 71229.16149026203 + ], + "scorePercentiles" : { + "0.0" : 70857.99060334494, + "50.0" : 70923.80077840707, + "90.0" : 71184.9506282876, + "95.0" : 71184.9506282876, + "99.0" : 71184.9506282876, + "99.9" : 71184.9506282876, + "99.99" : 71184.9506282876, + "99.999" : 71184.9506282876, + "99.9999" : 71184.9506282876, + "100.0" : 71184.9506282876 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70973.6692035204, + 70923.80077840707, + 70903.17863630773 + ], + [ + 71184.9506282876, + 71184.3262835792, + 71164.54289466105 + ], + [ + 70857.99060334494, + 70916.85608232094, + 70917.70274318576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 352.38226824513544, + "scoreError" : 7.476513158615815, + "scoreConfidence" : [ + 344.9057550865196, + 359.85878140375127 + ], + "scorePercentiles" : { + "0.0" : 346.3626408752838, + "50.0" : 353.1910462537864, + "90.0" : 360.13309044096724, + "95.0" : 360.13309044096724, + "99.0" : 360.13309044096724, + "99.9" : 360.13309044096724, + "99.99" : 360.13309044096724, + "99.999" : 360.13309044096724, + "99.9999" : 360.13309044096724, + "100.0" : 360.13309044096724 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.13309044096724, + 354.0114902596122, + 354.8992054315646 + ], + [ + 348.1853851621876, + 346.3626408752838, + 346.95881248467407 + ], + [ + 354.5816970955848, + 353.11704620255824, + 353.1910462537864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 109.10022468858686, + "scoreError" : 2.3501641962858777, + "scoreConfidence" : [ + 106.75006049230099, + 111.45038888487274 + ], + "scorePercentiles" : { + "0.0" : 107.70994138070586, + "50.0" : 108.52727320445477, + "90.0" : 111.38642304206356, + "95.0" : 111.38642304206356, + "99.0" : 111.38642304206356, + "99.9" : 111.38642304206356, + "99.99" : 111.38642304206356, + "99.999" : 111.38642304206356, + "99.9999" : 111.38642304206356, + "100.0" : 111.38642304206356 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.52727320445477, + 108.48393073097333, + 108.75781417072851 + ], + [ + 111.38642304206356, + 110.86333689582654, + 110.38348521770283 + ], + [ + 107.70994138070586, + 107.92321928833897, + 107.86659826648732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014221039915220942, + "scoreError" : 2.626663013411908E-4, + "scoreConfidence" : [ + 0.01395837361387975, + 0.014483706216562134 + ], + "scorePercentiles" : { + "0.0" : 0.014024734535800536, + "50.0" : 0.014236648604823324, + "90.0" : 0.014412459617527056, + "95.0" : 0.014412459617527056, + "99.0" : 0.014412459617527056, + "99.9" : 0.014412459617527056, + "99.99" : 0.014412459617527056, + "99.999" : 0.014412459617527056, + "99.9999" : 0.014412459617527056, + "100.0" : 0.014412459617527056 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014412459617527056, + 0.014401516950372995, + 0.01437941576137362 + ], + [ + 0.014047371501014911, + 0.014042817105640093, + 0.014024734535800536 + ], + [ + 0.014236648604823324, + 0.014207094412131579, + 0.014237300748304356 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9942440211101774, + "scoreError" : 0.02390461473886758, + "scoreConfidence" : [ + 0.9703394063713098, + 1.018148635849045 + ], + "scorePercentiles" : { + "0.0" : 0.9743954687713144, + "50.0" : 0.9901732647524752, + "90.0" : 1.0120957015484262, + "95.0" : 1.0120957015484262, + "99.0" : 1.0120957015484262, + "99.9" : 1.0120957015484262, + "99.99" : 1.0120957015484262, + "99.999" : 1.0120957015484262, + "99.9999" : 1.0120957015484262, + "100.0" : 1.0120957015484262 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.010028034036966, + 1.0106066732012935, + 1.0120957015484262 + ], + [ + 0.9972798716593538, + 0.9773831014464426, + 0.9743954687713144 + ], + [ + 0.9866703780584056, + 0.9901732647524752, + 0.9895636965169207 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012955598848475294, + "scoreError" : 2.3999670936960022E-4, + "scoreConfidence" : [ + 0.012715602139105693, + 0.013195595557844894 + ], + "scorePercentiles" : { + "0.0" : 0.012822485927646949, + "50.0" : 0.012942355418299141, + "90.0" : 0.013063587491149645, + "95.0" : 0.013063587491149645, + "99.0" : 0.013063587491149645, + "99.9" : 0.013063587491149645, + "99.99" : 0.013063587491149645, + "99.999" : 0.013063587491149645, + "99.9999" : 0.013063587491149645, + "100.0" : 0.013063587491149645 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012822485927646949, + 0.012943171870550899, + 0.012941538966047385 + ], + [ + 0.012928680997347095, + 0.013034127838109786, + 0.013063587491149645 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.638930492890097, + "scoreError" : 0.1003970316328303, + "scoreConfidence" : [ + 3.5385334612572668, + 3.739327524522927 + ], + "scorePercentiles" : { + "0.0" : 3.5787822303290415, + "50.0" : 3.6449954462283793, + "90.0" : 3.6791761544117647, + "95.0" : 3.6791761544117647, + "99.0" : 3.6791761544117647, + "99.9" : 3.6791761544117647, + "99.99" : 3.6791761544117647, + "99.999" : 3.6791761544117647, + "99.9999" : 3.6791761544117647, + "100.0" : 3.6791761544117647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5787822303290415, + 3.63090818287373, + 3.6245014231884056 + ], + [ + 3.661132256954612, + 3.6590827095830285, + 3.6791761544117647 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.847417907792545, + "scoreError" : 0.116819409513867, + "scoreConfidence" : [ + 2.7305984982786784, + 2.964237317306412 + ], + "scorePercentiles" : { + "0.0" : 2.7529092496559318, + "50.0" : 2.8777063679516686, + "90.0" : 2.921575672801636, + "95.0" : 2.921575672801636, + "99.0" : 2.921575672801636, + "99.9" : 2.921575672801636, + "99.99" : 2.921575672801636, + "99.999" : 2.921575672801636, + "99.9999" : 2.921575672801636, + "100.0" : 2.921575672801636 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8777063679516686, + 2.877371197065593, + 2.882502662536023 + ], + [ + 2.921575672801636, + 2.903710849303136, + 2.8941062572337963 + ], + [ + 2.7529092496559318, + 2.757577626964433, + 2.7593012866206896 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1784711380749599, + "scoreError" : 0.006343286936357945, + "scoreConfidence" : [ + 0.17212785113860196, + 0.18481442501131784 + ], + "scorePercentiles" : { + "0.0" : 0.1745021115919521, + "50.0" : 0.17718292266123317, + "90.0" : 0.18330034890114927, + "95.0" : 0.18330034890114927, + "99.0" : 0.18330034890114927, + "99.9" : 0.18330034890114927, + "99.99" : 0.18330034890114927, + "99.999" : 0.18330034890114927, + "99.9999" : 0.18330034890114927, + "100.0" : 0.18330034890114927 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17538364753853977, + 0.17455278001396404, + 0.1745021115919521 + ], + [ + 0.17718292266123317, + 0.17657819980930184, + 0.17833551557735175 + ], + [ + 0.18330034890114927, + 0.18323100183227367, + 0.1831737147488735 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33533802084093994, + "scoreError" : 0.01194928814488877, + "scoreConfidence" : [ + 0.3233887326960512, + 0.3472873089858287 + ], + "scorePercentiles" : { + "0.0" : 0.32534111988418246, + "50.0" : 0.3390308479845408, + "90.0" : 0.3412313907732205, + "95.0" : 0.3412313907732205, + "99.0" : 0.3412313907732205, + "99.9" : 0.3412313907732205, + "99.99" : 0.3412313907732205, + "99.999" : 0.3412313907732205, + "99.9999" : 0.3412313907732205, + "100.0" : 0.3412313907732205 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.326667493417829, + 0.3258572763205057, + 0.32534111988418246 + ], + [ + 0.3390515225631463, + 0.3386837247942561, + 0.3390308479845408 + ], + [ + 0.3412313907732205, + 0.34111317256199475, + 0.34106563926878347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16927030043181046, + "scoreError" : 0.012463968221868946, + "scoreConfidence" : [ + 0.1568063322099415, + 0.18173426865367942 + ], + "scorePercentiles" : { + "0.0" : 0.1597120899798767, + "50.0" : 0.17153760280975008, + "90.0" : 0.17657531521700745, + "95.0" : 0.17657531521700745, + "99.0" : 0.17657531521700745, + "99.9" : 0.17657531521700745, + "99.99" : 0.17657531521700745, + "99.999" : 0.17657531521700745, + "99.9999" : 0.17657531521700745, + "100.0" : 0.17657531521700745 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15983509142345684, + 0.15978003380893796, + 0.1597120899798767 + ], + [ + 0.17657531521700745, + 0.17646659101095838, + 0.17618008565740562 + ], + [ + 0.17187182930015124, + 0.17147406467874965, + 0.17153760280975008 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3963000690307283, + "scoreError" : 0.005716787708106384, + "scoreConfidence" : [ + 0.3905832813226219, + 0.4020168567388347 + ], + "scorePercentiles" : { + "0.0" : 0.3926168154764242, + "50.0" : 0.3953295221378874, + "90.0" : 0.40172962820873337, + "95.0" : 0.40172962820873337, + "99.0" : 0.40172962820873337, + "99.9" : 0.40172962820873337, + "99.99" : 0.40172962820873337, + "99.999" : 0.40172962820873337, + "99.9999" : 0.40172962820873337, + "100.0" : 0.40172962820873337 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39757093607378546, + 0.39651309218508385, + 0.3953295221378874 + ], + [ + 0.40152707986027464, + 0.3943262865817594, + 0.39405590286862635 + ], + [ + 0.40172962820873337, + 0.3930313578839805, + 0.3926168154764242 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15831173145313004, + "scoreError" : 0.0030272423283522493, + "scoreConfidence" : [ + 0.1552844891247778, + 0.1613389737814823 + ], + "scorePercentiles" : { + "0.0" : 0.15655079634615987, + "50.0" : 0.1574761917074784, + "90.0" : 0.16100002611369602, + "95.0" : 0.16100002611369602, + "99.0" : 0.16100002611369602, + "99.9" : 0.16100002611369602, + "99.99" : 0.16100002611369602, + "99.999" : 0.16100002611369602, + "99.9999" : 0.16100002611369602, + "100.0" : 0.16100002611369602 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16100002611369602, + 0.16037180656231959, + 0.16022089158054956 + ], + [ + 0.15656058518982388, + 0.15671883595047797, + 0.15655079634615987 + ], + [ + 0.1587234615262523, + 0.1574761917074784, + 0.15718298810141307 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04721208488681848, + "scoreError" : 7.293969171730858E-4, + "scoreConfidence" : [ + 0.04648268796964539, + 0.04794148180399157 + ], + "scorePercentiles" : { + "0.0" : 0.04670943996973264, + "50.0" : 0.046960116708147454, + "90.0" : 0.0477835956565367, + "95.0" : 0.0477835956565367, + "99.0" : 0.0477835956565367, + "99.9" : 0.0477835956565367, + "99.99" : 0.0477835956565367, + "99.999" : 0.0477835956565367, + "99.9999" : 0.0477835956565367, + "100.0" : 0.0477835956565367 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047395170383184436, + 0.046960116708147454, + 0.04689423038326088 + ], + [ + 0.0477835956565367, + 0.04766173785477683, + 0.047752969949478065 + ], + [ + 0.04694250115242526, + 0.046809001923824055, + 0.04670943996973264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9630622.948722191, + "scoreError" : 363748.3480624857, + "scoreConfidence" : [ + 9266874.600659706, + 9994371.296784677 + ], + "scorePercentiles" : { + "0.0" : 9355448.681308411, + "50.0" : 9637481.202312138, + "90.0" : 9925310.231150793, + "95.0" : 9925310.231150793, + "99.0" : 9925310.231150793, + "99.9" : 9925310.231150793, + "99.99" : 9925310.231150793, + "99.999" : 9925310.231150793, + "99.9999" : 9925310.231150793, + "100.0" : 9925310.231150793 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9925310.231150793, + 9853500.939901479, + 9846036.579724409 + ], + [ + 9630494.096246392, + 9637481.202312138, + 9645752.631629702 + ], + [ + 9411868.841956725, + 9369713.334269663, + 9355448.681308411 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-12T01:40:12Z-11a2be59907cdbd3bb9943a941861930807555de-jdk17.json b/performance-results/2025-03-12T01:40:12Z-11a2be59907cdbd3bb9943a941861930807555de-jdk17.json new file mode 100644 index 0000000000..5dedbbda14 --- /dev/null +++ b/performance-results/2025-03-12T01:40:12Z-11a2be59907cdbd3bb9943a941861930807555de-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4076702946979935, + "scoreError" : 0.03121695051498341, + "scoreConfidence" : [ + 3.3764533441830102, + 3.438887245212977 + ], + "scorePercentiles" : { + "0.0" : 3.4023668922631765, + "50.0" : 3.407716749267827, + "90.0" : 3.4128807879931413, + "95.0" : 3.4128807879931413, + "99.0" : 3.4128807879931413, + "99.9" : 3.4128807879931413, + "99.99" : 3.4128807879931413, + "99.999" : 3.4128807879931413, + "99.9999" : 3.4128807879931413, + "100.0" : 3.4128807879931413 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4023668922631765, + 3.410430779758213 + ], + [ + 3.4050027187774417, + 3.4128807879931413 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7203584625512023, + "scoreError" : 0.016926372222672525, + "scoreConfidence" : [ + 1.7034320903285298, + 1.7372848347738747 + ], + "scorePercentiles" : { + "0.0" : 1.7179994830077605, + "50.0" : 1.7197199204007574, + "90.0" : 1.7239945263955332, + "95.0" : 1.7239945263955332, + "99.0" : 1.7239945263955332, + "99.9" : 1.7239945263955332, + "99.99" : 1.7239945263955332, + "99.999" : 1.7239945263955332, + "99.9999" : 1.7239945263955332, + "100.0" : 1.7239945263955332 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.720420690227677, + 1.7239945263955332 + ], + [ + 1.7179994830077605, + 1.7190191505738377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8648697545079026, + "scoreError" : 0.0075160983778016855, + "scoreConfidence" : [ + 0.857353656130101, + 0.8723858528857042 + ], + "scorePercentiles" : { + "0.0" : 0.863427883815053, + "50.0" : 0.8649943438233192, + "90.0" : 0.8660624465699193, + "95.0" : 0.8660624465699193, + "99.0" : 0.8660624465699193, + "99.9" : 0.8660624465699193, + "99.99" : 0.8660624465699193, + "99.999" : 0.8660624465699193, + "99.9999" : 0.8660624465699193, + "100.0" : 0.8660624465699193 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8644814960543413, + 0.8655071915922969 + ], + [ + 0.863427883815053, + 0.8660624465699193 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69389.95500863831, + "scoreError" : 1755.8886125589615, + "scoreConfidence" : [ + 67634.06639607935, + 71145.84362119727 + ], + "scorePercentiles" : { + "0.0" : 68185.71876777064, + "50.0" : 69278.7096608454, + "90.0" : 70722.78777504961, + "95.0" : 70722.78777504961, + "99.0" : 70722.78777504961, + "99.9" : 70722.78777504961, + "99.99" : 70722.78777504961, + "99.999" : 70722.78777504961, + "99.9999" : 70722.78777504961, + "100.0" : 70722.78777504961 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69364.0209108631, + 69204.40314517489, + 69278.7096608454 + ], + [ + 70609.4285342994, + 70601.79215979534, + 70722.78777504961 + ], + [ + 68185.71876777064, + 68237.46553567571, + 68305.26858827074 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 340.8338008020541, + "scoreError" : 2.893493166734086, + "scoreConfidence" : [ + 337.94030763532004, + 343.72729396878816 + ], + "scorePercentiles" : { + "0.0" : 337.51858191131913, + "50.0" : 341.0045137233911, + "90.0" : 343.1466067997579, + "95.0" : 343.1466067997579, + "99.0" : 343.1466067997579, + "99.9" : 343.1466067997579, + "99.99" : 343.1466067997579, + "99.999" : 343.1466067997579, + "99.9999" : 343.1466067997579, + "100.0" : 343.1466067997579 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 341.79525643351167, + 340.68463968792423, + 339.4671920234933 + ], + [ + 339.7021322573094, + 341.88583929366797, + 342.2994450881126 + ], + [ + 343.1466067997579, + 341.0045137233911, + 337.51858191131913 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 101.9505095823736, + "scoreError" : 3.70236669542828, + "scoreConfidence" : [ + 98.24814288694532, + 105.65287627780188 + ], + "scorePercentiles" : { + "0.0" : 98.95005773885293, + "50.0" : 101.69121875987764, + "90.0" : 104.79007731231022, + "95.0" : 104.79007731231022, + "99.0" : 104.79007731231022, + "99.9" : 104.79007731231022, + "99.99" : 104.79007731231022, + "99.999" : 104.79007731231022, + "99.9999" : 104.79007731231022, + "100.0" : 104.79007731231022 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.69121875987764, + 100.87319417929982, + 102.02589744799347 + ], + [ + 100.31006870314435, + 98.95005773885293, + 99.839171786519 + ], + [ + 104.51878795064138, + 104.79007731231022, + 104.55611236272352 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014207907244656271, + "scoreError" : 1.406139052230887E-4, + "scoreConfidence" : [ + 0.014067293339433183, + 0.01434852114987936 + ], + "scorePercentiles" : { + "0.0" : 0.014080431946664038, + "50.0" : 0.014222649451795088, + "90.0" : 0.01430348100952599, + "95.0" : 0.01430348100952599, + "99.0" : 0.01430348100952599, + "99.9" : 0.01430348100952599, + "99.99" : 0.01430348100952599, + "99.999" : 0.01430348100952599, + "99.9999" : 0.01430348100952599, + "100.0" : 0.01430348100952599 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01410771311237201, + 0.014080431946664038, + 0.014127782222950578 + ], + [ + 0.014288505505292396, + 0.01430348100952599, + 0.014290552535683052 + ], + [ + 0.014220443325151943, + 0.014229606092471352, + 0.014222649451795088 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9899931875389658, + "scoreError" : 0.019138091109985326, + "scoreConfidence" : [ + 0.9708550964289805, + 1.0091312786489512 + ], + "scorePercentiles" : { + "0.0" : 0.9765089769553754, + "50.0" : 0.9884470899476129, + "90.0" : 1.0120053324225866, + "95.0" : 1.0120053324225866, + "99.0" : 1.0120053324225866, + "99.9" : 1.0120053324225866, + "99.99" : 1.0120053324225866, + "99.999" : 1.0120053324225866, + "99.9999" : 1.0120053324225866, + "100.0" : 1.0120053324225866 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9765089769553754, + 0.9884470899476129, + 0.9902420496088722 + ], + [ + 0.98586842636041, + 0.9818955948944527, + 0.9790268553108175 + ], + [ + 1.0120053324225866, + 1.0023681029367546, + 0.9935762594138102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013177577224591489, + "scoreError" : 4.270440246067902E-4, + "scoreConfidence" : [ + 0.012750533199984699, + 0.013604621249198279 + ], + "scorePercentiles" : { + "0.0" : 0.012983986930667359, + "50.0" : 0.013193273216565243, + "90.0" : 0.013348885971492874, + "95.0" : 0.013348885971492874, + "99.0" : 0.013348885971492874, + "99.9" : 0.013348885971492874, + "99.99" : 0.013348885971492874, + "99.999" : 0.013348885971492874, + "99.9999" : 0.013348885971492874, + "100.0" : 0.013348885971492874 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013293016413664762, + 0.013348885971492874, + 0.013292778899067935 + ], + [ + 0.012983986930667359, + 0.01309376753406255, + 0.013053027598593442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8965855004740657, + "scoreError" : 0.13698940967062448, + "scoreConfidence" : [ + 3.7595960908034414, + 4.03357491014469 + ], + "scorePercentiles" : { + "0.0" : 3.8204210718105425, + "50.0" : 3.8998276071221425, + "90.0" : 3.9658294631245044, + "95.0" : 3.9658294631245044, + "99.0" : 3.9658294631245044, + "99.9" : 3.9658294631245044, + "99.99" : 3.9658294631245044, + "99.999" : 3.9658294631245044, + "99.9999" : 3.9658294631245044, + "100.0" : 3.9658294631245044 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9658294631245044, + 3.885656021756022, + 3.9181803915426783 + ], + [ + 3.8204210718105425, + 3.913999192488263, + 3.875426862122386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.953343152087654, + "scoreError" : 0.1008413095317884, + "scoreConfidence" : [ + 2.8525018425558653, + 3.0541844616194425 + ], + "scorePercentiles" : { + "0.0" : 2.8928908501590973, + "50.0" : 2.9422236131215063, + "90.0" : 3.05081770347773, + "95.0" : 3.05081770347773, + "99.0" : 3.05081770347773, + "99.9" : 3.05081770347773, + "99.99" : 3.05081770347773, + "99.999" : 3.05081770347773, + "99.9999" : 3.05081770347773, + "100.0" : 3.05081770347773 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9494852205838984, + 2.9129140305765873, + 2.8928908501590973 + ], + [ + 3.033292042462845, + 2.997000550494456, + 3.05081770347773 + ], + [ + 2.9422236131215063, + 2.895923255356109, + 2.9055411025566533 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1740608663647572, + "scoreError" : 0.0031797824390332624, + "scoreConfidence" : [ + 0.17088108392572393, + 0.17724064880379048 + ], + "scorePercentiles" : { + "0.0" : 0.1714743284349869, + "50.0" : 0.17423779480433496, + "90.0" : 0.17657913986544949, + "95.0" : 0.17657913986544949, + "99.0" : 0.17657913986544949, + "99.9" : 0.17657913986544949, + "99.99" : 0.17657913986544949, + "99.999" : 0.17657913986544949, + "99.9999" : 0.17657913986544949, + "100.0" : 0.17657913986544949 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17490636216878006, + 0.17413062688490336, + 0.17423779480433496 + ], + [ + 0.17180489303691995, + 0.17198642027689398, + 0.1714743284349869 + ], + [ + 0.17657913986544949, + 0.17574860689618813, + 0.17567962491435798 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3220899653280465, + "scoreError" : 0.011797543311675193, + "scoreConfidence" : [ + 0.3102924220163713, + 0.3338875086397217 + ], + "scorePercentiles" : { + "0.0" : 0.3133007488329835, + "50.0" : 0.32191402085948817, + "90.0" : 0.33121310459378, + "95.0" : 0.33121310459378, + "99.0" : 0.33121310459378, + "99.9" : 0.33121310459378, + "99.99" : 0.33121310459378, + "99.999" : 0.33121310459378, + "99.9999" : 0.33121310459378, + "100.0" : 0.33121310459378 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32191402085948817, + 0.32146066157703557, + 0.32222403992266796 + ], + [ + 0.33121310459378, + 0.3296149954843601, + 0.33000252455121437 + ], + [ + 0.3147955884852682, + 0.3133007488329835, + 0.31428400364562054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16434010627076526, + "scoreError" : 0.006922172642315291, + "scoreConfidence" : [ + 0.15741793362844997, + 0.17126227891308055 + ], + "scorePercentiles" : { + "0.0" : 0.158946975888103, + "50.0" : 0.16548735592182562, + "90.0" : 0.16844729587144372, + "95.0" : 0.16844729587144372, + "99.0" : 0.16844729587144372, + "99.9" : 0.16844729587144372, + "99.99" : 0.16844729587144372, + "99.999" : 0.16844729587144372, + "99.9999" : 0.16844729587144372, + "100.0" : 0.16844729587144372 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16844729587144372, + 0.16825600417262557, + 0.16784994932693276 + ], + [ + 0.16515502999124704, + 0.16548735592182562, + 0.1666896035204107 + ], + [ + 0.15900905450700417, + 0.1592196872372946, + 0.158946975888103 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38842922644034866, + "scoreError" : 0.0067031864482287465, + "scoreConfidence" : [ + 0.3817260399921199, + 0.3951324128885774 + ], + "scorePercentiles" : { + "0.0" : 0.3846055533633322, + "50.0" : 0.38798181970902035, + "90.0" : 0.3976954414618627, + "95.0" : 0.3976954414618627, + "99.0" : 0.3976954414618627, + "99.9" : 0.3976954414618627, + "99.99" : 0.3976954414618627, + "99.999" : 0.3976954414618627, + "99.9999" : 0.3976954414618627, + "100.0" : 0.3976954414618627 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3976954414618627, + 0.3865560140316969, + 0.3859009754572818 + ], + [ + 0.39057186982502734, + 0.38881781959564543, + 0.38798181970902035 + ], + [ + 0.3887489937801275, + 0.38498455073914384, + 0.3846055533633322 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15897312984427683, + "scoreError" : 0.007362010999413564, + "scoreConfidence" : [ + 0.15161111884486328, + 0.1663351408436904 + ], + "scorePercentiles" : { + "0.0" : 0.15367977617101058, + "50.0" : 0.15898293027137883, + "90.0" : 0.1647780857321755, + "95.0" : 0.1647780857321755, + "99.0" : 0.1647780857321755, + "99.9" : 0.1647780857321755, + "99.99" : 0.1647780857321755, + "99.999" : 0.1647780857321755, + "99.9999" : 0.1647780857321755, + "100.0" : 0.1647780857321755 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15948752983955855, + 0.15898293027137883, + 0.15867462969074783 + ], + [ + 0.1647780857321755, + 0.16382083167878908, + 0.163306469478738 + ], + [ + 0.15408670708782743, + 0.15394120864826588, + 0.15367977617101058 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047710108860097446, + "scoreError" : 6.500947272283788E-4, + "scoreConfidence" : [ + 0.04706001413286907, + 0.048360203587325824 + ], + "scorePercentiles" : { + "0.0" : 0.0472659968237763, + "50.0" : 0.04773794186079817, + "90.0" : 0.04823766706864117, + "95.0" : 0.04823766706864117, + "99.0" : 0.04823766706864117, + "99.9" : 0.04823766706864117, + "99.99" : 0.04823766706864117, + "99.999" : 0.04823766706864117, + "99.9999" : 0.04823766706864117, + "100.0" : 0.04823766706864117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04823766706864117, + 0.04728105270822301, + 0.0472659968237763 + ], + [ + 0.047403124687144485, + 0.04773794186079817, + 0.04735863134240711 + ], + [ + 0.04801767788341496, + 0.0480227627954552, + 0.04806612457101658 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9545103.75383263, + "scoreError" : 383788.9358783984, + "scoreConfidence" : [ + 9161314.817954233, + 9928892.689711029 + ], + "scorePercentiles" : { + "0.0" : 9173861.760769935, + "50.0" : 9645109.1195757, + "90.0" : 9782659.88172043, + "95.0" : 9782659.88172043, + "99.0" : 9782659.88172043, + "99.9" : 9782659.88172043, + "99.99" : 9782659.88172043, + "99.999" : 9782659.88172043, + "99.9999" : 9782659.88172043, + "100.0" : 9782659.88172043 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9722427.170068027, + 9638300.232177263, + 9645109.1195757 + ], + [ + 9782659.88172043, + 9661711.056949807, + 9705344.597478177 + ], + [ + 9317311.997206705, + 9173861.760769935, + 9259207.96854764 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-13T01:14:36Z-753555fd9ff1dae369f13fde1198ecf0ccdbe3f3-jdk17.json b/performance-results/2025-03-13T01:14:36Z-753555fd9ff1dae369f13fde1198ecf0ccdbe3f3-jdk17.json new file mode 100644 index 0000000000..9a95fb387f --- /dev/null +++ b/performance-results/2025-03-13T01:14:36Z-753555fd9ff1dae369f13fde1198ecf0ccdbe3f3-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4235289471012904, + "scoreError" : 0.025315012152433914, + "scoreConfidence" : [ + 3.3982139349488567, + 3.448843959253724 + ], + "scorePercentiles" : { + "0.0" : 3.418973543921273, + "50.0" : 3.423959070120495, + "90.0" : 3.4272241042428986, + "95.0" : 3.4272241042428986, + "99.0" : 3.4272241042428986, + "99.9" : 3.4272241042428986, + "99.99" : 3.4272241042428986, + "99.999" : 3.4272241042428986, + "99.9999" : 3.4272241042428986, + "100.0" : 3.4272241042428986 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4215857667884384, + 3.4272241042428986 + ], + [ + 3.418973543921273, + 3.4263323734525515 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.731466065401667, + "scoreError" : 0.01621103250787632, + "scoreConfidence" : [ + 1.7152550328937906, + 1.7476770979095433 + ], + "scorePercentiles" : { + "0.0" : 1.7288700515575068, + "50.0" : 1.7310567913839625, + "90.0" : 1.7348806272812356, + "95.0" : 1.7348806272812356, + "99.0" : 1.7348806272812356, + "99.9" : 1.7348806272812356, + "99.99" : 1.7348806272812356, + "99.999" : 1.7348806272812356, + "99.9999" : 1.7348806272812356, + "100.0" : 1.7348806272812356 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7288700515575068, + 1.7313277369538398 + ], + [ + 1.7307858458140855, + 1.7348806272812356 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8697984954948363, + "scoreError" : 0.008861407151655697, + "scoreConfidence" : [ + 0.8609370883431806, + 0.8786599026464921 + ], + "scorePercentiles" : { + "0.0" : 0.8679124538019363, + "50.0" : 0.8700474146575718, + "90.0" : 0.8711866988622655, + "95.0" : 0.8711866988622655, + "99.0" : 0.8711866988622655, + "99.9" : 0.8711866988622655, + "99.99" : 0.8711866988622655, + "99.999" : 0.8711866988622655, + "99.9999" : 0.8711866988622655, + "100.0" : 0.8711866988622655 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8679124538019363, + 0.8699183582693664 + ], + [ + 0.8711866988622655, + 0.8701764710457774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70820.79388702071, + "scoreError" : 231.68668855776454, + "scoreConfidence" : [ + 70589.10719846295, + 71052.48057557848 + ], + "scorePercentiles" : { + "0.0" : 70629.0793607269, + "50.0" : 70911.01076174284, + "90.0" : 70941.7424562172, + "95.0" : 70941.7424562172, + "99.0" : 70941.7424562172, + "99.9" : 70941.7424562172, + "99.99" : 70941.7424562172, + "99.999" : 70941.7424562172, + "99.9999" : 70941.7424562172, + "100.0" : 70941.7424562172 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70643.28992633008, + 70629.0793607269, + 70657.4130445598 + ], + [ + 70920.59943604424, + 70921.67177006771, + 70939.99468918028 + ], + [ + 70911.01076174284, + 70822.34353831736, + 70941.7424562172 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.2295935097646, + "scoreError" : 11.639809665349746, + "scoreConfidence" : [ + 338.58978384441485, + 361.8694031751143 + ], + "scorePercentiles" : { + "0.0" : 340.89493260237515, + "50.0" : 353.68886615744447, + "90.0" : 355.99957632871315, + "95.0" : 355.99957632871315, + "99.0" : 355.99957632871315, + "99.9" : 355.99957632871315, + "99.99" : 355.99957632871315, + "99.999" : 355.99957632871315, + "99.9999" : 355.99957632871315, + "100.0" : 355.99957632871315 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 340.89493260237515, + 341.42435224510996, + 341.26510021738767 + ], + [ + 355.6708203390944, + 355.8300028298273, + 355.99957632871315 + ], + [ + 351.49926625063017, + 353.68886615744447, + 355.79342461729897 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.65109974016178, + "scoreError" : 2.5522442534017724, + "scoreConfidence" : [ + 106.09885548676002, + 111.20334399356355 + ], + "scorePercentiles" : { + "0.0" : 107.03049434345812, + "50.0" : 108.17258660022053, + "90.0" : 110.61737269420547, + "95.0" : 110.61737269420547, + "99.0" : 110.61737269420547, + "99.9" : 110.61737269420547, + "99.99" : 110.61737269420547, + "99.999" : 110.61737269420547, + "99.9999" : 110.61737269420547, + "100.0" : 110.61737269420547 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.82145896771539, + 108.17258660022053, + 108.24703418493814 + ], + [ + 110.58815235947327, + 110.61737269420547, + 110.60165244657608 + ], + [ + 107.66093902870458, + 107.03049434345812, + 107.12020703616446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014279243473265146, + "scoreError" : 4.394936204422015E-4, + "scoreConfidence" : [ + 0.013839749852822944, + 0.014718737093707348 + ], + "scorePercentiles" : { + "0.0" : 0.014042465096456565, + "50.0" : 0.014159224540681671, + "90.0" : 0.014676226498498639, + "95.0" : 0.014676226498498639, + "99.0" : 0.014676226498498639, + "99.9" : 0.014676226498498639, + "99.99" : 0.014676226498498639, + "99.999" : 0.014676226498498639, + "99.9999" : 0.014676226498498639, + "100.0" : 0.014676226498498639 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014202651352641087, + 0.014158744326676936, + 0.014159224540681671 + ], + [ + 0.014591742794315707, + 0.014676226498498639, + 0.01458607336714348 + ], + [ + 0.014043656603105857, + 0.014052406679866392, + 0.014042465096456565 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9710502426780204, + "scoreError" : 0.014764440975773075, + "scoreConfidence" : [ + 0.9562858017022473, + 0.9858146836537935 + ], + "scorePercentiles" : { + "0.0" : 0.9562935803212851, + "50.0" : 0.9705228318128882, + "90.0" : 0.984122220035426, + "95.0" : 0.984122220035426, + "99.0" : 0.984122220035426, + "99.9" : 0.984122220035426, + "99.99" : 0.984122220035426, + "99.999" : 0.984122220035426, + "99.9999" : 0.984122220035426, + "100.0" : 0.984122220035426 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9703851923151562, + 0.9705228318128882, + 0.984122220035426 + ], + [ + 0.9797588517683943, + 0.9756658378536586, + 0.9748855913433417 + ], + [ + 0.9665884706166634, + 0.9562935803212851, + 0.961229608035371 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01294115826408152, + "scoreError" : 0.001014437164646088, + "scoreConfidence" : [ + 0.011926721099435432, + 0.013955595428727608 + ], + "scorePercentiles" : { + "0.0" : 0.012536907865737619, + "50.0" : 0.012912209069093654, + "90.0" : 0.013316694295522761, + "95.0" : 0.013316694295522761, + "99.0" : 0.013316694295522761, + "99.9" : 0.013316694295522761, + "99.99" : 0.013316694295522761, + "99.999" : 0.013316694295522761, + "99.9999" : 0.013316694295522761, + "100.0" : 0.013316694295522761 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013166219852067968, + 0.013316694295522761, + 0.013312663393594078 + ], + [ + 0.012536907865737619, + 0.01265626589144736, + 0.012658198286119339 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.659688428674198, + "scoreError" : 0.35262658295588856, + "scoreConfidence" : [ + 3.3070618457183096, + 4.012315011630086 + ], + "scorePercentiles" : { + "0.0" : 3.5062078731604767, + "50.0" : 3.6768514411668174, + "90.0" : 3.774024763773585, + "95.0" : 3.774024763773585, + "99.0" : 3.774024763773585, + "99.9" : 3.774024763773585, + "99.99" : 3.774024763773585, + "99.999" : 3.774024763773585, + "99.9999" : 3.774024763773585, + "100.0" : 3.774024763773585 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5062078731604767, + 3.551304622159091, + 3.5838853209169055 + ], + [ + 3.774024763773585, + 3.7698175614167293, + 3.7728904306184012 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8300064842002626, + "scoreError" : 0.045503109266854615, + "scoreConfidence" : [ + 2.784503374933408, + 2.8755095934671173 + ], + "scorePercentiles" : { + "0.0" : 2.8048665698261357, + "50.0" : 2.817010330140845, + "90.0" : 2.8728336325768455, + "95.0" : 2.8728336325768455, + "99.0" : 2.8728336325768455, + "99.9" : 2.8728336325768455, + "99.99" : 2.8728336325768455, + "99.999" : 2.8728336325768455, + "99.9999" : 2.8728336325768455, + "100.0" : 2.8728336325768455 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.817010330140845, + 2.8212701472496473, + 2.807157726915521 + ], + [ + 2.8048665698261357, + 2.809550511516854, + 2.8145303981429377 + ], + [ + 2.862065851788269, + 2.860773189645309, + 2.8728336325768455 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1831706552485558, + "scoreError" : 0.01373850570445273, + "scoreConfidence" : [ + 0.16943214954410307, + 0.19690916095300853 + ], + "scorePercentiles" : { + "0.0" : 0.1770023762257071, + "50.0" : 0.17780909203250297, + "90.0" : 0.19403957457748802, + "95.0" : 0.19403957457748802, + "99.0" : 0.19403957457748802, + "99.9" : 0.19403957457748802, + "99.99" : 0.19403957457748802, + "99.999" : 0.19403957457748802, + "99.9999" : 0.19403957457748802, + "100.0" : 0.19403957457748802 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17979130297909063, + 0.17780909203250297, + 0.17764850200739005 + ], + [ + 0.1771452058563027, + 0.1770023762257071, + 0.17709491752851172 + ], + [ + 0.1940173466232078, + 0.19403957457748802, + 0.19398757940680103 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3325174605480197, + "scoreError" : 0.01808023901793655, + "scoreConfidence" : [ + 0.3144372215300832, + 0.35059769956595627 + ], + "scorePercentiles" : { + "0.0" : 0.3243598086990367, + "50.0" : 0.32611440247839557, + "90.0" : 0.34748987869627157, + "95.0" : 0.34748987869627157, + "99.0" : 0.34748987869627157, + "99.9" : 0.34748987869627157, + "99.99" : 0.34748987869627157, + "99.999" : 0.34748987869627157, + "99.9999" : 0.34748987869627157, + "100.0" : 0.34748987869627157 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32611440247839557, + 0.32569432595101616, + 0.3270104821621268 + ], + [ + 0.34748987869627157, + 0.34672240551972816, + 0.34622278749480684 + ], + [ + 0.324573349680309, + 0.3243598086990367, + 0.3244697042504867 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1563755353557113, + "scoreError" : 0.008218591647864093, + "scoreConfidence" : [ + 0.1481569437078472, + 0.1645941270035754 + ], + "scorePercentiles" : { + "0.0" : 0.15114627648801426, + "50.0" : 0.15527347374386685, + "90.0" : 0.1627050920731509, + "95.0" : 0.1627050920731509, + "99.0" : 0.1627050920731509, + "99.9" : 0.1627050920731509, + "99.99" : 0.1627050920731509, + "99.999" : 0.1627050920731509, + "99.9999" : 0.1627050920731509, + "100.0" : 0.1627050920731509 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1627050920731509, + 0.16256147183705316, + 0.16222034130357202 + ], + [ + 0.1551279640884835, + 0.15535810315524554, + 0.15527347374386685 + ], + [ + 0.15164503142012284, + 0.1513420640918928, + 0.15114627648801426 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3909588769316857, + "scoreError" : 0.007017556895511356, + "scoreConfidence" : [ + 0.3839413200361743, + 0.39797643382719705 + ], + "scorePercentiles" : { + "0.0" : 0.38759703340955776, + "50.0" : 0.3903544967797338, + "90.0" : 0.39986755376064614, + "95.0" : 0.39986755376064614, + "99.0" : 0.39986755376064614, + "99.9" : 0.39986755376064614, + "99.99" : 0.39986755376064614, + "99.999" : 0.39986755376064614, + "99.9999" : 0.39986755376064614, + "100.0" : 0.39986755376064614 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.390763948382307, + 0.39082237861497576, + 0.3903544967797338 + ], + [ + 0.39986755376064614, + 0.3884779611918266, + 0.38759703340955776 + ], + [ + 0.3954614829167985, + 0.3876213509050738, + 0.3876636864242518 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15722552517859067, + "scoreError" : 0.0011511582869311112, + "scoreConfidence" : [ + 0.15607436689165957, + 0.15837668346552178 + ], + "scorePercentiles" : { + "0.0" : 0.1562580664864527, + "50.0" : 0.15734629136509534, + "90.0" : 0.15837414240691763, + "95.0" : 0.15837414240691763, + "99.0" : 0.15837414240691763, + "99.9" : 0.15837414240691763, + "99.99" : 0.15837414240691763, + "99.999" : 0.15837414240691763, + "99.9999" : 0.15837414240691763, + "100.0" : 0.15837414240691763 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15734629136509534, + 0.15751020181448755, + 0.15674231195924765 + ], + [ + 0.15837414240691763, + 0.15780906814057347, + 0.156918052864473 + ], + [ + 0.15761143390754778, + 0.15646015766252053, + 0.1562580664864527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04698808880000418, + "scoreError" : 8.233100908406212E-4, + "scoreConfidence" : [ + 0.04616477870916356, + 0.0478113988908448 + ], + "scorePercentiles" : { + "0.0" : 0.04632947766947111, + "50.0" : 0.046950707557091347, + "90.0" : 0.04777402328470013, + "95.0" : 0.04777402328470013, + "99.0" : 0.04777402328470013, + "99.9" : 0.04777402328470013, + "99.99" : 0.04777402328470013, + "99.999" : 0.04777402328470013, + "99.9999" : 0.04777402328470013, + "100.0" : 0.04777402328470013 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04702555390236677, + 0.04694176933151202, + 0.046950707557091347 + ], + [ + 0.0475525959219386, + 0.04777402328470013, + 0.04725548325284239 + ], + [ + 0.04670036606984412, + 0.046362822210271076, + 0.04632947766947111 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9317046.219681531, + "scoreError" : 207195.67907354757, + "scoreConfidence" : [ + 9109850.540607983, + 9524241.89875508 + ], + "scorePercentiles" : { + "0.0" : 9157390.381518755, + "50.0" : 9319772.534948742, + "90.0" : 9506483.568441065, + "95.0" : 9506483.568441065, + "99.0" : 9506483.568441065, + "99.9" : 9506483.568441065, + "99.99" : 9506483.568441065, + "99.999" : 9506483.568441065, + "99.9999" : 9506483.568441065, + "100.0" : 9506483.568441065 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9304948.350697674, + 9321557.7166822, + 9319772.534948742 + ], + [ + 9210019.607734807, + 9168707.978001833, + 9157390.381518755 + ], + [ + 9506483.568441065, + 9437706.294339623, + 9426829.544769086 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-15T11:47:41Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json b/performance-results/2025-03-15T11:47:41Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json new file mode 100644 index 0000000000..e193b1af7c --- /dev/null +++ b/performance-results/2025-03-15T11:47:41Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4231252386576827, + "scoreError" : 0.018002418557553388, + "scoreConfidence" : [ + 3.405122820100129, + 3.4411276572152363 + ], + "scorePercentiles" : { + "0.0" : 3.4206360868600725, + "50.0" : 3.4227234889032605, + "90.0" : 3.426417889964138, + "95.0" : 3.426417889964138, + "99.0" : 3.426417889964138, + "99.9" : 3.426417889964138, + "99.99" : 3.426417889964138, + "99.999" : 3.426417889964138, + "99.9999" : 3.426417889964138, + "100.0" : 3.426417889964138 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4206360868600725, + 3.426417889964138 + ], + [ + 3.4210025321286244, + 3.4244444456778966 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7292023782063795, + "scoreError" : 0.008901727040554206, + "scoreConfidence" : [ + 1.7203006511658252, + 1.7381041052469337 + ], + "scorePercentiles" : { + "0.0" : 1.727258983952786, + "50.0" : 1.7295273432478537, + "90.0" : 1.7304958423770247, + "95.0" : 1.7304958423770247, + "99.0" : 1.7304958423770247, + "99.9" : 1.7304958423770247, + "99.99" : 1.7304958423770247, + "99.999" : 1.7304958423770247, + "99.9999" : 1.7304958423770247, + "100.0" : 1.7304958423770247 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.727258983952786, + 1.729653664527176 + ], + [ + 1.7294010219685314, + 1.7304958423770247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.869712827685915, + "scoreError" : 0.004324516237681346, + "scoreConfidence" : [ + 0.8653883114482336, + 0.8740373439235963 + ], + "scorePercentiles" : { + "0.0" : 0.8688162079164902, + "50.0" : 0.8698652531758249, + "90.0" : 0.8703045964755199, + "95.0" : 0.8703045964755199, + "99.0" : 0.8703045964755199, + "99.9" : 0.8703045964755199, + "99.99" : 0.8703045964755199, + "99.999" : 0.8703045964755199, + "99.9999" : 0.8703045964755199, + "100.0" : 0.8703045964755199 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8695978615068914, + 0.8703045964755199 + ], + [ + 0.8688162079164902, + 0.8701326448447583 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69653.97322970562, + "scoreError" : 1241.7114519240731, + "scoreConfidence" : [ + 68412.26177778155, + 70895.68468162969 + ], + "scorePercentiles" : { + "0.0" : 68917.9239635008, + "50.0" : 69422.69087159562, + "90.0" : 70623.12588344632, + "95.0" : 70623.12588344632, + "99.0" : 70623.12588344632, + "99.9" : 70623.12588344632, + "99.99" : 70623.12588344632, + "99.999" : 70623.12588344632, + "99.9999" : 70623.12588344632, + "100.0" : 70623.12588344632 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69422.69087159562, + 69447.65361598988, + 69400.19164738775 + ], + [ + 68940.63600147932, + 68961.39448861738, + 68917.9239635008 + ], + [ + 70600.79825836433, + 70571.34433696925, + 70623.12588344632 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 354.88093484304494, + "scoreError" : 7.331351454553499, + "scoreConfidence" : [ + 347.54958338849144, + 362.21228629759844 + ], + "scorePercentiles" : { + "0.0" : 350.8325447951137, + "50.0" : 353.1650809438877, + "90.0" : 361.5314151767399, + "95.0" : 361.5314151767399, + "99.0" : 361.5314151767399, + "99.9" : 361.5314151767399, + "99.99" : 361.5314151767399, + "99.999" : 361.5314151767399, + "99.9999" : 361.5314151767399, + "100.0" : 361.5314151767399 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.55160168006574, + 350.8325447951137, + 351.18421384816645 + ], + [ + 361.5314151767399, + 360.32258091010436, + 359.8482269083232 + ], + [ + 353.1650809438877, + 353.2751303140137, + 352.217619010989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.31040747128041, + "scoreError" : 1.5707935883293318, + "scoreConfidence" : [ + 103.73961388295108, + 106.88120105960975 + ], + "scorePercentiles" : { + "0.0" : 103.84489219491039, + "50.0" : 105.45124511244312, + "90.0" : 106.35534837676299, + "95.0" : 106.35534837676299, + "99.0" : 106.35534837676299, + "99.9" : 106.35534837676299, + "99.99" : 106.35534837676299, + "99.999" : 106.35534837676299, + "99.9999" : 106.35534837676299, + "100.0" : 106.35534837676299 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.26255275762055, + 106.35534837676299, + 106.22838730121315 + ], + [ + 104.56216360600726, + 103.84489219491039, + 104.14140128934277 + ], + [ + 105.44628502972814, + 105.45124511244312, + 105.50139157349538 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014266009260685645, + "scoreError" : 2.4840351995337605E-4, + "scoreConfidence" : [ + 0.014017605740732268, + 0.014514412780639021 + ], + "scorePercentiles" : { + "0.0" : 0.01415508872730258, + "50.0" : 0.014178914767305513, + "90.0" : 0.014487416443321521, + "95.0" : 0.014487416443321521, + "99.0" : 0.014487416443321521, + "99.9" : 0.014487416443321521, + "99.99" : 0.014487416443321521, + "99.999" : 0.014487416443321521, + "99.9999" : 0.014487416443321521, + "100.0" : 0.014487416443321521 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014487416443321521, + 0.014444846733189272, + 0.014454177195923972 + ], + [ + 0.01415580208738833, + 0.01415508872730258, + 0.014162183566676203 + ], + [ + 0.014173912294303573, + 0.014178914767305513, + 0.014181741530759849 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9737795573950387, + "scoreError" : 0.023019476479558414, + "scoreConfidence" : [ + 0.9507600809154804, + 0.9967990338745971 + ], + "scorePercentiles" : { + "0.0" : 0.9530193546788641, + "50.0" : 0.9795748023312764, + "90.0" : 0.9933472102701629, + "95.0" : 0.9933472102701629, + "99.0" : 0.9933472102701629, + "99.9" : 0.9933472102701629, + "99.99" : 0.9933472102701629, + "99.999" : 0.9933472102701629, + "99.9999" : 0.9933472102701629, + "100.0" : 0.9933472102701629 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9583253188003066, + 0.9530193546788641, + 0.9583518679444178 + ], + [ + 0.9933472102701629, + 0.9791489124730761, + 0.9805528812628689 + ], + [ + 0.9819098810996564, + 0.9797857876947194, + 0.9795748023312764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013001308170039402, + "scoreError" : 2.976310973814306E-4, + "scoreConfidence" : [ + 0.012703677072657972, + 0.013298939267420833 + ], + "scorePercentiles" : { + "0.0" : 0.01288314263629407, + "50.0" : 0.013002860792589627, + "90.0" : 0.013110911374780397, + "95.0" : 0.013110911374780397, + "99.0" : 0.013110911374780397, + "99.9" : 0.013110911374780397, + "99.99" : 0.013110911374780397, + "99.999" : 0.013110911374780397, + "99.9999" : 0.013110911374780397, + "100.0" : 0.013110911374780397 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01288314263629407, + 0.012924590065370965, + 0.01290896248228287 + ], + [ + 0.013081131519808288, + 0.013099110941699807, + 0.013110911374780397 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6469265221099043, + "scoreError" : 0.233983938982243, + "scoreConfidence" : [ + 3.4129425831276614, + 3.880910461092147 + ], + "scorePercentiles" : { + "0.0" : 3.550249164655784, + "50.0" : 3.6518308336198055, + "90.0" : 3.725429276247208, + "95.0" : 3.725429276247208, + "99.0" : 3.725429276247208, + "99.9" : 3.725429276247208, + "99.99" : 3.725429276247208, + "99.999" : 3.725429276247208, + "99.9999" : 3.725429276247208, + "100.0" : 3.725429276247208 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.71911931598513, + 3.72239825, + 3.725429276247208 + ], + [ + 3.550249164655784, + 3.5798207745168216, + 3.5845423512544805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8297739018441317, + "scoreError" : 0.055082385306873205, + "scoreConfidence" : [ + 2.7746915165372585, + 2.884856287151005 + ], + "scorePercentiles" : { + "0.0" : 2.776723303442532, + "50.0" : 2.849999239954403, + "90.0" : 2.857089768637532, + "95.0" : 2.857089768637532, + "99.0" : 2.857089768637532, + "99.9" : 2.857089768637532, + "99.99" : 2.857089768637532, + "99.999" : 2.857089768637532, + "99.9999" : 2.857089768637532, + "100.0" : 2.857089768637532 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.857089768637532, + 2.846963235980643, + 2.8502645807922486 + ], + [ + 2.849999239954403, + 2.8532497991440797, + 2.850531029353092 + ], + [ + 2.7937917039106144, + 2.7893524553820415, + 2.776723303442532 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17399340825190943, + "scoreError" : 0.002415189799166387, + "scoreConfidence" : [ + 0.17157821845274304, + 0.1764085980510758 + ], + "scorePercentiles" : { + "0.0" : 0.17195098658802896, + "50.0" : 0.17425089607945635, + "90.0" : 0.17574364637446838, + "95.0" : 0.17574364637446838, + "99.0" : 0.17574364637446838, + "99.9" : 0.17574364637446838, + "99.99" : 0.17574364637446838, + "99.999" : 0.17574364637446838, + "99.9999" : 0.17574364637446838, + "100.0" : 0.17574364637446838 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17527287233371308, + 0.1742294504242382, + 0.17425089607945635 + ], + [ + 0.17256591154443485, + 0.17195098658802896, + 0.17207340420882372 + ], + [ + 0.17574364637446838, + 0.17510702307867412, + 0.17474648363534695 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3288146853420742, + "scoreError" : 0.00961866055753691, + "scoreConfidence" : [ + 0.3191960247845373, + 0.3384333458996111 + ], + "scorePercentiles" : { + "0.0" : 0.3229496437267883, + "50.0" : 0.32701093767371897, + "90.0" : 0.33675235816271554, + "95.0" : 0.33675235816271554, + "99.0" : 0.33675235816271554, + "99.9" : 0.33675235816271554, + "99.99" : 0.33675235816271554, + "99.999" : 0.33675235816271554, + "99.9999" : 0.33675235816271554, + "100.0" : 0.33675235816271554 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3237096521865795, + 0.3234401143633365, + 0.3229496437267883 + ], + [ + 0.3271919762792828, + 0.32659347181580667, + 0.32701093767371897 + ], + [ + 0.33675235816271554, + 0.33555434001073753, + 0.3361296738597022 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16611211253103553, + "scoreError" : 0.012610331553940314, + "scoreConfidence" : [ + 0.15350178097709521, + 0.17872244408497584 + ], + "scorePercentiles" : { + "0.0" : 0.15637186147206455, + "50.0" : 0.16811454968479447, + "90.0" : 0.17377661910471623, + "95.0" : 0.17377661910471623, + "99.0" : 0.17377661910471623, + "99.9" : 0.17377661910471623, + "99.99" : 0.17377661910471623, + "99.999" : 0.17377661910471623, + "99.9999" : 0.17377661910471623, + "100.0" : 0.17377661910471623 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16811454968479447, + 0.16761891483405966, + 0.168381385940394 + ], + [ + 0.1568560021488848, + 0.15637186147206455, + 0.1567233963923019 + ], + [ + 0.1736130055380983, + 0.17377661910471623, + 0.17355327766400555 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3944184633266344, + "scoreError" : 0.009038540290119374, + "scoreConfidence" : [ + 0.385379923036515, + 0.40345700361675374 + ], + "scorePercentiles" : { + "0.0" : 0.3866889062294575, + "50.0" : 0.3934567140103081, + "90.0" : 0.4031605217899617, + "95.0" : 0.4031605217899617, + "99.0" : 0.4031605217899617, + "99.9" : 0.4031605217899617, + "99.99" : 0.4031605217899617, + "99.999" : 0.4031605217899617, + "99.9999" : 0.4031605217899617, + "100.0" : 0.4031605217899617 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3925430768566494, + 0.3866889062294575, + 0.38754908797085724 + ], + [ + 0.4031605217899617, + 0.3982964957384101, + 0.39914906773369524 + ], + [ + 0.39622482324973257, + 0.3934567140103081, + 0.39269747636063773 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15571468225916585, + "scoreError" : 0.0021395399956352862, + "scoreConfidence" : [ + 0.15357514226353056, + 0.15785422225480114 + ], + "scorePercentiles" : { + "0.0" : 0.15414635183044317, + "50.0" : 0.15539449561798802, + "90.0" : 0.15795597009951035, + "95.0" : 0.15795597009951035, + "99.0" : 0.15795597009951035, + "99.9" : 0.15795597009951035, + "99.99" : 0.15795597009951035, + "99.999" : 0.15795597009951035, + "99.9999" : 0.15795597009951035, + "100.0" : 0.15795597009951035 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1554432936860758, + 0.1543657783489241, + 0.15414635183044317 + ], + [ + 0.15795597009951035, + 0.15723632378930819, + 0.1565063382214849 + ], + [ + 0.15517247261273004, + 0.15539449561798802, + 0.15521111612602825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048346727576037835, + "scoreError" : 7.806057457140025E-4, + "scoreConfidence" : [ + 0.04756612183032383, + 0.049127333321751836 + ], + "scorePercentiles" : { + "0.0" : 0.04790786884931756, + "50.0" : 0.04807760585096154, + "90.0" : 0.0491959880701133, + "95.0" : 0.0491959880701133, + "99.0" : 0.0491959880701133, + "99.9" : 0.0491959880701133, + "99.99" : 0.0491959880701133, + "99.999" : 0.0491959880701133, + "99.9999" : 0.0491959880701133, + "100.0" : 0.0491959880701133 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04790786884931756, + 0.048031901780996936, + 0.04796132565802095 + ], + [ + 0.04867936401871206, + 0.04863606014726767, + 0.048699932351881255 + ], + [ + 0.0491959880701133, + 0.04793050145706918, + 0.04807760585096154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9389509.542990893, + "scoreError" : 168809.23465839543, + "scoreConfidence" : [ + 9220700.308332497, + 9558318.777649289 + ], + "scorePercentiles" : { + "0.0" : 9245023.112754159, + "50.0" : 9440439.841509433, + "90.0" : 9504771.950617284, + "95.0" : 9504771.950617284, + "99.0" : 9504771.950617284, + "99.9" : 9504771.950617284, + "99.99" : 9504771.950617284, + "99.999" : 9504771.950617284, + "99.9999" : 9504771.950617284, + "100.0" : 9504771.950617284 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9447608.750708215, + 9440439.841509433, + 9409778.511759171 + ], + [ + 9458990.512287335, + 9504771.950617284, + 9461597.62630085 + ], + [ + 9290695.124419684, + 9245023.112754159, + 9246680.456561923 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-15T21:51:58Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json b/performance-results/2025-03-15T21:51:58Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json new file mode 100644 index 0000000000..44fbbec310 --- /dev/null +++ b/performance-results/2025-03-15T21:51:58Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.419081479349856, + "scoreError" : 0.02181667824030549, + "scoreConfidence" : [ + 3.3972648011095505, + 3.4408981575901616 + ], + "scorePercentiles" : { + "0.0" : 3.4151876582998333, + "50.0" : 3.418878719276705, + "90.0" : 3.4233808205461798, + "95.0" : 3.4233808205461798, + "99.0" : 3.4233808205461798, + "99.9" : 3.4233808205461798, + "99.99" : 3.4233808205461798, + "99.999" : 3.4233808205461798, + "99.9999" : 3.4233808205461798, + "100.0" : 3.4233808205461798 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4183955684003458, + 3.4233808205461798 + ], + [ + 3.4151876582998333, + 3.4193618701530646 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7278052370461388, + "scoreError" : 0.015468518360417289, + "scoreConfidence" : [ + 1.7123367186857215, + 1.743273755406556 + ], + "scorePercentiles" : { + "0.0" : 1.725058425680371, + "50.0" : 1.7276601761908168, + "90.0" : 1.7308421701225511, + "95.0" : 1.7308421701225511, + "99.0" : 1.7308421701225511, + "99.9" : 1.7308421701225511, + "99.99" : 1.7308421701225511, + "99.999" : 1.7308421701225511, + "99.9999" : 1.7308421701225511, + "100.0" : 1.7308421701225511 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.725058425680371, + 1.7272240633541005 + ], + [ + 1.7280962890275329, + 1.7308421701225511 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8685942360123592, + "scoreError" : 0.0032093629192022875, + "scoreConfidence" : [ + 0.8653848730931569, + 0.8718035989315615 + ], + "scorePercentiles" : { + "0.0" : 0.8680596600008403, + "50.0" : 0.8685323243645763, + "90.0" : 0.8692526353194442, + "95.0" : 0.8692526353194442, + "99.0" : 0.8692526353194442, + "99.9" : 0.8692526353194442, + "99.99" : 0.8692526353194442, + "99.999" : 0.8692526353194442, + "99.9999" : 0.8692526353194442, + "100.0" : 0.8692526353194442 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8684515043579376, + 0.8692526353194442 + ], + [ + 0.8680596600008403, + 0.868613144371215 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70219.63258531665, + "scoreError" : 2456.2624530759686, + "scoreConfidence" : [ + 67763.37013224069, + 72675.89503839261 + ], + "scorePercentiles" : { + "0.0" : 68262.69827508756, + "50.0" : 71070.91574665892, + "90.0" : 71360.62796599019, + "95.0" : 71360.62796599019, + "99.0" : 71360.62796599019, + "99.9" : 71360.62796599019, + "99.99" : 71360.62796599019, + "99.999" : 71360.62796599019, + "99.9999" : 71360.62796599019, + "100.0" : 71360.62796599019 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71090.84115154805, + 71070.91574665892, + 71068.11668011114 + ], + [ + 71326.00567174528, + 71360.62796599019, + 71232.73593615185 + ], + [ + 68263.9148079727, + 68262.69827508756, + 68300.83703258426 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 352.62506314566724, + "scoreError" : 5.912882195955713, + "scoreConfidence" : [ + 346.7121809497115, + 358.53794534162296 + ], + "scorePercentiles" : { + "0.0" : 348.5994939203698, + "50.0" : 351.2596406536745, + "90.0" : 357.8709892240457, + "95.0" : 357.8709892240457, + "99.0" : 357.8709892240457, + "99.9" : 357.8709892240457, + "99.99" : 357.8709892240457, + "99.999" : 357.8709892240457, + "99.9999" : 357.8709892240457, + "100.0" : 357.8709892240457 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.6002990284403, + 357.8709892240457, + 355.992835288197 + ], + [ + 355.0809382965137, + 351.2596406536745, + 350.96968106293775 + ], + [ + 348.5994939203698, + 349.08160018811935, + 349.1700906487072 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.6838769084973, + "scoreError" : 2.183117097066455, + "scoreConfidence" : [ + 105.50075981143084, + 109.86699400556375 + ], + "scorePercentiles" : { + "0.0" : 106.1920201263132, + "50.0" : 107.28988932269989, + "90.0" : 109.68039857724867, + "95.0" : 109.68039857724867, + "99.0" : 109.68039857724867, + "99.9" : 109.68039857724867, + "99.99" : 109.68039857724867, + "99.999" : 109.68039857724867, + "99.9999" : 109.68039857724867, + "100.0" : 109.68039857724867 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.1920201263132, + 106.3107103466616, + 106.51494550464022 + ], + [ + 109.68039857724867, + 108.93303271007677, + 109.1345679005366 + ], + [ + 107.85149666900807, + 107.24783101929074, + 107.28988932269989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01424904469711514, + "scoreError" : 2.8712049885863054E-4, + "scoreConfidence" : [ + 0.01396192419825651, + 0.01453616519597377 + ], + "scorePercentiles" : { + "0.0" : 0.014081548691345716, + "50.0" : 0.014197285943467211, + "90.0" : 0.014469735555761344, + "95.0" : 0.014469735555761344, + "99.0" : 0.014469735555761344, + "99.9" : 0.014469735555761344, + "99.99" : 0.014469735555761344, + "99.999" : 0.014469735555761344, + "99.9999" : 0.014469735555761344, + "100.0" : 0.014469735555761344 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014469735555761344, + 0.014466371526486872, + 0.014465053651656951 + ], + [ + 0.014084542436261102, + 0.014081548691345716, + 0.014082558140615627 + ], + [ + 0.014202345880946092, + 0.014197285943467211, + 0.014191960447495364 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9605920681254805, + "scoreError" : 0.0156261620457851, + "scoreConfidence" : [ + 0.9449659060796953, + 0.9762182301712656 + ], + "scorePercentiles" : { + "0.0" : 0.9515725629876308, + "50.0" : 0.9594482724743356, + "90.0" : 0.9813261324698264, + "95.0" : 0.9813261324698264, + "99.0" : 0.9813261324698264, + "99.9" : 0.9813261324698264, + "99.99" : 0.9813261324698264, + "99.999" : 0.9813261324698264, + "99.9999" : 0.9813261324698264, + "100.0" : 0.9813261324698264 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9632121626697486, + 0.9640522833317265, + 0.9634844487475915 + ], + [ + 0.9523479509570517, + 0.9517655204149614, + 0.9515725629876308 + ], + [ + 0.9581192790764514, + 0.9594482724743356, + 0.9813261324698264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012935286805918217, + "scoreError" : 2.0065649442416766E-4, + "scoreConfidence" : [ + 0.01273463031149405, + 0.013135943300342384 + ], + "scorePercentiles" : { + "0.0" : 0.01282056484627199, + "50.0" : 0.012957244368985167, + "90.0" : 0.01300262296676349, + "95.0" : 0.01300262296676349, + "99.0" : 0.01300262296676349, + "99.9" : 0.01300262296676349, + "99.99" : 0.01300262296676349, + "99.999" : 0.01300262296676349, + "99.9999" : 0.01300262296676349, + "100.0" : 0.01300262296676349 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012886497260394009, + 0.012987495216820997, + 0.012987547024109466 + ], + [ + 0.01282056484627199, + 0.012926993521149337, + 0.01300262296676349 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6640448498751206, + "scoreError" : 0.10001425229743845, + "scoreConfidence" : [ + 3.5640305975776823, + 3.764059102172559 + ], + "scorePercentiles" : { + "0.0" : 3.6288989746008706, + "50.0" : 3.664207595317245, + "90.0" : 3.697876677014043, + "95.0" : 3.697876677014043, + "99.0" : 3.697876677014043, + "99.9" : 3.697876677014043, + "99.99" : 3.697876677014043, + "99.999" : 3.697876677014043, + "99.9999" : 3.697876677014043, + "100.0" : 3.697876677014043 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.697876677014043, + 3.6976350059127863, + 3.6941182392909897 + ], + [ + 3.6288989746008706, + 3.6342969513435004, + 3.631443251088534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.796145889648464, + "scoreError" : 0.10606264859186876, + "scoreConfidence" : [ + 2.690083241056595, + 2.9022085382403326 + ], + "scorePercentiles" : { + "0.0" : 2.735265740153173, + "50.0" : 2.7747582746947836, + "90.0" : 2.8826144273775216, + "95.0" : 2.8826144273775216, + "99.0" : 2.8826144273775216, + "99.9" : 2.8826144273775216, + "99.99" : 2.8826144273775216, + "99.999" : 2.8826144273775216, + "99.9999" : 2.8826144273775216, + "100.0" : 2.8826144273775216 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.77613158340272, + 2.7747582746947836, + 2.759658219646799 + ], + [ + 2.7483473440505635, + 2.735265740153173, + 2.7371980117679255 + ], + [ + 2.86899744205393, + 2.8823419636887606, + 2.8826144273775216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18386029216491354, + "scoreError" : 0.015936383371688425, + "scoreConfidence" : [ + 0.1679239087932251, + 0.19979667553660196 + ], + "scorePercentiles" : { + "0.0" : 0.17637173245149912, + "50.0" : 0.1786052278401886, + "90.0" : 0.1967785992325856, + "95.0" : 0.1967785992325856, + "99.0" : 0.1967785992325856, + "99.9" : 0.1967785992325856, + "99.99" : 0.1967785992325856, + "99.999" : 0.1967785992325856, + "99.9999" : 0.1967785992325856, + "100.0" : 0.1967785992325856 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17676752035423257, + 0.17639937312800974, + 0.17637173245149912 + ], + [ + 0.1965152944112561, + 0.19603218908905573, + 0.1967785992325856 + ], + [ + 0.17880823137303986, + 0.17846446160435442, + 0.1786052278401886 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3268686979876325, + "scoreError" : 0.009509582095350317, + "scoreConfidence" : [ + 0.3173591158922822, + 0.3363782800829828 + ], + "scorePercentiles" : { + "0.0" : 0.32142813943173054, + "50.0" : 0.3239967884011016, + "90.0" : 0.3350558973766208, + "95.0" : 0.3350558973766208, + "99.0" : 0.3350558973766208, + "99.9" : 0.3350558973766208, + "99.99" : 0.3350558973766208, + "99.999" : 0.3350558973766208, + "99.9999" : 0.3350558973766208, + "100.0" : 0.3350558973766208 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32486509677419356, + 0.3239967884011016, + 0.32357341784766713 + ], + [ + 0.33470154652252493, + 0.33304827188863356, + 0.3350558973766208 + ], + [ + 0.3226825007905521, + 0.32142813943173054, + 0.3224666228556688 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16040518763688932, + "scoreError" : 0.005985603649017898, + "scoreConfidence" : [ + 0.15441958398787142, + 0.16639079128590722 + ], + "scorePercentiles" : { + "0.0" : 0.15520278784163394, + "50.0" : 0.16224452822168503, + "90.0" : 0.1633454222407344, + "95.0" : 0.1633454222407344, + "99.0" : 0.1633454222407344, + "99.9" : 0.1633454222407344, + "99.99" : 0.1633454222407344, + "99.999" : 0.1633454222407344, + "99.9999" : 0.1633454222407344, + "100.0" : 0.1633454222407344 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16206104194013646, + 0.16235918097835794, + 0.16224452822168503 + ], + [ + 0.15520278784163394, + 0.15584427127228526, + 0.15607415878763287 + ], + [ + 0.1633454222407344, + 0.16317626146691686, + 0.1633390359826212 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39186170392434727, + "scoreError" : 0.008382766232144253, + "scoreConfidence" : [ + 0.38347893769220304, + 0.4002444701564915 + ], + "scorePercentiles" : { + "0.0" : 0.3852108789723046, + "50.0" : 0.39403914370148546, + "90.0" : 0.39714948530579824, + "95.0" : 0.39714948530579824, + "99.0" : 0.39714948530579824, + "99.9" : 0.39714948530579824, + "99.99" : 0.39714948530579824, + "99.999" : 0.39714948530579824, + "99.9999" : 0.39714948530579824, + "100.0" : 0.39714948530579824 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38585839105606357, + 0.38531843093284013, + 0.3852108789723046 + ], + [ + 0.3969191444334193, + 0.39403914370148546, + 0.3927082935794227 + ], + [ + 0.39714948530579824, + 0.394844230031192, + 0.3947073373065993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15617891534733674, + "scoreError" : 0.0027246898703879286, + "scoreConfidence" : [ + 0.1534542254769488, + 0.15890360521772467 + ], + "scorePercentiles" : { + "0.0" : 0.15406912377709647, + "50.0" : 0.1558871378020265, + "90.0" : 0.15838028224133288, + "95.0" : 0.15838028224133288, + "99.0" : 0.15838028224133288, + "99.9" : 0.15838028224133288, + "99.99" : 0.15838028224133288, + "99.999" : 0.15838028224133288, + "99.9999" : 0.15838028224133288, + "100.0" : 0.15838028224133288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15838028224133288, + 0.15824253888757023, + 0.1577863723847392 + ], + [ + 0.15528550955760181, + 0.15422730028839776, + 0.15406912377709647 + ], + [ + 0.1558871378020265, + 0.155819362336003, + 0.15591261085126287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046892479422411135, + "scoreError" : 7.27228595279716E-4, + "scoreConfidence" : [ + 0.04616525082713142, + 0.04761970801769085 + ], + "scorePercentiles" : { + "0.0" : 0.04646620786848378, + "50.0" : 0.04681246217834389, + "90.0" : 0.04745806077877702, + "95.0" : 0.04745806077877702, + "99.0" : 0.04745806077877702, + "99.9" : 0.04745806077877702, + "99.99" : 0.04745806077877702, + "99.999" : 0.04745806077877702, + "99.9999" : 0.04745806077877702, + "100.0" : 0.04745806077877702 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04697078824430134, + 0.04647115450996794, + 0.04646620786848378 + ], + [ + 0.04681246217834389, + 0.04654221015349387, + 0.04649830915304675 + ], + [ + 0.04740479233190489, + 0.04740832958338074, + 0.04745806077877702 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9153374.794718103, + "scoreError" : 35141.224373571386, + "scoreConfidence" : [ + 9118233.570344532, + 9188516.019091675 + ], + "scorePercentiles" : { + "0.0" : 9121060.185050137, + "50.0" : 9156568.882891126, + "90.0" : 9189768.824609734, + "95.0" : 9189768.824609734, + "99.0" : 9189768.824609734, + "99.9" : 9189768.824609734, + "99.99" : 9189768.824609734, + "99.999" : 9189768.824609734, + "99.9999" : 9189768.824609734, + "100.0" : 9189768.824609734 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9138728.467579909, + 9135038.461187216, + 9121060.185050137 + ], + [ + 9144502.108775137, + 9156568.882891126, + 9157744.234432235 + ], + [ + 9189768.824609734, + 9171180.827681027, + 9165781.16025641 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-15T22:05:06Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json b/performance-results/2025-03-15T22:05:06Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json new file mode 100644 index 0000000000..662bfc4c3b --- /dev/null +++ b/performance-results/2025-03-15T22:05:06Z-2d799ff19a93b0033f4386c5f73692f03905ad99-jdk17.json @@ -0,0 +1,1074 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.419640407240273, + "scoreError" : 0.033845851587922124, + "scoreConfidence" : [ + 3.3857945556523505, + 3.453486258828195 + ], + "scorePercentiles" : { + "0.0" : 3.4146699284177893, + "50.0" : 3.4184445363788676, + "90.0" : 3.427002627785568, + "95.0" : 3.427002627785568, + "99.0" : 3.427002627785568, + "99.9" : 3.427002627785568, + "99.99" : 3.427002627785568, + "99.999" : 3.427002627785568, + "99.9999" : 3.427002627785568, + "100.0" : 3.427002627785568 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.418960193365409, + 3.427002627785568 + ], + [ + 3.4146699284177893, + 3.417928879392327 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.728259570626513, + "scoreError" : 0.009225737494153523, + "scoreConfidence" : [ + 1.7190338331323594, + 1.7374853081206665 + ], + "scorePercentiles" : { + "0.0" : 1.726468041428064, + "50.0" : 1.7283038272179163, + "90.0" : 1.7299625866421546, + "95.0" : 1.7299625866421546, + "99.0" : 1.7299625866421546, + "99.9" : 1.7299625866421546, + "99.99" : 1.7299625866421546, + "99.999" : 1.7299625866421546, + "99.9999" : 1.7299625866421546, + "100.0" : 1.7299625866421546 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7282796925630504, + 1.7299625866421546 + ], + [ + 1.726468041428064, + 1.7283279618727825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8681979109233867, + "scoreError" : 0.006028616842983343, + "scoreConfidence" : [ + 0.8621692940804033, + 0.8742265277663701 + ], + "scorePercentiles" : { + "0.0" : 0.8668273030701195, + "50.0" : 0.8685266393427444, + "90.0" : 0.8689110619379388, + "95.0" : 0.8689110619379388, + "99.0" : 0.8689110619379388, + "99.9" : 0.8689110619379388, + "99.99" : 0.8689110619379388, + "99.999" : 0.8689110619379388, + "99.9999" : 0.8689110619379388, + "100.0" : 0.8689110619379388 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8685892047662458, + 0.8689110619379388 + ], + [ + 0.8668273030701195, + 0.8684640739192432 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69648.01861478564, + "scoreError" : 2087.607519878574, + "scoreConfidence" : [ + 67560.41109490707, + 71735.62613466421 + ], + "scorePercentiles" : { + "0.0" : 68001.28467819697, + "50.0" : 69992.90089804973, + "90.0" : 71029.82538555992, + "95.0" : 71029.82538555992, + "99.0" : 71029.82538555992, + "99.9" : 71029.82538555992, + "99.99" : 71029.82538555992, + "99.999" : 71029.82538555992, + "99.9999" : 71029.82538555992, + "100.0" : 71029.82538555992 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68001.28467819697, + 70138.72785998843, + 69992.90089804973 + ], + [ + 71001.67829047698, + 71024.5754757033, + 71029.82538555992 + ], + [ + 68613.0120961982, + 68517.5283816697, + 68512.63446722752 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 346.553845841135, + "scoreError" : 7.0370841367788906, + "scoreConfidence" : [ + 339.5167617043561, + 353.5909299779139 + ], + "scorePercentiles" : { + "0.0" : 338.8824915344101, + "50.0" : 345.86361663474355, + "90.0" : 352.82648521467127, + "95.0" : 352.82648521467127, + "99.0" : 352.82648521467127, + "99.9" : 352.82648521467127, + "99.99" : 352.82648521467127, + "99.999" : 352.82648521467127, + "99.9999" : 352.82648521467127, + "100.0" : 352.82648521467127 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.78276083942797, + 343.2203107307122, + 338.8824915344101 + ], + [ + 349.6999294135891, + 350.7825466039242, + 352.82648521467127 + ], + [ + 345.07844612419234, + 345.84802547454444, + 345.86361663474355 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.93576515773535, + "scoreError" : 4.531444666535601, + "scoreConfidence" : [ + 103.40432049119974, + 112.46720982427095 + ], + "scorePercentiles" : { + "0.0" : 104.48158965432441, + "50.0" : 107.8583918780271, + "90.0" : 111.14908882675743, + "95.0" : 111.14908882675743, + "99.0" : 111.14908882675743, + "99.9" : 111.14908882675743, + "99.99" : 111.14908882675743, + "99.999" : 111.14908882675743, + "99.9999" : 111.14908882675743, + "100.0" : 111.14908882675743 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.14908882675743, + 110.92489527140685, + 111.13665039776886 + ], + [ + 107.64938815573633, + 107.8583918780271, + 108.09974628464035 + ], + [ + 105.27645600496199, + 104.48158965432441, + 104.84567994599468 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014182477074290387, + "scoreError" : 4.544045452456582E-5, + "scoreConfidence" : [ + 0.01413703661976582, + 0.014227917528814953 + ], + "scorePercentiles" : { + "0.0" : 0.014150026652705457, + "50.0" : 0.01417108860798957, + "90.0" : 0.014222776878592986, + "95.0" : 0.014222776878592986, + "99.0" : 0.014222776878592986, + "99.9" : 0.014222776878592986, + "99.99" : 0.014222776878592986, + "99.999" : 0.014222776878592986, + "99.9999" : 0.014222776878592986, + "100.0" : 0.014222776878592986 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014193744343859291, + 0.014196946813177453, + 0.01417108860798957 + ], + [ + 0.014150026652705457, + 0.014220712166243843, + 0.014222776878592986 + ], + [ + 0.01416372353148631, + 0.014158148562610167, + 0.014165126111948418 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9717049067434507, + "scoreError" : 0.006816987246318855, + "scoreConfidence" : [ + 0.9648879194971318, + 0.9785218939897695 + ], + "scorePercentiles" : { + "0.0" : 0.9666643270178831, + "50.0" : 0.9739816991624465, + "90.0" : 0.9758728205503513, + "95.0" : 0.9758728205503513, + "99.0" : 0.9758728205503513, + "99.9" : 0.9758728205503513, + "99.99" : 0.9758728205503513, + "99.999" : 0.9758728205503513, + "99.9999" : 0.9758728205503513, + "100.0" : 0.9758728205503513 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9676304501209483, + 0.9666643270178831, + 0.9755419225441421 + ], + [ + 0.9683314082106894, + 0.9673373230798994, + 0.9753787322734809 + ], + [ + 0.9739816991624465, + 0.9758728205503513, + 0.9746054777312153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013071837844191544, + "scoreError" : 2.2574804378363924E-4, + "scoreConfidence" : [ + 0.012846089800407905, + 0.013297585887975184 + ], + "scorePercentiles" : { + "0.0" : 0.012941054920453339, + "50.0" : 0.013066141899765456, + "90.0" : 0.013166056665429086, + "95.0" : 0.013166056665429086, + "99.0" : 0.013166056665429086, + "99.9" : 0.013166056665429086, + "99.99" : 0.013166056665429086, + "99.999" : 0.013166056665429086, + "99.9999" : 0.013166056665429086, + "100.0" : 0.013166056665429086 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012941054920453339, + 0.013062482853298849, + 0.013044916436211845 + ], + [ + 0.013069800946232063, + 0.01314671524352408, + 0.013166056665429086 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.714277948000932, + "scoreError" : 0.21064436555544172, + "scoreConfidence" : [ + 3.5036335824454903, + 3.9249223135563738 + ], + "scorePercentiles" : { + "0.0" : 3.6397042852983987, + "50.0" : 3.7140892108414008, + "90.0" : 3.7856188084784255, + "95.0" : 3.7856188084784255, + "99.0" : 3.7856188084784255, + "99.9" : 3.7856188084784255, + "99.99" : 3.7856188084784255, + "99.999" : 3.7856188084784255, + "99.9999" : 3.7856188084784255, + "100.0" : 3.7856188084784255 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.650553775912409, + 3.6397042852983987, + 3.647226038657914 + ], + [ + 3.7776246457703926, + 3.7856188084784255, + 3.7849401338880484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8470397521263693, + "scoreError" : 0.025566746262419202, + "scoreConfidence" : [ + 2.82147300586395, + 2.8726064983887887 + ], + "scorePercentiles" : { + "0.0" : 2.8274614687588353, + "50.0" : 2.8499350316329437, + "90.0" : 2.8701827578192254, + "95.0" : 2.8701827578192254, + "99.0" : 2.8701827578192254, + "99.9" : 2.8701827578192254, + "99.99" : 2.8701827578192254, + "99.999" : 2.8701827578192254, + "99.9999" : 2.8701827578192254, + "100.0" : 2.8701827578192254 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8701827578192254, + 2.8599932299113524, + 2.8499350316329437 + ], + [ + 2.860579891590389, + 2.8513845940706957, + 2.841021331534091 + ], + [ + 2.835212614512472, + 2.8274614687588353, + 2.8275868493073224 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1745005195505932, + "scoreError" : 0.0020275178639915406, + "scoreConfidence" : [ + 0.17247300168660165, + 0.17652803741458475 + ], + "scorePercentiles" : { + "0.0" : 0.17309754439867064, + "50.0" : 0.1741435452329125, + "90.0" : 0.1760333223960992, + "95.0" : 0.1760333223960992, + "99.0" : 0.1760333223960992, + "99.9" : 0.1760333223960992, + "99.99" : 0.1760333223960992, + "99.999" : 0.1760333223960992, + "99.9999" : 0.1760333223960992, + "100.0" : 0.1760333223960992 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17357218840906724, + 0.1732631288875028, + 0.17309754439867064 + ], + [ + 0.17473068384819682, + 0.1737637954162395, + 0.1741435452329125 + ], + [ + 0.1760333223960992, + 0.17601621082831698, + 0.175884256538333 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3228836238631105, + "scoreError" : 0.0025800955935671417, + "scoreConfidence" : [ + 0.32030352826954334, + 0.3254637194566776 + ], + "scorePercentiles" : { + "0.0" : 0.3206341434800731, + "50.0" : 0.32319999993536086, + "90.0" : 0.3249434223883022, + "95.0" : 0.3249434223883022, + "99.0" : 0.3249434223883022, + "99.9" : 0.3249434223883022, + "99.99" : 0.3249434223883022, + "99.999" : 0.3249434223883022, + "99.9999" : 0.3249434223883022, + "100.0" : 0.3249434223883022 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3206341434800731, + 0.32145425224211643, + 0.3210235518923951 + ], + [ + 0.3242084933700762, + 0.32319999993536086, + 0.32265440853068333 + ], + [ + 0.3249434223883022, + 0.3239831920173648, + 0.3238511509116228 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16591044519258213, + "scoreError" : 0.0067544336253027755, + "scoreConfidence" : [ + 0.15915601156727935, + 0.17266487881788492 + ], + "scorePercentiles" : { + "0.0" : 0.1618345934814623, + "50.0" : 0.16472899033060437, + "90.0" : 0.17116194415062044, + "95.0" : 0.17116194415062044, + "99.0" : 0.17116194415062044, + "99.9" : 0.17116194415062044, + "99.99" : 0.17116194415062044, + "99.999" : 0.17116194415062044, + "99.9999" : 0.17116194415062044, + "100.0" : 0.17116194415062044 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16472899033060437, + 0.16473938853104458, + 0.1646474898167509 + ], + [ + 0.17080365469358474, + 0.17116194415062044, + 0.17112831592997588 + ], + [ + 0.16229985615749157, + 0.1618345934814623, + 0.16184977364170455 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3956644356033628, + "scoreError" : 0.008307636951365563, + "scoreConfidence" : [ + 0.38735679865199724, + 0.40397207255472833 + ], + "scorePercentiles" : { + "0.0" : 0.390096359625512, + "50.0" : 0.3933824678808859, + "90.0" : 0.405691865030426, + "95.0" : 0.405691865030426, + "99.0" : 0.405691865030426, + "99.9" : 0.405691865030426, + "99.99" : 0.405691865030426, + "99.999" : 0.405691865030426, + "99.9999" : 0.405691865030426, + "100.0" : 0.405691865030426 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39496456504739336, + 0.3915411707842293, + 0.390096359625512 + ], + [ + 0.405691865030426, + 0.39975288051646946, + 0.3991692626831118 + ], + [ + 0.39332322076696163, + 0.3930581280952755, + 0.3933824678808859 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1572647709808916, + "scoreError" : 0.0037341884184379057, + "scoreConfidence" : [ + 0.1535305825624537, + 0.16099895939932948 + ], + "scorePercentiles" : { + "0.0" : 0.15498375, + "50.0" : 0.15638225283437848, + "90.0" : 0.16048965336778417, + "95.0" : 0.16048965336778417, + "99.0" : 0.16048965336778417, + "99.9" : 0.16048965336778417, + "99.99" : 0.16048965336778417, + "99.999" : 0.16048965336778417, + "99.9999" : 0.16048965336778417, + "100.0" : 0.16048965336778417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1560176270184252, + 0.15642328273111217, + 0.15638225283437848 + ], + [ + 0.1554366101715991, + 0.15567427536660544, + 0.15498375 + ], + [ + 0.16048965336778417, + 0.16026842540506755, + 0.15970706193305226 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0472223516947196, + "scoreError" : 0.0011805643716068521, + "scoreConfidence" : [ + 0.046041787323112746, + 0.04840291606632645 + ], + "scorePercentiles" : { + "0.0" : 0.04637169603342422, + "50.0" : 0.0471845359800318, + "90.0" : 0.04845031826065892, + "95.0" : 0.04845031826065892, + "99.0" : 0.04845031826065892, + "99.9" : 0.04845031826065892, + "99.99" : 0.04845031826065892, + "99.999" : 0.04845031826065892, + "99.9999" : 0.04845031826065892, + "100.0" : 0.04845031826065892 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046576301418225004, + 0.04637169603342422, + 0.046407148343055496 + ], + [ + 0.04845031826065892, + 0.047919916816813936, + 0.04754857862529361 + ], + [ + 0.047405010376817366, + 0.04713765939815601, + 0.0471845359800318 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9322508.960505482, + "scoreError" : 254291.34908198053, + "scoreConfidence" : [ + 9068217.611423502, + 9576800.309587462 + ], + "scorePercentiles" : { + "0.0" : 9170753.268560953, + "50.0" : 9282116.878478665, + "90.0" : 9531735.557142857, + "95.0" : 9531735.557142857, + "99.0" : 9531735.557142857, + "99.9" : 9531735.557142857, + "99.99" : 9531735.557142857, + "99.999" : 9531735.557142857, + "99.9999" : 9531735.557142857, + "100.0" : 9531735.557142857 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9250168.812384473, + 9284957.720779222, + 9282116.878478665 + ], + [ + 9193211.326286765, + 9170753.268560953, + 9173660.361136572 + ], + [ + 9493256.503795067, + 9522720.215984777, + 9531735.557142857 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-18T23:42:07Z-3d7dce5e49dfbe92d656629ae4fdbab979bba8be-jdk17.json b/performance-results/2025-03-18T23:42:07Z-3d7dce5e49dfbe92d656629ae4fdbab979bba8be-jdk17.json new file mode 100644 index 0000000000..01af99efd7 --- /dev/null +++ b/performance-results/2025-03-18T23:42:07Z-3d7dce5e49dfbe92d656629ae4fdbab979bba8be-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4030341962375994, + "scoreError" : 0.02905720653413424, + "scoreConfidence" : [ + 3.3739769897034653, + 3.4320914027717335 + ], + "scorePercentiles" : { + "0.0" : 3.3984726801583083, + "50.0" : 3.40222251416189, + "90.0" : 3.40921907646831, + "95.0" : 3.40921907646831, + "99.0" : 3.40921907646831, + "99.9" : 3.40921907646831, + "99.99" : 3.40921907646831, + "99.999" : 3.40921907646831, + "99.9999" : 3.40921907646831, + "100.0" : 3.40921907646831 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3984726801583083, + 3.40921907646831 + ], + [ + 3.401847449089267, + 3.402597579234513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7177090587738857, + "scoreError" : 0.011729170580772197, + "scoreConfidence" : [ + 1.7059798881931134, + 1.729438229354658 + ], + "scorePercentiles" : { + "0.0" : 1.7161540986078148, + "50.0" : 1.7174972498814143, + "90.0" : 1.7196876367249, + "95.0" : 1.7196876367249, + "99.0" : 1.7196876367249, + "99.9" : 1.7196876367249, + "99.99" : 1.7196876367249, + "99.999" : 1.7196876367249, + "99.9999" : 1.7196876367249, + "100.0" : 1.7196876367249 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7161816911797099, + 1.7188128085831187 + ], + [ + 1.7161540986078148, + 1.7196876367249 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8648592999960828, + "scoreError" : 0.005526498918160724, + "scoreConfidence" : [ + 0.8593328010779221, + 0.8703857989142435 + ], + "scorePercentiles" : { + "0.0" : 0.8639429699495912, + "50.0" : 0.8649398593777518, + "90.0" : 0.8656145112792367, + "95.0" : 0.8656145112792367, + "99.0" : 0.8656145112792367, + "99.9" : 0.8656145112792367, + "99.99" : 0.8656145112792367, + "99.999" : 0.8656145112792367, + "99.9999" : 0.8656145112792367, + "100.0" : 0.8656145112792367 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.864318860199225, + 0.8639429699495912 + ], + [ + 0.8655608585562785, + 0.8656145112792367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.894285209058118, + "scoreError" : 0.22100514707279106, + "scoreConfidence" : [ + 15.673280061985327, + 16.11529035613091 + ], + "scorePercentiles" : { + "0.0" : 15.675229525482061, + "50.0" : 15.907164710763897, + "90.0" : 16.06855890412849, + "95.0" : 16.06855890412849, + "99.0" : 16.06855890412849, + "99.9" : 16.06855890412849, + "99.99" : 16.06855890412849, + "99.999" : 16.06855890412849, + "99.9999" : 16.06855890412849, + "100.0" : 16.06855890412849 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.06855890412849, + 15.954200891572873, + 15.889569229430252 + ], + [ + 15.907164710763897, + 16.00879970270076, + 15.99190467327713 + ], + [ + 15.830796895625069, + 15.675229525482061, + 15.72234234854253 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 23.84258595407435, + "scoreError" : 0.16971826450224373, + "scoreConfidence" : [ + 23.672867689572108, + 24.012304218576595 + ], + "scorePercentiles" : { + "0.0" : 23.73385673723001, + "50.0" : 23.823719230321753, + "90.0" : 24.079442391385157, + "95.0" : 24.079442391385157, + "99.0" : 24.079442391385157, + "99.9" : 24.079442391385157, + "99.99" : 24.079442391385157, + "99.999" : 24.079442391385157, + "99.9999" : 24.079442391385157, + "100.0" : 24.079442391385157 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 23.899958603431326, + 23.796039927842227, + 23.790688365773097 + ], + [ + 23.849380733110003, + 24.079442391385157, + 23.823719230321753 + ], + [ + 23.839112614729608, + 23.73385673723001, + 23.771074982845974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70190.75403769573, + "scoreError" : 401.50400495191934, + "scoreConfidence" : [ + 69789.25003274382, + 70592.25804264765 + ], + "scorePercentiles" : { + "0.0" : 69854.4041312379, + "50.0" : 70190.65239873884, + "90.0" : 70493.13169380104, + "95.0" : 70493.13169380104, + "99.0" : 70493.13169380104, + "99.9" : 70493.13169380104, + "99.99" : 70493.13169380104, + "99.999" : 70493.13169380104, + "99.9999" : 70493.13169380104, + "100.0" : 70493.13169380104 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70482.36880103988, + 70493.13169380104, + 70329.6963337318 + ], + [ + 69983.17063049234, + 70365.16553246543, + 70190.65239873884 + ], + [ + 70073.43951918474, + 69854.4041312379, + 69944.75729856959 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 324.33117298479885, + "scoreError" : 16.396151264190877, + "scoreConfidence" : [ + 307.935021720608, + 340.7273242489897 + ], + "scorePercentiles" : { + "0.0" : 311.7536298897916, + "50.0" : 320.7394310847248, + "90.0" : 341.3502382353502, + "95.0" : 341.3502382353502, + "99.0" : 341.3502382353502, + "99.9" : 341.3502382353502, + "99.99" : 341.3502382353502, + "99.999" : 341.3502382353502, + "99.9999" : 341.3502382353502, + "100.0" : 341.3502382353502 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 320.6566368654864, + 323.2717383562003, + 320.0584633567249 + ], + [ + 334.0350009976469, + 341.3502382353502, + 332.8480453159042 + ], + [ + 314.2673727613599, + 311.7536298897916, + 320.7394310847248 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 98.82877677960663, + "scoreError" : 2.213364397678412, + "scoreConfidence" : [ + 96.61541238192821, + 101.04214117728505 + ], + "scorePercentiles" : { + "0.0" : 96.7095691352346, + "50.0" : 98.54617145982048, + "90.0" : 100.73049767909293, + "95.0" : 100.73049767909293, + "99.0" : 100.73049767909293, + "99.9" : 100.73049767909293, + "99.99" : 100.73049767909293, + "99.999" : 100.73049767909293, + "99.9999" : 100.73049767909293, + "100.0" : 100.73049767909293 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 98.54617145982048, + 98.33512677300635, + 97.41535629373469 + ], + [ + 100.49777592353054, + 98.52742877499989, + 99.21958486804665 + ], + [ + 99.47748010899346, + 100.73049767909293, + 96.7095691352346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06274013284017438, + "scoreError" : 7.00780518209212E-4, + "scoreConfidence" : [ + 0.06203935232196517, + 0.06344091335838359 + ], + "scorePercentiles" : { + "0.0" : 0.06218591576394503, + "50.0" : 0.06281513064070351, + "90.0" : 0.06342166454841226, + "95.0" : 0.06342166454841226, + "99.0" : 0.06342166454841226, + "99.9" : 0.06342166454841226, + "99.99" : 0.06342166454841226, + "99.999" : 0.06342166454841226, + "99.9999" : 0.06342166454841226, + "100.0" : 0.06342166454841226 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06298900028974552, + 0.06281513064070351, + 0.06218591576394503 + ], + [ + 0.06310182017466368, + 0.06285766694114098, + 0.06342166454841226 + ], + [ + 0.06224469643779682, + 0.062339103487828444, + 0.06270619727733327 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.041783924753189074, + "scoreError" : 3.37840812015335E-4, + "scoreConfidence" : [ + 0.04144608394117374, + 0.04212176556520441 + ], + "scorePercentiles" : { + "0.0" : 0.04141958317973782, + "50.0" : 0.04176708066375415, + "90.0" : 0.04209846797618948, + "95.0" : 0.04209846797618948, + "99.0" : 0.04209846797618948, + "99.9" : 0.04209846797618948, + "99.99" : 0.04209846797618948, + "99.999" : 0.04209846797618948, + "99.9999" : 0.04209846797618948, + "100.0" : 0.04209846797618948 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04191370691440092, + 0.04174531906358145, + 0.04141958317973782 + ], + [ + 0.04176708066375415, + 0.04170001375666671, + 0.04209846797618948 + ], + [ + 0.04160955372753638, + 0.041965154257729884, + 0.041836443239104876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014174588031238746, + "scoreError" : 1.2015869779662313E-4, + "scoreConfidence" : [ + 0.014054429333442123, + 0.014294746729035369 + ], + "scorePercentiles" : { + "0.0" : 0.0140440420136085, + "50.0" : 0.01417231512733663, + "90.0" : 0.014274561368398815, + "95.0" : 0.014274561368398815, + "99.0" : 0.014274561368398815, + "99.9" : 0.014274561368398815, + "99.99" : 0.014274561368398815, + "99.999" : 0.014274561368398815, + "99.9999" : 0.014274561368398815, + "100.0" : 0.014274561368398815 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014137954149789701, + 0.014109782593543162, + 0.0140440420136085 + ], + [ + 0.014237063277154677, + 0.014236445661644117, + 0.014274561368398815 + ], + [ + 0.014163128768233044, + 0.01417231512733663, + 0.01419599932144008 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.983950143153562, + "scoreError" : 0.01789666233502451, + "scoreConfidence" : [ + 0.9660534808185375, + 1.0018468054885865 + ], + "scorePercentiles" : { + "0.0" : 0.9690377924418605, + "50.0" : 0.9826584856047951, + "90.0" : 1.0008194397518015, + "95.0" : 1.0008194397518015, + "99.0" : 1.0008194397518015, + "99.9" : 1.0008194397518015, + "99.99" : 1.0008194397518015, + "99.999" : 1.0008194397518015, + "99.9999" : 1.0008194397518015, + "100.0" : 1.0008194397518015 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9766162767578125, + 0.9759815764614034, + 0.977302323463305 + ], + [ + 0.9921559711309523, + 1.0008194397518015, + 0.9969865728242449 + ], + [ + 0.9690377924418605, + 0.9826584856047951, + 0.9839928499458821 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013046854808199082, + "scoreError" : 7.155498045868686E-4, + "scoreConfidence" : [ + 0.012331305003612214, + 0.013762404612785951 + ], + "scorePercentiles" : { + "0.0" : 0.012759913740041137, + "50.0" : 0.013023311519173332, + "90.0" : 0.013313933373629036, + "95.0" : 0.013313933373629036, + "99.0" : 0.013313933373629036, + "99.9" : 0.013313933373629036, + "99.99" : 0.013313933373629036, + "99.999" : 0.013313933373629036, + "99.9999" : 0.013313933373629036, + "100.0" : 0.013313933373629036 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013197641879604188, + 0.013312456124516436, + 0.013313933373629036 + ], + [ + 0.012759913740041137, + 0.012848981158742476, + 0.012848202572661234 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.9100372274851996, + "scoreError" : 0.09267811388781177, + "scoreConfidence" : [ + 3.8173591135973877, + 4.002715341373011 + ], + "scorePercentiles" : { + "0.0" : 3.8678984586233565, + "50.0" : 3.906645754355439, + "90.0" : 3.9560345450949366, + "95.0" : 3.9560345450949366, + "99.0" : 3.9560345450949366, + "99.9" : 3.9560345450949366, + "99.99" : 3.9560345450949366, + "99.999" : 3.9560345450949366, + "99.9999" : 3.9560345450949366, + "100.0" : 3.9560345450949366 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8678984586233565, + 3.8990089734996105, + 3.914282535211268 + ], + [ + 3.8847961304347827, + 3.938202722047244, + 3.9560345450949366 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.074877921242732, + "scoreError" : 0.14285652352037062, + "scoreConfidence" : [ + 2.9320213977223615, + 3.217734444763103 + ], + "scorePercentiles" : { + "0.0" : 2.9614455812851643, + "50.0" : 3.079247117302956, + "90.0" : 3.1787071652892562, + "95.0" : 3.1787071652892562, + "99.0" : 3.1787071652892562, + "99.9" : 3.1787071652892562, + "99.99" : 3.1787071652892562, + "99.999" : 3.1787071652892562, + "99.9999" : 3.1787071652892562, + "100.0" : 3.1787071652892562 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.079247117302956, + 3.1787071652892562, + 3.1742028940019043 + ], + [ + 2.9614455812851643, + 3.001099893189319, + 2.99687381810009 + ], + [ + 3.162621833649589, + 3.011864800361337, + 3.107838188004972 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1792216150867655, + "scoreError" : 0.0028134776583006605, + "scoreConfidence" : [ + 0.17640813742846484, + 0.18203509274506618 + ], + "scorePercentiles" : { + "0.0" : 0.1767819975958139, + "50.0" : 0.1795381048653501, + "90.0" : 0.1817618339270784, + "95.0" : 0.1817618339270784, + "99.0" : 0.1817618339270784, + "99.9" : 0.1817618339270784, + "99.99" : 0.1817618339270784, + "99.999" : 0.1817618339270784, + "99.9999" : 0.1817618339270784, + "100.0" : 0.1817618339270784 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18049263225340673, + 0.1804214153210529, + 0.1795381048653501 + ], + [ + 0.1817618339270784, + 0.17952781720912697, + 0.17965059216743015 + ], + [ + 0.1772999119373083, + 0.1775202305043225, + 0.1767819975958139 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33466733956572775, + "scoreError" : 0.004866797587081008, + "scoreConfidence" : [ + 0.3298005419786467, + 0.3395341371528088 + ], + "scorePercentiles" : { + "0.0" : 0.3300852951544758, + "50.0" : 0.3358559937533584, + "90.0" : 0.33746668143623665, + "95.0" : 0.33746668143623665, + "99.0" : 0.33746668143623665, + "99.9" : 0.33746668143623665, + "99.99" : 0.33746668143623665, + "99.999" : 0.33746668143623665, + "99.9999" : 0.33746668143623665, + "100.0" : 0.33746668143623665 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3300852951544758, + 0.3314083194034797, + 0.33132537756352914 + ], + [ + 0.33537929941645983, + 0.33673772668193147, + 0.3358559937533584 + ], + [ + 0.337392372537112, + 0.33746668143623665, + 0.33635499014496656 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17101508461082024, + "scoreError" : 0.010519194639942204, + "scoreConfidence" : [ + 0.16049588997087805, + 0.18153427925076243 + ], + "scorePercentiles" : { + "0.0" : 0.16516208604743343, + "50.0" : 0.16813719979487524, + "90.0" : 0.17961573141030246, + "95.0" : 0.17961573141030246, + "99.0" : 0.17961573141030246, + "99.9" : 0.17961573141030246, + "99.99" : 0.17961573141030246, + "99.999" : 0.17961573141030246, + "99.9999" : 0.17961573141030246, + "100.0" : 0.17961573141030246 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17919520307852202, + 0.17888246420649684, + 0.17961573141030246 + ], + [ + 0.16516208604743343, + 0.16615715744786907, + 0.16587774737505598 + ], + [ + 0.16861689849598704, + 0.16749127364084013, + 0.16813719979487524 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39043772821823275, + "scoreError" : 0.0047876565689028575, + "scoreConfidence" : [ + 0.3856500716493299, + 0.3952253847871356 + ], + "scorePercentiles" : { + "0.0" : 0.38742203788788593, + "50.0" : 0.38943609887456676, + "90.0" : 0.39498915905679755, + "95.0" : 0.39498915905679755, + "99.0" : 0.39498915905679755, + "99.9" : 0.39498915905679755, + "99.99" : 0.39498915905679755, + "99.999" : 0.39498915905679755, + "99.9999" : 0.39498915905679755, + "100.0" : 0.39498915905679755 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39472534043812907, + 0.39137307032717594, + 0.38897682500291725 + ], + [ + 0.39498915905679755, + 0.3910808260529506, + 0.38943609887456676 + ], + [ + 0.388212455628882, + 0.38742203788788593, + 0.3877237406947891 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15861643109426515, + "scoreError" : 0.003487971523721404, + "scoreConfidence" : [ + 0.15512845957054375, + 0.16210440261798656 + ], + "scorePercentiles" : { + "0.0" : 0.15579235488946705, + "50.0" : 0.1587464442257322, + "90.0" : 0.1619693449677691, + "95.0" : 0.1619693449677691, + "99.0" : 0.1619693449677691, + "99.9" : 0.1619693449677691, + "99.99" : 0.1619693449677691, + "99.999" : 0.1619693449677691, + "99.9999" : 0.1619693449677691, + "100.0" : 0.1619693449677691 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.158881436433542, + 0.1587464442257322, + 0.1579010665382429 + ], + [ + 0.1573456464535213, + 0.1560672353767401, + 0.15579235488946705 + ], + [ + 0.1619693449677691, + 0.16050901377140747, + 0.16033533719196422 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04797686652872106, + "scoreError" : 0.0022187213778125004, + "scoreConfidence" : [ + 0.04575814515090856, + 0.05019558790653356 + ], + "scorePercentiles" : { + "0.0" : 0.04637634170569958, + "50.0" : 0.04768700323789723, + "90.0" : 0.04974361433389377, + "95.0" : 0.04974361433389377, + "99.0" : 0.04974361433389377, + "99.9" : 0.04974361433389377, + "99.99" : 0.04974361433389377, + "99.999" : 0.04974361433389377, + "99.9999" : 0.04974361433389377, + "100.0" : 0.04974361433389377 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04974361433389377, + 0.049498889757855345, + 0.04956484810095212 + ], + [ + 0.04768409821807484, + 0.047797690581116346, + 0.04768700323789723 + ], + [ + 0.04654392197026818, + 0.04637634170569958, + 0.04689539085273208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.0102506343115807E7, + "scoreError" : 414058.2334989545, + "scoreConfidence" : [ + 9688448.109616851, + 1.0516564576614762E7 + ], + "scorePercentiles" : { + "0.0" : 9719042.463556852, + "50.0" : 1.0038881575727182E7, + "90.0" : 1.0483148298742138E7, + "95.0" : 1.0483148298742138E7, + "99.0" : 1.0483148298742138E7, + "99.9" : 1.0483148298742138E7, + "99.99" : 1.0483148298742138E7, + "99.999" : 1.0483148298742138E7, + "99.9999" : 1.0483148298742138E7, + "100.0" : 1.0483148298742138E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9950572.298507463, + 9989488.596806386, + 9719042.463556852 + ], + [ + 1.014154786828774E7, + 1.0462304284518829E7, + 1.0483148298742138E7 + ], + [ + 1.0038881575727182E7, + 9967271.066733068, + 1.0170300635162601E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-20T04:24:26Z-9a931ba6ad8e2ee49ea48c98ca86c2901f2343b1-jdk17.json b/performance-results/2025-03-20T04:24:26Z-9a931ba6ad8e2ee49ea48c98ca86c2901f2343b1-jdk17.json new file mode 100644 index 0000000000..f2de5b21a6 --- /dev/null +++ b/performance-results/2025-03-20T04:24:26Z-9a931ba6ad8e2ee49ea48c98ca86c2901f2343b1-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.424254609168787, + "scoreError" : 0.02613921724586001, + "scoreConfidence" : [ + 3.3981153919229268, + 3.450393826414647 + ], + "scorePercentiles" : { + "0.0" : 3.419489493150746, + "50.0" : 3.424232606853354, + "90.0" : 3.429063729817694, + "95.0" : 3.429063729817694, + "99.0" : 3.429063729817694, + "99.9" : 3.429063729817694, + "99.99" : 3.429063729817694, + "99.999" : 3.429063729817694, + "99.9999" : 3.429063729817694, + "100.0" : 3.429063729817694 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.422957283038915, + 3.4255079306677936 + ], + [ + 3.419489493150746, + 3.429063729817694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7283881755988588, + "scoreError" : 0.0075711935811060855, + "scoreConfidence" : [ + 1.7208169820177528, + 1.7359593691799649 + ], + "scorePercentiles" : { + "0.0" : 1.7272608832354859, + "50.0" : 1.7281327281107284, + "90.0" : 1.7300263629384918, + "95.0" : 1.7300263629384918, + "99.0" : 1.7300263629384918, + "99.9" : 1.7300263629384918, + "99.99" : 1.7300263629384918, + "99.999" : 1.7300263629384918, + "99.9999" : 1.7300263629384918, + "100.0" : 1.7300263629384918 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7282618455510002, + 1.7272608832354859 + ], + [ + 1.7280036106704566, + 1.7300263629384918 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8682027175699097, + "scoreError" : 0.004935973252822849, + "scoreConfidence" : [ + 0.8632667443170869, + 0.8731386908227325 + ], + "scorePercentiles" : { + "0.0" : 0.8675676336105674, + "50.0" : 0.8679655469663551, + "90.0" : 0.8693121427363618, + "95.0" : 0.8693121427363618, + "99.0" : 0.8693121427363618, + "99.9" : 0.8693121427363618, + "99.99" : 0.8693121427363618, + "99.999" : 0.8693121427363618, + "99.9999" : 0.8693121427363618, + "100.0" : 0.8693121427363618 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8675676336105674, + 0.867922346385138 + ], + [ + 0.8680087475475722, + 0.8693121427363618 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.36869394908749, + "scoreError" : 0.04032602783381367, + "scoreConfidence" : [ + 16.328367921253676, + 16.409019976921304 + ], + "scorePercentiles" : { + "0.0" : 16.330608886150326, + "50.0" : 16.36573210114837, + "90.0" : 16.3997056798874, + "95.0" : 16.3997056798874, + "99.0" : 16.3997056798874, + "99.9" : 16.3997056798874, + "99.99" : 16.3997056798874, + "99.999" : 16.3997056798874, + "99.9999" : 16.3997056798874, + "100.0" : 16.3997056798874 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.36573210114837, + 16.39567738769027, + 16.3997056798874 + ], + [ + 16.354154879020427, + 16.35331486739305, + 16.330608886150326 + ], + [ + 16.38900046883599, + 16.348132670430132, + 16.38191860123142 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2755.2645435237955, + "scoreError" : 142.15005863441795, + "scoreConfidence" : [ + 2613.1144848893778, + 2897.4146021582133 + ], + "scorePercentiles" : { + "0.0" : 2645.769653967194, + "50.0" : 2777.358790668434, + "90.0" : 2844.082898480718, + "95.0" : 2844.082898480718, + "99.0" : 2844.082898480718, + "99.9" : 2844.082898480718, + "99.99" : 2844.082898480718, + "99.999" : 2844.082898480718, + "99.9999" : 2844.082898480718, + "100.0" : 2844.082898480718 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2645.769653967194, + 2650.136785283063, + 2651.473877519024 + ], + [ + 2780.1082222295813, + 2769.131638137327, + 2777.358790668434 + ], + [ + 2844.082898480718, + 2840.1765737310034, + 2839.1424516978195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69686.99595380232, + "scoreError" : 1940.033884888202, + "scoreConfidence" : [ + 67746.96206891412, + 71627.02983869053 + ], + "scorePercentiles" : { + "0.0" : 68658.18447808478, + "50.0" : 69182.69094993896, + "90.0" : 71219.67727831232, + "95.0" : 71219.67727831232, + "99.0" : 71219.67727831232, + "99.9" : 71219.67727831232, + "99.99" : 71219.67727831232, + "99.999" : 71219.67727831232, + "99.9999" : 71219.67727831232, + "100.0" : 71219.67727831232 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71197.47410218067, + 71180.94216999353, + 71219.67727831232 + ], + [ + 69167.24550293588, + 69182.69094993896, + 69185.52767427432 + ], + [ + 68700.10055066991, + 68658.18447808478, + 68691.12087783056 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.88994514661977, + "scoreError" : 8.60461783150149, + "scoreConfidence" : [ + 345.28532731511825, + 362.4945629781213 + ], + "scorePercentiles" : { + "0.0" : 347.80532224376645, + "50.0" : 353.0663168731576, + "90.0" : 360.1943821922987, + "95.0" : 360.1943821922987, + "99.0" : 360.1943821922987, + "99.9" : 360.1943821922987, + "99.99" : 360.1943821922987, + "99.999" : 360.1943821922987, + "99.9999" : 360.1943821922987, + "100.0" : 360.1943821922987 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 359.3096151632722, + 360.1943821922987, + 359.9042966967716 + ], + [ + 348.9299003319532, + 348.06675704900783, + 347.80532224376645 + ], + [ + 353.0663168731576, + 351.83558769978185, + 355.8973280695685 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.22422695181898, + "scoreError" : 2.300054928270859, + "scoreConfidence" : [ + 104.92417202354812, + 109.52428188008983 + ], + "scorePercentiles" : { + "0.0" : 105.11702222043792, + "50.0" : 107.60099849482508, + "90.0" : 108.64394817524074, + "95.0" : 108.64394817524074, + "99.0" : 108.64394817524074, + "99.9" : 108.64394817524074, + "99.99" : 108.64394817524074, + "99.999" : 108.64394817524074, + "99.9999" : 108.64394817524074, + "100.0" : 108.64394817524074 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.10524767429007, + 105.47579180802381, + 105.11702222043792 + ], + [ + 108.61995646598682, + 108.56537197809733, + 108.64394817524074 + ], + [ + 107.10120847440774, + 107.60099849482508, + 107.78849727506135 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0612988109620845, + "scoreError" : 8.652535687359045E-4, + "scoreConfidence" : [ + 0.060433557393348596, + 0.0621640645308204 + ], + "scorePercentiles" : { + "0.0" : 0.06061360878156405, + "50.0" : 0.06131260160268791, + "90.0" : 0.061910864993035136, + "95.0" : 0.061910864993035136, + "99.0" : 0.061910864993035136, + "99.9" : 0.061910864993035136, + "99.99" : 0.061910864993035136, + "99.999" : 0.061910864993035136, + "99.9999" : 0.061910864993035136, + "100.0" : 0.061910864993035136 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061816245462750045, + 0.061910864993035136, + 0.061907721375817945 + ], + [ + 0.06070640137194196, + 0.06061360878156405, + 0.06077460113646723 + ], + [ + 0.06124887921308744, + 0.06131260160268791, + 0.0613983747214087 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.83704055702058E-4, + "scoreError" : 1.8341314884139816E-5, + "scoreConfidence" : [ + 3.653627408179182E-4, + 4.020453705861978E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7188639856197784E-4, + "50.0" : 3.7950586013066773E-4, + "90.0" : 3.981731629629329E-4, + "95.0" : 3.981731629629329E-4, + "99.0" : 3.981731629629329E-4, + "99.9" : 3.981731629629329E-4, + "99.99" : 3.981731629629329E-4, + "99.999" : 3.981731629629329E-4, + "99.9999" : 3.981731629629329E-4, + "100.0" : 3.981731629629329E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.974309778124687E-4, + 3.981731629629329E-4, + 3.978541673612461E-4 + ], + [ + 3.7925996341091464E-4, + 3.7981703252567807E-4, + 3.7950586013066773E-4 + ], + [ + 3.7188639856197784E-4, + 3.7403482801825057E-4, + 3.7537411053438545E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014271994702376285, + "scoreError" : 5.216322474734358E-4, + "scoreConfidence" : [ + 0.01375036245490285, + 0.01479362694984972 + ], + "scorePercentiles" : { + "0.0" : 0.01395132297181729, + "50.0" : 0.014194895541158969, + "90.0" : 0.014695156501421738, + "95.0" : 0.014695156501421738, + "99.0" : 0.014695156501421738, + "99.9" : 0.014695156501421738, + "99.99" : 0.014695156501421738, + "99.999" : 0.014695156501421738, + "99.9999" : 0.014695156501421738, + "100.0" : 0.014695156501421738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014645885331614907, + 0.014695156501421738, + 0.01464714127276136 + ], + [ + 0.013970092754773178, + 0.013957995058929938, + 0.01395132297181729 + ], + [ + 0.014183137027334836, + 0.014194895541158969, + 0.014202325861574338 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9710519168134688, + "scoreError" : 0.011208694685730868, + "scoreConfidence" : [ + 0.959843222127738, + 0.9822606114991996 + ], + "scorePercentiles" : { + "0.0" : 0.9630646993451464, + "50.0" : 0.9684868110594615, + "90.0" : 0.9809538926924963, + "95.0" : 0.9809538926924963, + "99.0" : 0.9809538926924963, + "99.9" : 0.9809538926924963, + "99.99" : 0.9809538926924963, + "99.999" : 0.9809538926924963, + "99.9999" : 0.9809538926924963, + "100.0" : 0.9809538926924963 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9668159646171693, + 0.9671069353060633, + 0.9724057801439129 + ], + [ + 0.9751261756045242, + 0.9808086011180855, + 0.9809538926924963 + ], + [ + 0.964698391434359, + 0.9684868110594615, + 0.9630646993451464 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013268263113495505, + "scoreError" : 4.465237350273874E-4, + "scoreConfidence" : [ + 0.012821739378468118, + 0.013714786848522892 + ], + "scorePercentiles" : { + "0.0" : 0.013099557043340206, + "50.0" : 0.013270168813548271, + "90.0" : 0.01348281547845361, + "95.0" : 0.01348281547845361, + "99.0" : 0.01348281547845361, + "99.9" : 0.01348281547845361, + "99.99" : 0.01348281547845361, + "99.999" : 0.01348281547845361, + "99.9999" : 0.01348281547845361, + "100.0" : 0.01348281547845361 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013351823428725543, + 0.013380745552344251, + 0.01348281547845361 + ], + [ + 0.013099557043340206, + 0.013188514198370999, + 0.013106122979738408 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8236215956341684, + "scoreError" : 0.11204404869949024, + "scoreConfidence" : [ + 3.711577546934678, + 3.9356656443336586 + ], + "scorePercentiles" : { + "0.0" : 3.7785576442598185, + "50.0" : 3.8263314364495367, + "90.0" : 3.8664696870170014, + "95.0" : 3.8664696870170014, + "99.0" : 3.8664696870170014, + "99.9" : 3.8664696870170014, + "99.99" : 3.8664696870170014, + "99.999" : 3.8664696870170014, + "99.9999" : 3.8664696870170014, + "100.0" : 3.8664696870170014 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.784792498487141, + 3.800600712006079, + 3.7785576442598185 + ], + [ + 3.859246871141975, + 3.8520621608929946, + 3.8664696870170014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8760393545398433, + "scoreError" : 0.03561405209144057, + "scoreConfidence" : [ + 2.8404253024484025, + 2.911653406631284 + ], + "scorePercentiles" : { + "0.0" : 2.8550628495575223, + "50.0" : 2.867487625860092, + "90.0" : 2.9119395694323145, + "95.0" : 2.9119395694323145, + "99.0" : 2.9119395694323145, + "99.9" : 2.9119395694323145, + "99.99" : 2.9119395694323145, + "99.999" : 2.9119395694323145, + "99.9999" : 2.9119395694323145, + "100.0" : 2.9119395694323145 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9119395694323145, + 2.896368578048074, + 2.9009854074825987 + ], + [ + 2.8569692313624677, + 2.8603496425507577, + 2.8550628495575223 + ], + [ + 2.868876608146873, + 2.867487625860092, + 2.8663146784178846 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17666360171690498, + "scoreError" : 0.007018650315553071, + "scoreConfidence" : [ + 0.1696449514013519, + 0.18368225203245805 + ], + "scorePercentiles" : { + "0.0" : 0.171930377965752, + "50.0" : 0.17588338716428936, + "90.0" : 0.18198961034777703, + "95.0" : 0.18198961034777703, + "99.0" : 0.18198961034777703, + "99.9" : 0.18198961034777703, + "99.99" : 0.18198961034777703, + "99.999" : 0.18198961034777703, + "99.9999" : 0.18198961034777703, + "100.0" : 0.18198961034777703 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17230693078553336, + 0.171930377965752, + 0.17222718737944337 + ], + [ + 0.18198961034777703, + 0.18161404623794564, + 0.18156196546778264 + ], + [ + 0.17679468235980483, + 0.17588338716428936, + 0.17566422774381676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.328427280265929, + "scoreError" : 0.009007381611096744, + "scoreConfidence" : [ + 0.3194198986548322, + 0.33743466187702575 + ], + "scorePercentiles" : { + "0.0" : 0.32402172724621714, + "50.0" : 0.32554089566717664, + "90.0" : 0.3365099610000673, + "95.0" : 0.3365099610000673, + "99.0" : 0.3365099610000673, + "99.9" : 0.3365099610000673, + "99.99" : 0.3365099610000673, + "99.999" : 0.3365099610000673, + "99.9999" : 0.3365099610000673, + "100.0" : 0.3365099610000673 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32554089566717664, + 0.3255366924379049, + 0.3257196699889258 + ], + [ + 0.32449776503991173, + 0.32402172724621714, + 0.3240274855161688 + ], + [ + 0.3365099610000673, + 0.33505243635876303, + 0.33493888913822556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1671680197141367, + "scoreError" : 0.0031650202498782714, + "scoreConfidence" : [ + 0.16400299946425842, + 0.17033303996401497 + ], + "scorePercentiles" : { + "0.0" : 0.16575822910658047, + "50.0" : 0.1660215798718332, + "90.0" : 0.16990446979170207, + "95.0" : 0.16990446979170207, + "99.0" : 0.16990446979170207, + "99.9" : 0.16990446979170207, + "99.99" : 0.16990446979170207, + "99.999" : 0.16990446979170207, + "99.9999" : 0.16990446979170207, + "100.0" : 0.16990446979170207 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16575822910658047, + 0.16582184809391945, + 0.16580947611546815 + ], + [ + 0.16954085197680727, + 0.16956868575982637, + 0.16990446979170207 + ], + [ + 0.16597716160727624, + 0.1660215798718332, + 0.16610987510381714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3920398294957659, + "scoreError" : 0.008199953086242167, + "scoreConfidence" : [ + 0.3838398764095237, + 0.40023978258200804 + ], + "scorePercentiles" : { + "0.0" : 0.3855065223777033, + "50.0" : 0.39384232234562067, + "90.0" : 0.3974420058421429, + "95.0" : 0.3974420058421429, + "99.0" : 0.3974420058421429, + "99.9" : 0.3974420058421429, + "99.99" : 0.3974420058421429, + "99.999" : 0.3974420058421429, + "99.9999" : 0.3974420058421429, + "100.0" : 0.3974420058421429 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3960158337161413, + 0.39384232234562067, + 0.3934183516660766 + ], + [ + 0.3974420058421429, + 0.3958316693714376, + 0.3945936228149785 + ], + [ + 0.38551056595990746, + 0.3855065223777033, + 0.38619757136788446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15782436732750707, + "scoreError" : 0.002616382192165471, + "scoreConfidence" : [ + 0.1552079851353416, + 0.16044074951967255 + ], + "scorePercentiles" : { + "0.0" : 0.15603131695557879, + "50.0" : 0.15772105887548302, + "90.0" : 0.1594922870972887, + "95.0" : 0.1594922870972887, + "99.0" : 0.1594922870972887, + "99.9" : 0.1594922870972887, + "99.99" : 0.1594922870972887, + "99.999" : 0.1594922870972887, + "99.9999" : 0.1594922870972887, + "100.0" : 0.1594922870972887 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15940837378455064, + 0.15939634857662022, + 0.15924676244088093 + ], + [ + 0.1594922870972887, + 0.15603131695557879, + 0.15647512279960568 + ], + [ + 0.15772105887548302, + 0.15649656486697966, + 0.15615147055057618 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047281600662263244, + "scoreError" : 6.838695510515516E-4, + "scoreConfidence" : [ + 0.046597731111211696, + 0.04796547021331479 + ], + "scorePercentiles" : { + "0.0" : 0.04668713239804851, + "50.0" : 0.04720676570665181, + "90.0" : 0.04785155874401267, + "95.0" : 0.04785155874401267, + "99.0" : 0.04785155874401267, + "99.9" : 0.04785155874401267, + "99.99" : 0.04785155874401267, + "99.999" : 0.04785155874401267, + "99.9999" : 0.04785155874401267, + "100.0" : 0.04785155874401267 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04781449074800138, + 0.047079504446610076, + 0.046953820972119184 + ], + [ + 0.046992236287851735, + 0.04668713239804851, + 0.04720676570665181 + ], + [ + 0.04785155874401267, + 0.047633694671760235, + 0.0473152019853136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9135012.469143517, + "scoreError" : 253053.52971484294, + "scoreConfidence" : [ + 8881958.939428674, + 9388065.99885836 + ], + "scorePercentiles" : { + "0.0" : 8947247.978533095, + "50.0" : 9055753.752941176, + "90.0" : 9349670.872897197, + "95.0" : 9349670.872897197, + "99.0" : 9349670.872897197, + "99.9" : 9349670.872897197, + "99.99" : 9349670.872897197, + "99.999" : 9349670.872897197, + "99.9999" : 9349670.872897197, + "100.0" : 9349670.872897197 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9320103.47530289, + 9349670.872897197, + 9313670.555865921 + ], + [ + 8947247.978533095, + 9036093.97289973, + 9037422.124661246 + ], + [ + 9106851.006369427, + 9048298.482820977, + 9055753.752941176 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:22:41Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:22:41Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..a51d44b83f --- /dev/null +++ b/performance-results/2025-03-24T00:22:41Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4176518241718075, + "scoreError" : 0.03280658276993444, + "scoreConfidence" : [ + 3.384845241401873, + 3.450458406941742 + ], + "scorePercentiles" : { + "0.0" : 3.4124960763887926, + "50.0" : 3.4167311543305194, + "90.0" : 3.424648911637398, + "95.0" : 3.424648911637398, + "99.0" : 3.424648911637398, + "99.9" : 3.424648911637398, + "99.99" : 3.424648911637398, + "99.999" : 3.424648911637398, + "99.9999" : 3.424648911637398, + "100.0" : 3.424648911637398 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4124960763887926, + 3.4169398837072293 + ], + [ + 3.416522424953809, + 3.424648911637398 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7270621320703794, + "scoreError" : 0.008373270312183335, + "scoreConfidence" : [ + 1.7186888617581961, + 1.7354354023825627 + ], + "scorePercentiles" : { + "0.0" : 1.7254785768184715, + "50.0" : 1.7272053680709314, + "90.0" : 1.728359215321183, + "95.0" : 1.728359215321183, + "99.0" : 1.728359215321183, + "99.9" : 1.728359215321183, + "99.99" : 1.728359215321183, + "99.999" : 1.728359215321183, + "99.9999" : 1.728359215321183, + "100.0" : 1.728359215321183 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7278401816392681, + 1.728359215321183 + ], + [ + 1.7254785768184715, + 1.7265705545025947 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.868071044762071, + "scoreError" : 0.004228217601595203, + "scoreConfidence" : [ + 0.8638428271604758, + 0.8722992623636662 + ], + "scorePercentiles" : { + "0.0" : 0.8675660430469083, + "50.0" : 0.8678863787909559, + "90.0" : 0.8689453784194636, + "95.0" : 0.8689453784194636, + "99.0" : 0.8689453784194636, + "99.9" : 0.8689453784194636, + "99.99" : 0.8689453784194636, + "99.999" : 0.8689453784194636, + "99.9999" : 0.8689453784194636, + "100.0" : 0.8689453784194636 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8675727546647017, + 0.8682000029172099 + ], + [ + 0.8675660430469083, + 0.8689453784194636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.21024972688744, + "scoreError" : 0.07558240245151955, + "scoreConfidence" : [ + 16.13466732443592, + 16.28583212933896 + ], + "scorePercentiles" : { + "0.0" : 16.13359353840349, + "50.0" : 16.236806302152885, + "90.0" : 16.25798250721321, + "95.0" : 16.25798250721321, + "99.0" : 16.25798250721321, + "99.9" : 16.25798250721321, + "99.99" : 16.25798250721321, + "99.999" : 16.25798250721321, + "99.9999" : 16.25798250721321, + "100.0" : 16.25798250721321 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.203181117707555, + 16.16988292740664, + 16.13359353840349 + ], + [ + 16.245425626132974, + 16.161443650413105, + 16.244571346287103 + ], + [ + 16.239360526269998, + 16.236806302152885, + 16.25798250721321 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2669.028993204871, + "scoreError" : 137.4498966451194, + "scoreConfidence" : [ + 2531.5790965597516, + 2806.47888984999 + ], + "scorePercentiles" : { + "0.0" : 2556.6799422908157, + "50.0" : 2698.057835761459, + "90.0" : 2749.80392247701, + "95.0" : 2749.80392247701, + "99.0" : 2749.80392247701, + "99.9" : 2749.80392247701, + "99.99" : 2749.80392247701, + "99.999" : 2749.80392247701, + "99.9999" : 2749.80392247701, + "100.0" : 2749.80392247701 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2698.057835761459, + 2700.513649170286, + 2691.3840174449533 + ], + [ + 2745.679025287743, + 2743.8605837566774, + 2749.80392247701 + ], + [ + 2556.6799422908157, + 2569.604626828068, + 2565.6773358268297 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69622.25476604533, + "scoreError" : 3039.3046996421267, + "scoreConfidence" : [ + 66582.9500664032, + 72661.55946568746 + ], + "scorePercentiles" : { + "0.0" : 67945.86095422869, + "50.0" : 68858.10770484112, + "90.0" : 71994.01572630244, + "95.0" : 71994.01572630244, + "99.0" : 71994.01572630244, + "99.9" : 71994.01572630244, + "99.99" : 71994.01572630244, + "99.999" : 71994.01572630244, + "99.9999" : 71994.01572630244, + "100.0" : 71994.01572630244 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71985.8498471133, + 71984.38163765594, + 71994.01572630244 + ], + [ + 68131.5306860081, + 67945.86095422869, + 68039.64569420867 + ], + [ + 68858.10770484112, + 68791.96960924863, + 68868.93103480102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 345.54602006775417, + "scoreError" : 10.379158594558005, + "scoreConfidence" : [ + 335.16686147319615, + 355.9251786623122 + ], + "scorePercentiles" : { + "0.0" : 337.0649979908811, + "50.0" : 347.4970106082307, + "90.0" : 354.3317645250134, + "95.0" : 354.3317645250134, + "99.0" : 354.3317645250134, + "99.9" : 354.3317645250134, + "99.99" : 354.3317645250134, + "99.999" : 354.3317645250134, + "99.9999" : 354.3317645250134, + "100.0" : 354.3317645250134 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.88831901345856, + 350.18456102805493, + 354.3317645250134 + ], + [ + 347.4970106082307, + 348.05296895971105, + 346.12872413474 + ], + [ + 337.23163930227275, + 337.0649979908811, + 339.53419504742493 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.35371713199402, + "scoreError" : 1.314903125074696, + "scoreConfidence" : [ + 106.03881400691932, + 108.66862025706871 + ], + "scorePercentiles" : { + "0.0" : 106.50530219512214, + "50.0" : 107.18568194367174, + "90.0" : 108.41755405532847, + "95.0" : 108.41755405532847, + "99.0" : 108.41755405532847, + "99.9" : 108.41755405532847, + "99.99" : 108.41755405532847, + "99.999" : 108.41755405532847, + "99.9999" : 108.41755405532847, + "100.0" : 108.41755405532847 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.24981127400055, + 108.32662146400149, + 108.41755405532847 + ], + [ + 107.18568194367174, + 107.13477003105366, + 107.19828019655115 + ], + [ + 106.51999139644225, + 106.50530219512214, + 106.64544163177464 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06214532710612761, + "scoreError" : 0.0011852883013128773, + "scoreConfidence" : [ + 0.06096003880481473, + 0.06333061540744049 + ], + "scorePercentiles" : { + "0.0" : 0.06138486032693099, + "50.0" : 0.061953984499293735, + "90.0" : 0.06306548163563896, + "95.0" : 0.06306548163563896, + "99.0" : 0.06306548163563896, + "99.9" : 0.06306548163563896, + "99.99" : 0.06306548163563896, + "99.999" : 0.06306548163563896, + "99.9999" : 0.06306548163563896, + "100.0" : 0.06306548163563896 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06296859688814448, + 0.06306548163563896, + 0.06306126613401607 + ], + [ + 0.06203823581048805, + 0.061953984499293735, + 0.06191340799787021 + ], + [ + 0.06145513012296971, + 0.06138486032693099, + 0.0614669805397963 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6512152469115493E-4, + "scoreError" : 1.1829384828379278E-5, + "scoreConfidence" : [ + 3.5329213986277566E-4, + 3.769509095195342E-4 + ], + "scorePercentiles" : { + "0.0" : 3.567600496961329E-4, + "50.0" : 3.644490447931634E-4, + "90.0" : 3.741745325947859E-4, + "95.0" : 3.741745325947859E-4, + "99.0" : 3.741745325947859E-4, + "99.9" : 3.741745325947859E-4, + "99.99" : 3.741745325947859E-4, + "99.999" : 3.741745325947859E-4, + "99.9999" : 3.741745325947859E-4, + "100.0" : 3.741745325947859E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6447179445013437E-4, + 3.644490447931634E-4, + 3.638343372007972E-4 + ], + [ + 3.574252590678668E-4, + 3.582691317531037E-4, + 3.567600496961329E-4 + ], + [ + 3.7298703933026005E-4, + 3.741745325947859E-4, + 3.7372253333415055E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014286522855636308, + "scoreError" : 3.422176757491122E-4, + "scoreConfidence" : [ + 0.013944305179887196, + 0.01462874053138542 + ], + "scorePercentiles" : { + "0.0" : 0.014121189797843438, + "50.0" : 0.014170198734616665, + "90.0" : 0.014574590904983574, + "95.0" : 0.014574590904983574, + "99.0" : 0.014574590904983574, + "99.9" : 0.014574590904983574, + "99.99" : 0.014574590904983574, + "99.999" : 0.014574590904983574, + "99.9999" : 0.014574590904983574, + "100.0" : 0.014574590904983574 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014548139487416732, + 0.014546160303777877, + 0.014574590904983574 + ], + [ + 0.01416057589840752, + 0.014192353136610967, + 0.014170198734616665 + ], + [ + 0.014127603557568556, + 0.014121189797843438, + 0.014137893879501448 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9921077492196557, + "scoreError" : 0.01930856406398767, + "scoreConfidence" : [ + 0.9727991851556681, + 1.0114163132836433 + ], + "scorePercentiles" : { + "0.0" : 0.9776878349789814, + "50.0" : 0.9924878263199682, + "90.0" : 1.0144587190099412, + "95.0" : 1.0144587190099412, + "99.0" : 1.0144587190099412, + "99.9" : 1.0144587190099412, + "99.99" : 1.0144587190099412, + "99.999" : 1.0144587190099412, + "99.9999" : 1.0144587190099412, + "100.0" : 1.0144587190099412 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9970329595214357, + 0.9986729526662672, + 0.9964110701404802 + ], + [ + 0.9829197303911933, + 0.9788613039052559, + 0.9776878349789814 + ], + [ + 1.0144587190099412, + 0.9904373460433792, + 0.9924878263199682 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012921779722266246, + "scoreError" : 2.2252345704252554E-4, + "scoreConfidence" : [ + 0.01269925626522372, + 0.013144303179308772 + ], + "scorePercentiles" : { + "0.0" : 0.012807454812541783, + "50.0" : 0.012926500284236968, + "90.0" : 0.013009797126978096, + "95.0" : 0.013009797126978096, + "99.0" : 0.013009797126978096, + "99.9" : 0.013009797126978096, + "99.99" : 0.013009797126978096, + "99.999" : 0.013009797126978096, + "99.9999" : 0.013009797126978096, + "100.0" : 0.013009797126978096 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012807454812541783, + 0.012876620666477814, + 0.012877833138453773 + ], + [ + 0.012975167430020163, + 0.012983805159125847, + 0.013009797126978096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6740661339279614, + "scoreError" : 0.1367137587039101, + "scoreConfidence" : [ + 3.537352375224051, + 3.8107798926318717 + ], + "scorePercentiles" : { + "0.0" : 3.6163268293564714, + "50.0" : 3.665471940654629, + "90.0" : 3.7335179947761192, + "95.0" : 3.7335179947761192, + "99.0" : 3.7335179947761192, + "99.9" : 3.7335179947761192, + "99.99" : 3.7335179947761192, + "99.999" : 3.7335179947761192, + "99.9999" : 3.7335179947761192, + "100.0" : 3.7335179947761192 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6163268293564714, + 3.639242845705968, + 3.641746879096868 + ], + [ + 3.6891970022123894, + 3.7335179947761192, + 3.7243652524199553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.912590076892591, + "scoreError" : 0.0803534341024097, + "scoreConfidence" : [ + 2.8322366427901815, + 2.992943510995001 + ], + "scorePercentiles" : { + "0.0" : 2.875525743243243, + "50.0" : 2.884065987600923, + "90.0" : 2.9793437852249034, + "95.0" : 2.9793437852249034, + "99.0" : 2.9793437852249034, + "99.9" : 2.9793437852249034, + "99.99" : 2.9793437852249034, + "99.999" : 2.9793437852249034, + "99.9999" : 2.9793437852249034, + "100.0" : 2.9793437852249034 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8792008750719633, + 2.875525743243243, + 2.879239616292458 + ], + [ + 2.977670115212861, + 2.9793437852249034, + 2.971356167260844 + ], + [ + 2.887610698614319, + 2.884065987600923, + 2.879297703511802 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18040665676819445, + "scoreError" : 0.016040685065821514, + "scoreConfidence" : [ + 0.16436597170237294, + 0.19644734183401596 + ], + "scorePercentiles" : { + "0.0" : 0.17271579670120898, + "50.0" : 0.17492238903270946, + "90.0" : 0.19332436052041446, + "95.0" : 0.19332436052041446, + "99.0" : 0.19332436052041446, + "99.9" : 0.19332436052041446, + "99.99" : 0.19332436052041446, + "99.999" : 0.19332436052041446, + "99.9999" : 0.19332436052041446, + "100.0" : 0.19332436052041446 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17597227153867812, + 0.17492238903270946, + 0.1748560182371352 + ], + [ + 0.19332436052041446, + 0.19294238105344394, + 0.19289537515190094 + ], + [ + 0.17271579670120898, + 0.17295336802144587, + 0.17307795065681303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3337584233657038, + "scoreError" : 0.00641428915227004, + "scoreConfidence" : [ + 0.3273441342134338, + 0.3401727125179739 + ], + "scorePercentiles" : { + "0.0" : 0.330027413253688, + "50.0" : 0.3320781430563857, + "90.0" : 0.33920266566040297, + "95.0" : 0.33920266566040297, + "99.0" : 0.33920266566040297, + "99.9" : 0.33920266566040297, + "99.99" : 0.33920266566040297, + "99.999" : 0.33920266566040297, + "99.9999" : 0.33920266566040297, + "100.0" : 0.33920266566040297 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33920266566040297, + 0.33819932622002774, + 0.33880499762840494 + ], + [ + 0.330027413253688, + 0.3304519575705505, + 0.3308180865394158 + ], + [ + 0.3322776499534822, + 0.3320781430563857, + 0.33196557040897623 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1661026225633705, + "scoreError" : 0.008337119359901021, + "scoreConfidence" : [ + 0.15776550320346946, + 0.17443974192327152 + ], + "scorePercentiles" : { + "0.0" : 0.15952054031807814, + "50.0" : 0.167699954084285, + "90.0" : 0.17118456085453113, + "95.0" : 0.17118456085453113, + "99.0" : 0.17118456085453113, + "99.9" : 0.17118456085453113, + "99.99" : 0.17118456085453113, + "99.999" : 0.17118456085453113, + "99.9999" : 0.17118456085453113, + "100.0" : 0.17118456085453113 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17118456085453113, + 0.17085764863571903, + 0.17079298237464136 + ], + [ + 0.15952054031807814, + 0.15996125433489028, + 0.159874185931255 + ], + [ + 0.16773681192237375, + 0.167699954084285, + 0.16729566461456102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38635613779325884, + "scoreError" : 0.0060439134029958005, + "scoreConfidence" : [ + 0.380312224390263, + 0.39240005119625465 + ], + "scorePercentiles" : { + "0.0" : 0.38195458276678634, + "50.0" : 0.38560133064702706, + "90.0" : 0.39093867740422206, + "95.0" : 0.39093867740422206, + "99.0" : 0.39093867740422206, + "99.9" : 0.39093867740422206, + "99.99" : 0.39093867740422206, + "99.999" : 0.39093867740422206, + "99.9999" : 0.39093867740422206, + "100.0" : 0.39093867740422206 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3823639669649002, + 0.38230232548359966, + 0.38195458276678634 + ], + [ + 0.38974632624030553, + 0.3855979278195489, + 0.38560133064702706 + ], + [ + 0.38964763343074227, + 0.39093867740422206, + 0.38905246938219734 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15826757739724495, + "scoreError" : 0.004627573086720224, + "scoreConfidence" : [ + 0.1536400043105247, + 0.1628951504839652 + ], + "scorePercentiles" : { + "0.0" : 0.15448236841536134, + "50.0" : 0.1591381985041375, + "90.0" : 0.16089253403587805, + "95.0" : 0.16089253403587805, + "99.0" : 0.16089253403587805, + "99.9" : 0.16089253403587805, + "99.99" : 0.16089253403587805, + "99.999" : 0.16089253403587805, + "99.9999" : 0.16089253403587805, + "100.0" : 0.16089253403587805 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15521114455998758, + 0.15448236841536134, + 0.15455100908739663 + ], + [ + 0.1608481260535289, + 0.16089253403587805, + 0.16086269677959014 + ], + [ + 0.1591381985041375, + 0.15963652022540067, + 0.1587855989139237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047272604046442124, + "scoreError" : 0.001440391145386556, + "scoreConfidence" : [ + 0.04583221290105557, + 0.04871299519182868 + ], + "scorePercentiles" : { + "0.0" : 0.04625750033304962, + "50.0" : 0.04723635614652465, + "90.0" : 0.04837972442320066, + "95.0" : 0.04837972442320066, + "99.0" : 0.04837972442320066, + "99.9" : 0.04837972442320066, + "99.99" : 0.04837972442320066, + "99.999" : 0.04837972442320066, + "99.9999" : 0.04837972442320066, + "100.0" : 0.04837972442320066 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04741171134216128, + 0.04722703777166983, + 0.04723635614652465 + ], + [ + 0.04837972442320066, + 0.048154765152864924, + 0.04821053368912287 + ], + [ + 0.046259463596623106, + 0.04625750033304962, + 0.04631634396276226 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9628501.02926758, + "scoreError" : 641376.5173927421, + "scoreConfidence" : [ + 8987124.511874838, + 1.026987754666032E7 + ], + "scorePercentiles" : { + "0.0" : 9113710.301457195, + "50.0" : 9821262.300294407, + "90.0" : 9976360.238285145, + "95.0" : 9976360.238285145, + "99.0" : 9976360.238285145, + "99.9" : 9976360.238285145, + "99.99" : 9976360.238285145, + "99.999" : 9976360.238285145, + "99.9999" : 9976360.238285145, + "100.0" : 9976360.238285145 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9976360.238285145, + 9899911.798219584, + 9908957.99009901 + ], + [ + 9126353.703467153, + 9131182.38229927, + 9113710.301457195 + ], + [ + 9866579.378698224, + 9812191.170588234, + 9821262.300294407 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:22:42Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:22:42Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..71f139c13c --- /dev/null +++ b/performance-results/2025-03-24T00:22:42Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.420161184183998, + "scoreError" : 0.01312921616822022, + "scoreConfidence" : [ + 3.4070319680157777, + 3.4332904003522184 + ], + "scorePercentiles" : { + "0.0" : 3.4181212856651784, + "50.0" : 3.4200665558935337, + "90.0" : 3.422390339283747, + "95.0" : 3.422390339283747, + "99.0" : 3.422390339283747, + "99.9" : 3.422390339283747, + "99.99" : 3.422390339283747, + "99.999" : 3.422390339283747, + "99.9999" : 3.422390339283747, + "100.0" : 3.422390339283747 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4213385479537735, + 3.422390339283747 + ], + [ + 3.418794563833294, + 3.4181212856651784 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7276845429241154, + "scoreError" : 0.01306208372096958, + "scoreConfidence" : [ + 1.7146224592031458, + 1.740746626645085 + ], + "scorePercentiles" : { + "0.0" : 1.7256505716963815, + "50.0" : 1.727679262588992, + "90.0" : 1.7297290748220968, + "95.0" : 1.7297290748220968, + "99.0" : 1.7297290748220968, + "99.9" : 1.7297290748220968, + "99.99" : 1.7297290748220968, + "99.999" : 1.7297290748220968, + "99.9999" : 1.7297290748220968, + "100.0" : 1.7297290748220968 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7290829413006634, + 1.7297290748220968 + ], + [ + 1.7256505716963815, + 1.7262755838773205 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8687410304418786, + "scoreError" : 0.0024592742022505935, + "scoreConfidence" : [ + 0.866281756239628, + 0.8712003046441291 + ], + "scorePercentiles" : { + "0.0" : 0.8684148887674343, + "50.0" : 0.8686953515573114, + "90.0" : 0.8691585298854573, + "95.0" : 0.8691585298854573, + "99.0" : 0.8691585298854573, + "99.9" : 0.8691585298854573, + "99.99" : 0.8691585298854573, + "99.999" : 0.8691585298854573, + "99.9999" : 0.8691585298854573, + "100.0" : 0.8691585298854573 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.868968907418696, + 0.8691585298854573 + ], + [ + 0.8684217956959267, + 0.8684148887674343 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.224821826130235, + "scoreError" : 0.10048051732951685, + "scoreConfidence" : [ + 16.12434130880072, + 16.32530234345975 + ], + "scorePercentiles" : { + "0.0" : 16.16446628444778, + "50.0" : 16.216501795428456, + "90.0" : 16.31885112609713, + "95.0" : 16.31885112609713, + "99.0" : 16.31885112609713, + "99.9" : 16.31885112609713, + "99.99" : 16.31885112609713, + "99.999" : 16.31885112609713, + "99.9999" : 16.31885112609713, + "100.0" : 16.31885112609713 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.167966195040854, + 16.171702268596363, + 16.186333278362973 + ], + [ + 16.216501795428456, + 16.219076817393454, + 16.16446628444778 + ], + [ + 16.27979011280597, + 16.31885112609713, + 16.29870855699916 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2737.5909349527656, + "scoreError" : 119.9485903655442, + "scoreConfidence" : [ + 2617.6423445872215, + 2857.5395253183096 + ], + "scorePercentiles" : { + "0.0" : 2657.620468169439, + "50.0" : 2728.8335513951547, + "90.0" : 2828.7526106375753, + "95.0" : 2828.7526106375753, + "99.0" : 2828.7526106375753, + "99.9" : 2828.7526106375753, + "99.99" : 2828.7526106375753, + "99.999" : 2828.7526106375753, + "99.9999" : 2828.7526106375753, + "100.0" : 2828.7526106375753 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2657.620468169439, + 2662.884293462235, + 2659.29952062177 + ], + [ + 2824.7339008494246, + 2828.7526106375753, + 2818.3510215124497 + ], + [ + 2728.2922326958756, + 2729.550815230966, + 2728.8335513951547 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69862.82581904189, + "scoreError" : 1728.1188838150238, + "scoreConfidence" : [ + 68134.70693522686, + 71590.94470285691 + ], + "scorePercentiles" : { + "0.0" : 68958.28296516981, + "50.0" : 69417.52869894679, + "90.0" : 71216.90369253689, + "95.0" : 71216.90369253689, + "99.0" : 71216.90369253689, + "99.9" : 71216.90369253689, + "99.99" : 71216.90369253689, + "99.999" : 71216.90369253689, + "99.9999" : 71216.90369253689, + "100.0" : 71216.90369253689 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69002.86496078158, + 68958.28296516981, + 68978.58832205336 + ], + [ + 69353.2210103416, + 69417.52869894679, + 69417.55557708694 + ], + [ + 71210.03441354769, + 71216.90369253689, + 71210.45273091237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.6851162543681, + "scoreError" : 2.9786665796925273, + "scoreConfidence" : [ + 353.7064496746756, + 359.6637828340606 + ], + "scorePercentiles" : { + "0.0" : 355.03951802399394, + "50.0" : 355.77587736376466, + "90.0" : 359.56820737462897, + "95.0" : 359.56820737462897, + "99.0" : 359.56820737462897, + "99.9" : 359.56820737462897, + "99.99" : 359.56820737462897, + "99.999" : 359.56820737462897, + "99.9999" : 359.56820737462897, + "100.0" : 359.56820737462897 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.77587736376466, + 355.1195495481835, + 355.03951802399394 + ], + [ + 355.53794376732657, + 355.6143610562547, + 356.1276712534493 + ], + [ + 358.60885342768995, + 359.56820737462897, + 358.77406447402103 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.63031003241571, + "scoreError" : 5.9928407989608665, + "scoreConfidence" : [ + 100.63746923345484, + 112.62315083137658 + ], + "scorePercentiles" : { + "0.0" : 101.8237778560693, + "50.0" : 108.37566141662414, + "90.0" : 109.67987437919469, + "95.0" : 109.67987437919469, + "99.0" : 109.67987437919469, + "99.9" : 109.67987437919469, + "99.99" : 109.67987437919469, + "99.999" : 109.67987437919469, + "99.9999" : 109.67987437919469, + "100.0" : 109.67987437919469 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.96717304519494, + 101.8237778560693, + 102.04935047858294 + ], + [ + 107.95691746021808, + 108.37566141662414, + 108.5213479810202 + ], + [ + 109.67987437919469, + 109.62918120434263, + 109.66950647049454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06115860988012198, + "scoreError" : 2.5866124625998005E-4, + "scoreConfidence" : [ + 0.060899948633862, + 0.061417271126381956 + ], + "scorePercentiles" : { + "0.0" : 0.06094085120904836, + "50.0" : 0.06123712456675362, + "90.0" : 0.061325009830254865, + "95.0" : 0.061325009830254865, + "99.0" : 0.061325009830254865, + "99.9" : 0.061325009830254865, + "99.99" : 0.061325009830254865, + "99.999" : 0.061325009830254865, + "99.9999" : 0.061325009830254865, + "100.0" : 0.061325009830254865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06121436393797861, + 0.06124506581292373, + 0.061244503631753655 + ], + [ + 0.061325009830254865, + 0.0612870807567614, + 0.06123712456675362 + ], + [ + 0.06094085120904836, + 0.06097625959597807, + 0.06095722957964548 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.660580843532509E-4, + "scoreError" : 2.1584630401834428E-5, + "scoreConfidence" : [ + 3.444734539514165E-4, + 3.876427147550853E-4 + ], + "scorePercentiles" : { + "0.0" : 3.485295668586137E-4, + "50.0" : 3.7371202020352256E-4, + "90.0" : 3.7543158886062337E-4, + "95.0" : 3.7543158886062337E-4, + "99.0" : 3.7543158886062337E-4, + "99.9" : 3.7543158886062337E-4, + "99.99" : 3.7543158886062337E-4, + "99.999" : 3.7543158886062337E-4, + "99.9999" : 3.7543158886062337E-4, + "100.0" : 3.7543158886062337E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7371202020352256E-4, + 3.743454742106291E-4, + 3.736798714136409E-4 + ], + [ + 3.485295668586137E-4, + 3.4913701701646063E-4, + 3.491975061719075E-4 + ], + [ + 3.7543158886062337E-4, + 3.753495183136453E-4, + 3.7514019613021487E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014294007118711134, + "scoreError" : 2.467831746836528E-4, + "scoreConfidence" : [ + 0.01404722394402748, + 0.014540790293394787 + ], + "scorePercentiles" : { + "0.0" : 0.01410185573973926, + "50.0" : 0.014340279476126561, + "90.0" : 0.014435574408039945, + "95.0" : 0.014435574408039945, + "99.0" : 0.014435574408039945, + "99.9" : 0.014435574408039945, + "99.99" : 0.014435574408039945, + "99.999" : 0.014435574408039945, + "99.9999" : 0.014435574408039945, + "100.0" : 0.014435574408039945 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014340279476126561, + 0.014339337843476616, + 0.014350159556011566 + ], + [ + 0.014435574408039945, + 0.014430580636409946, + 0.014434201299929129 + ], + [ + 0.014106480124135986, + 0.01410185573973926, + 0.014107594984531218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9827271961215186, + "scoreError" : 0.01661406289183188, + "scoreConfidence" : [ + 0.9661131332296867, + 0.9993412590133505 + ], + "scorePercentiles" : { + "0.0" : 0.9650379618836245, + "50.0" : 0.9843077026574804, + "90.0" : 0.9982393412856858, + "95.0" : 0.9982393412856858, + "99.0" : 0.9982393412856858, + "99.9" : 0.9982393412856858, + "99.99" : 0.9982393412856858, + "99.999" : 0.9982393412856858, + "99.9999" : 0.9982393412856858, + "100.0" : 0.9982393412856858 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9900924386694386, + 0.9982393412856858, + 0.98929232505688 + ], + [ + 0.9650379618836245, + 0.9769195255445932, + 0.9732962304622871 + ], + [ + 0.9851143342198582, + 0.9822449053138199, + 0.9843077026574804 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012964384898346287, + "scoreError" : 2.577701313091225E-4, + "scoreConfidence" : [ + 0.012706614767037164, + 0.01322215502965541 + ], + "scorePercentiles" : { + "0.0" : 0.012813191806904116, + "50.0" : 0.01298516114747426, + "90.0" : 0.013039108015990779, + "95.0" : 0.013039108015990779, + "99.0" : 0.013039108015990779, + "99.9" : 0.013039108015990779, + "99.99" : 0.013039108015990779, + "99.999" : 0.013039108015990779, + "99.9999" : 0.013039108015990779, + "100.0" : 0.013039108015990779 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012813191806904116, + 0.012931354416990374, + 0.012924645154536313 + ], + [ + 0.013038967877958146, + 0.013039042117697986, + 0.013039108015990779 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.673469200929784, + "scoreError" : 0.14943802892508878, + "scoreConfidence" : [ + 3.524031172004695, + 3.8229072298548727 + ], + "scorePercentiles" : { + "0.0" : 3.6237315644927537, + "50.0" : 3.67061608442467, + "90.0" : 3.7256586865227104, + "95.0" : 3.7256586865227104, + "99.0" : 3.7256586865227104, + "99.9" : 3.7256586865227104, + "99.99" : 3.7256586865227104, + "99.999" : 3.7256586865227104, + "99.9999" : 3.7256586865227104, + "100.0" : 3.7256586865227104 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6248462644927537, + 3.6237315644927537, + 3.626285658448151 + ], + [ + 3.7253465212211467, + 3.7149465104011887, + 3.7256586865227104 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.845002438442127, + "scoreError" : 0.04287871366742935, + "scoreConfidence" : [ + 2.802123724774698, + 2.887881152109556 + ], + "scorePercentiles" : { + "0.0" : 2.7989082118667787, + "50.0" : 2.8569832750642674, + "90.0" : 2.8689466262191625, + "95.0" : 2.8689466262191625, + "99.0" : 2.8689466262191625, + "99.9" : 2.8689466262191625, + "99.99" : 2.8689466262191625, + "99.999" : 2.8689466262191625, + "99.9999" : 2.8689466262191625, + "100.0" : 2.8689466262191625 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8689466262191625, + 2.8678104997133027, + 2.8603603591649986 + ], + [ + 2.8197480668170285, + 2.8194921466027627, + 2.7989082118667787 + ], + [ + 2.862014226323319, + 2.8569832750642674, + 2.8507585342075257 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17667398738573184, + "scoreError" : 0.004522962845580232, + "scoreConfidence" : [ + 0.1721510245401516, + 0.18119695023131208 + ], + "scorePercentiles" : { + "0.0" : 0.17274437678355503, + "50.0" : 0.17773538823424864, + "90.0" : 0.17929800475131782, + "95.0" : 0.17929800475131782, + "99.0" : 0.17929800475131782, + "99.9" : 0.17929800475131782, + "99.99" : 0.17929800475131782, + "99.999" : 0.17929800475131782, + "99.9999" : 0.17929800475131782, + "100.0" : 0.17929800475131782 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17929800475131782, + 0.17875492422779923, + 0.1786768472698685 + ], + [ + 0.17354256814868804, + 0.17317766123473893, + 0.17274437678355503 + ], + [ + 0.17841636940231936, + 0.177719746419051, + 0.17773538823424864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3278785338826535, + "scoreError" : 0.02325834532732937, + "scoreConfidence" : [ + 0.30462018855532413, + 0.3511368792099828 + ], + "scorePercentiles" : { + "0.0" : 0.3089522779288186, + "50.0" : 0.33629414826646936, + "90.0" : 0.33916132474139393, + "95.0" : 0.33916132474139393, + "99.0" : 0.33916132474139393, + "99.9" : 0.33916132474139393, + "99.99" : 0.33916132474139393, + "99.999" : 0.33916132474139393, + "99.9999" : 0.33916132474139393, + "100.0" : 0.33916132474139393 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.336947062232555, + 0.33597702281202757, + 0.33629414826646936 + ], + [ + 0.31003876372655403, + 0.3089522779288186, + 0.3094074593298475 + ], + [ + 0.33916132474139393, + 0.3373513187828903, + 0.3367774271233246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16002382610015384, + "scoreError" : 0.0028749300894222066, + "scoreConfidence" : [ + 0.15714889601073162, + 0.16289875618957605 + ], + "scorePercentiles" : { + "0.0" : 0.157941736670036, + "50.0" : 0.16011360556863122, + "90.0" : 0.16208578819067376, + "95.0" : 0.16208578819067376, + "99.0" : 0.16208578819067376, + "99.9" : 0.16208578819067376, + "99.99" : 0.16208578819067376, + "99.999" : 0.16208578819067376, + "99.9999" : 0.16208578819067376, + "100.0" : 0.16208578819067376 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15800144895089427, + 0.15802927755566443, + 0.157941736670036 + ], + [ + 0.16208578819067376, + 0.1619398366719026, + 0.16176520781636713 + ], + [ + 0.1602269537756557, + 0.16011360556863122, + 0.16011057970155945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3937664494679593, + "scoreError" : 0.005156686612415254, + "scoreConfidence" : [ + 0.38860976285554405, + 0.39892313608037455 + ], + "scorePercentiles" : { + "0.0" : 0.3895133925761471, + "50.0" : 0.393265371583625, + "90.0" : 0.39806655210572406, + "95.0" : 0.39806655210572406, + "99.0" : 0.39806655210572406, + "99.9" : 0.39806655210572406, + "99.99" : 0.39806655210572406, + "99.999" : 0.39806655210572406, + "99.9999" : 0.39806655210572406, + "100.0" : 0.39806655210572406 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39707056577327776, + 0.39672426091958585, + 0.39806655210572406 + ], + [ + 0.3921561219952159, + 0.39032111385191837, + 0.3895133925761471 + ], + [ + 0.39482050100675115, + 0.393265371583625, + 0.39196016539938855 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15675301344455994, + "scoreError" : 0.004658609047840728, + "scoreConfidence" : [ + 0.1520944043967192, + 0.16141162249240068 + ], + "scorePercentiles" : { + "0.0" : 0.1545591449127525, + "50.0" : 0.15518161604233263, + "90.0" : 0.16099979876998374, + "95.0" : 0.16099979876998374, + "99.0" : 0.16099979876998374, + "99.9" : 0.16099979876998374, + "99.99" : 0.16099979876998374, + "99.999" : 0.16099979876998374, + "99.9999" : 0.16099979876998374, + "100.0" : 0.16099979876998374 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15467007167272445, + 0.1545591449127525, + 0.1545636310453021 + ], + [ + 0.15573376948951942, + 0.15518161604233263, + 0.1548710712548977 + ], + [ + 0.16099979876998374, + 0.1602751452383242, + 0.1599228725752027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047817784078729414, + "scoreError" : 0.0011948342870446483, + "scoreConfidence" : [ + 0.04662294979168476, + 0.049012618365774065 + ], + "scorePercentiles" : { + "0.0" : 0.047114732199141585, + "50.0" : 0.047610175369687965, + "90.0" : 0.04905999008021194, + "95.0" : 0.04905999008021194, + "99.0" : 0.04905999008021194, + "99.9" : 0.04905999008021194, + "99.99" : 0.04905999008021194, + "99.999" : 0.04905999008021194, + "99.9999" : 0.04905999008021194, + "100.0" : 0.04905999008021194 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047308128061386207, + 0.04719235425810044, + 0.047269258719872184 + ], + [ + 0.04856412413314167, + 0.04905999008021194, + 0.048489256354432346 + ], + [ + 0.047610175369687965, + 0.04775203753259032, + 0.047114732199141585 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9421759.159399383, + "scoreError" : 707140.3164048794, + "scoreConfidence" : [ + 8714618.842994504, + 1.0128899475804262E7 + ], + "scorePercentiles" : { + "0.0" : 9036655.30532972, + "50.0" : 9254157.081406105, + "90.0" : 1.0006135448E7, + "95.0" : 1.0006135448E7, + "99.0" : 1.0006135448E7, + "99.9" : 1.0006135448E7, + "99.99" : 1.0006135448E7, + "99.999" : 1.0006135448E7, + "99.9999" : 1.0006135448E7, + "100.0" : 1.0006135448E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9206639.917203313, + 9254157.081406105, + 9259158.390379278 + ], + [ + 9036655.30532972, + 9050269.691402715, + 9074580.583484573 + ], + [ + 9935700.8897716, + 9972535.127617149, + 1.0006135448E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:23:14Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:23:14Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..cde7a7ef91 --- /dev/null +++ b/performance-results/2025-03-24T00:23:14Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4223396104835797, + "scoreError" : 0.043725212925550025, + "scoreConfidence" : [ + 3.37861439755803, + 3.4660648234091296 + ], + "scorePercentiles" : { + "0.0" : 3.4145587032492717, + "50.0" : 3.42227609893122, + "90.0" : 3.4302475408226076, + "95.0" : 3.4302475408226076, + "99.0" : 3.4302475408226076, + "99.9" : 3.4302475408226076, + "99.99" : 3.4302475408226076, + "99.999" : 3.4302475408226076, + "99.9999" : 3.4302475408226076, + "100.0" : 3.4302475408226076 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4145587032492717, + 3.4196048034813886 + ], + [ + 3.424947394381052, + 3.4302475408226076 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7293409537320772, + "scoreError" : 0.013098203820130744, + "scoreConfidence" : [ + 1.7162427499119464, + 1.742439157552208 + ], + "scorePercentiles" : { + "0.0" : 1.7271885468681993, + "50.0" : 1.7291572733627323, + "90.0" : 1.7318607213346457, + "95.0" : 1.7318607213346457, + "99.0" : 1.7318607213346457, + "99.9" : 1.7318607213346457, + "99.99" : 1.7318607213346457, + "99.999" : 1.7318607213346457, + "99.9999" : 1.7318607213346457, + "100.0" : 1.7318607213346457 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7271885468681993, + 1.7299560719039933 + ], + [ + 1.728358474821471, + 1.7318607213346457 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8690871927147313, + "scoreError" : 0.004974514875233495, + "scoreConfidence" : [ + 0.8641126778394979, + 0.8740617075899648 + ], + "scorePercentiles" : { + "0.0" : 0.8683436536883511, + "50.0" : 0.8689709686170206, + "90.0" : 0.8700631799365328, + "95.0" : 0.8700631799365328, + "99.0" : 0.8700631799365328, + "99.9" : 0.8700631799365328, + "99.99" : 0.8700631799365328, + "99.999" : 0.8700631799365328, + "99.9999" : 0.8700631799365328, + "100.0" : 0.8700631799365328 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8683436536883511, + 0.8686206739831588 + ], + [ + 0.8693212632508825, + 0.8700631799365328 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.176447094328555, + "scoreError" : 0.21039762953362492, + "scoreConfidence" : [ + 15.96604946479493, + 16.38684472386218 + ], + "scorePercentiles" : { + "0.0" : 16.02273460262859, + "50.0" : 16.17803229239284, + "90.0" : 16.338047338633128, + "95.0" : 16.338047338633128, + "99.0" : 16.338047338633128, + "99.9" : 16.338047338633128, + "99.99" : 16.338047338633128, + "99.999" : 16.338047338633128, + "99.9999" : 16.338047338633128, + "100.0" : 16.338047338633128 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.149948890904675, + 16.1789391938823, + 16.17803229239284 + ], + [ + 16.042872420624704, + 16.0440694515352, + 16.02273460262859 + ], + [ + 16.338047338633128, + 16.327952875347822, + 16.30542678300774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2700.2882550030386, + "scoreError" : 96.7322058302932, + "scoreConfidence" : [ + 2603.5560491727456, + 2797.0204608333315 + ], + "scorePercentiles" : { + "0.0" : 2653.07991575285, + "50.0" : 2666.391896086423, + "90.0" : 2780.899937372966, + "95.0" : 2780.899937372966, + "99.0" : 2780.899937372966, + "99.9" : 2780.899937372966, + "99.99" : 2780.899937372966, + "99.999" : 2780.899937372966, + "99.9999" : 2780.899937372966, + "100.0" : 2780.899937372966 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2773.2417483443546, + 2780.899937372966, + 2775.7904882477383 + ], + [ + 2663.2819930577834, + 2653.07991575285, + 2654.1555989667613 + ], + [ + 2666.391896086423, + 2665.495887754995, + 2670.2568294434764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70174.19309953183, + "scoreError" : 1564.0509467698946, + "scoreConfidence" : [ + 68610.14215276192, + 71738.24404630173 + ], + "scorePercentiles" : { + "0.0" : 68930.65160154008, + "50.0" : 70571.78206598868, + "90.0" : 71019.93901817729, + "95.0" : 71019.93901817729, + "99.0" : 71019.93901817729, + "99.9" : 71019.93901817729, + "99.99" : 71019.93901817729, + "99.999" : 71019.93901817729, + "99.9999" : 71019.93901817729, + "100.0" : 71019.93901817729 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70996.91830347097, + 71019.93901817729, + 71006.93058404124 + ], + [ + 68970.93751249161, + 68930.65160154008, + 68983.81206796458 + ], + [ + 70506.51290054324, + 70580.25384156879, + 70571.78206598868 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 351.0196860126746, + "scoreError" : 6.327176034437353, + "scoreConfidence" : [ + 344.69250997823724, + 357.3468620471119 + ], + "scorePercentiles" : { + "0.0" : 344.5603693554375, + "50.0" : 350.39200219743225, + "90.0" : 355.7240486824901, + "95.0" : 355.7240486824901, + "99.0" : 355.7240486824901, + "99.9" : 355.7240486824901, + "99.99" : 355.7240486824901, + "99.999" : 355.7240486824901, + "99.9999" : 355.7240486824901, + "100.0" : 355.7240486824901 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.7240486824901, + 355.236232183386, + 355.3319181912754 + ], + [ + 348.72447907602054, + 348.4251848899698, + 344.5603693554375 + ], + [ + 350.39200219743225, + 350.3541221087014, + 350.42881742935845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.65909013547264, + "scoreError" : 1.4190899578645233, + "scoreConfidence" : [ + 105.24000017760811, + 108.07818009333717 + ], + "scorePercentiles" : { + "0.0" : 105.6162841290003, + "50.0" : 106.50638068901223, + "90.0" : 107.78984731739712, + "95.0" : 107.78984731739712, + "99.0" : 107.78984731739712, + "99.9" : 107.78984731739712, + "99.99" : 107.78984731739712, + "99.999" : 107.78984731739712, + "99.9999" : 107.78984731739712, + "100.0" : 107.78984731739712 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.5904277872302, + 107.78984731739712, + 107.70949927973304 + ], + [ + 106.506954789398, + 106.50638068901223, + 106.50478486079068 + ], + [ + 105.6162841290003, + 105.87755649908355, + 105.8300758676087 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06209317411218212, + "scoreError" : 7.538075008411679E-4, + "scoreConfidence" : [ + 0.06133936661134095, + 0.06284698161302328 + ], + "scorePercentiles" : { + "0.0" : 0.06144225748201306, + "50.0" : 0.062250828252709424, + "90.0" : 0.06256984610571628, + "95.0" : 0.06256984610571628, + "99.0" : 0.06256984610571628, + "99.9" : 0.06256984610571628, + "99.99" : 0.06256984610571628, + "99.999" : 0.06256984610571628, + "99.9999" : 0.06256984610571628, + "100.0" : 0.06256984610571628 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06239646361095166, + 0.062418272145657004, + 0.06221235583108335 + ], + [ + 0.06144225748201306, + 0.06161576037905581, + 0.06148573024188094 + ], + [ + 0.062250828252709424, + 0.06256984610571628, + 0.06244705296057151 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7607663812243037E-4, + "scoreError" : 1.1442859251684939E-5, + "scoreConfidence" : [ + 3.646337788707454E-4, + 3.875194973741153E-4 + ], + "scorePercentiles" : { + "0.0" : 3.681143338609699E-4, + "50.0" : 3.7442910870162834E-4, + "90.0" : 3.8507081206627316E-4, + "95.0" : 3.8507081206627316E-4, + "99.0" : 3.8507081206627316E-4, + "99.9" : 3.8507081206627316E-4, + "99.99" : 3.8507081206627316E-4, + "99.999" : 3.8507081206627316E-4, + "99.9999" : 3.8507081206627316E-4, + "100.0" : 3.8507081206627316E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8409582662134395E-4, + 3.8449133940953627E-4, + 3.8507081206627316E-4 + ], + [ + 3.690260844272774E-4, + 3.681143338609699E-4, + 3.702101250850547E-4 + ], + [ + 3.7412950073089176E-4, + 3.751226121988977E-4, + 3.7442910870162834E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014130309759608764, + "scoreError" : 1.1557199490178697E-4, + "scoreConfidence" : [ + 0.014014737764706976, + 0.014245881754510551 + ], + "scorePercentiles" : { + "0.0" : 0.014047087416772018, + "50.0" : 0.014118687416612664, + "90.0" : 0.014217589361396605, + "95.0" : 0.014217589361396605, + "99.0" : 0.014217589361396605, + "99.9" : 0.014217589361396605, + "99.99" : 0.014217589361396605, + "99.999" : 0.014217589361396605, + "99.9999" : 0.014217589361396605, + "100.0" : 0.014217589361396605 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014077196809581392, + 0.01405035927748288, + 0.014047087416772018 + ], + [ + 0.01421129386050927, + 0.014217589361396605, + 0.014214491057772673 + ], + [ + 0.014119107481913626, + 0.014116975154437756, + 0.014118687416612664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9773896294313688, + "scoreError" : 0.010852659511471296, + "scoreConfidence" : [ + 0.9665369699198975, + 0.98824228894284 + ], + "scorePercentiles" : { + "0.0" : 0.968145494482091, + "50.0" : 0.9763926268306972, + "90.0" : 0.9898854295753736, + "95.0" : 0.9898854295753736, + "99.0" : 0.9898854295753736, + "99.9" : 0.9898854295753736, + "99.99" : 0.9898854295753736, + "99.999" : 0.9898854295753736, + "99.9999" : 0.9898854295753736, + "100.0" : 0.9898854295753736 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.980458675490196, + 0.9763926268306972, + 0.9734553186021611 + ], + [ + 0.9725973313557673, + 0.9735463582554517, + 0.968145494482091 + ], + [ + 0.9898854295753736, + 0.9820591416085633, + 0.9799662886820186 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012999210482276655, + "scoreError" : 2.1611055986766895E-4, + "scoreConfidence" : [ + 0.012783099922408987, + 0.013215321042144323 + ], + "scorePercentiles" : { + "0.0" : 0.012919324624185454, + "50.0" : 0.013001931921219387, + "90.0" : 0.01307385693106586, + "95.0" : 0.01307385693106586, + "99.0" : 0.01307385693106586, + "99.9" : 0.01307385693106586, + "99.99" : 0.01307385693106586, + "99.999" : 0.01307385693106586, + "99.9999" : 0.01307385693106586, + "100.0" : 0.01307385693106586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012919324624185454, + 0.012938083570310377, + 0.012929917723875773 + ], + [ + 0.01306829977209407, + 0.01307385693106586, + 0.013065780272128397 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.700450900560987, + "scoreError" : 0.040650582191514045, + "scoreConfidence" : [ + 3.659800318369473, + 3.741101482752501 + ], + "scorePercentiles" : { + "0.0" : 3.6858584502579217, + "50.0" : 3.6987097385567482, + "90.0" : 3.7201648074349443, + "95.0" : 3.7201648074349443, + "99.0" : 3.7201648074349443, + "99.9" : 3.7201648074349443, + "99.99" : 3.7201648074349443, + "99.999" : 3.7201648074349443, + "99.9999" : 3.7201648074349443, + "100.0" : 3.7201648074349443 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7083377094143812, + 3.7201648074349443, + 3.7109526958456973 + ], + [ + 3.689081767699115, + 3.6858584502579217, + 3.6883099727138644 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.840180921798341, + "scoreError" : 0.044513227628576325, + "scoreConfidence" : [ + 2.7956676941697647, + 2.884694149426917 + ], + "scorePercentiles" : { + "0.0" : 2.801557466946779, + "50.0" : 2.8510196391106044, + "90.0" : 2.872490500861574, + "95.0" : 2.872490500861574, + "99.0" : 2.872490500861574, + "99.9" : 2.872490500861574, + "99.99" : 2.872490500861574, + "99.999" : 2.872490500861574, + "99.9999" : 2.872490500861574, + "100.0" : 2.872490500861574 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8067425004209934, + 2.801557466946779, + 2.8109157793704327 + ], + [ + 2.8510196391106044, + 2.8517295494724837, + 2.846561409220262 + ], + [ + 2.861186417620137, + 2.859425033161807, + 2.872490500861574 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17907202947603687, + "scoreError" : 0.00670484560821617, + "scoreConfidence" : [ + 0.1723671838678207, + 0.18577687508425303 + ], + "scorePercentiles" : { + "0.0" : 0.1755640429592177, + "50.0" : 0.1774438194722927, + "90.0" : 0.18523565140962472, + "95.0" : 0.18523565140962472, + "99.0" : 0.18523565140962472, + "99.9" : 0.18523565140962472, + "99.99" : 0.18523565140962472, + "99.999" : 0.18523565140962472, + "99.9999" : 0.18523565140962472, + "100.0" : 0.18523565140962472 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17574525320726864, + 0.1755640429592177, + 0.17574461892376367 + ], + [ + 0.18321511113553918, + 0.18432324685737458, + 0.18523565140962472 + ], + [ + 0.17765377328524987, + 0.1774438194722927, + 0.17672274803400073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33467355980546004, + "scoreError" : 0.015732504644345665, + "scoreConfidence" : [ + 0.3189410551611144, + 0.3504060644498057 + ], + "scorePercentiles" : { + "0.0" : 0.3225942608387097, + "50.0" : 0.33705844103272775, + "90.0" : 0.3445825397815375, + "95.0" : 0.3445825397815375, + "99.0" : 0.3445825397815375, + "99.9" : 0.3445825397815375, + "99.99" : 0.3445825397815375, + "99.999" : 0.3445825397815375, + "99.9999" : 0.3445825397815375, + "100.0" : 0.3445825397815375 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3225942608387097, + 0.3227770372151572, + 0.32293328559434237 + ], + [ + 0.3445825397815375, + 0.34353106176571624, + 0.3433423331731099 + ], + [ + 0.3383529962444174, + 0.33705844103272775, + 0.33689008260342274 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16641165219979803, + "scoreError" : 0.008301354539846898, + "scoreConfidence" : [ + 0.15811029765995113, + 0.17471300673964493 + ], + "scorePercentiles" : { + "0.0" : 0.1613107943638798, + "50.0" : 0.16515381480074648, + "90.0" : 0.17292260472756826, + "95.0" : 0.17292260472756826, + "99.0" : 0.17292260472756826, + "99.9" : 0.17292260472756826, + "99.99" : 0.17292260472756826, + "99.999" : 0.17292260472756826, + "99.9999" : 0.17292260472756826, + "100.0" : 0.17292260472756826 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17292260472756826, + 0.17262155191520948, + 0.17226494201650272 + ], + [ + 0.16135854223477208, + 0.1614882046669358, + 0.1613107943638798 + ], + [ + 0.16554833105434802, + 0.16515381480074648, + 0.16503608401821962 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38875197801253086, + "scoreError" : 0.010133028661687969, + "scoreConfidence" : [ + 0.3786189493508429, + 0.39888500667421883 + ], + "scorePercentiles" : { + "0.0" : 0.37941510911712256, + "50.0" : 0.3914092459882583, + "90.0" : 0.3958145895111815, + "95.0" : 0.3958145895111815, + "99.0" : 0.3958145895111815, + "99.9" : 0.3958145895111815, + "99.99" : 0.3958145895111815, + "99.999" : 0.3958145895111815, + "99.9999" : 0.3958145895111815, + "100.0" : 0.3958145895111815 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38415878153810695, + 0.37941510911712256, + 0.3798788741880342 + ], + [ + 0.3958145895111815, + 0.39277299945013944, + 0.3931043139274343 + ], + [ + 0.3917136562475519, + 0.3914092459882583, + 0.39050023214494906 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1567575782526978, + "scoreError" : 0.001756730125437472, + "scoreConfidence" : [ + 0.1550008481272603, + 0.15851430837813527 + ], + "scorePercentiles" : { + "0.0" : 0.1552836069099379, + "50.0" : 0.1568126810826068, + "90.0" : 0.15808412828214166, + "95.0" : 0.15808412828214166, + "99.0" : 0.15808412828214166, + "99.9" : 0.15808412828214166, + "99.99" : 0.15808412828214166, + "99.999" : 0.15808412828214166, + "99.9999" : 0.15808412828214166, + "100.0" : 0.15808412828214166 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1560860536296805, + 0.1552836069099379, + 0.15552143758261924 + ], + [ + 0.1580676237157399, + 0.15808412828214166, + 0.15766376098506946 + ], + [ + 0.1570153811744387, + 0.1568126810826068, + 0.156283530912046 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048592658466308974, + "scoreError" : 0.0017968188521679121, + "scoreConfidence" : [ + 0.04679583961414106, + 0.050389477318476886 + ], + "scorePercentiles" : { + "0.0" : 0.047535836964220354, + "50.0" : 0.048176836740199735, + "90.0" : 0.05068937412245353, + "95.0" : 0.05068937412245353, + "99.0" : 0.05068937412245353, + "99.9" : 0.05068937412245353, + "99.99" : 0.05068937412245353, + "99.999" : 0.05068937412245353, + "99.9999" : 0.05068937412245353, + "100.0" : 0.05068937412245353 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04894306757471051, + 0.048111777384870005, + 0.048176836740199735 + ], + [ + 0.047619933290158525, + 0.047535836964220354, + 0.047573736302526606 + ], + [ + 0.05068937412245353, + 0.049340145975389535, + 0.04934321784225199 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9118731.258717624, + "scoreError" : 64258.13778346629, + "scoreConfidence" : [ + 9054473.120934159, + 9182989.39650109 + ], + "scorePercentiles" : { + "0.0" : 9080304.523593467, + "50.0" : 9100486.565059144, + "90.0" : 9171500.41796517, + "95.0" : 9171500.41796517, + "99.0" : 9171500.41796517, + "99.9" : 9171500.41796517, + "99.99" : 9171500.41796517, + "99.999" : 9171500.41796517, + "99.9999" : 9171500.41796517, + "100.0" : 9171500.41796517 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9169333.384051329, + 9171500.41796517, + 9156587.633119853 + ], + [ + 9100486.565059144, + 9087986.72479564, + 9093709.6 + ], + [ + 9128045.636861313, + 9080304.523593467, + 9080626.843012704 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:23:52Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:23:52Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..43a8f0b979 --- /dev/null +++ b/performance-results/2025-03-24T00:23:52Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4139790279787423, + "scoreError" : 0.01733409931536483, + "scoreConfidence" : [ + 3.3966449286633775, + 3.431313127294107 + ], + "scorePercentiles" : { + "0.0" : 3.410359353387592, + "50.0" : 3.4147105177822104, + "90.0" : 3.4161357229629568, + "95.0" : 3.4161357229629568, + "99.0" : 3.4161357229629568, + "99.9" : 3.4161357229629568, + "99.99" : 3.4161357229629568, + "99.999" : 3.4161357229629568, + "99.9999" : 3.4161357229629568, + "100.0" : 3.4161357229629568 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.410359353387592, + 3.4161357229629568 + ], + [ + 3.4135350559911077, + 3.415885979573313 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7232104134744857, + "scoreError" : 0.007629890942061581, + "scoreConfidence" : [ + 1.715580522532424, + 1.7308403044165472 + ], + "scorePercentiles" : { + "0.0" : 1.7220037289307688, + "50.0" : 1.7232692487178383, + "90.0" : 1.724299427531498, + "95.0" : 1.724299427531498, + "99.0" : 1.724299427531498, + "99.9" : 1.724299427531498, + "99.99" : 1.724299427531498, + "99.999" : 1.724299427531498, + "99.9999" : 1.724299427531498, + "100.0" : 1.724299427531498 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7220037289307688, + 1.724144873194817 + ], + [ + 1.7223936242408595, + 1.724299427531498 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8662626240049967, + "scoreError" : 0.012849636408795155, + "scoreConfidence" : [ + 0.8534129875962015, + 0.8791122604137918 + ], + "scorePercentiles" : { + "0.0" : 0.8648472759593716, + "50.0" : 0.8655491554294797, + "90.0" : 0.8691049092016552, + "95.0" : 0.8691049092016552, + "99.0" : 0.8691049092016552, + "99.9" : 0.8691049092016552, + "99.99" : 0.8691049092016552, + "99.999" : 0.8691049092016552, + "99.9999" : 0.8691049092016552, + "100.0" : 0.8691049092016552 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8649317121070363, + 0.8648472759593716 + ], + [ + 0.8661665987519231, + 0.8691049092016552 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.747041994645217, + "scoreError" : 0.14758109112545448, + "scoreConfidence" : [ + 15.599460903519763, + 15.894623085770672 + ], + "scorePercentiles" : { + "0.0" : 15.609608788536184, + "50.0" : 15.753115594028856, + "90.0" : 15.892679137848754, + "95.0" : 15.892679137848754, + "99.0" : 15.892679137848754, + "99.9" : 15.892679137848754, + "99.99" : 15.892679137848754, + "99.999" : 15.892679137848754, + "99.9999" : 15.892679137848754, + "100.0" : 15.892679137848754 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.892679137848754, + 15.840820211442846, + 15.760137568493265 + ], + [ + 15.716608944186692, + 15.750055674111344, + 15.639867067639829 + ], + [ + 15.76048496551918, + 15.753115594028856, + 15.609608788536184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2545.4144779507083, + "scoreError" : 133.1445397106979, + "scoreConfidence" : [ + 2412.2699382400106, + 2678.559017661406 + ], + "scorePercentiles" : { + "0.0" : 2423.101821634822, + "50.0" : 2562.1716441581257, + "90.0" : 2649.288918606347, + "95.0" : 2649.288918606347, + "99.0" : 2649.288918606347, + "99.9" : 2649.288918606347, + "99.99" : 2649.288918606347, + "99.999" : 2649.288918606347, + "99.9999" : 2649.288918606347, + "100.0" : 2649.288918606347 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2637.4876233069353, + 2609.3290298838847, + 2649.288918606347 + ], + [ + 2564.6887466700787, + 2562.1716441581257, + 2515.2897354670463 + ], + [ + 2479.1384646149886, + 2468.2343172141473, + 2423.101821634822 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70197.89601850326, + "scoreError" : 653.3580011482312, + "scoreConfidence" : [ + 69544.53801735504, + 70851.25401965149 + ], + "scorePercentiles" : { + "0.0" : 69486.97210441956, + "50.0" : 70326.68061681147, + "90.0" : 70559.23822474394, + "95.0" : 70559.23822474394, + "99.0" : 70559.23822474394, + "99.9" : 70559.23822474394, + "99.99" : 70559.23822474394, + "99.999" : 70559.23822474394, + "99.9999" : 70559.23822474394, + "100.0" : 70559.23822474394 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70326.68061681147, + 70503.0313110003, + 70559.23822474394 + ], + [ + 70280.42396857131, + 70461.33770627339, + 70492.21472352139 + ], + [ + 69486.97210441956, + 69697.21793988864, + 69973.94757129939 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 344.5101901407003, + "scoreError" : 2.383199551240554, + "scoreConfidence" : [ + 342.1269905894597, + 346.89338969194085 + ], + "scorePercentiles" : { + "0.0" : 342.6941923456472, + "50.0" : 344.34952393825296, + "90.0" : 347.15351826154125, + "95.0" : 347.15351826154125, + "99.0" : 347.15351826154125, + "99.9" : 347.15351826154125, + "99.99" : 347.15351826154125, + "99.999" : 347.15351826154125, + "99.9999" : 347.15351826154125, + "100.0" : 347.15351826154125 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 344.34952393825296, + 342.75642153725806, + 347.15351826154125 + ], + [ + 344.46026237521187, + 345.8795032843992, + 342.6941923456472 + ], + [ + 344.2612697809226, + 343.90034476443435, + 345.13667497863463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.19980969284724, + "scoreError" : 4.314449187306226, + "scoreConfidence" : [ + 101.88536050554102, + 110.51425888015346 + ], + "scorePercentiles" : { + "0.0" : 102.98445685458186, + "50.0" : 106.25756148437183, + "90.0" : 109.45660740565823, + "95.0" : 109.45660740565823, + "99.0" : 109.45660740565823, + "99.9" : 109.45660740565823, + "99.99" : 109.45660740565823, + "99.999" : 109.45660740565823, + "99.9999" : 109.45660740565823, + "100.0" : 109.45660740565823 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.4167165580331, + 109.45660740565823, + 108.58405853540157 + ], + [ + 103.46395059370718, + 102.98445685458186, + 103.48652507131372 + ], + [ + 106.73553070412007, + 106.25756148437183, + 105.4128800284376 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06275639899463895, + "scoreError" : 9.54564950141199E-4, + "scoreConfidence" : [ + 0.061801834044497746, + 0.06371096394478014 + ], + "scorePercentiles" : { + "0.0" : 0.06206886380451109, + "50.0" : 0.06277109492125466, + "90.0" : 0.06384064171167375, + "95.0" : 0.06384064171167375, + "99.0" : 0.06384064171167375, + "99.9" : 0.06384064171167375, + "99.99" : 0.06384064171167375, + "99.999" : 0.06384064171167375, + "99.9999" : 0.06384064171167375, + "100.0" : 0.06384064171167375 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06277109492125466, + 0.06384064171167375, + 0.0628098215095501 + ], + [ + 0.06311703809060958, + 0.062423528202599284, + 0.062465097437723306 + ], + [ + 0.06319615820904954, + 0.06206886380451109, + 0.06211534706477921 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7162303018110915E-4, + "scoreError" : 1.3300625207700327E-5, + "scoreConfidence" : [ + 3.583224049734088E-4, + 3.849236553888095E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6245800606610196E-4, + "50.0" : 3.6733737068606417E-4, + "90.0" : 3.8197260089267476E-4, + "95.0" : 3.8197260089267476E-4, + "99.0" : 3.8197260089267476E-4, + "99.9" : 3.8197260089267476E-4, + "99.99" : 3.8197260089267476E-4, + "99.999" : 3.8197260089267476E-4, + "99.9999" : 3.8197260089267476E-4, + "100.0" : 3.8197260089267476E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7946744438874773E-4, + 3.8197260089267476E-4, + 3.801795977685541E-4 + ], + [ + 3.774281412412418E-4, + 3.6596905308952E-4, + 3.6733737068606417E-4 + ], + [ + 3.655366763432819E-4, + 3.64258381153796E-4, + 3.6245800606610196E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014576655465828222, + "scoreError" : 4.4815463271461934E-4, + "scoreConfidence" : [ + 0.014128500833113603, + 0.015024810098542842 + ], + "scorePercentiles" : { + "0.0" : 0.014191622172709856, + "50.0" : 0.014660958410302422, + "90.0" : 0.01486787987493291, + "95.0" : 0.01486787987493291, + "99.0" : 0.01486787987493291, + "99.9" : 0.01486787987493291, + "99.99" : 0.01486787987493291, + "99.999" : 0.01486787987493291, + "99.9999" : 0.01486787987493291, + "100.0" : 0.01486787987493291 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014191622172709856, + 0.014290993181850661, + 0.014229220261302128 + ], + [ + 0.014660958410302422, + 0.014729058729871167, + 0.014615897812608705 + ], + [ + 0.01486787987493291, + 0.014796878423028379, + 0.014807390325847788 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9886220481891734, + "scoreError" : 0.02202937493183751, + "scoreConfidence" : [ + 0.9665926732573359, + 1.0106514231210109 + ], + "scorePercentiles" : { + "0.0" : 0.9708414966508107, + "50.0" : 0.9914381361157926, + "90.0" : 1.0050596295477388, + "95.0" : 1.0050596295477388, + "99.0" : 1.0050596295477388, + "99.9" : 1.0050596295477388, + "99.99" : 1.0050596295477388, + "99.999" : 1.0050596295477388, + "99.9999" : 1.0050596295477388, + "100.0" : 1.0050596295477388 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9988275476428286, + 0.9798739526748971, + 1.0050596295477388 + ], + [ + 0.9914381361157926, + 0.9749231319945408, + 0.9770868427943332 + ], + [ + 0.9708414966508107, + 1.00367483410277, + 0.9958728621788488 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013247707048733286, + "scoreError" : 5.193704451363999E-4, + "scoreConfidence" : [ + 0.012728336603596886, + 0.013767077493869686 + ], + "scorePercentiles" : { + "0.0" : 0.013023179856227536, + "50.0" : 0.013218959993194505, + "90.0" : 0.013476428963390805, + "95.0" : 0.013476428963390805, + "99.0" : 0.013476428963390805, + "99.9" : 0.013476428963390805, + "99.99" : 0.013476428963390805, + "99.999" : 0.013476428963390805, + "99.9999" : 0.013476428963390805, + "100.0" : 0.013476428963390805 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013431655164077107, + 0.013476428963390805, + 0.013309052718435748 + ], + [ + 0.013023179856227536, + 0.013117058322315264, + 0.013128867267953263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8007924550689083, + "scoreError" : 0.1575107709395715, + "scoreConfidence" : [ + 3.6432816841293367, + 3.95830322600848 + ], + "scorePercentiles" : { + "0.0" : 3.7105204391691395, + "50.0" : 3.810032759650752, + "90.0" : 3.8690372513534417, + "95.0" : 3.8690372513534417, + "99.0" : 3.8690372513534417, + "99.9" : 3.8690372513534417, + "99.99" : 3.8690372513534417, + "99.999" : 3.8690372513534417, + "99.9999" : 3.8690372513534417, + "100.0" : 3.8690372513534417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7105204391691395, + 3.7916760227445034, + 3.7700243978899772 + ], + [ + 3.828389496557001, + 3.8351071226993865, + 3.8690372513534417 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9027731564072075, + "scoreError" : 0.07612377795801785, + "scoreConfidence" : [ + 2.8266493784491895, + 2.9788969343652254 + ], + "scorePercentiles" : { + "0.0" : 2.825844649901102, + "50.0" : 2.915686231778426, + "90.0" : 2.9708684835164836, + "95.0" : 2.9708684835164836, + "99.0" : 2.9708684835164836, + "99.9" : 2.9708684835164836, + "99.99" : 2.9708684835164836, + "99.999" : 2.9708684835164836, + "99.9999" : 2.9708684835164836, + "100.0" : 2.9708684835164836 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.915686231778426, + 2.8977852381918283, + 2.9708684835164836 + ], + [ + 2.851340196123147, + 2.876133754385965, + 2.825844649901102 + ], + [ + 2.9407795983534255, + 2.9272113388937666, + 2.9193089165207238 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17689930835873036, + "scoreError" : 0.002842059148974742, + "scoreConfidence" : [ + 0.17405724920975563, + 0.17974136750770509 + ], + "scorePercentiles" : { + "0.0" : 0.1749956751596815, + "50.0" : 0.17624560317236518, + "90.0" : 0.1805695294680582, + "95.0" : 0.1805695294680582, + "99.0" : 0.1805695294680582, + "99.9" : 0.1805695294680582, + "99.99" : 0.1805695294680582, + "99.999" : 0.1805695294680582, + "99.9999" : 0.1805695294680582, + "100.0" : 0.1805695294680582 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1756597641623777, + 0.17624560317236518, + 0.1749956751596815 + ], + [ + 0.1805695294680582, + 0.17602795509672423, + 0.1759503923462655 + ], + [ + 0.17831782509539604, + 0.17724520107761293, + 0.1770818296500921 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3354327846464433, + "scoreError" : 0.011347978196975963, + "scoreConfidence" : [ + 0.32408480644946736, + 0.3467807628434193 + ], + "scorePercentiles" : { + "0.0" : 0.3264376331320385, + "50.0" : 0.3361444103865546, + "90.0" : 0.3443870391555892, + "95.0" : 0.3443870391555892, + "99.0" : 0.3443870391555892, + "99.9" : 0.3443870391555892, + "99.99" : 0.3443870391555892, + "99.999" : 0.3443870391555892, + "99.9999" : 0.3443870391555892, + "100.0" : 0.3443870391555892 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3373253261148216, + 0.3342318498328877, + 0.3361444103865546 + ], + [ + 0.3443870391555892, + 0.34167287751546005, + 0.342488746600911 + ], + [ + 0.3264376331320385, + 0.32709297160893597, + 0.3291142074707915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16110332563434188, + "scoreError" : 0.0020874150798940866, + "scoreConfidence" : [ + 0.1590159105544478, + 0.16319074071423595 + ], + "scorePercentiles" : { + "0.0" : 0.15933203478163888, + "50.0" : 0.1610831870298481, + "90.0" : 0.16265270313262417, + "95.0" : 0.16265270313262417, + "99.0" : 0.16265270313262417, + "99.9" : 0.16265270313262417, + "99.99" : 0.16265270313262417, + "99.999" : 0.16265270313262417, + "99.9999" : 0.16265270313262417, + "100.0" : 0.16265270313262417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16261264577133844, + 0.15933203478163888, + 0.1594406899872449 + ], + [ + 0.1620065954120563, + 0.1610831870298481, + 0.16164427368829407 + ], + [ + 0.16265270313262417, + 0.16080782867801952, + 0.1603499722280125 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39241547184985115, + "scoreError" : 0.004628031957858871, + "scoreConfidence" : [ + 0.38778743989199227, + 0.39704350380771003 + ], + "scorePercentiles" : { + "0.0" : 0.38753200643286184, + "50.0" : 0.3934960783032974, + "90.0" : 0.3954240305654409, + "95.0" : 0.3954240305654409, + "99.0" : 0.3954240305654409, + "99.9" : 0.3954240305654409, + "99.99" : 0.3954240305654409, + "99.999" : 0.3954240305654409, + "99.9999" : 0.3954240305654409, + "100.0" : 0.3954240305654409 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39394333220405753, + 0.3947797881252221, + 0.3938365002756774 + ], + [ + 0.3954240305654409, + 0.3930255630011005, + 0.3934960783032974 + ], + [ + 0.39110447979975754, + 0.38859746794124506, + 0.38753200643286184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15713051585289387, + "scoreError" : 0.0032836281079149463, + "scoreConfidence" : [ + 0.15384688774497893, + 0.1604141439608088 + ], + "scorePercentiles" : { + "0.0" : 0.15493549551475716, + "50.0" : 0.15686275267838937, + "90.0" : 0.1600880574863528, + "95.0" : 0.1600880574863528, + "99.0" : 0.1600880574863528, + "99.9" : 0.1600880574863528, + "99.99" : 0.1600880574863528, + "99.999" : 0.1600880574863528, + "99.9999" : 0.1600880574863528, + "100.0" : 0.1600880574863528 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1577168077626723, + 0.15493549551475716, + 0.1556498461275059 + ], + [ + 0.1600880574863528, + 0.15967283248974118, + 0.15846983966405198 + ], + [ + 0.15555324712232454, + 0.1552257638302496, + 0.15686275267838937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04705066768023394, + "scoreError" : 0.001354979886918993, + "scoreConfidence" : [ + 0.04569568779331495, + 0.04840564756715294 + ], + "scorePercentiles" : { + "0.0" : 0.046198589189688624, + "50.0" : 0.04695832817738709, + "90.0" : 0.04813244350534022, + "95.0" : 0.04813244350534022, + "99.0" : 0.04813244350534022, + "99.9" : 0.04813244350534022, + "99.99" : 0.04813244350534022, + "99.999" : 0.04813244350534022, + "99.9999" : 0.04813244350534022, + "100.0" : 0.04813244350534022 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046199114461003984, + 0.046198589189688624, + 0.04623714843789734 + ], + [ + 0.04695832817738709, + 0.04697174483905363, + 0.04676409584646608 + ], + [ + 0.04811783464051659, + 0.047876710024751884, + 0.04813244350534022 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9532333.788803102, + "scoreError" : 184675.12319489112, + "scoreConfidence" : [ + 9347658.66560821, + 9717008.911997994 + ], + "scorePercentiles" : { + "0.0" : 9399325.62781955, + "50.0" : 9531696.442857143, + "90.0" : 9684418.71732817, + "95.0" : 9684418.71732817, + "99.0" : 9684418.71732817, + "99.9" : 9684418.71732817, + "99.99" : 9684418.71732817, + "99.999" : 9684418.71732817, + "99.9999" : 9684418.71732817, + "100.0" : 9684418.71732817 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9399325.62781955, + 9531696.442857143, + 9439758.283018868 + ], + [ + 9542497.550572518, + 9446944.228517469, + 9435623.42264151 + ], + [ + 9665474.026086956, + 9645265.800385728, + 9684418.71732817 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:24:07Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:24:07Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..31b6567efb --- /dev/null +++ b/performance-results/2025-03-24T00:24:07Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.418727796332958, + "scoreError" : 0.019260305937663362, + "scoreConfidence" : [ + 3.3994674903952946, + 3.437988102270621 + ], + "scorePercentiles" : { + "0.0" : 3.4152823316089855, + "50.0" : 3.418559195614442, + "90.0" : 3.4225104624939626, + "95.0" : 3.4225104624939626, + "99.0" : 3.4225104624939626, + "99.9" : 3.4225104624939626, + "99.99" : 3.4225104624939626, + "99.999" : 3.4225104624939626, + "99.9999" : 3.4225104624939626, + "100.0" : 3.4225104624939626 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4152823316089855, + 3.418103971728598 + ], + [ + 3.4190144195002863, + 3.4225104624939626 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7267000534572148, + "scoreError" : 0.009745745154939877, + "scoreConfidence" : [ + 1.716954308302275, + 1.7364457986121546 + ], + "scorePercentiles" : { + "0.0" : 1.725070583670842, + "50.0" : 1.7265046397066905, + "90.0" : 1.7287203507446358, + "95.0" : 1.7287203507446358, + "99.0" : 1.7287203507446358, + "99.9" : 1.7287203507446358, + "99.99" : 1.7287203507446358, + "99.999" : 1.7287203507446358, + "99.9999" : 1.7287203507446358, + "100.0" : 1.7287203507446358 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7287203507446358, + 1.7265772264402828 + ], + [ + 1.725070583670842, + 1.7264320529730983 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8679407914173365, + "scoreError" : 0.006622606573662276, + "scoreConfidence" : [ + 0.8613181848436742, + 0.8745633979909988 + ], + "scorePercentiles" : { + "0.0" : 0.8669313223112551, + "50.0" : 0.8677987709768098, + "90.0" : 0.8692343014044714, + "95.0" : 0.8692343014044714, + "99.0" : 0.8692343014044714, + "99.9" : 0.8692343014044714, + "99.99" : 0.8692343014044714, + "99.999" : 0.8692343014044714, + "99.9999" : 0.8692343014044714, + "100.0" : 0.8692343014044714 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8669313223112551, + 0.8692343014044714 + ], + [ + 0.8673413586729263, + 0.8682561832806932 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.235936579563116, + "scoreError" : 0.10012301905339593, + "scoreConfidence" : [ + 16.13581356050972, + 16.33605959861651 + ], + "scorePercentiles" : { + "0.0" : 16.137368925786877, + "50.0" : 16.23306955047474, + "90.0" : 16.320767303396018, + "95.0" : 16.320767303396018, + "99.0" : 16.320767303396018, + "99.9" : 16.320767303396018, + "99.99" : 16.320767303396018, + "99.999" : 16.320767303396018, + "99.9999" : 16.320767303396018, + "100.0" : 16.320767303396018 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.137368925786877, + 16.156522429329012, + 16.224274005597668 + ], + [ + 16.23306955047474, + 16.270260500138413, + 16.229219191891904 + ], + [ + 16.29340742332964, + 16.258539886123778, + 16.320767303396018 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2693.999980775219, + "scoreError" : 143.563391004748, + "scoreConfidence" : [ + 2550.4365897704706, + 2837.563371779967 + ], + "scorePercentiles" : { + "0.0" : 2587.0134717566575, + "50.0" : 2705.156115027511, + "90.0" : 2786.233952324298, + "95.0" : 2786.233952324298, + "99.0" : 2786.233952324298, + "99.9" : 2786.233952324298, + "99.99" : 2786.233952324298, + "99.999" : 2786.233952324298, + "99.9999" : 2786.233952324298, + "100.0" : 2786.233952324298 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2785.8671292365375, + 2786.233952324298, + 2785.9989424675027 + ], + [ + 2705.156115027511, + 2701.0886255987457, + 2711.748006185997 + ], + [ + 2589.3528046902547, + 2593.5407796894633, + 2587.0134717566575 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70073.68564851678, + "scoreError" : 1632.0955447784556, + "scoreConfidence" : [ + 68441.59010373833, + 71705.78119329523 + ], + "scorePercentiles" : { + "0.0" : 68765.72725889308, + "50.0" : 70559.97147775891, + "90.0" : 70873.8723885834, + "95.0" : 70873.8723885834, + "99.0" : 70873.8723885834, + "99.9" : 70873.8723885834, + "99.99" : 70873.8723885834, + "99.999" : 70873.8723885834, + "99.9999" : 70873.8723885834, + "100.0" : 70873.8723885834 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70652.15947951954, + 70559.97147775891, + 70557.58478472116 + ], + [ + 70873.8723885834, + 70794.07496145777, + 70861.8622002032 + ], + [ + 68800.60238606091, + 68765.72725889308, + 68797.31589945283 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 346.4769662363869, + "scoreError" : 5.749983693062291, + "scoreConfidence" : [ + 340.7269825433246, + 352.2269499294492 + ], + "scorePercentiles" : { + "0.0" : 342.6456839432396, + "50.0" : 345.21547181686816, + "90.0" : 350.95338261651966, + "95.0" : 350.95338261651966, + "99.0" : 350.95338261651966, + "99.9" : 350.95338261651966, + "99.99" : 350.95338261651966, + "99.999" : 350.95338261651966, + "99.9999" : 350.95338261651966, + "100.0" : 350.95338261651966 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 350.81948717326736, + 350.8788328484417, + 350.95338261651966 + ], + [ + 343.53993221462224, + 342.6456839432396, + 345.7400937176836 + ], + [ + 345.21547181686816, + 344.3811516063152, + 344.1186601905246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.48660478045684, + "scoreError" : 3.6159200713995125, + "scoreConfidence" : [ + 104.87068470905733, + 112.10252485185636 + ], + "scorePercentiles" : { + "0.0" : 106.35313512940456, + "50.0" : 107.62571485891694, + "90.0" : 111.58741620896292, + "95.0" : 111.58741620896292, + "99.0" : 111.58741620896292, + "99.9" : 111.58741620896292, + "99.99" : 111.58741620896292, + "99.999" : 111.58741620896292, + "99.9999" : 111.58741620896292, + "100.0" : 111.58741620896292 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.993872610707, + 107.63913033013222, + 107.62571485891694 + ], + [ + 106.35313512940456, + 107.01793018601509, + 106.84737908686986 + ], + [ + 110.96237137270401, + 111.35249324039887, + 111.58741620896292 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0622361102645904, + "scoreError" : 0.0014092667087201524, + "scoreConfidence" : [ + 0.06082684355587025, + 0.06364537697331056 + ], + "scorePercentiles" : { + "0.0" : 0.06113559449297867, + "50.0" : 0.06233768628404366, + "90.0" : 0.06329307029247391, + "95.0" : 0.06329307029247391, + "99.0" : 0.06329307029247391, + "99.9" : 0.06329307029247391, + "99.99" : 0.06329307029247391, + "99.999" : 0.06329307029247391, + "99.9999" : 0.06329307029247391, + "100.0" : 0.06329307029247391 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06113559449297867, + 0.06127452007328341, + 0.061268865124343666 + ], + [ + 0.06329307029247391, + 0.06295227893083542, + 0.06318084146249005 + ], + [ + 0.06233768628404366, + 0.062332511154188974, + 0.06234962456667581 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.665468543083284E-4, + "scoreError" : 1.005729578916367E-5, + "scoreConfidence" : [ + 3.564895585191647E-4, + 3.7660415009749205E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5904002448909427E-4, + "50.0" : 3.674106865832467E-4, + "90.0" : 3.7315715283631613E-4, + "95.0" : 3.7315715283631613E-4, + "99.0" : 3.7315715283631613E-4, + "99.9" : 3.7315715283631613E-4, + "99.99" : 3.7315715283631613E-4, + "99.999" : 3.7315715283631613E-4, + "99.9999" : 3.7315715283631613E-4, + "100.0" : 3.7315715283631613E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5904002448909427E-4, + 3.593027288419463E-4, + 3.59669568734919E-4 + ], + [ + 3.6629329073931805E-4, + 3.68010703875466E-4, + 3.674106865832467E-4 + ], + [ + 3.7315715283631613E-4, + 3.7295545675339195E-4, + 3.7308207592125686E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014168876622290247, + "scoreError" : 2.180404606342525E-4, + "scoreConfidence" : [ + 0.013950836161655995, + 0.0143869170829245 + ], + "scorePercentiles" : { + "0.0" : 0.014005904332395416, + "50.0" : 0.014214103812740216, + "90.0" : 0.014365163314117767, + "95.0" : 0.014365163314117767, + "99.0" : 0.014365163314117767, + "99.9" : 0.014365163314117767, + "99.99" : 0.014365163314117767, + "99.999" : 0.014365163314117767, + "99.9999" : 0.014365163314117767, + "100.0" : 0.014365163314117767 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014248717006779458, + 0.014241400673894561, + 0.014247215099016953 + ], + [ + 0.014015916791290052, + 0.01400655825116253, + 0.014005904332395416 + ], + [ + 0.014365163314117767, + 0.014214103812740216, + 0.014174910319215287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9883874619998374, + "scoreError" : 0.012262246983570126, + "scoreConfidence" : [ + 0.9761252150162673, + 1.0006497089834074 + ], + "scorePercentiles" : { + "0.0" : 0.9782718871172845, + "50.0" : 0.9889908523536393, + "90.0" : 1.0001254258425842, + "95.0" : 1.0001254258425842, + "99.0" : 1.0001254258425842, + "99.9" : 1.0001254258425842, + "99.99" : 1.0001254258425842, + "99.999" : 1.0001254258425842, + "99.9999" : 1.0001254258425842, + "100.0" : 1.0001254258425842 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9902935940192098, + 0.9942343288597276, + 1.0001254258425842 + ], + [ + 0.9818900094256259, + 0.9782718871172845, + 0.9801009946099569 + ], + [ + 0.9872359937808489, + 0.9889908523536393, + 0.9943440719896589 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013229909001656678, + "scoreError" : 9.406588269167901E-4, + "scoreConfidence" : [ + 0.012289250174739887, + 0.014170567828573469 + ], + "scorePercentiles" : { + "0.0" : 0.012873240898839377, + "50.0" : 0.013235218525888437, + "90.0" : 0.013595976207632591, + "95.0" : 0.013595976207632591, + "99.0" : 0.013595976207632591, + "99.9" : 0.013595976207632591, + "99.99" : 0.013595976207632591, + "99.999" : 0.013595976207632591, + "99.9999" : 0.013595976207632591, + "100.0" : 0.013595976207632591 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012873240898839377, + 0.012927177535904031, + 0.012980483442625505 + ], + [ + 0.013489953609151367, + 0.013512622315787199, + 0.013595976207632591 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8953529355881122, + "scoreError" : 0.16813129815441916, + "scoreConfidence" : [ + 3.727221637433693, + 4.063484233742531 + ], + "scorePercentiles" : { + "0.0" : 3.8246030955657493, + "50.0" : 3.8941909112009157, + "90.0" : 3.9681537279936556, + "95.0" : 3.9681537279936556, + "99.0" : 3.9681537279936556, + "99.9" : 3.9681537279936556, + "99.99" : 3.9681537279936556, + "99.999" : 3.9681537279936556, + "99.9999" : 3.9681537279936556, + "100.0" : 3.9681537279936556 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8246030955657493, + 3.8482302953846155, + 3.8541955454545453 + ], + [ + 3.9681537279936556, + 3.9341862769472855, + 3.9427486721828213 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.860606839688258, + "scoreError" : 0.04294079178434248, + "scoreConfidence" : [ + 2.8176660479039155, + 2.9035476314726 + ], + "scorePercentiles" : { + "0.0" : 2.832584204474653, + "50.0" : 2.848960992309883, + "90.0" : 2.8993197460869564, + "95.0" : 2.8993197460869564, + "99.0" : 2.8993197460869564, + "99.9" : 2.8993197460869564, + "99.99" : 2.8993197460869564, + "99.999" : 2.8993197460869564, + "99.9999" : 2.8993197460869564, + "100.0" : 2.8993197460869564 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.841267359375, + 2.853678905278174, + 2.846926069740962 + ], + [ + 2.841372784375, + 2.832584204474653, + 2.848960992309883 + ], + [ + 2.8877761952064684, + 2.8935753003472224, + 2.8993197460869564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17612873481401406, + "scoreError" : 0.002273465359969216, + "scoreConfidence" : [ + 0.17385526945404484, + 0.17840220017398328 + ], + "scorePercentiles" : { + "0.0" : 0.17405524113203608, + "50.0" : 0.17676613815777845, + "90.0" : 0.17724810159697973, + "95.0" : 0.17724810159697973, + "99.0" : 0.17724810159697973, + "99.9" : 0.17724810159697973, + "99.99" : 0.17724810159697973, + "99.999" : 0.17724810159697973, + "99.9999" : 0.17724810159697973, + "100.0" : 0.17724810159697973 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17460966817991339, + 0.17438350551041049, + 0.17405524113203608 + ], + [ + 0.17709970664281793, + 0.17698738675822523, + 0.1767625913493831 + ], + [ + 0.17724810159697973, + 0.17724627399858206, + 0.17676613815777845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3286495142725523, + "scoreError" : 0.00669510717019289, + "scoreConfidence" : [ + 0.3219544071023594, + 0.3353446214427452 + ], + "scorePercentiles" : { + "0.0" : 0.3232384157993406, + "50.0" : 0.3294961234596376, + "90.0" : 0.3335745540545048, + "95.0" : 0.3335745540545048, + "99.0" : 0.3335745540545048, + "99.9" : 0.3335745540545048, + "99.99" : 0.3335745540545048, + "99.999" : 0.3335745540545048, + "99.9999" : 0.3335745540545048, + "100.0" : 0.3335745540545048 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3335745540545048, + 0.33236815833554906, + 0.33235919395792485 + ], + [ + 0.3243569388278032, + 0.3236054946445329, + 0.3232384157993406 + ], + [ + 0.32962189515145524, + 0.3294961234596376, + 0.3292248542222222 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1617962695319054, + "scoreError" : 0.009564736250000632, + "scoreConfidence" : [ + 0.15223153328190478, + 0.17136100578190602 + ], + "scorePercentiles" : { + "0.0" : 0.15489851643432465, + "50.0" : 0.16205769522590263, + "90.0" : 0.16841606593351072, + "95.0" : 0.16841606593351072, + "99.0" : 0.16841606593351072, + "99.9" : 0.16841606593351072, + "99.99" : 0.16841606593351072, + "99.999" : 0.16841606593351072, + "99.9999" : 0.16841606593351072, + "100.0" : 0.16841606593351072 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16201351245038478, + 0.16205769522590263, + 0.16216430718212335 + ], + [ + 0.1681184438747205, + 0.16812965105331293, + 0.16841606593351072 + ], + [ + 0.1551939337802815, + 0.1551742998525875, + 0.15489851643432465 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3925601761045857, + "scoreError" : 0.002854200782560512, + "scoreConfidence" : [ + 0.3897059753220252, + 0.3954143768871462 + ], + "scorePercentiles" : { + "0.0" : 0.3902284047684083, + "50.0" : 0.3928132682457381, + "90.0" : 0.39562102373605507, + "95.0" : 0.39562102373605507, + "99.0" : 0.39562102373605507, + "99.9" : 0.39562102373605507, + "99.99" : 0.39562102373605507, + "99.999" : 0.39562102373605507, + "99.9999" : 0.39562102373605507, + "100.0" : 0.39562102373605507 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3928132682457381, + 0.3921554295517823, + 0.3917012223179664 + ], + [ + 0.39295643506621086, + 0.3903483630118272, + 0.3902284047684083 + ], + [ + 0.39562102373605507, + 0.39343656243606895, + 0.3937808758072137 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1590055963300603, + "scoreError" : 0.0038154826825017377, + "scoreConfidence" : [ + 0.15519011364755858, + 0.16282107901256204 + ], + "scorePercentiles" : { + "0.0" : 0.15701236564035734, + "50.0" : 0.15821260119923425, + "90.0" : 0.16385100081922893, + "95.0" : 0.16385100081922893, + "99.0" : 0.16385100081922893, + "99.9" : 0.16385100081922893, + "99.99" : 0.16385100081922893, + "99.999" : 0.16385100081922893, + "99.9999" : 0.16385100081922893, + "100.0" : 0.16385100081922893 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16385100081922893, + 0.16060318779108984, + 0.16053085958744684 + ], + [ + 0.1570874410706712, + 0.15701236564035734, + 0.1571129542340927 + ], + [ + 0.15852308593304165, + 0.15811687069537994, + 0.15821260119923425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04709400613370748, + "scoreError" : 8.959832103309933E-4, + "scoreConfidence" : [ + 0.04619802292337649, + 0.047989989344038475 + ], + "scorePercentiles" : { + "0.0" : 0.046410384114873394, + "50.0" : 0.04702598648019525, + "90.0" : 0.0478789975917228, + "95.0" : 0.0478789975917228, + "99.0" : 0.0478789975917228, + "99.9" : 0.0478789975917228, + "99.99" : 0.0478789975917228, + "99.999" : 0.0478789975917228, + "99.9999" : 0.0478789975917228, + "100.0" : 0.0478789975917228 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04702598648019525, + 0.046662754487720885, + 0.046708876802354096 + ], + [ + 0.047046067618236646, + 0.04673500164037855, + 0.046410384114873394 + ], + [ + 0.0477683986367067, + 0.04760958783117903, + 0.0478789975917228 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9327352.777649432, + "scoreError" : 192657.07108017706, + "scoreConfidence" : [ + 9134695.706569256, + 9520009.848729609 + ], + "scorePercentiles" : { + "0.0" : 9175624.649541285, + "50.0" : 9338098.31372549, + "90.0" : 9463799.421948912, + "95.0" : 9463799.421948912, + "99.0" : 9463799.421948912, + "99.9" : 9463799.421948912, + "99.99" : 9463799.421948912, + "99.999" : 9463799.421948912, + "99.9999" : 9463799.421948912, + "100.0" : 9463799.421948912 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9368004.88857678, + 9338098.31372549, + 9322472.486486487 + ], + [ + 9198349.157169119, + 9175624.649541285, + 9193192.830882354 + ], + [ + 9433707.31856739, + 9463799.421948912, + 9452925.93194707 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:24:36Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:24:36Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..fbe88ad5af --- /dev/null +++ b/performance-results/2025-03-24T00:24:36Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.420038635731748, + "scoreError" : 0.03572612124681014, + "scoreConfidence" : [ + 3.3843125144849378, + 3.4557647569785583 + ], + "scorePercentiles" : { + "0.0" : 3.412757503952283, + "50.0" : 3.4206086449711632, + "90.0" : 3.4261797490323804, + "95.0" : 3.4261797490323804, + "99.0" : 3.4261797490323804, + "99.9" : 3.4261797490323804, + "99.99" : 3.4261797490323804, + "99.999" : 3.4261797490323804, + "99.9999" : 3.4261797490323804, + "100.0" : 3.4261797490323804 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.420208542034723, + 3.4261797490323804 + ], + [ + 3.412757503952283, + 3.421008747907604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7269594749383836, + "scoreError" : 0.009130618232612993, + "scoreConfidence" : [ + 1.7178288567057707, + 1.7360900931709966 + ], + "scorePercentiles" : { + "0.0" : 1.7252408089036402, + "50.0" : 1.7270218836065996, + "90.0" : 1.7285533236366952, + "95.0" : 1.7285533236366952, + "99.0" : 1.7285533236366952, + "99.9" : 1.7285533236366952, + "99.99" : 1.7285533236366952, + "99.999" : 1.7285533236366952, + "99.9999" : 1.7285533236366952, + "100.0" : 1.7285533236366952 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7265281609307856, + 1.7275156062824133 + ], + [ + 1.7252408089036402, + 1.7285533236366952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8683627355847058, + "scoreError" : 0.004424765135251617, + "scoreConfidence" : [ + 0.8639379704494542, + 0.8727875007199574 + ], + "scorePercentiles" : { + "0.0" : 0.8676182677477435, + "50.0" : 0.8683318351838458, + "90.0" : 0.8691690042233875, + "95.0" : 0.8691690042233875, + "99.0" : 0.8691690042233875, + "99.9" : 0.8691690042233875, + "99.99" : 0.8691690042233875, + "99.999" : 0.8691690042233875, + "99.9999" : 0.8691690042233875, + "100.0" : 0.8691690042233875 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8680153036900241, + 0.8691690042233875 + ], + [ + 0.8676182677477435, + 0.8686483666776675 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.055543045735995, + "scoreError" : 0.2069643928273129, + "scoreConfidence" : [ + 15.848578652908682, + 16.262507438563308 + ], + "scorePercentiles" : { + "0.0" : 15.853454930952296, + "50.0" : 16.095843976286545, + "90.0" : 16.17934655862583, + "95.0" : 16.17934655862583, + "99.0" : 16.17934655862583, + "99.9" : 16.17934655862583, + "99.99" : 16.17934655862583, + "99.999" : 16.17934655862583, + "99.9999" : 16.17934655862583, + "100.0" : 16.17934655862583 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.853454930952296, + 15.919691762471901, + 15.92626644855112 + ], + [ + 16.101053864799674, + 16.16745467342604, + 16.088498782754574 + ], + [ + 16.17934655862583, + 16.095843976286545, + 16.168276413755958 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2633.4585624258307, + "scoreError" : 107.03761392892255, + "scoreConfidence" : [ + 2526.4209484969083, + 2740.496176354753 + ], + "scorePercentiles" : { + "0.0" : 2549.5553016703866, + "50.0" : 2651.5276426160167, + "90.0" : 2695.661966615178, + "95.0" : 2695.661966615178, + "99.0" : 2695.661966615178, + "99.9" : 2695.661966615178, + "99.99" : 2695.661966615178, + "99.999" : 2695.661966615178, + "99.9999" : 2695.661966615178, + "100.0" : 2695.661966615178 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2552.6745350860156, + 2552.7855568633254, + 2549.5553016703866 + ], + [ + 2665.1315269714228, + 2651.5276426160167, + 2649.0604733029927 + ], + [ + 2691.478381856197, + 2693.251676850942, + 2695.661966615178 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69931.37941176901, + "scoreError" : 1465.4758812930647, + "scoreConfidence" : [ + 68465.90353047595, + 71396.85529306208 + ], + "scorePercentiles" : { + "0.0" : 68845.18560964587, + "50.0" : 70023.56910032906, + "90.0" : 70921.12070454148, + "95.0" : 70921.12070454148, + "99.0" : 70921.12070454148, + "99.9" : 70921.12070454148, + "99.99" : 70921.12070454148, + "99.999" : 70921.12070454148, + "99.9999" : 70921.12070454148, + "100.0" : 70921.12070454148 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68875.69735017336, + 68845.18560964587, + 68901.2495725469 + ], + [ + 70094.01325465711, + 70012.04067921391, + 70023.56910032906 + ], + [ + 70889.52196622957, + 70921.12070454148, + 70820.0164685838 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.19467879376697, + "scoreError" : 7.823959503486677, + "scoreConfidence" : [ + 341.3707192902803, + 357.01863829725363 + ], + "scorePercentiles" : { + "0.0" : 342.85429652799536, + "50.0" : 351.3516869295316, + "90.0" : 353.85345733628844, + "95.0" : 353.85345733628844, + "99.0" : 353.85345733628844, + "99.9" : 353.85345733628844, + "99.99" : 353.85345733628844, + "99.999" : 353.85345733628844, + "99.9999" : 353.85345733628844, + "100.0" : 353.85345733628844 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.3459819255283, + 351.6033818518908, + 351.3516869295316 + ], + [ + 342.85429652799536, + 343.0360144184278, + 343.3701754846237 + ], + [ + 352.1977931513615, + 353.85345733628844, + 353.13932151825475 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.23185794008825, + "scoreError" : 2.631478358621384, + "scoreConfidence" : [ + 104.60037958146687, + 109.86333629870963 + ], + "scorePercentiles" : { + "0.0" : 105.6072203712119, + "50.0" : 107.10883582462246, + "90.0" : 109.34753566473427, + "95.0" : 109.34753566473427, + "99.0" : 109.34753566473427, + "99.9" : 109.34753566473427, + "99.99" : 109.34753566473427, + "99.999" : 109.34753566473427, + "99.9999" : 109.34753566473427, + "100.0" : 109.34753566473427 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.90448525309176, + 107.10883582462246, + 107.37865546414842 + ], + [ + 108.80366786552064, + 109.29181493925394, + 109.34753566473427 + ], + [ + 105.6072203712119, + 105.91024847813217, + 105.73425760007858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06181778714684108, + "scoreError" : 8.67739054633523E-4, + "scoreConfidence" : [ + 0.060950048092207554, + 0.0626855262014746 + ], + "scorePercentiles" : { + "0.0" : 0.061366941830923685, + "50.0" : 0.06172266934334052, + "90.0" : 0.06312104011285884, + "95.0" : 0.06312104011285884, + "99.0" : 0.06312104011285884, + "99.9" : 0.06312104011285884, + "99.99" : 0.06312104011285884, + "99.999" : 0.06312104011285884, + "99.9999" : 0.06312104011285884, + "100.0" : 0.06312104011285884 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06195911648151475, + 0.06172355798537173, + 0.06173098702437097 + ], + [ + 0.06153243771151503, + 0.06167637224233528, + 0.06172266934334052 + ], + [ + 0.06312104011285884, + 0.06152696158933878, + 0.061366941830923685 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6857029118731886E-4, + "scoreError" : 1.5216564218543925E-5, + "scoreConfidence" : [ + 3.5335372696877494E-4, + 3.837868554058628E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5672240780497004E-4, + "50.0" : 3.6874689627437875E-4, + "90.0" : 3.791402232827823E-4, + "95.0" : 3.791402232827823E-4, + "99.0" : 3.791402232827823E-4, + "99.9" : 3.791402232827823E-4, + "99.99" : 3.791402232827823E-4, + "99.999" : 3.791402232827823E-4, + "99.9999" : 3.791402232827823E-4, + "100.0" : 3.791402232827823E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.686687545112998E-4, + 3.6874689627437875E-4, + 3.6928144258397934E-4 + ], + [ + 3.5672240780497004E-4, + 3.591926452381613E-4, + 3.580368797876607E-4 + ], + [ + 3.782523123139139E-4, + 3.790910588887234E-4, + 3.791402232827823E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014149934787332199, + "scoreError" : 1.5484970065954965E-4, + "scoreConfidence" : [ + 0.013995085086672649, + 0.014304784487991749 + ], + "scorePercentiles" : { + "0.0" : 0.014058790354938164, + "50.0" : 0.014136459809273935, + "90.0" : 0.014363401301596329, + "95.0" : 0.014363401301596329, + "99.0" : 0.014363401301596329, + "99.9" : 0.014363401301596329, + "99.99" : 0.014363401301596329, + "99.999" : 0.014363401301596329, + "99.9999" : 0.014363401301596329, + "100.0" : 0.014363401301596329 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014151441471108086, + 0.014164649357216513, + 0.014363401301596329 + ], + [ + 0.014128270719925855, + 0.014136459809273935, + 0.014193550559501302 + ], + [ + 0.014060995313528198, + 0.014091854198901412, + 0.014058790354938164 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9848796345153955, + "scoreError" : 0.026365331267761083, + "scoreConfidence" : [ + 0.9585143032476344, + 1.0112449657831566 + ], + "scorePercentiles" : { + "0.0" : 0.9705371368400622, + "50.0" : 0.977281722759699, + "90.0" : 1.0084672936371886, + "95.0" : 1.0084672936371886, + "99.0" : 1.0084672936371886, + "99.9" : 1.0084672936371886, + "99.99" : 1.0084672936371886, + "99.999" : 1.0084672936371886, + "99.9999" : 1.0084672936371886, + "100.0" : 1.0084672936371886 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9727504306001362, + 0.972441956437184, + 0.9705371368400622 + ], + [ + 0.9843706345112708, + 0.971754894859586, + 0.977281722759699 + ], + [ + 1.0012740556668, + 1.0050385853266333, + 1.0084672936371886 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01303848291506131, + "scoreError" : 7.648798660533651E-4, + "scoreConfidence" : [ + 0.012273603049007945, + 0.013803362781114676 + ], + "scorePercentiles" : { + "0.0" : 0.012721311135196195, + "50.0" : 0.01305365903752266, + "90.0" : 0.013294264663889117, + "95.0" : 0.013294264663889117, + "99.0" : 0.013294264663889117, + "99.9" : 0.013294264663889117, + "99.99" : 0.013294264663889117, + "99.999" : 0.013294264663889117, + "99.9999" : 0.013294264663889117, + "100.0" : 0.013294264663889117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012721311135196195, + 0.012828935289786096, + 0.012825929841347202 + ], + [ + 0.013278382785259227, + 0.013294264663889117, + 0.013282073774890027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6859162919508712, + "scoreError" : 0.08130077546456034, + "scoreConfidence" : [ + 3.604615516486311, + 3.7672170674154315 + ], + "scorePercentiles" : { + "0.0" : 3.6448528950437318, + "50.0" : 3.680905968346083, + "90.0" : 3.722713207589286, + "95.0" : 3.722713207589286, + "99.0" : 3.722713207589286, + "99.9" : 3.722713207589286, + "99.99" : 3.722713207589286, + "99.999" : 3.722713207589286, + "99.9999" : 3.722713207589286, + "100.0" : 3.722713207589286 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6448528950437318, + 3.6821769646539027, + 3.6796349720382633 + ], + [ + 3.670619360968452, + 3.71550035141159, + 3.722713207589286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9123843056312286, + "scoreError" : 0.040828029372389635, + "scoreConfidence" : [ + 2.871556276258839, + 2.9532123350036183 + ], + "scorePercentiles" : { + "0.0" : 2.883016596137215, + "50.0" : 2.9039433644018584, + "90.0" : 2.9513215104750663, + "95.0" : 2.9513215104750663, + "99.0" : 2.9513215104750663, + "99.9" : 2.9513215104750663, + "99.99" : 2.9513215104750663, + "99.999" : 2.9513215104750663, + "99.9999" : 2.9513215104750663, + "100.0" : 2.9513215104750663 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9101809997090484, + 2.9016431763852624, + 2.883016596137215 + ], + [ + 2.949388729283397, + 2.9513215104750663, + 2.923200353405437 + ], + [ + 2.891391844174617, + 2.9039433644018584, + 2.8973721767091543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17631540626328382, + "scoreError" : 0.005322650101665493, + "scoreConfidence" : [ + 0.17099275616161833, + 0.1816380563649493 + ], + "scorePercentiles" : { + "0.0" : 0.17230167962921483, + "50.0" : 0.17607343552362842, + "90.0" : 0.18029872303254305, + "95.0" : 0.18029872303254305, + "99.0" : 0.18029872303254305, + "99.9" : 0.18029872303254305, + "99.99" : 0.18029872303254305, + "99.999" : 0.18029872303254305, + "99.9999" : 0.18029872303254305, + "100.0" : 0.18029872303254305 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17323904012126462, + 0.17264319178578827, + 0.17230167962921483 + ], + [ + 0.18029872303254305, + 0.1797842819646196, + 0.17992781205131433 + ], + [ + 0.17659479259376987, + 0.17607343552362842, + 0.1759756996674116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3374518829803303, + "scoreError" : 0.009005641323680674, + "scoreConfidence" : [ + 0.3284462416566496, + 0.346457524304011 + ], + "scorePercentiles" : { + "0.0" : 0.33093121890201527, + "50.0" : 0.3372985680652995, + "90.0" : 0.34342195291895605, + "95.0" : 0.34342195291895605, + "99.0" : 0.34342195291895605, + "99.9" : 0.34342195291895605, + "99.99" : 0.34342195291895605, + "99.999" : 0.34342195291895605, + "99.9999" : 0.34342195291895605, + "100.0" : 0.34342195291895605 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3393818560374669, + 0.3372985680652995, + 0.33715946481912273 + ], + [ + 0.3309354022767887, + 0.331359524055666, + 0.33093121890201527 + ], + [ + 0.34341128602335164, + 0.34316767372430595, + 0.34342195291895605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16313051381345262, + "scoreError" : 0.010396355099357468, + "scoreConfidence" : [ + 0.15273415871409515, + 0.17352686891281008 + ], + "scorePercentiles" : { + "0.0" : 0.15699070771911647, + "50.0" : 0.1611923607730621, + "90.0" : 0.1712437169081133, + "95.0" : 0.1712437169081133, + "99.0" : 0.1712437169081133, + "99.9" : 0.1712437169081133, + "99.99" : 0.1712437169081133, + "99.999" : 0.1712437169081133, + "99.9999" : 0.1712437169081133, + "100.0" : 0.1712437169081133 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15752309528385106, + 0.15699070771911647, + 0.15700094895988695 + ], + [ + 0.1712437169081133, + 0.17107739566154584, + 0.17081330198992228 + ], + [ + 0.16126023378968926, + 0.1610728632358863, + 0.1611923607730621 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38568584578686127, + "scoreError" : 0.008013563016641172, + "scoreConfidence" : [ + 0.3776722827702201, + 0.39369940880350246 + ], + "scorePercentiles" : { + "0.0" : 0.38021937287555607, + "50.0" : 0.3842808693463475, + "90.0" : 0.39188927098518694, + "95.0" : 0.39188927098518694, + "99.0" : 0.39188927098518694, + "99.9" : 0.39188927098518694, + "99.99" : 0.39188927098518694, + "99.999" : 0.39188927098518694, + "99.9999" : 0.39188927098518694, + "100.0" : 0.39188927098518694 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3802239573020037, + 0.38021937287555607, + 0.38083733512319584 + ], + [ + 0.3888499179951785, + 0.39188927098518694, + 0.38913277193665124 + ], + [ + 0.3915314130060293, + 0.3842808693463475, + 0.3842077035116029 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15686664020284957, + "scoreError" : 0.004103900306174808, + "scoreConfidence" : [ + 0.15276273989667477, + 0.16097054050902437 + ], + "scorePercentiles" : { + "0.0" : 0.15334087613469088, + "50.0" : 0.15778918079113874, + "90.0" : 0.15933047987699955, + "95.0" : 0.15933047987699955, + "99.0" : 0.15933047987699955, + "99.9" : 0.15933047987699955, + "99.99" : 0.15933047987699955, + "99.999" : 0.15933047987699955, + "99.9999" : 0.15933047987699955, + "100.0" : 0.15933047987699955 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15933047987699955, + 0.1585143294973608, + 0.15778918079113874 + ], + [ + 0.15860314175601092, + 0.15883556409726965, + 0.15759307658850227 + ], + [ + 0.15443659665189258, + 0.15334087613469088, + 0.1533565164317809 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04798045376241683, + "scoreError" : 0.0016470127208893697, + "scoreConfidence" : [ + 0.04633344104152746, + 0.0496274664833062 + ], + "scorePercentiles" : { + "0.0" : 0.04644588398890886, + "50.0" : 0.048023235478015326, + "90.0" : 0.04916658521188045, + "95.0" : 0.04916658521188045, + "99.0" : 0.04916658521188045, + "99.9" : 0.04916658521188045, + "99.99" : 0.04916658521188045, + "99.999" : 0.04916658521188045, + "99.9999" : 0.04916658521188045, + "100.0" : 0.04916658521188045 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04727092483538093, + 0.04644588398890886, + 0.046728657712005385 + ], + [ + 0.04916658521188045, + 0.048825053589563315, + 0.04881958612861809 + ], + [ + 0.04790924984789035, + 0.048023235478015326, + 0.04863490706948875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9397966.469331594, + "scoreError" : 400921.4801179857, + "scoreConfidence" : [ + 8997044.989213608, + 9798887.94944958 + ], + "scorePercentiles" : { + "0.0" : 9164177.787545787, + "50.0" : 9301691.79739777, + "90.0" : 9721944.350826045, + "95.0" : 9721944.350826045, + "99.0" : 9721944.350826045, + "99.9" : 9721944.350826045, + "99.99" : 9721944.350826045, + "99.999" : 9721944.350826045, + "99.9999" : 9721944.350826045, + "100.0" : 9721944.350826045 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9301769.69888476, + 9301691.79739777, + 9293745.372330548 + ], + [ + 9216755.062615102, + 9177969.882568806, + 9164177.787545787 + ], + [ + 9686416.676669894, + 9721944.350826045, + 9717227.595145632 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:25:13Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:25:13Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..9ec78ec79a --- /dev/null +++ b/performance-results/2025-03-24T00:25:13Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.427192512014576, + "scoreError" : 0.012873173657204301, + "scoreConfidence" : [ + 3.414319338357372, + 3.44006568567178 + ], + "scorePercentiles" : { + "0.0" : 3.4251916231698507, + "50.0" : 3.427044764180539, + "90.0" : 3.4294888965273755, + "95.0" : 3.4294888965273755, + "99.0" : 3.4294888965273755, + "99.9" : 3.4294888965273755, + "99.99" : 3.4294888965273755, + "99.999" : 3.4294888965273755, + "99.9999" : 3.4294888965273755, + "100.0" : 3.4294888965273755 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4251916231698507, + 3.4294888965273755 + ], + [ + 3.4259078290300446, + 3.4281816993310326 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.729194618855824, + "scoreError" : 0.008041480454113865, + "scoreConfidence" : [ + 1.7211531384017102, + 1.7372360993099378 + ], + "scorePercentiles" : { + "0.0" : 1.728180199312595, + "50.0" : 1.7288913442207987, + "90.0" : 1.730815587669104, + "95.0" : 1.730815587669104, + "99.0" : 1.730815587669104, + "99.9" : 1.730815587669104, + "99.99" : 1.730815587669104, + "99.999" : 1.730815587669104, + "99.9999" : 1.730815587669104, + "100.0" : 1.730815587669104 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7282568108323697, + 1.7295258776092277 + ], + [ + 1.728180199312595, + 1.730815587669104 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8689448347025848, + "scoreError" : 0.005903307335313809, + "scoreConfidence" : [ + 0.8630415273672709, + 0.8748481420378986 + ], + "scorePercentiles" : { + "0.0" : 0.8676539255997362, + "50.0" : 0.8691740741199422, + "90.0" : 0.8697772649707182, + "95.0" : 0.8697772649707182, + "99.0" : 0.8697772649707182, + "99.9" : 0.8697772649707182, + "99.99" : 0.8697772649707182, + "99.999" : 0.8697772649707182, + "99.9999" : 0.8697772649707182, + "100.0" : 0.8697772649707182 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8676539255997362, + 0.8690340804702854 + ], + [ + 0.869314067769599, + 0.8697772649707182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.167508035118427, + "scoreError" : 0.25972430198208885, + "scoreConfidence" : [ + 15.907783733136338, + 16.427232337100516 + ], + "scorePercentiles" : { + "0.0" : 15.92809758573588, + "50.0" : 16.183659072249025, + "90.0" : 16.343217981430513, + "95.0" : 16.343217981430513, + "99.0" : 16.343217981430513, + "99.9" : 16.343217981430513, + "99.99" : 16.343217981430513, + "99.999" : 16.343217981430513, + "99.9999" : 16.343217981430513, + "100.0" : 16.343217981430513 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.197843725815492, + 16.17705961536494, + 16.183659072249025 + ], + [ + 16.310391435762632, + 16.343217981430513, + 16.34076437108 + ], + [ + 15.92809758573588, + 15.970675179208435, + 16.05586334941892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2687.1436345801776, + "scoreError" : 18.904649497499815, + "scoreConfidence" : [ + 2668.2389850826776, + 2706.0482840776776 + ], + "scorePercentiles" : { + "0.0" : 2670.3886255919297, + "50.0" : 2684.9111243097527, + "90.0" : 2703.5474294577257, + "95.0" : 2703.5474294577257, + "99.0" : 2703.5474294577257, + "99.9" : 2703.5474294577257, + "99.99" : 2703.5474294577257, + "99.999" : 2703.5474294577257, + "99.9999" : 2703.5474294577257, + "100.0" : 2703.5474294577257 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2703.5474294577257, + 2700.7496243988994, + 2697.685683724869 + ], + [ + 2687.329405036839, + 2684.9111243097527, + 2681.400528174645 + ], + [ + 2679.5193054018728, + 2670.3886255919297, + 2678.7609851250654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69734.09464764553, + "scoreError" : 1969.4613868559036, + "scoreConfidence" : [ + 67764.63326078962, + 71703.55603450144 + ], + "scorePercentiles" : { + "0.0" : 68737.04196237889, + "50.0" : 69100.07053657329, + "90.0" : 71311.58539349773, + "95.0" : 71311.58539349773, + "99.0" : 71311.58539349773, + "99.9" : 71311.58539349773, + "99.99" : 71311.58539349773, + "99.999" : 71311.58539349773, + "99.9999" : 71311.58539349773, + "100.0" : 71311.58539349773 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71238.58894866482, + 71309.06321666678, + 71311.58539349773 + ], + [ + 68737.04196237889, + 68887.45002530912, + 68811.03706522842 + ], + [ + 69073.30047654698, + 69138.71420394372, + 69100.07053657329 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 351.50220235933625, + "scoreError" : 7.756306318471352, + "scoreConfidence" : [ + 343.7458960408649, + 359.2585086778076 + ], + "scorePercentiles" : { + "0.0" : 345.4808066065005, + "50.0" : 351.31352568630047, + "90.0" : 356.91040681496656, + "95.0" : 356.91040681496656, + "99.0" : 356.91040681496656, + "99.9" : 356.91040681496656, + "99.99" : 356.91040681496656, + "99.999" : 356.91040681496656, + "99.9999" : 356.91040681496656, + "100.0" : 356.91040681496656 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.91040681496656, + 356.88629417444713, + 356.5931456022146 + ], + [ + 345.4808066065005, + 346.0590898633618, + 347.0960040572533 + ], + [ + 352.2717640794763, + 351.31352568630047, + 350.90878434950565 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.89426072041461, + "scoreError" : 3.212501268374495, + "scoreConfidence" : [ + 103.68175945204011, + 110.1067619887891 + ], + "scorePercentiles" : { + "0.0" : 104.89864582142164, + "50.0" : 106.2840255003389, + "90.0" : 109.5152093057473, + "95.0" : 109.5152093057473, + "99.0" : 109.5152093057473, + "99.9" : 109.5152093057473, + "99.99" : 109.5152093057473, + "99.999" : 109.5152093057473, + "99.9999" : 109.5152093057473, + "100.0" : 109.5152093057473 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.89864582142164, + 105.31981365401647, + 105.27531851739955 + ], + [ + 109.19609289827845, + 109.5152093057473, + 109.37650741372804 + ], + [ + 105.80530145136055, + 106.2840255003389, + 106.37743192144043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06176367037071446, + "scoreError" : 0.0012202223664750805, + "scoreConfidence" : [ + 0.06054344800423938, + 0.06298389273718955 + ], + "scorePercentiles" : { + "0.0" : 0.0613146869738496, + "50.0" : 0.0613733022891862, + "90.0" : 0.06359179673142348, + "95.0" : 0.06359179673142348, + "99.0" : 0.06359179673142348, + "99.9" : 0.06359179673142348, + "99.99" : 0.06359179673142348, + "99.999" : 0.06359179673142348, + "99.9999" : 0.06359179673142348, + "100.0" : 0.06359179673142348 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06137311087516877, + 0.0613733022891862, + 0.06134540644975278 + ], + [ + 0.06186620599352887, + 0.061843810723562154, + 0.061818986511297254 + ], + [ + 0.06359179673142348, + 0.06134572678866103, + 0.0613146869738496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6557456403008633E-4, + "scoreError" : 1.4201606647306137E-5, + "scoreConfidence" : [ + 3.513729573827802E-4, + 3.797761706773925E-4 + ], + "scorePercentiles" : { + "0.0" : 3.552793083481791E-4, + "50.0" : 3.657273559060746E-4, + "90.0" : 3.7604188406507215E-4, + "95.0" : 3.7604188406507215E-4, + "99.0" : 3.7604188406507215E-4, + "99.9" : 3.7604188406507215E-4, + "99.99" : 3.7604188406507215E-4, + "99.999" : 3.7604188406507215E-4, + "99.9999" : 3.7604188406507215E-4, + "100.0" : 3.7604188406507215E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.655510130763393E-4, + 3.665766364791667E-4, + 3.657273559060746E-4 + ], + [ + 3.747549098404646E-4, + 3.7456665019215994E-4, + 3.7604188406507215E-4 + ], + [ + 3.5582687465080437E-4, + 3.558464437125165E-4, + 3.552793083481791E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01478077065447956, + "scoreError" : 4.596114266672553E-4, + "scoreConfidence" : [ + 0.014321159227812304, + 0.015240382081146815 + ], + "scorePercentiles" : { + "0.0" : 0.014584980540950492, + "50.0" : 0.014609507818172522, + "90.0" : 0.015151146695958486, + "95.0" : 0.015151146695958486, + "99.0" : 0.015151146695958486, + "99.9" : 0.015151146695958486, + "99.99" : 0.015151146695958486, + "99.999" : 0.015151146695958486, + "99.9999" : 0.015151146695958486, + "100.0" : 0.015151146695958486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.015151146695958486, + 0.015140491343534866, + 0.015144086810876953 + ], + [ + 0.014609507818172522, + 0.014589845803357664, + 0.014596098798462171 + ], + [ + 0.014597137646444033, + 0.01461364043255882, + 0.014584980540950492 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9851262027850285, + "scoreError" : 0.022089658643544983, + "scoreConfidence" : [ + 0.9630365441414835, + 1.0072158614285736 + ], + "scorePercentiles" : { + "0.0" : 0.9747190762183235, + "50.0" : 0.9791730844022325, + "90.0" : 1.01408276617319, + "95.0" : 1.01408276617319, + "99.0" : 1.01408276617319, + "99.9" : 1.01408276617319, + "99.99" : 1.01408276617319, + "99.999" : 1.01408276617319, + "99.9999" : 1.01408276617319, + "100.0" : 1.01408276617319 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9758338460187354, + 0.9761059209370425, + 0.9747190762183235 + ], + [ + 0.9823366401768173, + 0.9763997227104081, + 0.9791730844022325 + ], + [ + 0.9938331164662626, + 1.01408276617319, + 0.9936516519622454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012908189953084093, + "scoreError" : 5.544120422241866E-4, + "scoreConfidence" : [ + 0.012353777910859906, + 0.01346260199530828 + ], + "scorePercentiles" : { + "0.0" : 0.012679037873927696, + "50.0" : 0.012885974801918061, + "90.0" : 0.013127490649506812, + "95.0" : 0.013127490649506812, + "99.0" : 0.013127490649506812, + "99.9" : 0.013127490649506812, + "99.99" : 0.013127490649506812, + "99.999" : 0.013127490649506812, + "99.9999" : 0.013127490649506812, + "100.0" : 0.013127490649506812 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012679037873927696, + 0.012766024883001891, + 0.012756999800995532 + ], + [ + 0.013005924720834233, + 0.013127490649506812, + 0.013113661790238401 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6561826880524, + "scoreError" : 0.06436677310614175, + "scoreConfidence" : [ + 3.5918159149462583, + 3.720549461158542 + ], + "scorePercentiles" : { + "0.0" : 3.6185629515195368, + "50.0" : 3.6526129974433896, + "90.0" : 3.682027943298969, + "95.0" : 3.682027943298969, + "99.0" : 3.682027943298969, + "99.9" : 3.682027943298969, + "99.99" : 3.682027943298969, + "99.999" : 3.682027943298969, + "99.9999" : 3.682027943298969, + "100.0" : 3.682027943298969 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6526484506939374, + 3.682027943298969, + 3.678807961764706 + ], + [ + 3.6185629515195368, + 3.652471276844412, + 3.6525775441928414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8098269224905965, + "scoreError" : 0.0682573600462391, + "scoreConfidence" : [ + 2.7415695624443575, + 2.8780842825368356 + ], + "scorePercentiles" : { + "0.0" : 2.756005176357123, + "50.0" : 2.8269731232334654, + "90.0" : 2.852774981745579, + "95.0" : 2.852774981745579, + "99.0" : 2.852774981745579, + "99.9" : 2.852774981745579, + "99.99" : 2.852774981745579, + "99.999" : 2.852774981745579, + "99.9999" : 2.852774981745579, + "100.0" : 2.852774981745579 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.852774981745579, + 2.8471311010532308, + 2.841508862215909 + ], + [ + 2.760114301048565, + 2.756005176357123, + 2.756156037475889 + ], + [ + 2.8206438959390865, + 2.8271348233465234, + 2.8269731232334654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.182257758641677, + "scoreError" : 0.009369711322852617, + "scoreConfidence" : [ + 0.1728880473188244, + 0.19162746996452962 + ], + "scorePercentiles" : { + "0.0" : 0.17512085773574992, + "50.0" : 0.18244345578603616, + "90.0" : 0.18892104490582434, + "95.0" : 0.18892104490582434, + "99.0" : 0.18892104490582434, + "99.9" : 0.18892104490582434, + "99.99" : 0.18892104490582434, + "99.999" : 0.18892104490582434, + "99.9999" : 0.18892104490582434, + "100.0" : 0.18892104490582434 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18892104490582434, + 0.18846615911875012, + 0.18838380496948234 + ], + [ + 0.17668158256183747, + 0.17546814056358787, + 0.17512085773574992 + ], + [ + 0.18229967321715035, + 0.18253510891667427, + 0.18244345578603616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33033853868194574, + "scoreError" : 0.010265857312702213, + "scoreConfidence" : [ + 0.32007268136924355, + 0.3406043959946479 + ], + "scorePercentiles" : { + "0.0" : 0.32237836437782075, + "50.0" : 0.3325730915893445, + "90.0" : 0.3368782656560552, + "95.0" : 0.3368782656560552, + "99.0" : 0.3368782656560552, + "99.9" : 0.3368782656560552, + "99.99" : 0.3368782656560552, + "99.999" : 0.3368782656560552, + "99.9999" : 0.3368782656560552, + "100.0" : 0.3368782656560552 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3368782656560552, + 0.3358404426906673, + 0.33497170506464796 + ], + [ + 0.33304267895560663, + 0.3325730915893445, + 0.3324330246659132 + ], + [ + 0.322414881290905, + 0.32237836437782075, + 0.3225143938465508 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16090177068882616, + "scoreError" : 0.005913352137785627, + "scoreConfidence" : [ + 0.15498841855104054, + 0.1668151228266118 + ], + "scorePercentiles" : { + "0.0" : 0.15638643631245602, + "50.0" : 0.16139914766216368, + "90.0" : 0.1650659744317713, + "95.0" : 0.1650659744317713, + "99.0" : 0.1650659744317713, + "99.9" : 0.1650659744317713, + "99.99" : 0.1650659744317713, + "99.999" : 0.1650659744317713, + "99.9999" : 0.1650659744317713, + "100.0" : 0.1650659744317713 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1650659744317713, + 0.16443675696785331, + 0.1646148937431069 + ], + [ + 0.1609050628801287, + 0.16174211627417998, + 0.16139914766216368 + ], + [ + 0.15649513283047214, + 0.15707041509730316, + 0.15638643631245602 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39215436517063057, + "scoreError" : 0.00894198906358332, + "scoreConfidence" : [ + 0.3832123761070472, + 0.4010963542342139 + ], + "scorePercentiles" : { + "0.0" : 0.3839347225016317, + "50.0" : 0.3935621432900433, + "90.0" : 0.39837528426881247, + "95.0" : 0.39837528426881247, + "99.0" : 0.39837528426881247, + "99.9" : 0.39837528426881247, + "99.99" : 0.39837528426881247, + "99.999" : 0.39837528426881247, + "99.9999" : 0.39837528426881247, + "100.0" : 0.39837528426881247 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39837528426881247, + 0.3951016906483347, + 0.3937299167683767 + ], + [ + 0.38905089678649235, + 0.3843139198339802, + 0.3839347225016317 + ], + [ + 0.3980502241372448, + 0.3935621432900433, + 0.393270488300759 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15446192003082043, + "scoreError" : 0.001081224597951432, + "scoreConfidence" : [ + 0.153380695432869, + 0.15554314462877186 + ], + "scorePercentiles" : { + "0.0" : 0.15360487676451162, + "50.0" : 0.15451793318809004, + "90.0" : 0.15524694288597377, + "95.0" : 0.15524694288597377, + "99.0" : 0.15524694288597377, + "99.9" : 0.15524694288597377, + "99.99" : 0.15524694288597377, + "99.999" : 0.15524694288597377, + "99.9999" : 0.15524694288597377, + "100.0" : 0.15524694288597377 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15498702888892332, + 0.15524694288597377, + 0.1549091697467276 + ], + [ + 0.15451793318809004, + 0.15411996120888943, + 0.15380470221012318 + ], + [ + 0.15516613101832458, + 0.15380053436582028, + 0.15360487676451162 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04748573782000606, + "scoreError" : 0.0012040196670550232, + "scoreConfidence" : [ + 0.04628171815295104, + 0.048689757487061086 + ], + "scorePercentiles" : { + "0.0" : 0.046663098938428876, + "50.0" : 0.04712490444145991, + "90.0" : 0.048372361226128514, + "95.0" : 0.048372361226128514, + "99.0" : 0.048372361226128514, + "99.9" : 0.048372361226128514, + "99.99" : 0.048372361226128514, + "99.999" : 0.048372361226128514, + "99.9999" : 0.048372361226128514, + "100.0" : 0.048372361226128514 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04778590171548717, + 0.04712490444145991, + 0.046904938836772984 + ], + [ + 0.04829784319805265, + 0.04837072604720905, + 0.048372361226128514 + ], + [ + 0.04701799494562432, + 0.04683387103089114, + 0.046663098938428876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9317618.65213532, + "scoreError" : 293418.301524301, + "scoreConfidence" : [ + 9024200.35061102, + 9611036.95365962 + ], + "scorePercentiles" : { + "0.0" : 9093342.035454545, + "50.0" : 9337089.965485075, + "90.0" : 9534807.62726406, + "95.0" : 9534807.62726406, + "99.0" : 9534807.62726406, + "99.9" : 9534807.62726406, + "99.99" : 9534807.62726406, + "99.999" : 9534807.62726406, + "99.9999" : 9534807.62726406, + "100.0" : 9534807.62726406 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9301863.918215614, + 9338010.549953315, + 9337089.965485075 + ], + [ + 9534807.62726406, + 9507893.685361216, + 9498141.189933524 + ], + [ + 9150132.32936871, + 9097286.568181818, + 9093342.035454545 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:25:27Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:25:27Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..e7a92860fd --- /dev/null +++ b/performance-results/2025-03-24T00:25:27Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.421246302583824, + "scoreError" : 0.025733017281439678, + "scoreConfidence" : [ + 3.395513285302384, + 3.4469793198652634 + ], + "scorePercentiles" : { + "0.0" : 3.417136102719499, + "50.0" : 3.4205731276212257, + "90.0" : 3.4267028523733463, + "95.0" : 3.4267028523733463, + "99.0" : 3.4267028523733463, + "99.9" : 3.4267028523733463, + "99.99" : 3.4267028523733463, + "99.999" : 3.4267028523733463, + "99.9999" : 3.4267028523733463, + "100.0" : 3.4267028523733463 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.417136102719499, + 3.4205781955314856 + ], + [ + 3.4205680597109653, + 3.4267028523733463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7273766517476457, + "scoreError" : 0.01233951072091223, + "scoreConfidence" : [ + 1.7150371410267333, + 1.739716162468558 + ], + "scorePercentiles" : { + "0.0" : 1.7248858281468324, + "50.0" : 1.7275784917996955, + "90.0" : 1.7294637952443586, + "95.0" : 1.7294637952443586, + "99.0" : 1.7294637952443586, + "99.9" : 1.7294637952443586, + "99.99" : 1.7294637952443586, + "99.999" : 1.7294637952443586, + "99.9999" : 1.7294637952443586, + "100.0" : 1.7294637952443586 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7271929218788888, + 1.7294637952443586 + ], + [ + 1.7248858281468324, + 1.727964061720502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8683348226608707, + "scoreError" : 0.0037602099325063747, + "scoreConfidence" : [ + 0.8645746127283643, + 0.8720950325933771 + ], + "scorePercentiles" : { + "0.0" : 0.8678619660868055, + "50.0" : 0.8681469488116227, + "90.0" : 0.8691834269334319, + "95.0" : 0.8691834269334319, + "99.0" : 0.8691834269334319, + "99.9" : 0.8691834269334319, + "99.99" : 0.8691834269334319, + "99.999" : 0.8691834269334319, + "99.9999" : 0.8691834269334319, + "100.0" : 0.8691834269334319 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8678619660868055, + 0.8691834269334319 + ], + [ + 0.8681742930439199, + 0.8681196045793255 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.341865851698003, + "scoreError" : 0.10566306717401301, + "scoreConfidence" : [ + 16.23620278452399, + 16.447528918872017 + ], + "scorePercentiles" : { + "0.0" : 16.22303246272705, + "50.0" : 16.362295927808958, + "90.0" : 16.435421636550824, + "95.0" : 16.435421636550824, + "99.0" : 16.435421636550824, + "99.9" : 16.435421636550824, + "99.99" : 16.435421636550824, + "99.999" : 16.435421636550824, + "99.9999" : 16.435421636550824, + "100.0" : 16.435421636550824 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.35107234728992, + 16.362295927808958, + 16.435421636550824 + ], + [ + 16.378925272900975, + 16.374444545565535, + 16.367253221102832 + ], + [ + 16.281324433699563, + 16.22303246272705, + 16.303022817636357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2723.7793282226216, + "scoreError" : 34.82246156603348, + "scoreConfidence" : [ + 2688.9568666565883, + 2758.601789788655 + ], + "scorePercentiles" : { + "0.0" : 2702.465007990573, + "50.0" : 2718.2824063648923, + "90.0" : 2752.109075671271, + "95.0" : 2752.109075671271, + "99.0" : 2752.109075671271, + "99.9" : 2752.109075671271, + "99.99" : 2752.109075671271, + "99.999" : 2752.109075671271, + "99.9999" : 2752.109075671271, + "100.0" : 2752.109075671271 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2751.25254211314, + 2745.482247982233, + 2752.109075671271 + ], + [ + 2703.1017470328934, + 2702.5273149643604, + 2702.465007990573 + ], + [ + 2718.2824063648923, + 2720.945553216911, + 2717.8480586673195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69969.63461352007, + "scoreError" : 1134.2174371916856, + "scoreConfidence" : [ + 68835.41717632838, + 71103.85205071176 + ], + "scorePercentiles" : { + "0.0" : 69043.0075343839, + "50.0" : 70280.94069877287, + "90.0" : 70603.5514723977, + "95.0" : 70603.5514723977, + "99.0" : 70603.5514723977, + "99.9" : 70603.5514723977, + "99.99" : 70603.5514723977, + "99.999" : 70603.5514723977, + "99.9999" : 70603.5514723977, + "100.0" : 70603.5514723977 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70332.83724038013, + 70280.94069877287, + 70280.81855460658 + ], + [ + 70505.14309459185, + 70478.95648670508, + 70603.5514723977 + ], + [ + 69133.77056067433, + 69043.0075343839, + 69067.68587916823 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.43725104505324, + "scoreError" : 4.453722696756971, + "scoreConfidence" : [ + 344.98352834829626, + 353.8909737418102 + ], + "scorePercentiles" : { + "0.0" : 345.9068962532555, + "50.0" : 350.13288831364576, + "90.0" : 352.6286330072688, + "95.0" : 352.6286330072688, + "99.0" : 352.6286330072688, + "99.9" : 352.6286330072688, + "99.99" : 352.6286330072688, + "99.999" : 352.6286330072688, + "99.9999" : 352.6286330072688, + "100.0" : 352.6286330072688 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.2672803390126, + 346.2982345844763, + 345.9068962532555 + ], + [ + 350.13288831364576, + 350.55161549887754, + 349.3974695571367 + ], + [ + 351.77503927442575, + 351.97720257737996, + 352.6286330072688 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.03740194054079, + "scoreError" : 4.341780378218412, + "scoreConfidence" : [ + 101.69562156232237, + 110.3791823187592 + ], + "scorePercentiles" : { + "0.0" : 102.61722251422017, + "50.0" : 106.99671128488392, + "90.0" : 108.66695605213567, + "95.0" : 108.66695605213567, + "99.0" : 108.66695605213567, + "99.9" : 108.66695605213567, + "99.99" : 108.66695605213567, + "99.999" : 108.66695605213567, + "99.9999" : 108.66695605213567, + "100.0" : 108.66695605213567 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.2477674737249, + 106.99671128488392, + 106.51128399292004 + ], + [ + 102.61722251422017, + 102.78829964896627, + 102.76383751861742 + ], + [ + 108.31343183269428, + 108.66695605213567, + 108.4311071467046 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06114094780691651, + "scoreError" : 6.931905613668829E-4, + "scoreConfidence" : [ + 0.06044775724554963, + 0.06183413836828339 + ], + "scorePercentiles" : { + "0.0" : 0.06052651748890866, + "50.0" : 0.06120342482496083, + "90.0" : 0.06171405804122439, + "95.0" : 0.06171405804122439, + "99.0" : 0.06171405804122439, + "99.9" : 0.06171405804122439, + "99.99" : 0.06171405804122439, + "99.999" : 0.06171405804122439, + "99.9999" : 0.06171405804122439, + "100.0" : 0.06171405804122439 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060785686946479046, + 0.06061288448576832, + 0.06052651748890866 + ], + [ + 0.06120342482496083, + 0.06117210848687269, + 0.06171405804122439 + ], + [ + 0.06145645012567678, + 0.061479210661568064, + 0.06131818920078977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.558887426986108E-4, + "scoreError" : 1.1643968365827848E-5, + "scoreConfidence" : [ + 3.4424477433278296E-4, + 3.675327110644386E-4 + ], + "scorePercentiles" : { + "0.0" : 3.4989609340297815E-4, + "50.0" : 3.527937491614633E-4, + "90.0" : 3.652218515584872E-4, + "95.0" : 3.652218515584872E-4, + "99.0" : 3.652218515584872E-4, + "99.9" : 3.652218515584872E-4, + "99.99" : 3.652218515584872E-4, + "99.999" : 3.652218515584872E-4, + "99.9999" : 3.652218515584872E-4, + "100.0" : 3.652218515584872E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6513254492621797E-4, + 3.646400005615393E-4, + 3.652218515584872E-4 + ], + [ + 3.519855166866087E-4, + 3.527937491614633E-4, + 3.530516825367461E-4 + ], + [ + 3.4989609340297815E-4, + 3.4996294116570423E-4, + 3.503143042877524E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014459886907853124, + "scoreError" : 1.751271748642364E-5, + "scoreConfidence" : [ + 0.0144423741903667, + 0.014477399625339548 + ], + "scorePercentiles" : { + "0.0" : 0.01444761801971787, + "50.0" : 0.0144585426456789, + "90.0" : 0.014479206546259053, + "95.0" : 0.014479206546259053, + "99.0" : 0.014479206546259053, + "99.9" : 0.014479206546259053, + "99.99" : 0.014479206546259053, + "99.999" : 0.014479206546259053, + "99.9999" : 0.014479206546259053, + "100.0" : 0.014479206546259053 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0144585426456789, + 0.01444858810287856, + 0.01445240660900229 + ], + [ + 0.014471111776452883, + 0.014463550117008629, + 0.014462029081353746 + ], + [ + 0.014479206546259053, + 0.01445592927232619, + 0.01444761801971787 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9848656516090956, + "scoreError" : 0.01790359690960157, + "scoreConfidence" : [ + 0.966962054699494, + 1.0027692485186972 + ], + "scorePercentiles" : { + "0.0" : 0.9702499647812166, + "50.0" : 0.987872356910007, + "90.0" : 0.999280423361311, + "95.0" : 0.999280423361311, + "99.0" : 0.999280423361311, + "99.9" : 0.999280423361311, + "99.99" : 0.999280423361311, + "99.999" : 0.999280423361311, + "99.9999" : 0.999280423361311, + "100.0" : 0.999280423361311 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9702499647812166, + 0.9752142199902487, + 0.97071049669967 + ], + [ + 0.9902428413704327, + 0.999280423361311, + 0.9967743983853284 + ], + [ + 0.987872356910007, + 0.9849215701201497, + 0.988524592863497 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013021840921867006, + "scoreError" : 1.9749862566405114E-4, + "scoreConfidence" : [ + 0.012824342296202955, + 0.013219339547531057 + ], + "scorePercentiles" : { + "0.0" : 0.012931413966648046, + "50.0" : 0.01299823102761962, + "90.0" : 0.013108989882703329, + "95.0" : 0.013108989882703329, + "99.0" : 0.013108989882703329, + "99.9" : 0.013108989882703329, + "99.99" : 0.013108989882703329, + "99.999" : 0.013108989882703329, + "99.9999" : 0.013108989882703329, + "100.0" : 0.013108989882703329 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012931413966648046, + 0.013104382452609151, + 0.013108989882703329 + ], + [ + 0.013004359931858672, + 0.012992102123380572, + 0.012989797174002275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.607023788037479, + "scoreError" : 0.07327604702535247, + "scoreConfidence" : [ + 3.5337477410121267, + 3.6802998350628315 + ], + "scorePercentiles" : { + "0.0" : 3.5660110042765503, + "50.0" : 3.6107640732839337, + "90.0" : 3.6383183745454546, + "95.0" : 3.6383183745454546, + "99.0" : 3.6383183745454546, + "99.9" : 3.6383183745454546, + "99.99" : 3.6383183745454546, + "99.999" : 3.6383183745454546, + "99.9999" : 3.6383183745454546, + "100.0" : 3.6383183745454546 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.589340019368723, + 3.6383183745454546, + 3.62694518346628 + ], + [ + 3.5660110042765503, + 3.6080095750360752, + 3.613518571531792 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8059151286489663, + "scoreError" : 0.05752197780891353, + "scoreConfidence" : [ + 2.748393150840053, + 2.8634371064578796 + ], + "scorePercentiles" : { + "0.0" : 2.7601151989514348, + "50.0" : 2.8134174627285513, + "90.0" : 2.844721040386803, + "95.0" : 2.844721040386803, + "99.0" : 2.844721040386803, + "99.9" : 2.844721040386803, + "99.99" : 2.844721040386803, + "99.999" : 2.844721040386803, + "99.9999" : 2.844721040386803, + "100.0" : 2.844721040386803 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.84413932044356, + 2.844721040386803, + 2.8285615141402713 + ], + [ + 2.823798961038961, + 2.8089209247402414, + 2.8134174627285513 + ], + [ + 2.76110121783545, + 2.768460517575422, + 2.7601151989514348 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.19079301512188468, + "scoreError" : 0.014774377161596323, + "scoreConfidence" : [ + 0.17601863796028835, + 0.205567392283481 + ], + "scorePercentiles" : { + "0.0" : 0.1786670587268407, + "50.0" : 0.1959693705148053, + "90.0" : 0.19811789208732863, + "95.0" : 0.19811789208732863, + "99.0" : 0.19811789208732863, + "99.9" : 0.19811789208732863, + "99.99" : 0.19811789208732863, + "99.999" : 0.19811789208732863, + "99.9999" : 0.19811789208732863, + "100.0" : 0.19811789208732863 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1972381575511331, + 0.1959693705148053, + 0.19596850636880267 + ], + [ + 0.19811789208732863, + 0.19637531048228732, + 0.1961232889642864 + ], + [ + 0.17988990216042164, + 0.1786670587268407, + 0.17878764924105625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31952785321151783, + "scoreError" : 0.01001783873026382, + "scoreConfidence" : [ + 0.30951001448125404, + 0.3295456919417816 + ], + "scorePercentiles" : { + "0.0" : 0.31381017921360654, + "50.0" : 0.31626577435167613, + "90.0" : 0.32794699619597295, + "95.0" : 0.32794699619597295, + "99.0" : 0.32794699619597295, + "99.9" : 0.32794699619597295, + "99.99" : 0.32794699619597295, + "99.999" : 0.32794699619597295, + "99.9999" : 0.32794699619597295, + "100.0" : 0.32794699619597295 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3189972577434687, + 0.31626577435167613, + 0.31608200075858145 + ], + [ + 0.31446555177510144, + 0.3145012565965343, + 0.31381017921360654 + ], + [ + 0.3270510261307519, + 0.32663063613796706, + 0.32794699619597295 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16863322355175633, + "scoreError" : 0.0036872991180300486, + "scoreConfidence" : [ + 0.1649459244337263, + 0.17232052266978637 + ], + "scorePercentiles" : { + "0.0" : 0.16568923645099826, + "50.0" : 0.1695653306485799, + "90.0" : 0.1706155962260288, + "95.0" : 0.1706155962260288, + "99.0" : 0.1706155962260288, + "99.9" : 0.1706155962260288, + "99.99" : 0.1706155962260288, + "99.999" : 0.1706155962260288, + "99.9999" : 0.1706155962260288, + "100.0" : 0.1706155962260288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16583173301936854, + 0.16568923645099826, + 0.16583332192428238 + ], + [ + 0.17051351466375664, + 0.1706155962260288, + 0.17053552343110503 + ], + [ + 0.17005843134087237, + 0.16905632426081518, + 0.1695653306485799 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39274708507310296, + "scoreError" : 0.00931143808849305, + "scoreConfidence" : [ + 0.3834356469846099, + 0.402058523161596 + ], + "scorePercentiles" : { + "0.0" : 0.38599543554114557, + "50.0" : 0.39204008754116354, + "90.0" : 0.3999358855828834, + "95.0" : 0.3999358855828834, + "99.0" : 0.3999358855828834, + "99.9" : 0.3999358855828834, + "99.99" : 0.3999358855828834, + "99.999" : 0.3999358855828834, + "99.9999" : 0.3999358855828834, + "100.0" : 0.3999358855828834 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39978432941552733, + 0.3999358855828834, + 0.3985876615648292 + ], + [ + 0.38599543554114557, + 0.38682379077054, + 0.3874426654914571 + ], + [ + 0.3922239095544399, + 0.39204008754116354, + 0.3918900001959401 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15654185959972333, + "scoreError" : 0.003324708225371492, + "scoreConfidence" : [ + 0.15321715137435185, + 0.1598665678250948 + ], + "scorePercentiles" : { + "0.0" : 0.1537966328934822, + "50.0" : 0.15711305921445404, + "90.0" : 0.15991182664385314, + "95.0" : 0.15991182664385314, + "99.0" : 0.15991182664385314, + "99.9" : 0.15991182664385314, + "99.99" : 0.15991182664385314, + "99.999" : 0.15991182664385314, + "99.9999" : 0.15991182664385314, + "100.0" : 0.15991182664385314 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15991182664385314, + 0.1574710881977797, + 0.1574142480166226 + ], + [ + 0.15711305921445404, + 0.1573238880655717, + 0.15707679514325207 + ], + [ + 0.15401986099987677, + 0.1537966328934822, + 0.1547493372226177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04730248592662241, + "scoreError" : 0.001214882838521849, + "scoreConfidence" : [ + 0.04608760308810056, + 0.04851736876514426 + ], + "scorePercentiles" : { + "0.0" : 0.04615450604845223, + "50.0" : 0.04744312130542456, + "90.0" : 0.04815119295365029, + "95.0" : 0.04815119295365029, + "99.0" : 0.04815119295365029, + "99.9" : 0.04815119295365029, + "99.99" : 0.04815119295365029, + "99.999" : 0.04815119295365029, + "99.9999" : 0.04815119295365029, + "100.0" : 0.04815119295365029 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04669727998860601, + 0.04615450604845223, + 0.04643505562830264 + ], + [ + 0.04815119295365029, + 0.04791434695676756, + 0.04799755646589584 + ], + [ + 0.04744312130542456, + 0.04768213433305519, + 0.04724717965944741 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9214657.65577173, + "scoreError" : 324186.95975341706, + "scoreConfidence" : [ + 8890470.696018314, + 9538844.615525147 + ], + "scorePercentiles" : { + "0.0" : 9072593.251133272, + "50.0" : 9095946.824545454, + "90.0" : 9473104.0625, + "95.0" : 9473104.0625, + "99.0" : 9473104.0625, + "99.9" : 9473104.0625, + "99.99" : 9473104.0625, + "99.999" : 9473104.0625, + "99.9999" : 9473104.0625, + "100.0" : 9473104.0625 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9100846.449499546, + 9095946.824545454, + 9093544.356363636 + ], + [ + 9471608.28125, + 9470003.732007576, + 9473104.0625 + ], + [ + 9076957.367513612, + 9077314.577132486, + 9072593.251133272 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T00:26:22Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json b/performance-results/2025-03-24T00:26:22Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json new file mode 100644 index 0000000000..3b71828ef6 --- /dev/null +++ b/performance-results/2025-03-24T00:26:22Z-c46c07a77f81d0493fc0e7c93d9de49e97118281-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4058150783351246, + "scoreError" : 0.026452604872451217, + "scoreConfidence" : [ + 3.3793624734626735, + 3.432267683207576 + ], + "scorePercentiles" : { + "0.0" : 3.4004071794259927, + "50.0" : 3.406246718629739, + "90.0" : 3.4103596966550294, + "95.0" : 3.4103596966550294, + "99.0" : 3.4103596966550294, + "99.9" : 3.4103596966550294, + "99.99" : 3.4103596966550294, + "99.999" : 3.4103596966550294, + "99.9999" : 3.4103596966550294, + "100.0" : 3.4103596966550294 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.406232750028374, + 3.4103596966550294 + ], + [ + 3.4004071794259927, + 3.406260687231104 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7237606775531091, + "scoreError" : 0.01471389781372789, + "scoreConfidence" : [ + 1.7090467797393813, + 1.738474575366837 + ], + "scorePercentiles" : { + "0.0" : 1.7204652078126201, + "50.0" : 1.7244467307218376, + "90.0" : 1.7256840409561414, + "95.0" : 1.7256840409561414, + "99.0" : 1.7256840409561414, + "99.9" : 1.7256840409561414, + "99.99" : 1.7256840409561414, + "99.999" : 1.7256840409561414, + "99.9999" : 1.7256840409561414, + "100.0" : 1.7256840409561414 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7246099665286807, + 1.7204652078126201 + ], + [ + 1.7256840409561414, + 1.7242834949149946 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8663232166649114, + "scoreError" : 0.006686175885856252, + "scoreConfidence" : [ + 0.8596370407790551, + 0.8730093925507677 + ], + "scorePercentiles" : { + "0.0" : 0.8652181246222682, + "50.0" : 0.8663474533310827, + "90.0" : 0.8673798353752123, + "95.0" : 0.8673798353752123, + "99.0" : 0.8673798353752123, + "99.9" : 0.8673798353752123, + "99.99" : 0.8673798353752123, + "99.999" : 0.8673798353752123, + "99.9999" : 0.8673798353752123, + "100.0" : 0.8673798353752123 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8673798353752123, + 0.8670081057362332 + ], + [ + 0.865686800925932, + 0.8652181246222682 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.063146484271993, + "scoreError" : 0.09274549186336652, + "scoreConfidence" : [ + 15.970400992408626, + 16.155891976135358 + ], + "scorePercentiles" : { + "0.0" : 15.988271964073459, + "50.0" : 16.056373512006516, + "90.0" : 16.151461751402852, + "95.0" : 16.151461751402852, + "99.0" : 16.151461751402852, + "99.9" : 16.151461751402852, + "99.99" : 16.151461751402852, + "99.999" : 16.151461751402852, + "99.9999" : 16.151461751402852, + "100.0" : 16.151461751402852 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.056373512006516, + 16.074774345532692, + 16.042297273489353 + ], + [ + 16.021096192431116, + 16.005741694538813, + 15.988271964073459 + ], + [ + 16.107798059757286, + 16.151461751402852, + 16.120503565215856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2631.4019878913555, + "scoreError" : 45.07292665333818, + "scoreConfidence" : [ + 2586.3290612380174, + 2676.4749145446935 + ], + "scorePercentiles" : { + "0.0" : 2598.1253635550966, + "50.0" : 2628.6049799406546, + "90.0" : 2670.80836297728, + "95.0" : 2670.80836297728, + "99.0" : 2670.80836297728, + "99.9" : 2670.80836297728, + "99.99" : 2670.80836297728, + "99.999" : 2670.80836297728, + "99.9999" : 2670.80836297728, + "100.0" : 2670.80836297728 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2628.363719532275, + 2634.404337259284, + 2628.6049799406546 + ], + [ + 2602.783085480924, + 2598.1253635550966, + 2603.021830794198 + ], + [ + 2670.80836297728, + 2657.0851252173516, + 2659.4210862651344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70139.36832003857, + "scoreError" : 1080.653635734936, + "scoreConfidence" : [ + 69058.71468430363, + 71220.02195577351 + ], + "scorePercentiles" : { + "0.0" : 69331.95951448398, + "50.0" : 70230.85843595021, + "90.0" : 70859.36155987332, + "95.0" : 70859.36155987332, + "99.0" : 70859.36155987332, + "99.9" : 70859.36155987332, + "99.99" : 70859.36155987332, + "99.999" : 70859.36155987332, + "99.9999" : 70859.36155987332, + "100.0" : 70859.36155987332 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70230.85843595021, + 70306.19172133977, + 70212.58255702884 + ], + [ + 70778.52672038162, + 70820.40440516589, + 70859.36155987332 + ], + [ + 69338.63968738963, + 69375.79027873385, + 69331.95951448398 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.39493729944945, + "scoreError" : 5.38735019936265, + "scoreConfidence" : [ + 337.0075871000868, + 347.7822874988121 + ], + "scorePercentiles" : { + "0.0" : 337.26407618201983, + "50.0" : 344.3494882000147, + "90.0" : 345.3180429063327, + "95.0" : 345.3180429063327, + "99.0" : 345.3180429063327, + "99.9" : 345.3180429063327, + "99.99" : 345.3180429063327, + "99.999" : 345.3180429063327, + "99.9999" : 345.3180429063327, + "100.0" : 345.3180429063327 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.09902243857897, + 341.8493886510512, + 344.6666914454054 + ], + [ + 337.26407618201983, + 338.34929933870706, + 339.6471681207518 + ], + [ + 345.0112584121833, + 345.3180429063327, + 344.3494882000147 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.47572256516146, + "scoreError" : 3.6800047610781017, + "scoreConfidence" : [ + 101.79571780408337, + 109.15572732623956 + ], + "scorePercentiles" : { + "0.0" : 102.42778427400434, + "50.0" : 106.31243167262423, + "90.0" : 107.74689637106496, + "95.0" : 107.74689637106496, + "99.0" : 107.74689637106496, + "99.9" : 107.74689637106496, + "99.99" : 107.74689637106496, + "99.999" : 107.74689637106496, + "99.9999" : 107.74689637106496, + "100.0" : 107.74689637106496 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.283036063032, + 107.37412707665254, + 107.74689637106496 + ], + [ + 106.11333166047164, + 106.31243167262423, + 106.51985552590087 + ], + [ + 102.42778427400434, + 102.67053516833408, + 102.8335052743686 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06311428347152606, + "scoreError" : 0.00152037655154138, + "scoreConfidence" : [ + 0.06159390691998468, + 0.06463466002306745 + ], + "scorePercentiles" : { + "0.0" : 0.062365334173173345, + "50.0" : 0.06271125822291064, + "90.0" : 0.06517277432368142, + "95.0" : 0.06517277432368142, + "99.0" : 0.06517277432368142, + "99.9" : 0.06517277432368142, + "99.99" : 0.06517277432368142, + "99.999" : 0.06517277432368142, + "99.9999" : 0.06517277432368142, + "100.0" : 0.06517277432368142 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06270253047289417, + 0.06275191931475904, + 0.06271125822291064 + ], + [ + 0.062365334173173345, + 0.06256196170015765, + 0.06247188241063508 + ], + [ + 0.06369551286950872, + 0.06359537775601443, + 0.06517277432368142 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8222663335657985E-4, + "scoreError" : 2.8979427134608703E-6, + "scoreConfidence" : [ + 3.79328690643119E-4, + 3.851245760700407E-4 + ], + "scorePercentiles" : { + "0.0" : 3.790968269142776E-4, + "50.0" : 3.8297120240527854E-4, + "90.0" : 3.8414170084109486E-4, + "95.0" : 3.8414170084109486E-4, + "99.0" : 3.8414170084109486E-4, + "99.9" : 3.8414170084109486E-4, + "99.99" : 3.8414170084109486E-4, + "99.999" : 3.8414170084109486E-4, + "99.9999" : 3.8414170084109486E-4, + "100.0" : 3.8414170084109486E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.790968269142776E-4, + 3.80274158956133E-4, + 3.809465855965468E-4 + ], + [ + 3.8414170084109486E-4, + 3.824734405275988E-4, + 3.8297120240527854E-4 + ], + [ + 3.8380708551126946E-4, + 3.831089772239076E-4, + 3.832197222331119E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014194196126241223, + "scoreError" : 8.231346586656076E-5, + "scoreConfidence" : [ + 0.014111882660374662, + 0.014276509592107784 + ], + "scorePercentiles" : { + "0.0" : 0.014149952206303724, + "50.0" : 0.014168512126664777, + "90.0" : 0.014269262559644757, + "95.0" : 0.014269262559644757, + "99.0" : 0.014269262559644757, + "99.9" : 0.014269262559644757, + "99.99" : 0.014269262559644757, + "99.999" : 0.014269262559644757, + "99.9999" : 0.014269262559644757, + "100.0" : 0.014269262559644757 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014149952206303724, + 0.014151971689328413, + 0.01415818948088244 + ], + [ + 0.014168512126664777, + 0.014177382997877677, + 0.014167298605955855 + ], + [ + 0.01425682910980045, + 0.014269262559644757, + 0.014248366359712928 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9976094463518428, + "scoreError" : 0.020593406679277775, + "scoreConfidence" : [ + 0.977016039672565, + 1.0182028530311205 + ], + "scorePercentiles" : { + "0.0" : 0.9861651139927029, + "50.0" : 0.9900198547668547, + "90.0" : 1.0160989425988012, + "95.0" : 1.0160989425988012, + "99.0" : 1.0160989425988012, + "99.9" : 1.0160989425988012, + "99.99" : 1.0160989425988012, + "99.999" : 1.0160989425988012, + "99.9999" : 1.0160989425988012, + "100.0" : 1.0160989425988012 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9956012011946241, + 0.989060773711799, + 0.9890333369597468 + ], + [ + 1.0111175650591446, + 1.013320355253825, + 1.0160989425988012 + ], + [ + 0.9900198547668547, + 0.9861651139927029, + 0.988067873629088 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013280445247701916, + "scoreError" : 1.4610011076541306E-4, + "scoreConfidence" : [ + 0.013134345136936502, + 0.01342654535846733 + ], + "scorePercentiles" : { + "0.0" : 0.013238463008903915, + "50.0" : 0.013259971745728908, + "90.0" : 0.01337144344340329, + "95.0" : 0.01337144344340329, + "99.0" : 0.01337144344340329, + "99.9" : 0.01337144344340329, + "99.99" : 0.01337144344340329, + "99.999" : 0.01337144344340329, + "99.9999" : 0.01337144344340329, + "100.0" : 0.01337144344340329 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01325390333619611, + 0.013266040155261706, + 0.013240461469816412 + ], + [ + 0.013312360072630071, + 0.01337144344340329, + 0.013238463008903915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8909240052175984, + "scoreError" : 0.04217030962671556, + "scoreConfidence" : [ + 3.848753695590883, + 3.933094314844314 + ], + "scorePercentiles" : { + "0.0" : 3.8692972204176335, + "50.0" : 3.8944467164305974, + "90.0" : 3.9083230546875, + "95.0" : 3.9083230546875, + "99.0" : 3.9083230546875, + "99.9" : 3.9083230546875, + "99.99" : 3.9083230546875, + "99.999" : 3.9083230546875, + "99.9999" : 3.9083230546875, + "100.0" : 3.9083230546875 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9021358884555384, + 3.896992226635514, + 3.876894434883721 + ], + [ + 3.8692972204176335, + 3.891901206225681, + 3.9083230546875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9464650664152674, + "scoreError" : 0.07900631384816474, + "scoreConfidence" : [ + 2.8674587525671025, + 3.0254713802634323 + ], + "scorePercentiles" : { + "0.0" : 2.8846654577444477, + "50.0" : 2.949214712769095, + "90.0" : 3.0071091683704148, + "95.0" : 3.0071091683704148, + "99.0" : 3.0071091683704148, + "99.9" : 3.0071091683704148, + "99.99" : 3.0071091683704148, + "99.999" : 3.0071091683704148, + "99.9999" : 3.0071091683704148, + "100.0" : 3.0071091683704148 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0030966561561563, + 3.0071091683704148, + 2.9888247429766888 + ], + [ + 2.8951925684515194, + 2.898828372173913, + 2.8846654577444477 + ], + [ + 2.9574190813128327, + 2.949214712769095, + 2.933834837782341 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17691180678475368, + "scoreError" : 0.0020375512397658494, + "scoreConfidence" : [ + 0.17487425554498784, + 0.17894935802451953 + ], + "scorePercentiles" : { + "0.0" : 0.17535436262252538, + "50.0" : 0.1772252414978645, + "90.0" : 0.1782519088089551, + "95.0" : 0.1782519088089551, + "99.0" : 0.1782519088089551, + "99.9" : 0.1782519088089551, + "99.99" : 0.1782519088089551, + "99.999" : 0.1782519088089551, + "99.9999" : 0.1782519088089551, + "100.0" : 0.1782519088089551 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1772252414978645, + 0.17715724875992064, + 0.17734751363765341 + ], + [ + 0.1782519088089551, + 0.17805553854782422, + 0.17803248316747075 + ], + [ + 0.17542131004964304, + 0.17536065397092604, + 0.17535436262252538 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33425991649520753, + "scoreError" : 0.005110301773248331, + "scoreConfidence" : [ + 0.3291496147219592, + 0.33937021826845587 + ], + "scorePercentiles" : { + "0.0" : 0.3314547915879487, + "50.0" : 0.33275132459321866, + "90.0" : 0.338584502843987, + "95.0" : 0.338584502843987, + "99.0" : 0.338584502843987, + "99.9" : 0.338584502843987, + "99.99" : 0.338584502843987, + "99.999" : 0.338584502843987, + "99.9999" : 0.338584502843987, + "100.0" : 0.338584502843987 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.338584502843987, + 0.3381622264980387, + 0.33802885596944293 + ], + [ + 0.332660973854035, + 0.3329679401012186, + 0.33275132459321866 + ], + [ + 0.33184054337005575, + 0.3318880896389221, + 0.3314547915879487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16033987885490203, + "scoreError" : 0.0088942834909611, + "scoreConfidence" : [ + 0.15144559536394092, + 0.16923416234586314 + ], + "scorePercentiles" : { + "0.0" : 0.15388121990890347, + "50.0" : 0.16065122100308443, + "90.0" : 0.166323342004158, + "95.0" : 0.166323342004158, + "99.0" : 0.166323342004158, + "99.9" : 0.166323342004158, + "99.99" : 0.166323342004158, + "99.999" : 0.166323342004158, + "99.9999" : 0.166323342004158, + "100.0" : 0.166323342004158 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1541098480351364, + 0.15412502709450712, + 0.15388121990890347 + ], + [ + 0.16623179028906732, + 0.166323342004158, + 0.16616231505574663 + ], + [ + 0.16094142122119223, + 0.1606327250823227, + 0.16065122100308443 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39744495573528943, + "scoreError" : 0.005411637246195458, + "scoreConfidence" : [ + 0.39203331848909395, + 0.4028565929814849 + ], + "scorePercentiles" : { + "0.0" : 0.3940697161603026, + "50.0" : 0.39633976704185164, + "90.0" : 0.402766328567401, + "95.0" : 0.402766328567401, + "99.0" : 0.402766328567401, + "99.9" : 0.402766328567401, + "99.99" : 0.402766328567401, + "99.999" : 0.402766328567401, + "99.9999" : 0.402766328567401, + "100.0" : 0.402766328567401 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.402766328567401, + 0.3995626060012786, + 0.3994064622973081 + ], + [ + 0.3944502245888061, + 0.3940697161603026, + 0.3944233631379664 + ], + [ + 0.4007321151673011, + 0.39633976704185164, + 0.3952540186553891 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1578731358594352, + "scoreError" : 0.001429244900730236, + "scoreConfidence" : [ + 0.15644389095870495, + 0.15930238076016542 + ], + "scorePercentiles" : { + "0.0" : 0.15651093406369826, + "50.0" : 0.15804752496325447, + "90.0" : 0.15899748204973288, + "95.0" : 0.15899748204973288, + "99.0" : 0.15899748204973288, + "99.9" : 0.15899748204973288, + "99.99" : 0.15899748204973288, + "99.999" : 0.15899748204973288, + "99.9999" : 0.15899748204973288, + "100.0" : 0.15899748204973288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15817670798139888, + 0.15885249123949613, + 0.15842256156137127 + ], + [ + 0.15899748204973288, + 0.15804752496325447, + 0.15767250805688698 + ], + [ + 0.15651093406369826, + 0.15700596079631984, + 0.157172052022758 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04795383363672171, + "scoreError" : 5.299177065546994E-4, + "scoreConfidence" : [ + 0.04742391593016701, + 0.04848375134327641 + ], + "scorePercentiles" : { + "0.0" : 0.04746444761660663, + "50.0" : 0.04800709954586042, + "90.0" : 0.04852743631837416, + "95.0" : 0.04852743631837416, + "99.0" : 0.04852743631837416, + "99.9" : 0.04852743631837416, + "99.99" : 0.04852743631837416, + "99.999" : 0.04852743631837416, + "99.9999" : 0.04852743631837416, + "100.0" : 0.04852743631837416 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047803915034585615, + 0.04798231661172767, + 0.04801513513708167 + ], + [ + 0.0480238308625434, + 0.04800709954586042, + 0.04818131418150632 + ], + [ + 0.04852743631837416, + 0.04746444761660663, + 0.04757900742220954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9466197.532085942, + "scoreError" : 123449.88258417205, + "scoreConfidence" : [ + 9342747.64950177, + 9589647.414670113 + ], + "scorePercentiles" : { + "0.0" : 9371300.07022472, + "50.0" : 9485310.44549763, + "90.0" : 9569203.46462715, + "95.0" : 9569203.46462715, + "99.0" : 9569203.46462715, + "99.9" : 9569203.46462715, + "99.99" : 9569203.46462715, + "99.999" : 9569203.46462715, + "99.9999" : 9569203.46462715, + "100.0" : 9569203.46462715 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9371300.07022472, + 9371471.336142322, + 9412303.88052681 + ], + [ + 9485310.44549763, + 9489903.88235294, + 9427795.868991517 + ], + [ + 9569203.46462715, + 9531204.40952381, + 9537284.43088656 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:13:10Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:13:10Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..e2485a8d00 --- /dev/null +++ b/performance-results/2025-03-24T01:13:10Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.406454124310017, + "scoreError" : 0.018858190056667414, + "scoreConfidence" : [ + 3.3875959342533495, + 3.4253123143666846 + ], + "scorePercentiles" : { + "0.0" : 3.403381953657993, + "50.0" : 3.406207135056139, + "90.0" : 3.410020273469797, + "95.0" : 3.410020273469797, + "99.0" : 3.410020273469797, + "99.9" : 3.410020273469797, + "99.99" : 3.410020273469797, + "99.999" : 3.410020273469797, + "99.9999" : 3.410020273469797, + "100.0" : 3.410020273469797 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.403381953657993, + 3.407486239518625 + ], + [ + 3.404928030593653, + 3.410020273469797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7214546892881701, + "scoreError" : 0.004938647272620143, + "scoreConfidence" : [ + 1.71651604201555, + 1.7263933365607902 + ], + "scorePercentiles" : { + "0.0" : 1.7204864939331292, + "50.0" : 1.7215383639780086, + "90.0" : 1.7222555352635336, + "95.0" : 1.7222555352635336, + "99.0" : 1.7222555352635336, + "99.9" : 1.7222555352635336, + "99.99" : 1.7222555352635336, + "99.999" : 1.7222555352635336, + "99.9999" : 1.7222555352635336, + "100.0" : 1.7222555352635336 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7212559407094044, + 1.7204864939331292 + ], + [ + 1.721820787246613, + 1.7222555352635336 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8668132758292565, + "scoreError" : 0.008547982869116547, + "scoreConfidence" : [ + 0.85826529296014, + 0.875361258698373 + ], + "scorePercentiles" : { + "0.0" : 0.8658233476391417, + "50.0" : 0.8663400506622068, + "90.0" : 0.8687496543534708, + "95.0" : 0.8687496543534708, + "99.0" : 0.8687496543534708, + "99.9" : 0.8687496543534708, + "99.99" : 0.8687496543534708, + "99.999" : 0.8687496543534708, + "99.9999" : 0.8687496543534708, + "100.0" : 0.8687496543534708 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8658233476391417, + 0.8661502169712597 + ], + [ + 0.8665298843531537, + 0.8687496543534708 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.902287964479932, + "scoreError" : 0.11396164265965075, + "scoreConfidence" : [ + 15.78832632182028, + 16.01624960713958 + ], + "scorePercentiles" : { + "0.0" : 15.80922986452746, + "50.0" : 15.920960661790467, + "90.0" : 15.97118075881037, + "95.0" : 15.97118075881037, + "99.0" : 15.97118075881037, + "99.9" : 15.97118075881037, + "99.99" : 15.97118075881037, + "99.999" : 15.97118075881037, + "99.9999" : 15.97118075881037, + "100.0" : 15.97118075881037 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.80922986452746, + 15.824703875481319, + 15.820446126136925 + ], + [ + 15.97118075881037, + 15.956354305652036, + 15.967698445224553 + ], + [ + 15.892708365722527, + 15.920960661790467, + 15.957309276973744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2722.266736729774, + "scoreError" : 105.57849040404129, + "scoreConfidence" : [ + 2616.688246325733, + 2827.845227133815 + ], + "scorePercentiles" : { + "0.0" : 2636.873921470413, + "50.0" : 2760.8545369376047, + "90.0" : 2772.0616199852557, + "95.0" : 2772.0616199852557, + "99.0" : 2772.0616199852557, + "99.9" : 2772.0616199852557, + "99.99" : 2772.0616199852557, + "99.999" : 2772.0616199852557, + "99.9999" : 2772.0616199852557, + "100.0" : 2772.0616199852557 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2636.873921470413, + 2642.265641869794, + 2636.9323275347615 + ], + [ + 2765.7734690069874, + 2760.8545369376047, + 2772.0616199852557 + ], + [ + 2756.996665783692, + 2764.59089597599, + 2764.051552003467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69403.28294159488, + "scoreError" : 1789.5098351053073, + "scoreConfidence" : [ + 67613.77310648958, + 71192.79277670018 + ], + "scorePercentiles" : { + "0.0" : 68148.26382761766, + "50.0" : 69446.16304178763, + "90.0" : 70726.5839917201, + "95.0" : 70726.5839917201, + "99.0" : 70726.5839917201, + "99.9" : 70726.5839917201, + "99.99" : 70726.5839917201, + "99.999" : 70726.5839917201, + "99.9999" : 70726.5839917201, + "100.0" : 70726.5839917201 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69465.85758059853, + 69446.16304178763, + 68976.76943002627 + ], + [ + 68304.00362996088, + 68148.26382761766, + 68275.46953815382 + ], + [ + 70726.5839917201, + 70682.72282740971, + 70603.71260707919 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 335.70220206197814, + "scoreError" : 15.07249257701705, + "scoreConfidence" : [ + 320.6297094849611, + 350.7746946389952 + ], + "scorePercentiles" : { + "0.0" : 327.22299189736594, + "50.0" : 332.9895061687026, + "90.0" : 347.9638389367264, + "95.0" : 347.9638389367264, + "99.0" : 347.9638389367264, + "99.9" : 347.9638389367264, + "99.99" : 347.9638389367264, + "99.999" : 347.9638389367264, + "99.9999" : 347.9638389367264, + "100.0" : 347.9638389367264 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.6069929006137, + 347.9638389367264, + 347.28162821148885 + ], + [ + 333.69198738799884, + 329.7415538701372, + 332.9895061687026 + ], + [ + 327.9921801088395, + 327.22299189736594, + 327.82913907593047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 103.20240192236119, + "scoreError" : 1.7118826264673341, + "scoreConfidence" : [ + 101.49051929589386, + 104.91428454882852 + ], + "scorePercentiles" : { + "0.0" : 101.86121014089116, + "50.0" : 103.17117821314267, + "90.0" : 104.71944989338951, + "95.0" : 104.71944989338951, + "99.0" : 104.71944989338951, + "99.9" : 104.71944989338951, + "99.99" : 104.71944989338951, + "99.999" : 104.71944989338951, + "99.9999" : 104.71944989338951, + "100.0" : 104.71944989338951 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 103.14285113507162, + 103.17117821314267, + 103.41142732656795 + ], + [ + 102.26046497937386, + 101.86121014089116, + 101.98306700690846 + ], + [ + 104.00069533126559, + 104.27127327463997, + 104.71944989338951 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06280098304120152, + "scoreError" : 3.937176959420289E-4, + "scoreConfidence" : [ + 0.06240726534525949, + 0.06319470073714355 + ], + "scorePercentiles" : { + "0.0" : 0.06254160231025166, + "50.0" : 0.06279172655234555, + "90.0" : 0.06323299884917925, + "95.0" : 0.06323299884917925, + "99.0" : 0.06323299884917925, + "99.9" : 0.06323299884917925, + "99.99" : 0.06323299884917925, + "99.999" : 0.06323299884917925, + "99.9999" : 0.06323299884917925, + "100.0" : 0.06323299884917925 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06254160231025166, + 0.06256130020144389, + 0.06289950600052835 + ], + [ + 0.06279268673904444, + 0.06279172655234555, + 0.0625852339908877 + ], + [ + 0.06323299884917925, + 0.06306160496793356, + 0.06274218775919942 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.800666345175178E-4, + "scoreError" : 1.4269686166394017E-5, + "scoreConfidence" : [ + 3.657969483511238E-4, + 3.9433632068391184E-4 + ], + "scorePercentiles" : { + "0.0" : 3.683397532387197E-4, + "50.0" : 3.854766220563561E-4, + "90.0" : 3.8654012930314224E-4, + "95.0" : 3.8654012930314224E-4, + "99.0" : 3.8654012930314224E-4, + "99.9" : 3.8654012930314224E-4, + "99.99" : 3.8654012930314224E-4, + "99.999" : 3.8654012930314224E-4, + "99.9999" : 3.8654012930314224E-4, + "100.0" : 3.8654012930314224E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.859636843167263E-4, + 3.8455198181245204E-4, + 3.854766220563561E-4 + ], + [ + 3.6918629544099645E-4, + 3.6879014199807185E-4, + 3.683397532387197E-4 + ], + [ + 3.8654012930314224E-4, + 3.8552127057348224E-4, + 3.8622983191771357E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01422155170621673, + "scoreError" : 1.222545120086124E-4, + "scoreConfidence" : [ + 0.014099297194208117, + 0.014343806218225343 + ], + "scorePercentiles" : { + "0.0" : 0.014122907994599466, + "50.0" : 0.0142476932221646, + "90.0" : 0.014300206638362132, + "95.0" : 0.014300206638362132, + "99.0" : 0.014300206638362132, + "99.9" : 0.014300206638362132, + "99.99" : 0.014300206638362132, + "99.999" : 0.014300206638362132, + "99.9999" : 0.014300206638362132, + "100.0" : 0.014300206638362132 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014255982918679112, + 0.014234981336734506, + 0.0142476932221646 + ], + [ + 0.01412348233458089, + 0.014139337159864547, + 0.014122907994599466 + ], + [ + 0.014300206638362132, + 0.01428836946243565, + 0.014281004288529646 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9803882629131864, + "scoreError" : 0.020658568420889065, + "scoreConfidence" : [ + 0.9597296944922973, + 1.0010468313340755 + ], + "scorePercentiles" : { + "0.0" : 0.9592676801918465, + "50.0" : 0.9825492621340145, + "90.0" : 0.9934468711632065, + "95.0" : 0.9934468711632065, + "99.0" : 0.9934468711632065, + "99.9" : 0.9934468711632065, + "99.99" : 0.9934468711632065, + "99.999" : 0.9934468711632065, + "99.9999" : 0.9934468711632065, + "100.0" : 0.9934468711632065 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9934468711632065, + 0.9888148557445126, + 0.9868741706137754 + ], + [ + 0.9825492621340145, + 0.9926531631761787, + 0.9820926468624177 + ], + [ + 0.9592676801918465, + 0.9635445763561037, + 0.9742511399766218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013139045113127988, + "scoreError" : 8.038683793137916E-4, + "scoreConfidence" : [ + 0.012335176733814197, + 0.01394291349244178 + ], + "scorePercentiles" : { + "0.0" : 0.012814005489380022, + "50.0" : 0.013142212237676986, + "90.0" : 0.013427707323033625, + "95.0" : 0.013427707323033625, + "99.0" : 0.013427707323033625, + "99.9" : 0.013427707323033625, + "99.99" : 0.013427707323033625, + "99.999" : 0.013427707323033625, + "99.9999" : 0.013427707323033625, + "100.0" : 0.013427707323033625 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013369222135175747, + 0.013397351988253483, + 0.013427707323033625 + ], + [ + 0.012814005489380022, + 0.012915202340178225, + 0.012910781402746829 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.840400281821194, + "scoreError" : 0.07710475631475237, + "scoreConfidence" : [ + 3.7632955255064418, + 3.9175050381359466 + ], + "scorePercentiles" : { + "0.0" : 3.7997022750759877, + "50.0" : 3.8363600249409693, + "90.0" : 3.8819478875096975, + "95.0" : 3.8819478875096975, + "99.0" : 3.8819478875096975, + "99.9" : 3.8819478875096975, + "99.99" : 3.8819478875096975, + "99.999" : 3.8819478875096975, + "99.9999" : 3.8819478875096975, + "100.0" : 3.8819478875096975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.834708003834356, + 3.8819478875096975, + 3.8569279853508096 + ], + [ + 3.7997022750759877, + 3.831103493108729, + 3.8380120460475826 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.961820214803675, + "scoreError" : 0.04684169380098943, + "scoreConfidence" : [ + 2.914978521002686, + 3.0086619086046644 + ], + "scorePercentiles" : { + "0.0" : 2.9317596974494284, + "50.0" : 2.9511743021540275, + "90.0" : 2.9983626555755394, + "95.0" : 2.9983626555755394, + "99.0" : 2.9983626555755394, + "99.9" : 2.9983626555755394, + "99.99" : 2.9983626555755394, + "99.999" : 2.9983626555755394, + "99.9999" : 2.9983626555755394, + "100.0" : 2.9983626555755394 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9317596974494284, + 2.9345205044014087, + 2.936623438344099 + ], + [ + 2.9511743021540275, + 2.947147355922216, + 2.966120393534994 + ], + [ + 2.994105714071856, + 2.9983626555755394, + 2.996567871779509 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1757288501955799, + "scoreError" : 0.00513685216512485, + "scoreConfidence" : [ + 0.17059199803045505, + 0.18086570236070476 + ], + "scorePercentiles" : { + "0.0" : 0.17125731531176683, + "50.0" : 0.17670132100576033, + "90.0" : 0.17882767461239962, + "95.0" : 0.17882767461239962, + "99.0" : 0.17882767461239962, + "99.9" : 0.17882767461239962, + "99.99" : 0.17882767461239962, + "99.999" : 0.17882767461239962, + "99.9999" : 0.17882767461239962, + "100.0" : 0.17882767461239962 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1769569301741223, + 0.17670132100576033, + 0.17669613964131106 + ], + [ + 0.17275412223815365, + 0.1714712559499314, + 0.17125731531176683 + ], + [ + 0.17882767461239962, + 0.17852007883180407, + 0.17837481399496993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.34706825206330116, + "scoreError" : 0.001580435927439251, + "scoreConfidence" : [ + 0.34548781613586194, + 0.3486486879907404 + ], + "scorePercentiles" : { + "0.0" : 0.3460187886924328, + "50.0" : 0.34727262110636525, + "90.0" : 0.3483138171780851, + "95.0" : 0.3483138171780851, + "99.0" : 0.3483138171780851, + "99.9" : 0.3483138171780851, + "99.99" : 0.3483138171780851, + "99.999" : 0.3483138171780851, + "99.9999" : 0.3483138171780851, + "100.0" : 0.3483138171780851 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.34613291267176627, + 0.3461400510193486, + 0.3460187886924328 + ], + [ + 0.34794822761908073, + 0.34727262110636525, + 0.3476111665334214 + ], + [ + 0.3483138171780851, + 0.34620084740012463, + 0.34797583634908485 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15901443524647912, + "scoreError" : 0.006788045196272182, + "scoreConfidence" : [ + 0.15222639005020694, + 0.1658024804427513 + ], + "scorePercentiles" : { + "0.0" : 0.15484666245490158, + "50.0" : 0.15790013287121835, + "90.0" : 0.1641328795627626, + "95.0" : 0.1641328795627626, + "99.0" : 0.1641328795627626, + "99.9" : 0.1641328795627626, + "99.99" : 0.1641328795627626, + "99.999" : 0.1641328795627626, + "99.9999" : 0.1641328795627626, + "100.0" : 0.1641328795627626 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15799359083655898, + 0.1578523076935219, + 0.15790013287121835 + ], + [ + 0.1641328795627626, + 0.16412531186607582, + 0.16412967892136748 + ], + [ + 0.15502788157690758, + 0.15512147143499774, + 0.15484666245490158 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39415298606633214, + "scoreError" : 0.0073863990684665615, + "scoreConfidence" : [ + 0.3867665869978656, + 0.4015393851347987 + ], + "scorePercentiles" : { + "0.0" : 0.387162633255904, + "50.0" : 0.3951555636780337, + "90.0" : 0.4017765369224588, + "95.0" : 0.4017765369224588, + "99.0" : 0.4017765369224588, + "99.9" : 0.4017765369224588, + "99.99" : 0.4017765369224588, + "99.999" : 0.4017765369224588, + "99.9999" : 0.4017765369224588, + "100.0" : 0.4017765369224588 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3951555636780337, + 0.387162633255904, + 0.38800434348568325 + ], + [ + 0.39662847281164476, + 0.3953628665691468, + 0.3951758637082115 + ], + [ + 0.4017765369224588, + 0.39381700567085415, + 0.39429358849505186 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15758703083047398, + "scoreError" : 0.005201091754230971, + "scoreConfidence" : [ + 0.152385939076243, + 0.16278812258470496 + ], + "scorePercentiles" : { + "0.0" : 0.15472419694273823, + "50.0" : 0.15595056361112844, + "90.0" : 0.1617285585367037, + "95.0" : 0.1617285585367037, + "99.0" : 0.1617285585367037, + "99.9" : 0.1617285585367037, + "99.99" : 0.1617285585367037, + "99.999" : 0.1617285585367037, + "99.9999" : 0.1617285585367037, + "100.0" : 0.1617285585367037 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15483804412789348, + 0.1558617654650021, + 0.15472419694273823 + ], + [ + 0.16167252702287607, + 0.1617285585367037, + 0.16159403569524117 + ], + [ + 0.15595056361112844, + 0.15604103013091578, + 0.15587255594176694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048128917200255104, + "scoreError" : 0.001081398938893643, + "scoreConfidence" : [ + 0.047047518261361464, + 0.049210316139148745 + ], + "scorePercentiles" : { + "0.0" : 0.04691966639610009, + "50.0" : 0.048270016783156025, + "90.0" : 0.049073969491159455, + "95.0" : 0.049073969491159455, + "99.0" : 0.049073969491159455, + "99.9" : 0.049073969491159455, + "99.99" : 0.049073969491159455, + "99.999" : 0.049073969491159455, + "99.9999" : 0.049073969491159455, + "100.0" : 0.049073969491159455 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047598662782672434, + 0.04691966639610009, + 0.04762934602158527 + ], + [ + 0.049073969491159455, + 0.048270016783156025, + 0.048181095204598345 + ], + [ + 0.04849201205981903, + 0.04850977500036382, + 0.04848571106284152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9451596.3953978, + "scoreError" : 178389.00774169658, + "scoreConfidence" : [ + 9273207.387656102, + 9629985.403139496 + ], + "scorePercentiles" : { + "0.0" : 9312494.095903166, + "50.0" : 9479242.483412322, + "90.0" : 9571400.162679426, + "95.0" : 9571400.162679426, + "99.0" : 9571400.162679426, + "99.9" : 9571400.162679426, + "99.99" : 9571400.162679426, + "99.999" : 9571400.162679426, + "99.9999" : 9571400.162679426, + "100.0" : 9571400.162679426 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9479242.483412322, + 9467233.308420056, + 9499272.824311491 + ], + [ + 9528669.641904762, + 9571400.162679426, + 9564784.041108986 + ], + [ + 9312494.095903166, + 9328251.902143523, + 9313019.098696461 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:13:31Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:13:31Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..b5cdb60176 --- /dev/null +++ b/performance-results/2025-03-24T01:13:31Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.422918226767772, + "scoreError" : 0.018333149688673566, + "scoreConfidence" : [ + 3.404585077079098, + 3.4412513764564454 + ], + "scorePercentiles" : { + "0.0" : 3.419464583762408, + "50.0" : 3.422947389990944, + "90.0" : 3.426313543326791, + "95.0" : 3.426313543326791, + "99.0" : 3.426313543326791, + "99.9" : 3.426313543326791, + "99.99" : 3.426313543326791, + "99.999" : 3.426313543326791, + "99.9999" : 3.426313543326791, + "100.0" : 3.426313543326791 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.419464583762408, + 3.426313543326791 + ], + [ + 3.4223602521562295, + 3.4235345278256584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7248233246272615, + "scoreError" : 0.023643110989649992, + "scoreConfidence" : [ + 1.7011802136376115, + 1.7484664356169115 + ], + "scorePercentiles" : { + "0.0" : 1.7201482102136298, + "50.0" : 1.7253085313214631, + "90.0" : 1.7285280256524898, + "95.0" : 1.7285280256524898, + "99.0" : 1.7285280256524898, + "99.9" : 1.7285280256524898, + "99.99" : 1.7285280256524898, + "99.999" : 1.7285280256524898, + "99.9999" : 1.7285280256524898, + "100.0" : 1.7285280256524898 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7201482102136298, + 1.723875345355189 + ], + [ + 1.7267417172877373, + 1.7285280256524898 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8691911317000947, + "scoreError" : 0.002655907669193238, + "scoreConfidence" : [ + 0.8665352240309014, + 0.8718470393692879 + ], + "scorePercentiles" : { + "0.0" : 0.8686357338501872, + "50.0" : 0.869250861572249, + "90.0" : 0.8696270698056936, + "95.0" : 0.8696270698056936, + "99.0" : 0.8696270698056936, + "99.9" : 0.8696270698056936, + "99.99" : 0.8696270698056936, + "99.999" : 0.8696270698056936, + "99.9999" : 0.8696270698056936, + "100.0" : 0.8696270698056936 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8686357338501872, + 0.8696270698056936 + ], + [ + 0.869274635006496, + 0.869227088138002 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.269713337427504, + "scoreError" : 0.14438877525995078, + "scoreConfidence" : [ + 16.125324562167553, + 16.414102112687456 + ], + "scorePercentiles" : { + "0.0" : 16.117858602831706, + "50.0" : 16.322456788864862, + "90.0" : 16.348479604511603, + "95.0" : 16.348479604511603, + "99.0" : 16.348479604511603, + "99.9" : 16.348479604511603, + "99.99" : 16.348479604511603, + "99.999" : 16.348479604511603, + "99.9999" : 16.348479604511603, + "100.0" : 16.348479604511603 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.322854104364346, + 16.335474903690017, + 16.348479604511603 + ], + [ + 16.28551807447759, + 16.322456788864862, + 16.331614273616157 + ], + [ + 16.192817675350103, + 16.117858602831706, + 16.170346009141166 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2705.9594158818363, + "scoreError" : 192.99783864660245, + "scoreConfidence" : [ + 2512.961577235234, + 2898.9572545284386 + ], + "scorePercentiles" : { + "0.0" : 2577.247939215522, + "50.0" : 2692.3021417137543, + "90.0" : 2850.8813638762285, + "95.0" : 2850.8813638762285, + "99.0" : 2850.8813638762285, + "99.9" : 2850.8813638762285, + "99.99" : 2850.8813638762285, + "99.999" : 2850.8813638762285, + "99.9999" : 2850.8813638762285, + "100.0" : 2850.8813638762285 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2692.3021417137543, + 2695.2601082938186, + 2691.307173319121 + ], + [ + 2850.8813638762285, + 2843.8230950227876, + 2838.84709036833 + ], + [ + 2577.892907020788, + 2577.247939215522, + 2586.0729241061736 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70330.90293571194, + "scoreError" : 1814.8467265792697, + "scoreConfidence" : [ + 68516.05620913267, + 72145.74966229121 + ], + "scorePercentiles" : { + "0.0" : 69039.15347272958, + "50.0" : 70411.6312894578, + "90.0" : 71564.1567915699, + "95.0" : 71564.1567915699, + "99.0" : 71564.1567915699, + "99.9" : 71564.1567915699, + "99.99" : 71564.1567915699, + "99.999" : 71564.1567915699, + "99.9999" : 71564.1567915699, + "100.0" : 71564.1567915699 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69039.15347272958, + 69066.18990884532, + 69044.98069845003 + ], + [ + 71510.90218062312, + 71564.1567915699, + 71545.78744063577 + ], + [ + 70349.9073863051, + 70411.6312894578, + 70445.41725279074 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.8932895289724, + "scoreError" : 6.778917399249856, + "scoreConfidence" : [ + 351.11437212972254, + 364.67220692822224 + ], + "scorePercentiles" : { + "0.0" : 354.3820744687182, + "50.0" : 355.97315553038175, + "90.0" : 363.8908628823784, + "95.0" : 363.8908628823784, + "99.0" : 363.8908628823784, + "99.9" : 363.8908628823784, + "99.99" : 363.8908628823784, + "99.999" : 363.8908628823784, + "99.9999" : 363.8908628823784, + "100.0" : 363.8908628823784 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.9125115105426, + 354.68922837188575, + 354.3820744687182 + ], + [ + 355.97315553038175, + 356.6277140587543, + 354.96717029330796 + ], + [ + 363.4166848352348, + 363.8908628823784, + 362.1802038095481 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 109.31292831463014, + "scoreError" : 1.96493773221573, + "scoreConfidence" : [ + 107.34799058241441, + 111.27786604684587 + ], + "scorePercentiles" : { + "0.0" : 107.69539614027994, + "50.0" : 109.76809662718475, + "90.0" : 110.36454561045173, + "95.0" : 110.36454561045173, + "99.0" : 110.36454561045173, + "99.9" : 110.36454561045173, + "99.99" : 110.36454561045173, + "99.999" : 110.36454561045173, + "99.9999" : 110.36454561045173, + "100.0" : 110.36454561045173 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.69539614027994, + 107.86202400330613, + 107.81319167511278 + ], + [ + 110.34968849825734, + 110.36069523704057, + 110.36454561045173 + ], + [ + 109.75382660904711, + 109.76809662718475, + 109.84889043099095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06115231415443667, + "scoreError" : 2.7757492177696216E-4, + "scoreConfidence" : [ + 0.06087473923265971, + 0.061429889076213634 + ], + "scorePercentiles" : { + "0.0" : 0.06093074006080805, + "50.0" : 0.061178577077903806, + "90.0" : 0.061452698443424346, + "95.0" : 0.061452698443424346, + "99.0" : 0.061452698443424346, + "99.9" : 0.061452698443424346, + "99.99" : 0.061452698443424346, + "99.999" : 0.061452698443424346, + "99.9999" : 0.061452698443424346, + "100.0" : 0.061452698443424346 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06108022874890821, + 0.06096968443097709, + 0.06093074006080805 + ], + [ + 0.061178577077903806, + 0.0612031103474445, + 0.061452698443424346 + ], + [ + 0.06119962405600911, + 0.0613076285420013, + 0.061048535682453636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6351884197456766E-4, + "scoreError" : 1.1708507477707113E-5, + "scoreConfidence" : [ + 3.5181033449686053E-4, + 3.752273494522748E-4 + ], + "scorePercentiles" : { + "0.0" : 3.542770620589208E-4, + "50.0" : 3.669356435358375E-4, + "90.0" : 3.6963335624417025E-4, + "95.0" : 3.6963335624417025E-4, + "99.0" : 3.6963335624417025E-4, + "99.9" : 3.6963335624417025E-4, + "99.99" : 3.6963335624417025E-4, + "99.999" : 3.6963335624417025E-4, + "99.9999" : 3.6963335624417025E-4, + "100.0" : 3.6963335624417025E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.693484092028624E-4, + 3.6963335624417025E-4, + 3.6946049352507286E-4 + ], + [ + 3.542770620589208E-4, + 3.5438673282758176E-4, + 3.5446827063455045E-4 + ], + [ + 3.660474383407284E-4, + 3.669356435358375E-4, + 3.6711217140138446E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014040306639199382, + "scoreError" : 2.189874459994869E-4, + "scoreConfidence" : [ + 0.013821319193199894, + 0.01425929408519887 + ], + "scorePercentiles" : { + "0.0" : 0.013873872933511657, + "50.0" : 0.014066023999178553, + "90.0" : 0.014185114222814207, + "95.0" : 0.014185114222814207, + "99.0" : 0.014185114222814207, + "99.9" : 0.014185114222814207, + "99.99" : 0.014185114222814207, + "99.999" : 0.014185114222814207, + "99.9999" : 0.014185114222814207, + "100.0" : 0.014185114222814207 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013873872933511657, + 0.013874219684504072, + 0.013887816720458182 + ], + [ + 0.014062647974788746, + 0.014070673822931002, + 0.014066023999178553 + ], + [ + 0.014172631385231997, + 0.014185114222814207, + 0.014169759009376014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9742580802486356, + "scoreError" : 0.025198240489418596, + "scoreConfidence" : [ + 0.949059839759217, + 0.9994563207380541 + ], + "scorePercentiles" : { + "0.0" : 0.9591472857964899, + "50.0" : 0.9688832565394303, + "90.0" : 0.9961906805458711, + "95.0" : 0.9961906805458711, + "99.0" : 0.9961906805458711, + "99.9" : 0.9961906805458711, + "99.99" : 0.9961906805458711, + "99.999" : 0.9961906805458711, + "99.9999" : 0.9961906805458711, + "100.0" : 0.9961906805458711 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9896558599703117, + 0.9947686386153387, + 0.9961906805458711 + ], + [ + 0.9688832565394303, + 0.9673317737473399, + 0.9690521334302326 + ], + [ + 0.9591472857964899, + 0.9638375641865844, + 0.9594555294061211 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01304551071126541, + "scoreError" : 4.5378102190033647E-4, + "scoreConfidence" : [ + 0.012591729689365073, + 0.013499291733165745 + ], + "scorePercentiles" : { + "0.0" : 0.012846069177073887, + "50.0" : 0.0130605302303139, + "90.0" : 0.013192607064739887, + "95.0" : 0.013192607064739887, + "99.0" : 0.013192607064739887, + "99.9" : 0.013192607064739887, + "99.99" : 0.013192607064739887, + "99.999" : 0.013192607064739887, + "99.9999" : 0.013192607064739887, + "100.0" : 0.013192607064739887 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012846069177073887, + 0.012922527678061463, + 0.012932401976023898 + ], + [ + 0.013188658484603901, + 0.013192607064739887, + 0.013190799887089414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6124515862232065, + "scoreError" : 0.3329195335223676, + "scoreConfidence" : [ + 3.279532052700839, + 3.945371119745574 + ], + "scorePercentiles" : { + "0.0" : 3.4783565465924897, + "50.0" : 3.6183021933966506, + "90.0" : 3.7219963913690477, + "95.0" : 3.7219963913690477, + "99.0" : 3.7219963913690477, + "99.9" : 3.7219963913690477, + "99.99" : 3.7219963913690477, + "99.999" : 3.7219963913690477, + "99.9999" : 3.7219963913690477, + "100.0" : 3.7219963913690477 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4783565465924897, + 3.51792920745429, + 3.518397646272855 + ], + [ + 3.7198229851301114, + 3.7219963913690477, + 3.718206740520446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.820564883208848, + "scoreError" : 0.07635244025538424, + "scoreConfidence" : [ + 2.744212442953464, + 2.896917323464232 + ], + "scorePercentiles" : { + "0.0" : 2.7563458605676496, + "50.0" : 2.8488649763600113, + "90.0" : 2.856326268989149, + "95.0" : 2.856326268989149, + "99.0" : 2.856326268989149, + "99.9" : 2.856326268989149, + "99.99" : 2.856326268989149, + "99.999" : 2.856326268989149, + "99.9999" : 2.856326268989149, + "100.0" : 2.856326268989149 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8540345976027397, + 2.853888280171184, + 2.8488649763600113 + ], + [ + 2.856326268989149, + 2.8520386968919302, + 2.8387283894408175 + ], + [ + 2.763057338121547, + 2.7617995407346037, + 2.7563458605676496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18422658410785747, + "scoreError" : 0.025242427508284763, + "scoreConfidence" : [ + 0.1589841565995727, + 0.20946901161614223 + ], + "scorePercentiles" : { + "0.0" : 0.1730692323907099, + "50.0" : 0.1752739016387696, + "90.0" : 0.20461711738587768, + "95.0" : 0.20461711738587768, + "99.0" : 0.20461711738587768, + "99.9" : 0.20461711738587768, + "99.99" : 0.20461711738587768, + "99.999" : 0.20461711738587768, + "99.9999" : 0.20461711738587768, + "100.0" : 0.20461711738587768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1732926723621051, + 0.1730692323907099, + 0.17307003277894117 + ], + [ + 0.1751855069546633, + 0.17550739095105214, + 0.1752739016387696 + ], + [ + 0.20461711738587768, + 0.2041418652295507, + 0.20388153727904748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3313797971859773, + "scoreError" : 0.020569230998265856, + "scoreConfidence" : [ + 0.31081056618771147, + 0.3519490281842432 + ], + "scorePercentiles" : { + "0.0" : 0.3170424942616194, + "50.0" : 0.33000916014916015, + "90.0" : 0.3460290239100346, + "95.0" : 0.3460290239100346, + "99.0" : 0.3460290239100346, + "99.9" : 0.3460290239100346, + "99.99" : 0.3460290239100346, + "99.999" : 0.3460290239100346, + "99.9999" : 0.3460290239100346, + "100.0" : 0.3460290239100346 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33180670217989977, + 0.3296485476661392, + 0.33000916014916015 + ], + [ + 0.31890494929523566, + 0.3172751786541451, + 0.3170424942616194 + ], + [ + 0.3460290239100346, + 0.34592098360372203, + 0.3457811349538398 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1549902340662419, + "scoreError" : 0.003544496616706501, + "scoreConfidence" : [ + 0.1514457374495354, + 0.1585347306829484 + ], + "scorePercentiles" : { + "0.0" : 0.15323426649913424, + "50.0" : 0.15390085390439842, + "90.0" : 0.15797860720999668, + "95.0" : 0.15797860720999668, + "99.0" : 0.15797860720999668, + "99.9" : 0.15797860720999668, + "99.99" : 0.15797860720999668, + "99.999" : 0.15797860720999668, + "99.9999" : 0.15797860720999668, + "100.0" : 0.15797860720999668 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15344080177374067, + 0.1533190904407819, + 0.15323426649913424 + ], + [ + 0.15797860720999668, + 0.15759360946167422, + 0.1577704870314275 + ], + [ + 0.15390085390439842, + 0.15396346709878064, + 0.15371092317624274 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.397097650470543, + "scoreError" : 0.024930142478511705, + "scoreConfidence" : [ + 0.3721675079920313, + 0.42202779294905474 + ], + "scorePercentiles" : { + "0.0" : 0.38140312475209764, + "50.0" : 0.39157604408943186, + "90.0" : 0.4164570443509766, + "95.0" : 0.4164570443509766, + "99.0" : 0.4164570443509766, + "99.9" : 0.4164570443509766, + "99.99" : 0.4164570443509766, + "99.999" : 0.4164570443509766, + "99.9999" : 0.4164570443509766, + "100.0" : 0.4164570443509766 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4161600940491053, + 0.41621297852416034, + 0.4164570443509766 + ], + [ + 0.39187239076766334, + 0.39157604408943186, + 0.3909906981272237 + ], + [ + 0.3859372891710404, + 0.38326919040318874, + 0.38140312475209764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15905829126011567, + "scoreError" : 0.00219234128808664, + "scoreConfidence" : [ + 0.15686594997202902, + 0.16125063254820232 + ], + "scorePercentiles" : { + "0.0" : 0.1576184559467894, + "50.0" : 0.15896080007947863, + "90.0" : 0.1610654456255637, + "95.0" : 0.1610654456255637, + "99.0" : 0.1610654456255637, + "99.9" : 0.1610654456255637, + "99.99" : 0.1610654456255637, + "99.999" : 0.1610654456255637, + "99.9999" : 0.1610654456255637, + "100.0" : 0.1610654456255637 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15821193833059105, + 0.1578200735433369, + 0.1576240174644957 + ], + [ + 0.16021311116985484, + 0.15896080007947863, + 0.1576184559467894 + ], + [ + 0.1610654456255637, + 0.16019364413866016, + 0.15981713504227063 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047881073265585855, + "scoreError" : 7.391661947761921E-4, + "scoreConfidence" : [ + 0.04714190707080966, + 0.04862023946036205 + ], + "scorePercentiles" : { + "0.0" : 0.04747618604695326, + "50.0" : 0.04758646360404859, + "90.0" : 0.04868108797986584, + "95.0" : 0.04868108797986584, + "99.0" : 0.04868108797986584, + "99.9" : 0.04868108797986584, + "99.99" : 0.04868108797986584, + "99.999" : 0.04868108797986584, + "99.9999" : 0.04868108797986584, + "100.0" : 0.04868108797986584 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047553612824073194, + 0.04753731592858094, + 0.04747618604695326 + ], + [ + 0.04868108797986584, + 0.04828521061678561, + 0.048222274048105855 + ], + [ + 0.04805520271315781, + 0.04758646360404859, + 0.04753230562870153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9271893.135588221, + "scoreError" : 226020.91233735438, + "scoreConfidence" : [ + 9045872.223250866, + 9497914.047925577 + ], + "scorePercentiles" : { + "0.0" : 9089321.821071753, + "50.0" : 9271490.395736793, + "90.0" : 9463506.104068117, + "95.0" : 9463506.104068117, + "99.0" : 9463506.104068117, + "99.9" : 9463506.104068117, + "99.99" : 9463506.104068117, + "99.999" : 9463506.104068117, + "99.9999" : 9463506.104068117, + "100.0" : 9463506.104068117 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9463506.104068117, + 9412204.553151459, + 9399670.632518796 + ], + [ + 9271490.395736793, + 9270540.29935125, + 9273005.521779425 + ], + [ + 9148431.066727605, + 9118867.825888788, + 9089321.821071753 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:13:36Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:13:36Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..fba2b47404 --- /dev/null +++ b/performance-results/2025-03-24T01:13:36Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4255027365084705, + "scoreError" : 0.015268297622684238, + "scoreConfidence" : [ + 3.4102344388857864, + 3.4407710341311546 + ], + "scorePercentiles" : { + "0.0" : 3.423680586656175, + "50.0" : 3.4247710163271283, + "90.0" : 3.42878832672345, + "95.0" : 3.42878832672345, + "99.0" : 3.42878832672345, + "99.9" : 3.42878832672345, + "99.99" : 3.42878832672345, + "99.999" : 3.42878832672345, + "99.9999" : 3.42878832672345, + "100.0" : 3.42878832672345 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4256547896178025, + 3.42878832672345 + ], + [ + 3.423680586656175, + 3.423887243036454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.72787103241473, + "scoreError" : 0.015311326619137618, + "scoreConfidence" : [ + 1.7125597057955924, + 1.7431823590338675 + ], + "scorePercentiles" : { + "0.0" : 1.7258301618950143, + "50.0" : 1.72761015824926, + "90.0" : 1.7304336512653857, + "95.0" : 1.7304336512653857, + "99.0" : 1.7304336512653857, + "99.9" : 1.7304336512653857, + "99.99" : 1.7304336512653857, + "99.999" : 1.7304336512653857, + "99.9999" : 1.7304336512653857, + "100.0" : 1.7304336512653857 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.729338528385661, + 1.7304336512653857 + ], + [ + 1.7258301618950143, + 1.725881788112859 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8675124306454595, + "scoreError" : 0.005320038114788069, + "scoreConfidence" : [ + 0.8621923925306714, + 0.8728324687602476 + ], + "scorePercentiles" : { + "0.0" : 0.8666706939441462, + "50.0" : 0.8675694953743074, + "90.0" : 0.8682400378890769, + "95.0" : 0.8682400378890769, + "99.0" : 0.8682400378890769, + "99.9" : 0.8682400378890769, + "99.99" : 0.8682400378890769, + "99.999" : 0.8682400378890769, + "99.9999" : 0.8682400378890769, + "100.0" : 0.8682400378890769 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8681975610402533, + 0.8669414297083615 + ], + [ + 0.8666706939441462, + 0.8682400378890769 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.08387646024225, + "scoreError" : 0.28169323607593694, + "scoreConfidence" : [ + 15.802183224166315, + 16.36556969631819 + ], + "scorePercentiles" : { + "0.0" : 15.857648305820325, + "50.0" : 16.169853409735502, + "90.0" : 16.220922945381865, + "95.0" : 16.220922945381865, + "99.0" : 16.220922945381865, + "99.9" : 16.220922945381865, + "99.99" : 16.220922945381865, + "99.999" : 16.220922945381865, + "99.9999" : 16.220922945381865, + "100.0" : 16.220922945381865 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.86268753833565, + 15.857648305820325, + 15.86481780525936 + ], + [ + 16.220922945381865, + 16.214595465849875, + 16.210400315425794 + ], + [ + 16.169747624196056, + 16.184214732175867, + 16.169853409735502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2714.00827636627, + "scoreError" : 55.61639089855765, + "scoreConfidence" : [ + 2658.391885467712, + 2769.6246672648276 + ], + "scorePercentiles" : { + "0.0" : 2667.708875949212, + "50.0" : 2717.824085599261, + "90.0" : 2754.3955765089468, + "95.0" : 2754.3955765089468, + "99.0" : 2754.3955765089468, + "99.9" : 2754.3955765089468, + "99.99" : 2754.3955765089468, + "99.999" : 2754.3955765089468, + "99.9999" : 2754.3955765089468, + "100.0" : 2754.3955765089468 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2710.520618895013, + 2717.824085599261, + 2719.7067761834132 + ], + [ + 2683.136600437227, + 2674.865175131134, + 2667.708875949212 + ], + [ + 2749.5732786152225, + 2748.3434999769956, + 2754.3955765089468 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70426.43446172662, + "scoreError" : 903.3310026109199, + "scoreConfidence" : [ + 69523.1034591157, + 71329.76546433754 + ], + "scorePercentiles" : { + "0.0" : 69722.5379226521, + "50.0" : 70645.27630459232, + "90.0" : 70965.6169677315, + "95.0" : 70965.6169677315, + "99.0" : 70965.6169677315, + "99.9" : 70965.6169677315, + "99.99" : 70965.6169677315, + "99.999" : 70965.6169677315, + "99.9999" : 70965.6169677315, + "100.0" : 70965.6169677315 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69722.5379226521, + 69731.8772056881, + 69731.03011934547 + ], + [ + 70564.19048055039, + 70645.27630459232, + 70728.42014552624 + ], + [ + 70965.6169677315, + 70872.53267611962, + 70876.42833333378 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.15213022456425, + "scoreError" : 5.601239292143671, + "scoreConfidence" : [ + 341.5508909324206, + 352.7533695167079 + ], + "scorePercentiles" : { + "0.0" : 342.43002863553767, + "50.0" : 348.0046593211147, + "90.0" : 350.7291616178739, + "95.0" : 350.7291616178739, + "99.0" : 350.7291616178739, + "99.9" : 350.7291616178739, + "99.99" : 350.7291616178739, + "99.999" : 350.7291616178739, + "99.9999" : 350.7291616178739, + "100.0" : 350.7291616178739 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 350.6492554423494, + 350.7291616178739, + 349.088136414228 + ], + [ + 348.0046593211147, + 349.4400643546579, + 347.65661947655303 + ], + [ + 342.93217357156874, + 343.43907318719454, + 342.43002863553767 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 103.225095253805, + "scoreError" : 2.632840318025602, + "scoreConfidence" : [ + 100.5922549357794, + 105.8579355718306 + ], + "scorePercentiles" : { + "0.0" : 101.82354108992503, + "50.0" : 102.27286704928098, + "90.0" : 105.37862607434907, + "95.0" : 105.37862607434907, + "99.0" : 105.37862607434907, + "99.9" : 105.37862607434907, + "99.99" : 105.37862607434907, + "99.999" : 105.37862607434907, + "99.9999" : 105.37862607434907, + "100.0" : 105.37862607434907 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.82354108992503, + 102.14092633561962, + 102.25810535530064 + ], + [ + 105.21616990044764, + 105.31650086545383, + 105.37862607434907 + ], + [ + 102.26552728272861, + 102.35359333113948, + 102.27286704928098 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06230045880514185, + "scoreError" : 7.518182294873389E-4, + "scoreConfidence" : [ + 0.06154864057565451, + 0.06305227703462919 + ], + "scorePercentiles" : { + "0.0" : 0.06176947449890361, + "50.0" : 0.06223176112687626, + "90.0" : 0.06286822427938264, + "95.0" : 0.06286822427938264, + "99.0" : 0.06286822427938264, + "99.9" : 0.06286822427938264, + "99.99" : 0.06286822427938264, + "99.999" : 0.06286822427938264, + "99.9999" : 0.06286822427938264, + "100.0" : 0.06286822427938264 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06281667806351919, + 0.06284513343681657, + 0.06286822427938264 + ], + [ + 0.06177516175562145, + 0.0619247579401693, + 0.06176947449890361 + ], + [ + 0.06223176112687626, + 0.062192614485705226, + 0.06228032365928242 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.784185944753912E-4, + "scoreError" : 2.9961168533700172E-5, + "scoreConfidence" : [ + 3.4845742594169103E-4, + 4.083797630090914E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5462576541199346E-4, + "50.0" : 3.8776968823675393E-4, + "90.0" : 3.932338892053513E-4, + "95.0" : 3.932338892053513E-4, + "99.0" : 3.932338892053513E-4, + "99.9" : 3.932338892053513E-4, + "99.99" : 3.932338892053513E-4, + "99.999" : 3.932338892053513E-4, + "99.9999" : 3.932338892053513E-4, + "100.0" : 3.932338892053513E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.932338892053513E-4, + 3.921218514055642E-4, + 3.9255882731871754E-4 + ], + [ + 3.8776968823675393E-4, + 3.8844496690490987E-4, + 3.871850316723476E-4 + ], + [ + 3.548904501436881E-4, + 3.549368799791953E-4, + 3.5462576541199346E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014112566362291336, + "scoreError" : 1.1457189642839478E-4, + "scoreConfidence" : [ + 0.013997994465862942, + 0.01422713825871973 + ], + "scorePercentiles" : { + "0.0" : 0.014037298399628298, + "50.0" : 0.014102882472316397, + "90.0" : 0.014198602709345268, + "95.0" : 0.014198602709345268, + "99.0" : 0.014198602709345268, + "99.9" : 0.014198602709345268, + "99.99" : 0.014198602709345268, + "99.999" : 0.014198602709345268, + "99.9999" : 0.014198602709345268, + "100.0" : 0.014198602709345268 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01419368768628965, + 0.01419327041108878, + 0.014198602709345268 + ], + [ + 0.014111649840610857, + 0.014102882472316397, + 0.014096726636716178 + ], + [ + 0.014038897584779789, + 0.014040081519846797, + 0.014037298399628298 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.98631598312936, + "scoreError" : 0.008020690408102148, + "scoreConfidence" : [ + 0.9782952927212578, + 0.9943366735374621 + ], + "scorePercentiles" : { + "0.0" : 0.978657759761229, + "50.0" : 0.9860868756655492, + "90.0" : 0.9935871373075013, + "95.0" : 0.9935871373075013, + "99.0" : 0.9935871373075013, + "99.9" : 0.9935871373075013, + "99.99" : 0.9935871373075013, + "99.999" : 0.9935871373075013, + "99.9999" : 0.9935871373075013, + "100.0" : 0.9935871373075013 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9887167659911024, + 0.9916675884977689, + 0.9851070933806146 + ], + [ + 0.9855722197693899, + 0.9869512607322609, + 0.9860868756655492 + ], + [ + 0.978657759761229, + 0.9804971470588235, + 0.9935871373075013 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01313144176204755, + "scoreError" : 5.18352424928154E-4, + "scoreConfidence" : [ + 0.012613089337119396, + 0.013649794186975706 + ], + "scorePercentiles" : { + "0.0" : 0.012891570798741814, + "50.0" : 0.013147115764235705, + "90.0" : 0.013308197912812965, + "95.0" : 0.013308197912812965, + "99.0" : 0.013308197912812965, + "99.9" : 0.013308197912812965, + "99.99" : 0.013308197912812965, + "99.999" : 0.013308197912812965, + "99.9999" : 0.013308197912812965, + "100.0" : 0.013308197912812965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013296880921925651, + 0.013308197912812965, + 0.013281904583173956 + ], + [ + 0.012891570798741814, + 0.012997769410333461, + 0.013012326945297454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.7079852049983484, + "scoreError" : 0.11627454463127139, + "scoreConfidence" : [ + 3.591710660367077, + 3.82425974962962 + ], + "scorePercentiles" : { + "0.0" : 3.6668081752199413, + "50.0" : 3.695892137459865, + "90.0" : 3.7589851232156275, + "95.0" : 3.7589851232156275, + "99.0" : 3.7589851232156275, + "99.9" : 3.7589851232156275, + "99.99" : 3.7589851232156275, + "99.999" : 3.7589851232156275, + "99.9999" : 3.7589851232156275, + "100.0" : 3.7589851232156275 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6668081752199413, + 3.6728324199706313, + 3.6832431259204714 + ], + [ + 3.7085411489992586, + 3.7589851232156275, + 3.7575012366641625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8926147839484724, + "scoreError" : 0.09645934758523785, + "scoreConfidence" : [ + 2.7961554363632346, + 2.98907413153371 + ], + "scorePercentiles" : { + "0.0" : 2.8026243536004483, + "50.0" : 2.921494793456033, + "90.0" : 2.9457562176730487, + "95.0" : 2.9457562176730487, + "99.0" : 2.9457562176730487, + "99.9" : 2.9457562176730487, + "99.99" : 2.9457562176730487, + "99.999" : 2.9457562176730487, + "99.9999" : 2.9457562176730487, + "100.0" : 2.9457562176730487 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9457562176730487, + 2.93675267498532, + 2.921494793456033 + ], + [ + 2.9296250128881076, + 2.927352605209248, + 2.920907433995327 + ], + [ + 2.823672700169396, + 2.825347263559322, + 2.8026243536004483 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18133326474609845, + "scoreError" : 0.01346855229269323, + "scoreConfidence" : [ + 0.16786471245340523, + 0.19480181703879168 + ], + "scorePercentiles" : { + "0.0" : 0.1740499499269006, + "50.0" : 0.17767172076041574, + "90.0" : 0.1920147274821912, + "95.0" : 0.1920147274821912, + "99.0" : 0.1920147274821912, + "99.9" : 0.1920147274821912, + "99.99" : 0.1920147274821912, + "99.999" : 0.1920147274821912, + "99.9999" : 0.1920147274821912, + "100.0" : 0.1920147274821912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17821891932207015, + 0.17765134902559912, + 0.17767172076041574 + ], + [ + 0.1743843624315558, + 0.17456054072406088, + 0.1740499499269006 + ], + [ + 0.1920147274821912, + 0.19182560413949207, + 0.19162220890260026 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3367788147831052, + "scoreError" : 0.02374465315352348, + "scoreConfidence" : [ + 0.3130341616295817, + 0.36052346793662865 + ], + "scorePercentiles" : { + "0.0" : 0.32071956720438727, + "50.0" : 0.33412888810184105, + "90.0" : 0.35441121898146505, + "95.0" : 0.35441121898146505, + "99.0" : 0.35441121898146505, + "99.9" : 0.35441121898146505, + "99.99" : 0.35441121898146505, + "99.999" : 0.35441121898146505, + "99.9999" : 0.35441121898146505, + "100.0" : 0.35441121898146505 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.35441121898146505, + 0.3540245686975608, + 0.35409223429643794 + ], + [ + 0.32071956720438727, + 0.32220562051744694, + 0.3226218893118689 + ], + [ + 0.33409698326206066, + 0.33470836267487786, + 0.33412888810184105 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16858839828710112, + "scoreError" : 0.010531615699214387, + "scoreConfidence" : [ + 0.15805678258788675, + 0.1791200139863155 + ], + "scorePercentiles" : { + "0.0" : 0.16052026189826482, + "50.0" : 0.17016409602164442, + "90.0" : 0.17525053695979811, + "95.0" : 0.17525053695979811, + "99.0" : 0.17525053695979811, + "99.9" : 0.17525053695979811, + "99.99" : 0.17525053695979811, + "99.999" : 0.17525053695979811, + "99.9999" : 0.17525053695979811, + "100.0" : 0.17525053695979811 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17016409602164442, + 0.17025412281866625, + 0.17014017352320676 + ], + [ + 0.17525053695979811, + 0.17473462677569848, + 0.17468118482741754 + ], + [ + 0.16098750687401397, + 0.16052026189826482, + 0.16056307488519958 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39153306316745484, + "scoreError" : 0.011987780396202052, + "scoreConfidence" : [ + 0.37954528277125277, + 0.4035208435636569 + ], + "scorePercentiles" : { + "0.0" : 0.3824763335883118, + "50.0" : 0.3891833180261519, + "90.0" : 0.405713951357053, + "95.0" : 0.405713951357053, + "99.0" : 0.405713951357053, + "99.9" : 0.405713951357053, + "99.99" : 0.405713951357053, + "99.999" : 0.405713951357053, + "99.9999" : 0.405713951357053, + "100.0" : 0.405713951357053 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.405713951357053, + 0.39427057364768964, + 0.39585323267228756 + ], + [ + 0.3959599306303453, + 0.3891833180261519, + 0.3883369830304442 + ], + [ + 0.3868123861834217, + 0.38519085937138897, + 0.3824763335883118 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15836425098734164, + "scoreError" : 0.001008748099331414, + "scoreConfidence" : [ + 0.15735550288801023, + 0.15937299908667305 + ], + "scorePercentiles" : { + "0.0" : 0.1578140798838512, + "50.0" : 0.15816451689942587, + "90.0" : 0.159676068308105, + "95.0" : 0.159676068308105, + "99.0" : 0.159676068308105, + "99.9" : 0.159676068308105, + "99.99" : 0.159676068308105, + "99.999" : 0.159676068308105, + "99.9999" : 0.159676068308105, + "100.0" : 0.159676068308105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15865113410435802, + 0.15809743934675036, + 0.15790347873869037 + ], + [ + 0.15876646168256942, + 0.159676068308105, + 0.1583807269876465 + ], + [ + 0.1578140798838512, + 0.15782435293467797, + 0.15816451689942587 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04791337412082488, + "scoreError" : 6.092732015952206E-4, + "scoreConfidence" : [ + 0.04730410091922966, + 0.0485226473224201 + ], + "scorePercentiles" : { + "0.0" : 0.04742956409538896, + "50.0" : 0.04789460816111497, + "90.0" : 0.04834787348491808, + "95.0" : 0.04834787348491808, + "99.0" : 0.04834787348491808, + "99.9" : 0.04834787348491808, + "99.99" : 0.04834787348491808, + "99.999" : 0.04834787348491808, + "99.9999" : 0.04834787348491808, + "100.0" : 0.04834787348491808 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04790588642123165, + 0.04789460816111497, + 0.047890905550952774 + ], + [ + 0.0483252757449235, + 0.048341155593475967, + 0.04834787348491808 + ], + [ + 0.04753277148452354, + 0.04755232655089445, + 0.04742956409538896 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9462755.68721248, + "scoreError" : 319695.88956154167, + "scoreConfidence" : [ + 9143059.797650939, + 9782451.576774022 + ], + "scorePercentiles" : { + "0.0" : 9210562.837016575, + "50.0" : 9569353.49043977, + "90.0" : 9645247.50819672, + "95.0" : 9645247.50819672, + "99.0" : 9645247.50819672, + "99.9" : 9645247.50819672, + "99.99" : 9645247.50819672, + "99.999" : 9645247.50819672, + "99.9999" : 9645247.50819672, + "100.0" : 9645247.50819672 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9609886.60518732, + 9569353.49043977, + 9552628.962750716 + ], + [ + 9645247.50819672, + 9577503.71291866, + 9575471.54354067 + ], + [ + 9212506.072744016, + 9211640.452117864, + 9210562.837016575 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:14:33Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:14:33Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..ad9d1d5a8c --- /dev/null +++ b/performance-results/2025-03-24T01:14:33Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.40858461951776, + "scoreError" : 0.02823504274507638, + "scoreConfidence" : [ + 3.3803495767726837, + 3.4368196622628364 + ], + "scorePercentiles" : { + "0.0" : 3.403842617984939, + "50.0" : 3.408227397148522, + "90.0" : 3.414041065789058, + "95.0" : 3.414041065789058, + "99.0" : 3.414041065789058, + "99.9" : 3.414041065789058, + "99.99" : 3.414041065789058, + "99.999" : 3.414041065789058, + "99.9999" : 3.414041065789058, + "100.0" : 3.414041065789058 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.403842617984939, + 3.409770199303155 + ], + [ + 3.406684594993889, + 3.414041065789058 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.719980936295944, + "scoreError" : 0.023474343074217335, + "scoreConfidence" : [ + 1.6965065932217267, + 1.7434552793701612 + ], + "scorePercentiles" : { + "0.0" : 1.7165348324954257, + "50.0" : 1.7198702033470656, + "90.0" : 1.7236485059942186, + "95.0" : 1.7236485059942186, + "99.0" : 1.7236485059942186, + "99.9" : 1.7236485059942186, + "99.99" : 1.7236485059942186, + "99.999" : 1.7236485059942186, + "99.9999" : 1.7236485059942186, + "100.0" : 1.7236485059942186 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.722538337715663, + 1.7236485059942186 + ], + [ + 1.7172020689784684, + 1.7165348324954257 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8662508137633711, + "scoreError" : 0.006600936431906626, + "scoreConfidence" : [ + 0.8596498773314645, + 0.8728517501952777 + ], + "scorePercentiles" : { + "0.0" : 0.8649383265860422, + "50.0" : 0.8664958062991177, + "90.0" : 0.8670733158692063, + "95.0" : 0.8670733158692063, + "99.0" : 0.8670733158692063, + "99.9" : 0.8670733158692063, + "99.99" : 0.8670733158692063, + "99.999" : 0.8670733158692063, + "99.9999" : 0.8670733158692063, + "100.0" : 0.8670733158692063 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8670486287680078, + 0.8670733158692063 + ], + [ + 0.8649383265860422, + 0.8659429838302277 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.77838375496337, + "scoreError" : 0.236087536028889, + "scoreConfidence" : [ + 15.542296218934482, + 16.014471290992258 + ], + "scorePercentiles" : { + "0.0" : 15.5961961951466, + "50.0" : 15.711442912088485, + "90.0" : 15.972625063204788, + "95.0" : 15.972625063204788, + "99.0" : 15.972625063204788, + "99.9" : 15.972625063204788, + "99.99" : 15.972625063204788, + "99.999" : 15.972625063204788, + "99.9999" : 15.972625063204788, + "100.0" : 15.972625063204788 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.923619257367257, + 15.688122136687152, + 15.861394961333474 + ], + [ + 15.917691639008215, + 15.972625063204788, + 15.700576098794429 + ], + [ + 15.63378553103995, + 15.5961961951466, + 15.711442912088485 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2568.2740998550807, + "scoreError" : 97.78617105196564, + "scoreConfidence" : [ + 2470.487928803115, + 2666.0602709070463 + ], + "scorePercentiles" : { + "0.0" : 2475.227524256153, + "50.0" : 2577.6124597652006, + "90.0" : 2636.058733746114, + "95.0" : 2636.058733746114, + "99.0" : 2636.058733746114, + "99.9" : 2636.058733746114, + "99.99" : 2636.058733746114, + "99.999" : 2636.058733746114, + "99.9999" : 2636.058733746114, + "100.0" : 2636.058733746114 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2510.514525115231, + 2475.227524256153, + 2512.7676390395122 + ], + [ + 2618.47099094829, + 2552.117579354896, + 2612.291342265198 + ], + [ + 2636.058733746114, + 2577.6124597652006, + 2619.406104205128 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69829.0263668477, + "scoreError" : 1060.1346840457486, + "scoreConfidence" : [ + 68768.89168280194, + 70889.16105089345 + ], + "scorePercentiles" : { + "0.0" : 68925.80132472458, + "50.0" : 69768.77289161518, + "90.0" : 70700.90064854718, + "95.0" : 70700.90064854718, + "99.0" : 70700.90064854718, + "99.9" : 70700.90064854718, + "99.99" : 70700.90064854718, + "99.999" : 70700.90064854718, + "99.9999" : 70700.90064854718, + "100.0" : 70700.90064854718 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69506.85659733678, + 70028.64672895106, + 69768.77289161518 + ], + [ + 70700.90064854718, + 70253.3941584423, + 70621.94107476607 + ], + [ + 69600.20646558938, + 68925.80132472458, + 69054.71741165676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.9282095584336, + "scoreError" : 2.6303078428595033, + "scoreConfidence" : [ + 340.2979017155741, + 345.5585174012931 + ], + "scorePercentiles" : { + "0.0" : 339.7323315026931, + "50.0" : 343.5420116887202, + "90.0" : 345.02858681117044, + "95.0" : 345.02858681117044, + "99.0" : 345.02858681117044, + "99.9" : 345.02858681117044, + "99.99" : 345.02858681117044, + "99.999" : 345.02858681117044, + "99.9999" : 345.02858681117044, + "100.0" : 345.02858681117044 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.02858681117044, + 343.5420116887202, + 342.0739074233191 + ], + [ + 343.5761532037889, + 341.92689876445934, + 339.7323315026931 + ], + [ + 342.55961907210377, + 344.2673861390148, + 343.6469914206324 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.48756562624698, + "scoreError" : 1.0958141946055548, + "scoreConfidence" : [ + 105.39175143164142, + 107.58337982085253 + ], + "scorePercentiles" : { + "0.0" : 105.49245380830173, + "50.0" : 106.5276062463189, + "90.0" : 107.65841429984553, + "95.0" : 107.65841429984553, + "99.0" : 107.65841429984553, + "99.9" : 107.65841429984553, + "99.99" : 107.65841429984553, + "99.999" : 107.65841429984553, + "99.9999" : 107.65841429984553, + "100.0" : 107.65841429984553 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.77795669889201, + 106.85071095308024, + 106.68181660710022 + ], + [ + 106.35814726073099, + 105.49245380830173, + 106.93707535894518 + ], + [ + 106.5276062463189, + 106.1039094030079, + 107.65841429984553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06297848004678867, + "scoreError" : 5.894937036759589E-4, + "scoreConfidence" : [ + 0.06238898634311271, + 0.06356797375046463 + ], + "scorePercentiles" : { + "0.0" : 0.06252654531244138, + "50.0" : 0.06302387430044368, + "90.0" : 0.06367914714722364, + "95.0" : 0.06367914714722364, + "99.0" : 0.06367914714722364, + "99.9" : 0.06367914714722364, + "99.99" : 0.06367914714722364, + "99.999" : 0.06367914714722364, + "99.9999" : 0.06367914714722364, + "100.0" : 0.06367914714722364 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06319152964594221, + 0.06269488202250713, + 0.06314516624675595 + ], + [ + 0.06302387430044368, + 0.062759557803704, + 0.06308125920342147 + ], + [ + 0.06367914714722364, + 0.06270435873865852, + 0.06252654531244138 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.761317551796573E-4, + "scoreError" : 1.2845499363296883E-5, + "scoreConfidence" : [ + 3.632862558163604E-4, + 3.889772545429542E-4 + ], + "scorePercentiles" : { + "0.0" : 3.654097590578796E-4, + "50.0" : 3.7901738871717514E-4, + "90.0" : 3.834261705410972E-4, + "95.0" : 3.834261705410972E-4, + "99.0" : 3.834261705410972E-4, + "99.9" : 3.834261705410972E-4, + "99.99" : 3.834261705410972E-4, + "99.999" : 3.834261705410972E-4, + "99.9999" : 3.834261705410972E-4, + "100.0" : 3.834261705410972E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7850269643764254E-4, + 3.7901738871717514E-4, + 3.834261705410972E-4 + ], + [ + 3.6558843802575615E-4, + 3.677787138036308E-4, + 3.654097590578796E-4 + ], + [ + 3.828899716507752E-4, + 3.796131917762167E-4, + 3.829594666067419E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014172803140729643, + "scoreError" : 1.0782891474152387E-4, + "scoreConfidence" : [ + 0.014064974225988118, + 0.014280632055471167 + ], + "scorePercentiles" : { + "0.0" : 0.014081310722784686, + "50.0" : 0.01416622602502008, + "90.0" : 0.014286797526133748, + "95.0" : 0.014286797526133748, + "99.0" : 0.014286797526133748, + "99.9" : 0.014286797526133748, + "99.99" : 0.014286797526133748, + "99.999" : 0.014286797526133748, + "99.9999" : 0.014286797526133748, + "100.0" : 0.014286797526133748 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014178331408884037, + 0.014115230361415172, + 0.014081310722784686 + ], + [ + 0.01416622602502008, + 0.014132456071226682, + 0.014158328896641263 + ], + [ + 0.014286797526133748, + 0.014185009923713932, + 0.014251537330747185 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9905397184409652, + "scoreError" : 0.02238876384346547, + "scoreConfidence" : [ + 0.9681509545974998, + 1.0129284822844307 + ], + "scorePercentiles" : { + "0.0" : 0.9773580523846755, + "50.0" : 0.9843310696850394, + "90.0" : 1.0116134580214444, + "95.0" : 1.0116134580214444, + "99.0" : 1.0116134580214444, + "99.9" : 1.0116134580214444, + "99.99" : 1.0116134580214444, + "99.999" : 1.0116134580214444, + "99.9999" : 1.0116134580214444, + "100.0" : 1.0116134580214444 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9831717689736532, + 0.9843310696850394, + 0.9784792103512376 + ], + [ + 1.010704397877716, + 1.0116134580214444, + 0.9998777521495701 + ], + [ + 0.9773580523846755, + 0.9853596882451473, + 0.9839620682802046 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013155411922502263, + "scoreError" : 2.795852915008635E-4, + "scoreConfidence" : [ + 0.012875826631001399, + 0.013434997214003127 + ], + "scorePercentiles" : { + "0.0" : 0.013002453662963657, + "50.0" : 0.01316711428100242, + "90.0" : 0.01327616876247929, + "95.0" : 0.01327616876247929, + "99.0" : 0.01327616876247929, + "99.9" : 0.01327616876247929, + "99.99" : 0.01327616876247929, + "99.999" : 0.01327616876247929, + "99.9999" : 0.01327616876247929, + "100.0" : 0.01327616876247929 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013121031901689159, + 0.013219664486364297, + 0.01327616876247929 + ], + [ + 0.013002453662963657, + 0.013099956061201498, + 0.013213196660315682 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.750332902092968, + "scoreError" : 0.1674325694384914, + "scoreConfidence" : [ + 3.582900332654477, + 3.9177654715314594 + ], + "scorePercentiles" : { + "0.0" : 3.659013118507681, + "50.0" : 3.746797678884942, + "90.0" : 3.840637273425499, + "95.0" : 3.840637273425499, + "99.0" : 3.840637273425499, + "99.9" : 3.840637273425499, + "99.99" : 3.840637273425499, + "99.999" : 3.840637273425499, + "99.9999" : 3.840637273425499, + "100.0" : 3.840637273425499 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.840637273425499, + 3.751801334583646, + 3.779107640483384 + ], + [ + 3.659013118507681, + 3.7296440223713647, + 3.741794023186238 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8548886386460897, + "scoreError" : 0.03636649593192445, + "scoreConfidence" : [ + 2.818522142714165, + 2.891255134578014 + ], + "scorePercentiles" : { + "0.0" : 2.8271100124364046, + "50.0" : 2.8555864614505997, + "90.0" : 2.880886245391705, + "95.0" : 2.880886245391705, + "99.0" : 2.880886245391705, + "99.9" : 2.880886245391705, + "99.99" : 2.880886245391705, + "99.999" : 2.880886245391705, + "99.9999" : 2.880886245391705, + "100.0" : 2.880886245391705 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.868786039586919, + 2.880886245391705, + 2.8482905326117915 + ], + [ + 2.827418055414193, + 2.8798364851713214, + 2.8555864614505997 + ], + [ + 2.871456194946885, + 2.8271100124364046, + 2.834627720804989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17971936084685597, + "scoreError" : 0.016517911751403654, + "scoreConfidence" : [ + 0.1632014490954523, + 0.19623727259825963 + ], + "scorePercentiles" : { + "0.0" : 0.16987528725283685, + "50.0" : 0.17653581038713437, + "90.0" : 0.19261740506182826, + "95.0" : 0.19261740506182826, + "99.0" : 0.19261740506182826, + "99.9" : 0.19261740506182826, + "99.99" : 0.19261740506182826, + "99.999" : 0.19261740506182826, + "99.9999" : 0.19261740506182826, + "100.0" : 0.19261740506182826 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19216519448501154, + 0.19261740506182826, + 0.19231822860494635 + ], + [ + 0.17595648287086726, + 0.1765369575793952, + 0.17653581038713437 + ], + [ + 0.16987528725283685, + 0.17103812304166383, + 0.17043075833802002 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33498656189355885, + "scoreError" : 0.00339606700371187, + "scoreConfidence" : [ + 0.331590494889847, + 0.3383826288972707 + ], + "scorePercentiles" : { + "0.0" : 0.3326694837829746, + "50.0" : 0.3347886653610525, + "90.0" : 0.33945752532247114, + "95.0" : 0.33945752532247114, + "99.0" : 0.33945752532247114, + "99.9" : 0.33945752532247114, + "99.99" : 0.33945752532247114, + "99.999" : 0.33945752532247114, + "99.9999" : 0.33945752532247114, + "100.0" : 0.33945752532247114 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3366052745296038, + 0.3343679756921225, + 0.33945752532247114 + ], + [ + 0.33349957656906554, + 0.33495701289523044, + 0.3349827138311057 + ], + [ + 0.3347886653610525, + 0.3326694837829746, + 0.33355082905840366 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16055367098210246, + "scoreError" : 0.010627721830330528, + "scoreConfidence" : [ + 0.14992594915177193, + 0.171181392812433 + ], + "scorePercentiles" : { + "0.0" : 0.15152957390711416, + "50.0" : 0.1632057275353331, + "90.0" : 0.16693598417467947, + "95.0" : 0.16693598417467947, + "99.0" : 0.16693598417467947, + "99.9" : 0.16693598417467947, + "99.99" : 0.16693598417467947, + "99.999" : 0.16693598417467947, + "99.9999" : 0.16693598417467947, + "100.0" : 0.16693598417467947 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1535686558915217, + 0.15192134652487657, + 0.15152957390711416 + ], + [ + 0.16276372596474667, + 0.1632057275353331, + 0.1637623504298698 + ], + [ + 0.16609101062964007, + 0.16693598417467947, + 0.16520466378114054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39828964003913936, + "scoreError" : 0.00934466580815901, + "scoreConfidence" : [ + 0.38894497423098034, + 0.4076343058472984 + ], + "scorePercentiles" : { + "0.0" : 0.3920836011918764, + "50.0" : 0.3969977016673283, + "90.0" : 0.40858754435137895, + "95.0" : 0.40858754435137895, + "99.0" : 0.40858754435137895, + "99.9" : 0.40858754435137895, + "99.99" : 0.40858754435137895, + "99.999" : 0.40858754435137895, + "99.9999" : 0.40858754435137895, + "100.0" : 0.40858754435137895 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3922899960379727, + 0.3920836011918764, + 0.39326324503519605 + ], + [ + 0.40858754435137895, + 0.3969044770201619, + 0.3969977016673283 + ], + [ + 0.4036797789932588, + 0.4003199688563308, + 0.40048044719875053 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16041917557422003, + "scoreError" : 0.001737144665873153, + "scoreConfidence" : [ + 0.15868203090834687, + 0.1621563202400932 + ], + "scorePercentiles" : { + "0.0" : 0.15906686147165489, + "50.0" : 0.16033186659077792, + "90.0" : 0.1626990494265029, + "95.0" : 0.1626990494265029, + "99.0" : 0.1626990494265029, + "99.9" : 0.1626990494265029, + "99.99" : 0.1626990494265029, + "99.999" : 0.1626990494265029, + "99.9999" : 0.1626990494265029, + "100.0" : 0.1626990494265029 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1626990494265029, + 0.16033186659077792, + 0.16045412686926386 + ], + [ + 0.1595371675648098, + 0.16000919154212934, + 0.15906686147165489 + ], + [ + 0.16053158194076572, + 0.16107567585851426, + 0.16006705890356143 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04807424698073026, + "scoreError" : 5.436220780624052E-4, + "scoreConfidence" : [ + 0.04753062490266786, + 0.048617869058792666 + ], + "scorePercentiles" : { + "0.0" : 0.04746269952775339, + "50.0" : 0.048026309701617975, + "90.0" : 0.048588726259887666, + "95.0" : 0.048588726259887666, + "99.0" : 0.048588726259887666, + "99.9" : 0.048588726259887666, + "99.99" : 0.048588726259887666, + "99.999" : 0.048588726259887666, + "99.9999" : 0.048588726259887666, + "100.0" : 0.048588726259887666 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.048350908289173405, + 0.048588726259887666, + 0.048329807225189085 + ], + [ + 0.0480161819836171, + 0.047919599771906116, + 0.04746269952775339 + ], + [ + 0.04790992621054094, + 0.048026309701617975, + 0.048064063856886746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9676391.013650784, + "scoreError" : 287328.6480368536, + "scoreConfidence" : [ + 9389062.36561393, + 9963719.661687639 + ], + "scorePercentiles" : { + "0.0" : 9478153.125, + "50.0" : 9586281.842911877, + "90.0" : 9966990.433266932, + "95.0" : 9966990.433266932, + "99.0" : 9966990.433266932, + "99.9" : 9966990.433266932, + "99.99" : 9966990.433266932, + "99.999" : 9966990.433266932, + "99.9999" : 9966990.433266932, + "100.0" : 9966990.433266932 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9558136.078319008, + 9557984.59503343, + 9478153.125 + ], + [ + 9966990.433266932, + 9883363.479249012, + 9822402.113837095 + ], + [ + 9586281.842911877, + 9579493.921455938, + 9654713.533783784 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:14:54Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:14:54Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..c247dd7f92 --- /dev/null +++ b/performance-results/2025-03-24T01:14:54Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.416841228362352, + "scoreError" : 0.046224539933131144, + "scoreConfidence" : [ + 3.370616688429221, + 3.463065768295483 + ], + "scorePercentiles" : { + "0.0" : 3.4104833073322536, + "50.0" : 3.4149070097262744, + "90.0" : 3.4270675866646054, + "95.0" : 3.4270675866646054, + "99.0" : 3.4270675866646054, + "99.9" : 3.4270675866646054, + "99.99" : 3.4270675866646054, + "99.999" : 3.4270675866646054, + "99.9999" : 3.4270675866646054, + "100.0" : 3.4270675866646054 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4104833073322536, + 3.415622928858356 + ], + [ + 3.414191090594193, + 3.4270675866646054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7256805880386656, + "scoreError" : 0.008670416239197185, + "scoreConfidence" : [ + 1.7170101717994684, + 1.734351004277863 + ], + "scorePercentiles" : { + "0.0" : 1.7238767187983217, + "50.0" : 1.7258640396415021, + "90.0" : 1.7271175540733374, + "95.0" : 1.7271175540733374, + "99.0" : 1.7271175540733374, + "99.9" : 1.7271175540733374, + "99.99" : 1.7271175540733374, + "99.999" : 1.7271175540733374, + "99.9999" : 1.7271175540733374, + "100.0" : 1.7271175540733374 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7257779960512811, + 1.7238767187983217 + ], + [ + 1.725950083231723, + 1.7271175540733374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8668202231331765, + "scoreError" : 0.004831866423434959, + "scoreConfidence" : [ + 0.8619883567097416, + 0.8716520895566114 + ], + "scorePercentiles" : { + "0.0" : 0.866215610918664, + "50.0" : 0.8666131123079148, + "90.0" : 0.8678390569982123, + "95.0" : 0.8678390569982123, + "99.0" : 0.8678390569982123, + "99.9" : 0.8678390569982123, + "99.99" : 0.8678390569982123, + "99.999" : 0.8678390569982123, + "99.9999" : 0.8678390569982123, + "100.0" : 0.8678390569982123 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8663065488930909, + 0.8678390569982123 + ], + [ + 0.866215610918664, + 0.8669196757227386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.31640431452635, + "scoreError" : 0.3186289582091417, + "scoreConfidence" : [ + 15.997775356317206, + 16.63503327273549 + ], + "scorePercentiles" : { + "0.0" : 16.01931994704482, + "50.0" : 16.40630490278462, + "90.0" : 16.49237024973776, + "95.0" : 16.49237024973776, + "99.0" : 16.49237024973776, + "99.9" : 16.49237024973776, + "99.99" : 16.49237024973776, + "99.999" : 16.49237024973776, + "99.9999" : 16.49237024973776, + "100.0" : 16.49237024973776 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.40630490278462, + 16.401037480073782, + 16.411364862887655 + ], + [ + 16.01931994704482, + 16.08726384861906, + 16.099568628269374 + ], + [ + 16.452416990458655, + 16.49237024973776, + 16.47799192086142 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2809.778181329612, + "scoreError" : 90.87641938701525, + "scoreConfidence" : [ + 2718.9017619425967, + 2900.654600716627 + ], + "scorePercentiles" : { + "0.0" : 2751.543366182571, + "50.0" : 2799.350960371689, + "90.0" : 2882.7440630130905, + "95.0" : 2882.7440630130905, + "99.0" : 2882.7440630130905, + "99.9" : 2882.7440630130905, + "99.99" : 2882.7440630130905, + "99.999" : 2882.7440630130905, + "99.9999" : 2882.7440630130905, + "100.0" : 2882.7440630130905 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2751.543366182571, + 2754.397261861922, + 2753.9996216878067 + ], + [ + 2873.0058513045706, + 2882.7440630130905, + 2874.397658886027 + ], + [ + 2799.6827906200256, + 2798.8820580388037, + 2799.350960371689 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69538.89231546373, + "scoreError" : 2700.454110688654, + "scoreConfidence" : [ + 66838.43820477507, + 72239.34642615239 + ], + "scorePercentiles" : { + "0.0" : 67053.05858762588, + "50.0" : 70502.74638799811, + "90.0" : 70713.11228173104, + "95.0" : 70713.11228173104, + "99.0" : 70713.11228173104, + "99.9" : 70713.11228173104, + "99.99" : 70713.11228173104, + "99.999" : 70713.11228173104, + "99.9999" : 70713.11228173104, + "100.0" : 70713.11228173104 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 67586.91728942825, + 67053.05858762588, + 67587.19740878949 + ], + [ + 70692.91981659395, + 70713.11228173104, + 70694.96634571847 + ], + [ + 70502.74638799811, + 70522.83979766157, + 70496.2729236268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.46608040287845, + "scoreError" : 2.1052187242826883, + "scoreConfidence" : [ + 351.36086167859577, + 355.5712991271611 + ], + "scorePercentiles" : { + "0.0" : 351.46498132968077, + "50.0" : 353.7673749359021, + "90.0" : 355.081588309483, + "95.0" : 355.081588309483, + "99.0" : 355.081588309483, + "99.9" : 355.081588309483, + "99.99" : 355.081588309483, + "99.999" : 355.081588309483, + "99.9999" : 355.081588309483, + "100.0" : 355.081588309483 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.89802732725707, + 355.081588309483, + 353.87855531342655 + ], + [ + 354.1289425757435, + 353.7673749359021, + 351.46498132968077 + ], + [ + 352.1390732144776, + 352.2742231087273, + 353.5619575112081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.22875395145122, + "scoreError" : 2.2268608546616937, + "scoreConfidence" : [ + 106.00189309678953, + 110.45561480611292 + ], + "scorePercentiles" : { + "0.0" : 106.86010819192902, + "50.0" : 107.79288461324526, + "90.0" : 110.04883231120205, + "95.0" : 110.04883231120205, + "99.0" : 110.04883231120205, + "99.9" : 110.04883231120205, + "99.99" : 110.04883231120205, + "99.999" : 110.04883231120205, + "99.9999" : 110.04883231120205, + "100.0" : 110.04883231120205 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.9151305341687, + 106.86010819192902, + 106.9410451235742 + ], + [ + 109.80234788582067, + 109.83710038953076, + 110.04883231120205 + ], + [ + 108.0859766767882, + 107.79288461324526, + 107.77535983680224 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061717211018078616, + "scoreError" : 7.746341957989277E-4, + "scoreConfidence" : [ + 0.06094257682227969, + 0.062491845213877545 + ], + "scorePercentiles" : { + "0.0" : 0.06129506386838944, + "50.0" : 0.061503650343801126, + "90.0" : 0.06238190136302673, + "95.0" : 0.06238190136302673, + "99.0" : 0.06238190136302673, + "99.9" : 0.06238190136302673, + "99.99" : 0.06238190136302673, + "99.999" : 0.06238190136302673, + "99.9999" : 0.06238190136302673, + "100.0" : 0.06238190136302673 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06140399041496273, + 0.06129506386838944, + 0.061410989824367476 + ], + [ + 0.062216737816600406, + 0.062367104588288855, + 0.06238190136302673 + ], + [ + 0.06135302896443406, + 0.06152243197883663, + 0.061503650343801126 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.594316967390262E-4, + "scoreError" : 2.025210075568485E-5, + "scoreConfidence" : [ + 3.3917959598334135E-4, + 3.79683797494711E-4 + ], + "scorePercentiles" : { + "0.0" : 3.451150199006584E-4, + "50.0" : 3.5978557142412557E-4, + "90.0" : 3.738151868826466E-4, + "95.0" : 3.738151868826466E-4, + "99.0" : 3.738151868826466E-4, + "99.9" : 3.738151868826466E-4, + "99.99" : 3.738151868826466E-4, + "99.999" : 3.738151868826466E-4, + "99.9999" : 3.738151868826466E-4, + "100.0" : 3.738151868826466E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5978557142412557E-4, + 3.5895190739054946E-4, + 3.5982580568855865E-4 + ], + [ + 3.451150199006584E-4, + 3.455401107623804E-4, + 3.4577895015172963E-4 + ], + [ + 3.728989930124733E-4, + 3.738151868826466E-4, + 3.731737254381133E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014191966644421385, + "scoreError" : 2.1829014589974747E-4, + "scoreConfidence" : [ + 0.013973676498521638, + 0.014410256790321131 + ], + "scorePercentiles" : { + "0.0" : 0.014034512911592084, + "50.0" : 0.014199062441074573, + "90.0" : 0.014338884630605725, + "95.0" : 0.014338884630605725, + "99.0" : 0.014338884630605725, + "99.9" : 0.014338884630605725, + "99.99" : 0.014338884630605725, + "99.999" : 0.014338884630605725, + "99.9999" : 0.014338884630605725, + "100.0" : 0.014338884630605725 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014034512911592084, + 0.014036816928473472, + 0.014044025110419842 + ], + [ + 0.014203260520230885, + 0.014199062441074573, + 0.014195771940384105 + ], + [ + 0.014338884630605725, + 0.014338267550563345, + 0.01433709776644841 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9925031145812194, + "scoreError" : 0.042226353185113495, + "scoreConfidence" : [ + 0.950276761396106, + 1.034729467766333 + ], + "scorePercentiles" : { + "0.0" : 0.9630525597072419, + "50.0" : 0.9913075222045995, + "90.0" : 1.0285787390723027, + "95.0" : 1.0285787390723027, + "99.0" : 1.0285787390723027, + "99.9" : 1.0285787390723027, + "99.99" : 1.0285787390723027, + "99.999" : 1.0285787390723027, + "99.9999" : 1.0285787390723027, + "100.0" : 1.0285787390723027 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9906748670629024, + 0.9913075222045995, + 0.9914711291761673 + ], + [ + 0.9630525597072419, + 0.9650835647558387, + 0.9655797285893598 + ], + [ + 1.0129199996961409, + 1.023859920966421, + 1.0285787390723027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013059418001820743, + "scoreError" : 2.515838452231582E-4, + "scoreConfidence" : [ + 0.012807834156597584, + 0.013311001847043901 + ], + "scorePercentiles" : { + "0.0" : 0.012981688982469987, + "50.0" : 0.013024948595270976, + "90.0" : 0.013170221643917884, + "95.0" : 0.013170221643917884, + "99.0" : 0.013170221643917884, + "99.9" : 0.013170221643917884, + "99.99" : 0.013170221643917884, + "99.999" : 0.013170221643917884, + "99.9999" : 0.013170221643917884, + "100.0" : 0.013170221643917884 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013056340266081757, + 0.013169372862338977, + 0.013170221643917884 + ], + [ + 0.012985327331655668, + 0.012981688982469987, + 0.012993556924460197 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6592788291395366, + "scoreError" : 0.050967515054031964, + "scoreConfidence" : [ + 3.6083113140855048, + 3.7102463441935685 + ], + "scorePercentiles" : { + "0.0" : 3.623741924637681, + "50.0" : 3.664233986813187, + "90.0" : 3.6741932277736957, + "95.0" : 3.6741932277736957, + "99.0" : 3.6741932277736957, + "99.9" : 3.6741932277736957, + "99.99" : 3.6741932277736957, + "99.999" : 3.6741932277736957, + "99.9999" : 3.6741932277736957, + "100.0" : 3.6741932277736957 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.665116643223443, + 3.6633513304029304, + 3.6592315215801023 + ], + [ + 3.623741924637681, + 3.670038327219369, + 3.6741932277736957 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.816428854728746, + "scoreError" : 0.06208714333215352, + "scoreConfidence" : [ + 2.7543417113965925, + 2.8785159980609 + ], + "scorePercentiles" : { + "0.0" : 2.765137873652198, + "50.0" : 2.8340587007650893, + "90.0" : 2.8525728069024527, + "95.0" : 2.8525728069024527, + "99.0" : 2.8525728069024527, + "99.9" : 2.8525728069024527, + "99.99" : 2.8525728069024527, + "99.999" : 2.8525728069024527, + "99.9999" : 2.8525728069024527, + "100.0" : 2.8525728069024527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8513465621436715, + 2.8525728069024527, + 2.8419214063654445 + ], + [ + 2.834123484839898, + 2.8340587007650893, + 2.8287812502828054 + ], + [ + 2.7730404374826727, + 2.766877170124481, + 2.765137873652198 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1793954246557457, + "scoreError" : 0.015718117464958145, + "scoreConfidence" : [ + 0.16367730719078755, + 0.19511354212070386 + ], + "scorePercentiles" : { + "0.0" : 0.17193095985489307, + "50.0" : 0.1741289254744907, + "90.0" : 0.19208350172870808, + "95.0" : 0.19208350172870808, + "99.0" : 0.19208350172870808, + "99.9" : 0.19208350172870808, + "99.99" : 0.19208350172870808, + "99.999" : 0.19208350172870808, + "99.9999" : 0.19208350172870808, + "100.0" : 0.19208350172870808 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19208350172870808, + 0.19167580244570948, + 0.1917056374511157 + ], + [ + 0.1741670207600404, + 0.17371442937794224, + 0.1741289254744907 + ], + [ + 0.17308442873461757, + 0.17193095985489307, + 0.1720681160741939 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3310067074422411, + "scoreError" : 0.005286940810887437, + "scoreConfidence" : [ + 0.32571976663135366, + 0.3362936482531285 + ], + "scorePercentiles" : { + "0.0" : 0.3272692564060608, + "50.0" : 0.3299537344925432, + "90.0" : 0.33597765600537544, + "95.0" : 0.33597765600537544, + "99.0" : 0.33597765600537544, + "99.9" : 0.33597765600537544, + "99.99" : 0.33597765600537544, + "99.999" : 0.33597765600537544, + "99.9999" : 0.33597765600537544, + "100.0" : 0.33597765600537544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33105885374251004, + 0.32922863973662553, + 0.3299537344925432 + ], + [ + 0.33597765600537544, + 0.33463009536556804, + 0.3340892610496776 + ], + [ + 0.32880638031827447, + 0.32804648986353496, + 0.3272692564060608 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1655695332101355, + "scoreError" : 0.0014940467802612104, + "scoreConfidence" : [ + 0.1640754864298743, + 0.16706357999039673 + ], + "scorePercentiles" : { + "0.0" : 0.1643908343634929, + "50.0" : 0.16573519637382125, + "90.0" : 0.16663853021945976, + "95.0" : 0.16663853021945976, + "99.0" : 0.16663853021945976, + "99.9" : 0.16663853021945976, + "99.99" : 0.16663853021945976, + "99.999" : 0.16663853021945976, + "99.9999" : 0.16663853021945976, + "100.0" : 0.16663853021945976 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16573519637382125, + 0.16486172864255333, + 0.16493741781296387 + ], + [ + 0.1658688282302206, + 0.16462066344016987, + 0.1643908343634929 + ], + [ + 0.1664890851077999, + 0.16658351470073796, + 0.16663853021945976 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3880358277948496, + "scoreError" : 0.015062129870327713, + "scoreConfidence" : [ + 0.37297369792452184, + 0.4030979576651773 + ], + "scorePercentiles" : { + "0.0" : 0.3791764736862061, + "50.0" : 0.3846368117235278, + "90.0" : 0.40354941443041037, + "95.0" : 0.40354941443041037, + "99.0" : 0.40354941443041037, + "99.9" : 0.40354941443041037, + "99.99" : 0.40354941443041037, + "99.999" : 0.40354941443041037, + "99.9999" : 0.40354941443041037, + "100.0" : 0.40354941443041037 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38075618664331407, + 0.3798244570625546, + 0.3791764736862061 + ], + [ + 0.38515324564782005, + 0.3846368117235278, + 0.3846282916153846 + ], + [ + 0.40354941443041037, + 0.3971281042808355, + 0.397469465063593 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15783876494082616, + "scoreError" : 0.0036673927342274586, + "scoreConfidence" : [ + 0.1541713722065987, + 0.1615061576750536 + ], + "scorePercentiles" : { + "0.0" : 0.1556568356914935, + "50.0" : 0.15700002814933434, + "90.0" : 0.1620545456254355, + "95.0" : 0.1620545456254355, + "99.0" : 0.1620545456254355, + "99.9" : 0.1620545456254355, + "99.99" : 0.1620545456254355, + "99.999" : 0.1620545456254355, + "99.9999" : 0.1620545456254355, + "100.0" : 0.1620545456254355 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15700002814933434, + 0.15577499482841878, + 0.1556568356914935 + ], + [ + 0.15725884702237738, + 0.1567389933544403, + 0.15655110679733242 + ], + [ + 0.1620545456254355, + 0.15990778622255625, + 0.159605746776047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04759487313143161, + "scoreError" : 5.249458188152128E-4, + "scoreConfidence" : [ + 0.047069927312616396, + 0.04811981895024683 + ], + "scorePercentiles" : { + "0.0" : 0.0471997846347726, + "50.0" : 0.04748367897265933, + "90.0" : 0.048040983771942464, + "95.0" : 0.048040983771942464, + "99.0" : 0.048040983771942464, + "99.9" : 0.048040983771942464, + "99.99" : 0.048040983771942464, + "99.999" : 0.048040983771942464, + "99.9999" : 0.048040983771942464, + "100.0" : 0.048040983771942464 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.048040983771942464, + 0.047442269875608435, + 0.04746866217460649 + ], + [ + 0.04795914089221827, + 0.04756065644603612, + 0.04748367897265933 + ], + [ + 0.04794581715666532, + 0.047252864258375465, + 0.0471997846347726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9273198.347081004, + "scoreError" : 151405.44321916296, + "scoreConfidence" : [ + 9121792.903861841, + 9424603.790300166 + ], + "scorePercentiles" : { + "0.0" : 9155483.271729186, + "50.0" : 9294069.286245354, + "90.0" : 9361522.364826942, + "95.0" : 9361522.364826942, + "99.0" : 9361522.364826942, + "99.9" : 9361522.364826942, + "99.99" : 9361522.364826942, + "99.999" : 9361522.364826942, + "99.9999" : 9361522.364826942, + "100.0" : 9361522.364826942 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9159622.364468865, + 9161932.124542125, + 9155483.271729186 + ], + [ + 9338092.402427638, + 9294069.286245354, + 9278606.829313543 + ], + [ + 9350569.692523364, + 9358886.787652012, + 9361522.364826942 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:15:42Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:15:42Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..347a362b1b --- /dev/null +++ b/performance-results/2025-03-24T01:15:42Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.423985031790188, + "scoreError" : 0.020585678001601503, + "scoreConfidence" : [ + 3.4033993537885863, + 3.4445707097917895 + ], + "scorePercentiles" : { + "0.0" : 3.4193836164754052, + "50.0" : 3.425190782059619, + "90.0" : 3.4261749465661073, + "95.0" : 3.4261749465661073, + "99.0" : 3.4261749465661073, + "99.9" : 3.4261749465661073, + "99.99" : 3.4261749465661073, + "99.999" : 3.4261749465661073, + "99.9999" : 3.4261749465661073, + "100.0" : 3.4261749465661073 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4193836164754052, + 3.4261749465661073 + ], + [ + 3.4243051172951176, + 3.4260764468241205 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7287797917121857, + "scoreError" : 0.007600411881287742, + "scoreConfidence" : [ + 1.7211793798308979, + 1.7363802035934734 + ], + "scorePercentiles" : { + "0.0" : 1.7276067282125074, + "50.0" : 1.728753700082378, + "90.0" : 1.7300050384714796, + "95.0" : 1.7300050384714796, + "99.0" : 1.7300050384714796, + "99.9" : 1.7300050384714796, + "99.99" : 1.7300050384714796, + "99.999" : 1.7300050384714796, + "99.9999" : 1.7300050384714796, + "100.0" : 1.7300050384714796 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7276067282125074, + 1.729551031146016 + ], + [ + 1.7279563690187403, + 1.7300050384714796 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8680077673242658, + "scoreError" : 0.001730336967352543, + "scoreConfidence" : [ + 0.8662774303569132, + 0.8697381042916184 + ], + "scorePercentiles" : { + "0.0" : 0.8676148794980105, + "50.0" : 0.868100694296265, + "90.0" : 0.8682148012065225, + "95.0" : 0.8682148012065225, + "99.0" : 0.8682148012065225, + "99.9" : 0.8682148012065225, + "99.99" : 0.8682148012065225, + "99.999" : 0.8682148012065225, + "99.9999" : 0.8682148012065225, + "100.0" : 0.8682148012065225 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8676148794980105, + 0.8682148012065225 + ], + [ + 0.8680832284714595, + 0.8681181601210705 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.38240461990315, + "scoreError" : 0.12334786222297711, + "scoreConfidence" : [ + 16.25905675768017, + 16.505752482126127 + ], + "scorePercentiles" : { + "0.0" : 16.276350464015767, + "50.0" : 16.405246368329045, + "90.0" : 16.491374585997335, + "95.0" : 16.491374585997335, + "99.0" : 16.491374585997335, + "99.9" : 16.491374585997335, + "99.99" : 16.491374585997335, + "99.999" : 16.491374585997335, + "99.9999" : 16.491374585997335, + "100.0" : 16.491374585997335 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.276350464015767, + 16.28949960657584, + 16.309277751841147 + ], + [ + 16.405246368329045, + 16.4140186013479, + 16.491374585997335 + ], + [ + 16.435045435937738, + 16.418812751229037, + 16.402016013854535 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2708.5653430356538, + "scoreError" : 91.70865496219062, + "scoreConfidence" : [ + 2616.8566880734634, + 2800.273997997844 + ], + "scorePercentiles" : { + "0.0" : 2655.382188812315, + "50.0" : 2683.8756391544052, + "90.0" : 2780.8420757077465, + "95.0" : 2780.8420757077465, + "99.0" : 2780.8420757077465, + "99.9" : 2780.8420757077465, + "99.99" : 2780.8420757077465, + "99.999" : 2780.8420757077465, + "99.9999" : 2780.8420757077465, + "100.0" : 2780.8420757077465 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2778.394621699917, + 2780.6211412089756, + 2780.8420757077465 + ], + [ + 2681.688877607523, + 2683.8756391544052, + 2686.991378749153 + ], + [ + 2669.7043469811665, + 2655.382188812315, + 2659.5878173996875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69453.92527304837, + "scoreError" : 1521.0238725110248, + "scoreConfidence" : [ + 67932.90140053735, + 70974.9491455594 + ], + "scorePercentiles" : { + "0.0" : 68693.4254198043, + "50.0" : 68981.39786361123, + "90.0" : 70688.90214143042, + "95.0" : 70688.90214143042, + "99.0" : 70688.90214143042, + "99.9" : 70688.90214143042, + "99.99" : 70688.90214143042, + "99.999" : 70688.90214143042, + "99.9999" : 70688.90214143042, + "100.0" : 70688.90214143042 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68981.39786361123, + 68965.05800560681, + 68981.99555956059 + ], + [ + 70626.75144783205, + 70688.90214143042, + 70640.85183648426 + ], + [ + 68693.4254198043, + 68759.7918936698, + 68747.15328943594 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.10407851079464, + "scoreError" : 6.498936628587323, + "scoreConfidence" : [ + 349.6051418822073, + 362.60301513938197 + ], + "scorePercentiles" : { + "0.0" : 350.9120636475959, + "50.0" : 355.3428972137064, + "90.0" : 361.4061321659956, + "95.0" : 361.4061321659956, + "99.0" : 361.4061321659956, + "99.9" : 361.4061321659956, + "99.99" : 361.4061321659956, + "99.999" : 361.4061321659956, + "99.9999" : 361.4061321659956, + "100.0" : 361.4061321659956 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.25636836864624, + 354.82855651204625, + 351.4684689201288 + ], + [ + 360.4932364258982, + 360.36491162891963, + 361.4061321659956 + ], + [ + 355.8640717142149, + 355.3428972137064, + 350.9120636475959 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.31669412956369, + "scoreError" : 3.5778548693793955, + "scoreConfidence" : [ + 103.73883926018429, + 110.89454899894308 + ], + "scorePercentiles" : { + "0.0" : 105.79308903472088, + "50.0" : 105.93376479703352, + "90.0" : 110.34952243173072, + "95.0" : 110.34952243173072, + "99.0" : 110.34952243173072, + "99.9" : 110.34952243173072, + "99.99" : 110.34952243173072, + "99.999" : 110.34952243173072, + "99.9999" : 110.34952243173072, + "100.0" : 110.34952243173072 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.77252022787577, + 110.31612729927951, + 110.34952243173072 + ], + [ + 106.03328503402605, + 105.87577646935003, + 105.79308903472088 + ], + [ + 105.87219204411367, + 105.90396982794302, + 105.93376479703352 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06119980136377835, + "scoreError" : 8.618213928725673E-4, + "scoreConfidence" : [ + 0.060337979970905786, + 0.06206162275665092 + ], + "scorePercentiles" : { + "0.0" : 0.06066733146885389, + "50.0" : 0.06089297250114173, + "90.0" : 0.061862555115650385, + "95.0" : 0.061862555115650385, + "99.0" : 0.061862555115650385, + "99.9" : 0.061862555115650385, + "99.99" : 0.061862555115650385, + "99.999" : 0.061862555115650385, + "99.9999" : 0.061862555115650385, + "100.0" : 0.061862555115650385 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06178237913394827, + 0.061862555115650385, + 0.06185610631664894 + ], + [ + 0.06089089902575656, + 0.06089297250114173, + 0.06134222386549055 + ], + [ + 0.06074345491377582, + 0.0607602899327391, + 0.06066733146885389 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.714779192655463E-4, + "scoreError" : 1.623245467441315E-5, + "scoreConfidence" : [ + 3.552454645911331E-4, + 3.8771037393995944E-4 + ], + "scorePercentiles" : { + "0.0" : 3.584074242444118E-4, + "50.0" : 3.7633382446846465E-4, + "90.0" : 3.7957460862137523E-4, + "95.0" : 3.7957460862137523E-4, + "99.0" : 3.7957460862137523E-4, + "99.9" : 3.7957460862137523E-4, + "99.99" : 3.7957460862137523E-4, + "99.999" : 3.7957460862137523E-4, + "99.9999" : 3.7957460862137523E-4, + "100.0" : 3.7957460862137523E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7924316070034667E-4, + 3.7957460862137523E-4, + 3.7955198229060557E-4 + ], + [ + 3.593466223899345E-4, + 3.5847276303743996E-4, + 3.584074242444118E-4 + ], + [ + 3.7633382446846465E-4, + 3.766252124611751E-4, + 3.7574567517616273E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014355010333514245, + "scoreError" : 4.1067815151196995E-4, + "scoreConfidence" : [ + 0.013944332182002275, + 0.014765688485026216 + ], + "scorePercentiles" : { + "0.0" : 0.014026616836784073, + "50.0" : 0.014459461475396798, + "90.0" : 0.01459370264405256, + "95.0" : 0.01459370264405256, + "99.0" : 0.01459370264405256, + "99.9" : 0.01459370264405256, + "99.99" : 0.01459370264405256, + "99.999" : 0.01459370264405256, + "99.9999" : 0.01459370264405256, + "100.0" : 0.01459370264405256 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014453072907829299, + 0.01459370264405256, + 0.014459461475396798 + ], + [ + 0.014026616836784073, + 0.014033903854924926, + 0.01404158894438352 + ], + [ + 0.014542850651003227, + 0.014528971946336417, + 0.01451492374091739 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9771543281961408, + "scoreError" : 0.02185627742500379, + "scoreConfidence" : [ + 0.955298050771137, + 0.9990106056211445 + ], + "scorePercentiles" : { + "0.0" : 0.9627037857142857, + "50.0" : 0.974022056199474, + "90.0" : 0.9980891943113772, + "95.0" : 0.9980891943113772, + "99.0" : 0.9980891943113772, + "99.9" : 0.9980891943113772, + "99.99" : 0.9980891943113772, + "99.999" : 0.9980891943113772, + "99.9999" : 0.9980891943113772, + "100.0" : 0.9980891943113772 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9669437919164572, + 0.9627037857142857, + 0.963355748579135 + ], + [ + 0.991817503818308, + 0.9980891943113772, + 0.989932828152841 + ], + [ + 0.974022056199474, + 0.9732893321654501, + 0.9742347129079396 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012885614874331264, + "scoreError" : 5.050071426909742E-4, + "scoreConfidence" : [ + 0.01238060773164029, + 0.013390622017022237 + ], + "scorePercentiles" : { + "0.0" : 0.012721508086860284, + "50.0" : 0.012853246073407367, + "90.0" : 0.013082793771193537, + "95.0" : 0.013082793771193537, + "99.0" : 0.013082793771193537, + "99.9" : 0.013082793771193537, + "99.99" : 0.013082793771193537, + "99.999" : 0.013082793771193537, + "99.9999" : 0.013082793771193537, + "100.0" : 0.013082793771193537 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012979090677596537, + 0.013082793771193537, + 0.013077631711922834 + ], + [ + 0.012727401469218198, + 0.012721508086860284, + 0.01272526352919619 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6305832853859683, + "scoreError" : 0.07908803946707522, + "scoreConfidence" : [ + 3.551495245918893, + 3.7096713248530437 + ], + "scorePercentiles" : { + "0.0" : 3.5858967541218636, + "50.0" : 3.6275817135425212, + "90.0" : 3.661791859443631, + "95.0" : 3.661791859443631, + "99.0" : 3.661791859443631, + "99.9" : 3.661791859443631, + "99.99" : 3.661791859443631, + "99.999" : 3.661791859443631, + "99.9999" : 3.661791859443631, + "100.0" : 3.661791859443631 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5858967541218636, + 3.620618655571635, + 3.624266738405797 + ], + [ + 3.630896688679245, + 3.6600290160936355, + 3.661791859443631 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8635983475617643, + "scoreError" : 0.05318319058426944, + "scoreConfidence" : [ + 2.810415156977495, + 2.916781538146034 + ], + "scorePercentiles" : { + "0.0" : 2.814156100168824, + "50.0" : 2.8762246813344836, + "90.0" : 2.8928681952560025, + "95.0" : 2.8928681952560025, + "99.0" : 2.8928681952560025, + "99.9" : 2.8928681952560025, + "99.99" : 2.8928681952560025, + "99.999" : 2.8928681952560025, + "99.9999" : 2.8928681952560025, + "100.0" : 2.8928681952560025 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8762246813344836, + 2.8830864364370137, + 2.8709831374856485 + ], + [ + 2.830178765138653, + 2.8240756487859966, + 2.814156100168824 + ], + [ + 2.8894638145044786, + 2.8913483489447818, + 2.8928681952560025 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17460592529590413, + "scoreError" : 0.007290842462030162, + "scoreConfidence" : [ + 0.16731508283387397, + 0.18189676775793429 + ], + "scorePercentiles" : { + "0.0" : 0.16902718518330714, + "50.0" : 0.17527733757492903, + "90.0" : 0.1789688415627181, + "95.0" : 0.1789688415627181, + "99.0" : 0.1789688415627181, + "99.9" : 0.1789688415627181, + "99.99" : 0.1789688415627181, + "99.999" : 0.1789688415627181, + "99.9999" : 0.1789688415627181, + "100.0" : 0.1789688415627181 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17740387072911123, + 0.1752745377618088, + 0.17527733757492903 + ], + [ + 0.16919842399837576, + 0.16908881285719116, + 0.16902718518330714 + ], + [ + 0.1789688415627181, + 0.17867402992728118, + 0.17854028806841513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32594856915486825, + "scoreError" : 0.006512483666661735, + "scoreConfidence" : [ + 0.3194360854882065, + 0.33246105282153 + ], + "scorePercentiles" : { + "0.0" : 0.32274181687913506, + "50.0" : 0.32294927724850636, + "90.0" : 0.3315308010542368, + "95.0" : 0.3315308010542368, + "99.0" : 0.3315308010542368, + "99.9" : 0.3315308010542368, + "99.99" : 0.3315308010542368, + "99.999" : 0.3315308010542368, + "99.9999" : 0.3315308010542368, + "100.0" : 0.3315308010542368 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3266327356937549, + 0.32294927724850636, + 0.32284441984116735 + ], + [ + 0.33064299758637794, + 0.3315308010542368, + 0.33034233406005353 + ], + [ + 0.3229322670584816, + 0.32292047297210025, + 0.32274181687913506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16163972415380565, + "scoreError" : 0.007092012523861331, + "scoreConfidence" : [ + 0.15454771162994432, + 0.16873173667766697 + ], + "scorePercentiles" : { + "0.0" : 0.15710679449192483, + "50.0" : 0.16063566504963536, + "90.0" : 0.16717027942159812, + "95.0" : 0.16717027942159812, + "99.0" : 0.16717027942159812, + "99.9" : 0.16717027942159812, + "99.99" : 0.16717027942159812, + "99.999" : 0.16717027942159812, + "99.9999" : 0.16717027942159812, + "100.0" : 0.16717027942159812 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16096042670894428, + 0.16060938489335733, + 0.16063566504963536 + ], + [ + 0.15735056534600497, + 0.15741520246190657, + 0.15710679449192483 + ], + [ + 0.16711328819705554, + 0.16717027942159812, + 0.16639591081382385 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3908731216705499, + "scoreError" : 0.008318461719991843, + "scoreConfidence" : [ + 0.38255465995055804, + 0.3991915833905417 + ], + "scorePercentiles" : { + "0.0" : 0.3850710142472083, + "50.0" : 0.39186429463166145, + "90.0" : 0.39874439389952154, + "95.0" : 0.39874439389952154, + "99.0" : 0.39874439389952154, + "99.9" : 0.39874439389952154, + "99.99" : 0.39874439389952154, + "99.999" : 0.39874439389952154, + "99.9999" : 0.39874439389952154, + "100.0" : 0.39874439389952154 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39874439389952154, + 0.3877659189220628, + 0.386286415868356 + ], + [ + 0.39493609237391886, + 0.3853260085153932, + 0.3850710142472083 + ], + [ + 0.39510388317332384, + 0.3927600734035033, + 0.39186429463166145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1586786249037039, + "scoreError" : 0.0034100905503789674, + "scoreConfidence" : [ + 0.15526853435332494, + 0.16208871545408288 + ], + "scorePercentiles" : { + "0.0" : 0.15661870924496094, + "50.0" : 0.1578523135339058, + "90.0" : 0.16217684937238494, + "95.0" : 0.16217684937238494, + "99.0" : 0.16217684937238494, + "99.9" : 0.16217684937238494, + "99.99" : 0.16217684937238494, + "99.999" : 0.16217684937238494, + "99.9999" : 0.16217684937238494, + "100.0" : 0.16217684937238494 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15877473223358313, + 0.1578523135339058, + 0.15726137488598838 + ], + [ + 0.16217684937238494, + 0.16083772981536285, + 0.16052423554906337 + ], + [ + 0.15739435946549987, + 0.15666732003258604, + 0.15661870924496094 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04705562194714075, + "scoreError" : 0.001724178194025406, + "scoreConfidence" : [ + 0.04533144375311534, + 0.04877980014116615 + ], + "scorePercentiles" : { + "0.0" : 0.04576418512315, + "50.0" : 0.047069235799412586, + "90.0" : 0.048249880785691195, + "95.0" : 0.048249880785691195, + "99.0" : 0.048249880785691195, + "99.9" : 0.048249880785691195, + "99.99" : 0.048249880785691195, + "99.999" : 0.048249880785691195, + "99.9999" : 0.048249880785691195, + "100.0" : 0.048249880785691195 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047069235799412586, + 0.04717382480446822, + 0.046859601845300296 + ], + [ + 0.048249880785691195, + 0.048244426864980386, + 0.048241332310631276 + ], + [ + 0.04600872909506655, + 0.04588938089556622, + 0.04576418512315 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9393487.11191537, + "scoreError" : 76117.81686439089, + "scoreConfidence" : [ + 9317369.295050979, + 9469604.928779762 + ], + "scorePercentiles" : { + "0.0" : 9326570.458527492, + "50.0" : 9421905.214689266, + "90.0" : 9427197.699340245, + "95.0" : 9427197.699340245, + "99.0" : 9427197.699340245, + "99.9" : 9427197.699340245, + "99.99" : 9427197.699340245, + "99.999" : 9427197.699340245, + "99.9999" : 9427197.699340245, + "100.0" : 9427197.699340245 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9423936.029190207, + 9422548.15913371, + 9421905.214689266 + ], + [ + 9331684.680037314, + 9341840.24089636, + 9326570.458527492 + ], + [ + 9427197.699340245, + 9420696.956685498, + 9425004.56873823 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-24T01:16:10Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json b/performance-results/2025-03-24T01:16:10Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json new file mode 100644 index 0000000000..2a0b401278 --- /dev/null +++ b/performance-results/2025-03-24T01:16:10Z-ae7279fa86294a4250c1df7bbf056a940e80459c-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.426145151023948, + "scoreError" : 0.013210663115301039, + "scoreConfidence" : [ + 3.412934487908647, + 3.439355814139249 + ], + "scorePercentiles" : { + "0.0" : 3.4234322248782174, + "50.0" : 3.426652794233978, + "90.0" : 3.427842790749618, + "95.0" : 3.427842790749618, + "99.0" : 3.427842790749618, + "99.9" : 3.427842790749618, + "99.99" : 3.427842790749618, + "99.999" : 3.427842790749618, + "99.9999" : 3.427842790749618, + "100.0" : 3.427842790749618 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4275964386075892, + 3.427842790749618 + ], + [ + 3.4234322248782174, + 3.4257091498603667 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.729128204255764, + "scoreError" : 0.007766170352462106, + "scoreConfidence" : [ + 1.721362033903302, + 1.7368943746082262 + ], + "scorePercentiles" : { + "0.0" : 1.7279808848819176, + "50.0" : 1.7290426231590101, + "90.0" : 1.7304466858231178, + "95.0" : 1.7304466858231178, + "99.0" : 1.7304466858231178, + "99.9" : 1.7304466858231178, + "99.99" : 1.7304466858231178, + "99.999" : 1.7304466858231178, + "99.9999" : 1.7304466858231178, + "100.0" : 1.7304466858231178 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7282477158561975, + 1.7298375304618228 + ], + [ + 1.7279808848819176, + 1.7304466858231178 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8683695224465093, + "scoreError" : 0.0022479338394988647, + "scoreConfidence" : [ + 0.8661215886070105, + 0.8706174562860082 + ], + "scorePercentiles" : { + "0.0" : 0.8679904677398708, + "50.0" : 0.8683417491104126, + "90.0" : 0.8688041238253417, + "95.0" : 0.8688041238253417, + "99.0" : 0.8688041238253417, + "99.9" : 0.8688041238253417, + "99.99" : 0.8688041238253417, + "99.999" : 0.8688041238253417, + "99.9999" : 0.8688041238253417, + "100.0" : 0.8688041238253417 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8682214628124686, + 0.8684620354083565 + ], + [ + 0.8679904677398708, + 0.8688041238253417 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.240687874378818, + "scoreError" : 0.14206130369424322, + "scoreConfidence" : [ + 16.098626570684573, + 16.382749178073063 + ], + "scorePercentiles" : { + "0.0" : 16.102134406564456, + "50.0" : 16.20890091093278, + "90.0" : 16.34498291737838, + "95.0" : 16.34498291737838, + "99.0" : 16.34498291737838, + "99.9" : 16.34498291737838, + "99.99" : 16.34498291737838, + "99.999" : 16.34498291737838, + "99.9999" : 16.34498291737838, + "100.0" : 16.34498291737838 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.33512895649821, + 16.342082271169485, + 16.34498291737838 + ], + [ + 16.20890091093278, + 16.201763368385475, + 16.204084508361756 + ], + [ + 16.102134406564456, + 16.177766103475452, + 16.24934742664334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2768.9873500346007, + "scoreError" : 104.42207140117078, + "scoreConfidence" : [ + 2664.56527863343, + 2873.4094214357715 + ], + "scorePercentiles" : { + "0.0" : 2685.5244079379963, + "50.0" : 2795.830847084459, + "90.0" : 2824.7859522281055, + "95.0" : 2824.7859522281055, + "99.0" : 2824.7859522281055, + "99.9" : 2824.7859522281055, + "99.99" : 2824.7859522281055, + "99.999" : 2824.7859522281055, + "99.9999" : 2824.7859522281055, + "100.0" : 2824.7859522281055 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2687.576466737567, + 2685.5244079379963, + 2691.1189811657555 + ], + [ + 2824.4863505006483, + 2824.7859522281055, + 2824.782033862034 + ], + [ + 2790.6171435181855, + 2796.1639672766546, + 2795.830847084459 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69477.58904509427, + "scoreError" : 2033.1449142317103, + "scoreConfidence" : [ + 67444.44413086255, + 71510.73395932598 + ], + "scorePercentiles" : { + "0.0" : 68354.45274228718, + "50.0" : 68850.00819272888, + "90.0" : 71104.42582085764, + "95.0" : 71104.42582085764, + "99.0" : 71104.42582085764, + "99.9" : 71104.42582085764, + "99.99" : 71104.42582085764, + "99.999" : 71104.42582085764, + "99.9999" : 71104.42582085764, + "100.0" : 71104.42582085764 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68845.9116730038, + 68850.00819272888, + 68933.08606569297 + ], + [ + 68354.45274228718, + 68569.71784579945, + 68527.59360154229 + ], + [ + 71069.65064660512, + 71043.45481733108, + 71104.42582085764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.43246559746035, + "scoreError" : 5.017815172324881, + "scoreConfidence" : [ + 348.41465042513545, + 358.45028076978525 + ], + "scorePercentiles" : { + "0.0" : 348.49531796540316, + "50.0" : 352.22740012108295, + "90.0" : 357.6247499948426, + "95.0" : 357.6247499948426, + "99.0" : 357.6247499948426, + "99.9" : 357.6247499948426, + "99.99" : 357.6247499948426, + "99.999" : 357.6247499948426, + "99.9999" : 357.6247499948426, + "100.0" : 357.6247499948426 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.5264560603956, + 352.22740012108295, + 348.49531796540316 + ], + [ + 356.42376106443544, + 356.8220207221888, + 357.6247499948426 + ], + [ + 352.2169543217317, + 351.9050707919133, + 353.6504593351496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.90948380386186, + "scoreError" : 3.918996971616842, + "scoreConfidence" : [ + 104.99048683224501, + 112.82848077547871 + ], + "scorePercentiles" : { + "0.0" : 105.69252450514203, + "50.0" : 109.97755758368027, + "90.0" : 111.12718275777527, + "95.0" : 111.12718275777527, + "99.0" : 111.12718275777527, + "99.9" : 111.12718275777527, + "99.99" : 111.12718275777527, + "99.999" : 111.12718275777527, + "99.9999" : 111.12718275777527, + "100.0" : 111.12718275777527 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.97755758368027, + 110.15002579246816, + 109.55958182687034 + ], + [ + 110.62620785006521, + 111.11818071668289, + 111.12718275777527 + ], + [ + 105.69252450514203, + 105.96696635595293, + 105.96712684611965 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061097025447483445, + "scoreError" : 0.0011606211932044168, + "scoreConfidence" : [ + 0.05993640425427903, + 0.062257646640687864 + ], + "scorePercentiles" : { + "0.0" : 0.06035415747290153, + "50.0" : 0.06096801351030039, + "90.0" : 0.06199666086385081, + "95.0" : 0.06199666086385081, + "99.0" : 0.06199666086385081, + "99.9" : 0.06199666086385081, + "99.99" : 0.06199666086385081, + "99.999" : 0.06199666086385081, + "99.9999" : 0.06199666086385081, + "100.0" : 0.06199666086385081 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06199666086385081, + 0.061894619520075266, + 0.061959236395516704 + ], + [ + 0.06036282408083686, + 0.06035415747290153, + 0.06040292525837023 + ], + [ + 0.06096801351030039, + 0.06101391860841128, + 0.06092087331708803 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.578972828265755E-4, + "scoreError" : 5.7237137478910345E-6, + "scoreConfidence" : [ + 3.5217356907868446E-4, + 3.6362099657446655E-4 + ], + "scorePercentiles" : { + "0.0" : 3.549562143708115E-4, + "50.0" : 3.5624617220250085E-4, + "90.0" : 3.6339893810142566E-4, + "95.0" : 3.6339893810142566E-4, + "99.0" : 3.6339893810142566E-4, + "99.9" : 3.6339893810142566E-4, + "99.99" : 3.6339893810142566E-4, + "99.999" : 3.6339893810142566E-4, + "99.9999" : 3.6339893810142566E-4, + "100.0" : 3.6339893810142566E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6191391529543857E-4, + 3.6339893810142566E-4, + 3.617474791706142E-4 + ], + [ + 3.563956431412455E-4, + 3.549562143708115E-4, + 3.553836690005984E-4 + ], + [ + 3.5512751742728077E-4, + 3.5590599672926385E-4, + 3.5624617220250085E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014230959816322204, + "scoreError" : 3.529362494757639E-4, + "scoreConfidence" : [ + 0.01387802356684644, + 0.014583896065797968 + ], + "scorePercentiles" : { + "0.0" : 0.014070434197529822, + "50.0" : 0.014109343967413465, + "90.0" : 0.014518360081650312, + "95.0" : 0.014518360081650312, + "99.0" : 0.014518360081650312, + "99.9" : 0.014518360081650312, + "99.99" : 0.014518360081650312, + "99.999" : 0.014518360081650312, + "99.9999" : 0.014518360081650312, + "100.0" : 0.014518360081650312 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014070434197529822, + 0.014071993049926826, + 0.01409282296653415 + ], + [ + 0.014109343967413465, + 0.014115185616529233, + 0.01408806176698895 + ], + [ + 0.014518360081650312, + 0.014509509125652376, + 0.014502927574674702 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9697289381301906, + "scoreError" : 0.00528362052375522, + "scoreConfidence" : [ + 0.9644453176064354, + 0.9750125586539458 + ], + "scorePercentiles" : { + "0.0" : 0.9641568281912842, + "50.0" : 0.9692605071719326, + "90.0" : 0.9739204806194001, + "95.0" : 0.9739204806194001, + "99.0" : 0.9739204806194001, + "99.9" : 0.9739204806194001, + "99.99" : 0.9739204806194001, + "99.999" : 0.9739204806194001, + "99.9999" : 0.9739204806194001, + "100.0" : 0.9739204806194001 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9677952521049066, + 0.9674707717906549, + 0.9706912509948559 + ], + [ + 0.9641568281912842, + 0.9739204806194001, + 0.9733063868613139 + ], + [ + 0.9722907940890531, + 0.9692605071719326, + 0.9686681713483146 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013101354791376594, + "scoreError" : 4.999515490779988E-4, + "scoreConfidence" : [ + 0.012601403242298595, + 0.013601306340454592 + ], + "scorePercentiles" : { + "0.0" : 0.012865263901217797, + "50.0" : 0.013119884615840766, + "90.0" : 0.013265388737961957, + "95.0" : 0.013265388737961957, + "99.0" : 0.013265388737961957, + "99.9" : 0.013265388737961957, + "99.99" : 0.013265388737961957, + "99.999" : 0.013265388737961957, + "99.9999" : 0.013265388737961957, + "100.0" : 0.013265388737961957 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012865263901217797, + 0.012979990903828231, + 0.012984937465915287 + ], + [ + 0.013257715973570058, + 0.013265388737961957, + 0.013254831765766244 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.5684094461451203, + "scoreError" : 0.06843728423472582, + "scoreConfidence" : [ + 3.4999721619103945, + 3.636846730379846 + ], + "scorePercentiles" : { + "0.0" : 3.5270711086036672, + "50.0" : 3.5678580502980344, + "90.0" : 3.595799877785766, + "95.0" : 3.595799877785766, + "99.0" : 3.595799877785766, + "99.9" : 3.595799877785766, + "99.99" : 3.595799877785766, + "99.999" : 3.595799877785766, + "99.9999" : 3.595799877785766, + "100.0" : 3.595799877785766 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5617510263532766, + 3.595799877785766, + 3.5901185635319455 + ], + [ + 3.5270711086036672, + 3.5666760649072753, + 3.569040035688794 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8218470565413725, + "scoreError" : 0.058995670696254006, + "scoreConfidence" : [ + 2.7628513858451185, + 2.8808427272376265 + ], + "scorePercentiles" : { + "0.0" : 2.7884896799553944, + "50.0" : 2.812975501265823, + "90.0" : 2.8689687375215147, + "95.0" : 2.8689687375215147, + "99.0" : 2.8689687375215147, + "99.9" : 2.8689687375215147, + "99.99" : 2.8689687375215147, + "99.999" : 2.8689687375215147, + "99.9999" : 2.8689687375215147, + "100.0" : 2.8689687375215147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.866157445558739, + 2.8689687375215147, + 2.865885706876791 + ], + [ + 2.7884896799553944, + 2.7952312970933484, + 2.788916612660346 + ], + [ + 2.8146177188291586, + 2.812975501265823, + 2.7953808091112355 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17479665863226598, + "scoreError" : 0.0036510964053856694, + "scoreConfidence" : [ + 0.17114556222688032, + 0.17844775503765165 + ], + "scorePercentiles" : { + "0.0" : 0.17170469753266598, + "50.0" : 0.1757618755800056, + "90.0" : 0.17690241083337757, + "95.0" : 0.17690241083337757, + "99.0" : 0.17690241083337757, + "99.9" : 0.17690241083337757, + "99.99" : 0.17690241083337757, + "99.999" : 0.17690241083337757, + "99.9999" : 0.17690241083337757, + "100.0" : 0.17690241083337757 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17690241083337757, + 0.17658258348636813, + 0.17661318091907738 + ], + [ + 0.1757618755800056, + 0.1759331799405359, + 0.17544330049122808 + ], + [ + 0.1724683128503182, + 0.17170469753266598, + 0.171760386056817 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3246266612392709, + "scoreError" : 0.019924162165017714, + "scoreConfidence" : [ + 0.30470249907425323, + 0.3445508234042886 + ], + "scorePercentiles" : { + "0.0" : 0.31273289608155863, + "50.0" : 0.3212355564549806, + "90.0" : 0.3402318470043888, + "95.0" : 0.3402318470043888, + "99.0" : 0.3402318470043888, + "99.9" : 0.3402318470043888, + "99.99" : 0.3402318470043888, + "99.999" : 0.3402318470043888, + "99.9999" : 0.3402318470043888, + "100.0" : 0.3402318470043888 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3220469740435399, + 0.3212355564549806, + 0.32113408535371374 + ], + [ + 0.3128711308700685, + 0.3127965790247412, + 0.31273289608155863 + ], + [ + 0.3402318470043888, + 0.3399265549134913, + 0.3386643274069559 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1609434612920892, + "scoreError" : 0.005787544780688637, + "scoreConfidence" : [ + 0.15515591651140057, + 0.16673100607277783 + ], + "scorePercentiles" : { + "0.0" : 0.157457594693749, + "50.0" : 0.15970487859526966, + "90.0" : 0.16554137850320316, + "95.0" : 0.16554137850320316, + "99.0" : 0.16554137850320316, + "99.9" : 0.16554137850320316, + "99.99" : 0.16554137850320316, + "99.999" : 0.16554137850320316, + "99.9999" : 0.16554137850320316, + "100.0" : 0.16554137850320316 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15970487859526966, + 0.15976183559127072, + 0.1596239163421019 + ], + [ + 0.16554137850320316, + 0.16528086764511438, + 0.16534963091320953 + ], + [ + 0.15787519901172978, + 0.1578958503331544, + 0.157457594693749 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38969563839387505, + "scoreError" : 0.01257371231763372, + "scoreConfidence" : [ + 0.37712192607624134, + 0.40226935071150877 + ], + "scorePercentiles" : { + "0.0" : 0.38017483816149633, + "50.0" : 0.3889050955510617, + "90.0" : 0.40367623961571064, + "95.0" : 0.40367623961571064, + "99.0" : 0.40367623961571064, + "99.9" : 0.40367623961571064, + "99.99" : 0.40367623961571064, + "99.999" : 0.40367623961571064, + "99.9999" : 0.40367623961571064, + "100.0" : 0.40367623961571064 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3834444588190184, + 0.38162887341627233, + 0.38017483816149633 + ], + [ + 0.40367623961571064, + 0.39445489649731774, + 0.39294918110731264 + ], + [ + 0.3941998362568489, + 0.3878273261198371, + 0.3889050955510617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15826806224850987, + "scoreError" : 0.002061095263214545, + "scoreConfidence" : [ + 0.15620696698529532, + 0.1603291575117244 + ], + "scorePercentiles" : { + "0.0" : 0.15657704847497964, + "50.0" : 0.15863054351929698, + "90.0" : 0.1598088950396318, + "95.0" : 0.1598088950396318, + "99.0" : 0.1598088950396318, + "99.9" : 0.1598088950396318, + "99.99" : 0.1598088950396318, + "99.999" : 0.1598088950396318, + "99.9999" : 0.1598088950396318, + "100.0" : 0.1598088950396318 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1598088950396318, + 0.1592978537840292, + 0.15920936771635993 + ], + [ + 0.15691187307788865, + 0.15657704847497964, + 0.15667079597048364 + ], + [ + 0.15878778983470682, + 0.15863054351929698, + 0.15851839281921218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048150610010993106, + "scoreError" : 0.001506079249802445, + "scoreConfidence" : [ + 0.04664453076119066, + 0.04965668926079555 + ], + "scorePercentiles" : { + "0.0" : 0.04693892552782028, + "50.0" : 0.04831327972558398, + "90.0" : 0.04916321137915607, + "95.0" : 0.04916321137915607, + "99.0" : 0.04916321137915607, + "99.9" : 0.04916321137915607, + "99.99" : 0.04916321137915607, + "99.999" : 0.04916321137915607, + "99.9999" : 0.04916321137915607, + "100.0" : 0.04916321137915607 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.048350991471009165, + 0.04831327972558398, + 0.048275269739509914 + ], + [ + 0.04721030312243299, + 0.04699559927439858, + 0.04693892552782028 + ], + [ + 0.04916321137915607, + 0.049058127318573605, + 0.049049782540453314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9279650.608622259, + "scoreError" : 462029.7659555513, + "scoreConfidence" : [ + 8817620.842666708, + 9741680.37457781 + ], + "scorePercentiles" : { + "0.0" : 8933317.997321429, + "50.0" : 9321904.258154707, + "90.0" : 9607548.77137368, + "95.0" : 9607548.77137368, + "99.0" : 9607548.77137368, + "99.9" : 9607548.77137368, + "99.99" : 9607548.77137368, + "99.999" : 9607548.77137368, + "99.9999" : 9607548.77137368, + "100.0" : 9607548.77137368 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8953302.709937332, + 8933317.997321429, + 8941444.654155497 + ], + [ + 9314768.808193669, + 9321904.258154707, + 9337448.018674137 + ], + [ + 9607548.77137368, + 9554760.581661891, + 9552359.678127985 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-03-31T23:20:48Z-cd99d17c3d8134fcfa8ca0ab4f2283c99b1370e7-jdk17.json b/performance-results/2025-03-31T23:20:48Z-cd99d17c3d8134fcfa8ca0ab4f2283c99b1370e7-jdk17.json new file mode 100644 index 0000000000..ac01ce7b4f --- /dev/null +++ b/performance-results/2025-03-31T23:20:48Z-cd99d17c3d8134fcfa8ca0ab4f2283c99b1370e7-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4095002146992455, + "scoreError" : 0.025505340753752086, + "scoreConfidence" : [ + 3.3839948739454933, + 3.4350055554529977 + ], + "scorePercentiles" : { + "0.0" : 3.404163195746615, + "50.0" : 3.4102788182455352, + "90.0" : 3.4132800265592973, + "95.0" : 3.4132800265592973, + "99.0" : 3.4132800265592973, + "99.9" : 3.4132800265592973, + "99.99" : 3.4132800265592973, + "99.999" : 3.4132800265592973, + "99.9999" : 3.4132800265592973, + "100.0" : 3.4132800265592973 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4132800265592973, + 3.411452008475927 + ], + [ + 3.404163195746615, + 3.4091056280151433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7245578519058582, + "scoreError" : 0.024912795202235074, + "scoreConfidence" : [ + 1.6996450567036232, + 1.7494706471080932 + ], + "scorePercentiles" : { + "0.0" : 1.7211598482106032, + "50.0" : 1.7235201540372407, + "90.0" : 1.7300312513383473, + "95.0" : 1.7300312513383473, + "99.0" : 1.7300312513383473, + "99.9" : 1.7300312513383473, + "99.99" : 1.7300312513383473, + "99.999" : 1.7300312513383473, + "99.9999" : 1.7300312513383473, + "100.0" : 1.7300312513383473 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7211598482106032, + 1.7228377141578146 + ], + [ + 1.7242025939166667, + 1.7300312513383473 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8653820156363996, + "scoreError" : 0.010780862871240771, + "scoreConfidence" : [ + 0.8546011527651588, + 0.8761628785076404 + ], + "scorePercentiles" : { + "0.0" : 0.8629236869657826, + "50.0" : 0.8659809453132804, + "90.0" : 0.8666424849532549, + "95.0" : 0.8666424849532549, + "99.0" : 0.8666424849532549, + "99.9" : 0.8666424849532549, + "99.99" : 0.8666424849532549, + "99.999" : 0.8666424849532549, + "99.9999" : 0.8666424849532549, + "100.0" : 0.8666424849532549 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8659980265177031, + 0.8659638641088577 + ], + [ + 0.8629236869657826, + 0.8666424849532549 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.845427151308781, + "scoreError" : 0.23528497239241766, + "scoreConfidence" : [ + 15.610142178916364, + 16.0807121237012 + ], + "scorePercentiles" : { + "0.0" : 15.685382986452229, + "50.0" : 15.794741526952283, + "90.0" : 16.05433497503823, + "95.0" : 16.05433497503823, + "99.0" : 16.05433497503823, + "99.9" : 16.05433497503823, + "99.99" : 16.05433497503823, + "99.999" : 16.05433497503823, + "99.9999" : 16.05433497503823, + "100.0" : 16.05433497503823 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.705963889103662, + 15.983985656350747, + 15.907397863104613 + ], + [ + 15.794741526952283, + 15.685382986452229, + 15.783258404085283 + ], + [ + 15.707878097947686, + 16.05433497503823, + 15.985900962744292 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2618.6331027609417, + "scoreError" : 164.53393097173048, + "scoreConfidence" : [ + 2454.099171789211, + 2783.1670337326723 + ], + "scorePercentiles" : { + "0.0" : 2526.588483782207, + "50.0" : 2574.4482466906097, + "90.0" : 2779.116655176981, + "95.0" : 2779.116655176981, + "99.0" : 2779.116655176981, + "99.9" : 2779.116655176981, + "99.99" : 2779.116655176981, + "99.999" : 2779.116655176981, + "99.9999" : 2779.116655176981, + "100.0" : 2779.116655176981 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2574.4482466906097, + 2567.169496959159, + 2583.5862751102313 + ], + [ + 2691.7266850893725, + 2759.1161944439864, + 2779.116655176981 + ], + [ + 2526.588483782207, + 2550.387208827728, + 2535.558678768202 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70548.16913826618, + "scoreError" : 244.49656136443414, + "scoreConfidence" : [ + 70303.67257690175, + 70792.66569963061 + ], + "scorePercentiles" : { + "0.0" : 70333.39038528103, + "50.0" : 70574.58948612705, + "90.0" : 70727.34078165884, + "95.0" : 70727.34078165884, + "99.0" : 70727.34078165884, + "99.9" : 70727.34078165884, + "99.99" : 70727.34078165884, + "99.999" : 70727.34078165884, + "99.9999" : 70727.34078165884, + "100.0" : 70727.34078165884 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70727.34078165884, + 70333.39038528103, + 70469.07400113309 + ], + [ + 70446.7874393602, + 70574.58948612705, + 70377.48010235681 + ], + [ + 70686.9996314109, + 70637.21329216441, + 70680.64712490341 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 333.90502579287846, + "scoreError" : 10.48452847769103, + "scoreConfidence" : [ + 323.42049731518745, + 344.3895542705695 + ], + "scorePercentiles" : { + "0.0" : 323.7340712326594, + "50.0" : 332.554273388344, + "90.0" : 344.35325070599015, + "95.0" : 344.35325070599015, + "99.0" : 344.35325070599015, + "99.9" : 344.35325070599015, + "99.99" : 344.35325070599015, + "99.999" : 344.35325070599015, + "99.9999" : 344.35325070599015, + "100.0" : 344.35325070599015 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 323.7340712326594, + 330.9442044287599, + 332.554273388344 + ], + [ + 344.35325070599015, + 341.53721675036223, + 330.2777034476568 + ], + [ + 337.1697350039635, + 332.963429061658, + 331.611348116512 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.14950954869005, + "scoreError" : 4.836651540160923, + "scoreConfidence" : [ + 100.31285800852912, + 109.98616108885098 + ], + "scorePercentiles" : { + "0.0" : 100.91133191706817, + "50.0" : 106.59798299070972, + "90.0" : 108.39761451537689, + "95.0" : 108.39761451537689, + "99.0" : 108.39761451537689, + "99.9" : 108.39761451537689, + "99.99" : 108.39761451537689, + "99.999" : 108.39761451537689, + "99.9999" : 108.39761451537689, + "100.0" : 108.39761451537689 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.27462527804794, + 100.91133191706817, + 102.60138617565751 + ], + [ + 106.59798299070972, + 104.85781049140613, + 106.73497928138285 + ], + [ + 108.39761451537689, + 108.05399948905632, + 106.91585579950491 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0635880857287969, + "scoreError" : 0.0011326306299092221, + "scoreConfidence" : [ + 0.062455455098887676, + 0.06472071635870612 + ], + "scorePercentiles" : { + "0.0" : 0.062470017516351305, + "50.0" : 0.0637208354944978, + "90.0" : 0.06454115485794684, + "95.0" : 0.06454115485794684, + "99.0" : 0.06454115485794684, + "99.9" : 0.06454115485794684, + "99.99" : 0.06454115485794684, + "99.999" : 0.06454115485794684, + "99.9999" : 0.06454115485794684, + "100.0" : 0.06454115485794684 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062470017516351305, + 0.06317745563438563, + 0.06288347814522062 + ], + [ + 0.06391383142340362, + 0.06341452927486604, + 0.0637208354944978 + ], + [ + 0.06437003169535384, + 0.06380143751714634, + 0.06454115485794684 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.731061859869773E-4, + "scoreError" : 7.774255833409394E-6, + "scoreConfidence" : [ + 3.6533193015356787E-4, + 3.808804418203867E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6551122994718863E-4, + "50.0" : 3.755504457892557E-4, + "90.0" : 3.7857010140567406E-4, + "95.0" : 3.7857010140567406E-4, + "99.0" : 3.7857010140567406E-4, + "99.9" : 3.7857010140567406E-4, + "99.99" : 3.7857010140567406E-4, + "99.999" : 3.7857010140567406E-4, + "99.9999" : 3.7857010140567406E-4, + "100.0" : 3.7857010140567406E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.757933912683506E-4, + 3.76255239570355E-4, + 3.7088208784642214E-4 + ], + [ + 3.7857010140567406E-4, + 3.755504457892557E-4, + 3.770222975377734E-4 + ], + [ + 3.71370276442085E-4, + 3.670006040756906E-4, + 3.6551122994718863E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014464432942230857, + "scoreError" : 3.773796000125417E-4, + "scoreConfidence" : [ + 0.014087053342218315, + 0.014841812542243399 + ], + "scorePercentiles" : { + "0.0" : 0.01420708790665494, + "50.0" : 0.014423894288491884, + "90.0" : 0.01477697409632679, + "95.0" : 0.01477697409632679, + "99.0" : 0.01477697409632679, + "99.9" : 0.01477697409632679, + "99.99" : 0.01477697409632679, + "99.999" : 0.01477697409632679, + "99.9999" : 0.01477697409632679, + "100.0" : 0.01477697409632679 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014423894288491884, + 0.014402292067465215, + 0.014473567330947153 + ], + [ + 0.01474985725411184, + 0.014677930232216797, + 0.01477697409632679 + ], + [ + 0.01420708790665494, + 0.014254813051832719, + 0.014213480252030371 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0010298916700413, + "scoreError" : 0.015481496915640302, + "scoreConfidence" : [ + 0.985548394754401, + 1.0165113885856816 + ], + "scorePercentiles" : { + "0.0" : 0.991348368259318, + "50.0" : 0.9985827688467299, + "90.0" : 1.022128904333606, + "95.0" : 1.022128904333606, + "99.0" : 1.022128904333606, + "99.9" : 1.022128904333606, + "99.99" : 1.022128904333606, + "99.999" : 1.022128904333606, + "99.9999" : 1.022128904333606, + "100.0" : 1.022128904333606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9941657343672333, + 0.9980671982035928, + 0.991348368259318 + ], + [ + 0.9985827688467299, + 1.0013906113336004, + 1.022128904333606 + ], + [ + 1.005601708396179, + 1.0039356745306696, + 0.9940480567594433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012962170975303838, + "scoreError" : 3.677345354410526E-4, + "scoreConfidence" : [ + 0.012594436439862786, + 0.01332990551074489 + ], + "scorePercentiles" : { + "0.0" : 0.012833838495399187, + "50.0" : 0.012916732160113319, + "90.0" : 0.01318912247864082, + "95.0" : 0.01318912247864082, + "99.0" : 0.01318912247864082, + "99.9" : 0.01318912247864082, + "99.99" : 0.01318912247864082, + "99.999" : 0.01318912247864082, + "99.9999" : 0.01318912247864082, + "100.0" : 0.01318912247864082 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012908908054701438, + 0.01318912247864082, + 0.01304114794828526 + ], + [ + 0.012833838495399187, + 0.012875452609271113, + 0.012924556265525201 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.9034817930410655, + "scoreError" : 0.22224119148390883, + "scoreConfidence" : [ + 3.681240601557157, + 4.125722984524974 + ], + "scorePercentiles" : { + "0.0" : 3.7797827596371882, + "50.0" : 3.8966766567625974, + "90.0" : 3.991222782122905, + "95.0" : 3.991222782122905, + "99.0" : 3.991222782122905, + "99.9" : 3.991222782122905, + "99.99" : 3.991222782122905, + "99.999" : 3.991222782122905, + "99.9999" : 3.991222782122905, + "100.0" : 3.991222782122905 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7797827596371882, + 3.868858556071152, + 3.900277293291732 + ], + [ + 3.893076020233463, + 3.9876733468899523, + 3.991222782122905 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9975317276163223, + "scoreError" : 0.10471051985244478, + "scoreConfidence" : [ + 2.8928212077638773, + 3.102242247468767 + ], + "scorePercentiles" : { + "0.0" : 2.902337391468369, + "50.0" : 3.0179460974652987, + "90.0" : 3.090146808773556, + "95.0" : 3.090146808773556, + "99.0" : 3.090146808773556, + "99.9" : 3.090146808773556, + "99.99" : 3.090146808773556, + "99.999" : 3.090146808773556, + "99.9999" : 3.090146808773556, + "100.0" : 3.090146808773556 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.052372484894721, + 3.0179460974652987, + 3.090146808773556 + ], + [ + 2.997661714028777, + 2.902337391468369, + 2.909984528658714 + ], + [ + 3.0189954114095987, + 2.963754678222222, + 3.0245864336256427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17330625960990392, + "scoreError" : 0.0066047385708272064, + "scoreConfidence" : [ + 0.1667015210390767, + 0.17991099818073114 + ], + "scorePercentiles" : { + "0.0" : 0.1698520789965351, + "50.0" : 0.17148525901982303, + "90.0" : 0.17856710444083354, + "95.0" : 0.17856710444083354, + "99.0" : 0.17856710444083354, + "99.9" : 0.17856710444083354, + "99.99" : 0.17856710444083354, + "99.999" : 0.17856710444083354, + "99.9999" : 0.17856710444083354, + "100.0" : 0.17856710444083354 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17148525901982303, + 0.17180318619753637, + 0.17054395748418233 + ], + [ + 0.17856710444083354, + 0.17850592938488452, + 0.17838055207720163 + ], + [ + 0.17040596131890604, + 0.17021230756923286, + 0.1698520789965351 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3292259542440874, + "scoreError" : 0.012091801546312187, + "scoreConfidence" : [ + 0.31713415269777523, + 0.3413177557903996 + ], + "scorePercentiles" : { + "0.0" : 0.3221258255113545, + "50.0" : 0.3256091559274574, + "90.0" : 0.33965986006385435, + "95.0" : 0.33965986006385435, + "99.0" : 0.33965986006385435, + "99.9" : 0.33965986006385435, + "99.99" : 0.33965986006385435, + "99.999" : 0.33965986006385435, + "99.9999" : 0.33965986006385435, + "100.0" : 0.33965986006385435 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3256091559274574, + 0.32656926765070865, + 0.3250800603972304 + ], + [ + 0.33965986006385435, + 0.33829378360001355, + 0.33800826975596565 + ], + [ + 0.3221258255113545, + 0.32344406209974774, + 0.3242433031904546 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.164591468070587, + "scoreError" : 0.010540941826718983, + "scoreConfidence" : [ + 0.154050526243868, + 0.175132409897306 + ], + "scorePercentiles" : { + "0.0" : 0.15646001839943674, + "50.0" : 0.16499985348468849, + "90.0" : 0.1718761545296736, + "95.0" : 0.1718761545296736, + "99.0" : 0.1718761545296736, + "99.9" : 0.1718761545296736, + "99.99" : 0.1718761545296736, + "99.999" : 0.1718761545296736, + "99.9999" : 0.1718761545296736, + "100.0" : 0.1718761545296736 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16499985348468849, + 0.16565805920453228, + 0.16446735321689362 + ], + [ + 0.17158116838529244, + 0.1712827279562894, + 0.1718761545296736 + ], + [ + 0.15763110239435066, + 0.15646001839943674, + 0.15736677506412577 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39030310779049593, + "scoreError" : 0.0062346041971935336, + "scoreConfidence" : [ + 0.3840685035933024, + 0.39653771198768945 + ], + "scorePercentiles" : { + "0.0" : 0.3861410541740675, + "50.0" : 0.38990841648471614, + "90.0" : 0.3984212686454183, + "95.0" : 0.3984212686454183, + "99.0" : 0.3984212686454183, + "99.9" : 0.3984212686454183, + "99.99" : 0.3984212686454183, + "99.999" : 0.3984212686454183, + "99.9999" : 0.3984212686454183, + "100.0" : 0.3984212686454183 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38856887371774945, + 0.38621954667284597, + 0.3861410541740675 + ], + [ + 0.3902935326854779, + 0.38990841648471614, + 0.389275338030362 + ], + [ + 0.3984212686454183, + 0.39248510859497643, + 0.39141483110884967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15973932982259292, + "scoreError" : 0.004125870217414085, + "scoreConfidence" : [ + 0.15561345960517883, + 0.16386520004000701 + ], + "scorePercentiles" : { + "0.0" : 0.15601926915876185, + "50.0" : 0.1600415154837161, + "90.0" : 0.16276038462289638, + "95.0" : 0.16276038462289638, + "99.0" : 0.16276038462289638, + "99.9" : 0.16276038462289638, + "99.99" : 0.16276038462289638, + "99.999" : 0.16276038462289638, + "99.9999" : 0.16276038462289638, + "100.0" : 0.16276038462289638 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16039395408032334, + 0.1600415154837161, + 0.1600059933438935 + ], + [ + 0.1571330822098614, + 0.15717875150495889, + 0.15601926915876185 + ], + [ + 0.16276038462289638, + 0.16258213159049895, + 0.16153888640842567 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04749754239285639, + "scoreError" : 6.638648530745888E-4, + "scoreConfidence" : [ + 0.0468336775397818, + 0.04816140724593098 + ], + "scorePercentiles" : { + "0.0" : 0.04688907084816175, + "50.0" : 0.04767168074233331, + "90.0" : 0.04789557901240481, + "95.0" : 0.04789557901240481, + "99.0" : 0.04789557901240481, + "99.9" : 0.04789557901240481, + "99.99" : 0.04789557901240481, + "99.999" : 0.04789557901240481, + "99.9999" : 0.04789557901240481, + "100.0" : 0.04789557901240481 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046991556753302285, + 0.04688907084816175, + 0.04708833516975091 + ], + [ + 0.047696189976295295, + 0.04767168074233331, + 0.04775386363592952 + ], + [ + 0.04789557901240481, + 0.047608589495784316, + 0.04788301590174531 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9596764.60533551, + "scoreError" : 238953.03479679223, + "scoreConfidence" : [ + 9357811.570538716, + 9835717.640132302 + ], + "scorePercentiles" : { + "0.0" : 9416117.540921919, + "50.0" : 9583250.818007663, + "90.0" : 9791073.728962818, + "95.0" : 9791073.728962818, + "99.0" : 9791073.728962818, + "99.9" : 9791073.728962818, + "99.99" : 9791073.728962818, + "99.999" : 9791073.728962818, + "99.9999" : 9791073.728962818, + "100.0" : 9791073.728962818 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9583250.818007663, + 9601638.153550863, + 9492654.818785578 + ], + [ + 9515580.683158897, + 9452075.962192817, + 9416117.540921919 + ], + [ + 9759589.867317073, + 9758899.875121951, + 9791073.728962818 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-01T21:33:42Z-12273f47d604fd8003c1cb1a2a8924e8f7626f89-jdk17.json b/performance-results/2025-04-01T21:33:42Z-12273f47d604fd8003c1cb1a2a8924e8f7626f89-jdk17.json new file mode 100644 index 0000000000..93c7bd839e --- /dev/null +++ b/performance-results/2025-04-01T21:33:42Z-12273f47d604fd8003c1cb1a2a8924e8f7626f89-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.420985462330865, + "scoreError" : 0.021308159867503323, + "scoreConfidence" : [ + 3.399677302463362, + 3.442293622198368 + ], + "scorePercentiles" : { + "0.0" : 3.418007258992135, + "50.0" : 3.420373229961676, + "90.0" : 3.425188130407973, + "95.0" : 3.425188130407973, + "99.0" : 3.425188130407973, + "99.9" : 3.425188130407973, + "99.99" : 3.425188130407973, + "99.999" : 3.425188130407973, + "99.9999" : 3.425188130407973, + "100.0" : 3.425188130407973 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.418007258992135, + 3.42200693473186 + ], + [ + 3.4187395251914925, + 3.425188130407973 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7259211816186313, + "scoreError" : 0.011219628682282887, + "scoreConfidence" : [ + 1.7147015529363483, + 1.7371408103009143 + ], + "scorePercentiles" : { + "0.0" : 1.7240481148983835, + "50.0" : 1.7259595429086452, + "90.0" : 1.727717525758852, + "95.0" : 1.727717525758852, + "99.0" : 1.727717525758852, + "99.9" : 1.727717525758852, + "99.99" : 1.727717525758852, + "99.999" : 1.727717525758852, + "99.9999" : 1.727717525758852, + "100.0" : 1.727717525758852 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.724885876907566, + 1.7270332089097247 + ], + [ + 1.7240481148983835, + 1.727717525758852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8674466325046533, + "scoreError" : 0.007705896262075907, + "scoreConfidence" : [ + 0.8597407362425773, + 0.8751525287667292 + ], + "scorePercentiles" : { + "0.0" : 0.8666059785196016, + "50.0" : 0.866992153998527, + "90.0" : 0.8691962435019575, + "95.0" : 0.8691962435019575, + "99.0" : 0.8691962435019575, + "99.9" : 0.8691962435019575, + "99.99" : 0.8691962435019575, + "99.999" : 0.8691962435019575, + "99.9999" : 0.8691962435019575, + "100.0" : 0.8691962435019575 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8667857553889012, + 0.8691962435019575 + ], + [ + 0.8666059785196016, + 0.8671985526081527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.154507473954208, + "scoreError" : 0.3032032937894869, + "scoreConfidence" : [ + 15.851304180164721, + 16.457710767743695 + ], + "scorePercentiles" : { + "0.0" : 15.883888547322103, + "50.0" : 16.237351237284106, + "90.0" : 16.350840322494335, + "95.0" : 16.350840322494335, + "99.0" : 16.350840322494335, + "99.9" : 16.350840322494335, + "99.99" : 16.350840322494335, + "99.999" : 16.350840322494335, + "99.9999" : 16.350840322494335, + "100.0" : 16.350840322494335 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.217804435983428, + 16.350840322494335, + 16.237351237284106 + ], + [ + 15.902125351212634, + 15.977259361703576, + 15.883888547322103 + ], + [ + 16.276565741155228, + 16.272309984981842, + 16.272422283450616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2644.344808486787, + "scoreError" : 86.02528562254417, + "scoreConfidence" : [ + 2558.3195228642426, + 2730.370094109331 + ], + "scorePercentiles" : { + "0.0" : 2586.8209241778127, + "50.0" : 2637.5472685222603, + "90.0" : 2708.2319955639605, + "95.0" : 2708.2319955639605, + "99.0" : 2708.2319955639605, + "99.9" : 2708.2319955639605, + "99.99" : 2708.2319955639605, + "99.999" : 2708.2319955639605, + "99.9999" : 2708.2319955639605, + "100.0" : 2708.2319955639605 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2637.5472685222603, + 2634.608120991165, + 2640.9078602226705 + ], + [ + 2707.3095209289977, + 2703.7568171125213, + 2708.2319955639605 + ], + [ + 2587.4985780982424, + 2592.4221907634533, + 2586.8209241778127 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70325.77067177565, + "scoreError" : 1291.3849307178716, + "scoreConfidence" : [ + 69034.38574105778, + 71617.15560249353 + ], + "scorePercentiles" : { + "0.0" : 69322.45195764846, + "50.0" : 70592.4237150667, + "90.0" : 71095.16711300776, + "95.0" : 71095.16711300776, + "99.0" : 71095.16711300776, + "99.9" : 71095.16711300776, + "99.99" : 71095.16711300776, + "99.999" : 71095.16711300776, + "99.9999" : 71095.16711300776, + "100.0" : 71095.16711300776 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70613.44484999884, + 70468.08939852084, + 70592.4237150667 + ], + [ + 71073.30799444801, + 71049.2033306343, + 71095.16711300776 + ], + [ + 69354.70219205428, + 69322.45195764846, + 69363.1454946017 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 340.7577166349173, + "scoreError" : 13.198336746781516, + "scoreConfidence" : [ + 327.55937988813577, + 353.95605338169884 + ], + "scorePercentiles" : { + "0.0" : 330.78040096354056, + "50.0" : 341.8254902127628, + "90.0" : 349.35471838817614, + "95.0" : 349.35471838817614, + "99.0" : 349.35471838817614, + "99.9" : 349.35471838817614, + "99.99" : 349.35471838817614, + "99.999" : 349.35471838817614, + "99.9999" : 349.35471838817614, + "100.0" : 349.35471838817614 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.31589625960527, + 349.35471838817614, + 349.2481281662378 + ], + [ + 330.78040096354056, + 331.33226859378885, + 331.6847680735642 + ], + [ + 342.2954285076341, + 341.8254902127628, + 340.98235054894616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.89965983414605, + "scoreError" : 1.0234192467503809, + "scoreConfidence" : [ + 107.87624058739567, + 109.92307908089643 + ], + "scorePercentiles" : { + "0.0" : 108.37603229365496, + "50.0" : 108.5505522600155, + "90.0" : 109.83768561008253, + "95.0" : 109.83768561008253, + "99.0" : 109.83768561008253, + "99.9" : 109.83768561008253, + "99.99" : 109.83768561008253, + "99.999" : 109.83768561008253, + "99.9999" : 109.83768561008253, + "100.0" : 109.83768561008253 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.37603229365496, + 108.5505522600155, + 108.56280243220073 + ], + [ + 109.55591592645746, + 109.83768561008253, + 109.71555007594219 + ], + [ + 108.48281995549353, + 108.4905998536738, + 108.52498009979388 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06272724120605161, + "scoreError" : 0.0022162873271655403, + "scoreConfidence" : [ + 0.06051095387888607, + 0.06494352853321715 + ], + "scorePercentiles" : { + "0.0" : 0.06136190240535068, + "50.0" : 0.06223583766694465, + "90.0" : 0.06464186464858017, + "95.0" : 0.06464186464858017, + "99.0" : 0.06464186464858017, + "99.9" : 0.06464186464858017, + "99.99" : 0.06464186464858017, + "99.999" : 0.06464186464858017, + "99.9999" : 0.06464186464858017, + "100.0" : 0.06464186464858017 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0640337739962861, + 0.06457937539311984, + 0.06464186464858017 + ], + [ + 0.06165480211595847, + 0.06136190240535068, + 0.061548181982680625 + ], + [ + 0.06226324983967474, + 0.06223583766694465, + 0.062226182805869105 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.710390379094124E-4, + "scoreError" : 1.1928445832262768E-5, + "scoreConfidence" : [ + 3.591105920771496E-4, + 3.829674837416752E-4 + ], + "scorePercentiles" : { + "0.0" : 3.626336021150838E-4, + "50.0" : 3.705256004146279E-4, + "90.0" : 3.799144246528192E-4, + "95.0" : 3.799144246528192E-4, + "99.0" : 3.799144246528192E-4, + "99.9" : 3.799144246528192E-4, + "99.99" : 3.799144246528192E-4, + "99.999" : 3.799144246528192E-4, + "99.9999" : 3.799144246528192E-4, + "100.0" : 3.799144246528192E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.799144246528192E-4, + 3.793384301920466E-4, + 3.7943793885042047E-4 + ], + [ + 3.626336021150838E-4, + 3.6448350332461536E-4, + 3.62749219272948E-4 + ], + [ + 3.70708421954848E-4, + 3.705256004146279E-4, + 3.695602004073025E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014321677295737002, + "scoreError" : 4.099545398900902E-4, + "scoreConfidence" : [ + 0.013911722755846912, + 0.014731631835627092 + ], + "scorePercentiles" : { + "0.0" : 0.014128172541091303, + "50.0" : 0.014189505785698575, + "90.0" : 0.014654304488123552, + "95.0" : 0.014654304488123552, + "99.0" : 0.014654304488123552, + "99.9" : 0.014654304488123552, + "99.99" : 0.014654304488123552, + "99.999" : 0.014654304488123552, + "99.9999" : 0.014654304488123552, + "100.0" : 0.014654304488123552 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014189505785698575, + 0.014186176067956552, + 0.014195022822474986 + ], + [ + 0.014128172541091303, + 0.014130851554584623, + 0.014130318505141966 + ], + [ + 0.014640681621466511, + 0.01464006227509494, + 0.014654304488123552 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.058156856583621, + "scoreError" : 0.15887940561407896, + "scoreConfidence" : [ + 0.899277450969542, + 1.2170362621977 + ], + "scorePercentiles" : { + "0.0" : 0.9879297991702065, + "50.0" : 1.0016554988982371, + "90.0" : 1.18968641232453, + "95.0" : 1.18968641232453, + "99.0" : 1.18968641232453, + "99.9" : 1.18968641232453, + "99.99" : 1.18968641232453, + "99.999" : 1.18968641232453, + "99.9999" : 1.18968641232453, + "100.0" : 1.18968641232453 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.18968641232453, + 1.1785333975960406, + 1.183730490530303 + ], + [ + 1.0016554988982371, + 1.0042734961839728, + 0.9910632743038351 + ], + [ + 0.9879297991702065, + 0.9945502313276977, + 0.9919891089177661 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01328452052372637, + "scoreError" : 9.392093654110593E-4, + "scoreConfidence" : [ + 0.012345311158315312, + 0.01422372988913743 + ], + "scorePercentiles" : { + "0.0" : 0.012975986001863305, + "50.0" : 0.013256764035906334, + "90.0" : 0.01362551115901114, + "95.0" : 0.01362551115901114, + "99.0" : 0.01362551115901114, + "99.9" : 0.01362551115901114, + "99.99" : 0.01362551115901114, + "99.999" : 0.01362551115901114, + "99.9999" : 0.01362551115901114, + "100.0" : 0.01362551115901114 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01362551115901114, + 0.013530204566610382, + 0.013610755139983395 + ], + [ + 0.012975986001863305, + 0.012983323505202288, + 0.012981342769687702 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8199575825224277, + "scoreError" : 0.05323858201215984, + "scoreConfidence" : [ + 3.766719000510268, + 3.8731961645345874 + ], + "scorePercentiles" : { + "0.0" : 3.796875929384966, + "50.0" : 3.819544478009818, + "90.0" : 3.8509473918398767, + "95.0" : 3.8509473918398767, + "99.0" : 3.8509473918398767, + "99.9" : 3.8509473918398767, + "99.99" : 3.8509473918398767, + "99.999" : 3.8509473918398767, + "99.9999" : 3.8509473918398767, + "100.0" : 3.8509473918398767 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8140265087719296, + 3.8509473918398767, + 3.8269707582249426 + ], + [ + 3.796875929384966, + 3.8058624596651445, + 3.8250624472477064 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.901999271654215, + "scoreError" : 0.06511539595555306, + "scoreConfidence" : [ + 2.836883875698662, + 2.9671146676097684 + ], + "scorePercentiles" : { + "0.0" : 2.863777385738832, + "50.0" : 2.8855375709751874, + "90.0" : 2.9610254289520426, + "95.0" : 2.9610254289520426, + "99.0" : 2.9610254289520426, + "99.9" : 2.9610254289520426, + "99.99" : 2.9610254289520426, + "99.999" : 2.9610254289520426, + "99.9999" : 2.9610254289520426, + "100.0" : 2.9610254289520426 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.863777385738832, + 2.873600486494253, + 2.8855375709751874 + ], + [ + 2.8745960767461916, + 2.871018776406429, + 2.8936733446180556 + ], + [ + 2.9540984152392205, + 2.9610254289520426, + 2.9406659597177303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18278995623871602, + "scoreError" : 0.01646910130162921, + "scoreConfidence" : [ + 0.16632085493708682, + 0.19925905754034523 + ], + "scorePercentiles" : { + "0.0" : 0.17524887399891348, + "50.0" : 0.17712125903294368, + "90.0" : 0.1963312424658879, + "95.0" : 0.1963312424658879, + "99.0" : 0.1963312424658879, + "99.9" : 0.1963312424658879, + "99.99" : 0.1963312424658879, + "99.999" : 0.1963312424658879, + "99.9999" : 0.1963312424658879, + "100.0" : 0.1963312424658879 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17712125903294368, + 0.17764719309683263, + 0.17682571326519786 + ], + [ + 0.1963312424658879, + 0.19568520027786473, + 0.19540450698555992 + ], + [ + 0.17527204134534494, + 0.17557357567989887, + 0.17524887399891348 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3232566254882523, + "scoreError" : 0.02282913570582237, + "scoreConfidence" : [ + 0.30042748978242995, + 0.34608576119407464 + ], + "scorePercentiles" : { + "0.0" : 0.3092274280148423, + "50.0" : 0.3201938921298668, + "90.0" : 0.3405121527853446, + "95.0" : 0.3405121527853446, + "99.0" : 0.3405121527853446, + "99.9" : 0.3405121527853446, + "99.99" : 0.3405121527853446, + "99.999" : 0.3405121527853446, + "99.9999" : 0.3405121527853446, + "100.0" : 0.3405121527853446 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32029835740823775, + 0.31994934137445613, + 0.3201938921298668 + ], + [ + 0.3405121527853446, + 0.3400584822157236, + 0.34022206205559147 + ], + [ + 0.3092274280148423, + 0.30933073147947665, + 0.30951718193073136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1657651871890437, + "scoreError" : 0.007932720842646653, + "scoreConfidence" : [ + 0.15783246634639705, + 0.17369790803169036 + ], + "scorePercentiles" : { + "0.0" : 0.1593353740320576, + "50.0" : 0.16877857649659922, + "90.0" : 0.16972019656495027, + "95.0" : 0.16972019656495027, + "99.0" : 0.16972019656495027, + "99.9" : 0.16972019656495027, + "99.99" : 0.16972019656495027, + "99.999" : 0.16972019656495027, + "99.9999" : 0.16972019656495027, + "100.0" : 0.16972019656495027 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16877857649659922, + 0.16808839190506605, + 0.16972019656495027 + ], + [ + 0.1593642279485586, + 0.15979414727877025, + 0.1593353740320576 + ], + [ + 0.1687985193099723, + 0.16892914557924255, + 0.16907810558617659 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3922519583598169, + "scoreError" : 0.00540791058135611, + "scoreConfidence" : [ + 0.3868440477784608, + 0.397659868941173 + ], + "scorePercentiles" : { + "0.0" : 0.38899327481717755, + "50.0" : 0.3920643285372643, + "90.0" : 0.39907136154674966, + "95.0" : 0.39907136154674966, + "99.0" : 0.39907136154674966, + "99.9" : 0.39907136154674966, + "99.99" : 0.39907136154674966, + "99.999" : 0.39907136154674966, + "99.9999" : 0.39907136154674966, + "100.0" : 0.39907136154674966 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3941107479703634, + 0.39320674989187276, + 0.39292061883619506 + ], + [ + 0.39907136154674966, + 0.3920643285372643, + 0.3918314238304208 + ], + [ + 0.38903332743328406, + 0.38899327481717755, + 0.38903579237502434 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15861264541642875, + "scoreError" : 0.003450571682714868, + "scoreConfidence" : [ + 0.15516207373371388, + 0.16206321709914362 + ], + "scorePercentiles" : { + "0.0" : 0.15590977652359644, + "50.0" : 0.15834482064761302, + "90.0" : 0.1617350184858728, + "95.0" : 0.1617350184858728, + "99.0" : 0.1617350184858728, + "99.9" : 0.1617350184858728, + "99.99" : 0.1617350184858728, + "99.999" : 0.1617350184858728, + "99.9999" : 0.1617350184858728, + "100.0" : 0.1617350184858728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.160611737548785, + 0.15831396635901657, + 0.15834482064761302 + ], + [ + 0.1566366366299104, + 0.15627956014314962, + 0.15590977652359644 + ], + [ + 0.1617350184858728, + 0.16011737287647107, + 0.15956491953344396 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047483792777320843, + "scoreError" : 3.9679518207553995E-4, + "scoreConfidence" : [ + 0.0470869975952453, + 0.047880587959396384 + ], + "scorePercentiles" : { + "0.0" : 0.04715763853285422, + "50.0" : 0.047544488575204914, + "90.0" : 0.047805480103640816, + "95.0" : 0.047805480103640816, + "99.0" : 0.047805480103640816, + "99.9" : 0.047805480103640816, + "99.99" : 0.047805480103640816, + "99.999" : 0.047805480103640816, + "99.9999" : 0.047805480103640816, + "100.0" : 0.047805480103640816 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047805480103640816, + 0.0477210462219762, + 0.04757783843280919 + ], + [ + 0.04722691685832621, + 0.04715763853285422, + 0.04722577149684536 + ], + [ + 0.04766301272586019, + 0.047544488575204914, + 0.04743194204837049 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9409975.270078996, + "scoreError" : 266484.5794582535, + "scoreConfidence" : [ + 9143490.690620743, + 9676459.84953725 + ], + "scorePercentiles" : { + "0.0" : 9229127.362546125, + "50.0" : 9368682.052434457, + "90.0" : 9608553.345821325, + "95.0" : 9608553.345821325, + "99.0" : 9608553.345821325, + "99.9" : 9608553.345821325, + "99.99" : 9608553.345821325, + "99.999" : 9608553.345821325, + "99.9999" : 9608553.345821325, + "100.0" : 9608553.345821325 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9229127.362546125, + 9258536.712303422, + 9247606.292051757 + ], + [ + 9608553.345821325, + 9604708.076775432, + 9604726.285988484 + ], + [ + 9404343.094924811, + 9363494.20786517, + 9368682.052434457 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-01T22:24:13Z-dff69a4069ce12440d48b3d0bdd6cc1c10d6b6b0-jdk17.json b/performance-results/2025-04-01T22:24:13Z-dff69a4069ce12440d48b3d0bdd6cc1c10d6b6b0-jdk17.json new file mode 100644 index 0000000000..cc683602ae --- /dev/null +++ b/performance-results/2025-04-01T22:24:13Z-dff69a4069ce12440d48b3d0bdd6cc1c10d6b6b0-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4194744891916873, + "scoreError" : 0.02554187101683565, + "scoreConfidence" : [ + 3.3939326181748517, + 3.445016360208523 + ], + "scorePercentiles" : { + "0.0" : 3.415566520359219, + "50.0" : 3.4189396043971776, + "90.0" : 3.4244522276131746, + "95.0" : 3.4244522276131746, + "99.0" : 3.4244522276131746, + "99.9" : 3.4244522276131746, + "99.99" : 3.4244522276131746, + "99.999" : 3.4244522276131746, + "99.9999" : 3.4244522276131746, + "100.0" : 3.4244522276131746 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4171721747963577, + 3.4244522276131746 + ], + [ + 3.415566520359219, + 3.4207070339979975 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7266663105789197, + "scoreError" : 0.00869904524406742, + "scoreConfidence" : [ + 1.7179672653348523, + 1.7353653558229871 + ], + "scorePercentiles" : { + "0.0" : 1.724945010664874, + "50.0" : 1.7267529382479703, + "90.0" : 1.7282143551548643, + "95.0" : 1.7282143551548643, + "99.0" : 1.7282143551548643, + "99.9" : 1.7282143551548643, + "99.99" : 1.7282143551548643, + "99.999" : 1.7282143551548643, + "99.9999" : 1.7282143551548643, + "100.0" : 1.7282143551548643 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.724945010664874, + 1.7265763975379063 + ], + [ + 1.726929478958034, + 1.7282143551548643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8628031120549917, + "scoreError" : 0.0767462701324756, + "scoreConfidence" : [ + 0.7860568419225161, + 0.9395493821874673 + ], + "scorePercentiles" : { + "0.0" : 0.8451682861185522, + "50.0" : 0.867492884671893, + "90.0" : 0.8710583927576289, + "95.0" : 0.8710583927576289, + "99.0" : 0.8710583927576289, + "99.9" : 0.8710583927576289, + "99.99" : 0.8710583927576289, + "99.999" : 0.8710583927576289, + "99.9999" : 0.8710583927576289, + "100.0" : 0.8710583927576289 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8673623407164245, + 0.8676234286273615 + ], + [ + 0.8710583927576289, + 0.8451682861185522 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.31392561301447, + "scoreError" : 0.1312391844802445, + "scoreConfidence" : [ + 16.182686428534225, + 16.445164797494712 + ], + "scorePercentiles" : { + "0.0" : 16.21093971066763, + "50.0" : 16.302884394353885, + "90.0" : 16.46017338456293, + "95.0" : 16.46017338456293, + "99.0" : 16.46017338456293, + "99.9" : 16.46017338456293, + "99.99" : 16.46017338456293, + "99.999" : 16.46017338456293, + "99.9999" : 16.46017338456293, + "100.0" : 16.46017338456293 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.335544036726933, + 16.3881504707433, + 16.338990592960965 + ], + [ + 16.46017338456293, + 16.300954823858877, + 16.302884394353885 + ], + [ + 16.250290632880514, + 16.23740247037521, + 16.21093971066763 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2756.9992365127205, + "scoreError" : 113.15020257290064, + "scoreConfidence" : [ + 2643.84903393982, + 2870.149439085621 + ], + "scorePercentiles" : { + "0.0" : 2698.7491764529773, + "50.0" : 2720.6434970594128, + "90.0" : 2847.352513628344, + "95.0" : 2847.352513628344, + "99.0" : 2847.352513628344, + "99.9" : 2847.352513628344, + "99.99" : 2847.352513628344, + "99.999" : 2847.352513628344, + "99.9999" : 2847.352513628344, + "100.0" : 2847.352513628344 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2708.7644589191254, + 2720.6434970594128, + 2722.404526193519 + ], + [ + 2710.1717555299124, + 2698.7491764529773, + 2713.328570944813 + ], + [ + 2846.681855022229, + 2847.352513628344, + 2844.896774864152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69904.38873607699, + "scoreError" : 1519.5438025687874, + "scoreConfidence" : [ + 68384.8449335082, + 71423.93253864578 + ], + "scorePercentiles" : { + "0.0" : 68682.559730696, + "50.0" : 70478.32467330323, + "90.0" : 70580.13042248992, + "95.0" : 70580.13042248992, + "99.0" : 70580.13042248992, + "99.9" : 70580.13042248992, + "99.99" : 70580.13042248992, + "99.999" : 70580.13042248992, + "99.9999" : 70580.13042248992, + "100.0" : 70580.13042248992 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68682.559730696, + 68708.866932472, + 68707.26495938459 + ], + [ + 70518.02892766449, + 70457.87631837883, + 70478.32467330323 + ], + [ + 70508.3088102308, + 70498.13785007298, + 70580.13042248992 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.97170890665683, + "scoreError" : 8.839750478157988, + "scoreConfidence" : [ + 342.1319584284988, + 359.81145938481484 + ], + "scorePercentiles" : { + "0.0" : 344.2073326740012, + "50.0" : 350.7670243218901, + "90.0" : 357.7030520279713, + "95.0" : 357.7030520279713, + "99.0" : 357.7030520279713, + "99.9" : 357.7030520279713, + "99.99" : 357.7030520279713, + "99.999" : 357.7030520279713, + "99.9999" : 357.7030520279713, + "100.0" : 357.7030520279713 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.5023818760904, + 356.86336793959464, + 357.7030520279713 + ], + [ + 344.51655037432863, + 344.2073326740012, + 346.18135193755194 + ], + [ + 351.4179954510821, + 350.7670243218901, + 350.58632355740076 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.13558739995234, + "scoreError" : 0.9471044773107464, + "scoreConfidence" : [ + 106.1884829226416, + 108.08269187726309 + ], + "scorePercentiles" : { + "0.0" : 106.41150472365675, + "50.0" : 106.98591081143343, + "90.0" : 108.05644484593567, + "95.0" : 108.05644484593567, + "99.0" : 108.05644484593567, + "99.9" : 108.05644484593567, + "99.99" : 108.05644484593567, + "99.999" : 108.05644484593567, + "99.9999" : 108.05644484593567, + "100.0" : 108.05644484593567 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.05644484593567, + 106.98591081143343, + 106.86280167853995 + ], + [ + 107.3278838833463, + 107.63659682409566, + 107.66812717658092 + ], + [ + 106.62162483191045, + 106.41150472365675, + 106.64939182407181 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06116770333920915, + "scoreError" : 4.8614906962900385E-4, + "scoreConfidence" : [ + 0.06068155426958015, + 0.06165385240883815 + ], + "scorePercentiles" : { + "0.0" : 0.060782978586450445, + "50.0" : 0.061090301025083386, + "90.0" : 0.06161584813121542, + "95.0" : 0.06161584813121542, + "99.0" : 0.06161584813121542, + "99.9" : 0.06161584813121542, + "99.99" : 0.06161584813121542, + "99.999" : 0.06161584813121542, + "99.9999" : 0.06161584813121542, + "100.0" : 0.06161584813121542 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06153806217731365, + 0.06138916308364743, + 0.06161584813121542 + ], + [ + 0.061090301025083386, + 0.06104354878525211, + 0.061186428299589445 + ], + [ + 0.06095554725825328, + 0.06090745270607725, + 0.060782978586450445 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.695521446448638E-4, + "scoreError" : 2.8262222982506193E-5, + "scoreConfidence" : [ + 3.412899216623576E-4, + 3.9781436762737E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5000887232047905E-4, + "50.0" : 3.6917912816374846E-4, + "90.0" : 3.8959380126631364E-4, + "95.0" : 3.8959380126631364E-4, + "99.0" : 3.8959380126631364E-4, + "99.9" : 3.8959380126631364E-4, + "99.99" : 3.8959380126631364E-4, + "99.999" : 3.8959380126631364E-4, + "99.9999" : 3.8959380126631364E-4, + "100.0" : 3.8959380126631364E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5046645867463925E-4, + 3.5000887232047905E-4, + 3.5024093424695045E-4 + ], + [ + 3.8959380126631364E-4, + 3.8892023345357696E-4, + 3.886819629837889E-4 + ], + [ + 3.700855260474804E-4, + 3.6917912816374846E-4, + 3.687923846467969E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014166576121955722, + "scoreError" : 2.1144263631359052E-4, + "scoreConfidence" : [ + 0.01395513348564213, + 0.014378018758269313 + ], + "scorePercentiles" : { + "0.0" : 0.014046923717671385, + "50.0" : 0.014122111461491641, + "90.0" : 0.01439731619304848, + "95.0" : 0.01439731619304848, + "99.0" : 0.01439731619304848, + "99.9" : 0.01439731619304848, + "99.99" : 0.01439731619304848, + "99.999" : 0.01439731619304848, + "99.9999" : 0.01439731619304848, + "100.0" : 0.01439731619304848 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01439731619304848, + 0.014281812945140039, + 0.014289442321377029 + ], + [ + 0.014058839168851619, + 0.014046923717671385, + 0.014048392538699385 + ], + [ + 0.01413298399034446, + 0.014122111461491641, + 0.01412136276097747 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9740776945547436, + "scoreError" : 0.009058175914346716, + "scoreConfidence" : [ + 0.9650195186403968, + 0.9831358704690903 + ], + "scorePercentiles" : { + "0.0" : 0.9649532202817445, + "50.0" : 0.9764470310486233, + "90.0" : 0.979412945255117, + "95.0" : 0.979412945255117, + "99.0" : 0.979412945255117, + "99.9" : 0.979412945255117, + "99.99" : 0.979412945255117, + "99.999" : 0.979412945255117, + "99.9999" : 0.979412945255117, + "100.0" : 0.979412945255117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9791201020168396, + 0.9764470310486233, + 0.9716871637193937 + ], + [ + 0.9707747388856532, + 0.9649532202817445, + 0.9679974266769916 + ], + [ + 0.979412945255117, + 0.9793519523063363, + 0.9769546708019927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013012135619588671, + "scoreError" : 3.106285482246328E-4, + "scoreConfidence" : [ + 0.012701507071364039, + 0.013322764167813304 + ], + "scorePercentiles" : { + "0.0" : 0.012917852429793061, + "50.0" : 0.012971381308933288, + "90.0" : 0.013147150097681156, + "95.0" : 0.013147150097681156, + "99.0" : 0.013147150097681156, + "99.9" : 0.013147150097681156, + "99.99" : 0.013147150097681156, + "99.999" : 0.013147150097681156, + "99.9999" : 0.013147150097681156, + "100.0" : 0.013147150097681156 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012917852429793061, + 0.012919215704208975, + 0.012924454169714609 + ], + [ + 0.013018308448151966, + 0.013145832867982269, + 0.013147150097681156 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.632083144066653, + "scoreError" : 0.07389883297062878, + "scoreConfidence" : [ + 3.5581843110960243, + 3.7059819770372817 + ], + "scorePercentiles" : { + "0.0" : 3.590731975592247, + "50.0" : 3.6395454342607834, + "90.0" : 3.6549121504747992, + "95.0" : 3.6549121504747992, + "99.0" : 3.6549121504747992, + "99.9" : 3.6549121504747992, + "99.99" : 3.6549121504747992, + "99.999" : 3.6549121504747992, + "99.9999" : 3.6549121504747992, + "100.0" : 3.6549121504747992 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6517999656934306, + 3.6549121504747992, + 3.6541691212563916 + ], + [ + 3.590731975592247, + 3.613594748554913, + 3.627290902828136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.814660377440884, + "scoreError" : 0.024490734182133617, + "scoreConfidence" : [ + 2.7901696432587504, + 2.8391511116230173 + ], + "scorePercentiles" : { + "0.0" : 2.797245694825175, + "50.0" : 2.8061119545454547, + "90.0" : 2.8349407777777778, + "95.0" : 2.8349407777777778, + "99.0" : 2.8349407777777778, + "99.9" : 2.8349407777777778, + "99.99" : 2.8349407777777778, + "99.999" : 2.8349407777777778, + "99.9999" : 2.8349407777777778, + "100.0" : 2.8349407777777778 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8255445700564974, + 2.8261645255721954, + 2.8051827203366058 + ], + [ + 2.8037174272497896, + 2.797245694825175, + 2.8016132535014004 + ], + [ + 2.8349407777777778, + 2.831422473103058, + 2.8061119545454547 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18077341062741054, + "scoreError" : 0.014353792857067442, + "scoreConfidence" : [ + 0.1664196177703431, + 0.19512720348447798 + ], + "scorePercentiles" : { + "0.0" : 0.17193353889930024, + "50.0" : 0.1785189516405441, + "90.0" : 0.19204514456905822, + "95.0" : 0.19204514456905822, + "99.0" : 0.19204514456905822, + "99.9" : 0.19204514456905822, + "99.99" : 0.19204514456905822, + "99.999" : 0.19204514456905822, + "99.9999" : 0.19204514456905822, + "100.0" : 0.19204514456905822 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19204514456905822, + 0.19126840104047127, + 0.19137153131757725 + ], + [ + 0.17851557071707813, + 0.17853092246581212, + 0.1785189516405441 + ], + [ + 0.17207392991603002, + 0.17193353889930024, + 0.17270270508082344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3255786312013808, + "scoreError" : 0.006781671949494997, + "scoreConfidence" : [ + 0.31879695925188584, + 0.3323603031508758 + ], + "scorePercentiles" : { + "0.0" : 0.3198157626083341, + "50.0" : 0.32745385523903076, + "90.0" : 0.32982301777704487, + "95.0" : 0.32982301777704487, + "99.0" : 0.32982301777704487, + "99.9" : 0.32982301777704487, + "99.99" : 0.32982301777704487, + "99.999" : 0.32982301777704487, + "99.9999" : 0.32982301777704487, + "100.0" : 0.32982301777704487 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32040968607221815, + 0.3207289064143682, + 0.3198157626083341 + ], + [ + 0.32693975477311366, + 0.32745385523903076, + 0.3277725755162242 + ], + [ + 0.32982301777704487, + 0.32863060256325993, + 0.3286335198488334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16520958330540386, + "scoreError" : 0.003904719990913554, + "scoreConfidence" : [ + 0.16130486331449032, + 0.1691143032963174 + ], + "scorePercentiles" : { + "0.0" : 0.1623530315934735, + "50.0" : 0.1654880534015125, + "90.0" : 0.16782697615211628, + "95.0" : 0.16782697615211628, + "99.0" : 0.16782697615211628, + "99.9" : 0.16782697615211628, + "99.99" : 0.16782697615211628, + "99.999" : 0.16782697615211628, + "99.9999" : 0.16782697615211628, + "100.0" : 0.16782697615211628 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16251762683438156, + 0.1623530315934735, + 0.16235577231548529 + ], + [ + 0.16781707266319854, + 0.16782697615211628, + 0.16760257225220393 + ], + [ + 0.16563840416404413, + 0.1652867403722191, + 0.1654880534015125 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3928930526593304, + "scoreError" : 0.0025513234074087984, + "scoreConfidence" : [ + 0.39034172925192157, + 0.3954443760667392 + ], + "scorePercentiles" : { + "0.0" : 0.3907715779766324, + "50.0" : 0.392861043134944, + "90.0" : 0.39614403272064647, + "95.0" : 0.39614403272064647, + "99.0" : 0.39614403272064647, + "99.9" : 0.39614403272064647, + "99.99" : 0.39614403272064647, + "99.999" : 0.39614403272064647, + "99.9999" : 0.39614403272064647, + "100.0" : 0.39614403272064647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3937948602087025, + 0.3928797329692779, + 0.3920452974360985 + ], + [ + 0.39313111813035617, + 0.3915590486687549, + 0.3907715779766324 + ], + [ + 0.39614403272064647, + 0.392861043134944, + 0.3928507626885607 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15668086807705478, + "scoreError" : 0.0026468715335953544, + "scoreConfidence" : [ + 0.15403399654345942, + 0.15932773961065014 + ], + "scorePercentiles" : { + "0.0" : 0.15500656603890567, + "50.0" : 0.15602657285507, + "90.0" : 0.1587486827634378, + "95.0" : 0.1587486827634378, + "99.0" : 0.1587486827634378, + "99.9" : 0.1587486827634378, + "99.99" : 0.1587486827634378, + "99.999" : 0.1587486827634378, + "99.9999" : 0.1587486827634378, + "100.0" : 0.1587486827634378 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1564891541844016, + 0.15550979076602495, + 0.15500656603890567 + ], + [ + 0.15869252295412348, + 0.1586838797683275, + 0.1587486827634378 + ], + [ + 0.15602657285507, + 0.15557162095519603, + 0.15539902240800596 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047155284663097694, + "scoreError" : 4.936480783222632E-4, + "scoreConfidence" : [ + 0.04666163658477543, + 0.04764893274141996 + ], + "scorePercentiles" : { + "0.0" : 0.04676411413981285, + "50.0" : 0.047194693460316864, + "90.0" : 0.04768852778055957, + "95.0" : 0.04768852778055957, + "99.0" : 0.04768852778055957, + "99.9" : 0.04768852778055957, + "99.99" : 0.04768852778055957, + "99.999" : 0.04768852778055957, + "99.9999" : 0.04768852778055957, + "100.0" : 0.04768852778055957 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04768852778055957, + 0.047379118801701835, + 0.047233946125687834 + ], + [ + 0.047268657425789375, + 0.04714530012776209, + 0.047194693460316864 + ], + [ + 0.04693128750703961, + 0.04679191659920923, + 0.04676411413981285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9336798.090218965, + "scoreError" : 189887.07302217573, + "scoreConfidence" : [ + 9146911.01719679, + 9526685.16324114 + ], + "scorePercentiles" : { + "0.0" : 9185498.928374656, + "50.0" : 9326856.899347624, + "90.0" : 9472147.553977273, + "95.0" : 9472147.553977273, + "99.0" : 9472147.553977273, + "99.9" : 9472147.553977273, + "99.99" : 9472147.553977273, + "99.999" : 9472147.553977273, + "99.9999" : 9472147.553977273, + "100.0" : 9472147.553977273 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9224735.104147466, + 9185498.928374656, + 9203164.059797607 + ], + [ + 9472147.553977273, + 9452682.468809074, + 9455593.06899811 + ], + [ + 9388428.242964353, + 9326856.899347624, + 9322076.48555452 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-02T00:54:25Z-14343b248c8e4c4f6f5e3567656bf546701169c7-jdk17.json b/performance-results/2025-04-02T00:54:25Z-14343b248c8e4c4f6f5e3567656bf546701169c7-jdk17.json new file mode 100644 index 0000000000..46a74f75af --- /dev/null +++ b/performance-results/2025-04-02T00:54:25Z-14343b248c8e4c4f6f5e3567656bf546701169c7-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.421526384634706, + "scoreError" : 0.024204253048581707, + "scoreConfidence" : [ + 3.397322131586124, + 3.4457306376832877 + ], + "scorePercentiles" : { + "0.0" : 3.4173147730655797, + "50.0" : 3.421193313876114, + "90.0" : 3.426404137721016, + "95.0" : 3.426404137721016, + "99.0" : 3.426404137721016, + "99.9" : 3.426404137721016, + "99.99" : 3.426404137721016, + "99.999" : 3.426404137721016, + "99.9999" : 3.426404137721016, + "100.0" : 3.426404137721016 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.420782629000279, + 3.426404137721016 + ], + [ + 3.4173147730655797, + 3.4216039987519493 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7283454988973057, + "scoreError" : 0.0025880343464985893, + "scoreConfidence" : [ + 1.7257574645508071, + 1.7309335332438043 + ], + "scorePercentiles" : { + "0.0" : 1.7279527704336943, + "50.0" : 1.7282621497493265, + "90.0" : 1.728904925656876, + "95.0" : 1.728904925656876, + "99.0" : 1.728904925656876, + "99.9" : 1.728904925656876, + "99.99" : 1.728904925656876, + "99.999" : 1.728904925656876, + "99.9999" : 1.728904925656876, + "100.0" : 1.728904925656876 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7279527704336943, + 1.7282545511010183 + ], + [ + 1.7282697483976346, + 1.728904925656876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8691224272889502, + "scoreError" : 0.0033289897328440546, + "scoreConfidence" : [ + 0.8657934375561062, + 0.8724514170217942 + ], + "scorePercentiles" : { + "0.0" : 0.8686308534225845, + "50.0" : 0.869010981659937, + "90.0" : 0.8698368924133419, + "95.0" : 0.8698368924133419, + "99.0" : 0.8698368924133419, + "99.9" : 0.8698368924133419, + "99.99" : 0.8698368924133419, + "99.999" : 0.8698368924133419, + "99.9999" : 0.8698368924133419, + "100.0" : 0.8698368924133419 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8686308534225845, + 0.869109060504571 + ], + [ + 0.868912902815303, + 0.8698368924133419 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.309649787987688, + "scoreError" : 0.07794437405308531, + "scoreConfidence" : [ + 16.231705413934602, + 16.387594162040774 + ], + "scorePercentiles" : { + "0.0" : 16.26765662772302, + "50.0" : 16.28656758905185, + "90.0" : 16.38712193348276, + "95.0" : 16.38712193348276, + "99.0" : 16.38712193348276, + "99.9" : 16.38712193348276, + "99.99" : 16.38712193348276, + "99.999" : 16.38712193348276, + "99.9999" : 16.38712193348276, + "100.0" : 16.38712193348276 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.28656758905185, + 16.273200002371972, + 16.299111445359156 + ], + [ + 16.366013192165212, + 16.3540962884704, + 16.38712193348276 + ], + [ + 16.26765662772302, + 16.26851464142473, + 16.28456637184009 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2712.6069740459716, + "scoreError" : 11.038642078368325, + "scoreConfidence" : [ + 2701.568331967603, + 2723.64561612434 + ], + "scorePercentiles" : { + "0.0" : 2703.8693752278577, + "50.0" : 2711.819323271369, + "90.0" : 2722.840900870486, + "95.0" : 2722.840900870486, + "99.0" : 2722.840900870486, + "99.9" : 2722.840900870486, + "99.99" : 2722.840900870486, + "99.999" : 2722.840900870486, + "99.9999" : 2722.840900870486, + "100.0" : 2722.840900870486 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2711.6700217383127, + 2712.519688484181, + 2711.819323271369 + ], + [ + 2722.840900870486, + 2713.2880055354126, + 2722.7197608423567 + ], + [ + 2703.8693752278577, + 2708.9476508866146, + 2705.7880395571538 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70977.29311251568, + "scoreError" : 253.57898466017767, + "scoreConfidence" : [ + 70723.71412785549, + 71230.87209717586 + ], + "scorePercentiles" : { + "0.0" : 70751.37602239971, + "50.0" : 70921.36587253957, + "90.0" : 71183.33947884571, + "95.0" : 71183.33947884571, + "99.0" : 71183.33947884571, + "99.9" : 71183.33947884571, + "99.99" : 71183.33947884571, + "99.999" : 71183.33947884571, + "99.9999" : 71183.33947884571, + "100.0" : 71183.33947884571 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70913.88389465859, + 70969.59237313575, + 70921.36587253957 + ], + [ + 70844.70664555264, + 70751.37602239971, + 70911.93988780752 + ], + [ + 71158.56853347426, + 71140.86530422738, + 71183.33947884571 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.31244511380766, + "scoreError" : 6.666002229820555, + "scoreConfidence" : [ + 343.6464428839871, + 356.9784473436282 + ], + "scorePercentiles" : { + "0.0" : 345.20414333375453, + "50.0" : 350.5234018035162, + "90.0" : 355.26663651937116, + "95.0" : 355.26663651937116, + "99.0" : 355.26663651937116, + "99.9" : 355.26663651937116, + "99.99" : 355.26663651937116, + "99.999" : 355.26663651937116, + "99.9999" : 355.26663651937116, + "100.0" : 355.26663651937116 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.0198481362827, + 354.58181399517474, + 355.26663651937116 + ], + [ + 350.5234018035162, + 350.38433326530674, + 351.37866449831887 + ], + [ + 345.20414333375453, + 345.84513014838336, + 345.6080343241608 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.87761273102751, + "scoreError" : 2.104556922800753, + "scoreConfidence" : [ + 102.77305580822676, + 106.98216965382827 + ], + "scorePercentiles" : { + "0.0" : 103.59739904226069, + "50.0" : 104.47823668180365, + "90.0" : 106.64228593068609, + "95.0" : 106.64228593068609, + "99.0" : 106.64228593068609, + "99.9" : 106.64228593068609, + "99.99" : 106.64228593068609, + "99.999" : 106.64228593068609, + "99.9999" : 106.64228593068609, + "100.0" : 106.64228593068609 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 103.59739904226069, + 103.72012032272589, + 103.6785773206504 + ], + [ + 104.57502425284017, + 104.47823668180365, + 104.42984806950203 + ], + [ + 106.64228593068609, + 106.3804639830908, + 106.39655897568788 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061408572434368404, + "scoreError" : 4.563862938090769E-4, + "scoreConfidence" : [ + 0.06095218614055933, + 0.06186495872817748 + ], + "scorePercentiles" : { + "0.0" : 0.06097075857086242, + "50.0" : 0.061388873282667684, + "90.0" : 0.06178538960661835, + "95.0" : 0.06178538960661835, + "99.0" : 0.06178538960661835, + "99.9" : 0.06178538960661835, + "99.99" : 0.06178538960661835, + "99.999" : 0.06178538960661835, + "99.9999" : 0.06178538960661835, + "100.0" : 0.06178538960661835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06097075857086242, + 0.061146214680974656, + 0.0612855844349249 + ], + [ + 0.061388873282667684, + 0.06155373061392818, + 0.06124024126422281 + ], + [ + 0.06178538960661835, + 0.061691854335031895, + 0.06161450512008478 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7316652617251883E-4, + "scoreError" : 8.119757313773042E-6, + "scoreConfidence" : [ + 3.6504676885874577E-4, + 3.812862834862919E-4 + ], + "scorePercentiles" : { + "0.0" : 3.667738323748724E-4, + "50.0" : 3.752289794739548E-4, + "90.0" : 3.778600239409276E-4, + "95.0" : 3.778600239409276E-4, + "99.0" : 3.778600239409276E-4, + "99.9" : 3.778600239409276E-4, + "99.99" : 3.778600239409276E-4, + "99.999" : 3.778600239409276E-4, + "99.9999" : 3.778600239409276E-4, + "100.0" : 3.778600239409276E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.668491935524401E-4, + 3.667738323748724E-4, + 3.6701340072654664E-4 + ], + [ + 3.778600239409276E-4, + 3.7740688490455637E-4, + 3.7720805236979543E-4 + ], + [ + 3.754190644322722E-4, + 3.7473930377730384E-4, + 3.752289794739548E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014008341450335656, + "scoreError" : 1.4498033977860858E-4, + "scoreConfidence" : [ + 0.013863361110557047, + 0.014153321790114266 + ], + "scorePercentiles" : { + "0.0" : 0.013880233651371766, + "50.0" : 0.013988460148024223, + "90.0" : 0.014114319541008596, + "95.0" : 0.014114319541008596, + "99.0" : 0.014114319541008596, + "99.9" : 0.014114319541008596, + "99.99" : 0.014114319541008596, + "99.999" : 0.014114319541008596, + "99.9999" : 0.014114319541008596, + "100.0" : 0.014114319541008596 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014114319541008596, + 0.014112022618451226, + 0.014106586750966642 + ], + [ + 0.013912293381858856, + 0.013880233651371766, + 0.013970244557602174 + ], + [ + 0.013988460148024223, + 0.014002486228898102, + 0.01398842617483931 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9778241649362742, + "scoreError" : 0.004838244956807494, + "scoreConfidence" : [ + 0.9729859199794667, + 0.9826624098930817 + ], + "scorePercentiles" : { + "0.0" : 0.9736546614740531, + "50.0" : 0.9773280237467018, + "90.0" : 0.9821452236299352, + "95.0" : 0.9821452236299352, + "99.0" : 0.9821452236299352, + "99.9" : 0.9821452236299352, + "99.99" : 0.9821452236299352, + "99.999" : 0.9821452236299352, + "99.9999" : 0.9821452236299352, + "100.0" : 0.9821452236299352 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9749890558642879, + 0.9736546614740531, + 0.9772415279976546 + ], + [ + 0.9773280237467018, + 0.9776727197184476, + 0.9762410675517376 + ], + [ + 0.9819867925176747, + 0.9821452236299352, + 0.9791584119259767 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012869722100222638, + "scoreError" : 3.8966084585346096E-4, + "scoreConfidence" : [ + 0.012480061254369177, + 0.013259382946076098 + ], + "scorePercentiles" : { + "0.0" : 0.012669512538736168, + "50.0" : 0.012853368862123522, + "90.0" : 0.013023504013752508, + "95.0" : 0.013023504013752508, + "99.0" : 0.013023504013752508, + "99.9" : 0.013023504013752508, + "99.99" : 0.013023504013752508, + "99.999" : 0.013023504013752508, + "99.9999" : 0.013023504013752508, + "100.0" : 0.013023504013752508 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012900479146832615, + 0.013020436614143498, + 0.013023504013752508 + ], + [ + 0.012669512538736168, + 0.0127981417104566, + 0.012806258577414431 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.5468241771900515, + "scoreError" : 0.21376380574191445, + "scoreConfidence" : [ + 3.333060371448137, + 3.760587982931966 + ], + "scorePercentiles" : { + "0.0" : 3.453652321132597, + "50.0" : 3.551183448477694, + "90.0" : 3.61925639146165, + "95.0" : 3.61925639146165, + "99.0" : 3.61925639146165, + "99.9" : 3.61925639146165, + "99.99" : 3.61925639146165, + "99.999" : 3.61925639146165, + "99.9999" : 3.61925639146165, + "100.0" : 3.61925639146165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.453652321132597, + 3.4880539741980474, + 3.4936314308659218 + ], + [ + 3.6176154793926245, + 3.61925639146165, + 3.608735466089466 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8304880688757925, + "scoreError" : 0.07599696860642481, + "scoreConfidence" : [ + 2.7544911002693677, + 2.9064850374822173 + ], + "scorePercentiles" : { + "0.0" : 2.780787323324993, + "50.0" : 2.814811319729806, + "90.0" : 2.8892461886192953, + "95.0" : 2.8892461886192953, + "99.0" : 2.8892461886192953, + "99.9" : 2.8892461886192953, + "99.99" : 2.8892461886192953, + "99.999" : 2.8892461886192953, + "99.9999" : 2.8892461886192953, + "100.0" : 2.8892461886192953 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8892461886192953, + 2.8884606503032053, + 2.887350749133949 + ], + [ + 2.793379465083799, + 2.7882133852801783, + 2.780787323324993 + ], + [ + 2.8192035718714767, + 2.814811319729806, + 2.812939966535433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17450209716197213, + "scoreError" : 0.005812830363912847, + "scoreConfidence" : [ + 0.1686892667980593, + 0.18031492752588496 + ], + "scorePercentiles" : { + "0.0" : 0.170191207610749, + "50.0" : 0.1748316288921135, + "90.0" : 0.17852150263312924, + "95.0" : 0.17852150263312924, + "99.0" : 0.17852150263312924, + "99.9" : 0.17852150263312924, + "99.99" : 0.17852150263312924, + "99.999" : 0.17852150263312924, + "99.9999" : 0.17852150263312924, + "100.0" : 0.17852150263312924 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17498419680134386, + 0.1748316288921135, + 0.17469628181611727 + ], + [ + 0.17852150263312924, + 0.17834503670281068, + 0.17807120077281954 + ], + [ + 0.1706394429731759, + 0.170191207610749, + 0.1702383762554901 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33112232276848347, + "scoreError" : 0.01408401635978298, + "scoreConfidence" : [ + 0.3170383064087005, + 0.3452063391282664 + ], + "scorePercentiles" : { + "0.0" : 0.3189610034765413, + "50.0" : 0.33347466086434574, + "90.0" : 0.33958328683486705, + "95.0" : 0.33958328683486705, + "99.0" : 0.33958328683486705, + "99.9" : 0.33958328683486705, + "99.99" : 0.33958328683486705, + "99.999" : 0.33958328683486705, + "99.9999" : 0.33958328683486705, + "100.0" : 0.33958328683486705 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3213060990553913, + 0.3212401773209123, + 0.3189610034765413 + ], + [ + 0.3333820681090812, + 0.3337180653073483, + 0.33347466086434574 + ], + [ + 0.33958328683486705, + 0.3391921009734423, + 0.3392434429744216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15903038363523334, + "scoreError" : 0.0032727032804364393, + "scoreConfidence" : [ + 0.1557576803547969, + 0.16230308691566978 + ], + "scorePercentiles" : { + "0.0" : 0.1568177738748628, + "50.0" : 0.15869251267931953, + "90.0" : 0.16177639883523418, + "95.0" : 0.16177639883523418, + "99.0" : 0.16177639883523418, + "99.9" : 0.16177639883523418, + "99.99" : 0.16177639883523418, + "99.999" : 0.16177639883523418, + "99.9999" : 0.16177639883523418, + "100.0" : 0.16177639883523418 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15893024055179428, + 0.1585677964830495, + 0.15869251267931953 + ], + [ + 0.15714625532316107, + 0.15691627485132356, + 0.1568177738748628 + ], + [ + 0.16131501726029165, + 0.16111118285806347, + 0.16177639883523418 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39920263185700916, + "scoreError" : 0.01508577615443086, + "scoreConfidence" : [ + 0.3841168557025783, + 0.41428840801144 + ], + "scorePercentiles" : { + "0.0" : 0.3892273552718639, + "50.0" : 0.3956107737558351, + "90.0" : 0.4115906599991769, + "95.0" : 0.4115906599991769, + "99.0" : 0.4115906599991769, + "99.9" : 0.4115906599991769, + "99.99" : 0.4115906599991769, + "99.999" : 0.4115906599991769, + "99.9999" : 0.4115906599991769, + "100.0" : 0.4115906599991769 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39916488715922244, + 0.394366896561243, + 0.3937410017324199 + ], + [ + 0.4115906599991769, + 0.4101335106016487, + 0.40964308319678844 + ], + [ + 0.3956107737558351, + 0.3893455184348842, + 0.3892273552718639 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15671659954710748, + "scoreError" : 0.002376152157258202, + "scoreConfidence" : [ + 0.15434044738984928, + 0.15909275170436568 + ], + "scorePercentiles" : { + "0.0" : 0.15505241405668568, + "50.0" : 0.1567589684761651, + "90.0" : 0.15864113097069973, + "95.0" : 0.15864113097069973, + "99.0" : 0.15864113097069973, + "99.9" : 0.15864113097069973, + "99.99" : 0.15864113097069973, + "99.999" : 0.15864113097069973, + "99.9999" : 0.15864113097069973, + "100.0" : 0.15864113097069973 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15712338663859474, + 0.1567589684761651, + 0.15637328781410767 + ], + [ + 0.15864113097069973, + 0.15834399254215817, + 0.15792437585079672 + ], + [ + 0.15505241405668568, + 0.15506374830596517, + 0.15516809126879452 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046883255194173766, + "scoreError" : 9.061111451677109E-4, + "scoreConfidence" : [ + 0.045977144049006054, + 0.04778936633934148 + ], + "scorePercentiles" : { + "0.0" : 0.046237800306090364, + "50.0" : 0.046795298544688814, + "90.0" : 0.04808867215992152, + "95.0" : 0.04808867215992152, + "99.0" : 0.04808867215992152, + "99.9" : 0.04808867215992152, + "99.99" : 0.04808867215992152, + "99.999" : 0.04808867215992152, + "99.9999" : 0.04808867215992152, + "100.0" : 0.04808867215992152 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046750469346061786, + 0.046892388873518806, + 0.047285378485471784 + ], + [ + 0.046619141515195306, + 0.04643861545641564, + 0.046237800306090364 + ], + [ + 0.04808867215992152, + 0.046795298544688814, + 0.04684153206019982 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9241780.57363828, + "scoreError" : 265931.63507504837, + "scoreConfidence" : [ + 8975848.938563233, + 9507712.208713328 + ], + "scorePercentiles" : { + "0.0" : 9038273.207768744, + "50.0" : 9277086.333951762, + "90.0" : 9444023.251180358, + "95.0" : 9444023.251180358, + "99.0" : 9444023.251180358, + "99.9" : 9444023.251180358, + "99.99" : 9444023.251180358, + "99.999" : 9444023.251180358, + "99.9999" : 9444023.251180358, + "100.0" : 9444023.251180358 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9444023.251180358, + 9391734.985915493, + 9381496.035647279 + ], + [ + 9278744.134508349, + 9262558.790740741, + 9277086.333951762 + ], + [ + 9061707.098731885, + 9040401.32429991, + 9038273.207768744 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-02T23:08:02Z-5a0354109936c23ea8738604500215b1936cbd6f-jdk17.json b/performance-results/2025-04-02T23:08:02Z-5a0354109936c23ea8738604500215b1936cbd6f-jdk17.json new file mode 100644 index 0000000000..41be86bf29 --- /dev/null +++ b/performance-results/2025-04-02T23:08:02Z-5a0354109936c23ea8738604500215b1936cbd6f-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.424479155837928, + "scoreError" : 0.011075372549510833, + "scoreConfidence" : [ + 3.4134037832884174, + 3.435554528387439 + ], + "scorePercentiles" : { + "0.0" : 3.4222286409542613, + "50.0" : 3.424837405471688, + "90.0" : 3.426013171454075, + "95.0" : 3.426013171454075, + "99.0" : 3.426013171454075, + "99.9" : 3.426013171454075, + "99.99" : 3.426013171454075, + "99.999" : 3.426013171454075, + "99.9999" : 3.426013171454075, + "100.0" : 3.426013171454075 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.426013171454075, + 3.4255917004773675 + ], + [ + 3.4222286409542613, + 3.4240831104660083 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.730114924834354, + "scoreError" : 0.015068036624339469, + "scoreConfidence" : [ + 1.7150468882100145, + 1.7451829614586933 + ], + "scorePercentiles" : { + "0.0" : 1.7278191249827204, + "50.0" : 1.7300845809684677, + "90.0" : 1.7324714124177591, + "95.0" : 1.7324714124177591, + "99.0" : 1.7324714124177591, + "99.9" : 1.7324714124177591, + "99.99" : 1.7324714124177591, + "99.999" : 1.7324714124177591, + "99.9999" : 1.7324714124177591, + "100.0" : 1.7324714124177591 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7278191249827204, + 1.7317408171276252 + ], + [ + 1.7284283448093105, + 1.7324714124177591 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8681857109496245, + "scoreError" : 0.0035043749820760526, + "scoreConfidence" : [ + 0.8646813359675485, + 0.8716900859317005 + ], + "scorePercentiles" : { + "0.0" : 0.8676305266413037, + "50.0" : 0.8682075476996174, + "90.0" : 0.8686972217579596, + "95.0" : 0.8686972217579596, + "99.0" : 0.8686972217579596, + "99.9" : 0.8686972217579596, + "99.99" : 0.8686972217579596, + "99.999" : 0.8686972217579596, + "99.9999" : 0.8686972217579596, + "100.0" : 0.8686972217579596 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8678129209888844, + 0.8686021744103505 + ], + [ + 0.8676305266413037, + 0.8686972217579596 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.387280261757567, + "scoreError" : 0.10028607635809765, + "scoreConfidence" : [ + 16.286994185399468, + 16.487566338115666 + ], + "scorePercentiles" : { + "0.0" : 16.299881227884125, + "50.0" : 16.410224457562155, + "90.0" : 16.457636875301638, + "95.0" : 16.457636875301638, + "99.0" : 16.457636875301638, + "99.9" : 16.457636875301638, + "99.99" : 16.457636875301638, + "99.999" : 16.457636875301638, + "99.9999" : 16.457636875301638, + "100.0" : 16.457636875301638 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.299881227884125, + 16.328028210173624, + 16.30546147881785 + ], + [ + 16.457636875301638, + 16.429821212221743, + 16.410224457562155 + ], + [ + 16.412175542163634, + 16.436125687636725, + 16.406167664056625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2642.0682457066564, + "scoreError" : 114.34022799708357, + "scoreConfidence" : [ + 2527.7280177095727, + 2756.40847370374 + ], + "scorePercentiles" : { + "0.0" : 2555.2046983574915, + "50.0" : 2659.7345801498823, + "90.0" : 2713.6502722405826, + "95.0" : 2713.6502722405826, + "99.0" : 2713.6502722405826, + "99.9" : 2713.6502722405826, + "99.99" : 2713.6502722405826, + "99.999" : 2713.6502722405826, + "99.9999" : 2713.6502722405826, + "100.0" : 2713.6502722405826 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2706.2844882940467, + 2712.2668309135865, + 2713.6502722405826 + ], + [ + 2555.3276391760605, + 2555.2046983574915, + 2558.8986334792153 + ], + [ + 2661.411687999915, + 2655.8353807491285, + 2659.7345801498823 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69729.45525114956, + "scoreError" : 2962.4156855070937, + "scoreConfidence" : [ + 66767.03956564247, + 72691.87093665665 + ], + "scorePercentiles" : { + "0.0" : 67361.01966300381, + "50.0" : 70738.98053842774, + "90.0" : 71080.73631929721, + "95.0" : 71080.73631929721, + "99.0" : 71080.73631929721, + "99.9" : 71080.73631929721, + "99.99" : 71080.73631929721, + "99.999" : 71080.73631929721, + "99.9999" : 71080.73631929721, + "100.0" : 71080.73631929721 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 67411.41767701558, + 67361.01966300381, + 67389.57797458366 + ], + [ + 71080.73631929721, + 71053.29571140243, + 71079.39665194794 + ], + [ + 70705.69662773378, + 70744.97609693388, + 70738.98053842774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.94580919495104, + "scoreError" : 10.159825623076115, + "scoreConfidence" : [ + 343.7859835718749, + 364.10563481802717 + ], + "scorePercentiles" : { + "0.0" : 347.0369763846074, + "50.0" : 353.17931736004226, + "90.0" : 361.39092290805024, + "95.0" : 361.39092290805024, + "99.0" : 361.39092290805024, + "99.9" : 361.39092290805024, + "99.99" : 361.39092290805024, + "99.999" : 361.39092290805024, + "99.9999" : 361.39092290805024, + "100.0" : 361.39092290805024 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 347.3977135026078, + 347.69793010856546, + 347.0369763846074 + ], + [ + 361.2079659440757, + 361.21748163628587, + 361.39092290805024 + ], + [ + 353.2714724807457, + 353.17931736004226, + 353.11250242957925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.68682541606691, + "scoreError" : 2.1175975242501184, + "scoreConfidence" : [ + 105.5692278918168, + 109.80442294031702 + ], + "scorePercentiles" : { + "0.0" : 106.26146297343669, + "50.0" : 107.34763854854604, + "90.0" : 109.36109832163555, + "95.0" : 109.36109832163555, + "99.0" : 109.36109832163555, + "99.9" : 109.36109832163555, + "99.99" : 109.36109832163555, + "99.999" : 109.36109832163555, + "99.9999" : 109.36109832163555, + "100.0" : 109.36109832163555 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.19339810163474, + 109.30825077522033, + 109.36109832163555 + ], + [ + 107.00354599780425, + 106.4757245889034, + 106.26146297343669 + ], + [ + 106.74918851780693, + 107.34763854854604, + 107.48112091961424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06162681252669893, + "scoreError" : 3.3686119708431755E-4, + "scoreConfidence" : [ + 0.061289951329614616, + 0.061963673723783246 + ], + "scorePercentiles" : { + "0.0" : 0.061328496562593905, + "50.0" : 0.061681442692720474, + "90.0" : 0.06197374492597344, + "95.0" : 0.06197374492597344, + "99.0" : 0.06197374492597344, + "99.9" : 0.06197374492597344, + "99.99" : 0.06197374492597344, + "99.999" : 0.06197374492597344, + "99.9999" : 0.06197374492597344, + "100.0" : 0.06197374492597344 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06197374492597344, + 0.061568095189134614, + 0.061681442692720474 + ], + [ + 0.061702634419482816, + 0.06179707055900928, + 0.06169649623656577 + ], + [ + 0.061328496562593905, + 0.06142226142128862, + 0.061471070733521434 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.601361537296343E-4, + "scoreError" : 1.3735303553208745E-5, + "scoreConfidence" : [ + 3.464008501764256E-4, + 3.7387145728284306E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5257102726447045E-4, + "50.0" : 3.563742360272379E-4, + "90.0" : 3.711108373662132E-4, + "95.0" : 3.711108373662132E-4, + "99.0" : 3.711108373662132E-4, + "99.9" : 3.711108373662132E-4, + "99.99" : 3.711108373662132E-4, + "99.999" : 3.711108373662132E-4, + "99.9999" : 3.711108373662132E-4, + "100.0" : 3.711108373662132E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7094360919965913E-4, + 3.7054810797679537E-4, + 3.711108373662132E-4 + ], + [ + 3.564217083170926E-4, + 3.561934064597772E-4, + 3.563742360272379E-4 + ], + [ + 3.5417943252750647E-4, + 3.5257102726447045E-4, + 3.5288301842795726E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014064441341060416, + "scoreError" : 1.2119529604295307E-4, + "scoreConfidence" : [ + 0.013943246045017463, + 0.01418563663710337 + ], + "scorePercentiles" : { + "0.0" : 0.01398626967601172, + "50.0" : 0.0140487007086081, + "90.0" : 0.014176805886422469, + "95.0" : 0.014176805886422469, + "99.0" : 0.014176805886422469, + "99.9" : 0.014176805886422469, + "99.99" : 0.014176805886422469, + "99.999" : 0.014176805886422469, + "99.9999" : 0.014176805886422469, + "100.0" : 0.014176805886422469 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013999763167326047, + 0.013999175775825382, + 0.01398626967601172 + ], + [ + 0.014029347007575757, + 0.0140487007086081, + 0.01405117447410611 + ], + [ + 0.014176805886422469, + 0.014143796568194129, + 0.014144938805474027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.009089933464979, + "scoreError" : 0.01145814597855419, + "scoreConfidence" : [ + 0.9976317874864248, + 1.020548079443533 + ], + "scorePercentiles" : { + "0.0" : 1.0003654717415225, + "50.0" : 1.0087827143433528, + "90.0" : 1.0205102271428572, + "95.0" : 1.0205102271428572, + "99.0" : 1.0205102271428572, + "99.9" : 1.0205102271428572, + "99.99" : 1.0205102271428572, + "99.999" : 1.0205102271428572, + "99.9999" : 1.0205102271428572, + "100.0" : 1.0205102271428572 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0153699043557722, + 1.0152101648563598, + 1.0087827143433528 + ], + [ + 1.0026712928614396, + 1.0003654717415225, + 1.0058263027255356 + ], + [ + 1.0031070592718885, + 1.0099662638860836, + 1.0205102271428572 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013063078195670041, + "scoreError" : 3.172213737715068E-4, + "scoreConfidence" : [ + 0.012745856821898535, + 0.013380299569441548 + ], + "scorePercentiles" : { + "0.0" : 0.012905051156776511, + "50.0" : 0.013051076766829785, + "90.0" : 0.013247707986805675, + "95.0" : 0.013247707986805675, + "99.0" : 0.013247707986805675, + "99.9" : 0.013247707986805675, + "99.99" : 0.013247707986805675, + "99.999" : 0.013247707986805675, + "99.9999" : 0.013247707986805675, + "100.0" : 0.013247707986805675 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013015171863042652, + 0.013247707986805675, + 0.013039056843488737 + ], + [ + 0.012905051156776511, + 0.013063096690170833, + 0.013108384633735837 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.972506567178479, + "scoreError" : 0.19669975350394048, + "scoreConfidence" : [ + 3.7758068136745386, + 4.169206320682419 + ], + "scorePercentiles" : { + "0.0" : 3.865339341576507, + "50.0" : 3.980264222581429, + "90.0" : 4.068455570382425, + "95.0" : 4.068455570382425, + "99.0" : 4.068455570382425, + "99.9" : 4.068455570382425, + "99.99" : 4.068455570382425, + "99.999" : 4.068455570382425, + "99.9999" : 4.068455570382425, + "100.0" : 4.068455570382425 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 4.068455570382425, + 3.9299753731343285, + 3.9963807795527155 + ], + [ + 4.010740672814755, + 3.865339341576507, + 3.9641476656101426 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.158331899464004, + "scoreError" : 0.04410759724726521, + "scoreConfidence" : [ + 3.114224302216739, + 3.2024394967112695 + ], + "scorePercentiles" : { + "0.0" : 3.1209627138845555, + "50.0" : 3.151894622439332, + "90.0" : 3.205059529958347, + "95.0" : 3.205059529958347, + "99.0" : 3.205059529958347, + "99.9" : 3.205059529958347, + "99.99" : 3.205059529958347, + "99.999" : 3.205059529958347, + "99.9999" : 3.205059529958347, + "100.0" : 3.205059529958347 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.205059529958347, + 3.151894622439332, + 3.1209627138845555 + ], + [ + 3.1614530736409607, + 3.1490925138539043, + 3.1931810312899107 + ], + [ + 3.138146982428616, + 3.159927334913112, + 3.1452692927672956 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17926628376468318, + "scoreError" : 0.0041338115424907305, + "scoreConfidence" : [ + 0.17513247222219244, + 0.1834000953071739 + ], + "scorePercentiles" : { + "0.0" : 0.17606456009788904, + "50.0" : 0.17991486069481677, + "90.0" : 0.1824510914962325, + "95.0" : 0.1824510914962325, + "99.0" : 0.1824510914962325, + "99.9" : 0.1824510914962325, + "99.99" : 0.1824510914962325, + "99.999" : 0.1824510914962325, + "99.9999" : 0.1824510914962325, + "100.0" : 0.1824510914962325 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1762438778308454, + 0.17617481822666173, + 0.17606456009788904 + ], + [ + 0.18154535195338029, + 0.1824510914962325, + 0.18063986376445088 + ], + [ + 0.17991486069481677, + 0.1799070998992552, + 0.18045502991861703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33563272825190205, + "scoreError" : 0.009558237070581397, + "scoreConfidence" : [ + 0.32607449118132065, + 0.34519096532248345 + ], + "scorePercentiles" : { + "0.0" : 0.3284607007160218, + "50.0" : 0.33644188396581887, + "90.0" : 0.3440445917363333, + "95.0" : 0.3440445917363333, + "99.0" : 0.3440445917363333, + "99.9" : 0.3440445917363333, + "99.99" : 0.3440445917363333, + "99.999" : 0.3440445917363333, + "99.9999" : 0.3440445917363333, + "100.0" : 0.3440445917363333 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.329211396694759, + 0.32936281339129864, + 0.3284607007160218 + ], + [ + 0.3413116095904437, + 0.3403381569615084, + 0.3440445917363333 + ], + [ + 0.33644188396581887, + 0.3350542349984923, + 0.3364691662124424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16489447994355155, + "scoreError" : 0.012856772971821528, + "scoreConfidence" : [ + 0.15203770697173002, + 0.17775125291537308 + ], + "scorePercentiles" : { + "0.0" : 0.1552361662216703, + "50.0" : 0.16498882176796673, + "90.0" : 0.17424424524323948, + "95.0" : 0.17424424524323948, + "99.0" : 0.17424424524323948, + "99.9" : 0.17424424524323948, + "99.99" : 0.17424424524323948, + "99.999" : 0.17424424524323948, + "99.9999" : 0.17424424524323948, + "100.0" : 0.17424424524323948 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16498882176796673, + 0.1665575346346663, + 0.16489984001714927 + ], + [ + 0.1552361662216703, + 0.15588410461092406, + 0.15634531709452487 + ], + [ + 0.17229772164504403, + 0.17424424524323948, + 0.1735965682567788 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3875551586103285, + "scoreError" : 0.0063050988879517446, + "scoreConfidence" : [ + 0.3812500597223768, + 0.39386025749828024 + ], + "scorePercentiles" : { + "0.0" : 0.38285499134762635, + "50.0" : 0.385947726409633, + "90.0" : 0.39251833351650506, + "95.0" : 0.39251833351650506, + "99.0" : 0.39251833351650506, + "99.9" : 0.39251833351650506, + "99.99" : 0.39251833351650506, + "99.999" : 0.39251833351650506, + "99.9999" : 0.39251833351650506, + "100.0" : 0.39251833351650506 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.385947726409633, + 0.3845023914564749, + 0.38541915674259064 + ], + [ + 0.39251833351650506, + 0.39210625470514426, + 0.39240598979792035 + ], + [ + 0.38285499134762635, + 0.3868541281237911, + 0.3853874553932714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1597276282520068, + "scoreError" : 0.0046269221140336735, + "scoreConfidence" : [ + 0.1551007061379731, + 0.16435455036604046 + ], + "scorePercentiles" : { + "0.0" : 0.1554737507501438, + "50.0" : 0.1615286003876595, + "90.0" : 0.1617219838281907, + "95.0" : 0.1617219838281907, + "99.0" : 0.1617219838281907, + "99.9" : 0.1617219838281907, + "99.99" : 0.1617219838281907, + "99.999" : 0.1617219838281907, + "99.9999" : 0.1617219838281907, + "100.0" : 0.1617219838281907 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16165860842224378, + 0.1617219838281907, + 0.1615286003876595 + ], + [ + 0.15625568347942936, + 0.15650595923126281, + 0.1554737507501438 + ], + [ + 0.1615476022486794, + 0.16123468213404704, + 0.16162178378640463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04761128317096445, + "scoreError" : 3.479280769183812E-4, + "scoreConfidence" : [ + 0.04726335509404607, + 0.04795921124788283 + ], + "scorePercentiles" : { + "0.0" : 0.04738616306773758, + "50.0" : 0.047527383797194026, + "90.0" : 0.047924545537323164, + "95.0" : 0.047924545537323164, + "99.0" : 0.047924545537323164, + "99.9" : 0.047924545537323164, + "99.99" : 0.047924545537323164, + "99.999" : 0.047924545537323164, + "99.9999" : 0.047924545537323164, + "100.0" : 0.047924545537323164 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047924545537323164, + 0.047923508297830535, + 0.04775109323280267 + ], + [ + 0.04747591117377846, + 0.047487881058774925, + 0.04738616306773758 + ], + [ + 0.047604741071853605, + 0.04742032130138513, + 0.047527383797194026 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.0398962932366718E7, + "scoreError" : 351179.03066771803, + "scoreConfidence" : [ + 1.0047783901699E7, + 1.0750141963034436E7 + ], + "scorePercentiles" : { + "0.0" : 9973581.754735792, + "50.0" : 1.0443271703549061E7, + "90.0" : 1.0618271176220806E7, + "95.0" : 1.0618271176220806E7, + "99.0" : 1.0618271176220806E7, + "99.9" : 1.0618271176220806E7, + "99.99" : 1.0618271176220806E7, + "99.999" : 1.0618271176220806E7, + "99.9999" : 1.0618271176220806E7, + "100.0" : 1.0618271176220806E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1.0368837321243523E7, + 1.0231072242331289E7, + 1.028341827954779E7 + ], + [ + 1.0542553845100105E7, + 9973581.754735792, + 1.0552821065400844E7 + ], + [ + 1.0618271176220806E7, + 1.0443271703549061E7, + 1.0576839003171246E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T02:51:35Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json b/performance-results/2025-04-03T02:51:35Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json new file mode 100644 index 0000000000..e7e3fde930 --- /dev/null +++ b/performance-results/2025-04-03T02:51:35Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.412009068804363, + "scoreError" : 0.027147540536237486, + "scoreConfidence" : [ + 3.3848615282681256, + 3.4391566093406003 + ], + "scorePercentiles" : { + "0.0" : 3.406407858797982, + "50.0" : 3.412581318388711, + "90.0" : 3.416465779642049, + "95.0" : 3.416465779642049, + "99.0" : 3.416465779642049, + "99.9" : 3.416465779642049, + "99.99" : 3.416465779642049, + "99.999" : 3.416465779642049, + "99.9999" : 3.416465779642049, + "100.0" : 3.416465779642049 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.411854248718382, + 3.416465779642049 + ], + [ + 3.406407858797982, + 3.41330838805904 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7247825532086658, + "scoreError" : 0.008412192988375613, + "scoreConfidence" : [ + 1.7163703602202902, + 1.7331947461970414 + ], + "scorePercentiles" : { + "0.0" : 1.7232151056048182, + "50.0" : 1.7247590010147462, + "90.0" : 1.7263971052003526, + "95.0" : 1.7263971052003526, + "99.0" : 1.7263971052003526, + "99.9" : 1.7263971052003526, + "99.99" : 1.7263971052003526, + "99.999" : 1.7263971052003526, + "99.9999" : 1.7263971052003526, + "100.0" : 1.7263971052003526 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7232151056048182, + 1.7263971052003526 + ], + [ + 1.7246609185990969, + 1.7248570834303953 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8665645873428459, + "scoreError" : 0.007980730163315616, + "scoreConfidence" : [ + 0.8585838571795303, + 0.8745453175061615 + ], + "scorePercentiles" : { + "0.0" : 0.8652048329749016, + "50.0" : 0.8665310283763555, + "90.0" : 0.8679914596437709, + "95.0" : 0.8679914596437709, + "99.0" : 0.8679914596437709, + "99.9" : 0.8679914596437709, + "99.99" : 0.8679914596437709, + "99.999" : 0.8679914596437709, + "99.9999" : 0.8679914596437709, + "100.0" : 0.8679914596437709 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8671178524031105, + 0.8679914596437709 + ], + [ + 0.8652048329749016, + 0.8659442043496006 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.190306505865994, + "scoreError" : 0.19886222794442865, + "scoreConfidence" : [ + 15.991444277921566, + 16.389168733810422 + ], + "scorePercentiles" : { + "0.0" : 16.00356710808966, + "50.0" : 16.19719540512624, + "90.0" : 16.338223872579796, + "95.0" : 16.338223872579796, + "99.0" : 16.338223872579796, + "99.9" : 16.338223872579796, + "99.99" : 16.338223872579796, + "99.999" : 16.338223872579796, + "99.9999" : 16.338223872579796, + "100.0" : 16.338223872579796 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.263091004643808, + 16.332625869940873, + 16.338223872579796 + ], + [ + 16.20694779720255, + 16.19719540512624, + 16.18695691399324 + ], + [ + 16.163126086734835, + 16.00356710808966, + 16.02102449448297 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2652.1374561733314, + "scoreError" : 149.48652867483324, + "scoreConfidence" : [ + 2502.6509274984983, + 2801.6239848481646 + ], + "scorePercentiles" : { + "0.0" : 2572.313124395027, + "50.0" : 2615.4625094289067, + "90.0" : 2776.2508648496128, + "95.0" : 2776.2508648496128, + "99.0" : 2776.2508648496128, + "99.9" : 2776.2508648496128, + "99.99" : 2776.2508648496128, + "99.999" : 2776.2508648496128, + "99.9999" : 2776.2508648496128, + "100.0" : 2776.2508648496128 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2572.327591862452, + 2573.670192282608, + 2572.313124395027 + ], + [ + 2763.3332028422533, + 2776.2508648496128, + 2764.5264619939276 + ], + [ + 2617.16311033585, + 2614.190047569343, + 2615.4625094289067 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69244.53393821999, + "scoreError" : 2238.7153835897343, + "scoreConfidence" : [ + 67005.81855463026, + 71483.24932180972 + ], + "scorePercentiles" : { + "0.0" : 68283.01701912875, + "50.0" : 68404.88908740183, + "90.0" : 71025.63666207869, + "95.0" : 71025.63666207869, + "99.0" : 71025.63666207869, + "99.9" : 71025.63666207869, + "99.99" : 71025.63666207869, + "99.999" : 71025.63666207869, + "99.9999" : 71025.63666207869, + "100.0" : 71025.63666207869 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68283.01701912875, + 68299.08646909134, + 68346.94205609483 + ], + [ + 68410.80512801414, + 68396.52696193331, + 68404.88908740183 + ], + [ + 71020.59502416776, + 71025.63666207869, + 71013.30703606934 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 352.0495439106279, + "scoreError" : 5.688087554984918, + "scoreConfidence" : [ + 346.361456355643, + 357.7376314656128 + ], + "scorePercentiles" : { + "0.0" : 347.5038937323927, + "50.0" : 352.6586337417818, + "90.0" : 355.9543623081089, + "95.0" : 355.9543623081089, + "99.0" : 355.9543623081089, + "99.9" : 355.9543623081089, + "99.99" : 355.9543623081089, + "99.999" : 355.9543623081089, + "99.9999" : 355.9543623081089, + "100.0" : 355.9543623081089 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.36606065776704, + 355.9543623081089, + 355.44739687765446 + ], + [ + 353.3104547724866, + 352.6586337417818, + 352.0106775017903 + ], + [ + 348.08547373181875, + 348.1089418718505, + 347.5038937323927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.97197788613875, + "scoreError" : 2.7303080728968436, + "scoreConfidence" : [ + 105.2416698132419, + 110.70228595903559 + ], + "scorePercentiles" : { + "0.0" : 105.82762260516864, + "50.0" : 108.34243905974502, + "90.0" : 109.89787443224124, + "95.0" : 109.89787443224124, + "99.0" : 109.89787443224124, + "99.9" : 109.89787443224124, + "99.99" : 109.89787443224124, + "99.999" : 109.89787443224124, + "99.9999" : 109.89787443224124, + "100.0" : 109.89787443224124 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.24278780414237, + 109.77494855538254, + 109.89787443224124 + ], + [ + 108.25668688929966, + 108.34243905974502, + 108.35487959785104 + ], + [ + 105.99650175505398, + 105.82762260516864, + 106.05406027636413 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06264234939734833, + "scoreError" : 0.001940503038725499, + "scoreConfidence" : [ + 0.06070184635862284, + 0.06458285243607384 + ], + "scorePercentiles" : { + "0.0" : 0.061487347325639305, + "50.0" : 0.06224014973548267, + "90.0" : 0.0643154368235226, + "95.0" : 0.0643154368235226, + "99.0" : 0.0643154368235226, + "99.9" : 0.0643154368235226, + "99.99" : 0.0643154368235226, + "99.999" : 0.0643154368235226, + "99.9999" : 0.0643154368235226, + "100.0" : 0.0643154368235226 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06234369102198837, + 0.062147674374957274, + 0.06224014973548267 + ], + [ + 0.06389407033371457, + 0.0643154368235226, + 0.06415574181545232 + ], + [ + 0.06163425568567026, + 0.0615627774597077, + 0.061487347325639305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.693017818862823E-4, + "scoreError" : 1.4251241076151806E-5, + "scoreConfidence" : [ + 3.550505408101305E-4, + 3.8355302296243406E-4 + ], + "scorePercentiles" : { + "0.0" : 3.581285258168051E-4, + "50.0" : 3.7241348116836534E-4, + "90.0" : 3.774987506762271E-4, + "95.0" : 3.774987506762271E-4, + "99.0" : 3.774987506762271E-4, + "99.9" : 3.774987506762271E-4, + "99.99" : 3.774987506762271E-4, + "99.999" : 3.774987506762271E-4, + "99.9999" : 3.774987506762271E-4, + "100.0" : 3.774987506762271E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7728784066109127E-4, + 3.7661322860138834E-4, + 3.774987506762271E-4 + ], + [ + 3.581285258168051E-4, + 3.5816292636233426E-4, + 3.5870577075242295E-4 + ], + [ + 3.7241348116836534E-4, + 3.7278464199828296E-4, + 3.721208709396231E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014251813348747193, + "scoreError" : 2.4133152936300968E-4, + "scoreConfidence" : [ + 0.014010481819384184, + 0.014493144878110202 + ], + "scorePercentiles" : { + "0.0" : 0.014109882265792994, + "50.0" : 0.014200063186653244, + "90.0" : 0.01444335340454787, + "95.0" : 0.01444335340454787, + "99.0" : 0.01444335340454787, + "99.9" : 0.01444335340454787, + "99.99" : 0.01444335340454787, + "99.999" : 0.01444335340454787, + "99.9999" : 0.01444335340454787, + "100.0" : 0.01444335340454787 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014433382154187222, + 0.014433030841594948, + 0.01444335340454787 + ], + [ + 0.014115376225199589, + 0.014109882265792994, + 0.014123692329094866 + ], + [ + 0.014207825716136768, + 0.014199714015517262, + 0.014200063186653244 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9922482637732131, + "scoreError" : 0.04060752324069984, + "scoreConfidence" : [ + 0.9516407405325132, + 1.032855787013913 + ], + "scorePercentiles" : { + "0.0" : 0.9736791512024146, + "50.0" : 0.9777998899100508, + "90.0" : 1.0262624400205234, + "95.0" : 1.0262624400205234, + "99.0" : 1.0262624400205234, + "99.9" : 1.0262624400205234, + "99.99" : 1.0262624400205234, + "99.999" : 1.0262624400205234, + "99.9999" : 1.0262624400205234, + "100.0" : 1.0262624400205234 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0262624400205234, + 1.0246107202868853, + 1.0222336996831238 + ], + [ + 0.976044982920164, + 0.9750917759360375, + 0.9736791512024146 + ], + [ + 0.9752420151160522, + 0.9777998899100508, + 0.9792696988836663 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013020478890194788, + "scoreError" : 7.333534194251844E-4, + "scoreConfidence" : [ + 0.012287125470769603, + 0.013753832309619973 + ], + "scorePercentiles" : { + "0.0" : 0.012776612812060816, + "50.0" : 0.013020479729130969, + "90.0" : 0.013262022369869371, + "95.0" : 0.013262022369869371, + "99.0" : 0.013262022369869371, + "99.9" : 0.013262022369869371, + "99.99" : 0.013262022369869371, + "99.999" : 0.013262022369869371, + "99.9999" : 0.013262022369869371, + "100.0" : 0.013262022369869371 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013262022369869371, + 0.013255514599294823, + 0.013260036602118372 + ], + [ + 0.012785444858967114, + 0.012776612812060816, + 0.012783242098858227 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6823549127759994, + "scoreError" : 0.12037344013443266, + "scoreConfidence" : [ + 3.5619814726415666, + 3.802728352910432 + ], + "scorePercentiles" : { + "0.0" : 3.6239961630434783, + "50.0" : 3.674330386428005, + "90.0" : 3.7354224331590737, + "95.0" : 3.7354224331590737, + "99.0" : 3.7354224331590737, + "99.9" : 3.7354224331590737, + "99.99" : 3.7354224331590737, + "99.999" : 3.7354224331590737, + "99.9999" : 3.7354224331590737, + "100.0" : 3.7354224331590737 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6239961630434783, + 3.6654824945054947, + 3.6578229041697146 + ], + [ + 3.6831782783505154, + 3.7354224331590737, + 3.72822720342772 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.830217610770232, + "scoreError" : 0.02941764690765332, + "scoreConfidence" : [ + 2.8007999638625787, + 2.859635257677885 + ], + "scorePercentiles" : { + "0.0" : 2.8059439887766553, + "50.0" : 2.8304837555178266, + "90.0" : 2.8638871964490265, + "95.0" : 2.8638871964490265, + "99.0" : 2.8638871964490265, + "99.9" : 2.8638871964490265, + "99.99" : 2.8638871964490265, + "99.999" : 2.8638871964490265, + "99.9999" : 2.8638871964490265, + "100.0" : 2.8638871964490265 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8059439887766553, + 2.80763629365525, + 2.8274634690415605 + ], + [ + 2.8266450850763145, + 2.8334196541076486, + 2.8638871964490265 + ], + [ + 2.8327837142452563, + 2.8304837555178266, + 2.8436953400625535 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1753886762344773, + "scoreError" : 0.0030167678177013334, + "scoreConfidence" : [ + 0.17237190841677597, + 0.17840544405217862 + ], + "scorePercentiles" : { + "0.0" : 0.1728514556469734, + "50.0" : 0.17628545656465944, + "90.0" : 0.17697612007574418, + "95.0" : 0.17697612007574418, + "99.0" : 0.17697612007574418, + "99.9" : 0.17697612007574418, + "99.99" : 0.17697612007574418, + "99.999" : 0.17697612007574418, + "99.9999" : 0.17697612007574418, + "100.0" : 0.17697612007574418 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17323752276270657, + 0.17297506889453929, + 0.1728514556469734 + ], + [ + 0.17697612007574418, + 0.17628545656465944, + 0.1761608011520778 + ], + [ + 0.17683352849640147, + 0.17655357137056196, + 0.1766245611466318 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3252011556337465, + "scoreError" : 0.011613804722758634, + "scoreConfidence" : [ + 0.3135873509109879, + 0.33681496035650516 + ], + "scorePercentiles" : { + "0.0" : 0.31793855517756653, + "50.0" : 0.32358584517068434, + "90.0" : 0.3339527306061112, + "95.0" : 0.3339527306061112, + "99.0" : 0.3339527306061112, + "99.9" : 0.3339527306061112, + "99.99" : 0.3339527306061112, + "99.999" : 0.3339527306061112, + "99.9999" : 0.3339527306061112, + "100.0" : 0.3339527306061112 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32359638985244626, + 0.32337204507679873, + 0.32358584517068434 + ], + [ + 0.333943945167969, + 0.33376095434216674, + 0.3339527306061112 + ], + [ + 0.3185725668822274, + 0.31793855517756653, + 0.318087368427749 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16379379419542822, + "scoreError" : 0.011142070500678086, + "scoreConfidence" : [ + 0.15265172369475014, + 0.1749358646961063 + ], + "scorePercentiles" : { + "0.0" : 0.15917055110064143, + "50.0" : 0.15955122844105493, + "90.0" : 0.1727546144039249, + "95.0" : 0.1727546144039249, + "99.0" : 0.1727546144039249, + "99.9" : 0.1727546144039249, + "99.99" : 0.1727546144039249, + "99.999" : 0.1727546144039249, + "99.9999" : 0.1727546144039249, + "100.0" : 0.1727546144039249 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15958058684134938, + 0.15917055110064143, + 0.15917860239717305 + ], + [ + 0.1727546144039249, + 0.17259759036227756, + 0.17254379072415757 + ], + [ + 0.15955122844105493, + 0.15929815637892858, + 0.15946902710934635 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38991118899124244, + "scoreError" : 0.01124237080592444, + "scoreConfidence" : [ + 0.378668818185318, + 0.4011535597971669 + ], + "scorePercentiles" : { + "0.0" : 0.38210326390799326, + "50.0" : 0.39018023211080766, + "90.0" : 0.39966706621907844, + "95.0" : 0.39966706621907844, + "99.0" : 0.39966706621907844, + "99.9" : 0.39966706621907844, + "99.99" : 0.39966706621907844, + "99.999" : 0.39966706621907844, + "99.9999" : 0.39966706621907844, + "100.0" : 0.39966706621907844 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39966706621907844, + 0.39717512927439536, + 0.39558205047468353 + ], + [ + 0.38210326390799326, + 0.38233665801345773, + 0.38222272790857664 + ], + [ + 0.3904339530316636, + 0.39018023211080766, + 0.3894996199805258 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15684870185149255, + "scoreError" : 0.0037258751961398227, + "scoreConfidence" : [ + 0.15312282665535273, + 0.16057457704763237 + ], + "scorePercentiles" : { + "0.0" : 0.15480540073375748, + "50.0" : 0.1556524699052096, + "90.0" : 0.15974400097442532, + "95.0" : 0.15974400097442532, + "99.0" : 0.15974400097442532, + "99.9" : 0.15974400097442532, + "99.99" : 0.15974400097442532, + "99.999" : 0.15974400097442532, + "99.9999" : 0.15974400097442532, + "100.0" : 0.15974400097442532 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1597275829925888, + 0.15974400097442532, + 0.159548770716998 + ], + [ + 0.15493251851392806, + 0.15480540073375748, + 0.1548956253620607 + ], + [ + 0.15698526397915294, + 0.1556524699052096, + 0.15534668348531216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04782230709382967, + "scoreError" : 0.0017082561348700006, + "scoreConfidence" : [ + 0.046114050958959665, + 0.04953056322869967 + ], + "scorePercentiles" : { + "0.0" : 0.04707639163183068, + "50.0" : 0.04721573866013211, + "90.0" : 0.04920717646943044, + "95.0" : 0.04920717646943044, + "99.0" : 0.04920717646943044, + "99.9" : 0.04920717646943044, + "99.99" : 0.04920717646943044, + "99.999" : 0.04920717646943044, + "99.9999" : 0.04920717646943044, + "100.0" : 0.04920717646943044 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04721573866013211, + 0.04707639163183068, + 0.047087921274932665 + ], + [ + 0.04726264621172378, + 0.047139337894786464, + 0.047093677427406215 + ], + [ + 0.0491894079390064, + 0.0491284663352182, + 0.04920717646943044 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9281569.0026659, + "scoreError" : 115612.17714641236, + "scoreConfidence" : [ + 9165956.825519487, + 9397181.179812312 + ], + "scorePercentiles" : { + "0.0" : 9196106.576286765, + "50.0" : 9263902.401851851, + "90.0" : 9365629.605805244, + "95.0" : 9365629.605805244, + "99.0" : 9365629.605805244, + "99.9" : 9365629.605805244, + "99.99" : 9365629.605805244, + "99.999" : 9365629.605805244, + "99.9999" : 9365629.605805244, + "100.0" : 9365629.605805244 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9310784.226046512, + 9263902.401851851, + 9258585.227567067 + ], + [ + 9361236.768942937, + 9365629.605805244, + 9355414.256314313 + ], + [ + 9218562.90046083, + 9203899.060717572, + 9196106.576286765 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T02:52:17Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json b/performance-results/2025-04-03T02:52:17Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json new file mode 100644 index 0000000000..fe3a7e2f75 --- /dev/null +++ b/performance-results/2025-04-03T02:52:17Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.403194491531668, + "scoreError" : 0.0054344602373101285, + "scoreConfidence" : [ + 3.3977600312943577, + 3.408628951768978 + ], + "scorePercentiles" : { + "0.0" : 3.40204038330392, + "50.0" : 3.403455956648364, + "90.0" : 3.4038256695260225, + "95.0" : 3.4038256695260225, + "99.0" : 3.4038256695260225, + "99.9" : 3.4038256695260225, + "99.99" : 3.4038256695260225, + "99.999" : 3.4038256695260225, + "99.9999" : 3.4038256695260225, + "100.0" : 3.4038256695260225 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4038256695260225, + 3.403812822654316 + ], + [ + 3.403099090642413, + 3.40204038330392 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7219424259297373, + "scoreError" : 0.013541201269863041, + "scoreConfidence" : [ + 1.7084012246598743, + 1.7354836271996004 + ], + "scorePercentiles" : { + "0.0" : 1.7197695025152795, + "50.0" : 1.7218632263632574, + "90.0" : 1.7242737484771553, + "95.0" : 1.7242737484771553, + "99.0" : 1.7242737484771553, + "99.9" : 1.7242737484771553, + "99.99" : 1.7242737484771553, + "99.999" : 1.7242737484771553, + "99.9999" : 1.7242737484771553, + "100.0" : 1.7242737484771553 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7197695025152795, + 1.7242737484771553 + ], + [ + 1.7206375929853883, + 1.7230888597411262 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8640697627505329, + "scoreError" : 0.014770242609452224, + "scoreConfidence" : [ + 0.8492995201410807, + 0.8788400053599852 + ], + "scorePercentiles" : { + "0.0" : 0.8624312182679136, + "50.0" : 0.8632019184962488, + "90.0" : 0.8674439957417209, + "95.0" : 0.8674439957417209, + "99.0" : 0.8674439957417209, + "99.9" : 0.8674439957417209, + "99.99" : 0.8674439957417209, + "99.999" : 0.8674439957417209, + "99.9999" : 0.8674439957417209, + "100.0" : 0.8674439957417209 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8624312182679136, + 0.8634219709025568 + ], + [ + 0.8629818660899409, + 0.8674439957417209 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.9436319756992, + "scoreError" : 0.09563035262704961, + "scoreConfidence" : [ + 15.84800162307215, + 16.03926232832625 + ], + "scorePercentiles" : { + "0.0" : 15.84638395040122, + "50.0" : 15.959992832909032, + "90.0" : 16.02254842355818, + "95.0" : 16.02254842355818, + "99.0" : 16.02254842355818, + "99.9" : 16.02254842355818, + "99.99" : 16.02254842355818, + "99.999" : 16.02254842355818, + "99.9999" : 16.02254842355818, + "100.0" : 16.02254842355818 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.02254842355818, + 15.987810841814806, + 15.991277618896921 + ], + [ + 15.912647622226181, + 15.879334862745797, + 15.84638395040122 + ], + [ + 15.928670625550126, + 15.964021003190537, + 15.959992832909032 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2640.280594719942, + "scoreError" : 163.1601437194584, + "scoreConfidence" : [ + 2477.1204510004836, + 2803.440738439401 + ], + "scorePercentiles" : { + "0.0" : 2532.8517014134386, + "50.0" : 2628.7413437275936, + "90.0" : 2765.5166739080864, + "95.0" : 2765.5166739080864, + "99.0" : 2765.5166739080864, + "99.9" : 2765.5166739080864, + "99.99" : 2765.5166739080864, + "99.999" : 2765.5166739080864, + "99.9999" : 2765.5166739080864, + "100.0" : 2765.5166739080864 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2628.7413437275936, + 2624.102851090245, + 2631.2151456928896 + ], + [ + 2747.292980003622, + 2760.780272754581, + 2765.5166739080864 + ], + [ + 2536.3386188386053, + 2532.8517014134386, + 2535.6857650504176 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70561.7075536086, + "scoreError" : 675.1940634943425, + "scoreConfidence" : [ + 69886.51349011426, + 71236.90161710295 + ], + "scorePercentiles" : { + "0.0" : 70054.20588415946, + "50.0" : 70598.37075600476, + "90.0" : 71032.91635748415, + "95.0" : 71032.91635748415, + "99.0" : 71032.91635748415, + "99.9" : 71032.91635748415, + "99.99" : 71032.91635748415, + "99.999" : 71032.91635748415, + "99.9999" : 71032.91635748415, + "100.0" : 71032.91635748415 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70634.05122592344, + 70598.37075600476, + 70573.16509122771 + ], + [ + 70977.18073904366, + 71032.91635748415, + 70999.40010834833 + ], + [ + 70063.63182051902, + 70054.20588415946, + 70122.4459997669 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 337.49420084887447, + "scoreError" : 9.469080745548057, + "scoreConfidence" : [ + 328.0251201033264, + 346.96328159442254 + ], + "scorePercentiles" : { + "0.0" : 330.2899132159104, + "50.0" : 339.15051295464735, + "90.0" : 344.43838779117556, + "95.0" : 344.43838779117556, + "99.0" : 344.43838779117556, + "99.9" : 344.43838779117556, + "99.99" : 344.43838779117556, + "99.999" : 344.43838779117556, + "99.9999" : 344.43838779117556, + "100.0" : 344.43838779117556 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 330.386498161057, + 330.47431679190134, + 330.2899132159104 + ], + [ + 341.3405225744992, + 342.95327223940876, + 344.43838779117556 + ], + [ + 338.54115541959317, + 339.15051295464735, + 339.8732284916776 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.33461889685323, + "scoreError" : 5.416508050150125, + "scoreConfidence" : [ + 99.9181108467031, + 110.75112694700336 + ], + "scorePercentiles" : { + "0.0" : 100.52179981974373, + "50.0" : 107.24703425038527, + "90.0" : 107.99725413741437, + "95.0" : 107.99725413741437, + "99.0" : 107.99725413741437, + "99.9" : 107.99725413741437, + "99.99" : 107.99725413741437, + "99.999" : 107.99725413741437, + "99.9999" : 107.99725413741437, + "100.0" : 107.99725413741437 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.86967319741898, + 107.24703425038527, + 107.35165090978742 + ], + [ + 107.99725413741437, + 107.84506179509498, + 107.47085951287897 + ], + [ + 101.69064834493503, + 100.52179981974373, + 101.01758810402046 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06268900704606982, + "scoreError" : 0.001163791376921044, + "scoreConfidence" : [ + 0.06152521566914877, + 0.06385279842299087 + ], + "scorePercentiles" : { + "0.0" : 0.06172657346287506, + "50.0" : 0.06306495052626931, + "90.0" : 0.06333138844979798, + "95.0" : 0.06333138844979798, + "99.0" : 0.06333138844979798, + "99.9" : 0.06333138844979798, + "99.99" : 0.06333138844979798, + "99.999" : 0.06333138844979798, + "99.9999" : 0.06333138844979798, + "100.0" : 0.06333138844979798 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06176310465626177, + 0.06172657346287506, + 0.06184468065776942 + ], + [ + 0.06320055288221502, + 0.06314213385319653, + 0.06292492596997269 + ], + [ + 0.06320275295627058, + 0.06306495052626931, + 0.06333138844979798 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7481237278850056E-4, + "scoreError" : 1.1980570626435157E-5, + "scoreConfidence" : [ + 3.6283180216206543E-4, + 3.867929434149357E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6409876203927915E-4, + "50.0" : 3.7933416066346235E-4, + "90.0" : 3.8019052370467216E-4, + "95.0" : 3.8019052370467216E-4, + "99.0" : 3.8019052370467216E-4, + "99.9" : 3.8019052370467216E-4, + "99.99" : 3.8019052370467216E-4, + "99.999" : 3.8019052370467216E-4, + "99.9999" : 3.8019052370467216E-4, + "100.0" : 3.8019052370467216E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6570256780549384E-4, + 3.6409876203927915E-4, + 3.663767519349152E-4 + ], + [ + 3.8019052370467216E-4, + 3.8017008019173117E-4, + 3.7933416066346235E-4 + ], + [ + 3.797582444148515E-4, + 3.7767420023679903E-4, + 3.800060641053006E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014098005962349182, + "scoreError" : 2.050573003153203E-5, + "scoreConfidence" : [ + 0.01407750023231765, + 0.014118511692380714 + ], + "scorePercentiles" : { + "0.0" : 0.014083777860870986, + "50.0" : 0.014098247163116069, + "90.0" : 0.01412190544660648, + "95.0" : 0.01412190544660648, + "99.0" : 0.01412190544660648, + "99.9" : 0.01412190544660648, + "99.99" : 0.01412190544660648, + "99.999" : 0.01412190544660648, + "99.9999" : 0.01412190544660648, + "100.0" : 0.01412190544660648 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014083777860870986, + 0.014092198276262962, + 0.014087036303267731 + ], + [ + 0.01412190544660648, + 0.014103096767051113, + 0.014105937445252077 + ], + [ + 0.014086103755592116, + 0.014098247163116069, + 0.014103750643123096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9900720714208604, + "scoreError" : 0.032398284485443664, + "scoreConfidence" : [ + 0.9576737869354167, + 1.022470355906304 + ], + "scorePercentiles" : { + "0.0" : 0.9747853510088703, + "50.0" : 0.9790084789035732, + "90.0" : 1.0185325541297485, + "95.0" : 1.0185325541297485, + "99.0" : 1.0185325541297485, + "99.9" : 1.0185325541297485, + "99.99" : 1.0185325541297485, + "99.999" : 1.0185325541297485, + "99.9999" : 1.0185325541297485, + "100.0" : 1.0185325541297485 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0146146674444556, + 1.013647100851409, + 1.0185325541297485 + ], + [ + 0.9802752494608901, + 0.9790084789035732, + 0.9757974534100888 + ], + [ + 0.9747853510088703, + 0.978946785238841, + 0.9750410023398655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013014100910331693, + "scoreError" : 2.3206391521088976E-4, + "scoreConfidence" : [ + 0.012782036995120804, + 0.013246164825542582 + ], + "scorePercentiles" : { + "0.0" : 0.012868733088318561, + "50.0" : 0.013027448912159054, + "90.0" : 0.013099782038014646, + "95.0" : 0.013099782038014646, + "99.0" : 0.013099782038014646, + "99.9" : 0.013099782038014646, + "99.99" : 0.013099782038014646, + "99.999" : 0.013099782038014646, + "99.9999" : 0.013099782038014646, + "100.0" : 0.013099782038014646 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012868733088318561, + 0.013014096830110695, + 0.013040800994207413 + ], + [ + 0.012983094574488803, + 0.013078097936850035, + 0.013099782038014646 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.803681758942895, + "scoreError" : 0.058068017082038216, + "scoreConfidence" : [ + 3.745613741860857, + 3.861749776024933 + ], + "scorePercentiles" : { + "0.0" : 3.7688745960813868, + "50.0" : 3.8028532290171775, + "90.0" : 3.828712826952527, + "95.0" : 3.828712826952527, + "99.0" : 3.828712826952527, + "99.9" : 3.828712826952527, + "99.99" : 3.828712826952527, + "99.999" : 3.828712826952527, + "99.9999" : 3.828712826952527, + "100.0" : 3.828712826952527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7688745960813868, + 3.7987889476082004, + 3.8001995714285712 + ], + [ + 3.8055068866057837, + 3.8200077249809015, + 3.828712826952527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.922983171605901, + "scoreError" : 0.06878756494659564, + "scoreConfidence" : [ + 2.8541956066593053, + 2.9917707365524966 + ], + "scorePercentiles" : { + "0.0" : 2.882975975208994, + "50.0" : 2.899830810089881, + "90.0" : 2.991555425067305, + "95.0" : 2.991555425067305, + "99.0" : 2.991555425067305, + "99.9" : 2.991555425067305, + "99.99" : 2.991555425067305, + "99.999" : 2.991555425067305, + "99.9999" : 2.991555425067305, + "100.0" : 2.991555425067305 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8932728536303154, + 2.882975975208994, + 2.911509500727802 + ], + [ + 2.9790622302651175, + 2.991555425067305, + 2.955098183751846 + ], + [ + 2.899830810089881, + 2.8976569843568947, + 2.895886581354951 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1752739306467576, + "scoreError" : 0.0067926352926449335, + "scoreConfidence" : [ + 0.16848129535411266, + 0.1820665659394025 + ], + "scorePercentiles" : { + "0.0" : 0.16931798284853206, + "50.0" : 0.17703718935330254, + "90.0" : 0.179263765438738, + "95.0" : 0.179263765438738, + "99.0" : 0.179263765438738, + "99.9" : 0.179263765438738, + "99.99" : 0.179263765438738, + "99.999" : 0.179263765438738, + "99.9999" : 0.179263765438738, + "100.0" : 0.179263765438738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17127871834001301, + 0.16931798284853206, + 0.16951058001525554 + ], + [ + 0.179263765438738, + 0.17873609151027703, + 0.17824298643590475 + ], + [ + 0.17700606642948175, + 0.17703718935330254, + 0.17707199544931385 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3311272051006344, + "scoreError" : 0.02574131802826179, + "scoreConfidence" : [ + 0.30538588707237263, + 0.3568685231288962 + ], + "scorePercentiles" : { + "0.0" : 0.32002414304457744, + "50.0" : 0.3214951376583296, + "90.0" : 0.35274181238095237, + "95.0" : 0.35274181238095237, + "99.0" : 0.35274181238095237, + "99.9" : 0.35274181238095237, + "99.99" : 0.35274181238095237, + "99.999" : 0.35274181238095237, + "99.9999" : 0.35274181238095237, + "100.0" : 0.35274181238095237 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3225040451818885, + 0.3214951376583296, + 0.32122822893578745 + ], + [ + 0.32008386182504883, + 0.3202712323853446, + 0.32002414304457744 + ], + [ + 0.35274181238095237, + 0.35085857753841837, + 0.35093780695536214 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1573598302291365, + "scoreError" : 0.0033830824565148298, + "scoreConfidence" : [ + 0.15397674777262166, + 0.16074291268565133 + ], + "scorePercentiles" : { + "0.0" : 0.15461272411447302, + "50.0" : 0.15828907844627, + "90.0" : 0.1594421173947704, + "95.0" : 0.1594421173947704, + "99.0" : 0.1594421173947704, + "99.9" : 0.1594421173947704, + "99.99" : 0.1594421173947704, + "99.999" : 0.1594421173947704, + "99.9999" : 0.1594421173947704, + "100.0" : 0.1594421173947704 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15461272411447302, + 0.15493705184060486, + 0.15469718323432957 + ], + [ + 0.1586219272265842, + 0.1594421173947704, + 0.15929977722377978 + ], + [ + 0.158008010443988, + 0.15828907844627, + 0.15833060213742875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3929055482587191, + "scoreError" : 0.008874881668847938, + "scoreConfidence" : [ + 0.3840306665898712, + 0.401780429927567 + ], + "scorePercentiles" : { + "0.0" : 0.3861855186329407, + "50.0" : 0.3916299738789896, + "90.0" : 0.39987236290935263, + "95.0" : 0.39987236290935263, + "99.0" : 0.39987236290935263, + "99.9" : 0.39987236290935263, + "99.99" : 0.39987236290935263, + "99.999" : 0.39987236290935263, + "99.9999" : 0.39987236290935263, + "100.0" : 0.39987236290935263 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39418789096929324, + 0.3916299738789896, + 0.391009796019706 + ], + [ + 0.3995561204203124, + 0.39987236290935263, + 0.39806413752885916 + ], + [ + 0.38798272721629484, + 0.3876614067527232, + 0.3861855186329407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15638411625309134, + "scoreError" : 0.0038605736119067847, + "scoreConfidence" : [ + 0.15252354264118456, + 0.16024468986499812 + ], + "scorePercentiles" : { + "0.0" : 0.15314811026371405, + "50.0" : 0.15670415334712298, + "90.0" : 0.159883718659568, + "95.0" : 0.159883718659568, + "99.0" : 0.159883718659568, + "99.9" : 0.159883718659568, + "99.99" : 0.159883718659568, + "99.999" : 0.159883718659568, + "99.9999" : 0.159883718659568, + "100.0" : 0.159883718659568 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1566501469187631, + 0.15670415334712298, + 0.1567198383613597 + ], + [ + 0.1547686963506361, + 0.15314811026371405, + 0.15320902544735873 + ], + [ + 0.159883718659568, + 0.15830709884438815, + 0.15806625808491132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04731102617255678, + "scoreError" : 5.494062501007604E-4, + "scoreConfidence" : [ + 0.04676161992245602, + 0.04786043242265754 + ], + "scorePercentiles" : { + "0.0" : 0.04687650850095393, + "50.0" : 0.04743667847350695, + "90.0" : 0.047676395332538736, + "95.0" : 0.047676395332538736, + "99.0" : 0.047676395332538736, + "99.9" : 0.047676395332538736, + "99.99" : 0.047676395332538736, + "99.999" : 0.047676395332538736, + "99.9999" : 0.047676395332538736, + "100.0" : 0.047676395332538736 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04749636832506115, + 0.04743667847350695, + 0.04734048231150498 + ], + [ + 0.04691541189661886, + 0.04689057975486013, + 0.04687650850095393 + ], + [ + 0.047676395332538736, + 0.047574515204567076, + 0.04759229575339923 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9441197.85305533, + "scoreError" : 304521.42768585624, + "scoreConfidence" : [ + 9136676.425369473, + 9745719.280741187 + ], + "scorePercentiles" : { + "0.0" : 9249209.369685767, + "50.0" : 9358704.228250701, + "90.0" : 9681377.27589545, + "95.0" : 9681377.27589545, + "99.0" : 9681377.27589545, + "99.9" : 9681377.27589545, + "99.99" : 9681377.27589545, + "99.999" : 9681377.27589545, + "99.9999" : 9681377.27589545, + "100.0" : 9681377.27589545 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9409813.65098777, + 9358704.228250701, + 9353099.48317757 + ], + [ + 9675122.80754352, + 9664841.801932367, + 9681377.27589545 + ], + [ + 9318771.304469274, + 9259840.755555555, + 9249209.369685767 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T02:52:33Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json b/performance-results/2025-04-03T02:52:33Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json new file mode 100644 index 0000000000..43c4405b48 --- /dev/null +++ b/performance-results/2025-04-03T02:52:33Z-e98ca21274456df314a2574b48271e4f236d2970-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4156356646292396, + "scoreError" : 0.013598054926190144, + "scoreConfidence" : [ + 3.4020376097030494, + 3.42923371955543 + ], + "scorePercentiles" : { + "0.0" : 3.4130888415653047, + "50.0" : 3.415786695895449, + "90.0" : 3.4178804251607553, + "95.0" : 3.4178804251607553, + "99.0" : 3.4178804251607553, + "99.9" : 3.4178804251607553, + "99.99" : 3.4178804251607553, + "99.999" : 3.4178804251607553, + "99.9999" : 3.4178804251607553, + "100.0" : 3.4178804251607553 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4148610786856364, + 3.4178804251607553 + ], + [ + 3.4130888415653047, + 3.4167123131052617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7253259788610695, + "scoreError" : 0.008555086625644845, + "scoreConfidence" : [ + 1.7167708922354248, + 1.7338810654867143 + ], + "scorePercentiles" : { + "0.0" : 1.7241059127032126, + "50.0" : 1.7252574282825233, + "90.0" : 1.726683146176019, + "95.0" : 1.726683146176019, + "99.0" : 1.726683146176019, + "99.9" : 1.726683146176019, + "99.99" : 1.726683146176019, + "99.999" : 1.726683146176019, + "99.9999" : 1.726683146176019, + "100.0" : 1.726683146176019 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7241059127032126, + 1.726683146176019 + ], + [ + 1.7242780552173471, + 1.7262368013476994 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8680284206920243, + "scoreError" : 0.0038235580345896383, + "scoreConfidence" : [ + 0.8642048626574347, + 0.871851978726614 + ], + "scorePercentiles" : { + "0.0" : 0.8672392519716291, + "50.0" : 0.8681156014545766, + "90.0" : 0.8686432278873151, + "95.0" : 0.8686432278873151, + "99.0" : 0.8686432278873151, + "99.9" : 0.8686432278873151, + "99.99" : 0.8686432278873151, + "99.999" : 0.8686432278873151, + "99.9999" : 0.8686432278873151, + "100.0" : 0.8686432278873151 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8682466548186853, + 0.8679845480904678 + ], + [ + 0.8672392519716291, + 0.8686432278873151 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.266398884740102, + "scoreError" : 0.12089071736767489, + "scoreConfidence" : [ + 16.145508167372427, + 16.387289602107778 + ], + "scorePercentiles" : { + "0.0" : 16.16215887190314, + "50.0" : 16.2909633020778, + "90.0" : 16.35367633567486, + "95.0" : 16.35367633567486, + "99.0" : 16.35367633567486, + "99.9" : 16.35367633567486, + "99.99" : 16.35367633567486, + "99.999" : 16.35367633567486, + "99.9999" : 16.35367633567486, + "100.0" : 16.35367633567486 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.30206765152038, + 16.2909633020778, + 16.35367633567486 + ], + [ + 16.286595407788486, + 16.32141250450957, + 16.319740312132282 + ], + [ + 16.181694193122404, + 16.16215887190314, + 16.17928138393201 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2708.4379672756168, + "scoreError" : 52.77435647527872, + "scoreConfidence" : [ + 2655.663610800338, + 2761.2123237508954 + ], + "scorePercentiles" : { + "0.0" : 2678.8808548562843, + "50.0" : 2690.720282550591, + "90.0" : 2759.421890618881, + "95.0" : 2759.421890618881, + "99.0" : 2759.421890618881, + "99.9" : 2759.421890618881, + "99.99" : 2759.421890618881, + "99.999" : 2759.421890618881, + "99.9999" : 2759.421890618881, + "100.0" : 2759.421890618881 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2678.8808548562843, + 2680.4724669738675, + 2683.5451766372953 + ], + [ + 2733.344157571987, + 2759.421890618881, + 2750.126719125809 + ], + [ + 2709.4928928539957, + 2690.720282550591, + 2689.9372642918393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 71058.98757792657, + "scoreError" : 822.5121592927409, + "scoreConfidence" : [ + 70236.47541863383, + 71881.49973721932 + ], + "scorePercentiles" : { + "0.0" : 70334.4708128567, + "50.0" : 71230.61338609025, + "90.0" : 71513.68980710543, + "95.0" : 71513.68980710543, + "99.0" : 71513.68980710543, + "99.9" : 71513.68980710543, + "99.99" : 71513.68980710543, + "99.999" : 71513.68980710543, + "99.9999" : 71513.68980710543, + "100.0" : 71513.68980710543 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71368.81270009922, + 71230.61338609025, + 71190.58903098464 + ], + [ + 70334.4708128567, + 70389.2239357189, + 70557.90033738017 + ], + [ + 71513.68980710543, + 71475.07240288406, + 71470.51578821983 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.8880754496758, + "scoreError" : 2.8872515097664553, + "scoreConfidence" : [ + 351.00082393990937, + 356.7753269594422 + ], + "scorePercentiles" : { + "0.0" : 350.7947815417503, + "50.0" : 354.64335969623687, + "90.0" : 355.8222124963307, + "95.0" : 355.8222124963307, + "99.0" : 355.8222124963307, + "99.9" : 355.8222124963307, + "99.99" : 355.8222124963307, + "99.999" : 355.8222124963307, + "99.9999" : 355.8222124963307, + "100.0" : 355.8222124963307 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.56970556775656, + 355.8222124963307, + 354.9352269121157 + ], + [ + 354.6486608825263, + 353.1706551915284, + 354.64335969623687 + ], + [ + 350.7947815417503, + 353.6826154737699, + 351.7254612850681 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.725544877288, + "scoreError" : 1.8828817446497361, + "scoreConfidence" : [ + 105.84266313263826, + 109.60842662193774 + ], + "scorePercentiles" : { + "0.0" : 106.20111805060321, + "50.0" : 108.05817565088162, + "90.0" : 108.91316264233733, + "95.0" : 108.91316264233733, + "99.0" : 108.91316264233733, + "99.9" : 108.91316264233733, + "99.99" : 108.91316264233733, + "99.999" : 108.91316264233733, + "99.9999" : 108.91316264233733, + "100.0" : 108.91316264233733 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.08754446696082, + 107.92893729958848, + 108.05817565088162 + ], + [ + 108.91316264233733, + 108.80524904880716, + 108.7959124505325 + ], + [ + 106.51012019955222, + 106.22968408632865, + 106.20111805060321 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06139367548232111, + "scoreError" : 3.540999759717375E-4, + "scoreConfidence" : [ + 0.06103957550634937, + 0.061747775458292846 + ], + "scorePercentiles" : { + "0.0" : 0.06110012819854828, + "50.0" : 0.061308202516047156, + "90.0" : 0.061741893811702385, + "95.0" : 0.061741893811702385, + "99.0" : 0.061741893811702385, + "99.9" : 0.061741893811702385, + "99.99" : 0.061741893811702385, + "99.999" : 0.061741893811702385, + "99.9999" : 0.061741893811702385, + "100.0" : 0.061741893811702385 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061263466611938835, + 0.06129953820738525, + 0.06110012819854828 + ], + [ + 0.061741893811702385, + 0.06153386918050137, + 0.06166293546437777 + ], + [ + 0.061243678443693196, + 0.06138936690669564, + 0.061308202516047156 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.694689698392999E-4, + "scoreError" : 9.255300635961062E-6, + "scoreConfidence" : [ + 3.602136692033388E-4, + 3.7872427047526094E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6217798291792163E-4, + "50.0" : 3.7218480085890395E-4, + "90.0" : 3.7506734062791447E-4, + "95.0" : 3.7506734062791447E-4, + "99.0" : 3.7506734062791447E-4, + "99.9" : 3.7506734062791447E-4, + "99.99" : 3.7506734062791447E-4, + "99.999" : 3.7506734062791447E-4, + "99.9999" : 3.7506734062791447E-4, + "100.0" : 3.7506734062791447E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.622063955463637E-4, + 3.6227118109386175E-4, + 3.6217798291792163E-4 + ], + [ + 3.7320771985383417E-4, + 3.7278784840373975E-4, + 3.7506734062791447E-4 + ], + [ + 3.7218480085890395E-4, + 3.719860773868182E-4, + 3.733313818643414E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014185911212594595, + "scoreError" : 3.2603556268247393E-4, + "scoreConfidence" : [ + 0.013859875649912121, + 0.01451194677527707 + ], + "scorePercentiles" : { + "0.0" : 0.014013460115357451, + "50.0" : 0.014108437662597841, + "90.0" : 0.014442271787354495, + "95.0" : 0.014442271787354495, + "99.0" : 0.014442271787354495, + "99.9" : 0.014442271787354495, + "99.99" : 0.014442271787354495, + "99.999" : 0.014442271787354495, + "99.9999" : 0.014442271787354495, + "100.0" : 0.014442271787354495 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014110861143644116, + 0.014108437662597841, + 0.014073766856660334 + ], + [ + 0.014013460115357451, + 0.014017406076755624, + 0.014028585135753145 + ], + [ + 0.014441690347867277, + 0.014442271787354495, + 0.014436721787361084 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.000218969280612, + "scoreError" : 0.028304821762359534, + "scoreConfidence" : [ + 0.9719141475182526, + 1.0285237910429716 + ], + "scorePercentiles" : { + "0.0" : 0.971517003011463, + "50.0" : 1.006556415601409, + "90.0" : 1.0175622131664632, + "95.0" : 1.0175622131664632, + "99.0" : 1.0175622131664632, + "99.9" : 1.0175622131664632, + "99.99" : 1.0175622131664632, + "99.999" : 1.0175622131664632, + "99.9999" : 1.0175622131664632, + "100.0" : 1.0175622131664632 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9864229748471098, + 0.9793540111644305, + 0.971517003011463 + ], + [ + 1.0175622131664632, + 1.0142364593306288, + 1.0141052803690935 + ], + [ + 1.0029004894705174, + 1.006556415601409, + 1.0093158765643924 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013081022622499473, + "scoreError" : 3.378864151227627E-4, + "scoreConfidence" : [ + 0.01274313620737671, + 0.013418909037622237 + ], + "scorePercentiles" : { + "0.0" : 0.012912455037290306, + "50.0" : 0.013086725894439325, + "90.0" : 0.013221848698075737, + "95.0" : 0.013221848698075737, + "99.0" : 0.013221848698075737, + "99.9" : 0.013221848698075737, + "99.99" : 0.013221848698075737, + "99.999" : 0.013221848698075737, + "99.9999" : 0.013221848698075737, + "100.0" : 0.013221848698075737 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013221848698075737, + 0.013161446690900669, + 0.013169755604253201 + ], + [ + 0.012912455037290306, + 0.013008624606498946, + 0.013012005097977983 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6645016367361083, + "scoreError" : 0.13736673724963294, + "scoreConfidence" : [ + 3.5271348994864753, + 3.8018683739857413 + ], + "scorePercentiles" : { + "0.0" : 3.6035412175792505, + "50.0" : 3.6690025230107586, + "90.0" : 3.720898994791667, + "95.0" : 3.720898994791667, + "99.0" : 3.720898994791667, + "99.9" : 3.720898994791667, + "99.99" : 3.720898994791667, + "99.999" : 3.720898994791667, + "99.9999" : 3.720898994791667, + "100.0" : 3.720898994791667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6035412175792505, + 3.638543946909091, + 3.6223095568428674 + ], + [ + 3.720898994791667, + 3.699461099112426, + 3.702255005181347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8352983613756226, + "scoreError" : 0.08666946035359768, + "scoreConfidence" : [ + 2.748628901022025, + 2.92196782172922 + ], + "scorePercentiles" : { + "0.0" : 2.765421011611833, + "50.0" : 2.8449870605802046, + "90.0" : 2.8918537652500724, + "95.0" : 2.8918537652500724, + "99.0" : 2.8918537652500724, + "99.9" : 2.8918537652500724, + "99.99" : 2.8918537652500724, + "99.999" : 2.8918537652500724, + "99.9999" : 2.8918537652500724, + "100.0" : 2.8918537652500724 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.835161081632653, + 2.8449870605802046, + 2.855578256996002 + ], + [ + 2.7817287532684283, + 2.768810570598007, + 2.765421011611833 + ], + [ + 2.8824682089337177, + 2.8918537652500724, + 2.8916765435096847 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17668539768407285, + "scoreError" : 0.0038052870787773085, + "scoreConfidence" : [ + 0.17288011060529554, + 0.18049068476285016 + ], + "scorePercentiles" : { + "0.0" : 0.17355092122663612, + "50.0" : 0.1777485684322787, + "90.0" : 0.17866238191628106, + "95.0" : 0.17866238191628106, + "99.0" : 0.17866238191628106, + "99.9" : 0.17866238191628106, + "99.99" : 0.17866238191628106, + "99.999" : 0.17866238191628106, + "99.9999" : 0.17866238191628106, + "100.0" : 0.17866238191628106 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17391668427826087, + 0.17365871248220052, + 0.17355092122663612 + ], + [ + 0.1777485684322787, + 0.17777599557349072, + 0.17773426860392785 + ], + [ + 0.17863249555214175, + 0.17866238191628106, + 0.17848855109143805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32587688199055964, + "scoreError" : 0.019338886180817538, + "scoreConfidence" : [ + 0.3065379958097421, + 0.34521576817137717 + ], + "scorePercentiles" : { + "0.0" : 0.3141145466453072, + "50.0" : 0.32231344068069745, + "90.0" : 0.3408148210074296, + "95.0" : 0.3408148210074296, + "99.0" : 0.3408148210074296, + "99.9" : 0.3408148210074296, + "99.99" : 0.3408148210074296, + "99.999" : 0.3408148210074296, + "99.9999" : 0.3408148210074296, + "100.0" : 0.3408148210074296 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3235398579054644, + 0.32227414531098936, + 0.32231344068069745 + ], + [ + 0.3408148210074296, + 0.34049507483827035, + 0.3400488105617519 + ], + [ + 0.3141145466453072, + 0.31483124140536456, + 0.3144599995597623 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1623926354338566, + "scoreError" : 0.012456786224923444, + "scoreConfidence" : [ + 0.14993584920893316, + 0.17484942165878004 + ], + "scorePercentiles" : { + "0.0" : 0.1533380093227226, + "50.0" : 0.16319451313685174, + "90.0" : 0.17073326242914702, + "95.0" : 0.17073326242914702, + "99.0" : 0.17073326242914702, + "99.9" : 0.17073326242914702, + "99.99" : 0.17073326242914702, + "99.999" : 0.17073326242914702, + "99.9999" : 0.17073326242914702, + "100.0" : 0.17073326242914702 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15338722272838826, + 0.15366977726043396, + 0.1533380093227226 + ], + [ + 0.16311651067577929, + 0.1632495087255334, + 0.16319451313685174 + ], + [ + 0.17073326242914702, + 0.17037008702318687, + 0.17047482760266616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39736623534599325, + "scoreError" : 0.0072331898616597515, + "scoreConfidence" : [ + 0.3901330454843335, + 0.404599425207653 + ], + "scorePercentiles" : { + "0.0" : 0.39367914727186837, + "50.0" : 0.3956107970567292, + "90.0" : 0.40649457729360594, + "95.0" : 0.40649457729360594, + "99.0" : 0.40649457729360594, + "99.9" : 0.40649457729360594, + "99.99" : 0.40649457729360594, + "99.999" : 0.40649457729360594, + "99.9999" : 0.40649457729360594, + "100.0" : 0.40649457729360594 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3956107970567292, + 0.39441284527706566, + 0.3941601015726617 + ], + [ + 0.40649457729360594, + 0.39985587800879646, + 0.400734263273893 + ], + [ + 0.39739873168017803, + 0.3939497766791412, + 0.39367914727186837 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15825399365071202, + "scoreError" : 0.0013317635767325676, + "scoreConfidence" : [ + 0.15692223007397946, + 0.15958575722744459 + ], + "scorePercentiles" : { + "0.0" : 0.15673044195595956, + "50.0" : 0.1583845141196408, + "90.0" : 0.1593887585470426, + "95.0" : 0.1593887585470426, + "99.0" : 0.1593887585470426, + "99.9" : 0.1593887585470426, + "99.99" : 0.1593887585470426, + "99.999" : 0.1593887585470426, + "99.9999" : 0.1593887585470426, + "100.0" : 0.1593887585470426 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1583845141196408, + 0.15735447831696878, + 0.15673044195595956 + ], + [ + 0.15894453801039465, + 0.1582970085161617, + 0.15822979096518988 + ], + [ + 0.1593887585470426, + 0.1585478360180106, + 0.15840857640703956 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04790902474190342, + "scoreError" : 9.884302829136805E-4, + "scoreConfidence" : [ + 0.046920594458989745, + 0.0488974550248171 + ], + "scorePercentiles" : { + "0.0" : 0.04700120233216146, + "50.0" : 0.048178018003912006, + "90.0" : 0.04842747581320794, + "95.0" : 0.04842747581320794, + "99.0" : 0.04842747581320794, + "99.9" : 0.04842747581320794, + "99.99" : 0.04842747581320794, + "99.999" : 0.04842747581320794, + "99.9999" : 0.04842747581320794, + "100.0" : 0.04842747581320794 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047425067774184065, + 0.0470235094445202, + 0.04700120233216146 + ], + [ + 0.04842747581320794, + 0.04839052659746921, + 0.04833344739220586 + ], + [ + 0.04817166911375088, + 0.048178018003912006, + 0.04823030620571908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9340768.943235474, + "scoreError" : 334580.2702463491, + "scoreConfidence" : [ + 9006188.672989124, + 9675349.213481823 + ], + "scorePercentiles" : { + "0.0" : 9167080.854262145, + "50.0" : 9249256.829944547, + "90.0" : 9604620.571976967, + "95.0" : 9604620.571976967, + "99.0" : 9604620.571976967, + "99.9" : 9604620.571976967, + "99.99" : 9604620.571976967, + "99.999" : 9604620.571976967, + "99.9999" : 9604620.571976967, + "100.0" : 9604620.571976967 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9603299.714971209, + 9604620.571976967, + 9599769.868522072 + ], + [ + 9176881.251376146, + 9171812.810265811, + 9167080.854262145 + ], + [ + 9250278.53789279, + 9243920.049907578, + 9249256.829944547 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T03:21:08Z-9099f7a1b442ee3cec5e62c9ac2172649b0e9303-jdk17.json b/performance-results/2025-04-03T03:21:08Z-9099f7a1b442ee3cec5e62c9ac2172649b0e9303-jdk17.json new file mode 100644 index 0000000000..3968fb62a0 --- /dev/null +++ b/performance-results/2025-04-03T03:21:08Z-9099f7a1b442ee3cec5e62c9ac2172649b0e9303-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4206904700900105, + "scoreError" : 0.02183667760750563, + "scoreConfidence" : [ + 3.398853792482505, + 3.442527147697516 + ], + "scorePercentiles" : { + "0.0" : 3.4169173445120937, + "50.0" : 3.4204712443645153, + "90.0" : 3.4249020471189184, + "95.0" : 3.4249020471189184, + "99.0" : 3.4249020471189184, + "99.9" : 3.4249020471189184, + "99.99" : 3.4249020471189184, + "99.999" : 3.4249020471189184, + "99.9999" : 3.4249020471189184, + "100.0" : 3.4249020471189184 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4169173445120937, + 3.42151719244912 + ], + [ + 3.4194252962799103, + 3.4249020471189184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7252335363338895, + "scoreError" : 0.008307105083911945, + "scoreConfidence" : [ + 1.7169264312499777, + 1.7335406414178014 + ], + "scorePercentiles" : { + "0.0" : 1.7239610059033839, + "50.0" : 1.7249873882714315, + "90.0" : 1.7269983628893113, + "95.0" : 1.7269983628893113, + "99.0" : 1.7269983628893113, + "99.9" : 1.7269983628893113, + "99.99" : 1.7269983628893113, + "99.999" : 1.7269983628893113, + "99.9999" : 1.7269983628893113, + "100.0" : 1.7269983628893113 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.725213956729067, + 1.7269983628893113 + ], + [ + 1.7239610059033839, + 1.7247608198137958 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8684343770623647, + "scoreError" : 0.007317786949523727, + "scoreConfidence" : [ + 0.861116590112841, + 0.8757521640118884 + ], + "scorePercentiles" : { + "0.0" : 0.867179793041212, + "50.0" : 0.8684535805333289, + "90.0" : 0.8696505541415892, + "95.0" : 0.8696505541415892, + "99.0" : 0.8696505541415892, + "99.9" : 0.8696505541415892, + "99.99" : 0.8696505541415892, + "99.999" : 0.8696505541415892, + "99.9999" : 0.8696505541415892, + "100.0" : 0.8696505541415892 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.867179793041212, + 0.8690834321319288 + ], + [ + 0.867823728934729, + 0.8696505541415892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.17909126766679, + "scoreError" : 0.2559768985488164, + "scoreConfidence" : [ + 15.923114369117975, + 16.435068166215608 + ], + "scorePercentiles" : { + "0.0" : 15.95867060528112, + "50.0" : 16.219606732032062, + "90.0" : 16.34178668248754, + "95.0" : 16.34178668248754, + "99.0" : 16.34178668248754, + "99.9" : 16.34178668248754, + "99.99" : 16.34178668248754, + "99.999" : 16.34178668248754, + "99.9999" : 16.34178668248754, + "100.0" : 16.34178668248754 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.33268306277049, + 16.34178668248754, + 16.317455598781788 + ], + [ + 16.222099039014896, + 16.21617211413328, + 16.219606732032062 + ], + [ + 15.998538550283158, + 16.0048090242168, + 15.95867060528112 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2741.393458861405, + "scoreError" : 128.33119256683457, + "scoreConfidence" : [ + 2613.0622662945707, + 2869.7246514282397 + ], + "scorePercentiles" : { + "0.0" : 2652.278337073892, + "50.0" : 2734.203485973766, + "90.0" : 2835.992818278071, + "95.0" : 2835.992818278071, + "99.0" : 2835.992818278071, + "99.9" : 2835.992818278071, + "99.99" : 2835.992818278071, + "99.999" : 2835.992818278071, + "99.9999" : 2835.992818278071, + "100.0" : 2835.992818278071 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2661.1713934815975, + 2657.433088914789, + 2652.278337073892 + ], + [ + 2832.7345846544295, + 2829.543160848537, + 2835.992818278071 + ], + [ + 2737.992023875842, + 2731.192236651723, + 2734.203485973766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69626.51006344466, + "scoreError" : 1442.2282000666273, + "scoreConfidence" : [ + 68184.28186337803, + 71068.73826351129 + ], + "scorePercentiles" : { + "0.0" : 68747.77960524686, + "50.0" : 69415.45501954913, + "90.0" : 70718.66289611543, + "95.0" : 70718.66289611543, + "99.0" : 70718.66289611543, + "99.9" : 70718.66289611543, + "99.99" : 70718.66289611543, + "99.999" : 70718.66289611543, + "99.9999" : 70718.66289611543, + "100.0" : 70718.66289611543 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69508.20422837307, + 69329.92052768177, + 69415.45501954913 + ], + [ + 68759.44810168311, + 68766.27396576387, + 68747.77960524686 + ], + [ + 70718.66289611543, + 70696.14519876917, + 70696.7010278194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 354.62313474254336, + "scoreError" : 7.606529656984937, + "scoreConfidence" : [ + 347.0166050855584, + 362.2296643995283 + ], + "scorePercentiles" : { + "0.0" : 349.0330227618401, + "50.0" : 354.7798397775166, + "90.0" : 359.74298642059154, + "95.0" : 359.74298642059154, + "99.0" : 359.74298642059154, + "99.9" : 359.74298642059154, + "99.99" : 359.74298642059154, + "99.999" : 359.74298642059154, + "99.9999" : 359.74298642059154, + "100.0" : 359.74298642059154 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 359.23653220898484, + 358.78449189912214, + 359.74298642059154 + ], + [ + 349.12833515981123, + 349.0330227618401, + 349.0772965711547 + ], + [ + 354.7798397775166, + 354.58012610305406, + 357.245581780815 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.85075131510806, + "scoreError" : 2.625356711099751, + "scoreConfidence" : [ + 105.2253946040083, + 110.47610802620781 + ], + "scorePercentiles" : { + "0.0" : 106.59276942871568, + "50.0" : 107.03915029820716, + "90.0" : 109.93824920257076, + "95.0" : 109.93824920257076, + "99.0" : 109.93824920257076, + "99.9" : 109.93824920257076, + "99.99" : 109.93824920257076, + "99.999" : 109.93824920257076, + "99.9999" : 109.93824920257076, + "100.0" : 109.93824920257076 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.64717439112054, + 106.74946925270864, + 106.74222649575631 + ], + [ + 106.59276942871568, + 107.03915029820716, + 107.12172718231646 + ], + [ + 109.92123791555389, + 109.93824920257076, + 109.90475766902303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06159594570780158, + "scoreError" : 8.981845003630485E-4, + "scoreConfidence" : [ + 0.060697761207438534, + 0.062494130208164626 + ], + "scorePercentiles" : { + "0.0" : 0.061129065987737714, + "50.0" : 0.06128236699738327, + "90.0" : 0.062467338455580126, + "95.0" : 0.062467338455580126, + "99.0" : 0.062467338455580126, + "99.9" : 0.062467338455580126, + "99.99" : 0.062467338455580126, + "99.999" : 0.062467338455580126, + "99.9999" : 0.062467338455580126, + "100.0" : 0.062467338455580126 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06209102383642957, + 0.06232024442865689, + 0.062467338455580126 + ], + [ + 0.06126727419097916, + 0.06119005713219277, + 0.061129065987737714 + ], + [ + 0.061336540454007375, + 0.06128236699738327, + 0.0612795998872473 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.696119107404097E-4, + "scoreError" : 9.97721816459628E-6, + "scoreConfidence" : [ + 3.596346925758134E-4, + 3.79589128905006E-4 + ], + "scorePercentiles" : { + "0.0" : 3.626888560288343E-4, + "50.0" : 3.686331515365253E-4, + "90.0" : 3.773193622138792E-4, + "95.0" : 3.773193622138792E-4, + "99.0" : 3.773193622138792E-4, + "99.9" : 3.773193622138792E-4, + "99.99" : 3.773193622138792E-4, + "99.999" : 3.773193622138792E-4, + "99.9999" : 3.773193622138792E-4, + "100.0" : 3.773193622138792E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7698920463475277E-4, + 3.773193622138792E-4, + 3.762850259338338E-4 + ], + [ + 3.626888560288343E-4, + 3.637296742969206E-4, + 3.63402454815387E-4 + ], + [ + 3.6888732463155117E-4, + 3.686331515365253E-4, + 3.685721425720028E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01429124971939135, + "scoreError" : 4.7653081770894496E-4, + "scoreConfidence" : [ + 0.013814718901682404, + 0.014767780537100294 + ], + "scorePercentiles" : { + "0.0" : 0.014011771877022926, + "50.0" : 0.014203055541826094, + "90.0" : 0.014662239724822296, + "95.0" : 0.014662239724822296, + "99.0" : 0.014662239724822296, + "99.9" : 0.014662239724822296, + "99.99" : 0.014662239724822296, + "99.999" : 0.014662239724822296, + "99.9999" : 0.014662239724822296, + "100.0" : 0.014662239724822296 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0142007654630245, + 0.014205766461443175, + 0.014203055541826094 + ], + [ + 0.014025981748205747, + 0.014011771877022926, + 0.014013038340596667 + ], + [ + 0.01464161089498721, + 0.01465701742259353, + 0.014662239724822296 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9781382338333438, + "scoreError" : 0.01588711632877792, + "scoreConfidence" : [ + 0.9622511175045658, + 0.9940253501621217 + ], + "scorePercentiles" : { + "0.0" : 0.9687070489151491, + "50.0" : 0.9749398667381556, + "90.0" : 0.9923944358440012, + "95.0" : 0.9923944358440012, + "99.0" : 0.9923944358440012, + "99.9" : 0.9923944358440012, + "99.99" : 0.9923944358440012, + "99.999" : 0.9923944358440012, + "99.9999" : 0.9923944358440012, + "100.0" : 0.9923944358440012 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9905149994057052, + 0.9877674571315685, + 0.9923944358440012 + ], + [ + 0.9687070489151491, + 0.9702613015426409, + 0.9690745838178294 + ], + [ + 0.9750571266575663, + 0.9749398667381556, + 0.9745272844474762 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012951543349691617, + "scoreError" : 7.17908173353132E-5, + "scoreConfidence" : [ + 0.012879752532356304, + 0.01302333416702693 + ], + "scorePercentiles" : { + "0.0" : 0.012927962256345552, + "50.0" : 0.012945963688038627, + "90.0" : 0.012992789849235263, + "95.0" : 0.012992789849235263, + "99.0" : 0.012992789849235263, + "99.9" : 0.012992789849235263, + "99.99" : 0.012992789849235263, + "99.999" : 0.012992789849235263, + "99.9999" : 0.012992789849235263, + "100.0" : 0.012992789849235263 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01293589796652265, + 0.012929136678630163, + 0.012927962256345552 + ], + [ + 0.012992789849235263, + 0.012956029409554606, + 0.012967443937861459 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6448004708793054, + "scoreError" : 0.23658004422340556, + "scoreConfidence" : [ + 3.4082204266559, + 3.8813805151027108 + ], + "scorePercentiles" : { + "0.0" : 3.5409849886765747, + "50.0" : 3.650745095226265, + "90.0" : 3.722874720982143, + "95.0" : 3.722874720982143, + "99.0" : 3.722874720982143, + "99.9" : 3.722874720982143, + "99.99" : 3.722874720982143, + "99.999" : 3.722874720982143, + "99.9999" : 3.722874720982143, + "100.0" : 3.722874720982143 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7169321567607727, + 3.722874720982143, + 3.7216814717261903 + ], + [ + 3.5409849886765747, + 3.5817714534383955, + 3.5845580336917564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.792517699935429, + "scoreError" : 0.02652058118597728, + "scoreConfidence" : [ + 2.7659971187494516, + 2.819038281121406 + ], + "scorePercentiles" : { + "0.0" : 2.7707105880886425, + "50.0" : 2.791919388051368, + "90.0" : 2.811218851602024, + "95.0" : 2.811218851602024, + "99.0" : 2.811218851602024, + "99.9" : 2.811218851602024, + "99.99" : 2.811218851602024, + "99.999" : 2.811218851602024, + "99.9999" : 2.811218851602024, + "100.0" : 2.811218851602024 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8110501843732436, + 2.811218851602024, + 2.8094077328651688 + ], + [ + 2.771137926018288, + 2.7707105880886425, + 2.7836048469245758 + ], + [ + 2.791919388051368, + 2.792374098548297, + 2.791235682947251 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1742432157856465, + "scoreError" : 0.004875078290119533, + "scoreConfidence" : [ + 0.16936813749552695, + 0.17911829407576604 + ], + "scorePercentiles" : { + "0.0" : 0.17208208915388984, + "50.0" : 0.17246391856514615, + "90.0" : 0.17818732172766474, + "95.0" : 0.17818732172766474, + "99.0" : 0.17818732172766474, + "99.9" : 0.17818732172766474, + "99.99" : 0.17818732172766474, + "99.999" : 0.17818732172766474, + "99.9999" : 0.17818732172766474, + "100.0" : 0.17818732172766474 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17262994255036337, + 0.1722843506761995, + 0.17215549340655556 + ], + [ + 0.1722585692803252, + 0.17208208915388984, + 0.17246391856514615 + ], + [ + 0.17818732172766474, + 0.17799467089689053, + 0.17813258581378363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3333449063182734, + "scoreError" : 0.005905235020739848, + "scoreConfidence" : [ + 0.32743967129753354, + 0.33925014133901327 + ], + "scorePercentiles" : { + "0.0" : 0.329350732446318, + "50.0" : 0.33232254492888474, + "90.0" : 0.33807079141311697, + "95.0" : 0.33807079141311697, + "99.0" : 0.33807079141311697, + "99.9" : 0.33807079141311697, + "99.99" : 0.33807079141311697, + "99.999" : 0.33807079141311697, + "99.9999" : 0.33807079141311697, + "100.0" : 0.33807079141311697 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3301769634508716, + 0.329350732446318, + 0.32948116519504483 + ], + [ + 0.33404202852657244, + 0.33232254492888474, + 0.33195924776763486 + ], + [ + 0.33807079141311697, + 0.33732083306348243, + 0.3373798500725347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16205925527522547, + "scoreError" : 0.005801548356563951, + "scoreConfidence" : [ + 0.1562577069186615, + 0.16786080363178943 + ], + "scorePercentiles" : { + "0.0" : 0.15775786740810854, + "50.0" : 0.162711726244712, + "90.0" : 0.16611034483904188, + "95.0" : 0.16611034483904188, + "99.0" : 0.16611034483904188, + "99.9" : 0.16611034483904188, + "99.99" : 0.16611034483904188, + "99.999" : 0.16611034483904188, + "99.9999" : 0.16611034483904188, + "100.0" : 0.16611034483904188 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15784430243863942, + 0.15775786740810854, + 0.1578714414309169 + ], + [ + 0.16611034483904188, + 0.1653657661931771, + 0.16567923764475886 + ], + [ + 0.16281569179922176, + 0.162711726244712, + 0.1623769194784529 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38844540306756375, + "scoreError" : 0.007554763837641979, + "scoreConfidence" : [ + 0.3808906392299218, + 0.39600016690520573 + ], + "scorePercentiles" : { + "0.0" : 0.38233104985471783, + "50.0" : 0.38763725885727573, + "90.0" : 0.3965965093793377, + "95.0" : 0.3965965093793377, + "99.0" : 0.3965965093793377, + "99.9" : 0.3965965093793377, + "99.99" : 0.3965965093793377, + "99.999" : 0.3965965093793377, + "99.9999" : 0.3965965093793377, + "100.0" : 0.3965965093793377 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3913939590215264, + 0.3826024790343561, + 0.38233104985471783 + ], + [ + 0.39190607030607044, + 0.38736799585528353, + 0.38763725885727573 + ], + [ + 0.3965965093793377, + 0.38878835813700335, + 0.38738494716250244 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15717731845538507, + "scoreError" : 0.0025445160448387513, + "scoreConfidence" : [ + 0.15463280241054633, + 0.1597218345002238 + ], + "scorePercentiles" : { + "0.0" : 0.15498779949474598, + "50.0" : 0.1574507210334892, + "90.0" : 0.15957643376896932, + "95.0" : 0.15957643376896932, + "99.0" : 0.15957643376896932, + "99.9" : 0.15957643376896932, + "99.99" : 0.15957643376896932, + "99.999" : 0.15957643376896932, + "99.9999" : 0.15957643376896932, + "100.0" : 0.15957643376896932 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15595670473472442, + 0.1553044715721141, + 0.15498779949474598 + ], + [ + 0.15957643376896932, + 0.15827448316794074, + 0.15837715270343036 + ], + [ + 0.15745232445326154, + 0.1574507210334892, + 0.15721577516978996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04712556397907962, + "scoreError" : 0.0015890684722958284, + "scoreConfidence" : [ + 0.04553649550678379, + 0.048714632451375445 + ], + "scorePercentiles" : { + "0.0" : 0.045865031742610134, + "50.0" : 0.047629415089756474, + "90.0" : 0.048132523928707226, + "95.0" : 0.048132523928707226, + "99.0" : 0.048132523928707226, + "99.9" : 0.048132523928707226, + "99.99" : 0.048132523928707226, + "99.999" : 0.048132523928707226, + "99.9999" : 0.048132523928707226, + "100.0" : 0.048132523928707226 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047704076315776923, + 0.04758969826585194, + 0.047651035980787376 + ], + [ + 0.045865031742610134, + 0.04587505893929455, + 0.04590735107926219 + ], + [ + 0.048132523928707226, + 0.04777588446966982, + 0.047629415089756474 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9287425.275754306, + "scoreError" : 673064.5173172944, + "scoreConfidence" : [ + 8614360.758437011, + 9960489.793071602 + ], + "scorePercentiles" : { + "0.0" : 8931976.855357142, + "50.0" : 9097843.042727273, + "90.0" : 9823178.722276742, + "95.0" : 9823178.722276742, + "99.0" : 9823178.722276742, + "99.9" : 9823178.722276742, + "99.99" : 9823178.722276742, + "99.999" : 9823178.722276742, + "99.9999" : 9823178.722276742, + "100.0" : 9823178.722276742 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9798666.694417238, + 9815992.58390579, + 9823178.722276742 + ], + [ + 9135345.167123288, + 9097843.042727273, + 9086959.946412353 + ], + [ + 8957876.223813787, + 8938988.245755138, + 8931976.855357142 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:18:38Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json b/performance-results/2025-04-03T04:18:38Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json new file mode 100644 index 0000000000..0fe671611f --- /dev/null +++ b/performance-results/2025-04-03T04:18:38Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4069670399174807, + "scoreError" : 0.01377711284446077, + "scoreConfidence" : [ + 3.39318992707302, + 3.4207441527619413 + ], + "scorePercentiles" : { + "0.0" : 3.4045192638077895, + "50.0" : 3.4072206524360227, + "90.0" : 3.408907590990087, + "95.0" : 3.408907590990087, + "99.0" : 3.408907590990087, + "99.9" : 3.408907590990087, + "99.99" : 3.408907590990087, + "99.999" : 3.408907590990087, + "99.9999" : 3.408907590990087, + "100.0" : 3.408907590990087 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4045192638077895, + 3.4085900660281925 + ], + [ + 3.405851238843853, + 3.408907590990087 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.719648412053527, + "scoreError" : 0.02809970741527712, + "scoreConfidence" : [ + 1.6915487046382498, + 1.747748119468804 + ], + "scorePercentiles" : { + "0.0" : 1.7142389493573933, + "50.0" : 1.7197343077505653, + "90.0" : 1.724886083355584, + "95.0" : 1.724886083355584, + "99.0" : 1.724886083355584, + "99.9" : 1.724886083355584, + "99.99" : 1.724886083355584, + "99.999" : 1.724886083355584, + "99.9999" : 1.724886083355584, + "100.0" : 1.724886083355584 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7198267502215996, + 1.724886083355584 + ], + [ + 1.7142389493573933, + 1.719641865279531 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8662654811505468, + "scoreError" : 0.00672456953410522, + "scoreConfidence" : [ + 0.8595409116164415, + 0.8729900506846521 + ], + "scorePercentiles" : { + "0.0" : 0.8653473559404564, + "50.0" : 0.8660314345774419, + "90.0" : 0.8676516995068471, + "95.0" : 0.8676516995068471, + "99.0" : 0.8676516995068471, + "99.9" : 0.8676516995068471, + "99.99" : 0.8676516995068471, + "99.999" : 0.8676516995068471, + "99.9999" : 0.8676516995068471, + "100.0" : 0.8676516995068471 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8653473559404564, + 0.8664642452472594 + ], + [ + 0.8655986239076244, + 0.8676516995068471 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.881613268860953, + "scoreError" : 0.16972371039592618, + "scoreConfidence" : [ + 15.711889558465026, + 16.051336979256877 + ], + "scorePercentiles" : { + "0.0" : 15.742701283030245, + "50.0" : 15.901656590162244, + "90.0" : 15.99973571476549, + "95.0" : 15.99973571476549, + "99.0" : 15.99973571476549, + "99.9" : 15.99973571476549, + "99.99" : 15.99973571476549, + "99.999" : 15.99973571476549, + "99.9999" : 15.99973571476549, + "100.0" : 15.99973571476549 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.935344863973986, + 15.972098879330911, + 15.901656590162244 + ], + [ + 15.757391679403302, + 15.871936389357284, + 15.773600580677298 + ], + [ + 15.742701283030245, + 15.980053439047829, + 15.99973571476549 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2573.939325064266, + "scoreError" : 66.9181072449432, + "scoreConfidence" : [ + 2507.021217819323, + 2640.8574323092093 + ], + "scorePercentiles" : { + "0.0" : 2515.2229208854337, + "50.0" : 2569.4866319365015, + "90.0" : 2639.1359506980743, + "95.0" : 2639.1359506980743, + "99.0" : 2639.1359506980743, + "99.9" : 2639.1359506980743, + "99.99" : 2639.1359506980743, + "99.999" : 2639.1359506980743, + "99.9999" : 2639.1359506980743, + "100.0" : 2639.1359506980743 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2560.1238720819943, + 2515.2229208854337, + 2554.682790491716 + ], + [ + 2569.4866319365015, + 2607.02742513819, + 2586.839165945245 + ], + [ + 2527.5210870802625, + 2605.414081320981, + 2639.1359506980743 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 68846.59384431818, + "scoreError" : 1148.764589611738, + "scoreConfidence" : [ + 67697.82925470645, + 69995.35843392991 + ], + "scorePercentiles" : { + "0.0" : 68007.01410414431, + "50.0" : 68771.41539379892, + "90.0" : 69848.51628355683, + "95.0" : 69848.51628355683, + "99.0" : 69848.51628355683, + "99.9" : 69848.51628355683, + "99.99" : 69848.51628355683, + "99.999" : 69848.51628355683, + "99.9999" : 69848.51628355683, + "100.0" : 69848.51628355683 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69523.41353028912, + 69848.51628355683, + 69556.08312562345 + ], + [ + 68007.01410414431, + 68771.41539379892, + 69007.79544421007 + ], + [ + 68034.56775354304, + 68574.90101325582, + 68295.63795044218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.9326843032323, + "scoreError" : 5.632654178479563, + "scoreConfidence" : [ + 337.3000301247527, + 348.5653384817119 + ], + "scorePercentiles" : { + "0.0" : 338.22134638914224, + "50.0" : 342.65657276820275, + "90.0" : 348.7118127353454, + "95.0" : 348.7118127353454, + "99.0" : 348.7118127353454, + "99.9" : 348.7118127353454, + "99.99" : 348.7118127353454, + "99.999" : 348.7118127353454, + "99.9999" : 348.7118127353454, + "100.0" : 348.7118127353454 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.2396737614174, + 344.4937949433161, + 348.7118127353454 + ], + [ + 338.22134638914224, + 339.50568888443763, + 344.2246711810125 + ], + [ + 342.65657276820275, + 340.39185850752824, + 341.9487395586887 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.41664466797751, + "scoreError" : 3.4239410559884464, + "scoreConfidence" : [ + 100.99270361198906, + 107.84058572396596 + ], + "scorePercentiles" : { + "0.0" : 101.34074595436566, + "50.0" : 105.26679530526971, + "90.0" : 106.52285125107282, + "95.0" : 106.52285125107282, + "99.0" : 106.52285125107282, + "99.9" : 106.52285125107282, + "99.99" : 106.52285125107282, + "99.999" : 106.52285125107282, + "99.9999" : 106.52285125107282, + "100.0" : 106.52285125107282 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 102.03512173310942, + 101.34074595436566, + 102.14607145041818 + ], + [ + 105.99328845197857, + 106.09573198089387, + 104.36496507781024 + ], + [ + 105.26679530526971, + 105.98423080687914, + 106.52285125107282 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06291601396860064, + "scoreError" : 0.0010268130772880873, + "scoreConfidence" : [ + 0.06188920089131255, + 0.06394282704588873 + ], + "scorePercentiles" : { + "0.0" : 0.06190691776395209, + "50.0" : 0.06296611601329824, + "90.0" : 0.0638439230946027, + "95.0" : 0.0638439230946027, + "99.0" : 0.0638439230946027, + "99.9" : 0.0638439230946027, + "99.99" : 0.0638439230946027, + "99.999" : 0.0638439230946027, + "99.9999" : 0.0638439230946027, + "100.0" : 0.0638439230946027 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06264503327653603, + 0.06243686636905691, + 0.06332339414394447 + ], + [ + 0.06244408786981879, + 0.06190691776395209, + 0.0638439230946027 + ], + [ + 0.06317183357022381, + 0.06296611601329824, + 0.06350595361597276 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.772918445712037E-4, + "scoreError" : 1.3750074525357626E-5, + "scoreConfidence" : [ + 3.635417700458461E-4, + 3.910419190965613E-4 + ], + "scorePercentiles" : { + "0.0" : 3.67455808549216E-4, + "50.0" : 3.758903578714715E-4, + "90.0" : 3.898184364874329E-4, + "95.0" : 3.898184364874329E-4, + "99.0" : 3.898184364874329E-4, + "99.9" : 3.898184364874329E-4, + "99.99" : 3.898184364874329E-4, + "99.999" : 3.898184364874329E-4, + "99.9999" : 3.898184364874329E-4, + "100.0" : 3.898184364874329E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.822310819920716E-4, + 3.8398533949458825E-4, + 3.898184364874329E-4 + ], + [ + 3.7456247794088814E-4, + 3.758903578714715E-4, + 3.844980090532881E-4 + ], + [ + 3.684198426518969E-4, + 3.6876524709997987E-4, + 3.67455808549216E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014692487168159126, + "scoreError" : 1.0890921120123715E-4, + "scoreConfidence" : [ + 0.014583577956957888, + 0.014801396379360364 + ], + "scorePercentiles" : { + "0.0" : 0.014623069662020972, + "50.0" : 0.014686299765904265, + "90.0" : 0.01481580967669291, + "95.0" : 0.01481580967669291, + "99.0" : 0.01481580967669291, + "99.9" : 0.01481580967669291, + "99.99" : 0.01481580967669291, + "99.999" : 0.01481580967669291, + "99.9999" : 0.01481580967669291, + "100.0" : 0.01481580967669291 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01481580967669291, + 0.014761402142737998, + 0.01471955471785874 + ], + [ + 0.014686299765904265, + 0.014623069662020972, + 0.01464070584084271 + ], + [ + 0.014698066747505035, + 0.014626562814467248, + 0.014660913145402247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.991542696406702, + "scoreError" : 0.023328699477302327, + "scoreConfidence" : [ + 0.9682139969293997, + 1.0148713958840043 + ], + "scorePercentiles" : { + "0.0" : 0.9696445302501454, + "50.0" : 0.9992563994804157, + "90.0" : 1.0060960282696176, + "95.0" : 1.0060960282696176, + "99.0" : 1.0060960282696176, + "99.9" : 1.0060960282696176, + "99.99" : 1.0060960282696176, + "99.999" : 1.0060960282696176, + "99.9999" : 1.0060960282696176, + "100.0" : 1.0060960282696176 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9999140340965903, + 0.9992563994804157, + 0.9996002698650674 + ], + [ + 1.001559894241362, + 1.0060960282696176, + 0.9970750286141575 + ], + [ + 0.9696445302501454, + 0.9763279108659573, + 0.9744101719770047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013056361858015402, + "scoreError" : 9.322779867712266E-4, + "scoreConfidence" : [ + 0.012124083871244177, + 0.013988639844786628 + ], + "scorePercentiles" : { + "0.0" : 0.01265293295628519, + "50.0" : 0.013073918976377876, + "90.0" : 0.013424728910260541, + "95.0" : 0.013424728910260541, + "99.0" : 0.013424728910260541, + "99.9" : 0.013424728910260541, + "99.99" : 0.013424728910260541, + "99.999" : 0.013424728910260541, + "99.9999" : 0.013424728910260541, + "100.0" : 0.013424728910260541 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01265293295628519, + 0.012762067769615975, + 0.01287342819259179 + ], + [ + 0.013274409760163962, + 0.013424728910260541, + 0.013350603559174955 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.7533453814696007, + "scoreError" : 0.07221931908733174, + "scoreConfidence" : [ + 3.681126062382269, + 3.8255647005569324 + ], + "scorePercentiles" : { + "0.0" : 3.715878045319465, + "50.0" : 3.7647120831820504, + "90.0" : 3.7759736120754717, + "95.0" : 3.7759736120754717, + "99.0" : 3.7759736120754717, + "99.9" : 3.7759736120754717, + "99.99" : 3.7759736120754717, + "99.999" : 3.7759736120754717, + "99.9999" : 3.7759736120754717, + "100.0" : 3.7759736120754717 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7583392802404205, + 3.715878045319465, + 3.726707458271237 + ], + [ + 3.7710848861236803, + 3.7720890067873305, + 3.7759736120754717 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.889554648811101, + "scoreError" : 0.10180974707315243, + "scoreConfidence" : [ + 2.7877449017379483, + 2.9913643958842533 + ], + "scorePercentiles" : { + "0.0" : 2.8047336149747615, + "50.0" : 2.9016337911227152, + "90.0" : 2.970081754083754, + "95.0" : 2.970081754083754, + "99.0" : 2.970081754083754, + "99.9" : 2.970081754083754, + "99.99" : 2.970081754083754, + "99.999" : 2.970081754083754, + "99.9999" : 2.970081754083754, + "100.0" : 2.970081754083754 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.970081754083754, + 2.9444875981748604, + 2.90051821287703 + ], + [ + 2.8047336149747615, + 2.8152427427526034, + 2.822288823927765 + ], + [ + 2.9185109804493727, + 2.9284943209370424, + 2.9016337911227152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1805457075975223, + "scoreError" : 0.0032906053591940008, + "scoreConfidence" : [ + 0.1772551022383283, + 0.18383631295671632 + ], + "scorePercentiles" : { + "0.0" : 0.1789229324936036, + "50.0" : 0.1797346438469419, + "90.0" : 0.18514838317410945, + "95.0" : 0.18514838317410945, + "99.0" : 0.18514838317410945, + "99.9" : 0.18514838317410945, + "99.99" : 0.18514838317410945, + "99.999" : 0.18514838317410945, + "99.9999" : 0.18514838317410945, + "100.0" : 0.18514838317410945 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18514838317410945, + 0.18192817100858683, + 0.18085476485694651 + ], + [ + 0.1797346438469419, + 0.17923391680108972, + 0.18011414041280935 + ], + [ + 0.1789229324936036, + 0.17933638023420548, + 0.1796380355494081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33802979936950583, + "scoreError" : 0.007790846575675005, + "scoreConfidence" : [ + 0.3302389527938308, + 0.34582064594518086 + ], + "scorePercentiles" : { + "0.0" : 0.33224624904481875, + "50.0" : 0.3363953684405275, + "90.0" : 0.3439181182681065, + "95.0" : 0.3439181182681065, + "99.0" : 0.3439181182681065, + "99.9" : 0.3439181182681065, + "99.99" : 0.3439181182681065, + "99.999" : 0.3439181182681065, + "99.9999" : 0.3439181182681065, + "100.0" : 0.3439181182681065 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3363953684405275, + 0.3355822697651007, + 0.33907762964093174 + ], + [ + 0.3438371653142621, + 0.3439181182681065, + 0.34326591658943467 + ], + [ + 0.33389524587646074, + 0.3340502313859104, + 0.33224624904481875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16610825006196098, + "scoreError" : 0.005481242770670671, + "scoreConfidence" : [ + 0.1606270072912903, + 0.17158949283263164 + ], + "scorePercentiles" : { + "0.0" : 0.16116178712671833, + "50.0" : 0.16686997396876252, + "90.0" : 0.16965193444847826, + "95.0" : 0.16965193444847826, + "99.0" : 0.16965193444847826, + "99.9" : 0.16965193444847826, + "99.99" : 0.16965193444847826, + "99.999" : 0.16965193444847826, + "99.9999" : 0.16965193444847826, + "100.0" : 0.16965193444847826 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16686997396876252, + 0.1677147124744239, + 0.1665400422502373 + ], + [ + 0.16275387152529133, + 0.16116178712671833, + 0.16213362620989316 + ], + [ + 0.16965193444847826, + 0.1692971778936498, + 0.16885112466019417 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3900476853359935, + "scoreError" : 0.013179482989262305, + "scoreConfidence" : [ + 0.3768682023467312, + 0.4032271683252558 + ], + "scorePercentiles" : { + "0.0" : 0.378498379168086, + "50.0" : 0.39198960250078396, + "90.0" : 0.401988626281304, + "95.0" : 0.401988626281304, + "99.0" : 0.401988626281304, + "99.9" : 0.401988626281304, + "99.99" : 0.401988626281304, + "99.999" : 0.401988626281304, + "99.9999" : 0.401988626281304, + "100.0" : 0.401988626281304 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39413079210184054, + 0.378498379168086, + 0.37850229889103365 + ], + [ + 0.401988626281304, + 0.39198960250078396, + 0.3924206083032491 + ], + [ + 0.39697791433448454, + 0.38790818863460047, + 0.38801275780855937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1558497393759247, + "scoreError" : 0.005886044703965503, + "scoreConfidence" : [ + 0.1499636946719592, + 0.1617357840798902 + ], + "scorePercentiles" : { + "0.0" : 0.1525339157870653, + "50.0" : 0.15429124798654612, + "90.0" : 0.16052009594054478, + "95.0" : 0.16052009594054478, + "99.0" : 0.16052009594054478, + "99.9" : 0.16052009594054478, + "99.99" : 0.16052009594054478, + "99.999" : 0.16052009594054478, + "99.9999" : 0.16052009594054478, + "100.0" : 0.16052009594054478 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15263621707343134, + 0.15287506503195034, + 0.1525339157870653 + ], + [ + 0.16052009594054478, + 0.1603939217617245, + 0.16025259234331682 + ], + [ + 0.15504192820155038, + 0.15429124798654612, + 0.1541026702571926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046866688633485816, + "scoreError" : 4.7205703256350144E-4, + "scoreConfidence" : [ + 0.04639463160092232, + 0.047338745666049314 + ], + "scorePercentiles" : { + "0.0" : 0.0465004971821031, + "50.0" : 0.04677862280611481, + "90.0" : 0.047195328475420975, + "95.0" : 0.047195328475420975, + "99.0" : 0.047195328475420975, + "99.9" : 0.047195328475420975, + "99.99" : 0.047195328475420975, + "99.999" : 0.047195328475420975, + "99.9999" : 0.047195328475420975, + "100.0" : 0.047195328475420975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04677862280611481, + 0.0465004971821031, + 0.04658195166248987 + ], + [ + 0.047106999882234345, + 0.04674651273349414, + 0.046599830365755344 + ], + [ + 0.04717519188221475, + 0.04711526271154499, + 0.047195328475420975 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9274065.194162289, + "scoreError" : 255674.20191399023, + "scoreConfidence" : [ + 9018390.992248299, + 9529739.396076279 + ], + "scorePercentiles" : { + "0.0" : 9054173.222624434, + "50.0" : 9343782.669467786, + "90.0" : 9467276.662251655, + "95.0" : 9467276.662251655, + "99.0" : 9467276.662251655, + "99.9" : 9467276.662251655, + "99.99" : 9467276.662251655, + "99.999" : 9467276.662251655, + "99.9999" : 9467276.662251655, + "100.0" : 9467276.662251655 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9370335.287453184, + 9343782.669467786, + 9419851.420507995 + ], + [ + 9199186.877757354, + 9373907.444236176, + 9467276.662251655 + ], + [ + 9054173.222624434, + 9103496.834394904, + 9134576.328767123 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:19:02Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json b/performance-results/2025-04-03T04:19:02Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json new file mode 100644 index 0000000000..4f6416e5a3 --- /dev/null +++ b/performance-results/2025-04-03T04:19:02Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4207323250526915, + "scoreError" : 0.0319456484452798, + "scoreConfidence" : [ + 3.388786676607412, + 3.452677973497971 + ], + "scorePercentiles" : { + "0.0" : 3.4148720216622768, + "50.0" : 3.420843722069556, + "90.0" : 3.4263698344093774, + "95.0" : 3.4263698344093774, + "99.0" : 3.4263698344093774, + "99.9" : 3.4263698344093774, + "99.99" : 3.4263698344093774, + "99.999" : 3.4263698344093774, + "99.9999" : 3.4263698344093774, + "100.0" : 3.4263698344093774 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4148720216622768, + 3.4227369708906776 + ], + [ + 3.4189504732484335, + 3.4263698344093774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7277102944001554, + "scoreError" : 0.0031271802076314223, + "scoreConfidence" : [ + 1.724583114192524, + 1.7308374746077868 + ], + "scorePercentiles" : { + "0.0" : 1.7273150184436197, + "50.0" : 1.7276098423405877, + "90.0" : 1.7283064744758272, + "95.0" : 1.7283064744758272, + "99.0" : 1.7283064744758272, + "99.9" : 1.7283064744758272, + "99.99" : 1.7283064744758272, + "99.999" : 1.7283064744758272, + "99.9999" : 1.7283064744758272, + "100.0" : 1.7283064744758272 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7273150184436197, + 1.7279020093223763 + ], + [ + 1.7273176753587989, + 1.7283064744758272 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8682495052702349, + "scoreError" : 0.003949470062662093, + "scoreConfidence" : [ + 0.8643000352075728, + 0.872198975332897 + ], + "scorePercentiles" : { + "0.0" : 0.8677494428788252, + "50.0" : 0.8680539988529801, + "90.0" : 0.8691405804961545, + "95.0" : 0.8691405804961545, + "99.0" : 0.8691405804961545, + "99.9" : 0.8691405804961545, + "99.99" : 0.8691405804961545, + "99.999" : 0.8691405804961545, + "99.9999" : 0.8691405804961545, + "100.0" : 0.8691405804961545 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8680616748545228, + 0.8677494428788252 + ], + [ + 0.8680463228514372, + 0.8691405804961545 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.129063634777115, + "scoreError" : 0.08527819871813747, + "scoreConfidence" : [ + 16.04378543605898, + 16.21434183349525 + ], + "scorePercentiles" : { + "0.0" : 16.059264510157075, + "50.0" : 16.108068079257407, + "90.0" : 16.214119925984104, + "95.0" : 16.214119925984104, + "99.0" : 16.214119925984104, + "99.9" : 16.214119925984104, + "99.99" : 16.214119925984104, + "99.999" : 16.214119925984104, + "99.9999" : 16.214119925984104, + "100.0" : 16.214119925984104 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.0925343717999, + 16.09984081671261, + 16.108068079257407 + ], + [ + 16.214119925984104, + 16.159726236461857, + 16.19100512182415 + ], + [ + 16.059264510157075, + 16.097684680162253, + 16.139328970634665 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2690.9112918289243, + "scoreError" : 89.11642467727573, + "scoreConfidence" : [ + 2601.7948671516488, + 2780.0277165062 + ], + "scorePercentiles" : { + "0.0" : 2652.044232240892, + "50.0" : 2657.6655237443792, + "90.0" : 2763.516905739167, + "95.0" : 2763.516905739167, + "99.0" : 2763.516905739167, + "99.9" : 2763.516905739167, + "99.99" : 2763.516905739167, + "99.999" : 2763.516905739167, + "99.9999" : 2763.516905739167, + "100.0" : 2763.516905739167 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2763.516905739167, + 2757.9183269925015, + 2763.176354709843 + ], + [ + 2659.1776750958593, + 2652.044232240892, + 2657.6655237443792 + ], + [ + 2653.991151912376, + 2655.9615935642164, + 2654.7498624610816 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70813.59294604426, + "scoreError" : 285.425501314716, + "scoreConfidence" : [ + 70528.16744472954, + 71099.01844735898 + ], + "scorePercentiles" : { + "0.0" : 70628.70211461508, + "50.0" : 70783.99135660434, + "90.0" : 71040.45930720455, + "95.0" : 71040.45930720455, + "99.0" : 71040.45930720455, + "99.9" : 71040.45930720455, + "99.99" : 71040.45930720455, + "99.999" : 71040.45930720455, + "99.9999" : 71040.45930720455, + "100.0" : 71040.45930720455 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71040.45930720455, + 71024.63676656474, + 71018.19681898014 + ], + [ + 70800.4921040496, + 70689.3527485353, + 70783.99135660434 + ], + [ + 70670.66800835967, + 70628.70211461508, + 70665.83728948496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.25425258646266, + "scoreError" : 7.344410731177084, + "scoreConfidence" : [ + 345.90984185528555, + 360.59866331763976 + ], + "scorePercentiles" : { + "0.0" : 347.27155054221925, + "50.0" : 355.65845226413325, + "90.0" : 357.51761485639236, + "95.0" : 357.51761485639236, + "99.0" : 357.51761485639236, + "99.9" : 357.51761485639236, + "99.99" : 357.51761485639236, + "99.999" : 357.51761485639236, + "99.9999" : 357.51761485639236, + "100.0" : 357.51761485639236 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.7057941305003, + 355.65845226413325, + 356.40599321473053 + ], + [ + 357.51761485639236, + 356.7266455150841, + 354.7055422687994 + ], + [ + 347.27155054221925, + 347.42020970279657, + 347.8764707835086 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.2220803435144, + "scoreError" : 1.3778531511347178, + "scoreConfidence" : [ + 106.84422719237969, + 109.59993349464912 + ], + "scorePercentiles" : { + "0.0" : 107.19737504715748, + "50.0" : 108.38482161616515, + "90.0" : 109.49844061242605, + "95.0" : 109.49844061242605, + "99.0" : 109.49844061242605, + "99.9" : 109.49844061242605, + "99.99" : 109.49844061242605, + "99.999" : 109.49844061242605, + "99.9999" : 109.49844061242605, + "100.0" : 109.49844061242605 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.49844061242605, + 108.855934976009, + 108.84497615431408 + ], + [ + 108.27115702933337, + 108.41776316427838, + 108.38482161616515 + ], + [ + 107.32316112420783, + 107.20509336773831, + 107.19737504715748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06187979929930037, + "scoreError" : 4.89919681720745E-4, + "scoreConfidence" : [ + 0.06138987961757962, + 0.062369718981021116 + ], + "scorePercentiles" : { + "0.0" : 0.06156398933727337, + "50.0" : 0.06173390797466479, + "90.0" : 0.062283656367169496, + "95.0" : 0.062283656367169496, + "99.0" : 0.062283656367169496, + "99.9" : 0.062283656367169496, + "99.99" : 0.062283656367169496, + "99.999" : 0.062283656367169496, + "99.9999" : 0.062283656367169496, + "100.0" : 0.062283656367169496 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061646123259297615, + 0.06173390797466479, + 0.06196862166148202 + ], + [ + 0.062283656367169496, + 0.06225505770954729, + 0.06216190292903675 + ], + [ + 0.061721765325268484, + 0.06156398933727337, + 0.06158316912996354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.724198382138392E-4, + "scoreError" : 8.699200781534305E-6, + "scoreConfidence" : [ + 3.637206374323049E-4, + 3.8111903899537347E-4 + ], + "scorePercentiles" : { + "0.0" : 3.651132355641374E-4, + "50.0" : 3.7532956662498937E-4, + "90.0" : 3.770072542482455E-4, + "95.0" : 3.770072542482455E-4, + "99.0" : 3.770072542482455E-4, + "99.9" : 3.770072542482455E-4, + "99.99" : 3.770072542482455E-4, + "99.999" : 3.770072542482455E-4, + "99.9999" : 3.770072542482455E-4, + "100.0" : 3.770072542482455E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7532956662498937E-4, + 3.7440243865318883E-4, + 3.754156135124096E-4 + ], + [ + 3.770072542482455E-4, + 3.7648122859236174E-4, + 3.763393834485371E-4 + ], + [ + 3.6621271513166535E-4, + 3.6547710814901834E-4, + 3.651132355641374E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014120962875839724, + "scoreError" : 1.5472298051941275E-4, + "scoreConfidence" : [ + 0.013966239895320311, + 0.014275685856359138 + ], + "scorePercentiles" : { + "0.0" : 0.014002392716320438, + "50.0" : 0.014128934788690208, + "90.0" : 0.0142317715103421, + "95.0" : 0.0142317715103421, + "99.0" : 0.0142317715103421, + "99.9" : 0.0142317715103421, + "99.99" : 0.0142317715103421, + "99.999" : 0.0142317715103421, + "99.9999" : 0.0142317715103421, + "100.0" : 0.0142317715103421 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014128934788690208, + 0.014126580095325006, + 0.014130934258050294 + ], + [ + 0.014205468612696974, + 0.014230774158935892, + 0.0142317715103421 + ], + [ + 0.014018518749561925, + 0.014002392716320438, + 0.014013290992634694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9710586987458186, + "scoreError" : 0.010987316611614452, + "scoreConfidence" : [ + 0.9600713821342042, + 0.9820460153574331 + ], + "scorePercentiles" : { + "0.0" : 0.955936307111451, + "50.0" : 0.9733839632080981, + "90.0" : 0.9767457063189765, + "95.0" : 0.9767457063189765, + "99.0" : 0.9767457063189765, + "99.9" : 0.9767457063189765, + "99.99" : 0.9767457063189765, + "99.999" : 0.9767457063189765, + "99.9999" : 0.9767457063189765, + "100.0" : 0.9767457063189765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9752175705509507, + 0.9749185228114642, + 0.973517640221941 + ], + [ + 0.9652071514332593, + 0.9733839632080981, + 0.955936307111451 + ], + [ + 0.9767457063189765, + 0.9722837267159246, + 0.9723177003403014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012983448700691527, + "scoreError" : 2.576521228683663E-4, + "scoreConfidence" : [ + 0.01272579657782316, + 0.013241100823559894 + ], + "scorePercentiles" : { + "0.0" : 0.012864549208333976, + "50.0" : 0.01295442629267363, + "90.0" : 0.013094527081456496, + "95.0" : 0.013094527081456496, + "99.0" : 0.013094527081456496, + "99.9" : 0.013094527081456496, + "99.99" : 0.013094527081456496, + "99.999" : 0.013094527081456496, + "99.9999" : 0.013094527081456496, + "100.0" : 0.013094527081456496 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012967554409251349, + 0.013094527081456496, + 0.01309233181204047 + ], + [ + 0.012864549208333976, + 0.012940431516970975, + 0.012941298176095909 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.695386946419859, + "scoreError" : 0.017234151890428238, + "scoreConfidence" : [ + 3.6781527945294306, + 3.7126210983102874 + ], + "scorePercentiles" : { + "0.0" : 3.689411109882006, + "50.0" : 3.6941566158227035, + "90.0" : 3.706890833951075, + "95.0" : 3.706890833951075, + "99.0" : 3.706890833951075, + "99.9" : 3.706890833951075, + "99.99" : 3.706890833951075, + "99.999" : 3.706890833951075, + "99.9999" : 3.706890833951075, + "100.0" : 3.706890833951075 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6956624397634887, + 3.69178669298893, + 3.6959198100517368 + ], + [ + 3.706890833951075, + 3.689411109882006, + 3.6926507918819187 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.836029495688691, + "scoreError" : 0.08247781158293523, + "scoreConfidence" : [ + 2.7535516841057555, + 2.9185073072716263 + ], + "scorePercentiles" : { + "0.0" : 2.780162533500139, + "50.0" : 2.8326620141602947, + "90.0" : 2.896600083405734, + "95.0" : 2.896600083405734, + "99.0" : 2.896600083405734, + "99.9" : 2.896600083405734, + "99.99" : 2.896600083405734, + "99.999" : 2.896600083405734, + "99.9999" : 2.896600083405734, + "100.0" : 2.896600083405734 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.896600083405734, + 2.89330250390512, + 2.8909107427745666 + ], + [ + 2.8418196442171073, + 2.826841927077445, + 2.8326620141602947 + ], + [ + 2.780162533500139, + 2.7807002805115375, + 2.7812657316462737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17517850014596284, + "scoreError" : 0.0037486979732552785, + "scoreConfidence" : [ + 0.17142980217270756, + 0.17892719811921812 + ], + "scorePercentiles" : { + "0.0" : 0.1717836128766276, + "50.0" : 0.17623950894383447, + "90.0" : 0.17721852954102427, + "95.0" : 0.17721852954102427, + "99.0" : 0.17721852954102427, + "99.9" : 0.17721852954102427, + "99.99" : 0.17721852954102427, + "99.999" : 0.17721852954102427, + "99.9999" : 0.17721852954102427, + "100.0" : 0.17721852954102427 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.172831079570004, + 0.17218152398415978, + 0.1717836128766276 + ], + [ + 0.17621121955560254, + 0.17623950894383447, + 0.17624023835959254 + ], + [ + 0.17707964202362192, + 0.17721852954102427, + 0.176821146459199 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32290382875128587, + "scoreError" : 0.019311333448506423, + "scoreConfidence" : [ + 0.30359249530277943, + 0.3422151621997923 + ], + "scorePercentiles" : { + "0.0" : 0.31114121480352197, + "50.0" : 0.3198565041100272, + "90.0" : 0.33750574249071885, + "95.0" : 0.33750574249071885, + "99.0" : 0.33750574249071885, + "99.9" : 0.33750574249071885, + "99.99" : 0.33750574249071885, + "99.999" : 0.33750574249071885, + "99.9999" : 0.33750574249071885, + "100.0" : 0.33750574249071885 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3373749518588489, + 0.33750574249071885, + 0.3373804223541716 + ], + [ + 0.31175855700346045, + 0.31131111596052674, + 0.31114121480352197 + ], + [ + 0.3197633228240711, + 0.3200426273562262, + 0.3198565041100272 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1583957563563813, + "scoreError" : 0.0027862408712994364, + "scoreConfidence" : [ + 0.15560951548508187, + 0.16118199722768076 + ], + "scorePercentiles" : { + "0.0" : 0.1563399570070665, + "50.0" : 0.15848177283676704, + "90.0" : 0.16027697366691776, + "95.0" : 0.16027697366691776, + "99.0" : 0.16027697366691776, + "99.9" : 0.16027697366691776, + "99.99" : 0.16027697366691776, + "99.999" : 0.16027697366691776, + "99.9999" : 0.16027697366691776, + "100.0" : 0.16027697366691776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1565101095703889, + 0.1564862471637587, + 0.1563399570070665 + ], + [ + 0.15829687175103682, + 0.15848177283676704, + 0.15865207415281127 + ], + [ + 0.16027111858131932, + 0.1602466824773656, + 0.16027697366691776 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3868561814412517, + "scoreError" : 0.0069254109492785645, + "scoreConfidence" : [ + 0.37993077049197316, + 0.3937815923905303 + ], + "scorePercentiles" : { + "0.0" : 0.38157141117216115, + "50.0" : 0.3869765164460955, + "90.0" : 0.39176893238266863, + "95.0" : 0.39176893238266863, + "99.0" : 0.39176893238266863, + "99.9" : 0.39176893238266863, + "99.99" : 0.39176893238266863, + "99.999" : 0.39176893238266863, + "99.9999" : 0.39176893238266863, + "100.0" : 0.39176893238266863 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3870978555392119, + 0.3869765164460955, + 0.3851402720970537 + ], + [ + 0.3840976532493471, + 0.381694085610687, + 0.38157141117216115 + ], + [ + 0.3917450901363209, + 0.39176893238266863, + 0.3916138163377193 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15523830175393216, + "scoreError" : 0.0026270894280356724, + "scoreConfidence" : [ + 0.1526112123258965, + 0.15786539118196782 + ], + "scorePercentiles" : { + "0.0" : 0.15325871712310923, + "50.0" : 0.15492024173134422, + "90.0" : 0.15720893628460486, + "95.0" : 0.15720893628460486, + "99.0" : 0.15720893628460486, + "99.9" : 0.15720893628460486, + "99.99" : 0.15720893628460486, + "99.999" : 0.15720893628460486, + "99.9999" : 0.15720893628460486, + "100.0" : 0.15720893628460486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15564634977431907, + 0.15492024173134422, + 0.15463564016762282 + ], + [ + 0.15720893628460486, + 0.15707466542581597, + 0.1569684785584228 + ], + [ + 0.15395843413800536, + 0.15325871712310923, + 0.15347325258214523 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04755786559883292, + "scoreError" : 0.0014208049396587064, + "scoreConfidence" : [ + 0.04613706065917421, + 0.04897867053849163 + ], + "scorePercentiles" : { + "0.0" : 0.04647786951045506, + "50.0" : 0.04765763511935682, + "90.0" : 0.04853239242226439, + "95.0" : 0.04853239242226439, + "99.0" : 0.04853239242226439, + "99.9" : 0.04853239242226439, + "99.99" : 0.04853239242226439, + "99.999" : 0.04853239242226439, + "99.9999" : 0.04853239242226439, + "100.0" : 0.04853239242226439 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04780514980997681, + 0.04758781751300317, + 0.04765763511935682 + ], + [ + 0.048491284037900165, + 0.04853239242226439, + 0.04836042689473073 + ], + [ + 0.046539819069869176, + 0.04656839601193997, + 0.04647786951045506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9210789.606424699, + "scoreError" : 67701.16141275437, + "scoreConfidence" : [ + 9143088.445011944, + 9278490.767837454 + ], + "scorePercentiles" : { + "0.0" : 9137590.056621004, + "50.0" : 9214177.742173113, + "90.0" : 9257430.554116558, + "95.0" : 9257430.554116558, + "99.0" : 9257430.554116558, + "99.9" : 9257430.554116558, + "99.99" : 9257430.554116558, + "99.999" : 9257430.554116558, + "99.9999" : 9257430.554116558, + "100.0" : 9257430.554116558 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9185812.64003673, + 9189725.07805326, + 9137590.056621004 + ], + [ + 9257430.554116558, + 9256689.355226642, + 9251173.079555966 + ], + [ + 9186617.759412305, + 9217890.192626728, + 9214177.742173113 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:20:01Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json b/performance-results/2025-04-03T04:20:01Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json new file mode 100644 index 0000000000..98ae378714 --- /dev/null +++ b/performance-results/2025-04-03T04:20:01Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3992092882886666, + "scoreError" : 0.028178246222827573, + "scoreConfidence" : [ + 3.371031042065839, + 3.427387534511494 + ], + "scorePercentiles" : { + "0.0" : 3.395005069255314, + "50.0" : 3.3986561825358588, + "90.0" : 3.4045197188276344, + "95.0" : 3.4045197188276344, + "99.0" : 3.4045197188276344, + "99.9" : 3.4045197188276344, + "99.99" : 3.4045197188276344, + "99.999" : 3.4045197188276344, + "99.9999" : 3.4045197188276344, + "100.0" : 3.4045197188276344 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.395005069255314, + 3.4045197188276344 + ], + [ + 3.396358694557847, + 3.4009536705138705 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7185863296289448, + "scoreError" : 0.0226247904680873, + "scoreConfidence" : [ + 1.6959615391608573, + 1.7412111200970322 + ], + "scorePercentiles" : { + "0.0" : 1.713896569825601, + "50.0" : 1.7191667413071396, + "90.0" : 1.7221152660758985, + "95.0" : 1.7221152660758985, + "99.0" : 1.7221152660758985, + "99.9" : 1.7221152660758985, + "99.99" : 1.7221152660758985, + "99.999" : 1.7221152660758985, + "99.9999" : 1.7221152660758985, + "100.0" : 1.7221152660758985 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.713896569825601, + 1.718257222681635 + ], + [ + 1.7200762599326442, + 1.7221152660758985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8638131333573812, + "scoreError" : 0.005739607080341613, + "scoreConfidence" : [ + 0.8580735262770396, + 0.8695527404377228 + ], + "scorePercentiles" : { + "0.0" : 0.8629604388633407, + "50.0" : 0.8637508804684315, + "90.0" : 0.8647903336293211, + "95.0" : 0.8647903336293211, + "99.0" : 0.8647903336293211, + "99.9" : 0.8647903336293211, + "99.99" : 0.8647903336293211, + "99.999" : 0.8647903336293211, + "99.9999" : 0.8647903336293211, + "100.0" : 0.8647903336293211 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8629604388633407, + 0.8647903336293211 + ], + [ + 0.8631690751649713, + 0.8643326857718918 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.875310471082843, + "scoreError" : 0.26777051507050426, + "scoreConfidence" : [ + 15.607539956012339, + 16.143080986153347 + ], + "scorePercentiles" : { + "0.0" : 15.612288653326042, + "50.0" : 15.832222806276663, + "90.0" : 16.106444002568377, + "95.0" : 16.106444002568377, + "99.0" : 16.106444002568377, + "99.9" : 16.106444002568377, + "99.99" : 16.106444002568377, + "99.999" : 16.106444002568377, + "99.9999" : 16.106444002568377, + "100.0" : 16.106444002568377 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.106444002568377, + 16.047190666002482, + 16.011487463515408 + ], + [ + 15.753348985453242, + 15.78377177928709, + 15.925255493182311 + ], + [ + 15.832222806276663, + 15.805784390133978, + 15.612288653326042 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2667.7601557240364, + "scoreError" : 119.67998425181611, + "scoreConfidence" : [ + 2548.08017147222, + 2787.4401399758526 + ], + "scorePercentiles" : { + "0.0" : 2558.413530316072, + "50.0" : 2697.246014837451, + "90.0" : 2745.2269193723982, + "95.0" : 2745.2269193723982, + "99.0" : 2745.2269193723982, + "99.9" : 2745.2269193723982, + "99.99" : 2745.2269193723982, + "99.999" : 2745.2269193723982, + "99.9999" : 2745.2269193723982, + "100.0" : 2745.2269193723982 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2601.2023290761535, + 2568.775645722441, + 2558.413530316072 + ], + [ + 2692.6922111857752, + 2708.3682091572205, + 2745.2269193723982 + ], + [ + 2721.1608852061686, + 2716.755656642648, + 2697.246014837451 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69653.26025364155, + "scoreError" : 837.2247301229313, + "scoreConfidence" : [ + 68816.03552351861, + 70490.48498376449 + ], + "scorePercentiles" : { + "0.0" : 69143.04281828675, + "50.0" : 69490.61975836863, + "90.0" : 70297.39157492763, + "95.0" : 70297.39157492763, + "99.0" : 70297.39157492763, + "99.9" : 70297.39157492763, + "99.99" : 70297.39157492763, + "99.999" : 70297.39157492763, + "99.9999" : 70297.39157492763, + "100.0" : 70297.39157492763 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69673.21206564475, + 69226.62057270289, + 69143.04281828675 + ], + [ + 69360.11899118814, + 69148.32384924784, + 69490.61975836863 + ], + [ + 70265.82211287168, + 70274.19053953572, + 70297.39157492763 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 325.76357997471234, + "scoreError" : 15.438554362778062, + "scoreConfidence" : [ + 310.3250256119343, + 341.2021343374904 + ], + "scorePercentiles" : { + "0.0" : 312.51355700005786, + "50.0" : 329.8447893587314, + "90.0" : 335.30161127464805, + "95.0" : 335.30161127464805, + "99.0" : 335.30161127464805, + "99.9" : 335.30161127464805, + "99.99" : 335.30161127464805, + "99.999" : 335.30161127464805, + "99.9999" : 335.30161127464805, + "100.0" : 335.30161127464805 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 335.30161127464805, + 333.0629081494773, + 330.14557873677194 + ], + [ + 329.8447893587314, + 333.10079335684634, + 328.95696746140584 + ], + [ + 313.93428796549847, + 312.51355700005786, + 315.0117264689737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 103.49485554121512, + "scoreError" : 3.793394744918793, + "scoreConfidence" : [ + 99.70146079629632, + 107.28825028613392 + ], + "scorePercentiles" : { + "0.0" : 100.45672061279393, + "50.0" : 102.92956348814475, + "90.0" : 106.59142705404575, + "95.0" : 106.59142705404575, + "99.0" : 106.59142705404575, + "99.9" : 106.59142705404575, + "99.99" : 106.59142705404575, + "99.999" : 106.59142705404575, + "99.9999" : 106.59142705404575, + "100.0" : 106.59142705404575 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.59142705404575, + 106.51678823289815, + 105.1312372742135 + ], + [ + 102.92956348814475, + 100.45672061279393, + 100.84404127845603 + ], + [ + 102.08705881148529, + 104.08286168477012, + 102.81400143412843 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0631853564618406, + "scoreError" : 0.0015354385052261798, + "scoreConfidence" : [ + 0.061649917956614425, + 0.06472079496706679 + ], + "scorePercentiles" : { + "0.0" : 0.0622281343053248, + "50.0" : 0.06272677993903052, + "90.0" : 0.0644954543314501, + "95.0" : 0.0644954543314501, + "99.0" : 0.0644954543314501, + "99.9" : 0.0644954543314501, + "99.99" : 0.0644954543314501, + "99.999" : 0.0644954543314501, + "99.9999" : 0.0644954543314501, + "100.0" : 0.0644954543314501 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06427183367932593, + 0.0644954543314501, + 0.06438153322045247 + ], + [ + 0.06272677993903052, + 0.06272599818724675, + 0.0627533352870303 + ], + [ + 0.06256258656673465, + 0.0622281343053248, + 0.06252255263996999 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8448266611457985E-4, + "scoreError" : 4.210014110702952E-6, + "scoreConfidence" : [ + 3.802726520038769E-4, + 3.886926802252828E-4 + ], + "scorePercentiles" : { + "0.0" : 3.813840175864892E-4, + "50.0" : 3.838468919576846E-4, + "90.0" : 3.8902695347126055E-4, + "95.0" : 3.8902695347126055E-4, + "99.0" : 3.8902695347126055E-4, + "99.9" : 3.8902695347126055E-4, + "99.99" : 3.8902695347126055E-4, + "99.999" : 3.8902695347126055E-4, + "99.9999" : 3.8902695347126055E-4, + "100.0" : 3.8902695347126055E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8159715463319407E-4, + 3.830467416295346E-4, + 3.813840175864892E-4 + ], + [ + 3.8554534892830454E-4, + 3.833462317780834E-4, + 3.838468919576846E-4 + ], + [ + 3.866754638332235E-4, + 3.8587519121344437E-4, + 3.8902695347126055E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014356945249008832, + "scoreError" : 4.749203126173207E-4, + "scoreConfidence" : [ + 0.013882024936391511, + 0.014831865561626153 + ], + "scorePercentiles" : { + "0.0" : 0.014186610823678286, + "50.0" : 0.014250738606324111, + "90.0" : 0.015081788841130516, + "95.0" : 0.015081788841130516, + "99.0" : 0.015081788841130516, + "99.9" : 0.015081788841130516, + "99.99" : 0.015081788841130516, + "99.999" : 0.015081788841130516, + "99.9999" : 0.015081788841130516, + "100.0" : 0.015081788841130516 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014211193623522056, + 0.014198740368054954, + 0.014186610823678286 + ], + [ + 0.014194806765726226, + 0.014383023576350585, + 0.014250738606324111 + ], + [ + 0.014355401821679275, + 0.014350202814613489, + 0.015081788841130516 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9889173184430794, + "scoreError" : 0.020906436622996124, + "scoreConfidence" : [ + 0.9680108818200833, + 1.0098237550660756 + ], + "scorePercentiles" : { + "0.0" : 0.9751137195787831, + "50.0" : 0.9838115681259223, + "90.0" : 1.0076507319899244, + "95.0" : 1.0076507319899244, + "99.0" : 1.0076507319899244, + "99.9" : 1.0076507319899244, + "99.99" : 1.0076507319899244, + "99.999" : 1.0076507319899244, + "99.9999" : 1.0076507319899244, + "100.0" : 1.0076507319899244 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0076507319899244, + 1.006104635915493, + 1.0008279665732587 + ], + [ + 0.9845124068714314, + 0.9838115681259223, + 0.9837508866810939 + ], + [ + 0.9790087858051885, + 0.9751137195787831, + 0.979475164446621 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013070564786537432, + "scoreError" : 3.312438477869377E-4, + "scoreConfidence" : [ + 0.012739320938750494, + 0.01340180863432437 + ], + "scorePercentiles" : { + "0.0" : 0.01294236621136469, + "50.0" : 0.013038706144191437, + "90.0" : 0.0132176846025943, + "95.0" : 0.0132176846025943, + "99.0" : 0.0132176846025943, + "99.9" : 0.0132176846025943, + "99.99" : 0.0132176846025943, + "99.999" : 0.0132176846025943, + "99.9999" : 0.0132176846025943, + "100.0" : 0.0132176846025943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01294236621136469, + 0.013041755751930787, + 0.013035656536452087 + ], + [ + 0.012973304387985968, + 0.013212621228896751, + 0.0132176846025943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.9320503683012595, + "scoreError" : 0.13073817145027877, + "scoreConfidence" : [ + 3.8013121968509807, + 4.062788539751538 + ], + "scorePercentiles" : { + "0.0" : 3.886556063714064, + "50.0" : 3.9285158029082803, + "90.0" : 3.9836880589171972, + "95.0" : 3.9836880589171972, + "99.0" : 3.9836880589171972, + "99.9" : 3.9836880589171972, + "99.99" : 3.9836880589171972, + "99.999" : 3.9836880589171972, + "99.9999" : 3.9836880589171972, + "100.0" : 3.9836880589171972 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9627668122028528, + 3.975874643879173, + 3.9836880589171972 + ], + [ + 3.886556063714064, + 3.8942647936137074, + 3.88915183748056 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.004364586156701, + "scoreError" : 0.14161123897060376, + "scoreConfidence" : [ + 2.8627533471860973, + 3.145975825127305 + ], + "scorePercentiles" : { + "0.0" : 2.899472187880545, + "50.0" : 2.9752824544913743, + "90.0" : 3.116214405919003, + "95.0" : 3.116214405919003, + "99.0" : 3.116214405919003, + "99.9" : 3.116214405919003, + "99.99" : 3.116214405919003, + "99.999" : 3.116214405919003, + "99.9999" : 3.116214405919003, + "100.0" : 3.116214405919003 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1080275556246115, + 3.116214405919003, + 3.1107170768273718 + ], + [ + 2.94470944581861, + 2.9752824544913743, + 2.982728600954369 + ], + [ + 2.969614950415677, + 2.9325145974787454, + 2.899472187880545 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17564792482371683, + "scoreError" : 0.002974252867516921, + "scoreConfidence" : [ + 0.1726736719561999, + 0.17862217769123376 + ], + "scorePercentiles" : { + "0.0" : 0.1731033127055565, + "50.0" : 0.1768566043965761, + "90.0" : 0.17698233668412855, + "95.0" : 0.17698233668412855, + "99.0" : 0.17698233668412855, + "99.9" : 0.17698233668412855, + "99.99" : 0.17698233668412855, + "99.999" : 0.17698233668412855, + "99.9999" : 0.17698233668412855, + "100.0" : 0.17698233668412855 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17686704975150774, + 0.1768795816898668, + 0.1769473231708396 + ], + [ + 0.1768566043965761, + 0.1763903096094825, + 0.17698233668412855 + ], + [ + 0.17349474921929217, + 0.17331005618620127, + 0.1731033127055565 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3224626777755301, + "scoreError" : 0.016155882614857214, + "scoreConfidence" : [ + 0.3063067951606729, + 0.33861856039038735 + ], + "scorePercentiles" : { + "0.0" : 0.3106331735470444, + "50.0" : 0.32324063284633786, + "90.0" : 0.333969142098584, + "95.0" : 0.333969142098584, + "99.0" : 0.333969142098584, + "99.9" : 0.333969142098584, + "99.99" : 0.333969142098584, + "99.999" : 0.333969142098584, + "99.9999" : 0.333969142098584, + "100.0" : 0.333969142098584 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32324063284633786, + 0.3228341037221164, + 0.32352256436220117 + ], + [ + 0.333969142098584, + 0.3330036538909793, + 0.3325125170074813 + ], + [ + 0.31173687711587017, + 0.31071143538915647, + 0.3106331735470444 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16336138611669254, + "scoreError" : 0.013309637759159056, + "scoreConfidence" : [ + 0.1500517483575335, + 0.1766710238758516 + ], + "scorePercentiles" : { + "0.0" : 0.15236389503915654, + "50.0" : 0.16749676753651346, + "90.0" : 0.17041830118777798, + "95.0" : 0.17041830118777798, + "99.0" : 0.17041830118777798, + "99.9" : 0.17041830118777798, + "99.99" : 0.17041830118777798, + "99.999" : 0.17041830118777798, + "99.9999" : 0.17041830118777798, + "100.0" : 0.17041830118777798 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16764070001508727, + 0.1672745904688624, + 0.16749676753651346 + ], + [ + 0.15236389503915654, + 0.15341220566081154, + 0.15290987807153014 + ], + [ + 0.17041830118777798, + 0.16932816888482508, + 0.1694079681856683 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3916901877748583, + "scoreError" : 0.013066770761379609, + "scoreConfidence" : [ + 0.3786234170134787, + 0.40475695853623794 + ], + "scorePercentiles" : { + "0.0" : 0.3831963658274897, + "50.0" : 0.3880605029491657, + "90.0" : 0.40703388969840043, + "95.0" : 0.40703388969840043, + "99.0" : 0.40703388969840043, + "99.9" : 0.40703388969840043, + "99.99" : 0.40703388969840043, + "99.999" : 0.40703388969840043, + "99.9999" : 0.40703388969840043, + "100.0" : 0.40703388969840043 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40703388969840043, + 0.3974855021264756, + 0.3967198541336084 + ], + [ + 0.3880605029491657, + 0.3875346873086611, + 0.3875294380546406 + ], + [ + 0.39397768474963557, + 0.38367376512564744, + 0.3831963658274897 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15989002361063018, + "scoreError" : 0.004543996585626853, + "scoreConfidence" : [ + 0.15534602702500333, + 0.16443402019625702 + ], + "scorePercentiles" : { + "0.0" : 0.15594041546594312, + "50.0" : 0.1613597867688584, + "90.0" : 0.1622719936715023, + "95.0" : 0.1622719936715023, + "99.0" : 0.1622719936715023, + "99.9" : 0.1622719936715023, + "99.99" : 0.1622719936715023, + "99.999" : 0.1622719936715023, + "99.9999" : 0.1622719936715023, + "100.0" : 0.1622719936715023 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15676905651356013, + 0.15594041546594312, + 0.15631288311241714 + ], + [ + 0.16217939525153255, + 0.1622719936715023, + 0.16147748038883236 + ], + [ + 0.1618514822211792, + 0.1613597867688584, + 0.1608477191018465 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04783453527496373, + "scoreError" : 7.974832162056922E-4, + "scoreConfidence" : [ + 0.047037052058758036, + 0.048632018491169424 + ], + "scorePercentiles" : { + "0.0" : 0.04737623978226162, + "50.0" : 0.04774475477679637, + "90.0" : 0.04894417089131105, + "95.0" : 0.04894417089131105, + "99.0" : 0.04894417089131105, + "99.9" : 0.04894417089131105, + "99.99" : 0.04894417089131105, + "99.999" : 0.04894417089131105, + "99.9999" : 0.04894417089131105, + "100.0" : 0.04894417089131105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04749892322380233, + 0.047416286812295816, + 0.04737623978226162 + ], + [ + 0.04774475477679637, + 0.047800833626508096, + 0.04774200215790931 + ], + [ + 0.04894417089131105, + 0.04804041357891248, + 0.04794719262487654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9631059.90526732, + "scoreError" : 171531.34109600133, + "scoreConfidence" : [ + 9459528.56417132, + 9802591.246363321 + ], + "scorePercentiles" : { + "0.0" : 9512877.128326995, + "50.0" : 9688628.696030978, + "90.0" : 9758324.88195122, + "95.0" : 9758324.88195122, + "99.0" : 9758324.88195122, + "99.9" : 9758324.88195122, + "99.99" : 9758324.88195122, + "99.999" : 9758324.88195122, + "99.9999" : 9758324.88195122, + "100.0" : 9758324.88195122 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9758324.88195122, + 9737305.494644595, + 9534123.904671116 + ], + [ + 9694253.833333334, + 9696302.620155038, + 9688628.696030978 + ], + [ + 9534044.147759771, + 9523678.440532826, + 9512877.128326995 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:20:12Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json b/performance-results/2025-04-03T04:20:12Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json new file mode 100644 index 0000000000..7d0bb435fc --- /dev/null +++ b/performance-results/2025-04-03T04:20:12Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4141460140654183, + "scoreError" : 0.02523433949722112, + "scoreConfidence" : [ + 3.388911674568197, + 3.4393803535626395 + ], + "scorePercentiles" : { + "0.0" : 3.4109114729011334, + "50.0" : 3.412942036862178, + "90.0" : 3.419788509636182, + "95.0" : 3.419788509636182, + "99.0" : 3.419788509636182, + "99.9" : 3.419788509636182, + "99.99" : 3.419788509636182, + "99.999" : 3.419788509636182, + "99.9999" : 3.419788509636182, + "100.0" : 3.419788509636182 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4109114729011334, + 3.413465927756727 + ], + [ + 3.412418145967629, + 3.419788509636182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7201150901156992, + "scoreError" : 0.028373580112449958, + "scoreConfidence" : [ + 1.6917415100032491, + 1.7484886702281492 + ], + "scorePercentiles" : { + "0.0" : 1.715451119237048, + "50.0" : 1.7205134919863199, + "90.0" : 1.7239822572531092, + "95.0" : 1.7239822572531092, + "99.0" : 1.7239822572531092, + "99.9" : 1.7239822572531092, + "99.99" : 1.7239822572531092, + "99.999" : 1.7239822572531092, + "99.9999" : 1.7239822572531092, + "100.0" : 1.7239822572531092 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7239822572531092, + 1.7237394376447464 + ], + [ + 1.715451119237048, + 1.7172875463278934 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8659551304749118, + "scoreError" : 0.010436027041818195, + "scoreConfidence" : [ + 0.8555191034330936, + 0.87639115751673 + ], + "scorePercentiles" : { + "0.0" : 0.8639684361227421, + "50.0" : 0.8662045209892448, + "90.0" : 0.8674430437984155, + "95.0" : 0.8674430437984155, + "99.0" : 0.8674430437984155, + "99.9" : 0.8674430437984155, + "99.99" : 0.8674430437984155, + "99.999" : 0.8674430437984155, + "99.9999" : 0.8674430437984155, + "100.0" : 0.8674430437984155 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8639684361227421, + 0.8653272198110116 + ], + [ + 0.8674430437984155, + 0.867081822167478 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.252654676449723, + "scoreError" : 0.10537930227104682, + "scoreConfidence" : [ + 16.147275374178676, + 16.35803397872077 + ], + "scorePercentiles" : { + "0.0" : 16.168129744860877, + "50.0" : 16.268725836178465, + "90.0" : 16.355642468960376, + "95.0" : 16.355642468960376, + "99.0" : 16.355642468960376, + "99.9" : 16.355642468960376, + "99.99" : 16.355642468960376, + "99.999" : 16.355642468960376, + "99.9999" : 16.355642468960376, + "100.0" : 16.355642468960376 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.355642468960376, + 16.272526956761183, + 16.268725836178465 + ], + [ + 16.168129744860877, + 16.274173548129912, + 16.318351985527347 + ], + [ + 16.17852783509764, + 16.23478021354547, + 16.203033498986223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2711.90349954842, + "scoreError" : 92.62280441102727, + "scoreConfidence" : [ + 2619.2806951373927, + 2804.526303959447 + ], + "scorePercentiles" : { + "0.0" : 2649.300552891204, + "50.0" : 2690.6946489145466, + "90.0" : 2797.8890502273834, + "95.0" : 2797.8890502273834, + "99.0" : 2797.8890502273834, + "99.9" : 2797.8890502273834, + "99.99" : 2797.8890502273834, + "99.999" : 2797.8890502273834, + "99.9999" : 2797.8890502273834, + "100.0" : 2797.8890502273834 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2666.717149029226, + 2649.300552891204, + 2669.5037781743854 + ], + [ + 2680.457249875851, + 2705.622885659174, + 2690.6946489145466 + ], + [ + 2797.8890502273834, + 2766.6792631764147, + 2780.266917987591 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69111.95639690965, + "scoreError" : 83.29528789521649, + "scoreConfidence" : [ + 69028.66110901443, + 69195.25168480487 + ], + "scorePercentiles" : { + "0.0" : 69046.25547453541, + "50.0" : 69118.4881065913, + "90.0" : 69182.46390916892, + "95.0" : 69182.46390916892, + "99.0" : 69182.46390916892, + "99.9" : 69182.46390916892, + "99.99" : 69182.46390916892, + "99.999" : 69182.46390916892, + "99.9999" : 69182.46390916892, + "100.0" : 69182.46390916892 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69162.28535818945, + 69182.46390916892, + 69118.4881065913 + ], + [ + 69136.79708672072, + 69054.3599191844, + 69046.25547453541 + ], + [ + 69060.3327196236, + 69101.69400475129, + 69144.93099342177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.3278857421012, + "scoreError" : 11.852637802821008, + "scoreConfidence" : [ + 335.4752479392802, + 359.1805235449222 + ], + "scorePercentiles" : { + "0.0" : 337.69633644382174, + "50.0" : 349.8230392811812, + "90.0" : 354.5053703216764, + "95.0" : 354.5053703216764, + "99.0" : 354.5053703216764, + "99.9" : 354.5053703216764, + "99.99" : 354.5053703216764, + "99.999" : 354.5053703216764, + "99.9999" : 354.5053703216764, + "100.0" : 354.5053703216764 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.8230392811812, + 349.75558705623996, + 350.2228570416806 + ], + [ + 353.86196935718107, + 354.5053703216764, + 353.13588747335746 + ], + [ + 338.3428057877555, + 338.60711891601716, + 337.69633644382174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.73978567279248, + "scoreError" : 2.23951667478191, + "scoreConfidence" : [ + 105.50026899801057, + 109.97930234757439 + ], + "scorePercentiles" : { + "0.0" : 105.94123260786559, + "50.0" : 108.09616081351409, + "90.0" : 109.21003352792893, + "95.0" : 109.21003352792893, + "99.0" : 109.21003352792893, + "99.9" : 109.21003352792893, + "99.99" : 109.21003352792893, + "99.999" : 109.21003352792893, + "99.9999" : 109.21003352792893, + "100.0" : 109.21003352792893 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.97381347858634, + 105.94123260786559, + 106.4660416765197 + ], + [ + 109.21003352792893, + 109.12797422747417, + 109.0807392320912 + ], + [ + 107.58179783757122, + 108.09616081351409, + 108.18027765358097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061909221750764645, + "scoreError" : 7.93118736000689E-4, + "scoreConfidence" : [ + 0.06111610301476396, + 0.06270234048676533 + ], + "scorePercentiles" : { + "0.0" : 0.06120587202007528, + "50.0" : 0.06209829328042624, + "90.0" : 0.06241124775010922, + "95.0" : 0.06241124775010922, + "99.0" : 0.06241124775010922, + "99.9" : 0.06241124775010922, + "99.99" : 0.06241124775010922, + "99.999" : 0.06241124775010922, + "99.9999" : 0.06241124775010922, + "100.0" : 0.06241124775010922 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06120587202007528, + 0.06131094404831244, + 0.061437342034772996 + ], + [ + 0.06209829328042624, + 0.06231152692741468, + 0.0619119299166677 + ], + [ + 0.06241124775010922, + 0.06213026141468112, + 0.06236557836442216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7692210394697193E-4, + "scoreError" : 1.9364149312350478E-5, + "scoreConfidence" : [ + 3.5755795463462145E-4, + 3.962862532593224E-4 + ], + "scorePercentiles" : { + "0.0" : 3.610834907005055E-4, + "50.0" : 3.804653194718181E-4, + "90.0" : 3.906616198985073E-4, + "95.0" : 3.906616198985073E-4, + "99.0" : 3.906616198985073E-4, + "99.9" : 3.906616198985073E-4, + "99.99" : 3.906616198985073E-4, + "99.999" : 3.906616198985073E-4, + "99.9999" : 3.906616198985073E-4, + "100.0" : 3.906616198985073E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8721810412907065E-4, + 3.906616198985073E-4, + 3.866140347051792E-4 + ], + [ + 3.6320046181129455E-4, + 3.610834907005055E-4, + 3.628257406006513E-4 + ], + [ + 3.789365386107795E-4, + 3.804653194718181E-4, + 3.8129362559494065E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014347172959238966, + "scoreError" : 5.008339226000911E-4, + "scoreConfidence" : [ + 0.013846339036638875, + 0.014848006881839057 + ], + "scorePercentiles" : { + "0.0" : 0.014093595788880276, + "50.0" : 0.014189940964876059, + "90.0" : 0.01476075187496033, + "95.0" : 0.01476075187496033, + "99.0" : 0.01476075187496033, + "99.9" : 0.01476075187496033, + "99.99" : 0.01476075187496033, + "99.999" : 0.01476075187496033, + "99.9999" : 0.01476075187496033, + "100.0" : 0.01476075187496033 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014122154853159652, + 0.014099223867423879, + 0.014093595788880276 + ], + [ + 0.01418198724770538, + 0.014189940964876059, + 0.014215869308036984 + ], + [ + 0.014730909794904051, + 0.01476075187496033, + 0.014730122933204103 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9851786290563604, + "scoreError" : 0.007389816834762871, + "scoreConfidence" : [ + 0.9777888122215975, + 0.9925684458911234 + ], + "scorePercentiles" : { + "0.0" : 0.9780690916381418, + "50.0" : 0.986488261195502, + "90.0" : 0.9905183169572108, + "95.0" : 0.9905183169572108, + "99.0" : 0.9905183169572108, + "99.9" : 0.9905183169572108, + "99.99" : 0.9905183169572108, + "99.999" : 0.9905183169572108, + "99.9999" : 0.9905183169572108, + "100.0" : 0.9905183169572108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9838497288735858, + 0.986488261195502, + 0.9877146994567901 + ], + [ + 0.9813227989402414, + 0.9807172931254291, + 0.9780690916381418 + ], + [ + 0.9900390989010989, + 0.9905183169572108, + 0.9878883724192433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013110931908467226, + "scoreError" : 3.1593701265900207E-4, + "scoreConfidence" : [ + 0.012794994895808223, + 0.013426868921126229 + ], + "scorePercentiles" : { + "0.0" : 0.012994717709554265, + "50.0" : 0.013109973759007349, + "90.0" : 0.013229475688776117, + "95.0" : 0.013229475688776117, + "99.0" : 0.013229475688776117, + "99.9" : 0.013229475688776117, + "99.99" : 0.013229475688776117, + "99.999" : 0.013229475688776117, + "99.9999" : 0.013229475688776117, + "100.0" : 0.013229475688776117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01302357288717445, + 0.013008309857432749, + 0.012994717709554265 + ], + [ + 0.013229475688776117, + 0.013213140677025528, + 0.013196374630840247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.7185666837587, + "scoreError" : 0.059501212486211645, + "scoreConfidence" : [ + 3.659065471272488, + 3.7780678962449117 + ], + "scorePercentiles" : { + "0.0" : 3.6901369336283185, + "50.0" : 3.71791115056773, + "90.0" : 3.748282396551724, + "95.0" : 3.748282396551724, + "99.0" : 3.748282396551724, + "99.9" : 3.748282396551724, + "99.99" : 3.748282396551724, + "99.999" : 3.748282396551724, + "99.9999" : 3.748282396551724, + "100.0" : 3.748282396551724 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7134024246473647, + 3.702479917838638, + 3.6901369336283185 + ], + [ + 3.734678553398058, + 3.748282396551724, + 3.7224198764880954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.808103327650971, + "scoreError" : 0.038645407159203296, + "scoreConfidence" : [ + 2.7694579204917673, + 2.8467487348101743 + ], + "scorePercentiles" : { + "0.0" : 2.776432284564131, + "50.0" : 2.8192024323562572, + "90.0" : 2.8317730673839185, + "95.0" : 2.8317730673839185, + "99.0" : 2.8317730673839185, + "99.9" : 2.8317730673839185, + "99.99" : 2.8317730673839185, + "99.999" : 2.8317730673839185, + "99.9999" : 2.8317730673839185, + "100.0" : 2.8317730673839185 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8192024323562572, + 2.812318770528684, + 2.825893922576999 + ], + [ + 2.8219859692437925, + 2.8317730673839185, + 2.826690167326173 + ], + [ + 2.782025319054242, + 2.776432284564131, + 2.776608015824542 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17652238855933255, + "scoreError" : 0.003125705040678961, + "scoreConfidence" : [ + 0.1733966835186536, + 0.17964809360001152 + ], + "scorePercentiles" : { + "0.0" : 0.17452421106457242, + "50.0" : 0.17574864547196006, + "90.0" : 0.17961467400675335, + "95.0" : 0.17961467400675335, + "99.0" : 0.17961467400675335, + "99.9" : 0.17961467400675335, + "99.99" : 0.17961467400675335, + "99.999" : 0.17961467400675335, + "99.9999" : 0.17961467400675335, + "100.0" : 0.17961467400675335 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17961467400675335, + 0.17849365485667368, + 0.17829464331051206 + ], + [ + 0.17667822780516246, + 0.175622275771838, + 0.17574864547196006 + ], + [ + 0.175139794949035, + 0.17452421106457242, + 0.17458536979748604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33159081262614715, + "scoreError" : 0.012872917742416154, + "scoreConfidence" : [ + 0.318717894883731, + 0.3444637303685633 + ], + "scorePercentiles" : { + "0.0" : 0.32417070874258486, + "50.0" : 0.327614753407155, + "90.0" : 0.34253819167665694, + "95.0" : 0.34253819167665694, + "99.0" : 0.34253819167665694, + "99.9" : 0.34253819167665694, + "99.99" : 0.34253819167665694, + "99.999" : 0.34253819167665694, + "99.9999" : 0.34253819167665694, + "100.0" : 0.34253819167665694 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.327614753407155, + 0.32804313826472037, + 0.3272351357657068 + ], + [ + 0.32650751772887554, + 0.32417070874258486, + 0.3257033246482543 + ], + [ + 0.34253819167665694, + 0.3412840927923009, + 0.3412204506090695 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16257438283358802, + "scoreError" : 0.0015079171733187204, + "scoreConfidence" : [ + 0.1610664656602693, + 0.16408230000690674 + ], + "scorePercentiles" : { + "0.0" : 0.16145170934306333, + "50.0" : 0.16253732088872996, + "90.0" : 0.16372694721590073, + "95.0" : 0.16372694721590073, + "99.0" : 0.16372694721590073, + "99.9" : 0.16372694721590073, + "99.99" : 0.16372694721590073, + "99.999" : 0.16372694721590073, + "99.9999" : 0.16372694721590073, + "100.0" : 0.16372694721590073 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16217501864975756, + 0.16253732088872996, + 0.16269733150573498 + ], + [ + 0.16175499032722448, + 0.1616261715800362, + 0.16145170934306333 + ], + [ + 0.16363694076449797, + 0.16372694721590073, + 0.16356301522734706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3891936853118775, + "scoreError" : 0.005998609157386771, + "scoreConfidence" : [ + 0.3831950761544907, + 0.39519229446926424 + ], + "scorePercentiles" : { + "0.0" : 0.3858164131558642, + "50.0" : 0.38843062722858807, + "90.0" : 0.39801564624875624, + "95.0" : 0.39801564624875624, + "99.0" : 0.39801564624875624, + "99.9" : 0.39801564624875624, + "99.99" : 0.39801564624875624, + "99.999" : 0.39801564624875624, + "99.9999" : 0.39801564624875624, + "100.0" : 0.39801564624875624 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39801564624875624, + 0.3878194711859148, + 0.38843062722858807 + ], + [ + 0.3893662909593521, + 0.38925788793741, + 0.3895342826705099 + ], + [ + 0.3883784769505612, + 0.38612407146994093, + 0.3858164131558642 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15658902672809438, + "scoreError" : 0.003943926804707067, + "scoreConfidence" : [ + 0.15264509992338732, + 0.16053295353280145 + ], + "scorePercentiles" : { + "0.0" : 0.15414155185967293, + "50.0" : 0.15551880479611832, + "90.0" : 0.16021518488256592, + "95.0" : 0.16021518488256592, + "99.0" : 0.16021518488256592, + "99.9" : 0.16021518488256592, + "99.99" : 0.16021518488256592, + "99.999" : 0.16021518488256592, + "99.9999" : 0.16021518488256592, + "100.0" : 0.16021518488256592 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1564305789794769, + 0.15551880479611832, + 0.15540823026356684 + ], + [ + 0.15484570807655385, + 0.1542891126745352, + 0.15414155185967293 + ], + [ + 0.16021518488256592, + 0.15947678614486652, + 0.1589752828754928 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04743935270487015, + "scoreError" : 0.0014339295540742704, + "scoreConfidence" : [ + 0.04600542315079588, + 0.048873282258944425 + ], + "scorePercentiles" : { + "0.0" : 0.04618683700436459, + "50.0" : 0.0473992635310958, + "90.0" : 0.04867919720586088, + "95.0" : 0.04867919720586088, + "99.0" : 0.04867919720586088, + "99.9" : 0.04867919720586088, + "99.99" : 0.04867919720586088, + "99.999" : 0.04867919720586088, + "99.9999" : 0.04867919720586088, + "100.0" : 0.04867919720586088 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0473992635310958, + 0.04618683700436459, + 0.04625727953835835 + ], + [ + 0.047923044246684976, + 0.04867919720586088, + 0.04845878558760249 + ], + [ + 0.04747248577504973, + 0.047303504564719684, + 0.047273776890094876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9071703.616870854, + "scoreError" : 160321.0639152296, + "scoreConfidence" : [ + 8911382.552955624, + 9232024.680786084 + ], + "scorePercentiles" : { + "0.0" : 8985842.091644205, + "50.0" : 9013161.59009009, + "90.0" : 9212517.708103132, + "95.0" : 9212517.708103132, + "99.0" : 9212517.708103132, + "99.9" : 9212517.708103132, + "99.99" : 9212517.708103132, + "99.999" : 9212517.708103132, + "99.9999" : 9212517.708103132, + "100.0" : 9212517.708103132 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9172326.609532539, + 9212517.708103132, + 9203796.53449862 + ], + [ + 9047417.420433996, + 9013161.59009009, + 9006460.631863186 + ], + [ + 9005402.827182718, + 8985842.091644205, + 8998407.13848921 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:20:22Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json b/performance-results/2025-04-03T04:20:22Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json new file mode 100644 index 0000000000..69a93bc83d --- /dev/null +++ b/performance-results/2025-04-03T04:20:22Z-bfd7b46570071ef5cb5edd7377fbc51fb477ee3d-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4171100486983814, + "scoreError" : 0.029050359197470347, + "scoreConfidence" : [ + 3.388059689500911, + 3.4461604078958517 + ], + "scorePercentiles" : { + "0.0" : 3.4120508869424384, + "50.0" : 3.417248324070669, + "90.0" : 3.4218926597097488, + "95.0" : 3.4218926597097488, + "99.0" : 3.4218926597097488, + "99.9" : 3.4218926597097488, + "99.99" : 3.4218926597097488, + "99.999" : 3.4218926597097488, + "99.9999" : 3.4218926597097488, + "100.0" : 3.4218926597097488 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4120508869424384, + 3.4147862249287275 + ], + [ + 3.4197104232126105, + 3.4218926597097488 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7291216308035666, + "scoreError" : 0.010634177230505332, + "scoreConfidence" : [ + 1.7184874535730612, + 1.739755808034072 + ], + "scorePercentiles" : { + "0.0" : 1.7278385132821346, + "50.0" : 1.7286578762881986, + "90.0" : 1.7313322573557348, + "95.0" : 1.7313322573557348, + "99.0" : 1.7313322573557348, + "99.9" : 1.7313322573557348, + "99.99" : 1.7313322573557348, + "99.999" : 1.7313322573557348, + "99.9999" : 1.7313322573557348, + "100.0" : 1.7313322573557348 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7278385132821346, + 1.7278959373704097 + ], + [ + 1.7313322573557348, + 1.7294198152059874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8672043251385466, + "scoreError" : 0.006581078982478564, + "scoreConfidence" : [ + 0.860623246156068, + 0.8737854041210252 + ], + "scorePercentiles" : { + "0.0" : 0.8660632068022843, + "50.0" : 0.8671657259458264, + "90.0" : 0.8684226418602491, + "95.0" : 0.8684226418602491, + "99.0" : 0.8684226418602491, + "99.9" : 0.8684226418602491, + "99.99" : 0.8684226418602491, + "99.999" : 0.8684226418602491, + "99.9999" : 0.8684226418602491, + "100.0" : 0.8684226418602491 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8667643732520639, + 0.8675670786395889 + ], + [ + 0.8660632068022843, + 0.8684226418602491 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.162001317325213, + "scoreError" : 0.12285363357149377, + "scoreConfidence" : [ + 16.03914768375372, + 16.284854950896708 + ], + "scorePercentiles" : { + "0.0" : 16.08098225063554, + "50.0" : 16.158180279448743, + "90.0" : 16.264393757728516, + "95.0" : 16.264393757728516, + "99.0" : 16.264393757728516, + "99.9" : 16.264393757728516, + "99.99" : 16.264393757728516, + "99.999" : 16.264393757728516, + "99.9999" : 16.264393757728516, + "100.0" : 16.264393757728516 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.2498132766456, + 16.232697591247195, + 16.264393757728516 + ], + [ + 16.167029538529444, + 16.158180279448743, + 16.13834542567008 + ], + [ + 16.08543601225834, + 16.08098225063554, + 16.08113372376346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2713.372153938922, + "scoreError" : 38.77531189294057, + "scoreConfidence" : [ + 2674.5968420459817, + 2752.1474658318625 + ], + "scorePercentiles" : { + "0.0" : 2691.019153774729, + "50.0" : 2702.636105906266, + "90.0" : 2748.609138326982, + "95.0" : 2748.609138326982, + "99.0" : 2748.609138326982, + "99.9" : 2748.609138326982, + "99.99" : 2748.609138326982, + "99.999" : 2748.609138326982, + "99.9999" : 2748.609138326982, + "100.0" : 2748.609138326982 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2740.4996046953506, + 2748.609138326982, + 2741.3544851741417 + ], + [ + 2695.644525570017, + 2695.7406319067013, + 2691.019153774729 + ], + [ + 2705.513011761636, + 2699.332728334476, + 2702.636105906266 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70136.62092217, + "scoreError" : 1833.6126634576278, + "scoreConfidence" : [ + 68303.00825871238, + 71970.23358562762 + ], + "scorePercentiles" : { + "0.0" : 68636.20359353884, + "50.0" : 70840.18396558113, + "90.0" : 70914.97550703726, + "95.0" : 70914.97550703726, + "99.0" : 70914.97550703726, + "99.9" : 70914.97550703726, + "99.99" : 70914.97550703726, + "99.999" : 70914.97550703726, + "99.9999" : 70914.97550703726, + "100.0" : 70914.97550703726 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70884.08944043725, + 70894.06686001566, + 70759.17612968457 + ], + [ + 70887.07004709519, + 70840.18396558113, + 70914.97550703726 + ], + [ + 68636.20359353884, + 68734.45468992933, + 68679.36806621081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.3760123281292, + "scoreError" : 8.909817000066589, + "scoreConfidence" : [ + 348.4661953280626, + 366.2858293281958 + ], + "scorePercentiles" : { + "0.0" : 351.1186240805577, + "50.0" : 357.0735177853829, + "90.0" : 363.5453188941034, + "95.0" : 363.5453188941034, + "99.0" : 363.5453188941034, + "99.9" : 363.5453188941034, + "99.99" : 363.5453188941034, + "99.999" : 363.5453188941034, + "99.9999" : 363.5453188941034, + "100.0" : 363.5453188941034 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.3800725684625, + 351.1186240805577, + 351.14898598830297 + ], + [ + 356.46301856590736, + 357.0735177853829, + 359.1732893240755 + ], + [ + 363.5453188941034, + 363.31735936112716, + 363.1639243852433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.21095768888088, + "scoreError" : 1.728555284357556, + "scoreConfidence" : [ + 106.48240240452333, + 109.93951297323844 + ], + "scorePercentiles" : { + "0.0" : 106.6361791958133, + "50.0" : 108.34945308402088, + "90.0" : 109.38279632848486, + "95.0" : 109.38279632848486, + "99.0" : 109.38279632848486, + "99.9" : 109.38279632848486, + "99.99" : 109.38279632848486, + "99.999" : 109.38279632848486, + "99.9999" : 109.38279632848486, + "100.0" : 109.38279632848486 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.21218065367852, + 108.34945308402088, + 108.46737250455398 + ], + [ + 106.6361791958133, + 107.10942310914471, + 107.19210526928929 + ], + [ + 109.1947139384956, + 109.35439511644663, + 109.38279632848486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06169959127089957, + "scoreError" : 0.0010302074088845569, + "scoreConfidence" : [ + 0.060669383862015015, + 0.06272979867978414 + ], + "scorePercentiles" : { + "0.0" : 0.06091269048924299, + "50.0" : 0.0620058904927547, + "90.0" : 0.0622928827164339, + "95.0" : 0.0622928827164339, + "99.0" : 0.0622928827164339, + "99.9" : 0.0622928827164339, + "99.99" : 0.0622928827164339, + "99.999" : 0.0622928827164339, + "99.9999" : 0.0622928827164339, + "100.0" : 0.0622928827164339 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06222775979141516, + 0.0622928827164339, + 0.0622715326828114 + ], + [ + 0.06091787278719283, + 0.06091326277029908, + 0.06091269048924299 + ], + [ + 0.0617303522657827, + 0.0620058904927547, + 0.06202407744216337 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6798945543601994E-4, + "scoreError" : 1.651439730618763E-5, + "scoreConfidence" : [ + 3.514750581298323E-4, + 3.845038527422076E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5445183380887837E-4, + "50.0" : 3.6962223546356776E-4, + "90.0" : 3.7913274260289705E-4, + "95.0" : 3.7913274260289705E-4, + "99.0" : 3.7913274260289705E-4, + "99.9" : 3.7913274260289705E-4, + "99.99" : 3.7913274260289705E-4, + "99.999" : 3.7913274260289705E-4, + "99.9999" : 3.7913274260289705E-4, + "100.0" : 3.7913274260289705E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7913274260289705E-4, + 3.772585944041239E-4, + 3.7845987324760806E-4 + ], + [ + 3.6962223546356776E-4, + 3.698791820859403E-4, + 3.695285413619942E-4 + ], + [ + 3.5902273255519643E-4, + 3.5445183380887837E-4, + 3.545493633939737E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014403353417093919, + "scoreError" : 5.362041725711555E-4, + "scoreConfidence" : [ + 0.013867149244522764, + 0.014939557589665075 + ], + "scorePercentiles" : { + "0.0" : 0.01398167059872964, + "50.0" : 0.014544293900340769, + "90.0" : 0.014684813553348615, + "95.0" : 0.014684813553348615, + "99.0" : 0.014684813553348615, + "99.9" : 0.014684813553348615, + "99.99" : 0.014684813553348615, + "99.999" : 0.014684813553348615, + "99.9999" : 0.014684813553348615, + "100.0" : 0.014684813553348615 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014683949145623569, + 0.014679144894583022, + 0.014684813553348615 + ], + [ + 0.014533443404507641, + 0.014544293900340769, + 0.014547071132853868 + ], + [ + 0.013982993723109276, + 0.01398167059872964, + 0.013992800400748885 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9704870782068402, + "scoreError" : 0.010541865346184598, + "scoreConfidence" : [ + 0.9599452128606556, + 0.9810289435530248 + ], + "scorePercentiles" : { + "0.0" : 0.9624246163025695, + "50.0" : 0.9728594578793774, + "90.0" : 0.9772800762239813, + "95.0" : 0.9772800762239813, + "99.0" : 0.9772800762239813, + "99.9" : 0.9772800762239813, + "99.99" : 0.9772800762239813, + "99.999" : 0.9772800762239813, + "99.9999" : 0.9772800762239813, + "100.0" : 0.9772800762239813 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9760755084911185, + 0.9772800762239813, + 0.9765354366761059 + ], + [ + 0.9710249972812894, + 0.9728594578793774, + 0.9729500664461523 + ], + [ + 0.9625655503368624, + 0.9624246163025695, + 0.9626679942241048 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013325571908170615, + "scoreError" : 4.7289741439673064E-4, + "scoreConfidence" : [ + 0.012852674493773884, + 0.013798469322567345 + ], + "scorePercentiles" : { + "0.0" : 0.013084378469896164, + "50.0" : 0.013347866633788563, + "90.0" : 0.013475767826630661, + "95.0" : 0.013475767826630661, + "99.0" : 0.013475767826630661, + "99.9" : 0.013475767826630661, + "99.99" : 0.013475767826630661, + "99.999" : 0.013475767826630661, + "99.9999" : 0.013475767826630661, + "100.0" : 0.013475767826630661 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013084378469896164, + 0.013225057919112142, + 0.013227907234958916 + ], + [ + 0.01347249396580759, + 0.01346782603261821, + 0.013475767826630661 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.51804067922278, + "scoreError" : 0.10090682815622272, + "scoreConfidence" : [ + 3.417133851066557, + 3.6189475073790027 + ], + "scorePercentiles" : { + "0.0" : 3.4634543123268697, + "50.0" : 3.5154336537433952, + "90.0" : 3.556867966571835, + "95.0" : 3.556867966571835, + "99.0" : 3.556867966571835, + "99.9" : 3.556867966571835, + "99.99" : 3.556867966571835, + "99.999" : 3.556867966571835, + "99.9999" : 3.556867966571835, + "100.0" : 3.556867966571835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4634543123268697, + 3.5054302095304837, + 3.5006572841147654 + ], + [ + 3.525437097956307, + 3.556867966571835, + 3.5563972048364154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.788730153094184, + "scoreError" : 0.06903096873348752, + "scoreConfidence" : [ + 2.719699184360697, + 2.8577611218276715 + ], + "scorePercentiles" : { + "0.0" : 2.7437548197530863, + "50.0" : 2.783771960478709, + "90.0" : 2.849354674928775, + "95.0" : 2.849354674928775, + "99.0" : 2.849354674928775, + "99.9" : 2.849354674928775, + "99.99" : 2.849354674928775, + "99.999" : 2.849354674928775, + "99.9999" : 2.849354674928775, + "100.0" : 2.849354674928775 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7891072551589513, + 2.783771960478709, + 2.775938651124063 + ], + [ + 2.824776698107879, + 2.840119266609881, + 2.849354674928775 + ], + [ + 2.7456887584408456, + 2.7460592932454695, + 2.7437548197530863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17712537921057037, + "scoreError" : 0.007302705141392033, + "scoreConfidence" : [ + 0.16982267406917834, + 0.1844280843519624 + ], + "scorePercentiles" : { + "0.0" : 0.17273654465997618, + "50.0" : 0.17481974593989827, + "90.0" : 0.18281082563708823, + "95.0" : 0.18281082563708823, + "99.0" : 0.18281082563708823, + "99.9" : 0.18281082563708823, + "99.99" : 0.18281082563708823, + "99.999" : 0.18281082563708823, + "99.9999" : 0.18281082563708823, + "100.0" : 0.18281082563708823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1745027607273108, + 0.1769361178187866, + 0.17273654465997618 + ], + [ + 0.17481974593989827, + 0.17345907777700686, + 0.1735599226283453 + ], + [ + 0.18281082563708823, + 0.18277720421106503, + 0.18252621349565598 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32447753868441737, + "scoreError" : 0.005001733991219815, + "scoreConfidence" : [ + 0.31947580469319753, + 0.3294792726756372 + ], + "scorePercentiles" : { + "0.0" : 0.3203402676660901, + "50.0" : 0.3253693742964047, + "90.0" : 0.32748490490224974, + "95.0" : 0.32748490490224974, + "99.0" : 0.32748490490224974, + "99.9" : 0.32748490490224974, + "99.99" : 0.32748490490224974, + "99.999" : 0.32748490490224974, + "99.9999" : 0.32748490490224974, + "100.0" : 0.32748490490224974 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32748490490224974, + 0.3271972053396152, + 0.3270538788304935 + ], + [ + 0.3260087019396903, + 0.3252007965269422, + 0.3253693742964047 + ], + [ + 0.321195865324083, + 0.3203402676660901, + 0.3204468533341878 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16340967242962043, + "scoreError" : 0.011490652019065893, + "scoreConfidence" : [ + 0.15191902041055452, + 0.17490032444868633 + ], + "scorePercentiles" : { + "0.0" : 0.15772524404208002, + "50.0" : 0.15996247744577388, + "90.0" : 0.17276041387233307, + "95.0" : 0.17276041387233307, + "99.0" : 0.17276041387233307, + "99.9" : 0.17276041387233307, + "99.99" : 0.17276041387233307, + "99.999" : 0.17276041387233307, + "99.9999" : 0.17276041387233307, + "100.0" : 0.17276041387233307 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15996247744577388, + 0.15985878575995907, + 0.16040340945399717 + ], + [ + 0.15772524404208002, + 0.157725860035961, + 0.1577472638735527 + ], + [ + 0.17276041387233307, + 0.17239612719154584, + 0.17210747019138098 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38778148958174263, + "scoreError" : 0.007870026339949909, + "scoreConfidence" : [ + 0.3799114632417927, + 0.39565151592169256 + ], + "scorePercentiles" : { + "0.0" : 0.38187174053001377, + "50.0" : 0.388548793379439, + "90.0" : 0.39541730797516905, + "95.0" : 0.39541730797516905, + "99.0" : 0.39541730797516905, + "99.9" : 0.39541730797516905, + "99.99" : 0.39541730797516905, + "99.999" : 0.39541730797516905, + "99.9999" : 0.39541730797516905, + "100.0" : 0.39541730797516905 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3931338122026969, + 0.3896887151819811, + 0.38912040210116733 + ], + [ + 0.39541730797516905, + 0.388548793379439, + 0.38593098062673664 + ], + [ + 0.38401105663927504, + 0.38187174053001377, + 0.3823105975992048 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15859959775618343, + "scoreError" : 0.004781731731620883, + "scoreConfidence" : [ + 0.15381786602456254, + 0.16338132948780432 + ], + "scorePercentiles" : { + "0.0" : 0.15511315565379247, + "50.0" : 0.15770749495347736, + "90.0" : 0.16296427483092968, + "95.0" : 0.16296427483092968, + "99.0" : 0.16296427483092968, + "99.9" : 0.16296427483092968, + "99.99" : 0.16296427483092968, + "99.999" : 0.16296427483092968, + "99.9999" : 0.16296427483092968, + "100.0" : 0.16296427483092968 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15585705683961162, + 0.1566942354747728, + 0.15511315565379247 + ], + [ + 0.16296427483092968, + 0.16186691430883782, + 0.16168290255614298 + ], + [ + 0.15766940961765866, + 0.15784093557042742, + 0.15770749495347736 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04710584983796012, + "scoreError" : 5.002445975454384E-4, + "scoreConfidence" : [ + 0.04660560524041468, + 0.047606094435505564 + ], + "scorePercentiles" : { + "0.0" : 0.04662526819408893, + "50.0" : 0.047111269473208144, + "90.0" : 0.04774415838473731, + "95.0" : 0.04774415838473731, + "99.0" : 0.04774415838473731, + "99.9" : 0.04774415838473731, + "99.99" : 0.04774415838473731, + "99.999" : 0.04774415838473731, + "99.9999" : 0.04774415838473731, + "100.0" : 0.04774415838473731 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04774415838473731, + 0.04719217090366819, + 0.04711298183822594 + ], + [ + 0.04718592201198509, + 0.047111269473208144, + 0.046999683827607275 + ], + [ + 0.0470874619162421, + 0.046893731991878115, + 0.04662526819408893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9443774.941414071, + "scoreError" : 307746.71388554137, + "scoreConfidence" : [ + 9136028.22752853, + 9751521.655299613 + ], + "scorePercentiles" : { + "0.0" : 9286955.811513463, + "50.0" : 9365019.601123596, + "90.0" : 9707768.672162948, + "95.0" : 9707768.672162948, + "99.0" : 9707768.672162948, + "99.9" : 9707768.672162948, + "99.99" : 9707768.672162948, + "99.999" : 9707768.672162948, + "99.9999" : 9707768.672162948, + "100.0" : 9707768.672162948 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9286955.811513463, + 9303999.322790697, + 9307733.983255815 + ], + [ + 9309956.244651163, + 9365232.038389513, + 9365019.601123596 + ], + [ + 9707768.672162948, + 9675951.720502902, + 9671357.078336557 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:37:11Z-064de5fd6e70ca895fb1a652ac7d4f27423b2831-jdk17.json b/performance-results/2025-04-03T04:37:11Z-064de5fd6e70ca895fb1a652ac7d4f27423b2831-jdk17.json new file mode 100644 index 0000000000..967434fc3e --- /dev/null +++ b/performance-results/2025-04-03T04:37:11Z-064de5fd6e70ca895fb1a652ac7d4f27423b2831-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.398063238727424, + "scoreError" : 0.01846794614525216, + "scoreConfidence" : [ + 3.379595292582172, + 3.4165311848726763 + ], + "scorePercentiles" : { + "0.0" : 3.394463481045468, + "50.0" : 3.3981746276446567, + "90.0" : 3.401440218574916, + "95.0" : 3.401440218574916, + "99.0" : 3.401440218574916, + "99.9" : 3.401440218574916, + "99.99" : 3.401440218574916, + "99.999" : 3.401440218574916, + "99.9999" : 3.401440218574916, + "100.0" : 3.401440218574916 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.394463481045468, + 3.3979334679294224 + ], + [ + 3.398415787359891, + 3.401440218574916 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7155884162836184, + "scoreError" : 0.01669652478284702, + "scoreConfidence" : [ + 1.6988918915007714, + 1.7322849410664654 + ], + "scorePercentiles" : { + "0.0" : 1.7121557905255511, + "50.0" : 1.715993604740984, + "90.0" : 1.7182106651269544, + "95.0" : 1.7182106651269544, + "99.0" : 1.7182106651269544, + "99.9" : 1.7182106651269544, + "99.99" : 1.7182106651269544, + "99.999" : 1.7182106651269544, + "99.9999" : 1.7182106651269544, + "100.0" : 1.7182106651269544 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7121557905255511, + 1.7167149547253382 + ], + [ + 1.7152722547566301, + 1.7182106651269544 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.860582322212074, + "scoreError" : 0.007014266752437115, + "scoreConfidence" : [ + 0.8535680554596369, + 0.8675965889645111 + ], + "scorePercentiles" : { + "0.0" : 0.8590306137321312, + "50.0" : 0.8609782904232638, + "90.0" : 0.8613420942696371, + "95.0" : 0.8613420942696371, + "99.0" : 0.8613420942696371, + "99.9" : 0.8613420942696371, + "99.99" : 0.8613420942696371, + "99.999" : 0.8613420942696371, + "99.9999" : 0.8613420942696371, + "100.0" : 0.8613420942696371 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8613218540335297, + 0.8613420942696371 + ], + [ + 0.8590306137321312, + 0.8606347268129979 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.761189069739004, + "scoreError" : 0.15368336132423224, + "scoreConfidence" : [ + 15.607505708414772, + 15.914872431063236 + ], + "scorePercentiles" : { + "0.0" : 15.647324344216493, + "50.0" : 15.774902689094654, + "90.0" : 15.862001171401516, + "95.0" : 15.862001171401516, + "99.0" : 15.862001171401516, + "99.9" : 15.862001171401516, + "99.99" : 15.862001171401516, + "99.999" : 15.862001171401516, + "99.9999" : 15.862001171401516, + "100.0" : 15.862001171401516 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.691891086008026, + 15.647324344216493, + 15.648750806162413 + ], + [ + 15.691263256496491, + 15.834115149372924, + 15.843618460484318 + ], + [ + 15.862001171401516, + 15.856834664414194, + 15.774902689094654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2605.564647314867, + "scoreError" : 71.75800348528772, + "scoreConfidence" : [ + 2533.8066438295796, + 2677.322650800155 + ], + "scorePercentiles" : { + "0.0" : 2549.627018607967, + "50.0" : 2605.008813064446, + "90.0" : 2656.065490907737, + "95.0" : 2656.065490907737, + "99.0" : 2656.065490907737, + "99.9" : 2656.065490907737, + "99.99" : 2656.065490907737, + "99.999" : 2656.065490907737, + "99.9999" : 2656.065490907737, + "100.0" : 2656.065490907737 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2656.065490907737, + 2650.5415035008077, + 2639.3811388336094 + ], + [ + 2549.627018607967, + 2554.9937206067393, + 2560.1159714856094 + ], + [ + 2637.7776962860908, + 2596.5704725407954, + 2605.008813064446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69899.48411961367, + "scoreError" : 1599.6195809567562, + "scoreConfidence" : [ + 68299.86453865691, + 71499.10370057043 + ], + "scorePercentiles" : { + "0.0" : 68635.08400989581, + "50.0" : 70097.78329072687, + "90.0" : 70958.29943121137, + "95.0" : 70958.29943121137, + "99.0" : 70958.29943121137, + "99.9" : 70958.29943121137, + "99.99" : 70958.29943121137, + "99.999" : 70958.29943121137, + "99.9999" : 70958.29943121137, + "100.0" : 70958.29943121137 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70897.41237148685, + 70958.29943121137, + 70827.88010165881 + ], + [ + 70034.7228781272, + 70111.79570507018, + 70097.78329072687 + ], + [ + 68771.26924276495, + 68635.08400989581, + 68761.11004558101 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 318.2890154966056, + "scoreError" : 3.5026047930382624, + "scoreConfidence" : [ + 314.78641070356736, + 321.79162028964384 + ], + "scorePercentiles" : { + "0.0" : 313.54494204120397, + "50.0" : 318.3475360395479, + "90.0" : 321.16303018492044, + "95.0" : 321.16303018492044, + "99.0" : 321.16303018492044, + "99.9" : 321.16303018492044, + "99.99" : 321.16303018492044, + "99.999" : 321.16303018492044, + "99.9999" : 321.16303018492044, + "100.0" : 321.16303018492044 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 319.28675349502834, + 319.88635243263707, + 321.16303018492044 + ], + [ + 318.3475360395479, + 317.7739042163214, + 317.9026036071082 + ], + [ + 318.4421318678474, + 318.25388558483576, + 313.54494204120397 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 99.19790546048765, + "scoreError" : 4.922560682981105, + "scoreConfidence" : [ + 94.27534477750655, + 104.12046614346875 + ], + "scorePercentiles" : { + "0.0" : 95.29875350183407, + "50.0" : 99.31747082669419, + "90.0" : 102.77934146542273, + "95.0" : 102.77934146542273, + "99.0" : 102.77934146542273, + "99.9" : 102.77934146542273, + "99.99" : 102.77934146542273, + "99.999" : 102.77934146542273, + "99.9999" : 102.77934146542273, + "100.0" : 102.77934146542273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 95.5248125728636, + 95.29875350183407, + 96.26365728304859 + ], + [ + 99.02528655018615, + 100.36379191537276, + 99.31747082669419 + ], + [ + 102.43738296774471, + 102.77934146542273, + 101.77065206122195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06388822878506939, + "scoreError" : 9.979567518627098E-4, + "scoreConfidence" : [ + 0.06289027203320668, + 0.0648861855369321 + ], + "scorePercentiles" : { + "0.0" : 0.06305835662668836, + "50.0" : 0.06389496701787117, + "90.0" : 0.06479736363636364, + "95.0" : 0.06479736363636364, + "99.0" : 0.06479736363636364, + "99.9" : 0.06479736363636364, + "99.99" : 0.06479736363636364, + "99.999" : 0.06479736363636364, + "99.9999" : 0.06479736363636364, + "100.0" : 0.06479736363636364 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06374456063947781, + 0.06419815483084035, + 0.06389496701787117 + ], + [ + 0.06406173624296935, + 0.06479736363636364, + 0.06459939156217903 + ], + [ + 0.0632592709037082, + 0.06338025760552668, + 0.06305835662668836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.83019606931175E-4, + "scoreError" : 1.3784581850369122E-5, + "scoreConfidence" : [ + 3.6923502508080585E-4, + 3.968041887815441E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7020701441402385E-4, + "50.0" : 3.844138049114324E-4, + "90.0" : 3.934721148100017E-4, + "95.0" : 3.934721148100017E-4, + "99.0" : 3.934721148100017E-4, + "99.9" : 3.934721148100017E-4, + "99.99" : 3.934721148100017E-4, + "99.999" : 3.934721148100017E-4, + "99.9999" : 3.934721148100017E-4, + "100.0" : 3.934721148100017E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8526200194871147E-4, + 3.8127326824683404E-4, + 3.844138049114324E-4 + ], + [ + 3.934721148100017E-4, + 3.9015963338102455E-4, + 3.9196502741253386E-4 + ], + [ + 3.7619870712614367E-4, + 3.7422489012986976E-4, + 3.7020701441402385E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014507169573223098, + "scoreError" : 5.580762315377476E-4, + "scoreConfidence" : [ + 0.01394909334168535, + 0.015065245804760846 + ], + "scorePercentiles" : { + "0.0" : 0.014197896179254592, + "50.0" : 0.014309983227464544, + "90.0" : 0.014960949395286768, + "95.0" : 0.014960949395286768, + "99.0" : 0.014960949395286768, + "99.9" : 0.014960949395286768, + "99.99" : 0.014960949395286768, + "99.999" : 0.014960949395286768, + "99.9999" : 0.014960949395286768, + "100.0" : 0.014960949395286768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014448763521694528, + 0.014238935660798879, + 0.014197896179254592 + ], + [ + 0.014309983227464544, + 0.014273343558159617, + 0.014274491531762492 + ], + [ + 0.014931303598997824, + 0.014960949395286768, + 0.01492885948558863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9907268310671148, + "scoreError" : 0.02012586950490829, + "scoreConfidence" : [ + 0.9706009615622065, + 1.0108527005720231 + ], + "scorePercentiles" : { + "0.0" : 0.9740569874354729, + "50.0" : 0.9971856530062818, + "90.0" : 1.0045795006529383, + "95.0" : 1.0045795006529383, + "99.0" : 1.0045795006529383, + "99.9" : 1.0045795006529383, + "99.99" : 1.0045795006529383, + "99.999" : 1.0045795006529383, + "99.9999" : 1.0045795006529383, + "100.0" : 1.0045795006529383 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9986444846215299, + 0.9971856530062818, + 1.0045795006529383 + ], + [ + 0.9973045451735142, + 0.9972825439768648, + 0.9962513022213367 + ], + [ + 0.9757165716655284, + 0.9755198908505658, + 0.9740569874354729 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013343001108488255, + "scoreError" : 1.603246869937958E-4, + "scoreConfidence" : [ + 0.01318267642149446, + 0.01350332579548205 + ], + "scorePercentiles" : { + "0.0" : 0.013283585089821314, + "50.0" : 0.013325930652973463, + "90.0" : 0.01342174419659634, + "95.0" : 0.01342174419659634, + "99.0" : 0.01342174419659634, + "99.9" : 0.01342174419659634, + "99.99" : 0.01342174419659634, + "99.999" : 0.01342174419659634, + "99.9999" : 0.01342174419659634, + "100.0" : 0.01342174419659634 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013296058110407913, + 0.01342174419659634, + 0.013404757948157025 + ], + [ + 0.013328466066544758, + 0.013323395239402168, + 0.013283585089821314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.9281097096224347, + "scoreError" : 0.19831393229042082, + "scoreConfidence" : [ + 3.729795777332014, + 4.126423641912855 + ], + "scorePercentiles" : { + "0.0" : 3.8423004477726574, + "50.0" : 3.9272893627166936, + "90.0" : 3.9999446554756197, + "95.0" : 3.9999446554756197, + "99.0" : 3.9999446554756197, + "99.9" : 3.9999446554756197, + "99.99" : 3.9999446554756197, + "99.999" : 3.9999446554756197, + "99.9999" : 3.9999446554756197, + "100.0" : 3.9999446554756197 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9999446554756197, + 3.978067418456643, + 3.9959317412140574 + ], + [ + 3.8423004477726574, + 3.8765113069767443, + 3.8759026878388845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.1320001021459305, + "scoreError" : 0.1305735498002403, + "scoreConfidence" : [ + 3.00142655234569, + 3.262573651946171 + ], + "scorePercentiles" : { + "0.0" : 3.0153515375339164, + "50.0" : 3.1369162976787957, + "90.0" : 3.216451787459807, + "95.0" : 3.216451787459807, + "99.0" : 3.216451787459807, + "99.9" : 3.216451787459807, + "99.99" : 3.216451787459807, + "99.999" : 3.216451787459807, + "99.9999" : 3.216451787459807, + "100.0" : 3.216451787459807 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.160231842022117, + 3.1369162976787957, + 3.1275856741713572 + ], + [ + 3.216451787459807, + 3.2145117405978785, + 3.214671719061395 + ], + [ + 3.0153515375339164, + 3.052139432102533, + 3.0501408886855748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1797257930507823, + "scoreError" : 0.006638397579902533, + "scoreConfidence" : [ + 0.17308739547087976, + 0.18636419063068482 + ], + "scorePercentiles" : { + "0.0" : 0.1743994850107253, + "50.0" : 0.18180634640487228, + "90.0" : 0.18315693981574754, + "95.0" : 0.18315693981574754, + "99.0" : 0.18315693981574754, + "99.9" : 0.18315693981574754, + "99.99" : 0.18315693981574754, + "99.999" : 0.18315693981574754, + "99.9999" : 0.18315693981574754, + "100.0" : 0.18315693981574754 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18180634640487228, + 0.1818186315703351, + 0.18180463257885646 + ], + [ + 0.1746522944566698, + 0.1743994850107253, + 0.1744420070472901 + ], + [ + 0.18315693981574754, + 0.18280616558204152, + 0.18264563499050263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3383194540641472, + "scoreError" : 0.020423803604438278, + "scoreConfidence" : [ + 0.3178956504597089, + 0.3587432576685855 + ], + "scorePercentiles" : { + "0.0" : 0.3253307799863366, + "50.0" : 0.3337108633163146, + "90.0" : 0.355636786656709, + "95.0" : 0.355636786656709, + "99.0" : 0.355636786656709, + "99.9" : 0.355636786656709, + "99.99" : 0.355636786656709, + "99.999" : 0.355636786656709, + "99.9999" : 0.355636786656709, + "100.0" : 0.355636786656709 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3275824299331761, + 0.3281772648661066, + 0.3253307799863366 + ], + [ + 0.3352680090854231, + 0.3337108633163146, + 0.33307845443645084 + ], + [ + 0.3517657857117732, + 0.354324712585034, + 0.355636786656709 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16835279831565275, + "scoreError" : 0.008841408090625332, + "scoreConfidence" : [ + 0.15951139022502742, + 0.1771942064062781 + ], + "scorePercentiles" : { + "0.0" : 0.16128091963551328, + "50.0" : 0.1713425613734494, + "90.0" : 0.1726306326992128, + "95.0" : 0.1726306326992128, + "99.0" : 0.1726306326992128, + "99.9" : 0.1726306326992128, + "99.99" : 0.1726306326992128, + "99.999" : 0.1726306326992128, + "99.9999" : 0.1726306326992128, + "100.0" : 0.1726306326992128 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1713425613734494, + 0.17160019881254718, + 0.17104700237749082 + ], + [ + 0.17248626498439038, + 0.1726306326992128, + 0.17196016485538398 + ], + [ + 0.16128091963551328, + 0.16137944565655912, + 0.16144799444632796 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3952465346387055, + "scoreError" : 0.003297160570744365, + "scoreConfidence" : [ + 0.39194937406796115, + 0.3985436952094499 + ], + "scorePercentiles" : { + "0.0" : 0.39318401466540853, + "50.0" : 0.3945501908387911, + "90.0" : 0.3986785879843725, + "95.0" : 0.3986785879843725, + "99.0" : 0.3986785879843725, + "99.9" : 0.3986785879843725, + "99.99" : 0.3986785879843725, + "99.999" : 0.3986785879843725, + "99.9999" : 0.3986785879843725, + "100.0" : 0.3986785879843725 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3945501908387911, + 0.39391868401150193, + 0.3934821552626402 + ], + [ + 0.3986785879843725, + 0.39347827231949634, + 0.39318401466540853 + ], + [ + 0.3968952295999365, + 0.39692631868698897, + 0.39610535837921335 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1593310385581499, + "scoreError" : 0.0028442450259137868, + "scoreConfidence" : [ + 0.1564867935322361, + 0.1621752835840637 + ], + "scorePercentiles" : { + "0.0" : 0.15777442514554377, + "50.0" : 0.15874837003524145, + "90.0" : 0.1624385157156084, + "95.0" : 0.1624385157156084, + "99.0" : 0.1624385157156084, + "99.9" : 0.1624385157156084, + "99.99" : 0.1624385157156084, + "99.999" : 0.1624385157156084, + "99.9999" : 0.1624385157156084, + "100.0" : 0.1624385157156084 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1624385157156084, + 0.16167678781950753, + 0.16008429511109687 + ], + [ + 0.15874837003524145, + 0.1587637378548295, + 0.1582909996992529 + ], + [ + 0.1581139882998403, + 0.1580882273424285, + 0.15777442514554377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04777432791293147, + "scoreError" : 0.0013125816839008406, + "scoreConfidence" : [ + 0.04646174622903063, + 0.04908690959683231 + ], + "scorePercentiles" : { + "0.0" : 0.04719819954218289, + "50.0" : 0.04727648992076549, + "90.0" : 0.04886981457571789, + "95.0" : 0.04886981457571789, + "99.0" : 0.04886981457571789, + "99.9" : 0.04886981457571789, + "99.99" : 0.04886981457571789, + "99.999" : 0.04886981457571789, + "99.9999" : 0.04886981457571789, + "100.0" : 0.04886981457571789 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04727648992076549, + 0.04726375017723625, + 0.04729652034904344 + ], + [ + 0.047260753382641366, + 0.04722931846261382, + 0.04719819954218289 + ], + [ + 0.04878328790044441, + 0.04886981457571789, + 0.04879081690573771 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9854902.347201487, + "scoreError" : 395549.2532945072, + "scoreConfidence" : [ + 9459353.09390698, + 1.0250451600495994E7 + ], + "scorePercentiles" : { + "0.0" : 9519942.573739296, + "50.0" : 9846367.802165354, + "90.0" : 1.0131742660931174E7, + "95.0" : 1.0131742660931174E7, + "99.0" : 1.0131742660931174E7, + "99.9" : 1.0131742660931174E7, + "99.99" : 1.0131742660931174E7, + "99.999" : 1.0131742660931174E7, + "99.9999" : 1.0131742660931174E7, + "100.0" : 1.0131742660931174E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9718148.198058253, + 9563246.647227533, + 9519942.573739296 + ], + [ + 9846367.802165354, + 9882046.2023692, + 9784536.290322581 + ], + [ + 1.012611225708502E7, + 1.0131742660931174E7, + 1.012197849291498E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-03T04:39:22Z-064de5fd6e70ca895fb1a652ac7d4f27423b2831-jdk17.json b/performance-results/2025-04-03T04:39:22Z-064de5fd6e70ca895fb1a652ac7d4f27423b2831-jdk17.json new file mode 100644 index 0000000000..0831530274 --- /dev/null +++ b/performance-results/2025-04-03T04:39:22Z-064de5fd6e70ca895fb1a652ac7d4f27423b2831-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4028158052032147, + "scoreError" : 0.02698436626698203, + "scoreConfidence" : [ + 3.3758314389362325, + 3.429800171470197 + ], + "scorePercentiles" : { + "0.0" : 3.3984327814572493, + "50.0" : 3.4024482494709245, + "90.0" : 3.40793394041376, + "95.0" : 3.40793394041376, + "99.0" : 3.40793394041376, + "99.9" : 3.40793394041376, + "99.99" : 3.40793394041376, + "99.999" : 3.40793394041376, + "99.9999" : 3.40793394041376, + "100.0" : 3.40793394041376 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3984327814572493, + 3.400626569701109 + ], + [ + 3.40426992924074, + 3.40793394041376 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7217318691895986, + "scoreError" : 0.010243454629387177, + "scoreConfidence" : [ + 1.7114884145602114, + 1.731975323818986 + ], + "scorePercentiles" : { + "0.0" : 1.719393836215952, + "50.0" : 1.7223979685910846, + "90.0" : 1.722737703360273, + "95.0" : 1.722737703360273, + "99.0" : 1.722737703360273, + "99.9" : 1.722737703360273, + "99.99" : 1.722737703360273, + "99.999" : 1.722737703360273, + "99.9999" : 1.722737703360273, + "100.0" : 1.722737703360273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7221038886454691, + 1.722737703360273 + ], + [ + 1.719393836215952, + 1.7226920485366999 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8654434507790818, + "scoreError" : 0.008438986629075771, + "scoreConfidence" : [ + 0.8570044641500061, + 0.8738824374081575 + ], + "scorePercentiles" : { + "0.0" : 0.8645342532584883, + "50.0" : 0.8649425572522541, + "90.0" : 0.8673544353533303, + "95.0" : 0.8673544353533303, + "99.0" : 0.8673544353533303, + "99.9" : 0.8673544353533303, + "99.99" : 0.8673544353533303, + "99.999" : 0.8673544353533303, + "99.9999" : 0.8673544353533303, + "100.0" : 0.8673544353533303 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8645342532584883, + 0.8652034852013738 + ], + [ + 0.8646816293031344, + 0.8673544353533303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.856852526851778, + "scoreError" : 0.22239508840105984, + "scoreConfidence" : [ + 15.634457438450719, + 16.07924761525284 + ], + "scorePercentiles" : { + "0.0" : 15.655595185675983, + "50.0" : 15.897855959962087, + "90.0" : 16.075434896788032, + "95.0" : 16.075434896788032, + "99.0" : 16.075434896788032, + "99.9" : 16.075434896788032, + "99.99" : 16.075434896788032, + "99.999" : 16.075434896788032, + "99.9999" : 16.075434896788032, + "100.0" : 16.075434896788032 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.795514884463312, + 15.734436696789428, + 15.655595185675983 + ], + [ + 15.961511976581217, + 15.748292618608652, + 15.933875666964484 + ], + [ + 16.075434896788032, + 15.897855959962087, + 15.909154855832826 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2627.694997644631, + "scoreError" : 100.4623977422994, + "scoreConfidence" : [ + 2527.2325999023315, + 2728.15739538693 + ], + "scorePercentiles" : { + "0.0" : 2546.832028910364, + "50.0" : 2617.358010776736, + "90.0" : 2726.1959070049306, + "95.0" : 2726.1959070049306, + "99.0" : 2726.1959070049306, + "99.9" : 2726.1959070049306, + "99.99" : 2726.1959070049306, + "99.999" : 2726.1959070049306, + "99.9999" : 2726.1959070049306, + "100.0" : 2726.1959070049306 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2682.3819623737045, + 2686.3172658046005, + 2726.1959070049306 + ], + [ + 2617.358010776736, + 2566.8713813030668, + 2611.7854559352445 + ], + [ + 2626.9936504978727, + 2546.832028910364, + 2584.5193161951593 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69994.63854814746, + "scoreError" : 914.8097763908709, + "scoreConfidence" : [ + 69079.82877175658, + 70909.44832453833 + ], + "scorePercentiles" : { + "0.0" : 68967.6464426141, + "50.0" : 70207.4304985715, + "90.0" : 70500.16253561925, + "95.0" : 70500.16253561925, + "99.0" : 70500.16253561925, + "99.9" : 70500.16253561925, + "99.99" : 70500.16253561925, + "99.999" : 70500.16253561925, + "99.9999" : 70500.16253561925, + "100.0" : 70500.16253561925 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69828.42820603953, + 69413.01432131404, + 69734.47790099871 + ], + [ + 70448.36211536035, + 70207.4304985715, + 70500.16253561925 + ], + [ + 70468.08488030932, + 68967.6464426141, + 70384.14003250026 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 346.7931852807508, + "scoreError" : 3.3342629800102954, + "scoreConfidence" : [ + 343.4589223007405, + 350.12744826076107 + ], + "scorePercentiles" : { + "0.0" : 343.7680474475259, + "50.0" : 346.25243329497414, + "90.0" : 349.58594626041577, + "95.0" : 349.58594626041577, + "99.0" : 349.58594626041577, + "99.9" : 349.58594626041577, + "99.99" : 349.58594626041577, + "99.999" : 349.58594626041577, + "99.9999" : 349.58594626041577, + "100.0" : 349.58594626041577 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 343.7680474475259, + 345.8715452517336, + 347.96462884988966 + ], + [ + 346.07920593473517, + 346.25243329497414, + 347.765244689211 + ], + [ + 344.63011611183293, + 349.22149968643856, + 349.58594626041577 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 103.84830895680096, + "scoreError" : 2.853451773658508, + "scoreConfidence" : [ + 100.99485718314246, + 106.70176073045947 + ], + "scorePercentiles" : { + "0.0" : 101.71035761699841, + "50.0" : 103.04915723582602, + "90.0" : 106.43837078897053, + "95.0" : 106.43837078897053, + "99.0" : 106.43837078897053, + "99.9" : 106.43837078897053, + "99.99" : 106.43837078897053, + "99.999" : 106.43837078897053, + "99.9999" : 106.43837078897053, + "100.0" : 106.43837078897053 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.71035761699841, + 102.96619234811652, + 103.04915723582602 + ], + [ + 106.43837078897053, + 106.37364400433496, + 105.10326118216283 + ], + [ + 103.40392088198075, + 102.76412725260485, + 102.82574930021367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06326091308772883, + "scoreError" : 6.878635265646218E-4, + "scoreConfidence" : [ + 0.0625730495611642, + 0.06394877661429345 + ], + "scorePercentiles" : { + "0.0" : 0.06274002661396574, + "50.0" : 0.06328955167525284, + "90.0" : 0.06400515197772658, + "95.0" : 0.06400515197772658, + "99.0" : 0.06400515197772658, + "99.9" : 0.06400515197772658, + "99.99" : 0.06400515197772658, + "99.999" : 0.06400515197772658, + "99.9999" : 0.06400515197772658, + "100.0" : 0.06400515197772658 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06287397867350723, + 0.06279671892543612, + 0.06346642787149512 + ], + [ + 0.06337502196548643, + 0.06274002661396574, + 0.06328955167525284 + ], + [ + 0.06356635234142094, + 0.06400515197772658, + 0.06323498774526852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.855581819461642E-4, + "scoreError" : 6.921607125895276E-6, + "scoreConfidence" : [ + 3.786365748202689E-4, + 3.924797890720594E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7792593484907937E-4, + "50.0" : 3.8691700719416E-4, + "90.0" : 3.913857062366774E-4, + "95.0" : 3.913857062366774E-4, + "99.0" : 3.913857062366774E-4, + "99.9" : 3.913857062366774E-4, + "99.99" : 3.913857062366774E-4, + "99.999" : 3.913857062366774E-4, + "99.9999" : 3.913857062366774E-4, + "100.0" : 3.913857062366774E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7792593484907937E-4, + 3.8200901836640285E-4, + 3.8237432355374515E-4 + ], + [ + 3.855961513716939E-4, + 3.877975459473206E-4, + 3.913857062366774E-4 + ], + [ + 3.8691700719416E-4, + 3.8703300435309726E-4, + 3.8898494564330134E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01446867119144881, + "scoreError" : 3.071290232277809E-4, + "scoreConfidence" : [ + 0.01416154216822103, + 0.014775800214676591 + ], + "scorePercentiles" : { + "0.0" : 0.01424524991666643, + "50.0" : 0.014418233085102549, + "90.0" : 0.01471546875142554, + "95.0" : 0.01471546875142554, + "99.0" : 0.01471546875142554, + "99.9" : 0.01471546875142554, + "99.99" : 0.01471546875142554, + "99.999" : 0.01471546875142554, + "99.9999" : 0.01471546875142554, + "100.0" : 0.01471546875142554 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01441417423497701, + 0.014418233085102549, + 0.014425451218720563 + ], + [ + 0.014347761017875667, + 0.01427606893824538, + 0.01424524991666643 + ], + [ + 0.01471291030230269, + 0.01471546875142554, + 0.014662723257723494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0029323812394497, + "scoreError" : 0.008664048351075164, + "scoreConfidence" : [ + 0.9942683328883746, + 1.0115964295905249 + ], + "scorePercentiles" : { + "0.0" : 0.995025286240175, + "50.0" : 1.0018026926775518, + "90.0" : 1.0113044462534129, + "95.0" : 1.0113044462534129, + "99.0" : 1.0113044462534129, + "99.9" : 1.0113044462534129, + "99.99" : 1.0113044462534129, + "99.999" : 1.0113044462534129, + "99.9999" : 1.0113044462534129, + "100.0" : 1.0113044462534129 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0113044462534129, + 0.9978523330672521, + 1.0008790364291433 + ], + [ + 1.0075035067499496, + 1.0012708366039247, + 1.0079401847409797 + ], + [ + 0.995025286240175, + 1.0018026926775518, + 1.0028131083926601 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01299504090943715, + "scoreError" : 5.276041924888734E-4, + "scoreConfidence" : [ + 0.012467436716948277, + 0.013522645101926023 + ], + "scorePercentiles" : { + "0.0" : 0.012795588516489282, + "50.0" : 0.01293060720421979, + "90.0" : 0.013293538975678752, + "95.0" : 0.013293538975678752, + "99.0" : 0.013293538975678752, + "99.9" : 0.013293538975678752, + "99.99" : 0.013293538975678752, + "99.999" : 0.013293538975678752, + "99.9999" : 0.013293538975678752, + "100.0" : 0.013293538975678752 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012966117529756502, + 0.013293538975678752, + 0.01314568560822162 + ], + [ + 0.012795588516489282, + 0.012874217947793667, + 0.01289509687868308 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.734757970815448, + "scoreError" : 0.10371285218767395, + "scoreConfidence" : [ + 3.631045118627774, + 3.838470823003122 + ], + "scorePercentiles" : { + "0.0" : 3.6964419098300074, + "50.0" : 3.7301802576484198, + "90.0" : 3.8028869977186313, + "95.0" : 3.8028869977186313, + "99.0" : 3.8028869977186313, + "99.9" : 3.8028869977186313, + "99.99" : 3.8028869977186313, + "99.999" : 3.8028869977186313, + "99.9999" : 3.8028869977186313, + "100.0" : 3.8028869977186313 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.726333251117735, + 3.7340272641791046, + 3.8028869977186313 + ], + [ + 3.6964419098300074, + 3.7393437959641256, + 3.709514606083086 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.915910361825667, + "scoreError" : 0.07793360653432067, + "scoreConfidence" : [ + 2.837976755291346, + 2.993843968359988 + ], + "scorePercentiles" : { + "0.0" : 2.867956468597648, + "50.0" : 2.8936321148726853, + "90.0" : 2.9790791128984213, + "95.0" : 2.9790791128984213, + "99.0" : 2.9790791128984213, + "99.9" : 2.9790791128984213, + "99.99" : 2.9790791128984213, + "99.999" : 2.9790791128984213, + "99.9999" : 2.9790791128984213, + "100.0" : 2.9790791128984213 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.896652921227918, + 2.89269080075188, + 2.8936321148726853 + ], + [ + 2.9790791128984213, + 2.9724285346210997, + 2.977471262578148 + ], + [ + 2.867956468597648, + 2.8722168515221136, + 2.891065189361087 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1781156711732394, + "scoreError" : 0.006079830536500371, + "scoreConfidence" : [ + 0.17203584063673902, + 0.18419550170973978 + ], + "scorePercentiles" : { + "0.0" : 0.17460855640528697, + "50.0" : 0.17648928387631924, + "90.0" : 0.1839968523827047, + "95.0" : 0.1839968523827047, + "99.0" : 0.1839968523827047, + "99.9" : 0.1839968523827047, + "99.99" : 0.1839968523827047, + "99.999" : 0.1839968523827047, + "99.9999" : 0.1839968523827047, + "100.0" : 0.1839968523827047 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17637950940966896, + 0.17687212596614726, + 0.17648928387631924 + ], + [ + 0.17460855640528697, + 0.17498917958633722, + 0.17535292089989304 + ], + [ + 0.1825232611473106, + 0.18182935088548674, + 0.1839968523827047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33701370251603385, + "scoreError" : 0.009438468960818618, + "scoreConfidence" : [ + 0.32757523355521523, + 0.3464521714768525 + ], + "scorePercentiles" : { + "0.0" : 0.3287976433010028, + "50.0" : 0.3379593185197702, + "90.0" : 0.34396548885602257, + "95.0" : 0.34396548885602257, + "99.0" : 0.34396548885602257, + "99.9" : 0.34396548885602257, + "99.99" : 0.34396548885602257, + "99.999" : 0.34396548885602257, + "99.9999" : 0.34396548885602257, + "100.0" : 0.34396548885602257 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3379593185197702, + 0.33675483223329744, + 0.3381346030092984 + ], + [ + 0.3313426720453265, + 0.33083449103480217, + 0.3287976433010028 + ], + [ + 0.34284380513558915, + 0.34396548885602257, + 0.3424904685091955 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16854884601881842, + "scoreError" : 0.009004225213796735, + "scoreConfidence" : [ + 0.1595446208050217, + 0.17755307123261516 + ], + "scorePercentiles" : { + "0.0" : 0.1625799294249622, + "50.0" : 0.16720458142723382, + "90.0" : 0.17602810589684914, + "95.0" : 0.17602810589684914, + "99.0" : 0.17602810589684914, + "99.9" : 0.17602810589684914, + "99.99" : 0.17602810589684914, + "99.999" : 0.17602810589684914, + "99.9999" : 0.17602810589684914, + "100.0" : 0.17602810589684914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16455403246560915, + 0.16276767064893635, + 0.1625799294249622 + ], + [ + 0.17602810589684914, + 0.17495130307907628, + 0.1749156841460855 + ], + [ + 0.1674244847647748, + 0.16720458142723382, + 0.16651382231583856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.391641101994612, + "scoreError" : 0.005342483206538888, + "scoreConfidence" : [ + 0.3862986187880731, + 0.3969835852011509 + ], + "scorePercentiles" : { + "0.0" : 0.38694450398545116, + "50.0" : 0.39131360545468774, + "90.0" : 0.3956067646965741, + "95.0" : 0.3956067646965741, + "99.0" : 0.3956067646965741, + "99.9" : 0.3956067646965741, + "99.99" : 0.3956067646965741, + "99.999" : 0.3956067646965741, + "99.9999" : 0.3956067646965741, + "100.0" : 0.3956067646965741 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39131360545468774, + 0.3917293123114889, + 0.39113433987797247 + ], + [ + 0.3896956932818954, + 0.3879598262792412, + 0.38694450398545116 + ], + [ + 0.3956067646965741, + 0.3949321541347445, + 0.3954537179294527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1615410805047081, + "scoreError" : 0.0036366686572976447, + "scoreConfidence" : [ + 0.15790441184741047, + 0.16517774916200575 + ], + "scorePercentiles" : { + "0.0" : 0.158518118710966, + "50.0" : 0.16221693251901959, + "90.0" : 0.16381021045734503, + "95.0" : 0.16381021045734503, + "99.0" : 0.16381021045734503, + "99.9" : 0.16381021045734503, + "99.99" : 0.16381021045734503, + "99.999" : 0.16381021045734503, + "99.9999" : 0.16381021045734503, + "100.0" : 0.16381021045734503 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1627364314819938, + 0.16221693251901959, + 0.16200593401590876 + ], + [ + 0.15881188489574236, + 0.15897466935330026, + 0.158518118710966 + ], + [ + 0.16381021045734503, + 0.1636706063666121, + 0.16312493674148507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048394316920121444, + "scoreError" : 9.371383005411213E-4, + "scoreConfidence" : [ + 0.04745717861958032, + 0.04933145522066257 + ], + "scorePercentiles" : { + "0.0" : 0.047463494195318284, + "50.0" : 0.04846126208487398, + "90.0" : 0.04896047807333206, + "95.0" : 0.04896047807333206, + "99.0" : 0.04896047807333206, + "99.9" : 0.04896047807333206, + "99.99" : 0.04896047807333206, + "99.999" : 0.04896047807333206, + "99.9999" : 0.04896047807333206, + "100.0" : 0.04896047807333206 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04894498875750071, + 0.04896047807333206, + 0.04881620786612839 + ], + [ + 0.048715233678231475, + 0.04844254924358024, + 0.04846126208487398 + ], + [ + 0.04815959974379596, + 0.04758503863833189, + 0.047463494195318284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9323662.9841781, + "scoreError" : 138556.00966994776, + "scoreConfidence" : [ + 9185106.974508151, + 9462218.993848048 + ], + "scorePercentiles" : { + "0.0" : 9180911.86055046, + "50.0" : 9361837.434050515, + "90.0" : 9421453.089453861, + "95.0" : 9421453.089453861, + "99.0" : 9421453.089453861, + "99.9" : 9421453.089453861, + "99.99" : 9421453.089453861, + "99.999" : 9421453.089453861, + "99.9999" : 9421453.089453861, + "100.0" : 9421453.089453861 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9370760.92977528, + 9361837.434050515, + 9305615.085581396 + ], + [ + 9421453.089453861, + 9368289.597378276, + 9369009.029026218 + ], + [ + 9180911.86055046, + 9338604.646125117, + 9196485.185661765 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-04T00:51:24Z-95742271c556d7833837a8bb84b519969b097d10-jdk17.json b/performance-results/2025-04-04T00:51:24Z-95742271c556d7833837a8bb84b519969b097d10-jdk17.json new file mode 100644 index 0000000000..1158c0d2e2 --- /dev/null +++ b/performance-results/2025-04-04T00:51:24Z-95742271c556d7833837a8bb84b519969b097d10-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.410055263437113, + "scoreError" : 0.044175216312736174, + "scoreConfidence" : [ + 3.3658800471243766, + 3.454230479749849 + ], + "scorePercentiles" : { + "0.0" : 3.4022423915588753, + "50.0" : 3.4096308464644025, + "90.0" : 3.4187169692607715, + "95.0" : 3.4187169692607715, + "99.0" : 3.4187169692607715, + "99.9" : 3.4187169692607715, + "99.99" : 3.4187169692607715, + "99.999" : 3.4187169692607715, + "99.9999" : 3.4187169692607715, + "100.0" : 3.4187169692607715 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.411004350188826, + 3.4187169692607715 + ], + [ + 3.4022423915588753, + 3.4082573427399785 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7222751587969176, + "scoreError" : 0.020331821722778594, + "scoreConfidence" : [ + 1.701943337074139, + 1.7426069805196962 + ], + "scorePercentiles" : { + "0.0" : 1.7197942687239545, + "50.0" : 1.7213092858607992, + "90.0" : 1.7266877947421173, + "95.0" : 1.7266877947421173, + "99.0" : 1.7266877947421173, + "99.9" : 1.7266877947421173, + "99.99" : 1.7266877947421173, + "99.999" : 1.7266877947421173, + "99.9999" : 1.7266877947421173, + "100.0" : 1.7266877947421173 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7202588154580092, + 1.7197942687239545 + ], + [ + 1.722359756263589, + 1.7266877947421173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8674677837492119, + "scoreError" : 0.0032325394754821957, + "scoreConfidence" : [ + 0.8642352442737297, + 0.870700323224694 + ], + "scorePercentiles" : { + "0.0" : 0.8667362217669433, + "50.0" : 0.8676693253640158, + "90.0" : 0.8677962625018725, + "95.0" : 0.8677962625018725, + "99.0" : 0.8677962625018725, + "99.9" : 0.8677962625018725, + "99.99" : 0.8677962625018725, + "99.999" : 0.8677962625018725, + "99.9999" : 0.8677962625018725, + "100.0" : 0.8677962625018725 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8677962625018725, + 0.8677842124557796 + ], + [ + 0.8667362217669433, + 0.867554438272252 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.2586900425068, + "scoreError" : 0.13636078587224731, + "scoreConfidence" : [ + 16.12232925663455, + 16.39505082837905 + ], + "scorePercentiles" : { + "0.0" : 16.135512844186522, + "50.0" : 16.273833465528117, + "90.0" : 16.34983499696942, + "95.0" : 16.34983499696942, + "99.0" : 16.34983499696942, + "99.9" : 16.34983499696942, + "99.99" : 16.34983499696942, + "99.999" : 16.34983499696942, + "99.9999" : 16.34983499696942, + "100.0" : 16.34983499696942 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.303901131535557, + 16.273833465528117, + 16.24110655705213 + ], + [ + 16.176868280921056, + 16.135512844186522, + 16.17233484324961 + ], + [ + 16.33151180545686, + 16.34983499696942, + 16.343306457661935 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2672.9855538524826, + "scoreError" : 14.616387865211415, + "scoreConfidence" : [ + 2658.369165987271, + 2687.601941717694 + ], + "scorePercentiles" : { + "0.0" : 2661.079080442354, + "50.0" : 2671.607818200002, + "90.0" : 2687.040356143568, + "95.0" : 2687.040356143568, + "99.0" : 2687.040356143568, + "99.9" : 2687.040356143568, + "99.99" : 2687.040356143568, + "99.999" : 2687.040356143568, + "99.9999" : 2687.040356143568, + "100.0" : 2687.040356143568 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2661.079080442354, + 2663.538227857365, + 2666.4540926531217 + ], + [ + 2671.607818200002, + 2671.283841175784, + 2674.8653706116493 + ], + [ + 2683.025033592116, + 2677.9761639963845, + 2687.040356143568 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70775.80766872116, + "scoreError" : 742.2818518809171, + "scoreConfidence" : [ + 70033.52581684024, + 71518.08952060208 + ], + "scorePercentiles" : { + "0.0" : 70142.75578283423, + "50.0" : 70954.80008396578, + "90.0" : 71195.13156890463, + "95.0" : 71195.13156890463, + "99.0" : 71195.13156890463, + "99.9" : 71195.13156890463, + "99.99" : 71195.13156890463, + "99.999" : 71195.13156890463, + "99.9999" : 71195.13156890463, + "100.0" : 71195.13156890463 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70142.75578283423, + 70226.43035099976, + 70232.69147423247 + ], + [ + 70950.31244706645, + 70954.80008396578, + 70973.0529781649 + ], + [ + 71173.35377017567, + 71133.74056214653, + 71195.13156890463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 354.3389211609874, + "scoreError" : 5.666682962041467, + "scoreConfidence" : [ + 348.67223819894593, + 360.0056041230289 + ], + "scorePercentiles" : { + "0.0" : 349.8278019785032, + "50.0" : 356.1210976315482, + "90.0" : 357.67017227481824, + "95.0" : 357.67017227481824, + "99.0" : 357.67017227481824, + "99.9" : 357.67017227481824, + "99.99" : 357.67017227481824, + "99.999" : 357.67017227481824, + "99.9999" : 357.67017227481824, + "100.0" : 357.67017227481824 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.8548042520111, + 349.98260316975643, + 349.8278019785032 + ], + [ + 356.2227738236618, + 356.0560147982399, + 356.1210976315482 + ], + [ + 356.57428086763986, + 356.74074165270775, + 357.67017227481824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.66346338200165, + "scoreError" : 0.9408238124872885, + "scoreConfidence" : [ + 106.72263956951436, + 108.60428719448895 + ], + "scorePercentiles" : { + "0.0" : 106.93014223867108, + "50.0" : 107.65326652205152, + "90.0" : 108.490211199469, + "95.0" : 108.490211199469, + "99.0" : 108.490211199469, + "99.9" : 108.490211199469, + "99.99" : 108.490211199469, + "99.999" : 108.490211199469, + "99.9999" : 108.490211199469, + "100.0" : 108.490211199469 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.65326652205152, + 107.71425907277816, + 107.6000277167281 + ], + [ + 107.89863468304631, + 108.45276519843372, + 108.490211199469 + ], + [ + 106.93014223867108, + 107.14562496679335, + 107.08623884004336 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061783570798361755, + "scoreError" : 2.919212182128583E-4, + "scoreConfidence" : [ + 0.0614916495801489, + 0.06207549201657461 + ], + "scorePercentiles" : { + "0.0" : 0.06148453356082265, + "50.0" : 0.061730150100618525, + "90.0" : 0.06201947467161161, + "95.0" : 0.06201947467161161, + "99.0" : 0.06201947467161161, + "99.9" : 0.06201947467161161, + "99.99" : 0.06201947467161161, + "99.999" : 0.06201947467161161, + "99.9999" : 0.06201947467161161, + "100.0" : 0.06201947467161161 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06167753843070015, + 0.0616939214339916, + 0.06148453356082265 + ], + [ + 0.061730150100618525, + 0.06168849578981784, + 0.06183821364878737 + ], + [ + 0.0619587773110285, + 0.06201947467161161, + 0.061961032237877495 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7475232240008607E-4, + "scoreError" : 1.2599051816234049E-5, + "scoreConfidence" : [ + 3.62153270583852E-4, + 3.873513742163201E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6686498471328336E-4, + "50.0" : 3.731783481611584E-4, + "90.0" : 3.8423162303683427E-4, + "95.0" : 3.8423162303683427E-4, + "99.0" : 3.8423162303683427E-4, + "99.9" : 3.8423162303683427E-4, + "99.99" : 3.8423162303683427E-4, + "99.999" : 3.8423162303683427E-4, + "99.9999" : 3.8423162303683427E-4, + "100.0" : 3.8423162303683427E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7298764866361634E-4, + 3.731783481611584E-4, + 3.735189434301613E-4 + ], + [ + 3.8423162303683427E-4, + 3.84173949945471E-4, + 3.8379800995952856E-4 + ], + [ + 3.6686498471328336E-4, + 3.6702205385880045E-4, + 3.6699533983192086E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014140536648291398, + "scoreError" : 2.9374731934949075E-5, + "scoreConfidence" : [ + 0.01411116191635645, + 0.014169911380226347 + ], + "scorePercentiles" : { + "0.0" : 0.014115446296996832, + "50.0" : 0.014134114425519104, + "90.0" : 0.014178302476496185, + "95.0" : 0.014178302476496185, + "99.0" : 0.014178302476496185, + "99.9" : 0.014178302476496185, + "99.99" : 0.014178302476496185, + "99.999" : 0.014178302476496185, + "99.9999" : 0.014178302476496185, + "100.0" : 0.014178302476496185 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014115446296996832, + 0.01413876408802675, + 0.014134114425519104 + ], + [ + 0.014178302476496185, + 0.014151227157331673, + 0.014148102450991488 + ], + [ + 0.01413344815772737, + 0.014132977418616285, + 0.014132447362916902 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9932611928230904, + "scoreError" : 0.024257323453275522, + "scoreConfidence" : [ + 0.969003869369815, + 1.017518516276366 + ], + "scorePercentiles" : { + "0.0" : 0.9739963147643164, + "50.0" : 0.9965134862495018, + "90.0" : 1.0099352177337912, + "95.0" : 1.0099352177337912, + "99.0" : 1.0099352177337912, + "99.9" : 1.0099352177337912, + "99.99" : 1.0099352177337912, + "99.999" : 1.0099352177337912, + "99.9999" : 1.0099352177337912, + "100.0" : 1.0099352177337912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9739963147643164, + 0.9766263461914062, + 0.9746201055452685 + ], + [ + 1.0033032107744784, + 1.0099352177337912, + 1.0079804976312872 + ], + [ + 0.9952722825437899, + 0.9965134862495018, + 1.001103273973974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012913305599668646, + "scoreError" : 1.3451547784434068E-4, + "scoreConfidence" : [ + 0.012778790121824306, + 0.013047821077512987 + ], + "scorePercentiles" : { + "0.0" : 0.012815936662497309, + "50.0" : 0.012931272408566084, + "90.0" : 0.012941176037145452, + "95.0" : 0.012941176037145452, + "99.0" : 0.012941176037145452, + "99.9" : 0.012941176037145452, + "99.99" : 0.012941176037145452, + "99.999" : 0.012941176037145452, + "99.9999" : 0.012941176037145452, + "100.0" : 0.012941176037145452 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012815936662497309, + 0.012941176037145452, + 0.012925974531250405 + ], + [ + 0.012934201549986549, + 0.012932876422251133, + 0.012929668394881038 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.621569585832803, + "scoreError" : 0.06695805853852926, + "scoreConfidence" : [ + 3.554611527294274, + 3.6885276443713324 + ], + "scorePercentiles" : { + "0.0" : 3.5804726342161777, + "50.0" : 3.619984607755292, + "90.0" : 3.646612061953353, + "95.0" : 3.646612061953353, + "99.0" : 3.646612061953353, + "99.9" : 3.646612061953353, + "99.99" : 3.646612061953353, + "99.999" : 3.646612061953353, + "99.9999" : 3.646612061953353, + "100.0" : 3.646612061953353 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6192033798842256, + 3.64428997596504, + 3.646612061953353 + ], + [ + 3.5804726342161777, + 3.620765835626358, + 3.6180736273516643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.817315562985054, + "scoreError" : 0.06309278853592672, + "scoreConfidence" : [ + 2.754222774449127, + 2.880408351520981 + ], + "scorePercentiles" : { + "0.0" : 2.7663685322268328, + "50.0" : 2.8407819358136894, + "90.0" : 2.8458255546385884, + "95.0" : 2.8458255546385884, + "99.0" : 2.8458255546385884, + "99.9" : 2.8458255546385884, + "99.99" : 2.8458255546385884, + "99.999" : 2.8458255546385884, + "99.9999" : 2.8458255546385884, + "100.0" : 2.8458255546385884 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8458255546385884, + 2.842856151506538, + 2.845687959601707 + ], + [ + 2.7663685322268328, + 2.7678247785773595, + 2.768014618045945 + ], + [ + 2.8407819358136894, + 2.84237150951975, + 2.8361090269350724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17466291628472425, + "scoreError" : 0.0010892299205336289, + "scoreConfidence" : [ + 0.17357368636419063, + 0.17575214620525786 + ], + "scorePercentiles" : { + "0.0" : 0.1736334279959718, + "50.0" : 0.17477649892514463, + "90.0" : 0.17539436958046864, + "95.0" : 0.17539436958046864, + "99.0" : 0.17539436958046864, + "99.9" : 0.17539436958046864, + "99.99" : 0.17539436958046864, + "99.999" : 0.17539436958046864, + "99.9999" : 0.17539436958046864, + "100.0" : 0.17539436958046864 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17439916790777976, + 0.17477649892514463, + 0.1743388813479542 + ], + [ + 0.17520865829770832, + 0.17515058082143795, + 0.17524262767020066 + ], + [ + 0.17539436958046864, + 0.17382203401585206, + 0.1736334279959718 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3274353774579488, + "scoreError" : 0.016014656619373645, + "scoreConfidence" : [ + 0.3114207208385752, + 0.34345003407732244 + ], + "scorePercentiles" : { + "0.0" : 0.31721999308485327, + "50.0" : 0.32569945065789474, + "90.0" : 0.33981387947262903, + "95.0" : 0.33981387947262903, + "99.0" : 0.33981387947262903, + "99.9" : 0.33981387947262903, + "99.99" : 0.33981387947262903, + "99.999" : 0.33981387947262903, + "99.9999" : 0.33981387947262903, + "100.0" : 0.33981387947262903 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31730455720903666, + 0.31721999308485327, + 0.31775410793721404 + ], + [ + 0.3257833393927548, + 0.3255280544596354, + 0.32569945065789474 + ], + [ + 0.33981387947262903, + 0.3387748820759511, + 0.33904013283157036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16641532323284058, + "scoreError" : 0.017350118915669347, + "scoreConfidence" : [ + 0.14906520431717124, + 0.18376544214850993 + ], + "scorePercentiles" : { + "0.0" : 0.15270957588760786, + "50.0" : 0.17205132084853073, + "90.0" : 0.174647807174418, + "95.0" : 0.174647807174418, + "99.0" : 0.174647807174418, + "99.9" : 0.174647807174418, + "99.99" : 0.174647807174418, + "99.999" : 0.174647807174418, + "99.9999" : 0.174647807174418, + "100.0" : 0.174647807174418 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17205132084853073, + 0.17206169996558843, + 0.17200997505934157 + ], + [ + 0.1527471536910599, + 0.1527100326945102, + 0.15270957588760786 + ], + [ + 0.17458898942020637, + 0.174647807174418, + 0.17421135435430204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38986128538799675, + "scoreError" : 0.00979797094307402, + "scoreConfidence" : [ + 0.38006331444492275, + 0.39965925633107074 + ], + "scorePercentiles" : { + "0.0" : 0.3846523111393184, + "50.0" : 0.3872767771280304, + "90.0" : 0.3985590201665936, + "95.0" : 0.3985590201665936, + "99.0" : 0.3985590201665936, + "99.9" : 0.3985590201665936, + "99.99" : 0.3985590201665936, + "99.999" : 0.3985590201665936, + "99.9999" : 0.3985590201665936, + "100.0" : 0.3985590201665936 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3872767771280304, + 0.38737736459422817, + 0.3867428934565705 + ], + [ + 0.3985590201665936, + 0.39697225658939345, + 0.39697280100035726 + ], + [ + 0.38533757949291, + 0.384860564924569, + 0.3846523111393184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15609274809169155, + "scoreError" : 0.0036412484112455373, + "scoreConfidence" : [ + 0.15245149968044602, + 0.15973399650293707 + ], + "scorePercentiles" : { + "0.0" : 0.15436526028433387, + "50.0" : 0.15480616190903743, + "90.0" : 0.15913727148313175, + "95.0" : 0.15913727148313175, + "99.0" : 0.15913727148313175, + "99.9" : 0.15913727148313175, + "99.99" : 0.15913727148313175, + "99.999" : 0.15913727148313175, + "99.9999" : 0.15913727148313175, + "100.0" : 0.15913727148313175 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15436526028433387, + 0.1544817916550808, + 0.15470838450471078 + ], + [ + 0.15882465640683566, + 0.15913727148313175, + 0.15895154913928758 + ], + [ + 0.15495011549784624, + 0.1546095419449598, + 0.15480616190903743 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04758667191926049, + "scoreError" : 0.0023739868350441734, + "scoreConfidence" : [ + 0.04521268508421632, + 0.049960658754304665 + ], + "scorePercentiles" : { + "0.0" : 0.04611377217810733, + "50.0" : 0.04710306553369477, + "90.0" : 0.04951102378960189, + "95.0" : 0.04951102378960189, + "99.0" : 0.04951102378960189, + "99.9" : 0.04951102378960189, + "99.99" : 0.04951102378960189, + "99.999" : 0.04951102378960189, + "99.9999" : 0.04951102378960189, + "100.0" : 0.04951102378960189 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04951102378960189, + 0.049440907275109386, + 0.0491906721874339 + ], + [ + 0.047310086098574095, + 0.04710306553369477, + 0.047064187063192126 + ], + [ + 0.04642925747502136, + 0.04611377217810733, + 0.04611707567260955 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9395685.427692974, + "scoreError" : 239163.15498882558, + "scoreConfidence" : [ + 9156522.272704149, + 9634848.5826818 + ], + "scorePercentiles" : { + "0.0" : 9199383.375919119, + "50.0" : 9405962.368421054, + "90.0" : 9559300.52244508, + "95.0" : 9559300.52244508, + "99.0" : 9559300.52244508, + "99.9" : 9559300.52244508, + "99.99" : 9559300.52244508, + "99.999" : 9559300.52244508, + "99.9999" : 9559300.52244508, + "100.0" : 9559300.52244508 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9410055.000940735, + 9405962.368421054, + 9405348.242481204 + ], + [ + 9268332.786839666, + 9214277.049723757, + 9199383.375919119 + ], + [ + 9559300.52244508, + 9544774.91793893, + 9553734.58452722 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-04T05:27:30Z-6eb2616cb700661d6c433a8ffbc7e0feb045b19a-jdk17.json b/performance-results/2025-04-04T05:27:30Z-6eb2616cb700661d6c433a8ffbc7e0feb045b19a-jdk17.json new file mode 100644 index 0000000000..863d559e57 --- /dev/null +++ b/performance-results/2025-04-04T05:27:30Z-6eb2616cb700661d6c433a8ffbc7e0feb045b19a-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.41547431211834, + "scoreError" : 0.02013445470791421, + "scoreConfidence" : [ + 3.395339857410426, + 3.4356087668262543 + ], + "scorePercentiles" : { + "0.0" : 3.411373024163593, + "50.0" : 3.415796403863652, + "90.0" : 3.418931416582463, + "95.0" : 3.418931416582463, + "99.0" : 3.418931416582463, + "99.9" : 3.418931416582463, + "99.99" : 3.418931416582463, + "99.999" : 3.418931416582463, + "99.9999" : 3.418931416582463, + "100.0" : 3.418931416582463 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4160661756130946, + 3.418931416582463 + ], + [ + 3.411373024163593, + 3.4155266321142097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7257794060486682, + "scoreError" : 0.014829676059242635, + "scoreConfidence" : [ + 1.7109497299894256, + 1.7406090821079108 + ], + "scorePercentiles" : { + "0.0" : 1.7229459392720967, + "50.0" : 1.7260640883842262, + "90.0" : 1.728043508154123, + "95.0" : 1.728043508154123, + "99.0" : 1.728043508154123, + "99.9" : 1.728043508154123, + "99.99" : 1.728043508154123, + "99.999" : 1.728043508154123, + "99.9999" : 1.728043508154123, + "100.0" : 1.728043508154123 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7229459392720967, + 1.7249498535300087 + ], + [ + 1.728043508154123, + 1.727178323238444 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8670239652165881, + "scoreError" : 0.0038232692313808036, + "scoreConfidence" : [ + 0.8632006959852073, + 0.8708472344479689 + ], + "scorePercentiles" : { + "0.0" : 0.8664786283013596, + "50.0" : 0.8669751735844602, + "90.0" : 0.8676668853960727, + "95.0" : 0.8676668853960727, + "99.0" : 0.8676668853960727, + "99.9" : 0.8676668853960727, + "99.99" : 0.8676668853960727, + "99.999" : 0.8676668853960727, + "99.9999" : 0.8676668853960727, + "100.0" : 0.8676668853960727 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8664786283013596, + 0.8665661091157533 + ], + [ + 0.867384238053167, + 0.8676668853960727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.257614896779337, + "scoreError" : 0.2156823417456936, + "scoreConfidence" : [ + 16.041932555033643, + 16.47329723852503 + ], + "scorePercentiles" : { + "0.0" : 16.046117112775594, + "50.0" : 16.351278502311153, + "90.0" : 16.358823560420063, + "95.0" : 16.358823560420063, + "99.0" : 16.358823560420063, + "99.9" : 16.358823560420063, + "99.99" : 16.358823560420063, + "99.999" : 16.358823560420063, + "99.9999" : 16.358823560420063, + "100.0" : 16.358823560420063 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.132712758895906, + 16.105581835399015, + 16.046117112775594 + ], + [ + 16.356463835561264, + 16.358823560420063, + 16.351278502311153 + ], + [ + 16.254642767027285, + 16.35464668287753, + 16.3582670157462 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2657.7695720704037, + "scoreError" : 148.2972269158939, + "scoreConfidence" : [ + 2509.4723451545096, + 2806.0667989862977 + ], + "scorePercentiles" : { + "0.0" : 2539.768121859389, + "50.0" : 2706.007591520502, + "90.0" : 2728.2643986587595, + "95.0" : 2728.2643986587595, + "99.0" : 2728.2643986587595, + "99.9" : 2728.2643986587595, + "99.99" : 2728.2643986587595, + "99.999" : 2728.2643986587595, + "99.9999" : 2728.2643986587595, + "100.0" : 2728.2643986587595 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2702.1623484921656, + 2707.919946005747, + 2706.007591520502 + ], + [ + 2540.1588945402596, + 2539.768121859389, + 2542.476993406105 + ], + [ + 2725.722525637147, + 2728.2643986587595, + 2727.4453285135583 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69187.62949561818, + "scoreError" : 1950.2487427776907, + "scoreConfidence" : [ + 67237.38075284049, + 71137.87823839588 + ], + "scorePercentiles" : { + "0.0" : 67811.69749602833, + "50.0" : 69182.75188864459, + "90.0" : 70554.04343863564, + "95.0" : 70554.04343863564, + "99.0" : 70554.04343863564, + "99.9" : 70554.04343863564, + "99.99" : 70554.04343863564, + "99.999" : 70554.04343863564, + "99.9999" : 70554.04343863564, + "100.0" : 70554.04343863564 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70489.37946132944, + 70554.04343863564, + 70515.75586998963 + ], + [ + 67864.5403327218, + 67811.69749602833, + 67845.50582086251 + ], + [ + 69182.75188864459, + 69171.5162798034, + 69253.47487254828 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 351.14686595143564, + "scoreError" : 12.402276547808718, + "scoreConfidence" : [ + 338.74458940362695, + 363.54914249924434 + ], + "scorePercentiles" : { + "0.0" : 341.4050740261924, + "50.0" : 350.9959831827741, + "90.0" : 361.14535751562823, + "95.0" : 361.14535751562823, + "99.0" : 361.14535751562823, + "99.9" : 361.14535751562823, + "99.99" : 361.14535751562823, + "99.999" : 361.14535751562823, + "99.9999" : 361.14535751562823, + "100.0" : 361.14535751562823 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 341.4050740261924, + 341.75306137898, + 345.9414385143761 + ], + [ + 349.9015669158507, + 350.9959831827741, + 351.72342119398223 + ], + [ + 360.81338018128395, + 361.14535751562823, + 356.64251065385264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.33465576346994, + "scoreError" : 5.16876703445678, + "scoreConfidence" : [ + 100.16588872901316, + 110.50342279792672 + ], + "scorePercentiles" : { + "0.0" : 101.2422526340046, + "50.0" : 105.98517929748999, + "90.0" : 108.60769860695804, + "95.0" : 108.60769860695804, + "99.0" : 108.60769860695804, + "99.9" : 108.60769860695804, + "99.99" : 108.60769860695804, + "99.999" : 108.60769860695804, + "99.9999" : 108.60769860695804, + "100.0" : 108.60769860695804 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.47585305815755, + 108.51299893266345, + 108.60769860695804 + ], + [ + 101.2422526340046, + 101.66996889742603, + 101.63790810097589 + ], + [ + 105.88856190695395, + 105.98517929748999, + 105.99148043659996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0613835700776904, + "scoreError" : 5.30970211986948E-4, + "scoreConfidence" : [ + 0.060852599865703454, + 0.06191454028967735 + ], + "scorePercentiles" : { + "0.0" : 0.06095189772408665, + "50.0" : 0.061378639564216665, + "90.0" : 0.06184695769116592, + "95.0" : 0.06184695769116592, + "99.0" : 0.06184695769116592, + "99.9" : 0.06184695769116592, + "99.99" : 0.06184695769116592, + "99.999" : 0.06184695769116592, + "99.9999" : 0.06184695769116592, + "100.0" : 0.06184695769116592 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06144970979555971, + 0.06122663911100226, + 0.061378639564216665 + ], + [ + 0.061581722824346624, + 0.06179943338112424, + 0.06184695769116592 + ], + [ + 0.06095189772408665, + 0.06105782843047466, + 0.06115930217723686 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6792774673077264E-4, + "scoreError" : 9.52400144527695E-6, + "scoreConfidence" : [ + 3.584037452854957E-4, + 3.774517481760496E-4 + ], + "scorePercentiles" : { + "0.0" : 3.601947262437733E-4, + "50.0" : 3.710066787160918E-4, + "90.0" : 3.7284325731862846E-4, + "95.0" : 3.7284325731862846E-4, + "99.0" : 3.7284325731862846E-4, + "99.9" : 3.7284325731862846E-4, + "99.99" : 3.7284325731862846E-4, + "99.999" : 3.7284325731862846E-4, + "99.9999" : 3.7284325731862846E-4, + "100.0" : 3.7284325731862846E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.606764144071223E-4, + 3.601947262437733E-4, + 3.603632293866587E-4 + ], + [ + 3.716483250039227E-4, + 3.721081112498685E-4, + 3.7284325731862846E-4 + ], + [ + 3.70884520477737E-4, + 3.71624457773151E-4, + 3.710066787160918E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01402845854457803, + "scoreError" : 4.044676667384548E-5, + "scoreConfidence" : [ + 0.013988011777904185, + 0.014068905311251876 + ], + "scorePercentiles" : { + "0.0" : 0.013993197164454371, + "50.0" : 0.01404240319713314, + "90.0" : 0.014049538132783347, + "95.0" : 0.014049538132783347, + "99.0" : 0.014049538132783347, + "99.9" : 0.014049538132783347, + "99.99" : 0.014049538132783347, + "99.999" : 0.014049538132783347, + "99.9999" : 0.014049538132783347, + "100.0" : 0.014049538132783347 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014000710592155463, + 0.013993197164454371, + 0.013996113428682996 + ], + [ + 0.014042536027781405, + 0.014049538132783347, + 0.01404240319713314 + ], + [ + 0.0140474361495304, + 0.014043828995948403, + 0.014040363212732769 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9794412564438721, + "scoreError" : 0.01637443287226072, + "scoreConfidence" : [ + 0.9630668235716114, + 0.9958156893161328 + ], + "scorePercentiles" : { + "0.0" : 0.9663152830225142, + "50.0" : 0.9845775188539924, + "90.0" : 0.9877359903209877, + "95.0" : 0.9877359903209877, + "99.0" : 0.9877359903209877, + "99.9" : 0.9877359903209877, + "99.99" : 0.9877359903209877, + "99.999" : 0.9877359903209877, + "99.9999" : 0.9877359903209877, + "100.0" : 0.9877359903209877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9665899604678136, + 0.9669146041767379, + 0.9663152830225142 + ], + [ + 0.9829151665028504, + 0.9853623369790128, + 0.9845775188539924 + ], + [ + 0.9871915410661402, + 0.9873689066047981, + 0.9877359903209877 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013066821965947481, + "scoreError" : 1.4899924544193566E-4, + "scoreConfidence" : [ + 0.012917822720505545, + 0.013215821211389417 + ], + "scorePercentiles" : { + "0.0" : 0.013011505698910181, + "50.0" : 0.01306633020899141, + "90.0" : 0.013123710692154048, + "95.0" : 0.013123710692154048, + "99.0" : 0.013123710692154048, + "99.9" : 0.013123710692154048, + "99.99" : 0.013123710692154048, + "99.999" : 0.013123710692154048, + "99.9999" : 0.013123710692154048, + "100.0" : 0.013123710692154048 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0131095357868546, + 0.013123710692154048, + 0.013111727565707873 + ], + [ + 0.01302312463112822, + 0.013011505698910181, + 0.01302132742092996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6016004776114623, + "scoreError" : 0.04408562358601525, + "scoreConfidence" : [ + 3.557514854025447, + 3.6456861011974775 + ], + "scorePercentiles" : { + "0.0" : 3.5702578772305498, + "50.0" : 3.6067730656092287, + "90.0" : 3.613936494219653, + "95.0" : 3.613936494219653, + "99.0" : 3.613936494219653, + "99.9" : 3.613936494219653, + "99.99" : 3.613936494219653, + "99.999" : 3.613936494219653, + "99.9999" : 3.613936494219653, + "100.0" : 3.613936494219653 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5702578772305498, + 3.613936494219653, + 3.6067297692862295 + ], + [ + 3.608194422077922, + 3.606816361932228, + 3.60366794092219 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7855132821873965, + "scoreError" : 0.026726483277009803, + "scoreConfidence" : [ + 2.7587867989103865, + 2.8122397654644065 + ], + "scorePercentiles" : { + "0.0" : 2.759536437637969, + "50.0" : 2.786476934522151, + "90.0" : 2.8075433060078607, + "95.0" : 2.8075433060078607, + "99.0" : 2.8075433060078607, + "99.9" : 2.8075433060078607, + "99.99" : 2.8075433060078607, + "99.999" : 2.8075433060078607, + "99.9999" : 2.8075433060078607, + "100.0" : 2.8075433060078607 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.786476934522151, + 2.7926873155543146, + 2.7885715913019236 + ], + [ + 2.759536437637969, + 2.7736968960066557, + 2.7713081041839844 + ], + [ + 2.8075433060078607, + 2.806818850687623, + 2.7829801037840847 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1761613666321471, + "scoreError" : 0.002516338259768568, + "scoreConfidence" : [ + 0.17364502837237852, + 0.17867770489191567 + ], + "scorePercentiles" : { + "0.0" : 0.17409059075953554, + "50.0" : 0.1760895962564491, + "90.0" : 0.17804075546574563, + "95.0" : 0.17804075546574563, + "99.0" : 0.17804075546574563, + "99.9" : 0.17804075546574563, + "99.99" : 0.17804075546574563, + "99.999" : 0.17804075546574563, + "99.9999" : 0.17804075546574563, + "100.0" : 0.17804075546574563 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17804075546574563, + 0.1777888090954345, + 0.17770007303290924 + ], + [ + 0.17501571777594988, + 0.17409059075953554, + 0.1742418977227188 + ], + [ + 0.1764508362211949, + 0.1760895962564491, + 0.176034023359386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32730021817444466, + "scoreError" : 0.017163920712541466, + "scoreConfidence" : [ + 0.3101362974619032, + 0.3444641388869861 + ], + "scorePercentiles" : { + "0.0" : 0.31596479819905215, + "50.0" : 0.3256441752906314, + "90.0" : 0.3405568089562404, + "95.0" : 0.3405568089562404, + "99.0" : 0.3405568089562404, + "99.9" : 0.3405568089562404, + "99.99" : 0.3405568089562404, + "99.999" : 0.3405568089562404, + "99.9999" : 0.3405568089562404, + "100.0" : 0.3405568089562404 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3388611753244553, + 0.3405568089562404, + 0.33991513701563564 + ], + [ + 0.3256005505160681, + 0.3259885275287675, + 0.3256441752906314 + ], + [ + 0.31713970326324803, + 0.316031087475903, + 0.31596479819905215 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1652042889286885, + "scoreError" : 0.0017617414374246191, + "scoreConfidence" : [ + 0.16344254749126388, + 0.1669660303661131 + ], + "scorePercentiles" : { + "0.0" : 0.163923576657651, + "50.0" : 0.16483931719579337, + "90.0" : 0.16660534148007464, + "95.0" : 0.16660534148007464, + "99.0" : 0.16660534148007464, + "99.9" : 0.16660534148007464, + "99.99" : 0.16660534148007464, + "99.999" : 0.16660534148007464, + "99.9999" : 0.16660534148007464, + "100.0" : 0.16660534148007464 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16660534148007464, + 0.16656146767934177, + 0.1663387481328698 + ], + [ + 0.16394726561962064, + 0.163923576657651, + 0.16483931719579337 + ], + [ + 0.16482515006922469, + 0.16480627729527514, + 0.16499145622834516 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39010744239973744, + "scoreError" : 0.01670421567031333, + "scoreConfidence" : [ + 0.3734032267294241, + 0.40681165807005076 + ], + "scorePercentiles" : { + "0.0" : 0.37962961616430035, + "50.0" : 0.38764850711323023, + "90.0" : 0.40918921207905395, + "95.0" : 0.40918921207905395, + "99.0" : 0.40918921207905395, + "99.9" : 0.40918921207905395, + "99.99" : 0.40918921207905395, + "99.999" : 0.40918921207905395, + "99.9999" : 0.40918921207905395, + "100.0" : 0.40918921207905395 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3897532790552654, + 0.3830618254807324, + 0.38492263564280216 + ], + [ + 0.40918921207905395, + 0.3987026886213221, + 0.39790933049498645 + ], + [ + 0.38764850711323023, + 0.38014988694594387, + 0.37962961616430035 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15589403072362684, + "scoreError" : 0.0019617589008532423, + "scoreConfidence" : [ + 0.1539322718227736, + 0.15785578962448008 + ], + "scorePercentiles" : { + "0.0" : 0.15429051936310056, + "50.0" : 0.15572938609359183, + "90.0" : 0.15757248833984622, + "95.0" : 0.15757248833984622, + "99.0" : 0.15757248833984622, + "99.9" : 0.15757248833984622, + "99.99" : 0.15757248833984622, + "99.999" : 0.15757248833984622, + "99.9999" : 0.15757248833984622, + "100.0" : 0.15757248833984622 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15757248833984622, + 0.15724325976068054, + 0.15697942648813262 + ], + [ + 0.1552752374578824, + 0.15445985558284292, + 0.15429051936310056 + ], + [ + 0.15580430851445043, + 0.1556917949121141, + 0.15572938609359183 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046893268004107674, + "scoreError" : 0.001162133260808305, + "scoreConfidence" : [ + 0.045731134743299366, + 0.04805540126491598 + ], + "scorePercentiles" : { + "0.0" : 0.04607961999179795, + "50.0" : 0.04681437227603189, + "90.0" : 0.04772420759282237, + "95.0" : 0.04772420759282237, + "99.0" : 0.04772420759282237, + "99.9" : 0.04772420759282237, + "99.99" : 0.04772420759282237, + "99.999" : 0.04772420759282237, + "99.9999" : 0.04772420759282237, + "100.0" : 0.04772420759282237 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047255712641233925, + 0.04681437227603189, + 0.04675393894029146 + ], + [ + 0.04772420759282237, + 0.0476040818683385, + 0.0476215452255324 + ], + [ + 0.04608960344652766, + 0.04609633005439292, + 0.04607961999179795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9247386.677157959, + "scoreError" : 103775.56890511974, + "scoreConfidence" : [ + 9143611.10825284, + 9351162.246063078 + ], + "scorePercentiles" : { + "0.0" : 9170927.29422548, + "50.0" : 9251081.91119334, + "90.0" : 9346239.112149533, + "95.0" : 9346239.112149533, + "99.0" : 9346239.112149533, + "99.9" : 9346239.112149533, + "99.99" : 9346239.112149533, + "99.999" : 9346239.112149533, + "99.9999" : 9346239.112149533, + "100.0" : 9346239.112149533 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9251081.91119334, + 9249757.321626617, + 9258786.827012027 + ], + [ + 9170927.29422548, + 9172337.738771768, + 9183301.19651056 + ], + [ + 9346239.112149533, + 9303166.288104089, + 9290882.404828226 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-06T04:21:24Z-31b5f1b83c785c1acaff247c88aca6763328b754-jdk17.json b/performance-results/2025-04-06T04:21:24Z-31b5f1b83c785c1acaff247c88aca6763328b754-jdk17.json new file mode 100644 index 0000000000..1399ed8956 --- /dev/null +++ b/performance-results/2025-04-06T04:21:24Z-31b5f1b83c785c1acaff247c88aca6763328b754-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.405781402066154, + "scoreError" : 0.04629911913002043, + "scoreConfidence" : [ + 3.3594822829361335, + 3.4520805211961743 + ], + "scorePercentiles" : { + "0.0" : 3.396624620926415, + "50.0" : 3.4062908345364202, + "90.0" : 3.4139193182653607, + "95.0" : 3.4139193182653607, + "99.0" : 3.4139193182653607, + "99.9" : 3.4139193182653607, + "99.99" : 3.4139193182653607, + "99.999" : 3.4139193182653607, + "99.9999" : 3.4139193182653607, + "100.0" : 3.4139193182653607 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4049844214875487, + 3.4139193182653607 + ], + [ + 3.396624620926415, + 3.407597247585292 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7201965667995456, + "scoreError" : 0.014319793782545227, + "scoreConfidence" : [ + 1.7058767730170004, + 1.7345163605820908 + ], + "scorePercentiles" : { + "0.0" : 1.717273001278032, + "50.0" : 1.7204317124975719, + "90.0" : 1.722649840925006, + "95.0" : 1.722649840925006, + "99.0" : 1.722649840925006, + "99.9" : 1.722649840925006, + "99.99" : 1.722649840925006, + "99.999" : 1.722649840925006, + "99.9999" : 1.722649840925006, + "100.0" : 1.722649840925006 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.722649840925006, + 1.717273001278032 + ], + [ + 1.7205985118976679, + 1.7202649130974759 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8645438475526157, + "scoreError" : 0.006962670109372867, + "scoreConfidence" : [ + 0.8575811774432428, + 0.8715065176619886 + ], + "scorePercentiles" : { + "0.0" : 0.8630685172427868, + "50.0" : 0.8647808022374026, + "90.0" : 0.8655452684928708, + "95.0" : 0.8655452684928708, + "99.0" : 0.8655452684928708, + "99.9" : 0.8655452684928708, + "99.99" : 0.8655452684928708, + "99.999" : 0.8655452684928708, + "99.9999" : 0.8655452684928708, + "100.0" : 0.8655452684928708 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8630685172427868, + 0.8650899598383918 + ], + [ + 0.8644716446364135, + 0.8655452684928708 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.05989386004153, + "scoreError" : 0.3259215020951166, + "scoreConfidence" : [ + 15.733972357946413, + 16.385815362136647 + ], + "scorePercentiles" : { + "0.0" : 15.72532512446189, + "50.0" : 16.158593388145643, + "90.0" : 16.20446067632027, + "95.0" : 16.20446067632027, + "99.0" : 16.20446067632027, + "99.9" : 16.20446067632027, + "99.99" : 16.20446067632027, + "99.999" : 16.20446067632027, + "99.9999" : 16.20446067632027, + "100.0" : 16.20446067632027 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.967443811944504, + 15.72532512446189, + 15.760029346712017 + ], + [ + 16.150287625332755, + 16.19410303415797, + 16.20446067632027 + ], + [ + 16.198468930460553, + 16.180332802838194, + 16.158593388145643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2756.8020116085313, + "scoreError" : 91.39304598010132, + "scoreConfidence" : [ + 2665.40896562843, + 2848.1950575886326 + ], + "scorePercentiles" : { + "0.0" : 2690.356683491557, + "50.0" : 2750.4605046843676, + "90.0" : 2845.5252577614933, + "95.0" : 2845.5252577614933, + "99.0" : 2845.5252577614933, + "99.9" : 2845.5252577614933, + "99.99" : 2845.5252577614933, + "99.999" : 2845.5252577614933, + "99.9999" : 2845.5252577614933, + "100.0" : 2845.5252577614933 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2791.045225296556, + 2741.798957219609, + 2783.3375517726395 + ], + [ + 2690.7068308911184, + 2709.71805278636, + 2690.356683491557 + ], + [ + 2845.5252577614933, + 2808.2690405730837, + 2750.4605046843676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 68533.4742069145, + "scoreError" : 2439.3220251166053, + "scoreConfidence" : [ + 66094.1521817979, + 70972.7962320311 + ], + "scorePercentiles" : { + "0.0" : 66835.83632727223, + "50.0" : 68487.06242377267, + "90.0" : 70252.10139834581, + "95.0" : 70252.10139834581, + "99.0" : 70252.10139834581, + "99.9" : 70252.10139834581, + "99.99" : 70252.10139834581, + "99.999" : 70252.10139834581, + "99.9999" : 70252.10139834581, + "100.0" : 70252.10139834581 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70219.46335615995, + 70252.10139834581, + 70226.14046013122 + ], + [ + 66900.3928975727, + 66835.83632727223, + 66909.21094385958 + ], + [ + 68454.6761328727, + 68516.38392224368, + 68487.06242377267 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 337.52855496465264, + "scoreError" : 9.658309838793654, + "scoreConfidence" : [ + 327.870245125859, + 347.18686480344627 + ], + "scorePercentiles" : { + "0.0" : 327.3231459328245, + "50.0" : 339.70911503866444, + "90.0" : 342.52691897035885, + "95.0" : 342.52691897035885, + "99.0" : 342.52691897035885, + "99.9" : 342.52691897035885, + "99.99" : 342.52691897035885, + "99.999" : 342.52691897035885, + "99.9999" : 342.52691897035885, + "100.0" : 342.52691897035885 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 340.36259544413855, + 339.3679710278199, + 339.70911503866444 + ], + [ + 327.3231459328245, + 329.51373715892254, + 334.41701909854896 + ], + [ + 342.02520640669826, + 342.52691897035885, + 342.5112856038977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.56678718393282, + "scoreError" : 0.8035552983655688, + "scoreConfidence" : [ + 106.76323188556725, + 108.37034248229838 + ], + "scorePercentiles" : { + "0.0" : 106.96254754530847, + "50.0" : 107.6430612124555, + "90.0" : 108.25459860591951, + "95.0" : 108.25459860591951, + "99.0" : 108.25459860591951, + "99.9" : 108.25459860591951, + "99.99" : 108.25459860591951, + "99.999" : 108.25459860591951, + "99.9999" : 108.25459860591951, + "100.0" : 108.25459860591951 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.75910317895423, + 108.16501022003597, + 108.25459860591951 + ], + [ + 107.47077297938178, + 107.6430612124555, + 107.75656223064789 + ], + [ + 106.96254754530847, + 107.04988075523372, + 107.03954792745826 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06282593834342524, + "scoreError" : 0.00124014987561755, + "scoreConfidence" : [ + 0.0615857884678077, + 0.06406608821904279 + ], + "scorePercentiles" : { + "0.0" : 0.061971611277398725, + "50.0" : 0.06275012118093684, + "90.0" : 0.06380773513779088, + "95.0" : 0.06380773513779088, + "99.0" : 0.06380773513779088, + "99.9" : 0.06380773513779088, + "99.99" : 0.06380773513779088, + "99.999" : 0.06380773513779088, + "99.9999" : 0.06380773513779088, + "100.0" : 0.06380773513779088 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06380773513779088, + 0.06360714405566828, + 0.06368026652317607 + ], + [ + 0.06204686022919756, + 0.061971611277398725, + 0.06207596931003445 + ], + [ + 0.0630071047979082, + 0.06275012118093684, + 0.06248663257871617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7645891824443105E-4, + "scoreError" : 7.420531364522643E-6, + "scoreConfidence" : [ + 3.690383868799084E-4, + 3.838794496089537E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7083719638183197E-4, + "50.0" : 3.784746061574875E-4, + "90.0" : 3.81487875620763E-4, + "95.0" : 3.81487875620763E-4, + "99.0" : 3.81487875620763E-4, + "99.9" : 3.81487875620763E-4, + "99.99" : 3.81487875620763E-4, + "99.999" : 3.81487875620763E-4, + "99.9999" : 3.81487875620763E-4, + "100.0" : 3.81487875620763E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.81487875620763E-4, + 3.7847707489032533E-4, + 3.758967400060188E-4 + ], + [ + 3.784746061574875E-4, + 3.799740420807843E-4, + 3.808930146034486E-4 + ], + [ + 3.709759403254721E-4, + 3.7083719638183197E-4, + 3.711137741337483E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014170195070241436, + "scoreError" : 1.5374022955591253E-4, + "scoreConfidence" : [ + 0.014016454840685524, + 0.014323935299797348 + ], + "scorePercentiles" : { + "0.0" : 0.014048208614820965, + "50.0" : 0.014181384624438778, + "90.0" : 0.014275301442216413, + "95.0" : 0.014275301442216413, + "99.0" : 0.014275301442216413, + "99.9" : 0.014275301442216413, + "99.99" : 0.014275301442216413, + "99.999" : 0.014275301442216413, + "99.9999" : 0.014275301442216413, + "100.0" : 0.014275301442216413 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01408180109132642, + 0.014048208614820965, + 0.014050356922169065 + ], + [ + 0.014182106285153491, + 0.014179868830771063, + 0.014181384624438778 + ], + [ + 0.014275301442216413, + 0.014266937955287974, + 0.014265789865988764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9853098955367946, + "scoreError" : 0.021446285031264112, + "scoreConfidence" : [ + 0.9638636105055305, + 1.0067561805680587 + ], + "scorePercentiles" : { + "0.0" : 0.9752768992588258, + "50.0" : 0.9783446756016435, + "90.0" : 1.0023353015936654, + "95.0" : 1.0023353015936654, + "99.0" : 1.0023353015936654, + "99.9" : 1.0023353015936654, + "99.99" : 1.0023353015936654, + "99.999" : 1.0023353015936654, + "99.9999" : 1.0023353015936654, + "100.0" : 1.0023353015936654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0022688939667268, + 1.0023353015936654, + 1.0022084627718209 + ], + [ + 0.9752768992588258, + 0.9762894800351459, + 0.9758775303473849 + ], + [ + 0.9767574471139759, + 0.9784303691419626, + 0.9783446756016435 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013155312270424532, + "scoreError" : 2.2122281273061355E-4, + "scoreConfidence" : [ + 0.012934089457693919, + 0.013376535083155146 + ], + "scorePercentiles" : { + "0.0" : 0.01308103762286097, + "50.0" : 0.013132885895183091, + "90.0" : 0.013261304114086875, + "95.0" : 0.013261304114086875, + "99.0" : 0.013261304114086875, + "99.9" : 0.013261304114086875, + "99.99" : 0.013261304114086875, + "99.999" : 0.013261304114086875, + "99.9999" : 0.013261304114086875, + "100.0" : 0.013261304114086875 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013170846136420509, + 0.013233967485032793, + 0.013261304114086875 + ], + [ + 0.013089792610200374, + 0.013094925653945672, + 0.01308103762286097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.775777798225155, + "scoreError" : 0.054194193911174686, + "scoreConfidence" : [ + 3.7215836043139805, + 3.8299719921363296 + ], + "scorePercentiles" : { + "0.0" : 3.7556604196696695, + "50.0" : 3.7757238366945414, + "90.0" : 3.8012071276595742, + "95.0" : 3.8012071276595742, + "99.0" : 3.8012071276595742, + "99.9" : 3.8012071276595742, + "99.99" : 3.8012071276595742, + "99.999" : 3.8012071276595742, + "99.9999" : 3.8012071276595742, + "100.0" : 3.8012071276595742 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7556604196696695, + 3.788914986363636, + 3.788116437121212 + ], + [ + 3.8012071276595742, + 3.7574365822689706, + 3.7633312362678706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.997883209839679, + "scoreError" : 0.09377215361018633, + "scoreConfidence" : [ + 2.9041110562294925, + 3.091655363449865 + ], + "scorePercentiles" : { + "0.0" : 2.9241853023391813, + "50.0" : 3.0141105696202533, + "90.0" : 3.0615126179981633, + "95.0" : 3.0615126179981633, + "99.0" : 3.0615126179981633, + "99.9" : 3.0615126179981633, + "99.99" : 3.0615126179981633, + "99.999" : 3.0615126179981633, + "99.9999" : 3.0615126179981633, + "100.0" : 3.0615126179981633 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9241853023391813, + 2.9325244403400763, + 2.925960527501463 + ], + [ + 3.051239873703478, + 3.0029951573101172, + 3.0444756797564687 + ], + [ + 3.0239447199879046, + 3.0141105696202533, + 3.0615126179981633 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.177529407092993, + "scoreError" : 0.0055248675533280875, + "scoreConfidence" : [ + 0.1720045395396649, + 0.1830542746463211 + ], + "scorePercentiles" : { + "0.0" : 0.17486462843603554, + "50.0" : 0.1756732380324989, + "90.0" : 0.18216117268388649, + "95.0" : 0.18216117268388649, + "99.0" : 0.18216117268388649, + "99.9" : 0.18216117268388649, + "99.99" : 0.18216117268388649, + "99.999" : 0.18216117268388649, + "99.9999" : 0.18216117268388649, + "100.0" : 0.18216117268388649 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17616140713794987, + 0.17548674602533956, + 0.1750206234314017 + ], + [ + 0.18172378042885698, + 0.18174547134834523, + 0.18216117268388649 + ], + [ + 0.1756732380324989, + 0.17492759631262245, + 0.17486462843603554 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32976828318298224, + "scoreError" : 0.010628414016052913, + "scoreConfidence" : [ + 0.3191398691669293, + 0.34039669719903515 + ], + "scorePercentiles" : { + "0.0" : 0.3216373301492345, + "50.0" : 0.33094866118410166, + "90.0" : 0.3368310063659941, + "95.0" : 0.3368310063659941, + "99.0" : 0.3368310063659941, + "99.9" : 0.3368310063659941, + "99.99" : 0.3368310063659941, + "99.999" : 0.3368310063659941, + "99.9999" : 0.3368310063659941, + "100.0" : 0.3368310063659941 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3368310063659941, + 0.33574312472302426, + 0.33595367309436625 + ], + [ + 0.33283418678027027, + 0.32985339994062735, + 0.33094866118410166 + ], + [ + 0.32246368138140075, + 0.3216373301492345, + 0.32164948502782154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16037060522180674, + "scoreError" : 0.011186335452461017, + "scoreConfidence" : [ + 0.14918426976934573, + 0.17155694067426774 + ], + "scorePercentiles" : { + "0.0" : 0.15342508020865295, + "50.0" : 0.15895105458244588, + "90.0" : 0.16888263868341946, + "95.0" : 0.16888263868341946, + "99.0" : 0.16888263868341946, + "99.9" : 0.16888263868341946, + "99.99" : 0.16888263868341946, + "99.999" : 0.16888263868341946, + "99.9999" : 0.16888263868341946, + "100.0" : 0.16888263868341946 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16888263868341946, + 0.16861914202610193, + 0.16854025700273031 + ], + [ + 0.1535660718980344, + 0.15342508020865295, + 0.15356292708957173 + ], + [ + 0.15895105458244588, + 0.15883483265565437, + 0.15895344284964952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3861324143689894, + "scoreError" : 0.003575572767244633, + "scoreConfidence" : [ + 0.38255684160174475, + 0.389707987136234 + ], + "scorePercentiles" : { + "0.0" : 0.38304099191818597, + "50.0" : 0.38653313933982686, + "90.0" : 0.3896898799002416, + "95.0" : 0.3896898799002416, + "99.0" : 0.3896898799002416, + "99.9" : 0.3896898799002416, + "99.99" : 0.3896898799002416, + "99.999" : 0.3896898799002416, + "99.9999" : 0.3896898799002416, + "100.0" : 0.3896898799002416 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38653313933982686, + 0.38562719511818916, + 0.38522279780431434 + ], + [ + 0.38747809643922665, + 0.38698291312591904, + 0.3874144294735211 + ], + [ + 0.3896898799002416, + 0.3832022862014791, + 0.38304099191818597 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15756813557818247, + "scoreError" : 0.0065165439758813224, + "scoreConfidence" : [ + 0.15105159160230114, + 0.1640846795540638 + ], + "scorePercentiles" : { + "0.0" : 0.15212867388757892, + "50.0" : 0.15919887802470709, + "90.0" : 0.16154582684199473, + "95.0" : 0.16154582684199473, + "99.0" : 0.16154582684199473, + "99.9" : 0.16154582684199473, + "99.99" : 0.16154582684199473, + "99.999" : 0.16154582684199473, + "99.9999" : 0.16154582684199473, + "100.0" : 0.16154582684199473 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1531477717234831, + 0.1522394138807697, + 0.15212867388757892 + ], + [ + 0.16154582684199473, + 0.1602374568251374, + 0.1601357834358186 + ], + [ + 0.16049824886449354, + 0.15898116671965914, + 0.15919887802470709 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04687713978540145, + "scoreError" : 0.0010612687857045062, + "scoreConfidence" : [ + 0.045815870999696945, + 0.047938408571105956 + ], + "scorePercentiles" : { + "0.0" : 0.04606025472801806, + "50.0" : 0.04693274996010775, + "90.0" : 0.04757975261209653, + "95.0" : 0.04757975261209653, + "99.0" : 0.04757975261209653, + "99.9" : 0.04757975261209653, + "99.99" : 0.04757975261209653, + "99.999" : 0.04757975261209653, + "99.9999" : 0.04757975261209653, + "100.0" : 0.04757975261209653 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04755243152779165, + 0.04757975261209653, + 0.04754639047849984 + ], + [ + 0.04707834560177012, + 0.04693274996010775, + 0.04685888061946488 + ], + [ + 0.046183133010363364, + 0.04610231953050085, + 0.04606025472801806 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9360297.634597164, + "scoreError" : 175391.63757937515, + "scoreConfidence" : [ + 9184905.997017788, + 9535689.27217654 + ], + "scorePercentiles" : { + "0.0" : 9260010.685185185, + "50.0" : 9321470.84249767, + "90.0" : 9536754.620591039, + "95.0" : 9536754.620591039, + "99.0" : 9536754.620591039, + "99.9" : 9536754.620591039, + "99.99" : 9536754.620591039, + "99.999" : 9536754.620591039, + "99.9999" : 9536754.620591039, + "100.0" : 9536754.620591039 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9536754.620591039, + 9475862.076704545, + 9467337.743614001 + ], + [ + 9321470.84249767, + 9315488.694599628, + 9326853.998136068 + ], + [ + 9270368.858202038, + 9260010.685185185, + 9268531.1918443 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-06T11:33:26Z-14c9136a6a33103f69f86f39bcd486bcae2ff525-jdk17.json b/performance-results/2025-04-06T11:33:26Z-14c9136a6a33103f69f86f39bcd486bcae2ff525-jdk17.json new file mode 100644 index 0000000000..3751f422c6 --- /dev/null +++ b/performance-results/2025-04-06T11:33:26Z-14c9136a6a33103f69f86f39bcd486bcae2ff525-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3957352409364385, + "scoreError" : 0.015684974253292697, + "scoreConfidence" : [ + 3.380050266683146, + 3.411420215189731 + ], + "scorePercentiles" : { + "0.0" : 3.392976664184572, + "50.0" : 3.395705894477954, + "90.0" : 3.3985525106052745, + "95.0" : 3.3985525106052745, + "99.0" : 3.3985525106052745, + "99.9" : 3.3985525106052745, + "99.99" : 3.3985525106052745, + "99.999" : 3.3985525106052745, + "99.9999" : 3.3985525106052745, + "100.0" : 3.3985525106052745 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.394674778427625, + 3.3967370105282826 + ], + [ + 3.392976664184572, + 3.3985525106052745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.715366014713939, + "scoreError" : 0.022445605539527534, + "scoreConfidence" : [ + 1.6929204091744114, + 1.7378116202534664 + ], + "scorePercentiles" : { + "0.0" : 1.7114341422770996, + "50.0" : 1.7154414395911841, + "90.0" : 1.7191470373962887, + "95.0" : 1.7191470373962887, + "99.0" : 1.7191470373962887, + "99.9" : 1.7191470373962887, + "99.99" : 1.7191470373962887, + "99.999" : 1.7191470373962887, + "99.9999" : 1.7191470373962887, + "100.0" : 1.7191470373962887 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7114341422770996, + 1.7136486614788984 + ], + [ + 1.7172342177034698, + 1.7191470373962887 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8623839906524824, + "scoreError" : 0.017881712405582097, + "scoreConfidence" : [ + 0.8445022782469003, + 0.8802657030580645 + ], + "scorePercentiles" : { + "0.0" : 0.8590144212325085, + "50.0" : 0.8627068784950527, + "90.0" : 0.865107784387316, + "95.0" : 0.865107784387316, + "99.0" : 0.865107784387316, + "99.9" : 0.865107784387316, + "99.99" : 0.865107784387316, + "99.999" : 0.865107784387316, + "99.9999" : 0.865107784387316, + "100.0" : 0.865107784387316 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8641194770854608, + 0.865107784387316 + ], + [ + 0.8590144212325085, + 0.8612942799046445 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.964369759761347, + "scoreError" : 0.14949247492861661, + "scoreConfidence" : [ + 15.81487728483273, + 16.113862234689964 + ], + "scorePercentiles" : { + "0.0" : 15.811852078065343, + "50.0" : 15.958841605607912, + "90.0" : 16.068686757278652, + "95.0" : 16.068686757278652, + "99.0" : 16.068686757278652, + "99.9" : 16.068686757278652, + "99.99" : 16.068686757278652, + "99.999" : 16.068686757278652, + "99.9999" : 16.068686757278652, + "100.0" : 16.068686757278652 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.884122348234245, + 15.892067793051442, + 15.811852078065343 + ], + [ + 16.068686757278652, + 16.02611385854489, + 16.05950077065129 + ], + [ + 16.030228524873884, + 15.958841605607912, + 15.947914101544484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2632.946473250312, + "scoreError" : 93.99387762333102, + "scoreConfidence" : [ + 2538.952595626981, + 2726.940350873643 + ], + "scorePercentiles" : { + "0.0" : 2573.8895531139106, + "50.0" : 2619.4836853276893, + "90.0" : 2713.525151295088, + "95.0" : 2713.525151295088, + "99.0" : 2713.525151295088, + "99.9" : 2713.525151295088, + "99.99" : 2713.525151295088, + "99.999" : 2713.525151295088, + "99.9999" : 2713.525151295088, + "100.0" : 2713.525151295088 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2621.4226450253977, + 2619.4836853276893, + 2611.349597133837 + ], + [ + 2581.449953604812, + 2578.211708521408, + 2573.8895531139106 + ], + [ + 2697.7887121079466, + 2713.525151295088, + 2699.397253122716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69534.66430141217, + "scoreError" : 2801.5518349881327, + "scoreConfidence" : [ + 66733.11246642403, + 72336.2161364003 + ], + "scorePercentiles" : { + "0.0" : 65567.4080996611, + "50.0" : 69961.79605161793, + "90.0" : 71051.43139625118, + "95.0" : 71051.43139625118, + "99.0" : 71051.43139625118, + "99.9" : 71051.43139625118, + "99.99" : 71051.43139625118, + "99.999" : 71051.43139625118, + "99.9999" : 71051.43139625118, + "100.0" : 71051.43139625118 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68854.52710104783, + 68971.27421927753, + 65567.4080996611 + ], + [ + 69961.79605161793, + 69908.7846493282, + 70055.8954803111 + ], + [ + 70651.62694371553, + 71051.43139625118, + 70789.23477149908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 324.37714013322415, + "scoreError" : 6.953692403364356, + "scoreConfidence" : [ + 317.4234477298598, + 331.3308325365885 + ], + "scorePercentiles" : { + "0.0" : 317.9794415797697, + "50.0" : 325.6979033805179, + "90.0" : 329.47163983902743, + "95.0" : 329.47163983902743, + "99.0" : 329.47163983902743, + "99.9" : 329.47163983902743, + "99.99" : 329.47163983902743, + "99.999" : 329.47163983902743, + "99.9999" : 329.47163983902743, + "100.0" : 329.47163983902743 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 325.6979033805179, + 326.8589024612708, + 327.71947283667845 + ], + [ + 319.1493847905536, + 317.9794415797697, + 320.4422634820272 + ], + [ + 329.47163983902743, + 327.1995344627017, + 324.87571836647084 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 102.959790420029, + "scoreError" : 2.6836297682130374, + "scoreConfidence" : [ + 100.27616065181596, + 105.64342018824203 + ], + "scorePercentiles" : { + "0.0" : 101.06488807701024, + "50.0" : 102.31342535678377, + "90.0" : 105.815826229701, + "95.0" : 105.815826229701, + "99.0" : 105.815826229701, + "99.9" : 105.815826229701, + "99.99" : 105.815826229701, + "99.999" : 105.815826229701, + "99.9999" : 105.815826229701, + "100.0" : 105.815826229701 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.6268312221908, + 102.22420517816848, + 101.06488807701024 + ], + [ + 101.94574008326629, + 102.31342535678377, + 102.68228515975018 + ], + [ + 104.18470572687318, + 104.78020674651705, + 105.815826229701 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06385212124215954, + "scoreError" : 3.980491241938138E-4, + "scoreConfidence" : [ + 0.06345407211796572, + 0.06425017036635336 + ], + "scorePercentiles" : { + "0.0" : 0.06360682266025519, + "50.0" : 0.06375608461533558, + "90.0" : 0.06420885625770495, + "95.0" : 0.06420885625770495, + "99.0" : 0.06420885625770495, + "99.9" : 0.06420885625770495, + "99.99" : 0.06420885625770495, + "99.999" : 0.06420885625770495, + "99.9999" : 0.06420885625770495, + "100.0" : 0.06420885625770495 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0636074658720113, + 0.06368320890912564, + 0.06400144288283445 + ], + [ + 0.0640410836295172, + 0.06411013171222689, + 0.06420885625770495 + ], + [ + 0.06365399464042469, + 0.06360682266025519, + 0.06375608461533558 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.9662898037091357E-4, + "scoreError" : 2.4763194628361096E-5, + "scoreConfidence" : [ + 3.718657857425525E-4, + 4.2139217499927465E-4 + ], + "scorePercentiles" : { + "0.0" : 3.815935281333288E-4, + "50.0" : 3.910863244286691E-4, + "90.0" : 4.1596443371843373E-4, + "95.0" : 4.1596443371843373E-4, + "99.0" : 4.1596443371843373E-4, + "99.9" : 4.1596443371843373E-4, + "99.99" : 4.1596443371843373E-4, + "99.999" : 4.1596443371843373E-4, + "99.9999" : 4.1596443371843373E-4, + "100.0" : 4.1596443371843373E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 4.1507248171887697E-4, + 4.1596443371843373E-4, + 4.158961915449522E-4 + ], + [ + 3.9249085467373625E-4, + 3.910863244286691E-4, + 3.9028536381353695E-4 + ], + [ + 3.815935281333288E-4, + 3.83322489934839E-4, + 3.839491553718492E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014256156575693513, + "scoreError" : 1.1832459269240048E-4, + "scoreConfidence" : [ + 0.014137831983001113, + 0.014374481168385913 + ], + "scorePercentiles" : { + "0.0" : 0.014160325917188587, + "50.0" : 0.014281502312143682, + "90.0" : 0.01434438235319431, + "95.0" : 0.01434438235319431, + "99.0" : 0.01434438235319431, + "99.9" : 0.01434438235319431, + "99.99" : 0.01434438235319431, + "99.999" : 0.01434438235319431, + "99.9999" : 0.01434438235319431, + "100.0" : 0.01434438235319431 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014294949020667335, + 0.014281502312143682, + 0.014222103556901898 + ], + [ + 0.01434438235319431, + 0.01433649228420283, + 0.014300185563870207 + ], + [ + 0.01419311983093378, + 0.014160325917188587, + 0.014172348342138978 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9824788631918102, + "scoreError" : 0.015282153141593577, + "scoreConfidence" : [ + 0.9671967100502167, + 0.9977610163334037 + ], + "scorePercentiles" : { + "0.0" : 0.971180237253569, + "50.0" : 0.9812488621467818, + "90.0" : 0.9941125791252485, + "95.0" : 0.9941125791252485, + "99.0" : 0.9941125791252485, + "99.9" : 0.9941125791252485, + "99.99" : 0.9941125791252485, + "99.999" : 0.9941125791252485, + "99.9999" : 0.9941125791252485, + "100.0" : 0.9941125791252485 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9812488621467818, + 0.9805092572801255, + 0.9850614140070922 + ], + [ + 0.9910779913784561, + 0.9941125791252485, + 0.9935723269746647 + ], + [ + 0.9720085908251531, + 0.9735385097352025, + 0.971180237253569 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01313513390633781, + "scoreError" : 1.7088782952539693E-4, + "scoreConfidence" : [ + 0.012964246076812413, + 0.013306021735863208 + ], + "scorePercentiles" : { + "0.0" : 0.013032883220601843, + "50.0" : 0.013130920356492343, + "90.0" : 0.013206380218375443, + "95.0" : 0.013206380218375443, + "99.0" : 0.013206380218375443, + "99.9" : 0.013206380218375443, + "99.99" : 0.013206380218375443, + "99.999" : 0.013206380218375443, + "99.9999" : 0.013206380218375443, + "100.0" : 0.013206380218375443 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013032883220601843, + 0.01318755262359721, + 0.013206380218375443 + ], + [ + 0.013137456023499675, + 0.013122146662467688, + 0.013124384689485012 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.867786864317754, + "scoreError" : 0.048553694236964026, + "scoreConfidence" : [ + 3.81923317008079, + 3.916340558554718 + ], + "scorePercentiles" : { + "0.0" : 3.8529737359507314, + "50.0" : 3.8585532311495188, + "90.0" : 3.8924816739299613, + "95.0" : 3.8924816739299613, + "99.0" : 3.8924816739299613, + "99.9" : 3.8924816739299613, + "99.99" : 3.8924816739299613, + "99.999" : 3.8924816739299613, + "99.9999" : 3.8924816739299613, + "100.0" : 3.8924816739299613 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8569471233616035, + 3.8600316018518517, + 3.8529737359507314 + ], + [ + 3.857074860447186, + 3.88721219036519, + 3.8924816739299613 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.0750627687740564, + "scoreError" : 0.05511820982963315, + "scoreConfidence" : [ + 3.0199445589444234, + 3.1301809786036894 + ], + "scorePercentiles" : { + "0.0" : 3.0299908679188126, + "50.0" : 3.064409943627451, + "90.0" : 3.135634054231975, + "95.0" : 3.135634054231975, + "99.0" : 3.135634054231975, + "99.9" : 3.135634054231975, + "99.99" : 3.135634054231975, + "99.999" : 3.135634054231975, + "99.9999" : 3.135634054231975, + "100.0" : 3.135634054231975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0817256949152543, + 3.0892173233477456, + 3.1099776281094527 + ], + [ + 3.0299908679188126, + 3.064409943627451, + 3.135634054231975 + ], + [ + 3.063156679019908, + 3.051907723527617, + 3.0495450042682926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17707974113798844, + "scoreError" : 0.001753183598704396, + "scoreConfidence" : [ + 0.17532655753928406, + 0.17883292473669282 + ], + "scorePercentiles" : { + "0.0" : 0.17542807671256908, + "50.0" : 0.17744374794612913, + "90.0" : 0.17834795757165023, + "95.0" : 0.17834795757165023, + "99.0" : 0.17834795757165023, + "99.9" : 0.17834795757165023, + "99.99" : 0.17834795757165023, + "99.999" : 0.17834795757165023, + "99.9999" : 0.17834795757165023, + "100.0" : 0.17834795757165023 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17542807671256908, + 0.17567099878790007, + 0.17622787493391603 + ], + [ + 0.17834795757165023, + 0.17778623739088695, + 0.1777325394021256 + ], + [ + 0.17783960020984493, + 0.17744374794612913, + 0.17724063728687392 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3291669764763291, + "scoreError" : 0.007571788356830977, + "scoreConfidence" : [ + 0.3215951881194981, + 0.33673876483316006 + ], + "scorePercentiles" : { + "0.0" : 0.3241040484848485, + "50.0" : 0.32796601954611043, + "90.0" : 0.3354437538239635, + "95.0" : 0.3354437538239635, + "99.0" : 0.3354437538239635, + "99.9" : 0.3354437538239635, + "99.99" : 0.3354437538239635, + "99.999" : 0.3354437538239635, + "99.9999" : 0.3354437538239635, + "100.0" : 0.3354437538239635 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3354437538239635, + 0.3346651346964728, + 0.3344965017894772 + ], + [ + 0.3279725352399069, + 0.3277535350353959, + 0.32796601954611043 + ], + [ + 0.32507591015180576, + 0.3241040484848485, + 0.32502534951898077 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16062776080834268, + "scoreError" : 0.005431148276752742, + "scoreConfidence" : [ + 0.15519661253158995, + 0.1660589090850954 + ], + "scorePercentiles" : { + "0.0" : 0.1560528020661028, + "50.0" : 0.16137011350470382, + "90.0" : 0.16436436313730646, + "95.0" : 0.16436436313730646, + "99.0" : 0.16436436313730646, + "99.9" : 0.16436436313730646, + "99.99" : 0.16436436313730646, + "99.999" : 0.16436436313730646, + "99.9999" : 0.16436436313730646, + "100.0" : 0.16436436313730646 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1570186333689235, + 0.1567735383614473, + 0.1560528020661028 + ], + [ + 0.16436436313730646, + 0.16383697162423408, + 0.16358005905157608 + ], + [ + 0.161679944674384, + 0.16137011350470382, + 0.160973421486406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3903617858409897, + "scoreError" : 0.009828721884524704, + "scoreConfidence" : [ + 0.38053306395646497, + 0.4001905077255144 + ], + "scorePercentiles" : { + "0.0" : 0.3824873031821311, + "50.0" : 0.3917676618349918, + "90.0" : 0.39610914148776044, + "95.0" : 0.39610914148776044, + "99.0" : 0.39610914148776044, + "99.9" : 0.39610914148776044, + "99.99" : 0.39610914148776044, + "99.999" : 0.39610914148776044, + "99.9999" : 0.39610914148776044, + "100.0" : 0.39610914148776044 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39610914148776044, + 0.3953911683536296, + 0.39527777813352305 + ], + [ + 0.3824873031821311, + 0.38368207650399017, + 0.3827536854212118 + ], + [ + 0.39533068979285263, + 0.3917676618349918, + 0.39045656785881616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15819162474581686, + "scoreError" : 0.0048135868130951606, + "scoreConfidence" : [ + 0.1533780379327217, + 0.163005211558912 + ], + "scorePercentiles" : { + "0.0" : 0.15527001720363326, + "50.0" : 0.15726231035241944, + "90.0" : 0.16197077154565037, + "95.0" : 0.16197077154565037, + "99.0" : 0.16197077154565037, + "99.9" : 0.16197077154565037, + "99.99" : 0.16197077154565037, + "99.999" : 0.16197077154565037, + "99.9999" : 0.16197077154565037, + "100.0" : 0.16197077154565037 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15765723094386025, + 0.15726231035241944, + 0.15718987414137287 + ], + [ + 0.16197077154565037, + 0.16175013906995553, + 0.1617629850048528 + ], + [ + 0.15536635726936582, + 0.15549493718124144, + 0.15527001720363326 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047076397918228714, + "scoreError" : 9.393130932661902E-4, + "scoreConfidence" : [ + 0.046137084824962524, + 0.048015711011494905 + ], + "scorePercentiles" : { + "0.0" : 0.04660691954381909, + "50.0" : 0.04679847674848492, + "90.0" : 0.04791543753354033, + "95.0" : 0.04791543753354033, + "99.0" : 0.04791543753354033, + "99.9" : 0.04791543753354033, + "99.99" : 0.04791543753354033, + "99.999" : 0.04791543753354033, + "99.9999" : 0.04791543753354033, + "100.0" : 0.04791543753354033 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04681345522126048, + 0.04679847674848492, + 0.046763169458395294 + ], + [ + 0.046641739345997954, + 0.04660691954381909, + 0.04662555677971633 + ], + [ + 0.047764110466837977, + 0.047758716166006014, + 0.04791543753354033 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9813602.948911339, + "scoreError" : 123718.98750194644, + "scoreConfidence" : [ + 9689883.961409392, + 9937321.936413286 + ], + "scorePercentiles" : { + "0.0" : 9679557.92843327, + "50.0" : 9822463.236506378, + "90.0" : 9927081.881944444, + "95.0" : 9927081.881944444, + "99.0" : 9927081.881944444, + "99.9" : 9927081.881944444, + "99.99" : 9927081.881944444, + "99.999" : 9927081.881944444, + "99.9999" : 9927081.881944444, + "100.0" : 9927081.881944444 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9872000.78183613, + 9822463.236506378, + 9927081.881944444 + ], + [ + 9853020.666995075, + 9853184.431527093, + 9790321.015655577 + ], + [ + 9679557.92843327, + 9754578.18031189, + 9770218.416992188 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-07T01:27:42Z-154bb89d14e9701d1b9f0764cbf813ba3a3c050a-jdk17.json b/performance-results/2025-04-07T01:27:42Z-154bb89d14e9701d1b9f0764cbf813ba3a3c050a-jdk17.json new file mode 100644 index 0000000000..1a46afd5c6 --- /dev/null +++ b/performance-results/2025-04-07T01:27:42Z-154bb89d14e9701d1b9f0764cbf813ba3a3c050a-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion": "1.37", + "benchmark": "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 2, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "howManyItems": "5" + }, + "primaryMetric": { + "score": 3.4102846934427835, + "scoreError": 0.029120215772332664, + "scoreConfidence": [ + 3.381164477670451, + 3.439404909215116 + ], + "scorePercentiles": { + "0.0": 3.40421431924695, + "50.0": 3.411477217299319, + "90.0": 3.4139700199255474, + "95.0": 3.4139700199255474, + "99.0": 3.4139700199255474, + "99.9": 3.4139700199255474, + "99.99": 3.4139700199255474, + "99.999": 3.4139700199255474, + "99.9999": 3.4139700199255474, + "100.0": 3.4139700199255474 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 3.40421431924695, + 3.4139700199255474 + ], + [ + 3.4095218102136196, + 3.4134326243850186 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 2, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "howManyItems": "10" + }, + "primaryMetric": { + "score": 1.7221652033520922, + "scoreError": 0.009478621744532833, + "scoreConfidence": [ + 1.7126865816075594, + 1.731643825096625 + ], + "scorePercentiles": { + "0.0": 1.7203619756019852, + "50.0": 1.722271370931328, + "90.0": 1.723756095943728, + "95.0": 1.723756095943728, + "99.0": 1.723756095943728, + "99.9": 1.723756095943728, + "99.99": 1.723756095943728, + "99.999": 1.723756095943728, + "99.9999": 1.723756095943728, + "100.0": 1.723756095943728 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 1.7228412979004932, + 1.723756095943728 + ], + [ + 1.7203619756019852, + 1.7217014439621625 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 2, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "howManyItems": "20" + }, + "primaryMetric": { + "score": 0.8638167830583094, + "scoreError": 0.005432486996052623, + "scoreConfidence": [ + 0.8583842960622569, + 0.869249270054362 + ], + "scorePercentiles": { + "0.0": 0.8627272504566224, + "50.0": 0.8639140939295744, + "90.0": 0.8647116939174667, + "95.0": 0.8647116939174667, + "99.0": 0.8647116939174667, + "99.9": 0.8647116939174667, + "99.99": 0.8647116939174667, + "99.999": 0.8647116939174667, + "99.9999": 0.8647116939174667, + "100.0": 0.8647116939174667 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 0.8627272504566224, + 0.8647116939174667 + ], + [ + 0.8641521696201839, + 0.863676018238965 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 15.856427557514358, + "scoreError": 0.21807549856382044, + "scoreConfidence": [ + 15.638352058950538, + 16.07450305607818 + ], + "scorePercentiles": { + "0.0": 15.681327891325898, + "50.0": 15.904269221101467, + "90.0": 16.02142911448296, + "95.0": 16.02142911448296, + "99.0": 16.02142911448296, + "99.9": 16.02142911448296, + "99.99": 16.02142911448296, + "99.999": 16.02142911448296, + "99.9999": 16.02142911448296, + "100.0": 16.02142911448296 + }, + "scoreUnit": "ops/ms", + "rawData": [ + [ + 15.904269221101467, + 16.02142911448296, + 15.943726644806675 + ], + [ + 15.681327891325898, + 15.700241982223265, + 15.6913767022947 + ], + [ + 15.881763309316872, + 15.936401461123317, + 15.947311690954091 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 2615.3268175518824, + "scoreError": 85.27331964422102, + "scoreConfidence": [ + 2530.0534979076615, + 2700.6001371961033 + ], + "scorePercentiles": { + "0.0": 2550.521812924825, + "50.0": 2603.3546349283893, + "90.0": 2682.250838153494, + "95.0": 2682.250838153494, + "99.0": 2682.250838153494, + "99.9": 2682.250838153494, + "99.99": 2682.250838153494, + "99.999": 2682.250838153494, + "99.9999": 2682.250838153494, + "100.0": 2682.250838153494 + }, + "scoreUnit": "ops/ms", + "rawData": [ + [ + 2682.250838153494, + 2674.2071330474264, + 2676.491646172537 + ], + [ + 2573.055142655825, + 2564.6397919711726, + 2550.521812924825 + ], + [ + 2612.447308343581, + 2603.3546349283893, + 2600.9730497696914 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENF1Performance.benchMarkThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 68682.74721165966, + "scoreError": 1904.0986389262905, + "scoreConfidence": [ + 66778.64857273338, + 70586.84585058595 + ], + "scorePercentiles": { + "0.0": 67315.78978042262, + "50.0": 68558.57912756453, + "90.0": 70108.49357429743, + "95.0": 70108.49357429743, + "99.0": 70108.49357429743, + "99.9": 70108.49357429743, + "99.99": 70108.49357429743, + "99.999": 70108.49357429743, + "99.9999": 70108.49357429743, + "100.0": 70108.49357429743 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 70081.54631565987, + 69908.33092759324, + 70108.49357429743 + ], + [ + 68695.19237810129, + 68558.57912756453, + 68502.6084660597 + ], + [ + 67315.78978042262, + 67441.95616624445, + 67532.22816899384 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 341.9660588620118, + "scoreError": 5.428672335615734, + "scoreConfidence": [ + 336.53738652639606, + 347.3947311976275 + ], + "scorePercentiles": { + "0.0": 336.4476621680284, + "50.0": 342.2783710532269, + "90.0": 345.6060043253826, + "95.0": 345.6060043253826, + "99.0": 345.6060043253826, + "99.9": 345.6060043253826, + "99.99": 345.6060043253826, + "99.999": 345.6060043253826, + "99.9999": 345.6060043253826, + "100.0": 345.6060043253826 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 344.6308661866658, + 342.2263703728633, + 339.18226799196634 + ], + [ + 343.869334695566, + 344.96989920298415, + 345.6060043253826 + ], + [ + 342.2783710532269, + 336.4476621680284, + 338.48375376142235 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 102.86025606846653, + "scoreError": 1.38084080828978, + "scoreConfidence": [ + 101.47941526017675, + 104.2410968767563 + ], + "scorePercentiles": { + "0.0": 101.80541629343892, + "50.0": 102.80111987931467, + "90.0": 104.77421204891745, + "95.0": 104.77421204891745, + "99.0": 104.77421204891745, + "99.9": 104.77421204891745, + "99.99": 104.77421204891745, + "99.999": 104.77421204891745, + "99.9999": 104.77421204891745, + "100.0": 104.77421204891745 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 102.3242423337249, + 101.80541629343892, + 102.80111987931467 + ], + [ + 104.77421204891745, + 102.62377671322751, + 102.42665569290861 + ], + [ + 102.93712545820337, + 102.90042617995776, + 103.14933001650559 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 0.06299738431052335, + "scoreError": 3.244688347044825E-4, + "scoreConfidence": [ + 0.06267291547581887, + 0.06332185314522783 + ], + "scorePercentiles": { + "0.0": 0.06275631095268876, + "50.0": 0.06303528535589117, + "90.0": 0.06329175614711299, + "95.0": 0.06329175614711299, + "99.0": 0.06329175614711299, + "99.9": 0.06329175614711299, + "99.99": 0.06329175614711299, + "99.999": 0.06329175614711299, + "99.9999": 0.06329175614711299, + "100.0": 0.06329175614711299 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.06309860325332525, + 0.06324095105863604, + 0.06305016569991047 + ], + [ + 0.06283930007917657, + 0.06329175614711299, + 0.06303528535589117 + ], + [ + 0.0628358286427014, + 0.06275631095268876, + 0.06282825760526746 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 3.733489768801373E-4, + "scoreError": 7.710948014590726E-6, + "scoreConfidence": [ + 3.6563802886554656E-4, + 3.81059924894728E-4 + ], + "scorePercentiles": { + "0.0": 3.682361400802075E-4, + "50.0": 3.729608204948727E-4, + "90.0": 3.8100045308045563E-4, + "95.0": 3.8100045308045563E-4, + "99.0": 3.8100045308045563E-4, + "99.9": 3.8100045308045563E-4, + "99.99": 3.8100045308045563E-4, + "99.999": 3.8100045308045563E-4, + "99.9999": 3.8100045308045563E-4, + "100.0": 3.8100045308045563E-4 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 3.682361400802075E-4, + 3.70625831766964E-4, + 3.692070808996729E-4 + ], + [ + 3.6864684928719307E-4, + 3.729608204948727E-4, + 3.7460464471704793E-4 + ], + [ + 3.784421620702325E-4, + 3.8100045308045563E-4, + 3.7641680952458926E-4 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENF1Performance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 0.01435726879619418, + "scoreError": 4.0347910114715526E-4, + "scoreConfidence": [ + 0.013953789695047025, + 0.014760747897341334 + ], + "scorePercentiles": { + "0.0": 0.014138349409377849, + "50.0": 0.01422107446198828, + "90.0": 0.014705323339239892, + "95.0": 0.014705323339239892, + "99.0": 0.014705323339239892, + "99.9": 0.014705323339239892, + "99.99": 0.014705323339239892, + "99.999": 0.014705323339239892, + "99.9999": 0.014705323339239892, + "100.0": 0.014705323339239892 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.014220843329512714, + 0.014249974604034115, + 0.01422107446198828 + ], + [ + 0.01465220841904762, + 0.0146646087476152, + 0.014705323339239892 + ], + [ + 0.014192360439900428, + 0.014170676415031508, + 0.014138349409377849 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENF2Performance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 0.9895251951545363, + "scoreError": 0.011617451159531738, + "scoreConfidence": [ + 0.9779077439950046, + 1.001142646314068 + ], + "scorePercentiles": { + "0.0": 0.9812811987047395, + "50.0": 0.9870416658112909, + "90.0": 1.0005223407703852, + "95.0": 1.0005223407703852, + "99.0": 1.0005223407703852, + "99.9": 1.0005223407703852, + "99.99": 1.0005223407703852, + "99.999": 1.0005223407703852, + "99.9999": 1.0005223407703852, + "100.0": 1.0005223407703852 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 1.0005223407703852, + 0.9968223352272727, + 0.9975727868541792 + ], + [ + 0.9870416658112909, + 0.9846626468097677, + 0.9872980485734031 + ], + [ + 0.9837904186915888, + 0.9867353149481993, + 0.9812811987047395 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "5 s", + "measurementBatchSize": 1, + "params": { + "howDeep": "2" + }, + "primaryMetric": { + "score": 0.01330986014742821, + "scoreError": 9.891136536444913E-5, + "scoreConfidence": [ + 0.013210948782063761, + 0.013408771512792659 + ], + "scorePercentiles": { + "0.0": 0.01327384584671746, + "50.0": 0.013299086737854359, + "90.0": 0.013362976738343782, + "95.0": 0.013362976738343782, + "99.0": 0.013362976738343782, + "99.9": 0.013362976738343782, + "99.99": 0.013362976738343782, + "99.999": 0.013362976738343782, + "99.9999": 0.013362976738343782, + "100.0": 0.013362976738343782 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.013294660619516086, + 0.01327384584671746, + 0.01330351285619263 + ], + [ + 0.013281905929416514, + 0.01334225889438279, + 0.013362976738343782 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "5 s", + "measurementBatchSize": 1, + "params": { + "howDeep": "10" + }, + "primaryMetric": { + "score": 3.8025668235689842, + "scoreError": 0.06390927980432547, + "scoreConfidence": [ + 3.738657543764659, + 3.8664761033733095 + ], + "scorePercentiles": { + "0.0": 3.7659801807228916, + "50.0": 3.806910667222677, + "90.0": 3.8267197444529457, + "95.0": 3.8267197444529457, + "99.0": 3.8267197444529457, + "99.9": 3.8267197444529457, + "99.99": 3.8267197444529457, + "99.999": 3.8267197444529457, + "99.9999": 3.8267197444529457, + "100.0": 3.8267197444529457 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 3.8143089107551487, + 3.7659801807228916, + 3.820578360580596 + ], + [ + 3.788301321212121, + 3.799512423690205, + 3.8267197444529457 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 2.9759041347139985, + "scoreError": 0.10713863758918146, + "scoreConfidence": [ + 2.868765497124817, + 3.08304277230318 + ], + "scorePercentiles": { + "0.0": 2.884954732621863, + "50.0": 3.000250045290942, + "90.0": 3.0388375967790946, + "95.0": 3.0388375967790946, + "99.0": 3.0388375967790946, + "99.9": 3.0388375967790946, + "99.99": 3.0388375967790946, + "99.999": 3.0388375967790946, + "99.9999": 3.0388375967790946, + "100.0": 3.0388375967790946 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 3.0026239456619632, + 3.000250045290942, + 2.9838356843675418 + ], + [ + 2.9118269863173216, + 2.884954732621863, + 2.8888414780473717 + ], + [ + 3.0388375967790946, + 3.038463558323208, + 3.033503185016682 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.18603597518816295, + "scoreError": 0.012679982126799527, + "scoreConfidence": [ + 0.17335599306136343, + 0.19871595731496247 + ], + "scorePercentiles": { + "0.0": 0.17767118692369194, + "50.0": 0.18524742478187578, + "90.0": 0.19535688841352633, + "95.0": 0.19535688841352633, + "99.0": 0.19535688841352633, + "99.9": 0.19535688841352633, + "99.99": 0.19535688841352633, + "99.999": 0.19535688841352633, + "99.9999": 0.19535688841352633, + "100.0": 0.19535688841352633 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.18528033961425158, + 0.18524742478187578, + 0.185177052070217 + ], + [ + 0.17788650417133609, + 0.17767118692369194, + 0.1776996488734096 + ], + [ + 0.19535688841352633, + 0.19508885146312915, + 0.19491588038202903 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.32826031013776114, + "scoreError": 0.011022615826861565, + "scoreConfidence": [ + 0.31723769431089954, + 0.33928292596462273 + ], + "scorePercentiles": { + "0.0": 0.320983046477291, + "50.0": 0.32681424316198815, + "90.0": 0.3371025889769088, + "95.0": 0.3371025889769088, + "99.0": 0.3371025889769088, + "99.9": 0.3371025889769088, + "99.99": 0.3371025889769088, + "99.999": 0.3371025889769088, + "99.9999": 0.3371025889769088, + "100.0": 0.3371025889769088 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.3223364937467767, + 0.320983046477291, + 0.3219397327366964 + ], + [ + 0.3371025889769088, + 0.3363084072305364, + 0.3361761716811779 + ], + [ + 0.32709179727210286, + 0.32681424316198815, + 0.32559030995637167 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.16457991754255474, + "scoreError": 0.010323140494181456, + "scoreConfidence": [ + 0.1542567770483733, + 0.1749030580367362 + ], + "scorePercentiles": { + "0.0": 0.1599626444910103, + "50.0": 0.1606458390200803, + "90.0": 0.1729952570276956, + "95.0": 0.1729952570276956, + "99.0": 0.1729952570276956, + "99.9": 0.1729952570276956, + "99.99": 0.1729952570276956, + "99.999": 0.1729952570276956, + "99.9999": 0.1729952570276956, + "100.0": 0.1729952570276956 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.1729952570276956, + 0.17261480054890047, + 0.17268161886342837 + ], + [ + 0.16080234687248754, + 0.1606458390200803, + 0.16053277127813273 + ], + [ + 0.16059716269732932, + 0.16038681708392807, + 0.1599626444910103 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.3934084316923969, + "scoreError": 0.008778638315417864, + "scoreConfidence": [ + 0.38462979337697906, + 0.4021870700078148 + ], + "scorePercentiles": { + "0.0": 0.3879532519300151, + "50.0": 0.39231844958807377, + "90.0": 0.4034614294359719, + "95.0": 0.4034614294359719, + "99.0": 0.4034614294359719, + "99.9": 0.4034614294359719, + "99.99": 0.4034614294359719, + "99.999": 0.4034614294359719, + "99.9999": 0.4034614294359719, + "100.0": 0.4034614294359719 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.3972338251439921, + 0.3963039667512087, + 0.3955053498516907 + ], + [ + 0.4034614294359719, + 0.39231844958807377, + 0.3916460862771207 + ], + [ + 0.3881032016144681, + 0.3879532519300151, + 0.3881503246390312 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.15900952508569965, + "scoreError": 0.0023946034846080585, + "scoreConfidence": [ + 0.15661492160109158, + 0.16140412857030773 + ], + "scorePercentiles": { + "0.0": 0.15720717609884927, + "50.0": 0.15895266305850936, + "90.0": 0.16082181456048375, + "95.0": 0.16082181456048375, + "99.0": 0.16082181456048375, + "99.9": 0.16082181456048375, + "99.99": 0.16082181456048375, + "99.999": 0.16082181456048375, + "99.9999": 0.16082181456048375, + "100.0": 0.16082181456048375 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.16082181456048375, + 0.16076233775419982, + 0.1602524095476179 + ], + [ + 0.15938672460233974, + 0.15895266305850936, + 0.15877954825188148 + ], + [ + 0.15768934277334512, + 0.15723370912407036, + 0.15720717609884927 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.047361120540854944, + "scoreError": 0.0011842744715550232, + "scoreConfidence": [ + 0.04617684606929992, + 0.04854539501240997 + ], + "scorePercentiles": { + "0.0": 0.046548068140666095, + "50.0": 0.04735400536040686, + "90.0": 0.04889141967751714, + "95.0": 0.04889141967751714, + "99.0": 0.04889141967751714, + "99.9": 0.04889141967751714, + "99.99": 0.04889141967751714, + "99.999": 0.04889141967751714, + "99.9999": 0.04889141967751714, + "100.0": 0.04889141967751714 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.04889141967751714, + 0.047445435486855404, + 0.04735400536040686 + ], + [ + 0.047628977833767544, + 0.046628790649202896, + 0.046548068140666095 + ], + [ + 0.04771143517321336, + 0.047044408982495095, + 0.046997543563570054 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 9484339.070811357, + "scoreError": 303876.42890579335, + "scoreConfidence": [ + 9180462.641905565, + 9788215.49971715 + ], + "scorePercentiles": { + "0.0": 9283828.396103896, + "50.0": 9397674.42629108, + "90.0": 9777845.836754642, + "95.0": 9777845.836754642, + "99.0": 9777845.836754642, + "99.9": 9777845.836754642, + "99.99": 9777845.836754642, + "99.999": 9777845.836754642, + "99.9999": 9777845.836754642, + "100.0": 9777845.836754642 + }, + "scoreUnit": "ns/op", + "rawData": [ + [ + 9380661.102155576, + 9355213.106641721, + 9283828.396103896 + ], + [ + 9397674.42629108, + 9401537.636278195, + 9390028.017840376 + ], + [ + 9777845.836754642, + 9646593.927675989, + 9725669.187560739 + ] + ] + }, + "secondaryMetrics": { + } + } +] + + diff --git a/performance-results/2025-04-07T02:23:04Z-27b9defd98c4d044b6142c18773188f0dc9113c2-jdk17.json b/performance-results/2025-04-07T02:23:04Z-27b9defd98c4d044b6142c18773188f0dc9113c2-jdk17.json new file mode 100644 index 0000000000..007f18eb8c --- /dev/null +++ b/performance-results/2025-04-07T02:23:04Z-27b9defd98c4d044b6142c18773188f0dc9113c2-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion": "1.37", + "benchmark": "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 2, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "howManyItems": "5" + }, + "primaryMetric": { + "score": 3.4024128744691158, + "scoreError": 0.04158750625008169, + "scoreConfidence": [ + 3.360825368219034, + 3.4440003807191975 + ], + "scorePercentiles": { + "0.0": 3.3944039605121104, + "50.0": 3.40345905590568, + "90.0": 3.4083294255529943, + "95.0": 3.4083294255529943, + "99.0": 3.4083294255529943, + "99.9": 3.4083294255529943, + "99.99": 3.4083294255529943, + "99.999": 3.4083294255529943, + "99.9999": 3.4083294255529943, + "100.0": 3.4083294255529943 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 3.3944039605121104, + 3.4083294255529943 + ], + [ + 3.4000739473145463, + 3.406844164496813 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 2, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "howManyItems": "10" + }, + "primaryMetric": { + "score": 1.7155725537784197, + "scoreError": 0.037770129964421216, + "scoreConfidence": [ + 1.6778024238139984, + 1.753342683742841 + ], + "scorePercentiles": { + "0.0": 1.710161968644825, + "50.0": 1.7154011487883323, + "90.0": 1.7213259488921897, + "95.0": 1.7213259488921897, + "99.0": 1.7213259488921897, + "99.9": 1.7213259488921897, + "99.99": 1.7213259488921897, + "99.999": 1.7213259488921897, + "99.9999": 1.7213259488921897, + "100.0": 1.7213259488921897 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 1.7198764284685448, + 1.7213259488921897 + ], + [ + 1.7109258691081197, + 1.710161968644825 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 2, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "howManyItems": "20" + }, + "primaryMetric": { + "score": 0.8640943472992049, + "scoreError": 0.004405615686319763, + "scoreConfidence": [ + 0.8596887316128851, + 0.8684999629855247 + ], + "scorePercentiles": { + "0.0": 0.8632641986249527, + "50.0": 0.8641162781756921, + "90.0": 0.8648806342204824, + "95.0": 0.8648806342204824, + "99.0": 0.8648806342204824, + "99.9": 0.8648806342204824, + "99.99": 0.8648806342204824, + "99.999": 0.8648806342204824, + "99.9999": 0.8648806342204824, + "100.0": 0.8648806342204824 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 0.8648806342204824, + 0.8643237523893058 + ], + [ + 0.8632641986249527, + 0.8639088039620784 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 15.917522993984761, + "scoreError": 0.10534551178634009, + "scoreConfidence": [ + 15.812177482198422, + 16.0228685057711 + ], + "scorePercentiles": { + "0.0": 15.847175310824856, + "50.0": 15.886193196714204, + "90.0": 15.998838791758699, + "95.0": 15.998838791758699, + "99.0": 15.998838791758699, + "99.9": 15.998838791758699, + "99.99": 15.998838791758699, + "99.999": 15.998838791758699, + "99.9999": 15.998838791758699, + "100.0": 15.998838791758699 + }, + "scoreUnit": "ops/ms", + "rawData": [ + [ + 15.998658314668303, + 15.885772075707989, + 15.853625494474564 + ], + [ + 15.952482344330894, + 15.972257475645264, + 15.998838791758699 + ], + [ + 15.862703941738092, + 15.847175310824856, + 15.886193196714204 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 2651.996925133564, + "scoreError": 102.61405658300019, + "scoreConfidence": [ + 2549.382868550564, + 2754.6109817165643 + ], + "scorePercentiles": { + "0.0": 2594.5766768309095, + "50.0": 2621.8559833967493, + "90.0": 2759.3571287575314, + "95.0": 2759.3571287575314, + "99.0": 2759.3571287575314, + "99.9": 2759.3571287575314, + "99.99": 2759.3571287575314, + "99.999": 2759.3571287575314, + "99.9999": 2759.3571287575314, + "100.0": 2759.3571287575314 + }, + "scoreUnit": "ops/ms", + "rawData": [ + [ + 2642.229533006958, + 2621.8559833967493, + 2614.1465639076587 + ], + [ + 2703.6596783021764, + 2724.2967547863987, + 2759.3571287575314 + ], + [ + 2609.049711493145, + 2598.8002957205467, + 2594.5766768309095 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENF1Performance.benchMarkThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 68612.0898374958, + "scoreError": 919.1459755874994, + "scoreConfidence": [ + 67692.94386190831, + 69531.2358130833 + ], + "scorePercentiles": { + "0.0": 67452.23010905962, + "50.0": 68636.00030823321, + "90.0": 69250.59981145305, + "95.0": 69250.59981145305, + "99.0": 69250.59981145305, + "99.9": 69250.59981145305, + "99.99": 69250.59981145305, + "99.999": 69250.59981145305, + "99.9999": 69250.59981145305, + "100.0": 69250.59981145305 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 68357.6305934753, + 68326.28436629583, + 67452.23010905962 + ], + [ + 68968.79799847226, + 69250.59981145305, + 69213.97860275264 + ], + [ + 68631.82410693438, + 68636.00030823321, + 68671.46264078599 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 330.4601630317331, + "scoreError": 9.658737192895103, + "scoreConfidence": [ + 320.801425838838, + 340.1189002246282 + ], + "scorePercentiles": { + "0.0": 323.1202470082651, + "50.0": 328.76437581551824, + "90.0": 341.84570372389413, + "95.0": 341.84570372389413, + "99.0": 341.84570372389413, + "99.9": 341.84570372389413, + "99.99": 341.84570372389413, + "99.999": 341.84570372389413, + "99.9999": 341.84570372389413, + "100.0": 341.84570372389413 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 329.79261883074423, + 327.7660443555497, + 328.76437581551824 + ], + [ + 333.16257444872934, + 341.84570372389413, + 336.19328864061754 + ], + [ + 325.6343215111571, + 323.1202470082651, + 327.86229295112247 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode": "thrpt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 100.12561032974878, + "scoreError": 2.8985841561115095, + "scoreConfidence": [ + 97.22702617363727, + 103.02419448586029 + ], + "scorePercentiles": { + "0.0": 97.95482936466934, + "50.0": 100.3875153367714, + "90.0": 103.3944677652683, + "95.0": 103.3944677652683, + "99.0": 103.3944677652683, + "99.9": 103.3944677652683, + "99.99": 103.3944677652683, + "99.999": 103.3944677652683, + "99.9999": 103.3944677652683, + "100.0": 103.3944677652683 + }, + "scoreUnit": "ops/s", + "rawData": [ + [ + 100.8323274119472, + 100.4198752326016, + 98.84554145420253 + ], + [ + 99.6008992466689, + 97.95482936466934, + 98.16208928086066 + ], + [ + 100.3875153367714, + 103.3944677652683, + 101.5329478747493 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 0.06316792203283529, + "scoreError": 8.270715540534216E-4, + "scoreConfidence": [ + 0.06234085047878187, + 0.06399499358688872 + ], + "scorePercentiles": { + "0.0": 0.06222177331723889, + "50.0": 0.06337011391907735, + "90.0": 0.06358116983507331, + "95.0": 0.06358116983507331, + "99.0": 0.06358116983507331, + "99.9": 0.06358116983507331, + "99.99": 0.06358116983507331, + "99.999": 0.06358116983507331, + "99.9999": 0.06358116983507331, + "100.0": 0.06358116983507331 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.06349092706263293, + 0.06334888231195125, + 0.06337011391907735 + ], + [ + 0.0635717372429357, + 0.06358116983507331, + 0.06350392368850533 + ], + [ + 0.06273545851996838, + 0.06222177331723889, + 0.06268731239813445 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 3.8155791647813083E-4, + "scoreError": 3.3424823701870774E-6, + "scoreConfidence": [ + 3.7821543410794376E-4, + 3.849003988483179E-4 + ], + "scorePercentiles": { + "0.0": 3.7877016592745467E-4, + "50.0": 3.822095981027384E-4, + "90.0": 3.842126257983555E-4, + "95.0": 3.842126257983555E-4, + "99.0": 3.842126257983555E-4, + "99.9": 3.842126257983555E-4, + "99.99": 3.842126257983555E-4, + "99.999": 3.842126257983555E-4, + "99.9999": 3.842126257983555E-4, + "100.0": 3.842126257983555E-4 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 3.822095981027384E-4, + 3.8229752960112107E-4, + 3.801560559184481E-4 + ], + [ + 3.7877016592745467E-4, + 3.7948895620940705E-4, + 3.800347896686719E-4 + ], + [ + 3.838236461244403E-4, + 3.8302788095254055E-4, + 3.842126257983555E-4 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENF1Performance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 0.014208448375770424, + "scoreError": 4.036614484293156E-5, + "scoreConfidence": [ + 0.014168082230927493, + 0.014248814520613355 + ], + "scorePercentiles": { + "0.0": 0.014178370370107812, + "50.0": 0.014204685320049261, + "90.0": 0.014251159324333375, + "95.0": 0.014251159324333375, + "99.0": 0.014251159324333375, + "99.9": 0.014251159324333375, + "99.99": 0.014251159324333375, + "99.999": 0.014251159324333375, + "99.9999": 0.014251159324333375, + "100.0": 0.014251159324333375 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.01422632329773477, + 0.014251159324333375, + 0.014191335593985218 + ], + [ + 0.014178370370107812, + 0.014186347490183172, + 0.01419074600570745 + ], + [ + 0.014204685320049261, + 0.014222163774860056, + 0.014224904204972681 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENF2Performance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 0.9891671827289721, + "scoreError": 0.005271542909133186, + "scoreConfidence": [ + 0.9838956398198389, + 0.9944387256381053 + ], + "scorePercentiles": { + "0.0": 0.9848689664171755, + "50.0": 0.9887918086810362, + "90.0": 0.9937846931332605, + "95.0": 0.9937846931332605, + "99.0": 0.9937846931332605, + "99.9": 0.9937846931332605, + "99.99": 0.9937846931332605, + "99.999": 0.9937846931332605, + "99.9999": 0.9937846931332605, + "100.0": 0.9937846931332605 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.9887918086810362, + 0.9876427126209757, + 0.9872937858623754 + ], + [ + 0.9858262918966877, + 0.9848689664171755, + 0.989383180846854 + ], + [ + 0.992224959718226, + 0.9937846931332605, + 0.9926882453841572 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "5 s", + "measurementBatchSize": 1, + "params": { + "howDeep": "2" + }, + "primaryMetric": { + "score": 0.013286598302855711, + "scoreError": 2.885899395432918E-4, + "scoreConfidence": [ + 0.01299800836331242, + 0.013575188242399002 + ], + "scorePercentiles": { + "0.0": 0.013133001691491848, + "50.0": 0.013278352595363613, + "90.0": 0.01340046419478466, + "95.0": 0.01340046419478466, + "99.0": 0.01340046419478466, + "99.9": 0.01340046419478466, + "99.99": 0.01340046419478466, + "99.999": 0.01340046419478466, + "99.9999": 0.01340046419478466, + "100.0": 0.01340046419478466 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.013133001691491848, + 0.013239373324930958, + 0.013238407885644388 + ], + [ + 0.013317331865796266, + 0.013391010854486147, + 0.01340046419478466 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 2, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "5 s", + "measurementBatchSize": 1, + "params": { + "howDeep": "10" + }, + "primaryMetric": { + "score": 3.9518865488084622, + "scoreError": 0.1620644508117164, + "scoreConfidence": [ + 3.789822097996746, + 4.113950999620179 + ], + "scorePercentiles": { + "0.0": 3.8908548794712288, + "50.0": 3.9458725575215814, + "90.0": 4.017380144578313, + "95.0": 4.017380144578313, + "99.0": 4.017380144578313, + "99.9": 4.017380144578313, + "99.99": 4.017380144578313, + "99.999": 4.017380144578313, + "99.9999": 4.017380144578313, + "100.0": 4.017380144578313 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 3.971634164416203, + 4.017380144578313, + 4.015910879614768 + ], + [ + 3.895428274143302, + 3.8908548794712288, + 3.920110950626959 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "primaryMetric": { + "score": 3.0523075817714425, + "scoreError": 0.06250911760604816, + "scoreConfidence": [ + 2.9897984641653945, + 3.1148166993774904 + ], + "scorePercentiles": { + "0.0": 2.9699671710213775, + "50.0": 3.0696655647636586, + "90.0": 3.086972935802469, + "95.0": 3.086972935802469, + "99.0": 3.086972935802469, + "99.9": 3.086972935802469, + "99.99": 3.086972935802469, + "99.999": 3.086972935802469, + "99.9999": 3.086972935802469, + "100.0": 3.086972935802469 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 3.0423442236081533, + 3.08352511621455, + 3.072799676497696 + ], + [ + 3.031278664746893, + 3.086972935802469, + 3.077165876 + ], + [ + 3.0696655647636586, + 2.9699671710213775, + 3.037049007288187 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.18166747949930095, + "scoreError": 0.006648671920999719, + "scoreConfidence": [ + 0.17501880757830124, + 0.18831615142030067 + ], + "scorePercentiles": { + "0.0": 0.1764090981160034, + "50.0": 0.18331922956499422, + "90.0": 0.1866240205467948, + "95.0": 0.1866240205467948, + "99.0": 0.1866240205467948, + "99.9": 0.1866240205467948, + "99.99": 0.1866240205467948, + "99.999": 0.1866240205467948, + "99.9999": 0.1866240205467948, + "100.0": 0.1866240205467948 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.1866240205467948, + 0.18308862911021603, + 0.18331922956499422 + ], + [ + 0.18389326961622626, + 0.1843292598982526, + 0.18405789231024075 + ], + [ + 0.1767467385779176, + 0.1764090981160034, + 0.17653917775306288 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.32936443132369997, + "scoreError": 0.016700051163016847, + "scoreConfidence": [ + 0.3126643801606831, + 0.34606448248671684 + ], + "scorePercentiles": { + "0.0": 0.3160410036028064, + "50.0": 0.33423063933823527, + "90.0": 0.3384082277757098, + "95.0": 0.3384082277757098, + "99.0": 0.3384082277757098, + "99.9": 0.3384082277757098, + "99.99": 0.3384082277757098, + "99.999": 0.3384082277757098, + "99.9999": 0.3384082277757098, + "100.0": 0.3384082277757098 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.3384082277757098, + 0.3366214163188367, + 0.3374201485930225 + ], + [ + 0.335473614747224, + 0.33423063933823527, + 0.33330557534246574 + ], + [ + 0.3160410036028064, + 0.3164667069936709, + 0.3163125492013285 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.15942278226557283, + "scoreError": 0.0011649283398282816, + "scoreConfidence": [ + 0.15825785392574454, + 0.1605877106054011 + ], + "scorePercentiles": { + "0.0": 0.158541066569431, + "50.0": 0.15914956365083155, + "90.0": 0.16043488962330746, + "95.0": 0.16043488962330746, + "99.0": 0.16043488962330746, + "99.9": 0.16043488962330746, + "99.99": 0.16043488962330746, + "99.999": 0.16043488962330746, + "99.9999": 0.16043488962330746, + "100.0": 0.16043488962330746 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.16024201910042143, + 0.16010645414665386, + 0.16043488962330746 + ], + [ + 0.158541066569431, + 0.1588924116656339, + 0.15914956365083155 + ], + [ + 0.1595501935288299, + 0.15875188312987157, + 0.15913655897517504 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.38738454017209295, + "scoreError": 0.005927807766160227, + "scoreConfidence": [ + 0.3814567324059327, + 0.3933123479382532 + ], + "scorePercentiles": { + "0.0": 0.382517749684428, + "50.0": 0.3899068544525889, + "90.0": 0.39072758224583887, + "95.0": 0.39072758224583887, + "99.0": 0.39072758224583887, + "99.9": 0.39072758224583887, + "99.99": 0.39072758224583887, + "99.999": 0.39072758224583887, + "99.9999": 0.39072758224583887, + "100.0": 0.39072758224583887 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.39072758224583887, + 0.3852419058130128, + 0.38403093575268815 + ], + [ + 0.39006229202745923, + 0.3832175821965052, + 0.382517749684428 + ], + [ + 0.3905045636299738, + 0.3902513957463415, + 0.3899068544525889 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.15627878522040609, + "scoreError": 7.785367456182951E-4, + "scoreConfidence": [ + 0.1555002484747878, + 0.15705732196602437 + ], + "scorePercentiles": { + "0.0": 0.15560179941806188, + "50.0": 0.15620902129088693, + "90.0": 0.1568640207839877, + "95.0": 0.1568640207839877, + "99.0": 0.1568640207839877, + "99.9": 0.1568640207839877, + "99.99": 0.1568640207839877, + "99.999": 0.1568640207839877, + "99.9999": 0.1568640207839877, + "100.0": 0.1568640207839877 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.15640216331190665, + 0.15572468925673888, + 0.15560179941806188 + ], + [ + 0.1568640207839877, + 0.1567813124872619, + 0.15676521391732376 + ], + [ + 0.15597704858533237, + 0.15620902129088693, + 0.15618379793215467 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 0.04806022908342739, + "scoreError": 0.0026399188420189288, + "scoreConfidence": [ + 0.04542031024140846, + 0.050700147925446325 + ], + "scorePercentiles": { + "0.0": 0.046529167814369866, + "50.0": 0.04744658384179611, + "90.0": 0.050145358333792994, + "95.0": 0.050145358333792994, + "99.0": 0.050145358333792994, + "99.9": 0.050145358333792994, + "99.99": 0.050145358333792994, + "99.999": 0.050145358333792994, + "99.9999": 0.050145358333792994, + "100.0": 0.050145358333792994 + }, + "scoreUnit": "ms/op", + "rawData": [ + [ + 0.047653858208243985, + 0.04744658384179611, + 0.047323675478198324 + ], + [ + 0.050145358333792994, + 0.05012683766673183, + 0.049999637767244656 + ], + [ + 0.0466059831382126, + 0.046529167814369866, + 0.0467109595022561 + ] + ] + }, + "secondaryMetrics": { + } + }, + { + "jmhVersion": "1.37", + "benchmark": "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode": "avgt", + "threads": 1, + "forks": 3, + "jvm": "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs": [ + ], + "jdkVersion": "17.0.10", + "vmName": "OpenJDK 64-Bit Server VM", + "vmVersion": "17.0.10+7-LTS", + "warmupIterations": 2, + "warmupTime": "5 s", + "warmupBatchSize": 1, + "measurementIterations": 3, + "measurementTime": "10 s", + "measurementBatchSize": 1, + "params": { + "size": "100" + }, + "primaryMetric": { + "score": 1.0190032978742655E7, + "scoreError": 360464.8084112424, + "scoreConfidence": [ + 9829568.170331413, + 1.0550497787153898E7 + ], + "scorePercentiles": { + "0.0": 9784278.565982405, + "50.0": 1.0226893349693252E7, + "90.0": 1.051854128811777E7, + "95.0": 1.051854128811777E7, + "99.0": 1.051854128811777E7, + "99.9": 1.051854128811777E7, + "99.99": 1.051854128811777E7, + "99.999": 1.051854128811777E7, + "99.9999": 1.051854128811777E7, + "100.0": 1.051854128811777E7 + }, + "scoreUnit": "ns/op", + "rawData": [ + [ + 1.0004127156E7, + 1.0086599470766129E7, + 9784278.565982405 + ], + [ + 1.0226893349693252E7, + 1.0233475158486707E7, + 1.020059461365953E7 + ], + [ + 1.026109897025641E7, + 1.0394688235721704E7, + 1.051854128811777E7 + ] + ] + }, + "secondaryMetrics": { + } + } +] + + diff --git a/performance-results/2025-04-08T00:39:51Z-12c944f587bcd78172e3c7e98da29714f8ce3cca-jdk17.json b/performance-results/2025-04-08T00:39:51Z-12c944f587bcd78172e3c7e98da29714f8ce3cca-jdk17.json new file mode 100644 index 0000000000..a7f7d57fcc --- /dev/null +++ b/performance-results/2025-04-08T00:39:51Z-12c944f587bcd78172e3c7e98da29714f8ce3cca-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.405944633730623, + "scoreError" : 0.035690595423983874, + "scoreConfidence" : [ + 3.3702540383066393, + 3.4416352291546066 + ], + "scorePercentiles" : { + "0.0" : 3.399675791278035, + "50.0" : 3.406647411164472, + "90.0" : 3.410807921315513, + "95.0" : 3.410807921315513, + "99.0" : 3.410807921315513, + "99.9" : 3.410807921315513, + "99.99" : 3.410807921315513, + "99.999" : 3.410807921315513, + "99.9999" : 3.410807921315513, + "100.0" : 3.410807921315513 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.399675791278035, + 3.4029340490166438 + ], + [ + 3.4103607733123, + 3.410807921315513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.717810127163518, + "scoreError" : 0.004962954978142403, + "scoreConfidence" : [ + 1.7128471721853755, + 1.7227730821416605 + ], + "scorePercentiles" : { + "0.0" : 1.7169658918290782, + "50.0" : 1.7178760568128157, + "90.0" : 1.7185225031993625, + "95.0" : 1.7185225031993625, + "99.0" : 1.7185225031993625, + "99.9" : 1.7185225031993625, + "99.99" : 1.7185225031993625, + "99.999" : 1.7185225031993625, + "99.9999" : 1.7185225031993625, + "100.0" : 1.7185225031993625 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7169658918290782, + 1.7185225031993625 + ], + [ + 1.7183959945985663, + 1.7173561190270652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8626232614863947, + "scoreError" : 0.006234935229327949, + "scoreConfidence" : [ + 0.8563883262570667, + 0.8688581967157226 + ], + "scorePercentiles" : { + "0.0" : 0.8614433123591576, + "50.0" : 0.8626224986068669, + "90.0" : 0.8638047363726871, + "95.0" : 0.8638047363726871, + "99.0" : 0.8638047363726871, + "99.9" : 0.8638047363726871, + "99.99" : 0.8638047363726871, + "99.999" : 0.8638047363726871, + "99.9999" : 0.8638047363726871, + "100.0" : 0.8638047363726871 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8614433123591576, + 0.8626710710054474 + ], + [ + 0.8625739262082865, + 0.8638047363726871 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.677433385256291, + "scoreError" : 0.19462801363096613, + "scoreConfidence" : [ + 15.482805371625325, + 15.872061398887258 + ], + "scorePercentiles" : { + "0.0" : 15.462205303003266, + "50.0" : 15.726769142037734, + "90.0" : 15.78390474678472, + "95.0" : 15.78390474678472, + "99.0" : 15.78390474678472, + "99.9" : 15.78390474678472, + "99.99" : 15.78390474678472, + "99.999" : 15.78390474678472, + "99.9999" : 15.78390474678472, + "100.0" : 15.78390474678472 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.744876827392385, + 15.780592777145946, + 15.726769142037734 + ], + [ + 15.697986326859112, + 15.764693818298959, + 15.78390474678472 + ], + [ + 15.570596367740702, + 15.462205303003266, + 15.565275158043814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2566.1604164587816, + "scoreError" : 49.29470214898458, + "scoreConfidence" : [ + 2516.865714309797, + 2615.455118607766 + ], + "scorePercentiles" : { + "0.0" : 2527.888056908459, + "50.0" : 2554.397956024521, + "90.0" : 2612.178703428962, + "95.0" : 2612.178703428962, + "99.0" : 2612.178703428962, + "99.9" : 2612.178703428962, + "99.99" : 2612.178703428962, + "99.999" : 2612.178703428962, + "99.9999" : 2612.178703428962, + "100.0" : 2612.178703428962 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2567.293090950401, + 2542.9110811890646, + 2527.888056908459 + ], + [ + 2544.9517635995703, + 2554.397956024521, + 2551.336723797366 + ], + [ + 2600.377240428651, + 2594.1091318020376, + 2612.178703428962 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70595.18887645093, + "scoreError" : 702.324358673368, + "scoreConfidence" : [ + 69892.86451777756, + 71297.51323512431 + ], + "scorePercentiles" : { + "0.0" : 70235.28515029328, + "50.0" : 70360.2975377157, + "90.0" : 71187.86981658025, + "95.0" : 71187.86981658025, + "99.0" : 71187.86981658025, + "99.9" : 71187.86981658025, + "99.99" : 71187.86981658025, + "99.999" : 71187.86981658025, + "99.9999" : 71187.86981658025, + "100.0" : 71187.86981658025 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70477.2726107129, + 70286.63545650164, + 70282.00587232129 + ], + [ + 71187.86981658025, + 71180.59375003455, + 71060.22387718175 + ], + [ + 70286.51581671699, + 70235.28515029328, + 70360.2975377157 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 322.51384096300905, + "scoreError" : 15.37397122766947, + "scoreConfidence" : [ + 307.1398697353396, + 337.8878121906785 + ], + "scorePercentiles" : { + "0.0" : 311.04889485320496, + "50.0" : 322.1449897161936, + "90.0" : 334.9862414785886, + "95.0" : 334.9862414785886, + "99.0" : 334.9862414785886, + "99.9" : 334.9862414785886, + "99.99" : 334.9862414785886, + "99.999" : 334.9862414785886, + "99.9999" : 334.9862414785886, + "100.0" : 334.9862414785886 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 332.20229146610575, + 334.9862414785886, + 330.5952601484892 + ], + [ + 311.9478280671314, + 311.04889485320496, + 312.79536615560716 + ], + [ + 320.67349021117036, + 322.1449897161936, + 326.23020657059044 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 99.789343910173, + "scoreError" : 5.012338003208437, + "scoreConfidence" : [ + 94.77700590696456, + 104.80168191338144 + ], + "scorePercentiles" : { + "0.0" : 95.22725117955228, + "50.0" : 100.57495025978356, + "90.0" : 103.80877570265383, + "95.0" : 103.80877570265383, + "99.0" : 103.80877570265383, + "99.9" : 103.80877570265383, + "99.99" : 103.80877570265383, + "99.999" : 103.80877570265383, + "99.9999" : 103.80877570265383, + "100.0" : 103.80877570265383 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 101.74843432082963, + 101.28797280276068, + 99.41480547835579 + ], + [ + 97.95222559449202, + 95.22725117955228, + 95.66242419199332 + ], + [ + 100.57495025978356, + 102.4272556611359, + 103.80877570265383 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06338794162120033, + "scoreError" : 1.5726534835213874E-4, + "scoreConfidence" : [ + 0.06323067627284819, + 0.06354520696955247 + ], + "scorePercentiles" : { + "0.0" : 0.06324880637285905, + "50.0" : 0.06339518815414948, + "90.0" : 0.06354354101985703, + "95.0" : 0.06354354101985703, + "99.0" : 0.06354354101985703, + "99.9" : 0.06354354101985703, + "99.99" : 0.06354354101985703, + "99.999" : 0.06354354101985703, + "99.9999" : 0.06354354101985703, + "100.0" : 0.06354354101985703 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0633856410973144, + 0.0632769373821486, + 0.06339794185854845 + ], + [ + 0.06348533288471306, + 0.06333227822672577, + 0.06342580759448711 + ], + [ + 0.06324880637285905, + 0.06339518815414948, + 0.06354354101985703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.9592109738320277E-4, + "scoreError" : 1.830194236340082E-5, + "scoreConfidence" : [ + 3.7761915501980194E-4, + 4.142230397466036E-4 + ], + "scorePercentiles" : { + "0.0" : 3.8375898326365566E-4, + "50.0" : 3.916885380229883E-4, + "90.0" : 4.127118819188557E-4, + "95.0" : 4.127118819188557E-4, + "99.0" : 4.127118819188557E-4, + "99.9" : 4.127118819188557E-4, + "99.99" : 4.127118819188557E-4, + "99.999" : 4.127118819188557E-4, + "99.9999" : 4.127118819188557E-4, + "100.0" : 4.127118819188557E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 4.127118819188557E-4, + 4.095822106135256E-4, + 4.073474213177044E-4 + ], + [ + 3.880206140621127E-4, + 3.9356238511074627E-4, + 3.916885380229883E-4 + ], + [ + 3.885579488450353E-4, + 3.880598932942008E-4, + 3.8375898326365566E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014362073577426863, + "scoreError" : 1.0619998578927389E-4, + "scoreConfidence" : [ + 0.014255873591637588, + 0.014468273563216137 + ], + "scorePercentiles" : { + "0.0" : 0.014293950502069025, + "50.0" : 0.01433580733639829, + "90.0" : 0.014468589814818834, + "95.0" : 0.014468589814818834, + "99.0" : 0.014468589814818834, + "99.9" : 0.014468589814818834, + "99.99" : 0.014468589814818834, + "99.999" : 0.014468589814818834, + "99.9999" : 0.014468589814818834, + "100.0" : 0.014468589814818834 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014318969188826188, + 0.014298744784956768, + 0.014360223446495218 + ], + [ + 0.014293950502069025, + 0.014330278852216579, + 0.01433580733639829 + ], + [ + 0.014468589814818834, + 0.01443621848072284, + 0.01441587979033802 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9983918706205172, + "scoreError" : 0.011931758849890535, + "scoreConfidence" : [ + 0.9864601117706266, + 1.0103236294704077 + ], + "scorePercentiles" : { + "0.0" : 0.9907781139290668, + "50.0" : 0.9955621412643106, + "90.0" : 1.0086233100353001, + "95.0" : 1.0086233100353001, + "99.0" : 1.0086233100353001, + "99.9" : 1.0086233100353001, + "99.99" : 1.0086233100353001, + "99.999" : 1.0086233100353001, + "99.9999" : 1.0086233100353001, + "100.0" : 1.0086233100353001 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9920449626029164, + 0.992189108939379, + 0.9907781139290668 + ], + [ + 0.9955621412643106, + 0.9951834170564235, + 0.997519147830424 + ], + [ + 1.0086233100353001, + 1.007524445194439, + 1.0061021887323944 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013198445895714471, + "scoreError" : 5.989511316419171E-4, + "scoreConfidence" : [ + 0.012599494764072555, + 0.013797397027356387 + ], + "scorePercentiles" : { + "0.0" : 0.012995667514827657, + "50.0" : 0.01319977358985635, + "90.0" : 0.013397833911212098, + "95.0" : 0.013397833911212098, + "99.0" : 0.013397833911212098, + "99.9" : 0.013397833911212098, + "99.99" : 0.013397833911212098, + "99.999" : 0.013397833911212098, + "99.9999" : 0.013397833911212098, + "100.0" : 0.013397833911212098 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013387454538639279, + 0.013394747606418601, + 0.013397833911212098 + ], + [ + 0.012995667514827657, + 0.013012092641073418, + 0.013002879162115774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8936852214575004, + "scoreError" : 0.2642461125837702, + "scoreConfidence" : [ + 3.62943910887373, + 4.157931334041271 + ], + "scorePercentiles" : { + "0.0" : 3.78609557002271, + "50.0" : 3.8987543262238553, + "90.0" : 3.9828089665605098, + "95.0" : 3.9828089665605098, + "99.0" : 3.9828089665605098, + "99.9" : 3.9828089665605098, + "99.99" : 3.9828089665605098, + "99.999" : 3.9828089665605098, + "99.9999" : 3.9828089665605098, + "100.0" : 3.9828089665605098 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9776420389507154, + 3.9764091383147853, + 3.9828089665605098 + ], + [ + 3.78609557002271, + 3.818056100763359, + 3.821099514132926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.093584690463981, + "scoreError" : 0.025069616616546733, + "scoreConfidence" : [ + 3.068515073847434, + 3.118654307080528 + ], + "scorePercentiles" : { + "0.0" : 3.076262235004614, + "50.0" : 3.094422233910891, + "90.0" : 3.1102522154850747, + "95.0" : 3.1102522154850747, + "99.0" : 3.1102522154850747, + "99.9" : 3.1102522154850747, + "99.99" : 3.1102522154850747, + "99.999" : 3.1102522154850747, + "99.9999" : 3.1102522154850747, + "100.0" : 3.1102522154850747 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0807677498459642, + 3.077672676, + 3.079972659069911 + ], + [ + 3.094422233910891, + 3.076262235004614, + 3.108845642213242 + ], + [ + 3.1102522154850747, + 3.1085397743940337, + 3.1055270282520957 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17480657578646794, + "scoreError" : 0.003315430116910228, + "scoreConfidence" : [ + 0.1714911456695577, + 0.17812200590337818 + ], + "scorePercentiles" : { + "0.0" : 0.17214637813086364, + "50.0" : 0.1758951546944806, + "90.0" : 0.17650921792925728, + "95.0" : 0.17650921792925728, + "99.0" : 0.17650921792925728, + "99.9" : 0.17650921792925728, + "99.99" : 0.17650921792925728, + "99.999" : 0.17650921792925728, + "99.9999" : 0.17650921792925728, + "100.0" : 0.17650921792925728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17596423460787247, + 0.1758951546944806, + 0.17582233250698875 + ], + [ + 0.17225540363448455, + 0.17217202720245167, + 0.17214637813086364 + ], + [ + 0.17650921792925728, + 0.17630945460155148, + 0.17618497877026074 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3386760647654293, + "scoreError" : 0.024104901314377963, + "scoreConfidence" : [ + 0.3145711634510513, + 0.36278096607980725 + ], + "scorePercentiles" : { + "0.0" : 0.3216662912927402, + "50.0" : 0.33732743230115364, + "90.0" : 0.3561887818777604, + "95.0" : 0.3561887818777604, + "99.0" : 0.3561887818777604, + "99.9" : 0.3561887818777604, + "99.99" : 0.3561887818777604, + "99.999" : 0.3561887818777604, + "99.9999" : 0.3561887818777604, + "100.0" : 0.3561887818777604 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32364722110747923, + 0.32257669965484986, + 0.3216662912927402 + ], + [ + 0.3390080094240483, + 0.33732743230115364, + 0.33685993771684575 + ], + [ + 0.3561887818777604, + 0.3552160612723333, + 0.35559414824165275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16510065358156611, + "scoreError" : 0.0030277860479547714, + "scoreConfidence" : [ + 0.16207286753361133, + 0.1681284396295209 + ], + "scorePercentiles" : { + "0.0" : 0.1624358493925021, + "50.0" : 0.16603372570147767, + "90.0" : 0.16683119488839213, + "95.0" : 0.16683119488839213, + "99.0" : 0.16683119488839213, + "99.9" : 0.16683119488839213, + "99.99" : 0.16683119488839213, + "99.999" : 0.16683119488839213, + "99.9999" : 0.16683119488839213, + "100.0" : 0.16683119488839213 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16683119488839213, + 0.1664982001265359, + 0.16603372570147767 + ], + [ + 0.1627374155410903, + 0.1624358493925021, + 0.16319213214967607 + ], + [ + 0.16521613434882454, + 0.1664452391771109, + 0.1665159909084854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39415783773982344, + "scoreError" : 0.004520035612863572, + "scoreConfidence" : [ + 0.38963780212695986, + 0.398677873352687 + ], + "scorePercentiles" : { + "0.0" : 0.39106009846707335, + "50.0" : 0.3940456848575594, + "90.0" : 0.3981276557846962, + "95.0" : 0.3981276557846962, + "99.0" : 0.3981276557846962, + "99.9" : 0.3981276557846962, + "99.99" : 0.3981276557846962, + "99.999" : 0.3981276557846962, + "99.9999" : 0.3981276557846962, + "100.0" : 0.3981276557846962 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3967465585971594, + 0.3959194276664819, + 0.39635898129211256 + ], + [ + 0.3981276557846962, + 0.39156542715063236, + 0.3917368617988092 + ], + [ + 0.3940456848575594, + 0.39185984404388713, + 0.39106009846707335 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1591613929015046, + "scoreError" : 0.0015630194024168164, + "scoreConfidence" : [ + 0.15759837349908778, + 0.16072441230392143 + ], + "scorePercentiles" : { + "0.0" : 0.15776427671289064, + "50.0" : 0.1591903816042917, + "90.0" : 0.16114006611450393, + "95.0" : 0.16114006611450393, + "99.0" : 0.16114006611450393, + "99.9" : 0.16114006611450393, + "99.99" : 0.16114006611450393, + "99.999" : 0.16114006611450393, + "99.9999" : 0.16114006611450393, + "100.0" : 0.16114006611450393 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1593235681329361, + 0.158202761117527, + 0.15776427671289064 + ], + [ + 0.1591903816042917, + 0.15936757643946517, + 0.1591658167565933 + ], + [ + 0.16114006611450393, + 0.15932941627366007, + 0.15896867296167358 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048252539378800835, + "scoreError" : 0.0024906298363890464, + "scoreConfidence" : [ + 0.045761909542411786, + 0.050743169215189884 + ], + "scorePercentiles" : { + "0.0" : 0.04688616605403074, + "50.0" : 0.04756015620437262, + "90.0" : 0.05076947223463233, + "95.0" : 0.05076947223463233, + "99.0" : 0.05076947223463233, + "99.9" : 0.05076947223463233, + "99.99" : 0.05076947223463233, + "99.999" : 0.05076947223463233, + "99.9999" : 0.05076947223463233, + "100.0" : 0.05076947223463233 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047469081412845865, + 0.04756015620437262, + 0.047565522581443025 + ], + [ + 0.047265313576745835, + 0.0470043094303616, + 0.04688616605403074 + ], + [ + 0.05076947223463233, + 0.049876253347897, + 0.04987657956687847 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 1.014297043956772E7, + "scoreError" : 216508.6620834925, + "scoreConfidence" : [ + 9926461.777484229, + 1.0359479101651212E7 + ], + "scorePercentiles" : { + "0.0" : 9917228.294350842, + "50.0" : 1.01066923010101E7, + "90.0" : 1.0297594556584362E7, + "95.0" : 1.0297594556584362E7, + "99.0" : 1.0297594556584362E7, + "99.9" : 1.0297594556584362E7, + "99.99" : 1.0297594556584362E7, + "99.999" : 1.0297594556584362E7, + "99.9999" : 1.0297594556584362E7, + "100.0" : 1.0297594556584362E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1.0069873019114688E7, + 9917228.294350842, + 1.0068325299798792E7 + ], + [ + 1.0297594556584362E7, + 1.0280031505652621E7, + 1.007314212386707E7 + ], + [ + 1.01066923010101E7, + 1.0190103263747454E7, + 1.0283743591983557E7 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-08T02:04:26Z-6afaab511c68984a71f6a7fb0d5b6eeb3ab31b33-jdk17.json b/performance-results/2025-04-08T02:04:26Z-6afaab511c68984a71f6a7fb0d5b6eeb3ab31b33-jdk17.json new file mode 100644 index 0000000000..d25e95698f --- /dev/null +++ b/performance-results/2025-04-08T02:04:26Z-6afaab511c68984a71f6a7fb0d5b6eeb3ab31b33-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4106745227547854, + "scoreError" : 0.024123632505928624, + "scoreConfidence" : [ + 3.386550890248857, + 3.434798155260714 + ], + "scorePercentiles" : { + "0.0" : 3.4064536280469113, + "50.0" : 3.4103674161046613, + "90.0" : 3.415509630762909, + "95.0" : 3.415509630762909, + "99.0" : 3.415509630762909, + "99.9" : 3.415509630762909, + "99.99" : 3.415509630762909, + "99.999" : 3.415509630762909, + "99.9999" : 3.415509630762909, + "100.0" : 3.415509630762909 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.409905586019726, + 3.410829246189597 + ], + [ + 3.4064536280469113, + 3.415509630762909 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7210421058833152, + "scoreError" : 0.006103258258501814, + "scoreConfidence" : [ + 1.7149388476248133, + 1.727145364141817 + ], + "scorePercentiles" : { + "0.0" : 1.7204591917970213, + "50.0" : 1.7206278973318931, + "90.0" : 1.7224534370724527, + "95.0" : 1.7224534370724527, + "99.0" : 1.7224534370724527, + "99.9" : 1.7224534370724527, + "99.99" : 1.7224534370724527, + "99.999" : 1.7224534370724527, + "99.9999" : 1.7224534370724527, + "100.0" : 1.7224534370724527 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7224534370724527, + 1.7206016366680696 + ], + [ + 1.7206541579957164, + 1.7204591917970213 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8654563752967519, + "scoreError" : 0.007096537131964505, + "scoreConfidence" : [ + 0.8583598381647874, + 0.8725529124287164 + ], + "scorePercentiles" : { + "0.0" : 0.8642995449812649, + "50.0" : 0.8653988285947679, + "90.0" : 0.8667282990162068, + "95.0" : 0.8667282990162068, + "99.0" : 0.8667282990162068, + "99.9" : 0.8667282990162068, + "99.99" : 0.8667282990162068, + "99.999" : 0.8667282990162068, + "99.9999" : 0.8667282990162068, + "100.0" : 0.8667282990162068 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8667282990162068, + 0.8659712970328545 + ], + [ + 0.8642995449812649, + 0.8648263601566814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.039169161977497, + "scoreError" : 0.08986157586072346, + "scoreConfidence" : [ + 15.949307586116774, + 16.12903073783822 + ], + "scorePercentiles" : { + "0.0" : 15.939752753713112, + "50.0" : 16.069130366420104, + "90.0" : 16.080801611150523, + "95.0" : 16.080801611150523, + "99.0" : 16.080801611150523, + "99.9" : 16.080801611150523, + "99.99" : 16.080801611150523, + "99.999" : 16.080801611150523, + "99.9999" : 16.080801611150523, + "100.0" : 16.080801611150523 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.97787230253739, + 15.996364760659104, + 15.939752753713112 + ], + [ + 16.05469876719471, + 16.080763707650004, + 16.080801611150523 + ], + [ + 16.0751730730727, + 16.07796511539983, + 16.069130366420104 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2630.1625248887117, + "scoreError" : 57.209961329511565, + "scoreConfidence" : [ + 2572.9525635592, + 2687.3724862182235 + ], + "scorePercentiles" : { + "0.0" : 2592.798432229326, + "50.0" : 2622.3161216064136, + "90.0" : 2678.388945940704, + "95.0" : 2678.388945940704, + "99.0" : 2678.388945940704, + "99.9" : 2678.388945940704, + "99.99" : 2678.388945940704, + "99.999" : 2678.388945940704, + "99.9999" : 2678.388945940704, + "100.0" : 2678.388945940704 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2622.3161216064136, + 2619.643989158748, + 2624.7367627947256 + ], + [ + 2592.798432229326, + 2594.1657410301773, + 2599.917540416809 + ], + [ + 2678.388945940704, + 2671.223826252167, + 2668.271364569331 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70019.6169006723, + "scoreError" : 1547.201487134348, + "scoreConfidence" : [ + 68472.41541353796, + 71566.81838780665 + ], + "scorePercentiles" : { + "0.0" : 68794.21140727811, + "50.0" : 70492.56392294558, + "90.0" : 70809.26628461784, + "95.0" : 70809.26628461784, + "99.0" : 70809.26628461784, + "99.9" : 70809.26628461784, + "99.99" : 70809.26628461784, + "99.999" : 70809.26628461784, + "99.9999" : 70809.26628461784, + "100.0" : 70809.26628461784 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70399.38096656189, + 70492.56392294558, + 70501.01512060892 + ], + [ + 68796.08737174375, + 68794.21140727811, + 68830.70340712844 + ], + [ + 70768.19688711762, + 70809.26628461784, + 70785.12673804846 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 339.36903665076335, + "scoreError" : 14.334132583726097, + "scoreConfidence" : [ + 325.03490406703725, + 353.70316923448945 + ], + "scorePercentiles" : { + "0.0" : 325.1765145164509, + "50.0" : 344.0451947702268, + "90.0" : 345.8774124409928, + "95.0" : 345.8774124409928, + "99.0" : 345.8774124409928, + "99.9" : 345.8774124409928, + "99.99" : 345.8774124409928, + "99.999" : 345.8774124409928, + "99.9999" : 345.8774124409928, + "100.0" : 345.8774124409928 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.21681690101633, + 345.41313484856335, + 345.8774124409928 + ], + [ + 330.10532856465244, + 329.26548958525694, + 325.1765145164509 + ], + [ + 343.41495222249574, + 344.0451947702268, + 345.80648600721514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.83901719837074, + "scoreError" : 0.7838467724176471, + "scoreConfidence" : [ + 104.0551704259531, + 105.62286397078839 + ], + "scorePercentiles" : { + "0.0" : 103.89732083095693, + "50.0" : 104.92977893531283, + "90.0" : 105.4224951842652, + "95.0" : 105.4224951842652, + "99.0" : 105.4224951842652, + "99.9" : 105.4224951842652, + "99.99" : 105.4224951842652, + "99.999" : 105.4224951842652, + "99.9999" : 105.4224951842652, + "100.0" : 105.4224951842652 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.7047542000011, + 104.84750442724584, + 104.36712427236051 + ], + [ + 104.92977893531283, + 105.17436061540405, + 105.4224951842652 + ], + [ + 103.89732083095693, + 105.18003958420395, + 105.02777673558612 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06252812410824989, + "scoreError" : 8.532023009857468E-4, + "scoreConfidence" : [ + 0.06167492180726414, + 0.06338132640923563 + ], + "scorePercentiles" : { + "0.0" : 0.06183504901257621, + "50.0" : 0.0623134390239343, + "90.0" : 0.06324152939428052, + "95.0" : 0.06324152939428052, + "99.0" : 0.06324152939428052, + "99.9" : 0.06324152939428052, + "99.99" : 0.06324152939428052, + "99.999" : 0.06324152939428052, + "99.9999" : 0.06324152939428052, + "100.0" : 0.06324152939428052 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06183504901257621, + 0.062202279838027466, + 0.0623134390239343 + ], + [ + 0.06219473836355947, + 0.062296954038025466, + 0.062397182677548575 + ], + [ + 0.06314039521404217, + 0.06313154941225489, + 0.06324152939428052 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6696603099080084E-4, + "scoreError" : 1.66230079353207E-5, + "scoreConfidence" : [ + 3.5034302305548014E-4, + 3.8358903892612154E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5855721342641257E-4, + "50.0" : 3.61532641186855E-4, + "90.0" : 3.807798742550273E-4, + "95.0" : 3.807798742550273E-4, + "99.0" : 3.807798742550273E-4, + "99.9" : 3.807798742550273E-4, + "99.99" : 3.807798742550273E-4, + "99.999" : 3.807798742550273E-4, + "99.9999" : 3.807798742550273E-4, + "100.0" : 3.807798742550273E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.61532641186855E-4, + 3.6175184273219994E-4, + 3.6120773541345187E-4 + ], + [ + 3.8077661358790953E-4, + 3.807798742550273E-4, + 3.7861814931453106E-4 + ], + [ + 3.5855721342641257E-4, + 3.593154338296459E-4, + 3.601547751711743E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014266204467328089, + "scoreError" : 4.1408579985298394E-4, + "scoreConfidence" : [ + 0.013852118667475105, + 0.014680290267181073 + ], + "scorePercentiles" : { + "0.0" : 0.014054820680863743, + "50.0" : 0.014150934975766796, + "90.0" : 0.014594906274263696, + "95.0" : 0.014594906274263696, + "99.0" : 0.014594906274263696, + "99.9" : 0.014594906274263696, + "99.99" : 0.014594906274263696, + "99.999" : 0.014594906274263696, + "99.9999" : 0.014594906274263696, + "100.0" : 0.014594906274263696 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014153143222289213, + 0.014150934975766796, + 0.014147816421464255 + ], + [ + 0.014054820680863743, + 0.014060506540161216, + 0.014057680542845214 + ], + [ + 0.014592110212896353, + 0.014594906274263696, + 0.014583921335402277 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9860856320916257, + "scoreError" : 0.011298110430866136, + "scoreConfidence" : [ + 0.9747875216607595, + 0.9973837425224918 + ], + "scorePercentiles" : { + "0.0" : 0.9768496805040047, + "50.0" : 0.9894034636921251, + "90.0" : 0.9924821984914649, + "95.0" : 0.9924821984914649, + "99.0" : 0.9924821984914649, + "99.9" : 0.9924821984914649, + "99.99" : 0.9924821984914649, + "99.999" : 0.9924821984914649, + "99.9999" : 0.9924821984914649, + "100.0" : 0.9924821984914649 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9894034636921251, + 0.9895949228181279, + 0.989354845370004 + ], + [ + 0.9924821984914649, + 0.9902797075948113, + 0.991923799642928 + ], + [ + 0.9778032469691044, + 0.9770788237420616, + 0.9768496805040047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013128283938799265, + "scoreError" : 0.0012657419077312822, + "scoreConfidence" : [ + 0.011862542031067983, + 0.014394025846530547 + ], + "scorePercentiles" : { + "0.0" : 0.012636009067383701, + "50.0" : 0.013204896402692226, + "90.0" : 0.013561459875454974, + "95.0" : 0.013561459875454974, + "99.0" : 0.013561459875454974, + "99.9" : 0.013561459875454974, + "99.99" : 0.013561459875454974, + "99.999" : 0.013561459875454974, + "99.9999" : 0.013561459875454974, + "100.0" : 0.013561459875454974 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012901341007725137, + 0.012640616877338457, + 0.012636009067383701 + ], + [ + 0.013521825007234011, + 0.013508451797659315, + 0.013561459875454974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.9252737683700407, + "scoreError" : 0.08983425073427523, + "scoreConfidence" : [ + 3.8354395176357654, + 4.015108019104316 + ], + "scorePercentiles" : { + "0.0" : 3.896490785825545, + "50.0" : 3.9164602392095684, + "90.0" : 3.9681580150674067, + "95.0" : 3.9681580150674067, + "99.0" : 3.9681580150674067, + "99.9" : 3.9681580150674067, + "99.99" : 3.9681580150674067, + "99.999" : 3.9681580150674067, + "99.9999" : 3.9681580150674067, + "100.0" : 3.9681580150674067 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9312583333333335, + 3.9681580150674067, + 3.9575685443037973 + ], + [ + 3.896490785825545, + 3.9016621450858033, + 3.8965047866043614 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.940115475982663, + "scoreError" : 0.1079441585697692, + "scoreConfidence" : [ + 2.832171317412894, + 3.0480596345524322 + ], + "scorePercentiles" : { + "0.0" : 2.8560816122215877, + "50.0" : 2.9505492666666666, + "90.0" : 3.034462321601942, + "95.0" : 3.034462321601942, + "99.0" : 3.034462321601942, + "99.9" : 3.034462321601942, + "99.99" : 3.034462321601942, + "99.999" : 3.034462321601942, + "99.9999" : 3.034462321601942, + "100.0" : 3.034462321601942 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9787892355568792, + 2.975750072597441, + 3.034462321601942 + ], + [ + 2.8676906290137616, + 2.859544243567753, + 2.8560816122215877 + ], + [ + 2.949631930404011, + 2.9505492666666666, + 2.988539972213923 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17802944681101765, + "scoreError" : 0.006233857528802094, + "scoreConfidence" : [ + 0.17179558928221556, + 0.18426330433981974 + ], + "scorePercentiles" : { + "0.0" : 0.173863887391773, + "50.0" : 0.17729219266022517, + "90.0" : 0.18305629819326732, + "95.0" : 0.18305629819326732, + "99.0" : 0.18305629819326732, + "99.9" : 0.18305629819326732, + "99.99" : 0.18305629819326732, + "99.999" : 0.18305629819326732, + "99.9999" : 0.18305629819326732, + "100.0" : 0.18305629819326732 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1825907695917324, + 0.18305629819326732, + 0.18212997676070447 + ], + [ + 0.17465364324012783, + 0.173863887391773, + 0.173905442647468 + ], + [ + 0.17758387770141887, + 0.17718893311244197, + 0.17729219266022517 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3280036696752776, + "scoreError" : 0.0072904870277840615, + "scoreConfidence" : [ + 0.32071318264749354, + 0.3352941567030617 + ], + "scorePercentiles" : { + "0.0" : 0.3230449766765732, + "50.0" : 0.3285960677553971, + "90.0" : 0.3350218208710218, + "95.0" : 0.3350218208710218, + "99.0" : 0.3350218208710218, + "99.9" : 0.3350218208710218, + "99.99" : 0.3350218208710218, + "99.999" : 0.3350218208710218, + "99.9999" : 0.3350218208710218, + "100.0" : 0.3350218208710218 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3350218208710218, + 0.3313785579892637, + 0.33214259798060314 + ], + [ + 0.3230449766765732, + 0.32308109058895745, + 0.323336461088299 + ], + [ + 0.3267985959282376, + 0.32863285819914556, + 0.3285960677553971 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16393034011616078, + "scoreError" : 0.010818336189738688, + "scoreConfidence" : [ + 0.1531120039264221, + 0.17474867630589946 + ], + "scorePercentiles" : { + "0.0" : 0.1572548254839369, + "50.0" : 0.16263789347514962, + "90.0" : 0.1721502192976416, + "95.0" : 0.1721502192976416, + "99.0" : 0.1721502192976416, + "99.9" : 0.1721502192976416, + "99.99" : 0.1721502192976416, + "99.999" : 0.1721502192976416, + "99.9999" : 0.1721502192976416, + "100.0" : 0.1721502192976416 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1572548254839369, + 0.15726288619100787, + 0.15731232625965486 + ], + [ + 0.16263789347514962, + 0.16286263915443872, + 0.16219788980439226 + ], + [ + 0.1721502192976416, + 0.17194005434913429, + 0.1717543270300907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3900127802781739, + "scoreError" : 0.010040535270291057, + "scoreConfidence" : [ + 0.37997224500788285, + 0.4000533155484649 + ], + "scorePercentiles" : { + "0.0" : 0.3857957074958528, + "50.0" : 0.387306897211464, + "90.0" : 0.40456259678789597, + "95.0" : 0.40456259678789597, + "99.0" : 0.40456259678789597, + "99.9" : 0.40456259678789597, + "99.99" : 0.40456259678789597, + "99.999" : 0.40456259678789597, + "99.9999" : 0.40456259678789597, + "100.0" : 0.40456259678789597 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39098822140986045, + 0.387306897211464, + 0.38692783339137166 + ], + [ + 0.40456259678789597, + 0.392978785632884, + 0.3891036243725925 + ], + [ + 0.386120248030888, + 0.3863311081707553, + 0.3857957074958528 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16098246355631118, + "scoreError" : 0.0016169925436001703, + "scoreConfidence" : [ + 0.159365471012711, + 0.16259945609991136 + ], + "scorePercentiles" : { + "0.0" : 0.159929256872811, + "50.0" : 0.16084167420465145, + "90.0" : 0.16264033896596028, + "95.0" : 0.16264033896596028, + "99.0" : 0.16264033896596028, + "99.9" : 0.16264033896596028, + "99.99" : 0.16264033896596028, + "99.999" : 0.16264033896596028, + "99.9999" : 0.16264033896596028, + "100.0" : 0.16264033896596028 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16264033896596028, + 0.16204472218171212, + 0.1616688600297465 + ], + [ + 0.16006754341736695, + 0.159929256872811, + 0.15995681565309192 + ], + [ + 0.16089218724157348, + 0.1608007734398868, + 0.16084167420465145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04693083593108395, + "scoreError" : 0.0013197680187504504, + "scoreConfidence" : [ + 0.0456110679123335, + 0.0482506039498344 + ], + "scorePercentiles" : { + "0.0" : 0.04617824880977119, + "50.0" : 0.04651635501276857, + "90.0" : 0.04846171708399766, + "95.0" : 0.04846171708399766, + "99.0" : 0.04846171708399766, + "99.9" : 0.04846171708399766, + "99.99" : 0.04846171708399766, + "99.999" : 0.04846171708399766, + "99.9999" : 0.04846171708399766, + "100.0" : 0.04846171708399766 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04718569986599475, + 0.04623054528685683, + 0.04617824880977119 + ], + [ + 0.04846171708399766, + 0.04752103033226254, + 0.047513170142204866 + ], + [ + 0.04651635501276857, + 0.046471550743764786, + 0.04629920610213436 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9493043.184075, + "scoreError" : 396627.359347403, + "scoreConfidence" : [ + 9096415.824727597, + 9889670.543422403 + ], + "scorePercentiles" : { + "0.0" : 9246875.504621072, + "50.0" : 9382336.876172608, + "90.0" : 9833868.79252704, + "95.0" : 9833868.79252704, + "99.0" : 9833868.79252704, + "99.9" : 9833868.79252704, + "99.99" : 9833868.79252704, + "99.999" : 9833868.79252704, + "99.9999" : 9833868.79252704, + "100.0" : 9833868.79252704 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9833868.79252704, + 9828432.62475442, + 9740735.680623174 + ], + [ + 9316690.216014897, + 9355467.715622077, + 9385929.39587242 + ], + [ + 9382336.876172608, + 9347051.850467289, + 9246875.504621072 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-10T04:33:55Z-78f257de548f6acca271b8a6db4dab8ac414bb17-jdk17.json b/performance-results/2025-04-10T04:33:55Z-78f257de548f6acca271b8a6db4dab8ac414bb17-jdk17.json new file mode 100644 index 0000000000..a74e4d4f90 --- /dev/null +++ b/performance-results/2025-04-10T04:33:55Z-78f257de548f6acca271b8a6db4dab8ac414bb17-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.424886185220211, + "scoreError" : 0.02288937204720089, + "scoreConfidence" : [ + 3.4019968131730103, + 3.447775557267412 + ], + "scorePercentiles" : { + "0.0" : 3.4223046552592433, + "50.0" : 3.423618714442802, + "90.0" : 3.4300026567359976, + "95.0" : 3.4300026567359976, + "99.0" : 3.4300026567359976, + "99.9" : 3.4300026567359976, + "99.99" : 3.4300026567359976, + "99.999" : 3.4300026567359976, + "99.9999" : 3.4300026567359976, + "100.0" : 3.4300026567359976 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4223046552592433, + 3.4300026567359976 + ], + [ + 3.422728473427089, + 3.4245089554585153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7271315754975538, + "scoreError" : 0.004966103870763177, + "scoreConfidence" : [ + 1.7221654716267907, + 1.732097679368317 + ], + "scorePercentiles" : { + "0.0" : 1.726486474885949, + "50.0" : 1.726916712033872, + "90.0" : 1.7282064030365223, + "95.0" : 1.7282064030365223, + "99.0" : 1.7282064030365223, + "99.9" : 1.7282064030365223, + "99.99" : 1.7282064030365223, + "99.999" : 1.7282064030365223, + "99.9999" : 1.7282064030365223, + "100.0" : 1.7282064030365223 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7266842453323068, + 1.727149178735437 + ], + [ + 1.726486474885949, + 1.7282064030365223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8684024984939731, + "scoreError" : 0.005240325724240037, + "scoreConfidence" : [ + 0.8631621727697331, + 0.8736428242182132 + ], + "scorePercentiles" : { + "0.0" : 0.867397723899297, + "50.0" : 0.8684580073972272, + "90.0" : 0.8692962552821406, + "95.0" : 0.8692962552821406, + "99.0" : 0.8692962552821406, + "99.9" : 0.8692962552821406, + "99.99" : 0.8692962552821406, + "99.999" : 0.8692962552821406, + "99.9999" : 0.8692962552821406, + "100.0" : 0.8692962552821406 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.867397723899297, + 0.8681766130206038 + ], + [ + 0.8687394017738508, + 0.8692962552821406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.032129452957125, + "scoreError" : 0.08373484051320008, + "scoreConfidence" : [ + 15.948394612443925, + 16.115864293470324 + ], + "scorePercentiles" : { + "0.0" : 15.965720170110863, + "50.0" : 16.04646865645673, + "90.0" : 16.09750002308707, + "95.0" : 16.09750002308707, + "99.0" : 16.09750002308707, + "99.9" : 16.09750002308707, + "99.99" : 16.09750002308707, + "99.999" : 16.09750002308707, + "99.9999" : 16.09750002308707, + "100.0" : 16.09750002308707 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.04878306057498, + 16.026522462299912, + 16.04646865645673 + ], + [ + 16.093985459126838, + 16.09750002308707, + 16.057319615113542 + ], + [ + 15.965720170110863, + 15.977066380139977, + 15.975799249704208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2659.2660480465156, + "scoreError" : 52.83065843292076, + "scoreConfidence" : [ + 2606.435389613595, + 2712.0967064794363 + ], + "scorePercentiles" : { + "0.0" : 2623.490342043969, + "50.0" : 2655.8428612692337, + "90.0" : 2697.8381159598043, + "95.0" : 2697.8381159598043, + "99.0" : 2697.8381159598043, + "99.9" : 2697.8381159598043, + "99.99" : 2697.8381159598043, + "99.999" : 2697.8381159598043, + "99.9999" : 2697.8381159598043, + "100.0" : 2697.8381159598043 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2623.490342043969, + 2623.8076996606283, + 2625.3335784847322 + ], + [ + 2655.0094683322463, + 2655.8428612692337, + 2660.0529731999677 + ], + [ + 2696.188039456565, + 2695.8313540114987, + 2697.8381159598043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70628.75811851461, + "scoreError" : 416.83448272910647, + "scoreConfidence" : [ + 70211.92363578551, + 71045.59260124371 + ], + "scorePercentiles" : { + "0.0" : 70234.43023788626, + "50.0" : 70776.68712267073, + "90.0" : 70820.05528670856, + "95.0" : 70820.05528670856, + "99.0" : 70820.05528670856, + "99.9" : 70820.05528670856, + "99.99" : 70820.05528670856, + "99.999" : 70820.05528670856, + "99.9999" : 70820.05528670856, + "100.0" : 70820.05528670856 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70391.61966832611, + 70234.43023788626, + 70283.23188861534 + ], + [ + 70764.00845841023, + 70795.94033197615, + 70776.68712267073 + ], + [ + 70820.05528670856, + 70805.76311128291, + 70787.08696075529 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 355.4878415324151, + "scoreError" : 3.8495329535968454, + "scoreConfidence" : [ + 351.6383085788182, + 359.3373744860119 + ], + "scorePercentiles" : { + "0.0" : 351.33385265402495, + "50.0" : 356.39817493867076, + "90.0" : 357.66606585973585, + "95.0" : 357.66606585973585, + "99.0" : 357.66606585973585, + "99.9" : 357.66606585973585, + "99.99" : 357.66606585973585, + "99.999" : 357.66606585973585, + "99.9999" : 357.66606585973585, + "100.0" : 357.66606585973585 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 353.13811300477545, + 353.35272596351626, + 351.33385265402495 + ], + [ + 357.1934660742412, + 357.592585496536, + 357.66606585973585 + ], + [ + 356.0259282003938, + 356.39817493867076, + 356.6896615998413 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.85676686228155, + "scoreError" : 1.5434947978753855, + "scoreConfidence" : [ + 105.31327206440616, + 108.40026166015693 + ], + "scorePercentiles" : { + "0.0" : 105.82738952101255, + "50.0" : 106.35365150408913, + "90.0" : 108.10528228128692, + "95.0" : 108.10528228128692, + "99.0" : 108.10528228128692, + "99.9" : 108.10528228128692, + "99.99" : 108.10528228128692, + "99.999" : 108.10528228128692, + "99.9999" : 108.10528228128692, + "100.0" : 108.10528228128692 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.01469264211123, + 108.10528228128692, + 108.04302695630714 + ], + [ + 106.33565873861741, + 106.35365150408913, + 106.54797025010714 + ], + [ + 105.82738952101255, + 106.18684839779065, + 106.29638146921167 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061552231147395865, + "scoreError" : 3.8671400517215505E-4, + "scoreConfidence" : [ + 0.06116551714222371, + 0.06193894515256802 + ], + "scorePercentiles" : { + "0.0" : 0.06123520343892178, + "50.0" : 0.06162852530736758, + "90.0" : 0.061795015405245075, + "95.0" : 0.061795015405245075, + "99.0" : 0.061795015405245075, + "99.9" : 0.061795015405245075, + "99.99" : 0.061795015405245075, + "99.999" : 0.061795015405245075, + "99.9999" : 0.061795015405245075, + "100.0" : 0.061795015405245075 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061780295837297515, + 0.061795015405245075, + 0.06174503386659587 + ], + [ + 0.06123520343892178, + 0.06127275373605299, + 0.06126781611322142 + ], + [ + 0.06162852530736758, + 0.06161100870550979, + 0.06163442791635079 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7328350128866886E-4, + "scoreError" : 6.821877107806369E-6, + "scoreConfidence" : [ + 3.664616241808625E-4, + 3.801053783964752E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6756358457330426E-4, + "50.0" : 3.7591985938495296E-4, + "90.0" : 3.7651412265522115E-4, + "95.0" : 3.7651412265522115E-4, + "99.0" : 3.7651412265522115E-4, + "99.9" : 3.7651412265522115E-4, + "99.99" : 3.7651412265522115E-4, + "99.999" : 3.7651412265522115E-4, + "99.9999" : 3.7651412265522115E-4, + "100.0" : 3.7651412265522115E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6756358457330426E-4, + 3.67879946293119E-4, + 3.683010133688077E-4 + ], + [ + 3.7651412265522115E-4, + 3.7601604683122045E-4, + 3.763907991729729E-4 + ], + [ + 3.7615964157218306E-4, + 3.7591985938495296E-4, + 3.748064977462384E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01419174351532329, + "scoreError" : 3.5269317026143744E-4, + "scoreConfidence" : [ + 0.013839050345061853, + 0.014544436685584729 + ], + "scorePercentiles" : { + "0.0" : 0.014018094766825723, + "50.0" : 0.014079585394561962, + "90.0" : 0.014472452002674477, + "95.0" : 0.014472452002674477, + "99.0" : 0.014472452002674477, + "99.9" : 0.014472452002674477, + "99.99" : 0.014472452002674477, + "99.999" : 0.014472452002674477, + "99.9999" : 0.014472452002674477, + "100.0" : 0.014472452002674477 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014030071913104356, + 0.014018094766825723, + 0.014024899786263053 + ], + [ + 0.014079585394561962, + 0.014078321295583264, + 0.014085909656899617 + ], + [ + 0.014472452002674477, + 0.014468795468718125, + 0.014467561353279033 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9945057544056086, + "scoreError" : 0.036416468403792125, + "scoreConfidence" : [ + 0.9580892860018165, + 1.0309222228094008 + ], + "scorePercentiles" : { + "0.0" : 0.968692614974816, + "50.0" : 0.984372430062014, + "90.0" : 1.0242185525399425, + "95.0" : 1.0242185525399425, + "99.0" : 1.0242185525399425, + "99.9" : 1.0242185525399425, + "99.99" : 1.0242185525399425, + "99.999" : 1.0242185525399425, + "99.9999" : 1.0242185525399425, + "100.0" : 1.0242185525399425 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.984372430062014, + 0.9846667744190626, + 0.9812977671474831 + ], + [ + 1.0223313447147822, + 1.0215115833503574, + 1.0242185525399425 + ], + [ + 0.968692614974816, + 0.9831266424498624, + 0.9803340799921576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.0132303658430084, + "scoreError" : 3.9247364190063487E-4, + "scoreConfidence" : [ + 0.012837892201107766, + 0.013622839484909034 + ], + "scorePercentiles" : { + "0.0" : 0.013031519580707543, + "50.0" : 0.013249929718698584, + "90.0" : 0.013353252362131125, + "95.0" : 0.013353252362131125, + "99.0" : 0.013353252362131125, + "99.9" : 0.013353252362131125, + "99.99" : 0.013353252362131125, + "99.999" : 0.013353252362131125, + "99.9999" : 0.013353252362131125, + "100.0" : 0.013353252362131125 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013031519580707543, + 0.013144478228066393, + 0.01314967844763653 + ], + [ + 0.013353085449748166, + 0.013353252362131125, + 0.013350180989760636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6392078634851894, + "scoreError" : 0.06541333766466793, + "scoreConfidence" : [ + 3.5737945258205217, + 3.704621201149857 + ], + "scorePercentiles" : { + "0.0" : 3.6007005737940965, + "50.0" : 3.6402839559568614, + "90.0" : 3.66594598973607, + "95.0" : 3.66594598973607, + "99.0" : 3.66594598973607, + "99.9" : 3.66594598973607, + "99.99" : 3.66594598973607, + "99.999" : 3.66594598973607, + "99.9999" : 3.66594598973607, + "100.0" : 3.66594598973607 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6007005737940965, + 3.6389140305454544, + 3.641653881368268 + ], + [ + 3.628675238751814, + 3.659357466715435, + 3.66594598973607 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.861272924329247, + "scoreError" : 0.036385695606204325, + "scoreConfidence" : [ + 2.8248872287230427, + 2.8976586199354513 + ], + "scorePercentiles" : { + "0.0" : 2.825970594800791, + "50.0" : 2.8757847725704426, + "90.0" : 2.881069466724287, + "95.0" : 2.881069466724287, + "99.0" : 2.881069466724287, + "99.9" : 2.881069466724287, + "99.99" : 2.881069466724287, + "99.999" : 2.881069466724287, + "99.9999" : 2.881069466724287, + "100.0" : 2.881069466724287 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8412861664772726, + 2.8516040481893357, + 2.825970594800791 + ], + [ + 2.8793874217040876, + 2.881069466724287, + 2.8757847725704426 + ], + [ + 2.8795824411171895, + 2.8774763659378597, + 2.839295041441953 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1736661846677111, + "scoreError" : 0.003713448810268133, + "scoreConfidence" : [ + 0.16995273585744297, + 0.17737963347797925 + ], + "scorePercentiles" : { + "0.0" : 0.17086125760319848, + "50.0" : 0.17387487196160933, + "90.0" : 0.176499382392912, + "95.0" : 0.176499382392912, + "99.0" : 0.176499382392912, + "99.9" : 0.176499382392912, + "99.99" : 0.176499382392912, + "99.999" : 0.176499382392912, + "99.9999" : 0.176499382392912, + "100.0" : 0.176499382392912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17416599188407816, + 0.17387487196160933, + 0.17375947067000277 + ], + [ + 0.176499382392912, + 0.17581156517993707, + 0.17586875428229748 + ], + [ + 0.17100749628920278, + 0.17114687174616214, + 0.17086125760319848 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32531769290505985, + "scoreError" : 0.004017758806714038, + "scoreConfidence" : [ + 0.32129993409834584, + 0.32933545171177386 + ], + "scorePercentiles" : { + "0.0" : 0.3224649505675222, + "50.0" : 0.3248864432929405, + "90.0" : 0.3287259787317971, + "95.0" : 0.3287259787317971, + "99.0" : 0.3287259787317971, + "99.9" : 0.3287259787317971, + "99.99" : 0.3287259787317971, + "99.999" : 0.3287259787317971, + "99.9999" : 0.3287259787317971, + "100.0" : 0.3287259787317971 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3248864432929405, + 0.3251668364765559, + 0.3248066146875406 + ], + [ + 0.3287259787317971, + 0.3279436203843379, + 0.32798270596917023 + ], + [ + 0.3232667449814126, + 0.32261534105426154, + 0.3224649505675222 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16216252799698816, + "scoreError" : 0.010414055226397255, + "scoreConfidence" : [ + 0.1517484727705909, + 0.17257658322338543 + ], + "scorePercentiles" : { + "0.0" : 0.15376685839932344, + "50.0" : 0.16590980272086273, + "90.0" : 0.16717917788959843, + "95.0" : 0.16717917788959843, + "99.0" : 0.16717917788959843, + "99.9" : 0.16717917788959843, + "99.99" : 0.16717917788959843, + "99.999" : 0.16717917788959843, + "99.9999" : 0.16717917788959843, + "100.0" : 0.16717917788959843 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16608696150205113, + 0.16462984212172596, + 0.16590980272086273 + ], + [ + 0.16717917788959843, + 0.16689216715620828, + 0.16688292889207818 + ], + [ + 0.15394207102723173, + 0.1541729422638135, + 0.15376685839932344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3910526805304007, + "scoreError" : 0.005573550516625776, + "scoreConfidence" : [ + 0.38547913001377493, + 0.3966262310470265 + ], + "scorePercentiles" : { + "0.0" : 0.3877020788555478, + "50.0" : 0.39071458187145924, + "90.0" : 0.39725935577801613, + "95.0" : 0.39725935577801613, + "99.0" : 0.39725935577801613, + "99.9" : 0.39725935577801613, + "99.99" : 0.39725935577801613, + "99.999" : 0.39725935577801613, + "99.9999" : 0.39725935577801613, + "100.0" : 0.39725935577801613 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39442088356866767, + 0.39264162731163377, + 0.3919065695026845 + ], + [ + 0.39071458187145924, + 0.38879390381400414, + 0.38811062013428027 + ], + [ + 0.39725935577801613, + 0.3879245039373133, + 0.3877020788555478 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1592241740494486, + "scoreError" : 0.0018199006554632427, + "scoreConfidence" : [ + 0.15740427339398536, + 0.16104407470491186 + ], + "scorePercentiles" : { + "0.0" : 0.15746357693518928, + "50.0" : 0.15947281740766728, + "90.0" : 0.16109741302596817, + "95.0" : 0.16109741302596817, + "99.0" : 0.16109741302596817, + "99.9" : 0.16109741302596817, + "99.99" : 0.16109741302596817, + "99.999" : 0.16109741302596817, + "99.9999" : 0.16109741302596817, + "100.0" : 0.16109741302596817 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15836762342824565, + 0.15746357693518928, + 0.1581412618128914 + ], + [ + 0.1594747038448658, + 0.15947281740766728, + 0.15934576122566046 + ], + [ + 0.16109741302596817, + 0.1598520538371777, + 0.1598023549273718 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04712108750819384, + "scoreError" : 7.182684687481833E-4, + "scoreConfidence" : [ + 0.04640281903944566, + 0.04783935597694202 + ], + "scorePercentiles" : { + "0.0" : 0.04651576728500725, + "50.0" : 0.04719090808747192, + "90.0" : 0.047708944186024324, + "95.0" : 0.047708944186024324, + "99.0" : 0.047708944186024324, + "99.9" : 0.047708944186024324, + "99.99" : 0.047708944186024324, + "99.999" : 0.047708944186024324, + "99.9999" : 0.047708944186024324, + "100.0" : 0.047708944186024324 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04719090808747192, + 0.04702287955234759, + 0.04695951733481097 + ], + [ + 0.047708944186024324, + 0.04723783189260172, + 0.04724911852754823 + ], + [ + 0.04768475045896058, + 0.04651576728500725, + 0.04652007024897192 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9310568.23100094, + "scoreError" : 173148.93658738173, + "scoreConfidence" : [ + 9137419.294413557, + 9483717.167588321 + ], + "scorePercentiles" : { + "0.0" : 9169324.511457378, + "50.0" : 9329873.112873135, + "90.0" : 9459066.508506617, + "95.0" : 9459066.508506617, + "99.0" : 9459066.508506617, + "99.9" : 9459066.508506617, + "99.99" : 9459066.508506617, + "99.999" : 9459066.508506617, + "99.9999" : 9459066.508506617, + "100.0" : 9459066.508506617 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9218835.206451613, + 9184230.989898989, + 9169324.511457378 + ], + [ + 9459066.508506617, + 9410630.807149576, + 9397396.217840375 + ], + [ + 9295238.24535316, + 9330518.479477612, + 9329873.112873135 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-11T02:44:53Z-5a3f64d6241fca6e2bbf218086f3b16f1a2e36eb-jdk17.json b/performance-results/2025-04-11T02:44:53Z-5a3f64d6241fca6e2bbf218086f3b16f1a2e36eb-jdk17.json new file mode 100644 index 0000000000..842cf3719c --- /dev/null +++ b/performance-results/2025-04-11T02:44:53Z-5a3f64d6241fca6e2bbf218086f3b16f1a2e36eb-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.40265301185707, + "scoreError" : 0.027431673626871933, + "scoreConfidence" : [ + 3.375221338230198, + 3.430084685483942 + ], + "scorePercentiles" : { + "0.0" : 3.3965504921908103, + "50.0" : 3.4039265655019424, + "90.0" : 3.4062084242335846, + "95.0" : 3.4062084242335846, + "99.0" : 3.4062084242335846, + "99.9" : 3.4062084242335846, + "99.99" : 3.4062084242335846, + "99.999" : 3.4062084242335846, + "99.9999" : 3.4062084242335846, + "100.0" : 3.4062084242335846 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.403242248782115, + 3.4062084242335846 + ], + [ + 3.3965504921908103, + 3.4046108822217693 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7175936798859224, + "scoreError" : 0.0134684701590882, + "scoreConfidence" : [ + 1.7041252097268342, + 1.7310621500450105 + ], + "scorePercentiles" : { + "0.0" : 1.7153447300577356, + "50.0" : 1.7177008710932307, + "90.0" : 1.7196282472994926, + "95.0" : 1.7196282472994926, + "99.0" : 1.7196282472994926, + "99.9" : 1.7196282472994926, + "99.99" : 1.7196282472994926, + "99.999" : 1.7196282472994926, + "99.9999" : 1.7196282472994926, + "100.0" : 1.7196282472994926 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7153447300577356, + 1.7163202538817688 + ], + [ + 1.7196282472994926, + 1.7190814883046928 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8651047413453794, + "scoreError" : 0.008605148330017314, + "scoreConfidence" : [ + 0.856499593015362, + 0.8737098896753968 + ], + "scorePercentiles" : { + "0.0" : 0.8632352159731381, + "50.0" : 0.8654020379044889, + "90.0" : 0.8663796735994017, + "95.0" : 0.8663796735994017, + "99.0" : 0.8663796735994017, + "99.9" : 0.8663796735994017, + "99.99" : 0.8663796735994017, + "99.999" : 0.8663796735994017, + "99.9999" : 0.8663796735994017, + "100.0" : 0.8663796735994017 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.865295790358891, + 0.8663796735994017 + ], + [ + 0.8632352159731381, + 0.8655082854500867 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.828660504860544, + "scoreError" : 0.19515628336859078, + "scoreConfidence" : [ + 15.633504221491952, + 16.023816788229134 + ], + "scorePercentiles" : { + "0.0" : 15.604080445906902, + "50.0" : 15.860104697084749, + "90.0" : 15.992175410686185, + "95.0" : 15.992175410686185, + "99.0" : 15.992175410686185, + "99.9" : 15.992175410686185, + "99.99" : 15.992175410686185, + "99.999" : 15.992175410686185, + "99.9999" : 15.992175410686185, + "100.0" : 15.992175410686185 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.844544505135401, + 15.992175410686185, + 15.884953530649513 + ], + [ + 15.891235056561767, + 15.870904279027659, + 15.860104697084749 + ], + [ + 15.824810817551638, + 15.604080445906902, + 15.68513580114108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2557.6634487223264, + "scoreError" : 47.006079344690676, + "scoreConfidence" : [ + 2510.657369377636, + 2604.669528067017 + ], + "scorePercentiles" : { + "0.0" : 2520.102557582096, + "50.0" : 2558.092951448287, + "90.0" : 2593.6464634645013, + "95.0" : 2593.6464634645013, + "99.0" : 2593.6464634645013, + "99.9" : 2593.6464634645013, + "99.99" : 2593.6464634645013, + "99.999" : 2593.6464634645013, + "99.9999" : 2593.6464634645013, + "100.0" : 2593.6464634645013 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2546.187217621026, + 2572.8795982662687, + 2558.092951448287 + ], + [ + 2593.6464634645013, + 2582.369578750866, + 2587.668775948308 + ], + [ + 2533.380449879916, + 2524.6434455396707, + 2520.102557582096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69413.11742722343, + "scoreError" : 2286.6984959583874, + "scoreConfidence" : [ + 67126.41893126504, + 71699.81592318183 + ], + "scorePercentiles" : { + "0.0" : 67684.66210717411, + "50.0" : 69640.6380260107, + "90.0" : 71005.7251766002, + "95.0" : 71005.7251766002, + "99.0" : 71005.7251766002, + "99.9" : 71005.7251766002, + "99.99" : 71005.7251766002, + "99.999" : 71005.7251766002, + "99.9999" : 71005.7251766002, + "100.0" : 71005.7251766002 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 67738.74412096803, + 67807.18254373013, + 67684.66210717411 + ], + [ + 70776.77630644778, + 70789.3475759133, + 71005.7251766002 + ], + [ + 69613.11695761139, + 69661.86403055525, + 69640.6380260107 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 326.28796603194354, + "scoreError" : 11.11137678113879, + "scoreConfidence" : [ + 315.17658925080474, + 337.39934281308234 + ], + "scorePercentiles" : { + "0.0" : 315.31627183159503, + "50.0" : 328.18727690128657, + "90.0" : 333.0587989612745, + "95.0" : 333.0587989612745, + "99.0" : 333.0587989612745, + "99.9" : 333.0587989612745, + "99.99" : 333.0587989612745, + "99.999" : 333.0587989612745, + "99.9999" : 333.0587989612745, + "100.0" : 333.0587989612745 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 330.89756036927355, + 332.5329843616352, + 325.0252309033603 + ], + [ + 315.31627183159503, + 317.85845192710246, + 322.0413679247984 + ], + [ + 331.67375110716574, + 333.0587989612745, + 328.18727690128657 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 101.54030399246984, + "scoreError" : 3.8075778509487628, + "scoreConfidence" : [ + 97.73272614152108, + 105.3478818434186 + ], + "scorePercentiles" : { + "0.0" : 97.95425255277081, + "50.0" : 101.08863211831058, + "90.0" : 104.68379921897991, + "95.0" : 104.68379921897991, + "99.0" : 104.68379921897991, + "99.9" : 104.68379921897991, + "99.99" : 104.68379921897991, + "99.999" : 104.68379921897991, + "99.9999" : 104.68379921897991, + "100.0" : 104.68379921897991 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.50588636708386, + 102.97645467048544, + 100.99121641014219 + ], + [ + 99.14150512399577, + 100.53352546357344, + 97.95425255277081 + ], + [ + 101.08863211831058, + 101.98746400688667, + 104.68379921897991 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06280877414445157, + "scoreError" : 4.3648144842625236E-4, + "scoreConfidence" : [ + 0.062372292696025323, + 0.06324525559287783 + ], + "scorePercentiles" : { + "0.0" : 0.0623048855286194, + "50.0" : 0.06278044688237658, + "90.0" : 0.0631197039278929, + "95.0" : 0.0631197039278929, + "99.0" : 0.0631197039278929, + "99.9" : 0.0631197039278929, + "99.99" : 0.0631197039278929, + "99.999" : 0.0631197039278929, + "99.9999" : 0.0631197039278929, + "100.0" : 0.0631197039278929 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0628047768643312, + 0.0626707639910758, + 0.06305239426611434 + ], + [ + 0.0623048855286194, + 0.06273687804740335, + 0.06278044688237658 + ], + [ + 0.0631197039278929, + 0.06311242463237614, + 0.06269669315987461 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.905567705018995E-4, + "scoreError" : 3.512883638471716E-6, + "scoreConfidence" : [ + 3.870438868634278E-4, + 3.940696541403712E-4 + ], + "scorePercentiles" : { + "0.0" : 3.869264655787353E-4, + "50.0" : 3.906685237258492E-4, + "90.0" : 3.94258298699116E-4, + "95.0" : 3.94258298699116E-4, + "99.0" : 3.94258298699116E-4, + "99.9" : 3.94258298699116E-4, + "99.99" : 3.94258298699116E-4, + "99.999" : 3.94258298699116E-4, + "99.9999" : 3.94258298699116E-4, + "100.0" : 3.94258298699116E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.906685237258492E-4, + 3.899373265506365E-4, + 3.916502545108758E-4 + ], + [ + 3.869264655787353E-4, + 3.9152966281895385E-4, + 3.9122832217896463E-4 + ], + [ + 3.94258298699116E-4, + 3.905110322089086E-4, + 3.8830104824505543E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1103155214342608, + "scoreError" : 0.0018108082796381155, + "scoreConfidence" : [ + 0.10850471315462268, + 0.11212632971389891 + ], + "scorePercentiles" : { + "0.0" : 0.109056815424714, + "50.0" : 0.11032555367761437, + "90.0" : 0.11206928803568227, + "95.0" : 0.11206928803568227, + "99.0" : 0.11206928803568227, + "99.9" : 0.11206928803568227, + "99.99" : 0.11206928803568227, + "99.999" : 0.11206928803568227, + "99.9999" : 0.11206928803568227, + "100.0" : 0.11206928803568227 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.109056815424714, + 0.10916100215044373, + 0.10922656882277126 + ], + [ + 0.1100146221630601, + 0.11036208881727787, + 0.11032555367761437 + ], + [ + 0.11206928803568227, + 0.11143925750805131, + 0.1111844963087323 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014327076436476897, + "scoreError" : 3.177702819593848E-4, + "scoreConfidence" : [ + 0.014009306154517513, + 0.014644846718436282 + ], + "scorePercentiles" : { + "0.0" : 0.014152389746434702, + "50.0" : 0.01424539409250844, + "90.0" : 0.014588857645124536, + "95.0" : 0.014588857645124536, + "99.0" : 0.014588857645124536, + "99.9" : 0.014588857645124536, + "99.99" : 0.014588857645124536, + "99.999" : 0.014588857645124536, + "99.9999" : 0.014588857645124536, + "100.0" : 0.014588857645124536 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014159838111042987, + 0.014152389746434702, + 0.014162963792849495 + ], + [ + 0.014557956909038767, + 0.014588857645124536, + 0.014572394456442225 + ], + [ + 0.014270335410117258, + 0.01423355776473368, + 0.01424539409250844 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9850389971329451, + "scoreError" : 0.022098538415354096, + "scoreConfidence" : [ + 0.9629404587175909, + 1.0071375355482992 + ], + "scorePercentiles" : { + "0.0" : 0.9639907766531713, + "50.0" : 0.9858015206505668, + "90.0" : 1.004286032536654, + "95.0" : 1.004286032536654, + "99.0" : 1.004286032536654, + "99.9" : 1.004286032536654, + "99.99" : 1.004286032536654, + "99.999" : 1.004286032536654, + "99.9999" : 1.004286032536654, + "100.0" : 1.004286032536654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.977079590913532, + 0.9730350326911851, + 0.9639907766531713 + ], + [ + 0.9868019045786461, + 0.983253146691574, + 0.9858015206505668 + ], + [ + 1.003756836595403, + 0.9873461328857736, + 1.004286032536654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013272734320049778, + "scoreError" : 2.2225112594113E-4, + "scoreConfidence" : [ + 0.013050483194108647, + 0.013494985445990908 + ], + "scorePercentiles" : { + "0.0" : 0.013123427779542108, + "50.0" : 0.013295886198625352, + "90.0" : 0.013345353621300765, + "95.0" : 0.013345353621300765, + "99.0" : 0.013345353621300765, + "99.9" : 0.013345353621300765, + "99.99" : 0.013345353621300765, + "99.999" : 0.013345353621300765, + "99.9999" : 0.013345353621300765, + "100.0" : 0.013345353621300765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013123427779542108, + 0.013293946703321537, + 0.013297825693929167 + ], + [ + 0.013254005942945601, + 0.013321846179259484, + 0.013345353621300765 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8497826451058668, + "scoreError" : 0.09810452995735744, + "scoreConfidence" : [ + 3.7516781151485095, + 3.947887175063224 + ], + "scorePercentiles" : { + "0.0" : 3.797895554290053, + "50.0" : 3.845572258690387, + "90.0" : 3.894707704049844, + "95.0" : 3.894707704049844, + "99.0" : 3.894707704049844, + "99.9" : 3.894707704049844, + "99.99" : 3.894707704049844, + "99.999" : 3.894707704049844, + "99.9999" : 3.894707704049844, + "100.0" : 3.894707704049844 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.852870629429892, + 3.894707704049844, + 3.881441991466253 + ], + [ + 3.8382738879508826, + 3.833506103448276, + 3.797895554290053 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.013008784457508, + "scoreError" : 0.13599751684191327, + "scoreConfidence" : [ + 2.8770112676155946, + 3.1490063012994214 + ], + "scorePercentiles" : { + "0.0" : 2.918604712868398, + "50.0" : 2.9945180479041915, + "90.0" : 3.1372488601003763, + "95.0" : 3.1372488601003763, + "99.0" : 3.1372488601003763, + "99.9" : 3.1372488601003763, + "99.99" : 3.1372488601003763, + "99.999" : 3.1372488601003763, + "99.9999" : 3.1372488601003763, + "100.0" : 3.1372488601003763 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9705402494802495, + 2.9945180479041915, + 3.008261935639098 + ], + [ + 2.918604712868398, + 2.930226899208907, + 2.962444305094787 + ], + [ + 3.1372488601003763, + 3.1304406848200315, + 3.0647933650015324 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17586394276705064, + "scoreError" : 0.004869647030494683, + "scoreConfidence" : [ + 0.17099429573655595, + 0.18073358979754534 + ], + "scorePercentiles" : { + "0.0" : 0.17341529851212154, + "50.0" : 0.17405492792494864, + "90.0" : 0.1803368732981083, + "95.0" : 0.1803368732981083, + "99.0" : 0.1803368732981083, + "99.9" : 0.1803368732981083, + "99.99" : 0.1803368732981083, + "99.999" : 0.1803368732981083, + "99.9999" : 0.1803368732981083, + "100.0" : 0.1803368732981083 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17405492792494864, + 0.17377448895685266, + 0.17395810566050865 + ], + [ + 0.1745735588820613, + 0.17393631311093333, + 0.17341529851212154 + ], + [ + 0.17950368971459343, + 0.17922222884332772, + 0.1803368732981083 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33202975286606495, + "scoreError" : 0.006844235543547486, + "scoreConfidence" : [ + 0.3251855173225175, + 0.3388739884096124 + ], + "scorePercentiles" : { + "0.0" : 0.3261195985651394, + "50.0" : 0.33188947429557597, + "90.0" : 0.3372914570474552, + "95.0" : 0.3372914570474552, + "99.0" : 0.3372914570474552, + "99.9" : 0.3372914570474552, + "99.99" : 0.3372914570474552, + "99.999" : 0.3372914570474552, + "99.9999" : 0.3372914570474552, + "100.0" : 0.3372914570474552 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32916951211323237, + 0.3271407056168013, + 0.3261195985651394 + ], + [ + 0.33164076039663065, + 0.3323394652886245, + 0.33188947429557597 + ], + [ + 0.33578489231750724, + 0.33689191015361813, + 0.3372914570474552 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1672147582603807, + "scoreError" : 0.006059265389804464, + "scoreConfidence" : [ + 0.16115549287057623, + 0.17327402365018518 + ], + "scorePercentiles" : { + "0.0" : 0.16370752368791539, + "50.0" : 0.16626085706922925, + "90.0" : 0.17218467334148316, + "95.0" : 0.17218467334148316, + "99.0" : 0.17218467334148316, + "99.9" : 0.17218467334148316, + "99.99" : 0.17218467334148316, + "99.999" : 0.17218467334148316, + "99.9999" : 0.17218467334148316, + "100.0" : 0.17218467334148316 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17141363580733632, + 0.17218467334148316, + 0.17194902923071634 + ], + [ + 0.16410475112409334, + 0.16370752368791539, + 0.16395010335273383 + ], + [ + 0.16639665498593986, + 0.16626085706922925, + 0.16496559574397887 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3903175045098534, + "scoreError" : 0.003079925662555646, + "scoreConfidence" : [ + 0.38723757884729776, + 0.3933974301724091 + ], + "scorePercentiles" : { + "0.0" : 0.38886359746471205, + "50.0" : 0.3897894992984097, + "90.0" : 0.394799417923411, + "95.0" : 0.394799417923411, + "99.0" : 0.394799417923411, + "99.9" : 0.394799417923411, + "99.99" : 0.394799417923411, + "99.999" : 0.394799417923411, + "99.9999" : 0.394799417923411, + "100.0" : 0.394799417923411 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.394799417923411, + 0.3889408928904792, + 0.38886359746471205 + ], + [ + 0.390764965809628, + 0.3893752111902815, + 0.38918666565479665 + ], + [ + 0.3897894992984097, + 0.3905169387691346, + 0.3906203515878286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15895099417994044, + "scoreError" : 7.038372725397592E-4, + "scoreConfidence" : [ + 0.15824715690740068, + 0.1596548314524802 + ], + "scorePercentiles" : { + "0.0" : 0.15839843471718434, + "50.0" : 0.15885019666740796, + "90.0" : 0.15979176627838232, + "95.0" : 0.15979176627838232, + "99.0" : 0.15979176627838232, + "99.9" : 0.15979176627838232, + "99.99" : 0.15979176627838232, + "99.999" : 0.15979176627838232, + "99.9999" : 0.15979176627838232, + "100.0" : 0.15979176627838232 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1593783898159216, + 0.1590568645501972, + 0.15876350654092844 + ], + [ + 0.15873043815177537, + 0.15895976289938007, + 0.15862958799828683 + ], + [ + 0.15979176627838232, + 0.15885019666740796, + 0.15839843471718434 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047243714386061265, + "scoreError" : 0.001059814077917392, + "scoreConfidence" : [ + 0.04618390030814387, + 0.04830352846397866 + ], + "scorePercentiles" : { + "0.0" : 0.046237011887313266, + "50.0" : 0.04747622012960809, + "90.0" : 0.04792656282110268, + "95.0" : 0.04792656282110268, + "99.0" : 0.04792656282110268, + "99.9" : 0.04792656282110268, + "99.99" : 0.04792656282110268, + "99.999" : 0.04792656282110268, + "99.9999" : 0.04792656282110268, + "100.0" : 0.04792656282110268 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047675682974736955, + 0.04747622012960809, + 0.04735127878687438 + ], + [ + 0.046917604279755845, + 0.046237011887313266, + 0.04626559894700804 + ], + [ + 0.04792656282110268, + 0.047773280721366294, + 0.04757018892678588 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9813762.636173323, + "scoreError" : 382872.5136751298, + "scoreConfidence" : [ + 9430890.122498194, + 1.0196635149848452E7 + ], + "scorePercentiles" : { + "0.0" : 9559530.836676218, + "50.0" : 9818805.70363101, + "90.0" : 1.0206541185714286E7, + "95.0" : 1.0206541185714286E7, + "99.0" : 1.0206541185714286E7, + "99.9" : 1.0206541185714286E7, + "99.99" : 1.0206541185714286E7, + "99.999" : 1.0206541185714286E7, + "99.9999" : 1.0206541185714286E7, + "100.0" : 1.0206541185714286E7 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9581061.033524904, + 9627920.865255052, + 9559530.836676218 + ], + [ + 9818805.70363101, + 1.008136304939516E7, + 1.0206541185714286E7 + ], + [ + 9661313.49903475, + 9888530.595849803, + 9898796.956478734 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-11T11:32:54Z-572fbdf69fecc12fdb7a6a5c0f691adcbefd27d5-jdk17.json b/performance-results/2025-04-11T11:32:54Z-572fbdf69fecc12fdb7a6a5c0f691adcbefd27d5-jdk17.json new file mode 100644 index 0000000000..82a66a3b6a --- /dev/null +++ b/performance-results/2025-04-11T11:32:54Z-572fbdf69fecc12fdb7a6a5c0f691adcbefd27d5-jdk17.json @@ -0,0 +1,128 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "enableDataLoaderChaining" : "true" + }, + "primaryMetric" : { + "score" : 0.15275268998987082, + "scoreError" : 0.002701854514514433, + "scoreConfidence" : [ + 0.1500508354753564, + 0.15545454450438526 + ], + "scorePercentiles" : { + "0.0" : 0.15020872268869695, + "50.0" : 0.15303056841831425, + "90.0" : 0.15461172318681488, + "95.0" : 0.15461172318681488, + "99.0" : 0.15461172318681488, + "99.9" : 0.15461172318681488, + "99.99" : 0.15461172318681488, + "99.999" : 0.15461172318681488, + "99.9999" : 0.15461172318681488, + "100.0" : 0.15461172318681488 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15093022850415805, + 0.15135348939036203, + 0.15020872268869695 + ], + [ + 0.15303056841831425, + 0.1532261759162785, + 0.1527119071376214 + ], + [ + 0.15452919102512594, + 0.15461172318681488, + 0.15417220364146522 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "enableDataLoaderChaining" : "false" + }, + "primaryMetric" : { + "score" : 0.13341252894468913, + "scoreError" : 5.207141359596564E-4, + "scoreConfidence" : [ + 0.13289181480872947, + 0.1339332430806488 + ], + "scorePercentiles" : { + "0.0" : 0.13297701200765938, + "50.0" : 0.13346115493126917, + "90.0" : 0.13387963636120223, + "95.0" : 0.13387963636120223, + "99.0" : 0.13387963636120223, + "99.9" : 0.13387963636120223, + "99.99" : 0.13387963636120223, + "99.999" : 0.13387963636120223, + "99.9999" : 0.13387963636120223, + "100.0" : 0.13387963636120223 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1332875159875778, + 0.13297701200765938, + 0.1330036767925306 + ], + [ + 0.13354569715018297, + 0.13346115493126917, + 0.1332346234595041 + ], + [ + 0.13387963636120223, + 0.1336338561864418, + 0.13368958762583388 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-11T11:48:05Z-6c3d14ccbed15fb8062240dc36286488e65c5062-jdk17.json b/performance-results/2025-04-11T11:48:05Z-6c3d14ccbed15fb8062240dc36286488e65c5062-jdk17.json new file mode 100644 index 0000000000..e5d6e3b525 --- /dev/null +++ b/performance-results/2025-04-11T11:48:05Z-6c3d14ccbed15fb8062240dc36286488e65c5062-jdk17.json @@ -0,0 +1,63 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.15450705534887477, + "scoreError" : 0.003298478711981938, + "scoreConfidence" : [ + 0.15120857663689283, + 0.1578055340608567 + ], + "scorePercentiles" : { + "0.0" : 0.1526355479493872, + "50.0" : 0.15370355617718484, + "90.0" : 0.15762606131391463, + "95.0" : 0.15762606131391463, + "99.0" : 0.15762606131391463, + "99.9" : 0.15762606131391463, + "99.99" : 0.15762606131391463, + "99.999" : 0.15762606131391463, + "99.9999" : 0.15762606131391463, + "100.0" : 0.15762606131391463 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15762606131391463, + 0.15670122787031668, + 0.15684944239848173 + ], + [ + 0.15299841920381874, + 0.15312287682979114, + 0.1526355479493872 + ], + [ + 0.15383340897134154, + 0.15370355617718484, + 0.15309295742563647 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-14T04:48:27Z-04a359a3b500351509a6d178dfacdf90e4303a4e-jdk17.json b/performance-results/2025-04-14T04:48:27Z-04a359a3b500351509a6d178dfacdf90e4303a4e-jdk17.json new file mode 100644 index 0000000000..2737bc4ab3 --- /dev/null +++ b/performance-results/2025-04-14T04:48:27Z-04a359a3b500351509a6d178dfacdf90e4303a4e-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4111467063880516, + "scoreError" : 0.028995715723955873, + "scoreConfidence" : [ + 3.382150990664096, + 3.4401424221120074 + ], + "scorePercentiles" : { + "0.0" : 3.4044552860492434, + "50.0" : 3.4131108777701327, + "90.0" : 3.4139097839626955, + "95.0" : 3.4139097839626955, + "99.0" : 3.4139097839626955, + "99.9" : 3.4139097839626955, + "99.99" : 3.4139097839626955, + "99.999" : 3.4139097839626955, + "99.9999" : 3.4139097839626955, + "100.0" : 3.4139097839626955 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4044552860492434, + 3.4127386739915155 + ], + [ + 3.4139097839626955, + 3.4134830815487502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7209449283872307, + "scoreError" : 0.04749975519992041, + "scoreConfidence" : [ + 1.6734451731873103, + 1.768444683587151 + ], + "scorePercentiles" : { + "0.0" : 1.7144864274156433, + "50.0" : 1.7202324126140236, + "90.0" : 1.728828460905232, + "95.0" : 1.728828460905232, + "99.0" : 1.728828460905232, + "99.9" : 1.728828460905232, + "99.99" : 1.728828460905232, + "99.999" : 1.728828460905232, + "99.9999" : 1.728828460905232, + "100.0" : 1.728828460905232 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7148836728272139, + 1.7144864274156433 + ], + [ + 1.7255811524008335, + 1.728828460905232 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8658849432983765, + "scoreError" : 0.0029456488420708873, + "scoreConfidence" : [ + 0.8629392944563056, + 0.8688305921404474 + ], + "scorePercentiles" : { + "0.0" : 0.8653071391946788, + "50.0" : 0.8659476988856136, + "90.0" : 0.8663372362276, + "95.0" : 0.8663372362276, + "99.0" : 0.8663372362276, + "99.9" : 0.8663372362276, + "99.99" : 0.8663372362276, + "99.999" : 0.8663372362276, + "99.9999" : 0.8663372362276, + "100.0" : 0.8663372362276 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8653071391946788, + 0.8661440072262341 + ], + [ + 0.8663372362276, + 0.8657513905449932 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.957740198522325, + "scoreError" : 0.12806058962784847, + "scoreConfidence" : [ + 15.829679608894477, + 16.085800788150173 + ], + "scorePercentiles" : { + "0.0" : 15.878945697096766, + "50.0" : 15.942813764315957, + "90.0" : 16.083306741377864, + "95.0" : 16.083306741377864, + "99.0" : 16.083306741377864, + "99.9" : 16.083306741377864, + "99.99" : 16.083306741377864, + "99.999" : 16.083306741377864, + "99.9999" : 16.083306741377864, + "100.0" : 16.083306741377864 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.878945697096766, + 15.880987251942377, + 15.892916894525875 + ], + [ + 15.986139710476007, + 16.083306741377864, + 16.054806565268578 + ], + [ + 15.9061907795102, + 15.942813764315957, + 15.993554382187286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2595.3876048099523, + "scoreError" : 50.756297070234275, + "scoreConfidence" : [ + 2544.631307739718, + 2646.1439018801866 + ], + "scorePercentiles" : { + "0.0" : 2559.4694167490175, + "50.0" : 2593.257795767608, + "90.0" : 2632.2525583647766, + "95.0" : 2632.2525583647766, + "99.0" : 2632.2525583647766, + "99.9" : 2632.2525583647766, + "99.99" : 2632.2525583647766, + "99.999" : 2632.2525583647766, + "99.9999" : 2632.2525583647766, + "100.0" : 2632.2525583647766 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2565.5638947326142, + 2559.8747980331786, + 2559.4694167490175 + ], + [ + 2590.9314831222046, + 2593.257795767608, + 2596.036235475856 + ], + [ + 2629.894374104914, + 2631.207886939403, + 2632.2525583647766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70360.54724576049, + "scoreError" : 349.21755988695463, + "scoreConfidence" : [ + 70011.32968587354, + 70709.76480564744 + ], + "scorePercentiles" : { + "0.0" : 70095.20972074133, + "50.0" : 70252.63703065725, + "90.0" : 70643.97985509799, + "95.0" : 70643.97985509799, + "99.0" : 70643.97985509799, + "99.9" : 70643.97985509799, + "99.99" : 70643.97985509799, + "99.999" : 70643.97985509799, + "99.9999" : 70643.97985509799, + "100.0" : 70643.97985509799 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70252.63703065725, + 70236.10081852683, + 70174.2941254237 + ], + [ + 70392.08527496582, + 70095.20972074133, + 70243.59007858284 + ], + [ + 70593.68469235738, + 70613.3436154913, + 70643.97985509799 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 341.88381344542813, + "scoreError" : 9.546421293774017, + "scoreConfidence" : [ + 332.3373921516541, + 351.43023473920215 + ], + "scorePercentiles" : { + "0.0" : 335.37390371811694, + "50.0" : 341.2730460500591, + "90.0" : 349.42881715679937, + "95.0" : 349.42881715679937, + "99.0" : 349.42881715679937, + "99.9" : 349.42881715679937, + "99.99" : 349.42881715679937, + "99.999" : 349.42881715679937, + "99.9999" : 349.42881715679937, + "100.0" : 349.42881715679937 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 341.2730460500591, + 341.84586768131504, + 339.42672320128844 + ], + [ + 335.84226592699633, + 335.37390371811694, + 336.6712334294637 + ], + [ + 348.6419227055528, + 349.42881715679937, + 348.450541139261 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.28315530825641, + "scoreError" : 3.753352014968278, + "scoreConfidence" : [ + 104.52980329328814, + 112.03650732322468 + ], + "scorePercentiles" : { + "0.0" : 106.44714460708023, + "50.0" : 106.97839809812236, + "90.0" : 111.81604689066181, + "95.0" : 111.81604689066181, + "99.0" : 111.81604689066181, + "99.9" : 111.81604689066181, + "99.99" : 111.81604689066181, + "99.999" : 111.81604689066181, + "99.9999" : 111.81604689066181, + "100.0" : 111.81604689066181 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.84955039710748, + 106.97839809812236, + 107.04019135730321 + ], + [ + 106.6608827718748, + 106.44714460708023, + 106.90597870402031 + ], + [ + 110.55950576783664, + 111.29069918030089, + 111.81604689066181 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06250195166021222, + "scoreError" : 4.0643066476709917E-4, + "scoreConfidence" : [ + 0.062095520995445116, + 0.06290838232497932 + ], + "scorePercentiles" : { + "0.0" : 0.06218114185160083, + "50.0" : 0.062436826065782575, + "90.0" : 0.06283466759660697, + "95.0" : 0.06283466759660697, + "99.0" : 0.06283466759660697, + "99.9" : 0.06283466759660697, + "99.99" : 0.06283466759660697, + "99.999" : 0.06283466759660697, + "99.9999" : 0.06283466759660697, + "100.0" : 0.06283466759660697 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06243123878193123, + 0.06218114185160083, + 0.06220331236898579 + ], + [ + 0.06278797754100007, + 0.06283466759660697, + 0.062436826065782575 + ], + [ + 0.062336141756481306, + 0.06263177068380243, + 0.06267448829571877 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.763931321982923E-4, + "scoreError" : 5.047240920078014E-6, + "scoreConfidence" : [ + 3.713458912782143E-4, + 3.814403731183703E-4 + ], + "scorePercentiles" : { + "0.0" : 3.723628598436273E-4, + "50.0" : 3.7546109636464825E-4, + "90.0" : 3.806760084731394E-4, + "95.0" : 3.806760084731394E-4, + "99.0" : 3.806760084731394E-4, + "99.9" : 3.806760084731394E-4, + "99.99" : 3.806760084731394E-4, + "99.999" : 3.806760084731394E-4, + "99.9999" : 3.806760084731394E-4, + "100.0" : 3.806760084731394E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.804273528747368E-4, + 3.806760084731394E-4, + 3.7930564810188393E-4 + ], + [ + 3.749873144534879E-4, + 3.7546109636464825E-4, + 3.7595639224821757E-4 + ], + [ + 3.741597534584873E-4, + 3.742017639664023E-4, + 3.723628598436273E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1110982853842243, + "scoreError" : 0.0033993686888330304, + "scoreConfidence" : [ + 0.10769891669539126, + 0.11449765407305733 + ], + "scorePercentiles" : { + "0.0" : 0.10862349404212333, + "50.0" : 0.11101319547962389, + "90.0" : 0.1134542113270481, + "95.0" : 0.1134542113270481, + "99.0" : 0.1134542113270481, + "99.9" : 0.1134542113270481, + "99.99" : 0.1134542113270481, + "99.999" : 0.1134542113270481, + "99.9999" : 0.1134542113270481, + "100.0" : 0.1134542113270481 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10881517134929271, + 0.10884405976533588, + 0.10862349404212333 + ], + [ + 0.1134542113270481, + 0.11343169139065336, + 0.11339374310012473 + ], + [ + 0.11129718835418244, + 0.11101181364963422, + 0.11101319547962389 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01412296697103164, + "scoreError" : 8.169932638944794E-5, + "scoreConfidence" : [ + 0.014041267644642192, + 0.014204666297421087 + ], + "scorePercentiles" : { + "0.0" : 0.014056673242762663, + "50.0" : 0.014135587403384579, + "90.0" : 0.014179703816562259, + "95.0" : 0.014179703816562259, + "99.0" : 0.014179703816562259, + "99.9" : 0.014179703816562259, + "99.99" : 0.014179703816562259, + "99.999" : 0.014179703816562259, + "99.9999" : 0.014179703816562259, + "100.0" : 0.014179703816562259 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014129743113614238, + 0.014135587403384579, + 0.01414318876111464 + ], + [ + 0.01416080803869813, + 0.014179703816562259, + 0.01417203205814995 + ], + [ + 0.014065367385632407, + 0.014056673242762663, + 0.014063598919365908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9857626422864109, + "scoreError" : 0.008358507597933267, + "scoreConfidence" : [ + 0.9774041346884776, + 0.9941211498843441 + ], + "scorePercentiles" : { + "0.0" : 0.9802160982160361, + "50.0" : 0.9840446739151826, + "90.0" : 0.9931879542159102, + "95.0" : 0.9931879542159102, + "99.0" : 0.9931879542159102, + "99.9" : 0.9931879542159102, + "99.99" : 0.9931879542159102, + "99.999" : 0.9931879542159102, + "99.9999" : 0.9931879542159102, + "100.0" : 0.9931879542159102 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9844508347278276, + 0.9925314928543073, + 0.9931879542159102 + ], + [ + 0.9840446739151826, + 0.980470467254902, + 0.9802160982160361 + ], + [ + 0.9836777185993902, + 0.9829250139571457, + 0.9903595268369975 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013188942649367976, + "scoreError" : 5.295557939570219E-4, + "scoreConfidence" : [ + 0.012659386855410954, + 0.013718498443324999 + ], + "scorePercentiles" : { + "0.0" : 0.012951529484748642, + "50.0" : 0.013171834949463732, + "90.0" : 0.01340251443819306, + "95.0" : 0.01340251443819306, + "99.0" : 0.01340251443819306, + "99.9" : 0.01340251443819306, + "99.99" : 0.01340251443819306, + "99.999" : 0.01340251443819306, + "99.9999" : 0.01340251443819306, + "100.0" : 0.01340251443819306 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013280107967342343, + 0.013377057404811335, + 0.01340251443819306 + ], + [ + 0.012951529484748642, + 0.013058884669527359, + 0.013063561931585121 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8604282720790066, + "scoreError" : 0.07840614805729196, + "scoreConfidence" : [ + 3.7820221240217147, + 3.9388344201362986 + ], + "scorePercentiles" : { + "0.0" : 3.815332032036613, + "50.0" : 3.8602328171296296, + "90.0" : 3.9033303900156007, + "95.0" : 3.9033303900156007, + "99.0" : 3.9033303900156007, + "99.9" : 3.9033303900156007, + "99.99" : 3.9033303900156007, + "99.999" : 3.9033303900156007, + "99.9999" : 3.9033303900156007, + "100.0" : 3.9033303900156007 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8577754818812644, + 3.8656660942812984, + 3.9033303900156007 + ], + [ + 3.815332032036613, + 3.860462302469136, + 3.8600033317901237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9219873868943775, + "scoreError" : 0.059572104818889256, + "scoreConfidence" : [ + 2.8624152820754882, + 2.981559491713267 + ], + "scorePercentiles" : { + "0.0" : 2.8774678857882625, + "50.0" : 2.920831448890187, + "90.0" : 2.969246175178147, + "95.0" : 2.969246175178147, + "99.0" : 2.969246175178147, + "99.9" : 2.969246175178147, + "99.99" : 2.969246175178147, + "99.999" : 2.969246175178147, + "99.9999" : 2.969246175178147, + "100.0" : 2.969246175178147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.956449234111735, + 2.969246175178147, + 2.96028769635987 + ], + [ + 2.8774678857882625, + 2.8789117812320093, + 2.886434249062049 + ], + [ + 2.920831448890187, + 2.918937915645067, + 2.929320095782074 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17653126331230015, + "scoreError" : 0.006883506824634695, + "scoreConfidence" : [ + 0.16964775648766545, + 0.18341477013693486 + ], + "scorePercentiles" : { + "0.0" : 0.1711137734506006, + "50.0" : 0.17793257307569127, + "90.0" : 0.18046910107918862, + "95.0" : 0.18046910107918862, + "99.0" : 0.18046910107918862, + "99.9" : 0.18046910107918862, + "99.99" : 0.18046910107918862, + "99.999" : 0.18046910107918862, + "99.9999" : 0.18046910107918862, + "100.0" : 0.18046910107918862 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17147159504458162, + 0.17119870958519506, + 0.1711137734506006 + ], + [ + 0.1802850988299771, + 0.1804294302751466, + 0.18046910107918862 + ], + [ + 0.17818562236516222, + 0.17793257307569127, + 0.1776954661051584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.333145333963962, + "scoreError" : 0.015132366133567478, + "scoreConfidence" : [ + 0.3180129678303945, + 0.3482777000975295 + ], + "scorePercentiles" : { + "0.0" : 0.3227571863542473, + "50.0" : 0.3335272022479405, + "90.0" : 0.34411261446612296, + "95.0" : 0.34411261446612296, + "99.0" : 0.34411261446612296, + "99.9" : 0.34411261446612296, + "99.99" : 0.34411261446612296, + "99.999" : 0.34411261446612296, + "99.9999" : 0.34411261446612296, + "100.0" : 0.34411261446612296 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32817596075085326, + 0.3337560030370791, + 0.3335272022479405 + ], + [ + 0.32497462459378657, + 0.3227571863542473, + 0.32324420622555516 + ], + [ + 0.3437178911803121, + 0.34411261446612296, + 0.3440423168197612 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15850080116053814, + "scoreError" : 0.012644310452077069, + "scoreConfidence" : [ + 0.14585649070846107, + 0.1711451116126152 + ], + "scorePercentiles" : { + "0.0" : 0.14887960351347326, + "50.0" : 0.16071174217758136, + "90.0" : 0.16611452931014434, + "95.0" : 0.16611452931014434, + "99.0" : 0.16611452931014434, + "99.9" : 0.16611452931014434, + "99.99" : 0.16611452931014434, + "99.999" : 0.16611452931014434, + "99.9999" : 0.16611452931014434, + "100.0" : 0.16611452931014434 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14896414061848298, + 0.14897319334991882, + 0.14887960351347326 + ], + [ + 0.16611452931014434, + 0.16596250653876793, + 0.16563627400867922 + ], + [ + 0.16086383096869672, + 0.16071174217758136, + 0.16040138995909856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3868683349633209, + "scoreError" : 0.01098873236127017, + "scoreConfidence" : [ + 0.3758796026020507, + 0.3978570673245911 + ], + "scorePercentiles" : { + "0.0" : 0.3810287050217176, + "50.0" : 0.38296346785126184, + "90.0" : 0.3956893806829423, + "95.0" : 0.3956893806829423, + "99.0" : 0.3956893806829423, + "99.9" : 0.3956893806829423, + "99.99" : 0.3956893806829423, + "99.999" : 0.3956893806829423, + "99.9999" : 0.3956893806829423, + "100.0" : 0.3956893806829423 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3956893806829423, + 0.39546501087515323, + 0.39502327780850055 + ], + [ + 0.385864201875217, + 0.38296346785126184, + 0.38150716453668027 + ], + [ + 0.3821082290321348, + 0.38216557698628045, + 0.3810287050217176 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16065689865670058, + "scoreError" : 0.0017897774263760235, + "scoreConfidence" : [ + 0.15886712123032457, + 0.16244667608307659 + ], + "scorePercentiles" : { + "0.0" : 0.15903354863949365, + "50.0" : 0.1612849705175556, + "90.0" : 0.16174259617002004, + "95.0" : 0.16174259617002004, + "99.0" : 0.16174259617002004, + "99.9" : 0.16174259617002004, + "99.99" : 0.16174259617002004, + "99.999" : 0.16174259617002004, + "99.9999" : 0.16174259617002004, + "100.0" : 0.16174259617002004 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.159709556176635, + 0.15915344004838144, + 0.15903354863949365 + ], + [ + 0.16174259617002004, + 0.16142818530057468, + 0.16138398040829502 + ], + [ + 0.16141468303902895, + 0.1612849705175556, + 0.16076112761032071 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047049841955816324, + "scoreError" : 6.427784091603552E-4, + "scoreConfidence" : [ + 0.04640706354665597, + 0.04769262036497668 + ], + "scorePercentiles" : { + "0.0" : 0.04669233446171517, + "50.0" : 0.0469847830791494, + "90.0" : 0.04789604152058547, + "95.0" : 0.04789604152058547, + "99.0" : 0.04789604152058547, + "99.9" : 0.04789604152058547, + "99.99" : 0.04789604152058547, + "99.999" : 0.04789604152058547, + "99.9999" : 0.04789604152058547, + "100.0" : 0.04789604152058547 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04789604152058547, + 0.0472788827973562, + 0.04715241765449213 + ], + [ + 0.04714059057011134, + 0.04670176241313607, + 0.04669233446171517 + ], + [ + 0.0469847830791494, + 0.046855918373753656, + 0.04674584673204753 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9561463.24035374, + "scoreError" : 540737.3292327791, + "scoreConfidence" : [ + 9020725.911120962, + 1.010220056958652E7 + ], + "scorePercentiles" : { + "0.0" : 9196065.042279411, + "50.0" : 9509749.255703421, + "90.0" : 9979119.463609172, + "95.0" : 9979119.463609172, + "99.0" : 9979119.463609172, + "99.9" : 9979119.463609172, + "99.99" : 9979119.463609172, + "99.999" : 9979119.463609172, + "99.9999" : 9979119.463609172, + "100.0" : 9979119.463609172 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9260454.827777777, + 9202573.529898804, + 9196065.042279411 + ], + [ + 9912567.365708623, + 9979119.463609172, + 9971481.045862412 + ], + [ + 9540229.52049571, + 9509749.255703421, + 9480929.111848341 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-15T00:25:09Z-ee1541d583cf2334a9da02fd65a897e1a6cec20d-jdk17.json b/performance-results/2025-04-15T00:25:09Z-ee1541d583cf2334a9da02fd65a897e1a6cec20d-jdk17.json new file mode 100644 index 0000000000..073b881e47 --- /dev/null +++ b/performance-results/2025-04-15T00:25:09Z-ee1541d583cf2334a9da02fd65a897e1a6cec20d-jdk17.json @@ -0,0 +1,63 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.13211000286799135, + "scoreError" : 0.002155148324342315, + "scoreConfidence" : [ + 0.12995485454364902, + 0.13426515119233368 + ], + "scorePercentiles" : { + "0.0" : 0.13060583810469126, + "50.0" : 0.13182195652575104, + "90.0" : 0.13374850080915887, + "95.0" : 0.13374850080915887, + "99.0" : 0.13374850080915887, + "99.9" : 0.13374850080915887, + "99.99" : 0.13374850080915887, + "99.999" : 0.13374850080915887, + "99.9999" : 0.13374850080915887, + "100.0" : 0.13374850080915887 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13219848658867075, + 0.13148381968549488, + 0.13182195652575104 + ], + [ + 0.13374850080915887, + 0.13361761406696773, + 0.13370575607016794 + ], + [ + 0.13091305163114625, + 0.13089500232987342, + 0.13060583810469126 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-15T02:21:30Z-f1ac9ac58d0f7e22bb505453b225387d64599318-jdk17.json b/performance-results/2025-04-15T02:21:30Z-f1ac9ac58d0f7e22bb505453b225387d64599318-jdk17.json new file mode 100644 index 0000000000..e3626a8707 --- /dev/null +++ b/performance-results/2025-04-15T02:21:30Z-f1ac9ac58d0f7e22bb505453b225387d64599318-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.415322760546764, + "scoreError" : 0.008877684133462406, + "scoreConfidence" : [ + 3.4064450764133016, + 3.4242004446802263 + ], + "scorePercentiles" : { + "0.0" : 3.4140894541828954, + "50.0" : 3.4150852752032304, + "90.0" : 3.4170310375977015, + "95.0" : 3.4170310375977015, + "99.0" : 3.4170310375977015, + "99.9" : 3.4170310375977015, + "99.99" : 3.4170310375977015, + "99.999" : 3.4170310375977015, + "99.9999" : 3.4170310375977015, + "100.0" : 3.4170310375977015 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4140894541828954, + 3.415830320465181 + ], + [ + 3.414340229941279, + 3.4170310375977015 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.726168576489703, + "scoreError" : 0.012552115379516391, + "scoreConfidence" : [ + 1.7136164611101867, + 1.7387206918692193 + ], + "scorePercentiles" : { + "0.0" : 1.724831043650483, + "50.0" : 1.7254023599916009, + "90.0" : 1.7290385423251273, + "95.0" : 1.7290385423251273, + "99.0" : 1.7290385423251273, + "99.9" : 1.7290385423251273, + "99.99" : 1.7290385423251273, + "99.999" : 1.7290385423251273, + "99.9999" : 1.7290385423251273, + "100.0" : 1.7290385423251273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7256468045337503, + 1.7290385423251273 + ], + [ + 1.724831043650483, + 1.7251579154494512 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8682374949456866, + "scoreError" : 0.00545843684967786, + "scoreConfidence" : [ + 0.8627790580960087, + 0.8736959317953644 + ], + "scorePercentiles" : { + "0.0" : 0.867328139207002, + "50.0" : 0.8681261178147017, + "90.0" : 0.8693696049463412, + "95.0" : 0.8693696049463412, + "99.0" : 0.8693696049463412, + "99.9" : 0.8693696049463412, + "99.99" : 0.8693696049463412, + "99.999" : 0.8693696049463412, + "99.9999" : 0.8693696049463412, + "100.0" : 0.8693696049463412 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8681858643252067, + 0.8693696049463412 + ], + [ + 0.867328139207002, + 0.8680663713041967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.300666638426538, + "scoreError" : 0.1319480135658443, + "scoreConfidence" : [ + 16.168718624860695, + 16.43261465199238 + ], + "scorePercentiles" : { + "0.0" : 16.169592327457902, + "50.0" : 16.34361266133987, + "90.0" : 16.36809027402251, + "95.0" : 16.36809027402251, + "99.0" : 16.36809027402251, + "99.9" : 16.36809027402251, + "99.99" : 16.36809027402251, + "99.999" : 16.36809027402251, + "99.9999" : 16.36809027402251, + "100.0" : 16.36809027402251 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.23421932287947, + 16.194473829597943, + 16.169592327457902 + ], + [ + 16.34361266133987, + 16.32947932341642, + 16.36809027402251 + ], + [ + 16.365114656893955, + 16.344867551466116, + 16.356549798764693 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2681.6825671924084, + "scoreError" : 128.09488938125727, + "scoreConfidence" : [ + 2553.587677811151, + 2809.777456573666 + ], + "scorePercentiles" : { + "0.0" : 2589.317831849761, + "50.0" : 2682.083192537607, + "90.0" : 2770.55344358305, + "95.0" : 2770.55344358305, + "99.0" : 2770.55344358305, + "99.9" : 2770.55344358305, + "99.99" : 2770.55344358305, + "99.999" : 2770.55344358305, + "99.9999" : 2770.55344358305, + "100.0" : 2770.55344358305 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2677.68345740909, + 2682.083192537607, + 2684.079233016626 + ], + [ + 2590.9658057294705, + 2601.627056703632, + 2589.317831849761 + ], + [ + 2769.9709001112137, + 2770.55344358305, + 2768.8621837912297 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 71173.61262840743, + "scoreError" : 288.0821606105507, + "scoreConfidence" : [ + 70885.53046779688, + 71461.69478901797 + ], + "scorePercentiles" : { + "0.0" : 70976.6636535815, + "50.0" : 71138.38646852618, + "90.0" : 71435.28650698674, + "95.0" : 71435.28650698674, + "99.0" : 71435.28650698674, + "99.9" : 71435.28650698674, + "99.99" : 71435.28650698674, + "99.999" : 71435.28650698674, + "99.9999" : 71435.28650698674, + "100.0" : 71435.28650698674 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71377.2880619351, + 71435.28650698674, + 71349.89466660391 + ], + [ + 71151.33487803435, + 71138.38646852618, + 71080.79031160948 + ], + [ + 71054.87130124698, + 70997.99780714247, + 70976.6636535815 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.4816561043797, + "scoreError" : 5.265399187767131, + "scoreConfidence" : [ + 348.21625691661256, + 358.7470552921468 + ], + "scorePercentiles" : { + "0.0" : 349.629848344264, + "50.0" : 353.85083493882615, + "90.0" : 357.43439363191766, + "95.0" : 357.43439363191766, + "99.0" : 357.43439363191766, + "99.9" : 357.43439363191766, + "99.99" : 357.43439363191766, + "99.999" : 357.43439363191766, + "99.9999" : 357.43439363191766, + "100.0" : 357.43439363191766 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.7003346352882, + 349.629848344264, + 349.7478442724203 + ], + [ + 354.932122496948, + 357.43439363191766, + 357.36818969254136 + ], + [ + 353.85083493882615, + 355.05644068169914, + 353.6148962455119 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.23699180977785, + "scoreError" : 2.0907741551563395, + "scoreConfidence" : [ + 102.14621765462151, + 106.32776596493419 + ], + "scorePercentiles" : { + "0.0" : 102.62138068273445, + "50.0" : 104.48109622481194, + "90.0" : 105.71028203455687, + "95.0" : 105.71028203455687, + "99.0" : 105.71028203455687, + "99.9" : 105.71028203455687, + "99.99" : 105.71028203455687, + "99.999" : 105.71028203455687, + "99.9999" : 105.71028203455687, + "100.0" : 105.71028203455687 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.71028203455687, + 105.43682926345448, + 105.41694516195695 + ], + [ + 104.47786550747375, + 104.48109622481194, + 104.53314698616293 + ], + [ + 102.7984462528841, + 102.62138068273445, + 102.65693417396511 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061393494879658804, + "scoreError" : 1.1962425357889179E-4, + "scoreConfidence" : [ + 0.06127387062607991, + 0.0615131191332377 + ], + "scorePercentiles" : { + "0.0" : 0.06131567766243799, + "50.0" : 0.061371366092853416, + "90.0" : 0.0615420625565409, + "95.0" : 0.0615420625565409, + "99.0" : 0.0615420625565409, + "99.9" : 0.0615420625565409, + "99.99" : 0.0615420625565409, + "99.999" : 0.0615420625565409, + "99.9999" : 0.0615420625565409, + "100.0" : 0.0615420625565409 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06134546595670284, + 0.06139859910850238, + 0.06131567766243799 + ], + [ + 0.06145154837401372, + 0.061371366092853416, + 0.0615420625565409 + ], + [ + 0.06142878124232149, + 0.06134990278033398, + 0.061338050143222536 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.64554982535371E-4, + "scoreError" : 6.8586724458433974E-6, + "scoreConfidence" : [ + 3.576963100895276E-4, + 3.714136549812144E-4 + ], + "scorePercentiles" : { + "0.0" : 3.598166457885479E-4, + "50.0" : 3.6341976860741065E-4, + "90.0" : 3.707749243868395E-4, + "95.0" : 3.707749243868395E-4, + "99.0" : 3.707749243868395E-4, + "99.9" : 3.707749243868395E-4, + "99.99" : 3.707749243868395E-4, + "99.999" : 3.707749243868395E-4, + "99.9999" : 3.707749243868395E-4, + "100.0" : 3.707749243868395E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.697832456407533E-4, + 3.707749243868395E-4, + 3.6837124169971627E-4 + ], + [ + 3.641311723708613E-4, + 3.6341976860741065E-4, + 3.625277007969317E-4 + ], + [ + 3.6161957230427E-4, + 3.598166457885479E-4, + 3.6055057122300836E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11051191799918697, + "scoreError" : 0.002707744013328891, + "scoreConfidence" : [ + 0.10780417398585808, + 0.11321966201251586 + ], + "scorePercentiles" : { + "0.0" : 0.10899726683161302, + "50.0" : 0.10984616498604978, + "90.0" : 0.1127032575115519, + "95.0" : 0.1127032575115519, + "99.0" : 0.1127032575115519, + "99.9" : 0.1127032575115519, + "99.99" : 0.1127032575115519, + "99.999" : 0.1127032575115519, + "99.9999" : 0.1127032575115519, + "100.0" : 0.1127032575115519 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10964769043781454, + 0.10988352146538179, + 0.10984616498604978 + ], + [ + 0.1127032575115519, + 0.11257319460110544, + 0.11258857181941004 + ], + [ + 0.10899726683161302, + 0.10920509101035251, + 0.10916250332940354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014404611777662037, + "scoreError" : 4.94837964361807E-4, + "scoreConfidence" : [ + 0.01390977381330023, + 0.014899449742023844 + ], + "scorePercentiles" : { + "0.0" : 0.014163445031591202, + "50.0" : 0.014250613055981486, + "90.0" : 0.014796964243543419, + "95.0" : 0.014796964243543419, + "99.0" : 0.014796964243543419, + "99.9" : 0.014796964243543419, + "99.99" : 0.014796964243543419, + "99.999" : 0.014796964243543419, + "99.9999" : 0.014796964243543419, + "100.0" : 0.014796964243543419 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014178386236064579, + 0.014163445031591202, + 0.014165898809936977 + ], + [ + 0.014244344022642552, + 0.014255661387857742, + 0.014250613055981486 + ], + [ + 0.014796964243543419, + 0.014795223785400841, + 0.014790969425939512 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9881261754564223, + "scoreError" : 0.008924161395120192, + "scoreConfidence" : [ + 0.9792020140613021, + 0.9970503368515425 + ], + "scorePercentiles" : { + "0.0" : 0.9794501876591577, + "50.0" : 0.9873859891390205, + "90.0" : 0.9956756888689765, + "95.0" : 0.9956756888689765, + "99.0" : 0.9956756888689765, + "99.9" : 0.9956756888689765, + "99.99" : 0.9956756888689765, + "99.999" : 0.9956756888689765, + "99.9999" : 0.9956756888689765, + "100.0" : 0.9956756888689765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9864574973367528, + 0.9850826977935382, + 0.9923917527041778 + ], + [ + 0.9873859891390205, + 0.9825333868146984, + 0.9794501876591577 + ], + [ + 0.9922053252306776, + 0.9956756888689765, + 0.9919530535608014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01315948640587937, + "scoreError" : 1.009289306331267E-4, + "scoreConfidence" : [ + 0.013058557475246244, + 0.013260415336512496 + ], + "scorePercentiles" : { + "0.0" : 0.013125023558903822, + "50.0" : 0.013151889443773998, + "90.0" : 0.013207332544434965, + "95.0" : 0.013207332544434965, + "99.0" : 0.013207332544434965, + "99.9" : 0.013207332544434965, + "99.99" : 0.013207332544434965, + "99.999" : 0.013207332544434965, + "99.9999" : 0.013207332544434965, + "100.0" : 0.013207332544434965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013207332544434965, + 0.013195739565767008, + 0.01316575044959885 + ], + [ + 0.013125023558903822, + 0.013125043878622428, + 0.013138028437949147 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.5755535503120117, + "scoreError" : 0.14074597545832987, + "scoreConfidence" : [ + 3.4348075748536817, + 3.7162995257703417 + ], + "scorePercentiles" : { + "0.0" : 3.5072742994389903, + "50.0" : 3.5793373091961818, + "90.0" : 3.623208715423606, + "95.0" : 3.623208715423606, + "99.0" : 3.623208715423606, + "99.9" : 3.623208715423606, + "99.99" : 3.623208715423606, + "99.999" : 3.623208715423606, + "99.9999" : 3.623208715423606, + "100.0" : 3.623208715423606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5072742994389903, + 3.545946366406804, + 3.541344769992923 + ], + [ + 3.6127282519855597, + 3.623208715423606, + 3.6228188986241854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8584262386525356, + "scoreError" : 0.11296655079735753, + "scoreConfidence" : [ + 2.745459687855178, + 2.9713927894498933 + ], + "scorePercentiles" : { + "0.0" : 2.7725898680343777, + "50.0" : 2.8794690858047796, + "90.0" : 2.9462836488954345, + "95.0" : 2.9462836488954345, + "99.0" : 2.9462836488954345, + "99.9" : 2.9462836488954345, + "99.99" : 2.9462836488954345, + "99.999" : 2.9462836488954345, + "99.9999" : 2.9462836488954345, + "100.0" : 2.9462836488954345 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7754202280799114, + 2.775161105160932, + 2.7725898680343777 + ], + [ + 2.8794690858047796, + 2.8831267172095707, + 2.8662103215821153 + ], + [ + 2.913743901252549, + 2.9138312718531467, + 2.9462836488954345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1744819798446093, + "scoreError" : 0.00421227370866724, + "scoreConfidence" : [ + 0.17026970613594206, + 0.17869425355327656 + ], + "scorePercentiles" : { + "0.0" : 0.1721613260854595, + "50.0" : 0.1734807359354671, + "90.0" : 0.17781383723328592, + "95.0" : 0.17781383723328592, + "99.0" : 0.17781383723328592, + "99.9" : 0.17781383723328592, + "99.99" : 0.17781383723328592, + "99.999" : 0.17781383723328592, + "99.9999" : 0.17781383723328592, + "100.0" : 0.17781383723328592 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17337849144402642, + 0.17350859569705906, + 0.1734807359354671 + ], + [ + 0.1722161709547427, + 0.1721613260854595, + 0.17234670100303323 + ], + [ + 0.17774275413245175, + 0.17768920611595798, + 0.17781383723328592 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32466101895043337, + "scoreError" : 0.003985813143698082, + "scoreConfidence" : [ + 0.3206752058067353, + 0.3286468320941314 + ], + "scorePercentiles" : { + "0.0" : 0.32243601005964856, + "50.0" : 0.32337311951495556, + "90.0" : 0.3290730748955214, + "95.0" : 0.3290730748955214, + "99.0" : 0.3290730748955214, + "99.9" : 0.3290730748955214, + "99.99" : 0.3290730748955214, + "99.999" : 0.3290730748955214, + "99.9999" : 0.3290730748955214, + "100.0" : 0.3290730748955214 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32337311951495556, + 0.32243601005964856, + 0.32283099951576977 + ], + [ + 0.32310682762520193, + 0.3232315713823976, + 0.32397497699883376 + ], + [ + 0.3290730748955214, + 0.3271489701648783, + 0.3267736203966931 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15744661128564347, + "scoreError" : 0.007736581048892359, + "scoreConfidence" : [ + 0.1497100302367511, + 0.16518319233453582 + ], + "scorePercentiles" : { + "0.0" : 0.15317215995527442, + "50.0" : 0.15548416937979073, + "90.0" : 0.16349197984174216, + "95.0" : 0.16349197984174216, + "99.0" : 0.16349197984174216, + "99.9" : 0.16349197984174216, + "99.99" : 0.16349197984174216, + "99.999" : 0.16349197984174216, + "99.9999" : 0.16349197984174216, + "100.0" : 0.16349197984174216 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15336360400883353, + 0.15354447732960738, + 0.15317215995527442 + ], + [ + 0.15545134189336235, + 0.15563929790512357, + 0.15548416937979073 + ], + [ + 0.1634775595370431, + 0.16339491172001372, + 0.16349197984174216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39292306883244443, + "scoreError" : 0.010449578000728097, + "scoreConfidence" : [ + 0.38247349083171633, + 0.40337264683317253 + ], + "scorePercentiles" : { + "0.0" : 0.38727376070792346, + "50.0" : 0.3917069853897376, + "90.0" : 0.40439078357394154, + "95.0" : 0.40439078357394154, + "99.0" : 0.40439078357394154, + "99.9" : 0.40439078357394154, + "99.99" : 0.40439078357394154, + "99.999" : 0.40439078357394154, + "99.9999" : 0.40439078357394154, + "100.0" : 0.40439078357394154 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4022832136047307, + 0.3917069853897376, + 0.391772772162808 + ], + [ + 0.40439078357394154, + 0.3918120368295263, + 0.3913865062815545 + ], + [ + 0.3874848421032238, + 0.3881967188385544, + 0.38727376070792346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15957013230052164, + "scoreError" : 0.0036448537800050245, + "scoreConfidence" : [ + 0.1559252785205166, + 0.16321498608052668 + ], + "scorePercentiles" : { + "0.0" : 0.15716058272827282, + "50.0" : 0.15893123397221956, + "90.0" : 0.1625172265938602, + "95.0" : 0.1625172265938602, + "99.0" : 0.1625172265938602, + "99.9" : 0.1625172265938602, + "99.99" : 0.1625172265938602, + "99.999" : 0.1625172265938602, + "99.9999" : 0.1625172265938602, + "100.0" : 0.1625172265938602 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1621620600149186, + 0.1622808943089431, + 0.1625172265938602 + ], + [ + 0.15796503121297803, + 0.15716058272827282, + 0.1572905430022964 + ], + [ + 0.15878767101732325, + 0.15893123397221956, + 0.15903594785388273 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04746720505196515, + "scoreError" : 0.0013620488038863217, + "scoreConfidence" : [ + 0.04610515624807883, + 0.048829253855851476 + ], + "scorePercentiles" : { + "0.0" : 0.046411901236859815, + "50.0" : 0.0476629237834231, + "90.0" : 0.04846337497576862, + "95.0" : 0.04846337497576862, + "99.0" : 0.04846337497576862, + "99.9" : 0.04846337497576862, + "99.99" : 0.04846337497576862, + "99.999" : 0.04846337497576862, + "99.9999" : 0.04846337497576862, + "100.0" : 0.04846337497576862 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04655497455808345, + 0.04644502037982268, + 0.046411901236859815 + ], + [ + 0.04846337497576862, + 0.048294155514130625, + 0.0481767965187983 + ], + [ + 0.0476629237834231, + 0.04767803558164039, + 0.04751766291915933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9139488.588184066, + "scoreError" : 163154.86468702252, + "scoreConfidence" : [ + 8976333.723497044, + 9302643.452871088 + ], + "scorePercentiles" : { + "0.0" : 9010035.514414415, + "50.0" : 9117277.23609845, + "90.0" : 9248973.311460258, + "95.0" : 9248973.311460258, + "99.0" : 9248973.311460258, + "99.9" : 9248973.311460258, + "99.99" : 9248973.311460258, + "99.999" : 9248973.311460258, + "99.9999" : 9248973.311460258, + "100.0" : 9248973.311460258 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9185662.463728191, + 9117277.23609845, + 9105157.005459508 + ], + [ + 9248237.228280962, + 9248973.311460258, + 9246554.19685767 + ], + [ + 9012298.154054053, + 9010035.514414415, + 9081202.183303086 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-15T03:15:10Z-0998a7426f9c9cec13ba0b3bf34ef9f68cc0dc1d-jdk17.json b/performance-results/2025-04-15T03:15:10Z-0998a7426f9c9cec13ba0b3bf34ef9f68cc0dc1d-jdk17.json new file mode 100644 index 0000000000..0173858c94 --- /dev/null +++ b/performance-results/2025-04-15T03:15:10Z-0998a7426f9c9cec13ba0b3bf34ef9f68cc0dc1d-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4053504948650732, + "scoreError" : 0.03362550385434585, + "scoreConfidence" : [ + 3.371724991010727, + 3.4389759987194193 + ], + "scorePercentiles" : { + "0.0" : 3.399759955868604, + "50.0" : 3.4047976427764493, + "90.0" : 3.412046738038791, + "95.0" : 3.412046738038791, + "99.0" : 3.412046738038791, + "99.9" : 3.412046738038791, + "99.99" : 3.412046738038791, + "99.999" : 3.412046738038791, + "99.9999" : 3.412046738038791, + "100.0" : 3.412046738038791 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.399759955868604, + 3.4063020974562876 + ], + [ + 3.4032931880966104, + 3.412046738038791 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7231837792845122, + "scoreError" : 0.010525895662980704, + "scoreConfidence" : [ + 1.7126578836215314, + 1.733709674947493 + ], + "scorePercentiles" : { + "0.0" : 1.7209325393948356, + "50.0" : 1.7236281340979593, + "90.0" : 1.724546309547295, + "95.0" : 1.724546309547295, + "99.0" : 1.724546309547295, + "99.9" : 1.724546309547295, + "99.99" : 1.724546309547295, + "99.999" : 1.724546309547295, + "99.9999" : 1.724546309547295, + "100.0" : 1.724546309547295 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7230622653485166, + 1.724194002847402 + ], + [ + 1.7209325393948356, + 1.724546309547295 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8661331683179052, + "scoreError" : 0.006736745156992537, + "scoreConfidence" : [ + 0.8593964231609127, + 0.8728699134748977 + ], + "scorePercentiles" : { + "0.0" : 0.8646050242289606, + "50.0" : 0.866487628437641, + "90.0" : 0.866952392167378, + "95.0" : 0.866952392167378, + "99.0" : 0.866952392167378, + "99.9" : 0.866952392167378, + "99.99" : 0.866952392167378, + "99.999" : 0.866952392167378, + "99.9999" : 0.866952392167378, + "100.0" : 0.866952392167378 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8665257081787283, + 0.866952392167378 + ], + [ + 0.8646050242289606, + 0.8664495486965537 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.000425442949847, + "scoreError" : 0.1606955175520907, + "scoreConfidence" : [ + 15.839729925397757, + 16.16112096050194 + ], + "scorePercentiles" : { + "0.0" : 15.862888964884078, + "50.0" : 16.016988213771644, + "90.0" : 16.103494649846574, + "95.0" : 16.103494649846574, + "99.0" : 16.103494649846574, + "99.9" : 16.103494649846574, + "99.99" : 16.103494649846574, + "99.999" : 16.103494649846574, + "99.9999" : 16.103494649846574, + "100.0" : 16.103494649846574 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.89983455226215, + 15.878548221800122, + 15.862888964884078 + ], + [ + 16.090410903882017, + 16.07689640057629, + 16.103494649846574 + ], + [ + 16.008286840055753, + 16.016988213771644, + 16.06648023946999 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2715.448363664927, + "scoreError" : 58.13912184667665, + "scoreConfidence" : [ + 2657.3092418182505, + 2773.5874855116035 + ], + "scorePercentiles" : { + "0.0" : 2663.215285444246, + "50.0" : 2730.1985367954894, + "90.0" : 2747.8567809066762, + "95.0" : 2747.8567809066762, + "99.0" : 2747.8567809066762, + "99.9" : 2747.8567809066762, + "99.99" : 2747.8567809066762, + "99.999" : 2747.8567809066762, + "99.9999" : 2747.8567809066762, + "100.0" : 2747.8567809066762 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2673.420934497315, + 2663.215285444246, + 2674.3610863564936 + ], + [ + 2730.1985367954894, + 2726.864069163898, + 2737.0429961605337 + ], + [ + 2747.8567809066762, + 2744.8193179142713, + 2741.2562657454177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70357.13923852931, + "scoreError" : 1424.0117748678715, + "scoreConfidence" : [ + 68933.12746366144, + 71781.15101339719 + ], + "scorePercentiles" : { + "0.0" : 69207.47295685667, + "50.0" : 70756.40974285261, + "90.0" : 71083.01684327383, + "95.0" : 71083.01684327383, + "99.0" : 71083.01684327383, + "99.9" : 71083.01684327383, + "99.99" : 71083.01684327383, + "99.999" : 71083.01684327383, + "99.9999" : 71083.01684327383, + "100.0" : 71083.01684327383 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70756.40974285261, + 70748.81137733445, + 70853.85957089269 + ], + [ + 69207.47295685667, + 69293.17071621685, + 69215.19593187529 + ], + [ + 71028.95145263147, + 71083.01684327383, + 71027.3645548299 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.21104617030466, + "scoreError" : 8.428059144495359, + "scoreConfidence" : [ + 333.7829870258093, + 350.6391053148 + ], + "scorePercentiles" : { + "0.0" : 335.4191928205808, + "50.0" : 345.11865121992435, + "90.0" : 347.16506536965244, + "95.0" : 347.16506536965244, + "99.0" : 347.16506536965244, + "99.9" : 347.16506536965244, + "99.99" : 347.16506536965244, + "99.999" : 347.16506536965244, + "99.9999" : 347.16506536965244, + "100.0" : 347.16506536965244 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 336.1982604556769, + 335.4191928205808, + 336.1217481680525 + ], + [ + 341.3333124819405, + 345.11865121992435, + 345.4419260651438 + ], + [ + 347.16506536965244, + 346.5842998005359, + 346.5169591512344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.44734254349012, + "scoreError" : 2.6242468505211503, + "scoreConfidence" : [ + 101.82309569296898, + 107.07158939401127 + ], + "scorePercentiles" : { + "0.0" : 102.1044044858287, + "50.0" : 105.03337843091175, + "90.0" : 106.10387354054552, + "95.0" : 106.10387354054552, + "99.0" : 106.10387354054552, + "99.9" : 106.10387354054552, + "99.99" : 106.10387354054552, + "99.999" : 106.10387354054552, + "99.9999" : 106.10387354054552, + "100.0" : 106.10387354054552 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.10387354054552, + 105.70112914041317, + 105.37654250722802 + ], + [ + 105.64596540597816, + 104.78687403988239, + 105.03337843091175 + ], + [ + 103.07893372739045, + 102.1044044858287, + 102.1949816132329 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06260033692358571, + "scoreError" : 0.001199990439541251, + "scoreConfidence" : [ + 0.061400346484044466, + 0.06380032736312696 + ], + "scorePercentiles" : { + "0.0" : 0.061499798960671564, + "50.0" : 0.06293313147809013, + "90.0" : 0.0632234464254103, + "95.0" : 0.0632234464254103, + "99.0" : 0.0632234464254103, + "99.9" : 0.0632234464254103, + "99.99" : 0.0632234464254103, + "99.999" : 0.0632234464254103, + "99.9999" : 0.0632234464254103, + "100.0" : 0.0632234464254103 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061499798960671564, + 0.061681539123891294, + 0.06183675060290135 + ], + [ + 0.06293313147809013, + 0.06299717423459746, + 0.06281552363394242 + ], + [ + 0.0632234464254103, + 0.06320046040864823, + 0.06321520744411854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7852257586131036E-4, + "scoreError" : 1.4834148493775336E-5, + "scoreConfidence" : [ + 3.63688427367535E-4, + 3.933567243550857E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6771197707239934E-4, + "50.0" : 3.7732587668654375E-4, + "90.0" : 3.897809143551212E-4, + "95.0" : 3.897809143551212E-4, + "99.0" : 3.897809143551212E-4, + "99.9" : 3.897809143551212E-4, + "99.99" : 3.897809143551212E-4, + "99.999" : 3.897809143551212E-4, + "99.9999" : 3.897809143551212E-4, + "100.0" : 3.897809143551212E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.897809143551212E-4, + 3.8751391563726406E-4, + 3.89457679709334E-4 + ], + [ + 3.6952472891886703E-4, + 3.6878001094895423E-4, + 3.6771197707239934E-4 + ], + [ + 3.79294171075628E-4, + 3.7732587668654375E-4, + 3.7731390834768147E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11142793515454283, + "scoreError" : 7.799755480253577E-4, + "scoreConfidence" : [ + 0.11064795960651747, + 0.11220791070256819 + ], + "scorePercentiles" : { + "0.0" : 0.11090168945669894, + "50.0" : 0.11135513500512227, + "90.0" : 0.11204627959350595, + "95.0" : 0.11204627959350595, + "99.0" : 0.11204627959350595, + "99.9" : 0.11204627959350595, + "99.99" : 0.11204627959350595, + "99.999" : 0.11204627959350595, + "99.9999" : 0.11204627959350595, + "100.0" : 0.11204627959350595 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11193024702550844, + 0.11196701819423606, + 0.11204627959350595 + ], + [ + 0.11147397626771004, + 0.11135513500512227, + 0.11132430569192577 + ], + [ + 0.11090168945669894, + 0.1109283749750416, + 0.1109243901811365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014139801651952952, + "scoreError" : 1.789652847785874E-4, + "scoreConfidence" : [ + 0.013960836367174365, + 0.01431876693673154 + ], + "scorePercentiles" : { + "0.0" : 0.014056779686509448, + "50.0" : 0.014077511421657439, + "90.0" : 0.01431037733721426, + "95.0" : 0.01431037733721426, + "99.0" : 0.01431037733721426, + "99.9" : 0.01431037733721426, + "99.99" : 0.01431037733721426, + "99.999" : 0.01431037733721426, + "99.9999" : 0.01431037733721426, + "100.0" : 0.01431037733721426 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014262368709299242, + 0.014268121113585809, + 0.01431037733721426 + ], + [ + 0.014056779686509448, + 0.014068228026391683, + 0.01408131384598054 + ], + [ + 0.014077511421657439, + 0.014075841191307996, + 0.014057673535630142 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9924332881246145, + "scoreError" : 0.011113059842805861, + "scoreConfidence" : [ + 0.9813202282818086, + 1.0035463479674203 + ], + "scorePercentiles" : { + "0.0" : 0.9829682683310399, + "50.0" : 0.994471576372315, + "90.0" : 0.9996053167416292, + "95.0" : 0.9996053167416292, + "99.0" : 0.9996053167416292, + "99.9" : 0.9996053167416292, + "99.99" : 0.9996053167416292, + "99.999" : 0.9996053167416292, + "99.9999" : 0.9996053167416292, + "100.0" : 0.9996053167416292 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9829682683310399, + 0.9855688172053607, + 0.9835769158143194 + ], + [ + 0.9939944320644071, + 0.9950123619540344, + 0.994471576372315 + ], + [ + 0.9996053167416292, + 0.9982675707726093, + 0.9984343338658147 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012895585300642694, + "scoreError" : 3.062953972559641E-4, + "scoreConfidence" : [ + 0.01258928990338673, + 0.013201880697898658 + ], + "scorePercentiles" : { + "0.0" : 0.012693811217003213, + "50.0" : 0.012905369991386278, + "90.0" : 0.012996414480284876, + "95.0" : 0.012996414480284876, + "99.0" : 0.012996414480284876, + "99.9" : 0.012996414480284876, + "99.99" : 0.012996414480284876, + "99.999" : 0.012996414480284876, + "99.9999" : 0.012996414480284876, + "100.0" : 0.012996414480284876 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012693811217003213, + 0.01288566156665069, + 0.012913996681181655 + ], + [ + 0.012896743301590904, + 0.012996414480284876, + 0.012986884557144824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.811457185997916, + "scoreError" : 0.16061216680757984, + "scoreConfidence" : [ + 3.6508450191903363, + 3.972069352805496 + ], + "scorePercentiles" : { + "0.0" : 3.740837990276739, + "50.0" : 3.814371268649891, + "90.0" : 3.8742911928737414, + "95.0" : 3.8742911928737414, + "99.0" : 3.8742911928737414, + "99.9" : 3.8742911928737414, + "99.99" : 3.8742911928737414, + "99.999" : 3.8742911928737414, + "99.9999" : 3.8742911928737414, + "100.0" : 3.8742911928737414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.851576015396459, + 3.8742911928737414, + 3.8608099899691357 + ], + [ + 3.740837990276739, + 3.7771665219033235, + 3.7640614055680963 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9364844452314522, + "scoreError" : 0.12591397806458157, + "scoreConfidence" : [ + 2.8105704671668708, + 3.0623984232960337 + ], + "scorePercentiles" : { + "0.0" : 2.841760882386364, + "50.0" : 2.9522826517119243, + "90.0" : 3.029664845501363, + "95.0" : 3.029664845501363, + "99.0" : 3.029664845501363, + "99.9" : 3.029664845501363, + "99.99" : 3.029664845501363, + "99.999" : 3.029664845501363, + "99.9999" : 3.029664845501363, + "100.0" : 3.029664845501363 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9522826517119243, + 2.965428013637711, + 2.9503159005899704 + ], + [ + 2.8447495719567693, + 2.841760882386364, + 2.844535181740614 + ], + [ + 2.976455938095238, + 3.029664845501363, + 3.0231670214631197 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17560572190048726, + "scoreError" : 0.006584111512174446, + "scoreConfidence" : [ + 0.16902161038831282, + 0.1821898334126617 + ], + "scorePercentiles" : { + "0.0" : 0.17063822254073885, + "50.0" : 0.17619656395799563, + "90.0" : 0.17981623607789546, + "95.0" : 0.17981623607789546, + "99.0" : 0.17981623607789546, + "99.9" : 0.17981623607789546, + "99.99" : 0.17981623607789546, + "99.999" : 0.17981623607789546, + "99.9999" : 0.17981623607789546, + "100.0" : 0.17981623607789546 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17087530959948055, + 0.1708109856523076, + 0.17063822254073885 + ], + [ + 0.17975555852746622, + 0.17964059028526264, + 0.17981623607789546 + ], + [ + 0.1765262410414828, + 0.17619656395799563, + 0.17619178942175553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32619100712800586, + "scoreError" : 0.013703182184899522, + "scoreConfidence" : [ + 0.31248782494310634, + 0.3398941893129054 + ], + "scorePercentiles" : { + "0.0" : 0.3175438340583622, + "50.0" : 0.32435507112970713, + "90.0" : 0.33869735758314706, + "95.0" : 0.33869735758314706, + "99.0" : 0.33869735758314706, + "99.9" : 0.33869735758314706, + "99.99" : 0.33869735758314706, + "99.999" : 0.33869735758314706, + "99.9999" : 0.33869735758314706, + "100.0" : 0.33869735758314706 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31809932212608943, + 0.3177638269517969, + 0.3175438340583622 + ], + [ + 0.33869735758314706, + 0.33501108552477304, + 0.33497628411603136 + ], + [ + 0.3253834047634542, + 0.32435507112970713, + 0.32388887789869153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15769629753949746, + "scoreError" : 0.013313914295695823, + "scoreConfidence" : [ + 0.14438238324380165, + 0.17101021183519327 + ], + "scorePercentiles" : { + "0.0" : 0.15026901161550135, + "50.0" : 0.15454895558371712, + "90.0" : 0.16813969691976596, + "95.0" : 0.16813969691976596, + "99.0" : 0.16813969691976596, + "99.9" : 0.16813969691976596, + "99.99" : 0.16813969691976596, + "99.999" : 0.16813969691976596, + "99.9999" : 0.16813969691976596, + "100.0" : 0.16813969691976596 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16813969691976596, + 0.16803919120834804, + 0.16780301414548202 + ], + [ + 0.15466450425314732, + 0.15454895558371712, + 0.1545218161379545 + ], + [ + 0.15083692974147034, + 0.15044355825009026, + 0.15026901161550135 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39321215070398746, + "scoreError" : 0.005175623085294156, + "scoreConfidence" : [ + 0.3880365276186933, + 0.39838777378928164 + ], + "scorePercentiles" : { + "0.0" : 0.3913463575174141, + "50.0" : 0.3921057463535132, + "90.0" : 0.4012574662547147, + "95.0" : 0.4012574662547147, + "99.0" : 0.4012574662547147, + "99.9" : 0.4012574662547147, + "99.99" : 0.4012574662547147, + "99.999" : 0.4012574662547147, + "99.9999" : 0.4012574662547147, + "100.0" : 0.4012574662547147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3919904412825337, + 0.3916212337092732, + 0.3913463575174141 + ], + [ + 0.4012574662547147, + 0.3921057463535132, + 0.3917179641975792 + ], + [ + 0.39298994820607536, + 0.39296980847217855, + 0.39291039034260566 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15726034727597302, + "scoreError" : 0.004050535630587042, + "scoreConfidence" : [ + 0.15320981164538597, + 0.16131088290656007 + ], + "scorePercentiles" : { + "0.0" : 0.15441515587844723, + "50.0" : 0.1568665687372549, + "90.0" : 0.16097080030583502, + "95.0" : 0.16097080030583502, + "99.0" : 0.16097080030583502, + "99.9" : 0.16097080030583502, + "99.99" : 0.16097080030583502, + "99.999" : 0.16097080030583502, + "99.9999" : 0.16097080030583502, + "100.0" : 0.16097080030583502 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15741333787718995, + 0.15675702580179954, + 0.1568665687372549 + ], + [ + 0.16097080030583502, + 0.15976038181963415, + 0.15961192857484877 + ], + [ + 0.1546292745856012, + 0.15491865190314635, + 0.15441515587844723 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046845207742204215, + "scoreError" : 0.0018409756490792033, + "scoreConfidence" : [ + 0.04500423209312501, + 0.048686183391283416 + ], + "scorePercentiles" : { + "0.0" : 0.04567891911311283, + "50.0" : 0.04645947486573377, + "90.0" : 0.048691715820174605, + "95.0" : 0.048691715820174605, + "99.0" : 0.048691715820174605, + "99.9" : 0.048691715820174605, + "99.99" : 0.048691715820174605, + "99.999" : 0.048691715820174605, + "99.9999" : 0.048691715820174605, + "100.0" : 0.048691715820174605 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.048691715820174605, + 0.04796834660916949, + 0.04787070228196401 + ], + [ + 0.04584362988227528, + 0.045753071867794, + 0.04567891911311283 + ], + [ + 0.04690812245644648, + 0.04645947486573377, + 0.04643288678316743 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9371650.330817224, + "scoreError" : 192453.16026786753, + "scoreConfidence" : [ + 9179197.170549357, + 9564103.491085092 + ], + "scorePercentiles" : { + "0.0" : 9251249.041628122, + "50.0" : 9319632.198324023, + "90.0" : 9540715.473784557, + "95.0" : 9540715.473784557, + "99.0" : 9540715.473784557, + "99.9" : 9540715.473784557, + "99.99" : 9540715.473784557, + "99.999" : 9540715.473784557, + "99.9999" : 9540715.473784557, + "100.0" : 9540715.473784557 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9251249.041628122, + 9282600.880333953, + 9321988.44361603 + ], + [ + 9319632.198324023, + 9301838.871747212, + 9303449.284651162 + ], + [ + 9512346.58174905, + 9511032.201520912, + 9540715.473784557 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-15T07:21:56Z-14d74114b364ffcebdef37840cb2f2ce58cb485c-jdk17.json b/performance-results/2025-04-15T07:21:56Z-14d74114b364ffcebdef37840cb2f2ce58cb485c-jdk17.json new file mode 100644 index 0000000000..6e31c81490 --- /dev/null +++ b/performance-results/2025-04-15T07:21:56Z-14d74114b364ffcebdef37840cb2f2ce58cb485c-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.410292803144114, + "scoreError" : 0.01182806701663521, + "scoreConfidence" : [ + 3.3984647361274787, + 3.4221208701607493 + ], + "scorePercentiles" : { + "0.0" : 3.4077670830798916, + "50.0" : 3.410809558111277, + "90.0" : 3.4117850132740113, + "95.0" : 3.4117850132740113, + "99.0" : 3.4117850132740113, + "99.9" : 3.4117850132740113, + "99.99" : 3.4117850132740113, + "99.999" : 3.4117850132740113, + "99.9999" : 3.4117850132740113, + "100.0" : 3.4117850132740113 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.41013459916428, + 3.4117850132740113 + ], + [ + 3.4077670830798916, + 3.411484517058274 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7222031601810324, + "scoreError" : 0.01347607151342635, + "scoreConfidence" : [ + 1.708727088667606, + 1.7356792316944587 + ], + "scorePercentiles" : { + "0.0" : 1.7199194158206257, + "50.0" : 1.7223592365796612, + "90.0" : 1.7241747517441812, + "95.0" : 1.7241747517441812, + "99.0" : 1.7241747517441812, + "99.9" : 1.7241747517441812, + "99.99" : 1.7241747517441812, + "99.999" : 1.7241747517441812, + "99.9999" : 1.7241747517441812, + "100.0" : 1.7241747517441812 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7199194158206257, + 1.7209635716914682 + ], + [ + 1.7241747517441812, + 1.7237549014678542 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8660841476755752, + "scoreError" : 0.005775184550174271, + "scoreConfidence" : [ + 0.860308963125401, + 0.8718593322257494 + ], + "scorePercentiles" : { + "0.0" : 0.8652621597398462, + "50.0" : 0.8659391194902488, + "90.0" : 0.8671961919819569, + "95.0" : 0.8671961919819569, + "99.0" : 0.8671961919819569, + "99.9" : 0.8671961919819569, + "99.99" : 0.8671961919819569, + "99.999" : 0.8671961919819569, + "99.9999" : 0.8671961919819569, + "100.0" : 0.8671961919819569 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.865469112632009, + 0.8671961919819569 + ], + [ + 0.8652621597398462, + 0.8664091263484885 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.871294708545065, + "scoreError" : 0.15059860362868493, + "scoreConfidence" : [ + 15.72069610491638, + 16.02189331217375 + ], + "scorePercentiles" : { + "0.0" : 15.720407723693132, + "50.0" : 15.919099829453616, + "90.0" : 15.971684147480252, + "95.0" : 15.971684147480252, + "99.0" : 15.971684147480252, + "99.9" : 15.971684147480252, + "99.99" : 15.971684147480252, + "99.999" : 15.971684147480252, + "99.9999" : 15.971684147480252, + "100.0" : 15.971684147480252 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.925823796685513, + 15.930324239715281, + 15.869413499478672 + ], + [ + 15.759283678616658, + 15.720407723693132, + 15.801710940429453 + ], + [ + 15.919099829453616, + 15.943904521353007, + 15.971684147480252 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2608.1472437379434, + "scoreError" : 50.5379813336605, + "scoreConfidence" : [ + 2557.609262404283, + 2658.685225071604 + ], + "scorePercentiles" : { + "0.0" : 2566.014336029912, + "50.0" : 2615.8878491919777, + "90.0" : 2642.858195737688, + "95.0" : 2642.858195737688, + "99.0" : 2642.858195737688, + "99.9" : 2642.858195737688, + "99.99" : 2642.858195737688, + "99.999" : 2642.858195737688, + "99.9999" : 2642.858195737688, + "100.0" : 2642.858195737688 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2621.199372962536, + 2615.8858948444877, + 2615.8878491919777 + ], + [ + 2566.014336029912, + 2576.2600691941225, + 2568.5318925328747 + ], + [ + 2642.858195737688, + 2640.747659848716, + 2625.939923299173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70794.01963855607, + "scoreError" : 528.9974177671851, + "scoreConfidence" : [ + 70265.02222078889, + 71323.01705632325 + ], + "scorePercentiles" : { + "0.0" : 70321.11046608105, + "50.0" : 70948.41406005879, + "90.0" : 71091.15177592258, + "95.0" : 71091.15177592258, + "99.0" : 71091.15177592258, + "99.9" : 71091.15177592258, + "99.99" : 71091.15177592258, + "99.999" : 71091.15177592258, + "99.9999" : 71091.15177592258, + "100.0" : 71091.15177592258 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70321.11046608105, + 70404.26807500672, + 70426.34280576854 + ], + [ + 71009.73090780649, + 71091.15177592258, + 71082.580950961 + ], + [ + 70948.41406005879, + 70896.3874848616, + 70966.19022053799 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 343.2410161356936, + "scoreError" : 4.623746215215708, + "scoreConfidence" : [ + 338.6172699204779, + 347.8647623509093 + ], + "scorePercentiles" : { + "0.0" : 339.8211997115519, + "50.0" : 343.66605545073764, + "90.0" : 347.1444375193373, + "95.0" : 347.1444375193373, + "99.0" : 347.1444375193373, + "99.9" : 347.1444375193373, + "99.99" : 347.1444375193373, + "99.999" : 347.1444375193373, + "99.9999" : 347.1444375193373, + "100.0" : 347.1444375193373 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 344.0689153690961, + 347.07423896993123, + 347.1444375193373 + ], + [ + 339.8211997115519, + 340.85217353178217, + 339.866531813213 + ], + [ + 342.6439616080109, + 344.03163124758225, + 343.66605545073764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.7575472969454, + "scoreError" : 2.8543196982554644, + "scoreConfidence" : [ + 101.90322759868994, + 107.61186699520087 + ], + "scorePercentiles" : { + "0.0" : 103.11215378618374, + "50.0" : 104.21575575565748, + "90.0" : 107.22682267956844, + "95.0" : 107.22682267956844, + "99.0" : 107.22682267956844, + "99.9" : 107.22682267956844, + "99.99" : 107.22682267956844, + "99.999" : 107.22682267956844, + "99.9999" : 107.22682267956844, + "100.0" : 107.22682267956844 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 103.11215378618374, + 103.29999631689557, + 103.2246620997145 + ], + [ + 107.22682267956844, + 106.85476881446539, + 106.76102285304083 + ], + [ + 103.80947788614054, + 104.21575575565748, + 104.31326548084208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06257426671045607, + "scoreError" : 3.8954539348918946E-4, + "scoreConfidence" : [ + 0.06218472131696688, + 0.06296381210394526 + ], + "scorePercentiles" : { + "0.0" : 0.062250462762381414, + "50.0" : 0.06254025957010363, + "90.0" : 0.06294470145777734, + "95.0" : 0.06294470145777734, + "99.0" : 0.06294470145777734, + "99.9" : 0.06294470145777734, + "99.99" : 0.06294470145777734, + "99.999" : 0.06294470145777734, + "99.9999" : 0.06294470145777734, + "100.0" : 0.06294470145777734 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06267829445684057, + 0.06287059840688046, + 0.06294470145777734 + ], + [ + 0.06242959036851601, + 0.06254025957010363, + 0.06264179693059384 + ], + [ + 0.06235090103189201, + 0.0624617954091193, + 0.062250462762381414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.747283104606411E-4, + "scoreError" : 8.538668176370108E-6, + "scoreConfidence" : [ + 3.6618964228427096E-4, + 3.832669786370112E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6897100525467864E-4, + "50.0" : 3.7324096239890053E-4, + "90.0" : 3.816977656735156E-4, + "95.0" : 3.816977656735156E-4, + "99.0" : 3.816977656735156E-4, + "99.9" : 3.816977656735156E-4, + "99.99" : 3.816977656735156E-4, + "99.999" : 3.816977656735156E-4, + "99.9999" : 3.816977656735156E-4, + "100.0" : 3.816977656735156E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6897100525467864E-4, + 3.705701313630293E-4, + 3.7022087381974523E-4 + ], + [ + 3.807030475403627E-4, + 3.816977656735156E-4, + 3.8124218696954397E-4 + ], + [ + 3.73497417444771E-4, + 3.7324096239890053E-4, + 3.724114036812226E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11044553323371656, + "scoreError" : 0.0035570951835899693, + "scoreConfidence" : [ + 0.10688843805012659, + 0.11400262841730653 + ], + "scorePercentiles" : { + "0.0" : 0.10885254383959769, + "50.0" : 0.10913497449553099, + "90.0" : 0.11351311864195149, + "95.0" : 0.11351311864195149, + "99.0" : 0.11351311864195149, + "99.9" : 0.11351311864195149, + "99.99" : 0.11351311864195149, + "99.999" : 0.11351311864195149, + "99.9999" : 0.11351311864195149, + "100.0" : 0.11351311864195149 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11286081799200957, + 0.11351311864195149, + 0.11339104114885704 + ], + [ + 0.10908786974070317, + 0.10913497449553099, + 0.10921466787165261 + ], + [ + 0.10894872224038, + 0.10885254383959769, + 0.10900604313276652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014236036951059041, + "scoreError" : 4.298809354819538E-4, + "scoreConfidence" : [ + 0.013806156015577086, + 0.014665917886540996 + ], + "scorePercentiles" : { + "0.0" : 0.013972213143202052, + "50.0" : 0.014160779609054838, + "90.0" : 0.014568680119694703, + "95.0" : 0.014568680119694703, + "99.0" : 0.014568680119694703, + "99.9" : 0.014568680119694703, + "99.99" : 0.014568680119694703, + "99.999" : 0.014568680119694703, + "99.9999" : 0.014568680119694703, + "100.0" : 0.014568680119694703 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014558670123339603, + 0.014568680119694703, + 0.014554224121846324 + ], + [ + 0.013998457149136376, + 0.013980279631540244, + 0.013972213143202052 + ], + [ + 0.014160779609054838, + 0.014150098439547315, + 0.01418093022216991 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9854941574416668, + "scoreError" : 0.010708625724236557, + "scoreConfidence" : [ + 0.9747855317174302, + 0.9962027831659034 + ], + "scorePercentiles" : { + "0.0" : 0.9781389203834115, + "50.0" : 0.9832220200570249, + "90.0" : 0.9944033431440787, + "95.0" : 0.9944033431440787, + "99.0" : 0.9944033431440787, + "99.9" : 0.9944033431440787, + "99.99" : 0.9944033431440787, + "99.999" : 0.9944033431440787, + "99.9999" : 0.9944033431440787, + "100.0" : 0.9944033431440787 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9781389203834115, + 0.9832220200570249, + 0.9856847189040016 + ], + [ + 0.9795573236360074, + 0.9806987001078749, + 0.9816890071659958 + ], + [ + 0.9944033431440787, + 0.9929992610465693, + 0.9930541225300368 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013174758590103293, + "scoreError" : 4.240949771235966E-4, + "scoreConfidence" : [ + 0.012750663612979695, + 0.01359885356722689 + ], + "scorePercentiles" : { + "0.0" : 0.012950466615558341, + "50.0" : 0.013190393459009467, + "90.0" : 0.013315938673604989, + "95.0" : 0.013315938673604989, + "99.0" : 0.013315938673604989, + "99.9" : 0.013315938673604989, + "99.99" : 0.013315938673604989, + "99.999" : 0.013315938673604989, + "99.9999" : 0.013315938673604989, + "100.0" : 0.013315938673604989 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013315938673604989, + 0.013310052118243649, + 0.013286221689013599 + ], + [ + 0.012950466615558341, + 0.013094565229005335, + 0.01309130721519385 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.9291784224187665, + "scoreError" : 0.18834085042439327, + "scoreConfidence" : [ + 3.740837571994373, + 4.117519272843159 + ], + "scorePercentiles" : { + "0.0" : 3.8460302290545734, + "50.0" : 3.940609385460778, + "90.0" : 3.9935603535514765, + "95.0" : 3.9935603535514765, + "99.0" : 3.9935603535514765, + "99.9" : 3.9935603535514765, + "99.99" : 3.9935603535514765, + "99.999" : 3.9935603535514765, + "99.9999" : 3.9935603535514765, + "100.0" : 3.9935603535514765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8460302290545734, + 3.8641268261205566, + 3.900064360093531 + ], + [ + 3.9811544108280255, + 3.9901343548644337, + 3.9935603535514765 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9267776734148163, + "scoreError" : 0.017990781784617955, + "scoreConfidence" : [ + 2.908786891630198, + 2.9447684551994344 + ], + "scorePercentiles" : { + "0.0" : 2.9109470908032598, + "50.0" : 2.927967918911007, + "90.0" : 2.9405286777418405, + "95.0" : 2.9405286777418405, + "99.0" : 2.9405286777418405, + "99.9" : 2.9405286777418405, + "99.99" : 2.9405286777418405, + "99.999" : 2.9405286777418405, + "99.9999" : 2.9405286777418405, + "100.0" : 2.9405286777418405 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.927967918911007, + 2.918395442077619, + 2.9109470908032598 + ], + [ + 2.929937630931459, + 2.92262867270602, + 2.9152304590498397 + ], + [ + 2.9395852242798353, + 2.9405286777418405, + 2.9357779442324627 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1760237677009665, + "scoreError" : 0.0030617428581940936, + "scoreConfidence" : [ + 0.1729620248427724, + 0.1790855105591606 + ], + "scorePercentiles" : { + "0.0" : 0.17315710711317356, + "50.0" : 0.17711498407778684, + "90.0" : 0.177475656113014, + "95.0" : 0.177475656113014, + "99.0" : 0.177475656113014, + "99.9" : 0.177475656113014, + "99.99" : 0.177475656113014, + "99.999" : 0.177475656113014, + "99.9999" : 0.177475656113014, + "100.0" : 0.177475656113014 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17722715315634638, + 0.17711498407778684, + 0.17687001798726565 + ], + [ + 0.17727816236482893, + 0.1773046742491401, + 0.177475656113014 + ], + [ + 0.17443281527995813, + 0.173353338967185, + 0.17315710711317356 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33084230324855846, + "scoreError" : 0.016368594437593413, + "scoreConfidence" : [ + 0.31447370881096504, + 0.3472108976861519 + ], + "scorePercentiles" : { + "0.0" : 0.3222616254511472, + "50.0" : 0.32729555554100936, + "90.0" : 0.3511456440886267, + "95.0" : 0.3511456440886267, + "99.0" : 0.3511456440886267, + "99.9" : 0.3511456440886267, + "99.99" : 0.3511456440886267, + "99.999" : 0.3511456440886267, + "99.9999" : 0.3511456440886267, + "100.0" : 0.3511456440886267 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32729555554100936, + 0.32686044673966336, + 0.3286277139336181 + ], + [ + 0.32302589227340267, + 0.3223118456505624, + 0.3222616254511472 + ], + [ + 0.33920483026931686, + 0.3511456440886267, + 0.33684717528967933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1577641674397424, + "scoreError" : 0.0036615746579684327, + "scoreConfidence" : [ + 0.15410259278177396, + 0.16142574209771082 + ], + "scorePercentiles" : { + "0.0" : 0.15590696673006765, + "50.0" : 0.15664480703320802, + "90.0" : 0.16070379563861928, + "95.0" : 0.16070379563861928, + "99.0" : 0.16070379563861928, + "99.9" : 0.16070379563861928, + "99.99" : 0.16070379563861928, + "99.999" : 0.16070379563861928, + "99.9999" : 0.16070379563861928, + "100.0" : 0.16070379563861928 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15590696673006765, + 0.15667597183010326, + 0.15664480703320802 + ], + [ + 0.16066627109875808, + 0.16070379563861928, + 0.160586099722191 + ], + [ + 0.15622478293132538, + 0.15613670856232825, + 0.15633210341108053 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.392909867879589, + "scoreError" : 0.011401638649886373, + "scoreConfidence" : [ + 0.3815082292297026, + 0.40431150652947534 + ], + "scorePercentiles" : { + "0.0" : 0.38323660404690735, + "50.0" : 0.3918369251626048, + "90.0" : 0.40141045145104964, + "95.0" : 0.40141045145104964, + "99.0" : 0.40141045145104964, + "99.9" : 0.40141045145104964, + "99.99" : 0.40141045145104964, + "99.999" : 0.40141045145104964, + "99.9999" : 0.40141045145104964, + "100.0" : 0.40141045145104964 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3937036515097831, + 0.39128612301432036, + 0.3918369251626048 + ], + [ + 0.40141045145104964, + 0.4008483047538881, + 0.40047799875855994 + ], + [ + 0.38718047636377717, + 0.3862082758554105, + 0.38323660404690735 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15825107332007277, + "scoreError" : 0.005378564708602068, + "scoreConfidence" : [ + 0.1528725086114707, + 0.16362963802867483 + ], + "scorePercentiles" : { + "0.0" : 0.15381523411520417, + "50.0" : 0.15953894543888197, + "90.0" : 0.1622689236710586, + "95.0" : 0.1622689236710586, + "99.0" : 0.1622689236710586, + "99.9" : 0.1622689236710586, + "99.99" : 0.1622689236710586, + "99.999" : 0.1622689236710586, + "99.9999" : 0.1622689236710586, + "100.0" : 0.1622689236710586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1543801934019791, + 0.15381523411520417, + 0.15423138014158144 + ], + [ + 0.15971047701030106, + 0.15953894543888197, + 0.15933283052116692 + ], + [ + 0.1622689236710586, + 0.1605263527834853, + 0.16045532279699634 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046909693803489375, + "scoreError" : 3.033970327389251E-4, + "scoreConfidence" : [ + 0.04660629677075045, + 0.0472130908362283 + ], + "scorePercentiles" : { + "0.0" : 0.04675042174797223, + "50.0" : 0.04683818963110761, + "90.0" : 0.047358650811240875, + "95.0" : 0.047358650811240875, + "99.0" : 0.047358650811240875, + "99.9" : 0.047358650811240875, + "99.99" : 0.047358650811240875, + "99.999" : 0.047358650811240875, + "99.9999" : 0.047358650811240875, + "100.0" : 0.047358650811240875 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04680276841893422, + 0.04683818963110761, + 0.04675042174797223 + ], + [ + 0.046892010109772626, + 0.04682796918300546, + 0.046823597974444096 + ], + [ + 0.047358650811240875, + 0.04695519927032662, + 0.04693843708460065 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9633664.701751849, + "scoreError" : 175694.1089404981, + "scoreConfidence" : [ + 9457970.59281135, + 9809358.810692348 + ], + "scorePercentiles" : { + "0.0" : 9509088.715779468, + "50.0" : 9595729.272291467, + "90.0" : 9791252.443248533, + "95.0" : 9791252.443248533, + "99.0" : 9791252.443248533, + "99.9" : 9791252.443248533, + "99.99" : 9791252.443248533, + "99.999" : 9791252.443248533, + "99.9999" : 9791252.443248533, + "100.0" : 9791252.443248533 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9791252.443248533, + 9749772.801169591, + 9750620.584795322 + ], + [ + 9635159.6088632, + 9571225.518660286, + 9567675.37667304 + ], + [ + 9595729.272291467, + 9532457.994285714, + 9509088.715779468 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-19T05:34:20Z-083fac7eaad2329f371f803324ff855b0de33531-jdk17.json b/performance-results/2025-04-19T05:34:20Z-083fac7eaad2329f371f803324ff855b0de33531-jdk17.json new file mode 100644 index 0000000000..f09dfa0541 --- /dev/null +++ b/performance-results/2025-04-19T05:34:20Z-083fac7eaad2329f371f803324ff855b0de33531-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.42627374205401, + "scoreError" : 0.016011546361178, + "scoreConfidence" : [ + 3.410262195692832, + 3.4422852884151878 + ], + "scorePercentiles" : { + "0.0" : 3.423400368844257, + "50.0" : 3.4261432518671446, + "90.0" : 3.4294080956374926, + "95.0" : 3.4294080956374926, + "99.0" : 3.4294080956374926, + "99.9" : 3.4294080956374926, + "99.99" : 3.4294080956374926, + "99.999" : 3.4294080956374926, + "99.9999" : 3.4294080956374926, + "100.0" : 3.4294080956374926 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.423400368844257, + 3.4257533516251386 + ], + [ + 3.426533152109151, + 3.4294080956374926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.73103735947286, + "scoreError" : 0.006679532663678652, + "scoreConfidence" : [ + 1.7243578268091815, + 1.7377168921365387 + ], + "scorePercentiles" : { + "0.0" : 1.7301200757427653, + "50.0" : 1.7307736838477226, + "90.0" : 1.7324819944532301, + "95.0" : 1.7324819944532301, + "99.0" : 1.7324819944532301, + "99.9" : 1.7324819944532301, + "99.99" : 1.7324819944532301, + "99.999" : 1.7324819944532301, + "99.9999" : 1.7324819944532301, + "100.0" : 1.7324819944532301 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.731036325346641, + 1.7324819944532301 + ], + [ + 1.7305110423488042, + 1.7301200757427653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8699607741534178, + "scoreError" : 0.002506721689289652, + "scoreConfidence" : [ + 0.8674540524641281, + 0.8724674958427074 + ], + "scorePercentiles" : { + "0.0" : 0.8694631713130918, + "50.0" : 0.8700053139358462, + "90.0" : 0.870369297428887, + "95.0" : 0.870369297428887, + "99.0" : 0.870369297428887, + "99.9" : 0.870369297428887, + "99.99" : 0.870369297428887, + "99.999" : 0.870369297428887, + "99.9999" : 0.870369297428887, + "100.0" : 0.870369297428887 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8694631713130918, + 0.870369297428887 + ], + [ + 0.869876913031519, + 0.8701337148401734 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.41419899981236, + "scoreError" : 0.13936351326473603, + "scoreConfidence" : [ + 16.274835486547623, + 16.553562513077097 + ], + "scorePercentiles" : { + "0.0" : 16.339535155742567, + "50.0" : 16.386084511518415, + "90.0" : 16.550785814625694, + "95.0" : 16.550785814625694, + "99.0" : 16.550785814625694, + "99.9" : 16.550785814625694, + "99.99" : 16.550785814625694, + "99.999" : 16.550785814625694, + "99.9999" : 16.550785814625694, + "100.0" : 16.550785814625694 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.339535155742567, + 16.346768148883314, + 16.348522139523087 + ], + [ + 16.46806272650543, + 16.550785814625694, + 16.531728368824346 + ], + [ + 16.34791640635959, + 16.386084511518415, + 16.408387726328822 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2748.8348912858187, + "scoreError" : 79.68130762190818, + "scoreConfidence" : [ + 2669.1535836639105, + 2828.516198907727 + ], + "scorePercentiles" : { + "0.0" : 2684.2126429590894, + "50.0" : 2777.8148801532543, + "90.0" : 2787.501307160279, + "95.0" : 2787.501307160279, + "99.0" : 2787.501307160279, + "99.9" : 2787.501307160279, + "99.99" : 2787.501307160279, + "99.999" : 2787.501307160279, + "99.9999" : 2787.501307160279, + "100.0" : 2787.501307160279 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2687.4400408233214, + 2684.2126429590894, + 2686.373523970276 + ], + [ + 2787.501307160279, + 2784.6973486013626, + 2782.533622952103 + ], + [ + 2780.3541481711923, + 2768.586506781491, + 2777.8148801532543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69631.43025261146, + "scoreError" : 1086.394300549713, + "scoreConfidence" : [ + 68545.03595206175, + 70717.82455316118 + ], + "scorePercentiles" : { + "0.0" : 68718.54748457175, + "50.0" : 70044.63602743245, + "90.0" : 70094.41242619143, + "95.0" : 70094.41242619143, + "99.0" : 70094.41242619143, + "99.9" : 70094.41242619143, + "99.99" : 70094.41242619143, + "99.999" : 70094.41242619143, + "99.9999" : 70094.41242619143, + "100.0" : 70094.41242619143 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70064.2047292378, + 70070.01908365132, + 70094.41242619143 + ], + [ + 70056.86541256234, + 70042.16307319765, + 70044.63602743245 + ], + [ + 68793.7050076566, + 68718.54748457175, + 68798.31902900171 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 358.5636025029099, + "scoreError" : 10.522905124506686, + "scoreConfidence" : [ + 348.0406973784032, + 369.08650762741655 + ], + "scorePercentiles" : { + "0.0" : 350.14734939351376, + "50.0" : 361.657800429712, + "90.0" : 363.842414915681, + "95.0" : 363.842414915681, + "99.0" : 363.842414915681, + "99.9" : 363.842414915681, + "99.99" : 363.842414915681, + "99.999" : 363.842414915681, + "99.9999" : 363.842414915681, + "100.0" : 363.842414915681 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 361.657800429712, + 361.63169630707563, + 361.86051323800467 + ], + [ + 363.842414915681, + 363.68413704352093, + 363.5156717071805 + ], + [ + 350.14734939351376, + 350.2774591551149, + 350.4553803363854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.73883077999297, + "scoreError" : 2.1541084370248815, + "scoreConfidence" : [ + 103.58472234296808, + 107.89293921701785 + ], + "scorePercentiles" : { + "0.0" : 104.07559453327093, + "50.0" : 105.97683572101799, + "90.0" : 107.32568624594654, + "95.0" : 107.32568624594654, + "99.0" : 107.32568624594654, + "99.9" : 107.32568624594654, + "99.99" : 107.32568624594654, + "99.999" : 107.32568624594654, + "99.9999" : 107.32568624594654, + "100.0" : 107.32568624594654 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.3730500643636, + 104.07559453327093, + 104.08066267674415 + ], + [ + 105.97683572101799, + 105.9739707157024, + 105.98239379141204 + ], + [ + 106.58843842669576, + 107.27284484478315, + 107.32568624594654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061187186123597574, + "scoreError" : 3.6458663901066564E-4, + "scoreConfidence" : [ + 0.06082259948458691, + 0.06155177276260824 + ], + "scorePercentiles" : { + "0.0" : 0.06090785262356488, + "50.0" : 0.0611900615928727, + "90.0" : 0.06145593445181908, + "95.0" : 0.06145593445181908, + "99.0" : 0.06145593445181908, + "99.9" : 0.06145593445181908, + "99.99" : 0.06145593445181908, + "99.999" : 0.06145593445181908, + "99.9999" : 0.06145593445181908, + "100.0" : 0.06145593445181908 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060925311896087436, + 0.06090785262356488, + 0.0609775741873327 + ], + [ + 0.06140714787841572, + 0.06145593445181908, + 0.06144207211364181 + ], + [ + 0.061204125846135014, + 0.0611900615928727, + 0.061174594522508854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.680535259873933E-4, + "scoreError" : 1.2617565179847096E-5, + "scoreConfidence" : [ + 3.5543596080754624E-4, + 3.806710911672404E-4 + ], + "scorePercentiles" : { + "0.0" : 3.608635754554795E-4, + "50.0" : 3.650681987878625E-4, + "90.0" : 3.7884101071388387E-4, + "95.0" : 3.7884101071388387E-4, + "99.0" : 3.7884101071388387E-4, + "99.9" : 3.7884101071388387E-4, + "99.99" : 3.7884101071388387E-4, + "99.999" : 3.7884101071388387E-4, + "99.9999" : 3.7884101071388387E-4, + "100.0" : 3.7884101071388387E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.612773151072454E-4, + 3.608635754554795E-4, + 3.612575641438211E-4 + ], + [ + 3.6489192063517893E-4, + 3.6589958807135793E-4, + 3.650681987878625E-4 + ], + [ + 3.7884101071388387E-4, + 3.7679756682629267E-4, + 3.775849941454177E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1111973415085475, + "scoreError" : 0.004008218317969188, + "scoreConfidence" : [ + 0.10718912319057831, + 0.11520555982651669 + ], + "scorePercentiles" : { + "0.0" : 0.1081608231699403, + "50.0" : 0.11170663668148612, + "90.0" : 0.11366037566348045, + "95.0" : 0.11366037566348045, + "99.0" : 0.11366037566348045, + "99.9" : 0.11366037566348045, + "99.99" : 0.11366037566348045, + "99.999" : 0.11366037566348045, + "99.9999" : 0.11366037566348045, + "100.0" : 0.11366037566348045 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11366037566348045, + 0.11365532800300045, + 0.11365060471644504 + ], + [ + 0.1081608231699403, + 0.10824979241177744, + 0.10825240464179783 + ], + [ + 0.11173908936712255, + 0.11170663668148612, + 0.11170101892187745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014260699539865742, + "scoreError" : 3.2143317791977834E-4, + "scoreConfidence" : [ + 0.013939266361945963, + 0.014582132717785521 + ], + "scorePercentiles" : { + "0.0" : 0.014016248590682668, + "50.0" : 0.014315274706790941, + "90.0" : 0.014452096543242348, + "95.0" : 0.014452096543242348, + "99.0" : 0.014452096543242348, + "99.9" : 0.014452096543242348, + "99.99" : 0.014452096543242348, + "99.999" : 0.014452096543242348, + "99.9999" : 0.014452096543242348, + "100.0" : 0.014452096543242348 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014016248590682668, + 0.014017658773412729, + 0.01401817411770643 + ], + [ + 0.014315274706790941, + 0.014313201249813931, + 0.014320542904604721 + ], + [ + 0.014452096543242348, + 0.01445045396573549, + 0.014442645006802406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9769531999380311, + "scoreError" : 0.04077356801038438, + "scoreConfidence" : [ + 0.9361796319276467, + 1.0177267679484154 + ], + "scorePercentiles" : { + "0.0" : 0.9553780986816967, + "50.0" : 0.9657025842023947, + "90.0" : 1.0090252014932903, + "95.0" : 1.0090252014932903, + "99.0" : 1.0090252014932903, + "99.9" : 1.0090252014932903, + "99.99" : 1.0090252014932903, + "99.999" : 1.0090252014932903, + "99.9999" : 1.0090252014932903, + "100.0" : 1.0090252014932903 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9648999544577384, + 0.9657025842023947, + 0.9661773759057096 + ], + [ + 1.0087031128706878, + 1.0090252014932903, + 1.008847105417129 + ], + [ + 0.9568213258394719, + 0.9570240405741627, + 0.9553780986816967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012924418906265613, + "scoreError" : 3.8965013306023873E-4, + "scoreConfidence" : [ + 0.012534768773205375, + 0.013314069039325851 + ], + "scorePercentiles" : { + "0.0" : 0.012735315866017692, + "50.0" : 0.012940439808610482, + "90.0" : 0.013049666281276018, + "95.0" : 0.013049666281276018, + "99.0" : 0.013049666281276018, + "99.9" : 0.013049666281276018, + "99.99" : 0.013049666281276018, + "99.999" : 0.013049666281276018, + "99.9999" : 0.013049666281276018, + "100.0" : 0.013049666281276018 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013043667261443586, + 0.013049666281276018, + 0.013047006646000657 + ], + [ + 0.012735315866017692, + 0.012837212355777377, + 0.01283364502707836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.566305886143264, + "scoreError" : 0.09570705350222038, + "scoreConfidence" : [ + 3.4705988326410435, + 3.6620129396454844 + ], + "scorePercentiles" : { + "0.0" : 3.5189903342716398, + "50.0" : 3.55783447583511, + "90.0" : 3.6104352953068592, + "95.0" : 3.6104352953068592, + "99.0" : 3.6104352953068592, + "99.9" : 3.6104352953068592, + "99.99" : 3.6104352953068592, + "99.999" : 3.6104352953068592, + "99.9999" : 3.6104352953068592, + "100.0" : 3.6104352953068592 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.561564, + 3.6015119863210945, + 3.6104352953068592 + ], + [ + 3.5189903342716398, + 3.551228749289773, + 3.55410495167022 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.800649162591949, + "scoreError" : 0.0345714763720071, + "scoreConfidence" : [ + 2.766077686219942, + 2.8352206389639565 + ], + "scorePercentiles" : { + "0.0" : 2.7742893509015256, + "50.0" : 2.799184954100196, + "90.0" : 2.8341115919523943, + "95.0" : 2.8341115919523943, + "99.0" : 2.8341115919523943, + "99.9" : 2.8341115919523943, + "99.99" : 2.8341115919523943, + "99.999" : 2.8341115919523943, + "99.9999" : 2.8341115919523943, + "100.0" : 2.8341115919523943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.796055624545709, + 2.7997031704927213, + 2.799184954100196 + ], + [ + 2.7742893509015256, + 2.7824100247566066, + 2.7823066703755215 + ], + [ + 2.8341115919523943, + 2.8292017445544553, + 2.8085793316484136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17267050230088243, + "scoreError" : 0.003151151466562172, + "scoreConfidence" : [ + 0.16951935083432026, + 0.1758216537674446 + ], + "scorePercentiles" : { + "0.0" : 0.17111582447254495, + "50.0" : 0.17164817255406797, + "90.0" : 0.1752360331364887, + "95.0" : 0.1752360331364887, + "99.0" : 0.1752360331364887, + "99.9" : 0.1752360331364887, + "99.99" : 0.1752360331364887, + "99.999" : 0.1752360331364887, + "99.9999" : 0.1752360331364887, + "100.0" : 0.1752360331364887 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1752300553189998, + 0.1752360331364887, + 0.17500771766332407 + ], + [ + 0.17137741852892788, + 0.171670974593147, + 0.17151709153745884 + ], + [ + 0.17164817255406797, + 0.17123123290298278, + 0.17111582447254495 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3235524142428894, + "scoreError" : 0.004084250483863322, + "scoreConfidence" : [ + 0.3194681637590261, + 0.3276366647267527 + ], + "scorePercentiles" : { + "0.0" : 0.32034494381266615, + "50.0" : 0.3238990923724696, + "90.0" : 0.32674055433575117, + "95.0" : 0.32674055433575117, + "99.0" : 0.32674055433575117, + "99.9" : 0.32674055433575117, + "99.99" : 0.32674055433575117, + "99.999" : 0.32674055433575117, + "99.9999" : 0.32674055433575117, + "100.0" : 0.32674055433575117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3241351402502269, + 0.3238990923724696, + 0.3237139987051664 + ], + [ + 0.320722837299551, + 0.32034494381266615, + 0.32074722987362886 + ], + [ + 0.32674055433575117, + 0.3259625402718472, + 0.3257053912646973 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16539352779052965, + "scoreError" : 0.0048365102969989155, + "scoreConfidence" : [ + 0.16055701749353074, + 0.17023003808752857 + ], + "scorePercentiles" : { + "0.0" : 0.16211707347004944, + "50.0" : 0.1651007180452369, + "90.0" : 0.16910644712188852, + "95.0" : 0.16910644712188852, + "99.0" : 0.16910644712188852, + "99.9" : 0.16910644712188852, + "99.99" : 0.16910644712188852, + "99.999" : 0.16910644712188852, + "99.9999" : 0.16910644712188852, + "100.0" : 0.16910644712188852 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16877239570992186, + 0.1686780631346355, + 0.16910644712188852 + ], + [ + 0.165262546594834, + 0.1651007180452369, + 0.16491513333223393 + ], + [ + 0.16234858171664204, + 0.16224079098932476, + 0.16211707347004944 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38974448413117135, + "scoreError" : 0.00801366997563882, + "scoreConfidence" : [ + 0.38173081415553256, + 0.39775815410681015 + ], + "scorePercentiles" : { + "0.0" : 0.3837897027286334, + "50.0" : 0.3899108134747349, + "90.0" : 0.3994573024565608, + "95.0" : 0.3994573024565608, + "99.0" : 0.3994573024565608, + "99.9" : 0.3994573024565608, + "99.99" : 0.3994573024565608, + "99.999" : 0.3994573024565608, + "99.9999" : 0.3994573024565608, + "100.0" : 0.3994573024565608 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39020925066333695, + 0.3898385298222361, + 0.3899108134747349 + ], + [ + 0.3848243881171355, + 0.3856046933369322, + 0.3837897027286334 + ], + [ + 0.3994573024565608, + 0.3922103194101267, + 0.3918553571708464 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15612984119790863, + "scoreError" : 0.0014828309073842754, + "scoreConfidence" : [ + 0.15464701029052436, + 0.1576126721052929 + ], + "scorePercentiles" : { + "0.0" : 0.15515133153362812, + "50.0" : 0.15579655467618053, + "90.0" : 0.15749902234856836, + "95.0" : 0.15749902234856836, + "99.0" : 0.15749902234856836, + "99.9" : 0.15749902234856836, + "99.99" : 0.15749902234856836, + "99.999" : 0.15749902234856836, + "99.9999" : 0.15749902234856836, + "100.0" : 0.15749902234856836 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1562939737430255, + 0.15577637251542154, + 0.15579655467618053 + ], + [ + 0.15737729339187637, + 0.15749902234856836, + 0.15663811916733236 + ], + [ + 0.15515133153362812, + 0.15529291875271756, + 0.15534298465242719 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0470756026279924, + "scoreError" : 6.691578266174269E-4, + "scoreConfidence" : [ + 0.04640644480137498, + 0.047744760454609826 + ], + "scorePercentiles" : { + "0.0" : 0.04659337120852087, + "50.0" : 0.0470886511903865, + "90.0" : 0.04761406129746459, + "95.0" : 0.04761406129746459, + "99.0" : 0.04761406129746459, + "99.9" : 0.04761406129746459, + "99.99" : 0.04761406129746459, + "99.999" : 0.04761406129746459, + "99.9999" : 0.04761406129746459, + "100.0" : 0.04761406129746459 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04761406129746459, + 0.047498459840597335, + 0.04745361069115239 + ], + [ + 0.04661251135701534, + 0.04659337120852087, + 0.04662590289822637 + ], + [ + 0.04715433838979215, + 0.0470886511903865, + 0.04703951677877605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9419445.041771932, + "scoreError" : 538928.2168990934, + "scoreConfidence" : [ + 8880516.824872838, + 9958373.258671025 + ], + "scorePercentiles" : { + "0.0" : 8965759.088709677, + "50.0" : 9617590.397115385, + "90.0" : 9653816.620656371, + "95.0" : 9653816.620656371, + "99.0" : 9653816.620656371, + "99.9" : 9653816.620656371, + "99.99" : 9653816.620656371, + "99.999" : 9653816.620656371, + "99.9999" : 9653816.620656371, + "100.0" : 9653816.620656371 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9637883.496146435, + 9632204.286814244, + 9644302.040501447 + ], + [ + 8965759.088709677, + 8998299.294964029, + 9013363.286486486 + ], + [ + 9611786.864553314, + 9617590.397115385, + 9653816.620656371 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-19T05:34:27Z-083fac7eaad2329f371f803324ff855b0de33531-jdk17.json b/performance-results/2025-04-19T05:34:27Z-083fac7eaad2329f371f803324ff855b0de33531-jdk17.json new file mode 100644 index 0000000000..f472d42a39 --- /dev/null +++ b/performance-results/2025-04-19T05:34:27Z-083fac7eaad2329f371f803324ff855b0de33531-jdk17.json @@ -0,0 +1,1369 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.425695994784005, + "scoreError" : 0.02533575657348106, + "scoreConfidence" : [ + 3.4003602382105242, + 3.451031751357486 + ], + "scorePercentiles" : { + "0.0" : 3.4229796381927127, + "50.0" : 3.4241541164161093, + "90.0" : 3.431496108111089, + "95.0" : 3.431496108111089, + "99.0" : 3.431496108111089, + "99.9" : 3.431496108111089, + "99.99" : 3.431496108111089, + "99.999" : 3.431496108111089, + "99.9999" : 3.431496108111089, + "100.0" : 3.431496108111089 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.42374069434408, + 3.431496108111089 + ], + [ + 3.4229796381927127, + 3.424567538488139 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7260263431013518, + "scoreError" : 0.0315413775222339, + "scoreConfidence" : [ + 1.6944849655791179, + 1.7575677206235858 + ], + "scorePercentiles" : { + "0.0" : 1.7217424651355324, + "50.0" : 1.725965478910251, + "90.0" : 1.730431949449373, + "95.0" : 1.730431949449373, + "99.0" : 1.730431949449373, + "99.9" : 1.730431949449373, + "99.99" : 1.730431949449373, + "99.999" : 1.730431949449373, + "99.9999" : 1.730431949449373, + "100.0" : 1.730431949449373 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7300707160484499, + 1.730431949449373 + ], + [ + 1.7217424651355324, + 1.7218602417720519 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8689685739892383, + "scoreError" : 0.0061142711214475075, + "scoreConfidence" : [ + 0.8628543028677909, + 0.8750828451106858 + ], + "scorePercentiles" : { + "0.0" : 0.8679429348532268, + "50.0" : 0.868874776741024, + "90.0" : 0.8701818076216785, + "95.0" : 0.8701818076216785, + "99.0" : 0.8701818076216785, + "99.9" : 0.8701818076216785, + "99.99" : 0.8701818076216785, + "99.999" : 0.8701818076216785, + "99.9999" : 0.8701818076216785, + "100.0" : 0.8701818076216785 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8679429348532268, + 0.8691434405541499 + ], + [ + 0.868606112927898, + 0.8701818076216785 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.359845932987152, + "scoreError" : 0.0698591863659578, + "scoreConfidence" : [ + 16.289986746621196, + 16.42970511935311 + ], + "scorePercentiles" : { + "0.0" : 16.302987991053268, + "50.0" : 16.364410028836858, + "90.0" : 16.417612299403828, + "95.0" : 16.417612299403828, + "99.0" : 16.417612299403828, + "99.9" : 16.417612299403828, + "99.99" : 16.417612299403828, + "99.999" : 16.417612299403828, + "99.9999" : 16.417612299403828, + "100.0" : 16.417612299403828 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.37636709039433, + 16.330509898167325, + 16.364410028836858 + ], + [ + 16.307341755305227, + 16.302987991053268, + 16.34226587416218 + ], + [ + 16.40294992882686, + 16.417612299403828, + 16.394168530734515 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2710.1847879168704, + "scoreError" : 134.47170833527892, + "scoreConfidence" : [ + 2575.7130795815915, + 2844.6564962521493 + ], + "scorePercentiles" : { + "0.0" : 2600.981395430096, + "50.0" : 2756.0561086739285, + "90.0" : 2772.9036698605455, + "95.0" : 2772.9036698605455, + "99.0" : 2772.9036698605455, + "99.9" : 2772.9036698605455, + "99.99" : 2772.9036698605455, + "99.999" : 2772.9036698605455, + "99.9999" : 2772.9036698605455, + "100.0" : 2772.9036698605455 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2756.0561086739285, + 2760.387417761637, + 2752.438612054852 + ], + [ + 2605.609079376698, + 2600.981395430096, + 2605.036796949673 + ], + [ + 2772.2172720957806, + 2766.032739048628, + 2772.9036698605455 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70686.15783859028, + "scoreError" : 1854.0323200444645, + "scoreConfidence" : [ + 68832.12551854581, + 72540.19015863475 + ], + "scorePercentiles" : { + "0.0" : 69256.73487929575, + "50.0" : 71018.86562775528, + "90.0" : 71802.3494796297, + "95.0" : 71802.3494796297, + "99.0" : 71802.3494796297, + "99.9" : 71802.3494796297, + "99.99" : 71802.3494796297, + "99.999" : 71802.3494796297, + "99.9999" : 71802.3494796297, + "100.0" : 71802.3494796297 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71033.27617737287, + 71018.86562775528, + 70967.16803059903 + ], + [ + 69271.37542125554, + 69320.9471582513, + 69256.73487929575 + ], + [ + 71749.31704870629, + 71802.3494796297, + 71755.38672444687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.33461436489677, + "scoreError" : 5.78738913969486, + "scoreConfidence" : [ + 350.5472252252019, + 362.12200350459165 + ], + "scorePercentiles" : { + "0.0" : 351.78326788618125, + "50.0" : 357.13038678791185, + "90.0" : 360.04158098522316, + "95.0" : 360.04158098522316, + "99.0" : 360.04158098522316, + "99.9" : 360.04158098522316, + "99.99" : 360.04158098522316, + "99.999" : 360.04158098522316, + "99.9999" : 360.04158098522316, + "100.0" : 360.04158098522316 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.04158098522316, + 359.88806121741237, + 359.60720411615296 + ], + [ + 356.75228370422525, + 357.13038678791185, + 357.4878282544236 + ], + [ + 351.92575348474327, + 351.78326788618125, + 352.39516284779717 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 109.28471290552234, + "scoreError" : 2.401014324630506, + "scoreConfidence" : [ + 106.88369858089183, + 111.68572723015285 + ], + "scorePercentiles" : { + "0.0" : 108.04428776254298, + "50.0" : 108.69769114147269, + "90.0" : 111.34526679775162, + "95.0" : 111.34526679775162, + "99.0" : 111.34526679775162, + "99.9" : 111.34526679775162, + "99.99" : 111.34526679775162, + "99.999" : 111.34526679775162, + "99.9999" : 111.34526679775162, + "100.0" : 111.34526679775162 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.04428776254298, + 108.04903264461714, + 108.06425230211276 + ], + [ + 108.53258332531895, + 108.71740764633286, + 108.69769114147269 + ], + [ + 110.94586845679417, + 111.16602607275799, + 111.34526679775162 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06154931090385804, + "scoreError" : 2.4225016982650936E-4, + "scoreConfidence" : [ + 0.061307060734031533, + 0.061791561073684546 + ], + "scorePercentiles" : { + "0.0" : 0.06135195244697755, + "50.0" : 0.06157969546288656, + "90.0" : 0.061753830654274866, + "95.0" : 0.061753830654274866, + "99.0" : 0.061753830654274866, + "99.9" : 0.061753830654274866, + "99.99" : 0.061753830654274866, + "99.999" : 0.061753830654274866, + "99.9999" : 0.061753830654274866, + "100.0" : 0.061753830654274866 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061753830654274866, + 0.0616728271332363, + 0.061684454477607335 + ], + [ + 0.06159813612368721, + 0.0615067294724023, + 0.06157969546288656 + ], + [ + 0.061374654269160896, + 0.06135195244697755, + 0.06142151809448935 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.760750908242404E-4, + "scoreError" : 8.434031411615685E-6, + "scoreConfidence" : [ + 3.676410594126247E-4, + 3.845091222358561E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7088353521284097E-4, + "50.0" : 3.739344159231379E-4, + "90.0" : 3.834190915539945E-4, + "95.0" : 3.834190915539945E-4, + "99.0" : 3.834190915539945E-4, + "99.9" : 3.834190915539945E-4, + "99.99" : 3.834190915539945E-4, + "99.999" : 3.834190915539945E-4, + "99.9999" : 3.834190915539945E-4, + "100.0" : 3.834190915539945E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.834190915539945E-4, + 3.8273148569289674E-4, + 3.814880285179107E-4 + ], + [ + 3.723592021830137E-4, + 3.7088353521284097E-4, + 3.715125941764848E-4 + ], + [ + 3.747160940030065E-4, + 3.739344159231379E-4, + 3.7363137015487764E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11046893352879489, + "scoreError" : 0.002138774241423794, + "scoreConfidence" : [ + 0.1083301592873711, + 0.11260770777021868 + ], + "scorePercentiles" : { + "0.0" : 0.1087234751244863, + "50.0" : 0.11118943017411995, + "90.0" : 0.11152621038955246, + "95.0" : 0.11152621038955246, + "99.0" : 0.11152621038955246, + "99.9" : 0.11152621038955246, + "99.99" : 0.11152621038955246, + "99.999" : 0.11152621038955246, + "99.9999" : 0.11152621038955246, + "100.0" : 0.11152621038955246 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11109712882583626, + 0.11118943017411995, + 0.11129137859464032 + ], + [ + 0.11152621038955246, + 0.1113868389489747, + 0.11138687892491562 + ], + [ + 0.10888735639155052, + 0.1087317043850779, + 0.1087234751244863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014165312701952966, + "scoreError" : 4.815072553459514E-4, + "scoreConfidence" : [ + 0.013683805446607014, + 0.014646819957298917 + ], + "scorePercentiles" : { + "0.0" : 0.01395668349404266, + "50.0" : 0.013989677564033513, + "90.0" : 0.014556064673285716, + "95.0" : 0.014556064673285716, + "99.0" : 0.014556064673285716, + "99.9" : 0.014556064673285716, + "99.99" : 0.014556064673285716, + "99.999" : 0.014556064673285716, + "99.9999" : 0.014556064673285716, + "100.0" : 0.014556064673285716 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014544858232877987, + 0.014539803734064579, + 0.014556064673285716 + ], + [ + 0.013964511364889982, + 0.01395668349404266, + 0.01395705616531657 + ], + [ + 0.013989677564033513, + 0.013992148289829927, + 0.013987010799235759 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9823763253227124, + "scoreError" : 0.01767823646629488, + "scoreConfidence" : [ + 0.9646980888564175, + 1.0000545617890073 + ], + "scorePercentiles" : { + "0.0" : 0.9698457434057409, + "50.0" : 0.9839505178079496, + "90.0" : 0.9975501751620948, + "95.0" : 0.9975501751620948, + "99.0" : 0.9975501751620948, + "99.9" : 0.9975501751620948, + "99.99" : 0.9975501751620948, + "99.999" : 0.9975501751620948, + "99.9999" : 0.9975501751620948, + "100.0" : 0.9975501751620948 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.994282262278783, + 0.9914581876672945, + 0.9975501751620948 + ], + [ + 0.9756333034146342, + 0.9839505178079496, + 0.9847643025110783 + ], + [ + 0.970755030188313, + 0.9698457434057409, + 0.973147405468522 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013320605587337516, + "scoreError" : 0.0010088284743755237, + "scoreConfidence" : [ + 0.012311777112961993, + 0.01432943406171304 + ], + "scorePercentiles" : { + "0.0" : 0.012983403693951952, + "50.0" : 0.013313732498541665, + "90.0" : 0.013659499825162407, + "95.0" : 0.013659499825162407, + "99.0" : 0.013659499825162407, + "99.9" : 0.013659499825162407, + "99.99" : 0.013659499825162407, + "99.999" : 0.013659499825162407, + "99.9999" : 0.013659499825162407, + "100.0" : 0.013659499825162407 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012983403693951952, + 0.012996723417749486, + 0.012996930223672069 + ], + [ + 0.013656541590077922, + 0.013659499825162407, + 0.013630534773411262 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.763223985833615, + "scoreError" : 0.05379514057442273, + "scoreConfidence" : [ + 3.7094288452591924, + 3.817019126408038 + ], + "scorePercentiles" : { + "0.0" : 3.7410425190725505, + "50.0" : 3.764923808580922, + "90.0" : 3.782251360816944, + "95.0" : 3.782251360816944, + "99.0" : 3.782251360816944, + "99.9" : 3.782251360816944, + "99.99" : 3.782251360816944, + "99.999" : 3.782251360816944, + "99.9999" : 3.782251360816944, + "100.0" : 3.782251360816944 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7807019969765685, + 3.7783525196374623, + 3.782251360816944 + ], + [ + 3.7410425190725505, + 3.7514950975243813, + 3.7455004209737828 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7888884488701353, + "scoreError" : 0.02867098420555031, + "scoreConfidence" : [ + 2.760217464664585, + 2.8175594330756857 + ], + "scorePercentiles" : { + "0.0" : 2.765524676438053, + "50.0" : 2.7872077915273135, + "90.0" : 2.8127805618672665, + "95.0" : 2.8127805618672665, + "99.0" : 2.8127805618672665, + "99.9" : 2.8127805618672665, + "99.99" : 2.8127805618672665, + "99.999" : 2.8127805618672665, + "99.9999" : 2.8127805618672665, + "100.0" : 2.8127805618672665 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8127805618672665, + 2.8065891492704824, + 2.8076440741156654 + ], + [ + 2.775067, + 2.765524676438053, + 2.770210220221607 + ], + [ + 2.787901388346808, + 2.7872077915273135, + 2.7870711780440236 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17765917554060356, + "scoreError" : 0.005312054418488953, + "scoreConfidence" : [ + 0.17234712112211462, + 0.1829712299590925 + ], + "scorePercentiles" : { + "0.0" : 0.1740636555499469, + "50.0" : 0.17742501951634937, + "90.0" : 0.18146718631026912, + "95.0" : 0.18146718631026912, + "99.0" : 0.18146718631026912, + "99.9" : 0.18146718631026912, + "99.99" : 0.18146718631026912, + "99.999" : 0.18146718631026912, + "99.9999" : 0.18146718631026912, + "100.0" : 0.18146718631026912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1741679257711131, + 0.17417738748388895, + 0.1740636555499469 + ], + [ + 0.18146718631026912, + 0.18141467578550177, + 0.18138980384901415 + ], + [ + 0.17745831782367974, + 0.1773686077756691, + 0.17742501951634937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32944903027998373, + "scoreError" : 0.004751421529257433, + "scoreConfidence" : [ + 0.3246976087507263, + 0.3342004518092412 + ], + "scorePercentiles" : { + "0.0" : 0.32573183821373897, + "50.0" : 0.33055895398803425, + "90.0" : 0.33357614773674904, + "95.0" : 0.33357614773674904, + "99.0" : 0.33357614773674904, + "99.9" : 0.33357614773674904, + "99.99" : 0.33357614773674904, + "99.999" : 0.33357614773674904, + "99.9999" : 0.33357614773674904, + "100.0" : 0.33357614773674904 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3260747078809221, + 0.32573183821373897, + 0.32594461376747824 + ], + [ + 0.33357614773674904, + 0.331354836713055, + 0.3311566846479899 + ], + [ + 0.3300601760512245, + 0.33058331352066117, + 0.33055895398803425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15864893604010794, + "scoreError" : 0.00518664053330179, + "scoreConfidence" : [ + 0.15346229550680615, + 0.16383557657340972 + ], + "scorePercentiles" : { + "0.0" : 0.15606451216505143, + "50.0" : 0.1568420326537014, + "90.0" : 0.16277467318835862, + "95.0" : 0.16277467318835862, + "99.0" : 0.16277467318835862, + "99.9" : 0.16277467318835862, + "99.99" : 0.16277467318835862, + "99.999" : 0.16277467318835862, + "99.9999" : 0.16277467318835862, + "100.0" : 0.16277467318835862 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16272160386292633, + 0.162739456101808, + 0.16277467318835862 + ], + [ + 0.15669222058570062, + 0.15606451216505143, + 0.156202886037394 + ], + [ + 0.15696292820706, + 0.1568420326537014, + 0.15684011155897115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3900080156242898, + "scoreError" : 0.00300343548489861, + "scoreConfidence" : [ + 0.3870045801393912, + 0.39301145110918845 + ], + "scorePercentiles" : { + "0.0" : 0.38657571626270826, + "50.0" : 0.3902557004487805, + "90.0" : 0.3923050295006081, + "95.0" : 0.3923050295006081, + "99.0" : 0.3923050295006081, + "99.9" : 0.3923050295006081, + "99.99" : 0.3923050295006081, + "99.999" : 0.3923050295006081, + "99.9999" : 0.3923050295006081, + "100.0" : 0.3923050295006081 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3902557004487805, + 0.3905326066309993, + 0.3898382468813348 + ], + [ + 0.3923050295006081, + 0.3915571262725137, + 0.39138963590466125 + ], + [ + 0.38949802442064263, + 0.38812005429635954, + 0.38657571626270826 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1567267156588646, + "scoreError" : 0.0025937601932065494, + "scoreConfidence" : [ + 0.15413295546565803, + 0.15932047585207115 + ], + "scorePercentiles" : { + "0.0" : 0.15462258207962892, + "50.0" : 0.15760147088396137, + "90.0" : 0.15837979365230198, + "95.0" : 0.15837979365230198, + "99.0" : 0.15837979365230198, + "99.9" : 0.15837979365230198, + "99.99" : 0.15837979365230198, + "99.999" : 0.15837979365230198, + "99.9999" : 0.15837979365230198, + "100.0" : 0.15837979365230198 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15837979365230198, + 0.157548456312821, + 0.15764174156630303 + ], + [ + 0.15760147088396137, + 0.15767686564599034, + 0.15760258934312552 + ], + [ + 0.15462258207962892, + 0.15478591770241615, + 0.15468102374323278 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04642022671263654, + "scoreError" : 0.001413288794817226, + "scoreConfidence" : [ + 0.04500693791781932, + 0.04783351550745377 + ], + "scorePercentiles" : { + "0.0" : 0.04545278462538407, + "50.0" : 0.04642856185117091, + "90.0" : 0.04747142907394045, + "95.0" : 0.04747142907394045, + "99.0" : 0.04747142907394045, + "99.9" : 0.04747142907394045, + "99.99" : 0.04747142907394045, + "99.999" : 0.04747142907394045, + "99.9999" : 0.04747142907394045, + "100.0" : 0.04747142907394045 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04649789863576762, + 0.04642856185117091, + 0.046217081045232075 + ], + [ + 0.04741952635771764, + 0.04747142907394045, + 0.04732541950062942 + ], + [ + 0.045514183351159455, + 0.04545278462538407, + 0.04545515597272727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9318725.38196741, + "scoreError" : 403232.20389907574, + "scoreConfidence" : [ + 8915493.178068334, + 9721957.585866487 + ], + "scorePercentiles" : { + "0.0" : 9141357.023765996, + "50.0" : 9185854.114784205, + "90.0" : 9641518.673410404, + "95.0" : 9641518.673410404, + "99.0" : 9641518.673410404, + "99.9" : 9641518.673410404, + "99.99" : 9641518.673410404, + "99.999" : 9641518.673410404, + "99.9999" : 9641518.673410404, + "100.0" : 9641518.673410404 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9152496.51601098, + 9147746.644424131, + 9141477.754113346 + ], + [ + 9141357.023765996, + 9185854.114784205, + 9185952.093663912 + ], + [ + 9638040.732177263, + 9641518.673410404, + 9634084.885356454 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-22T04:30:19Z-272f8fadca51f8aa3326d5c4b0ac084a5edb47bb-jdk17.json b/performance-results/2025-04-22T04:30:19Z-272f8fadca51f8aa3326d5c4b0ac084a5edb47bb-jdk17.json new file mode 100644 index 0000000000..9240866ff9 --- /dev/null +++ b/performance-results/2025-04-22T04:30:19Z-272f8fadca51f8aa3326d5c4b0ac084a5edb47bb-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4127115413457414, + "scoreError" : 0.023818295936563618, + "scoreConfidence" : [ + 3.388893245409178, + 3.436529837282305 + ], + "scorePercentiles" : { + "0.0" : 3.408790910367565, + "50.0" : 3.4124267197828493, + "90.0" : 3.4172018154497006, + "95.0" : 3.4172018154497006, + "99.0" : 3.4172018154497006, + "99.9" : 3.4172018154497006, + "99.99" : 3.4172018154497006, + "99.999" : 3.4172018154497006, + "99.9999" : 3.4172018154497006, + "100.0" : 3.4172018154497006 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.408790910367565, + 3.410835872457578 + ], + [ + 3.414017567108121, + 3.4172018154497006 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7228743985302142, + "scoreError" : 0.005018255154910196, + "scoreConfidence" : [ + 1.717856143375304, + 1.7278926536851245 + ], + "scorePercentiles" : { + "0.0" : 1.7220239373364237, + "50.0" : 1.7228187182758958, + "90.0" : 1.7238362202326416, + "95.0" : 1.7238362202326416, + "99.0" : 1.7238362202326416, + "99.9" : 1.7238362202326416, + "99.99" : 1.7238362202326416, + "99.999" : 1.7238362202326416, + "99.9999" : 1.7238362202326416, + "100.0" : 1.7238362202326416 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7220239373364237, + 1.723096788586162 + ], + [ + 1.7238362202326416, + 1.7225406479656293 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8667147624809695, + "scoreError" : 0.007094090320634176, + "scoreConfidence" : [ + 0.8596206721603353, + 0.8738088528016036 + ], + "scorePercentiles" : { + "0.0" : 0.8654674214767059, + "50.0" : 0.8667706679878056, + "90.0" : 0.8678502924715609, + "95.0" : 0.8678502924715609, + "99.0" : 0.8678502924715609, + "99.9" : 0.8678502924715609, + "99.99" : 0.8678502924715609, + "99.999" : 0.8678502924715609, + "99.9999" : 0.8678502924715609, + "100.0" : 0.8678502924715609 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8654674214767059, + 0.8673887604015584 + ], + [ + 0.8678502924715609, + 0.8661525755740527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.192109290783293, + "scoreError" : 0.029219959554604866, + "scoreConfidence" : [ + 16.162889331228687, + 16.2213292503379 + ], + "scorePercentiles" : { + "0.0" : 16.170071132047212, + "50.0" : 16.18990550904613, + "90.0" : 16.22348455699213, + "95.0" : 16.22348455699213, + "99.0" : 16.22348455699213, + "99.9" : 16.22348455699213, + "99.99" : 16.22348455699213, + "99.999" : 16.22348455699213, + "99.9999" : 16.22348455699213, + "100.0" : 16.22348455699213 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.179157183208993, + 16.178505581937568, + 16.18990550904613 + ], + [ + 16.17867011044498, + 16.20076627069513, + 16.170071132047212 + ], + [ + 16.208825806640007, + 16.22348455699213, + 16.19959746603748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2654.4173184945766, + "scoreError" : 101.70228326464833, + "scoreConfidence" : [ + 2552.715035229928, + 2756.119601759225 + ], + "scorePercentiles" : { + "0.0" : 2599.0909153926536, + "50.0" : 2629.737511851428, + "90.0" : 2738.03030561129, + "95.0" : 2738.03030561129, + "99.0" : 2738.03030561129, + "99.9" : 2738.03030561129, + "99.99" : 2738.03030561129, + "99.999" : 2738.03030561129, + "99.9999" : 2738.03030561129, + "100.0" : 2738.03030561129 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2729.882343923157, + 2738.03030561129, + 2731.9303767336796 + ], + [ + 2602.253096689208, + 2599.9235622130914, + 2599.0909153926536 + ], + [ + 2629.737511851428, + 2630.233123802959, + 2628.6746302337274 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70219.08143066481, + "scoreError" : 987.728204101295, + "scoreConfidence" : [ + 69231.35322656351, + 71206.8096347661 + ], + "scorePercentiles" : { + "0.0" : 69608.82393814632, + "50.0" : 70088.63572548059, + "90.0" : 70980.20391041573, + "95.0" : 70980.20391041573, + "99.0" : 70980.20391041573, + "99.9" : 70980.20391041573, + "99.99" : 70980.20391041573, + "99.999" : 70980.20391041573, + "99.9999" : 70980.20391041573, + "100.0" : 70980.20391041573 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69608.82393814632, + 69616.85239393705, + 69628.7048603332 + ], + [ + 70071.59074403135, + 70088.63572548059, + 70093.0590445055 + ], + [ + 70980.20391041573, + 70967.16474502598, + 70916.69751410744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.94577240181684, + "scoreError" : 10.389346561589953, + "scoreConfidence" : [ + 339.5564258402269, + 360.3351189634068 + ], + "scorePercentiles" : { + "0.0" : 343.3319309427049, + "50.0" : 347.31376539572716, + "90.0" : 358.0092489157099, + "95.0" : 358.0092489157099, + "99.0" : 358.0092489157099, + "99.9" : 358.0092489157099, + "99.99" : 358.0092489157099, + "99.999" : 358.0092489157099, + "99.9999" : 358.0092489157099, + "100.0" : 358.0092489157099 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 357.2327291475415, + 358.0092489157099, + 357.2593295621967 + ], + [ + 343.3319309427049, + 343.86619461756703, + 343.8160191897183 + ], + [ + 351.37190138637834, + 347.310832458807, + 347.31376539572716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.15871691567798063, + "scoreError" : 0.039717514509502, + "scoreConfidence" : [ + 0.11899940116847862, + 0.19843443018748264 + ], + "scorePercentiles" : { + "0.0" : 0.15144481893500517, + "50.0" : 0.15861564702880188, + "90.0" : 0.16619154971931357, + "95.0" : 0.16619154971931357, + "99.0" : 0.16619154971931357, + "99.9" : 0.16619154971931357, + "99.99" : 0.16619154971931357, + "99.999" : 0.16619154971931357, + "99.9999" : 0.16619154971931357, + "100.0" : 0.16619154971931357 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16619154971931357, + 0.1571060051654021 + ], + [ + 0.16012528889220165, + 0.15144481893500517 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.83195258245355, + "scoreError" : 1.5297666776815844, + "scoreConfidence" : [ + 105.30218590477197, + 108.36171926013513 + ], + "scorePercentiles" : { + "0.0" : 105.70656874396997, + "50.0" : 106.69773666359124, + "90.0" : 108.19688907976642, + "95.0" : 108.19688907976642, + "99.0" : 108.19688907976642, + "99.9" : 108.19688907976642, + "99.99" : 108.19688907976642, + "99.999" : 108.19688907976642, + "99.9999" : 108.19688907976642, + "100.0" : 108.19688907976642 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.60491662295091, + 105.70656874396997, + 105.78420489491664 + ], + [ + 108.19688907976642, + 107.78126928600777, + 107.74017180717735 + ], + [ + 106.05774927594952, + 106.69773666359124, + 106.9180668677521 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061996559058925996, + "scoreError" : 5.70134993193192E-4, + "scoreConfidence" : [ + 0.0614264240657328, + 0.06256669405211919 + ], + "scorePercentiles" : { + "0.0" : 0.06173059760117534, + "50.0" : 0.06180828258948162, + "90.0" : 0.06250642418086583, + "95.0" : 0.06250642418086583, + "99.0" : 0.06250642418086583, + "99.9" : 0.06250642418086583, + "99.99" : 0.06250642418086583, + "99.999" : 0.06250642418086583, + "99.9999" : 0.06250642418086583, + "100.0" : 0.06250642418086583 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06173059760117534, + 0.061750593958405375, + 0.061764083769277806 + ], + [ + 0.06246450702404228, + 0.06250642418086583, + 0.06236390625565166 + ], + [ + 0.06181479267011176, + 0.06180828258948162, + 0.06176584348132227 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7574223862614606E-4, + "scoreError" : 9.741797174160208E-6, + "scoreConfidence" : [ + 3.6600044145198587E-4, + 3.8548403580030625E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6863659880709076E-4, + "50.0" : 3.7536581726309645E-4, + "90.0" : 3.833523489446626E-4, + "95.0" : 3.833523489446626E-4, + "99.0" : 3.833523489446626E-4, + "99.9" : 3.833523489446626E-4, + "99.99" : 3.833523489446626E-4, + "99.999" : 3.833523489446626E-4, + "99.9999" : 3.833523489446626E-4, + "100.0" : 3.833523489446626E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.748514555148026E-4, + 3.7536581726309645E-4, + 3.7537262840412156E-4 + ], + [ + 3.6944403588529405E-4, + 3.7002040020112586E-4, + 3.6863659880709076E-4 + ], + [ + 3.8281033084065525E-4, + 3.833523489446626E-4, + 3.818265317744651E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10975899074937023, + "scoreError" : 0.0029354055865175844, + "scoreConfidence" : [ + 0.10682358516285265, + 0.11269439633588782 + ], + "scorePercentiles" : { + "0.0" : 0.1083622634772715, + "50.0" : 0.10877326216063349, + "90.0" : 0.11213652715325356, + "95.0" : 0.11213652715325356, + "99.0" : 0.11213652715325356, + "99.9" : 0.11213652715325356, + "99.99" : 0.11213652715325356, + "99.999" : 0.11213652715325356, + "99.9999" : 0.11213652715325356, + "100.0" : 0.11213652715325356 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1087198346832498, + 0.10878003503752856, + 0.10877326216063349 + ], + [ + 0.1083622634772715, + 0.1084530513626948, + 0.10850256368469592 + ], + [ + 0.11213652715325356, + 0.11206634563058923, + 0.11203703355441529 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014128055259110726, + "scoreError" : 8.087257104102246E-5, + "scoreConfidence" : [ + 0.014047182688069704, + 0.014208927830151749 + ], + "scorePercentiles" : { + "0.0" : 0.014082055788219656, + "50.0" : 0.014105600604277336, + "90.0" : 0.014195984732401804, + "95.0" : 0.014195984732401804, + "99.0" : 0.014195984732401804, + "99.9" : 0.014195984732401804, + "99.99" : 0.014195984732401804, + "99.999" : 0.014195984732401804, + "99.9999" : 0.014195984732401804, + "100.0" : 0.014195984732401804 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014105600604277336, + 0.0141184486546699, + 0.014094073317858235 + ], + [ + 0.014189013595751292, + 0.014186639476405773, + 0.014195984732401804 + ], + [ + 0.014085124585726017, + 0.014082055788219656, + 0.014095556576686546 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9970342546788632, + "scoreError" : 0.031274882559950624, + "scoreConfidence" : [ + 0.9657593721189126, + 1.0283091372388138 + ], + "scorePercentiles" : { + "0.0" : 0.9785777445205479, + "50.0" : 0.9917853927402559, + "90.0" : 1.0242761747234739, + "95.0" : 1.0242761747234739, + "99.0" : 1.0242761747234739, + "99.9" : 1.0242761747234739, + "99.99" : 1.0242761747234739, + "99.999" : 1.0242761747234739, + "99.9999" : 1.0242761747234739, + "100.0" : 1.0242761747234739 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9865097576205978, + 0.9917853927402559, + 0.9932157909424968 + ], + [ + 0.9813429997056226, + 0.9785777445205479, + 0.9793452711515863 + ], + [ + 1.0242761747234739, + 1.0191551771119942, + 1.0190999835931926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012983314972046862, + "scoreError" : 3.730340218479375E-4, + "scoreConfidence" : [ + 0.012610280950198925, + 0.0133563489938948 + ], + "scorePercentiles" : { + "0.0" : 0.01287018607787822, + "50.0" : 0.012931144468737782, + "90.0" : 0.013147369393458959, + "95.0" : 0.013147369393458959, + "99.0" : 0.013147369393458959, + "99.9" : 0.013147369393458959, + "99.99" : 0.013147369393458959, + "99.999" : 0.013147369393458959, + "99.9999" : 0.013147369393458959, + "100.0" : 0.013147369393458959 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012985828812216754, + 0.013147369393458959, + 0.01314403526458295 + ], + [ + 0.01287018607787822, + 0.01287646012525881, + 0.012876010158885483 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6827545858911104, + "scoreError" : 0.07051273227895546, + "scoreConfidence" : [ + 3.6122418536121548, + 3.753267318170066 + ], + "scorePercentiles" : { + "0.0" : 3.65348649963477, + "50.0" : 3.688918918141593, + "90.0" : 3.7191890639405205, + "95.0" : 3.7191890639405205, + "99.0" : 3.7191890639405205, + "99.9" : 3.7191890639405205, + "99.99" : 3.7191890639405205, + "99.999" : 3.7191890639405205, + "99.9999" : 3.7191890639405205, + "100.0" : 3.7191890639405205 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.65348649963477, + 3.7191890639405205, + 3.6892335759587023 + ], + [ + 3.6541501081081083, + 3.6918640073800737, + 3.688604260324484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8694381513107627, + "scoreError" : 0.023123051355761273, + "scoreConfidence" : [ + 2.8463150999550013, + 2.892561202666524 + ], + "scorePercentiles" : { + "0.0" : 2.852911375641757, + "50.0" : 2.8660179925501432, + "90.0" : 2.8887154581166956, + "95.0" : 2.8887154581166956, + "99.0" : 2.8887154581166956, + "99.9" : 2.8887154581166956, + "99.99" : 2.8887154581166956, + "99.999" : 2.8887154581166956, + "99.9999" : 2.8887154581166956, + "100.0" : 2.8887154581166956 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.864341072737686, + 2.8660179925501432, + 2.867773817373853 + ], + [ + 2.8834204978379936, + 2.8887154581166956, + 2.887454 + ], + [ + 2.852911375641757, + 2.8551937819012276, + 2.859115365637507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.70391768075, + "scoreError" : 1.8962065515193804, + "scoreConfidence" : [ + 4.807711129230619, + 8.60012423226938 + ], + "scorePercentiles" : { + "0.0" : 6.3129306365, + "50.0" : 6.7690040645, + "90.0" : 6.9647319575, + "95.0" : 6.9647319575, + "99.0" : 6.9647319575, + "99.9" : 6.9647319575, + "99.99" : 6.9647319575, + "99.999" : 6.9647319575, + "99.9999" : 6.9647319575, + "100.0" : 6.9647319575 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.3129306365, + 6.648684114 + ], + [ + 6.9647319575, + 6.889324015 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17754228237968872, + "scoreError" : 0.008502560694812967, + "scoreConfidence" : [ + 0.16903972168487574, + 0.1860448430745017 + ], + "scorePercentiles" : { + "0.0" : 0.17062550560494122, + "50.0" : 0.17872643084374384, + "90.0" : 0.1828380300215746, + "95.0" : 0.1828380300215746, + "99.0" : 0.1828380300215746, + "99.9" : 0.1828380300215746, + "99.99" : 0.1828380300215746, + "99.999" : 0.1828380300215746, + "99.9999" : 0.1828380300215746, + "100.0" : 0.1828380300215746 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1719386091778137, + 0.17092676679314942, + 0.17062550560494122 + ], + [ + 0.17949860819931074, + 0.17848043631982866, + 0.17872643084374384 + ], + [ + 0.1828380300215746, + 0.182442258004488, + 0.1824038964523484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32224014139830565, + "scoreError" : 0.004596910300809624, + "scoreConfidence" : [ + 0.31764323109749604, + 0.32683705169911526 + ], + "scorePercentiles" : { + "0.0" : 0.3191069485927628, + "50.0" : 0.32138266718087155, + "90.0" : 0.3259481202372804, + "95.0" : 0.3259481202372804, + "99.0" : 0.3259481202372804, + "99.9" : 0.3259481202372804, + "99.99" : 0.3259481202372804, + "99.999" : 0.3259481202372804, + "99.9999" : 0.3259481202372804, + "100.0" : 0.3259481202372804 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3259481202372804, + 0.32543529490058254, + 0.3256288955097522 + ], + [ + 0.3213605381921013, + 0.32138266718087155, + 0.3217476355007883 + ], + [ + 0.32037035928239627, + 0.3191069485927628, + 0.3191808131882161 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15612223042893858, + "scoreError" : 0.005980633317742678, + "scoreConfidence" : [ + 0.1501415971111959, + 0.16210286374668126 + ], + "scorePercentiles" : { + "0.0" : 0.1530403684556877, + "50.0" : 0.15430316457590768, + "90.0" : 0.16088386566491844, + "95.0" : 0.16088386566491844, + "99.0" : 0.16088386566491844, + "99.9" : 0.16088386566491844, + "99.99" : 0.16088386566491844, + "99.999" : 0.16088386566491844, + "99.9999" : 0.16088386566491844, + "100.0" : 0.16088386566491844 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1533851910363974, + 0.15304628414012642, + 0.1530403684556877 + ], + [ + 0.15468841272738523, + 0.15430316457590768, + 0.15421340170557937 + ], + [ + 0.16088386566491844, + 0.16078554757540678, + 0.16075383797903806 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.393413232056684, + "scoreError" : 0.004527827006908674, + "scoreConfidence" : [ + 0.3888854050497753, + 0.3979410590635927 + ], + "scorePercentiles" : { + "0.0" : 0.3902681086091164, + "50.0" : 0.39370936917322835, + "90.0" : 0.39860254930644134, + "95.0" : 0.39860254930644134, + "99.0" : 0.39860254930644134, + "99.9" : 0.39860254930644134, + "99.99" : 0.39860254930644134, + "99.999" : 0.39860254930644134, + "99.9999" : 0.39860254930644134, + "100.0" : 0.39860254930644134 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39465405726350683, + 0.3911542951185168, + 0.3902681086091164 + ], + [ + 0.39860254930644134, + 0.39370936917322835, + 0.3938205744102706 + ], + [ + 0.39575615493292177, + 0.3919160631760464, + 0.39083791652010785 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15501029522453952, + "scoreError" : 0.0021873575353937, + "scoreConfidence" : [ + 0.15282293768914582, + 0.15719765275993322 + ], + "scorePercentiles" : { + "0.0" : 0.1536603057160418, + "50.0" : 0.15459063514098442, + "90.0" : 0.15703186355856352, + "95.0" : 0.15703186355856352, + "99.0" : 0.15703186355856352, + "99.9" : 0.15703186355856352, + "99.99" : 0.15703186355856352, + "99.999" : 0.15703186355856352, + "99.9999" : 0.15703186355856352, + "100.0" : 0.15703186355856352 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1548037081688571, + 0.15456499871713628, + 0.15459063514098442 + ], + [ + 0.1536603057160418, + 0.15379269200602855, + 0.15377065729706457 + ], + [ + 0.15703186355856352, + 0.15669110261512667, + 0.15618669380105268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04687822373703285, + "scoreError" : 9.797440939483914E-4, + "scoreConfidence" : [ + 0.04589847964308446, + 0.047857967830981236 + ], + "scorePercentiles" : { + "0.0" : 0.04621952806869968, + "50.0" : 0.046888065520426486, + "90.0" : 0.04793403680305238, + "95.0" : 0.04793403680305238, + "99.0" : 0.04793403680305238, + "99.9" : 0.04793403680305238, + "99.99" : 0.04793403680305238, + "99.999" : 0.04793403680305238, + "99.9999" : 0.04793403680305238, + "100.0" : 0.04793403680305238 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047467820237145894, + 0.047150842778267615, + 0.04670665154947339 + ], + [ + 0.04621952806869968, + 0.0462897520853199, + 0.046274813399166136 + ], + [ + 0.04793403680305238, + 0.04697250319174421, + 0.046888065520426486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9477655.523819288, + "scoreError" : 544059.9695304473, + "scoreConfidence" : [ + 8933595.554288842, + 1.0021715493349735E7 + ], + "scorePercentiles" : { + "0.0" : 9034804.157181572, + "50.0" : 9626351.183830606, + "90.0" : 9762268.607804878, + "95.0" : 9762268.607804878, + "99.0" : 9762268.607804878, + "99.9" : 9762268.607804878, + "99.99" : 9762268.607804878, + "99.999" : 9762268.607804878, + "99.9999" : 9762268.607804878, + "100.0" : 9762268.607804878 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9618111.770192308, + 9640038.421001926, + 9626351.183830606 + ], + [ + 9088065.289736602, + 9034804.157181572, + 9034914.014453478 + ], + [ + 9738151.803310614, + 9762268.607804878, + 9756194.466861598 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-22T04:32:54Z-272f8fadca51f8aa3326d5c4b0ac084a5edb47bb-jdk17.json b/performance-results/2025-04-22T04:32:54Z-272f8fadca51f8aa3326d5c4b0ac084a5edb47bb-jdk17.json new file mode 100644 index 0000000000..ef100b3a44 --- /dev/null +++ b/performance-results/2025-04-22T04:32:54Z-272f8fadca51f8aa3326d5c4b0ac084a5edb47bb-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.411508827731021, + "scoreError" : 0.030213327558698464, + "scoreConfidence" : [ + 3.3812955001723224, + 3.4417221552897197 + ], + "scorePercentiles" : { + "0.0" : 3.4061824009040715, + "50.0" : 3.4112169971781476, + "90.0" : 3.4174189156637165, + "95.0" : 3.4174189156637165, + "99.0" : 3.4174189156637165, + "99.9" : 3.4174189156637165, + "99.99" : 3.4174189156637165, + "99.999" : 3.4174189156637165, + "99.9999" : 3.4174189156637165, + "100.0" : 3.4174189156637165 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4101894039519682, + 3.412244590404327 + ], + [ + 3.4061824009040715, + 3.4174189156637165 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.720005413136225, + "scoreError" : 0.034745361123641065, + "scoreConfidence" : [ + 1.685260052012584, + 1.754750774259866 + ], + "scorePercentiles" : { + "0.0" : 1.7143138577681474, + "50.0" : 1.7204895506884859, + "90.0" : 1.7247286933997816, + "95.0" : 1.7247286933997816, + "99.0" : 1.7247286933997816, + "99.9" : 1.7247286933997816, + "99.99" : 1.7247286933997816, + "99.999" : 1.7247286933997816, + "99.9999" : 1.7247286933997816, + "100.0" : 1.7247286933997816 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7247286933997816, + 1.7244619969213304 + ], + [ + 1.7143138577681474, + 1.7165171044556413 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.866975573429833, + "scoreError" : 0.0020841011913773967, + "scoreConfidence" : [ + 0.8648914722384556, + 0.8690596746212104 + ], + "scorePercentiles" : { + "0.0" : 0.8666430380743453, + "50.0" : 0.8669698187580581, + "90.0" : 0.8673196181288707, + "95.0" : 0.8673196181288707, + "99.0" : 0.8673196181288707, + "99.9" : 0.8673196181288707, + "99.99" : 0.8673196181288707, + "99.999" : 0.8673196181288707, + "99.9999" : 0.8673196181288707, + "100.0" : 0.8673196181288707 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.867173581893368, + 0.8666430380743453 + ], + [ + 0.8667660556227481, + 0.8673196181288707 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.856005974922722, + "scoreError" : 0.26661275625263864, + "scoreConfidence" : [ + 15.589393218670082, + 16.12261873117536 + ], + "scorePercentiles" : { + "0.0" : 15.598142992517541, + "50.0" : 15.919151747196164, + "90.0" : 16.065181238820553, + "95.0" : 16.065181238820553, + "99.0" : 16.065181238820553, + "99.9" : 16.065181238820553, + "99.99" : 16.065181238820553, + "99.999" : 16.065181238820553, + "99.9999" : 16.065181238820553, + "100.0" : 16.065181238820553 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.598142992517541, + 15.66755920214911, + 15.739502107240005 + ], + [ + 15.919151747196164, + 16.065181238820553, + 15.98829123768365 + ], + [ + 15.822472744988458, + 15.97478762638086, + 15.928964877328136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2579.106020769643, + "scoreError" : 67.64773074522886, + "scoreConfidence" : [ + 2511.458290024414, + 2646.7537515148715 + ], + "scorePercentiles" : { + "0.0" : 2500.548553474408, + "50.0" : 2564.2726183742325, + "90.0" : 2627.6694932706714, + "95.0" : 2627.6694932706714, + "99.0" : 2627.6694932706714, + "99.9" : 2627.6694932706714, + "99.99" : 2627.6694932706714, + "99.999" : 2627.6694932706714, + "99.9999" : 2627.6694932706714, + "100.0" : 2627.6694932706714 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2561.3449801962197, + 2627.6694932706714, + 2618.0060817274602 + ], + [ + 2500.548553474408, + 2564.2726183742325, + 2558.7182958058543 + ], + [ + 2564.232249758729, + 2610.9890352278353, + 2606.1728790913776 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69703.31262097623, + "scoreError" : 1447.445227023106, + "scoreConfidence" : [ + 68255.86739395311, + 71150.75784799934 + ], + "scorePercentiles" : { + "0.0" : 68231.38188526178, + "50.0" : 69880.69550620578, + "90.0" : 70764.91160314676, + "95.0" : 70764.91160314676, + "99.0" : 70764.91160314676, + "99.9" : 70764.91160314676, + "99.99" : 70764.91160314676, + "99.999" : 70764.91160314676, + "99.9999" : 70764.91160314676, + "100.0" : 70764.91160314676 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68231.38188526178, + 68911.39555593283, + 68864.67850636363 + ], + [ + 69880.69550620578, + 70553.9506376975, + 70764.91160314676 + ], + [ + 69676.77202395037, + 70310.94869612648, + 70135.07917410089 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 345.5745863682407, + "scoreError" : 11.564283964888611, + "scoreConfidence" : [ + 334.0103024033521, + 357.1388703331293 + ], + "scorePercentiles" : { + "0.0" : 334.2841358777637, + "50.0" : 346.53244419306947, + "90.0" : 356.34001906629067, + "95.0" : 356.34001906629067, + "99.0" : 356.34001906629067, + "99.9" : 356.34001906629067, + "99.99" : 356.34001906629067, + "99.999" : 356.34001906629067, + "99.9999" : 356.34001906629067, + "100.0" : 356.34001906629067 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.84768017790077, + 346.53244419306947, + 343.0863459525297 + ], + [ + 334.2841358777637, + 338.90512208767007, + 341.63052222490154 + ], + [ + 350.3248190676912, + 356.34001906629067, + 352.22018866634915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.15310942521226972, + "scoreError" : 0.03253727756821339, + "scoreConfidence" : [ + 0.12057214764405633, + 0.18564670278048312 + ], + "scorePercentiles" : { + "0.0" : 0.14717731435109477, + "50.0" : 0.1537725239575156, + "90.0" : 0.15771533858295295, + "95.0" : 0.15771533858295295, + "99.0" : 0.15771533858295295, + "99.9" : 0.15771533858295295, + "99.99" : 0.15771533858295295, + "99.999" : 0.15771533858295295, + "99.9999" : 0.15771533858295295, + "100.0" : 0.15771533858295295 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.15683645340401753, + 0.14717731435109477 + ], + [ + 0.15771533858295295, + 0.15070859451101365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.57680581481428, + "scoreError" : 3.272354582677361, + "scoreConfidence" : [ + 102.30445123213691, + 108.84916039749164 + ], + "scorePercentiles" : { + "0.0" : 102.24768818091964, + "50.0" : 106.5890315303227, + "90.0" : 107.5626320317188, + "95.0" : 107.5626320317188, + "99.0" : 107.5626320317188, + "99.9" : 107.5626320317188, + "99.99" : 107.5626320317188, + "99.999" : 107.5626320317188, + "99.9999" : 107.5626320317188, + "100.0" : 107.5626320317188 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.55943835700468, + 106.84147429173929, + 106.86030739066761 + ], + [ + 105.0767546261267, + 106.5890315303227, + 107.5626320317188 + ], + [ + 102.24768818091964, + 103.64327875935324, + 103.81064716547591 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06301105905670507, + "scoreError" : 6.387046483196352E-4, + "scoreConfidence" : [ + 0.06237235440838543, + 0.0636497637050247 + ], + "scorePercentiles" : { + "0.0" : 0.06242052996766663, + "50.0" : 0.06310440314886098, + "90.0" : 0.06351396995833546, + "95.0" : 0.06351396995833546, + "99.0" : 0.06351396995833546, + "99.9" : 0.06351396995833546, + "99.99" : 0.06351396995833546, + "99.999" : 0.06351396995833546, + "99.9999" : 0.06351396995833546, + "100.0" : 0.06351396995833546 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06297622236006852, + 0.06273290029358627, + 0.06322835851263602 + ], + [ + 0.06310440314886098, + 0.06351396995833546, + 0.06344674994765727 + ], + [ + 0.0625466905111863, + 0.06242052996766663, + 0.06312970681034809 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.735335691923649E-4, + "scoreError" : 1.6196603923288733E-5, + "scoreConfidence" : [ + 3.573369652690762E-4, + 3.897301731156536E-4 + ], + "scorePercentiles" : { + "0.0" : 3.614343273715042E-4, + "50.0" : 3.723071156880851E-4, + "90.0" : 3.8694067340423787E-4, + "95.0" : 3.8694067340423787E-4, + "99.0" : 3.8694067340423787E-4, + "99.9" : 3.8694067340423787E-4, + "99.99" : 3.8694067340423787E-4, + "99.999" : 3.8694067340423787E-4, + "99.9999" : 3.8694067340423787E-4, + "100.0" : 3.8694067340423787E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.723071156880851E-4, + 3.623620998277894E-4, + 3.748522363900488E-4 + ], + [ + 3.662285296046896E-4, + 3.614343273715042E-4, + 3.698457582756536E-4 + ], + [ + 3.821194029394492E-4, + 3.857119792298262E-4, + 3.8694067340423787E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11335710020511125, + "scoreError" : 0.0021026383922769253, + "scoreConfidence" : [ + 0.11125446181283433, + 0.11545973859738817 + ], + "scorePercentiles" : { + "0.0" : 0.11157325753941247, + "50.0" : 0.11371136744974074, + "90.0" : 0.11549547044556857, + "95.0" : 0.11549547044556857, + "99.0" : 0.11549547044556857, + "99.9" : 0.11549547044556857, + "99.99" : 0.11549547044556857, + "99.999" : 0.11549547044556857, + "99.9999" : 0.11549547044556857, + "100.0" : 0.11549547044556857 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11549547044556857, + 0.11357431645655877, + 0.11404134308750243 + ], + [ + 0.11371136744974074, + 0.11386642068227364, + 0.11390656537537161 + ], + [ + 0.11207797028859624, + 0.11196719052097678, + 0.11157325753941247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014587977259907502, + "scoreError" : 7.03320283756346E-4, + "scoreConfidence" : [ + 0.013884656976151155, + 0.015291297543663849 + ], + "scorePercentiles" : { + "0.0" : 0.014018041347117574, + "50.0" : 0.014854092140208905, + "90.0" : 0.014921084238907431, + "95.0" : 0.014921084238907431, + "99.0" : 0.014921084238907431, + "99.9" : 0.014921084238907431, + "99.99" : 0.014921084238907431, + "99.999" : 0.014921084238907431, + "99.9999" : 0.014921084238907431, + "100.0" : 0.014921084238907431 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014921084238907431, + 0.014868450753374349, + 0.014854092140208905 + ], + [ + 0.014866522735111349, + 0.014863613958528105, + 0.01482507056491664 + ], + [ + 0.014047071111011222, + 0.014027848489991963, + 0.014018041347117574 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9784612617260944, + "scoreError" : 0.014814361909358828, + "scoreConfidence" : [ + 0.9636468998167356, + 0.9932756236354532 + ], + "scorePercentiles" : { + "0.0" : 0.9603574932296168, + "50.0" : 0.9792126939195144, + "90.0" : 0.992761241909867, + "95.0" : 0.992761241909867, + "99.0" : 0.992761241909867, + "99.9" : 0.992761241909867, + "99.99" : 0.992761241909867, + "99.999" : 0.992761241909867, + "99.9999" : 0.992761241909867, + "100.0" : 0.992761241909867 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9762199439672004, + 0.9796988307210032, + 0.992761241909867 + ], + [ + 0.9729139751921393, + 0.9603574932296168, + 0.9820079668106835 + ], + [ + 0.9847064571681764, + 0.9782727526166487, + 0.9792126939195144 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.0132593199275848, + "scoreError" : 4.787815168122398E-4, + "scoreConfidence" : [ + 0.01278053841077256, + 0.013738101444397039 + ], + "scorePercentiles" : { + "0.0" : 0.013089428605460252, + "50.0" : 0.013258935765416199, + "90.0" : 0.013465418332969777, + "95.0" : 0.013465418332969777, + "99.0" : 0.013465418332969777, + "99.9" : 0.013465418332969777, + "99.99" : 0.013465418332969777, + "99.999" : 0.013465418332969777, + "99.9999" : 0.013465418332969777, + "100.0" : 0.013465418332969777 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013381347668888812, + 0.013465418332969777, + 0.013389621299192356 + ], + [ + 0.01309357979705401, + 0.013136523861943583, + 0.013089428605460252 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.781118089989578, + "scoreError" : 0.11546829612131464, + "scoreConfidence" : [ + 3.6656497938682637, + 3.8965863861108927 + ], + "scorePercentiles" : { + "0.0" : 3.730160135719612, + "50.0" : 3.777153663921011, + "90.0" : 3.828048441469013, + "95.0" : 3.828048441469013, + "99.0" : 3.828048441469013, + "99.9" : 3.828048441469013, + "99.99" : 3.828048441469013, + "99.999" : 3.828048441469013, + "99.9999" : 3.828048441469013, + "100.0" : 3.828048441469013 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8268429143075746, + 3.7627296576373213, + 3.7915776702047004 + ], + [ + 3.7473497205992508, + 3.828048441469013, + 3.730160135719612 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.863423200853669, + "scoreError" : 0.11143098750712782, + "scoreConfidence" : [ + 2.751992213346541, + 2.974854188360797 + ], + "scorePercentiles" : { + "0.0" : 2.781810797774687, + "50.0" : 2.878338304172662, + "90.0" : 2.968725054021965, + "95.0" : 2.968725054021965, + "99.0" : 2.968725054021965, + "99.9" : 2.968725054021965, + "99.99" : 2.968725054021965, + "99.999" : 2.968725054021965, + "99.9999" : 2.968725054021965, + "100.0" : 2.968725054021965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7881445059938668, + 2.781810797774687, + 2.78970139804742 + ], + [ + 2.968725054021965, + 2.9061028076699595, + 2.9218728875255624 + ], + [ + 2.8477734137243735, + 2.8883396387525266, + 2.878338304172662 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.41013333675, + "scoreError" : 1.915660838419777, + "scoreConfidence" : [ + 4.494472498330223, + 8.325794175169777 + ], + "scorePercentiles" : { + "0.0" : 6.057172863, + "50.0" : 6.40351615475, + "90.0" : 6.7763281745, + "95.0" : 6.7763281745, + "99.0" : 6.7763281745, + "99.9" : 6.7763281745, + "99.99" : 6.7763281745, + "99.999" : 6.7763281745, + "99.9999" : 6.7763281745, + "100.0" : 6.7763281745 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.057172863, + 6.354111661 + ], + [ + 6.4529206485, + 6.7763281745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17529859417750462, + "scoreError" : 0.005318291129688179, + "scoreConfidence" : [ + 0.16998030304781644, + 0.1806168853071928 + ], + "scorePercentiles" : { + "0.0" : 0.17090243717742762, + "50.0" : 0.17613550783781878, + "90.0" : 0.17873346857071365, + "95.0" : 0.17873346857071365, + "99.0" : 0.17873346857071365, + "99.9" : 0.17873346857071365, + "99.99" : 0.17873346857071365, + "99.999" : 0.17873346857071365, + "99.9999" : 0.17873346857071365, + "100.0" : 0.17873346857071365 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17090243717742762, + 0.17160361484341485, + 0.17137066662096856 + ], + [ + 0.17613550783781878, + 0.17644555178558827, + 0.1760570273938839 + ], + [ + 0.17858570977016625, + 0.17873346857071365, + 0.1778533635975599 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32264458916713745, + "scoreError" : 0.006465841522527593, + "scoreConfidence" : [ + 0.31617874764460985, + 0.32911043068966506 + ], + "scorePercentiles" : { + "0.0" : 0.3175302044198895, + "50.0" : 0.3219793051933417, + "90.0" : 0.32815969593752053, + "95.0" : 0.32815969593752053, + "99.0" : 0.32815969593752053, + "99.9" : 0.32815969593752053, + "99.99" : 0.32815969593752053, + "99.999" : 0.32815969593752053, + "99.9999" : 0.32815969593752053, + "100.0" : 0.32815969593752053 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32696304283145333, + 0.3264260142969056, + 0.32815969593752053 + ], + [ + 0.32122287761788515, + 0.3175302044198895, + 0.3176074453407864 + ], + [ + 0.3222151502126563, + 0.3219793051933417, + 0.3216975666537991 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16897623175359444, + "scoreError" : 0.004650547695083193, + "scoreConfidence" : [ + 0.16432568405851125, + 0.17362677944867763 + ], + "scorePercentiles" : { + "0.0" : 0.16618179073400136, + "50.0" : 0.16771365981853859, + "90.0" : 0.1739875364058667, + "95.0" : 0.1739875364058667, + "99.0" : 0.1739875364058667, + "99.9" : 0.1739875364058667, + "99.99" : 0.1739875364058667, + "99.999" : 0.1739875364058667, + "99.9999" : 0.1739875364058667, + "100.0" : 0.1739875364058667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16618179073400136, + 0.1672907168141593, + 0.16630812055345828 + ], + [ + 0.16870615775355963, + 0.16771365981853859, + 0.1673853330376272 + ], + [ + 0.1739875364058667, + 0.17202811050902272, + 0.17118466015611628 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.391812188514016, + "scoreError" : 0.005448214863811001, + "scoreConfidence" : [ + 0.38636397365020503, + 0.397260403377827 + ], + "scorePercentiles" : { + "0.0" : 0.38840035872140444, + "50.0" : 0.3908021093438587, + "90.0" : 0.3996945747402078, + "95.0" : 0.3996945747402078, + "99.0" : 0.3996945747402078, + "99.9" : 0.3996945747402078, + "99.99" : 0.3996945747402078, + "99.999" : 0.3996945747402078, + "99.9999" : 0.3996945747402078, + "100.0" : 0.3996945747402078 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3996945747402078, + 0.389835481698047, + 0.38840035872140444 + ], + [ + 0.39140606367906067, + 0.3905072100823929, + 0.39039653146470954 + ], + [ + 0.3923420294244576, + 0.39292533747200503, + 0.3908021093438587 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15680871939905913, + "scoreError" : 0.004531254031304196, + "scoreConfidence" : [ + 0.15227746536775494, + 0.16133997343036333 + ], + "scorePercentiles" : { + "0.0" : 0.15313347595859367, + "50.0" : 0.15773371872239747, + "90.0" : 0.15986266637359123, + "95.0" : 0.15986266637359123, + "99.0" : 0.15986266637359123, + "99.9" : 0.15986266637359123, + "99.99" : 0.15986266637359123, + "99.999" : 0.15986266637359123, + "99.9999" : 0.15986266637359123, + "100.0" : 0.15986266637359123 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15377808679071198, + 0.15321041517672473, + 0.15313347595859367 + ], + [ + 0.15773371872239747, + 0.1574786911750811, + 0.15780160703465254 + ], + [ + 0.15899469257675247, + 0.15928512078302698, + 0.15986266637359123 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047663043539003226, + "scoreError" : 5.663575331487285E-4, + "scoreConfidence" : [ + 0.047096686005854496, + 0.048229401072151956 + ], + "scorePercentiles" : { + "0.0" : 0.04716799802368745, + "50.0" : 0.047764543625186874, + "90.0" : 0.048215253792079305, + "95.0" : 0.048215253792079305, + "99.0" : 0.048215253792079305, + "99.9" : 0.048215253792079305, + "99.99" : 0.048215253792079305, + "99.999" : 0.048215253792079305, + "99.9999" : 0.048215253792079305, + "100.0" : 0.048215253792079305 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04759558798416037, + 0.04791369522116601, + 0.04778025055185529 + ], + [ + 0.04716799802368745, + 0.047203957465187636, + 0.04749492648371899 + ], + [ + 0.048215253792079305, + 0.04783117870398714, + 0.047764543625186874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9364493.000768173, + "scoreError" : 141997.80451701072, + "scoreConfidence" : [ + 9222495.196251163, + 9506490.805285184 + ], + "scorePercentiles" : { + "0.0" : 9215742.624309393, + "50.0" : 9391256.443192488, + "90.0" : 9479963.022748815, + "95.0" : 9479963.022748815, + "99.0" : 9479963.022748815, + "99.9" : 9479963.022748815, + "99.99" : 9479963.022748815, + "99.999" : 9479963.022748815, + "99.9999" : 9479963.022748815, + "100.0" : 9479963.022748815 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9275980.784986097, + 9331616.729477612, + 9215742.624309393 + ], + [ + 9424516.342749529, + 9323990.641192917, + 9397302.329577465 + ], + [ + 9440068.088679245, + 9479963.022748815, + 9391256.443192488 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-23T00:49:24Z-bf9bad8f21689a23555ef1806c93d019400a0a9b-jdk17.json b/performance-results/2025-04-23T00:49:24Z-bf9bad8f21689a23555ef1806c93d019400a0a9b-jdk17.json new file mode 100644 index 0000000000..955292d09e --- /dev/null +++ b/performance-results/2025-04-23T00:49:24Z-bf9bad8f21689a23555ef1806c93d019400a0a9b-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4205893702481136, + "scoreError" : 0.01382351128766436, + "scoreConfidence" : [ + 3.406765858960449, + 3.434412881535778 + ], + "scorePercentiles" : { + "0.0" : 3.4182941455648703, + "50.0" : 3.420314806038646, + "90.0" : 3.4234337233502927, + "95.0" : 3.4234337233502927, + "99.0" : 3.4234337233502927, + "99.9" : 3.4234337233502927, + "99.99" : 3.4234337233502927, + "99.999" : 3.4234337233502927, + "99.9999" : 3.4234337233502927, + "100.0" : 3.4234337233502927 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4206460198237965, + 3.419983592253495 + ], + [ + 3.4182941455648703, + 3.4234337233502927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7265276361612134, + "scoreError" : 0.013245005178981263, + "scoreConfidence" : [ + 1.7132826309822322, + 1.7397726413401946 + ], + "scorePercentiles" : { + "0.0" : 1.724124306654102, + "50.0" : 1.7264632848734682, + "90.0" : 1.7290596682438153, + "95.0" : 1.7290596682438153, + "99.0" : 1.7290596682438153, + "99.9" : 1.7290596682438153, + "99.99" : 1.7290596682438153, + "99.999" : 1.7290596682438153, + "99.9999" : 1.7290596682438153, + "100.0" : 1.7290596682438153 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.724124306654102, + 1.7269150000836886 + ], + [ + 1.726011569663248, + 1.7290596682438153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8675463416255575, + "scoreError" : 0.002018744231309582, + "scoreConfidence" : [ + 0.865527597394248, + 0.8695650858568671 + ], + "scorePercentiles" : { + "0.0" : 0.8670811628122921, + "50.0" : 0.8676780221186478, + "90.0" : 0.8677481594526426, + "95.0" : 0.8677481594526426, + "99.0" : 0.8677481594526426, + "99.9" : 0.8677481594526426, + "99.99" : 0.8677481594526426, + "99.999" : 0.8677481594526426, + "99.9999" : 0.8677481594526426, + "100.0" : 0.8677481594526426 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8670811628122921, + 0.8677481594526426 + ], + [ + 0.8676558246425776, + 0.8677002195947178 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.075547315684123, + "scoreError" : 0.209773702890232, + "scoreConfidence" : [ + 15.865773612793891, + 16.285321018574354 + ], + "scorePercentiles" : { + "0.0" : 15.877970985673285, + "50.0" : 16.05931300214754, + "90.0" : 16.238195577355878, + "95.0" : 16.238195577355878, + "99.0" : 16.238195577355878, + "99.9" : 16.238195577355878, + "99.99" : 16.238195577355878, + "99.999" : 16.238195577355878, + "99.9999" : 16.238195577355878, + "100.0" : 16.238195577355878 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.17066503700288, + 16.21173765355542, + 16.238195577355878 + ], + [ + 16.05931300214754, + 15.904856129250485, + 16.0567847106306 + ], + [ + 16.05032067145426, + 15.877970985673285, + 16.11008207408676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2655.7241844538175, + "scoreError" : 55.56426813498251, + "scoreConfidence" : [ + 2600.159916318835, + 2711.2884525888003 + ], + "scorePercentiles" : { + "0.0" : 2613.5754422912505, + "50.0" : 2655.069882819036, + "90.0" : 2704.789431396354, + "95.0" : 2704.789431396354, + "99.0" : 2704.789431396354, + "99.9" : 2704.789431396354, + "99.99" : 2704.789431396354, + "99.999" : 2704.789431396354, + "99.9999" : 2704.789431396354, + "100.0" : 2704.789431396354 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2671.9406398492306, + 2655.069882819036, + 2646.2610242555397 + ], + [ + 2627.632568191786, + 2614.3519177273197, + 2613.5754422912505 + ], + [ + 2691.553855851885, + 2676.342897701956, + 2704.789431396354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70327.00946893464, + "scoreError" : 2306.580210576427, + "scoreConfidence" : [ + 68020.42925835821, + 72633.58967951107 + ], + "scorePercentiles" : { + "0.0" : 68357.78337117803, + "50.0" : 71109.22452456043, + "90.0" : 71505.52857642435, + "95.0" : 71505.52857642435, + "99.0" : 71505.52857642435, + "99.9" : 71505.52857642435, + "99.99" : 71505.52857642435, + "99.999" : 71505.52857642435, + "99.9999" : 71505.52857642435, + "100.0" : 71505.52857642435 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71505.52857642435, + 71223.83896056406, + 71382.35212755966 + ], + [ + 68700.28829922371, + 68472.30883670754, + 68357.78337117803 + ], + [ + 71156.33709421569, + 71035.42342997841, + 71109.22452456043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 348.64800422174386, + "scoreError" : 12.515035255034533, + "scoreConfidence" : [ + 336.1329689667093, + 361.1630394767784 + ], + "scorePercentiles" : { + "0.0" : 337.7681134065756, + "50.0" : 352.6197424066732, + "90.0" : 355.45009928473166, + "95.0" : 355.45009928473166, + "99.0" : 355.45009928473166, + "99.9" : 355.45009928473166, + "99.99" : 355.45009928473166, + "99.999" : 355.45009928473166, + "99.9999" : 355.45009928473166, + "100.0" : 355.45009928473166 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 337.7681134065756, + 339.1068829454776, + 339.60445130277304 + ], + [ + 352.7746231927581, + 354.3589232451558, + 352.6197424066732 + ], + [ + 352.16507078918585, + 353.98413142236456, + 355.45009928473166 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.15587855645595167, + "scoreError" : 0.03414492885084999, + "scoreConfidence" : [ + 0.12173362760510167, + 0.19002348530680166 + ], + "scorePercentiles" : { + "0.0" : 0.15134710597340245, + "50.0" : 0.1548200624676393, + "90.0" : 0.16252699491512568, + "95.0" : 0.16252699491512568, + "99.0" : 0.16252699491512568, + "99.9" : 0.16252699491512568, + "99.99" : 0.16252699491512568, + "99.999" : 0.16252699491512568, + "99.9999" : 0.16252699491512568, + "100.0" : 0.16252699491512568 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16252699491512568, + 0.15192314351099073 + ], + [ + 0.15771698142428783, + 0.15134710597340245 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.39274397832948, + "scoreError" : 2.9974808306516856, + "scoreConfidence" : [ + 104.3952631476778, + 110.39022480898116 + ], + "scorePercentiles" : { + "0.0" : 104.48007009229367, + "50.0" : 108.52423009722895, + "90.0" : 108.78381922276925, + "95.0" : 108.78381922276925, + "99.0" : 108.78381922276925, + "99.9" : 108.78381922276925, + "99.99" : 108.78381922276925, + "99.999" : 108.78381922276925, + "99.9999" : 108.78381922276925, + "100.0" : 108.78381922276925 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.8224406591211, + 104.48007009229367, + 104.92756330913332 + ], + [ + 108.64265911069866, + 108.02180297361868, + 108.78381922276925 + ], + [ + 108.52423009722895, + 108.59003902486124, + 108.7420713152404 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061991785006931935, + "scoreError" : 0.0012685512837584997, + "scoreConfidence" : [ + 0.06072323372317343, + 0.06326033629069043 + ], + "scorePercentiles" : { + "0.0" : 0.06135991206013192, + "50.0" : 0.06155176213015566, + "90.0" : 0.06365254245886509, + "95.0" : 0.06365254245886509, + "99.0" : 0.06365254245886509, + "99.9" : 0.06365254245886509, + "99.99" : 0.06365254245886509, + "99.999" : 0.06365254245886509, + "99.9999" : 0.06365254245886509, + "100.0" : 0.06365254245886509 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061950534118856905, + 0.061550741496891735, + 0.06139477097671334 + ], + [ + 0.06238561109447522, + 0.06253784706014784, + 0.06365254245886509 + ], + [ + 0.06154234366614972, + 0.06155176213015566, + 0.06135991206013192 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8081771228558044E-4, + "scoreError" : 1.643792858679272E-5, + "scoreConfidence" : [ + 3.6437978369878774E-4, + 3.9725564087237313E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7045464619358127E-4, + "50.0" : 3.7624948117687346E-4, + "90.0" : 3.944878571970986E-4, + "95.0" : 3.944878571970986E-4, + "99.0" : 3.944878571970986E-4, + "99.9" : 3.944878571970986E-4, + "99.99" : 3.944878571970986E-4, + "99.999" : 3.944878571970986E-4, + "99.9999" : 3.944878571970986E-4, + "100.0" : 3.944878571970986E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.944878571970986E-4, + 3.919362696540822E-4, + 3.941655533647635E-4 + ], + [ + 3.7436265665442977E-4, + 3.7298513771853183E-4, + 3.7045464619358127E-4 + ], + [ + 3.780605470208322E-4, + 3.7624948117687346E-4, + 3.746572615900311E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11091484657045732, + "scoreError" : 9.128674197618146E-4, + "scoreConfidence" : [ + 0.1100019791506955, + 0.11182771399021914 + ], + "scorePercentiles" : { + "0.0" : 0.11013142867998502, + "50.0" : 0.11102032203916692, + "90.0" : 0.11163326387291948, + "95.0" : 0.11163326387291948, + "99.0" : 0.11163326387291948, + "99.9" : 0.11163326387291948, + "99.99" : 0.11163326387291948, + "99.999" : 0.11163326387291948, + "99.9999" : 0.11163326387291948, + "100.0" : 0.11163326387291948 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11102032203916692, + 0.11163326387291948, + 0.11124467258852191 + ], + [ + 0.11096545994229916, + 0.11138952852066787, + 0.11125633156067821 + ], + [ + 0.11027027014599507, + 0.11013142867998502, + 0.11032234178388217 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014500064500003308, + "scoreError" : 5.474910588268142E-4, + "scoreConfidence" : [ + 0.013952573441176494, + 0.015047555558830122 + ], + "scorePercentiles" : { + "0.0" : 0.014100616836200891, + "50.0" : 0.014552634945166247, + "90.0" : 0.014885838570856536, + "95.0" : 0.014885838570856536, + "99.0" : 0.014885838570856536, + "99.9" : 0.014885838570856536, + "99.99" : 0.014885838570856536, + "99.999" : 0.014885838570856536, + "99.9999" : 0.014885838570856536, + "100.0" : 0.014885838570856536 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014100616836200891, + 0.014103064751965589, + 0.014109256066899561 + ], + [ + 0.014822423103717121, + 0.014843942695685217, + 0.014885838570856536 + ], + [ + 0.014552634945166247, + 0.01457390523721665, + 0.014508898292321978 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9887449224129087, + "scoreError" : 0.012029876683904718, + "scoreConfidence" : [ + 0.9767150457290039, + 1.0007747990968134 + ], + "scorePercentiles" : { + "0.0" : 0.9755059465470152, + "50.0" : 0.9878300698340576, + "90.0" : 1.0010541571571572, + "95.0" : 1.0010541571571572, + "99.0" : 1.0010541571571572, + "99.9" : 1.0010541571571572, + "99.99" : 1.0010541571571572, + "99.999" : 1.0010541571571572, + "99.9999" : 1.0010541571571572, + "100.0" : 1.0010541571571572 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9926866897955132, + 0.9916920194367315, + 1.0010541571571572 + ], + [ + 0.9932946465037743, + 0.9878300698340576, + 0.9755059465470152 + ], + [ + 0.9875628668904908, + 0.9851136687352245, + 0.9839642368162141 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013171633246078888, + "scoreError" : 2.2692635880550694E-4, + "scoreConfidence" : [ + 0.012944706887273382, + 0.013398559604884395 + ], + "scorePercentiles" : { + "0.0" : 0.013104580251864083, + "50.0" : 0.013157317702907364, + "90.0" : 0.013325825881280631, + "95.0" : 0.013325825881280631, + "99.0" : 0.013325825881280631, + "99.9" : 0.013325825881280631, + "99.99" : 0.013325825881280631, + "99.999" : 0.013325825881280631, + "99.9999" : 0.013325825881280631, + "100.0" : 0.013325825881280631 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013104580251864083, + 0.013325825881280631, + 0.013175213130088799 + ], + [ + 0.013147457724184354, + 0.01310954480742508, + 0.013167177681630374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.795605233896595, + "scoreError" : 0.1206947553325696, + "scoreConfidence" : [ + 3.6749104785640254, + 3.916299989229165 + ], + "scorePercentiles" : { + "0.0" : 3.7521398514628657, + "50.0" : 3.791028892428754, + "90.0" : 3.874325894655306, + "95.0" : 3.874325894655306, + "99.0" : 3.874325894655306, + "99.9" : 3.874325894655306, + "99.99" : 3.874325894655306, + "99.999" : 3.874325894655306, + "99.9999" : 3.874325894655306, + "100.0" : 3.874325894655306 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7637098397291195, + 3.7521398514628657, + 3.7845612685325265 + ], + [ + 3.801398032674772, + 3.797496516324981, + 3.874325894655306 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8974235638218286, + "scoreError" : 0.04078040221505274, + "scoreConfidence" : [ + 2.856643161606776, + 2.9382039660368813 + ], + "scorePercentiles" : { + "0.0" : 2.864194845074456, + "50.0" : 2.8888214188330443, + "90.0" : 2.941597655882353, + "95.0" : 2.941597655882353, + "99.0" : 2.941597655882353, + "99.9" : 2.941597655882353, + "99.99" : 2.941597655882353, + "99.999" : 2.941597655882353, + "99.9999" : 2.941597655882353, + "100.0" : 2.941597655882353 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8888214188330443, + 2.876919297382801, + 2.8828767195157106 + ], + [ + 2.941597655882353, + 2.9240752280701754, + 2.9093106698662012 + ], + [ + 2.864194845074456, + 2.8881343511406294, + 2.9008818886310905 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.490047534625001, + "scoreError" : 0.9726091811245781, + "scoreConfidence" : [ + 5.517438353500423, + 7.462656715749579 + ], + "scorePercentiles" : { + "0.0" : 6.32754971, + "50.0" : 6.50557035875, + "90.0" : 6.621499711, + "95.0" : 6.621499711, + "99.0" : 6.621499711, + "99.9" : 6.621499711, + "99.99" : 6.621499711, + "99.999" : 6.621499711, + "99.9999" : 6.621499711, + "100.0" : 6.621499711 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.32754971, + 6.614645485 + ], + [ + 6.3964952325, + 6.621499711 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1745776712217435, + "scoreError" : 0.004206028300475727, + "scoreConfidence" : [ + 0.17037164292126777, + 0.17878369952221923 + ], + "scorePercentiles" : { + "0.0" : 0.17137056014051924, + "50.0" : 0.17459460048536063, + "90.0" : 0.17762025441821638, + "95.0" : 0.17762025441821638, + "99.0" : 0.17762025441821638, + "99.9" : 0.17762025441821638, + "99.99" : 0.17762025441821638, + "99.999" : 0.17762025441821638, + "99.9999" : 0.17762025441821638, + "100.0" : 0.17762025441821638 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17137056014051924, + 0.17194991581553698, + 0.17177878950803901 + ], + [ + 0.17459460048536063, + 0.1747922786128784, + 0.17433077135087077 + ], + [ + 0.17730323380376584, + 0.1774586368605043, + 0.17762025441821638 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3303444454135176, + "scoreError" : 0.02058406933939373, + "scoreConfidence" : [ + 0.3097603760741239, + 0.3509285147529113 + ], + "scorePercentiles" : { + "0.0" : 0.31307321426335233, + "50.0" : 0.3364601669806877, + "90.0" : 0.34251582970853167, + "95.0" : 0.34251582970853167, + "99.0" : 0.34251582970853167, + "99.9" : 0.34251582970853167, + "99.99" : 0.34251582970853167, + "99.999" : 0.34251582970853167, + "99.9999" : 0.34251582970853167, + "100.0" : 0.34251582970853167 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31307321426335233, + 0.31527174227616644, + 0.31431190105607243 + ], + [ + 0.33757157473669996, + 0.3359965806874307, + 0.3364601669806877 + ], + [ + 0.33887193727762527, + 0.34251582970853167, + 0.33902706173509173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1562693597108447, + "scoreError" : 0.008845099697065262, + "scoreConfidence" : [ + 0.14742426001377945, + 0.16511445940790997 + ], + "scorePercentiles" : { + "0.0" : 0.1486287264093456, + "50.0" : 0.15930842999378714, + "90.0" : 0.16062775716786867, + "95.0" : 0.16062775716786867, + "99.0" : 0.16062775716786867, + "99.9" : 0.16062775716786867, + "99.99" : 0.16062775716786867, + "99.999" : 0.16062775716786867, + "99.9999" : 0.16062775716786867, + "100.0" : 0.16062775716786867 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.160005357456, + 0.15930842999378714, + 0.16025830483485842 + ], + [ + 0.15939140208798214, + 0.16062775716786867, + 0.15894370848896164 + ], + [ + 0.14939837715130871, + 0.1486287264093456, + 0.14986217380749 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.389152093719067, + "scoreError" : 0.007566046808585527, + "scoreConfidence" : [ + 0.3815860469104815, + 0.39671814052765253 + ], + "scorePercentiles" : { + "0.0" : 0.3828534013782542, + "50.0" : 0.3905037583271506, + "90.0" : 0.3953757113035227, + "95.0" : 0.3953757113035227, + "99.0" : 0.3953757113035227, + "99.9" : 0.3953757113035227, + "99.99" : 0.3953757113035227, + "99.999" : 0.3953757113035227, + "99.9999" : 0.3953757113035227, + "100.0" : 0.3953757113035227 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3905037583271506, + 0.3907207516702481, + 0.3903423895546274 + ], + [ + 0.3953757113035227, + 0.39264856763123795, + 0.3921757525490196 + ], + [ + 0.3845759696958043, + 0.383172541361738, + 0.3828534013782542 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15429255081230073, + "scoreError" : 0.003921364867476106, + "scoreConfidence" : [ + 0.15037118594482463, + 0.15821391567977683 + ], + "scorePercentiles" : { + "0.0" : 0.15174565566531614, + "50.0" : 0.1531924791127315, + "90.0" : 0.15795315791635078, + "95.0" : 0.15795315791635078, + "99.0" : 0.15795315791635078, + "99.9" : 0.15795315791635078, + "99.99" : 0.15795315791635078, + "99.999" : 0.15795315791635078, + "99.9999" : 0.15795315791635078, + "100.0" : 0.15795315791635078 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1531924791127315, + 0.15219594598666789, + 0.15174565566531614 + ], + [ + 0.15349359262329051, + 0.15302347861547644, + 0.15309620217391304 + ], + [ + 0.15795315791635078, + 0.1571824657508409, + 0.1567499794661191 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04744018246776174, + "scoreError" : 0.0019252094781829537, + "scoreConfidence" : [ + 0.04551497298957879, + 0.0493653919459447 + ], + "scorePercentiles" : { + "0.0" : 0.04612923753949766, + "50.0" : 0.047155143849407506, + "90.0" : 0.04906682002090213, + "95.0" : 0.04906682002090213, + "99.0" : 0.04906682002090213, + "99.9" : 0.04906682002090213, + "99.99" : 0.04906682002090213, + "99.999" : 0.04906682002090213, + "99.9999" : 0.04906682002090213, + "100.0" : 0.04906682002090213 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04717302514281401, + 0.04698703097336816, + 0.047155143849407506 + ], + [ + 0.04906682002090213, + 0.048787603142852964, + 0.04880492191800879 + ], + [ + 0.04659401368446066, + 0.04612923753949766, + 0.04626384593854382 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9104432.825831644, + "scoreError" : 231471.09485886127, + "scoreConfidence" : [ + 8872961.730972784, + 9335903.920690505 + ], + "scorePercentiles" : { + "0.0" : 8918914.088235294, + "50.0" : 9071289.56482321, + "90.0" : 9285829.121634169, + "95.0" : 9285829.121634169, + "99.0" : 9285829.121634169, + "99.9" : 9285829.121634169, + "99.99" : 9285829.121634169, + "99.999" : 9285829.121634169, + "99.9999" : 9285829.121634169, + "100.0" : 9285829.121634169 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9092988.733636364, + 9071289.56482321, + 9070230.352674523 + ], + [ + 8972040.394618833, + 8996052.81115108, + 8918914.088235294 + ], + [ + 9280557.111317255, + 9251993.254394079, + 9285829.121634169 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-27T07:27:46Z-bfd567ed115ce7a28045a2cf936309d8b71a3db7-jdk17.json b/performance-results/2025-04-27T07:27:46Z-bfd567ed115ce7a28045a2cf936309d8b71a3db7-jdk17.json new file mode 100644 index 0000000000..6e4c0845b9 --- /dev/null +++ b/performance-results/2025-04-27T07:27:46Z-bfd567ed115ce7a28045a2cf936309d8b71a3db7-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4189850794437735, + "scoreError" : 0.016413303092428316, + "scoreConfidence" : [ + 3.402571776351345, + 3.435398382536202 + ], + "scorePercentiles" : { + "0.0" : 3.416487316391673, + "50.0" : 3.4191117484603875, + "90.0" : 3.4212295044626457, + "95.0" : 3.4212295044626457, + "99.0" : 3.4212295044626457, + "99.9" : 3.4212295044626457, + "99.99" : 3.4212295044626457, + "99.999" : 3.4212295044626457, + "99.9999" : 3.4212295044626457, + "100.0" : 3.4212295044626457 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4212295044626457, + 3.4211175017801088 + ], + [ + 3.416487316391673, + 3.417105995140666 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7283176381649854, + "scoreError" : 0.012371799220572594, + "scoreConfidence" : [ + 1.7159458389444129, + 1.740689437385558 + ], + "scorePercentiles" : { + "0.0" : 1.726454699291861, + "50.0" : 1.7281549335015507, + "90.0" : 1.7305059863649797, + "95.0" : 1.7305059863649797, + "99.0" : 1.7305059863649797, + "99.9" : 1.7305059863649797, + "99.99" : 1.7305059863649797, + "99.999" : 1.7305059863649797, + "99.9999" : 1.7305059863649797, + "100.0" : 1.7305059863649797 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7293134122638396, + 1.7305059863649797 + ], + [ + 1.726454699291861, + 1.7269964547392616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8670492736377341, + "scoreError" : 0.010231180079828268, + "scoreConfidence" : [ + 0.8568180935579058, + 0.8772804537175624 + ], + "scorePercentiles" : { + "0.0" : 0.8651870928385561, + "50.0" : 0.8671486879533767, + "90.0" : 0.8687126258056268, + "95.0" : 0.8687126258056268, + "99.0" : 0.8687126258056268, + "99.9" : 0.8687126258056268, + "99.99" : 0.8687126258056268, + "99.999" : 0.8687126258056268, + "99.9999" : 0.8687126258056268, + "100.0" : 0.8687126258056268 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8679443523619672, + 0.8687126258056268 + ], + [ + 0.8651870928385561, + 0.8663530235447862 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.296638241738467, + "scoreError" : 0.15422893287751652, + "scoreConfidence" : [ + 16.14240930886095, + 16.450867174615983 + ], + "scorePercentiles" : { + "0.0" : 16.189111123259437, + "50.0" : 16.29015969733824, + "90.0" : 16.439282163072058, + "95.0" : 16.439282163072058, + "99.0" : 16.439282163072058, + "99.9" : 16.439282163072058, + "99.99" : 16.439282163072058, + "99.999" : 16.439282163072058, + "99.9999" : 16.439282163072058, + "100.0" : 16.439282163072058 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.287817348416255, + 16.29436506621504, + 16.29015969733824 + ], + [ + 16.439282163072058, + 16.387489717370695, + 16.384819537767008 + ], + [ + 16.197395630980367, + 16.189111123259437, + 16.199303891227093 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2755.20601165857, + "scoreError" : 67.46511941840183, + "scoreConfidence" : [ + 2687.7408922401683, + 2822.6711310769715 + ], + "scorePercentiles" : { + "0.0" : 2700.3354753568874, + "50.0" : 2776.5536318545146, + "90.0" : 2786.088818826823, + "95.0" : 2786.088818826823, + "99.0" : 2786.088818826823, + "99.9" : 2786.088818826823, + "99.99" : 2786.088818826823, + "99.999" : 2786.088818826823, + "99.9999" : 2786.088818826823, + "100.0" : 2786.088818826823 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2782.5199804617478, + 2776.5536318545146, + 2786.088818826823 + ], + [ + 2784.4958167097984, + 2785.2901211838544, + 2776.248834053172 + ], + [ + 2702.1833668724025, + 2703.1380596079302, + 2700.3354753568874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 71490.81060833327, + "scoreError" : 532.8298887737551, + "scoreConfidence" : [ + 70957.9807195595, + 72023.64049710703 + ], + "scorePercentiles" : { + "0.0" : 71049.72469581163, + "50.0" : 71677.49621845018, + "90.0" : 71757.89164555281, + "95.0" : 71757.89164555281, + "99.0" : 71757.89164555281, + "99.9" : 71757.89164555281, + "99.99" : 71757.89164555281, + "99.999" : 71757.89164555281, + "99.9999" : 71757.89164555281, + "100.0" : 71757.89164555281 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71682.00305026403, + 71677.49621845018, + 71660.97791242748 + ], + [ + 71049.72469581163, + 71081.84450661566, + 71078.19999353561 + ], + [ + 71757.89164555281, + 71700.20636447797, + 71728.95108786387 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 354.3962695686639, + "scoreError" : 2.8275115926714403, + "scoreConfidence" : [ + 351.56875797599247, + 357.22378116133535 + ], + "scorePercentiles" : { + "0.0" : 352.22996636234916, + "50.0" : 354.73340387610995, + "90.0" : 356.61337779032397, + "95.0" : 356.61337779032397, + "99.0" : 356.61337779032397, + "99.9" : 356.61337779032397, + "99.99" : 356.61337779032397, + "99.999" : 356.61337779032397, + "99.9999" : 356.61337779032397, + "100.0" : 356.61337779032397 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.61337779032397, + 355.8142274223376, + 355.40967604276665 + ], + [ + 354.1433908872535, + 355.79340305661725, + 354.73340387610995 + ], + [ + 352.22996636234916, + 352.51145021649114, + 352.31753046372637 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.15488298727510533, + "scoreError" : 0.031701349353123374, + "scoreConfidence" : [ + 0.12318163792198195, + 0.1865843366282287 + ], + "scorePercentiles" : { + "0.0" : 0.1502595120575458, + "50.0" : 0.15422125601458714, + "90.0" : 0.16082992501370125, + "95.0" : 0.16082992501370125, + "99.0" : 0.16082992501370125, + "99.9" : 0.16082992501370125, + "99.99" : 0.16082992501370125, + "99.999" : 0.16082992501370125, + "99.9999" : 0.16082992501370125, + "100.0" : 0.16082992501370125 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16082992501370125, + 0.15152099590954102 + ], + [ + 0.15692151611963323, + 0.1502595120575458 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 111.0113627596366, + "scoreError" : 2.4024628476294323, + "scoreConfidence" : [ + 108.60889991200716, + 113.41382560726603 + ], + "scorePercentiles" : { + "0.0" : 109.69820365900563, + "50.0" : 110.35438773958123, + "90.0" : 113.08715900963803, + "95.0" : 113.08715900963803, + "99.0" : 113.08715900963803, + "99.9" : 113.08715900963803, + "99.99" : 113.08715900963803, + "99.999" : 113.08715900963803, + "99.9999" : 113.08715900963803, + "100.0" : 113.08715900963803 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.69820365900563, + 110.35438773958123, + 110.4597378011346 + ], + [ + 112.54186898475123, + 113.08715900963803, + 113.01115755551382 + ], + [ + 109.76884954340822, + 110.10960532131418, + 110.07129522238237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0616437774872666, + "scoreError" : 4.403409785016151E-4, + "scoreConfidence" : [ + 0.06120343650876498, + 0.062084118465768216 + ], + "scorePercentiles" : { + "0.0" : 0.061280247685171, + "50.0" : 0.06181035153410636, + "90.0" : 0.06187501818485565, + "95.0" : 0.06187501818485565, + "99.0" : 0.06187501818485565, + "99.9" : 0.06187501818485565, + "99.99" : 0.06187501818485565, + "99.999" : 0.06187501818485565, + "99.9999" : 0.06187501818485565, + "100.0" : 0.06187501818485565 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061304592568752224, + 0.061318338631151666, + 0.061280247685171 + ], + [ + 0.06184952163775242, + 0.06169529601021661, + 0.06187501818485565 + ], + [ + 0.06184465789929375, + 0.06181597323409963, + 0.06181035153410636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7007916662943333E-4, + "scoreError" : 1.0038207239144258E-5, + "scoreConfidence" : [ + 3.6004095939028906E-4, + 3.801173738685776E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6470761228278765E-4, + "50.0" : 3.6762248049049116E-4, + "90.0" : 3.7831303925567577E-4, + "95.0" : 3.7831303925567577E-4, + "99.0" : 3.7831303925567577E-4, + "99.9" : 3.7831303925567577E-4, + "99.99" : 3.7831303925567577E-4, + "99.999" : 3.7831303925567577E-4, + "99.9999" : 3.7831303925567577E-4, + "100.0" : 3.7831303925567577E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6470761228278765E-4, + 3.647274415377106E-4, + 3.6481383072564893E-4 + ], + [ + 3.7741963412604387E-4, + 3.77855677799178E-4, + 3.7831303925567577E-4 + ], + [ + 3.675043073246716E-4, + 3.6762248049049116E-4, + 3.6774847612269215E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11065283751351825, + "scoreError" : 0.003048326784107685, + "scoreConfidence" : [ + 0.10760451072941056, + 0.11370116429762593 + ], + "scorePercentiles" : { + "0.0" : 0.10815935709186875, + "50.0" : 0.11180283140477389, + "90.0" : 0.11196958440729586, + "95.0" : 0.11196958440729586, + "99.0" : 0.11196958440729586, + "99.9" : 0.11196958440729586, + "99.99" : 0.11196958440729586, + "99.999" : 0.11196958440729586, + "99.9999" : 0.11196958440729586, + "100.0" : 0.11196958440729586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11181985065581286, + 0.11176684935120092, + 0.11180283140477389 + ], + [ + 0.11191412920229196, + 0.11196958440729586, + 0.1118939883296782 + ], + [ + 0.10823070085608841, + 0.10831824632265333, + 0.10815935709186875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014237604895882543, + "scoreError" : 3.54836538095862E-4, + "scoreConfidence" : [ + 0.01388276835778668, + 0.014592441433978405 + ], + "scorePercentiles" : { + "0.0" : 0.014068889350967997, + "50.0" : 0.014122253701750149, + "90.0" : 0.014520157515688843, + "95.0" : 0.014520157515688843, + "99.0" : 0.014520157515688843, + "99.9" : 0.014520157515688843, + "99.99" : 0.014520157515688843, + "99.999" : 0.014520157515688843, + "99.9999" : 0.014520157515688843, + "100.0" : 0.014520157515688843 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014517940427780625, + 0.014520157515688843, + 0.014515420808469934 + ], + [ + 0.014068889350967997, + 0.014073290571720087, + 0.014081481430997434 + ], + [ + 0.014124733681174487, + 0.014122253701750149, + 0.01411427657439334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.989805827765794, + "scoreError" : 0.020497470536923183, + "scoreConfidence" : [ + 0.9693083572288708, + 1.0103032983027171 + ], + "scorePercentiles" : { + "0.0" : 0.9745196392516079, + "50.0" : 0.9891997307616222, + "90.0" : 1.0074892338303445, + "95.0" : 1.0074892338303445, + "99.0" : 1.0074892338303445, + "99.9" : 1.0074892338303445, + "99.99" : 1.0074892338303445, + "99.999" : 1.0074892338303445, + "99.9999" : 1.0074892338303445, + "100.0" : 1.0074892338303445 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9759581102761784, + 0.9780333606845966, + 0.9745196392516079 + ], + [ + 0.9891997307616222, + 0.9904009607843137, + 0.9889041342826066 + ], + [ + 0.9986522467545437, + 1.0074892338303445, + 1.0050950332663318 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01280596546297985, + "scoreError" : 2.235972159275345E-4, + "scoreConfidence" : [ + 0.012582368247052314, + 0.013029562678907385 + ], + "scorePercentiles" : { + "0.0" : 0.012675894257436787, + "50.0" : 0.012810142355059232, + "90.0" : 0.012890940973708229, + "95.0" : 0.012890940973708229, + "99.0" : 0.012890940973708229, + "99.9" : 0.012890940973708229, + "99.99" : 0.012890940973708229, + "99.999" : 0.012890940973708229, + "99.9999" : 0.012890940973708229, + "100.0" : 0.012890940973708229 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012675894257436787, + 0.012809088027113643, + 0.01281119668300482 + ], + [ + 0.012765436388795279, + 0.012890940973708229, + 0.012883236447820341 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.5817571430548476, + "scoreError" : 0.07479326761599203, + "scoreConfidence" : [ + 3.5069638754388555, + 3.6565504106708397 + ], + "scorePercentiles" : { + "0.0" : 3.539031644019816, + "50.0" : 3.577537363577778, + "90.0" : 3.6115560620938627, + "95.0" : 3.6115560620938627, + "99.0" : 3.6115560620938627, + "99.9" : 3.6115560620938627, + "99.99" : 3.6115560620938627, + "99.999" : 3.6115560620938627, + "99.9999" : 3.6115560620938627, + "100.0" : 3.6115560620938627 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5792541453113818, + 3.609377896825397, + 3.6115560620938627 + ], + [ + 3.539031644019816, + 3.5758205818441744, + 3.5755025282344532 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.812005924852654, + "scoreError" : 0.0753375929545065, + "scoreConfidence" : [ + 2.7366683318981475, + 2.8873435178071607 + ], + "scorePercentiles" : { + "0.0" : 2.7662552544247787, + "50.0" : 2.7963360145373217, + "90.0" : 2.8762605858498707, + "95.0" : 2.8762605858498707, + "99.0" : 2.8762605858498707, + "99.9" : 2.8762605858498707, + "99.99" : 2.8762605858498707, + "99.999" : 2.8762605858498707, + "99.9999" : 2.8762605858498707, + "100.0" : 2.8762605858498707 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.770084333979507, + 2.7662552544247787, + 2.7746462116504853 + ], + [ + 2.856649103970294, + 2.8750374642138548, + 2.8762605858498707 + ], + [ + 2.798025943200895, + 2.7963360145373217, + 2.7947584118468844 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.400671131875, + "scoreError" : 1.2393829692583074, + "scoreConfidence" : [ + 5.161288162616692, + 7.640054101133307 + ], + "scorePercentiles" : { + "0.0" : 6.2599181375, + "50.0" : 6.33228571625, + "90.0" : 6.6781949575, + "95.0" : 6.6781949575, + "99.0" : 6.6781949575, + "99.9" : 6.6781949575, + "99.99" : 6.6781949575, + "99.999" : 6.6781949575, + "99.9999" : 6.6781949575, + "100.0" : 6.6781949575 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.286607621, + 6.6781949575 + ], + [ + 6.2599181375, + 6.3779638115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1812391769952394, + "scoreError" : 0.016505152839115158, + "scoreConfidence" : [ + 0.16473402415612423, + 0.19774432983435455 + ], + "scorePercentiles" : { + "0.0" : 0.17249095113410953, + "50.0" : 0.17698623264251456, + "90.0" : 0.19424218056445816, + "95.0" : 0.19424218056445816, + "99.0" : 0.19424218056445816, + "99.9" : 0.19424218056445816, + "99.99" : 0.19424218056445816, + "99.999" : 0.19424218056445816, + "99.9999" : 0.19424218056445816, + "100.0" : 0.19424218056445816 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17285320019359077, + 0.17256516809318379, + 0.17249095113410953 + ], + [ + 0.17706001558101242, + 0.17698623264251456, + 0.17692558656806198 + ], + [ + 0.19394774302282733, + 0.19408151515739627, + 0.19424218056445816 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.322084441983042, + "scoreError" : 0.012945333288878, + "scoreConfidence" : [ + 0.309139108694164, + 0.33502977527191996 + ], + "scorePercentiles" : { + "0.0" : 0.3118201284026067, + "50.0" : 0.3266602675573267, + "90.0" : 0.32812063470814057, + "95.0" : 0.32812063470814057, + "99.0" : 0.32812063470814057, + "99.9" : 0.32812063470814057, + "99.99" : 0.32812063470814057, + "99.999" : 0.32812063470814057, + "99.9999" : 0.32812063470814057, + "100.0" : 0.32812063470814057 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32760372931271703, + 0.3273447267757774, + 0.32757700940120543 + ], + [ + 0.32812063470814057, + 0.325913000945118, + 0.3266602675573267 + ], + [ + 0.31188139898328343, + 0.3118390817612024, + 0.3118201284026067 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15826865975598392, + "scoreError" : 0.016500610210593326, + "scoreConfidence" : [ + 0.1417680495453906, + 0.17476926996657724 + ], + "scorePercentiles" : { + "0.0" : 0.15064311915521814, + "50.0" : 0.15224961506021345, + "90.0" : 0.1718356121554746, + "95.0" : 0.1718356121554746, + "99.0" : 0.1718356121554746, + "99.9" : 0.1718356121554746, + "99.99" : 0.1718356121554746, + "99.999" : 0.1718356121554746, + "99.9999" : 0.1718356121554746, + "100.0" : 0.1718356121554746 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15224961506021345, + 0.15199410653108994, + 0.15219689478890816 + ], + [ + 0.1718356121554746, + 0.1711448609299858, + 0.17101342484096038 + ], + [ + 0.15064311915521814, + 0.15249435202354447, + 0.15084595231846018 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3856805276737913, + "scoreError" : 0.01233458837010862, + "scoreConfidence" : [ + 0.37334593930368265, + 0.39801511604389994 + ], + "scorePercentiles" : { + "0.0" : 0.37636113334086035, + "50.0" : 0.3854542303808202, + "90.0" : 0.4008592856455686, + "95.0" : 0.4008592856455686, + "99.0" : 0.4008592856455686, + "99.9" : 0.4008592856455686, + "99.99" : 0.4008592856455686, + "99.999" : 0.4008592856455686, + "99.9999" : 0.4008592856455686, + "100.0" : 0.4008592856455686 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3882726562742662, + 0.4008592856455686, + 0.3845488307248606 + ], + [ + 0.38286656673047476, + 0.37636113334086035, + 0.37643531028382143 + ], + [ + 0.3881565872923459, + 0.38817014839110353, + 0.3854542303808202 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1577402834304589, + "scoreError" : 0.0033927033782234334, + "scoreConfidence" : [ + 0.15434758005223548, + 0.16113298680868232 + ], + "scorePercentiles" : { + "0.0" : 0.15547497475124378, + "50.0" : 0.15726563032333143, + "90.0" : 0.16033265125376772, + "95.0" : 0.16033265125376772, + "99.0" : 0.16033265125376772, + "99.9" : 0.16033265125376772, + "99.99" : 0.16033265125376772, + "99.999" : 0.16033265125376772, + "99.9999" : 0.16033265125376772, + "100.0" : 0.16033265125376772 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15779303018492805, + 0.15723389732865836, + 0.15726563032333143 + ], + [ + 0.15568029112958465, + 0.15560917482299852, + 0.15547497475124378 + ], + [ + 0.16009098887394743, + 0.16033265125376772, + 0.16018191220567035 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04648576212643121, + "scoreError" : 7.53218870745491E-4, + "scoreConfidence" : [ + 0.04573254325568572, + 0.0472389809971767 + ], + "scorePercentiles" : { + "0.0" : 0.04588070069600246, + "50.0" : 0.04650997701512946, + "90.0" : 0.04701734011472095, + "95.0" : 0.04701734011472095, + "99.0" : 0.04701734011472095, + "99.9" : 0.04701734011472095, + "99.99" : 0.04701734011472095, + "99.999" : 0.04701734011472095, + "99.9999" : 0.04701734011472095, + "100.0" : 0.04701734011472095 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0470124493519437, + 0.04701734011472095, + 0.04673730892903045 + ], + [ + 0.04650997701512946, + 0.04677091654779221, + 0.04650580047900293 + ], + [ + 0.045989632657753986, + 0.04594773334650481, + 0.04588070069600246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9323983.827192925, + "scoreError" : 404409.9994661528, + "scoreConfidence" : [ + 8919573.827726772, + 9728393.826659078 + ], + "scorePercentiles" : { + "0.0" : 9092506.486363636, + "50.0" : 9221235.247926267, + "90.0" : 9638616.761078998, + "95.0" : 9638616.761078998, + "99.0" : 9638616.761078998, + "99.9" : 9638616.761078998, + "99.99" : 9638616.761078998, + "99.999" : 9638616.761078998, + "99.9999" : 9638616.761078998, + "100.0" : 9638616.761078998 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9279827.688311689, + 9221235.247926267, + 9210344.659300184 + ], + [ + 9630551.056785371, + 9632749.213666987, + 9638616.761078998 + ], + [ + 9092506.486363636, + 9112631.71675774, + 9097391.614545455 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-29T01:27:36Z-abff4a3cbb87aeba79c6a22cec6f18c352fc08bd-jdk17.json b/performance-results/2025-04-29T01:27:36Z-abff4a3cbb87aeba79c6a22cec6f18c352fc08bd-jdk17.json new file mode 100644 index 0000000000..b126781175 --- /dev/null +++ b/performance-results/2025-04-29T01:27:36Z-abff4a3cbb87aeba79c6a22cec6f18c352fc08bd-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4169841105961867, + "scoreError" : 0.016861346743152383, + "scoreConfidence" : [ + 3.4001227638530342, + 3.433845457339339 + ], + "scorePercentiles" : { + "0.0" : 3.414341187539911, + "50.0" : 3.4165246044564377, + "90.0" : 3.4205460459319585, + "95.0" : 3.4205460459319585, + "99.0" : 3.4205460459319585, + "99.9" : 3.4205460459319585, + "99.99" : 3.4205460459319585, + "99.999" : 3.4205460459319585, + "99.9999" : 3.4205460459319585, + "100.0" : 3.4205460459319585 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.416117903658298, + 3.4205460459319585 + ], + [ + 3.416931305254578, + 3.414341187539911 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.725110666429803, + "scoreError" : 0.0037718061271390683, + "scoreConfidence" : [ + 1.721338860302664, + 1.728882472556942 + ], + "scorePercentiles" : { + "0.0" : 1.724404557343964, + "50.0" : 1.7251051821743175, + "90.0" : 1.7258277440266132, + "95.0" : 1.7258277440266132, + "99.0" : 1.7258277440266132, + "99.9" : 1.7258277440266132, + "99.99" : 1.7258277440266132, + "99.999" : 1.7258277440266132, + "99.9999" : 1.7258277440266132, + "100.0" : 1.7258277440266132 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7251731368736785, + 1.7250372274749568 + ], + [ + 1.724404557343964, + 1.7258277440266132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8674590800024715, + "scoreError" : 0.006482248420430546, + "scoreConfidence" : [ + 0.860976831582041, + 0.8739413284229021 + ], + "scorePercentiles" : { + "0.0" : 0.866504354720508, + "50.0" : 0.8673948560902545, + "90.0" : 0.8685422531088689, + "95.0" : 0.8685422531088689, + "99.0" : 0.8685422531088689, + "99.9" : 0.8685422531088689, + "99.99" : 0.8685422531088689, + "99.999" : 0.8685422531088689, + "99.9999" : 0.8685422531088689, + "100.0" : 0.8685422531088689 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.866504354720508, + 0.8680752333508601 + ], + [ + 0.8667144788296489, + 0.8685422531088689 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.07274728904666, + "scoreError" : 0.15780953310602785, + "scoreConfidence" : [ + 15.914937755940633, + 16.23055682215269 + ], + "scorePercentiles" : { + "0.0" : 15.89185521457576, + "50.0" : 16.080248300697424, + "90.0" : 16.19791924417957, + "95.0" : 16.19791924417957, + "99.0" : 16.19791924417957, + "99.9" : 16.19791924417957, + "99.99" : 16.19791924417957, + "99.999" : 16.19791924417957, + "99.9999" : 16.19791924417957, + "100.0" : 16.19791924417957 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.980908134815024, + 16.19791924417957, + 16.055670183953687 + ], + [ + 16.080248300697424, + 16.04077425978792, + 15.89185521457576 + ], + [ + 16.150697718971347, + 16.121125139652708, + 16.135527404786473 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2634.92470809111, + "scoreError" : 107.89661205315173, + "scoreConfidence" : [ + 2527.028096037958, + 2742.821320144262 + ], + "scorePercentiles" : { + "0.0" : 2537.996492943148, + "50.0" : 2654.6942112821953, + "90.0" : 2708.3658745443013, + "95.0" : 2708.3658745443013, + "99.0" : 2708.3658745443013, + "99.9" : 2708.3658745443013, + "99.99" : 2708.3658745443013, + "99.999" : 2708.3658745443013, + "99.9999" : 2708.3658745443013, + "100.0" : 2708.3658745443013 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2565.8837479201966, + 2558.4721732226185, + 2537.996492943148 + ], + [ + 2649.6304202913975, + 2654.892639455716, + 2654.6942112821953 + ], + [ + 2708.3658745443013, + 2694.961395631789, + 2689.4254175286264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69377.96630362794, + "scoreError" : 1072.6759615486774, + "scoreConfidence" : [ + 68305.29034207926, + 70450.64226517662 + ], + "scorePercentiles" : { + "0.0" : 68749.47940621381, + "50.0" : 69135.07670493906, + "90.0" : 70236.03335964867, + "95.0" : 70236.03335964867, + "99.0" : 70236.03335964867, + "99.9" : 70236.03335964867, + "99.99" : 70236.03335964867, + "99.999" : 70236.03335964867, + "99.9999" : 70236.03335964867, + "100.0" : 70236.03335964867 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70153.95527622451, + 70232.03785959605, + 70236.03335964867 + ], + [ + 69135.07670493906, + 69196.3831159384, + 68983.01249215448 + ], + [ + 68795.03561789548, + 68920.68290004092, + 68749.47940621381 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.1226186014949, + "scoreError" : 14.508102392270148, + "scoreConfidence" : [ + 335.61451620922475, + 364.630720993765 + ], + "scorePercentiles" : { + "0.0" : 337.49114521107396, + "50.0" : 348.35296541744464, + "90.0" : 361.6531658426927, + "95.0" : 361.6531658426927, + "99.0" : 361.6531658426927, + "99.9" : 361.6531658426927, + "99.99" : 361.6531658426927, + "99.999" : 361.6531658426927, + "99.9999" : 361.6531658426927, + "100.0" : 361.6531658426927 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 350.3209569073325, + 348.35296541744464, + 346.22353217050363 + ], + [ + 342.95780346643915, + 344.0438960393807, + 337.49114521107396 + ], + [ + 360.6713617921953, + 359.3887405663913, + 361.6531658426927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1629261446578569, + "scoreError" : 0.05099195680461377, + "scoreConfidence" : [ + 0.11193418785324313, + 0.21391810146247067 + ], + "scorePercentiles" : { + "0.0" : 0.15363760146225472, + "50.0" : 0.16309303153526916, + "90.0" : 0.1718809140986346, + "95.0" : 0.1718809140986346, + "99.0" : 0.1718809140986346, + "99.9" : 0.1718809140986346, + "99.99" : 0.1718809140986346, + "99.999" : 0.1718809140986346, + "99.9999" : 0.1718809140986346, + "100.0" : 0.1718809140986346 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.15990822901277135, + 0.15363760146225472 + ], + [ + 0.1718809140986346, + 0.166277834057767 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.67991451956517, + "scoreError" : 5.0067874177778675, + "scoreConfidence" : [ + 101.6731271017873, + 111.68670193734305 + ], + "scorePercentiles" : { + "0.0" : 103.46426426049211, + "50.0" : 105.94171626014702, + "90.0" : 110.99981272343388, + "95.0" : 110.99981272343388, + "99.0" : 110.99981272343388, + "99.9" : 110.99981272343388, + "99.99" : 110.99981272343388, + "99.999" : 110.99981272343388, + "99.9999" : 110.99981272343388, + "100.0" : 110.99981272343388 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.29644360147252, + 110.0468389252019, + 110.99981272343388 + ], + [ + 104.91782840924878, + 106.21775191955447, + 105.94171626014702 + ], + [ + 103.56846255389095, + 104.66611202264498, + 103.46426426049211 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06201299940733291, + "scoreError" : 4.311935163610452E-4, + "scoreConfidence" : [ + 0.06158180589097186, + 0.06244419292369396 + ], + "scorePercentiles" : { + "0.0" : 0.06163831407368142, + "50.0" : 0.061916252180966004, + "90.0" : 0.06235981539890997, + "95.0" : 0.06235981539890997, + "99.0" : 0.06235981539890997, + "99.9" : 0.06235981539890997, + "99.99" : 0.06235981539890997, + "99.999" : 0.06235981539890997, + "99.9999" : 0.06235981539890997, + "100.0" : 0.06235981539890997 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06229266055377332, + 0.062187873822331395, + 0.0617617887657104 + ], + [ + 0.062221621990069566, + 0.06235981539890997, + 0.06186835962904304 + ], + [ + 0.06163831407368142, + 0.06187030825151116, + 0.061916252180966004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7048282486742837E-4, + "scoreError" : 6.2318940762426424E-6, + "scoreConfidence" : [ + 3.642509307911857E-4, + 3.7671471894367103E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6550937057065476E-4, + "50.0" : 3.705233868726101E-4, + "90.0" : 3.7574568171424677E-4, + "95.0" : 3.7574568171424677E-4, + "99.0" : 3.7574568171424677E-4, + "99.9" : 3.7574568171424677E-4, + "99.99" : 3.7574568171424677E-4, + "99.999" : 3.7574568171424677E-4, + "99.9999" : 3.7574568171424677E-4, + "100.0" : 3.7574568171424677E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7323567356169614E-4, + 3.737041859784811E-4, + 3.7574568171424677E-4 + ], + [ + 3.680468343111912E-4, + 3.6550937057065476E-4, + 3.677059834491752E-4 + ], + [ + 3.7350040214372075E-4, + 3.6637390520507943E-4, + 3.705233868726101E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11296045966158491, + "scoreError" : 0.0013462397991689833, + "scoreConfidence" : [ + 0.11161421986241593, + 0.11430669946075389 + ], + "scorePercentiles" : { + "0.0" : 0.11172170046922132, + "50.0" : 0.11303341444089024, + "90.0" : 0.11421999667626097, + "95.0" : 0.11421999667626097, + "99.0" : 0.11421999667626097, + "99.9" : 0.11421999667626097, + "99.99" : 0.11421999667626097, + "99.999" : 0.11421999667626097, + "99.9999" : 0.11421999667626097, + "100.0" : 0.11421999667626097 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11172170046922132, + 0.11229566329784844, + 0.1120552170702464 + ], + [ + 0.11342930688958962, + 0.11348786085545355, + 0.11421999667626097 + ], + [ + 0.11303341444089024, + 0.11294210606265953, + 0.1134588711920943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014211016977995226, + "scoreError" : 3.2450050098998363E-4, + "scoreConfidence" : [ + 0.013886516477005242, + 0.01453551747898521 + ], + "scorePercentiles" : { + "0.0" : 0.013995309737535233, + "50.0" : 0.014186597527308838, + "90.0" : 0.014487708502294099, + "95.0" : 0.014487708502294099, + "99.0" : 0.014487708502294099, + "99.9" : 0.014487708502294099, + "99.99" : 0.014487708502294099, + "99.999" : 0.014487708502294099, + "99.9999" : 0.014487708502294099, + "100.0" : 0.014487708502294099 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013995309737535233, + 0.014026710071339002, + 0.013999355323262316 + ], + [ + 0.0144319443107101, + 0.014421175412765184, + 0.014487708502294099 + ], + [ + 0.01418778617700471, + 0.01416256573973757, + 0.014186597527308838 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9747416122090438, + "scoreError" : 0.02771354829453182, + "scoreConfidence" : [ + 0.9470280639145119, + 1.0024551605035756 + ], + "scorePercentiles" : { + "0.0" : 0.9613563659521291, + "50.0" : 0.9654528933191736, + "90.0" : 0.9997473583924823, + "95.0" : 0.9997473583924823, + "99.0" : 0.9997473583924823, + "99.9" : 0.9997473583924823, + "99.99" : 0.9997473583924823, + "99.999" : 0.9997473583924823, + "99.9999" : 0.9997473583924823, + "100.0" : 0.9997473583924823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.99129063907613, + 0.9980391284431138, + 0.9997473583924823 + ], + [ + 0.9623278973248652, + 0.9623309266743649, + 0.9613563659521291 + ], + [ + 0.9682756677962819, + 0.9638536329028528, + 0.9654528933191736 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013104962445900434, + "scoreError" : 2.4980606674703063E-4, + "scoreConfidence" : [ + 0.012855156379153403, + 0.013354768512647466 + ], + "scorePercentiles" : { + "0.0" : 0.012970660892257726, + "50.0" : 0.013099514039777799, + "90.0" : 0.013209452283330604, + "95.0" : 0.013209452283330604, + "99.0" : 0.013209452283330604, + "99.9" : 0.013209452283330604, + "99.99" : 0.013209452283330604, + "99.999" : 0.013209452283330604, + "99.9999" : 0.013209452283330604, + "100.0" : 0.013209452283330604 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012970660892257726, + 0.013195432111113457, + 0.013209452283330604 + ], + [ + 0.013055201309145217, + 0.013098137045080067, + 0.01310089103447553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.604313844159822, + "scoreError" : 0.04534713389148014, + "scoreConfidence" : [ + 3.5589667102683418, + 3.649660978051302 + ], + "scorePercentiles" : { + "0.0" : 3.5937952629310344, + "50.0" : 3.598727486330935, + "90.0" : 3.636989528, + "95.0" : 3.636989528, + "99.0" : 3.636989528, + "99.9" : 3.636989528, + "99.99" : 3.636989528, + "99.999" : 3.636989528, + "99.9999" : 3.636989528, + "100.0" : 3.636989528 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5937952629310344, + 3.636989528, + 3.5994765553956833 + ], + [ + 3.597978417266187, + 3.597188201294033, + 3.6004551000719944 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.85706986103338, + "scoreError" : 0.05550092630841743, + "scoreConfidence" : [ + 2.8015689347249624, + 2.912570787341797 + ], + "scorePercentiles" : { + "0.0" : 2.8149184466647905, + "50.0" : 2.8451828332859175, + "90.0" : 2.9116465097525475, + "95.0" : 2.9116465097525475, + "99.0" : 2.9116465097525475, + "99.9" : 2.9116465097525475, + "99.99" : 2.9116465097525475, + "99.999" : 2.9116465097525475, + "99.9999" : 2.9116465097525475, + "100.0" : 2.9116465097525475 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8426617549744173, + 2.8451828332859175, + 2.875999301897642 + ], + [ + 2.8337422153584586, + 2.823628097120271, + 2.8149184466647905 + ], + [ + 2.9116465097525475, + 2.8714230410565604, + 2.8944265491898147 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.461447670875, + "scoreError" : 1.557823378352132, + "scoreConfidence" : [ + 4.903624292522868, + 8.019271049227132 + ], + "scorePercentiles" : { + "0.0" : 6.217415002, + "50.0" : 6.45516865225, + "90.0" : 6.718038377, + "95.0" : 6.718038377, + "99.0" : 6.718038377, + "99.9" : 6.718038377, + "99.99" : 6.718038377, + "99.999" : 6.718038377, + "99.9999" : 6.718038377, + "100.0" : 6.718038377 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.217415002, + 6.6115043885 + ], + [ + 6.298832916, + 6.718038377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18207746532125393, + "scoreError" : 0.013780054260598152, + "scoreConfidence" : [ + 0.1682974110606558, + 0.19585751958185207 + ], + "scorePercentiles" : { + "0.0" : 0.1745451103799766, + "50.0" : 0.17868691494684177, + "90.0" : 0.19307464954146153, + "95.0" : 0.19307464954146153, + "99.0" : 0.19307464954146153, + "99.9" : 0.19307464954146153, + "99.99" : 0.19307464954146153, + "99.999" : 0.19307464954146153, + "99.9999" : 0.19307464954146153, + "100.0" : 0.19307464954146153 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17909542611529988, + 0.17866306638915191, + 0.17868691494684177 + ], + [ + 0.19307464954146153, + 0.19237869708745334, + 0.1927737764626506 + ], + [ + 0.1748562180413002, + 0.17462332892714955, + 0.1745451103799766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3316795743404948, + "scoreError" : 0.009466290531291692, + "scoreConfidence" : [ + 0.3222132838092031, + 0.34114586487178644 + ], + "scorePercentiles" : { + "0.0" : 0.3243246460400856, + "50.0" : 0.3319771668824486, + "90.0" : 0.33880407477300445, + "95.0" : 0.33880407477300445, + "99.0" : 0.33880407477300445, + "99.9" : 0.33880407477300445, + "99.99" : 0.33880407477300445, + "99.999" : 0.33880407477300445, + "99.9999" : 0.33880407477300445, + "100.0" : 0.33880407477300445 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33880407477300445, + 0.33773891675109763, + 0.33748274277807777 + ], + [ + 0.3317106607071779, + 0.33204528193379157, + 0.3319771668824486 + ], + [ + 0.32661789894833104, + 0.3243246460400856, + 0.32441478025043796 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16295648200369642, + "scoreError" : 0.007355535448948819, + "scoreConfidence" : [ + 0.1556009465547476, + 0.17031201745264524 + ], + "scorePercentiles" : { + "0.0" : 0.15796330077242643, + "50.0" : 0.16256182123350021, + "90.0" : 0.16847007458009738, + "95.0" : 0.16847007458009738, + "99.0" : 0.16847007458009738, + "99.9" : 0.16847007458009738, + "99.99" : 0.16847007458009738, + "99.999" : 0.16847007458009738, + "99.9999" : 0.16847007458009738, + "100.0" : 0.16847007458009738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16803389792146253, + 0.1679515931275402, + 0.16847007458009738 + ], + [ + 0.16300649911163997, + 0.16256182123350021, + 0.16237046639822045 + ], + [ + 0.15825178851753385, + 0.15796330077242643, + 0.1579988963708467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38908629516224646, + "scoreError" : 0.015621116060515255, + "scoreConfidence" : [ + 0.3734651791017312, + 0.4047074112227617 + ], + "scorePercentiles" : { + "0.0" : 0.38194538574647674, + "50.0" : 0.38371984759419847, + "90.0" : 0.407430642534121, + "95.0" : 0.407430642534121, + "99.0" : 0.407430642534121, + "99.9" : 0.407430642534121, + "99.99" : 0.407430642534121, + "99.999" : 0.407430642534121, + "99.9999" : 0.407430642534121, + "100.0" : 0.407430642534121 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38246707507553446, + 0.38266204687380423, + 0.38258841646581737 + ], + [ + 0.407430642534121, + 0.39726210487427005, + 0.39757622363137596 + ], + [ + 0.38612491366462026, + 0.38371984759419847, + 0.38194538574647674 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15566721581851667, + "scoreError" : 0.0011478013215318824, + "scoreConfidence" : [ + 0.15451941449698478, + 0.15681501714004856 + ], + "scorePercentiles" : { + "0.0" : 0.15479193437040475, + "50.0" : 0.1555546226919906, + "90.0" : 0.1570862999010383, + "95.0" : 0.1570862999010383, + "99.0" : 0.1570862999010383, + "99.9" : 0.1570862999010383, + "99.99" : 0.1570862999010383, + "99.999" : 0.1570862999010383, + "99.9999" : 0.1570862999010383, + "100.0" : 0.1570862999010383 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.155355506555849, + 0.1555546226919906, + 0.15536562854612684 + ], + [ + 0.15559557033498778, + 0.15505680587341458, + 0.15479193437040475 + ], + [ + 0.1570862999010383, + 0.15608327922584672, + 0.15611529486699138 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04756821866980623, + "scoreError" : 9.502492797525353E-4, + "scoreConfidence" : [ + 0.04661796939005369, + 0.04851846794955876 + ], + "scorePercentiles" : { + "0.0" : 0.047061467059781356, + "50.0" : 0.047468389879906966, + "90.0" : 0.04879920123070016, + "95.0" : 0.04879920123070016, + "99.0" : 0.04879920123070016, + "99.9" : 0.04879920123070016, + "99.99" : 0.04879920123070016, + "99.999" : 0.04879920123070016, + "99.9999" : 0.04879920123070016, + "100.0" : 0.04879920123070016 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04879920123070016, + 0.047835660213726726, + 0.047892390603673285 + ], + [ + 0.047468389879906966, + 0.04710655139715858, + 0.04708556215686829 + ], + [ + 0.047673648736907846, + 0.04719109674953282, + 0.047061467059781356 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9338115.451061364, + "scoreError" : 294253.3030853776, + "scoreConfidence" : [ + 9043862.147975987, + 9632368.754146742 + ], + "scorePercentiles" : { + "0.0" : 9150383.46020128, + "50.0" : 9258928.046253469, + "90.0" : 9612853.083573487, + "95.0" : 9612853.083573487, + "99.0" : 9612853.083573487, + "99.9" : 9612853.083573487, + "99.99" : 9612853.083573487, + "99.999" : 9612853.083573487, + "99.9999" : 9612853.083573487, + "100.0" : 9612853.083573487 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9612853.083573487, + 9494145.622390892, + 9570389.524401914 + ], + [ + 9151741.862763038, + 9150383.46020128, + 9288248.306406686 + ], + [ + 9258868.16651249, + 9257480.987049028, + 9258928.046253469 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-04-29T01:27:59Z-abff4a3cbb87aeba79c6a22cec6f18c352fc08bd-jdk17.json b/performance-results/2025-04-29T01:27:59Z-abff4a3cbb87aeba79c6a22cec6f18c352fc08bd-jdk17.json new file mode 100644 index 0000000000..c9e384b10d --- /dev/null +++ b/performance-results/2025-04-29T01:27:59Z-abff4a3cbb87aeba79c6a22cec6f18c352fc08bd-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.41368755675915, + "scoreError" : 0.011577156508616154, + "scoreConfidence" : [ + 3.4021104002505336, + 3.425264713267766 + ], + "scorePercentiles" : { + "0.0" : 3.4124310628695893, + "50.0" : 3.412991278818737, + "90.0" : 3.4163366065295357, + "95.0" : 3.4163366065295357, + "99.0" : 3.4163366065295357, + "99.9" : 3.4163366065295357, + "99.99" : 3.4163366065295357, + "99.999" : 3.4163366065295357, + "99.9999" : 3.4163366065295357, + "100.0" : 3.4163366065295357 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.412813226359765, + 3.4131693312777087 + ], + [ + 3.4124310628695893, + 3.4163366065295357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7223860030654072, + "scoreError" : 0.010350866728441316, + "scoreConfidence" : [ + 1.712035136336966, + 1.7327368697938486 + ], + "scorePercentiles" : { + "0.0" : 1.7207239576746316, + "50.0" : 1.722483513543537, + "90.0" : 1.7238530274999235, + "95.0" : 1.7238530274999235, + "99.0" : 1.7238530274999235, + "99.9" : 1.7238530274999235, + "99.99" : 1.7238530274999235, + "99.999" : 1.7238530274999235, + "99.9999" : 1.7238530274999235, + "100.0" : 1.7238530274999235 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7207239576746316, + 1.7236590549622335 + ], + [ + 1.7213079721248403, + 1.7238530274999235 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.866003896362989, + "scoreError" : 0.0037517889106824867, + "scoreConfidence" : [ + 0.8622521074523065, + 0.8697556852736715 + ], + "scorePercentiles" : { + "0.0" : 0.8653165470889159, + "50.0" : 0.8659812831762026, + "90.0" : 0.8667364720106346, + "95.0" : 0.8667364720106346, + "99.0" : 0.8667364720106346, + "99.9" : 0.8667364720106346, + "99.99" : 0.8667364720106346, + "99.999" : 0.8667364720106346, + "99.9999" : 0.8667364720106346, + "100.0" : 0.8667364720106346 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8667364720106346, + 0.8659575389707542 + ], + [ + 0.8653165470889159, + 0.866005027381651 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.927719435913271, + "scoreError" : 0.2518439433608151, + "scoreConfidence" : [ + 15.675875492552457, + 16.179563379274086 + ], + "scorePercentiles" : { + "0.0" : 15.718224629279074, + "50.0" : 15.988244650145868, + "90.0" : 16.101281761616875, + "95.0" : 16.101281761616875, + "99.0" : 16.101281761616875, + "99.9" : 16.101281761616875, + "99.99" : 16.101281761616875, + "99.999" : 16.101281761616875, + "99.9999" : 16.101281761616875, + "100.0" : 16.101281761616875 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.744516962118057, + 15.718224629279074, + 15.744884329723428 + ], + [ + 15.988322848818745, + 15.988244650145868, + 15.9676454709409 + ], + [ + 16.101281761616875, + 16.067281870581326, + 16.02907239999518 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2620.2361096447444, + "scoreError" : 51.89020085549408, + "scoreConfidence" : [ + 2568.34590878925, + 2672.1263105002386 + ], + "scorePercentiles" : { + "0.0" : 2576.5388949462267, + "50.0" : 2631.725690292548, + "90.0" : 2655.985391852798, + "95.0" : 2655.985391852798, + "99.0" : 2655.985391852798, + "99.9" : 2655.985391852798, + "99.99" : 2655.985391852798, + "99.999" : 2655.985391852798, + "99.9999" : 2655.985391852798, + "100.0" : 2655.985391852798 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2632.94722052838, + 2631.725690292548, + 2629.3090371009102 + ], + [ + 2587.91087441954, + 2577.893162490877, + 2576.5388949462267 + ], + [ + 2655.985391852798, + 2642.7200589743707, + 2647.094656197051 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69241.14943496707, + "scoreError" : 1906.8418686539374, + "scoreConfidence" : [ + 67334.30756631313, + 71147.991303621 + ], + "scorePercentiles" : { + "0.0" : 68226.68138216344, + "50.0" : 69000.80238236197, + "90.0" : 71147.5302712457, + "95.0" : 71147.5302712457, + "99.0" : 71147.5302712457, + "99.9" : 71147.5302712457, + "99.99" : 71147.5302712457, + "99.999" : 71147.5302712457, + "99.9999" : 71147.5302712457, + "100.0" : 71147.5302712457 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69164.10201917295, + 71123.49922799463, + 71147.5302712457 + ], + [ + 68309.53933395917, + 68228.17762326672, + 68226.68138216344 + ], + [ + 69036.53690521562, + 69000.80238236197, + 68933.47576932357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.2792670791336, + "scoreError" : 3.5350193767648963, + "scoreConfidence" : [ + 338.7442477023687, + 345.8142864558985 + ], + "scorePercentiles" : { + "0.0" : 339.88258625164644, + "50.0" : 342.3836016058778, + "90.0" : 347.12623720195, + "95.0" : 347.12623720195, + "99.0" : 347.12623720195, + "99.9" : 347.12623720195, + "99.99" : 347.12623720195, + "99.999" : 347.12623720195, + "99.9999" : 347.12623720195, + "100.0" : 347.12623720195 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 342.5086562637084, + 342.3836016058778, + 342.5035533284069 + ], + [ + 340.4531462932821, + 339.88258625164644, + 340.67189221825595 + ], + [ + 347.12623720195, + 342.6374857222025, + 342.3462448268719 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.16111747920324632, + "scoreError" : 0.0538676088832617, + "scoreConfidence" : [ + 0.10724987031998462, + 0.214985088086508 + ], + "scorePercentiles" : { + "0.0" : 0.15090960650630372, + "50.0" : 0.16161780119251848, + "90.0" : 0.17032470792164467, + "95.0" : 0.17032470792164467, + "99.0" : 0.17032470792164467, + "99.9" : 0.17032470792164467, + "99.99" : 0.17032470792164467, + "99.999" : 0.17032470792164467, + "99.9999" : 0.17032470792164467, + "100.0" : 0.17032470792164467 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.17032470792164467, + 0.16469967760454798 + ], + [ + 0.15853592478048897, + 0.15090960650630372 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.10938930134132, + "scoreError" : 3.6282468011070375, + "scoreConfidence" : [ + 104.48114250023428, + 111.73763610244836 + ], + "scorePercentiles" : { + "0.0" : 105.30628681911303, + "50.0" : 108.78253762875588, + "90.0" : 110.65151009607298, + "95.0" : 110.65151009607298, + "99.0" : 110.65151009607298, + "99.9" : 110.65151009607298, + "99.99" : 110.65151009607298, + "99.999" : 110.65151009607298, + "99.9999" : 110.65151009607298, + "100.0" : 110.65151009607298 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.97352903064439, + 109.88250695762211, + 110.65151009607298 + ], + [ + 108.71518504389563, + 108.78253762875588, + 108.91094858170385 + ], + [ + 105.30628681911303, + 105.33335102787056, + 105.42864852639354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06258311150804946, + "scoreError" : 5.269476101376093E-4, + "scoreConfidence" : [ + 0.062056163897911853, + 0.06311005911818707 + ], + "scorePercentiles" : { + "0.0" : 0.0621607190755613, + "50.0" : 0.06271106371344003, + "90.0" : 0.06301436140797499, + "95.0" : 0.06301436140797499, + "99.0" : 0.06301436140797499, + "99.9" : 0.06301436140797499, + "99.99" : 0.06301436140797499, + "99.999" : 0.06301436140797499, + "99.9999" : 0.06301436140797499, + "100.0" : 0.06301436140797499 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06217967207620611, + 0.062247000311229796, + 0.0621607190755613 + ], + [ + 0.06257053132664298, + 0.06280703970606707, + 0.06301436140797499 + ], + [ + 0.06271106371344003, + 0.06273846189317038, + 0.06281915406215254 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7221581397684265E-4, + "scoreError" : 1.177369956265137E-5, + "scoreConfidence" : [ + 3.6044211441419127E-4, + 3.83989513539494E-4 + ], + "scorePercentiles" : { + "0.0" : 3.651943797713429E-4, + "50.0" : 3.684511197112292E-4, + "90.0" : 3.8206138252579056E-4, + "95.0" : 3.8206138252579056E-4, + "99.0" : 3.8206138252579056E-4, + "99.9" : 3.8206138252579056E-4, + "99.99" : 3.8206138252579056E-4, + "99.999" : 3.8206138252579056E-4, + "99.9999" : 3.8206138252579056E-4, + "100.0" : 3.8206138252579056E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.667970103236022E-4, + 3.651943797713429E-4, + 3.6783979720932E-4 + ], + [ + 3.805402051279124E-4, + 3.8165769840827607E-4, + 3.8206138252579056E-4 + ], + [ + 3.6926042160078705E-4, + 3.684511197112292E-4, + 3.681403111133232E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10977070758028086, + "scoreError" : 0.0013676405767257937, + "scoreConfidence" : [ + 0.10840306700355506, + 0.11113834815700666 + ], + "scorePercentiles" : { + "0.0" : 0.10854249681978032, + "50.0" : 0.11023640924423475, + "90.0" : 0.11051916565359622, + "95.0" : 0.11051916565359622, + "99.0" : 0.11051916565359622, + "99.9" : 0.11051916565359622, + "99.99" : 0.11051916565359622, + "99.999" : 0.11051916565359622, + "99.9999" : 0.11051916565359622, + "100.0" : 0.11051916565359622 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11010809666266612, + 0.11031526147532845, + 0.11023640924423475 + ], + [ + 0.10854249681978032, + 0.10878423256497002, + 0.10877439167890357 + ], + [ + 0.11023944485354911, + 0.11041686926949916, + 0.11051916565359622 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01408694479338862, + "scoreError" : 1.0565525131245779E-4, + "scoreConfidence" : [ + 0.013981289542076161, + 0.014192600044701078 + ], + "scorePercentiles" : { + "0.0" : 0.013995514641236181, + "50.0" : 0.014123541616587599, + "90.0" : 0.014144480601811319, + "95.0" : 0.014144480601811319, + "99.0" : 0.014144480601811319, + "99.9" : 0.014144480601811319, + "99.99" : 0.014144480601811319, + "99.999" : 0.014144480601811319, + "99.9999" : 0.014144480601811319, + "100.0" : 0.014144480601811319 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014125111797425873, + 0.014123541616587599, + 0.014107840634280193 + ], + [ + 0.013995514641236181, + 0.014009519051288158, + 0.01400795923450177 + ], + [ + 0.014136497413054602, + 0.01413203815031189, + 0.014144480601811319 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9939279989700756, + "scoreError" : 0.020666613290608375, + "scoreConfidence" : [ + 0.9732613856794672, + 1.014594612260684 + ], + "scorePercentiles" : { + "0.0" : 0.979461177668952, + "50.0" : 0.9925874555831266, + "90.0" : 1.0138561537915654, + "95.0" : 1.0138561537915654, + "99.0" : 1.0138561537915654, + "99.9" : 1.0138561537915654, + "99.99" : 1.0138561537915654, + "99.999" : 1.0138561537915654, + "99.9999" : 1.0138561537915654, + "100.0" : 1.0138561537915654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9872934017178399, + 1.012256402631579, + 1.0138561537915654 + ], + [ + 0.9864056460840402, + 0.9957079935284747, + 0.996353598684866 + ], + [ + 0.9814301610402355, + 0.979461177668952, + 0.9925874555831266 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013255854812593525, + "scoreError" : 2.4951556212009034E-4, + "scoreConfidence" : [ + 0.013006339250473434, + 0.013505370374713615 + ], + "scorePercentiles" : { + "0.0" : 0.013096687724766557, + "50.0" : 0.013276384707824045, + "90.0" : 0.01332916270799678, + "95.0" : 0.01332916270799678, + "99.0" : 0.01332916270799678, + "99.9" : 0.01332916270799678, + "99.99" : 0.01332916270799678, + "99.999" : 0.01332916270799678, + "99.9999" : 0.01332916270799678, + "100.0" : 0.01332916270799678 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01332916270799678, + 0.013321451000817918, + 0.013317007143066405 + ], + [ + 0.013096687724766557, + 0.013235058026331811, + 0.013235762272581683 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8869303000430793, + "scoreError" : 0.031746190577912885, + "scoreConfidence" : [ + 3.855184109465166, + 3.9186764906209923 + ], + "scorePercentiles" : { + "0.0" : 3.873573435321456, + "50.0" : 3.8883467326180607, + "90.0" : 3.899414849571317, + "95.0" : 3.899414849571317, + "99.0" : 3.899414849571317, + "99.9" : 3.899414849571317, + "99.99" : 3.899414849571317, + "99.999" : 3.899414849571317, + "99.9999" : 3.899414849571317, + "100.0" : 3.899414849571317 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.873573435321456, + 3.8751488048024787, + 3.8825463905279505 + ], + [ + 3.899414849571317, + 3.894147074708171, + 3.8967512453271027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9541461609155713, + "scoreError" : 0.038795008077040734, + "scoreConfidence" : [ + 2.9153511528385305, + 2.992941168992612 + ], + "scorePercentiles" : { + "0.0" : 2.914105585664336, + "50.0" : 2.9453822176089517, + "90.0" : 2.986228295013437, + "95.0" : 2.986228295013437, + "99.0" : 2.986228295013437, + "99.9" : 2.986228295013437, + "99.99" : 2.986228295013437, + "99.999" : 2.986228295013437, + "99.9999" : 2.986228295013437, + "100.0" : 2.986228295013437 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.973226924197384, + 2.986228295013437, + 2.97903182365207 + ], + [ + 2.9640392243627742, + 2.9418444729411766, + 2.939128399059653 + ], + [ + 2.914105585664336, + 2.944328505740359, + 2.9453822176089517 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.671671494625, + "scoreError" : 1.427425309256216, + "scoreConfidence" : [ + 5.244246185368785, + 8.099096803881217 + ], + "scorePercentiles" : { + "0.0" : 6.3983953535, + "50.0" : 6.67918252625, + "90.0" : 6.9299255725, + "95.0" : 6.9299255725, + "99.0" : 6.9299255725, + "99.9" : 6.9299255725, + "99.99" : 6.9299255725, + "99.999" : 6.9299255725, + "99.9999" : 6.9299255725, + "100.0" : 6.9299255725 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.9299255725, + 6.728663891 + ], + [ + 6.3983953535, + 6.6297011615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17529723927871282, + "scoreError" : 0.0031816027588813787, + "scoreConfidence" : [ + 0.17211563651983144, + 0.1784788420375942 + ], + "scorePercentiles" : { + "0.0" : 0.172653693651698, + "50.0" : 0.17636829038288565, + "90.0" : 0.17688169380571672, + "95.0" : 0.17688169380571672, + "99.0" : 0.17688169380571672, + "99.9" : 0.17688169380571672, + "99.99" : 0.17688169380571672, + "99.999" : 0.17688169380571672, + "99.9999" : 0.17688169380571672, + "100.0" : 0.17688169380571672 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17289628023858922, + 0.172653693651698, + 0.17283391348081575 + ], + [ + 0.17636829038288565, + 0.1761232168369144, + 0.1763793540398963 + ], + [ + 0.1768444755252175, + 0.17669423554668173, + 0.17688169380571672 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3241345741846201, + "scoreError" : 0.002621936054513108, + "scoreConfidence" : [ + 0.321512638130107, + 0.3267565102391332 + ], + "scorePercentiles" : { + "0.0" : 0.32175236955052927, + "50.0" : 0.32450469883505856, + "90.0" : 0.32644549226349806, + "95.0" : 0.32644549226349806, + "99.0" : 0.32644549226349806, + "99.9" : 0.32644549226349806, + "99.99" : 0.32644549226349806, + "99.999" : 0.32644549226349806, + "99.9999" : 0.32644549226349806, + "100.0" : 0.32644549226349806 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32410530303030305, + 0.32450469883505856, + 0.3245193459890966 + ], + [ + 0.32644549226349806, + 0.3253919584811115, + 0.3252804277907885 + ], + [ + 0.32315627156983134, + 0.32175236955052927, + 0.3220553001513639 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16538222438793435, + "scoreError" : 0.003477002178493912, + "scoreConfidence" : [ + 0.16190522220944042, + 0.16885922656642827 + ], + "scorePercentiles" : { + "0.0" : 0.16347978162854948, + "50.0" : 0.16441667545172056, + "90.0" : 0.16834960779098346, + "95.0" : 0.16834960779098346, + "99.0" : 0.16834960779098346, + "99.9" : 0.16834960779098346, + "99.99" : 0.16834960779098346, + "99.999" : 0.16834960779098346, + "99.9999" : 0.16834960779098346, + "100.0" : 0.16834960779098346 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16834960779098346, + 0.16795209213664306, + 0.16797631347319975 + ], + [ + 0.16347978162854948, + 0.16370579234194416, + 0.16371023036752066 + ], + [ + 0.16441667545172056, + 0.16466946952856132, + 0.16418005677228698 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38983976775589047, + "scoreError" : 0.0029368725353503514, + "scoreConfidence" : [ + 0.3869028952205401, + 0.3927766402912408 + ], + "scorePercentiles" : { + "0.0" : 0.38760766441860467, + "50.0" : 0.3900748257986504, + "90.0" : 0.392181996156712, + "95.0" : 0.392181996156712, + "99.0" : 0.392181996156712, + "99.9" : 0.392181996156712, + "99.99" : 0.392181996156712, + "99.999" : 0.392181996156712, + "99.9999" : 0.392181996156712, + "100.0" : 0.392181996156712 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.391200565309236, + 0.3900748257986504, + 0.3896598868843516 + ], + [ + 0.38780298379028194, + 0.38760766441860467, + 0.3877373259276492 + ], + [ + 0.39129563012090623, + 0.392181996156712, + 0.39099703139662184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15630790531466518, + "scoreError" : 0.003333830035347559, + "scoreConfidence" : [ + 0.1529740752793176, + 0.15964173535001275 + ], + "scorePercentiles" : { + "0.0" : 0.1542653814886232, + "50.0" : 0.1556865988043529, + "90.0" : 0.1589805362468602, + "95.0" : 0.1589805362468602, + "99.0" : 0.1589805362468602, + "99.9" : 0.1589805362468602, + "99.99" : 0.1589805362468602, + "99.999" : 0.1589805362468602, + "99.9999" : 0.1589805362468602, + "100.0" : 0.1589805362468602 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15888887718266895, + 0.1589805362468602, + 0.15867289492891598 + ], + [ + 0.1558002886143396, + 0.1556865988043529, + 0.155496769541758 + ], + [ + 0.1544361401942767, + 0.1542653814886232, + 0.154543660830191 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04772426326987242, + "scoreError" : 9.827650192634106E-4, + "scoreConfidence" : [ + 0.046741498250609005, + 0.04870702828913583 + ], + "scorePercentiles" : { + "0.0" : 0.04705741660823777, + "50.0" : 0.04782632825584788, + "90.0" : 0.04869421438310139, + "95.0" : 0.04869421438310139, + "99.0" : 0.04869421438310139, + "99.9" : 0.04869421438310139, + "99.99" : 0.04869421438310139, + "99.999" : 0.04869421438310139, + "99.9999" : 0.04869421438310139, + "100.0" : 0.04869421438310139 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04782632825584788, + 0.047424349873141584, + 0.047841863523501976 + ], + [ + 0.04869421438310139, + 0.04827508779187928, + 0.04816352189241387 + ], + [ + 0.0471654166057456, + 0.0470701704949824, + 0.04705741660823777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9401129.078227697, + "scoreError" : 284192.2396809549, + "scoreConfidence" : [ + 9116936.838546742, + 9685321.317908652 + ], + "scorePercentiles" : { + "0.0" : 9196445.55514706, + "50.0" : 9416180.048918156, + "90.0" : 9650362.570877532, + "95.0" : 9650362.570877532, + "99.0" : 9650362.570877532, + "99.9" : 9650362.570877532, + "99.99" : 9650362.570877532, + "99.999" : 9650362.570877532, + "99.9999" : 9650362.570877532, + "100.0" : 9650362.570877532 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9196445.55514706, + 9211536.816758748, + 9202149.348666053 + ], + [ + 9650362.570877532, + 9586731.591954023, + 9519164.273073263 + ], + [ + 9400970.309210526, + 9426621.189443922, + 9416180.048918156 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-01T11:19:28Z-5853d24aabb5d0798db3489ce7cfd56563327b47-jdk17.json b/performance-results/2025-05-01T11:19:28Z-5853d24aabb5d0798db3489ce7cfd56563327b47-jdk17.json new file mode 100644 index 0000000000..d17a2e25dd --- /dev/null +++ b/performance-results/2025-05-01T11:19:28Z-5853d24aabb5d0798db3489ce7cfd56563327b47-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4331544089953354, + "scoreError" : 0.03177968229117539, + "scoreConfidence" : [ + 3.40137472670416, + 3.4649340912865108 + ], + "scorePercentiles" : { + "0.0" : 3.4277164851193134, + "50.0" : 3.4332792272710844, + "90.0" : 3.438342696319859, + "95.0" : 3.438342696319859, + "99.0" : 3.438342696319859, + "99.9" : 3.438342696319859, + "99.99" : 3.438342696319859, + "99.999" : 3.438342696319859, + "99.9999" : 3.438342696319859, + "100.0" : 3.438342696319859 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4277164851193134, + 3.4304474494937147 + ], + [ + 3.4361110050484545, + 3.438342696319859 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.731349118324024, + "scoreError" : 0.01821960210623778, + "scoreConfidence" : [ + 1.7131295162177862, + 1.7495687204302617 + ], + "scorePercentiles" : { + "0.0" : 1.727723323161049, + "50.0" : 1.7318234320563273, + "90.0" : 1.7340262860223925, + "95.0" : 1.7340262860223925, + "99.0" : 1.7340262860223925, + "99.9" : 1.7340262860223925, + "99.99" : 1.7340262860223925, + "99.999" : 1.7340262860223925, + "99.9999" : 1.7340262860223925, + "100.0" : 1.7340262860223925 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.727723323161049, + 1.730581410103184 + ], + [ + 1.7330654540094705, + 1.7340262860223925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8683275840915288, + "scoreError" : 0.009787509044077934, + "scoreConfidence" : [ + 0.8585400750474509, + 0.8781150931356067 + ], + "scorePercentiles" : { + "0.0" : 0.8675290163998897, + "50.0" : 0.8675913449020631, + "90.0" : 0.8705986301620992, + "95.0" : 0.8705986301620992, + "99.0" : 0.8705986301620992, + "99.9" : 0.8705986301620992, + "99.99" : 0.8705986301620992, + "99.999" : 0.8705986301620992, + "99.9999" : 0.8705986301620992, + "100.0" : 0.8705986301620992 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8675290163998897, + 0.8675536902217257 + ], + [ + 0.8676289995824007, + 0.8705986301620992 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.301823621536087, + "scoreError" : 0.16475613077645887, + "scoreConfidence" : [ + 16.137067490759627, + 16.466579752312548 + ], + "scorePercentiles" : { + "0.0" : 16.1660826243866, + "50.0" : 16.343464106610817, + "90.0" : 16.3901176261365, + "95.0" : 16.3901176261365, + "99.0" : 16.3901176261365, + "99.9" : 16.3901176261365, + "99.99" : 16.3901176261365, + "99.999" : 16.3901176261365, + "99.9999" : 16.3901176261365, + "100.0" : 16.3901176261365 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.379685416293235, + 16.343181865917316, + 16.343464106610817 + ], + [ + 16.1660826243866, + 16.181717489867033, + 16.170711088901847 + ], + [ + 16.365197369399212, + 16.3901176261365, + 16.376255006312228 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2727.7510559201937, + "scoreError" : 68.74168751625591, + "scoreConfidence" : [ + 2659.009368403938, + 2796.4927434364495 + ], + "scorePercentiles" : { + "0.0" : 2690.775685817979, + "50.0" : 2704.363055657605, + "90.0" : 2783.719272858419, + "95.0" : 2783.719272858419, + "99.0" : 2783.719272858419, + "99.9" : 2783.719272858419, + "99.99" : 2783.719272858419, + "99.999" : 2783.719272858419, + "99.9999" : 2783.719272858419, + "100.0" : 2783.719272858419 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2783.719272858419, + 2779.225474967515, + 2782.3951254669596 + ], + [ + 2698.3864458398625, + 2700.430783644288, + 2690.775685817979 + ], + [ + 2711.6347176328904, + 2698.8289413962284, + 2704.363055657605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69963.05784238216, + "scoreError" : 1755.5857351594716, + "scoreConfidence" : [ + 68207.47210722268, + 71718.64357754163 + ], + "scorePercentiles" : { + "0.0" : 69096.72488306968, + "50.0" : 69423.78823458655, + "90.0" : 71378.85768487239, + "95.0" : 71378.85768487239, + "99.0" : 71378.85768487239, + "99.9" : 71378.85768487239, + "99.99" : 71378.85768487239, + "99.999" : 71378.85768487239, + "99.9999" : 71378.85768487239, + "100.0" : 71378.85768487239 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69108.39910967356, + 69124.6150692585, + 69096.72488306968 + ], + [ + 69473.63631105285, + 69411.86763370689, + 69423.78823458655 + ], + [ + 71315.8989592746, + 71378.85768487239, + 71333.73269594439 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.8189419846196, + "scoreError" : 4.117881347698783, + "scoreConfidence" : [ + 353.70106063692083, + 361.93682333231834 + ], + "scorePercentiles" : { + "0.0" : 354.3381288421538, + "50.0" : 358.4459490750687, + "90.0" : 360.571233302493, + "95.0" : 360.571233302493, + "99.0" : 360.571233302493, + "99.9" : 360.571233302493, + "99.99" : 360.571233302493, + "99.999" : 360.571233302493, + "99.9999" : 360.571233302493, + "100.0" : 360.571233302493 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 358.4459490750687, + 357.93090376557893, + 358.5789424874603 + ], + [ + 360.1331119729269, + 360.3222092455371, + 360.571233302493 + ], + [ + 354.3381288421538, + 354.7694417567496, + 355.28055741360777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1628404468743436, + "scoreError" : 0.0180067282313712, + "scoreConfidence" : [ + 0.1448337186429724, + 0.1808471751057148 + ], + "scorePercentiles" : { + "0.0" : 0.16013101812294775, + "50.0" : 0.1625851642098328, + "90.0" : 0.16606044095476102, + "95.0" : 0.16606044095476102, + "99.0" : 0.16606044095476102, + "99.9" : 0.16606044095476102, + "99.99" : 0.16606044095476102, + "99.999" : 0.16606044095476102, + "99.9999" : 0.16606044095476102, + "100.0" : 0.16606044095476102 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16423668838661862, + 0.16013101812294775 + ], + [ + 0.16606044095476102, + 0.16093364003304697 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.00819460386987, + "scoreError" : 2.1012401340495, + "scoreConfidence" : [ + 104.90695446982036, + 109.10943473791937 + ], + "scorePercentiles" : { + "0.0" : 105.46958941538895, + "50.0" : 107.22162049147911, + "90.0" : 108.76068371977975, + "95.0" : 108.76068371977975, + "99.0" : 108.76068371977975, + "99.9" : 108.76068371977975, + "99.99" : 108.76068371977975, + "99.999" : 108.76068371977975, + "99.9999" : 108.76068371977975, + "100.0" : 108.76068371977975 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.8106626620419, + 108.76068371977975, + 108.34220607443652 + ], + [ + 107.1874512113681, + 107.2654229801758, + 107.22162049147911 + ], + [ + 105.46958941538895, + 105.48022985106704, + 105.53588502909172 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061311000146145794, + "scoreError" : 4.3159681687185056E-4, + "scoreConfidence" : [ + 0.06087940332927395, + 0.06174259696301764 + ], + "scorePercentiles" : { + "0.0" : 0.060954215841765205, + "50.0" : 0.06127715635282944, + "90.0" : 0.06168272162322202, + "95.0" : 0.06168272162322202, + "99.0" : 0.06168272162322202, + "99.9" : 0.06168272162322202, + "99.99" : 0.06168272162322202, + "99.999" : 0.06168272162322202, + "99.9999" : 0.06168272162322202, + "100.0" : 0.06168272162322202 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06096009053668528, + 0.06125375765352999, + 0.060954215841765205 + ], + [ + 0.061524612443782725, + 0.06160351737499307, + 0.06168272162322202 + ], + [ + 0.06127715635282944, + 0.06125795435138165, + 0.06128497513712272 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6496866033435037E-4, + "scoreError" : 1.676735138638407E-5, + "scoreConfidence" : [ + 3.482013089479663E-4, + 3.8173601172073444E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5160092519147956E-4, + "50.0" : 3.676415861598922E-4, + "90.0" : 3.7610264764731654E-4, + "95.0" : 3.7610264764731654E-4, + "99.0" : 3.7610264764731654E-4, + "99.9" : 3.7610264764731654E-4, + "99.99" : 3.7610264764731654E-4, + "99.999" : 3.7610264764731654E-4, + "99.9999" : 3.7610264764731654E-4, + "100.0" : 3.7610264764731654E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.741616669267054E-4, + 3.7406218729312316E-4, + 3.7610264764731654E-4 + ], + [ + 3.5160092519147956E-4, + 3.5286637087208225E-4, + 3.5249021028154576E-4 + ], + [ + 3.681727805733994E-4, + 3.6761956806360914E-4, + 3.676415861598922E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10678573452911717, + "scoreError" : 0.0032009021750539026, + "scoreConfidence" : [ + 0.10358483235406327, + 0.10998663670417108 + ], + "scorePercentiles" : { + "0.0" : 0.1045414161430946, + "50.0" : 0.10652317767741111, + "90.0" : 0.10908806842949242, + "95.0" : 0.10908806842949242, + "99.0" : 0.10908806842949242, + "99.9" : 0.10908806842949242, + "99.99" : 0.10908806842949242, + "99.999" : 0.10908806842949242, + "99.9999" : 0.10908806842949242, + "100.0" : 0.10908806842949242 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10905503311958821, + 0.10908806842949242, + 0.10906078671450695 + ], + [ + 0.10682793524196132, + 0.10652317767741111, + 0.10644720485390388 + ], + [ + 0.1045414161430946, + 0.10480142245860406, + 0.10472656612349196 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014037120829859633, + "scoreError" : 7.708600708813382E-5, + "scoreConfidence" : [ + 0.013960034822771498, + 0.014114206836947767 + ], + "scorePercentiles" : { + "0.0" : 0.013974094751669186, + "50.0" : 0.01404556190860098, + "90.0" : 0.014089196923800883, + "95.0" : 0.014089196923800883, + "99.0" : 0.014089196923800883, + "99.9" : 0.014089196923800883, + "99.99" : 0.014089196923800883, + "99.999" : 0.014089196923800883, + "99.9999" : 0.014089196923800883, + "100.0" : 0.014089196923800883 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014089196923800883, + 0.014078045303976293, + 0.014077113184174149 + ], + [ + 0.013983831954077637, + 0.013974094751669186, + 0.013979940247637768 + ], + [ + 0.01404556190860098, + 0.014062676414793189, + 0.014043626780006629 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9639536792613548, + "scoreError" : 0.015245548974456803, + "scoreConfidence" : [ + 0.9487081302868979, + 0.9791992282358116 + ], + "scorePercentiles" : { + "0.0" : 0.9548244862516708, + "50.0" : 0.9588513089165868, + "90.0" : 0.9772749397048763, + "95.0" : 0.9772749397048763, + "99.0" : 0.9772749397048763, + "99.9" : 0.9772749397048763, + "99.99" : 0.9772749397048763, + "99.999" : 0.9772749397048763, + "99.9999" : 0.9772749397048763, + "100.0" : 0.9772749397048763 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9738222115103711, + 0.9762625546661461, + 0.9772749397048763 + ], + [ + 0.9588035496644295, + 0.9607213345182054, + 0.9548244862516708 + ], + [ + 0.956337170125275, + 0.9588513089165868, + 0.958685557994632 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01289778096567619, + "scoreError" : 3.6453540731185274E-4, + "scoreConfidence" : [ + 0.012533245558364336, + 0.013262316372988043 + ], + "scorePercentiles" : { + "0.0" : 0.012703689044095976, + "50.0" : 0.012933667693141103, + "90.0" : 0.013015965068605478, + "95.0" : 0.013015965068605478, + "99.0" : 0.013015965068605478, + "99.9" : 0.013015965068605478, + "99.99" : 0.013015965068605478, + "99.999" : 0.013015965068605478, + "99.9999" : 0.013015965068605478, + "100.0" : 0.013015965068605478 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013005510625237344, + 0.012996688934636088, + 0.013015965068605478 + ], + [ + 0.012703689044095976, + 0.012870646451646118, + 0.012794185669836136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.674057934612236, + "scoreError" : 0.12087799342201626, + "scoreConfidence" : [ + 3.5531799411902196, + 3.7949359280342523 + ], + "scorePercentiles" : { + "0.0" : 3.617333802603037, + "50.0" : 3.6772550161617636, + "90.0" : 3.7151268610698365, + "95.0" : 3.7151268610698365, + "99.0" : 3.7151268610698365, + "99.9" : 3.7151268610698365, + "99.99" : 3.7151268610698365, + "99.999" : 3.7151268610698365, + "99.9999" : 3.7151268610698365, + "100.0" : 3.7151268610698365 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.706195300740741, + 3.7151268610698365, + 3.7150756567607726 + ], + [ + 3.617333802603037, + 3.6483147315827864, + 3.6423012549162417 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8091278993146394, + "scoreError" : 0.030001576195461992, + "scoreConfidence" : [ + 2.7791263231191774, + 2.8391294755101013 + ], + "scorePercentiles" : { + "0.0" : 2.782211942141864, + "50.0" : 2.8196893963913165, + "90.0" : 2.8240205011293056, + "95.0" : 2.8240205011293056, + "99.0" : 2.8240205011293056, + "99.9" : 2.8240205011293056, + "99.99" : 2.8240205011293056, + "99.999" : 2.8240205011293056, + "99.9999" : 2.8240205011293056, + "100.0" : 2.8240205011293056 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8226192842224105, + 2.8196893963913165, + 2.8240205011293056 + ], + [ + 2.7931045322535604, + 2.7824341863699584, + 2.782211942141864 + ], + [ + 2.815133274134534, + 2.8217641343115125, + 2.821173842877292 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.1550624795, + "scoreError" : 1.3772840632565821, + "scoreConfidence" : [ + 4.777778416243418, + 7.532346542756581 + ], + "scorePercentiles" : { + "0.0" : 5.93547497, + "50.0" : 6.12984728875, + "90.0" : 6.4250803705, + "95.0" : 6.4250803705, + "99.0" : 6.4250803705, + "99.9" : 6.4250803705, + "99.99" : 6.4250803705, + "99.999" : 6.4250803705, + "99.9999" : 6.4250803705, + "100.0" : 6.4250803705 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.046536982, + 6.2131575955 + ], + [ + 5.93547497, + 6.4250803705 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17366173452942113, + "scoreError" : 0.007676119542253908, + "scoreConfidence" : [ + 0.1659856149871672, + 0.18133785407167505 + ], + "scorePercentiles" : { + "0.0" : 0.1697848606451613, + "50.0" : 0.17142281736834888, + "90.0" : 0.17983730943945905, + "95.0" : 0.17983730943945905, + "99.0" : 0.17983730943945905, + "99.9" : 0.17983730943945905, + "99.99" : 0.17983730943945905, + "99.999" : 0.17983730943945905, + "99.9999" : 0.17983730943945905, + "100.0" : 0.17983730943945905 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1697848606451613, + 0.1699338216252039, + 0.16989955813795446 + ], + [ + 0.17983730943945905, + 0.17953908820466785, + 0.17967764846557424 + ], + [ + 0.17146787827712145, + 0.1713926286012991, + 0.17142281736834888 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3303097706864887, + "scoreError" : 0.0018546913437811911, + "scoreConfidence" : [ + 0.3284550793427075, + 0.3321644620302699 + ], + "scorePercentiles" : { + "0.0" : 0.3290259291636507, + "50.0" : 0.3301188618492721, + "90.0" : 0.33182816315492586, + "95.0" : 0.33182816315492586, + "99.0" : 0.33182816315492586, + "99.9" : 0.33182816315492586, + "99.99" : 0.33182816315492586, + "99.999" : 0.33182816315492586, + "99.9999" : 0.33182816315492586, + "100.0" : 0.33182816315492586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3301188618492721, + 0.3299398862714045, + 0.32923145221399175 + ], + [ + 0.33028759861945967, + 0.32920082694143593, + 0.3290259291636507 + ], + [ + 0.3316493930620502, + 0.33150582490220776, + 0.33182816315492586 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16833527674216875, + "scoreError" : 0.010108659288660655, + "scoreConfidence" : [ + 0.1582266174535081, + 0.1784439360308294 + ], + "scorePercentiles" : { + "0.0" : 0.16105653531107567, + "50.0" : 0.16847778344228048, + "90.0" : 0.1756378751778281, + "95.0" : 0.1756378751778281, + "99.0" : 0.1756378751778281, + "99.9" : 0.1756378751778281, + "99.99" : 0.1756378751778281, + "99.999" : 0.1756378751778281, + "99.9999" : 0.1756378751778281, + "100.0" : 0.1756378751778281 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16799141508197823, + 0.16849116833751748, + 0.16847778344228048 + ], + [ + 0.1756378751778281, + 0.17518834003118267, + 0.17502095011988728 + ], + [ + 0.16158091387946358, + 0.16157250929830513, + 0.16105653531107567 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3886825167716063, + "scoreError" : 0.0136787565561771, + "scoreConfidence" : [ + 0.3750037602154292, + 0.40236127332778343 + ], + "scorePercentiles" : { + "0.0" : 0.38137406479292196, + "50.0" : 0.38508448415418384, + "90.0" : 0.40037342581471697, + "95.0" : 0.40037342581471697, + "99.0" : 0.40037342581471697, + "99.9" : 0.40037342581471697, + "99.99" : 0.40037342581471697, + "99.999" : 0.40037342581471697, + "99.9999" : 0.40037342581471697, + "100.0" : 0.40037342581471697 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38508448415418384, + 0.38286303518376724, + 0.38205842162368675 + ], + [ + 0.40037342581471697, + 0.39901259314527393, + 0.39812480484891916 + ], + [ + 0.3878287897614892, + 0.38142303161949803, + 0.38137406479292196 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15697485930277733, + "scoreError" : 0.0021114974464798548, + "scoreConfidence" : [ + 0.15486336185629748, + 0.15908635674925717 + ], + "scorePercentiles" : { + "0.0" : 0.1557953886396211, + "50.0" : 0.1569588983394023, + "90.0" : 0.15956860461145683, + "95.0" : 0.15956860461145683, + "99.0" : 0.15956860461145683, + "99.9" : 0.15956860461145683, + "99.99" : 0.15956860461145683, + "99.999" : 0.15956860461145683, + "99.9999" : 0.15956860461145683, + "100.0" : 0.15956860461145683 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1569588983394023, + 0.1557953886396211, + 0.15597408592507098 + ], + [ + 0.15710531805256625, + 0.156042505352183, + 0.15583136555872407 + ], + [ + 0.15956860461145683, + 0.1579921334049545, + 0.15750543384101684 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04611423230893656, + "scoreError" : 0.001335790267434904, + "scoreConfidence" : [ + 0.04477844204150166, + 0.047450022576371466 + ], + "scorePercentiles" : { + "0.0" : 0.045298149155429124, + "50.0" : 0.04593333518441964, + "90.0" : 0.0471357658138351, + "95.0" : 0.0471357658138351, + "99.0" : 0.0471357658138351, + "99.9" : 0.0471357658138351, + "99.99" : 0.0471357658138351, + "99.999" : 0.0471357658138351, + "99.9999" : 0.0471357658138351, + "100.0" : 0.0471357658138351 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045300807850509626, + 0.04531304694367665, + 0.045298149155429124 + ], + [ + 0.04712368901088544, + 0.0471357658138351, + 0.04707212910286524 + ], + [ + 0.04595271881462011, + 0.04593333518441964, + 0.045898448904188184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9386046.012497738, + "scoreError" : 442451.58751577395, + "scoreConfidence" : [ + 8943594.424981965, + 9828497.600013511 + ], + "scorePercentiles" : { + "0.0" : 9056526.171040723, + "50.0" : 9405550.32612782, + "90.0" : 9679187.61025145, + "95.0" : 9679187.61025145, + "99.0" : 9679187.61025145, + "99.9" : 9679187.61025145, + "99.99" : 9679187.61025145, + "99.999" : 9679187.61025145, + "99.9999" : 9679187.61025145, + "100.0" : 9679187.61025145 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9056526.171040723, + 9082294.342105264, + 9074768.792196007 + ], + [ + 9678359.470986461, + 9679187.61025145, + 9675365.270793037 + ], + [ + 9419148.11676083, + 9405550.32612782, + 9403214.012218045 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-01T11:56:38Z-876c9ae43e9b40fa87cf9e89e58309da6a8120df-jdk17.json b/performance-results/2025-05-01T11:56:38Z-876c9ae43e9b40fa87cf9e89e58309da6a8120df-jdk17.json new file mode 100644 index 0000000000..2aadf10372 --- /dev/null +++ b/performance-results/2025-05-01T11:56:38Z-876c9ae43e9b40fa87cf9e89e58309da6a8120df-jdk17.json @@ -0,0 +1,1473 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.43111087891561, + "scoreError" : 0.023550850239527854, + "scoreConfidence" : [ + 3.407560028676082, + 3.454661729155138 + ], + "scorePercentiles" : { + "0.0" : 3.4267768991920184, + "50.0" : 3.4314114501311526, + "90.0" : 3.434843716208115, + "95.0" : 3.434843716208115, + "99.0" : 3.434843716208115, + "99.9" : 3.434843716208115, + "99.99" : 3.434843716208115, + "99.999" : 3.434843716208115, + "99.9999" : 3.434843716208115, + "100.0" : 3.434843716208115 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4267768991920184, + 3.4332755103001062 + ], + [ + 3.4295473899621984, + 3.434843716208115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7297428097536118, + "scoreError" : 0.011833830658248551, + "scoreConfidence" : [ + 1.7179089790953632, + 1.7415766404118604 + ], + "scorePercentiles" : { + "0.0" : 1.7277556040215192, + "50.0" : 1.7296993377226184, + "90.0" : 1.731816959547691, + "95.0" : 1.731816959547691, + "99.0" : 1.731816959547691, + "99.9" : 1.731816959547691, + "99.99" : 1.731816959547691, + "99.999" : 1.731816959547691, + "99.9999" : 1.731816959547691, + "100.0" : 1.731816959547691 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7306496265719902, + 1.731816959547691 + ], + [ + 1.7277556040215192, + 1.7287490488732467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8680423469955787, + "scoreError" : 0.009719293368076446, + "scoreConfidence" : [ + 0.8583230536275023, + 0.8777616403636551 + ], + "scorePercentiles" : { + "0.0" : 0.8667726481012058, + "50.0" : 0.8676674128737308, + "90.0" : 0.8700619141336473, + "95.0" : 0.8700619141336473, + "99.0" : 0.8700619141336473, + "99.9" : 0.8700619141336473, + "99.99" : 0.8700619141336473, + "99.999" : 0.8700619141336473, + "99.9999" : 0.8700619141336473, + "100.0" : 0.8700619141336473 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8670291517610635, + 0.8700619141336473 + ], + [ + 0.8667726481012058, + 0.8683056739863981 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.085033805728045, + "scoreError" : 0.13699063750964222, + "scoreConfidence" : [ + 15.948043168218403, + 16.222024443237686 + ], + "scorePercentiles" : { + "0.0" : 15.964636738350794, + "50.0" : 16.083198389066595, + "90.0" : 16.199350794047188, + "95.0" : 16.199350794047188, + "99.0" : 16.199350794047188, + "99.9" : 16.199350794047188, + "99.99" : 16.199350794047188, + "99.999" : 16.199350794047188, + "99.9999" : 16.199350794047188, + "100.0" : 16.199350794047188 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.147409173147874, + 16.07540109263212, + 15.989465221885307 + ], + [ + 16.083198389066595, + 15.964636738350794, + 16.014324161273485 + ], + [ + 16.199350794047188, + 16.15304756178801, + 16.138471119361043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2664.565367803272, + "scoreError" : 50.97428669473854, + "scoreConfidence" : [ + 2613.591081108533, + 2715.5396544980103 + ], + "scorePercentiles" : { + "0.0" : 2612.856685825606, + "50.0" : 2660.3087744250174, + "90.0" : 2704.91588752433, + "95.0" : 2704.91588752433, + "99.0" : 2704.91588752433, + "99.9" : 2704.91588752433, + "99.99" : 2704.91588752433, + "99.999" : 2704.91588752433, + "99.9999" : 2704.91588752433, + "100.0" : 2704.91588752433 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2704.91588752433, + 2696.098729080225, + 2691.457909427693 + ], + [ + 2612.856685825606, + 2676.9439663385883, + 2660.3087744250174 + ], + [ + 2656.2926714270757, + 2640.301093809492, + 2641.9125923714187 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69866.4139868763, + "scoreError" : 2432.456899095497, + "scoreConfidence" : [ + 67433.9570877808, + 72298.8708859718 + ], + "scorePercentiles" : { + "0.0" : 67680.92433743284, + "50.0" : 70738.39806420317, + "90.0" : 70933.92485270213, + "95.0" : 70933.92485270213, + "99.0" : 70933.92485270213, + "99.9" : 70933.92485270213, + "99.99" : 70933.92485270213, + "99.999" : 70933.92485270213, + "99.9999" : 70933.92485270213, + "100.0" : 70933.92485270213 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 70873.31659954524, + 70885.73693928937, + 70738.39806420317 + ], + [ + 68194.93082832862, + 67680.92433743284, + 67964.70003183158 + ], + [ + 70850.97022886216, + 70933.92485270213, + 70674.82399969149 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 351.7039052887165, + "scoreError" : 3.1747703982745534, + "scoreConfidence" : [ + 348.5291348904419, + 354.8786756869911 + ], + "scorePercentiles" : { + "0.0" : 347.4143717028219, + "50.0" : 352.0290494603568, + "90.0" : 354.2249961867724, + "95.0" : 354.2249961867724, + "99.0" : 354.2249961867724, + "99.9" : 354.2249961867724, + "99.99" : 354.2249961867724, + "99.999" : 354.2249961867724, + "99.9999" : 354.2249961867724, + "100.0" : 354.2249961867724 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 352.97960222653427, + 352.49003031297866, + 352.0290494603568 + ], + [ + 354.2249961867724, + 352.2873474237736, + 351.7561364670655 + ], + [ + 347.4143717028219, + 350.678357043567, + 351.47525677457855 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.16282654422383214, + "scoreError" : 0.03581156597913356, + "scoreConfidence" : [ + 0.12701497824469857, + 0.1986381102029657 + ], + "scorePercentiles" : { + "0.0" : 0.15737631327011145, + "50.0" : 0.1623262754255892, + "90.0" : 0.16927731277403876, + "95.0" : 0.16927731277403876, + "99.0" : 0.16927731277403876, + "99.9" : 0.16927731277403876, + "99.99" : 0.16927731277403876, + "99.999" : 0.16927731277403876, + "99.9999" : 0.16927731277403876, + "100.0" : 0.16927731277403876 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16927731277403876, + 0.15737631327011145 + ], + [ + 0.16551369713520536, + 0.15913885371597303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 105.7223036733633, + "scoreError" : 4.988097830317343, + "scoreConfidence" : [ + 100.73420584304596, + 110.71040150368064 + ], + "scorePercentiles" : { + "0.0" : 101.94595520726325, + "50.0" : 105.9740605384487, + "90.0" : 109.70286096888644, + "95.0" : 109.70286096888644, + "99.0" : 109.70286096888644, + "99.9" : 109.70286096888644, + "99.99" : 109.70286096888644, + "99.999" : 109.70286096888644, + "99.9999" : 109.70286096888644, + "100.0" : 109.70286096888644 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.70286096888644, + 108.61585910636695, + 108.77740921643134 + ], + [ + 102.70174866728841, + 101.94595520726325, + 102.06155210693345 + ], + [ + 105.70299248449716, + 106.01829476415398, + 105.9740605384487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062116702901546236, + "scoreError" : 5.562757128021455E-4, + "scoreConfidence" : [ + 0.06156042718874409, + 0.06267297861434838 + ], + "scorePercentiles" : { + "0.0" : 0.06159444896677035, + "50.0" : 0.06216501131383458, + "90.0" : 0.06278693511059766, + "95.0" : 0.06278693511059766, + "99.0" : 0.06278693511059766, + "99.9" : 0.06278693511059766, + "99.99" : 0.06278693511059766, + "99.999" : 0.06278693511059766, + "99.9999" : 0.06278693511059766, + "100.0" : 0.06278693511059766 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06218421936386531, + 0.06223247550563196, + 0.06278693511059766 + ], + [ + 0.06227093330884047, + 0.06216501131383458, + 0.06183951484438288 + ], + [ + 0.062008989477208884, + 0.06159444896677035, + 0.06196779822278406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.699584597968717E-4, + "scoreError" : 4.511581519946409E-6, + "scoreConfidence" : [ + 3.6544687827692526E-4, + 3.744700413168181E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6487450924488303E-4, + "50.0" : 3.70099047461211E-4, + "90.0" : 3.742667936788574E-4, + "95.0" : 3.742667936788574E-4, + "99.0" : 3.742667936788574E-4, + "99.9" : 3.742667936788574E-4, + "99.99" : 3.742667936788574E-4, + "99.999" : 3.742667936788574E-4, + "99.9999" : 3.742667936788574E-4, + "100.0" : 3.742667936788574E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6487450924488303E-4, + 3.690437397365516E-4, + 3.6933393948953983E-4 + ], + [ + 3.7204387159876887E-4, + 3.742667936788574E-4, + 3.7115816656422196E-4 + ], + [ + 3.70099047461211E-4, + 3.7107693511109264E-4, + 3.6772913528671923E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1083441914749893, + "scoreError" : 0.002872250709849492, + "scoreConfidence" : [ + 0.10547194076513981, + 0.1112164421848388 + ], + "scorePercentiles" : { + "0.0" : 0.10622213899983005, + "50.0" : 0.10846203502169198, + "90.0" : 0.11038892573131692, + "95.0" : 0.11038892573131692, + "99.0" : 0.11038892573131692, + "99.9" : 0.11038892573131692, + "99.99" : 0.11038892573131692, + "99.999" : 0.11038892573131692, + "99.9999" : 0.11038892573131692, + "100.0" : 0.11038892573131692 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10846203502169198, + 0.1089636906020158, + 0.10809051231665531 + ], + [ + 0.11038264427396656, + 0.11038892573131692, + 0.10984348556678383 + ], + [ + 0.10622285035531054, + 0.10652144040733284, + 0.10622213899983005 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014119334075794207, + "scoreError" : 2.712655078104915E-4, + "scoreConfidence" : [ + 0.013848068567983715, + 0.014390599583604698 + ], + "scorePercentiles" : { + "0.0" : 0.013919332645726678, + "50.0" : 0.014096618926725299, + "90.0" : 0.01433968165432035, + "95.0" : 0.01433968165432035, + "99.0" : 0.01433968165432035, + "99.9" : 0.01433968165432035, + "99.99" : 0.01433968165432035, + "99.999" : 0.01433968165432035, + "99.9999" : 0.01433968165432035, + "100.0" : 0.01433968165432035 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013919332645726678, + 0.013941467566252563, + 0.013964327067149455 + ], + [ + 0.014080176032451597, + 0.014096618926725299, + 0.014144973943842268 + ], + [ + 0.014312755815917308, + 0.01433968165432035, + 0.01427467302976233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0004986570245231, + "scoreError" : 0.05042727555351308, + "scoreConfidence" : [ + 0.95007138147101, + 1.0509259325780362 + ], + "scorePercentiles" : { + "0.0" : 0.9653052558880308, + "50.0" : 1.0003774282284685, + "90.0" : 1.0426164286905755, + "95.0" : 1.0426164286905755, + "99.0" : 1.0426164286905755, + "99.9" : 1.0426164286905755, + "99.99" : 1.0426164286905755, + "99.999" : 1.0426164286905755, + "99.9999" : 1.0426164286905755, + "100.0" : 1.0426164286905755 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0203349673502704, + 1.040820051415487, + 1.0426164286905755 + ], + [ + 0.9677289622604993, + 0.9653052558880308, + 0.968064897009002 + ], + [ + 1.0003774282284685, + 1.0043594710254093, + 0.9948804513529645 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012812440824606525, + "scoreError" : 2.5041362909309804E-4, + "scoreConfidence" : [ + 0.012562027195513427, + 0.013062854453699623 + ], + "scorePercentiles" : { + "0.0" : 0.01267956478717874, + "50.0" : 0.012830737937680844, + "90.0" : 0.012930194764961133, + "95.0" : 0.012930194764961133, + "99.0" : 0.012930194764961133, + "99.9" : 0.012930194764961133, + "99.99" : 0.012930194764961133, + "99.999" : 0.012930194764961133, + "99.9999" : 0.012930194764961133, + "100.0" : 0.012930194764961133 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012740929730459732, + 0.012930194764961133, + 0.012862479789677854 + ], + [ + 0.01267956478717874, + 0.012825123818513398, + 0.012836352056848289 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.7447377736055967, + "scoreError" : 0.09612982210990338, + "scoreConfidence" : [ + 3.6486079514956935, + 3.8408675957155 + ], + "scorePercentiles" : { + "0.0" : 3.6995127374260357, + "50.0" : 3.7565718539785546, + "90.0" : 3.783590488653555, + "95.0" : 3.783590488653555, + "99.0" : 3.783590488653555, + "99.9" : 3.783590488653555, + "99.99" : 3.783590488653555, + "99.999" : 3.783590488653555, + "99.9999" : 3.783590488653555, + "100.0" : 3.783590488653555 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.706641014825797, + 3.7655386927710843, + 3.783590488653555 + ], + [ + 3.7654291603915664, + 3.6995127374260357, + 3.747714547565543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8834508207569516, + "scoreError" : 0.1212462521689161, + "scoreConfidence" : [ + 2.7622045685880354, + 3.0046970729258677 + ], + "scorePercentiles" : { + "0.0" : 2.801058332399888, + "50.0" : 2.8643350123138602, + "90.0" : 3.0050248563701922, + "95.0" : 3.0050248563701922, + "99.0" : 3.0050248563701922, + "99.9" : 3.0050248563701922, + "99.99" : 3.0050248563701922, + "99.999" : 3.0050248563701922, + "99.9999" : 3.0050248563701922, + "100.0" : 3.0050248563701922 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0050248563701922, + 2.9599527321692807, + 2.9227347285213328 + ], + [ + 2.801058332399888, + 2.810494565327339, + 2.815468326295045 + ], + [ + 2.9203442169343066, + 2.8643350123138602, + 2.851644616481323 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.255903795875, + "scoreError" : 1.2238425527609669, + "scoreConfidence" : [ + 5.032061243114033, + 7.479746348635967 + ], + "scorePercentiles" : { + "0.0" : 6.034213462, + "50.0" : 6.26329503775, + "90.0" : 6.462811646, + "95.0" : 6.462811646, + "99.0" : 6.462811646, + "99.9" : 6.462811646, + "99.99" : 6.462811646, + "99.999" : 6.462811646, + "99.9999" : 6.462811646, + "100.0" : 6.462811646 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.175147101, + 6.462811646 + ], + [ + 6.034213462, + 6.3514429745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18001828918530607, + "scoreError" : 0.0030242831183845483, + "scoreConfidence" : [ + 0.17699400606692153, + 0.18304257230369061 + ], + "scorePercentiles" : { + "0.0" : 0.17702600805452293, + "50.0" : 0.1808766457033299, + "90.0" : 0.1816479737344014, + "95.0" : 0.1816479737344014, + "99.0" : 0.1816479737344014, + "99.9" : 0.1816479737344014, + "99.99" : 0.1816479737344014, + "99.999" : 0.1816479737344014, + "99.9999" : 0.1816479737344014, + "100.0" : 0.1816479737344014 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18146177963671994, + 0.1810151702778532, + 0.1808766457033299 + ], + [ + 0.1816479737344014, + 0.1807215504472757, + 0.18136137415669207 + ], + [ + 0.1783869673023065, + 0.17702600805452293, + 0.17766713335465303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32167037938706466, + "scoreError" : 0.013360558152904599, + "scoreConfidence" : [ + 0.30830982123416006, + 0.33503093753996926 + ], + "scorePercentiles" : { + "0.0" : 0.3116429008382935, + "50.0" : 0.32166399305220494, + "90.0" : 0.33116004900986823, + "95.0" : 0.33116004900986823, + "99.0" : 0.33116004900986823, + "99.9" : 0.33116004900986823, + "99.99" : 0.33116004900986823, + "99.999" : 0.33116004900986823, + "99.9999" : 0.33116004900986823, + "100.0" : 0.33116004900986823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31187029942304695, + 0.3116429008382935, + 0.31403847616505465 + ], + [ + 0.3309824036870325, + 0.33116004900986823, + 0.33021461725663714 + ], + [ + 0.32246738417386817, + 0.3209932908775759, + 0.32166399305220494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15728655136693948, + "scoreError" : 0.007831043057633151, + "scoreConfidence" : [ + 0.14945550830930632, + 0.16511759442457263 + ], + "scorePercentiles" : { + "0.0" : 0.15110916062497168, + "50.0" : 0.15855282616692035, + "90.0" : 0.16301074980031624, + "95.0" : 0.16301074980031624, + "99.0" : 0.16301074980031624, + "99.9" : 0.16301074980031624, + "99.99" : 0.16301074980031624, + "99.999" : 0.16301074980031624, + "99.9999" : 0.16301074980031624, + "100.0" : 0.16301074980031624 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1617882048664477, + 0.16301074980031624, + 0.1608020581765557 + ], + [ + 0.1520033665754674, + 0.15110916062497168, + 0.15117529758125473 + ], + [ + 0.15855282616692035, + 0.15843901609708952, + 0.15869828241343192 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.393933319138966, + "scoreError" : 0.00740009185476945, + "scoreConfidence" : [ + 0.38653322728419653, + 0.4013334109937355 + ], + "scorePercentiles" : { + "0.0" : 0.38828055294117647, + "50.0" : 0.396703518108612, + "90.0" : 0.3992958881613096, + "95.0" : 0.3992958881613096, + "99.0" : 0.3992958881613096, + "99.9" : 0.3992958881613096, + "99.99" : 0.3992958881613096, + "99.999" : 0.3992958881613096, + "99.9999" : 0.3992958881613096, + "100.0" : 0.3992958881613096 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3970287170080991, + 0.3969245985711451, + 0.39676444665740923 + ], + [ + 0.3992958881613096, + 0.39348996698670025, + 0.396703518108612 + ], + [ + 0.3885362804025177, + 0.38828055294117647, + 0.3883759034137248 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1581837547693671, + "scoreError" : 0.002828381951133783, + "scoreConfidence" : [ + 0.15535537281823333, + 0.16101213672050088 + ], + "scorePercentiles" : { + "0.0" : 0.15597313878187632, + "50.0" : 0.15750064592947255, + "90.0" : 0.1603225453539823, + "95.0" : 0.1603225453539823, + "99.0" : 0.1603225453539823, + "99.9" : 0.1603225453539823, + "99.99" : 0.1603225453539823, + "99.999" : 0.1603225453539823, + "99.9999" : 0.1603225453539823, + "100.0" : 0.1603225453539823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1603225453539823, + 0.16015349393036737, + 0.16017225207419034 + ], + [ + 0.15734491129083014, + 0.15750064592947255, + 0.15735382277505036 + ], + [ + 0.15849620418740293, + 0.15597313878187632, + 0.15633677860113185 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04819242759723642, + "scoreError" : 0.0022432092299751144, + "scoreConfidence" : [ + 0.04594921836726131, + 0.050435636827211534 + ], + "scorePercentiles" : { + "0.0" : 0.046557766339215045, + "50.0" : 0.048149836047340244, + "90.0" : 0.0497915005327624, + "95.0" : 0.0497915005327624, + "99.0" : 0.0497915005327624, + "99.9" : 0.0497915005327624, + "99.99" : 0.0497915005327624, + "99.999" : 0.0497915005327624, + "99.9999" : 0.0497915005327624, + "100.0" : 0.0497915005327624 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04682351307059479, + 0.046648382198317885, + 0.046557766339215045 + ], + [ + 0.0497915005327624, + 0.049706544163551775, + 0.049748964250890496 + ], + [ + 0.048307803636556866, + 0.048149836047340244, + 0.047997538135898285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9311862.99914772, + "scoreError" : 226318.11020111045, + "scoreConfidence" : [ + 9085544.88894661, + 9538181.109348832 + ], + "scorePercentiles" : { + "0.0" : 9113777.428051002, + "50.0" : 9348595.629906543, + "90.0" : 9461808.175023653, + "95.0" : 9461808.175023653, + "99.0" : 9461808.175023653, + "99.9" : 9461808.175023653, + "99.99" : 9461808.175023653, + "99.999" : 9461808.175023653, + "99.9999" : 9461808.175023653, + "100.0" : 9461808.175023653 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9364917.730337078, + 9348595.629906543, + 9320853.864864865 + ], + [ + 9113777.428051002, + 9129664.670620438, + 9192369.182904411 + ], + [ + 9428718.525918944, + 9446061.784702549, + 9461808.175023653 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-02T00:30:06Z-24b955a4d926a13b47f746c465ae6ae8fdb4ccf8-jdk17.json b/performance-results/2025-05-02T00:30:06Z-24b955a4d926a13b47f746c465ae6ae8fdb4ccf8-jdk17.json new file mode 100644 index 0000000000..1d0c41c288 --- /dev/null +++ b/performance-results/2025-05-02T00:30:06Z-24b955a4d926a13b47f746c465ae6ae8fdb4ccf8-jdk17.json @@ -0,0 +1,1383 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4243856111178195, + "scoreError" : 0.026687961567986532, + "scoreConfidence" : [ + 3.397697649549833, + 3.451073572685806 + ], + "scorePercentiles" : { + "0.0" : 3.4206764352036485, + "50.0" : 3.4234141671996174, + "90.0" : 3.4300376748683936, + "95.0" : 3.4300376748683936, + "99.0" : 3.4300376748683936, + "99.9" : 3.4300376748683936, + "99.99" : 3.4300376748683936, + "99.999" : 3.4300376748683936, + "99.9999" : 3.4300376748683936, + "100.0" : 3.4300376748683936 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4220763939500256, + 3.4247519404492093 + ], + [ + 3.4206764352036485, + 3.4300376748683936 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7299134966509564, + "scoreError" : 0.017495983738753242, + "scoreConfidence" : [ + 1.7124175129122032, + 1.7474094803897096 + ], + "scorePercentiles" : { + "0.0" : 1.725861904409544, + "50.0" : 1.731162195838301, + "90.0" : 1.7314676905176798, + "95.0" : 1.7314676905176798, + "99.0" : 1.7314676905176798, + "99.9" : 1.7314676905176798, + "99.99" : 1.7314676905176798, + "99.999" : 1.7314676905176798, + "99.9999" : 1.7314676905176798, + "100.0" : 1.7314676905176798 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7310162123288497, + 1.7313081793477525 + ], + [ + 1.725861904409544, + 1.7314676905176798 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8643696043999212, + "scoreError" : 0.03325214076174867, + "scoreConfidence" : [ + 0.8311174636381725, + 0.8976217451616698 + ], + "scorePercentiles" : { + "0.0" : 0.859094878124866, + "50.0" : 0.8647333011024333, + "90.0" : 0.8689169372699526, + "95.0" : 0.8689169372699526, + "99.0" : 0.8689169372699526, + "99.9" : 0.8689169372699526, + "99.99" : 0.8689169372699526, + "99.999" : 0.8689169372699526, + "99.9999" : 0.8689169372699526, + "100.0" : 0.8689169372699526 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.860817153668851, + 0.859094878124866 + ], + [ + 0.8686494485360156, + 0.8689169372699526 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.826238890603088, + "scoreError" : 0.5226062001932811, + "scoreConfidence" : [ + 15.303632690409808, + 16.34884509079637 + ], + "scorePercentiles" : { + "0.0" : 15.63902181680493, + "50.0" : 15.81351901611821, + "90.0" : 16.046870143027384, + "95.0" : 16.046870143027384, + "99.0" : 16.046870143027384, + "99.9" : 16.046870143027384, + "99.99" : 16.046870143027384, + "99.999" : 16.046870143027384, + "99.9999" : 16.046870143027384, + "100.0" : 16.046870143027384 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.046870143027384, + 15.951019844262966, + 15.983132782797945 + ], + [ + 15.661370568751853, + 15.63902181680493, + 15.676018187973455 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2622.707372500936, + "scoreError" : 61.69216982398543, + "scoreConfidence" : [ + 2561.0152026769506, + 2684.399542324921 + ], + "scorePercentiles" : { + "0.0" : 2598.539744249902, + "50.0" : 2624.5569539614144, + "90.0" : 2645.559318887333, + "95.0" : 2645.559318887333, + "99.0" : 2645.559318887333, + "99.9" : 2645.559318887333, + "99.99" : 2645.559318887333, + "99.999" : 2645.559318887333, + "99.9999" : 2645.559318887333, + "100.0" : 2645.559318887333 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2608.1543192997337, + 2601.9459628493933, + 2598.539744249902 + ], + [ + 2641.0853010961564, + 2645.559318887333, + 2640.9595886230954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69527.00397996168, + "scoreError" : 3656.3613545614085, + "scoreConfidence" : [ + 65870.64262540027, + 73183.36533452309 + ], + "scorePercentiles" : { + "0.0" : 68289.81097269504, + "50.0" : 69524.47463057046, + "90.0" : 70747.30123467014, + "95.0" : 70747.30123467014, + "99.0" : 70747.30123467014, + "99.9" : 70747.30123467014, + "99.99" : 70747.30123467014, + "99.999" : 70747.30123467014, + "99.9999" : 70747.30123467014, + "100.0" : 70747.30123467014 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68289.81097269504, + 68369.69017469382, + 68351.89232669951 + ], + [ + 70747.30123467014, + 70724.07008456449, + 70679.2590864471 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 340.34708699055324, + "scoreError" : 12.499776908512432, + "scoreConfidence" : [ + 327.8473100820408, + 352.8468638990657 + ], + "scorePercentiles" : { + "0.0" : 335.21818269475693, + "50.0" : 340.5839377944749, + "90.0" : 344.83439984172765, + "95.0" : 344.83439984172765, + "99.0" : 344.83439984172765, + "99.9" : 344.83439984172765, + "99.99" : 344.83439984172765, + "99.999" : 344.83439984172765, + "99.9999" : 344.83439984172765, + "100.0" : 344.83439984172765 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 335.21818269475693, + 337.0684060726962, + 336.68520090098883 + ], + [ + 344.09946951625363, + 344.83439984172765, + 344.17686291689654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1617177265215101, + "scoreError" : 0.026305514696952997, + "scoreConfidence" : [ + 0.1354122118245571, + 0.1880232412184631 + ], + "scorePercentiles" : { + "0.0" : 0.15763519982340746, + "50.0" : 0.16138602094797083, + "90.0" : 0.16646366436669122, + "95.0" : 0.16646366436669122, + "99.0" : 0.16646366436669122, + "99.9" : 0.16646366436669122, + "99.99" : 0.16646366436669122, + "99.999" : 0.16646366436669122, + "99.9999" : 0.16646366436669122, + "100.0" : 0.16646366436669122 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16365575816783037, + 0.15763519982340746 + ], + [ + 0.16646366436669122, + 0.15911628372811126 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.13674301109596, + "scoreError" : 6.002710388364565, + "scoreConfidence" : [ + 98.1340326227314, + 110.13945339946052 + ], + "scorePercentiles" : { + "0.0" : 101.99977973901824, + "50.0" : 104.15057160506032, + "90.0" : 106.18050171345665, + "95.0" : 106.18050171345665, + "99.0" : 106.18050171345665, + "99.9" : 106.18050171345665, + "99.99" : 106.18050171345665, + "99.999" : 106.18050171345665, + "99.9999" : 106.18050171345665, + "100.0" : 106.18050171345665 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.18050171345665, + 105.95066027141591, + 106.12969937935499 + ], + [ + 101.99977973901824, + 102.20933402462518, + 102.35048293870474 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06276416507349948, + "scoreError" : 4.7856568485136493E-4, + "scoreConfidence" : [ + 0.06228559938864812, + 0.06324273075835085 + ], + "scorePercentiles" : { + "0.0" : 0.0625393391327188, + "50.0" : 0.06284264966115377, + "90.0" : 0.06291919207731414, + "95.0" : 0.06291919207731414, + "99.0" : 0.06291919207731414, + "99.9" : 0.06291919207731414, + "99.99" : 0.06291919207731414, + "99.999" : 0.06291919207731414, + "99.9999" : 0.06291919207731414, + "100.0" : 0.06291919207731414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06282642821242564, + 0.06285887110988189, + 0.06288550536092717 + ], + [ + 0.0625393391327188, + 0.06255565454772927, + 0.06291919207731414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.755497758984778E-4, + "scoreError" : 1.507373859523289E-5, + "scoreConfidence" : [ + 3.6047603730324495E-4, + 3.906235144937107E-4 + ], + "scorePercentiles" : { + "0.0" : 3.693789497079226E-4, + "50.0" : 3.761478843638265E-4, + "90.0" : 3.807522085084488E-4, + "95.0" : 3.807522085084488E-4, + "99.0" : 3.807522085084488E-4, + "99.9" : 3.807522085084488E-4, + "99.99" : 3.807522085084488E-4, + "99.999" : 3.807522085084488E-4, + "99.9999" : 3.807522085084488E-4, + "100.0" : 3.807522085084488E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.807522085084488E-4, + 3.804366998608912E-4, + 3.799277165440546E-4 + ], + [ + 3.7236805218359835E-4, + 3.693789497079226E-4, + 3.7043502858595154E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11290153921278383, + "scoreError" : 0.013576548025850324, + "scoreConfidence" : [ + 0.0993249911869335, + 0.12647808723863416 + ], + "scorePercentiles" : { + "0.0" : 0.10842414959016393, + "50.0" : 0.11269077323091009, + "90.0" : 0.11772949796331615, + "95.0" : 0.11772949796331615, + "99.0" : 0.11772949796331615, + "99.9" : 0.11772949796331615, + "99.99" : 0.11772949796331615, + "99.999" : 0.11772949796331615, + "99.9999" : 0.11772949796331615, + "100.0" : 0.11772949796331615 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10842414959016393, + 0.10858159691849986, + 0.10846579419070035 + ], + [ + 0.11679994954332033, + 0.11740824707070233, + 0.11772949796331615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014076907020775666, + "scoreError" : 1.3641447035885385E-4, + "scoreConfidence" : [ + 0.013940492550416812, + 0.01421332149113452 + ], + "scorePercentiles" : { + "0.0" : 0.014023505217382768, + "50.0" : 0.014082435088302044, + "90.0" : 0.014122586124158657, + "95.0" : 0.014122586124158657, + "99.0" : 0.014122586124158657, + "99.9" : 0.014122586124158657, + "99.99" : 0.014122586124158657, + "99.999" : 0.014122586124158657, + "99.9999" : 0.014122586124158657, + "100.0" : 0.014122586124158657 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014122586124158657, + 0.014120595838146045, + 0.014119267525672033 + ], + [ + 0.014023505217382768, + 0.014045602650932054, + 0.014029884768362437 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9764073327958921, + "scoreError" : 0.010733854277373577, + "scoreConfidence" : [ + 0.9656734785185185, + 0.9871411870732657 + ], + "scorePercentiles" : { + "0.0" : 0.9702764706510139, + "50.0" : 0.9784738653424762, + "90.0" : 0.9793149625930279, + "95.0" : 0.9793149625930279, + "99.0" : 0.9793149625930279, + "99.9" : 0.9793149625930279, + "99.99" : 0.9793149625930279, + "99.999" : 0.9793149625930279, + "99.9999" : 0.9793149625930279, + "100.0" : 0.9793149625930279 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9789567909162099, + 0.9793149625930279, + 0.978798503278849 + ], + [ + 0.9729480419301488, + 0.9702764706510139, + 0.9781492274061033 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013349951937366723, + "scoreError" : 1.791208067635585E-4, + "scoreConfidence" : [ + 0.013170831130603165, + 0.013529072744130281 + ], + "scorePercentiles" : { + "0.0" : 0.013235830900201445, + "50.0" : 0.013353415729403694, + "90.0" : 0.013424181076698382, + "95.0" : 0.013424181076698382, + "99.0" : 0.013424181076698382, + "99.9" : 0.013424181076698382, + "99.99" : 0.013424181076698382, + "99.999" : 0.013424181076698382, + "99.9999" : 0.013424181076698382, + "100.0" : 0.013424181076698382 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013235830900201445, + 0.013341004637226416, + 0.013351593859480475 + ], + [ + 0.013424181076698382, + 0.013355237599326913, + 0.013391863551266703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.8609756297113442, + "scoreError" : 0.057604963218926615, + "scoreConfidence" : [ + 3.8033706664924174, + 3.918580592930271 + ], + "scorePercentiles" : { + "0.0" : 3.837878002302379, + "50.0" : 3.8613886136308926, + "90.0" : 3.8899327783825814, + "95.0" : 3.8899327783825814, + "99.0" : 3.8899327783825814, + "99.9" : 3.8899327783825814, + "99.99" : 3.8899327783825814, + "99.999" : 3.8899327783825814, + "99.9999" : 3.8899327783825814, + "100.0" : 3.8899327783825814 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.838923483499616, + 3.8641435312741312, + 3.8899327783825814 + ], + [ + 3.837878002302379, + 3.8763422868217052, + 3.8586336959876544 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9107152906140112, + "scoreError" : 0.17264115891016824, + "scoreConfidence" : [ + 2.738074131703843, + 3.0833564495241794 + ], + "scorePercentiles" : { + "0.0" : 2.847217072018218, + "50.0" : 2.9068154346759494, + "90.0" : 2.9797577593089066, + "95.0" : 2.9797577593089066, + "99.0" : 2.9797577593089066, + "99.9" : 2.9797577593089066, + "99.99" : 2.9797577593089066, + "99.999" : 2.9797577593089066, + "99.9999" : 2.9797577593089066, + "100.0" : 2.9797577593089066 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.952159564344746, + 2.966649619697419, + 2.9797577593089066 + ], + [ + 2.857036423307626, + 2.861471305007153, + 2.847217072018218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.2330806728749995, + "scoreError" : 1.3604002583457515, + "scoreConfidence" : [ + 4.872680414529248, + 7.593480931220751 + ], + "scorePercentiles" : { + "0.0" : 6.0471666775, + "50.0" : 6.22303639175, + "90.0" : 6.4390832305, + "95.0" : 6.4390832305, + "99.0" : 6.4390832305, + "99.9" : 6.4390832305, + "99.99" : 6.4390832305, + "99.999" : 6.4390832305, + "99.9999" : 6.4390832305, + "100.0" : 6.4390832305 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.0560670515, + 6.4390832305 + ], + [ + 6.0471666775, + 6.390005732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17695705749653878, + "scoreError" : 0.02066596468028046, + "scoreConfidence" : [ + 0.15629109281625833, + 0.19762302217681924 + ], + "scorePercentiles" : { + "0.0" : 0.1698947330150694, + "50.0" : 0.17718588646026395, + "90.0" : 0.18381453600838174, + "95.0" : 0.18381453600838174, + "99.0" : 0.18381453600838174, + "99.9" : 0.18381453600838174, + "99.99" : 0.18381453600838174, + "99.999" : 0.18381453600838174, + "99.9999" : 0.18381453600838174, + "100.0" : 0.18381453600838174 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17085623141978473, + 0.16996064849247086, + 0.1698947330150694 + ], + [ + 0.18370065454278262, + 0.1835155415007432, + 0.18381453600838174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3341891233812217, + "scoreError" : 0.004207100055810972, + "scoreConfidence" : [ + 0.3299820233254107, + 0.3383962234370327 + ], + "scorePercentiles" : { + "0.0" : 0.332324526119899, + "50.0" : 0.33453383257104535, + "90.0" : 0.33559092214503844, + "95.0" : 0.33559092214503844, + "99.0" : 0.33559092214503844, + "99.9" : 0.33559092214503844, + "99.99" : 0.33559092214503844, + "99.999" : 0.33559092214503844, + "99.9999" : 0.33559092214503844, + "100.0" : 0.33559092214503844 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33559092214503844, + 0.3354814033681103, + 0.3354276811565037 + ], + [ + 0.33363998398558703, + 0.3326702235121919, + 0.332324526119899 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1587210943140552, + "scoreError" : 0.00565100470236045, + "scoreConfidence" : [ + 0.15307008961169474, + 0.16437209901641567 + ], + "scorePercentiles" : { + "0.0" : 0.15675245813217129, + "50.0" : 0.1586225019819986, + "90.0" : 0.16080159168676636, + "95.0" : 0.16080159168676636, + "99.0" : 0.16080159168676636, + "99.9" : 0.16080159168676636, + "99.99" : 0.16080159168676636, + "99.999" : 0.16080159168676636, + "99.9999" : 0.16080159168676636, + "100.0" : 0.16080159168676636 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15696206339564597, + 0.15695212438201364, + 0.15675245813217129 + ], + [ + 0.1602829405683512, + 0.16057538771938276, + 0.16080159168676636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39721682302078376, + "scoreError" : 0.022266720097578307, + "scoreConfidence" : [ + 0.37495010292320546, + 0.41948354311836206 + ], + "scorePercentiles" : { + "0.0" : 0.3896957332242226, + "50.0" : 0.3971700266310394, + "90.0" : 0.4047341756111381, + "95.0" : 0.4047341756111381, + "99.0" : 0.4047341756111381, + "99.9" : 0.4047341756111381, + "99.99" : 0.4047341756111381, + "99.999" : 0.4047341756111381, + "99.9999" : 0.4047341756111381, + "100.0" : 0.4047341756111381 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3896957332242226, + 0.3900972101033743, + 0.39012002941405943 + ], + [ + 0.4047341756111381, + 0.40443376592388885, + 0.4042200238480194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.159007283640204, + "scoreError" : 0.004836125088409615, + "scoreConfidence" : [ + 0.1541711585517944, + 0.1638434087286136 + ], + "scorePercentiles" : { + "0.0" : 0.15733778182476124, + "50.0" : 0.15905864411380383, + "90.0" : 0.16068966459916764, + "95.0" : 0.16068966459916764, + "99.0" : 0.16068966459916764, + "99.9" : 0.16068966459916764, + "99.99" : 0.16068966459916764, + "99.999" : 0.16068966459916764, + "99.9999" : 0.16068966459916764, + "100.0" : 0.16068966459916764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16068966459916764, + 0.1605280937299345, + 0.16051771197431783 + ], + [ + 0.15733778182476124, + 0.15737087345975292, + 0.15759957625328982 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04688617318915551, + "scoreError" : 7.659160210506382E-4, + "scoreConfidence" : [ + 0.04612025716810487, + 0.047652089210206146 + ], + "scorePercentiles" : { + "0.0" : 0.04653300963686111, + "50.0" : 0.04687608762843795, + "90.0" : 0.04735991646775782, + "95.0" : 0.04735991646775782, + "99.0" : 0.04735991646775782, + "99.9" : 0.04735991646775782, + "99.99" : 0.04735991646775782, + "99.999" : 0.04735991646775782, + "99.9999" : 0.04735991646775782, + "100.0" : 0.04735991646775782 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04735991646775782, + 0.04692590022289482, + 0.04684122071291395 + ], + [ + 0.04691095454396195, + 0.046746037550543414, + 0.04653300963686111 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9503120.30191485, + "scoreError" : 74805.68846656613, + "scoreConfidence" : [ + 9428314.613448285, + 9577925.990381416 + ], + "scorePercentiles" : { + "0.0" : 9464995.247871334, + "50.0" : 9501648.158594493, + "90.0" : 9548497.897900764, + "95.0" : 9548497.897900764, + "99.0" : 9548497.897900764, + "99.9" : 9548497.897900764, + "99.99" : 9548497.897900764, + "99.999" : 9548497.897900764, + "99.9999" : 9548497.897900764, + "100.0" : 9548497.897900764 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9548497.897900764, + 9497262.630579296, + 9464995.247871334 + ], + [ + 9504669.717948718, + 9500153.840455841, + 9503142.476733143 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-06T06:59:13Z-5f071380a3130ed30e1f827392da3c478b80ee0f-jdk17.json b/performance-results/2025-05-06T06:59:13Z-5f071380a3130ed30e1f827392da3c478b80ee0f-jdk17.json new file mode 100644 index 0000000000..45d1c5224d --- /dev/null +++ b/performance-results/2025-05-06T06:59:13Z-5f071380a3130ed30e1f827392da3c478b80ee0f-jdk17.json @@ -0,0 +1,1383 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4238281061518467, + "scoreError" : 0.021587910601074102, + "scoreConfidence" : [ + 3.402240195550773, + 3.4454160167529206 + ], + "scorePercentiles" : { + "0.0" : 3.419976050503771, + "50.0" : 3.4240426898365275, + "90.0" : 3.4272509944305605, + "95.0" : 3.4272509944305605, + "99.0" : 3.4272509944305605, + "99.9" : 3.4272509944305605, + "99.99" : 3.4272509944305605, + "99.999" : 3.4272509944305605, + "99.9999" : 3.4272509944305605, + "100.0" : 3.4272509944305605 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.425891379083185, + 3.4272509944305605 + ], + [ + 3.419976050503771, + 3.4221940005898697 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7278819981787108, + "scoreError" : 0.026316711584586296, + "scoreConfidence" : [ + 1.7015652865941244, + 1.7541987097632972 + ], + "scorePercentiles" : { + "0.0" : 1.7242065808810239, + "50.0" : 1.727347819447981, + "90.0" : 1.7326257729378574, + "95.0" : 1.7326257729378574, + "99.0" : 1.7326257729378574, + "99.9" : 1.7326257729378574, + "99.99" : 1.7326257729378574, + "99.999" : 1.7326257729378574, + "99.9999" : 1.7326257729378574, + "100.0" : 1.7326257729378574 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7242065808810239, + 1.7247813075039693 + ], + [ + 1.7299143313919927, + 1.7326257729378574 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8685107179636625, + "scoreError" : 0.008537708602383207, + "scoreConfidence" : [ + 0.8599730093612793, + 0.8770484265660458 + ], + "scorePercentiles" : { + "0.0" : 0.8671226744056505, + "50.0" : 0.8684046520041548, + "90.0" : 0.8701108934406896, + "95.0" : 0.8701108934406896, + "99.0" : 0.8701108934406896, + "99.9" : 0.8701108934406896, + "99.99" : 0.8701108934406896, + "99.999" : 0.8701108934406896, + "99.9999" : 0.8701108934406896, + "100.0" : 0.8701108934406896 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8690076193660159, + 0.8701108934406896 + ], + [ + 0.8671226744056505, + 0.8678016846422939 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.308463189937523, + "scoreError" : 0.12295515149320659, + "scoreConfidence" : [ + 16.185508038444315, + 16.43141834143073 + ], + "scorePercentiles" : { + "0.0" : 16.26455759953936, + "50.0" : 16.29367546032239, + "90.0" : 16.37890727922539, + "95.0" : 16.37890727922539, + "99.0" : 16.37890727922539, + "99.9" : 16.37890727922539, + "99.99" : 16.37890727922539, + "99.999" : 16.37890727922539, + "99.9999" : 16.37890727922539, + "100.0" : 16.37890727922539 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.27885238725999, + 16.280585526078514, + 16.26455759953936 + ], + [ + 16.37890727922539, + 16.30676539456627, + 16.341110952955606 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2717.614277954233, + "scoreError" : 245.0687793146003, + "scoreConfidence" : [ + 2472.5454986396326, + 2962.683057268833 + ], + "scorePercentiles" : { + "0.0" : 2635.867328132349, + "50.0" : 2717.3008707281824, + "90.0" : 2801.387358524166, + "95.0" : 2801.387358524166, + "99.0" : 2801.387358524166, + "99.9" : 2801.387358524166, + "99.99" : 2801.387358524166, + "99.999" : 2801.387358524166, + "99.9999" : 2801.387358524166, + "100.0" : 2801.387358524166 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2635.867328132349, + 2636.903477278355, + 2640.870432892098 + ], + [ + 2796.9257623341628, + 2801.387358524166, + 2793.731308564267 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70084.7582490412, + "scoreError" : 1033.8326861847038, + "scoreConfidence" : [ + 69050.9255628565, + 71118.5909352259 + ], + "scorePercentiles" : { + "0.0" : 69744.94339957966, + "50.0" : 70074.84584498432, + "90.0" : 70459.20937721158, + "95.0" : 70459.20937721158, + "99.0" : 70459.20937721158, + "99.9" : 70459.20937721158, + "99.99" : 70459.20937721158, + "99.999" : 70459.20937721158, + "99.9999" : 70459.20937721158, + "100.0" : 70459.20937721158 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69745.49571586706, + 69744.94339957966, + 69755.97807926149 + ], + [ + 70393.71361070714, + 70409.20931162035, + 70459.20937721158 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 351.92321383084754, + "scoreError" : 3.8858348724684193, + "scoreConfidence" : [ + 348.0373789583791, + 355.80904870331597 + ], + "scorePercentiles" : { + "0.0" : 350.4665946456915, + "50.0" : 351.91757563656887, + "90.0" : 354.13033218763997, + "95.0" : 354.13033218763997, + "99.0" : 354.13033218763997, + "99.9" : 354.13033218763997, + "99.99" : 354.13033218763997, + "99.999" : 354.13033218763997, + "99.9999" : 354.13033218763997, + "100.0" : 354.13033218763997 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 352.61320246188666, + 350.4665946456915, + 350.4940024167295 + ], + [ + 354.13033218763997, + 351.7062929579826, + 352.1288583151551 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1649868628449748, + "scoreError" : 0.029178142156921567, + "scoreConfidence" : [ + 0.13580872068805322, + 0.19416500500189637 + ], + "scorePercentiles" : { + "0.0" : 0.15891694649289018, + "50.0" : 0.16560083639571194, + "90.0" : 0.1698288320955851, + "95.0" : 0.1698288320955851, + "99.0" : 0.1698288320955851, + "99.9" : 0.1698288320955851, + "99.99" : 0.1698288320955851, + "99.999" : 0.1698288320955851, + "99.9999" : 0.1698288320955851, + "100.0" : 0.1698288320955851 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16584849905045618, + 0.15891694649289018 + ], + [ + 0.1698288320955851, + 0.1653531737409677 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.06277088669714, + "scoreError" : 3.2591391249264023, + "scoreConfidence" : [ + 103.80363176177073, + 110.32191001162354 + ], + "scorePercentiles" : { + "0.0" : 105.9799425116281, + "50.0" : 106.98158371401064, + "90.0" : 108.33392020869383, + "95.0" : 108.33392020869383, + "99.0" : 108.33392020869383, + "99.9" : 108.33392020869383, + "99.99" : 108.33392020869383, + "99.999" : 108.33392020869383, + "99.9999" : 108.33392020869383, + "100.0" : 108.33392020869383 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.33392020869383, + 107.92746331179418, + 108.08969666312571 + ], + [ + 105.9799425116281, + 106.00989850871396, + 106.0357041162271 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06146696890292219, + "scoreError" : 0.0013111442609606396, + "scoreConfidence" : [ + 0.06015582464196155, + 0.06277811316388283 + ], + "scorePercentiles" : { + "0.0" : 0.06099497867642574, + "50.0" : 0.06146025591581415, + "90.0" : 0.06193752884704717, + "95.0" : 0.06193752884704717, + "99.0" : 0.06193752884704717, + "99.9" : 0.06193752884704717, + "99.99" : 0.06193752884704717, + "99.999" : 0.06193752884704717, + "99.9999" : 0.06193752884704717, + "100.0" : 0.06193752884704717 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0610976581640446, + 0.06103522918421406, + 0.06099497867642574 + ], + [ + 0.061913564878217905, + 0.06193752884704717, + 0.061822853667583694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.650252007566001E-4, + "scoreError" : 2.096583751124534E-5, + "scoreConfidence" : [ + 3.4405936324535477E-4, + 3.859910382678454E-4 + ], + "scorePercentiles" : { + "0.0" : 3.580183650284668E-4, + "50.0" : 3.650329137771385E-4, + "90.0" : 3.723388988078882E-4, + "95.0" : 3.723388988078882E-4, + "99.0" : 3.723388988078882E-4, + "99.9" : 3.723388988078882E-4, + "99.99" : 3.723388988078882E-4, + "99.999" : 3.723388988078882E-4, + "99.9999" : 3.723388988078882E-4, + "100.0" : 3.723388988078882E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7163264021046656E-4, + 3.715610749278557E-4, + 3.723388988078882E-4 + ], + [ + 3.5809547293850184E-4, + 3.580183650284668E-4, + 3.5850475262642125E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11151048857418296, + "scoreError" : 0.0036012004174408147, + "scoreConfidence" : [ + 0.10790928815674214, + 0.11511168899162377 + ], + "scorePercentiles" : { + "0.0" : 0.1101930165838393, + "50.0" : 0.11156708828092737, + "90.0" : 0.11269847700993982, + "95.0" : 0.11269847700993982, + "99.0" : 0.11269847700993982, + "99.9" : 0.11269847700993982, + "99.99" : 0.11269847700993982, + "99.999" : 0.11269847700993982, + "99.9999" : 0.11269847700993982, + "100.0" : 0.11269847700993982 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1101930165838393, + 0.1104775654676418, + 0.11035277646214964 + ], + [ + 0.11265661109421293, + 0.11268448482731422, + 0.11269847700993982 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014454337680991634, + "scoreError" : 0.0011056294165671127, + "scoreConfidence" : [ + 0.013348708264424521, + 0.015559967097558747 + ], + "scorePercentiles" : { + "0.0" : 0.01409273849412481, + "50.0" : 0.014436837402719276, + "90.0" : 0.014840477070292443, + "95.0" : 0.014840477070292443, + "99.0" : 0.014840477070292443, + "99.9" : 0.014840477070292443, + "99.99" : 0.014840477070292443, + "99.999" : 0.014840477070292443, + "99.9999" : 0.014840477070292443, + "100.0" : 0.014840477070292443 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01409420747970459, + 0.014097886918188278, + 0.01409273849412481 + ], + [ + 0.014840477070292443, + 0.014824928236389404, + 0.014775787887250274 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.013626964011056, + "scoreError" : 0.11286758364665457, + "scoreConfidence" : [ + 0.9007593803644014, + 1.1264945476577106 + ], + "scorePercentiles" : { + "0.0" : 0.9745805970178345, + "50.0" : 1.0122933979675715, + "90.0" : 1.0528886240261108, + "95.0" : 1.0528886240261108, + "99.0" : 1.0528886240261108, + "99.9" : 1.0528886240261108, + "99.99" : 1.0528886240261108, + "99.999" : 1.0528886240261108, + "99.9999" : 1.0528886240261108, + "100.0" : 1.0528886240261108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.052404088498369, + 1.0528886240261108, + 1.045514877783586 + ], + [ + 0.9790719181515567, + 0.9773016785888791, + 0.9745805970178345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013090921400999338, + "scoreError" : 5.52469163409891E-4, + "scoreConfidence" : [ + 0.012538452237589447, + 0.01364339056440923 + ], + "scorePercentiles" : { + "0.0" : 0.012824598348230888, + "50.0" : 0.013110151532014044, + "90.0" : 0.013274434060843224, + "95.0" : 0.013274434060843224, + "99.0" : 0.013274434060843224, + "99.9" : 0.013274434060843224, + "99.99" : 0.013274434060843224, + "99.999" : 0.013274434060843224, + "99.9999" : 0.013274434060843224, + "100.0" : 0.013274434060843224 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013274434060843224, + 0.013263107961930429, + 0.013256338659603857 + ], + [ + 0.012824598348230888, + 0.012963084970963393, + 0.012963964404424233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6553551250394416, + "scoreError" : 0.05582724698160624, + "scoreConfidence" : [ + 3.5995278780578355, + 3.7111823720210477 + ], + "scorePercentiles" : { + "0.0" : 3.6290547503628448, + "50.0" : 3.650766546153256, + "90.0" : 3.6828544558173784, + "95.0" : 3.6828544558173784, + "99.0" : 3.6828544558173784, + "99.9" : 3.6828544558173784, + "99.99" : 3.6828544558173784, + "99.999" : 3.6828544558173784, + "99.9999" : 3.6828544558173784, + "100.0" : 3.6828544558173784 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.64799881619256, + 3.6444350153061222, + 3.6535342761139518 + ], + [ + 3.6290547503628448, + 3.6828544558173784, + 3.6742534364437915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8171906726572473, + "scoreError" : 0.026122920412839375, + "scoreConfidence" : [ + 2.791067752244408, + 2.8433135930700866 + ], + "scorePercentiles" : { + "0.0" : 2.807821878158338, + "50.0" : 2.8164682150858207, + "90.0" : 2.8307121052929523, + "95.0" : 2.8307121052929523, + "99.0" : 2.8307121052929523, + "99.9" : 2.8307121052929523, + "99.99" : 2.8307121052929523, + "99.999" : 2.8307121052929523, + "99.9999" : 2.8307121052929523, + "100.0" : 2.8307121052929523 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.812385161136108, + 2.8079230870297587, + 2.807821878158338 + ], + [ + 2.820551269035533, + 2.8307121052929523, + 2.823750535290796 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.19253867275, + "scoreError" : 1.3275032103318722, + "scoreConfidence" : [ + 4.865035462418128, + 7.520041883081872 + ], + "scorePercentiles" : { + "0.0" : 5.9956882395, + "50.0" : 6.18323885725, + "90.0" : 6.407988737, + "95.0" : 6.407988737, + "99.0" : 6.407988737, + "99.9" : 6.407988737, + "99.99" : 6.407988737, + "99.999" : 6.407988737, + "99.9999" : 6.407988737, + "100.0" : 6.407988737 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.0395971985, + 6.326880516 + ], + [ + 5.9956882395, + 6.407988737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17472567296834188, + "scoreError" : 0.001246385199007067, + "scoreConfidence" : [ + 0.1734792877693348, + 0.17597205816734895 + ], + "scorePercentiles" : { + "0.0" : 0.17418555248994094, + "50.0" : 0.17477212609355527, + "90.0" : 0.1752152739250797, + "95.0" : 0.1752152739250797, + "99.0" : 0.1752152739250797, + "99.9" : 0.1752152739250797, + "99.99" : 0.1752152739250797, + "99.999" : 0.1752152739250797, + "99.9999" : 0.1752152739250797, + "100.0" : 0.1752152739250797 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17468682441001276, + 0.17423726711851414, + 0.17418555248994094 + ], + [ + 0.17517169208940583, + 0.1752152739250797, + 0.17485742777709778 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3269344119849197, + "scoreError" : 0.027100657627667255, + "scoreConfidence" : [ + 0.2998337543572524, + 0.35403506961258696 + ], + "scorePercentiles" : { + "0.0" : 0.3176090671727117, + "50.0" : 0.3271259233227094, + "90.0" : 0.3365622321206206, + "95.0" : 0.3365622321206206, + "99.0" : 0.3365622321206206, + "99.9" : 0.3365622321206206, + "99.99" : 0.3365622321206206, + "99.999" : 0.3365622321206206, + "99.9999" : 0.3365622321206206, + "100.0" : 0.3365622321206206 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3365622321206206, + 0.3354636546125461, + 0.33517605030835235 + ], + [ + 0.31907579633706645, + 0.3177196713582208, + 0.3176090671727117 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1623726378248437, + "scoreError" : 0.010379303412992967, + "scoreConfidence" : [ + 0.15199333441185073, + 0.1727519412378367 + ], + "scorePercentiles" : { + "0.0" : 0.15891018695375814, + "50.0" : 0.16221927924021579, + "90.0" : 0.16600401244999252, + "95.0" : 0.16600401244999252, + "99.0" : 0.16600401244999252, + "99.9" : 0.16600401244999252, + "99.99" : 0.16600401244999252, + "99.999" : 0.16600401244999252, + "99.9999" : 0.16600401244999252, + "100.0" : 0.16600401244999252 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16600401244999252, + 0.1658432150118576, + 0.16539146103466526 + ], + [ + 0.15903985405302248, + 0.15891018695375814, + 0.15904709744576628 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3932025477213803, + "scoreError" : 0.011982173260084241, + "scoreConfidence" : [ + 0.3812203744612961, + 0.4051847209814645 + ], + "scorePercentiles" : { + "0.0" : 0.39067946548423643, + "50.0" : 0.39156479063393246, + "90.0" : 0.4018392396126336, + "95.0" : 0.4018392396126336, + "99.0" : 0.4018392396126336, + "99.9" : 0.4018392396126336, + "99.99" : 0.4018392396126336, + "99.999" : 0.4018392396126336, + "99.9999" : 0.4018392396126336, + "100.0" : 0.4018392396126336 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3924692785321821, + 0.39156603394807943, + 0.39156354731978543 + ], + [ + 0.4018392396126336, + 0.39067946548423643, + 0.3910977214313649 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15476892149701563, + "scoreError" : 0.004714815404976954, + "scoreConfidence" : [ + 0.15005410609203867, + 0.15948373690199258 + ], + "scorePercentiles" : { + "0.0" : 0.15297736484625976, + "50.0" : 0.15483975883254003, + "90.0" : 0.15681389060858383, + "95.0" : 0.15681389060858383, + "99.0" : 0.15681389060858383, + "99.9" : 0.15681389060858383, + "99.99" : 0.15681389060858383, + "99.999" : 0.15681389060858383, + "99.9999" : 0.15681389060858383, + "100.0" : 0.15681389060858383 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15681389060858383, + 0.1559906344917951, + 0.15598571484947746 + ], + [ + 0.15297736484625976, + 0.15369380281560263, + 0.1531521213703749 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0480902862179155, + "scoreError" : 0.003078461531903063, + "scoreConfidence" : [ + 0.04501182468601244, + 0.05116874774981856 + ], + "scorePercentiles" : { + "0.0" : 0.046929009517060784, + "50.0" : 0.048166273815346786, + "90.0" : 0.04931991827323795, + "95.0" : 0.04931991827323795, + "99.0" : 0.04931991827323795, + "99.9" : 0.04931991827323795, + "99.99" : 0.04931991827323795, + "99.999" : 0.04931991827323795, + "99.9999" : 0.04931991827323795, + "100.0" : 0.04931991827323795 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04931991827323795, + 0.04898645612591297, + 0.04890928217330275 + ], + [ + 0.04742326545739081, + 0.04697378576058773, + 0.046929009517060784 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9221745.397668578, + "scoreError" : 143861.5511208718, + "scoreConfidence" : [ + 9077883.846547706, + 9365606.94878945 + ], + "scorePercentiles" : { + "0.0" : 9168308.037580201, + "50.0" : 9218388.63718991, + "90.0" : 9287273.291550603, + "95.0" : 9287273.291550603, + "99.0" : 9287273.291550603, + "99.9" : 9287273.291550603, + "99.99" : 9287273.291550603, + "99.999" : 9287273.291550603, + "99.9999" : 9287273.291550603, + "100.0" : 9287273.291550603 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9287273.291550603, + 9254544.11933395, + 9260037.392592592 + ], + [ + 9168308.037580201, + 9182233.15504587, + 9178076.389908256 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-06T06:59:43Z-5f071380a3130ed30e1f827392da3c478b80ee0f-jdk17.json b/performance-results/2025-05-06T06:59:43Z-5f071380a3130ed30e1f827392da3c478b80ee0f-jdk17.json new file mode 100644 index 0000000000..3c4638c98a --- /dev/null +++ b/performance-results/2025-05-06T06:59:43Z-5f071380a3130ed30e1f827392da3c478b80ee0f-jdk17.json @@ -0,0 +1,1383 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4274948140048926, + "scoreError" : 0.019815404564520085, + "scoreConfidence" : [ + 3.4076794094403726, + 3.4473102185694127 + ], + "scorePercentiles" : { + "0.0" : 3.4231017853962156, + "50.0" : 3.428316700808038, + "90.0" : 3.430244069007278, + "95.0" : 3.430244069007278, + "99.0" : 3.430244069007278, + "99.9" : 3.430244069007278, + "99.99" : 3.430244069007278, + "99.999" : 3.430244069007278, + "99.9999" : 3.430244069007278, + "100.0" : 3.430244069007278 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.4283427208899386, + 3.430244069007278 + ], + [ + 3.4231017853962156, + 3.4282906807261373 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7314748261185322, + "scoreError" : 0.002425073185432369, + "scoreConfidence" : [ + 1.7290497529331, + 1.7338998993039645 + ], + "scorePercentiles" : { + "0.0" : 1.73111392401501, + "50.0" : 1.7314727394851182, + "90.0" : 1.7318399014888823, + "95.0" : 1.7318399014888823, + "99.0" : 1.7318399014888823, + "99.9" : 1.7318399014888823, + "99.99" : 1.7318399014888823, + "99.999" : 1.7318399014888823, + "99.9999" : 1.7318399014888823, + "100.0" : 1.7318399014888823 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7311908065258408, + 1.73111392401501 + ], + [ + 1.7318399014888823, + 1.7317546724443955 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8672666922031457, + "scoreError" : 0.009391448234389031, + "scoreConfidence" : [ + 0.8578752439687567, + 0.8766581404375346 + ], + "scorePercentiles" : { + "0.0" : 0.8658586331067909, + "50.0" : 0.8671549256544173, + "90.0" : 0.8688982843969567, + "95.0" : 0.8688982843969567, + "99.0" : 0.8688982843969567, + "99.9" : 0.8688982843969567, + "99.99" : 0.8688982843969567, + "99.999" : 0.8688982843969567, + "99.9999" : 0.8688982843969567, + "100.0" : 0.8688982843969567 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8658586331067909, + 0.8662420022279755 + ], + [ + 0.8680678490808592, + 0.8688982843969567 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.109411242030568, + "scoreError" : 0.1789687806930012, + "scoreConfidence" : [ + 15.930442461337567, + 16.28838002272357 + ], + "scorePercentiles" : { + "0.0" : 16.025294687129527, + "50.0" : 16.13328814089325, + "90.0" : 16.175282332460707, + "95.0" : 16.175282332460707, + "99.0" : 16.175282332460707, + "99.9" : 16.175282332460707, + "99.99" : 16.175282332460707, + "99.999" : 16.175282332460707, + "99.9999" : 16.175282332460707, + "100.0" : 16.175282332460707 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.15486867197354, + 16.175282332460707, + 16.125376716746217 + ], + [ + 16.034445478833135, + 16.025294687129527, + 16.14119956504028 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2654.8268339342053, + "scoreError" : 128.79136200911495, + "scoreConfidence" : [ + 2526.0354719250904, + 2783.61819594332 + ], + "scorePercentiles" : { + "0.0" : 2605.825643671692, + "50.0" : 2658.5911162574616, + "90.0" : 2703.10671751895, + "95.0" : 2703.10671751895, + "99.0" : 2703.10671751895, + "99.9" : 2703.10671751895, + "99.99" : 2703.10671751895, + "99.999" : 2703.10671751895, + "99.9999" : 2703.10671751895, + "100.0" : 2703.10671751895 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2696.352508663536, + 2703.10671751895, + 2687.9693293983696 + ], + [ + 2605.825643671692, + 2606.49390123613, + 2629.2129031165537 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 71263.75060667233, + "scoreError" : 813.7624659973826, + "scoreConfidence" : [ + 70449.98814067495, + 72077.51307266971 + ], + "scorePercentiles" : { + "0.0" : 70968.28323881395, + "50.0" : 71251.06800695727, + "90.0" : 71558.53739761094, + "95.0" : 71558.53739761094, + "99.0" : 71558.53739761094, + "99.9" : 71558.53739761094, + "99.99" : 71558.53739761094, + "99.999" : 71558.53739761094, + "99.9999" : 71558.53739761094, + "100.0" : 71558.53739761094 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71469.38940133234, + 71558.53739761094, + 71551.43480720546 + ], + [ + 71032.7466125822, + 71002.11218248906, + 70968.28323881395 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 358.6809641084505, + "scoreError" : 6.926072374440979, + "scoreConfidence" : [ + 351.7548917340095, + 365.6070364828915 + ], + "scorePercentiles" : { + "0.0" : 354.6951861182518, + "50.0" : 359.17557777119225, + "90.0" : 361.1811305252531, + "95.0" : 361.1811305252531, + "99.0" : 361.1811305252531, + "99.9" : 361.1811305252531, + "99.99" : 361.1811305252531, + "99.999" : 361.1811305252531, + "99.9999" : 361.1811305252531, + "100.0" : 361.1811305252531 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.71189474900234, + 360.01106459465564, + 361.1811305252531 + ], + [ + 358.3400909477289, + 354.6951861182518, + 357.14641771581114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.16191143148728612, + "scoreError" : 0.03168675834844535, + "scoreConfidence" : [ + 0.13022467313884079, + 0.19359818983573146 + ], + "scorePercentiles" : { + "0.0" : 0.15697226012559007, + "50.0" : 0.16114050676664457, + "90.0" : 0.16839245229026528, + "95.0" : 0.16839245229026528, + "99.0" : 0.16839245229026528, + "99.9" : 0.16839245229026528, + "99.99" : 0.16839245229026528, + "99.999" : 0.16839245229026528, + "99.9999" : 0.16839245229026528, + "100.0" : 0.16839245229026528 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.16264832557705297, + 0.15697226012559007 + ], + [ + 0.16839245229026528, + 0.15963268795623617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 108.38784234430334, + "scoreError" : 7.923395204431814, + "scoreConfidence" : [ + 100.46444713987152, + 116.31123754873515 + ], + "scorePercentiles" : { + "0.0" : 105.72853765848248, + "50.0" : 108.3916951280389, + "90.0" : 111.02142912431371, + "95.0" : 111.02142912431371, + "99.0" : 111.02142912431371, + "99.9" : 111.02142912431371, + "99.99" : 111.02142912431371, + "99.999" : 111.02142912431371, + "99.9999" : 111.02142912431371, + "100.0" : 111.02142912431371 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.72853765848248, + 105.88171728740609, + 105.81701617957165 + ], + [ + 110.97668084737425, + 110.90167296867172, + 111.02142912431371 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061283431978971285, + "scoreError" : 6.846496817103977E-4, + "scoreConfidence" : [ + 0.060598782297260886, + 0.061968081660681684 + ], + "scorePercentiles" : { + "0.0" : 0.0610864050456614, + "50.0" : 0.061175787743609863, + "90.0" : 0.0616975123239328, + "95.0" : 0.0616975123239328, + "99.0" : 0.0616975123239328, + "99.9" : 0.0616975123239328, + "99.99" : 0.0616975123239328, + "99.999" : 0.0616975123239328, + "99.9999" : 0.0616975123239328, + "100.0" : 0.0616975123239328 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0611124470865035, + 0.061452651930510235, + 0.0616975123239328 + ], + [ + 0.06123377353025822, + 0.0610864050456614, + 0.061117801956961516 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.870853520286541E-4, + "scoreError" : 7.586012156841937E-6, + "scoreConfidence" : [ + 3.7949933987181216E-4, + 3.946713641854961E-4 + ], + "scorePercentiles" : { + "0.0" : 3.83362857637061E-4, + "50.0" : 3.872173559699855E-4, + "90.0" : 3.9001206379025207E-4, + "95.0" : 3.9001206379025207E-4, + "99.0" : 3.9001206379025207E-4, + "99.9" : 3.9001206379025207E-4, + "99.99" : 3.9001206379025207E-4, + "99.999" : 3.9001206379025207E-4, + "99.9999" : 3.9001206379025207E-4, + "100.0" : 3.9001206379025207E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.83362857637061E-4, + 3.8550402559716274E-4, + 3.8533605920758714E-4 + ], + [ + 3.9001206379025207E-4, + 3.889306863428083E-4, + 3.893664195970532E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.11009985832511282, + "scoreError" : 0.0031232888758091324, + "scoreConfidence" : [ + 0.10697656944930369, + 0.11322314720092196 + ], + "scorePercentiles" : { + "0.0" : 0.1090115867989317, + "50.0" : 0.11004520755808582, + "90.0" : 0.11121798916754713, + "95.0" : 0.11121798916754713, + "99.0" : 0.11121798916754713, + "99.9" : 0.11121798916754713, + "99.99" : 0.11121798916754713, + "99.999" : 0.11121798916754713, + "99.9999" : 0.11121798916754713, + "100.0" : 0.11121798916754713 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11095645377079011, + 0.11116385372225125, + 0.11121798916754713 + ], + [ + 0.10911530514577514, + 0.10913396134538153, + 0.1090115867989317 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014361303208532189, + "scoreError" : 9.008475681492518E-4, + "scoreConfidence" : [ + 0.013460455640382937, + 0.01526215077668144 + ], + "scorePercentiles" : { + "0.0" : 0.014056936544930355, + "50.0" : 0.014367534783958672, + "90.0" : 0.014662941026392961, + "95.0" : 0.014662941026392961, + "99.0" : 0.014662941026392961, + "99.9" : 0.014662941026392961, + "99.99" : 0.014662941026392961, + "99.999" : 0.014662941026392961, + "99.9999" : 0.014662941026392961, + "100.0" : 0.014662941026392961 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014056936544930355, + 0.014060548877350015, + 0.014087211004237384 + ], + [ + 0.01464785856367996, + 0.014662941026392961, + 0.014652323234602452 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9715748816156576, + "scoreError" : 0.01684348480317524, + "scoreConfidence" : [ + 0.9547313968124824, + 0.9884183664188328 + ], + "scorePercentiles" : { + "0.0" : 0.9643964800385728, + "50.0" : 0.9709968658231811, + "90.0" : 0.9814247137389598, + "95.0" : 0.9814247137389598, + "99.0" : 0.9814247137389598, + "99.9" : 0.9814247137389598, + "99.99" : 0.9814247137389598, + "99.999" : 0.9814247137389598, + "99.9999" : 0.9814247137389598, + "100.0" : 0.9814247137389598 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9695136693165294, + 0.9672374933746011, + 0.9643964800385728 + ], + [ + 0.9814247137389598, + 0.9743968708954497, + 0.9724800623298328 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.013298563879302373, + "scoreError" : 7.978731914848166E-4, + "scoreConfidence" : [ + 0.012500690687817556, + 0.01409643707078719 + ], + "scorePercentiles" : { + "0.0" : 0.01298430556053276, + "50.0" : 0.013285627442692426, + "90.0" : 0.013604988218360311, + "95.0" : 0.013604988218360311, + "99.0" : 0.013604988218360311, + "99.9" : 0.013604988218360311, + "99.99" : 0.013604988218360311, + "99.999" : 0.013604988218360311, + "99.9999" : 0.013604988218360311, + "100.0" : 0.013604988218360311 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013473226458105978, + 0.013604988218360311, + 0.013580785719329885 + ], + [ + 0.01298430556053276, + 0.013098028427278871, + 0.013050048892206427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6649080310068354, + "scoreError" : 0.0656917564380821, + "scoreConfidence" : [ + 3.5992162745687533, + 3.7305997874449175 + ], + "scorePercentiles" : { + "0.0" : 3.6245500456521738, + "50.0" : 3.665970831381784, + "90.0" : 3.6896134483775813, + "95.0" : 3.6896134483775813, + "99.0" : 3.6896134483775813, + "99.9" : 3.6896134483775813, + "99.99" : 3.6896134483775813, + "99.999" : 3.6896134483775813, + "99.9999" : 3.6896134483775813, + "100.0" : 3.6896134483775813 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6896134483775813, + 3.6842562201767306, + 3.6590868090709585 + ], + [ + 3.6245500456521738, + 3.6728387995594716, + 3.6591028632040965 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8892314465124467, + "scoreError" : 0.21817381698837585, + "scoreConfidence" : [ + 2.671057629524071, + 3.1074052635008225 + ], + "scorePercentiles" : { + "0.0" : 2.8115710503233062, + "50.0" : 2.889482907781501, + "90.0" : 2.97219625794948, + "95.0" : 2.97219625794948, + "99.0" : 2.97219625794948, + "99.9" : 2.97219625794948, + "99.99" : 2.97219625794948, + "99.999" : 2.97219625794948, + "99.9999" : 2.97219625794948, + "100.0" : 2.97219625794948 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8315745812570783, + 2.8115710503233062, + 2.813429184528833 + ], + [ + 2.947391234305924, + 2.97219625794948, + 2.9592263707100592 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.LargeInMemoryQueryPerformance.benchMarkSimpleQueriesAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6.226174725125, + "scoreError" : 1.0121014676875972, + "scoreConfidence" : [ + 5.214073257437403, + 7.238276192812598 + ], + "scorePercentiles" : { + "0.0" : 6.0414780505, + "50.0" : 6.223016444000001, + "90.0" : 6.417187962, + "95.0" : 6.417187962, + "99.0" : 6.417187962, + "99.9" : 6.417187962, + "99.99" : 6.417187962, + "99.999" : 6.417187962, + "99.9999" : 6.417187962, + "100.0" : 6.417187962 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 6.0414780505, + 6.2615793635 + ], + [ + 6.1844535245, + 6.417187962 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.174208750789316, + "scoreError" : 0.005875458271976553, + "scoreConfidence" : [ + 0.16833329251733944, + 0.18008420906129255 + ], + "scorePercentiles" : { + "0.0" : 0.1718808210412334, + "50.0" : 0.17432058404910458, + "90.0" : 0.17673681073486266, + "95.0" : 0.17673681073486266, + "99.0" : 0.17673681073486266, + "99.9" : 0.17673681073486266, + "99.99" : 0.17673681073486266, + "99.999" : 0.17673681073486266, + "99.9999" : 0.17673681073486266, + "100.0" : 0.17673681073486266 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17308537468845195, + 0.17212955292011636, + 0.1718808210412334 + ], + [ + 0.17673681073486266, + 0.1758641519414744, + 0.17555579340975722 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33039262061397084, + "scoreError" : 0.004694267193263049, + "scoreConfidence" : [ + 0.3256983534207078, + 0.3350868878072339 + ], + "scorePercentiles" : { + "0.0" : 0.3283385040220639, + "50.0" : 0.33082092781170713, + "90.0" : 0.33283826766516894, + "95.0" : 0.33283826766516894, + "99.0" : 0.33283826766516894, + "99.9" : 0.33283826766516894, + "99.99" : 0.33283826766516894, + "99.999" : 0.33283826766516894, + "99.9999" : 0.33283826766516894, + "100.0" : 0.33283826766516894 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3283385040220639, + 0.33080202368508105, + 0.3286142943611987 + ], + [ + 0.33283826766516894, + 0.3309228020119792, + 0.3308398319383333 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1596296598213994, + "scoreError" : 0.00964103113056959, + "scoreConfidence" : [ + 0.14998862869082982, + 0.16927069095196898 + ], + "scorePercentiles" : { + "0.0" : 0.15626861796418415, + "50.0" : 0.15960347243945344, + "90.0" : 0.16290861315283614, + "95.0" : 0.16290861315283614, + "99.0" : 0.16290861315283614, + "99.9" : 0.16290861315283614, + "99.99" : 0.16290861315283614, + "99.999" : 0.16290861315283614, + "99.9999" : 0.16290861315283614, + "100.0" : 0.16290861315283614 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16290861315283614, + 0.16279553734453345, + 0.1625901399863428 + ], + [ + 0.15661680489256405, + 0.15659824558793592, + 0.15626861796418415 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39055867423443386, + "scoreError" : 0.006712356621653988, + "scoreConfidence" : [ + 0.3838463176127799, + 0.39727103085608784 + ], + "scorePercentiles" : { + "0.0" : 0.38766473565669096, + "50.0" : 0.39067229276938564, + "90.0" : 0.39335552204696533, + "95.0" : 0.39335552204696533, + "99.0" : 0.39335552204696533, + "99.9" : 0.39335552204696533, + "99.99" : 0.39335552204696533, + "99.999" : 0.39335552204696533, + "99.9999" : 0.39335552204696533, + "100.0" : 0.39335552204696533 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3921351710061956, + 0.3925106822356543, + 0.39335552204696533 + ], + [ + 0.3884765199285215, + 0.3892094145325757, + 0.38766473565669096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15650644033707403, + "scoreError" : 0.012118884589496951, + "scoreConfidence" : [ + 0.14438755574757708, + 0.16862532492657098 + ], + "scorePercentiles" : { + "0.0" : 0.1524325068898238, + "50.0" : 0.15654782870735393, + "90.0" : 0.16070292175547984, + "95.0" : 0.16070292175547984, + "99.0" : 0.16070292175547984, + "99.9" : 0.16070292175547984, + "99.99" : 0.16070292175547984, + "99.999" : 0.16070292175547984, + "99.9999" : 0.16070292175547984, + "100.0" : 0.16070292175547984 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16027296918022277, + 0.1603661441331644, + 0.16070292175547984 + ], + [ + 0.15282268823448508, + 0.1524414118292683, + 0.1524325068898238 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047363776100216644, + "scoreError" : 3.95546506965149E-4, + "scoreConfidence" : [ + 0.0469682295932515, + 0.04775932260718179 + ], + "scorePercentiles" : { + "0.0" : 0.04716881258254405, + "50.0" : 0.04735179398254641, + "90.0" : 0.04758480779333251, + "95.0" : 0.04758480779333251, + "99.0" : 0.04758480779333251, + "99.9" : 0.04758480779333251, + "99.99" : 0.04758480779333251, + "99.999" : 0.04758480779333251, + "99.9999" : 0.04758480779333251, + "100.0" : 0.04758480779333251 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04743432101640729, + 0.04738401337629416, + 0.04716881258254405 + ], + [ + 0.04758480779333251, + 0.0472911272439232, + 0.047319574588798666 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9292059.801090613, + "scoreError" : 1093430.051071653, + "scoreConfidence" : [ + 8198629.75001896, + 1.0385489852162266E7 + ], + "scorePercentiles" : { + "0.0" : 8927506.744870652, + "50.0" : 9291195.943758812, + "90.0" : 9653870.822393822, + "95.0" : 9653870.822393822, + "99.0" : 9653870.822393822, + "99.9" : 9653870.822393822, + "99.99" : 9653870.822393822, + "99.999" : 9653870.822393822, + "99.9999" : 9653870.822393822, + "100.0" : 9653870.822393822 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8945201.296958854, + 8927506.744870652, + 8935842.590178572 + ], + [ + 9653870.822393822, + 9652746.761583012, + 9637190.590558767 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-08T09:55:21Z-2eed3a690e159857677547c41f3686fd4fb131cb-jdk17.json b/performance-results/2025-05-08T09:55:21Z-2eed3a690e159857677547c41f3686fd4fb131cb-jdk17.json new file mode 100644 index 0000000000..d316019bb3 --- /dev/null +++ b/performance-results/2025-05-08T09:55:21Z-2eed3a690e159857677547c41f3686fd4fb131cb-jdk17.json @@ -0,0 +1,181 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.largeSchema1", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.05037110041903725, + "scoreError" : 3.648927036387041E-4, + "scoreConfidence" : [ + 0.05000620771539855, + 0.05073599312267595 + ], + "scorePercentiles" : { + "0.0" : 0.050167364590440265, + "50.0" : 0.050246103575968606, + "90.0" : 0.05066289795577172, + "95.0" : 0.05066289795577172, + "99.0" : 0.05066289795577172, + "99.9" : 0.05066289795577172, + "99.99" : 0.05066289795577172, + "99.999" : 0.05066289795577172, + "99.9999" : 0.05066289795577172, + "100.0" : 0.05066289795577172 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.050223124541719816, + 0.050167364590440265, + 0.050189584214567845 + ], + [ + 0.050246103575968606, + 0.05041447662067262, + 0.050169613991079984 + ], + [ + 0.05063743971440869, + 0.05066289795577172, + 0.05062929856670565 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.largeSchema4", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 21.3962776924908, + "scoreError" : 0.5382785637469608, + "scoreConfidence" : [ + 20.857999128743838, + 21.93455625623776 + ], + "scorePercentiles" : { + "0.0" : 20.982693540880504, + "50.0" : 21.3717974017094, + "90.0" : 21.782303667391304, + "95.0" : 21.782303667391304, + "99.0" : 21.782303667391304, + "99.9" : 21.782303667391304, + "99.99" : 21.782303667391304, + "99.999" : 21.782303667391304, + "99.9999" : 21.782303667391304, + "100.0" : 21.782303667391304 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 20.982693540880504, + 21.08151422736842, + 21.044756590336135 + ], + [ + 21.782303667391304, + 21.74976952173913, + 21.77905801304348 + ], + [ + 21.33301046695096, + 21.44159580299786, + 21.3717974017094 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.manyFragments", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 13.605598539304891, + "scoreError" : 0.041528819669041, + "scoreConfidence" : [ + 13.56406971963585, + 13.647127358973933 + ], + "scorePercentiles" : { + "0.0" : 13.571908153324287, + "50.0" : 13.600049917119565, + "90.0" : 13.645124362892224, + "95.0" : 13.645124362892224, + "99.0" : 13.645124362892224, + "99.9" : 13.645124362892224, + "99.99" : 13.645124362892224, + "99.999" : 13.645124362892224, + "99.9999" : 13.645124362892224, + "100.0" : 13.645124362892224 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 13.600049917119565, + 13.632648222070845, + 13.59452378125 + ], + [ + 13.584037056987789, + 13.571908153324287, + 13.583858663500678 + ], + [ + 13.645124362892224, + 13.619546295238095, + 13.618690401360544 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-08T10:27:23Z-e5ee22a3a56eedd025b4edf296a9768cea9217cd-jdk17.json b/performance-results/2025-05-08T10:27:23Z-e5ee22a3a56eedd025b4edf296a9768cea9217cd-jdk17.json new file mode 100644 index 0000000000..c8669ec6c8 --- /dev/null +++ b/performance-results/2025-05-08T10:27:23Z-e5ee22a3a56eedd025b4edf296a9768cea9217cd-jdk17.json @@ -0,0 +1,181 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.largeSchema1", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.02972921973588643, + "scoreError" : 2.7684413219470434E-4, + "scoreConfidence" : [ + 0.029452375603691724, + 0.030006063868081134 + ], + "scorePercentiles" : { + "0.0" : 0.029439274725339425, + "50.0" : 0.02975579625326188, + "90.0" : 0.02994045947467223, + "95.0" : 0.02994045947467223, + "99.0" : 0.02994045947467223, + "99.9" : 0.02994045947467223, + "99.99" : 0.02994045947467223, + "99.999" : 0.02994045947467223, + "99.9999" : 0.02994045947467223, + "100.0" : 0.02994045947467223 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.029576355392823765, + 0.029580841897268277, + 0.02974222042251217 + ], + [ + 0.02994045947467223, + 0.029890606422089645, + 0.029439274725339425 + ], + [ + 0.029811086942912506, + 0.029826336092098005, + 0.02975579625326188 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.largeSchema4", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 12.668458430740422, + "scoreError" : 1.1805915273343897, + "scoreConfidence" : [ + 11.487866903406033, + 13.849049958074811 + ], + "scorePercentiles" : { + "0.0" : 11.99842861031175, + "50.0" : 12.413366718362283, + "90.0" : 13.598897039402173, + "95.0" : 13.598897039402173, + "99.0" : 13.598897039402173, + "99.9" : 13.598897039402173, + "99.99" : 13.598897039402173, + "99.999" : 13.598897039402173, + "99.9999" : 13.598897039402173, + "100.0" : 13.598897039402173 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 13.598897039402173, + 13.560075350948509, + 13.559446012195123 + ], + [ + 12.282530855214723, + 12.413366718362283, + 12.54340595112782 + ], + [ + 12.039703132370638, + 11.99842861031175, + 12.02027220673077 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.manyFragments", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 8.515695505125898, + "scoreError" : 0.42296393832454243, + "scoreConfidence" : [ + 8.092731566801355, + 8.93865944345044 + ], + "scorePercentiles" : { + "0.0" : 8.141705238405207, + "50.0" : 8.641473876511226, + "90.0" : 8.75441319160105, + "95.0" : 8.75441319160105, + "99.0" : 8.75441319160105, + "99.9" : 8.75441319160105, + "99.99" : 8.75441319160105, + "99.999" : 8.75441319160105, + "99.9999" : 8.75441319160105, + "100.0" : 8.75441319160105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 8.262796129644922, + 8.157323823001631, + 8.141705238405207 + ], + [ + 8.72026731386225, + 8.75441319160105, + 8.69142112945265 + ], + [ + 8.643492397579948, + 8.628366446074201, + 8.641473876511226 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-08T10:51:47Z-886710753d02132446f3c796f474fa611163a1fd-jdk17.json b/performance-results/2025-05-08T10:51:47Z-886710753d02132446f3c796f474fa611163a1fd-jdk17.json new file mode 100644 index 0000000000..136baac7cd --- /dev/null +++ b/performance-results/2025-05-08T10:51:47Z-886710753d02132446f3c796f474fa611163a1fd-jdk17.json @@ -0,0 +1,181 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.largeSchema1", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.03588946212484385, + "scoreError" : 4.7140718135983906E-4, + "scoreConfidence" : [ + 0.03541805494348401, + 0.036360869306203684 + ], + "scorePercentiles" : { + "0.0" : 0.03561240574275478, + "50.0" : 0.035830644991848654, + "90.0" : 0.03643118911091277, + "95.0" : 0.03643118911091277, + "99.0" : 0.03643118911091277, + "99.9" : 0.03643118911091277, + "99.99" : 0.03643118911091277, + "99.999" : 0.03643118911091277, + "99.9999" : 0.03643118911091277, + "100.0" : 0.03643118911091277 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.03562620693180766, + 0.03561240574275478, + 0.03563747476194549 + ], + [ + 0.03643118911091277, + 0.03620586770961937, + 0.03601010940065681 + ], + [ + 0.035830644991848654, + 0.035836954771060074, + 0.03581430570298902 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.largeSchema4", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 14.314630405923973, + "scoreError" : 0.4815885716607373, + "scoreConfidence" : [ + 13.833041834263236, + 14.79621897758471 + ], + "scorePercentiles" : { + "0.0" : 13.965903894002789, + "50.0" : 14.35250331276901, + "90.0" : 14.824477482962964, + "95.0" : 14.824477482962964, + "99.0" : 14.824477482962964, + "99.9" : 14.824477482962964, + "99.99" : 14.824477482962964, + "99.999" : 14.824477482962964, + "99.9999" : 14.824477482962964, + "100.0" : 14.824477482962964 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 14.824477482962964, + 14.530075682148041, + 14.452718239884392 + ], + [ + 14.022494978991597, + 13.969122085195531, + 13.965903894002789 + ], + [ + 14.346336878223497, + 14.368041099137931, + 14.35250331276901 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "benchmark.ValidatorBenchmark.manyFragments", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 9.579567427027618, + "scoreError" : 0.39068822365148453, + "scoreConfidence" : [ + 9.188879203376134, + 9.970255650679102 + ], + "scorePercentiles" : { + "0.0" : 9.359694462114126, + "50.0" : 9.44529126345609, + "90.0" : 9.958791935323383, + "95.0" : 9.958791935323383, + "99.0" : 9.958791935323383, + "99.9" : 9.958791935323383, + "99.99" : 9.958791935323383, + "99.999" : 9.958791935323383, + "99.9999" : 9.958791935323383, + "100.0" : 9.958791935323383 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 9.428172920829406, + 9.40382117575188, + 9.405310712406015 + ], + [ + 9.958791935323383, + 9.833126397246804, + 9.847409210629921 + ], + [ + 9.534488765490943, + 9.44529126345609, + 9.359694462114126 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-11T04:22:39Z-7d9516a906b57a0cd1a98d10b3a54ba5f9f9f5e6-jdk17.json b/performance-results/2025-05-11T04:22:39Z-7d9516a906b57a0cd1a98d10b3a54ba5f9f9f5e6-jdk17.json new file mode 100644 index 0000000000..4e02f12af3 --- /dev/null +++ b/performance-results/2025-05-11T04:22:39Z-7d9516a906b57a0cd1a98d10b3a54ba5f9f9f5e6-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.321755214726807, + "scoreError" : 0.03784740798068185, + "scoreConfidence" : [ + 3.283907806746125, + 3.359602622707489 + ], + "scorePercentiles" : { + "0.0" : 3.317097183279122, + "50.0" : 3.3203070727332618, + "90.0" : 3.329309530161583, + "95.0" : 3.329309530161583, + "99.0" : 3.329309530161583, + "99.9" : 3.329309530161583, + "99.99" : 3.329309530161583, + "99.999" : 3.329309530161583, + "99.9999" : 3.329309530161583, + "100.0" : 3.329309530161583 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.317148619196145, + 3.323465526270379 + ], + [ + 3.317097183279122, + 3.329309530161583 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6831956247489366, + "scoreError" : 0.03200703808252988, + "scoreConfidence" : [ + 1.6511885866664067, + 1.7152026628314665 + ], + "scorePercentiles" : { + "0.0" : 1.6797429641902084, + "50.0" : 1.6812992018190203, + "90.0" : 1.6904411311674972, + "95.0" : 1.6904411311674972, + "99.0" : 1.6904411311674972, + "99.9" : 1.6904411311674972, + "99.99" : 1.6904411311674972, + "99.999" : 1.6904411311674972, + "99.9999" : 1.6904411311674972, + "100.0" : 1.6904411311674972 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6803018901699753, + 1.6797429641902084 + ], + [ + 1.6822965134680654, + 1.6904411311674972 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8450477408470614, + "scoreError" : 0.034944818887395736, + "scoreConfidence" : [ + 0.8101029219596656, + 0.8799925597344571 + ], + "scorePercentiles" : { + "0.0" : 0.8389020590339495, + "50.0" : 0.8447179948597651, + "90.0" : 0.851852914634766, + "95.0" : 0.851852914634766, + "99.0" : 0.851852914634766, + "99.9" : 0.851852914634766, + "99.99" : 0.851852914634766, + "99.999" : 0.851852914634766, + "99.9999" : 0.851852914634766, + "100.0" : 0.851852914634766 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8460283384789308, + 0.851852914634766 + ], + [ + 0.8389020590339495, + 0.8434076512405994 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.974823156553773, + "scoreError" : 0.3040839658090654, + "scoreConfidence" : [ + 15.670739190744708, + 16.27890712236284 + ], + "scorePercentiles" : { + "0.0" : 15.86707233097951, + "50.0" : 15.976674603217845, + "90.0" : 16.09879112784439, + "95.0" : 16.09879112784439, + "99.0" : 16.09879112784439, + "99.9" : 16.09879112784439, + "99.99" : 16.09879112784439, + "99.999" : 16.09879112784439, + "99.9999" : 16.09879112784439, + "100.0" : 16.09879112784439 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.057564299042436, + 16.09879112784439, + 16.061106407453916 + ], + [ + 15.86707233097951, + 15.86861986660914, + 15.895784907393251 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2701.4928808906166, + "scoreError" : 104.13066418929037, + "scoreConfidence" : [ + 2597.3622167013264, + 2805.6235450799068 + ], + "scorePercentiles" : { + "0.0" : 2665.7488528059566, + "50.0" : 2698.8346768361494, + "90.0" : 2738.719718090565, + "95.0" : 2738.719718090565, + "99.0" : 2738.719718090565, + "99.9" : 2738.719718090565, + "99.99" : 2738.719718090565, + "99.999" : 2738.719718090565, + "99.9999" : 2738.719718090565, + "100.0" : 2738.719718090565 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2738.319694039668, + 2728.602928567922, + 2738.719718090565 + ], + [ + 2669.066425104377, + 2668.4996667352116, + 2665.7488528059566 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69217.87540387959, + "scoreError" : 1255.9011580864683, + "scoreConfidence" : [ + 67961.97424579311, + 70473.77656196606 + ], + "scorePercentiles" : { + "0.0" : 68767.09378834584, + "50.0" : 69179.99400277555, + "90.0" : 69710.71150214219, + "95.0" : 69710.71150214219, + "99.0" : 69710.71150214219, + "99.9" : 69710.71150214219, + "99.99" : 69710.71150214219, + "99.999" : 69710.71150214219, + "99.9999" : 69710.71150214219, + "100.0" : 69710.71150214219 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 68767.09378834584, + 68889.97151064611, + 68795.88671736693 + ], + [ + 69470.016494905, + 69673.57240987147, + 69710.71150214219 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 335.5390922188157, + "scoreError" : 27.51780601246999, + "scoreConfidence" : [ + 308.02128620634574, + 363.0568982312857 + ], + "scorePercentiles" : { + "0.0" : 325.50262263541237, + "50.0" : 335.64223182719854, + "90.0" : 345.5429899678228, + "95.0" : 345.5429899678228, + "99.0" : 345.5429899678228, + "99.9" : 345.5429899678228, + "99.99" : 345.5429899678228, + "99.999" : 345.5429899678228, + "99.9999" : 345.5429899678228, + "100.0" : 345.5429899678228 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 343.55629816158176, + 344.26632256011516, + 345.5429899678228 + ], + [ + 327.7281654928153, + 325.50262263541237, + 326.638154495147 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 104.66046693307199, + "scoreError" : 2.7828443376637853, + "scoreConfidence" : [ + 101.8776225954082, + 107.44331127073578 + ], + "scorePercentiles" : { + "0.0" : 102.71755078932173, + "50.0" : 105.00441569159892, + "90.0" : 105.47556915800844, + "95.0" : 105.47556915800844, + "99.0" : 105.47556915800844, + "99.9" : 105.47556915800844, + "99.99" : 105.47556915800844, + "99.999" : 105.47556915800844, + "99.9999" : 105.47556915800844, + "100.0" : 105.47556915800844 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 102.71755078932173, + 105.07169119619266, + 105.47556915800844 + ], + [ + 104.93714018700518, + 105.14730443999524, + 104.6135458279087 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06189445165071968, + "scoreError" : 6.206799706235633E-4, + "scoreConfidence" : [ + 0.061273771680096116, + 0.06251513162134324 + ], + "scorePercentiles" : { + "0.0" : 0.0616818912999229, + "50.0" : 0.06187882060587834, + "90.0" : 0.06214901881844058, + "95.0" : 0.06214901881844058, + "99.0" : 0.06214901881844058, + "99.9" : 0.06214901881844058, + "99.99" : 0.06214901881844058, + "99.999" : 0.06214901881844058, + "99.9999" : 0.06214901881844058, + "100.0" : 0.06214901881844058 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062056362495113156, + 0.06214901881844058, + 0.06207800124774196 + ], + [ + 0.06170127871664353, + 0.061700157326455944, + 0.0616818912999229 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6222278417058626E-4, + "scoreError" : 1.436205728799381E-6, + "scoreConfidence" : [ + 3.6078657844178686E-4, + 3.6365898989938565E-4 + ], + "scorePercentiles" : { + "0.0" : 3.615833889109351E-4, + "50.0" : 3.621813052566248E-4, + "90.0" : 3.6304272550598184E-4, + "95.0" : 3.6304272550598184E-4, + "99.0" : 3.6304272550598184E-4, + "99.9" : 3.6304272550598184E-4, + "99.99" : 3.6304272550598184E-4, + "99.999" : 3.6304272550598184E-4, + "99.9999" : 3.6304272550598184E-4, + "100.0" : 3.6304272550598184E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.624321171897431E-4, + 3.6304272550598184E-4, + 3.619703884101321E-4 + ], + [ + 3.6191586290360814E-4, + 3.615833889109351E-4, + 3.623922221031176E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10569772905795588, + "scoreError" : 0.005766000783490596, + "scoreConfidence" : [ + 0.09993172827446528, + 0.11146372984144648 + ], + "scorePercentiles" : { + "0.0" : 0.10378403606417867, + "50.0" : 0.10562626161616948, + "90.0" : 0.1078374621066707, + "95.0" : 0.1078374621066707, + "99.0" : 0.1078374621066707, + "99.9" : 0.1078374621066707, + "99.99" : 0.1078374621066707, + "99.999" : 0.1078374621066707, + "99.9999" : 0.1078374621066707, + "100.0" : 0.1078374621066707 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10378403606417867, + 0.10380597842966284, + 0.10388855987492078 + ], + [ + 0.1078374621066707, + 0.10750637451488405, + 0.10736396335741816 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014650392799757389, + "scoreError" : 4.607404163229839E-4, + "scoreConfidence" : [ + 0.014189652383434405, + 0.015111133216080373 + ], + "scorePercentiles" : { + "0.0" : 0.014497930270151154, + "50.0" : 0.014649711624315102, + "90.0" : 0.014804060042931163, + "95.0" : 0.014804060042931163, + "99.0" : 0.014804060042931163, + "99.9" : 0.014804060042931163, + "99.99" : 0.014804060042931163, + "99.999" : 0.014804060042931163, + "99.9999" : 0.014804060042931163, + "100.0" : 0.014804060042931163 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01450220590956552, + 0.014497930270151154, + 0.014501132174707443 + ], + [ + 0.014799811062124368, + 0.014797217339064686, + 0.014804060042931163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0229649178515388, + "scoreError" : 0.05788767400199589, + "scoreConfidence" : [ + 0.9650772438495429, + 1.0808525918535346 + ], + "scorePercentiles" : { + "0.0" : 0.9965358906826108, + "50.0" : 1.0235189831895215, + "90.0" : 1.0449999470219435, + "95.0" : 1.0449999470219435, + "99.0" : 1.0449999470219435, + "99.9" : 1.0449999470219435, + "99.99" : 1.0449999470219435, + "99.999" : 1.0449999470219435, + "99.9999" : 1.0449999470219435, + "100.0" : 1.0449999470219435 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0408379277685262, + 1.0449999470219435, + 1.0379038788916564 + ], + [ + 1.0083777752571084, + 0.9965358906826108, + 1.0091340874873864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01233187839236372, + "scoreError" : 0.002065716953982727, + "scoreConfidence" : [ + 0.010266161438380994, + 0.014397595346346447 + ], + "scorePercentiles" : { + "0.0" : 0.01164799008554017, + "50.0" : 0.012335272617598625, + "90.0" : 0.013011149584826319, + "95.0" : 0.013011149584826319, + "99.0" : 0.013011149584826319, + "99.9" : 0.013011149584826319, + "99.99" : 0.013011149584826319, + "99.999" : 0.013011149584826319, + "99.9999" : 0.013011149584826319, + "100.0" : 0.013011149584826319 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01164799008554017, + 0.011658676801686267, + 0.011671690615911076 + ], + [ + 0.013011149584826319, + 0.013002908646932317, + 0.012998854619286173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.847116915236733, + "scoreError" : 0.15295487315868667, + "scoreConfidence" : [ + 3.6941620420780463, + 4.000071788395419 + ], + "scorePercentiles" : { + "0.0" : 3.773638907239819, + "50.0" : 3.869265487575702, + "90.0" : 3.894678387071651, + "95.0" : 3.894678387071651, + "99.0" : 3.894678387071651, + "99.9" : 3.894678387071651, + "99.99" : 3.894678387071651, + "99.999" : 3.894678387071651, + "99.9999" : 3.894678387071651, + "100.0" : 3.894678387071651 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.892681727626459, + 3.8751172052672347, + 3.894678387071651 + ], + [ + 3.8634137698841697, + 3.7831714943310657, + 3.773638907239819 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9797002593735313, + "scoreError" : 0.011882920216597351, + "scoreConfidence" : [ + 2.967817339156934, + 2.991583179590129 + ], + "scorePercentiles" : { + "0.0" : 2.9745567911957167, + "50.0" : 2.9795149181285163, + "90.0" : 2.9864260644968645, + "95.0" : 2.9864260644968645, + "99.0" : 2.9864260644968645, + "99.9" : 2.9864260644968645, + "99.99" : 2.9864260644968645, + "99.999" : 2.9864260644968645, + "99.9999" : 2.9864260644968645, + "100.0" : 2.9864260644968645 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9763880276785715, + 2.978365785884455, + 2.9745567911957167 + ], + [ + 2.980664050372578, + 2.9864260644968645, + 2.9818008366129996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17938311706802712, + "scoreError" : 0.00918432020980252, + "scoreConfidence" : [ + 0.1701987968582246, + 0.18856743727782965 + ], + "scorePercentiles" : { + "0.0" : 0.1763890787208523, + "50.0" : 0.17864971073123184, + "90.0" : 0.18346935419953767, + "95.0" : 0.18346935419953767, + "99.0" : 0.18346935419953767, + "99.9" : 0.18346935419953767, + "99.99" : 0.18346935419953767, + "99.999" : 0.18346935419953767, + "99.9999" : 0.18346935419953767, + "100.0" : 0.18346935419953767 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17670494580601842, + 0.17646691988706548, + 0.1763890787208523 + ], + [ + 0.18346935419953767, + 0.18267392813824346, + 0.18059447565644526 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3385581582622825, + "scoreError" : 0.006812947137468368, + "scoreConfidence" : [ + 0.33174521112481414, + 0.3453711053997509 + ], + "scorePercentiles" : { + "0.0" : 0.3365162952855268, + "50.0" : 0.3376265530343475, + "90.0" : 0.3425956716341213, + "95.0" : 0.3425956716341213, + "99.0" : 0.3425956716341213, + "99.9" : 0.3425956716341213, + "99.99" : 0.3425956716341213, + "99.999" : 0.3425956716341213, + "99.9999" : 0.3425956716341213, + "100.0" : 0.3425956716341213 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3425956716341213, + 0.34025810585233074, + 0.3367257707330213 + ], + [ + 0.3365162952855268, + 0.3368985727759625, + 0.33835453329273246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15470342614514052, + "scoreError" : 0.0011858530750550893, + "scoreConfidence" : [ + 0.15351757307008543, + 0.1558892792201956 + ], + "scorePercentiles" : { + "0.0" : 0.1542367767015747, + "50.0" : 0.1546718108122327, + "90.0" : 0.1552512860136929, + "95.0" : 0.1552512860136929, + "99.0" : 0.1552512860136929, + "99.9" : 0.1552512860136929, + "99.99" : 0.1552512860136929, + "99.999" : 0.1552512860136929, + "99.9999" : 0.1552512860136929, + "100.0" : 0.1552512860136929 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15483104629342911, + 0.1552512860136929, + 0.1550965437132621 + ], + [ + 0.1542367767015747, + 0.154292328817848, + 0.1545125753310363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.41721164638313013, + "scoreError" : 0.03866243040348561, + "scoreConfidence" : [ + 0.3785492159796445, + 0.45587407678661573 + ], + "scorePercentiles" : { + "0.0" : 0.40423246942075264, + "50.0" : 0.4157824582157289, + "90.0" : 0.4316762584390918, + "95.0" : 0.4316762584390918, + "99.0" : 0.4316762584390918, + "99.9" : 0.4316762584390918, + "99.99" : 0.4316762584390918, + "99.999" : 0.4316762584390918, + "99.9999" : 0.4316762584390918, + "100.0" : 0.4316762584390918 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4057453275449345, + 0.40423246942075264, + 0.404365533015244 + ], + [ + 0.4316762584390918, + 0.4314307009922347, + 0.4258195888865233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15678497335885955, + "scoreError" : 0.0024965474209332275, + "scoreConfidence" : [ + 0.15428842593792633, + 0.15928152077979277 + ], + "scorePercentiles" : { + "0.0" : 0.15609496935924452, + "50.0" : 0.1565392116380705, + "90.0" : 0.1585025348063146, + "95.0" : 0.1585025348063146, + "99.0" : 0.1585025348063146, + "99.9" : 0.1585025348063146, + "99.99" : 0.1585025348063146, + "99.999" : 0.1585025348063146, + "99.9999" : 0.1585025348063146, + "100.0" : 0.1585025348063146 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1585025348063146, + 0.15680876772301758, + 0.15676527845620855 + ], + [ + 0.15631314481993247, + 0.15622514498843967, + 0.15609496935924452 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04681681512179368, + "scoreError" : 0.0025801131373482072, + "scoreConfidence" : [ + 0.04423670198444547, + 0.04939692825914188 + ], + "scorePercentiles" : { + "0.0" : 0.04591605002020276, + "50.0" : 0.046829234705807674, + "90.0" : 0.04768982080775999, + "95.0" : 0.04768982080775999, + "99.0" : 0.04768982080775999, + "99.9" : 0.04768982080775999, + "99.99" : 0.04768982080775999, + "99.999" : 0.04768982080775999, + "99.9999" : 0.04768982080775999, + "100.0" : 0.04768982080775999 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04604696674540574, + 0.04597117970771982, + 0.04591605002020276 + ], + [ + 0.047665370783464174, + 0.0476115026662096, + 0.04768982080775999 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9671527.092539549, + "scoreError" : 314390.489275314, + "scoreConfidence" : [ + 9357136.603264235, + 9985917.581814863 + ], + "scorePercentiles" : { + "0.0" : 9558568.090735435, + "50.0" : 9675081.829200074, + "90.0" : 9787145.432485323, + "95.0" : 9787145.432485323, + "99.0" : 9787145.432485323, + "99.9" : 9787145.432485323, + "99.99" : 9787145.432485323, + "99.999" : 9787145.432485323, + "99.9999" : 9787145.432485323, + "100.0" : 9787145.432485323 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9585310.691570882, + 9558568.090735435, + 9565325.200764818 + ], + [ + 9787145.432485323, + 9764852.966829268, + 9767960.172851562 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-12T05:47:12Z-061262145be24a76f10d625ca569d463703d053c-jdk17.json b/performance-results/2025-05-12T05:47:12Z-061262145be24a76f10d625ca569d463703d053c-jdk17.json new file mode 100644 index 0000000000..dcc120e001 --- /dev/null +++ b/performance-results/2025-05-12T05:47:12Z-061262145be24a76f10d625ca569d463703d053c-jdk17.json @@ -0,0 +1,4 @@ +[ +] + + diff --git a/performance-results/2025-05-12T06:46:25Z-061262145be24a76f10d625ca569d463703d053c-jdk17.json b/performance-results/2025-05-12T06:46:25Z-061262145be24a76f10d625ca569d463703d053c-jdk17.json new file mode 100644 index 0000000000..6092ed9526 --- /dev/null +++ b/performance-results/2025-05-12T06:46:25Z-061262145be24a76f10d625ca569d463703d053c-jdk17.json @@ -0,0 +1,1456 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.4039635682050546, + "scoreError" : 0.038135340492503556, + "scoreConfidence" : [ + 3.365828227712551, + 3.442098908697558 + ], + "scorePercentiles" : { + "0.0" : 3.3993150852608, + "50.0" : 3.4023028992672737, + "90.0" : 3.4119333890248726, + "95.0" : 3.4119333890248726, + "99.0" : 3.4119333890248726, + "99.9" : 3.4119333890248726, + "99.99" : 3.4119333890248726, + "99.999" : 3.4119333890248726, + "99.9999" : 3.4119333890248726, + "100.0" : 3.4119333890248726 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3996722590154436, + 3.4119333890248726 + ], + [ + 3.3993150852608, + 3.4049335395191034 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7159960167031723, + "scoreError" : 0.020244938478001826, + "scoreConfidence" : [ + 1.6957510782251703, + 1.7362409551811742 + ], + "scorePercentiles" : { + "0.0" : 1.7133302953905818, + "50.0" : 1.715062171918238, + "90.0" : 1.7205294275856318, + "95.0" : 1.7205294275856318, + "99.0" : 1.7205294275856318, + "99.9" : 1.7205294275856318, + "99.99" : 1.7205294275856318, + "99.999" : 1.7205294275856318, + "99.9999" : 1.7205294275856318, + "100.0" : 1.7205294275856318 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7152099411140975, + 1.7149144027223782 + ], + [ + 1.7133302953905818, + 1.7205294275856318 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8572918447992708, + "scoreError" : 0.06125468211661899, + "scoreConfidence" : [ + 0.7960371626826518, + 0.9185465269158898 + ], + "scorePercentiles" : { + "0.0" : 0.8485362926860941, + "50.0" : 0.8574366544396106, + "90.0" : 0.8657577776317679, + "95.0" : 0.8657577776317679, + "99.0" : 0.8657577776317679, + "99.9" : 0.8657577776317679, + "99.99" : 0.8657577776317679, + "99.999" : 0.8657577776317679, + "99.9999" : 0.8657577776317679, + "100.0" : 0.8657577776317679 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8496522551321891, + 0.8485362926860941 + ], + [ + 0.8657577776317679, + 0.8652210537470321 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 26.15093331933329, + "scoreError" : 2.2129287054070703, + "scoreConfidence" : [ + 23.93800461392622, + 28.36386202474036 + ], + "scorePercentiles" : { + "0.0" : 25.389464390620365, + "50.0" : 26.140757807476934, + "90.0" : 26.909329883243206, + "95.0" : 26.909329883243206, + "99.0" : 26.909329883243206, + "99.9" : 26.909329883243206, + "99.99" : 26.909329883243206, + "99.999" : 26.909329883243206, + "99.9999" : 26.909329883243206, + "100.0" : 26.909329883243206 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 26.909329883243206, + 26.878878098377818, + 26.823524468756656 + ], + [ + 25.457991146197212, + 25.389464390620365, + 25.446411928804476 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3742.4305410117445, + "scoreError" : 38.89806337448347, + "scoreConfidence" : [ + 3703.532477637261, + 3781.328604386228 + ], + "scorePercentiles" : { + "0.0" : 3728.5068387144943, + "50.0" : 3742.275292659087, + "90.0" : 3756.52360753583, + "95.0" : 3756.52360753583, + "99.0" : 3756.52360753583, + "99.9" : 3756.52360753583, + "99.99" : 3756.52360753583, + "99.999" : 3756.52360753583, + "99.9999" : 3756.52360753583, + "100.0" : 3756.52360753583 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 3728.5068387144943, + 3730.9339518464744, + 3730.005351211029 + ], + [ + 3756.52360753583, + 3753.6166334716995, + 3754.9968632909395 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 88235.55538968794, + "scoreError" : 1968.179801429618, + "scoreConfidence" : [ + 86267.37558825832, + 90203.73519111756 + ], + "scorePercentiles" : { + "0.0" : 87522.48914386719, + "50.0" : 88267.72687030758, + "90.0" : 88939.88806148905, + "95.0" : 88939.88806148905, + "99.0" : 88939.88806148905, + "99.9" : 88939.88806148905, + "99.99" : 88939.88806148905, + "99.999" : 88939.88806148905, + "99.9999" : 88939.88806148905, + "100.0" : 88939.88806148905 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 88858.17153380606, + 88819.47950118239, + 88939.88806148905 + ], + [ + 87715.97423943278, + 87557.32985835015, + 87522.48914386719 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 451.0310081249445, + "scoreError" : 2.029584828392785, + "scoreConfidence" : [ + 449.0014232965517, + 453.0605929533373 + ], + "scorePercentiles" : { + "0.0" : 450.13480490558544, + "50.0" : 450.9712058419325, + "90.0" : 452.11894578823916, + "95.0" : 452.11894578823916, + "99.0" : 452.11894578823916, + "99.9" : 452.11894578823916, + "99.99" : 452.11894578823916, + "99.999" : 452.11894578823916, + "99.9999" : 452.11894578823916, + "100.0" : 452.11894578823916 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 451.0714706316255, + 452.11894578823916, + 451.5438342686307 + ], + [ + 450.13480490558544, + 450.8709410522395, + 450.4460521033468 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 160.7960165072474, + "scoreError" : 12.41939459509834, + "scoreConfidence" : [ + 148.37662191214906, + 173.21541110234574 + ], + "scorePercentiles" : { + "0.0" : 154.3189147774426, + "50.0" : 161.6859086069535, + "90.0" : 165.5060574708323, + "95.0" : 165.5060574708323, + "99.0" : 165.5060574708323, + "99.9" : 165.5060574708323, + "99.99" : 165.5060574708323, + "99.999" : 165.5060574708323, + "99.9999" : 165.5060574708323, + "100.0" : 165.5060574708323 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 154.3189147774426, + 161.53864337477995, + 161.833173839127 + ], + [ + 156.7703203683641, + 165.5060574708323, + 164.80898921293863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.03737130375486193, + "scoreError" : 0.0037769606774510126, + "scoreConfidence" : [ + 0.03359434307741092, + 0.041148264432312946 + ], + "scorePercentiles" : { + "0.0" : 0.03607893355798163, + "50.0" : 0.037357473244903724, + "90.0" : 0.038637066222862726, + "95.0" : 0.038637066222862726, + "99.0" : 0.038637066222862726, + "99.9" : 0.038637066222862726, + "99.99" : 0.038637066222862726, + "99.999" : 0.038637066222862726, + "99.9999" : 0.038637066222862726, + "100.0" : 0.038637066222862726 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.038637066222862726, + 0.03853895032796109, + 0.03862414179444595 + ], + [ + 0.036175996161846365, + 0.03607893355798163, + 0.03617273446407385 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7668549526923907E-4, + "scoreError" : 1.4107565433314784E-6, + "scoreConfidence" : [ + 2.752747387259076E-4, + 2.7809625181257055E-4 + ], + "scorePercentiles" : { + "0.0" : 2.761075022443768E-4, + "50.0" : 2.767079788762257E-4, + "90.0" : 2.772291928512049E-4, + "95.0" : 2.772291928512049E-4, + "99.0" : 2.772291928512049E-4, + "99.9" : 2.772291928512049E-4, + "99.99" : 2.772291928512049E-4, + "99.999" : 2.772291928512049E-4, + "99.9999" : 2.772291928512049E-4, + "100.0" : 2.772291928512049E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7708372459992804E-4, + 2.772291928512049E-4, + 2.770999056903482E-4 + ], + [ + 2.762604130770531E-4, + 2.761075022443768E-4, + 2.763322331525234E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.08233263703044463, + "scoreError" : 0.005750170923647221, + "scoreConfidence" : [ + 0.0765824661067974, + 0.08808280795409186 + ], + "scorePercentiles" : { + "0.0" : 0.08041689977001142, + "50.0" : 0.08216582500384481, + "90.0" : 0.08513194734691445, + "95.0" : 0.08513194734691445, + "99.0" : 0.08513194734691445, + "99.9" : 0.08513194734691445, + "99.99" : 0.08513194734691445, + "99.999" : 0.08513194734691445, + "99.9999" : 0.08513194734691445, + "100.0" : 0.08513194734691445 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.08513194734691445, + 0.08362927676495677, + 0.08364316995098613 + ], + [ + 0.08047215510706612, + 0.08041689977001142, + 0.08070237324273287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.011324664949041392, + "scoreError" : 1.226797428763545E-4, + "scoreConfidence" : [ + 0.011201985206165038, + 0.011447344691917747 + ], + "scorePercentiles" : { + "0.0" : 0.011273352780633641, + "50.0" : 0.011326313158639217, + "90.0" : 0.011369750131034256, + "95.0" : 0.011369750131034256, + "99.0" : 0.011369750131034256, + "99.9" : 0.011369750131034256, + "99.99" : 0.011369750131034256, + "99.999" : 0.011369750131034256, + "99.9999" : 0.011369750131034256, + "100.0" : 0.011369750131034256 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011293261533353586, + 0.011289322499144848, + 0.011273352780633641 + ], + [ + 0.011359364783924849, + 0.011369750131034256, + 0.011362937966157161 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.910049293166913, + "scoreError" : 0.01654550738732981, + "scoreConfidence" : [ + 0.8935037857795831, + 0.9265948005542428 + ], + "scorePercentiles" : { + "0.0" : 0.9040742694811065, + "50.0" : 0.9103817569473458, + "90.0" : 0.9156442657938106, + "95.0" : 0.9156442657938106, + "99.0" : 0.9156442657938106, + "99.9" : 0.9156442657938106, + "99.99" : 0.9156442657938106, + "99.999" : 0.9156442657938106, + "99.9999" : 0.9156442657938106, + "100.0" : 0.9156442657938106 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9040742694811065, + 0.90546437971933, + 0.9045013259768452 + ], + [ + 0.9152991341753616, + 0.9156442657938106, + 0.9153123838550247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.009666037150918334, + "scoreError" : 2.351783750952818E-4, + "scoreConfidence" : [ + 0.009430858775823052, + 0.009901215526013616 + ], + "scorePercentiles" : { + "0.0" : 0.00955085898912568, + "50.0" : 0.009646370429975555, + "90.0" : 0.009769925221136054, + "95.0" : 0.009769925221136054, + "99.0" : 0.009769925221136054, + "99.9" : 0.009769925221136054, + "99.99" : 0.009769925221136054, + "99.999" : 0.009769925221136054, + "99.9999" : 0.009769925221136054, + "100.0" : 0.009769925221136054 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.009661462780295052, + 0.009756919619023087, + 0.009769925221136054 + ], + [ + 0.00955085898912568, + 0.009631278079656058, + 0.009625778216274073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.656105733436621, + "scoreError" : 0.10180240668832735, + "scoreConfidence" : [ + 2.5543033267482937, + 2.757908140124948 + ], + "scorePercentiles" : { + "0.0" : 2.605159203125, + "50.0" : 2.654755433648141, + "90.0" : 2.6971860490830637, + "95.0" : 2.6971860490830637, + "99.0" : 2.6971860490830637, + "99.9" : 2.6971860490830637, + "99.99" : 2.6971860490830637, + "99.999" : 2.6971860490830637, + "99.9999" : 2.6971860490830637, + "100.0" : 2.6971860490830637 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6741479331550804, + 2.6971860490830637, + 2.6895176462365593 + ], + [ + 2.605159203125, + 2.6353629341412015, + 2.63526063487882 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.171946794756839, + "scoreError" : 0.1366653557024983, + "scoreConfidence" : [ + 2.035281439054341, + 2.3086121504593375 + ], + "scorePercentiles" : { + "0.0" : 2.125853376833156, + "50.0" : 2.1721354459924114, + "90.0" : 2.2186541098047914, + "95.0" : 2.2186541098047914, + "99.0" : 2.2186541098047914, + "99.9" : 2.2186541098047914, + "99.99" : 2.2186541098047914, + "99.999" : 2.2186541098047914, + "99.9999" : 2.2186541098047914, + "100.0" : 2.2186541098047914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.1273093952350566, + 2.125853376833156, + 2.129284882903981 + ], + [ + 2.2186541098047914, + 2.2149860090808415, + 2.215592994683208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1114998334250367, + "scoreError" : 0.012074117704502238, + "scoreConfidence" : [ + 0.09942571572053446, + 0.12357395112953895 + ], + "scorePercentiles" : { + "0.0" : 0.10759132118649538, + "50.0" : 0.11064675664156765, + "90.0" : 0.11909836585046328, + "95.0" : 0.11909836585046328, + "99.0" : 0.11909836585046328, + "99.9" : 0.11909836585046328, + "99.99" : 0.11909836585046328, + "99.999" : 0.11909836585046328, + "99.9999" : 0.11909836585046328, + "100.0" : 0.11909836585046328 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10841273219648104, + 0.10759132118649538, + 0.10871280873384283 + ], + [ + 0.11909836585046328, + 0.11260306803364524, + 0.11258070454929245 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.2509630707756349, + "scoreError" : 0.01696682424425605, + "scoreConfidence" : [ + 0.23399624653137885, + 0.26792989501989095 + ], + "scorePercentiles" : { + "0.0" : 0.2465078494133307, + "50.0" : 0.2476348999050887, + "90.0" : 0.25922167463321066, + "95.0" : 0.25922167463321066, + "99.0" : 0.25922167463321066, + "99.9" : 0.25922167463321066, + "99.99" : 0.25922167463321066, + "99.999" : 0.25922167463321066, + "99.9999" : 0.25922167463321066, + "100.0" : 0.25922167463321066 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.25922167463321066, + 0.2465078494133307, + 0.2465310340942708 + ], + [ + 0.25824806670281997, + 0.24738625009895113, + 0.24788354971122623 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1187141272556791, + "scoreError" : 0.002635325185164799, + "scoreConfidence" : [ + 0.11607880207051431, + 0.1213494524408439 + ], + "scorePercentiles" : { + "0.0" : 0.11768829323432149, + "50.0" : 0.11872789060613767, + "90.0" : 0.119642910532046, + "95.0" : 0.119642910532046, + "99.0" : 0.119642910532046, + "99.9" : 0.119642910532046, + "99.99" : 0.119642910532046, + "99.999" : 0.119642910532046, + "99.9999" : 0.119642910532046, + "100.0" : 0.119642910532046 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.119642910532046, + 0.11949162717919917, + 0.1195648542665503 + ], + [ + 0.11768829323432149, + 0.11793292428888155, + 0.11796415403307618 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.22293134044623394, + "scoreError" : 0.02193957281967013, + "scoreConfidence" : [ + 0.20099176762656382, + 0.24487091326590407 + ], + "scorePercentiles" : { + "0.0" : 0.21530867803470696, + "50.0" : 0.22244727199610093, + "90.0" : 0.2322431269421027, + "95.0" : 0.2322431269421027, + "99.0" : 0.2322431269421027, + "99.9" : 0.2322431269421027, + "99.99" : 0.2322431269421027, + "99.999" : 0.2322431269421027, + "99.9999" : 0.2322431269421027, + "100.0" : 0.2322431269421027 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.2322431269421027, + 0.21606679275775645, + 0.21530867803470696 + ], + [ + 0.22907490095063568, + 0.2286082709857352, + 0.2162862730064667 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.08669651554760087, + "scoreError" : 0.01063026087453031, + "scoreConfidence" : [ + 0.07606625467307056, + 0.09732677642213118 + ], + "scorePercentiles" : { + "0.0" : 0.08253204213193362, + "50.0" : 0.08653567018067199, + "90.0" : 0.09189718713643757, + "95.0" : 0.09189718713643757, + "99.0" : 0.09189718713643757, + "99.9" : 0.09189718713643757, + "99.99" : 0.09189718713643757, + "99.999" : 0.09189718713643757, + "99.9999" : 0.09189718713643757, + "100.0" : 0.09189718713643757 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.09189718713643757, + 0.0865249259794421, + 0.08654641438190189 + ], + [ + 0.09002408143386986, + 0.08253204213193362, + 0.08265444222202019 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.02688092896808536, + "scoreError" : 0.004478743633936838, + "scoreConfidence" : [ + 0.022402185334148523, + 0.0313596726020222 + ], + "scorePercentiles" : { + "0.0" : 0.025218869114687622, + "50.0" : 0.02680919723415516, + "90.0" : 0.029402981602848516, + "95.0" : 0.029402981602848516, + "99.0" : 0.029402981602848516, + "99.9" : 0.029402981602848516, + "99.99" : 0.029402981602848516, + "99.999" : 0.029402981602848516, + "99.9999" : 0.029402981602848516, + "100.0" : 0.029402981602848516 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.029402981602848516, + 0.026873348184197655, + 0.02674504628411267 + ], + [ + 0.027818084913612047, + 0.025227243709053666, + 0.025218869114687622 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 6252346.324412476, + "scoreError" : 460883.43605244183, + "scoreConfidence" : [ + 5791462.888360035, + 6713229.760464918 + ], + "scorePercentiles" : { + "0.0" : 6035799.255280628, + "50.0" : 6291846.744589164, + "90.0" : 6486939.183527886, + "95.0" : 6486939.183527886, + "99.0" : 6486939.183527886, + "99.9" : 6486939.183527886, + "99.99" : 6486939.183527886, + "99.999" : 6486939.183527886, + "99.9999" : 6486939.183527886, + "100.0" : 6486939.183527886 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6486939.183527886, + 6301348.154379332, + 6315910.075126262 + ], + [ + 6282345.334798995, + 6035799.255280628, + 6091735.943361754 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ValidatorPerformance.largeSchema1", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.025287922605893198, + "scoreError" : 0.002936959394093174, + "scoreConfidence" : [ + 0.022350963211800023, + 0.028224881999986372 + ], + "scorePercentiles" : { + "0.0" : 0.02352473156571181, + "50.0" : 0.02537146819986554, + "90.0" : 0.028350539164183675, + "95.0" : 0.028350539164183675, + "99.0" : 0.028350539164183675, + "99.9" : 0.028350539164183675, + "99.99" : 0.028350539164183675, + "99.999" : 0.028350539164183675, + "99.9999" : 0.028350539164183675, + "100.0" : 0.028350539164183675 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.02537146819986554, + 0.023552887678292164, + 0.02352473156571181 + ], + [ + 0.0256087116184379, + 0.023839349074932716, + 0.023855965586093212 + ], + [ + 0.028350539164183675, + 0.027212772513408857, + 0.026274878052112864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ValidatorPerformance.largeSchema4", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 10.207298421372542, + "scoreError" : 0.6558113227681831, + "scoreConfidence" : [ + 9.551487098604358, + 10.863109744140726 + ], + "scorePercentiles" : { + "0.0" : 9.651269155255545, + "50.0" : 10.217042909090909, + "90.0" : 10.866004875135722, + "95.0" : 10.866004875135722, + "99.0" : 10.866004875135722, + "99.9" : 10.866004875135722, + "99.99" : 10.866004875135722, + "99.999" : 10.866004875135722, + "99.9999" : 10.866004875135722, + "100.0" : 10.866004875135722 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 10.866004875135722, + 10.28923801851852, + 10.034374594784353 + ], + [ + 10.420364461458334, + 10.217042909090909, + 9.651269155255545 + ], + [ + 10.617607174097664, + 9.977153226321036, + 9.792631377690803 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ValidatorPerformance.manyFragments", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/24.0.1-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "24.0.1", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "24.0.1+9-FR", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 7.117507957846131, + "scoreError" : 0.36834630575554955, + "scoreConfidence" : [ + 6.7491616520905815, + 7.485854263601681 + ], + "scorePercentiles" : { + "0.0" : 6.849033302532512, + "50.0" : 7.252914697606961, + "90.0" : 7.344143314977973, + "95.0" : 7.344143314977973, + "99.0" : 7.344143314977973, + "99.9" : 7.344143314977973, + "99.99" : 7.344143314977973, + "99.999" : 7.344143314977973, + "99.9999" : 7.344143314977973, + "100.0" : 7.344143314977973 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 6.882275011691885, + 6.849033302532512, + 6.853697062328767 + ], + [ + 7.310176976608187, + 7.344143314977973, + 7.252914697606961 + ], + [ + 7.324417578330893, + 7.257789008708273, + 6.983124667829728 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-13T01:49:54Z-65e27d9e0903be95d10252021ef5af45a731bd65-jdk17.json b/performance-results/2025-05-13T01:49:54Z-65e27d9e0903be95d10252021ef5af45a731bd65-jdk17.json new file mode 100644 index 0000000000..1be37280b3 --- /dev/null +++ b/performance-results/2025-05-13T01:49:54Z-65e27d9e0903be95d10252021ef5af45a731bd65-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3282025744568506, + "scoreError" : 0.031854593840040954, + "scoreConfidence" : [ + 3.29634798061681, + 3.3600571682968914 + ], + "scorePercentiles" : { + "0.0" : 3.321750624035161, + "50.0" : 3.3286505112358626, + "90.0" : 3.333758651320517, + "95.0" : 3.333758651320517, + "99.0" : 3.333758651320517, + "99.9" : 3.333758651320517, + "99.99" : 3.333758651320517, + "99.999" : 3.333758651320517, + "99.9999" : 3.333758651320517, + "100.0" : 3.333758651320517 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.328681793581338, + 3.333758651320517 + ], + [ + 3.321750624035161, + 3.3286192288903873 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6800356245695665, + "scoreError" : 0.05216034991909038, + "scoreConfidence" : [ + 1.627875274650476, + 1.7321959744886568 + ], + "scorePercentiles" : { + "0.0" : 1.6736069978985413, + "50.0" : 1.6775910923965405, + "90.0" : 1.691353315586643, + "95.0" : 1.691353315586643, + "99.0" : 1.691353315586643, + "99.9" : 1.691353315586643, + "99.99" : 1.691353315586643, + "99.999" : 1.691353315586643, + "99.9999" : 1.691353315586643, + "100.0" : 1.691353315586643 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6736069978985413, + 1.6749362382193909 + ], + [ + 1.68024594657369, + 1.691353315586643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8406275309627536, + "scoreError" : 0.0536071708701671, + "scoreConfidence" : [ + 0.7870203600925865, + 0.8942347018329206 + ], + "scorePercentiles" : { + "0.0" : 0.8336830700970194, + "50.0" : 0.8382191329590478, + "90.0" : 0.8523887878358988, + "95.0" : 0.8523887878358988, + "99.0" : 0.8523887878358988, + "99.9" : 0.8523887878358988, + "99.99" : 0.8523887878358988, + "99.999" : 0.8523887878358988, + "99.9999" : 0.8523887878358988, + "100.0" : 0.8523887878358988 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.836181255430769, + 0.8523887878358988 + ], + [ + 0.8336830700970194, + 0.8402570104873267 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.09158503338968, + "scoreError" : 0.2839609063482079, + "scoreConfidence" : [ + 15.807624127041473, + 16.37554593973789 + ], + "scorePercentiles" : { + "0.0" : 15.923528236919983, + "50.0" : 16.111815444849967, + "90.0" : 16.19581700725027, + "95.0" : 16.19581700725027, + "99.0" : 16.19581700725027, + "99.9" : 16.19581700725027, + "99.99" : 16.19581700725027, + "99.999" : 16.19581700725027, + "99.9999" : 16.19581700725027, + "100.0" : 16.19581700725027 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.19581700725027, + 16.1180123321631, + 16.17741385228604 + ], + [ + 15.923528236919983, + 16.105618557536832, + 16.029120214181855 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2630.5747064423244, + "scoreError" : 39.64914886995501, + "scoreConfidence" : [ + 2590.9255575723696, + 2670.2238553122793 + ], + "scorePercentiles" : { + "0.0" : 2612.2786518959947, + "50.0" : 2629.6190143669755, + "90.0" : 2655.754307951745, + "95.0" : 2655.754307951745, + "99.0" : 2655.754307951745, + "99.9" : 2655.754307951745, + "99.99" : 2655.754307951745, + "99.999" : 2655.754307951745, + "99.9999" : 2655.754307951745, + "100.0" : 2655.754307951745 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2612.2786518959947, + 2630.914361215289, + 2630.201744376071 + ], + [ + 2629.03628435788, + 2625.2628888569648, + 2655.754307951745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69246.29313138958, + "scoreError" : 744.791374217602, + "scoreConfidence" : [ + 68501.50175717198, + 69991.08450560718 + ], + "scorePercentiles" : { + "0.0" : 68914.4668618786, + "50.0" : 69237.97150935838, + "90.0" : 69553.9959302055, + "95.0" : 69553.9959302055, + "99.0" : 69553.9959302055, + "99.9" : 69553.9959302055, + "99.99" : 69553.9959302055, + "99.999" : 69553.9959302055, + "99.9999" : 69553.9959302055, + "100.0" : 69553.9959302055 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69553.9959302055, + 69501.45417556056, + 69373.46309750617 + ], + [ + 69102.47992121059, + 69031.89880197613, + 68914.4668618786 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.661921524353, + "scoreError" : 5.026434578574118, + "scoreConfidence" : [ + 342.63548694577884, + 352.6883561029271 + ], + "scorePercentiles" : { + "0.0" : 345.11262373021, + "50.0" : 347.6357131007909, + "90.0" : 350.4918877250619, + "95.0" : 350.4918877250619, + "99.0" : 350.4918877250619, + "99.9" : 350.4918877250619, + "99.99" : 350.4918877250619, + "99.999" : 350.4918877250619, + "99.9999" : 350.4918877250619, + "100.0" : 350.4918877250619 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 347.6857621985008, + 345.11262373021, + 350.4918877250619 + ], + [ + 346.67464854963816, + 347.58566400308104, + 348.42094293962606 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.00238432076134, + "scoreError" : 6.857987346581766, + "scoreConfidence" : [ + 100.14439697417957, + 113.8603716673431 + ], + "scorePercentiles" : { + "0.0" : 103.8336008315911, + "50.0" : 107.15926188925562, + "90.0" : 109.74866873677877, + "95.0" : 109.74866873677877, + "99.0" : 109.74866873677877, + "99.9" : 109.74866873677877, + "99.99" : 109.74866873677877, + "99.999" : 109.74866873677877, + "99.9999" : 109.74866873677877, + "100.0" : 109.74866873677877 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.50682816303517, + 107.52070849869929, + 103.8336008315911 + ], + [ + 104.60668441465171, + 106.79781527981194, + 109.74866873677877 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06260161725282631, + "scoreError" : 0.004232067371114513, + "scoreConfidence" : [ + 0.0583695498817118, + 0.06683368462394082 + ], + "scorePercentiles" : { + "0.0" : 0.06105434497411351, + "50.0" : 0.06228573273913556, + "90.0" : 0.06545024072752977, + "95.0" : 0.06545024072752977, + "99.0" : 0.06545024072752977, + "99.9" : 0.06545024072752977, + "99.99" : 0.06545024072752977, + "99.999" : 0.06545024072752977, + "99.9999" : 0.06545024072752977, + "100.0" : 0.06545024072752977 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061985069000570256, + 0.06189593403274224, + 0.06545024072752977 + ], + [ + 0.06263771830430126, + 0.06258639647770087, + 0.06105434497411351 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 4.031353724038786E-4, + "scoreError" : 1.8795673335172726E-5, + "scoreConfidence" : [ + 3.843396990687059E-4, + 4.2193104573905134E-4 + ], + "scorePercentiles" : { + "0.0" : 3.956440911185278E-4, + "50.0" : 4.028911593448254E-4, + "90.0" : 4.132115151622585E-4, + "95.0" : 4.132115151622585E-4, + "99.0" : 4.132115151622585E-4, + "99.9" : 4.132115151622585E-4, + "99.99" : 4.132115151622585E-4, + "99.999" : 4.132115151622585E-4, + "99.9999" : 4.132115151622585E-4, + "100.0" : 4.132115151622585E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.956440911185278E-4, + 4.0064080787555266E-4, + 3.968651224518151E-4 + ], + [ + 4.051415108140982E-4, + 4.0730918700101934E-4, + 4.132115151622585E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10813153993675766, + "scoreError" : 0.007086229449738516, + "scoreConfidence" : [ + 0.10104531048701915, + 0.11521776938649617 + ], + "scorePercentiles" : { + "0.0" : 0.10572389305197277, + "50.0" : 0.10756089269840047, + "90.0" : 0.11099187548279689, + "95.0" : 0.11099187548279689, + "99.0" : 0.11099187548279689, + "99.9" : 0.11099187548279689, + "99.99" : 0.11099187548279689, + "99.999" : 0.11099187548279689, + "99.9999" : 0.11099187548279689, + "100.0" : 0.11099187548279689 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.11099187548279689, + 0.11094913917056827, + 0.10911460662964136 + ], + [ + 0.10600254651840701, + 0.1060071787671596, + 0.10572389305197277 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014418096432272993, + "scoreError" : 1.9825021424852468E-4, + "scoreConfidence" : [ + 0.01421984621802447, + 0.014616346646521517 + ], + "scorePercentiles" : { + "0.0" : 0.014305885758958138, + "50.0" : 0.014436239034811681, + "90.0" : 0.014484291108787217, + "95.0" : 0.014484291108787217, + "99.0" : 0.014484291108787217, + "99.9" : 0.014484291108787217, + "99.99" : 0.014484291108787217, + "99.999" : 0.014484291108787217, + "99.9999" : 0.014484291108787217, + "100.0" : 0.014484291108787217 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014362497134009987, + 0.01443578637337383, + 0.014305885758958138 + ], + [ + 0.014483426522259268, + 0.014484291108787217, + 0.014436691696249533 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9951848157184422, + "scoreError" : 0.04346887407085314, + "scoreConfidence" : [ + 0.9517159416475891, + 1.0386536897892953 + ], + "scorePercentiles" : { + "0.0" : 0.9761590412844037, + "50.0" : 0.9951228396033112, + "90.0" : 1.015633401238956, + "95.0" : 1.015633401238956, + "99.0" : 1.015633401238956, + "99.9" : 1.015633401238956, + "99.99" : 1.015633401238956, + "99.999" : 1.015633401238956, + "99.9999" : 1.015633401238956, + "100.0" : 1.015633401238956 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9879497163884224, + 0.9819340638193421, + 0.9761590412844037 + ], + [ + 1.015633401238956, + 1.0071367087613292, + 1.0022959628182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01257257521257804, + "scoreError" : 3.1156489458417227E-4, + "scoreConfidence" : [ + 0.012261010317993867, + 0.012884140107162212 + ], + "scorePercentiles" : { + "0.0" : 0.012420598567198585, + "50.0" : 0.012544114865921139, + "90.0" : 0.01270699201006366, + "95.0" : 0.01270699201006366, + "99.0" : 0.01270699201006366, + "99.9" : 0.01270699201006366, + "99.99" : 0.01270699201006366, + "99.999" : 0.01270699201006366, + "99.9999" : 0.01270699201006366, + "100.0" : 0.01270699201006366 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012420598567198585, + 0.012522408135819042, + 0.012523075003443742 + ], + [ + 0.012565154728398536, + 0.01270699201006366, + 0.012697222830544672 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.648485539795114, + "scoreError" : 0.1542581201274607, + "scoreConfidence" : [ + 3.494227419667653, + 3.802743659922575 + ], + "scorePercentiles" : { + "0.0" : 3.582500664756447, + "50.0" : 3.6475571060547853, + "90.0" : 3.715977369242199, + "95.0" : 3.715977369242199, + "99.0" : 3.715977369242199, + "99.9" : 3.715977369242199, + "99.99" : 3.715977369242199, + "99.999" : 3.715977369242199, + "99.9999" : 3.715977369242199, + "100.0" : 3.715977369242199 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6130622290462426, + 3.582500664756447, + 3.60484421037464 + ], + [ + 3.692476782287823, + 3.6820519830633285, + 3.715977369242199 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.0327848738846743, + "scoreError" : 0.1117323811100563, + "scoreConfidence" : [ + 2.921052492774618, + 3.1445172549947307 + ], + "scorePercentiles" : { + "0.0" : 2.987133938172043, + "50.0" : 3.03278687631995, + "90.0" : 3.079861695103172, + "95.0" : 3.079861695103172, + "99.0" : 3.079861695103172, + "99.9" : 3.079861695103172, + "99.99" : 3.079861695103172, + "99.999" : 3.079861695103172, + "99.9999" : 3.079861695103172, + "100.0" : 3.079861695103172 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.987133938172043, + 2.997293118969134, + 3.0081094836090227 + ], + [ + 3.079861695103172, + 3.0574642690308775, + 3.0668467384237963 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17933685665995813, + "scoreError" : 0.007108318416156557, + "scoreConfidence" : [ + 0.17222853824380158, + 0.1864451750761147 + ], + "scorePercentiles" : { + "0.0" : 0.17684863441031354, + "50.0" : 0.17928138712537317, + "90.0" : 0.1817674912389123, + "95.0" : 0.1817674912389123, + "99.0" : 0.1817674912389123, + "99.9" : 0.1817674912389123, + "99.99" : 0.1817674912389123, + "99.999" : 0.1817674912389123, + "99.9999" : 0.1817674912389123, + "100.0" : 0.1817674912389123 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1817674912389123, + 0.18141919442327928, + 0.1817522603006125 + ], + [ + 0.1771435798274671, + 0.17684863441031354, + 0.17708997975916416 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32600073499402754, + "scoreError" : 0.005875124003174771, + "scoreConfidence" : [ + 0.3201256109908528, + 0.3318758589972023 + ], + "scorePercentiles" : { + "0.0" : 0.3237107717282232, + "50.0" : 0.32621108847384306, + "90.0" : 0.3294161914816523, + "95.0" : 0.3294161914816523, + "99.0" : 0.3294161914816523, + "99.9" : 0.3294161914816523, + "99.99" : 0.3294161914816523, + "99.999" : 0.3294161914816523, + "99.9999" : 0.3294161914816523, + "100.0" : 0.3294161914816523 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32611222690363606, + 0.32630995004405, + 0.32659421352057477 + ], + [ + 0.3294161914816523, + 0.3238610562860289, + 0.3237107717282232 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1520372851628994, + "scoreError" : 0.007080248447016387, + "scoreConfidence" : [ + 0.14495703671588303, + 0.1591175336099158 + ], + "scorePercentiles" : { + "0.0" : 0.1495491058038852, + "50.0" : 0.1518283720522713, + "90.0" : 0.15497031751123508, + "95.0" : 0.15497031751123508, + "99.0" : 0.15497031751123508, + "99.9" : 0.15497031751123508, + "99.99" : 0.15497031751123508, + "99.999" : 0.15497031751123508, + "99.9999" : 0.15497031751123508, + "100.0" : 0.15497031751123508 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14995569250839733, + 0.14978994221263592, + 0.1495491058038852 + ], + [ + 0.15497031751123508, + 0.1542576013450978, + 0.15370105159614528 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39466514004624437, + "scoreError" : 0.030698022853897552, + "scoreConfidence" : [ + 0.3639671171923468, + 0.4253631629001419 + ], + "scorePercentiles" : { + "0.0" : 0.3844967982236918, + "50.0" : 0.3945367520596545, + "90.0" : 0.4051826445849034, + "95.0" : 0.4051826445849034, + "99.0" : 0.4051826445849034, + "99.9" : 0.4051826445849034, + "99.99" : 0.4051826445849034, + "99.999" : 0.4051826445849034, + "99.9999" : 0.4051826445849034, + "100.0" : 0.4051826445849034 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4046990327789244, + 0.4051826445849034, + 0.4040745852357671 + ], + [ + 0.3849989188835419, + 0.3844967982236918, + 0.3845388605706375 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15997120898904224, + "scoreError" : 0.007840074650991959, + "scoreConfidence" : [ + 0.15213113433805028, + 0.1678112836400342 + ], + "scorePercentiles" : { + "0.0" : 0.1571211335197813, + "50.0" : 0.16008104438318044, + "90.0" : 0.16260650731707318, + "95.0" : 0.16260650731707318, + "99.0" : 0.16260650731707318, + "99.9" : 0.16260650731707318, + "99.99" : 0.16260650731707318, + "99.999" : 0.16260650731707318, + "99.9999" : 0.16260650731707318, + "100.0" : 0.16260650731707318 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16249837706569603, + 0.16260650731707318, + 0.16244684320987654 + ], + [ + 0.1577152455564843, + 0.1574391472653421, + 0.1571211335197813 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04792504765304747, + "scoreError" : 0.0012564530767281274, + "scoreConfidence" : [ + 0.04666859457631934, + 0.0491815007297756 + ], + "scorePercentiles" : { + "0.0" : 0.0474264511088136, + "50.0" : 0.047942219750661784, + "90.0" : 0.04859070644742788, + "95.0" : 0.04859070644742788, + "99.0" : 0.04859070644742788, + "99.9" : 0.04859070644742788, + "99.99" : 0.04859070644742788, + "99.999" : 0.04859070644742788, + "99.9999" : 0.04859070644742788, + "100.0" : 0.04859070644742788 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04859070644742788, + 0.048177748207816236, + 0.04779827040474916 + ], + [ + 0.048086169096574406, + 0.0474264511088136, + 0.047470940652903505 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9610011.602224838, + "scoreError" : 1091392.5902405938, + "scoreConfidence" : [ + 8518619.011984244, + 1.0701404192465432E7 + ], + "scorePercentiles" : { + "0.0" : 9210753.397790056, + "50.0" : 9616087.62004205, + "90.0" : 9974524.014955135, + "95.0" : 9974524.014955135, + "99.0" : 9974524.014955135, + "99.9" : 9974524.014955135, + "99.99" : 9974524.014955135, + "99.999" : 9974524.014955135, + "99.9999" : 9974524.014955135, + "100.0" : 9974524.014955135 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9286788.739090065, + 9269238.507877665, + 9210753.397790056 + ], + [ + 9945386.500994036, + 9974524.014955135, + 9973378.452642074 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-13T09:39:15Z-4ed03668955a2cb0c5ffb84db57fcf940962856a-jdk17.json b/performance-results/2025-05-13T09:39:15Z-4ed03668955a2cb0c5ffb84db57fcf940962856a-jdk17.json new file mode 100644 index 0000000000..122ff29925 --- /dev/null +++ b/performance-results/2025-05-13T09:39:15Z-4ed03668955a2cb0c5ffb84db57fcf940962856a-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.35015794405493, + "scoreError" : 0.03530946668719832, + "scoreConfidence" : [ + 3.3148484773677316, + 3.3854674107421285 + ], + "scorePercentiles" : { + "0.0" : 3.3422069054463197, + "50.0" : 3.352052645956847, + "90.0" : 3.3543195788597076, + "95.0" : 3.3543195788597076, + "99.0" : 3.3543195788597076, + "99.9" : 3.3543195788597076, + "99.99" : 3.3543195788597076, + "99.999" : 3.3543195788597076, + "99.9999" : 3.3543195788597076, + "100.0" : 3.3543195788597076 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3422069054463197, + 3.3530153890270427 + ], + [ + 3.3510899028866517, + 3.3543195788597076 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6928042330689244, + "scoreError" : 0.05324748538911852, + "scoreConfidence" : [ + 1.6395567476798059, + 1.7460517184580429 + ], + "scorePercentiles" : { + "0.0" : 1.6841437522163505, + "50.0" : 1.6932039580964555, + "90.0" : 1.7006652638664361, + "95.0" : 1.7006652638664361, + "99.0" : 1.7006652638664361, + "99.9" : 1.7006652638664361, + "99.99" : 1.7006652638664361, + "99.999" : 1.7006652638664361, + "99.9999" : 1.7006652638664361, + "100.0" : 1.7006652638664361 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6989736552816628, + 1.7006652638664361 + ], + [ + 1.6874342609112483, + 1.6841437522163505 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8498989289192711, + "scoreError" : 0.03875678065237622, + "scoreConfidence" : [ + 0.8111421482668949, + 0.8886557095716473 + ], + "scorePercentiles" : { + "0.0" : 0.8434756652333436, + "50.0" : 0.84965239749089, + "90.0" : 0.8568152554619604, + "95.0" : 0.8568152554619604, + "99.0" : 0.8568152554619604, + "99.9" : 0.8568152554619604, + "99.99" : 0.8568152554619604, + "99.999" : 0.8568152554619604, + "99.9999" : 0.8568152554619604, + "100.0" : 0.8568152554619604 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8465946089728422, + 0.8568152554619604 + ], + [ + 0.8434756652333436, + 0.852710186008938 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.316952147064402, + "scoreError" : 0.12085369211135315, + "scoreConfidence" : [ + 16.19609845495305, + 16.437805839175756 + ], + "scorePercentiles" : { + "0.0" : 16.250585906655974, + "50.0" : 16.340184112522156, + "90.0" : 16.35222809678643, + "95.0" : 16.35222809678643, + "99.0" : 16.35222809678643, + "99.9" : 16.35222809678643, + "99.99" : 16.35222809678643, + "99.999" : 16.35222809678643, + "99.9999" : 16.35222809678643, + "100.0" : 16.35222809678643 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.337129801843922, + 16.35222809678643, + 16.34323842320039 + ], + [ + 16.274466902438004, + 16.344063751461693, + 16.250585906655974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2664.7884773533683, + "scoreError" : 292.1095246956262, + "scoreConfidence" : [ + 2372.6789526577422, + 2956.8980020489944 + ], + "scorePercentiles" : { + "0.0" : 2568.135697546449, + "50.0" : 2663.499055641999, + "90.0" : 2763.8448898240117, + "95.0" : 2763.8448898240117, + "99.0" : 2763.8448898240117, + "99.9" : 2763.8448898240117, + "99.99" : 2763.8448898240117, + "99.999" : 2763.8448898240117, + "99.9999" : 2763.8448898240117, + "100.0" : 2763.8448898240117 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2759.7232633347335, + 2755.983453150897, + 2763.8448898240117 + ], + [ + 2568.135697546449, + 2571.0146581331014, + 2570.028902131016 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70056.07972928292, + "scoreError" : 1378.5606910273643, + "scoreConfidence" : [ + 68677.51903825556, + 71434.64042031029 + ], + "scorePercentiles" : { + "0.0" : 69582.93503304542, + "50.0" : 70067.7195274584, + "90.0" : 70541.75095292993, + "95.0" : 70541.75095292993, + "99.0" : 70541.75095292993, + "99.9" : 70541.75095292993, + "99.99" : 70541.75095292993, + "99.999" : 70541.75095292993, + "99.9999" : 70541.75095292993, + "100.0" : 70541.75095292993 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69658.05881291989, + 69584.25267302568, + 69582.93503304542 + ], + [ + 70492.10066177975, + 70477.38024199689, + 70541.75095292993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.05684408346633, + "scoreError" : 9.123965814279275, + "scoreConfidence" : [ + 332.93287826918703, + 351.18080989774563 + ], + "scorePercentiles" : { + "0.0" : 336.18412424262726, + "50.0" : 342.4001186593647, + "90.0" : 345.2946653010095, + "95.0" : 345.2946653010095, + "99.0" : 345.2946653010095, + "99.9" : 345.2946653010095, + "99.99" : 345.2946653010095, + "99.999" : 345.2946653010095, + "99.9999" : 345.2946653010095, + "100.0" : 345.2946653010095 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 336.18412424262726, + 341.4279997317022, + 342.986315669172 + ], + [ + 341.81392164955747, + 344.63403790672976, + 345.2946653010095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.27288507822318, + "scoreError" : 9.698515022628715, + "scoreConfidence" : [ + 96.57437005559447, + 115.9714001008519 + ], + "scorePercentiles" : { + "0.0" : 102.89363899176516, + "50.0" : 106.31228207654371, + "90.0" : 109.51472044912738, + "95.0" : 109.51472044912738, + "99.0" : 109.51472044912738, + "99.9" : 109.51472044912738, + "99.99" : 109.51472044912738, + "99.999" : 109.51472044912738, + "99.9999" : 109.51472044912738, + "100.0" : 109.51472044912738 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.32898046280206, + 109.51472044912738, + 109.43862861186797 + ], + [ + 102.89363899176516, + 103.29558369028534, + 103.16575826349134 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06110903789534477, + "scoreError" : 7.341767887821249E-4, + "scoreConfidence" : [ + 0.06037486110656264, + 0.061843214684126895 + ], + "scorePercentiles" : { + "0.0" : 0.0608419183453697, + "50.0" : 0.061082702318724216, + "90.0" : 0.06149920654834385, + "95.0" : 0.06149920654834385, + "99.0" : 0.06149920654834385, + "99.9" : 0.06149920654834385, + "99.99" : 0.06149920654834385, + "99.999" : 0.06149920654834385, + "99.9999" : 0.06149920654834385, + "100.0" : 0.06149920654834385 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061248335146259006, + 0.06124761931477149, + 0.06149920654834385 + ], + [ + 0.0608419183453697, + 0.06089936269464761, + 0.060917785322676936 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.661623733738552E-4, + "scoreError" : 4.237896604312413E-6, + "scoreConfidence" : [ + 3.619244767695428E-4, + 3.7040026997816765E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6463292773790407E-4, + "50.0" : 3.66023261383791E-4, + "90.0" : 3.678637413638742E-4, + "95.0" : 3.678637413638742E-4, + "99.0" : 3.678637413638742E-4, + "99.9" : 3.678637413638742E-4, + "99.99" : 3.678637413638742E-4, + "99.999" : 3.678637413638742E-4, + "99.9999" : 3.678637413638742E-4, + "100.0" : 3.678637413638742E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.678637413638742E-4, + 3.6766109253192833E-4, + 3.6701376880842016E-4 + ], + [ + 3.6476995584184304E-4, + 3.6503275395916187E-4, + 3.6463292773790407E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10673738027687153, + "scoreError" : 0.007810803814833202, + "scoreConfidence" : [ + 0.09892657646203833, + 0.11454818409170474 + ], + "scorePercentiles" : { + "0.0" : 0.1040970362875523, + "50.0" : 0.10676872198154505, + "90.0" : 0.10935326136164815, + "95.0" : 0.10935326136164815, + "99.0" : 0.10935326136164815, + "99.9" : 0.10935326136164815, + "99.99" : 0.10935326136164815, + "99.999" : 0.10935326136164815, + "99.9999" : 0.10935326136164815, + "100.0" : 0.10935326136164815 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1040970362875523, + 0.10435468781892747, + 0.10413753192818762 + ], + [ + 0.10918275614416263, + 0.10935326136164815, + 0.10929900812075109 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014369072224106211, + "scoreError" : 6.80479182315641E-4, + "scoreConfidence" : [ + 0.01368859304179057, + 0.015049551406421852 + ], + "scorePercentiles" : { + "0.0" : 0.014145644917531898, + "50.0" : 0.01436460841699332, + "90.0" : 0.014609431852247924, + "95.0" : 0.014609431852247924, + "99.0" : 0.014609431852247924, + "99.9" : 0.014609431852247924, + "99.99" : 0.014609431852247924, + "99.999" : 0.014609431852247924, + "99.9999" : 0.014609431852247924, + "100.0" : 0.014609431852247924 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014145644917531898, + 0.014150913223561509, + 0.014146738830589374 + ], + [ + 0.014583400910281426, + 0.014578303610425128, + 0.014609431852247924 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9952357863063392, + "scoreError" : 0.028920885844544445, + "scoreConfidence" : [ + 0.9663149004617948, + 1.0241566721508837 + ], + "scorePercentiles" : { + "0.0" : 0.9834699797423542, + "50.0" : 0.9964456178387, + "90.0" : 1.0058368255053807, + "95.0" : 1.0058368255053807, + "99.0" : 1.0058368255053807, + "99.9" : 1.0058368255053807, + "99.99" : 1.0058368255053807, + "99.999" : 1.0058368255053807, + "99.9999" : 1.0058368255053807, + "100.0" : 1.0058368255053807 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9834699797423542, + 0.9853245297536946, + 0.9892023884272997 + ], + [ + 1.003892147159205, + 1.0036888472501004, + 1.0058368255053807 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012161192630965713, + "scoreError" : 5.220354122380617E-4, + "scoreConfidence" : [ + 0.011639157218727651, + 0.012683228043203775 + ], + "scorePercentiles" : { + "0.0" : 0.011987228124557985, + "50.0" : 0.012161459320240296, + "90.0" : 0.012333712414560327, + "95.0" : 0.012333712414560327, + "99.0" : 0.012333712414560327, + "99.9" : 0.012333712414560327, + "99.99" : 0.012333712414560327, + "99.999" : 0.012333712414560327, + "99.9999" : 0.012333712414560327, + "100.0" : 0.012333712414560327 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012329116763735532, + 0.012330523592629492, + 0.012333712414560327 + ], + [ + 0.011993801876745057, + 0.011992773013565891, + 0.011987228124557985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6567998249117775, + "scoreError" : 0.17996355945114023, + "scoreConfidence" : [ + 3.476836265460637, + 3.836763384362918 + ], + "scorePercentiles" : { + "0.0" : 3.5936356170977013, + "50.0" : 3.6596107074999678, + "90.0" : 3.7220352782738093, + "95.0" : 3.7220352782738093, + "99.0" : 3.7220352782738093, + "99.9" : 3.7220352782738093, + "99.99" : 3.7220352782738093, + "99.999" : 3.7220352782738093, + "99.9999" : 3.7220352782738093, + "100.0" : 3.7220352782738093 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5936356170977013, + 3.607614173160173, + 3.594236988505747 + ], + [ + 3.7220352782738093, + 3.7116072418397628, + 3.7116696505934716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.902496222935477, + "scoreError" : 0.07026468170222931, + "scoreConfidence" : [ + 2.8322315412332477, + 2.972760904637706 + ], + "scorePercentiles" : { + "0.0" : 2.868738924290221, + "50.0" : 2.905690249620731, + "90.0" : 2.931327939038687, + "95.0" : 2.931327939038687, + "99.0" : 2.931327939038687, + "99.9" : 2.931327939038687, + "99.99" : 2.931327939038687, + "99.999" : 2.931327939038687, + "99.9999" : 2.931327939038687, + "100.0" : 2.931327939038687 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.868738924290221, + 2.8815234047824836, + 2.892892936650275 + ], + [ + 2.931327939038687, + 2.922006570260006, + 2.9184875625911877 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18627634487016906, + "scoreError" : 0.032121360426932435, + "scoreConfidence" : [ + 0.1541549844432366, + 0.2183977052971015 + ], + "scorePercentiles" : { + "0.0" : 0.1754389209487553, + "50.0" : 0.18620384980627064, + "90.0" : 0.19792789959426027, + "95.0" : 0.19792789959426027, + "99.0" : 0.19792789959426027, + "99.9" : 0.19792789959426027, + "99.99" : 0.19792789959426027, + "99.999" : 0.19792789959426027, + "99.9999" : 0.19792789959426027, + "100.0" : 0.19792789959426027 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19621275538594357, + 0.19792789959426027, + 0.1959924071417372 + ], + [ + 0.1764152924708041, + 0.17567079367951374, + 0.1754389209487553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33370649225857996, + "scoreError" : 0.005705711574214816, + "scoreConfidence" : [ + 0.32800078068436517, + 0.33941220383279475 + ], + "scorePercentiles" : { + "0.0" : 0.33154157560587477, + "50.0" : 0.33388681099812323, + "90.0" : 0.33565433118517773, + "95.0" : 0.33565433118517773, + "99.0" : 0.33565433118517773, + "99.9" : 0.33565433118517773, + "99.99" : 0.33565433118517773, + "99.999" : 0.33565433118517773, + "99.9999" : 0.33565433118517773, + "100.0" : 0.33565433118517773 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3322854115829346, + 0.33154157560587477, + 0.33176187715631633 + ], + [ + 0.33550754760786416, + 0.33565433118517773, + 0.33548821041331184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15377269170614982, + "scoreError" : 0.005827824113541727, + "scoreConfidence" : [ + 0.1479448675926081, + 0.15960051581969154 + ], + "scorePercentiles" : { + "0.0" : 0.15112629450967946, + "50.0" : 0.15475111138524472, + "90.0" : 0.15545969420305625, + "95.0" : 0.15545969420305625, + "99.0" : 0.15545969420305625, + "99.9" : 0.15545969420305625, + "99.99" : 0.15545969420305625, + "99.999" : 0.15545969420305625, + "99.9999" : 0.15545969420305625, + "100.0" : 0.15545969420305625 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1554195401591446, + 0.15545969420305625, + 0.15500348467046934 + ], + [ + 0.15449873810002007, + 0.15112629450967946, + 0.15112839859452926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4047567509579466, + "scoreError" : 0.006894979178594339, + "scoreConfidence" : [ + 0.3978617717793523, + 0.41165173013654094 + ], + "scorePercentiles" : { + "0.0" : 0.4019873848936769, + "50.0" : 0.40525090503915984, + "90.0" : 0.40696459186912465, + "95.0" : 0.40696459186912465, + "99.0" : 0.40696459186912465, + "99.9" : 0.40696459186912465, + "99.99" : 0.40696459186912465, + "99.999" : 0.40696459186912465, + "99.9999" : 0.40696459186912465, + "100.0" : 0.40696459186912465 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40695273390575404, + 0.40696459186912465, + 0.4069085104980469 + ], + [ + 0.40359329958027285, + 0.4021339850008043, + 0.4019873848936769 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1599981857148882, + "scoreError" : 0.005809565101016157, + "scoreConfidence" : [ + 0.15418862061387203, + 0.16580775081590435 + ], + "scorePercentiles" : { + "0.0" : 0.15824759275552672, + "50.0" : 0.1590014495805341, + "90.0" : 0.16286566089052473, + "95.0" : 0.16286566089052473, + "99.0" : 0.16286566089052473, + "99.9" : 0.16286566089052473, + "99.99" : 0.16286566089052473, + "99.999" : 0.16286566089052473, + "99.9999" : 0.16286566089052473, + "100.0" : 0.16286566089052473 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15849753098551367, + 0.15862497723775837, + 0.15824759275552672 + ], + [ + 0.16237543049669573, + 0.16286566089052473, + 0.15937792192330985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046641326357640005, + "scoreError" : 0.0013777360661474235, + "scoreConfidence" : [ + 0.04526359029149258, + 0.04801906242378743 + ], + "scorePercentiles" : { + "0.0" : 0.04619024598727939, + "50.0" : 0.04661636604080223, + "90.0" : 0.047116425253129667, + "95.0" : 0.047116425253129667, + "99.0" : 0.047116425253129667, + "99.9" : 0.047116425253129667, + "99.99" : 0.047116425253129667, + "99.999" : 0.047116425253129667, + "99.9999" : 0.047116425253129667, + "100.0" : 0.047116425253129667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04703559510460566, + 0.047116425253129667, + 0.04711507402155016 + ], + [ + 0.0461971369769988, + 0.04619348080227638, + 0.04619024598727939 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9285938.753668854, + "scoreError" : 927072.831052481, + "scoreConfidence" : [ + 8358865.922616373, + 1.0213011584721334E7 + ], + "scorePercentiles" : { + "0.0" : 8975628.922869954, + "50.0" : 9287102.91161534, + "90.0" : 9591657.205177372, + "95.0" : 9591657.205177372, + "99.0" : 9591657.205177372, + "99.9" : 9591657.205177372, + "99.99" : 9591657.205177372, + "99.999" : 9591657.205177372, + "99.9999" : 9591657.205177372, + "100.0" : 9591657.205177372 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8990784.471698113, + 8986137.081761006, + 8975628.922869954 + ], + [ + 9588003.488974113, + 9583421.351532567, + 9591657.205177372 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-14T08:04:30Z-d5b64982dfed0b307dbfd701658c33fce37fee82-jdk17.json b/performance-results/2025-05-14T08:04:30Z-d5b64982dfed0b307dbfd701658c33fce37fee82-jdk17.json new file mode 100644 index 0000000000..27899adb3e --- /dev/null +++ b/performance-results/2025-05-14T08:04:30Z-d5b64982dfed0b307dbfd701658c33fce37fee82-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3636634065622895, + "scoreError" : 0.03051571466729772, + "scoreConfidence" : [ + 3.333147691894992, + 3.394179121229587 + ], + "scorePercentiles" : { + "0.0" : 3.357191625062564, + "50.0" : 3.3646962066763226, + "90.0" : 3.3680695878339493, + "95.0" : 3.3680695878339493, + "99.0" : 3.3680695878339493, + "99.9" : 3.3680695878339493, + "99.99" : 3.3680695878339493, + "99.999" : 3.3680695878339493, + "99.9999" : 3.3680695878339493, + "100.0" : 3.3680695878339493 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.357191625062564, + 3.3680695878339493 + ], + [ + 3.3633790579440372, + 3.3660133554086085 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6968295351887925, + "scoreError" : 0.058349351692212, + "scoreConfidence" : [ + 1.6384801834965805, + 1.7551788868810045 + ], + "scorePercentiles" : { + "0.0" : 1.688756368852093, + "50.0" : 1.6956932678196965, + "90.0" : 1.7071752362636845, + "95.0" : 1.7071752362636845, + "99.0" : 1.7071752362636845, + "99.9" : 1.7071752362636845, + "99.99" : 1.7071752362636845, + "99.999" : 1.7071752362636845, + "99.9999" : 1.7071752362636845, + "100.0" : 1.7071752362636845 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.688756368852093, + 1.6897851917391544 + ], + [ + 1.7016013439002384, + 1.7071752362636845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8549709121839838, + "scoreError" : 0.03319407417665871, + "scoreConfidence" : [ + 0.821776838007325, + 0.8881649863606426 + ], + "scorePercentiles" : { + "0.0" : 0.8495706378505353, + "50.0" : 0.8542989047926541, + "90.0" : 0.8617152013000916, + "95.0" : 0.8617152013000916, + "99.0" : 0.8617152013000916, + "99.9" : 0.8617152013000916, + "99.99" : 0.8617152013000916, + "99.999" : 0.8617152013000916, + "99.9999" : 0.8617152013000916, + "100.0" : 0.8617152013000916 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8495706378505353, + 0.8529555574518084 + ], + [ + 0.8556422521335, + 0.8617152013000916 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.417657158471073, + "scoreError" : 0.19160576400793555, + "scoreConfidence" : [ + 16.226051394463138, + 16.609262922479008 + ], + "scorePercentiles" : { + "0.0" : 16.348027424434346, + "50.0" : 16.401712594465216, + "90.0" : 16.514716883254057, + "95.0" : 16.514716883254057, + "99.0" : 16.514716883254057, + "99.9" : 16.514716883254057, + "99.99" : 16.514716883254057, + "99.999" : 16.514716883254057, + "99.9999" : 16.514716883254057, + "100.0" : 16.514716883254057 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.514716883254057, + 16.477687859863334, + 16.43232844755624 + ], + [ + 16.37109674137419, + 16.36208559434426, + 16.348027424434346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2779.165153519887, + "scoreError" : 74.59368316361015, + "scoreConfidence" : [ + 2704.571470356277, + 2853.758836683497 + ], + "scorePercentiles" : { + "0.0" : 2753.3490495460223, + "50.0" : 2778.200589243578, + "90.0" : 2808.036467958535, + "95.0" : 2808.036467958535, + "99.0" : 2808.036467958535, + "99.9" : 2808.036467958535, + "99.99" : 2808.036467958535, + "99.999" : 2808.036467958535, + "99.9999" : 2808.036467958535, + "100.0" : 2808.036467958535 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2808.036467958535, + 2800.1273485123406, + 2801.774675547103 + ], + [ + 2755.4295495805072, + 2756.2738299748153, + 2753.3490495460223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70012.29910881979, + "scoreError" : 2041.819437040458, + "scoreConfidence" : [ + 67970.47967177934, + 72054.11854586024 + ], + "scorePercentiles" : { + "0.0" : 69316.29302834792, + "50.0" : 70007.42143137183, + "90.0" : 70717.96455690844, + "95.0" : 70717.96455690844, + "99.0" : 70717.96455690844, + "99.9" : 70717.96455690844, + "99.99" : 70717.96455690844, + "99.999" : 70717.96455690844, + "99.9999" : 70717.96455690844, + "100.0" : 70717.96455690844 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69354.52513427814, + 69316.29302834792, + 69373.7853829509 + ], + [ + 70717.96455690844, + 70641.05747979274, + 70670.16907064061 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 348.92205370736565, + "scoreError" : 21.151553361449253, + "scoreConfidence" : [ + 327.7705003459164, + 370.0736070688149 + ], + "scorePercentiles" : { + "0.0" : 341.56790378631456, + "50.0" : 348.72169408357576, + "90.0" : 356.3357552645768, + "95.0" : 356.3357552645768, + "99.0" : 356.3357552645768, + "99.9" : 356.3357552645768, + "99.99" : 356.3357552645768, + "99.999" : 356.3357552645768, + "99.9999" : 356.3357552645768, + "100.0" : 356.3357552645768 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 342.44203952742515, + 341.56790378631456, + 342.1493077744289 + ], + [ + 355.00134863972636, + 356.0359672517221, + 356.3357552645768 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.31014115365947, + "scoreError" : 1.7459374882623497, + "scoreConfidence" : [ + 104.56420366539712, + 108.05607864192183 + ], + "scorePercentiles" : { + "0.0" : 105.38848983799961, + "50.0" : 106.31111376014422, + "90.0" : 107.10457434407247, + "95.0" : 107.10457434407247, + "99.0" : 107.10457434407247, + "99.9" : 107.10457434407247, + "99.99" : 107.10457434407247, + "99.999" : 107.10457434407247, + "99.9999" : 107.10457434407247, + "100.0" : 107.10457434407247 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.10457434407247, + 106.76389709423225, + 106.57935243534237 + ], + [ + 105.38848983799961, + 106.04287508494609, + 105.98165812536405 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060496403917698525, + "scoreError" : 3.9800334750414966E-4, + "scoreConfidence" : [ + 0.060098400570194374, + 0.06089440726520268 + ], + "scorePercentiles" : { + "0.0" : 0.060232865249209455, + "50.0" : 0.06053635980177402, + "90.0" : 0.06061412381500788, + "95.0" : 0.06061412381500788, + "99.0" : 0.06061412381500788, + "99.9" : 0.06061412381500788, + "99.99" : 0.06061412381500788, + "99.999" : 0.06061412381500788, + "99.9999" : 0.06061412381500788, + "100.0" : 0.06061412381500788 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060232865249209455, + 0.060492002492226915, + 0.06046566809161598 + ], + [ + 0.06058071711132112, + 0.06059304674680983, + 0.06061412381500788 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.693627905513809E-4, + "scoreError" : 1.2320793273573173E-5, + "scoreConfidence" : [ + 3.5704199727780775E-4, + 3.8168358382495405E-4 + ], + "scorePercentiles" : { + "0.0" : 3.652675266957013E-4, + "50.0" : 3.693046335657938E-4, + "90.0" : 3.7345924532388743E-4, + "95.0" : 3.7345924532388743E-4, + "99.0" : 3.7345924532388743E-4, + "99.9" : 3.7345924532388743E-4, + "99.99" : 3.7345924532388743E-4, + "99.999" : 3.7345924532388743E-4, + "99.9999" : 3.7345924532388743E-4, + "100.0" : 3.7345924532388743E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6539509769051824E-4, + 3.6539613449590306E-4, + 3.652675266957013E-4 + ], + [ + 3.7345924532388743E-4, + 3.7344560646659095E-4, + 3.7321313263568456E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10562833164294146, + "scoreError" : 9.542899965539635E-4, + "scoreConfidence" : [ + 0.1046740416463875, + 0.10658262163949542 + ], + "scorePercentiles" : { + "0.0" : 0.10526105110311144, + "50.0" : 0.10566569058067381, + "90.0" : 0.10594309787905755, + "95.0" : 0.10594309787905755, + "99.0" : 0.10594309787905755, + "99.9" : 0.10594309787905755, + "99.99" : 0.10594309787905755, + "99.999" : 0.10594309787905755, + "99.9999" : 0.10594309787905755, + "100.0" : 0.10594309787905755 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10593147652592107, + 0.10593405480932204, + 0.10594309787905755 + ], + [ + 0.10526105110311144, + 0.10530040490481005, + 0.10539990463542655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01439907804599185, + "scoreError" : 1.9028050005544857E-4, + "scoreConfidence" : [ + 0.014208797545936402, + 0.014589358546047298 + ], + "scorePercentiles" : { + "0.0" : 0.01433228054960773, + "50.0" : 0.014398641464941943, + "90.0" : 0.01446563431953861, + "95.0" : 0.01446563431953861, + "99.0" : 0.01446563431953861, + "99.9" : 0.01446563431953861, + "99.99" : 0.01446563431953861, + "99.999" : 0.01446563431953861, + "99.9999" : 0.01446563431953861, + "100.0" : 0.01446563431953861 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014452787426815644, + 0.014463923155805873, + 0.01446563431953861 + ], + [ + 0.01433228054960773, + 0.014344495503068242, + 0.014335347321114989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9470120473870925, + "scoreError" : 0.03542580987255533, + "scoreConfidence" : [ + 0.9115862375145373, + 0.9824378572596478 + ], + "scorePercentiles" : { + "0.0" : 0.934464487105214, + "50.0" : 0.947583960981452, + "90.0" : 0.9587462641165756, + "95.0" : 0.9587462641165756, + "99.0" : 0.9587462641165756, + "99.9" : 0.9587462641165756, + "99.99" : 0.9587462641165756, + "99.999" : 0.9587462641165756, + "99.9999" : 0.9587462641165756, + "100.0" : 0.9587462641165756 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9368017221545667, + 0.934464487105214, + 0.9352357852800898 + ], + [ + 0.9583661998083374, + 0.9587462641165756, + 0.9584578258577726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012155003643159587, + "scoreError" : 0.001376092809324051, + "scoreConfidence" : [ + 0.010778910833835536, + 0.013531096452483639 + ], + "scorePercentiles" : { + "0.0" : 0.011703342542095974, + "50.0" : 0.012155718003315379, + "90.0" : 0.012604866132065483, + "95.0" : 0.012604866132065483, + "99.0" : 0.012604866132065483, + "99.9" : 0.012604866132065483, + "99.99" : 0.012604866132065483, + "99.999" : 0.012604866132065483, + "99.9999" : 0.012604866132065483, + "100.0" : 0.012604866132065483 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011703342542095974, + 0.011709943660553487, + 0.011707826886423557 + ], + [ + 0.012604866132065483, + 0.01260149234607727, + 0.012602550291741755 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6072230883897896, + "scoreError" : 0.16262231214322484, + "scoreConfidence" : [ + 3.4446007762465647, + 3.7698454005330144 + ], + "scorePercentiles" : { + "0.0" : 3.5459591141034728, + "50.0" : 3.60823668079488, + "90.0" : 3.6633346805860807, + "95.0" : 3.6633346805860807, + "99.0" : 3.6633346805860807, + "99.9" : 3.6633346805860807, + "99.99" : 3.6633346805860807, + "99.999" : 3.6633346805860807, + "99.9999" : 3.6633346805860807, + "100.0" : 3.6633346805860807 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5628589138176636, + 3.5459591141034728, + 3.5549862935323384 + ], + [ + 3.6625850805270863, + 3.6536144477720964, + 3.6633346805860807 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8456917395180548, + "scoreError" : 0.11571485485688263, + "scoreConfidence" : [ + 2.729976884661172, + 2.9614065943749375 + ], + "scorePercentiles" : { + "0.0" : 2.793757996648045, + "50.0" : 2.8492013764865556, + "90.0" : 2.8866878747474747, + "95.0" : 2.8866878747474747, + "99.0" : 2.8866878747474747, + "99.9" : 2.8866878747474747, + "99.99" : 2.8866878747474747, + "99.999" : 2.8866878747474747, + "99.9999" : 2.8866878747474747, + "100.0" : 2.8866878747474747 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8132698210970464, + 2.81970741330702, + 2.793757996648045 + ], + [ + 2.878695339666091, + 2.8866878747474747, + 2.882031991642651 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17671022748283427, + "scoreError" : 0.002389103485291517, + "scoreConfidence" : [ + 0.17432112399754277, + 0.17909933096812578 + ], + "scorePercentiles" : { + "0.0" : 0.1759714528849707, + "50.0" : 0.17652233606084483, + "90.0" : 0.17825434313113847, + "95.0" : 0.17825434313113847, + "99.0" : 0.17825434313113847, + "99.9" : 0.17825434313113847, + "99.99" : 0.17825434313113847, + "99.999" : 0.17825434313113847, + "99.9999" : 0.17825434313113847, + "100.0" : 0.17825434313113847 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1761800771480418, + 0.1759714528849707, + 0.1761067988729418 + ], + [ + 0.17825434313113847, + 0.1768645949736479, + 0.17688409788626513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32966227997923453, + "scoreError" : 0.026867495322076124, + "scoreConfidence" : [ + 0.3027947846571584, + 0.35652977530131064 + ], + "scorePercentiles" : { + "0.0" : 0.32071788467335877, + "50.0" : 0.32971675193628003, + "90.0" : 0.33853897251184834, + "95.0" : 0.33853897251184834, + "99.0" : 0.33853897251184834, + "99.9" : 0.33853897251184834, + "99.99" : 0.33853897251184834, + "99.999" : 0.33853897251184834, + "99.9999" : 0.33853897251184834, + "100.0" : 0.33853897251184834 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33828498420269265, + 0.3383984804412561, + 0.33853897251184834 + ], + [ + 0.32088483837638376, + 0.32071788467335877, + 0.32114851966986735 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1524122319786452, + "scoreError" : 0.0010809224553808916, + "scoreConfidence" : [ + 0.15133130952326432, + 0.15349315443402609 + ], + "scorePercentiles" : { + "0.0" : 0.15195021162992114, + "50.0" : 0.15242492467925883, + "90.0" : 0.15283956004218313, + "95.0" : 0.15283956004218313, + "99.0" : 0.15283956004218313, + "99.9" : 0.15283956004218313, + "99.99" : 0.15283956004218313, + "99.999" : 0.15283956004218313, + "99.9999" : 0.15283956004218313, + "100.0" : 0.15283956004218313 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15265047990413824, + 0.15276669788118116, + 0.15283956004218313 + ], + [ + 0.15206707296006813, + 0.15219936945437942, + 0.15195021162992114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38723737454399415, + "scoreError" : 0.005887266132572788, + "scoreConfidence" : [ + 0.38135010841142136, + 0.39312464067656694 + ], + "scorePercentiles" : { + "0.0" : 0.38522424734206473, + "50.0" : 0.3869990450188455, + "90.0" : 0.38992805244278084, + "95.0" : 0.38992805244278084, + "99.0" : 0.38992805244278084, + "99.9" : 0.38992805244278084, + "99.99" : 0.38992805244278084, + "99.999" : 0.38992805244278084, + "99.9999" : 0.38992805244278084, + "100.0" : 0.38992805244278084 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3885554079024049, + 0.3888351385745947, + 0.38992805244278084 + ], + [ + 0.3854387188668337, + 0.3854426821352862, + 0.38522424734206473 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15560316577422054, + "scoreError" : 0.008962275845234345, + "scoreConfidence" : [ + 0.1466408899289862, + 0.16456544161945488 + ], + "scorePercentiles" : { + "0.0" : 0.1526030984724787, + "50.0" : 0.1555997428560673, + "90.0" : 0.15861202323589588, + "95.0" : 0.15861202323589588, + "99.0" : 0.15861202323589588, + "99.9" : 0.15861202323589588, + "99.99" : 0.15861202323589588, + "99.999" : 0.15861202323589588, + "99.9999" : 0.15861202323589588, + "100.0" : 0.15861202323589588 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15856348714086382, + 0.15861202323589588, + 0.158381917579981 + ], + [ + 0.15264090008395023, + 0.1528175681321536, + 0.1526030984724787 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04773363353671171, + "scoreError" : 0.002148423668007366, + "scoreConfidence" : [ + 0.04558520986870434, + 0.049882057204719076 + ], + "scorePercentiles" : { + "0.0" : 0.04653973565561373, + "50.0" : 0.04791604720171553, + "90.0" : 0.04845653846414762, + "95.0" : 0.04845653846414762, + "99.0" : 0.04845653846414762, + "99.9" : 0.04845653846414762, + "99.99" : 0.04845653846414762, + "99.999" : 0.04845653846414762, + "99.9999" : 0.04845653846414762, + "100.0" : 0.04845653846414762 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04845653846414762, + 0.048226755730455206, + 0.048387411727988855 + ], + [ + 0.04760533867297585, + 0.047186020969089, + 0.04653973565561373 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9397490.448223135, + "scoreError" : 215604.2636401191, + "scoreConfidence" : [ + 9181886.184583016, + 9613094.711863253 + ], + "scorePercentiles" : { + "0.0" : 9330717.762126865, + "50.0" : 9371083.267984957, + "90.0" : 9539491.83508103, + "95.0" : 9539491.83508103, + "99.0" : 9539491.83508103, + "99.9" : 9539491.83508103, + "99.99" : 9539491.83508103, + "99.999" : 9539491.83508103, + "99.9999" : 9539491.83508103, + "100.0" : 9539491.83508103 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9539491.83508103, + 9423232.63653484, + 9387791.621951219 + ], + [ + 9354374.914018692, + 9330717.762126865, + 9349333.919626169 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-14T08:10:10Z-1a760d719050ed692ebce51f120f07e8f46e979c-jdk17.json b/performance-results/2025-05-14T08:10:10Z-1a760d719050ed692ebce51f120f07e8f46e979c-jdk17.json new file mode 100644 index 0000000000..a7af77fdd8 --- /dev/null +++ b/performance-results/2025-05-14T08:10:10Z-1a760d719050ed692ebce51f120f07e8f46e979c-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.370139590364174, + "scoreError" : 0.02470520788840132, + "scoreConfidence" : [ + 3.345434382475773, + 3.394844798252575 + ], + "scorePercentiles" : { + "0.0" : 3.3646370462238977, + "50.0" : 3.371254273409082, + "90.0" : 3.3734127684146356, + "95.0" : 3.3734127684146356, + "99.0" : 3.3734127684146356, + "99.9" : 3.3734127684146356, + "99.99" : 3.3734127684146356, + "99.999" : 3.3734127684146356, + "99.9999" : 3.3734127684146356, + "100.0" : 3.3734127684146356 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3734127684146356, + 3.37082247816052 + ], + [ + 3.3646370462238977, + 3.371686068657644 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6972229084750117, + "scoreError" : 0.020832781397906674, + "scoreConfidence" : [ + 1.6763901270771049, + 1.7180556898729185 + ], + "scorePercentiles" : { + "0.0" : 1.6927561867572536, + "50.0" : 1.6982332801592515, + "90.0" : 1.6996688868242902, + "95.0" : 1.6996688868242902, + "99.0" : 1.6996688868242902, + "99.9" : 1.6996688868242902, + "99.99" : 1.6996688868242902, + "99.999" : 1.6996688868242902, + "99.9999" : 1.6996688868242902, + "100.0" : 1.6996688868242902 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6927561867572536, + 1.6996688868242902 + ], + [ + 1.6969674995631543, + 1.6994990607553488 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8527190081591871, + "scoreError" : 0.0284156073218873, + "scoreConfidence" : [ + 0.8243034008372998, + 0.8811346154810744 + ], + "scorePercentiles" : { + "0.0" : 0.8499132777907785, + "50.0" : 0.8508906185172829, + "90.0" : 0.8591815178114042, + "95.0" : 0.8591815178114042, + "99.0" : 0.8591815178114042, + "99.9" : 0.8591815178114042, + "99.99" : 0.8591815178114042, + "99.999" : 0.8591815178114042, + "99.9999" : 0.8591815178114042, + "100.0" : 0.8591815178114042 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8499132777907785, + 0.8591815178114042 + ], + [ + 0.8499719775666398, + 0.8518092594679259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.332235623807907, + "scoreError" : 0.20715360810351968, + "scoreConfidence" : [ + 16.125082015704386, + 16.53938923191143 + ], + "scorePercentiles" : { + "0.0" : 16.254099964042563, + "50.0" : 16.330486925632947, + "90.0" : 16.411712773691235, + "95.0" : 16.411712773691235, + "99.0" : 16.411712773691235, + "99.9" : 16.411712773691235, + "99.99" : 16.411712773691235, + "99.999" : 16.411712773691235, + "99.9999" : 16.411712773691235, + "100.0" : 16.411712773691235 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.389117276254602, + 16.39648321174611, + 16.411712773691235 + ], + [ + 16.271856575011288, + 16.254099964042563, + 16.270143942101654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2652.918770833054, + "scoreError" : 124.9996809074908, + "scoreConfidence" : [ + 2527.919089925563, + 2777.918451740545 + ], + "scorePercentiles" : { + "0.0" : 2611.4249538534323, + "50.0" : 2653.231171170539, + "90.0" : 2693.8368739575126, + "95.0" : 2693.8368739575126, + "99.0" : 2693.8368739575126, + "99.9" : 2693.8368739575126, + "99.99" : 2693.8368739575126, + "99.999" : 2693.8368739575126, + "99.9999" : 2693.8368739575126, + "100.0" : 2693.8368739575126 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2611.4249538534323, + 2612.2190711266508, + 2613.0442450075416 + ], + [ + 2693.8368739575126, + 2693.4180973335365, + 2693.5693837196486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 69262.37585843161, + "scoreError" : 2282.328019304852, + "scoreConfidence" : [ + 66980.04783912675, + 71544.70387773647 + ], + "scorePercentiles" : { + "0.0" : 68487.79231759085, + "50.0" : 69261.04294853669, + "90.0" : 70038.85521638897, + "95.0" : 70038.85521638897, + "99.0" : 70038.85521638897, + "99.9" : 70038.85521638897, + "99.99" : 70038.85521638897, + "99.999" : 70038.85521638897, + "99.9999" : 70038.85521638897, + "100.0" : 70038.85521638897 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 69995.44090846958, + 70038.85521638897, + 69980.63433255524 + ], + [ + 68541.45156451812, + 68530.08081106693, + 68487.79231759085 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.4316734566819, + "scoreError" : 25.27468754118229, + "scoreConfidence" : [ + 322.1569859154996, + 372.7063609978642 + ], + "scorePercentiles" : { + "0.0" : 334.780629391915, + "50.0" : 348.64000484253074, + "90.0" : 356.17898665079616, + "95.0" : 356.17898665079616, + "99.0" : 356.17898665079616, + "99.9" : 356.17898665079616, + "99.99" : 356.17898665079616, + "99.999" : 356.17898665079616, + "99.9999" : 356.17898665079616, + "100.0" : 356.17898665079616 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 343.5768111764294, + 340.614568450461, + 334.780629391915 + ], + [ + 353.70319850863217, + 355.73584656185744, + 356.17898665079616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.8355306643244, + "scoreError" : 5.532398020945029, + "scoreConfidence" : [ + 101.30313264337937, + 112.36792868526942 + ], + "scorePercentiles" : { + "0.0" : 104.24474745881417, + "50.0" : 106.86517181357549, + "90.0" : 108.89930891115843, + "95.0" : 108.89930891115843, + "99.0" : 108.89930891115843, + "99.9" : 108.89930891115843, + "99.99" : 108.89930891115843, + "99.999" : 108.89930891115843, + "99.9999" : 108.89930891115843, + "100.0" : 108.89930891115843 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.24474745881417, + 105.34331009812756, + 105.76503460838364 + ], + [ + 107.96530901876733, + 108.89930891115843, + 108.7954738906952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060828851220586816, + "scoreError" : 7.320031249896371E-5, + "scoreConfidence" : [ + 0.06075565090808785, + 0.06090205153308578 + ], + "scorePercentiles" : { + "0.0" : 0.06079568737537085, + "50.0" : 0.06082735904667381, + "90.0" : 0.060858228232888466, + "95.0" : 0.060858228232888466, + "99.0" : 0.060858228232888466, + "99.9" : 0.060858228232888466, + "99.99" : 0.060858228232888466, + "99.999" : 0.060858228232888466, + "99.9999" : 0.060858228232888466, + "100.0" : 0.060858228232888466 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060858228232888466, + 0.060857648997997824, + 0.060835273967185986 + ], + [ + 0.060806824623916136, + 0.06081944412616163, + 0.06079568737537085 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.771253861784456E-4, + "scoreError" : 3.20566102239807E-5, + "scoreConfidence" : [ + 3.450687759544649E-4, + 4.091819964024263E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6644673865198906E-4, + "50.0" : 3.773105682693279E-4, + "90.0" : 3.8765561398091867E-4, + "95.0" : 3.8765561398091867E-4, + "99.0" : 3.8765561398091867E-4, + "99.9" : 3.8765561398091867E-4, + "99.99" : 3.8765561398091867E-4, + "99.999" : 3.8765561398091867E-4, + "99.9999" : 3.8765561398091867E-4, + "100.0" : 3.8765561398091867E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8757203759514155E-4, + 3.8744662048861226E-4, + 3.8765561398091867E-4 + ], + [ + 3.664567903039684E-4, + 3.671745160500435E-4, + 3.6644673865198906E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10220033324019878, + "scoreError" : 7.348407769324592E-4, + "scoreConfidence" : [ + 0.10146549246326632, + 0.10293517401713125 + ], + "scorePercentiles" : { + "0.0" : 0.10193692394650467, + "50.0" : 0.10213691112455872, + "90.0" : 0.10256970829572495, + "95.0" : 0.10256970829572495, + "99.0" : 0.10256970829572495, + "99.9" : 0.10256970829572495, + "99.99" : 0.10256970829572495, + "99.999" : 0.10256970829572495, + "99.9999" : 0.10256970829572495, + "100.0" : 0.10256970829572495 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10193692394650467, + 0.10203699231679693, + 0.1019769971446927 + ], + [ + 0.10256970829572495, + 0.1024445478051529, + 0.10223682993232053 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014415331154454133, + "scoreError" : 4.328686442361903E-4, + "scoreConfidence" : [ + 0.013982462510217944, + 0.014848199798690323 + ], + "scorePercentiles" : { + "0.0" : 0.014270254059831499, + "50.0" : 0.014415585143728343, + "90.0" : 0.014565975831013734, + "95.0" : 0.014565975831013734, + "99.0" : 0.014565975831013734, + "99.9" : 0.014565975831013734, + "99.99" : 0.014565975831013734, + "99.999" : 0.014565975831013734, + "99.9999" : 0.014565975831013734, + "100.0" : 0.014565975831013734 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01427273858913463, + 0.014280618256959211, + 0.014270254059831499 + ], + [ + 0.01455184815928825, + 0.014565975831013734, + 0.014550552030497476 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0033324945142952, + "scoreError" : 0.05397205682089358, + "scoreConfidence" : [ + 0.9493604376934016, + 1.0573045513351889 + ], + "scorePercentiles" : { + "0.0" : 0.9846515982081323, + "50.0" : 1.0035884769390897, + "90.0" : 1.0218775064377683, + "95.0" : 1.0218775064377683, + "99.0" : 1.0218775064377683, + "99.9" : 1.0218775064377683, + "99.99" : 1.0218775064377683, + "99.999" : 1.0218775064377683, + "99.9999" : 1.0218775064377683, + "100.0" : 1.0218775064377683 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.020321899704112, + 1.0204522047959184, + 1.0218775064377683 + ], + [ + 0.9868550541740675, + 0.9858367037657729, + 0.9846515982081323 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012460747499087385, + "scoreError" : 2.344741054678024E-4, + "scoreConfidence" : [ + 0.012226273393619582, + 0.012695221604555188 + ], + "scorePercentiles" : { + "0.0" : 0.012383000222888135, + "50.0" : 0.012429302249815324, + "90.0" : 0.01256563645045122, + "95.0" : 0.01256563645045122, + "99.0" : 0.01256563645045122, + "99.9" : 0.01256563645045122, + "99.99" : 0.01256563645045122, + "99.999" : 0.01256563645045122, + "99.9999" : 0.01256563645045122, + "100.0" : 0.01256563645045122 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012383000222888135, + 0.01239570650212209, + 0.012401507561007672 + ], + [ + 0.012457096938622979, + 0.01256563645045122, + 0.012561537319432232 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.6112984608750374, + "scoreError" : 0.12747358287926502, + "scoreConfidence" : [ + 3.4838248779957723, + 3.7387720437543024 + ], + "scorePercentiles" : { + "0.0" : 3.5527282151988637, + "50.0" : 3.6127836804227824, + "90.0" : 3.6556680263157895, + "95.0" : 3.6556680263157895, + "99.0" : 3.6556680263157895, + "99.9" : 3.6556680263157895, + "99.99" : 3.6556680263157895, + "99.999" : 3.6556680263157895, + "99.9999" : 3.6556680263157895, + "100.0" : 3.6556680263157895 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6556680263157895, + 3.645465748542274, + 3.6538557699050402 + ], + [ + 3.5527282151988637, + 3.5801016123032903, + 3.5799713929849677 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8611117035417184, + "scoreError" : 0.04350602193530415, + "scoreConfidence" : [ + 2.8176056816064143, + 2.9046177254770225 + ], + "scorePercentiles" : { + "0.0" : 2.8315016531710078, + "50.0" : 2.8650410848719114, + "90.0" : 2.874777800229951, + "95.0" : 2.874777800229951, + "99.0" : 2.874777800229951, + "99.9" : 2.874777800229951, + "99.99" : 2.874777800229951, + "99.999" : 2.874777800229951, + "99.9999" : 2.874777800229951, + "100.0" : 2.874777800229951 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8601125501858737, + 2.8701960479196558, + 2.868619031832521 + ], + [ + 2.8315016531710078, + 2.861463137911302, + 2.874777800229951 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18681796853368926, + "scoreError" : 0.02115320809019466, + "scoreConfidence" : [ + 0.1656647604434946, + 0.20797117662388392 + ], + "scorePercentiles" : { + "0.0" : 0.1779729366791244, + "50.0" : 0.18831507960067728, + "90.0" : 0.1942224326943619, + "95.0" : 0.1942224326943619, + "99.0" : 0.1942224326943619, + "99.9" : 0.1942224326943619, + "99.99" : 0.1942224326943619, + "99.999" : 0.1942224326943619, + "99.9999" : 0.1942224326943619, + "100.0" : 0.1942224326943619 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1837946036757949, + 0.17879898762739138, + 0.1779729366791244 + ], + [ + 0.19328329499990335, + 0.1928355555255597, + 0.1942224326943619 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3397743504691115, + "scoreError" : 0.019005977960164063, + "scoreConfidence" : [ + 0.3207683725089474, + 0.35878032842927554 + ], + "scorePercentiles" : { + "0.0" : 0.33394418957456756, + "50.0" : 0.33786573322545543, + "90.0" : 0.3492599469493242, + "95.0" : 0.3492599469493242, + "99.0" : 0.3492599469493242, + "99.9" : 0.3492599469493242, + "99.99" : 0.3492599469493242, + "99.999" : 0.3492599469493242, + "99.9999" : 0.3492599469493242, + "100.0" : 0.3492599469493242 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33405711611437733, + 0.33394418957456756, + 0.33396415846246325 + ], + [ + 0.3492599469493242, + 0.34574634137740284, + 0.34167435033653354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14969528232292936, + "scoreError" : 0.00440972774395302, + "scoreConfidence" : [ + 0.14528555457897635, + 0.15410501006688238 + ], + "scorePercentiles" : { + "0.0" : 0.1482274776699029, + "50.0" : 0.14961047337011923, + "90.0" : 0.1512611949872943, + "95.0" : 0.1512611949872943, + "99.0" : 0.1512611949872943, + "99.9" : 0.1512611949872943, + "99.99" : 0.1512611949872943, + "99.999" : 0.1512611949872943, + "99.9999" : 0.1512611949872943, + "100.0" : 0.1512611949872943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14827325643116612, + 0.1482274776699029, + 0.14828932528137373 + ], + [ + 0.1509316214588647, + 0.1512611949872943, + 0.15118881810897436 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3981214765634346, + "scoreError" : 0.02086147318599553, + "scoreConfidence" : [ + 0.3772600033774391, + 0.4189829497494301 + ], + "scorePercentiles" : { + "0.0" : 0.389766691234361, + "50.0" : 0.39873682948768496, + "90.0" : 0.40715051367966776, + "95.0" : 0.40715051367966776, + "99.0" : 0.40715051367966776, + "99.9" : 0.40715051367966776, + "99.99" : 0.40715051367966776, + "99.999" : 0.40715051367966776, + "99.9999" : 0.40715051367966776, + "100.0" : 0.40715051367966776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39413904898908286, + 0.3908228704861654, + 0.389766691234361 + ], + [ + 0.40715051367966776, + 0.4035151250050438, + 0.403334609986287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15416333844967361, + "scoreError" : 0.0037646306821965255, + "scoreConfidence" : [ + 0.1503987077674771, + 0.15792796913187013 + ], + "scorePercentiles" : { + "0.0" : 0.15284310736993337, + "50.0" : 0.15399168125384866, + "90.0" : 0.1562776362712924, + "95.0" : 0.1562776362712924, + "99.0" : 0.1562776362712924, + "99.9" : 0.1562776362712924, + "99.99" : 0.1562776362712924, + "99.999" : 0.1562776362712924, + "99.9999" : 0.1562776362712924, + "100.0" : 0.1562776362712924 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1562776362712924, + 0.15485281633348302, + 0.1546858990223982 + ], + [ + 0.15329746348529907, + 0.15284310736993337, + 0.15302310821563556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047172424366579944, + "scoreError" : 4.344566689682615E-4, + "scoreConfidence" : [ + 0.04673796769761168, + 0.04760688103554821 + ], + "scorePercentiles" : { + "0.0" : 0.04699316665883459, + "50.0" : 0.047182017704422256, + "90.0" : 0.04742785077946777, + "95.0" : 0.04742785077946777, + "99.0" : 0.04742785077946777, + "99.9" : 0.04742785077946777, + "99.99" : 0.04742785077946777, + "99.999" : 0.04742785077946777, + "99.9999" : 0.04742785077946777, + "100.0" : 0.04742785077946777 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04719294494100991, + 0.0471710904678346, + 0.04721875084992256 + ], + [ + 0.04742785077946777, + 0.04699316665883459, + 0.04703074250241023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9460456.227808142, + "scoreError" : 548391.4390651599, + "scoreConfidence" : [ + 8912064.788742982, + 1.0008847666873302E7 + ], + "scorePercentiles" : { + "0.0" : 9266164.849074075, + "50.0" : 9459758.150763154, + "90.0" : 9649990.819672132, + "95.0" : 9649990.819672132, + "99.0" : 9649990.819672132, + "99.9" : 9649990.819672132, + "99.99" : 9649990.819672132, + "99.999" : 9649990.819672132, + "99.9999" : 9649990.819672132, + "100.0" : 9649990.819672132 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9641715.66955684, + 9649990.819672132, + 9624122.20673077 + ], + [ + 9266164.849074075, + 9295394.094795538, + 9285349.727019498 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-14T08:13:36Z-1a760d719050ed692ebce51f120f07e8f46e979c-jdk17.json b/performance-results/2025-05-14T08:13:36Z-1a760d719050ed692ebce51f120f07e8f46e979c-jdk17.json new file mode 100644 index 0000000000..1b9e2d9405 --- /dev/null +++ b/performance-results/2025-05-14T08:13:36Z-1a760d719050ed692ebce51f120f07e8f46e979c-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3785679841698584, + "scoreError" : 0.04214487808540427, + "scoreConfidence" : [ + 3.336423106084454, + 3.4207128622552627 + ], + "scorePercentiles" : { + "0.0" : 3.370647753211857, + "50.0" : 3.3785073236231695, + "90.0" : 3.386609536221237, + "95.0" : 3.386609536221237, + "99.0" : 3.386609536221237, + "99.9" : 3.386609536221237, + "99.99" : 3.386609536221237, + "99.999" : 3.386609536221237, + "99.9999" : 3.386609536221237, + "100.0" : 3.386609536221237 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.378187819919075, + 3.386609536221237 + ], + [ + 3.370647753211857, + 3.378826827327264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7048257385279155, + "scoreError" : 0.006376021150997846, + "scoreConfidence" : [ + 1.6984497173769177, + 1.7112017596789133 + ], + "scorePercentiles" : { + "0.0" : 1.7037733059352842, + "50.0" : 1.7048595742862216, + "90.0" : 1.7058104996039343, + "95.0" : 1.7058104996039343, + "99.0" : 1.7058104996039343, + "99.9" : 1.7058104996039343, + "99.99" : 1.7058104996039343, + "99.999" : 1.7058104996039343, + "99.9999" : 1.7058104996039343, + "100.0" : 1.7058104996039343 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7037733059352842, + 1.7058104996039343 + ], + [ + 1.7042110951067069, + 1.7055080534657365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.859962288809697, + "scoreError" : 0.007710138801591379, + "scoreConfidence" : [ + 0.8522521500081057, + 0.8676724276112884 + ], + "scorePercentiles" : { + "0.0" : 0.8587517652150629, + "50.0" : 0.8598760657889408, + "90.0" : 0.8613452584458438, + "95.0" : 0.8613452584458438, + "99.0" : 0.8613452584458438, + "99.9" : 0.8613452584458438, + "99.99" : 0.8613452584458438, + "99.999" : 0.8613452584458438, + "99.9999" : 0.8613452584458438, + "100.0" : 0.8613452584458438 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8587517652150629, + 0.860538635619139 + ], + [ + 0.8592134959587427, + 0.8613452584458438 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.242222630252485, + "scoreError" : 0.40169282101150305, + "scoreConfidence" : [ + 15.840529809240982, + 16.64391545126399 + ], + "scorePercentiles" : { + "0.0" : 16.09772925138583, + "50.0" : 16.237817706656884, + "90.0" : 16.406707770808403, + "95.0" : 16.406707770808403, + "99.0" : 16.406707770808403, + "99.9" : 16.406707770808403, + "99.99" : 16.406707770808403, + "99.999" : 16.406707770808403, + "99.9999" : 16.406707770808403, + "100.0" : 16.406707770808403 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.406707770808403, + 16.363133279291233, + 16.34402255226887 + ], + [ + 16.131612861044893, + 16.09772925138583, + 16.110130066715666 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2603.5201174038452, + "scoreError" : 29.583333561553165, + "scoreConfidence" : [ + 2573.9367838422922, + 2633.103450965398 + ], + "scorePercentiles" : { + "0.0" : 2592.9156315080922, + "50.0" : 2603.610942717016, + "90.0" : 2614.175689792112, + "95.0" : 2614.175689792112, + "99.0" : 2614.175689792112, + "99.9" : 2614.175689792112, + "99.99" : 2614.175689792112, + "99.999" : 2614.175689792112, + "99.9999" : 2614.175689792112, + "100.0" : 2614.175689792112 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2612.3102358081533, + 2612.866457395936, + 2614.175689792112 + ], + [ + 2593.9410402928993, + 2594.911649625879, + 2592.9156315080922 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 70916.54313720208, + "scoreError" : 870.4990256159559, + "scoreConfidence" : [ + 70046.04411158613, + 71787.04216281803 + ], + "scorePercentiles" : { + "0.0" : 70604.8350767051, + "50.0" : 70917.17821880765, + "90.0" : 71221.49522349113, + "95.0" : 71221.49522349113, + "99.0" : 71221.49522349113, + "99.9" : 71221.49522349113, + "99.99" : 71221.49522349113, + "99.999" : 71221.49522349113, + "99.9999" : 71221.49522349113, + "100.0" : 71221.49522349113 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71221.49522349113, + 71167.65986097971, + 71207.53343280114 + ], + [ + 70604.8350767051, + 70666.6965766356, + 70631.0386525998 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 343.7176900430316, + "scoreError" : 3.572314029136568, + "scoreConfidence" : [ + 340.14537601389503, + 347.2900040721682 + ], + "scorePercentiles" : { + "0.0" : 341.8135134219375, + "50.0" : 343.88520629690936, + "90.0" : 345.10071956145265, + "95.0" : 345.10071956145265, + "99.0" : 345.10071956145265, + "99.9" : 345.10071956145265, + "99.99" : 345.10071956145265, + "99.999" : 345.10071956145265, + "99.9999" : 345.10071956145265, + "100.0" : 345.10071956145265 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 343.59626241288146, + 341.8135134219375, + 342.7301683169292 + ], + [ + 344.8913263640519, + 344.1741501809372, + 345.10071956145265 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.74790023600792, + "scoreError" : 0.9438948009680315, + "scoreConfidence" : [ + 105.8040054350399, + 107.69179503697595 + ], + "scorePercentiles" : { + "0.0" : 106.11924027619916, + "50.0" : 106.82078485079462, + "90.0" : 107.06307691042083, + "95.0" : 107.06307691042083, + "99.0" : 107.06307691042083, + "99.9" : 107.06307691042083, + "99.99" : 107.06307691042083, + "99.999" : 107.06307691042083, + "99.9999" : 107.06307691042083, + "100.0" : 107.06307691042083 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 106.11924027619916, + 107.06307691042083, + 106.97551988249337 + ], + [ + 106.76632816354338, + 106.87524153804587, + 106.68799464534494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06051150051051311, + "scoreError" : 0.001122511559034843, + "scoreConfidence" : [ + 0.05938898895147826, + 0.06163401206954795 + ], + "scorePercentiles" : { + "0.0" : 0.060066236892212514, + "50.0" : 0.06053216847167737, + "90.0" : 0.06088006549372945, + "95.0" : 0.06088006549372945, + "99.0" : 0.06088006549372945, + "99.9" : 0.06088006549372945, + "99.99" : 0.06088006549372945, + "99.999" : 0.06088006549372945, + "99.9999" : 0.06088006549372945, + "100.0" : 0.06088006549372945 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06018400067405317, + 0.06019503745282281, + 0.060066236892212514 + ], + [ + 0.06088006549372945, + 0.06087436305972875, + 0.06086929949053193 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6315896688861424E-4, + "scoreError" : 3.830660297141263E-5, + "scoreConfidence" : [ + 3.248523639172016E-4, + 4.014655698600269E-4 + ], + "scorePercentiles" : { + "0.0" : 3.501250659583308E-4, + "50.0" : 3.635080022294647E-4, + "90.0" : 3.7563639866240213E-4, + "95.0" : 3.7563639866240213E-4, + "99.0" : 3.7563639866240213E-4, + "99.9" : 3.7563639866240213E-4, + "99.99" : 3.7563639866240213E-4, + "99.999" : 3.7563639866240213E-4, + "99.9999" : 3.7563639866240213E-4, + "100.0" : 3.7563639866240213E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7563639866240213E-4, + 3.756110131631251E-4, + 3.756232867057088E-4 + ], + [ + 3.5055304554631425E-4, + 3.514049912958042E-4, + 3.501250659583308E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10255226672652944, + "scoreError" : 4.754330174721577E-4, + "scoreConfidence" : [ + 0.10207683370905728, + 0.1030276997440016 + ], + "scorePercentiles" : { + "0.0" : 0.10222656209110238, + "50.0" : 0.10258916137740645, + "90.0" : 0.10273096904759459, + "95.0" : 0.10273096904759459, + "99.0" : 0.10273096904759459, + "99.9" : 0.10273096904759459, + "99.99" : 0.10273096904759459, + "99.999" : 0.10273096904759459, + "99.9999" : 0.10273096904759459, + "100.0" : 0.10273096904759459 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10260120574354134, + 0.10258990820398659, + 0.10273096904759459 + ], + [ + 0.10258841455082633, + 0.10222656209110238, + 0.10257654072212534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014349260967523992, + "scoreError" : 1.0090775616586608E-4, + "scoreConfidence" : [ + 0.014248353211358126, + 0.014450168723689859 + ], + "scorePercentiles" : { + "0.0" : 0.014309645192448036, + "50.0" : 0.014348172366035115, + "90.0" : 0.014388673696402877, + "95.0" : 0.014388673696402877, + "99.0" : 0.014388673696402877, + "99.9" : 0.014388673696402877, + "99.99" : 0.014388673696402877, + "99.999" : 0.014388673696402877, + "99.9999" : 0.014388673696402877, + "100.0" : 0.014388673696402877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014374564100315805, + 0.014388673696402877, + 0.01438170378967321 + ], + [ + 0.014309645192448036, + 0.014319198394549601, + 0.014321780631754424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9793126411206203, + "scoreError" : 0.1073989532666016, + "scoreConfidence" : [ + 0.8719136878540188, + 1.0867115943872219 + ], + "scorePercentiles" : { + "0.0" : 0.9429985540782649, + "50.0" : 0.9784013443119111, + "90.0" : 1.0189078739684156, + "95.0" : 1.0189078739684156, + "99.0" : 1.0189078739684156, + "99.9" : 1.0189078739684156, + "99.99" : 1.0189078739684156, + "99.999" : 1.0189078739684156, + "99.9999" : 1.0189078739684156, + "100.0" : 1.0189078739684156 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9429985540782649, + 0.9456022879160363, + 0.9447197945399585 + ], + [ + 1.0124469355132617, + 1.0112004007077857, + 1.0189078739684156 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.012344769242187971, + "scoreError" : 5.0372232441035845E-5, + "scoreConfidence" : [ + 0.012294397009746936, + 0.012395141474629006 + ], + "scorePercentiles" : { + "0.0" : 0.012325702427612864, + "50.0" : 0.012343249889004204, + "90.0" : 0.012363363621977545, + "95.0" : 0.012363363621977545, + "99.0" : 0.012363363621977545, + "99.9" : 0.012363363621977545, + "99.99" : 0.012363363621977545, + "99.999" : 0.012363363621977545, + "99.9999" : 0.012363363621977545, + "100.0" : 0.012363363621977545 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012325702427612864, + 0.012330029872387646, + 0.012330037290024758 + ], + [ + 0.012363019753141365, + 0.012363363621977545, + 0.01235646248798365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.505150055312686, + "scoreError" : 0.1860641105606592, + "scoreConfidence" : [ + 3.3190859447520267, + 3.6912141658733453 + ], + "scorePercentiles" : { + "0.0" : 3.4251966130136986, + "50.0" : 3.5107318360058617, + "90.0" : 3.5694156909350463, + "95.0" : 3.5694156909350463, + "99.0" : 3.5694156909350463, + "99.9" : 3.5694156909350463, + "99.99" : 3.5694156909350463, + "99.999" : 3.5694156909350463, + "99.9999" : 3.5694156909350463, + "100.0" : 3.5694156909350463 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5694156909350463, + 3.5603156014234876, + 3.5644246186742694 + ], + [ + 3.4251966130136986, + 3.4611480705882354, + 3.4503997372413795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8492045265280646, + "scoreError" : 0.018234642048560203, + "scoreConfidence" : [ + 2.8309698844795044, + 2.8674391685766247 + ], + "scorePercentiles" : { + "0.0" : 2.841439738068182, + "50.0" : 2.847963167551712, + "90.0" : 2.8602171629968542, + "95.0" : 2.8602171629968542, + "99.0" : 2.8602171629968542, + "99.9" : 2.8602171629968542, + "99.99" : 2.8602171629968542, + "99.999" : 2.8602171629968542, + "99.9999" : 2.8602171629968542, + "100.0" : 2.8602171629968542 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8602171629968542, + 2.8524446680923865, + 2.8483018832241527 + ], + [ + 2.847624451879271, + 2.845199254907539, + 2.841439738068182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1760942858874841, + "scoreError" : 0.0073879778428384705, + "scoreConfidence" : [ + 0.16870630804464562, + 0.1834822637303226 + ], + "scorePercentiles" : { + "0.0" : 0.17331126717041298, + "50.0" : 0.17622867737840928, + "90.0" : 0.1797891385243249, + "95.0" : 0.1797891385243249, + "99.0" : 0.1797891385243249, + "99.9" : 0.1797891385243249, + "99.99" : 0.1797891385243249, + "99.999" : 0.1797891385243249, + "99.9999" : 0.1797891385243249, + "100.0" : 0.1797891385243249 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17340231128296718, + 0.1748608251967127, + 0.17331126717041298 + ], + [ + 0.1797891385243249, + 0.17760564359038114, + 0.17759652956010585 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33639321413002166, + "scoreError" : 0.007646768010038521, + "scoreConfidence" : [ + 0.32874644611998316, + 0.34403998214006015 + ], + "scorePercentiles" : { + "0.0" : 0.3337408923374716, + "50.0" : 0.33645028808166216, + "90.0" : 0.3389598427956479, + "95.0" : 0.3389598427956479, + "99.0" : 0.3389598427956479, + "99.9" : 0.3389598427956479, + "99.99" : 0.3389598427956479, + "99.999" : 0.3389598427956479, + "99.9999" : 0.3389598427956479, + "100.0" : 0.3389598427956479 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3340631234967932, + 0.3337408923374716, + 0.33391384994490636 + ], + [ + 0.3389598427956479, + 0.3388441235387795, + 0.33883745266653115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16242809379934284, + "scoreError" : 0.012330120698542165, + "scoreConfidence" : [ + 0.15009797310080067, + 0.174758214497885 + ], + "scorePercentiles" : { + "0.0" : 0.15807219257397573, + "50.0" : 0.1626438524479838, + "90.0" : 0.1666093599846723, + "95.0" : 0.1666093599846723, + "99.0" : 0.1666093599846723, + "99.9" : 0.1666093599846723, + "99.99" : 0.1666093599846723, + "99.999" : 0.1666093599846723, + "99.9999" : 0.1666093599846723, + "100.0" : 0.1666093599846723 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15820958676770713, + 0.15899491031368745, + 0.15807219257397573 + ], + [ + 0.1666093599846723, + 0.16629279458228016, + 0.16638971857373422 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39275317702564944, + "scoreError" : 0.029452107550936742, + "scoreConfidence" : [ + 0.3633010694747127, + 0.4222052845765862 + ], + "scorePercentiles" : { + "0.0" : 0.38266731810354726, + "50.0" : 0.3928501453295805, + "90.0" : 0.4024224785110664, + "95.0" : 0.4024224785110664, + "99.0" : 0.4024224785110664, + "99.9" : 0.4024224785110664, + "99.99" : 0.4024224785110664, + "99.999" : 0.4024224785110664, + "99.9999" : 0.4024224785110664, + "100.0" : 0.4024224785110664 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.402196212234556, + 0.40239322384516335, + 0.4024224785110664 + ], + [ + 0.383504078424605, + 0.3833357510349586, + 0.38266731810354726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15795994014912945, + "scoreError" : 0.0041476396878400365, + "scoreConfidence" : [ + 0.1538123004612894, + 0.1621075798369695 + ], + "scorePercentiles" : { + "0.0" : 0.15632779731123964, + "50.0" : 0.15804988071084491, + "90.0" : 0.1596122677445613, + "95.0" : 0.1596122677445613, + "99.0" : 0.1596122677445613, + "99.9" : 0.1596122677445613, + "99.99" : 0.1596122677445613, + "99.999" : 0.1596122677445613, + "99.9999" : 0.1596122677445613, + "100.0" : 0.1596122677445613 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1571954524105192, + 0.156437207915526, + 0.15632779731123964 + ], + [ + 0.15928260650176004, + 0.1589043090111706, + 0.1596122677445613 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04852059916433813, + "scoreError" : 0.002269200882250536, + "scoreConfidence" : [ + 0.046251398282087595, + 0.050789800046588666 + ], + "scorePercentiles" : { + "0.0" : 0.047763267298406166, + "50.0" : 0.04840643381079313, + "90.0" : 0.04950884536133514, + "95.0" : 0.04950884536133514, + "99.0" : 0.04950884536133514, + "99.9" : 0.04950884536133514, + "99.99" : 0.04950884536133514, + "99.999" : 0.04950884536133514, + "99.9999" : 0.04950884536133514, + "100.0" : 0.04950884536133514 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04950884536133514, + 0.049234081318464906, + 0.04898786289176929 + ], + [ + 0.0478045333862363, + 0.047825004729816975, + 0.047763267298406166 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9371481.263867075, + "scoreError" : 29270.826948461792, + "scoreConfidence" : [ + 9342210.436918613, + 9400752.090815537 + ], + "scorePercentiles" : { + "0.0" : 9352008.46448598, + "50.0" : 9373237.117619494, + "90.0" : 9383151.533771107, + "95.0" : 9383151.533771107, + "99.0" : 9383151.533771107, + "99.9" : 9383151.533771107, + "99.99" : 9383151.533771107, + "99.999" : 9383151.533771107, + "99.9999" : 9383151.533771107, + "100.0" : 9383151.533771107 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9373823.492970947, + 9371043.863295881, + 9376209.486410497 + ], + [ + 9383151.533771107, + 9372650.74226804, + 9352008.46448598 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-14T08:22:27Z-6fcb38196f6e372eaba3041d6eb3419c2da54a5c-jdk17.json b/performance-results/2025-05-14T08:22:27Z-6fcb38196f6e372eaba3041d6eb3419c2da54a5c-jdk17.json new file mode 100644 index 0000000000..9a22ea5428 --- /dev/null +++ b/performance-results/2025-05-14T08:22:27Z-6fcb38196f6e372eaba3041d6eb3419c2da54a5c-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3434326063413575, + "scoreError" : 0.05493111205750819, + "scoreConfidence" : [ + 3.2885014942838495, + 3.3983637183988655 + ], + "scorePercentiles" : { + "0.0" : 3.334027053494585, + "50.0" : 3.3426992370582087, + "90.0" : 3.3543048977544276, + "95.0" : 3.3543048977544276, + "99.0" : 3.3543048977544276, + "99.9" : 3.3543048977544276, + "99.99" : 3.3543048977544276, + "99.999" : 3.3543048977544276, + "99.9999" : 3.3543048977544276, + "100.0" : 3.3543048977544276 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3405736353167557, + 3.3543048977544276 + ], + [ + 3.334027053494585, + 3.3448248387996617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6859003716059564, + "scoreError" : 0.01671555296576354, + "scoreConfidence" : [ + 1.669184818640193, + 1.7026159245717198 + ], + "scorePercentiles" : { + "0.0" : 1.6832568786424777, + "50.0" : 1.6859059303483654, + "90.0" : 1.6885327470846165, + "95.0" : 1.6885327470846165, + "99.0" : 1.6885327470846165, + "99.9" : 1.6885327470846165, + "99.99" : 1.6885327470846165, + "99.999" : 1.6885327470846165, + "99.9999" : 1.6885327470846165, + "100.0" : 1.6885327470846165 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.684151462592159, + 1.6876603981045721 + ], + [ + 1.6832568786424777, + 1.6885327470846165 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8481499957170132, + "scoreError" : 0.026060872232263485, + "scoreConfidence" : [ + 0.8220891234847497, + 0.8742108679492767 + ], + "scorePercentiles" : { + "0.0" : 0.8435519365359572, + "50.0" : 0.8481193108900993, + "90.0" : 0.8528094245518967, + "95.0" : 0.8528094245518967, + "99.0" : 0.8528094245518967, + "99.9" : 0.8528094245518967, + "99.99" : 0.8528094245518967, + "99.999" : 0.8528094245518967, + "99.9999" : 0.8528094245518967, + "100.0" : 0.8528094245518967 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8435519365359572, + 0.8528094245518967 + ], + [ + 0.8463959826752865, + 0.8498426391049122 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.021151973806372, + "scoreError" : 0.10810940741657382, + "scoreConfidence" : [ + 15.913042566389798, + 16.129261381222946 + ], + "scorePercentiles" : { + "0.0" : 15.949247493108613, + "50.0" : 16.03753360034897, + "90.0" : 16.053561503474235, + "95.0" : 16.053561503474235, + "99.0" : 16.053561503474235, + "99.9" : 16.053561503474235, + "99.99" : 16.053561503474235, + "99.999" : 16.053561503474235, + "99.9999" : 16.053561503474235, + "100.0" : 16.053561503474235 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.042326985262434, + 15.949247493108613, + 16.006708660295004 + ], + [ + 16.04047263271662, + 16.053561503474235, + 16.034594567981316 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2587.1396952385066, + "scoreError" : 179.6508538136482, + "scoreConfidence" : [ + 2407.4888414248585, + 2766.790549052155 + ], + "scorePercentiles" : { + "0.0" : 2526.8868569546526, + "50.0" : 2587.9471865679134, + "90.0" : 2648.277777389688, + "95.0" : 2648.277777389688, + "99.0" : 2648.277777389688, + "99.9" : 2648.277777389688, + "99.99" : 2648.277777389688, + "99.999" : 2648.277777389688, + "99.9999" : 2648.277777389688, + "100.0" : 2648.277777389688 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2648.277777389688, + 2644.4880749569174, + 2643.9895780702805 + ], + [ + 2526.8868569546526, + 2531.904795065546, + 2527.291088993956 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75852.64268313852, + "scoreError" : 2708.6832611939158, + "scoreConfidence" : [ + 73143.9594219446, + 78561.32594433244 + ], + "scorePercentiles" : { + "0.0" : 74904.0053887309, + "50.0" : 75882.75751871968, + "90.0" : 76759.27708483196, + "95.0" : 76759.27708483196, + "99.0" : 76759.27708483196, + "99.9" : 76759.27708483196, + "99.99" : 76759.27708483196, + "99.999" : 76759.27708483196, + "99.9999" : 76759.27708483196, + "100.0" : 76759.27708483196 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76736.50664592147, + 76759.27708483196, + 76703.28458083562 + ], + [ + 75062.23045660372, + 74904.0053887309, + 74950.55194190744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 341.1070724101766, + "scoreError" : 21.680346049536215, + "scoreConfidence" : [ + 319.4267263606404, + 362.78741845971285 + ], + "scorePercentiles" : { + "0.0" : 333.4360491331106, + "50.0" : 340.49308182545616, + "90.0" : 350.1156978118412, + "95.0" : 350.1156978118412, + "99.0" : 350.1156978118412, + "99.9" : 350.1156978118412, + "99.99" : 350.1156978118412, + "99.999" : 350.1156978118412, + "99.9999" : 350.1156978118412, + "100.0" : 350.1156978118412 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 333.4360491331106, + 334.3016383955047, + 334.70634906312023 + ], + [ + 346.2798145877921, + 350.1156978118412, + 347.8028854696908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.8209748936336, + "scoreError" : 4.6152265053975325, + "scoreConfidence" : [ + 112.20574838823607, + 121.43620139903113 + ], + "scorePercentiles" : { + "0.0" : 114.6190197369563, + "50.0" : 117.0268952790785, + "90.0" : 118.40734244182285, + "95.0" : 118.40734244182285, + "99.0" : 118.40734244182285, + "99.9" : 118.40734244182285, + "99.99" : 118.40734244182285, + "99.999" : 118.40734244182285, + "99.9999" : 118.40734244182285, + "100.0" : 118.40734244182285 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 118.25765538672955, + 118.40734244182285, + 118.14709624683381 + ], + [ + 114.6190197369563, + 115.90669431132319, + 115.5880412381359 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062389351554314416, + "scoreError" : 4.7932139097571475E-4, + "scoreConfidence" : [ + 0.0619100301633387, + 0.06286867294529012 + ], + "scorePercentiles" : { + "0.0" : 0.062199805672523714, + "50.0" : 0.06236838190339086, + "90.0" : 0.06261868740763932, + "95.0" : 0.06261868740763932, + "99.0" : 0.06261868740763932, + "99.9" : 0.06261868740763932, + "99.99" : 0.06261868740763932, + "99.999" : 0.06261868740763932, + "99.9999" : 0.06261868740763932, + "100.0" : 0.06261868740763932 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06261868740763932, + 0.06246388528686093, + 0.0625290629095593 + ], + [ + 0.062199805672523714, + 0.06227287851992079, + 0.06225178952938247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.810142103757004E-4, + "scoreError" : 1.8422944779307066E-5, + "scoreConfidence" : [ + 3.6259126559639335E-4, + 3.994371551550075E-4 + ], + "scorePercentiles" : { + "0.0" : 3.743604535086239E-4, + "50.0" : 3.8113356107916254E-4, + "90.0" : 3.875407688336346E-4, + "95.0" : 3.875407688336346E-4, + "99.0" : 3.875407688336346E-4, + "99.9" : 3.875407688336346E-4, + "99.99" : 3.875407688336346E-4, + "99.999" : 3.875407688336346E-4, + "99.9999" : 3.875407688336346E-4, + "100.0" : 3.875407688336346E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.862025061731704E-4, + 3.871842027022166E-4, + 3.875407688336346E-4 + ], + [ + 3.7606461598515466E-4, + 3.743604535086239E-4, + 3.747327150514023E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10148302255267977, + "scoreError" : 0.002113706935799896, + "scoreConfidence" : [ + 0.09936931561687987, + 0.10359672948847967 + ], + "scorePercentiles" : { + "0.0" : 0.10051683041170795, + "50.0" : 0.1015798621853776, + "90.0" : 0.10222254455779531, + "95.0" : 0.10222254455779531, + "99.0" : 0.10222254455779531, + "99.9" : 0.10222254455779531, + "99.99" : 0.10222254455779531, + "99.999" : 0.10222254455779531, + "99.9999" : 0.10222254455779531, + "100.0" : 0.10222254455779531 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10082921640451704, + 0.10110948764976492, + 0.10051683041170795 + ], + [ + 0.10216981957130306, + 0.10205023672099027, + 0.10222254455779531 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012971430810405369, + "scoreError" : 1.79231537377462E-4, + "scoreConfidence" : [ + 0.012792199273027906, + 0.01315066234778283 + ], + "scorePercentiles" : { + "0.0" : 0.012909012750093266, + "50.0" : 0.012971260636224252, + "90.0" : 0.013039744782864952, + "95.0" : 0.013039744782864952, + "99.0" : 0.013039744782864952, + "99.9" : 0.013039744782864952, + "99.99" : 0.013039744782864952, + "99.999" : 0.013039744782864952, + "99.9999" : 0.013039744782864952, + "100.0" : 0.013039744782864952 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013025517492318332, + 0.013039744782864952, + 0.01302312893714887 + ], + [ + 0.012911788564707158, + 0.012909012750093266, + 0.012919392335299635 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9266070008042951, + "scoreError" : 0.02764470085155464, + "scoreConfidence" : [ + 0.8989622999527405, + 0.9542517016558498 + ], + "scorePercentiles" : { + "0.0" : 0.9167091621596847, + "50.0" : 0.9270408048291614, + "90.0" : 0.9362849647069837, + "95.0" : 0.9362849647069837, + "99.0" : 0.9362849647069837, + "99.9" : 0.9362849647069837, + "99.99" : 0.9362849647069837, + "99.999" : 0.9362849647069837, + "99.9999" : 0.9362849647069837, + "100.0" : 0.9362849647069837 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9167091621596847, + 0.9192275517970402, + 0.9170195827067669 + ], + [ + 0.9355466855940131, + 0.9362849647069837, + 0.9348540578612825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010781186876464746, + "scoreError" : 1.7734658530255175E-4, + "scoreConfidence" : [ + 0.010603840291162195, + 0.010958533461767297 + ], + "scorePercentiles" : { + "0.0" : 0.010705549223973845, + "50.0" : 0.010788429068632921, + "90.0" : 0.010851521650339209, + "95.0" : 0.010851521650339209, + "99.0" : 0.010851521650339209, + "99.9" : 0.010851521650339209, + "99.99" : 0.010851521650339209, + "99.999" : 0.010851521650339209, + "99.9999" : 0.010851521650339209, + "100.0" : 0.010851521650339209 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010751896575822607, + 0.010705549223973845, + 0.010719524360700443 + ], + [ + 0.010833667886509149, + 0.010824961561443237, + 0.010851521650339209 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.5858491465959443, + "scoreError" : 0.21085157148421574, + "scoreConfidence" : [ + 3.3749975751117285, + 3.79670071808016 + ], + "scorePercentiles" : { + "0.0" : 3.511752580758427, + "50.0" : 3.586675970572024, + "90.0" : 3.6584904718361377, + "95.0" : 3.6584904718361377, + "99.0" : 3.6584904718361377, + "99.9" : 3.6584904718361377, + "99.99" : 3.6584904718361377, + "99.999" : 3.6584904718361377, + "99.9999" : 3.6584904718361377, + "100.0" : 3.6584904718361377 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.511752580758427, + 3.5188561843771993, + 3.5212888163265306 + ], + [ + 3.652063124817518, + 3.6584904718361377, + 3.652643701459854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9431181133970252, + "scoreError" : 0.03185153532850182, + "scoreConfidence" : [ + 2.911266578068523, + 2.9749696487255273 + ], + "scorePercentiles" : { + "0.0" : 2.9315702010550995, + "50.0" : 2.942092324067618, + "90.0" : 2.9579960618160306, + "95.0" : 2.9579960618160306, + "99.0" : 2.9579960618160306, + "99.9" : 2.9579960618160306, + "99.99" : 2.9579960618160306, + "99.999" : 2.9579960618160306, + "99.9999" : 2.9579960618160306, + "100.0" : 2.9579960618160306 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9332771524926686, + 2.934407539612676, + 2.9315702010550995 + ], + [ + 2.9579960618160306, + 2.94977710852256, + 2.9516806168831167 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1779339283835671, + "scoreError" : 0.0059975711928150245, + "scoreConfidence" : [ + 0.1719363571907521, + 0.18393149957638213 + ], + "scorePercentiles" : { + "0.0" : 0.1761909297367772, + "50.0" : 0.17731557852205032, + "90.0" : 0.18180954345138536, + "95.0" : 0.18180954345138536, + "99.0" : 0.18180954345138536, + "99.9" : 0.18180954345138536, + "99.99" : 0.18180954345138536, + "99.999" : 0.18180954345138536, + "99.9999" : 0.18180954345138536, + "100.0" : 0.18180954345138536 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17650980287706292, + 0.17640219948844593, + 0.1761909297367772 + ], + [ + 0.18180954345138536, + 0.17856974058069355, + 0.17812135416703775 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32390219678900667, + "scoreError" : 0.003910859976888052, + "scoreConfidence" : [ + 0.3199913368121186, + 0.32781305676589473 + ], + "scorePercentiles" : { + "0.0" : 0.3221171358028668, + "50.0" : 0.3241110730031184, + "90.0" : 0.32532988438140475, + "95.0" : 0.32532988438140475, + "99.0" : 0.32532988438140475, + "99.9" : 0.32532988438140475, + "99.99" : 0.32532988438140475, + "99.999" : 0.32532988438140475, + "99.9999" : 0.32532988438140475, + "100.0" : 0.32532988438140475 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3250109031167734, + 0.3250535409068747, + 0.32532988438140475 + ], + [ + 0.32321124288946346, + 0.3221171358028668, + 0.322690473636657 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14338331303770604, + "scoreError" : 0.00393181579501914, + "scoreConfidence" : [ + 0.1394514972426869, + 0.14731512883272518 + ], + "scorePercentiles" : { + "0.0" : 0.1419636853723631, + "50.0" : 0.14338507397679073, + "90.0" : 0.14476720678074062, + "95.0" : 0.14476720678074062, + "99.0" : 0.14476720678074062, + "99.9" : 0.14476720678074062, + "99.99" : 0.14476720678074062, + "99.999" : 0.14476720678074062, + "99.9999" : 0.14476720678074062, + "100.0" : 0.14476720678074062 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14219382243203277, + 0.14216237421812805, + 0.1419636853723631 + ], + [ + 0.14476720678074062, + 0.14457632552154867, + 0.14463646390142312 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40000971326889023, + "scoreError" : 0.008183865357448493, + "scoreConfidence" : [ + 0.39182584791144176, + 0.4081935786263387 + ], + "scorePercentiles" : { + "0.0" : 0.3960343752722664, + "50.0" : 0.40024346185840687, + "90.0" : 0.40336227892061954, + "95.0" : 0.40336227892061954, + "99.0" : 0.40336227892061954, + "99.9" : 0.40336227892061954, + "99.99" : 0.40336227892061954, + "99.999" : 0.40336227892061954, + "99.9999" : 0.40336227892061954, + "100.0" : 0.40336227892061954 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40160596767198103, + 0.39766769924841927, + 0.3960343752722664 + ], + [ + 0.40336227892061954, + 0.40250700245522236, + 0.3988809560448327 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1596068760423844, + "scoreError" : 0.001700237433113472, + "scoreConfidence" : [ + 0.15790663860927093, + 0.1613071134754979 + ], + "scorePercentiles" : { + "0.0" : 0.15894328094155794, + "50.0" : 0.15969293815677532, + "90.0" : 0.16056366864152338, + "95.0" : 0.16056366864152338, + "99.0" : 0.16056366864152338, + "99.9" : 0.16056366864152338, + "99.99" : 0.16056366864152338, + "99.999" : 0.16056366864152338, + "99.9999" : 0.16056366864152338, + "100.0" : 0.16056366864152338 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16056366864152338, + 0.15973525842983788, + 0.1589525174288303 + ], + [ + 0.15965061788371276, + 0.1597959129288442, + 0.15894328094155794 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047464815792502495, + "scoreError" : 0.00256346544085452, + "scoreConfidence" : [ + 0.044901350351647974, + 0.050028281233357015 + ], + "scorePercentiles" : { + "0.0" : 0.04656481634591655, + "50.0" : 0.047432617883775056, + "90.0" : 0.0484077992467882, + "95.0" : 0.0484077992467882, + "99.0" : 0.0484077992467882, + "99.9" : 0.0484077992467882, + "99.99" : 0.0484077992467882, + "99.999" : 0.0484077992467882, + "99.9999" : 0.0484077992467882, + "100.0" : 0.0484077992467882 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04656481634591655, + 0.046634040244545066, + 0.04670436355059874 + ], + [ + 0.0484077992467882, + 0.048317003150215004, + 0.048160872216951374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8767484.014163809, + "scoreError" : 512112.929789071, + "scoreConfidence" : [ + 8255371.084374738, + 9279596.94395288 + ], + "scorePercentiles" : { + "0.0" : 8514199.70893617, + "50.0" : 8819506.132189628, + "90.0" : 8940381.55227882, + "95.0" : 8940381.55227882, + "99.0" : 8940381.55227882, + "99.9" : 8940381.55227882, + "99.99" : 8940381.55227882, + "99.999" : 8940381.55227882, + "99.9999" : 8940381.55227882, + "100.0" : 8940381.55227882 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8940381.55227882, + 8912671.738201248, + 8913230.288770054 + ], + [ + 8726340.52617801, + 8598080.270618556, + 8514199.70893617 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-14T23:22:42Z-97de42ff192bffc720de50fb9784a9df59119837-jdk17.json b/performance-results/2025-05-14T23:22:42Z-97de42ff192bffc720de50fb9784a9df59119837-jdk17.json new file mode 100644 index 0000000000..6ec497f503 --- /dev/null +++ b/performance-results/2025-05-14T23:22:42Z-97de42ff192bffc720de50fb9784a9df59119837-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3702627691493348, + "scoreError" : 0.04297276945593371, + "scoreConfidence" : [ + 3.327289999693401, + 3.4132355386052686 + ], + "scorePercentiles" : { + "0.0" : 3.361946863749914, + "50.0" : 3.3716923975689124, + "90.0" : 3.3757194177096, + "95.0" : 3.3757194177096, + "99.0" : 3.3757194177096, + "99.9" : 3.3757194177096, + "99.99" : 3.3757194177096, + "99.999" : 3.3757194177096, + "99.9999" : 3.3757194177096, + "100.0" : 3.3757194177096 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.367841821875018, + 3.3757194177096 + ], + [ + 3.361946863749914, + 3.375542973262806 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6894510351292862, + "scoreError" : 0.014552270244878223, + "scoreConfidence" : [ + 1.674898764884408, + 1.7040033053741643 + ], + "scorePercentiles" : { + "0.0" : 1.6863027738527496, + "50.0" : 1.6900671054227758, + "90.0" : 1.6913671558188432, + "95.0" : 1.6913671558188432, + "99.0" : 1.6913671558188432, + "99.9" : 1.6913671558188432, + "99.99" : 1.6913671558188432, + "99.999" : 1.6913671558188432, + "99.9999" : 1.6913671558188432, + "100.0" : 1.6913671558188432 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6907274417096398, + 1.6894067691359118 + ], + [ + 1.6863027738527496, + 1.6913671558188432 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8592273065068963, + "scoreError" : 0.017420744170110605, + "scoreConfidence" : [ + 0.8418065623367856, + 0.8766480506770069 + ], + "scorePercentiles" : { + "0.0" : 0.8559820123270362, + "50.0" : 0.8592888370850831, + "90.0" : 0.8623495395303827, + "95.0" : 0.8623495395303827, + "99.0" : 0.8623495395303827, + "99.9" : 0.8623495395303827, + "99.99" : 0.8623495395303827, + "99.999" : 0.8623495395303827, + "99.9999" : 0.8623495395303827, + "100.0" : 0.8623495395303827 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8601593118226384, + 0.8584183623475278 + ], + [ + 0.8559820123270362, + 0.8623495395303827 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.49966247377747, + "scoreError" : 0.11404015314928159, + "scoreConfidence" : [ + 16.385622320628187, + 16.613702626926752 + ], + "scorePercentiles" : { + "0.0" : 16.442177606394132, + "50.0" : 16.508308902137315, + "90.0" : 16.545777495693393, + "95.0" : 16.545777495693393, + "99.0" : 16.545777495693393, + "99.9" : 16.545777495693393, + "99.99" : 16.545777495693393, + "99.999" : 16.545777495693393, + "99.9999" : 16.545777495693393, + "100.0" : 16.545777495693393 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.545777495693393, + 16.516747414336816, + 16.532259174580602 + ], + [ + 16.49987038993781, + 16.442177606394132, + 16.461142761722062 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2763.750811951975, + "scoreError" : 39.97685790883956, + "scoreConfidence" : [ + 2723.7739540431353, + 2803.7276698608143 + ], + "scorePercentiles" : { + "0.0" : 2745.3688929093114, + "50.0" : 2765.2758624970647, + "90.0" : 2778.805796493642, + "95.0" : 2778.805796493642, + "99.0" : 2778.805796493642, + "99.9" : 2778.805796493642, + "99.99" : 2778.805796493642, + "99.999" : 2778.805796493642, + "99.9999" : 2778.805796493642, + "100.0" : 2778.805796493642 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2774.139263507648, + 2775.927281843939, + 2778.805796493642 + ], + [ + 2745.3688929093114, + 2751.8511754708275, + 2756.412461486481 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77902.17585896842, + "scoreError" : 3170.1260208224653, + "scoreConfidence" : [ + 74732.04983814595, + 81072.30187979089 + ], + "scorePercentiles" : { + "0.0" : 76848.66044059259, + "50.0" : 77885.23228959792, + "90.0" : 79006.12918058524, + "95.0" : 79006.12918058524, + "99.0" : 79006.12918058524, + "99.9" : 79006.12918058524, + "99.99" : 79006.12918058524, + "99.999" : 79006.12918058524, + "99.9999" : 79006.12918058524, + "100.0" : 79006.12918058524 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78875.92273631005, + 79006.12918058524, + 78918.07546186892 + ], + [ + 76848.66044059259, + 76894.5418428858, + 76869.72549156795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 371.4312955749431, + "scoreError" : 11.907841568516718, + "scoreConfidence" : [ + 359.52345400642633, + 383.3391371434598 + ], + "scorePercentiles" : { + "0.0" : 366.3388131755764, + "50.0" : 371.519961731325, + "90.0" : 375.66567546479934, + "95.0" : 375.66567546479934, + "99.0" : 375.66567546479934, + "99.9" : 375.66567546479934, + "99.99" : 375.66567546479934, + "99.999" : 375.66567546479934, + "99.9999" : 375.66567546479934, + "100.0" : 375.66567546479934 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 374.7269425607698, + 375.3410980968168, + 375.66567546479934 + ], + [ + 366.3388131755764, + 368.2022632498159, + 368.3129809018802 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 119.00528098496886, + "scoreError" : 4.620284104528436, + "scoreConfidence" : [ + 114.38499688044043, + 123.6255650894973 + ], + "scorePercentiles" : { + "0.0" : 117.42018970841153, + "50.0" : 118.97582396455738, + "90.0" : 120.7091561118185, + "95.0" : 120.7091561118185, + "99.0" : 120.7091561118185, + "99.9" : 120.7091561118185, + "99.99" : 120.7091561118185, + "99.999" : 120.7091561118185, + "99.9999" : 120.7091561118185, + "100.0" : 120.7091561118185 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.43297619747537, + 117.67265287547174, + 117.42018970841153 + ], + [ + 120.278995053643, + 120.7091561118185, + 120.517715962993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060764193957138134, + "scoreError" : 6.267673513787958E-4, + "scoreConfidence" : [ + 0.06013742660575934, + 0.06139096130851693 + ], + "scorePercentiles" : { + "0.0" : 0.06046792128383894, + "50.0" : 0.06075066210136768, + "90.0" : 0.061016569014961074, + "95.0" : 0.061016569014961074, + "99.0" : 0.061016569014961074, + "99.9" : 0.061016569014961074, + "99.99" : 0.061016569014961074, + "99.999" : 0.061016569014961074, + "99.9999" : 0.061016569014961074, + "100.0" : 0.061016569014961074 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060862273133383646, + 0.06098744810362808, + 0.061016569014961074 + ], + [ + 0.06046792128383894, + 0.06061190113766539, + 0.06063905106935172 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5157793050781435E-4, + "scoreError" : 1.2317728975975028E-6, + "scoreConfidence" : [ + 3.5034615761021684E-4, + 3.5280970340541187E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5076705821873147E-4, + "50.0" : 3.5170749317529676E-4, + "90.0" : 3.5202164630643334E-4, + "95.0" : 3.5202164630643334E-4, + "99.0" : 3.5202164630643334E-4, + "99.9" : 3.5202164630643334E-4, + "99.99" : 3.5202164630643334E-4, + "99.999" : 3.5202164630643334E-4, + "99.9999" : 3.5202164630643334E-4, + "100.0" : 3.5202164630643334E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5076705821873147E-4, + 3.516479314132526E-4, + 3.5181062842694284E-4 + ], + [ + 3.517670549373409E-4, + 3.5145326374418486E-4, + 3.5202164630643334E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10017210504415941, + "scoreError" : 0.001017140100009089, + "scoreConfidence" : [ + 0.09915496494415033, + 0.1011892451441685 + ], + "scorePercentiles" : { + "0.0" : 0.09976262063427141, + "50.0" : 0.1001800775399842, + "90.0" : 0.10052295692644826, + "95.0" : 0.10052295692644826, + "99.0" : 0.10052295692644826, + "99.9" : 0.10052295692644826, + "99.99" : 0.10052295692644826, + "99.999" : 0.10052295692644826, + "99.9999" : 0.10052295692644826, + "100.0" : 0.10052295692644826 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10046018604838061, + 0.10052295692644826, + 0.10051679211354247 + ], + [ + 0.09987010551072584, + 0.09976262063427141, + 0.09989996903158778 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012923516489972751, + "scoreError" : 5.5467603433215854E-5, + "scoreConfidence" : [ + 0.012868048886539534, + 0.012978984093405968 + ], + "scorePercentiles" : { + "0.0" : 0.01290104050225636, + "50.0" : 0.012920830054943537, + "90.0" : 0.012946059829579878, + "95.0" : 0.012946059829579878, + "99.0" : 0.012946059829579878, + "99.9" : 0.012946059829579878, + "99.99" : 0.012946059829579878, + "99.999" : 0.012946059829579878, + "99.9999" : 0.012946059829579878, + "100.0" : 0.012946059829579878 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012944956295767958, + 0.012946059829579878, + 0.012931040617164699 + ], + [ + 0.01290104050225636, + 0.012907382202345228, + 0.012910619492722377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9911694515097166, + "scoreError" : 0.01740561343700532, + "scoreConfidence" : [ + 0.9737638380727113, + 1.008575064946722 + ], + "scorePercentiles" : { + "0.0" : 0.9832274800904532, + "50.0" : 0.9911467255657341, + "90.0" : 0.9999467521247876, + "95.0" : 0.9999467521247876, + "99.0" : 0.9999467521247876, + "99.9" : 0.9999467521247876, + "99.99" : 0.9999467521247876, + "99.999" : 0.9999467521247876, + "99.9999" : 0.9999467521247876, + "100.0" : 0.9999467521247876 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9832274800904532, + 0.9869754419224317, + 0.9877305839012346 + ], + [ + 0.9945628672302337, + 0.9999467521247876, + 0.9945735837891596 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011088656588665787, + "scoreError" : 9.478057085327789E-4, + "scoreConfidence" : [ + 0.010140850880133008, + 0.012036462297198566 + ], + "scorePercentiles" : { + "0.0" : 0.01076838455077595, + "50.0" : 0.011089013089414474, + "90.0" : 0.011402970298339315, + "95.0" : 0.011402970298339315, + "99.0" : 0.011402970298339315, + "99.9" : 0.011402970298339315, + "99.99" : 0.011402970298339315, + "99.999" : 0.011402970298339315, + "99.9999" : 0.011402970298339315, + "100.0" : 0.011402970298339315 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01076838455077595, + 0.010785549792383439, + 0.010786617354368146 + ], + [ + 0.01139700871166707, + 0.011402970298339315, + 0.011391408824460802 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2004652916579146, + "scoreError" : 0.2719705954771019, + "scoreConfidence" : [ + 2.9284946961808127, + 3.4724358871350165 + ], + "scorePercentiles" : { + "0.0" : 3.103641433622829, + "50.0" : 3.2005559044071052, + "90.0" : 3.296763577455504, + "95.0" : 3.296763577455504, + "99.0" : 3.296763577455504, + "99.9" : 3.296763577455504, + "99.99" : 3.296763577455504, + "99.999" : 3.296763577455504, + "99.9999" : 3.296763577455504, + "100.0" : 3.296763577455504 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.288873658119658, + 3.296763577455504, + 3.2805970452459015 + ], + [ + 3.103641433622829, + 3.112401271935283, + 3.1205147635683095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7139550185222148, + "scoreError" : 0.07715827341526325, + "scoreConfidence" : [ + 2.6367967451069516, + 2.791113291937478 + ], + "scorePercentiles" : { + "0.0" : 2.6821136063287745, + "50.0" : 2.715442825177002, + "90.0" : 2.74460473298573, + "95.0" : 2.74460473298573, + "99.0" : 2.74460473298573, + "99.9" : 2.74460473298573, + "99.99" : 2.74460473298573, + "99.999" : 2.74460473298573, + "99.9999" : 2.74460473298573, + "100.0" : 2.74460473298573 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.74460473298573, + 2.7379467054475772, + 2.7325862098360654 + ], + [ + 2.698299440517939, + 2.6821136063287745, + 2.6881794160171997 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17757216552330304, + "scoreError" : 0.004471415576009319, + "scoreConfidence" : [ + 0.17310074994729371, + 0.18204358109931237 + ], + "scorePercentiles" : { + "0.0" : 0.17602356410617476, + "50.0" : 0.17733519749170545, + "90.0" : 0.1798441798906593, + "95.0" : 0.1798441798906593, + "99.0" : 0.1798441798906593, + "99.9" : 0.1798441798906593, + "99.99" : 0.1798441798906593, + "99.999" : 0.1798441798906593, + "99.9999" : 0.1798441798906593, + "100.0" : 0.1798441798906593 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1798441798906593, + 0.17866911597077056, + 0.17834124327216308 + ], + [ + 0.17622573818880294, + 0.17602356410617476, + 0.17632915171124786 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.317578457901899, + "scoreError" : 0.012006776637288224, + "scoreConfidence" : [ + 0.30557168126461076, + 0.3295852345391872 + ], + "scorePercentiles" : { + "0.0" : 0.31331157594460807, + "50.0" : 0.31773150891630086, + "90.0" : 0.32156549419595487, + "95.0" : 0.32156549419595487, + "99.0" : 0.32156549419595487, + "99.9" : 0.32156549419595487, + "99.99" : 0.32156549419595487, + "99.999" : 0.32156549419595487, + "99.9999" : 0.32156549419595487, + "100.0" : 0.32156549419595487 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31331157594460807, + 0.31407069027354667, + 0.3136465905469828 + ], + [ + 0.32156549419595487, + 0.32148406889124637, + 0.3213923275590551 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14216086867376182, + "scoreError" : 0.010368065574487804, + "scoreConfidence" : [ + 0.13179280309927402, + 0.15252893424824962 + ], + "scorePercentiles" : { + "0.0" : 0.13855889363058208, + "50.0" : 0.14221082536841728, + "90.0" : 0.14560259804606737, + "95.0" : 0.14560259804606737, + "99.0" : 0.14560259804606737, + "99.9" : 0.14560259804606737, + "99.99" : 0.14560259804606737, + "99.999" : 0.14560259804606737, + "99.9999" : 0.14560259804606737, + "100.0" : 0.14560259804606737 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13855889363058208, + 0.13884825309970425, + 0.13895681664952894 + ], + [ + 0.14546483408730562, + 0.14560259804606737, + 0.14553381652938266 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3925621364772381, + "scoreError" : 0.02619736322016944, + "scoreConfidence" : [ + 0.3663647732570686, + 0.41875949969740756 + ], + "scorePercentiles" : { + "0.0" : 0.38082825286568417, + "50.0" : 0.3936383001798788, + "90.0" : 0.40223659464242617, + "95.0" : 0.40223659464242617, + "99.0" : 0.40223659464242617, + "99.9" : 0.40223659464242617, + "99.99" : 0.40223659464242617, + "99.999" : 0.40223659464242617, + "99.9999" : 0.40223659464242617, + "100.0" : 0.40223659464242617 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38872586263458625, + 0.3837258425233107, + 0.38082825286568417 + ], + [ + 0.40223659464242617, + 0.4013055284722501, + 0.39855073772517136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15443369719654837, + "scoreError" : 0.005762011048327298, + "scoreConfidence" : [ + 0.14867168614822107, + 0.16019570824487567 + ], + "scorePercentiles" : { + "0.0" : 0.15249758541234598, + "50.0" : 0.15442639226726965, + "90.0" : 0.15644162202962938, + "95.0" : 0.15644162202962938, + "99.0" : 0.15644162202962938, + "99.9" : 0.15644162202962938, + "99.99" : 0.15644162202962938, + "99.999" : 0.15644162202962938, + "99.9999" : 0.15644162202962938, + "100.0" : 0.15644162202962938 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15252100424000245, + 0.15249758541234598, + 0.15266157675632766 + ], + [ + 0.1562891869627731, + 0.15644162202962938, + 0.15619120777821163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04648785248527262, + "scoreError" : 0.003010632165431645, + "scoreConfidence" : [ + 0.04347722031984097, + 0.049498484650704264 + ], + "scorePercentiles" : { + "0.0" : 0.04540210879514024, + "50.0" : 0.04636408027513523, + "90.0" : 0.047847239045559375, + "95.0" : 0.047847239045559375, + "99.0" : 0.047847239045559375, + "99.9" : 0.047847239045559375, + "99.99" : 0.047847239045559375, + "99.999" : 0.047847239045559375, + "99.9999" : 0.047847239045559375, + "100.0" : 0.047847239045559375 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04580121610530462, + 0.045456981776527225, + 0.04540210879514024 + ], + [ + 0.047847239045559375, + 0.04749262474413833, + 0.04692694444496584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8547863.930717023, + "scoreError" : 521245.9431007223, + "scoreConfidence" : [ + 8026617.987616301, + 9069109.873817746 + ], + "scorePercentiles" : { + "0.0" : 8317483.216957606, + "50.0" : 8585747.05313152, + "90.0" : 8727523.605584642, + "95.0" : 8727523.605584642, + "99.0" : 8727523.605584642, + "99.9" : 8727523.605584642, + "99.99" : 8727523.605584642, + "99.999" : 8727523.605584642, + "99.9999" : 8727523.605584642, + "100.0" : 8727523.605584642 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8504309.926020408, + 8346981.887406172, + 8317483.216957606 + ], + [ + 8723700.76809067, + 8727523.605584642, + 8667184.180242633 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-15T02:24:00Z-06377ea866e5dae073d93c86528cda47dc49b7f5-jdk17.json b/performance-results/2025-05-15T02:24:00Z-06377ea866e5dae073d93c86528cda47dc49b7f5-jdk17.json new file mode 100644 index 0000000000..3977352090 --- /dev/null +++ b/performance-results/2025-05-15T02:24:00Z-06377ea866e5dae073d93c86528cda47dc49b7f5-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3416915306963952, + "scoreError" : 0.03779025622733417, + "scoreConfidence" : [ + 3.303901274469061, + 3.3794817869237295 + ], + "scorePercentiles" : { + "0.0" : 3.335327939554456, + "50.0" : 3.3412737980381317, + "90.0" : 3.3488905871548633, + "95.0" : 3.3488905871548633, + "99.0" : 3.3488905871548633, + "99.9" : 3.3488905871548633, + "99.99" : 3.3488905871548633, + "99.999" : 3.3488905871548633, + "99.9999" : 3.3488905871548633, + "100.0" : 3.3488905871548633 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.339045620359447, + 3.3488905871548633 + ], + [ + 3.335327939554456, + 3.343501975716816 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.677158532278434, + "scoreError" : 0.040854497915147454, + "scoreConfidence" : [ + 1.6363040343632864, + 1.7180130301935814 + ], + "scorePercentiles" : { + "0.0" : 1.6707938687247332, + "50.0" : 1.6762302818494663, + "90.0" : 1.6853796966900698, + "95.0" : 1.6853796966900698, + "99.0" : 1.6853796966900698, + "99.9" : 1.6853796966900698, + "99.99" : 1.6853796966900698, + "99.999" : 1.6853796966900698, + "99.9999" : 1.6853796966900698, + "100.0" : 1.6853796966900698 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6784768172480575, + 1.6853796966900698 + ], + [ + 1.6707938687247332, + 1.673983746450875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.848086188458516, + "scoreError" : 0.017439862559141785, + "scoreConfidence" : [ + 0.8306463258993743, + 0.8655260510176578 + ], + "scorePercentiles" : { + "0.0" : 0.8442640292571827, + "50.0" : 0.8489191292997078, + "90.0" : 0.850242465977466, + "95.0" : 0.850242465977466, + "99.0" : 0.850242465977466, + "99.9" : 0.850242465977466, + "99.99" : 0.850242465977466, + "99.999" : 0.850242465977466, + "99.9999" : 0.850242465977466, + "100.0" : 0.850242465977466 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8496953913821156, + 0.850242465977466 + ], + [ + 0.8442640292571827, + 0.8481428672173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.017400794726104, + "scoreError" : 0.5672344061708663, + "scoreConfidence" : [ + 15.450166388555237, + 16.58463520089697 + ], + "scorePercentiles" : { + "0.0" : 15.825692291569359, + "50.0" : 16.00304025020426, + "90.0" : 16.230984293464935, + "95.0" : 16.230984293464935, + "99.0" : 16.230984293464935, + "99.9" : 16.230984293464935, + "99.99" : 16.230984293464935, + "99.999" : 16.230984293464935, + "99.9999" : 16.230984293464935, + "100.0" : 16.230984293464935 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.841025856790624, + 15.834698542176094, + 15.825692291569359 + ], + [ + 16.165054643617896, + 16.230984293464935, + 16.206949140737724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2583.4399970202944, + "scoreError" : 136.3379185593203, + "scoreConfidence" : [ + 2447.102078460974, + 2719.7779155796147 + ], + "scorePercentiles" : { + "0.0" : 2536.201048188304, + "50.0" : 2581.72340042013, + "90.0" : 2633.8071638746346, + "95.0" : 2633.8071638746346, + "99.0" : 2633.8071638746346, + "99.9" : 2633.8071638746346, + "99.99" : 2633.8071638746346, + "99.999" : 2633.8071638746346, + "99.9999" : 2633.8071638746346, + "100.0" : 2633.8071638746346 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2540.118744544158, + 2541.319218812213, + 2536.201048188304 + ], + [ + 2627.066224674409, + 2622.127582028047, + 2633.8071638746346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77007.68857457419, + "scoreError" : 2948.0850161172443, + "scoreConfidence" : [ + 74059.60355845695, + 79955.77359069143 + ], + "scorePercentiles" : { + "0.0" : 76048.4734445912, + "50.0" : 76941.03743983922, + "90.0" : 78125.00220309968, + "95.0" : 78125.00220309968, + "99.0" : 78125.00220309968, + "99.9" : 78125.00220309968, + "99.99" : 78125.00220309968, + "99.999" : 78125.00220309968, + "99.9999" : 78125.00220309968, + "100.0" : 78125.00220309968 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76048.4734445912, + 76057.06375275661, + 76050.34944947324 + ], + [ + 77940.23147060264, + 77825.01112692182, + 78125.00220309968 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.94202980014825, + "scoreError" : 21.972459091390952, + "scoreConfidence" : [ + 334.9695707087573, + 378.9144888915392 + ], + "scorePercentiles" : { + "0.0" : 348.3530476873264, + "50.0" : 357.2129490947517, + "90.0" : 364.5935261315126, + "95.0" : 364.5935261315126, + "99.0" : 364.5935261315126, + "99.9" : 364.5935261315126, + "99.99" : 364.5935261315126, + "99.999" : 364.5935261315126, + "99.9999" : 364.5935261315126, + "100.0" : 364.5935261315126 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 348.3530476873264, + 350.1778494651143, + 350.98790579913714 + ], + [ + 363.43799239036633, + 364.1018573274324, + 364.5935261315126 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.50140773119368, + "scoreError" : 4.338509547319294, + "scoreConfidence" : [ + 109.16289818387439, + 117.83991727851297 + ], + "scorePercentiles" : { + "0.0" : 111.34964722185775, + "50.0" : 113.63132500961723, + "90.0" : 115.2533591323223, + "95.0" : 115.2533591323223, + "99.0" : 115.2533591323223, + "99.9" : 115.2533591323223, + "99.99" : 115.2533591323223, + "99.999" : 115.2533591323223, + "99.9999" : 115.2533591323223, + "100.0" : 115.2533591323223 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.74883282989792, + 114.48360196416938, + 115.2533591323223 + ], + [ + 111.34964722185775, + 112.3939571838496, + 112.77904805506509 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06212820909531347, + "scoreError" : 3.318097579313472E-4, + "scoreConfidence" : [ + 0.061796399337382124, + 0.062460018853244814 + ], + "scorePercentiles" : { + "0.0" : 0.06198472309275283, + "50.0" : 0.062100782046607295, + "90.0" : 0.0623046943191447, + "95.0" : 0.0623046943191447, + "99.0" : 0.0623046943191447, + "99.9" : 0.0623046943191447, + "99.99" : 0.0623046943191447, + "99.999" : 0.0623046943191447, + "99.9999" : 0.0623046943191447, + "100.0" : 0.0623046943191447 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062223889217979986, + 0.0623046943191447, + 0.06213365500851217 + ], + [ + 0.06198472309275283, + 0.06206790908470242, + 0.062054383848788724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8807399822264583E-4, + "scoreError" : 3.2063021521749736E-5, + "scoreConfidence" : [ + 3.560109767008961E-4, + 4.201370197443956E-4 + ], + "scorePercentiles" : { + "0.0" : 3.76835829749135E-4, + "50.0" : 3.87822918252944E-4, + "90.0" : 3.993693133005046E-4, + "95.0" : 3.993693133005046E-4, + "99.0" : 3.993693133005046E-4, + "99.9" : 3.993693133005046E-4, + "99.99" : 3.993693133005046E-4, + "99.999" : 3.993693133005046E-4, + "99.9999" : 3.993693133005046E-4, + "100.0" : 3.993693133005046E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7830526666293913E-4, + 3.76835829749135E-4, + 3.7784655983883635E-4 + ], + [ + 3.973405698429489E-4, + 3.993693133005046E-4, + 3.987464499415107E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1020710582835004, + "scoreError" : 2.827373090958066E-4, + "scoreConfidence" : [ + 0.10178832097440459, + 0.1023537955925962 + ], + "scorePercentiles" : { + "0.0" : 0.10195060061780628, + "50.0" : 0.1020752703567501, + "90.0" : 0.10220569794775357, + "95.0" : 0.10220569794775357, + "99.0" : 0.10220569794775357, + "99.9" : 0.10220569794775357, + "99.99" : 0.10220569794775357, + "99.999" : 0.10220569794775357, + "99.9999" : 0.10220569794775357, + "100.0" : 0.10220569794775357 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10210032208563903, + 0.10196852419165707, + 0.10220569794775357 + ], + [ + 0.1021509862302852, + 0.10205021862786118, + 0.10195060061780628 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012876698380756146, + "scoreError" : 4.288452609247336E-4, + "scoreConfidence" : [ + 0.012447853119831412, + 0.01330554364168088 + ], + "scorePercentiles" : { + "0.0" : 0.012731721089821122, + "50.0" : 0.012875197276563933, + "90.0" : 0.013023269628724765, + "95.0" : 0.013023269628724765, + "99.0" : 0.013023269628724765, + "99.9" : 0.013023269628724765, + "99.99" : 0.013023269628724765, + "99.999" : 0.013023269628724765, + "99.9999" : 0.013023269628724765, + "100.0" : 0.013023269628724765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013023269628724765, + 0.013008591062176335, + 0.013016764649069257 + ], + [ + 0.012731721089821122, + 0.01273804036379385, + 0.012741803490951532 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0245459669121153, + "scoreError" : 0.048649310600998, + "scoreConfidence" : [ + 0.9758966563111173, + 1.0731952775131133 + ], + "scorePercentiles" : { + "0.0" : 1.0086042168431668, + "50.0" : 1.0230384311861536, + "90.0" : 1.0457039351735675, + "95.0" : 1.0457039351735675, + "99.0" : 1.0457039351735675, + "99.9" : 1.0457039351735675, + "99.99" : 1.0457039351735675, + "99.999" : 1.0457039351735675, + "99.9999" : 1.0457039351735675, + "100.0" : 1.0457039351735675 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0086042168431668, + 1.0096132381625442, + 1.008686192253379 + ], + [ + 1.0364636242097627, + 1.0457039351735675, + 1.038204594830271 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011292868346502456, + "scoreError" : 6.926357956585544E-4, + "scoreConfidence" : [ + 0.010600232550843901, + 0.011985504142161011 + ], + "scorePercentiles" : { + "0.0" : 0.011064454028456993, + "50.0" : 0.011291916264649218, + "90.0" : 0.011523494943628603, + "95.0" : 0.011523494943628603, + "99.0" : 0.011523494943628603, + "99.9" : 0.011523494943628603, + "99.99" : 0.011523494943628603, + "99.999" : 0.011523494943628603, + "99.9999" : 0.011523494943628603, + "100.0" : 0.011523494943628603 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011072578049812104, + 0.011064454028456993, + 0.011065267172852729 + ], + [ + 0.011520161404777978, + 0.011523494943628603, + 0.011511254479486335 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.351669076554213, + "scoreError" : 0.24194605910437733, + "scoreConfidence" : [ + 3.1097230174498356, + 3.5936151356585904 + ], + "scorePercentiles" : { + "0.0" : 3.270666040549379, + "50.0" : 3.337274007152349, + "90.0" : 3.4503669055172415, + "95.0" : 3.4503669055172415, + "99.0" : 3.4503669055172415, + "99.9" : 3.4503669055172415, + "99.99" : 3.4503669055172415, + "99.999" : 3.4503669055172415, + "99.9999" : 3.4503669055172415, + "100.0" : 3.4503669055172415 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.44044342434663, + 3.4503669055172415, + 3.394673246435845 + ], + [ + 3.270666040549379, + 3.2798747678688525, + 3.27399007460733 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8743357161158207, + "scoreError" : 0.0839359983240515, + "scoreConfidence" : [ + 2.7903997177917694, + 2.958271714439872 + ], + "scorePercentiles" : { + "0.0" : 2.8410853928977273, + "50.0" : 2.8755319907158965, + "90.0" : 2.9123876371578334, + "95.0" : 2.9123876371578334, + "99.0" : 2.9123876371578334, + "99.9" : 2.9123876371578334, + "99.99" : 2.9123876371578334, + "99.999" : 2.9123876371578334, + "99.9999" : 2.9123876371578334, + "100.0" : 2.9123876371578334 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8410853928977273, + 2.843821853284049, + 2.860558034610984 + ], + [ + 2.8905059468208094, + 2.9123876371578334, + 2.8976554319235226 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18282321170451432, + "scoreError" : 0.008593276045994714, + "scoreConfidence" : [ + 0.1742299356585196, + 0.19141648775050904 + ], + "scorePercentiles" : { + "0.0" : 0.17948118482689304, + "50.0" : 0.1829765233969919, + "90.0" : 0.18574667394776923, + "95.0" : 0.18574667394776923, + "99.0" : 0.18574667394776923, + "99.9" : 0.18574667394776923, + "99.99" : 0.18574667394776923, + "99.999" : 0.18574667394776923, + "99.9999" : 0.18574667394776923, + "100.0" : 0.18574667394776923 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18574667394776923, + 0.1854646528004451, + 0.1855997972383586 + ], + [ + 0.18015856742008104, + 0.18048839399353872, + 0.17948118482689304 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3126876084849364, + "scoreError" : 0.026803395973569934, + "scoreConfidence" : [ + 0.2858842125113664, + 0.33949100445850633 + ], + "scorePercentiles" : { + "0.0" : 0.30367397646594396, + "50.0" : 0.31226506203567717, + "90.0" : 0.32340690065325656, + "95.0" : 0.32340690065325656, + "99.0" : 0.32340690065325656, + "99.9" : 0.32340690065325656, + "99.99" : 0.32340690065325656, + "99.999" : 0.32340690065325656, + "99.9999" : 0.32340690065325656, + "100.0" : 0.32340690065325656 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3042344764831153, + 0.30367397646594396, + 0.3041655567248616 + ], + [ + 0.32340690065325656, + 0.3202956475882391, + 0.3203490929942019 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14161281355510572, + "scoreError" : 0.011112042472218722, + "scoreConfidence" : [ + 0.130500771082887, + 0.15272485602732444 + ], + "scorePercentiles" : { + "0.0" : 0.13806423673238347, + "50.0" : 0.14019122286007996, + "90.0" : 0.14757952985449072, + "95.0" : 0.14757952985449072, + "99.0" : 0.14757952985449072, + "99.9" : 0.14757952985449072, + "99.99" : 0.14757952985449072, + "99.999" : 0.14757952985449072, + "99.9999" : 0.14757952985449072, + "100.0" : 0.14757952985449072 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13806423673238347, + 0.13868429644422256, + 0.1385355396411997 + ], + [ + 0.14757952985449072, + 0.14511512938240073, + 0.14169814927593732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3969469360522522, + "scoreError" : 0.015809864974863672, + "scoreConfidence" : [ + 0.3811370710773885, + 0.41275680102711587 + ], + "scorePercentiles" : { + "0.0" : 0.39084212037362726, + "50.0" : 0.39715000882084267, + "90.0" : 0.40212955786553, + "95.0" : 0.40212955786553, + "99.0" : 0.40212955786553, + "99.9" : 0.40212955786553, + "99.99" : 0.40212955786553, + "99.999" : 0.40212955786553, + "99.9999" : 0.40212955786553, + "100.0" : 0.40212955786553 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40212955786553, + 0.4019619879818321, + 0.40211811343439624 + ], + [ + 0.392291806998274, + 0.39233802965985326, + 0.39084212037362726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15805057070175219, + "scoreError" : 0.0018526366231976913, + "scoreConfidence" : [ + 0.1561979340785545, + 0.15990320732494986 + ], + "scorePercentiles" : { + "0.0" : 0.157346220250177, + "50.0" : 0.15789600243461305, + "90.0" : 0.15925193231945217, + "95.0" : 0.15925193231945217, + "99.0" : 0.15925193231945217, + "99.9" : 0.15925193231945217, + "99.99" : 0.15925193231945217, + "99.999" : 0.15925193231945217, + "99.9999" : 0.15925193231945217, + "100.0" : 0.15925193231945217 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1580120173808621, + 0.15823111662974684, + 0.15777998748836403 + ], + [ + 0.15925193231945217, + 0.15768215014191106, + 0.157346220250177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04766036399767399, + "scoreError" : 0.0016132330914923442, + "scoreConfidence" : [ + 0.04604713090618164, + 0.049273597089166336 + ], + "scorePercentiles" : { + "0.0" : 0.04706348164550409, + "50.0" : 0.04767556046906954, + "90.0" : 0.04835791123576489, + "95.0" : 0.04835791123576489, + "99.0" : 0.04835791123576489, + "99.9" : 0.04835791123576489, + "99.99" : 0.04835791123576489, + "99.999" : 0.04835791123576489, + "99.9999" : 0.04835791123576489, + "100.0" : 0.04835791123576489 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047278492331549384, + 0.04710107312788195, + 0.04706348164550409 + ], + [ + 0.04807262860658969, + 0.04808859703875395, + 0.04835791123576489 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8895570.16801502, + "scoreError" : 959801.5388019746, + "scoreConfidence" : [ + 7935768.629213045, + 9855371.706816994 + ], + "scorePercentiles" : { + "0.0" : 8550969.638461538, + "50.0" : 8902102.206025003, + "90.0" : 9216937.69953917, + "95.0" : 9216937.69953917, + "99.0" : 9216937.69953917, + "99.9" : 9216937.69953917, + "99.99" : 9216937.69953917, + "99.999" : 9216937.69953917, + "99.9999" : 9216937.69953917, + "100.0" : 9216937.69953917 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8594540.370274914, + 8550969.638461538, + 8605299.622527946 + ], + [ + 9206768.88776449, + 9216937.69953917, + 9198904.78952206 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-15T05:33:06Z-397c0502311d65d01eff00427ad686b0cb760d1f-jdk17.json b/performance-results/2025-05-15T05:33:06Z-397c0502311d65d01eff00427ad686b0cb760d1f-jdk17.json new file mode 100644 index 0000000000..0437c76d74 --- /dev/null +++ b/performance-results/2025-05-15T05:33:06Z-397c0502311d65d01eff00427ad686b0cb760d1f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3576310671127927, + "scoreError" : 0.0415843019176757, + "scoreConfidence" : [ + 3.316046765195117, + 3.3992153690304683 + ], + "scorePercentiles" : { + "0.0" : 3.352924776868835, + "50.0" : 3.355520383353268, + "90.0" : 3.366558724875801, + "95.0" : 3.366558724875801, + "99.0" : 3.366558724875801, + "99.9" : 3.366558724875801, + "99.99" : 3.366558724875801, + "99.999" : 3.366558724875801, + "99.9999" : 3.366558724875801, + "100.0" : 3.366558724875801 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3529248264663556, + 3.366558724875801 + ], + [ + 3.352924776868835, + 3.3581159402401806 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6869758484194564, + "scoreError" : 0.05887312740784853, + "scoreConfidence" : [ + 1.628102721011608, + 1.7458489758273048 + ], + "scorePercentiles" : { + "0.0" : 1.6789235655274242, + "50.0" : 1.6863198084235946, + "90.0" : 1.6963402113032116, + "95.0" : 1.6963402113032116, + "99.0" : 1.6963402113032116, + "99.9" : 1.6963402113032116, + "99.99" : 1.6963402113032116, + "99.999" : 1.6963402113032116, + "99.9999" : 1.6963402113032116, + "100.0" : 1.6963402113032116 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6789235655274242, + 1.679405250208656 + ], + [ + 1.6963402113032116, + 1.6932343666385332 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8484962994249471, + "scoreError" : 0.0173525274587443, + "scoreConfidence" : [ + 0.8311437719662028, + 0.8658488268836914 + ], + "scorePercentiles" : { + "0.0" : 0.8456034309121245, + "50.0" : 0.8483122837075049, + "90.0" : 0.8517571993726539, + "95.0" : 0.8517571993726539, + "99.0" : 0.8517571993726539, + "99.9" : 0.8517571993726539, + "99.99" : 0.8517571993726539, + "99.999" : 0.8517571993726539, + "99.9999" : 0.8517571993726539, + "100.0" : 0.8517571993726539 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8456034309121245, + 0.8471802510508805 + ], + [ + 0.8494443163641293, + 0.8517571993726539 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.162875942385373, + "scoreError" : 0.12017514291829039, + "scoreConfidence" : [ + 16.04270079946708, + 16.283051085303665 + ], + "scorePercentiles" : { + "0.0" : 16.103487940169302, + "50.0" : 16.156871631066572, + "90.0" : 16.218051256756606, + "95.0" : 16.218051256756606, + "99.0" : 16.218051256756606, + "99.9" : 16.218051256756606, + "99.99" : 16.218051256756606, + "99.999" : 16.218051256756606, + "99.9999" : 16.218051256756606, + "100.0" : 16.218051256756606 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.103487940169302, + 16.218051256756606, + 16.201746061933097 + ], + [ + 16.17293104757061, + 16.140812214562533, + 16.140227133320085 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2660.167998901377, + "scoreError" : 271.93438150159545, + "scoreConfidence" : [ + 2388.2336173997815, + 2932.1023804029724 + ], + "scorePercentiles" : { + "0.0" : 2541.3364723384466, + "50.0" : 2668.160664662356, + "90.0" : 2750.2637248650417, + "95.0" : 2750.2637248650417, + "99.0" : 2750.2637248650417, + "99.9" : 2750.2637248650417, + "99.99" : 2750.2637248650417, + "99.999" : 2750.2637248650417, + "99.9999" : 2750.2637248650417, + "100.0" : 2750.2637248650417 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2750.2637248650417, + 2743.064737291189, + 2748.2491888664035 + ], + [ + 2593.2565920335223, + 2541.3364723384466, + 2584.837278013655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76506.69845297885, + "scoreError" : 2766.9181687214473, + "scoreConfidence" : [ + 73739.7802842574, + 79273.61662170029 + ], + "scorePercentiles" : { + "0.0" : 75405.31480946892, + "50.0" : 76525.0593393334, + "90.0" : 77498.30489470302, + "95.0" : 77498.30489470302, + "99.0" : 77498.30489470302, + "99.9" : 77498.30489470302, + "99.99" : 77498.30489470302, + "99.999" : 77498.30489470302, + "99.9999" : 77498.30489470302, + "100.0" : 77498.30489470302 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77249.91068356884, + 77442.52836731783, + 77498.30489470302 + ], + [ + 75800.20799509795, + 75643.92396771653, + 75405.31480946892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 354.7352574794391, + "scoreError" : 10.603132736480525, + "scoreConfidence" : [ + 344.1321247429586, + 365.3383902159196 + ], + "scorePercentiles" : { + "0.0" : 348.537146936998, + "50.0" : 354.7675971787069, + "90.0" : 359.6472243233259, + "95.0" : 359.6472243233259, + "99.0" : 359.6472243233259, + "99.9" : 359.6472243233259, + "99.99" : 359.6472243233259, + "99.999" : 359.6472243233259, + "99.9999" : 359.6472243233259, + "100.0" : 359.6472243233259 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.00698218738137, + 348.537146936998, + 357.22181496852437 + ], + [ + 353.47016429037257, + 355.5282121700325, + 359.6472243233259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.72517238154826, + "scoreError" : 2.8658123465032697, + "scoreConfidence" : [ + 114.85936003504499, + 120.59098472805154 + ], + "scorePercentiles" : { + "0.0" : 116.91119632460001, + "50.0" : 117.20478092604213, + "90.0" : 119.30623538036792, + "95.0" : 119.30623538036792, + "99.0" : 119.30623538036792, + "99.9" : 119.30623538036792, + "99.99" : 119.30623538036792, + "99.999" : 119.30623538036792, + "99.9999" : 119.30623538036792, + "100.0" : 119.30623538036792 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.3196170096426, + 119.30623538036792, + 118.71478543483884 + ], + [ + 117.08994484244168, + 117.00925529739848, + 116.91119632460001 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061822297005635775, + "scoreError" : 0.0019075267653216393, + "scoreConfidence" : [ + 0.059914770240314136, + 0.06372982377095741 + ], + "scorePercentiles" : { + "0.0" : 0.06108622431202468, + "50.0" : 0.06171337632035827, + "90.0" : 0.06290883672403814, + "95.0" : 0.06290883672403814, + "99.0" : 0.06290883672403814, + "99.9" : 0.06290883672403814, + "99.99" : 0.06290883672403814, + "99.999" : 0.06290883672403814, + "99.9999" : 0.06290883672403814, + "100.0" : 0.06290883672403814 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062248457164377, + 0.06290883672403814, + 0.06190533423507636 + ], + [ + 0.06108622431202468, + 0.061263511192658306, + 0.06152141840564018 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8376115104972285E-4, + "scoreError" : 1.1427849771660066E-5, + "scoreConfidence" : [ + 3.723333012780628E-4, + 3.951890008213829E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7898194232727597E-4, + "50.0" : 3.8442046429865064E-4, + "90.0" : 3.877544257638569E-4, + "95.0" : 3.877544257638569E-4, + "99.0" : 3.877544257638569E-4, + "99.9" : 3.877544257638569E-4, + "99.99" : 3.877544257638569E-4, + "99.999" : 3.877544257638569E-4, + "99.9999" : 3.877544257638569E-4, + "100.0" : 3.877544257638569E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8672475016956993E-4, + 3.875334787626185E-4, + 3.877544257638569E-4 + ], + [ + 3.794561308472842E-4, + 3.821161784277313E-4, + 3.7898194232727597E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10580525988515939, + "scoreError" : 0.010719114943689476, + "scoreConfidence" : [ + 0.09508614494146991, + 0.11652437482884886 + ], + "scorePercentiles" : { + "0.0" : 0.10202988230012651, + "50.0" : 0.10576612512381728, + "90.0" : 0.1096183773731749, + "95.0" : 0.1096183773731749, + "99.0" : 0.1096183773731749, + "99.9" : 0.1096183773731749, + "99.99" : 0.1096183773731749, + "99.999" : 0.1096183773731749, + "99.9999" : 0.1096183773731749, + "100.0" : 0.1096183773731749 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.10253038448130908, + 0.10241071968703916, + 0.10202988230012651 + ], + [ + 0.10924032970298111, + 0.10900186576632549, + 0.1096183773731749 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012883102219746435, + "scoreError" : 1.086865344011196E-4, + "scoreConfidence" : [ + 0.012774415685345316, + 0.012991788754147554 + ], + "scorePercentiles" : { + "0.0" : 0.012841585523113886, + "50.0" : 0.012874251483095196, + "90.0" : 0.012943166010887658, + "95.0" : 0.012943166010887658, + "99.0" : 0.012943166010887658, + "99.9" : 0.012943166010887658, + "99.99" : 0.012943166010887658, + "99.999" : 0.012943166010887658, + "99.9999" : 0.012943166010887658, + "100.0" : 0.012943166010887658 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012943166010887658, + 0.012875831319576956, + 0.012872671646613435 + ], + [ + 0.012850915788959654, + 0.012841585523113886, + 0.012914443029327025 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9854996139058468, + "scoreError" : 0.01478742843482547, + "scoreConfidence" : [ + 0.9707121854710213, + 1.0002870423406722 + ], + "scorePercentiles" : { + "0.0" : 0.9776837813080458, + "50.0" : 0.9870169350998195, + "90.0" : 0.9915657243704145, + "95.0" : 0.9915657243704145, + "99.0" : 0.9915657243704145, + "99.9" : 0.9915657243704145, + "99.99" : 0.9915657243704145, + "99.999" : 0.9915657243704145, + "99.9999" : 0.9915657243704145, + "100.0" : 0.9915657243704145 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9776837813080458, + 0.9889259861564323, + 0.9807883214005493 + ], + [ + 0.9858735241522082, + 0.9881603460474309, + 0.9915657243704145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01101034730368723, + "scoreError" : 4.29639234261356E-4, + "scoreConfidence" : [ + 0.010580708069425874, + 0.011439986537948586 + ], + "scorePercentiles" : { + "0.0" : 0.010761404310040548, + "50.0" : 0.011083609726920362, + "90.0" : 0.01113375885886822, + "95.0" : 0.01113375885886822, + "99.0" : 0.01113375885886822, + "99.9" : 0.01113375885886822, + "99.99" : 0.01113375885886822, + "99.999" : 0.01113375885886822, + "99.9999" : 0.01113375885886822, + "100.0" : 0.01113375885886822 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011120535529212909, + 0.01113375885886822, + 0.011077128610482195 + ], + [ + 0.010879165670160965, + 0.010761404310040548, + 0.01109009084335853 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.345838720085373, + "scoreError" : 0.105625257319342, + "scoreConfidence" : [ + 3.240213462766031, + 3.4514639774047153 + ], + "scorePercentiles" : { + "0.0" : 3.278457878112713, + "50.0" : 3.352372825858927, + "90.0" : 3.3933336635006786, + "95.0" : 3.3933336635006786, + "99.0" : 3.3933336635006786, + "99.9" : 3.3933336635006786, + "99.99" : 3.3933336635006786, + "99.999" : 3.3933336635006786, + "99.9999" : 3.3933336635006786, + "100.0" : 3.3933336635006786 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3398369586114818, + 3.354854007377599, + 3.3586581685695096 + ], + [ + 3.3498916443402544, + 3.3933336635006786, + 3.278457878112713 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.799416641417924, + "scoreError" : 0.05761662646448499, + "scoreConfidence" : [ + 2.741800014953439, + 2.857033267882409 + ], + "scorePercentiles" : { + "0.0" : 2.767933941599779, + "50.0" : 2.8004025858936226, + "90.0" : 2.8272792108535896, + "95.0" : 2.8272792108535896, + "99.0" : 2.8272792108535896, + "99.9" : 2.8272792108535896, + "99.99" : 2.8272792108535896, + "99.999" : 2.8272792108535896, + "99.9999" : 2.8272792108535896, + "100.0" : 2.8272792108535896 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.767933941599779, + 2.787698459587514, + 2.8039675901317636 + ], + [ + 2.812783064679415, + 2.796837581655481, + 2.8272792108535896 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.180852914552783, + "scoreError" : 0.012798413822687834, + "scoreConfidence" : [ + 0.16805450073009515, + 0.19365132837547083 + ], + "scorePercentiles" : { + "0.0" : 0.17619229721444052, + "50.0" : 0.18067314763750955, + "90.0" : 0.18551996150563965, + "95.0" : 0.18551996150563965, + "99.0" : 0.18551996150563965, + "99.9" : 0.18551996150563965, + "99.99" : 0.18551996150563965, + "99.999" : 0.18551996150563965, + "99.9999" : 0.18551996150563965, + "100.0" : 0.18551996150563965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18520264418393614, + 0.18425725998194314, + 0.18551996150563965 + ], + [ + 0.17685628913766271, + 0.17708903529307596, + 0.17619229721444052 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32733455267693395, + "scoreError" : 0.008499350373305967, + "scoreConfidence" : [ + 0.318835202303628, + 0.3358339030502399 + ], + "scorePercentiles" : { + "0.0" : 0.32502584334373374, + "50.0" : 0.3263787826415744, + "90.0" : 0.3330953996402638, + "95.0" : 0.3330953996402638, + "99.0" : 0.3330953996402638, + "99.9" : 0.3330953996402638, + "99.99" : 0.3330953996402638, + "99.999" : 0.3330953996402638, + "99.9999" : 0.3330953996402638, + "100.0" : 0.3330953996402638 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3330953996402638, + 0.32502584334373374, + 0.326137314678929 + ], + [ + 0.32802806278291674, + 0.32510044501154056, + 0.32662025060421973 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.144662571972952, + "scoreError" : 0.003921182810745997, + "scoreConfidence" : [ + 0.140741389162206, + 0.14858375478369798 + ], + "scorePercentiles" : { + "0.0" : 0.1419665936457461, + "50.0" : 0.14495787474025662, + "90.0" : 0.1460983882306535, + "95.0" : 0.1460983882306535, + "99.0" : 0.1460983882306535, + "99.9" : 0.1460983882306535, + "99.99" : 0.1460983882306535, + "99.999" : 0.1460983882306535, + "99.9999" : 0.1460983882306535, + "100.0" : 0.1460983882306535 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1460983882306535, + 0.14514985444728287, + 0.14498713946036856 + ], + [ + 0.14492861002014465, + 0.1419665936457461, + 0.14484484603351633 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4071434480112923, + "scoreError" : 0.006497629960740587, + "scoreConfidence" : [ + 0.4006458180505517, + 0.4136410779720329 + ], + "scorePercentiles" : { + "0.0" : 0.4049782277071353, + "50.0" : 0.40629956871338696, + "90.0" : 0.41040625395001434, + "95.0" : 0.41040625395001434, + "99.0" : 0.41040625395001434, + "99.9" : 0.41040625395001434, + "99.99" : 0.41040625395001434, + "99.999" : 0.41040625395001434, + "99.9999" : 0.41040625395001434, + "100.0" : 0.41040625395001434 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4058837990096599, + 0.4052514200672691, + 0.4049782277071353 + ], + [ + 0.40671533841711405, + 0.40962564891656084, + 0.41040625395001434 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16152343348339, + "scoreError" : 0.00777651056117432, + "scoreConfidence" : [ + 0.15374692292221567, + 0.1692999440445643 + ], + "scorePercentiles" : { + "0.0" : 0.1587053428766406, + "50.0" : 0.1615866547872588, + "90.0" : 0.16416808761532653, + "95.0" : 0.16416808761532653, + "99.0" : 0.16416808761532653, + "99.9" : 0.16416808761532653, + "99.99" : 0.16416808761532653, + "99.999" : 0.16416808761532653, + "99.9999" : 0.16416808761532653, + "100.0" : 0.16416808761532653 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15933769790637647, + 0.1587053428766406, + 0.15895926208453212 + ], + [ + 0.16383561166814115, + 0.16413459874932296, + 0.16416808761532653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047829370874426104, + "scoreError" : 0.0019315818173346485, + "scoreConfidence" : [ + 0.04589778905709146, + 0.04976095269176075 + ], + "scorePercentiles" : { + "0.0" : 0.04717973539222208, + "50.0" : 0.0477591693389282, + "90.0" : 0.04867519937988873, + "95.0" : 0.04867519937988873, + "99.0" : 0.04867519937988873, + "99.9" : 0.04867519937988873, + "99.99" : 0.04867519937988873, + "99.999" : 0.04867519937988873, + "99.9999" : 0.04867519937988873, + "100.0" : 0.04867519937988873 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04719124506505212, + 0.047269914069627286, + 0.04717973539222208 + ], + [ + 0.04867519937988873, + 0.04824842460822912, + 0.04841170673153729 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8633026.465523541, + "scoreError" : 252320.6805427409, + "scoreConfidence" : [ + 8380705.7849808, + 8885347.146066282 + ], + "scorePercentiles" : { + "0.0" : 8538413.633105801, + "50.0" : 8599622.056032673, + "90.0" : 8780030.765789473, + "95.0" : 8780030.765789473, + "99.0" : 8780030.765789473, + "99.9" : 8780030.765789473, + "99.99" : 8780030.765789473, + "99.999" : 8780030.765789473, + "99.9999" : 8780030.765789473, + "100.0" : 8780030.765789473 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8579003.468267582, + 8538413.633105801, + 8606174.22203098 + ], + [ + 8780030.765789473, + 8701466.813913044, + 8593069.890034365 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-15T06:54:22Z-abb2cddba09331511de89f1ea7215a576c2ec53e-jdk17.json b/performance-results/2025-05-15T06:54:22Z-abb2cddba09331511de89f1ea7215a576c2ec53e-jdk17.json new file mode 100644 index 0000000000..924abe6b17 --- /dev/null +++ b/performance-results/2025-05-15T06:54:22Z-abb2cddba09331511de89f1ea7215a576c2ec53e-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.37195428995437, + "scoreError" : 0.03656795654922715, + "scoreConfidence" : [ + 3.335386333405143, + 3.408522246503597 + ], + "scorePercentiles" : { + "0.0" : 3.364809599446622, + "50.0" : 3.3727481981213208, + "90.0" : 3.3775111641282174, + "95.0" : 3.3775111641282174, + "99.0" : 3.3775111641282174, + "99.9" : 3.3775111641282174, + "99.99" : 3.3775111641282174, + "99.999" : 3.3775111641282174, + "99.9999" : 3.3775111641282174, + "100.0" : 3.3775111641282174 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.364809599446622, + 3.3752863561549433 + ], + [ + 3.3702100400876986, + 3.3775111641282174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7053908831308398, + "scoreError" : 0.03334444870194397, + "scoreConfidence" : [ + 1.672046434428896, + 1.7387353318327836 + ], + "scorePercentiles" : { + "0.0" : 1.6986567178951304, + "50.0" : 1.706226771460252, + "90.0" : 1.710453271707724, + "95.0" : 1.710453271707724, + "99.0" : 1.710453271707724, + "99.9" : 1.710453271707724, + "99.99" : 1.710453271707724, + "99.999" : 1.710453271707724, + "99.9999" : 1.710453271707724, + "100.0" : 1.710453271707724 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.710453271707724, + 1.7081639626013112 + ], + [ + 1.6986567178951304, + 1.7042895803191926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8583783088895638, + "scoreError" : 0.020219181369093637, + "scoreConfidence" : [ + 0.8381591275204702, + 0.8785974902586574 + ], + "scorePercentiles" : { + "0.0" : 0.8560231000108657, + "50.0" : 0.8573746604752659, + "90.0" : 0.8627408145968576, + "95.0" : 0.8627408145968576, + "99.0" : 0.8627408145968576, + "99.9" : 0.8627408145968576, + "99.99" : 0.8627408145968576, + "99.999" : 0.8627408145968576, + "99.9999" : 0.8627408145968576, + "100.0" : 0.8627408145968576 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8561961604774199, + 0.8627408145968576 + ], + [ + 0.8560231000108657, + 0.8585531604731119 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.270301891645246, + "scoreError" : 0.7391113944523202, + "scoreConfidence" : [ + 15.531190497192926, + 17.009413286097566 + ], + "scorePercentiles" : { + "0.0" : 15.990303431040326, + "50.0" : 16.291431187657636, + "90.0" : 16.519720237571345, + "95.0" : 16.519720237571345, + "99.0" : 16.519720237571345, + "99.9" : 16.519720237571345, + "99.99" : 16.519720237571345, + "99.999" : 16.519720237571345, + "99.9999" : 16.519720237571345, + "100.0" : 16.519720237571345 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.082491978464134, + 15.990303431040326, + 16.02107409003847 + ], + [ + 16.519720237571345, + 16.507851215906058, + 16.50037039685114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2845.3293027242885, + "scoreError" : 135.5364996353283, + "scoreConfidence" : [ + 2709.79280308896, + 2980.8658023596167 + ], + "scorePercentiles" : { + "0.0" : 2800.917356607162, + "50.0" : 2844.5395485450726, + "90.0" : 2892.636092844852, + "95.0" : 2892.636092844852, + "99.0" : 2892.636092844852, + "99.9" : 2892.636092844852, + "99.99" : 2892.636092844852, + "99.999" : 2892.636092844852, + "99.9999" : 2892.636092844852, + "100.0" : 2892.636092844852 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2892.636092844852, + 2888.214890071085, + 2887.4126101472834 + ], + [ + 2800.917356607162, + 2801.1283797324877, + 2801.6664869428614 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 78522.44985647289, + "scoreError" : 1288.6811817338073, + "scoreConfidence" : [ + 77233.76867473908, + 79811.13103820669 + ], + "scorePercentiles" : { + "0.0" : 78080.3588921106, + "50.0" : 78511.0817151787, + "90.0" : 79006.8170050835, + "95.0" : 79006.8170050835, + "99.0" : 79006.8170050835, + "99.9" : 79006.8170050835, + "99.99" : 79006.8170050835, + "99.999" : 79006.8170050835, + "99.9999" : 79006.8170050835, + "100.0" : 79006.8170050835 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78109.12394686391, + 78123.95189174458, + 78080.3588921106 + ], + [ + 79006.8170050835, + 78898.21153861281, + 78916.23586442192 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.55121076179006, + "scoreError" : 11.350139942221542, + "scoreConfidence" : [ + 350.20107081956854, + 372.9013507040116 + ], + "scorePercentiles" : { + "0.0" : 357.2262618551446, + "50.0" : 361.3044979464174, + "90.0" : 365.8454757439234, + "95.0" : 365.8454757439234, + "99.0" : 365.8454757439234, + "99.9" : 365.8454757439234, + "99.99" : 365.8454757439234, + "99.999" : 365.8454757439234, + "99.9999" : 365.8454757439234, + "100.0" : 365.8454757439234 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 364.2136983258551, + 365.52690361123956, + 365.8454757439234 + ], + [ + 357.2262618551446, + 358.09962746759794, + 358.3952975669797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 118.45375967613869, + "scoreError" : 0.9106387601247157, + "scoreConfidence" : [ + 117.54312091601398, + 119.3643984362634 + ], + "scorePercentiles" : { + "0.0" : 117.81232443337488, + "50.0" : 118.57660372937849, + "90.0" : 118.66156583921091, + "95.0" : 118.66156583921091, + "99.0" : 118.66156583921091, + "99.9" : 118.66156583921091, + "99.99" : 118.66156583921091, + "99.999" : 118.66156583921091, + "99.9999" : 118.66156583921091, + "100.0" : 118.66156583921091 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.81232443337488, + 118.43632243883722, + 118.57611855628575 + ], + [ + 118.65913788665209, + 118.57708890247125, + 118.66156583921091 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060960917415130746, + "scoreError" : 0.0013431405636872367, + "scoreConfidence" : [ + 0.05961777685144351, + 0.06230405797881798 + ], + "scorePercentiles" : { + "0.0" : 0.060411443153672355, + "50.0" : 0.060959125434619024, + "90.0" : 0.06145845179271606, + "95.0" : 0.06145845179271606, + "99.0" : 0.06145845179271606, + "99.9" : 0.06145845179271606, + "99.99" : 0.06145845179271606, + "99.999" : 0.06145845179271606, + "99.9999" : 0.06145845179271606, + "100.0" : 0.06145845179271606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06145845179271606, + 0.06128789280307905, + 0.06142451641851551 + ], + [ + 0.060630358066159, + 0.06055284225664253, + 0.060411443153672355 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6345906862424344E-4, + "scoreError" : 2.361115302174571E-5, + "scoreConfidence" : [ + 3.3984791560249774E-4, + 3.8707022164598915E-4 + ], + "scorePercentiles" : { + "0.0" : 3.545454816324163E-4, + "50.0" : 3.6380369544923244E-4, + "90.0" : 3.7192402972402753E-4, + "95.0" : 3.7192402972402753E-4, + "99.0" : 3.7192402972402753E-4, + "99.9" : 3.7192402972402753E-4, + "99.99" : 3.7192402972402753E-4, + "99.999" : 3.7192402972402753E-4, + "99.9999" : 3.7192402972402753E-4, + "100.0" : 3.7192402972402753E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7192402972402753E-4, + 3.7077138996286874E-4, + 3.706087230929873E-4 + ], + [ + 3.545454816324163E-4, + 3.5699866780547756E-4, + 3.5590611952768334E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0991451591398791, + "scoreError" : 0.004161848056231463, + "scoreConfidence" : [ + 0.09498331108364765, + 0.10330700719611056 + ], + "scorePercentiles" : { + "0.0" : 0.0975821024882904, + "50.0" : 0.09916111466065208, + "90.0" : 0.10072151672458075, + "95.0" : 0.10072151672458075, + "99.0" : 0.10072151672458075, + "99.9" : 0.10072151672458075, + "99.99" : 0.10072151672458075, + "99.999" : 0.10072151672458075, + "99.9999" : 0.10072151672458075, + "100.0" : 0.10072151672458075 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0975821024882904, + 0.09785103980508425, + 0.0979672744300871 + ], + [ + 0.10039406650001506, + 0.10035495489121708, + 0.10072151672458075 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013099467608308511, + "scoreError" : 1.4103692724244877E-4, + "scoreConfidence" : [ + 0.012958430681066063, + 0.01324050453555096 + ], + "scorePercentiles" : { + "0.0" : 0.01304987551366891, + "50.0" : 0.013098013276803266, + "90.0" : 0.013148424082055543, + "95.0" : 0.013148424082055543, + "99.0" : 0.013148424082055543, + "99.9" : 0.013148424082055543, + "99.99" : 0.013148424082055543, + "99.999" : 0.013148424082055543, + "99.9999" : 0.013148424082055543, + "100.0" : 0.013148424082055543 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013148424082055543, + 0.013147869971824468, + 0.013139441651764538 + ], + [ + 0.01304987551366891, + 0.013056584901841996, + 0.013054609528695613 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9877065095343959, + "scoreError" : 0.09095707583910845, + "scoreConfidence" : [ + 0.8967494336952875, + 1.0786635853735043 + ], + "scorePercentiles" : { + "0.0" : 0.957401012444955, + "50.0" : 0.9870791514357575, + "90.0" : 1.0187789376528118, + "95.0" : 1.0187789376528118, + "99.0" : 1.0187789376528118, + "99.9" : 1.0187789376528118, + "99.99" : 1.0187789376528118, + "99.999" : 1.0187789376528118, + "99.9999" : 1.0187789376528118, + "100.0" : 1.0187789376528118 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9583194571674971, + 0.9586211597967791, + 0.957401012444955 + ], + [ + 1.015537143074736, + 1.0187789376528118, + 1.0175813470695971 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010834772869580176, + "scoreError" : 6.068451328571229E-4, + "scoreConfidence" : [ + 0.010227927736723054, + 0.0114416180024373 + ], + "scorePercentiles" : { + "0.0" : 0.010633836351494761, + "50.0" : 0.010831742475056574, + "90.0" : 0.011042859869741803, + "95.0" : 0.011042859869741803, + "99.0" : 0.011042859869741803, + "99.9" : 0.011042859869741803, + "99.99" : 0.011042859869741803, + "99.999" : 0.011042859869741803, + "99.9999" : 0.011042859869741803, + "100.0" : 0.011042859869741803 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01064356072562088, + 0.010634678313468263, + 0.010633836351494761 + ], + [ + 0.011033777732663086, + 0.011042859869741803, + 0.011019924224492269 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.296616641413387, + "scoreError" : 0.14155502659447888, + "scoreConfidence" : [ + 3.155061614818908, + 3.438171668007866 + ], + "scorePercentiles" : { + "0.0" : 3.248337700649351, + "50.0" : 3.295346318359713, + "90.0" : 3.3462634153846156, + "95.0" : 3.3462634153846156, + "99.0" : 3.3462634153846156, + "99.9" : 3.3462634153846156, + "99.99" : 3.3462634153846156, + "99.999" : 3.3462634153846156, + "99.9999" : 3.3462634153846156, + "100.0" : 3.3462634153846156 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2494850883690707, + 3.248337700649351, + 3.2541910409889394 + ], + [ + 3.3462634153846156, + 3.3449210073578595, + 3.336501595730487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7186639212584445, + "scoreError" : 0.3119715605849149, + "scoreConfidence" : [ + 2.4066923606735298, + 3.030635481843359 + ], + "scorePercentiles" : { + "0.0" : 2.615954781846717, + "50.0" : 2.7038807754803287, + "90.0" : 2.8478124487471526, + "95.0" : 2.8478124487471526, + "99.0" : 2.8478124487471526, + "99.9" : 2.8478124487471526, + "99.99" : 2.8478124487471526, + "99.999" : 2.8478124487471526, + "99.9999" : 2.8478124487471526, + "100.0" : 2.8478124487471526 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8478124487471526, + 2.8212246930888574, + 2.786988266369462 + ], + [ + 2.615954781846717, + 2.619230052907281, + 2.620773284591195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17605234556528881, + "scoreError" : 0.007570707459614557, + "scoreConfidence" : [ + 0.16848163810567426, + 0.18362305302490337 + ], + "scorePercentiles" : { + "0.0" : 0.1717007991140414, + "50.0" : 0.17661816932751023, + "90.0" : 0.1783451790911685, + "95.0" : 0.1783451790911685, + "99.0" : 0.1783451790911685, + "99.9" : 0.1783451790911685, + "99.99" : 0.1783451790911685, + "99.999" : 0.1783451790911685, + "99.9999" : 0.1783451790911685, + "100.0" : 0.1783451790911685 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1783451790911685, + 0.17821373678582886, + 0.17826079997860925 + ], + [ + 0.17502260186919158, + 0.17477095655289326, + 0.1717007991140414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32113381206472613, + "scoreError" : 0.006139268927095596, + "scoreConfidence" : [ + 0.31499454313763053, + 0.32727308099182173 + ], + "scorePercentiles" : { + "0.0" : 0.3191856957007437, + "50.0" : 0.3205128405748442, + "90.0" : 0.32458446212268743, + "95.0" : 0.32458446212268743, + "99.0" : 0.32458446212268743, + "99.9" : 0.32458446212268743, + "99.99" : 0.32458446212268743, + "99.999" : 0.32458446212268743, + "99.9999" : 0.32458446212268743, + "100.0" : 0.32458446212268743 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32458446212268743, + 0.3216074762180415, + 0.32259441287096774 + ], + [ + 0.31941820493164685, + 0.3191856957007437, + 0.31941262054426983 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.13879002206253346, + "scoreError" : 0.006224974789872499, + "scoreConfidence" : [ + 0.13256504727266097, + 0.14501499685240596 + ], + "scorePercentiles" : { + "0.0" : 0.1370720149130983, + "50.0" : 0.13813471171344857, + "90.0" : 0.1426676694058064, + "95.0" : 0.1426676694058064, + "99.0" : 0.1426676694058064, + "99.9" : 0.1426676694058064, + "99.99" : 0.1426676694058064, + "99.999" : 0.1426676694058064, + "99.9999" : 0.1426676694058064, + "100.0" : 0.1426676694058064 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1426676694058064, + 0.13915643811140643, + 0.13965869467215977 + ], + [ + 0.1370720149130983, + 0.1370723299572392, + 0.1371129853154907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40160948036562716, + "scoreError" : 0.02861953008608887, + "scoreConfidence" : [ + 0.3729899502795383, + 0.430229010451716 + ], + "scorePercentiles" : { + "0.0" : 0.39169938228036505, + "50.0" : 0.4014631203198312, + "90.0" : 0.41176186186025443, + "95.0" : 0.41176186186025443, + "99.0" : 0.41176186186025443, + "99.9" : 0.41176186186025443, + "99.99" : 0.41176186186025443, + "99.999" : 0.41176186186025443, + "99.9999" : 0.41176186186025443, + "100.0" : 0.41176186186025443 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3929859131135301, + 0.3922602360555425, + 0.39169938228036505 + ], + [ + 0.41176186186025443, + 0.4099403275261324, + 0.4110091613579384 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15550992133162486, + "scoreError" : 0.013671170635439368, + "scoreConfidence" : [ + 0.14183875069618548, + 0.16918109196706424 + ], + "scorePercentiles" : { + "0.0" : 0.15103718238936717, + "50.0" : 0.154299127902926, + "90.0" : 0.16184881107676372, + "95.0" : 0.16184881107676372, + "99.0" : 0.16184881107676372, + "99.9" : 0.16184881107676372, + "99.99" : 0.16184881107676372, + "99.999" : 0.16184881107676372, + "99.9999" : 0.16184881107676372, + "100.0" : 0.16184881107676372 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15146836601435884, + 0.15103718238936717, + 0.15134119667963133 + ], + [ + 0.16184881107676372, + 0.1602340820381349, + 0.15712988979149317 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047701765467678764, + "scoreError" : 0.001656950263455347, + "scoreConfidence" : [ + 0.04604481520422342, + 0.04935871573113411 + ], + "scorePercentiles" : { + "0.0" : 0.046794948329675574, + "50.0" : 0.04793205925220363, + "90.0" : 0.048216510132545166, + "95.0" : 0.048216510132545166, + "99.0" : 0.048216510132545166, + "99.9" : 0.048216510132545166, + "99.99" : 0.048216510132545166, + "99.999" : 0.048216510132545166, + "99.9999" : 0.048216510132545166, + "100.0" : 0.048216510132545166 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04812390186717998, + 0.048216510132545166, + 0.04815557443068818 + ], + [ + 0.04774021663722729, + 0.04717944140875637, + 0.046794948329675574 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8632929.072036976, + "scoreError" : 34464.53796412084, + "scoreConfidence" : [ + 8598464.534072855, + 8667393.610001097 + ], + "scorePercentiles" : { + "0.0" : 8618219.789836347, + "50.0" : 8632032.17428818, + "90.0" : 8651978.74567474, + "95.0" : 8651978.74567474, + "99.0" : 8651978.74567474, + "99.9" : 8651978.74567474, + "99.99" : 8651978.74567474, + "99.999" : 8651978.74567474, + "99.9999" : 8651978.74567474, + "100.0" : 8651978.74567474 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8651978.74567474, + 8634976.036238136, + 8622885.630172415 + ], + [ + 8640425.917962003, + 8629088.312338222, + 8618219.789836347 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-15T06:54:24Z-abb2cddba09331511de89f1ea7215a576c2ec53e-jdk17.json b/performance-results/2025-05-15T06:54:24Z-abb2cddba09331511de89f1ea7215a576c2ec53e-jdk17.json new file mode 100644 index 0000000000..4b816ad32f --- /dev/null +++ b/performance-results/2025-05-15T06:54:24Z-abb2cddba09331511de89f1ea7215a576c2ec53e-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3619693022144115, + "scoreError" : 0.0346155048003694, + "scoreConfidence" : [ + 3.327353797414042, + 3.396584807014781 + ], + "scorePercentiles" : { + "0.0" : 3.3560782862736076, + "50.0" : 3.3624626206166175, + "90.0" : 3.366873681350802, + "95.0" : 3.366873681350802, + "99.0" : 3.366873681350802, + "99.9" : 3.366873681350802, + "99.99" : 3.366873681350802, + "99.999" : 3.366873681350802, + "99.9999" : 3.366873681350802, + "100.0" : 3.366873681350802 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3560782862736076, + 3.3661260748119513 + ], + [ + 3.358799166421284, + 3.366873681350802 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7043465364070687, + "scoreError" : 0.01259928411751115, + "scoreConfidence" : [ + 1.6917472522895576, + 1.7169458205245798 + ], + "scorePercentiles" : { + "0.0" : 1.7026592286585995, + "50.0" : 1.7041490966947093, + "90.0" : 1.706428723580257, + "95.0" : 1.706428723580257, + "99.0" : 1.706428723580257, + "99.9" : 1.706428723580257, + "99.99" : 1.706428723580257, + "99.999" : 1.706428723580257, + "99.9999" : 1.706428723580257, + "100.0" : 1.706428723580257 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.702709628658194, + 1.7055885647312243 + ], + [ + 1.7026592286585995, + 1.706428723580257 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8527199659895021, + "scoreError" : 0.012818551607094471, + "scoreConfidence" : [ + 0.8399014143824076, + 0.8655385175965965 + ], + "scorePercentiles" : { + "0.0" : 0.8506495123151063, + "50.0" : 0.8524542751860122, + "90.0" : 0.8553218012708776, + "95.0" : 0.8553218012708776, + "99.0" : 0.8553218012708776, + "99.9" : 0.8553218012708776, + "99.99" : 0.8553218012708776, + "99.999" : 0.8553218012708776, + "99.9999" : 0.8553218012708776, + "100.0" : 0.8553218012708776 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8506495123151063, + 0.8519031351479918 + ], + [ + 0.8530054152240326, + 0.8553218012708776 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.16502511474498, + "scoreError" : 0.10246523625935697, + "scoreConfidence" : [ + 16.062559878485626, + 16.267490351004337 + ], + "scorePercentiles" : { + "0.0" : 16.120308535989917, + "50.0" : 16.1676799465021, + "90.0" : 16.204897696012992, + "95.0" : 16.204897696012992, + "99.0" : 16.204897696012992, + "99.9" : 16.204897696012992, + "99.99" : 16.204897696012992, + "99.999" : 16.204897696012992, + "99.9999" : 16.204897696012992, + "100.0" : 16.204897696012992 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.204897696012992, + 16.20379604919371, + 16.171533737314167 + ], + [ + 16.163826155690035, + 16.120308535989917, + 16.125788514269058 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2727.9219353261765, + "scoreError" : 308.86139876953905, + "scoreConfidence" : [ + 2419.0605365566375, + 3036.7833340957154 + ], + "scorePercentiles" : { + "0.0" : 2625.720920916892, + "50.0" : 2726.712793958962, + "90.0" : 2831.61210236092, + "95.0" : 2831.61210236092, + "99.0" : 2831.61210236092, + "99.9" : 2831.61210236092, + "99.99" : 2831.61210236092, + "99.999" : 2831.61210236092, + "99.9999" : 2831.61210236092, + "100.0" : 2831.61210236092 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2625.720920916892, + 2626.5576145671957, + 2629.9681570868142 + ], + [ + 2830.215386194129, + 2823.45743083111, + 2831.61210236092 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76619.60159904526, + "scoreError" : 1185.3111157436413, + "scoreConfidence" : [ + 75434.29048330162, + 77804.9127147889 + ], + "scorePercentiles" : { + "0.0" : 76212.86159865643, + "50.0" : 76626.37534973578, + "90.0" : 77032.94237558937, + "95.0" : 77032.94237558937, + "99.0" : 77032.94237558937, + "99.9" : 77032.94237558937, + "99.99" : 77032.94237558937, + "99.999" : 77032.94237558937, + "99.9999" : 77032.94237558937, + "100.0" : 77032.94237558937 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76986.91811654503, + 76994.74392469338, + 77032.94237558937 + ], + [ + 76212.86159865643, + 76224.31099586085, + 76265.83258292654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.9604739966983, + "scoreError" : 4.318961573188895, + "scoreConfidence" : [ + 353.64151242350937, + 362.2794355698872 + ], + "scorePercentiles" : { + "0.0" : 355.27336828198554, + "50.0" : 358.4125965204686, + "90.0" : 359.29035165282573, + "95.0" : 359.29035165282573, + "99.0" : 359.29035165282573, + "99.9" : 359.29035165282573, + "99.99" : 359.29035165282573, + "99.999" : 359.29035165282573, + "99.9999" : 359.29035165282573, + "100.0" : 359.29035165282573 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 359.29035165282573, + 358.5699914567, + 359.26184657152504 + ], + [ + 355.27336828198554, + 357.1120844329163, + 358.25520158423717 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.19278461900154, + "scoreError" : 3.693452106666015, + "scoreConfidence" : [ + 112.49933251233553, + 119.88623672566756 + ], + "scorePercentiles" : { + "0.0" : 114.6236954071504, + "50.0" : 116.28043773374716, + "90.0" : 117.48474766011977, + "95.0" : 117.48474766011977, + "99.0" : 117.48474766011977, + "99.9" : 117.48474766011977, + "99.99" : 117.48474766011977, + "99.999" : 117.48474766011977, + "99.9999" : 117.48474766011977, + "100.0" : 117.48474766011977 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.35311290156567, + 117.29548851054362, + 117.48474766011977 + ], + [ + 114.6236954071504, + 115.13427627767912, + 115.26538695695069 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06163297424202521, + "scoreError" : 0.002170615650729767, + "scoreConfidence" : [ + 0.05946235859129544, + 0.06380358989275497 + ], + "scorePercentiles" : { + "0.0" : 0.06086966160644722, + "50.0" : 0.06160315455879634, + "90.0" : 0.06243518140838739, + "95.0" : 0.06243518140838739, + "99.0" : 0.06243518140838739, + "99.9" : 0.06243518140838739, + "99.99" : 0.06243518140838739, + "99.999" : 0.06243518140838739, + "99.9999" : 0.06243518140838739, + "100.0" : 0.06243518140838739 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06220352153142786, + 0.06243518140838739, + 0.0623668127151624 + ], + [ + 0.06100278758616483, + 0.06086966160644722, + 0.060919880604561626 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6996404217497827E-4, + "scoreError" : 3.8890227470509756E-5, + "scoreConfidence" : [ + 3.310738147044685E-4, + 4.08854269645488E-4 + ], + "scorePercentiles" : { + "0.0" : 3.571925648607826E-4, + "50.0" : 3.7000096411347893E-4, + "90.0" : 3.8267256861147645E-4, + "95.0" : 3.8267256861147645E-4, + "99.0" : 3.8267256861147645E-4, + "99.9" : 3.8267256861147645E-4, + "99.99" : 3.8267256861147645E-4, + "99.999" : 3.8267256861147645E-4, + "99.9999" : 3.8267256861147645E-4, + "100.0" : 3.8267256861147645E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.825868129404473E-4, + 3.8261298644305013E-4, + 3.8267256861147645E-4 + ], + [ + 3.571925648607826E-4, + 3.574151152865106E-4, + 3.5730420490760257E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.10073400889652667, + "scoreError" : 0.002989392075828481, + "scoreConfidence" : [ + 0.0977446168206982, + 0.10372340097235515 + ], + "scorePercentiles" : { + "0.0" : 0.09961565138263538, + "50.0" : 0.1007482534611579, + "90.0" : 0.10176195647705302, + "95.0" : 0.10176195647705302, + "99.0" : 0.10176195647705302, + "99.9" : 0.10176195647705302, + "99.99" : 0.10176195647705302, + "99.999" : 0.10176195647705302, + "99.9999" : 0.10176195647705302, + "100.0" : 0.10176195647705302 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1017232468161289, + 0.10162459706513013, + 0.10176195647705302 + ], + [ + 0.09987190985718566, + 0.09961565138263538, + 0.099806691781027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012938159454429027, + "scoreError" : 3.106674172131585E-4, + "scoreConfidence" : [ + 0.012627492037215868, + 0.013248826871642186 + ], + "scorePercentiles" : { + "0.0" : 0.012833961275170369, + "50.0" : 0.012938728767601387, + "90.0" : 0.013044523378749437, + "95.0" : 0.013044523378749437, + "99.0" : 0.013044523378749437, + "99.9" : 0.013044523378749437, + "99.99" : 0.013044523378749437, + "99.999" : 0.013044523378749437, + "99.9999" : 0.013044523378749437, + "100.0" : 0.013044523378749437 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01303669574019852, + 0.013036495524645086, + 0.013044523378749437 + ], + [ + 0.012840962010557688, + 0.012833961275170369, + 0.012836318797253065 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9498497469960206, + "scoreError" : 0.014164299500634742, + "scoreConfidence" : [ + 0.935685447495386, + 0.9640140464966553 + ], + "scorePercentiles" : { + "0.0" : 0.9428600098039216, + "50.0" : 0.9492197338705611, + "90.0" : 0.9564556433626625, + "95.0" : 0.9564556433626625, + "99.0" : 0.9564556433626625, + "99.9" : 0.9564556433626625, + "99.99" : 0.9564556433626625, + "99.999" : 0.9564556433626625, + "99.9999" : 0.9564556433626625, + "100.0" : 0.9564556433626625 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.947116597973293, + 0.9472636086009283, + 0.9428600098039216 + ], + [ + 0.951175859140194, + 0.9542267630951246, + 0.9564556433626625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010973149688501877, + "scoreError" : 0.0014137093168784477, + "scoreConfidence" : [ + 0.009559440371623429, + 0.012386859005380325 + ], + "scorePercentiles" : { + "0.0" : 0.010496211194961953, + "50.0" : 0.010973621890873681, + "90.0" : 0.011449813897736145, + "95.0" : 0.011449813897736145, + "99.0" : 0.011449813897736145, + "99.9" : 0.011449813897736145, + "99.99" : 0.011449813897736145, + "99.999" : 0.011449813897736145, + "99.9999" : 0.011449813897736145, + "100.0" : 0.011449813897736145 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010519976071853869, + 0.01052307094046414, + 0.010496211194961953 + ], + [ + 0.011424172841283223, + 0.01142565318471192, + 0.011449813897736145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1585801498753443, + "scoreError" : 0.08097212523440647, + "scoreConfidence" : [ + 3.077608024640938, + 3.2395522751097507 + ], + "scorePercentiles" : { + "0.0" : 3.129428031289111, + "50.0" : 3.15424663399424, + "90.0" : 3.1915879559668157, + "95.0" : 3.1915879559668157, + "99.0" : 3.1915879559668157, + "99.9" : 3.1915879559668157, + "99.99" : 3.1915879559668157, + "99.999" : 3.1915879559668157, + "99.9999" : 3.1915879559668157, + "100.0" : 3.1915879559668157 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1915879559668157, + 3.169854698352345, + 3.1900825338010206 + ], + [ + 3.1318891102066373, + 3.1386385696361354, + 3.129428031289111 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7190414302712753, + "scoreError" : 0.17550582426468056, + "scoreConfidence" : [ + 2.5435356060065946, + 2.894547254535956 + ], + "scorePercentiles" : { + "0.0" : 2.6598154445626165, + "50.0" : 2.717206667021072, + "90.0" : 2.7806592051709758, + "95.0" : 2.7806592051709758, + "99.0" : 2.7806592051709758, + "99.9" : 2.7806592051709758, + "99.99" : 2.7806592051709758, + "99.999" : 2.7806592051709758, + "99.9999" : 2.7806592051709758, + "100.0" : 2.7806592051709758 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6623827324993345, + 2.6598154445626165, + 2.663785386950732 + ], + [ + 2.7806592051709758, + 2.776977865352582, + 2.7706279470914126 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1787179587512269, + "scoreError" : 0.0033078899798098063, + "scoreConfidence" : [ + 0.1754100687714171, + 0.1820258487310367 + ], + "scorePercentiles" : { + "0.0" : 0.1766384218214576, + "50.0" : 0.1792555473139359, + "90.0" : 0.17970526009919494, + "95.0" : 0.17970526009919494, + "99.0" : 0.17970526009919494, + "99.9" : 0.17970526009919494, + "99.99" : 0.17970526009919494, + "99.999" : 0.17970526009919494, + "99.9999" : 0.17970526009919494, + "100.0" : 0.17970526009919494 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17917072557064537, + 0.1793403690572264, + 0.17945648973549153 + ], + [ + 0.17970526009919494, + 0.17799648622334555, + 0.1766384218214576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3246324442300104, + "scoreError" : 0.00897567559493461, + "scoreConfidence" : [ + 0.3156567686350758, + 0.33360811982494504 + ], + "scorePercentiles" : { + "0.0" : 0.32072831690186016, + "50.0" : 0.32465153844389766, + "90.0" : 0.32876527375238346, + "95.0" : 0.32876527375238346, + "99.0" : 0.32876527375238346, + "99.9" : 0.32876527375238346, + "99.99" : 0.32876527375238346, + "99.999" : 0.32876527375238346, + "99.9999" : 0.32876527375238346, + "100.0" : 0.32876527375238346 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32876527375238346, + 0.3268396783998431, + 0.32664020685262607 + ], + [ + 0.32266287003516925, + 0.32072831690186016, + 0.3221583194381805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.13995119928186395, + "scoreError" : 0.0074268372832595984, + "scoreConfidence" : [ + 0.13252436199860435, + 0.14737803656512355 + ], + "scorePercentiles" : { + "0.0" : 0.13765918293069035, + "50.0" : 0.13935433607492367, + "90.0" : 0.14450633475427366, + "95.0" : 0.14450633475427366, + "99.0" : 0.14450633475427366, + "99.9" : 0.14450633475427366, + "99.99" : 0.14450633475427366, + "99.999" : 0.14450633475427366, + "99.9999" : 0.14450633475427366, + "100.0" : 0.14450633475427366 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13809952799911618, + 0.13789395562664608, + 0.13765918293069035 + ], + [ + 0.14450633475427366, + 0.1409390502297263, + 0.14060914415073117 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3854714736904563, + "scoreError" : 0.010920080632331224, + "scoreConfidence" : [ + 0.37455139305812507, + 0.39639155432278755 + ], + "scorePercentiles" : { + "0.0" : 0.3818199040510099, + "50.0" : 0.38534273178153144, + "90.0" : 0.38941936670560745, + "95.0" : 0.38941936670560745, + "99.0" : 0.38941936670560745, + "99.9" : 0.38941936670560745, + "99.99" : 0.38941936670560745, + "99.999" : 0.38941936670560745, + "99.9999" : 0.38941936670560745, + "100.0" : 0.38941936670560745 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.38941936670560745, + 0.3890532366557734, + 0.3885779630090146 + ], + [ + 0.3818199040510099, + 0.38210750055404835, + 0.381850871167284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1558298173177769, + "scoreError" : 0.0025495043941361852, + "scoreConfidence" : [ + 0.15328031292364072, + 0.15837932171191307 + ], + "scorePercentiles" : { + "0.0" : 0.15481046526100686, + "50.0" : 0.15572319557897962, + "90.0" : 0.1568925131552111, + "95.0" : 0.1568925131552111, + "99.0" : 0.1568925131552111, + "99.9" : 0.1568925131552111, + "99.99" : 0.1568925131552111, + "99.999" : 0.1568925131552111, + "99.9999" : 0.1568925131552111, + "100.0" : 0.1568925131552111 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1550859539406346, + 0.15519708319883296, + 0.15481046526100686 + ], + [ + 0.15624930795912628, + 0.1568925131552111, + 0.15674358039184952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046923209411195425, + "scoreError" : 0.0013603600469595239, + "scoreConfidence" : [ + 0.0455628493642359, + 0.04828356945815495 + ], + "scorePercentiles" : { + "0.0" : 0.046373586909846366, + "50.0" : 0.04697889587217166, + "90.0" : 0.047369550734454716, + "95.0" : 0.047369550734454716, + "99.0" : 0.047369550734454716, + "99.9" : 0.047369550734454716, + "99.99" : 0.047369550734454716, + "99.999" : 0.047369550734454716, + "99.9999" : 0.047369550734454716, + "100.0" : 0.047369550734454716 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04736314282128276, + 0.047369550734454716, + 0.04734965155446548 + ], + [ + 0.04660814018987784, + 0.046373586909846366, + 0.04647518425724537 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8761586.107490508, + "scoreError" : 226991.68683237876, + "scoreConfidence" : [ + 8534594.420658128, + 8988577.794322887 + ], + "scorePercentiles" : { + "0.0" : 8669208.551126517, + "50.0" : 8762259.52210733, + "90.0" : 8858118.155004429, + "95.0" : 8858118.155004429, + "99.0" : 8858118.155004429, + "99.9" : 8858118.155004429, + "99.99" : 8858118.155004429, + "99.999" : 8858118.155004429, + "99.9999" : 8858118.155004429, + "100.0" : 8858118.155004429 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8817195.985903084, + 8858118.155004429, + 8825387.334215168 + ], + [ + 8669208.551126517, + 8707323.058311576, + 8692283.560382277 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-16T00:55:25Z-cab5b9fb685c333e14cca9df99ee262ad037da76-jdk17.json b/performance-results/2025-05-16T00:55:25Z-cab5b9fb685c333e14cca9df99ee262ad037da76-jdk17.json new file mode 100644 index 0000000000..92da28494c --- /dev/null +++ b/performance-results/2025-05-16T00:55:25Z-cab5b9fb685c333e14cca9df99ee262ad037da76-jdk17.json @@ -0,0 +1,1310 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3534673779873008, + "scoreError" : 0.040895235869392636, + "scoreConfidence" : [ + 3.312572142117908, + 3.3943626138566936 + ], + "scorePercentiles" : { + "0.0" : 3.348056855166135, + "50.0" : 3.3520672087412704, + "90.0" : 3.361678239300528, + "95.0" : 3.361678239300528, + "99.0" : 3.361678239300528, + "99.9" : 3.361678239300528, + "99.99" : 3.361678239300528, + "99.999" : 3.361678239300528, + "99.9999" : 3.361678239300528, + "100.0" : 3.361678239300528 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.348056855166135, + 3.3551929039078474 + ], + [ + 3.3489415135746934, + 3.361678239300528 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6888742432465573, + "scoreError" : 0.013335283830812448, + "scoreConfidence" : [ + 1.6755389594157448, + 1.7022095270773698 + ], + "scorePercentiles" : { + "0.0" : 1.6866107939987056, + "50.0" : 1.6886986487753723, + "90.0" : 1.6914888814367792, + "95.0" : 1.6914888814367792, + "99.0" : 1.6914888814367792, + "99.9" : 1.6914888814367792, + "99.99" : 1.6914888814367792, + "99.999" : 1.6914888814367792, + "99.9999" : 1.6914888814367792, + "100.0" : 1.6914888814367792 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6893129577168926, + 1.688084339833852 + ], + [ + 1.6866107939987056, + 1.6914888814367792 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8465062382843163, + "scoreError" : 0.030874564151205215, + "scoreConfidence" : [ + 0.815631674133111, + 0.8773808024355215 + ], + "scorePercentiles" : { + "0.0" : 0.8423525926177947, + "50.0" : 0.8456111706607004, + "90.0" : 0.8524500191980695, + "95.0" : 0.8524500191980695, + "99.0" : 0.8524500191980695, + "99.9" : 0.8524500191980695, + "99.99" : 0.8524500191980695, + "99.999" : 0.8524500191980695, + "99.9999" : 0.8524500191980695, + "100.0" : 0.8524500191980695 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8482851765151651, + 0.8524500191980695 + ], + [ + 0.8429371648062355, + 0.8423525926177947 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.26239604170146, + "scoreError" : 0.13515206335529997, + "scoreConfidence" : [ + 16.12724397834616, + 16.39754810505676 + ], + "scorePercentiles" : { + "0.0" : 16.106850757759318, + "50.0" : 16.30007047963325, + "90.0" : 16.334633023490937, + "95.0" : 16.334633023490937, + "99.0" : 16.334633023490937, + "99.9" : 16.334633023490937, + "99.99" : 16.334633023490937, + "99.999" : 16.334633023490937, + "99.9999" : 16.334633023490937, + "100.0" : 16.334633023490937 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.19116695243847, + 16.186626209692314, + 16.106850757759318 + ], + [ + 16.287107699367837, + 16.30007047963325, + 16.312161216059256 + ], + [ + 16.325573374920637, + 16.31737466195113, + 16.334633023490937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2651.011932202933, + "scoreError" : 215.1304329534489, + "scoreConfidence" : [ + 2435.8814992494845, + 2866.142365156382 + ], + "scorePercentiles" : { + "0.0" : 2553.4467147998175, + "50.0" : 2574.5226270161975, + "90.0" : 2823.590932139633, + "95.0" : 2823.590932139633, + "99.0" : 2823.590932139633, + "99.9" : 2823.590932139633, + "99.99" : 2823.590932139633, + "99.999" : 2823.590932139633, + "99.9999" : 2823.590932139633, + "100.0" : 2823.590932139633 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2553.4467147998175, + 2559.1656064475105, + 2556.629406697637 + ], + [ + 2820.660311473938, + 2823.590932139633, + 2819.6435857264178 + ], + [ + 2574.5226270161975, + 2570.0801509094613, + 2581.3680546157857 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77203.20016579951, + "scoreError" : 957.8515277349302, + "scoreConfidence" : [ + 76245.34863806458, + 78161.05169353445 + ], + "scorePercentiles" : { + "0.0" : 76573.47101335388, + "50.0" : 77111.80701865598, + "90.0" : 77928.82384796672, + "95.0" : 77928.82384796672, + "99.0" : 77928.82384796672, + "99.9" : 77928.82384796672, + "99.99" : 77928.82384796672, + "99.999" : 77928.82384796672, + "99.9999" : 77928.82384796672, + "100.0" : 77928.82384796672 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77057.03716615487, + 77243.45087109742, + 77111.80701865598 + ], + [ + 77928.82384796672, + 77868.31951928424, + 77870.21936158196 + ], + [ + 76596.50718019278, + 76573.47101335388, + 76579.16551390772 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.10862168518247, + "scoreError" : 5.7359838456138625, + "scoreConfidence" : [ + 350.3726378395686, + 361.84460553079634 + ], + "scorePercentiles" : { + "0.0" : 350.77361193256684, + "50.0" : 357.10945793237164, + "90.0" : 359.6653385837557, + "95.0" : 359.6653385837557, + "99.0" : 359.6653385837557, + "99.9" : 359.6653385837557, + "99.99" : 359.6653385837557, + "99.999" : 359.6653385837557, + "99.9999" : 359.6653385837557, + "100.0" : 359.6653385837557 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.68261261434156, + 357.4540481739997, + 357.10945793237164 + ], + [ + 359.6653385837557, + 359.3025899060137, + 359.2645049183992 + ], + [ + 350.77361193256684, + 351.7579736105755, + 352.9674574946181 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.82841204144792, + "scoreError" : 4.265816128720171, + "scoreConfidence" : [ + 109.56259591272774, + 118.0942281701681 + ], + "scorePercentiles" : { + "0.0" : 109.41096697879635, + "50.0" : 114.21922508919265, + "90.0" : 116.79808555089993, + "95.0" : 116.79808555089993, + "99.0" : 116.79808555089993, + "99.9" : 116.79808555089993, + "99.99" : 116.79808555089993, + "99.999" : 116.79808555089993, + "99.9999" : 116.79808555089993, + "100.0" : 116.79808555089993 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.41096697879635, + 111.08582789224916, + 111.8911726144754 + ], + [ + 115.87980734099584, + 116.36546895436693, + 116.79808555089993 + ], + [ + 114.21922508919265, + 113.90849822603386, + 114.89665572602111 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061790546867354385, + "scoreError" : 6.105863341445122E-4, + "scoreConfidence" : [ + 0.06117996053320987, + 0.0624011332014989 + ], + "scorePercentiles" : { + "0.0" : 0.061242978816439766, + "50.0" : 0.06190882366852183, + "90.0" : 0.062198397034401685, + "95.0" : 0.062198397034401685, + "99.0" : 0.062198397034401685, + "99.9" : 0.062198397034401685, + "99.99" : 0.062198397034401685, + "99.999" : 0.062198397034401685, + "99.9999" : 0.062198397034401685, + "100.0" : 0.062198397034401685 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06190882366852183, + 0.06188176751381489, + 0.06214347138951032 + ], + [ + 0.062198397034401685, + 0.06195416120238892, + 0.06204289397079078 + ], + [ + 0.06139378686189643, + 0.061348641348424895, + 0.061242978816439766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8037665718987357E-4, + "scoreError" : 3.0760954973572304E-5, + "scoreConfidence" : [ + 3.496157022163013E-4, + 4.1113761216344586E-4 + ], + "scorePercentiles" : { + "0.0" : 3.552504588709267E-4, + "50.0" : 3.9203119328728883E-4, + "90.0" : 3.935684671393577E-4, + "95.0" : 3.935684671393577E-4, + "99.0" : 3.935684671393577E-4, + "99.9" : 3.935684671393577E-4, + "99.99" : 3.935684671393577E-4, + "99.999" : 3.935684671393577E-4, + "99.9999" : 3.935684671393577E-4, + "100.0" : 3.935684671393577E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.930545217028878E-4, + 3.935684671393577E-4, + 3.925294679372791E-4 + ], + [ + 3.9164624942051755E-4, + 3.9260785747270087E-4, + 3.9203119328728883E-4 + ], + [ + 3.552504588709267E-4, + 3.5640166362956293E-4, + 3.563000352483412E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01288682501059022, + "scoreError" : 2.315572965674496E-4, + "scoreConfidence" : [ + 0.012655267714022771, + 0.01311838230715767 + ], + "scorePercentiles" : { + "0.0" : 0.012691638868582569, + "50.0" : 0.012901039640706512, + "90.0" : 0.013047250257027148, + "95.0" : 0.013047250257027148, + "99.0" : 0.013047250257027148, + "99.9" : 0.013047250257027148, + "99.99" : 0.013047250257027148, + "99.999" : 0.013047250257027148, + "99.9999" : 0.013047250257027148, + "100.0" : 0.013047250257027148 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012691638868582569, + 0.01277703399543099, + 0.012699944983337905 + ], + [ + 0.012907003135071368, + 0.012901039640706512, + 0.01289994060425151 + ], + [ + 0.013029868165430364, + 0.013027705445473613, + 0.013047250257027148 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.053638657611185, + "scoreError" : 0.1020238635039845, + "scoreConfidence" : [ + 0.9516147941072004, + 1.1556625211151694 + ], + "scorePercentiles" : { + "0.0" : 1.0064871770330113, + "50.0" : 1.0202947283207509, + "90.0" : 1.1349413142305946, + "95.0" : 1.1349413142305946, + "99.0" : 1.1349413142305946, + "99.9" : 1.1349413142305946, + "99.99" : 1.1349413142305946, + "99.999" : 1.1349413142305946, + "99.9999" : 1.1349413142305946, + "100.0" : 1.1349413142305946 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0067225163076303, + 1.0064871770330113, + 1.0074844953657063 + ], + [ + 1.133879839909297, + 1.1349413142305946, + 1.1338963595238096 + ], + [ + 1.020894702633728, + 1.0181467851761352, + 1.0202947283207509 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01052963737140567, + "scoreError" : 1.2117379812278244E-4, + "scoreConfidence" : [ + 0.010408463573282888, + 0.010650811169528452 + ], + "scorePercentiles" : { + "0.0" : 0.010485816813567283, + "50.0" : 0.01052741050421943, + "90.0" : 0.010576258130769166, + "95.0" : 0.010576258130769166, + "99.0" : 0.010576258130769166, + "99.9" : 0.010576258130769166, + "99.99" : 0.010576258130769166, + "99.999" : 0.010576258130769166, + "99.9999" : 0.010576258130769166, + "100.0" : 0.010576258130769166 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010556058373480495, + 0.010572830702967408, + 0.010576258130769166 + ], + [ + 0.010485816813567283, + 0.01048809757269131, + 0.010498762634958364 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.227228623277515, + "scoreError" : 0.2536200409139891, + "scoreConfidence" : [ + 2.973608582363526, + 3.4808486641915044 + ], + "scorePercentiles" : { + "0.0" : 3.1355214952978057, + "50.0" : 3.231385594921664, + "90.0" : 3.3151863326706428, + "95.0" : 3.3151863326706428, + "99.0" : 3.3151863326706428, + "99.9" : 3.3151863326706428, + "99.99" : 3.3151863326706428, + "99.999" : 3.3151863326706428, + "99.9999" : 3.3151863326706428, + "100.0" : 3.3151863326706428 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3075624523809526, + 3.3151863326706428, + 3.3057409114342367 + ], + [ + 3.1423302694723616, + 3.157030278409091, + 3.1355214952978057 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7761640327720176, + "scoreError" : 0.05586433016158096, + "scoreConfidence" : [ + 2.7202997026104367, + 2.8320283629335985 + ], + "scorePercentiles" : { + "0.0" : 2.733869421541826, + "50.0" : 2.770709843490305, + "90.0" : 2.8172938123943663, + "95.0" : 2.8172938123943663, + "99.0" : 2.8172938123943663, + "99.9" : 2.8172938123943663, + "99.99" : 2.8172938123943663, + "99.999" : 2.8172938123943663, + "99.9999" : 2.8172938123943663, + "100.0" : 2.8172938123943663 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.783549381853604, + 2.770709843490305, + 2.761674409718388 + ], + [ + 2.7493244431006048, + 2.733869421541826, + 2.7394475979183786 + ], + [ + 2.8123490826771653, + 2.8172938123943663, + 2.817258302253521 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1790134549531295, + "scoreError" : 0.002862209757215734, + "scoreConfidence" : [ + 0.17615124519591377, + 0.18187566471034525 + ], + "scorePercentiles" : { + "0.0" : 0.176835408675355, + "50.0" : 0.17921648241935484, + "90.0" : 0.18152882640817586, + "95.0" : 0.18152882640817586, + "99.0" : 0.18152882640817586, + "99.9" : 0.18152882640817586, + "99.99" : 0.18152882640817586, + "99.999" : 0.18152882640817586, + "99.9999" : 0.18152882640817586, + "100.0" : 0.18152882640817586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17915963537990218, + 0.18073763526116032, + 0.17921648241935484 + ], + [ + 0.18152882640817586, + 0.17984586364535562, + 0.1797403719826734 + ], + [ + 0.17701539027153326, + 0.1770414805346552, + 0.176835408675355 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3258793135740633, + "scoreError" : 0.006485738578294348, + "scoreConfidence" : [ + 0.3193935749957689, + 0.3323650521523577 + ], + "scorePercentiles" : { + "0.0" : 0.32213417062878497, + "50.0" : 0.3240410555717572, + "90.0" : 0.3310495732587394, + "95.0" : 0.3310495732587394, + "99.0" : 0.3310495732587394, + "99.9" : 0.3310495732587394, + "99.99" : 0.3310495732587394, + "99.999" : 0.3310495732587394, + "99.9999" : 0.3310495732587394, + "100.0" : 0.3310495732587394 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32251011606682145, + 0.32213417062878497, + 0.3228926847696232 + ], + [ + 0.32366887733436905, + 0.3240410555717572, + 0.3249576049587314 + ], + [ + 0.3310495732587394, + 0.3307603734537276, + 0.3308993661240156 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14241536578409383, + "scoreError" : 0.0077280678118041915, + "scoreConfidence" : [ + 0.13468729797228965, + 0.15014343359589802 + ], + "scorePercentiles" : { + "0.0" : 0.13692587486650054, + "50.0" : 0.14274127025792546, + "90.0" : 0.14764767623392538, + "95.0" : 0.14764767623392538, + "99.0" : 0.14764767623392538, + "99.9" : 0.14764767623392538, + "99.99" : 0.14764767623392538, + "99.999" : 0.14764767623392538, + "99.9999" : 0.14764767623392538, + "100.0" : 0.14764767623392538 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1427466895483613, + 0.14262076473943924, + 0.14274127025792546 + ], + [ + 0.13704001903443738, + 0.13693696730021362, + 0.13692587486650054 + ], + [ + 0.14758714126745182, + 0.14764767623392538, + 0.1474918888085897 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4047976336353598, + "scoreError" : 0.011996243351085895, + "scoreConfidence" : [ + 0.3928013902842739, + 0.4167938769864457 + ], + "scorePercentiles" : { + "0.0" : 0.3970063332804002, + "50.0" : 0.4016961715536632, + "90.0" : 0.41466724754322676, + "95.0" : 0.41466724754322676, + "99.0" : 0.41466724754322676, + "99.9" : 0.41466724754322676, + "99.99" : 0.41466724754322676, + "99.999" : 0.41466724754322676, + "99.9999" : 0.41466724754322676, + "100.0" : 0.41466724754322676 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41466724754322676, + 0.41275569328875683, + 0.41367709795648216 + ], + [ + 0.40577278320146076, + 0.4016961715536632, + 0.4004024747357463 + ], + [ + 0.3980047477115339, + 0.3970063332804002, + 0.3991961534469682 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1570760144790013, + "scoreError" : 0.002791944801991304, + "scoreConfidence" : [ + 0.15428406967701, + 0.1598679592809926 + ], + "scorePercentiles" : { + "0.0" : 0.15511718703562952, + "50.0" : 0.15741889816928234, + "90.0" : 0.16024883169617818, + "95.0" : 0.16024883169617818, + "99.0" : 0.16024883169617818, + "99.9" : 0.16024883169617818, + "99.99" : 0.16024883169617818, + "99.999" : 0.16024883169617818, + "99.9999" : 0.16024883169617818, + "100.0" : 0.16024883169617818 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15531637040661014, + 0.15518899359083785, + 0.15511718703562952 + ], + [ + 0.15741889816928234, + 0.1574912640282218, + 0.15719385694075483 + ], + [ + 0.16024883169617818, + 0.1577969593524158, + 0.15791176909108134 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048080740514219136, + "scoreError" : 7.735893804021649E-4, + "scoreConfidence" : [ + 0.04730715113381697, + 0.0488543298946213 + ], + "scorePercentiles" : { + "0.0" : 0.04755119428158419, + "50.0" : 0.04809009220618715, + "90.0" : 0.0489788298648695, + "95.0" : 0.0489788298648695, + "99.0" : 0.0489788298648695, + "99.9" : 0.0489788298648695, + "99.99" : 0.0489788298648695, + "99.999" : 0.0489788298648695, + "99.9999" : 0.0489788298648695, + "100.0" : 0.0489788298648695 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04755119428158419, + 0.04764913158145519, + 0.04758649213735482 + ], + [ + 0.0489788298648695, + 0.048483318108212936, + 0.04810017364347797 + ], + [ + 0.04809009220618715, + 0.0480830349990624, + 0.04820439780576805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 3, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8564577.069390323, + "scoreError" : 215018.68304839788, + "scoreConfidence" : [ + 8349558.386341925, + 8779595.75243872 + ], + "scorePercentiles" : { + "0.0" : 8366116.078595318, + "50.0" : 8609619.247848537, + "90.0" : 8688698.606429191, + "95.0" : 8688698.606429191, + "99.0" : 8688698.606429191, + "99.9" : 8688698.606429191, + "99.99" : 8688698.606429191, + "99.999" : 8688698.606429191, + "99.9999" : 8688698.606429191, + "100.0" : 8688698.606429191 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8470700.714648603, + 8378140.517587939, + 8366116.078595318 + ], + [ + 8616968.260981912, + 8609619.247848537, + 8588286.163090128 + ], + [ + 8684041.736979166, + 8688698.606429191, + 8678622.298352124 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-16T03:56:23Z-c16cf96e83acf6f2551e95f499bfa909c47d2007-jdk17.json b/performance-results/2025-05-16T03:56:23Z-c16cf96e83acf6f2551e95f499bfa909c47d2007-jdk17.json new file mode 100644 index 0000000000..bfb44a33fd --- /dev/null +++ b/performance-results/2025-05-16T03:56:23Z-c16cf96e83acf6f2551e95f499bfa909c47d2007-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3553703725435438, + "scoreError" : 0.032657057547065105, + "scoreConfidence" : [ + 3.3227133149964785, + 3.388027430090609 + ], + "scorePercentiles" : { + "0.0" : 3.3499177306463777, + "50.0" : 3.355360011656905, + "90.0" : 3.360843736213989, + "95.0" : 3.360843736213989, + "99.0" : 3.360843736213989, + "99.9" : 3.360843736213989, + "99.99" : 3.360843736213989, + "99.999" : 3.360843736213989, + "99.9999" : 3.360843736213989, + "100.0" : 3.360843736213989 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.352450466840584, + 3.358269556473226 + ], + [ + 3.3499177306463777, + 3.360843736213989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.702491965048374, + "scoreError" : 0.015110338721156047, + "scoreConfidence" : [ + 1.687381626327218, + 1.71760230376953 + ], + "scorePercentiles" : { + "0.0" : 1.6991305141367838, + "50.0" : 1.7031811360639257, + "90.0" : 1.7044750739288603, + "95.0" : 1.7044750739288603, + "99.0" : 1.7044750739288603, + "99.9" : 1.7044750739288603, + "99.99" : 1.7044750739288603, + "99.999" : 1.7044750739288603, + "99.9999" : 1.7044750739288603, + "100.0" : 1.7044750739288603 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7028483159315277, + 1.6991305141367838 + ], + [ + 1.7044750739288603, + 1.7035139561963237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8518040848096116, + "scoreError" : 0.015434812926358853, + "scoreConfidence" : [ + 0.8363692718832527, + 0.8672388977359704 + ], + "scorePercentiles" : { + "0.0" : 0.8495899774033487, + "50.0" : 0.8517530267189388, + "90.0" : 0.8541203083972198, + "95.0" : 0.8541203083972198, + "99.0" : 0.8541203083972198, + "99.9" : 0.8541203083972198, + "99.99" : 0.8541203083972198, + "99.999" : 0.8541203083972198, + "99.9999" : 0.8541203083972198, + "100.0" : 0.8541203083972198 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8536027833229437, + 0.8541203083972198 + ], + [ + 0.8495899774033487, + 0.849903270114934 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.228714477595517, + "scoreError" : 0.08651454881848845, + "scoreConfidence" : [ + 16.14219992877703, + 16.315229026414006 + ], + "scorePercentiles" : { + "0.0" : 16.170915239207936, + "50.0" : 16.24097170234195, + "90.0" : 16.25561034290486, + "95.0" : 16.25561034290486, + "99.0" : 16.25561034290486, + "99.9" : 16.25561034290486, + "99.99" : 16.25561034290486, + "99.999" : 16.25561034290486, + "99.9999" : 16.25561034290486, + "100.0" : 16.25561034290486 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.237693552340406, + 16.25561034290486, + 16.2451883398166 + ], + [ + 16.170915239207936, + 16.21862953895982, + 16.244249852343494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2645.2444536259627, + "scoreError" : 258.5530761003146, + "scoreConfidence" : [ + 2386.691377525648, + 2903.7975297262774 + ], + "scorePercentiles" : { + "0.0" : 2560.1199026348786, + "50.0" : 2645.3601504827247, + "90.0" : 2730.987798107538, + "95.0" : 2730.987798107538, + "99.0" : 2730.987798107538, + "99.9" : 2730.987798107538, + "99.99" : 2730.987798107538, + "99.999" : 2730.987798107538, + "99.9999" : 2730.987798107538, + "100.0" : 2730.987798107538 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2560.1199026348786, + 2560.7173687801046, + 2562.4091622042693 + ], + [ + 2730.987798107538, + 2728.3111387611802, + 2728.921351267805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77319.17682906751, + "scoreError" : 1091.6954622467447, + "scoreConfidence" : [ + 76227.48136682076, + 78410.87229131426 + ], + "scorePercentiles" : { + "0.0" : 76932.68907560426, + "50.0" : 77328.01517228465, + "90.0" : 77684.12244353759, + "95.0" : 77684.12244353759, + "99.0" : 77684.12244353759, + "99.9" : 77684.12244353759, + "99.99" : 77684.12244353759, + "99.999" : 77684.12244353759, + "99.9999" : 77684.12244353759, + "100.0" : 77684.12244353759 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77661.38655773611, + 77676.64661237481, + 77684.12244353759 + ], + [ + 76994.64378683319, + 76932.68907560426, + 76965.57249831907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.03095712236194, + "scoreError" : 7.4937784731266195, + "scoreConfidence" : [ + 353.53717864923533, + 368.52473559548855 + ], + "scorePercentiles" : { + "0.0" : 356.43992087508474, + "50.0" : 361.47107602818596, + "90.0" : 363.5445707591954, + "95.0" : 363.5445707591954, + "99.0" : 363.5445707591954, + "99.9" : 363.5445707591954, + "99.99" : 363.5445707591954, + "99.999" : 363.5445707591954, + "99.9999" : 363.5445707591954, + "100.0" : 363.5445707591954 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.43992087508474, + 360.13072208514933, + 360.3060655424482 + ], + [ + 363.1283769583699, + 362.6360865139238, + 363.5445707591954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.2151330572169, + "scoreError" : 6.9149393246398905, + "scoreConfidence" : [ + 105.30019373257701, + 119.13007238185679 + ], + "scorePercentiles" : { + "0.0" : 109.84956905149458, + "50.0" : 111.78811476516739, + "90.0" : 115.40671540168225, + "95.0" : 115.40671540168225, + "99.0" : 115.40671540168225, + "99.9" : 115.40671540168225, + "99.99" : 115.40671540168225, + "99.999" : 115.40671540168225, + "99.9999" : 115.40671540168225, + "100.0" : 115.40671540168225 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.84956905149458, + 110.12366994761211, + 110.1463241982282 + ], + [ + 113.42990533210657, + 114.33461441217766, + 115.40671540168225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06088126613168612, + "scoreError" : 5.22041055550832E-4, + "scoreConfidence" : [ + 0.06035922507613529, + 0.061403307187236945 + ], + "scorePercentiles" : { + "0.0" : 0.06069725215016236, + "50.0" : 0.06084511941189625, + "90.0" : 0.061121216799501256, + "95.0" : 0.061121216799501256, + "99.0" : 0.061121216799501256, + "99.9" : 0.061121216799501256, + "99.99" : 0.061121216799501256, + "99.999" : 0.061121216799501256, + "99.9999" : 0.061121216799501256, + "100.0" : 0.061121216799501256 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06069725215016236, + 0.06074769567726494, + 0.06071606686581301 + ], + [ + 0.06106282215084754, + 0.060942543146527556, + 0.061121216799501256 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.72757742636935E-4, + "scoreError" : 2.8281785331329748E-5, + "scoreConfidence" : [ + 3.4447595730560524E-4, + 4.0103952796826476E-4 + ], + "scorePercentiles" : { + "0.0" : 3.634110671151054E-4, + "50.0" : 3.727601105921812E-4, + "90.0" : 3.8210939651776637E-4, + "95.0" : 3.8210939651776637E-4, + "99.0" : 3.8210939651776637E-4, + "99.9" : 3.8210939651776637E-4, + "99.99" : 3.8210939651776637E-4, + "99.999" : 3.8210939651776637E-4, + "99.9999" : 3.8210939651776637E-4, + "100.0" : 3.8210939651776637E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8192090817917325E-4, + 3.8210939651776637E-4, + 3.8186157194333074E-4 + ], + [ + 3.634110671151054E-4, + 3.635848628252025E-4, + 3.6365864924103164E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12378884025089688, + "scoreError" : 0.002609165204847373, + "scoreConfidence" : [ + 0.12117967504604951, + 0.12639800545574426 + ], + "scorePercentiles" : { + "0.0" : 0.12276025089918122, + "50.0" : 0.12386527738914205, + "90.0" : 0.12465295960112184, + "95.0" : 0.12465295960112184, + "99.0" : 0.12465295960112184, + "99.9" : 0.12465295960112184, + "99.99" : 0.12465295960112184, + "99.999" : 0.12465295960112184, + "99.9999" : 0.12465295960112184, + "100.0" : 0.12465295960112184 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12276025089918122, + 0.12294303046471601, + 0.12313664987932818 + ], + [ + 0.12465295960112184, + 0.12464624576207808, + 0.12459390489895592 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013017202759325006, + "scoreError" : 2.2596415049446224E-4, + "scoreConfidence" : [ + 0.012791238608830543, + 0.013243166909819469 + ], + "scorePercentiles" : { + "0.0" : 0.012934287448748626, + "50.0" : 0.013014979483601155, + "90.0" : 0.013097654594272467, + "95.0" : 0.013097654594272467, + "99.0" : 0.013097654594272467, + "99.9" : 0.013097654594272467, + "99.99" : 0.013097654594272467, + "99.999" : 0.013097654594272467, + "99.9999" : 0.013097654594272467, + "100.0" : 0.013097654594272467 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01294916990521327, + 0.012948465411199246, + 0.012934287448748626 + ], + [ + 0.013080789061989038, + 0.013092850134527387, + 0.013097654594272467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.010850876444796, + "scoreError" : 0.027264327039679657, + "scoreConfidence" : [ + 0.9835865494051165, + 1.0381152034844758 + ], + "scorePercentiles" : { + "0.0" : 0.9998249461107779, + "50.0" : 1.0107009774638844, + "90.0" : 1.024357302366076, + "95.0" : 1.024357302366076, + "99.0" : 1.024357302366076, + "99.9" : 1.024357302366076, + "99.99" : 1.024357302366076, + "99.999" : 1.024357302366076, + "99.9999" : 1.024357302366076, + "100.0" : 1.024357302366076 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0050143791578736, + 1.0026343631441748, + 0.9998249461107779 + ], + [ + 1.024357302366076, + 1.0163875757698952, + 1.0168866921199797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011449980648462164, + "scoreError" : 1.5143040230067135E-4, + "scoreConfidence" : [ + 0.011298550246161493, + 0.011601411050762836 + ], + "scorePercentiles" : { + "0.0" : 0.011397680155824735, + "50.0" : 0.011448375552722552, + "90.0" : 0.011502706189669927, + "95.0" : 0.011502706189669927, + "99.0" : 0.011502706189669927, + "99.9" : 0.011502706189669927, + "99.99" : 0.011502706189669927, + "99.999" : 0.011502706189669927, + "99.9999" : 0.011502706189669927, + "100.0" : 0.011502706189669927 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011402490656858744, + 0.011397680155824735, + 0.011402151126384465 + ], + [ + 0.011502706189669927, + 0.011500595313448764, + 0.011494260448586358 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.287366772677738, + "scoreError" : 0.035271139700450906, + "scoreConfidence" : [ + 3.2520956329772868, + 3.322637912378189 + ], + "scorePercentiles" : { + "0.0" : 3.265128242819843, + "50.0" : 3.291970129315079, + "90.0" : 3.2976442781806194, + "95.0" : 3.2976442781806194, + "99.0" : 3.2976442781806194, + "99.9" : 3.2976442781806194, + "99.99" : 3.2976442781806194, + "99.999" : 3.2976442781806194, + "99.9999" : 3.2976442781806194, + "100.0" : 3.2976442781806194 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2972307580751483, + 3.2976442781806194, + 3.291410140789474 + ], + [ + 3.2925301178406845, + 3.280257098360656, + 3.265128242819843 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7573124710191284, + "scoreError" : 0.05370785558329982, + "scoreConfidence" : [ + 2.7036046154358284, + 2.8110203266024283 + ], + "scorePercentiles" : { + "0.0" : 2.736961, + "50.0" : 2.756286582845668, + "90.0" : 2.783874885054272, + "95.0" : 2.783874885054272, + "99.0" : 2.783874885054272, + "99.9" : 2.783874885054272, + "99.99" : 2.783874885054272, + "99.999" : 2.783874885054272, + "99.9999" : 2.783874885054272, + "100.0" : 2.783874885054272 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7440335736625516, + 2.741031372156755, + 2.736961 + ], + [ + 2.783874885054272, + 2.7694344032124065, + 2.7685395920287847 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1824581992452332, + "scoreError" : 0.01263337015323987, + "scoreConfidence" : [ + 0.16982482909199334, + 0.19509156939847308 + ], + "scorePercentiles" : { + "0.0" : 0.1783783544111876, + "50.0" : 0.1818142796479224, + "90.0" : 0.18801836031361047, + "95.0" : 0.18801836031361047, + "99.0" : 0.18801836031361047, + "99.9" : 0.18801836031361047, + "99.99" : 0.18801836031361047, + "99.999" : 0.18801836031361047, + "99.9999" : 0.18801836031361047, + "100.0" : 0.18801836031361047 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18628539033568048, + 0.18515257173538724, + 0.18801836031361047 + ], + [ + 0.17843853111507582, + 0.1783783544111876, + 0.1784759875604576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3221278195931336, + "scoreError" : 0.006196440491176188, + "scoreConfidence" : [ + 0.3159313791019574, + 0.32832426008430976 + ], + "scorePercentiles" : { + "0.0" : 0.32062849788393716, + "50.0" : 0.3212660450332257, + "90.0" : 0.32650045456919913, + "95.0" : 0.32650045456919913, + "99.0" : 0.32650045456919913, + "99.9" : 0.32650045456919913, + "99.99" : 0.32650045456919913, + "99.999" : 0.32650045456919913, + "99.9999" : 0.32650045456919913, + "100.0" : 0.32650045456919913 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32062849788393716, + 0.3209410500657916, + 0.32099118572253965 + ], + [ + 0.32650045456919913, + 0.32216482497342225, + 0.32154090434391175 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14073558263808947, + "scoreError" : 0.005065998009303859, + "scoreConfidence" : [ + 0.13566958462878562, + 0.14580158064739332 + ], + "scorePercentiles" : { + "0.0" : 0.13909703171335577, + "50.0" : 0.1401810541738386, + "90.0" : 0.14385419664254787, + "95.0" : 0.14385419664254787, + "99.0" : 0.14385419664254787, + "99.9" : 0.14385419664254787, + "99.99" : 0.14385419664254787, + "99.999" : 0.14385419664254787, + "99.9999" : 0.14385419664254787, + "100.0" : 0.14385419664254787 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14385419664254787, + 0.14181902571084168, + 0.13909703171335577 + ], + [ + 0.1392811334141144, + 0.14013720411995514, + 0.14022490422772207 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4029450634253009, + "scoreError" : 0.028920544530209154, + "scoreConfidence" : [ + 0.37402451889509175, + 0.43186560795551004 + ], + "scorePercentiles" : { + "0.0" : 0.3932387117691007, + "50.0" : 0.4023735325715181, + "90.0" : 0.4137857563720622, + "95.0" : 0.4137857563720622, + "99.0" : 0.4137857563720622, + "99.9" : 0.4137857563720622, + "99.99" : 0.4137857563720622, + "99.999" : 0.4137857563720622, + "99.9999" : 0.4137857563720622, + "100.0" : 0.4137857563720622 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4137857563720622, + 0.41232167465160385, + 0.4108517400681977 + ], + [ + 0.3938953250748385, + 0.3932387117691007, + 0.3935771726160022 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15889903022691718, + "scoreError" : 0.0013640564201312852, + "scoreConfidence" : [ + 0.15753497380678588, + 0.16026308664704847 + ], + "scorePercentiles" : { + "0.0" : 0.15840507866183015, + "50.0" : 0.15887285332889767, + "90.0" : 0.15975560961387925, + "95.0" : 0.15975560961387925, + "99.0" : 0.15975560961387925, + "99.9" : 0.15975560961387925, + "99.99" : 0.15975560961387925, + "99.999" : 0.15975560961387925, + "99.9999" : 0.15975560961387925, + "100.0" : 0.15975560961387925 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15884170446495227, + 0.15890400219284306, + 0.15840507866183015 + ], + [ + 0.15975560961387925, + 0.15846646222229266, + 0.15902132420570556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04718610007413779, + "scoreError" : 0.001326334888219713, + "scoreConfidence" : [ + 0.045859765185918076, + 0.0485124349623575 + ], + "scorePercentiles" : { + "0.0" : 0.04670062911074374, + "50.0" : 0.04716122024754414, + "90.0" : 0.04779456044964441, + "95.0" : 0.04779456044964441, + "99.0" : 0.04779456044964441, + "99.9" : 0.04779456044964441, + "99.99" : 0.04779456044964441, + "99.999" : 0.04779456044964441, + "99.9999" : 0.04779456044964441, + "100.0" : 0.04779456044964441 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04670062911074374, + 0.046786509881164035, + 0.04681104828018799 + ], + [ + 0.047512460508186284, + 0.0475113922149003, + 0.04779456044964441 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8453659.808721319, + "scoreError" : 225905.11525009322, + "scoreConfidence" : [ + 8227754.693471226, + 8679564.923971413 + ], + "scorePercentiles" : { + "0.0" : 8373439.4234309625, + "50.0" : 8455909.886086714, + "90.0" : 8528363.404092072, + "95.0" : 8528363.404092072, + "99.0" : 8528363.404092072, + "99.9" : 8528363.404092072, + "99.99" : 8528363.404092072, + "99.999" : 8528363.404092072, + "99.9999" : 8528363.404092072, + "100.0" : 8528363.404092072 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8381523.269681742, + 8385666.062028499, + 8373439.4234309625 + ], + [ + 8528363.404092072, + 8526812.982949702, + 8526153.710144928 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-16T04:29:15Z-444af98a224b7d26cf1571233daa581b856fc53a-jdk17.json b/performance-results/2025-05-16T04:29:15Z-444af98a224b7d26cf1571233daa581b856fc53a-jdk17.json new file mode 100644 index 0000000000..c753ce812c --- /dev/null +++ b/performance-results/2025-05-16T04:29:15Z-444af98a224b7d26cf1571233daa581b856fc53a-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3486397495147173, + "scoreError" : 0.021052002959585835, + "scoreConfidence" : [ + 3.3275877465551313, + 3.3696917524743033 + ], + "scorePercentiles" : { + "0.0" : 3.344461233285716, + "50.0" : 3.3493418564862587, + "90.0" : 3.3514140518006355, + "95.0" : 3.3514140518006355, + "99.0" : 3.3514140518006355, + "99.9" : 3.3514140518006355, + "99.99" : 3.3514140518006355, + "99.999" : 3.3514140518006355, + "99.9999" : 3.3514140518006355, + "100.0" : 3.3514140518006355 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3476540281646368, + 3.3514140518006355 + ], + [ + 3.344461233285716, + 3.35102968480788 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6745915078987168, + "scoreError" : 0.05814685454503823, + "scoreConfidence" : [ + 1.6164446533536785, + 1.7327383624437551 + ], + "scorePercentiles" : { + "0.0" : 1.6647441277709387, + "50.0" : 1.6754529716801128, + "90.0" : 1.6827159604637032, + "95.0" : 1.6827159604637032, + "99.0" : 1.6827159604637032, + "99.9" : 1.6827159604637032, + "99.99" : 1.6827159604637032, + "99.999" : 1.6827159604637032, + "99.9999" : 1.6827159604637032, + "100.0" : 1.6827159604637032 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6827159604637032, + 1.6817157909299627 + ], + [ + 1.6647441277709387, + 1.669190152430263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8415276701310598, + "scoreError" : 0.023072166052072265, + "scoreConfidence" : [ + 0.8184555040789875, + 0.8645998361831321 + ], + "scorePercentiles" : { + "0.0" : 0.8380459354325034, + "50.0" : 0.8407896450094752, + "90.0" : 0.8464854550727857, + "95.0" : 0.8464854550727857, + "99.0" : 0.8464854550727857, + "99.9" : 0.8464854550727857, + "99.99" : 0.8464854550727857, + "99.999" : 0.8464854550727857, + "99.9999" : 0.8464854550727857, + "100.0" : 0.8464854550727857 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8403138695885073, + 0.8464854550727857 + ], + [ + 0.8380459354325034, + 0.841265420430443 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.254336188437463, + "scoreError" : 0.04522065263163152, + "scoreConfidence" : [ + 16.209115535805832, + 16.299556841069094 + ], + "scorePercentiles" : { + "0.0" : 16.230523024, + "50.0" : 16.250792736932066, + "90.0" : 16.272678912875218, + "95.0" : 16.272678912875218, + "99.0" : 16.272678912875218, + "99.9" : 16.272678912875218, + "99.99" : 16.272678912875218, + "99.999" : 16.272678912875218, + "99.9999" : 16.272678912875218, + "100.0" : 16.272678912875218 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.24926018691846, + 16.27261659936383, + 16.272678912875218 + ], + [ + 16.2486131205216, + 16.252325286945673, + 16.230523024 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2651.709722800399, + "scoreError" : 67.28487903274501, + "scoreConfidence" : [ + 2584.4248437676542, + 2718.994601833144 + ], + "scorePercentiles" : { + "0.0" : 2625.4630574330176, + "50.0" : 2649.531599919619, + "90.0" : 2682.0414502632066, + "95.0" : 2682.0414502632066, + "99.0" : 2682.0414502632066, + "99.9" : 2682.0414502632066, + "99.99" : 2682.0414502632066, + "99.999" : 2682.0414502632066, + "99.9999" : 2682.0414502632066, + "100.0" : 2682.0414502632066 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2682.0414502632066, + 2665.6722416878174, + 2671.0702700891547 + ], + [ + 2625.4630574330176, + 2632.6203591777744, + 2633.3909581514213 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77350.11743981263, + "scoreError" : 677.1399205096427, + "scoreConfidence" : [ + 76672.977519303, + 78027.25736032227 + ], + "scorePercentiles" : { + "0.0" : 77121.10839293046, + "50.0" : 77343.00595908737, + "90.0" : 77622.35288222185, + "95.0" : 77622.35288222185, + "99.0" : 77622.35288222185, + "99.9" : 77622.35288222185, + "99.99" : 77622.35288222185, + "99.999" : 77622.35288222185, + "99.9999" : 77622.35288222185, + "100.0" : 77622.35288222185 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77546.95793173401, + 77536.83561754768, + 77622.35288222185 + ], + [ + 77149.17630062706, + 77124.27351381471, + 77121.10839293046 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 366.7524418237054, + "scoreError" : 12.873858422778126, + "scoreConfidence" : [ + 353.87858340092725, + 379.62630024648354 + ], + "scorePercentiles" : { + "0.0" : 362.28466506978305, + "50.0" : 365.57710195754044, + "90.0" : 373.2687714014126, + "95.0" : 373.2687714014126, + "99.0" : 373.2687714014126, + "99.9" : 373.2687714014126, + "99.99" : 373.2687714014126, + "99.999" : 373.2687714014126, + "99.9999" : 373.2687714014126, + "100.0" : 373.2687714014126 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 367.6800766940573, + 370.85993455491626, + 373.2687714014126 + ], + [ + 362.28466506978305, + 362.94707600103993, + 363.4741272210236 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 118.52945997693017, + "scoreError" : 3.4834645517908753, + "scoreConfidence" : [ + 115.0459954251393, + 122.01292452872104 + ], + "scorePercentiles" : { + "0.0" : 117.34897556234512, + "50.0" : 118.38284580487621, + "90.0" : 119.92411168633737, + "95.0" : 119.92411168633737, + "99.0" : 119.92411168633737, + "99.9" : 119.92411168633737, + "99.99" : 119.92411168633737, + "99.999" : 119.92411168633737, + "99.9999" : 119.92411168633737, + "100.0" : 119.92411168633737 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.48958524985825, + 117.34897556234512, + 117.39954157621182 + ], + [ + 119.27610635989416, + 119.73843942693425, + 119.92411168633737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06072738315468815, + "scoreError" : 6.600570602612759E-4, + "scoreConfidence" : [ + 0.06006732609442687, + 0.06138744021494942 + ], + "scorePercentiles" : { + "0.0" : 0.06049536013042637, + "50.0" : 0.06072163141781364, + "90.0" : 0.060976845407593946, + "95.0" : 0.060976845407593946, + "99.0" : 0.060976845407593946, + "99.9" : 0.060976845407593946, + "99.99" : 0.060976845407593946, + "99.999" : 0.060976845407593946, + "99.9999" : 0.060976845407593946, + "100.0" : 0.060976845407593946 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06091257444281337, + 0.06093412547375605, + 0.060976845407593946 + ], + [ + 0.060530688392813906, + 0.06051470508072519, + 0.06049536013042637 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.617192809677106E-4, + "scoreError" : 2.1375662334148513E-5, + "scoreConfidence" : [ + 3.403436186335621E-4, + 3.8309494330185915E-4 + ], + "scorePercentiles" : { + "0.0" : 3.546447875159397E-4, + "50.0" : 3.616479935680319E-4, + "90.0" : 3.689266811938284E-4, + "95.0" : 3.689266811938284E-4, + "99.0" : 3.689266811938284E-4, + "99.9" : 3.689266811938284E-4, + "99.99" : 3.689266811938284E-4, + "99.999" : 3.689266811938284E-4, + "99.9999" : 3.689266811938284E-4, + "100.0" : 3.689266811938284E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.547972581367566E-4, + 3.546447875159397E-4, + 3.5484487245150876E-4 + ], + [ + 3.689266811938284E-4, + 3.686509718236753E-4, + 3.6845111468455493E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12356891125388027, + "scoreError" : 0.0011513017325794671, + "scoreConfidence" : [ + 0.1224176095213008, + 0.12472021298645973 + ], + "scorePercentiles" : { + "0.0" : 0.12313493344743517, + "50.0" : 0.12351449757675095, + "90.0" : 0.12414115408106263, + "95.0" : 0.12414115408106263, + "99.0" : 0.12414115408106263, + "99.9" : 0.12414115408106263, + "99.99" : 0.12414115408106263, + "99.999" : 0.12414115408106263, + "99.9999" : 0.12414115408106263, + "100.0" : 0.12414115408106263 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12323341219238684, + 0.12327484595850643, + 0.12313493344743517 + ], + [ + 0.12414115408106263, + 0.12387497264889505, + 0.12375414919499549 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012897936102508669, + "scoreError" : 4.191945820707046E-5, + "scoreConfidence" : [ + 0.012856016644301598, + 0.01293985556071574 + ], + "scorePercentiles" : { + "0.0" : 0.012877975964869354, + "50.0" : 0.012898875423619078, + "90.0" : 0.012914283443619664, + "95.0" : 0.012914283443619664, + "99.0" : 0.012914283443619664, + "99.9" : 0.012914283443619664, + "99.99" : 0.012914283443619664, + "99.999" : 0.012914283443619664, + "99.9999" : 0.012914283443619664, + "100.0" : 0.012914283443619664 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012914283443619664, + 0.012906736482963345, + 0.012911547629407459 + ], + [ + 0.012891014364274813, + 0.012886058729917375, + 0.012877975964869354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9866651210372711, + "scoreError" : 0.02733537609581743, + "scoreConfidence" : [ + 0.9593297449414537, + 1.0140004971330885 + ], + "scorePercentiles" : { + "0.0" : 0.9762133196993362, + "50.0" : 0.9857869378481827, + "90.0" : 0.9977272287738203, + "95.0" : 0.9977272287738203, + "99.0" : 0.9977272287738203, + "99.9" : 0.9977272287738203, + "99.99" : 0.9977272287738203, + "99.999" : 0.9977272287738203, + "99.9999" : 0.9977272287738203, + "100.0" : 0.9977272287738203 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9799263633512983, + 0.977947805691375, + 0.9762133196993362 + ], + [ + 0.9977272287738203, + 0.991647512345067, + 0.9965284963627304 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010752751417349321, + "scoreError" : 3.84877393380212E-4, + "scoreConfidence" : [ + 0.010367874023969109, + 0.011137628810729534 + ], + "scorePercentiles" : { + "0.0" : 0.010622569864969365, + "50.0" : 0.010753898425173231, + "90.0" : 0.010880908953219899, + "95.0" : 0.010880908953219899, + "99.0" : 0.010880908953219899, + "99.9" : 0.010880908953219899, + "99.99" : 0.010880908953219899, + "99.999" : 0.010880908953219899, + "99.9999" : 0.010880908953219899, + "100.0" : 0.010880908953219899 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010622569864969365, + 0.010627355154230526, + 0.010632584495092119 + ], + [ + 0.010877877681329678, + 0.010880908953219899, + 0.010875212355254344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.132369830691392, + "scoreError" : 0.2254012314917079, + "scoreConfidence" : [ + 2.906968599199684, + 3.3577710621830996 + ], + "scorePercentiles" : { + "0.0" : 3.054211153846154, + "50.0" : 3.1344008644659658, + "90.0" : 3.207172176282051, + "95.0" : 3.207172176282051, + "99.0" : 3.207172176282051, + "99.9" : 3.207172176282051, + "99.99" : 3.207172176282051, + "99.999" : 3.207172176282051, + "99.9999" : 3.207172176282051, + "100.0" : 3.207172176282051 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0583114648318044, + 3.064661156862745, + 3.054211153846154 + ], + [ + 3.207172176282051, + 3.2041405720691865, + 3.20572246025641 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.755751717843389, + "scoreError" : 0.224103079278987, + "scoreConfidence" : [ + 2.531648638564402, + 2.9798547971223757 + ], + "scorePercentiles" : { + "0.0" : 2.6799126232583066, + "50.0" : 2.7488218531539115, + "90.0" : 2.8446509729806597, + "95.0" : 2.8446509729806597, + "99.0" : 2.8446509729806597, + "99.9" : 2.8446509729806597, + "99.99" : 2.8446509729806597, + "99.999" : 2.8446509729806597, + "99.9999" : 2.8446509729806597, + "100.0" : 2.8446509729806597 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.807409103564412, + 2.831377642412231, + 2.8446509729806597 + ], + [ + 2.6902346027434105, + 2.680925362101313, + 2.6799126232583066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18069378773291658, + "scoreError" : 0.007482142358572619, + "scoreConfidence" : [ + 0.17321164537434397, + 0.1881759300914892 + ], + "scorePercentiles" : { + "0.0" : 0.1773874220487805, + "50.0" : 0.1805687114124219, + "90.0" : 0.18402020941059566, + "95.0" : 0.18402020941059566, + "99.0" : 0.18402020941059566, + "99.9" : 0.18402020941059566, + "99.99" : 0.18402020941059566, + "99.999" : 0.18402020941059566, + "99.9999" : 0.18402020941059566, + "100.0" : 0.18402020941059566 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18183246037056566, + 0.17853424317569136, + 0.1773874220487805 + ], + [ + 0.1830834289375881, + 0.18402020941059566, + 0.17930496245427813 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32073315389110973, + "scoreError" : 0.004118638267239754, + "scoreConfidence" : [ + 0.31661451562387, + 0.3248517921583495 + ], + "scorePercentiles" : { + "0.0" : 0.3193641372273497, + "50.0" : 0.32055670670649206, + "90.0" : 0.3223893649376189, + "95.0" : 0.3223893649376189, + "99.0" : 0.3223893649376189, + "99.9" : 0.3223893649376189, + "99.99" : 0.3223893649376189, + "99.999" : 0.3223893649376189, + "99.9999" : 0.3223893649376189, + "100.0" : 0.3223893649376189 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31944930279508066, + 0.3194147597738597, + 0.3193641372273497 + ], + [ + 0.3223893649376189, + 0.32166411061790345, + 0.3221172479948462 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14074623102859005, + "scoreError" : 0.013656340907119615, + "scoreConfidence" : [ + 0.12708989012147043, + 0.15440257193570966 + ], + "scorePercentiles" : { + "0.0" : 0.13624503378792627, + "50.0" : 0.14074474274269233, + "90.0" : 0.1452655243822722, + "95.0" : 0.1452655243822722, + "99.0" : 0.1452655243822722, + "99.9" : 0.1452655243822722, + "99.99" : 0.1452655243822722, + "99.999" : 0.1452655243822722, + "99.9999" : 0.1452655243822722, + "100.0" : 0.1452655243822722 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14520759298948713, + 0.1452655243822722, + 0.14510113045749357 + ], + [ + 0.13638835502789107, + 0.13624503378792627, + 0.13626974952646997 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4048787683522633, + "scoreError" : 0.014694050411327732, + "scoreConfidence" : [ + 0.39018471794093557, + 0.419572818763591 + ], + "scorePercentiles" : { + "0.0" : 0.39963506242007674, + "50.0" : 0.4047466854531962, + "90.0" : 0.41064748790703404, + "95.0" : 0.41064748790703404, + "99.0" : 0.41064748790703404, + "99.9" : 0.41064748790703404, + "99.99" : 0.41064748790703404, + "99.999" : 0.41064748790703404, + "99.9999" : 0.41064748790703404, + "100.0" : 0.41064748790703404 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4007099738740183, + 0.400065582349882, + 0.39963506242007674 + ], + [ + 0.4094311065301945, + 0.41064748790703404, + 0.4087833970323741 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15720273461936463, + "scoreError" : 0.010275625071061818, + "scoreConfidence" : [ + 0.14692710954830282, + 0.16747835969042643 + ], + "scorePercentiles" : { + "0.0" : 0.15366278443122974, + "50.0" : 0.15673182414429515, + "90.0" : 0.1612035853147417, + "95.0" : 0.1612035853147417, + "99.0" : 0.1612035853147417, + "99.9" : 0.1612035853147417, + "99.99" : 0.1612035853147417, + "99.999" : 0.1612035853147417, + "99.9999" : 0.1612035853147417, + "100.0" : 0.1612035853147417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15921509982486864, + 0.1612035853147417, + 0.1610284515152491 + ], + [ + 0.1538579381663769, + 0.15366278443122974, + 0.15424854846372163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048078161137925936, + "scoreError" : 0.005000568832200431, + "scoreConfidence" : [ + 0.043077592305725505, + 0.053078729970126366 + ], + "scorePercentiles" : { + "0.0" : 0.04627695980897114, + "50.0" : 0.0481695254169037, + "90.0" : 0.050022558673022764, + "95.0" : 0.050022558673022764, + "99.0" : 0.050022558673022764, + "99.9" : 0.050022558673022764, + "99.99" : 0.050022558673022764, + "99.999" : 0.050022558673022764, + "99.9999" : 0.050022558673022764, + "100.0" : 0.050022558673022764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.050022558673022764, + 0.04953634246439628, + 0.04950160851314493 + ], + [ + 0.046837442320662455, + 0.04629405504735804, + 0.04627695980897114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8575413.919945104, + "scoreError" : 164706.9264814469, + "scoreConfidence" : [ + 8410706.993463658, + 8740120.84642655 + ], + "scorePercentiles" : { + "0.0" : 8458832.218089603, + "50.0" : 8591315.29586412, + "90.0" : 8622857.265517242, + "95.0" : 8622857.265517242, + "99.0" : 8622857.265517242, + "99.9" : 8622857.265517242, + "99.99" : 8622857.265517242, + "99.999" : 8622857.265517242, + "99.9999" : 8622857.265517242, + "100.0" : 8622857.265517242 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8585675.61888412, + 8585682.228326181, + 8458832.218089603 + ], + [ + 8602487.825451419, + 8622857.265517242, + 8596948.363402061 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-16T23:25:50Z-d5fdf3a58cfc02adc0ffca775bcf55f27036025f-jdk17.json b/performance-results/2025-05-16T23:25:50Z-d5fdf3a58cfc02adc0ffca775bcf55f27036025f-jdk17.json new file mode 100644 index 0000000000..1278df91d4 --- /dev/null +++ b/performance-results/2025-05-16T23:25:50Z-d5fdf3a58cfc02adc0ffca775bcf55f27036025f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3485332952594336, + "scoreError" : 0.04879126773174917, + "scoreConfidence" : [ + 3.2997420275276843, + 3.397324562991183 + ], + "scorePercentiles" : { + "0.0" : 3.3412172259327924, + "50.0" : 3.348830052853981, + "90.0" : 3.355255849396979, + "95.0" : 3.355255849396979, + "99.0" : 3.355255849396979, + "99.9" : 3.355255849396979, + "99.99" : 3.355255849396979, + "99.999" : 3.355255849396979, + "99.9999" : 3.355255849396979, + "100.0" : 3.355255849396979 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3412172259327924, + 3.355255849396979 + ], + [ + 3.3428243664670387, + 3.3548357392409236 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6916768527424648, + "scoreError" : 0.009872646749575645, + "scoreConfidence" : [ + 1.6818042059928893, + 1.7015494994920404 + ], + "scorePercentiles" : { + "0.0" : 1.6907214860064301, + "50.0" : 1.6910134608650778, + "90.0" : 1.6939590032332736, + "95.0" : 1.6939590032332736, + "99.0" : 1.6939590032332736, + "99.9" : 1.6939590032332736, + "99.99" : 1.6939590032332736, + "99.999" : 1.6939590032332736, + "99.9999" : 1.6939590032332736, + "100.0" : 1.6939590032332736 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6907214860064301, + 1.6939590032332736 + ], + [ + 1.6910402200619792, + 1.6909867016681763 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8461978928693442, + "scoreError" : 0.041057934226326614, + "scoreConfidence" : [ + 0.8051399586430176, + 0.8872558270956709 + ], + "scorePercentiles" : { + "0.0" : 0.8387615585495802, + "50.0" : 0.8465910640552544, + "90.0" : 0.8528478848172879, + "95.0" : 0.8528478848172879, + "99.0" : 0.8528478848172879, + "99.9" : 0.8528478848172879, + "99.99" : 0.8528478848172879, + "99.999" : 0.8528478848172879, + "99.9999" : 0.8528478848172879, + "100.0" : 0.8528478848172879 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8433291474731703, + 0.8498529806373385 + ], + [ + 0.8387615585495802, + 0.8528478848172879 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.256599471459527, + "scoreError" : 0.2787524220185262, + "scoreConfidence" : [ + 15.977847049441001, + 16.535351893478055 + ], + "scorePercentiles" : { + "0.0" : 16.155066260423812, + "50.0" : 16.26108550605796, + "90.0" : 16.355515477817196, + "95.0" : 16.355515477817196, + "99.0" : 16.355515477817196, + "99.9" : 16.355515477817196, + "99.99" : 16.355515477817196, + "99.999" : 16.355515477817196, + "99.9999" : 16.355515477817196, + "100.0" : 16.355515477817196 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.182277888526613, + 16.16168199143196, + 16.155066260423812 + ], + [ + 16.34516208696827, + 16.33989312358931, + 16.355515477817196 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2683.9936271796705, + "scoreError" : 19.319469889376673, + "scoreConfidence" : [ + 2664.674157290294, + 2703.313097069047 + ], + "scorePercentiles" : { + "0.0" : 2676.389209418719, + "50.0" : 2683.8525718996325, + "90.0" : 2691.329297784617, + "95.0" : 2691.329297784617, + "99.0" : 2691.329297784617, + "99.9" : 2691.329297784617, + "99.99" : 2691.329297784617, + "99.999" : 2691.329297784617, + "99.9999" : 2691.329297784617, + "100.0" : 2691.329297784617 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2688.3946117641317, + 2691.329297784617, + 2690.758881758454 + ], + [ + 2677.7792303169663, + 2676.389209418719, + 2679.3105320351333 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77142.05573032568, + "scoreError" : 220.90521261295947, + "scoreConfidence" : [ + 76921.15051771273, + 77362.96094293863 + ], + "scorePercentiles" : { + "0.0" : 77054.66709590497, + "50.0" : 77143.46969524735, + "90.0" : 77224.817896545, + "95.0" : 77224.817896545, + "99.0" : 77224.817896545, + "99.9" : 77224.817896545, + "99.99" : 77224.817896545, + "99.999" : 77224.817896545, + "99.9999" : 77224.817896545, + "100.0" : 77224.817896545 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77202.83787507354, + 77224.817896545, + 77211.83131580667 + ], + [ + 77084.10151542115, + 77074.07868320274, + 77054.66709590497 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.5613405009665, + "scoreError" : 2.097969084329703, + "scoreConfidence" : [ + 359.4633714166368, + 363.65930958529617 + ], + "scorePercentiles" : { + "0.0" : 360.768968493252, + "50.0" : 361.4501338279872, + "90.0" : 362.76065577734784, + "95.0" : 362.76065577734784, + "99.0" : 362.76065577734784, + "99.9" : 362.76065577734784, + "99.99" : 362.76065577734784, + "99.999" : 362.76065577734784, + "99.9999" : 362.76065577734784, + "100.0" : 362.76065577734784 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.768968493252, + 361.5579749957365, + 360.8913829603599 + ], + [ + 361.34229266023794, + 362.0467681188648, + 362.76065577734784 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.41286281722006, + "scoreError" : 2.7658785609669714, + "scoreConfidence" : [ + 112.64698425625309, + 118.17874137818703 + ], + "scorePercentiles" : { + "0.0" : 114.46377517976738, + "50.0" : 115.3826217566801, + "90.0" : 116.43094615643359, + "95.0" : 116.43094615643359, + "99.0" : 116.43094615643359, + "99.9" : 116.43094615643359, + "99.99" : 116.43094615643359, + "99.999" : 116.43094615643359, + "99.9999" : 116.43094615643359, + "100.0" : 116.43094615643359 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.5410049109041, + 114.54011354922763, + 114.46377517976738 + ], + [ + 116.43094615643359, + 116.2242386024561, + 116.27709850453152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06123955041553603, + "scoreError" : 6.686315176849867E-4, + "scoreConfidence" : [ + 0.060570918897851045, + 0.06190818193322102 + ], + "scorePercentiles" : { + "0.0" : 0.06098943727358111, + "50.0" : 0.06121367408569922, + "90.0" : 0.06153322701149425, + "95.0" : 0.06153322701149425, + "99.0" : 0.06153322701149425, + "99.9" : 0.06153322701149425, + "99.99" : 0.06153322701149425, + "99.999" : 0.06153322701149425, + "99.9999" : 0.06153322701149425, + "100.0" : 0.06153322701149425 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061380435174102785, + 0.061441730188377834, + 0.06153322701149425 + ], + [ + 0.06098943727358111, + 0.06104555984836461, + 0.061046912997295665 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6379009231795E-4, + "scoreError" : 3.9808509128719546E-5, + "scoreConfidence" : [ + 3.2398158318923046E-4, + 4.0359860144666956E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5024822091671396E-4, + "50.0" : 3.639527746232146E-4, + "90.0" : 3.768244804063268E-4, + "95.0" : 3.768244804063268E-4, + "99.0" : 3.768244804063268E-4, + "99.9" : 3.768244804063268E-4, + "99.99" : 3.768244804063268E-4, + "99.999" : 3.768244804063268E-4, + "99.9999" : 3.768244804063268E-4, + "100.0" : 3.768244804063268E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5123385198576916E-4, + 3.510211961113107E-4, + 3.5024822091671396E-4 + ], + [ + 3.768244804063268E-4, + 3.767411072269191E-4, + 3.7667169726066E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12497599318251795, + "scoreError" : 0.004576699170764069, + "scoreConfidence" : [ + 0.12039929401175388, + 0.129552692353282 + ], + "scorePercentiles" : { + "0.0" : 0.12328780417442334, + "50.0" : 0.12500886529403304, + "90.0" : 0.1266213751851805, + "95.0" : 0.1266213751851805, + "99.0" : 0.1266213751851805, + "99.9" : 0.1266213751851805, + "99.99" : 0.1266213751851805, + "99.999" : 0.1266213751851805, + "99.9999" : 0.1266213751851805, + "100.0" : 0.1266213751851805 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12636516821248958, + 0.1266213751851805, + 0.12639278700707784 + ], + [ + 0.12365256237557652, + 0.12328780417442334, + 0.12353626214035998 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01293874240767341, + "scoreError" : 2.1020577336480913E-4, + "scoreConfidence" : [ + 0.0127285366343086, + 0.01314894818103822 + ], + "scorePercentiles" : { + "0.0" : 0.012866964603477892, + "50.0" : 0.012937122921233453, + "90.0" : 0.01302185110156481, + "95.0" : 0.01302185110156481, + "99.0" : 0.01302185110156481, + "99.9" : 0.01302185110156481, + "99.99" : 0.01302185110156481, + "99.999" : 0.01302185110156481, + "99.9999" : 0.01302185110156481, + "100.0" : 0.01302185110156481 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012869310811889037, + 0.01287609668148686, + 0.012866964603477892 + ], + [ + 0.012998149160980048, + 0.013000082086641811, + 0.01302185110156481 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0507447085083805, + "scoreError" : 0.18511727393568816, + "scoreConfidence" : [ + 0.8656274345726924, + 1.2358619824440686 + ], + "scorePercentiles" : { + "0.0" : 0.9882363250988142, + "50.0" : 1.0519249063666862, + "90.0" : 1.1120452586456133, + "95.0" : 1.1120452586456133, + "99.0" : 1.1120452586456133, + "99.9" : 1.1120452586456133, + "99.99" : 1.1120452586456133, + "99.999" : 1.1120452586456133, + "99.9999" : 1.1120452586456133, + "100.0" : 1.1120452586456133 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.109943247835738, + 1.1120452586456133, + 1.1109503237058431 + ], + [ + 0.9939065648976346, + 0.9882363250988142, + 0.9893865308666403 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01114496222190449, + "scoreError" : 9.845403968771883E-4, + "scoreConfidence" : [ + 0.010160421825027301, + 0.012129502618781677 + ], + "scorePercentiles" : { + "0.0" : 0.010818756617168178, + "50.0" : 0.011145967326004973, + "90.0" : 0.011474907342171877, + "95.0" : 0.011474907342171877, + "99.0" : 0.011474907342171877, + "99.9" : 0.011474907342171877, + "99.99" : 0.011474907342171877, + "99.999" : 0.011474907342171877, + "99.9999" : 0.011474907342171877, + "100.0" : 0.011474907342171877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01082326582045582, + 0.010831517569151253, + 0.010818756617168178 + ], + [ + 0.011474907342171877, + 0.011460417082858694, + 0.011460908899621113 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.259013992367413, + "scoreError" : 0.05551585960771413, + "scoreConfidence" : [ + 3.203498132759699, + 3.314529851975127 + ], + "scorePercentiles" : { + "0.0" : 3.229602766946417, + "50.0" : 3.258843932496002, + "90.0" : 3.284254667760998, + "95.0" : 3.284254667760998, + "99.0" : 3.284254667760998, + "99.9" : 3.284254667760998, + "99.99" : 3.284254667760998, + "99.999" : 3.284254667760998, + "99.9999" : 3.284254667760998, + "100.0" : 3.284254667760998 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2652488929503916, + 3.284254667760998, + 3.2747843798297316 + ], + [ + 3.229602766946417, + 3.2524389720416127, + 3.2477542746753247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.736860866743806, + "scoreError" : 0.06131591517156935, + "scoreConfidence" : [ + 2.675544951572237, + 2.7981767819153753 + ], + "scorePercentiles" : { + "0.0" : 2.715666369264187, + "50.0" : 2.729530704848, + "90.0" : 2.766776043430152, + "95.0" : 2.766776043430152, + "99.0" : 2.766776043430152, + "99.9" : 2.766776043430152, + "99.99" : 2.766776043430152, + "99.999" : 2.766776043430152, + "99.9999" : 2.766776043430152, + "100.0" : 2.766776043430152 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.736017878522572, + 2.7602901918299754, + 2.766776043430152 + ], + [ + 2.715666369264187, + 2.7230435311734276, + 2.719371186242523 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1762838807846657, + "scoreError" : 0.002834068184915265, + "scoreConfidence" : [ + 0.17344981259975042, + 0.17911794896958097 + ], + "scorePercentiles" : { + "0.0" : 0.17529885929146144, + "50.0" : 0.17625626323278742, + "90.0" : 0.17736376577631158, + "95.0" : 0.17736376577631158, + "99.0" : 0.17736376577631158, + "99.9" : 0.17736376577631158, + "99.99" : 0.17736376577631158, + "99.999" : 0.17736376577631158, + "99.9999" : 0.17736376577631158, + "100.0" : 0.17736376577631158 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17713494489416348, + 0.17710818466633607, + 0.17736376577631158 + ], + [ + 0.17540434179923878, + 0.17539318828048267, + 0.17529885929146144 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31711075907888536, + "scoreError" : 0.015524970061448703, + "scoreConfidence" : [ + 0.30158578901743666, + 0.33263572914033407 + ], + "scorePercentiles" : { + "0.0" : 0.31133116599732263, + "50.0" : 0.31737682917524723, + "90.0" : 0.3224552843001322, + "95.0" : 0.3224552843001322, + "99.0" : 0.3224552843001322, + "99.9" : 0.3224552843001322, + "99.99" : 0.3224552843001322, + "99.999" : 0.3224552843001322, + "99.9999" : 0.3224552843001322, + "100.0" : 0.3224552843001322 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.313052211557726, + 0.3118787157960393, + 0.31133116599732263 + ], + [ + 0.3222457300293236, + 0.3224552843001322, + 0.32170144679276846 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14568844816893337, + "scoreError" : 0.010220215553954378, + "scoreConfidence" : [ + 0.13546823261497898, + 0.15590866372288775 + ], + "scorePercentiles" : { + "0.0" : 0.13968616668296294, + "50.0" : 0.146890473771341, + "90.0" : 0.1493058369613903, + "95.0" : 0.1493058369613903, + "99.0" : 0.1493058369613903, + "99.9" : 0.1493058369613903, + "99.99" : 0.1493058369613903, + "99.999" : 0.1493058369613903, + "99.9999" : 0.1493058369613903, + "100.0" : 0.1493058369613903 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1493058369613903, + 0.14802655261482897, + 0.14811119206730058 + ], + [ + 0.14575439492785308, + 0.1432465457592643, + 0.13968616668296294 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3959323552236957, + "scoreError" : 0.04674963050880147, + "scoreConfidence" : [ + 0.3491827247148942, + 0.4426819857324972 + ], + "scorePercentiles" : { + "0.0" : 0.3808367657945847, + "50.0" : 0.3937994517094966, + "90.0" : 0.41643206408761557, + "95.0" : 0.41643206408761557, + "99.0" : 0.41643206408761557, + "99.9" : 0.41643206408761557, + "99.99" : 0.41643206408761557, + "99.999" : 0.41643206408761557, + "99.9999" : 0.41643206408761557, + "100.0" : 0.41643206408761557 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41643206408761557, + 0.40973263051583564, + 0.4064258172396976 + ], + [ + 0.3808367657945847, + 0.3809937675251448, + 0.38117308617929563 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15748971492947586, + "scoreError" : 0.004117480189868355, + "scoreConfidence" : [ + 0.1533722347396075, + 0.1616071951193442 + ], + "scorePercentiles" : { + "0.0" : 0.1562519462977141, + "50.0" : 0.1570571049900381, + "90.0" : 0.1598164303453566, + "95.0" : 0.1598164303453566, + "99.0" : 0.1598164303453566, + "99.9" : 0.1598164303453566, + "99.99" : 0.1598164303453566, + "99.999" : 0.1598164303453566, + "99.9999" : 0.1598164303453566, + "100.0" : 0.1598164303453566 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15635164122889306, + 0.1562519462977141, + 0.1562733953150394 + ], + [ + 0.1598164303453566, + 0.15848230763866877, + 0.1577625687511832 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047417499189958266, + "scoreError" : 0.0010754251010530894, + "scoreConfidence" : [ + 0.04634207408890518, + 0.048492924291011354 + ], + "scorePercentiles" : { + "0.0" : 0.04706691139800534, + "50.0" : 0.04731835108258424, + "90.0" : 0.0480060865008881, + "95.0" : 0.0480060865008881, + "99.0" : 0.0480060865008881, + "99.9" : 0.0480060865008881, + "99.99" : 0.0480060865008881, + "99.999" : 0.0480060865008881, + "99.9999" : 0.0480060865008881, + "100.0" : 0.0480060865008881 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04715241316094718, + 0.04708900419556711, + 0.04706691139800534 + ], + [ + 0.0480060865008881, + 0.0477062908801206, + 0.047484289004221296 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8418890.226238409, + "scoreError" : 359756.97733033716, + "scoreConfidence" : [ + 8059133.248908072, + 8778647.203568745 + ], + "scorePercentiles" : { + "0.0" : 8300239.660580913, + "50.0" : 8416218.803516183, + "90.0" : 8541675.653287789, + "95.0" : 8541675.653287789, + "99.0" : 8541675.653287789, + "99.9" : 8541675.653287789, + "99.99" : 8541675.653287789, + "99.999" : 8541675.653287789, + "99.9999" : 8541675.653287789, + "100.0" : 8541675.653287789 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8541675.653287789, + 8538739.727815699, + 8527320.139812447 + ], + [ + 8300239.660580913, + 8305117.467219917, + 8300248.708713693 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-19T12:39:17Z-f1a512cab0cc343e4da7f6ecc15afabaf521a9c1-jdk17.json b/performance-results/2025-05-19T12:39:17Z-f1a512cab0cc343e4da7f6ecc15afabaf521a9c1-jdk17.json new file mode 100644 index 0000000000..0132b3cca8 --- /dev/null +++ b/performance-results/2025-05-19T12:39:17Z-f1a512cab0cc343e4da7f6ecc15afabaf521a9c1-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3121402580415644, + "scoreError" : 0.02028391942989787, + "scoreConfidence" : [ + 3.2918563386116664, + 3.3324241774714625 + ], + "scorePercentiles" : { + "0.0" : 3.308974889215251, + "50.0" : 3.311580657577065, + "90.0" : 3.316424827796877, + "95.0" : 3.316424827796877, + "99.0" : 3.316424827796877, + "99.9" : 3.316424827796877, + "99.99" : 3.316424827796877, + "99.999" : 3.316424827796877, + "99.9999" : 3.316424827796877, + "100.0" : 3.316424827796877 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.308974889215251, + 3.316424827796877 + ], + [ + 3.311053501353287, + 3.3121078138008424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6735854199994473, + "scoreError" : 0.023589887737052586, + "scoreConfidence" : [ + 1.6499955322623947, + 1.6971753077365 + ], + "scorePercentiles" : { + "0.0" : 1.6690259000647742, + "50.0" : 1.6743220071926057, + "90.0" : 1.676671765547804, + "95.0" : 1.676671765547804, + "99.0" : 1.676671765547804, + "99.9" : 1.676671765547804, + "99.99" : 1.676671765547804, + "99.999" : 1.676671765547804, + "99.9999" : 1.676671765547804, + "100.0" : 1.676671765547804 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.672250785351506, + 1.6763932290337056 + ], + [ + 1.6690259000647742, + 1.676671765547804 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8430090854288081, + "scoreError" : 0.026911393872755086, + "scoreConfidence" : [ + 0.816097691556053, + 0.8699204793015632 + ], + "scorePercentiles" : { + "0.0" : 0.8378909150493596, + "50.0" : 0.8433555202774811, + "90.0" : 0.8474343861109108, + "95.0" : 0.8474343861109108, + "99.0" : 0.8474343861109108, + "99.9" : 0.8474343861109108, + "99.99" : 0.8474343861109108, + "99.999" : 0.8474343861109108, + "99.9999" : 0.8474343861109108, + "100.0" : 0.8474343861109108 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8378909150493596, + 0.8450892865944613 + ], + [ + 0.8416217539605009, + 0.8474343861109108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.938019006834173, + "scoreError" : 0.15457242385146122, + "scoreConfidence" : [ + 15.783446582982712, + 16.092591430685633 + ], + "scorePercentiles" : { + "0.0" : 15.867640865557025, + "50.0" : 15.946860258386561, + "90.0" : 16.016217456306233, + "95.0" : 16.016217456306233, + "99.0" : 16.016217456306233, + "99.9" : 16.016217456306233, + "99.99" : 16.016217456306233, + "99.999" : 16.016217456306233, + "99.9999" : 16.016217456306233, + "100.0" : 16.016217456306233 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.884564970388242, + 16.016217456306233, + 15.959689174101978 + ], + [ + 15.965970231980414, + 15.934031342671144, + 15.867640865557025 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2725.61884870853, + "scoreError" : 113.64970415838532, + "scoreConfidence" : [ + 2611.969144550145, + 2839.2685528669153 + ], + "scorePercentiles" : { + "0.0" : 2680.388351024052, + "50.0" : 2716.9758113546254, + "90.0" : 2792.2587875657173, + "95.0" : 2792.2587875657173, + "99.0" : 2792.2587875657173, + "99.9" : 2792.2587875657173, + "99.99" : 2792.2587875657173, + "99.999" : 2792.2587875657173, + "99.9999" : 2792.2587875657173, + "100.0" : 2792.2587875657173 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2707.811082218431, + 2697.0972000224874, + 2680.388351024052 + ], + [ + 2726.14054049082, + 2792.2587875657173, + 2750.0171309296725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75810.08383031965, + "scoreError" : 3141.8662676566746, + "scoreConfidence" : [ + 72668.21756266298, + 78951.95009797633 + ], + "scorePercentiles" : { + "0.0" : 74679.74027226919, + "50.0" : 75850.58456337653, + "90.0" : 76832.58544107577, + "95.0" : 76832.58544107577, + "99.0" : 76832.58544107577, + "99.9" : 76832.58544107577, + "99.99" : 76832.58544107577, + "99.999" : 76832.58544107577, + "99.9999" : 76832.58544107577, + "100.0" : 76832.58544107577 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74679.74027226919, + 74814.6829365795, + 74872.20956046304 + ], + [ + 76832.32520524043, + 76832.58544107577, + 76828.95956629 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 341.32415407808384, + "scoreError" : 7.543962031610742, + "scoreConfidence" : [ + 333.7801920464731, + 348.8681161096946 + ], + "scorePercentiles" : { + "0.0" : 337.8196560471646, + "50.0" : 341.8869142863537, + "90.0" : 343.8692681627958, + "95.0" : 343.8692681627958, + "99.0" : 343.8692681627958, + "99.9" : 343.8692681627958, + "99.99" : 343.8692681627958, + "99.999" : 343.8692681627958, + "99.9999" : 343.8692681627958, + "100.0" : 343.8692681627958 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 343.1918644652569, + 343.8692681627958, + 343.8271167655657 + ], + [ + 337.8196560471646, + 338.65505492026915, + 340.5819641074505 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.27834841420095, + "scoreError" : 3.889262504071276, + "scoreConfidence" : [ + 108.38908591012967, + 116.16761091827223 + ], + "scorePercentiles" : { + "0.0" : 110.83269828479163, + "50.0" : 112.22137383181743, + "90.0" : 114.79967199761434, + "95.0" : 114.79967199761434, + "99.0" : 114.79967199761434, + "99.9" : 114.79967199761434, + "99.99" : 114.79967199761434, + "99.999" : 114.79967199761434, + "99.9999" : 114.79967199761434, + "100.0" : 114.79967199761434 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.83269828479163, + 112.33188657205643, + 112.37962813567452 + ], + [ + 111.21534440349028, + 112.11086109157844, + 114.79967199761434 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06276492044795608, + "scoreError" : 7.965691903985652E-4, + "scoreConfidence" : [ + 0.061968351257557515, + 0.06356148963835465 + ], + "scorePercentiles" : { + "0.0" : 0.06234056212128768, + "50.0" : 0.06283716544870513, + "90.0" : 0.06311808624302558, + "95.0" : 0.06311808624302558, + "99.0" : 0.06311808624302558, + "99.9" : 0.06311808624302558, + "99.99" : 0.06311808624302558, + "99.999" : 0.06311808624302558, + "99.9999" : 0.06311808624302558, + "100.0" : 0.06311808624302558 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06291894641902138, + 0.06291722101143814, + 0.06311808624302558 + ], + [ + 0.06234056212128768, + 0.0625375970069916, + 0.06275710988597212 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.853481788238693E-4, + "scoreError" : 5.249140156433392E-5, + "scoreConfidence" : [ + 3.328567772595354E-4, + 4.3783958038820324E-4 + ], + "scorePercentiles" : { + "0.0" : 3.648880582091008E-4, + "50.0" : 3.8651054012512416E-4, + "90.0" : 4.0370106381488487E-4, + "95.0" : 4.0370106381488487E-4, + "99.0" : 4.0370106381488487E-4, + "99.9" : 4.0370106381488487E-4, + "99.99" : 4.0370106381488487E-4, + "99.999" : 4.0370106381488487E-4, + "99.9999" : 4.0370106381488487E-4, + "100.0" : 4.0370106381488487E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.71514461758944E-4, + 3.687461337037666E-4, + 3.648880582091008E-4 + ], + [ + 4.015066184913043E-4, + 4.017327369652154E-4, + 4.0370106381488487E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12482460744059132, + "scoreError" : 0.0010689589775819187, + "scoreConfidence" : [ + 0.1237556484630094, + 0.12589356641817323 + ], + "scorePercentiles" : { + "0.0" : 0.1241299858621717, + "50.0" : 0.12498991572853144, + "90.0" : 0.1251225155962614, + "95.0" : 0.1251225155962614, + "99.0" : 0.1251225155962614, + "99.9" : 0.1251225155962614, + "99.99" : 0.1251225155962614, + "99.999" : 0.1251225155962614, + "99.9999" : 0.1251225155962614, + "100.0" : 0.1251225155962614 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1241299858621717, + 0.12499992591435215, + 0.1251225155962614 + ], + [ + 0.12497990554271074, + 0.12507933626846443, + 0.12463597545958746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01313064531699191, + "scoreError" : 3.673643974808897E-5, + "scoreConfidence" : [ + 0.01309390887724382, + 0.01316738175674 + ], + "scorePercentiles" : { + "0.0" : 0.013115192152532236, + "50.0" : 0.013130055202360037, + "90.0" : 0.013148006523925662, + "95.0" : 0.013148006523925662, + "99.0" : 0.013148006523925662, + "99.9" : 0.013148006523925662, + "99.99" : 0.013148006523925662, + "99.999" : 0.013148006523925662, + "99.9999" : 0.013148006523925662, + "100.0" : 0.013148006523925662 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013129806353691265, + 0.013130304051028809, + 0.013115192152532236 + ], + [ + 0.013117695158503936, + 0.01314286766226956, + 0.013148006523925662 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0333822377778963, + "scoreError" : 0.28805500263543654, + "scoreConfidence" : [ + 0.7453272351424598, + 1.3214372404133328 + ], + "scorePercentiles" : { + "0.0" : 0.9373642665666886, + "50.0" : 1.0331401602532695, + "90.0" : 1.1285810742579845, + "95.0" : 1.1285810742579845, + "99.0" : 1.1285810742579845, + "99.9" : 1.1285810742579845, + "99.99" : 1.1285810742579845, + "99.999" : 1.1285810742579845, + "99.9999" : 1.1285810742579845, + "100.0" : 1.1285810742579845 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1285810742579845, + 1.1274754954904171, + 1.12537454056487 + ], + [ + 0.9373642665666886, + 0.940905779941669, + 0.9405922698457487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011185019594943302, + "scoreError" : 5.92307371630041E-4, + "scoreConfidence" : [ + 0.010592712223313261, + 0.011777326966573343 + ], + "scorePercentiles" : { + "0.0" : 0.010958918005983365, + "50.0" : 0.011187293368333495, + "90.0" : 0.011389528301113184, + "95.0" : 0.011389528301113184, + "99.0" : 0.011389528301113184, + "99.9" : 0.011389528301113184, + "99.99" : 0.011389528301113184, + "99.999" : 0.011389528301113184, + "99.9999" : 0.011389528301113184, + "100.0" : 0.011389528301113184 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010958918005983365, + 0.011015194562609736, + 0.011005476577649335 + ], + [ + 0.011359392174057254, + 0.011381607948246938, + 0.011389528301113184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.335579489186422, + "scoreError" : 0.06194368295443053, + "scoreConfidence" : [ + 3.2736358062319915, + 3.3975231721408528 + ], + "scorePercentiles" : { + "0.0" : 3.308568775132275, + "50.0" : 3.3403229046044913, + "90.0" : 3.359624419744795, + "95.0" : 3.359624419744795, + "99.0" : 3.359624419744795, + "99.9" : 3.359624419744795, + "99.99" : 3.359624419744795, + "99.999" : 3.359624419744795, + "99.9999" : 3.359624419744795, + "100.0" : 3.359624419744795 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3093267915287887, + 3.308568775132275, + 3.338261614152203 + ], + [ + 3.355311139503689, + 3.359624419744795, + 3.34238419505678 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9200156228834935, + "scoreError" : 0.03468371532879787, + "scoreConfidence" : [ + 2.8853319075546957, + 2.9546993382122912 + ], + "scorePercentiles" : { + "0.0" : 2.9046826526285217, + "50.0" : 2.918061654318713, + "90.0" : 2.935145964201878, + "95.0" : 2.935145964201878, + "99.0" : 2.935145964201878, + "99.9" : 2.935145964201878, + "99.99" : 2.935145964201878, + "99.999" : 2.935145964201878, + "99.9999" : 2.935145964201878, + "100.0" : 2.935145964201878 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.910921332654249, + 2.9138091704545452, + 2.9046826526285217 + ], + [ + 2.933220479178886, + 2.935145964201878, + 2.9223141381828803 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18249072178489034, + "scoreError" : 0.011949274627893655, + "scoreConfidence" : [ + 0.17054144715699668, + 0.194439996412784 + ], + "scorePercentiles" : { + "0.0" : 0.17864398808481752, + "50.0" : 0.18200473028051978, + "90.0" : 0.18827531001957978, + "95.0" : 0.18827531001957978, + "99.0" : 0.18827531001957978, + "99.9" : 0.18827531001957978, + "99.99" : 0.18827531001957978, + "99.999" : 0.18827531001957978, + "99.9999" : 0.18827531001957978, + "100.0" : 0.18827531001957978 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18523700585336939, + 0.18827531001957978, + 0.18522473663641414 + ], + [ + 0.17878472392462544, + 0.17877856619053578, + 0.17864398808481752 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3204501963942008, + "scoreError" : 0.0021333915829879137, + "scoreConfidence" : [ + 0.3183168048112129, + 0.3225835879771887 + ], + "scorePercentiles" : { + "0.0" : 0.31899667329101405, + "50.0" : 0.3206204946649439, + "90.0" : 0.3212193724665146, + "95.0" : 0.3212193724665146, + "99.0" : 0.3212193724665146, + "99.9" : 0.3212193724665146, + "99.99" : 0.3212193724665146, + "99.999" : 0.3212193724665146, + "99.9999" : 0.3212193724665146, + "100.0" : 0.3212193724665146 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3207515224196549, + 0.3204838529034739, + 0.320489466910233 + ], + [ + 0.31899667329101405, + 0.3212193724665146, + 0.3207602903743144 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1456780624236438, + "scoreError" : 0.006062498037854331, + "scoreConfidence" : [ + 0.13961556438578948, + 0.15174056046149814 + ], + "scorePercentiles" : { + "0.0" : 0.14327140853020817, + "50.0" : 0.14555049015311, + "90.0" : 0.1481327087647573, + "95.0" : 0.1481327087647573, + "99.0" : 0.1481327087647573, + "99.9" : 0.1481327087647573, + "99.99" : 0.1481327087647573, + "99.999" : 0.1481327087647573, + "99.9999" : 0.1481327087647573, + "100.0" : 0.1481327087647573 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1481327087647573, + 0.14700531095463498, + 0.14768764885101607 + ], + [ + 0.14409566935158502, + 0.1438756280896613, + 0.14327140853020817 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.393988910174538, + "scoreError" : 0.007616769645711548, + "scoreConfidence" : [ + 0.38637214052882646, + 0.4016056798202496 + ], + "scorePercentiles" : { + "0.0" : 0.39127959421707487, + "50.0" : 0.3938838809398213, + "90.0" : 0.3972072719942805, + "95.0" : 0.3972072719942805, + "99.0" : 0.3972072719942805, + "99.9" : 0.3972072719942805, + "99.99" : 0.3972072719942805, + "99.999" : 0.3972072719942805, + "99.9999" : 0.3972072719942805, + "100.0" : 0.3972072719942805 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39180001014731236, + 0.3915547898981989, + 0.39127959421707487 + ], + [ + 0.3972072719942805, + 0.3961240430580313, + 0.39596775173233023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15573958080067427, + "scoreError" : 0.0044784914690043556, + "scoreConfidence" : [ + 0.1512610893316699, + 0.16021807226967863 + ], + "scorePercentiles" : { + "0.0" : 0.15444332881853282, + "50.0" : 0.15536494872211853, + "90.0" : 0.1585405062225534, + "95.0" : 0.1585405062225534, + "99.0" : 0.1585405062225534, + "99.9" : 0.1585405062225534, + "99.99" : 0.1585405062225534, + "99.999" : 0.1585405062225534, + "99.9999" : 0.1585405062225534, + "100.0" : 0.1585405062225534 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1585405062225534, + 0.15625105103045264, + 0.15609995815057054 + ], + [ + 0.15444332881853282, + 0.1546299392936665, + 0.15447270128826965 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04802610219461675, + "scoreError" : 0.0013919515088104935, + "scoreConfidence" : [ + 0.04663415068580625, + 0.049418053703427244 + ], + "scorePercentiles" : { + "0.0" : 0.0475161795750221, + "50.0" : 0.04785542582467714, + "90.0" : 0.04871813496633636, + "95.0" : 0.04871813496633636, + "99.0" : 0.04871813496633636, + "99.9" : 0.04871813496633636, + "99.99" : 0.04871813496633636, + "99.999" : 0.04871813496633636, + "99.9999" : 0.04871813496633636, + "100.0" : 0.04871813496633636 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04871813496633636, + 0.04853959621591974, + 0.048006456477907716 + ], + [ + 0.04767185076106802, + 0.0475161795750221, + 0.04770439517144656 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9050300.601748051, + "scoreError" : 216867.14926966996, + "scoreConfidence" : [ + 8833433.45247838, + 9267167.751017721 + ], + "scorePercentiles" : { + "0.0" : 8902809.979537366, + "50.0" : 9071584.07643768, + "90.0" : 9107113.215650592, + "95.0" : 9107113.215650592, + "99.0" : 9107113.215650592, + "99.9" : 9107113.215650592, + "99.99" : 9107113.215650592, + "99.999" : 9107113.215650592, + "99.9999" : 9107113.215650592, + "100.0" : 9107113.215650592 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9107113.215650592, + 9051294.767420815, + 8902809.979537366 + ], + [ + 9042440.513562387, + 9106271.748862602, + 9091873.385454545 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-22T22:09:31Z-9ac3e6348793f5ce7536c5833a1dddb7cefb58ab-jdk17.json b/performance-results/2025-05-22T22:09:31Z-9ac3e6348793f5ce7536c5833a1dddb7cefb58ab-jdk17.json new file mode 100644 index 0000000000..3c820c84ef --- /dev/null +++ b/performance-results/2025-05-22T22:09:31Z-9ac3e6348793f5ce7536c5833a1dddb7cefb58ab-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.33689114770609, + "scoreError" : 0.040328856012277293, + "scoreConfidence" : [ + 3.296562291693813, + 3.3772200037183673 + ], + "scorePercentiles" : { + "0.0" : 3.3292767884336545, + "50.0" : 3.337568421406037, + "90.0" : 3.3431509595786317, + "95.0" : 3.3431509595786317, + "99.0" : 3.3431509595786317, + "99.9" : 3.3431509595786317, + "99.99" : 3.3431509595786317, + "99.999" : 3.3431509595786317, + "99.9999" : 3.3431509595786317, + "100.0" : 3.3431509595786317 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3345051958206513, + 3.3431509595786317 + ], + [ + 3.3292767884336545, + 3.3406316469914223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6831562025835927, + "scoreError" : 0.03442981630637006, + "scoreConfidence" : [ + 1.6487263862772226, + 1.7175860188899628 + ], + "scorePercentiles" : { + "0.0" : 1.678523315992677, + "50.0" : 1.681699102127212, + "90.0" : 1.6907032900872698, + "95.0" : 1.6907032900872698, + "99.0" : 1.6907032900872698, + "99.9" : 1.6907032900872698, + "99.99" : 1.6907032900872698, + "99.999" : 1.6907032900872698, + "99.9999" : 1.6907032900872698, + "100.0" : 1.6907032900872698 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6805819699008329, + 1.6907032900872698 + ], + [ + 1.678523315992677, + 1.6828162343535913 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8488580671569362, + "scoreError" : 0.020632400380486464, + "scoreConfidence" : [ + 0.8282256667764498, + 0.8694904675374227 + ], + "scorePercentiles" : { + "0.0" : 0.8450366414615168, + "50.0" : 0.8488991330101565, + "90.0" : 0.8525973611459151, + "95.0" : 0.8525973611459151, + "99.0" : 0.8525973611459151, + "99.9" : 0.8525973611459151, + "99.99" : 0.8525973611459151, + "99.999" : 0.8525973611459151, + "99.9999" : 0.8525973611459151, + "100.0" : 0.8525973611459151 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8498977799987801, + 0.8525973611459151 + ], + [ + 0.8450366414615168, + 0.8479004860215329 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.364539522171743, + "scoreError" : 0.2983349242996803, + "scoreConfidence" : [ + 16.066204597872062, + 16.662874446471424 + ], + "scorePercentiles" : { + "0.0" : 16.231913683651342, + "50.0" : 16.364767003662926, + "90.0" : 16.47296123647928, + "95.0" : 16.47296123647928, + "99.0" : 16.47296123647928, + "99.9" : 16.47296123647928, + "99.99" : 16.47296123647928, + "99.999" : 16.47296123647928, + "99.9999" : 16.47296123647928, + "100.0" : 16.47296123647928 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.231913683651342, + 16.293027639232772, + 16.285109276600682 + ], + [ + 16.47296123647928, + 16.43650636809308, + 16.46771892897332 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2757.516066190327, + "scoreError" : 44.67263750389502, + "scoreConfidence" : [ + 2712.8434286864317, + 2802.188703694222 + ], + "scorePercentiles" : { + "0.0" : 2739.672995709291, + "50.0" : 2758.206657395908, + "90.0" : 2773.9705683119923, + "95.0" : 2773.9705683119923, + "99.0" : 2773.9705683119923, + "99.9" : 2773.9705683119923, + "99.99" : 2773.9705683119923, + "99.999" : 2773.9705683119923, + "99.9999" : 2773.9705683119923, + "100.0" : 2773.9705683119923 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2739.672995709291, + 2743.3007782964974, + 2746.4913601598564 + ], + [ + 2773.9705683119923, + 2769.9219546319605, + 2771.7387400323655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 78137.43869305775, + "scoreError" : 237.38701687681254, + "scoreConfidence" : [ + 77900.05167618093, + 78374.82570993456 + ], + "scorePercentiles" : { + "0.0" : 78045.11995699845, + "50.0" : 78114.77731486593, + "90.0" : 78246.79995894844, + "95.0" : 78246.79995894844, + "99.0" : 78246.79995894844, + "99.9" : 78246.79995894844, + "99.99" : 78246.79995894844, + "99.999" : 78246.79995894844, + "99.9999" : 78246.79995894844, + "100.0" : 78246.79995894844 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78246.79995894844, + 78229.77685284622, + 78143.86728830791 + ], + [ + 78045.11995699845, + 78073.38075982152, + 78085.68734142394 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 366.4805760888209, + "scoreError" : 14.67950795879988, + "scoreConfidence" : [ + 351.801068130021, + 381.1600840476208 + ], + "scorePercentiles" : { + "0.0" : 361.4855469522038, + "50.0" : 366.5380425803455, + "90.0" : 371.4912375618814, + "95.0" : 371.4912375618814, + "99.0" : 371.4912375618814, + "99.9" : 371.4912375618814, + "99.99" : 371.4912375618814, + "99.999" : 371.4912375618814, + "99.9999" : 371.4912375618814, + "100.0" : 371.4912375618814 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 361.4855469522038, + 361.59691848165767, + 362.03732974525684 + ], + [ + 371.4912375618814, + 371.03875541543425, + 371.23366837649155 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.37575384165285, + "scoreError" : 0.6201983356151941, + "scoreConfidence" : [ + 116.75555550603765, + 117.99595217726805 + ], + "scorePercentiles" : { + "0.0" : 117.10847749977286, + "50.0" : 117.34181519017628, + "90.0" : 117.74357632450233, + "95.0" : 117.74357632450233, + "99.0" : 117.74357632450233, + "99.9" : 117.74357632450233, + "99.99" : 117.74357632450233, + "99.999" : 117.74357632450233, + "99.9999" : 117.74357632450233, + "100.0" : 117.74357632450233 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.24023340278019, + 117.3992610089999, + 117.10847749977286 + ], + [ + 117.47860544250914, + 117.28436937135264, + 117.74357632450233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06089952398349054, + "scoreError" : 3.006484522745726E-4, + "scoreConfidence" : [ + 0.06059887553121597, + 0.061200172435765116 + ], + "scorePercentiles" : { + "0.0" : 0.06077398178028162, + "50.0" : 0.06088298605387938, + "90.0" : 0.06104455426143647, + "95.0" : 0.06104455426143647, + "99.0" : 0.06104455426143647, + "99.9" : 0.06104455426143647, + "99.99" : 0.06104455426143647, + "99.999" : 0.06104455426143647, + "99.9999" : 0.06104455426143647, + "100.0" : 0.06104455426143647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060861840057452724, + 0.06077398178028162, + 0.060808475911050576 + ], + [ + 0.06104455426143647, + 0.06090413205030604, + 0.061004159840415795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.684864130484098E-4, + "scoreError" : 1.355533726832454E-6, + "scoreConfidence" : [ + 3.671308793215773E-4, + 3.6984194677524223E-4 + ], + "scorePercentiles" : { + "0.0" : 3.677474976396435E-4, + "50.0" : 3.6842054785400126E-4, + "90.0" : 3.6905014069388514E-4, + "95.0" : 3.6905014069388514E-4, + "99.0" : 3.6905014069388514E-4, + "99.9" : 3.6905014069388514E-4, + "99.99" : 3.6905014069388514E-4, + "99.999" : 3.6905014069388514E-4, + "99.9999" : 3.6905014069388514E-4, + "100.0" : 3.6905014069388514E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6898918388738244E-4, + 3.6905014069388514E-4, + 3.683717511008368E-4 + ], + [ + 3.677474976396435E-4, + 3.684693446071657E-4, + 3.6829056036154494E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1230624515954224, + "scoreError" : 5.272794088452165E-4, + "scoreConfidence" : [ + 0.12253517218657718, + 0.12358973100426761 + ], + "scorePercentiles" : { + "0.0" : 0.12279985495180205, + "50.0" : 0.1230435173095858, + "90.0" : 0.12327772081756432, + "95.0" : 0.12327772081756432, + "99.0" : 0.12327772081756432, + "99.9" : 0.12327772081756432, + "99.99" : 0.12327772081756432, + "99.999" : 0.12327772081756432, + "99.9999" : 0.12327772081756432, + "100.0" : 0.12327772081756432 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12279985495180205, + 0.12299122569734836, + 0.12294431839584948 + ], + [ + 0.12309580892182326, + 0.12327772081756432, + 0.12326578078814698 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012910590324822946, + "scoreError" : 2.792659836352556E-4, + "scoreConfidence" : [ + 0.01263132434118769, + 0.013189856308458201 + ], + "scorePercentiles" : { + "0.0" : 0.012815531948758958, + "50.0" : 0.012911860895510711, + "90.0" : 0.013004634032885634, + "95.0" : 0.013004634032885634, + "99.0" : 0.013004634032885634, + "99.9" : 0.013004634032885634, + "99.99" : 0.013004634032885634, + "99.999" : 0.013004634032885634, + "99.9999" : 0.013004634032885634, + "100.0" : 0.013004634032885634 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012999149780772165, + 0.013000564010561499, + 0.013004634032885634 + ], + [ + 0.012815531948758958, + 0.012824572010249256, + 0.012819090165710161 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0011203722859954, + "scoreError" : 0.08380700843743881, + "scoreConfidence" : [ + 0.9173133638485566, + 1.084927380723434 + ], + "scorePercentiles" : { + "0.0" : 0.972361766478709, + "50.0" : 1.0020919277685993, + "90.0" : 1.029254303519967, + "95.0" : 1.029254303519967, + "99.0" : 1.029254303519967, + "99.9" : 1.029254303519967, + "99.99" : 1.029254303519967, + "99.999" : 1.029254303519967, + "99.9999" : 1.029254303519967, + "100.0" : 1.029254303519967 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.029254303519967, + 1.0275243268262613, + 1.0283092615938303 + ], + [ + 0.972361766478709, + 0.9766595287109375, + 0.9726130465862672 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011176691726336596, + "scoreError" : 0.0017618390379087504, + "scoreConfidence" : [ + 0.009414852688427846, + 0.012938530764245346 + ], + "scorePercentiles" : { + "0.0" : 0.010598490973489593, + "50.0" : 0.011174476592963231, + "90.0" : 0.011762573605935711, + "95.0" : 0.011762573605935711, + "99.0" : 0.011762573605935711, + "99.9" : 0.011762573605935711, + "99.99" : 0.011762573605935711, + "99.999" : 0.011762573605935711, + "99.9999" : 0.011762573605935711, + "100.0" : 0.011762573605935711 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010598490973489593, + 0.010605626090497795, + 0.010605433371936165 + ], + [ + 0.011762573605935711, + 0.011744699220731639, + 0.011743327095428668 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1355409437163875, + "scoreError" : 0.20895367450490537, + "scoreConfidence" : [ + 2.926587269211482, + 3.344494618221293 + ], + "scorePercentiles" : { + "0.0" : 3.061306892900857, + "50.0" : 3.1378143618561616, + "90.0" : 3.207713130128205, + "95.0" : 3.207713130128205, + "99.0" : 3.207713130128205, + "99.9" : 3.207713130128205, + "99.99" : 3.207713130128205, + "99.999" : 3.207713130128205, + "99.9999" : 3.207713130128205, + "100.0" : 3.207713130128205 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.200091075495841, + 3.2023889314980796, + 3.207713130128205 + ], + [ + 3.061306892900857, + 3.0662079840588596, + 3.075537648216482 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8083632951915227, + "scoreError" : 0.09129852497252103, + "scoreConfidence" : [ + 2.7170647702190016, + 2.899661820164044 + ], + "scorePercentiles" : { + "0.0" : 2.772142431263858, + "50.0" : 2.8108115090890484, + "90.0" : 2.8409348028969044, + "95.0" : 2.8409348028969044, + "99.0" : 2.8409348028969044, + "99.9" : 2.8409348028969044, + "99.99" : 2.8409348028969044, + "99.999" : 2.8409348028969044, + "99.9999" : 2.8409348028969044, + "100.0" : 2.8409348028969044 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8312534735352393, + 2.8409348028969044, + 2.8399789293015334 + ], + [ + 2.790369544642857, + 2.775500589508743, + 2.772142431263858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17832405237582152, + "scoreError" : 0.0026770469580971058, + "scoreConfidence" : [ + 0.1756470054177244, + 0.18100109933391864 + ], + "scorePercentiles" : { + "0.0" : 0.17784544945758493, + "50.0" : 0.17794948826844714, + "90.0" : 0.1802703837903124, + "95.0" : 0.1802703837903124, + "99.0" : 0.1802703837903124, + "99.9" : 0.1802703837903124, + "99.99" : 0.1802703837903124, + "99.999" : 0.1802703837903124, + "99.9999" : 0.1802703837903124, + "100.0" : 0.1802703837903124 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1802703837903124, + 0.1779537101928963, + 0.17798467055850212 + ], + [ + 0.17794526634399802, + 0.17794483391163543, + 0.17784544945758493 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3312494210612915, + "scoreError" : 0.003861330257279199, + "scoreConfidence" : [ + 0.3273880908040123, + 0.3351107513185707 + ], + "scorePercentiles" : { + "0.0" : 0.32994058408393545, + "50.0" : 0.33107271639023794, + "90.0" : 0.33329966611118517, + "95.0" : 0.33329966611118517, + "99.0" : 0.33329966611118517, + "99.9" : 0.33329966611118517, + "99.99" : 0.33329966611118517, + "99.999" : 0.33329966611118517, + "99.9999" : 0.33329966611118517, + "100.0" : 0.33329966611118517 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33329966611118517, + 0.3320768963937039, + 0.33189106017058845 + ], + [ + 0.32994058408393545, + 0.3300339469984489, + 0.3302543726098874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1410414341822426, + "scoreError" : 0.003062258760121863, + "scoreConfidence" : [ + 0.13797917542212074, + 0.14410369294236447 + ], + "scorePercentiles" : { + "0.0" : 0.13968855237536493, + "50.0" : 0.14130215268249957, + "90.0" : 0.14221909218516676, + "95.0" : 0.14221909218516676, + "99.0" : 0.14221909218516676, + "99.9" : 0.14221909218516676, + "99.99" : 0.14221909218516676, + "99.999" : 0.14221909218516676, + "99.9999" : 0.14221909218516676, + "100.0" : 0.14221909218516676 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14079858942625836, + 0.1398577686530635, + 0.13968855237536493 + ], + [ + 0.14221909218516676, + 0.14187888651486133, + 0.14180571593874078 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3902911183330701, + "scoreError" : 0.00761128279467112, + "scoreConfidence" : [ + 0.382679835538399, + 0.3979024011277412 + ], + "scorePercentiles" : { + "0.0" : 0.38746394633862846, + "50.0" : 0.3901324214494687, + "90.0" : 0.3939931007406824, + "95.0" : 0.3939931007406824, + "99.0" : 0.3939931007406824, + "99.9" : 0.3939931007406824, + "99.99" : 0.3939931007406824, + "99.999" : 0.3939931007406824, + "99.9999" : 0.3939931007406824, + "100.0" : 0.3939931007406824 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.392382461155144, + 0.3876423588650283, + 0.38746394633862846 + ], + [ + 0.3914922675383652, + 0.3939931007406824, + 0.38877257536057225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15921345674452006, + "scoreError" : 0.004143751146812588, + "scoreConfidence" : [ + 0.15506970559770747, + 0.16335720789133265 + ], + "scorePercentiles" : { + "0.0" : 0.15723523635220127, + "50.0" : 0.15906303165528918, + "90.0" : 0.16147497104842487, + "95.0" : 0.16147497104842487, + "99.0" : 0.16147497104842487, + "99.9" : 0.16147497104842487, + "99.99" : 0.16147497104842487, + "99.999" : 0.16147497104842487, + "99.9999" : 0.16147497104842487, + "100.0" : 0.16147497104842487 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1584426240414475, + 0.15962392880858128, + 0.15723523635220127 + ], + [ + 0.16147497104842487, + 0.16000184571446857, + 0.15850213450199707 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048834946368335706, + "scoreError" : 6.325623771865807E-4, + "scoreConfidence" : [ + 0.04820238399114912, + 0.04946750874552229 + ], + "scorePercentiles" : { + "0.0" : 0.048519972897178125, + "50.0" : 0.04889447395551033, + "90.0" : 0.04908195467351186, + "95.0" : 0.04908195467351186, + "99.0" : 0.04908195467351186, + "99.9" : 0.04908195467351186, + "99.99" : 0.04908195467351186, + "99.999" : 0.04908195467351186, + "99.9999" : 0.04908195467351186, + "100.0" : 0.04908195467351186 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04881297619419523, + 0.048975971716825425, + 0.0486189683300597 + ], + [ + 0.048999834398243874, + 0.04908195467351186, + 0.048519972897178125 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8566661.459651751, + "scoreError" : 432264.60236985097, + "scoreConfidence" : [ + 8134396.857281901, + 8998926.062021602 + ], + "scorePercentiles" : { + "0.0" : 8395757.823825503, + "50.0" : 8556445.875525326, + "90.0" : 8753329.12248469, + "95.0" : 8753329.12248469, + "99.0" : 8753329.12248469, + "99.9" : 8753329.12248469, + "99.99" : 8753329.12248469, + "99.999" : 8753329.12248469, + "99.9999" : 8753329.12248469, + "100.0" : 8753329.12248469 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8537574.704778157, + 8404943.263865545, + 8395757.823825503 + ], + [ + 8753329.12248469, + 8733046.796684118, + 8575317.046272494 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-23T08:33:15Z-ed6c2fbb1cceee0ddb9f6a4ce154631e775c7453-jdk17.json b/performance-results/2025-05-23T08:33:15Z-ed6c2fbb1cceee0ddb9f6a4ce154631e775c7453-jdk17.json new file mode 100644 index 0000000000..8f478e5fd1 --- /dev/null +++ b/performance-results/2025-05-23T08:33:15Z-ed6c2fbb1cceee0ddb9f6a4ce154631e775c7453-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3368853082521843, + "scoreError" : 0.04366888105685862, + "scoreConfidence" : [ + 3.2932164271953255, + 3.380554189309043 + ], + "scorePercentiles" : { + "0.0" : 3.328478258637335, + "50.0" : 3.3383080808021868, + "90.0" : 3.342446812767029, + "95.0" : 3.342446812767029, + "99.0" : 3.342446812767029, + "99.9" : 3.342446812767029, + "99.99" : 3.342446812767029, + "99.999" : 3.342446812767029, + "99.9999" : 3.342446812767029, + "100.0" : 3.342446812767029 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.328478258637335, + 3.334349134297776 + ], + [ + 3.342446812767029, + 3.342267027306598 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6836478081966015, + "scoreError" : 0.028191839061743464, + "scoreConfidence" : [ + 1.655455969134858, + 1.711839647258345 + ], + "scorePercentiles" : { + "0.0" : 1.6782198710288996, + "50.0" : 1.6837354586595263, + "90.0" : 1.6889004444384537, + "95.0" : 1.6889004444384537, + "99.0" : 1.6889004444384537, + "99.9" : 1.6889004444384537, + "99.99" : 1.6889004444384537, + "99.999" : 1.6889004444384537, + "99.9999" : 1.6889004444384537, + "100.0" : 1.6889004444384537 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6838617090765755, + 1.6782198710288996 + ], + [ + 1.6836092082424772, + 1.6889004444384537 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8496949450012029, + "scoreError" : 0.03618414483110517, + "scoreConfidence" : [ + 0.8135108001700977, + 0.8858790898323081 + ], + "scorePercentiles" : { + "0.0" : 0.8434106483488939, + "50.0" : 0.8492377908669799, + "90.0" : 0.8568935499219578, + "95.0" : 0.8568935499219578, + "99.0" : 0.8568935499219578, + "99.9" : 0.8568935499219578, + "99.99" : 0.8568935499219578, + "99.999" : 0.8568935499219578, + "99.9999" : 0.8568935499219578, + "100.0" : 0.8568935499219578 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8481574786716781, + 0.8503181030622817 + ], + [ + 0.8434106483488939, + 0.8568935499219578 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.0342353693201, + "scoreError" : 0.4696352422869809, + "scoreConfidence" : [ + 15.56460012703312, + 16.50387061160708 + ], + "scorePercentiles" : { + "0.0" : 15.827939161893788, + "50.0" : 16.011625326875638, + "90.0" : 16.28797697524647, + "95.0" : 16.28797697524647, + "99.0" : 16.28797697524647, + "99.9" : 16.28797697524647, + "99.99" : 16.28797697524647, + "99.999" : 16.28797697524647, + "99.9999" : 16.28797697524647, + "100.0" : 16.28797697524647 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.907557770845557, + 15.827939161893788, + 15.99237866547927 + ], + [ + 16.030871988272008, + 16.158687654183513, + 16.28797697524647 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2666.6163039636576, + "scoreError" : 67.73104106703518, + "scoreConfidence" : [ + 2598.8852628966224, + 2734.347345030693 + ], + "scorePercentiles" : { + "0.0" : 2644.2330569203446, + "50.0" : 2659.8307716586005, + "90.0" : 2706.603435598254, + "95.0" : 2706.603435598254, + "99.0" : 2706.603435598254, + "99.9" : 2706.603435598254, + "99.99" : 2706.603435598254, + "99.999" : 2706.603435598254, + "99.9999" : 2706.603435598254, + "100.0" : 2706.603435598254 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2667.345784256022, + 2706.603435598254, + 2681.9754212316357 + ], + [ + 2652.315759061179, + 2647.224366714513, + 2644.2330569203446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76525.81287667895, + "scoreError" : 1111.859628252806, + "scoreConfidence" : [ + 75413.95324842614, + 77637.67250493175 + ], + "scorePercentiles" : { + "0.0" : 76057.25109304917, + "50.0" : 76512.12974721203, + "90.0" : 77032.78711516388, + "95.0" : 77032.78711516388, + "99.0" : 77032.78711516388, + "99.9" : 77032.78711516388, + "99.99" : 77032.78711516388, + "99.999" : 77032.78711516388, + "99.9999" : 77032.78711516388, + "100.0" : 77032.78711516388 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77032.78711516388, + 76692.559260679, + 76869.5336504553 + ], + [ + 76171.04590698122, + 76331.70023374507, + 76057.25109304917 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 360.6511668267501, + "scoreError" : 3.8829095920800603, + "scoreConfidence" : [ + 356.76825723467005, + 364.5340764188302 + ], + "scorePercentiles" : { + "0.0" : 358.91099488267645, + "50.0" : 360.7814849934582, + "90.0" : 362.1414211625653, + "95.0" : 362.1414211625653, + "99.0" : 362.1414211625653, + "99.9" : 362.1414211625653, + "99.99" : 362.1414211625653, + "99.999" : 362.1414211625653, + "99.9999" : 362.1414211625653, + "100.0" : 362.1414211625653 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 358.91099488267645, + 361.1196966213673, + 362.07319684366456 + ], + [ + 360.4432733655491, + 362.1414211625653, + 359.218418084678 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.40127880201021, + "scoreError" : 2.221792064769706, + "scoreConfidence" : [ + 112.17948673724051, + 116.62307086677991 + ], + "scorePercentiles" : { + "0.0" : 113.26386823706027, + "50.0" : 114.53312533808344, + "90.0" : 115.42054106000217, + "95.0" : 115.42054106000217, + "99.0" : 115.42054106000217, + "99.9" : 115.42054106000217, + "99.99" : 115.42054106000217, + "99.999" : 115.42054106000217, + "99.9999" : 115.42054106000217, + "100.0" : 115.42054106000217 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.42054106000217, + 114.92597279060936, + 114.68626903734736 + ], + [ + 113.73104004822267, + 113.26386823706027, + 114.3799816388195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0625063673871074, + "scoreError" : 0.0023291554961452016, + "scoreConfidence" : [ + 0.060177211890962194, + 0.0648355228832526 + ], + "scorePercentiles" : { + "0.0" : 0.061721294313700076, + "50.0" : 0.06238741780594462, + "90.0" : 0.06342995156574081, + "95.0" : 0.06342995156574081, + "99.0" : 0.06342995156574081, + "99.9" : 0.06342995156574081, + "99.99" : 0.06342995156574081, + "99.999" : 0.06342995156574081, + "99.9999" : 0.06342995156574081, + "100.0" : 0.06342995156574081 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06173081600780266, + 0.06184666303426865, + 0.061721294313700076 + ], + [ + 0.06342995156574081, + 0.0629281725776206, + 0.06338130682351152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8394543418184397E-4, + "scoreError" : 1.9122747462921474E-5, + "scoreConfidence" : [ + 3.648226867189225E-4, + 4.0306818164476544E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7750758305852737E-4, + "50.0" : 3.824604654390173E-4, + "90.0" : 3.936078335619306E-4, + "95.0" : 3.936078335619306E-4, + "99.0" : 3.936078335619306E-4, + "99.9" : 3.936078335619306E-4, + "99.99" : 3.936078335619306E-4, + "99.999" : 3.936078335619306E-4, + "99.9999" : 3.936078335619306E-4, + "100.0" : 3.936078335619306E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8977231602350254E-4, + 3.936078335619306E-4, + 3.858043270315457E-4 + ], + [ + 3.7750758305852737E-4, + 3.791166038464889E-4, + 3.7786394156906847E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12555735775806184, + "scoreError" : 0.005365496873346317, + "scoreConfidence" : [ + 0.12019186088471552, + 0.13092285463140815 + ], + "scorePercentiles" : { + "0.0" : 0.12310637570169392, + "50.0" : 0.12559933882645982, + "90.0" : 0.1277276631116447, + "95.0" : 0.1277276631116447, + "99.0" : 0.1277276631116447, + "99.9" : 0.1277276631116447, + "99.99" : 0.1277276631116447, + "99.999" : 0.1277276631116447, + "99.9999" : 0.1277276631116447, + "100.0" : 0.1277276631116447 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12692706952835456, + 0.1277276631116447, + 0.12707682668310163 + ], + [ + 0.12427160812456507, + 0.1242346033990111, + 0.12310637570169392 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013046195283202005, + "scoreError" : 4.769874703931685E-4, + "scoreConfidence" : [ + 0.012569207812808837, + 0.013523182753595174 + ], + "scorePercentiles" : { + "0.0" : 0.012883810447874648, + "50.0" : 0.013026893365341888, + "90.0" : 0.013222338525676116, + "95.0" : 0.013222338525676116, + "99.0" : 0.013222338525676116, + "99.9" : 0.013222338525676116, + "99.99" : 0.013222338525676116, + "99.999" : 0.013222338525676116, + "99.9999" : 0.013222338525676116, + "100.0" : 0.013222338525676116 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012883810447874648, + 0.012895665817718052, + 0.01289822455447026 + ], + [ + 0.013155562176213517, + 0.01322157017725944, + 0.013222338525676116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0008528274076403, + "scoreError" : 0.07247363632639794, + "scoreConfidence" : [ + 0.9283791910812423, + 1.0733264637340383 + ], + "scorePercentiles" : { + "0.0" : 0.9718420679300291, + "50.0" : 1.00258471376137, + "90.0" : 1.0274792475084764, + "95.0" : 1.0274792475084764, + "99.0" : 1.0274792475084764, + "99.9" : 1.0274792475084764, + "99.99" : 1.0274792475084764, + "99.999" : 1.0274792475084764, + "99.9999" : 1.0274792475084764, + "100.0" : 1.0274792475084764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9772408520617549, + 0.9836382428444969, + 0.9718420679300291 + ], + [ + 1.021531184678243, + 1.0233853694228408, + 1.0274792475084764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01048112165937097, + "scoreError" : 3.2858283889881403E-4, + "scoreConfidence" : [ + 0.010152538820472156, + 0.010809704498269785 + ], + "scorePercentiles" : { + "0.0" : 0.010343414143629036, + "50.0" : 0.010492933655505368, + "90.0" : 0.010666617439441937, + "95.0" : 0.010666617439441937, + "99.0" : 0.010666617439441937, + "99.9" : 0.010666617439441937, + "99.99" : 0.010666617439441937, + "99.999" : 0.010666617439441937, + "99.9999" : 0.010666617439441937, + "100.0" : 0.010666617439441937 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010522802418081949, + 0.010666617439441937, + 0.010508303114367196 + ], + [ + 0.010368028644062173, + 0.010343414143629036, + 0.01047756419664354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.181822692653299, + "scoreError" : 0.1602402071629384, + "scoreConfidence" : [ + 3.021582485490361, + 3.3420628998162374 + ], + "scorePercentiles" : { + "0.0" : 3.111689081518357, + "50.0" : 3.1757361550490537, + "90.0" : 3.2671744121489223, + "95.0" : 3.2671744121489223, + "99.0" : 3.2671744121489223, + "99.9" : 3.2671744121489223, + "99.99" : 3.2671744121489223, + "99.999" : 3.2671744121489223, + "99.9999" : 3.2671744121489223, + "100.0" : 3.2671744121489223 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1389224526051476, + 3.1581275214646465, + 3.111689081518357 + ], + [ + 3.193344788633461, + 3.2216778995492596, + 3.2671744121489223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8214042861936686, + "scoreError" : 0.09588760321668656, + "scoreConfidence" : [ + 2.725516682976982, + 2.917291889410355 + ], + "scorePercentiles" : { + "0.0" : 2.777473387947792, + "50.0" : 2.8298773190435766, + "90.0" : 2.872572923319931, + "95.0" : 2.872572923319931, + "99.0" : 2.872572923319931, + "99.9" : 2.872572923319931, + "99.99" : 2.872572923319931, + "99.999" : 2.872572923319931, + "99.9999" : 2.872572923319931, + "100.0" : 2.872572923319931 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.872572923319931, + 2.788550323111235, + 2.777473387947792 + ], + [ + 2.8298168851160157, + 2.8299377529711376, + 2.830074444695898 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18290622012399874, + "scoreError" : 0.004058598274795433, + "scoreConfidence" : [ + 0.1788476218492033, + 0.18696481839879417 + ], + "scorePercentiles" : { + "0.0" : 0.18097177178378182, + "50.0" : 0.18302590179846326, + "90.0" : 0.18426716231803944, + "95.0" : 0.18426716231803944, + "99.0" : 0.18426716231803944, + "99.9" : 0.18426716231803944, + "99.99" : 0.18426716231803944, + "99.999" : 0.18426716231803944, + "99.9999" : 0.18426716231803944, + "100.0" : 0.18426716231803944 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18197678592615507, + 0.18097177178378182, + 0.1819344585380053 + ], + [ + 0.18407501767077145, + 0.18426716231803944, + 0.18421212450723942 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32632256057157966, + "scoreError" : 0.0013296847068736766, + "scoreConfidence" : [ + 0.324992875864706, + 0.3276522452784533 + ], + "scorePercentiles" : { + "0.0" : 0.3255198149799811, + "50.0" : 0.32636255789213686, + "90.0" : 0.3269260892804603, + "95.0" : 0.3269260892804603, + "99.0" : 0.3269260892804603, + "99.9" : 0.3269260892804603, + "99.99" : 0.3269260892804603, + "99.999" : 0.3269260892804603, + "99.9999" : 0.3269260892804603, + "100.0" : 0.3269260892804603 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32655644858439736, + 0.32620789480036533, + 0.3269260892804603 + ], + [ + 0.3265117672391276, + 0.3255198149799811, + 0.32621334854514616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1463139842498076, + "scoreError" : 0.004158853261690341, + "scoreConfidence" : [ + 0.14215513098811725, + 0.15047283751149795 + ], + "scorePercentiles" : { + "0.0" : 0.1446591200347172, + "50.0" : 0.14644836033845438, + "90.0" : 0.1484301051608211, + "95.0" : 0.1484301051608211, + "99.0" : 0.1484301051608211, + "99.9" : 0.1484301051608211, + "99.99" : 0.1484301051608211, + "99.999" : 0.1484301051608211, + "99.9999" : 0.1484301051608211, + "100.0" : 0.1484301051608211 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1484301051608211, + 0.14708309789674953, + 0.14710501616651955 + ], + [ + 0.14581362278015922, + 0.14479294345987895, + 0.1446591200347172 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4063850946909137, + "scoreError" : 0.0335227165435586, + "scoreConfidence" : [ + 0.3728623781473551, + 0.4399078112344723 + ], + "scorePercentiles" : { + "0.0" : 0.39548623416119594, + "50.0" : 0.40531292875936986, + "90.0" : 0.4201236399613494, + "95.0" : 0.4201236399613494, + "99.0" : 0.4201236399613494, + "99.9" : 0.4201236399613494, + "99.99" : 0.4201236399613494, + "99.999" : 0.4201236399613494, + "99.9999" : 0.4201236399613494, + "100.0" : 0.4201236399613494 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39548623416119594, + 0.3955503506447275, + 0.3957076599002849 + ], + [ + 0.4201236399613494, + 0.4165244858594694, + 0.4149181976184549 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15885093466052472, + "scoreError" : 0.003049744993945281, + "scoreConfidence" : [ + 0.15580118966657944, + 0.16190067965447 + ], + "scorePercentiles" : { + "0.0" : 0.15787372603128996, + "50.0" : 0.1584433455884178, + "90.0" : 0.1605397828097157, + "95.0" : 0.1605397828097157, + "99.0" : 0.1605397828097157, + "99.9" : 0.1605397828097157, + "99.99" : 0.1605397828097157, + "99.999" : 0.1605397828097157, + "99.9999" : 0.1605397828097157, + "100.0" : 0.1605397828097157 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15826346466836533, + 0.15797951691126522, + 0.15787372603128996 + ], + [ + 0.15982589103404188, + 0.1605397828097157, + 0.15862322650847027 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04664455933774688, + "scoreError" : 0.002191785324931511, + "scoreConfidence" : [ + 0.04445277401281537, + 0.048836344662678395 + ], + "scorePercentiles" : { + "0.0" : 0.045911793620186214, + "50.0" : 0.04642862947690648, + "90.0" : 0.0476626823760432, + "95.0" : 0.0476626823760432, + "99.0" : 0.0476626823760432, + "99.9" : 0.0476626823760432, + "99.99" : 0.0476626823760432, + "99.999" : 0.0476626823760432, + "99.9999" : 0.0476626823760432, + "100.0" : 0.0476626823760432 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0476626823760432, + 0.04746826093890919, + 0.046782698756064126 + ], + [ + 0.04607456019774883, + 0.045911793620186214, + 0.04596736013752971 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8605379.099783057, + "scoreError" : 164401.15696770872, + "scoreConfidence" : [ + 8440977.942815349, + 8769780.256750766 + ], + "scorePercentiles" : { + "0.0" : 8556294.344739093, + "50.0" : 8592459.056410734, + "90.0" : 8712649.466898955, + "95.0" : 8712649.466898955, + "99.0" : 8712649.466898955, + "99.9" : 8712649.466898955, + "99.99" : 8712649.466898955, + "99.999" : 8712649.466898955, + "99.9999" : 8712649.466898955, + "100.0" : 8712649.466898955 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8712649.466898955, + 8610993.132530121, + 8573924.980291346 + ], + [ + 8618578.148148147, + 8559834.526090676, + 8556294.344739093 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-26T00:46:24Z-4b1f2316e8053adfb4c50abbbaf898657480e1ed-jdk17.json b/performance-results/2025-05-26T00:46:24Z-4b1f2316e8053adfb4c50abbbaf898657480e1ed-jdk17.json new file mode 100644 index 0000000000..f2f2bbb0d3 --- /dev/null +++ b/performance-results/2025-05-26T00:46:24Z-4b1f2316e8053adfb4c50abbbaf898657480e1ed-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3602205783710297, + "scoreError" : 0.026557289603301223, + "scoreConfidence" : [ + 3.3336632887677284, + 3.386777867974331 + ], + "scorePercentiles" : { + "0.0" : 3.3557709373676095, + "50.0" : 3.3597527525630744, + "90.0" : 3.3656058709903607, + "95.0" : 3.3656058709903607, + "99.0" : 3.3656058709903607, + "99.9" : 3.3656058709903607, + "99.99" : 3.3656058709903607, + "99.999" : 3.3656058709903607, + "99.9999" : 3.3656058709903607, + "100.0" : 3.3656058709903607 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3557709373676095, + 3.3656058709903607 + ], + [ + 3.358906518604916, + 3.3605989865212327 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6937317416595927, + "scoreError" : 0.015431761513365057, + "scoreConfidence" : [ + 1.6782999801462277, + 1.7091635031729577 + ], + "scorePercentiles" : { + "0.0" : 1.6910585813576287, + "50.0" : 1.6937055738270748, + "90.0" : 1.696457237626593, + "95.0" : 1.696457237626593, + "99.0" : 1.696457237626593, + "99.9" : 1.696457237626593, + "99.99" : 1.696457237626593, + "99.999" : 1.696457237626593, + "99.9999" : 1.696457237626593, + "100.0" : 1.696457237626593 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.696457237626593, + 1.6948310349908955 + ], + [ + 1.6925801126632538, + 1.6910585813576287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8497856099305433, + "scoreError" : 0.037959632752125765, + "scoreConfidence" : [ + 0.8118259771784175, + 0.8877452426826691 + ], + "scorePercentiles" : { + "0.0" : 0.844952825095208, + "50.0" : 0.8479398723901039, + "90.0" : 0.8583098698467573, + "95.0" : 0.8583098698467573, + "99.0" : 0.8583098698467573, + "99.9" : 0.8583098698467573, + "99.99" : 0.8583098698467573, + "99.999" : 0.8583098698467573, + "99.9999" : 0.8583098698467573, + "100.0" : 0.8583098698467573 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.844952825095208, + 0.8583098698467573 + ], + [ + 0.8473526240112758, + 0.8485271207689321 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.360666480505966, + "scoreError" : 0.18848979930966828, + "scoreConfidence" : [ + 16.172176681196298, + 16.549156279815634 + ], + "scorePercentiles" : { + "0.0" : 16.29171205229308, + "50.0" : 16.34145448256377, + "90.0" : 16.44877223056117, + "95.0" : 16.44877223056117, + "99.0" : 16.44877223056117, + "99.9" : 16.44877223056117, + "99.99" : 16.44877223056117, + "99.999" : 16.44877223056117, + "99.9999" : 16.44877223056117, + "100.0" : 16.44877223056117 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.29171205229308, + 16.303422029915076, + 16.331367935928895 + ], + [ + 16.437183605138927, + 16.44877223056117, + 16.351541029198643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2847.219314180182, + "scoreError" : 47.6687574536888, + "scoreConfidence" : [ + 2799.5505567264936, + 2894.888071633871 + ], + "scorePercentiles" : { + "0.0" : 2830.743929818157, + "50.0" : 2847.456219941718, + "90.0" : 2863.572418171459, + "95.0" : 2863.572418171459, + "99.0" : 2863.572418171459, + "99.9" : 2863.572418171459, + "99.99" : 2863.572418171459, + "99.999" : 2863.572418171459, + "99.9999" : 2863.572418171459, + "100.0" : 2863.572418171459 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2861.4726506950783, + 2863.572418171459, + 2863.057550035444 + ], + [ + 2830.743929818157, + 2831.029547172599, + 2833.4397891883573 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77173.4701098917, + "scoreError" : 754.1415796799811, + "scoreConfidence" : [ + 76419.32853021171, + 77927.61168957168 + ], + "scorePercentiles" : { + "0.0" : 76903.42716890328, + "50.0" : 77163.09766392107, + "90.0" : 77507.12296039943, + "95.0" : 77507.12296039943, + "99.0" : 77507.12296039943, + "99.9" : 77507.12296039943, + "99.99" : 77507.12296039943, + "99.999" : 77507.12296039943, + "99.9999" : 77507.12296039943, + "100.0" : 77507.12296039943 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76983.3752602997, + 76915.76835730243, + 76903.42716890328 + ], + [ + 77388.30684490294, + 77342.82006754245, + 77507.12296039943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 368.77632945642944, + "scoreError" : 25.687615108069487, + "scoreConfidence" : [ + 343.08871434835993, + 394.46394456449895 + ], + "scorePercentiles" : { + "0.0" : 360.34814262310846, + "50.0" : 368.4880339814724, + "90.0" : 377.53462021562336, + "95.0" : 377.53462021562336, + "99.0" : 377.53462021562336, + "99.9" : 377.53462021562336, + "99.99" : 377.53462021562336, + "99.999" : 377.53462021562336, + "99.9999" : 377.53462021562336, + "100.0" : 377.53462021562336 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 376.5148920466809, + 377.53462021562336, + 377.3485319243367 + ], + [ + 360.4611759162639, + 360.45061401256305, + 360.34814262310846 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.5584373677998, + "scoreError" : 1.5342001779384482, + "scoreConfidence" : [ + 116.02423718986135, + 119.09263754573824 + ], + "scorePercentiles" : { + "0.0" : 116.90349656106073, + "50.0" : 117.55716747987739, + "90.0" : 118.29358831007322, + "95.0" : 118.29358831007322, + "99.0" : 118.29358831007322, + "99.9" : 118.29358831007322, + "99.99" : 118.29358831007322, + "99.999" : 118.29358831007322, + "99.9999" : 118.29358831007322, + "100.0" : 118.29358831007322 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 118.29358831007322, + 117.80255005515481, + 117.96894097206436 + ], + [ + 116.90349656106073, + 117.07026340384574, + 117.31178490459996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06092838087560045, + "scoreError" : 5.502083722971356E-4, + "scoreConfidence" : [ + 0.060378172503303316, + 0.061478589247897585 + ], + "scorePercentiles" : { + "0.0" : 0.06072943971506303, + "50.0" : 0.06092112683012177, + "90.0" : 0.06121079013539652, + "95.0" : 0.06121079013539652, + "99.0" : 0.06121079013539652, + "99.9" : 0.06121079013539652, + "99.99" : 0.06121079013539652, + "99.999" : 0.06121079013539652, + "99.9999" : 0.06121079013539652, + "100.0" : 0.06121079013539652 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061044156759330476, + 0.061034091037260825, + 0.06121079013539652 + ], + [ + 0.06072943971506303, + 0.060743644983569114, + 0.06080816262298272 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.630495193739473E-4, + "scoreError" : 2.027537177186093E-5, + "scoreConfidence" : [ + 3.427741476020863E-4, + 3.8332489114580823E-4 + ], + "scorePercentiles" : { + "0.0" : 3.562624227260778E-4, + "50.0" : 3.626886563353374E-4, + "90.0" : 3.707248799802154E-4, + "95.0" : 3.707248799802154E-4, + "99.0" : 3.707248799802154E-4, + "99.9" : 3.707248799802154E-4, + "99.99" : 3.707248799802154E-4, + "99.999" : 3.707248799802154E-4, + "99.9999" : 3.707248799802154E-4, + "100.0" : 3.707248799802154E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.565912667211388E-4, + 3.562624227260778E-4, + 3.5657147000965226E-4 + ], + [ + 3.6878604594953597E-4, + 3.707248799802154E-4, + 3.6936103085706323E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12289439409353096, + "scoreError" : 9.329502932930627E-4, + "scoreConfidence" : [ + 0.1219614438002379, + 0.12382734438682402 + ], + "scorePercentiles" : { + "0.0" : 0.12257835035914785, + "50.0" : 0.12281178943900778, + "90.0" : 0.12349538276300678, + "95.0" : 0.12349538276300678, + "99.0" : 0.12349538276300678, + "99.9" : 0.12349538276300678, + "99.99" : 0.12349538276300678, + "99.999" : 0.12349538276300678, + "99.9999" : 0.12349538276300678, + "100.0" : 0.12349538276300678 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12349538276300678, + 0.12301598529990651, + 0.12275839381068707 + ], + [ + 0.12286518506732848, + 0.12257835035914785, + 0.122653067261109 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012917029108279921, + "scoreError" : 3.9187874156510453E-4, + "scoreConfidence" : [ + 0.012525150366714817, + 0.013308907849845026 + ], + "scorePercentiles" : { + "0.0" : 0.012785314601799894, + "50.0" : 0.012919970969676321, + "90.0" : 0.013047729825188602, + "95.0" : 0.013047729825188602, + "99.0" : 0.013047729825188602, + "99.9" : 0.013047729825188602, + "99.99" : 0.013047729825188602, + "99.999" : 0.013047729825188602, + "99.9999" : 0.013047729825188602, + "100.0" : 0.013047729825188602 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013047729825188602, + 0.013043413701396018, + 0.013042440623785439 + ], + [ + 0.012785774581942366, + 0.012797501315567204, + 0.012785314601799894 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9541839001962235, + "scoreError" : 0.0027601384411125563, + "scoreConfidence" : [ + 0.9514237617551109, + 0.956944038637336 + ], + "scorePercentiles" : { + "0.0" : 0.9533739846520496, + "50.0" : 0.9538841733174372, + "90.0" : 0.9561116341300191, + "95.0" : 0.9561116341300191, + "99.0" : 0.9561116341300191, + "99.9" : 0.9561116341300191, + "99.99" : 0.9561116341300191, + "99.999" : 0.9561116341300191, + "99.9999" : 0.9561116341300191, + "100.0" : 0.9561116341300191 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9541993032153421, + 0.9536501325450558, + 0.9533739846520496 + ], + [ + 0.953824113304721, + 0.9561116341300191, + 0.9539442333301535 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011101639820944108, + "scoreError" : 0.0014781236413846357, + "scoreConfidence" : [ + 0.009623516179559472, + 0.012579763462328744 + ], + "scorePercentiles" : { + "0.0" : 0.010619703991215588, + "50.0" : 0.011098379613741185, + "90.0" : 0.01159072897059778, + "95.0" : 0.01159072897059778, + "99.0" : 0.01159072897059778, + "99.9" : 0.01159072897059778, + "99.99" : 0.01159072897059778, + "99.999" : 0.01159072897059778, + "99.9999" : 0.01159072897059778, + "100.0" : 0.01159072897059778 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010619703991215588, + 0.010620667875265775, + 0.0106210484646626 + ], + [ + 0.011581978861103133, + 0.01159072897059778, + 0.01157571076281977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1546525047068026, + "scoreError" : 0.13638269792049654, + "scoreConfidence" : [ + 3.018269806786306, + 3.2910352026272993 + ], + "scorePercentiles" : { + "0.0" : 3.104949684667908, + "50.0" : 3.1542624448445213, + "90.0" : 3.209651849165597, + "95.0" : 3.209651849165597, + "99.0" : 3.209651849165597, + "99.9" : 3.209651849165597, + "99.99" : 3.209651849165597, + "99.999" : 3.209651849165597, + "99.9999" : 3.209651849165597, + "100.0" : 3.209651849165597 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.194790556832695, + 3.209651849165597, + 3.191183418367347 + ], + [ + 3.1173414713216956, + 3.109998047885572, + 3.104949684667908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.751089085298536, + "scoreError" : 0.03134477128550224, + "scoreConfidence" : [ + 2.7197443140130337, + 2.7824338565840385 + ], + "scorePercentiles" : { + "0.0" : 2.740577685941354, + "50.0" : 2.7501860386307397, + "90.0" : 2.77214739883592, + "95.0" : 2.77214739883592, + "99.0" : 2.77214739883592, + "99.9" : 2.77214739883592, + "99.99" : 2.77214739883592, + "99.999" : 2.77214739883592, + "99.9999" : 2.77214739883592, + "100.0" : 2.77214739883592 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.77214739883592, + 2.75005715039868, + 2.740577685941354 + ], + [ + 2.7427871300054854, + 2.750314926862799, + 2.7506502197469747 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17919790306991587, + "scoreError" : 0.015853815780527587, + "scoreConfidence" : [ + 0.1633440872893883, + 0.19505171885044345 + ], + "scorePercentiles" : { + "0.0" : 0.1740034737089365, + "50.0" : 0.17890113617389405, + "90.0" : 0.18513699846341825, + "95.0" : 0.18513699846341825, + "99.0" : 0.18513699846341825, + "99.9" : 0.18513699846341825, + "99.99" : 0.18513699846341825, + "99.999" : 0.18513699846341825, + "99.9999" : 0.18513699846341825, + "100.0" : 0.18513699846341825 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18421843722943723, + 0.18513699846341825, + 0.18366738737878344 + ], + [ + 0.17402623666991507, + 0.1740034737089365, + 0.17413488496900467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3184364190500539, + "scoreError" : 0.01071793412012776, + "scoreConfidence" : [ + 0.3077184849299261, + 0.32915435317018166 + ], + "scorePercentiles" : { + "0.0" : 0.3140165639954782, + "50.0" : 0.31804847677458875, + "90.0" : 0.3242084317069217, + "95.0" : 0.3242084317069217, + "99.0" : 0.3242084317069217, + "99.9" : 0.3242084317069217, + "99.99" : 0.3242084317069217, + "99.999" : 0.3242084317069217, + "99.9999" : 0.3242084317069217, + "100.0" : 0.3242084317069217 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3242084317069217, + 0.3197950272776694, + 0.3207582424222985 + ], + [ + 0.3163019262715081, + 0.3155383226264475, + 0.3140165639954782 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14318679714089835, + "scoreError" : 0.006936757578552282, + "scoreConfidence" : [ + 0.13625003956234608, + 0.15012355471945063 + ], + "scorePercentiles" : { + "0.0" : 0.14037445077203817, + "50.0" : 0.14327897979553111, + "90.0" : 0.14564875122341975, + "95.0" : 0.14564875122341975, + "99.0" : 0.14564875122341975, + "99.9" : 0.14564875122341975, + "99.99" : 0.14564875122341975, + "99.999" : 0.14564875122341975, + "99.9999" : 0.14564875122341975, + "100.0" : 0.14564875122341975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14538712085659455, + 0.14564875122341975, + 0.14523205762667557 + ], + [ + 0.14037445077203817, + 0.14115250040227534, + 0.14132590196438666 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3866835328503511, + "scoreError" : 0.024597066683524273, + "scoreConfidence" : [ + 0.3620864661668268, + 0.4112805995338754 + ], + "scorePercentiles" : { + "0.0" : 0.3786501283556094, + "50.0" : 0.3857915962267088, + "90.0" : 0.39879501738714307, + "95.0" : 0.39879501738714307, + "99.0" : 0.39879501738714307, + "99.9" : 0.39879501738714307, + "99.99" : 0.39879501738714307, + "99.999" : 0.39879501738714307, + "99.9999" : 0.39879501738714307, + "100.0" : 0.39879501738714307 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39879501738714307, + 0.3923343547020283, + 0.39198960046252745 + ], + [ + 0.3795935919908901, + 0.3787385042039085, + 0.3786501283556094 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15549794985525098, + "scoreError" : 0.005600189489897454, + "scoreConfidence" : [ + 0.14989776036535352, + 0.16109813934514844 + ], + "scorePercentiles" : { + "0.0" : 0.1536378334613612, + "50.0" : 0.15526240812412084, + "90.0" : 0.15767040851399292, + "95.0" : 0.15767040851399292, + "99.0" : 0.15767040851399292, + "99.9" : 0.15767040851399292, + "99.99" : 0.15767040851399292, + "99.999" : 0.15767040851399292, + "99.9999" : 0.15767040851399292, + "100.0" : 0.15767040851399292 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15376034619760756, + 0.1536378334613612, + 0.15368971296182454 + ], + [ + 0.15767040851399292, + 0.1567644700506341, + 0.15746492794608552 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047322421253506795, + "scoreError" : 0.005250741507082252, + "scoreConfidence" : [ + 0.04207167974642454, + 0.05257316276058905 + ], + "scorePercentiles" : { + "0.0" : 0.045606956797161466, + "50.0" : 0.047192443621667426, + "90.0" : 0.04928546776276232, + "95.0" : 0.04928546776276232, + "99.0" : 0.04928546776276232, + "99.9" : 0.04928546776276232, + "99.99" : 0.04928546776276232, + "99.999" : 0.04928546776276232, + "99.9999" : 0.04928546776276232, + "100.0" : 0.04928546776276232 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045647531201928125, + 0.04560714302653842, + 0.045606956797161466 + ], + [ + 0.049050072691243694, + 0.04928546776276232, + 0.048737356041406735 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8445745.78103538, + "scoreError" : 80742.13937181125, + "scoreConfidence" : [ + 8365003.641663569, + 8526487.92040719 + ], + "scorePercentiles" : { + "0.0" : 8405974.074789915, + "50.0" : 8449801.171343591, + "90.0" : 8472685.052497882, + "95.0" : 8472685.052497882, + "99.0" : 8472685.052497882, + "99.9" : 8472685.052497882, + "99.99" : 8472685.052497882, + "99.999" : 8472685.052497882, + "99.9999" : 8472685.052497882, + "100.0" : 8472685.052497882 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8405974.074789915, + 8431196.714406066, + 8424638.517676767 + ], + [ + 8471574.698560541, + 8468405.628281118, + 8472685.052497882 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-26T00:46:54Z-4b1f2316e8053adfb4c50abbbaf898657480e1ed-jdk17.json b/performance-results/2025-05-26T00:46:54Z-4b1f2316e8053adfb4c50abbbaf898657480e1ed-jdk17.json new file mode 100644 index 0000000000..1891c276d5 --- /dev/null +++ b/performance-results/2025-05-26T00:46:54Z-4b1f2316e8053adfb4c50abbbaf898657480e1ed-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.355314158445994, + "scoreError" : 0.03012316097364703, + "scoreConfidence" : [ + 3.325190997472347, + 3.385437319419641 + ], + "scorePercentiles" : { + "0.0" : 3.3489262131874447, + "50.0" : 3.3563192708112775, + "90.0" : 3.359691878973976, + "95.0" : 3.359691878973976, + "99.0" : 3.359691878973976, + "99.9" : 3.359691878973976, + "99.99" : 3.359691878973976, + "99.999" : 3.359691878973976, + "99.9999" : 3.359691878973976, + "100.0" : 3.359691878973976 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3489262131874447, + 3.355054250916895 + ], + [ + 3.35758429070566, + 3.359691878973976 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.693390837980584, + "scoreError" : 0.02960694075601076, + "scoreConfidence" : [ + 1.6637838972245733, + 1.7229977787365947 + ], + "scorePercentiles" : { + "0.0" : 1.6887998988299189, + "50.0" : 1.6936222215794623, + "90.0" : 1.6975190099334927, + "95.0" : 1.6975190099334927, + "99.0" : 1.6975190099334927, + "99.9" : 1.6975190099334927, + "99.99" : 1.6975190099334927, + "99.999" : 1.6975190099334927, + "99.9999" : 1.6975190099334927, + "100.0" : 1.6975190099334927 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6887998988299189, + 1.6901043734861991 + ], + [ + 1.6971400696727252, + 1.6975190099334927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8581819685206622, + "scoreError" : 0.015737855953137942, + "scoreConfidence" : [ + 0.8424441125675243, + 0.8739198244738001 + ], + "scorePercentiles" : { + "0.0" : 0.8560888448782534, + "50.0" : 0.8575889101396239, + "90.0" : 0.8614612089251477, + "95.0" : 0.8614612089251477, + "99.0" : 0.8614612089251477, + "99.9" : 0.8614612089251477, + "99.99" : 0.8614612089251477, + "99.999" : 0.8614612089251477, + "99.9999" : 0.8614612089251477, + "100.0" : 0.8614612089251477 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8565999109974037, + 0.8614612089251477 + ], + [ + 0.8560888448782534, + 0.8585779092818442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.650268493017055, + "scoreError" : 0.7767883489313367, + "scoreConfidence" : [ + 15.873480144085718, + 17.427056841948392 + ], + "scorePercentiles" : { + "0.0" : 16.390146442378825, + "50.0" : 16.64256496798029, + "90.0" : 16.93202356270371, + "95.0" : 16.93202356270371, + "99.0" : 16.93202356270371, + "99.9" : 16.93202356270371, + "99.99" : 16.93202356270371, + "99.999" : 16.93202356270371, + "99.9999" : 16.93202356270371, + "100.0" : 16.93202356270371 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.87951694231654, + 16.93202356270371, + 16.896347533085525 + ], + [ + 16.390146442378825, + 16.39796348397369, + 16.405612993644045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2782.5178180288585, + "scoreError" : 150.78187530267343, + "scoreConfidence" : [ + 2631.735942726185, + 2933.299693331532 + ], + "scorePercentiles" : { + "0.0" : 2729.649988265249, + "50.0" : 2781.975064833364, + "90.0" : 2836.866598164395, + "95.0" : 2836.866598164395, + "99.0" : 2836.866598164395, + "99.9" : 2836.866598164395, + "99.99" : 2836.866598164395, + "99.999" : 2836.866598164395, + "99.9999" : 2836.866598164395, + "100.0" : 2836.866598164395 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2832.4251745689007, + 2824.9035332360822, + 2836.866598164395 + ], + [ + 2732.2150175078787, + 2729.649988265249, + 2739.046596430645 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76784.9357927587, + "scoreError" : 983.6004942484963, + "scoreConfidence" : [ + 75801.3352985102, + 77768.5362870072 + ], + "scorePercentiles" : { + "0.0" : 76424.49424601327, + "50.0" : 76783.8121241946, + "90.0" : 77138.80417438509, + "95.0" : 77138.80417438509, + "99.0" : 77138.80417438509, + "99.9" : 77138.80417438509, + "99.99" : 77138.80417438509, + "99.999" : 77138.80417438509, + "99.9999" : 77138.80417438509, + "100.0" : 77138.80417438509 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76496.15537192616, + 76477.50260703718, + 76424.49424601327 + ], + [ + 77101.18948072744, + 77138.80417438509, + 77071.46887646307 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.65470880480916, + "scoreError" : 10.423132454794835, + "scoreConfidence" : [ + 351.23157635001434, + 372.077841259604 + ], + "scorePercentiles" : { + "0.0" : 358.2272006025982, + "50.0" : 361.3078071206453, + "90.0" : 366.16631658023755, + "95.0" : 366.16631658023755, + "99.0" : 366.16631658023755, + "99.9" : 366.16631658023755, + "99.99" : 366.16631658023755, + "99.999" : 366.16631658023755, + "99.9999" : 366.16631658023755, + "100.0" : 366.16631658023755 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.16631658023755, + 364.25809480170295, + 364.5621719718059 + ], + [ + 358.2272006025982, + 358.35694943292236, + 358.3575194395876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.14577470612043, + "scoreError" : 6.319167859770692, + "scoreConfidence" : [ + 108.82660684634975, + 121.46494256589112 + ], + "scorePercentiles" : { + "0.0" : 112.8896660348153, + "50.0" : 114.69414174834648, + "90.0" : 117.98841173274515, + "95.0" : 117.98841173274515, + "99.0" : 117.98841173274515, + "99.9" : 117.98841173274515, + "99.99" : 117.98841173274515, + "99.999" : 117.98841173274515, + "99.9999" : 117.98841173274515, + "100.0" : 117.98841173274515 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.90448259432385, + 117.98841173274515, + 117.40559606217705 + ], + [ + 113.20269091029216, + 113.48380090236913, + 112.8896660348153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06059127442503907, + "scoreError" : 1.5554258024931013E-4, + "scoreConfidence" : [ + 0.06043573184478976, + 0.060746817005288375 + ], + "scorePercentiles" : { + "0.0" : 0.06050131054886017, + "50.0" : 0.060603343537398824, + "90.0" : 0.06064565371903333, + "95.0" : 0.06064565371903333, + "99.0" : 0.06064565371903333, + "99.9" : 0.06064565371903333, + "99.99" : 0.06064565371903333, + "99.999" : 0.06064565371903333, + "99.9999" : 0.06064565371903333, + "100.0" : 0.06064565371903333 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060641574199847184, + 0.06060236977310741, + 0.06064565371903333 + ], + [ + 0.06060431730169023, + 0.06055242100769608, + 0.06050131054886017 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.601026604506969E-4, + "scoreError" : 1.9819603092252923E-6, + "scoreConfidence" : [ + 3.581207001414716E-4, + 3.620846207599222E-4 + ], + "scorePercentiles" : { + "0.0" : 3.594077976533664E-4, + "50.0" : 3.6009308724864036E-4, + "90.0" : 3.6095189598293263E-4, + "95.0" : 3.6095189598293263E-4, + "99.0" : 3.6095189598293263E-4, + "99.9" : 3.6095189598293263E-4, + "99.99" : 3.6095189598293263E-4, + "99.999" : 3.6095189598293263E-4, + "99.9999" : 3.6095189598293263E-4, + "100.0" : 3.6095189598293263E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.606163546400467E-4, + 3.6064198798842727E-4, + 3.6095189598293263E-4 + ], + [ + 3.594077976533664E-4, + 3.594281065821746E-4, + 3.5956981985723404E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12418701275997601, + "scoreError" : 0.0035839483863352346, + "scoreConfidence" : [ + 0.12060306437364078, + 0.12777096114631126 + ], + "scorePercentiles" : { + "0.0" : 0.12293411060162762, + "50.0" : 0.1241676744395013, + "90.0" : 0.1254135146479721, + "95.0" : 0.1254135146479721, + "99.0" : 0.1254135146479721, + "99.9" : 0.1254135146479721, + "99.99" : 0.1254135146479721, + "99.999" : 0.1254135146479721, + "99.9999" : 0.1254135146479721, + "100.0" : 0.1254135146479721 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1230992162069008, + 0.12293411060162762, + 0.12303481936293507 + ], + [ + 0.1252361326721018, + 0.1254135146479721, + 0.1254042830683186 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012976240293775027, + "scoreError" : 1.5034914932536146E-4, + "scoreConfidence" : [ + 0.012825891144449665, + 0.013126589443100389 + ], + "scorePercentiles" : { + "0.0" : 0.012925125507145599, + "50.0" : 0.012975020998023883, + "90.0" : 0.01303144844953765, + "95.0" : 0.01303144844953765, + "99.0" : 0.01303144844953765, + "99.9" : 0.01303144844953765, + "99.99" : 0.01303144844953765, + "99.999" : 0.01303144844953765, + "99.9999" : 0.01303144844953765, + "100.0" : 0.01303144844953765 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01303144844953765, + 0.013022313691198608, + 0.013021437488931946 + ], + [ + 0.012928604507115818, + 0.012925125507145599, + 0.01292851211872054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9735437818773524, + "scoreError" : 0.01770260727615262, + "scoreConfidence" : [ + 0.9558411746011998, + 0.9912463891535049 + ], + "scorePercentiles" : { + "0.0" : 0.964080837944664, + "50.0" : 0.9720882981926966, + "90.0" : 0.9809756350171652, + "95.0" : 0.9809756350171652, + "99.0" : 0.9809756350171652, + "99.9" : 0.9809756350171652, + "99.99" : 0.9809756350171652, + "99.999" : 0.9809756350171652, + "99.9999" : 0.9809756350171652, + "100.0" : 0.9809756350171652 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.964080837944664, + 0.9803636567983531, + 0.9809756350171652 + ], + [ + 0.9716659651185386, + 0.9724133431544146, + 0.9717632532309786 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011280642379926794, + "scoreError" : 3.505701381248431E-4, + "scoreConfidence" : [ + 0.01093007224180195, + 0.011631212518051636 + ], + "scorePercentiles" : { + "0.0" : 0.011160072226177748, + "50.0" : 0.011279874302047757, + "90.0" : 0.011410773677352217, + "95.0" : 0.011410773677352217, + "99.0" : 0.011410773677352217, + "99.9" : 0.011410773677352217, + "99.99" : 0.011410773677352217, + "99.999" : 0.011410773677352217, + "99.9999" : 0.011410773677352217, + "100.0" : 0.011410773677352217 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011410773677352217, + 0.011391183885526042, + 0.011380859270049733 + ], + [ + 0.011162075886409247, + 0.011178889334045783, + 0.011160072226177748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1910874204484645, + "scoreError" : 0.0627220484176189, + "scoreConfidence" : [ + 3.1283653720308457, + 3.2538094688660832 + ], + "scorePercentiles" : { + "0.0" : 3.163626561669829, + "50.0" : 3.193272353999566, + "90.0" : 3.2125267071290944, + "95.0" : 3.2125267071290944, + "99.0" : 3.2125267071290944, + "99.9" : 3.2125267071290944, + "99.99" : 3.2125267071290944, + "99.999" : 3.2125267071290944, + "99.9999" : 3.2125267071290944, + "100.0" : 3.2125267071290944 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.17214985225111, + 3.1775300819567978, + 3.163626561669829 + ], + [ + 3.2116766936416186, + 3.2125267071290944, + 3.2090146260423347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6533328512416032, + "scoreError" : 0.017166451234994457, + "scoreConfidence" : [ + 2.636166400006609, + 2.6704993024765975 + ], + "scorePercentiles" : { + "0.0" : 2.6453069418143347, + "50.0" : 2.653733123391657, + "90.0" : 2.6608787720138336, + "95.0" : 2.6608787720138336, + "99.0" : 2.6608787720138336, + "99.9" : 2.6608787720138336, + "99.99" : 2.6608787720138336, + "99.999" : 2.6608787720138336, + "99.9999" : 2.6608787720138336, + "100.0" : 2.6608787720138336 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6608787720138336, + 2.657953804677119, + 2.656889790382572 + ], + [ + 2.650576456400742, + 2.648391342161017, + 2.6453069418143347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1787263824513697, + "scoreError" : 0.0035420271382964846, + "scoreConfidence" : [ + 0.17518435531307322, + 0.1822684095896662 + ], + "scorePercentiles" : { + "0.0" : 0.17749152617940436, + "50.0" : 0.1786193503115488, + "90.0" : 0.18011950147694525, + "95.0" : 0.18011950147694525, + "99.0" : 0.18011950147694525, + "99.9" : 0.18011950147694525, + "99.99" : 0.18011950147694525, + "99.999" : 0.18011950147694525, + "99.9999" : 0.18011950147694525, + "100.0" : 0.18011950147694525 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17761668992220525, + 0.1776449230468611, + 0.17749152617940436 + ], + [ + 0.17989187650656593, + 0.18011950147694525, + 0.17959377757623649 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3277736552476341, + "scoreError" : 0.009626807327651036, + "scoreConfidence" : [ + 0.31814684791998304, + 0.3374004625752851 + ], + "scorePercentiles" : { + "0.0" : 0.3229094516774839, + "50.0" : 0.3287168355966337, + "90.0" : 0.330930362619544, + "95.0" : 0.330930362619544, + "99.0" : 0.330930362619544, + "99.9" : 0.330930362619544, + "99.99" : 0.330930362619544, + "99.999" : 0.330930362619544, + "99.9999" : 0.330930362619544, + "100.0" : 0.330930362619544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32693886128547145, + 0.3229094516774839, + 0.32475292404364486 + ], + [ + 0.330930362619544, + 0.330494809907796, + 0.3306155219518646 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.13945600831798408, + "scoreError" : 0.009609701362911878, + "scoreConfidence" : [ + 0.1298463069550722, + 0.14906570968089594 + ], + "scorePercentiles" : { + "0.0" : 0.13572622595312098, + "50.0" : 0.13907296816708287, + "90.0" : 0.14378956588255593, + "95.0" : 0.14378956588255593, + "99.0" : 0.14378956588255593, + "99.9" : 0.14378956588255593, + "99.99" : 0.14378956588255593, + "99.999" : 0.14378956588255593, + "99.9999" : 0.14378956588255593, + "100.0" : 0.14378956588255593 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14378956588255593, + 0.14307050002146016, + 0.13845975851851852 + ], + [ + 0.1396861778156472, + 0.13572622595312098, + 0.1360038217166016 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3985150274811047, + "scoreError" : 0.02800248730669272, + "scoreConfidence" : [ + 0.37051254017441193, + 0.4265175147877974 + ], + "scorePercentiles" : { + "0.0" : 0.3871723473227767, + "50.0" : 0.4003953489419816, + "90.0" : 0.4079391089581464, + "95.0" : 0.4079391089581464, + "99.0" : 0.4079391089581464, + "99.9" : 0.4079391089581464, + "99.99" : 0.4079391089581464, + "99.999" : 0.4079391089581464, + "99.9999" : 0.4079391089581464, + "100.0" : 0.4079391089581464 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4072222865985259, + 0.4079391089581464, + 0.40698896605754753 + ], + [ + 0.3938017318264157, + 0.3879657241232154, + 0.3871723473227767 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15448244128381358, + "scoreError" : 5.89213777021657E-4, + "scoreConfidence" : [ + 0.15389322750679194, + 0.15507165506083523 + ], + "scorePercentiles" : { + "0.0" : 0.15422005116895934, + "50.0" : 0.1544669877670076, + "90.0" : 0.15473506907222875, + "95.0" : 0.15473506907222875, + "99.0" : 0.15473506907222875, + "99.9" : 0.15473506907222875, + "99.99" : 0.15473506907222875, + "99.999" : 0.15473506907222875, + "99.9999" : 0.15473506907222875, + "100.0" : 0.15473506907222875 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15469080968954477, + 0.15473506907222875, + 0.15455660713733732 + ], + [ + 0.15422005116895934, + 0.15431474223813346, + 0.15437736839667787 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047019876893764086, + "scoreError" : 6.3864915970609E-4, + "scoreConfidence" : [ + 0.046381227734058, + 0.04765852605347017 + ], + "scorePercentiles" : { + "0.0" : 0.046678125893874045, + "50.0" : 0.046971939101597374, + "90.0" : 0.04731776117630359, + "95.0" : 0.04731776117630359, + "99.0" : 0.04731776117630359, + "99.9" : 0.04731776117630359, + "99.99" : 0.04731776117630359, + "99.999" : 0.04731776117630359, + "99.9999" : 0.04731776117630359, + "100.0" : 0.04731776117630359 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046992444194865673, + 0.04695143400832907, + 0.046950792949969955 + ], + [ + 0.04731776117630359, + 0.04722870313924218, + 0.046678125893874045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8401325.853389855, + "scoreError" : 131504.84064462886, + "scoreConfidence" : [ + 8269821.012745227, + 8532830.694034485 + ], + "scorePercentiles" : { + "0.0" : 8358130.066833751, + "50.0" : 8395696.085385714, + "90.0" : 8467619.102455545, + "95.0" : 8467619.102455545, + "99.0" : 8467619.102455545, + "99.9" : 8467619.102455545, + "99.99" : 8467619.102455545, + "99.999" : 8467619.102455545, + "99.9999" : 8467619.102455545, + "100.0" : 8467619.102455545 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8359222.380952381, + 8364205.1438127095, + 8358130.066833751 + ], + [ + 8467619.102455545, + 8427187.026958719, + 8431591.399326032 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-26T03:45:33Z-6e9e023a9bfcb7ac009ca303bb6aadb9f59c634f-jdk17.json b/performance-results/2025-05-26T03:45:33Z-6e9e023a9bfcb7ac009ca303bb6aadb9f59c634f-jdk17.json new file mode 100644 index 0000000000..f529f26b93 --- /dev/null +++ b/performance-results/2025-05-26T03:45:33Z-6e9e023a9bfcb7ac009ca303bb6aadb9f59c634f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3614714348268766, + "scoreError" : 0.023730264725304887, + "scoreConfidence" : [ + 3.337741170101572, + 3.3852016995521814 + ], + "scorePercentiles" : { + "0.0" : 3.357414067104462, + "50.0" : 3.3613794971751148, + "90.0" : 3.3657126778528133, + "95.0" : 3.3657126778528133, + "99.0" : 3.3657126778528133, + "99.9" : 3.3657126778528133, + "99.99" : 3.3657126778528133, + "99.999" : 3.3657126778528133, + "99.9999" : 3.3657126778528133, + "100.0" : 3.3657126778528133 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.357414067104462, + 3.359648927153407 + ], + [ + 3.3631100671968226, + 3.3657126778528133 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6962817844570828, + "scoreError" : 0.03622820318709655, + "scoreConfidence" : [ + 1.6600535812699861, + 1.7325099876441794 + ], + "scorePercentiles" : { + "0.0" : 1.690711715576101, + "50.0" : 1.6963508243773273, + "90.0" : 1.7017137734975756, + "95.0" : 1.7017137734975756, + "99.0" : 1.7017137734975756, + "99.9" : 1.7017137734975756, + "99.99" : 1.7017137734975756, + "99.999" : 1.7017137734975756, + "99.9999" : 1.7017137734975756, + "100.0" : 1.7017137734975756 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.690711715576101, + 1.6922427878287205 + ], + [ + 1.7004588609259341, + 1.7017137734975756 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.851620858898376, + "scoreError" : 0.030261899132737996, + "scoreConfidence" : [ + 0.821358959765638, + 0.881882758031114 + ], + "scorePercentiles" : { + "0.0" : 0.8454826620983287, + "50.0" : 0.8523796671157864, + "90.0" : 0.8562414392636027, + "95.0" : 0.8562414392636027, + "99.0" : 0.8562414392636027, + "99.9" : 0.8562414392636027, + "99.99" : 0.8562414392636027, + "99.999" : 0.8562414392636027, + "99.9999" : 0.8562414392636027, + "100.0" : 0.8562414392636027 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8507041944482526, + 0.8562414392636027 + ], + [ + 0.8454826620983287, + 0.85405513978332 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.328236098591066, + "scoreError" : 0.1599667742886451, + "scoreConfidence" : [ + 16.168269324302422, + 16.48820287287971 + ], + "scorePercentiles" : { + "0.0" : 16.259886445903398, + "50.0" : 16.331649995849233, + "90.0" : 16.391977039606704, + "95.0" : 16.391977039606704, + "99.0" : 16.391977039606704, + "99.9" : 16.391977039606704, + "99.99" : 16.391977039606704, + "99.999" : 16.391977039606704, + "99.9999" : 16.391977039606704, + "100.0" : 16.391977039606704 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.37098061248881, + 16.37412073937079, + 16.391977039606704 + ], + [ + 16.28013237496706, + 16.29231937920966, + 16.259886445903398 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2813.852287068455, + "scoreError" : 73.46350599468525, + "scoreConfidence" : [ + 2740.3887810737697, + 2887.3157930631405 + ], + "scorePercentiles" : { + "0.0" : 2778.689724756634, + "50.0" : 2816.1433312413237, + "90.0" : 2838.152239402783, + "95.0" : 2838.152239402783, + "99.0" : 2838.152239402783, + "99.9" : 2838.152239402783, + "99.99" : 2838.152239402783, + "99.999" : 2838.152239402783, + "99.9999" : 2838.152239402783, + "100.0" : 2838.152239402783 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2778.689724756634, + 2797.497743153841, + 2796.0259982634466 + ], + [ + 2837.9590975052183, + 2838.152239402783, + 2834.7889193288065 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77596.47334592814, + "scoreError" : 2214.590397392616, + "scoreConfidence" : [ + 75381.88294853552, + 79811.06374332076 + ], + "scorePercentiles" : { + "0.0" : 76865.39029436032, + "50.0" : 77591.17630082692, + "90.0" : 78369.13659056665, + "95.0" : 78369.13659056665, + "99.0" : 78369.13659056665, + "99.9" : 78369.13659056665, + "99.99" : 78369.13659056665, + "99.999" : 78369.13659056665, + "99.9999" : 78369.13659056665, + "100.0" : 78369.13659056665 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76894.50354849873, + 76865.39029436032, + 76868.32781949542 + ], + [ + 78287.84905315512, + 78293.63276949254, + 78369.13659056665 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 368.1424097942556, + "scoreError" : 19.501545043130996, + "scoreConfidence" : [ + 348.64086475112464, + 387.6439548373866 + ], + "scorePercentiles" : { + "0.0" : 361.63724429339584, + "50.0" : 368.0868787665804, + "90.0" : 374.8018399977875, + "95.0" : 374.8018399977875, + "99.0" : 374.8018399977875, + "99.9" : 374.8018399977875, + "99.99" : 374.8018399977875, + "99.999" : 374.8018399977875, + "99.9999" : 374.8018399977875, + "100.0" : 374.8018399977875 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 374.25302555664666, + 374.8018399977875, + 374.4099290270758 + ], + [ + 361.9207319765142, + 361.8316879141139, + 361.63724429339584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.64137479006438, + "scoreError" : 4.4047327208724765, + "scoreConfidence" : [ + 108.2366420691919, + 117.04610751093685 + ], + "scorePercentiles" : { + "0.0" : 110.49395248918994, + "50.0" : 113.06679898430392, + "90.0" : 114.25698865358899, + "95.0" : 114.25698865358899, + "99.0" : 114.25698865358899, + "99.9" : 114.25698865358899, + "99.99" : 114.25698865358899, + "99.999" : 114.25698865358899, + "99.9999" : 114.25698865358899, + "100.0" : 114.25698865358899 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.49395248918994, + 111.07185808985291, + 112.46433866036132 + ], + [ + 113.66925930824652, + 114.25698865358899, + 113.89185153914651 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06147850547103111, + "scoreError" : 0.0023284702367402255, + "scoreConfidence" : [ + 0.05915003523429089, + 0.06380697570777134 + ], + "scorePercentiles" : { + "0.0" : 0.0606144883045721, + "50.0" : 0.061487224399485244, + "90.0" : 0.062443772532564036, + "95.0" : 0.062443772532564036, + "99.0" : 0.062443772532564036, + "99.9" : 0.062443772532564036, + "99.99" : 0.062443772532564036, + "99.999" : 0.062443772532564036, + "99.9999" : 0.062443772532564036, + "100.0" : 0.062443772532564036 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0621282459555169, + 0.06210219740045209, + 0.062443772532564036 + ], + [ + 0.060872251398518394, + 0.060710077234563106, + 0.0606144883045721 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.655511578901231E-4, + "scoreError" : 3.0723521523622295E-6, + "scoreConfidence" : [ + 3.6247880573776086E-4, + 3.6862351004248535E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6427925177357244E-4, + "50.0" : 3.6528128404572863E-4, + "90.0" : 3.674832453939252E-4, + "95.0" : 3.674832453939252E-4, + "99.0" : 3.674832453939252E-4, + "99.9" : 3.674832453939252E-4, + "99.99" : 3.674832453939252E-4, + "99.999" : 3.674832453939252E-4, + "99.9999" : 3.674832453939252E-4, + "100.0" : 3.674832453939252E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.650033329407174E-4, + 3.651743189870615E-4, + 3.653882491043957E-4 + ], + [ + 3.674832453939252E-4, + 3.659785491410664E-4, + 3.6427925177357244E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12147732072933852, + "scoreError" : 3.219580011016646E-4, + "scoreConfidence" : [ + 0.12115536272823685, + 0.12179927873044019 + ], + "scorePercentiles" : { + "0.0" : 0.12135218729218747, + "50.0" : 0.12146356598028832, + "90.0" : 0.1216369989782762, + "95.0" : 0.1216369989782762, + "99.0" : 0.1216369989782762, + "99.9" : 0.1216369989782762, + "99.99" : 0.1216369989782762, + "99.999" : 0.1216369989782762, + "99.9999" : 0.1216369989782762, + "100.0" : 0.1216369989782762 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12153447687857759, + 0.12139265508199905, + 0.12138925979291341 + ], + [ + 0.1216369989782762, + 0.12135218729218747, + 0.1215583463520774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012766078080547286, + "scoreError" : 7.432614842799652E-4, + "scoreConfidence" : [ + 0.01202281659626732, + 0.013509339564827251 + ], + "scorePercentiles" : { + "0.0" : 0.012514292589009844, + "50.0" : 0.012768145273215195, + "90.0" : 0.013017491898027618, + "95.0" : 0.013017491898027618, + "99.0" : 0.013017491898027618, + "99.9" : 0.013017491898027618, + "99.99" : 0.013017491898027618, + "99.999" : 0.013017491898027618, + "99.9999" : 0.013017491898027618, + "100.0" : 0.013017491898027618 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012543586387651273, + 0.012514292589009844, + 0.01251540483863499 + ], + [ + 0.013017491898027618, + 0.013012988611180875, + 0.012992704158779117 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0196311993562193, + "scoreError" : 0.01283966206251965, + "scoreConfidence" : [ + 1.0067915372936995, + 1.032470861418739 + ], + "scorePercentiles" : { + "0.0" : 1.0133841465194042, + "50.0" : 1.0188113735998054, + "90.0" : 1.0266213273791192, + "95.0" : 1.0266213273791192, + "99.0" : 1.0266213273791192, + "99.9" : 1.0266213273791192, + "99.99" : 1.0266213273791192, + "99.999" : 1.0266213273791192, + "99.9999" : 1.0266213273791192, + "100.0" : 1.0266213273791192 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0228221251917766, + 1.0185404550361543, + 1.0266213273791192 + ], + [ + 1.0190822921634566, + 1.0133841465194042, + 1.0173368498474058 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011282248798704155, + "scoreError" : 8.665969514843246E-4, + "scoreConfidence" : [ + 0.01041565184721983, + 0.01214884575018848 + ], + "scorePercentiles" : { + "0.0" : 0.010991958227171904, + "50.0" : 0.01128469994569675, + "90.0" : 0.011566696598308985, + "95.0" : 0.011566696598308985, + "99.0" : 0.011566696598308985, + "99.9" : 0.011566696598308985, + "99.99" : 0.011566696598308985, + "99.999" : 0.011566696598308985, + "99.9999" : 0.011566696598308985, + "100.0" : 0.011566696598308985 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011566696598308985, + 0.011560329199468238, + 0.011565901123252436 + ], + [ + 0.010991958227171904, + 0.011009070691925263, + 0.010999536952098113 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1373012986232642, + "scoreError" : 0.30535302635071476, + "scoreConfidence" : [ + 2.8319482722725495, + 3.442654324973979 + ], + "scorePercentiles" : { + "0.0" : 3.035403775485437, + "50.0" : 3.1366105918609364, + "90.0" : 3.241204611147116, + "95.0" : 3.241204611147116, + "99.0" : 3.241204611147116, + "99.9" : 3.241204611147116, + "99.99" : 3.241204611147116, + "99.999" : 3.241204611147116, + "99.9999" : 3.241204611147116, + "100.0" : 3.241204611147116 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0415834020681265, + 3.0368725094110505, + 3.035403775485437 + ], + [ + 3.2316377816537467, + 3.241204611147116, + 3.23710571197411 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6491367156774066, + "scoreError" : 0.05650122024386562, + "scoreConfidence" : [ + 2.592635495433541, + 2.7056379359212723 + ], + "scorePercentiles" : { + "0.0" : 2.6254675991073775, + "50.0" : 2.648729287550855, + "90.0" : 2.678552433851098, + "95.0" : 2.678552433851098, + "99.0" : 2.678552433851098, + "99.9" : 2.678552433851098, + "99.99" : 2.678552433851098, + "99.999" : 2.678552433851098, + "99.9999" : 2.678552433851098, + "100.0" : 2.678552433851098 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6380909680823, + 2.6331517006319114, + 2.6254675991073775 + ], + [ + 2.678552433851098, + 2.6601899853723405, + 2.65936760701941 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17702547118618883, + "scoreError" : 0.002225237339140757, + "scoreConfidence" : [ + 0.17480023384704807, + 0.1792507085253296 + ], + "scorePercentiles" : { + "0.0" : 0.17618010371375215, + "50.0" : 0.17704507386369328, + "90.0" : 0.17782491446760082, + "95.0" : 0.17782491446760082, + "99.0" : 0.17782491446760082, + "99.9" : 0.17782491446760082, + "99.99" : 0.17782491446760082, + "99.999" : 0.17782491446760082, + "99.9999" : 0.17782491446760082, + "100.0" : 0.17782491446760082 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17782491446760082, + 0.1777458098005759, + 0.1776638920906765 + ], + [ + 0.17642625563671008, + 0.17618010371375215, + 0.1763118514078175 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31393337094165, + "scoreError" : 0.014401946094595957, + "scoreConfidence" : [ + 0.2995314248470541, + 0.32833531703624597 + ], + "scorePercentiles" : { + "0.0" : 0.30903255562422743, + "50.0" : 0.31388112620180975, + "90.0" : 0.31902956533529, + "95.0" : 0.31902956533529, + "99.0" : 0.31902956533529, + "99.9" : 0.31902956533529, + "99.99" : 0.31902956533529, + "99.999" : 0.31902956533529, + "99.9999" : 0.31902956533529, + "100.0" : 0.31902956533529 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3094502182819656, + 0.30903255562422743, + 0.30927158153703416 + ], + [ + 0.31902956533529, + 0.31850427074972926, + 0.3183120341216539 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14760101212202417, + "scoreError" : 0.01383644471042753, + "scoreConfidence" : [ + 0.13376456741159665, + 0.1614374568324517 + ], + "scorePercentiles" : { + "0.0" : 0.14302856689264568, + "50.0" : 0.14756751791979614, + "90.0" : 0.15221194875190258, + "95.0" : 0.15221194875190258, + "99.0" : 0.15221194875190258, + "99.9" : 0.15221194875190258, + "99.99" : 0.15221194875190258, + "99.999" : 0.15221194875190258, + "99.9999" : 0.15221194875190258, + "100.0" : 0.15221194875190258 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15221194875190258, + 0.1521647355143031, + 0.1519359289718774 + ], + [ + 0.14319910686771486, + 0.14302856689264568, + 0.1430657857337015 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3916138479368183, + "scoreError" : 0.012535842365686277, + "scoreConfidence" : [ + 0.379078005571132, + 0.4041496903025046 + ], + "scorePercentiles" : { + "0.0" : 0.3860144325085884, + "50.0" : 0.3925293881449001, + "90.0" : 0.39639481040906926, + "95.0" : 0.39639481040906926, + "99.0" : 0.39639481040906926, + "99.9" : 0.39639481040906926, + "99.99" : 0.39639481040906926, + "99.999" : 0.39639481040906926, + "99.9999" : 0.39639481040906926, + "100.0" : 0.39639481040906926 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39532098248804204, + 0.39639481040906926, + 0.39453138635735985 + ], + [ + 0.39052738993244035, + 0.3868940859254101, + 0.3860144325085884 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15209557792349654, + "scoreError" : 0.007169311210385957, + "scoreConfidence" : [ + 0.14492626671311057, + 0.1592648891338825 + ], + "scorePercentiles" : { + "0.0" : 0.14992068262772848, + "50.0" : 0.15152611853143644, + "90.0" : 0.15630555441629285, + "95.0" : 0.15630555441629285, + "99.0" : 0.15630555441629285, + "99.9" : 0.15630555441629285, + "99.99" : 0.15630555441629285, + "99.999" : 0.15630555441629285, + "99.9999" : 0.15630555441629285, + "100.0" : 0.15630555441629285 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15630555441629285, + 0.15322737660885022, + 0.1529728295320698 + ], + [ + 0.14992068262772848, + 0.15007940753080307, + 0.15006761682523484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04745508248648409, + "scoreError" : 0.0010635545155073974, + "scoreConfidence" : [ + 0.0463915279709767, + 0.04851863700199149 + ], + "scorePercentiles" : { + "0.0" : 0.04702969041785219, + "50.0" : 0.047468857613714166, + "90.0" : 0.04792646974445978, + "95.0" : 0.04792646974445978, + "99.0" : 0.04792646974445978, + "99.9" : 0.04792646974445978, + "99.99" : 0.04792646974445978, + "99.999" : 0.04792646974445978, + "99.9999" : 0.04792646974445978, + "100.0" : 0.04792646974445978 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04792646974445978, + 0.04780433725960734, + 0.047382369942004815 + ], + [ + 0.047555345285423524, + 0.04702969041785219, + 0.04703228226955691 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8618132.613253148, + "scoreError" : 28997.403884526953, + "scoreConfidence" : [ + 8589135.209368622, + 8647130.017137675 + ], + "scorePercentiles" : { + "0.0" : 8603472.471195186, + "50.0" : 8620817.683484066, + "90.0" : 8628014.930172414, + "95.0" : 8628014.930172414, + "99.0" : 8628014.930172414, + "99.9" : 8628014.930172414, + "99.99" : 8628014.930172414, + "99.999" : 8628014.930172414, + "99.9999" : 8628014.930172414, + "100.0" : 8628014.930172414 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8628014.930172414, + 8623291.05, + 8627716.897413794 + ], + [ + 8607956.013769364, + 8618344.316968132, + 8603472.471195186 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-27T08:51:22Z-27a71b2d3a48a9b168878df96c7dd7166471c4ec-jdk17.json b/performance-results/2025-05-27T08:51:22Z-27a71b2d3a48a9b168878df96c7dd7166471c4ec-jdk17.json new file mode 100644 index 0000000000..2acf834a18 --- /dev/null +++ b/performance-results/2025-05-27T08:51:22Z-27a71b2d3a48a9b168878df96c7dd7166471c4ec-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.34814208392132, + "scoreError" : 0.03980385542138689, + "scoreConfidence" : [ + 3.3083382284999328, + 3.387945939342707 + ], + "scorePercentiles" : { + "0.0" : 3.342277998332218, + "50.0" : 3.347096749364452, + "90.0" : 3.3560968386241568, + "95.0" : 3.3560968386241568, + "99.0" : 3.3560968386241568, + "99.9" : 3.3560968386241568, + "99.99" : 3.3560968386241568, + "99.999" : 3.3560968386241568, + "99.9999" : 3.3560968386241568, + "100.0" : 3.3560968386241568 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.342277998332218, + 3.34974007087489 + ], + [ + 3.3444534278540137, + 3.3560968386241568 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6881478079426446, + "scoreError" : 0.04575941559937918, + "scoreConfidence" : [ + 1.6423883923432654, + 1.7339072235420239 + ], + "scorePercentiles" : { + "0.0" : 1.6807256329018374, + "50.0" : 1.6881508810246513, + "90.0" : 1.6955638368194386, + "95.0" : 1.6955638368194386, + "99.0" : 1.6955638368194386, + "99.9" : 1.6955638368194386, + "99.99" : 1.6955638368194386, + "99.999" : 1.6955638368194386, + "99.9999" : 1.6955638368194386, + "100.0" : 1.6955638368194386 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6807256329018374, + 1.6836592720421095 + ], + [ + 1.6926424900071932, + 1.6955638368194386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8505912976048506, + "scoreError" : 0.029344760700535943, + "scoreConfidence" : [ + 0.8212465369043147, + 0.8799360583053866 + ], + "scorePercentiles" : { + "0.0" : 0.8459571299364086, + "50.0" : 0.8502503813332682, + "90.0" : 0.8559072978164576, + "95.0" : 0.8559072978164576, + "99.0" : 0.8559072978164576, + "99.9" : 0.8559072978164576, + "99.99" : 0.8559072978164576, + "99.999" : 0.8559072978164576, + "99.9999" : 0.8559072978164576, + "100.0" : 0.8559072978164576 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8459571299364086, + 0.8526894265828573 + ], + [ + 0.8478113360836792, + 0.8559072978164576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.257992756399528, + "scoreError" : 0.03758079825652606, + "scoreConfidence" : [ + 16.220411958143, + 16.295573554656055 + ], + "scorePercentiles" : { + "0.0" : 16.242897432179504, + "50.0" : 16.258776498158145, + "90.0" : 16.274466607874377, + "95.0" : 16.274466607874377, + "99.0" : 16.274466607874377, + "99.9" : 16.274466607874377, + "99.99" : 16.274466607874377, + "99.999" : 16.274466607874377, + "99.9999" : 16.274466607874377, + "100.0" : 16.274466607874377 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.274466607874377, + 16.269067978687023, + 16.265032846835492 + ], + [ + 16.24397152333997, + 16.242897432179504, + 16.252520149480798 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2617.983139296641, + "scoreError" : 184.7011599734979, + "scoreConfidence" : [ + 2433.2819793231433, + 2802.684299270139 + ], + "scorePercentiles" : { + "0.0" : 2556.381605593551, + "50.0" : 2619.039889932432, + "90.0" : 2678.329687455635, + "95.0" : 2678.329687455635, + "99.0" : 2678.329687455635, + "99.9" : 2678.329687455635, + "99.99" : 2678.329687455635, + "99.999" : 2678.329687455635, + "99.9999" : 2678.329687455635, + "100.0" : 2678.329687455635 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2678.090770519794, + 2678.329687455635, + 2677.8756924811564 + ], + [ + 2556.381605593551, + 2560.204087383707, + 2557.0169923460035 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76399.52247218134, + "scoreError" : 277.31048491386997, + "scoreConfidence" : [ + 76122.21198726747, + 76676.83295709522 + ], + "scorePercentiles" : { + "0.0" : 76295.56853250694, + "50.0" : 76386.39102129872, + "90.0" : 76543.8514960974, + "95.0" : 76543.8514960974, + "99.0" : 76543.8514960974, + "99.9" : 76543.8514960974, + "99.99" : 76543.8514960974, + "99.999" : 76543.8514960974, + "99.9999" : 76543.8514960974, + "100.0" : 76543.8514960974 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76462.8635095208, + 76543.8514960974, + 76445.1468131089 + ], + [ + 76327.63522948854, + 76322.06925236547, + 76295.56853250694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.9028577206111, + "scoreError" : 10.683519201534338, + "scoreConfidence" : [ + 352.21933851907676, + 373.58637692214546 + ], + "scorePercentiles" : { + "0.0" : 358.3340361147952, + "50.0" : 363.1677812123269, + "90.0" : 366.62538256901263, + "95.0" : 366.62538256901263, + "99.0" : 366.62538256901263, + "99.9" : 366.62538256901263, + "99.99" : 366.62538256901263, + "99.999" : 366.62538256901263, + "99.9999" : 366.62538256901263, + "100.0" : 366.62538256901263 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.65117104123647, + 359.5265237441057, + 358.3340361147952 + ], + [ + 365.6843913834173, + 366.62538256901263, + 366.59564147109944 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.86006505853636, + "scoreError" : 6.48731814507662, + "scoreConfidence" : [ + 110.37274691345975, + 123.34738320361298 + ], + "scorePercentiles" : { + "0.0" : 114.66861380144546, + "50.0" : 116.78126588593946, + "90.0" : 119.10672745026966, + "95.0" : 119.10672745026966, + "99.0" : 119.10672745026966, + "99.9" : 119.10672745026966, + "99.99" : 119.10672745026966, + "99.999" : 119.10672745026966, + "99.9999" : 119.10672745026966, + "100.0" : 119.10672745026966 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 119.07252825308761, + 119.10672745026966, + 118.72423311504211 + ], + [ + 114.66861380144546, + 114.8382986568368, + 114.74998907453659 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06155172133323721, + "scoreError" : 3.2266152824694306E-4, + "scoreConfidence" : [ + 0.06122905980499027, + 0.06187438286148415 + ], + "scorePercentiles" : { + "0.0" : 0.06141200833962797, + "50.0" : 0.06151803176198145, + "90.0" : 0.06175221790786711, + "95.0" : 0.06175221790786711, + "99.0" : 0.06175221790786711, + "99.9" : 0.06175221790786711, + "99.99" : 0.06175221790786711, + "99.999" : 0.06175221790786711, + "99.9999" : 0.06175221790786711, + "100.0" : 0.06175221790786711 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06141200833962797, + 0.06152190000369126, + 0.06175221790786711 + ], + [ + 0.06151416352027164, + 0.061509419703651765, + 0.06160061852431347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.74179419012454E-4, + "scoreError" : 1.0756214526763104E-5, + "scoreConfidence" : [ + 3.634232044856909E-4, + 3.849356335392171E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7050227880352414E-4, + "50.0" : 3.740571455804957E-4, + "90.0" : 3.7808743226131944E-4, + "95.0" : 3.7808743226131944E-4, + "99.0" : 3.7808743226131944E-4, + "99.9" : 3.7808743226131944E-4, + "99.99" : 3.7808743226131944E-4, + "99.999" : 3.7808743226131944E-4, + "99.9999" : 3.7808743226131944E-4, + "100.0" : 3.7808743226131944E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7055961828791697E-4, + 3.7050227880352414E-4, + 3.710209701303108E-4 + ], + [ + 3.770933210306806E-4, + 3.7808743226131944E-4, + 3.7781289356097217E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1268802022980863, + "scoreError" : 0.009520261154938854, + "scoreConfidence" : [ + 0.11735994114314745, + 0.13640046345302514 + ], + "scorePercentiles" : { + "0.0" : 0.12376695106314513, + "50.0" : 0.12634937875526825, + "90.0" : 0.13065661295548675, + "95.0" : 0.13065661295548675, + "99.0" : 0.13065661295548675, + "99.9" : 0.13065661295548675, + "99.99" : 0.13065661295548675, + "99.999" : 0.13065661295548675, + "99.9999" : 0.13065661295548675, + "100.0" : 0.13065661295548675 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1287227311167748, + 0.13065661295548675, + 0.1303785778021147 + ], + [ + 0.12397602639376169, + 0.12376695106314513, + 0.12378031445723481 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012874845402550739, + "scoreError" : 4.610545707824252E-4, + "scoreConfidence" : [ + 0.012413790831768313, + 0.013335899973333164 + ], + "scorePercentiles" : { + "0.0" : 0.012714385865094512, + "50.0" : 0.01287412766541373, + "90.0" : 0.013031731777973541, + "95.0" : 0.013031731777973541, + "99.0" : 0.013031731777973541, + "99.9" : 0.013031731777973541, + "99.99" : 0.013031731777973541, + "99.999" : 0.013031731777973541, + "99.9999" : 0.013031731777973541, + "100.0" : 0.013031731777973541 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012729758377027665, + 0.012730560000865667, + 0.012714385865094512 + ], + [ + 0.01302494106438126, + 0.013031731777973541, + 0.013017695329961793 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9983100431779817, + "scoreError" : 0.050988826937066856, + "scoreConfidence" : [ + 0.9473212162409148, + 1.0492988701150485 + ], + "scorePercentiles" : { + "0.0" : 0.9794604709108717, + "50.0" : 0.9997606056636592, + "90.0" : 1.0149253270752994, + "95.0" : 1.0149253270752994, + "99.0" : 1.0149253270752994, + "99.9" : 1.0149253270752994, + "99.99" : 1.0149253270752994, + "99.999" : 1.0149253270752994, + "99.9999" : 1.0149253270752994, + "100.0" : 1.0149253270752994 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0148305803734523, + 1.014747443429731, + 1.0149253270752994 + ], + [ + 0.9811226693809477, + 0.9847737678975874, + 0.9794604709108717 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011120742015541911, + "scoreError" : 5.928333425436988E-4, + "scoreConfidence" : [ + 0.010527908672998212, + 0.01171357535808561 + ], + "scorePercentiles" : { + "0.0" : 0.0109265402284031, + "50.0" : 0.011120019902827228, + "90.0" : 0.01131878381908524, + "95.0" : 0.01131878381908524, + "99.0" : 0.01131878381908524, + "99.9" : 0.01131878381908524, + "99.99" : 0.01131878381908524, + "99.999" : 0.01131878381908524, + "99.9999" : 0.01131878381908524, + "100.0" : 0.01131878381908524 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0109265402284031, + 0.0109299854351105, + 0.010926792841814503 + ], + [ + 0.01131878381908524, + 0.011310054370543955, + 0.011312295398294156 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1827640717500816, + "scoreError" : 0.07564698986787523, + "scoreConfidence" : [ + 3.1071170818822065, + 3.2584110616179567 + ], + "scorePercentiles" : { + "0.0" : 3.1556967766561512, + "50.0" : 3.1827721291788187, + "90.0" : 3.208490781270045, + "95.0" : 3.208490781270045, + "99.0" : 3.208490781270045, + "99.9" : 3.208490781270045, + "99.99" : 3.208490781270045, + "99.999" : 3.208490781270045, + "99.9999" : 3.208490781270045, + "100.0" : 3.208490781270045 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1556967766561512, + 3.158570057449495, + 3.1603266683512317 + ], + [ + 3.2082825567671582, + 3.208490781270045, + 3.205217590006406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7805940401948113, + "scoreError" : 0.0567602358259444, + "scoreConfidence" : [ + 2.723833804368867, + 2.8373542760207555 + ], + "scorePercentiles" : { + "0.0" : 2.760562223019597, + "50.0" : 2.778956413453237, + "90.0" : 2.8047508244531687, + "95.0" : 2.8047508244531687, + "99.0" : 2.8047508244531687, + "99.9" : 2.8047508244531687, + "99.99" : 2.8047508244531687, + "99.999" : 2.8047508244531687, + "99.9999" : 2.8047508244531687, + "100.0" : 2.8047508244531687 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7653904863146255, + 2.761596043622308, + 2.760562223019597 + ], + [ + 2.792522340591848, + 2.8047508244531687, + 2.7987423231673194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1797801207245702, + "scoreError" : 0.0043665419335601405, + "scoreConfidence" : [ + 0.17541357879101005, + 0.18414666265813034 + ], + "scorePercentiles" : { + "0.0" : 0.17831252896599684, + "50.0" : 0.1795732957180716, + "90.0" : 0.18199993797546682, + "95.0" : 0.18199993797546682, + "99.0" : 0.18199993797546682, + "99.9" : 0.18199993797546682, + "99.99" : 0.18199993797546682, + "99.999" : 0.18199993797546682, + "99.9999" : 0.18199993797546682, + "100.0" : 0.18199993797546682 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1806539862706843, + 0.18074298286581839, + 0.18199993797546682 + ], + [ + 0.1784926051654589, + 0.178478683103996, + 0.17831252896599684 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3224227646702594, + "scoreError" : 0.008193754716902424, + "scoreConfidence" : [ + 0.31422900995335695, + 0.3306165193871618 + ], + "scorePercentiles" : { + "0.0" : 0.31967130061055526, + "50.0" : 0.3223839148859723, + "90.0" : 0.32533177364260385, + "95.0" : 0.32533177364260385, + "99.0" : 0.32533177364260385, + "99.9" : 0.32533177364260385, + "99.99" : 0.32533177364260385, + "99.999" : 0.32533177364260385, + "99.9999" : 0.32533177364260385, + "100.0" : 0.32533177364260385 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32500753950404626, + 0.32533177364260385, + 0.32492088452790957 + ], + [ + 0.31967130061055526, + 0.31984694524403506, + 0.3197581444924061 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14231707366577723, + "scoreError" : 4.300216237360895E-4, + "scoreConfidence" : [ + 0.14188705204204113, + 0.14274709528951332 + ], + "scorePercentiles" : { + "0.0" : 0.1421596775037316, + "50.0" : 0.14231843833318913, + "90.0" : 0.1425031159529747, + "95.0" : 0.1425031159529747, + "99.0" : 0.1425031159529747, + "99.9" : 0.1425031159529747, + "99.99" : 0.1425031159529747, + "99.999" : 0.1425031159529747, + "99.9999" : 0.1425031159529747, + "100.0" : 0.1425031159529747 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14220723069922214, + 0.1421596775037316, + 0.14217300098097757 + ], + [ + 0.14242964596715615, + 0.1425031159529747, + 0.1424297708906012 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4062989175231066, + "scoreError" : 0.009717542657617439, + "scoreConfidence" : [ + 0.39658137486548917, + 0.416016460180724 + ], + "scorePercentiles" : { + "0.0" : 0.40164894863041206, + "50.0" : 0.4066761272176605, + "90.0" : 0.4096687818606366, + "95.0" : 0.4096687818606366, + "99.0" : 0.4096687818606366, + "99.9" : 0.4096687818606366, + "99.99" : 0.4096687818606366, + "99.999" : 0.4096687818606366, + "99.9999" : 0.4096687818606366, + "100.0" : 0.4096687818606366 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4096687818606366, + 0.4090726300417246, + 0.40931462479535036 + ], + [ + 0.4042796243935964, + 0.40380889541691906, + 0.40164894863041206 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15484678447249986, + "scoreError" : 0.010819375231709463, + "scoreConfidence" : [ + 0.14402740924079038, + 0.16566615970420934 + ], + "scorePercentiles" : { + "0.0" : 0.15109161676185295, + "50.0" : 0.15487128021113755, + "90.0" : 0.15842573994803713, + "95.0" : 0.15842573994803713, + "99.0" : 0.15842573994803713, + "99.9" : 0.15842573994803713, + "99.99" : 0.15842573994803713, + "99.999" : 0.15842573994803713, + "99.9999" : 0.15842573994803713, + "100.0" : 0.15842573994803713 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15829102056160568, + 0.15842573994803713, + 0.15838339020256895 + ], + [ + 0.1514515398606694, + 0.15109161676185295, + 0.15143739950026502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04770164499451853, + "scoreError" : 0.0012118748336652936, + "scoreConfidence" : [ + 0.04648977016085324, + 0.04891351982818382 + ], + "scorePercentiles" : { + "0.0" : 0.04708700749613892, + "50.0" : 0.04779880272805559, + "90.0" : 0.04822899591990277, + "95.0" : 0.04822899591990277, + "99.0" : 0.04822899591990277, + "99.9" : 0.04822899591990277, + "99.99" : 0.04822899591990277, + "99.999" : 0.04822899591990277, + "99.9999" : 0.04822899591990277, + "100.0" : 0.04822899591990277 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04800020566000605, + 0.04729605543495226, + 0.04708700749613892 + ], + [ + 0.04785095360977664, + 0.04822899591990277, + 0.047746651846334545 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8563892.022033507, + "scoreError" : 333523.4156191505, + "scoreConfidence" : [ + 8230368.606414356, + 8897415.437652657 + ], + "scorePercentiles" : { + "0.0" : 8448510.170608109, + "50.0" : 8562976.644572806, + "90.0" : 8682584.618923612, + "95.0" : 8682584.618923612, + "99.0" : 8682584.618923612, + "99.9" : 8682584.618923612, + "99.99" : 8682584.618923612, + "99.999" : 8682584.618923612, + "99.9999" : 8682584.618923612, + "100.0" : 8682584.618923612 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8448644.847972972, + 8448510.170608109, + 8470501.309906859 + ], + [ + 8682584.618923612, + 8677659.205550738, + 8655451.979238754 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-05-27T08:52:28Z-27a71b2d3a48a9b168878df96c7dd7166471c4ec-jdk17.json b/performance-results/2025-05-27T08:52:28Z-27a71b2d3a48a9b168878df96c7dd7166471c4ec-jdk17.json new file mode 100644 index 0000000000..cdca43f5f5 --- /dev/null +++ b/performance-results/2025-05-27T08:52:28Z-27a71b2d3a48a9b168878df96c7dd7166471c4ec-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.350689929561259, + "scoreError" : 0.012276688251055153, + "scoreConfidence" : [ + 3.338413241310204, + 3.3629666178123143 + ], + "scorePercentiles" : { + "0.0" : 3.347875106864924, + "50.0" : 3.3515175103853525, + "90.0" : 3.351849590609409, + "95.0" : 3.351849590609409, + "99.0" : 3.351849590609409, + "99.9" : 3.351849590609409, + "99.99" : 3.351849590609409, + "99.999" : 3.351849590609409, + "99.9999" : 3.351849590609409, + "100.0" : 3.351849590609409 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.347875106864924, + 3.351209083745472 + ], + [ + 3.351849590609409, + 3.351825937025233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6894862130819415, + "scoreError" : 0.05216217510598638, + "scoreConfidence" : [ + 1.637324037975955, + 1.7416483881879279 + ], + "scorePercentiles" : { + "0.0" : 1.6809447002715603, + "50.0" : 1.6894022093117624, + "90.0" : 1.698195733432681, + "95.0" : 1.698195733432681, + "99.0" : 1.698195733432681, + "99.9" : 1.698195733432681, + "99.99" : 1.698195733432681, + "99.999" : 1.698195733432681, + "99.9999" : 1.698195733432681, + "100.0" : 1.698195733432681 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6809447002715603, + 1.684572523615142 + ], + [ + 1.6942318950083826, + 1.698195733432681 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8509807483206872, + "scoreError" : 0.029850930209643727, + "scoreConfidence" : [ + 0.8211298181110435, + 0.8808316785303308 + ], + "scorePercentiles" : { + "0.0" : 0.8459063545815967, + "50.0" : 0.8514082374283676, + "90.0" : 0.8552001638444165, + "95.0" : 0.8552001638444165, + "99.0" : 0.8552001638444165, + "99.9" : 0.8552001638444165, + "99.99" : 0.8552001638444165, + "99.999" : 0.8552001638444165, + "99.9999" : 0.8552001638444165, + "100.0" : 0.8552001638444165 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8482380699605424, + 0.8545784048961926 + ], + [ + 0.8459063545815967, + 0.8552001638444165 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.128498155054952, + "scoreError" : 0.2588607840101835, + "scoreConfidence" : [ + 15.86963737104477, + 16.387358939065138 + ], + "scorePercentiles" : { + "0.0" : 16.038335112461116, + "50.0" : 16.1231065107601, + "90.0" : 16.22738749250472, + "95.0" : 16.22738749250472, + "99.0" : 16.22738749250472, + "99.9" : 16.22738749250472, + "99.99" : 16.22738749250472, + "99.999" : 16.22738749250472, + "99.9999" : 16.22738749250472, + "100.0" : 16.22738749250472 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.051804367029096, + 16.044464807399283, + 16.038335112461116 + ], + [ + 16.22738749250472, + 16.214588496444403, + 16.194408654491102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2658.5956986978254, + "scoreError" : 353.2868358169668, + "scoreConfidence" : [ + 2305.3088628808587, + 3011.882534514792 + ], + "scorePercentiles" : { + "0.0" : 2540.660151974212, + "50.0" : 2657.7861780799713, + "90.0" : 2778.8285049599554, + "95.0" : 2778.8285049599554, + "99.0" : 2778.8285049599554, + "99.9" : 2778.8285049599554, + "99.99" : 2778.8285049599554, + "99.999" : 2778.8285049599554, + "99.9999" : 2778.8285049599554, + "100.0" : 2778.8285049599554 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2770.1725149727795, + 2778.8285049599554, + 2771.689561163659 + ], + [ + 2540.660151974212, + 2544.8236179291816, + 2545.399841187163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77130.86090650568, + "scoreError" : 273.6456293169485, + "scoreConfidence" : [ + 76857.21527718873, + 77404.50653582263 + ], + "scorePercentiles" : { + "0.0" : 76939.73063633371, + "50.0" : 77160.63337032148, + "90.0" : 77212.76221304128, + "95.0" : 77212.76221304128, + "99.0" : 77212.76221304128, + "99.9" : 77212.76221304128, + "99.99" : 77212.76221304128, + "99.999" : 77212.76221304128, + "99.9999" : 77212.76221304128, + "100.0" : 77212.76221304128 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77181.85020786953, + 77129.55564114664, + 76939.73063633371 + ], + [ + 77159.99280039931, + 77161.27394024366, + 77212.76221304128 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 360.51803455692396, + "scoreError" : 30.949289883062324, + "scoreConfidence" : [ + 329.56874467386166, + 391.46732443998627 + ], + "scorePercentiles" : { + "0.0" : 349.78137669509505, + "50.0" : 360.6718032082213, + "90.0" : 370.68349783790654, + "95.0" : 370.68349783790654, + "99.0" : 370.68349783790654, + "99.9" : 370.68349783790654, + "99.99" : 370.68349783790654, + "99.999" : 370.68349783790654, + "99.9999" : 370.68349783790654, + "100.0" : 370.68349783790654 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.78137669509505, + 350.6710515085572, + 350.89405964428545 + ], + [ + 370.4495467721572, + 370.68349783790654, + 370.6286748835422 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.15578416430783, + "scoreError" : 1.4634621757737745, + "scoreConfidence" : [ + 115.69232198853406, + 118.6192463400816 + ], + "scorePercentiles" : { + "0.0" : 116.63455961436804, + "50.0" : 117.14589718624941, + "90.0" : 117.67010079224434, + "95.0" : 117.67010079224434, + "99.0" : 117.67010079224434, + "99.9" : 117.67010079224434, + "99.99" : 117.67010079224434, + "99.999" : 117.67010079224434, + "99.9999" : 117.67010079224434, + "100.0" : 117.67010079224434 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.70100416031477, + 116.70612694829401, + 116.63455961436804 + ], + [ + 117.67010079224434, + 117.58566742420483, + 117.63724604642107 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06234401436829248, + "scoreError" : 2.090261150153013E-4, + "scoreConfidence" : [ + 0.06213498825327718, + 0.06255304048330779 + ], + "scorePercentiles" : { + "0.0" : 0.062259162300307556, + "50.0" : 0.062333574685813374, + "90.0" : 0.0624437480252518, + "95.0" : 0.0624437480252518, + "99.0" : 0.0624437480252518, + "99.9" : 0.0624437480252518, + "99.99" : 0.0624437480252518, + "99.999" : 0.0624437480252518, + "99.9999" : 0.0624437480252518, + "100.0" : 0.0624437480252518 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062278048613706, + 0.062259162300307556, + 0.062312518581291595 + ], + [ + 0.06235463079033515, + 0.0624159778988628, + 0.0624437480252518 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7515238077002935E-4, + "scoreError" : 1.6580303682836416E-5, + "scoreConfidence" : [ + 3.5857207708719295E-4, + 3.9173268445286575E-4 + ], + "scorePercentiles" : { + "0.0" : 3.696236985477625E-4, + "50.0" : 3.752001244070216E-4, + "90.0" : 3.8066848620039415E-4, + "95.0" : 3.8066848620039415E-4, + "99.0" : 3.8066848620039415E-4, + "99.9" : 3.8066848620039415E-4, + "99.99" : 3.8066848620039415E-4, + "99.999" : 3.8066848620039415E-4, + "99.9999" : 3.8066848620039415E-4, + "100.0" : 3.8066848620039415E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6966821058004545E-4, + 3.69977489226882E-4, + 3.696236985477625E-4 + ], + [ + 3.8042275958716123E-4, + 3.8066848620039415E-4, + 3.805536404779307E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12692875661514072, + "scoreError" : 0.01016085172952964, + "scoreConfidence" : [ + 0.11676790488561108, + 0.13708960834467035 + ], + "scorePercentiles" : { + "0.0" : 0.12354302556056582, + "50.0" : 0.12688676577676555, + "90.0" : 0.13037678598993507, + "95.0" : 0.13037678598993507, + "99.0" : 0.13037678598993507, + "99.9" : 0.13037678598993507, + "99.99" : 0.13037678598993507, + "99.999" : 0.13037678598993507, + "99.9999" : 0.13037678598993507, + "100.0" : 0.13037678598993507 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12359314431728298, + 0.12373288928620037, + 0.12354302556056582 + ], + [ + 0.1302860522695294, + 0.13037678598993507, + 0.13004064226733072 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012863104759860812, + "scoreError" : 4.7507273248622575E-4, + "scoreConfidence" : [ + 0.012388032027374585, + 0.013338177492347038 + ], + "scorePercentiles" : { + "0.0" : 0.012703400030741791, + "50.0" : 0.012863003582298646, + "90.0" : 0.01302204036393563, + "95.0" : 0.01302204036393563, + "99.0" : 0.01302204036393563, + "99.9" : 0.01302204036393563, + "99.99" : 0.01302204036393563, + "99.999" : 0.01302204036393563, + "99.9999" : 0.01302204036393563, + "100.0" : 0.01302204036393563 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012703400030741791, + 0.012706899360344403, + 0.012715292319429345 + ], + [ + 0.01302204036393563, + 0.013020281639545755, + 0.013010714845167947 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9658364336905084, + "scoreError" : 0.07133241066239478, + "scoreConfidence" : [ + 0.8945040230281136, + 1.0371688443529032 + ], + "scorePercentiles" : { + "0.0" : 0.9412807003294118, + "50.0" : 0.9651567787214905, + "90.0" : 0.99028982552728, + "95.0" : 0.99028982552728, + "99.0" : 0.99028982552728, + "99.9" : 0.99028982552728, + "99.99" : 0.99028982552728, + "99.999" : 0.99028982552728, + "99.9999" : 0.99028982552728, + "100.0" : 0.99028982552728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9868763195184528, + 0.99028982552728, + 0.9899017109769376 + ], + [ + 0.9412807003294118, + 0.9432328078664403, + 0.9434372379245283 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011013876092997123, + "scoreError" : 1.1462732064827779E-4, + "scoreConfidence" : [ + 0.010899248772348845, + 0.0111285034136454 + ], + "scorePercentiles" : { + "0.0" : 0.010972415736599796, + "50.0" : 0.011014744432220974, + "90.0" : 0.011052374926779884, + "95.0" : 0.011052374926779884, + "99.0" : 0.011052374926779884, + "99.9" : 0.011052374926779884, + "99.99" : 0.011052374926779884, + "99.999" : 0.011052374926779884, + "99.9999" : 0.011052374926779884, + "100.0" : 0.011052374926779884 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010978459034930365, + 0.010979001574339798, + 0.010972415736599796 + ], + [ + 0.011050517995230739, + 0.011052374926779884, + 0.011050487290102148 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2822900515506137, + "scoreError" : 0.40313736153920837, + "scoreConfidence" : [ + 2.8791526900114053, + 3.685427413089822 + ], + "scorePercentiles" : { + "0.0" : 3.1472569181875394, + "50.0" : 3.28234366891121, + "90.0" : 3.418200850307587, + "95.0" : 3.418200850307587, + "99.0" : 3.418200850307587, + "99.9" : 3.418200850307587, + "99.99" : 3.418200850307587, + "99.999" : 3.418200850307587, + "99.9999" : 3.418200850307587, + "100.0" : 3.418200850307587 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4084303258350377, + 3.418200850307587, + 3.413776100341297 + ], + [ + 3.156257011987382, + 3.149819102644836, + 3.1472569181875394 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7183110648108944, + "scoreError" : 0.017655089924838312, + "scoreConfidence" : [ + 2.700655974886056, + 2.7359661547357326 + ], + "scorePercentiles" : { + "0.0" : 2.711118488750339, + "50.0" : 2.718760513449465, + "90.0" : 2.7260558871627145, + "95.0" : 2.7260558871627145, + "99.0" : 2.7260558871627145, + "99.9" : 2.7260558871627145, + "99.99" : 2.7260558871627145, + "99.999" : 2.7260558871627145, + "99.9999" : 2.7260558871627145, + "100.0" : 2.7260558871627145 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7260558871627145, + 2.711118488750339, + 2.7113011301165626 + ], + [ + 2.7238698559368193, + 2.720498002992383, + 2.717023023906547 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17596604949463376, + "scoreError" : 0.007393577568151005, + "scoreConfidence" : [ + 0.16857247192648275, + 0.18335962706278477 + ], + "scorePercentiles" : { + "0.0" : 0.17336598110361806, + "50.0" : 0.1760392860208222, + "90.0" : 0.1784005122825796, + "95.0" : 0.1784005122825796, + "99.0" : 0.1784005122825796, + "99.9" : 0.1784005122825796, + "99.99" : 0.1784005122825796, + "99.999" : 0.1784005122825796, + "99.9999" : 0.1784005122825796, + "100.0" : 0.1784005122825796 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17375143537485882, + 0.17336598110361806, + 0.17356808020480777 + ], + [ + 0.1784005122825796, + 0.17838315133515278, + 0.17832713666678554 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32346813478562775, + "scoreError" : 0.006628423948974936, + "scoreConfidence" : [ + 0.3168397108366528, + 0.3300965587346027 + ], + "scorePercentiles" : { + "0.0" : 0.32109080542623214, + "50.0" : 0.32334465215816954, + "90.0" : 0.3263243923641703, + "95.0" : 0.3263243923641703, + "99.0" : 0.3263243923641703, + "99.9" : 0.3263243923641703, + "99.99" : 0.3263243923641703, + "99.999" : 0.3263243923641703, + "99.9999" : 0.3263243923641703, + "100.0" : 0.3263243923641703 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32109080542623214, + 0.32161448736090564, + 0.3213418597043702 + ], + [ + 0.3263243923641703, + 0.3250748169554335, + 0.32536244690265487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.13919824785042312, + "scoreError" : 0.002889235881228295, + "scoreConfidence" : [ + 0.13630901196919482, + 0.14208748373165142 + ], + "scorePercentiles" : { + "0.0" : 0.1382112894242198, + "50.0" : 0.13918007066075988, + "90.0" : 0.1402040985755545, + "95.0" : 0.1402040985755545, + "99.0" : 0.1402040985755545, + "99.9" : 0.1402040985755545, + "99.99" : 0.1402040985755545, + "99.999" : 0.1402040985755545, + "99.9999" : 0.1402040985755545, + "100.0" : 0.1402040985755545 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1383433134813585, + 0.13822694527686397, + 0.1382112894242198 + ], + [ + 0.1402040985755545, + 0.14001682784016128, + 0.14018701250438073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40117093865788195, + "scoreError" : 0.009465644537727053, + "scoreConfidence" : [ + 0.39170529412015487, + 0.41063658319560903 + ], + "scorePercentiles" : { + "0.0" : 0.39666430268533576, + "50.0" : 0.40065464728991446, + "90.0" : 0.4069779666286831, + "95.0" : 0.4069779666286831, + "99.0" : 0.4069779666286831, + "99.9" : 0.4069779666286831, + "99.99" : 0.4069779666286831, + "99.999" : 0.4069779666286831, + "99.9999" : 0.4069779666286831, + "100.0" : 0.4069779666286831 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4069779666286831, + 0.4020224, + 0.40111786647146125 + ], + [ + 0.40019142810836766, + 0.4000516680534443, + 0.39666430268533576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15930800313631852, + "scoreError" : 0.003264534159678587, + "scoreConfidence" : [ + 0.15604346897663993, + 0.1625725372959971 + ], + "scorePercentiles" : { + "0.0" : 0.1580271695110774, + "50.0" : 0.1594463812250709, + "90.0" : 0.16111799102597152, + "95.0" : 0.16111799102597152, + "99.0" : 0.16111799102597152, + "99.9" : 0.16111799102597152, + "99.99" : 0.16111799102597152, + "99.999" : 0.16111799102597152, + "99.9999" : 0.16111799102597152, + "100.0" : 0.16111799102597152 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15925291894259097, + 0.15963984350755084, + 0.15974822757188498 + ], + [ + 0.16111799102597152, + 0.15806186825883542, + 0.1580271695110774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046995216255561655, + "scoreError" : 9.350558881015056E-4, + "scoreConfidence" : [ + 0.04606016036746015, + 0.04793027214366316 + ], + "scorePercentiles" : { + "0.0" : 0.04639994337906747, + "50.0" : 0.047048089353178696, + "90.0" : 0.047294220174418054, + "95.0" : 0.047294220174418054, + "99.0" : 0.047294220174418054, + "99.9" : 0.047294220174418054, + "99.99" : 0.047294220174418054, + "99.999" : 0.047294220174418054, + "99.9999" : 0.047294220174418054, + "100.0" : 0.047294220174418054 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04726533066761196, + 0.046931248849029245, + 0.04691562460591503 + ], + [ + 0.047294220174418054, + 0.04716492985732815, + 0.04639994337906747 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8648908.744124115, + "scoreError" : 708250.5562980257, + "scoreConfidence" : [ + 7940658.187826089, + 9357159.30042214 + ], + "scorePercentiles" : { + "0.0" : 8414266.977291841, + "50.0" : 8610720.038868744, + "90.0" : 8954862.264995523, + "95.0" : 8954862.264995523, + "99.0" : 8954862.264995523, + "99.9" : 8954862.264995523, + "99.99" : 8954862.264995523, + "99.999" : 8954862.264995523, + "99.9999" : 8954862.264995523, + "100.0" : 8954862.264995523 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8954862.264995523, + 8881767.031083481, + 8785737.02546093 + ], + [ + 8435703.05227656, + 8421116.113636363, + 8414266.977291841 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-02T12:04:37Z-589b33d9c662ea926020bf1a384ab91d9bd6566b-jdk17.json b/performance-results/2025-06-02T12:04:37Z-589b33d9c662ea926020bf1a384ab91d9bd6566b-jdk17.json new file mode 100644 index 0000000000..2e323f621b --- /dev/null +++ b/performance-results/2025-06-02T12:04:37Z-589b33d9c662ea926020bf1a384ab91d9bd6566b-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3542550442231147, + "scoreError" : 0.05415665989140512, + "scoreConfidence" : [ + 3.3000983843317098, + 3.4084117041145197 + ], + "scorePercentiles" : { + "0.0" : 3.3443292696067717, + "50.0" : 3.354238714374313, + "90.0" : 3.3642134785370614, + "95.0" : 3.3642134785370614, + "99.0" : 3.3642134785370614, + "99.9" : 3.3642134785370614, + "99.99" : 3.3642134785370614, + "99.999" : 3.3642134785370614, + "99.9999" : 3.3642134785370614, + "100.0" : 3.3642134785370614 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3516870844007705, + 3.3642134785370614 + ], + [ + 3.3443292696067717, + 3.3567903443478557 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6945902792679637, + "scoreError" : 0.019106667992435454, + "scoreConfidence" : [ + 1.6754836112755283, + 1.7136969472603991 + ], + "scorePercentiles" : { + "0.0" : 1.6906900680502455, + "50.0" : 1.6949680324169336, + "90.0" : 1.6977349841877427, + "95.0" : 1.6977349841877427, + "99.0" : 1.6977349841877427, + "99.9" : 1.6977349841877427, + "99.99" : 1.6977349841877427, + "99.999" : 1.6977349841877427, + "99.9999" : 1.6977349841877427, + "100.0" : 1.6977349841877427 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6943194195319953, + 1.6977349841877427 + ], + [ + 1.6906900680502455, + 1.695616645301872 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8481344005483605, + "scoreError" : 0.02911045238592997, + "scoreConfidence" : [ + 0.8190239481624305, + 0.8772448529342906 + ], + "scorePercentiles" : { + "0.0" : 0.8440078743151324, + "50.0" : 0.8474938871318505, + "90.0" : 0.853541953614609, + "95.0" : 0.853541953614609, + "99.0" : 0.853541953614609, + "99.9" : 0.853541953614609, + "99.99" : 0.853541953614609, + "99.999" : 0.853541953614609, + "99.9999" : 0.853541953614609, + "100.0" : 0.853541953614609 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8440078743151324, + 0.8448679277634978 + ], + [ + 0.8501198465002031, + 0.853541953614609 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.430343692640687, + "scoreError" : 0.24321196561449052, + "scoreConfidence" : [ + 16.187131727026195, + 16.67355565825518 + ], + "scorePercentiles" : { + "0.0" : 16.333994152472094, + "50.0" : 16.431857836943376, + "90.0" : 16.52569285870286, + "95.0" : 16.52569285870286, + "99.0" : 16.52569285870286, + "99.9" : 16.52569285870286, + "99.99" : 16.52569285870286, + "99.999" : 16.52569285870286, + "99.9999" : 16.52569285870286, + "100.0" : 16.52569285870286 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.48898207171955, + 16.52569285870286, + 16.509030016275823 + ], + [ + 16.333994152472094, + 16.3747336021672, + 16.3496294545066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2696.0097486690083, + "scoreError" : 175.79335193872143, + "scoreConfidence" : [ + 2520.2163967302868, + 2871.80310060773 + ], + "scorePercentiles" : { + "0.0" : 2631.2637440908234, + "50.0" : 2697.2978177332175, + "90.0" : 2758.2496362055895, + "95.0" : 2758.2496362055895, + "99.0" : 2758.2496362055895, + "99.9" : 2758.2496362055895, + "99.99" : 2758.2496362055895, + "99.999" : 2758.2496362055895, + "99.9999" : 2758.2496362055895, + "100.0" : 2758.2496362055895 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2631.2637440908234, + 2639.119572285854, + 2646.722417168577 + ], + [ + 2758.2496362055895, + 2752.829903965346, + 2747.873218297858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77005.48988535638, + "scoreError" : 1854.0672961124958, + "scoreConfidence" : [ + 75151.42258924388, + 78859.55718146887 + ], + "scorePercentiles" : { + "0.0" : 76392.55390662995, + "50.0" : 76974.08555952754, + "90.0" : 77649.95947201247, + "95.0" : 77649.95947201247, + "99.0" : 77649.95947201247, + "99.9" : 77649.95947201247, + "99.99" : 77649.95947201247, + "99.999" : 77649.95947201247, + "99.9999" : 77649.95947201247, + "100.0" : 77649.95947201247 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77539.3221801599, + 77634.84781635502, + 77649.95947201247 + ], + [ + 76408.84893889516, + 76407.40699808573, + 76392.55390662995 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.3582915533586, + "scoreError" : 12.380271337109436, + "scoreConfidence" : [ + 337.97802021624915, + 362.738562890468 + ], + "scorePercentiles" : { + "0.0" : 345.4613081952976, + "50.0" : 350.29537065860774, + "90.0" : 354.9760181041977, + "95.0" : 354.9760181041977, + "99.0" : 354.9760181041977, + "99.9" : 354.9760181041977, + "99.99" : 354.9760181041977, + "99.999" : 354.9760181041977, + "99.9999" : 354.9760181041977, + "100.0" : 354.9760181041977 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.94643230352375, + 346.7116085104185, + 345.4613081952976 + ], + [ + 353.6443090136917, + 354.41007319302224, + 354.9760181041977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.7374852433923, + "scoreError" : 3.567448632303928, + "scoreConfidence" : [ + 114.17003661108838, + 121.30493387569622 + ], + "scorePercentiles" : { + "0.0" : 116.48967852522601, + "50.0" : 117.50102886972141, + "90.0" : 119.32975966341384, + "95.0" : 119.32975966341384, + "99.0" : 119.32975966341384, + "99.9" : 119.32975966341384, + "99.99" : 119.32975966341384, + "99.999" : 119.32975966341384, + "99.9999" : 119.32975966341384, + "100.0" : 119.32975966341384 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 118.20728429387502, + 119.00218014841691, + 119.32975966341384 + ], + [ + 116.60123538385417, + 116.48967852522601, + 116.79477344556778 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06071555517335542, + "scoreError" : 0.001330523606268949, + "scoreConfidence" : [ + 0.059385031567086466, + 0.06204607877962437 + ], + "scorePercentiles" : { + "0.0" : 0.06016159537603552, + "50.0" : 0.06068404152331893, + "90.0" : 0.06129165527681926, + "95.0" : 0.06129165527681926, + "99.0" : 0.06129165527681926, + "99.9" : 0.06129165527681926, + "99.99" : 0.06129165527681926, + "99.999" : 0.06129165527681926, + "99.9999" : 0.06129165527681926, + "100.0" : 0.06129165527681926 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06034680117795439, + 0.06038311761225032, + 0.06016159537603552 + ], + [ + 0.06098496543438754, + 0.06112519616268551, + 0.06129165527681926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.703583113332299E-4, + "scoreError" : 7.219314219478108E-6, + "scoreConfidence" : [ + 3.631389971137518E-4, + 3.7757762555270803E-4 + ], + "scorePercentiles" : { + "0.0" : 3.679141111677487E-4, + "50.0" : 3.7012400025787184E-4, + "90.0" : 3.7303834028090427E-4, + "95.0" : 3.7303834028090427E-4, + "99.0" : 3.7303834028090427E-4, + "99.9" : 3.7303834028090427E-4, + "99.99" : 3.7303834028090427E-4, + "99.999" : 3.7303834028090427E-4, + "99.9999" : 3.7303834028090427E-4, + "100.0" : 3.7303834028090427E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7210494082876234E-4, + 3.729239771483686E-4, + 3.7303834028090427E-4 + ], + [ + 3.6802543888661473E-4, + 3.679141111677487E-4, + 3.681430596869813E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12264900608969875, + "scoreError" : 0.0011896876152817652, + "scoreConfidence" : [ + 0.12145931847441699, + 0.12383869370498052 + ], + "scorePercentiles" : { + "0.0" : 0.12228445021337997, + "50.0" : 0.12247990734607563, + "90.0" : 0.12334902619893429, + "95.0" : 0.12334902619893429, + "99.0" : 0.12334902619893429, + "99.9" : 0.12334902619893429, + "99.99" : 0.12334902619893429, + "99.999" : 0.12334902619893429, + "99.9999" : 0.12334902619893429, + "100.0" : 0.12334902619893429 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12228445021337997, + 0.1224672832982267, + 0.12231907438077182 + ], + [ + 0.12249253139392455, + 0.12334902619893429, + 0.12298167105295521 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012930714105879067, + "scoreError" : 1.1634760040524515E-4, + "scoreConfidence" : [ + 0.012814366505473821, + 0.013047061706284313 + ], + "scorePercentiles" : { + "0.0" : 0.012888652145222178, + "50.0" : 0.012929809354510147, + "90.0" : 0.012975725108994654, + "95.0" : 0.012975725108994654, + "99.0" : 0.012975725108994654, + "99.9" : 0.012975725108994654, + "99.99" : 0.012975725108994654, + "99.999" : 0.012975725108994654, + "99.9999" : 0.012975725108994654, + "100.0" : 0.012975725108994654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01289585343792596, + 0.012888652145222178, + 0.0128947615245552 + ], + [ + 0.012963765271094333, + 0.012965527147482066, + 0.012975725108994654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9671551972519126, + "scoreError" : 0.04451526150886872, + "scoreConfidence" : [ + 0.9226399357430438, + 1.0116704587607812 + ], + "scorePercentiles" : { + "0.0" : 0.952344129130559, + "50.0" : 0.9657353875350614, + "90.0" : 0.9831889283326779, + "95.0" : 0.9831889283326779, + "99.0" : 0.9831889283326779, + "99.9" : 0.9831889283326779, + "99.99" : 0.9831889283326779, + "99.999" : 0.9831889283326779, + "99.9999" : 0.9831889283326779, + "100.0" : 0.9831889283326779 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9783571948738016, + 0.9831889283326779, + 0.9831228761305545 + ], + [ + 0.9531135801963213, + 0.952344129130559, + 0.9528044748475609 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010676157581029746, + "scoreError" : 8.572126287263604E-4, + "scoreConfidence" : [ + 0.009818944952303385, + 0.011533370209756106 + ], + "scorePercentiles" : { + "0.0" : 0.010384952155852787, + "50.0" : 0.010676539010044204, + "90.0" : 0.010959189083154155, + "95.0" : 0.010959189083154155, + "99.0" : 0.010959189083154155, + "99.9" : 0.010959189083154155, + "99.99" : 0.010959189083154155, + "99.999" : 0.010959189083154155, + "99.9999" : 0.010959189083154155, + "100.0" : 0.010959189083154155 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0109564313884446, + 0.010949776575523058, + 0.010959189083154155 + ], + [ + 0.01040330144456535, + 0.010384952155852787, + 0.010403294838638534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.212647787031693, + "scoreError" : 0.02632272311351372, + "scoreConfidence" : [ + 3.1863250639181793, + 3.238970510145207 + ], + "scorePercentiles" : { + "0.0" : 3.2016699180537773, + "50.0" : 3.213095294766111, + "90.0" : 3.2273036812903224, + "95.0" : 3.2273036812903224, + "99.0" : 3.2273036812903224, + "99.9" : 3.2273036812903224, + "99.99" : 3.2273036812903224, + "99.999" : 3.2273036812903224, + "99.9999" : 3.2273036812903224, + "100.0" : 3.2273036812903224 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2035007828315183, + 3.2273036812903224, + 3.2127246878612716 + ], + [ + 3.213465901670951, + 3.2172217504823153, + 3.2016699180537773 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.745571660611588, + "scoreError" : 0.08293417143932898, + "scoreConfidence" : [ + 2.6626374891722593, + 2.828505832050917 + ], + "scorePercentiles" : { + "0.0" : 2.7161789818033677, + "50.0" : 2.745333682556835, + "90.0" : 2.775075796337403, + "95.0" : 2.775075796337403, + "99.0" : 2.775075796337403, + "99.9" : 2.775075796337403, + "99.99" : 2.775075796337403, + "99.999" : 2.775075796337403, + "99.9999" : 2.775075796337403, + "100.0" : 2.775075796337403 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7161789818033677, + 2.719147842033714, + 2.72060443960827 + ], + [ + 2.775075796337403, + 2.772359978381375, + 2.7700629255054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.177874960329253, + "scoreError" : 0.003693004241928387, + "scoreConfidence" : [ + 0.17418195608732462, + 0.1815679645711814 + ], + "scorePercentiles" : { + "0.0" : 0.1766362772233507, + "50.0" : 0.1778651937971314, + "90.0" : 0.179150174901469, + "95.0" : 0.179150174901469, + "99.0" : 0.179150174901469, + "99.9" : 0.179150174901469, + "99.99" : 0.179150174901469, + "99.999" : 0.179150174901469, + "99.9999" : 0.179150174901469, + "100.0" : 0.179150174901469 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.179150174901469, + 0.17905393418202, + 0.17902512959415673 + ], + [ + 0.17667898807441565, + 0.17670525800010603, + 0.1766362772233507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32462472883601207, + "scoreError" : 0.023296253827589198, + "scoreConfidence" : [ + 0.30132847500842286, + 0.3479209826636013 + ], + "scorePercentiles" : { + "0.0" : 0.31719164101750824, + "50.0" : 0.3225894406411488, + "90.0" : 0.3365256245793512, + "95.0" : 0.3365256245793512, + "99.0" : 0.3365256245793512, + "99.9" : 0.3365256245793512, + "99.99" : 0.3365256245793512, + "99.999" : 0.3365256245793512, + "99.9999" : 0.3365256245793512, + "100.0" : 0.3365256245793512 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31719164101750824, + 0.3176828877664475, + 0.31765512889905345 + ], + [ + 0.3365256245793512, + 0.3274959935158501, + 0.33119709723786184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1404437415020914, + "scoreError" : 0.006615461265367119, + "scoreConfidence" : [ + 0.1338282802367243, + 0.1470592027674585 + ], + "scorePercentiles" : { + "0.0" : 0.13827158509741022, + "50.0" : 0.14040977140978317, + "90.0" : 0.14269332814417396, + "95.0" : 0.14269332814417396, + "99.0" : 0.14269332814417396, + "99.9" : 0.14269332814417396, + "99.99" : 0.14269332814417396, + "99.999" : 0.14269332814417396, + "99.9999" : 0.14269332814417396, + "100.0" : 0.14269332814417396 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1383152868879668, + 0.13827158509741022, + 0.13828578321533272 + ], + [ + 0.14269332814417396, + 0.14250425593159957, + 0.14259220973606537 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38923083065742786, + "scoreError" : 0.009029075146993878, + "scoreConfidence" : [ + 0.380201755510434, + 0.3982599058044217 + ], + "scorePercentiles" : { + "0.0" : 0.38664925715279924, + "50.0" : 0.38765779789484217, + "90.0" : 0.3934577652752095, + "95.0" : 0.3934577652752095, + "99.0" : 0.3934577652752095, + "99.9" : 0.3934577652752095, + "99.99" : 0.3934577652752095, + "99.999" : 0.3934577652752095, + "99.9999" : 0.3934577652752095, + "100.0" : 0.3934577652752095 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3934577652752095, + 0.3881304453328158, + 0.3932048551881414 + ], + [ + 0.3871851504568685, + 0.38664925715279924, + 0.38675751053873225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15958860758972224, + "scoreError" : 0.0032495747385322465, + "scoreConfidence" : [ + 0.15633903285119, + 0.16283818232825448 + ], + "scorePercentiles" : { + "0.0" : 0.15815088529542004, + "50.0" : 0.15938910494422867, + "90.0" : 0.16151672896713237, + "95.0" : 0.16151672896713237, + "99.0" : 0.16151672896713237, + "99.9" : 0.16151672896713237, + "99.99" : 0.16151672896713237, + "99.999" : 0.16151672896713237, + "99.9999" : 0.16151672896713237, + "100.0" : 0.16151672896713237 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16151672896713237, + 0.16018490334620128, + 0.15890091804112244 + ], + [ + 0.15928507309419898, + 0.15949313679425836, + 0.15815088529542004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04765020702902307, + "scoreError" : 0.001390738104659118, + "scoreConfidence" : [ + 0.04625946892436395, + 0.049040945133682186 + ], + "scorePercentiles" : { + "0.0" : 0.04724274734499896, + "50.0" : 0.04743248341570385, + "90.0" : 0.04845506719158833, + "95.0" : 0.04845506719158833, + "99.0" : 0.04845506719158833, + "99.9" : 0.04845506719158833, + "99.99" : 0.04845506719158833, + "99.999" : 0.04845506719158833, + "99.9999" : 0.04845506719158833, + "100.0" : 0.04845506719158833 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04806604303292478, + 0.04845506719158833, + 0.047485210501574095 + ], + [ + 0.04727241777321868, + 0.04724274734499896, + 0.04737975632983361 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8609341.948687557, + "scoreError" : 134606.12511506703, + "scoreConfidence" : [ + 8474735.82357249, + 8743948.073802624 + ], + "scorePercentiles" : { + "0.0" : 8559126.613344738, + "50.0" : 8608140.893795703, + "90.0" : 8661007.152380953, + "95.0" : 8661007.152380953, + "99.0" : 8661007.152380953, + "99.9" : 8661007.152380953, + "99.99" : 8661007.152380953, + "99.999" : 8661007.152380953, + "99.9999" : 8661007.152380953, + "100.0" : 8661007.152380953 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8574941.663239075, + 8559126.613344738, + 8564418.211472603 + ], + [ + 8661007.152380953, + 8641340.124352332, + 8655217.92733564 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-05T03:13:41Z-4373db51579b5e849f0e42db412503664fa48092-jdk17.json b/performance-results/2025-06-05T03:13:41Z-4373db51579b5e849f0e42db412503664fa48092-jdk17.json new file mode 100644 index 0000000000..cc1c4f259d --- /dev/null +++ b/performance-results/2025-06-05T03:13:41Z-4373db51579b5e849f0e42db412503664fa48092-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3583487614414915, + "scoreError" : 0.03017521966767004, + "scoreConfidence" : [ + 3.3281735417738214, + 3.3885239811091616 + ], + "scorePercentiles" : { + "0.0" : 3.3538188921638743, + "50.0" : 3.3580976326952188, + "90.0" : 3.363380888211654, + "95.0" : 3.363380888211654, + "99.0" : 3.363380888211654, + "99.9" : 3.363380888211654, + "99.99" : 3.363380888211654, + "99.999" : 3.363380888211654, + "99.9999" : 3.363380888211654, + "100.0" : 3.363380888211654 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3538188921638743, + 3.3549792429970204 + ], + [ + 3.3612160223934175, + 3.363380888211654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.696775350498371, + "scoreError" : 0.02058790614396534, + "scoreConfidence" : [ + 1.6761874443544056, + 1.7173632566423362 + ], + "scorePercentiles" : { + "0.0" : 1.6922234061208514, + "50.0" : 1.6977641538847275, + "90.0" : 1.6993496881031775, + "95.0" : 1.6993496881031775, + "99.0" : 1.6993496881031775, + "99.9" : 1.6993496881031775, + "99.99" : 1.6993496881031775, + "99.999" : 1.6993496881031775, + "99.9999" : 1.6993496881031775, + "100.0" : 1.6993496881031775 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6985220906209715, + 1.6922234061208514 + ], + [ + 1.6970062171484832, + 1.6993496881031775 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8528450139874564, + "scoreError" : 0.016197477432025972, + "scoreConfidence" : [ + 0.8366475365554304, + 0.8690424914194823 + ], + "scorePercentiles" : { + "0.0" : 0.8497942404064186, + "50.0" : 0.8528336161124015, + "90.0" : 0.8559185833186042, + "95.0" : 0.8559185833186042, + "99.0" : 0.8559185833186042, + "99.9" : 0.8559185833186042, + "99.99" : 0.8559185833186042, + "99.999" : 0.8559185833186042, + "99.9999" : 0.8559185833186042, + "100.0" : 0.8559185833186042 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8526162621090654, + 0.8559185833186042 + ], + [ + 0.8497942404064186, + 0.8530509701157377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.39367057626973, + "scoreError" : 0.3870293050768862, + "scoreConfidence" : [ + 16.006641271192844, + 16.780699881346617 + ], + "scorePercentiles" : { + "0.0" : 16.226559014504108, + "50.0" : 16.39675004625169, + "90.0" : 16.55246005222859, + "95.0" : 16.55246005222859, + "99.0" : 16.55246005222859, + "99.9" : 16.55246005222859, + "99.99" : 16.55246005222859, + "99.999" : 16.55246005222859, + "99.9999" : 16.55246005222859, + "100.0" : 16.55246005222859 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.55246005222859, + 16.50084169912421, + 16.49567855871189 + ], + [ + 16.297821533791492, + 16.288662599258082, + 16.226559014504108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2733.1957546460653, + "scoreError" : 327.56007173561, + "scoreConfidence" : [ + 2405.635682910455, + 3060.7558263816754 + ], + "scorePercentiles" : { + "0.0" : 2625.3376944308184, + "50.0" : 2733.336262573395, + "90.0" : 2840.612317151373, + "95.0" : 2840.612317151373, + "99.0" : 2840.612317151373, + "99.9" : 2840.612317151373, + "99.99" : 2840.612317151373, + "99.999" : 2840.612317151373, + "99.9999" : 2840.612317151373, + "100.0" : 2840.612317151373 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2839.413529660308, + 2839.4542276708635, + 2840.612317151373 + ], + [ + 2627.0977634765495, + 2625.3376944308184, + 2627.2589954864816 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 78265.2258013661, + "scoreError" : 378.71340215341013, + "scoreConfidence" : [ + 77886.51239921269, + 78643.93920351952 + ], + "scorePercentiles" : { + "0.0" : 78136.99963543477, + "50.0" : 78244.09131701662, + "90.0" : 78432.7267780164, + "95.0" : 78432.7267780164, + "99.0" : 78432.7267780164, + "99.9" : 78432.7267780164, + "99.99" : 78432.7267780164, + "99.999" : 78432.7267780164, + "99.9999" : 78432.7267780164, + "100.0" : 78432.7267780164 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78335.02779180357, + 78387.6797546668, + 78432.7267780164 + ], + [ + 78136.99963543477, + 78153.15484222966, + 78145.76600604542 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 364.0378493796623, + "scoreError" : 7.462741062086967, + "scoreConfidence" : [ + 356.5751083175753, + 371.5005904417493 + ], + "scorePercentiles" : { + "0.0" : 361.1540563284553, + "50.0" : 363.9944231699365, + "90.0" : 367.01781494855913, + "95.0" : 367.01781494855913, + "99.0" : 367.01781494855913, + "99.9" : 367.01781494855913, + "99.99" : 367.01781494855913, + "99.999" : 367.01781494855913, + "99.9999" : 367.01781494855913, + "100.0" : 367.01781494855913 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 361.8803986034575, + 361.1540563284553, + 361.8798516155016 + ], + [ + 367.01781494855913, + 366.186527045585, + 366.10844773641554 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.86461422940145, + "scoreError" : 0.8516714280613955, + "scoreConfidence" : [ + 117.01294280134006, + 118.71628565746285 + ], + "scorePercentiles" : { + "0.0" : 117.47220531265368, + "50.0" : 117.83144814322866, + "90.0" : 118.21124743280906, + "95.0" : 118.21124743280906, + "99.0" : 118.21124743280906, + "99.9" : 118.21124743280906, + "99.99" : 118.21124743280906, + "99.999" : 118.21124743280906, + "99.9999" : 118.21124743280906, + "100.0" : 118.21124743280906 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.47220531265368, + 117.65211023796213, + 117.70041083404337 + ], + [ + 117.96248545241394, + 118.18922610652658, + 118.21124743280906 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06121126352802388, + "scoreError" : 9.424252173118608E-4, + "scoreConfidence" : [ + 0.060268838310712024, + 0.06215368874533574 + ], + "scorePercentiles" : { + "0.0" : 0.060794728860545565, + "50.0" : 0.06125431181862533, + "90.0" : 0.061585775565504965, + "95.0" : 0.061585775565504965, + "99.0" : 0.061585775565504965, + "99.9" : 0.061585775565504965, + "99.99" : 0.061585775565504965, + "99.999" : 0.061585775565504965, + "99.9999" : 0.061585775565504965, + "100.0" : 0.061585775565504965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06104217750865263, + 0.06090967162260933, + 0.060794728860545565 + ], + [ + 0.061585775565504965, + 0.061466446128598036, + 0.061468781482232754 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6177776478349633E-4, + "scoreError" : 3.5437822475386245E-5, + "scoreConfidence" : [ + 3.263399423081101E-4, + 3.9721558725888255E-4 + ], + "scorePercentiles" : { + "0.0" : 3.4955457993828557E-4, + "50.0" : 3.617766884796719E-4, + "90.0" : 3.7398545671454245E-4, + "95.0" : 3.7398545671454245E-4, + "99.0" : 3.7398545671454245E-4, + "99.9" : 3.7398545671454245E-4, + "99.99" : 3.7398545671454245E-4, + "99.999" : 3.7398545671454245E-4, + "99.9999" : 3.7398545671454245E-4, + "100.0" : 3.7398545671454245E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7398545671454245E-4, + 3.729793164029726E-4, + 3.7294672855555776E-4 + ], + [ + 3.4955457993828557E-4, + 3.5059385868583376E-4, + 3.50606648403786E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12338572543943184, + "scoreError" : 3.86327320099816E-4, + "scoreConfidence" : [ + 0.12299939811933203, + 0.12377205275953165 + ], + "scorePercentiles" : { + "0.0" : 0.12314839799763558, + "50.0" : 0.12340167388629494, + "90.0" : 0.12354554830500099, + "95.0" : 0.12354554830500099, + "99.0" : 0.12354554830500099, + "99.9" : 0.12354554830500099, + "99.99" : 0.12354554830500099, + "99.999" : 0.12354554830500099, + "99.9999" : 0.12354554830500099, + "100.0" : 0.12354554830500099 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12354554830500099, + 0.12346972597631894, + 0.12344636000938167 + ], + [ + 0.12334733258504577, + 0.1233569877632082, + 0.12314839799763558 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012926122934714694, + "scoreError" : 3.499613568935553E-4, + "scoreConfidence" : [ + 0.012576161577821139, + 0.01327608429160825 + ], + "scorePercentiles" : { + "0.0" : 0.01280441648388654, + "50.0" : 0.012925891577536047, + "90.0" : 0.013045700979068417, + "95.0" : 0.013045700979068417, + "99.0" : 0.013045700979068417, + "99.9" : 0.013045700979068417, + "99.99" : 0.013045700979068417, + "99.999" : 0.013045700979068417, + "99.9999" : 0.013045700979068417, + "100.0" : 0.013045700979068417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01281291295768837, + 0.012819738808888023, + 0.01280441648388654 + ], + [ + 0.013045700979068417, + 0.013041924032572746, + 0.01303204434618407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.050172894751404, + "scoreError" : 0.2349325371415315, + "scoreConfidence" : [ + 0.8152403576098725, + 1.2851054318929354 + ], + "scorePercentiles" : { + "0.0" : 0.9725198707575611, + "50.0" : 1.0486663463982568, + "90.0" : 1.1293367393562959, + "95.0" : 1.1293367393562959, + "99.0" : 1.1293367393562959, + "99.9" : 1.1293367393562959, + "99.99" : 1.1293367393562959, + "99.999" : 1.1293367393562959, + "99.9999" : 1.1293367393562959, + "100.0" : 1.1293367393562959 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1226961092276606, + 1.1293367393562959, + 1.127837591068005 + ], + [ + 0.9725198707575611, + 0.974636583568853, + 0.9740104745300477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011321600938389296, + "scoreError" : 5.083905043625274E-4, + "scoreConfidence" : [ + 0.01081321043402677, + 0.011829991442751823 + ], + "scorePercentiles" : { + "0.0" : 0.01115289260716532, + "50.0" : 0.011318274238287278, + "90.0" : 0.011494069411080486, + "95.0" : 0.011494069411080486, + "99.0" : 0.011494069411080486, + "99.9" : 0.011494069411080486, + "99.99" : 0.011494069411080486, + "99.999" : 0.011494069411080486, + "99.9999" : 0.011494069411080486, + "100.0" : 0.011494069411080486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011489850217612103, + 0.011494069411080486, + 0.011477117683514667 + ], + [ + 0.011156244917903305, + 0.01115289260716532, + 0.011159430793059888 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2048260390540855, + "scoreError" : 0.015495690676250553, + "scoreConfidence" : [ + 3.189330348377835, + 3.220321729730336 + ], + "scorePercentiles" : { + "0.0" : 3.198452440537084, + "50.0" : 3.2060237576923076, + "90.0" : 3.2130152536929995, + "95.0" : 3.2130152536929995, + "99.0" : 3.2130152536929995, + "99.9" : 3.2130152536929995, + "99.99" : 3.2130152536929995, + "99.999" : 3.2130152536929995, + "99.9999" : 3.2130152536929995, + "100.0" : 3.2130152536929995 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2067924115384616, + 3.2130152536929995, + 3.205804346153846 + ], + [ + 3.206243169230769, + 3.198452440537084, + 3.1986486131713554 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7944454605828013, + "scoreError" : 0.07110962568798375, + "scoreConfidence" : [ + 2.7233358348948173, + 2.8655550862707853 + ], + "scorePercentiles" : { + "0.0" : 2.7687413604651163, + "50.0" : 2.7910282464056175, + "90.0" : 2.8228587174710698, + "95.0" : 2.8228587174710698, + "99.0" : 2.8228587174710698, + "99.9" : 2.8228587174710698, + "99.99" : 2.8228587174710698, + "99.999" : 2.8228587174710698, + "99.9999" : 2.8228587174710698, + "100.0" : 2.8228587174710698 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.772537483781536, + 2.7742029908460473, + 2.7687413604651163 + ], + [ + 2.8228587174710698, + 2.820478708967851, + 2.8078535019651882 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17650772315135188, + "scoreError" : 0.0026793685192294183, + "scoreConfidence" : [ + 0.17382835463212246, + 0.1791870916705813 + ], + "scorePercentiles" : { + "0.0" : 0.1753855408548028, + "50.0" : 0.17672741032169487, + "90.0" : 0.17746352226224912, + "95.0" : 0.17746352226224912, + "99.0" : 0.17746352226224912, + "99.9" : 0.17746352226224912, + "99.99" : 0.17746352226224912, + "99.999" : 0.17746352226224912, + "99.9999" : 0.17746352226224912, + "100.0" : 0.17746352226224912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17746352226224912, + 0.17735057802330326, + 0.1771396638325008 + ], + [ + 0.17631515681088897, + 0.1753918771243664, + 0.1753855408548028 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3269457326987292, + "scoreError" : 0.017583334057544888, + "scoreConfidence" : [ + 0.3093623986411843, + 0.34452906675627404 + ], + "scorePercentiles" : { + "0.0" : 0.3211144117911502, + "50.0" : 0.326975257113473, + "90.0" : 0.33279908040201006, + "95.0" : 0.33279908040201006, + "99.0" : 0.33279908040201006, + "99.9" : 0.33279908040201006, + "99.99" : 0.33279908040201006, + "99.999" : 0.33279908040201006, + "99.9999" : 0.33279908040201006, + "100.0" : 0.33279908040201006 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32143746006235735, + 0.3211144117911502, + 0.32111799707790123 + ], + [ + 0.33251305416458854, + 0.33269239269436773, + 0.33279908040201006 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1412733797584331, + "scoreError" : 0.007565164666258601, + "scoreConfidence" : [ + 0.1337082150921745, + 0.1488385444246917 + ], + "scorePercentiles" : { + "0.0" : 0.13695183340180772, + "50.0" : 0.14128373197677582, + "90.0" : 0.14544687773980075, + "95.0" : 0.14544687773980075, + "99.0" : 0.14544687773980075, + "99.9" : 0.14544687773980075, + "99.99" : 0.14544687773980075, + "99.999" : 0.14544687773980075, + "99.9999" : 0.14544687773980075, + "100.0" : 0.14544687773980075 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1414526031317189, + 0.14099668117025027, + 0.14111486082183275 + ], + [ + 0.14544687773980075, + 0.14167742228518806, + 0.13695183340180772 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40002429473897233, + "scoreError" : 0.018591547315398273, + "scoreConfidence" : [ + 0.3814327474235741, + 0.4186158420543706 + ], + "scorePercentiles" : { + "0.0" : 0.3922989703828652, + "50.0" : 0.401533559595563, + "90.0" : 0.40660868341872003, + "95.0" : 0.40660868341872003, + "99.0" : 0.40660868341872003, + "99.9" : 0.40660868341872003, + "99.99" : 0.40660868341872003, + "99.999" : 0.40660868341872003, + "99.9999" : 0.40660868341872003, + "100.0" : 0.40660868341872003 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39781197987111144, + 0.3922989703828652, + 0.39265409211197927 + ], + [ + 0.40660868341872003, + 0.4055169033291432, + 0.4052551393200146 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16151324697656924, + "scoreError" : 0.0034961079272124414, + "scoreConfidence" : [ + 0.1580171390493568, + 0.16500935490378169 + ], + "scorePercentiles" : { + "0.0" : 0.16023828249583386, + "50.0" : 0.16134038297771214, + "90.0" : 0.16300352472697638, + "95.0" : 0.16300352472697638, + "99.0" : 0.16300352472697638, + "99.9" : 0.16300352472697638, + "99.99" : 0.16300352472697638, + "99.999" : 0.16300352472697638, + "99.9999" : 0.16300352472697638, + "100.0" : 0.16300352472697638 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16198587736292216, + 0.16300352472697638, + 0.162808051609332 + ], + [ + 0.1603488570718489, + 0.16069488859250214, + 0.16023828249583386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0463763750803837, + "scoreError" : 0.005020839607295861, + "scoreConfidence" : [ + 0.04135553547308784, + 0.051397214687679556 + ], + "scorePercentiles" : { + "0.0" : 0.044610879173283845, + "50.0" : 0.046213061774170144, + "90.0" : 0.04829509015570065, + "95.0" : 0.04829509015570065, + "99.0" : 0.04829509015570065, + "99.9" : 0.04829509015570065, + "99.99" : 0.04829509015570065, + "99.999" : 0.04829509015570065, + "99.9999" : 0.04829509015570065, + "100.0" : 0.04829509015570065 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04829509015570065, + 0.048168760480137955, + 0.04750603667423588 + ], + [ + 0.044610879173283845, + 0.044757397124839435, + 0.04492008687410442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8692789.728057452, + "scoreError" : 529507.1265061001, + "scoreConfidence" : [ + 8163282.601551351, + 9222296.854563551 + ], + "scorePercentiles" : { + "0.0" : 8516815.311489362, + "50.0" : 8692485.68268945, + "90.0" : 8870875.319148935, + "95.0" : 8870875.319148935, + "99.0" : 8870875.319148935, + "99.9" : 8870875.319148935, + "99.99" : 8870875.319148935, + "99.999" : 8870875.319148935, + "99.9999" : 8870875.319148935, + "100.0" : 8870875.319148935 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8516815.311489362, + 8520480.325383306, + 8524063.833049404 + ], + [ + 8870875.319148935, + 8863596.0469442, + 8860907.532329496 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-05T07:40:26Z-2b26495c3b73738ff36f6d7c8aff3b9a11f372d8-jdk17.json b/performance-results/2025-06-05T07:40:26Z-2b26495c3b73738ff36f6d7c8aff3b9a11f372d8-jdk17.json new file mode 100644 index 0000000000..44819b32ea --- /dev/null +++ b/performance-results/2025-06-05T07:40:26Z-2b26495c3b73738ff36f6d7c8aff3b9a11f372d8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3414395805070933, + "scoreError" : 0.046871730438032486, + "scoreConfidence" : [ + 3.2945678500690607, + 3.388311310945126 + ], + "scorePercentiles" : { + "0.0" : 3.3342719312088582, + "50.0" : 3.3408602416443793, + "90.0" : 3.349765907530756, + "95.0" : 3.349765907530756, + "99.0" : 3.349765907530756, + "99.9" : 3.349765907530756, + "99.99" : 3.349765907530756, + "99.999" : 3.349765907530756, + "99.9999" : 3.349765907530756, + "100.0" : 3.349765907530756 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.345130108147345, + 3.3342719312088582 + ], + [ + 3.336590375141414, + 3.349765907530756 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6868891038103977, + "scoreError" : 0.02374132039693783, + "scoreConfidence" : [ + 1.6631477834134598, + 1.7106304242073356 + ], + "scorePercentiles" : { + "0.0" : 1.6828580143091856, + "50.0" : 1.687131522216376, + "90.0" : 1.6904353564996533, + "95.0" : 1.6904353564996533, + "99.0" : 1.6904353564996533, + "99.9" : 1.6904353564996533, + "99.99" : 1.6904353564996533, + "99.999" : 1.6904353564996533, + "99.9999" : 1.6904353564996533, + "100.0" : 1.6904353564996533 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6847282320560697, + 1.6828580143091856 + ], + [ + 1.6904353564996533, + 1.6895348123766825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8521760159633964, + "scoreError" : 0.052399630945909534, + "scoreConfidence" : [ + 0.7997763850174869, + 0.9045756469093059 + ], + "scorePercentiles" : { + "0.0" : 0.840186427117903, + "50.0" : 0.8554541224921689, + "90.0" : 0.8576093917513448, + "95.0" : 0.8576093917513448, + "99.0" : 0.8576093917513448, + "99.9" : 0.8576093917513448, + "99.99" : 0.8576093917513448, + "99.999" : 0.8576093917513448, + "99.9999" : 0.8576093917513448, + "100.0" : 0.8576093917513448 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8543363025042242, + 0.8565719424801136 + ], + [ + 0.840186427117903, + 0.8576093917513448 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.26044330123182, + "scoreError" : 0.061014681563519996, + "scoreConfidence" : [ + 16.1994286196683, + 16.32145798279534 + ], + "scorePercentiles" : { + "0.0" : 16.23538573601834, + "50.0" : 16.260390943702564, + "90.0" : 16.28712557333508, + "95.0" : 16.28712557333508, + "99.0" : 16.28712557333508, + "99.9" : 16.28712557333508, + "99.99" : 16.28712557333508, + "99.999" : 16.28712557333508, + "99.9999" : 16.28712557333508, + "100.0" : 16.28712557333508 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.237456160497093, + 16.28712557333508, + 16.256028199208508 + ], + [ + 16.28191045013528, + 16.26475368819662, + 16.23538573601834 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2682.8696701358167, + "scoreError" : 9.702727245015499, + "scoreConfidence" : [ + 2673.1669428908012, + 2692.572397380832 + ], + "scorePercentiles" : { + "0.0" : 2677.848755035492, + "50.0" : 2683.345453382898, + "90.0" : 2687.1617887209823, + "95.0" : 2687.1617887209823, + "99.0" : 2687.1617887209823, + "99.9" : 2687.1617887209823, + "99.99" : 2687.1617887209823, + "99.999" : 2687.1617887209823, + "99.9999" : 2687.1617887209823, + "100.0" : 2687.1617887209823 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2680.257553263025, + 2682.0718300463427, + 2677.848755035492 + ], + [ + 2685.2590170296035, + 2687.1617887209823, + 2684.619076719453 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76751.3037439017, + "scoreError" : 162.20627971714285, + "scoreConfidence" : [ + 76589.09746418457, + 76913.51002361884 + ], + "scorePercentiles" : { + "0.0" : 76679.71186689303, + "50.0" : 76760.0581561534, + "90.0" : 76821.37127832204, + "95.0" : 76821.37127832204, + "99.0" : 76821.37127832204, + "99.9" : 76821.37127832204, + "99.99" : 76821.37127832204, + "99.999" : 76821.37127832204, + "99.9999" : 76821.37127832204, + "100.0" : 76821.37127832204 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76689.18579588505, + 76743.40348690572, + 76679.71186689303 + ], + [ + 76797.4372100032, + 76821.37127832204, + 76776.71282540109 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 366.84163305013243, + "scoreError" : 16.126028157710902, + "scoreConfidence" : [ + 350.71560489242154, + 382.9676612078433 + ], + "scorePercentiles" : { + "0.0" : 361.0489187989683, + "50.0" : 366.7129216111448, + "90.0" : 372.6018908667993, + "95.0" : 372.6018908667993, + "99.0" : 372.6018908667993, + "99.9" : 372.6018908667993, + "99.99" : 372.6018908667993, + "99.999" : 372.6018908667993, + "99.9999" : 372.6018908667993, + "100.0" : 372.6018908667993 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 361.0489187989683, + 362.11539546763754, + 361.6824785816711 + ], + [ + 371.31044775465205, + 372.2906668310661, + 372.6018908667993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.09832284560314, + "scoreError" : 1.6733126385018424, + "scoreConfidence" : [ + 114.4250102071013, + 117.77163548410498 + ], + "scorePercentiles" : { + "0.0" : 115.49558217848609, + "50.0" : 116.04750179445273, + "90.0" : 116.89519600488786, + "95.0" : 116.89519600488786, + "99.0" : 116.89519600488786, + "99.9" : 116.89519600488786, + "99.99" : 116.89519600488786, + "99.999" : 116.89519600488786, + "99.9999" : 116.89519600488786, + "100.0" : 116.89519600488786 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.67187474223924, + 116.54727101932599, + 116.4231288466662 + ], + [ + 115.49558217848609, + 115.55688428201333, + 116.89519600488786 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06111106039408757, + "scoreError" : 5.664424634283335E-4, + "scoreConfidence" : [ + 0.06054461793065924, + 0.0616775028575159 + ], + "scorePercentiles" : { + "0.0" : 0.06089610361899194, + "50.0" : 0.061106452395836536, + "90.0" : 0.06134028017886498, + "95.0" : 0.06134028017886498, + "99.0" : 0.06134028017886498, + "99.9" : 0.06134028017886498, + "99.99" : 0.06134028017886498, + "99.999" : 0.06134028017886498, + "99.9999" : 0.06134028017886498, + "100.0" : 0.06134028017886498 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06092414317568432, + 0.06097004813525427, + 0.06089610361899194 + ], + [ + 0.0612428566564188, + 0.06129293059931108, + 0.06134028017886498 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6208296152911973E-4, + "scoreError" : 6.269044336205225E-6, + "scoreConfidence" : [ + 3.558139171929145E-4, + 3.6835200586532495E-4 + ], + "scorePercentiles" : { + "0.0" : 3.598733395451569E-4, + "50.0" : 3.6207523471659155E-4, + "90.0" : 3.6463127250748904E-4, + "95.0" : 3.6463127250748904E-4, + "99.0" : 3.6463127250748904E-4, + "99.9" : 3.6463127250748904E-4, + "99.99" : 3.6463127250748904E-4, + "99.999" : 3.6463127250748904E-4, + "99.9999" : 3.6463127250748904E-4, + "100.0" : 3.6463127250748904E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.639577312825218E-4, + 3.6369806355412103E-4, + 3.6463127250748904E-4 + ], + [ + 3.598733395451569E-4, + 3.6045240587906206E-4, + 3.5988495640636755E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12233218943311586, + "scoreError" : 0.0010413720738431669, + "scoreConfidence" : [ + 0.12129081735927269, + 0.12337356150695902 + ], + "scorePercentiles" : { + "0.0" : 0.12199824691960473, + "50.0" : 0.12226286580960624, + "90.0" : 0.12294852500737681, + "95.0" : 0.12294852500737681, + "99.0" : 0.12294852500737681, + "99.9" : 0.12294852500737681, + "99.99" : 0.12294852500737681, + "99.999" : 0.12294852500737681, + "99.9999" : 0.12294852500737681, + "100.0" : 0.12294852500737681 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12251935851853667, + 0.12241122001885106, + 0.12294852500737681 + ], + [ + 0.12211451160036144, + 0.12199824691960473, + 0.12200127453396448 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012770732156686735, + "scoreError" : 3.445818928663633E-4, + "scoreConfidence" : [ + 0.012426150263820372, + 0.013115314049553097 + ], + "scorePercentiles" : { + "0.0" : 0.012646308104669721, + "50.0" : 0.01277044279092674, + "90.0" : 0.012891148131580847, + "95.0" : 0.012891148131580847, + "99.0" : 0.012891148131580847, + "99.9" : 0.012891148131580847, + "99.99" : 0.012891148131580847, + "99.999" : 0.012891148131580847, + "99.9999" : 0.012891148131580847, + "100.0" : 0.012891148131580847 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012885210215515131, + 0.012871279644448105, + 0.012891148131580847 + ], + [ + 0.012646308104669721, + 0.012660840906501235, + 0.012669605937405376 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0135445399567617, + "scoreError" : 0.05863018093752046, + "scoreConfidence" : [ + 0.9549143590192413, + 1.0721747208942822 + ], + "scorePercentiles" : { + "0.0" : 0.992837416757669, + "50.0" : 1.012872757032553, + "90.0" : 1.0349437505950534, + "95.0" : 1.0349437505950534, + "99.0" : 1.0349437505950534, + "99.9" : 1.0349437505950534, + "99.99" : 1.0349437505950534, + "99.999" : 1.0349437505950534, + "99.9999" : 1.0349437505950534, + "100.0" : 1.0349437505950534 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0349437505950534, + 1.0301878420889987, + 1.0325557049044916 + ], + [ + 0.9951848534182506, + 0.9955576719761076, + 0.992837416757669 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01087323187166928, + "scoreError" : 1.3417266082953273E-4, + "scoreConfidence" : [ + 0.010739059210839747, + 0.011007404532498814 + ], + "scorePercentiles" : { + "0.0" : 0.010828105880569542, + "50.0" : 0.010869751756007177, + "90.0" : 0.010929093596791293, + "95.0" : 0.010929093596791293, + "99.0" : 0.010929093596791293, + "99.9" : 0.010929093596791293, + "99.99" : 0.010929093596791293, + "99.999" : 0.010929093596791293, + "99.9999" : 0.010929093596791293, + "100.0" : 0.010929093596791293 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010828105880569542, + 0.010829799562486463, + 0.010832290673188994 + ], + [ + 0.010907212838825361, + 0.010912888678154022, + 0.010929093596791293 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2166360642089464, + "scoreError" : 0.41701653968057645, + "scoreConfidence" : [ + 2.79961952452837, + 3.633652603889523 + ], + "scorePercentiles" : { + "0.0" : 3.0776599193846153, + "50.0" : 3.2162520343284062, + "90.0" : 3.3564145751677854, + "95.0" : 3.3564145751677854, + "99.0" : 3.3564145751677854, + "99.9" : 3.3564145751677854, + "99.99" : 3.3564145751677854, + "99.999" : 3.3564145751677854, + "99.9999" : 3.3564145751677854, + "100.0" : 3.3564145751677854 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.349930972538513, + 3.3564145751677854, + 3.3507525244474214 + ], + [ + 3.0825730961182995, + 3.0824852975970427, + 3.0776599193846153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7325655714716564, + "scoreError" : 0.17111138604912524, + "scoreConfidence" : [ + 2.561454185422531, + 2.9036769575207817 + ], + "scorePercentiles" : { + "0.0" : 2.6723747563451776, + "50.0" : 2.7329903645014735, + "90.0" : 2.7918626769960917, + "95.0" : 2.7918626769960917, + "99.0" : 2.7918626769960917, + "99.9" : 2.7918626769960917, + "99.99" : 2.7918626769960917, + "99.999" : 2.7918626769960917, + "99.9999" : 2.7918626769960917, + "100.0" : 2.7918626769960917 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6801927033762056, + 2.67826197643278, + 2.6723747563451776 + ], + [ + 2.7869132900529396, + 2.7918626769960917, + 2.785788025626741 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1837080428215959, + "scoreError" : 0.023837178825182676, + "scoreConfidence" : [ + 0.1598708639964132, + 0.20754522164677858 + ], + "scorePercentiles" : { + "0.0" : 0.17586422177866098, + "50.0" : 0.18360247702795607, + "90.0" : 0.19174997802577082, + "95.0" : 0.19174997802577082, + "99.0" : 0.19174997802577082, + "99.9" : 0.19174997802577082, + "99.99" : 0.19174997802577082, + "99.999" : 0.19174997802577082, + "99.9999" : 0.19174997802577082, + "100.0" : 0.19174997802577082 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19145767355261142, + 0.19174997802577082, + 0.19119081500812543 + ], + [ + 0.17597142951662004, + 0.17601413904778668, + 0.17586422177866098 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31892102930624616, + "scoreError" : 0.03806269812438478, + "scoreConfidence" : [ + 0.2808583311818614, + 0.35698372743063095 + ], + "scorePercentiles" : { + "0.0" : 0.3055318921817238, + "50.0" : 0.31907028784776503, + "90.0" : 0.3339448963467575, + "95.0" : 0.3339448963467575, + "99.0" : 0.3339448963467575, + "99.9" : 0.3339448963467575, + "99.99" : 0.3339448963467575, + "99.999" : 0.3339448963467575, + "99.9999" : 0.3339448963467575, + "100.0" : 0.3339448963467575 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3339448963467575, + 0.3302890899362552, + 0.3293176085224092 + ], + [ + 0.30882296717312085, + 0.30561972167721035, + 0.3055318921817238 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1402900360119306, + "scoreError" : 0.007428553056603889, + "scoreConfidence" : [ + 0.1328614829553267, + 0.1477185890685345 + ], + "scorePercentiles" : { + "0.0" : 0.1378113738630726, + "50.0" : 0.14014746715830104, + "90.0" : 0.14307564805276562, + "95.0" : 0.14307564805276562, + "99.0" : 0.14307564805276562, + "99.9" : 0.14307564805276562, + "99.99" : 0.14307564805276562, + "99.999" : 0.14307564805276562, + "99.9999" : 0.14307564805276562, + "100.0" : 0.14307564805276562 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13792411646093372, + 0.1378113738630726, + 0.13790661888738726 + ], + [ + 0.14307564805276562, + 0.14237081785566835, + 0.142651640951756 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4092967325656189, + "scoreError" : 0.0121157111598231, + "scoreConfidence" : [ + 0.3971810214057958, + 0.42141244372544195 + ], + "scorePercentiles" : { + "0.0" : 0.4041225980360462, + "50.0" : 0.4083675004407429, + "90.0" : 0.41586958156942655, + "95.0" : 0.41586958156942655, + "99.0" : 0.41586958156942655, + "99.9" : 0.41586958156942655, + "99.99" : 0.41586958156942655, + "99.999" : 0.41586958156942655, + "99.9999" : 0.41586958156942655, + "100.0" : 0.41586958156942655 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41269858162759987, + 0.41586958156942655, + 0.40920641218593995 + ], + [ + 0.40752858869554587, + 0.40635463327915483, + 0.4041225980360462 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15983828064684039, + "scoreError" : 0.007843807728838907, + "scoreConfidence" : [ + 0.15199447291800147, + 0.1676820883756793 + ], + "scorePercentiles" : { + "0.0" : 0.15716707081787892, + "50.0" : 0.15944649042566278, + "90.0" : 0.1628719169543974, + "95.0" : 0.1628719169543974, + "99.0" : 0.1628719169543974, + "99.9" : 0.1628719169543974, + "99.99" : 0.1628719169543974, + "99.999" : 0.1628719169543974, + "99.9999" : 0.1628719169543974, + "100.0" : 0.1628719169543974 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1628719169543974, + 0.16274452030204892, + 0.16142813327306774 + ], + [ + 0.15735319495539157, + 0.15746484757825785, + 0.15716707081787892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04645975449587328, + "scoreError" : 0.0031885827727397105, + "scoreConfidence" : [ + 0.04327117172313357, + 0.04964833726861299 + ], + "scorePercentiles" : { + "0.0" : 0.04539349169083836, + "50.0" : 0.04646975527885863, + "90.0" : 0.04752755751947416, + "95.0" : 0.04752755751947416, + "99.0" : 0.04752755751947416, + "99.9" : 0.04752755751947416, + "99.99" : 0.04752755751947416, + "99.999" : 0.04752755751947416, + "99.9999" : 0.04752755751947416, + "100.0" : 0.04752755751947416 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047485382456290304, + 0.04752755751947416, + 0.047479445864590256 + ], + [ + 0.04539349169083836, + 0.04546006469312701, + 0.045412584750919575 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8419345.796838839, + "scoreError" : 103562.52099104252, + "scoreConfidence" : [ + 8315783.275847796, + 8522908.31782988 + ], + "scorePercentiles" : { + "0.0" : 8380159.912897822, + "50.0" : 8416146.237416815, + "90.0" : 8460306.114116652, + "95.0" : 8460306.114116652, + "99.0" : 8460306.114116652, + "99.9" : 8460306.114116652, + "99.99" : 8460306.114116652, + "99.999" : 8460306.114116652, + "99.9999" : 8460306.114116652, + "100.0" : 8460306.114116652 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8389732.617449664, + 8388644.272422465, + 8380159.912897822 + ], + [ + 8460306.114116652, + 8454672.00676247, + 8442559.857383966 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-05T07:40:52Z-2b26495c3b73738ff36f6d7c8aff3b9a11f372d8-jdk17.json b/performance-results/2025-06-05T07:40:52Z-2b26495c3b73738ff36f6d7c8aff3b9a11f372d8-jdk17.json new file mode 100644 index 0000000000..04a95bc9c5 --- /dev/null +++ b/performance-results/2025-06-05T07:40:52Z-2b26495c3b73738ff36f6d7c8aff3b9a11f372d8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.346800541757778, + "scoreError" : 0.01795258592853953, + "scoreConfidence" : [ + 3.3288479558292385, + 3.364753127686318 + ], + "scorePercentiles" : { + "0.0" : 3.343041574244067, + "50.0" : 3.3472073423986926, + "90.0" : 3.34974590798966, + "95.0" : 3.34974590798966, + "99.0" : 3.34974590798966, + "99.9" : 3.34974590798966, + "99.99" : 3.34974590798966, + "99.999" : 3.34974590798966, + "99.9999" : 3.34974590798966, + "100.0" : 3.34974590798966 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.343041574244067, + 3.3471101255694107 + ], + [ + 3.3473045592279744, + 3.34974590798966 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.688834364463484, + "scoreError" : 0.0710313933416004, + "scoreConfidence" : [ + 1.6178029711218835, + 1.7598657578050845 + ], + "scorePercentiles" : { + "0.0" : 1.678078661551572, + "50.0" : 1.6888565871216203, + "90.0" : 1.6995456220591239, + "95.0" : 1.6995456220591239, + "99.0" : 1.6995456220591239, + "99.9" : 1.6995456220591239, + "99.99" : 1.6995456220591239, + "99.999" : 1.6995456220591239, + "99.9999" : 1.6995456220591239, + "100.0" : 1.6995456220591239 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.678078661551572, + 1.68073047684942 + ], + [ + 1.6969826973938207, + 1.6995456220591239 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8520010071018522, + "scoreError" : 0.01340114517920515, + "scoreConfidence" : [ + 0.8385998619226471, + 0.8654021522810573 + ], + "scorePercentiles" : { + "0.0" : 0.8495619047606462, + "50.0" : 0.8519279137889959, + "90.0" : 0.8545862960687713, + "95.0" : 0.8545862960687713, + "99.0" : 0.8545862960687713, + "99.9" : 0.8545862960687713, + "99.99" : 0.8545862960687713, + "99.999" : 0.8545862960687713, + "99.9999" : 0.8545862960687713, + "100.0" : 0.8545862960687713 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8495619047606462, + 0.8545862960687713 + ], + [ + 0.8515681652553272, + 0.8522876623226645 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.112989259433288, + "scoreError" : 0.34282622247933536, + "scoreConfidence" : [ + 15.770163036953953, + 16.455815481912623 + ], + "scorePercentiles" : { + "0.0" : 15.985740816789841, + "50.0" : 16.118236718346175, + "90.0" : 16.241124233681205, + "95.0" : 16.241124233681205, + "99.0" : 16.241124233681205, + "99.9" : 16.241124233681205, + "99.99" : 16.241124233681205, + "99.999" : 16.241124233681205, + "99.9999" : 16.241124233681205, + "100.0" : 16.241124233681205 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.22043562311978, + 16.20879335409353, + 16.241124233681205 + ], + [ + 15.994161446316557, + 16.02768008259882, + 15.985740816789841 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2780.647348200287, + "scoreError" : 275.5496490193163, + "scoreConfidence" : [ + 2505.0976991809707, + 3056.1969972196034 + ], + "scorePercentiles" : { + "0.0" : 2675.8728519192077, + "50.0" : 2779.4591041552685, + "90.0" : 2879.1671450252084, + "95.0" : 2879.1671450252084, + "99.0" : 2879.1671450252084, + "99.9" : 2879.1671450252084, + "99.99" : 2879.1671450252084, + "99.999" : 2879.1671450252084, + "99.9999" : 2879.1671450252084, + "100.0" : 2879.1671450252084 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2696.509120804338, + 2702.3012831430515, + 2675.8728519192077 + ], + [ + 2879.1671450252084, + 2856.616925167485, + 2873.416763142431 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76928.57720658074, + "scoreError" : 3056.045495554094, + "scoreConfidence" : [ + 73872.53171102665, + 79984.62270213483 + ], + "scorePercentiles" : { + "0.0" : 75916.00701031623, + "50.0" : 76909.51089956146, + "90.0" : 77970.82208215236, + "95.0" : 77970.82208215236, + "99.0" : 77970.82208215236, + "99.9" : 77970.82208215236, + "99.99" : 77970.82208215236, + "99.999" : 77970.82208215236, + "99.9999" : 77970.82208215236, + "100.0" : 77970.82208215236 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77853.89921148181, + 77943.3536416547, + 77970.82208215236 + ], + [ + 75922.25870623822, + 75916.00701031623, + 75965.12258764109 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 365.6214443274716, + "scoreError" : 14.871053515394365, + "scoreConfidence" : [ + 350.7503908120772, + 380.49249784286593 + ], + "scorePercentiles" : { + "0.0" : 360.3963346972968, + "50.0" : 365.7084965133279, + "90.0" : 370.65408652232134, + "95.0" : 370.65408652232134, + "99.0" : 370.65408652232134, + "99.9" : 370.65408652232134, + "99.99" : 370.65408652232134, + "99.999" : 370.65408652232134, + "99.9999" : 370.65408652232134, + "100.0" : 370.65408652232134 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 370.48917493614, + 370.223028522099, + 370.65408652232134 + ], + [ + 361.1939645045568, + 360.3963346972968, + 360.7720767824152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.28509013810505, + "scoreError" : 6.236868789193347, + "scoreConfidence" : [ + 109.0482213489117, + 121.5219589272984 + ], + "scorePercentiles" : { + "0.0" : 112.39772540723094, + "50.0" : 116.03719204371811, + "90.0" : 117.21807898061627, + "95.0" : 117.21807898061627, + "99.0" : 117.21807898061627, + "99.9" : 117.21807898061627, + "99.99" : 117.21807898061627, + "99.999" : 117.21807898061627, + "99.9999" : 117.21807898061627, + "100.0" : 117.21807898061627 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.39772540723094, + 112.85464333513782, + 115.01609436746419 + ], + [ + 117.21807898061627, + 117.05828971997201, + 117.16570901820907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06154713140579223, + "scoreError" : 0.0010052292743893078, + "scoreConfidence" : [ + 0.060541902131402925, + 0.06255236068018154 + ], + "scorePercentiles" : { + "0.0" : 0.061191925096222684, + "50.0" : 0.061498076086224956, + "90.0" : 0.06202456001091615, + "95.0" : 0.06202456001091615, + "99.0" : 0.06202456001091615, + "99.9" : 0.06202456001091615, + "99.99" : 0.06202456001091615, + "99.999" : 0.06202456001091615, + "99.9999" : 0.06202456001091615, + "100.0" : 0.06202456001091615 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06124222500734898, + 0.061191925096222684, + 0.061261661633085635 + ], + [ + 0.061827926147815654, + 0.06173449053936427, + 0.06202456001091615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6575890749415E-4, + "scoreError" : 1.3828591895466834E-5, + "scoreConfidence" : [ + 3.519303155986832E-4, + 3.7958749938961687E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6046085047311625E-4, + "50.0" : 3.656176093781589E-4, + "90.0" : 3.71789535425747E-4, + "95.0" : 3.71789535425747E-4, + "99.0" : 3.71789535425747E-4, + "99.9" : 3.71789535425747E-4, + "99.99" : 3.71789535425747E-4, + "99.999" : 3.71789535425747E-4, + "99.9999" : 3.71789535425747E-4, + "100.0" : 3.71789535425747E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6046085047311625E-4, + 3.610734094781565E-4, + 3.626831063278454E-4 + ], + [ + 3.699944308315629E-4, + 3.71789535425747E-4, + 3.685521124284723E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12664009562942016, + "scoreError" : 9.381624397491443E-4, + "scoreConfidence" : [ + 0.12570193318967102, + 0.1275782580691693 + ], + "scorePercentiles" : { + "0.0" : 0.12612485943648472, + "50.0" : 0.12663474022440227, + "90.0" : 0.12713994263628967, + "95.0" : 0.12713994263628967, + "99.0" : 0.12713994263628967, + "99.9" : 0.12713994263628967, + "99.99" : 0.12713994263628967, + "99.999" : 0.12713994263628967, + "99.9999" : 0.12713994263628967, + "100.0" : 0.12713994263628967 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12612485943648472, + 0.12656488020806966, + 0.12670460024073488 + ], + [ + 0.12713994263628967, + 0.12678385582433185, + 0.1265224354306102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012766302846904956, + "scoreError" : 4.8622731258282393E-4, + "scoreConfidence" : [ + 0.012280075534322131, + 0.01325253015948778 + ], + "scorePercentiles" : { + "0.0" : 0.012601365308886999, + "50.0" : 0.012769128912713318, + "90.0" : 0.012934245718823725, + "95.0" : 0.012934245718823725, + "99.0" : 0.012934245718823725, + "99.9" : 0.012934245718823725, + "99.99" : 0.012934245718823725, + "99.999" : 0.012934245718823725, + "99.9999" : 0.012934245718823725, + "100.0" : 0.012934245718823725 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012601365308886999, + 0.012619525593961888, + 0.012603700137882706 + ], + [ + 0.01292024809040967, + 0.012918732231464747, + 0.012934245718823725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0381645193554132, + "scoreError" : 0.09028927776853148, + "scoreConfidence" : [ + 0.9478752415868817, + 1.1284537971239448 + ], + "scorePercentiles" : { + "0.0" : 1.0068082438336856, + "50.0" : 1.0386005208966131, + "90.0" : 1.0681727486648152, + "95.0" : 1.0681727486648152, + "99.0" : 1.0681727486648152, + "99.9" : 1.0681727486648152, + "99.99" : 1.0681727486648152, + "99.999" : 1.0681727486648152, + "99.9999" : 1.0681727486648152, + "100.0" : 1.0681727486648152 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.068098819181886, + 1.0681727486648152, + 1.0663099347478409 + ], + [ + 1.0108911070453857, + 1.0087062626588663, + 1.0068082438336856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011107134460866646, + "scoreError" : 0.0016983355767711118, + "scoreConfidence" : [ + 0.009408798884095534, + 0.012805470037637759 + ], + "scorePercentiles" : { + "0.0" : 0.010534898578878061, + "50.0" : 0.011115936138504316, + "90.0" : 0.011676937712368083, + "95.0" : 0.011676937712368083, + "99.0" : 0.011676937712368083, + "99.9" : 0.011676937712368083, + "99.99" : 0.011676937712368083, + "99.999" : 0.011676937712368083, + "99.9999" : 0.011676937712368083, + "100.0" : 0.011676937712368083 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01166030222519682, + 0.011641639650945395, + 0.011676937712368083 + ], + [ + 0.010534898578878061, + 0.010590232626063236, + 0.010538795971748281 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2741913629104027, + "scoreError" : 0.1272162716327141, + "scoreConfidence" : [ + 3.146975091277689, + 3.4014076345431166 + ], + "scorePercentiles" : { + "0.0" : 3.2216848235672892, + "50.0" : 3.2807756638793326, + "90.0" : 3.315588143141153, + "95.0" : 3.315588143141153, + "99.0" : 3.315588143141153, + "99.9" : 3.315588143141153, + "99.99" : 3.315588143141153, + "99.999" : 3.315588143141153, + "99.9999" : 3.315588143141153, + "100.0" : 3.315588143141153 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.315440432736912, + 3.315588143141153, + 3.3136102582781457 + ], + [ + 3.230883450258398, + 3.2216848235672892, + 3.2479410694805195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8267180525545563, + "scoreError" : 0.045743115058050426, + "scoreConfidence" : [ + 2.780974937496506, + 2.872461167612607 + ], + "scorePercentiles" : { + "0.0" : 2.8131432396624474, + "50.0" : 2.8233969917348984, + "90.0" : 2.8532055044222537, + "95.0" : 2.8532055044222537, + "99.0" : 2.8532055044222537, + "99.9" : 2.8532055044222537, + "99.99" : 2.8532055044222537, + "99.999" : 2.8532055044222537, + "99.9999" : 2.8532055044222537, + "100.0" : 2.8532055044222537 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8131432396624474, + 2.8136968140646976, + 2.81322152883263 + ], + [ + 2.8532055044222537, + 2.83394405894021, + 2.8330971694050993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18393929359352265, + "scoreError" : 0.009864984179311535, + "scoreConfidence" : [ + 0.17407430941421112, + 0.19380427777283418 + ], + "scorePercentiles" : { + "0.0" : 0.18089873929559885, + "50.0" : 0.1831129950010586, + "90.0" : 0.1894004436068865, + "95.0" : 0.1894004436068865, + "99.0" : 0.1894004436068865, + "99.9" : 0.1894004436068865, + "99.99" : 0.1894004436068865, + "99.999" : 0.1894004436068865, + "99.9999" : 0.1894004436068865, + "100.0" : 0.1894004436068865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1894004436068865, + 0.18607028862756772, + 0.18517452746092883 + ], + [ + 0.18104030002896557, + 0.1810514625411884, + 0.18089873929559885 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31973503069035514, + "scoreError" : 0.002340966167381667, + "scoreConfidence" : [ + 0.3173940645229735, + 0.3220759968577368 + ], + "scorePercentiles" : { + "0.0" : 0.31879358028626986, + "50.0" : 0.31973810436332917, + "90.0" : 0.3209818412132884, + "95.0" : 0.3209818412132884, + "99.0" : 0.3209818412132884, + "99.9" : 0.3209818412132884, + "99.99" : 0.3209818412132884, + "99.999" : 0.3209818412132884, + "99.9999" : 0.3209818412132884, + "100.0" : 0.3209818412132884 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3197548508073541, + 0.31879358028626986, + 0.3188740875609834 + ], + [ + 0.3197213579193043, + 0.3202844663549307, + 0.3209818412132884 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1427815629437479, + "scoreError" : 0.009744923940682299, + "scoreConfidence" : [ + 0.1330366390030656, + 0.15252648688443018 + ], + "scorePercentiles" : { + "0.0" : 0.13979187326660703, + "50.0" : 0.14217908933503132, + "90.0" : 0.14841604611160583, + "95.0" : 0.14841604611160583, + "99.0" : 0.14841604611160583, + "99.9" : 0.14841604611160583, + "99.99" : 0.14841604611160583, + "99.999" : 0.14841604611160583, + "99.9999" : 0.14841604611160583, + "100.0" : 0.14841604611160583 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14018814910141028, + 0.13979187326660703, + 0.13982479890658425 + ], + [ + 0.14841604611160583, + 0.1442984807076275, + 0.14417002956865232 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40131010395932104, + "scoreError" : 0.0356162690745942, + "scoreConfidence" : [ + 0.36569383488472684, + 0.43692637303391524 + ], + "scorePercentiles" : { + "0.0" : 0.38920219019264446, + "50.0" : 0.39943109835112733, + "90.0" : 0.4156298187938988, + "95.0" : 0.4156298187938988, + "99.0" : 0.4156298187938988, + "99.9" : 0.4156298187938988, + "99.99" : 0.4156298187938988, + "99.999" : 0.4156298187938988, + "99.9999" : 0.4156298187938988, + "100.0" : 0.4156298187938988 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.391164942227959, + 0.38920219019264446, + 0.3896329257772929 + ], + [ + 0.4156298187938988, + 0.4145334922898358, + 0.4076972544742957 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1565493334604792, + "scoreError" : 0.004195158002448803, + "scoreConfidence" : [ + 0.1523541754580304, + 0.160744491462928 + ], + "scorePercentiles" : { + "0.0" : 0.1549165470318503, + "50.0" : 0.15653063931033043, + "90.0" : 0.1581113321211738, + "95.0" : 0.1581113321211738, + "99.0" : 0.1581113321211738, + "99.9" : 0.1581113321211738, + "99.99" : 0.1581113321211738, + "99.999" : 0.1581113321211738, + "99.9999" : 0.1581113321211738, + "100.0" : 0.1581113321211738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1581113321211738, + 0.15794151854191674, + 0.15764804618974051 + ], + [ + 0.15541323243092034, + 0.1549165470318503, + 0.15526532444727362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047689161432700446, + "scoreError" : 0.0010190283998247136, + "scoreConfidence" : [ + 0.04667013303287573, + 0.04870818983252516 + ], + "scorePercentiles" : { + "0.0" : 0.04721845914016574, + "50.0" : 0.04783774370152301, + "90.0" : 0.048017714866032846, + "95.0" : 0.048017714866032846, + "99.0" : 0.048017714866032846, + "99.9" : 0.048017714866032846, + "99.99" : 0.048017714866032846, + "99.999" : 0.048017714866032846, + "99.9999" : 0.048017714866032846, + "100.0" : 0.048017714866032846 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04777892620162446, + 0.048017714866032846, + 0.04797749889173551 + ], + [ + 0.04789656120142155, + 0.04721845914016574, + 0.04724580829522262 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8628959.413159462, + "scoreError" : 66738.33212440078, + "scoreConfidence" : [ + 8562221.08103506, + 8695697.745283863 + ], + "scorePercentiles" : { + "0.0" : 8598174.565292096, + "50.0" : 8630070.847784579, + "90.0" : 8661977.858874459, + "95.0" : 8661977.858874459, + "99.0" : 8661977.858874459, + "99.9" : 8661977.858874459, + "99.99" : 8661977.858874459, + "99.999" : 8661977.858874459, + "99.9999" : 8661977.858874459, + "100.0" : 8661977.858874459 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8661977.858874459, + 8645937.082973206, + 8634762.86022433 + ], + [ + 8625378.835344827, + 8607525.276247848, + 8598174.565292096 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-05T08:39:29Z-fa22b821dd44aa991c3746f36b49661aa97db913-jdk17.json b/performance-results/2025-06-05T08:39:29Z-fa22b821dd44aa991c3746f36b49661aa97db913-jdk17.json new file mode 100644 index 0000000000..22466414f1 --- /dev/null +++ b/performance-results/2025-06-05T08:39:29Z-fa22b821dd44aa991c3746f36b49661aa97db913-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3275185541629226, + "scoreError" : 0.03553605784569815, + "scoreConfidence" : [ + 3.2919824963172246, + 3.3630546120086207 + ], + "scorePercentiles" : { + "0.0" : 3.3206265226352634, + "50.0" : 3.3286442233336073, + "90.0" : 3.332159247349212, + "95.0" : 3.332159247349212, + "99.0" : 3.332159247349212, + "99.9" : 3.332159247349212, + "99.99" : 3.332159247349212, + "99.999" : 3.332159247349212, + "99.9999" : 3.332159247349212, + "100.0" : 3.332159247349212 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3206265226352634, + 3.331738950237085 + ], + [ + 3.32554949643013, + 3.332159247349212 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6783071368347324, + "scoreError" : 0.03742877767379456, + "scoreConfidence" : [ + 1.640878359160938, + 1.715735914508527 + ], + "scorePercentiles" : { + "0.0" : 1.6705872749133792, + "50.0" : 1.679398823553512, + "90.0" : 1.6838436253185265, + "95.0" : 1.6838436253185265, + "99.0" : 1.6838436253185265, + "99.9" : 1.6838436253185265, + "99.99" : 1.6838436253185265, + "99.999" : 1.6838436253185265, + "99.9999" : 1.6838436253185265, + "100.0" : 1.6838436253185265 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6773970380100793, + 1.6838436253185265 + ], + [ + 1.6705872749133792, + 1.6814006090969447 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.837734827737114, + "scoreError" : 0.056575984181638735, + "scoreConfidence" : [ + 0.7811588435554753, + 0.8943108119187528 + ], + "scorePercentiles" : { + "0.0" : 0.831071620013888, + "50.0" : 0.8346987268326309, + "90.0" : 0.8504702372693066, + "95.0" : 0.8504702372693066, + "99.0" : 0.8504702372693066, + "99.9" : 0.8504702372693066, + "99.99" : 0.8504702372693066, + "99.999" : 0.8504702372693066, + "99.9999" : 0.8504702372693066, + "100.0" : 0.8504702372693066 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.831071620013888, + 0.8504702372693066 + ], + [ + 0.8331278083400208, + 0.8362696453252411 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.100386170470006, + "scoreError" : 0.051845933379740895, + "scoreConfidence" : [ + 16.048540237090265, + 16.152232103849748 + ], + "scorePercentiles" : { + "0.0" : 16.076321609097263, + "50.0" : 16.101201851337187, + "90.0" : 16.124197152104248, + "95.0" : 16.124197152104248, + "99.0" : 16.124197152104248, + "99.9" : 16.124197152104248, + "99.99" : 16.124197152104248, + "99.999" : 16.124197152104248, + "99.9999" : 16.124197152104248, + "100.0" : 16.124197152104248 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.124197152104248, + 16.087072280598328, + 16.112202854308315 + ], + [ + 16.09020084836606, + 16.112322278345818, + 16.076321609097263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2661.108134772785, + "scoreError" : 40.74426752627458, + "scoreConfidence" : [ + 2620.3638672465104, + 2701.8524022990596 + ], + "scorePercentiles" : { + "0.0" : 2645.760867496771, + "50.0" : 2661.4692396823148, + "90.0" : 2676.1943510441174, + "95.0" : 2676.1943510441174, + "99.0" : 2676.1943510441174, + "99.9" : 2676.1943510441174, + "99.99" : 2676.1943510441174, + "99.999" : 2676.1943510441174, + "99.9999" : 2676.1943510441174, + "100.0" : 2676.1943510441174 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2647.385801023843, + 2645.760867496771, + 2650.791677688593 + ], + [ + 2672.1468016760364, + 2674.3693097073483, + 2676.1943510441174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76062.25624319282, + "scoreError" : 3286.3003218041436, + "scoreConfidence" : [ + 72775.95592138868, + 79348.55656499696 + ], + "scorePercentiles" : { + "0.0" : 74976.73753861556, + "50.0" : 76068.11337509079, + "90.0" : 77161.06996916088, + "95.0" : 77161.06996916088, + "99.0" : 77161.06996916088, + "99.9" : 77161.06996916088, + "99.99" : 77161.06996916088, + "99.999" : 77161.06996916088, + "99.9999" : 77161.06996916088, + "100.0" : 77161.06996916088 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77117.18294774441, + 77161.06996916088, + 77117.42175779326 + ], + [ + 74976.73753861556, + 74982.08144340567, + 75019.04380243717 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.19808083250183, + "scoreError" : 16.278482393815015, + "scoreConfidence" : [ + 330.9195984386868, + 363.47656322631684 + ], + "scorePercentiles" : { + "0.0" : 340.23628691060594, + "50.0" : 347.44731119614687, + "90.0" : 353.02060217166763, + "95.0" : 353.02060217166763, + "99.0" : 353.02060217166763, + "99.9" : 353.02060217166763, + "99.99" : 353.02060217166763, + "99.999" : 353.02060217166763, + "99.9999" : 353.02060217166763, + "100.0" : 353.02060217166763 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 352.5952866825053, + 351.58543536238886, + 353.02060217166763 + ], + [ + 340.23628691060594, + 343.3091870299048, + 342.44168683793845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.1248913157721, + "scoreError" : 5.070437280189476, + "scoreConfidence" : [ + 108.05445403558262, + 118.19532859596158 + ], + "scorePercentiles" : { + "0.0" : 110.80431543202809, + "50.0" : 113.19278472780539, + "90.0" : 115.00996289791087, + "95.0" : 115.00996289791087, + "99.0" : 115.00996289791087, + "99.9" : 115.00996289791087, + "99.99" : 115.00996289791087, + "99.999" : 115.00996289791087, + "99.9999" : 115.00996289791087, + "100.0" : 115.00996289791087 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.00996289791087, + 114.67741122197295, + 114.50040033826056 + ], + [ + 110.80431543202809, + 111.88516911735023, + 111.87208888710984 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06305882537886515, + "scoreError" : 3.868245116256811E-4, + "scoreConfidence" : [ + 0.06267200086723947, + 0.06344564989049083 + ], + "scorePercentiles" : { + "0.0" : 0.06288577523094434, + "50.0" : 0.06306533821042906, + "90.0" : 0.06322890090921736, + "95.0" : 0.06322890090921736, + "99.0" : 0.06322890090921736, + "99.9" : 0.06322890090921736, + "99.99" : 0.06322890090921736, + "99.999" : 0.06322890090921736, + "99.9999" : 0.06322890090921736, + "100.0" : 0.06322890090921736 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06313659345918303, + 0.06322890090921736, + 0.06316777921306795 + ], + [ + 0.06299408296167511, + 0.06288577523094434, + 0.06293982049910313 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.819890204839837E-4, + "scoreError" : 2.8155049448342767E-5, + "scoreConfidence" : [ + 3.5383397103564096E-4, + 4.1014406993232646E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7240742095874285E-4, + "50.0" : 3.820694401702231E-4, + "90.0" : 3.9159490862441854E-4, + "95.0" : 3.9159490862441854E-4, + "99.0" : 3.9159490862441854E-4, + "99.9" : 3.9159490862441854E-4, + "99.99" : 3.9159490862441854E-4, + "99.999" : 3.9159490862441854E-4, + "99.9999" : 3.9159490862441854E-4, + "100.0" : 3.9159490862441854E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7332782283147934E-4, + 3.7275582259353637E-4, + 3.7240742095874285E-4 + ], + [ + 3.9159490862441854E-4, + 3.9103709038675825E-4, + 3.9081105750896685E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12793495400057106, + "scoreError" : 0.005903153005339292, + "scoreConfidence" : [ + 0.12203180099523177, + 0.13383810700591034 + ], + "scorePercentiles" : { + "0.0" : 0.1258542628810189, + "50.0" : 0.12795132062774078, + "90.0" : 0.12999869358864363, + "95.0" : 0.12999869358864363, + "99.0" : 0.12999869358864363, + "99.9" : 0.12999869358864363, + "99.99" : 0.12999869358864363, + "99.999" : 0.12999869358864363, + "99.9999" : 0.12999869358864363, + "100.0" : 0.12999869358864363 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1298626153676337, + 0.12999869358864363, + 0.129694305877623 + ], + [ + 0.12620833537785855, + 0.1258542628810189, + 0.12599151091064859 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012827324761851227, + "scoreError" : 5.921921710726301E-4, + "scoreConfidence" : [ + 0.012235132590778597, + 0.013419516932923857 + ], + "scorePercentiles" : { + "0.0" : 0.012630132576379504, + "50.0" : 0.012824285422540403, + "90.0" : 0.013033911165997602, + "95.0" : 0.013033911165997602, + "99.0" : 0.013033911165997602, + "99.9" : 0.013033911165997602, + "99.99" : 0.013033911165997602, + "99.999" : 0.013033911165997602, + "99.9999" : 0.013033911165997602, + "100.0" : 0.013033911165997602 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01263935978922915, + 0.01263460896894074, + 0.012630132576379504 + ], + [ + 0.013009211055851656, + 0.013016725014708715, + 0.013033911165997602 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0329025282873017, + "scoreError" : 0.11404561656718837, + "scoreConfidence" : [ + 0.9188569117201133, + 1.14694814485449 + ], + "scorePercentiles" : { + "0.0" : 0.9949510858621032, + "50.0" : 1.0324422948250203, + "90.0" : 1.073087094527897, + "95.0" : 1.073087094527897, + "99.0" : 1.073087094527897, + "99.9" : 1.073087094527897, + "99.99" : 1.073087094527897, + "99.999" : 1.073087094527897, + "99.9999" : 1.073087094527897, + "100.0" : 1.073087094527897 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.06913593884969, + 1.073087094527897, + 1.0677413523382446 + ], + [ + 0.9971432373117958, + 0.9949510858621032, + 0.9953564608340798 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011002983045993883, + "scoreError" : 4.693119569182763E-4, + "scoreConfidence" : [ + 0.010533671089075608, + 0.011472295002912159 + ], + "scorePercentiles" : { + "0.0" : 0.010840400550677507, + "50.0" : 0.0110005442616239, + "90.0" : 0.011161152678384086, + "95.0" : 0.011161152678384086, + "99.0" : 0.011161152678384086, + "99.9" : 0.011161152678384086, + "99.99" : 0.011161152678384086, + "99.999" : 0.011161152678384086, + "99.9999" : 0.011161152678384086, + "100.0" : 0.011161152678384086 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011145391949213934, + 0.011161152678384086, + 0.011160241073142424 + ], + [ + 0.010855015450511471, + 0.010840400550677507, + 0.010855696574033869 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3181149783541666, + "scoreError" : 0.2516155743197692, + "scoreConfidence" : [ + 3.0664994040343974, + 3.569730552673936 + ], + "scorePercentiles" : { + "0.0" : 3.2335043639301873, + "50.0" : 3.3187364709667073, + "90.0" : 3.406899996596324, + "95.0" : 3.406899996596324, + "99.0" : 3.406899996596324, + "99.9" : 3.406899996596324, + "99.99" : 3.406899996596324, + "99.999" : 3.406899996596324, + "99.9999" : 3.406899996596324, + "100.0" : 3.406899996596324 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.406899996596324, + 3.3965266510522745, + 3.3963181771894093 + ], + [ + 3.2335043639301873, + 3.2411547647440053, + 3.234285916612799 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.881322080291804, + "scoreError" : 0.1835931396267798, + "scoreConfidence" : [ + 2.697728940665024, + 3.064915219918584 + ], + "scorePercentiles" : { + "0.0" : 2.818735461104848, + "50.0" : 2.881099468845196, + "90.0" : 2.9456323422680413, + "95.0" : 2.9456323422680413, + "99.0" : 2.9456323422680413, + "99.9" : 2.9456323422680413, + "99.99" : 2.9456323422680413, + "99.999" : 2.9456323422680413, + "99.9999" : 2.9456323422680413, + "100.0" : 2.9456323422680413 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9347947799295775, + 2.9456323422680413, + 2.942376180935569 + ], + [ + 2.818735461104848, + 2.827404157760814, + 2.818989559751973 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17904732672856902, + "scoreError" : 0.004497225572885277, + "scoreConfidence" : [ + 0.17455010115568373, + 0.1835445523014543 + ], + "scorePercentiles" : { + "0.0" : 0.17746791201419698, + "50.0" : 0.1786121480766729, + "90.0" : 0.1812736734582895, + "95.0" : 0.1812736734582895, + "99.0" : 0.1812736734582895, + "99.9" : 0.1812736734582895, + "99.99" : 0.1812736734582895, + "99.999" : 0.1812736734582895, + "99.9999" : 0.1812736734582895, + "100.0" : 0.1812736734582895 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1812736734582895, + 0.17926846310770114, + 0.18059843925739982 + ], + [ + 0.17771963948818198, + 0.17795583304564463, + 0.17746791201419698 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3305803018138836, + "scoreError" : 0.01763758958924229, + "scoreConfidence" : [ + 0.3129427122246413, + 0.34821789140312587 + ], + "scorePercentiles" : { + "0.0" : 0.32463925681729644, + "50.0" : 0.3305187612350788, + "90.0" : 0.3366173438131143, + "95.0" : 0.3366173438131143, + "99.0" : 0.3366173438131143, + "99.9" : 0.3366173438131143, + "99.99" : 0.3366173438131143, + "99.999" : 0.3366173438131143, + "99.9999" : 0.3366173438131143, + "100.0" : 0.3366173438131143 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3250161059182944, + 0.32463925681729644, + 0.32487127772724317 + ], + [ + 0.3363164100554902, + 0.3360214165518632, + 0.3366173438131143 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14281373981692372, + "scoreError" : 0.006608722763422632, + "scoreConfidence" : [ + 0.13620501705350108, + 0.14942246258034636 + ], + "scorePercentiles" : { + "0.0" : 0.1406003855887522, + "50.0" : 0.14279134187358195, + "90.0" : 0.14507544514079296, + "95.0" : 0.14507544514079296, + "99.0" : 0.14507544514079296, + "99.9" : 0.14507544514079296, + "99.99" : 0.14507544514079296, + "99.999" : 0.14507544514079296, + "99.9999" : 0.14507544514079296, + "100.0" : 0.14507544514079296 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14507544514079296, + 0.14482979243424865, + 0.14498511217270277 + ], + [ + 0.1407528913129152, + 0.1406003855887522, + 0.14063881225213062 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39974282188467364, + "scoreError" : 0.009756078694397848, + "scoreConfidence" : [ + 0.38998674319027576, + 0.4094989005790715 + ], + "scorePercentiles" : { + "0.0" : 0.39739409974170475, + "50.0" : 0.3985827173317513, + "90.0" : 0.40667370359074456, + "95.0" : 0.40667370359074456, + "99.0" : 0.40667370359074456, + "99.9" : 0.40667370359074456, + "99.99" : 0.40667370359074456, + "99.999" : 0.40667370359074456, + "99.9999" : 0.40667370359074456, + "100.0" : 0.40667370359074456 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40667370359074456, + 0.39931313999361123, + 0.399188502953856 + ], + [ + 0.39739409974170475, + 0.3979769317096466, + 0.3979105533184784 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15677058408348474, + "scoreError" : 8.390759070516399E-4, + "scoreConfidence" : [ + 0.1559315081764331, + 0.1576096599905364 + ], + "scorePercentiles" : { + "0.0" : 0.15642070479572046, + "50.0" : 0.15670050516204867, + "90.0" : 0.15724425567243738, + "95.0" : 0.15724425567243738, + "99.0" : 0.15724425567243738, + "99.9" : 0.15724425567243738, + "99.99" : 0.15724425567243738, + "99.999" : 0.15724425567243738, + "99.9999" : 0.15724425567243738, + "100.0" : 0.15724425567243738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15724425567243738, + 0.1566387478971853, + 0.1565746756485932 + ], + [ + 0.15676226242691205, + 0.15642070479572046, + 0.15698285806005996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0480776971696018, + "scoreError" : 0.0010786891038840646, + "scoreConfidence" : [ + 0.04699900806571774, + 0.04915638627348586 + ], + "scorePercentiles" : { + "0.0" : 0.04737427092492231, + "50.0" : 0.048219409502382106, + "90.0" : 0.0483855027990536, + "95.0" : 0.0483855027990536, + "99.0" : 0.0483855027990536, + "99.9" : 0.0483855027990536, + "99.99" : 0.0483855027990536, + "99.999" : 0.0483855027990536, + "99.9999" : 0.0483855027990536, + "100.0" : 0.0483855027990536 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0483855027990536, + 0.048353952826721856, + 0.048160637607035185 + ], + [ + 0.04827818139772903, + 0.0479136374621488, + 0.04737427092492231 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9169404.804392328, + "scoreError" : 1012465.4981652143, + "scoreConfidence" : [ + 8156939.306227114, + 1.0181870302557543E7 + ], + "scorePercentiles" : { + "0.0" : 8781089.880701754, + "50.0" : 9227210.741988193, + "90.0" : 9496339.839658445, + "95.0" : 9496339.839658445, + "99.0" : 9496339.839658445, + "99.9" : 9496339.839658445, + "99.99" : 9496339.839658445, + "99.999" : 9496339.839658445, + "99.9999" : 9496339.839658445, + "100.0" : 9496339.839658445 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8962382.046594983, + 8791784.67135325, + 8781089.880701754 + ], + [ + 9496339.839658445, + 9492792.950664137, + 9492039.437381404 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-05T08:40:24Z-fa22b821dd44aa991c3746f36b49661aa97db913-jdk17.json b/performance-results/2025-06-05T08:40:24Z-fa22b821dd44aa991c3746f36b49661aa97db913-jdk17.json new file mode 100644 index 0000000000..ffb4c0b41f --- /dev/null +++ b/performance-results/2025-06-05T08:40:24Z-fa22b821dd44aa991c3746f36b49661aa97db913-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.323303541062623, + "scoreError" : 0.04784951378278793, + "scoreConfidence" : [ + 3.2754540272798347, + 3.371153054845411 + ], + "scorePercentiles" : { + "0.0" : 3.3159772105007193, + "50.0" : 3.3230378246394165, + "90.0" : 3.3311613044709394, + "95.0" : 3.3311613044709394, + "99.0" : 3.3311613044709394, + "99.9" : 3.3311613044709394, + "99.99" : 3.3311613044709394, + "99.999" : 3.3311613044709394, + "99.9999" : 3.3311613044709394, + "100.0" : 3.3311613044709394 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3180915700790323, + 3.3279840791998003 + ], + [ + 3.3159772105007193, + 3.3311613044709394 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6803825942852157, + "scoreError" : 0.010372906680830163, + "scoreConfidence" : [ + 1.6700096876043855, + 1.690755500966046 + ], + "scorePercentiles" : { + "0.0" : 1.6789057952699855, + "50.0" : 1.6803956196189893, + "90.0" : 1.6818333426328989, + "95.0" : 1.6818333426328989, + "99.0" : 1.6818333426328989, + "99.9" : 1.6818333426328989, + "99.99" : 1.6818333426328989, + "99.999" : 1.6818333426328989, + "99.9999" : 1.6818333426328989, + "100.0" : 1.6818333426328989 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6790833245526493, + 1.6817079146853295 + ], + [ + 1.6789057952699855, + 1.6818333426328989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8454517793297212, + "scoreError" : 0.029177788222166153, + "scoreConfidence" : [ + 0.816273991107555, + 0.8746295675518873 + ], + "scorePercentiles" : { + "0.0" : 0.8392436471945683, + "50.0" : 0.8467668325477291, + "90.0" : 0.8490298050288578, + "95.0" : 0.8490298050288578, + "99.0" : 0.8490298050288578, + "99.9" : 0.8490298050288578, + "99.99" : 0.8490298050288578, + "99.999" : 0.8490298050288578, + "99.9999" : 0.8490298050288578, + "100.0" : 0.8490298050288578 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8449833296670461, + 0.848550335428412 + ], + [ + 0.8392436471945683, + 0.8490298050288578 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.18154154425366, + "scoreError" : 0.4876887572569573, + "scoreConfidence" : [ + 15.6938527869967, + 16.669230301510616 + ], + "scorePercentiles" : { + "0.0" : 15.996149452382825, + "50.0" : 16.193279965398506, + "90.0" : 16.343634615329844, + "95.0" : 16.343634615329844, + "99.0" : 16.343634615329844, + "99.9" : 16.343634615329844, + "99.99" : 16.343634615329844, + "99.999" : 16.343634615329844, + "99.9999" : 16.343634615329844, + "100.0" : 16.343634615329844 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.343634615329844, + 16.332619418664482, + 16.341890046639865 + ], + [ + 16.021015220372423, + 16.05394051213253, + 15.996149452382825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2655.826396014289, + "scoreError" : 177.34839923387736, + "scoreConfidence" : [ + 2478.4779967804116, + 2833.1747952481664 + ], + "scorePercentiles" : { + "0.0" : 2597.0197297809823, + "50.0" : 2655.273185437959, + "90.0" : 2715.160658768505, + "95.0" : 2715.160658768505, + "99.0" : 2715.160658768505, + "99.9" : 2715.160658768505, + "99.99" : 2715.160658768505, + "99.999" : 2715.160658768505, + "99.9999" : 2715.160658768505, + "100.0" : 2715.160658768505 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2714.1519215725325, + 2711.3230373626725, + 2715.160658768505 + ], + [ + 2597.0197297809823, + 2599.223333513246, + 2598.0796950877966 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76369.51630663862, + "scoreError" : 3185.3504945248087, + "scoreConfidence" : [ + 73184.1658121138, + 79554.86680116343 + ], + "scorePercentiles" : { + "0.0" : 75303.62208568261, + "50.0" : 76377.87393196806, + "90.0" : 77418.3657705047, + "95.0" : 77418.3657705047, + "99.0" : 77418.3657705047, + "99.9" : 77418.3657705047, + "99.99" : 77418.3657705047, + "99.999" : 77418.3657705047, + "99.9999" : 77418.3657705047, + "100.0" : 77418.3657705047 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75338.30044503884, + 75303.62208568261, + 75356.15977841077 + ], + [ + 77399.58808552533, + 77418.3657705047, + 77401.06167466943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.82147509309766, + "scoreError" : 14.901992740186317, + "scoreConfidence" : [ + 342.91948235291136, + 372.72346783328396 + ], + "scorePercentiles" : { + "0.0" : 351.6833825733217, + "50.0" : 358.0103417265581, + "90.0" : 363.0555009770507, + "95.0" : 363.0555009770507, + "99.0" : 363.0555009770507, + "99.9" : 363.0555009770507, + "99.99" : 363.0555009770507, + "99.999" : 363.0555009770507, + "99.9999" : 363.0555009770507, + "100.0" : 363.0555009770507 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.6833825733217, + 353.63924311592825, + 353.7442487744116 + ], + [ + 362.2764346787047, + 363.0555009770507, + 362.5300404391692 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.86327790473626, + "scoreError" : 11.811822184389225, + "scoreConfidence" : [ + 102.05145572034704, + 125.6751000891255 + ], + "scorePercentiles" : { + "0.0" : 108.74637929180025, + "50.0" : 114.37264820715622, + "90.0" : 118.07686482202945, + "95.0" : 118.07686482202945, + "99.0" : 118.07686482202945, + "99.9" : 118.07686482202945, + "99.99" : 118.07686482202945, + "99.999" : 118.07686482202945, + "99.9999" : 118.07686482202945, + "100.0" : 118.07686482202945 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.74637929180025, + 109.88723944321818, + 111.77029569149941 + ], + [ + 116.97500072281302, + 117.72388745705729, + 118.07686482202945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061061494890769084, + "scoreError" : 9.799797262308853E-4, + "scoreConfidence" : [ + 0.0600815151645382, + 0.06204147461699997 + ], + "scorePercentiles" : { + "0.0" : 0.06063107086470952, + "50.0" : 0.061066911992722746, + "90.0" : 0.06145504228658518, + "95.0" : 0.06145504228658518, + "99.0" : 0.06145504228658518, + "99.9" : 0.06145504228658518, + "99.99" : 0.06145504228658518, + "99.999" : 0.06145504228658518, + "99.9999" : 0.06145504228658518, + "100.0" : 0.06145504228658518 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06145504228658518, + 0.061320686987981356, + 0.06134031814975433 + ], + [ + 0.06063107086470952, + 0.060808714058119946, + 0.060813136997464136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5882177092025737E-4, + "scoreError" : 1.2259069440694305E-5, + "scoreConfidence" : [ + 3.4656270147956304E-4, + 3.710808403609517E-4 + ], + "scorePercentiles" : { + "0.0" : 3.547846618292102E-4, + "50.0" : 3.587636434204854E-4, + "90.0" : 3.6314266514681474E-4, + "95.0" : 3.6314266514681474E-4, + "99.0" : 3.6314266514681474E-4, + "99.9" : 3.6314266514681474E-4, + "99.99" : 3.6314266514681474E-4, + "99.999" : 3.6314266514681474E-4, + "99.9999" : 3.6314266514681474E-4, + "100.0" : 3.6314266514681474E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6314266514681474E-4, + 3.626083114667236E-4, + 3.626754409789806E-4 + ], + [ + 3.548005707255676E-4, + 3.547846618292102E-4, + 3.549189753742472E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12340197858834524, + "scoreError" : 0.001002323575216014, + "scoreConfidence" : [ + 0.12239965501312923, + 0.12440430216356126 + ], + "scorePercentiles" : { + "0.0" : 0.12293044180557604, + "50.0" : 0.1234042305649592, + "90.0" : 0.12389656478430013, + "95.0" : 0.12389656478430013, + "99.0" : 0.12389656478430013, + "99.9" : 0.12389656478430013, + "99.99" : 0.12389656478430013, + "99.999" : 0.12389656478430013, + "99.9999" : 0.12389656478430013, + "100.0" : 0.12389656478430013 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12342505851424904, + 0.12389656478430013, + 0.1236802555809783 + ], + [ + 0.12338340261566934, + 0.12309614822929874, + 0.12293044180557604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012832217076013092, + "scoreError" : 9.581721888366957E-5, + "scoreConfidence" : [ + 0.012736399857129422, + 0.012928034294896761 + ], + "scorePercentiles" : { + "0.0" : 0.012790897798203157, + "50.0" : 0.012833786044344308, + "90.0" : 0.012870691539323862, + "95.0" : 0.012870691539323862, + "99.0" : 0.012870691539323862, + "99.9" : 0.012870691539323862, + "99.99" : 0.012870691539323862, + "99.999" : 0.012870691539323862, + "99.9999" : 0.012870691539323862, + "100.0" : 0.012870691539323862 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012812670975082256, + 0.012802460597099, + 0.012790897798203157 + ], + [ + 0.012854901113606359, + 0.012870691539323862, + 0.012861680432763912 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0254152102121374, + "scoreError" : 0.12231853119959481, + "scoreConfidence" : [ + 0.9030966790125426, + 1.1477337414117323 + ], + "scorePercentiles" : { + "0.0" : 0.9848525858774867, + "50.0" : 1.025284698354441, + "90.0" : 1.0663285682908625, + "95.0" : 1.0663285682908625, + "99.0" : 1.0663285682908625, + "99.9" : 1.0663285682908625, + "99.99" : 1.0663285682908625, + "99.999" : 1.0663285682908625, + "99.9999" : 1.0663285682908625, + "100.0" : 1.0663285682908625 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.986467190175577, + 0.9854915258178951, + 0.9848525858774867 + ], + [ + 1.0663285682908625, + 1.0652491845776972, + 1.064102206533305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011010103944000189, + "scoreError" : 2.0142751264376913E-4, + "scoreConfidence" : [ + 0.010808676431356419, + 0.011211531456643959 + ], + "scorePercentiles" : { + "0.0" : 0.010938657639584692, + "50.0" : 0.011010386150836736, + "90.0" : 0.011081204604787844, + "95.0" : 0.011081204604787844, + "99.0" : 0.011081204604787844, + "99.9" : 0.011081204604787844, + "99.99" : 0.011081204604787844, + "99.999" : 0.011081204604787844, + "99.9999" : 0.011081204604787844, + "100.0" : 0.011081204604787844 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011070807794071085, + 0.011074557880911459, + 0.011081204604787844 + ], + [ + 0.01094543123704367, + 0.010938657639584692, + 0.010949964507602385 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3788180381553885, + "scoreError" : 0.5232751358365683, + "scoreConfidence" : [ + 2.8555429023188204, + 3.9020931739919567 + ], + "scorePercentiles" : { + "0.0" : 3.2042892459961565, + "50.0" : 3.3762090318307703, + "90.0" : 3.559737034163701, + "95.0" : 3.559737034163701, + "99.0" : 3.559737034163701, + "99.9" : 3.559737034163701, + "99.99" : 3.559737034163701, + "99.999" : 3.559737034163701, + "99.9999" : 3.559737034163701, + "100.0" : 3.559737034163701 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.209370641848524, + 3.2042892459961565, + 3.212086389210019 + ], + [ + 3.559737034163701, + 3.5403316744515214, + 3.5470932432624114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.78863590640011, + "scoreError" : 0.16727359202285144, + "scoreConfidence" : [ + 2.6213623143772584, + 2.9559094984229612 + ], + "scorePercentiles" : { + "0.0" : 2.728995936425648, + "50.0" : 2.79033693146956, + "90.0" : 2.845823271200911, + "95.0" : 2.845823271200911, + "99.0" : 2.845823271200911, + "99.9" : 2.845823271200911, + "99.99" : 2.845823271200911, + "99.999" : 2.845823271200911, + "99.9999" : 2.845823271200911, + "100.0" : 2.845823271200911 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.843148814951677, + 2.845823271200911, + 2.8398878886996024 + ], + [ + 2.7331735528833017, + 2.728995936425648, + 2.7407859742395178 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18127349255683864, + "scoreError" : 0.005453197264984373, + "scoreConfidence" : [ + 0.17582029529185428, + 0.186726689821823 + ], + "scorePercentiles" : { + "0.0" : 0.17978007473258428, + "50.0" : 0.18056594887905647, + "90.0" : 0.1848200959931988, + "95.0" : 0.1848200959931988, + "99.0" : 0.1848200959931988, + "99.9" : 0.1848200959931988, + "99.99" : 0.1848200959931988, + "99.999" : 0.1848200959931988, + "99.9999" : 0.1848200959931988, + "100.0" : 0.1848200959931988 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18010049245398552, + 0.17978007473258428, + 0.17984499498246562 + ], + [ + 0.1848200959931988, + 0.18206389187467, + 0.18103140530412745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31766891096410366, + "scoreError" : 0.016605056666604986, + "scoreConfidence" : [ + 0.30106385429749866, + 0.33427396763070866 + ], + "scorePercentiles" : { + "0.0" : 0.3120143881314156, + "50.0" : 0.31761500724974473, + "90.0" : 0.3234757575287078, + "95.0" : 0.3234757575287078, + "99.0" : 0.3234757575287078, + "99.9" : 0.3234757575287078, + "99.99" : 0.3234757575287078, + "99.999" : 0.3234757575287078, + "99.9999" : 0.3234757575287078, + "100.0" : 0.3234757575287078 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3120143881314156, + 0.31245948411185753, + 0.3123332994565557 + ], + [ + 0.3234757575287078, + 0.3227705303876319, + 0.32296000616845366 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1432583922352052, + "scoreError" : 0.0027195257904943054, + "scoreConfidence" : [ + 0.1405388664447109, + 0.1459779180256995 + ], + "scorePercentiles" : { + "0.0" : 0.14227658420476047, + "50.0" : 0.14331239219448794, + "90.0" : 0.14423656390988288, + "95.0" : 0.14423656390988288, + "99.0" : 0.14423656390988288, + "99.9" : 0.14423656390988288, + "99.99" : 0.14423656390988288, + "99.999" : 0.14423656390988288, + "99.9999" : 0.14423656390988288, + "100.0" : 0.14423656390988288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14254842202044105, + 0.14227658420476047, + 0.14231086056638678 + ], + [ + 0.14410156034122512, + 0.1440763623685348, + 0.14423656390988288 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3954007548563778, + "scoreError" : 0.009612892665008213, + "scoreConfidence" : [ + 0.3857878621913696, + 0.405013647521386 + ], + "scorePercentiles" : { + "0.0" : 0.3920099395923167, + "50.0" : 0.3951932186072826, + "90.0" : 0.3991148948754789, + "95.0" : 0.3991148948754789, + "99.0" : 0.3991148948754789, + "99.9" : 0.3991148948754789, + "99.99" : 0.3991148948754789, + "99.999" : 0.3991148948754789, + "99.9999" : 0.3991148948754789, + "100.0" : 0.3991148948754789 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3920099395923167, + 0.39239127658322215, + 0.3924817181711146 + ], + [ + 0.3985019808726838, + 0.3991148948754789, + 0.3979047190434506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15457273773458435, + "scoreError" : 0.004487606358980273, + "scoreConfidence" : [ + 0.1500851313756041, + 0.15906034409356462 + ], + "scorePercentiles" : { + "0.0" : 0.15162810465186802, + "50.0" : 0.15528336667650727, + "90.0" : 0.155838691257597, + "95.0" : 0.155838691257597, + "99.0" : 0.155838691257597, + "99.9" : 0.155838691257597, + "99.99" : 0.155838691257597, + "99.999" : 0.155838691257597, + "99.9999" : 0.155838691257597, + "100.0" : 0.155838691257597 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15556203618262426, + 0.15384086096240232, + 0.15162810465186802 + ], + [ + 0.15522280799379123, + 0.155838691257597, + 0.1553439253592233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04791317225830927, + "scoreError" : 0.0014018961247334808, + "scoreConfidence" : [ + 0.04651127613357579, + 0.04931506838304275 + ], + "scorePercentiles" : { + "0.0" : 0.047294115943948126, + "50.0" : 0.04800083165145018, + "90.0" : 0.04862845883663029, + "95.0" : 0.04862845883663029, + "99.0" : 0.04862845883663029, + "99.9" : 0.04862845883663029, + "99.99" : 0.04862845883663029, + "99.999" : 0.04862845883663029, + "99.9999" : 0.04862845883663029, + "100.0" : 0.04862845883663029 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04862845883663029, + 0.048058310712552205, + 0.04794335259034816 + ], + [ + 0.04816206464228093, + 0.047294115943948126, + 0.04739273082409588 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8674925.832979992, + "scoreError" : 259741.95199489142, + "scoreConfidence" : [ + 8415183.8809851, + 8934667.784974884 + ], + "scorePercentiles" : { + "0.0" : 8588854.972532189, + "50.0" : 8666197.591014167, + "90.0" : 8796064.36939314, + "95.0" : 8796064.36939314, + "99.0" : 8796064.36939314, + "99.9" : 8796064.36939314, + "99.99" : 8796064.36939314, + "99.999" : 8796064.36939314, + "99.9999" : 8796064.36939314, + "100.0" : 8796064.36939314 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8796064.36939314, + 8742092.52972028, + 8733147.452879582 + ], + [ + 8599247.729148753, + 8588854.972532189, + 8590147.944206009 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-05T10:10:46Z-9c358d367dc60598589a88ac1e6ef3b1260f16b8-jdk17.json b/performance-results/2025-06-05T10:10:46Z-9c358d367dc60598589a88ac1e6ef3b1260f16b8-jdk17.json new file mode 100644 index 0000000000..5d4919c314 --- /dev/null +++ b/performance-results/2025-06-05T10:10:46Z-9c358d367dc60598589a88ac1e6ef3b1260f16b8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3576612924458096, + "scoreError" : 0.021753557915125017, + "scoreConfidence" : [ + 3.3359077345306845, + 3.3794148503609347 + ], + "scorePercentiles" : { + "0.0" : 3.3540459133993603, + "50.0" : 3.357204654393395, + "90.0" : 3.3621899475970873, + "95.0" : 3.3621899475970873, + "99.0" : 3.3621899475970873, + "99.9" : 3.3621899475970873, + "99.99" : 3.3621899475970873, + "99.999" : 3.3621899475970873, + "99.9999" : 3.3621899475970873, + "100.0" : 3.3621899475970873 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3572266535483415, + 3.357182655238448 + ], + [ + 3.3540459133993603, + 3.3621899475970873 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7006866709964206, + "scoreError" : 0.02068371391057096, + "scoreConfidence" : [ + 1.6800029570858497, + 1.7213703849069915 + ], + "scorePercentiles" : { + "0.0" : 1.6967987488935095, + "50.0" : 1.7009901377436487, + "90.0" : 1.7039676596048754, + "95.0" : 1.7039676596048754, + "99.0" : 1.7039676596048754, + "99.9" : 1.7039676596048754, + "99.99" : 1.7039676596048754, + "99.999" : 1.7039676596048754, + "99.9999" : 1.7039676596048754, + "100.0" : 1.7039676596048754 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.699461922484166, + 1.7039676596048754 + ], + [ + 1.6967987488935095, + 1.7025183530031314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8516483565783783, + "scoreError" : 0.016101229051777344, + "scoreConfidence" : [ + 0.835547127526601, + 0.8677495856301557 + ], + "scorePercentiles" : { + "0.0" : 0.8494790285376405, + "50.0" : 0.8515494268236375, + "90.0" : 0.8540155441285977, + "95.0" : 0.8540155441285977, + "99.0" : 0.8540155441285977, + "99.9" : 0.8540155441285977, + "99.99" : 0.8540155441285977, + "99.999" : 0.8540155441285977, + "99.9999" : 0.8540155441285977, + "100.0" : 0.8540155441285977 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8495127239048758, + 0.8540155441285977 + ], + [ + 0.8494790285376405, + 0.8535861297423993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.562638218496232, + "scoreError" : 0.025391089586609263, + "scoreConfidence" : [ + 16.537247128909623, + 16.58802930808284 + ], + "scorePercentiles" : { + "0.0" : 16.546847860786983, + "50.0" : 16.562785285798185, + "90.0" : 16.57260199147099, + "95.0" : 16.57260199147099, + "99.0" : 16.57260199147099, + "99.9" : 16.57260199147099, + "99.99" : 16.57260199147099, + "99.999" : 16.57260199147099, + "99.9999" : 16.57260199147099, + "100.0" : 16.57260199147099 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.546847860786983, + 16.57260199147099, + 16.561563530683596 + ], + [ + 16.570040918928267, + 16.560767968194774, + 16.564007040912777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2765.908320493483, + "scoreError" : 111.38626898148688, + "scoreConfidence" : [ + 2654.5220515119963, + 2877.29458947497 + ], + "scorePercentiles" : { + "0.0" : 2728.452946640882, + "50.0" : 2765.6559885780007, + "90.0" : 2804.372783041907, + "95.0" : 2804.372783041907, + "99.0" : 2804.372783041907, + "99.9" : 2804.372783041907, + "99.99" : 2804.372783041907, + "99.999" : 2804.372783041907, + "99.9999" : 2804.372783041907, + "100.0" : 2804.372783041907 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2801.987170513875, + 2800.0535755298024, + 2804.372783041907 + ], + [ + 2729.325045608231, + 2731.258401626199, + 2728.452946640882 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77919.02116995126, + "scoreError" : 2262.0009898416997, + "scoreConfidence" : [ + 75657.02018010955, + 80181.02215979296 + ], + "scorePercentiles" : { + "0.0" : 77156.2772308574, + "50.0" : 77910.54648707797, + "90.0" : 78682.07805159144, + "95.0" : 78682.07805159144, + "99.0" : 78682.07805159144, + "99.9" : 78682.07805159144, + "99.99" : 78682.07805159144, + "99.999" : 78682.07805159144, + "99.9999" : 78682.07805159144, + "100.0" : 78682.07805159144 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78682.07805159144, + 78616.25589001142, + 78666.61750114738 + ], + [ + 77188.06126195536, + 77156.2772308574, + 77204.83708414451 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 364.64907863296025, + "scoreError" : 5.29246948189975, + "scoreConfidence" : [ + 359.3566091510605, + 369.94154811486 + ], + "scorePercentiles" : { + "0.0" : 362.46956542417394, + "50.0" : 364.77088490851816, + "90.0" : 366.52135151852195, + "95.0" : 366.52135151852195, + "99.0" : 366.52135151852195, + "99.9" : 366.52135151852195, + "99.99" : 366.52135151852195, + "99.999" : 366.52135151852195, + "99.9999" : 366.52135151852195, + "100.0" : 366.52135151852195 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.1674983869752, + 366.3574853861649, + 366.52135151852195 + ], + [ + 362.46956542417394, + 363.0042996518647, + 363.3742714300611 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.53510822932536, + "scoreError" : 6.621341450475171, + "scoreConfidence" : [ + 107.91376677885019, + 121.15644967980053 + ], + "scorePercentiles" : { + "0.0" : 111.96423207436787, + "50.0" : 114.51590385439837, + "90.0" : 117.01965949746193, + "95.0" : 117.01965949746193, + "99.0" : 117.01965949746193, + "99.9" : 117.01965949746193, + "99.99" : 117.01965949746193, + "99.999" : 117.01965949746193, + "99.9999" : 117.01965949746193, + "100.0" : 117.01965949746193 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.41270865217597, + 116.58373793258814, + 117.01965949746193 + ], + [ + 111.96423207436787, + 112.61909905662078, + 112.61121216273737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061193585134175894, + "scoreError" : 8.593602311481436E-4, + "scoreConfidence" : [ + 0.06033422490302775, + 0.06205294536532404 + ], + "scorePercentiles" : { + "0.0" : 0.06089888648612439, + "50.0" : 0.06117957348277493, + "90.0" : 0.061501597672802416, + "95.0" : 0.061501597672802416, + "99.0" : 0.061501597672802416, + "99.9" : 0.061501597672802416, + "99.99" : 0.061501597672802416, + "99.999" : 0.061501597672802416, + "99.9999" : 0.061501597672802416, + "100.0" : 0.061501597672802416 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06142937817815481, + 0.061501597672802416, + 0.06148602946981389 + ], + [ + 0.060915850210764844, + 0.06092976878739505, + 0.06089888648612439 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6406987535314556E-4, + "scoreError" : 4.1000923063178546E-5, + "scoreConfidence" : [ + 3.23068952289967E-4, + 4.050707984163241E-4 + ], + "scorePercentiles" : { + "0.0" : 3.505447480146687E-4, + "50.0" : 3.640375832678535E-4, + "90.0" : 3.7774011552205736E-4, + "95.0" : 3.7774011552205736E-4, + "99.0" : 3.7774011552205736E-4, + "99.9" : 3.7774011552205736E-4, + "99.99" : 3.7774011552205736E-4, + "99.999" : 3.7774011552205736E-4, + "99.9999" : 3.7774011552205736E-4, + "100.0" : 3.7774011552205736E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.771203952946018E-4, + 3.773859913654269E-4, + 3.7774011552205736E-4 + ], + [ + 3.506732306810138E-4, + 3.509547712411052E-4, + 3.505447480146687E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12203659209549732, + "scoreError" : 0.0025233851086143644, + "scoreConfidence" : [ + 0.11951320698688295, + 0.12455997720411169 + ], + "scorePercentiles" : { + "0.0" : 0.12117420249130588, + "50.0" : 0.12204650191068676, + "90.0" : 0.12288566790778835, + "95.0" : 0.12288566790778835, + "99.0" : 0.12288566790778835, + "99.9" : 0.12288566790778835, + "99.99" : 0.12288566790778835, + "99.999" : 0.12288566790778835, + "99.9999" : 0.12288566790778835, + "100.0" : 0.12288566790778835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12121104204695587, + 0.12117420249130588, + 0.12126178452248144 + ], + [ + 0.12288566790778835, + 0.12285563630556033, + 0.12283121929889208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012768508534902322, + "scoreError" : 1.0192026186285195E-4, + "scoreConfidence" : [ + 0.012666588273039469, + 0.012870428796765174 + ], + "scorePercentiles" : { + "0.0" : 0.012732495483256537, + "50.0" : 0.012770634060230934, + "90.0" : 0.012802965638558967, + "95.0" : 0.012802965638558967, + "99.0" : 0.012802965638558967, + "99.9" : 0.012802965638558967, + "99.99" : 0.012802965638558967, + "99.999" : 0.012802965638558967, + "99.9999" : 0.012802965638558967, + "100.0" : 0.012802965638558967 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01273297782834122, + 0.012740875102722055, + 0.012732495483256537 + ], + [ + 0.012800393017739815, + 0.012801344138795334, + 0.012802965638558967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9970706969896166, + "scoreError" : 0.01956761240766671, + "scoreConfidence" : [ + 0.9775030845819499, + 1.0166383093972833 + ], + "scorePercentiles" : { + "0.0" : 0.990227232894346, + "50.0" : 0.9967368204025804, + "90.0" : 1.0039164215017065, + "95.0" : 1.0039164215017065, + "99.0" : 1.0039164215017065, + "99.9" : 1.0039164215017065, + "99.99" : 1.0039164215017065, + "99.999" : 1.0039164215017065, + "99.9999" : 1.0039164215017065, + "100.0" : 1.0039164215017065 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.990227232894346, + 0.9910560289366762, + 0.9908927506192411 + ], + [ + 1.0039141361172454, + 1.0039164215017065, + 1.0024176118684844 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010718515281552434, + "scoreError" : 0.001243442240400771, + "scoreConfidence" : [ + 0.009475073041151662, + 0.011961957521953205 + ], + "scorePercentiles" : { + "0.0" : 0.010307293212809598, + "50.0" : 0.010719685368391728, + "90.0" : 0.011125491135398773, + "95.0" : 0.011125491135398773, + "99.0" : 0.011125491135398773, + "99.9" : 0.011125491135398773, + "99.99" : 0.011125491135398773, + "99.999" : 0.011125491135398773, + "99.9999" : 0.011125491135398773, + "100.0" : 0.011125491135398773 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010307293212809598, + 0.01031858877694635, + 0.010315347357063577 + ], + [ + 0.011125491135398773, + 0.0111235892472592, + 0.011120781959837107 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.070055183460948, + "scoreError" : 0.08136554834042345, + "scoreConfidence" : [ + 2.9886896351205245, + 3.151420731801372 + ], + "scorePercentiles" : { + "0.0" : 3.03781039854192, + "50.0" : 3.069473719279751, + "90.0" : 3.10023378983261, + "95.0" : 3.10023378983261, + "99.0" : 3.10023378983261, + "99.9" : 3.10023378983261, + "99.99" : 3.10023378983261, + "99.999" : 3.10023378983261, + "99.9999" : 3.10023378983261, + "100.0" : 3.10023378983261 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0965967789473683, + 3.10023378983261, + 3.0919513337453646 + ], + [ + 3.03781039854192, + 3.046996104814138, + 3.0467426948842875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6826081257481817, + "scoreError" : 0.08764445560548972, + "scoreConfidence" : [ + 2.594963670142692, + 2.7702525813536716 + ], + "scorePercentiles" : { + "0.0" : 2.6482670503044745, + "50.0" : 2.684230876499164, + "90.0" : 2.713629004069452, + "95.0" : 2.713629004069452, + "99.0" : 2.713629004069452, + "99.9" : 2.713629004069452, + "99.99" : 2.713629004069452, + "99.999" : 2.713629004069452, + "99.9999" : 2.713629004069452, + "100.0" : 2.713629004069452 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.660365699654163, + 2.6482670503044745, + 2.654375671974522 + ], + [ + 2.710915275142315, + 2.713629004069452, + 2.7080960533441645 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18224116251614567, + "scoreError" : 0.010187895284626708, + "scoreConfidence" : [ + 0.17205326723151895, + 0.19242905780077238 + ], + "scorePercentiles" : { + "0.0" : 0.17880543652553282, + "50.0" : 0.18223486526138216, + "90.0" : 0.18578910755025452, + "95.0" : 0.18578910755025452, + "99.0" : 0.18578910755025452, + "99.9" : 0.18578910755025452, + "99.99" : 0.18578910755025452, + "99.999" : 0.18578910755025452, + "99.9999" : 0.18578910755025452, + "100.0" : 0.18578910755025452 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18578910755025452, + 0.18533132048407125, + 0.18553977505658836 + ], + [ + 0.17884292544173402, + 0.17913841003869305, + 0.17880543652553282 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.314596113979403, + "scoreError" : 0.011400531090064723, + "scoreConfidence" : [ + 0.3031955828893383, + 0.32599664506946774 + ], + "scorePercentiles" : { + "0.0" : 0.30884754865808084, + "50.0" : 0.31516173638371325, + "90.0" : 0.3199233938191823, + "95.0" : 0.3199233938191823, + "99.0" : 0.3199233938191823, + "99.9" : 0.3199233938191823, + "99.99" : 0.3199233938191823, + "99.999" : 0.3199233938191823, + "99.9999" : 0.3199233938191823, + "100.0" : 0.3199233938191823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3162245512585378, + 0.30884754865808084, + 0.31409892150888874 + ], + [ + 0.3199233938191823, + 0.3172466377767908, + 0.3112356308549376 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14129161946283383, + "scoreError" : 0.003717121071394576, + "scoreConfidence" : [ + 0.13757449839143926, + 0.1450087405342284 + ], + "scorePercentiles" : { + "0.0" : 0.14001808822335168, + "50.0" : 0.14125736705007447, + "90.0" : 0.14256779541793194, + "95.0" : 0.14256779541793194, + "99.0" : 0.14256779541793194, + "99.9" : 0.14256779541793194, + "99.99" : 0.14256779541793194, + "99.999" : 0.14256779541793194, + "99.9999" : 0.14256779541793194, + "100.0" : 0.14256779541793194 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14256779541793194, + 0.1425408141739242, + 0.14239137337320235 + ], + [ + 0.14012336072694662, + 0.14001808822335168, + 0.14010828486164623 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39755571915728455, + "scoreError" : 0.011955348665881453, + "scoreConfidence" : [ + 0.3856003704914031, + 0.409511067823166 + ], + "scorePercentiles" : { + "0.0" : 0.3922925302840107, + "50.0" : 0.39907157998522547, + "90.0" : 0.4013064882619688, + "95.0" : 0.4013064882619688, + "99.0" : 0.4013064882619688, + "99.9" : 0.4013064882619688, + "99.99" : 0.4013064882619688, + "99.999" : 0.4013064882619688, + "99.9999" : 0.4013064882619688, + "100.0" : 0.4013064882619688 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40110979957484355, + 0.4008246898472885, + 0.4013064882619688 + ], + [ + 0.3973184701231625, + 0.3924823368524333, + 0.3922925302840107 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1636868781485565, + "scoreError" : 0.005189545134376114, + "scoreConfidence" : [ + 0.1584973330141804, + 0.16887642328293262 + ], + "scorePercentiles" : { + "0.0" : 0.16157942053643562, + "50.0" : 0.163977986407841, + "90.0" : 0.16566474602412035, + "95.0" : 0.16566474602412035, + "99.0" : 0.16566474602412035, + "99.9" : 0.16566474602412035, + "99.99" : 0.16566474602412035, + "99.999" : 0.16566474602412035, + "99.9999" : 0.16566474602412035, + "100.0" : 0.16566474602412035 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16566474602412035, + 0.16505563239638865, + 0.16290034041929335 + ], + [ + 0.1652179023592387, + 0.16170322715586244, + 0.16157942053643562 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04821899877841073, + "scoreError" : 5.210557666998475E-4, + "scoreConfidence" : [ + 0.04769794301171088, + 0.04874005454511058 + ], + "scorePercentiles" : { + "0.0" : 0.048077048860107115, + "50.0" : 0.04815326076810051, + "90.0" : 0.04857906723244257, + "95.0" : 0.04857906723244257, + "99.0" : 0.04857906723244257, + "99.9" : 0.04857906723244257, + "99.99" : 0.04857906723244257, + "99.999" : 0.04857906723244257, + "99.9999" : 0.04857906723244257, + "100.0" : 0.04857906723244257 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04824663094209996, + 0.04813967744979108, + 0.048077048860107115 + ], + [ + 0.04857906723244257, + 0.04810472409961373, + 0.04816684408640994 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8530017.971034542, + "scoreError" : 542943.2522141851, + "scoreConfidence" : [ + 7987074.718820357, + 9072961.223248728 + ], + "scorePercentiles" : { + "0.0" : 8342149.070058382, + "50.0" : 8524797.408754895, + "90.0" : 8766196.874671342, + "95.0" : 8766196.874671342, + "99.0" : 8766196.874671342, + "99.9" : 8766196.874671342, + "99.99" : 8766196.874671342, + "99.999" : 8766196.874671342, + "99.9999" : 8766196.874671342, + "100.0" : 8766196.874671342 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8343192.874895747, + 8384761.862531434, + 8342149.070058382 + ], + [ + 8766196.874671342, + 8664832.954978354, + 8678974.189071987 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-06T01:04:20Z-b96a9ea7c55ef11c8aa72b3f71f2348f3f234d9d-jdk17.json b/performance-results/2025-06-06T01:04:20Z-b96a9ea7c55ef11c8aa72b3f71f2348f3f234d9d-jdk17.json new file mode 100644 index 0000000000..24d03d625d --- /dev/null +++ b/performance-results/2025-06-06T01:04:20Z-b96a9ea7c55ef11c8aa72b3f71f2348f3f234d9d-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3466312091896038, + "scoreError" : 0.02325363858737208, + "scoreConfidence" : [ + 3.3233775706022315, + 3.369884847776976 + ], + "scorePercentiles" : { + "0.0" : 3.3433205374816457, + "50.0" : 3.346584927983306, + "90.0" : 3.3500344433101574, + "95.0" : 3.3500344433101574, + "99.0" : 3.3500344433101574, + "99.9" : 3.3500344433101574, + "99.99" : 3.3500344433101574, + "99.999" : 3.3500344433101574, + "99.9999" : 3.3500344433101574, + "100.0" : 3.3500344433101574 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3433205374816457, + 3.3494398659255946 + ], + [ + 3.343729990041018, + 3.3500344433101574 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.681302980958336, + "scoreError" : 0.020262622986746148, + "scoreConfidence" : [ + 1.6610403579715898, + 1.7015656039450822 + ], + "scorePercentiles" : { + "0.0" : 1.6768774779337476, + "50.0" : 1.6820306998510288, + "90.0" : 1.6842730461975384, + "95.0" : 1.6842730461975384, + "99.0" : 1.6842730461975384, + "99.9" : 1.6842730461975384, + "99.99" : 1.6842730461975384, + "99.999" : 1.6842730461975384, + "99.9999" : 1.6842730461975384, + "100.0" : 1.6842730461975384 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6768774779337476, + 1.681904923141496 + ], + [ + 1.6821564765605617, + 1.6842730461975384 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.851427308039495, + "scoreError" : 0.015419533182996402, + "scoreConfidence" : [ + 0.8360077748564986, + 0.8668468412224913 + ], + "scorePercentiles" : { + "0.0" : 0.8490141431345646, + "50.0" : 0.8514160749862232, + "90.0" : 0.8538629390509689, + "95.0" : 0.8538629390509689, + "99.0" : 0.8538629390509689, + "99.9" : 0.8538629390509689, + "99.99" : 0.8538629390509689, + "99.999" : 0.8538629390509689, + "99.9999" : 0.8538629390509689, + "100.0" : 0.8538629390509689 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8497842370581803, + 0.8538629390509689 + ], + [ + 0.8490141431345646, + 0.8530479129142661 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.417855075772422, + "scoreError" : 0.1959738179567229, + "scoreConfidence" : [ + 16.2218812578157, + 16.613828893729146 + ], + "scorePercentiles" : { + "0.0" : 16.338509927728595, + "50.0" : 16.418416977981718, + "90.0" : 16.49057064089824, + "95.0" : 16.49057064089824, + "99.0" : 16.49057064089824, + "99.9" : 16.49057064089824, + "99.99" : 16.49057064089824, + "99.999" : 16.49057064089824, + "99.9999" : 16.49057064089824, + "100.0" : 16.49057064089824 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.368945991606786, + 16.338509927728595, + 16.357653141749143 + ], + [ + 16.48356278829511, + 16.46788796435665, + 16.49057064089824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2793.858268612083, + "scoreError" : 104.14067876254514, + "scoreConfidence" : [ + 2689.717589849538, + 2897.998947374628 + ], + "scorePercentiles" : { + "0.0" : 2757.431112427251, + "50.0" : 2794.4432551862537, + "90.0" : 2828.669220889821, + "95.0" : 2828.669220889821, + "99.0" : 2828.669220889821, + "99.9" : 2828.669220889821, + "99.99" : 2828.669220889821, + "99.999" : 2828.669220889821, + "99.9999" : 2828.669220889821, + "100.0" : 2828.669220889821 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2760.0606472069103, + 2757.431112427251, + 2762.4929023097466 + ], + [ + 2828.102120776009, + 2826.393608062761, + 2828.669220889821 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76573.32681249721, + "scoreError" : 140.0676958431153, + "scoreConfidence" : [ + 76433.2591166541, + 76713.39450834032 + ], + "scorePercentiles" : { + "0.0" : 76525.1390095577, + "50.0" : 76567.94055104232, + "90.0" : 76661.03154981975, + "95.0" : 76661.03154981975, + "99.0" : 76661.03154981975, + "99.9" : 76661.03154981975, + "99.99" : 76661.03154981975, + "99.999" : 76661.03154981975, + "99.9999" : 76661.03154981975, + "100.0" : 76661.03154981975 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76588.08277240224, + 76661.03154981975, + 76529.8264411189 + ], + [ + 76525.1390095577, + 76555.8465860446, + 76580.03451604005 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 351.16476239814307, + "scoreError" : 2.93797727784493, + "scoreConfidence" : [ + 348.22678512029813, + 354.102739675988 + ], + "scorePercentiles" : { + "0.0" : 349.55208053447325, + "50.0" : 351.21582346515845, + "90.0" : 352.50954287871144, + "95.0" : 352.50954287871144, + "99.0" : 352.50954287871144, + "99.9" : 352.50954287871144, + "99.99" : 352.50954287871144, + "99.999" : 352.50954287871144, + "99.9999" : 352.50954287871144, + "100.0" : 352.50954287871144 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 352.50954287871144, + 350.6647853305287, + 351.6522242826524 + ], + [ + 349.55208053447325, + 351.83051871482854, + 350.77942264766455 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.53599302908223, + "scoreError" : 1.0593264794417006, + "scoreConfidence" : [ + 115.47666654964054, + 117.59531950852393 + ], + "scorePercentiles" : { + "0.0" : 116.0898386215985, + "50.0" : 116.50513092656439, + "90.0" : 117.12753593430179, + "95.0" : 117.12753593430179, + "99.0" : 117.12753593430179, + "99.9" : 117.12753593430179, + "99.99" : 117.12753593430179, + "99.999" : 117.12753593430179, + "99.9999" : 117.12753593430179, + "100.0" : 117.12753593430179 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.719967709325, + 116.67421204727998, + 117.12753593430179 + ], + [ + 116.0898386215985, + 116.33604980584882, + 116.26835405613933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06159391448048709, + "scoreError" : 8.615057153433739E-4, + "scoreConfidence" : [ + 0.060732408765143714, + 0.06245542019583046 + ], + "scorePercentiles" : { + "0.0" : 0.061182862646607154, + "50.0" : 0.061616163128566014, + "90.0" : 0.0618983784484733, + "95.0" : 0.0618983784484733, + "99.0" : 0.0618983784484733, + "99.9" : 0.0618983784484733, + "99.99" : 0.0618983784484733, + "99.999" : 0.0618983784484733, + "99.9999" : 0.0618983784484733, + "100.0" : 0.0618983784484733 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061182862646607154, + 0.06140608510742817, + 0.061380952234225385 + ], + [ + 0.06182624114970386, + 0.06186896729648465, + 0.0618983784484733 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.698584289572545E-4, + "scoreError" : 1.1954735914294045E-5, + "scoreConfidence" : [ + 3.579036930429605E-4, + 3.8181316487154854E-4 + ], + "scorePercentiles" : { + "0.0" : 3.657335809070759E-4, + "50.0" : 3.697422832276202E-4, + "90.0" : 3.742179012609938E-4, + "95.0" : 3.742179012609938E-4, + "99.0" : 3.742179012609938E-4, + "99.9" : 3.742179012609938E-4, + "99.99" : 3.742179012609938E-4, + "99.999" : 3.742179012609938E-4, + "99.9999" : 3.742179012609938E-4, + "100.0" : 3.742179012609938E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.742179012609938E-4, + 3.733859061265959E-4, + 3.7361724487490575E-4 + ], + [ + 3.6609728024531113E-4, + 3.657335809070759E-4, + 3.6609866032864444E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12435993343202244, + "scoreError" : 0.0027096101417100277, + "scoreConfidence" : [ + 0.1216503232903124, + 0.12706954357373246 + ], + "scorePercentiles" : { + "0.0" : 0.12326425689034612, + "50.0" : 0.12451499031533848, + "90.0" : 0.1253072608417808, + "95.0" : 0.1253072608417808, + "99.0" : 0.1253072608417808, + "99.9" : 0.1253072608417808, + "99.99" : 0.1253072608417808, + "99.999" : 0.1253072608417808, + "99.9999" : 0.1253072608417808, + "100.0" : 0.1253072608417808 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12397420041158386, + 0.12329813180282594, + 0.12326425689034612 + ], + [ + 0.1253072608417808, + 0.12525997042650466, + 0.1250557802190931 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012959620700319223, + "scoreError" : 3.3376210635461574E-4, + "scoreConfidence" : [ + 0.012625858593964607, + 0.013293382806673838 + ], + "scorePercentiles" : { + "0.0" : 0.012841967672134262, + "50.0" : 0.01295822928992828, + "90.0" : 0.013079059918309266, + "95.0" : 0.013079059918309266, + "99.0" : 0.013079059918309266, + "99.9" : 0.013079059918309266, + "99.99" : 0.013079059918309266, + "99.999" : 0.013079059918309266, + "99.9999" : 0.013079059918309266, + "100.0" : 0.013079059918309266 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013060326159383665, + 0.013079059918309266, + 0.013064694924820134 + ], + [ + 0.012856132420472894, + 0.012855543106795118, + 0.012841967672134262 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0182778966801935, + "scoreError" : 0.060600327826022204, + "scoreConfidence" : [ + 0.9576775688541713, + 1.0788782245062158 + ], + "scorePercentiles" : { + "0.0" : 0.9963874177543091, + "50.0" : 1.017808907528047, + "90.0" : 1.0405659978150037, + "95.0" : 1.0405659978150037, + "99.0" : 1.0405659978150037, + "99.9" : 1.0405659978150037, + "99.99" : 1.0405659978150037, + "99.999" : 1.0405659978150037, + "99.9999" : 1.0405659978150037, + "100.0" : 1.0405659978150037 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0358437097876747, + 1.0405659978150037, + 1.0373637154859454 + ], + [ + 0.9963874177543091, + 0.999732433969809, + 0.9997741052684195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010720676981911176, + "scoreError" : 2.0727623449036842E-4, + "scoreConfidence" : [ + 0.010513400747420807, + 0.010927953216401545 + ], + "scorePercentiles" : { + "0.0" : 0.010646202747070246, + "50.0" : 0.010718251974902218, + "90.0" : 0.01079558140403528, + "95.0" : 0.01079558140403528, + "99.0" : 0.01079558140403528, + "99.9" : 0.01079558140403528, + "99.99" : 0.01079558140403528, + "99.999" : 0.01079558140403528, + "99.9999" : 0.01079558140403528, + "100.0" : 0.01079558140403528 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010778818299402438, + 0.010789231533088639, + 0.01079558140403528 + ], + [ + 0.010646202747070246, + 0.010657685650401998, + 0.010656542257468453 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2382184355428225, + "scoreError" : 0.15560106018909467, + "scoreConfidence" : [ + 3.082617375353728, + 3.393819495731917 + ], + "scorePercentiles" : { + "0.0" : 3.1803714348378893, + "50.0" : 3.2414223156782525, + "90.0" : 3.29081365, + "95.0" : 3.29081365, + "99.0" : 3.29081365, + "99.9" : 3.29081365, + "99.99" : 3.29081365, + "99.999" : 3.29081365, + "99.9999" : 3.29081365, + "100.0" : 3.29081365 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.186944449330784, + 3.196028722683706, + 3.1803714348378893 + ], + [ + 3.29081365, + 3.2883364477317554, + 3.286815908672799 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8668854944912154, + "scoreError" : 0.0497693409703118, + "scoreConfidence" : [ + 2.8171161535209035, + 2.9166548354615274 + ], + "scorePercentiles" : { + "0.0" : 2.844454523037543, + "50.0" : 2.8710284255860596, + "90.0" : 2.8850163766945487, + "95.0" : 2.8850163766945487, + "99.0" : 2.8850163766945487, + "99.9" : 2.8850163766945487, + "99.99" : 2.8850163766945487, + "99.999" : 2.8850163766945487, + "99.9999" : 2.8850163766945487, + "100.0" : 2.8850163766945487 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8850163766945487, + 2.878910797063903, + 2.881871798617113 + ], + [ + 2.8631460541082165, + 2.847913417425968, + 2.844454523037543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17934533372583464, + "scoreError" : 0.010453566215828845, + "scoreConfidence" : [ + 0.16889176751000579, + 0.1897988999416635 + ], + "scorePercentiles" : { + "0.0" : 0.17593362551679245, + "50.0" : 0.1790673041792642, + "90.0" : 0.18375777786148728, + "95.0" : 0.18375777786148728, + "99.0" : 0.18375777786148728, + "99.9" : 0.18375777786148728, + "99.99" : 0.18375777786148728, + "99.999" : 0.18375777786148728, + "99.9999" : 0.18375777786148728, + "100.0" : 0.18375777786148728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17607055705406977, + 0.17594808012527272, + 0.17593362551679245 + ], + [ + 0.18375777786148728, + 0.18229791049292693, + 0.18206405130445866 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32150134630822297, + "scoreError" : 0.02495639820464376, + "scoreConfidence" : [ + 0.29654494810357923, + 0.3464577445128667 + ], + "scorePercentiles" : { + "0.0" : 0.31339818646776774, + "50.0" : 0.32063907850280193, + "90.0" : 0.33303493392833355, + "95.0" : 0.33303493392833355, + "99.0" : 0.33303493392833355, + "99.9" : 0.33303493392833355, + "99.99" : 0.33303493392833355, + "99.999" : 0.33303493392833355, + "99.9999" : 0.33303493392833355, + "100.0" : 0.33303493392833355 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33303493392833355, + 0.32747483568013624, + 0.3277526436156266 + ], + [ + 0.31380332132546757, + 0.31354415683200604, + 0.31339818646776774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14421020207516558, + "scoreError" : 4.224752422180992E-4, + "scoreConfidence" : [ + 0.14378772683294747, + 0.1446326773173837 + ], + "scorePercentiles" : { + "0.0" : 0.14404212790781418, + "50.0" : 0.14422801717342568, + "90.0" : 0.14444164534253895, + "95.0" : 0.14444164534253895, + "99.0" : 0.14444164534253895, + "99.9" : 0.14444164534253895, + "99.99" : 0.14444164534253895, + "99.999" : 0.14444164534253895, + "99.9999" : 0.14444164534253895, + "100.0" : 0.14444164534253895 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14444164534253895, + 0.1442585996162779, + 0.14404212790781418 + ], + [ + 0.144270860522823, + 0.14419743473057345, + 0.14405054433096615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39102399151392714, + "scoreError" : 0.0254313169814734, + "scoreConfidence" : [ + 0.36559267453245375, + 0.4164553084954005 + ], + "scorePercentiles" : { + "0.0" : 0.3822442730295849, + "50.0" : 0.39121009811639296, + "90.0" : 0.3993929591437358, + "95.0" : 0.3993929591437358, + "99.0" : 0.3993929591437358, + "99.9" : 0.3993929591437358, + "99.99" : 0.3993929591437358, + "99.999" : 0.3993929591437358, + "99.9999" : 0.3993929591437358, + "100.0" : 0.3993929591437358 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3827909746602871, + 0.3832149417918455, + 0.3822442730295849 + ], + [ + 0.39920525444094046, + 0.3992955460171691, + 0.3993929591437358 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15335932327862026, + "scoreError" : 0.0025434730042375284, + "scoreConfidence" : [ + 0.15081585027438274, + 0.15590279628285778 + ], + "scorePercentiles" : { + "0.0" : 0.15233132269071412, + "50.0" : 0.1534542217455895, + "90.0" : 0.15431652338626298, + "95.0" : 0.15431652338626298, + "99.0" : 0.15431652338626298, + "99.9" : 0.15431652338626298, + "99.99" : 0.15431652338626298, + "99.999" : 0.15431652338626298, + "99.9999" : 0.15431652338626298, + "100.0" : 0.15431652338626298 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15283995378266851, + 0.15233132269071412, + 0.152474982450523 + ], + [ + 0.1540684897085105, + 0.15431652338626298, + 0.15412466765304236 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047100241875724556, + "scoreError" : 0.0010409544009827613, + "scoreConfidence" : [ + 0.04605928747474179, + 0.04814119627670732 + ], + "scorePercentiles" : { + "0.0" : 0.046733874016851966, + "50.0" : 0.047111543056984465, + "90.0" : 0.04745215932751896, + "95.0" : 0.04745215932751896, + "99.0" : 0.04745215932751896, + "99.9" : 0.04745215932751896, + "99.99" : 0.04745215932751896, + "99.999" : 0.04745215932751896, + "99.9999" : 0.04745215932751896, + "100.0" : 0.04745215932751896 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04744072937431509, + 0.04745215932751896, + 0.04742234250310612 + ], + [ + 0.046733874016851966, + 0.04675160242169238, + 0.04680074361086282 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8546608.906856257, + "scoreError" : 359602.9147876238, + "scoreConfidence" : [ + 8187005.992068633, + 8906211.821643881 + ], + "scorePercentiles" : { + "0.0" : 8409282.046218487, + "50.0" : 8506915.41147989, + "90.0" : 8701880.559130434, + "95.0" : 8701880.559130434, + "99.0" : 8701880.559130434, + "99.9" : 8701880.559130434, + "99.99" : 8701880.559130434, + "99.999" : 8701880.559130434, + "99.9999" : 8701880.559130434, + "100.0" : 8701880.559130434 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8461005.928087987, + 8454849.97717667, + 8409282.046218487 + ], + [ + 8699810.035652174, + 8701880.559130434, + 8552824.894871796 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-06T04:49:08Z-52eefcdcd13f09c48da85fa4590755e4cba6a5cc-jdk17.json b/performance-results/2025-06-06T04:49:08Z-52eefcdcd13f09c48da85fa4590755e4cba6a5cc-jdk17.json new file mode 100644 index 0000000000..7f02f54887 --- /dev/null +++ b/performance-results/2025-06-06T04:49:08Z-52eefcdcd13f09c48da85fa4590755e4cba6a5cc-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.34855108705949, + "scoreError" : 0.007578080085977567, + "scoreConfidence" : [ + 3.3409730069735124, + 3.3561291671454674 + ], + "scorePercentiles" : { + "0.0" : 3.3472065251581262, + "50.0" : 3.348714773534019, + "90.0" : 3.3495682760117966, + "95.0" : 3.3495682760117966, + "99.0" : 3.3495682760117966, + "99.9" : 3.3495682760117966, + "99.99" : 3.3495682760117966, + "99.999" : 3.3495682760117966, + "99.9999" : 3.3495682760117966, + "100.0" : 3.3495682760117966 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3479306549724765, + 3.3495682760117966 + ], + [ + 3.3472065251581262, + 3.349498892095561 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6896217438285726, + "scoreError" : 0.023925104779922667, + "scoreConfidence" : [ + 1.6656966390486498, + 1.7135468486084953 + ], + "scorePercentiles" : { + "0.0" : 1.6845287676157337, + "50.0" : 1.6903555106174297, + "90.0" : 1.6932471864636967, + "95.0" : 1.6932471864636967, + "99.0" : 1.6932471864636967, + "99.9" : 1.6932471864636967, + "99.99" : 1.6932471864636967, + "99.999" : 1.6932471864636967, + "99.9999" : 1.6932471864636967, + "100.0" : 1.6932471864636967 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.69105014669201, + 1.6932471864636967 + ], + [ + 1.6845287676157337, + 1.6896608745428494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8518611329425024, + "scoreError" : 0.017012329720268227, + "scoreConfidence" : [ + 0.8348488032222342, + 0.8688734626627707 + ], + "scorePercentiles" : { + "0.0" : 0.8493988589471697, + "50.0" : 0.851792395411735, + "90.0" : 0.8544608819993701, + "95.0" : 0.8544608819993701, + "99.0" : 0.8544608819993701, + "99.9" : 0.8544608819993701, + "99.99" : 0.8544608819993701, + "99.999" : 0.8544608819993701, + "99.9999" : 0.8544608819993701, + "100.0" : 0.8544608819993701 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8537876427894755, + 0.8544608819993701 + ], + [ + 0.8493988589471697, + 0.8497971480339945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.161780121402703, + "scoreError" : 0.08392981125066477, + "scoreConfidence" : [ + 16.077850310152037, + 16.24570993265337 + ], + "scorePercentiles" : { + "0.0" : 16.121393605858362, + "50.0" : 16.16060210953796, + "90.0" : 16.20653245283835, + "95.0" : 16.20653245283835, + "99.0" : 16.20653245283835, + "99.9" : 16.20653245283835, + "99.99" : 16.20653245283835, + "99.999" : 16.20653245283835, + "99.9999" : 16.20653245283835, + "100.0" : 16.20653245283835 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.14274371134374, + 16.121393605858362, + 16.17035327043407 + ], + [ + 16.17880673929986, + 16.20653245283835, + 16.15085094864185 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2728.5457140911562, + "scoreError" : 226.49558301940226, + "scoreConfidence" : [ + 2502.050131071754, + 2955.0412971105584 + ], + "scorePercentiles" : { + "0.0" : 2650.354042990703, + "50.0" : 2726.5980865679508, + "90.0" : 2807.868510164806, + "95.0" : 2807.868510164806, + "99.0" : 2807.868510164806, + "99.9" : 2807.868510164806, + "99.99" : 2807.868510164806, + "99.999" : 2807.868510164806, + "99.9999" : 2807.868510164806, + "100.0" : 2807.868510164806 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2804.2784149498893, + 2807.868510164806, + 2794.2216386558225 + ], + [ + 2655.577143305638, + 2658.974534480079, + 2650.354042990703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77111.36449958193, + "scoreError" : 788.2067277091307, + "scoreConfidence" : [ + 76323.15777187281, + 77899.57122729106 + ], + "scorePercentiles" : { + "0.0" : 76814.64174004368, + "50.0" : 77112.58092512525, + "90.0" : 77382.79112266192, + "95.0" : 77382.79112266192, + "99.0" : 77382.79112266192, + "99.9" : 77382.79112266192, + "99.99" : 77382.79112266192, + "99.999" : 77382.79112266192, + "99.9999" : 77382.79112266192, + "100.0" : 77382.79112266192 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76876.3495923097, + 76814.64174004368, + 76876.37885874725 + ], + [ + 77348.78299150325, + 77382.79112266192, + 77369.2426922258 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 365.39982602139133, + "scoreError" : 17.10703644662201, + "scoreConfidence" : [ + 348.2927895747693, + 382.50686246801337 + ], + "scorePercentiles" : { + "0.0" : 359.52730181788866, + "50.0" : 365.3167582268056, + "90.0" : 371.25271161160794, + "95.0" : 371.25271161160794, + "99.0" : 371.25271161160794, + "99.9" : 371.25271161160794, + "99.99" : 371.25271161160794, + "99.999" : 371.25271161160794, + "99.9999" : 371.25271161160794, + "100.0" : 371.25271161160794 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.02276222868704, + 359.52730181788866, + 359.9584597498653 + ], + [ + 371.25271161160794, + 371.0269664953746, + 370.6107542249241 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.87664467998341, + "scoreError" : 4.209807610016364, + "scoreConfidence" : [ + 112.66683706996704, + 121.08645228999978 + ], + "scorePercentiles" : { + "0.0" : 115.27136442597494, + "50.0" : 116.90865121152463, + "90.0" : 118.41025780105362, + "95.0" : 118.41025780105362, + "99.0" : 118.41025780105362, + "99.9" : 118.41025780105362, + "99.99" : 118.41025780105362, + "99.999" : 118.41025780105362, + "99.9999" : 118.41025780105362, + "100.0" : 118.41025780105362 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.27136442597494, + 115.47345997256967, + 115.81811441572754 + ], + [ + 118.41025780105362, + 117.99918800732172, + 118.28748345725296 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06101413041775949, + "scoreError" : 5.586329308800986E-4, + "scoreConfidence" : [ + 0.060455497486879395, + 0.06157276334863959 + ], + "scorePercentiles" : { + "0.0" : 0.06068102533995959, + "50.0" : 0.061039908935551265, + "90.0" : 0.06124316624205382, + "95.0" : 0.06124316624205382, + "99.0" : 0.06124316624205382, + "99.9" : 0.06124316624205382, + "99.99" : 0.06124316624205382, + "99.999" : 0.06124316624205382, + "99.9999" : 0.06124316624205382, + "100.0" : 0.06124316624205382 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06124316624205382, + 0.061165142604621574, + 0.061064183086636865 + ], + [ + 0.06068102533995959, + 0.061015634784465665, + 0.06091563044881947 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6557233157775586E-4, + "scoreError" : 1.8172014387358202E-5, + "scoreConfidence" : [ + 3.4740031719039763E-4, + 3.837443459651141E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5930529210687794E-4, + "50.0" : 3.658830017293834E-4, + "90.0" : 3.714994001315754E-4, + "95.0" : 3.714994001315754E-4, + "99.0" : 3.714994001315754E-4, + "99.9" : 3.714994001315754E-4, + "99.99" : 3.714994001315754E-4, + "99.999" : 3.714994001315754E-4, + "99.9999" : 3.714994001315754E-4, + "100.0" : 3.714994001315754E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.603071418246206E-4, + 3.593837766667977E-4, + 3.5930529210687794E-4 + ], + [ + 3.714588616341462E-4, + 3.714994001315754E-4, + 3.7147951710251703E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12398553405912653, + "scoreError" : 0.0013991073609022338, + "scoreConfidence" : [ + 0.1225864266982243, + 0.12538464142002875 + ], + "scorePercentiles" : { + "0.0" : 0.12326611146720574, + "50.0" : 0.1240177284255026, + "90.0" : 0.12461342621806853, + "95.0" : 0.12461342621806853, + "99.0" : 0.12461342621806853, + "99.9" : 0.12461342621806853, + "99.99" : 0.12461342621806853, + "99.999" : 0.12461342621806853, + "99.9999" : 0.12461342621806853, + "100.0" : 0.12461342621806853 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12428503084647602, + 0.12461342621806853, + 0.12430530875845267 + ], + [ + 0.12326611146720574, + 0.12369290106002696, + 0.1237504260045292 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012999232761343738, + "scoreError" : 2.767127089931583E-4, + "scoreConfidence" : [ + 0.01272252005235058, + 0.013275945470336895 + ], + "scorePercentiles" : { + "0.0" : 0.012893604586965519, + "50.0" : 0.013002369566817166, + "90.0" : 0.013109529199778714, + "95.0" : 0.013109529199778714, + "99.0" : 0.013109529199778714, + "99.9" : 0.013109529199778714, + "99.99" : 0.013109529199778714, + "99.999" : 0.013109529199778714, + "99.9999" : 0.013109529199778714, + "100.0" : 0.013109529199778714 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012907978678858536, + 0.012929680167204102, + 0.012893604586965519 + ], + [ + 0.01307954496882533, + 0.013109529199778714, + 0.01307505896643023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9926524026051903, + "scoreError" : 0.10681762181816905, + "scoreConfidence" : [ + 0.8858347807870213, + 1.0994700244233593 + ], + "scorePercentiles" : { + "0.0" : 0.9569506252631579, + "50.0" : 0.9915446640314953, + "90.0" : 1.0294522447761194, + "95.0" : 1.0294522447761194, + "99.0" : 1.0294522447761194, + "99.9" : 1.0294522447761194, + "99.99" : 1.0294522447761194, + "99.999" : 1.0294522447761194, + "99.9999" : 1.0294522447761194, + "100.0" : 1.0294522447761194 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9569506252631579, + 0.9582028583884258, + 0.95859017377552 + ], + [ + 1.0282193591404483, + 1.0294522447761194, + 1.0244991542874706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01076043635400553, + "scoreError" : 0.0014976211026030365, + "scoreConfidence" : [ + 0.009262815251402493, + 0.012258057456608566 + ], + "scorePercentiles" : { + "0.0" : 0.010269545301813551, + "50.0" : 0.010759797482236676, + "90.0" : 0.011256786643913486, + "95.0" : 0.011256786643913486, + "99.0" : 0.011256786643913486, + "99.9" : 0.011256786643913486, + "99.99" : 0.011256786643913486, + "99.999" : 0.011256786643913486, + "99.9999" : 0.011256786643913486, + "100.0" : 0.011256786643913486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010269545301813551, + 0.010277058946485717, + 0.01027218057453011 + ], + [ + 0.011242536017987633, + 0.011244510639302678, + 0.011256786643913486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0278886362501116, + "scoreError" : 0.03802084980744342, + "scoreConfidence" : [ + 2.989867786442668, + 3.065909486057555 + ], + "scorePercentiles" : { + "0.0" : 3.0078587883343357, + "50.0" : 3.0255275738052028, + "90.0" : 3.0484487483241924, + "95.0" : 3.0484487483241924, + "99.0" : 3.0484487483241924, + "99.9" : 3.0484487483241924, + "99.99" : 3.0484487483241924, + "99.999" : 3.0484487483241924, + "99.9999" : 3.0484487483241924, + "100.0" : 3.0484487483241924 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0255470852994555, + 3.0484487483241924, + 3.0361217275485437 + ], + [ + 3.0238474056831923, + 3.0255080623109496, + 3.0078587883343357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7266708630315555, + "scoreError" : 0.011051789314758096, + "scoreConfidence" : [ + 2.7156190737167973, + 2.7377226523463136 + ], + "scorePercentiles" : { + "0.0" : 2.720755473068553, + "50.0" : 2.7263289882336075, + "90.0" : 2.731086132441289, + "95.0" : 2.731086132441289, + "99.0" : 2.731086132441289, + "99.9" : 2.731086132441289, + "99.99" : 2.731086132441289, + "99.999" : 2.731086132441289, + "99.9999" : 2.731086132441289, + "100.0" : 2.731086132441289 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7255501591280655, + 2.7271078173391494, + 2.720755473068553 + ], + [ + 2.731086132441289, + 2.730872966138722, + 2.7246526300735496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.180610820564118, + "scoreError" : 0.006173128828743966, + "scoreConfidence" : [ + 0.17443769173537405, + 0.18678394939286197 + ], + "scorePercentiles" : { + "0.0" : 0.17908764691977078, + "50.0" : 0.17930672878690407, + "90.0" : 0.18384680639408757, + "95.0" : 0.18384680639408757, + "99.0" : 0.18384680639408757, + "99.9" : 0.18384680639408757, + "99.99" : 0.18384680639408757, + "99.999" : 0.18384680639408757, + "99.9999" : 0.18384680639408757, + "100.0" : 0.18384680639408757 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18384680639408757, + 0.18301234711394165, + 0.17933789076790646 + ], + [ + 0.17927556680590165, + 0.17908764691977078, + 0.1791046653830999 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3251072766823573, + "scoreError" : 0.03778983531375931, + "scoreConfidence" : [ + 0.287317441368598, + 0.3628971119961166 + ], + "scorePercentiles" : { + "0.0" : 0.3126096298530791, + "50.0" : 0.32517183704677055, + "90.0" : 0.33744229501282225, + "95.0" : 0.33744229501282225, + "99.0" : 0.33744229501282225, + "99.9" : 0.33744229501282225, + "99.99" : 0.33744229501282225, + "99.999" : 0.33744229501282225, + "99.9999" : 0.33744229501282225, + "100.0" : 0.33744229501282225 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3126096298530791, + 0.3129672137514474, + 0.31284021960833386 + ], + [ + 0.33737646034209373, + 0.33740784152636727, + 0.33744229501282225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14076251955387628, + "scoreError" : 0.010213692251744498, + "scoreConfidence" : [ + 0.13054882730213177, + 0.1509762118056208 + ], + "scorePercentiles" : { + "0.0" : 0.1373793959088911, + "50.0" : 0.1407917102552879, + "90.0" : 0.1441659815183231, + "95.0" : 0.1441659815183231, + "99.0" : 0.1441659815183231, + "99.9" : 0.1441659815183231, + "99.99" : 0.1441659815183231, + "99.999" : 0.1441659815183231, + "99.9999" : 0.1441659815183231, + "100.0" : 0.1441659815183231 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.144053357346586, + 0.14404113098839053, + 0.1441659815183231 + ], + [ + 0.13739296203888163, + 0.1373793959088911, + 0.13754228952218525 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39820884779712284, + "scoreError" : 0.002635916815896139, + "scoreConfidence" : [ + 0.3955729309812267, + 0.400844764613019 + ], + "scorePercentiles" : { + "0.0" : 0.39703040066698425, + "50.0" : 0.3983806257745231, + "90.0" : 0.3996614534409719, + "95.0" : 0.3996614534409719, + "99.0" : 0.3996614534409719, + "99.9" : 0.3996614534409719, + "99.99" : 0.3996614534409719, + "99.999" : 0.3996614534409719, + "99.9999" : 0.3996614534409719, + "100.0" : 0.3996614534409719 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3996614534409719, + 0.3982930794169189, + 0.39847183268916603 + ], + [ + 0.39703040066698425, + 0.3984681721321273, + 0.3973281484365688 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15878401783001664, + "scoreError" : 0.0019372022877405463, + "scoreConfidence" : [ + 0.15684681554227609, + 0.1607212201177572 + ], + "scorePercentiles" : { + "0.0" : 0.15791370135960964, + "50.0" : 0.1588629026970258, + "90.0" : 0.15954436182195278, + "95.0" : 0.15954436182195278, + "99.0" : 0.15954436182195278, + "99.9" : 0.15954436182195278, + "99.99" : 0.15954436182195278, + "99.999" : 0.15954436182195278, + "99.9999" : 0.15954436182195278, + "100.0" : 0.15954436182195278 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15850221126291764, + 0.15791370135960964, + 0.15813688666803713 + ], + [ + 0.15954436182195278, + 0.15922359413113396, + 0.1593833517364487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.045923568350921866, + "scoreError" : 0.0011502405957562127, + "scoreConfidence" : [ + 0.044773327755165654, + 0.04707380894667808 + ], + "scorePercentiles" : { + "0.0" : 0.04550853706830252, + "50.0" : 0.04587061409772908, + "90.0" : 0.046491582456205605, + "95.0" : 0.046491582456205605, + "99.0" : 0.046491582456205605, + "99.9" : 0.046491582456205605, + "99.99" : 0.046491582456205605, + "99.999" : 0.046491582456205605, + "99.9999" : 0.046491582456205605, + "100.0" : 0.046491582456205605 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04625820486536745, + 0.046491582456205605, + 0.04566679761257826 + ], + [ + 0.04607443058287989, + 0.045541857520197467, + 0.04550853706830252 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8771781.299119929, + "scoreError" : 56228.89335273691, + "scoreConfidence" : [ + 8715552.405767191, + 8828010.192472667 + ], + "scorePercentiles" : { + "0.0" : 8743717.043706294, + "50.0" : 8768926.599474145, + "90.0" : 8796175.488126649, + "95.0" : 8796175.488126649, + "99.0" : 8796175.488126649, + "99.9" : 8796175.488126649, + "99.99" : 8796175.488126649, + "99.999" : 8796175.488126649, + "99.9999" : 8796175.488126649, + "100.0" : 8796175.488126649 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8769313.71779141, + 8768539.48115688, + 8743717.043706294 + ], + [ + 8793310.004393673, + 8796175.488126649, + 8759632.059544658 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-08T03:25:28Z-8950aa312751869089a0302484955777babbf1a3-jdk17.json b/performance-results/2025-06-08T03:25:28Z-8950aa312751869089a0302484955777babbf1a3-jdk17.json new file mode 100644 index 0000000000..77823e7327 --- /dev/null +++ b/performance-results/2025-06-08T03:25:28Z-8950aa312751869089a0302484955777babbf1a3-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.326300008660375, + "scoreError" : 0.036861237386349555, + "scoreConfidence" : [ + 3.289438771274025, + 3.3631612460467246 + ], + "scorePercentiles" : { + "0.0" : 3.3209603564489116, + "50.0" : 3.3249869973032977, + "90.0" : 3.334265683585993, + "95.0" : 3.334265683585993, + "99.0" : 3.334265683585993, + "99.9" : 3.334265683585993, + "99.99" : 3.334265683585993, + "99.999" : 3.334265683585993, + "99.9999" : 3.334265683585993, + "100.0" : 3.334265683585993 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3209603564489116, + 3.326037198896786 + ], + [ + 3.323936795709809, + 3.334265683585993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6724787244596493, + "scoreError" : 0.025381193001681648, + "scoreConfidence" : [ + 1.6470975314579677, + 1.697859917461331 + ], + "scorePercentiles" : { + "0.0" : 1.6678689369085122, + "50.0" : 1.6723381036036176, + "90.0" : 1.677369753722849, + "95.0" : 1.677369753722849, + "99.0" : 1.677369753722849, + "99.9" : 1.677369753722849, + "99.99" : 1.677369753722849, + "99.999" : 1.677369753722849, + "99.9999" : 1.677369753722849, + "100.0" : 1.677369753722849 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6678689369085122, + 1.673069615952946 + ], + [ + 1.6716065912542895, + 1.677369753722849 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8441799846879083, + "scoreError" : 0.0294894117773398, + "scoreConfidence" : [ + 0.8146905729105686, + 0.8736693964652481 + ], + "scorePercentiles" : { + "0.0" : 0.8399224103195174, + "50.0" : 0.8439531649936853, + "90.0" : 0.848891198444745, + "95.0" : 0.848891198444745, + "99.0" : 0.848891198444745, + "99.9" : 0.848891198444745, + "99.99" : 0.848891198444745, + "99.999" : 0.848891198444745, + "99.9999" : 0.848891198444745, + "100.0" : 0.848891198444745 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8406326415985236, + 0.8472736883888471 + ], + [ + 0.8399224103195174, + 0.848891198444745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.923373812318886, + "scoreError" : 0.1774856773892179, + "scoreConfidence" : [ + 15.745888134929668, + 16.100859489708103 + ], + "scorePercentiles" : { + "0.0" : 15.855860462344824, + "50.0" : 15.92046959076927, + "90.0" : 16.001072717258857, + "95.0" : 16.001072717258857, + "99.0" : 16.001072717258857, + "99.9" : 16.001072717258857, + "99.99" : 16.001072717258857, + "99.999" : 16.001072717258857, + "99.9999" : 16.001072717258857, + "100.0" : 16.001072717258857 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.855860462344824, + 15.877970591905294, + 15.867351561703128 + ], + [ + 16.001072717258857, + 15.975018951067964, + 15.962968589633247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2700.815957300882, + "scoreError" : 70.81316290228325, + "scoreConfidence" : [ + 2630.002794398599, + 2771.6291202031653 + ], + "scorePercentiles" : { + "0.0" : 2674.980686587218, + "50.0" : 2700.8310489142837, + "90.0" : 2726.7702619859783, + "95.0" : 2726.7702619859783, + "99.0" : 2726.7702619859783, + "99.9" : 2726.7702619859783, + "99.99" : 2726.7702619859783, + "99.999" : 2726.7702619859783, + "99.9999" : 2726.7702619859783, + "100.0" : 2726.7702619859783 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2678.4516660937898, + 2674.980686587218, + 2680.1704033415463 + ], + [ + 2723.0310313097393, + 2721.491694487021, + 2726.7702619859783 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76014.16147118887, + "scoreError" : 608.2102829145441, + "scoreConfidence" : [ + 75405.95118827432, + 76622.37175410341 + ], + "scorePercentiles" : { + "0.0" : 75752.58096772344, + "50.0" : 76016.78097898219, + "90.0" : 76261.17239722954, + "95.0" : 76261.17239722954, + "99.0" : 76261.17239722954, + "99.9" : 76261.17239722954, + "99.99" : 76261.17239722954, + "99.999" : 76261.17239722954, + "99.9999" : 76261.17239722954, + "100.0" : 76261.17239722954 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75752.58096772344, + 75867.16202392904, + 75844.260727533 + ], + [ + 76166.39993403533, + 76193.39277668287, + 76261.17239722954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.3841676492919, + "scoreError" : 23.230451597898497, + "scoreConfidence" : [ + 324.1537160513934, + 370.6146192471904 + ], + "scorePercentiles" : { + "0.0" : 338.629058837593, + "50.0" : 347.50529630069497, + "90.0" : 355.79994073094787, + "95.0" : 355.79994073094787, + "99.0" : 355.79994073094787, + "99.9" : 355.79994073094787, + "99.99" : 355.79994073094787, + "99.999" : 355.79994073094787, + "99.9999" : 355.79994073094787, + "100.0" : 355.79994073094787 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 338.629058837593, + 340.072642380182, + 340.89894480313984 + ], + [ + 354.79277134563876, + 354.1116477982501, + 355.79994073094787 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.83925674769597, + "scoreError" : 3.902105615234272, + "scoreConfidence" : [ + 108.9371511324617, + 116.74136236293025 + ], + "scorePercentiles" : { + "0.0" : 110.69833407863078, + "50.0" : 112.96052134287146, + "90.0" : 114.16084214617881, + "95.0" : 114.16084214617881, + "99.0" : 114.16084214617881, + "99.9" : 114.16084214617881, + "99.99" : 114.16084214617881, + "99.999" : 114.16084214617881, + "99.9999" : 114.16084214617881, + "100.0" : 114.16084214617881 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.12969287931604, + 113.71805639473017, + 114.16084214617881 + ], + [ + 110.69833407863078, + 112.20298629101276, + 112.12562869630736 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06205154221928095, + "scoreError" : 4.633917286503495E-4, + "scoreConfidence" : [ + 0.0615881504906306, + 0.0625149339479313 + ], + "scorePercentiles" : { + "0.0" : 0.06188737159159828, + "50.0" : 0.062036046793786145, + "90.0" : 0.06226950594974937, + "95.0" : 0.06226950594974937, + "99.0" : 0.06226950594974937, + "99.9" : 0.06226950594974937, + "99.99" : 0.06226950594974937, + "99.999" : 0.06226950594974937, + "99.9999" : 0.06226950594974937, + "100.0" : 0.06226950594974937 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06190328379089418, + 0.06192678215179213, + 0.06188737159159828 + ], + [ + 0.06217699839587155, + 0.06214531143578016, + 0.06226950594974937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8442595146646826E-4, + "scoreError" : 1.626423048094481E-6, + "scoreConfidence" : [ + 3.827995284183738E-4, + 3.860523745145627E-4 + ], + "scorePercentiles" : { + "0.0" : 3.8334160880106803E-4, + "50.0" : 3.84615165513068E-4, + "90.0" : 3.849239774000826E-4, + "95.0" : 3.849239774000826E-4, + "99.0" : 3.849239774000826E-4, + "99.9" : 3.849239774000826E-4, + "99.99" : 3.849239774000826E-4, + "99.999" : 3.849239774000826E-4, + "99.9999" : 3.849239774000826E-4, + "100.0" : 3.849239774000826E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8481677395665333E-4, + 3.8424301761486973E-4, + 3.8334160880106803E-4 + ], + [ + 3.849239774000826E-4, + 3.846283822251221E-4, + 3.8460194880101387E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12505591959082105, + "scoreError" : 7.387214206481599E-4, + "scoreConfidence" : [ + 0.1243171981701729, + 0.1257946410114692 + ], + "scorePercentiles" : { + "0.0" : 0.12471996552842284, + "50.0" : 0.12507586764744089, + "90.0" : 0.125330207153689, + "95.0" : 0.125330207153689, + "99.0" : 0.125330207153689, + "99.9" : 0.125330207153689, + "99.99" : 0.125330207153689, + "99.999" : 0.125330207153689, + "99.9999" : 0.125330207153689, + "100.0" : 0.125330207153689 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12519514417166394, + 0.125330207153689, + 0.12532117169818413 + ], + [ + 0.12471996552842284, + 0.12495659112321783, + 0.12481243786974863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01312297568888591, + "scoreError" : 4.773371917494584E-4, + "scoreConfidence" : [ + 0.012645638497136453, + 0.013600312880635368 + ], + "scorePercentiles" : { + "0.0" : 0.012959037725726505, + "50.0" : 0.013121381985909515, + "90.0" : 0.013312890358765588, + "95.0" : 0.013312890358765588, + "99.0" : 0.013312890358765588, + "99.9" : 0.013312890358765588, + "99.99" : 0.013312890358765588, + "99.999" : 0.013312890358765588, + "99.9999" : 0.013312890358765588, + "100.0" : 0.013312890358765588 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012985584339594465, + 0.012959037725726505, + 0.012961932411501127 + ], + [ + 0.01326122966550323, + 0.013312890358765588, + 0.013257179632224564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.019857742519362, + "scoreError" : 0.02433631590564748, + "scoreConfidence" : [ + 0.9955214266137146, + 1.0441940584250096 + ], + "scorePercentiles" : { + "0.0" : 1.0109205237036287, + "50.0" : 1.01946077565627, + "90.0" : 1.030164497012773, + "95.0" : 1.030164497012773, + "99.0" : 1.030164497012773, + "99.9" : 1.030164497012773, + "99.99" : 1.030164497012773, + "99.999" : 1.030164497012773, + "99.9999" : 1.030164497012773, + "100.0" : 1.030164497012773 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0276875902784914, + 1.030164497012773, + 1.024855731194917 + ], + [ + 1.0114522928087388, + 1.0109205237036287, + 1.0140658201176231 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010972491073741195, + "scoreError" : 8.317736302414524E-4, + "scoreConfidence" : [ + 0.010140717443499743, + 0.011804264703982647 + ], + "scorePercentiles" : { + "0.0" : 0.010690179782823888, + "50.0" : 0.010969496319929894, + "90.0" : 0.01129249920841586, + "95.0" : 0.01129249920841586, + "99.0" : 0.01129249920841586, + "99.9" : 0.01129249920841586, + "99.99" : 0.01129249920841586, + "99.999" : 0.01129249920841586, + "99.9999" : 0.01129249920841586, + "100.0" : 0.01129249920841586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011216567148141584, + 0.011216636603870088, + 0.01129249920841586 + ], + [ + 0.010722425491718205, + 0.010696638207477543, + 0.010690179782823888 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.4183261502028164, + "scoreError" : 0.2232241419302077, + "scoreConfidence" : [ + 3.1951020082726087, + 3.641550292133024 + ], + "scorePercentiles" : { + "0.0" : 3.342383076871658, + "50.0" : 3.41602260156317, + "90.0" : 3.495865106219427, + "95.0" : 3.495865106219427, + "99.0" : 3.495865106219427, + "99.9" : 3.495865106219427, + "99.99" : 3.495865106219427, + "99.999" : 3.495865106219427, + "99.9999" : 3.495865106219427, + "100.0" : 3.495865106219427 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3480300053547523, + 3.342383076871658, + 3.346882750334672 + ], + [ + 3.4927807646648046, + 3.484015197771588, + 3.495865106219427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8832666881843774, + "scoreError" : 0.08555421836469514, + "scoreConfidence" : [ + 2.797712469819682, + 2.9688209065490727 + ], + "scorePercentiles" : { + "0.0" : 2.852367781579698, + "50.0" : 2.8832497851990375, + "90.0" : 2.9161354944606415, + "95.0" : 2.9161354944606415, + "99.0" : 2.9161354944606415, + "99.9" : 2.9161354944606415, + "99.99" : 2.9161354944606415, + "99.999" : 2.9161354944606415, + "99.9999" : 2.9161354944606415, + "100.0" : 2.9161354944606415 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.906483815751235, + 2.9161354944606415, + 2.910025156240908 + ], + [ + 2.8600157546468403, + 2.852367781579698, + 2.8545721264269406 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1793276064048396, + "scoreError" : 0.0041980538770803625, + "scoreConfidence" : [ + 0.17512955252775925, + 0.18352566028191997 + ], + "scorePercentiles" : { + "0.0" : 0.17784321056375602, + "50.0" : 0.17926328954075682, + "90.0" : 0.18110110710081676, + "95.0" : 0.18110110710081676, + "99.0" : 0.18110110710081676, + "99.9" : 0.18110110710081676, + "99.99" : 0.18110110710081676, + "99.999" : 0.18110110710081676, + "99.9999" : 0.18110110710081676, + "100.0" : 0.18110110710081676 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17808047731319895, + 0.17801488032468804, + 0.17784321056375602 + ], + [ + 0.18110110710081676, + 0.1804461017683147, + 0.1804798613582631 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3223147454949445, + "scoreError" : 0.00737541692117947, + "scoreConfidence" : [ + 0.314939328573765, + 0.329690162416124 + ], + "scorePercentiles" : { + "0.0" : 0.31734292990194524, + "50.0" : 0.3236373854753921, + "90.0" : 0.32397040384864584, + "95.0" : 0.32397040384864584, + "99.0" : 0.32397040384864584, + "99.9" : 0.32397040384864584, + "99.99" : 0.32397040384864584, + "99.999" : 0.32397040384864584, + "99.9999" : 0.32397040384864584, + "100.0" : 0.32397040384864584 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3239417102458618, + 0.32135865802243, + 0.31734292990194524 + ], + [ + 0.32345261422518357, + 0.32397040384864584, + 0.32382215672560066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14840744222130792, + "scoreError" : 0.002301891751961203, + "scoreConfidence" : [ + 0.1461055504693467, + 0.15070933397326913 + ], + "scorePercentiles" : { + "0.0" : 0.14750392349106142, + "50.0" : 0.14838924703963544, + "90.0" : 0.1493168357845699, + "95.0" : 0.1493168357845699, + "99.0" : 0.1493168357845699, + "99.9" : 0.1493168357845699, + "99.99" : 0.1493168357845699, + "99.999" : 0.1493168357845699, + "99.9999" : 0.1493168357845699, + "100.0" : 0.1493168357845699 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14776423210248682, + 0.14773588284827893, + 0.14750392349106142 + ], + [ + 0.14901426197678405, + 0.14910951712466639, + 0.1493168357845699 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4032389044779767, + "scoreError" : 0.00803422370051802, + "scoreConfidence" : [ + 0.3952046807774587, + 0.41127312817849476 + ], + "scorePercentiles" : { + "0.0" : 0.40002715704628183, + "50.0" : 0.4035986385135548, + "90.0" : 0.4062878975786138, + "95.0" : 0.4062878975786138, + "99.0" : 0.4062878975786138, + "99.9" : 0.4062878975786138, + "99.99" : 0.4062878975786138, + "99.999" : 0.4062878975786138, + "99.9999" : 0.4062878975786138, + "100.0" : 0.4062878975786138 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4058214473662852, + 0.4062878975786138, + 0.40512318833299577 + ], + [ + 0.4020740886941139, + 0.40002715704628183, + 0.4000996478495699 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15908551586024422, + "scoreError" : 0.005931200288687198, + "scoreConfidence" : [ + 0.153154315571557, + 0.16501671614893143 + ], + "scorePercentiles" : { + "0.0" : 0.15733547998741346, + "50.0" : 0.15863692199878837, + "90.0" : 0.16270222910972276, + "95.0" : 0.16270222910972276, + "99.0" : 0.16270222910972276, + "99.9" : 0.16270222910972276, + "99.99" : 0.16270222910972276, + "99.999" : 0.16270222910972276, + "99.9999" : 0.16270222910972276, + "100.0" : 0.16270222910972276 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1575088468892739, + 0.15733547998741346, + 0.15741587553323783 + ], + [ + 0.16270222910972276, + 0.15978566653351442, + 0.15976499710830286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048212365670898726, + "scoreError" : 0.0011907334760381243, + "scoreConfidence" : [ + 0.0470216321948606, + 0.04940309914693685 + ], + "scorePercentiles" : { + "0.0" : 0.047399205994018305, + "50.0" : 0.04829948107880795, + "90.0" : 0.04865486060564778, + "95.0" : 0.04865486060564778, + "99.0" : 0.04865486060564778, + "99.9" : 0.04865486060564778, + "99.99" : 0.04865486060564778, + "99.999" : 0.04865486060564778, + "99.9999" : 0.04865486060564778, + "100.0" : 0.04865486060564778 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04837945356600323, + 0.04828286189864617, + 0.04831610025896973 + ], + [ + 0.04865486060564778, + 0.04824171170210713, + 0.047399205994018305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8612026.139965571, + "scoreError" : 208415.05689595002, + "scoreConfidence" : [ + 8403611.08306962, + 8820441.196861522 + ], + "scorePercentiles" : { + "0.0" : 8534150.870307168, + "50.0" : 8608030.897169497, + "90.0" : 8692508.815812336, + "95.0" : 8692508.815812336, + "99.0" : 8692508.815812336, + "99.9" : 8692508.815812336, + "99.99" : 8692508.815812336, + "99.999" : 8692508.815812336, + "99.9999" : 8692508.815812336, + "100.0" : 8692508.815812336 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8553063.569230769, + 8547679.78034188, + 8534150.870307168 + ], + [ + 8662998.225108225, + 8692508.815812336, + 8681755.578993056 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-12T04:49:15Z-4dc7965b406a690fedb0abde79f925db1c7a9249-jdk17.json b/performance-results/2025-06-12T04:49:15Z-4dc7965b406a690fedb0abde79f925db1c7a9249-jdk17.json new file mode 100644 index 0000000000..faec207901 --- /dev/null +++ b/performance-results/2025-06-12T04:49:15Z-4dc7965b406a690fedb0abde79f925db1c7a9249-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3454357927276748, + "scoreError" : 0.03346623788303074, + "scoreConfidence" : [ + 3.311969554844644, + 3.3789020306107056 + ], + "scorePercentiles" : { + "0.0" : 3.3388439482953935, + "50.0" : 3.345695436374289, + "90.0" : 3.3515083498667275, + "95.0" : 3.3515083498667275, + "99.0" : 3.3515083498667275, + "99.9" : 3.3515083498667275, + "99.99" : 3.3515083498667275, + "99.999" : 3.3515083498667275, + "99.9999" : 3.3515083498667275, + "100.0" : 3.3515083498667275 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3388439482953935, + 3.345673260052136 + ], + [ + 3.345717612696442, + 3.3515083498667275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6892424696520048, + "scoreError" : 0.037218593382815274, + "scoreConfidence" : [ + 1.6520238762691895, + 1.72646106303482 + ], + "scorePercentiles" : { + "0.0" : 1.6814803265125757, + "50.0" : 1.690682490886024, + "90.0" : 1.6941245703233956, + "95.0" : 1.6941245703233956, + "99.0" : 1.6941245703233956, + "99.9" : 1.6941245703233956, + "99.99" : 1.6941245703233956, + "99.999" : 1.6941245703233956, + "99.9999" : 1.6941245703233956, + "100.0" : 1.6941245703233956 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6814803265125757, + 1.6883069360823495 + ], + [ + 1.6941245703233956, + 1.6930580456896989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.849495016030323, + "scoreError" : 0.050678993212390416, + "scoreConfidence" : [ + 0.7988160228179325, + 0.9001740092427134 + ], + "scorePercentiles" : { + "0.0" : 0.838006091613769, + "50.0" : 0.8522563515387271, + "90.0" : 0.8554612694300683, + "95.0" : 0.8554612694300683, + "99.0" : 0.8554612694300683, + "99.9" : 0.8554612694300683, + "99.99" : 0.8554612694300683, + "99.999" : 0.8554612694300683, + "99.9999" : 0.8554612694300683, + "100.0" : 0.8554612694300683 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.838006091613769, + 0.8531726043713805 + ], + [ + 0.8513400987060737, + 0.8554612694300683 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.147131900506867, + "scoreError" : 0.10299292847783706, + "scoreConfidence" : [ + 16.04413897202903, + 16.250124828984703 + ], + "scorePercentiles" : { + "0.0" : 16.10162403909608, + "50.0" : 16.154565084863677, + "90.0" : 16.184147658388124, + "95.0" : 16.184147658388124, + "99.0" : 16.184147658388124, + "99.9" : 16.184147658388124, + "99.99" : 16.184147658388124, + "99.999" : 16.184147658388124, + "99.9999" : 16.184147658388124, + "100.0" : 16.184147658388124 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.10162403909608, + 16.1084565061823, + 16.13648133615506 + ], + [ + 16.17264883357229, + 16.179433029647353, + 16.184147658388124 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2830.3758981251326, + "scoreError" : 235.27508411293192, + "scoreConfidence" : [ + 2595.1008140122008, + 3065.6509822380644 + ], + "scorePercentiles" : { + "0.0" : 2752.4217717537435, + "50.0" : 2830.9825710172527, + "90.0" : 2907.6578160049808, + "95.0" : 2907.6578160049808, + "99.0" : 2907.6578160049808, + "99.9" : 2907.6578160049808, + "99.99" : 2907.6578160049808, + "99.999" : 2907.6578160049808, + "99.9999" : 2907.6578160049808, + "100.0" : 2907.6578160049808 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2906.116809288673, + 2907.6578160049808, + 2907.1009837420484 + ], + [ + 2752.4217717537435, + 2753.109675215517, + 2755.8483327458325 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76601.3864598707, + "scoreError" : 902.6894045488183, + "scoreConfidence" : [ + 75698.69705532189, + 77504.07586441952 + ], + "scorePercentiles" : { + "0.0" : 76241.75440401683, + "50.0" : 76608.75172089232, + "90.0" : 76913.62879622646, + "95.0" : 76913.62879622646, + "99.0" : 76913.62879622646, + "99.9" : 76913.62879622646, + "99.99" : 76913.62879622646, + "99.999" : 76913.62879622646, + "99.9999" : 76913.62879622646, + "100.0" : 76913.62879622646 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76241.75440401683, + 76341.82333599713, + 76345.6765699282 + ], + [ + 76871.82687185645, + 76913.62879622646, + 76893.60878119916 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 368.0559647780049, + "scoreError" : 16.580615212591304, + "scoreConfidence" : [ + 351.47534956541364, + 384.6365799905962 + ], + "scorePercentiles" : { + "0.0" : 362.39781207966365, + "50.0" : 367.83190254778924, + "90.0" : 374.1082585914812, + "95.0" : 374.1082585914812, + "99.0" : 374.1082585914812, + "99.9" : 374.1082585914812, + "99.99" : 374.1082585914812, + "99.999" : 374.1082585914812, + "99.9999" : 374.1082585914812, + "100.0" : 374.1082585914812 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 372.6262213123719, + 373.5642262569317, + 374.1082585914812 + ], + [ + 362.6016866443747, + 363.03758378320657, + 362.39781207966365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.63134159337665, + "scoreError" : 5.927605613830075, + "scoreConfidence" : [ + 109.70373597954656, + 121.55894720720673 + ], + "scorePercentiles" : { + "0.0" : 112.42741814052104, + "50.0" : 116.10110530294807, + "90.0" : 117.48420478909345, + "95.0" : 117.48420478909345, + "99.0" : 117.48420478909345, + "99.9" : 117.48420478909345, + "99.99" : 117.48420478909345, + "99.999" : 117.48420478909345, + "99.9999" : 117.48420478909345, + "100.0" : 117.48420478909345 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.42741814052104, + 114.26977394217266, + 114.83534679255655 + ], + [ + 117.4044420825766, + 117.36686381333958, + 117.48420478909345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06141427195493044, + "scoreError" : 3.212316364439723E-4, + "scoreConfidence" : [ + 0.06109304031848647, + 0.06173550359137441 + ], + "scorePercentiles" : { + "0.0" : 0.06125492063336498, + "50.0" : 0.06141106216968727, + "90.0" : 0.061591201294621964, + "95.0" : 0.061591201294621964, + "99.0" : 0.061591201294621964, + "99.9" : 0.061591201294621964, + "99.99" : 0.061591201294621964, + "99.999" : 0.061591201294621964, + "99.9999" : 0.061591201294621964, + "100.0" : 0.061591201294621964 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06125492063336498, + 0.061350614871165644, + 0.061591201294621964 + ], + [ + 0.061443370544683726, + 0.06146677059105549, + 0.06137875379469081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6838182371264555E-4, + "scoreError" : 1.903310830236175E-5, + "scoreConfidence" : [ + 3.493487154102838E-4, + 3.874149320150073E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6202698495705054E-4, + "50.0" : 3.6814786140893516E-4, + "90.0" : 3.7599648647197525E-4, + "95.0" : 3.7599648647197525E-4, + "99.0" : 3.7599648647197525E-4, + "99.9" : 3.7599648647197525E-4, + "99.99" : 3.7599648647197525E-4, + "99.999" : 3.7599648647197525E-4, + "99.9999" : 3.7599648647197525E-4, + "100.0" : 3.7599648647197525E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.625053749681407E-4, + 3.6216015949765834E-4, + 3.6202698495705054E-4 + ], + [ + 3.7381158853131883E-4, + 3.737903478497297E-4, + 3.7599648647197525E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12306254881918803, + "scoreError" : 0.002722389008229372, + "scoreConfidence" : [ + 0.12034015981095866, + 0.1257849378274174 + ], + "scorePercentiles" : { + "0.0" : 0.12215084521235663, + "50.0" : 0.12298111060762147, + "90.0" : 0.12427056703657219, + "95.0" : 0.12427056703657219, + "99.0" : 0.12427056703657219, + "99.9" : 0.12427056703657219, + "99.99" : 0.12427056703657219, + "99.999" : 0.12427056703657219, + "99.9999" : 0.12427056703657219, + "100.0" : 0.12427056703657219 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12226971381237085, + 0.12215084521235663, + 0.12216285123381383 + ], + [ + 0.12427056703657219, + 0.12382880821714258, + 0.12369250740287209 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013007208569849694, + "scoreError" : 1.9890754769820944E-4, + "scoreConfidence" : [ + 0.012808301022151485, + 0.013206116117547904 + ], + "scorePercentiles" : { + "0.0" : 0.012939799746383375, + "50.0" : 0.01300579114382538, + "90.0" : 0.013079719174104573, + "95.0" : 0.013079719174104573, + "99.0" : 0.013079719174104573, + "99.9" : 0.013079719174104573, + "99.99" : 0.013079719174104573, + "99.999" : 0.013079719174104573, + "99.9999" : 0.013079719174104573, + "100.0" : 0.013079719174104573 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01294331463569636, + 0.012939799746383375, + 0.012944672768271482 + ], + [ + 0.013068835575263105, + 0.013066909519379277, + 0.013079719174104573 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0266511110017034, + "scoreError" : 0.01631301319977663, + "scoreConfidence" : [ + 1.0103380978019267, + 1.04296412420148 + ], + "scorePercentiles" : { + "0.0" : 1.0201625281036417, + "50.0" : 1.0259300933042172, + "90.0" : 1.0346968341438179, + "95.0" : 1.0346968341438179, + "99.0" : 1.0346968341438179, + "99.9" : 1.0346968341438179, + "99.99" : 1.0346968341438179, + "99.999" : 1.0346968341438179, + "99.9999" : 1.0346968341438179, + "100.0" : 1.0346968341438179 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0346968341438179, + 1.031042740927835, + 1.0292268523206751 + ], + [ + 1.0226333342877594, + 1.0221443762264921, + 1.0201625281036417 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011084942421516059, + "scoreError" : 0.001417778510777805, + "scoreConfidence" : [ + 0.009667163910738253, + 0.012502720932293864 + ], + "scorePercentiles" : { + "0.0" : 0.010620506982810075, + "50.0" : 0.01107784994876481, + "90.0" : 0.011558327431050784, + "95.0" : 0.011558327431050784, + "99.0" : 0.011558327431050784, + "99.9" : 0.011558327431050784, + "99.99" : 0.011558327431050784, + "99.999" : 0.011558327431050784, + "99.9999" : 0.011558327431050784, + "100.0" : 0.011558327431050784 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010620506982810075, + 0.010627579553908086, + 0.01062241013542939 + ], + [ + 0.011552710082276478, + 0.011528120343621537, + 0.011558327431050784 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1331987242477624, + "scoreError" : 0.1955358491941313, + "scoreConfidence" : [ + 2.937662875053631, + 3.328734573441894 + ], + "scorePercentiles" : { + "0.0" : 3.068296353374233, + "50.0" : 3.1340730939624857, + "90.0" : 3.197649632992327, + "95.0" : 3.197649632992327, + "99.0" : 3.197649632992327, + "99.9" : 3.197649632992327, + "99.99" : 3.197649632992327, + "99.999" : 3.197649632992327, + "99.9999" : 3.197649632992327, + "100.0" : 3.197649632992327 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0683552012269937, + 3.068296353374233, + 3.0720216332923833 + ], + [ + 3.197649632992327, + 3.196744969968051, + 3.196124554632588 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7714272639288695, + "scoreError" : 0.021129936380113935, + "scoreConfidence" : [ + 2.7502973275487554, + 2.7925572003089836 + ], + "scorePercentiles" : { + "0.0" : 2.759330518344828, + "50.0" : 2.7735923442569677, + "90.0" : 2.77904220561267, + "95.0" : 2.77904220561267, + "99.0" : 2.77904220561267, + "99.9" : 2.77904220561267, + "99.99" : 2.77904220561267, + "99.999" : 2.77904220561267, + "99.9999" : 2.77904220561267, + "100.0" : 2.77904220561267 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.77904220561267, + 2.775864974465723, + 2.776973764575236 + ], + [ + 2.7713197140482126, + 2.7660324065265485, + 2.759330518344828 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18025176902212237, + "scoreError" : 0.004885508880853, + "scoreConfidence" : [ + 0.17536626014126935, + 0.18513727790297538 + ], + "scorePercentiles" : { + "0.0" : 0.17711319218235275, + "50.0" : 0.1805237782963995, + "90.0" : 0.1820507791411043, + "95.0" : 0.1820507791411043, + "99.0" : 0.1820507791411043, + "99.9" : 0.1820507791411043, + "99.99" : 0.1820507791411043, + "99.999" : 0.1820507791411043, + "99.9999" : 0.1820507791411043, + "100.0" : 0.1820507791411043 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18020209689335784, + 0.17980747480087023, + 0.181491611415608 + ], + [ + 0.1820507791411043, + 0.18084545969944119, + 0.17711319218235275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32322875170664583, + "scoreError" : 0.0363996863467658, + "scoreConfidence" : [ + 0.28682906535988006, + 0.3596284380534116 + ], + "scorePercentiles" : { + "0.0" : 0.31117704960014936, + "50.0" : 0.32334204089846375, + "90.0" : 0.33515043370869363, + "95.0" : 0.33515043370869363, + "99.0" : 0.33515043370869363, + "99.9" : 0.33515043370869363, + "99.99" : 0.33515043370869363, + "99.999" : 0.33515043370869363, + "99.9999" : 0.33515043370869363, + "100.0" : 0.33515043370869363 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31117704960014936, + 0.3112637747758964, + 0.3117005543122526 + ], + [ + 0.3349835274846749, + 0.33509717035820796, + 0.33515043370869363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14412107804474347, + "scoreError" : 0.013194177153618411, + "scoreConfidence" : [ + 0.13092690089112508, + 0.15731525519836187 + ], + "scorePercentiles" : { + "0.0" : 0.13979213077331692, + "50.0" : 0.14388323389337696, + "90.0" : 0.14930642058586402, + "95.0" : 0.14930642058586402, + "99.0" : 0.14930642058586402, + "99.9" : 0.14930642058586402, + "99.99" : 0.14930642058586402, + "99.999" : 0.14930642058586402, + "99.9999" : 0.14930642058586402, + "100.0" : 0.14930642058586402 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13985680801074066, + 0.1399028825965305, + 0.13979213077331692 + ], + [ + 0.14930642058586402, + 0.14800464111178535, + 0.1478635851902234 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4051289352510445, + "scoreError" : 0.0106598646203304, + "scoreConfidence" : [ + 0.39446907063071407, + 0.4157887998713749 + ], + "scorePercentiles" : { + "0.0" : 0.3984384051954261, + "50.0" : 0.4054499986249511, + "90.0" : 0.4099162485653386, + "95.0" : 0.4099162485653386, + "99.0" : 0.4099162485653386, + "99.9" : 0.4099162485653386, + "99.99" : 0.4099162485653386, + "99.999" : 0.4099162485653386, + "99.9999" : 0.4099162485653386, + "100.0" : 0.4099162485653386 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40471256341562123, + 0.4046452348466456, + 0.3984384051954261 + ], + [ + 0.4061874338342811, + 0.4099162485653386, + 0.40687372564895435 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15578051319478628, + "scoreError" : 0.00856324314292947, + "scoreConfidence" : [ + 0.1472172700518568, + 0.16434375633771575 + ], + "scorePercentiles" : { + "0.0" : 0.1530146542116135, + "50.0" : 0.15554438874709248, + "90.0" : 0.15947986682082768, + "95.0" : 0.15947986682082768, + "99.0" : 0.15947986682082768, + "99.9" : 0.15947986682082768, + "99.99" : 0.15947986682082768, + "99.999" : 0.15947986682082768, + "99.9999" : 0.15947986682082768, + "100.0" : 0.15947986682082768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1530146542116135, + 0.15306931962897202, + 0.1530179467660245 + ], + [ + 0.15947986682082768, + 0.15808183387606703, + 0.15801945786521293 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04759288639126818, + "scoreError" : 0.0012461336410645929, + "scoreConfidence" : [ + 0.046346752750203585, + 0.04883902003233277 + ], + "scorePercentiles" : { + "0.0" : 0.04685687221849976, + "50.0" : 0.047567805047909514, + "90.0" : 0.04819953176301609, + "95.0" : 0.04819953176301609, + "99.0" : 0.04819953176301609, + "99.9" : 0.04819953176301609, + "99.99" : 0.04819953176301609, + "99.999" : 0.04819953176301609, + "99.9999" : 0.04819953176301609, + "100.0" : 0.04819953176301609 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047603448346281274, + 0.04751275197768835, + 0.047532161749537755 + ], + [ + 0.04819953176301609, + 0.04785255229258582, + 0.04685687221849976 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8610764.430470346, + "scoreError" : 530501.2515003902, + "scoreConfidence" : [ + 8080263.178969955, + 9141265.681970736 + ], + "scorePercentiles" : { + "0.0" : 8434098.327993255, + "50.0" : 8606902.140823618, + "90.0" : 8795628.941072999, + "95.0" : 8795628.941072999, + "99.0" : 8795628.941072999, + "99.9" : 8795628.941072999, + "99.99" : 8795628.941072999, + "99.999" : 8795628.941072999, + "99.9999" : 8795628.941072999, + "100.0" : 8795628.941072999 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8444266.764556961, + 8436411.753794266, + 8434098.327993255 + ], + [ + 8795628.941072999, + 8784643.278314311, + 8769537.517090272 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-06-16T00:20:30Z-2dc43f7f1f5c1b710bd683a347eed01751f2648e-jdk17.json b/performance-results/2025-06-16T00:20:30Z-2dc43f7f1f5c1b710bd683a347eed01751f2648e-jdk17.json new file mode 100644 index 0000000000..a001420f9b --- /dev/null +++ b/performance-results/2025-06-16T00:20:30Z-2dc43f7f1f5c1b710bd683a347eed01751f2648e-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3437734562883676, + "scoreError" : 0.04530443995195778, + "scoreConfidence" : [ + 3.29846901633641, + 3.3890778962403254 + ], + "scorePercentiles" : { + "0.0" : 3.3337930666656512, + "50.0" : 3.3462436618084546, + "90.0" : 3.3488134348709115, + "95.0" : 3.3488134348709115, + "99.0" : 3.3488134348709115, + "99.9" : 3.3488134348709115, + "99.99" : 3.3488134348709115, + "99.999" : 3.3488134348709115, + "99.9999" : 3.3488134348709115, + "100.0" : 3.3488134348709115 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3337930666656512, + 3.343980336909365 + ], + [ + 3.348506986707544, + 3.3488134348709115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6898731625384302, + "scoreError" : 0.04689607828437407, + "scoreConfidence" : [ + 1.642977084254056, + 1.7367692408228044 + ], + "scorePercentiles" : { + "0.0" : 1.6815122980913808, + "50.0" : 1.6900683536061343, + "90.0" : 1.697843644850071, + "95.0" : 1.697843644850071, + "99.0" : 1.697843644850071, + "99.9" : 1.697843644850071, + "99.99" : 1.697843644850071, + "99.999" : 1.697843644850071, + "99.9999" : 1.697843644850071, + "100.0" : 1.697843644850071 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6815122980913808, + 1.686568861800249 + ], + [ + 1.6935678454120198, + 1.697843644850071 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8463780786153096, + "scoreError" : 0.04218795989312758, + "scoreConfidence" : [ + 0.8041901187221819, + 0.8885660385084372 + ], + "scorePercentiles" : { + "0.0" : 0.8386450646265594, + "50.0" : 0.8463313469918654, + "90.0" : 0.8542045558509483, + "95.0" : 0.8542045558509483, + "99.0" : 0.8542045558509483, + "99.9" : 0.8542045558509483, + "99.99" : 0.8542045558509483, + "99.999" : 0.8542045558509483, + "99.9999" : 0.8542045558509483, + "100.0" : 0.8542045558509483 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8481768207638288, + 0.8542045558509483 + ], + [ + 0.8386450646265594, + 0.844485873219902 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.26822194461779, + "scoreError" : 0.07968288915334563, + "scoreConfidence" : [ + 16.188539055464442, + 16.347904833771135 + ], + "scorePercentiles" : { + "0.0" : 16.213274053202415, + "50.0" : 16.274612731568666, + "90.0" : 16.294907465891345, + "95.0" : 16.294907465891345, + "99.0" : 16.294907465891345, + "99.9" : 16.294907465891345, + "99.99" : 16.294907465891345, + "99.999" : 16.294907465891345, + "99.9999" : 16.294907465891345, + "100.0" : 16.294907465891345 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.276762408099128, + 16.269066179353963, + 16.213274053202415 + ], + [ + 16.282858506121695, + 16.27246305503821, + 16.294907465891345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2799.7126991856508, + "scoreError" : 287.31060789903313, + "scoreConfidence" : [ + 2512.4020912866176, + 3087.023307084684 + ], + "scorePercentiles" : { + "0.0" : 2704.9302267335274, + "50.0" : 2799.0326818499443, + "90.0" : 2895.2784520573177, + "95.0" : 2895.2784520573177, + "99.0" : 2895.2784520573177, + "99.9" : 2895.2784520573177, + "99.99" : 2895.2784520573177, + "99.999" : 2895.2784520573177, + "99.9999" : 2895.2784520573177, + "100.0" : 2895.2784520573177 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2890.83490756246, + 2895.2784520573177, + 2893.5826289600004 + ], + [ + 2704.9302267335274, + 2706.419523663169, + 2707.230456137429 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77226.39889933485, + "scoreError" : 805.7016869196405, + "scoreConfidence" : [ + 76420.69721241521, + 78032.10058625448 + ], + "scorePercentiles" : { + "0.0" : 76917.23038112016, + "50.0" : 77219.46314062207, + "90.0" : 77534.38502843317, + "95.0" : 77534.38502843317, + "99.0" : 77534.38502843317, + "99.9" : 77534.38502843317, + "99.99" : 77534.38502843317, + "99.999" : 77534.38502843317, + "99.9999" : 77534.38502843317, + "100.0" : 77534.38502843317 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77031.6604602437, + 76917.23038112016, + 76958.62883593282 + ], + [ + 77407.26582100046, + 77509.22286927875, + 77534.38502843317 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 366.4149540519022, + "scoreError" : 14.307999017063269, + "scoreConfidence" : [ + 352.10695503483896, + 380.72295306896547 + ], + "scorePercentiles" : { + "0.0" : 361.5685637827905, + "50.0" : 366.46401042586683, + "90.0" : 371.1707859640125, + "95.0" : 371.1707859640125, + "99.0" : 371.1707859640125, + "99.9" : 371.1707859640125, + "99.99" : 371.1707859640125, + "99.999" : 371.1707859640125, + "99.9999" : 371.1707859640125, + "100.0" : 371.1707859640125 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 371.08574555747305, + 370.9560839930404, + 371.1707859640125 + ], + [ + 361.73660815540336, + 361.5685637827905, + 361.97193685869325 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.15781377990079, + "scoreError" : 11.064188157926136, + "scoreConfidence" : [ + 102.09362562197465, + 124.22200193782693 + ], + "scorePercentiles" : { + "0.0" : 108.99345209847239, + "50.0" : 113.4446281131207, + "90.0" : 116.88076166039222, + "95.0" : 116.88076166039222, + "99.0" : 116.88076166039222, + "99.9" : 116.88076166039222, + "99.99" : 116.88076166039222, + "99.999" : 116.88076166039222, + "99.9999" : 116.88076166039222, + "100.0" : 116.88076166039222 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.65650936840193, + 116.68550414815113, + 116.88076166039222 + ], + [ + 109.4979085461476, + 108.99345209847239, + 110.23274685783946 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06126016299608595, + "scoreError" : 0.0010888239447645724, + "scoreConfidence" : [ + 0.060171339051321375, + 0.062348986940850525 + ], + "scorePercentiles" : { + "0.0" : 0.060908707576302054, + "50.0" : 0.06120148196475759, + "90.0" : 0.061670831808034336, + "95.0" : 0.061670831808034336, + "99.0" : 0.061670831808034336, + "99.9" : 0.061670831808034336, + "99.99" : 0.061670831808034336, + "99.999" : 0.061670831808034336, + "99.9999" : 0.061670831808034336, + "100.0" : 0.061670831808034336 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06148854661665693, + 0.06166888654345427, + 0.061670831808034336 + ], + [ + 0.060908707576302054, + 0.0609095881192099, + 0.060914417312858245 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.550149737365908E-4, + "scoreError" : 1.7432098896703561E-6, + "scoreConfidence" : [ + 3.532717638469204E-4, + 3.5675818362626116E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5418618853920594E-4, + "50.0" : 3.5503154484607045E-4, + "90.0" : 3.558955880334308E-4, + "95.0" : 3.558955880334308E-4, + "99.0" : 3.558955880334308E-4, + "99.9" : 3.558955880334308E-4, + "99.99" : 3.558955880334308E-4, + "99.999" : 3.558955880334308E-4, + "99.9999" : 3.558955880334308E-4, + "100.0" : 3.558955880334308E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5418618853920594E-4, + 3.558955880334308E-4, + 3.54533222458149E-4 + ], + [ + 3.548318188055081E-4, + 3.552312708866328E-4, + 3.554117536966181E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12618428775466198, + "scoreError" : 0.004821740370329758, + "scoreConfidence" : [ + 0.12136254738433222, + 0.13100602812499174 + ], + "scorePercentiles" : { + "0.0" : 0.1244358393683739, + "50.0" : 0.12617461991038056, + "90.0" : 0.12788440960881853, + "95.0" : 0.12788440960881853, + "99.0" : 0.12788440960881853, + "99.9" : 0.12788440960881853, + "99.99" : 0.12788440960881853, + "99.999" : 0.12788440960881853, + "99.9999" : 0.12788440960881853, + "100.0" : 0.12788440960881853 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12458568206508197, + 0.1244358393683739, + 0.12485110577175175 + ], + [ + 0.12788440960881853, + 0.12785055566493647, + 0.12749813404900937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012978090687244537, + "scoreError" : 1.9572829974510604E-4, + "scoreConfidence" : [ + 0.01278236238749943, + 0.013173818986989643 + ], + "scorePercentiles" : { + "0.0" : 0.012913511909327692, + "50.0" : 0.012970946070467712, + "90.0" : 0.013065657839243251, + "95.0" : 0.013065657839243251, + "99.0" : 0.013065657839243251, + "99.9" : 0.013065657839243251, + "99.99" : 0.013065657839243251, + "99.999" : 0.013065657839243251, + "99.9999" : 0.013065657839243251, + "100.0" : 0.013065657839243251 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012920237924569988, + 0.012913511909327692, + 0.012913582013690793 + ], + [ + 0.013021654216365437, + 0.013065657839243251, + 0.013033900220270058 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.028562150342937, + "scoreError" : 0.04470070915251111, + "scoreConfidence" : [ + 0.9838614411904258, + 1.073262859495448 + ], + "scorePercentiles" : { + "0.0" : 1.0130934063418093, + "50.0" : 1.0285121155218908, + "90.0" : 1.044383840538847, + "95.0" : 1.044383840538847, + "99.0" : 1.044383840538847, + "99.9" : 1.044383840538847, + "99.99" : 1.044383840538847, + "99.999" : 1.044383840538847, + "99.9999" : 1.044383840538847, + "100.0" : 1.044383840538847 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.044383840538847, + 1.041686903125, + 1.043162136956295 + ], + [ + 1.013709287176888, + 1.0153373279187816, + 1.0130934063418093 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010495474707258477, + "scoreError" : 3.305329233212566E-4, + "scoreConfidence" : [ + 0.010164941783937221, + 0.010826007630579733 + ], + "scorePercentiles" : { + "0.0" : 0.01037974303899161, + "50.0" : 0.010494958705089581, + "90.0" : 0.010609473131193108, + "95.0" : 0.010609473131193108, + "99.0" : 0.010609473131193108, + "99.9" : 0.010609473131193108, + "99.99" : 0.010609473131193108, + "99.999" : 0.010609473131193108, + "99.9999" : 0.010609473131193108, + "100.0" : 0.010609473131193108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010391757095293913, + 0.010392532651326359, + 0.01037974303899161 + ], + [ + 0.010609473131193108, + 0.010601957567893068, + 0.010597384758852803 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1143205326002517, + "scoreError" : 0.03321486006653464, + "scoreConfidence" : [ + 3.081105672533717, + 3.147535392666786 + ], + "scorePercentiles" : { + "0.0" : 3.100018301301922, + "50.0" : 3.1146745324214296, + "90.0" : 3.129520176470588, + "95.0" : 3.129520176470588, + "99.0" : 3.129520176470588, + "99.9" : 3.129520176470588, + "99.99" : 3.129520176470588, + "99.999" : 3.129520176470588, + "99.9999" : 3.129520176470588, + "100.0" : 3.129520176470588 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1216792996254683, + 3.129520176470588, + 3.1226346622971284 + ], + [ + 3.104400990689013, + 3.100018301301922, + 3.1076697652173912 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.702333601132635, + "scoreError" : 0.10685277567848961, + "scoreConfidence" : [ + 2.5954808254541453, + 2.809186376811125 + ], + "scorePercentiles" : { + "0.0" : 2.660223896276596, + "50.0" : 2.7049965552209247, + "90.0" : 2.737997322200931, + "95.0" : 2.737997322200931, + "99.0" : 2.737997322200931, + "99.9" : 2.737997322200931, + "99.99" : 2.737997322200931, + "99.999" : 2.737997322200931, + "99.9999" : 2.737997322200931, + "100.0" : 2.737997322200931 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7366642848153213, + 2.737997322200931, + 2.7359723577680524 + ], + [ + 2.660223896276596, + 2.669122993061116, + 2.6740207526737967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18055492354994107, + "scoreError" : 0.004433512537167173, + "scoreConfidence" : [ + 0.1761214110127739, + 0.18498843608710824 + ], + "scorePercentiles" : { + "0.0" : 0.17926074683612375, + "50.0" : 0.17975328052040385, + "90.0" : 0.18300023593675657, + "95.0" : 0.18300023593675657, + "99.0" : 0.18300023593675657, + "99.9" : 0.18300023593675657, + "99.99" : 0.18300023593675657, + "99.999" : 0.18300023593675657, + "99.9999" : 0.18300023593675657, + "100.0" : 0.18300023593675657 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1794705150481865, + 0.17926074683612375, + 0.17964919640707805 + ], + [ + 0.18300023593675657, + 0.18209148243777198, + 0.17985736463372962 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3205630258901815, + "scoreError" : 0.02193666979870561, + "scoreConfidence" : [ + 0.29862635609147586, + 0.3424996956888871 + ], + "scorePercentiles" : { + "0.0" : 0.3131518901171165, + "50.0" : 0.3206333650320337, + "90.0" : 0.3280536231465687, + "95.0" : 0.3280536231465687, + "99.0" : 0.3280536231465687, + "99.9" : 0.3280536231465687, + "99.99" : 0.3280536231465687, + "99.999" : 0.3280536231465687, + "99.9999" : 0.3280536231465687, + "100.0" : 0.3280536231465687 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3280536231465687, + 0.327453637491814, + 0.32759028155403414 + ], + [ + 0.3131518901171165, + 0.3138130925722534, + 0.31331563045930194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14797053956729145, + "scoreError" : 0.010380943530007944, + "scoreConfidence" : [ + 0.1375895960372835, + 0.1583514830972994 + ], + "scorePercentiles" : { + "0.0" : 0.14184062000198572, + "50.0" : 0.14918402258817665, + "90.0" : 0.15231480217805193, + "95.0" : 0.15231480217805193, + "99.0" : 0.15231480217805193, + "99.9" : 0.15231480217805193, + "99.99" : 0.15231480217805193, + "99.999" : 0.15231480217805193, + "99.9999" : 0.15231480217805193, + "100.0" : 0.15231480217805193 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14867865043635986, + 0.14559904254327855, + 0.14184062000198572 + ], + [ + 0.15231480217805193, + 0.1496893947399934, + 0.14970072750407928 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39613360155640015, + "scoreError" : 0.007282878780686697, + "scoreConfidence" : [ + 0.3888507227757135, + 0.4034164803370868 + ], + "scorePercentiles" : { + "0.0" : 0.39363329348553433, + "50.0" : 0.39588728646652827, + "90.0" : 0.39970631599984013, + "95.0" : 0.39970631599984013, + "99.0" : 0.39970631599984013, + "99.9" : 0.39970631599984013, + "99.99" : 0.39970631599984013, + "99.999" : 0.39970631599984013, + "99.9999" : 0.39970631599984013, + "100.0" : 0.39970631599984013 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39378401992518214, + 0.39363329348553433, + 0.3941645143667967 + ], + [ + 0.39970631599984013, + 0.3979034069947877, + 0.3976100585662598 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15701583311696257, + "scoreError" : 0.0068470743625372605, + "scoreConfidence" : [ + 0.1501687587544253, + 0.16386290747949983 + ], + "scorePercentiles" : { + "0.0" : 0.15412730177396236, + "50.0" : 0.15767006533039554, + "90.0" : 0.15949435629984052, + "95.0" : 0.15949435629984052, + "99.0" : 0.15949435629984052, + "99.9" : 0.15949435629984052, + "99.99" : 0.15949435629984052, + "99.999" : 0.15949435629984052, + "99.9999" : 0.15949435629984052, + "100.0" : 0.15949435629984052 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1589615707836592, + 0.15949435629984052, + 0.15880853536604733 + ], + [ + 0.15653159529474375, + 0.15417163918352245, + 0.15412730177396236 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04775808731800734, + "scoreError" : 0.0032267564743731748, + "scoreConfidence" : [ + 0.04453133084363416, + 0.05098484379238052 + ], + "scorePercentiles" : { + "0.0" : 0.04672263088697017, + "50.0" : 0.047552917901705016, + "90.0" : 0.049031240994336985, + "95.0" : 0.049031240994336985, + "99.0" : 0.049031240994336985, + "99.9" : 0.049031240994336985, + "99.99" : 0.049031240994336985, + "99.999" : 0.049031240994336985, + "99.9999" : 0.049031240994336985, + "100.0" : 0.049031240994336985 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04672263088697017, + 0.046726391009975936, + 0.04673794576607061 + ], + [ + 0.048962425213350896, + 0.049031240994336985, + 0.04836789003733942 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8638023.594341721, + "scoreError" : 334285.629776753, + "scoreConfidence" : [ + 8303737.964564968, + 8972309.224118475 + ], + "scorePercentiles" : { + "0.0" : 8520767.283645656, + "50.0" : 8640151.180326223, + "90.0" : 8759941.232049037, + "95.0" : 8759941.232049037, + "99.0" : 8759941.232049037, + "99.9" : 8759941.232049037, + "99.99" : 8759941.232049037, + "99.999" : 8759941.232049037, + "99.9999" : 8759941.232049037, + "100.0" : 8759941.232049037 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8525900.724637682, + 8542147.617421007, + 8520767.283645656 + ], + [ + 8759941.232049037, + 8738154.743231442, + 8741229.965065502 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-04T01:42:51Z-268bdd6b52c5c73ba8cb59786949154c6951a77a-jdk17.json b/performance-results/2025-07-04T01:42:51Z-268bdd6b52c5c73ba8cb59786949154c6951a77a-jdk17.json new file mode 100644 index 0000000000..16cd9e4592 --- /dev/null +++ b/performance-results/2025-07-04T01:42:51Z-268bdd6b52c5c73ba8cb59786949154c6951a77a-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.328569635572334, + "scoreError" : 0.04499031091502342, + "scoreConfidence" : [ + 3.283579324657311, + 3.3735599464873576 + ], + "scorePercentiles" : { + "0.0" : 3.3191582999768867, + "50.0" : 3.330006998780836, + "90.0" : 3.335106244750779, + "95.0" : 3.335106244750779, + "99.0" : 3.335106244750779, + "99.9" : 3.335106244750779, + "99.99" : 3.335106244750779, + "99.999" : 3.335106244750779, + "99.9999" : 3.335106244750779, + "100.0" : 3.335106244750779 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3277722327984507, + 3.335106244750779 + ], + [ + 3.3191582999768867, + 3.3322417647632205 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.676618813728786, + "scoreError" : 0.018943931506279238, + "scoreConfidence" : [ + 1.657674882222507, + 1.6955627452350652 + ], + "scorePercentiles" : { + "0.0" : 1.6728819247175617, + "50.0" : 1.6771856545725192, + "90.0" : 1.6792220210525435, + "95.0" : 1.6792220210525435, + "99.0" : 1.6792220210525435, + "99.9" : 1.6792220210525435, + "99.99" : 1.6792220210525435, + "99.999" : 1.6792220210525435, + "99.9999" : 1.6792220210525435, + "100.0" : 1.6792220210525435 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.67570256797388, + 1.6728819247175617 + ], + [ + 1.6786687411711585, + 1.6792220210525435 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8405517538440088, + "scoreError" : 0.031080222523943737, + "scoreConfidence" : [ + 0.8094715313200651, + 0.8716319763679525 + ], + "scorePercentiles" : { + "0.0" : 0.8364098239245641, + "50.0" : 0.8391998768241387, + "90.0" : 0.8473974378031941, + "95.0" : 0.8473974378031941, + "99.0" : 0.8473974378031941, + "99.9" : 0.8473974378031941, + "99.99" : 0.8473974378031941, + "99.999" : 0.8473974378031941, + "99.9999" : 0.8473974378031941, + "100.0" : 0.8473974378031941 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8364098239245641, + 0.8473974378031941 + ], + [ + 0.8382710352085699, + 0.8401287184397074 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.21760710382724, + "scoreError" : 0.15787985480029326, + "scoreConfidence" : [ + 16.05972724902695, + 16.375486958627533 + ], + "scorePercentiles" : { + "0.0" : 16.122730263498145, + "50.0" : 16.215068331439333, + "90.0" : 16.286459054380217, + "95.0" : 16.286459054380217, + "99.0" : 16.286459054380217, + "99.9" : 16.286459054380217, + "99.99" : 16.286459054380217, + "99.999" : 16.286459054380217, + "99.9999" : 16.286459054380217, + "100.0" : 16.286459054380217 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.26028553984196, + 16.122730263498145, + 16.206739698691678 + ], + [ + 16.286459054380217, + 16.206031102364456, + 16.223396964186993 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2693.5846812396653, + "scoreError" : 454.5426011347362, + "scoreConfidence" : [ + 2239.042080104929, + 3148.1272823744016 + ], + "scorePercentiles" : { + "0.0" : 2518.23157869718, + "50.0" : 2701.740523794515, + "90.0" : 2844.303868030501, + "95.0" : 2844.303868030501, + "99.0" : 2844.303868030501, + "99.9" : 2844.303868030501, + "99.99" : 2844.303868030501, + "99.999" : 2844.303868030501, + "99.9999" : 2844.303868030501, + "100.0" : 2844.303868030501 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2567.938621545183, + 2552.945563563044, + 2518.23157869718 + ], + [ + 2842.5460295582384, + 2835.542426043847, + 2844.303868030501 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75647.27460356419, + "scoreError" : 722.3248209283865, + "scoreConfidence" : [ + 74924.9497826358, + 76369.59942449258 + ], + "scorePercentiles" : { + "0.0" : 75217.8592051042, + "50.0" : 75662.48929821365, + "90.0" : 76009.48589288088, + "95.0" : 76009.48589288088, + "99.0" : 76009.48589288088, + "99.9" : 76009.48589288088, + "99.99" : 76009.48589288088, + "99.999" : 76009.48589288088, + "99.9999" : 76009.48589288088, + "100.0" : 76009.48589288088 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75581.88399052445, + 76009.48589288088, + 75640.27896969432 + ], + [ + 75217.8592051042, + 75684.69962673298, + 75749.43993644835 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 347.20347929983217, + "scoreError" : 31.29104056759904, + "scoreConfidence" : [ + 315.9124387322331, + 378.4945198674312 + ], + "scorePercentiles" : { + "0.0" : 333.6026527109628, + "50.0" : 348.3806538706525, + "90.0" : 358.2138652909862, + "95.0" : 358.2138652909862, + "99.0" : 358.2138652909862, + "99.9" : 358.2138652909862, + "99.99" : 358.2138652909862, + "99.999" : 358.2138652909862, + "99.9999" : 358.2138652909862, + "100.0" : 358.2138652909862 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.910233792627, + 356.4331167513741, + 358.2138652909862 + ], + [ + 333.6026527109628, + 337.7328162631119, + 340.3281909899309 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.16431633892027, + "scoreError" : 13.548919211491588, + "scoreConfidence" : [ + 101.61539712742868, + 128.71323555041187 + ], + "scorePercentiles" : { + "0.0" : 109.67076055788982, + "50.0" : 116.1405656443205, + "90.0" : 120.20279445226346, + "95.0" : 120.20279445226346, + "99.0" : 120.20279445226346, + "99.9" : 120.20279445226346, + "99.99" : 120.20279445226346, + "99.999" : 120.20279445226346, + "99.9999" : 120.20279445226346, + "100.0" : 120.20279445226346 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.67076055788982, + 109.82067469266423, + 113.32046282619633 + ], + [ + 119.01053704206313, + 118.96066846244467, + 120.20279445226346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06266591277642168, + "scoreError" : 0.002625876614673094, + "scoreConfidence" : [ + 0.060040036161748585, + 0.06529178939109477 + ], + "scorePercentiles" : { + "0.0" : 0.0616495696997719, + "50.0" : 0.06258968207936447, + "90.0" : 0.0636766039185971, + "95.0" : 0.0636766039185971, + "99.0" : 0.0636766039185971, + "99.9" : 0.0636766039185971, + "99.99" : 0.0636766039185971, + "99.999" : 0.0636766039185971, + "99.9999" : 0.0636766039185971, + "100.0" : 0.0636766039185971 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0616495696997719, + 0.06184238756617029, + 0.06200810427104519 + ], + [ + 0.0636766039185971, + 0.06317125988768374, + 0.06364755131526187 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7953539036866715E-4, + "scoreError" : 2.3145334662497465E-5, + "scoreConfidence" : [ + 3.563900557061697E-4, + 4.026807250311646E-4 + ], + "scorePercentiles" : { + "0.0" : 3.708554576369343E-4, + "50.0" : 3.790656615752058E-4, + "90.0" : 3.8854873230873314E-4, + "95.0" : 3.8854873230873314E-4, + "99.0" : 3.8854873230873314E-4, + "99.9" : 3.8854873230873314E-4, + "99.99" : 3.8854873230873314E-4, + "99.999" : 3.8854873230873314E-4, + "99.9999" : 3.8854873230873314E-4, + "100.0" : 3.8854873230873314E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8401351560791763E-4, + 3.8854873230873314E-4, + 3.880378389176149E-4 + ], + [ + 3.7163899019830896E-4, + 3.708554576369343E-4, + 3.7411780754249396E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.13016217860590687, + "scoreError" : 0.012255974476987364, + "scoreConfidence" : [ + 0.1179062041289195, + 0.14241815308289424 + ], + "scorePercentiles" : { + "0.0" : 0.12594823671582767, + "50.0" : 0.12966313654388942, + "90.0" : 0.13542895576982977, + "95.0" : 0.13542895576982977, + "99.0" : 0.13542895576982977, + "99.9" : 0.13542895576982977, + "99.99" : 0.13542895576982977, + "99.999" : 0.13542895576982977, + "99.9999" : 0.13542895576982977, + "100.0" : 0.13542895576982977 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12692428802243969, + 0.12594823671582767, + 0.12598075417931695 + ], + [ + 0.13542895576982977, + 0.13428885188268785, + 0.13240198506533915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013036678612754905, + "scoreError" : 2.3725758161708682E-4, + "scoreConfidence" : [ + 0.012799421031137818, + 0.013273936194371993 + ], + "scorePercentiles" : { + "0.0" : 0.012929688491694078, + "50.0" : 0.013030795956163473, + "90.0" : 0.01314815389540808, + "95.0" : 0.01314815389540808, + "99.0" : 0.01314815389540808, + "99.9" : 0.01314815389540808, + "99.99" : 0.01314815389540808, + "99.999" : 0.01314815389540808, + "99.9999" : 0.01314815389540808, + "100.0" : 0.01314815389540808 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012929688491694078, + 0.012978251873385851, + 0.01298541457279907 + ], + [ + 0.013076177339527878, + 0.013102385503714477, + 0.01314815389540808 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0572838331070766, + "scoreError" : 0.05991101274435279, + "scoreConfidence" : [ + 0.9973728203627239, + 1.1171948458514294 + ], + "scorePercentiles" : { + "0.0" : 1.0335207425589086, + "50.0" : 1.056997560738023, + "90.0" : 1.082338166017316, + "95.0" : 1.082338166017316, + "99.0" : 1.082338166017316, + "99.9" : 1.082338166017316, + "99.99" : 1.082338166017316, + "99.999" : 1.082338166017316, + "99.9999" : 1.082338166017316, + "100.0" : 1.082338166017316 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.082338166017316, + 1.074705080601827, + 1.0721163802530018 + ], + [ + 1.0391438879883623, + 1.0418787412230441, + 1.0335207425589086 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010985166013428284, + "scoreError" : 9.558302337604837E-4, + "scoreConfidence" : [ + 0.0100293357796678, + 0.011940996247188768 + ], + "scorePercentiles" : { + "0.0" : 0.010627249693411916, + "50.0" : 0.010984774938781958, + "90.0" : 0.01132889475532556, + "95.0" : 0.01132889475532556, + "99.0" : 0.01132889475532556, + "99.9" : 0.01132889475532556, + "99.99" : 0.01132889475532556, + "99.999" : 0.01132889475532556, + "99.9999" : 0.01132889475532556, + "100.0" : 0.01132889475532556 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010627249693411916, + 0.010689134302162765, + 0.01071062964644896 + ], + [ + 0.011258920231114954, + 0.011296167452105548, + 0.01132889475532556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1431437141102188, + "scoreError" : 0.30182764200753, + "scoreConfidence" : [ + 2.8413160721026887, + 3.444971356117749 + ], + "scorePercentiles" : { + "0.0" : 3.0455057679658952, + "50.0" : 3.1239017227965267, + "90.0" : 3.306339204890945, + "95.0" : 3.306339204890945, + "99.0" : 3.306339204890945, + "99.9" : 3.306339204890945, + "99.99" : 3.306339204890945, + "99.999" : 3.306339204890945, + "99.9999" : 3.306339204890945, + "100.0" : 3.306339204890945 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2072099205128204, + 3.306339204890945, + 3.1895092767857145 + ], + [ + 3.052003945698597, + 3.0582941688073393, + 3.0455057679658952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8366126365123487, + "scoreError" : 0.11192807361441415, + "scoreConfidence" : [ + 2.7246845628979344, + 2.948540710126763 + ], + "scorePercentiles" : { + "0.0" : 2.7947252179379714, + "50.0" : 2.8310708502559776, + "90.0" : 2.886915958429561, + "95.0" : 2.886915958429561, + "99.0" : 2.886915958429561, + "99.9" : 2.886915958429561, + "99.99" : 2.886915958429561, + "99.999" : 2.886915958429561, + "99.9999" : 2.886915958429561, + "100.0" : 2.886915958429561 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7997416735722283, + 2.7947252179379714, + 2.812406526152981 + ], + [ + 2.886915958429561, + 2.8497351743589743, + 2.8761512686223756 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17977832978042338, + "scoreError" : 0.004877102964240993, + "scoreConfidence" : [ + 0.1749012268161824, + 0.18465543274466437 + ], + "scorePercentiles" : { + "0.0" : 0.1777849959643727, + "50.0" : 0.1797032127486152, + "90.0" : 0.18211270738636365, + "95.0" : 0.18211270738636365, + "99.0" : 0.18211270738636365, + "99.9" : 0.18211270738636365, + "99.99" : 0.18211270738636365, + "99.999" : 0.18211270738636365, + "99.9999" : 0.18211270738636365, + "100.0" : 0.18211270738636365 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18211270738636365, + 0.18070151829565784, + 0.18103921550381982 + ], + [ + 0.1783266343307536, + 0.17870490720157256, + 0.1777849959643727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3101527324158909, + "scoreError" : 0.02168362204182396, + "scoreConfidence" : [ + 0.288469110374067, + 0.33183635445771487 + ], + "scorePercentiles" : { + "0.0" : 0.3028557830102968, + "50.0" : 0.31001197527496527, + "90.0" : 0.3176828542202738, + "95.0" : 0.3176828542202738, + "99.0" : 0.3176828542202738, + "99.9" : 0.3176828542202738, + "99.99" : 0.3176828542202738, + "99.999" : 0.3176828542202738, + "99.9999" : 0.3176828542202738, + "100.0" : 0.3176828542202738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3176828542202738, + 0.31743217632681564, + 0.3164810422178619 + ], + [ + 0.30292163038802894, + 0.3028557830102968, + 0.3035429083320686 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14420180106861882, + "scoreError" : 0.0041929587533655775, + "scoreConfidence" : [ + 0.14000884231525323, + 0.1483947598219844 + ], + "scorePercentiles" : { + "0.0" : 0.14193640824639842, + "50.0" : 0.14428982220825337, + "90.0" : 0.14608486293185305, + "95.0" : 0.14608486293185305, + "99.0" : 0.14608486293185305, + "99.9" : 0.14608486293185305, + "99.99" : 0.14608486293185305, + "99.999" : 0.14608486293185305, + "99.9999" : 0.14608486293185305, + "100.0" : 0.14608486293185305 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14193640824639842, + 0.14330323165768658, + 0.1438116514086026 + ], + [ + 0.1447679930079041, + 0.14530665915926824, + 0.14608486293185305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40256510419185343, + "scoreError" : 0.03837545291742832, + "scoreConfidence" : [ + 0.3641896512744251, + 0.44094055710928176 + ], + "scorePercentiles" : { + "0.0" : 0.3868554717601547, + "50.0" : 0.40257871915665266, + "90.0" : 0.4174543263483052, + "95.0" : 0.4174543263483052, + "99.0" : 0.4174543263483052, + "99.9" : 0.4174543263483052, + "99.99" : 0.4174543263483052, + "99.999" : 0.4174543263483052, + "99.9999" : 0.4174543263483052, + "100.0" : 0.4174543263483052 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39398967673942165, + 0.3903113171226728, + 0.3868554717601547 + ], + [ + 0.41561207160668273, + 0.4174543263483052, + 0.41116776157388374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15931755939366926, + "scoreError" : 0.005422266089113401, + "scoreConfidence" : [ + 0.15389529330455587, + 0.16473982548278265 + ], + "scorePercentiles" : { + "0.0" : 0.15754395212363728, + "50.0" : 0.15882352632361643, + "90.0" : 0.16233668514009286, + "95.0" : 0.16233668514009286, + "99.0" : 0.16233668514009286, + "99.9" : 0.16233668514009286, + "99.99" : 0.16233668514009286, + "99.999" : 0.16233668514009286, + "99.9999" : 0.16233668514009286, + "100.0" : 0.16233668514009286 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15757453417685616, + 0.15754395212363728, + 0.1582316371044304 + ], + [ + 0.16233668514009286, + 0.1608031322741964, + 0.15941541554280247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04742637600013449, + "scoreError" : 0.00247058092297966, + "scoreConfidence" : [ + 0.04495579507715483, + 0.04989695692311415 + ], + "scorePercentiles" : { + "0.0" : 0.04659008959145736, + "50.0" : 0.04730976450273462, + "90.0" : 0.048550663520638526, + "95.0" : 0.048550663520638526, + "99.0" : 0.048550663520638526, + "99.9" : 0.048550663520638526, + "99.99" : 0.048550663520638526, + "99.999" : 0.048550663520638526, + "99.9999" : 0.048550663520638526, + "100.0" : 0.048550663520638526 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046712032184079856, + 0.04663268631117536, + 0.04659008959145736 + ], + [ + 0.04816528757206641, + 0.048550663520638526, + 0.04790749682138939 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8603037.06604283, + "scoreError" : 183557.92827805484, + "scoreConfidence" : [ + 8419479.137764774, + 8786594.994320884 + ], + "scorePercentiles" : { + "0.0" : 8543200.56618275, + "50.0" : 8583624.577461895, + "90.0" : 8692733.995655952, + "95.0" : 8692733.995655952, + "99.0" : 8692733.995655952, + "99.9" : 8692733.995655952, + "99.99" : 8692733.995655952, + "99.999" : 8692733.995655952, + "99.9999" : 8692733.995655952, + "100.0" : 8692733.995655952 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8671240.39341421, + 8604642.790197764, + 8692733.995655952 + ], + [ + 8543200.56618275, + 8562606.364726027, + 8543798.286080273 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-04T05:58:15Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json b/performance-results/2025-07-04T05:58:15Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json new file mode 100644 index 0000000000..f62bfe5cd9 --- /dev/null +++ b/performance-results/2025-07-04T05:58:15Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3323523993996833, + "scoreError" : 0.10836096358190753, + "scoreConfidence" : [ + 3.223991435817776, + 3.4407133629815907 + ], + "scorePercentiles" : { + "0.0" : 3.316409452045907, + "50.0" : 3.3309917873255532, + "90.0" : 3.3510165709017192, + "95.0" : 3.3510165709017192, + "99.0" : 3.3510165709017192, + "99.9" : 3.3510165709017192, + "99.99" : 3.3510165709017192, + "99.999" : 3.3510165709017192, + "99.9999" : 3.3510165709017192, + "100.0" : 3.3510165709017192 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3418859274427857, + 3.3510165709017192 + ], + [ + 3.316409452045907, + 3.3200976472083203 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6874784345492486, + "scoreError" : 0.02872424979591711, + "scoreConfidence" : [ + 1.6587541847533316, + 1.7162026843451657 + ], + "scorePercentiles" : { + "0.0" : 1.6830669938656884, + "50.0" : 1.6868807704975217, + "90.0" : 1.6930852033362633, + "95.0" : 1.6930852033362633, + "99.0" : 1.6930852033362633, + "99.9" : 1.6930852033362633, + "99.99" : 1.6930852033362633, + "99.999" : 1.6930852033362633, + "99.9999" : 1.6930852033362633, + "100.0" : 1.6930852033362633 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6888385657294533, + 1.6830669938656884 + ], + [ + 1.6849229752655899, + 1.6930852033362633 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8470965053221642, + "scoreError" : 0.04389317719369074, + "scoreConfidence" : [ + 0.8032033281284734, + 0.890989682515855 + ], + "scorePercentiles" : { + "0.0" : 0.836962581717173, + "50.0" : 0.8500846488465077, + "90.0" : 0.8512541418784684, + "95.0" : 0.8512541418784684, + "99.0" : 0.8512541418784684, + "99.9" : 0.8512541418784684, + "99.99" : 0.8512541418784684, + "99.999" : 0.8512541418784684, + "99.9999" : 0.8512541418784684, + "100.0" : 0.8512541418784684 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.836962581717173, + 0.8495486732650098 + ], + [ + 0.8512541418784684, + 0.8506206244280056 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.063876927422527, + "scoreError" : 0.29710123818011275, + "scoreConfidence" : [ + 15.766775689242413, + 16.36097816560264 + ], + "scorePercentiles" : { + "0.0" : 15.883611601264155, + "50.0" : 16.11394515319412, + "90.0" : 16.14780049876918, + "95.0" : 16.14780049876918, + "99.0" : 16.14780049876918, + "99.9" : 16.14780049876918, + "99.99" : 16.14780049876918, + "99.999" : 16.14780049876918, + "99.9999" : 16.14780049876918, + "100.0" : 16.14780049876918 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.14780049876918, + 15.986649959202648, + 16.137309198910955 + ], + [ + 16.124371443230906, + 16.103518863157333, + 15.883611601264155 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2608.889916115124, + "scoreError" : 150.2012147905411, + "scoreConfidence" : [ + 2458.688701324583, + 2759.091130905665 + ], + "scorePercentiles" : { + "0.0" : 2551.694837093502, + "50.0" : 2603.4606607707783, + "90.0" : 2671.7147111368527, + "95.0" : 2671.7147111368527, + "99.0" : 2671.7147111368527, + "99.9" : 2671.7147111368527, + "99.99" : 2671.7147111368527, + "99.999" : 2671.7147111368527, + "99.9999" : 2671.7147111368527, + "100.0" : 2671.7147111368527 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2671.7147111368527, + 2640.5448253394898, + 2657.8926513843385 + ], + [ + 2565.1159755344947, + 2566.3764962020673, + 2551.694837093502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77472.04522761896, + "scoreError" : 1627.3034473631394, + "scoreConfidence" : [ + 75844.74178025582, + 79099.3486749821 + ], + "scorePercentiles" : { + "0.0" : 76764.98685570348, + "50.0" : 77574.24116308108, + "90.0" : 78038.36240973724, + "95.0" : 78038.36240973724, + "99.0" : 78038.36240973724, + "99.9" : 78038.36240973724, + "99.99" : 78038.36240973724, + "99.999" : 78038.36240973724, + "99.9999" : 78038.36240973724, + "100.0" : 78038.36240973724 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76764.98685570348, + 76875.37716592866, + 77256.31383860511 + ], + [ + 78005.06260818211, + 77892.16848755706, + 78038.36240973724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.1199549742569, + "scoreError" : 12.18998028177667, + "scoreConfidence" : [ + 337.92997469248024, + 362.3099352560336 + ], + "scorePercentiles" : { + "0.0" : 344.4559231445097, + "50.0" : 349.6430205680216, + "90.0" : 356.7510454442657, + "95.0" : 356.7510454442657, + "99.0" : 356.7510454442657, + "99.9" : 356.7510454442657, + "99.99" : 356.7510454442657, + "99.999" : 356.7510454442657, + "99.9999" : 356.7510454442657, + "100.0" : 356.7510454442657 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.7510454442657, + 351.24881939402655, + 352.6451605389943 + ], + [ + 347.58155958172875, + 344.4559231445097, + 348.03722174201664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.04846632547981, + "scoreError" : 1.9870677769056013, + "scoreConfidence" : [ + 114.0613985485742, + 118.03553410238541 + ], + "scorePercentiles" : { + "0.0" : 115.24299335926284, + "50.0" : 115.82781848615889, + "90.0" : 117.0797233841941, + "95.0" : 117.0797233841941, + "99.0" : 117.0797233841941, + "99.9" : 117.0797233841941, + "99.99" : 117.0797233841941, + "99.999" : 117.0797233841941, + "99.9999" : 117.0797233841941, + "100.0" : 117.0797233841941 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.6226675362829, + 115.61143875918565, + 115.24299335926284 + ], + [ + 116.03296943603486, + 116.70100547791841, + 117.0797233841941 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06206072630840462, + "scoreError" : 0.0012569148226224216, + "scoreConfidence" : [ + 0.0608038114857822, + 0.06331764113102704 + ], + "scorePercentiles" : { + "0.0" : 0.061424995368635715, + "50.0" : 0.06207792806229913, + "90.0" : 0.0627229876939674, + "95.0" : 0.0627229876939674, + "99.0" : 0.0627229876939674, + "99.9" : 0.0627229876939674, + "99.99" : 0.0627229876939674, + "99.999" : 0.0627229876939674, + "99.9999" : 0.0627229876939674, + "100.0" : 0.0627229876939674 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062218338070143785, + 0.061424995368635715, + 0.06178539281941021 + ], + [ + 0.061937518054454466, + 0.06227512584381616, + 0.0627229876939674 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.760003069214069E-4, + "scoreError" : 1.1322024188618305E-5, + "scoreConfidence" : [ + 3.646782827327886E-4, + 3.873223311100252E-4 + ], + "scorePercentiles" : { + "0.0" : 3.725059712204462E-4, + "50.0" : 3.749595351790482E-4, + "90.0" : 3.837030479488953E-4, + "95.0" : 3.837030479488953E-4, + "99.0" : 3.837030479488953E-4, + "99.9" : 3.837030479488953E-4, + "99.99" : 3.837030479488953E-4, + "99.999" : 3.837030479488953E-4, + "99.9999" : 3.837030479488953E-4, + "100.0" : 3.837030479488953E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.725059712204462E-4, + 3.741678237734874E-4, + 3.7640049574240485E-4 + ], + [ + 3.734732562585984E-4, + 3.75751246584609E-4, + 3.837030479488953E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1286117464936559, + "scoreError" : 0.001409369129219998, + "scoreConfidence" : [ + 0.1272023773644359, + 0.13002111562287588 + ], + "scorePercentiles" : { + "0.0" : 0.127877823979233, + "50.0" : 0.1286863755561996, + "90.0" : 0.1293028226121362, + "95.0" : 0.1293028226121362, + "99.0" : 0.1293028226121362, + "99.9" : 0.1293028226121362, + "99.99" : 0.1293028226121362, + "99.999" : 0.1293028226121362, + "99.9999" : 0.1293028226121362, + "100.0" : 0.1293028226121362 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.127877823979233, + 0.1285704188094626, + 0.12887719842773374 + ], + [ + 0.12823988283043306, + 0.12880233230293664, + 0.1293028226121362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013020736146484774, + "scoreError" : 8.07372172896285E-5, + "scoreConfidence" : [ + 0.012939998929195146, + 0.013101473363774402 + ], + "scorePercentiles" : { + "0.0" : 0.012975599161527313, + "50.0" : 0.013022768538688166, + "90.0" : 0.013060617274260094, + "95.0" : 0.013060617274260094, + "99.0" : 0.013060617274260094, + "99.9" : 0.013060617274260094, + "99.99" : 0.013060617274260094, + "99.999" : 0.013060617274260094, + "99.9999" : 0.013060617274260094, + "100.0" : 0.013060617274260094 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012975599161527313, + 0.01303725834859754, + 0.01302219344967191 + ], + [ + 0.013005405017147361, + 0.013023343627704421, + 0.013060617274260094 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.093264672094142, + "scoreError" : 0.030655672923689987, + "scoreConfidence" : [ + 1.062608999170452, + 1.123920345017832 + ], + "scorePercentiles" : { + "0.0" : 1.0813420767733564, + "50.0" : 1.0937734159830863, + "90.0" : 1.1038023586092716, + "95.0" : 1.1038023586092716, + "99.0" : 1.1038023586092716, + "99.9" : 1.1038023586092716, + "99.99" : 1.1038023586092716, + "99.999" : 1.1038023586092716, + "99.9999" : 1.1038023586092716, + "100.0" : 1.1038023586092716 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1034647006509986, + 1.1038023586092716, + 1.102232891325912 + ], + [ + 1.0853139406402605, + 1.0834320645650526, + 1.0813420767733564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01076947678615732, + "scoreError" : 0.0012862089174365315, + "scoreConfidence" : [ + 0.009483267868720788, + 0.012055685703593852 + ], + "scorePercentiles" : { + "0.0" : 0.010314508410243292, + "50.0" : 0.010767445537056889, + "90.0" : 0.011279167167067814, + "95.0" : 0.011279167167067814, + "99.0" : 0.011279167167067814, + "99.9" : 0.011279167167067814, + "99.99" : 0.011279167167067814, + "99.999" : 0.011279167167067814, + "99.9999" : 0.011279167167067814, + "100.0" : 0.011279167167067814 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010314508410243292, + 0.010401478633954351, + 0.010346670027852386 + ], + [ + 0.011141624037666647, + 0.011133412440159427, + 0.011279167167067814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.081990037463644, + "scoreError" : 0.26187695977865455, + "scoreConfidence" : [ + 2.820113077684989, + 3.3438669972422987 + ], + "scorePercentiles" : { + "0.0" : 2.9890510932456666, + "50.0" : 3.080605347862321, + "90.0" : 3.186042552866242, + "95.0" : 3.186042552866242, + "99.0" : 3.186042552866242, + "99.9" : 3.186042552866242, + "99.99" : 3.186042552866242, + "99.999" : 3.186042552866242, + "99.9999" : 3.186042552866242, + "100.0" : 3.186042552866242 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0059038389423076, + 2.9973735578190532, + 2.9890510932456666 + ], + [ + 3.1553068567823344, + 3.186042552866242, + 3.1582623251262625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8157565876808555, + "scoreError" : 0.08497694789334033, + "scoreConfidence" : [ + 2.730779639787515, + 2.900733535574196 + ], + "scorePercentiles" : { + "0.0" : 2.7805151912705033, + "50.0" : 2.813436575745383, + "90.0" : 2.8503097232829866, + "95.0" : 2.8503097232829866, + "99.0" : 2.8503097232829866, + "99.9" : 2.8503097232829866, + "99.99" : 2.8503097232829866, + "99.999" : 2.8503097232829866, + "99.9999" : 2.8503097232829866, + "100.0" : 2.8503097232829866 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.801535624089636, + 2.788027971006412, + 2.7805151912705033 + ], + [ + 2.82533752740113, + 2.848813489034463, + 2.8503097232829866 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17730000919048186, + "scoreError" : 0.004476859054980772, + "scoreConfidence" : [ + 0.1728231501355011, + 0.18177686824546263 + ], + "scorePercentiles" : { + "0.0" : 0.1759902577653415, + "50.0" : 0.17676542623774572, + "90.0" : 0.18011637657823165, + "95.0" : 0.18011637657823165, + "99.0" : 0.18011637657823165, + "99.9" : 0.18011637657823165, + "99.99" : 0.18011637657823165, + "99.999" : 0.18011637657823165, + "99.9999" : 0.18011637657823165, + "100.0" : 0.18011637657823165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18011637657823165, + 0.17811741397121686, + 0.1771410426896234 + ], + [ + 0.1759902577653415, + 0.176389809785868, + 0.1760451543526098 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3274763135193081, + "scoreError" : 0.027021335929683133, + "scoreConfidence" : [ + 0.30045497758962497, + 0.35449764944899126 + ], + "scorePercentiles" : { + "0.0" : 0.31752955905886837, + "50.0" : 0.3250746689283508, + "90.0" : 0.33977580959499865, + "95.0" : 0.33977580959499865, + "99.0" : 0.33977580959499865, + "99.9" : 0.33977580959499865, + "99.99" : 0.33977580959499865, + "99.999" : 0.33977580959499865, + "99.9999" : 0.33977580959499865, + "100.0" : 0.33977580959499865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3202610748759007, + 0.31752955905886837, + 0.31995019282697723 + ], + [ + 0.33977580959499865, + 0.3374529817783027, + 0.32988826298080093 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14821245076765757, + "scoreError" : 0.014948824693493979, + "scoreConfidence" : [ + 0.1332636260741636, + 0.16316127546115156 + ], + "scorePercentiles" : { + "0.0" : 0.1423789941198246, + "50.0" : 0.14889153283216483, + "90.0" : 0.153198552683988, + "95.0" : 0.153198552683988, + "99.0" : 0.153198552683988, + "99.9" : 0.153198552683988, + "99.99" : 0.153198552683988, + "99.999" : 0.153198552683988, + "99.9999" : 0.153198552683988, + "100.0" : 0.153198552683988 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14504189059712533, + 0.14283310646594205, + 0.1423789941198246 + ], + [ + 0.15308098567186113, + 0.153198552683988, + 0.1527411750672043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3979270022771164, + "scoreError" : 0.00504921754899508, + "scoreConfidence" : [ + 0.39287778472812135, + 0.4029762198261115 + ], + "scorePercentiles" : { + "0.0" : 0.3969118106370312, + "50.0" : 0.39726089769902595, + "90.0" : 0.40158917693357965, + "95.0" : 0.40158917693357965, + "99.0" : 0.40158917693357965, + "99.9" : 0.40158917693357965, + "99.99" : 0.40158917693357965, + "99.999" : 0.40158917693357965, + "99.9999" : 0.40158917693357965, + "100.0" : 0.40158917693357965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3971821769331586, + 0.39728971531860796, + 0.3973570537608773 + ], + [ + 0.40158917693357965, + 0.3972320800794439, + 0.3969118106370312 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15698157133931076, + "scoreError" : 0.01110033778686666, + "scoreConfidence" : [ + 0.1458812335524441, + 0.16808190912617743 + ], + "scorePercentiles" : { + "0.0" : 0.15289820270931442, + "50.0" : 0.1567068278305195, + "90.0" : 0.16114186169389927, + "95.0" : 0.16114186169389927, + "99.0" : 0.16114186169389927, + "99.9" : 0.16114186169389927, + "99.99" : 0.16114186169389927, + "99.999" : 0.16114186169389927, + "99.9999" : 0.16114186169389927, + "100.0" : 0.16114186169389927 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16090068511069636, + 0.16114186169389927, + 0.15962033770151637 + ], + [ + 0.15353502286091536, + 0.15379331795952264, + 0.15289820270931442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04753752717638143, + "scoreError" : 0.0022810970219840723, + "scoreConfidence" : [ + 0.04525643015439736, + 0.0498186241983655 + ], + "scorePercentiles" : { + "0.0" : 0.04648255789772146, + "50.0" : 0.04755419141638124, + "90.0" : 0.04862141765609654, + "95.0" : 0.04862141765609654, + "99.0" : 0.04862141765609654, + "99.9" : 0.04862141765609654, + "99.99" : 0.04862141765609654, + "99.999" : 0.04862141765609654, + "99.9999" : 0.04862141765609654, + "100.0" : 0.04862141765609654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047094913431289444, + 0.046960301978407976, + 0.04648255789772146 + ], + [ + 0.04862141765609654, + 0.04801346940147303, + 0.04805250269330014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8840426.954699269, + "scoreError" : 223143.3744572984, + "scoreConfidence" : [ + 8617283.58024197, + 9063570.329156566 + ], + "scorePercentiles" : { + "0.0" : 8735764.425327512, + "50.0" : 8862566.415559158, + "90.0" : 8939953.336014299, + "95.0" : 8939953.336014299, + "99.0" : 8939953.336014299, + "99.9" : 8939953.336014299, + "99.99" : 8939953.336014299, + "99.999" : 8939953.336014299, + "99.9999" : 8939953.336014299, + "100.0" : 8939953.336014299 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8882317.137655417, + 8842815.693462897, + 8735764.425327512 + ], + [ + 8939953.336014299, + 8885177.596802842, + 8756533.538932633 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-04T05:58:39Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json b/performance-results/2025-07-04T05:58:39Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json new file mode 100644 index 0000000000..402e6bb938 --- /dev/null +++ b/performance-results/2025-07-04T05:58:39Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3233015473720835, + "scoreError" : 0.02386213287029164, + "scoreConfidence" : [ + 3.299439414501792, + 3.347163680242375 + ], + "scorePercentiles" : { + "0.0" : 3.3178417450494915, + "50.0" : 3.3247782982539595, + "90.0" : 3.3258078479309248, + "95.0" : 3.3258078479309248, + "99.0" : 3.3258078479309248, + "99.9" : 3.3258078479309248, + "99.99" : 3.3258078479309248, + "99.999" : 3.3258078479309248, + "99.9999" : 3.3258078479309248, + "100.0" : 3.3258078479309248 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3258078479309248, + 3.3243011500740036 + ], + [ + 3.3178417450494915, + 3.325255446433915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6854330157729682, + "scoreError" : 0.016374279653121594, + "scoreConfidence" : [ + 1.6690587361198466, + 1.7018072954260899 + ], + "scorePercentiles" : { + "0.0" : 1.6834050662533355, + "50.0" : 1.6846514630158076, + "90.0" : 1.6890240708069222, + "95.0" : 1.6890240708069222, + "99.0" : 1.6890240708069222, + "99.9" : 1.6890240708069222, + "99.99" : 1.6890240708069222, + "99.999" : 1.6890240708069222, + "99.9999" : 1.6890240708069222, + "100.0" : 1.6890240708069222 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6853700097892022, + 1.6834050662533355 + ], + [ + 1.6839329162424128, + 1.6890240708069222 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8402844882171241, + "scoreError" : 0.044364506070087885, + "scoreConfidence" : [ + 0.7959199821470362, + 0.884648994287212 + ], + "scorePercentiles" : { + "0.0" : 0.8332741510397709, + "50.0" : 0.8408242306500534, + "90.0" : 0.8462153405286185, + "95.0" : 0.8462153405286185, + "99.0" : 0.8462153405286185, + "99.9" : 0.8462153405286185, + "99.99" : 0.8462153405286185, + "99.999" : 0.8462153405286185, + "99.9999" : 0.8462153405286185, + "100.0" : 0.8462153405286185 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8355091109235648, + 0.846139350376542 + ], + [ + 0.8332741510397709, + 0.8462153405286185 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.983346863123282, + "scoreError" : 0.5175247001946739, + "scoreConfidence" : [ + 15.465822162928609, + 16.500871563317958 + ], + "scorePercentiles" : { + "0.0" : 15.71308730922149, + "50.0" : 15.990099348897706, + "90.0" : 16.18345366194174, + "95.0" : 16.18345366194174, + "99.0" : 16.18345366194174, + "99.9" : 16.18345366194174, + "99.99" : 16.18345366194174, + "99.999" : 16.18345366194174, + "99.9999" : 16.18345366194174, + "100.0" : 16.18345366194174 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.18345366194174, + 16.172674538361527, + 16.032985036149828 + ], + [ + 15.947213661645584, + 15.71308730922149, + 15.85066697141952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2685.7513511606635, + "scoreError" : 263.4420271908575, + "scoreConfidence" : [ + 2422.309323969806, + 2949.193378351521 + ], + "scorePercentiles" : { + "0.0" : 2559.324739561141, + "50.0" : 2686.6226981204727, + "90.0" : 2792.169964266401, + "95.0" : 2792.169964266401, + "99.0" : 2792.169964266401, + "99.9" : 2792.169964266401, + "99.99" : 2792.169964266401, + "99.999" : 2792.169964266401, + "99.9999" : 2792.169964266401, + "100.0" : 2792.169964266401 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2559.324739561141, + 2632.6230323288096, + 2621.3300944358384 + ], + [ + 2768.437912459654, + 2792.169964266401, + 2740.6223639121363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76201.57549971544, + "scoreError" : 1338.88356449073, + "scoreConfidence" : [ + 74862.69193522472, + 77540.45906420617 + ], + "scorePercentiles" : { + "0.0" : 75452.48178102297, + "50.0" : 76371.21942271676, + "90.0" : 76673.37431985492, + "95.0" : 76673.37431985492, + "99.0" : 76673.37431985492, + "99.9" : 76673.37431985492, + "99.99" : 76673.37431985492, + "99.999" : 76673.37431985492, + "99.9999" : 76673.37431985492, + "100.0" : 76673.37431985492 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75452.48178102297, + 76279.53213501253, + 76462.90671042098 + ], + [ + 75796.54287157524, + 76673.37431985492, + 76544.6151804061 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 355.02138183383585, + "scoreError" : 4.473423820863153, + "scoreConfidence" : [ + 350.5479580129727, + 359.494805654699 + ], + "scorePercentiles" : { + "0.0" : 352.7172187854351, + "50.0" : 354.8952843264268, + "90.0" : 357.54994543897817, + "95.0" : 357.54994543897817, + "99.0" : 357.54994543897817, + "99.9" : 357.54994543897817, + "99.99" : 357.54994543897817, + "99.999" : 357.54994543897817, + "99.9999" : 357.54994543897817, + "100.0" : 357.54994543897817 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 357.54994543897817, + 355.65806019692286, + 354.41249792882513 + ], + [ + 352.7172187854351, + 354.5684302906722, + 355.2221383621814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.7246171186274, + "scoreError" : 3.7255123292650167, + "scoreConfidence" : [ + 110.99910478936239, + 118.45012944789242 + ], + "scorePercentiles" : { + "0.0" : 112.77792707028043, + "50.0" : 114.79055506261317, + "90.0" : 116.69147337737861, + "95.0" : 116.69147337737861, + "99.0" : 116.69147337737861, + "99.9" : 116.69147337737861, + "99.99" : 116.69147337737861, + "99.999" : 116.69147337737861, + "99.9999" : 116.69147337737861, + "100.0" : 116.69147337737861 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.69147337737861, + 115.3935931400004, + 114.65481237146845 + ], + [ + 113.90359899887869, + 114.92629775375788, + 112.77792707028043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06279275174251553, + "scoreError" : 0.0017315571428124618, + "scoreConfidence" : [ + 0.061061194599703064, + 0.064524308885328 + ], + "scorePercentiles" : { + "0.0" : 0.0620837101164054, + "50.0" : 0.06271956483240969, + "90.0" : 0.06377590104718052, + "95.0" : 0.06377590104718052, + "99.0" : 0.06377590104718052, + "99.9" : 0.06377590104718052, + "99.99" : 0.06377590104718052, + "99.999" : 0.06377590104718052, + "99.9999" : 0.06377590104718052, + "100.0" : 0.06377590104718052 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0620837101164054, + 0.06229525981137247, + 0.06257428105348126 + ], + [ + 0.06286484861133812, + 0.06377590104718052, + 0.06316250981531543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.811345319612806E-4, + "scoreError" : 5.053153374270462E-5, + "scoreConfidence" : [ + 3.30602998218576E-4, + 4.3166606570398526E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6284439455391333E-4, + "50.0" : 3.8109618528231503E-4, + "90.0" : 4.0249718080478367E-4, + "95.0" : 4.0249718080478367E-4, + "99.0" : 4.0249718080478367E-4, + "99.9" : 4.0249718080478367E-4, + "99.99" : 4.0249718080478367E-4, + "99.999" : 4.0249718080478367E-4, + "99.9999" : 4.0249718080478367E-4, + "100.0" : 4.0249718080478367E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9367227448069915E-4, + 3.956352069015953E-4, + 4.0249718080478367E-4 + ], + [ + 3.6284439455391333E-4, + 3.636380389427614E-4, + 3.6852009608393085E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.13109199782479133, + "scoreError" : 0.003971364865176752, + "scoreConfidence" : [ + 0.1271206329596146, + 0.13506336268996808 + ], + "scorePercentiles" : { + "0.0" : 0.12980312457003415, + "50.0" : 0.1308906781469002, + "90.0" : 0.1331832480489039, + "95.0" : 0.1331832480489039, + "99.0" : 0.1331832480489039, + "99.9" : 0.1331832480489039, + "99.99" : 0.1331832480489039, + "99.999" : 0.1331832480489039, + "99.9999" : 0.1331832480489039, + "100.0" : 0.1331832480489039 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1298393443391327, + 0.12999170459774598, + 0.12980312457003415 + ], + [ + 0.1317896516960544, + 0.13194491369687694, + 0.1331832480489039 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012930163833154422, + "scoreError" : 4.340288036853427E-4, + "scoreConfidence" : [ + 0.012496135029469078, + 0.013364192636839765 + ], + "scorePercentiles" : { + "0.0" : 0.012776318978932171, + "50.0" : 0.01293451590469918, + "90.0" : 0.013080545458231743, + "95.0" : 0.013080545458231743, + "99.0" : 0.013080545458231743, + "99.9" : 0.013080545458231743, + "99.99" : 0.013080545458231743, + "99.999" : 0.013080545458231743, + "99.9999" : 0.013080545458231743, + "100.0" : 0.013080545458231743 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01307416622411185, + 0.013080545458231743, + 0.013057908489068099 + ], + [ + 0.012811123320330265, + 0.012780920528252403, + 0.012776318978932171 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0844811976047588, + "scoreError" : 0.02104566505039116, + "scoreConfidence" : [ + 1.0634355325543676, + 1.10552686265515 + ], + "scorePercentiles" : { + "0.0" : 1.0775616377545523, + "50.0" : 1.0830124945462791, + "90.0" : 1.0982940855479904, + "95.0" : 1.0982940855479904, + "99.0" : 1.0982940855479904, + "99.9" : 1.0982940855479904, + "99.99" : 1.0982940855479904, + "99.999" : 1.0982940855479904, + "99.9999" : 1.0982940855479904, + "100.0" : 1.0982940855479904 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.085861358849077, + 1.0775616377545523, + 1.0982940855479904 + ], + [ + 1.0791451143843747, + 1.0809799274673009, + 1.0850450616252576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011104517140232174, + "scoreError" : 7.446308431767102E-4, + "scoreConfidence" : [ + 0.010359886297055464, + 0.011849147983408885 + ], + "scorePercentiles" : { + "0.0" : 0.01081200276339859, + "50.0" : 0.011092823028238621, + "90.0" : 0.011457501020831377, + "95.0" : 0.011457501020831377, + "99.0" : 0.011457501020831377, + "99.9" : 0.011457501020831377, + "99.99" : 0.011457501020831377, + "99.999" : 0.011457501020831377, + "99.9999" : 0.011457501020831377, + "100.0" : 0.011457501020831377 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010889363835732191, + 0.01091375906572899, + 0.01081200276339859 + ], + [ + 0.011457501020831377, + 0.011282589164953642, + 0.011271886990748254 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.333994104913327, + "scoreError" : 0.31103947138207233, + "scoreConfidence" : [ + 3.0229546335312545, + 3.6450335762953996 + ], + "scorePercentiles" : { + "0.0" : 3.22893523692705, + "50.0" : 3.3108708894015573, + "90.0" : 3.504104070077085, + "95.0" : 3.504104070077085, + "99.0" : 3.504104070077085, + "99.9" : 3.504104070077085, + "99.99" : 3.504104070077085, + "99.999" : 3.504104070077085, + "99.9999" : 3.504104070077085, + "100.0" : 3.504104070077085 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.369503977762803, + 3.4065040722070843, + 3.504104070077085 + ], + [ + 3.242679471465629, + 3.22893523692705, + 3.252237801040312 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8536313516660896, + "scoreError" : 0.11059181611693907, + "scoreConfidence" : [ + 2.7430395355491504, + 2.964223167783029 + ], + "scorePercentiles" : { + "0.0" : 2.81440027855937, + "50.0" : 2.850127059632415, + "90.0" : 2.922285966111598, + "95.0" : 2.922285966111598, + "99.0" : 2.922285966111598, + "99.9" : 2.922285966111598, + "99.99" : 2.922285966111598, + "99.999" : 2.922285966111598, + "99.9999" : 2.922285966111598, + "100.0" : 2.922285966111598 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.81440027855937, + 2.818012483234714, + 2.844803478100114 + ], + [ + 2.922285966111598, + 2.8668352628260245, + 2.855450641164716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1779223704763966, + "scoreError" : 0.005796313879332599, + "scoreConfidence" : [ + 0.172126056597064, + 0.18371868435572922 + ], + "scorePercentiles" : { + "0.0" : 0.1754829869092951, + "50.0" : 0.17826857401539326, + "90.0" : 0.18029101718138713, + "95.0" : 0.18029101718138713, + "99.0" : 0.18029101718138713, + "99.9" : 0.18029101718138713, + "99.99" : 0.18029101718138713, + "99.999" : 0.18029101718138713, + "99.9999" : 0.18029101718138713, + "100.0" : 0.18029101718138713 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18029101718138713, + 0.17938147884266983, + 0.17946784113709374 + ], + [ + 0.1757552295998172, + 0.1754829869092951, + 0.1771556691881167 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3291860465021783, + "scoreError" : 0.0063159190303111006, + "scoreConfidence" : [ + 0.3228701274718672, + 0.3355019655324894 + ], + "scorePercentiles" : { + "0.0" : 0.32666764593473363, + "50.0" : 0.3291065716023091, + "90.0" : 0.33299979427924475, + "95.0" : 0.33299979427924475, + "99.0" : 0.33299979427924475, + "99.9" : 0.33299979427924475, + "99.99" : 0.33299979427924475, + "99.999" : 0.33299979427924475, + "99.9999" : 0.33299979427924475, + "100.0" : 0.33299979427924475 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32666764593473363, + 0.3272453779901175, + 0.32926778545322843 + ], + [ + 0.3289453577513898, + 0.33299979427924475, + 0.3299903176043557 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.149413082509113, + "scoreError" : 0.024819846947753115, + "scoreConfidence" : [ + 0.12459323556135989, + 0.1742329294568661 + ], + "scorePercentiles" : { + "0.0" : 0.14083324044108328, + "50.0" : 0.1497588124115123, + "90.0" : 0.15782029568373707, + "95.0" : 0.15782029568373707, + "99.0" : 0.15782029568373707, + "99.9" : 0.15782029568373707, + "99.99" : 0.15782029568373707, + "99.999" : 0.15782029568373707, + "99.9999" : 0.15782029568373707, + "100.0" : 0.15782029568373707 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1423078943676002, + 0.14083324044108328, + 0.14090746299845006 + ], + [ + 0.15782029568373707, + 0.1573998711083829, + 0.15720973045542438 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4046092111966606, + "scoreError" : 0.004078930328007259, + "scoreConfidence" : [ + 0.40053028086865333, + 0.40868814152466787 + ], + "scorePercentiles" : { + "0.0" : 0.4028121823088697, + "50.0" : 0.4043870153615131, + "90.0" : 0.4063646225771059, + "95.0" : 0.4063646225771059, + "99.0" : 0.4063646225771059, + "99.9" : 0.4063646225771059, + "99.99" : 0.4063646225771059, + "99.999" : 0.4063646225771059, + "99.9999" : 0.4063646225771059, + "100.0" : 0.4063646225771059 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4062440527684121, + 0.40408948117019555, + 0.40468454955283073 + ], + [ + 0.4063646225771059, + 0.4034603788025498, + 0.4028121823088697 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1564718776358229, + "scoreError" : 0.0036802843827632155, + "scoreConfidence" : [ + 0.1527915932530597, + 0.16015216201858612 + ], + "scorePercentiles" : { + "0.0" : 0.15500489808729617, + "50.0" : 0.1562280147463201, + "90.0" : 0.1581943587914261, + "95.0" : 0.1581943587914261, + "99.0" : 0.1581943587914261, + "99.9" : 0.1581943587914261, + "99.99" : 0.1581943587914261, + "99.999" : 0.1581943587914261, + "99.9999" : 0.1581943587914261, + "100.0" : 0.1581943587914261 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15500489808729617, + 0.15579941976443462, + 0.1553673269478754 + ], + [ + 0.1581943587914261, + 0.15780865249569978, + 0.15665660972820553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04770177718638726, + "scoreError" : 0.0012206843363661952, + "scoreConfidence" : [ + 0.04648109285002106, + 0.04892246152275346 + ], + "scorePercentiles" : { + "0.0" : 0.04739612044115626, + "50.0" : 0.047463216718565696, + "90.0" : 0.04842430951228016, + "95.0" : 0.04842430951228016, + "99.0" : 0.04842430951228016, + "99.9" : 0.04842430951228016, + "99.99" : 0.04842430951228016, + "99.999" : 0.04842430951228016, + "99.9999" : 0.04842430951228016, + "100.0" : 0.04842430951228016 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04742685051267702, + 0.04740501806580675, + 0.04739612044115626 + ], + [ + 0.048058781661948956, + 0.04842430951228016, + 0.047499582924454366 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8652808.40043153, + "scoreError" : 347713.6176915485, + "scoreConfidence" : [ + 8305094.782739982, + 9000522.01812308 + ], + "scorePercentiles" : { + "0.0" : 8493101.295415958, + "50.0" : 8672612.843025256, + "90.0" : 8774329.630701754, + "95.0" : 8774329.630701754, + "99.0" : 8774329.630701754, + "99.9" : 8774329.630701754, + "99.99" : 8774329.630701754, + "99.999" : 8774329.630701754, + "99.9999" : 8774329.630701754, + "100.0" : 8774329.630701754 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8764825.302366346, + 8774329.630701754, + 8744734.098776223 + ], + [ + 8539368.488054607, + 8493101.295415958, + 8600491.58727429 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-04T06:01:13Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json b/performance-results/2025-07-04T06:01:13Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json new file mode 100644 index 0000000000..084cb7ae78 --- /dev/null +++ b/performance-results/2025-07-04T06:01:13Z-52bdcf19bbbd38425db05beebee12a9416f45542-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3500725580646846, + "scoreError" : 0.04194196075777726, + "scoreConfidence" : [ + 3.3081305973069073, + 3.392014518822462 + ], + "scorePercentiles" : { + "0.0" : 3.341338862182018, + "50.0" : 3.350956431619352, + "90.0" : 3.357038506838016, + "95.0" : 3.357038506838016, + "99.0" : 3.357038506838016, + "99.9" : 3.357038506838016, + "99.99" : 3.357038506838016, + "99.999" : 3.357038506838016, + "99.9999" : 3.357038506838016, + "100.0" : 3.357038506838016 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3508617073502753, + 3.357038506838016 + ], + [ + 3.341338862182018, + 3.351051155888429 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.692582888762888, + "scoreError" : 0.03688262082282431, + "scoreConfidence" : [ + 1.6557002679400636, + 1.7294655095857123 + ], + "scorePercentiles" : { + "0.0" : 1.6852540969269847, + "50.0" : 1.6935580510912405, + "90.0" : 1.6979613559420867, + "95.0" : 1.6979613559420867, + "99.0" : 1.6979613559420867, + "99.9" : 1.6979613559420867, + "99.99" : 1.6979613559420867, + "99.999" : 1.6979613559420867, + "99.9999" : 1.6979613559420867, + "100.0" : 1.6979613559420867 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6909899764015754, + 1.6979613559420867 + ], + [ + 1.6852540969269847, + 1.6961261257809055 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8500638292472653, + "scoreError" : 0.029291617594760833, + "scoreConfidence" : [ + 0.8207722116525045, + 0.8793554468420262 + ], + "scorePercentiles" : { + "0.0" : 0.8443811995128514, + "50.0" : 0.850430680471193, + "90.0" : 0.8550127565338237, + "95.0" : 0.8550127565338237, + "99.0" : 0.8550127565338237, + "99.9" : 0.8550127565338237, + "99.99" : 0.8550127565338237, + "99.999" : 0.8550127565338237, + "99.9999" : 0.8550127565338237, + "100.0" : 0.8550127565338237 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8519453593620813, + 0.8550127565338237 + ], + [ + 0.8443811995128514, + 0.8489160015803047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.29526577215442, + "scoreError" : 0.5578150790049303, + "scoreConfidence" : [ + 15.737450693149489, + 16.853080851159348 + ], + "scorePercentiles" : { + "0.0" : 16.06880658941637, + "50.0" : 16.300167743808423, + "90.0" : 16.514787487714607, + "95.0" : 16.514787487714607, + "99.0" : 16.514787487714607, + "99.9" : 16.514787487714607, + "99.99" : 16.514787487714607, + "99.999" : 16.514787487714607, + "99.9999" : 16.514787487714607, + "100.0" : 16.514787487714607 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.06880658941637, + 16.11111479943471, + 16.17456317366347 + ], + [ + 16.425772313953374, + 16.476550268743996, + 16.514787487714607 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2719.3390505525326, + "scoreError" : 144.8300863697524, + "scoreConfidence" : [ + 2574.5089641827803, + 2864.169136922285 + ], + "scorePercentiles" : { + "0.0" : 2667.9730695619264, + "50.0" : 2720.197683089517, + "90.0" : 2767.244563568595, + "95.0" : 2767.244563568595, + "99.0" : 2767.244563568595, + "99.9" : 2767.244563568595, + "99.99" : 2767.244563568595, + "99.999" : 2767.244563568595, + "99.9999" : 2767.244563568595, + "100.0" : 2767.244563568595 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2765.7859362232207, + 2766.278561460637, + 2767.244563568595 + ], + [ + 2674.609429955813, + 2674.142742545004, + 2667.9730695619264 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76544.68390482895, + "scoreError" : 169.1299010954944, + "scoreConfidence" : [ + 76375.55400373346, + 76713.81380592445 + ], + "scorePercentiles" : { + "0.0" : 76450.52293716864, + "50.0" : 76562.29305717247, + "90.0" : 76610.52052003574, + "95.0" : 76610.52052003574, + "99.0" : 76610.52052003574, + "99.9" : 76610.52052003574, + "99.99" : 76610.52052003574, + "99.999" : 76610.52052003574, + "99.9999" : 76610.52052003574, + "100.0" : 76610.52052003574 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76577.4123222941, + 76547.17379205086, + 76610.52052003574 + ], + [ + 76450.52293716864, + 76585.32004487883, + 76497.15381254557 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.379381293902, + "scoreError" : 4.166390488642571, + "scoreConfidence" : [ + 358.21299080525944, + 366.54577178254453 + ], + "scorePercentiles" : { + "0.0" : 360.4523875197254, + "50.0" : 362.45704233371777, + "90.0" : 363.97303069034496, + "95.0" : 363.97303069034496, + "99.0" : 363.97303069034496, + "99.9" : 363.97303069034496, + "99.99" : 363.97303069034496, + "99.999" : 363.97303069034496, + "99.9999" : 363.97303069034496, + "100.0" : 363.97303069034496 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 362.0003655895777, + 363.97303069034496, + 363.9414160954921 + ], + [ + 360.9953687904138, + 360.4523875197254, + 362.9137190778578 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.14665569399104, + "scoreError" : 8.306301674587809, + "scoreConfidence" : [ + 107.84035401940322, + 124.45295736857885 + ], + "scorePercentiles" : { + "0.0" : 113.12450181610805, + "50.0" : 116.12419738459572, + "90.0" : 119.16251002056491, + "95.0" : 119.16251002056491, + "99.0" : 119.16251002056491, + "99.9" : 119.16251002056491, + "99.99" : 119.16251002056491, + "99.999" : 119.16251002056491, + "99.9999" : 119.16251002056491, + "100.0" : 119.16251002056491 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.76256176478627, + 113.48110809635233, + 113.12450181610805 + ], + [ + 119.16251002056491, + 118.86341946172942, + 118.48583300440517 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061146793957996354, + "scoreError" : 2.7648286613596865E-4, + "scoreConfidence" : [ + 0.060870311091860384, + 0.061423276824132324 + ], + "scorePercentiles" : { + "0.0" : 0.06103525587456208, + "50.0" : 0.06114801436808863, + "90.0" : 0.06128008322303111, + "95.0" : 0.06128008322303111, + "99.0" : 0.06128008322303111, + "99.9" : 0.06128008322303111, + "99.99" : 0.06128008322303111, + "99.999" : 0.06128008322303111, + "99.9999" : 0.06128008322303111, + "100.0" : 0.06128008322303111 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06128008322303111, + 0.061184514515763906, + 0.06122255979209139 + ], + [ + 0.06104683612211634, + 0.06103525587456208, + 0.06111151422041335 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5647121084516183E-4, + "scoreError" : 2.619131817377669E-5, + "scoreConfidence" : [ + 3.3027989267138516E-4, + 3.826625290189385E-4 + ], + "scorePercentiles" : { + "0.0" : 3.4763775625082843E-4, + "50.0" : 3.563446240873886E-4, + "90.0" : 3.653637245117119E-4, + "95.0" : 3.653637245117119E-4, + "99.0" : 3.653637245117119E-4, + "99.9" : 3.653637245117119E-4, + "99.99" : 3.653637245117119E-4, + "99.999" : 3.653637245117119E-4, + "99.9999" : 3.653637245117119E-4, + "100.0" : 3.653637245117119E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.645490262089927E-4, + 3.653637245117119E-4, + 3.6506541747342153E-4 + ], + [ + 3.4763775625082843E-4, + 3.481402219657846E-4, + 3.480711186602321E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12586257494255446, + "scoreError" : 0.0038474665319434406, + "scoreConfidence" : [ + 0.12201510841061101, + 0.12971004147449788 + ], + "scorePercentiles" : { + "0.0" : 0.12453125221971782, + "50.0" : 0.12582808264594852, + "90.0" : 0.12730493236413631, + "95.0" : 0.12730493236413631, + "99.0" : 0.12730493236413631, + "99.9" : 0.12730493236413631, + "99.99" : 0.12730493236413631, + "99.999" : 0.12730493236413631, + "99.9999" : 0.12730493236413631, + "100.0" : 0.12730493236413631 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12477112111192903, + 0.12455273171916452, + 0.12453125221971782 + ], + [ + 0.12688504417996802, + 0.12730493236413631, + 0.12713036806041114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012867241822973845, + "scoreError" : 3.5674173458045895E-4, + "scoreConfidence" : [ + 0.012510500088393385, + 0.013223983557554305 + ], + "scorePercentiles" : { + "0.0" : 0.012737975367676093, + "50.0" : 0.01287252940963858, + "90.0" : 0.01298491315277601, + "95.0" : 0.01298491315277601, + "99.0" : 0.01298491315277601, + "99.9" : 0.01298491315277601, + "99.99" : 0.01298491315277601, + "99.999" : 0.01298491315277601, + "99.9999" : 0.01298491315277601, + "100.0" : 0.01298491315277601 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012982692845069106, + 0.01298491315277601, + 0.012981813048637056 + ], + [ + 0.012752810753044698, + 0.012763245770640107, + 0.012737975367676093 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.1340015385480036, + "scoreError" : 0.12730010224125868, + "scoreConfidence" : [ + 1.0067014363067448, + 1.2613016407892623 + ], + "scorePercentiles" : { + "0.0" : 1.0915954262169831, + "50.0" : 1.1339126950459173, + "90.0" : 1.1759154796002351, + "95.0" : 1.1759154796002351, + "99.0" : 1.1759154796002351, + "99.9" : 1.1759154796002351, + "99.99" : 1.1759154796002351, + "99.999" : 1.1759154796002351, + "99.9999" : 1.1759154796002351, + "100.0" : 1.1759154796002351 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1756312722463853, + 1.1747683332550218, + 1.1759154796002351 + ], + [ + 1.0930416631325828, + 1.0915954262169831, + 1.0930570568368128 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011408165491865949, + "scoreError" : 0.0010844108086044875, + "scoreConfidence" : [ + 0.01032375468326146, + 0.012492576300470437 + ], + "scorePercentiles" : { + "0.0" : 0.011053376555450183, + "50.0" : 0.011407695387048528, + "90.0" : 0.011766439164321282, + "95.0" : 0.011766439164321282, + "99.0" : 0.011766439164321282, + "99.9" : 0.011766439164321282, + "99.99" : 0.011766439164321282, + "99.999" : 0.011766439164321282, + "99.9999" : 0.011766439164321282, + "100.0" : 0.011766439164321282 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011053376555450183, + 0.011058010007253876, + 0.011054097479069623 + ], + [ + 0.011757380766843179, + 0.011766439164321282, + 0.011759688978257547 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1989598753194195, + "scoreError" : 0.15695047164652745, + "scoreConfidence" : [ + 3.042009403672892, + 3.355910346965947 + ], + "scorePercentiles" : { + "0.0" : 3.1439406530483973, + "50.0" : 3.196734009650096, + "90.0" : 3.257687003908795, + "95.0" : 3.257687003908795, + "99.0" : 3.257687003908795, + "99.9" : 3.257687003908795, + "99.99" : 3.257687003908795, + "99.999" : 3.257687003908795, + "99.9999" : 3.257687003908795, + "100.0" : 3.257687003908795 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1536363619167718, + 3.1439406530483973, + 3.1470716595342982 + ], + [ + 3.2515919161248377, + 3.257687003908795, + 3.23983165738342 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.753497233629058, + "scoreError" : 0.021138909173763303, + "scoreConfidence" : [ + 2.7323583244552947, + 2.7746361428028217 + ], + "scorePercentiles" : { + "0.0" : 2.744687479418222, + "50.0" : 2.7542216562759188, + "90.0" : 2.7658151789269914, + "95.0" : 2.7658151789269914, + "99.0" : 2.7658151789269914, + "99.9" : 2.7658151789269914, + "99.99" : 2.7658151789269914, + "99.999" : 2.7658151789269914, + "99.9999" : 2.7658151789269914, + "100.0" : 2.7658151789269914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7658151789269914, + 2.7554722567493113, + 2.744687479418222 + ], + [ + 2.755166500275482, + 2.7465651741279866, + 2.7532768122763556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1794522531389187, + "scoreError" : 0.003844117348925061, + "scoreConfidence" : [ + 0.17560813578999362, + 0.18329637048784375 + ], + "scorePercentiles" : { + "0.0" : 0.17858327411693276, + "50.0" : 0.1790348205393349, + "90.0" : 0.18220874551318259, + "95.0" : 0.18220874551318259, + "99.0" : 0.18220874551318259, + "99.9" : 0.18220874551318259, + "99.99" : 0.18220874551318259, + "99.999" : 0.18220874551318259, + "99.9999" : 0.18220874551318259, + "100.0" : 0.18220874551318259 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18220874551318259, + 0.17858327411693276, + 0.17867991259134847 + ], + [ + 0.17913275350195249, + 0.17917194553337873, + 0.1789368875767173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32986299242006795, + "scoreError" : 0.00217983133936684, + "scoreConfidence" : [ + 0.3276831610807011, + 0.3320428237594348 + ], + "scorePercentiles" : { + "0.0" : 0.3290730533416697, + "50.0" : 0.32983079635338886, + "90.0" : 0.330833399100172, + "95.0" : 0.330833399100172, + "99.0" : 0.330833399100172, + "99.9" : 0.330833399100172, + "99.99" : 0.330833399100172, + "99.999" : 0.330833399100172, + "99.9999" : 0.330833399100172, + "100.0" : 0.330833399100172 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3304542961139383, + 0.330833399100172, + 0.3303801436122766 + ], + [ + 0.3290730533416697, + 0.32928144909450113, + 0.32915561325785003 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14425143101892393, + "scoreError" : 0.00204122626266484, + "scoreConfidence" : [ + 0.1422102047562591, + 0.14629265728158877 + ], + "scorePercentiles" : { + "0.0" : 0.14348940708536007, + "50.0" : 0.14424958230627327, + "90.0" : 0.14513155353022278, + "95.0" : 0.14513155353022278, + "99.0" : 0.14513155353022278, + "99.9" : 0.14513155353022278, + "99.99" : 0.14513155353022278, + "99.999" : 0.14513155353022278, + "99.9999" : 0.14513155353022278, + "100.0" : 0.14513155353022278 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14348940708536007, + 0.14357860815506102, + 0.14373503581797797 + ], + [ + 0.14513155353022278, + 0.14480985273035318, + 0.14476412879456854 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40425709775325186, + "scoreError" : 0.013424458440701779, + "scoreConfidence" : [ + 0.3908326393125501, + 0.41768155619395364 + ], + "scorePercentiles" : { + "0.0" : 0.39627328871453477, + "50.0" : 0.40533617371336095, + "90.0" : 0.40966577501945844, + "95.0" : 0.40966577501945844, + "99.0" : 0.40966577501945844, + "99.9" : 0.40966577501945844, + "99.99" : 0.40966577501945844, + "99.999" : 0.40966577501945844, + "99.9999" : 0.40966577501945844, + "100.0" : 0.40966577501945844 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40750355401165395, + 0.40966577501945844, + 0.4059368249238888 + ], + [ + 0.40473552250283307, + 0.40142762134714194, + 0.39627328871453477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15352778244750315, + "scoreError" : 0.0013621800589627478, + "scoreConfidence" : [ + 0.1521656023885404, + 0.1548899625064659 + ], + "scorePercentiles" : { + "0.0" : 0.15305123913742175, + "50.0" : 0.15353682117903084, + "90.0" : 0.15404932877872943, + "95.0" : 0.15404932877872943, + "99.0" : 0.15404932877872943, + "99.9" : 0.15404932877872943, + "99.99" : 0.15404932877872943, + "99.999" : 0.15404932877872943, + "99.9999" : 0.15404932877872943, + "100.0" : 0.15404932877872943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15315545479745768, + 0.15305123913742175, + 0.15305595371688324 + ], + [ + 0.1539365306939228, + 0.15391818756060396, + 0.15404932877872943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046570546393412314, + "scoreError" : 6.883326908825211E-4, + "scoreConfidence" : [ + 0.045882213702529796, + 0.04725887908429483 + ], + "scorePercentiles" : { + "0.0" : 0.04637265599076311, + "50.0" : 0.04649219567312299, + "90.0" : 0.04705325463819055, + "95.0" : 0.04705325463819055, + "99.0" : 0.04705325463819055, + "99.9" : 0.04705325463819055, + "99.99" : 0.04705325463819055, + "99.999" : 0.04705325463819055, + "99.9999" : 0.04705325463819055, + "100.0" : 0.04705325463819055 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046488068355089444, + 0.04644098458180467, + 0.04649632299115653 + ], + [ + 0.04705325463819055, + 0.046571991803469555, + 0.04637265599076311 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8658541.392568666, + "scoreError" : 609930.2638127445, + "scoreConfidence" : [ + 8048611.1287559215, + 9268471.656381411 + ], + "scorePercentiles" : { + "0.0" : 8439101.735864978, + "50.0" : 8657563.667085737, + "90.0" : 8885968.184724689, + "95.0" : 8885968.184724689, + "99.0" : 8885968.184724689, + "99.9" : 8885968.184724689, + "99.99" : 8885968.184724689, + "99.999" : 8885968.184724689, + "99.9999" : 8885968.184724689, + "100.0" : 8885968.184724689 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8444694.48185654, + 8503047.969413763, + 8439101.735864978 + ], + [ + 8885968.184724689, + 8866356.618794326, + 8812079.36475771 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-04T06:34:06Z-309fa9df4d8fe7013cc2f85590ec8499c87a598f-jdk17.json b/performance-results/2025-07-04T06:34:06Z-309fa9df4d8fe7013cc2f85590ec8499c87a598f-jdk17.json new file mode 100644 index 0000000000..103870983c --- /dev/null +++ b/performance-results/2025-07-04T06:34:06Z-309fa9df4d8fe7013cc2f85590ec8499c87a598f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.310779230008781, + "scoreError" : 0.05632580666148456, + "scoreConfidence" : [ + 3.2544534233472966, + 3.3671050366702655 + ], + "scorePercentiles" : { + "0.0" : 3.3014928548718276, + "50.0" : 3.3114967271433793, + "90.0" : 3.318630610876537, + "95.0" : 3.318630610876537, + "99.0" : 3.318630610876537, + "99.9" : 3.318630610876537, + "99.99" : 3.318630610876537, + "99.999" : 3.318630610876537, + "99.9999" : 3.318630610876537, + "100.0" : 3.318630610876537 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3014928548718276, + 3.317782447881846 + ], + [ + 3.3052110064049125, + 3.318630610876537 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.666751293523411, + "scoreError" : 0.0561262389375135, + "scoreConfidence" : [ + 1.6106250545858976, + 1.7228775324609245 + ], + "scorePercentiles" : { + "0.0" : 1.6599736195078536, + "50.0" : 1.6643052774174847, + "90.0" : 1.6784209997508208, + "95.0" : 1.6784209997508208, + "99.0" : 1.6784209997508208, + "99.9" : 1.6784209997508208, + "99.99" : 1.6784209997508208, + "99.999" : 1.6784209997508208, + "99.9999" : 1.6784209997508208, + "100.0" : 1.6784209997508208 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6599736195078536, + 1.6602906840933942 + ], + [ + 1.6683198707415754, + 1.6784209997508208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8417482969892729, + "scoreError" : 0.023149148147354023, + "scoreConfidence" : [ + 0.8185991488419189, + 0.8648974451366269 + ], + "scorePercentiles" : { + "0.0" : 0.8377894734843169, + "50.0" : 0.8413580260699426, + "90.0" : 0.8464876623328894, + "95.0" : 0.8464876623328894, + "99.0" : 0.8464876623328894, + "99.9" : 0.8464876623328894, + "99.99" : 0.8464876623328894, + "99.999" : 0.8464876623328894, + "99.9999" : 0.8464876623328894, + "100.0" : 0.8464876623328894 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8377894734843169, + 0.8411828978264981 + ], + [ + 0.841533154313387, + 0.8464876623328894 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.889693198569367, + "scoreError" : 0.5775976886996227, + "scoreConfidence" : [ + 15.312095509869744, + 16.46729088726899 + ], + "scorePercentiles" : { + "0.0" : 15.691093648656713, + "50.0" : 15.893844337554953, + "90.0" : 16.08341958397121, + "95.0" : 16.08341958397121, + "99.0" : 16.08341958397121, + "99.9" : 16.08341958397121, + "99.99" : 16.08341958397121, + "99.999" : 16.08341958397121, + "99.9999" : 16.08341958397121, + "100.0" : 16.08341958397121 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.08341958397121, + 16.067222618682155, + 16.08162822569627 + ], + [ + 15.694329057982097, + 15.691093648656713, + 15.72046605642775 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2589.365066588849, + "scoreError" : 74.89636178891053, + "scoreConfidence" : [ + 2514.4687047999387, + 2664.2614283777593 + ], + "scorePercentiles" : { + "0.0" : 2558.990799096778, + "50.0" : 2589.8837581422927, + "90.0" : 2619.9599495184384, + "95.0" : 2619.9599495184384, + "99.0" : 2619.9599495184384, + "99.9" : 2619.9599495184384, + "99.99" : 2619.9599495184384, + "99.999" : 2619.9599495184384, + "99.9999" : 2619.9599495184384, + "100.0" : 2619.9599495184384 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2619.9599495184384, + 2609.431316398439, + 2610.4455581122666 + ], + [ + 2558.990799096778, + 2570.3361998861465, + 2567.0265765210233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75986.62216798366, + "scoreError" : 2421.5315160719383, + "scoreConfidence" : [ + 73565.09065191173, + 78408.1536840556 + ], + "scorePercentiles" : { + "0.0" : 75172.77276406018, + "50.0" : 75992.71742034989, + "90.0" : 76794.62769536201, + "95.0" : 76794.62769536201, + "99.0" : 76794.62769536201, + "99.9" : 76794.62769536201, + "99.99" : 76794.62769536201, + "99.999" : 76794.62769536201, + "99.9999" : 76794.62769536201, + "100.0" : 76794.62769536201 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76772.83721825983, + 76794.62769536201, + 76756.56724347614 + ], + [ + 75172.77276406018, + 75194.06048952017, + 75228.86759722362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 334.4355494104156, + "scoreError" : 4.688730227725187, + "scoreConfidence" : [ + 329.74681918269044, + 339.12427963814076 + ], + "scorePercentiles" : { + "0.0" : 331.8032716816492, + "50.0" : 334.6263901503445, + "90.0" : 336.14359413008856, + "95.0" : 336.14359413008856, + "99.0" : 336.14359413008856, + "99.9" : 336.14359413008856, + "99.99" : 336.14359413008856, + "99.999" : 336.14359413008856, + "99.9999" : 336.14359413008856, + "100.0" : 336.14359413008856 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 331.8032716816492, + 336.0002439131839, + 336.14359413008856 + ], + [ + 333.413406436883, + 335.1586057671727, + 334.0941745335163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 102.81566102614795, + "scoreError" : 7.317487885811224, + "scoreConfidence" : [ + 95.49817314033673, + 110.13314891195917 + ], + "scorePercentiles" : { + "0.0" : 100.01337366643226, + "50.0" : 102.8093900629585, + "90.0" : 106.00965306115933, + "95.0" : 106.00965306115933, + "99.0" : 106.00965306115933, + "99.9" : 106.00965306115933, + "99.99" : 106.00965306115933, + "99.999" : 106.00965306115933, + "99.9999" : 106.00965306115933, + "100.0" : 106.00965306115933 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.71390147623063, + 104.70711805361874, + 106.00965306115933 + ], + [ + 100.01337366643226, + 100.91166207229824, + 100.53825782714857 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06258784679799705, + "scoreError" : 3.6649498655505545E-4, + "scoreConfidence" : [ + 0.06222135181144199, + 0.0629543417845521 + ], + "scorePercentiles" : { + "0.0" : 0.06233805733770525, + "50.0" : 0.06261126664259425, + "90.0" : 0.06272414579347806, + "95.0" : 0.06272414579347806, + "99.0" : 0.06272414579347806, + "99.9" : 0.06272414579347806, + "99.99" : 0.06272414579347806, + "99.999" : 0.06272414579347806, + "99.9999" : 0.06272414579347806, + "100.0" : 0.06272414579347806 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06233805733770525, + 0.06261216871822485, + 0.06259756291038376 + ], + [ + 0.06272414579347806, + 0.06264478146122669, + 0.06261036456696364 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7058941333374613E-4, + "scoreError" : 1.8777290496220368E-5, + "scoreConfidence" : [ + 3.5181212283752575E-4, + 3.893667038299665E-4 + ], + "scorePercentiles" : { + "0.0" : 3.641316806545124E-4, + "50.0" : 3.707258980845138E-4, + "90.0" : 3.767821805799545E-4, + "95.0" : 3.767821805799545E-4, + "99.0" : 3.767821805799545E-4, + "99.9" : 3.767821805799545E-4, + "99.99" : 3.767821805799545E-4, + "99.999" : 3.767821805799545E-4, + "99.9999" : 3.767821805799545E-4, + "100.0" : 3.767821805799545E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6446115330064595E-4, + 3.641316806545124E-4, + 3.648484013812049E-4 + ], + [ + 3.767096692983364E-4, + 3.7660339478782264E-4, + 3.767821805799545E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12919006510917605, + "scoreError" : 0.0033714267349582833, + "scoreConfidence" : [ + 0.12581863837421778, + 0.13256149184413432 + ], + "scorePercentiles" : { + "0.0" : 0.12787845977084986, + "50.0" : 0.1292011989874538, + "90.0" : 0.1305010063552963, + "95.0" : 0.1305010063552963, + "99.0" : 0.1305010063552963, + "99.9" : 0.1305010063552963, + "99.99" : 0.1305010063552963, + "99.999" : 0.1305010063552963, + "99.9999" : 0.1305010063552963, + "100.0" : 0.1305010063552963 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13029987649189556, + 0.1300001108482288, + 0.1305010063552963 + ], + [ + 0.12787845977084986, + 0.1284022871266788, + 0.12805865006210704 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013142325704766785, + "scoreError" : 1.4502746199646733E-4, + "scoreConfidence" : [ + 0.012997298242770317, + 0.013287353166763253 + ], + "scorePercentiles" : { + "0.0" : 0.013074430222889299, + "50.0" : 0.013149246701169532, + "90.0" : 0.01319282479287599, + "95.0" : 0.01319282479287599, + "99.0" : 0.01319282479287599, + "99.9" : 0.01319282479287599, + "99.99" : 0.01319282479287599, + "99.999" : 0.01319282479287599, + "99.9999" : 0.01319282479287599, + "100.0" : 0.01319282479287599 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013187208180419161, + 0.01319282479287599, + 0.01318385634411494 + ], + [ + 0.013114637058224124, + 0.01310099763007719, + 0.013074430222889299 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.146450260032444, + "scoreError" : 0.19957128047526873, + "scoreConfidence" : [ + 0.9468789795571753, + 1.3460215405077127 + ], + "scorePercentiles" : { + "0.0" : 1.0802802871340607, + "50.0" : 1.1465256864386346, + "90.0" : 1.2124430883743484, + "95.0" : 1.2124430883743484, + "99.0" : 1.2124430883743484, + "99.9" : 1.2124430883743484, + "99.99" : 1.2124430883743484, + "99.999" : 1.2124430883743484, + "99.9999" : 1.2124430883743484, + "100.0" : 1.2124430883743484 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.081472527738726, + 1.08271344960485, + 1.0802802871340607 + ], + [ + 1.2103379232724192, + 1.2124430883743484, + 1.2114542840702605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011688679633861008, + "scoreError" : 4.275255013433637E-4, + "scoreConfidence" : [ + 0.011261154132517643, + 0.012116205135204372 + ], + "scorePercentiles" : { + "0.0" : 0.011516216362375887, + "50.0" : 0.011667033868928516, + "90.0" : 0.01190556935637871, + "95.0" : 0.01190556935637871, + "99.0" : 0.01190556935637871, + "99.9" : 0.01190556935637871, + "99.99" : 0.01190556935637871, + "99.999" : 0.01190556935637871, + "99.9999" : 0.01190556935637871, + "100.0" : 0.01190556935637871 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011585717285323694, + 0.011516216362375887, + 0.011575700893621947 + ], + [ + 0.011800523452932471, + 0.01190556935637871, + 0.01174835045253334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.342553598046463, + "scoreError" : 0.2278396912566572, + "scoreConfidence" : [ + 3.114713906789806, + 3.5703932893031203 + ], + "scorePercentiles" : { + "0.0" : 3.258577357654723, + "50.0" : 3.3412090617270733, + "90.0" : 3.4336416307481126, + "95.0" : 3.4336416307481126, + "99.0" : 3.4336416307481126, + "99.9" : 3.4336416307481126, + "99.99" : 3.4336416307481126, + "99.999" : 3.4336416307481126, + "99.9999" : 3.4336416307481126, + "100.0" : 3.4336416307481126 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.258577357654723, + 3.2817071207349082, + 3.2676639163945134 + ], + [ + 3.4336416307481126, + 3.4007110027192384, + 3.413020560027285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9932401162781663, + "scoreError" : 0.16033437025974975, + "scoreConfidence" : [ + 2.8329057460184166, + 3.153574486537916 + ], + "scorePercentiles" : { + "0.0" : 2.936681811215502, + "50.0" : 2.9908967706467626, + "90.0" : 3.0534030213675214, + "95.0" : 3.0534030213675214, + "99.0" : 3.0534030213675214, + "99.9" : 3.0534030213675214, + "99.99" : 3.0534030213675214, + "99.999" : 3.0534030213675214, + "99.9999" : 3.0534030213675214, + "100.0" : 3.0534030213675214 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0479379548918013, + 3.033616905975129, + 3.0534030213675214 + ], + [ + 2.9396243689006467, + 2.936681811215502, + 2.9481766353183962 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18327301452443348, + "scoreError" : 0.0314362583643107, + "scoreConfidence" : [ + 0.15183675616012277, + 0.2147092728887442 + ], + "scorePercentiles" : { + "0.0" : 0.17296033679822892, + "50.0" : 0.1832540174683389, + "90.0" : 0.19355382371385438, + "95.0" : 0.19355382371385438, + "99.0" : 0.19355382371385438, + "99.9" : 0.19355382371385438, + "99.99" : 0.19355382371385438, + "99.999" : 0.19355382371385438, + "99.9999" : 0.19355382371385438, + "100.0" : 0.19355382371385438 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19342033170863795, + 0.19355382371385438, + 0.19354552522789292 + ], + [ + 0.17308770322803982, + 0.17307036646994686, + 0.17296033679822892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3221902224486494, + "scoreError" : 0.009116362867446095, + "scoreConfidence" : [ + 0.3130738595812033, + 0.3313065853160955 + ], + "scorePercentiles" : { + "0.0" : 0.31915992965882617, + "50.0" : 0.3220608809609805, + "90.0" : 0.3258501210492017, + "95.0" : 0.3258501210492017, + "99.0" : 0.3258501210492017, + "99.9" : 0.3258501210492017, + "99.99" : 0.3258501210492017, + "99.999" : 0.3258501210492017, + "99.9999" : 0.3258501210492017, + "100.0" : 0.3258501210492017 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31940817595579546, + 0.31915992965882617, + 0.31916830406613045 + ], + [ + 0.3258501210492017, + 0.32471358596616556, + 0.32484121799577714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1449397669593481, + "scoreError" : 4.4980405135949336E-4, + "scoreConfidence" : [ + 0.1444899629079886, + 0.1453895710107076 + ], + "scorePercentiles" : { + "0.0" : 0.14469883416532825, + "50.0" : 0.14496806129135137, + "90.0" : 0.14516775397389928, + "95.0" : 0.14516775397389928, + "99.0" : 0.14516775397389928, + "99.9" : 0.14516775397389928, + "99.99" : 0.14516775397389928, + "99.999" : 0.14516775397389928, + "99.9999" : 0.14516775397389928, + "100.0" : 0.14516775397389928 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14496843625873415, + 0.1450075766776869, + 0.14469883416532825 + ], + [ + 0.14516775397389928, + 0.1448283143564715, + 0.14496768632396856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40339714281684064, + "scoreError" : 0.0033643665607053994, + "scoreConfidence" : [ + 0.40003277625613526, + 0.406761509377546 + ], + "scorePercentiles" : { + "0.0" : 0.4018458712930965, + "50.0" : 0.403458428500145, + "90.0" : 0.40473725372349034, + "95.0" : 0.40473725372349034, + "99.0" : 0.40473725372349034, + "99.9" : 0.40473725372349034, + "99.99" : 0.40473725372349034, + "99.999" : 0.40473725372349034, + "99.9999" : 0.40473725372349034, + "100.0" : 0.40473725372349034 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40463937751881524, + 0.40473725372349034, + 0.4032204272005161 + ], + [ + 0.40369642979977394, + 0.40224349736535137, + 0.4018458712930965 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15570504805497148, + "scoreError" : 8.215578599921024E-4, + "scoreConfidence" : [ + 0.15488349019497938, + 0.1565266059149636 + ], + "scorePercentiles" : { + "0.0" : 0.15546321660318693, + "50.0" : 0.15561148094989805, + "90.0" : 0.15624039546910398, + "95.0" : 0.15624039546910398, + "99.0" : 0.15624039546910398, + "99.9" : 0.15624039546910398, + "99.99" : 0.15624039546910398, + "99.999" : 0.15624039546910398, + "99.9999" : 0.15624039546910398, + "100.0" : 0.15624039546910398 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15558667097627382, + 0.1558246208084019, + 0.15547909354934 + ], + [ + 0.15563629092352227, + 0.15624039546910398, + 0.15546321660318693 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0471531086801415, + "scoreError" : 0.0022651536142112025, + "scoreConfidence" : [ + 0.044887955065930296, + 0.0494182622943527 + ], + "scorePercentiles" : { + "0.0" : 0.046358381305803054, + "50.0" : 0.047195712627227826, + "90.0" : 0.04791857923714601, + "95.0" : 0.04791857923714601, + "99.0" : 0.04791857923714601, + "99.9" : 0.04791857923714601, + "99.99" : 0.04791857923714601, + "99.999" : 0.04791857923714601, + "99.9999" : 0.04791857923714601, + "100.0" : 0.04791857923714601 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04791857923714601, + 0.04787348356767056, + 0.04787380796131843 + ], + [ + 0.04637645832212586, + 0.046358381305803054, + 0.0465179416867851 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8852045.93074288, + "scoreError" : 321094.2552875456, + "scoreConfidence" : [ + 8530951.675455336, + 9173140.186030425 + ], + "scorePercentiles" : { + "0.0" : 8733761.735602094, + "50.0" : 8843992.989574993, + "90.0" : 8984241.272890484, + "95.0" : 8984241.272890484, + "99.0" : 8984241.272890484, + "99.9" : 8984241.272890484, + "99.99" : 8984241.272890484, + "99.999" : 8984241.272890484, + "99.9999" : 8984241.272890484, + "100.0" : 8984241.272890484 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8929840.326785713, + 8951171.166368514, + 8984241.272890484 + ], + [ + 8758145.652364273, + 8733761.735602094, + 8755115.430446194 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-04T06:34:37Z-309fa9df4d8fe7013cc2f85590ec8499c87a598f-jdk17.json b/performance-results/2025-07-04T06:34:37Z-309fa9df4d8fe7013cc2f85590ec8499c87a598f-jdk17.json new file mode 100644 index 0000000000..cbb9bbb787 --- /dev/null +++ b/performance-results/2025-07-04T06:34:37Z-309fa9df4d8fe7013cc2f85590ec8499c87a598f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3223905606245654, + "scoreError" : 0.04660683881217576, + "scoreConfidence" : [ + 3.2757837218123895, + 3.3689973994367413 + ], + "scorePercentiles" : { + "0.0" : 3.3153268654854235, + "50.0" : 3.321717620309384, + "90.0" : 3.330800136394071, + "95.0" : 3.330800136394071, + "99.0" : 3.330800136394071, + "99.9" : 3.330800136394071, + "99.99" : 3.330800136394071, + "99.999" : 3.330800136394071, + "99.9999" : 3.330800136394071, + "100.0" : 3.330800136394071 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3153268654854235, + 3.3258731156054853 + ], + [ + 3.317562125013282, + 3.330800136394071 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6693352423556278, + "scoreError" : 0.02304713508133312, + "scoreConfidence" : [ + 1.6462881072742948, + 1.6923823774369608 + ], + "scorePercentiles" : { + "0.0" : 1.6660048478741867, + "50.0" : 1.6686773116501616, + "90.0" : 1.6739814982480017, + "95.0" : 1.6739814982480017, + "99.0" : 1.6739814982480017, + "99.9" : 1.6739814982480017, + "99.99" : 1.6739814982480017, + "99.999" : 1.6739814982480017, + "99.9999" : 1.6739814982480017, + "100.0" : 1.6739814982480017 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6660048478741867, + 1.6671580534940376 + ], + [ + 1.6701965698062857, + 1.6739814982480017 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8445951317899303, + "scoreError" : 0.032592002874542454, + "scoreConfidence" : [ + 0.8120031289153878, + 0.8771871346644727 + ], + "scorePercentiles" : { + "0.0" : 0.8377154222416822, + "50.0" : 0.8455350837476133, + "90.0" : 0.8495949374228121, + "95.0" : 0.8495949374228121, + "99.0" : 0.8495949374228121, + "99.9" : 0.8495949374228121, + "99.99" : 0.8495949374228121, + "99.999" : 0.8495949374228121, + "99.9999" : 0.8495949374228121, + "100.0" : 0.8495949374228121 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8377154222416822, + 0.8495949374228121 + ], + [ + 0.8444815914506458, + 0.8465885760445808 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.173252376025662, + "scoreError" : 0.06897577074273747, + "scoreConfidence" : [ + 16.104276605282923, + 16.2422281467684 + ], + "scorePercentiles" : { + "0.0" : 16.14354257638967, + "50.0" : 16.168215835480993, + "90.0" : 16.210500225703527, + "95.0" : 16.210500225703527, + "99.0" : 16.210500225703527, + "99.9" : 16.210500225703527, + "99.99" : 16.210500225703527, + "99.999" : 16.210500225703527, + "99.9999" : 16.210500225703527, + "100.0" : 16.210500225703527 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.191202650288258, + 16.210500225703527, + 16.157837132810545 + ], + [ + 16.15971535434042, + 16.17671631662157, + 16.14354257638967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2668.7630844816576, + "scoreError" : 174.5413703452925, + "scoreConfidence" : [ + 2494.2217141363653, + 2843.30445482695 + ], + "scorePercentiles" : { + "0.0" : 2609.073030535963, + "50.0" : 2667.7424280206706, + "90.0" : 2731.349677333966, + "95.0" : 2731.349677333966, + "99.0" : 2731.349677333966, + "99.9" : 2731.349677333966, + "99.99" : 2731.349677333966, + "99.999" : 2731.349677333966, + "99.9999" : 2731.349677333966, + "100.0" : 2731.349677333966 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2731.349677333966, + 2720.8236736229237, + 2724.2522313854774 + ], + [ + 2609.073030535963, + 2614.661182418417, + 2612.4187115932 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75742.48719679959, + "scoreError" : 4135.892610707586, + "scoreConfidence" : [ + 71606.594586092, + 79878.37980750717 + ], + "scorePercentiles" : { + "0.0" : 74348.41445572967, + "50.0" : 75744.43637060063, + "90.0" : 77145.0533807753, + "95.0" : 77145.0533807753, + "99.0" : 77145.0533807753, + "99.9" : 77145.0533807753, + "99.99" : 77145.0533807753, + "99.999" : 77145.0533807753, + "99.9999" : 77145.0533807753, + "100.0" : 77145.0533807753 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77145.0533807753, + 77076.19330417206, + 77043.52213030799 + ], + [ + 74396.38929891931, + 74445.35061089325, + 74348.41445572967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 358.0378898729861, + "scoreError" : 28.021606321459128, + "scoreConfidence" : [ + 330.016283551527, + 386.0594961944452 + ], + "scorePercentiles" : { + "0.0" : 346.9356405937976, + "50.0" : 359.31071294658034, + "90.0" : 367.31059450762643, + "95.0" : 367.31059450762643, + "99.0" : 367.31059450762643, + "99.9" : 367.31059450762643, + "99.99" : 367.31059450762643, + "99.999" : 367.31059450762643, + "99.9999" : 367.31059450762643, + "100.0" : 367.31059450762643 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.9356405937976, + 348.3098404854241, + 351.86274547623447 + ], + [ + 367.04983775790754, + 366.7586804169262, + 367.31059450762643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.66095399613873, + "scoreError" : 4.094370353186251, + "scoreConfidence" : [ + 108.56658364295248, + 116.75532434932498 + ], + "scorePercentiles" : { + "0.0" : 111.24146703162218, + "50.0" : 112.61082406822008, + "90.0" : 114.24459238946798, + "95.0" : 114.24459238946798, + "99.0" : 114.24459238946798, + "99.9" : 114.24459238946798, + "99.99" : 114.24459238946798, + "99.999" : 114.24459238946798, + "99.9999" : 114.24459238946798, + "100.0" : 114.24459238946798 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.24146703162218, + 111.41053965399706, + 111.35463470086697 + ], + [ + 113.8111084824431, + 114.24459238946798, + 113.90338171843511 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06261099082401529, + "scoreError" : 4.956520780921011E-4, + "scoreConfidence" : [ + 0.06211533874592319, + 0.0631066429021074 + ], + "scorePercentiles" : { + "0.0" : 0.06241721383765565, + "50.0" : 0.06260167198997668, + "90.0" : 0.06288100587299492, + "95.0" : 0.06288100587299492, + "99.0" : 0.06288100587299492, + "99.9" : 0.06288100587299492, + "99.99" : 0.06288100587299492, + "99.999" : 0.06288100587299492, + "99.9999" : 0.06288100587299492, + "100.0" : 0.06288100587299492 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0625102763039456, + 0.06246554190429193, + 0.06241721383765565 + ], + [ + 0.0626988393491959, + 0.06288100587299492, + 0.06269306767600777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.912288169450611E-4, + "scoreError" : 3.0339665385459026E-6, + "scoreConfidence" : [ + 3.881948504065152E-4, + 3.94262783483607E-4 + ], + "scorePercentiles" : { + "0.0" : 3.8996756928150514E-4, + "50.0" : 3.912044322116263E-4, + "90.0" : 3.929956763891778E-4, + "95.0" : 3.929956763891778E-4, + "99.0" : 3.929956763891778E-4, + "99.9" : 3.929956763891778E-4, + "99.99" : 3.929956763891778E-4, + "99.999" : 3.929956763891778E-4, + "99.9999" : 3.929956763891778E-4, + "100.0" : 3.929956763891778E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8996756928150514E-4, + 3.9029854779935077E-4, + 3.910467485029898E-4 + ], + [ + 3.917022437770805E-4, + 3.913621159202627E-4, + 3.929956763891778E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12800446240427837, + "scoreError" : 0.0029370367734169174, + "scoreConfidence" : [ + 0.12506742563086146, + 0.1309414991776953 + ], + "scorePercentiles" : { + "0.0" : 0.12681882571588, + "50.0" : 0.12792656396328667, + "90.0" : 0.1291921476242152, + "95.0" : 0.1291921476242152, + "99.0" : 0.1291921476242152, + "99.9" : 0.1291921476242152, + "99.99" : 0.1291921476242152, + "99.999" : 0.1291921476242152, + "99.9999" : 0.1291921476242152, + "100.0" : 0.1291921476242152 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1271791801302269, + 0.12681882571588, + 0.1272135002798626 + ], + [ + 0.12898349302877485, + 0.12863962764671075, + 0.1291921476242152 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013311272714631728, + "scoreError" : 8.532200436913206E-5, + "scoreConfidence" : [ + 0.013225950710262595, + 0.01339659471900086 + ], + "scorePercentiles" : { + "0.0" : 0.013270442549007118, + "50.0" : 0.013312601687575615, + "90.0" : 0.013345328956130553, + "95.0" : 0.013345328956130553, + "99.0" : 0.013345328956130553, + "99.9" : 0.013345328956130553, + "99.99" : 0.013345328956130553, + "99.999" : 0.013345328956130553, + "99.9999" : 0.013345328956130553, + "100.0" : 0.013345328956130553 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013289629892514844, + 0.013294346347890014, + 0.013270442549007118 + ], + [ + 0.013330857027261214, + 0.013337031514986624, + 0.013345328956130553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9535213620939125, + "scoreError" : 0.002705721874497277, + "scoreConfidence" : [ + 0.9508156402194152, + 0.9562270839684097 + ], + "scorePercentiles" : { + "0.0" : 0.951957043407901, + "50.0" : 0.9534785772700956, + "90.0" : 0.9548349386098911, + "95.0" : 0.9548349386098911, + "99.0" : 0.9548349386098911, + "99.9" : 0.9548349386098911, + "99.99" : 0.9548349386098911, + "99.999" : 0.9548349386098911, + "99.9999" : 0.9548349386098911, + "100.0" : 0.9548349386098911 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9535449720633105, + 0.9548349386098911, + 0.9534121824768805 + ], + [ + 0.9532348626441712, + 0.951957043407901, + 0.9541441733613205 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01113306117699941, + "scoreError" : 1.9031839852077574E-4, + "scoreConfidence" : [ + 0.010942742778478634, + 0.011323379575520185 + ], + "scorePercentiles" : { + "0.0" : 0.01106317554833271, + "50.0" : 0.011130154172857747, + "90.0" : 0.011220509855886828, + "95.0" : 0.011220509855886828, + "99.0" : 0.011220509855886828, + "99.9" : 0.011220509855886828, + "99.99" : 0.011220509855886828, + "99.999" : 0.011220509855886828, + "99.9999" : 0.011220509855886828, + "100.0" : 0.011220509855886828 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011066711058435033, + 0.011090787498280963, + 0.01106317554833271 + ], + [ + 0.011187662253626383, + 0.011220509855886828, + 0.011169520847434531 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1710597358200108, + "scoreError" : 0.12612005924033698, + "scoreConfidence" : [ + 3.044939676579674, + 3.2971797950603476 + ], + "scorePercentiles" : { + "0.0" : 3.120866799750468, + "50.0" : 3.172580523095402, + "90.0" : 3.224539889748549, + "95.0" : 3.224539889748549, + "99.0" : 3.224539889748549, + "99.9" : 3.224539889748549, + "99.99" : 3.224539889748549, + "99.999" : 3.224539889748549, + "99.9999" : 3.224539889748549, + "100.0" : 3.224539889748549 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.199296238643634, + 3.224539889748549, + 3.208407477228993 + ], + [ + 3.120866799750468, + 3.14586480754717, + 3.127383202001251 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8481420019271595, + "scoreError" : 0.015357709176996354, + "scoreConfidence" : [ + 2.832784292750163, + 2.863499711104156 + ], + "scorePercentiles" : { + "0.0" : 2.84049393638171, + "50.0" : 2.8495964757901544, + "90.0" : 2.8534116393723252, + "95.0" : 2.8534116393723252, + "99.0" : 2.8534116393723252, + "99.9" : 2.8534116393723252, + "99.99" : 2.8534116393723252, + "99.999" : 2.8534116393723252, + "99.9999" : 2.8534116393723252, + "100.0" : 2.8534116393723252 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.843070857873792, + 2.852160150270887, + 2.84049393638171 + ], + [ + 2.8534116393723252, + 2.85268262635482, + 2.847032801309422 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18168995026015697, + "scoreError" : 0.008528871812957278, + "scoreConfidence" : [ + 0.1731610784471997, + 0.19021882207311425 + ], + "scorePercentiles" : { + "0.0" : 0.17923422871634942, + "50.0" : 0.18078582189119435, + "90.0" : 0.18674005223058393, + "95.0" : 0.18674005223058393, + "99.0" : 0.18674005223058393, + "99.9" : 0.18674005223058393, + "99.99" : 0.18674005223058393, + "99.999" : 0.18674005223058393, + "99.9999" : 0.18674005223058393, + "100.0" : 0.18674005223058393 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18674005223058393, + 0.18225354017458495, + 0.1833543812981298 + ], + [ + 0.17931810360780376, + 0.17923939553348986, + 0.17923422871634942 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32434916561988625, + "scoreError" : 0.004825802250987568, + "scoreConfidence" : [ + 0.3195233633688987, + 0.3291749678708738 + ], + "scorePercentiles" : { + "0.0" : 0.322592585483871, + "50.0" : 0.3243666415269308, + "90.0" : 0.326057949462015, + "95.0" : 0.326057949462015, + "99.0" : 0.326057949462015, + "99.9" : 0.326057949462015, + "99.99" : 0.326057949462015, + "99.999" : 0.326057949462015, + "99.9999" : 0.326057949462015, + "100.0" : 0.326057949462015 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.326057949462015, + 0.32586196822965885, + 0.32582667330248927 + ], + [ + 0.3228492074899112, + 0.322592585483871, + 0.3229066097513723 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14140108751100935, + "scoreError" : 0.00235294349197454, + "scoreConfidence" : [ + 0.13904814401903481, + 0.1437540310029839 + ], + "scorePercentiles" : { + "0.0" : 0.1405672350650811, + "50.0" : 0.1414246343504953, + "90.0" : 0.14219950264482553, + "95.0" : 0.14219950264482553, + "99.0" : 0.14219950264482553, + "99.9" : 0.14219950264482553, + "99.99" : 0.14219950264482553, + "99.999" : 0.14219950264482553, + "99.9999" : 0.14219950264482553, + "100.0" : 0.14219950264482553 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14060492660602056, + 0.140740130673422, + 0.1405672350650811 + ], + [ + 0.14219950264482553, + 0.14218559204913836, + 0.14210913802756855 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4021932146886104, + "scoreError" : 0.008033109536830998, + "scoreConfidence" : [ + 0.3941601051517794, + 0.4102263242254414 + ], + "scorePercentiles" : { + "0.0" : 0.397637907391944, + "50.0" : 0.4022633405586866, + "90.0" : 0.4064574175337344, + "95.0" : 0.4064574175337344, + "99.0" : 0.4064574175337344, + "99.9" : 0.4064574175337344, + "99.99" : 0.4064574175337344, + "99.999" : 0.4064574175337344, + "99.9999" : 0.4064574175337344, + "100.0" : 0.4064574175337344 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4012538257834129, + 0.4023553053834393, + 0.397637907391944 + ], + [ + 0.4032834563051982, + 0.4064574175337344, + 0.4021713757339339 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15751860517048544, + "scoreError" : 0.007590748094782307, + "scoreConfidence" : [ + 0.14992785707570314, + 0.16510935326526774 + ], + "scorePercentiles" : { + "0.0" : 0.15514829899466304, + "50.0" : 0.15683363652669063, + "90.0" : 0.16145503568026606, + "95.0" : 0.16145503568026606, + "99.0" : 0.16145503568026606, + "99.9" : 0.16145503568026606, + "99.99" : 0.16145503568026606, + "99.999" : 0.16145503568026606, + "99.9999" : 0.16145503568026606, + "100.0" : 0.16145503568026606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1553055947104409, + 0.15514829899466304, + 0.15519608063815257 + ], + [ + 0.16145503568026606, + 0.15964494265644955, + 0.1583616783429404 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04713011408296786, + "scoreError" : 0.001990847566553604, + "scoreConfidence" : [ + 0.045139266516414256, + 0.04912096164952147 + ], + "scorePercentiles" : { + "0.0" : 0.04647591019575401, + "50.0" : 0.04700599101631811, + "90.0" : 0.04826770737322741, + "95.0" : 0.04826770737322741, + "99.0" : 0.04826770737322741, + "99.9" : 0.04826770737322741, + "99.99" : 0.04826770737322741, + "99.999" : 0.04826770737322741, + "99.9999" : 0.04826770737322741, + "100.0" : 0.04826770737322741 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04826770737322741, + 0.04752489379336565, + 0.04733356942031798 + ], + [ + 0.046500191102823905, + 0.04647591019575401, + 0.04667841261231825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8602079.70534184, + "scoreError" : 133472.1860724081, + "scoreConfidence" : [ + 8468607.519269433, + 8735551.891414247 + ], + "scorePercentiles" : { + "0.0" : 8557229.815226689, + "50.0" : 8591195.367993671, + "90.0" : 8693881.691572545, + "95.0" : 8693881.691572545, + "99.0" : 8693881.691572545, + "99.9" : 8693881.691572545, + "99.99" : 8693881.691572545, + "99.999" : 8693881.691572545, + "99.9999" : 8693881.691572545, + "100.0" : 8693881.691572545 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8693881.691572545, + 8601898.160791058, + 8557229.815226689 + ], + [ + 8587561.310729614, + 8577077.828473413, + 8594829.425257731 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-05T00:46:34Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json b/performance-results/2025-07-05T00:46:34Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json new file mode 100644 index 0000000000..5e2b0f9f12 --- /dev/null +++ b/performance-results/2025-07-05T00:46:34Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.312495434793269, + "scoreError" : 0.055104365981316086, + "scoreConfidence" : [ + 3.257391068811953, + 3.367599800774585 + ], + "scorePercentiles" : { + "0.0" : 3.3050152389032688, + "50.0" : 3.311346978562999, + "90.0" : 3.3222725431438107, + "95.0" : 3.3222725431438107, + "99.0" : 3.3222725431438107, + "99.9" : 3.3222725431438107, + "99.99" : 3.3222725431438107, + "99.999" : 3.3222725431438107, + "99.9999" : 3.3222725431438107, + "100.0" : 3.3222725431438107 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3050152389032688, + 3.3222725431438107 + ], + [ + 3.3056914624945657, + 3.317002494631432 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6712549644739547, + "scoreError" : 0.035683691083668014, + "scoreConfidence" : [ + 1.6355712733902867, + 1.7069386555576227 + ], + "scorePercentiles" : { + "0.0" : 1.666553392993196, + "50.0" : 1.6700889832309609, + "90.0" : 1.6782884984407014, + "95.0" : 1.6782884984407014, + "99.0" : 1.6782884984407014, + "99.9" : 1.6782884984407014, + "99.99" : 1.6782884984407014, + "99.999" : 1.6782884984407014, + "99.9999" : 1.6782884984407014, + "100.0" : 1.6782884984407014 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.673020370099939, + 1.6782884984407014 + ], + [ + 1.666553392993196, + 1.6671575963619825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8404361628264534, + "scoreError" : 0.044951627981280426, + "scoreConfidence" : [ + 0.795484534845173, + 0.8853877908077338 + ], + "scorePercentiles" : { + "0.0" : 0.8325612977001957, + "50.0" : 0.8398510572580533, + "90.0" : 0.8494812390895119, + "95.0" : 0.8494812390895119, + "99.0" : 0.8494812390895119, + "99.9" : 0.8494812390895119, + "99.99" : 0.8494812390895119, + "99.999" : 0.8494812390895119, + "99.9999" : 0.8494812390895119, + "100.0" : 0.8494812390895119 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8325612977001957, + 0.8392768975003958 + ], + [ + 0.8404252170157107, + 0.8494812390895119 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.07533284505306, + "scoreError" : 0.2029903731494133, + "scoreConfidence" : [ + 15.872342471903648, + 16.278323218202473 + ], + "scorePercentiles" : { + "0.0" : 15.995141955173379, + "50.0" : 16.077282909125962, + "90.0" : 16.177113482289982, + "95.0" : 16.177113482289982, + "99.0" : 16.177113482289982, + "99.9" : 16.177113482289982, + "99.99" : 16.177113482289982, + "99.999" : 16.177113482289982, + "99.9999" : 16.177113482289982, + "100.0" : 16.177113482289982 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.995141955173379, + 16.12307419459052, + 16.002101620012564 + ], + [ + 16.047611247972185, + 16.106954570279736, + 16.177113482289982 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2583.231976407065, + "scoreError" : 84.4780047733168, + "scoreConfidence" : [ + 2498.753971633748, + 2667.709981180382 + ], + "scorePercentiles" : { + "0.0" : 2545.3753576371155, + "50.0" : 2582.7853455531163, + "90.0" : 2623.4845593923255, + "95.0" : 2623.4845593923255, + "99.0" : 2623.4845593923255, + "99.9" : 2623.4845593923255, + "99.99" : 2623.4845593923255, + "99.999" : 2623.4845593923255, + "99.9999" : 2623.4845593923255, + "100.0" : 2623.4845593923255 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2570.1220700462004, + 2558.375222019917, + 2545.3753576371155 + ], + [ + 2623.4845593923255, + 2606.5860282867975, + 2595.448621060032 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74507.7330081277, + "scoreError" : 6349.067345176075, + "scoreConfidence" : [ + 68158.66566295162, + 80856.80035330378 + ], + "scorePercentiles" : { + "0.0" : 72276.89683772357, + "50.0" : 74588.97297555914, + "90.0" : 76635.05449644031, + "95.0" : 76635.05449644031, + "99.0" : 76635.05449644031, + "99.9" : 76635.05449644031, + "99.99" : 76635.05449644031, + "99.999" : 76635.05449644031, + "99.9999" : 76635.05449644031, + "100.0" : 76635.05449644031 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72356.80308243849, + 72276.89683772357, + 72703.0414909472 + ], + [ + 76635.05449644031, + 76599.69768104557, + 76474.90446017108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 344.6507038869407, + "scoreError" : 10.780100333105285, + "scoreConfidence" : [ + 333.8706035538354, + 355.43080422004596 + ], + "scorePercentiles" : { + "0.0" : 340.55136415692795, + "50.0" : 344.64557895956494, + "90.0" : 349.46117353566774, + "95.0" : 349.46117353566774, + "99.0" : 349.46117353566774, + "99.9" : 349.46117353566774, + "99.99" : 349.46117353566774, + "99.999" : 349.46117353566774, + "99.9999" : 349.46117353566774, + "100.0" : 349.46117353566774 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 342.5770716934263, + 340.75453271379456, + 340.55136415692795 + ], + [ + 346.71408622570357, + 347.84599499612386, + 349.46117353566774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 110.24589481871557, + "scoreError" : 3.5021685470376376, + "scoreConfidence" : [ + 106.74372627167793, + 113.74806336575321 + ], + "scorePercentiles" : { + "0.0" : 108.86793358159755, + "50.0" : 110.06584872014065, + "90.0" : 111.81348743369448, + "95.0" : 111.81348743369448, + "99.0" : 111.81348743369448, + "99.9" : 111.81348743369448, + "99.99" : 111.81348743369448, + "99.999" : 111.81348743369448, + "99.9999" : 111.81348743369448, + "100.0" : 111.81348743369448 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.81348743369448, + 109.76107559440356, + 110.37062184587775 + ], + [ + 109.07065205425394, + 111.59159840246619, + 108.86793358159755 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06291075132999228, + "scoreError" : 9.081578740106059E-4, + "scoreConfidence" : [ + 0.06200259345598168, + 0.06381890920400289 + ], + "scorePercentiles" : { + "0.0" : 0.06258517562645505, + "50.0" : 0.06276471809176434, + "90.0" : 0.06342224443796139, + "95.0" : 0.06342224443796139, + "99.0" : 0.06342224443796139, + "99.9" : 0.06342224443796139, + "99.99" : 0.06342224443796139, + "99.999" : 0.06342224443796139, + "99.9999" : 0.06342224443796139, + "100.0" : 0.06342224443796139 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06342224443796139, + 0.06319625503665319, + 0.06274950428573221 + ], + [ + 0.06273139669535543, + 0.06258517562645505, + 0.06277993189779647 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7018960618612613E-4, + "scoreError" : 1.1382248546367458E-5, + "scoreConfidence" : [ + 3.588073576397587E-4, + 3.815718547324936E-4 + ], + "scorePercentiles" : { + "0.0" : 3.660308912564523E-4, + "50.0" : 3.691559065803218E-4, + "90.0" : 3.767173440400918E-4, + "95.0" : 3.767173440400918E-4, + "99.0" : 3.767173440400918E-4, + "99.9" : 3.767173440400918E-4, + "99.99" : 3.767173440400918E-4, + "99.999" : 3.767173440400918E-4, + "99.9999" : 3.767173440400918E-4, + "100.0" : 3.767173440400918E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.660308912564523E-4, + 3.668596297509768E-4, + 3.6896201069406496E-4 + ], + [ + 3.767173440400918E-4, + 3.7321795890859225E-4, + 3.6934980246657864E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12810017113405692, + "scoreError" : 5.925426798072235E-4, + "scoreConfidence" : [ + 0.1275076284542497, + 0.12869271381386413 + ], + "scorePercentiles" : { + "0.0" : 0.12770335411452213, + "50.0" : 0.12817685138292834, + "90.0" : 0.128260545993228, + "95.0" : 0.128260545993228, + "99.0" : 0.128260545993228, + "99.9" : 0.128260545993228, + "99.99" : 0.128260545993228, + "99.999" : 0.128260545993228, + "99.9999" : 0.128260545993228, + "100.0" : 0.128260545993228 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1282530472727739, + 0.12803037665796077, + 0.12818259966673076 + ], + [ + 0.12770335411452213, + 0.12817110309912588, + 0.128260545993228 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013118787104508674, + "scoreError" : 9.695854494899747E-5, + "scoreConfidence" : [ + 0.013021828559559677, + 0.013215745649457671 + ], + "scorePercentiles" : { + "0.0" : 0.01305034815177319, + "50.0" : 0.01313271395440551, + "90.0" : 0.013140213319264736, + "95.0" : 0.013140213319264736, + "99.0" : 0.013140213319264736, + "99.9" : 0.013140213319264736, + "99.99" : 0.013140213319264736, + "99.999" : 0.013140213319264736, + "99.9999" : 0.013140213319264736, + "100.0" : 0.013140213319264736 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013140213319264736, + 0.013116909089716668, + 0.01305034815177319 + ], + [ + 0.01313328339554052, + 0.0131321445132705, + 0.01313982415748644 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9996355470203412, + "scoreError" : 0.028902186328048883, + "scoreConfidence" : [ + 0.9707333606922923, + 1.02853773334839 + ], + "scorePercentiles" : { + "0.0" : 0.9876470546118902, + "50.0" : 0.999253798628897, + "90.0" : 1.0117724146094698, + "95.0" : 1.0117724146094698, + "99.0" : 1.0117724146094698, + "99.9" : 1.0117724146094698, + "99.99" : 1.0117724146094698, + "99.999" : 1.0117724146094698, + "99.9999" : 1.0117724146094698, + "100.0" : 1.0117724146094698 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0058027616413556, + 1.00871420929998, + 1.0117724146094698 + ], + [ + 0.9927048356164384, + 0.9911720063429138, + 0.9876470546118902 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01121098501109073, + "scoreError" : 7.257903194991022E-4, + "scoreConfidence" : [ + 0.010485194691591627, + 0.011936775330589833 + ], + "scorePercentiles" : { + "0.0" : 0.01093589604808178, + "50.0" : 0.011214258542165284, + "90.0" : 0.011465852192337768, + "95.0" : 0.011465852192337768, + "99.0" : 0.011465852192337768, + "99.9" : 0.011465852192337768, + "99.99" : 0.011465852192337768, + "99.999" : 0.011465852192337768, + "99.9999" : 0.011465852192337768, + "100.0" : 0.011465852192337768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011440626980894635, + 0.011465852192337768, + 0.011432110453657935 + ], + [ + 0.010996406630672634, + 0.010995017760899634, + 0.01093589604808178 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3774034778582434, + "scoreError" : 0.30080554099110474, + "scoreConfidence" : [ + 3.0765979368671386, + 3.678209018849348 + ], + "scorePercentiles" : { + "0.0" : 3.2649472088772846, + "50.0" : 3.3779815823879358, + "90.0" : 3.4924981766759777, + "95.0" : 3.4924981766759777, + "99.0" : 3.4924981766759777, + "99.9" : 3.4924981766759777, + "99.99" : 3.4924981766759777, + "99.999" : 3.4924981766759777, + "99.9999" : 3.4924981766759777, + "100.0" : 3.4924981766759777 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2649472088772846, + 3.3047389729194188, + 3.2732701583769632 + ], + [ + 3.4924981766759777, + 3.4777421584433634, + 3.451224191856453 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9220159821461387, + "scoreError" : 0.09270550202631823, + "scoreConfidence" : [ + 2.8293104801198203, + 3.014721484172457 + ], + "scorePercentiles" : { + "0.0" : 2.8892281695551705, + "50.0" : 2.914053094703559, + "90.0" : 2.983260933492395, + "95.0" : 2.983260933492395, + "99.0" : 2.983260933492395, + "99.9" : 2.983260933492395, + "99.99" : 2.983260933492395, + "99.999" : 2.983260933492395, + "99.9999" : 2.983260933492395, + "100.0" : 2.983260933492395 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.930189960445356, + 2.911190788998836, + 2.9169154004082825 + ], + [ + 2.9013106399767916, + 2.8892281695551705, + 2.983260933492395 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17737929883037862, + "scoreError" : 0.0037697458153534524, + "scoreConfidence" : [ + 0.17360955301502518, + 0.18114904464573206 + ], + "scorePercentiles" : { + "0.0" : 0.17593688344475722, + "50.0" : 0.177344208263511, + "90.0" : 0.17904414562967738, + "95.0" : 0.17904414562967738, + "99.0" : 0.17904414562967738, + "99.9" : 0.17904414562967738, + "99.99" : 0.17904414562967738, + "99.999" : 0.17904414562967738, + "99.9999" : 0.17904414562967738, + "100.0" : 0.17904414562967738 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17649124339492772, + 0.17613812937032144, + 0.17593688344475722 + ], + [ + 0.17904414562967738, + 0.1781971731320943, + 0.17846821801049362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32062561056588973, + "scoreError" : 0.002561009998316468, + "scoreConfidence" : [ + 0.31806460056757324, + 0.3231866205642062 + ], + "scorePercentiles" : { + "0.0" : 0.3194193083556918, + "50.0" : 0.32051917450705214, + "90.0" : 0.321804870092676, + "95.0" : 0.321804870092676, + "99.0" : 0.321804870092676, + "99.9" : 0.321804870092676, + "99.99" : 0.321804870092676, + "99.999" : 0.321804870092676, + "99.9999" : 0.321804870092676, + "100.0" : 0.321804870092676 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3194193083556918, + 0.3205667761251442, + 0.31994913130278985 + ], + [ + 0.3204715728889601, + 0.321804870092676, + 0.3215420046300762 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14610574181099337, + "scoreError" : 0.0028194471004581796, + "scoreConfidence" : [ + 0.1432862947105352, + 0.14892518891145154 + ], + "scorePercentiles" : { + "0.0" : 0.14541311144232308, + "50.0" : 0.14573029123129017, + "90.0" : 0.14803312681706488, + "95.0" : 0.14803312681706488, + "99.0" : 0.14803312681706488, + "99.9" : 0.14803312681706488, + "99.99" : 0.14803312681706488, + "99.999" : 0.14803312681706488, + "99.9999" : 0.14803312681706488, + "100.0" : 0.14803312681706488 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14803312681706488, + 0.14543053310646714, + 0.14552344786740204 + ], + [ + 0.14541311144232308, + 0.14593713459517832, + 0.1462970970375247 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.41092122340295095, + "scoreError" : 0.009474079039296762, + "scoreConfidence" : [ + 0.4014471443636542, + 0.4203953024422477 + ], + "scorePercentiles" : { + "0.0" : 0.4061669763210268, + "50.0" : 0.4106982601127916, + "90.0" : 0.41674692411235204, + "95.0" : 0.41674692411235204, + "99.0" : 0.41674692411235204, + "99.9" : 0.41674692411235204, + "99.99" : 0.41674692411235204, + "99.999" : 0.41674692411235204, + "99.9999" : 0.41674692411235204, + "100.0" : 0.41674692411235204 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41674692411235204, + 0.4109359526216305, + 0.4108024318695313 + ], + [ + 0.4102809671371133, + 0.4105940883560519, + 0.4061669763210268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15839800179137106, + "scoreError" : 0.003123740167910204, + "scoreConfidence" : [ + 0.15527426162346086, + 0.16152174195928126 + ], + "scorePercentiles" : { + "0.0" : 0.1570603831571673, + "50.0" : 0.15827852887098906, + "90.0" : 0.15993384616245782, + "95.0" : 0.15993384616245782, + "99.0" : 0.15993384616245782, + "99.9" : 0.15993384616245782, + "99.99" : 0.15993384616245782, + "99.999" : 0.15993384616245782, + "99.9999" : 0.15993384616245782, + "100.0" : 0.15993384616245782 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15763281685056746, + 0.1576488829473618, + 0.1570603831571673 + ], + [ + 0.15890817479461633, + 0.15993384616245782, + 0.15920390683605565 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04764037291617812, + "scoreError" : 0.0011872650101901765, + "scoreConfidence" : [ + 0.046453107905987945, + 0.048827637926368295 + ], + "scorePercentiles" : { + "0.0" : 0.04724036632087148, + "50.0" : 0.04761753282515352, + "90.0" : 0.04806067320603827, + "95.0" : 0.04806067320603827, + "99.0" : 0.04806067320603827, + "99.9" : 0.04806067320603827, + "99.99" : 0.04806067320603827, + "99.999" : 0.04806067320603827, + "99.9999" : 0.04806067320603827, + "100.0" : 0.04806067320603827 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04724036632087148, + 0.04727325140871703, + 0.047252308453785564 + ], + [ + 0.04796181424159001, + 0.048053823866066325, + 0.04806067320603827 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9082529.955939034, + "scoreError" : 849981.3211799804, + "scoreConfidence" : [ + 8232548.634759054, + 9932511.277119014 + ], + "scorePercentiles" : { + "0.0" : 8742775.296328671, + "50.0" : 9002722.989551485, + "90.0" : 9501022.41025641, + "95.0" : 9501022.41025641, + "99.0" : 9501022.41025641, + "99.9" : 9501022.41025641, + "99.99" : 9501022.41025641, + "99.999" : 9501022.41025641, + "99.9999" : 9501022.41025641, + "100.0" : 9501022.41025641 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8886845.03374778, + 8742775.296328671, + 8872020.175531914 + ], + [ + 9501022.41025641, + 9373915.874414245, + 9118600.945355192 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-05T00:47:12Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json b/performance-results/2025-07-05T00:47:12Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json new file mode 100644 index 0000000000..3133c909d5 --- /dev/null +++ b/performance-results/2025-07-05T00:47:12Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3070641466544872, + "scoreError" : 0.04244598012815704, + "scoreConfidence" : [ + 3.26461816652633, + 3.3495101267826444 + ], + "scorePercentiles" : { + "0.0" : 3.2990266891359092, + "50.0" : 3.3070682585058804, + "90.0" : 3.3150933804702793, + "95.0" : 3.3150933804702793, + "99.0" : 3.3150933804702793, + "99.9" : 3.3150933804702793, + "99.99" : 3.3150933804702793, + "99.999" : 3.3150933804702793, + "99.9999" : 3.3150933804702793, + "100.0" : 3.3150933804702793 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.2990266891359092, + 3.306638908099548 + ], + [ + 3.307497608912213, + 3.3150933804702793 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6630032481221397, + "scoreError" : 0.024106819712119015, + "scoreConfidence" : [ + 1.6388964284100207, + 1.6871100678342588 + ], + "scorePercentiles" : { + "0.0" : 1.6581145436107447, + "50.0" : 1.663434868376007, + "90.0" : 1.6670287121258003, + "95.0" : 1.6670287121258003, + "99.0" : 1.6670287121258003, + "99.9" : 1.6670287121258003, + "99.99" : 1.6670287121258003, + "99.999" : 1.6670287121258003, + "99.9999" : 1.6670287121258003, + "100.0" : 1.6670287121258003 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6581145436107447, + 1.6642332364127526 + ], + [ + 1.6626365003392614, + 1.6670287121258003 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8403780479411779, + "scoreError" : 0.017884758773049632, + "scoreConfidence" : [ + 0.8224932891681282, + 0.8582628067142275 + ], + "scorePercentiles" : { + "0.0" : 0.8364775579050634, + "50.0" : 0.8413099187173936, + "90.0" : 0.842414796424861, + "95.0" : 0.842414796424861, + "99.0" : 0.842414796424861, + "99.9" : 0.842414796424861, + "99.99" : 0.842414796424861, + "99.999" : 0.842414796424861, + "99.9999" : 0.842414796424861, + "100.0" : 0.842414796424861 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8364775579050634, + 0.8422797970083116 + ], + [ + 0.842414796424861, + 0.8403400404264755 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.178863985332343, + "scoreError" : 0.8144359449277992, + "scoreConfidence" : [ + 14.364428040404544, + 15.993299930260143 + ], + "scorePercentiles" : { + "0.0" : 14.736716387882165, + "50.0" : 15.213239768138987, + "90.0" : 15.547112696159793, + "95.0" : 15.547112696159793, + "99.0" : 15.547112696159793, + "99.9" : 15.547112696159793, + "99.99" : 15.547112696159793, + "99.999" : 15.547112696159793, + "99.9999" : 15.547112696159793, + "100.0" : 15.547112696159793 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 14.736716387882165, + 15.374654765031705, + 15.547112696159793 + ], + [ + 15.130715433197334, + 14.988220526642417, + 15.295764103080637 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2375.174949210943, + "scoreError" : 212.3633008651267, + "scoreConfidence" : [ + 2162.811648345816, + 2587.5382500760697 + ], + "scorePercentiles" : { + "0.0" : 2307.641007094073, + "50.0" : 2344.1093865796092, + "90.0" : 2502.8580415617425, + "95.0" : 2502.8580415617425, + "99.0" : 2502.8580415617425, + "99.9" : 2502.8580415617425, + "99.99" : 2502.8580415617425, + "99.999" : 2502.8580415617425, + "99.9999" : 2502.8580415617425, + "100.0" : 2502.8580415617425 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2347.235226260049, + 2307.641007094073, + 2322.034985306579 + ], + [ + 2340.98354689917, + 2502.8580415617425, + 2430.296888144043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75340.38013917883, + "scoreError" : 1806.8890433444574, + "scoreConfidence" : [ + 73533.49109583437, + 77147.26918252329 + ], + "scorePercentiles" : { + "0.0" : 74422.34738651122, + "50.0" : 75384.57640165939, + "90.0" : 76036.69337782524, + "95.0" : 76036.69337782524, + "99.0" : 76036.69337782524, + "99.9" : 76036.69337782524, + "99.99" : 76036.69337782524, + "99.999" : 76036.69337782524, + "99.9999" : 76036.69337782524, + "100.0" : 76036.69337782524 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75052.25110726464, + 74899.77175872226, + 74422.34738651122 + ], + [ + 75716.90169605413, + 75914.31550869542, + 76036.69337782524 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 339.85148247059175, + "scoreError" : 11.685876741341024, + "scoreConfidence" : [ + 328.16560572925073, + 351.53735921193277 + ], + "scorePercentiles" : { + "0.0" : 335.35346383820684, + "50.0" : 339.0080858723947, + "90.0" : 345.52334796026145, + "95.0" : 345.52334796026145, + "99.0" : 345.52334796026145, + "99.9" : 345.52334796026145, + "99.99" : 345.52334796026145, + "99.999" : 345.52334796026145, + "99.9999" : 345.52334796026145, + "100.0" : 345.52334796026145 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 336.54239720136957, + 345.52334796026145, + 337.07819565871216 + ], + [ + 343.6735140789231, + 335.35346383820684, + 340.93797608607724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 100.3002190845122, + "scoreError" : 8.926514210325456, + "scoreConfidence" : [ + 91.37370487418674, + 109.22673329483764 + ], + "scorePercentiles" : { + "0.0" : 97.30175457408934, + "50.0" : 99.4518309109109, + "90.0" : 105.19803679423734, + "95.0" : 105.19803679423734, + "99.0" : 105.19803679423734, + "99.9" : 105.19803679423734, + "99.99" : 105.19803679423734, + "99.999" : 105.19803679423734, + "99.9999" : 105.19803679423734, + "100.0" : 105.19803679423734 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 97.30175457408934, + 97.96441801065532, + 105.19803679423734 + ], + [ + 100.93924381116649, + 102.62814273015086, + 97.7697185867738 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06559008106718416, + "scoreError" : 0.00237429763551806, + "scoreConfidence" : [ + 0.06321578343166609, + 0.06796437870270222 + ], + "scorePercentiles" : { + "0.0" : 0.0648344508369964, + "50.0" : 0.06536141221201949, + "90.0" : 0.06714946196717789, + "95.0" : 0.06714946196717789, + "99.0" : 0.06714946196717789, + "99.9" : 0.06714946196717789, + "99.99" : 0.06714946196717789, + "99.999" : 0.06714946196717789, + "99.9999" : 0.06714946196717789, + "100.0" : 0.06714946196717789 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0650969900210255, + 0.06562583440301348, + 0.0648344508369964 + ], + [ + 0.06714946196717789, + 0.06504443759756479, + 0.06578931157732691 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 4.017333031287936E-4, + "scoreError" : 1.8785393050945348E-5, + "scoreConfidence" : [ + 3.829479100778482E-4, + 4.2051869617973895E-4 + ], + "scorePercentiles" : { + "0.0" : 3.9200961676605345E-4, + "50.0" : 4.022701977280716E-4, + "90.0" : 4.1173720620955775E-4, + "95.0" : 4.1173720620955775E-4, + "99.0" : 4.1173720620955775E-4, + "99.9" : 4.1173720620955775E-4, + "99.99" : 4.1173720620955775E-4, + "99.999" : 4.1173720620955775E-4, + "99.9999" : 4.1173720620955775E-4, + "100.0" : 4.1173720620955775E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.973917512171938E-4, + 4.0310904447393004E-4, + 4.1173720620955775E-4 + ], + [ + 4.0472084912381327E-4, + 4.014313509822131E-4, + 3.9200961676605345E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.13111215973873416, + "scoreError" : 0.0017730616321248167, + "scoreConfidence" : [ + 0.12933909810660935, + 0.13288522137085898 + ], + "scorePercentiles" : { + "0.0" : 0.13030984673320997, + "50.0" : 0.13100747266286702, + "90.0" : 0.13201151215713192, + "95.0" : 0.13201151215713192, + "99.0" : 0.13201151215713192, + "99.9" : 0.13201151215713192, + "99.99" : 0.13201151215713192, + "99.999" : 0.13201151215713192, + "99.9999" : 0.13201151215713192, + "100.0" : 0.13201151215713192 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1310256165638143, + 0.13030984673320997, + 0.13167701709131607 + ], + [ + 0.13201151215713192, + 0.13065963712501308, + 0.13098932876191974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013202864386591831, + "scoreError" : 2.4750806215052053E-4, + "scoreConfidence" : [ + 0.01295535632444131, + 0.013450372448742353 + ], + "scorePercentiles" : { + "0.0" : 0.013103349656892098, + "50.0" : 0.013213838281703546, + "90.0" : 0.01334939433141417, + "95.0" : 0.01334939433141417, + "99.0" : 0.01334939433141417, + "99.9" : 0.01334939433141417, + "99.99" : 0.01334939433141417, + "99.999" : 0.01334939433141417, + "99.9999" : 0.01334939433141417, + "100.0" : 0.01334939433141417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013103349656892098, + 0.013118643366982166, + 0.01334939433141417 + ], + [ + 0.013218122400855466, + 0.01321144977606912, + 0.013216226787337972 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0641845110937815, + "scoreError" : 0.12206935913433964, + "scoreConfidence" : [ + 0.942115151959442, + 1.1862538702281211 + ], + "scorePercentiles" : { + "0.0" : 1.018122407309376, + "50.0" : 1.0651541851716382, + "90.0" : 1.1078630178353828, + "95.0" : 1.1078630178353828, + "99.0" : 1.1078630178353828, + "99.9" : 1.1078630178353828, + "99.99" : 1.1078630178353828, + "99.999" : 1.1078630178353828, + "99.9999" : 1.1078630178353828, + "100.0" : 1.1078630178353828 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.018122407309376, + 1.0269542911275416, + 1.0288366780864198 + ], + [ + 1.1018589799471132, + 1.1014716922568564, + 1.1078630178353828 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011167890222464292, + "scoreError" : 6.419110739446407E-4, + "scoreConfidence" : [ + 0.010525979148519651, + 0.011809801296408932 + ], + "scorePercentiles" : { + "0.0" : 0.010939053593266987, + "50.0" : 0.011147164016119593, + "90.0" : 0.011430697824342582, + "95.0" : 0.011430697824342582, + "99.0" : 0.011430697824342582, + "99.9" : 0.011430697824342582, + "99.99" : 0.011430697824342582, + "99.999" : 0.011430697824342582, + "99.9999" : 0.011430697824342582, + "100.0" : 0.011430697824342582 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010939053593266987, + 0.010976313115481036, + 0.01097001059012466 + ], + [ + 0.011318014916758152, + 0.011373251294812335, + 0.011430697824342582 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.424486985533617, + "scoreError" : 0.32093045613689936, + "scoreConfidence" : [ + 3.1035565293967173, + 3.7454174416705164 + ], + "scorePercentiles" : { + "0.0" : 3.309536432825943, + "50.0" : 3.392504927704642, + "90.0" : 3.5695522919343325, + "95.0" : 3.5695522919343325, + "99.0" : 3.5695522919343325, + "99.9" : 3.5695522919343325, + "99.99" : 3.5695522919343325, + "99.999" : 3.5695522919343325, + "99.9999" : 3.5695522919343325, + "100.0" : 3.5695522919343325 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3243864823920264, + 3.367761222895623, + 3.309536432825943 + ], + [ + 3.4172486325136613, + 3.558436850640114, + 3.5695522919343325 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9831855064973034, + "scoreError" : 0.2697092574551622, + "scoreConfidence" : [ + 2.713476249042141, + 3.2528947639524657 + ], + "scorePercentiles" : { + "0.0" : 2.8905141589595376, + "50.0" : 2.9523966833870112, + "90.0" : 3.11839525662613, + "95.0" : 3.11839525662613, + "99.0" : 3.11839525662613, + "99.9" : 3.11839525662613, + "99.99" : 3.11839525662613, + "99.999" : 3.11839525662613, + "99.9999" : 3.11839525662613, + "100.0" : 3.11839525662613 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.078011810403201, + 2.9894950753138074, + 3.11839525662613 + ], + [ + 2.8905141589595376, + 2.90739844622093, + 2.9152982914602155 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18552579974179229, + "scoreError" : 0.012781564142265011, + "scoreConfidence" : [ + 0.17274423559952728, + 0.19830736388405729 + ], + "scorePercentiles" : { + "0.0" : 0.1797718868355295, + "50.0" : 0.18627357166137082, + "90.0" : 0.1900898517906022, + "95.0" : 0.1900898517906022, + "99.0" : 0.1900898517906022, + "99.9" : 0.1900898517906022, + "99.99" : 0.1900898517906022, + "99.999" : 0.1900898517906022, + "99.9999" : 0.1900898517906022, + "100.0" : 0.1900898517906022 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18341209942593034, + 0.18134810055491077, + 0.1797718868355295 + ], + [ + 0.1900898517906022, + 0.1893978159469697, + 0.1891350438968113 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3383710501281317, + "scoreError" : 0.0197584361650953, + "scoreConfidence" : [ + 0.31861261396303636, + 0.358129486293227 + ], + "scorePercentiles" : { + "0.0" : 0.33087119249602964, + "50.0" : 0.3385230243624009, + "90.0" : 0.34676105222095077, + "95.0" : 0.34676105222095077, + "99.0" : 0.34676105222095077, + "99.9" : 0.34676105222095077, + "99.99" : 0.34676105222095077, + "99.999" : 0.34676105222095077, + "99.9999" : 0.34676105222095077, + "100.0" : 0.34676105222095077 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.34403806553823923, + 0.34312508618974097, + 0.34676105222095077 + ], + [ + 0.33392096253506076, + 0.3315099417887688, + 0.33087119249602964 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1530989316994479, + "scoreError" : 0.0034390765349487707, + "scoreConfidence" : [ + 0.14965985516449914, + 0.15653800823439668 + ], + "scorePercentiles" : { + "0.0" : 0.15139773350188485, + "50.0" : 0.1533867524409367, + "90.0" : 0.15464553746230572, + "95.0" : 0.15464553746230572, + "99.0" : 0.15464553746230572, + "99.9" : 0.15464553746230572, + "99.99" : 0.15464553746230572, + "99.999" : 0.15464553746230572, + "99.9999" : 0.15464553746230572, + "100.0" : 0.15464553746230572 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15139773350188485, + 0.15386806497722796, + 0.15190874937339552 + ], + [ + 0.15321277758541443, + 0.15356072729645895, + 0.15464553746230572 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4054485564485772, + "scoreError" : 0.00847866632650995, + "scoreConfidence" : [ + 0.39696989012206724, + 0.41392722277508714 + ], + "scorePercentiles" : { + "0.0" : 0.4027023718036484, + "50.0" : 0.40401676949545795, + "90.0" : 0.4104843854773828, + "95.0" : 0.4104843854773828, + "99.0" : 0.4104843854773828, + "99.9" : 0.4104843854773828, + "99.99" : 0.4104843854773828, + "99.999" : 0.4104843854773828, + "99.9999" : 0.4104843854773828, + "100.0" : 0.4104843854773828 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4104843854773828, + 0.4038437279408795, + 0.40367587498486257 + ], + [ + 0.40779516743465316, + 0.4041898110500364, + 0.4027023718036484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.165794414553091, + "scoreError" : 0.006078914237342212, + "scoreConfidence" : [ + 0.15971550031574877, + 0.1718733287904332 + ], + "scorePercentiles" : { + "0.0" : 0.16295015312041713, + "50.0" : 0.16585375321459717, + "90.0" : 0.16815868010761728, + "95.0" : 0.16815868010761728, + "99.0" : 0.16815868010761728, + "99.9" : 0.16815868010761728, + "99.99" : 0.16815868010761728, + "99.999" : 0.16815868010761728, + "99.9999" : 0.16815868010761728, + "100.0" : 0.16815868010761728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16386224047583936, + 0.1652147114771432, + 0.16295015312041713 + ], + [ + 0.16808790718547778, + 0.16815868010761728, + 0.16649279495205113 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04688887769197516, + "scoreError" : 0.0019141384083800725, + "scoreConfidence" : [ + 0.044974739283595085, + 0.048803016100355236 + ], + "scorePercentiles" : { + "0.0" : 0.046138794567759975, + "50.0" : 0.046913393690992414, + "90.0" : 0.04783971637764011, + "95.0" : 0.04783971637764011, + "99.0" : 0.04783971637764011, + "99.9" : 0.04783971637764011, + "99.99" : 0.04783971637764011, + "99.999" : 0.04783971637764011, + "99.9999" : 0.04783971637764011, + "100.0" : 0.04783971637764011 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04618629552739264, + 0.046138794567759975, + 0.04662778074118283 + ], + [ + 0.047199006640801996, + 0.04734167229707339, + 0.04783971637764011 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9357641.47941507, + "scoreError" : 528623.571754874, + "scoreConfidence" : [ + 8829017.907660196, + 9886265.051169945 + ], + "scorePercentiles" : { + "0.0" : 8985705.25965858, + "50.0" : 9406346.279001884, + "90.0" : 9513393.257604564, + "95.0" : 9513393.257604564, + "99.0" : 9513393.257604564, + "99.9" : 9513393.257604564, + "99.99" : 9513393.257604564, + "99.999" : 9513393.257604564, + "99.9999" : 9513393.257604564, + "100.0" : 9513393.257604564 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9396004.8, + 9513393.257604564, + 9416687.758003766 + ], + [ + 9377803.58950328, + 8985705.25965858, + 9456254.211720226 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-05T00:50:56Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json b/performance-results/2025-07-05T00:50:56Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json new file mode 100644 index 0000000000..aacbcbfe8a --- /dev/null +++ b/performance-results/2025-07-05T00:50:56Z-7c8a0200d0b9a8d0f4a59eb4fca6f3c8070dc7bc-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3282631703131016, + "scoreError" : 0.02125555360245804, + "scoreConfidence" : [ + 3.3070076167106435, + 3.3495187239155597 + ], + "scorePercentiles" : { + "0.0" : 3.32418039002193, + "50.0" : 3.3283678738294675, + "90.0" : 3.332136543571541, + "95.0" : 3.332136543571541, + "99.0" : 3.332136543571541, + "99.9" : 3.332136543571541, + "99.99" : 3.332136543571541, + "99.999" : 3.332136543571541, + "99.9999" : 3.332136543571541, + "100.0" : 3.332136543571541 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.32418039002193, + 3.3277494702073094 + ], + [ + 3.332136543571541, + 3.3289862774516252 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.683155833477382, + "scoreError" : 0.0339231255101849, + "scoreConfidence" : [ + 1.6492327079671971, + 1.7170789589875668 + ], + "scorePercentiles" : { + "0.0" : 1.6774398957936762, + "50.0" : 1.6833439919972277, + "90.0" : 1.6884954541213957, + "95.0" : 1.6884954541213957, + "99.0" : 1.6884954541213957, + "99.9" : 1.6884954541213957, + "99.99" : 1.6884954541213957, + "99.999" : 1.6884954541213957, + "99.9999" : 1.6884954541213957, + "100.0" : 1.6884954541213957 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6866167507293455, + 1.6884954541213957 + ], + [ + 1.6774398957936762, + 1.6800712332651102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8413683160338967, + "scoreError" : 0.017272283420540588, + "scoreConfidence" : [ + 0.8240960326133562, + 0.8586405994544373 + ], + "scorePercentiles" : { + "0.0" : 0.8377150694089133, + "50.0" : 0.8418685397254648, + "90.0" : 0.8440211152757442, + "95.0" : 0.8440211152757442, + "99.0" : 0.8440211152757442, + "99.9" : 0.8440211152757442, + "99.99" : 0.8440211152757442, + "99.999" : 0.8440211152757442, + "99.9999" : 0.8440211152757442, + "100.0" : 0.8440211152757442 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8377150694089133, + 0.8440211152757442 + ], + [ + 0.8413444877863161, + 0.8423925916646136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.09708598192805, + "scoreError" : 0.1244310755511922, + "scoreConfidence" : [ + 15.972654906376858, + 16.221517057479243 + ], + "scorePercentiles" : { + "0.0" : 16.06170320702963, + "50.0" : 16.07389110818133, + "90.0" : 16.15428070240861, + "95.0" : 16.15428070240861, + "99.0" : 16.15428070240861, + "99.9" : 16.15428070240861, + "99.99" : 16.15428070240861, + "99.999" : 16.15428070240861, + "99.9999" : 16.15428070240861, + "100.0" : 16.15428070240861 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.065306255619618, + 16.07935254519607, + 16.06170320702963 + ], + [ + 16.068429671166584, + 16.15428070240861, + 16.15344351014778 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2655.4904221352263, + "scoreError" : 120.33481500092981, + "scoreConfidence" : [ + 2535.1556071342966, + 2775.825237136156 + ], + "scorePercentiles" : { + "0.0" : 2605.9249957763427, + "50.0" : 2655.7756175673812, + "90.0" : 2704.377999303586, + "95.0" : 2704.377999303586, + "99.0" : 2704.377999303586, + "99.9" : 2704.377999303586, + "99.99" : 2704.377999303586, + "99.999" : 2704.377999303586, + "99.9999" : 2704.377999303586, + "100.0" : 2704.377999303586 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2630.9608279533168, + 2615.990429316044, + 2605.9249957763427 + ], + [ + 2680.5904071814457, + 2704.377999303586, + 2695.097873280623 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76742.37307341881, + "scoreError" : 1757.091001617286, + "scoreConfidence" : [ + 74985.28207180153, + 78499.4640750361 + ], + "scorePercentiles" : { + "0.0" : 76015.11955360694, + "50.0" : 76785.77199469347, + "90.0" : 77414.67242513646, + "95.0" : 77414.67242513646, + "99.0" : 77414.67242513646, + "99.9" : 77414.67242513646, + "99.99" : 77414.67242513646, + "99.999" : 77414.67242513646, + "99.9999" : 77414.67242513646, + "100.0" : 77414.67242513646 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77414.67242513646, + 77235.2765005379, + 77262.10198225007 + ], + [ + 76190.80049013249, + 76015.11955360694, + 76336.26748884903 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.67273486606126, + "scoreError" : 15.925846303569283, + "scoreConfidence" : [ + 340.74688856249196, + 372.59858116963056 + ], + "scorePercentiles" : { + "0.0" : 350.5004593416489, + "50.0" : 356.96551285551715, + "90.0" : 363.06577487859954, + "95.0" : 363.06577487859954, + "99.0" : 363.06577487859954, + "99.9" : 363.06577487859954, + "99.99" : 363.06577487859954, + "99.999" : 363.06577487859954, + "99.9999" : 363.06577487859954, + "100.0" : 363.06577487859954 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.88968490667014, + 361.3198275744951, + 363.06577487859954 + ], + [ + 353.04134080436415, + 351.21932169058994, + 350.5004593416489 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.74174034107342, + "scoreError" : 6.071749601747298, + "scoreConfidence" : [ + 107.66999073932612, + 119.81348994282072 + ], + "scorePercentiles" : { + "0.0" : 110.70818137992639, + "50.0" : 113.99574150699002, + "90.0" : 115.78602886408476, + "95.0" : 115.78602886408476, + "99.0" : 115.78602886408476, + "99.9" : 115.78602886408476, + "99.99" : 115.78602886408476, + "99.999" : 115.78602886408476, + "99.9999" : 115.78602886408476, + "100.0" : 115.78602886408476 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.70818137992639, + 112.67367968757445, + 112.20483629565771 + ], + [ + 115.31780332640557, + 115.78602886408476, + 115.75991249279163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06196478749521104, + "scoreError" : 0.0010502060183412998, + "scoreConfidence" : [ + 0.06091458147686974, + 0.06301499351355234 + ], + "scorePercentiles" : { + "0.0" : 0.06148123020030248, + "50.0" : 0.06184440165185134, + "90.0" : 0.06247178431985007, + "95.0" : 0.06247178431985007, + "99.0" : 0.06247178431985007, + "99.9" : 0.06247178431985007, + "99.99" : 0.06247178431985007, + "99.999" : 0.06247178431985007, + "99.9999" : 0.06247178431985007, + "100.0" : 0.06247178431985007 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061812698598722966, + 0.06247178431985007, + 0.06148123020030248 + ], + [ + 0.061794333189149106, + 0.06187610470497971, + 0.06235257395826189 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7664859309785435E-4, + "scoreError" : 7.234165973674477E-6, + "scoreConfidence" : [ + 3.6941442712417987E-4, + 3.838827590715288E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7218151179250857E-4, + "50.0" : 3.7752821194703915E-4, + "90.0" : 3.789832873398393E-4, + "95.0" : 3.789832873398393E-4, + "99.0" : 3.789832873398393E-4, + "99.9" : 3.789832873398393E-4, + "99.99" : 3.789832873398393E-4, + "99.999" : 3.789832873398393E-4, + "99.9999" : 3.789832873398393E-4, + "100.0" : 3.789832873398393E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7846667328723086E-4, + 3.7821006193809883E-4, + 3.768463619559795E-4 + ], + [ + 3.789832873398393E-4, + 3.752036622734693E-4, + 3.7218151179250857E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12805361843389454, + "scoreError" : 0.0011874300634604079, + "scoreConfidence" : [ + 0.12686618837043412, + 0.12924104849735496 + ], + "scorePercentiles" : { + "0.0" : 0.12740925286345858, + "50.0" : 0.12804254626663714, + "90.0" : 0.12870310352638353, + "95.0" : 0.12870310352638353, + "99.0" : 0.12870310352638353, + "99.9" : 0.12870310352638353, + "99.99" : 0.12870310352638353, + "99.999" : 0.12870310352638353, + "99.9999" : 0.12870310352638353, + "100.0" : 0.12870310352638353 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12795344277543919, + 0.12740925286345858, + 0.12813164975783511 + ], + [ + 0.12870310352638353, + 0.12820916557904588, + 0.12791509610120494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01312182801615632, + "scoreError" : 6.886535460805714E-5, + "scoreConfidence" : [ + 0.013052962661548262, + 0.013190693370764377 + ], + "scorePercentiles" : { + "0.0" : 0.013073739049890117, + "50.0" : 0.013130433226206408, + "90.0" : 0.013140150708637414, + "95.0" : 0.013140150708637414, + "99.0" : 0.013140150708637414, + "99.9" : 0.013140150708637414, + "99.99" : 0.013140150708637414, + "99.999" : 0.013140150708637414, + "99.9999" : 0.013140150708637414, + "100.0" : 0.013140150708637414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013140150708637414, + 0.01313617208593591, + 0.013132688192165407 + ], + [ + 0.013073739049890117, + 0.013120039800061661, + 0.013128178260247411 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.006372279111726, + "scoreError" : 0.07782383378537393, + "scoreConfidence" : [ + 0.9285484453263521, + 1.0841961128970998 + ], + "scorePercentiles" : { + "0.0" : 0.9780806067481662, + "50.0" : 1.0058241523084424, + "90.0" : 1.0354943400289915, + "95.0" : 1.0354943400289915, + "99.0" : 1.0354943400289915, + "99.9" : 1.0354943400289915, + "99.99" : 1.0354943400289915, + "99.999" : 1.0354943400289915, + "99.9999" : 1.0354943400289915, + "100.0" : 1.0354943400289915 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.031795528064383, + 1.0273034468412943, + 1.0354943400289915 + ], + [ + 0.981214895211931, + 0.9780806067481662, + 0.9843448577755906 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010784641487549268, + "scoreError" : 6.053543134433913E-4, + "scoreConfidence" : [ + 0.010179287174105876, + 0.01138999580099266 + ], + "scorePercentiles" : { + "0.0" : 0.010543396271212173, + "50.0" : 0.010781962351705211, + "90.0" : 0.011048356408318749, + "95.0" : 0.011048356408318749, + "99.0" : 0.011048356408318749, + "99.9" : 0.011048356408318749, + "99.99" : 0.011048356408318749, + "99.999" : 0.011048356408318749, + "99.9999" : 0.011048356408318749, + "100.0" : 0.011048356408318749 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010586487528397482, + 0.010543396271212173, + 0.010653102139518235 + ], + [ + 0.011048356408318749, + 0.010965684013956783, + 0.010910822563892187 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2991135967285623, + "scoreError" : 0.3058686030747992, + "scoreConfidence" : [ + 2.993244993653763, + 3.6049821998033615 + ], + "scorePercentiles" : { + "0.0" : 3.1891481575255103, + "50.0" : 3.2964677696343463, + "90.0" : 3.417100868852459, + "95.0" : 3.417100868852459, + "99.0" : 3.417100868852459, + "99.9" : 3.417100868852459, + "99.99" : 3.417100868852459, + "99.999" : 3.417100868852459, + "99.9999" : 3.417100868852459, + "100.0" : 3.417100868852459 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3928123181818184, + 3.384166552097429, + 3.417100868852459 + ], + [ + 3.2026846965428937, + 3.1891481575255103, + 3.2087689871712635 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.857292351202217, + "scoreError" : 0.09215514615230923, + "scoreConfidence" : [ + 2.7651372050499075, + 2.949447497354526 + ], + "scorePercentiles" : { + "0.0" : 2.836068081655798, + "50.0" : 2.845798895908323, + "90.0" : 2.922696489772063, + "95.0" : 2.922696489772063, + "99.0" : 2.922696489772063, + "99.9" : 2.922696489772063, + "99.99" : 2.922696489772063, + "99.999" : 2.922696489772063, + "99.9999" : 2.922696489772063, + "100.0" : 2.922696489772063 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.922696489772063, + 2.844483116040956, + 2.8561725865219874 + ], + [ + 2.8372191574468086, + 2.836068081655798, + 2.8471146757756904 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17907193816760078, + "scoreError" : 0.004601833163891263, + "scoreConfidence" : [ + 0.17447010500370952, + 0.18367377133149204 + ], + "scorePercentiles" : { + "0.0" : 0.17743187083266798, + "50.0" : 0.17865722001703827, + "90.0" : 0.18125369515886394, + "95.0" : 0.18125369515886394, + "99.0" : 0.18125369515886394, + "99.9" : 0.18125369515886394, + "99.99" : 0.18125369515886394, + "99.999" : 0.18125369515886394, + "99.9999" : 0.18125369515886394, + "100.0" : 0.18125369515886394 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1807023101678683, + 0.18125369515886394, + 0.17943527366683412 + ], + [ + 0.1777293128121279, + 0.17787916636724238, + 0.17743187083266798 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3250820687025236, + "scoreError" : 0.007468818995772884, + "scoreConfidence" : [ + 0.3176132497067507, + 0.3325508876982965 + ], + "scorePercentiles" : { + "0.0" : 0.3218076919066774, + "50.0" : 0.325907237413153, + "90.0" : 0.3275825915225367, + "95.0" : 0.3275825915225367, + "99.0" : 0.3275825915225367, + "99.9" : 0.3275825915225367, + "99.99" : 0.3275825915225367, + "99.999" : 0.3275825915225367, + "99.9999" : 0.3275825915225367, + "100.0" : 0.3275825915225367 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32740551568229437, + 0.3275825915225367, + 0.3267721012645819 + ], + [ + 0.325042373561724, + 0.32188213827732715, + 0.3218076919066774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14490277516728287, + "scoreError" : 0.0037427120732352608, + "scoreConfidence" : [ + 0.1411600630940476, + 0.14864548724051813 + ], + "scorePercentiles" : { + "0.0" : 0.143360292605654, + "50.0" : 0.1448584661757905, + "90.0" : 0.14671547334213614, + "95.0" : 0.14671547334213614, + "99.0" : 0.14671547334213614, + "99.9" : 0.14671547334213614, + "99.99" : 0.14671547334213614, + "99.999" : 0.14671547334213614, + "99.9999" : 0.14671547334213614, + "100.0" : 0.14671547334213614 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14569518172149537, + 0.14671547334213614, + 0.1457662354818961 + ], + [ + 0.14402175063008568, + 0.143360292605654, + 0.14385771722243001 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4055291250280828, + "scoreError" : 0.007215221539136638, + "scoreConfidence" : [ + 0.3983139034889462, + 0.4127443465672194 + ], + "scorePercentiles" : { + "0.0" : 0.40238874468855623, + "50.0" : 0.40509361377844355, + "90.0" : 0.4084964676688044, + "95.0" : 0.4084964676688044, + "99.0" : 0.4084964676688044, + "99.9" : 0.4084964676688044, + "99.99" : 0.4084964676688044, + "99.999" : 0.4084964676688044, + "99.9999" : 0.4084964676688044, + "100.0" : 0.4084964676688044 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40609787358888977, + 0.4036539131786075, + 0.40238874468855623 + ], + [ + 0.4084964676688044, + 0.40844839707564123, + 0.4040893539679974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1527937242784688, + "scoreError" : 0.001113980091395116, + "scoreConfidence" : [ + 0.15167974418707367, + 0.15390770436986392 + ], + "scorePercentiles" : { + "0.0" : 0.15221025520547946, + "50.0" : 0.15297208724042827, + "90.0" : 0.1531666853423189, + "95.0" : 0.1531666853423189, + "99.0" : 0.1531666853423189, + "99.9" : 0.1531666853423189, + "99.99" : 0.1531666853423189, + "99.999" : 0.1531666853423189, + "99.9999" : 0.1531666853423189, + "100.0" : 0.1531666853423189 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1531666853423189, + 0.15221025520547946, + 0.15306064646820233 + ], + [ + 0.15301662242555927, + 0.1529275520552973, + 0.15238058417395545 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046545531764455104, + "scoreError" : 0.003868384550060691, + "scoreConfidence" : [ + 0.04267714721439441, + 0.0504139163145158 + ], + "scorePercentiles" : { + "0.0" : 0.045270606834859686, + "50.0" : 0.04645417379088988, + "90.0" : 0.04806224739146525, + "95.0" : 0.04806224739146525, + "99.0" : 0.04806224739146525, + "99.9" : 0.04806224739146525, + "99.99" : 0.04806224739146525, + "99.999" : 0.04806224739146525, + "99.9999" : 0.04806224739146525, + "100.0" : 0.04806224739146525 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045270606834859686, + 0.045296542315532, + 0.045314717503013385 + ], + [ + 0.04806224739146525, + 0.04773544646309388, + 0.04759363007876639 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8667036.010033628, + "scoreError" : 101145.17545612513, + "scoreConfidence" : [ + 8565890.834577503, + 8768181.185489753 + ], + "scorePercentiles" : { + "0.0" : 8621243.338501291, + "50.0" : 8667030.769689955, + "90.0" : 8709799.25413403, + "95.0" : 8709799.25413403, + "99.0" : 8709799.25413403, + "99.9" : 8709799.25413403, + "99.99" : 8709799.25413403, + "99.999" : 8709799.25413403, + "99.9999" : 8709799.25413403, + "100.0" : 8709799.25413403 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8709799.25413403, + 8696734.98, + 8621243.338501291 + ], + [ + 8689241.010425717, + 8644820.528954191, + 8640376.948186528 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-07T22:42:09Z-d9ef509a7fc499523f41f4537546a4dd273cf6f2-jdk17.json b/performance-results/2025-07-07T22:42:09Z-d9ef509a7fc499523f41f4537546a4dd273cf6f2-jdk17.json new file mode 100644 index 0000000000..a3e2d61be6 --- /dev/null +++ b/performance-results/2025-07-07T22:42:09Z-d9ef509a7fc499523f41f4537546a4dd273cf6f2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.31990237191701, + "scoreError" : 0.05714858679725346, + "scoreConfidence" : [ + 3.2627537851197563, + 3.3770509587142636 + ], + "scorePercentiles" : { + "0.0" : 3.3116116182038695, + "50.0" : 3.3202238237359607, + "90.0" : 3.3275502219922477, + "95.0" : 3.3275502219922477, + "99.0" : 3.3275502219922477, + "99.9" : 3.3275502219922477, + "99.99" : 3.3275502219922477, + "99.999" : 3.3275502219922477, + "99.9999" : 3.3275502219922477, + "100.0" : 3.3275502219922477 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3129024201874766, + 3.3275502219922477 + ], + [ + 3.3116116182038695, + 3.3275452272844452 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6741411149940104, + "scoreError" : 0.039358034238974465, + "scoreConfidence" : [ + 1.6347830807550359, + 1.713499149232985 + ], + "scorePercentiles" : { + "0.0" : 1.6668245237734332, + "50.0" : 1.674424513338548, + "90.0" : 1.680890909525512, + "95.0" : 1.680890909525512, + "99.0" : 1.680890909525512, + "99.9" : 1.680890909525512, + "99.99" : 1.680890909525512, + "99.999" : 1.680890909525512, + "99.9999" : 1.680890909525512, + "100.0" : 1.680890909525512 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6768777758317097, + 1.680890909525512 + ], + [ + 1.6668245237734332, + 1.6719712508453863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8432130876598983, + "scoreError" : 0.04139592559380058, + "scoreConfidence" : [ + 0.8018171620660978, + 0.8846090132536989 + ], + "scorePercentiles" : { + "0.0" : 0.8339357877732736, + "50.0" : 0.8452000079301425, + "90.0" : 0.8485165470060348, + "95.0" : 0.8485165470060348, + "99.0" : 0.8485165470060348, + "99.9" : 0.8485165470060348, + "99.99" : 0.8485165470060348, + "99.999" : 0.8485165470060348, + "99.9999" : 0.8485165470060348, + "100.0" : 0.8485165470060348 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8339357877732736, + 0.8444850465139759 + ], + [ + 0.845914969346309, + 0.8485165470060348 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.037437139176333, + "scoreError" : 0.7043619399624873, + "scoreConfidence" : [ + 15.333075199213846, + 16.741799079138822 + ], + "scorePercentiles" : { + "0.0" : 15.798806477134223, + "50.0" : 16.04253471450666, + "90.0" : 16.278968865693592, + "95.0" : 16.278968865693592, + "99.0" : 16.278968865693592, + "99.9" : 16.278968865693592, + "99.99" : 16.278968865693592, + "99.999" : 16.278968865693592, + "99.9999" : 16.278968865693592, + "100.0" : 16.278968865693592 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.800191200473286, + 15.798806477134223, + 15.826201928389622 + ], + [ + 16.261586862743563, + 16.2588675006237, + 16.278968865693592 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2694.8845566737223, + "scoreError" : 188.06612129577456, + "scoreConfidence" : [ + 2506.818435377948, + 2882.9506779694966 + ], + "scorePercentiles" : { + "0.0" : 2631.427541740983, + "50.0" : 2695.829303337882, + "90.0" : 2758.953209506096, + "95.0" : 2758.953209506096, + "99.0" : 2758.953209506096, + "99.9" : 2758.953209506096, + "99.99" : 2758.953209506096, + "99.999" : 2758.953209506096, + "99.9999" : 2758.953209506096, + "100.0" : 2758.953209506096 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2753.490900271555, + 2755.695058103969, + 2758.953209506096 + ], + [ + 2631.427541740983, + 2638.1677064042087, + 2631.572924015522 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74784.30275247949, + "scoreError" : 1630.3998704373248, + "scoreConfidence" : [ + 73153.90288204217, + 76414.70262291681 + ], + "scorePercentiles" : { + "0.0" : 74224.7843242149, + "50.0" : 74775.82092588797, + "90.0" : 75352.73065250221, + "95.0" : 75352.73065250221, + "99.0" : 75352.73065250221, + "99.9" : 75352.73065250221, + "99.99" : 75352.73065250221, + "99.999" : 75352.73065250221, + "99.9999" : 75352.73065250221, + "100.0" : 75352.73065250221 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74263.39249391739, + 74224.7843242149, + 74274.44349371668 + ], + [ + 75313.26719246653, + 75277.19835805925, + 75352.73065250221 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 336.1185224107435, + "scoreError" : 5.3785567262035086, + "scoreConfidence" : [ + 330.73996568454, + 341.497079136947 + ], + "scorePercentiles" : { + "0.0" : 333.38271037258085, + "50.0" : 337.17422338754193, + "90.0" : 337.5327784569867, + "95.0" : 337.5327784569867, + "99.0" : 337.5327784569867, + "99.9" : 337.5327784569867, + "99.99" : 337.5327784569867, + "99.999" : 337.5327784569867, + "99.9999" : 337.5327784569867, + "100.0" : 337.5327784569867 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 337.03763809434224, + 337.3108086807416, + 337.5327784569867 + ], + [ + 337.50284781398994, + 333.38271037258085, + 333.94435104581964 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.43141528097944, + "scoreError" : 2.8009427265859266, + "scoreConfidence" : [ + 111.6304725543935, + 117.23235800756537 + ], + "scorePercentiles" : { + "0.0" : 113.30833164478857, + "50.0" : 114.43762995197244, + "90.0" : 115.5437693190163, + "95.0" : 115.5437693190163, + "99.0" : 115.5437693190163, + "99.9" : 115.5437693190163, + "99.99" : 115.5437693190163, + "99.999" : 115.5437693190163, + "99.9999" : 115.5437693190163, + "100.0" : 115.5437693190163 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.32963387282035, + 115.09833526371808, + 115.5437693190163 + ], + [ + 113.30833164478857, + 113.7769246402268, + 113.5314969453066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06149146215282423, + "scoreError" : 0.0011245371398410611, + "scoreConfidence" : [ + 0.060366925012983165, + 0.06261599929266529 + ], + "scorePercentiles" : { + "0.0" : 0.061098236781651334, + "50.0" : 0.061486946022951065, + "90.0" : 0.06196044229720687, + "95.0" : 0.06196044229720687, + "99.0" : 0.06196044229720687, + "99.9" : 0.06196044229720687, + "99.99" : 0.06196044229720687, + "99.999" : 0.06196044229720687, + "99.9999" : 0.06196044229720687, + "100.0" : 0.06196044229720687 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06178045218884756, + 0.06181514520166898, + 0.06196044229720687 + ], + [ + 0.06110105659051611, + 0.061098236781651334, + 0.06119343985705457 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.703225980431764E-4, + "scoreError" : 5.853931892235732E-6, + "scoreConfidence" : [ + 3.644686661509407E-4, + 3.7617652993541216E-4 + ], + "scorePercentiles" : { + "0.0" : 3.682098666525767E-4, + "50.0" : 3.700933378832847E-4, + "90.0" : 3.729604929701932E-4, + "95.0" : 3.729604929701932E-4, + "99.0" : 3.729604929701932E-4, + "99.9" : 3.729604929701932E-4, + "99.99" : 3.729604929701932E-4, + "99.999" : 3.729604929701932E-4, + "99.9999" : 3.729604929701932E-4, + "100.0" : 3.729604929701932E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7152963357769216E-4, + 3.7204061249331173E-4, + 3.729604929701932E-4 + ], + [ + 3.685379403764076E-4, + 3.682098666525767E-4, + 3.686570421888773E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12842081857070092, + "scoreError" : 0.004490872425351868, + "scoreConfidence" : [ + 0.12392994614534905, + 0.1329116909960528 + ], + "scorePercentiles" : { + "0.0" : 0.12681905886828823, + "50.0" : 0.1284635171913314, + "90.0" : 0.13011089740954215, + "95.0" : 0.13011089740954215, + "99.0" : 0.13011089740954215, + "99.9" : 0.13011089740954215, + "99.99" : 0.13011089740954215, + "99.999" : 0.13011089740954215, + "99.9999" : 0.13011089740954215, + "100.0" : 0.13011089740954215 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1268990734978745, + 0.12681905886828823, + 0.12718576749717017 + ], + [ + 0.13011089740954215, + 0.12974126688549262, + 0.1297688472658379 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013181385627247454, + "scoreError" : 2.5336854265830037E-4, + "scoreConfidence" : [ + 0.012928017084589153, + 0.013434754169905755 + ], + "scorePercentiles" : { + "0.0" : 0.013095606861726995, + "50.0" : 0.01317923264126971, + "90.0" : 0.013275303586813525, + "95.0" : 0.013275303586813525, + "99.0" : 0.013275303586813525, + "99.9" : 0.013275303586813525, + "99.99" : 0.013275303586813525, + "99.999" : 0.013275303586813525, + "99.9999" : 0.013275303586813525, + "100.0" : 0.013275303586813525 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013099001016470489, + 0.013095606861726995, + 0.013102833927539593 + ], + [ + 0.013275303586813525, + 0.013259937015934305, + 0.013255631354999829 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9815514904137438, + "scoreError" : 0.002173920531779427, + "scoreConfidence" : [ + 0.9793775698819643, + 0.9837254109455232 + ], + "scorePercentiles" : { + "0.0" : 0.9805930128443965, + "50.0" : 0.9817451579151826, + "90.0" : 0.9824273466601179, + "95.0" : 0.9824273466601179, + "99.0" : 0.9824273466601179, + "99.9" : 0.9824273466601179, + "99.99" : 0.9824273466601179, + "99.999" : 0.9824273466601179, + "99.9999" : 0.9824273466601179, + "100.0" : 0.9824273466601179 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9805930128443965, + 0.9806279314571484, + 0.9818093639308856 + ], + [ + 0.9816809518994797, + 0.9821703356904341, + 0.9824273466601179 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011340780563144496, + "scoreError" : 6.186687000832155E-4, + "scoreConfidence" : [ + 0.010722111863061282, + 0.011959449263227711 + ], + "scorePercentiles" : { + "0.0" : 0.011124146111661123, + "50.0" : 0.01134408245752975, + "90.0" : 0.01156234933588005, + "95.0" : 0.01156234933588005, + "99.0" : 0.01156234933588005, + "99.9" : 0.01156234933588005, + "99.99" : 0.01156234933588005, + "99.999" : 0.01156234933588005, + "99.9999" : 0.01156234933588005, + "100.0" : 0.01156234933588005 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011534057594714795, + 0.011528504198541923, + 0.01156234933588005 + ], + [ + 0.011135965421551508, + 0.011159660716517578, + 0.011124146111661123 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.4626516390351956, + "scoreError" : 0.35573125344180156, + "scoreConfidence" : [ + 3.1069203855933942, + 3.818382892476997 + ], + "scorePercentiles" : { + "0.0" : 3.3370025997331556, + "50.0" : 3.4615579650107016, + "90.0" : 3.5836596296561605, + "95.0" : 3.5836596296561605, + "99.0" : 3.5836596296561605, + "99.9" : 3.5836596296561605, + "99.99" : 3.5836596296561605, + "99.999" : 3.5836596296561605, + "99.9999" : 3.5836596296561605, + "100.0" : 3.5836596296561605 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3543576304493627, + 3.3498255874079037, + 3.3370025997331556 + ], + [ + 3.58230608739255, + 3.5836596296561605, + 3.56875829957204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.918934735397606, + "scoreError" : 0.06937621192197704, + "scoreConfidence" : [ + 2.849558523475629, + 2.988310947319583 + ], + "scorePercentiles" : { + "0.0" : 2.8936495923032406, + "50.0" : 2.910698691166844, + "90.0" : 2.9567036816435115, + "95.0" : 2.9567036816435115, + "99.0" : 2.9567036816435115, + "99.9" : 2.9567036816435115, + "99.99" : 2.9567036816435115, + "99.999" : 2.9567036816435115, + "99.9999" : 2.9567036816435115, + "100.0" : 2.9567036816435115 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9190311260945707, + 2.9397979667842447, + 2.9567036816435115 + ], + [ + 2.8936495923032406, + 2.9020597893209517, + 2.9023662562391177 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.181825310717497, + "scoreError" : 0.007967813393787004, + "scoreConfidence" : [ + 0.17385749732371, + 0.189793124111284 + ], + "scorePercentiles" : { + "0.0" : 0.17758674225742294, + "50.0" : 0.18271204289147855, + "90.0" : 0.18448476788547394, + "95.0" : 0.18448476788547394, + "99.0" : 0.18448476788547394, + "99.9" : 0.18448476788547394, + "99.99" : 0.18448476788547394, + "99.999" : 0.18448476788547394, + "99.9999" : 0.18448476788547394, + "100.0" : 0.18448476788547394 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18448476788547394, + 0.18434896012609225, + 0.1826942237404552 + ], + [ + 0.18272986204250188, + 0.17910730825303578, + 0.17758674225742294 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3202340092839608, + "scoreError" : 0.0013211108822978345, + "scoreConfidence" : [ + 0.3189128984016629, + 0.32155512016625865 + ], + "scorePercentiles" : { + "0.0" : 0.3197066691815857, + "50.0" : 0.32013615167755005, + "90.0" : 0.3209069882873921, + "95.0" : 0.3209069882873921, + "99.0" : 0.3209069882873921, + "99.9" : 0.3209069882873921, + "99.99" : 0.3209069882873921, + "99.999" : 0.3209069882873921, + "99.9999" : 0.3209069882873921, + "100.0" : 0.3209069882873921 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3209069882873921, + 0.32032071297245357, + 0.32064000298191614 + ], + [ + 0.3197066691815857, + 0.31995159038264653, + 0.3198780918977705 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1449938383777594, + "scoreError" : 0.006443120741508636, + "scoreConfidence" : [ + 0.13855071763625076, + 0.15143695911926802 + ], + "scorePercentiles" : { + "0.0" : 0.14277880988006852, + "50.0" : 0.14500988356295377, + "90.0" : 0.14713980126243306, + "95.0" : 0.14713980126243306, + "99.0" : 0.14713980126243306, + "99.9" : 0.14713980126243306, + "99.99" : 0.14713980126243306, + "99.999" : 0.14713980126243306, + "99.9999" : 0.14713980126243306, + "100.0" : 0.14713980126243306 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1471236607720826, + 0.14700593800899656, + 0.14713980126243306 + ], + [ + 0.143013829116911, + 0.1429009912260646, + 0.14277880988006852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.42052974135001775, + "scoreError" : 0.01099764743342641, + "scoreConfidence" : [ + 0.40953209391659134, + 0.43152738878344415 + ], + "scorePercentiles" : { + "0.0" : 0.4148416518709035, + "50.0" : 0.42176803755962167, + "90.0" : 0.42436678056439636, + "95.0" : 0.42436678056439636, + "99.0" : 0.42436678056439636, + "99.9" : 0.42436678056439636, + "99.99" : 0.42436678056439636, + "99.999" : 0.42436678056439636, + "99.9999" : 0.42436678056439636, + "100.0" : 0.42436678056439636 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.42238973973644195, + 0.423808107899644, + 0.42436678056439636 + ], + [ + 0.42114633538280133, + 0.41662583264591924, + 0.4148416518709035 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1555364832791507, + "scoreError" : 0.0029891635677358848, + "scoreConfidence" : [ + 0.15254731971141483, + 0.15852564684688658 + ], + "scorePercentiles" : { + "0.0" : 0.15440890871471805, + "50.0" : 0.1555592074448786, + "90.0" : 0.15654313662690586, + "95.0" : 0.15654313662690586, + "99.0" : 0.15654313662690586, + "99.9" : 0.15654313662690586, + "99.99" : 0.15654313662690586, + "99.999" : 0.15654313662690586, + "99.9999" : 0.15654313662690586, + "100.0" : 0.15654313662690586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15654313662690586, + 0.1564500871088861, + 0.15652432825682042 + ], + [ + 0.15462411118670275, + 0.15440890871471805, + 0.15466832778087108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04573451129948288, + "scoreError" : 0.0012527752540614772, + "scoreConfidence" : [ + 0.044481736045421404, + 0.04698728655354436 + ], + "scorePercentiles" : { + "0.0" : 0.045305776759421185, + "50.0" : 0.04561632253040336, + "90.0" : 0.046378149400339484, + "95.0" : 0.046378149400339484, + "99.0" : 0.046378149400339484, + "99.9" : 0.046378149400339484, + "99.99" : 0.046378149400339484, + "99.999" : 0.046378149400339484, + "99.9999" : 0.046378149400339484, + "100.0" : 0.046378149400339484 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046378149400339484, + 0.04616591756765491, + 0.04571055410909124 + ], + [ + 0.045324579008675, + 0.045305776759421185, + 0.04552209095171547 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9014688.75682218, + "scoreError" : 173268.30077746915, + "scoreConfidence" : [ + 8841420.456044711, + 9187957.057599649 + ], + "scorePercentiles" : { + "0.0" : 8916912.598039215, + "50.0" : 9043801.118047899, + "90.0" : 9069720.723481415, + "95.0" : 9069720.723481415, + "99.0" : 9069720.723481415, + "99.9" : 9069720.723481415, + "99.99" : 9069720.723481415, + "99.999" : 9069720.723481415, + "99.9999" : 9069720.723481415, + "100.0" : 9069720.723481415 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9038600.878048781, + 9069720.723481415, + 9049001.358047016 + ], + [ + 9055072.447058823, + 8958824.536257833, + 8916912.598039215 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-07T22:42:34Z-d9ef509a7fc499523f41f4537546a4dd273cf6f2-jdk17.json b/performance-results/2025-07-07T22:42:34Z-d9ef509a7fc499523f41f4537546a4dd273cf6f2-jdk17.json new file mode 100644 index 0000000000..39819b825a --- /dev/null +++ b/performance-results/2025-07-07T22:42:34Z-d9ef509a7fc499523f41f4537546a4dd273cf6f2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3179772336837954, + "scoreError" : 0.044381955591668916, + "scoreConfidence" : [ + 3.2735952780921265, + 3.3623591892754643 + ], + "scorePercentiles" : { + "0.0" : 3.309505944706429, + "50.0" : 3.318537668038254, + "90.0" : 3.3253276539522454, + "95.0" : 3.3253276539522454, + "99.0" : 3.3253276539522454, + "99.9" : 3.3253276539522454, + "99.99" : 3.3253276539522454, + "99.999" : 3.3253276539522454, + "99.9999" : 3.3253276539522454, + "100.0" : 3.3253276539522454 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.315790383627429, + 3.3253276539522454 + ], + [ + 3.309505944706429, + 3.3212849524490786 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6622561836525855, + "scoreError" : 0.020574307599716547, + "scoreConfidence" : [ + 1.641681876052869, + 1.682830491252302 + ], + "scorePercentiles" : { + "0.0" : 1.6588557259026173, + "50.0" : 1.662073862029811, + "90.0" : 1.666021284648103, + "95.0" : 1.666021284648103, + "99.0" : 1.666021284648103, + "99.9" : 1.666021284648103, + "99.99" : 1.666021284648103, + "99.999" : 1.666021284648103, + "99.9999" : 1.666021284648103, + "100.0" : 1.666021284648103 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.660556295363069, + 1.666021284648103 + ], + [ + 1.6588557259026173, + 1.6635914286965532 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8428306894526094, + "scoreError" : 0.024087334337411587, + "scoreConfidence" : [ + 0.8187433551151978, + 0.866918023790021 + ], + "scorePercentiles" : { + "0.0" : 0.8383750052149138, + "50.0" : 0.8433099239371674, + "90.0" : 0.8463279047211891, + "95.0" : 0.8463279047211891, + "99.0" : 0.8463279047211891, + "99.9" : 0.8463279047211891, + "99.99" : 0.8463279047211891, + "99.999" : 0.8463279047211891, + "99.9999" : 0.8463279047211891, + "100.0" : 0.8463279047211891 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8411720824727722, + 0.8454477654015626 + ], + [ + 0.8383750052149138, + 0.8463279047211891 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.928341236797332, + "scoreError" : 0.43850608913405387, + "scoreConfidence" : [ + 15.489835147663278, + 16.366847325931385 + ], + "scorePercentiles" : { + "0.0" : 15.631851616130561, + "50.0" : 15.98079310165991, + "90.0" : 16.07195369631061, + "95.0" : 16.07195369631061, + "99.0" : 16.07195369631061, + "99.9" : 16.07195369631061, + "99.99" : 16.07195369631061, + "99.999" : 16.07195369631061, + "99.9999" : 16.07195369631061, + "100.0" : 16.07195369631061 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.897077375738723, + 16.002900459834166, + 15.631851616130561 + ], + [ + 16.007578529284284, + 16.07195369631061, + 15.958685743485653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2599.7520288567107, + "scoreError" : 302.3614360358014, + "scoreConfidence" : [ + 2297.390592820909, + 2902.113464892512 + ], + "scorePercentiles" : { + "0.0" : 2486.216825780872, + "50.0" : 2595.1186396923886, + "90.0" : 2726.6502409390805, + "95.0" : 2726.6502409390805, + "99.0" : 2726.6502409390805, + "99.9" : 2726.6502409390805, + "99.99" : 2726.6502409390805, + "99.999" : 2726.6502409390805, + "99.9999" : 2726.6502409390805, + "100.0" : 2726.6502409390805 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2726.6502409390805, + 2672.2414247571724, + 2690.41470384476 + ], + [ + 2504.993123190774, + 2486.216825780872, + 2517.9958546276052 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76729.36243833984, + "scoreError" : 2810.9321112311795, + "scoreConfidence" : [ + 73918.43032710867, + 79540.29454957102 + ], + "scorePercentiles" : { + "0.0" : 75413.51372112431, + "50.0" : 76885.3183266782, + "90.0" : 77673.61132152652, + "95.0" : 77673.61132152652, + "99.0" : 77673.61132152652, + "99.9" : 77673.61132152652, + "99.99" : 77673.61132152652, + "99.999" : 77673.61132152652, + "99.9999" : 77673.61132152652, + "100.0" : 77673.61132152652 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75899.48210445554, + 75413.51372112431, + 76224.88587362839 + ], + [ + 77545.75077972801, + 77618.93082957633, + 77673.61132152652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.21152729871534, + "scoreError" : 11.276590970840466, + "scoreConfidence" : [ + 337.9349363278749, + 360.4881182695558 + ], + "scorePercentiles" : { + "0.0" : 345.4135675774814, + "50.0" : 348.8476038156191, + "90.0" : 354.8662693223416, + "95.0" : 354.8662693223416, + "99.0" : 354.8662693223416, + "99.9" : 354.8662693223416, + "99.99" : 354.8662693223416, + "99.999" : 354.8662693223416, + "99.9999" : 354.8662693223416, + "100.0" : 354.8662693223416 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.4135675774814, + 346.3101834150008, + 345.4317697641454 + ], + [ + 351.3850242162374, + 354.8662693223416, + 351.8623494970856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 109.43694598604448, + "scoreError" : 3.8330806035218843, + "scoreConfidence" : [ + 105.6038653825226, + 113.27002658956636 + ], + "scorePercentiles" : { + "0.0" : 107.74298613964223, + "50.0" : 109.33432508710804, + "90.0" : 111.3223466740526, + "95.0" : 111.3223466740526, + "99.0" : 111.3223466740526, + "99.9" : 111.3223466740526, + "99.99" : 111.3223466740526, + "99.999" : 111.3223466740526, + "99.9999" : 111.3223466740526, + "100.0" : 111.3223466740526 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.04835231638275, + 111.3223466740526, + 110.4126599975305 + ], + [ + 108.4750329308255, + 107.74298613964223, + 108.62029785783334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06276930135621368, + "scoreError" : 8.180630991347804E-4, + "scoreConfidence" : [ + 0.061951238257078906, + 0.06358736445534846 + ], + "scorePercentiles" : { + "0.0" : 0.06227668064343364, + "50.0" : 0.06284613863222183, + "90.0" : 0.06307034354423674, + "95.0" : 0.06307034354423674, + "99.0" : 0.06307034354423674, + "99.9" : 0.06307034354423674, + "99.99" : 0.06307034354423674, + "99.999" : 0.06307034354423674, + "99.9999" : 0.06307034354423674, + "100.0" : 0.06307034354423674 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06307034354423674, + 0.06276790410494602, + 0.06292437315949762 + ], + [ + 0.06227668064343364, + 0.06297191123019572, + 0.0626045954549723 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.9176789812820565E-4, + "scoreError" : 5.8286195474601557E-5, + "scoreConfidence" : [ + 3.334817026536041E-4, + 4.500540936028072E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7022717837265735E-4, + "50.0" : 3.895439988966469E-4, + "90.0" : 4.16843519504263E-4, + "95.0" : 4.16843519504263E-4, + "99.0" : 4.16843519504263E-4, + "99.9" : 4.16843519504263E-4, + "99.99" : 4.16843519504263E-4, + "99.999" : 4.16843519504263E-4, + "99.9999" : 4.16843519504263E-4, + "100.0" : 4.16843519504263E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7022717837265735E-4, + 3.7385320480978583E-4, + 3.7572240471911466E-4 + ], + [ + 4.16843519504263E-4, + 4.033655930741791E-4, + 4.1059548828923406E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12882819912825097, + "scoreError" : 0.004177637349988674, + "scoreConfidence" : [ + 0.1246505617782623, + 0.13300583647823963 + ], + "scorePercentiles" : { + "0.0" : 0.12715831988454301, + "50.0" : 0.1288186684001209, + "90.0" : 0.13050251340241165, + "95.0" : 0.13050251340241165, + "99.0" : 0.13050251340241165, + "99.9" : 0.13050251340241165, + "99.99" : 0.13050251340241165, + "99.999" : 0.13050251340241165, + "99.9999" : 0.13050251340241165, + "100.0" : 0.13050251340241165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12783469918699186, + 0.12749969741052875, + 0.12715831988454301 + ], + [ + 0.12980263761324992, + 0.13050251340241165, + 0.13017132727178057 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013054138897850322, + "scoreError" : 4.5383416670467737E-4, + "scoreConfidence" : [ + 0.012600304731145644, + 0.013507973064555 + ], + "scorePercentiles" : { + "0.0" : 0.012889926233227208, + "50.0" : 0.013035698222892949, + "90.0" : 0.013235337216089195, + "95.0" : 0.013235337216089195, + "99.0" : 0.013235337216089195, + "99.9" : 0.013235337216089195, + "99.99" : 0.013235337216089195, + "99.999" : 0.013235337216089195, + "99.9999" : 0.013235337216089195, + "100.0" : 0.013235337216089195 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013235337216089195, + 0.013126978319768967, + 0.013227828611300339 + ], + [ + 0.012900344880699292, + 0.012944418126016929, + 0.012889926233227208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9646815023881117, + "scoreError" : 0.031010418126798535, + "scoreConfidence" : [ + 0.9336710842613132, + 0.9956919205149102 + ], + "scorePercentiles" : { + "0.0" : 0.9522563815463722, + "50.0" : 0.9646899451581596, + "90.0" : 0.9768986981832389, + "95.0" : 0.9768986981832389, + "99.0" : 0.9768986981832389, + "99.9" : 0.9768986981832389, + "99.99" : 0.9768986981832389, + "99.999" : 0.9768986981832389, + "99.9999" : 0.9768986981832389, + "100.0" : 0.9768986981832389 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9563302923400593, + 0.9556109101767798, + 0.9522563815463722 + ], + [ + 0.97304959797626, + 0.9768986981832389, + 0.9739431341059602 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010831312673456377, + "scoreError" : 4.92220047129527E-4, + "scoreConfidence" : [ + 0.01033909262632685, + 0.011323532720585904 + ], + "scorePercentiles" : { + "0.0" : 0.010640821911044903, + "50.0" : 0.010807452107362147, + "90.0" : 0.011114534514261835, + "95.0" : 0.011114534514261835, + "99.0" : 0.011114534514261835, + "99.9" : 0.011114534514261835, + "99.99" : 0.011114534514261835, + "99.999" : 0.011114534514261835, + "99.9999" : 0.011114534514261835, + "100.0" : 0.011114534514261835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01073145331098396, + 0.010699605941551702, + 0.010640821911044903 + ], + [ + 0.010918009459155532, + 0.010883450903740335, + 0.011114534514261835 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3982641902945168, + "scoreError" : 0.2541062410605777, + "scoreConfidence" : [ + 3.144157949233939, + 3.6523704313550946 + ], + "scorePercentiles" : { + "0.0" : 3.2946570507246378, + "50.0" : 3.406327492420843, + "90.0" : 3.4902471772505232, + "95.0" : 3.4902471772505232, + "99.0" : 3.4902471772505232, + "99.9" : 3.4902471772505232, + "99.99" : 3.4902471772505232, + "99.999" : 3.4902471772505232, + "99.9999" : 3.4902471772505232, + "100.0" : 3.4902471772505232 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4792921488178026, + 3.4689798578363384, + 3.4902471772505232 + ], + [ + 3.2946570507246378, + 3.3127337801324503, + 3.3436751270053477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8692957377200057, + "scoreError" : 0.04661408342578394, + "scoreConfidence" : [ + 2.8226816542942217, + 2.9159098211457897 + ], + "scorePercentiles" : { + "0.0" : 2.8428308465036953, + "50.0" : 2.8688340281461073, + "90.0" : 2.891147969355305, + "95.0" : 2.891147969355305, + "99.0" : 2.891147969355305, + "99.9" : 2.891147969355305, + "99.99" : 2.891147969355305, + "99.999" : 2.891147969355305, + "99.9999" : 2.891147969355305, + "100.0" : 2.891147969355305 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8804319386520736, + 2.8639395085910655, + 2.891147969355305 + ], + [ + 2.8636956155167477, + 2.8428308465036953, + 2.8737285477011496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18011416649034798, + "scoreError" : 0.012591881445920133, + "scoreConfidence" : [ + 0.16752228504442784, + 0.1927060479362681 + ], + "scorePercentiles" : { + "0.0" : 0.17565802445108028, + "50.0" : 0.17996186928506674, + "90.0" : 0.1850035576172417, + "95.0" : 0.1850035576172417, + "99.0" : 0.1850035576172417, + "99.9" : 0.1850035576172417, + "99.99" : 0.1850035576172417, + "99.999" : 0.1850035576172417, + "99.9999" : 0.1850035576172417, + "100.0" : 0.1850035576172417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17616101985273394, + 0.17565802445108028, + 0.17630441124098659 + ], + [ + 0.1850035576172417, + 0.18393865845089852, + 0.18361932732914693 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.34556955133005357, + "scoreError" : 0.028966373167414836, + "scoreConfidence" : [ + 0.3166031781626387, + 0.3745359244974684 + ], + "scorePercentiles" : { + "0.0" : 0.33555554120528824, + "50.0" : 0.3454442617298198, + "90.0" : 0.35584910639433515, + "95.0" : 0.35584910639433515, + "99.0" : 0.35584910639433515, + "99.9" : 0.35584910639433515, + "99.99" : 0.35584910639433515, + "99.999" : 0.35584910639433515, + "99.9999" : 0.35584910639433515, + "100.0" : 0.35584910639433515 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.35429784748104587, + 0.35584910639433515, + 0.3548021745547435 + ], + [ + 0.33659067597859377, + 0.3363219623663147, + 0.33555554120528824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14512224421431838, + "scoreError" : 0.0030392361538840876, + "scoreConfidence" : [ + 0.14208300806043428, + 0.14816148036820248 + ], + "scorePercentiles" : { + "0.0" : 0.14374463335681123, + "50.0" : 0.1455985411303492, + "90.0" : 0.1460549326556544, + "95.0" : 0.1460549326556544, + "99.0" : 0.1460549326556544, + "99.9" : 0.1460549326556544, + "99.99" : 0.1460549326556544, + "99.999" : 0.1460549326556544, + "99.9999" : 0.1460549326556544, + "100.0" : 0.1460549326556544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1455807497961917, + 0.14374463335681123, + 0.1437453761157987 + ], + [ + 0.1460549326556544, + 0.14561633246450673, + 0.1459914408969474 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40011214047933, + "scoreError" : 0.02687909982744918, + "scoreConfidence" : [ + 0.37323304065188084, + 0.4269912403067792 + ], + "scorePercentiles" : { + "0.0" : 0.3910888125928823, + "50.0" : 0.39956063779791406, + "90.0" : 0.4097242616052772, + "95.0" : 0.4097242616052772, + "99.0" : 0.4097242616052772, + "99.9" : 0.4097242616052772, + "99.99" : 0.4097242616052772, + "99.999" : 0.4097242616052772, + "99.9999" : 0.4097242616052772, + "100.0" : 0.4097242616052772 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39180752836545996, + 0.3910888125928823, + 0.3912967872598505 + ], + [ + 0.4097242616052772, + 0.4094417058221422, + 0.4073137472303682 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15496893821552374, + "scoreError" : 0.0011346435053134173, + "scoreConfidence" : [ + 0.15383429471021032, + 0.15610358172083716 + ], + "scorePercentiles" : { + "0.0" : 0.1544363012524516, + "50.0" : 0.15505503897753825, + "90.0" : 0.15545565113712323, + "95.0" : 0.15545565113712323, + "99.0" : 0.15545565113712323, + "99.9" : 0.15545565113712323, + "99.99" : 0.15545565113712323, + "99.999" : 0.15545565113712323, + "99.9999" : 0.15545565113712323, + "100.0" : 0.15545565113712323 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1548946530621728, + 0.1544363012524516, + 0.154571309122666 + ], + [ + 0.15524028982582508, + 0.15545565113712323, + 0.15521542489290371 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04652006301007155, + "scoreError" : 0.001005773949428659, + "scoreConfidence" : [ + 0.045514289060642886, + 0.04752583695950021 + ], + "scorePercentiles" : { + "0.0" : 0.04615464651583543, + "50.0" : 0.04652105650404263, + "90.0" : 0.04713101404481143, + "95.0" : 0.04713101404481143, + "99.0" : 0.04713101404481143, + "99.9" : 0.04713101404481143, + "99.99" : 0.04713101404481143, + "99.999" : 0.04713101404481143, + "99.9999" : 0.04713101404481143, + "100.0" : 0.04713101404481143 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04713101404481143, + 0.04616709146938248, + 0.04615464651583543 + ], + [ + 0.04650214700972346, + 0.04653996599836181, + 0.046625513022314644 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8990981.808598017, + "scoreError" : 145391.99193079592, + "scoreConfidence" : [ + 8845589.816667221, + 9136373.800528813 + ], + "scorePercentiles" : { + "0.0" : 8931278.847321428, + "50.0" : 8987126.52909914, + "90.0" : 9083879.376930064, + "95.0" : 9083879.376930064, + "99.0" : 9083879.376930064, + "99.9" : 9083879.376930064, + "99.99" : 9083879.376930064, + "99.999" : 9083879.376930064, + "99.9999" : 9083879.376930064, + "100.0" : 9083879.376930064 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8983321.225314183, + 8990931.832884097, + 8957462.823634736 + ], + [ + 9083879.376930064, + 8931278.847321428, + 8999016.745503597 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-08T02:45:03Z-48f469d204c9b0e955bc8fbb7ae15d40f05711ea-jdk17.json b/performance-results/2025-07-08T02:45:03Z-48f469d204c9b0e955bc8fbb7ae15d40f05711ea-jdk17.json new file mode 100644 index 0000000000..8073a7d49c --- /dev/null +++ b/performance-results/2025-07-08T02:45:03Z-48f469d204c9b0e955bc8fbb7ae15d40f05711ea-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3111861877386053, + "scoreError" : 0.04470102755307947, + "scoreConfidence" : [ + 3.266485160185526, + 3.3558872152916845 + ], + "scorePercentiles" : { + "0.0" : 3.3049687089703568, + "50.0" : 3.3094569453262896, + "90.0" : 3.320862151331487, + "95.0" : 3.320862151331487, + "99.0" : 3.320862151331487, + "99.9" : 3.320862151331487, + "99.99" : 3.320862151331487, + "99.999" : 3.320862151331487, + "99.9999" : 3.320862151331487, + "100.0" : 3.320862151331487 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3078298410530467, + 3.3110840495995326 + ], + [ + 3.3049687089703568, + 3.320862151331487 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6753659085298707, + "scoreError" : 0.02860010959827416, + "scoreConfidence" : [ + 1.6467657989315965, + 1.7039660181281449 + ], + "scorePercentiles" : { + "0.0" : 1.6725027788648428, + "50.0" : 1.6735065161850493, + "90.0" : 1.6819478228845417, + "95.0" : 1.6819478228845417, + "99.0" : 1.6819478228845417, + "99.9" : 1.6819478228845417, + "99.99" : 1.6819478228845417, + "99.999" : 1.6819478228845417, + "99.9999" : 1.6819478228845417, + "100.0" : 1.6819478228845417 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6739139151999702, + 1.6819478228845417 + ], + [ + 1.6725027788648428, + 1.6730991171701284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8421832733153307, + "scoreError" : 0.0354929934469997, + "scoreConfidence" : [ + 0.806690279868331, + 0.8776762667623305 + ], + "scorePercentiles" : { + "0.0" : 0.8343765017386404, + "50.0" : 0.8436491691662704, + "90.0" : 0.8470582531901418, + "95.0" : 0.8470582531901418, + "99.0" : 0.8470582531901418, + "99.9" : 0.8470582531901418, + "99.99" : 0.8470582531901418, + "99.999" : 0.8470582531901418, + "99.9999" : 0.8470582531901418, + "100.0" : 0.8470582531901418 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8343765017386404, + 0.8470582531901418 + ], + [ + 0.8427841566094152, + 0.8445141817231258 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.877844446876482, + "scoreError" : 0.17759586155784932, + "scoreConfidence" : [ + 15.700248585318633, + 16.05544030843433 + ], + "scorePercentiles" : { + "0.0" : 15.778433816243677, + "50.0" : 15.875790957114207, + "90.0" : 15.959411956553302, + "95.0" : 15.959411956553302, + "99.0" : 15.959411956553302, + "99.9" : 15.959411956553302, + "99.99" : 15.959411956553302, + "99.999" : 15.959411956553302, + "99.9999" : 15.959411956553302, + "100.0" : 15.959411956553302 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.959411956553302, + 15.881307320211134, + 15.778433816243677 + ], + [ + 15.848763089624175, + 15.87027459401728, + 15.928875904609336 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2625.129232819502, + "scoreError" : 74.74242116017345, + "scoreConfidence" : [ + 2550.3868116593285, + 2699.871653979675 + ], + "scorePercentiles" : { + "0.0" : 2590.7559302768545, + "50.0" : 2633.3223789418107, + "90.0" : 2650.3388720892685, + "95.0" : 2650.3388720892685, + "99.0" : 2650.3388720892685, + "99.9" : 2650.3388720892685, + "99.99" : 2650.3388720892685, + "99.999" : 2650.3388720892685, + "99.9999" : 2650.3388720892685, + "100.0" : 2650.3388720892685 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2630.719588056037, + 2650.3388720892685, + 2635.925169827584 + ], + [ + 2590.7559302768545, + 2593.5786459636256, + 2649.4571907036425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76722.39059217849, + "scoreError" : 463.7358071425132, + "scoreConfidence" : [ + 76258.65478503598, + 77186.126399321 + ], + "scorePercentiles" : { + "0.0" : 76508.45852063182, + "50.0" : 76711.13400314134, + "90.0" : 76973.16205956138, + "95.0" : 76973.16205956138, + "99.0" : 76973.16205956138, + "99.9" : 76973.16205956138, + "99.99" : 76973.16205956138, + "99.999" : 76973.16205956138, + "99.9999" : 76973.16205956138, + "100.0" : 76973.16205956138 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76973.16205956138, + 76779.59769384586, + 76811.03124363018 + ], + [ + 76619.42372296487, + 76642.6703124368, + 76508.45852063182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 336.5046428066452, + "scoreError" : 11.584847503522433, + "scoreConfidence" : [ + 324.9197953031228, + 348.08949031016766 + ], + "scorePercentiles" : { + "0.0" : 330.8177965082622, + "50.0" : 336.09940638505753, + "90.0" : 342.3118122616779, + "95.0" : 342.3118122616779, + "99.0" : 342.3118122616779, + "99.9" : 342.3118122616779, + "99.99" : 342.3118122616779, + "99.999" : 342.3118122616779, + "99.9999" : 342.3118122616779, + "100.0" : 342.3118122616779 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 337.5329349398442, + 339.5512776513493, + 342.3118122616779 + ], + [ + 330.8177965082622, + 334.66587783027086, + 334.1481576484668 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.6112473012206, + "scoreError" : 10.262775363795884, + "scoreConfidence" : [ + 96.34847193742472, + 116.87402266501648 + ], + "scorePercentiles" : { + "0.0" : 102.27929920169393, + "50.0" : 106.99108172242693, + "90.0" : 111.23888913643067, + "95.0" : 111.23888913643067, + "99.0" : 111.23888913643067, + "99.9" : 111.23888913643067, + "99.99" : 111.23888913643067, + "99.999" : 111.23888913643067, + "99.9999" : 111.23888913643067, + "100.0" : 111.23888913643067 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 102.27929920169393, + 102.51190470324684, + 106.52684513921808 + ], + [ + 111.23888913643067, + 109.65522732109837, + 107.45531830563577 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06277289458362904, + "scoreError" : 0.0016463727331435215, + "scoreConfidence" : [ + 0.061126521850485525, + 0.06441926731677257 + ], + "scorePercentiles" : { + "0.0" : 0.06205951003487694, + "50.0" : 0.06269829759126007, + "90.0" : 0.06345989360027922, + "95.0" : 0.06345989360027922, + "99.0" : 0.06345989360027922, + "99.9" : 0.06345989360027922, + "99.99" : 0.06345989360027922, + "99.999" : 0.06345989360027922, + "99.9999" : 0.06345989360027922, + "100.0" : 0.06345989360027922 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06234717211259703, + 0.06337419657150099, + 0.06345989360027922 + ], + [ + 0.06300545099200473, + 0.062391144190515405, + 0.06205951003487694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7993614329277125E-4, + "scoreError" : 8.952824358270682E-6, + "scoreConfidence" : [ + 3.709833189345006E-4, + 3.888889676510419E-4 + ], + "scorePercentiles" : { + "0.0" : 3.767672024697854E-4, + "50.0" : 3.785163843943335E-4, + "90.0" : 3.84583105211169E-4, + "95.0" : 3.84583105211169E-4, + "99.0" : 3.84583105211169E-4, + "99.9" : 3.84583105211169E-4, + "99.99" : 3.84583105211169E-4, + "99.999" : 3.84583105211169E-4, + "99.9999" : 3.84583105211169E-4, + "100.0" : 3.84583105211169E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7824936950372465E-4, + 3.787833992849424E-4, + 3.7794966499175457E-4 + ], + [ + 3.767672024697854E-4, + 3.84583105211169E-4, + 3.832841182952514E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12830921352283547, + "scoreError" : 0.002731332017477503, + "scoreConfidence" : [ + 0.12557788150535798, + 0.13104054554031297 + ], + "scorePercentiles" : { + "0.0" : 0.1269519347983395, + "50.0" : 0.12827221420476245, + "90.0" : 0.1293692783958603, + "95.0" : 0.1293692783958603, + "99.0" : 0.1293692783958603, + "99.9" : 0.1293692783958603, + "99.99" : 0.1293692783958603, + "99.999" : 0.1293692783958603, + "99.9999" : 0.1293692783958603, + "100.0" : 0.1293692783958603 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12777093854370297, + 0.1269519347983395, + 0.12771911583948503 + ], + [ + 0.12927052369380315, + 0.1293692783958603, + 0.12877348986582193 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013348862864830328, + "scoreError" : 3.2105634440955406E-4, + "scoreConfidence" : [ + 0.013027806520420774, + 0.013669919209239883 + ], + "scorePercentiles" : { + "0.0" : 0.013227774104624892, + "50.0" : 0.013356163110647475, + "90.0" : 0.013468953135459332, + "95.0" : 0.013468953135459332, + "99.0" : 0.013468953135459332, + "99.9" : 0.013468953135459332, + "99.99" : 0.013468953135459332, + "99.999" : 0.013468953135459332, + "99.9999" : 0.013468953135459332, + "100.0" : 0.013468953135459332 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013468953135459332, + 0.013444068554458533, + 0.013444049000114273 + ], + [ + 0.013268277221180676, + 0.013240055173144269, + 0.013227774104624892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9968187037689585, + "scoreError" : 0.009986572694560615, + "scoreConfidence" : [ + 0.9868321310743979, + 1.0068052764635191 + ], + "scorePercentiles" : { + "0.0" : 0.9929747458047861, + "50.0" : 0.9963180555242077, + "90.0" : 1.0023362932745314, + "95.0" : 1.0023362932745314, + "99.0" : 1.0023362932745314, + "99.9" : 1.0023362932745314, + "99.99" : 1.0023362932745314, + "99.999" : 1.0023362932745314, + "99.9999" : 1.0023362932745314, + "100.0" : 1.0023362932745314 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9980668740518962, + 1.0023362932745314, + 0.9988648376947663 + ], + [ + 0.9929747458047861, + 0.9941002347912525, + 0.9945692369965191 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010905440239151456, + "scoreError" : 8.594165241699118E-4, + "scoreConfidence" : [ + 0.010046023714981544, + 0.011764856763321369 + ], + "scorePercentiles" : { + "0.0" : 0.010556125764507433, + "50.0" : 0.01092512002364807, + "90.0" : 0.011205883796085673, + "95.0" : 0.011205883796085673, + "99.0" : 0.011205883796085673, + "99.9" : 0.011205883796085673, + "99.99" : 0.011205883796085673, + "99.999" : 0.011205883796085673, + "99.9999" : 0.011205883796085673, + "100.0" : 0.011205883796085673 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01068130523880527, + 0.010647859976021686, + 0.010556125764507433 + ], + [ + 0.011168934808490868, + 0.011205883796085673, + 0.011172531850997794 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3453512570174113, + "scoreError" : 0.06386717355793192, + "scoreConfidence" : [ + 3.281484083459479, + 3.4092184305753435 + ], + "scorePercentiles" : { + "0.0" : 3.3175940039787797, + "50.0" : 3.3403724550869565, + "90.0" : 3.373957721322537, + "95.0" : 3.373957721322537, + "99.0" : 3.373957721322537, + "99.9" : 3.373957721322537, + "99.99" : 3.373957721322537, + "99.999" : 3.373957721322537, + "99.9999" : 3.373957721322537, + "100.0" : 3.373957721322537 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3707236138814016, + 3.373957721322537, + 3.335524458 + ], + [ + 3.3175940039787797, + 3.345220452173913, + 3.329087292747838 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.0079616733984746, + "scoreError" : 0.08355177916826348, + "scoreConfidence" : [ + 2.924409894230211, + 3.0915134525667383 + ], + "scorePercentiles" : { + "0.0" : 2.9821529499105544, + "50.0" : 2.999913718133117, + "90.0" : 3.0636365065849924, + "95.0" : 3.0636365065849924, + "99.0" : 3.0636365065849924, + "99.9" : 3.0636365065849924, + "99.99" : 3.0636365065849924, + "99.999" : 3.0636365065849924, + "99.9999" : 3.0636365065849924, + "100.0" : 3.0636365065849924 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.008593572330827, + 2.9821529499105544, + 2.9912338639354066 + ], + [ + 2.9888697149686285, + 3.01328343266044, + 3.0636365065849924 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18122155300118947, + "scoreError" : 0.009063308059644172, + "scoreConfidence" : [ + 0.1721582449415453, + 0.19028486106083364 + ], + "scorePercentiles" : { + "0.0" : 0.1780329494935109, + "50.0" : 0.1809839238952508, + "90.0" : 0.18515482881264927, + "95.0" : 0.18515482881264927, + "99.0" : 0.18515482881264927, + "99.9" : 0.18515482881264927, + "99.99" : 0.18515482881264927, + "99.999" : 0.18515482881264927, + "99.9999" : 0.18515482881264927, + "100.0" : 0.18515482881264927 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18313498903050945, + 0.18515482881264927, + 0.18401856169954364 + ], + [ + 0.17883285875999214, + 0.17815513021093138, + 0.1780329494935109 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31816100737555447, + "scoreError" : 0.008830802387586744, + "scoreConfidence" : [ + 0.3093302049879677, + 0.32699180976314124 + ], + "scorePercentiles" : { + "0.0" : 0.3145582155888274, + "50.0" : 0.31776938356964624, + "90.0" : 0.3220582074329329, + "95.0" : 0.3220582074329329, + "99.0" : 0.3220582074329329, + "99.9" : 0.3220582074329329, + "99.99" : 0.3220582074329329, + "99.999" : 0.3220582074329329, + "99.9999" : 0.3220582074329329, + "100.0" : 0.3220582074329329 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3158951409167009, + 0.3145582155888274, + 0.31576292491316704 + ], + [ + 0.3220582074329329, + 0.32104792917910685, + 0.31964362622259157 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1424024796974789, + "scoreError" : 0.004456492077122292, + "scoreConfidence" : [ + 0.13794598762035662, + 0.1468589717746012 + ], + "scorePercentiles" : { + "0.0" : 0.14066881949895205, + "50.0" : 0.14223852714229443, + "90.0" : 0.14494651903119202, + "95.0" : 0.14494651903119202, + "99.0" : 0.14494651903119202, + "99.9" : 0.14494651903119202, + "99.99" : 0.14494651903119202, + "99.999" : 0.14494651903119202, + "99.9999" : 0.14494651903119202, + "100.0" : 0.14494651903119202 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14147809809857959, + 0.14120629286924596, + 0.14066881949895205 + ], + [ + 0.14494651903119202, + 0.14299895618600927, + 0.14311619250089447 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40966062381724605, + "scoreError" : 0.022533144263186478, + "scoreConfidence" : [ + 0.3871274795540596, + 0.4321937680804325 + ], + "scorePercentiles" : { + "0.0" : 0.40210735778045836, + "50.0" : 0.409238245903968, + "90.0" : 0.41810533075507983, + "95.0" : 0.41810533075507983, + "99.0" : 0.41810533075507983, + "99.9" : 0.41810533075507983, + "99.99" : 0.41810533075507983, + "99.999" : 0.41810533075507983, + "99.9999" : 0.41810533075507983, + "100.0" : 0.41810533075507983 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4024812152688345, + 0.40246750116709595, + 0.40210735778045836 + ], + [ + 0.4159952765391015, + 0.41810533075507983, + 0.41680706139290624 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15530993485383823, + "scoreError" : 0.0018728554582300564, + "scoreConfidence" : [ + 0.1534370793956082, + 0.15718279031206828 + ], + "scorePercentiles" : { + "0.0" : 0.15455439169139465, + "50.0" : 0.15528874632037193, + "90.0" : 0.15612519779241865, + "95.0" : 0.15612519779241865, + "99.0" : 0.15612519779241865, + "99.9" : 0.15612519779241865, + "99.99" : 0.15612519779241865, + "99.999" : 0.15612519779241865, + "99.9999" : 0.15612519779241865, + "100.0" : 0.15612519779241865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15587509144896813, + 0.15569813772809366, + 0.15612519779241865 + ], + [ + 0.15455439169139465, + 0.1547274355495041, + 0.15487935491265023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047980968429249295, + "scoreError" : 0.0071018296586655, + "scoreConfidence" : [ + 0.040879138770583794, + 0.055082798087914796 + ], + "scorePercentiles" : { + "0.0" : 0.045308783196125246, + "50.0" : 0.04797000298196152, + "90.0" : 0.05074128772941075, + "95.0" : 0.05074128772941075, + "99.0" : 0.05074128772941075, + "99.9" : 0.05074128772941075, + "99.99" : 0.05074128772941075, + "99.999" : 0.05074128772941075, + "99.9999" : 0.05074128772941075, + "100.0" : 0.05074128772941075 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.05074128772941075, + 0.050183216461838785, + 0.049882316368624516 + ], + [ + 0.04605768959529852, + 0.04571251722419799, + 0.045308783196125246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9167712.766603893, + "scoreError" : 627819.1233977225, + "scoreConfidence" : [ + 8539893.64320617, + 9795531.890001616 + ], + "scorePercentiles" : { + "0.0" : 8894901.506666666, + "50.0" : 9234356.134530727, + "90.0" : 9458672.793005671, + "95.0" : 9458672.793005671, + "99.0" : 9458672.793005671, + "99.9" : 9458672.793005671, + "99.99" : 9458672.793005671, + "99.999" : 9458672.793005671, + "99.9999" : 9458672.793005671, + "100.0" : 9458672.793005671 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8904308.558718862, + 8894901.506666666, + 9253595.640148012 + ], + [ + 9279681.472170686, + 9215116.628913444, + 9458672.793005671 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-10T01:24:24Z-ecaebb16aeb692ba23468c5cd82b1cad34aa5554-jdk17.json b/performance-results/2025-07-10T01:24:24Z-ecaebb16aeb692ba23468c5cd82b1cad34aa5554-jdk17.json new file mode 100644 index 0000000000..496e0044c2 --- /dev/null +++ b/performance-results/2025-07-10T01:24:24Z-ecaebb16aeb692ba23468c5cd82b1cad34aa5554-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.323005923108179, + "scoreError" : 0.04315431117395122, + "scoreConfidence" : [ + 3.2798516119342276, + 3.3661602342821304 + ], + "scorePercentiles" : { + "0.0" : 3.3160301993257795, + "50.0" : 3.3225227127798456, + "90.0" : 3.330948067547246, + "95.0" : 3.330948067547246, + "99.0" : 3.330948067547246, + "99.9" : 3.330948067547246, + "99.99" : 3.330948067547246, + "99.999" : 3.330948067547246, + "99.9999" : 3.330948067547246, + "100.0" : 3.330948067547246 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.319237229857945, + 3.3258081957017462 + ], + [ + 3.3160301993257795, + 3.330948067547246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.673868262976891, + "scoreError" : 0.03020656530751464, + "scoreConfidence" : [ + 1.6436616976693765, + 1.7040748282844056 + ], + "scorePercentiles" : { + "0.0" : 1.6668959889018127, + "50.0" : 1.6758426967660927, + "90.0" : 1.6768916694735663, + "95.0" : 1.6768916694735663, + "99.0" : 1.6768916694735663, + "99.9" : 1.6768916694735663, + "99.99" : 1.6768916694735663, + "99.999" : 1.6768916694735663, + "99.9999" : 1.6768916694735663, + "100.0" : 1.6768916694735663 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6668959889018127, + 1.6768916694735663 + ], + [ + 1.6758777982453095, + 1.675807595286876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8442386528591477, + "scoreError" : 0.05158203258772448, + "scoreConfidence" : [ + 0.7926566202714231, + 0.8958206854468722 + ], + "scorePercentiles" : { + "0.0" : 0.8324064853223972, + "50.0" : 0.8473190211568677, + "90.0" : 0.8499100838004581, + "95.0" : 0.8499100838004581, + "99.0" : 0.8499100838004581, + "99.9" : 0.8499100838004581, + "99.99" : 0.8499100838004581, + "99.999" : 0.8499100838004581, + "99.9999" : 0.8499100838004581, + "100.0" : 0.8499100838004581 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8324064853223972, + 0.8472404232345855 + ], + [ + 0.8473976190791499, + 0.8499100838004581 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.014154586259714, + "scoreError" : 0.1540343587331148, + "scoreConfidence" : [ + 15.860120227526599, + 16.168188944992828 + ], + "scorePercentiles" : { + "0.0" : 15.952568887888775, + "50.0" : 16.01106336493644, + "90.0" : 16.0848092840248, + "95.0" : 16.0848092840248, + "99.0" : 16.0848092840248, + "99.9" : 16.0848092840248, + "99.99" : 16.0848092840248, + "99.999" : 16.0848092840248, + "99.9999" : 16.0848092840248, + "100.0" : 16.0848092840248 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.0848092840248, + 16.04405008087214, + 16.058000326794936 + ], + [ + 15.952568887888775, + 15.978076649000737, + 15.967422288976893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2596.719602636972, + "scoreError" : 45.01215347233643, + "scoreConfidence" : [ + 2551.7074491646354, + 2641.7317561093087 + ], + "scorePercentiles" : { + "0.0" : 2579.2937183539243, + "50.0" : 2597.756551787292, + "90.0" : 2612.1209995924146, + "95.0" : 2612.1209995924146, + "99.0" : 2612.1209995924146, + "99.9" : 2612.1209995924146, + "99.99" : 2612.1209995924146, + "99.999" : 2612.1209995924146, + "99.9999" : 2612.1209995924146, + "100.0" : 2612.1209995924146 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2609.3685423544284, + 2612.1209995924146, + 2612.1157164536526 + ], + [ + 2579.2937183539243, + 2586.144561220156, + 2581.2740778472557 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72962.98512175732, + "scoreError" : 4736.504566248494, + "scoreConfidence" : [ + 68226.48055550882, + 77699.48968800581 + ], + "scorePercentiles" : { + "0.0" : 71336.90040608442, + "50.0" : 72977.00617270188, + "90.0" : 74628.15749514847, + "95.0" : 74628.15749514847, + "99.0" : 74628.15749514847, + "99.9" : 74628.15749514847, + "99.99" : 74628.15749514847, + "99.999" : 74628.15749514847, + "99.9999" : 74628.15749514847, + "100.0" : 74628.15749514847 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74443.86631713864, + 74436.170108594, + 74628.15749514847 + ], + [ + 71517.84223680975, + 71336.90040608442, + 71414.97416676856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 333.47620038744043, + "scoreError" : 1.9553043344013494, + "scoreConfidence" : [ + 331.52089605303905, + 335.4315047218418 + ], + "scorePercentiles" : { + "0.0" : 332.3582652408605, + "50.0" : 333.44214791303096, + "90.0" : 334.3035836037439, + "95.0" : 334.3035836037439, + "99.0" : 334.3035836037439, + "99.9" : 334.3035836037439, + "99.99" : 334.3035836037439, + "99.999" : 334.3035836037439, + "99.9999" : 334.3035836037439, + "100.0" : 334.3035836037439 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 334.3035836037439, + 334.10335365560536, + 333.32188391657627 + ], + [ + 332.3582652408605, + 333.56241190948566, + 333.207703998371 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.4578486544778, + "scoreError" : 3.5201569945154336, + "scoreConfidence" : [ + 108.93769165996237, + 115.97800564899323 + ], + "scorePercentiles" : { + "0.0" : 111.12071324869143, + "50.0" : 112.48890692528505, + "90.0" : 113.87634312350211, + "95.0" : 113.87634312350211, + "99.0" : 113.87634312350211, + "99.9" : 113.87634312350211, + "99.99" : 113.87634312350211, + "99.999" : 113.87634312350211, + "99.9999" : 113.87634312350211, + "100.0" : 113.87634312350211 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.87634312350211, + 113.3029176413511, + 113.55693511080062 + ], + [ + 111.12071324869143, + 111.21528659330252, + 111.674896209219 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062176378242574694, + "scoreError" : 0.001597868950891, + "scoreConfidence" : [ + 0.060578509291683694, + 0.0637742471934657 + ], + "scorePercentiles" : { + "0.0" : 0.06154697670482521, + "50.0" : 0.062192199937072534, + "90.0" : 0.0627719292758099, + "95.0" : 0.0627719292758099, + "99.0" : 0.0627719292758099, + "99.9" : 0.0627719292758099, + "99.99" : 0.0627719292758099, + "99.999" : 0.0627719292758099, + "99.9999" : 0.0627719292758099, + "100.0" : 0.0627719292758099 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061761136966081175, + 0.06154697670482521, + 0.061677238205961625 + ], + [ + 0.0626232629080639, + 0.06267772539470633, + 0.0627719292758099 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6888442651416214E-4, + "scoreError" : 2.134356696497218E-5, + "scoreConfidence" : [ + 3.4754085954919E-4, + 3.902279934791343E-4 + ], + "scorePercentiles" : { + "0.0" : 3.604473438141589E-4, + "50.0" : 3.686788237354444E-4, + "90.0" : 3.773868659548477E-4, + "95.0" : 3.773868659548477E-4, + "99.0" : 3.773868659548477E-4, + "99.9" : 3.773868659548477E-4, + "99.99" : 3.773868659548477E-4, + "99.999" : 3.773868659548477E-4, + "99.9999" : 3.773868659548477E-4, + "100.0" : 3.773868659548477E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.604473438141589E-4, + 3.6252952839136565E-4, + 3.6316448081670754E-4 + ], + [ + 3.773868659548477E-4, + 3.741931666541812E-4, + 3.7558517345371147E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12730998644290217, + "scoreError" : 0.0023791726137559342, + "scoreConfidence" : [ + 0.12493081382914624, + 0.12968915905665812 + ], + "scorePercentiles" : { + "0.0" : 0.1264087550625711, + "50.0" : 0.12727730516329772, + "90.0" : 0.1281651864506703, + "95.0" : 0.1281651864506703, + "99.0" : 0.1281651864506703, + "99.9" : 0.1281651864506703, + "99.99" : 0.1281651864506703, + "99.999" : 0.1281651864506703, + "99.9999" : 0.1281651864506703, + "100.0" : 0.1281651864506703 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1281651864506703, + 0.12816447271422346, + 0.12789825723567252 + ], + [ + 0.1266563530909229, + 0.1265668941033527, + 0.1264087550625711 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0132658907922358, + "scoreError" : 6.420574643064141E-4, + "scoreConfidence" : [ + 0.012623833327929386, + 0.013907948256542214 + ], + "scorePercentiles" : { + "0.0" : 0.01305284900525501, + "50.0" : 0.013263493753057905, + "90.0" : 0.013480998916145522, + "95.0" : 0.013480998916145522, + "99.0" : 0.013480998916145522, + "99.9" : 0.013480998916145522, + "99.99" : 0.013480998916145522, + "99.999" : 0.013480998916145522, + "99.9999" : 0.013480998916145522, + "100.0" : 0.013480998916145522 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01305663237820928, + 0.013061348668021546, + 0.01305284900525501 + ], + [ + 0.013480998916145522, + 0.013477876947689189, + 0.013465638838094263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.979885543890148, + "scoreError" : 0.04365298879395025, + "scoreConfidence" : [ + 0.9362325550961977, + 1.0235385326840982 + ], + "scorePercentiles" : { + "0.0" : 0.96500151288237, + "50.0" : 0.979892679717701, + "90.0" : 0.9948080274544912, + "95.0" : 0.9948080274544912, + "99.0" : 0.9948080274544912, + "99.9" : 0.9948080274544912, + "99.99" : 0.9948080274544912, + "99.999" : 0.9948080274544912, + "99.9999" : 0.9948080274544912, + "100.0" : 0.9948080274544912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9658729567316979, + 0.96500151288237, + 0.9661772877016713 + ], + [ + 0.9948080274544912, + 0.9936080717337308, + 0.9938454068369273 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011066147284259961, + "scoreError" : 1.1634427171318027E-4, + "scoreConfidence" : [ + 0.01094980301254678, + 0.011182491555973142 + ], + "scorePercentiles" : { + "0.0" : 0.011028912152653706, + "50.0" : 0.011055648834345812, + "90.0" : 0.01112291139955732, + "95.0" : 0.01112291139955732, + "99.0" : 0.01112291139955732, + "99.9" : 0.01112291139955732, + "99.99" : 0.01112291139955732, + "99.999" : 0.01112291139955732, + "99.9999" : 0.01112291139955732, + "100.0" : 0.01112291139955732 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011030897964631445, + 0.011028912152653706, + 0.011031285301728987 + ], + [ + 0.011080012366962638, + 0.011102864520025669, + 0.01112291139955732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.4680176054707488, + "scoreError" : 0.7913755381501821, + "scoreConfidence" : [ + 2.6766420673205666, + 4.259393143620931 + ], + "scorePercentiles" : { + "0.0" : 3.1984932007672633, + "50.0" : 3.4700025430439356, + "90.0" : 3.7328222425373134, + "95.0" : 3.7328222425373134, + "99.0" : 3.7328222425373134, + "99.9" : 3.7328222425373134, + "99.99" : 3.7328222425373134, + "99.999" : 3.7328222425373134, + "99.9999" : 3.7328222425373134, + "100.0" : 3.7328222425373134 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7148553781575036, + 3.7287188635346755, + 3.7328222425373134 + ], + [ + 3.1984932007672633, + 3.2251497079303677, + 3.20806623989737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9458121083249114, + "scoreError" : 0.09713012775807732, + "scoreConfidence" : [ + 2.848681980566834, + 3.0429422360829887 + ], + "scorePercentiles" : { + "0.0" : 2.907372673837209, + "50.0" : 2.941439248068595, + "90.0" : 2.9957614534291706, + "95.0" : 2.9957614534291706, + "99.0" : 2.9957614534291706, + "99.9" : 2.9957614534291706, + "99.99" : 2.9957614534291706, + "99.999" : 2.9957614534291706, + "99.9999" : 2.9957614534291706, + "100.0" : 2.9957614534291706 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9957614534291706, + 2.9753003117192147, + 2.935184107100939 + ], + [ + 2.947694389036251, + 2.913559714826682, + 2.907372673837209 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1812379655142996, + "scoreError" : 0.0051469256021169415, + "scoreConfidence" : [ + 0.17609103991218267, + 0.18638489111641654 + ], + "scorePercentiles" : { + "0.0" : 0.17882158725390268, + "50.0" : 0.18221568091872486, + "90.0" : 0.18278863983988008, + "95.0" : 0.18278863983988008, + "99.0" : 0.18278863983988008, + "99.9" : 0.18278863983988008, + "99.99" : 0.18278863983988008, + "99.999" : 0.18278863983988008, + "99.9999" : 0.18278863983988008, + "100.0" : 0.18278863983988008 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18278863983988008, + 0.1823920969377519, + 0.18242989977561705 + ], + [ + 0.18203926489969782, + 0.17895630437894813, + 0.17882158725390268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33161202983987215, + "scoreError" : 0.0038698449713568182, + "scoreConfidence" : [ + 0.3277421848685153, + 0.335481874811229 + ], + "scorePercentiles" : { + "0.0" : 0.3302999030254987, + "50.0" : 0.3315259270111735, + "90.0" : 0.3331047863495553, + "95.0" : 0.3331047863495553, + "99.0" : 0.3331047863495553, + "99.9" : 0.3331047863495553, + "99.99" : 0.3331047863495553, + "99.999" : 0.3331047863495553, + "99.9999" : 0.3331047863495553, + "100.0" : 0.3331047863495553 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3302999030254987, + 0.3303105337076796, + 0.3304791277594184 + ], + [ + 0.3331047863495553, + 0.3325727262629286, + 0.3329051019341523 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14245758436713765, + "scoreError" : 0.00563701590517682, + "scoreConfidence" : [ + 0.13682056846196083, + 0.14809460027231447 + ], + "scorePercentiles" : { + "0.0" : 0.14041816567440815, + "50.0" : 0.14251290525350271, + "90.0" : 0.14436567547278764, + "95.0" : 0.14436567547278764, + "99.0" : 0.14436567547278764, + "99.9" : 0.14436567547278764, + "99.99" : 0.14436567547278764, + "99.999" : 0.14436567547278764, + "99.9999" : 0.14436567547278764, + "100.0" : 0.14436567547278764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14041816567440815, + 0.140652842501301, + 0.14080859239650803 + ], + [ + 0.14436567547278764, + 0.1442830120473236, + 0.1442172181104974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4143546864033436, + "scoreError" : 0.03462237626150933, + "scoreConfidence" : [ + 0.3797323101418343, + 0.44897706266485293 + ], + "scorePercentiles" : { + "0.0" : 0.4030289238302503, + "50.0" : 0.4128423201026994, + "90.0" : 0.4314309465895854, + "95.0" : 0.4314309465895854, + "99.0" : 0.4314309465895854, + "99.9" : 0.4314309465895854, + "99.99" : 0.4314309465895854, + "99.999" : 0.4314309465895854, + "99.9999" : 0.4314309465895854, + "100.0" : 0.4314309465895854 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4030289238302503, + 0.40363529201646753, + 0.40392738690524277 + ], + [ + 0.4314309465895854, + 0.4223483157783597, + 0.42175725330015607 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15547550080585767, + "scoreError" : 0.0040648289914254135, + "scoreConfidence" : [ + 0.15141067181443227, + 0.15954032979728308 + ], + "scorePercentiles" : { + "0.0" : 0.1533972472082464, + "50.0" : 0.15618186896438918, + "90.0" : 0.15680970081382403, + "95.0" : 0.15680970081382403, + "99.0" : 0.15680970081382403, + "99.9" : 0.15680970081382403, + "99.99" : 0.15680970081382403, + "99.999" : 0.15680970081382403, + "99.9999" : 0.15680970081382403, + "100.0" : 0.15680970081382403 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15680970081382403, + 0.15639404070813068, + 0.15633344265011648 + ], + [ + 0.1560302952786619, + 0.1533972472082464, + 0.15388827817616643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047523319880979166, + "scoreError" : 0.005152506381493881, + "scoreConfidence" : [ + 0.04237081349948529, + 0.052675826262473045 + ], + "scorePercentiles" : { + "0.0" : 0.045832362385993856, + "50.0" : 0.04750050541317424, + "90.0" : 0.04924132040278701, + "95.0" : 0.04924132040278701, + "99.0" : 0.04924132040278701, + "99.9" : 0.04924132040278701, + "99.99" : 0.04924132040278701, + "99.999" : 0.04924132040278701, + "99.9999" : 0.04924132040278701, + "100.0" : 0.04924132040278701 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04584105408254946, + 0.04586557592004843, + 0.045832362385993856 + ], + [ + 0.049135434906300055, + 0.04924132040278701, + 0.049224171588196204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8841982.883323878, + "scoreError" : 201193.75607458787, + "scoreConfidence" : [ + 8640789.12724929, + 9043176.639398467 + ], + "scorePercentiles" : { + "0.0" : 8775809.737719297, + "50.0" : 8819903.516331566, + "90.0" : 8941838.508489722, + "95.0" : 8941838.508489722, + "99.0" : 8941838.508489722, + "99.9" : 8941838.508489722, + "99.99" : 8941838.508489722, + "99.999" : 8941838.508489722, + "99.9999" : 8941838.508489722, + "100.0" : 8941838.508489722 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8781483.432835821, + 8775809.737719297, + 8790613.151142355 + ], + [ + 8912958.588235294, + 8941838.508489722, + 8849193.881520778 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-10T01:28:11Z-49a68f9b969ae7d6d6d4af1482deedb1522fdae2-jdk17.json b/performance-results/2025-07-10T01:28:11Z-49a68f9b969ae7d6d6d4af1482deedb1522fdae2-jdk17.json new file mode 100644 index 0000000000..4b1bd189df --- /dev/null +++ b/performance-results/2025-07-10T01:28:11Z-49a68f9b969ae7d6d6d4af1482deedb1522fdae2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3386711035583634, + "scoreError" : 0.047335172573526624, + "scoreConfidence" : [ + 3.291335930984837, + 3.38600627613189 + ], + "scorePercentiles" : { + "0.0" : 3.3302764451585163, + "50.0" : 3.339187001546528, + "90.0" : 3.346033965981881, + "95.0" : 3.346033965981881, + "99.0" : 3.346033965981881, + "99.9" : 3.346033965981881, + "99.99" : 3.346033965981881, + "99.999" : 3.346033965981881, + "99.9999" : 3.346033965981881, + "100.0" : 3.346033965981881 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3302764451585163, + 3.34341547809828 + ], + [ + 3.334958524994777, + 3.346033965981881 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6880200346087548, + "scoreError" : 0.02934086640834834, + "scoreConfidence" : [ + 1.6586791682004065, + 1.7173609010171031 + ], + "scorePercentiles" : { + "0.0" : 1.6825774172996646, + "50.0" : 1.6880061953836756, + "90.0" : 1.6934903303680033, + "95.0" : 1.6934903303680033, + "99.0" : 1.6934903303680033, + "99.9" : 1.6934903303680033, + "99.99" : 1.6934903303680033, + "99.999" : 1.6934903303680033, + "99.9999" : 1.6934903303680033, + "100.0" : 1.6934903303680033 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6825774172996646, + 1.6869331906092062 + ], + [ + 1.6890792001581452, + 1.6934903303680033 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8477616128920233, + "scoreError" : 0.03181944314820865, + "scoreConfidence" : [ + 0.8159421697438147, + 0.879581056040232 + ], + "scorePercentiles" : { + "0.0" : 0.8429903065929959, + "50.0" : 0.8467150912270157, + "90.0" : 0.8546259625210659, + "95.0" : 0.8546259625210659, + "99.0" : 0.8546259625210659, + "99.9" : 0.8546259625210659, + "99.99" : 0.8546259625210659, + "99.999" : 0.8546259625210659, + "99.9999" : 0.8546259625210659, + "100.0" : 0.8546259625210659 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8472917331416456, + 0.8546259625210659 + ], + [ + 0.8429903065929959, + 0.8461384493123858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.34542776986988, + "scoreError" : 0.3809278845808266, + "scoreConfidence" : [ + 15.964499885289053, + 16.726355654450707 + ], + "scorePercentiles" : { + "0.0" : 16.218984517815493, + "50.0" : 16.33571789275313, + "90.0" : 16.485411400695025, + "95.0" : 16.485411400695025, + "99.0" : 16.485411400695025, + "99.9" : 16.485411400695025, + "99.99" : 16.485411400695025, + "99.999" : 16.485411400695025, + "99.9999" : 16.485411400695025, + "100.0" : 16.485411400695025 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.221132507036504, + 16.22594683304194, + 16.218984517815493 + ], + [ + 16.485411400695025, + 16.475602408165997, + 16.44548895246432 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2659.3394598612563, + "scoreError" : 119.998444375737, + "scoreConfidence" : [ + 2539.341015485519, + 2779.3379042369934 + ], + "scorePercentiles" : { + "0.0" : 2617.9552038750894, + "50.0" : 2658.096153759663, + "90.0" : 2706.0509268899073, + "95.0" : 2706.0509268899073, + "99.0" : 2706.0509268899073, + "99.9" : 2706.0509268899073, + "99.99" : 2706.0509268899073, + "99.999" : 2706.0509268899073, + "99.9999" : 2706.0509268899073, + "100.0" : 2706.0509268899073 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2692.4137442399046, + 2695.990774844529, + 2706.0509268899073 + ], + [ + 2619.8475460386835, + 2623.778563279422, + 2617.9552038750894 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75087.19970446477, + "scoreError" : 4797.158260667454, + "scoreConfidence" : [ + 70290.04144379732, + 79884.35796513222 + ], + "scorePercentiles" : { + "0.0" : 73489.34419758937, + "50.0" : 75074.53538069059, + "90.0" : 76703.66991430972, + "95.0" : 76703.66991430972, + "99.0" : 76703.66991430972, + "99.9" : 76703.66991430972, + "99.99" : 76703.66991430972, + "99.999" : 76703.66991430972, + "99.9999" : 76703.66991430972, + "100.0" : 76703.66991430972 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76703.66991430972, + 76604.12674456972, + 76637.63962183472 + ], + [ + 73489.34419758937, + 73544.94401681147, + 73543.4737316737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.5812539036665, + "scoreError" : 3.646295318685582, + "scoreConfidence" : [ + 353.9349585849809, + 361.2275492223521 + ], + "scorePercentiles" : { + "0.0" : 355.96787126545604, + "50.0" : 357.73720973394086, + "90.0" : 358.99393135118805, + "95.0" : 358.99393135118805, + "99.0" : 358.99393135118805, + "99.9" : 358.99393135118805, + "99.99" : 358.99393135118805, + "99.999" : 358.99393135118805, + "99.9999" : 358.99393135118805, + "100.0" : 358.99393135118805 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 358.99393135118805, + 358.570202816146, + 358.6239923703594 + ], + [ + 356.4273089671137, + 355.96787126545604, + 356.9042166517358 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.98566579693492, + "scoreError" : 2.149268750674122, + "scoreConfidence" : [ + 112.8363970462608, + 117.13493454760905 + ], + "scorePercentiles" : { + "0.0" : 113.60100727569281, + "50.0" : 115.10344375336534, + "90.0" : 115.67250089874734, + "95.0" : 115.67250089874734, + "99.0" : 115.67250089874734, + "99.9" : 115.67250089874734, + "99.99" : 115.67250089874734, + "99.999" : 115.67250089874734, + "99.9999" : 115.67250089874734, + "100.0" : 115.67250089874734 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.67250089874734, + 115.3082896786432, + 115.6228126383617 + ], + [ + 113.60100727569281, + 114.8107864620769, + 114.89859782808747 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06205823492492347, + "scoreError" : 0.002462803424417031, + "scoreConfidence" : [ + 0.05959543150050644, + 0.0645210383493405 + ], + "scorePercentiles" : { + "0.0" : 0.061113345895998976, + "50.0" : 0.062083060660186505, + "90.0" : 0.06291792813011199, + "95.0" : 0.06291792813011199, + "99.0" : 0.06291792813011199, + "99.9" : 0.06291792813011199, + "99.99" : 0.06291792813011199, + "99.999" : 0.06291792813011199, + "99.9999" : 0.06291792813011199, + "100.0" : 0.06291792813011199 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06128660753815039, + 0.061113345895998976, + 0.06138426071290459 + ], + [ + 0.06278186060746842, + 0.06291792813011199, + 0.06286540666490646 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.743359031687043E-4, + "scoreError" : 2.7932749301509125E-5, + "scoreConfidence" : [ + 3.464031538671952E-4, + 4.0226865247021344E-4 + ], + "scorePercentiles" : { + "0.0" : 3.648290643195147E-4, + "50.0" : 3.7433905038306367E-4, + "90.0" : 3.8389494331663793E-4, + "95.0" : 3.8389494331663793E-4, + "99.0" : 3.8389494331663793E-4, + "99.9" : 3.8389494331663793E-4, + "99.99" : 3.8389494331663793E-4, + "99.999" : 3.8389494331663793E-4, + "99.9999" : 3.8389494331663793E-4, + "100.0" : 3.8389494331663793E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8389494331663793E-4, + 3.8321592089950304E-4, + 3.831597455898701E-4 + ], + [ + 3.655183551762572E-4, + 3.6539738971044306E-4, + 3.648290643195147E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12784193772271693, + "scoreError" : 0.005973645277113812, + "scoreConfidence" : [ + 0.12186829244560311, + 0.13381558299983073 + ], + "scorePercentiles" : { + "0.0" : 0.125846247042686, + "50.0" : 0.12772844797683292, + "90.0" : 0.13019946719700026, + "95.0" : 0.13019946719700026, + "99.0" : 0.13019946719700026, + "99.9" : 0.13019946719700026, + "99.99" : 0.13019946719700026, + "99.999" : 0.13019946719700026, + "99.9999" : 0.13019946719700026, + "100.0" : 0.13019946719700026 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.13019946719700026, + 0.12948817115332323, + 0.12963477625677322 + ], + [ + 0.125846247042686, + 0.12596872480034263, + 0.1259142398861762 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013209420583128352, + "scoreError" : 3.2622524769913836E-4, + "scoreConfidence" : [ + 0.012883195335429214, + 0.01353564583082749 + ], + "scorePercentiles" : { + "0.0" : 0.013095547648730405, + "50.0" : 0.013209395008418796, + "90.0" : 0.013322633812630477, + "95.0" : 0.013322633812630477, + "99.0" : 0.013322633812630477, + "99.9" : 0.013322633812630477, + "99.99" : 0.013322633812630477, + "99.999" : 0.013322633812630477, + "99.9999" : 0.013322633812630477, + "100.0" : 0.013322633812630477 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013095547648730405, + 0.013098903132298447, + 0.01311639201615918 + ], + [ + 0.013320648888273187, + 0.013322633812630477, + 0.013302398000678412 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0333141812876503, + "scoreError" : 0.0880836785083081, + "scoreConfidence" : [ + 0.9452305027793422, + 1.1213978597959584 + ], + "scorePercentiles" : { + "0.0" : 1.0003615240572172, + "50.0" : 1.036171193633142, + "90.0" : 1.0623858547753107, + "95.0" : 1.0623858547753107, + "99.0" : 1.0623858547753107, + "99.9" : 1.0623858547753107, + "99.99" : 1.0623858547753107, + "99.999" : 1.0623858547753107, + "99.9999" : 1.0623858547753107, + "100.0" : 1.0623858547753107 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0623858547753107, + 1.0617533774946921, + 1.0612794283137006 + ], + [ + 1.0003615240572172, + 1.0110629589525832, + 1.0030419441323972 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010793445745626039, + "scoreError" : 6.925182447429463E-4, + "scoreConfidence" : [ + 0.010100927500883093, + 0.011485963990368985 + ], + "scorePercentiles" : { + "0.0" : 0.010562353175282166, + "50.0" : 0.010793412100052541, + "90.0" : 0.011023545018827659, + "95.0" : 0.011023545018827659, + "99.0" : 0.011023545018827659, + "99.9" : 0.011023545018827659, + "99.99" : 0.011023545018827659, + "99.999" : 0.011023545018827659, + "99.9999" : 0.011023545018827659, + "100.0" : 0.011023545018827659 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011017424191010889, + 0.011015599827280058, + 0.011023545018827659 + ], + [ + 0.01057052788853044, + 0.010571224372825025, + 0.010562353175282166 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.122557366993984, + "scoreError" : 0.08011890952441872, + "scoreConfidence" : [ + 3.0424384574695655, + 3.2026762765184027 + ], + "scorePercentiles" : { + "0.0" : 3.092819901669759, + "50.0" : 3.123848700005852, + "90.0" : 3.1502229414357683, + "95.0" : 3.1502229414357683, + "99.0" : 3.1502229414357683, + "99.9" : 3.1502229414357683, + "99.99" : 3.1502229414357683, + "99.999" : 3.1502229414357683, + "99.9999" : 3.1502229414357683, + "100.0" : 3.1502229414357683 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0948857982673266, + 3.102341726426799, + 3.092819901669759 + ], + [ + 3.1502229414357683, + 3.149718160579345, + 3.1453556735849055 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7699728148832015, + "scoreError" : 0.14940413522694126, + "scoreConfidence" : [ + 2.62056867965626, + 2.9193769501101428 + ], + "scorePercentiles" : { + "0.0" : 2.7210124458650706, + "50.0" : 2.767843020407134, + "90.0" : 2.821346806488011, + "95.0" : 2.821346806488011, + "99.0" : 2.821346806488011, + "99.9" : 2.821346806488011, + "99.99" : 2.821346806488011, + "99.999" : 2.821346806488011, + "99.9999" : 2.821346806488011, + "100.0" : 2.821346806488011 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.820621964467005, + 2.821346806488011, + 2.813672436568214 + ], + [ + 2.7210124458650706, + 2.721169631664853, + 2.722013604246053 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.182361906716641, + "scoreError" : 0.006260704333333856, + "scoreConfidence" : [ + 0.17610120238330712, + 0.18862261104997485 + ], + "scorePercentiles" : { + "0.0" : 0.17975124118344896, + "50.0" : 0.18280763988388, + "90.0" : 0.1844741830843018, + "95.0" : 0.1844741830843018, + "99.0" : 0.1844741830843018, + "99.9" : 0.1844741830843018, + "99.99" : 0.1844741830843018, + "99.999" : 0.1844741830843018, + "99.9999" : 0.1844741830843018, + "100.0" : 0.1844741830843018 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17999564194175457, + 0.18143727372679935, + 0.17975124118344896 + ], + [ + 0.18433509432258063, + 0.1844741830843018, + 0.18417800604096066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3272153851648061, + "scoreError" : 0.0034131243715917474, + "scoreConfidence" : [ + 0.32380226079321434, + 0.33062850953639783 + ], + "scorePercentiles" : { + "0.0" : 0.32583248362712197, + "50.0" : 0.3272278174478433, + "90.0" : 0.3285037850009855, + "95.0" : 0.3285037850009855, + "99.0" : 0.3285037850009855, + "99.9" : 0.3285037850009855, + "99.99" : 0.3285037850009855, + "99.999" : 0.3285037850009855, + "99.9999" : 0.3285037850009855, + "100.0" : 0.3285037850009855 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32639225304350666, + 0.3261466079838236, + 0.32583248362712197 + ], + [ + 0.3283537994812188, + 0.3285037850009855, + 0.3280633818521799 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1466265380405978, + "scoreError" : 0.0013295659768003507, + "scoreConfidence" : [ + 0.14529697206379746, + 0.14795610401739814 + ], + "scorePercentiles" : { + "0.0" : 0.1457049814523414, + "50.0" : 0.14675010369343117, + "90.0" : 0.14704247655457367, + "95.0" : 0.14704247655457367, + "99.0" : 0.14704247655457367, + "99.9" : 0.14704247655457367, + "99.99" : 0.14704247655457367, + "99.999" : 0.14704247655457367, + "99.9999" : 0.14704247655457367, + "100.0" : 0.14704247655457367 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14663352956788223, + 0.1457049814523414, + 0.14668718379440843 + ], + [ + 0.14704247655457367, + 0.146878033281927, + 0.14681302359245393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40180722547472003, + "scoreError" : 0.006243360729656814, + "scoreConfidence" : [ + 0.3955638647450632, + 0.40805058620437684 + ], + "scorePercentiles" : { + "0.0" : 0.39985738656537384, + "50.0" : 0.4012504780753967, + "90.0" : 0.4057324315563129, + "95.0" : 0.4057324315563129, + "99.0" : 0.4057324315563129, + "99.9" : 0.4057324315563129, + "99.99" : 0.4057324315563129, + "99.999" : 0.4057324315563129, + "99.9999" : 0.4057324315563129, + "100.0" : 0.4057324315563129 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4057324315563129, + 0.3998781027671145, + 0.39985738656537384 + ], + [ + 0.40287447580872576, + 0.4014691618692039, + 0.4010317942815896 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16207254905005605, + "scoreError" : 0.008273960633344839, + "scoreConfidence" : [ + 0.1537985884167112, + 0.1703465096834009 + ], + "scorePercentiles" : { + "0.0" : 0.1597576347370439, + "50.0" : 0.16039306416151727, + "90.0" : 0.16627270743548817, + "95.0" : 0.16627270743548817, + "99.0" : 0.16627270743548817, + "99.9" : 0.16627270743548817, + "99.99" : 0.16627270743548817, + "99.999" : 0.16627270743548817, + "99.9999" : 0.16627270743548817, + "100.0" : 0.16627270743548817 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16048986081109273, + 0.1602962675119418, + 0.1601842199138221 + ], + [ + 0.16627270743548817, + 0.1597576347370439, + 0.16543460389094758 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0466384038173576, + "scoreError" : 8.698947453721076E-4, + "scoreConfidence" : [ + 0.04576850907198549, + 0.04750829856272971 + ], + "scorePercentiles" : { + "0.0" : 0.046393041298427765, + "50.0" : 0.04653162533323939, + "90.0" : 0.047191698817866494, + "95.0" : 0.047191698817866494, + "99.0" : 0.047191698817866494, + "99.9" : 0.047191698817866494, + "99.99" : 0.047191698817866494, + "99.999" : 0.047191698817866494, + "99.9999" : 0.047191698817866494, + "100.0" : 0.047191698817866494 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04643167857308682, + 0.04640738657731825, + 0.046393041298427765 + ], + [ + 0.047191698817866494, + 0.046631572093391964, + 0.046775045544054296 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8623520.088084025, + "scoreError" : 180031.65244300725, + "scoreConfidence" : [ + 8443488.435641019, + 8803551.740527032 + ], + "scorePercentiles" : { + "0.0" : 8554261.375213675, + "50.0" : 8619693.963995753, + "90.0" : 8694329.051259775, + "95.0" : 8694329.051259775, + "99.0" : 8694329.051259775, + "99.9" : 8694329.051259775, + "99.99" : 8694329.051259775, + "99.999" : 8694329.051259775, + "99.9999" : 8694329.051259775, + "100.0" : 8694329.051259775 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8694329.051259775, + 8685962.642361112, + 8662679.821645021 + ], + [ + 8576708.106346484, + 8567179.531678082, + 8554261.375213675 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-10T01:31:19Z-49a68f9b969ae7d6d6d4af1482deedb1522fdae2-jdk17.json b/performance-results/2025-07-10T01:31:19Z-49a68f9b969ae7d6d6d4af1482deedb1522fdae2-jdk17.json new file mode 100644 index 0000000000..8bc37ff42b --- /dev/null +++ b/performance-results/2025-07-10T01:31:19Z-49a68f9b969ae7d6d6d4af1482deedb1522fdae2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.350819914645622, + "scoreError" : 0.02333452740089837, + "scoreConfidence" : [ + 3.3274853872447236, + 3.37415444204652 + ], + "scorePercentiles" : { + "0.0" : 3.3467376436328893, + "50.0" : 3.3511692012658485, + "90.0" : 3.3542036124179013, + "95.0" : 3.3542036124179013, + "99.0" : 3.3542036124179013, + "99.9" : 3.3542036124179013, + "99.99" : 3.3542036124179013, + "99.999" : 3.3542036124179013, + "99.9999" : 3.3542036124179013, + "100.0" : 3.3542036124179013 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.348849657604126, + 3.353488744927571 + ], + [ + 3.3467376436328893, + 3.3542036124179013 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.689308129574393, + "scoreError" : 0.047443854042694716, + "scoreConfidence" : [ + 1.6418642755316983, + 1.7367519836170877 + ], + "scorePercentiles" : { + "0.0" : 1.6828186069646558, + "50.0" : 1.688609535642259, + "90.0" : 1.6971948400483985, + "95.0" : 1.6971948400483985, + "99.0" : 1.6971948400483985, + "99.9" : 1.6971948400483985, + "99.99" : 1.6971948400483985, + "99.999" : 1.6971948400483985, + "99.9999" : 1.6971948400483985, + "100.0" : 1.6971948400483985 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6939210435067305, + 1.6971948400483985 + ], + [ + 1.6828186069646558, + 1.6832980277777876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8485872258925267, + "scoreError" : 0.04086454089765866, + "scoreConfidence" : [ + 0.807722684994868, + 0.8894517667901853 + ], + "scorePercentiles" : { + "0.0" : 0.839106231535581, + "50.0" : 0.8516091497694063, + "90.0" : 0.852024372495713, + "95.0" : 0.852024372495713, + "99.0" : 0.852024372495713, + "99.9" : 0.852024372495713, + "99.99" : 0.852024372495713, + "99.999" : 0.852024372495713, + "99.9999" : 0.852024372495713, + "100.0" : 0.852024372495713 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.839106231535581, + 0.8516606788257489 + ], + [ + 0.8515576207130636, + 0.852024372495713 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.40461695193473, + "scoreError" : 0.2161016591656955, + "scoreConfidence" : [ + 16.188515292769036, + 16.620718611100425 + ], + "scorePercentiles" : { + "0.0" : 16.3297274878599, + "50.0" : 16.40653404546939, + "90.0" : 16.47793679209158, + "95.0" : 16.47793679209158, + "99.0" : 16.47793679209158, + "99.9" : 16.47793679209158, + "99.99" : 16.47793679209158, + "99.999" : 16.47793679209158, + "99.9999" : 16.47793679209158, + "100.0" : 16.47793679209158 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.3297274878599, + 16.333590373927436, + 16.33971459325851 + ], + [ + 16.473353497680268, + 16.47793679209158, + 16.473378966790694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2691.2529136656676, + "scoreError" : 127.79663441169158, + "scoreConfidence" : [ + 2563.456279253976, + 2819.0495480773593 + ], + "scorePercentiles" : { + "0.0" : 2647.1976602028967, + "50.0" : 2691.8918649164098, + "90.0" : 2732.9144928019823, + "95.0" : 2732.9144928019823, + "99.0" : 2732.9144928019823, + "99.9" : 2732.9144928019823, + "99.99" : 2732.9144928019823, + "99.999" : 2732.9144928019823, + "99.9999" : 2732.9144928019823, + "100.0" : 2732.9144928019823 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2732.9144928019823, + 2732.839303423572, + 2732.7578452780895 + ], + [ + 2651.02588455473, + 2647.1976602028967, + 2650.7822957327357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76176.971313861, + "scoreError" : 2227.4548357244817, + "scoreConfidence" : [ + 73949.51647813652, + 78404.42614958547 + ], + "scorePercentiles" : { + "0.0" : 75433.2501407948, + "50.0" : 76166.36462532615, + "90.0" : 76923.92912758036, + "95.0" : 76923.92912758036, + "99.0" : 76923.92912758036, + "99.9" : 76923.92912758036, + "99.99" : 76923.92912758036, + "99.999" : 76923.92912758036, + "99.9999" : 76923.92912758036, + "100.0" : 76923.92912758036 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75462.11227880357, + 75460.9014175589, + 75433.2501407948 + ], + [ + 76911.01794657961, + 76870.61697184872, + 76923.92912758036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.22255299217386, + "scoreError" : 19.069456850411857, + "scoreConfidence" : [ + 343.153096141762, + 381.29200984258574 + ], + "scorePercentiles" : { + "0.0" : 354.1557393864702, + "50.0" : 363.0498586240968, + "90.0" : 368.6176535071154, + "95.0" : 368.6176535071154, + "99.0" : 368.6176535071154, + "99.9" : 368.6176535071154, + "99.99" : 368.6176535071154, + "99.999" : 368.6176535071154, + "99.9999" : 368.6176535071154, + "100.0" : 368.6176535071154 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 367.85846734438877, + 368.461621295449, + 368.6176535071154 + ], + [ + 354.1557393864702, + 356.0005865158149, + 358.2412499038049 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.65045311741228, + "scoreError" : 5.192763991695376, + "scoreConfidence" : [ + 111.45768912571691, + 121.84321710910766 + ], + "scorePercentiles" : { + "0.0" : 114.9042774634322, + "50.0" : 116.63514901899373, + "90.0" : 118.44694596648905, + "95.0" : 118.44694596648905, + "99.0" : 118.44694596648905, + "99.9" : 118.44694596648905, + "99.99" : 118.44694596648905, + "99.999" : 118.44694596648905, + "99.9999" : 118.44694596648905, + "100.0" : 118.44694596648905 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.02988948941001, + 114.9042774634322, + 114.95022442624429 + ], + [ + 118.33097281032083, + 118.24040854857743, + 118.44694596648905 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061894241695642345, + "scoreError" : 0.002614448102822521, + "scoreConfidence" : [ + 0.059279793592819825, + 0.06450868979846487 + ], + "scorePercentiles" : { + "0.0" : 0.060928018619273626, + "50.0" : 0.06189595270510471, + "90.0" : 0.06287789266289824, + "95.0" : 0.06287789266289824, + "99.0" : 0.06287789266289824, + "99.9" : 0.06287789266289824, + "99.99" : 0.06287789266289824, + "99.999" : 0.06287789266289824, + "99.9999" : 0.06287789266289824, + "100.0" : 0.06287789266289824 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061049256231494764, + 0.060928018619273626, + 0.06117072757523856 + ], + [ + 0.06287789266289824, + 0.06271837724997804, + 0.06262117783497086 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.777970476362235E-4, + "scoreError" : 2.7864521438112513E-5, + "scoreConfidence" : [ + 3.4993252619811097E-4, + 4.05661569074336E-4 + ], + "scorePercentiles" : { + "0.0" : 3.68515105776253E-4, + "50.0" : 3.77867803407144E-4, + "90.0" : 3.8687994063328466E-4, + "95.0" : 3.8687994063328466E-4, + "99.0" : 3.8687994063328466E-4, + "99.9" : 3.8687994063328466E-4, + "99.99" : 3.8687994063328466E-4, + "99.999" : 3.8687994063328466E-4, + "99.9999" : 3.8687994063328466E-4, + "100.0" : 3.8687994063328466E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.868609797143012E-4, + 3.868611961185294E-4, + 3.8687994063328466E-4 + ], + [ + 3.68515105776253E-4, + 3.6887462709998673E-4, + 3.6879043647498574E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12477273281815464, + "scoreError" : 0.0013113660080159109, + "scoreConfidence" : [ + 0.12346136681013872, + 0.12608409882617055 + ], + "scorePercentiles" : { + "0.0" : 0.12417440569704345, + "50.0" : 0.12483444633477972, + "90.0" : 0.1252465153925154, + "95.0" : 0.1252465153925154, + "99.0" : 0.1252465153925154, + "99.9" : 0.1252465153925154, + "99.99" : 0.1252465153925154, + "99.999" : 0.1252465153925154, + "99.9999" : 0.1252465153925154, + "100.0" : 0.1252465153925154 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12517691182766089, + 0.1252465153925154, + 0.12513240699725967 + ], + [ + 0.12453648567229977, + 0.12436967132214857, + 0.12417440569704345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013306685107809737, + "scoreError" : 5.665022797275359E-4, + "scoreConfidence" : [ + 0.012740182828082201, + 0.013873187387537273 + ], + "scorePercentiles" : { + "0.0" : 0.013117763114330465, + "50.0" : 0.013307326384480053, + "90.0" : 0.013493517064383589, + "95.0" : 0.013493517064383589, + "99.0" : 0.013493517064383589, + "99.9" : 0.013493517064383589, + "99.99" : 0.013493517064383589, + "99.999" : 0.013493517064383589, + "99.9999" : 0.013493517064383589, + "100.0" : 0.013493517064383589 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013490528424190915, + 0.013489207860318557, + 0.013493517064383589 + ], + [ + 0.01312364927499334, + 0.013125444908641547, + 0.013117763114330465 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.030876720215693, + "scoreError" : 0.021711880521495325, + "scoreConfidence" : [ + 1.0091648396941977, + 1.0525886007371883 + ], + "scorePercentiles" : { + "0.0" : 1.022915315741025, + "50.0" : 1.0309249203114617, + "90.0" : 1.038546202928653, + "95.0" : 1.038546202928653, + "99.0" : 1.038546202928653, + "99.9" : 1.038546202928653, + "99.99" : 1.038546202928653, + "99.999" : 1.038546202928653, + "99.9999" : 1.038546202928653, + "100.0" : 1.038546202928653 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.024495459127228, + 1.0240882725038403, + 1.022915315741025 + ], + [ + 1.038546202928653, + 1.037860689497717, + 1.0373543814956954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010776716633841521, + "scoreError" : 2.637657165126356E-4, + "scoreConfidence" : [ + 0.010512950917328887, + 0.011040482350354156 + ], + "scorePercentiles" : { + "0.0" : 0.010689400152641075, + "50.0" : 0.010776800099100774, + "90.0" : 0.010864438780343657, + "95.0" : 0.010864438780343657, + "99.0" : 0.010864438780343657, + "99.9" : 0.010864438780343657, + "99.99" : 0.010864438780343657, + "99.999" : 0.010864438780343657, + "99.9999" : 0.010864438780343657, + "100.0" : 0.010864438780343657 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010690820255205237, + 0.010689400152641075, + 0.010692360659488703 + ], + [ + 0.010861239538712845, + 0.010864438780343657, + 0.010862040416657615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.067124041181389, + "scoreError" : 0.07368588225741621, + "scoreConfidence" : [ + 2.993438158923973, + 3.1408099234388054 + ], + "scorePercentiles" : { + "0.0" : 3.0285718267716537, + "50.0" : 3.0758596359560353, + "90.0" : 3.091910981458591, + "95.0" : 3.091910981458591, + "99.0" : 3.091910981458591, + "99.9" : 3.091910981458591, + "99.99" : 3.091910981458591, + "99.999" : 3.091910981458591, + "99.9999" : 3.091910981458591, + "100.0" : 3.091910981458591 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.091910981458591, + 3.0879196858024693, + 3.0849798488587292 + ], + [ + 3.0285718267716537, + 3.0667394230533414, + 3.0426224811435523 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8070905351331277, + "scoreError" : 0.11741319941302322, + "scoreConfidence" : [ + 2.6896773357201043, + 2.924503734546151 + ], + "scorePercentiles" : { + "0.0" : 2.7666692979253114, + "50.0" : 2.805843725031397, + "90.0" : 2.8491565190883192, + "95.0" : 2.8491565190883192, + "99.0" : 2.8491565190883192, + "99.9" : 2.8491565190883192, + "99.99" : 2.8491565190883192, + "99.999" : 2.8491565190883192, + "99.9999" : 2.8491565190883192, + "100.0" : 2.8491565190883192 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8491565190883192, + 2.8460913645418326, + 2.8403589349616585 + ], + [ + 2.7666692979253114, + 2.771328515101136, + 2.7689385791805092 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17310895297613224, + "scoreError" : 0.007363597113679554, + "scoreConfidence" : [ + 0.16574535586245268, + 0.1804725500898118 + ], + "scorePercentiles" : { + "0.0" : 0.17005229540700936, + "50.0" : 0.17369525572785827, + "90.0" : 0.17556015241740108, + "95.0" : 0.17556015241740108, + "99.0" : 0.17556015241740108, + "99.9" : 0.17556015241740108, + "99.99" : 0.17556015241740108, + "99.999" : 0.17556015241740108, + "99.9999" : 0.17556015241740108, + "100.0" : 0.17556015241740108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17219792952095603, + 0.17019919409081627, + 0.17005229540700936 + ], + [ + 0.17556015241740108, + 0.17519258193476053, + 0.17545156448585014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32881208395442413, + "scoreError" : 0.015697675201900792, + "scoreConfidence" : [ + 0.31311440875252333, + 0.3445097591563249 + ], + "scorePercentiles" : { + "0.0" : 0.3235423501245592, + "50.0" : 0.32885457860065725, + "90.0" : 0.33409412598135835, + "95.0" : 0.33409412598135835, + "99.0" : 0.33409412598135835, + "99.9" : 0.33409412598135835, + "99.99" : 0.33409412598135835, + "99.999" : 0.33409412598135835, + "99.9999" : 0.33409412598135835, + "100.0" : 0.33409412598135835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3239609487511743, + 0.3235423501245592, + 0.3236102250339784 + ], + [ + 0.33391664538533455, + 0.3337482084501402, + 0.33409412598135835 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.144110729217939, + "scoreError" : 0.004438371044765838, + "scoreConfidence" : [ + 0.13967235817317317, + 0.14854910026270482 + ], + "scorePercentiles" : { + "0.0" : 0.1425443439811845, + "50.0" : 0.14409787077368802, + "90.0" : 0.14561675334546778, + "95.0" : 0.14561675334546778, + "99.0" : 0.14561675334546778, + "99.9" : 0.14561675334546778, + "99.99" : 0.14561675334546778, + "99.999" : 0.14561675334546778, + "99.9999" : 0.14561675334546778, + "100.0" : 0.14561675334546778 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14275026592343049, + 0.1425443439811845, + 0.14271016949225104 + ], + [ + 0.14561675334546778, + 0.1455973669413546, + 0.14544547562394555 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4054655095119229, + "scoreError" : 0.012388019419332931, + "scoreConfidence" : [ + 0.39307749009258997, + 0.4178535289312558 + ], + "scorePercentiles" : { + "0.0" : 0.4013408142232211, + "50.0" : 0.4054086563721775, + "90.0" : 0.4098287064054752, + "95.0" : 0.4098287064054752, + "99.0" : 0.4098287064054752, + "99.9" : 0.4098287064054752, + "99.99" : 0.4098287064054752, + "99.999" : 0.4098287064054752, + "99.9999" : 0.4098287064054752, + "100.0" : 0.4098287064054752 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4098287064054752, + 0.4093563019771583, + 0.40929835562558836 + ], + [ + 0.40151895711876656, + 0.40144992172132793, + 0.4013408142232211 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.158931407183529, + "scoreError" : 0.007700048312805177, + "scoreConfidence" : [ + 0.1512313588707238, + 0.16663145549633418 + ], + "scorePercentiles" : { + "0.0" : 0.1563435273361162, + "50.0" : 0.15832637049988685, + "90.0" : 0.1620935687262943, + "95.0" : 0.1620935687262943, + "99.0" : 0.1620935687262943, + "99.9" : 0.1620935687262943, + "99.99" : 0.1620935687262943, + "99.999" : 0.1620935687262943, + "99.9999" : 0.1620935687262943, + "100.0" : 0.1620935687262943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1568328969481212, + 0.1563435273361162, + 0.15645568720371733 + ], + [ + 0.1620429188352724, + 0.1620935687262943, + 0.1598198440516525 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04645898786157401, + "scoreError" : 0.0012709537808444872, + "scoreConfidence" : [ + 0.04518803408072952, + 0.04772994164241849 + ], + "scorePercentiles" : { + "0.0" : 0.045811569795088165, + "50.0" : 0.04655808571537229, + "90.0" : 0.047015186078109644, + "95.0" : 0.047015186078109644, + "99.0" : 0.047015186078109644, + "99.9" : 0.047015186078109644, + "99.99" : 0.047015186078109644, + "99.999" : 0.047015186078109644, + "99.9999" : 0.047015186078109644, + "100.0" : 0.047015186078109644 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04673454051351073, + 0.047015186078109644, + 0.046389707823053516 + ], + [ + 0.04672646360769105, + 0.04607645935199093, + 0.045811569795088165 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8738210.149962107, + "scoreError" : 179757.9484483726, + "scoreConfidence" : [ + 8558452.201513734, + 8917968.09841048 + ], + "scorePercentiles" : { + "0.0" : 8673455.924544666, + "50.0" : 8735008.831389125, + "90.0" : 8819877.789241623, + "95.0" : 8819877.789241623, + "99.0" : 8819877.789241623, + "99.9" : 8819877.789241623, + "99.99" : 8819877.789241623, + "99.999" : 8819877.789241623, + "99.9999" : 8819877.789241623, + "100.0" : 8819877.789241623 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8689234.174630756, + 8680910.774305556, + 8673455.924544666 + ], + [ + 8819877.789241623, + 8784998.748902546, + 8780783.488147497 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-10T01:37:12Z-cc111070ee2f6b3cb7494ce6a5c086454386f656-jdk17.json b/performance-results/2025-07-10T01:37:12Z-cc111070ee2f6b3cb7494ce6a5c086454386f656-jdk17.json new file mode 100644 index 0000000000..b24de1c3f8 --- /dev/null +++ b/performance-results/2025-07-10T01:37:12Z-cc111070ee2f6b3cb7494ce6a5c086454386f656-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3308319072363797, + "scoreError" : 0.0157149575188142, + "scoreConfidence" : [ + 3.3151169497175657, + 3.3465468647551937 + ], + "scorePercentiles" : { + "0.0" : 3.3292496261295756, + "50.0" : 3.329816875335484, + "90.0" : 3.334444252144974, + "95.0" : 3.334444252144974, + "99.0" : 3.334444252144974, + "99.9" : 3.334444252144974, + "99.99" : 3.334444252144974, + "99.999" : 3.334444252144974, + "99.9999" : 3.334444252144974, + "100.0" : 3.334444252144974 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.330071126444625, + 3.334444252144974 + ], + [ + 3.3292496261295756, + 3.3295626242263427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.674695400547804, + "scoreError" : 0.04751559309026891, + "scoreConfidence" : [ + 1.6271798074575352, + 1.722210993638073 + ], + "scorePercentiles" : { + "0.0" : 1.6676677630469123, + "50.0" : 1.6744752117100288, + "90.0" : 1.6821634157242462, + "95.0" : 1.6821634157242462, + "99.0" : 1.6821634157242462, + "99.9" : 1.6821634157242462, + "99.99" : 1.6821634157242462, + "99.999" : 1.6821634157242462, + "99.9999" : 1.6821634157242462, + "100.0" : 1.6821634157242462 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6798113113881936, + 1.6821634157242462 + ], + [ + 1.6676677630469123, + 1.669139112031864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8411903488071606, + "scoreError" : 0.036464610804582506, + "scoreConfidence" : [ + 0.8047257380025781, + 0.8776549596117431 + ], + "scorePercentiles" : { + "0.0" : 0.8345142027654179, + "50.0" : 0.8421119833674082, + "90.0" : 0.8460232257284079, + "95.0" : 0.8460232257284079, + "99.0" : 0.8460232257284079, + "99.9" : 0.8460232257284079, + "99.99" : 0.8460232257284079, + "99.999" : 0.8460232257284079, + "99.9999" : 0.8460232257284079, + "100.0" : 0.8460232257284079 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8385132452568219, + 0.8457107214779946 + ], + [ + 0.8345142027654179, + 0.8460232257284079 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.043239319662742, + "scoreError" : 0.49704189522200887, + "scoreConfidence" : [ + 15.546197424440733, + 16.54028121488475 + ], + "scorePercentiles" : { + "0.0" : 15.885454860426231, + "50.0" : 15.99909534057647, + "90.0" : 16.31540553831293, + "95.0" : 16.31540553831293, + "99.0" : 16.31540553831293, + "99.9" : 16.31540553831293, + "99.99" : 16.31540553831293, + "99.999" : 16.31540553831293, + "99.9999" : 16.31540553831293, + "100.0" : 16.31540553831293 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.905649605311089, + 15.885454860426231, + 15.895256762833387 + ], + [ + 16.31540553831293, + 16.165128075250973, + 16.09254107584185 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2561.3547643355937, + "scoreError" : 57.94079389860759, + "scoreConfidence" : [ + 2503.413970436986, + 2619.2955582342015 + ], + "scorePercentiles" : { + "0.0" : 2527.8596270082235, + "50.0" : 2563.4745944662063, + "90.0" : 2585.3446476311337, + "95.0" : 2585.3446476311337, + "99.0" : 2585.3446476311337, + "99.9" : 2585.3446476311337, + "99.99" : 2585.3446476311337, + "99.999" : 2585.3446476311337, + "99.9999" : 2585.3446476311337, + "100.0" : 2585.3446476311337 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2560.58312746906, + 2578.0877634907515, + 2566.366061463353 + ], + [ + 2585.3446476311337, + 2549.8873589510426, + 2527.8596270082235 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75700.0420558788, + "scoreError" : 3597.5186002174855, + "scoreConfidence" : [ + 72102.52345566131, + 79297.56065609629 + ], + "scorePercentiles" : { + "0.0" : 74359.10315485684, + "50.0" : 75671.20854140012, + "90.0" : 76983.88807110753, + "95.0" : 76983.88807110753, + "99.0" : 76983.88807110753, + "99.9" : 76983.88807110753, + "99.99" : 76983.88807110753, + "99.999" : 76983.88807110753, + "99.9999" : 76983.88807110753, + "100.0" : 76983.88807110753 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74593.24525151214, + 74359.10315485684, + 74655.3229260646 + ], + [ + 76687.09415673562, + 76921.59877499603, + 76983.88807110753 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.09464699412456, + "scoreError" : 7.483846050821221, + "scoreConfidence" : [ + 341.61080094330333, + 356.5784930449458 + ], + "scorePercentiles" : { + "0.0" : 345.3748546037982, + "50.0" : 349.7822833447527, + "90.0" : 352.5884652093961, + "95.0" : 352.5884652093961, + "99.0" : 352.5884652093961, + "99.9" : 352.5884652093961, + "99.99" : 352.5884652093961, + "99.999" : 352.5884652093961, + "99.9999" : 352.5884652093961, + "100.0" : 352.5884652093961 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.3748546037982, + 350.0261998459773, + 352.5884652093961 + ], + [ + 350.5004060106329, + 349.5383668435281, + 346.53958945141494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.92073282823394, + "scoreError" : 9.361952187042274, + "scoreConfidence" : [ + 104.55878064119166, + 123.28268501527621 + ], + "scorePercentiles" : { + "0.0" : 110.21043964634602, + "50.0" : 113.85116353797076, + "90.0" : 117.66975407227746, + "95.0" : 117.66975407227746, + "99.0" : 117.66975407227746, + "99.9" : 117.66975407227746, + "99.99" : 117.66975407227746, + "99.999" : 117.66975407227746, + "99.9999" : 117.66975407227746, + "100.0" : 117.66975407227746 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.21043964634602, + 111.86787375045598, + 110.80652986089763 + ], + [ + 117.66975407227746, + 115.83445332548553, + 117.13534631394106 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06274318949190916, + "scoreError" : 8.199798131444502E-4, + "scoreConfidence" : [ + 0.061923209678764704, + 0.06356316930505361 + ], + "scorePercentiles" : { + "0.0" : 0.06220937561430793, + "50.0" : 0.06284629158119515, + "90.0" : 0.06298133465171936, + "95.0" : 0.06298133465171936, + "99.0" : 0.06298133465171936, + "99.9" : 0.06298133465171936, + "99.99" : 0.06298133465171936, + "99.999" : 0.06298133465171936, + "99.9999" : 0.06298133465171936, + "100.0" : 0.06298133465171936 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06295236890080766, + 0.06278924858569052, + 0.06220937561430793 + ], + [ + 0.06298133465171936, + 0.06262347462222974, + 0.06290333457669978 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7457967877873905E-4, + "scoreError" : 7.18272753027571E-6, + "scoreConfidence" : [ + 3.6739695124846333E-4, + 3.8176240630901476E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6958459479113047E-4, + "50.0" : 3.7537403850749E-4, + "90.0" : 3.76731680727499E-4, + "95.0" : 3.76731680727499E-4, + "99.0" : 3.76731680727499E-4, + "99.9" : 3.76731680727499E-4, + "99.99" : 3.76731680727499E-4, + "99.999" : 3.76731680727499E-4, + "99.9999" : 3.76731680727499E-4, + "100.0" : 3.76731680727499E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.76731680727499E-4, + 3.6958459479113047E-4, + 3.7517337845215484E-4 + ], + [ + 3.7446747485138615E-4, + 3.755746985628251E-4, + 3.7594624528743863E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12852723463754115, + "scoreError" : 0.0058290532630292475, + "scoreConfidence" : [ + 0.1226981813745119, + 0.1343562879005704 + ], + "scorePercentiles" : { + "0.0" : 0.1263418249823125, + "50.0" : 0.12862674289347187, + "90.0" : 0.1309475298816258, + "95.0" : 0.1309475298816258, + "99.0" : 0.1309475298816258, + "99.9" : 0.1309475298816258, + "99.99" : 0.1309475298816258, + "99.999" : 0.1309475298816258, + "99.9999" : 0.1309475298816258, + "100.0" : 0.1309475298816258 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12724858061027128, + 0.1263418249823125, + 0.1264316603747345 + ], + [ + 0.13018890679963027, + 0.1309475298816258, + 0.1300049051766725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013237524956391425, + "scoreError" : 1.6958037246543213E-4, + "scoreConfidence" : [ + 0.013067944583925992, + 0.013407105328856857 + ], + "scorePercentiles" : { + "0.0" : 0.013154269843295156, + "50.0" : 0.013234641389906598, + "90.0" : 0.013303247526293525, + "95.0" : 0.013303247526293525, + "99.0" : 0.013303247526293525, + "99.9" : 0.013303247526293525, + "99.99" : 0.013303247526293525, + "99.999" : 0.013303247526293525, + "99.9999" : 0.013303247526293525, + "100.0" : 0.013303247526293525 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013303247526293525, + 0.013264492654237145, + 0.013298996409330952 + ], + [ + 0.013199353179615719, + 0.013154269843295156, + 0.013204790125576052 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0406793201805093, + "scoreError" : 0.08603849521313481, + "scoreConfidence" : [ + 0.9546408249673746, + 1.1267178153936441 + ], + "scorePercentiles" : { + "0.0" : 1.007942221023987, + "50.0" : 1.0415386652472598, + "90.0" : 1.0733267749275517, + "95.0" : 1.0733267749275517, + "99.0" : 1.0733267749275517, + "99.9" : 1.0733267749275517, + "99.99" : 1.0733267749275517, + "99.999" : 1.0733267749275517, + "99.9999" : 1.0733267749275517, + "100.0" : 1.0733267749275517 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0113651396642396, + 1.0198345784213747, + 1.007942221023987 + ], + [ + 1.0683644549727593, + 1.0733267749275517, + 1.063242752073145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011216801328603643, + "scoreError" : 3.000537292775303E-4, + "scoreConfidence" : [ + 0.010916747599326112, + 0.011516855057881173 + ], + "scorePercentiles" : { + "0.0" : 0.011086911923440223, + "50.0" : 0.011187821759084247, + "90.0" : 0.011409034098480354, + "95.0" : 0.011409034098480354, + "99.0" : 0.011409034098480354, + "99.9" : 0.011409034098480354, + "99.99" : 0.011409034098480354, + "99.999" : 0.011409034098480354, + "99.9999" : 0.011409034098480354, + "100.0" : 0.011409034098480354 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011086911923440223, + 0.011244025925867625, + 0.011409034098480354 + ], + [ + 0.011185192505665156, + 0.011188955596580738, + 0.011186687921587755 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2000498808925495, + "scoreError" : 0.5342452733870223, + "scoreConfidence" : [ + 2.6658046075055273, + 3.7342951542795717 + ], + "scorePercentiles" : { + "0.0" : 3.014500322483424, + "50.0" : 3.1894549831946684, + "90.0" : 3.4202595328317376, + "95.0" : 3.4202595328317376, + "99.0" : 3.4202595328317376, + "99.9" : 3.4202595328317376, + "99.99" : 3.4202595328317376, + "99.999" : 3.4202595328317376, + "99.9999" : 3.4202595328317376, + "100.0" : 3.4202595328317376 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.014500322483424, + 3.0344179053398057, + 3.034937837378641 + ], + [ + 3.3439721290106954, + 3.4202595328317376, + 3.352211558310992 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.809899452708773, + "scoreError" : 0.13392968917126652, + "scoreConfidence" : [ + 2.6759697635375064, + 2.9438291418800393 + ], + "scorePercentiles" : { + "0.0" : 2.746953985992859, + "50.0" : 2.8083206490557453, + "90.0" : 2.875143469962633, + "95.0" : 2.875143469962633, + "99.0" : 2.875143469962633, + "99.9" : 2.875143469962633, + "99.99" : 2.875143469962633, + "99.999" : 2.875143469962633, + "99.9999" : 2.875143469962633, + "100.0" : 2.875143469962633 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7729238505683393, + 2.794485414082146, + 2.746953985992859 + ], + [ + 2.8477341116173123, + 2.8221558840293453, + 2.875143469962633 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18777746342704849, + "scoreError" : 0.004572960506774189, + "scoreConfidence" : [ + 0.1832045029202743, + 0.19235042393382268 + ], + "scorePercentiles" : { + "0.0" : 0.18517129965743911, + "50.0" : 0.18839868879963878, + "90.0" : 0.18919563365306394, + "95.0" : 0.18919563365306394, + "99.0" : 0.18919563365306394, + "99.9" : 0.18919563365306394, + "99.99" : 0.18919563365306394, + "99.999" : 0.18919563365306394, + "99.9999" : 0.18919563365306394, + "100.0" : 0.18919563365306394 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18904637954175962, + 0.18645409011075065, + 0.18517129965743911 + ], + [ + 0.18919563365306394, + 0.18797423834586466, + 0.18882313925341287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3601624216064699, + "scoreError" : 0.03292187933563572, + "scoreConfidence" : [ + 0.32724054227083416, + 0.3930843009421056 + ], + "scorePercentiles" : { + "0.0" : 0.3480167627631808, + "50.0" : 0.36055106540577764, + "90.0" : 0.3714486345739544, + "95.0" : 0.3714486345739544, + "99.0" : 0.3714486345739544, + "99.9" : 0.3714486345739544, + "99.99" : 0.3714486345739544, + "99.999" : 0.3714486345739544, + "99.9999" : 0.3714486345739544, + "100.0" : 0.3714486345739544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3480167627631808, + 0.3491084902775353, + 0.3513922217576162 + ], + [ + 0.36970990905393913, + 0.3712985112125938, + 0.3714486345739544 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14979917517497288, + "scoreError" : 0.006823645828235725, + "scoreConfidence" : [ + 0.14297552934673716, + 0.1566228210032086 + ], + "scorePercentiles" : { + "0.0" : 0.14710716330043103, + "50.0" : 0.15015725712252548, + "90.0" : 0.1522981194450367, + "95.0" : 0.1522981194450367, + "99.0" : 0.1522981194450367, + "99.9" : 0.1522981194450367, + "99.99" : 0.1522981194450367, + "99.999" : 0.1522981194450367, + "99.9999" : 0.1522981194450367, + "100.0" : 0.1522981194450367 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1522981194450367, + 0.15191000710922073, + 0.15165147152042704 + ], + [ + 0.14716524695009786, + 0.14866304272462388, + 0.14710716330043103 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4091450545041764, + "scoreError" : 0.007969279186245602, + "scoreConfidence" : [ + 0.40117577531793075, + 0.417114333690422 + ], + "scorePercentiles" : { + "0.0" : 0.406487306072677, + "50.0" : 0.4086165006825696, + "90.0" : 0.41332784215747054, + "95.0" : 0.41332784215747054, + "99.0" : 0.41332784215747054, + "99.9" : 0.41332784215747054, + "99.99" : 0.41332784215747054, + "99.999" : 0.41332784215747054, + "99.9999" : 0.41332784215747054, + "100.0" : 0.41332784215747054 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41332784215747054, + 0.4100862018781268, + 0.4065835369165718 + ], + [ + 0.4112386405132001, + 0.40714679948701243, + 0.406487306072677 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16004545186081076, + "scoreError" : 0.010464600465073564, + "scoreConfidence" : [ + 0.1495808513957372, + 0.17051005232588431 + ], + "scorePercentiles" : { + "0.0" : 0.15640643608552168, + "50.0" : 0.16004523200898693, + "90.0" : 0.16366322930134364, + "95.0" : 0.16366322930134364, + "99.0" : 0.16366322930134364, + "99.9" : 0.16366322930134364, + "99.99" : 0.16366322930134364, + "99.999" : 0.16366322930134364, + "99.9999" : 0.16366322930134364, + "100.0" : 0.16366322930134364 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16366322930134364, + 0.16345824472449696, + 0.1632196017007247 + ], + [ + 0.15687086231724917, + 0.15665433703552853, + 0.15640643608552168 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04779986683027423, + "scoreError" : 0.0037868361909343114, + "scoreConfidence" : [ + 0.044013030639339916, + 0.05158670302120854 + ], + "scorePercentiles" : { + "0.0" : 0.04630165130244747, + "50.0" : 0.04800056592721949, + "90.0" : 0.04906355881386118, + "95.0" : 0.04906355881386118, + "99.0" : 0.04906355881386118, + "99.9" : 0.04906355881386118, + "99.99" : 0.04906355881386118, + "99.999" : 0.04906355881386118, + "99.9999" : 0.04906355881386118, + "100.0" : 0.04906355881386118 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04703185517763585, + 0.04630165130244747, + 0.046430865542745975 + ], + [ + 0.04896927667680314, + 0.049001993468151726, + 0.04906355881386118 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8909326.354449812, + "scoreError" : 987324.7309505814, + "scoreConfidence" : [ + 7922001.623499231, + 9896651.085400393 + ], + "scorePercentiles" : { + "0.0" : 8549841.861538462, + "50.0" : 8894660.020037945, + "90.0" : 9373885.413308341, + "95.0" : 9373885.413308341, + "99.0" : 9373885.413308341, + "99.9" : 9373885.413308341, + "99.99" : 9373885.413308341, + "99.999" : 9373885.413308341, + "99.9999" : 9373885.413308341, + "100.0" : 9373885.413308341 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8683100.074652778, + 8549841.861538462, + 8569812.359897172 + ], + [ + 9373885.413308341, + 9173098.45187901, + 9106219.965423113 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-14T22:01:02Z-d6003326db74b5a55959257d090abfd548e1ed2a-jdk17.json b/performance-results/2025-07-14T22:01:02Z-d6003326db74b5a55959257d090abfd548e1ed2a-jdk17.json new file mode 100644 index 0000000000..14704a4663 --- /dev/null +++ b/performance-results/2025-07-14T22:01:02Z-d6003326db74b5a55959257d090abfd548e1ed2a-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3581073436412483, + "scoreError" : 0.02710646485880727, + "scoreConfidence" : [ + 3.331000878782441, + 3.3852138085000556 + ], + "scorePercentiles" : { + "0.0" : 3.35379066231419, + "50.0" : 3.3578930723381877, + "90.0" : 3.362852567574427, + "95.0" : 3.362852567574427, + "99.0" : 3.362852567574427, + "99.9" : 3.362852567574427, + "99.99" : 3.362852567574427, + "99.999" : 3.362852567574427, + "99.9999" : 3.362852567574427, + "100.0" : 3.362852567574427 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.35379066231419, + 3.362852567574427 + ], + [ + 3.355490448000643, + 3.360295696675732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7012690471370124, + "scoreError" : 0.010666331042968364, + "scoreConfidence" : [ + 1.690602716094044, + 1.7119353781799809 + ], + "scorePercentiles" : { + "0.0" : 1.6993004308091342, + "50.0" : 1.7012222918155686, + "90.0" : 1.7033311741077786, + "95.0" : 1.7033311741077786, + "99.0" : 1.7033311741077786, + "99.9" : 1.7033311741077786, + "99.99" : 1.7033311741077786, + "99.999" : 1.7033311741077786, + "99.9999" : 1.7033311741077786, + "100.0" : 1.7033311741077786 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7013663644917127, + 1.7010782191394243 + ], + [ + 1.7033311741077786, + 1.6993004308091342 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8531227132939547, + "scoreError" : 0.03378060483417919, + "scoreConfidence" : [ + 0.8193421084597755, + 0.8869033181281339 + ], + "scorePercentiles" : { + "0.0" : 0.8477087372047541, + "50.0" : 0.8522775109118934, + "90.0" : 0.8602270941472778, + "95.0" : 0.8602270941472778, + "99.0" : 0.8602270941472778, + "99.9" : 0.8602270941472778, + "99.99" : 0.8602270941472778, + "99.999" : 0.8602270941472778, + "99.9999" : 0.8602270941472778, + "100.0" : 0.8602270941472778 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8477087372047541, + 0.8516566778662232 + ], + [ + 0.8528983439575635, + 0.8602270941472778 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.658771275196315, + "scoreError" : 0.0365474205988281, + "scoreConfidence" : [ + 16.622223854597486, + 16.695318695795144 + ], + "scorePercentiles" : { + "0.0" : 16.647568678703696, + "50.0" : 16.65301353161767, + "90.0" : 16.675259034169326, + "95.0" : 16.675259034169326, + "99.0" : 16.675259034169326, + "99.9" : 16.675259034169326, + "99.99" : 16.675259034169326, + "99.999" : 16.675259034169326, + "99.9999" : 16.675259034169326, + "100.0" : 16.675259034169326 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.647568678703696, + 16.64888306520242, + 16.649266189360123 + ], + [ + 16.674889809867114, + 16.675259034169326, + 16.656760873875218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2674.9488730356693, + "scoreError" : 67.11968555061144, + "scoreConfidence" : [ + 2607.829187485058, + 2742.0685585862807 + ], + "scorePercentiles" : { + "0.0" : 2651.8960493684235, + "50.0" : 2674.447994063885, + "90.0" : 2700.0108998225237, + "95.0" : 2700.0108998225237, + "99.0" : 2700.0108998225237, + "99.9" : 2700.0108998225237, + "99.99" : 2700.0108998225237, + "99.999" : 2700.0108998225237, + "99.9999" : 2700.0108998225237, + "100.0" : 2700.0108998225237 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2651.8960493684235, + 2654.718934796574, + 2652.933194796615 + ], + [ + 2694.177053331196, + 2695.9571060986823, + 2700.0108998225237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77038.52841575335, + "scoreError" : 2978.8169924909735, + "scoreConfidence" : [ + 74059.71142326237, + 80017.34540824432 + ], + "scorePercentiles" : { + "0.0" : 76004.13672085656, + "50.0" : 77055.58013060322, + "90.0" : 78027.56413739573, + "95.0" : 78027.56413739573, + "99.0" : 78027.56413739573, + "99.9" : 78027.56413739573, + "99.99" : 78027.56413739573, + "99.999" : 78027.56413739573, + "99.9999" : 78027.56413739573, + "100.0" : 78027.56413739573 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76126.26593886662, + 76078.21299169592, + 76004.13672085656 + ], + [ + 78010.09638336545, + 78027.56413739573, + 77984.89432233982 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 363.44285954652145, + "scoreError" : 6.0287047235114954, + "scoreConfidence" : [ + 357.41415482300994, + 369.47156427003296 + ], + "scorePercentiles" : { + "0.0" : 361.30552272469043, + "50.0" : 363.5534651948339, + "90.0" : 365.4603657502423, + "95.0" : 365.4603657502423, + "99.0" : 365.4603657502423, + "99.9" : 365.4603657502423, + "99.99" : 365.4603657502423, + "99.999" : 365.4603657502423, + "99.9999" : 365.4603657502423, + "100.0" : 365.4603657502423 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 365.4388498747584, + 365.4603657502423, + 365.29476861361866 + ], + [ + 361.3454885397699, + 361.81216177604915, + 361.30552272469043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.84324182878305, + "scoreError" : 4.076898359803688, + "scoreConfidence" : [ + 111.76634346897936, + 119.92014018858674 + ], + "scorePercentiles" : { + "0.0" : 114.49490570946332, + "50.0" : 115.83590586825932, + "90.0" : 117.25459165852146, + "95.0" : 117.25459165852146, + "99.0" : 117.25459165852146, + "99.9" : 117.25459165852146, + "99.99" : 117.25459165852146, + "99.999" : 117.25459165852146, + "99.9999" : 117.25459165852146, + "100.0" : 117.25459165852146 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.25459165852146, + 117.12774698505744, + 117.12666177321468 + ], + [ + 114.49490570946332, + 114.51039488313742, + 114.54514996330396 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060678850049020884, + "scoreError" : 7.681907580550135E-4, + "scoreConfidence" : [ + 0.05991065929096587, + 0.0614470408070759 + ], + "scorePercentiles" : { + "0.0" : 0.06038200073061015, + "50.0" : 0.0606895397252282, + "90.0" : 0.06095123389692079, + "95.0" : 0.06095123389692079, + "99.0" : 0.06095123389692079, + "99.9" : 0.06095123389692079, + "99.99" : 0.06095123389692079, + "99.999" : 0.06095123389692079, + "99.9999" : 0.06095123389692079, + "100.0" : 0.06095123389692079 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06095123389692079, + 0.06090183969646957, + 0.06092791972875325 + ], + [ + 0.06038200073061015, + 0.060477239753986826, + 0.0604328664873848 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.607754363793428E-4, + "scoreError" : 2.0620266806125745E-5, + "scoreConfidence" : [ + 3.4015516957321704E-4, + 3.8139570318546854E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5374183551567485E-4, + "50.0" : 3.6064620727426703E-4, + "90.0" : 3.683799092742162E-4, + "95.0" : 3.683799092742162E-4, + "99.0" : 3.683799092742162E-4, + "99.9" : 3.683799092742162E-4, + "99.99" : 3.683799092742162E-4, + "99.999" : 3.683799092742162E-4, + "99.9999" : 3.683799092742162E-4, + "100.0" : 3.683799092742162E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.542190211591999E-4, + 3.5374183551567485E-4, + 3.5428011236902446E-4 + ], + [ + 3.683799092742162E-4, + 3.670194377784314E-4, + 3.6701230217950966E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12390292081696497, + "scoreError" : 0.0024803731041723996, + "scoreConfidence" : [ + 0.12142254771279257, + 0.12638329392113737 + ], + "scorePercentiles" : { + "0.0" : 0.12289101978494624, + "50.0" : 0.12406299844820684, + "90.0" : 0.12473521069700144, + "95.0" : 0.12473521069700144, + "99.0" : 0.12473521069700144, + "99.9" : 0.12473521069700144, + "99.99" : 0.12473521069700144, + "99.999" : 0.12473521069700144, + "99.9999" : 0.12473521069700144, + "100.0" : 0.12473521069700144 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12289101978494624, + 0.1235471942254948, + 0.122937652193155 + ], + [ + 0.12473521069700144, + 0.1247276453302734, + 0.12457880267091888 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012972946635625806, + "scoreError" : 7.347243648482396E-5, + "scoreConfidence" : [ + 0.012899474199140983, + 0.01304641907211063 + ], + "scorePercentiles" : { + "0.0" : 0.01294594748023178, + "50.0" : 0.012973183065703237, + "90.0" : 0.012998232414586433, + "95.0" : 0.012998232414586433, + "99.0" : 0.012998232414586433, + "99.9" : 0.012998232414586433, + "99.99" : 0.012998232414586433, + "99.999" : 0.012998232414586433, + "99.9999" : 0.012998232414586433, + "100.0" : 0.012998232414586433 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012950047602459441, + 0.01294594748023178, + 0.0129513091539929 + ], + [ + 0.012995056977413575, + 0.012998232414586433, + 0.012997086185070715 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9689787832196171, + "scoreError" : 0.014699200456419358, + "scoreConfidence" : [ + 0.9542795827631977, + 0.9836779836760364 + ], + "scorePercentiles" : { + "0.0" : 0.9628837318505681, + "50.0" : 0.9692995504052865, + "90.0" : 0.9742356146127618, + "95.0" : 0.9742356146127618, + "99.0" : 0.9742356146127618, + "99.9" : 0.9742356146127618, + "99.99" : 0.9742356146127618, + "99.999" : 0.9742356146127618, + "99.9999" : 0.9742356146127618, + "100.0" : 0.9742356146127618 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9742356146127618, + 0.9728151185797665, + 0.973958665368134 + ], + [ + 0.9641955866756653, + 0.9628837318505681, + 0.9657839822308064 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010700078671117464, + "scoreError" : 0.0013654921210303175, + "scoreConfidence" : [ + 0.009334586550087147, + 0.01206557079214778 + ], + "scorePercentiles" : { + "0.0" : 0.010246345338970026, + "50.0" : 0.010701962800476757, + "90.0" : 0.011156180661009877, + "95.0" : 0.011156180661009877, + "99.0" : 0.011156180661009877, + "99.9" : 0.011156180661009877, + "99.99" : 0.011156180661009877, + "99.999" : 0.011156180661009877, + "99.9999" : 0.011156180661009877, + "100.0" : 0.011156180661009877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010251043734085606, + 0.010269592040485614, + 0.010246345338970026 + ], + [ + 0.011142976691685758, + 0.011134333560467898, + 0.011156180661009877 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0139715932456617, + "scoreError" : 0.1340680251275121, + "scoreConfidence" : [ + 2.8799035681181495, + 3.148039618373174 + ], + "scorePercentiles" : { + "0.0" : 2.9669904816132857, + "50.0" : 3.0120378698953774, + "90.0" : 3.062598700551133, + "95.0" : 3.062598700551133, + "99.0" : 3.062598700551133, + "99.9" : 3.062598700551133, + "99.99" : 3.062598700551133, + "99.999" : 3.062598700551133, + "99.9999" : 3.062598700551133, + "100.0" : 3.062598700551133 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0600207669724773, + 3.062598700551133, + 3.0495096030487803 + ], + [ + 2.974566136741974, + 2.9701438705463183, + 2.9669904816132857 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7391876225229788, + "scoreError" : 0.031165467815250692, + "scoreConfidence" : [ + 2.708022154707728, + 2.7703530903382294 + ], + "scorePercentiles" : { + "0.0" : 2.7282466879432623, + "50.0" : 2.7390798846947897, + "90.0" : 2.750732664191419, + "95.0" : 2.750732664191419, + "99.0" : 2.750732664191419, + "99.9" : 2.750732664191419, + "99.99" : 2.750732664191419, + "99.999" : 2.750732664191419, + "99.9999" : 2.750732664191419, + "100.0" : 2.750732664191419 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7282466879432623, + 2.7299096476528386, + 2.729085802728513 + ], + [ + 2.750732664191419, + 2.7482501217367408, + 2.7489008108851016 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1781733904485464, + "scoreError" : 0.01539419483907109, + "scoreConfidence" : [ + 0.16277919560947532, + 0.1935675852876175 + ], + "scorePercentiles" : { + "0.0" : 0.17305912070606558, + "50.0" : 0.1780484700590578, + "90.0" : 0.18383466120077943, + "95.0" : 0.18383466120077943, + "99.0" : 0.18383466120077943, + "99.9" : 0.18383466120077943, + "99.99" : 0.18383466120077943, + "99.999" : 0.18383466120077943, + "99.9999" : 0.18383466120077943, + "100.0" : 0.18383466120077943 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18383466120077943, + 0.18283883526529418, + 0.18284708814817524 + ], + [ + 0.1732025325181426, + 0.17325810485282142, + 0.17305912070606558 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.31881618772709136, + "scoreError" : 0.009639145862982517, + "scoreConfidence" : [ + 0.3091770418641088, + 0.3284553335900739 + ], + "scorePercentiles" : { + "0.0" : 0.31538235041629875, + "50.0" : 0.3189867864157143, + "90.0" : 0.32218294055865204, + "95.0" : 0.32218294055865204, + "99.0" : 0.32218294055865204, + "99.9" : 0.32218294055865204, + "99.99" : 0.32218294055865204, + "99.999" : 0.32218294055865204, + "99.9999" : 0.32218294055865204, + "100.0" : 0.32218294055865204 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3155245565091184, + 0.31538235041629875, + 0.31616240227632 + ], + [ + 0.32183370604705047, + 0.3218111705551086, + 0.32218294055865204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14649771378338938, + "scoreError" : 0.002088090981567289, + "scoreConfidence" : [ + 0.1444096228018221, + 0.14858580476495667 + ], + "scorePercentiles" : { + "0.0" : 0.14576349823630586, + "50.0" : 0.14649918355558894, + "90.0" : 0.14729270019442073, + "95.0" : 0.14729270019442073, + "99.0" : 0.14729270019442073, + "99.9" : 0.14729270019442073, + "99.99" : 0.14729270019442073, + "99.999" : 0.14729270019442073, + "99.9999" : 0.14729270019442073, + "100.0" : 0.14729270019442073 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14593693022882492, + 0.14577050726644608, + 0.14576349823630586 + ], + [ + 0.14729270019442073, + 0.14716120989198575, + 0.14706143688235293 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4067546131704393, + "scoreError" : 0.01027505742572403, + "scoreConfidence" : [ + 0.3964795557447153, + 0.41702967059616336 + ], + "scorePercentiles" : { + "0.0" : 0.40224895885121276, + "50.0" : 0.4070826563132047, + "90.0" : 0.4112681787300543, + "95.0" : 0.4112681787300543, + "99.0" : 0.4112681787300543, + "99.9" : 0.4112681787300543, + "99.99" : 0.4112681787300543, + "99.999" : 0.4112681787300543, + "99.9999" : 0.4112681787300543, + "100.0" : 0.4112681787300543 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40847265619638917, + 0.40975114062115875, + 0.4112681787300543 + ], + [ + 0.4056926564300203, + 0.40309408819380066, + 0.40224895885121276 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.160258416830071, + "scoreError" : 0.004033999764718583, + "scoreConfidence" : [ + 0.15622441706535242, + 0.16429241659478958 + ], + "scorePercentiles" : { + "0.0" : 0.1588153917386609, + "50.0" : 0.16015476044348922, + "90.0" : 0.16231229376247747, + "95.0" : 0.16231229376247747, + "99.0" : 0.16231229376247747, + "99.9" : 0.16231229376247747, + "99.99" : 0.16231229376247747, + "99.999" : 0.16231229376247747, + "99.9999" : 0.16231229376247747, + "100.0" : 0.16231229376247747 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16231229376247747, + 0.1610217482328315, + 0.1611612606565567 + ], + [ + 0.15928777265414695, + 0.1588153917386609, + 0.15895203393575255 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04593580255077625, + "scoreError" : 7.083037066726166E-4, + "scoreConfidence" : [ + 0.04522749884410363, + 0.046644106257448865 + ], + "scorePercentiles" : { + "0.0" : 0.0456801348319226, + "50.0" : 0.04593701852658313, + "90.0" : 0.04618633716521105, + "95.0" : 0.04618633716521105, + "99.0" : 0.04618633716521105, + "99.9" : 0.04618633716521105, + "99.99" : 0.04618633716521105, + "99.999" : 0.04618633716521105, + "99.9999" : 0.04618633716521105, + "100.0" : 0.04618633716521105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04615976102048541, + 0.04618633716521105, + 0.046151208360639094 + ], + [ + 0.045714545233872146, + 0.04572282869252716, + 0.0456801348319226 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8506987.78981484, + "scoreError" : 186618.74042547448, + "scoreConfidence" : [ + 8320369.049389364, + 8693606.530240314 + ], + "scorePercentiles" : { + "0.0" : 8447312.75168919, + "50.0" : 8480112.02351723, + "90.0" : 8602675.13327601, + "95.0" : 8602675.13327601, + "99.0" : 8602675.13327601, + "99.9" : 8602675.13327601, + "99.99" : 8602675.13327601, + "99.999" : 8602675.13327601, + "99.9999" : 8602675.13327601, + "100.0" : 8602675.13327601 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8455794.64750634, + 8462642.928087987, + 8447312.75168919 + ], + [ + 8602675.13327601, + 8575920.159383034, + 8497581.118946474 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-21T02:43:48Z-ff857a65e6b9bd520ec49334dd6d3a0caa412380-jdk17.json b/performance-results/2025-07-21T02:43:48Z-ff857a65e6b9bd520ec49334dd6d3a0caa412380-jdk17.json new file mode 100644 index 0000000000..56d907a3bc --- /dev/null +++ b/performance-results/2025-07-21T02:43:48Z-ff857a65e6b9bd520ec49334dd6d3a0caa412380-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.353402942875439, + "scoreError" : 0.03810684829635145, + "scoreConfidence" : [ + 3.3152960945790877, + 3.3915097911717904 + ], + "scorePercentiles" : { + "0.0" : 3.3471181071710974, + "50.0" : 3.3530688207997947, + "90.0" : 3.360356022731068, + "95.0" : 3.360356022731068, + "99.0" : 3.360356022731068, + "99.9" : 3.360356022731068, + "99.99" : 3.360356022731068, + "99.999" : 3.360356022731068, + "99.9999" : 3.360356022731068, + "100.0" : 3.360356022731068 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3471181071710974, + 3.3502176109313764 + ], + [ + 3.3559200306682135, + 3.360356022731068 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6946906581819468, + "scoreError" : 0.035853813858369464, + "scoreConfidence" : [ + 1.6588368443235773, + 1.7305444720403163 + ], + "scorePercentiles" : { + "0.0" : 1.6868776184155958, + "50.0" : 1.6963950887611206, + "90.0" : 1.6990948367899503, + "95.0" : 1.6990948367899503, + "99.0" : 1.6990948367899503, + "99.9" : 1.6990948367899503, + "99.99" : 1.6990948367899503, + "99.999" : 1.6990948367899503, + "99.9999" : 1.6990948367899503, + "100.0" : 1.6990948367899503 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6990948367899503, + 1.6981421233265421 + ], + [ + 1.6868776184155958, + 1.694648054195699 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8508200475523294, + "scoreError" : 0.04645159544140204, + "scoreConfidence" : [ + 0.8043684521109273, + 0.8972716429937315 + ], + "scorePercentiles" : { + "0.0" : 0.843254449769734, + "50.0" : 0.850645700666328, + "90.0" : 0.8587343391069278, + "95.0" : 0.8587343391069278, + "99.0" : 0.8587343391069278, + "99.9" : 0.8587343391069278, + "99.99" : 0.8587343391069278, + "99.999" : 0.8587343391069278, + "99.9999" : 0.8587343391069278, + "100.0" : 0.8587343391069278 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.843254449769734, + 0.8587343391069278 + ], + [ + 0.8464572788851009, + 0.8548341224475552 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.397386851362327, + "scoreError" : 0.2150537322381261, + "scoreConfidence" : [ + 16.182333119124202, + 16.612440583600453 + ], + "scorePercentiles" : { + "0.0" : 16.323944069940083, + "50.0" : 16.368158309349546, + "90.0" : 16.50637214768951, + "95.0" : 16.50637214768951, + "99.0" : 16.50637214768951, + "99.9" : 16.50637214768951, + "99.99" : 16.50637214768951, + "99.999" : 16.50637214768951, + "99.9999" : 16.50637214768951, + "100.0" : 16.50637214768951 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.479128830991346, + 16.50637214768951, + 16.356235828799505 + ], + [ + 16.38008078989959, + 16.338559440853928, + 16.323944069940083 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2726.45504496448, + "scoreError" : 36.22420433010142, + "scoreConfidence" : [ + 2690.2308406343786, + 2762.679249294581 + ], + "scorePercentiles" : { + "0.0" : 2715.457363983382, + "50.0" : 2720.3673402409045, + "90.0" : 2746.855852259408, + "95.0" : 2746.855852259408, + "99.0" : 2746.855852259408, + "99.9" : 2746.855852259408, + "99.99" : 2746.855852259408, + "99.999" : 2746.855852259408, + "99.9999" : 2746.855852259408, + "100.0" : 2746.855852259408 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2722.88827922299, + 2746.855852259408, + 2738.0035057394325 + ], + [ + 2717.846401258819, + 2717.678867322848, + 2715.457363983382 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77621.1373828074, + "scoreError" : 921.2202000774472, + "scoreConfidence" : [ + 76699.91718272996, + 78542.35758288484 + ], + "scorePercentiles" : { + "0.0" : 77278.87456229345, + "50.0" : 77633.4273386586, + "90.0" : 77921.94452890838, + "95.0" : 77921.94452890838, + "99.0" : 77921.94452890838, + "99.9" : 77921.94452890838, + "99.99" : 77921.94452890838, + "99.999" : 77921.94452890838, + "99.9999" : 77921.94452890838, + "100.0" : 77921.94452890838 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77919.06400503554, + 77921.94452890838, + 77919.71655188149 + ], + [ + 77278.87456229345, + 77339.43397644389, + 77347.79067228167 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.17313933194123, + "scoreError" : 3.9017040406889434, + "scoreConfidence" : [ + 357.27143529125226, + 365.0748433726302 + ], + "scorePercentiles" : { + "0.0" : 358.50403854284554, + "50.0" : 361.4382420800065, + "90.0" : 362.3453350609023, + "95.0" : 362.3453350609023, + "99.0" : 362.3453350609023, + "99.9" : 362.3453350609023, + "99.99" : 362.3453350609023, + "99.999" : 362.3453350609023, + "99.9999" : 362.3453350609023, + "100.0" : 362.3453350609023 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 361.12260604479775, + 361.4815286192209, + 362.1903721830885 + ], + [ + 358.50403854284554, + 361.39495554079207, + 362.3453350609023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.13993254337142, + "scoreError" : 2.6777186807158353, + "scoreConfidence" : [ + 113.46221386265557, + 118.81765122408726 + ], + "scorePercentiles" : { + "0.0" : 115.12859215845955, + "50.0" : 116.05088725599444, + "90.0" : 117.51271812193997, + "95.0" : 117.51271812193997, + "99.0" : 117.51271812193997, + "99.9" : 117.51271812193997, + "99.99" : 117.51271812193997, + "99.999" : 117.51271812193997, + "99.9999" : 117.51271812193997, + "100.0" : 117.51271812193997 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.61434673899734, + 116.74974732453428, + 117.51271812193997 + ], + [ + 115.34676314330575, + 115.48742777299155, + 115.12859215845955 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061015735143366695, + "scoreError" : 4.2347589352947695E-4, + "scoreConfidence" : [ + 0.060592259249837216, + 0.061439211036896174 + ], + "scorePercentiles" : { + "0.0" : 0.06086907150813505, + "50.0" : 0.06099386796819187, + "90.0" : 0.06124963805743895, + "95.0" : 0.06124963805743895, + "99.0" : 0.06124963805743895, + "99.9" : 0.06124963805743895, + "99.99" : 0.06124963805743895, + "99.999" : 0.06124963805743895, + "99.9999" : 0.06124963805743895, + "100.0" : 0.06124963805743895 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06088822633008195, + 0.06124963805743895, + 0.06086907150813505 + ], + [ + 0.061099739028160495, + 0.06107613655158093, + 0.060911599384802805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.698613204164069E-4, + "scoreError" : 1.2032536153959123E-5, + "scoreConfidence" : [ + 3.578287842624478E-4, + 3.81893856570366E-4 + ], + "scorePercentiles" : { + "0.0" : 3.658432186096184E-4, + "50.0" : 3.6982689642658945E-4, + "90.0" : 3.742085838040515E-4, + "95.0" : 3.742085838040515E-4, + "99.0" : 3.742085838040515E-4, + "99.9" : 3.742085838040515E-4, + "99.99" : 3.742085838040515E-4, + "99.999" : 3.742085838040515E-4, + "99.9999" : 3.742085838040515E-4, + "100.0" : 3.742085838040515E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.742085838040515E-4, + 3.735528801338856E-4, + 3.7355306743065843E-4 + ], + [ + 3.661009127192933E-4, + 3.6590925980093444E-4, + 3.658432186096184E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12542027208140236, + "scoreError" : 0.0028396758885504718, + "scoreConfidence" : [ + 0.12258059619285189, + 0.12825994796995283 + ], + "scorePercentiles" : { + "0.0" : 0.12435404469148698, + "50.0" : 0.1254747168213527, + "90.0" : 0.12643094644482655, + "95.0" : 0.12643094644482655, + "99.0" : 0.12643094644482655, + "99.9" : 0.12643094644482655, + "99.99" : 0.12643094644482655, + "99.999" : 0.12643094644482655, + "99.9999" : 0.12643094644482655, + "100.0" : 0.12643094644482655 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12634322542987456, + 0.12643094644482655, + 0.126235683960716 + ], + [ + 0.12471374968198938, + 0.12435404469148698, + 0.12444398227952065 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013138433227355202, + "scoreError" : 5.462299977901367E-4, + "scoreConfidence" : [ + 0.012592203229565065, + 0.01368466322514534 + ], + "scorePercentiles" : { + "0.0" : 0.012956229647739242, + "50.0" : 0.013140072719325536, + "90.0" : 0.013321377321216384, + "95.0" : 0.013321377321216384, + "99.0" : 0.013321377321216384, + "99.9" : 0.013321377321216384, + "99.99" : 0.013321377321216384, + "99.999" : 0.013321377321216384, + "99.9999" : 0.013321377321216384, + "100.0" : 0.013321377321216384 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013321377321216384, + 0.013315264706861405, + 0.013311928651489455 + ], + [ + 0.012957582249663108, + 0.012956229647739242, + 0.012968216787161615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9553106707726821, + "scoreError" : 0.054922474432973614, + "scoreConfidence" : [ + 0.9003881963397085, + 1.0102331452056557 + ], + "scorePercentiles" : { + "0.0" : 0.9363559752808989, + "50.0" : 0.9549902011085116, + "90.0" : 0.975399884424071, + "95.0" : 0.975399884424071, + "99.0" : 0.975399884424071, + "99.9" : 0.975399884424071, + "99.99" : 0.975399884424071, + "99.999" : 0.975399884424071, + "99.9999" : 0.975399884424071, + "100.0" : 0.975399884424071 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9363559752808989, + 0.9379142220763388, + 0.9381582622889306 + ], + [ + 0.9722135406377601, + 0.975399884424071, + 0.9718221399280925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010813104411587766, + "scoreError" : 4.1008980937896086E-4, + "scoreConfidence" : [ + 0.010403014602208806, + 0.011223194220966726 + ], + "scorePercentiles" : { + "0.0" : 0.01067158939357075, + "50.0" : 0.010810696315419477, + "90.0" : 0.010955279795447973, + "95.0" : 0.010955279795447973, + "99.0" : 0.010955279795447973, + "99.9" : 0.010955279795447973, + "99.99" : 0.010955279795447973, + "99.999" : 0.010955279795447973, + "99.9999" : 0.010955279795447973, + "100.0" : 0.010955279795447973 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01067158939357075, + 0.0106864217368817, + 0.010681420104375616 + ], + [ + 0.010934970893957254, + 0.010948944545293302, + 0.010955279795447973 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.146371888171615, + "scoreError" : 0.028376781575687078, + "scoreConfidence" : [ + 3.117995106595928, + 3.174748669747302 + ], + "scorePercentiles" : { + "0.0" : 3.1281348605378363, + "50.0" : 3.1499273746887098, + "90.0" : 3.1568726875, + "95.0" : 3.1568726875, + "99.0" : 3.1568726875, + "99.9" : 3.1568726875, + "99.99" : 3.1568726875, + "99.999" : 3.1568726875, + "99.9999" : 3.1568726875, + "100.0" : 3.1568726875 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.151264666036547, + 3.1489987380352646, + 3.1281348605378363 + ], + [ + 3.1568726875, + 3.150856011342155, + 3.1421043655778895 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7211642564000003, + "scoreError" : 0.037442297211382695, + "scoreConfidence" : [ + 2.6837219591886177, + 2.758606553611383 + ], + "scorePercentiles" : { + "0.0" : 2.7088432941495126, + "50.0" : 2.7159281527522077, + "90.0" : 2.740524019731433, + "95.0" : 2.740524019731433, + "99.0" : 2.740524019731433, + "99.9" : 2.740524019731433, + "99.99" : 2.740524019731433, + "99.999" : 2.740524019731433, + "99.9999" : 2.740524019731433, + "100.0" : 2.740524019731433 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7109609113580917, + 2.7088432941495126, + 2.7127731505288852 + ], + [ + 2.734801007656549, + 2.71908315497553, + 2.740524019731433 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1795068574280204, + "scoreError" : 0.024607155862681012, + "scoreConfidence" : [ + 0.1548997015653394, + 0.2041140132907014 + ], + "scorePercentiles" : { + "0.0" : 0.1713882382943717, + "50.0" : 0.17890938241654963, + "90.0" : 0.18849500701185606, + "95.0" : 0.18849500701185606, + "99.0" : 0.18849500701185606, + "99.9" : 0.18849500701185606, + "99.99" : 0.18849500701185606, + "99.999" : 0.18849500701185606, + "99.9999" : 0.18849500701185606, + "100.0" : 0.18849500701185606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18849500701185606, + 0.1878270849141655, + 0.18613642479292694 + ], + [ + 0.17168234004017235, + 0.1715120495146297, + 0.1713882382943717 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33029560932878804, + "scoreError" : 0.016685196094065477, + "scoreConfidence" : [ + 0.31361041323472255, + 0.34698080542285353 + ], + "scorePercentiles" : { + "0.0" : 0.3246752081101263, + "50.0" : 0.3302238419566086, + "90.0" : 0.3362218044918132, + "95.0" : 0.3362218044918132, + "99.0" : 0.3362218044918132, + "99.9" : 0.3362218044918132, + "99.99" : 0.3362218044918132, + "99.999" : 0.3362218044918132, + "99.9999" : 0.3362218044918132, + "100.0" : 0.3362218044918132 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3246752081101263, + 0.32481457723788487, + 0.3251263675466545 + ], + [ + 0.3353213163665627, + 0.3362218044918132, + 0.33561438221968654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1479445980007159, + "scoreError" : 0.006920948817668318, + "scoreConfidence" : [ + 0.1410236491830476, + 0.15486554681838421 + ], + "scorePercentiles" : { + "0.0" : 0.14554108755512218, + "50.0" : 0.14801026432394207, + "90.0" : 0.1502116938294229, + "95.0" : 0.1502116938294229, + "99.0" : 0.1502116938294229, + "99.9" : 0.1502116938294229, + "99.99" : 0.1502116938294229, + "99.999" : 0.1502116938294229, + "99.9999" : 0.1502116938294229, + "100.0" : 0.1502116938294229 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14554108755512218, + 0.1458399522677556, + 0.14569866294655864 + ], + [ + 0.1501956150253075, + 0.1502116938294229, + 0.15018057638012855 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40364748065801476, + "scoreError" : 0.009978192428891515, + "scoreConfidence" : [ + 0.3936692882291232, + 0.4136256730869063 + ], + "scorePercentiles" : { + "0.0" : 0.40044748192047414, + "50.0" : 0.40292384584281526, + "90.0" : 0.40862512058186573, + "95.0" : 0.40862512058186573, + "99.0" : 0.40862512058186573, + "99.9" : 0.40862512058186573, + "99.99" : 0.40862512058186573, + "99.999" : 0.40862512058186573, + "99.9999" : 0.40862512058186573, + "100.0" : 0.40862512058186573 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40862512058186573, + 0.4064025708944609, + 0.40517477979012195 + ], + [ + 0.40067291189550863, + 0.4005620188656573, + 0.40044748192047414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15721684111093398, + "scoreError" : 0.008404918614946223, + "scoreConfidence" : [ + 0.14881192249598776, + 0.1656217597258802 + ], + "scorePercentiles" : { + "0.0" : 0.15445115148192196, + "50.0" : 0.15708830267784868, + "90.0" : 0.1605590765365102, + "95.0" : 0.1605590765365102, + "99.0" : 0.1605590765365102, + "99.9" : 0.1605590765365102, + "99.99" : 0.1605590765365102, + "99.999" : 0.1605590765365102, + "99.9999" : 0.1605590765365102, + "100.0" : 0.1605590765365102 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15457688193650107, + 0.15446865479849858, + 0.15445115148192196 + ], + [ + 0.1605590765365102, + 0.15964555849297574, + 0.15959972341919626 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04760987561911223, + "scoreError" : 0.0030562434476176376, + "scoreConfidence" : [ + 0.04455363217149459, + 0.05066611906672987 + ], + "scorePercentiles" : { + "0.0" : 0.04654766798549598, + "50.0" : 0.04750736183864036, + "90.0" : 0.049141659885206586, + "95.0" : 0.049141659885206586, + "99.0" : 0.049141659885206586, + "99.9" : 0.049141659885206586, + "99.99" : 0.049141659885206586, + "99.999" : 0.049141659885206586, + "99.9999" : 0.049141659885206586, + "100.0" : 0.049141659885206586 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.049141659885206586, + 0.048230377289695286, + 0.04830315963464056 + ], + [ + 0.04678434638758544, + 0.046652042532049486, + 0.04654766798549598 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8497163.683661932, + "scoreError" : 427494.6368391711, + "scoreConfidence" : [ + 8069669.046822761, + 8924658.320501104 + ], + "scorePercentiles" : { + "0.0" : 8339939.269166667, + "50.0" : 8500156.331570048, + "90.0" : 8652731.56314879, + "95.0" : 8652731.56314879, + "99.0" : 8652731.56314879, + "99.9" : 8652731.56314879, + "99.99" : 8652731.56314879, + "99.999" : 8652731.56314879, + "99.9999" : 8652731.56314879, + "100.0" : 8652731.56314879 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8347720.316360601, + 8390902.781040268, + 8339939.269166667 + ], + [ + 8642278.29015544, + 8652731.56314879, + 8609409.882099828 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-21T09:01:44Z-43a54fc9a2e2004d5e6593943deac2988a089bcd-jdk17.json b/performance-results/2025-07-21T09:01:44Z-43a54fc9a2e2004d5e6593943deac2988a089bcd-jdk17.json new file mode 100644 index 0000000000..08d3754fcb --- /dev/null +++ b/performance-results/2025-07-21T09:01:44Z-43a54fc9a2e2004d5e6593943deac2988a089bcd-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3395296683647198, + "scoreError" : 0.052074839604582555, + "scoreConfidence" : [ + 3.2874548287601373, + 3.3916045079693022 + ], + "scorePercentiles" : { + "0.0" : 3.3300617520363356, + "50.0" : 3.339731628772678, + "90.0" : 3.348593663877187, + "95.0" : 3.348593663877187, + "99.0" : 3.348593663877187, + "99.9" : 3.348593663877187, + "99.99" : 3.348593663877187, + "99.999" : 3.348593663877187, + "99.9999" : 3.348593663877187, + "100.0" : 3.348593663877187 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.343118807600336, + 3.348593663877187 + ], + [ + 3.3300617520363356, + 3.33634444994502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6841453793729038, + "scoreError" : 0.039986765756976766, + "scoreConfidence" : [ + 1.644158613615927, + 1.7241321451298806 + ], + "scorePercentiles" : { + "0.0" : 1.6772598569488215, + "50.0" : 1.6836510465834902, + "90.0" : 1.6920195673758136, + "95.0" : 1.6920195673758136, + "99.0" : 1.6920195673758136, + "99.9" : 1.6920195673758136, + "99.99" : 1.6920195673758136, + "99.999" : 1.6920195673758136, + "99.9999" : 1.6920195673758136, + "100.0" : 1.6920195673758136 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6772598569488215, + 1.6820743557923434 + ], + [ + 1.6852277373746372, + 1.6920195673758136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.845445131274986, + "scoreError" : 0.021027380397238386, + "scoreConfidence" : [ + 0.8244177508777476, + 0.8664725116722244 + ], + "scorePercentiles" : { + "0.0" : 0.8425504084557296, + "50.0" : 0.8449012418409492, + "90.0" : 0.849427632962316, + "95.0" : 0.849427632962316, + "99.0" : 0.849427632962316, + "99.9" : 0.849427632962316, + "99.99" : 0.849427632962316, + "99.999" : 0.849427632962316, + "99.9999" : 0.849427632962316, + "100.0" : 0.849427632962316 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8425504084557296, + 0.8430392026928639 + ], + [ + 0.8467632809890344, + 0.849427632962316 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.134890085465816, + "scoreError" : 0.426288903731031, + "scoreConfidence" : [ + 15.708601181734785, + 16.561178989196847 + ], + "scorePercentiles" : { + "0.0" : 15.95100229530205, + "50.0" : 16.135567151530807, + "90.0" : 16.302067481838954, + "95.0" : 16.302067481838954, + "99.0" : 16.302067481838954, + "99.9" : 16.302067481838954, + "99.99" : 16.302067481838954, + "99.999" : 16.302067481838954, + "99.9999" : 16.302067481838954, + "100.0" : 16.302067481838954 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.007061610032853, + 16.043527582506, + 15.95100229530205 + ], + [ + 16.227606720555613, + 16.278074822559443, + 16.302067481838954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2665.8740617669464, + "scoreError" : 114.46676969627923, + "scoreConfidence" : [ + 2551.407292070667, + 2780.3408314632256 + ], + "scorePercentiles" : { + "0.0" : 2612.5779056346055, + "50.0" : 2667.119844069909, + "90.0" : 2725.500101763791, + "95.0" : 2725.500101763791, + "99.0" : 2725.500101763791, + "99.9" : 2725.500101763791, + "99.99" : 2725.500101763791, + "99.999" : 2725.500101763791, + "99.9999" : 2725.500101763791, + "100.0" : 2725.500101763791 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2612.5779056346055, + 2648.559111065983, + 2636.9217069611495 + ], + [ + 2686.004968102314, + 2725.500101763791, + 2685.6805770738356 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75890.4625431142, + "scoreError" : 1933.2438813452575, + "scoreConfidence" : [ + 73957.21866176894, + 77823.70642445947 + ], + "scorePercentiles" : { + "0.0" : 75171.86796656065, + "50.0" : 75898.53799604665, + "90.0" : 76624.48414828714, + "95.0" : 76624.48414828714, + "99.0" : 76624.48414828714, + "99.9" : 76624.48414828714, + "99.99" : 76624.48414828714, + "99.999" : 76624.48414828714, + "99.9999" : 76624.48414828714, + "100.0" : 76624.48414828714 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76624.48414828714, + 76521.80172849288, + 76390.02021178631 + ], + [ + 75171.86796656065, + 75407.05578030701, + 75227.54542325121 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 358.7245600605024, + "scoreError" : 24.35427538070495, + "scoreConfidence" : [ + 334.37028467979746, + 383.0788354412074 + ], + "scorePercentiles" : { + "0.0" : 349.08482301369224, + "50.0" : 358.0562225279694, + "90.0" : 368.7800317782533, + "95.0" : 368.7800317782533, + "99.0" : 368.7800317782533, + "99.9" : 368.7800317782533, + "99.99" : 368.7800317782533, + "99.999" : 368.7800317782533, + "99.9999" : 368.7800317782533, + "100.0" : 368.7800317782533 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.5370553245632, + 364.12600209537857, + 368.7800317782533 + ], + [ + 349.08482301369224, + 351.9864429605602, + 351.8330051905671 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.64367989581547, + "scoreError" : 1.2034438547428785, + "scoreConfidence" : [ + 115.4402360410726, + 117.84712375055834 + ], + "scorePercentiles" : { + "0.0" : 115.91318028612135, + "50.0" : 116.81532519696273, + "90.0" : 117.02108909877536, + "95.0" : 117.02108909877536, + "99.0" : 117.02108909877536, + "99.9" : 117.02108909877536, + "99.99" : 117.02108909877536, + "99.999" : 117.02108909877536, + "99.9999" : 117.02108909877536, + "100.0" : 117.02108909877536 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.75727205747702, + 117.02108909877536, + 115.91318028612135 + ], + [ + 116.34932224927984, + 116.94783734679078, + 116.87337833644843 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06136364903368103, + "scoreError" : 3.025204838736298E-4, + "scoreConfidence" : [ + 0.0610611285498074, + 0.06166616951755466 + ], + "scorePercentiles" : { + "0.0" : 0.06121976743516909, + "50.0" : 0.06140227874427741, + "90.0" : 0.061469299898577, + "95.0" : 0.061469299898577, + "99.0" : 0.061469299898577, + "99.9" : 0.061469299898577, + "99.99" : 0.061469299898577, + "99.999" : 0.061469299898577, + "99.9999" : 0.061469299898577, + "100.0" : 0.061469299898577 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06123948405349794, + 0.061383857739147514, + 0.0614206997494073 + ], + [ + 0.061469299898577, + 0.06121976743516909, + 0.06144878532628733 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.643976712244534E-4, + "scoreError" : 2.468188723939987E-5, + "scoreConfidence" : [ + 3.397157839850535E-4, + 3.8907955846385325E-4 + ], + "scorePercentiles" : { + "0.0" : 3.55307915918976E-4, + "50.0" : 3.641154636049315E-4, + "90.0" : 3.7552256004423304E-4, + "95.0" : 3.7552256004423304E-4, + "99.0" : 3.7552256004423304E-4, + "99.9" : 3.7552256004423304E-4, + "99.99" : 3.7552256004423304E-4, + "99.999" : 3.7552256004423304E-4, + "99.9999" : 3.7552256004423304E-4, + "100.0" : 3.7552256004423304E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7552256004423304E-4, + 3.6943930681771625E-4, + 3.7150591145516693E-4 + ], + [ + 3.55307915918976E-4, + 3.558187127184809E-4, + 3.5879162039214674E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12749728648834927, + "scoreError" : 0.003829018675387292, + "scoreConfidence" : [ + 0.12366826781296197, + 0.13132630516373656 + ], + "scorePercentiles" : { + "0.0" : 0.12600521034991116, + "50.0" : 0.12759610020486023, + "90.0" : 0.1292823132821388, + "95.0" : 0.1292823132821388, + "99.0" : 0.1292823132821388, + "99.9" : 0.1292823132821388, + "99.99" : 0.1292823132821388, + "99.999" : 0.1292823132821388, + "99.9999" : 0.1292823132821388, + "100.0" : 0.1292823132821388 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12607663913613557, + 0.12600521034991116, + 0.12688650007613053 + ], + [ + 0.1292823132821388, + 0.12830570033358993, + 0.12842735575218966 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013145683190638602, + "scoreError" : 1.8475533071340449E-4, + "scoreConfidence" : [ + 0.012960927859925198, + 0.013330438521352007 + ], + "scorePercentiles" : { + "0.0" : 0.013074028748074876, + "50.0" : 0.013142266174467974, + "90.0" : 0.013234839565532721, + "95.0" : 0.013234839565532721, + "99.0" : 0.013234839565532721, + "99.9" : 0.013234839565532721, + "99.99" : 0.013234839565532721, + "99.999" : 0.013234839565532721, + "99.9999" : 0.013234839565532721, + "100.0" : 0.013234839565532721 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013089071269073804, + 0.013101755788938588, + 0.013074028748074876 + ], + [ + 0.013182776559997363, + 0.013191627212214271, + 0.013234839565532721 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0327181301780206, + "scoreError" : 0.011641240884108813, + "scoreConfidence" : [ + 1.0210768892939117, + 1.0443593710621295 + ], + "scorePercentiles" : { + "0.0" : 1.0278013557040082, + "50.0" : 1.0331959079865263, + "90.0" : 1.0372554411368116, + "95.0" : 1.0372554411368116, + "99.0" : 1.0372554411368116, + "99.9" : 1.0372554411368116, + "99.99" : 1.0372554411368116, + "99.999" : 1.0372554411368116, + "99.9999" : 1.0372554411368116, + "100.0" : 1.0372554411368116 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.031690665015991, + 1.0278013557040082, + 1.0281725106404853 + ], + [ + 1.0372554411368116, + 1.0347011509570616, + 1.036687657613766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010855624609490862, + "scoreError" : 0.0016129789246444564, + "scoreConfidence" : [ + 0.009242645684846406, + 0.012468603534135318 + ], + "scorePercentiles" : { + "0.0" : 0.01028154978779579, + "50.0" : 0.010858672997300044, + "90.0" : 0.011439420927524428, + "95.0" : 0.011439420927524428, + "99.0" : 0.011439420927524428, + "99.9" : 0.011439420927524428, + "99.99" : 0.011439420927524428, + "99.999" : 0.011439420927524428, + "99.9999" : 0.011439420927524428, + "100.0" : 0.011439420927524428 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010407942039574201, + 0.010310381006680963, + 0.01028154978779579 + ], + [ + 0.011439420927524428, + 0.011309403955025887, + 0.01138504994034391 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.323051102738992, + "scoreError" : 0.22578671324912253, + "scoreConfidence" : [ + 3.0972643894898693, + 3.5488378159881147 + ], + "scorePercentiles" : { + "0.0" : 3.233474136393019, + "50.0" : 3.3344086587187345, + "90.0" : 3.399839808293678, + "95.0" : 3.399839808293678, + "99.0" : 3.399839808293678, + "99.9" : 3.399839808293678, + "99.99" : 3.399839808293678, + "99.999" : 3.399839808293678, + "99.9999" : 3.399839808293678, + "100.0" : 3.399839808293678 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2794511114754097, + 3.2401548465025907, + 3.233474136393019 + ], + [ + 3.3960205078071963, + 3.3893662059620597, + 3.399839808293678 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8233421626990425, + "scoreError" : 0.09277570281225515, + "scoreConfidence" : [ + 2.7305664598867874, + 2.9161178655112976 + ], + "scorePercentiles" : { + "0.0" : 2.7830908870339455, + "50.0" : 2.826048434893754, + "90.0" : 2.861434471816881, + "95.0" : 2.861434471816881, + "99.0" : 2.861434471816881, + "99.9" : 2.861434471816881, + "99.99" : 2.861434471816881, + "99.999" : 2.861434471816881, + "99.9999" : 2.861434471816881, + "100.0" : 2.861434471816881 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8418254893435635, + 2.861434471816881, + 2.8524076297775243 + ], + [ + 2.810271380443945, + 2.7830908870339455, + 2.791023117778398 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18183386840603266, + "scoreError" : 0.017888929166994777, + "scoreConfidence" : [ + 0.16394493923903788, + 0.19972279757302744 + ], + "scorePercentiles" : { + "0.0" : 0.17586656111286975, + "50.0" : 0.18103952522767514, + "90.0" : 0.18879722628756984, + "95.0" : 0.18879722628756984, + "99.0" : 0.18879722628756984, + "99.9" : 0.18879722628756984, + "99.99" : 0.18879722628756984, + "99.999" : 0.18879722628756984, + "99.9999" : 0.18879722628756984, + "100.0" : 0.18879722628756984 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18564282915645652, + 0.18827697247481878, + 0.18879722628756984 + ], + [ + 0.17586656111286975, + 0.17598340010558733, + 0.17643622129889378 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3294255143815663, + "scoreError" : 0.01278462688370167, + "scoreConfidence" : [ + 0.3166408874978646, + 0.342210141265268 + ], + "scorePercentiles" : { + "0.0" : 0.3248514578677235, + "50.0" : 0.32914625044051615, + "90.0" : 0.33575594117647056, + "95.0" : 0.33575594117647056, + "99.0" : 0.33575594117647056, + "99.9" : 0.33575594117647056, + "99.99" : 0.33575594117647056, + "99.999" : 0.33575594117647056, + "99.9999" : 0.33575594117647056, + "100.0" : 0.33575594117647056 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33575594117647056, + 0.3315880841871415, + 0.33270816088894806 + ], + [ + 0.3267044166938909, + 0.3249450254752234, + 0.3248514578677235 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1462685779301067, + "scoreError" : 0.006878577052161618, + "scoreConfidence" : [ + 0.1393900008779451, + 0.1531471549822683 + ], + "scorePercentiles" : { + "0.0" : 0.14338569941069354, + "50.0" : 0.14655260835111644, + "90.0" : 0.14902003106978406, + "95.0" : 0.14902003106978406, + "99.0" : 0.14902003106978406, + "99.9" : 0.14902003106978406, + "99.99" : 0.14902003106978406, + "99.999" : 0.14902003106978406, + "99.9999" : 0.14902003106978406, + "100.0" : 0.14902003106978406 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14902003106978406, + 0.1480221387803434, + 0.14824434741617007 + ], + [ + 0.1438561729817596, + 0.14508307792188951, + 0.14338569941069354 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40002628351912356, + "scoreError" : 0.012611016860689536, + "scoreConfidence" : [ + 0.387415266658434, + 0.4126373003798131 + ], + "scorePercentiles" : { + "0.0" : 0.3940947955862069, + "50.0" : 0.3998577084150632, + "90.0" : 0.4057242382343395, + "95.0" : 0.4057242382343395, + "99.0" : 0.4057242382343395, + "99.9" : 0.4057242382343395, + "99.99" : 0.4057242382343395, + "99.999" : 0.4057242382343395, + "99.9999" : 0.4057242382343395, + "100.0" : 0.4057242382343395 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39708418610283897, + 0.39736543489490206, + 0.3940947955862069 + ], + [ + 0.40353906436122994, + 0.4057242382343395, + 0.4023499819352243 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15236921783977786, + "scoreError" : 0.01105649940733485, + "scoreConfidence" : [ + 0.141312718432443, + 0.16342571724711272 + ], + "scorePercentiles" : { + "0.0" : 0.14852456077528592, + "50.0" : 0.1523615217339061, + "90.0" : 0.15635272212928947, + "95.0" : 0.15635272212928947, + "99.0" : 0.15635272212928947, + "99.9" : 0.15635272212928947, + "99.99" : 0.15635272212928947, + "99.999" : 0.15635272212928947, + "99.9999" : 0.15635272212928947, + "100.0" : 0.15635272212928947 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14897401303499336, + 0.14852456077528592, + 0.1488345497693109 + ], + [ + 0.15635272212928947, + 0.15578043089696855, + 0.15574903043281885 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04703852858078635, + "scoreError" : 7.881321045162739E-4, + "scoreConfidence" : [ + 0.04625039647627008, + 0.04782666068530263 + ], + "scorePercentiles" : { + "0.0" : 0.046583208736077665, + "50.0" : 0.047166424486323036, + "90.0" : 0.0472888680090226, + "95.0" : 0.0472888680090226, + "99.0" : 0.0472888680090226, + "99.9" : 0.0472888680090226, + "99.99" : 0.0472888680090226, + "99.999" : 0.0472888680090226, + "99.9999" : 0.0472888680090226, + "100.0" : 0.0472888680090226 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0471998917627957, + 0.046802493777700814, + 0.046583208736077665 + ], + [ + 0.0472888680090226, + 0.04722375198927092, + 0.04713295720985036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8586794.273687998, + "scoreError" : 136819.62220666892, + "scoreConfidence" : [ + 8449974.651481329, + 8723613.895894667 + ], + "scorePercentiles" : { + "0.0" : 8543041.335610589, + "50.0" : 8573917.744420212, + "90.0" : 8668276.213171577, + "95.0" : 8668276.213171577, + "99.0" : 8668276.213171577, + "99.9" : 8668276.213171577, + "99.99" : 8668276.213171577, + "99.999" : 8668276.213171577, + "99.9999" : 8668276.213171577, + "100.0" : 8668276.213171577 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8668276.213171577, + 8613698.919035314, + 8593692.823883161 + ], + [ + 8547913.685470086, + 8554142.664957264, + 8543041.335610589 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-23T07:28:34Z-e8028d9097760fa289e0439c0c2ec14b36531832-jdk17.json b/performance-results/2025-07-23T07:28:34Z-e8028d9097760fa289e0439c0c2ec14b36531832-jdk17.json new file mode 100644 index 0000000000..cde2d353c1 --- /dev/null +++ b/performance-results/2025-07-23T07:28:34Z-e8028d9097760fa289e0439c0c2ec14b36531832-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3210693322577427, + "scoreError" : 0.04412599747722316, + "scoreConfidence" : [ + 3.2769433347805195, + 3.365195329734966 + ], + "scorePercentiles" : { + "0.0" : 3.311714602616375, + "50.0" : 3.323190266743688, + "90.0" : 3.32618219292722, + "95.0" : 3.32618219292722, + "99.0" : 3.32618219292722, + "99.9" : 3.32618219292722, + "99.99" : 3.32618219292722, + "99.999" : 3.32618219292722, + "99.9999" : 3.32618219292722, + "100.0" : 3.32618219292722 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3202544428868146, + 3.326126090600561 + ], + [ + 3.311714602616375, + 3.32618219292722 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6728462100885109, + "scoreError" : 0.06637088928819275, + "scoreConfidence" : [ + 1.6064753208003182, + 1.7392170993767035 + ], + "scorePercentiles" : { + "0.0" : 1.6614069284180348, + "50.0" : 1.6736975929349045, + "90.0" : 1.6825827260661992, + "95.0" : 1.6825827260661992, + "99.0" : 1.6825827260661992, + "99.9" : 1.6825827260661992, + "99.99" : 1.6825827260661992, + "99.999" : 1.6825827260661992, + "99.9999" : 1.6825827260661992, + "100.0" : 1.6825827260661992 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6614069284180348, + 1.6670128426393849 + ], + [ + 1.6803823432304243, + 1.6825827260661992 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8403205807665421, + "scoreError" : 0.0409450543545081, + "scoreConfidence" : [ + 0.799375526412034, + 0.8812656351210503 + ], + "scorePercentiles" : { + "0.0" : 0.8346553689345669, + "50.0" : 0.8386182143697944, + "90.0" : 0.8493905253920129, + "95.0" : 0.8493905253920129, + "99.0" : 0.8493905253920129, + "99.9" : 0.8493905253920129, + "99.99" : 0.8493905253920129, + "99.999" : 0.8493905253920129, + "99.9999" : 0.8493905253920129, + "100.0" : 0.8493905253920129 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8346553689345669, + 0.8389997796000715 + ], + [ + 0.8382366491395175, + 0.8493905253920129 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.904028462861662, + "scoreError" : 0.3210965131777212, + "scoreConfidence" : [ + 15.58293194968394, + 16.225124976039382 + ], + "scorePercentiles" : { + "0.0" : 15.772808742468323, + "50.0" : 15.885731976728243, + "90.0" : 16.039565463012917, + "95.0" : 16.039565463012917, + "99.0" : 16.039565463012917, + "99.9" : 16.039565463012917, + "99.99" : 16.039565463012917, + "99.999" : 16.039565463012917, + "99.9999" : 16.039565463012917, + "100.0" : 16.039565463012917 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.815260802087998, + 15.827557073905762, + 15.772808742468323 + ], + [ + 16.039565463012917, + 15.943906879550724, + 16.025071816144248 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2663.424897868778, + "scoreError" : 316.21383478370404, + "scoreConfidence" : [ + 2347.211063085074, + 2979.638732652482 + ], + "scorePercentiles" : { + "0.0" : 2556.047755010782, + "50.0" : 2664.87683489745, + "90.0" : 2776.4688962236846, + "95.0" : 2776.4688962236846, + "99.0" : 2776.4688962236846, + "99.9" : 2776.4688962236846, + "99.99" : 2776.4688962236846, + "99.999" : 2776.4688962236846, + "99.9999" : 2776.4688962236846, + "100.0" : 2776.4688962236846 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2568.7994825505266, + 2556.047755010782, + 2557.237235957458 + ], + [ + 2776.4688962236846, + 2761.041830225842, + 2760.9541872443733 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74369.42246699448, + "scoreError" : 2478.9298893132095, + "scoreConfidence" : [ + 71890.49257768127, + 76848.35235630769 + ], + "scorePercentiles" : { + "0.0" : 73430.44287823535, + "50.0" : 74350.25196964684, + "90.0" : 75243.70201380273, + "95.0" : 75243.70201380273, + "99.0" : 75243.70201380273, + "99.9" : 75243.70201380273, + "99.99" : 75243.70201380273, + "99.999" : 75243.70201380273, + "99.9999" : 75243.70201380273, + "100.0" : 75243.70201380273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75206.51453895739, + 75064.75683004271, + 75243.70201380273 + ], + [ + 73430.44287823535, + 73635.37143167769, + 73635.74710925095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 345.8325098273844, + "scoreError" : 5.333215622290192, + "scoreConfidence" : [ + 340.4992942050942, + 351.1657254496746 + ], + "scorePercentiles" : { + "0.0" : 343.0816229357919, + "50.0" : 346.2311985247809, + "90.0" : 347.89370235862117, + "95.0" : 347.89370235862117, + "99.0" : 347.89370235862117, + "99.9" : 347.89370235862117, + "99.99" : 347.89370235862117, + "99.999" : 347.89370235862117, + "99.9999" : 347.89370235862117, + "100.0" : 347.89370235862117 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 346.89084187364006, + 347.3717482904487, + 347.89370235862117 + ], + [ + 345.57155517592173, + 343.0816229357919, + 344.1855883298826 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.8763820125598, + "scoreError" : 2.1504869059830325, + "scoreConfidence" : [ + 111.72589510657677, + 116.02686891854283 + ], + "scorePercentiles" : { + "0.0" : 112.93312515921971, + "50.0" : 114.02124266844669, + "90.0" : 114.78958134174972, + "95.0" : 114.78958134174972, + "99.0" : 114.78958134174972, + "99.9" : 114.78958134174972, + "99.99" : 114.78958134174972, + "99.999" : 114.78958134174972, + "99.9999" : 114.78958134174972, + "100.0" : 114.78958134174972 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.78958134174972, + 114.20290144982496, + 114.47976557550679 + ], + [ + 112.93312515921971, + 113.83958388706841, + 113.0133346619891 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062498624819781384, + "scoreError" : 3.5393198837301905E-4, + "scoreConfidence" : [ + 0.06214469283140837, + 0.06285255680815441 + ], + "scorePercentiles" : { + "0.0" : 0.062321238394376206, + "50.0" : 0.06246576123335251, + "90.0" : 0.06265961065196278, + "95.0" : 0.06265961065196278, + "99.0" : 0.06265961065196278, + "99.9" : 0.06265961065196278, + "99.99" : 0.06265961065196278, + "99.999" : 0.06265961065196278, + "99.9999" : 0.06265961065196278, + "100.0" : 0.06265961065196278 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06265961065196278, + 0.06263016651844429, + 0.06244921088720001 + ], + [ + 0.062321238394376206, + 0.062479260596291296, + 0.062452261870413736 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.82931855293523E-4, + "scoreError" : 4.80534574179295E-5, + "scoreConfidence" : [ + 3.348783978755935E-4, + 4.309853127114525E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6712111417559713E-4, + "50.0" : 3.8238391221777574E-4, + "90.0" : 3.9972883960500013E-4, + "95.0" : 3.9972883960500013E-4, + "99.0" : 3.9972883960500013E-4, + "99.9" : 3.9972883960500013E-4, + "99.99" : 3.9972883960500013E-4, + "99.999" : 3.9972883960500013E-4, + "99.9999" : 3.9972883960500013E-4, + "100.0" : 3.9972883960500013E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9882352020140645E-4, + 3.9972883960500013E-4, + 3.9711368449191724E-4 + ], + [ + 3.671498333435828E-4, + 3.6712111417559713E-4, + 3.6765413994363424E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1280177638901225, + "scoreError" : 0.004624635539129939, + "scoreConfidence" : [ + 0.12339312835099257, + 0.13264239942925246 + ], + "scorePercentiles" : { + "0.0" : 0.12643302672735318, + "50.0" : 0.1279505834810614, + "90.0" : 0.12986649093553582, + "95.0" : 0.12986649093553582, + "99.0" : 0.12986649093553582, + "99.9" : 0.12986649093553582, + "99.99" : 0.12986649093553582, + "99.999" : 0.12986649093553582, + "99.9999" : 0.12986649093553582, + "100.0" : 0.12986649093553582 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12663277876408763, + 0.12650738700536382, + 0.12643302672735318 + ], + [ + 0.12939851171035946, + 0.12986649093553582, + 0.12926838819803516 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013281114539635106, + "scoreError" : 7.986062210596716E-5, + "scoreConfidence" : [ + 0.013201253917529139, + 0.013360975161741073 + ], + "scorePercentiles" : { + "0.0" : 0.013235320004658772, + "50.0" : 0.013280349961591307, + "90.0" : 0.013316014101480056, + "95.0" : 0.013316014101480056, + "99.0" : 0.013316014101480056, + "99.9" : 0.013316014101480056, + "99.99" : 0.013316014101480056, + "99.999" : 0.013316014101480056, + "99.9999" : 0.013316014101480056, + "100.0" : 0.013316014101480056 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013235320004658772, + 0.013276786587980696, + 0.01326948811269355 + ], + [ + 0.013316014101480056, + 0.01328391333520192, + 0.013305165095795636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0165166842574735, + "scoreError" : 0.0352455868899257, + "scoreConfidence" : [ + 0.9812710973675478, + 1.0517622711473993 + ], + "scorePercentiles" : { + "0.0" : 1.0028103538554096, + "50.0" : 1.0171845207526777, + "90.0" : 1.0288915903292182, + "95.0" : 1.0288915903292182, + "99.0" : 1.0288915903292182, + "99.9" : 1.0288915903292182, + "99.99" : 1.0288915903292182, + "99.999" : 1.0288915903292182, + "99.9999" : 1.0288915903292182, + "100.0" : 1.0288915903292182 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.026361710591133, + 1.028337266529563, + 1.0288915903292182 + ], + [ + 1.0046918533252964, + 1.0028103538554096, + 1.0080073309142223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01152877189871051, + "scoreError" : 9.0023643687256E-4, + "scoreConfidence" : [ + 0.010628535461837951, + 0.01242900833558307 + ], + "scorePercentiles" : { + "0.0" : 0.011226953346446085, + "50.0" : 0.011510304062614371, + "90.0" : 0.01185988414373814, + "95.0" : 0.01185988414373814, + "99.0" : 0.01185988414373814, + "99.9" : 0.01185988414373814, + "99.99" : 0.01185988414373814, + "99.999" : 0.01185988414373814, + "99.9999" : 0.01185988414373814, + "100.0" : 0.01185988414373814 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011830040583159633, + 0.011771952249446143, + 0.01185988414373814 + ], + [ + 0.0112486558757826, + 0.011235145193690455, + 0.011226953346446085 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.380113235191704, + "scoreError" : 0.34118619387210386, + "scoreConfidence" : [ + 3.0389270413196003, + 3.7212994290638077 + ], + "scorePercentiles" : { + "0.0" : 3.246664155094095, + "50.0" : 3.3967437457418215, + "90.0" : 3.4949635296995107, + "95.0" : 3.4949635296995107, + "99.0" : 3.4949635296995107, + "99.9" : 3.4949635296995107, + "99.99" : 3.4949635296995107, + "99.999" : 3.4949635296995107, + "99.9999" : 3.4949635296995107, + "100.0" : 3.4949635296995107 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4928898324022346, + 3.4949635296995107, + 3.478922445757997 + ], + [ + 3.314565045725646, + 3.252674402470741, + 3.246664155094095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.890360681688394, + "scoreError" : 0.09906966435672872, + "scoreConfidence" : [ + 2.791291017331665, + 2.989430346045123 + ], + "scorePercentiles" : { + "0.0" : 2.846870462852263, + "50.0" : 2.900062499935226, + "90.0" : 2.924440034502924, + "95.0" : 2.924440034502924, + "99.0" : 2.924440034502924, + "99.9" : 2.924440034502924, + "99.99" : 2.924440034502924, + "99.999" : 2.924440034502924, + "99.9999" : 2.924440034502924, + "100.0" : 2.924440034502924 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.924440034502924, + 2.9199205772262773, + 2.916818213764946 + ], + [ + 2.8833067861055057, + 2.846870462852263, + 2.8508080156784494 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17554518688559415, + "scoreError" : 0.004750111818234367, + "scoreConfidence" : [ + 0.17079507506735978, + 0.18029529870382852 + ], + "scorePercentiles" : { + "0.0" : 0.17391181494556712, + "50.0" : 0.175523412460851, + "90.0" : 0.17719244254655633, + "95.0" : 0.17719244254655633, + "99.0" : 0.17719244254655633, + "99.9" : 0.17719244254655633, + "99.99" : 0.17719244254655633, + "99.999" : 0.17719244254655633, + "99.9999" : 0.17719244254655633, + "100.0" : 0.17719244254655633 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17391181494556712, + 0.17397717526096032, + 0.17411743329735 + ], + [ + 0.17714286363877915, + 0.176929391624352, + 0.17719244254655633 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3284708466388047, + "scoreError" : 0.025412264021217428, + "scoreConfidence" : [ + 0.3030585826175873, + 0.35388311066002215 + ], + "scorePercentiles" : { + "0.0" : 0.3199065666986564, + "50.0" : 0.3280011422187443, + "90.0" : 0.33808313735632184, + "95.0" : 0.33808313735632184, + "99.0" : 0.33808313735632184, + "99.9" : 0.33808313735632184, + "99.99" : 0.33808313735632184, + "99.999" : 0.33808313735632184, + "99.9999" : 0.33808313735632184, + "100.0" : 0.33808313735632184 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33651154667205063, + 0.335530231337024, + 0.33808313735632184 + ], + [ + 0.320321544668311, + 0.3199065666986564, + 0.32047205310046467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14497358251569623, + "scoreError" : 0.008356850940807696, + "scoreConfidence" : [ + 0.13661673157488852, + 0.15333043345650393 + ], + "scorePercentiles" : { + "0.0" : 0.14197348209037863, + "50.0" : 0.1449930684363192, + "90.0" : 0.14793544317223628, + "95.0" : 0.14793544317223628, + "99.0" : 0.14793544317223628, + "99.9" : 0.14793544317223628, + "99.99" : 0.14793544317223628, + "99.999" : 0.14793544317223628, + "99.9999" : 0.14793544317223628, + "100.0" : 0.14793544317223628 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14197348209037863, + 0.1422311287299104, + 0.14258538193483994 + ], + [ + 0.14793544317223628, + 0.14771530422901372, + 0.14740075493779847 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.41140711342600295, + "scoreError" : 0.019916798435813315, + "scoreConfidence" : [ + 0.3914903149901896, + 0.4313239118618163 + ], + "scorePercentiles" : { + "0.0" : 0.4047791495992876, + "50.0" : 0.41058531593608677, + "90.0" : 0.4196176641910037, + "95.0" : 0.4196176641910037, + "99.0" : 0.4196176641910037, + "99.9" : 0.4196176641910037, + "99.99" : 0.4196176641910037, + "99.999" : 0.4196176641910037, + "99.9999" : 0.4196176641910037, + "100.0" : 0.4196176641910037 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4051201206400648, + 0.4051212531901965, + 0.4047791495992876 + ], + [ + 0.4196176641910037, + 0.41775511425348816, + 0.41604937868197706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16088846584649133, + "scoreError" : 0.012547586364348488, + "scoreConfidence" : [ + 0.14834087948214283, + 0.17343605221083983 + ], + "scorePercentiles" : { + "0.0" : 0.15652884564934963, + "50.0" : 0.16068996562679355, + "90.0" : 0.16583116544507828, + "95.0" : 0.16583116544507828, + "99.0" : 0.16583116544507828, + "99.9" : 0.16583116544507828, + "99.99" : 0.16583116544507828, + "99.999" : 0.16583116544507828, + "99.9999" : 0.16583116544507828, + "100.0" : 0.16583116544507828 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1572895279258875, + 0.15652884564934963, + 0.1567057351876518 + ], + [ + 0.16583116544507828, + 0.1648851175432811, + 0.16409040332769964 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04837959948905729, + "scoreError" : 0.0037902092083928873, + "scoreConfidence" : [ + 0.0445893902806644, + 0.05216980869745018 + ], + "scorePercentiles" : { + "0.0" : 0.04707020434809212, + "50.0" : 0.04836821901307904, + "90.0" : 0.04966591475952083, + "95.0" : 0.04966591475952083, + "99.0" : 0.04966591475952083, + "99.9" : 0.04966591475952083, + "99.99" : 0.04966591475952083, + "99.999" : 0.04966591475952083, + "99.9999" : 0.04966591475952083, + "100.0" : 0.04966591475952083 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04954455266769388, + 0.04966591475952083, + 0.049626549759811026 + ], + [ + 0.04719188535846421, + 0.04717849004076164, + 0.04707020434809212 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9043415.83336745, + "scoreError" : 434704.9609345177, + "scoreConfidence" : [ + 8608710.872432932, + 9478120.794301968 + ], + "scorePercentiles" : { + "0.0" : 8834682.399293287, + "50.0" : 9060342.61479463, + "90.0" : 9223578.02764977, + "95.0" : 9223578.02764977, + "99.0" : 9223578.02764977, + "99.9" : 9223578.02764977, + "99.99" : 9223578.02764977, + "99.999" : 9223578.02764977, + "99.9999" : 9223578.02764977, + "100.0" : 9223578.02764977 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8989382.492362984, + 8834682.399293287, + 8911410.376669634 + ], + [ + 9223578.02764977, + 9131302.737226278, + 9170138.96700275 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-25T00:33:09Z-378eb2b1ff6cadd27994b2e8fa23fba57c6286ab-jdk17.json b/performance-results/2025-07-25T00:33:09Z-378eb2b1ff6cadd27994b2e8fa23fba57c6286ab-jdk17.json new file mode 100644 index 0000000000..0fcb044cd0 --- /dev/null +++ b/performance-results/2025-07-25T00:33:09Z-378eb2b1ff6cadd27994b2e8fa23fba57c6286ab-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3066775275726714, + "scoreError" : 0.033919743261016475, + "scoreConfidence" : [ + 3.272757784311655, + 3.3405972708336877 + ], + "scorePercentiles" : { + "0.0" : 3.301072458041701, + "50.0" : 3.306422217105671, + "90.0" : 3.3127932180376423, + "95.0" : 3.3127932180376423, + "99.0" : 3.3127932180376423, + "99.9" : 3.3127932180376423, + "99.99" : 3.3127932180376423, + "99.999" : 3.3127932180376423, + "99.9999" : 3.3127932180376423, + "100.0" : 3.3127932180376423 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3038039283157077, + 3.3127932180376423 + ], + [ + 3.301072458041701, + 3.3090405058956347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6814308976912047, + "scoreError" : 0.022089312539861548, + "scoreConfidence" : [ + 1.6593415851513431, + 1.7035202102310663 + ], + "scorePercentiles" : { + "0.0" : 1.6785182901910285, + "50.0" : 1.6807376668985228, + "90.0" : 1.6857299667767454, + "95.0" : 1.6857299667767454, + "99.0" : 1.6857299667767454, + "99.9" : 1.6857299667767454, + "99.99" : 1.6857299667767454, + "99.999" : 1.6857299667767454, + "99.9999" : 1.6857299667767454, + "100.0" : 1.6857299667767454 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6788496992175892, + 1.6785182901910285 + ], + [ + 1.6826256345794561, + 1.6857299667767454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8381848165625602, + "scoreError" : 0.04411699408186375, + "scoreConfidence" : [ + 0.7940678224806964, + 0.8823018106444239 + ], + "scorePercentiles" : { + "0.0" : 0.8299295997776214, + "50.0" : 0.838692253199008, + "90.0" : 0.8454251600746033, + "95.0" : 0.8454251600746033, + "99.0" : 0.8454251600746033, + "99.9" : 0.8454251600746033, + "99.99" : 0.8454251600746033, + "99.999" : 0.8454251600746033, + "99.9999" : 0.8454251600746033, + "100.0" : 0.8454251600746033 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8299295997776214, + 0.8454251600746033 + ], + [ + 0.8356308875372876, + 0.8417536188607282 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.004961566280702, + "scoreError" : 0.1528592055047278, + "scoreConfidence" : [ + 15.852102360775975, + 16.15782077178543 + ], + "scorePercentiles" : { + "0.0" : 15.955488873780125, + "50.0" : 15.988206082006558, + "90.0" : 16.10950939067394, + "95.0" : 16.10950939067394, + "99.0" : 16.10950939067394, + "99.9" : 16.10950939067394, + "99.99" : 16.10950939067394, + "99.999" : 16.10950939067394, + "99.9999" : 16.10950939067394, + "100.0" : 16.10950939067394 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.955488873780125, + 16.10950939067394, + 15.991094934683712 + ], + [ + 15.985317229329404, + 15.975892928959603, + 16.01246604025744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2582.118025703376, + "scoreError" : 188.36873932962732, + "scoreConfidence" : [ + 2393.749286373749, + 2770.4867650330034 + ], + "scorePercentiles" : { + "0.0" : 2519.5276419027423, + "50.0" : 2576.4650052428824, + "90.0" : 2663.3688734556135, + "95.0" : 2663.3688734556135, + "99.0" : 2663.3688734556135, + "99.9" : 2663.3688734556135, + "99.99" : 2663.3688734556135, + "99.999" : 2663.3688734556135, + "99.9999" : 2663.3688734556135, + "100.0" : 2663.3688734556135 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2526.3379058760356, + 2519.5276419027423, + 2519.592969574141 + ], + [ + 2626.592104609729, + 2663.3688734556135, + 2637.2886588019974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75929.43713956332, + "scoreError" : 1795.725219760547, + "scoreConfidence" : [ + 74133.71191980278, + 77725.16235932386 + ], + "scorePercentiles" : { + "0.0" : 75254.86153805364, + "50.0" : 75898.6036985468, + "90.0" : 76573.93021625052, + "95.0" : 76573.93021625052, + "99.0" : 76573.93021625052, + "99.9" : 76573.93021625052, + "99.99" : 76573.93021625052, + "99.999" : 76573.93021625052, + "99.9999" : 76573.93021625052, + "100.0" : 76573.93021625052 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76389.67320304408, + 76573.93021625052, + 76563.3402721159 + ], + [ + 75407.53419404951, + 75387.28341386627, + 75254.86153805364 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 336.6049353290876, + "scoreError" : 16.489521506150968, + "scoreConfidence" : [ + 320.1154138229366, + 353.0944568352386 + ], + "scorePercentiles" : { + "0.0" : 331.32458413008754, + "50.0" : 335.20008333375665, + "90.0" : 347.06334480071985, + "95.0" : 347.06334480071985, + "99.0" : 347.06334480071985, + "99.9" : 347.06334480071985, + "99.99" : 347.06334480071985, + "99.999" : 347.06334480071985, + "99.9999" : 347.06334480071985, + "100.0" : 347.06334480071985 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 332.05922428946457, + 333.42823124036664, + 331.32458413008754 + ], + [ + 336.9719354271467, + 338.78229208674026, + 347.06334480071985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.60582690655242, + "scoreError" : 11.173389818839349, + "scoreConfidence" : [ + 96.43243708771307, + 118.77921672539178 + ], + "scorePercentiles" : { + "0.0" : 102.11801195009656, + "50.0" : 108.69010971957573, + "90.0" : 111.67494993512767, + "95.0" : 111.67494993512767, + "99.0" : 111.67494993512767, + "99.9" : 111.67494993512767, + "99.99" : 111.67494993512767, + "99.999" : 111.67494993512767, + "99.9999" : 111.67494993512767, + "100.0" : 111.67494993512767 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 102.11801195009656, + 103.77459901875596, + 106.93163472430241 + ], + [ + 110.68718109618288, + 110.44858471484906, + 111.67494993512767 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06257742894897945, + "scoreError" : 4.616417683000458E-4, + "scoreConfidence" : [ + 0.06211578718067941, + 0.0630390707172795 + ], + "scorePercentiles" : { + "0.0" : 0.0623212224264935, + "50.0" : 0.0625570274063876, + "90.0" : 0.06276186021991263, + "95.0" : 0.06276186021991263, + "99.0" : 0.06276186021991263, + "99.9" : 0.06276186021991263, + "99.99" : 0.06276186021991263, + "99.999" : 0.06276186021991263, + "99.9999" : 0.06276186021991263, + "100.0" : 0.06276186021991263 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06256933182543407, + 0.0623212224264935, + 0.06275283901655392 + ], + [ + 0.06251459721814147, + 0.06254472298734114, + 0.06276186021991263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.804979073315174E-4, + "scoreError" : 3.1290959030715905E-5, + "scoreConfidence" : [ + 3.492069483008015E-4, + 4.117888663622333E-4 + ], + "scorePercentiles" : { + "0.0" : 3.686052191223459E-4, + "50.0" : 3.805710213074775E-4, + "90.0" : 3.9295602562939327E-4, + "95.0" : 3.9295602562939327E-4, + "99.0" : 3.9295602562939327E-4, + "99.9" : 3.9295602562939327E-4, + "99.99" : 3.9295602562939327E-4, + "99.999" : 3.9295602562939327E-4, + "99.9999" : 3.9295602562939327E-4, + "100.0" : 3.9295602562939327E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7203306319338707E-4, + 3.706584066808534E-4, + 3.686052191223459E-4 + ], + [ + 3.89108979421568E-4, + 3.8962574994155693E-4, + 3.9295602562939327E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12677889442068035, + "scoreError" : 0.008951730346661569, + "scoreConfidence" : [ + 0.11782716407401879, + 0.13573062476734193 + ], + "scorePercentiles" : { + "0.0" : 0.12342886066403357, + "50.0" : 0.12693422320553238, + "90.0" : 0.12988056201052017, + "95.0" : 0.12988056201052017, + "99.0" : 0.12988056201052017, + "99.9" : 0.12988056201052017, + "99.99" : 0.12988056201052017, + "99.999" : 0.12988056201052017, + "99.9999" : 0.12988056201052017, + "100.0" : 0.12988056201052017 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12956015696943785, + 0.12988056201052017, + 0.12959982908685622 + ], + [ + 0.12430828944162689, + 0.12389566835160751, + 0.12342886066403357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013185124640204576, + "scoreError" : 9.870438880579569E-5, + "scoreConfidence" : [ + 0.01308642025139878, + 0.013283829029010373 + ], + "scorePercentiles" : { + "0.0" : 0.013149310564282202, + "50.0" : 0.01317385008032829, + "90.0" : 0.013235472953066414, + "95.0" : 0.013235472953066414, + "99.0" : 0.013235472953066414, + "99.9" : 0.013235472953066414, + "99.99" : 0.013235472953066414, + "99.999" : 0.013235472953066414, + "99.9999" : 0.013235472953066414, + "100.0" : 0.013235472953066414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013149310564282202, + 0.013156921266151537, + 0.013176660858920927 + ], + [ + 0.013171039301735651, + 0.013221342897070722, + 0.013235472953066414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0354221684983729, + "scoreError" : 0.027954869197301387, + "scoreConfidence" : [ + 1.0074672993010716, + 1.0633770376956742 + ], + "scorePercentiles" : { + "0.0" : 1.025096790692907, + "50.0" : 1.034103071230585, + "90.0" : 1.047773467993714, + "95.0" : 1.047773467993714, + "99.0" : 1.047773467993714, + "99.9" : 1.047773467993714, + "99.99" : 1.047773467993714, + "99.999" : 1.047773467993714, + "99.9999" : 1.047773467993714, + "100.0" : 1.047773467993714 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.047773467993714, + 1.0442930651629072, + 1.0407120288271412 + ], + [ + 1.025096790692907, + 1.0271635446795397, + 1.0274941136340285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01068772594921502, + "scoreError" : 1.462473792761726E-4, + "scoreConfidence" : [ + 0.010541478569938846, + 0.010833973328491193 + ], + "scorePercentiles" : { + "0.0" : 0.010607628229144347, + "50.0" : 0.01068450706691373, + "90.0" : 0.01077134530715823, + "95.0" : 0.01077134530715823, + "99.0" : 0.01077134530715823, + "99.9" : 0.01077134530715823, + "99.99" : 0.01077134530715823, + "99.999" : 0.01077134530715823, + "99.9999" : 0.01077134530715823, + "100.0" : 0.01077134530715823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010607628229144347, + 0.010680124086609009, + 0.01068332102292151 + ], + [ + 0.01068569311090595, + 0.010698243938551072, + 0.01077134530715823 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.279232238968176, + "scoreError" : 0.12999334086418882, + "scoreConfidence" : [ + 3.149238898103987, + 3.4092255798323645 + ], + "scorePercentiles" : { + "0.0" : 3.228267479018722, + "50.0" : 3.278079688598224, + "90.0" : 3.338102288192128, + "95.0" : 3.338102288192128, + "99.0" : 3.338102288192128, + "99.9" : 3.338102288192128, + "99.99" : 3.338102288192128, + "99.999" : 3.338102288192128, + "99.9999" : 3.338102288192128, + "100.0" : 3.338102288192128 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.252843413524057, + 3.235263989003881, + 3.228267479018722 + ], + [ + 3.303315963672391, + 3.338102288192128, + 3.317600300397878 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.942751566759662, + "scoreError" : 0.033475477865511326, + "scoreConfidence" : [ + 2.909276088894151, + 2.9762270446251735 + ], + "scorePercentiles" : { + "0.0" : 2.9285283704245972, + "50.0" : 2.9419997167171643, + "90.0" : 2.95762009668835, + "95.0" : 2.95762009668835, + "99.0" : 2.95762009668835, + "99.9" : 2.95762009668835, + "99.99" : 2.95762009668835, + "99.999" : 2.95762009668835, + "99.9999" : 2.95762009668835, + "100.0" : 2.95762009668835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9285283704245972, + 2.95762009668835, + 2.9320072486074467 + ], + [ + 2.9463571843888072, + 2.9543542514032497, + 2.9376422490455214 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1780843687883823, + "scoreError" : 0.00337053557336736, + "scoreConfidence" : [ + 0.17471383321501494, + 0.18145490436174966 + ], + "scorePercentiles" : { + "0.0" : 0.17633287293694455, + "50.0" : 0.17868748060792106, + "90.0" : 0.17911248701461527, + "95.0" : 0.17911248701461527, + "99.0" : 0.17911248701461527, + "99.9" : 0.17911248701461527, + "99.99" : 0.17911248701461527, + "99.999" : 0.17911248701461527, + "99.9999" : 0.17911248701461527, + "100.0" : 0.17911248701461527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17858500491097737, + 0.1767861157211802, + 0.17633287293694455 + ], + [ + 0.17889977584171168, + 0.17878995630486474, + 0.17911248701461527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3334283231280681, + "scoreError" : 0.018617853315637842, + "scoreConfidence" : [ + 0.3148104698124302, + 0.35204617644370595 + ], + "scorePercentiles" : { + "0.0" : 0.32690004857637867, + "50.0" : 0.33342136438463, + "90.0" : 0.33975365040429434, + "95.0" : 0.33975365040429434, + "99.0" : 0.33975365040429434, + "99.9" : 0.33975365040429434, + "99.99" : 0.33975365040429434, + "99.999" : 0.33975365040429434, + "99.9999" : 0.33975365040429434, + "100.0" : 0.33975365040429434 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32787988878688523, + 0.32690004857637867, + 0.3273588003142595 + ], + [ + 0.3389628399823747, + 0.33971471070421577, + 0.33975365040429434 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14758968251906296, + "scoreError" : 0.003533857499484376, + "scoreConfidence" : [ + 0.1440558250195786, + 0.15112354001854733 + ], + "scorePercentiles" : { + "0.0" : 0.14604092429685447, + "50.0" : 0.14751047342677978, + "90.0" : 0.14905529530041287, + "95.0" : 0.14905529530041287, + "99.0" : 0.14905529530041287, + "99.9" : 0.14905529530041287, + "99.99" : 0.14905529530041287, + "99.999" : 0.14905529530041287, + "99.9999" : 0.14905529530041287, + "100.0" : 0.14905529530041287 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14905529530041287, + 0.1482887649099914, + 0.14874505205931787 + ], + [ + 0.14673218194356816, + 0.14667587660423298, + 0.14604092429685447 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4102380454104919, + "scoreError" : 0.01905155753606237, + "scoreConfidence" : [ + 0.39118648787442956, + 0.42928960294655427 + ], + "scorePercentiles" : { + "0.0" : 0.40432925112198276, + "50.0" : 0.40806549427284267, + "90.0" : 0.4200787366210199, + "95.0" : 0.4200787366210199, + "99.0" : 0.4200787366210199, + "99.9" : 0.4200787366210199, + "99.99" : 0.4200787366210199, + "99.999" : 0.4200787366210199, + "99.9999" : 0.4200787366210199, + "100.0" : 0.4200787366210199 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40432925112198276, + 0.40499237293969953, + 0.4045022773126239 + ], + [ + 0.4200787366210199, + 0.41638701886163965, + 0.41113861560598586 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15779309849350384, + "scoreError" : 0.004036259275626001, + "scoreConfidence" : [ + 0.15375683921787783, + 0.16182935776912985 + ], + "scorePercentiles" : { + "0.0" : 0.156635180784412, + "50.0" : 0.15725132103513056, + "90.0" : 0.16036106122416255, + "95.0" : 0.16036106122416255, + "99.0" : 0.16036106122416255, + "99.9" : 0.16036106122416255, + "99.99" : 0.16036106122416255, + "99.999" : 0.16036106122416255, + "99.9999" : 0.16036106122416255, + "100.0" : 0.16036106122416255 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.156635180784412, + 0.15675691365959182, + 0.1568912394728585 + ], + [ + 0.16036106122416255, + 0.15850279322259558, + 0.1576114025974026 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046463276420450415, + "scoreError" : 0.0018381035938579088, + "scoreConfidence" : [ + 0.04462517282659251, + 0.04830138001430832 + ], + "scorePercentiles" : { + "0.0" : 0.04589555564530564, + "50.0" : 0.04632686305658129, + "90.0" : 0.047575926943680596, + "95.0" : 0.047575926943680596, + "99.0" : 0.047575926943680596, + "99.9" : 0.047575926943680596, + "99.99" : 0.047575926943680596, + "99.999" : 0.047575926943680596, + "99.9999" : 0.047575926943680596, + "100.0" : 0.047575926943680596 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04594306312941047, + 0.04589555564530564, + 0.04599624998045195 + ], + [ + 0.047575926943680596, + 0.04671138669114316, + 0.046657476132710624 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9459466.352530636, + "scoreError" : 635263.0245088574, + "scoreConfidence" : [ + 8824203.328021778, + 1.0094729377039494E7 + ], + "scorePercentiles" : { + "0.0" : 9219518.085714286, + "50.0" : 9453558.55638749, + "90.0" : 9734180.823929962, + "95.0" : 9734180.823929962, + "99.0" : 9734180.823929962, + "99.9" : 9734180.823929962, + "99.99" : 9734180.823929962, + "99.999" : 9734180.823929962, + "99.9999" : 9734180.823929962, + "100.0" : 9734180.823929962 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9219518.085714286, + 9287835.073351903, + 9263195.210185185 + ], + [ + 9632786.882579403, + 9619282.039423076, + 9734180.823929962 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-27T09:24:22Z-b09381df9d22c7e0cf40fbec37c0c31777cd1f1c-jdk17.json b/performance-results/2025-07-27T09:24:22Z-b09381df9d22c7e0cf40fbec37c0c31777cd1f1c-jdk17.json new file mode 100644 index 0000000000..2bfb72f2d0 --- /dev/null +++ b/performance-results/2025-07-27T09:24:22Z-b09381df9d22c7e0cf40fbec37c0c31777cd1f1c-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3480527247230194, + "scoreError" : 0.012743480511871318, + "scoreConfidence" : [ + 3.3353092442111483, + 3.3607962052348905 + ], + "scorePercentiles" : { + "0.0" : 3.3455154146994603, + "50.0" : 3.3483735517415854, + "90.0" : 3.349948380709445, + "95.0" : 3.349948380709445, + "99.0" : 3.349948380709445, + "99.9" : 3.349948380709445, + "99.99" : 3.349948380709445, + "99.999" : 3.349948380709445, + "99.9999" : 3.349948380709445, + "100.0" : 3.349948380709445 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3455154146994603, + 3.3492190810125106 + ], + [ + 3.3475280224706605, + 3.349948380709445 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6899168268853022, + "scoreError" : 0.07319984246382837, + "scoreConfidence" : [ + 1.616716984421474, + 1.7631166693491305 + ], + "scorePercentiles" : { + "0.0" : 1.6758231560635783, + "50.0" : 1.692186231166425, + "90.0" : 1.6994716891447805, + "95.0" : 1.6994716891447805, + "99.0" : 1.6994716891447805, + "99.9" : 1.6994716891447805, + "99.99" : 1.6994716891447805, + "99.999" : 1.6994716891447805, + "99.9999" : 1.6994716891447805, + "100.0" : 1.6994716891447805 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.698694951104173, + 1.6994716891447805 + ], + [ + 1.6758231560635783, + 1.6856775112286773 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8496055007675353, + "scoreError" : 0.024271144244446485, + "scoreConfidence" : [ + 0.8253343565230888, + 0.8738766450119817 + ], + "scorePercentiles" : { + "0.0" : 0.8460206409848652, + "50.0" : 0.8487520857991151, + "90.0" : 0.8548971904870462, + "95.0" : 0.8548971904870462, + "99.0" : 0.8548971904870462, + "99.9" : 0.8548971904870462, + "99.99" : 0.8548971904870462, + "99.999" : 0.8548971904870462, + "99.9999" : 0.8548971904870462, + "100.0" : 0.8548971904870462 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8486731288187406, + 0.8548971904870462 + ], + [ + 0.8460206409848652, + 0.8488310427794895 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.375572927204825, + "scoreError" : 0.32121140463545256, + "scoreConfidence" : [ + 16.054361522569373, + 16.696784331840277 + ], + "scorePercentiles" : { + "0.0" : 16.223867171282226, + "50.0" : 16.385003305280673, + "90.0" : 16.48545098231728, + "95.0" : 16.48545098231728, + "99.0" : 16.48545098231728, + "99.9" : 16.48545098231728, + "99.99" : 16.48545098231728, + "99.999" : 16.48545098231728, + "99.9999" : 16.48545098231728, + "100.0" : 16.48545098231728 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.303640931884864, + 16.223867171282226, + 16.29530655026829 + ], + [ + 16.466365678676482, + 16.47880624879981, + 16.48545098231728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2752.0578556027504, + "scoreError" : 123.19634072686533, + "scoreConfidence" : [ + 2628.861514875885, + 2875.2541963296158 + ], + "scorePercentiles" : { + "0.0" : 2710.2566488690954, + "50.0" : 2752.0432644794128, + "90.0" : 2792.8334573625502, + "95.0" : 2792.8334573625502, + "99.0" : 2792.8334573625502, + "99.9" : 2792.8334573625502, + "99.99" : 2792.8334573625502, + "99.999" : 2792.8334573625502, + "99.9999" : 2792.8334573625502, + "100.0" : 2792.8334573625502 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2712.841558289169, + 2710.2566488690954, + 2712.7954990856365 + ], + [ + 2792.3749993403962, + 2792.8334573625502, + 2791.244970669656 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75688.79805559274, + "scoreError" : 6403.278749229374, + "scoreConfidence" : [ + 69285.51930636336, + 82092.0768048221 + ], + "scorePercentiles" : { + "0.0" : 73588.24872656632, + "50.0" : 75665.19656631522, + "90.0" : 77812.64230236896, + "95.0" : 77812.64230236896, + "99.0" : 77812.64230236896, + "99.9" : 77812.64230236896, + "99.99" : 77812.64230236896, + "99.999" : 77812.64230236896, + "99.9999" : 77812.64230236896, + "100.0" : 77812.64230236896 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77700.82911163302, + 77812.64230236896, + 77805.41060635136 + ], + [ + 73588.24872656632, + 73629.56402099741, + 73596.09356563933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 365.8627288594442, + "scoreError" : 10.42048602500302, + "scoreConfidence" : [ + 355.4422428344412, + 376.2832148844472 + ], + "scorePercentiles" : { + "0.0" : 362.15098246615713, + "50.0" : 365.84617795527276, + "90.0" : 369.81297960361985, + "95.0" : 369.81297960361985, + "99.0" : 369.81297960361985, + "99.9" : 369.81297960361985, + "99.99" : 369.81297960361985, + "99.999" : 369.81297960361985, + "99.9999" : 369.81297960361985, + "100.0" : 369.81297960361985 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 368.7153027027884, + 369.16429250997413, + 369.81297960361985 + ], + [ + 362.15098246615713, + 362.3557626663687, + 362.9770532077572 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.74427882855461, + "scoreError" : 1.9491424437607001, + "scoreConfidence" : [ + 111.7951363847939, + 115.69342127231532 + ], + "scorePercentiles" : { + "0.0" : 112.58434260275494, + "50.0" : 113.79067030125663, + "90.0" : 114.69661771144031, + "95.0" : 114.69661771144031, + "99.0" : 114.69661771144031, + "99.9" : 114.69661771144031, + "99.99" : 114.69661771144031, + "99.999" : 114.69661771144031, + "99.9999" : 114.69661771144031, + "100.0" : 114.69661771144031 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.07493084756696, + 113.52844120705214, + 114.69661771144031 + ], + [ + 112.58434260275494, + 113.82990878972608, + 113.75143181278719 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06162743718018923, + "scoreError" : 3.591914278173167E-4, + "scoreConfidence" : [ + 0.061268245752371914, + 0.06198662860800655 + ], + "scorePercentiles" : { + "0.0" : 0.061477613267922025, + "50.0" : 0.06161646286462216, + "90.0" : 0.06180226438578818, + "95.0" : 0.06180226438578818, + "99.0" : 0.06180226438578818, + "99.9" : 0.06180226438578818, + "99.99" : 0.06180226438578818, + "99.999" : 0.06180226438578818, + "99.9999" : 0.06180226438578818, + "100.0" : 0.06180226438578818 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06180226438578818, + 0.061477613267922025, + 0.0616938086468879 + ], + [ + 0.06153911708235642, + 0.06171760130468861, + 0.061534218393492254 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.707365752780934E-4, + "scoreError" : 1.3112036792635523E-5, + "scoreConfidence" : [ + 3.5762453848545785E-4, + 3.838486120707289E-4 + ], + "scorePercentiles" : { + "0.0" : 3.661568925578196E-4, + "50.0" : 3.7081394770288687E-4, + "90.0" : 3.7513296348639264E-4, + "95.0" : 3.7513296348639264E-4, + "99.0" : 3.7513296348639264E-4, + "99.9" : 3.7513296348639264E-4, + "99.99" : 3.7513296348639264E-4, + "99.999" : 3.7513296348639264E-4, + "99.9999" : 3.7513296348639264E-4, + "100.0" : 3.7513296348639264E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.747989706723821E-4, + 3.750661881631323E-4, + 3.7513296348639264E-4 + ], + [ + 3.668289247333916E-4, + 3.661568925578196E-4, + 3.664355120554419E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12515975337827603, + "scoreError" : 0.0018819369363948916, + "scoreConfidence" : [ + 0.12327781644188114, + 0.1270416903146709 + ], + "scorePercentiles" : { + "0.0" : 0.12451498170906329, + "50.0" : 0.125113702460143, + "90.0" : 0.12585044662161313, + "95.0" : 0.12585044662161313, + "99.0" : 0.12585044662161313, + "99.9" : 0.12585044662161313, + "99.99" : 0.12585044662161313, + "99.999" : 0.12585044662161313, + "99.9999" : 0.12585044662161313, + "100.0" : 0.12585044662161313 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12461622089024026, + 0.12452751233422577, + 0.12451498170906329 + ], + [ + 0.12583817468446815, + 0.12585044662161313, + 0.12561118403004573 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01298828611601984, + "scoreError" : 2.2829858274778095E-4, + "scoreConfidence" : [ + 0.012759987533272059, + 0.01321658469876762 + ], + "scorePercentiles" : { + "0.0" : 0.012909820407557303, + "50.0" : 0.012986902508766352, + "90.0" : 0.013068841367296184, + "95.0" : 0.013068841367296184, + "99.0" : 0.013068841367296184, + "99.9" : 0.013068841367296184, + "99.99" : 0.013068841367296184, + "99.999" : 0.013068841367296184, + "99.9999" : 0.013068841367296184, + "100.0" : 0.013068841367296184 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013068841367296184, + 0.013054219633024649, + 0.013064214315854932 + ], + [ + 0.012919585384508055, + 0.012913035587877911, + 0.012909820407557303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9570497101032437, + "scoreError" : 0.06870793812974671, + "scoreConfidence" : [ + 0.888341771973497, + 1.0257576482329904 + ], + "scorePercentiles" : { + "0.0" : 0.9341369757145526, + "50.0" : 0.9572804363022998, + "90.0" : 0.9797242170846395, + "95.0" : 0.9797242170846395, + "99.0" : 0.9797242170846395, + "99.9" : 0.9797242170846395, + "99.99" : 0.9797242170846395, + "99.999" : 0.9797242170846395, + "99.9999" : 0.9797242170846395, + "100.0" : 0.9797242170846395 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9341369757145526, + 0.9346130296261682, + 0.935307234006734 + ], + [ + 0.9792631655895025, + 0.9797242170846395, + 0.9792536385978655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010662369221472366, + "scoreError" : 3.6261902408499366E-4, + "scoreConfidence" : [ + 0.010299750197387372, + 0.01102498824555736 + ], + "scorePercentiles" : { + "0.0" : 0.010541451729808362, + "50.0" : 0.01066228605668934, + "90.0" : 0.010782180810757776, + "95.0" : 0.010782180810757776, + "99.0" : 0.010782180810757776, + "99.9" : 0.010782180810757776, + "99.99" : 0.010782180810757776, + "99.999" : 0.010782180810757776, + "99.9999" : 0.010782180810757776, + "100.0" : 0.010782180810757776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010780964613447408, + 0.010778053849453465, + 0.010782180810757776 + ], + [ + 0.010545046061441968, + 0.010546518263925215, + 0.010541451729808362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.088338168746136, + "scoreError" : 0.0692484451009362, + "scoreConfidence" : [ + 3.0190897236452, + 3.157586613847072 + ], + "scorePercentiles" : { + "0.0" : 3.060924018971848, + "50.0" : 3.092390426173913, + "90.0" : 3.1151917391033623, + "95.0" : 3.1151917391033623, + "99.0" : 3.1151917391033623, + "99.9" : 3.1151917391033623, + "99.99" : 3.1151917391033623, + "99.999" : 3.1151917391033623, + "99.9999" : 3.1151917391033623, + "100.0" : 3.1151917391033623 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1151917391033623, + 3.1066782043478263, + 3.1080917582349286 + ], + [ + 3.0610406438188495, + 3.078102648, + 3.060924018971848 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7125927608610696, + "scoreError" : 0.12439364757781035, + "scoreConfidence" : [ + 2.588199113283259, + 2.83698640843888 + ], + "scorePercentiles" : { + "0.0" : 2.6691942740859353, + "50.0" : 2.71111360511988, + "90.0" : 2.7617167856945595, + "95.0" : 2.7617167856945595, + "99.0" : 2.7617167856945595, + "99.9" : 2.7617167856945595, + "99.99" : 2.7617167856945595, + "99.999" : 2.7617167856945595, + "99.9999" : 2.7617167856945595, + "100.0" : 2.7617167856945595 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6741723772727273, + 2.6737596859128576, + 2.6691942740859353 + ], + [ + 2.7617167856945595, + 2.748054832967033, + 2.748658609233306 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17593930609518574, + "scoreError" : 0.012829140597269412, + "scoreConfidence" : [ + 0.16311016549791632, + 0.18876844669245516 + ], + "scorePercentiles" : { + "0.0" : 0.17177691756703367, + "50.0" : 0.1754336300504918, + "90.0" : 0.18198033134371816, + "95.0" : 0.18198033134371816, + "99.0" : 0.18198033134371816, + "99.9" : 0.18198033134371816, + "99.99" : 0.18198033134371816, + "99.999" : 0.18198033134371816, + "99.9999" : 0.18198033134371816, + "100.0" : 0.18198033134371816 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18198033134371816, + 0.17908566701885711, + 0.17892025329206326 + ], + [ + 0.17194700680892036, + 0.17177691756703367, + 0.17192566054052194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3285984612365002, + "scoreError" : 0.010586300929319519, + "scoreConfidence" : [ + 0.3180121603071807, + 0.3391847621658197 + ], + "scorePercentiles" : { + "0.0" : 0.32475763852174194, + "50.0" : 0.32874220721812786, + "90.0" : 0.33208890107262645, + "95.0" : 0.33208890107262645, + "99.0" : 0.33208890107262645, + "99.9" : 0.33208890107262645, + "99.99" : 0.33208890107262645, + "99.999" : 0.33208890107262645, + "99.9999" : 0.33208890107262645, + "100.0" : 0.33208890107262645 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33208890107262645, + 0.3320516788192715, + 0.3319720958372062 + ], + [ + 0.32551231859904955, + 0.3252081345691057, + 0.32475763852174194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14286089464430035, + "scoreError" : 0.001063750751637408, + "scoreConfidence" : [ + 0.14179714389266293, + 0.14392464539593777 + ], + "scorePercentiles" : { + "0.0" : 0.14241141853576567, + "50.0" : 0.1429526327523724, + "90.0" : 0.14326526219879088, + "95.0" : 0.14326526219879088, + "99.0" : 0.14326526219879088, + "99.9" : 0.14326526219879088, + "99.99" : 0.14326526219879088, + "99.999" : 0.14326526219879088, + "99.9999" : 0.14326526219879088, + "100.0" : 0.14326526219879088 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14326526219879088, + 0.14314880849997852, + 0.14314305923190335 + ], + [ + 0.14276220627284147, + 0.14243461312652225, + 0.14241141853576567 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40193088818342976, + "scoreError" : 0.005279078413821035, + "scoreConfidence" : [ + 0.39665180976960873, + 0.4072099665972508 + ], + "scorePercentiles" : { + "0.0" : 0.3989974169326524, + "50.0" : 0.40267258137708883, + "90.0" : 0.40403318698234414, + "95.0" : 0.40403318698234414, + "99.0" : 0.40403318698234414, + "99.9" : 0.40403318698234414, + "99.99" : 0.40403318698234414, + "99.999" : 0.40403318698234414, + "99.9999" : 0.40403318698234414, + "100.0" : 0.40403318698234414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40403318698234414, + 0.400304297454167, + 0.3989974169326524 + ], + [ + 0.4026699213609825, + 0.4026752413931951, + 0.402905264977237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15779688562509273, + "scoreError" : 0.007626460758325325, + "scoreConfidence" : [ + 0.1501704248667674, + 0.16542334638341805 + ], + "scorePercentiles" : { + "0.0" : 0.155282176878882, + "50.0" : 0.15775205581729318, + "90.0" : 0.16046199895701288, + "95.0" : 0.16046199895701288, + "99.0" : 0.16046199895701288, + "99.9" : 0.16046199895701288, + "99.99" : 0.16046199895701288, + "99.999" : 0.16046199895701288, + "99.9999" : 0.16046199895701288, + "100.0" : 0.16046199895701288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.155282176878882, + 0.1553703675714308, + 0.1552961208497686 + ], + [ + 0.16013374406315553, + 0.16046199895701288, + 0.16023690543030653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04733881393774781, + "scoreError" : 1.6565757249014737E-4, + "scoreConfidence" : [ + 0.047173156365257665, + 0.047504471510237956 + ], + "scorePercentiles" : { + "0.0" : 0.04728205182978724, + "50.0" : 0.047333661675769204, + "90.0" : 0.0474455739499267, + "95.0" : 0.0474455739499267, + "99.0" : 0.0474455739499267, + "99.9" : 0.0474455739499267, + "99.99" : 0.0474455739499267, + "99.999" : 0.0474455739499267, + "99.9999" : 0.0474455739499267, + "100.0" : 0.0474455739499267 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04735047274543784, + 0.047335008023174904, + 0.04733231532836351 + ], + [ + 0.04728205182978724, + 0.047287461749796665, + 0.0474455739499267 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8692433.674385035, + "scoreError" : 67675.5941264889, + "scoreConfidence" : [ + 8624758.080258546, + 8760109.268511524 + ], + "scorePercentiles" : { + "0.0" : 8656142.101211073, + "50.0" : 8697235.26347826, + "90.0" : 8717519.744773518, + "95.0" : 8717519.744773518, + "99.0" : 8717519.744773518, + "99.9" : 8717519.744773518, + "99.99" : 8717519.744773518, + "99.999" : 8717519.744773518, + "99.9999" : 8717519.744773518, + "100.0" : 8717519.744773518 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8714644.011324042, + 8717519.744773518, + 8696311.950434783 + ], + [ + 8698158.57652174, + 8656142.101211073, + 8671825.662045062 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-27T23:52:34Z-72fb3d09a570c0bd653b66257fcfac5a8cb603c2-jdk17.json b/performance-results/2025-07-27T23:52:34Z-72fb3d09a570c0bd653b66257fcfac5a8cb603c2-jdk17.json new file mode 100644 index 0000000000..08183a5cd3 --- /dev/null +++ b/performance-results/2025-07-27T23:52:34Z-72fb3d09a570c0bd653b66257fcfac5a8cb603c2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3381787744528983, + "scoreError" : 0.052908944469568946, + "scoreConfidence" : [ + 3.2852698299833296, + 3.391087718922467 + ], + "scorePercentiles" : { + "0.0" : 3.3273248563057742, + "50.0" : 3.339745418065334, + "90.0" : 3.345899405375152, + "95.0" : 3.345899405375152, + "99.0" : 3.345899405375152, + "99.9" : 3.345899405375152, + "99.99" : 3.345899405375152, + "99.999" : 3.345899405375152, + "99.9999" : 3.345899405375152, + "100.0" : 3.345899405375152 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3366801497940215, + 3.345899405375152 + ], + [ + 3.3273248563057742, + 3.342810686336647 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.684586894404262, + "scoreError" : 0.053426960880809275, + "scoreConfidence" : [ + 1.6311599335234526, + 1.7380138552850712 + ], + "scorePercentiles" : { + "0.0" : 1.6756625743866254, + "50.0" : 1.6843055253887116, + "90.0" : 1.6940739524529989, + "95.0" : 1.6940739524529989, + "99.0" : 1.6940739524529989, + "99.9" : 1.6940739524529989, + "99.99" : 1.6940739524529989, + "99.999" : 1.6940739524529989, + "99.9999" : 1.6940739524529989, + "100.0" : 1.6940739524529989 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6885047806877211, + 1.6940739524529989 + ], + [ + 1.6756625743866254, + 1.680106270089702 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8487724778959634, + "scoreError" : 0.010759981800526824, + "scoreConfidence" : [ + 0.8380124960954366, + 0.8595324596964903 + ], + "scorePercentiles" : { + "0.0" : 0.8468391144089067, + "50.0" : 0.8486759279560974, + "90.0" : 0.8508989412627525, + "95.0" : 0.8508989412627525, + "99.0" : 0.8508989412627525, + "99.9" : 0.8508989412627525, + "99.99" : 0.8508989412627525, + "99.999" : 0.8508989412627525, + "99.9999" : 0.8508989412627525, + "100.0" : 0.8508989412627525 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8468391144089067, + 0.8488164274018315 + ], + [ + 0.8485354285103631, + 0.8508989412627525 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.30642368772897, + "scoreError" : 0.0764152475644141, + "scoreConfidence" : [ + 16.230008440164557, + 16.382838935293382 + ], + "scorePercentiles" : { + "0.0" : 16.26766054704475, + "50.0" : 16.313080658309325, + "90.0" : 16.33602976449483, + "95.0" : 16.33602976449483, + "99.0" : 16.33602976449483, + "99.9" : 16.33602976449483, + "99.99" : 16.33602976449483, + "99.999" : 16.33602976449483, + "99.9999" : 16.33602976449483, + "100.0" : 16.33602976449483 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.323152150890056, + 16.30300916572859, + 16.33602976449483 + ], + [ + 16.32707940886456, + 16.26766054704475, + 16.281611089351014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2667.4873988008935, + "scoreError" : 217.89883159883343, + "scoreConfidence" : [ + 2449.58856720206, + 2885.386230399727 + ], + "scorePercentiles" : { + "0.0" : 2594.679516462749, + "50.0" : 2667.548815857057, + "90.0" : 2741.5360445700167, + "95.0" : 2741.5360445700167, + "99.0" : 2741.5360445700167, + "99.9" : 2741.5360445700167, + "99.99" : 2741.5360445700167, + "99.999" : 2741.5360445700167, + "99.9999" : 2741.5360445700167, + "100.0" : 2741.5360445700167 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2594.679516462749, + 2595.014748203577, + 2600.1054418880676 + ], + [ + 2741.5360445700167, + 2734.992189826047, + 2738.5964518549044 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75876.55191802412, + "scoreError" : 1318.6896735964767, + "scoreConfidence" : [ + 74557.86224442764, + 77195.24159162061 + ], + "scorePercentiles" : { + "0.0" : 75433.44483697362, + "50.0" : 75868.92013544834, + "90.0" : 76341.06389809935, + "95.0" : 76341.06389809935, + "99.0" : 76341.06389809935, + "99.9" : 76341.06389809935, + "99.99" : 76341.06389809935, + "99.999" : 76341.06389809935, + "99.9999" : 76341.06389809935, + "100.0" : 76341.06389809935 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75442.0607811654, + 75468.16307212332, + 75433.44483697362 + ], + [ + 76269.67719877334, + 76304.90172100966, + 76341.06389809935 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.23399785959253, + "scoreError" : 12.615174785571135, + "scoreConfidence" : [ + 348.6188230740214, + 373.84917264516366 + ], + "scorePercentiles" : { + "0.0" : 356.41651299599584, + "50.0" : 361.15588964219916, + "90.0" : 366.1894802917049, + "95.0" : 366.1894802917049, + "99.0" : 366.1894802917049, + "99.9" : 366.1894802917049, + "99.99" : 366.1894802917049, + "99.999" : 366.1894802917049, + "99.9999" : 366.1894802917049, + "100.0" : 366.1894802917049 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 364.99490730833463, + 366.1894802917049, + 364.70989061673146 + ], + [ + 357.60188866766686, + 357.4913072771214, + 356.41651299599584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.52427543965842, + "scoreError" : 5.10604691303488, + "scoreConfidence" : [ + 110.41822852662355, + 120.6303223526933 + ], + "scorePercentiles" : { + "0.0" : 113.53031875737602, + "50.0" : 115.54220750898128, + "90.0" : 117.35603432208174, + "95.0" : 117.35603432208174, + "99.0" : 117.35603432208174, + "99.9" : 117.35603432208174, + "99.99" : 117.35603432208174, + "99.999" : 117.35603432208174, + "99.9999" : 117.35603432208174, + "100.0" : 117.35603432208174 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.35603432208174, + 116.92626534996757, + 117.23162852130869 + ], + [ + 114.15814966799498, + 113.9432560192216, + 113.53031875737602 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061462049003638615, + "scoreError" : 9.829962077341746E-4, + "scoreConfidence" : [ + 0.06047905279590444, + 0.06244504521137279 + ], + "scorePercentiles" : { + "0.0" : 0.061129893672557445, + "50.0" : 0.06139802352929069, + "90.0" : 0.06188336952418671, + "95.0" : 0.06188336952418671, + "99.0" : 0.06188336952418671, + "99.9" : 0.06188336952418671, + "99.99" : 0.06188336952418671, + "99.999" : 0.06188336952418671, + "99.9999" : 0.06188336952418671, + "100.0" : 0.06188336952418671 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06118066556135403, + 0.061147478030108476, + 0.061129893672557445 + ], + [ + 0.06181550573639769, + 0.06161538149722735, + 0.06188336952418671 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6742406229967224E-4, + "scoreError" : 3.252810535800362E-5, + "scoreConfidence" : [ + 3.3489595694166863E-4, + 3.9995216765767585E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5652459844805456E-4, + "50.0" : 3.6744417209059305E-4, + "90.0" : 3.7819231221456487E-4, + "95.0" : 3.7819231221456487E-4, + "99.0" : 3.7819231221456487E-4, + "99.9" : 3.7819231221456487E-4, + "99.99" : 3.7819231221456487E-4, + "99.999" : 3.7819231221456487E-4, + "99.9999" : 3.7819231221456487E-4, + "100.0" : 3.7819231221456487E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5702991159574125E-4, + 3.5652459844805456E-4, + 3.5695507345340216E-4 + ], + [ + 3.7798404550082554E-4, + 3.7785843258544485E-4, + 3.7819231221456487E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1244396962610237, + "scoreError" : 0.003998894076406452, + "scoreConfidence" : [ + 0.12044080218461725, + 0.12843859033743016 + ], + "scorePercentiles" : { + "0.0" : 0.1231189042893726, + "50.0" : 0.12431504513525693, + "90.0" : 0.12608096121841747, + "95.0" : 0.12608096121841747, + "99.0" : 0.12608096121841747, + "99.9" : 0.12608096121841747, + "99.99" : 0.12608096121841747, + "99.999" : 0.12608096121841747, + "99.9999" : 0.12608096121841747, + "100.0" : 0.12608096121841747 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1231727407284238, + 0.12316184676585054, + 0.1231189042893726 + ], + [ + 0.12608096121841747, + 0.1256463750219877, + 0.12545734954209006 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013228661642077283, + "scoreError" : 2.1192761188391186E-4, + "scoreConfidence" : [ + 0.01301673403019337, + 0.013440589253961195 + ], + "scorePercentiles" : { + "0.0" : 0.013141296478179167, + "50.0" : 0.013232700958132924, + "90.0" : 0.01329895060170304, + "95.0" : 0.01329895060170304, + "99.0" : 0.01329895060170304, + "99.9" : 0.01329895060170304, + "99.99" : 0.01329895060170304, + "99.999" : 0.01329895060170304, + "99.9999" : 0.01329895060170304, + "100.0" : 0.01329895060170304 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01329895060170304, + 0.013298824676145045, + 0.013293067834753897 + ], + [ + 0.013167496180170596, + 0.013172334081511953, + 0.013141296478179167 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0042422484438465, + "scoreError" : 0.060493074322720886, + "scoreConfidence" : [ + 0.9437491741211256, + 1.0647353227665675 + ], + "scorePercentiles" : { + "0.0" : 0.983829284800787, + "50.0" : 1.0044252953689092, + "90.0" : 1.024237226136829, + "95.0" : 1.024237226136829, + "99.0" : 1.024237226136829, + "99.9" : 1.024237226136829, + "99.99" : 1.024237226136829, + "99.999" : 1.024237226136829, + "99.9999" : 1.024237226136829, + "100.0" : 1.024237226136829 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.983829284800787, + 0.9846654595313116, + 0.9851671281520883 + ], + [ + 1.0236834625857303, + 1.024237226136829, + 1.0238709294563326 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01097491510325437, + "scoreError" : 2.1227888608834453E-4, + "scoreConfidence" : [ + 0.010762636217166026, + 0.011187193989342715 + ], + "scorePercentiles" : { + "0.0" : 0.010899842078760068, + "50.0" : 0.010974946828584149, + "90.0" : 0.011050464476961463, + "95.0" : 0.011050464476961463, + "99.0" : 0.011050464476961463, + "99.9" : 0.011050464476961463, + "99.99" : 0.011050464476961463, + "99.999" : 0.011050464476961463, + "99.9999" : 0.011050464476961463, + "100.0" : 0.011050464476961463 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011038484160168841, + 0.011042598043740876, + 0.011050464476961463 + ], + [ + 0.010906692362895522, + 0.010911409496999454, + 0.010899842078760068 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2075394143939917, + "scoreError" : 0.08543657729638544, + "scoreConfidence" : [ + 3.1221028370976063, + 3.292975991690377 + ], + "scorePercentiles" : { + "0.0" : 3.1772210565438375, + "50.0" : 3.207404272871176, + "90.0" : 3.238036270550162, + "95.0" : 3.238036270550162, + "99.0" : 3.238036270550162, + "99.9" : 3.238036270550162, + "99.99" : 3.238036270550162, + "99.999" : 3.238036270550162, + "99.9999" : 3.238036270550162, + "100.0" : 3.238036270550162 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2351129288486415, + 3.238036270550162, + 3.232667912790698 + ], + [ + 3.1772210565438375, + 3.1821406329516537, + 3.180057684678957 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8013710442343194, + "scoreError" : 0.09908869720702473, + "scoreConfidence" : [ + 2.7022823470272948, + 2.900459741441344 + ], + "scorePercentiles" : { + "0.0" : 2.7667862246196404, + "50.0" : 2.7997444810839576, + "90.0" : 2.838148126276958, + "95.0" : 2.838148126276958, + "99.0" : 2.838148126276958, + "99.9" : 2.838148126276958, + "99.99" : 2.838148126276958, + "99.999" : 2.838148126276958, + "99.9999" : 2.838148126276958, + "100.0" : 2.838148126276958 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.838148126276958, + 2.8275970070681367, + 2.8345902721088434 + ], + [ + 2.7718919550997785, + 2.7692126802325583, + 2.7667862246196404 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18831522247602908, + "scoreError" : 0.01320230585813595, + "scoreConfidence" : [ + 0.17511291661789313, + 0.20151752833416503 + ], + "scorePercentiles" : { + "0.0" : 0.18232057179580674, + "50.0" : 0.18956005307675755, + "90.0" : 0.1925366986657425, + "95.0" : 0.1925366986657425, + "99.0" : 0.1925366986657425, + "99.9" : 0.1925366986657425, + "99.99" : 0.1925366986657425, + "99.999" : 0.1925366986657425, + "99.9999" : 0.1925366986657425, + "100.0" : 0.1925366986657425 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18683431329870712, + 0.1835491625461153, + 0.18232057179580674 + ], + [ + 0.19236479569499482, + 0.1925366986657425, + 0.192285792854808 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33122974542499567, + "scoreError" : 0.00936213599925976, + "scoreConfidence" : [ + 0.3218676094257359, + 0.34059188142425545 + ], + "scorePercentiles" : { + "0.0" : 0.32807261216455613, + "50.0" : 0.33130213506674144, + "90.0" : 0.33431934437683875, + "95.0" : 0.33431934437683875, + "99.0" : 0.33431934437683875, + "99.9" : 0.33431934437683875, + "99.99" : 0.33431934437683875, + "99.999" : 0.33431934437683875, + "99.9999" : 0.33431934437683875, + "100.0" : 0.33431934437683875 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33428951552732744, + 0.334218085291267, + 0.33431934437683875 + ], + [ + 0.3283861848422159, + 0.32809273034776903, + 0.32807261216455613 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14199090320111704, + "scoreError" : 6.406888073906941E-4, + "scoreConfidence" : [ + 0.14135021439372636, + 0.14263159200850772 + ], + "scorePercentiles" : { + "0.0" : 0.1415685460015006, + "50.0" : 0.1420378276953001, + "90.0" : 0.14224588614833147, + "95.0" : 0.14224588614833147, + "99.0" : 0.14224588614833147, + "99.9" : 0.14224588614833147, + "99.99" : 0.14224588614833147, + "99.999" : 0.14224588614833147, + "99.9999" : 0.14224588614833147, + "100.0" : 0.14224588614833147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14202898292856128, + 0.1415685460015006, + 0.1420466724620389 + ], + [ + 0.14209957129662523, + 0.14195576036964483, + 0.14224588614833147 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.41481445061366445, + "scoreError" : 0.025023534227998082, + "scoreConfidence" : [ + 0.3897909163856664, + 0.43983798484166253 + ], + "scorePercentiles" : { + "0.0" : 0.40636495729204763, + "50.0" : 0.414385713218664, + "90.0" : 0.4236801572191154, + "95.0" : 0.4236801572191154, + "99.0" : 0.4236801572191154, + "99.9" : 0.4236801572191154, + "99.99" : 0.4236801572191154, + "99.999" : 0.4236801572191154, + "99.9999" : 0.4236801572191154, + "100.0" : 0.4236801572191154 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4072214660613217, + 0.40651910788617884, + 0.40636495729204763 + ], + [ + 0.4236801572191154, + 0.4235510548473169, + 0.4215499603760064 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15830778150074207, + "scoreError" : 0.005984104324630183, + "scoreConfidence" : [ + 0.1523236771761119, + 0.16429188582537224 + ], + "scorePercentiles" : { + "0.0" : 0.15638672403277765, + "50.0" : 0.15795887540542858, + "90.0" : 0.16156183815047578, + "95.0" : 0.16156183815047578, + "99.0" : 0.16156183815047578, + "99.9" : 0.16156183815047578, + "99.99" : 0.16156183815047578, + "99.999" : 0.16156183815047578, + "99.9999" : 0.16156183815047578, + "100.0" : 0.16156183815047578 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15638672403277765, + 0.15658995474617143, + 0.15652439225844825 + ], + [ + 0.16156183815047578, + 0.1594559837518935, + 0.15932779606468572 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048243928350234104, + "scoreError" : 0.004235270320438999, + "scoreConfidence" : [ + 0.0440086580297951, + 0.052479198670673105 + ], + "scorePercentiles" : { + "0.0" : 0.04681095559570843, + "50.0" : 0.048234986205287045, + "90.0" : 0.04988847041157396, + "95.0" : 0.04988847041157396, + "99.0" : 0.04988847041157396, + "99.9" : 0.04988847041157396, + "99.99" : 0.04988847041157396, + "99.999" : 0.04988847041157396, + "99.9999" : 0.04988847041157396, + "100.0" : 0.04988847041157396 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046993042800148495, + 0.04681593707105606, + 0.04681095559570843 + ], + [ + 0.04988847041157396, + 0.04947823461249208, + 0.049476929610425595 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9133420.639616901, + "scoreError" : 412419.678574724, + "scoreConfidence" : [ + 8721000.961042177, + 9545840.318191625 + ], + "scorePercentiles" : { + "0.0" : 8939655.63538874, + "50.0" : 9201217.744126346, + "90.0" : 9254384.480111009, + "95.0" : 9254384.480111009, + "99.0" : 9254384.480111009, + "99.9" : 9254384.480111009, + "99.99" : 9254384.480111009, + "99.999" : 9254384.480111009, + "99.9999" : 9254384.480111009, + "100.0" : 9254384.480111009 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9254384.480111009, + 9251219.370027753, + 9213303.569060773 + ], + [ + 8952828.863921218, + 8939655.63538874, + 9189131.91919192 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-28T21:23:46Z-db9f64ea67056746df85dc2901f82970e1dcc487-jdk17.json b/performance-results/2025-07-28T21:23:46Z-db9f64ea67056746df85dc2901f82970e1dcc487-jdk17.json new file mode 100644 index 0000000000..f4502dfb3e --- /dev/null +++ b/performance-results/2025-07-28T21:23:46Z-db9f64ea67056746df85dc2901f82970e1dcc487-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.331643164772836, + "scoreError" : 0.051247818181749914, + "scoreConfidence" : [ + 3.280395346591086, + 3.382890982954586 + ], + "scorePercentiles" : { + "0.0" : 3.3206381936419542, + "50.0" : 3.333204573495289, + "90.0" : 3.3395253184588114, + "95.0" : 3.3395253184588114, + "99.0" : 3.3395253184588114, + "99.9" : 3.3395253184588114, + "99.99" : 3.3395253184588114, + "99.999" : 3.3395253184588114, + "99.9999" : 3.3395253184588114, + "100.0" : 3.3395253184588114 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.333739461894395, + 3.3326696850961826 + ], + [ + 3.3206381936419542, + 3.3395253184588114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6818165999056673, + "scoreError" : 0.0268110540331406, + "scoreConfidence" : [ + 1.6550055458725268, + 1.7086276539388079 + ], + "scorePercentiles" : { + "0.0" : 1.676581598598524, + "50.0" : 1.6820594087665177, + "90.0" : 1.68656598349111, + "95.0" : 1.68656598349111, + "99.0" : 1.68656598349111, + "99.9" : 1.68656598349111, + "99.99" : 1.68656598349111, + "99.999" : 1.68656598349111, + "99.9999" : 1.68656598349111, + "100.0" : 1.68656598349111 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6829436628482946, + 1.68656598349111 + ], + [ + 1.676581598598524, + 1.6811751546847407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8451206185553661, + "scoreError" : 0.028158247701432854, + "scoreConfidence" : [ + 0.8169623708539333, + 0.873278866256799 + ], + "scorePercentiles" : { + "0.0" : 0.839166147307282, + "50.0" : 0.8462662582459716, + "90.0" : 0.8487838104222392, + "95.0" : 0.8487838104222392, + "99.0" : 0.8487838104222392, + "99.9" : 0.8487838104222392, + "99.99" : 0.8487838104222392, + "99.999" : 0.8487838104222392, + "99.9999" : 0.8487838104222392, + "100.0" : 0.8487838104222392 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.839166147307282, + 0.8487838104222392 + ], + [ + 0.844613342854886, + 0.8479191736370572 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.991852858006974, + "scoreError" : 0.2893930297259564, + "scoreConfidence" : [ + 15.702459828281018, + 16.28124588773293 + ], + "scorePercentiles" : { + "0.0" : 15.825655653459275, + "50.0" : 15.994339276151408, + "90.0" : 16.131730692048308, + "95.0" : 16.131730692048308, + "99.0" : 16.131730692048308, + "99.9" : 16.131730692048308, + "99.99" : 16.131730692048308, + "99.999" : 16.131730692048308, + "99.9999" : 16.131730692048308, + "100.0" : 16.131730692048308 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.131730692048308, + 15.825655653459275, + 15.987034413792097 + ], + [ + 16.055992516436707, + 16.00164413851072, + 15.949059733794734 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2635.2188133655827, + "scoreError" : 121.33905865655838, + "scoreConfidence" : [ + 2513.8797547090244, + 2756.557872022141 + ], + "scorePercentiles" : { + "0.0" : 2587.552765539256, + "50.0" : 2625.0432501873474, + "90.0" : 2686.5489180150803, + "95.0" : 2686.5489180150803, + "99.0" : 2686.5489180150803, + "99.9" : 2686.5489180150803, + "99.99" : 2686.5489180150803, + "99.999" : 2686.5489180150803, + "99.9999" : 2686.5489180150803, + "100.0" : 2686.5489180150803 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2609.501709446339, + 2587.552765539256, + 2600.9857496997092 + ], + [ + 2686.5489180150803, + 2640.584790928356, + 2686.138946564755 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75121.99264019799, + "scoreError" : 2899.2101794917526, + "scoreConfidence" : [ + 72222.78246070624, + 78021.20281968974 + ], + "scorePercentiles" : { + "0.0" : 74003.79761382437, + "50.0" : 75206.79416276628, + "90.0" : 76205.35181396423, + "95.0" : 76205.35181396423, + "99.0" : 76205.35181396423, + "99.9" : 76205.35181396423, + "99.99" : 76205.35181396423, + "99.999" : 76205.35181396423, + "99.9999" : 76205.35181396423, + "100.0" : 76205.35181396423 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76038.22467289977, + 75900.37684015009, + 76205.35181396423 + ], + [ + 74513.21148538248, + 74070.99341496703, + 74003.79761382437 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 348.31523010548176, + "scoreError" : 14.34267483846891, + "scoreConfidence" : [ + 333.97255526701286, + 362.65790494395065 + ], + "scorePercentiles" : { + "0.0" : 342.2807512258495, + "50.0" : 348.4780580738318, + "90.0" : 353.8869869384937, + "95.0" : 353.8869869384937, + "99.0" : 353.8869869384937, + "99.9" : 353.8869869384937, + "99.99" : 353.8869869384937, + "99.999" : 353.8869869384937, + "99.9999" : 353.8869869384937, + "100.0" : 353.8869869384937 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 353.56004531067157, + 350.67953479823257, + 353.8869869384937 + ], + [ + 346.276581349431, + 343.2074810102121, + 342.2807512258495 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.41423355966064, + "scoreError" : 3.66211911767386, + "scoreConfidence" : [ + 109.75211444198679, + 117.0763526773345 + ], + "scorePercentiles" : { + "0.0" : 112.14262805577192, + "50.0" : 113.37295573035257, + "90.0" : 114.79595469387294, + "95.0" : 114.79595469387294, + "99.0" : 114.79595469387294, + "99.9" : 114.79595469387294, + "99.99" : 114.79595469387294, + "99.999" : 114.79595469387294, + "99.9999" : 114.79595469387294, + "100.0" : 114.79595469387294 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.14262805577192, + 112.3311606901494, + 112.21156920423408 + ], + [ + 114.41475077055574, + 114.58933794337959, + 114.79595469387294 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06229997289667589, + "scoreError" : 8.386683911875162E-4, + "scoreConfidence" : [ + 0.061461304505488375, + 0.06313864128786341 + ], + "scorePercentiles" : { + "0.0" : 0.061992412597946835, + "50.0" : 0.06227300967056189, + "90.0" : 0.06266411988745668, + "95.0" : 0.06266411988745668, + "99.0" : 0.06266411988745668, + "99.9" : 0.06266411988745668, + "99.99" : 0.06266411988745668, + "99.999" : 0.06266411988745668, + "99.9999" : 0.06266411988745668, + "100.0" : 0.06266411988745668 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06266411988745668, + 0.061992412597946835, + 0.06211519034249723 + ], + [ + 0.062008153430229675, + 0.06258913212329839, + 0.06243082899862654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7806239285135683E-4, + "scoreError" : 3.299084706897687E-5, + "scoreConfidence" : [ + 3.4507154578238E-4, + 4.110532399203337E-4 + ], + "scorePercentiles" : { + "0.0" : 3.643146844686191E-4, + "50.0" : 3.7814691054728936E-4, + "90.0" : 3.9005836309059924E-4, + "95.0" : 3.9005836309059924E-4, + "99.0" : 3.9005836309059924E-4, + "99.9" : 3.9005836309059924E-4, + "99.99" : 3.9005836309059924E-4, + "99.999" : 3.9005836309059924E-4, + "99.9999" : 3.9005836309059924E-4, + "100.0" : 3.9005836309059924E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8585234062375913E-4, + 3.9005836309059924E-4, + 3.8978859857380344E-4 + ], + [ + 3.6791888988054047E-4, + 3.643146844686191E-4, + 3.7044148047081954E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12713244157367373, + "scoreError" : 0.0046481853466590435, + "scoreConfidence" : [ + 0.12248425622701468, + 0.13178062692033277 + ], + "scorePercentiles" : { + "0.0" : 0.12543768301493924, + "50.0" : 0.12718442822571785, + "90.0" : 0.12886493870003352, + "95.0" : 0.12886493870003352, + "99.0" : 0.12886493870003352, + "99.9" : 0.12886493870003352, + "99.99" : 0.12886493870003352, + "99.999" : 0.12886493870003352, + "99.9999" : 0.12886493870003352, + "100.0" : 0.12886493870003352 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12843506913513653, + 0.12859790914702365, + 0.12886493870003352 + ], + [ + 0.12593378731629917, + 0.12543768301493924, + 0.12552526212861034 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013143034323990497, + "scoreError" : 4.8252151400674344E-4, + "scoreConfidence" : [ + 0.012660512809983754, + 0.01362555583799724 + ], + "scorePercentiles" : { + "0.0" : 0.012943142682783194, + "50.0" : 0.013151494756082769, + "90.0" : 0.013377522964142147, + "95.0" : 0.013377522964142147, + "99.0" : 0.013377522964142147, + "99.9" : 0.013377522964142147, + "99.99" : 0.013377522964142147, + "99.999" : 0.013377522964142147, + "99.9999" : 0.013377522964142147, + "100.0" : 0.013377522964142147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013377522964142147, + 0.013273398080159704, + 0.013189463002919989 + ], + [ + 0.01311352650924555, + 0.012961152704692384, + 0.012943142682783194 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0189571718304444, + "scoreError" : 0.05048367241199941, + "scoreConfidence" : [ + 0.9684734994184451, + 1.069440844242444 + ], + "scorePercentiles" : { + "0.0" : 1.002440727947073, + "50.0" : 1.0178045820635433, + "90.0" : 1.0372601136811535, + "95.0" : 1.0372601136811535, + "99.0" : 1.0372601136811535, + "99.9" : 1.0372601136811535, + "99.99" : 1.0372601136811535, + "99.999" : 1.0372601136811535, + "99.9999" : 1.0372601136811535, + "100.0" : 1.0372601136811535 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0327662514716514, + 1.0372601136811535, + 1.035983271418212 + ], + [ + 1.002449753809142, + 1.002440727947073, + 1.0028429126554352 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01095586365769796, + "scoreError" : 4.40702445061621E-4, + "scoreConfidence" : [ + 0.01051516121263634, + 0.01139656610275958 + ], + "scorePercentiles" : { + "0.0" : 0.010765138448786264, + "50.0" : 0.010970742090528885, + "90.0" : 0.011130419814617772, + "95.0" : 0.011130419814617772, + "99.0" : 0.011130419814617772, + "99.9" : 0.011130419814617772, + "99.99" : 0.011130419814617772, + "99.999" : 0.011130419814617772, + "99.9999" : 0.011130419814617772, + "100.0" : 0.011130419814617772 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011098440128738694, + 0.0110465389135833, + 0.011130419814617772 + ], + [ + 0.010799699372987264, + 0.010765138448786264, + 0.010894945267474468 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.2042947257471455, + "scoreError" : 0.2941758148099074, + "scoreConfidence" : [ + 2.9101189109372383, + 3.4984705405570526 + ], + "scorePercentiles" : { + "0.0" : 3.103877549348231, + "50.0" : 3.1971679404254294, + "90.0" : 3.321170586321381, + "95.0" : 3.321170586321381, + "99.0" : 3.321170586321381, + "99.9" : 3.321170586321381, + "99.99" : 3.321170586321381, + "99.999" : 3.321170586321381, + "99.9999" : 3.321170586321381, + "100.0" : 3.321170586321381 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.103877549348231, + 3.1202652407985028, + 3.1048289894475483 + ], + [ + 3.274070640052356, + 3.321170586321381, + 3.3015553485148517 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8547099613500584, + "scoreError" : 0.03933021225603408, + "scoreConfidence" : [ + 2.815379749094024, + 2.8940401736060926 + ], + "scorePercentiles" : { + "0.0" : 2.8406476160181766, + "50.0" : 2.8517831442122312, + "90.0" : 2.881364099106886, + "95.0" : 2.881364099106886, + "99.0" : 2.881364099106886, + "99.9" : 2.881364099106886, + "99.99" : 2.881364099106886, + "99.999" : 2.881364099106886, + "99.9999" : 2.881364099106886, + "100.0" : 2.881364099106886 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8478931976082005, + 2.8547885669426205, + 2.8406476160181766 + ], + [ + 2.8493563934472936, + 2.854209894977169, + 2.881364099106886 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1756349745244731, + "scoreError" : 0.004332128107500396, + "scoreConfidence" : [ + 0.17130284641697271, + 0.1799671026319735 + ], + "scorePercentiles" : { + "0.0" : 0.17369850514138818, + "50.0" : 0.1761021839924573, + "90.0" : 0.1772355841943888, + "95.0" : 0.1772355841943888, + "99.0" : 0.1772355841943888, + "99.9" : 0.1772355841943888, + "99.99" : 0.1772355841943888, + "99.999" : 0.1772355841943888, + "99.9999" : 0.1772355841943888, + "100.0" : 0.1772355841943888 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1737629930670188, + 0.17593057899829354, + 0.17369850514138818 + ], + [ + 0.17690839675912823, + 0.1772355841943888, + 0.17627378898662108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33801709073173153, + "scoreError" : 0.00600661825870432, + "scoreConfidence" : [ + 0.33201047247302723, + 0.34402370899043583 + ], + "scorePercentiles" : { + "0.0" : 0.33513639282841823, + "50.0" : 0.3379684057409665, + "90.0" : 0.34079614309569245, + "95.0" : 0.34079614309569245, + "99.0" : 0.34079614309569245, + "99.9" : 0.34079614309569245, + "99.99" : 0.34079614309569245, + "99.999" : 0.34079614309569245, + "99.9999" : 0.34079614309569245, + "100.0" : 0.34079614309569245 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.34079614309569245, + 0.3371740507434506, + 0.33979485769622836 + ], + [ + 0.33643833928811734, + 0.33513639282841823, + 0.3387627607384824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14765633204777087, + "scoreError" : 0.011111430803548622, + "scoreConfidence" : [ + 0.13654490124422225, + 0.1587677628513195 + ], + "scorePercentiles" : { + "0.0" : 0.14350285903911833, + "50.0" : 0.14749487041746023, + "90.0" : 0.15259609337137975, + "95.0" : 0.15259609337137975, + "99.0" : 0.15259609337137975, + "99.9" : 0.15259609337137975, + "99.99" : 0.15259609337137975, + "99.999" : 0.15259609337137975, + "99.9999" : 0.15259609337137975, + "100.0" : 0.15259609337137975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14350285903911833, + 0.1445069205080778, + 0.14435569037892457 + ], + [ + 0.15048282032684263, + 0.15049360866228234, + 0.15259609337137975 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4096547899709148, + "scoreError" : 0.012798631943481974, + "scoreConfidence" : [ + 0.39685615802743285, + 0.4224534219143968 + ], + "scorePercentiles" : { + "0.0" : 0.40474324971669096, + "50.0" : 0.40932563235845926, + "90.0" : 0.4151857947770489, + "95.0" : 0.4151857947770489, + "99.0" : 0.4151857947770489, + "99.9" : 0.4151857947770489, + "99.99" : 0.4151857947770489, + "99.999" : 0.4151857947770489, + "99.9999" : 0.4151857947770489, + "100.0" : 0.4151857947770489 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4086183155185094, + 0.40474324971669096, + 0.40476389614279357 + ], + [ + 0.4100329491984091, + 0.4151857947770489, + 0.4145845344720368 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15859302569501932, + "scoreError" : 0.008073820047993934, + "scoreConfidence" : [ + 0.1505192056470254, + 0.16666684574301324 + ], + "scorePercentiles" : { + "0.0" : 0.1556597189465164, + "50.0" : 0.15854398725939578, + "90.0" : 0.16206386583152368, + "95.0" : 0.16206386583152368, + "99.0" : 0.16206386583152368, + "99.9" : 0.16206386583152368, + "99.99" : 0.16206386583152368, + "99.999" : 0.16206386583152368, + "99.9999" : 0.16206386583152368, + "100.0" : 0.16206386583152368 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16206386583152368, + 0.16082867278341562, + 0.16062231524759474 + ], + [ + 0.1564656592711968, + 0.1556597189465164, + 0.1559179220898687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046799052754565175, + "scoreError" : 7.884140873007828E-4, + "scoreConfidence" : [ + 0.04601063866726439, + 0.04758746684186596 + ], + "scorePercentiles" : { + "0.0" : 0.04639564129794332, + "50.0" : 0.04679468600142449, + "90.0" : 0.04713802923929746, + "95.0" : 0.04713802923929746, + "99.0" : 0.04713802923929746, + "99.9" : 0.04713802923929746, + "99.99" : 0.04713802923929746, + "99.999" : 0.04713802923929746, + "99.9999" : 0.04713802923929746, + "100.0" : 0.04713802923929746 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04713802923929746, + 0.04693714135383518, + 0.04639564129794332 + ], + [ + 0.04702837487302483, + 0.04665223064901379, + 0.04664289911427652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8775559.738631895, + "scoreError" : 269473.8422176585, + "scoreConfidence" : [ + 8506085.896414237, + 9045033.580849553 + ], + "scorePercentiles" : { + "0.0" : 8678199.808326107, + "50.0" : 8781481.356036095, + "90.0" : 8866652.171985816, + "95.0" : 8866652.171985816, + "99.0" : 8866652.171985816, + "99.9" : 8866652.171985816, + "99.99" : 8866652.171985816, + "99.999" : 8866652.171985816, + "99.9999" : 8866652.171985816, + "100.0" : 8866652.171985816 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8704656.553524803, + 8678199.808326107, + 8681924.269965278 + ], + [ + 8858306.158547387, + 8866652.171985816, + 8863619.469441984 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-30T22:03:05Z-80f35b3b901ac8dd68ab8b45afabc0db3087a5b6-jdk17.json b/performance-results/2025-07-30T22:03:05Z-80f35b3b901ac8dd68ab8b45afabc0db3087a5b6-jdk17.json new file mode 100644 index 0000000000..b44612e96a --- /dev/null +++ b/performance-results/2025-07-30T22:03:05Z-80f35b3b901ac8dd68ab8b45afabc0db3087a5b6-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3460800372190596, + "scoreError" : 0.026018905589721572, + "scoreConfidence" : [ + 3.320061131629338, + 3.372098942808781 + ], + "scorePercentiles" : { + "0.0" : 3.3410183864073546, + "50.0" : 3.3465459993581894, + "90.0" : 3.3502097637525043, + "95.0" : 3.3502097637525043, + "99.0" : 3.3502097637525043, + "99.9" : 3.3502097637525043, + "99.99" : 3.3502097637525043, + "99.999" : 3.3502097637525043, + "99.9999" : 3.3502097637525043, + "100.0" : 3.3502097637525043 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3410183864073546, + 3.3482084996574164 + ], + [ + 3.3448834990589624, + 3.3502097637525043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6884764675376813, + "scoreError" : 0.01851244470576729, + "scoreConfidence" : [ + 1.6699640228319141, + 1.7069889122434485 + ], + "scorePercentiles" : { + "0.0" : 1.6845142944551652, + "50.0" : 1.6890237266310426, + "90.0" : 1.691344122433475, + "95.0" : 1.691344122433475, + "99.0" : 1.691344122433475, + "99.9" : 1.691344122433475, + "99.99" : 1.691344122433475, + "99.999" : 1.691344122433475, + "99.9999" : 1.691344122433475, + "100.0" : 1.691344122433475 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6845142944551652, + 1.6892477336076865 + ], + [ + 1.6887997196543987, + 1.691344122433475 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8483547677000283, + "scoreError" : 0.009248879937832943, + "scoreConfidence" : [ + 0.8391058877621953, + 0.8576036476378612 + ], + "scorePercentiles" : { + "0.0" : 0.8470417117721241, + "50.0" : 0.8480400135686396, + "90.0" : 0.8502973318907097, + "95.0" : 0.8502973318907097, + "99.0" : 0.8502973318907097, + "99.9" : 0.8502973318907097, + "99.99" : 0.8502973318907097, + "99.999" : 0.8502973318907097, + "99.9999" : 0.8502973318907097, + "100.0" : 0.8502973318907097 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8485142642745391, + 0.8502973318907097 + ], + [ + 0.84756576286274, + 0.8470417117721241 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.11748871557649, + "scoreError" : 0.06158701905901077, + "scoreConfidence" : [ + 16.055901696517477, + 16.1790757346355 + ], + "scorePercentiles" : { + "0.0" : 16.08579749911244, + "50.0" : 16.113787786571887, + "90.0" : 16.147999399668446, + "95.0" : 16.147999399668446, + "99.0" : 16.147999399668446, + "99.9" : 16.147999399668446, + "99.99" : 16.147999399668446, + "99.999" : 16.147999399668446, + "99.9999" : 16.147999399668446, + "100.0" : 16.147999399668446 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.11480246676955, + 16.112773106374224, + 16.10745780021079 + ], + [ + 16.147999399668446, + 16.13610202132347, + 16.08579749911244 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2727.4950486614894, + "scoreError" : 31.130154912431564, + "scoreConfidence" : [ + 2696.364893749058, + 2758.6252035739208 + ], + "scorePercentiles" : { + "0.0" : 2715.017580095496, + "50.0" : 2727.9003271961824, + "90.0" : 2738.7885308400705, + "95.0" : 2738.7885308400705, + "99.0" : 2738.7885308400705, + "99.9" : 2738.7885308400705, + "99.99" : 2738.7885308400705, + "99.999" : 2738.7885308400705, + "99.9999" : 2738.7885308400705, + "100.0" : 2738.7885308400705 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2715.017580095496, + 2716.996133953458, + 2720.6822170732016 + ], + [ + 2738.7885308400705, + 2738.3673926875476, + 2735.118437319163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75520.93425397173, + "scoreError" : 208.36580917073772, + "scoreConfidence" : [ + 75312.568444801, + 75729.30006314247 + ], + "scorePercentiles" : { + "0.0" : 75441.10262054022, + "50.0" : 75506.95709001189, + "90.0" : 75614.04948602953, + "95.0" : 75614.04948602953, + "99.0" : 75614.04948602953, + "99.9" : 75614.04948602953, + "99.99" : 75614.04948602953, + "99.999" : 75614.04948602953, + "99.9999" : 75614.04948602953, + "100.0" : 75614.04948602953 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75451.72553724766, + 75493.79486898505, + 75441.10262054022 + ], + [ + 75614.04948602953, + 75520.11931103874, + 75604.8136999892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.0250529144755, + "scoreError" : 16.630689264489344, + "scoreConfidence" : [ + 339.3943636499862, + 372.65574217896483 + ], + "scorePercentiles" : { + "0.0" : 350.32916186698924, + "50.0" : 355.9283726253776, + "90.0" : 361.836969519625, + "95.0" : 361.836969519625, + "99.0" : 361.836969519625, + "99.9" : 361.836969519625, + "99.99" : 361.836969519625, + "99.999" : 361.836969519625, + "99.9999" : 361.836969519625, + "100.0" : 361.836969519625 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 350.32916186698924, + 350.8930297205004, + 350.6364150665372 + ], + [ + 360.96371553025483, + 361.49102578294594, + 361.836969519625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.8920167010855, + "scoreError" : 5.543464396779908, + "scoreConfidence" : [ + 112.34855230430558, + 123.4354810978654 + ], + "scorePercentiles" : { + "0.0" : 115.96053380638747, + "50.0" : 117.80244936542726, + "90.0" : 119.91662000747624, + "95.0" : 119.91662000747624, + "99.0" : 119.91662000747624, + "99.9" : 119.91662000747624, + "99.99" : 119.91662000747624, + "99.999" : 119.91662000747624, + "99.9999" : 119.91662000747624, + "100.0" : 119.91662000747624 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.33225670228359, + 115.96053380638747, + 116.0157253186122 + ], + [ + 119.91662000747624, + 119.85432234318266, + 119.27264202857093 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0614265552673224, + "scoreError" : 3.3668008544388516E-4, + "scoreConfidence" : [ + 0.061089875181878514, + 0.06176323535276629 + ], + "scorePercentiles" : { + "0.0" : 0.06129606563486469, + "50.0" : 0.06140238501599983, + "90.0" : 0.06159755376787848, + "95.0" : 0.06159755376787848, + "99.0" : 0.06159755376787848, + "99.9" : 0.06159755376787848, + "99.99" : 0.06159755376787848, + "99.999" : 0.06159755376787848, + "99.9999" : 0.06159755376787848, + "100.0" : 0.06159755376787848 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06133819969946026, + 0.06129606563486469, + 0.06134081823758174 + ], + [ + 0.06152274246973127, + 0.061463951794417916, + 0.06159755376787848 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6681746603231313E-4, + "scoreError" : 3.989741437255106E-5, + "scoreConfidence" : [ + 3.2692005165976205E-4, + 4.067148804048642E-4 + ], + "scorePercentiles" : { + "0.0" : 3.537229808475251E-4, + "50.0" : 3.666446673142193E-4, + "90.0" : 3.803598765869038E-4, + "95.0" : 3.803598765869038E-4, + "99.0" : 3.803598765869038E-4, + "99.9" : 3.803598765869038E-4, + "99.99" : 3.803598765869038E-4, + "99.999" : 3.803598765869038E-4, + "99.9999" : 3.803598765869038E-4, + "100.0" : 3.803598765869038E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.803598765869038E-4, + 3.793440103911502E-4, + 3.797022554929362E-4 + ], + [ + 3.537229808475251E-4, + 3.538303486380751E-4, + 3.5394532423728837E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1249983755167423, + "scoreError" : 0.0011489724205739774, + "scoreConfidence" : [ + 0.12384940309616832, + 0.12614734793731627 + ], + "scorePercentiles" : { + "0.0" : 0.12447274743589744, + "50.0" : 0.12507293334945305, + "90.0" : 0.12543530287484636, + "95.0" : 0.12543530287484636, + "99.0" : 0.12543530287484636, + "99.9" : 0.12543530287484636, + "99.99" : 0.12543530287484636, + "99.999" : 0.12543530287484636, + "99.9999" : 0.12543530287484636, + "100.0" : 0.12543530287484636 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12543530287484636, + 0.12529770734610518, + 0.125327495563465 + ], + [ + 0.12484815935280091, + 0.12447274743589744, + 0.12460884052733888 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013248594903843634, + "scoreError" : 5.094146825521463E-4, + "scoreConfidence" : [ + 0.012739180221291488, + 0.01375800958639578 + ], + "scorePercentiles" : { + "0.0" : 0.013075960317584848, + "50.0" : 0.01325006685660348, + "90.0" : 0.013416597166991343, + "95.0" : 0.013416597166991343, + "99.0" : 0.013416597166991343, + "99.9" : 0.013416597166991343, + "99.99" : 0.013416597166991343, + "99.999" : 0.013416597166991343, + "99.9999" : 0.013416597166991343, + "100.0" : 0.013416597166991343 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013084574541914617, + 0.013087875810458149, + 0.013075960317584848 + ], + [ + 0.013412257902748812, + 0.013416597166991343, + 0.01341430368336403 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9821103882463782, + "scoreError" : 0.08673128197615132, + "scoreConfidence" : [ + 0.8953791062702269, + 1.0688416702225294 + ], + "scorePercentiles" : { + "0.0" : 0.9538307179780638, + "50.0" : 0.9820338022176116, + "90.0" : 1.0107782253891247, + "95.0" : 1.0107782253891247, + "99.0" : 1.0107782253891247, + "99.9" : 1.0107782253891247, + "99.99" : 1.0107782253891247, + "99.999" : 1.0107782253891247, + "99.9999" : 1.0107782253891247, + "100.0" : 1.0107782253891247 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.010139483030303, + 1.0101140005050504, + 1.0107782253891247 + ], + [ + 0.9539536039301727, + 0.9538307179780638, + 0.9538462986455551 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010729451493956557, + "scoreError" : 6.346760668853688E-4, + "scoreConfidence" : [ + 0.010094775427071188, + 0.011364127560841927 + ], + "scorePercentiles" : { + "0.0" : 0.010519571615514731, + "50.0" : 0.01072981262668108, + "90.0" : 0.010937844242804737, + "95.0" : 0.010937844242804737, + "99.0" : 0.010937844242804737, + "99.9" : 0.010937844242804737, + "99.99" : 0.010937844242804737, + "99.999" : 0.010937844242804737, + "99.9999" : 0.010937844242804737, + "100.0" : 0.010937844242804737 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010937844242804737, + 0.010935829899939855, + 0.010934487524109849 + ], + [ + 0.010523837952117863, + 0.010519571615514731, + 0.01052513772925231 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1521960089884797, + "scoreError" : 0.18666857592276306, + "scoreConfidence" : [ + 2.965527433065717, + 3.3388645849112426 + ], + "scorePercentiles" : { + "0.0" : 3.0855574713140035, + "50.0" : 3.15077570937262, + "90.0" : 3.217996956241956, + "95.0" : 3.217996956241956, + "99.0" : 3.217996956241956, + "99.9" : 3.217996956241956, + "99.99" : 3.217996956241956, + "99.999" : 3.217996956241956, + "99.9999" : 3.217996956241956, + "100.0" : 3.217996956241956 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.213506692159383, + 3.217996956241956, + 3.206906673076923 + ], + [ + 3.094563515470297, + 3.094644745668317, + 3.0855574713140035 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.742696288578506, + "scoreError" : 0.11503660288956712, + "scoreConfidence" : [ + 2.627659685688939, + 2.857732891468073 + ], + "scorePercentiles" : { + "0.0" : 2.7040657499324143, + "50.0" : 2.7413798741813262, + "90.0" : 2.785626130362117, + "95.0" : 2.785626130362117, + "99.0" : 2.785626130362117, + "99.9" : 2.785626130362117, + "99.99" : 2.785626130362117, + "99.999" : 2.785626130362117, + "99.9999" : 2.785626130362117, + "100.0" : 2.785626130362117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7061974829545457, + 2.7040657499324143, + 2.705816186147186 + ], + [ + 2.785626130362117, + 2.7779099166666668, + 2.776562265408107 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17420262646833398, + "scoreError" : 0.005749665359104493, + "scoreConfidence" : [ + 0.1684529611092295, + 0.17995229182743847 + ], + "scorePercentiles" : { + "0.0" : 0.17168228134388575, + "50.0" : 0.17430648289974532, + "90.0" : 0.1768495236798359, + "95.0" : 0.1768495236798359, + "99.0" : 0.1768495236798359, + "99.9" : 0.1768495236798359, + "99.99" : 0.1768495236798359, + "99.999" : 0.1768495236798359, + "99.9999" : 0.1768495236798359, + "100.0" : 0.1768495236798359 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1768495236798359, + 0.17562005298187694, + 0.175438542358906 + ], + [ + 0.17317442344058462, + 0.17168228134388575, + 0.17245093500491473 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3259979455684359, + "scoreError" : 0.004489274816290288, + "scoreConfidence" : [ + 0.3215086707521456, + 0.3304872203847262 + ], + "scorePercentiles" : { + "0.0" : 0.32407702284658757, + "50.0" : 0.3263130527466429, + "90.0" : 0.3276310654894509, + "95.0" : 0.3276310654894509, + "99.0" : 0.3276310654894509, + "99.9" : 0.3276310654894509, + "99.99" : 0.3276310654894509, + "99.999" : 0.3276310654894509, + "99.9999" : 0.3276310654894509, + "100.0" : 0.3276310654894509 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32543521032249667, + 0.32407702284658757, + 0.32430042802477543 + ], + [ + 0.3273530515565158, + 0.32719089517078914, + 0.3276310654894509 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14449774652122083, + "scoreError" : 3.9635351046255114E-4, + "scoreConfidence" : [ + 0.14410139301075828, + 0.14489410003168338 + ], + "scorePercentiles" : { + "0.0" : 0.14436442583476491, + "50.0" : 0.14445022494750426, + "90.0" : 0.14474523102420103, + "95.0" : 0.14474523102420103, + "99.0" : 0.14474523102420103, + "99.9" : 0.14474523102420103, + "99.99" : 0.14474523102420103, + "99.999" : 0.14474523102420103, + "99.9999" : 0.14474523102420103, + "100.0" : 0.14474523102420103 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14474523102420103, + 0.14443204809497676, + 0.14457623934132344 + ], + [ + 0.1444684018000318, + 0.14436442583476491, + 0.14440013303202703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40710077240933656, + "scoreError" : 0.006942328913300606, + "scoreConfidence" : [ + 0.40015844349603596, + 0.41404310132263716 + ], + "scorePercentiles" : { + "0.0" : 0.4050743493195075, + "50.0" : 0.40632440813205617, + "90.0" : 0.4115546036462406, + "95.0" : 0.4115546036462406, + "99.0" : 0.4115546036462406, + "99.9" : 0.4115546036462406, + "99.99" : 0.4115546036462406, + "99.999" : 0.4115546036462406, + "99.9999" : 0.4115546036462406, + "100.0" : 0.4115546036462406 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4115546036462406, + 0.40811117666503427, + 0.4070035775507712 + ], + [ + 0.4050743493195075, + 0.4056452387133412, + 0.40521568856112483 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15907875000332258, + "scoreError" : 0.012651090802988084, + "scoreConfidence" : [ + 0.1464276592003345, + 0.17172984080631068 + ], + "scorePercentiles" : { + "0.0" : 0.15449959529400858, + "50.0" : 0.1590325722030273, + "90.0" : 0.16438924245064357, + "95.0" : 0.16438924245064357, + "99.0" : 0.16438924245064357, + "99.9" : 0.16438924245064357, + "99.99" : 0.16438924245064357, + "99.999" : 0.16438924245064357, + "99.9999" : 0.16438924245064357, + "100.0" : 0.16438924245064357 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15598926339926375, + 0.15449959529400858, + 0.15464426556459346 + ], + [ + 0.16438924245064357, + 0.16287425230463534, + 0.16207588100679082 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04745177076858712, + "scoreError" : 0.0032115805946338004, + "scoreConfidence" : [ + 0.04424019017395332, + 0.05066335136322092 + ], + "scorePercentiles" : { + "0.0" : 0.04638537488171884, + "50.0" : 0.04728441744428115, + "90.0" : 0.04872298560257254, + "95.0" : 0.04872298560257254, + "99.0" : 0.04872298560257254, + "99.9" : 0.04872298560257254, + "99.99" : 0.04872298560257254, + "99.999" : 0.04872298560257254, + "99.9999" : 0.04872298560257254, + "100.0" : 0.04872298560257254 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04872298560257254, + 0.04861319215493731, + 0.04810178364559032 + ], + [ + 0.04642023708373177, + 0.04638537488171884, + 0.04646705124297198 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8658420.181959266, + "scoreError" : 240687.8205461195, + "scoreConfidence" : [ + 8417732.361413145, + 8899108.002505386 + ], + "scorePercentiles" : { + "0.0" : 8579289.288164666, + "50.0" : 8647310.401244972, + "90.0" : 8766050.457493426, + "95.0" : 8766050.457493426, + "99.0" : 8766050.457493426, + "99.9" : 8766050.457493426, + "99.99" : 8766050.457493426, + "99.999" : 8766050.457493426, + "99.9999" : 8766050.457493426, + "100.0" : 8766050.457493426 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8766050.457493426, + 8709770.618798956, + 8729172.792321118 + ], + [ + 8579289.288164666, + 8581387.751286449, + 8584850.183690988 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-31T05:01:36Z-1b2f619e4b944ca224a7296197479e79bc39a9e1-jdk17.json b/performance-results/2025-07-31T05:01:36Z-1b2f619e4b944ca224a7296197479e79bc39a9e1-jdk17.json new file mode 100644 index 0000000000..09d80e6758 --- /dev/null +++ b/performance-results/2025-07-31T05:01:36Z-1b2f619e4b944ca224a7296197479e79bc39a9e1-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.353482858631146, + "scoreError" : 0.038276186398402176, + "scoreConfidence" : [ + 3.3152066722327436, + 3.391759045029548 + ], + "scorePercentiles" : { + "0.0" : 3.346497691792046, + "50.0" : 3.353255068379298, + "90.0" : 3.3609236059739396, + "95.0" : 3.3609236059739396, + "99.0" : 3.3609236059739396, + "99.9" : 3.3609236059739396, + "99.99" : 3.3609236059739396, + "99.999" : 3.3609236059739396, + "99.9999" : 3.3609236059739396, + "100.0" : 3.3609236059739396 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3539603211651747, + 3.3609236059739396 + ], + [ + 3.346497691792046, + 3.3525498155934215 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.7020432718910865, + "scoreError" : 0.013755654946980111, + "scoreConfidence" : [ + 1.6882876169441063, + 1.7157989268380667 + ], + "scorePercentiles" : { + "0.0" : 1.6991756177622328, + "50.0" : 1.7023371607273865, + "90.0" : 1.7043231483473402, + "95.0" : 1.7043231483473402, + "99.0" : 1.7043231483473402, + "99.9" : 1.7043231483473402, + "99.99" : 1.7043231483473402, + "99.999" : 1.7043231483473402, + "99.9999" : 1.7043231483473402, + "100.0" : 1.7043231483473402 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7023445450305896, + 1.7023297764241831 + ], + [ + 1.6991756177622328, + 1.7043231483473402 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.851553165364491, + "scoreError" : 0.037225329252169405, + "scoreConfidence" : [ + 0.8143278361123216, + 0.8887784946166604 + ], + "scorePercentiles" : { + "0.0" : 0.8444278799178012, + "50.0" : 0.852215983388291, + "90.0" : 0.8573528147635805, + "95.0" : 0.8573528147635805, + "99.0" : 0.8573528147635805, + "99.9" : 0.8573528147635805, + "99.99" : 0.8573528147635805, + "99.999" : 0.8573528147635805, + "99.9999" : 0.8573528147635805, + "100.0" : 0.8573528147635805 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8444278799178012, + 0.8495447139367008 + ], + [ + 0.854887252839881, + 0.8573528147635805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.483937486809797, + "scoreError" : 0.12424298772002351, + "scoreConfidence" : [ + 16.359694499089773, + 16.60818047452982 + ], + "scorePercentiles" : { + "0.0" : 16.440802488419305, + "50.0" : 16.478395945076294, + "90.0" : 16.53481312099235, + "95.0" : 16.53481312099235, + "99.0" : 16.53481312099235, + "99.9" : 16.53481312099235, + "99.99" : 16.53481312099235, + "99.999" : 16.53481312099235, + "99.9999" : 16.53481312099235, + "100.0" : 16.53481312099235 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.44343717796621, + 16.448880022547907, + 16.440802488419305 + ], + [ + 16.52778024332833, + 16.53481312099235, + 16.50791186760468 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2757.119904801759, + "scoreError" : 288.38943624942414, + "scoreConfidence" : [ + 2468.7304685523345, + 3045.509341051183 + ], + "scorePercentiles" : { + "0.0" : 2661.9909168135537, + "50.0" : 2756.459464719503, + "90.0" : 2852.9335470111214, + "95.0" : 2852.9335470111214, + "99.0" : 2852.9335470111214, + "99.9" : 2852.9335470111214, + "99.99" : 2852.9335470111214, + "99.999" : 2852.9335470111214, + "99.9999" : 2852.9335470111214, + "100.0" : 2852.9335470111214 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2852.9335470111214, + 2848.9655643403053, + 2851.07892392382 + ], + [ + 2663.953365098701, + 2661.9909168135537, + 2663.797111623049 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76585.05858938322, + "scoreError" : 1266.263550159021, + "scoreConfidence" : [ + 75318.79503922419, + 77851.32213954224 + ], + "scorePercentiles" : { + "0.0" : 76115.07745482646, + "50.0" : 76610.95525768644, + "90.0" : 77000.19535442891, + "95.0" : 77000.19535442891, + "99.0" : 77000.19535442891, + "99.9" : 77000.19535442891, + "99.99" : 77000.19535442891, + "99.999" : 77000.19535442891, + "99.9999" : 77000.19535442891, + "100.0" : 77000.19535442891 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76177.91179091227, + 76115.07745482646, + 76229.54514109461 + ], + [ + 76992.36537427825, + 77000.19535442891, + 76995.25642075881 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.7264432334691, + "scoreError" : 3.5096609700386523, + "scoreConfidence" : [ + 359.21678226343045, + 366.2361042035078 + ], + "scorePercentiles" : { + "0.0" : 361.6276971707852, + "50.0" : 362.2416763776158, + "90.0" : 364.4246887591129, + "95.0" : 364.4246887591129, + "99.0" : 364.4246887591129, + "99.9" : 364.4246887591129, + "99.99" : 364.4246887591129, + "99.999" : 364.4246887591129, + "99.9999" : 364.4246887591129, + "100.0" : 364.4246887591129 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 362.5172587346009, + 364.1464940256564, + 364.4246887591129 + ], + [ + 361.96609402063075, + 361.6276971707852, + 361.67642669002885 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.12040759178154, + "scoreError" : 5.587069436645381, + "scoreConfidence" : [ + 108.53333815513616, + 119.70747702842692 + ], + "scorePercentiles" : { + "0.0" : 111.26196446325504, + "50.0" : 114.31630357553416, + "90.0" : 116.01487473534624, + "95.0" : 116.01487473534624, + "99.0" : 116.01487473534624, + "99.9" : 116.01487473534624, + "99.99" : 116.01487473534624, + "99.999" : 116.01487473534624, + "99.9999" : 116.01487473534624, + "100.0" : 116.01487473534624 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.96548381306346, + 115.53845946785674, + 116.01487473534624 + ], + [ + 111.26196446325504, + 113.09414768321159, + 112.84751538795616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06039248248481773, + "scoreError" : 6.181374848629453E-4, + "scoreConfidence" : [ + 0.059774344999954786, + 0.06101061996968068 + ], + "scorePercentiles" : { + "0.0" : 0.060203173237732305, + "50.0" : 0.060354282456001385, + "90.0" : 0.060750003942628375, + "95.0" : 0.060750003942628375, + "99.0" : 0.060750003942628375, + "99.9" : 0.060750003942628375, + "99.99" : 0.060750003942628375, + "99.999" : 0.060750003942628375, + "99.9999" : 0.060750003942628375, + "100.0" : 0.060750003942628375 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060481614526254675, + 0.060750003942628375, + 0.06048752949324365 + ], + [ + 0.0602269503857481, + 0.06020562332329922, + 0.060203173237732305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6682822158171725E-4, + "scoreError" : 4.884083095039461E-5, + "scoreConfidence" : [ + 3.1798739063132263E-4, + 4.156690525321119E-4 + ], + "scorePercentiles" : { + "0.0" : 3.508456336502254E-4, + "50.0" : 3.6679063090814466E-4, + "90.0" : 3.829964732939617E-4, + "95.0" : 3.829964732939617E-4, + "99.0" : 3.829964732939617E-4, + "99.9" : 3.829964732939617E-4, + "99.99" : 3.829964732939617E-4, + "99.999" : 3.829964732939617E-4, + "99.9999" : 3.829964732939617E-4, + "100.0" : 3.829964732939617E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5094553394315783E-4, + 3.5099667298510163E-4, + 3.508456336502254E-4 + ], + [ + 3.825845888311877E-4, + 3.829964732939617E-4, + 3.826004267866694E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1240012052451922, + "scoreError" : 5.23147068183301E-4, + "scoreConfidence" : [ + 0.1234780581770089, + 0.12452435231337551 + ], + "scorePercentiles" : { + "0.0" : 0.1237848824192011, + "50.0" : 0.12398571541574485, + "90.0" : 0.12425495182773788, + "95.0" : 0.12425495182773788, + "99.0" : 0.12425495182773788, + "99.9" : 0.12425495182773788, + "99.99" : 0.12425495182773788, + "99.999" : 0.12425495182773788, + "99.9999" : 0.12425495182773788, + "100.0" : 0.12425495182773788 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1237848824192011, + 0.12395541131191433, + 0.12382405558375949 + ], + [ + 0.12425495182773788, + 0.12401601951957539, + 0.12417191080896504 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013177677040063696, + "scoreError" : 3.375376591257966E-4, + "scoreConfidence" : [ + 0.0128401393809379, + 0.013515214699189492 + ], + "scorePercentiles" : { + "0.0" : 0.01306630065108403, + "50.0" : 0.013166360446818431, + "90.0" : 0.013300087010762298, + "95.0" : 0.013300087010762298, + "99.0" : 0.013300087010762298, + "99.9" : 0.013300087010762298, + "99.99" : 0.013300087010762298, + "99.999" : 0.013300087010762298, + "99.9999" : 0.013300087010762298, + "100.0" : 0.013300087010762298 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013262698887938408, + 0.013300087010762298, + 0.013297864781053444 + ], + [ + 0.013070022005698453, + 0.01306630065108403, + 0.013069088903845526 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9885506742744191, + "scoreError" : 0.0632063612825815, + "scoreConfidence" : [ + 0.9253443129918376, + 1.0517570355570007 + ], + "scorePercentiles" : { + "0.0" : 0.9671989556092844, + "50.0" : 0.9886548614717992, + "90.0" : 1.009485964772383, + "95.0" : 1.009485964772383, + "99.0" : 1.009485964772383, + "99.9" : 1.009485964772383, + "99.99" : 1.009485964772383, + "99.999" : 1.009485964772383, + "99.9999" : 1.009485964772383, + "100.0" : 1.009485964772383 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9682148281537419, + 0.9685245988766221, + 0.9671989556092844 + ], + [ + 1.008785124066976, + 1.0090945741675075, + 1.009485964772383 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010733988396759986, + "scoreError" : 0.0010812263513256348, + "scoreConfidence" : [ + 0.009652762045434351, + 0.01181521474808562 + ], + "scorePercentiles" : { + "0.0" : 0.010373753348575506, + "50.0" : 0.010735976162856625, + "90.0" : 0.011094092872896059, + "95.0" : 0.011094092872896059, + "99.0" : 0.011094092872896059, + "99.9" : 0.011094092872896059, + "99.99" : 0.011094092872896059, + "99.999" : 0.011094092872896059, + "99.9999" : 0.011094092872896059, + "100.0" : 0.011094092872896059 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011094092872896059, + 0.011075956253225796, + 0.011087530743030486 + ], + [ + 0.010395996072487453, + 0.010376601090344618, + 0.010373753348575506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0244017929846456, + "scoreError" : 0.02350721394922381, + "scoreConfidence" : [ + 3.000894579035422, + 3.0479090069338692 + ], + "scorePercentiles" : { + "0.0" : 3.0140141271850514, + "50.0" : 3.027378536565311, + "90.0" : 3.033068093389933, + "95.0" : 3.033068093389933, + "99.0" : 3.033068093389933, + "99.9" : 3.033068093389933, + "99.99" : 3.033068093389933, + "99.999" : 3.033068093389933, + "99.9999" : 3.033068093389933, + "100.0" : 3.033068093389933 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0305397575757578, + 3.033068093389933, + 3.029024942459116 + ], + [ + 3.014031706626506, + 3.025732130671506, + 3.0140141271850514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8081195794171196, + "scoreError" : 0.04451368328698103, + "scoreConfidence" : [ + 2.7636058961301386, + 2.8526332627041007 + ], + "scorePercentiles" : { + "0.0" : 2.7892624670942556, + "50.0" : 2.809088813599385, + "90.0" : 2.824478731996611, + "95.0" : 2.824478731996611, + "99.0" : 2.824478731996611, + "99.9" : 2.824478731996611, + "99.99" : 2.824478731996611, + "99.999" : 2.824478731996611, + "99.9999" : 2.824478731996611, + "100.0" : 2.824478731996611 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.824478731996611, + 2.819786429940795, + 2.822643530906012 + ], + [ + 2.7983911972579745, + 2.794155119307069, + 2.7892624670942556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17612863827510697, + "scoreError" : 0.0016477289885006518, + "scoreConfidence" : [ + 0.1744809092866063, + 0.17777636726360763 + ], + "scorePercentiles" : { + "0.0" : 0.1756184496601865, + "50.0" : 0.17597844740560853, + "90.0" : 0.17728533952630832, + "95.0" : 0.17728533952630832, + "99.0" : 0.17728533952630832, + "99.9" : 0.17728533952630832, + "99.99" : 0.17728533952630832, + "99.999" : 0.17728533952630832, + "99.9999" : 0.17728533952630832, + "100.0" : 0.17728533952630832 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17602657610321945, + 0.17605160570744502, + 0.17728533952630832 + ], + [ + 0.17585953994548492, + 0.1759303187079976, + 0.1756184496601865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32291559915548146, + "scoreError" : 3.2985694367027133E-4, + "scoreConfidence" : [ + 0.3225857422118112, + 0.32324545609915173 + ], + "scorePercentiles" : { + "0.0" : 0.32278306817081437, + "50.0" : 0.32292217191202494, + "90.0" : 0.3230849756397002, + "95.0" : 0.3230849756397002, + "99.0" : 0.3230849756397002, + "99.9" : 0.3230849756397002, + "99.99" : 0.3230849756397002, + "99.999" : 0.3230849756397002, + "99.9999" : 0.3230849756397002, + "100.0" : 0.3230849756397002 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32298991101995994, + 0.32279129627836417, + 0.3228915813825837 + ], + [ + 0.3230849756397002, + 0.32278306817081437, + 0.32295276244146615 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14388199181729064, + "scoreError" : 0.004925840882024297, + "scoreConfidence" : [ + 0.13895615093526634, + 0.14880783269931494 + ], + "scorePercentiles" : { + "0.0" : 0.1413976640178723, + "50.0" : 0.14356822943939596, + "90.0" : 0.14681751623038186, + "95.0" : 0.14681751623038186, + "99.0" : 0.14681751623038186, + "99.9" : 0.14681751623038186, + "99.99" : 0.14681751623038186, + "99.999" : 0.14681751623038186, + "99.9999" : 0.14681751623038186, + "100.0" : 0.14681751623038186 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1435107920840389, + 0.14361619035788142, + 0.14352026852091046 + ], + [ + 0.14681751623038186, + 0.14442951969265877, + 0.1413976640178723 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4018423565058164, + "scoreError" : 0.01027690974808848, + "scoreConfidence" : [ + 0.3915654467577279, + 0.4121192662539049 + ], + "scorePercentiles" : { + "0.0" : 0.39786439737417945, + "50.0" : 0.4016776301419805, + "90.0" : 0.4064869786602715, + "95.0" : 0.4064869786602715, + "99.0" : 0.4064869786602715, + "99.9" : 0.4064869786602715, + "99.99" : 0.4064869786602715, + "99.999" : 0.4064869786602715, + "99.9999" : 0.4064869786602715, + "100.0" : 0.4064869786602715 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39786439737417945, + 0.39879919620354126, + 0.3991162329182631 + ], + [ + 0.404548306512945, + 0.4042390273656979, + 0.4064869786602715 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16364278704681767, + "scoreError" : 0.02976645612587646, + "scoreConfidence" : [ + 0.1338763309209412, + 0.19340924317269415 + ], + "scorePercentiles" : { + "0.0" : 0.15386256352027078, + "50.0" : 0.16283202349547626, + "90.0" : 0.176492349482007, + "95.0" : 0.176492349482007, + "99.0" : 0.176492349482007, + "99.9" : 0.176492349482007, + "99.99" : 0.176492349482007, + "99.999" : 0.176492349482007, + "99.9999" : 0.176492349482007, + "100.0" : 0.176492349482007 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1542853183269821, + 0.15386256352027078, + 0.15413900257406207 + ], + [ + 0.176492349482007, + 0.1713787286639704, + 0.17169875971361365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04661222868382268, + "scoreError" : 0.0017142685469840424, + "scoreConfidence" : [ + 0.04489796013683864, + 0.04832649723080672 + ], + "scorePercentiles" : { + "0.0" : 0.04604029042282831, + "50.0" : 0.04661151299084754, + "90.0" : 0.047195157842077694, + "95.0" : 0.047195157842077694, + "99.0" : 0.047195157842077694, + "99.9" : 0.047195157842077694, + "99.99" : 0.047195157842077694, + "99.999" : 0.047195157842077694, + "99.9999" : 0.047195157842077694, + "100.0" : 0.047195157842077694 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046073407637941835, + 0.04604029042282831, + 0.04604954747147291 + ], + [ + 0.04714961834375324, + 0.04716535038486209, + 0.047195157842077694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8684522.139708702, + "scoreError" : 165967.2367030303, + "scoreConfidence" : [ + 8518554.90300567, + 8850489.376411732 + ], + "scorePercentiles" : { + "0.0" : 8632144.482312338, + "50.0" : 8658058.607342992, + "90.0" : 8781617.052677788, + "95.0" : 8781617.052677788, + "99.0" : 8781617.052677788, + "99.9" : 8781617.052677788, + "99.99" : 8781617.052677788, + "99.999" : 8781617.052677788, + "99.9999" : 8781617.052677788, + "100.0" : 8781617.052677788 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8649923.417458946, + 8645169.681071738, + 8666193.797227036 + ], + [ + 8781617.052677788, + 8732084.407504363, + 8632144.482312338 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-31T05:01:42Z-1b2f619e4b944ca224a7296197479e79bc39a9e1-jdk17.json b/performance-results/2025-07-31T05:01:42Z-1b2f619e4b944ca224a7296197479e79bc39a9e1-jdk17.json new file mode 100644 index 0000000000..a4f31fdcb4 --- /dev/null +++ b/performance-results/2025-07-31T05:01:42Z-1b2f619e4b944ca224a7296197479e79bc39a9e1-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.318403365647165, + "scoreError" : 0.020195822723520666, + "scoreConfidence" : [ + 3.2982075429236444, + 3.3385991883706856 + ], + "scorePercentiles" : { + "0.0" : 3.3151508428359695, + "50.0" : 3.318040275916247, + "90.0" : 3.322382067920195, + "95.0" : 3.322382067920195, + "99.0" : 3.322382067920195, + "99.9" : 3.322382067920195, + "99.99" : 3.322382067920195, + "99.999" : 3.322382067920195, + "99.9999" : 3.322382067920195, + "100.0" : 3.322382067920195 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3151508428359695, + 3.319187084887637 + ], + [ + 3.3168934669448573, + 3.322382067920195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6646723633911307, + "scoreError" : 0.05434315514451174, + "scoreConfidence" : [ + 1.610329208246619, + 1.7190155185356424 + ], + "scorePercentiles" : { + "0.0" : 1.6570171460694267, + "50.0" : 1.6646417879500253, + "90.0" : 1.6723887315950448, + "95.0" : 1.6723887315950448, + "99.0" : 1.6723887315950448, + "99.9" : 1.6723887315950448, + "99.99" : 1.6723887315950448, + "99.999" : 1.6723887315950448, + "99.9999" : 1.6723887315950448, + "100.0" : 1.6723887315950448 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6577853765003463, + 1.6570171460694267 + ], + [ + 1.6723887315950448, + 1.6714981993997042 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8398016456176536, + "scoreError" : 0.03432004917268803, + "scoreConfidence" : [ + 0.8054815964449655, + 0.8741216947903416 + ], + "scorePercentiles" : { + "0.0" : 0.8320322913729159, + "50.0" : 0.8415760657814932, + "90.0" : 0.8440221595347125, + "95.0" : 0.8440221595347125, + "99.0" : 0.8440221595347125, + "99.9" : 0.8440221595347125, + "99.99" : 0.8440221595347125, + "99.999" : 0.8440221595347125, + "99.9999" : 0.8440221595347125, + "100.0" : 0.8440221595347125 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8320322913729159, + 0.8418494852989352 + ], + [ + 0.8413026462640512, + 0.8440221595347125 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.04832769592115, + "scoreError" : 0.27187067208350196, + "scoreConfidence" : [ + 15.776457023837647, + 16.32019836800465 + ], + "scorePercentiles" : { + "0.0" : 15.894931377249218, + "50.0" : 16.09193448463687, + "90.0" : 16.148261716250115, + "95.0" : 16.148261716250115, + "99.0" : 16.148261716250115, + "99.9" : 16.148261716250115, + "99.99" : 16.148261716250115, + "99.999" : 16.148261716250115, + "99.9999" : 16.148261716250115, + "100.0" : 16.148261716250115 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.894931377249218, + 15.964115685485288, + 16.0874696157206 + ], + [ + 16.098788427268538, + 16.09639935355314, + 16.148261716250115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2647.9264001933484, + "scoreError" : 141.246126687054, + "scoreConfidence" : [ + 2506.6802735062943, + 2789.1725268804025 + ], + "scorePercentiles" : { + "0.0" : 2588.698634241166, + "50.0" : 2647.3617284989086, + "90.0" : 2704.505620773411, + "95.0" : 2704.505620773411, + "99.0" : 2704.505620773411, + "99.9" : 2704.505620773411, + "99.99" : 2704.505620773411, + "99.999" : 2704.505620773411, + "99.9999" : 2704.505620773411, + "100.0" : 2704.505620773411 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2618.1870490834576, + 2588.698634241166, + 2603.6292320701937 + ], + [ + 2676.53640791436, + 2704.505620773411, + 2696.0014570775043 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74665.97443450178, + "scoreError" : 3158.7404424063757, + "scoreConfidence" : [ + 71507.23399209541, + 77824.71487690815 + ], + "scorePercentiles" : { + "0.0" : 73582.99072670742, + "50.0" : 74651.26138451396, + "90.0" : 75772.54357622322, + "95.0" : 75772.54357622322, + "99.0" : 75772.54357622322, + "99.9" : 75772.54357622322, + "99.99" : 75772.54357622322, + "99.999" : 75772.54357622322, + "99.9999" : 75772.54357622322, + "100.0" : 75772.54357622322 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73740.63996323425, + 73599.30538572317, + 73582.99072670742 + ], + [ + 75772.54357622322, + 75561.88280579365, + 75738.48414932893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 344.0629998053023, + "scoreError" : 18.94138527021444, + "scoreConfidence" : [ + 325.1216145350879, + 363.0043850755167 + ], + "scorePercentiles" : { + "0.0" : 337.25004844514956, + "50.0" : 343.62889235954134, + "90.0" : 352.3469807290136, + "95.0" : 352.3469807290136, + "99.0" : 352.3469807290136, + "99.9" : 352.3469807290136, + "99.99" : 352.3469807290136, + "99.999" : 352.3469807290136, + "99.9999" : 352.3469807290136, + "100.0" : 352.3469807290136 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.29597583092163, + 352.3469807290136, + 348.69201906732917 + ], + [ + 338.22720910764633, + 337.25004844514956, + 338.5657656517535 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.35505918929802, + "scoreError" : 9.190780657305664, + "scoreConfidence" : [ + 97.16427853199235, + 115.54583984660368 + ], + "scorePercentiles" : { + "0.0" : 102.85647297148368, + "50.0" : 105.68465179322885, + "90.0" : 112.16757070644547, + "95.0" : 112.16757070644547, + "99.0" : 112.16757070644547, + "99.9" : 112.16757070644547, + "99.99" : 112.16757070644547, + "99.999" : 112.16757070644547, + "99.9999" : 112.16757070644547, + "100.0" : 112.16757070644547 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.94208342292123, + 107.62640252596964, + 112.16757070644547 + ], + [ + 105.42722016353646, + 102.85647297148368, + 104.11060534543167 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06254438412278612, + "scoreError" : 0.0015033842946808585, + "scoreConfidence" : [ + 0.061040999828105263, + 0.06404776841746698 + ], + "scorePercentiles" : { + "0.0" : 0.06179052928200692, + "50.0" : 0.06264674495475323, + "90.0" : 0.06306537395943695, + "95.0" : 0.06306537395943695, + "99.0" : 0.06306537395943695, + "99.9" : 0.06306537395943695, + "99.99" : 0.06306537395943695, + "99.999" : 0.06306537395943695, + "99.9999" : 0.06306537395943695, + "100.0" : 0.06306537395943695 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06296256803314298, + 0.06306537395943695, + 0.06299236989140294 + ], + [ + 0.06212454169436351, + 0.06179052928200692, + 0.06233092187636346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.9458640404245714E-4, + "scoreError" : 9.70964383767474E-6, + "scoreConfidence" : [ + 3.848767602047824E-4, + 4.042960478801319E-4 + ], + "scorePercentiles" : { + "0.0" : 3.903585827686922E-4, + "50.0" : 3.9492492658870957E-4, + "90.0" : 3.980631731868366E-4, + "95.0" : 3.980631731868366E-4, + "99.0" : 3.980631731868366E-4, + "99.9" : 3.980631731868366E-4, + "99.99" : 3.980631731868366E-4, + "99.999" : 3.980631731868366E-4, + "99.9999" : 3.980631731868366E-4, + "100.0" : 3.980631731868366E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9257645310684854E-4, + 3.9156388434290256E-4, + 3.903585827686922E-4 + ], + [ + 3.972734000705706E-4, + 3.976829307788922E-4, + 3.980631731868366E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1255006748516653, + "scoreError" : 0.002253001087482237, + "scoreConfidence" : [ + 0.12324767376418307, + 0.12775367593914755 + ], + "scorePercentiles" : { + "0.0" : 0.12461556924783172, + "50.0" : 0.12547914510805042, + "90.0" : 0.1263697855662547, + "95.0" : 0.1263697855662547, + "99.0" : 0.1263697855662547, + "99.9" : 0.1263697855662547, + "99.99" : 0.1263697855662547, + "99.999" : 0.1263697855662547, + "99.9999" : 0.1263697855662547, + "100.0" : 0.1263697855662547 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1262420374297797, + 0.12605911880751292, + 0.1263697855662547 + ], + [ + 0.12481836665002496, + 0.12489917140858792, + 0.12461556924783172 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01319577608563824, + "scoreError" : 3.907740862088009E-5, + "scoreConfidence" : [ + 0.01315669867701736, + 0.013234853494259121 + ], + "scorePercentiles" : { + "0.0" : 0.013177232390208935, + "50.0" : 0.013198787004726969, + "90.0" : 0.013212527298022905, + "95.0" : 0.013212527298022905, + "99.0" : 0.013212527298022905, + "99.9" : 0.013212527298022905, + "99.99" : 0.013212527298022905, + "99.999" : 0.013212527298022905, + "99.9999" : 0.013212527298022905, + "100.0" : 0.013212527298022905 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013212527298022905, + 0.013201464978310288, + 0.01319610903114365 + ], + [ + 0.013181310612631185, + 0.013177232390208935, + 0.013206012203512488 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9594635033562505, + "scoreError" : 0.016855352369805343, + "scoreConfidence" : [ + 0.9426081509864452, + 0.9763188557260558 + ], + "scorePercentiles" : { + "0.0" : 0.9520353520228463, + "50.0" : 0.9592794800224103, + "90.0" : 0.9669648454844324, + "95.0" : 0.9669648454844324, + "99.0" : 0.9669648454844324, + "99.9" : 0.9669648454844324, + "99.99" : 0.9669648454844324, + "99.999" : 0.9669648454844324, + "99.9999" : 0.9669648454844324, + "100.0" : 0.9669648454844324 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9552573530423154, + 0.9553309745892243, + 0.9520353520228463 + ], + [ + 0.9639645095430885, + 0.9632279854555962, + 0.9669648454844324 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011122006218449066, + "scoreError" : 0.0014124151794276225, + "scoreConfidence" : [ + 0.009709591039021444, + 0.012534421397876689 + ], + "scorePercentiles" : { + "0.0" : 0.010642811646335883, + "50.0" : 0.011116983379102878, + "90.0" : 0.011621793595158018, + "95.0" : 0.011621793595158018, + "99.0" : 0.011621793595158018, + "99.9" : 0.011621793595158018, + "99.99" : 0.011621793595158018, + "99.999" : 0.011621793595158018, + "99.9999" : 0.011621793595158018, + "100.0" : 0.011621793595158018 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011548253599490044, + 0.011573330450884177, + 0.011621793595158018 + ], + [ + 0.010642811646335883, + 0.010660134860110564, + 0.01068571315871571 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.389075628542314, + "scoreError" : 0.08934401070662355, + "scoreConfidence" : [ + 3.29973161783569, + 3.4784196392489375 + ], + "scorePercentiles" : { + "0.0" : 3.332509489673551, + "50.0" : 3.4006833887686287, + "90.0" : 3.4159558674863386, + "95.0" : 3.4159558674863386, + "99.0" : 3.4159558674863386, + "99.9" : 3.4159558674863386, + "99.99" : 3.4159558674863386, + "99.999" : 3.4159558674863386, + "99.9999" : 3.4159558674863386, + "100.0" : 3.4159558674863386 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.393344762550882, + 3.3728789298718813, + 3.332509489673551 + ], + [ + 3.408022014986376, + 3.4159558674863386, + 3.4117427066848567 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.92610005753114, + "scoreError" : 0.10223805544992967, + "scoreConfidence" : [ + 2.8238620020812104, + 3.02833811298107 + ], + "scorePercentiles" : { + "0.0" : 2.8899446047385147, + "50.0" : 2.9219609696081195, + "90.0" : 2.980806488822653, + "95.0" : 2.980806488822653, + "99.0" : 2.980806488822653, + "99.9" : 2.980806488822653, + "99.99" : 2.980806488822653, + "99.999" : 2.980806488822653, + "99.9999" : 2.980806488822653, + "100.0" : 2.980806488822653 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.980806488822653, + 2.947704010904804, + 2.942322551632833 + ], + [ + 2.8899446047385147, + 2.901599387583406, + 2.8942233015046295 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18184344814445005, + "scoreError" : 0.0072012532464625694, + "scoreConfidence" : [ + 0.1746421948979875, + 0.18904470139091262 + ], + "scorePercentiles" : { + "0.0" : 0.17927036310345446, + "50.0" : 0.1817668604106166, + "90.0" : 0.18496747709238878, + "95.0" : 0.18496747709238878, + "99.0" : 0.18496747709238878, + "99.9" : 0.18496747709238878, + "99.99" : 0.18496747709238878, + "99.999" : 0.18496747709238878, + "99.9999" : 0.18496747709238878, + "100.0" : 0.18496747709238878 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17939653808481631, + 0.17927036310345446, + 0.1799786145456509 + ], + [ + 0.18496747709238878, + 0.1835551062755823, + 0.18389258976480757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3337631399472168, + "scoreError" : 0.030501669192729765, + "scoreConfidence" : [ + 0.303261470754487, + 0.3642648091399466 + ], + "scorePercentiles" : { + "0.0" : 0.32348158958434414, + "50.0" : 0.33328192560874653, + "90.0" : 0.34450988772908914, + "95.0" : 0.34450988772908914, + "99.0" : 0.34450988772908914, + "99.9" : 0.34450988772908914, + "99.99" : 0.34450988772908914, + "99.999" : 0.34450988772908914, + "99.9999" : 0.34450988772908914, + "100.0" : 0.34450988772908914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.34450988772908914, + 0.3441212088365851, + 0.3423751785750967 + ], + [ + 0.3239023023157895, + 0.32418867264239637, + 0.32348158958434414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15040484837488619, + "scoreError" : 0.0035886436967529182, + "scoreConfidence" : [ + 0.14681620467813328, + 0.1539934920716391 + ], + "scorePercentiles" : { + "0.0" : 0.14919495652563108, + "50.0" : 0.1502442421332506, + "90.0" : 0.15176951359062693, + "95.0" : 0.15176951359062693, + "99.0" : 0.15176951359062693, + "99.9" : 0.15176951359062693, + "99.99" : 0.15176951359062693, + "99.999" : 0.15176951359062693, + "99.9999" : 0.15176951359062693, + "100.0" : 0.15176951359062693 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15176951359062693, + 0.15174155141647572, + 0.15115383114920117 + ], + [ + 0.1492345844500821, + 0.14933465311730007, + 0.14919495652563108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.41562631564230706, + "scoreError" : 0.009840468667838151, + "scoreConfidence" : [ + 0.4057858469744689, + 0.42546678431014523 + ], + "scorePercentiles" : { + "0.0" : 0.4124977937548983, + "50.0" : 0.41429262462655747, + "90.0" : 0.42002929736654204, + "95.0" : 0.42002929736654204, + "99.0" : 0.42002929736654204, + "99.9" : 0.42002929736654204, + "99.99" : 0.42002929736654204, + "99.999" : 0.42002929736654204, + "99.9999" : 0.42002929736654204, + "100.0" : 0.42002929736654204 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4124977937548983, + 0.41304656189335426, + 0.4128038415686274 + ], + [ + 0.42002929736654204, + 0.41984171191065955, + 0.4155386873597607 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16031556314285697, + "scoreError" : 0.0028330169401163583, + "scoreConfidence" : [ + 0.1574825462027406, + 0.16314858008297334 + ], + "scorePercentiles" : { + "0.0" : 0.15926494830387003, + "50.0" : 0.16029965080255174, + "90.0" : 0.16164282374810074, + "95.0" : 0.16164282374810074, + "99.0" : 0.16164282374810074, + "99.9" : 0.16164282374810074, + "99.99" : 0.16164282374810074, + "99.999" : 0.16164282374810074, + "99.9999" : 0.16164282374810074, + "100.0" : 0.16164282374810074 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16164282374810074, + 0.15975494800070292, + 0.1592948068431616 + ], + [ + 0.16084435360440055, + 0.15926494830387003, + 0.16109149835690584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04628224904856556, + "scoreError" : 0.004966382401929507, + "scoreConfidence" : [ + 0.04131586664663605, + 0.05124863145049507 + ], + "scorePercentiles" : { + "0.0" : 0.044660849366274555, + "50.0" : 0.046199723221185846, + "90.0" : 0.04825054774334874, + "95.0" : 0.04825054774334874, + "99.0" : 0.04825054774334874, + "99.9" : 0.04825054774334874, + "99.99" : 0.04825054774334874, + "99.999" : 0.04825054774334874, + "99.9999" : 0.04825054774334874, + "100.0" : 0.04825054774334874 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.044669575807388215, + 0.044660849366274555, + 0.04469663826240089 + ], + [ + 0.04825054774334874, + 0.047713074932010116, + 0.04770280817997081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9252879.439628795, + "scoreError" : 627035.8808514815, + "scoreConfidence" : [ + 8625843.558777314, + 9879915.320480276 + ], + "scorePercentiles" : { + "0.0" : 9035202.729900632, + "50.0" : 9197328.971140334, + "90.0" : 9658543.075289575, + "95.0" : 9658543.075289575, + "99.0" : 9658543.075289575, + "99.9" : 9658543.075289575, + "99.99" : 9658543.075289575, + "99.999" : 9658543.075289575, + "99.9999" : 9658543.075289575, + "100.0" : 9658543.075289575 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9035202.729900632, + 9094981.092727272, + 9183404.227731865 + ], + [ + 9658543.075289575, + 9211253.714548804, + 9333891.797574626 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-07-31T22:55:18Z-d61c53a270cff0016e5a0f1f4a43a367f0e76ec8-jdk17.json b/performance-results/2025-07-31T22:55:18Z-d61c53a270cff0016e5a0f1f4a43a367f0e76ec8-jdk17.json new file mode 100644 index 0000000000..ec6df10b4e --- /dev/null +++ b/performance-results/2025-07-31T22:55:18Z-d61c53a270cff0016e5a0f1f4a43a367f0e76ec8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3447429434627516, + "scoreError" : 0.03581451591722982, + "scoreConfidence" : [ + 3.308928427545522, + 3.380557459379981 + ], + "scorePercentiles" : { + "0.0" : 3.337836809185784, + "50.0" : 3.345077001097102, + "90.0" : 3.3509809624710187, + "95.0" : 3.3509809624710187, + "99.0" : 3.3509809624710187, + "99.9" : 3.3509809624710187, + "99.99" : 3.3509809624710187, + "99.999" : 3.3509809624710187, + "99.9999" : 3.3509809624710187, + "100.0" : 3.3509809624710187 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.337836809185784, + 3.346708212858601 + ], + [ + 3.343445789335603, + 3.3509809624710187 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6833351354222796, + "scoreError" : 0.029750920572430017, + "scoreConfidence" : [ + 1.6535842148498496, + 1.7130860559947096 + ], + "scorePercentiles" : { + "0.0" : 1.6779923228996667, + "50.0" : 1.6834081003792578, + "90.0" : 1.6885320180309362, + "95.0" : 1.6885320180309362, + "99.0" : 1.6885320180309362, + "99.9" : 1.6885320180309362, + "99.99" : 1.6885320180309362, + "99.999" : 1.6885320180309362, + "99.9999" : 1.6885320180309362, + "100.0" : 1.6885320180309362 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6885320180309362, + 1.6854113765992647 + ], + [ + 1.6779923228996667, + 1.6814048241592512 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8509271113617204, + "scoreError" : 0.01930545126804809, + "scoreConfidence" : [ + 0.8316216600936723, + 0.8702325626297684 + ], + "scorePercentiles" : { + "0.0" : 0.848026120672921, + "50.0" : 0.8503695143478552, + "90.0" : 0.8549432960782498, + "95.0" : 0.8549432960782498, + "99.0" : 0.8549432960782498, + "99.9" : 0.8549432960782498, + "99.99" : 0.8549432960782498, + "99.999" : 0.8549432960782498, + "99.9999" : 0.8549432960782498, + "100.0" : 0.8549432960782498 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8494726115078388, + 0.8512664171878717 + ], + [ + 0.848026120672921, + 0.8549432960782498 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.23359191816515, + "scoreError" : 0.20565572903796425, + "scoreConfidence" : [ + 16.027936189127185, + 16.439247647203114 + ], + "scorePercentiles" : { + "0.0" : 16.146802884674425, + "50.0" : 16.240562669235327, + "90.0" : 16.30811201802358, + "95.0" : 16.30811201802358, + "99.0" : 16.30811201802358, + "99.9" : 16.30811201802358, + "99.99" : 16.30811201802358, + "99.999" : 16.30811201802358, + "99.9999" : 16.30811201802358, + "100.0" : 16.30811201802358 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.29560499740361, + 16.294454506118964, + 16.30811201802358 + ], + [ + 16.16990627041862, + 16.18667083235169, + 16.146802884674425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2742.3468009268727, + "scoreError" : 14.196156095864847, + "scoreConfidence" : [ + 2728.150644831008, + 2756.5429570227375 + ], + "scorePercentiles" : { + "0.0" : 2738.059704068701, + "50.0" : 2739.686991758973, + "90.0" : 2749.215413532476, + "95.0" : 2749.215413532476, + "99.0" : 2749.215413532476, + "99.9" : 2749.215413532476, + "99.99" : 2749.215413532476, + "99.999" : 2749.215413532476, + "99.9999" : 2749.215413532476, + "100.0" : 2749.215413532476 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2749.215413532476, + 2748.4145869528884, + 2738.059704068701 + ], + [ + 2739.1708541459966, + 2739.0171174892253, + 2740.2031293719497 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75882.37380601972, + "scoreError" : 216.86245467898758, + "scoreConfidence" : [ + 75665.51135134073, + 76099.23626069872 + ], + "scorePercentiles" : { + "0.0" : 75791.66267788902, + "50.0" : 75883.50426015347, + "90.0" : 75960.92447942347, + "95.0" : 75960.92447942347, + "99.0" : 75960.92447942347, + "99.9" : 75960.92447942347, + "99.99" : 75960.92447942347, + "99.999" : 75960.92447942347, + "99.9999" : 75960.92447942347, + "100.0" : 75960.92447942347 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75818.68947607337, + 75791.66267788902, + 75828.58548661624 + ], + [ + 75960.92447942347, + 75955.95768242556, + 75938.42303369069 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 358.20639413166924, + "scoreError" : 2.503616116668585, + "scoreConfidence" : [ + 355.70277801500066, + 360.7100102483378 + ], + "scorePercentiles" : { + "0.0" : 357.1544925888796, + "50.0" : 358.1230203107281, + "90.0" : 359.6826421832757, + "95.0" : 359.6826421832757, + "99.0" : 359.6826421832757, + "99.9" : 359.6826421832757, + "99.99" : 359.6826421832757, + "99.999" : 359.6826421832757, + "99.9999" : 359.6826421832757, + "100.0" : 359.6826421832757 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 357.9541121441845, + 358.62332116975807, + 359.6826421832757 + ], + [ + 357.1544925888796, + 358.29192847727177, + 357.5318682266461 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.45953970685032, + "scoreError" : 8.540372108085162, + "scoreConfidence" : [ + 105.91916759876516, + 122.99991181493549 + ], + "scorePercentiles" : { + "0.0" : 110.93164893203861, + "50.0" : 114.61952880377628, + "90.0" : 117.37124946643245, + "95.0" : 117.37124946643245, + "99.0" : 117.37124946643245, + "99.9" : 117.37124946643245, + "99.99" : 117.37124946643245, + "99.999" : 117.37124946643245, + "99.9999" : 117.37124946643245, + "100.0" : 117.37124946643245 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.16683158143142, + 117.09538384235908, + 117.37124946643245 + ], + [ + 110.93164893203861, + 112.14367376519347, + 112.04845065364694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06161090972431956, + "scoreError" : 0.001154035149373283, + "scoreConfidence" : [ + 0.06045687457494628, + 0.06276494487369284 + ], + "scorePercentiles" : { + "0.0" : 0.061172217654075545, + "50.0" : 0.06162349173350587, + "90.0" : 0.06210324555193293, + "95.0" : 0.06210324555193293, + "99.0" : 0.06210324555193293, + "99.9" : 0.06210324555193293, + "99.99" : 0.06210324555193293, + "99.999" : 0.06210324555193293, + "99.9999" : 0.06210324555193293, + "100.0" : 0.06210324555193293 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061172217654075545, + 0.06133272215543889, + 0.06122548204588173 + ], + [ + 0.06191752962701538, + 0.06210324555193293, + 0.06191426131157285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.759438405070489E-4, + "scoreError" : 1.5227227062947226E-5, + "scoreConfidence" : [ + 3.607166134441017E-4, + 3.911710675699961E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7057527735488406E-4, + "50.0" : 3.7597120138570115E-4, + "90.0" : 3.811299878352407E-4, + "95.0" : 3.811299878352407E-4, + "99.0" : 3.811299878352407E-4, + "99.9" : 3.811299878352407E-4, + "99.99" : 3.811299878352407E-4, + "99.999" : 3.811299878352407E-4, + "99.9999" : 3.811299878352407E-4, + "100.0" : 3.811299878352407E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.811299878352407E-4, + 3.80545023616607E-4, + 3.810010383679906E-4 + ], + [ + 3.7057527735488406E-4, + 3.710143367127759E-4, + 3.7139737915479527E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12403572272138354, + "scoreError" : 0.0016099867476702095, + "scoreConfidence" : [ + 0.12242573597371333, + 0.12564570946905373 + ], + "scorePercentiles" : { + "0.0" : 0.12342072772937082, + "50.0" : 0.12401077159131019, + "90.0" : 0.12463167110346718, + "95.0" : 0.12463167110346718, + "99.0" : 0.12463167110346718, + "99.9" : 0.12463167110346718, + "99.99" : 0.12463167110346718, + "99.999" : 0.12463167110346718, + "99.9999" : 0.12463167110346718, + "100.0" : 0.12463167110346718 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12445210571969037, + 0.12463167110346718, + 0.1245808918787607 + ], + [ + 0.12342072772937082, + 0.12356943746293002, + 0.12355950243408209 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013001622683439037, + "scoreError" : 3.24255455442878E-4, + "scoreConfidence" : [ + 0.012677367227996159, + 0.013325878138881916 + ], + "scorePercentiles" : { + "0.0" : 0.012887285901516811, + "50.0" : 0.013007222950893977, + "90.0" : 0.01311277812089003, + "95.0" : 0.01311277812089003, + "99.0" : 0.01311277812089003, + "99.9" : 0.01311277812089003, + "99.99" : 0.01311277812089003, + "99.999" : 0.01311277812089003, + "99.9999" : 0.01311277812089003, + "100.0" : 0.01311277812089003 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012887285901516811, + 0.012890106533732052, + 0.0129117874132664 + ], + [ + 0.013102658488521553, + 0.01311277812089003, + 0.013105119642707372 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9898452145949371, + "scoreError" : 0.028663340129279874, + "scoreConfidence" : [ + 0.9611818744656573, + 1.018508554724217 + ], + "scorePercentiles" : { + "0.0" : 0.9803023719858851, + "50.0" : 0.9895225049491614, + "90.0" : 0.9996415455817673, + "95.0" : 0.9996415455817673, + "99.0" : 0.9996415455817673, + "99.9" : 0.9996415455817673, + "99.99" : 0.9996415455817673, + "99.999" : 0.9996415455817673, + "99.9999" : 0.9996415455817673, + "100.0" : 0.9996415455817673 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9996415455817673, + 0.9994696580051969, + 0.9983908891883797 + ], + [ + 0.9806541207099432, + 0.9803023719858851, + 0.9806127020984506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010542894109932498, + "scoreError" : 2.009888932115536E-4, + "scoreConfidence" : [ + 0.010341905216720943, + 0.010743883003144052 + ], + "scorePercentiles" : { + "0.0" : 0.01047359392464244, + "50.0" : 0.010543936494095782, + "90.0" : 0.01060966379222543, + "95.0" : 0.01060966379222543, + "99.0" : 0.01060966379222543, + "99.9" : 0.01060966379222543, + "99.99" : 0.01060966379222543, + "99.999" : 0.01060966379222543, + "99.9999" : 0.01060966379222543, + "100.0" : 0.01060966379222543 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010477509751124726, + 0.01047359392464244, + 0.010481427978794542 + ], + [ + 0.010608724203410832, + 0.01060644500939702, + 0.01060966379222543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.148146948868682, + "scoreError" : 0.26140079187105253, + "scoreConfidence" : [ + 2.8867461569976296, + 3.4095477407397343 + ], + "scorePercentiles" : { + "0.0" : 3.0555105430665854, + "50.0" : 3.149699198716333, + "90.0" : 3.236624098381877, + "95.0" : 3.236624098381877, + "99.0" : 3.236624098381877, + "99.9" : 3.236624098381877, + "99.99" : 3.236624098381877, + "99.999" : 3.236624098381877, + "99.9999" : 3.236624098381877, + "100.0" : 3.236624098381877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.236624098381877, + 3.232234904330963, + 3.2305329489664083 + ], + [ + 3.0555105430665854, + 3.0688654484662576, + 3.06511375 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8055585408599355, + "scoreError" : 0.06611911919208836, + "scoreConfidence" : [ + 2.7394394216678473, + 2.8716776600520237 + ], + "scorePercentiles" : { + "0.0" : 2.785817532590529, + "50.0" : 2.796373105520504, + "90.0" : 2.84690062852263, + "95.0" : 2.84690062852263, + "99.0" : 2.84690062852263, + "99.9" : 2.84690062852263, + "99.99" : 2.84690062852263, + "99.999" : 2.84690062852263, + "99.9999" : 2.84690062852263, + "100.0" : 2.84690062852263 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.785817532590529, + 2.790505919642857, + 2.789143199386503 + ], + [ + 2.802240291398151, + 2.81874367361894, + 2.84690062852263 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17818622258417713, + "scoreError" : 9.51045486120946E-4, + "scoreConfidence" : [ + 0.1772351770980562, + 0.17913726807029806 + ], + "scorePercentiles" : { + "0.0" : 0.1777865706945901, + "50.0" : 0.17822540837365275, + "90.0" : 0.1786671407514606, + "95.0" : 0.1786671407514606, + "99.0" : 0.1786671407514606, + "99.9" : 0.1786671407514606, + "99.99" : 0.1786671407514606, + "99.999" : 0.1786671407514606, + "99.9999" : 0.1786671407514606, + "100.0" : 0.1786671407514606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1786671407514606, + 0.17831284710161724, + 0.1783830009989119 + ], + [ + 0.17782980631279452, + 0.1777865706945901, + 0.17813796964568823 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3346599006855217, + "scoreError" : 0.010793068198533514, + "scoreConfidence" : [ + 0.32386683248698817, + 0.34545296888405524 + ], + "scorePercentiles" : { + "0.0" : 0.3309993482391103, + "50.0" : 0.3346490690556416, + "90.0" : 0.33853017345971564, + "95.0" : 0.33853017345971564, + "99.0" : 0.33853017345971564, + "99.9" : 0.33853017345971564, + "99.99" : 0.33853017345971564, + "99.999" : 0.33853017345971564, + "99.9999" : 0.33853017345971564, + "100.0" : 0.33853017345971564 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3310541459595458, + 0.3314079576139188, + 0.3309993482391103 + ], + [ + 0.3378901804973645, + 0.33853017345971564, + 0.33807759834347534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14282208398860097, + "scoreError" : 0.0023631804398264182, + "scoreConfidence" : [ + 0.14045890354877455, + 0.14518526442842739 + ], + "scorePercentiles" : { + "0.0" : 0.14186982019634548, + "50.0" : 0.14302447002571195, + "90.0" : 0.14356884727366698, + "95.0" : 0.14356884727366698, + "99.0" : 0.14356884727366698, + "99.9" : 0.14356884727366698, + "99.99" : 0.14356884727366698, + "99.999" : 0.14356884727366698, + "99.9999" : 0.14356884727366698, + "100.0" : 0.14356884727366698 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14356884727366698, + 0.14355641794430088, + 0.14356471303261745 + ], + [ + 0.14249252210712302, + 0.14188018337755204, + 0.14186982019634548 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40609635142939066, + "scoreError" : 0.005372799986368221, + "scoreConfidence" : [ + 0.4007235514430224, + 0.4114691514157589 + ], + "scorePercentiles" : { + "0.0" : 0.40335263808333, + "50.0" : 0.4059603653504845, + "90.0" : 0.40936235646158253, + "95.0" : 0.40936235646158253, + "99.0" : 0.40936235646158253, + "99.9" : 0.40936235646158253, + "99.99" : 0.40936235646158253, + "99.999" : 0.40936235646158253, + "99.9999" : 0.40936235646158253, + "100.0" : 0.40936235646158253 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40613637062908664, + 0.4060972901928934, + 0.4058234405080756 + ], + [ + 0.40936235646158253, + 0.4058060127013756, + 0.40335263808333 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1536626369787302, + "scoreError" : 0.0018848814311616332, + "scoreConfidence" : [ + 0.15177775554756856, + 0.15554751840989184 + ], + "scorePercentiles" : { + "0.0" : 0.15280170508510835, + "50.0" : 0.15367310626538933, + "90.0" : 0.15464760590736876, + "95.0" : 0.15464760590736876, + "99.0" : 0.15464760590736876, + "99.9" : 0.15464760590736876, + "99.99" : 0.15464760590736876, + "99.999" : 0.15464760590736876, + "99.9999" : 0.15464760590736876, + "100.0" : 0.15464760590736876 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15464760590736876, + 0.1540523418060819, + 0.153907308949596 + ], + [ + 0.15343890358118267, + 0.15280170508510835, + 0.1531279565430435 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04684310548716889, + "scoreError" : 0.003715849866710442, + "scoreConfidence" : [ + 0.04312725562045845, + 0.05055895535387933 + ], + "scorePercentiles" : { + "0.0" : 0.045580877894919165, + "50.0" : 0.04688522018283306, + "90.0" : 0.04809616717487495, + "95.0" : 0.04809616717487495, + "99.0" : 0.04809616717487495, + "99.9" : 0.04809616717487495, + "99.99" : 0.04809616717487495, + "99.999" : 0.04809616717487495, + "99.9999" : 0.04809616717487495, + "100.0" : 0.04809616717487495 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04809616717487495, + 0.04802994055406665, + 0.04802794923036285 + ], + [ + 0.045742491135303265, + 0.045580877894919165, + 0.04558120693348648 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8650758.197539447, + "scoreError" : 323224.16376427445, + "scoreConfidence" : [ + 8327534.033775172, + 8973982.36130372 + ], + "scorePercentiles" : { + "0.0" : 8534389.760238908, + "50.0" : 8652048.152955076, + "90.0" : 8767666.733567046, + "95.0" : 8767666.733567046, + "99.0" : 8767666.733567046, + "99.9" : 8767666.733567046, + "99.99" : 8767666.733567046, + "99.999" : 8767666.733567046, + "99.9999" : 8767666.733567046, + "100.0" : 8767666.733567046 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8767666.733567046, + 8760342.227670753, + 8737214.230567686 + ], + [ + 8566882.075342465, + 8538054.15784983, + 8534389.760238908 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-02T02:49:39Z-141af0809b409b0c1845c37ecddd9072f3e3b87c-jdk17.json b/performance-results/2025-08-02T02:49:39Z-141af0809b409b0c1845c37ecddd9072f3e3b87c-jdk17.json new file mode 100644 index 0000000000..1cb62b413b --- /dev/null +++ b/performance-results/2025-08-02T02:49:39Z-141af0809b409b0c1845c37ecddd9072f3e3b87c-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3538692326094255, + "scoreError" : 0.03612309866043596, + "scoreConfidence" : [ + 3.3177461339489893, + 3.3899923312698617 + ], + "scorePercentiles" : { + "0.0" : 3.348261028598882, + "50.0" : 3.3532623470115914, + "90.0" : 3.3606912078156372, + "95.0" : 3.3606912078156372, + "99.0" : 3.3606912078156372, + "99.9" : 3.3606912078156372, + "99.99" : 3.3606912078156372, + "99.999" : 3.3606912078156372, + "99.9999" : 3.3606912078156372, + "100.0" : 3.3606912078156372 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3505219653067173, + 3.3606912078156372 + ], + [ + 3.348261028598882, + 3.3560027287164655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6945835007607855, + "scoreError" : 0.015589009096169493, + "scoreConfidence" : [ + 1.678994491664616, + 1.710172509856955 + ], + "scorePercentiles" : { + "0.0" : 1.6910643592749353, + "50.0" : 1.6954557765435476, + "90.0" : 1.6963580906811107, + "95.0" : 1.6963580906811107, + "99.0" : 1.6963580906811107, + "99.9" : 1.6963580906811107, + "99.99" : 1.6963580906811107, + "99.999" : 1.6963580906811107, + "99.9999" : 1.6963580906811107, + "100.0" : 1.6963580906811107 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6959052220868958, + 1.6963580906811107 + ], + [ + 1.6910643592749353, + 1.6950063310001997 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8529746015749877, + "scoreError" : 0.041808631673772065, + "scoreConfidence" : [ + 0.8111659699012157, + 0.8947832332487597 + ], + "scorePercentiles" : { + "0.0" : 0.8437251175707257, + "50.0" : 0.8546738574637633, + "90.0" : 0.8588255738016985, + "95.0" : 0.8588255738016985, + "99.0" : 0.8588255738016985, + "99.9" : 0.8588255738016985, + "99.99" : 0.8588255738016985, + "99.999" : 0.8588255738016985, + "99.9999" : 0.8588255738016985, + "100.0" : 0.8588255738016985 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8545782280814558, + 0.8547694868460708 + ], + [ + 0.8437251175707257, + 0.8588255738016985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.570208179654887, + "scoreError" : 0.25431646247726825, + "scoreConfidence" : [ + 16.31589171717762, + 16.824524642132154 + ], + "scorePercentiles" : { + "0.0" : 16.47710476158917, + "50.0" : 16.57294711407239, + "90.0" : 16.65673234796492, + "95.0" : 16.65673234796492, + "99.0" : 16.65673234796492, + "99.9" : 16.65673234796492, + "99.99" : 16.65673234796492, + "99.999" : 16.65673234796492, + "99.9999" : 16.65673234796492, + "100.0" : 16.65673234796492 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.489999214169334, + 16.47710476158917, + 16.495777203084362 + ], + [ + 16.65151852606114, + 16.650117025060418, + 16.65673234796492 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2780.459318554716, + "scoreError" : 29.84078468038006, + "scoreConfidence" : [ + 2750.6185338743358, + 2810.3001032350962 + ], + "scorePercentiles" : { + "0.0" : 2768.0277428002055, + "50.0" : 2781.6714029216055, + "90.0" : 2790.358083526049, + "95.0" : 2790.358083526049, + "99.0" : 2790.358083526049, + "99.9" : 2790.358083526049, + "99.99" : 2790.358083526049, + "99.999" : 2790.358083526049, + "99.9999" : 2790.358083526049, + "100.0" : 2790.358083526049 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2789.673732697351, + 2790.358083526049, + 2790.070323764354 + ], + [ + 2770.956955394474, + 2773.66907314586, + 2768.0277428002055 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75667.85235526373, + "scoreError" : 3305.78989098499, + "scoreConfidence" : [ + 72362.06246427874, + 78973.64224624872 + ], + "scorePercentiles" : { + "0.0" : 74565.58948713128, + "50.0" : 75676.2576000201, + "90.0" : 76780.24572712336, + "95.0" : 76780.24572712336, + "99.0" : 76780.24572712336, + "99.9" : 76780.24572712336, + "99.99" : 76780.24572712336, + "99.999" : 76780.24572712336, + "99.9999" : 76780.24572712336, + "100.0" : 76780.24572712336 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76710.76973616649, + 76780.24572712336, + 76739.60346718333 + ], + [ + 74565.58948713128, + 74641.74546387368, + 74569.16025010435 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 373.0041791672965, + "scoreError" : 4.0136771917274485, + "scoreConfidence" : [ + 368.9905019755691, + 377.01785635902394 + ], + "scorePercentiles" : { + "0.0" : 371.4930048610171, + "50.0" : 372.83837099293794, + "90.0" : 374.8792616792439, + "95.0" : 374.8792616792439, + "99.0" : 374.8792616792439, + "99.9" : 374.8792616792439, + "99.99" : 374.8792616792439, + "99.999" : 374.8792616792439, + "99.9999" : 374.8792616792439, + "100.0" : 374.8792616792439 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 373.386673493575, + 374.3640723361575, + 374.8792616792439 + ], + [ + 371.6119941414846, + 372.29006849230086, + 371.4930048610171 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.37655665345265, + "scoreError" : 3.3837661670949624, + "scoreConfidence" : [ + 110.99279048635769, + 117.76032282054761 + ], + "scorePercentiles" : { + "0.0" : 113.17497237343437, + "50.0" : 114.39786457566868, + "90.0" : 115.51022681474026, + "95.0" : 115.51022681474026, + "99.0" : 115.51022681474026, + "99.9" : 115.51022681474026, + "99.99" : 115.51022681474026, + "99.999" : 115.51022681474026, + "99.9999" : 115.51022681474026, + "100.0" : 115.51022681474026 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.29118232069762, + 113.17497237343437, + 113.36372852685723 + ], + [ + 115.43200062448012, + 115.51022681474026, + 115.48722926050625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06068878381783934, + "scoreError" : 2.6477453476700955E-4, + "scoreConfidence" : [ + 0.06042400928307233, + 0.06095355835260635 + ], + "scorePercentiles" : { + "0.0" : 0.06055761485823634, + "50.0" : 0.0607017497929746, + "90.0" : 0.060793160679655914, + "95.0" : 0.060793160679655914, + "99.0" : 0.060793160679655914, + "99.9" : 0.060793160679655914, + "99.99" : 0.060793160679655914, + "99.999" : 0.060793160679655914, + "99.9999" : 0.060793160679655914, + "100.0" : 0.060793160679655914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060793160679655914, + 0.06076683056038307, + 0.06074698056129267 + ], + [ + 0.06055761485823634, + 0.06065651902465654, + 0.060611597222811495 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.665463547441459E-4, + "scoreError" : 1.0163305176535358E-5, + "scoreConfidence" : [ + 3.5638304956761053E-4, + 3.767096599206812E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6315320603756517E-4, + "50.0" : 3.665395814910835E-4, + "90.0" : 3.700238909975227E-4, + "95.0" : 3.700238909975227E-4, + "99.0" : 3.700238909975227E-4, + "99.9" : 3.700238909975227E-4, + "99.99" : 3.700238909975227E-4, + "99.999" : 3.700238909975227E-4, + "99.9999" : 3.700238909975227E-4, + "100.0" : 3.700238909975227E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.631553729872792E-4, + 3.6341307933253635E-4, + 3.6315320603756517E-4 + ], + [ + 3.700238909975227E-4, + 3.69866495460341E-4, + 3.6966608364963073E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12400797335580338, + "scoreError" : 0.0034661896838241047, + "scoreConfidence" : [ + 0.12054178367197928, + 0.1274741630396275 + ], + "scorePercentiles" : { + "0.0" : 0.12297680757027964, + "50.0" : 0.12354673326243973, + "90.0" : 0.12565758567784577, + "95.0" : 0.12565758567784577, + "99.0" : 0.12565758567784577, + "99.9" : 0.12565758567784577, + "99.99" : 0.12565758567784577, + "99.999" : 0.12565758567784577, + "99.9999" : 0.12565758567784577, + "100.0" : 0.12565758567784577 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12565758567784577, + 0.12409282715359989, + 0.12534040607139277 + ], + [ + 0.12300063937127959, + 0.12297680757027964, + 0.12297957429042256 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013013662593494733, + "scoreError" : 2.2378766104029175E-5, + "scoreConfidence" : [ + 0.012991283827390704, + 0.013036041359598762 + ], + "scorePercentiles" : { + "0.0" : 0.013002671547804334, + "50.0" : 0.013013698752754863, + "90.0" : 0.01302614761442029, + "95.0" : 0.01302614761442029, + "99.0" : 0.01302614761442029, + "99.9" : 0.01302614761442029, + "99.99" : 0.01302614761442029, + "99.999" : 0.01302614761442029, + "99.9999" : 0.01302614761442029, + "100.0" : 0.01302614761442029 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01302614761442029, + 0.01301728620354352, + 0.013014618940466646 + ], + [ + 0.013002671547804334, + 0.013008472689690518, + 0.01301277856504308 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9703116016415669, + "scoreError" : 0.06631356112427532, + "scoreConfidence" : [ + 0.9039980405172916, + 1.0366251627658423 + ], + "scorePercentiles" : { + "0.0" : 0.948474313353566, + "50.0" : 0.9703890799940342, + "90.0" : 0.9920238530899712, + "95.0" : 0.9920238530899712, + "99.0" : 0.9920238530899712, + "99.9" : 0.9920238530899712, + "99.99" : 0.9920238530899712, + "99.999" : 0.9920238530899712, + "99.9999" : 0.9920238530899712, + "100.0" : 0.9920238530899712 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.948474313353566, + 0.9487564482496916, + 0.9489427386848848 + ], + [ + 0.9918368351681047, + 0.9920238530899712, + 0.9918354213031836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010656141134302946, + "scoreError" : 0.001117436934315331, + "scoreConfidence" : [ + 0.009538704199987615, + 0.011773578068618278 + ], + "scorePercentiles" : { + "0.0" : 0.010290066931183721, + "50.0" : 0.010653311125516885, + "90.0" : 0.011024971598288092, + "95.0" : 0.011024971598288092, + "99.0" : 0.011024971598288092, + "99.9" : 0.011024971598288092, + "99.99" : 0.011024971598288092, + "99.999" : 0.011024971598288092, + "99.9999" : 0.011024971598288092, + "100.0" : 0.011024971598288092 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011022484485153099, + 0.011024971598288092, + 0.011012204200831181 + ], + [ + 0.010292701540158997, + 0.010290066931183721, + 0.01029441805020259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.038373796103457, + "scoreError" : 0.09059080459191333, + "scoreConfidence" : [ + 2.9477829915115437, + 3.12896460069537 + ], + "scorePercentiles" : { + "0.0" : 3.006889778111846, + "50.0" : 3.038135464581415, + "90.0" : 3.0710444530386742, + "95.0" : 3.0710444530386742, + "99.0" : 3.0710444530386742, + "99.9" : 3.0710444530386742, + "99.99" : 3.0710444530386742, + "99.999" : 3.0710444530386742, + "99.9999" : 3.0710444530386742, + "100.0" : 3.0710444530386742 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.06550787377451, + 3.0710444530386742, + 3.066835171060699 + ], + [ + 3.006889778111846, + 3.0107630553883205, + 3.009202445246691 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6968318191828335, + "scoreError" : 0.02532849952986353, + "scoreConfidence" : [ + 2.67150331965297, + 2.7221603187126973 + ], + "scorePercentiles" : { + "0.0" : 2.688398769354839, + "50.0" : 2.6954899621679917, + "90.0" : 2.7072846253383864, + "95.0" : 2.7072846253383864, + "99.0" : 2.7072846253383864, + "99.9" : 2.7072846253383864, + "99.99" : 2.7072846253383864, + "99.999" : 2.7072846253383864, + "99.9999" : 2.7072846253383864, + "100.0" : 2.7072846253383864 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7072846253383864, + 2.7054583205301594, + 2.702052080518779 + ], + [ + 2.6888692755376344, + 2.688927843817204, + 2.688398769354839 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1760095219852856, + "scoreError" : 0.0025447639255362143, + "scoreConfidence" : [ + 0.1734647580597494, + 0.17855428591082181 + ], + "scorePercentiles" : { + "0.0" : 0.17487516932762087, + "50.0" : 0.17619766117759345, + "90.0" : 0.17693832892175945, + "95.0" : 0.17693832892175945, + "99.0" : 0.17693832892175945, + "99.9" : 0.17693832892175945, + "99.99" : 0.17693832892175945, + "99.999" : 0.17693832892175945, + "99.9999" : 0.17693832892175945, + "100.0" : 0.17693832892175945 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17693832892175945, + 0.17671940400791689, + 0.1767422110602499 + ], + [ + 0.1751061002468963, + 0.17567591834727003, + 0.17487516932762087 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3318867529874087, + "scoreError" : 0.010010212818511206, + "scoreConfidence" : [ + 0.3218765401688975, + 0.34189696580591994 + ], + "scorePercentiles" : { + "0.0" : 0.32840706433286265, + "50.0" : 0.3318677800591868, + "90.0" : 0.33537746971627874, + "95.0" : 0.33537746971627874, + "99.0" : 0.33537746971627874, + "99.9" : 0.33537746971627874, + "99.99" : 0.33537746971627874, + "99.999" : 0.33537746971627874, + "99.9999" : 0.33537746971627874, + "100.0" : 0.33537746971627874 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33537746971627874, + 0.3349437455203135, + 0.3351015875749757 + ], + [ + 0.3287918145980602, + 0.3286988361819616, + 0.32840706433286265 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14688343135764284, + "scoreError" : 0.006940425772100712, + "scoreConfidence" : [ + 0.13994300558554212, + 0.15382385712974356 + ], + "scorePercentiles" : { + "0.0" : 0.14458298824566984, + "50.0" : 0.14683738440994837, + "90.0" : 0.1492717196871315, + "95.0" : 0.1492717196871315, + "99.0" : 0.1492717196871315, + "99.9" : 0.1492717196871315, + "99.99" : 0.1492717196871315, + "99.999" : 0.1492717196871315, + "99.9999" : 0.1492717196871315, + "100.0" : 0.1492717196871315 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14467778987268518, + 0.14461610861894433, + 0.14458298824566984 + ], + [ + 0.14915500277421473, + 0.1492717196871315, + 0.1489969789472116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39991443001602334, + "scoreError" : 0.005986701874403861, + "scoreConfidence" : [ + 0.39392772814161947, + 0.4059011318904272 + ], + "scorePercentiles" : { + "0.0" : 0.397049660499464, + "50.0" : 0.4006146245204564, + "90.0" : 0.4026165764554312, + "95.0" : 0.4026165764554312, + "99.0" : 0.4026165764554312, + "99.9" : 0.4026165764554312, + "99.99" : 0.4026165764554312, + "99.999" : 0.4026165764554312, + "99.9999" : 0.4026165764554312, + "100.0" : 0.4026165764554312 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4026165764554312, + 0.3976360146327886, + 0.397049660499464 + ], + [ + 0.4009550794675434, + 0.40072897010619113, + 0.4005002789347217 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1541356535041077, + "scoreError" : 0.013634881816485101, + "scoreConfidence" : [ + 0.14050077168762262, + 0.1677705353205928 + ], + "scorePercentiles" : { + "0.0" : 0.14974724517085441, + "50.0" : 0.15354035008862116, + "90.0" : 0.16062211953291894, + "95.0" : 0.16062211953291894, + "99.0" : 0.16062211953291894, + "99.9" : 0.16062211953291894, + "99.99" : 0.16062211953291894, + "99.999" : 0.16062211953291894, + "99.9999" : 0.16062211953291894, + "100.0" : 0.16062211953291894 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14989337458780502, + 0.14986371256874823, + 0.14974724517085441 + ], + [ + 0.16062211953291894, + 0.15750014357488226, + 0.1571873255894373 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046725013202832795, + "scoreError" : 0.0024956819775445597, + "scoreConfidence" : [ + 0.044229331225288236, + 0.049220695180377354 + ], + "scorePercentiles" : { + "0.0" : 0.045770405705628736, + "50.0" : 0.046713371945552085, + "90.0" : 0.04776599891572768, + "95.0" : 0.04776599891572768, + "99.0" : 0.04776599891572768, + "99.9" : 0.04776599891572768, + "99.99" : 0.04776599891572768, + "99.999" : 0.04776599891572768, + "99.9999" : 0.04776599891572768, + "100.0" : 0.04776599891572768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04776599891572768, + 0.047406149136987014, + 0.047401607019107256 + ], + [ + 0.046025136871996906, + 0.045770405705628736, + 0.04598078156754917 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8741998.630667271, + "scoreError" : 133134.10169957188, + "scoreConfidence" : [ + 8608864.528967699, + 8875132.732366843 + ], + "scorePercentiles" : { + "0.0" : 8692009.231972199, + "50.0" : 8742702.747062664, + "90.0" : 8795589.088830255, + "95.0" : 8795589.088830255, + "99.0" : 8795589.088830255, + "99.9" : 8795589.088830255, + "99.99" : 8795589.088830255, + "99.999" : 8795589.088830255, + "99.9999" : 8795589.088830255, + "100.0" : 8795589.088830255 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8692009.231972199, + 8697880.474782608, + 8707899.744125327 + ], + [ + 8795589.088830255, + 8781107.494293239, + 8777505.75 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-07T01:48:36Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json b/performance-results/2025-08-07T01:48:36Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json new file mode 100644 index 0000000000..3ca8d4f4b5 --- /dev/null +++ b/performance-results/2025-08-07T01:48:36Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3208636819786546, + "scoreError" : 0.04580967327287364, + "scoreConfidence" : [ + 3.275054008705781, + 3.366673355251528 + ], + "scorePercentiles" : { + "0.0" : 3.3132820513451287, + "50.0" : 3.3199293041279994, + "90.0" : 3.330314068313491, + "95.0" : 3.330314068313491, + "99.0" : 3.330314068313491, + "99.9" : 3.330314068313491, + "99.99" : 3.330314068313491, + "99.999" : 3.330314068313491, + "99.9999" : 3.330314068313491, + "100.0" : 3.330314068313491 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3132820513451287, + 3.3209849715656574 + ], + [ + 3.318873636690341, + 3.330314068313491 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6833359157782506, + "scoreError" : 0.027371723311678902, + "scoreConfidence" : [ + 1.6559641924665718, + 1.7107076390899294 + ], + "scorePercentiles" : { + "0.0" : 1.6770908381894634, + "50.0" : 1.6849180589355717, + "90.0" : 1.6864167070523952, + "95.0" : 1.6864167070523952, + "99.0" : 1.6864167070523952, + "99.9" : 1.6864167070523952, + "99.99" : 1.6864167070523952, + "99.999" : 1.6864167070523952, + "99.9999" : 1.6864167070523952, + "100.0" : 1.6864167070523952 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6770908381894634, + 1.6853227167551017 + ], + [ + 1.6845134011160414, + 1.6864167070523952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8428819633863808, + "scoreError" : 0.03064381179271536, + "scoreConfidence" : [ + 0.8122381515936654, + 0.8735257751790961 + ], + "scorePercentiles" : { + "0.0" : 0.838343794770164, + "50.0" : 0.8420920187446153, + "90.0" : 0.8490000212861285, + "95.0" : 0.8490000212861285, + "99.0" : 0.8490000212861285, + "99.9" : 0.8490000212861285, + "99.99" : 0.8490000212861285, + "99.999" : 0.8490000212861285, + "99.9999" : 0.8490000212861285, + "100.0" : 0.8490000212861285 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.838343794770164, + 0.8400683191048959 + ], + [ + 0.8441157183843346, + 0.8490000212861285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.13158589597619, + "scoreError" : 0.2949796815419324, + "scoreConfidence" : [ + 15.836606214434259, + 16.426565577518122 + ], + "scorePercentiles" : { + "0.0" : 16.00707175755424, + "50.0" : 16.127908886444196, + "90.0" : 16.2512795822699, + "95.0" : 16.2512795822699, + "99.0" : 16.2512795822699, + "99.9" : 16.2512795822699, + "99.99" : 16.2512795822699, + "99.999" : 16.2512795822699, + "99.9999" : 16.2512795822699, + "100.0" : 16.2512795822699 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.230027418003452, + 16.2512795822699, + 16.192473907725322 + ], + [ + 16.00707175755424, + 16.045318845141175, + 16.063343865163066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2652.8745605883023, + "scoreError" : 173.23432477660106, + "scoreConfidence" : [ + 2479.640235811701, + 2826.1088853649035 + ], + "scorePercentiles" : { + "0.0" : 2589.289657289064, + "50.0" : 2653.720236189015, + "90.0" : 2715.7792490270385, + "95.0" : 2715.7792490270385, + "99.0" : 2715.7792490270385, + "99.9" : 2715.7792490270385, + "99.99" : 2715.7792490270385, + "99.999" : 2715.7792490270385, + "99.9999" : 2715.7792490270385, + "100.0" : 2715.7792490270385 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2715.7792490270385, + 2701.3560855860956, + 2709.5602372662547 + ], + [ + 2589.289657289064, + 2606.084386791935, + 2595.177747569427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77452.58901901603, + "scoreError" : 130.37351494547053, + "scoreConfidence" : [ + 77322.21550407055, + 77582.9625339615 + ], + "scorePercentiles" : { + "0.0" : 77396.64791708409, + "50.0" : 77461.68315541977, + "90.0" : 77519.13192653612, + "95.0" : 77519.13192653612, + "99.0" : 77519.13192653612, + "99.9" : 77519.13192653612, + "99.99" : 77519.13192653612, + "99.999" : 77519.13192653612, + "99.9999" : 77519.13192653612, + "100.0" : 77519.13192653612 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77519.13192653612, + 77403.1431374836, + 77472.01298331299 + ], + [ + 77451.35332752657, + 77396.64791708409, + 77473.24482215285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 355.6776502403723, + "scoreError" : 16.88069459927166, + "scoreConfidence" : [ + 338.7969556411007, + 372.55834483964395 + ], + "scorePercentiles" : { + "0.0" : 349.4690699254441, + "50.0" : 355.79798047323163, + "90.0" : 361.88205282147237, + "95.0" : 361.88205282147237, + "99.0" : 361.88205282147237, + "99.9" : 361.88205282147237, + "99.99" : 361.88205282147237, + "99.999" : 361.88205282147237, + "99.9999" : 361.88205282147237, + "100.0" : 361.88205282147237 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.4690699254441, + 349.6388975607928, + 351.67559329181483 + ], + [ + 361.88205282147237, + 361.47992018806144, + 359.92036765464843 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 111.92848815247207, + "scoreError" : 3.1426868238339214, + "scoreConfidence" : [ + 108.78580132863814, + 115.071174976306 + ], + "scorePercentiles" : { + "0.0" : 110.82227061142484, + "50.0" : 111.88808486678838, + "90.0" : 113.15070203821811, + "95.0" : 113.15070203821811, + "99.0" : 113.15070203821811, + "99.9" : 113.15070203821811, + "99.99" : 113.15070203821811, + "99.999" : 113.15070203821811, + "99.9999" : 113.15070203821811, + "100.0" : 113.15070203821811 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.1171218945592, + 110.82236087941833, + 110.82227061142484 + ], + [ + 113.15070203821811, + 112.99942565219425, + 112.65904783901756 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06235659807570962, + "scoreError" : 0.0014464124231325201, + "scoreConfidence" : [ + 0.060910185652577095, + 0.06380301049884214 + ], + "scorePercentiles" : { + "0.0" : 0.061804266081184646, + "50.0" : 0.06232507727881316, + "90.0" : 0.06302065593234224, + "95.0" : 0.06302065593234224, + "99.0" : 0.06302065593234224, + "99.9" : 0.06302065593234224, + "99.99" : 0.06302065593234224, + "99.999" : 0.06302065593234224, + "99.9999" : 0.06302065593234224, + "100.0" : 0.06302065593234224 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06276964583372564, + 0.06302065593234224, + 0.06264006651674976 + ], + [ + 0.061804266081184646, + 0.0618948660493789, + 0.062010088040876564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.714960413853132E-4, + "scoreError" : 2.6429742408544177E-5, + "scoreConfidence" : [ + 3.4506629897676906E-4, + 3.979257837938574E-4 + ], + "scorePercentiles" : { + "0.0" : 3.619770998204943E-4, + "50.0" : 3.72127742135605E-4, + "90.0" : 3.802390087861573E-4, + "95.0" : 3.802390087861573E-4, + "99.0" : 3.802390087861573E-4, + "99.9" : 3.802390087861573E-4, + "99.99" : 3.802390087861573E-4, + "99.999" : 3.802390087861573E-4, + "99.9999" : 3.802390087861573E-4, + "100.0" : 3.802390087861573E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8017938542329676E-4, + 3.797701007249324E-4, + 3.802390087861573E-4 + ], + [ + 3.644853835462777E-4, + 3.619770998204943E-4, + 3.6232527001072107E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12215615043149258, + "scoreError" : 0.001683679663807582, + "scoreConfidence" : [ + 0.120472470767685, + 0.12383983009530017 + ], + "scorePercentiles" : { + "0.0" : 0.12155620009967302, + "50.0" : 0.12212646035053538, + "90.0" : 0.12278038979471564, + "95.0" : 0.12278038979471564, + "99.0" : 0.12278038979471564, + "99.9" : 0.12278038979471564, + "99.99" : 0.12278038979471564, + "99.999" : 0.12278038979471564, + "99.9999" : 0.12278038979471564, + "100.0" : 0.12278038979471564 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12155620009967302, + 0.1215864094374263, + 0.12170178735548254 + ], + [ + 0.12276098255606978, + 0.12255113334558823, + 0.12278038979471564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013095239311012754, + "scoreError" : 2.1457643491175555E-4, + "scoreConfidence" : [ + 0.012880662876100998, + 0.013309815745924509 + ], + "scorePercentiles" : { + "0.0" : 0.013023623038183389, + "50.0" : 0.013092765134537328, + "90.0" : 0.013174280811631167, + "95.0" : 0.013174280811631167, + "99.0" : 0.013174280811631167, + "99.9" : 0.013174280811631167, + "99.99" : 0.013174280811631167, + "99.999" : 0.013174280811631167, + "99.9999" : 0.013174280811631167, + "100.0" : 0.013174280811631167 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013174280811631167, + 0.013163488156337659, + 0.013156905002479992 + ], + [ + 0.013023623038183389, + 0.013024513590849652, + 0.013028625266594663 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9793543314561045, + "scoreError" : 0.04708738317838406, + "scoreConfidence" : [ + 0.9322669482777205, + 1.0264417146344886 + ], + "scorePercentiles" : { + "0.0" : 0.9632218911682559, + "50.0" : 0.979271090448355, + "90.0" : 0.9957121061330148, + "95.0" : 0.9957121061330148, + "99.0" : 0.9957121061330148, + "99.9" : 0.9957121061330148, + "99.99" : 0.9957121061330148, + "99.999" : 0.9957121061330148, + "99.9999" : 0.9957121061330148, + "100.0" : 0.9957121061330148 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.964778833783523, + 0.9641274360358624, + 0.9632218911682559 + ], + [ + 0.9957121061330148, + 0.9945223745027844, + 0.9937633471131869 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.0111349196208136, + "scoreError" : 9.503379772231944E-4, + "scoreConfidence" : [ + 0.010184581643590407, + 0.012085257598036794 + ], + "scorePercentiles" : { + "0.0" : 0.01082286327616846, + "50.0" : 0.01113552968040572, + "90.0" : 0.011446806116562198, + "95.0" : 0.011446806116562198, + "99.0" : 0.011446806116562198, + "99.9" : 0.011446806116562198, + "99.99" : 0.011446806116562198, + "99.999" : 0.011446806116562198, + "99.9999" : 0.011446806116562198, + "100.0" : 0.011446806116562198 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010823839758159834, + 0.01082997867427918, + 0.01082286327616846 + ], + [ + 0.011446806116562198, + 0.01144494921317967, + 0.011441080686532261 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1590813478106075, + "scoreError" : 0.11972455084288515, + "scoreConfidence" : [ + 3.039356796967722, + 3.2788058986534927 + ], + "scorePercentiles" : { + "0.0" : 3.1031715552109183, + "50.0" : 3.162815038149388, + "90.0" : 3.2102676148908857, + "95.0" : 3.2102676148908857, + "99.0" : 3.2102676148908857, + "99.9" : 3.2102676148908857, + "99.99" : 3.2102676148908857, + "99.999" : 3.2102676148908857, + "99.9999" : 3.2102676148908857, + "100.0" : 3.2102676148908857 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.190967752393108, + 3.186526501910828, + 3.2102676148908857 + ], + [ + 3.1391035743879474, + 3.1031715552109183, + 3.1244510880699563 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.85322322362272, + "scoreError" : 0.09885376417133689, + "scoreConfidence" : [ + 2.7543694594513832, + 2.952076987794057 + ], + "scorePercentiles" : { + "0.0" : 2.809723872752809, + "50.0" : 2.85834809433244, + "90.0" : 2.886439058874459, + "95.0" : 2.886439058874459, + "99.0" : 2.886439058874459, + "99.9" : 2.886439058874459, + "99.99" : 2.886439058874459, + "99.999" : 2.886439058874459, + "99.9999" : 2.886439058874459, + "100.0" : 2.886439058874459 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.809723872752809, + 2.8222250530474042, + 2.8334311560906515 + ], + [ + 2.886439058874459, + 2.883265032574229, + 2.8842551683967703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18325042593071827, + "scoreError" : 0.002102624871295671, + "scoreConfidence" : [ + 0.1811478010594226, + 0.18535305080201395 + ], + "scorePercentiles" : { + "0.0" : 0.1825286501907387, + "50.0" : 0.18324116609043567, + "90.0" : 0.18404596240061838, + "95.0" : 0.18404596240061838, + "99.0" : 0.18404596240061838, + "99.9" : 0.18404596240061838, + "99.99" : 0.18404596240061838, + "99.999" : 0.18404596240061838, + "99.9999" : 0.18404596240061838, + "100.0" : 0.18404596240061838 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18389021076826892, + 0.18404596240061838, + 0.18385952144656284 + ], + [ + 0.18262281073430853, + 0.1825554000438124, + 0.1825286501907387 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3298057717309419, + "scoreError" : 0.014314023604912345, + "scoreConfidence" : [ + 0.31549174812602954, + 0.34411979533585424 + ], + "scorePercentiles" : { + "0.0" : 0.3249710869918435, + "50.0" : 0.3293926807585337, + "90.0" : 0.33626212286482854, + "95.0" : 0.33626212286482854, + "99.0" : 0.33626212286482854, + "99.9" : 0.33626212286482854, + "99.99" : 0.33626212286482854, + "99.999" : 0.33626212286482854, + "99.9999" : 0.33626212286482854, + "100.0" : 0.33626212286482854 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32522578721259227, + 0.32554677889185496, + 0.3249710869918435 + ], + [ + 0.33626212286482854, + 0.3335902717993195, + 0.33323858262521244 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14617845675663657, + "scoreError" : 0.004749918590184482, + "scoreConfidence" : [ + 0.1414285381664521, + 0.15092837534682105 + ], + "scorePercentiles" : { + "0.0" : 0.14452339662398475, + "50.0" : 0.14612928532678543, + "90.0" : 0.14800443399242244, + "95.0" : 0.14800443399242244, + "99.0" : 0.14800443399242244, + "99.9" : 0.14800443399242244, + "99.99" : 0.14800443399242244, + "99.999" : 0.14800443399242244, + "99.9999" : 0.14800443399242244, + "100.0" : 0.14800443399242244 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14800443399242244, + 0.14763115093448287, + 0.1475132841928251 + ], + [ + 0.14452339662398475, + 0.14474528646074572, + 0.14465318833535845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40320287410244265, + "scoreError" : 0.0176026626440897, + "scoreConfidence" : [ + 0.38560021145835294, + 0.42080553674653237 + ], + "scorePercentiles" : { + "0.0" : 0.3975365605819685, + "50.0" : 0.40213085753327055, + "90.0" : 0.41145547895494755, + "95.0" : 0.41145547895494755, + "99.0" : 0.41145547895494755, + "99.9" : 0.41145547895494755, + "99.99" : 0.41145547895494755, + "99.999" : 0.41145547895494755, + "99.9999" : 0.41145547895494755, + "100.0" : 0.41145547895494755 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4083749086491343, + 0.41145547895494755, + 0.406387611183355 + ], + [ + 0.3978741038831861, + 0.39758858136206415, + 0.3975365605819685 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15886284220924662, + "scoreError" : 0.006720146896817238, + "scoreConfidence" : [ + 0.15214269531242938, + 0.16558298910606387 + ], + "scorePercentiles" : { + "0.0" : 0.1567474936675131, + "50.0" : 0.1583959596263405, + "90.0" : 0.16280497667073668, + "95.0" : 0.16280497667073668, + "99.0" : 0.16280497667073668, + "99.9" : 0.16280497667073668, + "99.99" : 0.16280497667073668, + "99.999" : 0.16280497667073668, + "99.9999" : 0.16280497667073668, + "100.0" : 0.16280497667073668 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16280497667073668, + 0.1599544472240439, + 0.15964773795877968 + ], + [ + 0.15714418129390134, + 0.15687821644050515, + 0.1567474936675131 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047515188635482764, + "scoreError" : 0.003605761918698489, + "scoreConfidence" : [ + 0.04390942671678427, + 0.051120950554181255 + ], + "scorePercentiles" : { + "0.0" : 0.046330033199596006, + "50.0" : 0.04749170311889411, + "90.0" : 0.04880777814220452, + "95.0" : 0.04880777814220452, + "99.0" : 0.04880777814220452, + "99.9" : 0.04880777814220452, + "99.99" : 0.04880777814220452, + "99.999" : 0.04880777814220452, + "99.9999" : 0.04880777814220452, + "100.0" : 0.04880777814220452 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04880777814220452, + 0.048628350406527784, + 0.04862617113209566 + ], + [ + 0.046330033199596006, + 0.04635723510569256, + 0.04634156382678004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8752967.31729354, + "scoreError" : 103177.6190069826, + "scoreConfidence" : [ + 8649789.698286558, + 8856144.936300522 + ], + "scorePercentiles" : { + "0.0" : 8714258.959930314, + "50.0" : 8753963.713495454, + "90.0" : 8796975.933157431, + "95.0" : 8796975.933157431, + "99.0" : 8796975.933157431, + "99.9" : 8796975.933157431, + "99.99" : 8796975.933157431, + "99.999" : 8796975.933157431, + "99.9999" : 8796975.933157431, + "100.0" : 8796975.933157431 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8775682.888596492, + 8796975.933157431, + 8783685.896400351 + ], + [ + 8732244.538394416, + 8714258.959930314, + 8714955.68728223 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-07T01:49:00Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json b/performance-results/2025-08-07T01:49:00Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json new file mode 100644 index 0000000000..06a95fe354 --- /dev/null +++ b/performance-results/2025-08-07T01:49:00Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3553767474307996, + "scoreError" : 0.03923900512356873, + "scoreConfidence" : [ + 3.3161377423072307, + 3.3946157525543685 + ], + "scorePercentiles" : { + "0.0" : 3.349702898564459, + "50.0" : 3.354481304238947, + "90.0" : 3.362841482680845, + "95.0" : 3.362841482680845, + "99.0" : 3.362841482680845, + "99.9" : 3.362841482680845, + "99.99" : 3.362841482680845, + "99.999" : 3.362841482680845, + "99.9999" : 3.362841482680845, + "100.0" : 3.362841482680845 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.351233284546996, + 3.3577293239308985 + ], + [ + 3.349702898564459, + 3.362841482680845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6827242034938557, + "scoreError" : 0.01606673242181253, + "scoreConfidence" : [ + 1.6666574710720432, + 1.698790935915668 + ], + "scorePercentiles" : { + "0.0" : 1.6804007362502646, + "50.0" : 1.682170684023235, + "90.0" : 1.686154709678688, + "95.0" : 1.686154709678688, + "99.0" : 1.686154709678688, + "99.9" : 1.686154709678688, + "99.99" : 1.686154709678688, + "99.999" : 1.686154709678688, + "99.9999" : 1.686154709678688, + "100.0" : 1.686154709678688 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6804007362502646, + 1.686154709678688 + ], + [ + 1.6815517783403309, + 1.6827895897061393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8465421218673161, + "scoreError" : 0.025219223195345496, + "scoreConfidence" : [ + 0.8213228986719706, + 0.8717613450626617 + ], + "scorePercentiles" : { + "0.0" : 0.8430296661096958, + "50.0" : 0.8457877764480806, + "90.0" : 0.8515632684634078, + "95.0" : 0.8515632684634078, + "99.0" : 0.8515632684634078, + "99.9" : 0.8515632684634078, + "99.99" : 0.8515632684634078, + "99.999" : 0.8515632684634078, + "99.9999" : 0.8515632684634078, + "100.0" : 0.8515632684634078 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8430296661096958, + 0.8476593977519014 + ], + [ + 0.8439161551442599, + 0.8515632684634078 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.317191768123365, + "scoreError" : 0.10865551846388044, + "scoreConfidence" : [ + 16.208536249659485, + 16.425847286587246 + ], + "scorePercentiles" : { + "0.0" : 16.244522121204593, + "50.0" : 16.330395034066186, + "90.0" : 16.34799854290687, + "95.0" : 16.34799854290687, + "99.0" : 16.34799854290687, + "99.9" : 16.34799854290687, + "99.99" : 16.34799854290687, + "99.999" : 16.34799854290687, + "99.9999" : 16.34799854290687, + "100.0" : 16.34799854290687 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.308098020434834, + 16.31937473877467, + 16.244522121204593 + ], + [ + 16.341415329357705, + 16.341741856061535, + 16.34799854290687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2717.6842537697908, + "scoreError" : 35.13614267279007, + "scoreConfidence" : [ + 2682.548111097001, + 2752.8203964425807 + ], + "scorePercentiles" : { + "0.0" : 2704.3867070628435, + "50.0" : 2717.726321649926, + "90.0" : 2730.0705368652452, + "95.0" : 2730.0705368652452, + "99.0" : 2730.0705368652452, + "99.9" : 2730.0705368652452, + "99.99" : 2730.0705368652452, + "99.999" : 2730.0705368652452, + "99.9999" : 2730.0705368652452, + "100.0" : 2730.0705368652452 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2727.9579265635703, + 2729.166432993967, + 2730.0705368652452 + ], + [ + 2704.3867070628435, + 2707.494716736282, + 2707.0292023968345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75746.85030993138, + "scoreError" : 2575.805105209659, + "scoreConfidence" : [ + 73171.04520472173, + 78322.65541514104 + ], + "scorePercentiles" : { + "0.0" : 74857.2209027777, + "50.0" : 75750.24782517519, + "90.0" : 76617.45575115184, + "95.0" : 76617.45575115184, + "99.0" : 76617.45575115184, + "99.9" : 76617.45575115184, + "99.99" : 76617.45575115184, + "99.999" : 76617.45575115184, + "99.9999" : 76617.45575115184, + "100.0" : 76617.45575115184 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76588.85152366273, + 76547.69015415483, + 76617.45575115184 + ], + [ + 74952.80549619555, + 74917.07803164568, + 74857.2209027777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.39537425344446, + "scoreError" : 2.8352800652013377, + "scoreConfidence" : [ + 359.5600941882431, + 365.2306543186458 + ], + "scorePercentiles" : { + "0.0" : 361.44481597898664, + "50.0" : 361.98994286065476, + "90.0" : 363.75557907807195, + "95.0" : 363.75557907807195, + "99.0" : 363.75557907807195, + "99.9" : 363.75557907807195, + "99.99" : 363.75557907807195, + "99.999" : 363.75557907807195, + "99.9999" : 363.75557907807195, + "100.0" : 363.75557907807195 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 363.558728349338, + 363.75557907807195, + 362.2076379216283 + ], + [ + 361.63323639296016, + 361.7722477996812, + 361.44481597898664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.620252125954, + "scoreError" : 4.415550724330574, + "scoreConfidence" : [ + 111.20470140162342, + 120.03580285028457 + ], + "scorePercentiles" : { + "0.0" : 113.16468960666198, + "50.0" : 116.01025594509699, + "90.0" : 117.0057133562096, + "95.0" : 117.0057133562096, + "99.0" : 117.0057133562096, + "99.9" : 117.0057133562096, + "99.99" : 117.0057133562096, + "99.999" : 117.0057133562096, + "99.9999" : 117.0057133562096, + "100.0" : 117.0057133562096 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.905316758973, + 116.87697708217105, + 117.0057133562096 + ], + [ + 113.16468960666198, + 114.62528114368558, + 115.1435348080229 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060930622380201326, + "scoreError" : 0.0012205252989673568, + "scoreConfidence" : [ + 0.05971009708123397, + 0.06215114767916868 + ], + "scorePercentiles" : { + "0.0" : 0.06050883949608815, + "50.0" : 0.060910588813798155, + "90.0" : 0.06138525038058291, + "95.0" : 0.06138525038058291, + "99.0" : 0.06138525038058291, + "99.9" : 0.06138525038058291, + "99.99" : 0.06138525038058291, + "99.999" : 0.06138525038058291, + "99.9999" : 0.06138525038058291, + "100.0" : 0.06138525038058291 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06138525038058291, + 0.061271278798610385, + 0.06132256751801318 + ], + [ + 0.06050883949608815, + 0.06054589925892738, + 0.060549898828985926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6517484236350817E-4, + "scoreError" : 3.193417905794263E-5, + "scoreConfidence" : [ + 3.3324066330556553E-4, + 3.971090214214508E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5437801649659855E-4, + "50.0" : 3.652435895852092E-4, + "90.0" : 3.756493454225255E-4, + "95.0" : 3.756493454225255E-4, + "99.0" : 3.756493454225255E-4, + "99.9" : 3.756493454225255E-4, + "99.99" : 3.756493454225255E-4, + "99.999" : 3.756493454225255E-4, + "99.9999" : 3.756493454225255E-4, + "100.0" : 3.756493454225255E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.756493454225255E-4, + 3.755593965944598E-4, + 3.7549706011544607E-4 + ], + [ + 3.5437801649659855E-4, + 3.549751164970467E-4, + 3.5499011905497233E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1248036613823344, + "scoreError" : 0.0038036023392918573, + "scoreConfidence" : [ + 0.12100005904304253, + 0.12860726372162626 + ], + "scorePercentiles" : { + "0.0" : 0.12354733625311952, + "50.0" : 0.12440581979603876, + "90.0" : 0.1264828635644992, + "95.0" : 0.1264828635644992, + "99.0" : 0.1264828635644992, + "99.9" : 0.1264828635644992, + "99.99" : 0.1264828635644992, + "99.999" : 0.1264828635644992, + "99.9999" : 0.1264828635644992, + "100.0" : 0.1264828635644992 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12497333607018334, + 0.1264828635644992, + 0.1263631724582375 + ], + [ + 0.12383830352189419, + 0.12361695642607266, + 0.12354733625311952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013121941207441897, + "scoreError" : 5.429389356505544E-5, + "scoreConfidence" : [ + 0.013067647313876841, + 0.013176235101006952 + ], + "scorePercentiles" : { + "0.0" : 0.013094138865537966, + "50.0" : 0.013124708757678384, + "90.0" : 0.013140412744737326, + "95.0" : 0.013140412744737326, + "99.0" : 0.013140412744737326, + "99.9" : 0.013140412744737326, + "99.99" : 0.013140412744737326, + "99.999" : 0.013140412744737326, + "99.9999" : 0.013140412744737326, + "100.0" : 0.013140412744737326 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013140412744737326, + 0.013138840004729934, + 0.013136701152988746 + ], + [ + 0.013094138865537966, + 0.013108838114289385, + 0.013112716362368023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9630344500065394, + "scoreError" : 0.025536951600930387, + "scoreConfidence" : [ + 0.937497498405609, + 0.9885714016074698 + ], + "scorePercentiles" : { + "0.0" : 0.9541509278694781, + "50.0" : 0.9630544518321223, + "90.0" : 0.9717229493781578, + "95.0" : 0.9717229493781578, + "99.0" : 0.9717229493781578, + "99.9" : 0.9717229493781578, + "99.99" : 0.9717229493781578, + "99.999" : 0.9717229493781578, + "99.9999" : 0.9717229493781578, + "100.0" : 0.9717229493781578 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9717229493781578, + 0.9715299550223431, + 0.970752403377657 + ], + [ + 0.9553565002865877, + 0.954693964105012, + 0.9541509278694781 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010526555822248457, + "scoreError" : 4.1045130330325644E-5, + "scoreConfidence" : [ + 0.01048551069191813, + 0.010567600952578783 + ], + "scorePercentiles" : { + "0.0" : 0.010512005070870247, + "50.0" : 0.010521775493899644, + "90.0" : 0.01054557401759803, + "95.0" : 0.01054557401759803, + "99.0" : 0.01054557401759803, + "99.9" : 0.01054557401759803, + "99.99" : 0.01054557401759803, + "99.999" : 0.01054557401759803, + "99.9999" : 0.01054557401759803, + "100.0" : 0.01054557401759803 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010522018570932545, + 0.010514286658746097, + 0.010512005070870247 + ], + [ + 0.010543918198477081, + 0.010521532416866744, + 0.01054557401759803 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.070620598438744, + "scoreError" : 0.050961860277633456, + "scoreConfidence" : [ + 3.01965873816111, + 3.1215824587163774 + ], + "scorePercentiles" : { + "0.0" : 3.0516446809029896, + "50.0" : 3.0703694945337934, + "90.0" : 3.0904961440049443, + "95.0" : 3.0904961440049443, + "99.0" : 3.0904961440049443, + "99.9" : 3.0904961440049443, + "99.99" : 3.0904961440049443, + "99.999" : 3.0904961440049443, + "99.9999" : 3.0904961440049443, + "100.0" : 3.0904961440049443 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.055274002443494, + 3.0555854825901037, + 3.0516446809029896 + ], + [ + 3.085153506477483, + 3.0855697742134485, + 3.0904961440049443 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.745861209352848, + "scoreError" : 0.07330577316060438, + "scoreConfidence" : [ + 2.6725554361922437, + 2.8191669825134524 + ], + "scorePercentiles" : { + "0.0" : 2.7186507931503128, + "50.0" : 2.748398332755598, + "90.0" : 2.7713910016625105, + "95.0" : 2.7713910016625105, + "99.0" : 2.7713910016625105, + "99.9" : 2.7713910016625105, + "99.99" : 2.7713910016625105, + "99.999" : 2.7713910016625105, + "99.9999" : 2.7713910016625105, + "100.0" : 2.7713910016625105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7192661302338226, + 2.7186507931503128, + 2.728824817462483 + ], + [ + 2.7713910016625105, + 2.7690626655592467, + 2.7679718480487128 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17586683197191588, + "scoreError" : 0.0021011380467388435, + "scoreConfidence" : [ + 0.17376569392517704, + 0.17796797001865472 + ], + "scorePercentiles" : { + "0.0" : 0.17490174882817966, + "50.0" : 0.17617868243842588, + "90.0" : 0.17660694362814355, + "95.0" : 0.17660694362814355, + "99.0" : 0.17660694362814355, + "99.9" : 0.17660694362814355, + "99.99" : 0.17660694362814355, + "99.999" : 0.17660694362814355, + "99.9999" : 0.17660694362814355, + "100.0" : 0.17660694362814355 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17494469135089744, + 0.17660694362814355, + 0.17490174882817966 + ], + [ + 0.17624648107155447, + 0.17639024314742302, + 0.17611088380529727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3222080167217422, + "scoreError" : 0.005419801945432811, + "scoreConfidence" : [ + 0.3167882147763094, + 0.327627818667175 + ], + "scorePercentiles" : { + "0.0" : 0.320119753673293, + "50.0" : 0.3222621813348538, + "90.0" : 0.3240192545118751, + "95.0" : 0.3240192545118751, + "99.0" : 0.3240192545118751, + "99.9" : 0.3240192545118751, + "99.99" : 0.3240192545118751, + "99.999" : 0.3240192545118751, + "99.9999" : 0.3240192545118751, + "100.0" : 0.3240192545118751 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32062945896120554, + 0.320119753673293, + 0.32060645316106695 + ], + [ + 0.32389490370850205, + 0.3240192545118751, + 0.32397827631451065 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14626277049637187, + "scoreError" : 0.010397823416195181, + "scoreConfidence" : [ + 0.13586494708017668, + 0.15666059391256706 + ], + "scorePercentiles" : { + "0.0" : 0.142817049270933, + "50.0" : 0.1462983079729472, + "90.0" : 0.1496881730656967, + "95.0" : 0.1496881730656967, + "99.0" : 0.1496881730656967, + "99.9" : 0.1496881730656967, + "99.99" : 0.1496881730656967, + "99.999" : 0.1496881730656967, + "99.9999" : 0.1496881730656967, + "100.0" : 0.1496881730656967 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1429790913042235, + 0.14283883420939866, + 0.142817049270933 + ], + [ + 0.1496881730656967, + 0.14963595048630854, + 0.1496175246416709 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4022734997796377, + "scoreError" : 0.009996752926662975, + "scoreConfidence" : [ + 0.39227674685297476, + 0.4122702527063007 + ], + "scorePercentiles" : { + "0.0" : 0.3980044095757383, + "50.0" : 0.40331459345349885, + "90.0" : 0.40585686473214283, + "95.0" : 0.40585686473214283, + "99.0" : 0.40585686473214283, + "99.9" : 0.40585686473214283, + "99.99" : 0.40585686473214283, + "99.999" : 0.40585686473214283, + "99.9999" : 0.40585686473214283, + "100.0" : 0.40585686473214283 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40585686473214283, + 0.40512003694551346, + 0.4047645459586352 + ], + [ + 0.4018646409483625, + 0.3980044095757383, + 0.39803050051743355 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1561740705053884, + "scoreError" : 0.004420547548079618, + "scoreConfidence" : [ + 0.1517535229573088, + 0.160594618053468 + ], + "scorePercentiles" : { + "0.0" : 0.1546447804994974, + "50.0" : 0.15607942689446086, + "90.0" : 0.1578349646301236, + "95.0" : 0.1578349646301236, + "99.0" : 0.1578349646301236, + "99.9" : 0.1578349646301236, + "99.99" : 0.1578349646301236, + "99.999" : 0.1578349646301236, + "99.9999" : 0.1578349646301236, + "100.0" : 0.1578349646301236 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15731484062735968, + 0.15766167351958127, + 0.1578349646301236 + ], + [ + 0.15484401316156204, + 0.1547441505942065, + 0.1546447804994974 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047148849667884074, + "scoreError" : 0.0015902214116356617, + "scoreConfidence" : [ + 0.045558628256248415, + 0.04873907107951973 + ], + "scorePercentiles" : { + "0.0" : 0.04645296886830578, + "50.0" : 0.04724657241227666, + "90.0" : 0.04768806424892704, + "95.0" : 0.04768806424892704, + "99.0" : 0.04768806424892704, + "99.9" : 0.04768806424892704, + "99.99" : 0.04768806424892704, + "99.999" : 0.04768806424892704, + "99.9999" : 0.04768806424892704, + "100.0" : 0.04768806424892704 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0476479718262212, + 0.04768806424892704, + 0.04761764030112995 + ], + [ + 0.046875504523423366, + 0.04645296886830578, + 0.046610948239297116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8753841.322483579, + "scoreError" : 284082.41472918954, + "scoreConfidence" : [ + 8469758.90775439, + 9037923.737212768 + ], + "scorePercentiles" : { + "0.0" : 8637662.1044905, + "50.0" : 8746436.413518436, + "90.0" : 8863388.26040744, + "95.0" : 8863388.26040744, + "99.0" : 8863388.26040744, + "99.9" : 8863388.26040744, + "99.99" : 8863388.26040744, + "99.999" : 8863388.26040744, + "99.9999" : 8863388.26040744, + "100.0" : 8863388.26040744 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8863388.26040744, + 8809268.17165493, + 8858321.93534101 + ], + [ + 8670802.80762565, + 8683604.655381944, + 8637662.1044905 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-07T01:49:50Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json b/performance-results/2025-08-07T01:49:50Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json new file mode 100644 index 0000000000..96be8d6205 --- /dev/null +++ b/performance-results/2025-08-07T01:49:50Z-21bcb4a452a43aba0b9ac161b711dba520843525-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3536619392460922, + "scoreError" : 0.03438477327903431, + "scoreConfidence" : [ + 3.319277165967058, + 3.3880467125251266 + ], + "scorePercentiles" : { + "0.0" : 3.3487755126350396, + "50.0" : 3.3523588596310008, + "90.0" : 3.361154525087327, + "95.0" : 3.361154525087327, + "99.0" : 3.361154525087327, + "99.9" : 3.361154525087327, + "99.99" : 3.361154525087327, + "99.999" : 3.361154525087327, + "99.9999" : 3.361154525087327, + "100.0" : 3.361154525087327 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3514843049894876, + 3.361154525087327 + ], + [ + 3.3487755126350396, + 3.3532334142725144 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6858284005642281, + "scoreError" : 0.03325546398992875, + "scoreConfidence" : [ + 1.6525729365742994, + 1.7190838645541568 + ], + "scorePercentiles" : { + "0.0" : 1.6799361165831015, + "50.0" : 1.685795115686143, + "90.0" : 1.6917872543015255, + "95.0" : 1.6917872543015255, + "99.0" : 1.6917872543015255, + "99.9" : 1.6917872543015255, + "99.99" : 1.6917872543015255, + "99.999" : 1.6917872543015255, + "99.9999" : 1.6917872543015255, + "100.0" : 1.6917872543015255 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6836474820715919, + 1.6799361165831015 + ], + [ + 1.6917872543015255, + 1.6879427493006942 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8469397227587913, + "scoreError" : 0.03755178951046535, + "scoreConfidence" : [ + 0.8093879332483259, + 0.8844915122692566 + ], + "scorePercentiles" : { + "0.0" : 0.840565751038696, + "50.0" : 0.846348070263397, + "90.0" : 0.8544969994696753, + "95.0" : 0.8544969994696753, + "99.0" : 0.8544969994696753, + "99.9" : 0.8544969994696753, + "99.99" : 0.8544969994696753, + "99.999" : 0.8544969994696753, + "99.9999" : 0.8544969994696753, + "100.0" : 0.8544969994696753 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8451502761424292, + 0.8475458643843646 + ], + [ + 0.840565751038696, + 0.8544969994696753 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.24246667521709, + "scoreError" : 0.13330573302986878, + "scoreConfidence" : [ + 16.109160942187223, + 16.37577240824696 + ], + "scorePercentiles" : { + "0.0" : 16.19417151481468, + "50.0" : 16.236479670961074, + "90.0" : 16.31598298926825, + "95.0" : 16.31598298926825, + "99.0" : 16.31598298926825, + "99.9" : 16.31598298926825, + "99.99" : 16.31598298926825, + "99.999" : 16.31598298926825, + "99.9999" : 16.31598298926825, + "100.0" : 16.31598298926825 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.19417151481468, + 16.20815607211356, + 16.205856409772306 + ], + [ + 16.265829795525185, + 16.31598298926825, + 16.264803269808585 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2712.56494584262, + "scoreError" : 89.31490954529845, + "scoreConfidence" : [ + 2623.2500362973215, + 2801.8798553879187 + ], + "scorePercentiles" : { + "0.0" : 2683.356043650895, + "50.0" : 2710.1919958976587, + "90.0" : 2746.6766726448413, + "95.0" : 2746.6766726448413, + "99.0" : 2746.6766726448413, + "99.9" : 2746.6766726448413, + "99.99" : 2746.6766726448413, + "99.999" : 2746.6766726448413, + "99.9999" : 2746.6766726448413, + "100.0" : 2746.6766726448413 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2746.6766726448413, + 2736.244060557197, + 2741.5280556731327 + ], + [ + 2683.356043650895, + 2683.4449112915377, + 2684.1399312381204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74850.42000287138, + "scoreError" : 5945.021339870654, + "scoreConfidence" : [ + 68905.39866300073, + 80795.44134274204 + ], + "scorePercentiles" : { + "0.0" : 72449.88754180155, + "50.0" : 74965.47568189533, + "90.0" : 76785.37104531385, + "95.0" : 76785.37104531385, + "99.0" : 76785.37104531385, + "99.9" : 76785.37104531385, + "99.99" : 76785.37104531385, + "99.999" : 76785.37104531385, + "99.9999" : 76785.37104531385, + "100.0" : 76785.37104531385 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76752.43934269024, + 76774.50927102256, + 76785.37104531385 + ], + [ + 72449.88754180155, + 73178.51202110041, + 73161.80079529967 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 360.2381003397688, + "scoreError" : 10.597247664779028, + "scoreConfidence" : [ + 349.64085267498973, + 370.8353480045478 + ], + "scorePercentiles" : { + "0.0" : 356.43026709147057, + "50.0" : 360.16634642598564, + "90.0" : 364.03545065362835, + "95.0" : 364.03545065362835, + "99.0" : 364.03545065362835, + "99.9" : 364.03545065362835, + "99.99" : 364.03545065362835, + "99.999" : 364.03545065362835, + "99.9999" : 364.03545065362835, + "100.0" : 364.03545065362835 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 357.0245246227678, + 356.944372860878, + 356.43026709147057 + ], + [ + 363.3081682292035, + 363.6858185806646, + 364.03545065362835 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.7138832030367, + "scoreError" : 7.594402191221892, + "scoreConfidence" : [ + 107.11948101181481, + 122.30828539425859 + ], + "scorePercentiles" : { + "0.0" : 111.77782948230025, + "50.0" : 114.99659289632532, + "90.0" : 117.38560537884634, + "95.0" : 117.38560537884634, + "99.0" : 117.38560537884634, + "99.9" : 117.38560537884634, + "99.99" : 117.38560537884634, + "99.999" : 117.38560537884634, + "99.9999" : 117.38560537884634, + "100.0" : 117.38560537884634 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.19242172861044, + 116.85197713262424, + 117.38560537884634 + ], + [ + 111.93425683581255, + 111.77782948230025, + 113.14120866002641 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061371458331936544, + "scoreError" : 8.15929234320626E-4, + "scoreConfidence" : [ + 0.06055552909761592, + 0.06218738756625717 + ], + "scorePercentiles" : { + "0.0" : 0.061100917844879206, + "50.0" : 0.06133025863830799, + "90.0" : 0.061730857780439026, + "95.0" : 0.061730857780439026, + "99.0" : 0.061730857780439026, + "99.9" : 0.061730857780439026, + "99.99" : 0.061730857780439026, + "99.999" : 0.061730857780439026, + "99.9999" : 0.061730857780439026, + "100.0" : 0.061730857780439026 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061100917844879206, + 0.061119652338402115, + 0.061114430691193544 + ], + [ + 0.06154086493821386, + 0.061730857780439026, + 0.061622026398491514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7793359196776517E-4, + "scoreError" : 3.8959550050263445E-5, + "scoreConfidence" : [ + 3.389740419175017E-4, + 4.168931420180286E-4 + ], + "scorePercentiles" : { + "0.0" : 3.650415335387452E-4, + "50.0" : 3.778435392447382E-4, + "90.0" : 3.9105369539325685E-4, + "95.0" : 3.9105369539325685E-4, + "99.0" : 3.9105369539325685E-4, + "99.9" : 3.9105369539325685E-4, + "99.99" : 3.9105369539325685E-4, + "99.999" : 3.9105369539325685E-4, + "99.9999" : 3.9105369539325685E-4, + "100.0" : 3.9105369539325685E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9105369539325685E-4, + 3.9071967801257505E-4, + 3.9006178945230624E-4 + ], + [ + 3.656252890371702E-4, + 3.650415335387452E-4, + 3.6509956637253727E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12226799022279823, + "scoreError" : 8.685677275495095E-4, + "scoreConfidence" : [ + 0.12139942249524872, + 0.12313655795034774 + ], + "scorePercentiles" : { + "0.0" : 0.12193006270727663, + "50.0" : 0.12224291643862245, + "90.0" : 0.12264513168093405, + "95.0" : 0.12264513168093405, + "99.0" : 0.12264513168093405, + "99.9" : 0.12264513168093405, + "99.99" : 0.12264513168093405, + "99.999" : 0.12264513168093405, + "99.9999" : 0.12264513168093405, + "100.0" : 0.12264513168093405 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12203114869185337, + 0.1220163051807023, + 0.12193006270727663 + ], + [ + 0.12245468418539154, + 0.12253060889063151, + 0.12264513168093405 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013136952756678205, + "scoreError" : 6.112927037590135E-4, + "scoreConfidence" : [ + 0.01252566005291919, + 0.013748245460437219 + ], + "scorePercentiles" : { + "0.0" : 0.012936253689696791, + "50.0" : 0.013124057278914986, + "90.0" : 0.013356179419200857, + "95.0" : 0.013356179419200857, + "99.0" : 0.013356179419200857, + "99.9" : 0.013356179419200857, + "99.99" : 0.013356179419200857, + "99.999" : 0.013356179419200857, + "99.9999" : 0.013356179419200857, + "100.0" : 0.013356179419200857 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013356179419200857, + 0.013341681998292287, + 0.013308481492818177 + ], + [ + 0.012939633065011794, + 0.012936253689696791, + 0.012939486875049332 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9784550340529479, + "scoreError" : 0.002287147274399012, + "scoreConfidence" : [ + 0.9761678867785488, + 0.9807421813273469 + ], + "scorePercentiles" : { + "0.0" : 0.977492648910175, + "50.0" : 0.978415199484991, + "90.0" : 0.9797705126848859, + "95.0" : 0.9797705126848859, + "99.0" : 0.9797705126848859, + "99.9" : 0.9797705126848859, + "99.99" : 0.9797705126848859, + "99.999" : 0.9797705126848859, + "99.9999" : 0.9797705126848859, + "100.0" : 0.9797705126848859 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9788403001859646, + 0.9786201675310696, + 0.9797705126848859 + ], + [ + 0.9782102314389123, + 0.977492648910175, + 0.9777963435666797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010650005762342553, + "scoreError" : 9.262584344790854E-5, + "scoreConfidence" : [ + 0.010557379918894645, + 0.01074263160579046 + ], + "scorePercentiles" : { + "0.0" : 0.010613410845358023, + "50.0" : 0.010652172472746576, + "90.0" : 0.010681700297369815, + "95.0" : 0.010681700297369815, + "99.0" : 0.010681700297369815, + "99.9" : 0.010681700297369815, + "99.99" : 0.010681700297369815, + "99.999" : 0.010681700297369815, + "99.9999" : 0.010681700297369815, + "100.0" : 0.010681700297369815 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010621256633840873, + 0.01062556178810649, + 0.010613410845358023 + ], + [ + 0.010681700297369815, + 0.010679321851993447, + 0.010678783157386663 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.055242936812215, + "scoreError" : 0.07154720932299528, + "scoreConfidence" : [ + 2.98369572748922, + 3.1267901461352103 + ], + "scorePercentiles" : { + "0.0" : 3.023346483675937, + "50.0" : 3.0553576343305124, + "90.0" : 3.0847400647748304, + "95.0" : 3.0847400647748304, + "99.0" : 3.0847400647748304, + "99.9" : 3.0847400647748304, + "99.99" : 3.0847400647748304, + "99.999" : 3.0847400647748304, + "99.9999" : 3.0847400647748304, + "100.0" : 3.0847400647748304 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0790771761083744, + 3.0847400647748304, + 3.0682033599019007 + ], + [ + 3.033578627653123, + 3.042511908759124, + 3.023346483675937 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.796950429791837, + "scoreError" : 0.015569060297775937, + "scoreConfidence" : [ + 2.7813813694940612, + 2.812519490089613 + ], + "scorePercentiles" : { + "0.0" : 2.789528611436541, + "50.0" : 2.79638408672798, + "90.0" : 2.80609754657688, + "95.0" : 2.80609754657688, + "99.0" : 2.80609754657688, + "99.9" : 2.80609754657688, + "99.99" : 2.80609754657688, + "99.999" : 2.80609754657688, + "99.9999" : 2.80609754657688, + "100.0" : 2.80609754657688 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.789528611436541, + 2.7989215034984607, + 2.7949219737356805 + ], + [ + 2.80609754657688, + 2.7943867437831797, + 2.7978461997202797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17785033384017568, + "scoreError" : 0.003750596270401966, + "scoreConfidence" : [ + 0.1740997375697737, + 0.18160093011057765 + ], + "scorePercentiles" : { + "0.0" : 0.17653166990891117, + "50.0" : 0.17764309205761575, + "90.0" : 0.18022122968516283, + "95.0" : 0.18022122968516283, + "99.0" : 0.18022122968516283, + "99.9" : 0.18022122968516283, + "99.99" : 0.18022122968516283, + "99.999" : 0.18022122968516283, + "99.9999" : 0.18022122968516283, + "100.0" : 0.18022122968516283 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18022122968516283, + 0.17673834949277156, + 0.17653166990891117 + ], + [ + 0.17832456983897715, + 0.17777944767204137, + 0.1775067364431901 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3308607994661946, + "scoreError" : 0.010480800599952827, + "scoreConfidence" : [ + 0.3203799988662418, + 0.34134160006614744 + ], + "scorePercentiles" : { + "0.0" : 0.3273698471863031, + "50.0" : 0.3308263458590424, + "90.0" : 0.33452472241921455, + "95.0" : 0.33452472241921455, + "99.0" : 0.33452472241921455, + "99.9" : 0.33452472241921455, + "99.99" : 0.33452472241921455, + "99.999" : 0.33452472241921455, + "99.9999" : 0.33452472241921455, + "100.0" : 0.33452472241921455 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32757947156708594, + 0.32740705395495023, + 0.3273698471863031 + ], + [ + 0.33452472241921455, + 0.33421048151861504, + 0.3340732201509989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14625859890630358, + "scoreError" : 0.010556563505873962, + "scoreConfidence" : [ + 0.1357020354004296, + 0.15681516241217755 + ], + "scorePercentiles" : { + "0.0" : 0.14294837777491887, + "50.0" : 0.14539829600525694, + "90.0" : 0.15167139483422817, + "95.0" : 0.15167139483422817, + "99.0" : 0.15167139483422817, + "99.9" : 0.15167139483422817, + "99.99" : 0.15167139483422817, + "99.999" : 0.15167139483422817, + "99.9999" : 0.15167139483422817, + "100.0" : 0.15167139483422817 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15167139483422817, + 0.14911512576046762, + 0.14768699146384687 + ], + [ + 0.14302010305769286, + 0.14294837777491887, + 0.14310960054666705 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40398766036467143, + "scoreError" : 0.014300786928609664, + "scoreConfidence" : [ + 0.3896868734360618, + 0.4182884472932811 + ], + "scorePercentiles" : { + "0.0" : 0.3962160711965135, + "50.0" : 0.40663445854323593, + "90.0" : 0.407955883979929, + "95.0" : 0.407955883979929, + "99.0" : 0.407955883979929, + "99.9" : 0.407955883979929, + "99.99" : 0.407955883979929, + "99.999" : 0.407955883979929, + "99.9999" : 0.407955883979929, + "100.0" : 0.407955883979929 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.407564979948649, + 0.407955883979929, + 0.4074731948417064 + ], + [ + 0.40579572224476546, + 0.3962160711965135, + 0.39892010997646493 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1571069799884299, + "scoreError" : 0.0030859409703396855, + "scoreConfidence" : [ + 0.15402103901809022, + 0.16019292095876958 + ], + "scorePercentiles" : { + "0.0" : 0.15610340576316692, + "50.0" : 0.1569789874359973, + "90.0" : 0.15866786540475358, + "95.0" : 0.15866786540475358, + "99.0" : 0.15866786540475358, + "99.9" : 0.15866786540475358, + "99.99" : 0.15866786540475358, + "99.999" : 0.15866786540475358, + "99.9999" : 0.15866786540475358, + "100.0" : 0.15866786540475358 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15866786540475358, + 0.15780294680532106, + 0.157720603422443 + ], + [ + 0.1561096870853432, + 0.15610340576316692, + 0.1562373714495516 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04636653388143363, + "scoreError" : 0.0039008169389196435, + "scoreConfidence" : [ + 0.042465716942513984, + 0.050267350820353274 + ], + "scorePercentiles" : { + "0.0" : 0.04473217972884116, + "50.0" : 0.04656581074930752, + "90.0" : 0.04762261058727165, + "95.0" : 0.04762261058727165, + "99.0" : 0.04762261058727165, + "99.9" : 0.04762261058727165, + "99.99" : 0.04762261058727165, + "99.999" : 0.04762261058727165, + "99.9999" : 0.04762261058727165, + "100.0" : 0.04762261058727165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04762261058727165, + 0.04761992425678217, + 0.047603569019193416 + ], + [ + 0.04552805247942162, + 0.045092867217091735, + 0.04473217972884116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8763012.210608648, + "scoreError" : 559309.3959529683, + "scoreConfidence" : [ + 8203702.81465568, + 9322321.606561616 + ], + "scorePercentiles" : { + "0.0" : 8553371.0, + "50.0" : 8775249.804187644, + "90.0" : 8946173.307692308, + "95.0" : 8946173.307692308, + "99.0" : 8946173.307692308, + "99.9" : 8946173.307692308, + "99.99" : 8946173.307692308, + "99.999" : 8946173.307692308, + "99.9999" : 8946173.307692308, + "100.0" : 8946173.307692308 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8946173.307692308, + 8944673.64432529, + 8942338.765862377 + ], + [ + 8553371.0, + 8583355.703259004, + 8608160.84251291 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-10T00:58:51Z-e62055e9b3353e84110b59d65450483809ebb494-jdk17.json b/performance-results/2025-08-10T00:58:51Z-e62055e9b3353e84110b59d65450483809ebb494-jdk17.json new file mode 100644 index 0000000000..7cf9344315 --- /dev/null +++ b/performance-results/2025-08-10T00:58:51Z-e62055e9b3353e84110b59d65450483809ebb494-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.321778067926701, + "scoreError" : 0.06017942358096126, + "scoreConfidence" : [ + 3.2615986443457397, + 3.381957491507662 + ], + "scorePercentiles" : { + "0.0" : 3.3120987070643566, + "50.0" : 3.3206747441821904, + "90.0" : 3.333664076278065, + "95.0" : 3.333664076278065, + "99.0" : 3.333664076278065, + "99.9" : 3.333664076278065, + "99.99" : 3.333664076278065, + "99.999" : 3.333664076278065, + "99.9999" : 3.333664076278065, + "100.0" : 3.333664076278065 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.317299490495786, + 3.333664076278065 + ], + [ + 3.3120987070643566, + 3.324049997868595 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6797370871853792, + "scoreError" : 0.04207283752159059, + "scoreConfidence" : [ + 1.6376642496637885, + 1.7218099247069698 + ], + "scorePercentiles" : { + "0.0" : 1.6718009621370309, + "50.0" : 1.6803353460386576, + "90.0" : 1.6864766945271703, + "95.0" : 1.6864766945271703, + "99.0" : 1.6864766945271703, + "99.9" : 1.6864766945271703, + "99.99" : 1.6864766945271703, + "99.999" : 1.6864766945271703, + "99.9999" : 1.6864766945271703, + "100.0" : 1.6864766945271703 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6833396799777685, + 1.6864766945271703 + ], + [ + 1.6718009621370309, + 1.6773310120995466 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8442547773833415, + "scoreError" : 0.020257401121910767, + "scoreConfidence" : [ + 0.8239973762614308, + 0.8645121785052523 + ], + "scorePercentiles" : { + "0.0" : 0.8417024477175072, + "50.0" : 0.8432457074462938, + "90.0" : 0.8488252469232714, + "95.0" : 0.8488252469232714, + "99.0" : 0.8488252469232714, + "99.9" : 0.8488252469232714, + "99.99" : 0.8488252469232714, + "99.999" : 0.8488252469232714, + "99.9999" : 0.8488252469232714, + "100.0" : 0.8488252469232714 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8431009154432363, + 0.8488252469232714 + ], + [ + 0.8417024477175072, + 0.8433904994493512 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.20027142681322, + "scoreError" : 0.3238406903965271, + "scoreConfidence" : [ + 15.876430736416694, + 16.524112117209746 + ], + "scorePercentiles" : { + "0.0" : 16.080331593537174, + "50.0" : 16.207478729169996, + "90.0" : 16.30780863164474, + "95.0" : 16.30780863164474, + "99.0" : 16.30780863164474, + "99.9" : 16.30780863164474, + "99.99" : 16.30780863164474, + "99.999" : 16.30780863164474, + "99.9999" : 16.30780863164474, + "100.0" : 16.30780863164474 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.30370736475651, + 16.30780863164474, + 16.304403352591166 + ], + [ + 16.111250093583482, + 16.094127524766268, + 16.080331593537174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2697.603994271927, + "scoreError" : 19.814257961873277, + "scoreConfidence" : [ + 2677.7897363100537, + 2717.4182522338006 + ], + "scorePercentiles" : { + "0.0" : 2686.0152872116787, + "50.0" : 2697.725057676475, + "90.0" : 2707.5108612046392, + "95.0" : 2707.5108612046392, + "99.0" : 2707.5108612046392, + "99.9" : 2707.5108612046392, + "99.99" : 2707.5108612046392, + "99.999" : 2707.5108612046392, + "99.9999" : 2707.5108612046392, + "100.0" : 2707.5108612046392 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2686.0152872116787, + 2695.485174895187, + 2701.1625269671067 + ], + [ + 2707.5108612046392, + 2697.645647797982, + 2697.804467554968 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75337.87958556948, + "scoreError" : 418.4145999976774, + "scoreConfidence" : [ + 74919.4649855718, + 75756.29418556715 + ], + "scorePercentiles" : { + "0.0" : 75186.79983511387, + "50.0" : 75328.27216108268, + "90.0" : 75501.9619513773, + "95.0" : 75501.9619513773, + "99.0" : 75501.9619513773, + "99.9" : 75501.9619513773, + "99.99" : 75501.9619513773, + "99.999" : 75501.9619513773, + "99.9999" : 75501.9619513773, + "100.0" : 75501.9619513773 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75483.22148080665, + 75501.9619513773, + 75430.5098312405 + ], + [ + 75226.03449092487, + 75186.79983511387, + 75198.74992395371 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 337.73843484400606, + "scoreError" : 4.966405842771722, + "scoreConfidence" : [ + 332.77202900123433, + 342.7048406867778 + ], + "scorePercentiles" : { + "0.0" : 335.84969932034323, + "50.0" : 337.44871393610606, + "90.0" : 340.46662773352284, + "95.0" : 340.46662773352284, + "99.0" : 340.46662773352284, + "99.9" : 340.46662773352284, + "99.99" : 340.46662773352284, + "99.999" : 340.46662773352284, + "99.9999" : 340.46662773352284, + "100.0" : 340.46662773352284 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 335.84969932034323, + 336.1780939294256, + 337.8844131892889 + ], + [ + 339.03876020853266, + 340.46662773352284, + 337.01301468292314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.28515233156683, + "scoreError" : 5.348608376034191, + "scoreConfidence" : [ + 107.93654395553264, + 118.63376070760103 + ], + "scorePercentiles" : { + "0.0" : 111.17781836868595, + "50.0" : 113.2612083998196, + "90.0" : 115.31063193097873, + "95.0" : 115.31063193097873, + "99.0" : 115.31063193097873, + "99.9" : 115.31063193097873, + "99.99" : 115.31063193097873, + "99.999" : 115.31063193097873, + "99.9999" : 115.31063193097873, + "100.0" : 115.31063193097873 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.31063193097873, + 114.74575132985568, + 114.96704057050371 + ], + [ + 111.77666546978352, + 111.73300631959326, + 111.17781836868595 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06193014219243833, + "scoreError" : 2.6863577664159905E-4, + "scoreConfidence" : [ + 0.06166150641579673, + 0.06219877796907993 + ], + "scorePercentiles" : { + "0.0" : 0.06176354682230869, + "50.0" : 0.06193738990042652, + "90.0" : 0.06204704301021896, + "95.0" : 0.06204704301021896, + "99.0" : 0.06204704301021896, + "99.9" : 0.06204704301021896, + "99.99" : 0.06204704301021896, + "99.999" : 0.06204704301021896, + "99.9999" : 0.06204704301021896, + "100.0" : 0.06204704301021896 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06191079722024454, + 0.06198468630100475, + 0.061959886794674006 + ], + [ + 0.06204704301021896, + 0.06176354682230869, + 0.06191489300617903 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.685196658632991E-4, + "scoreError" : 2.3942502423480805E-5, + "scoreConfidence" : [ + 3.445771634398183E-4, + 3.924621682867799E-4 + ], + "scorePercentiles" : { + "0.0" : 3.606428488687736E-4, + "50.0" : 3.681985941374151E-4, + "90.0" : 3.772912687044325E-4, + "95.0" : 3.772912687044325E-4, + "99.0" : 3.772912687044325E-4, + "99.9" : 3.772912687044325E-4, + "99.99" : 3.772912687044325E-4, + "99.999" : 3.772912687044325E-4, + "99.9999" : 3.772912687044325E-4, + "100.0" : 3.772912687044325E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7614169322739284E-4, + 3.754512109854938E-4, + 3.772912687044325E-4 + ], + [ + 3.606428488687736E-4, + 3.606449961043658E-4, + 3.609459772893363E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12550309194144402, + "scoreError" : 0.0018973263214985816, + "scoreConfidence" : [ + 0.12360576561994543, + 0.1274004182629426 + ], + "scorePercentiles" : { + "0.0" : 0.12480652030551881, + "50.0" : 0.12544488604441703, + "90.0" : 0.12625016539578335, + "95.0" : 0.12625016539578335, + "99.0" : 0.12625016539578335, + "99.9" : 0.12625016539578335, + "99.99" : 0.12625016539578335, + "99.999" : 0.12625016539578335, + "99.9999" : 0.12625016539578335, + "100.0" : 0.12625016539578335 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1261478709034488, + 0.12593886717461117, + 0.12625016539578335 + ], + [ + 0.1249242229550792, + 0.12480652030551881, + 0.12495090491422288 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013012037266278545, + "scoreError" : 2.650845980540564E-4, + "scoreConfidence" : [ + 0.012746952668224489, + 0.013277121864332601 + ], + "scorePercentiles" : { + "0.0" : 0.012922141628816023, + "50.0" : 0.01301348104187932, + "90.0" : 0.013105257174384257, + "95.0" : 0.013105257174384257, + "99.0" : 0.013105257174384257, + "99.9" : 0.013105257174384257, + "99.99" : 0.013105257174384257, + "99.999" : 0.013105257174384257, + "99.9999" : 0.013105257174384257, + "100.0" : 0.013105257174384257 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01293311627236268, + 0.012922141628816023, + 0.01292241661670147 + ], + [ + 0.013105257174384257, + 0.013095446094010883, + 0.013093845811395957 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9482690844532632, + "scoreError" : 0.06266368397890038, + "scoreConfidence" : [ + 0.8856054004743628, + 1.0109327684321636 + ], + "scorePercentiles" : { + "0.0" : 0.9274287045349161, + "50.0" : 0.9475473330727355, + "90.0" : 0.9698123789759503, + "95.0" : 0.9698123789759503, + "99.0" : 0.9698123789759503, + "99.9" : 0.9698123789759503, + "99.99" : 0.9698123789759503, + "99.999" : 0.9698123789759503, + "99.9999" : 0.9698123789759503, + "100.0" : 0.9698123789759503 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9666323954185192, + 0.9694791732428503, + 0.9698123789759503 + ], + [ + 0.9277995838203915, + 0.928462270726952, + 0.9274287045349161 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010321762326941849, + "scoreError" : 7.921850886930279E-5, + "scoreConfidence" : [ + 0.010242543818072545, + 0.010400980835811152 + ], + "scorePercentiles" : { + "0.0" : 0.010290568372937308, + "50.0" : 0.010323231981216981, + "90.0" : 0.010350156109112437, + "95.0" : 0.010350156109112437, + "99.0" : 0.010350156109112437, + "99.9" : 0.010350156109112437, + "99.99" : 0.010350156109112437, + "99.999" : 0.010350156109112437, + "99.9999" : 0.010350156109112437, + "100.0" : 0.010350156109112437 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010341486276253607, + 0.010349444320714999, + 0.010350156109112437 + ], + [ + 0.010304977686180354, + 0.010293941196452393, + 0.010290568372937308 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.161475491166344, + "scoreError" : 0.09101410884471757, + "scoreConfidence" : [ + 3.0704613823216262, + 3.2524896000110615 + ], + "scorePercentiles" : { + "0.0" : 3.1204619631940114, + "50.0" : 3.1625255298414428, + "90.0" : 3.1975480812020463, + "95.0" : 3.1975480812020463, + "99.0" : 3.1975480812020463, + "99.9" : 3.1975480812020463, + "99.99" : 3.1975480812020463, + "99.999" : 3.1975480812020463, + "99.9999" : 3.1975480812020463, + "100.0" : 3.1975480812020463 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1204619631940114, + 3.142991798868636, + 3.13537856677116 + ], + [ + 3.190413276147959, + 3.1820592608142495, + 3.1975480812020463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.897403921009786, + "scoreError" : 0.05900639446323345, + "scoreConfidence" : [ + 2.8383975265465526, + 2.9564103154730192 + ], + "scorePercentiles" : { + "0.0" : 2.867888256954402, + "50.0" : 2.9047655933254974, + "90.0" : 2.920863092581776, + "95.0" : 2.920863092581776, + "99.0" : 2.920863092581776, + "99.9" : 2.920863092581776, + "99.99" : 2.920863092581776, + "99.999" : 2.920863092581776, + "99.9999" : 2.920863092581776, + "100.0" : 2.920863092581776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9110427619324795, + 2.9052258260238166, + 2.920863092581776 + ], + [ + 2.904305360627178, + 2.875098227939063, + 2.867888256954402 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1749812130276415, + "scoreError" : 0.004638338536154302, + "scoreConfidence" : [ + 0.1703428744914872, + 0.1796195515637958 + ], + "scorePercentiles" : { + "0.0" : 0.17344220262934248, + "50.0" : 0.1748887393124293, + "90.0" : 0.17666563887220435, + "95.0" : 0.17666563887220435, + "99.0" : 0.17666563887220435, + "99.9" : 0.17666563887220435, + "99.99" : 0.17666563887220435, + "99.999" : 0.17666563887220435, + "99.9999" : 0.17666563887220435, + "100.0" : 0.17666563887220435 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17666563887220435, + 0.17651663562388575, + 0.17627828653269875 + ], + [ + 0.17344220262934248, + 0.17349919209215983, + 0.17348532241555784 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33007612569864825, + "scoreError" : 0.020004809758620647, + "scoreConfidence" : [ + 0.3100713159400276, + 0.35008093545726887 + ], + "scorePercentiles" : { + "0.0" : 0.32345676757123915, + "50.0" : 0.3300183758535818, + "90.0" : 0.3369215387958627, + "95.0" : 0.3369215387958627, + "99.0" : 0.3369215387958627, + "99.9" : 0.3369215387958627, + "99.99" : 0.3369215387958627, + "99.999" : 0.3369215387958627, + "99.9999" : 0.3369215387958627, + "100.0" : 0.3369215387958627 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32365199614861806, + 0.3235899358982656, + 0.32345676757123915 + ], + [ + 0.3369215387958627, + 0.3363847555585455, + 0.33645176021935874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14460657985773762, + "scoreError" : 0.004127252677088936, + "scoreConfidence" : [ + 0.14047932718064868, + 0.14873383253482655 + ], + "scorePercentiles" : { + "0.0" : 0.14315282445567373, + "50.0" : 0.14462592479770905, + "90.0" : 0.14605969636467203, + "95.0" : 0.14605969636467203, + "99.0" : 0.14605969636467203, + "99.9" : 0.14605969636467203, + "99.99" : 0.14605969636467203, + "99.999" : 0.14605969636467203, + "99.9999" : 0.14605969636467203, + "100.0" : 0.14605969636467203 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14327865907788412, + 0.14336528933107778, + 0.14315282445567373 + ], + [ + 0.1458964496527778, + 0.14588656026434033, + 0.14605969636467203 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4052789081948393, + "scoreError" : 0.005784482209340655, + "scoreConfidence" : [ + 0.39949442598549867, + 0.41106339040417994 + ], + "scorePercentiles" : { + "0.0" : 0.4024967646703695, + "50.0" : 0.40484495168124035, + "90.0" : 0.4087639782546495, + "95.0" : 0.4087639782546495, + "99.0" : 0.4087639782546495, + "99.9" : 0.4087639782546495, + "99.99" : 0.4087639782546495, + "99.999" : 0.4087639782546495, + "99.9999" : 0.4087639782546495, + "100.0" : 0.4087639782546495 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4087639782546495, + 0.4048226489090394, + 0.4024967646703695 + ], + [ + 0.40606797222560603, + 0.4048672544534413, + 0.40465483065593005 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1562775176508592, + "scoreError" : 0.013567284867229292, + "scoreConfidence" : [ + 0.1427102327836299, + 0.1698448025180885 + ], + "scorePercentiles" : { + "0.0" : 0.15180776898671727, + "50.0" : 0.15620879328266668, + "90.0" : 0.16084495966094606, + "95.0" : 0.16084495966094606, + "99.0" : 0.16084495966094606, + "99.9" : 0.16084495966094606, + "99.99" : 0.16084495966094606, + "99.999" : 0.16084495966094606, + "99.9999" : 0.16084495966094606, + "100.0" : 0.16084495966094606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16084495966094606, + 0.1607522307383176, + 0.16048082721378823 + ], + [ + 0.15184255995384077, + 0.15180776898671727, + 0.15193675935154516 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04609910800295767, + "scoreError" : 0.0020054306697937273, + "scoreConfidence" : [ + 0.04409367733316394, + 0.0481045386727514 + ], + "scorePercentiles" : { + "0.0" : 0.04531589885262691, + "50.0" : 0.046189144027595, + "90.0" : 0.0469024258203103, + "95.0" : 0.0469024258203103, + "99.0" : 0.0469024258203103, + "99.9" : 0.0469024258203103, + "99.99" : 0.0469024258203103, + "99.999" : 0.0469024258203103, + "99.9999" : 0.0469024258203103, + "100.0" : 0.0469024258203103 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045753826659468165, + 0.04531589885262691, + 0.04533446812397717 + ], + [ + 0.0469024258203103, + 0.04662446139572182, + 0.04666356716564165 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8842699.314488744, + "scoreError" : 275129.4390939223, + "scoreConfidence" : [ + 8567569.875394821, + 9117828.753582668 + ], + "scorePercentiles" : { + "0.0" : 8720771.571926765, + "50.0" : 8850722.605901606, + "90.0" : 8943478.028596962, + "95.0" : 8943478.028596962, + "99.0" : 8943478.028596962, + "99.9" : 8943478.028596962, + "99.99" : 8943478.028596962, + "99.999" : 8943478.028596962, + "99.9999" : 8943478.028596962, + "100.0" : 8943478.028596962 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8933892.490178572, + 8943478.028596962, + 8910940.202137133 + ], + [ + 8720771.571926765, + 8756608.584426947, + 8790505.009666082 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-10T00:59:21Z-e62055e9b3353e84110b59d65450483809ebb494-jdk17.json b/performance-results/2025-08-10T00:59:21Z-e62055e9b3353e84110b59d65450483809ebb494-jdk17.json new file mode 100644 index 0000000000..c6ec66b397 --- /dev/null +++ b/performance-results/2025-08-10T00:59:21Z-e62055e9b3353e84110b59d65450483809ebb494-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.314241485308907, + "scoreError" : 0.0448766378380948, + "scoreConfidence" : [ + 3.269364847470812, + 3.3591181231470015 + ], + "scorePercentiles" : { + "0.0" : 3.30469589138146, + "50.0" : 3.3156116516955576, + "90.0" : 3.321046746463052, + "95.0" : 3.321046746463052, + "99.0" : 3.321046746463052, + "99.9" : 3.321046746463052, + "99.99" : 3.321046746463052, + "99.999" : 3.321046746463052, + "99.9999" : 3.321046746463052, + "100.0" : 3.321046746463052 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.30469589138146, + 3.3142883394694502 + ], + [ + 3.3169349639216645, + 3.321046746463052 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.672411943764561, + "scoreError" : 0.0170175325435611, + "scoreConfidence" : [ + 1.655394411221, + 1.6894294763081221 + ], + "scorePercentiles" : { + "0.0" : 1.6698980905545864, + "50.0" : 1.6719227472851887, + "90.0" : 1.6759041899332803, + "95.0" : 1.6759041899332803, + "99.0" : 1.6759041899332803, + "99.9" : 1.6759041899332803, + "99.99" : 1.6759041899332803, + "99.999" : 1.6759041899332803, + "99.9999" : 1.6759041899332803, + "100.0" : 1.6759041899332803 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6698980905545864, + 1.6759041899332803 + ], + [ + 1.6728745389252595, + 1.6709709556451182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8376702682332442, + "scoreError" : 0.05001458965415688, + "scoreConfidence" : [ + 0.7876556785790874, + 0.887684857887401 + ], + "scorePercentiles" : { + "0.0" : 0.8263738236394508, + "50.0" : 0.8401926937668663, + "90.0" : 0.8439218617597934, + "95.0" : 0.8439218617597934, + "99.0" : 0.8439218617597934, + "99.9" : 0.8439218617597934, + "99.99" : 0.8439218617597934, + "99.999" : 0.8439218617597934, + "99.9999" : 0.8439218617597934, + "100.0" : 0.8439218617597934 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8263738236394508, + 0.840577906557115 + ], + [ + 0.8398074809766177, + 0.8439218617597934 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.840350900971098, + "scoreError" : 0.23220231220249005, + "scoreConfidence" : [ + 15.608148588768607, + 16.072553213173588 + ], + "scorePercentiles" : { + "0.0" : 15.744957557569032, + "50.0" : 15.821157943453933, + "90.0" : 15.96306995939143, + "95.0" : 15.96306995939143, + "99.0" : 15.96306995939143, + "99.9" : 15.96306995939143, + "99.99" : 15.96306995939143, + "99.999" : 15.96306995939143, + "99.9999" : 15.96306995939143, + "100.0" : 15.96306995939143 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.744957557569032, + 15.85308176330583, + 15.96306995939143 + ], + [ + 15.906245727670672, + 15.789234123602034, + 15.78551627428759 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2654.2909465541547, + "scoreError" : 93.17097192294823, + "scoreConfidence" : [ + 2561.1199746312063, + 2747.461918477103 + ], + "scorePercentiles" : { + "0.0" : 2602.9160123915294, + "50.0" : 2653.1209273299664, + "90.0" : 2697.744132487091, + "95.0" : 2697.744132487091, + "99.0" : 2697.744132487091, + "99.9" : 2697.744132487091, + "99.99" : 2697.744132487091, + "99.999" : 2697.744132487091, + "99.9999" : 2697.744132487091, + "100.0" : 2697.744132487091 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2697.744132487091, + 2678.6829799756924, + 2640.160699810684 + ], + [ + 2602.9160123915294, + 2662.989771169244, + 2643.2520834906895 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75482.78742610964, + "scoreError" : 2030.6275869270132, + "scoreConfidence" : [ + 73452.15983918263, + 77513.41501303666 + ], + "scorePercentiles" : { + "0.0" : 74723.50901187926, + "50.0" : 75485.01111203729, + "90.0" : 76185.90345028992, + "95.0" : 76185.90345028992, + "99.0" : 76185.90345028992, + "99.9" : 76185.90345028992, + "99.99" : 76185.90345028992, + "99.999" : 76185.90345028992, + "99.9999" : 76185.90345028992, + "100.0" : 76185.90345028992 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74886.80831528471, + 74862.89444160186, + 74723.50901187926 + ], + [ + 76185.90345028992, + 76154.39542881229, + 76083.21390878987 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 341.35709905231573, + "scoreError" : 12.367853139149881, + "scoreConfidence" : [ + 328.98924591316586, + 353.7249521914656 + ], + "scorePercentiles" : { + "0.0" : 336.6858052927803, + "50.0" : 341.03891123609515, + "90.0" : 346.36553295799604, + "95.0" : 346.36553295799604, + "99.0" : 346.36553295799604, + "99.9" : 346.36553295799604, + "99.99" : 346.36553295799604, + "99.999" : 346.36553295799604, + "99.9999" : 346.36553295799604, + "100.0" : 346.36553295799604 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 344.0818858779343, + 345.4810288766461, + 346.36553295799604 + ], + [ + 337.5324047142815, + 336.6858052927803, + 337.99593659425597 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 110.27076571734129, + "scoreError" : 4.912661381916792, + "scoreConfidence" : [ + 105.3581043354245, + 115.18342709925808 + ], + "scorePercentiles" : { + "0.0" : 107.62582519609437, + "50.0" : 110.06187939592867, + "90.0" : 112.78436462458303, + "95.0" : 112.78436462458303, + "99.0" : 112.78436462458303, + "99.9" : 112.78436462458303, + "99.99" : 112.78436462458303, + "99.999" : 112.78436462458303, + "99.9999" : 112.78436462458303, + "100.0" : 112.78436462458303 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 107.62582519609437, + 109.66193772315671, + 112.78436462458303 + ], + [ + 109.72044783664668, + 110.40331095521066, + 111.42870796835619 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06326632979284742, + "scoreError" : 0.0022894109747256283, + "scoreConfidence" : [ + 0.0609769188181218, + 0.06555574076757305 + ], + "scorePercentiles" : { + "0.0" : 0.06232494769184746, + "50.0" : 0.06334517971761158, + "90.0" : 0.06413928341906436, + "95.0" : 0.06413928341906436, + "99.0" : 0.06413928341906436, + "99.9" : 0.06413928341906436, + "99.99" : 0.06413928341906436, + "99.999" : 0.06413928341906436, + "99.9999" : 0.06413928341906436, + "100.0" : 0.06413928341906436 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06239755305554515, + 0.06232494769184746, + 0.06295168728714866 + ], + [ + 0.06404583515540441, + 0.0637386721480745, + 0.06413928341906436 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.9128153000748646E-4, + "scoreError" : 2.873393242371398E-6, + "scoreConfidence" : [ + 3.8840813676511505E-4, + 3.941549232498579E-4 + ], + "scorePercentiles" : { + "0.0" : 3.9020809833837067E-4, + "50.0" : 3.9107640636765434E-4, + "90.0" : 3.928522614436148E-4, + "95.0" : 3.928522614436148E-4, + "99.0" : 3.928522614436148E-4, + "99.9" : 3.928522614436148E-4, + "99.99" : 3.928522614436148E-4, + "99.999" : 3.928522614436148E-4, + "99.9999" : 3.928522614436148E-4, + "100.0" : 3.928522614436148E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.9110461260082887E-4, + 3.921157446368011E-4, + 3.9036026289082323E-4 + ], + [ + 3.9020809833837067E-4, + 3.9104820013447986E-4, + 3.928522614436148E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12531456045649733, + "scoreError" : 0.00307411399812817, + "scoreConfidence" : [ + 0.12224044645836916, + 0.1283886744546255 + ], + "scorePercentiles" : { + "0.0" : 0.12365783431433164, + "50.0" : 0.12552688706244375, + "90.0" : 0.12667958988358394, + "95.0" : 0.12667958988358394, + "99.0" : 0.12667958988358394, + "99.9" : 0.12667958988358394, + "99.99" : 0.12667958988358394, + "99.999" : 0.12667958988358394, + "99.9999" : 0.12667958988358394, + "100.0" : 0.12667958988358394 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12573941613438616, + 0.12602639042218022, + 0.12667958988358394 + ], + [ + 0.12446977399400072, + 0.12531435799050136, + 0.12365783431433164 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013038024350847078, + "scoreError" : 2.628846559497434E-4, + "scoreConfidence" : [ + 0.012775139694897334, + 0.013300909006796821 + ], + "scorePercentiles" : { + "0.0" : 0.012938928823827004, + "50.0" : 0.013035530742388224, + "90.0" : 0.013146320388336751, + "95.0" : 0.013146320388336751, + "99.0" : 0.013146320388336751, + "99.9" : 0.013146320388336751, + "99.99" : 0.013146320388336751, + "99.999" : 0.013146320388336751, + "99.9999" : 0.013146320388336751, + "100.0" : 0.013146320388336751 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013107145699860542, + 0.013113750912378846, + 0.013146320388336751 + ], + [ + 0.012938928823827004, + 0.012963915784915904, + 0.01295808449576342 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0211754416662497, + "scoreError" : 0.028504756141734134, + "scoreConfidence" : [ + 0.9926706855245157, + 1.049680197807984 + ], + "scorePercentiles" : { + "0.0" : 1.0113308321367176, + "50.0" : 1.0193873499276875, + "90.0" : 1.032894407457137, + "95.0" : 1.032894407457137, + "99.0" : 1.032894407457137, + "99.9" : 1.032894407457137, + "99.99" : 1.032894407457137, + "99.999" : 1.032894407457137, + "99.9999" : 1.032894407457137, + "100.0" : 1.032894407457137 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0317668414319612, + 1.032894407457137, + 1.0258987251743947 + ], + [ + 1.0113308321367176, + 1.0128759746809803, + 1.0122858691163072 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010658715046327913, + "scoreError" : 1.5374315278234845E-4, + "scoreConfidence" : [ + 0.010504971893545564, + 0.010812458199110262 + ], + "scorePercentiles" : { + "0.0" : 0.010602114442439522, + "50.0" : 0.010651404341008378, + "90.0" : 0.010742738643663591, + "95.0" : 0.010742738643663591, + "99.0" : 0.010742738643663591, + "99.9" : 0.010742738643663591, + "99.99" : 0.010742738643663591, + "99.999" : 0.010742738643663591, + "99.9999" : 0.010742738643663591, + "100.0" : 0.010742738643663591 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010651900564962123, + 0.010700150910125873, + 0.010742738643663591 + ], + [ + 0.010602114442439522, + 0.010604477599721746, + 0.010650908117054634 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.4382215303404653, + "scoreError" : 0.5451237699005419, + "scoreConfidence" : [ + 2.8930977604399235, + 3.983345300241007 + ], + "scorePercentiles" : { + "0.0" : 3.2528599057217167, + "50.0" : 3.440334851062314, + "90.0" : 3.6309184165457182, + "95.0" : 3.6309184165457182, + "99.0" : 3.6309184165457182, + "99.9" : 3.6309184165457182, + "99.99" : 3.6309184165457182, + "99.999" : 3.6309184165457182, + "99.9999" : 3.6309184165457182, + "100.0" : 3.6309184165457182 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.274063681937173, + 3.256243556640625, + 3.2528599057217167 + ], + [ + 3.608637601010101, + 3.606606020187455, + 3.6309184165457182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.890485484888236, + "scoreError" : 0.06829794888036585, + "scoreConfidence" : [ + 2.8221875360078705, + 2.958783433768602 + ], + "scorePercentiles" : { + "0.0" : 2.8619255064377684, + "50.0" : 2.89243763271919, + "90.0" : 2.9170488314377367, + "95.0" : 2.9170488314377367, + "99.0" : 2.9170488314377367, + "99.9" : 2.9170488314377367, + "99.99" : 2.9170488314377367, + "99.999" : 2.9170488314377367, + "99.9999" : 2.9170488314377367, + "100.0" : 2.9170488314377367 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8638599026345934, + 2.8847825835015866, + 2.8619255064377684 + ], + [ + 2.9170488314377367, + 2.9152034033809384, + 2.900092681936793 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18015471253528567, + "scoreError" : 0.007531678254298898, + "scoreConfidence" : [ + 0.17262303428098677, + 0.18768639078958457 + ], + "scorePercentiles" : { + "0.0" : 0.17765863126010412, + "50.0" : 0.17937288614973781, + "90.0" : 0.1848235253848855, + "95.0" : 0.1848235253848855, + "99.0" : 0.1848235253848855, + "99.9" : 0.1848235253848855, + "99.99" : 0.1848235253848855, + "99.999" : 0.1848235253848855, + "99.9999" : 0.1848235253848855, + "100.0" : 0.1848235253848855 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17881892570273944, + 0.17811531162169383, + 0.17765863126010412 + ], + [ + 0.1848235253848855, + 0.18158503464555492, + 0.1799268465967362 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3307123182673856, + "scoreError" : 0.006132333375807538, + "scoreConfidence" : [ + 0.3245799848915781, + 0.33684465164319316 + ], + "scorePercentiles" : { + "0.0" : 0.3282446893258058, + "50.0" : 0.3305912574271351, + "90.0" : 0.3335465067040224, + "95.0" : 0.3335465067040224, + "99.0" : 0.3335465067040224, + "99.9" : 0.3335465067040224, + "99.99" : 0.3335465067040224, + "99.999" : 0.3335465067040224, + "99.9999" : 0.3335465067040224, + "100.0" : 0.3335465067040224 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32908114696107144, + 0.3290389183693614, + 0.3282446893258058 + ], + [ + 0.3321013678931987, + 0.3322612803508539, + 0.3335465067040224 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14903994834202133, + "scoreError" : 0.007121844548758751, + "scoreConfidence" : [ + 0.14191810379326258, + 0.15616179289078008 + ], + "scorePercentiles" : { + "0.0" : 0.14704774167365126, + "50.0" : 0.14771863569804766, + "90.0" : 0.15351056511727865, + "95.0" : 0.15351056511727865, + "99.0" : 0.15351056511727865, + "99.9" : 0.15351056511727865, + "99.99" : 0.15351056511727865, + "99.999" : 0.15351056511727865, + "99.9999" : 0.15351056511727865, + "100.0" : 0.15351056511727865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14704774167365126, + 0.1476247174089547, + 0.14781255398714063 + ], + [ + 0.15351056511727865, + 0.15066683527940578, + 0.147577276585697 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4026375365578448, + "scoreError" : 0.021466295108100372, + "scoreConfidence" : [ + 0.3811712414497444, + 0.4241038316659452 + ], + "scorePercentiles" : { + "0.0" : 0.39542367216291024, + "50.0" : 0.4025711390696852, + "90.0" : 0.4099623057024556, + "95.0" : 0.4099623057024556, + "99.0" : 0.4099623057024556, + "99.9" : 0.4099623057024556, + "99.99" : 0.4099623057024556, + "99.999" : 0.4099623057024556, + "99.9999" : 0.4099623057024556, + "100.0" : 0.4099623057024556 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40969899463312714, + 0.4099623057024556, + 0.40919991071647777 + ], + [ + 0.39542367216291024, + 0.39559796870920527, + 0.3959423674228927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1595075753531734, + "scoreError" : 0.016702735722032028, + "scoreConfidence" : [ + 0.14280483963114138, + 0.1762103110752054 + ], + "scorePercentiles" : { + "0.0" : 0.15400105496180855, + "50.0" : 0.15861204371832976, + "90.0" : 0.16585605859621189, + "95.0" : 0.16585605859621189, + "99.0" : 0.16585605859621189, + "99.9" : 0.16585605859621189, + "99.99" : 0.16585605859621189, + "99.999" : 0.16585605859621189, + "99.9999" : 0.16585605859621189, + "100.0" : 0.16585605859621189 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16579791284236356, + 0.16585605859621189, + 0.1629169706591509 + ], + [ + 0.15400105496180855, + 0.1543071167775086, + 0.15416633828199675 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04683078043086106, + "scoreError" : 0.002194719613108145, + "scoreConfidence" : [ + 0.04463606081775291, + 0.0490255000439692 + ], + "scorePercentiles" : { + "0.0" : 0.04609252335475069, + "50.0" : 0.04679773882646884, + "90.0" : 0.047731446324501575, + "95.0" : 0.047731446324501575, + "99.0" : 0.047731446324501575, + "99.9" : 0.047731446324501575, + "99.99" : 0.047731446324501575, + "99.999" : 0.047731446324501575, + "99.9999" : 0.047731446324501575, + "100.0" : 0.047731446324501575 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047731446324501575, + 0.047410180848441175, + 0.04747165794308229 + ], + [ + 0.04618529680449652, + 0.04609252335475069, + 0.04609357730989408 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9196988.38098221, + "scoreError" : 777788.4121037301, + "scoreConfidence" : [ + 8419199.968878482, + 9974776.79308594 + ], + "scorePercentiles" : { + "0.0" : 8815721.799118944, + "50.0" : 9177878.500463411, + "90.0" : 9559845.782234957, + "95.0" : 9559845.782234957, + "99.0" : 9559845.782234957, + "99.9" : 9559845.782234957, + "99.99" : 9559845.782234957, + "99.999" : 9559845.782234957, + "99.9999" : 9559845.782234957, + "100.0" : 9559845.782234957 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9022959.051397655, + 9069683.53853128, + 8815721.799118944 + ], + [ + 9286073.462395543, + 9559845.782234957, + 9427646.652214892 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-10T01:46:15Z-fc171b107f5f4cdfbb180f5aa0cb0f1bc75377e2-jdk17.json b/performance-results/2025-08-10T01:46:15Z-fc171b107f5f4cdfbb180f5aa0cb0f1bc75377e2-jdk17.json new file mode 100644 index 0000000000..c02c3c033a --- /dev/null +++ b/performance-results/2025-08-10T01:46:15Z-fc171b107f5f4cdfbb180f5aa0cb0f1bc75377e2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3578520810822936, + "scoreError" : 0.04170804404739272, + "scoreConfidence" : [ + 3.316144037034901, + 3.3995601251296863 + ], + "scorePercentiles" : { + "0.0" : 3.3484779716496833, + "50.0" : 3.3603875250713298, + "90.0" : 3.362155302536833, + "95.0" : 3.362155302536833, + "99.0" : 3.362155302536833, + "99.9" : 3.362155302536833, + "99.99" : 3.362155302536833, + "99.999" : 3.362155302536833, + "99.9999" : 3.362155302536833, + "100.0" : 3.362155302536833 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3484779716496833, + 3.3620798497733806 + ], + [ + 3.3586952003692785, + 3.362155302536833 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6965545813761094, + "scoreError" : 0.014804673221205619, + "scoreConfidence" : [ + 1.6817499081549037, + 1.711359254597315 + ], + "scorePercentiles" : { + "0.0" : 1.6946056288386402, + "50.0" : 1.6961397766131392, + "90.0" : 1.6993331434395187, + "95.0" : 1.6993331434395187, + "99.0" : 1.6993331434395187, + "99.9" : 1.6993331434395187, + "99.99" : 1.6993331434395187, + "99.999" : 1.6993331434395187, + "99.9999" : 1.6993331434395187, + "100.0" : 1.6993331434395187 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6975332682350228, + 1.6993331434395187 + ], + [ + 1.6946056288386402, + 1.6947462849912553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.852539875943776, + "scoreError" : 0.041583140552373374, + "scoreConfidence" : [ + 0.8109567353914027, + 0.8941230164961493 + ], + "scorePercentiles" : { + "0.0" : 0.8429795051939707, + "50.0" : 0.8552125735941242, + "90.0" : 0.8567548513928852, + "95.0" : 0.8567548513928852, + "99.0" : 0.8567548513928852, + "99.9" : 0.8567548513928852, + "99.99" : 0.8567548513928852, + "99.999" : 0.8567548513928852, + "99.9999" : 0.8567548513928852, + "100.0" : 0.8567548513928852 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8429795051939707, + 0.854589768500283 + ], + [ + 0.8558353786879653, + 0.8567548513928852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.54155599539207, + "scoreError" : 0.2954629628833302, + "scoreConfidence" : [ + 16.24609303250874, + 16.8370189582754 + ], + "scorePercentiles" : { + "0.0" : 16.44024089851539, + "50.0" : 16.540400456998363, + "90.0" : 16.650720146351283, + "95.0" : 16.650720146351283, + "99.0" : 16.650720146351283, + "99.9" : 16.650720146351283, + "99.99" : 16.650720146351283, + "99.999" : 16.650720146351283, + "99.9999" : 16.650720146351283, + "100.0" : 16.650720146351283 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.631280763130725, + 16.6303979454082, + 16.650720146351283 + ], + [ + 16.44629325035829, + 16.450402968588524, + 16.44024089851539 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2709.8302983366048, + "scoreError" : 49.39353859122522, + "scoreConfidence" : [ + 2660.4367597453797, + 2759.22383692783 + ], + "scorePercentiles" : { + "0.0" : 2693.3522760436945, + "50.0" : 2707.7597968038385, + "90.0" : 2729.942798266261, + "95.0" : 2729.942798266261, + "99.0" : 2729.942798266261, + "99.9" : 2729.942798266261, + "99.99" : 2729.942798266261, + "99.999" : 2729.942798266261, + "99.9999" : 2729.942798266261, + "100.0" : 2729.942798266261 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2729.942798266261, + 2726.24161596544, + 2720.8822332755626 + ], + [ + 2693.925506136556, + 2694.6373603321144, + 2693.3522760436945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77417.45878112779, + "scoreError" : 160.6656806563549, + "scoreConfidence" : [ + 77256.79310047143, + 77578.12446178414 + ], + "scorePercentiles" : { + "0.0" : 77366.66933312459, + "50.0" : 77406.74309022399, + "90.0" : 77497.2804845266, + "95.0" : 77497.2804845266, + "99.0" : 77497.2804845266, + "99.9" : 77497.2804845266, + "99.99" : 77497.2804845266, + "99.999" : 77497.2804845266, + "99.9999" : 77497.2804845266, + "100.0" : 77497.2804845266 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77368.98836121014, + 77367.00486375373, + 77366.66933312459 + ], + [ + 77497.2804845266, + 77460.31182491382, + 77444.49781923782 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 374.99739677233407, + "scoreError" : 29.042549952003064, + "scoreConfidence" : [ + 345.954846820331, + 404.03994672433714 + ], + "scorePercentiles" : { + "0.0" : 365.3220018894544, + "50.0" : 374.82235058044637, + "90.0" : 385.0952307881143, + "95.0" : 385.0952307881143, + "99.0" : 385.0952307881143, + "99.9" : 385.0952307881143, + "99.99" : 385.0952307881143, + "99.999" : 385.0952307881143, + "99.9999" : 385.0952307881143, + "100.0" : 385.0952307881143 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 383.8673238698566, + 385.0952307881143, + 384.37014278073804 + ], + [ + 365.5523040148052, + 365.3220018894544, + 365.7773772910361 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.18061396669134, + "scoreError" : 1.9475600889380174, + "scoreConfidence" : [ + 114.23305387775332, + 118.12817405562936 + ], + "scorePercentiles" : { + "0.0" : 115.4375425753084, + "50.0" : 116.142875296657, + "90.0" : 116.95034210117655, + "95.0" : 116.95034210117655, + "99.0" : 116.95034210117655, + "99.9" : 116.95034210117655, + "99.99" : 116.95034210117655, + "99.999" : 116.95034210117655, + "99.9999" : 116.95034210117655, + "100.0" : 116.95034210117655 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.51128704277293, + 115.4375425753084, + 115.75521452743425 + ], + [ + 116.8987614875761, + 116.95034210117655, + 116.53053606587976 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06067180108189951, + "scoreError" : 1.7778103371464936E-4, + "scoreConfidence" : [ + 0.06049402004818486, + 0.06084958211561416 + ], + "scorePercentiles" : { + "0.0" : 0.06059998696513735, + "50.0" : 0.060668033323660234, + "90.0" : 0.060764907924239386, + "95.0" : 0.060764907924239386, + "99.0" : 0.060764907924239386, + "99.9" : 0.060764907924239386, + "99.99" : 0.060764907924239386, + "99.999" : 0.060764907924239386, + "99.9999" : 0.060764907924239386, + "100.0" : 0.060764907924239386 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06059998696513735, + 0.06065419458125091, + 0.06061123538075496 + ], + [ + 0.060681872066069564, + 0.06071860957394488, + 0.060764907924239386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7625239901502625E-4, + "scoreError" : 6.507436401293764E-6, + "scoreConfidence" : [ + 3.6974496261373246E-4, + 3.8275983541632004E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7350582582150086E-4, + "50.0" : 3.7639675463173506E-4, + "90.0" : 3.783826175079246E-4, + "95.0" : 3.783826175079246E-4, + "99.0" : 3.783826175079246E-4, + "99.9" : 3.783826175079246E-4, + "99.99" : 3.783826175079246E-4, + "99.999" : 3.783826175079246E-4, + "99.9999" : 3.783826175079246E-4, + "100.0" : 3.783826175079246E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7350582582150086E-4, + 3.74517487222197E-4, + 3.74455848446912E-4 + ], + [ + 3.783765930503499E-4, + 3.7827602204127314E-4, + 3.783826175079246E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12231023013418056, + "scoreError" : 0.0012736495267368917, + "scoreConfidence" : [ + 0.12103658060744367, + 0.12358387966091745 + ], + "scorePercentiles" : { + "0.0" : 0.12177308990392226, + "50.0" : 0.12228649048511926, + "90.0" : 0.12279530937645816, + "95.0" : 0.12279530937645816, + "99.0" : 0.12279530937645816, + "99.9" : 0.12279530937645816, + "99.99" : 0.12279530937645816, + "99.999" : 0.12279530937645816, + "99.9999" : 0.12279530937645816, + "100.0" : 0.12279530937645816 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12279530937645816, + 0.12276644100568398, + 0.12257904622343165 + ], + [ + 0.12195355954878048, + 0.12199393474680688, + 0.12177308990392226 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013111989882552329, + "scoreError" : 4.3776558560913666E-4, + "scoreConfidence" : [ + 0.012674224296943192, + 0.013549755468161466 + ], + "scorePercentiles" : { + "0.0" : 0.012951516102419312, + "50.0" : 0.013113845410859328, + "90.0" : 0.013261396614669324, + "95.0" : 0.013261396614669324, + "99.0" : 0.013261396614669324, + "99.9" : 0.013261396614669324, + "99.99" : 0.013261396614669324, + "99.999" : 0.013261396614669324, + "99.9999" : 0.013261396614669324, + "100.0" : 0.013261396614669324 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012951516102419312, + 0.012981332090172234, + 0.012976696338801644 + ], + [ + 0.013261396614669324, + 0.013254639417705043, + 0.013246358731546424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0737944578601812, + "scoreError" : 0.1667444515086843, + "scoreConfidence" : [ + 0.9070500063514969, + 1.2405389093688655 + ], + "scorePercentiles" : { + "0.0" : 1.0191663128503006, + "50.0" : 1.0739247008846324, + "90.0" : 1.1284834018280299, + "95.0" : 1.1284834018280299, + "99.0" : 1.1284834018280299, + "99.9" : 1.1284834018280299, + "99.99" : 1.1284834018280299, + "99.999" : 1.1284834018280299, + "99.9999" : 1.1284834018280299, + "100.0" : 1.1284834018280299 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0191663128503006, + 1.019235173461068, + 1.0201407565279477 + ], + [ + 1.1284834018280299, + 1.1277086452413172, + 1.128032457252425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010638811570419291, + "scoreError" : 0.0011614337150658354, + "scoreConfidence" : [ + 0.009477377855353457, + 0.011800245285485126 + ], + "scorePercentiles" : { + "0.0" : 0.010259340775955993, + "50.0" : 0.010637812533889745, + "90.0" : 0.011018777255258008, + "95.0" : 0.011018777255258008, + "99.0" : 0.011018777255258008, + "99.9" : 0.011018777255258008, + "99.99" : 0.011018777255258008, + "99.999" : 0.011018777255258008, + "99.9999" : 0.011018777255258008, + "100.0" : 0.011018777255258008 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011018777255258008, + 0.011017772985181513, + 0.01101414913441989 + ], + [ + 0.010259340775955993, + 0.010261475933359602, + 0.010261353338340742 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0827285542303806, + "scoreError" : 0.08365090115802343, + "scoreConfidence" : [ + 2.9990776530723573, + 3.166379455388404 + ], + "scorePercentiles" : { + "0.0" : 3.049663473780488, + "50.0" : 3.0861501204309834, + "90.0" : 3.115209204234122, + "95.0" : 3.115209204234122, + "99.0" : 3.115209204234122, + "99.9" : 3.115209204234122, + "99.99" : 3.115209204234122, + "99.999" : 3.115209204234122, + "99.9999" : 3.115209204234122, + "100.0" : 3.115209204234122 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1022891978908187, + 3.115209204234122, + 3.1090706022374146 + ], + [ + 3.0501278042682927, + 3.070011042971148, + 3.049663473780488 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7119318334761715, + "scoreError" : 0.14436848601531116, + "scoreConfidence" : [ + 2.5675633474608603, + 2.8563003194914827 + ], + "scorePercentiles" : { + "0.0" : 2.663133615282215, + "50.0" : 2.709559625403682, + "90.0" : 2.7626440524861877, + "95.0" : 2.7626440524861877, + "99.0" : 2.7626440524861877, + "99.9" : 2.7626440524861877, + "99.99" : 2.7626440524861877, + "99.999" : 2.7626440524861877, + "99.9999" : 2.7626440524861877, + "100.0" : 2.7626440524861877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6659775495735607, + 2.6659901255665157, + 2.663133615282215 + ], + [ + 2.753129125240848, + 2.7626440524861877, + 2.760716532707701 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17250331924478768, + "scoreError" : 0.0038377511787421564, + "scoreConfidence" : [ + 0.16866556806604552, + 0.17634107042352984 + ], + "scorePercentiles" : { + "0.0" : 0.171199877456687, + "50.0" : 0.1723776480088797, + "90.0" : 0.17451642544762835, + "95.0" : 0.17451642544762835, + "99.0" : 0.17451642544762835, + "99.9" : 0.17451642544762835, + "99.99" : 0.17451642544762835, + "99.999" : 0.17451642544762835, + "99.9999" : 0.17451642544762835, + "100.0" : 0.17451642544762835 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17451642544762835, + 0.1732385074404504, + 0.17327283537789792 + ], + [ + 0.17151678857730898, + 0.17127548116875332, + 0.171199877456687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32976411110048703, + "scoreError" : 0.02641316216150992, + "scoreConfidence" : [ + 0.3033509489389771, + 0.35617727326199694 + ], + "scorePercentiles" : { + "0.0" : 0.32108948264568954, + "50.0" : 0.3296047258198368, + "90.0" : 0.3386812274867071, + "95.0" : 0.3386812274867071, + "99.0" : 0.3386812274867071, + "99.9" : 0.3386812274867071, + "99.99" : 0.3386812274867071, + "99.999" : 0.3386812274867071, + "99.9999" : 0.3386812274867071, + "100.0" : 0.3386812274867071 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3384311082608549, + 0.3379675409104735, + 0.3386812274867071 + ], + [ + 0.3211733965699971, + 0.32108948264568954, + 0.3212419107292001 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1473522006334595, + "scoreError" : 0.004636256673300404, + "scoreConfidence" : [ + 0.1427159439601591, + 0.1519884573067599 + ], + "scorePercentiles" : { + "0.0" : 0.14540217546818657, + "50.0" : 0.14776724613040498, + "90.0" : 0.1489661265585199, + "95.0" : 0.1489661265585199, + "99.0" : 0.1489661265585199, + "99.9" : 0.1489661265585199, + "99.99" : 0.1489661265585199, + "99.999" : 0.1489661265585199, + "99.9999" : 0.1489661265585199, + "100.0" : 0.1489661265585199 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1489661265585199, + 0.14867030679115129, + 0.14871185212283441 + ], + [ + 0.1468641854696587, + 0.14549855739040607, + 0.14540217546818657 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4068186304479915, + "scoreError" : 0.03155188489795706, + "scoreConfidence" : [ + 0.3752667455500344, + 0.43837051534594856 + ], + "scorePercentiles" : { + "0.0" : 0.3963528583488566, + "50.0" : 0.40671411868394014, + "90.0" : 0.41801421577561343, + "95.0" : 0.41801421577561343, + "99.0" : 0.41801421577561343, + "99.9" : 0.41801421577561343, + "99.99" : 0.41801421577561343, + "99.999" : 0.41801421577561343, + "99.9999" : 0.41801421577561343, + "100.0" : 0.41801421577561343 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41801421577561343, + 0.4165849729234358, + 0.41663558521851435 + ], + [ + 0.39684326444444445, + 0.3964808859770844, + 0.3963528583488566 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1538528611241408, + "scoreError" : 0.00720371164247281, + "scoreConfidence" : [ + 0.146649149481668, + 0.1610565727666136 + ], + "scorePercentiles" : { + "0.0" : 0.15138993747729199, + "50.0" : 0.15391928129100524, + "90.0" : 0.15626938653623776, + "95.0" : 0.15626938653623776, + "99.0" : 0.15626938653623776, + "99.9" : 0.15626938653623776, + "99.99" : 0.15626938653623776, + "99.999" : 0.15626938653623776, + "99.9999" : 0.15626938653623776, + "100.0" : 0.15626938653623776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15626938653623776, + 0.15616167960710214, + 0.15615694098908478 + ], + [ + 0.15138993747729199, + 0.15168162159292572, + 0.15145760054220242 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04738492024290411, + "scoreError" : 0.002666267328978843, + "scoreConfidence" : [ + 0.044718652913925266, + 0.050051187571882955 + ], + "scorePercentiles" : { + "0.0" : 0.04636883006593529, + "50.0" : 0.047270152920560304, + "90.0" : 0.048545326796021304, + "95.0" : 0.048545326796021304, + "99.0" : 0.048545326796021304, + "99.9" : 0.048545326796021304, + "99.99" : 0.048545326796021304, + "99.999" : 0.048545326796021304, + "99.9999" : 0.048545326796021304, + "100.0" : 0.048545326796021304 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04664576500221564, + 0.0466115686392408, + 0.04636883006593529 + ], + [ + 0.048545326796021304, + 0.04789454083890496, + 0.04824349011510667 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8590358.256264187, + "scoreError" : 133975.92039598845, + "scoreConfidence" : [ + 8456382.335868198, + 8724334.176660176 + ], + "scorePercentiles" : { + "0.0" : 8529077.79198636, + "50.0" : 8583848.588268487, + "90.0" : 8647488.84096802, + "95.0" : 8647488.84096802, + "99.0" : 8647488.84096802, + "99.9" : 8647488.84096802, + "99.99" : 8647488.84096802, + "99.999" : 8647488.84096802, + "99.9999" : 8647488.84096802, + "100.0" : 8647488.84096802 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8568406.9375, + 8529077.79198636, + 8556018.35158255 + ], + [ + 8599290.239036974, + 8641867.376511225, + 8647488.84096802 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-10T02:14:29Z-da04414d24783191bfc1dad4d5539c3ef09f39db-jdk17.json b/performance-results/2025-08-10T02:14:29Z-da04414d24783191bfc1dad4d5539c3ef09f39db-jdk17.json new file mode 100644 index 0000000000..564e293f91 --- /dev/null +++ b/performance-results/2025-08-10T02:14:29Z-da04414d24783191bfc1dad4d5539c3ef09f39db-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3084673082669753, + "scoreError" : 0.0495787054088271, + "scoreConfidence" : [ + 3.258888602858148, + 3.3580460136758026 + ], + "scorePercentiles" : { + "0.0" : 3.298682395085806, + "50.0" : 3.3089108791092228, + "90.0" : 3.3173650797636496, + "95.0" : 3.3173650797636496, + "99.0" : 3.3173650797636496, + "99.9" : 3.3173650797636496, + "99.99" : 3.3173650797636496, + "99.999" : 3.3173650797636496, + "99.9999" : 3.3173650797636496, + "100.0" : 3.3173650797636496 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.309713041525624, + 3.3173650797636496 + ], + [ + 3.298682395085806, + 3.308108716692822 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.671533028586416, + "scoreError" : 0.03384416598181523, + "scoreConfidence" : [ + 1.637688862604601, + 1.7053771945682312 + ], + "scorePercentiles" : { + "0.0" : 1.6647722465964487, + "50.0" : 1.672384250976591, + "90.0" : 1.6765913657960334, + "95.0" : 1.6765913657960334, + "99.0" : 1.6765913657960334, + "99.9" : 1.6765913657960334, + "99.99" : 1.6765913657960334, + "99.999" : 1.6765913657960334, + "99.9999" : 1.6765913657960334, + "100.0" : 1.6765913657960334 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6647722465964487, + 1.6701993408251181 + ], + [ + 1.6745691611280638, + 1.6765913657960334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8389227710839395, + "scoreError" : 0.02075559956838633, + "scoreConfidence" : [ + 0.8181671715155532, + 0.8596783706523259 + ], + "scorePercentiles" : { + "0.0" : 0.8358714735480048, + "50.0" : 0.8383871054252953, + "90.0" : 0.8430453999371632, + "95.0" : 0.8430453999371632, + "99.0" : 0.8430453999371632, + "99.9" : 0.8430453999371632, + "99.99" : 0.8430453999371632, + "99.999" : 0.8430453999371632, + "99.9999" : 0.8430453999371632, + "100.0" : 0.8430453999371632 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8358714735480048, + 0.8398135601915034 + ], + [ + 0.8369606506590871, + 0.8430453999371632 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.86578054756908, + "scoreError" : 0.17255775746977414, + "scoreConfidence" : [ + 15.693222790099307, + 16.038338305038856 + ], + "scorePercentiles" : { + "0.0" : 15.805260980199249, + "50.0" : 15.841317797183972, + "90.0" : 15.961612668625706, + "95.0" : 15.961612668625706, + "99.0" : 15.961612668625706, + "99.9" : 15.961612668625706, + "99.99" : 15.961612668625706, + "99.999" : 15.961612668625706, + "99.9999" : 15.961612668625706, + "100.0" : 15.961612668625706 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.824633196684303, + 15.805260980199249, + 15.831363214660925 + ], + [ + 15.85127237970702, + 15.920540845537275, + 15.961612668625706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2730.1837149564008, + "scoreError" : 141.3425765942073, + "scoreConfidence" : [ + 2588.8411383621933, + 2871.526291550608 + ], + "scorePercentiles" : { + "0.0" : 2673.7443335675944, + "50.0" : 2731.7312424123206, + "90.0" : 2781.30107337162, + "95.0" : 2781.30107337162, + "99.0" : 2781.30107337162, + "99.9" : 2781.30107337162, + "99.99" : 2781.30107337162, + "99.999" : 2781.30107337162, + "99.9999" : 2781.30107337162, + "100.0" : 2781.30107337162 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2686.5404243909197, + 2693.712276430712, + 2673.7443335675944 + ], + [ + 2781.30107337162, + 2769.7502083939294, + 2776.0539735836305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77083.19252376433, + "scoreError" : 965.4739208701415, + "scoreConfidence" : [ + 76117.7186028942, + 78048.66644463447 + ], + "scorePercentiles" : { + "0.0" : 76682.09120401308, + "50.0" : 77105.38732060436, + "90.0" : 77484.89337224307, + "95.0" : 77484.89337224307, + "99.0" : 77484.89337224307, + "99.9" : 77484.89337224307, + "99.99" : 77484.89337224307, + "99.999" : 77484.89337224307, + "99.9999" : 77484.89337224307, + "100.0" : 77484.89337224307 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77307.72406729138, + 77366.13189091973, + 77484.89337224307 + ], + [ + 76755.26403420133, + 76903.05057391735, + 76682.09120401308 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.4958631038318, + "scoreError" : 5.533643698395508, + "scoreConfidence" : [ + 336.9622194054363, + 348.02950680222733 + ], + "scorePercentiles" : { + "0.0" : 339.22904702213935, + "50.0" : 343.18539602696586, + "90.0" : 344.24139816885514, + "95.0" : 344.24139816885514, + "99.0" : 344.24139816885514, + "99.9" : 344.24139816885514, + "99.99" : 344.24139816885514, + "99.999" : 344.24139816885514, + "99.9999" : 344.24139816885514, + "100.0" : 344.24139816885514 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 344.24139816885514, + 342.60363529307494, + 339.22904702213935 + ], + [ + 341.13280386497433, + 344.0011375130901, + 343.7671567608568 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 110.90408209978482, + "scoreError" : 2.6998966244935403, + "scoreConfidence" : [ + 108.20418547529127, + 113.60397872427836 + ], + "scorePercentiles" : { + "0.0" : 109.35632375136728, + "50.0" : 111.02080270157111, + "90.0" : 111.8723713391271, + "95.0" : 111.8723713391271, + "99.0" : 111.8723713391271, + "99.9" : 111.8723713391271, + "99.99" : 111.8723713391271, + "99.999" : 111.8723713391271, + "99.9999" : 111.8723713391271, + "100.0" : 111.8723713391271 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.29807389782495, + 109.35632375136728, + 111.04317679679615 + ], + [ + 111.8723713391271, + 110.99842860634607, + 111.85611820724742 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06255932109035364, + "scoreError" : 6.566493253165014E-4, + "scoreConfidence" : [ + 0.061902671765037144, + 0.06321597041567015 + ], + "scorePercentiles" : { + "0.0" : 0.062260569431819596, + "50.0" : 0.062573523670248, + "90.0" : 0.06281568887995527, + "95.0" : 0.06281568887995527, + "99.0" : 0.06281568887995527, + "99.9" : 0.06281568887995527, + "99.99" : 0.06281568887995527, + "99.999" : 0.06281568887995527, + "99.9999" : 0.06281568887995527, + "100.0" : 0.06281568887995527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06276702714628238, + 0.06271158075541035, + 0.062260569431819596 + ], + [ + 0.062365593743568634, + 0.06243546658508566, + 0.06281568887995527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.814052184783808E-4, + "scoreError" : 2.1149740800615543E-5, + "scoreConfidence" : [ + 3.6025547767776526E-4, + 4.0255495927899636E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7333318980091543E-4, + "50.0" : 3.810589611966397E-4, + "90.0" : 3.903457537529501E-4, + "95.0" : 3.903457537529501E-4, + "99.0" : 3.903457537529501E-4, + "99.9" : 3.903457537529501E-4, + "99.99" : 3.903457537529501E-4, + "99.999" : 3.903457537529501E-4, + "99.9999" : 3.903457537529501E-4, + "100.0" : 3.903457537529501E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8644576969418547E-4, + 3.876828527683982E-4, + 3.903457537529501E-4 + ], + [ + 3.7333318980091543E-4, + 3.756721526990939E-4, + 3.7495159215474185E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12454567316972526, + "scoreError" : 5.561965564698811E-4, + "scoreConfidence" : [ + 0.12398947661325538, + 0.12510186972619514 + ], + "scorePercentiles" : { + "0.0" : 0.12432865041711735, + "50.0" : 0.12453315596535776, + "90.0" : 0.1248082304648986, + "95.0" : 0.1248082304648986, + "99.0" : 0.1248082304648986, + "99.9" : 0.1248082304648986, + "99.99" : 0.1248082304648986, + "99.999" : 0.1248082304648986, + "99.9999" : 0.1248082304648986, + "100.0" : 0.1248082304648986 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12470748977428607, + 0.12443085440541515, + 0.12432865041711735 + ], + [ + 0.12436335643133402, + 0.1248082304648986, + 0.12463545752530036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013189883031203713, + "scoreError" : 1.4657010338322763E-4, + "scoreConfidence" : [ + 0.013043312927820485, + 0.01333645313458694 + ], + "scorePercentiles" : { + "0.0" : 0.013124220356133245, + "50.0" : 0.013185911105323592, + "90.0" : 0.013245436990305793, + "95.0" : 0.013245436990305793, + "99.0" : 0.013245436990305793, + "99.9" : 0.013245436990305793, + "99.99" : 0.013245436990305793, + "99.999" : 0.013245436990305793, + "99.9999" : 0.013245436990305793, + "100.0" : 0.013245436990305793 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013244804703962661, + 0.01321636417462281, + 0.013245436990305793 + ], + [ + 0.013124220356133245, + 0.013155458036024375, + 0.013153013926173393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0158686166819377, + "scoreError" : 0.0027004496604895495, + "scoreConfidence" : [ + 1.013168167021448, + 1.0185690663424274 + ], + "scorePercentiles" : { + "0.0" : 1.0144033046962166, + "50.0" : 1.015954432040874, + "90.0" : 1.0171452855980472, + "95.0" : 1.0171452855980472, + "99.0" : 1.0171452855980472, + "99.9" : 1.0171452855980472, + "99.99" : 1.0171452855980472, + "99.999" : 1.0171452855980472, + "99.9999" : 1.0171452855980472, + "100.0" : 1.0171452855980472 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.015931843356359, + 1.016526734193942, + 1.0171452855980472 + ], + [ + 1.0159770207253886, + 1.015227511521673, + 1.0144033046962166 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010630762054109823, + "scoreError" : 3.770589840622781E-4, + "scoreConfidence" : [ + 0.010253703070047545, + 0.0110078210381721 + ], + "scorePercentiles" : { + "0.0" : 0.010470807807241833, + "50.0" : 0.010650233294003733, + "90.0" : 0.010754240363914012, + "95.0" : 0.010754240363914012, + "99.0" : 0.010754240363914012, + "99.9" : 0.010754240363914012, + "99.99" : 0.010754240363914012, + "99.999" : 0.010754240363914012, + "99.9999" : 0.010754240363914012, + "100.0" : 0.010754240363914012 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010754240363914012, + 0.010751918055241966, + 0.010747314417810868 + ], + [ + 0.0105531521701966, + 0.010507139510253657, + 0.010470807807241833 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3743637225332868, + "scoreError" : 0.05062411893758047, + "scoreConfidence" : [ + 3.323739603595706, + 3.4249878414708674 + ], + "scorePercentiles" : { + "0.0" : 3.354650947015426, + "50.0" : 3.3718571618341198, + "90.0" : 3.399334186267845, + "95.0" : 3.399334186267845, + "99.0" : 3.399334186267845, + "99.9" : 3.399334186267845, + "99.99" : 3.399334186267845, + "99.999" : 3.399334186267845, + "99.9999" : 3.399334186267845, + "100.0" : 3.399334186267845 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.370012, + 3.37370232366824, + 3.3569492389261746 + ], + [ + 3.391533639322034, + 3.399334186267845, + 3.354650947015426 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9429261094411276, + "scoreError" : 0.05777431256667438, + "scoreConfidence" : [ + 2.885151796874453, + 3.000700422007802 + ], + "scorePercentiles" : { + "0.0" : 2.915625160058309, + "50.0" : 2.9440864791437624, + "90.0" : 2.9637986296296295, + "95.0" : 2.9637986296296295, + "99.0" : 2.9637986296296295, + "99.9" : 2.9637986296296295, + "99.99" : 2.9637986296296295, + "99.999" : 2.9637986296296295, + "99.9999" : 2.9637986296296295, + "100.0" : 2.9637986296296295 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9289662029282577, + 2.915625160058309, + 2.929640394844757 + ], + [ + 2.9609937057430433, + 2.9585325634427684, + 2.9637986296296295 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17583020770185076, + "scoreError" : 0.003197375533510414, + "scoreConfidence" : [ + 0.17263283216834036, + 0.17902758323536117 + ], + "scorePercentiles" : { + "0.0" : 0.17476914024816498, + "50.0" : 0.17578685804798821, + "90.0" : 0.17704897825894517, + "95.0" : 0.17704897825894517, + "99.0" : 0.17704897825894517, + "99.9" : 0.17704897825894517, + "99.99" : 0.17704897825894517, + "99.999" : 0.17704897825894517, + "99.9999" : 0.17704897825894517, + "100.0" : 0.17704897825894517 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17476914024816498, + 0.17478097782088925, + 0.17483092487630902 + ], + [ + 0.17704897825894517, + 0.1768084337871287, + 0.17674279121966738 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3281124634783437, + "scoreError" : 0.00117163453717925, + "scoreConfidence" : [ + 0.3269408289411645, + 0.32928409801552294 + ], + "scorePercentiles" : { + "0.0" : 0.32754155533719825, + "50.0" : 0.32806511711445724, + "90.0" : 0.3288240634617914, + "95.0" : 0.3288240634617914, + "99.0" : 0.3288240634617914, + "99.9" : 0.3288240634617914, + "99.99" : 0.3288240634617914, + "99.999" : 0.3288240634617914, + "99.9999" : 0.3288240634617914, + "100.0" : 0.3288240634617914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.327957180205293, + 0.32806606770987107, + 0.3280641665190434 + ], + [ + 0.32754155533719825, + 0.3282217476368649, + 0.3288240634617914 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14697488455267071, + "scoreError" : 0.00711081737744563, + "scoreConfidence" : [ + 0.1398640671752251, + 0.15408570193011634 + ], + "scorePercentiles" : { + "0.0" : 0.1447065321458029, + "50.0" : 0.14659036040772058, + "90.0" : 0.15110987861708397, + "95.0" : 0.15110987861708397, + "99.0" : 0.15110987861708397, + "99.9" : 0.15110987861708397, + "99.99" : 0.15110987861708397, + "99.999" : 0.15110987861708397, + "99.9999" : 0.15110987861708397, + "100.0" : 0.15110987861708397 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15110987861708397, + 0.14799934717103996, + 0.1480133643710315 + ], + [ + 0.1451813736444012, + 0.1447065321458029, + 0.14483881136666474 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40520965762676947, + "scoreError" : 0.016664606129852037, + "scoreConfidence" : [ + 0.3885450514969174, + 0.4218742637566215 + ], + "scorePercentiles" : { + "0.0" : 0.3994700642326436, + "50.0" : 0.4048545111868923, + "90.0" : 0.41188960459656493, + "95.0" : 0.41188960459656493, + "99.0" : 0.41188960459656493, + "99.9" : 0.41188960459656493, + "99.99" : 0.41188960459656493, + "99.999" : 0.41188960459656493, + "99.9999" : 0.41188960459656493, + "100.0" : 0.41188960459656493 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4001176691073501, + 0.39990505910345103, + 0.3994700642326436 + ], + [ + 0.41188960459656493, + 0.4102841954541725, + 0.4095913532664346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15923400265217158, + "scoreError" : 0.0038352243884063465, + "scoreConfidence" : [ + 0.15539877826376525, + 0.1630692270405779 + ], + "scorePercentiles" : { + "0.0" : 0.1579531635576756, + "50.0" : 0.15911995105030075, + "90.0" : 0.16094071142332947, + "95.0" : 0.16094071142332947, + "99.0" : 0.16094071142332947, + "99.9" : 0.16094071142332947, + "99.99" : 0.16094071142332947, + "99.999" : 0.16094071142332947, + "99.9999" : 0.16094071142332947, + "100.0" : 0.16094071142332947 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15799123985717897, + 0.15808631203958393, + 0.1579531635576756 + ], + [ + 0.16094071142332947, + 0.1602789989742439, + 0.1601535900610176 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0463123233009882, + "scoreError" : 0.00137270057338245, + "scoreConfidence" : [ + 0.04493962272760575, + 0.04768502387437065 + ], + "scorePercentiles" : { + "0.0" : 0.045670728177819996, + "50.0" : 0.04653111273649652, + "90.0" : 0.046858487620306075, + "95.0" : 0.046858487620306075, + "99.0" : 0.046858487620306075, + "99.9" : 0.046858487620306075, + "99.99" : 0.046858487620306075, + "99.999" : 0.046858487620306075, + "99.9999" : 0.046858487620306075, + "100.0" : 0.046858487620306075 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046858487620306075, + 0.045732791626460566, + 0.045670728177819996 + ], + [ + 0.04654970690834951, + 0.046542409548498795, + 0.04651981592449425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8977540.945111837, + "scoreError" : 276635.6541227947, + "scoreConfidence" : [ + 8700905.290989043, + 9254176.599234631 + ], + "scorePercentiles" : { + "0.0" : 8834439.696113074, + "50.0" : 8982979.323865527, + "90.0" : 9130289.430656934, + "95.0" : 9130289.430656934, + "99.0" : 9130289.430656934, + "99.9" : 9130289.430656934, + "99.99" : 9130289.430656934, + "99.999" : 9130289.430656934, + "99.9999" : 9130289.430656934, + "100.0" : 9130289.430656934 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9014402.625225225, + 8974645.037668161, + 8991313.610062893 + ], + [ + 9130289.430656934, + 8920155.27094474, + 8834439.696113074 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-20T05:27:05Z-784a37ea628ff3de01aa8be415da7f228a20286b-jdk17.json b/performance-results/2025-08-20T05:27:05Z-784a37ea628ff3de01aa8be415da7f228a20286b-jdk17.json new file mode 100644 index 0000000000..7922c4e665 --- /dev/null +++ b/performance-results/2025-08-20T05:27:05Z-784a37ea628ff3de01aa8be415da7f228a20286b-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3481055486647313, + "scoreError" : 0.03929988919235386, + "scoreConfidence" : [ + 3.3088056594723776, + 3.387405437857085 + ], + "scorePercentiles" : { + "0.0" : 3.341048827216639, + "50.0" : 3.3477618669899405, + "90.0" : 3.355849633462407, + "95.0" : 3.355849633462407, + "99.0" : 3.355849633462407, + "99.9" : 3.355849633462407, + "99.99" : 3.355849633462407, + "99.999" : 3.355849633462407, + "99.9999" : 3.355849633462407, + "100.0" : 3.355849633462407 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.341048827216639, + 3.3470701759564183 + ], + [ + 3.3484535580234622, + 3.355849633462407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6897251852531046, + "scoreError" : 0.043060148079593574, + "scoreConfidence" : [ + 1.646665037173511, + 1.7327853333326981 + ], + "scorePercentiles" : { + "0.0" : 1.6829333490100358, + "50.0" : 1.6896625319831622, + "90.0" : 1.6966423280360576, + "95.0" : 1.6966423280360576, + "99.0" : 1.6966423280360576, + "99.9" : 1.6966423280360576, + "99.99" : 1.6966423280360576, + "99.999" : 1.6966423280360576, + "99.9999" : 1.6966423280360576, + "100.0" : 1.6966423280360576 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6940912543316682, + 1.6966423280360576 + ], + [ + 1.6829333490100358, + 1.685233809634656 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8471177333921709, + "scoreError" : 0.02666310392978403, + "scoreConfidence" : [ + 0.8204546294623869, + 0.8737808373219549 + ], + "scorePercentiles" : { + "0.0" : 0.8411874011807506, + "50.0" : 0.8482701255824613, + "90.0" : 0.85074328122301, + "95.0" : 0.85074328122301, + "99.0" : 0.85074328122301, + "99.9" : 0.85074328122301, + "99.99" : 0.85074328122301, + "99.999" : 0.85074328122301, + "99.9999" : 0.85074328122301, + "100.0" : 0.85074328122301 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8480401677896545, + 0.848500083375268 + ], + [ + 0.8411874011807506, + 0.85074328122301 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.354356539314917, + "scoreError" : 0.07237800354153569, + "scoreConfidence" : [ + 16.28197853577338, + 16.426734542856455 + ], + "scorePercentiles" : { + "0.0" : 16.330167306547, + "50.0" : 16.349494703164638, + "90.0" : 16.402336550591027, + "95.0" : 16.402336550591027, + "99.0" : 16.402336550591027, + "99.9" : 16.402336550591027, + "99.99" : 16.402336550591027, + "99.999" : 16.402336550591027, + "99.9999" : 16.402336550591027, + "100.0" : 16.402336550591027 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.347289332482372, + 16.330167306547, + 16.359319131757623 + ], + [ + 16.351700073846906, + 16.402336550591027, + 16.33532684066457 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2569.3294077283517, + "scoreError" : 158.76042814710144, + "scoreConfidence" : [ + 2410.5689795812505, + 2728.089835875453 + ], + "scorePercentiles" : { + "0.0" : 2513.7826679096847, + "50.0" : 2570.0237647390563, + "90.0" : 2622.612726625413, + "95.0" : 2622.612726625413, + "99.0" : 2622.612726625413, + "99.9" : 2622.612726625413, + "99.99" : 2622.612726625413, + "99.999" : 2622.612726625413, + "99.9999" : 2622.612726625413, + "100.0" : 2622.612726625413 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2620.2637976840274, + 2620.027627078389, + 2622.612726625413 + ], + [ + 2513.7826679096847, + 2519.2697246728735, + 2520.019902399724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77843.83063782762, + "scoreError" : 503.6381961606761, + "scoreConfidence" : [ + 77340.19244166694, + 78347.4688339883 + ], + "scorePercentiles" : { + "0.0" : 77671.74699398458, + "50.0" : 77836.80604854104, + "90.0" : 78027.7201044826, + "95.0" : 78027.7201044826, + "99.0" : 78027.7201044826, + "99.9" : 78027.7201044826, + "99.99" : 78027.7201044826, + "99.999" : 78027.7201044826, + "99.9999" : 78027.7201044826, + "100.0" : 78027.7201044826 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77688.93778246039, + 77680.59684937872, + 77671.74699398458 + ], + [ + 77984.67431462168, + 78027.7201044826, + 78009.30778203777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.3138440929183, + "scoreError" : 9.474606345524869, + "scoreConfidence" : [ + 351.83923774739344, + 370.7884504384432 + ], + "scorePercentiles" : { + "0.0" : 356.5764979360481, + "50.0" : 361.9825606305737, + "90.0" : 365.1075110748268, + "95.0" : 365.1075110748268, + "99.0" : 365.1075110748268, + "99.9" : 365.1075110748268, + "99.99" : 365.1075110748268, + "99.999" : 365.1075110748268, + "99.9999" : 365.1075110748268, + "100.0" : 365.1075110748268 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.6020260522307, + 358.3365636423047, + 356.5764979360481 + ], + [ + 363.36309520891666, + 363.897370643183, + 365.1075110748268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.20755996542543, + "scoreError" : 0.5446783151889296, + "scoreConfidence" : [ + 114.6628816502365, + 115.75223828061436 + ], + "scorePercentiles" : { + "0.0" : 115.03051113800528, + "50.0" : 115.1145583961866, + "90.0" : 115.5158983036923, + "95.0" : 115.5158983036923, + "99.0" : 115.5158983036923, + "99.9" : 115.5158983036923, + "99.99" : 115.5158983036923, + "99.999" : 115.5158983036923, + "99.9999" : 115.5158983036923, + "100.0" : 115.5158983036923 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.08870153501064, + 115.03051113800528, + 115.13284924923335 + ], + [ + 115.09626754313985, + 115.5158983036923, + 115.38113202347114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06090328393808464, + "scoreError" : 4.670504031190234E-4, + "scoreConfidence" : [ + 0.06043623353496562, + 0.06137033434120366 + ], + "scorePercentiles" : { + "0.0" : 0.06064530710265865, + "50.0" : 0.06092413898130761, + "90.0" : 0.06111937604894357, + "95.0" : 0.06111937604894357, + "99.0" : 0.06111937604894357, + "99.9" : 0.06111937604894357, + "99.99" : 0.06111937604894357, + "99.999" : 0.06111937604894357, + "99.9999" : 0.06111937604894357, + "100.0" : 0.06111937604894357 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060976476079268295, + 0.06100111127648932, + 0.06111937604894357 + ], + [ + 0.06064530710265865, + 0.06087180188334693, + 0.06080563123780106 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6899636001729887E-4, + "scoreError" : 2.999043165725129E-5, + "scoreConfidence" : [ + 3.3900592836004755E-4, + 3.989867916745502E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5853221834311133E-4, + "50.0" : 3.683424835114287E-4, + "90.0" : 3.7987749721031164E-4, + "95.0" : 3.7987749721031164E-4, + "99.0" : 3.7987749721031164E-4, + "99.9" : 3.7987749721031164E-4, + "99.99" : 3.7987749721031164E-4, + "99.999" : 3.7987749721031164E-4, + "99.9999" : 3.7987749721031164E-4, + "100.0" : 3.7987749721031164E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6019203612571446E-4, + 3.5919739579344794E-4, + 3.5853221834311133E-4 + ], + [ + 3.76492930897143E-4, + 3.7968608173406495E-4, + 3.7987749721031164E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12482872015838864, + "scoreError" : 0.001651445056926422, + "scoreConfidence" : [ + 0.12317727510146222, + 0.12648016521531505 + ], + "scorePercentiles" : { + "0.0" : 0.1241152106563074, + "50.0" : 0.12483818133866487, + "90.0" : 0.1256644473542015, + "95.0" : 0.1256644473542015, + "99.0" : 0.1256644473542015, + "99.9" : 0.1256644473542015, + "99.99" : 0.1256644473542015, + "99.999" : 0.1256644473542015, + "99.9999" : 0.1256644473542015, + "100.0" : 0.1256644473542015 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1241152106563074, + 0.1243487886471027, + 0.12453708973959825 + ], + [ + 0.1256644473542015, + 0.1251675116153904, + 0.1251392729377315 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012835642659831918, + "scoreError" : 3.2867915797878637E-4, + "scoreConfidence" : [ + 0.012506963501853131, + 0.013164321817810704 + ], + "scorePercentiles" : { + "0.0" : 0.012715382869291343, + "50.0" : 0.012837872290568953, + "90.0" : 0.012945627808350584, + "95.0" : 0.012945627808350584, + "99.0" : 0.012945627808350584, + "99.9" : 0.012945627808350584, + "99.99" : 0.012945627808350584, + "99.999" : 0.012945627808350584, + "99.9999" : 0.012945627808350584, + "100.0" : 0.012945627808350584 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012735089942972995, + 0.01273614474443342, + 0.012715382869291343 + ], + [ + 0.012942010757238682, + 0.012939599836704485, + 0.012945627808350584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9470193593680118, + "scoreError" : 0.05623167063148867, + "scoreConfidence" : [ + 0.8907876887365231, + 1.0032510299995006 + ], + "scorePercentiles" : { + "0.0" : 0.928436868907251, + "50.0" : 0.9472297954683266, + "90.0" : 0.9655064388878162, + "95.0" : 0.9655064388878162, + "99.0" : 0.9655064388878162, + "99.9" : 0.9655064388878162, + "99.99" : 0.9655064388878162, + "99.999" : 0.9655064388878162, + "99.9999" : 0.9655064388878162, + "100.0" : 0.9655064388878162 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9652297871827044, + 0.9655064388878162, + 0.9652324689701767 + ], + [ + 0.928436868907251, + 0.929229803753949, + 0.928480788506174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010562617915542026, + "scoreError" : 4.035558633805271E-4, + "scoreConfidence" : [ + 0.010159062052161499, + 0.010966173778922552 + ], + "scorePercentiles" : { + "0.0" : 0.010423209153446874, + "50.0" : 0.010562619497566272, + "90.0" : 0.01070475660359585, + "95.0" : 0.01070475660359585, + "99.0" : 0.01070475660359585, + "99.9" : 0.01070475660359585, + "99.99" : 0.01070475660359585, + "99.999" : 0.01070475660359585, + "99.9999" : 0.01070475660359585, + "100.0" : 0.01070475660359585 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01068766440735207, + 0.010688998745150016, + 0.01070475660359585 + ], + [ + 0.010437574587780475, + 0.010433503995926867, + 0.010423209153446874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0633842805316323, + "scoreError" : 0.24945548927706168, + "scoreConfidence" : [ + 2.8139287912545705, + 3.312839769808694 + ], + "scorePercentiles" : { + "0.0" : 2.974207533293698, + "50.0" : 3.0691086387526685, + "90.0" : 3.1474903121460036, + "95.0" : 3.1474903121460036, + "99.0" : 3.1474903121460036, + "99.9" : 3.1474903121460036, + "99.99" : 3.1474903121460036, + "99.999" : 3.1474903121460036, + "99.9999" : 3.1474903121460036, + "100.0" : 3.1474903121460036 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.974207533293698, + 2.9967986261234274, + 2.9765347601190477 + ], + [ + 3.1438558001257073, + 3.1474903121460036, + 3.1414186513819096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.754872169934478, + "scoreError" : 0.08748019619302023, + "scoreConfidence" : [ + 2.6673919737414575, + 2.842352366127498 + ], + "scorePercentiles" : { + "0.0" : 2.725468605449591, + "50.0" : 2.7536521554326057, + "90.0" : 2.7854637137287663, + "95.0" : 2.7854637137287663, + "99.0" : 2.7854637137287663, + "99.9" : 2.7854637137287663, + "99.99" : 2.7854637137287663, + "99.999" : 2.7854637137287663, + "99.9999" : 2.7854637137287663, + "100.0" : 2.7854637137287663 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7271460545404964, + 2.7267169506543074, + 2.725468605449591 + ], + [ + 2.7854637137287663, + 2.780158256324715, + 2.7842794389089898 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17466322585009306, + "scoreError" : 0.0127288363512104, + "scoreConfidence" : [ + 0.16193438949888267, + 0.18739206220130344 + ], + "scorePercentiles" : { + "0.0" : 0.17004018263590145, + "50.0" : 0.1751129124102042, + "90.0" : 0.17888705058852994, + "95.0" : 0.17888705058852994, + "99.0" : 0.17888705058852994, + "99.9" : 0.17888705058852994, + "99.99" : 0.17888705058852994, + "99.999" : 0.17888705058852994, + "99.9999" : 0.17888705058852994, + "100.0" : 0.17888705058852994 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17004018263590145, + 0.17150322198593723, + 0.1700991955401337 + ], + [ + 0.17888705058852994, + 0.17872260283447117, + 0.1787271015155848 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3299036247577283, + "scoreError" : 0.005064740456996642, + "scoreConfidence" : [ + 0.32483888430073166, + 0.3349683652147249 + ], + "scorePercentiles" : { + "0.0" : 0.32805842151363057, + "50.0" : 0.3298960810699583, + "90.0" : 0.3317419187593299, + "95.0" : 0.3317419187593299, + "99.0" : 0.3317419187593299, + "99.9" : 0.3317419187593299, + "99.99" : 0.3317419187593299, + "99.999" : 0.3317419187593299, + "99.9999" : 0.3317419187593299, + "100.0" : 0.3317419187593299 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3317419187593299, + 0.3315355167418114, + 0.3313575143141153 + ], + [ + 0.32843464782580134, + 0.32829372939168117, + 0.32805842151363057 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14567677778474744, + "scoreError" : 0.0028555890197772024, + "scoreConfidence" : [ + 0.14282118876497024, + 0.14853236680452464 + ], + "scorePercentiles" : { + "0.0" : 0.1445258718801035, + "50.0" : 0.14583122678947527, + "90.0" : 0.1466726741027559, + "95.0" : 0.1466726741027559, + "99.0" : 0.1466726741027559, + "99.9" : 0.1466726741027559, + "99.99" : 0.1466726741027559, + "99.999" : 0.1466726741027559, + "99.9999" : 0.1466726741027559, + "100.0" : 0.1466726741027559 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1466726741027559, + 0.14650473137608228, + 0.1465749810043092 + ], + [ + 0.14515772220286827, + 0.14462468614236543, + 0.1445258718801035 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4061403932745003, + "scoreError" : 0.022506198892622103, + "scoreConfidence" : [ + 0.3836341943818782, + 0.4286465921671224 + ], + "scorePercentiles" : { + "0.0" : 0.39846834665497866, + "50.0" : 0.40510007442277274, + "90.0" : 0.4152746352726216, + "95.0" : 0.4152746352726216, + "99.0" : 0.4152746352726216, + "99.9" : 0.4152746352726216, + "99.99" : 0.4152746352726216, + "99.999" : 0.4152746352726216, + "99.9999" : 0.4152746352726216, + "100.0" : 0.4152746352726216 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40001473088, + 0.39852163640710925, + 0.39846834665497866 + ], + [ + 0.4152746352726216, + 0.41437759246674677, + 0.41018541796554553 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16364712026707054, + "scoreError" : 0.005740254663860758, + "scoreConfidence" : [ + 0.15790686560320977, + 0.1693873749309313 + ], + "scorePercentiles" : { + "0.0" : 0.160553607520149, + "50.0" : 0.1641300293340589, + "90.0" : 0.16646828047542156, + "95.0" : 0.16646828047542156, + "99.0" : 0.16646828047542156, + "99.9" : 0.16646828047542156, + "99.99" : 0.16646828047542156, + "99.999" : 0.16646828047542156, + "99.9999" : 0.16646828047542156, + "100.0" : 0.16646828047542156 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1644634740486136, + 0.16213730089012113, + 0.160553607520149 + ], + [ + 0.16646828047542156, + 0.16405755544983266, + 0.1642025032182851 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047060121984730065, + "scoreError" : 6.134371993338326E-4, + "scoreConfidence" : [ + 0.04644668478539623, + 0.0476735591840639 + ], + "scorePercentiles" : { + "0.0" : 0.04686641361258998, + "50.0" : 0.0470081451281045, + "90.0" : 0.04743384679090991, + "95.0" : 0.04743384679090991, + "99.0" : 0.04743384679090991, + "99.9" : 0.04743384679090991, + "99.99" : 0.04743384679090991, + "99.999" : 0.04743384679090991, + "99.9999" : 0.04743384679090991, + "100.0" : 0.04743384679090991 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04692841372352108, + 0.046878788224264015, + 0.04686641361258998 + ], + [ + 0.04743384679090991, + 0.04708787653268792, + 0.0471653930244075 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8584423.750146763, + "scoreError" : 304009.9565947829, + "scoreConfidence" : [ + 8280413.7935519805, + 8888433.706741545 + ], + "scorePercentiles" : { + "0.0" : 8474155.465707028, + "50.0" : 8577629.37506578, + "90.0" : 8696232.69826087, + "95.0" : 8696232.69826087, + "99.0" : 8696232.69826087, + "99.9" : 8696232.69826087, + "99.99" : 8696232.69826087, + "99.999" : 8696232.69826087, + "99.9999" : 8696232.69826087, + "100.0" : 8696232.69826087 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8655087.233564014, + 8696232.69826087, + 8695190.529105127 + ], + [ + 8500171.516567545, + 8485705.057675997, + 8474155.465707028 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-27T10:34:01Z-7a411bc59d837a810f4b50f7400d2d917f831eb6-jdk17.json b/performance-results/2025-08-27T10:34:01Z-7a411bc59d837a810f4b50f7400d2d917f831eb6-jdk17.json new file mode 100644 index 0000000000..b651a6ce91 --- /dev/null +++ b/performance-results/2025-08-27T10:34:01Z-7a411bc59d837a810f4b50f7400d2d917f831eb6-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3390337902614204, + "scoreError" : 0.040181787519266904, + "scoreConfidence" : [ + 3.2988520027421537, + 3.379215577780687 + ], + "scorePercentiles" : { + "0.0" : 3.334204575044753, + "50.0" : 3.337209725730821, + "90.0" : 3.347511134539287, + "95.0" : 3.347511134539287, + "99.0" : 3.347511134539287, + "99.9" : 3.347511134539287, + "99.99" : 3.347511134539287, + "99.999" : 3.347511134539287, + "99.9999" : 3.347511134539287, + "100.0" : 3.347511134539287 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3398701799671238, + 3.347511134539287 + ], + [ + 3.334204575044753, + 3.3345492714945184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.688411404540354, + "scoreError" : 0.02536036491619441, + "scoreConfidence" : [ + 1.6630510396241596, + 1.7137717694565484 + ], + "scorePercentiles" : { + "0.0" : 1.6835138363776097, + "50.0" : 1.6889813205194217, + "90.0" : 1.6921691407449626, + "95.0" : 1.6921691407449626, + "99.0" : 1.6921691407449626, + "99.9" : 1.6921691407449626, + "99.99" : 1.6921691407449626, + "99.999" : 1.6921691407449626, + "99.9999" : 1.6921691407449626, + "100.0" : 1.6921691407449626 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6909113186892744, + 1.6870513223495691 + ], + [ + 1.6835138363776097, + 1.6921691407449626 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8482055391713899, + "scoreError" : 0.02816535450979951, + "scoreConfidence" : [ + 0.8200401846615903, + 0.8763708936811894 + ], + "scorePercentiles" : { + "0.0" : 0.8444548916733913, + "50.0" : 0.8469458364398222, + "90.0" : 0.8544755921325234, + "95.0" : 0.8544755921325234, + "99.0" : 0.8544755921325234, + "99.9" : 0.8544755921325234, + "99.99" : 0.8544755921325234, + "99.999" : 0.8544755921325234, + "99.9999" : 0.8544755921325234, + "100.0" : 0.8544755921325234 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8444548916733913, + 0.8544755921325234 + ], + [ + 0.8464778211497682, + 0.8474138517298763 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.194405746452734, + "scoreError" : 0.2818172877667651, + "scoreConfidence" : [ + 15.912588458685969, + 16.476223034219498 + ], + "scorePercentiles" : { + "0.0" : 16.100474488657024, + "50.0" : 16.18084988153969, + "90.0" : 16.350086561065005, + "95.0" : 16.350086561065005, + "99.0" : 16.350086561065005, + "99.9" : 16.350086561065005, + "99.99" : 16.350086561065005, + "99.999" : 16.350086561065005, + "99.9999" : 16.350086561065005, + "100.0" : 16.350086561065005 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.100474488657024, + 16.350086561065005, + 16.233727606167633 + ], + [ + 16.103327473673886, + 16.250846192241127, + 16.127972156911746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2652.3469234215167, + "scoreError" : 63.521546694356736, + "scoreConfidence" : [ + 2588.82537672716, + 2715.8684701158736 + ], + "scorePercentiles" : { + "0.0" : 2617.452192645777, + "50.0" : 2654.7661322210365, + "90.0" : 2676.9207346853805, + "95.0" : 2676.9207346853805, + "99.0" : 2676.9207346853805, + "99.9" : 2676.9207346853805, + "99.99" : 2676.9207346853805, + "99.999" : 2676.9207346853805, + "99.9999" : 2676.9207346853805, + "100.0" : 2676.9207346853805 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2676.9207346853805, + 2666.3580722280626, + 2643.1741922140104 + ], + [ + 2670.0658321066194, + 2617.452192645777, + 2640.1105166492507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75772.2727941917, + "scoreError" : 3152.903105798766, + "scoreConfidence" : [ + 72619.36968839294, + 78925.17589999046 + ], + "scorePercentiles" : { + "0.0" : 74715.05052723303, + "50.0" : 75695.52533501977, + "90.0" : 77177.83602567468, + "95.0" : 77177.83602567468, + "99.0" : 77177.83602567468, + "99.9" : 77177.83602567468, + "99.99" : 77177.83602567468, + "99.999" : 77177.83602567468, + "99.9999" : 77177.83602567468, + "100.0" : 77177.83602567468 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76537.97803882413, + 76617.54137664581, + 77177.83602567468 + ], + [ + 74732.15816555708, + 74715.05052723303, + 74853.0726312154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 359.0986410632618, + "scoreError" : 9.08988419474538, + "scoreConfidence" : [ + 350.00875686851646, + 368.1885252580072 + ], + "scorePercentiles" : { + "0.0" : 352.95917391827123, + "50.0" : 360.17985089931534, + "90.0" : 362.12810424499315, + "95.0" : 362.12810424499315, + "99.0" : 362.12810424499315, + "99.9" : 362.12810424499315, + "99.99" : 362.12810424499315, + "99.999" : 362.12810424499315, + "99.9999" : 362.12810424499315, + "100.0" : 362.12810424499315 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.4349063569992, + 358.3998039946362, + 352.95917391827123 + ], + [ + 362.12810424499315, + 360.74506242303966, + 359.9247954416315 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.68400614479106, + "scoreError" : 2.235401740135939, + "scoreConfidence" : [ + 112.44860440465511, + 116.919407884927 + ], + "scorePercentiles" : { + "0.0" : 113.70201859305065, + "50.0" : 114.43293070775633, + "90.0" : 115.75131455724222, + "95.0" : 115.75131455724222, + "99.0" : 115.75131455724222, + "99.9" : 115.75131455724222, + "99.99" : 115.75131455724222, + "99.999" : 115.75131455724222, + "99.9999" : 115.75131455724222, + "100.0" : 115.75131455724222 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.24320303196976, + 113.70201859305065, + 114.33806236272213 + ], + [ + 114.52779905279053, + 115.75131455724222, + 115.54163927097105 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06143616736855179, + "scoreError" : 0.0013484169245515257, + "scoreConfidence" : [ + 0.06008775044400027, + 0.06278458429310332 + ], + "scorePercentiles" : { + "0.0" : 0.060915389583650593, + "50.0" : 0.061371202135880626, + "90.0" : 0.06222678957095299, + "95.0" : 0.06222678957095299, + "99.0" : 0.06222678957095299, + "99.9" : 0.06222678957095299, + "99.99" : 0.06222678957095299, + "99.999" : 0.06222678957095299, + "99.9999" : 0.06222678957095299, + "100.0" : 0.06222678957095299 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06155168843095256, + 0.06222678957095299, + 0.06166323886072984 + ], + [ + 0.06106918192421605, + 0.061190715840808686, + 0.060915389583650593 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.829091797873001E-4, + "scoreError" : 7.6282105637454275E-6, + "scoreConfidence" : [ + 3.7528096922355463E-4, + 3.9053739035104553E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7944976195889606E-4, + "50.0" : 3.828158352802029E-4, + "90.0" : 3.8650623778317694E-4, + "95.0" : 3.8650623778317694E-4, + "99.0" : 3.8650623778317694E-4, + "99.9" : 3.8650623778317694E-4, + "99.99" : 3.8650623778317694E-4, + "99.999" : 3.8650623778317694E-4, + "99.9999" : 3.8650623778317694E-4, + "100.0" : 3.8650623778317694E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.853830244194048E-4, + 3.826201136603075E-4, + 3.8301155690009835E-4 + ], + [ + 3.8650623778317694E-4, + 3.7944976195889606E-4, + 3.804843840019164E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1252938866061631, + "scoreError" : 0.0029961725246053445, + "scoreConfidence" : [ + 0.12229771408155776, + 0.12829005913076846 + ], + "scorePercentiles" : { + "0.0" : 0.1241225439075552, + "50.0" : 0.1252945209307919, + "90.0" : 0.12634637766743737, + "95.0" : 0.12634637766743737, + "99.0" : 0.12634637766743737, + "99.9" : 0.12634637766743737, + "99.99" : 0.12634637766743737, + "99.999" : 0.12634637766743737, + "99.9999" : 0.12634637766743737, + "100.0" : 0.12634637766743737 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12634637766743737, + 0.12628474388796282, + 0.12615588273956704 + ], + [ + 0.12442061231243935, + 0.1241225439075552, + 0.12443315912201677 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01348185290798655, + "scoreError" : 7.087319451469934E-4, + "scoreConfidence" : [ + 0.012773120962839557, + 0.014190584853133542 + ], + "scorePercentiles" : { + "0.0" : 0.013228790655835076, + "50.0" : 0.013476799982965651, + "90.0" : 0.013740421682658023, + "95.0" : 0.013740421682658023, + "99.0" : 0.013740421682658023, + "99.9" : 0.013740421682658023, + "99.99" : 0.013740421682658023, + "99.999" : 0.013740421682658023, + "99.9999" : 0.013740421682658023, + "100.0" : 0.013740421682658023 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013269341777375576, + 0.013257932122899474, + 0.013228790655835076 + ], + [ + 0.013684258188555728, + 0.013740421682658023, + 0.013710373020595405 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.000315453717323, + "scoreError" : 0.010281803079813455, + "scoreConfidence" : [ + 0.9900336506375097, + 1.0105972567971366 + ], + "scorePercentiles" : { + "0.0" : 0.9975146206862159, + "50.0" : 0.9991784542125127, + "90.0" : 1.0074632220207516, + "95.0" : 1.0074632220207516, + "99.0" : 1.0074632220207516, + "99.9" : 1.0074632220207516, + "99.99" : 1.0074632220207516, + "99.999" : 1.0074632220207516, + "99.9999" : 1.0074632220207516, + "100.0" : 1.0074632220207516 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.000598892046023, + 1.0074632220207516, + 0.997959079125923 + ], + [ + 0.9989970976925382, + 0.9975146206862159, + 0.9993598107324873 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010895967165661968, + "scoreError" : 4.569968083251853E-4, + "scoreConfidence" : [ + 0.010438970357336782, + 0.011352963973987154 + ], + "scorePercentiles" : { + "0.0" : 0.01068820548847092, + "50.0" : 0.010906926846812453, + "90.0" : 0.01106819204836239, + "95.0" : 0.01106819204836239, + "99.0" : 0.01106819204836239, + "99.9" : 0.01106819204836239, + "99.99" : 0.01106819204836239, + "99.999" : 0.01106819204836239, + "99.9999" : 0.01106819204836239, + "100.0" : 0.01106819204836239 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010802823625490433, + 0.010765006148785098, + 0.01068820548847092 + ], + [ + 0.011011030068134472, + 0.01104054561472849, + 0.01106819204836239 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.21862355526878, + "scoreError" : 0.30278729613574984, + "scoreConfidence" : [ + 2.9158362591330302, + 3.5214108514045295 + ], + "scorePercentiles" : { + "0.0" : 3.1073994062111803, + "50.0" : 3.216452829987154, + "90.0" : 3.3269261669993346, + "95.0" : 3.3269261669993346, + "99.0" : 3.3269261669993346, + "99.9" : 3.3269261669993346, + "99.99" : 3.3269261669993346, + "99.999" : 3.3269261669993346, + "99.9999" : 3.3269261669993346, + "100.0" : 3.3269261669993346 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.123449860712055, + 3.1309133028785983, + 3.1073994062111803 + ], + [ + 3.3210602377158036, + 3.3019923570957097, + 3.3269261669993346 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.742389212740728, + "scoreError" : 0.03467718116297298, + "scoreConfidence" : [ + 2.707712031577755, + 2.777066393903701 + ], + "scorePercentiles" : { + "0.0" : 2.7278318311511183, + "50.0" : 2.7430890119044493, + "90.0" : 2.7558241328189585, + "95.0" : 2.7558241328189585, + "99.0" : 2.7558241328189585, + "99.9" : 2.7558241328189585, + "99.99" : 2.7558241328189585, + "99.999" : 2.7558241328189585, + "99.9999" : 2.7558241328189585, + "100.0" : 2.7558241328189585 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7278318311511183, + 2.728815456480218, + 2.7453446464452376 + ], + [ + 2.740833377363661, + 2.7558241328189585, + 2.755685832185175 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17781331834387862, + "scoreError" : 0.005071955394277396, + "scoreConfidence" : [ + 0.1727413629496012, + 0.18288527373815602 + ], + "scorePercentiles" : { + "0.0" : 0.17599284872056598, + "50.0" : 0.17782411953489902, + "90.0" : 0.1796192968118545, + "95.0" : 0.1796192968118545, + "99.0" : 0.1796192968118545, + "99.9" : 0.1796192968118545, + "99.99" : 0.1796192968118545, + "99.999" : 0.1796192968118545, + "99.9999" : 0.1796192968118545, + "100.0" : 0.1796192968118545 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17917406951785425, + 0.1796192968118545, + 0.17956140046325392 + ], + [ + 0.17605812499779933, + 0.17599284872056598, + 0.1764741695519438 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32363920910783217, + "scoreError" : 0.021666965543669203, + "scoreConfidence" : [ + 0.30197224356416297, + 0.3453061746515014 + ], + "scorePercentiles" : { + "0.0" : 0.3162001661607538, + "50.0" : 0.3233073381117014, + "90.0" : 0.33203949604887445, + "95.0" : 0.33203949604887445, + "99.0" : 0.33203949604887445, + "99.9" : 0.33203949604887445, + "99.99" : 0.33203949604887445, + "99.999" : 0.33203949604887445, + "99.9999" : 0.33203949604887445, + "100.0" : 0.33203949604887445 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.31751860342911575, + 0.3162338099168327, + 0.3162001661607538 + ], + [ + 0.33203949604887445, + 0.3307471062971292, + 0.32909607279428704 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14634197941326763, + "scoreError" : 0.00121342474064956, + "scoreConfidence" : [ + 0.14512855467261807, + 0.14755540415391719 + ], + "scorePercentiles" : { + "0.0" : 0.14587210253081467, + "50.0" : 0.14626416095736489, + "90.0" : 0.14709430583216887, + "95.0" : 0.14709430583216887, + "99.0" : 0.14709430583216887, + "99.9" : 0.14709430583216887, + "99.99" : 0.14709430583216887, + "99.999" : 0.14709430583216887, + "99.9999" : 0.14709430583216887, + "100.0" : 0.14709430583216887 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1464074375960764, + 0.14709430583216887, + 0.1464886214220842 + ], + [ + 0.14606852477980808, + 0.14587210253081467, + 0.1461208843186534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3985283491054757, + "scoreError" : 0.04191430842945069, + "scoreConfidence" : [ + 0.356614040676025, + 0.4404426575349264 + ], + "scorePercentiles" : { + "0.0" : 0.3839633240929161, + "50.0" : 0.3986570056303643, + "90.0" : 0.41242252857967665, + "95.0" : 0.41242252857967665, + "99.0" : 0.41242252857967665, + "99.9" : 0.41242252857967665, + "99.99" : 0.41242252857967665, + "99.999" : 0.41242252857967665, + "99.9999" : 0.41242252857967665, + "100.0" : 0.41242252857967665 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41242252857967665, + 0.4123810570309278, + 0.41168276295747397 + ], + [ + 0.3856312483032547, + 0.3850891736686049, + 0.3839633240929161 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15914319424519666, + "scoreError" : 0.008784679767922776, + "scoreConfidence" : [ + 0.15035851447727389, + 0.16792787401311943 + ], + "scorePercentiles" : { + "0.0" : 0.1562858656758404, + "50.0" : 0.15859133283704407, + "90.0" : 0.16314787811602716, + "95.0" : 0.16314787811602716, + "99.0" : 0.16314787811602716, + "99.9" : 0.16314787811602716, + "99.99" : 0.16314787811602716, + "99.999" : 0.16314787811602716, + "99.9999" : 0.16314787811602716, + "100.0" : 0.16314787811602716 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1562858656758404, + 0.15634907707821954, + 0.15648350065721528 + ], + [ + 0.16189367892700457, + 0.16314787811602716, + 0.1606991650168729 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04739547088272386, + "scoreError" : 0.001423599091643021, + "scoreConfidence" : [ + 0.04597187179108084, + 0.048819069974366885 + ], + "scorePercentiles" : { + "0.0" : 0.046999444647061864, + "50.0" : 0.04729328237685835, + "90.0" : 0.04836250592189578, + "95.0" : 0.04836250592189578, + "99.0" : 0.04836250592189578, + "99.9" : 0.04836250592189578, + "99.99" : 0.04836250592189578, + "99.999" : 0.04836250592189578, + "99.9999" : 0.04836250592189578, + "100.0" : 0.04836250592189578 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04836250592189578, + 0.047416492332859175, + 0.04740518493007822 + ], + [ + 0.04718137982363848, + 0.04700781764080965, + 0.046999444647061864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8805242.38946337, + "scoreError" : 351319.37218387827, + "scoreConfidence" : [ + 8453923.017279493, + 9156561.761647249 + ], + "scorePercentiles" : { + "0.0" : 8675478.313963573, + "50.0" : 8795151.81116318, + "90.0" : 8972276.431390135, + "95.0" : 8972276.431390135, + "99.0" : 8972276.431390135, + "99.9" : 8972276.431390135, + "99.99" : 8972276.431390135, + "99.999" : 8972276.431390135, + "99.9999" : 8972276.431390135, + "100.0" : 8972276.431390135 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8675478.313963573, + 8687455.127604166, + 8726146.37609075 + ], + [ + 8972276.431390135, + 8864157.246235607, + 8905940.841495993 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-08-27T10:34:09Z-7a411bc59d837a810f4b50f7400d2d917f831eb6-jdk17.json b/performance-results/2025-08-27T10:34:09Z-7a411bc59d837a810f4b50f7400d2d917f831eb6-jdk17.json new file mode 100644 index 0000000000..2b5faedce7 --- /dev/null +++ b/performance-results/2025-08-27T10:34:09Z-7a411bc59d837a810f4b50f7400d2d917f831eb6-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.348418290898171, + "scoreError" : 0.05253155075779109, + "scoreConfidence" : [ + 3.29588674014038, + 3.400949841655962 + ], + "scorePercentiles" : { + "0.0" : 3.3391856798555417, + "50.0" : 3.3489754079306633, + "90.0" : 3.3565366678758144, + "95.0" : 3.3565366678758144, + "99.0" : 3.3565366678758144, + "99.9" : 3.3565366678758144, + "99.99" : 3.3565366678758144, + "99.999" : 3.3565366678758144, + "99.9999" : 3.3565366678758144, + "100.0" : 3.3565366678758144 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3391856798555417, + 3.3565366678758144 + ], + [ + 3.3441542354809783, + 3.3537965803803482 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6942500988369928, + "scoreError" : 0.025669367803365952, + "scoreConfidence" : [ + 1.668580731033627, + 1.7199194666403588 + ], + "scorePercentiles" : { + "0.0" : 1.689255634475055, + "50.0" : 1.694455855774605, + "90.0" : 1.6988330493237065, + "95.0" : 1.6988330493237065, + "99.0" : 1.6988330493237065, + "99.9" : 1.6988330493237065, + "99.99" : 1.6988330493237065, + "99.999" : 1.6988330493237065, + "99.9999" : 1.6988330493237065, + "100.0" : 1.6988330493237065 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.689255634475055, + 1.6988330493237065 + ], + [ + 1.69364770229273, + 1.6952640092564797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8509181955269773, + "scoreError" : 0.0214721002100609, + "scoreConfidence" : [ + 0.8294460953169165, + 0.8723902957370382 + ], + "scorePercentiles" : { + "0.0" : 0.8468266606404825, + "50.0" : 0.8514447504142617, + "90.0" : 0.8539566206389035, + "95.0" : 0.8539566206389035, + "99.0" : 0.8539566206389035, + "99.9" : 0.8539566206389035, + "99.99" : 0.8539566206389035, + "99.999" : 0.8539566206389035, + "99.9999" : 0.8539566206389035, + "100.0" : 0.8539566206389035 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8468266606404825, + 0.8539566206389035 + ], + [ + 0.8496286532151931, + 0.8532608476133302 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.369539201814092, + "scoreError" : 0.23133610122967188, + "scoreConfidence" : [ + 16.13820310058442, + 16.600875303043765 + ], + "scorePercentiles" : { + "0.0" : 16.280857239393875, + "50.0" : 16.372328474863437, + "90.0" : 16.45349925142323, + "95.0" : 16.45349925142323, + "99.0" : 16.45349925142323, + "99.9" : 16.45349925142323, + "99.99" : 16.45349925142323, + "99.999" : 16.45349925142323, + "99.9999" : 16.45349925142323, + "100.0" : 16.45349925142323 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.313823687874052, + 16.280857239393875, + 16.290838331667466 + ], + [ + 16.430833261852825, + 16.44738343867308, + 16.45349925142323 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2825.5631629737945, + "scoreError" : 121.72355468367753, + "scoreConfidence" : [ + 2703.839608290117, + 2947.286717657472 + ], + "scorePercentiles" : { + "0.0" : 2784.8685278532257, + "50.0" : 2825.2152736916923, + "90.0" : 2868.666270966133, + "95.0" : 2868.666270966133, + "99.0" : 2868.666270966133, + "99.9" : 2868.666270966133, + "99.99" : 2868.666270966133, + "99.999" : 2868.666270966133, + "99.9999" : 2868.666270966133, + "100.0" : 2868.666270966133 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2785.4005001348196, + 2784.8685278532257, + 2787.6948176679407 + ], + [ + 2868.666270966133, + 2862.735729715444, + 2864.013131505203 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 78198.26833764707, + "scoreError" : 570.3557785203005, + "scoreConfidence" : [ + 77627.91255912677, + 78768.62411616737 + ], + "scorePercentiles" : { + "0.0" : 77949.33222786066, + "50.0" : 78230.89929536122, + "90.0" : 78395.0397320315, + "95.0" : 78395.0397320315, + "99.0" : 78395.0397320315, + "99.9" : 78395.0397320315, + "99.99" : 78395.0397320315, + "99.999" : 78395.0397320315, + "99.9999" : 78395.0397320315, + "100.0" : 78395.0397320315 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78122.0133580323, + 77991.43175977214, + 77949.33222786066 + ], + [ + 78339.78523269012, + 78392.00771549562, + 78395.0397320315 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 364.89581742746736, + "scoreError" : 5.895845231828615, + "scoreConfidence" : [ + 358.99997219563875, + 370.791662659296 + ], + "scorePercentiles" : { + "0.0" : 362.3449245860287, + "50.0" : 364.7081739103934, + "90.0" : 367.79599133940513, + "95.0" : 367.79599133940513, + "99.0" : 367.79599133940513, + "99.9" : 367.79599133940513, + "99.99" : 367.79599133940513, + "99.999" : 367.79599133940513, + "99.9999" : 367.79599133940513, + "100.0" : 367.79599133940513 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.5217749802183, + 367.79599133940513, + 365.68561564660286 + ], + [ + 363.73073217418386, + 363.2958658383651, + 362.3449245860287 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.55987161189427, + "scoreError" : 0.4917094009477342, + "scoreConfidence" : [ + 116.06816221094653, + 117.05158101284201 + ], + "scorePercentiles" : { + "0.0" : 116.30546997283993, + "50.0" : 116.5669907137955, + "90.0" : 116.76506695121296, + "95.0" : 116.76506695121296, + "99.0" : 116.76506695121296, + "99.9" : 116.76506695121296, + "99.99" : 116.76506695121296, + "99.999" : 116.76506695121296, + "99.9999" : 116.76506695121296, + "100.0" : 116.76506695121296 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.72885772999473, + 116.57905977783506, + 116.76506695121296 + ], + [ + 116.30546997283993, + 116.55492164975595, + 116.42585358972694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06124889993698327, + "scoreError" : 5.844637687865314E-4, + "scoreConfidence" : [ + 0.060664436168196736, + 0.061833363705769806 + ], + "scorePercentiles" : { + "0.0" : 0.06101960443362378, + "50.0" : 0.061251267190739506, + "90.0" : 0.06155508280293984, + "95.0" : 0.06155508280293984, + "99.0" : 0.06155508280293984, + "99.9" : 0.06155508280293984, + "99.99" : 0.06155508280293984, + "99.999" : 0.06155508280293984, + "99.9999" : 0.06155508280293984, + "100.0" : 0.06155508280293984 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06155508280293984, + 0.061367762063146265, + 0.06134222909791316 + ], + [ + 0.06101960443362378, + 0.06104841594071071, + 0.06116030528356584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.695052860167507E-4, + "scoreError" : 2.8828153343741848E-5, + "scoreConfidence" : [ + 3.4067713267300887E-4, + 3.9833343936049255E-4 + ], + "scorePercentiles" : { + "0.0" : 3.600580062172536E-4, + "50.0" : 3.6940418456582523E-4, + "90.0" : 3.793294056317001E-4, + "95.0" : 3.793294056317001E-4, + "99.0" : 3.793294056317001E-4, + "99.9" : 3.793294056317001E-4, + "99.99" : 3.793294056317001E-4, + "99.999" : 3.793294056317001E-4, + "99.9999" : 3.793294056317001E-4, + "100.0" : 3.793294056317001E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7877642548584333E-4, + 3.793294056317001E-4, + 3.7855490170173684E-4 + ], + [ + 3.600580062172536E-4, + 3.602534674299136E-4, + 3.600595096340566E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12475117517619351, + "scoreError" : 0.004132553722866594, + "scoreConfidence" : [ + 0.12061862145332691, + 0.1288837288990601 + ], + "scorePercentiles" : { + "0.0" : 0.12327218898462829, + "50.0" : 0.12470280680783176, + "90.0" : 0.12626789583201808, + "95.0" : 0.12626789583201808, + "99.0" : 0.12626789583201808, + "99.9" : 0.12626789583201808, + "99.99" : 0.12626789583201808, + "99.999" : 0.12626789583201808, + "99.9999" : 0.12626789583201808, + "100.0" : 0.12626789583201808 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12591662153110048, + 0.12608798834980836, + 0.12626789583201808 + ], + [ + 0.12347336427504291, + 0.12348899208456304, + 0.12327218898462829 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012980520289130057, + "scoreError" : 7.166707650873676E-4, + "scoreConfidence" : [ + 0.01226384952404269, + 0.013697191054217425 + ], + "scorePercentiles" : { + "0.0" : 0.012740515293512106, + "50.0" : 0.012979152217609499, + "90.0" : 0.013219519620816241, + "95.0" : 0.013219519620816241, + "99.0" : 0.013219519620816241, + "99.9" : 0.013219519620816241, + "99.99" : 0.013219519620816241, + "99.999" : 0.013219519620816241, + "99.9999" : 0.013219519620816241, + "100.0" : 0.013219519620816241 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012745910946690883, + 0.012740515293512106, + 0.012755540019949387 + ], + [ + 0.013202764415269611, + 0.013219519620816241, + 0.013218871438542132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0833504032064865, + "scoreError" : 0.01079171688957099, + "scoreConfidence" : [ + 1.0725586863169154, + 1.0941421200960575 + ], + "scorePercentiles" : { + "0.0" : 1.0791623952735514, + "50.0" : 1.0832560130188453, + "90.0" : 1.0873067735377255, + "95.0" : 1.0873067735377255, + "99.0" : 1.0873067735377255, + "99.9" : 1.0873067735377255, + "99.99" : 1.0873067735377255, + "99.999" : 1.0873067735377255, + "99.9999" : 1.0873067735377255, + "100.0" : 1.0873067735377255 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0859065773072747, + 1.0872145567514677, + 1.0873067735377255 + ], + [ + 1.080605448730416, + 1.0799066676384839, + 1.0791623952735514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010156438679503086, + "scoreError" : 1.9386913795007283E-4, + "scoreConfidence" : [ + 0.009962569541553013, + 0.010350307817453159 + ], + "scorePercentiles" : { + "0.0" : 0.01008582134594166, + "50.0" : 0.01015683186500409, + "90.0" : 0.010232662852710767, + "95.0" : 0.010232662852710767, + "99.0" : 0.010232662852710767, + "99.9" : 0.010232662852710767, + "99.99" : 0.010232662852710767, + "99.999" : 0.010232662852710767, + "99.9999" : 0.010232662852710767, + "100.0" : 0.010232662852710767 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010091656708465279, + 0.01008582134594166, + 0.010104413048047076 + ], + [ + 0.010209250681961107, + 0.010232662852710767, + 0.010214827439892625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.136358566834668, + "scoreError" : 0.04481716559088227, + "scoreConfidence" : [ + 3.0915414012437856, + 3.1811757324255505 + ], + "scorePercentiles" : { + "0.0" : 3.1127683721219666, + "50.0" : 3.136553746405208, + "90.0" : 3.161544818584071, + "95.0" : 3.161544818584071, + "99.0" : 3.161544818584071, + "99.9" : 3.161544818584071, + "99.99" : 3.161544818584071, + "99.999" : 3.161544818584071, + "99.9999" : 3.161544818584071, + "100.0" : 3.161544818584071 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1127683721219666, + 3.161544818584071, + 3.1295162922403006 + ], + [ + 3.141214425251256, + 3.133739317669173, + 3.139368175141243 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7876548104472807, + "scoreError" : 0.01760703535917173, + "scoreConfidence" : [ + 2.770047775088109, + 2.805261845806452 + ], + "scorePercentiles" : { + "0.0" : 2.7797256495275153, + "50.0" : 2.7892098733859614, + "90.0" : 2.7948733095836826, + "95.0" : 2.7948733095836826, + "99.0" : 2.7948733095836826, + "99.9" : 2.7948733095836826, + "99.99" : 2.7948733095836826, + "99.999" : 2.7948733095836826, + "99.9999" : 2.7948733095836826, + "100.0" : 2.7948733095836826 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.791922918202122, + 2.780987238598443, + 2.7797256495275153 + ], + [ + 2.7948733095836826, + 2.7919145949190396, + 2.7865051518528836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17603034332747022, + "scoreError" : 0.005608234707395024, + "scoreConfidence" : [ + 0.1704221086200752, + 0.18163857803486524 + ], + "scorePercentiles" : { + "0.0" : 0.17435669115159969, + "50.0" : 0.175568425794656, + "90.0" : 0.17935473700163207, + "95.0" : 0.17935473700163207, + "99.0" : 0.17935473700163207, + "99.9" : 0.17935473700163207, + "99.99" : 0.17935473700163207, + "99.999" : 0.17935473700163207, + "99.9999" : 0.17935473700163207, + "100.0" : 0.17935473700163207 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17935473700163207, + 0.17694948330531718, + 0.17660892635501474 + ], + [ + 0.17452792523429728, + 0.1743842969169602, + 0.17435669115159969 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32716971681590173, + "scoreError" : 0.008582695131976629, + "scoreConfidence" : [ + 0.3185870216839251, + 0.33575241194787836 + ], + "scorePercentiles" : { + "0.0" : 0.3241755609115664, + "50.0" : 0.327179740328899, + "90.0" : 0.330020016500561, + "95.0" : 0.330020016500561, + "99.0" : 0.330020016500561, + "99.9" : 0.330020016500561, + "99.99" : 0.330020016500561, + "99.999" : 0.330020016500561, + "99.9999" : 0.330020016500561, + "100.0" : 0.330020016500561 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33001869790772886, + 0.32984487861996176, + 0.330020016500561 + ], + [ + 0.3241755609115664, + 0.3244445449177562, + 0.3245146020378363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14447980008128167, + "scoreError" : 0.004958414840948835, + "scoreConfidence" : [ + 0.13952138524033283, + 0.1494382149222305 + ], + "scorePercentiles" : { + "0.0" : 0.14283653247346845, + "50.0" : 0.14445053683420261, + "90.0" : 0.14622189675542102, + "95.0" : 0.14622189675542102, + "99.0" : 0.14622189675542102, + "99.9" : 0.14622189675542102, + "99.99" : 0.14622189675542102, + "99.999" : 0.14622189675542102, + "99.9999" : 0.14622189675542102, + "100.0" : 0.14622189675542102 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14289249054069503, + 0.1428721645141012, + 0.14283653247346845 + ], + [ + 0.14604713307629397, + 0.14622189675542102, + 0.1460085831277102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.399813786270103, + "scoreError" : 0.018859887922225312, + "scoreConfidence" : [ + 0.3809538983478777, + 0.4186736741923283 + ], + "scorePercentiles" : { + "0.0" : 0.39353117306784197, + "50.0" : 0.3992481166749704, + "90.0" : 0.4074663979953551, + "95.0" : 0.4074663979953551, + "99.0" : 0.4074663979953551, + "99.9" : 0.4074663979953551, + "99.99" : 0.4074663979953551, + "99.999" : 0.4074663979953551, + "99.9999" : 0.4074663979953551, + "100.0" : 0.4074663979953551 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39398527594358207, + 0.39353117306784197, + 0.39369143466792644 + ], + [ + 0.4074663979953551, + 0.40569747853955374, + 0.40451095740635873 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1559648926174102, + "scoreError" : 0.005690136312152007, + "scoreConfidence" : [ + 0.1502747563052582, + 0.1616550289295622 + ], + "scorePercentiles" : { + "0.0" : 0.1538426477854868, + "50.0" : 0.15608610744359558, + "90.0" : 0.15803876313668475, + "95.0" : 0.15803876313668475, + "99.0" : 0.15803876313668475, + "99.9" : 0.15803876313668475, + "99.99" : 0.15803876313668475, + "99.999" : 0.15803876313668475, + "99.9999" : 0.15803876313668475, + "100.0" : 0.15803876313668475 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15803876313668475, + 0.15767512583762988, + 0.15769602843175906 + ], + [ + 0.15449708904956125, + 0.1540397014633395, + 0.1538426477854868 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0465429591171968, + "scoreError" : 0.001531919884485541, + "scoreConfidence" : [ + 0.04501103923271126, + 0.04807487900168234 + ], + "scorePercentiles" : { + "0.0" : 0.04593341110896765, + "50.0" : 0.046551542184661565, + "90.0" : 0.047208760687916615, + "95.0" : 0.047208760687916615, + "99.0" : 0.047208760687916615, + "99.9" : 0.047208760687916615, + "99.99" : 0.047208760687916615, + "99.999" : 0.047208760687916615, + "99.9999" : 0.047208760687916615, + "100.0" : 0.047208760687916615 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04707706223931608, + 0.047208760687916615, + 0.04665846789470246 + ], + [ + 0.04644461647462067, + 0.045935436297657325, + 0.04593341110896765 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8707910.047450403, + "scoreError" : 198252.620393171, + "scoreConfidence" : [ + 8509657.42705723, + 8906162.667843575 + ], + "scorePercentiles" : { + "0.0" : 8636079.027633851, + "50.0" : 8707175.335918924, + "90.0" : 8779058.336842105, + "95.0" : 8779058.336842105, + "99.0" : 8779058.336842105, + "99.9" : 8779058.336842105, + "99.99" : 8779058.336842105, + "99.999" : 8779058.336842105, + "99.9999" : 8779058.336842105, + "100.0" : 8779058.336842105 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8779058.336842105, + 8771173.524101665, + 8766470.707274321 + ], + [ + 8647879.964563526, + 8636079.027633851, + 8646798.72428695 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-14T22:47:12Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json b/performance-results/2025-09-14T22:47:12Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json new file mode 100644 index 0000000000..fc5f49ca2a --- /dev/null +++ b/performance-results/2025-09-14T22:47:12Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3564519638051014, + "scoreError" : 0.026754669074205307, + "scoreConfidence" : [ + 3.329697294730896, + 3.3832066328793067 + ], + "scorePercentiles" : { + "0.0" : 3.3525929748533447, + "50.0" : 3.355450816008278, + "90.0" : 3.3623132483505045, + "95.0" : 3.3623132483505045, + "99.0" : 3.3623132483505045, + "99.9" : 3.3623132483505045, + "99.99" : 3.3623132483505045, + "99.999" : 3.3623132483505045, + "99.9999" : 3.3623132483505045, + "100.0" : 3.3623132483505045 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.355154530462503, + 3.355747101554053 + ], + [ + 3.3525929748533447, + 3.3623132483505045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6955963461669277, + "scoreError" : 0.025399219674262195, + "scoreConfidence" : [ + 1.6701971264926654, + 1.72099556584119 + ], + "scorePercentiles" : { + "0.0" : 1.690949165339102, + "50.0" : 1.6954724679214577, + "90.0" : 1.7004912834856927, + "95.0" : 1.7004912834856927, + "99.0" : 1.7004912834856927, + "99.9" : 1.7004912834856927, + "99.99" : 1.7004912834856927, + "99.999" : 1.7004912834856927, + "99.9999" : 1.7004912834856927, + "100.0" : 1.7004912834856927 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6948558437102028, + 1.690949165339102 + ], + [ + 1.6960890921327125, + 1.7004912834856927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8534863812995895, + "scoreError" : 0.018651240545545403, + "scoreConfidence" : [ + 0.8348351407540441, + 0.872137621845135 + ], + "scorePercentiles" : { + "0.0" : 0.8497672901323416, + "50.0" : 0.8536869071818649, + "90.0" : 0.8568044207022865, + "95.0" : 0.8568044207022865, + "99.0" : 0.8568044207022865, + "99.9" : 0.8568044207022865, + "99.99" : 0.8568044207022865, + "99.999" : 0.8568044207022865, + "99.9999" : 0.8568044207022865, + "100.0" : 0.8568044207022865 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8497672901323416, + 0.8568044207022865 + ], + [ + 0.853874975391003, + 0.8534988389727268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.46773550256071, + "scoreError" : 0.14535237876637508, + "scoreConfidence" : [ + 16.322383123794335, + 16.613087881327086 + ], + "scorePercentiles" : { + "0.0" : 16.39883446360539, + "50.0" : 16.478862692989225, + "90.0" : 16.51826378882782, + "95.0" : 16.51826378882782, + "99.0" : 16.51826378882782, + "99.9" : 16.51826378882782, + "99.99" : 16.51826378882782, + "99.999" : 16.51826378882782, + "99.9999" : 16.51826378882782, + "100.0" : 16.51826378882782 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.515523911638322, + 16.51826378882782, + 16.500452432161843 + ], + [ + 16.457272953816602, + 16.39883446360539, + 16.416065465314304 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2806.031346554064, + "scoreError" : 363.0932911374896, + "scoreConfidence" : [ + 2442.9380554165746, + 3169.1246376915533 + ], + "scorePercentiles" : { + "0.0" : 2685.0981111336173, + "50.0" : 2805.641025032317, + "90.0" : 2927.370860223729, + "95.0" : 2927.370860223729, + "99.0" : 2927.370860223729, + "99.9" : 2927.370860223729, + "99.99" : 2927.370860223729, + "99.999" : 2927.370860223729, + "99.9999" : 2927.370860223729, + "100.0" : 2927.370860223729 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2927.370860223729, + 2919.9838872547216, + 2925.238681771159 + ], + [ + 2691.298162809912, + 2687.198376131245, + 2685.0981111336173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77408.15419943158, + "scoreError" : 4762.3102375177195, + "scoreConfidence" : [ + 72645.84396191385, + 82170.4644369493 + ], + "scorePercentiles" : { + "0.0" : 75849.39108190239, + "50.0" : 77387.68640395226, + "90.0" : 79025.16019962257, + "95.0" : 79025.16019962257, + "99.0" : 79025.16019962257, + "99.9" : 79025.16019962257, + "99.99" : 79025.16019962257, + "99.999" : 79025.16019962257, + "99.9999" : 79025.16019962257, + "100.0" : 79025.16019962257 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75852.58956360034, + 75872.83228754788, + 75849.39108190239 + ], + [ + 78902.54052035665, + 79025.16019962257, + 78946.41154355963 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 372.5555731049557, + "scoreError" : 17.819402263067463, + "scoreConfidence" : [ + 354.7361708418883, + 390.3749753680232 + ], + "scorePercentiles" : { + "0.0" : 366.6306288288166, + "50.0" : 372.29609995145137, + "90.0" : 378.75634030214576, + "95.0" : 378.75634030214576, + "99.0" : 378.75634030214576, + "99.9" : 378.75634030214576, + "99.99" : 378.75634030214576, + "99.999" : 378.75634030214576, + "99.9999" : 378.75634030214576, + "100.0" : 378.75634030214576 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.6306288288166, + 366.7820251499717, + 366.8794815312364 + ], + [ + 377.7127183716663, + 378.5722444458973, + 378.75634030214576 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.1161850867327, + "scoreError" : 4.845730380355185, + "scoreConfidence" : [ + 109.2704547063775, + 118.96191546708789 + ], + "scorePercentiles" : { + "0.0" : 112.37966686592478, + "50.0" : 114.01556114102594, + "90.0" : 115.91073453534281, + "95.0" : 115.91073453534281, + "99.0" : 115.91073453534281, + "99.9" : 115.91073453534281, + "99.99" : 115.91073453534281, + "99.999" : 115.91073453534281, + "99.9999" : 115.91073453534281, + "100.0" : 115.91073453534281 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.27330072085228, + 115.8461484776648, + 115.91073453534281 + ], + [ + 112.37966686592478, + 112.7578215611996, + 112.52943835941201 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06051366981378616, + "scoreError" : 8.270260221785121E-4, + "scoreConfidence" : [ + 0.05968664379160765, + 0.06134069583596467 + ], + "scorePercentiles" : { + "0.0" : 0.06024168675489907, + "50.0" : 0.06048885793870822, + "90.0" : 0.060841332372052276, + "95.0" : 0.060841332372052276, + "99.0" : 0.060841332372052276, + "99.9" : 0.060841332372052276, + "99.99" : 0.060841332372052276, + "99.999" : 0.060841332372052276, + "99.9999" : 0.060841332372052276, + "100.0" : 0.060841332372052276 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060841332372052276, + 0.06072616348366803, + 0.06077492409932905 + ], + [ + 0.06024635977902017, + 0.060251552393748416, + 0.06024168675489907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.558336269404063E-4, + "scoreError" : 2.7422425788469708E-5, + "scoreConfidence" : [ + 3.2841120115193655E-4, + 3.83256052728876E-4 + ], + "scorePercentiles" : { + "0.0" : 3.4670834123205004E-4, + "50.0" : 3.558511579118602E-4, + "90.0" : 3.6515849616556114E-4, + "95.0" : 3.6515849616556114E-4, + "99.0" : 3.6515849616556114E-4, + "99.9" : 3.6515849616556114E-4, + "99.99" : 3.6515849616556114E-4, + "99.999" : 3.6515849616556114E-4, + "99.9999" : 3.6515849616556114E-4, + "100.0" : 3.6515849616556114E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6447403044540883E-4, + 3.6515849616556114E-4, + 3.646380212699439E-4 + ], + [ + 3.4670834123205004E-4, + 3.467945871511623E-4, + 3.472282853783116E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12331382652256352, + "scoreError" : 4.6688850598333167E-4, + "scoreConfidence" : [ + 0.12284693801658018, + 0.12378071502854686 + ], + "scorePercentiles" : { + "0.0" : 0.12304664331680427, + "50.0" : 0.12334823201558294, + "90.0" : 0.12351932606654974, + "95.0" : 0.12351932606654974, + "99.0" : 0.12351932606654974, + "99.9" : 0.12351932606654974, + "99.99" : 0.12351932606654974, + "99.999" : 0.12351932606654974, + "99.9999" : 0.12351932606654974, + "100.0" : 0.12351932606654974 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12351932606654974, + 0.123416112220467, + 0.12333853212299116 + ], + [ + 0.12335793190817472, + 0.12320441350039424, + 0.12304664331680427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01298259531269849, + "scoreError" : 2.4179243872811946E-5, + "scoreConfidence" : [ + 0.012958416068825678, + 0.013006774556571302 + ], + "scorePercentiles" : { + "0.0" : 0.012972689343071374, + "50.0" : 0.012981420286749045, + "90.0" : 0.012994162917464715, + "95.0" : 0.012994162917464715, + "99.0" : 0.012994162917464715, + "99.9" : 0.012994162917464715, + "99.99" : 0.012994162917464715, + "99.999" : 0.012994162917464715, + "99.9999" : 0.012994162917464715, + "100.0" : 0.012994162917464715 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012989887184496538, + 0.012994162917464715, + 0.012985907259802929 + ], + [ + 0.012975991857660222, + 0.01297693331369516, + 0.012972689343071374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0886759140037454, + "scoreError" : 0.2358416273907459, + "scoreConfidence" : [ + 0.8528342866129995, + 1.3245175413944914 + ], + "scorePercentiles" : { + "0.0" : 1.0112115004044488, + "50.0" : 1.088446113614558, + "90.0" : 1.1669702096849475, + "95.0" : 1.1669702096849475, + "99.0" : 1.1669702096849475, + "99.9" : 1.1669702096849475, + "99.99" : 1.1669702096849475, + "99.999" : 1.1669702096849475, + "99.9999" : 1.1669702096849475, + "100.0" : 1.1669702096849475 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0123010509160846, + 1.012202311437247, + 1.0112115004044488 + ], + [ + 1.1669702096849475, + 1.1645911763130312, + 1.1647792352667132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010936801716436862, + "scoreError" : 8.881047436962124E-4, + "scoreConfidence" : [ + 0.01004869697274065, + 0.011824906460133075 + ], + "scorePercentiles" : { + "0.0" : 0.010645533288765215, + "50.0" : 0.010933873830918435, + "90.0" : 0.011231595174130247, + "95.0" : 0.011231595174130247, + "99.0" : 0.011231595174130247, + "99.9" : 0.011231595174130247, + "99.99" : 0.011231595174130247, + "99.999" : 0.011231595174130247, + "99.9999" : 0.011231595174130247, + "100.0" : 0.011231595174130247 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01121760498361156, + 0.011228439646538366, + 0.011231595174130247 + ], + [ + 0.010645533288765215, + 0.010650142678225309, + 0.010647494527350471 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.042485461788847, + "scoreError" : 0.3027566329682602, + "scoreConfidence" : [ + 2.7397288288205868, + 3.345242094757107 + ], + "scorePercentiles" : { + "0.0" : 2.9359650181924883, + "50.0" : 3.04551420930689, + "90.0" : 3.145036716981132, + "95.0" : 3.145036716981132, + "99.0" : 3.145036716981132, + "99.9" : 3.145036716981132, + "99.99" : 3.145036716981132, + "99.999" : 3.145036716981132, + "99.9999" : 3.145036716981132, + "100.0" : 3.145036716981132 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.145036716981132, + 3.139732849435383, + 3.1379178513174404 + ], + [ + 2.9431497675103, + 2.95311056729634, + 2.9359650181924883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6642307488982455, + "scoreError" : 0.2038368917526145, + "scoreConfidence" : [ + 2.460393857145631, + 2.86806764065086 + ], + "scorePercentiles" : { + "0.0" : 2.5970301004933782, + "50.0" : 2.663088486413512, + "90.0" : 2.7332158267286144, + "95.0" : 2.7332158267286144, + "99.0" : 2.7332158267286144, + "99.9" : 2.7332158267286144, + "99.99" : 2.7332158267286144, + "99.999" : 2.7332158267286144, + "99.9999" : 2.7332158267286144, + "100.0" : 2.7332158267286144 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7332158267286144, + 2.731629252390057, + 2.7268218857688113 + ], + [ + 2.5970301004933782, + 2.5993550870582123, + 2.5973323409504023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17667665791073298, + "scoreError" : 0.002204979660085408, + "scoreConfidence" : [ + 0.17447167825064758, + 0.17888163757081837 + ], + "scorePercentiles" : { + "0.0" : 0.17594032069529725, + "50.0" : 0.17657843697311018, + "90.0" : 0.1775555122154753, + "95.0" : 0.1775555122154753, + "99.0" : 0.1775555122154753, + "99.9" : 0.1775555122154753, + "99.99" : 0.1775555122154753, + "99.999" : 0.1775555122154753, + "99.9999" : 0.1775555122154753, + "100.0" : 0.1775555122154753 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1775555122154753, + 0.177433827430802, + 0.17716569377269908 + ], + [ + 0.17594032069529725, + 0.17599118017352128, + 0.1759734131766031 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33612278077529556, + "scoreError" : 0.05777838840566512, + "scoreConfidence" : [ + 0.27834439236963043, + 0.3939011691809607 + ], + "scorePercentiles" : { + "0.0" : 0.3171062451484018, + "50.0" : 0.33615472011963227, + "90.0" : 0.3552267063796533, + "95.0" : 0.3552267063796533, + "99.0" : 0.3552267063796533, + "99.9" : 0.3552267063796533, + "99.99" : 0.3552267063796533, + "99.999" : 0.3552267063796533, + "99.9999" : 0.3552267063796533, + "100.0" : 0.3552267063796533 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3548310689067878, + 0.3547345274733071, + 0.3552267063796533 + ], + [ + 0.3171062451484018, + 0.3172632239776657, + 0.31757491276595745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.146627079100471, + "scoreError" : 0.004652605002919793, + "scoreConfidence" : [ + 0.1419744740975512, + 0.15127968410339077 + ], + "scorePercentiles" : { + "0.0" : 0.14507447051399225, + "50.0" : 0.14664949006854702, + "90.0" : 0.14815177062222223, + "95.0" : 0.14815177062222223, + "99.0" : 0.14815177062222223, + "99.9" : 0.14815177062222223, + "99.99" : 0.14815177062222223, + "99.999" : 0.14815177062222223, + "99.9999" : 0.14815177062222223, + "100.0" : 0.14815177062222223 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14815177062222223, + 0.14813567558919816, + 0.14813688258995364 + ], + [ + 0.14510037073956383, + 0.1451633045478959, + 0.14507447051399225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.38661649948233273, + "scoreError" : 0.00959993198780478, + "scoreConfidence" : [ + 0.37701656749452794, + 0.3962164314701375 + ], + "scorePercentiles" : { + "0.0" : 0.38158553096500936, + "50.0" : 0.3871190149001623, + "90.0" : 0.3912356432846915, + "95.0" : 0.3912356432846915, + "99.0" : 0.3912356432846915, + "99.9" : 0.3912356432846915, + "99.99" : 0.3912356432846915, + "99.999" : 0.3912356432846915, + "99.9999" : 0.3912356432846915, + "100.0" : 0.3912356432846915 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3912356432846915, + 0.3884361934356186, + 0.3881945970653313 + ], + [ + 0.38604343273499325, + 0.38420359940835225, + 0.38158553096500936 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15931797368969283, + "scoreError" : 0.005880832666933082, + "scoreConfidence" : [ + 0.15343714102275974, + 0.16519880635662593 + ], + "scorePercentiles" : { + "0.0" : 0.1567474975547823, + "50.0" : 0.1600643076444174, + "90.0" : 0.1611456797138115, + "95.0" : 0.1611456797138115, + "99.0" : 0.1611456797138115, + "99.9" : 0.1611456797138115, + "99.99" : 0.1611456797138115, + "99.999" : 0.1611456797138115, + "99.9999" : 0.1611456797138115, + "100.0" : 0.1611456797138115 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1610017718352036, + 0.1611456797138115, + 0.1610513056383167 + ], + [ + 0.1591268434536312, + 0.1567474975547823, + 0.15683474394241173 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046565999959954085, + "scoreError" : 0.0021620359483256217, + "scoreConfidence" : [ + 0.044403964011628466, + 0.048728035908279704 + ], + "scorePercentiles" : { + "0.0" : 0.04583468100962971, + "50.0" : 0.04657359427018569, + "90.0" : 0.047279804116985166, + "95.0" : 0.047279804116985166, + "99.0" : 0.047279804116985166, + "99.9" : 0.047279804116985166, + "99.99" : 0.047279804116985166, + "99.999" : 0.047279804116985166, + "99.9999" : 0.047279804116985166, + "100.0" : 0.047279804116985166 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045861781251003216, + 0.04583468100962971, + 0.04589071867542861 + ], + [ + 0.04725646986494277, + 0.047279804116985166, + 0.04727254484173505 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8696717.03819724, + "scoreError" : 257580.01769427664, + "scoreConfidence" : [ + 8439137.020502964, + 8954297.055891516 + ], + "scorePercentiles" : { + "0.0" : 8600041.92261393, + "50.0" : 8703776.798315138, + "90.0" : 8809895.697183099, + "95.0" : 8809895.697183099, + "99.0" : 8809895.697183099, + "99.9" : 8809895.697183099, + "99.99" : 8809895.697183099, + "99.999" : 8809895.697183099, + "99.9999" : 8809895.697183099, + "100.0" : 8809895.697183099 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8646530.043215211, + 8600041.92261393, + 8601066.40154772 + ], + [ + 8761023.553415062, + 8809895.697183099, + 8761744.611208407 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-14T22:47:23Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json b/performance-results/2025-09-14T22:47:23Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json new file mode 100644 index 0000000000..b8ba221844 --- /dev/null +++ b/performance-results/2025-09-14T22:47:23Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3474405498837054, + "scoreError" : 0.02049456819412791, + "scoreConfidence" : [ + 3.3269459816895774, + 3.3679351180778334 + ], + "scorePercentiles" : { + "0.0" : 3.344873934123505, + "50.0" : 3.346410113714337, + "90.0" : 3.352068037982643, + "95.0" : 3.352068037982643, + "99.0" : 3.352068037982643, + "99.9" : 3.352068037982643, + "99.99" : 3.352068037982643, + "99.999" : 3.352068037982643, + "99.9999" : 3.352068037982643, + "100.0" : 3.352068037982643 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3465706808657867, + 3.352068037982643 + ], + [ + 3.344873934123505, + 3.3462495465628876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6867427603288274, + "scoreError" : 0.07816500882220505, + "scoreConfidence" : [ + 1.6085777515066224, + 1.7649077691510324 + ], + "scorePercentiles" : { + "0.0" : 1.6746762052419504, + "50.0" : 1.6874863994086438, + "90.0" : 1.6973220372560718, + "95.0" : 1.6973220372560718, + "99.0" : 1.6973220372560718, + "99.9" : 1.6973220372560718, + "99.99" : 1.6973220372560718, + "99.999" : 1.6973220372560718, + "99.9999" : 1.6973220372560718, + "100.0" : 1.6973220372560718 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.696981651536924, + 1.6973220372560718 + ], + [ + 1.6746762052419504, + 1.6779911472803635 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8479622938605308, + "scoreError" : 0.03733457450798919, + "scoreConfidence" : [ + 0.8106277193525416, + 0.88529686836852 + ], + "scorePercentiles" : { + "0.0" : 0.8409735553462205, + "50.0" : 0.8485556848345444, + "90.0" : 0.853764250426814, + "95.0" : 0.853764250426814, + "99.0" : 0.853764250426814, + "99.9" : 0.853764250426814, + "99.99" : 0.853764250426814, + "99.999" : 0.853764250426814, + "99.9999" : 0.853764250426814, + "100.0" : 0.853764250426814 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8409735553462205, + 0.845646093771146 + ], + [ + 0.8514652758979429, + 0.853764250426814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.385918953391172, + "scoreError" : 0.6768746481881669, + "scoreConfidence" : [ + 15.709044305203005, + 17.06279360157934 + ], + "scorePercentiles" : { + "0.0" : 16.13967507103234, + "50.0" : 16.387768183131147, + "90.0" : 16.61649880410918, + "95.0" : 16.61649880410918, + "99.0" : 16.61649880410918, + "99.9" : 16.61649880410918, + "99.99" : 16.61649880410918, + "99.999" : 16.61649880410918, + "99.9999" : 16.61649880410918, + "100.0" : 16.61649880410918 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.61649880410918, + 16.59003216554371, + 16.610555105602913 + ], + [ + 16.17324837334032, + 16.185504200718583, + 16.13967507103234 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2649.3399046042123, + "scoreError" : 191.6605371467069, + "scoreConfidence" : [ + 2457.6793674575056, + 2841.000441750919 + ], + "scorePercentiles" : { + "0.0" : 2583.5510890864216, + "50.0" : 2649.1502811413757, + "90.0" : 2714.839753466136, + "95.0" : 2714.839753466136, + "99.0" : 2714.839753466136, + "99.9" : 2714.839753466136, + "99.99" : 2714.839753466136, + "99.999" : 2714.839753466136, + "99.9999" : 2714.839753466136, + "100.0" : 2714.839753466136 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2709.355424486396, + 2710.8672672112907, + 2714.839753466136 + ], + [ + 2588.9451377963555, + 2588.480755578674, + 2583.5510890864216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77542.9436330187, + "scoreError" : 1265.427147537831, + "scoreConfidence" : [ + 76277.51648548087, + 78808.37078055654 + ], + "scorePercentiles" : { + "0.0" : 77116.80534582536, + "50.0" : 77550.68546675013, + "90.0" : 77971.96881691243, + "95.0" : 77971.96881691243, + "99.0" : 77971.96881691243, + "99.9" : 77971.96881691243, + "99.99" : 77971.96881691243, + "99.999" : 77971.96881691243, + "99.9999" : 77971.96881691243, + "100.0" : 77971.96881691243 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77948.97273313592, + 77942.75864577311, + 77971.96881691243 + ], + [ + 77118.54396873823, + 77158.61228772716, + 77116.80534582536 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.15469345250966, + "scoreError" : 9.151755033279596, + "scoreConfidence" : [ + 348.0029384192301, + 366.30644848578925 + ], + "scorePercentiles" : { + "0.0" : 352.9391611238716, + "50.0" : 357.29837892405817, + "90.0" : 360.4220029485363, + "95.0" : 360.4220029485363, + "99.0" : 360.4220029485363, + "99.9" : 360.4220029485363, + "99.99" : 360.4220029485363, + "99.999" : 360.4220029485363, + "99.9999" : 360.4220029485363, + "100.0" : 360.4220029485363 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 352.9391611238716, + 354.60399437272196, + 355.3048751140479 + ], + [ + 359.2918827340685, + 360.4220029485363, + 360.36624442181176 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.10123056031051, + "scoreError" : 3.3496344250937127, + "scoreConfidence" : [ + 111.7515961352168, + 118.45086498540422 + ], + "scorePercentiles" : { + "0.0" : 113.70208446075848, + "50.0" : 115.15709792215264, + "90.0" : 116.20581673107682, + "95.0" : 116.20581673107682, + "99.0" : 116.20581673107682, + "99.9" : 116.20581673107682, + "99.99" : 116.20581673107682, + "99.999" : 116.20581673107682, + "99.9999" : 116.20581673107682, + "100.0" : 116.20581673107682 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.70208446075848, + 114.18555715987274, + 114.18124925800997 + ], + [ + 116.20403706771256, + 116.20581673107682, + 116.12863868443254 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061739402860730715, + "scoreError" : 0.0032912650238799547, + "scoreConfidence" : [ + 0.05844813783685076, + 0.06503066788461066 + ], + "scorePercentiles" : { + "0.0" : 0.0606476519740433, + "50.0" : 0.06174847929605563, + "90.0" : 0.06281967501319195, + "95.0" : 0.06281967501319195, + "99.0" : 0.06281967501319195, + "99.9" : 0.06281967501319195, + "99.99" : 0.06281967501319195, + "99.999" : 0.06281967501319195, + "99.9999" : 0.06281967501319195, + "100.0" : 0.06281967501319195 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060694221876270764, + 0.0606476519740433, + 0.060662331964403786 + ], + [ + 0.06281967501319195, + 0.06280273671584051, + 0.06280979962063399 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6427847345060207E-4, + "scoreError" : 1.920260108690281E-6, + "scoreConfidence" : [ + 3.623582133419118E-4, + 3.6619873355929234E-4 + ], + "scorePercentiles" : { + "0.0" : 3.636424398989318E-4, + "50.0" : 3.642023151705085E-4, + "90.0" : 3.6515286245821746E-4, + "95.0" : 3.6515286245821746E-4, + "99.0" : 3.6515286245821746E-4, + "99.9" : 3.6515286245821746E-4, + "99.99" : 3.6515286245821746E-4, + "99.999" : 3.6515286245821746E-4, + "99.9999" : 3.6515286245821746E-4, + "100.0" : 3.6515286245821746E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.636424398989318E-4, + 3.63656622975963E-4, + 3.637072629142328E-4 + ], + [ + 3.648142850294833E-4, + 3.6515286245821746E-4, + 3.6469736742678424E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12556165314184428, + "scoreError" : 0.004791183118854291, + "scoreConfidence" : [ + 0.12077047002298999, + 0.13035283626069857 + ], + "scorePercentiles" : { + "0.0" : 0.12398997256146703, + "50.0" : 0.1253580892943923, + "90.0" : 0.12736351574818192, + "95.0" : 0.12736351574818192, + "99.0" : 0.12736351574818192, + "99.9" : 0.12736351574818192, + "99.99" : 0.12736351574818192, + "99.999" : 0.12736351574818192, + "99.9999" : 0.12736351574818192, + "100.0" : 0.12736351574818192 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12736351574818192, + 0.12729717427887674, + 0.1266533319148397 + ], + [ + 0.12400307767375535, + 0.12406284667394486, + 0.12398997256146703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013124672483431956, + "scoreError" : 8.229442897217138E-4, + "scoreConfidence" : [ + 0.012301728193710242, + 0.01394761677315367 + ], + "scorePercentiles" : { + "0.0" : 0.012843957393329197, + "50.0" : 0.013127712471558133, + "90.0" : 0.01339710950258494, + "95.0" : 0.01339710950258494, + "99.0" : 0.01339710950258494, + "99.9" : 0.01339710950258494, + "99.99" : 0.01339710950258494, + "99.999" : 0.01339710950258494, + "99.9999" : 0.01339710950258494, + "100.0" : 0.01339710950258494 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013389179756641612, + 0.013391147419630866, + 0.01339710950258494 + ], + [ + 0.012866245186474654, + 0.012860395641930472, + 0.012843957393329197 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.1127654524199293, + "scoreError" : 0.30953560956906634, + "scoreConfidence" : [ + 0.803229842850863, + 1.4223010619889958 + ], + "scorePercentiles" : { + "0.0" : 1.0117412898330804, + "50.0" : 1.1126156027974217, + "90.0" : 1.214143011776132, + "95.0" : 1.214143011776132, + "99.0" : 1.214143011776132, + "99.9" : 1.214143011776132, + "99.99" : 1.214143011776132, + "99.999" : 1.214143011776132, + "99.9999" : 1.214143011776132, + "100.0" : 1.214143011776132 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0121661803643724, + 1.0117412898330804, + 1.0120933285092601 + ], + [ + 1.2130650252304707, + 1.2133838788062599, + 1.214143011776132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010382426583996572, + "scoreError" : 2.747821771391445E-4, + "scoreConfidence" : [ + 0.010107644406857427, + 0.010657208761135717 + ], + "scorePercentiles" : { + "0.0" : 0.010289354760645577, + "50.0" : 0.010382759616797806, + "90.0" : 0.010476854994269334, + "95.0" : 0.010476854994269334, + "99.0" : 0.010476854994269334, + "99.9" : 0.010476854994269334, + "99.99" : 0.010476854994269334, + "99.999" : 0.010476854994269334, + "99.9999" : 0.010476854994269334, + "100.0" : 0.010476854994269334 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010289354760645577, + 0.010293379446355527, + 0.01029636457087082 + ], + [ + 0.010469451069113386, + 0.010469154662724793, + 0.010476854994269334 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1575941438198583, + "scoreError" : 0.4756481335322761, + "scoreConfidence" : [ + 2.6819460102875823, + 3.6332422773521342 + ], + "scorePercentiles" : { + "0.0" : 2.992346564931179, + "50.0" : 3.1607512185539957, + "90.0" : 3.3186850484406105, + "95.0" : 3.3186850484406105, + "99.0" : 3.3186850484406105, + "99.9" : 3.3186850484406105, + "99.99" : 3.3186850484406105, + "99.999" : 3.3186850484406105, + "99.9999" : 3.3186850484406105, + "100.0" : 3.3186850484406105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3054900118968935, + 3.3186850484406105, + 3.3125249894039737 + ], + [ + 2.992346564931179, + 3.016012425211098, + 3.0005058230353927 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8762953283435664, + "scoreError" : 0.19598277351224572, + "scoreConfidence" : [ + 2.6803125548313207, + 3.072278101855812 + ], + "scorePercentiles" : { + "0.0" : 2.809718504494382, + "50.0" : 2.875434964702202, + "90.0" : 2.949641361545267, + "95.0" : 2.949641361545267, + "99.0" : 2.949641361545267, + "99.9" : 2.949641361545267, + "99.99" : 2.949641361545267, + "99.999" : 2.949641361545267, + "99.9999" : 2.949641361545267, + "100.0" : 2.949641361545267 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.932312726473175, + 2.937513165345081, + 2.949641361545267 + ], + [ + 2.809718504494382, + 2.8100290092722675, + 2.818557202931229 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17797104068336722, + "scoreError" : 4.791070612877759E-4, + "scoreConfidence" : [ + 0.17749193362207943, + 0.178450147744655 + ], + "scorePercentiles" : { + "0.0" : 0.1776892362159953, + "50.0" : 0.17799680716173055, + "90.0" : 0.17818693036598837, + "95.0" : 0.17818693036598837, + "99.0" : 0.17818693036598837, + "99.9" : 0.17818693036598837, + "99.99" : 0.17818693036598837, + "99.999" : 0.17818693036598837, + "99.9999" : 0.17818693036598837, + "100.0" : 0.17818693036598837 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17806755279558403, + 0.17803248537501556, + 0.17818693036598837 + ], + [ + 0.17796112894844554, + 0.1776892362159953, + 0.17788891039917462 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3313144358611144, + "scoreError" : 0.02853629542341832, + "scoreConfidence" : [ + 0.3027781404376961, + 0.35985073128453277 + ], + "scorePercentiles" : { + "0.0" : 0.32185817183778564, + "50.0" : 0.3313736231112013, + "90.0" : 0.3407528401594657, + "95.0" : 0.3407528401594657, + "99.0" : 0.3407528401594657, + "99.9" : 0.3407528401594657, + "99.99" : 0.3407528401594657, + "99.999" : 0.3407528401594657, + "99.9999" : 0.3407528401594657, + "100.0" : 0.3407528401594657 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3219447537183697, + 0.32185817183778564, + 0.3222750681276184 + ], + [ + 0.3407528401594657, + 0.3405836032286629, + 0.34047217809478414 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14817834830922508, + "scoreError" : 0.008806819621003915, + "scoreConfidence" : [ + 0.13937152868822117, + 0.15698516793022899 + ], + "scorePercentiles" : { + "0.0" : 0.14529086439052738, + "50.0" : 0.14814149600295776, + "90.0" : 0.15119116332794097, + "95.0" : 0.15119116332794097, + "99.0" : 0.15119116332794097, + "99.9" : 0.15119116332794097, + "99.99" : 0.15119116332794097, + "99.999" : 0.15119116332794097, + "99.9999" : 0.15119116332794097, + "100.0" : 0.15119116332794097 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14531154353385645, + 0.14529086439052738, + 0.1453347535606325 + ], + [ + 0.15094823844528302, + 0.15119116332794097, + 0.15099352659711002 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40384706217063404, + "scoreError" : 0.021240362330965427, + "scoreConfidence" : [ + 0.3826066998396686, + 0.4250874245015995 + ], + "scorePercentiles" : { + "0.0" : 0.3946689730049728, + "50.0" : 0.40364517733120114, + "90.0" : 0.4122678249165189, + "95.0" : 0.4122678249165189, + "99.0" : 0.4122678249165189, + "99.9" : 0.4122678249165189, + "99.99" : 0.4122678249165189, + "99.999" : 0.4122678249165189, + "99.9999" : 0.4122678249165189, + "100.0" : 0.4122678249165189 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4122678249165189, + 0.4089156879293425, + 0.4105679637886439 + ], + [ + 0.3982872566512665, + 0.39837466673305977, + 0.3946689730049728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15524410337993863, + "scoreError" : 0.004295075235315681, + "scoreConfidence" : [ + 0.15094902814462294, + 0.15953917861525432 + ], + "scorePercentiles" : { + "0.0" : 0.15423349595915975, + "50.0" : 0.1547455508157778, + "90.0" : 0.1582567995727172, + "95.0" : 0.1582567995727172, + "99.0" : 0.1582567995727172, + "99.9" : 0.1582567995727172, + "99.99" : 0.1582567995727172, + "99.999" : 0.1582567995727172, + "99.9999" : 0.1582567995727172, + "100.0" : 0.1582567995727172 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15447859885687804, + 0.15423349595915975, + 0.1542478030447927 + ], + [ + 0.1582567995727172, + 0.1552354200714064, + 0.15501250277467757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04733081693723046, + "scoreError" : 5.555131646058355E-4, + "scoreConfidence" : [ + 0.04677530377262462, + 0.047886330101836294 + ], + "scorePercentiles" : { + "0.0" : 0.04719527595580705, + "50.0" : 0.047264985724402866, + "90.0" : 0.04772605865929786, + "95.0" : 0.04772605865929786, + "99.0" : 0.04772605865929786, + "99.9" : 0.04772605865929786, + "99.99" : 0.04772605865929786, + "99.999" : 0.04772605865929786, + "99.9999" : 0.04772605865929786, + "100.0" : 0.04772605865929786 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04731551202271114, + 0.047261610640339145, + 0.04726836080846659 + ], + [ + 0.04772605865929786, + 0.04719527595580705, + 0.04721808353676099 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8776000.174534973, + "scoreError" : 311197.49216569605, + "scoreConfidence" : [ + 8464802.682369277, + 9087197.666700669 + ], + "scorePercentiles" : { + "0.0" : 8614237.921619294, + "50.0" : 8812711.224438813, + "90.0" : 8870279.72251773, + "95.0" : 8870279.72251773, + "99.0" : 8870279.72251773, + "99.9" : 8870279.72251773, + "99.99" : 8870279.72251773, + "99.999" : 8870279.72251773, + "99.9999" : 8870279.72251773, + "100.0" : 8870279.72251773 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8763227.555166375, + 8675787.426712923, + 8614237.921619294 + ], + [ + 8862194.893711248, + 8870273.52748227, + 8870279.72251773 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-14T22:48:27Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json b/performance-results/2025-09-14T22:48:27Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json new file mode 100644 index 0000000000..9dc30429cf --- /dev/null +++ b/performance-results/2025-09-14T22:48:27Z-c40f35c220adec9c5882adbec74421041f7787c2-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3445829539226324, + "scoreError" : 0.0475064086518884, + "scoreConfidence" : [ + 3.297076545270744, + 3.392089362574521 + ], + "scorePercentiles" : { + "0.0" : 3.3379063645354465, + "50.0" : 3.344066233319009, + "90.0" : 3.352292984517065, + "95.0" : 3.352292984517065, + "99.0" : 3.352292984517065, + "99.9" : 3.352292984517065, + "99.99" : 3.352292984517065, + "99.999" : 3.352292984517065, + "99.9999" : 3.352292984517065, + "100.0" : 3.352292984517065 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3379063645354465, + 3.352292984517065 + ], + [ + 3.338700336020903, + 3.349432130617116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.682346879548956, + "scoreError" : 0.05210560826619359, + "scoreConfidence" : [ + 1.6302412712827623, + 1.7344524878151497 + ], + "scorePercentiles" : { + "0.0" : 1.673744106584672, + "50.0" : 1.6822448975420858, + "90.0" : 1.6911536165269803, + "95.0" : 1.6911536165269803, + "99.0" : 1.6911536165269803, + "99.9" : 1.6911536165269803, + "99.99" : 1.6911536165269803, + "99.999" : 1.6911536165269803, + "99.9999" : 1.6911536165269803, + "100.0" : 1.6911536165269803 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.673744106584672, + 1.6775829148054577 + ], + [ + 1.6869068802787137, + 1.6911536165269803 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8462664964426411, + "scoreError" : 0.025786842406286193, + "scoreConfidence" : [ + 0.8204796540363549, + 0.8720533388489272 + ], + "scorePercentiles" : { + "0.0" : 0.8416231124555156, + "50.0" : 0.8467604163676514, + "90.0" : 0.8499220405797462, + "95.0" : 0.8499220405797462, + "99.0" : 0.8499220405797462, + "99.9" : 0.8499220405797462, + "99.99" : 0.8499220405797462, + "99.999" : 0.8499220405797462, + "99.9999" : 0.8499220405797462, + "100.0" : 0.8499220405797462 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8442743195751514, + 0.8499220405797462 + ], + [ + 0.8416231124555156, + 0.8492465131601513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.18860002159096, + "scoreError" : 0.40119077412789583, + "scoreConfidence" : [ + 15.787409247463065, + 16.58979079571886 + ], + "scorePercentiles" : { + "0.0" : 16.051038809047864, + "50.0" : 16.18511616632528, + "90.0" : 16.33884000003908, + "95.0" : 16.33884000003908, + "99.0" : 16.33884000003908, + "99.9" : 16.33884000003908, + "99.99" : 16.33884000003908, + "99.999" : 16.33884000003908, + "99.9999" : 16.33884000003908, + "100.0" : 16.33884000003908 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.33884000003908, + 16.313861118688525, + 16.303394463106002 + ], + [ + 16.057627869119724, + 16.066837869544557, + 16.051038809047864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2751.8294437657137, + "scoreError" : 51.69742739432418, + "scoreConfidence" : [ + 2700.1320163713895, + 2803.526871160038 + ], + "scorePercentiles" : { + "0.0" : 2732.557345277224, + "50.0" : 2750.567363754922, + "90.0" : 2777.153039119587, + "95.0" : 2777.153039119587, + "99.0" : 2777.153039119587, + "99.9" : 2777.153039119587, + "99.99" : 2777.153039119587, + "99.999" : 2777.153039119587, + "99.9999" : 2777.153039119587, + "100.0" : 2777.153039119587 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2777.153039119587, + 2764.4558551227037, + 2762.037758759128 + ], + [ + 2735.675695564923, + 2732.557345277224, + 2739.0969687507163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75802.17010332175, + "scoreError" : 2250.7785092723634, + "scoreConfidence" : [ + 73551.39159404939, + 78052.94861259412 + ], + "scorePercentiles" : { + "0.0" : 75004.89946811108, + "50.0" : 75787.07534752195, + "90.0" : 76636.4859843357, + "95.0" : 76636.4859843357, + "99.0" : 76636.4859843357, + "99.9" : 76636.4859843357, + "99.99" : 76636.4859843357, + "99.999" : 76636.4859843357, + "99.9999" : 76636.4859843357, + "100.0" : 76636.4859843357 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75142.82062604737, + 75004.89946811108, + 75071.10959213317 + ], + [ + 76526.37488030671, + 76431.33006899655, + 76636.4859843357 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.4014412227016, + "scoreError" : 7.8124485433768704, + "scoreConfidence" : [ + 354.5889926793247, + 370.21388976607847 + ], + "scorePercentiles" : { + "0.0" : 359.03766625003425, + "50.0" : 362.0666161029553, + "90.0" : 365.8538307465605, + "95.0" : 365.8538307465605, + "99.0" : 365.8538307465605, + "99.9" : 365.8538307465605, + "99.99" : 365.8538307465605, + "99.999" : 365.8538307465605, + "99.9999" : 365.8538307465605, + "100.0" : 365.8538307465605 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.4000064055428, + 359.03766625003425, + 360.53760698415454 + ], + [ + 363.5956252217561, + 364.9839117281614, + 365.8538307465605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.8994158095233, + "scoreError" : 2.017710986201069, + "scoreConfidence" : [ + 113.88170482332224, + 117.91712679572437 + ], + "scorePercentiles" : { + "0.0" : 114.97121426618205, + "50.0" : 115.93330490624551, + "90.0" : 116.68807883080883, + "95.0" : 116.68807883080883, + "99.0" : 116.68807883080883, + "99.9" : 116.68807883080883, + "99.99" : 116.68807883080883, + "99.999" : 116.68807883080883, + "99.9999" : 116.68807883080883, + "100.0" : 116.68807883080883 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.47086300619593, + 115.35541230693576, + 114.97121426618205 + ], + [ + 116.51517964072221, + 116.3957468062951, + 116.68807883080883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06185252080196014, + "scoreError" : 4.4601294590707464E-4, + "scoreConfidence" : [ + 0.06140650785605306, + 0.062298533747867216 + ], + "scorePercentiles" : { + "0.0" : 0.061693308461087636, + "50.0" : 0.0618123711726776, + "90.0" : 0.06213660430103518, + "95.0" : 0.06213660430103518, + "99.0" : 0.06213660430103518, + "99.9" : 0.06213660430103518, + "99.99" : 0.06213660430103518, + "99.999" : 0.06213660430103518, + "99.9999" : 0.06213660430103518, + "100.0" : 0.06213660430103518 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0618161336687828, + 0.06180860867657239, + 0.06213660430103518 + ], + [ + 0.06174026018855227, + 0.06192020951573055, + 0.061693308461087636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.759135894521184E-4, + "scoreError" : 1.5743509109830077E-5, + "scoreConfidence" : [ + 3.6017008034228837E-4, + 3.916570985619485E-4 + ], + "scorePercentiles" : { + "0.0" : 3.696405728460527E-4, + "50.0" : 3.7562682510339056E-4, + "90.0" : 3.8175506812813454E-4, + "95.0" : 3.8175506812813454E-4, + "99.0" : 3.8175506812813454E-4, + "99.9" : 3.8175506812813454E-4, + "99.99" : 3.8175506812813454E-4, + "99.999" : 3.8175506812813454E-4, + "99.9999" : 3.8175506812813454E-4, + "100.0" : 3.8175506812813454E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8175506812813454E-4, + 3.81483566609206E-4, + 3.7963306781154304E-4 + ], + [ + 3.7134867892253584E-4, + 3.7162058239523807E-4, + 3.696405728460527E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1244767231375127, + "scoreError" : 0.0010234718313357042, + "scoreConfidence" : [ + 0.12345325130617699, + 0.1255001949688484 + ], + "scorePercentiles" : { + "0.0" : 0.12407943592034246, + "50.0" : 0.12439548191921468, + "90.0" : 0.12512003685955583, + "95.0" : 0.12512003685955583, + "99.0" : 0.12512003685955583, + "99.9" : 0.12512003685955583, + "99.99" : 0.12512003685955583, + "99.999" : 0.12512003685955583, + "99.9999" : 0.12512003685955583, + "100.0" : 0.12512003685955583 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1246277615308882, + 0.12512003685955583, + 0.1244362263202429 + ], + [ + 0.12435473751818646, + 0.12424214067586035, + 0.12407943592034246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012918754158222598, + "scoreError" : 1.9216849699697373E-4, + "scoreConfidence" : [ + 0.012726585661225623, + 0.013110922655219572 + ], + "scorePercentiles" : { + "0.0" : 0.012846908403958341, + "50.0" : 0.012923554916325573, + "90.0" : 0.012987892022681757, + "95.0" : 0.012987892022681757, + "99.0" : 0.012987892022681757, + "99.9" : 0.012987892022681757, + "99.99" : 0.012987892022681757, + "99.999" : 0.012987892022681757, + "99.9999" : 0.012987892022681757, + "100.0" : 0.012987892022681757 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012846908403958341, + 0.012876031766040427, + 0.012848402183423506 + ], + [ + 0.01297107806661072, + 0.012982212506620832, + 0.012987892022681757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9881898448487646, + "scoreError" : 0.044491361325412426, + "scoreConfidence" : [ + 0.9436984835233522, + 1.032681206174177 + ], + "scorePercentiles" : { + "0.0" : 0.9745524231144026, + "50.0" : 0.985950733378903, + "90.0" : 1.0181516198330278, + "95.0" : 1.0181516198330278, + "99.0" : 1.0181516198330278, + "99.9" : 1.0181516198330278, + "99.99" : 1.0181516198330278, + "99.999" : 1.0181516198330278, + "99.9999" : 1.0181516198330278, + "100.0" : 1.0181516198330278 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9753838083487759, + 0.9745524231144026, + 1.0181516198330278 + ], + [ + 0.9891497510385757, + 0.9860667911860397, + 0.9858346755717665 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010865166961127062, + "scoreError" : 0.0010176653219832836, + "scoreConfidence" : [ + 0.00984750163914378, + 0.011882832283110345 + ], + "scorePercentiles" : { + "0.0" : 0.010513296655375643, + "50.0" : 0.01087118163508993, + "90.0" : 0.011223849923230944, + "95.0" : 0.011223849923230944, + "99.0" : 0.011223849923230944, + "99.9" : 0.011223849923230944, + "99.99" : 0.011223849923230944, + "99.999" : 0.011223849923230944, + "99.9999" : 0.011223849923230944, + "100.0" : 0.011223849923230944 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010527487762101571, + 0.010562723603770316, + 0.010513296655375643 + ], + [ + 0.011179639666409542, + 0.011223849923230944, + 0.011184004155874366 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.050876586696313, + "scoreError" : 0.1588846770175737, + "scoreConfidence" : [ + 2.8919919096787394, + 3.2097612637138866 + ], + "scorePercentiles" : { + "0.0" : 2.9755086139202858, + "50.0" : 3.066182332923821, + "90.0" : 3.1163936386292836, + "95.0" : 3.1163936386292836, + "99.0" : 3.1163936386292836, + "99.9" : 3.1163936386292836, + "99.99" : 3.1163936386292836, + "99.999" : 3.1163936386292836, + "99.9999" : 3.1163936386292836, + "100.0" : 3.1163936386292836 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1163936386292836, + 3.0842620345252776, + 3.0891844373069794 + ], + [ + 2.9755086139202858, + 2.9918081644736843, + 3.0481026313223643 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.809117279281304, + "scoreError" : 0.042254275925068745, + "scoreConfidence" : [ + 2.766863003356235, + 2.8513715552063728 + ], + "scorePercentiles" : { + "0.0" : 2.7865324728336582, + "50.0" : 2.809684095968277, + "90.0" : 2.8297224226308346, + "95.0" : 2.8297224226308346, + "99.0" : 2.8297224226308346, + "99.9" : 2.8297224226308346, + "99.99" : 2.8297224226308346, + "99.999" : 2.8297224226308346, + "99.9999" : 2.8297224226308346, + "100.0" : 2.8297224226308346 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8297224226308346, + 2.8169954523943663, + 2.803033496076233 + ], + [ + 2.8163346958603213, + 2.7865324728336582, + 2.802085135892407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18284134528603757, + "scoreError" : 0.00589992366450785, + "scoreConfidence" : [ + 0.17694142162152973, + 0.1887412689505454 + ], + "scorePercentiles" : { + "0.0" : 0.1805053696142669, + "50.0" : 0.18271549579786478, + "90.0" : 0.18550744065815836, + "95.0" : 0.18550744065815836, + "99.0" : 0.18550744065815836, + "99.9" : 0.18550744065815836, + "99.99" : 0.18550744065815836, + "99.999" : 0.18550744065815836, + "99.9999" : 0.18550744065815836, + "100.0" : 0.18550744065815836 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18441217550297823, + 0.18550744065815836, + 0.18419017904702265 + ], + [ + 0.1805053696142669, + 0.1812408125487069, + 0.1811920943450925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3330187080067945, + "scoreError" : 0.026755496232965335, + "scoreConfidence" : [ + 0.30626321177382915, + 0.35977420423975986 + ], + "scorePercentiles" : { + "0.0" : 0.32385127691958937, + "50.0" : 0.33309652585810995, + "90.0" : 0.34238378327855384, + "95.0" : 0.34238378327855384, + "99.0" : 0.34238378327855384, + "99.9" : 0.34238378327855384, + "99.99" : 0.34238378327855384, + "99.999" : 0.34238378327855384, + "99.9999" : 0.34238378327855384, + "100.0" : 0.34238378327855384 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32411795018474104, + 0.32385127691958937, + 0.3249990713682158 + ], + [ + 0.3411939803480041, + 0.34238378327855384, + 0.34156618594166266 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14712258756098864, + "scoreError" : 0.004402363977589694, + "scoreConfidence" : [ + 0.14272022358339895, + 0.15152495153857834 + ], + "scorePercentiles" : { + "0.0" : 0.14551320120771188, + "50.0" : 0.14702177265366578, + "90.0" : 0.14872335637483083, + "95.0" : 0.14872335637483083, + "99.0" : 0.14872335637483083, + "99.9" : 0.14872335637483083, + "99.99" : 0.14872335637483083, + "99.999" : 0.14872335637483083, + "99.9999" : 0.14872335637483083, + "100.0" : 0.14872335637483083 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14579247574061116, + 0.14551320120771188, + 0.14579529140849382 + ], + [ + 0.14872335637483083, + 0.14866294673544628, + 0.14824825389883775 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40713135288276714, + "scoreError" : 0.0230428067923725, + "scoreConfidence" : [ + 0.38408854609039467, + 0.4301741596751396 + ], + "scorePercentiles" : { + "0.0" : 0.3987698630672302, + "50.0" : 0.4071819657061959, + "90.0" : 0.41667952629166666, + "95.0" : 0.41667952629166666, + "99.0" : 0.41667952629166666, + "99.9" : 0.41667952629166666, + "99.99" : 0.41667952629166666, + "99.999" : 0.41667952629166666, + "99.9999" : 0.41667952629166666, + "100.0" : 0.41667952629166666 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4010143789798701, + 0.3994296309062587, + 0.3987698630672302 + ], + [ + 0.41667952629166666, + 0.4133495524325218, + 0.4135451656190555 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15625649217166274, + "scoreError" : 0.008028187589217955, + "scoreConfidence" : [ + 0.1482283045824448, + 0.16428467976088068 + ], + "scorePercentiles" : { + "0.0" : 0.15313626286694332, + "50.0" : 0.1563979669329519, + "90.0" : 0.158931304662916, + "95.0" : 0.158931304662916, + "99.0" : 0.158931304662916, + "99.9" : 0.158931304662916, + "99.99" : 0.158931304662916, + "99.999" : 0.158931304662916, + "99.9999" : 0.158931304662916, + "100.0" : 0.158931304662916 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15401446932898, + 0.15382018627330338, + 0.15313626286694332 + ], + [ + 0.15878146453692382, + 0.1588552653609099, + 0.158931304662916 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04663174023075053, + "scoreError" : 7.084817035513027E-4, + "scoreConfidence" : [ + 0.04592325852719922, + 0.04734022193430183 + ], + "scorePercentiles" : { + "0.0" : 0.046323295899980084, + "50.0" : 0.046634672695296545, + "90.0" : 0.04697201119795581, + "95.0" : 0.04697201119795581, + "99.0" : 0.04697201119795581, + "99.9" : 0.04697201119795581, + "99.99" : 0.04697201119795581, + "99.999" : 0.04697201119795581, + "99.9999" : 0.04697201119795581, + "100.0" : 0.04697201119795581 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04697201119795581, + 0.046799219723701574, + 0.04677265760696713 + ], + [ + 0.046323295899980084, + 0.04649668778362595, + 0.04642656917227259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8637409.986487865, + "scoreError" : 82164.12640197344, + "scoreConfidence" : [ + 8555245.860085892, + 8719574.11288984 + ], + "scorePercentiles" : { + "0.0" : 8614189.802756244, + "50.0" : 8628143.722651066, + "90.0" : 8695358.835794961, + "95.0" : 8695358.835794961, + "99.0" : 8695358.835794961, + "99.9" : 8695358.835794961, + "99.99" : 8695358.835794961, + "99.999" : 8695358.835794961, + "99.9999" : 8695358.835794961, + "100.0" : 8695358.835794961 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8614189.802756244, + 8629152.550474547, + 8636036.34283247 + ], + [ + 8695358.835794961, + 8622587.492241379, + 8627134.894827586 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-15T00:29:03Z-f14da69b1381550817e68fc860d04bc58d26a940-jdk17.json b/performance-results/2025-09-15T00:29:03Z-f14da69b1381550817e68fc860d04bc58d26a940-jdk17.json new file mode 100644 index 0000000000..85db869658 --- /dev/null +++ b/performance-results/2025-09-15T00:29:03Z-f14da69b1381550817e68fc860d04bc58d26a940-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.361211655548786, + "scoreError" : 0.039755618474119646, + "scoreConfidence" : [ + 3.3214560370746664, + 3.4009672740229053 + ], + "scorePercentiles" : { + "0.0" : 3.353749188798845, + "50.0" : 3.36177439365012, + "90.0" : 3.3675486460960586, + "95.0" : 3.3675486460960586, + "99.0" : 3.3675486460960586, + "99.9" : 3.3675486460960586, + "99.99" : 3.3675486460960586, + "99.999" : 3.3675486460960586, + "99.9999" : 3.3675486460960586, + "100.0" : 3.3675486460960586 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3646959040014544, + 3.3675486460960586 + ], + [ + 3.353749188798845, + 3.3588528832987863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6908946214326968, + "scoreError" : 0.07045248289042995, + "scoreConfidence" : [ + 1.6204421385422667, + 1.7613471043231268 + ], + "scorePercentiles" : { + "0.0" : 1.6817676622955364, + "50.0" : 1.6878360846720644, + "90.0" : 1.706138654091122, + "95.0" : 1.706138654091122, + "99.0" : 1.706138654091122, + "99.9" : 1.706138654091122, + "99.99" : 1.706138654091122, + "99.999" : 1.706138654091122, + "99.9999" : 1.706138654091122, + "100.0" : 1.706138654091122 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6817676622955364, + 1.6845037557177505 + ], + [ + 1.691168413626378, + 1.706138654091122 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.854258929227458, + "scoreError" : 0.02374186403598579, + "scoreConfidence" : [ + 0.8305170651914723, + 0.8780007932634438 + ], + "scorePercentiles" : { + "0.0" : 0.8501824982905118, + "50.0" : 0.8546302843349012, + "90.0" : 0.8575926499495183, + "95.0" : 0.8575926499495183, + "99.0" : 0.8575926499495183, + "99.9" : 0.8575926499495183, + "99.99" : 0.8575926499495183, + "99.999" : 0.8575926499495183, + "99.9999" : 0.8575926499495183, + "100.0" : 0.8575926499495183 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8501824982905118, + 0.8571292634808951 + ], + [ + 0.8521313051889071, + 0.8575926499495183 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.175530493987974, + "scoreError" : 0.3063647766894457, + "scoreConfidence" : [ + 15.869165717298529, + 16.48189527067742 + ], + "scorePercentiles" : { + "0.0" : 16.06613773797418, + "50.0" : 16.170907122110176, + "90.0" : 16.377641901465747, + "95.0" : 16.377641901465747, + "99.0" : 16.377641901465747, + "99.9" : 16.377641901465747, + "99.99" : 16.377641901465747, + "99.999" : 16.377641901465747, + "99.9999" : 16.377641901465747, + "100.0" : 16.377641901465747 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.09309487492117, + 16.16734102829794, + 16.06613773797418 + ], + [ + 16.17447321592241, + 16.17449420534638, + 16.377641901465747 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2766.0571286258632, + "scoreError" : 239.1946911343957, + "scoreConfidence" : [ + 2526.8624374914675, + 3005.251819760259 + ], + "scorePercentiles" : { + "0.0" : 2683.7764408597036, + "50.0" : 2768.942132510829, + "90.0" : 2844.515931399862, + "95.0" : 2844.515931399862, + "99.0" : 2844.515931399862, + "99.9" : 2844.515931399862, + "99.99" : 2844.515931399862, + "99.999" : 2844.515931399862, + "99.9999" : 2844.515931399862, + "100.0" : 2844.515931399862 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2844.515931399862, + 2842.597885975197, + 2844.4081242723605 + ], + [ + 2695.286379046461, + 2685.7580102015954, + 2683.7764408597036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77222.17128443792, + "scoreError" : 1843.1265658008306, + "scoreConfidence" : [ + 75379.04471863709, + 79065.29785023876 + ], + "scorePercentiles" : { + "0.0" : 76601.6696198021, + "50.0" : 77192.83028863273, + "90.0" : 77884.2781650968, + "95.0" : 77884.2781650968, + "99.0" : 77884.2781650968, + "99.9" : 77884.2781650968, + "99.99" : 77884.2781650968, + "99.999" : 77884.2781650968, + "99.9999" : 77884.2781650968, + "100.0" : 77884.2781650968 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77828.86083913625, + 77749.2555553755, + 77884.2781650968 + ], + [ + 76636.40502188996, + 76601.6696198021, + 76632.55850532698 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 371.25906358696596, + "scoreError" : 1.0414107134502435, + "scoreConfidence" : [ + 370.2176528735157, + 372.3004743004162 + ], + "scorePercentiles" : { + "0.0" : 370.8901389955185, + "50.0" : 371.17104962186244, + "90.0" : 371.9384487615729, + "95.0" : 371.9384487615729, + "99.0" : 371.9384487615729, + "99.9" : 371.9384487615729, + "99.99" : 371.9384487615729, + "99.999" : 371.9384487615729, + "99.9999" : 371.9384487615729, + "100.0" : 371.9384487615729 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 371.0455583404525, + 371.2819668719972, + 371.33813618052676 + ], + [ + 371.06013237172766, + 370.8901389955185, + 371.9384487615729 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.60935633051457, + "scoreError" : 2.0278757057264754, + "scoreConfidence" : [ + 114.5814806247881, + 118.63723203624104 + ], + "scorePercentiles" : { + "0.0" : 115.88398242324227, + "50.0" : 116.59283976162146, + "90.0" : 117.3857659898333, + "95.0" : 117.3857659898333, + "99.0" : 117.3857659898333, + "99.9" : 117.3857659898333, + "99.99" : 117.3857659898333, + "99.999" : 117.3857659898333, + "99.9999" : 117.3857659898333, + "100.0" : 117.3857659898333 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.16683434578616, + 117.24307406747634, + 117.3857659898333 + ], + [ + 116.01884517745678, + 115.9576359792925, + 115.88398242324227 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06033440223956187, + "scoreError" : 1.6115755471466926E-4, + "scoreConfidence" : [ + 0.0601732446848472, + 0.060495559794276545 + ], + "scorePercentiles" : { + "0.0" : 0.06024600925368099, + "50.0" : 0.06035304283862823, + "90.0" : 0.06040398988855667, + "95.0" : 0.06040398988855667, + "99.0" : 0.06040398988855667, + "99.9" : 0.06040398988855667, + "99.99" : 0.06040398988855667, + "99.999" : 0.06040398988855667, + "99.9999" : 0.06040398988855667, + "100.0" : 0.06040398988855667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060347620418927155, + 0.06028686281318575, + 0.06024600925368099 + ], + [ + 0.06040398988855667, + 0.06035846525832931, + 0.06036346580469137 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.557402257192811E-4, + "scoreError" : 1.619249833120728E-5, + "scoreConfidence" : [ + 3.395477273880738E-4, + 3.719327240504884E-4 + ], + "scorePercentiles" : { + "0.0" : 3.504143753042E-4, + "50.0" : 3.5562377856922586E-4, + "90.0" : 3.6164059112653464E-4, + "95.0" : 3.6164059112653464E-4, + "99.0" : 3.6164059112653464E-4, + "99.9" : 3.6164059112653464E-4, + "99.99" : 3.6164059112653464E-4, + "99.999" : 3.6164059112653464E-4, + "99.9999" : 3.6164059112653464E-4, + "100.0" : 3.6164059112653464E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.504143753042E-4, + 3.50606386174783E-4, + 3.5041647405665834E-4 + ], + [ + 3.6164059112653464E-4, + 3.606411709636687E-4, + 3.6072235668984184E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12389754274192781, + "scoreError" : 0.008762539698714027, + "scoreConfidence" : [ + 0.11513500304321378, + 0.13266008244064184 + ], + "scorePercentiles" : { + "0.0" : 0.1210098662979949, + "50.0" : 0.12373306274585338, + "90.0" : 0.1269922176844832, + "95.0" : 0.1269922176844832, + "99.0" : 0.1269922176844832, + "99.9" : 0.1269922176844832, + "99.99" : 0.1269922176844832, + "99.999" : 0.1269922176844832, + "99.9999" : 0.1269922176844832, + "100.0" : 0.1269922176844832 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1269922176844832, + 0.12688483139837337, + 0.12635205834786345 + ], + [ + 0.12111406714384333, + 0.1210098662979949, + 0.12103221557900852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013170666492886689, + "scoreError" : 4.8463679885879404E-4, + "scoreConfidence" : [ + 0.012686029694027896, + 0.013655303291745483 + ], + "scorePercentiles" : { + "0.0" : 0.012994495635213522, + "50.0" : 0.013170837154657465, + "90.0" : 0.01334003946064274, + "95.0" : 0.01334003946064274, + "99.0" : 0.01334003946064274, + "99.9" : 0.01334003946064274, + "99.99" : 0.01334003946064274, + "99.999" : 0.01334003946064274, + "99.9999" : 0.01334003946064274, + "100.0" : 0.01334003946064274 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01332690470980355, + 0.01334003946064274, + 0.013317083586354944 + ], + [ + 0.013020884842345393, + 0.012994495635213522, + 0.013024590722959984 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9550103456767943, + "scoreError" : 0.014770276557648869, + "scoreConfidence" : [ + 0.9402400691191455, + 0.9697806222344432 + ], + "scorePercentiles" : { + "0.0" : 0.9498669790083587, + "50.0" : 0.9548775180752445, + "90.0" : 0.9601006990207374, + "95.0" : 0.9601006990207374, + "99.0" : 0.9601006990207374, + "99.9" : 0.9601006990207374, + "99.99" : 0.9601006990207374, + "99.999" : 0.9601006990207374, + "99.9999" : 0.9601006990207374, + "100.0" : 0.9601006990207374 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9593393440767386, + 0.9599889342421043, + 0.9601006990207374 + ], + [ + 0.9504156920737502, + 0.9503504256390763, + 0.9498669790083587 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010276883334616748, + "scoreError" : 1.3838557173169086E-4, + "scoreConfidence" : [ + 0.010138497762885057, + 0.010415268906348439 + ], + "scorePercentiles" : { + "0.0" : 0.010227897543523752, + "50.0" : 0.010278554129907594, + "90.0" : 0.010330106932570852, + "95.0" : 0.010330106932570852, + "99.0" : 0.010330106932570852, + "99.9" : 0.010330106932570852, + "99.99" : 0.010330106932570852, + "99.999" : 0.010330106932570852, + "99.9999" : 0.010330106932570852, + "100.0" : 0.010330106932570852 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010317553095911668, + 0.010330106932570852, + 0.010317005240906306 + ], + [ + 0.010240103018908884, + 0.010228634175879027, + 0.010227897543523752 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0441863702978007, + "scoreError" : 0.060008323815863164, + "scoreConfidence" : [ + 2.9841780464819374, + 3.104194694113664 + ], + "scorePercentiles" : { + "0.0" : 3.021537490634441, + "50.0" : 3.0454819839155545, + "90.0" : 3.0659607817290007, + "95.0" : 3.0659607817290007, + "99.0" : 3.0659607817290007, + "99.9" : 3.0659607817290007, + "99.99" : 3.0659607817290007, + "99.999" : 3.0659607817290007, + "99.9999" : 3.0659607817290007, + "100.0" : 3.0659607817290007 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.024092145707376, + 3.021537490634441, + 3.0287825850999393 + ], + [ + 3.0625638358848746, + 3.0621813827311697, + 3.0659607817290007 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7630421063182613, + "scoreError" : 0.03211009247862952, + "scoreConfidence" : [ + 2.730932013839632, + 2.795152198796891 + ], + "scorePercentiles" : { + "0.0" : 2.748393306128057, + "50.0" : 2.761890290608072, + "90.0" : 2.7833273757305874, + "95.0" : 2.7833273757305874, + "99.0" : 2.7833273757305874, + "99.9" : 2.7833273757305874, + "99.99" : 2.7833273757305874, + "99.999" : 2.7833273757305874, + "99.9999" : 2.7833273757305874, + "100.0" : 2.7833273757305874 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7626691648715824, + 2.7582054809707666, + 2.748393306128057 + ], + [ + 2.764545893864013, + 2.761111416344561, + 2.7833273757305874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17707587524167934, + "scoreError" : 0.003824572557606421, + "scoreConfidence" : [ + 0.1732513026840729, + 0.18090044779928577 + ], + "scorePercentiles" : { + "0.0" : 0.17574228012582815, + "50.0" : 0.17710288455697243, + "90.0" : 0.17851226049625135, + "95.0" : 0.17851226049625135, + "99.0" : 0.17851226049625135, + "99.9" : 0.17851226049625135, + "99.99" : 0.17851226049625135, + "99.999" : 0.17851226049625135, + "99.9999" : 0.17851226049625135, + "100.0" : 0.17851226049625135 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.178176461844098, + 0.17825052051620263, + 0.17851226049625135 + ], + [ + 0.17602930726984686, + 0.17574228012582815, + 0.17574442119784894 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32297668345180247, + "scoreError" : 0.00294958917201125, + "scoreConfidence" : [ + 0.3200270942797912, + 0.32592627262381374 + ], + "scorePercentiles" : { + "0.0" : 0.3217872655018181, + "50.0" : 0.32306885366340743, + "90.0" : 0.3241549621069692, + "95.0" : 0.3241549621069692, + "99.0" : 0.3241549621069692, + "99.9" : 0.3241549621069692, + "99.99" : 0.3241549621069692, + "99.999" : 0.3241549621069692, + "99.9999" : 0.3241549621069692, + "100.0" : 0.3241549621069692 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32253758313175296, + 0.32185750848057676, + 0.3217872655018181 + ], + [ + 0.3241549621069692, + 0.32360012419506196, + 0.32392265729463593 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14401661219384138, + "scoreError" : 0.005720722706462169, + "scoreConfidence" : [ + 0.1382958894873792, + 0.14973733490030355 + ], + "scorePercentiles" : { + "0.0" : 0.14210896865141395, + "50.0" : 0.14400502076157506, + "90.0" : 0.14592225465847572, + "95.0" : 0.14592225465847572, + "99.0" : 0.14592225465847572, + "99.9" : 0.14592225465847572, + "99.99" : 0.14592225465847572, + "99.999" : 0.14592225465847572, + "99.9999" : 0.14592225465847572, + "100.0" : 0.14592225465847572 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14589499452906163, + 0.14592225465847572, + 0.1458182791776028 + ], + [ + 0.1421634138009468, + 0.14219176234554737, + 0.14210896865141395 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3949350798529321, + "scoreError" : 0.01019146701012959, + "scoreConfidence" : [ + 0.3847436128428025, + 0.40512654686306165 + ], + "scorePercentiles" : { + "0.0" : 0.39148704924835576, + "50.0" : 0.39465437781181467, + "90.0" : 0.3992593512995568, + "95.0" : 0.3992593512995568, + "99.0" : 0.3992593512995568, + "99.9" : 0.3992593512995568, + "99.99" : 0.3992593512995568, + "99.999" : 0.3992593512995568, + "99.9999" : 0.3992593512995568, + "100.0" : 0.3992593512995568 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39187713444884203, + 0.391629497630703, + 0.39148704924835576 + ], + [ + 0.3992593512995568, + 0.3979258253153476, + 0.39743162117478736 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16077439629795479, + "scoreError" : 0.02074282703688582, + "scoreConfidence" : [ + 0.14003156926106897, + 0.1815172233348406 + ], + "scorePercentiles" : { + "0.0" : 0.15369803495020287, + "50.0" : 0.16024782655186814, + "90.0" : 0.16998476908040117, + "95.0" : 0.16998476908040117, + "99.0" : 0.16998476908040117, + "99.9" : 0.16998476908040117, + "99.99" : 0.16998476908040117, + "99.999" : 0.16998476908040117, + "99.9999" : 0.16998476908040117, + "100.0" : 0.16998476908040117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16998476908040117, + 0.16588405485701016, + 0.16631697588437808 + ], + [ + 0.15415094476901023, + 0.15369803495020287, + 0.15461159824672613 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048212516395001036, + "scoreError" : 0.0027710056523221082, + "scoreConfidence" : [ + 0.04544151074267893, + 0.05098352204732314 + ], + "scorePercentiles" : { + "0.0" : 0.047261173309135936, + "50.0" : 0.048165574842213954, + "90.0" : 0.049325880386905205, + "95.0" : 0.049325880386905205, + "99.0" : 0.049325880386905205, + "99.9" : 0.049325880386905205, + "99.99" : 0.049325880386905205, + "99.999" : 0.049325880386905205, + "99.9999" : 0.049325880386905205, + "100.0" : 0.049325880386905205 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04733547965786397, + 0.047356309076185786, + 0.047261173309135936 + ], + [ + 0.04902141533167317, + 0.04897484060824212, + 0.049325880386905205 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8572364.241122572, + "scoreError" : 205536.76158843684, + "scoreConfidence" : [ + 8366827.479534135, + 8777901.00271101 + ], + "scorePercentiles" : { + "0.0" : 8500085.932030587, + "50.0" : 8572453.846048784, + "90.0" : 8644657.640449438, + "95.0" : 8644657.640449438, + "99.0" : 8644657.640449438, + "99.9" : 8644657.640449438, + "99.99" : 8644657.640449438, + "99.999" : 8644657.640449438, + "99.9999" : 8644657.640449438, + "100.0" : 8644657.640449438 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8509147.530612245, + 8507475.503401361, + 8500085.932030587 + ], + [ + 8644657.640449438, + 8635760.16148532, + 8637058.678756477 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-15T00:30:00Z-f14da69b1381550817e68fc860d04bc58d26a940-jdk17.json b/performance-results/2025-09-15T00:30:00Z-f14da69b1381550817e68fc860d04bc58d26a940-jdk17.json new file mode 100644 index 0000000000..50b75af609 --- /dev/null +++ b/performance-results/2025-09-15T00:30:00Z-f14da69b1381550817e68fc860d04bc58d26a940-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.344232590592511, + "scoreError" : 0.07320107736551677, + "scoreConfidence" : [ + 3.2710315132269945, + 3.417433667958028 + ], + "scorePercentiles" : { + "0.0" : 3.334166221784455, + "50.0" : 3.3426374330677193, + "90.0" : 3.3574892744501503, + "95.0" : 3.3574892744501503, + "99.0" : 3.3574892744501503, + "99.9" : 3.3574892744501503, + "99.99" : 3.3574892744501503, + "99.999" : 3.3574892744501503, + "99.9999" : 3.3574892744501503, + "100.0" : 3.3574892744501503 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3498070459515095, + 3.3574892744501503 + ], + [ + 3.334166221784455, + 3.335467820183929 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6922616586590529, + "scoreError" : 0.04239784834405045, + "scoreConfidence" : [ + 1.6498638103150025, + 1.7346595070031032 + ], + "scorePercentiles" : { + "0.0" : 1.683171211219564, + "50.0" : 1.693883622152578, + "90.0" : 1.6981081791114914, + "95.0" : 1.6981081791114914, + "99.0" : 1.6981081791114914, + "99.9" : 1.6981081791114914, + "99.99" : 1.6981081791114914, + "99.999" : 1.6981081791114914, + "99.9999" : 1.6981081791114914, + "100.0" : 1.6981081791114914 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.683171211219564, + 1.6981081791114914 + ], + [ + 1.6920041166193418, + 1.695763127685814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.855313839405497, + "scoreError" : 0.005973107856820491, + "scoreConfidence" : [ + 0.8493407315486765, + 0.8612869472623175 + ], + "scorePercentiles" : { + "0.0" : 0.854429164564699, + "50.0" : 0.8553314418046017, + "90.0" : 0.8561633094480855, + "95.0" : 0.8561633094480855, + "99.0" : 0.8561633094480855, + "99.9" : 0.8561633094480855, + "99.99" : 0.8561633094480855, + "99.999" : 0.8561633094480855, + "99.9999" : 0.8561633094480855, + "100.0" : 0.8561633094480855 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.854429164564699, + 0.8561633094480855 + ], + [ + 0.8546039898429291, + 0.8560588937662744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.465829243280737, + "scoreError" : 0.10117874756485866, + "scoreConfidence" : [ + 16.36465049571588, + 16.567007990845596 + ], + "scorePercentiles" : { + "0.0" : 16.427650161725282, + "50.0" : 16.463577425958185, + "90.0" : 16.512689471465585, + "95.0" : 16.512689471465585, + "99.0" : 16.512689471465585, + "99.9" : 16.512689471465585, + "99.99" : 16.512689471465585, + "99.999" : 16.512689471465585, + "99.9999" : 16.512689471465585, + "100.0" : 16.512689471465585 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.434334335698598, + 16.44004582045157, + 16.427650161725282 + ], + [ + 16.4871090314648, + 16.512689471465585, + 16.493146638878592 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2835.0833193886974, + "scoreError" : 83.1393013808791, + "scoreConfidence" : [ + 2751.944018007818, + 2918.2226207695767 + ], + "scorePercentiles" : { + "0.0" : 2805.908458354108, + "50.0" : 2834.867667528939, + "90.0" : 2866.573971195705, + "95.0" : 2866.573971195705, + "99.0" : 2866.573971195705, + "99.9" : 2866.573971195705, + "99.99" : 2866.573971195705, + "99.999" : 2866.573971195705, + "99.9999" : 2866.573971195705, + "100.0" : 2866.573971195705 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2805.908458354108, + 2807.51242504473, + 2811.0745081725436 + ], + [ + 2860.7697266797663, + 2866.573971195705, + 2858.6608268853342 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76953.29654489252, + "scoreError" : 2586.5916067103835, + "scoreConfidence" : [ + 74366.70493818214, + 79539.8881516029 + ], + "scorePercentiles" : { + "0.0" : 76078.530532321, + "50.0" : 76936.57869018981, + "90.0" : 77838.14979989908, + "95.0" : 77838.14979989908, + "99.0" : 77838.14979989908, + "99.9" : 77838.14979989908, + "99.99" : 77838.14979989908, + "99.999" : 77838.14979989908, + "99.9999" : 77838.14979989908, + "100.0" : 77838.14979989908 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77717.78729837261, + 77826.52598476523, + 77838.14979989908 + ], + [ + 76155.37008200701, + 76103.41557199015, + 76078.530532321 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 365.0365698677142, + "scoreError" : 2.321058535524212, + "scoreConfidence" : [ + 362.71551133219, + 367.35762840323844 + ], + "scorePercentiles" : { + "0.0" : 363.4458911206893, + "50.0" : 365.28163979799535, + "90.0" : 365.85938821764216, + "95.0" : 365.85938821764216, + "99.0" : 365.85938821764216, + "99.9" : 365.85938821764216, + "99.99" : 365.85938821764216, + "99.999" : 365.85938821764216, + "99.9999" : 365.85938821764216, + "100.0" : 365.85938821764216 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 365.34599557790244, + 365.3078833431128, + 365.85938821764216 + ], + [ + 365.0048646940603, + 363.4458911206893, + 365.255396252878 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.37218269799665, + "scoreError" : 1.188180728901576, + "scoreConfidence" : [ + 116.18400196909508, + 118.56036342689822 + ], + "scorePercentiles" : { + "0.0" : 116.91235231763682, + "50.0" : 117.3430986583922, + "90.0" : 117.81625264956585, + "95.0" : 117.81625264956585, + "99.0" : 117.81625264956585, + "99.9" : 117.81625264956585, + "99.99" : 117.81625264956585, + "99.999" : 117.81625264956585, + "99.9999" : 117.81625264956585, + "100.0" : 117.81625264956585 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.62405966046367, + 117.81625264956585, + 117.81333406094741 + ], + [ + 116.91235231763682, + 117.00495984304547, + 117.06213765632071 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06081367836241453, + "scoreError" : 4.126852877702864E-4, + "scoreConfidence" : [ + 0.06040099307464424, + 0.06122636365018482 + ], + "scorePercentiles" : { + "0.0" : 0.06065401640060168, + "50.0" : 0.06081926282936455, + "90.0" : 0.06102180868695005, + "95.0" : 0.06102180868695005, + "99.0" : 0.06102180868695005, + "99.9" : 0.06102180868695005, + "99.99" : 0.06102180868695005, + "99.999" : 0.06102180868695005, + "99.9999" : 0.06102180868695005, + "100.0" : 0.06102180868695005 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06074626425226123, + 0.06066770679164012, + 0.06065401640060168 + ], + [ + 0.06102180868695005, + 0.060892261406467876, + 0.06090001263656626 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6098999758515547E-4, + "scoreError" : 3.1061384343038643E-5, + "scoreConfidence" : [ + 3.299286132421168E-4, + 3.920513819281941E-4 + ], + "scorePercentiles" : { + "0.0" : 3.504066573230701E-4, + "50.0" : 3.6142591843601595E-4, + "90.0" : 3.7117312466246875E-4, + "95.0" : 3.7117312466246875E-4, + "99.0" : 3.7117312466246875E-4, + "99.9" : 3.7117312466246875E-4, + "99.99" : 3.7117312466246875E-4, + "99.999" : 3.7117312466246875E-4, + "99.9999" : 3.7117312466246875E-4, + "100.0" : 3.7117312466246875E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7100770922258145E-4, + 3.710900526787672E-4, + 3.7117312466246875E-4 + ], + [ + 3.5184412764945045E-4, + 3.504183139745947E-4, + 3.504066573230701E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12454009173103497, + "scoreError" : 0.0023207612127116137, + "scoreConfidence" : [ + 0.12221933051832336, + 0.12686085294374658 + ], + "scorePercentiles" : { + "0.0" : 0.12358259940187101, + "50.0" : 0.12462321072656232, + "90.0" : 0.12539869912725085, + "95.0" : 0.12539869912725085, + "99.0" : 0.12539869912725085, + "99.9" : 0.12539869912725085, + "99.99" : 0.12539869912725085, + "99.999" : 0.12539869912725085, + "99.9999" : 0.12539869912725085, + "100.0" : 0.12539869912725085 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12539869912725085, + 0.1251949369155076, + 0.12524831519356738 + ], + [ + 0.12405148453761707, + 0.12376451521039604, + 0.12358259940187101 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013137245291107942, + "scoreError" : 1.0622924956219113E-4, + "scoreConfidence" : [ + 0.01303101604154575, + 0.013243474540670134 + ], + "scorePercentiles" : { + "0.0" : 0.013097326851999802, + "50.0" : 0.01313714965409778, + "90.0" : 0.013177223759545128, + "95.0" : 0.013177223759545128, + "99.0" : 0.013177223759545128, + "99.9" : 0.013177223759545128, + "99.99" : 0.013177223759545128, + "99.999" : 0.013177223759545128, + "99.9999" : 0.013177223759545128, + "100.0" : 0.013177223759545128 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013162275285978844, + 0.013174195800667393, + 0.013177223759545128 + ], + [ + 0.013100426026239774, + 0.013097326851999802, + 0.013112024022216714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9679761384991735, + "scoreError" : 0.04334209748707056, + "scoreConfidence" : [ + 0.924634041012103, + 1.011318235986244 + ], + "scorePercentiles" : { + "0.0" : 0.9537262587259203, + "50.0" : 0.9676833410034094, + "90.0" : 0.9832441938845737, + "95.0" : 0.9832441938845737, + "99.0" : 0.9832441938845737, + "99.9" : 0.9832441938845737, + "99.99" : 0.9832441938845737, + "99.999" : 0.9832441938845737, + "99.9999" : 0.9832441938845737, + "100.0" : 0.9832441938845737 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9832441938845737, + 0.9816340804868473, + 0.9813406797173977 + ], + [ + 0.9538856158908814, + 0.9540260022894209, + 0.9537262587259203 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010521037902980155, + "scoreError" : 4.547709928083766E-4, + "scoreConfidence" : [ + 0.010066266910171777, + 0.010975808895788532 + ], + "scorePercentiles" : { + "0.0" : 0.010368745572142811, + "50.0" : 0.010522653938808938, + "90.0" : 0.01067395609284374, + "95.0" : 0.01067395609284374, + "99.0" : 0.01067395609284374, + "99.9" : 0.01067395609284374, + "99.99" : 0.01067395609284374, + "99.999" : 0.01067395609284374, + "99.9999" : 0.01067395609284374, + "100.0" : 0.01067395609284374 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01037981376694712, + 0.010368745572142811, + 0.010370602044604653 + ], + [ + 0.010667615830671847, + 0.01067395609284374, + 0.010665494110670757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.010146797053285, + "scoreError" : 0.2674722985859212, + "scoreConfidence" : [ + 2.742674498467364, + 3.277619095639206 + ], + "scorePercentiles" : { + "0.0" : 2.921180296728972, + "50.0" : 3.006823172533222, + "90.0" : 3.1026224342431763, + "95.0" : 3.1026224342431763, + "99.0" : 3.1026224342431763, + "99.9" : 3.1026224342431763, + "99.99" : 3.1026224342431763, + "99.999" : 3.1026224342431763, + "99.9999" : 3.1026224342431763, + "100.0" : 3.1026224342431763 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.923244487434249, + 2.925148179532164, + 2.921180296728972 + ], + [ + 3.1026224342431763, + 3.100187218846869, + 3.0884981655342805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.729642674057592, + "scoreError" : 0.032059123252017076, + "scoreConfidence" : [ + 2.697583550805575, + 2.761701797309609 + ], + "scorePercentiles" : { + "0.0" : 2.715074183224756, + "50.0" : 2.7300454278271777, + "90.0" : 2.744416961855104, + "95.0" : 2.744416961855104, + "99.0" : 2.744416961855104, + "99.9" : 2.744416961855104, + "99.99" : 2.744416961855104, + "99.999" : 2.744416961855104, + "99.9999" : 2.744416961855104, + "100.0" : 2.744416961855104 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.723383799019608, + 2.715074183224756, + 2.7209697110990207 + ], + [ + 2.736707056634747, + 2.744416961855104, + 2.7373043325123154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17652233506429685, + "scoreError" : 5.489677945596517E-4, + "scoreConfidence" : [ + 0.1759733672697372, + 0.1770713028588565 + ], + "scorePercentiles" : { + "0.0" : 0.17617417544879588, + "50.0" : 0.17661149373378138, + "90.0" : 0.17668116913427562, + "95.0" : 0.17668116913427562, + "99.0" : 0.17668116913427562, + "99.9" : 0.17668116913427562, + "99.99" : 0.17668116913427562, + "99.999" : 0.17668116913427562, + "99.9999" : 0.17668116913427562, + "100.0" : 0.17668116913427562 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17668116913427562, + 0.17664823977672184, + 0.17662219117257458 + ], + [ + 0.17640743855842506, + 0.17660079629498818, + 0.17617417544879588 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33086610210481754, + "scoreError" : 0.00474967351888446, + "scoreConfidence" : [ + 0.3261164285859331, + 0.335615775623702 + ], + "scorePercentiles" : { + "0.0" : 0.32928795719319043, + "50.0" : 0.3303980289258971, + "90.0" : 0.3329669544849171, + "95.0" : 0.3329669544849171, + "99.0" : 0.3329669544849171, + "99.9" : 0.3329669544849171, + "99.99" : 0.3329669544849171, + "99.999" : 0.3329669544849171, + "99.9999" : 0.3329669544849171, + "100.0" : 0.3329669544849171 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33117495919989404, + 0.33276241142020496, + 0.3329669544849171 + ], + [ + 0.32938323167879846, + 0.32928795719319043, + 0.3296210986519002 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1451189023741535, + "scoreError" : 0.009012889054341095, + "scoreConfidence" : [ + 0.13610601331981242, + 0.1541317914284946 + ], + "scorePercentiles" : { + "0.0" : 0.14210293500348145, + "50.0" : 0.1451016025847538, + "90.0" : 0.1481631082598711, + "95.0" : 0.1481631082598711, + "99.0" : 0.1481631082598711, + "99.9" : 0.1481631082598711, + "99.99" : 0.1481631082598711, + "99.999" : 0.1481631082598711, + "99.9999" : 0.1481631082598711, + "100.0" : 0.1481631082598711 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14813388641346212, + 0.1481631082598711, + 0.14785349841800224 + ], + [ + 0.14234970675150532, + 0.14210293500348145, + 0.14211027939859883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40416547569483324, + "scoreError" : 0.004915244452317809, + "scoreConfidence" : [ + 0.3992502312425154, + 0.4090807201471511 + ], + "scorePercentiles" : { + "0.0" : 0.4025833841384863, + "50.0" : 0.403347456109614, + "90.0" : 0.40676451999186497, + "95.0" : 0.40676451999186497, + "99.0" : 0.40676451999186497, + "99.9" : 0.40676451999186497, + "99.99" : 0.40676451999186497, + "99.999" : 0.40676451999186497, + "99.9999" : 0.40676451999186497, + "100.0" : 0.40676451999186497 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40676451999186497, + 0.40356140423728815, + 0.40313350798193986 + ], + [ + 0.40597208484553243, + 0.40297795297388783, + 0.4025833841384863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15680901818471363, + "scoreError" : 0.005053863199666629, + "scoreConfidence" : [ + 0.151755154985047, + 0.16186288138438026 + ], + "scorePercentiles" : { + "0.0" : 0.15498692729724284, + "50.0" : 0.15690140180188056, + "90.0" : 0.15867090170567236, + "95.0" : 0.15867090170567236, + "99.0" : 0.15867090170567236, + "99.9" : 0.15867090170567236, + "99.99" : 0.15867090170567236, + "99.999" : 0.15867090170567236, + "99.9999" : 0.15867090170567236, + "100.0" : 0.15867090170567236 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15555055667377002, + 0.15499936303047213, + 0.15498692729724284 + ], + [ + 0.15825224692999112, + 0.15867090170567236, + 0.15839411347113327 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0469541824718936, + "scoreError" : 5.165021932614059E-4, + "scoreConfidence" : [ + 0.04643768027863219, + 0.04747068466515501 + ], + "scorePercentiles" : { + "0.0" : 0.04678104134350002, + "50.0" : 0.04692366618671954, + "90.0" : 0.047218807647450456, + "95.0" : 0.047218807647450456, + "99.0" : 0.047218807647450456, + "99.9" : 0.047218807647450456, + "99.99" : 0.047218807647450456, + "99.999" : 0.047218807647450456, + "99.9999" : 0.047218807647450456, + "100.0" : 0.047218807647450456 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047218807647450456, + 0.04702844885252069, + 0.04708952211522614 + ], + [ + 0.04681888352091838, + 0.04678104134350002, + 0.04678839135174589 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8407284.231460277, + "scoreError" : 93734.80850280596, + "scoreConfidence" : [ + 8313549.422957471, + 8501019.039963083 + ], + "scorePercentiles" : { + "0.0" : 8370662.910460251, + "50.0" : 8405551.987879582, + "90.0" : 8442828.016033756, + "95.0" : 8442828.016033756, + "99.0" : 8442828.016033756, + "99.9" : 8442828.016033756, + "99.99" : 8442828.016033756, + "99.999" : 8442828.016033756, + "99.9999" : 8442828.016033756, + "100.0" : 8442828.016033756 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8439679.210126583, + 8442828.016033756, + 8429541.865206402 + ], + [ + 8381562.110552764, + 8370662.910460251, + 8379431.27638191 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-16T00:58:58Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json b/performance-results/2025-09-16T00:58:58Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json new file mode 100644 index 0000000000..431886e19f --- /dev/null +++ b/performance-results/2025-09-16T00:58:58Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3550449678177383, + "scoreError" : 0.023088513079917286, + "scoreConfidence" : [ + 3.331956454737821, + 3.3781334808976555 + ], + "scorePercentiles" : { + "0.0" : 3.350712348899915, + "50.0" : 3.3552118042551586, + "90.0" : 3.359043913860722, + "95.0" : 3.359043913860722, + "99.0" : 3.359043913860722, + "99.9" : 3.359043913860722, + "99.99" : 3.359043913860722, + "99.999" : 3.359043913860722, + "99.9999" : 3.359043913860722, + "100.0" : 3.359043913860722 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.350712348899915, + 3.359043913860722 + ], + [ + 3.3538927928243742, + 3.356530815685943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.703700700071189, + "scoreError" : 0.01957657445058494, + "scoreConfidence" : [ + 1.684124125620604, + 1.723277274521774 + ], + "scorePercentiles" : { + "0.0" : 1.7013826734137225, + "50.0" : 1.7026688592926011, + "90.0" : 1.7080824082858308, + "95.0" : 1.7080824082858308, + "99.0" : 1.7080824082858308, + "99.9" : 1.7080824082858308, + "99.99" : 1.7080824082858308, + "99.999" : 1.7080824082858308, + "99.9999" : 1.7080824082858308, + "100.0" : 1.7080824082858308 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7020240558009494, + 1.703313662784253 + ], + [ + 1.7013826734137225, + 1.7080824082858308 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8573399039775881, + "scoreError" : 0.01749158541944735, + "scoreConfidence" : [ + 0.8398483185581407, + 0.8748314893970355 + ], + "scorePercentiles" : { + "0.0" : 0.8539934307109489, + "50.0" : 0.8575898420185514, + "90.0" : 0.8601865011623007, + "95.0" : 0.8601865011623007, + "99.0" : 0.8601865011623007, + "99.9" : 0.8601865011623007, + "99.99" : 0.8601865011623007, + "99.999" : 0.8601865011623007, + "99.9999" : 0.8601865011623007, + "100.0" : 0.8601865011623007 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8539934307109489, + 0.8564597873132151 + ], + [ + 0.8587198967238876, + 0.8601865011623007 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.451036717323344, + "scoreError" : 0.11004572043630732, + "scoreConfidence" : [ + 16.340990996887037, + 16.56108243775965 + ], + "scorePercentiles" : { + "0.0" : 16.402157620396196, + "50.0" : 16.445977458722616, + "90.0" : 16.505760419043106, + "95.0" : 16.505760419043106, + "99.0" : 16.505760419043106, + "99.9" : 16.505760419043106, + "99.99" : 16.505760419043106, + "99.999" : 16.505760419043106, + "99.9999" : 16.505760419043106, + "100.0" : 16.505760419043106 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.426984182281814, + 16.402157620396196, + 16.42547399861816 + ], + [ + 16.464970735163416, + 16.505760419043106, + 16.480873348437363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2762.2142120854023, + "scoreError" : 35.52146902776249, + "scoreConfidence" : [ + 2726.6927430576397, + 2797.735681113165 + ], + "scorePercentiles" : { + "0.0" : 2749.511600616329, + "50.0" : 2761.5504587299, + "90.0" : 2775.103563796102, + "95.0" : 2775.103563796102, + "99.0" : 2775.103563796102, + "99.9" : 2775.103563796102, + "99.99" : 2775.103563796102, + "99.999" : 2775.103563796102, + "99.9999" : 2775.103563796102, + "100.0" : 2775.103563796102 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2771.592763268247, + 2775.103563796102, + 2774.4375541740947 + ], + [ + 2751.131636466086, + 2751.5081541915533, + 2749.511600616329 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77114.63909813233, + "scoreError" : 109.57309185044635, + "scoreConfidence" : [ + 77005.0660062819, + 77224.21218998278 + ], + "scorePercentiles" : { + "0.0" : 77066.0927702493, + "50.0" : 77127.63914907348, + "90.0" : 77152.59085435388, + "95.0" : 77152.59085435388, + "99.0" : 77152.59085435388, + "99.9" : 77152.59085435388, + "99.99" : 77152.59085435388, + "99.999" : 77152.59085435388, + "99.9999" : 77152.59085435388, + "100.0" : 77152.59085435388 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77113.79475111396, + 77066.0927702493, + 77068.2250715392 + ], + [ + 77152.59085435388, + 77145.64759450464, + 77141.483547033 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 370.71452455056857, + "scoreError" : 9.13294739238112, + "scoreConfidence" : [ + 361.58157715818743, + 379.8474719429497 + ], + "scorePercentiles" : { + "0.0" : 367.58292213419594, + "50.0" : 370.509214731391, + "90.0" : 374.0681094966475, + "95.0" : 374.0681094966475, + "99.0" : 374.0681094966475, + "99.9" : 374.0681094966475, + "99.99" : 374.0681094966475, + "99.999" : 374.0681094966475, + "99.9999" : 374.0681094966475, + "100.0" : 374.0681094966475 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 373.07612984306036, + 374.0681094966475, + 373.866883544416 + ], + [ + 367.58292213419594, + 367.7508026653702, + 367.9422996197217 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.96901063647466, + "scoreError" : 0.4882902999085057, + "scoreConfidence" : [ + 114.48072033656616, + 115.45730093638316 + ], + "scorePercentiles" : { + "0.0" : 114.83549763592508, + "50.0" : 114.89491900916244, + "90.0" : 115.288016928934, + "95.0" : 115.288016928934, + "99.0" : 115.288016928934, + "99.9" : 115.288016928934, + "99.99" : 115.288016928934, + "99.999" : 115.288016928934, + "99.9999" : 115.288016928934, + "100.0" : 115.288016928934 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.90307142286534, + 114.83549763592508, + 114.84984251262325 + ], + [ + 115.288016928934, + 114.88676659545955, + 115.05086872304086 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060371863591423665, + "scoreError" : 3.1126908674266457E-4, + "scoreConfidence" : [ + 0.060060594504681, + 0.06068313267816633 + ], + "scorePercentiles" : { + "0.0" : 0.06023596475038551, + "50.0" : 0.060363143690271126, + "90.0" : 0.060549442403288994, + "95.0" : 0.060549442403288994, + "99.0" : 0.060549442403288994, + "99.9" : 0.060549442403288994, + "99.99" : 0.060549442403288994, + "99.999" : 0.060549442403288994, + "99.9999" : 0.060549442403288994, + "100.0" : 0.060549442403288994 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06023596475038551, + 0.06028581103093218, + 0.060373776378466165 + ], + [ + 0.060352511002076094, + 0.060549442403288994, + 0.06043367598339306 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6576892854784586E-4, + "scoreError" : 1.2179376781158934E-5, + "scoreConfidence" : [ + 3.5358955176668694E-4, + 3.779483053290048E-4 + ], + "scorePercentiles" : { + "0.0" : 3.614166724071045E-4, + "50.0" : 3.657744911455902E-4, + "90.0" : 3.698686990401891E-4, + "95.0" : 3.698686990401891E-4, + "99.0" : 3.698686990401891E-4, + "99.9" : 3.698686990401891E-4, + "99.99" : 3.698686990401891E-4, + "99.999" : 3.698686990401891E-4, + "99.9999" : 3.698686990401891E-4, + "100.0" : 3.698686990401891E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6982354011258695E-4, + 3.6948861737635084E-4, + 3.698686990401891E-4 + ], + [ + 3.614166724071045E-4, + 3.6206036491482957E-4, + 3.61955677436014E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12241245175665555, + "scoreError" : 7.138693804545063E-4, + "scoreConfidence" : [ + 0.12169858237620104, + 0.12312632113711006 + ], + "scorePercentiles" : { + "0.0" : 0.12206150754320867, + "50.0" : 0.12246346430495153, + "90.0" : 0.12270866142708142, + "95.0" : 0.12270866142708142, + "99.0" : 0.12270866142708142, + "99.9" : 0.12270866142708142, + "99.99" : 0.12270866142708142, + "99.999" : 0.12270866142708142, + "99.9999" : 0.12270866142708142, + "100.0" : 0.12270866142708142 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12206150754320867, + 0.12218907419173529, + 0.12234721984193012 + ], + [ + 0.12257970876797293, + 0.12270866142708142, + 0.1225885387680049 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013122014116494128, + "scoreError" : 4.0456715431769257E-4, + "scoreConfidence" : [ + 0.012717446962176436, + 0.01352658127081182 + ], + "scorePercentiles" : { + "0.0" : 0.012980473487115118, + "50.0" : 0.013122801917655502, + "90.0" : 0.013258719002533706, + "95.0" : 0.013258719002533706, + "99.0" : 0.013258719002533706, + "99.9" : 0.013258719002533706, + "99.99" : 0.013258719002533706, + "99.999" : 0.013258719002533706, + "99.9999" : 0.013258719002533706, + "100.0" : 0.013258719002533706 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012980473487115118, + 0.012990388756461002, + 0.013000674351697411 + ], + [ + 0.01325689961754393, + 0.013258719002533706, + 0.013244929483613593 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9660182373169045, + "scoreError" : 0.021376572231093002, + "scoreConfidence" : [ + 0.9446416650858115, + 0.9873948095479975 + ], + "scorePercentiles" : { + "0.0" : 0.9580420342944727, + "50.0" : 0.9659752388028264, + "90.0" : 0.9743621377630554, + "95.0" : 0.9743621377630554, + "99.0" : 0.9743621377630554, + "99.9" : 0.9743621377630554, + "99.99" : 0.9743621377630554, + "99.999" : 0.9743621377630554, + "99.9999" : 0.9743621377630554, + "100.0" : 0.9743621377630554 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9590697538122183, + 0.9602925449395046, + 0.9580420342944727 + ], + [ + 0.9716579326661484, + 0.9726850204260286, + 0.9743621377630554 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010696727219903194, + "scoreError" : 0.0016455761339107344, + "scoreConfidence" : [ + 0.00905115108599246, + 0.012342303353813928 + ], + "scorePercentiles" : { + "0.0" : 0.010156158698336868, + "50.0" : 0.01069767036841036, + "90.0" : 0.011236189171333292, + "95.0" : 0.011236189171333292, + "99.0" : 0.011236189171333292, + "99.9" : 0.011236189171333292, + "99.99" : 0.011236189171333292, + "99.999" : 0.011236189171333292, + "99.9999" : 0.011236189171333292, + "100.0" : 0.011236189171333292 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011226767841105044, + 0.011236189171333292, + 0.011234256215764429 + ], + [ + 0.010158418497163847, + 0.010168572895715678, + 0.010156158698336868 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.9394150388445976, + "scoreError" : 0.008464426809669977, + "scoreConfidence" : [ + 2.930950612034928, + 2.9478794656542675 + ], + "scorePercentiles" : { + "0.0" : 2.936533395772167, + "50.0" : 2.939048057981333, + "90.0" : 2.9437703625662155, + "95.0" : 2.9437703625662155, + "99.0" : 2.9437703625662155, + "99.9" : 2.9437703625662155, + "99.99" : 2.9437703625662155, + "99.999" : 2.9437703625662155, + "99.9999" : 2.9437703625662155, + "100.0" : 2.9437703625662155 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9406712422104646, + 2.9415423264705884, + 2.936533395772167 + ], + [ + 2.9437703625662155, + 2.937424873752202, + 2.9365480322959483 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.718082292105174, + "scoreError" : 0.17661847039226802, + "scoreConfidence" : [ + 2.541463821712906, + 2.8947007624974423 + ], + "scorePercentiles" : { + "0.0" : 2.6564675960159363, + "50.0" : 2.7180359866688555, + "90.0" : 2.7809428809788654, + "95.0" : 2.7809428809788654, + "99.0" : 2.7809428809788654, + "99.9" : 2.7809428809788654, + "99.99" : 2.7809428809788654, + "99.999" : 2.7809428809788654, + "99.9999" : 2.7809428809788654, + "100.0" : 2.7809428809788654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7809428809788654, + 2.7754469614317423, + 2.7698623356410965 + ], + [ + 2.6662096376966145, + 2.659564340866791, + 2.6564675960159363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17673625046473904, + "scoreError" : 0.006344659052973811, + "scoreConfidence" : [ + 0.17039159141176521, + 0.18308090951771286 + ], + "scorePercentiles" : { + "0.0" : 0.17411400168886568, + "50.0" : 0.17704545643031896, + "90.0" : 0.17901901213726928, + "95.0" : 0.17901901213726928, + "99.0" : 0.17901901213726928, + "99.9" : 0.17901901213726928, + "99.99" : 0.17901901213726928, + "99.999" : 0.17901901213726928, + "99.9999" : 0.17901901213726928, + "100.0" : 0.17901901213726928 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17550981492856893, + 0.17452768905099297, + 0.17411400168886568 + ], + [ + 0.17901901213726928, + 0.1786658870506682, + 0.178581097932069 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3321955513740942, + "scoreError" : 0.016770376234733375, + "scoreConfidence" : [ + 0.3154251751393608, + 0.34896592760882755 + ], + "scorePercentiles" : { + "0.0" : 0.32670429153871283, + "50.0" : 0.33133186169618795, + "90.0" : 0.3386654079379593, + "95.0" : 0.3386654079379593, + "99.0" : 0.3386654079379593, + "99.9" : 0.3386654079379593, + "99.99" : 0.3386654079379593, + "99.999" : 0.3386654079379593, + "99.9999" : 0.3386654079379593, + "100.0" : 0.3386654079379593 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3268085365359477, + 0.32670429153871283, + 0.32693540113770103 + ], + [ + 0.33833134883956967, + 0.33572832225467486, + 0.3386654079379593 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15057335959732468, + "scoreError" : 7.745994907699496E-4, + "scoreConfidence" : [ + 0.14979876010655474, + 0.15134795908809462 + ], + "scorePercentiles" : { + "0.0" : 0.15023308077818673, + "50.0" : 0.15056329840004645, + "90.0" : 0.15090615155127662, + "95.0" : 0.15090615155127662, + "99.0" : 0.15090615155127662, + "99.9" : 0.15090615155127662, + "99.99" : 0.15090615155127662, + "99.999" : 0.15090615155127662, + "99.9999" : 0.15090615155127662, + "100.0" : 0.15090615155127662 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15023308077818673, + 0.150333052389471, + 0.15045094923873142 + ], + [ + 0.15090615155127662, + 0.15084127606492095, + 0.15067564756136148 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40769737749400997, + "scoreError" : 0.013650682757160953, + "scoreConfidence" : [ + 0.394046694736849, + 0.42134806025117094 + ], + "scorePercentiles" : { + "0.0" : 0.4003315270616493, + "50.0" : 0.4077598938190644, + "90.0" : 0.4149509201659751, + "95.0" : 0.4149509201659751, + "99.0" : 0.4149509201659751, + "99.9" : 0.4149509201659751, + "99.99" : 0.4149509201659751, + "99.999" : 0.4149509201659751, + "99.9999" : 0.4149509201659751, + "100.0" : 0.4149509201659751 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40715925735922803, + 0.4053579532225375, + 0.4003315270616493 + ], + [ + 0.4149509201659751, + 0.41002407687576875, + 0.40836053027890074 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15321770845192786, + "scoreError" : 0.004433040820125156, + "scoreConfidence" : [ + 0.1487846676318027, + 0.15765074927205303 + ], + "scorePercentiles" : { + "0.0" : 0.15157169904663748, + "50.0" : 0.1532523023523888, + "90.0" : 0.15473707255481456, + "95.0" : 0.15473707255481456, + "99.0" : 0.15473707255481456, + "99.9" : 0.15473707255481456, + "99.99" : 0.15473707255481456, + "99.999" : 0.15473707255481456, + "99.9999" : 0.15473707255481456, + "100.0" : 0.15473707255481456 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15473707255481456, + 0.15457073535094362, + 0.1546601702315223 + ], + [ + 0.15157169904663748, + 0.151933869353834, + 0.15183270417381534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04701340447310221, + "scoreError" : 0.0020515380375950238, + "scoreConfidence" : [ + 0.04496186643550719, + 0.049064942510697235 + ], + "scorePercentiles" : { + "0.0" : 0.04616091880389225, + "50.0" : 0.04716541850962565, + "90.0" : 0.04783490022290678, + "95.0" : 0.04783490022290678, + "99.0" : 0.04783490022290678, + "99.9" : 0.04783490022290678, + "99.99" : 0.04783490022290678, + "99.999" : 0.04783490022290678, + "99.9999" : 0.04783490022290678, + "100.0" : 0.04783490022290678 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046806734661686514, + 0.046193587113075855, + 0.04616091880389225 + ], + [ + 0.04783490022290678, + 0.04756018367948712, + 0.04752410235756478 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8785675.387501236, + "scoreError" : 268140.73586703517, + "scoreConfidence" : [ + 8517534.651634201, + 9053816.12336827 + ], + "scorePercentiles" : { + "0.0" : 8699600.56, + "50.0" : 8754870.360699706, + "90.0" : 8921447.0, + "95.0" : 8921447.0, + "99.0" : 8921447.0, + "99.9" : 8921447.0, + "99.99" : 8921447.0, + "99.999" : 8921447.0, + "99.9999" : 8921447.0, + "100.0" : 8921447.0 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8881239.006216696, + 8921447.0, + 8785258.930640914 + ], + [ + 8699600.56, + 8724481.7907585, + 8702025.037391305 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-16T00:59:16Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json b/performance-results/2025-09-16T00:59:16Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json new file mode 100644 index 0000000000..e8d558c60c --- /dev/null +++ b/performance-results/2025-09-16T00:59:16Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3396823239955404, + "scoreError" : 0.05046504018688131, + "scoreConfidence" : [ + 3.289217283808659, + 3.390147364182422 + ], + "scorePercentiles" : { + "0.0" : 3.3296816985090474, + "50.0" : 3.340170671453315, + "90.0" : 3.3487062545664847, + "95.0" : 3.3487062545664847, + "99.0" : 3.3487062545664847, + "99.9" : 3.3487062545664847, + "99.99" : 3.3487062545664847, + "99.999" : 3.3487062545664847, + "99.9999" : 3.3487062545664847, + "100.0" : 3.3487062545664847 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3408935294089113, + 3.339447813497718 + ], + [ + 3.3296816985090474, + 3.3487062545664847 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.685645028683013, + "scoreError" : 0.03326865373846976, + "scoreConfidence" : [ + 1.6523763749445433, + 1.7189136824214826 + ], + "scorePercentiles" : { + "0.0" : 1.6780804897663881, + "50.0" : 1.6875389194790769, + "90.0" : 1.6894217860075103, + "95.0" : 1.6894217860075103, + "99.0" : 1.6894217860075103, + "99.9" : 1.6894217860075103, + "99.99" : 1.6894217860075103, + "99.999" : 1.6894217860075103, + "99.9999" : 1.6894217860075103, + "100.0" : 1.6894217860075103 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6780804897663881, + 1.686884292442754 + ], + [ + 1.6894217860075103, + 1.6881935465153994 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.846339044795851, + "scoreError" : 0.027499076332370538, + "scoreConfidence" : [ + 0.8188399684634804, + 0.8738381211282216 + ], + "scorePercentiles" : { + "0.0" : 0.8428882540177971, + "50.0" : 0.8451067328786906, + "90.0" : 0.8522544594082252, + "95.0" : 0.8522544594082252, + "99.0" : 0.8522544594082252, + "99.9" : 0.8522544594082252, + "99.99" : 0.8522544594082252, + "99.999" : 0.8522544594082252, + "99.9999" : 0.8522544594082252, + "100.0" : 0.8522544594082252 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8428882540177971, + 0.8522544594082252 + ], + [ + 0.843625029869833, + 0.8465884358875483 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.14727833488808, + "scoreError" : 0.31694168081424867, + "scoreConfidence" : [ + 15.830336654073832, + 16.46422001570233 + ], + "scorePercentiles" : { + "0.0" : 16.028544615595784, + "50.0" : 16.097451904218943, + "90.0" : 16.3036936545558, + "95.0" : 16.3036936545558, + "99.0" : 16.3036936545558, + "99.9" : 16.3036936545558, + "99.99" : 16.3036936545558, + "99.999" : 16.3036936545558, + "99.9999" : 16.3036936545558, + "100.0" : 16.3036936545558 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.27386266849639, + 16.08266526224263, + 16.3036936545558 + ], + [ + 16.028544615595784, + 16.088925431941277, + 16.105978376496605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2697.4020232576963, + "scoreError" : 128.73326398214346, + "scoreConfidence" : [ + 2568.668759275553, + 2826.1352872398397 + ], + "scorePercentiles" : { + "0.0" : 2629.649932782624, + "50.0" : 2694.9133619076874, + "90.0" : 2758.9758354550722, + "95.0" : 2758.9758354550722, + "99.0" : 2758.9758354550722, + "99.9" : 2758.9758354550722, + "99.99" : 2758.9758354550722, + "99.999" : 2758.9758354550722, + "99.9999" : 2758.9758354550722, + "100.0" : 2758.9758354550722 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2689.513822656626, + 2671.176505137815, + 2629.649932782624 + ], + [ + 2758.9758354550722, + 2734.783142355294, + 2700.3129011587484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74282.38663578841, + "scoreError" : 3066.4847797686316, + "scoreConfidence" : [ + 71215.90185601977, + 77348.87141555705 + ], + "scorePercentiles" : { + "0.0" : 73233.20318619379, + "50.0" : 74316.13999017303, + "90.0" : 75299.46466769963, + "95.0" : 75299.46466769963, + "99.0" : 75299.46466769963, + "99.9" : 75299.46466769963, + "99.99" : 75299.46466769963, + "99.999" : 75299.46466769963, + "99.9999" : 75299.46466769963, + "100.0" : 75299.46466769963 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73233.20318619379, + 73240.82268178622, + 73382.22459408993 + ], + [ + 75299.46466769963, + 75250.05538625614, + 75288.54929870475 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.8467196504794, + "scoreError" : 3.6656781513250905, + "scoreConfidence" : [ + 354.1810414991543, + 361.51239780180447 + ], + "scorePercentiles" : { + "0.0" : 356.2544578551256, + "50.0" : 357.5220461321448, + "90.0" : 359.44765277565193, + "95.0" : 359.44765277565193, + "99.0" : 359.44765277565193, + "99.9" : 359.44765277565193, + "99.99" : 359.44765277565193, + "99.999" : 359.44765277565193, + "99.9999" : 359.44765277565193, + "100.0" : 359.44765277565193 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.2544578551256, + 357.00824145617435, + 357.93678578648525 + ], + [ + 359.44765277565193, + 357.10730647780434, + 359.3258735516348 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.95257955609581, + "scoreError" : 0.8364592141112309, + "scoreConfidence" : [ + 114.11612034198458, + 115.78903877020704 + ], + "scorePercentiles" : { + "0.0" : 114.41632651662084, + "50.0" : 115.04001913490035, + "90.0" : 115.23315648397535, + "95.0" : 115.23315648397535, + "99.0" : 115.23315648397535, + "99.9" : 115.23315648397535, + "99.99" : 115.23315648397535, + "99.999" : 115.23315648397535, + "99.9999" : 115.23315648397535, + "100.0" : 115.23315648397535 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.81976580773376, + 115.03603465006977, + 114.41632651662084 + ], + [ + 115.04400361973093, + 115.23315648397535, + 115.16619025844416 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062215257634550734, + "scoreError" : 0.001265951070212804, + "scoreConfidence" : [ + 0.06094930656433793, + 0.06348120870476354 + ], + "scorePercentiles" : { + "0.0" : 0.06140721922628185, + "50.0" : 0.06236823656829643, + "90.0" : 0.06259354630922054, + "95.0" : 0.06259354630922054, + "99.0" : 0.06259354630922054, + "99.9" : 0.06259354630922054, + "99.99" : 0.06259354630922054, + "99.999" : 0.06259354630922054, + "99.9999" : 0.06259354630922054, + "100.0" : 0.06259354630922054 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06227581139383975, + 0.06255234126691228, + 0.062001965868296885 + ], + [ + 0.0624606617427531, + 0.06259354630922054, + 0.06140721922628185 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.702551438027938E-4, + "scoreError" : 2.1678190667416058E-5, + "scoreConfidence" : [ + 3.485769531353777E-4, + 3.9193333447020985E-4 + ], + "scorePercentiles" : { + "0.0" : 3.60873784563828E-4, + "50.0" : 3.6946714369642564E-4, + "90.0" : 3.7904443770764507E-4, + "95.0" : 3.7904443770764507E-4, + "99.0" : 3.7904443770764507E-4, + "99.9" : 3.7904443770764507E-4, + "99.99" : 3.7904443770764507E-4, + "99.999" : 3.7904443770764507E-4, + "99.9999" : 3.7904443770764507E-4, + "100.0" : 3.7904443770764507E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.784885923029374E-4, + 3.73190908653602E-4, + 3.7904443770764507E-4 + ], + [ + 3.60873784563828E-4, + 3.64189760849501E-4, + 3.657433787392493E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.12397908556326975, + "scoreError" : 0.004098085652230355, + "scoreConfidence" : [ + 0.1198809999110394, + 0.1280771712155001 + ], + "scorePercentiles" : { + "0.0" : 0.12243185160381978, + "50.0" : 0.1239494325147955, + "90.0" : 0.1255939366012333, + "95.0" : 0.1255939366012333, + "99.0" : 0.1255939366012333, + "99.9" : 0.1255939366012333, + "99.99" : 0.1255939366012333, + "99.999" : 0.1255939366012333, + "99.9999" : 0.1255939366012333, + "100.0" : 0.1255939366012333 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1248778289357026, + 0.1255939366012333, + 0.1253805235145877 + ], + [ + 0.12256933663038683, + 0.1230210360938884, + 0.12243185160381978 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013113840469039463, + "scoreError" : 1.2299106511551013E-4, + "scoreConfidence" : [ + 0.012990849403923954, + 0.013236831534154973 + ], + "scorePercentiles" : { + "0.0" : 0.013055917546514315, + "50.0" : 0.013102937535531088, + "90.0" : 0.01317625580736544, + "95.0" : 0.01317625580736544, + "99.0" : 0.01317625580736544, + "99.9" : 0.01317625580736544, + "99.99" : 0.01317625580736544, + "99.999" : 0.01317625580736544, + "99.9999" : 0.01317625580736544, + "100.0" : 0.01317625580736544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013104913892722024, + 0.013091094706168043, + 0.013153899683126798 + ], + [ + 0.01317625580736544, + 0.013055917546514315, + 0.013100961178340153 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9838195200849307, + "scoreError" : 0.033871023394463205, + "scoreConfidence" : [ + 0.9499484966904674, + 1.017690543479394 + ], + "scorePercentiles" : { + "0.0" : 0.9695870314136126, + "50.0" : 0.9848259598996902, + "90.0" : 0.9966390579031293, + "95.0" : 0.9966390579031293, + "99.0" : 0.9966390579031293, + "99.9" : 0.9966390579031293, + "99.99" : 0.9966390579031293, + "99.999" : 0.9966390579031293, + "99.9999" : 0.9966390579031293, + "100.0" : 0.9966390579031293 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9762672281335416, + 0.9695870314136126, + 0.9731787356232363 + ], + [ + 0.9966390579031293, + 0.9938603757702246, + 0.9933846916658389 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01066327489026221, + "scoreError" : 8.300908076620776E-4, + "scoreConfidence" : [ + 0.009833184082600132, + 0.011493365697924288 + ], + "scorePercentiles" : { + "0.0" : 0.010373916702109782, + "50.0" : 0.010619239386234498, + "90.0" : 0.011077930709258041, + "95.0" : 0.011077930709258041, + "99.0" : 0.011077930709258041, + "99.9" : 0.011077930709258041, + "99.99" : 0.011077930709258041, + "99.999" : 0.011077930709258041, + "99.9999" : 0.011077930709258041, + "100.0" : 0.011077930709258041 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010902821588371768, + 0.011077930709258041, + 0.010768575331933452 + ], + [ + 0.010373916702109782, + 0.010469903440535543, + 0.010386501569364673 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.112003459184257, + "scoreError" : 0.6079393498961505, + "scoreConfidence" : [ + 2.504064109288106, + 3.7199428090804076 + ], + "scorePercentiles" : { + "0.0" : 2.8907546849710983, + "50.0" : 3.1292498949334036, + "90.0" : 3.3149736335321407, + "95.0" : 3.3149736335321407, + "99.0" : 3.3149736335321407, + "99.9" : 3.3149736335321407, + "99.99" : 3.3149736335321407, + "99.999" : 3.3149736335321407, + "99.9999" : 3.3149736335321407, + "100.0" : 3.3149736335321407 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9612455393724098, + 2.8907546849710983, + 2.894516777199074 + ], + [ + 3.297254250494397, + 3.3149736335321407, + 3.3132758695364237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8207545568395553, + "scoreError" : 0.11667399366708205, + "scoreConfidence" : [ + 2.7040805631724734, + 2.9374285505066373 + ], + "scorePercentiles" : { + "0.0" : 2.762481432320442, + "50.0" : 2.8234998655820007, + "90.0" : 2.867837217665615, + "95.0" : 2.867837217665615, + "99.0" : 2.867837217665615, + "99.9" : 2.867837217665615, + "99.99" : 2.867837217665615, + "99.999" : 2.867837217665615, + "99.9999" : 2.867837217665615, + "100.0" : 2.867837217665615 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8584534615604458, + 2.8405730434535643, + 2.867837217665615 + ], + [ + 2.8064266877104376, + 2.7887554983268266, + 2.762481432320442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18638368530268346, + "scoreError" : 0.0055880202496070815, + "scoreConfidence" : [ + 0.18079566505307637, + 0.19197170555229054 + ], + "scorePercentiles" : { + "0.0" : 0.18364413492121792, + "50.0" : 0.18695337587567679, + "90.0" : 0.18823122295631223, + "95.0" : 0.18823122295631223, + "99.0" : 0.18823122295631223, + "99.9" : 0.18823122295631223, + "99.99" : 0.18823122295631223, + "99.999" : 0.18823122295631223, + "99.9999" : 0.18823122295631223, + "100.0" : 0.18823122295631223 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18364413492121792, + 0.18450805802583026, + 0.1859242331604291 + ], + [ + 0.18801194416138675, + 0.18823122295631223, + 0.18798251859092446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3254067043321544, + "scoreError" : 0.0061391009779280985, + "scoreConfidence" : [ + 0.3192676033542263, + 0.3315458053100825 + ], + "scorePercentiles" : { + "0.0" : 0.32295087608590345, + "50.0" : 0.325256886210932, + "90.0" : 0.32801790635352773, + "95.0" : 0.32801790635352773, + "99.0" : 0.32801790635352773, + "99.9" : 0.32801790635352773, + "99.99" : 0.32801790635352773, + "99.999" : 0.32801790635352773, + "99.9999" : 0.32801790635352773, + "100.0" : 0.32801790635352773 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3276230183462194, + 0.3262224295221008, + 0.32801790635352773 + ], + [ + 0.32333465278541174, + 0.32429134289976325, + 0.32295087608590345 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14446823374864848, + "scoreError" : 0.0021403571150723885, + "scoreConfidence" : [ + 0.1423278766335761, + 0.14660859086372086 + ], + "scorePercentiles" : { + "0.0" : 0.14374948436758808, + "50.0" : 0.14419529004207776, + "90.0" : 0.14591659226077566, + "95.0" : 0.14591659226077566, + "99.0" : 0.14591659226077566, + "99.9" : 0.14591659226077566, + "99.99" : 0.14591659226077566, + "99.999" : 0.14591659226077566, + "99.9999" : 0.14591659226077566, + "100.0" : 0.14591659226077566 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14423956228184048, + 0.14374948436758808, + 0.1441226171184804 + ], + [ + 0.14591659226077566, + 0.144151017802315, + 0.1446301286608912 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40163718657722763, + "scoreError" : 0.011186819812014649, + "scoreConfidence" : [ + 0.390450366765213, + 0.41282400638924227 + ], + "scorePercentiles" : { + "0.0" : 0.39663524792765636, + "50.0" : 0.402094487659547, + "90.0" : 0.40641478151670324, + "95.0" : 0.40641478151670324, + "99.0" : 0.40641478151670324, + "99.9" : 0.40641478151670324, + "99.99" : 0.40641478151670324, + "99.999" : 0.40641478151670324, + "99.9999" : 0.40641478151670324, + "100.0" : 0.40641478151670324 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40641478151670324, + 0.40458530015778615, + 0.404260301693819 + ], + [ + 0.39663524792765636, + 0.397998814542126, + 0.39992867362527496 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1570335688170079, + "scoreError" : 0.003486444475015119, + "scoreConfidence" : [ + 0.15354712434199277, + 0.160520013292023 + ], + "scorePercentiles" : { + "0.0" : 0.15588541739021994, + "50.0" : 0.1567182133609804, + "90.0" : 0.1592927673744405, + "95.0" : 0.1592927673744405, + "99.0" : 0.1592927673744405, + "99.9" : 0.1592927673744405, + "99.99" : 0.1592927673744405, + "99.999" : 0.1592927673744405, + "99.9999" : 0.1592927673744405, + "100.0" : 0.1592927673744405 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15630531289954516, + 0.15588541739021994, + 0.15622265226832469 + ], + [ + 0.1592927673744405, + 0.15713111382241565, + 0.1573641491471014 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.0476145327037237, + "scoreError" : 0.001935070857659329, + "scoreConfidence" : [ + 0.04567946184606437, + 0.04954960356138303 + ], + "scorePercentiles" : { + "0.0" : 0.04678782224031291, + "50.0" : 0.04779397925641198, + "90.0" : 0.048259524307968496, + "95.0" : 0.048259524307968496, + "99.0" : 0.048259524307968496, + "99.9" : 0.048259524307968496, + "99.99" : 0.048259524307968496, + "99.999" : 0.048259524307968496, + "99.9999" : 0.048259524307968496, + "100.0" : 0.048259524307968496 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04819725341713096, + 0.048259524307968496, + 0.048181327691373725 + ], + [ + 0.04740663082145024, + 0.04678782224031291, + 0.04685463774410585 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8841695.396501116, + "scoreError" : 316967.82965096884, + "scoreConfidence" : [ + 8524727.566850148, + 9158663.226152085 + ], + "scorePercentiles" : { + "0.0" : 8731610.221640488, + "50.0" : 8805257.730112758, + "90.0" : 9054428.724231465, + "95.0" : 9054428.724231465, + "99.0" : 9054428.724231465, + "99.9" : 9054428.724231465, + "99.99" : 9054428.724231465, + "99.999" : 9054428.724231465, + "99.9999" : 9054428.724231465, + "100.0" : 9054428.724231465 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9054428.724231465, + 8867938.558510639, + 8808936.27640845 + ], + [ + 8731610.221640488, + 8785679.414398596, + 8801579.183817063 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-16T00:59:40Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json b/performance-results/2025-09-16T00:59:40Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json new file mode 100644 index 0000000000..ca6ed9728c --- /dev/null +++ b/performance-results/2025-09-16T00:59:40Z-d5930735f094a27ffab6f6f92e364e432c72c8d8-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3513732215583074, + "scoreError" : 0.04329533128760706, + "scoreConfidence" : [ + 3.3080778902707, + 3.3946685528459146 + ], + "scorePercentiles" : { + "0.0" : 3.3450462120357662, + "50.0" : 3.34993514170585, + "90.0" : 3.360576390785763, + "95.0" : 3.360576390785763, + "99.0" : 3.360576390785763, + "99.9" : 3.360576390785763, + "99.99" : 3.360576390785763, + "99.999" : 3.360576390785763, + "99.9999" : 3.360576390785763, + "100.0" : 3.360576390785763 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3450462120357662, + 3.360576390785763 + ], + [ + 3.348231542999079, + 3.351638740412621 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6875759630004368, + "scoreError" : 0.029351828960631005, + "scoreConfidence" : [ + 1.6582241340398058, + 1.7169277919610677 + ], + "scorePercentiles" : { + "0.0" : 1.682027042664517, + "50.0" : 1.6880972764594329, + "90.0" : 1.6920822564183642, + "95.0" : 1.6920822564183642, + "99.0" : 1.6920822564183642, + "99.9" : 1.6920822564183642, + "99.99" : 1.6920822564183642, + "99.999" : 1.6920822564183642, + "99.9999" : 1.6920822564183642, + "100.0" : 1.6920822564183642 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6920822564183642, + 1.6903616498283525 + ], + [ + 1.682027042664517, + 1.6858329030905133 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8544711364734848, + "scoreError" : 0.02021196113868611, + "scoreConfidence" : [ + 0.8342591753347988, + 0.8746830976121709 + ], + "scorePercentiles" : { + "0.0" : 0.852189633376588, + "50.0" : 0.8534023271753635, + "90.0" : 0.8588902581666242, + "95.0" : 0.8588902581666242, + "99.0" : 0.8588902581666242, + "99.9" : 0.8588902581666242, + "99.99" : 0.8588902581666242, + "99.999" : 0.8588902581666242, + "99.9999" : 0.8588902581666242, + "100.0" : 0.8588902581666242 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.852189633376588, + 0.8588902581666242 + ], + [ + 0.8523226889597889, + 0.854481965390938 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.406256392178186, + "scoreError" : 0.516332672381059, + "scoreConfidence" : [ + 15.889923719797126, + 16.922589064559244 + ], + "scorePercentiles" : { + "0.0" : 16.227222090971747, + "50.0" : 16.40953911127422, + "90.0" : 16.58082036416752, + "95.0" : 16.58082036416752, + "99.0" : 16.58082036416752, + "99.9" : 16.58082036416752, + "99.99" : 16.58082036416752, + "99.999" : 16.58082036416752, + "99.9999" : 16.58082036416752, + "100.0" : 16.58082036416752 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.227222090971747, + 16.234592495932553, + 16.25341681996943 + ], + [ + 16.58082036416752, + 16.565661402579007, + 16.575825179448856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2790.794542202578, + "scoreError" : 205.75365189926077, + "scoreConfidence" : [ + 2585.0408903033176, + 2996.548194101839 + ], + "scorePercentiles" : { + "0.0" : 2719.1311592554384, + "50.0" : 2792.2965330302313, + "90.0" : 2857.8104575461466, + "95.0" : 2857.8104575461466, + "99.0" : 2857.8104575461466, + "99.9" : 2857.8104575461466, + "99.99" : 2857.8104575461466, + "99.999" : 2857.8104575461466, + "99.9999" : 2857.8104575461466, + "100.0" : 2857.8104575461466 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2725.5252434470494, + 2719.1311592554384, + 2726.9136721325312 + ], + [ + 2857.6793939279314, + 2857.8104575461466, + 2857.7073269063694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77367.53185838963, + "scoreError" : 1854.9656299200128, + "scoreConfidence" : [ + 75512.56622846962, + 79222.49748830964 + ], + "scorePercentiles" : { + "0.0" : 76728.84795612744, + "50.0" : 77381.47001218217, + "90.0" : 78008.60719901838, + "95.0" : 78008.60719901838, + "99.0" : 78008.60719901838, + "99.9" : 78008.60719901838, + "99.99" : 78008.60719901838, + "99.999" : 78008.60719901838, + "99.9999" : 78008.60719901838, + "100.0" : 78008.60719901838 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76728.84795612744, + 76741.55923091536, + 76823.83537687585 + ], + [ + 77939.10464748846, + 77963.23673991232, + 78008.60719901838 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 370.00153933618486, + "scoreError" : 12.537266739357735, + "scoreConfidence" : [ + 357.46427259682713, + 382.5388060755426 + ], + "scorePercentiles" : { + "0.0" : 365.4982943978104, + "50.0" : 369.97779722994096, + "90.0" : 374.3559521556015, + "95.0" : 374.3559521556015, + "99.0" : 374.3559521556015, + "99.9" : 374.3559521556015, + "99.99" : 374.3559521556015, + "99.999" : 374.3559521556015, + "99.9999" : 374.3559521556015, + "100.0" : 374.3559521556015 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 365.4982943978104, + 366.01715329841096, + 366.279802672377 + ], + [ + 374.3559521556015, + 374.18224170540446, + 373.67579178750486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.41140564861185, + "scoreError" : 3.859802086029224, + "scoreConfidence" : [ + 112.55160356258263, + 120.27120773464107 + ], + "scorePercentiles" : { + "0.0" : 114.85851580326698, + "50.0" : 116.4262762783896, + "90.0" : 117.8520412667565, + "95.0" : 117.8520412667565, + "99.0" : 117.8520412667565, + "99.9" : 117.8520412667565, + "99.99" : 117.8520412667565, + "99.999" : 117.8520412667565, + "99.9999" : 117.8520412667565, + "100.0" : 117.8520412667565 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.85851580326698, + 115.19520699238602, + 115.47237899539707 + ], + [ + 117.8520412667565, + 117.38017356138211, + 117.71011727248245 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06104651406060898, + "scoreError" : 6.400536445089513E-4, + "scoreConfidence" : [ + 0.060406460416100025, + 0.061686567705117934 + ], + "scorePercentiles" : { + "0.0" : 0.06080608401435, + "50.0" : 0.06100865473787888, + "90.0" : 0.06136843745742637, + "95.0" : 0.06136843745742637, + "99.0" : 0.06136843745742637, + "99.9" : 0.06136843745742637, + "99.99" : 0.06136843745742637, + "99.999" : 0.06136843745742637, + "99.9999" : 0.06136843745742637, + "100.0" : 0.06136843745742637 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06080608401435, + 0.060848982201966606, + 0.060907681657885925 + ], + [ + 0.06110962781787183, + 0.06136843745742637, + 0.06123827121415318 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.604555239205474E-4, + "scoreError" : 1.66167705428401E-6, + "scoreConfidence" : [ + 3.5879384686626336E-4, + 3.621172009748314E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5991789993936903E-4, + "50.0" : 3.601869040584312E-4, + "90.0" : 3.614226724555774E-4, + "95.0" : 3.614226724555774E-4, + "99.0" : 3.614226724555774E-4, + "99.9" : 3.614226724555774E-4, + "99.99" : 3.614226724555774E-4, + "99.999" : 3.614226724555774E-4, + "99.9999" : 3.614226724555774E-4, + "100.0" : 3.614226724555774E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.614226724555774E-4, + 3.609350589642829E-4, + 3.602837630229284E-4 + ], + [ + 3.6009004509393404E-4, + 3.6008370404719286E-4, + 3.5991789993936903E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.1240227049512289, + "scoreError" : 0.0010728537874539956, + "scoreConfidence" : [ + 0.12294985116377491, + 0.1250955587386829 + ], + "scorePercentiles" : { + "0.0" : 0.12351980975790514, + "50.0" : 0.12410367244722964, + "90.0" : 0.12440119361098671, + "95.0" : 0.12440119361098671, + "99.0" : 0.12440119361098671, + "99.9" : 0.12440119361098671, + "99.99" : 0.12440119361098671, + "99.999" : 0.12440119361098671, + "99.9999" : 0.12440119361098671, + "100.0" : 0.12440119361098671 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.12440119361098671, + 0.12432500437614999, + 0.12433855017593594 + ], + [ + 0.1238823405183093, + 0.12351980975790514, + 0.12366933126808637 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013119273161628411, + "scoreError" : 4.116480417793642E-4, + "scoreConfidence" : [ + 0.012707625119849048, + 0.013530921203407775 + ], + "scorePercentiles" : { + "0.0" : 0.012979875252292536, + "50.0" : 0.013113079751351026, + "90.0" : 0.013265673457719528, + "95.0" : 0.013265673457719528, + "99.0" : 0.013265673457719528, + "99.9" : 0.013265673457719528, + "99.99" : 0.013265673457719528, + "99.999" : 0.013265673457719528, + "99.9999" : 0.013265673457719528, + "100.0" : 0.013265673457719528 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013258037430943071, + 0.013265673457719528, + 0.013235064416909968 + ], + [ + 0.012991095085792083, + 0.012979875252292536, + 0.012985893326113267 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9746988448511705, + "scoreError" : 0.03492745536145124, + "scoreConfidence" : [ + 0.9397713894897193, + 1.0096263002126218 + ], + "scorePercentiles" : { + "0.0" : 0.9631206886556241, + "50.0" : 0.9739622614443544, + "90.0" : 0.9886826281759763, + "95.0" : 0.9886826281759763, + "99.0" : 0.9886826281759763, + "99.9" : 0.9886826281759763, + "99.99" : 0.9886826281759763, + "99.999" : 0.9886826281759763, + "99.9999" : 0.9886826281759763, + "100.0" : 0.9886826281759763 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9631206886556241, + 0.9635264435880143, + 0.9635861025146931 + ], + [ + 0.9886826281759763, + 0.9849387857987, + 0.9843384203740158 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010564458236843223, + "scoreError" : 8.613505510968865E-4, + "scoreConfidence" : [ + 0.009703107685746335, + 0.01142580878794011 + ], + "scorePercentiles" : { + "0.0" : 0.010278222846665214, + "50.0" : 0.010564007460520504, + "90.0" : 0.010847722520165403, + "95.0" : 0.010847722520165403, + "99.0" : 0.010847722520165403, + "99.9" : 0.010847722520165403, + "99.99" : 0.010847722520165403, + "99.999" : 0.010847722520165403, + "99.9999" : 0.010847722520165403, + "100.0" : 0.010847722520165403 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010278222846665214, + 0.010286831047316133, + 0.010287181086875121 + ], + [ + 0.010840833834165887, + 0.010847722520165403, + 0.010845958085871578 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0281197261660853, + "scoreError" : 0.027418555531521838, + "scoreConfidence" : [ + 3.0007011706345637, + 3.055538281697607 + ], + "scorePercentiles" : { + "0.0" : 3.011746446718844, + "50.0" : 3.0315825912890233, + "90.0" : 3.0367838816029145, + "95.0" : 3.0367838816029145, + "99.0" : 3.0367838816029145, + "99.9" : 3.0367838816029145, + "99.99" : 3.0367838816029145, + "99.999" : 3.0367838816029145, + "99.9999" : 3.0367838816029145, + "100.0" : 3.0367838816029145 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0367838816029145, + 3.0352256128640778, + 3.0347776547330096 + ], + [ + 3.011746446718844, + 3.0283875278450365, + 3.0217972332326286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6931020252481033, + "scoreError" : 0.0664020739179938, + "scoreConfidence" : [ + 2.6266999513301093, + 2.7595040991660973 + ], + "scorePercentiles" : { + "0.0" : 2.6701982106246662, + "50.0" : 2.6910557346573443, + "90.0" : 2.717999886956522, + "95.0" : 2.717999886956522, + "99.0" : 2.717999886956522, + "99.9" : 2.717999886956522, + "99.99" : 2.717999886956522, + "99.999" : 2.717999886956522, + "99.9999" : 2.717999886956522, + "100.0" : 2.717999886956522 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.717999886956522, + 2.716125870994025, + 2.7095326505012194 + ], + [ + 2.6701982106246662, + 2.672176713598718, + 2.6725788188134687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1767129632125861, + "scoreError" : 4.0776604955034814E-4, + "scoreConfidence" : [ + 0.17630519716303575, + 0.17712072926213643 + ], + "scorePercentiles" : { + "0.0" : 0.17657777536065544, + "50.0" : 0.1766553243992964, + "90.0" : 0.17694014763438196, + "95.0" : 0.17694014763438196, + "99.0" : 0.17694014763438196, + "99.9" : 0.17694014763438196, + "99.99" : 0.17694014763438196, + "99.999" : 0.17694014763438196, + "99.9999" : 0.17694014763438196, + "100.0" : 0.17694014763438196 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17668325992932862, + 0.17684156605775522, + 0.17662738886926418 + ], + [ + 0.1766076414241311, + 0.17694014763438196, + 0.17657777536065544 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3306563734192656, + "scoreError" : 0.004978490231674825, + "scoreConfidence" : [ + 0.3256778831875908, + 0.3356348636509405 + ], + "scorePercentiles" : { + "0.0" : 0.32896239865131577, + "50.0" : 0.33065394551089033, + "90.0" : 0.3324176407938038, + "95.0" : 0.3324176407938038, + "99.0" : 0.3324176407938038, + "99.9" : 0.3324176407938038, + "99.99" : 0.3324176407938038, + "99.999" : 0.3324176407938038, + "99.9999" : 0.3324176407938038, + "100.0" : 0.3324176407938038 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3322135199654508, + 0.3321934985384002, + 0.3324176407938038 + ], + [ + 0.3290367900832428, + 0.3291143924833805, + 0.32896239865131577 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14468580073601847, + "scoreError" : 8.665055195461925E-4, + "scoreConfidence" : [ + 0.14381929521647227, + 0.14555230625556467 + ], + "scorePercentiles" : { + "0.0" : 0.14435711028668766, + "50.0" : 0.14467398004191673, + "90.0" : 0.14514446807645975, + "95.0" : 0.14514446807645975, + "99.0" : 0.14514446807645975, + "99.9" : 0.14514446807645975, + "99.99" : 0.14514446807645975, + "99.999" : 0.14514446807645975, + "99.9999" : 0.14514446807645975, + "100.0" : 0.14514446807645975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14457854163775155, + 0.1447694184460819, + 0.14489230087803182 + ], + [ + 0.14514446807645975, + 0.14435711028668766, + 0.1443729650910981 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3971566388062775, + "scoreError" : 0.03094666276265523, + "scoreConfidence" : [ + 0.36620997604362227, + 0.4281033015689327 + ], + "scorePercentiles" : { + "0.0" : 0.3869390483265622, + "50.0" : 0.39663725734745137, + "90.0" : 0.4089756738917062, + "95.0" : 0.4089756738917062, + "99.0" : 0.4089756738917062, + "99.9" : 0.4089756738917062, + "99.99" : 0.4089756738917062, + "99.999" : 0.4089756738917062, + "99.9999" : 0.4089756738917062, + "100.0" : 0.4089756738917062 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3869390483265622, + 0.3872197171067916, + 0.3872112840825493 + ], + [ + 0.4089756738917062, + 0.4065393118419448, + 0.4060547975881111 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15523795084849243, + "scoreError" : 0.0031123120636527965, + "scoreConfidence" : [ + 0.15212563878483965, + 0.1583502629121452 + ], + "scorePercentiles" : { + "0.0" : 0.15415504040326186, + "50.0" : 0.15520149828633079, + "90.0" : 0.15648289713015992, + "95.0" : 0.15648289713015992, + "99.0" : 0.15648289713015992, + "99.9" : 0.15648289713015992, + "99.99" : 0.15648289713015992, + "99.999" : 0.15648289713015992, + "99.9999" : 0.15648289713015992, + "100.0" : 0.15648289713015992 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1543426213171176, + 0.15420479611410948, + 0.15415504040326186 + ], + [ + 0.15648289713015992, + 0.15606037525554395, + 0.1561819748707617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046699934113078524, + "scoreError" : 0.0023132303334222858, + "scoreConfidence" : [ + 0.04438670377965624, + 0.049013164446500807 + ], + "scorePercentiles" : { + "0.0" : 0.04591798964106473, + "50.0" : 0.04672285355758983, + "90.0" : 0.04746917375288963, + "95.0" : 0.04746917375288963, + "99.0" : 0.04746917375288963, + "99.9" : 0.04746917375288963, + "99.99" : 0.04746917375288963, + "99.999" : 0.04746917375288963, + "99.9999" : 0.04746917375288963, + "100.0" : 0.04746917375288963 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045922329589184525, + 0.04600197062814822, + 0.04591798964106473 + ], + [ + 0.04744373648703144, + 0.04746917375288963, + 0.04744440458015267 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8514371.258650241, + "scoreError" : 137220.36361009316, + "scoreConfidence" : [ + 8377150.895040148, + 8651591.622260334 + ], + "scorePercentiles" : { + "0.0" : 8463827.32994924, + "50.0" : 8502923.55567645, + "90.0" : 8582671.80703259, + "95.0" : 8582671.80703259, + "99.0" : 8582671.80703259, + "99.9" : 8582671.80703259, + "99.99" : 8582671.80703259, + "99.999" : 8582671.80703259, + "99.9999" : 8582671.80703259, + "100.0" : 8582671.80703259 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8463827.32994924, + 8477749.911864407, + 8476876.011864407 + ], + [ + 8582671.80703259, + 8557005.29170231, + 8528097.19948849 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-22T06:49:47Z-e6ca15a18f62837564202a548f294c32aa3ca28f-jdk17.json b/performance-results/2025-09-22T06:49:47Z-e6ca15a18f62837564202a548f294c32aa3ca28f-jdk17.json new file mode 100644 index 0000000000..cc943175a6 --- /dev/null +++ b/performance-results/2025-09-22T06:49:47Z-e6ca15a18f62837564202a548f294c32aa3ca28f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3496359760769683, + "scoreError" : 0.029788854925604347, + "scoreConfidence" : [ + 3.319847121151364, + 3.3794248310025727 + ], + "scorePercentiles" : { + "0.0" : 3.343058943697042, + "50.0" : 3.35086586116409, + "90.0" : 3.353753238282651, + "95.0" : 3.353753238282651, + "99.0" : 3.353753238282651, + "99.9" : 3.353753238282651, + "99.99" : 3.353753238282651, + "99.999" : 3.353753238282651, + "99.9999" : 3.353753238282651, + "100.0" : 3.353753238282651 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.343058943697042, + 3.351374753228679 + ], + [ + 3.3503569690995008, + 3.353753238282651 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.697293564229039, + "scoreError" : 0.01614358808624621, + "scoreConfidence" : [ + 1.6811499761427928, + 1.7134371523152852 + ], + "scorePercentiles" : { + "0.0" : 1.6938488115852268, + "50.0" : 1.6977982046674653, + "90.0" : 1.6997290359959976, + "95.0" : 1.6997290359959976, + "99.0" : 1.6997290359959976, + "99.9" : 1.6997290359959976, + "99.99" : 1.6997290359959976, + "99.999" : 1.6997290359959976, + "99.9999" : 1.6997290359959976, + "100.0" : 1.6997290359959976 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6938488115852268, + 1.6982545015866084 + ], + [ + 1.6973419077483225, + 1.6997290359959976 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8520049747056817, + "scoreError" : 0.030893589196560628, + "scoreConfidence" : [ + 0.8211113855091211, + 0.8828985639022423 + ], + "scorePercentiles" : { + "0.0" : 0.8474798972464561, + "50.0" : 0.8511394310643619, + "90.0" : 0.8582611394475472, + "95.0" : 0.8582611394475472, + "99.0" : 0.8582611394475472, + "99.9" : 0.8582611394475472, + "99.99" : 0.8582611394475472, + "99.999" : 0.8582611394475472, + "99.9999" : 0.8582611394475472, + "100.0" : 0.8582611394475472 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8530700245322967, + 0.8582611394475472 + ], + [ + 0.8474798972464561, + 0.8492088375964268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.485860471979176, + "scoreError" : 0.03824936393164474, + "scoreConfidence" : [ + 16.447611108047532, + 16.52410983591082 + ], + "scorePercentiles" : { + "0.0" : 16.470186216833234, + "50.0" : 16.48226527396083, + "90.0" : 16.502570084543326, + "95.0" : 16.502570084543326, + "99.0" : 16.502570084543326, + "99.9" : 16.502570084543326, + "99.99" : 16.502570084543326, + "99.999" : 16.502570084543326, + "99.9999" : 16.502570084543326, + "100.0" : 16.502570084543326 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.475557891676782, + 16.502570084543326, + 16.502318090900054 + ], + [ + 16.470186216833234, + 16.48114282263713, + 16.483387725284533 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2708.268536915973, + "scoreError" : 36.22216052793814, + "scoreConfidence" : [ + 2672.046376388035, + 2744.4906974439114 + ], + "scorePercentiles" : { + "0.0" : 2694.8842638461924, + "50.0" : 2708.0160123297355, + "90.0" : 2721.595279935854, + "95.0" : 2721.595279935854, + "99.0" : 2721.595279935854, + "99.9" : 2721.595279935854, + "99.99" : 2721.595279935854, + "99.999" : 2721.595279935854, + "99.9999" : 2721.595279935854, + "100.0" : 2721.595279935854 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2694.8842638461924, + 2696.2368011489557, + 2698.688130371997 + ], + [ + 2717.3438942874736, + 2721.595279935854, + 2720.8628519053696 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 75945.7787225041, + "scoreError" : 1641.990158273962, + "scoreConfidence" : [ + 74303.78856423014, + 77587.76888077805 + ], + "scorePercentiles" : { + "0.0" : 75367.44129599974, + "50.0" : 75953.8848213015, + "90.0" : 76492.38929076183, + "95.0" : 76492.38929076183, + "99.0" : 76492.38929076183, + "99.9" : 76492.38929076183, + "99.99" : 76492.38929076183, + "99.999" : 76492.38929076183, + "99.9999" : 76492.38929076183, + "100.0" : 76492.38929076183 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76492.38929076183, + 76474.04136730185, + 76473.00932650767 + ], + [ + 75367.44129599974, + 75433.03073835814, + 75434.76031609531 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 343.77591293827754, + "scoreError" : 2.8901245861991076, + "scoreConfidence" : [ + 340.8857883520784, + 346.6660375244767 + ], + "scorePercentiles" : { + "0.0" : 342.56633371119176, + "50.0" : 343.6449839679681, + "90.0" : 345.59208372253556, + "95.0" : 345.59208372253556, + "99.0" : 345.59208372253556, + "99.9" : 345.59208372253556, + "99.99" : 345.59208372253556, + "99.999" : 345.59208372253556, + "99.9999" : 345.59208372253556, + "100.0" : 345.59208372253556 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.59208372253556, + 343.1261078956025, + 344.0809843643991 + ], + [ + 342.56633371119176, + 343.64546775983484, + 343.64450017610136 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.32659320091456, + "scoreError" : 2.960395654273195, + "scoreConfidence" : [ + 111.36619754664136, + 117.28698885518776 + ], + "scorePercentiles" : { + "0.0" : 112.65183532479064, + "50.0" : 114.83129812160851, + "90.0" : 115.29110592527894, + "95.0" : 115.29110592527894, + "99.0" : 115.29110592527894, + "99.9" : 115.29110592527894, + "99.99" : 115.29110592527894, + "99.999" : 115.29110592527894, + "99.9999" : 115.29110592527894, + "100.0" : 115.29110592527894 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.37669102214478, + 112.65183532479064, + 115.29110592527894 + ], + [ + 114.7977916119232, + 114.86480463129382, + 114.97733069005595 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06159744638230849, + "scoreError" : 0.001637280741300189, + "scoreConfidence" : [ + 0.059960165641008305, + 0.06323472712360868 + ], + "scorePercentiles" : { + "0.0" : 0.06102665141427394, + "50.0" : 0.061625093759965575, + "90.0" : 0.062142634860367134, + "95.0" : 0.062142634860367134, + "99.0" : 0.062142634860367134, + "99.9" : 0.062142634860367134, + "99.99" : 0.062142634860367134, + "99.999" : 0.062142634860367134, + "99.9999" : 0.062142634860367134, + "100.0" : 0.062142634860367134 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06213141885779611, + 0.06211351735425285, + 0.062142634860367134 + ], + [ + 0.0610337856414826, + 0.0611366701656783, + 0.06102665141427394 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.739469346231514E-4, + "scoreError" : 1.4079256770433099E-5, + "scoreConfidence" : [ + 3.598676778527183E-4, + 3.880261913935845E-4 + ], + "scorePercentiles" : { + "0.0" : 3.684522013233481E-4, + "50.0" : 3.741899766392553E-4, + "90.0" : 3.785810440056022E-4, + "95.0" : 3.785810440056022E-4, + "99.0" : 3.785810440056022E-4, + "99.9" : 3.785810440056022E-4, + "99.99" : 3.785810440056022E-4, + "99.999" : 3.785810440056022E-4, + "99.9999" : 3.785810440056022E-4, + "100.0" : 3.785810440056022E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7843791332732303E-4, + 3.785810440056022E-4, + 3.784986528433399E-4 + ], + [ + 3.6994203995118754E-4, + 3.697697562881073E-4, + 3.684522013233481E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.521398443060576, + "scoreError" : 0.08910038705621467, + "scoreConfidence" : [ + 2.432298056004361, + 2.6104988301167906 + ], + "scorePercentiles" : { + "0.0" : 2.4864232282446546, + "50.0" : 2.51697658935123, + "90.0" : 2.5723473112139916, + "95.0" : 2.5723473112139916, + "99.0" : 2.5723473112139916, + "99.9" : 2.5723473112139916, + "99.99" : 2.5723473112139916, + "99.999" : 2.5723473112139916, + "99.9999" : 2.5723473112139916, + "100.0" : 2.5723473112139916 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.5398777447943117, + 2.495789195408036, + 2.4864232282446546 + ], + [ + 2.5723473112139916, + 2.5267867046488126, + 2.5071664740536477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013080461824156937, + "scoreError" : 8.680639739726075E-5, + "scoreConfidence" : [ + 0.012993655426759676, + 0.013167268221554198 + ], + "scorePercentiles" : { + "0.0" : 0.013051508657604688, + "50.0" : 0.013078615058292987, + "90.0" : 0.013114501506180124, + "95.0" : 0.013114501506180124, + "99.0" : 0.013114501506180124, + "99.9" : 0.013114501506180124, + "99.99" : 0.013114501506180124, + "99.999" : 0.013114501506180124, + "99.9999" : 0.013114501506180124, + "100.0" : 0.013114501506180124 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013103365944549925, + 0.013114501506180124, + 0.01310770615436641 + ], + [ + 0.013053864172036049, + 0.013051508657604688, + 0.013051824510204427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.1120725154260704, + "scoreError" : 0.2997884248803559, + "scoreConfidence" : [ + 0.8122840905457145, + 1.4118609403064264 + ], + "scorePercentiles" : { + "0.0" : 1.0134889811511958, + "50.0" : 1.1122757973107193, + "90.0" : 1.2105479820844933, + "95.0" : 1.2105479820844933, + "99.0" : 1.2105479820844933, + "99.9" : 1.2105479820844933, + "99.99" : 1.2105479820844933, + "99.999" : 1.2105479820844933, + "99.9999" : 1.2105479820844933, + "100.0" : 1.2105479820844933 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.2092566726723095, + 1.2091833881030105, + 1.2105479820844933 + ], + [ + 1.0134889811511958, + 1.0153682065184282, + 1.014589862026986 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010576567943549407, + "scoreError" : 8.01183711594851E-4, + "scoreConfidence" : [ + 0.009775384231954556, + 0.011377751655144258 + ], + "scorePercentiles" : { + "0.0" : 0.010312777170942587, + "50.0" : 0.01057730979818363, + "90.0" : 0.010839297513960667, + "95.0" : 0.010839297513960667, + "99.0" : 0.010839297513960667, + "99.9" : 0.010839297513960667, + "99.99" : 0.010839297513960667, + "99.999" : 0.010839297513960667, + "99.9999" : 0.010839297513960667, + "100.0" : 0.010839297513960667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010833619389952724, + 0.010839175763382773, + 0.010839297513960667 + ], + [ + 0.010313537616643153, + 0.010321000206414539, + 0.010312777170942587 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1242275525570045, + "scoreError" : 0.09976646116987556, + "scoreConfidence" : [ + 3.024461091387129, + 3.22399401372688 + ], + "scorePercentiles" : { + "0.0" : 3.0899167770228537, + "50.0" : 3.117203892057417, + "90.0" : 3.1720970196575777, + "95.0" : 3.1720970196575777, + "99.0" : 3.1720970196575777, + "99.9" : 3.1720970196575777, + "99.99" : 3.1720970196575777, + "99.999" : 3.1720970196575777, + "99.9999" : 3.1720970196575777, + "100.0" : 3.1720970196575777 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0899167770228537, + 3.102748251240695, + 3.09024156145769 + ], + [ + 3.131659532874139, + 3.1720970196575777, + 3.1587021730890714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8942256093892915, + "scoreError" : 0.1132928813899829, + "scoreConfidence" : [ + 2.780932727999309, + 3.0075184907792742 + ], + "scorePercentiles" : { + "0.0" : 2.8483187761321562, + "50.0" : 2.891599411155812, + "90.0" : 2.9406392446339313, + "95.0" : 2.9406392446339313, + "99.0" : 2.9406392446339313, + "99.9" : 2.9406392446339313, + "99.99" : 2.9406392446339313, + "99.999" : 2.9406392446339313, + "99.9999" : 2.9406392446339313, + "100.0" : 2.9406392446339313 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.862741448769319, + 2.8634743844832524, + 2.8483187761321562 + ], + [ + 2.9406392446339313, + 2.9304553644887195, + 2.9197244378283713 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18359464893897617, + "scoreError" : 0.026735088381444335, + "scoreConfidence" : [ + 0.15685956055753184, + 0.2103297373204205 + ], + "scorePercentiles" : { + "0.0" : 0.17404164472058337, + "50.0" : 0.1838341954352512, + "90.0" : 0.192449687739353, + "95.0" : 0.192449687739353, + "99.0" : 0.192449687739353, + "99.9" : 0.192449687739353, + "99.99" : 0.192449687739353, + "99.999" : 0.192449687739353, + "99.9999" : 0.192449687739353, + "100.0" : 0.192449687739353 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17554534597222954, + 0.17404164472058337, + 0.1751231626506024 + ], + [ + 0.192449687739353, + 0.19228500765281598, + 0.19212304489827284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3291284158749855, + "scoreError" : 0.02890070010517245, + "scoreConfidence" : [ + 0.30022771576981305, + 0.3580291159801579 + ], + "scorePercentiles" : { + "0.0" : 0.3196283847284815, + "50.0" : 0.32861018854278434, + "90.0" : 0.33912732657352146, + "95.0" : 0.33912732657352146, + "99.0" : 0.33912732657352146, + "99.9" : 0.33912732657352146, + "99.99" : 0.33912732657352146, + "99.999" : 0.33912732657352146, + "99.9999" : 0.33912732657352146, + "100.0" : 0.33912732657352146 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3373141362026512, + 0.33910977202441506, + 0.33912732657352146 + ], + [ + 0.3196283847284815, + 0.319684634837926, + 0.31990624088291747 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1479364146788637, + "scoreError" : 0.009020044394819867, + "scoreConfidence" : [ + 0.13891637028404383, + 0.15695645907368358 + ], + "scorePercentiles" : { + "0.0" : 0.14518249499128918, + "50.0" : 0.14735536607677147, + "90.0" : 0.15293019727485435, + "95.0" : 0.15293019727485435, + "99.0" : 0.15293019727485435, + "99.9" : 0.15293019727485435, + "99.99" : 0.15293019727485435, + "99.999" : 0.15293019727485435, + "99.9999" : 0.15293019727485435, + "100.0" : 0.15293019727485435 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15293019727485435, + 0.14958367144823048, + 0.14940442916903218 + ], + [ + 0.14521139220526522, + 0.14518249499128918, + 0.14530630298451078 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.39726246744718513, + "scoreError" : 0.009123819141630388, + "scoreConfidence" : [ + 0.3881386483055547, + 0.40638628658881554 + ], + "scorePercentiles" : { + "0.0" : 0.3947651694694458, + "50.0" : 0.3953507804131454, + "90.0" : 0.40206225666385237, + "95.0" : 0.40206225666385237, + "99.0" : 0.40206225666385237, + "99.9" : 0.40206225666385237, + "99.99" : 0.40206225666385237, + "99.999" : 0.40206225666385237, + "99.9999" : 0.40206225666385237, + "100.0" : 0.40206225666385237 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39526718150197626, + 0.39531371629046924, + 0.3947651694694458 + ], + [ + 0.40206225666385237, + 0.40077863622154536, + 0.3953878445358216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15360524371981474, + "scoreError" : 0.002750173499502835, + "scoreConfidence" : [ + 0.15085507022031192, + 0.15635541721931756 + ], + "scorePercentiles" : { + "0.0" : 0.1516243314734512, + "50.0" : 0.15395947178698044, + "90.0" : 0.15416787229056825, + "95.0" : 0.15416787229056825, + "99.0" : 0.15416787229056825, + "99.9" : 0.15416787229056825, + "99.99" : 0.15416787229056825, + "99.999" : 0.15416787229056825, + "99.9999" : 0.15416787229056825, + "100.0" : 0.15416787229056825 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15416787229056825, + 0.1538382793981909, + 0.1538252192893401 + ], + [ + 0.15408066417577, + 0.15409509569156804, + 0.1516243314734512 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04662359449964403, + "scoreError" : 0.0017915052564357013, + "scoreConfidence" : [ + 0.044832089243208334, + 0.04841509975607973 + ], + "scorePercentiles" : { + "0.0" : 0.0460147077878753, + "50.0" : 0.04660958504281068, + "90.0" : 0.04731384416960796, + "95.0" : 0.04731384416960796, + "99.0" : 0.04731384416960796, + "99.9" : 0.04731384416960796, + "99.99" : 0.04731384416960796, + "99.999" : 0.04731384416960796, + "99.9999" : 0.04731384416960796, + "100.0" : 0.04731384416960796 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04731384416960796, + 0.04715483416796341, + 0.0471430772853486 + ], + [ + 0.04603901078679619, + 0.0460147077878753, + 0.046076092800272764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8751847.78459636, + "scoreError" : 215597.68497896375, + "scoreConfidence" : [ + 8536250.099617396, + 8967445.469575323 + ], + "scorePercentiles" : { + "0.0" : 8678622.612315698, + "50.0" : 8750421.270949967, + "90.0" : 8833320.883495146, + "95.0" : 8833320.883495146, + "99.0" : 8833320.883495146, + "99.9" : 8833320.883495146, + "99.99" : 8833320.883495146, + "99.999" : 8833320.883495146, + "99.9999" : 8833320.883495146, + "100.0" : 8833320.883495146 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8686107.290798612, + 8678622.612315698, + 8681088.158854166 + ], + [ + 8833320.883495146, + 8814735.251101322, + 8817212.511013215 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-22T21:17:24Z-8e4f4596733814ad92020cfcc5171448a0be2e1a-jdk17.json b/performance-results/2025-09-22T21:17:24Z-8e4f4596733814ad92020cfcc5171448a0be2e1a-jdk17.json new file mode 100644 index 0000000000..d28d866358 --- /dev/null +++ b/performance-results/2025-09-22T21:17:24Z-8e4f4596733814ad92020cfcc5171448a0be2e1a-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.314022811691902, + "scoreError" : 0.0541966896066759, + "scoreConfidence" : [ + 3.2598261220852263, + 3.368219501298578 + ], + "scorePercentiles" : { + "0.0" : 3.304194048355106, + "50.0" : 3.313707183089784, + "90.0" : 3.324482832232933, + "95.0" : 3.324482832232933, + "99.0" : 3.324482832232933, + "99.9" : 3.324482832232933, + "99.99" : 3.324482832232933, + "99.999" : 3.324482832232933, + "99.9999" : 3.324482832232933, + "100.0" : 3.324482832232933 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.304194048355106, + 3.3152578813872067 + ], + [ + 3.312156484792362, + 3.324482832232933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6712603261970465, + "scoreError" : 0.018142346406554506, + "scoreConfidence" : [ + 1.653117979790492, + 1.6894026726036009 + ], + "scorePercentiles" : { + "0.0" : 1.668586385117959, + "50.0" : 1.6708547696159761, + "90.0" : 1.6747453804382741, + "95.0" : 1.6747453804382741, + "99.0" : 1.6747453804382741, + "99.9" : 1.6747453804382741, + "99.99" : 1.6747453804382741, + "99.999" : 1.6747453804382741, + "99.9999" : 1.6747453804382741, + "100.0" : 1.6747453804382741 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6694365904564337, + 1.6747453804382741 + ], + [ + 1.668586385117959, + 1.6722729487755186 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8394464879842283, + "scoreError" : 0.02129677653453746, + "scoreConfidence" : [ + 0.8181497114496908, + 0.8607432645187657 + ], + "scorePercentiles" : { + "0.0" : 0.8354426843180475, + "50.0" : 0.8397314013517216, + "90.0" : 0.8428804649154225, + "95.0" : 0.8428804649154225, + "99.0" : 0.8428804649154225, + "99.9" : 0.8428804649154225, + "99.99" : 0.8428804649154225, + "99.999" : 0.8428804649154225, + "99.9999" : 0.8428804649154225, + "100.0" : 0.8428804649154225 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8354426843180475, + 0.8428804649154225 + ], + [ + 0.841247962885109, + 0.8382148398183343 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.011288148980004, + "scoreError" : 0.5018285430660081, + "scoreConfidence" : [ + 15.509459605913996, + 16.51311669204601 + ], + "scorePercentiles" : { + "0.0" : 15.777353748640426, + "50.0" : 16.025052167576717, + "90.0" : 16.20868747168987, + "95.0" : 16.20868747168987, + "99.0" : 16.20868747168987, + "99.9" : 16.20868747168987, + "99.99" : 16.20868747168987, + "99.999" : 16.20868747168987, + "99.9999" : 16.20868747168987, + "100.0" : 16.20868747168987 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.20868747168987, + 16.179384309471292, + 16.104082184327684 + ], + [ + 15.777353748640426, + 15.852199028925018, + 15.946022150825748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2733.465575211411, + "scoreError" : 151.73841292032816, + "scoreConfidence" : [ + 2581.7271622910825, + 2885.203988131739 + ], + "scorePercentiles" : { + "0.0" : 2674.5303194476496, + "50.0" : 2737.309498514745, + "90.0" : 2790.6696012687553, + "95.0" : 2790.6696012687553, + "99.0" : 2790.6696012687553, + "99.9" : 2790.6696012687553, + "99.99" : 2790.6696012687553, + "99.999" : 2790.6696012687553, + "99.9999" : 2790.6696012687553, + "100.0" : 2790.6696012687553 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2790.6696012687553, + 2785.7195478920985, + 2766.8564123439705 + ], + [ + 2707.7625846855194, + 2674.5303194476496, + 2675.2549856304727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76531.1384609008, + "scoreError" : 515.4412416679229, + "scoreConfidence" : [ + 76015.69721923287, + 77046.57970256872 + ], + "scorePercentiles" : { + "0.0" : 76376.08383147985, + "50.0" : 76465.40591084602, + "90.0" : 76871.28084055861, + "95.0" : 76871.28084055861, + "99.0" : 76871.28084055861, + "99.9" : 76871.28084055861, + "99.99" : 76871.28084055861, + "99.999" : 76871.28084055861, + "99.9999" : 76871.28084055861, + "100.0" : 76871.28084055861 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76473.19417101903, + 76601.77884466675, + 76871.28084055861 + ], + [ + 76457.61765067301, + 76376.08383147985, + 76406.87542700753 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 337.7922444590617, + "scoreError" : 4.036389849878064, + "scoreConfidence" : [ + 333.75585460918364, + 341.82863430893974 + ], + "scorePercentiles" : { + "0.0" : 335.7420165479613, + "50.0" : 337.7801406204766, + "90.0" : 339.61496363944684, + "95.0" : 339.61496363944684, + "99.0" : 339.61496363944684, + "99.9" : 339.61496363944684, + "99.99" : 339.61496363944684, + "99.999" : 339.61496363944684, + "99.9999" : 339.61496363944684, + "100.0" : 339.61496363944684 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 335.7420165479613, + 337.3824893427294, + 336.80328909107857 + ], + [ + 339.03291623493044, + 338.1777918982238, + 339.61496363944684 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.73988583126498, + "scoreError" : 7.837746310010851, + "scoreConfidence" : [ + 99.90213952125413, + 115.57763214127584 + ], + "scorePercentiles" : { + "0.0" : 104.42290378696231, + "50.0" : 108.02725454189343, + "90.0" : 111.64004355831095, + "95.0" : 111.64004355831095, + "99.0" : 111.64004355831095, + "99.9" : 111.64004355831095, + "99.99" : 111.64004355831095, + "99.999" : 111.64004355831095, + "99.9999" : 111.64004355831095, + "100.0" : 111.64004355831095 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 104.42290378696231, + 109.56750571822366, + 108.4899662186823 + ], + [ + 104.75435284030613, + 107.56454286510457, + 111.64004355831095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06224595222351487, + "scoreError" : 6.995150499724861E-4, + "scoreConfidence" : [ + 0.06154643717354238, + 0.06294546727348735 + ], + "scorePercentiles" : { + "0.0" : 0.0618431342098428, + "50.0" : 0.06223886530851824, + "90.0" : 0.06260241496547536, + "95.0" : 0.06260241496547536, + "99.0" : 0.06260241496547536, + "99.9" : 0.06260241496547536, + "99.99" : 0.06260241496547536, + "99.999" : 0.06260241496547536, + "99.9999" : 0.06260241496547536, + "100.0" : 0.06260241496547536 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06237238086446704, + 0.06226513855646738, + 0.06260241496547536 + ], + [ + 0.0618431342098428, + 0.06218005268426747, + 0.06221259206056911 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7179579434428334E-4, + "scoreError" : 8.041842088100423E-6, + "scoreConfidence" : [ + 3.637539522561829E-4, + 3.798376364323838E-4 + ], + "scorePercentiles" : { + "0.0" : 3.667811652424725E-4, + "50.0" : 3.720500442273067E-4, + "90.0" : 3.7544620580236553E-4, + "95.0" : 3.7544620580236553E-4, + "99.0" : 3.7544620580236553E-4, + "99.9" : 3.7544620580236553E-4, + "99.99" : 3.7544620580236553E-4, + "99.999" : 3.7544620580236553E-4, + "99.9999" : 3.7544620580236553E-4, + "100.0" : 3.7544620580236553E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7544620580236553E-4, + 3.71340739322794E-4, + 3.667811652424725E-4 + ], + [ + 3.7150468125177785E-4, + 3.731065672434549E-4, + 3.7259540720283556E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6065140423547306, + "scoreError" : 0.0878324362403623, + "scoreConfidence" : [ + 2.5186816061143684, + 2.694346478595093 + ], + "scorePercentiles" : { + "0.0" : 2.5654608116983066, + "50.0" : 2.600502211316018, + "90.0" : 2.6559617652681893, + "95.0" : 2.6559617652681893, + "99.0" : 2.6559617652681893, + "99.9" : 2.6559617652681893, + "99.99" : 2.6559617652681893, + "99.999" : 2.6559617652681893, + "99.9999" : 2.6559617652681893, + "100.0" : 2.6559617652681893 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.5951435586403737, + 2.6058608639916625, + 2.62619703282563 + ], + [ + 2.6559617652681893, + 2.590460221704222, + 2.5654608116983066 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013068189520707547, + "scoreError" : 4.758208011554296E-5, + "scoreConfidence" : [ + 0.013020607440592004, + 0.013115771600823091 + ], + "scorePercentiles" : { + "0.0" : 0.013047852657811644, + "50.0" : 0.013066306973347515, + "90.0" : 0.013089392061414417, + "95.0" : 0.013089392061414417, + "99.0" : 0.013089392061414417, + "99.9" : 0.013089392061414417, + "99.99" : 0.013089392061414417, + "99.999" : 0.013089392061414417, + "99.9999" : 0.013089392061414417, + "100.0" : 0.013089392061414417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013047852657811644, + 0.013069138335855636, + 0.013053069020969437 + ], + [ + 0.013063475610839394, + 0.013089392061414417, + 0.013086209437354746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0458713106870163, + "scoreError" : 0.2555485889654377, + "scoreConfidence" : [ + 0.7903227217215787, + 1.301419899652454 + ], + "scorePercentiles" : { + "0.0" : 0.961285840430645, + "50.0" : 1.0453254822709421, + "90.0" : 1.1320143119764545, + "95.0" : 1.1320143119764545, + "99.0" : 1.1320143119764545, + "99.9" : 1.1320143119764545, + "99.99" : 1.1320143119764545, + "99.999" : 1.1320143119764545, + "99.9999" : 1.1320143119764545, + "100.0" : 1.1320143119764545 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1320143119764545, + 1.1263734874422795, + 1.1287370961625283 + ], + [ + 0.9625396510105871, + 0.9642774770996047, + 0.961285840430645 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010504882869921947, + "scoreError" : 1.4108359247088276E-4, + "scoreConfidence" : [ + 0.010363799277451064, + 0.01064596646239283 + ], + "scorePercentiles" : { + "0.0" : 0.010447678010476674, + "50.0" : 0.010497536453350269, + "90.0" : 0.0105750908623698, + "95.0" : 0.0105750908623698, + "99.0" : 0.0105750908623698, + "99.9" : 0.0105750908623698, + "99.99" : 0.0105750908623698, + "99.999" : 0.0105750908623698, + "99.9999" : 0.0105750908623698, + "100.0" : 0.0105750908623698 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010525354146362, + 0.010543129568988965, + 0.0105750908623698 + ], + [ + 0.010468325870995701, + 0.010469718760338538, + 0.010447678010476674 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.159283885424873, + "scoreError" : 0.25586271124217214, + "scoreConfidence" : [ + 2.9034211741827005, + 3.415146596667045 + ], + "scorePercentiles" : { + "0.0" : 3.0489593652439027, + "50.0" : 3.165829379693399, + "90.0" : 3.2517827880364107, + "95.0" : 3.2517827880364107, + "99.0" : 3.2517827880364107, + "99.9" : 3.2517827880364107, + "99.99" : 3.2517827880364107, + "99.999" : 3.2517827880364107, + "99.9999" : 3.2517827880364107, + "100.0" : 3.2517827880364107 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0489593652439027, + 3.0843352638717634, + 3.0993215855018588 + ], + [ + 3.2389671360103627, + 3.2323371738849387, + 3.2517827880364107 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9637489833842348, + "scoreError" : 0.05950943704115313, + "scoreConfidence" : [ + 2.9042395463430815, + 3.023258420425388 + ], + "scorePercentiles" : { + "0.0" : 2.9441374901383575, + "50.0" : 2.9602015223628886, + "90.0" : 2.9914487071492672, + "95.0" : 2.9914487071492672, + "99.0" : 2.9914487071492672, + "99.9" : 2.9914487071492672, + "99.99" : 2.9914487071492672, + "99.999" : 2.9914487071492672, + "99.9999" : 2.9914487071492672, + "100.0" : 2.9914487071492672 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9914487071492672, + 2.981926377161598, + 2.9739274451382696 + ], + [ + 2.946475599587507, + 2.9441374901383575, + 2.944578281130409 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17877283202507357, + "scoreError" : 0.008750092929814521, + "scoreConfidence" : [ + 0.17002273909525906, + 0.1875229249548881 + ], + "scorePercentiles" : { + "0.0" : 0.17687838380175813, + "50.0" : 0.17771275120783386, + "90.0" : 0.1851039395279963, + "95.0" : 0.1851039395279963, + "99.0" : 0.1851039395279963, + "99.9" : 0.1851039395279963, + "99.99" : 0.1851039395279963, + "99.999" : 0.1851039395279963, + "99.9999" : 0.1851039395279963, + "100.0" : 0.1851039395279963 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1851039395279963, + 0.17779775649391058, + 0.17779605763965436 + ], + [ + 0.17762944477601336, + 0.17743140991110876, + 0.17687838380175813 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3263847193121482, + "scoreError" : 0.012345491264338093, + "scoreConfidence" : [ + 0.3140392280478101, + 0.3387302105764863 + ], + "scorePercentiles" : { + "0.0" : 0.3217403550929799, + "50.0" : 0.32647665116039054, + "90.0" : 0.3322582626752608, + "95.0" : 0.3322582626752608, + "99.0" : 0.3322582626752608, + "99.9" : 0.3322582626752608, + "99.99" : 0.3322582626752608, + "99.999" : 0.3322582626752608, + "99.9999" : 0.3322582626752608, + "100.0" : 0.3322582626752608 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3242301800408521, + 0.3218224348651606, + 0.3217403550929799 + ], + [ + 0.3322582626752608, + 0.328723122279929, + 0.32953396091870696 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.145944147393136, + "scoreError" : 0.007036163387471947, + "scoreConfidence" : [ + 0.13890798400566404, + 0.15298031078060795 + ], + "scorePercentiles" : { + "0.0" : 0.14348563015998278, + "50.0" : 0.1459663244243061, + "90.0" : 0.14841178771463764, + "95.0" : 0.14841178771463764, + "99.0" : 0.14841178771463764, + "99.9" : 0.14841178771463764, + "99.99" : 0.14841178771463764, + "99.999" : 0.14841178771463764, + "99.9999" : 0.14841178771463764, + "100.0" : 0.14841178771463764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14806305275314255, + 0.1482142547316625, + 0.14841178771463764 + ], + [ + 0.14362056290392072, + 0.14348563015998278, + 0.14386959609546965 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40635855948103955, + "scoreError" : 0.013269123442330714, + "scoreConfidence" : [ + 0.39308943603870883, + 0.41962768292337027 + ], + "scorePercentiles" : { + "0.0" : 0.39969741011191046, + "50.0" : 0.4078320754049398, + "90.0" : 0.4105838537116111, + "95.0" : 0.4105838537116111, + "99.0" : 0.4105838537116111, + "99.9" : 0.4105838537116111, + "99.99" : 0.4105838537116111, + "99.999" : 0.4105838537116111, + "99.9999" : 0.4105838537116111, + "100.0" : 0.4105838537116111 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41034722905211324, + 0.4105838537116111, + 0.4099802880862578 + ], + [ + 0.4056838627236218, + 0.4018587132007233, + 0.39969741011191046 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15945744478336296, + "scoreError" : 0.004099220421924381, + "scoreConfidence" : [ + 0.1553582243614386, + 0.16355666520528733 + ], + "scorePercentiles" : { + "0.0" : 0.15828925202209665, + "50.0" : 0.15894693119756265, + "90.0" : 0.1620532286339329, + "95.0" : 0.1620532286339329, + "99.0" : 0.1620532286339329, + "99.9" : 0.1620532286339329, + "99.99" : 0.1620532286339329, + "99.999" : 0.1620532286339329, + "99.9999" : 0.1620532286339329, + "100.0" : 0.1620532286339329 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1620532286339329, + 0.16012251917441916, + 0.15943162768637203 + ], + [ + 0.15838580647460365, + 0.15846223470875326, + 0.15828925202209665 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04675981633134168, + "scoreError" : 0.00194891175221639, + "scoreConfidence" : [ + 0.04481090457912529, + 0.04870872808355807 + ], + "scorePercentiles" : { + "0.0" : 0.046050023664688085, + "50.0" : 0.046769634315124944, + "90.0" : 0.047424308945017216, + "95.0" : 0.047424308945017216, + "99.0" : 0.047424308945017216, + "99.9" : 0.047424308945017216, + "99.99" : 0.047424308945017216, + "99.999" : 0.047424308945017216, + "99.9999" : 0.047424308945017216, + "100.0" : 0.047424308945017216 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04734259124457343, + 0.047424308945017216, + 0.04741010129048775 + ], + [ + 0.0461351954576071, + 0.046050023664688085, + 0.04619667738567647 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9071387.26860865, + "scoreError" : 861671.6769094984, + "scoreConfidence" : [ + 8209715.591699151, + 9933058.945518149 + ], + "scorePercentiles" : { + "0.0" : 8665944.31629116, + "50.0" : 9088677.52329212, + "90.0" : 9449535.86496695, + "95.0" : 9449535.86496695, + "99.0" : 9449535.86496695, + "99.9" : 9449535.86496695, + "99.99" : 9449535.86496695, + "99.999" : 9449535.86496695, + "99.9999" : 9449535.86496695, + "100.0" : 9449535.86496695 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8949361.397137746, + 8817460.832599118, + 8665944.31629116 + ], + [ + 9449535.86496695, + 9318027.551210428, + 9227993.649446495 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-23T02:19:02Z-2a24cd7606ed6da9e38ab7799ba91643a48235b4-jdk17.json b/performance-results/2025-09-23T02:19:02Z-2a24cd7606ed6da9e38ab7799ba91643a48235b4-jdk17.json new file mode 100644 index 0000000000..43ae7b889d --- /dev/null +++ b/performance-results/2025-09-23T02:19:02Z-2a24cd7606ed6da9e38ab7799ba91643a48235b4-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3095789782897893, + "scoreError" : 0.04801273377918843, + "scoreConfidence" : [ + 3.261566244510601, + 3.3575917120689778 + ], + "scorePercentiles" : { + "0.0" : 3.299009383359393, + "50.0" : 3.3119763758360063, + "90.0" : 3.315353778127752, + "95.0" : 3.315353778127752, + "99.0" : 3.315353778127752, + "99.9" : 3.315353778127752, + "99.99" : 3.315353778127752, + "99.999" : 3.315353778127752, + "99.9999" : 3.315353778127752, + "100.0" : 3.315353778127752 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.299009383359393, + 3.3141042945798667 + ], + [ + 3.309848457092146, + 3.315353778127752 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6660827371626785, + "scoreError" : 0.032886787999731326, + "scoreConfidence" : [ + 1.633195949162947, + 1.69896952516241 + ], + "scorePercentiles" : { + "0.0" : 1.661395463297402, + "50.0" : 1.6661021651352073, + "90.0" : 1.6707311550828976, + "95.0" : 1.6707311550828976, + "99.0" : 1.6707311550828976, + "99.9" : 1.6707311550828976, + "99.99" : 1.6707311550828976, + "99.999" : 1.6707311550828976, + "99.9999" : 1.6707311550828976, + "100.0" : 1.6707311550828976 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6707311550828976, + 1.6702327117552471 + ], + [ + 1.661395463297402, + 1.6619716185151676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8356100491743486, + "scoreError" : 0.014578931263266277, + "scoreConfidence" : [ + 0.8210311179110823, + 0.8501889804376148 + ], + "scorePercentiles" : { + "0.0" : 0.8322866494118423, + "50.0" : 0.8364279076296748, + "90.0" : 0.8372977320262023, + "95.0" : 0.8372977320262023, + "99.0" : 0.8372977320262023, + "99.9" : 0.8372977320262023, + "99.99" : 0.8372977320262023, + "99.999" : 0.8372977320262023, + "99.9999" : 0.8372977320262023, + "100.0" : 0.8372977320262023 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8322866494118423, + 0.8365675414037795 + ], + [ + 0.8372977320262023, + 0.83628827385557 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.969170181416553, + "scoreError" : 0.28317620649087805, + "scoreConfidence" : [ + 15.685993974925674, + 16.25234638790743 + ], + "scorePercentiles" : { + "0.0" : 15.814964681233025, + "50.0" : 16.000453808931024, + "90.0" : 16.07259690184377, + "95.0" : 16.07259690184377, + "99.0" : 16.07259690184377, + "99.9" : 16.07259690184377, + "99.99" : 16.07259690184377, + "99.999" : 16.07259690184377, + "99.9999" : 16.07259690184377, + "100.0" : 16.07259690184377 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.985024269520867, + 16.0469682946154, + 16.07259690184377 + ], + [ + 15.814964681233025, + 15.879583592945076, + 16.01588334834118 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2573.7185257361284, + "scoreError" : 155.4941527711142, + "scoreConfidence" : [ + 2418.224372965014, + 2729.212678507243 + ], + "scorePercentiles" : { + "0.0" : 2515.989393106845, + "50.0" : 2575.658216426219, + "90.0" : 2628.2329781854205, + "95.0" : 2628.2329781854205, + "99.0" : 2628.2329781854205, + "99.9" : 2628.2329781854205, + "99.99" : 2628.2329781854205, + "99.999" : 2628.2329781854205, + "99.9999" : 2628.2329781854205, + "100.0" : 2628.2329781854205 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2515.989393106845, + 2520.1619941941312, + 2534.4510758798106 + ], + [ + 2616.865356972628, + 2626.6103560779343, + 2628.2329781854205 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76957.23559403383, + "scoreError" : 758.3029841918509, + "scoreConfidence" : [ + 76198.93260984198, + 77715.53857822568 + ], + "scorePercentiles" : { + "0.0" : 76615.1895682339, + "50.0" : 76975.5722330914, + "90.0" : 77232.2252515146, + "95.0" : 77232.2252515146, + "99.0" : 77232.2252515146, + "99.9" : 77232.2252515146, + "99.99" : 77232.2252515146, + "99.999" : 77232.2252515146, + "99.9999" : 77232.2252515146, + "100.0" : 77232.2252515146 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76615.1895682339, + 76753.11863462513, + 76781.03610547178 + ], + [ + 77191.7356436466, + 77232.2252515146, + 77170.10836071102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 339.3236232360392, + "scoreError" : 8.606615040571501, + "scoreConfidence" : [ + 330.7170081954677, + 347.93023827661074 + ], + "scorePercentiles" : { + "0.0" : 334.5973548333436, + "50.0" : 339.1572116456855, + "90.0" : 343.00540044827744, + "95.0" : 343.00540044827744, + "99.0" : 343.00540044827744, + "99.9" : 343.00540044827744, + "99.99" : 343.00540044827744, + "99.999" : 343.00540044827744, + "99.9999" : 343.00540044827744, + "100.0" : 343.00540044827744 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 343.00540044827744, + 342.05211479044726, + 340.12704961842326 + ], + [ + 334.5973548333436, + 338.18737367294773, + 337.97244605279616 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 107.48432849157484, + "scoreError" : 2.5347782155776972, + "scoreConfidence" : [ + 104.94955027599714, + 110.01910670715255 + ], + "scorePercentiles" : { + "0.0" : 106.52150762450255, + "50.0" : 107.12267671091882, + "90.0" : 108.64698423730712, + "95.0" : 108.64698423730712, + "99.0" : 108.64698423730712, + "99.9" : 108.64698423730712, + "99.99" : 108.64698423730712, + "99.999" : 108.64698423730712, + "99.9999" : 108.64698423730712, + "100.0" : 108.64698423730712 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 108.57019407262297, + 106.96512784941628, + 108.64698423730712 + ], + [ + 106.52150762450255, + 107.28022557242136, + 106.92193159317883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06211041797514658, + "scoreError" : 9.250884679121894E-4, + "scoreConfidence" : [ + 0.06118532950723439, + 0.06303550644305878 + ], + "scorePercentiles" : { + "0.0" : 0.06164008986346966, + "50.0" : 0.06208369845160775, + "90.0" : 0.0626596128826091, + "95.0" : 0.0626596128826091, + "99.0" : 0.0626596128826091, + "99.9" : 0.0626596128826091, + "99.99" : 0.0626596128826091, + "99.999" : 0.0626596128826091, + "99.9999" : 0.0626596128826091, + "100.0" : 0.0626596128826091 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06164008986346966, + 0.0620058137997743, + 0.062189594401810926 + ], + [ + 0.0626596128826091, + 0.06212039099024108, + 0.06204700591297442 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.739201694529456E-4, + "scoreError" : 2.0438533564249867E-5, + "scoreConfidence" : [ + 3.5348163588869576E-4, + 3.943587030171955E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6694989062872446E-4, + "50.0" : 3.7334034521908216E-4, + "90.0" : 3.8152067934462986E-4, + "95.0" : 3.8152067934462986E-4, + "99.0" : 3.8152067934462986E-4, + "99.9" : 3.8152067934462986E-4, + "99.99" : 3.8152067934462986E-4, + "99.999" : 3.8152067934462986E-4, + "99.9999" : 3.8152067934462986E-4, + "100.0" : 3.8152067934462986E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6708994313204075E-4, + 3.6694989062872446E-4, + 3.679656095995706E-4 + ], + [ + 3.787150808385938E-4, + 3.8127981317411425E-4, + 3.8152067934462986E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.708733128936368, + "scoreError" : 0.09480710099463438, + "scoreConfidence" : [ + 2.6139260279417336, + 2.803540229931002 + ], + "scorePercentiles" : { + "0.0" : 2.6735564448008553, + "50.0" : 2.706927408088565, + "90.0" : 2.7574730093741384, + "95.0" : 2.7574730093741384, + "99.0" : 2.7574730093741384, + "99.9" : 2.7574730093741384, + "99.99" : 2.7574730093741384, + "99.999" : 2.7574730093741384, + "99.9999" : 2.7574730093741384, + "100.0" : 2.7574730093741384 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7574730093741384, + 2.723458327342048, + 2.6735564448008553 + ], + [ + 2.690396488835082, + 2.731140889404697, + 2.676373613861386 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013082249642555692, + "scoreError" : 6.953747280457144E-5, + "scoreConfidence" : [ + 0.01301271216975112, + 0.013151787115360263 + ], + "scorePercentiles" : { + "0.0" : 0.013056661024539597, + "50.0" : 0.013075846872048269, + "90.0" : 0.013123045050778907, + "95.0" : 0.013123045050778907, + "99.0" : 0.013123045050778907, + "99.9" : 0.013123045050778907, + "99.99" : 0.013123045050778907, + "99.999" : 0.013123045050778907, + "99.9999" : 0.013123045050778907, + "100.0" : 0.013123045050778907 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013123045050778907, + 0.013098040561426303, + 0.013056661024539597 + ], + [ + 0.013069016938520268, + 0.013064057474492794, + 0.01308267680557627 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.969529345158123, + "scoreError" : 0.023726873881165934, + "scoreConfidence" : [ + 0.945802471276957, + 0.9932562190392888 + ], + "scorePercentiles" : { + "0.0" : 0.9602343382621219, + "50.0" : 0.9690918609681216, + "90.0" : 0.9787368435114504, + "95.0" : 0.9787368435114504, + "99.0" : 0.9787368435114504, + "99.9" : 0.9787368435114504, + "99.99" : 0.9787368435114504, + "99.999" : 0.9787368435114504, + "99.9999" : 0.9787368435114504, + "100.0" : 0.9787368435114504 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9602343382621219, + 0.964078407500241, + 0.961774333237161 + ], + [ + 0.9787368435114504, + 0.9782468340017607, + 0.9741053144360023 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.0102813420188602, + "scoreError" : 2.641824339899928E-4, + "scoreConfidence" : [ + 0.010017159584870207, + 0.010545524452850194 + ], + "scorePercentiles" : { + "0.0" : 0.010175120492298675, + "50.0" : 0.010282188849950719, + "90.0" : 0.01037699533046797, + "95.0" : 0.01037699533046797, + "99.0" : 0.01037699533046797, + "99.9" : 0.01037699533046797, + "99.99" : 0.01037699533046797, + "99.999" : 0.01037699533046797, + "99.9999" : 0.01037699533046797, + "100.0" : 0.01037699533046797 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010204343369387756, + 0.01020924839668004, + 0.010175120492298675 + ], + [ + 0.01037699533046797, + 0.01036721522110536, + 0.010355129303221397 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.265837577738878, + "scoreError" : 0.034587894230118855, + "scoreConfidence" : [ + 3.231249683508759, + 3.300425471968997 + ], + "scorePercentiles" : { + "0.0" : 3.2433177924773022, + "50.0" : 3.268676114782512, + "90.0" : 3.2775043931847967, + "95.0" : 3.2775043931847967, + "99.0" : 3.2775043931847967, + "99.9" : 3.2775043931847967, + "99.99" : 3.2775043931847967, + "99.999" : 3.2775043931847967, + "99.9999" : 3.2775043931847967, + "100.0" : 3.2775043931847967 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2619459680365295, + 3.274905083169614, + 3.2700814640522875 + ], + [ + 3.2433177924773022, + 3.2775043931847967, + 3.2672707655127367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9003792886728363, + "scoreError" : 0.14957413971308717, + "scoreConfidence" : [ + 2.750805148959749, + 3.0499534283859235 + ], + "scorePercentiles" : { + "0.0" : 2.845782786344239, + "50.0" : 2.900799230805492, + "90.0" : 2.9549145610044314, + "95.0" : 2.9549145610044314, + "99.0" : 2.9549145610044314, + "99.9" : 2.9549145610044314, + "99.99" : 2.9549145610044314, + "99.999" : 2.9549145610044314, + "99.9999" : 2.9549145610044314, + "100.0" : 2.9549145610044314 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9549145610044314, + 2.952189377804014, + 2.9383522967097533 + ], + [ + 2.845782786344239, + 2.8477905452733485, + 2.863246164901231 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17740550423110923, + "scoreError" : 8.012613890564514E-4, + "scoreConfidence" : [ + 0.17660424284205278, + 0.17820676562016569 + ], + "scorePercentiles" : { + "0.0" : 0.17697164089404852, + "50.0" : 0.17741756005622028, + "90.0" : 0.17776747002044263, + "95.0" : 0.17776747002044263, + "99.0" : 0.17776747002044263, + "99.9" : 0.17776747002044263, + "99.99" : 0.17776747002044263, + "99.999" : 0.17776747002044263, + "99.9999" : 0.17776747002044263, + "100.0" : 0.17776747002044263 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17755434968573558, + 0.17776747002044263, + 0.17728077042670495 + ], + [ + 0.17758769723499848, + 0.17727109712472525, + 0.17697164089404852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.337242834382161, + "scoreError" : 0.018107217783755545, + "scoreConfidence" : [ + 0.31913561659840545, + 0.3553500521659166 + ], + "scorePercentiles" : { + "0.0" : 0.3308738535269984, + "50.0" : 0.336070955409201, + "90.0" : 0.34481690473070825, + "95.0" : 0.34481690473070825, + "99.0" : 0.34481690473070825, + "99.9" : 0.34481690473070825, + "99.99" : 0.34481690473070825, + "99.999" : 0.34481690473070825, + "99.9999" : 0.34481690473070825, + "100.0" : 0.34481690473070825 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33195921108713694, + 0.33175661457054706, + 0.3308738535269984 + ], + [ + 0.3401826997312651, + 0.34386772264631044, + 0.34481690473070825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14962478777569557, + "scoreError" : 0.013296020759109756, + "scoreConfidence" : [ + 0.1363287670165858, + 0.16292080853480534 + ], + "scorePercentiles" : { + "0.0" : 0.145046001334397, + "50.0" : 0.14964429165303766, + "90.0" : 0.1546479741436635, + "95.0" : 0.1546479741436635, + "99.0" : 0.1546479741436635, + "99.9" : 0.1546479741436635, + "99.99" : 0.1546479741436635, + "99.999" : 0.1546479741436635, + "99.9999" : 0.1546479741436635, + "100.0" : 0.1546479741436635 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1546479741436635, + 0.1534419615638378, + 0.15369867840895118 + ], + [ + 0.145046001334397, + 0.14584662174223753, + 0.14506748946108652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4000424865094383, + "scoreError" : 0.007436356398219337, + "scoreConfidence" : [ + 0.392606130111219, + 0.4074788429076576 + ], + "scorePercentiles" : { + "0.0" : 0.39681826352128885, + "50.0" : 0.399696655135814, + "90.0" : 0.4049147449487792, + "95.0" : 0.4049147449487792, + "99.0" : 0.4049147449487792, + "99.9" : 0.4049147449487792, + "99.99" : 0.4049147449487792, + "99.999" : 0.4049147449487792, + "99.9999" : 0.4049147449487792, + "100.0" : 0.4049147449487792 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4049147449487792, + 0.3991696065141899, + 0.39681826352128885 + ], + [ + 0.39959757212499003, + 0.3997957381466379, + 0.3999589938007439 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15433508632479864, + "scoreError" : 0.013892588588388346, + "scoreConfidence" : [ + 0.1404424977364103, + 0.168227674913187 + ], + "scorePercentiles" : { + "0.0" : 0.14961103918195146, + "50.0" : 0.1543933164859873, + "90.0" : 0.15904309307059816, + "95.0" : 0.15904309307059816, + "99.0" : 0.15904309307059816, + "99.9" : 0.15904309307059816, + "99.99" : 0.15904309307059816, + "99.999" : 0.15904309307059816, + "99.9999" : 0.15904309307059816, + "100.0" : 0.15904309307059816 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15883331398802433, + 0.15904309307059816, + 0.15868584941049524 + ], + [ + 0.14961103918195146, + 0.15010078356147935, + 0.14973643873624318 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048113976404333035, + "scoreError" : 0.0010519157533025996, + "scoreConfidence" : [ + 0.047062060651030434, + 0.049165892157635636 + ], + "scorePercentiles" : { + "0.0" : 0.04757733251342852, + "50.0" : 0.04822778876981573, + "90.0" : 0.04857862111680552, + "95.0" : 0.04857862111680552, + "99.0" : 0.04857862111680552, + "99.9" : 0.04857862111680552, + "99.99" : 0.04857862111680552, + "99.999" : 0.04857862111680552, + "99.9999" : 0.04857862111680552, + "100.0" : 0.04857862111680552 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04857862111680552, + 0.048192631236024366, + 0.048262946303607106 + ], + [ + 0.04757733251342852, + 0.047754013160785064, + 0.04831831409534761 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9339927.80242196, + "scoreError" : 646079.2773135401, + "scoreConfidence" : [ + 8693848.52510842, + 9986007.079735499 + ], + "scorePercentiles" : { + "0.0" : 9024597.714156898, + "50.0" : 9353948.21616831, + "90.0" : 9594757.45637584, + "95.0" : 9594757.45637584, + "99.0" : 9594757.45637584, + "99.9" : 9594757.45637584, + "99.99" : 9594757.45637584, + "99.999" : 9594757.45637584, + "99.9999" : 9594757.45637584, + "100.0" : 9594757.45637584 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9133683.376255708, + 9024597.714156898, + 9330118.939365672 + ], + [ + 9578631.835406698, + 9594757.45637584, + 9377777.492970947 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-24T22:01:42Z-bf3752790305d563f28174ef3343288a7b18b54f-jdk17.json b/performance-results/2025-09-24T22:01:42Z-bf3752790305d563f28174ef3343288a7b18b54f-jdk17.json new file mode 100644 index 0000000000..8f8673e0a2 --- /dev/null +++ b/performance-results/2025-09-24T22:01:42Z-bf3752790305d563f28174ef3343288a7b18b54f-jdk17.json @@ -0,0 +1,1225 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3231476944845446, + "scoreError" : 0.05576763148549442, + "scoreConfidence" : [ + 3.26738006299905, + 3.378915325970039 + ], + "scorePercentiles" : { + "0.0" : 3.3105681887881118, + "50.0" : 3.3263610998001942, + "90.0" : 3.329300389549678, + "95.0" : 3.329300389549678, + "99.0" : 3.329300389549678, + "99.9" : 3.329300389549678, + "99.99" : 3.329300389549678, + "99.999" : 3.329300389549678, + "99.9999" : 3.329300389549678, + "100.0" : 3.329300389549678 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.324532924420686, + 3.329300389549678 + ], + [ + 3.3105681887881118, + 3.3281892751797026 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.673522800594215, + "scoreError" : 0.011992732645477735, + "scoreConfidence" : [ + 1.6615300679487373, + 1.685515533239693 + ], + "scorePercentiles" : { + "0.0" : 1.6710786181254627, + "50.0" : 1.6738182254695424, + "90.0" : 1.6753761333123123, + "95.0" : 1.6753761333123123, + "99.0" : 1.6753761333123123, + "99.9" : 1.6753761333123123, + "99.99" : 1.6753761333123123, + "99.999" : 1.6753761333123123, + "99.9999" : 1.6753761333123123, + "100.0" : 1.6753761333123123 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6710786181254627, + 1.6744304126336462 + ], + [ + 1.6753761333123123, + 1.6732060383054388 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8421733222098159, + "scoreError" : 0.05639745071895826, + "scoreConfidence" : [ + 0.7857758714908576, + 0.8985707729287742 + ], + "scorePercentiles" : { + "0.0" : 0.8294524478277855, + "50.0" : 0.8456688500567878, + "90.0" : 0.8479031408979021, + "95.0" : 0.8479031408979021, + "99.0" : 0.8479031408979021, + "99.9" : 0.8479031408979021, + "99.99" : 0.8479031408979021, + "99.999" : 0.8479031408979021, + "99.9999" : 0.8479031408979021, + "100.0" : 0.8479031408979021 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8294524478277855, + 0.8479031408979021 + ], + [ + 0.843498316866776, + 0.8478393832467996 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.088623045270147, + "scoreError" : 0.21721500433002625, + "scoreConfidence" : [ + 15.871408040940121, + 16.305838049600172 + ], + "scorePercentiles" : { + "0.0" : 15.987394154754861, + "50.0" : 16.080145178605214, + "90.0" : 16.183393031782632, + "95.0" : 16.183393031782632, + "99.0" : 16.183393031782632, + "99.9" : 16.183393031782632, + "99.99" : 16.183393031782632, + "99.999" : 16.183393031782632, + "99.9999" : 16.183393031782632, + "100.0" : 16.183393031782632 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.048931726057265, + 15.987394154754861, + 16.035500066178074 + ], + [ + 16.165160661694888, + 16.111358631153166, + 16.183393031782632 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2674.1967718242245, + "scoreError" : 275.451747785103, + "scoreConfidence" : [ + 2398.7450240391213, + 2949.6485196093276 + ], + "scorePercentiles" : { + "0.0" : 2577.6714732189, + "50.0" : 2672.2660062051855, + "90.0" : 2777.0927789771727, + "95.0" : 2777.0927789771727, + "99.0" : 2777.0927789771727, + "99.9" : 2777.0927789771727, + "99.99" : 2777.0927789771727, + "99.999" : 2777.0927789771727, + "99.9999" : 2777.0927789771727, + "100.0" : 2777.0927789771727 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2577.6714732189, + 2588.056523892936, + 2588.8455115893316 + ], + [ + 2777.0927789771727, + 2755.686500821039, + 2757.8278424459695 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77188.55397778591, + "scoreError" : 1355.7922697502684, + "scoreConfidence" : [ + 75832.76170803564, + 78544.34624753617 + ], + "scorePercentiles" : { + "0.0" : 76725.66787864313, + "50.0" : 77191.39761701284, + "90.0" : 77656.63956431513, + "95.0" : 77656.63956431513, + "99.0" : 77656.63956431513, + "99.9" : 77656.63956431513, + "99.99" : 77656.63956431513, + "99.999" : 77656.63956431513, + "99.9999" : 77656.63956431513, + "100.0" : 77656.63956431513 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76734.40630395035, + 76783.54232299031, + 76725.66787864313 + ], + [ + 77599.25291103538, + 77631.81488578107, + 77656.63956431513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 343.34084509571943, + "scoreError" : 22.532472115448, + "scoreConfidence" : [ + 320.80837298027143, + 365.87331721116743 + ], + "scorePercentiles" : { + "0.0" : 335.7897845360169, + "50.0" : 343.19190842152534, + "90.0" : 351.2292382317256, + "95.0" : 351.2292382317256, + "99.0" : 351.2292382317256, + "99.9" : 351.2292382317256, + "99.99" : 351.2292382317256, + "99.999" : 351.2292382317256, + "99.9999" : 351.2292382317256, + "100.0" : 351.2292382317256 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 336.1767970869616, + 335.7897845360169, + 336.07142653517315 + ], + [ + 351.2292382317256, + 350.20701975608915, + 350.57080442835013 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.38151335489005, + "scoreError" : 7.0127894170091025, + "scoreConfidence" : [ + 105.36872393788094, + 119.39430277189915 + ], + "scorePercentiles" : { + "0.0" : 109.85899414170567, + "50.0" : 112.30411326109922, + "90.0" : 114.84925754221614, + "95.0" : 114.84925754221614, + "99.0" : 114.84925754221614, + "99.9" : 114.84925754221614, + "99.99" : 114.84925754221614, + "99.999" : 114.84925754221614, + "99.9999" : 114.84925754221614, + "100.0" : 114.84925754221614 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 110.14104747794393, + 110.33136452413314, + 109.85899414170567 + ], + [ + 114.84925754221614, + 114.8315544452761, + 114.2768619980653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06175043821743703, + "scoreError" : 3.2647425496025006E-4, + "scoreConfidence" : [ + 0.061423963962476784, + 0.06207691247239728 + ], + "scorePercentiles" : { + "0.0" : 0.06156763646829941, + "50.0" : 0.06174904444054971, + "90.0" : 0.061895949753657996, + "95.0" : 0.061895949753657996, + "99.0" : 0.061895949753657996, + "99.9" : 0.061895949753657996, + "99.99" : 0.061895949753657996, + "99.999" : 0.061895949753657996, + "99.9999" : 0.061895949753657996, + "100.0" : 0.061895949753657996 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06170244482699047, + 0.061838509374574864, + 0.061895949753657996 + ], + [ + 0.06178853313973246, + 0.06170955574136697, + 0.06156763646829941 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.856778035658799E-4, + "scoreError" : 2.4676566450271538E-5, + "scoreConfidence" : [ + 3.610012371156084E-4, + 4.1035437001615143E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7755603787877756E-4, + "50.0" : 3.8541237400743485E-4, + "90.0" : 3.9454129757862465E-4, + "95.0" : 3.9454129757862465E-4, + "99.0" : 3.9454129757862465E-4, + "99.9" : 3.9454129757862465E-4, + "99.99" : 3.9454129757862465E-4, + "99.999" : 3.9454129757862465E-4, + "99.9999" : 3.9454129757862465E-4, + "100.0" : 3.9454129757862465E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7780081177138397E-4, + 3.7755603787877756E-4, + 3.776152396684678E-4 + ], + [ + 3.935294982545399E-4, + 3.930239362434858E-4, + 3.9454129757862465E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01313944650746763, + "scoreError" : 3.3036500535129596E-4, + "scoreConfidence" : [ + 0.012809081502116333, + 0.013469811512818926 + ], + "scorePercentiles" : { + "0.0" : 0.013026900289713856, + "50.0" : 0.01313486772305534, + "90.0" : 0.013256904513246766, + "95.0" : 0.013256904513246766, + "99.0" : 0.013256904513246766, + "99.9" : 0.013256904513246766, + "99.99" : 0.013256904513246766, + "99.999" : 0.013256904513246766, + "99.9999" : 0.013256904513246766, + "100.0" : 0.013256904513246766 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013035628478839531, + 0.013026900289713856, + 0.013033896908802035 + ], + [ + 0.013249241886932443, + 0.013256904513246766, + 0.01323410696727115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9925912770043442, + "scoreError" : 0.00515487370601758, + "scoreConfidence" : [ + 0.9874364032983267, + 0.9977461507103618 + ], + "scorePercentiles" : { + "0.0" : 0.9905894818740095, + "50.0" : 0.9922810043250647, + "90.0" : 0.9949423251417769, + "95.0" : 0.9949423251417769, + "99.0" : 0.9949423251417769, + "99.9" : 0.9949423251417769, + "99.99" : 0.9949423251417769, + "99.999" : 0.9949423251417769, + "99.9999" : 0.9949423251417769, + "100.0" : 0.9949423251417769 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9949423251417769, + 0.9942933991847286, + 0.9933356795788637 + ], + [ + 0.9911604471754212, + 0.9912263290712657, + 0.9905894818740095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010761148406008184, + "scoreError" : 8.811072557120488E-4, + "scoreConfidence" : [ + 0.009880041150296134, + 0.011642255661720233 + ], + "scorePercentiles" : { + "0.0" : 0.010463606288831737, + "50.0" : 0.01075893932734923, + "90.0" : 0.011056569420765753, + "95.0" : 0.011056569420765753, + "99.0" : 0.011056569420765753, + "99.9" : 0.011056569420765753, + "99.99" : 0.011056569420765753, + "99.999" : 0.011056569420765753, + "99.9999" : 0.011056569420765753, + "100.0" : 0.011056569420765753 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010479100573610562, + 0.010480554989855121, + 0.010463606288831737 + ], + [ + 0.011056569420765753, + 0.01103732366484334, + 0.011049735498142586 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.3629554933279664, + "scoreError" : 0.07084706215816614, + "scoreConfidence" : [ + 3.2921084311698, + 3.4338025554861327 + ], + "scorePercentiles" : { + "0.0" : 3.332798313790806, + "50.0" : 3.3605197265445237, + "90.0" : 3.392697289009498, + "95.0" : 3.392697289009498, + "99.0" : 3.392697289009498, + "99.9" : 3.392697289009498, + "99.99" : 3.392697289009498, + "99.999" : 3.392697289009498, + "99.9999" : 3.392697289009498, + "100.0" : 3.392697289009498 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.332798313790806, + 3.3430916290106953, + 3.347131188085676 + ], + [ + 3.392697289009498, + 3.388106275067751, + 3.3739082650033714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9354392314440556, + "scoreError" : 0.05115472897876458, + "scoreConfidence" : [ + 2.8842845024652912, + 2.98659396042282 + ], + "scorePercentiles" : { + "0.0" : 2.9136747786192836, + "50.0" : 2.936426058380065, + "90.0" : 2.9573701972205795, + "95.0" : 2.9573701972205795, + "99.0" : 2.9573701972205795, + "99.9" : 2.9573701972205795, + "99.99" : 2.9573701972205795, + "99.999" : 2.9573701972205795, + "99.9999" : 2.9573701972205795, + "100.0" : 2.9573701972205795 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9182054037339555, + 2.9268742999707347, + 2.9136747786192836 + ], + [ + 2.945977816789396, + 2.9505328923303833, + 2.9573701972205795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18308782767424345, + "scoreError" : 0.03048334682725773, + "scoreConfidence" : [ + 0.15260448084698572, + 0.21357117450150118 + ], + "scorePercentiles" : { + "0.0" : 0.17305646879867095, + "50.0" : 0.1830986727799045, + "90.0" : 0.19310122084266626, + "95.0" : 0.19310122084266626, + "99.0" : 0.19310122084266626, + "99.9" : 0.19310122084266626, + "99.99" : 0.19310122084266626, + "99.999" : 0.19310122084266626, + "99.9999" : 0.19310122084266626, + "100.0" : 0.19310122084266626 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19310122084266626, + 0.19298346324707152, + 0.19294850380103418 + ], + [ + 0.1732488417587748, + 0.1731884675972429, + 0.17305646879867095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3400980680966395, + "scoreError" : 0.03444656442815107, + "scoreConfidence" : [ + 0.3056515036684884, + 0.3745446325247906 + ], + "scorePercentiles" : { + "0.0" : 0.3232931979762713, + "50.0" : 0.34131120267884263, + "90.0" : 0.35398818665486725, + "95.0" : 0.35398818665486725, + "99.0" : 0.35398818665486725, + "99.9" : 0.35398818665486725, + "99.99" : 0.35398818665486725, + "99.999" : 0.35398818665486725, + "99.9999" : 0.35398818665486725, + "100.0" : 0.35398818665486725 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33611216391624377, + 0.3298062128157773, + 0.3232931979762713 + ], + [ + 0.34651024144144144, + 0.35087840577523594, + 0.35398818665486725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1502561927593922, + "scoreError" : 0.009203914482233668, + "scoreConfidence" : [ + 0.14105227827715852, + 0.15946010724162588 + ], + "scorePercentiles" : { + "0.0" : 0.14706316475242284, + "50.0" : 0.15025330358786043, + "90.0" : 0.1533787646165644, + "95.0" : 0.1533787646165644, + "99.0" : 0.1533787646165644, + "99.9" : 0.1533787646165644, + "99.99" : 0.1533787646165644, + "99.999" : 0.1533787646165644, + "99.9999" : 0.1533787646165644, + "100.0" : 0.1533787646165644 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15305326886344853, + 0.1533787646165644, + 0.15331390580587792 + ], + [ + 0.14727471420576713, + 0.14745333831227236, + 0.14706316475242284 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4050257256483299, + "scoreError" : 0.006761442110198147, + "scoreConfidence" : [ + 0.39826428353813176, + 0.411787167758528 + ], + "scorePercentiles" : { + "0.0" : 0.40190211722863, + "50.0" : 0.40632125634744065, + "90.0" : 0.40693219995930824, + "95.0" : 0.40693219995930824, + "99.0" : 0.40693219995930824, + "99.9" : 0.40693219995930824, + "99.99" : 0.40693219995930824, + "99.999" : 0.40693219995930824, + "99.9999" : 0.40693219995930824, + "100.0" : 0.40693219995930824 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40670188197974705, + 0.4066440817338972, + 0.40599843096098415 + ], + [ + 0.40693219995930824, + 0.40197564202741265, + 0.40190211722863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15717311502003936, + "scoreError" : 0.020348306551943675, + "scoreConfidence" : [ + 0.1368248084680957, + 0.17752142157198303 + ], + "scorePercentiles" : { + "0.0" : 0.150462264131923, + "50.0" : 0.1571170464237227, + "90.0" : 0.16415767261445527, + "95.0" : 0.16415767261445527, + "99.0" : 0.16415767261445527, + "99.9" : 0.16415767261445527, + "99.99" : 0.16415767261445527, + "99.999" : 0.16415767261445527, + "99.9999" : 0.16415767261445527, + "100.0" : 0.16415767261445527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15070725198926999, + 0.15048676344183107, + 0.150462264131923 + ], + [ + 0.16415767261445527, + 0.16369789708458152, + 0.1635268408581754 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04669520571657638, + "scoreError" : 0.004501776176268937, + "scoreConfidence" : [ + 0.04219342954030744, + 0.051196981892845314 + ], + "scorePercentiles" : { + "0.0" : 0.04521263395876662, + "50.0" : 0.04669549864524105, + "90.0" : 0.04818418672455081, + "95.0" : 0.04818418672455081, + "99.0" : 0.04818418672455081, + "99.9" : 0.04818418672455081, + "99.99" : 0.04818418672455081, + "99.999" : 0.04818418672455081, + "99.9999" : 0.04818418672455081, + "100.0" : 0.04818418672455081 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04521263395876662, + 0.04524873039402002, + 0.04522801630447073 + ], + [ + 0.04818418672455081, + 0.04815540002118807, + 0.04814226689646208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8884653.787414482, + "scoreError" : 420885.2406286423, + "scoreConfidence" : [ + 8463768.546785839, + 9305539.028043125 + ], + "scorePercentiles" : { + "0.0" : 8726034.162162162, + "50.0" : 8890614.237676539, + "90.0" : 9033791.406504065, + "95.0" : 9033791.406504065, + "99.0" : 9033791.406504065, + "99.9" : 9033791.406504065, + "99.99" : 9033791.406504065, + "99.999" : 9033791.406504065, + "99.9999" : 9033791.406504065, + "100.0" : 9033791.406504065 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8783079.978050921, + 8738461.64978166, + 8726034.162162162 + ], + [ + 8998148.497302158, + 9028407.03068592, + 9033791.406504065 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-25T22:51:54Z-8044c9f9e5a411c83dc6ec8f1ba419dbb7be0111-jdk17.json b/performance-results/2025-09-25T22:51:54Z-8044c9f9e5a411c83dc6ec8f1ba419dbb7be0111-jdk17.json new file mode 100644 index 0000000000..5887ba79ec --- /dev/null +++ b/performance-results/2025-09-25T22:51:54Z-8044c9f9e5a411c83dc6ec8f1ba419dbb7be0111-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3203538141842515, + "scoreError" : 0.06843195450057515, + "scoreConfidence" : [ + 3.2519218596836765, + 3.3887857686848264 + ], + "scorePercentiles" : { + "0.0" : 3.310512942014138, + "50.0" : 3.3203396584728004, + "90.0" : 3.3302229977772653, + "95.0" : 3.3302229977772653, + "99.0" : 3.3302229977772653, + "99.9" : 3.3302229977772653, + "99.99" : 3.3302229977772653, + "99.999" : 3.3302229977772653, + "99.9999" : 3.3302229977772653, + "100.0" : 3.3302229977772653 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.310512942014138, + 3.328771601048764 + ], + [ + 3.3119077158968375, + 3.3302229977772653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6753101783662656, + "scoreError" : 0.06576345939874756, + "scoreConfidence" : [ + 1.609546718967518, + 1.7410736377650131 + ], + "scorePercentiles" : { + "0.0" : 1.6625179798556808, + "50.0" : 1.677170636525328, + "90.0" : 1.6843814605587257, + "95.0" : 1.6843814605587257, + "99.0" : 1.6843814605587257, + "99.9" : 1.6843814605587257, + "99.99" : 1.6843814605587257, + "99.999" : 1.6843814605587257, + "99.9999" : 1.6843814605587257, + "100.0" : 1.6843814605587257 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6625179798556808, + 1.6717919318042744 + ], + [ + 1.6825493412463817, + 1.6843814605587257 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8441513970844166, + "scoreError" : 0.034194105502912873, + "scoreConfidence" : [ + 0.8099572915815036, + 0.8783455025873295 + ], + "scorePercentiles" : { + "0.0" : 0.8365719449310407, + "50.0" : 0.8455726558218887, + "90.0" : 0.848888331762848, + "95.0" : 0.848888331762848, + "99.0" : 0.848888331762848, + "99.9" : 0.848888331762848, + "99.99" : 0.848888331762848, + "99.999" : 0.848888331762848, + "99.9999" : 0.848888331762848, + "100.0" : 0.848888331762848 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8453780773671984, + 0.845767234276579 + ], + [ + 0.8365719449310407, + 0.848888331762848 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.03294025280983, + "scoreError" : 0.1976556805950903, + "scoreConfidence" : [ + 15.83528457221474, + 16.23059593340492 + ], + "scorePercentiles" : { + "0.0" : 15.92770032875591, + "50.0" : 16.040820422105245, + "90.0" : 16.109845560843876, + "95.0" : 16.109845560843876, + "99.0" : 16.109845560843876, + "99.9" : 16.109845560843876, + "99.99" : 16.109845560843876, + "99.999" : 16.109845560843876, + "99.9999" : 16.109845560843876, + "100.0" : 16.109845560843876 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.984878534303371, + 15.92770032875591, + 16.011319494491513 + ], + [ + 16.070321349718977, + 16.09357624874532, + 16.109845560843876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2665.039836112213, + "scoreError" : 210.95958249609416, + "scoreConfidence" : [ + 2454.0802536161186, + 2875.999418608307 + ], + "scorePercentiles" : { + "0.0" : 2591.9228508739297, + "50.0" : 2664.515271634845, + "90.0" : 2739.3715729044493, + "95.0" : 2739.3715729044493, + "99.0" : 2739.3715729044493, + "99.9" : 2739.3715729044493, + "99.99" : 2739.3715729044493, + "99.999" : 2739.3715729044493, + "99.9999" : 2739.3715729044493, + "100.0" : 2739.3715729044493 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2739.3715729044493, + 2728.967405412545, + 2732.4770578174202 + ], + [ + 2591.9228508739297, + 2597.4369918077855, + 2600.063137857145 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77753.14366768643, + "scoreError" : 1647.367701229895, + "scoreConfidence" : [ + 76105.77596645652, + 79400.51136891633 + ], + "scorePercentiles" : { + "0.0" : 77206.67910571207, + "50.0" : 77756.5331582586, + "90.0" : 78301.04017976095, + "95.0" : 78301.04017976095, + "99.0" : 78301.04017976095, + "99.9" : 78301.04017976095, + "99.99" : 78301.04017976095, + "99.999" : 78301.04017976095, + "99.9999" : 78301.04017976095, + "100.0" : 78301.04017976095 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77235.95262380512, + 77208.33979848209, + 77206.67910571207 + ], + [ + 78277.11369271205, + 78289.7366056462, + 78301.04017976095 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.5743070034512, + "scoreError" : 12.160742174102838, + "scoreConfidence" : [ + 337.4135648293484, + 361.73504917755406 + ], + "scorePercentiles" : { + "0.0" : 345.0800448966692, + "50.0" : 349.7980760372046, + "90.0" : 353.9929245741677, + "95.0" : 353.9929245741677, + "99.0" : 353.9929245741677, + "99.9" : 353.9929245741677, + "99.99" : 353.9929245741677, + "99.999" : 353.9929245741677, + "99.9999" : 353.9929245741677, + "100.0" : 353.9929245741677 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.0800448966692, + 346.40421016010043, + 345.4447822060659 + ], + [ + 353.9929245741677, + 353.19194191430876, + 353.33193826939544 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.77131852196857, + "scoreError" : 4.598849033798956, + "scoreConfidence" : [ + 108.17246948816961, + 117.37016755576752 + ], + "scorePercentiles" : { + "0.0" : 110.95237506881116, + "50.0" : 112.86997057982165, + "90.0" : 114.36707453124868, + "95.0" : 114.36707453124868, + "99.0" : 114.36707453124868, + "99.9" : 114.36707453124868, + "99.99" : 114.36707453124868, + "99.999" : 114.36707453124868, + "99.9999" : 114.36707453124868, + "100.0" : 114.36707453124868 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.36707453124868, + 114.06962242683949, + 114.31637936326293 + ], + [ + 111.25214100884533, + 110.95237506881116, + 111.67031873280384 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06221255257751246, + "scoreError" : 7.461314301691277E-4, + "scoreConfidence" : [ + 0.06146642114734333, + 0.06295868400768159 + ], + "scorePercentiles" : { + "0.0" : 0.06179716534216608, + "50.0" : 0.062264965051082685, + "90.0" : 0.06248170116651775, + "95.0" : 0.06248170116651775, + "99.0" : 0.06248170116651775, + "99.9" : 0.06248170116651775, + "99.99" : 0.06248170116651775, + "99.999" : 0.06248170116651775, + "99.9999" : 0.06248170116651775, + "100.0" : 0.06248170116651775 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.062045573153404684, + 0.06179716534216608, + 0.06213808889303135 + ], + [ + 0.06239184120913401, + 0.06248170116651775, + 0.062420945700820823 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.638945930167579E-4, + "scoreError" : 1.5624370855895026E-5, + "scoreConfidence" : [ + 3.4827022216086286E-4, + 3.7951896387265294E-4 + ], + "scorePercentiles" : { + "0.0" : 3.582909813280584E-4, + "50.0" : 3.6394213113750636E-4, + "90.0" : 3.69441621723546E-4, + "95.0" : 3.69441621723546E-4, + "99.0" : 3.69441621723546E-4, + "99.9" : 3.69441621723546E-4, + "99.99" : 3.69441621723546E-4, + "99.999" : 3.69441621723546E-4, + "99.9999" : 3.69441621723546E-4, + "100.0" : 3.69441621723546E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5986307320535533E-4, + 3.5840853006221336E-4, + 3.582909813280584E-4 + ], + [ + 3.69441621723546E-4, + 3.680211890696574E-4, + 3.693421627117169E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.4188472974603, + "scoreError" : 0.07351996236762309, + "scoreConfidence" : [ + 2.345327335092677, + 2.492367259827923 + ], + "scorePercentiles" : { + "0.0" : 2.3821655207241546, + "50.0" : 2.4219387257152247, + "90.0" : 2.4530300706401764, + "95.0" : 2.4530300706401764, + "99.0" : 2.4530300706401764, + "99.9" : 2.4530300706401764, + "99.99" : 2.4530300706401764, + "99.999" : 2.4530300706401764, + "99.9999" : 2.4530300706401764, + "100.0" : 2.4530300706401764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.4530300706401764, + 2.4373710175481356, + 2.4161307424498673 + ], + [ + 2.4277467089805826, + 2.3966397244188835, + 2.3821655207241546 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013284746179323487, + "scoreError" : 7.35070455023514E-5, + "scoreConfidence" : [ + 0.013211239133821136, + 0.013358253224825837 + ], + "scorePercentiles" : { + "0.0" : 0.013260811453736315, + "50.0" : 0.013277683403965193, + "90.0" : 0.013317628319385478, + "95.0" : 0.013317628319385478, + "99.0" : 0.013317628319385478, + "99.9" : 0.013317628319385478, + "99.99" : 0.013317628319385478, + "99.999" : 0.013317628319385478, + "99.9999" : 0.013317628319385478, + "100.0" : 0.013317628319385478 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013262359456728167, + 0.013260811453736315, + 0.013263177676507374 + ], + [ + 0.013312311038160581, + 0.013317628319385478, + 0.01329218913142301 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0524298727676078, + "scoreError" : 0.31651896165090876, + "scoreConfidence" : [ + 0.735910911116699, + 1.3689488344185166 + ], + "scorePercentiles" : { + "0.0" : 0.9482974781907832, + "50.0" : 1.0522439812975302, + "90.0" : 1.1560902230057803, + "95.0" : 1.1560902230057803, + "99.0" : 1.1560902230057803, + "99.9" : 1.1560902230057803, + "99.99" : 1.1560902230057803, + "99.999" : 1.1560902230057803, + "99.9999" : 1.1560902230057803, + "100.0" : 1.1560902230057803 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1560902230057803, + 1.1560513331406774, + 1.1542553313711912 + ], + [ + 0.9482974781907832, + 0.9502326312238693, + 0.9496522396733453 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010418188836098465, + "scoreError" : 3.314317211051785E-4, + "scoreConfidence" : [ + 0.010086757114993286, + 0.010749620557203644 + ], + "scorePercentiles" : { + "0.0" : 0.010306873812164262, + "50.0" : 0.010417321032912506, + "90.0" : 0.010531600576274185, + "95.0" : 0.010531600576274185, + "99.0" : 0.010531600576274185, + "99.9" : 0.010531600576274185, + "99.99" : 0.010531600576274185, + "99.999" : 0.010531600576274185, + "99.9999" : 0.010531600576274185, + "100.0" : 0.010531600576274185 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010521872718128503, + 0.010531600576274185, + 0.010524613871535379 + ], + [ + 0.010306873812164262, + 0.010311402690791956, + 0.010312769347696508 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.143070142953624, + "scoreError" : 0.15924950116588002, + "scoreConfidence" : [ + 2.983820641787744, + 3.3023196441195037 + ], + "scorePercentiles" : { + "0.0" : 3.07903597044335, + "50.0" : 3.144520015235258, + "90.0" : 3.2052303288461537, + "95.0" : 3.2052303288461537, + "99.0" : 3.2052303288461537, + "99.9" : 3.2052303288461537, + "99.99" : 3.2052303288461537, + "99.999" : 3.2052303288461537, + "99.9999" : 3.2052303288461537, + "100.0" : 3.2052303288461537 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2052303288461537, + 3.191565874282068, + 3.185463788535032 + ], + [ + 3.07903597044335, + 3.0935486536796537, + 3.103576241935484 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.906543587131805, + "scoreError" : 0.03034544518526469, + "scoreConfidence" : [ + 2.8761981419465403, + 2.9368890323170698 + ], + "scorePercentiles" : { + "0.0" : 2.891932198091382, + "50.0" : 2.91206557131654, + "90.0" : 2.9155620335276966, + "95.0" : 2.9155620335276966, + "99.0" : 2.9155620335276966, + "99.9" : 2.9155620335276966, + "99.99" : 2.9155620335276966, + "99.999" : 2.9155620335276966, + "99.9999" : 2.9155620335276966, + "100.0" : 2.9155620335276966 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9140065979020977, + 2.910162496654059, + 2.9155620335276966 + ], + [ + 2.893629550636574, + 2.913968645979021, + 2.891932198091382 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17725705435945885, + "scoreError" : 6.055690093922831E-4, + "scoreConfidence" : [ + 0.17665148535006656, + 0.17786262336885114 + ], + "scorePercentiles" : { + "0.0" : 0.1769843884395519, + "50.0" : 0.1772270733808966, + "90.0" : 0.17753531285838556, + "95.0" : 0.17753531285838556, + "99.0" : 0.17753531285838556, + "99.9" : 0.17753531285838556, + "99.99" : 0.17753531285838556, + "99.999" : 0.17753531285838556, + "99.9999" : 0.17753531285838556, + "100.0" : 0.17753531285838556 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17733039430425762, + 0.177115752966597, + 0.1769843884395519 + ], + [ + 0.17745272513042554, + 0.17753531285838556, + 0.17712375245753556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3261513059580012, + "scoreError" : 0.013117146293980968, + "scoreConfidence" : [ + 0.3130341596640202, + 0.33926845225198216 + ], + "scorePercentiles" : { + "0.0" : 0.32120384329029356, + "50.0" : 0.32638564338564535, + "90.0" : 0.330541314966616, + "95.0" : 0.330541314966616, + "99.0" : 0.330541314966616, + "99.9" : 0.330541314966616, + "99.99" : 0.330541314966616, + "99.999" : 0.330541314966616, + "99.9999" : 0.330541314966616, + "100.0" : 0.330541314966616 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3304295516933752, + 0.330541314966616, + 0.3302385647909649 + ], + [ + 0.32120384329029356, + 0.3219618390264319, + 0.32253272198032573 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14875283208564885, + "scoreError" : 0.0012435358783135042, + "scoreConfidence" : [ + 0.14750929620733536, + 0.14999636796396235 + ], + "scorePercentiles" : { + "0.0" : 0.14815042370596426, + "50.0" : 0.1487523356597178, + "90.0" : 0.14923021421536442, + "95.0" : 0.14923021421536442, + "99.0" : 0.14923021421536442, + "99.9" : 0.14923021421536442, + "99.99" : 0.14923021421536442, + "99.999" : 0.14923021421536442, + "99.9999" : 0.14923021421536442, + "100.0" : 0.14923021421536442 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1491745153124394, + 0.14923021421536442, + 0.1490045715882169 + ], + [ + 0.14845716796068942, + 0.14815042370596426, + 0.14850009973121872 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4172252503987513, + "scoreError" : 0.06007039679088737, + "scoreConfidence" : [ + 0.3571548536078639, + 0.4772956471896387 + ], + "scorePercentiles" : { + "0.0" : 0.39726845087991103, + "50.0" : 0.41712020490577295, + "90.0" : 0.4372320730587618, + "95.0" : 0.4372320730587618, + "99.0" : 0.4372320730587618, + "99.9" : 0.4372320730587618, + "99.99" : 0.4372320730587618, + "99.999" : 0.4372320730587618, + "99.9999" : 0.4372320730587618, + "100.0" : 0.4372320730587618 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3977801517899761, + 0.3979708047596307, + 0.39726845087991103 + ], + [ + 0.43683041685231294, + 0.4362696050519152, + 0.4372320730587618 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15898513961172192, + "scoreError" : 0.012389838642356354, + "scoreConfidence" : [ + 0.14659530096936557, + 0.17137497825407827 + ], + "scorePercentiles" : { + "0.0" : 0.15537523358503466, + "50.0" : 0.15668613429757094, + "90.0" : 0.1662426866262156, + "95.0" : 0.1662426866262156, + "99.0" : 0.1662426866262156, + "99.9" : 0.1662426866262156, + "99.99" : 0.1662426866262156, + "99.999" : 0.1662426866262156, + "99.9999" : 0.1662426866262156, + "100.0" : 0.1662426866262156 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.156546629492799, + 0.15623203763533253, + 0.15682563910234293 + ], + [ + 0.1662426866262156, + 0.15537523358503466, + 0.16268861122860676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04693592709633288, + "scoreError" : 0.002368394365338667, + "scoreConfidence" : [ + 0.044567532730994217, + 0.049304321461671546 + ], + "scorePercentiles" : { + "0.0" : 0.04609010241968936, + "50.0" : 0.04698496834144105, + "90.0" : 0.04770849034154068, + "95.0" : 0.04770849034154068, + "99.0" : 0.04770849034154068, + "99.9" : 0.04770849034154068, + "99.99" : 0.04770849034154068, + "99.999" : 0.04770849034154068, + "99.9999" : 0.04770849034154068, + "100.0" : 0.04770849034154068 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04770849034154068, + 0.04770098846605165, + 0.047705795030078095 + ], + [ + 0.04609010241968936, + 0.04614123810380706, + 0.046268948216830454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9363977.672261452, + "scoreError" : 567382.0574290771, + "scoreConfidence" : [ + 8796595.614832375, + 9931359.72969053 + ], + "scorePercentiles" : { + "0.0" : 9161486.075091574, + "50.0" : 9360385.903708858, + "90.0" : 9563297.985659655, + "95.0" : 9563297.985659655, + "99.0" : 9563297.985659655, + "99.9" : 9563297.985659655, + "99.99" : 9563297.985659655, + "99.999" : 9563297.985659655, + "99.9999" : 9563297.985659655, + "100.0" : 9563297.985659655 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9191993.295036765, + 9161486.075091574, + 9185890.162534434 + ], + [ + 9528778.512380952, + 9563297.985659655, + 9552420.00286533 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-28T11:37:28Z-3f0de4a7b48ad20c3e30e5c7fea0bf3f57ce5839-jdk17.json b/performance-results/2025-09-28T11:37:28Z-3f0de4a7b48ad20c3e30e5c7fea0bf3f57ce5839-jdk17.json new file mode 100644 index 0000000000..5c49c2f341 --- /dev/null +++ b/performance-results/2025-09-28T11:37:28Z-3f0de4a7b48ad20c3e30e5c7fea0bf3f57ce5839-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.314008789774307, + "scoreError" : 0.04241462006234165, + "scoreConfidence" : [ + 3.2715941697119653, + 3.356423409836649 + ], + "scorePercentiles" : { + "0.0" : 3.3058563388945497, + "50.0" : 3.314677463634016, + "90.0" : 3.320823892934646, + "95.0" : 3.320823892934646, + "99.0" : 3.320823892934646, + "99.9" : 3.320823892934646, + "99.99" : 3.320823892934646, + "99.999" : 3.320823892934646, + "99.9999" : 3.320823892934646, + "100.0" : 3.320823892934646 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.31189856928945, + 3.317456357978582 + ], + [ + 3.3058563388945497, + 3.320823892934646 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6752113643392523, + "scoreError" : 0.0208028090179944, + "scoreConfidence" : [ + 1.654408555321258, + 1.6960141733572467 + ], + "scorePercentiles" : { + "0.0" : 1.673019823637084, + "50.0" : 1.6739201551979241, + "90.0" : 1.6799853233240771, + "95.0" : 1.6799853233240771, + "99.0" : 1.6799853233240771, + "99.9" : 1.6799853233240771, + "99.99" : 1.6799853233240771, + "99.999" : 1.6799853233240771, + "99.9999" : 1.6799853233240771, + "100.0" : 1.6799853233240771 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.673634774989389, + 1.6742055354064591 + ], + [ + 1.673019823637084, + 1.6799853233240771 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8329697163970288, + "scoreError" : 0.05088711275775986, + "scoreConfidence" : [ + 0.782082603639269, + 0.8838568291547886 + ], + "scorePercentiles" : { + "0.0" : 0.8222081936816599, + "50.0" : 0.8351943924105409, + "90.0" : 0.8392818870853733, + "95.0" : 0.8392818870853733, + "99.0" : 0.8392818870853733, + "99.9" : 0.8392818870853733, + "99.99" : 0.8392818870853733, + "99.999" : 0.8392818870853733, + "99.9999" : 0.8392818870853733, + "100.0" : 0.8392818870853733 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8222081936816599, + 0.8383949343930645 + ], + [ + 0.8319938504280173, + 0.8392818870853733 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.01824741218742, + "scoreError" : 0.6005330335344947, + "scoreConfidence" : [ + 15.417714378652926, + 16.618780445721917 + ], + "scorePercentiles" : { + "0.0" : 15.7934490563086, + "50.0" : 16.017956958849943, + "90.0" : 16.235885357111663, + "95.0" : 16.235885357111663, + "99.0" : 16.235885357111663, + "99.9" : 16.235885357111663, + "99.99" : 16.235885357111663, + "99.999" : 16.235885357111663, + "99.9999" : 16.235885357111663, + "100.0" : 16.235885357111663 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.815825584355034, + 15.865855375482065, + 15.7934490563086 + ], + [ + 16.235885357111663, + 16.228410557649354, + 16.170058542217824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2577.5107578640273, + "scoreError" : 111.47374040521964, + "scoreConfidence" : [ + 2466.0370174588074, + 2688.984498269247 + ], + "scorePercentiles" : { + "0.0" : 2522.7080349621524, + "50.0" : 2588.7759700682336, + "90.0" : 2617.167645128689, + "95.0" : 2617.167645128689, + "99.0" : 2617.167645128689, + "99.9" : 2617.167645128689, + "99.99" : 2617.167645128689, + "99.999" : 2617.167645128689, + "99.9999" : 2617.167645128689, + "100.0" : 2617.167645128689 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2522.7080349621524, + 2537.3380664679185, + 2574.9443412598657 + ], + [ + 2617.167645128689, + 2610.2988604889374, + 2602.607598876601 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74536.45891510353, + "scoreError" : 760.9350853352792, + "scoreConfidence" : [ + 73775.52382976825, + 75297.39400043881 + ], + "scorePercentiles" : { + "0.0" : 74173.98060139695, + "50.0" : 74534.04451030455, + "90.0" : 74963.69515943294, + "95.0" : 74963.69515943294, + "99.0" : 74963.69515943294, + "99.9" : 74963.69515943294, + "99.99" : 74963.69515943294, + "99.999" : 74963.69515943294, + "99.9999" : 74963.69515943294, + "100.0" : 74963.69515943294 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74599.14211702555, + 74173.98060139695, + 74358.22370189102 + ], + [ + 74468.94690358356, + 74654.7650072912, + 74963.69515943294 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 349.37271673467336, + "scoreError" : 16.44807856446468, + "scoreConfidence" : [ + 332.9246381702087, + 365.820795299138 + ], + "scorePercentiles" : { + "0.0" : 341.9506007561679, + "50.0" : 351.2272547031589, + "90.0" : 354.8430323995652, + "95.0" : 354.8430323995652, + "99.0" : 354.8430323995652, + "99.9" : 354.8430323995652, + "99.99" : 354.8430323995652, + "99.999" : 354.8430323995652, + "99.9999" : 354.8430323995652, + "100.0" : 354.8430323995652 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.3449355411413, + 354.8430323995652, + 353.4770494067884 + ], + [ + 348.97745999952934, + 342.643222304848, + 341.9506007561679 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 111.53757013026215, + "scoreError" : 3.695342388965278, + "scoreConfidence" : [ + 107.84222774129688, + 115.23291251922743 + ], + "scorePercentiles" : { + "0.0" : 110.19823139333693, + "50.0" : 111.61922092653654, + "90.0" : 113.78792427929345, + "95.0" : 113.78792427929345, + "99.0" : 113.78792427929345, + "99.9" : 113.78792427929345, + "99.99" : 113.78792427929345, + "99.999" : 113.78792427929345, + "99.9999" : 113.78792427929345, + "100.0" : 113.78792427929345 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.72446258808411, + 111.51397926498898, + 110.19823139333693 + ], + [ + 113.78792427929345, + 111.77900920988479, + 110.22181404598467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06257253346192261, + "scoreError" : 0.0010809347824334002, + "scoreConfidence" : [ + 0.06149159867948921, + 0.06365346824435601 + ], + "scorePercentiles" : { + "0.0" : 0.06227081769951181, + "50.0" : 0.06237118887658796, + "90.0" : 0.06317758539867456, + "95.0" : 0.06317758539867456, + "99.0" : 0.06317758539867456, + "99.9" : 0.06317758539867456, + "99.99" : 0.06317758539867456, + "99.999" : 0.06317758539867456, + "99.9999" : 0.06317758539867456, + "100.0" : 0.06317758539867456 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06317758539867456, + 0.06293695945673791, + 0.062400109822225276 + ], + [ + 0.06234226793095064, + 0.06227081769951181, + 0.06230746046343545 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8104422908853084E-4, + "scoreError" : 2.9555531497728788E-5, + "scoreConfidence" : [ + 3.51488697590802E-4, + 4.1059976058625965E-4 + ], + "scorePercentiles" : { + "0.0" : 3.691059545201157E-4, + "50.0" : 3.805522832350023E-4, + "90.0" : 3.933463908654126E-4, + "95.0" : 3.933463908654126E-4, + "99.0" : 3.933463908654126E-4, + "99.9" : 3.933463908654126E-4, + "99.99" : 3.933463908654126E-4, + "99.999" : 3.933463908654126E-4, + "99.9999" : 3.933463908654126E-4, + "100.0" : 3.933463908654126E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.691059545201157E-4, + 3.7277062434607806E-4, + 3.7301779090383755E-4 + ], + [ + 3.933463908654126E-4, + 3.89937838329574E-4, + 3.88086775566167E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.5147762815884227, + "scoreError" : 0.09343401572962383, + "scoreConfidence" : [ + 2.421342265858799, + 2.6082102973180463 + ], + "scorePercentiles" : { + "0.0" : 2.4809094906970977, + "50.0" : 2.502931031156156, + "90.0" : 2.5740077578486877, + "95.0" : 2.5740077578486877, + "99.0" : 2.5740077578486877, + "99.9" : 2.5740077578486877, + "99.99" : 2.5740077578486877, + "99.999" : 2.5740077578486877, + "99.9999" : 2.5740077578486877, + "100.0" : 2.5740077578486877 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.5740077578486877, + 2.5031390735735735, + 2.4809094906970977 + ], + [ + 2.5314534720323967, + 2.5027229887387388, + 2.49642490664004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013211917134388703, + "scoreError" : 9.018885064487795E-5, + "scoreConfidence" : [ + 0.013121728283743826, + 0.01330210598503358 + ], + "scorePercentiles" : { + "0.0" : 0.013163604345771449, + "50.0" : 0.013222687797023899, + "90.0" : 0.013245836489541927, + "95.0" : 0.013245836489541927, + "99.0" : 0.013245836489541927, + "99.9" : 0.013245836489541927, + "99.99" : 0.013245836489541927, + "99.999" : 0.013245836489541927, + "99.9999" : 0.013245836489541927, + "100.0" : 0.013245836489541927 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013217681109002184, + 0.013182078220074452, + 0.013163604345771449 + ], + [ + 0.013227694485045615, + 0.013245836489541927, + 0.013234608156896584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9963920224707087, + "scoreError" : 0.1162429171424352, + "scoreConfidence" : [ + 0.8801491053282735, + 1.1126349396131439 + ], + "scorePercentiles" : { + "0.0" : 0.9579113626436782, + "50.0" : 0.9957960038934729, + "90.0" : 1.0357600411185914, + "95.0" : 1.0357600411185914, + "99.0" : 1.0357600411185914, + "99.9" : 1.0357600411185914, + "99.99" : 1.0357600411185914, + "99.999" : 1.0357600411185914, + "99.9999" : 1.0357600411185914, + "100.0" : 1.0357600411185914 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9579113626436782, + 0.9590306858457998, + 0.9587477846050614 + ], + [ + 1.0357600411185914, + 1.032561321941146, + 1.0343409386699762 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01040161657914577, + "scoreError" : 4.2741789208510704E-4, + "scoreConfidence" : [ + 0.009974198687060664, + 0.010829034471230877 + ], + "scorePercentiles" : { + "0.0" : 0.010244133399986888, + "50.0" : 0.01041135940838391, + "90.0" : 0.010548536998907206, + "95.0" : 0.010548536998907206, + "99.0" : 0.010548536998907206, + "99.9" : 0.010548536998907206, + "99.99" : 0.010548536998907206, + "99.999" : 0.010548536998907206, + "99.9999" : 0.010548536998907206, + "100.0" : 0.010548536998907206 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010548536998907206, + 0.010544492568442452, + 0.010525658277917065 + ], + [ + 0.010297060538850756, + 0.010244133399986888, + 0.010249817690770257 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.439188849709909, + "scoreError" : 0.6665965339509904, + "scoreConfidence" : [ + 2.7725923157589185, + 4.1057853836608995 + ], + "scorePercentiles" : { + "0.0" : 3.205009333119795, + "50.0" : 3.4269708064235713, + "90.0" : 3.677051331617647, + "95.0" : 3.677051331617647, + "99.0" : 3.677051331617647, + "99.9" : 3.677051331617647, + "99.99" : 3.677051331617647, + "99.999" : 3.677051331617647, + "99.9999" : 3.677051331617647, + "100.0" : 3.677051331617647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.205009333119795, + 3.2333436063348415, + 3.230903568475452 + ], + [ + 3.677051331617647, + 3.6682272521994137, + 3.620598006512301 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.904007474328752, + "scoreError" : 0.11602715317106929, + "scoreConfidence" : [ + 2.7879803211576824, + 3.0200346274998213 + ], + "scorePercentiles" : { + "0.0" : 2.8619051696709583, + "50.0" : 2.9044654440418958, + "90.0" : 2.946489165291691, + "95.0" : 2.946489165291691, + "99.0" : 2.946489165291691, + "99.9" : 2.946489165291691, + "99.99" : 2.946489165291691, + "99.999" : 2.946489165291691, + "99.9999" : 2.946489165291691, + "100.0" : 2.946489165291691 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9331919228739003, + 2.9441706856049454, + 2.946489165291691 + ], + [ + 2.8619051696709583, + 2.862548937321122, + 2.875738965209891 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18632433509154134, + "scoreError" : 0.026608797695635573, + "scoreConfidence" : [ + 0.15971553739590577, + 0.2129331327871769 + ], + "scorePercentiles" : { + "0.0" : 0.17736152262206695, + "50.0" : 0.18608439647790226, + "90.0" : 0.19589980917959568, + "95.0" : 0.19589980917959568, + "99.0" : 0.19589980917959568, + "99.9" : 0.19589980917959568, + "99.99" : 0.19589980917959568, + "99.999" : 0.19589980917959568, + "99.9999" : 0.19589980917959568, + "100.0" : 0.19589980917959568 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19428908323133415, + 0.19589980917959568, + 0.19472617065524292 + ], + [ + 0.17787970972447037, + 0.17778971513653818, + 0.17736152262206695 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32866715540648106, + "scoreError" : 8.780975902669096E-4, + "scoreConfidence" : [ + 0.32778905781621415, + 0.329545252996748 + ], + "scorePercentiles" : { + "0.0" : 0.3283038378910738, + "50.0" : 0.3285750315159803, + "90.0" : 0.32920356144451396, + "95.0" : 0.32920356144451396, + "99.0" : 0.32920356144451396, + "99.9" : 0.32920356144451396, + "99.99" : 0.32920356144451396, + "99.999" : 0.32920356144451396, + "99.9999" : 0.32920356144451396, + "100.0" : 0.32920356144451396 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3283038378910738, + 0.32920356144451396, + 0.3285161100160967 + ], + [ + 0.3288293600552413, + 0.32852787493429697, + 0.3286221880976636 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14574331270470028, + "scoreError" : 0.004478775253212766, + "scoreConfidence" : [ + 0.1412645374514875, + 0.15022208795791306 + ], + "scorePercentiles" : { + "0.0" : 0.14421321207620091, + "50.0" : 0.14557489910836663, + "90.0" : 0.1474142089536838, + "95.0" : 0.1474142089536838, + "99.0" : 0.1474142089536838, + "99.9" : 0.1474142089536838, + "99.99" : 0.1474142089536838, + "99.999" : 0.1474142089536838, + "99.9999" : 0.1474142089536838, + "100.0" : 0.1474142089536838 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14435521397329484, + 0.14421321207620091, + 0.14432962018849135 + ], + [ + 0.14679458424343844, + 0.14735303679309228, + 0.1474142089536838 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4034246492513369, + "scoreError" : 0.008997344566457217, + "scoreConfidence" : [ + 0.3944273046848797, + 0.41242199381779415 + ], + "scorePercentiles" : { + "0.0" : 0.4002134101568753, + "50.0" : 0.40292043651474885, + "90.0" : 0.4075895747299776, + "95.0" : 0.4075895747299776, + "99.0" : 0.4075895747299776, + "99.9" : 0.4075895747299776, + "99.99" : 0.4075895747299776, + "99.999" : 0.4075895747299776, + "99.9999" : 0.4075895747299776, + "100.0" : 0.4075895747299776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.401076211718938, + 0.4002134101568753, + 0.4005795036651312 + ], + [ + 0.4063245339265399, + 0.4075895747299776, + 0.40476466131055977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16576659391325677, + "scoreError" : 0.017149104156448592, + "scoreConfidence" : [ + 0.14861748975680816, + 0.18291569806970537 + ], + "scorePercentiles" : { + "0.0" : 0.1599088135663687, + "50.0" : 0.16560058402485228, + "90.0" : 0.17208362872334934, + "95.0" : 0.17208362872334934, + "99.0" : 0.17208362872334934, + "99.9" : 0.17208362872334934, + "99.99" : 0.17208362872334934, + "99.999" : 0.17208362872334934, + "99.9999" : 0.17208362872334934, + "100.0" : 0.17208362872334934 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17126788484329508, + 0.17208362872334934, + 0.1706394701385571 + ], + [ + 0.1605616979111475, + 0.1599088135663687, + 0.16013806829682295 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04717768998541607, + "scoreError" : 0.001771405082294385, + "scoreConfidence" : [ + 0.04540628490312169, + 0.04894909506771045 + ], + "scorePercentiles" : { + "0.0" : 0.04658995523243354, + "50.0" : 0.04713105965922479, + "90.0" : 0.04792876627397602, + "95.0" : 0.04792876627397602, + "99.0" : 0.04792876627397602, + "99.9" : 0.04792876627397602, + "99.99" : 0.04792876627397602, + "99.999" : 0.04792876627397602, + "99.9999" : 0.04792876627397602, + "100.0" : 0.04792876627397602 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04660038300232066, + 0.04658995523243354, + 0.04663569766498314 + ], + [ + 0.0476849160853166, + 0.04762642165346643, + 0.04792876627397602 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9213264.924470434, + "scoreError" : 868967.8667856371, + "scoreConfidence" : [ + 8344297.057684797, + 1.008223279125607E7 + ], + "scorePercentiles" : { + "0.0" : 8886337.555950267, + "50.0" : 9140098.366477784, + "90.0" : 9639563.648362234, + "95.0" : 9639563.648362234, + "99.0" : 9639563.648362234, + "99.9" : 9639563.648362234, + "99.99" : 9639563.648362234, + "99.999" : 9639563.648362234, + "99.9999" : 9639563.648362234, + "100.0" : 9639563.648362234 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9128992.959854014, + 8937190.236818587, + 8886337.555950267 + ], + [ + 9639563.648362234, + 9536301.37273594, + 9151203.773101555 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-09-28T12:49:23Z-45a7d597c343e87ccd2736f634eb676520eef5a1-jdk17.json b/performance-results/2025-09-28T12:49:23Z-45a7d597c343e87ccd2736f634eb676520eef5a1-jdk17.json new file mode 100644 index 0000000000..976edbb79d --- /dev/null +++ b/performance-results/2025-09-28T12:49:23Z-45a7d597c343e87ccd2736f634eb676520eef5a1-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3573770676804315, + "scoreError" : 0.0372023740197798, + "scoreConfidence" : [ + 3.3201746936606518, + 3.3945794417002113 + ], + "scorePercentiles" : { + "0.0" : 3.351963127371617, + "50.0" : 3.356040705840449, + "90.0" : 3.365463731669212, + "95.0" : 3.365463731669212, + "99.0" : 3.365463731669212, + "99.9" : 3.365463731669212, + "99.99" : 3.365463731669212, + "99.999" : 3.365463731669212, + "99.9999" : 3.365463731669212, + "100.0" : 3.365463731669212 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3568010632721865, + 3.365463731669212 + ], + [ + 3.351963127371617, + 3.3552803484087113 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.701446286514562, + "scoreError" : 0.03327606838783087, + "scoreConfidence" : [ + 1.6681702181267313, + 1.734722354902393 + ], + "scorePercentiles" : { + "0.0" : 1.6957454881850913, + "50.0" : 1.7015439786603643, + "90.0" : 1.7069517005524286, + "95.0" : 1.7069517005524286, + "99.0" : 1.7069517005524286, + "99.9" : 1.7069517005524286, + "99.99" : 1.7069517005524286, + "99.999" : 1.7069517005524286, + "99.9999" : 1.7069517005524286, + "100.0" : 1.7069517005524286 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6957454881850913, + 1.698652219853892 + ], + [ + 1.7044357374668364, + 1.7069517005524286 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.854620592777377, + "scoreError" : 0.025643493474185607, + "scoreConfidence" : [ + 0.8289770993031914, + 0.8802640862515626 + ], + "scorePercentiles" : { + "0.0" : 0.8494265449807054, + "50.0" : 0.855568089030005, + "90.0" : 0.8579196480687928, + "95.0" : 0.8579196480687928, + "99.0" : 0.8579196480687928, + "99.9" : 0.8579196480687928, + "99.99" : 0.8579196480687928, + "99.999" : 0.8579196480687928, + "99.9999" : 0.8579196480687928, + "100.0" : 0.8579196480687928 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8579196480687928, + 0.8575156802151622 + ], + [ + 0.8494265449807054, + 0.8536204978448477 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.395395271947198, + "scoreError" : 0.14479159077231285, + "scoreConfidence" : [ + 16.250603681174884, + 16.540186862719512 + ], + "scorePercentiles" : { + "0.0" : 16.338887723536807, + "50.0" : 16.378373580770432, + "90.0" : 16.466695458347516, + "95.0" : 16.466695458347516, + "99.0" : 16.466695458347516, + "99.9" : 16.466695458347516, + "99.99" : 16.466695458347516, + "99.999" : 16.466695458347516, + "99.9999" : 16.466695458347516, + "100.0" : 16.466695458347516 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.338887723536807, + 16.364623136062534, + 16.36080159583121 + ], + [ + 16.44923969242679, + 16.466695458347516, + 16.39212402547833 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2696.341750705173, + "scoreError" : 233.58282054999106, + "scoreConfidence" : [ + 2462.758930155182, + 2929.924571255164 + ], + "scorePercentiles" : { + "0.0" : 2619.1688203144463, + "50.0" : 2694.571061141222, + "90.0" : 2775.160949253664, + "95.0" : 2775.160949253664, + "99.0" : 2775.160949253664, + "99.9" : 2775.160949253664, + "99.99" : 2775.160949253664, + "99.999" : 2775.160949253664, + "99.9999" : 2775.160949253664, + "100.0" : 2775.160949253664 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2621.766253649908, + 2620.1031231688867, + 2619.1688203144463 + ], + [ + 2767.375868632536, + 2774.4754892115957, + 2775.160949253664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77939.56196765513, + "scoreError" : 370.0781000400471, + "scoreConfidence" : [ + 77569.48386761508, + 78309.64006769517 + ], + "scorePercentiles" : { + "0.0" : 77810.96008250768, + "50.0" : 77916.24211682155, + "90.0" : 78094.8505761046, + "95.0" : 78094.8505761046, + "99.0" : 78094.8505761046, + "99.9" : 78094.8505761046, + "99.99" : 78094.8505761046, + "99.999" : 78094.8505761046, + "99.9999" : 78094.8505761046, + "100.0" : 78094.8505761046 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 78073.67239108359, + 78094.8505761046, + 78000.8788592945 + ], + [ + 77810.96008250768, + 77825.40452259178, + 77831.6053743486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 363.49503939201776, + "scoreError" : 1.1373509945862947, + "scoreConfidence" : [ + 362.35768839743145, + 364.6323903866041 + ], + "scorePercentiles" : { + "0.0" : 363.00841301369746, + "50.0" : 363.5043540533728, + "90.0" : 364.0557112029149, + "95.0" : 364.0557112029149, + "99.0" : 364.0557112029149, + "99.9" : 364.0557112029149, + "99.99" : 364.0557112029149, + "99.999" : 364.0557112029149, + "99.9999" : 364.0557112029149, + "100.0" : 364.0557112029149 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 363.8038489710616, + 363.589890237666, + 363.4188178690797 + ], + [ + 363.093555057687, + 364.0557112029149, + 363.00841301369746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.47123648883388, + "scoreError" : 4.5718040236269335, + "scoreConfidence" : [ + 111.89943246520694, + 121.04304051246082 + ], + "scorePercentiles" : { + "0.0" : 114.90833861798698, + "50.0" : 116.44918455538483, + "90.0" : 118.04070475442956, + "95.0" : 118.04070475442956, + "99.0" : 118.04070475442956, + "99.9" : 118.04070475442956, + "99.99" : 118.04070475442956, + "99.999" : 118.04070475442956, + "99.9999" : 118.04070475442956, + "100.0" : 118.04070475442956 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.97271818366463, + 117.86087688337253, + 118.04070475442956 + ], + [ + 114.90833861798698, + 115.00728826615243, + 115.03749222739714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06047494639856729, + "scoreError" : 1.5391103258267883E-4, + "scoreConfidence" : [ + 0.06032103536598461, + 0.06062885743114997 + ], + "scorePercentiles" : { + "0.0" : 0.06040109985926807, + "50.0" : 0.06047085468113968, + "90.0" : 0.06054552628679364, + "95.0" : 0.06054552628679364, + "99.0" : 0.06054552628679364, + "99.9" : 0.06054552628679364, + "99.99" : 0.06054552628679364, + "99.999" : 0.06054552628679364, + "99.9999" : 0.06054552628679364, + "100.0" : 0.06054552628679364 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06047025328802162, + 0.06040109985926807, + 0.06054552628679364 + ], + [ + 0.06052825221075568, + 0.060471456074257725, + 0.060433090672307 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5307541354231633E-4, + "scoreError" : 8.108311117769504E-6, + "scoreConfidence" : [ + 3.449671024245468E-4, + 3.6118372466008585E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5036943791096623E-4, + "50.0" : 3.529057588032556E-4, + "90.0" : 3.56285345911571E-4, + "95.0" : 3.56285345911571E-4, + "99.0" : 3.56285345911571E-4, + "99.9" : 3.56285345911571E-4, + "99.99" : 3.56285345911571E-4, + "99.999" : 3.56285345911571E-4, + "99.9999" : 3.56285345911571E-4, + "100.0" : 3.56285345911571E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5551347483793217E-4, + 3.552934506510772E-4, + 3.56285345911571E-4 + ], + [ + 3.504727049869175E-4, + 3.5036943791096623E-4, + 3.50518066955434E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6495.137311416667, + "scoreError" : 10.580800927013952, + "scoreConfidence" : [ + 6484.556510489653, + 6505.718112343681 + ], + "scorePercentiles" : { + "0.0" : 6489.9264275, + "50.0" : 6496.776519, + "90.0" : 6498.245094, + "95.0" : 6498.245094, + "99.0" : 6498.245094, + "99.9" : 6498.245094, + "99.99" : 6498.245094, + "99.999" : 6498.245094, + "99.9999" : 6498.245094, + "100.0" : 6498.245094 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 6497.7046415, + 6498.245094, + 6490.9036535 + ], + [ + 6498.1956555, + 6495.8483965, + 6489.9264275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013037776364079068, + "scoreError" : 3.272341730244028E-4, + "scoreConfidence" : [ + 0.012710542191054665, + 0.013365010537103471 + ], + "scorePercentiles" : { + "0.0" : 0.01292964683849046, + "50.0" : 0.013038261747219757, + "90.0" : 0.01314484805426117, + "95.0" : 0.01314484805426117, + "99.0" : 0.01314484805426117, + "99.9" : 0.01314484805426117, + "99.99" : 0.01314484805426117, + "99.999" : 0.01314484805426117, + "99.9999" : 0.01314484805426117, + "100.0" : 0.01314484805426117 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01314484805426117, + 0.013144845183670144, + 0.013143196990247878 + ], + [ + 0.01292964683849046, + 0.012933326504191638, + 0.012930794613613118 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9983094399180912, + "scoreError" : 0.049334236135696506, + "scoreConfidence" : [ + 0.9489752037823946, + 1.0476436760537877 + ], + "scorePercentiles" : { + "0.0" : 0.9814484756624141, + "50.0" : 0.9983464602973076, + "90.0" : 1.0151593442290123, + "95.0" : 1.0151593442290123, + "99.0" : 1.0151593442290123, + "99.9" : 1.0151593442290123, + "99.99" : 1.0151593442290123, + "99.999" : 1.0151593442290123, + "99.9999" : 1.0151593442290123, + "100.0" : 1.0151593442290123 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9814484756624141, + 0.9828023950471698, + 0.9825279108862252 + ], + [ + 1.0138905255474453, + 1.0151593442290123, + 1.0140279881362806 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010196969733109624, + "scoreError" : 2.842842407934491E-4, + "scoreConfidence" : [ + 0.009912685492316175, + 0.010481253973903072 + ], + "scorePercentiles" : { + "0.0" : 0.010099291052644335, + "50.0" : 0.010196557820035843, + "90.0" : 0.010297588320338082, + "95.0" : 0.010297588320338082, + "99.0" : 0.010297588320338082, + "99.9" : 0.010297588320338082, + "99.99" : 0.010297588320338082, + "99.999" : 0.010297588320338082, + "99.9999" : 0.010297588320338082, + "100.0" : 0.010297588320338082 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010099291052644335, + 0.010103434936703745, + 0.010111070112432258 + ], + [ + 0.01028838844889989, + 0.010297588320338082, + 0.01028204552763943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0740147590391533, + "scoreError" : 0.20419846165742117, + "scoreConfidence" : [ + 2.8698162973817323, + 3.2782132206965744 + ], + "scorePercentiles" : { + "0.0" : 3.0060921971153847, + "50.0" : 3.069600350254446, + "90.0" : 3.147572238514789, + "95.0" : 3.147572238514789, + "99.0" : 3.147572238514789, + "99.9" : 3.147572238514789, + "99.99" : 3.147572238514789, + "99.999" : 3.147572238514789, + "99.9999" : 3.147572238514789, + "100.0" : 3.147572238514789 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.147572238514789, + 3.144509776869893, + 3.1285537023139462 + ], + [ + 3.0060921971153847, + 3.0067136412259616, + 3.0106469981949457 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.689742077173957, + "scoreError" : 0.05924811034072794, + "scoreConfidence" : [ + 2.630493966833229, + 2.7489901875146847 + ], + "scorePercentiles" : { + "0.0" : 2.668860516808965, + "50.0" : 2.6896800114771615, + "90.0" : 2.710820702900515, + "95.0" : 2.710820702900515, + "99.0" : 2.710820702900515, + "99.9" : 2.710820702900515, + "99.99" : 2.710820702900515, + "99.999" : 2.710820702900515, + "99.9999" : 2.710820702900515, + "100.0" : 2.710820702900515 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.67061774259012, + 2.668860516808965, + 2.6720305841346152 + ], + [ + 2.710820702900515, + 2.7087934777898157, + 2.707329438819708 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17732525610375874, + "scoreError" : 0.0026547821042158673, + "scoreConfidence" : [ + 0.17467047399954286, + 0.17998003820797462 + ], + "scorePercentiles" : { + "0.0" : 0.17670998395504586, + "50.0" : 0.1770115686810908, + "90.0" : 0.17921452971326166, + "95.0" : 0.17921452971326166, + "99.0" : 0.17921452971326166, + "99.9" : 0.17921452971326166, + "99.99" : 0.17921452971326166, + "99.999" : 0.17921452971326166, + "99.9999" : 0.17921452971326166, + "100.0" : 0.17921452971326166 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17921452971326166, + 0.17722614725481162, + 0.17712795079528146 + ], + [ + 0.17689518656690018, + 0.17670998395504586, + 0.17677773833725186 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3214128758542316, + "scoreError" : 0.012688790318188231, + "scoreConfidence" : [ + 0.30872408553604336, + 0.3341016661724199 + ], + "scorePercentiles" : { + "0.0" : 0.3172479205951399, + "50.0" : 0.3212981714145742, + "90.0" : 0.3258250528476476, + "95.0" : 0.3258250528476476, + "99.0" : 0.3258250528476476, + "99.9" : 0.3258250528476476, + "99.99" : 0.3258250528476476, + "99.999" : 0.3258250528476476, + "99.9999" : 0.3258250528476476, + "100.0" : 0.3258250528476476 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3173584111262734, + 0.3172479205951399, + 0.3172511645517416 + ], + [ + 0.3258250528476476, + 0.32523793170287496, + 0.32555677430171237 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14544657560568708, + "scoreError" : 0.013737668575178828, + "scoreConfidence" : [ + 0.13170890703050825, + 0.1591842441808659 + ], + "scorePercentiles" : { + "0.0" : 0.14093904800293147, + "50.0" : 0.14526542745690146, + "90.0" : 0.15074377021058502, + "95.0" : 0.15074377021058502, + "99.0" : 0.15074377021058502, + "99.9" : 0.15074377021058502, + "99.99" : 0.15074377021058502, + "99.999" : 0.15074377021058502, + "99.9999" : 0.15074377021058502, + "100.0" : 0.15074377021058502 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15074377021058502, + 0.1495175238999447, + 0.1494337046069246 + ], + [ + 0.14093904800293147, + 0.14094825660685845, + 0.1410971503068783 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4007326632808945, + "scoreError" : 0.014021736490580642, + "scoreConfidence" : [ + 0.3867109267903139, + 0.41475439977147516 + ], + "scorePercentiles" : { + "0.0" : 0.3945065894907097, + "50.0" : 0.4026830640948923, + "90.0" : 0.40494041778353645, + "95.0" : 0.40494041778353645, + "99.0" : 0.40494041778353645, + "99.9" : 0.40494041778353645, + "99.99" : 0.40494041778353645, + "99.999" : 0.40494041778353645, + "99.9999" : 0.40494041778353645, + "100.0" : 0.40494041778353645 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40494041778353645, + 0.4048262804112861, + 0.4047404325724462 + ], + [ + 0.40062569561733835, + 0.39475656381005014, + 0.3945065894907097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15950826254130665, + "scoreError" : 0.005857551022203361, + "scoreConfidence" : [ + 0.15365071151910328, + 0.16536581356351002 + ], + "scorePercentiles" : { + "0.0" : 0.15761391022711155, + "50.0" : 0.15910788549247828, + "90.0" : 0.16259217992033168, + "95.0" : 0.16259217992033168, + "99.0" : 0.16259217992033168, + "99.9" : 0.16259217992033168, + "99.99" : 0.16259217992033168, + "99.999" : 0.16259217992033168, + "99.9999" : 0.16259217992033168, + "100.0" : 0.16259217992033168 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15776121015018615, + 0.15778502313068998, + 0.15761391022711155 + ], + [ + 0.16259217992033168, + 0.1604307478542666, + 0.16086650396525376 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046539717559369836, + "scoreError" : 0.0014585768209207485, + "scoreConfidence" : [ + 0.045081140738449085, + 0.04799829438029059 + ], + "scorePercentiles" : { + "0.0" : 0.04589920037453184, + "50.0" : 0.04672463978271757, + "90.0" : 0.0470626504428527, + "95.0" : 0.0470626504428527, + "99.0" : 0.0470626504428527, + "99.9" : 0.0470626504428527, + "99.99" : 0.0470626504428527, + "99.999" : 0.0470626504428527, + "99.9999" : 0.0470626504428527, + "100.0" : 0.0470626504428527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04653922285669077, + 0.045913561812455234, + 0.04589920037453184 + ], + [ + 0.046910056708744374, + 0.04691361316094408, + 0.0470626504428527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8516975.72418855, + "scoreError" : 115893.91510264672, + "scoreConfidence" : [ + 8401081.809085902, + 8632869.639291197 + ], + "scorePercentiles" : { + "0.0" : 8468265.323454699, + "50.0" : 8522485.578783356, + "90.0" : 8563004.254280822, + "95.0" : 8563004.254280822, + "99.0" : 8563004.254280822, + "99.9" : 8563004.254280822, + "99.99" : 8563004.254280822, + "99.999" : 8563004.254280822, + "99.9999" : 8563004.254280822, + "100.0" : 8563004.254280822 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8563004.254280822, + 8550074.05982906, + 8546733.076003416 + ], + [ + 8475539.55, + 8498238.081563296, + 8468265.323454699 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-06T21:44:36Z-bca9112f6208e7b5f3be90f18826e8055de171a6-jdk17.json b/performance-results/2025-10-06T21:44:36Z-bca9112f6208e7b5f3be90f18826e8055de171a6-jdk17.json new file mode 100644 index 0000000000..ea60a53faf --- /dev/null +++ b/performance-results/2025-10-06T21:44:36Z-bca9112f6208e7b5f3be90f18826e8055de171a6-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3393840661134018, + "scoreError" : 0.06577381372992772, + "scoreConfidence" : [ + 3.2736102523834743, + 3.4051578798433293 + ], + "scorePercentiles" : { + "0.0" : 3.324824336952175, + "50.0" : 3.342230541305809, + "90.0" : 3.348250844889814, + "95.0" : 3.348250844889814, + "99.0" : 3.348250844889814, + "99.9" : 3.348250844889814, + "99.99" : 3.348250844889814, + "99.999" : 3.348250844889814, + "99.9999" : 3.348250844889814, + "100.0" : 3.348250844889814 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.324824336952175, + 3.343644678852801 + ], + [ + 3.3408164037588173, + 3.348250844889814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6816654049867235, + "scoreError" : 0.021638080553336818, + "scoreConfidence" : [ + 1.6600273244333867, + 1.7033034855400602 + ], + "scorePercentiles" : { + "0.0" : 1.677480251522569, + "50.0" : 1.6820635190082318, + "90.0" : 1.6850543304078613, + "95.0" : 1.6850543304078613, + "99.0" : 1.6850543304078613, + "99.9" : 1.6850543304078613, + "99.99" : 1.6850543304078613, + "99.999" : 1.6850543304078613, + "99.9999" : 1.6850543304078613, + "100.0" : 1.6850543304078613 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.677480251522569, + 1.6805937601735885 + ], + [ + 1.6850543304078613, + 1.6835332778428749 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8457285364386182, + "scoreError" : 0.038827145365275886, + "scoreConfidence" : [ + 0.8069013910733424, + 0.8845556818038941 + ], + "scorePercentiles" : { + "0.0" : 0.838465004910209, + "50.0" : 0.8462767806487431, + "90.0" : 0.8518955795467777, + "95.0" : 0.8518955795467777, + "99.0" : 0.8518955795467777, + "99.9" : 0.8518955795467777, + "99.99" : 0.8518955795467777, + "99.999" : 0.8518955795467777, + "99.9999" : 0.8518955795467777, + "100.0" : 0.8518955795467777 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.838465004910209, + 0.843368573411396 + ], + [ + 0.8491849878860902, + 0.8518955795467777 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.105836789241128, + "scoreError" : 0.7476140595016426, + "scoreConfidence" : [ + 15.358222729739484, + 16.85345084874277 + ], + "scorePercentiles" : { + "0.0" : 15.803397747375364, + "50.0" : 16.14443823731033, + "90.0" : 16.358409899958833, + "95.0" : 16.358409899958833, + "99.0" : 16.358409899958833, + "99.9" : 16.358409899958833, + "99.99" : 16.358409899958833, + "99.999" : 16.358409899958833, + "99.9999" : 16.358409899958833, + "100.0" : 16.358409899958833 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.965313861662315, + 15.834673292686755, + 15.803397747375364 + ], + [ + 16.34966332080516, + 16.358409899958833, + 16.323562612958344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2757.5314044709335, + "scoreError" : 118.10932654751461, + "scoreConfidence" : [ + 2639.422077923419, + 2875.640731018448 + ], + "scorePercentiles" : { + "0.0" : 2682.2377180417216, + "50.0" : 2775.9836814886876, + "90.0" : 2788.5927333305763, + "95.0" : 2788.5927333305763, + "99.0" : 2788.5927333305763, + "99.9" : 2788.5927333305763, + "99.99" : 2788.5927333305763, + "99.999" : 2788.5927333305763, + "99.9999" : 2788.5927333305763, + "100.0" : 2788.5927333305763 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2682.2377180417216, + 2734.191641631494, + 2770.073687822864 + ], + [ + 2788.198970844432, + 2788.5927333305763, + 2781.8936751545116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76135.30236437214, + "scoreError" : 1608.2176763015964, + "scoreConfidence" : [ + 74527.08468807054, + 77743.52004067374 + ], + "scorePercentiles" : { + "0.0" : 75483.43288316099, + "50.0" : 76001.59549419908, + "90.0" : 77079.4385852989, + "95.0" : 77079.4385852989, + "99.0" : 77079.4385852989, + "99.9" : 77079.4385852989, + "99.99" : 77079.4385852989, + "99.999" : 77079.4385852989, + "99.9999" : 77079.4385852989, + "100.0" : 77079.4385852989 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75483.43288316099, + 75778.4903955946, + 75835.83729909846 + ], + [ + 76467.26133378022, + 76167.35368929969, + 77079.4385852989 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 352.07642789187395, + "scoreError" : 11.719217608540701, + "scoreConfidence" : [ + 340.35721028333325, + 363.79564550041465 + ], + "scorePercentiles" : { + "0.0" : 346.8989537117176, + "50.0" : 352.17126161735735, + "90.0" : 356.7194454721357, + "95.0" : 356.7194454721357, + "99.0" : 356.7194454721357, + "99.9" : 356.7194454721357, + "99.99" : 356.7194454721357, + "99.999" : 356.7194454721357, + "99.9999" : 356.7194454721357, + "100.0" : 356.7194454721357 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 355.9765745343409, + 354.5265137087858, + 356.7194454721357 + ], + [ + 346.8989537117176, + 348.52107039833476, + 349.81600952592885 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.11206238986468, + "scoreError" : 6.764101107279889, + "scoreConfidence" : [ + 108.34796128258479, + 121.87616349714456 + ], + "scorePercentiles" : { + "0.0" : 112.51581700465533, + "50.0" : 115.40244783510373, + "90.0" : 117.60311527251159, + "95.0" : 117.60311527251159, + "99.0" : 117.60311527251159, + "99.9" : 117.60311527251159, + "99.99" : 117.60311527251159, + "99.999" : 117.60311527251159, + "99.9999" : 117.60311527251159, + "100.0" : 117.60311527251159 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.51581700465533, + 113.72433704917121, + 112.61235994888663 + ], + [ + 117.08055862103625, + 117.60311527251159, + 117.13618644292706 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06174467706577219, + "scoreError" : 0.001565407068951718, + "scoreConfidence" : [ + 0.060179269996820474, + 0.06331008413472392 + ], + "scorePercentiles" : { + "0.0" : 0.06124538956393925, + "50.0" : 0.061552499225385256, + "90.0" : 0.06278906514887045, + "95.0" : 0.06278906514887045, + "99.0" : 0.06278906514887045, + "99.9" : 0.06278906514887045, + "99.99" : 0.06278906514887045, + "99.999" : 0.06278906514887045, + "99.9999" : 0.06278906514887045, + "100.0" : 0.06278906514887045 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06124538956393925, + 0.061408047614953824, + 0.06155167350493636 + ], + [ + 0.061553324945834154, + 0.06278906514887045, + 0.061920561616099073 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5724794934487446E-4, + "scoreError" : 3.526658847602442E-5, + "scoreConfidence" : [ + 3.2198136086885004E-4, + 3.925145378208989E-4 + ], + "scorePercentiles" : { + "0.0" : 3.443754723307163E-4, + "50.0" : 3.5712952669604493E-4, + "90.0" : 3.7053693491823493E-4, + "95.0" : 3.7053693491823493E-4, + "99.0" : 3.7053693491823493E-4, + "99.9" : 3.7053693491823493E-4, + "99.99" : 3.7053693491823493E-4, + "99.999" : 3.7053693491823493E-4, + "99.9999" : 3.7053693491823493E-4, + "100.0" : 3.7053693491823493E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7053693491823493E-4, + 3.670358949765986E-4, + 3.683878902289874E-4 + ], + [ + 3.443754723307163E-4, + 3.4722315841549125E-4, + 3.4592834519921834E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6494.962316916667, + "scoreError" : 13.879348012771155, + "scoreConfidence" : [ + 6481.082968903896, + 6508.841664929439 + ], + "scorePercentiles" : { + "0.0" : 6489.461133, + "50.0" : 6495.61089375, + "90.0" : 6500.003721, + "95.0" : 6500.003721, + "99.0" : 6500.003721, + "99.9" : 6500.003721, + "99.99" : 6500.003721, + "99.999" : 6500.003721, + "99.9999" : 6500.003721, + "100.0" : 6500.003721 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 6498.543426, + 6492.6783615, + 6489.623364 + ], + [ + 6499.463896, + 6500.003721, + 6489.461133 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.012903655705554129, + "scoreError" : 9.944685277176038E-5, + "scoreConfidence" : [ + 0.012804208852782368, + 0.01300310255832589 + ], + "scorePercentiles" : { + "0.0" : 0.012854199278631713, + "50.0" : 0.012898045516914461, + "90.0" : 0.01295764951091865, + "95.0" : 0.01295764951091865, + "99.0" : 0.01295764951091865, + "99.9" : 0.01295764951091865, + "99.99" : 0.01295764951091865, + "99.999" : 0.01295764951091865, + "99.9999" : 0.01295764951091865, + "100.0" : 0.01295764951091865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012903236838234345, + 0.012854199278631713, + 0.01288714873378979 + ], + [ + 0.012892854195594577, + 0.012926845676155709, + 0.01295764951091865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0462064851949922, + "scoreError" : 0.35056126391919534, + "scoreConfidence" : [ + 0.6956452212757969, + 1.3967677491141874 + ], + "scorePercentiles" : { + "0.0" : 0.9313821275961628, + "50.0" : 1.0445490370813104, + "90.0" : 1.163402069799907, + "95.0" : 1.163402069799907, + "99.0" : 1.163402069799907, + "99.9" : 1.163402069799907, + "99.99" : 1.163402069799907, + "99.999" : 1.163402069799907, + "99.9999" : 1.163402069799907, + "100.0" : 1.163402069799907 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9313821275961628, + 0.9329518383244706, + 0.9319859958997297 + ], + [ + 1.1613706437115319, + 1.1561462358381502, + 1.163402069799907 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010154002720403862, + "scoreError" : 4.6861578855748024E-4, + "scoreConfidence" : [ + 0.009685386931846382, + 0.010622618508961342 + ], + "scorePercentiles" : { + "0.0" : 0.00995593061703174, + "50.0" : 0.010151347808365265, + "90.0" : 0.010376544259008691, + "95.0" : 0.010376544259008691, + "99.0" : 0.010376544259008691, + "99.9" : 0.010376544259008691, + "99.99" : 0.010376544259008691, + "99.999" : 0.010376544259008691, + "99.9999" : 0.010376544259008691, + "100.0" : 0.010376544259008691 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010047634106446, + 0.01002366362289584, + 0.00995593061703174 + ], + [ + 0.010376544259008691, + 0.01025506151028453, + 0.010265182206756382 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.958952399173146, + "scoreError" : 0.21317415348341887, + "scoreConfidence" : [ + 2.7457782456897273, + 3.172126552656565 + ], + "scorePercentiles" : { + "0.0" : 2.8789451076568797, + "50.0" : 2.9589990730492977, + "90.0" : 3.0562721967012827, + "95.0" : 3.0562721967012827, + "99.0" : 3.0562721967012827, + "99.9" : 3.0562721967012827, + "99.99" : 3.0562721967012827, + "99.999" : 3.0562721967012827, + "99.9999" : 3.0562721967012827, + "100.0" : 3.0562721967012827 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0562721967012827, + 3.0114263010234796, + 3.0108939879590606 + ], + [ + 2.8789451076568797, + 2.9071041581395347, + 2.8890726435586367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7450186867506083, + "scoreError" : 0.06388448066908226, + "scoreConfidence" : [ + 2.681134206081526, + 2.8089031674196905 + ], + "scorePercentiles" : { + "0.0" : 2.7226824956450737, + "50.0" : 2.733702624873194, + "90.0" : 2.775657668609492, + "95.0" : 2.775657668609492, + "99.0" : 2.775657668609492, + "99.9" : 2.775657668609492, + "99.99" : 2.775657668609492, + "99.999" : 2.775657668609492, + "99.9999" : 2.775657668609492, + "100.0" : 2.775657668609492 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7322075648729856, + 2.775657668609492, + 2.7721591416297118 + ], + [ + 2.7342358220338983, + 2.7331694277124896, + 2.7226824956450737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17893616381101893, + "scoreError" : 0.003686012251206939, + "scoreConfidence" : [ + 0.175250151559812, + 0.18262217606222586 + ], + "scorePercentiles" : { + "0.0" : 0.17737092185172046, + "50.0" : 0.17902525011591824, + "90.0" : 0.18017217488829634, + "95.0" : 0.18017217488829634, + "99.0" : 0.18017217488829634, + "99.9" : 0.18017217488829634, + "99.99" : 0.18017217488829634, + "99.999" : 0.18017217488829634, + "99.9999" : 0.18017217488829634, + "100.0" : 0.18017217488829634 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18004657146715158, + 0.18017217488829634, + 0.18014039603336154 + ], + [ + 0.17788298986089865, + 0.17737092185172046, + 0.17800392876468493 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.336362971121694, + "scoreError" : 0.01239194140341051, + "scoreConfidence" : [ + 0.3239710297182835, + 0.3487549125251045 + ], + "scorePercentiles" : { + "0.0" : 0.33160472132506547, + "50.0" : 0.3361841760169935, + "90.0" : 0.34100025878060425, + "95.0" : 0.34100025878060425, + "99.0" : 0.34100025878060425, + "99.9" : 0.34100025878060425, + "99.99" : 0.34100025878060425, + "99.999" : 0.34100025878060425, + "99.9999" : 0.34100025878060425, + "100.0" : 0.34100025878060425 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33160472132506547, + 0.3325284469309038, + 0.3330119470862471 + ], + [ + 0.34100025878060425, + 0.34067604765960346, + 0.33935640494773994 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14221811919264754, + "scoreError" : 0.0028900796566363246, + "scoreConfidence" : [ + 0.13932803953601122, + 0.14510819884928386 + ], + "scorePercentiles" : { + "0.0" : 0.1406805175494127, + "50.0" : 0.14265865027086397, + "90.0" : 0.14321378949403527, + "95.0" : 0.14321378949403527, + "99.0" : 0.14321378949403527, + "99.9" : 0.14321378949403527, + "99.99" : 0.14321378949403527, + "99.999" : 0.14321378949403527, + "99.9999" : 0.14321378949403527, + "100.0" : 0.14321378949403527 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14289205060939889, + 0.14120505696131036, + 0.1406805175494127 + ], + [ + 0.14286697868480078, + 0.14245032185692716, + 0.14321378949403527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4093246647507926, + "scoreError" : 0.022818180545027447, + "scoreConfidence" : [ + 0.38650648420576517, + 0.43214284529582003 + ], + "scorePercentiles" : { + "0.0" : 0.4011830281221166, + "50.0" : 0.40808554162038446, + "90.0" : 0.4184315846443515, + "95.0" : 0.4184315846443515, + "99.0" : 0.4184315846443515, + "99.9" : 0.4184315846443515, + "99.99" : 0.4184315846443515, + "99.999" : 0.4184315846443515, + "99.9999" : 0.4184315846443515, + "100.0" : 0.4184315846443515 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4180183589282729, + 0.4184315846443515, + 0.4131665074367873 + ], + [ + 0.4021439335692456, + 0.40300457580398164, + 0.4011830281221166 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15627084016303935, + "scoreError" : 0.0077204049524052356, + "scoreConfidence" : [ + 0.14855043521063413, + 0.16399124511544458 + ], + "scorePercentiles" : { + "0.0" : 0.15345857582174754, + "50.0" : 0.15635415420022053, + "90.0" : 0.15900438789690427, + "95.0" : 0.15900438789690427, + "99.0" : 0.15900438789690427, + "99.9" : 0.15900438789690427, + "99.99" : 0.15900438789690427, + "99.999" : 0.15900438789690427, + "99.9999" : 0.15900438789690427, + "100.0" : 0.15900438789690427 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15900438789690427, + 0.15869318895201218, + 0.15862743047492148 + ], + [ + 0.1540808779255196, + 0.15345857582174754, + 0.1537605799071312 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.048036403601231466, + "scoreError" : 0.0035586084639872523, + "scoreConfidence" : [ + 0.044477795137244217, + 0.051595012065218715 + ], + "scorePercentiles" : { + "0.0" : 0.04678703789236304, + "50.0" : 0.04801571301418221, + "90.0" : 0.04925744200789089, + "95.0" : 0.04925744200789089, + "99.0" : 0.04925744200789089, + "99.9" : 0.04925744200789089, + "99.99" : 0.04925744200789089, + "99.999" : 0.04925744200789089, + "99.9999" : 0.04925744200789089, + "100.0" : 0.04925744200789089 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04692483524940172, + 0.04678703789236304, + 0.04692747305934359 + ], + [ + 0.049103952969020835, + 0.04925744200789089, + 0.04921768042936874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8631106.049286822, + "scoreError" : 176921.2337387386, + "scoreConfidence" : [ + 8454184.815548083, + 8808027.28302556 + ], + "scorePercentiles" : { + "0.0" : 8559601.050470488, + "50.0" : 8626663.338150673, + "90.0" : 8727479.771378709, + "95.0" : 8727479.771378709, + "99.0" : 8727479.771378709, + "99.9" : 8727479.771378709, + "99.99" : 8727479.771378709, + "99.999" : 8727479.771378709, + "99.9999" : 8727479.771378709, + "100.0" : 8727479.771378709 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8604117.75322442, + 8559601.050470488, + 8576648.216981132 + ], + [ + 8649208.923076924, + 8669580.580589255, + 8727479.771378709 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-11T21:29:33Z-7f39f56d028b91691118f3e83084acfa0f901c4f-jdk17.json b/performance-results/2025-10-11T21:29:33Z-7f39f56d028b91691118f3e83084acfa0f901c4f-jdk17.json new file mode 100644 index 0000000000..bef3068b9e --- /dev/null +++ b/performance-results/2025-10-11T21:29:33Z-7f39f56d028b91691118f3e83084acfa0f901c4f-jdk17.json @@ -0,0 +1,1279 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3494613256679293, + "scoreError" : 0.012779583252561342, + "scoreConfidence" : [ + 3.336681742415368, + 3.3622409089204908 + ], + "scorePercentiles" : { + "0.0" : 3.3474541789070957, + "50.0" : 3.3491249001542664, + "90.0" : 3.352141323456088, + "95.0" : 3.352141323456088, + "99.0" : 3.352141323456088, + "99.9" : 3.352141323456088, + "99.99" : 3.352141323456088, + "99.999" : 3.352141323456088, + "99.9999" : 3.352141323456088, + "100.0" : 3.352141323456088 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3495095839728055, + 3.352141323456088 + ], + [ + 3.348740216335727, + 3.3474541789070957 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.686572471155633, + "scoreError" : 0.047281419068230565, + "scoreConfidence" : [ + 1.6392910520874024, + 1.7338538902238634 + ], + "scorePercentiles" : { + "0.0" : 1.6772410689506636, + "50.0" : 1.687943244507586, + "90.0" : 1.6931623266566964, + "95.0" : 1.6931623266566964, + "99.0" : 1.6931623266566964, + "99.9" : 1.6931623266566964, + "99.99" : 1.6931623266566964, + "99.999" : 1.6931623266566964, + "99.9999" : 1.6931623266566964, + "100.0" : 1.6931623266566964 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6772410689506636, + 1.6843135292946734 + ], + [ + 1.6931623266566964, + 1.6915729597204987 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8509698636908194, + "scoreError" : 0.018916648812393584, + "scoreConfidence" : [ + 0.8320532148784258, + 0.869886512503213 + ], + "scorePercentiles" : { + "0.0" : 0.8480475557494527, + "50.0" : 0.8503990331028728, + "90.0" : 0.8550338328080793, + "95.0" : 0.8550338328080793, + "99.0" : 0.8550338328080793, + "99.9" : 0.8550338328080793, + "99.99" : 0.8550338328080793, + "99.999" : 0.8550338328080793, + "99.9999" : 0.8550338328080793, + "100.0" : 0.8550338328080793 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8504225139057215, + 0.8550338328080793 + ], + [ + 0.8480475557494527, + 0.8503755523000239 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.286763827512576, + "scoreError" : 0.19790390270391436, + "scoreConfidence" : [ + 16.088859924808663, + 16.48466773021649 + ], + "scorePercentiles" : { + "0.0" : 16.215664028035498, + "50.0" : 16.283609047752357, + "90.0" : 16.36605674475218, + "95.0" : 16.36605674475218, + "99.0" : 16.36605674475218, + "99.9" : 16.36605674475218, + "99.99" : 16.36605674475218, + "99.999" : 16.36605674475218, + "99.9999" : 16.36605674475218, + "100.0" : 16.36605674475218 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.215664028035498, + 16.217459681573708, + 16.237823117511546 + ], + [ + 16.329394977993168, + 16.354184415209364, + 16.36605674475218 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2715.1767214367937, + "scoreError" : 230.66331323381922, + "scoreConfidence" : [ + 2484.5134082029745, + 2945.840034670613 + ], + "scorePercentiles" : { + "0.0" : 2637.2868368649133, + "50.0" : 2715.3782021816733, + "90.0" : 2793.077156751506, + "95.0" : 2793.077156751506, + "99.0" : 2793.077156751506, + "99.9" : 2793.077156751506, + "99.99" : 2793.077156751506, + "99.999" : 2793.077156751506, + "99.9999" : 2793.077156751506, + "100.0" : 2793.077156751506 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2637.2868368649133, + 2640.552561009385, + 2642.510192529743 + ], + [ + 2793.077156751506, + 2789.387369631609, + 2788.246211833604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 77011.54157666425, + "scoreError" : 2608.583826799485, + "scoreConfidence" : [ + 74402.95774986477, + 79620.12540346374 + ], + "scorePercentiles" : { + "0.0" : 76141.46781103406, + "50.0" : 77003.79246194298, + "90.0" : 77904.83038225982, + "95.0" : 77904.83038225982, + "99.0" : 77904.83038225982, + "99.9" : 77904.83038225982, + "99.99" : 77904.83038225982, + "99.999" : 77904.83038225982, + "99.9999" : 77904.83038225982, + "100.0" : 77904.83038225982 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 77853.05253164405, + 77823.04437709686, + 77904.83038225982 + ], + [ + 76141.46781103406, + 76184.54054678911, + 76162.31381116158 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 362.00314996952335, + "scoreError" : 7.004109424366095, + "scoreConfidence" : [ + 354.99904054515724, + 369.00725939388946 + ], + "scorePercentiles" : { + "0.0" : 359.4051283673726, + "50.0" : 361.8253131228389, + "90.0" : 364.76532066666823, + "95.0" : 364.76532066666823, + "99.0" : 364.76532066666823, + "99.9" : 364.76532066666823, + "99.99" : 364.76532066666823, + "99.999" : 364.76532066666823, + "99.9999" : 364.76532066666823, + "100.0" : 364.76532066666823 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 359.4051283673726, + 359.57121096695107, + 360.41927181378014 + ], + [ + 363.2313544318976, + 364.76532066666823, + 364.6266135704704 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.2575945189909, + "scoreError" : 2.6909687849759947, + "scoreConfidence" : [ + 113.5666257340149, + 118.94856330396689 + ], + "scorePercentiles" : { + "0.0" : 115.20419826240055, + "50.0" : 116.27446919995458, + "90.0" : 117.2160063387922, + "95.0" : 117.2160063387922, + "99.0" : 117.2160063387922, + "99.9" : 117.2160063387922, + "99.99" : 117.2160063387922, + "99.999" : 117.2160063387922, + "99.9999" : 117.2160063387922, + "100.0" : 117.2160063387922 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.14746705761324, + 117.01511921008053, + 117.2160063387922 + ], + [ + 115.20419826240055, + 115.53381918982862, + 115.42895705523017 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06127907089888868, + "scoreError" : 0.00140137342345168, + "scoreConfidence" : [ + 0.059877697475436996, + 0.06268044432234035 + ], + "scorePercentiles" : { + "0.0" : 0.060764960078021034, + "50.0" : 0.06130504302101565, + "90.0" : 0.061773000957469806, + "95.0" : 0.061773000957469806, + "99.0" : 0.061773000957469806, + "99.9" : 0.061773000957469806, + "99.99" : 0.061773000957469806, + "99.999" : 0.061773000957469806, + "99.9999" : 0.061773000957469806, + "100.0" : 0.061773000957469806 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06079065115925642, + 0.060922942301014346, + 0.060764960078021034 + ], + [ + 0.061773000957469806, + 0.061687143741016956, + 0.06173572715655347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7406564529763204E-4, + "scoreError" : 4.44270288907878E-5, + "scoreConfidence" : [ + 3.2963861640684423E-4, + 4.1849267418841984E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5935791576016706E-4, + "50.0" : 3.7424486718456627E-4, + "90.0" : 3.886030735781437E-4, + "95.0" : 3.886030735781437E-4, + "99.0" : 3.886030735781437E-4, + "99.9" : 3.886030735781437E-4, + "99.99" : 3.886030735781437E-4, + "99.999" : 3.886030735781437E-4, + "99.9999" : 3.886030735781437E-4, + "100.0" : 3.886030735781437E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.88499872670635E-4, + 3.8847759570385975E-4, + 3.886030735781437E-4 + ], + [ + 3.600121386652728E-4, + 3.594432754077143E-4, + 3.5935791576016706E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6496.576647083333, + "scoreError" : 21.584402158829644, + "scoreConfidence" : [ + 6474.992244924503, + 6518.161049242163 + ], + "scorePercentiles" : { + "0.0" : 6489.3069385, + "50.0" : 6493.81206575, + "90.0" : 6510.806913, + "95.0" : 6510.806913, + "99.0" : 6510.806913, + "99.9" : 6510.806913, + "99.99" : 6510.806913, + "99.999" : 6510.806913, + "99.9999" : 6510.806913, + "100.0" : 6510.806913 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 6510.806913, + 6493.8187355, + 6492.3555685 + ], + [ + 6499.366331, + 6493.805396, + 6489.3069385 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013071534877972807, + "scoreError" : 3.7479608638009144E-4, + "scoreConfidence" : [ + 0.012696738791592716, + 0.013446330964352897 + ], + "scorePercentiles" : { + "0.0" : 0.012946525508143238, + "50.0" : 0.013068845767432493, + "90.0" : 0.013206303395625424, + "95.0" : 0.013206303395625424, + "99.0" : 0.013206303395625424, + "99.9" : 0.013206303395625424, + "99.99" : 0.013206303395625424, + "99.999" : 0.013206303395625424, + "99.9999" : 0.013206303395625424, + "100.0" : 0.013206303395625424 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012952457513884859, + 0.012946525508143238, + 0.012950153212699803 + ], + [ + 0.013206303395625424, + 0.013188535616503395, + 0.013185234020980128 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0221122329669308, + "scoreError" : 0.23199484389062613, + "scoreConfidence" : [ + 0.7901173890763047, + 1.2541070768575568 + ], + "scorePercentiles" : { + "0.0" : 0.9462207809631943, + "50.0" : 1.0221016481154108, + "90.0" : 1.0979215361730157, + "95.0" : 1.0979215361730157, + "99.0" : 1.0979215361730157, + "99.9" : 1.0979215361730157, + "99.99" : 1.0979215361730157, + "99.999" : 1.0979215361730157, + "99.9999" : 1.0979215361730157, + "100.0" : 1.0979215361730157 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0978496920627951, + 1.0971327613823367, + 1.0979215361730157 + ], + [ + 0.9464780923717585, + 0.9470705348484848, + 0.9462207809631943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010001778264607778, + "scoreError" : 3.1704221174474263E-5, + "scoreConfidence" : [ + 0.009970074043433303, + 0.010033482485782253 + ], + "scorePercentiles" : { + "0.0" : 0.009982376434440957, + "50.0" : 0.010004194726078478, + "90.0" : 0.01001315701655135, + "95.0" : 0.01001315701655135, + "99.0" : 0.01001315701655135, + "99.9" : 0.01001315701655135, + "99.99" : 0.01001315701655135, + "99.999" : 0.01001315701655135, + "99.9999" : 0.01001315701655135, + "100.0" : 0.01001315701655135 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.00999752049938317, + 0.009999298503940629, + 0.009982376434440957 + ], + [ + 0.01001315701655135, + 0.010009090948216327, + 0.010009226185114233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.9854324193862047, + "scoreError" : 0.2974404856609421, + "scoreConfidence" : [ + 2.6879919337252627, + 3.282872905047147 + ], + "scorePercentiles" : { + "0.0" : 2.8849622906574393, + "50.0" : 2.985709090209444, + "90.0" : 3.0915777416563657, + "95.0" : 3.0915777416563657, + "99.0" : 3.0915777416563657, + "99.9" : 3.0915777416563657, + "99.99" : 3.0915777416563657, + "99.999" : 3.0915777416563657, + "99.9999" : 3.0915777416563657, + "100.0" : 3.0915777416563657 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.076804703567036, + 3.0915777416563657, + 3.077913464 + ], + [ + 2.894613476851852, + 2.8867228395845355, + 2.8849622906574393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.758253290363886, + "scoreError" : 0.10638071392243, + "scoreConfidence" : [ + 2.651872576441456, + 2.8646340042863163 + ], + "scorePercentiles" : { + "0.0" : 2.7190400421424687, + "50.0" : 2.7577134080266252, + "90.0" : 2.795686289069052, + "95.0" : 2.795686289069052, + "99.0" : 2.795686289069052, + "99.9" : 2.795686289069052, + "99.99" : 2.795686289069052, + "99.999" : 2.795686289069052, + "99.9999" : 2.795686289069052, + "100.0" : 2.795686289069052 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7256659572090487, + 2.726585385768811, + 2.7190400421424687 + ], + [ + 2.795686289069052, + 2.793700637709497, + 2.7888414302844393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17833646488861032, + "scoreError" : 0.0049199110990819726, + "scoreConfidence" : [ + 0.17341655378952836, + 0.1832563759876923 + ], + "scorePercentiles" : { + "0.0" : 0.17664254616430855, + "50.0" : 0.17833039055633187, + "90.0" : 0.1800755231569849, + "95.0" : 0.1800755231569849, + "99.0" : 0.1800755231569849, + "99.9" : 0.1800755231569849, + "99.99" : 0.1800755231569849, + "99.999" : 0.1800755231569849, + "99.9999" : 0.1800755231569849, + "100.0" : 0.1800755231569849 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17682031520970365, + 0.1767489541879496, + 0.17664254616430855 + ], + [ + 0.1800755231569849, + 0.17989098470975518, + 0.1798404659029601 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.35061888371486866, + "scoreError" : 0.06480043871515903, + "scoreConfidence" : [ + 0.28581844499970965, + 0.41541932243002766 + ], + "scorePercentiles" : { + "0.0" : 0.3292124717869371, + "50.0" : 0.34965080098693246, + "90.0" : 0.37486595854106536, + "95.0" : 0.37486595854106536, + "99.0" : 0.37486595854106536, + "99.9" : 0.37486595854106536, + "99.99" : 0.37486595854106536, + "99.999" : 0.37486595854106536, + "99.9999" : 0.37486595854106536, + "100.0" : 0.37486595854106536 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32971725901747445, + 0.3298365096474158, + 0.3292124717869371 + ], + [ + 0.37486595854106536, + 0.3706160109698699, + 0.3694650923264492 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14415480048259902, + "scoreError" : 0.013568403847564548, + "scoreConfidence" : [ + 0.13058639663503446, + 0.15772320433016357 + ], + "scorePercentiles" : { + "0.0" : 0.13968993443035146, + "50.0" : 0.1441487075464331, + "90.0" : 0.14865968997606624, + "95.0" : 0.14865968997606624, + "99.0" : 0.14865968997606624, + "99.9" : 0.14865968997606624, + "99.99" : 0.14865968997606624, + "99.999" : 0.14865968997606624, + "99.9999" : 0.14865968997606624, + "100.0" : 0.14865968997606624 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14856724076302535, + 0.14848728788216253, + 0.14865968997606624 + ], + [ + 0.1397145226332849, + 0.13981012721070366, + 0.13968993443035146 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40764824168324215, + "scoreError" : 0.026271745714335413, + "scoreConfidence" : [ + 0.3813764959689067, + 0.4339199873975776 + ], + "scorePercentiles" : { + "0.0" : 0.39886512599712826, + "50.0" : 0.4071241185520944, + "90.0" : 0.4171840606149097, + "95.0" : 0.4171840606149097, + "99.0" : 0.4171840606149097, + "99.9" : 0.4171840606149097, + "99.99" : 0.4171840606149097, + "99.999" : 0.4171840606149097, + "99.9999" : 0.4171840606149097, + "100.0" : 0.4171840606149097 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4171840606149097, + 0.4163693374136065, + 0.4149725665380306 + ], + [ + 0.39922268896961954, + 0.39886512599712826, + 0.39927567056615826 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15661503203640717, + "scoreError" : 0.0063913625577149335, + "scoreConfidence" : [ + 0.15022366947869223, + 0.1630063945941221 + ], + "scorePercentiles" : { + "0.0" : 0.15438460297954457, + "50.0" : 0.15629548565528933, + "90.0" : 0.1591372248408657, + "95.0" : 0.1591372248408657, + "99.0" : 0.1591372248408657, + "99.9" : 0.1591372248408657, + "99.99" : 0.1591372248408657, + "99.999" : 0.1591372248408657, + "99.9999" : 0.1591372248408657, + "100.0" : 0.1591372248408657 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1591372248408657, + 0.1590548418876147, + 0.15772772410964953 + ], + [ + 0.1545225511998393, + 0.15486324720092914, + 0.15438460297954457 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046850472881795814, + "scoreError" : 8.054320376881869E-4, + "scoreConfidence" : [ + 0.046045040844107626, + 0.047655904919484 + ], + "scorePercentiles" : { + "0.0" : 0.04669379334528679, + "50.0" : 0.04674238058355962, + "90.0" : 0.047433880084241285, + "95.0" : 0.047433880084241285, + "99.0" : 0.047433880084241285, + "99.9" : 0.047433880084241285, + "99.99" : 0.047433880084241285, + "99.999" : 0.047433880084241285, + "99.9999" : 0.047433880084241285, + "100.0" : 0.047433880084241285 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04675632102413525, + 0.04671641505458724, + 0.04669379334528679 + ], + [ + 0.047433880084241285, + 0.046728440142983975, + 0.046773987639540375 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8886938.438708296, + "scoreError" : 23149.006762205292, + "scoreConfidence" : [ + 8863789.431946091, + 8910087.4454705 + ], + "scorePercentiles" : { + "0.0" : 8877689.346938776, + "50.0" : 8887936.207371226, + "90.0" : 8899201.033807829, + "95.0" : 8899201.033807829, + "99.0" : 8899201.033807829, + "99.9" : 8899201.033807829, + "99.99" : 8899201.033807829, + "99.999" : 8899201.033807829, + "99.9999" : 8899201.033807829, + "100.0" : 8899201.033807829 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8899201.033807829, + 8891072.514666667, + 8888971.351687388 + ], + [ + 8886901.063055063, + 8877795.322094055, + 8877689.346938776 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-12T11:58:07Z-bce4817846d0f6f7af02cfbaf6240b23b18d105d-jdk17.json b/performance-results/2025-10-12T11:58:07Z-bce4817846d0f6f7af02cfbaf6240b23b18d105d-jdk17.json new file mode 100644 index 0000000000..f48373c12b --- /dev/null +++ b/performance-results/2025-10-12T11:58:07Z-bce4817846d0f6f7af02cfbaf6240b23b18d105d-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.334874650478584, + "scoreError" : 0.0733294557766752, + "scoreConfidence" : [ + 3.2615451947019087, + 3.4082041062552593 + ], + "scorePercentiles" : { + "0.0" : 3.3275702771797944, + "50.0" : 3.3300628835170825, + "90.0" : 3.3518025577003767, + "95.0" : 3.3518025577003767, + "99.0" : 3.3518025577003767, + "99.9" : 3.3518025577003767, + "99.99" : 3.3518025577003767, + "99.999" : 3.3518025577003767, + "99.9999" : 3.3518025577003767, + "100.0" : 3.3518025577003767 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3302915358112926, + 3.3518025577003767 + ], + [ + 3.3275702771797944, + 3.329834231222873 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6798181561098573, + "scoreError" : 0.06588161009639824, + "scoreConfidence" : [ + 1.6139365460134592, + 1.7456997662062554 + ], + "scorePercentiles" : { + "0.0" : 1.668380585372984, + "50.0" : 1.680738721562854, + "90.0" : 1.689414595940737, + "95.0" : 1.689414595940737, + "99.0" : 1.689414595940737, + "99.9" : 1.689414595940737, + "99.99" : 1.689414595940737, + "99.999" : 1.689414595940737, + "99.9999" : 1.689414595940737, + "100.0" : 1.689414595940737 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.668380585372984, + 1.6741347480554005 + ], + [ + 1.6873426950703074, + 1.689414595940737 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8405423298743612, + "scoreError" : 0.03920955751471709, + "scoreConfidence" : [ + 0.8013327723596441, + 0.8797518873890783 + ], + "scorePercentiles" : { + "0.0" : 0.8364682895407239, + "50.0" : 0.8380963816572362, + "90.0" : 0.849508266642248, + "95.0" : 0.849508266642248, + "99.0" : 0.849508266642248, + "99.9" : 0.849508266642248, + "99.99" : 0.849508266642248, + "99.999" : 0.849508266642248, + "99.9999" : 0.849508266642248, + "100.0" : 0.849508266642248 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8372301789521506, + 0.849508266642248 + ], + [ + 0.8364682895407239, + 0.838962584362322 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.202934641392456, + "scoreError" : 0.17032051883837662, + "scoreConfidence" : [ + 16.03261412255408, + 16.373255160230833 + ], + "scorePercentiles" : { + "0.0" : 16.13434717800659, + "50.0" : 16.19143722058228, + "90.0" : 16.276982669727392, + "95.0" : 16.276982669727392, + "99.0" : 16.276982669727392, + "99.9" : 16.276982669727392, + "99.99" : 16.276982669727392, + "99.999" : 16.276982669727392, + "99.9999" : 16.276982669727392, + "100.0" : 16.276982669727392 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.267457416421514, + 16.276982669727392, + 16.13434717800659 + ], + [ + 16.155946143034676, + 16.219920952065994, + 16.162953489098566 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2672.7268209716517, + "scoreError" : 86.99684993135682, + "scoreConfidence" : [ + 2585.729971040295, + 2759.7236709030085 + ], + "scorePercentiles" : { + "0.0" : 2637.3461783380835, + "50.0" : 2675.1675506964343, + "90.0" : 2705.558934193761, + "95.0" : 2705.558934193761, + "99.0" : 2705.558934193761, + "99.9" : 2705.558934193761, + "99.99" : 2705.558934193761, + "99.999" : 2705.558934193761, + "99.9999" : 2705.558934193761, + "100.0" : 2705.558934193761 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2697.4596471956415, + 2705.558934193761, + 2698.7096483750893 + ], + [ + 2652.875454197227, + 2644.4110635301095, + 2637.3461783380835 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 76734.15561376506, + "scoreError" : 1313.109858193552, + "scoreConfidence" : [ + 75421.04575557151, + 78047.26547195861 + ], + "scorePercentiles" : { + "0.0" : 76128.44007663561, + "50.0" : 76675.12837955286, + "90.0" : 77345.99926588064, + "95.0" : 77345.99926588064, + "99.0" : 77345.99926588064, + "99.9" : 77345.99926588064, + "99.99" : 77345.99926588064, + "99.999" : 77345.99926588064, + "99.9999" : 77345.99926588064, + "100.0" : 77345.99926588064 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 76128.44007663561, + 76478.3768232623, + 76426.47449832177 + ], + [ + 76871.87993584342, + 77153.76308264656, + 77345.99926588064 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.5610887067747, + "scoreError" : 4.90524211699213, + "scoreConfidence" : [ + 351.6558465897825, + 361.46633082376684 + ], + "scorePercentiles" : { + "0.0" : 353.5564931764435, + "50.0" : 356.73804154866207, + "90.0" : 358.47111998930075, + "95.0" : 358.47111998930075, + "99.0" : 358.47111998930075, + "99.9" : 358.47111998930075, + "99.99" : 358.47111998930075, + "99.999" : 358.47111998930075, + "99.9999" : 358.47111998930075, + "100.0" : 358.47111998930075 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.554261896737, + 357.9847976027941, + 356.92182120058715 + ], + [ + 353.5564931764435, + 355.87803837478606, + 358.47111998930075 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.20357932001933, + "scoreError" : 3.8198043785548146, + "scoreConfidence" : [ + 109.38377494146451, + 117.02338369857415 + ], + "scorePercentiles" : { + "0.0" : 111.12235902999046, + "50.0" : 113.29084797747072, + "90.0" : 114.75715531278253, + "95.0" : 114.75715531278253, + "99.0" : 114.75715531278253, + "99.9" : 114.75715531278253, + "99.99" : 114.75715531278253, + "99.999" : 114.75715531278253, + "99.9999" : 114.75715531278253, + "100.0" : 114.75715531278253 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.9055018770005, + 114.30192716338375, + 114.75715531278253 + ], + [ + 112.67619407794093, + 111.12235902999046, + 112.4583384590178 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06166578148892898, + "scoreError" : 0.001393558875137769, + "scoreConfidence" : [ + 0.060272222613791206, + 0.06305934036406674 + ], + "scorePercentiles" : { + "0.0" : 0.061040789558497684, + "50.0" : 0.06177333341616005, + "90.0" : 0.06223541570670202, + "95.0" : 0.06223541570670202, + "99.0" : 0.06223541570670202, + "99.9" : 0.06223541570670202, + "99.99" : 0.06223541570670202, + "99.999" : 0.06223541570670202, + "99.9999" : 0.06223541570670202, + "100.0" : 0.06223541570670202 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061040789558497684, + 0.0620748336985332, + 0.06109698313752085 + ], + [ + 0.06223541570670202, + 0.06182690927638738, + 0.061719757555932724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6795940097405095E-4, + "scoreError" : 1.1160501425676191E-5, + "scoreConfidence" : [ + 3.567988995483748E-4, + 3.7911990239972713E-4 + ], + "scorePercentiles" : { + "0.0" : 3.631679622235782E-4, + "50.0" : 3.6879224182151117E-4, + "90.0" : 3.7212592222979037E-4, + "95.0" : 3.7212592222979037E-4, + "99.0" : 3.7212592222979037E-4, + "99.9" : 3.7212592222979037E-4, + "99.99" : 3.7212592222979037E-4, + "99.999" : 3.7212592222979037E-4, + "99.9999" : 3.7212592222979037E-4, + "100.0" : 3.7212592222979037E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.716721979770859E-4, + 3.7212592222979037E-4, + 3.695383873047979E-4 + ], + [ + 3.632058397708289E-4, + 3.631679622235782E-4, + 3.680460963382244E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2602250666068544, + "scoreError" : 0.054856426911321365, + "scoreConfidence" : [ + 2.205368639695533, + 2.315081493518176 + ], + "scorePercentiles" : { + "0.0" : 2.1995577725973168, + "50.0" : 2.269421266057476, + "90.0" : 2.307198495439022, + "95.0" : 2.3079636125086544, + "99.0" : 2.3079636125086544, + "99.9" : 2.3079636125086544, + "99.99" : 2.3079636125086544, + "99.999" : 2.3079636125086544, + "99.9999" : 2.3079636125086544, + "100.0" : 2.3079636125086544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.3079636125086544, + 2.2478529633625532, + 2.265563615088355, + 2.2095519714980116, + 2.1995577725973168 + ], + [ + 2.3003124418123275, + 2.285693322669104, + 2.273278917026597, + 2.2747068644530364, + 2.2377691850525845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013105716670155768, + "scoreError" : 3.031350262385553E-4, + "scoreConfidence" : [ + 0.012802581643917212, + 0.013408851696394324 + ], + "scorePercentiles" : { + "0.0" : 0.0129981063348034, + "50.0" : 0.013104397765924803, + "90.0" : 0.013230033270315359, + "95.0" : 0.013230033270315359, + "99.0" : 0.013230033270315359, + "99.9" : 0.013230033270315359, + "99.99" : 0.013230033270315359, + "99.999" : 0.013230033270315359, + "99.9999" : 0.013230033270315359, + "100.0" : 0.013230033270315359 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013230033270315359, + 0.013185797592048566, + 0.013193656350270202 + ], + [ + 0.0129981063348034, + 0.013022997939801039, + 0.013003708533696045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.05348536806851, + "scoreError" : 0.303074437140624, + "scoreConfidence" : [ + 0.7504109309278859, + 1.3565598052091339 + ], + "scorePercentiles" : { + "0.0" : 0.9523855518522045, + "50.0" : 1.0540417665761823, + "90.0" : 1.1570364536619229, + "95.0" : 1.1570364536619229, + "99.0" : 1.1570364536619229, + "99.9" : 1.1570364536619229, + "99.99" : 1.1570364536619229, + "99.999" : 1.1570364536619229, + "99.9999" : 1.1570364536619229, + "100.0" : 1.1570364536619229 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9536324994755412, + 0.9523855518522045, + 0.9585983586696061 + ], + [ + 1.1494851744827586, + 1.1497741702690274, + 1.1570364536619229 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010728574518038244, + "scoreError" : 2.5383307606501824E-4, + "scoreConfidence" : [ + 0.010474741441973225, + 0.010982407594103263 + ], + "scorePercentiles" : { + "0.0" : 0.010620956096265772, + "50.0" : 0.010725752554612528, + "90.0" : 0.010854886566963288, + "95.0" : 0.010854886566963288, + "99.0" : 0.010854886566963288, + "99.9" : 0.010854886566963288, + "99.99" : 0.010854886566963288, + "99.999" : 0.010854886566963288, + "99.9999" : 0.010854886566963288, + "100.0" : 0.010854886566963288 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010854886566963288, + 0.010777689818766544, + 0.01078504270344423 + ], + [ + 0.010620956096265772, + 0.010659056632331122, + 0.010673815290458513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.104995500958499, + "scoreError" : 0.1978268273042192, + "scoreConfidence" : [ + 2.9071686736542794, + 3.3028223282627183 + ], + "scorePercentiles" : { + "0.0" : 3.023599038694075, + "50.0" : 3.1061568816139618, + "90.0" : 3.2185080135135133, + "95.0" : 3.2185080135135133, + "99.0" : 3.2185080135135133, + "99.9" : 3.2185080135135133, + "99.99" : 3.2185080135135133, + "99.999" : 3.2185080135135133, + "99.9999" : 3.2185080135135133, + "100.0" : 3.2185080135135133 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.023599038694075, + 3.1354982413793104, + 3.0400539489361704 + ], + [ + 3.116724943302181, + 3.2185080135135133, + 3.0955888199257426 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.811853634433998, + "scoreError" : 0.09752713229137792, + "scoreConfidence" : [ + 2.71432650214262, + 2.9093807667253757 + ], + "scorePercentiles" : { + "0.0" : 2.777064294362677, + "50.0" : 2.8049549662509614, + "90.0" : 2.86212831416309, + "95.0" : 2.86212831416309, + "99.0" : 2.86212831416309, + "99.9" : 2.86212831416309, + "99.99" : 2.86212831416309, + "99.999" : 2.86212831416309, + "99.9999" : 2.86212831416309, + "100.0" : 2.86212831416309 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.784424982739421, + 2.777064294362677, + 2.784954998886104 + ], + [ + 2.8375942828368794, + 2.86212831416309, + 2.8249549336158193 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18397182498882592, + "scoreError" : 0.041681381837962585, + "scoreConfidence" : [ + 0.14229044315086334, + 0.2256532068267885 + ], + "scorePercentiles" : { + "0.0" : 0.17016233597645017, + "50.0" : 0.1836557068510387, + "90.0" : 0.19864490044098368, + "95.0" : 0.19864490044098368, + "99.0" : 0.19864490044098368, + "99.9" : 0.19864490044098368, + "99.99" : 0.19864490044098368, + "99.999" : 0.19864490044098368, + "99.9999" : 0.19864490044098368, + "100.0" : 0.19864490044098368 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.19864490044098368, + 0.19748390550574668, + 0.19644301791537344 + ], + [ + 0.170868395786704, + 0.17016233597645017, + 0.17022839430769754 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32527489787834224, + "scoreError" : 0.0024176429533079866, + "scoreConfidence" : [ + 0.32285725492503425, + 0.3276925408316502 + ], + "scorePercentiles" : { + "0.0" : 0.3240460608535044, + "50.0" : 0.32526018961085174, + "90.0" : 0.3264472955866031, + "95.0" : 0.3264472955866031, + "99.0" : 0.3264472955866031, + "99.9" : 0.3264472955866031, + "99.99" : 0.3264472955866031, + "99.999" : 0.3264472955866031, + "99.9999" : 0.3264472955866031, + "100.0" : 0.3264472955866031 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3264472955866031, + 0.3240460608535044, + 0.32502842709958396 + ], + [ + 0.3259180138513183, + 0.3254919521221195, + 0.32471763775692436 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14633436214857262, + "scoreError" : 0.0025690300876691063, + "scoreConfidence" : [ + 0.14376533206090353, + 0.14890339223624172 + ], + "scorePercentiles" : { + "0.0" : 0.14541748146694006, + "50.0" : 0.14617164832531737, + "90.0" : 0.14808852881596873, + "95.0" : 0.14808852881596873, + "99.0" : 0.14808852881596873, + "99.9" : 0.14808852881596873, + "99.99" : 0.14808852881596873, + "99.999" : 0.14808852881596873, + "99.9999" : 0.14808852881596873, + "100.0" : 0.14808852881596873 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1462846263073975, + 0.14610158686282818, + 0.14541748146694006 + ], + [ + 0.14808852881596873, + 0.14624170978780657, + 0.1458722396504945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4078401417111381, + "scoreError" : 0.006070400940484759, + "scoreConfidence" : [ + 0.4017697407706533, + 0.41391054265162286 + ], + "scorePercentiles" : { + "0.0" : 0.40549977824182953, + "50.0" : 0.40777394468676953, + "90.0" : 0.41060328404845003, + "95.0" : 0.41060328404845003, + "99.0" : 0.41060328404845003, + "99.9" : 0.41060328404845003, + "99.99" : 0.41060328404845003, + "99.999" : 0.41060328404845003, + "99.9999" : 0.41060328404845003, + "100.0" : 0.41060328404845003 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41060328404845003, + 0.40549977824182953, + 0.4057211696283674 + ], + [ + 0.40966872897464257, + 0.4088866461544752, + 0.4066612432190639 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15776565180558264, + "scoreError" : 0.007791672781902128, + "scoreConfidence" : [ + 0.1499739790236805, + 0.16555732458748476 + ], + "scorePercentiles" : { + "0.0" : 0.15491989293736735, + "50.0" : 0.1578083312908437, + "90.0" : 0.16040673480583226, + "95.0" : 0.16040673480583226, + "99.0" : 0.16040673480583226, + "99.9" : 0.16040673480583226, + "99.99" : 0.16040673480583226, + "99.999" : 0.16040673480583226, + "99.9999" : 0.16040673480583226, + "100.0" : 0.16040673480583226 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15544408446544594, + 0.15491989293736735, + 0.15534146862184664 + ], + [ + 0.1603091518867622, + 0.16017257811624144, + 0.16040673480583226 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04748766377982861, + "scoreError" : 0.004794051268280141, + "scoreConfidence" : [ + 0.04269361251154847, + 0.05228171504810875 + ], + "scorePercentiles" : { + "0.0" : 0.04587141836388323, + "50.0" : 0.04747167515524625, + "90.0" : 0.04913096195361131, + "95.0" : 0.04913096195361131, + "99.0" : 0.04913096195361131, + "99.9" : 0.04913096195361131, + "99.99" : 0.04913096195361131, + "99.999" : 0.04913096195361131, + "99.9999" : 0.04913096195361131, + "100.0" : 0.04913096195361131 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.049028625839600715, + 0.04898273092277022, + 0.04913096195361131 + ], + [ + 0.04596061938772227, + 0.045951626211383906, + 0.04587141836388323 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8886472.121868137, + "scoreError" : 174410.93292251904, + "scoreConfidence" : [ + 8712061.188945618, + 9060883.054790657 + ], + "scorePercentiles" : { + "0.0" : 8782565.760316066, + "50.0" : 8910320.20035619, + "90.0" : 8946762.450805008, + "95.0" : 8946762.450805008, + "99.0" : 8946762.450805008, + "99.9" : 8946762.450805008, + "99.99" : 8946762.450805008, + "99.999" : 8946762.450805008, + "99.9999" : 8946762.450805008, + "100.0" : 8946762.450805008 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8946762.450805008, + 8911585.62511131, + 8927800.557537913 + ], + [ + 8909054.775601069, + 8841063.561837455, + 8782565.760316066 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-13T21:01:48Z-aa163f14936e8b09d766e5581963b91a29e9a6bb-jdk17.json b/performance-results/2025-10-13T21:01:48Z-aa163f14936e8b09d766e5581963b91a29e9a6bb-jdk17.json new file mode 100644 index 0000000000..bb54e21ac6 --- /dev/null +++ b/performance-results/2025-10-13T21:01:48Z-aa163f14936e8b09d766e5581963b91a29e9a6bb-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3618301409910187, + "scoreError" : 0.02023418754462769, + "scoreConfidence" : [ + 3.341595953446391, + 3.3820643285356464 + ], + "scorePercentiles" : { + "0.0" : 3.3577215376865004, + "50.0" : 3.362355835460109, + "90.0" : 3.3648873553573555, + "95.0" : 3.3648873553573555, + "99.0" : 3.3648873553573555, + "99.9" : 3.3648873553573555, + "99.99" : 3.3648873553573555, + "99.999" : 3.3648873553573555, + "99.9999" : 3.3648873553573555, + "100.0" : 3.3648873553573555 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3577215376865004, + 3.3635035576139694 + ], + [ + 3.361208113306249, + 3.3648873553573555 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6956837516810332, + "scoreError" : 0.029576401808779948, + "scoreConfidence" : [ + 1.6661073498722534, + 1.725260153489813 + ], + "scorePercentiles" : { + "0.0" : 1.6903907284593391, + "50.0" : 1.695596727039809, + "90.0" : 1.7011508241851758, + "95.0" : 1.7011508241851758, + "99.0" : 1.7011508241851758, + "99.9" : 1.7011508241851758, + "99.99" : 1.7011508241851758, + "99.999" : 1.7011508241851758, + "99.9999" : 1.7011508241851758, + "100.0" : 1.7011508241851758 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6971661441021393, + 1.7011508241851758 + ], + [ + 1.6903907284593391, + 1.6940273099774783 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8551071311443119, + "scoreError" : 0.01621703997938533, + "scoreConfidence" : [ + 0.8388900911649266, + 0.8713241711236972 + ], + "scorePercentiles" : { + "0.0" : 0.8529944311597017, + "50.0" : 0.854736997031417, + "90.0" : 0.8579600993547118, + "95.0" : 0.8579600993547118, + "99.0" : 0.8579600993547118, + "99.9" : 0.8579600993547118, + "99.99" : 0.8579600993547118, + "99.999" : 0.8579600993547118, + "99.9999" : 0.8579600993547118, + "100.0" : 0.8579600993547118 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8564715607696112, + 0.8579600993547118 + ], + [ + 0.8529944311597017, + 0.8530024332932229 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.483442436598327, + "scoreError" : 0.37697273007453463, + "scoreConfidence" : [ + 16.106469706523793, + 16.860415166672862 + ], + "scorePercentiles" : { + "0.0" : 16.3535406787147, + "50.0" : 16.481759216567077, + "90.0" : 16.61597618778554, + "95.0" : 16.61597618778554, + "99.0" : 16.61597618778554, + "99.9" : 16.61597618778554, + "99.99" : 16.61597618778554, + "99.999" : 16.61597618778554, + "99.9999" : 16.61597618778554, + "100.0" : 16.61597618778554 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.603630616055433, + 16.598378759956994, + 16.61597618778554 + ], + [ + 16.3535406787147, + 16.363988703900148, + 16.36513967317716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2775.4714487287365, + "scoreError" : 129.49374910038117, + "scoreConfidence" : [ + 2645.9776996283554, + 2904.9651978291176 + ], + "scorePercentiles" : { + "0.0" : 2732.5740015828583, + "50.0" : 2775.4669241047322, + "90.0" : 2818.4589304483407, + "95.0" : 2818.4589304483407, + "99.0" : 2818.4589304483407, + "99.9" : 2818.4589304483407, + "99.99" : 2818.4589304483407, + "99.999" : 2818.4589304483407, + "99.9999" : 2818.4589304483407, + "100.0" : 2818.4589304483407 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2817.8268883973096, + 2818.4589304483407, + 2816.573019217914 + ], + [ + 2732.5740015828583, + 2733.035023734444, + 2734.3608289915505 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 78712.12026119139, + "scoreError" : 2166.9017193334544, + "scoreConfidence" : [ + 76545.21854185793, + 80879.02198052485 + ], + "scorePercentiles" : { + "0.0" : 77970.53839937503, + "50.0" : 78695.14190743159, + "90.0" : 79453.02445192987, + "95.0" : 79453.02445192987, + "99.0" : 79453.02445192987, + "99.9" : 79453.02445192987, + "99.99" : 79453.02445192987, + "99.999" : 79453.02445192987, + "99.9999" : 79453.02445192987, + "100.0" : 79453.02445192987 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 79453.02445192987, + 79351.75820389396, + 79444.72459356039 + ], + [ + 78038.52561096923, + 78014.1503074198, + 77970.53839937503 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 370.0351310847652, + "scoreError" : 24.621071382820464, + "scoreConfidence" : [ + 345.4140597019448, + 394.6562024675857 + ], + "scorePercentiles" : { + "0.0" : 361.4209203797791, + "50.0" : 370.248628088863, + "90.0" : 378.38919963707474, + "95.0" : 378.38919963707474, + "99.0" : 378.38919963707474, + "99.9" : 378.38919963707474, + "99.99" : 378.38919963707474, + "99.999" : 378.38919963707474, + "99.9999" : 378.38919963707474, + "100.0" : 378.38919963707474 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 377.9361827544014, + 378.38919963707474, + 377.7934220577596 + ], + [ + 361.4209203797791, + 362.70383411996636, + 361.9672275596102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.5592394540048, + "scoreError" : 4.27230160588356, + "scoreConfidence" : [ + 111.28693784812124, + 119.83154105988835 + ], + "scorePercentiles" : { + "0.0" : 114.03582614497601, + "50.0" : 115.56021853305391, + "90.0" : 117.19593152463364, + "95.0" : 117.19593152463364, + "99.0" : 117.19593152463364, + "99.9" : 117.19593152463364, + "99.99" : 117.19593152463364, + "99.999" : 117.19593152463364, + "99.9999" : 117.19593152463364, + "100.0" : 117.19593152463364 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.03582614497601, + 114.13240841378327, + 114.36643185112165 + ], + [ + 116.75400521498618, + 116.87083357452813, + 117.19593152463364 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06086100024702932, + "scoreError" : 5.67080337678525E-4, + "scoreConfidence" : [ + 0.0602939199093508, + 0.06142808058470784 + ], + "scorePercentiles" : { + "0.0" : 0.060649711221222195, + "50.0" : 0.06083901075325816, + "90.0" : 0.06111157564868796, + "95.0" : 0.06111157564868796, + "99.0" : 0.06111157564868796, + "99.9" : 0.06111157564868796, + "99.99" : 0.06111157564868796, + "99.999" : 0.06111157564868796, + "99.9999" : 0.06111157564868796, + "100.0" : 0.06111157564868796 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06103651316231178, + 0.06111157564868796, + 0.06097335152339201 + ], + [ + 0.060649711221222195, + 0.06070466998312431, + 0.06069017994343768 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.63437866048912E-4, + "scoreError" : 3.741447709760074E-5, + "scoreConfidence" : [ + 3.2602338895131125E-4, + 4.008523431465127E-4 + ], + "scorePercentiles" : { + "0.0" : 3.509441232816086E-4, + "50.0" : 3.6351684768125064E-4, + "90.0" : 3.7596787708704324E-4, + "95.0" : 3.7596787708704324E-4, + "99.0" : 3.7596787708704324E-4, + "99.9" : 3.7596787708704324E-4, + "99.99" : 3.7596787708704324E-4, + "99.999" : 3.7596787708704324E-4, + "99.9999" : 3.7596787708704324E-4, + "100.0" : 3.7596787708704324E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7596787708704324E-4, + 3.7554318184609113E-4, + 3.7533142446469583E-4 + ], + [ + 3.517022708978054E-4, + 3.509441232816086E-4, + 3.5113831871622753E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2482011908604713, + "scoreError" : 0.0698027817316144, + "scoreConfidence" : [ + 2.178398409128857, + 2.3180039725920856 + ], + "scorePercentiles" : { + "0.0" : 2.204469547939167, + "50.0" : 2.239982586869294, + "90.0" : 2.33526553703727, + "95.0" : 2.3396837029239768, + "99.0" : 2.3396837029239768, + "99.9" : 2.3396837029239768, + "99.99" : 2.3396837029239768, + "99.999" : 2.3396837029239768, + "99.9999" : 2.3396837029239768, + "100.0" : 2.3396837029239768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.295502044056907, + 2.2383344630707254, + 2.2552243569334838, + 2.204469547939167, + 2.205688548522276 + ], + [ + 2.2857825499428572, + 2.3396837029239768, + 2.241630710667862, + 2.2079727885209715, + 2.2077231960264903 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01286902189876537, + "scoreError" : 5.142997078774713E-4, + "scoreConfidence" : [ + 0.0123547221908879, + 0.013383321606642842 + ], + "scorePercentiles" : { + "0.0" : 0.012694119618876915, + "50.0" : 0.012871102452407987, + "90.0" : 0.01303810375336379, + "95.0" : 0.01303810375336379, + "99.0" : 0.01303810375336379, + "99.9" : 0.01303810375336379, + "99.99" : 0.01303810375336379, + "99.999" : 0.01303810375336379, + "99.9999" : 0.01303810375336379, + "100.0" : 0.01303810375336379 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.012704144525339732, + 0.012706666443879145, + 0.012694119618876915 + ], + [ + 0.01303810375336379, + 0.013035558590195818, + 0.013035538460936828 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0067856127138273, + "scoreError" : 0.03912546296381674, + "scoreConfidence" : [ + 0.9676601497500106, + 1.045911075677644 + ], + "scorePercentiles" : { + "0.0" : 0.9935647962245405, + "50.0" : 1.006688662409876, + "90.0" : 1.0203711597796143, + "95.0" : 1.0203711597796143, + "99.0" : 1.0203711597796143, + "99.9" : 1.0203711597796143, + "99.99" : 1.0203711597796143, + "99.999" : 1.0203711597796143, + "99.9999" : 1.0203711597796143, + "100.0" : 1.0203711597796143 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0203711597796143, + 1.0189948671285918, + 1.0191719224498115 + ], + [ + 0.9935647962245405, + 0.9943824576911604, + 0.9942284730092454 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010332671474928116, + "scoreError" : 2.3459612949795186E-4, + "scoreConfidence" : [ + 0.010098075345430163, + 0.010567267604426068 + ], + "scorePercentiles" : { + "0.0" : 0.010249317425438147, + "50.0" : 0.010334256453874681, + "90.0" : 0.010412607382787934, + "95.0" : 0.010412607382787934, + "99.0" : 0.010412607382787934, + "99.9" : 0.010412607382787934, + "99.99" : 0.010412607382787934, + "99.999" : 0.010412607382787934, + "99.9999" : 0.010412607382787934, + "100.0" : 0.010412607382787934 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01040893297013956, + 0.010412607382787934, + 0.010405171302404368 + ], + [ + 0.010249317425438147, + 0.010256658163453688, + 0.010263341605344992 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.073316827693848, + "scoreError" : 0.39995355326333876, + "scoreConfidence" : [ + 2.673363274430509, + 3.4732703809571865 + ], + "scorePercentiles" : { + "0.0" : 2.9367759941280096, + "50.0" : 3.0765075490925784, + "90.0" : 3.206340585897436, + "95.0" : 3.206340585897436, + "99.0" : 3.206340585897436, + "99.9" : 3.206340585897436, + "99.99" : 3.206340585897436, + "99.999" : 3.206340585897436, + "99.9999" : 3.206340585897436, + "100.0" : 3.206340585897436 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2033417200512493, + 3.206340585897436, + 3.200579323096609 + ], + [ + 2.9404275679012346, + 2.952435775088548, + 2.9367759941280096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7205308176192737, + "scoreError" : 0.2327933489755726, + "scoreConfidence" : [ + 2.4877374686437013, + 2.953324166594846 + ], + "scorePercentiles" : { + "0.0" : 2.643450166270156, + "50.0" : 2.7068794818624315, + "90.0" : 2.8101845720708063, + "95.0" : 2.8101845720708063, + "99.0" : 2.8101845720708063, + "99.9" : 2.8101845720708063, + "99.99" : 2.8101845720708063, + "99.999" : 2.8101845720708063, + "99.9999" : 2.8101845720708063, + "100.0" : 2.8101845720708063 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8101845720708063, + 2.809873533014892, + 2.764139369817579 + ], + [ + 2.6496195939072846, + 2.643450166270156, + 2.645917670634921 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18525275686516982, + "scoreError" : 0.021670110954073663, + "scoreConfidence" : [ + 0.16358264591109614, + 0.2069228678192435 + ], + "scorePercentiles" : { + "0.0" : 0.17654356247793235, + "50.0" : 0.18583562259744954, + "90.0" : 0.19227783575919552, + "95.0" : 0.19227783575919552, + "99.0" : 0.19227783575919552, + "99.9" : 0.19227783575919552, + "99.99" : 0.19227783575919552, + "99.999" : 0.19227783575919552, + "99.9999" : 0.19227783575919552, + "100.0" : 0.19227783575919552 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1794385710825214, + 0.17877651987056867, + 0.17654356247793235 + ], + [ + 0.19223267411237768, + 0.19227783575919552, + 0.19224737788842325 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3321213532831711, + "scoreError" : 0.0016875546483844095, + "scoreConfidence" : [ + 0.3304337986347867, + 0.3338089079315555 + ], + "scorePercentiles" : { + "0.0" : 0.33113807854304633, + "50.0" : 0.3321662874579563, + "90.0" : 0.3327167295714666, + "95.0" : 0.3327167295714666, + "99.0" : 0.3327167295714666, + "99.9" : 0.3327167295714666, + "99.99" : 0.3327167295714666, + "99.999" : 0.3327167295714666, + "99.9999" : 0.3327167295714666, + "100.0" : 0.3327167295714666 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3327167295714666, + 0.3326719032633645, + 0.3324097969684882 + ], + [ + 0.33186883340523676, + 0.33113807854304633, + 0.3319227779474243 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14940571935339417, + "scoreError" : 0.013580856936990153, + "scoreConfidence" : [ + 0.135824862416404, + 0.16298657629038432 + ], + "scorePercentiles" : { + "0.0" : 0.14525114826864977, + "50.0" : 0.1484493666084486, + "90.0" : 0.15714747330127601, + "95.0" : 0.15714747330127601, + "99.0" : 0.15714747330127601, + "99.9" : 0.15714747330127601, + "99.99" : 0.15714747330127601, + "99.999" : 0.15714747330127601, + "99.9999" : 0.15714747330127601, + "100.0" : 0.15714747330127601 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15714747330127601, + 0.15171395127057574, + 0.15137015590706124 + ], + [ + 0.14542301006296623, + 0.14552857730983598, + 0.14525114826864977 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4201719123847465, + "scoreError" : 0.03899866140933052, + "scoreConfidence" : [ + 0.381173250975416, + 0.459170573794077 + ], + "scorePercentiles" : { + "0.0" : 0.405516782247273, + "50.0" : 0.4201130886133986, + "90.0" : 0.43559025860266576, + "95.0" : 0.43559025860266576, + "99.0" : 0.43559025860266576, + "99.9" : 0.43559025860266576, + "99.99" : 0.43559025860266576, + "99.999" : 0.43559025860266576, + "99.9999" : 0.43559025860266576, + "100.0" : 0.43559025860266576 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.43165049905041436, + 0.43559025860266576, + 0.43097141454059645 + ], + [ + 0.4080477571813285, + 0.4092547626862007, + 0.405516782247273 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15771189534607225, + "scoreError" : 0.02111632289978842, + "scoreConfidence" : [ + 0.13659557244628381, + 0.17882821824586068 + ], + "scorePercentiles" : { + "0.0" : 0.1490085824293718, + "50.0" : 0.15807803330491588, + "90.0" : 0.1656815986778886, + "95.0" : 0.1656815986778886, + "99.0" : 0.1656815986778886, + "99.9" : 0.1656815986778886, + "99.99" : 0.1656815986778886, + "99.999" : 0.1656815986778886, + "99.9999" : 0.1656815986778886, + "100.0" : 0.1656815986778886 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1656815986778886, + 0.16391929975248742, + 0.16386365225797994 + ], + [ + 0.1515058246068539, + 0.15229241435185184, + 0.1490085824293718 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04751420916450067, + "scoreError" : 0.001044118960513014, + "scoreConfidence" : [ + 0.04647009020398766, + 0.048558328125013685 + ], + "scorePercentiles" : { + "0.0" : 0.04717623467500731, + "50.0" : 0.04746949231317757, + "90.0" : 0.048050593193382694, + "95.0" : 0.048050593193382694, + "99.0" : 0.048050593193382694, + "99.9" : 0.048050593193382694, + "99.99" : 0.048050593193382694, + "99.999" : 0.048050593193382694, + "99.9999" : 0.048050593193382694, + "100.0" : 0.048050593193382694 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04722167857733117, + 0.04717623467500731, + 0.04717820644917793 + ], + [ + 0.048050593193382694, + 0.047741236043080976, + 0.04771730604902396 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8654394.440319499, + "scoreError" : 306393.3292801032, + "scoreConfidence" : [ + 8348001.111039395, + 8960787.769599602 + ], + "scorePercentiles" : { + "0.0" : 8545898.676345004, + "50.0" : 8641886.39783615, + "90.0" : 8780518.95258999, + "95.0" : 8780518.95258999, + "99.0" : 8780518.95258999, + "99.9" : 8780518.95258999, + "99.99" : 8780518.95258999, + "99.999" : 8780518.95258999, + "99.9999" : 8780518.95258999, + "100.0" : 8780518.95258999 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8558833.401197605, + 8564523.92208904, + 8545898.676345004 + ], + [ + 8780518.95258999, + 8757342.816112084, + 8719248.87358326 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-15T01:34:13Z-694c3e1502c20a43ceb4f3bab18f7ccc4c5adb34-jdk17.json b/performance-results/2025-10-15T01:34:13Z-694c3e1502c20a43ceb4f3bab18f7ccc4c5adb34-jdk17.json new file mode 100644 index 0000000000..a1ce763dac --- /dev/null +++ b/performance-results/2025-10-15T01:34:13Z-694c3e1502c20a43ceb4f3bab18f7ccc4c5adb34-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.358221378109777, + "scoreError" : 0.03556027767010579, + "scoreConfidence" : [ + 3.3226611004396713, + 3.393781655779883 + ], + "scorePercentiles" : { + "0.0" : 3.352363955801793, + "50.0" : 3.3574639492170393, + "90.0" : 3.365593658203238, + "95.0" : 3.365593658203238, + "99.0" : 3.365593658203238, + "99.9" : 3.365593658203238, + "99.99" : 3.365593658203238, + "99.999" : 3.365593658203238, + "99.9999" : 3.365593658203238, + "100.0" : 3.365593658203238 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3581855678495747, + 3.365593658203238 + ], + [ + 3.352363955801793, + 3.356742330584504 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6973624438426897, + "scoreError" : 0.054081285050156934, + "scoreConfidence" : [ + 1.643281158792533, + 1.7514437288928466 + ], + "scorePercentiles" : { + "0.0" : 1.6899581839729236, + "50.0" : 1.6966327522399578, + "90.0" : 1.7062260869179198, + "95.0" : 1.7062260869179198, + "99.0" : 1.7062260869179198, + "99.9" : 1.7062260869179198, + "99.99" : 1.7062260869179198, + "99.999" : 1.7062260869179198, + "99.9999" : 1.7062260869179198, + "100.0" : 1.7062260869179198 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.7027839844979273, + 1.7062260869179198 + ], + [ + 1.6899581839729236, + 1.6904815199819883 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8489950118774371, + "scoreError" : 0.00938006808692092, + "scoreConfidence" : [ + 0.8396149437905162, + 0.858375079964358 + ], + "scorePercentiles" : { + "0.0" : 0.8469539977270211, + "50.0" : 0.8493279183111813, + "90.0" : 0.8503702131603644, + "95.0" : 0.8503702131603644, + "99.0" : 0.8503702131603644, + "99.9" : 0.8503702131603644, + "99.99" : 0.8503702131603644, + "99.999" : 0.8503702131603644, + "99.9999" : 0.8503702131603644, + "100.0" : 0.8503702131603644 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8494739443921749, + 0.8503702131603644 + ], + [ + 0.8469539977270211, + 0.8491818922301876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.504963085918853, + "scoreError" : 0.2435191520883438, + "scoreConfidence" : [ + 16.26144393383051, + 16.748482238007195 + ], + "scorePercentiles" : { + "0.0" : 16.422834472327686, + "50.0" : 16.49592927303396, + "90.0" : 16.594174350944286, + "95.0" : 16.594174350944286, + "99.0" : 16.594174350944286, + "99.9" : 16.594174350944286, + "99.99" : 16.594174350944286, + "99.999" : 16.594174350944286, + "99.9999" : 16.594174350944286, + "100.0" : 16.594174350944286 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.429134214395418, + 16.422834472327686, + 16.427219275249804 + ], + [ + 16.59369187092342, + 16.594174350944286, + 16.562724331672495 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2633.0439304321035, + "scoreError" : 166.42974993955406, + "scoreConfidence" : [ + 2466.6141804925496, + 2799.4736803716573 + ], + "scorePercentiles" : { + "0.0" : 2524.5076486819216, + "50.0" : 2633.888534151558, + "90.0" : 2687.409096451293, + "95.0" : 2687.409096451293, + "99.0" : 2687.409096451293, + "99.9" : 2687.409096451293, + "99.99" : 2687.409096451293, + "99.999" : 2687.409096451293, + "99.9999" : 2687.409096451293, + "100.0" : 2687.409096451293 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2687.409096451293, + 2686.64157576082, + 2524.5076486819216 + ], + [ + 2633.0804804201266, + 2634.6965878829888, + 2631.9281933954703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74336.85355829727, + "scoreError" : 1503.3170684914035, + "scoreConfidence" : [ + 72833.53648980586, + 75840.17062678868 + ], + "scorePercentiles" : { + "0.0" : 73835.69217539746, + "50.0" : 74328.44175965735, + "90.0" : 74840.78191300874, + "95.0" : 74840.78191300874, + "99.0" : 74840.78191300874, + "99.9" : 74840.78191300874, + "99.99" : 74840.78191300874, + "99.999" : 74840.78191300874, + "99.9999" : 74840.78191300874, + "100.0" : 74840.78191300874 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74835.66896195887, + 74840.78191300874, + 74801.69957454137 + ], + [ + 73852.09478010386, + 73855.18394477334, + 73835.69217539746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.7915988584579, + "scoreError" : 11.280401474195285, + "scoreConfidence" : [ + 350.51119738426263, + 373.0720003326532 + ], + "scorePercentiles" : { + "0.0" : 356.86683707856395, + "50.0" : 362.9560789968623, + "90.0" : 365.3501684291273, + "95.0" : 365.3501684291273, + "99.0" : 365.3501684291273, + "99.9" : 365.3501684291273, + "99.99" : 365.3501684291273, + "99.999" : 365.3501684291273, + "99.9999" : 365.3501684291273, + "100.0" : 365.3501684291273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 365.1582477329226, + 365.3501684291273, + 365.2547864249057 + ], + [ + 356.86683707856395, + 357.36564322442604, + 360.75391026080206 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.42825361127768, + "scoreError" : 1.5582317947083921, + "scoreConfidence" : [ + 112.87002181656929, + 115.98648540598607 + ], + "scorePercentiles" : { + "0.0" : 113.63176119570254, + "50.0" : 114.48032066407046, + "90.0" : 114.96493915400269, + "95.0" : 114.96493915400269, + "99.0" : 114.96493915400269, + "99.9" : 114.96493915400269, + "99.99" : 114.96493915400269, + "99.999" : 114.96493915400269, + "99.9999" : 114.96493915400269, + "100.0" : 114.96493915400269 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.0684143305966, + 113.63176119570254, + 114.14804559695018 + ], + [ + 114.96493915400269, + 114.81259573119073, + 114.94376565922336 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06111189236899517, + "scoreError" : 6.15499020056652E-4, + "scoreConfidence" : [ + 0.06049639334893852, + 0.06172739138905182 + ], + "scorePercentiles" : { + "0.0" : 0.060841817684028646, + "50.0" : 0.06112647607643697, + "90.0" : 0.06137013169231902, + "95.0" : 0.06137013169231902, + "99.0" : 0.06137013169231902, + "99.9" : 0.06137013169231902, + "99.99" : 0.06137013169231902, + "99.999" : 0.06137013169231902, + "99.9999" : 0.06137013169231902, + "100.0" : 0.06137013169231902 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060989115828891355, + 0.060841817684028646, + 0.06092581933384916 + ], + [ + 0.06137013169231902, + 0.06126383632398258, + 0.0612806333509002 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5966936254528043E-4, + "scoreError" : 6.548441749310073E-5, + "scoreConfidence" : [ + 2.941849450521797E-4, + 4.2515378003838116E-4 + ], + "scorePercentiles" : { + "0.0" : 3.3779458774237407E-4, + "50.0" : 3.596138110549902E-4, + "90.0" : 3.8134025046093886E-4, + "95.0" : 3.8134025046093886E-4, + "99.0" : 3.8134025046093886E-4, + "99.9" : 3.8134025046093886E-4, + "99.99" : 3.8134025046093886E-4, + "99.999" : 3.8134025046093886E-4, + "99.9999" : 3.8134025046093886E-4, + "100.0" : 3.8134025046093886E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3779458774237407E-4, + 3.38686722409847E-4, + 3.385831305924719E-4 + ], + [ + 3.805408997001334E-4, + 3.8134025046093886E-4, + 3.810705843659173E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.279722603485268, + "scoreError" : 0.08231757514557823, + "scoreConfidence" : [ + 2.19740502833969, + 2.362040178630846 + ], + "scorePercentiles" : { + "0.0" : 2.1994852940400262, + "50.0" : 2.276119858443332, + "90.0" : 2.3721909760002986, + "95.0" : 2.376684415161597, + "99.0" : 2.376684415161597, + "99.9" : 2.376684415161597, + "99.99" : 2.376684415161597, + "99.999" : 2.376684415161597, + "99.9999" : 2.376684415161597, + "100.0" : 2.376684415161597 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.376684415161597, + 2.3182380088085304, + 2.331750023548613, + 2.276138265361857, + 2.2761014515248066 + ], + [ + 2.2936369637614678, + 2.2616269283129804, + 2.2592393437994125, + 2.204325340533392, + 2.1994852940400262 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013595437860568447, + "scoreError" : 2.505372626019602E-4, + "scoreConfidence" : [ + 0.013344900597966487, + 0.013845975123170406 + ], + "scorePercentiles" : { + "0.0" : 0.013500383802151397, + "50.0" : 0.013597178718720673, + "90.0" : 0.013680058485636115, + "95.0" : 0.013680058485636115, + "99.0" : 0.013680058485636115, + "99.9" : 0.013680058485636115, + "99.99" : 0.013680058485636115, + "99.999" : 0.013680058485636115, + "99.9999" : 0.013680058485636115, + "100.0" : 0.013680058485636115 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013679038309863008, + 0.013680058485636115, + 0.013670818735603114 + ], + [ + 0.013523538701838232, + 0.013500383802151397, + 0.013518789128318824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9724685663875733, + "scoreError" : 0.026288190702128143, + "scoreConfidence" : [ + 0.9461803756854451, + 0.9987567570897015 + ], + "scorePercentiles" : { + "0.0" : 0.9637943655551272, + "50.0" : 0.972447114273572, + "90.0" : 0.9813374969090374, + "95.0" : 0.9813374969090374, + "99.0" : 0.9813374969090374, + "99.9" : 0.9813374969090374, + "99.99" : 0.9813374969090374, + "99.999" : 0.9813374969090374, + "99.9999" : 0.9813374969090374, + "100.0" : 0.9813374969090374 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9641053437771137, + 0.9638388449306091, + 0.9637943655551272 + ], + [ + 0.9807888847700305, + 0.9809464623835213, + 0.9813374969090374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010798700917294029, + "scoreError" : 1.4446472235733353E-4, + "scoreConfidence" : [ + 0.010654236194936694, + 0.010943165639651363 + ], + "scorePercentiles" : { + "0.0" : 0.010747721983629532, + "50.0" : 0.010797712979320032, + "90.0" : 0.01085198286302137, + "95.0" : 0.01085198286302137, + "99.0" : 0.01085198286302137, + "99.9" : 0.01085198286302137, + "99.99" : 0.01085198286302137, + "99.999" : 0.01085198286302137, + "99.9999" : 0.01085198286302137, + "100.0" : 0.01085198286302137 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010847717730825721, + 0.01085198286302137, + 0.010836397777291356 + ], + [ + 0.01075902818134871, + 0.010749356967647483, + 0.010747721983629532 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0756931284734144, + "scoreError" : 0.1955599016342595, + "scoreConfidence" : [ + 2.880133226839155, + 3.271253030107674 + ], + "scorePercentiles" : { + "0.0" : 3.0075154203247143, + "50.0" : 3.076403861044579, + "90.0" : 3.1423286582914574, + "95.0" : 3.1423286582914574, + "99.0" : 3.1423286582914574, + "99.9" : 3.1423286582914574, + "99.99" : 3.1423286582914574, + "99.999" : 3.1423286582914574, + "99.9999" : 3.1423286582914574, + "100.0" : 3.1423286582914574 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1423286582914574, + 3.138963812303829, + 3.1365566702194356 + ], + [ + 3.0125431578313253, + 3.0162510518697228, + 3.0075154203247143 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.793517804191912, + "scoreError" : 0.0252457145878594, + "scoreConfidence" : [ + 2.7682720896040527, + 2.8187635187797717 + ], + "scorePercentiles" : { + "0.0" : 2.781598669076752, + "50.0" : 2.7951065683199214, + "90.0" : 2.8046232027481772, + "95.0" : 2.8046232027481772, + "99.0" : 2.8046232027481772, + "99.9" : 2.8046232027481772, + "99.99" : 2.8046232027481772, + "99.999" : 2.8046232027481772, + "99.9999" : 2.8046232027481772, + "100.0" : 2.8046232027481772 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7979029205594403, + 2.7999641769316908, + 2.8046232027481772 + ], + [ + 2.7847076397550112, + 2.781598669076752, + 2.792310216080402 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18214136772790535, + "scoreError" : 0.015763273166526606, + "scoreConfidence" : [ + 0.16637809456137875, + 0.19790464089443194 + ], + "scorePercentiles" : { + "0.0" : 0.17688305769775012, + "50.0" : 0.18205309582834023, + "90.0" : 0.18750261356733042, + "95.0" : 0.18750261356733042, + "99.0" : 0.18750261356733042, + "99.9" : 0.18750261356733042, + "99.99" : 0.18750261356733042, + "99.999" : 0.18750261356733042, + "99.9999" : 0.18750261356733042, + "100.0" : 0.18750261356733042 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18729668549595446, + 0.18750261356733042, + 0.1870123094027004 + ], + [ + 0.1770596579497167, + 0.17709388225398007, + 0.17688305769775012 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32598592453579894, + "scoreError" : 0.012955941767848025, + "scoreConfidence" : [ + 0.3130299827679509, + 0.338941866303647 + ], + "scorePercentiles" : { + "0.0" : 0.3216175759953689, + "50.0" : 0.32599137295499364, + "90.0" : 0.3305366355643695, + "95.0" : 0.3305366355643695, + "99.0" : 0.3305366355643695, + "99.9" : 0.3305366355643695, + "99.99" : 0.3305366355643695, + "99.999" : 0.3305366355643695, + "99.9999" : 0.3305366355643695, + "100.0" : 0.3305366355643695 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3217237529517743, + 0.3216175759953689, + 0.3219777575259989 + ], + [ + 0.3300548367932935, + 0.3305366355643695, + 0.3300049883839884 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1436416729157658, + "scoreError" : 0.003394448999497843, + "scoreConfidence" : [ + 0.14024722391626795, + 0.14703612191526363 + ], + "scorePercentiles" : { + "0.0" : 0.14248856941950927, + "50.0" : 0.1435855957504847, + "90.0" : 0.14496747445710476, + "95.0" : 0.14496747445710476, + "99.0" : 0.14496747445710476, + "99.9" : 0.14496747445710476, + "99.99" : 0.14496747445710476, + "99.999" : 0.14496747445710476, + "99.9999" : 0.14496747445710476, + "100.0" : 0.14496747445710476 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14496747445710476, + 0.14457887724092067, + 0.14467388244144497 + ], + [ + 0.14248856941950927, + 0.14259231426004876, + 0.14254891967556627 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4043522695263309, + "scoreError" : 0.01780191722570313, + "scoreConfidence" : [ + 0.3865503523006278, + 0.42215418675203403 + ], + "scorePercentiles" : { + "0.0" : 0.39850757021598787, + "50.0" : 0.4043293976140303, + "90.0" : 0.41031339393566385, + "95.0" : 0.41031339393566385, + "99.0" : 0.41031339393566385, + "99.9" : 0.41031339393566385, + "99.99" : 0.41031339393566385, + "99.999" : 0.41031339393566385, + "99.9999" : 0.41031339393566385, + "100.0" : 0.41031339393566385 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41006639135605033, + 0.41031339393566385, + 0.41006067589289374 + ], + [ + 0.3985674664222231, + 0.3985981193351668, + 0.39850757021598787 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15629282295921976, + "scoreError" : 0.004555034924374707, + "scoreConfidence" : [ + 0.15173778803484506, + 0.16084785788359446 + ], + "scorePercentiles" : { + "0.0" : 0.15461642729254604, + "50.0" : 0.15626424522104793, + "90.0" : 0.15806076509451855, + "95.0" : 0.15806076509451855, + "99.0" : 0.15806076509451855, + "99.9" : 0.15806076509451855, + "99.99" : 0.15806076509451855, + "99.999" : 0.15806076509451855, + "99.9999" : 0.15806076509451855, + "100.0" : 0.15806076509451855 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15806076509451855, + 0.15769848702947345, + 0.15753027709078307 + ], + [ + 0.15485276789668467, + 0.1549982133513128, + 0.15461642729254604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04669476371138736, + "scoreError" : 9.920732913827628E-4, + "scoreConfidence" : [ + 0.0457026904200046, + 0.04768683700277012 + ], + "scorePercentiles" : { + "0.0" : 0.04636662831283963, + "50.0" : 0.046678445080916946, + "90.0" : 0.04704397731111017, + "95.0" : 0.04704397731111017, + "99.0" : 0.04704397731111017, + "99.9" : 0.04704397731111017, + "99.99" : 0.04704397731111017, + "99.999" : 0.04704397731111017, + "99.9999" : 0.04704397731111017, + "100.0" : 0.04704397731111017 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046975508295753476, + 0.047031523745479684, + 0.04704397731111017 + ], + [ + 0.04636662831283963, + 0.046381381866080415, + 0.04636956273706077 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8529837.973993618, + "scoreError" : 370206.5431251566, + "scoreConfidence" : [ + 8159631.430868462, + 8900044.517118774 + ], + "scorePercentiles" : { + "0.0" : 8400766.229219144, + "50.0" : 8529683.942852532, + "90.0" : 8661036.68138528, + "95.0" : 8661036.68138528, + "99.0" : 8661036.68138528, + "99.9" : 8661036.68138528, + "99.99" : 8661036.68138528, + "99.999" : 8661036.68138528, + "99.9999" : 8661036.68138528, + "100.0" : 8661036.68138528 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8418873.178451179, + 8409109.905042017, + 8400766.229219144 + ], + [ + 8661036.68138528, + 8640494.707253886, + 8648747.142610198 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-15T01:47:22Z-43082799e033a83fd934df232d6ecb10b23663be-jdk17.json b/performance-results/2025-10-15T01:47:22Z-43082799e033a83fd934df232d6ecb10b23663be-jdk17.json new file mode 100644 index 0000000000..76ba21e84c --- /dev/null +++ b/performance-results/2025-10-15T01:47:22Z-43082799e033a83fd934df232d6ecb10b23663be-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3142526921538993, + "scoreError" : 0.06089829779633682, + "scoreConfidence" : [ + 3.2533543943575625, + 3.375150989950236 + ], + "scorePercentiles" : { + "0.0" : 3.3044063370493943, + "50.0" : 3.3149269996983977, + "90.0" : 3.322750432169406, + "95.0" : 3.322750432169406, + "99.0" : 3.322750432169406, + "99.9" : 3.322750432169406, + "99.99" : 3.322750432169406, + "99.999" : 3.322750432169406, + "99.9999" : 3.322750432169406, + "100.0" : 3.322750432169406 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3044063370493943, + 3.322750432169406 + ], + [ + 3.307985525822935, + 3.321868473573861 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6715608554193984, + "scoreError" : 0.02377100068069686, + "scoreConfidence" : [ + 1.6477898547387015, + 1.6953318561000952 + ], + "scorePercentiles" : { + "0.0" : 1.6681850081012481, + "50.0" : 1.6709519922678886, + "90.0" : 1.6761544290405685, + "95.0" : 1.6761544290405685, + "99.0" : 1.6761544290405685, + "99.9" : 1.6761544290405685, + "99.99" : 1.6761544290405685, + "99.999" : 1.6761544290405685, + "99.9999" : 1.6761544290405685, + "100.0" : 1.6761544290405685 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6681850081012481, + 1.6761544290405685 + ], + [ + 1.6690340048634709, + 1.6728699796723063 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8395464495543093, + "scoreError" : 0.020423111370492658, + "scoreConfidence" : [ + 0.8191233381838167, + 0.859969560924802 + ], + "scorePercentiles" : { + "0.0" : 0.8357130188031962, + "50.0" : 0.839867970697676, + "90.0" : 0.8427368380186893, + "95.0" : 0.8427368380186893, + "99.0" : 0.8427368380186893, + "99.9" : 0.8427368380186893, + "99.99" : 0.8427368380186893, + "99.999" : 0.8427368380186893, + "99.9999" : 0.8427368380186893, + "100.0" : 0.8427368380186893 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8414309393402474, + 0.8427368380186893 + ], + [ + 0.8357130188031962, + 0.8383050020551047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.669547543282995, + "scoreError" : 0.24906100992643931, + "scoreConfidence" : [ + 15.420486533356556, + 15.918608553209435 + ], + "scorePercentiles" : { + "0.0" : 15.515562138674634, + "50.0" : 15.717038714742444, + "90.0" : 15.733179298107443, + "95.0" : 15.733179298107443, + "99.0" : 15.733179298107443, + "99.9" : 15.733179298107443, + "99.99" : 15.733179298107443, + "99.999" : 15.733179298107443, + "99.9999" : 15.733179298107443, + "100.0" : 15.733179298107443 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.733179298107443, + 15.70981037707785, + 15.726631230299612 + ], + [ + 15.724267052407034, + 15.607835163131385, + 15.515562138674634 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2512.666505233547, + "scoreError" : 25.015632516507264, + "scoreConfidence" : [ + 2487.65087271704, + 2537.682137750054 + ], + "scorePercentiles" : { + "0.0" : 2499.291346933815, + "50.0" : 2513.2521998211905, + "90.0" : 2522.1021158264707, + "95.0" : 2522.1021158264707, + "99.0" : 2522.1021158264707, + "99.9" : 2522.1021158264707, + "99.99" : 2522.1021158264707, + "99.999" : 2522.1021158264707, + "99.9999" : 2522.1021158264707, + "100.0" : 2522.1021158264707 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2499.291346933815, + 2521.9689457438426, + 2513.426592122762 + ], + [ + 2513.0778075196185, + 2522.1021158264707, + 2506.1322232547764 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72944.8532766683, + "scoreError" : 1811.6686089513873, + "scoreConfidence" : [ + 71133.18466771692, + 74756.52188561969 + ], + "scorePercentiles" : { + "0.0" : 72299.45755949058, + "50.0" : 72841.03893429958, + "90.0" : 73654.86103189577, + "95.0" : 73654.86103189577, + "99.0" : 73654.86103189577, + "99.9" : 73654.86103189577, + "99.99" : 73654.86103189577, + "99.999" : 73654.86103189577, + "99.9999" : 73654.86103189577, + "100.0" : 73654.86103189577 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73263.26246032969, + 73654.86103189577, + 73640.05383674607 + ], + [ + 72418.81540826947, + 72299.45755949058, + 72392.66936327827 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 331.00109484005526, + "scoreError" : 19.062948544695836, + "scoreConfidence" : [ + 311.93814629535945, + 350.0640433847511 + ], + "scorePercentiles" : { + "0.0" : 323.08835566949983, + "50.0" : 331.8093838082406, + "90.0" : 337.37771917057273, + "95.0" : 337.37771917057273, + "99.0" : 337.37771917057273, + "99.9" : 337.37771917057273, + "99.99" : 337.37771917057273, + "99.999" : 337.37771917057273, + "99.9999" : 337.37771917057273, + "100.0" : 337.37771917057273 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 336.85793607792084, + 337.37771917057273, + 337.1052792484525 + ], + [ + 323.08835566949983, + 324.81644733532534, + 326.7608315385604 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 106.16831810718206, + "scoreError" : 5.143175953499081, + "scoreConfidence" : [ + 101.02514215368298, + 111.31149406068114 + ], + "scorePercentiles" : { + "0.0" : 103.36200395163198, + "50.0" : 105.85721405981319, + "90.0" : 108.44710519555863, + "95.0" : 108.44710519555863, + "99.0" : 108.44710519555863, + "99.9" : 108.44710519555863, + "99.99" : 108.44710519555863, + "99.999" : 108.44710519555863, + "99.9999" : 108.44710519555863, + "100.0" : 108.44710519555863 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 105.5446620365646, + 107.94170933971071, + 108.44710519555863 + ], + [ + 103.36200395163198, + 105.7476211940178, + 105.96680692560858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.0638832518832319, + "scoreError" : 0.0015083149234792243, + "scoreConfidence" : [ + 0.06237493695975268, + 0.06539156680671113 + ], + "scorePercentiles" : { + "0.0" : 0.06331936095914698, + "50.0" : 0.06390183831461523, + "90.0" : 0.06445239146155185, + "95.0" : 0.06445239146155185, + "99.0" : 0.06445239146155185, + "99.9" : 0.06445239146155185, + "99.99" : 0.06445239146155185, + "99.999" : 0.06445239146155185, + "99.9999" : 0.06445239146155185, + "100.0" : 0.06445239146155185 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06445239146155185, + 0.06434315949041307, + 0.06431423326408942 + ], + [ + 0.06331936095914698, + 0.06338092275904905, + 0.06348944336514104 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 4.0545589351634694E-4, + "scoreError" : 2.718698443078817E-5, + "scoreConfidence" : [ + 3.7826890908555875E-4, + 4.3264287794713514E-4 + ], + "scorePercentiles" : { + "0.0" : 3.916359272963846E-4, + "50.0" : 4.075803961889824E-4, + "90.0" : 4.182437980081773E-4, + "95.0" : 4.182437980081773E-4, + "99.0" : 4.182437980081773E-4, + "99.9" : 4.182437980081773E-4, + "99.99" : 4.182437980081773E-4, + "99.999" : 4.182437980081773E-4, + "99.9999" : 4.182437980081773E-4, + "100.0" : 4.182437980081773E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 4.182437980081773E-4, + 4.1038214859463376E-4, + 4.103879019528591E-4 + ], + [ + 3.916359272963846E-4, + 3.97306941462696E-4, + 4.0477864378333096E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.464310853264765, + "scoreError" : 0.09869931029222491, + "scoreConfidence" : [ + 2.3656115429725397, + 2.56301016355699 + ], + "scorePercentiles" : { + "0.0" : 2.40623983493744, + "50.0" : 2.435599433525828, + "90.0" : 2.584501354900003, + "95.0" : 2.590334935767936, + "99.0" : 2.590334935767936, + "99.9" : 2.590334935767936, + "99.99" : 2.590334935767936, + "99.999" : 2.590334935767936, + "99.9999" : 2.590334935767936, + "100.0" : 2.590334935767936 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.5319991270886075, + 2.590334935767936, + 2.52758611119535, + 2.455099180412371, + 2.409812433493976 + ], + [ + 2.477070732045567, + 2.4143643008208593, + 2.414502190246258, + 2.40623983493744, + 2.416099686639285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013753834887277947, + "scoreError" : 3.2914042127123815E-5, + "scoreConfidence" : [ + 0.013720920845150824, + 0.01378674892940507 + ], + "scorePercentiles" : { + "0.0" : 0.013737788410049715, + "50.0" : 0.013757794897653374, + "90.0" : 0.01376681748888739, + "95.0" : 0.01376681748888739, + "99.0" : 0.01376681748888739, + "99.9" : 0.01376681748888739, + "99.99" : 0.01376681748888739, + "99.999" : 0.01376681748888739, + "99.9999" : 0.01376681748888739, + "100.0" : 0.01376681748888739 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013737788410049715, + 0.01376173273681574, + 0.01374108089260809 + ], + [ + 0.01375600615296155, + 0.01376681748888739, + 0.013759583642345197 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.980615931371409, + "scoreError" : 0.05635167829220699, + "scoreConfidence" : [ + 0.924264253079202, + 1.036967609663616 + ], + "scorePercentiles" : { + "0.0" : 0.960495810026892, + "50.0" : 0.9808512407419551, + "90.0" : 1.000003198980102, + "95.0" : 1.000003198980102, + "99.0" : 1.000003198980102, + "99.9" : 1.000003198980102, + "99.99" : 1.000003198980102, + "99.999" : 1.000003198980102, + "99.9999" : 1.000003198980102, + "100.0" : 1.000003198980102 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9974313996210232, + 0.9993013209432454, + 1.000003198980102 + ], + [ + 0.9642710818628869, + 0.9621927767943044, + 0.960495810026892 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010895342707204459, + "scoreError" : 4.2671867550227876E-4, + "scoreConfidence" : [ + 0.01046862403170218, + 0.011322061382706737 + ], + "scorePercentiles" : { + "0.0" : 0.010739087832526492, + "50.0" : 0.010890161033889775, + "90.0" : 0.011054926513305951, + "95.0" : 0.011054926513305951, + "99.0" : 0.011054926513305951, + "99.9" : 0.011054926513305951, + "99.99" : 0.011054926513305951, + "99.999" : 0.011054926513305951, + "99.9999" : 0.011054926513305951, + "100.0" : 0.011054926513305951 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010755495660347732, + 0.010778999133396567, + 0.010739087832526492 + ], + [ + 0.011054926513305951, + 0.01104222416926702, + 0.011001322934382983 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.213659811043943, + "scoreError" : 0.033884292444003365, + "scoreConfidence" : [ + 3.1797755185999397, + 3.247544103487946 + ], + "scorePercentiles" : { + "0.0" : 3.2001368138195776, + "50.0" : 3.2120205353468085, + "90.0" : 3.2352481688227686, + "95.0" : 3.2352481688227686, + "99.0" : 3.2352481688227686, + "99.9" : 3.2352481688227686, + "99.99" : 3.2352481688227686, + "99.999" : 3.2352481688227686, + "99.9999" : 3.2352481688227686, + "100.0" : 3.2352481688227686 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.212857140655106, + 3.2056587794871794, + 3.2352481688227686 + ], + [ + 3.2001368138195776, + 3.2168740334405146, + 3.2111839300385108 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.0323427456681245, + "scoreError" : 0.2474704712524874, + "scoreConfidence" : [ + 2.784872274415637, + 3.279813216920612 + ], + "scorePercentiles" : { + "0.0" : 2.9530944216120463, + "50.0" : 3.0071262848659694, + "90.0" : 3.1798429888712243, + "95.0" : 3.1798429888712243, + "99.0" : 3.1798429888712243, + "99.9" : 3.1798429888712243, + "99.99" : 3.1798429888712243, + "99.999" : 3.1798429888712243, + "99.9999" : 3.1798429888712243, + "100.0" : 3.1798429888712243 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9738734463276835, + 2.963175444148148, + 2.9530944216120463 + ], + [ + 3.08369104964539, + 3.0403791234042554, + 3.1798429888712243 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18786496693374835, + "scoreError" : 0.025440384158599987, + "scoreConfidence" : [ + 0.16242458277514837, + 0.21330535109234833 + ], + "scorePercentiles" : { + "0.0" : 0.17927279565092683, + "50.0" : 0.18785803165767817, + "90.0" : 0.19647382449556966, + "95.0" : 0.19647382449556966, + "99.0" : 0.19647382449556966, + "99.9" : 0.19647382449556966, + "99.99" : 0.19647382449556966, + "99.999" : 0.19647382449556966, + "99.9999" : 0.19647382449556966, + "100.0" : 0.19647382449556966 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1960343993883912, + 0.19592241857685827, + 0.19647382449556966 + ], + [ + 0.17927279565092683, + 0.1796927187522461, + 0.17979364473849804 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3323462838816404, + "scoreError" : 0.009844476134683743, + "scoreConfidence" : [ + 0.32250180774695664, + 0.34219076001632415 + ], + "scorePercentiles" : { + "0.0" : 0.32910888504574476, + "50.0" : 0.33211196740762006, + "90.0" : 0.33579531805513585, + "95.0" : 0.33579531805513585, + "99.0" : 0.33579531805513585, + "99.9" : 0.33579531805513585, + "99.99" : 0.33579531805513585, + "99.999" : 0.33579531805513585, + "99.9999" : 0.33579531805513585, + "100.0" : 0.33579531805513585 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33503991855400694, + 0.33578820804512793, + 0.33579531805513585 + ], + [ + 0.32916135732859353, + 0.32910888504574476, + 0.3291840162612331 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14638320760906973, + "scoreError" : 0.005594611453734423, + "scoreConfidence" : [ + 0.14078859615533532, + 0.15197781906280414 + ], + "scorePercentiles" : { + "0.0" : 0.14441117103743067, + "50.0" : 0.14648890698556594, + "90.0" : 0.14827017913590132, + "95.0" : 0.14827017913590132, + "99.0" : 0.14827017913590132, + "99.9" : 0.14827017913590132, + "99.99" : 0.14827017913590132, + "99.999" : 0.14827017913590132, + "99.9999" : 0.14827017913590132, + "100.0" : 0.14827017913590132 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1482157981414788, + 0.14827017913590132, + 0.14810666167061612 + ], + [ + 0.14487115230051573, + 0.14441117103743067, + 0.1444242833684758 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4165657287602406, + "scoreError" : 0.027093493067786408, + "scoreConfidence" : [ + 0.3894722356924542, + 0.44365922182802703 + ], + "scorePercentiles" : { + "0.0" : 0.4066838060187068, + "50.0" : 0.41671200873547287, + "90.0" : 0.4265218668429583, + "95.0" : 0.4265218668429583, + "99.0" : 0.4265218668429583, + "99.9" : 0.4265218668429583, + "99.99" : 0.4265218668429583, + "99.999" : 0.4265218668429583, + "99.9999" : 0.4265218668429583, + "100.0" : 0.4265218668429583 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4248157147408666, + 0.4265218668429583, + 0.4247001635452499 + ], + [ + 0.40794896748796605, + 0.4087238539256958, + 0.4066838060187068 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1570340854191275, + "scoreError" : 0.004974292264305018, + "scoreConfidence" : [ + 0.1520597931548225, + 0.16200837768343251 + ], + "scorePercentiles" : { + "0.0" : 0.15529285502003043, + "50.0" : 0.15695298936580857, + "90.0" : 0.15907769488101298, + "95.0" : 0.15907769488101298, + "99.0" : 0.15907769488101298, + "99.9" : 0.15907769488101298, + "99.99" : 0.15907769488101298, + "99.999" : 0.15907769488101298, + "99.9999" : 0.15907769488101298, + "100.0" : 0.15907769488101298 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.155485281080913, + 0.15551617223146666, + 0.15529285502003043 + ], + [ + 0.15907769488101298, + 0.15844270280119147, + 0.15838980650015047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047018274151710136, + "scoreError" : 0.004572800130771919, + "scoreConfidence" : [ + 0.04244547402093822, + 0.05159107428248205 + ], + "scorePercentiles" : { + "0.0" : 0.04536798490629381, + "50.0" : 0.047103290396752054, + "90.0" : 0.04865234943856303, + "95.0" : 0.04865234943856303, + "99.0" : 0.04865234943856303, + "99.9" : 0.04865234943856303, + "99.99" : 0.04865234943856303, + "99.999" : 0.04865234943856303, + "99.9999" : 0.04865234943856303, + "100.0" : 0.04865234943856303 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04579326818881196, + 0.04536798490629381, + 0.04545077297621591 + ], + [ + 0.048413312604692144, + 0.04843195679568393, + 0.04865234943856303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 9669315.227578903, + "scoreError" : 270281.63628860674, + "scoreConfidence" : [ + 9399033.591290295, + 9939596.86386751 + ], + "scorePercentiles" : { + "0.0" : 9551889.490926456, + "50.0" : 9673984.17402568, + "90.0" : 9824911.040275048, + "95.0" : 9824911.040275048, + "99.0" : 9824911.040275048, + "99.9" : 9824911.040275048, + "99.99" : 9824911.040275048, + "99.999" : 9824911.040275048, + "99.9999" : 9824911.040275048, + "100.0" : 9824911.040275048 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9649584.56219865, + 9590385.475551294, + 9700737.010669254 + ], + [ + 9551889.490926456, + 9824911.040275048, + 9698383.785852714 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-16T00:14:35Z-fd372aeeccec4294c234219cf689d83b5f92501e-jdk17.json b/performance-results/2025-10-16T00:14:35Z-fd372aeeccec4294c234219cf689d83b5f92501e-jdk17.json new file mode 100644 index 0000000000..1b19cadfbc --- /dev/null +++ b/performance-results/2025-10-16T00:14:35Z-fd372aeeccec4294c234219cf689d83b5f92501e-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.344804978486017, + "scoreError" : 0.03372501614875968, + "scoreConfidence" : [ + 3.3110799623372573, + 3.3785299946347767 + ], + "scorePercentiles" : { + "0.0" : 3.3402421444586814, + "50.0" : 3.3447780369362374, + "90.0" : 3.349421695612912, + "95.0" : 3.349421695612912, + "99.0" : 3.349421695612912, + "99.9" : 3.349421695612912, + "99.99" : 3.349421695612912, + "99.999" : 3.349421695612912, + "99.9999" : 3.349421695612912, + "100.0" : 3.349421695612912 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.340329532370066, + 3.349421695612912 + ], + [ + 3.3402421444586814, + 3.349226541502409 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6914242428696418, + "scoreError" : 0.01648012479282642, + "scoreConfidence" : [ + 1.6749441180768154, + 1.7079043676624681 + ], + "scorePercentiles" : { + "0.0" : 1.6893068570324623, + "50.0" : 1.690676486590314, + "90.0" : 1.6950371412654766, + "95.0" : 1.6950371412654766, + "99.0" : 1.6950371412654766, + "99.9" : 1.6950371412654766, + "99.99" : 1.6950371412654766, + "99.999" : 1.6950371412654766, + "99.9999" : 1.6950371412654766, + "100.0" : 1.6950371412654766 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6900216116514066, + 1.6950371412654766 + ], + [ + 1.6913313615292218, + 1.6893068570324623 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8553555551773281, + "scoreError" : 0.022776176908929243, + "scoreConfidence" : [ + 0.8325793782683989, + 0.8781317320862573 + ], + "scorePercentiles" : { + "0.0" : 0.8513992368057242, + "50.0" : 0.8557170499741311, + "90.0" : 0.8585888839553258, + "95.0" : 0.8585888839553258, + "99.0" : 0.8585888839553258, + "99.9" : 0.8585888839553258, + "99.99" : 0.8585888839553258, + "99.999" : 0.8585888839553258, + "99.9999" : 0.8585888839553258, + "100.0" : 0.8585888839553258 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8513992368057242, + 0.8585888839553258 + ], + [ + 0.8533824188988806, + 0.8580516810493816 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.519551896237306, + "scoreError" : 0.4029247206974454, + "scoreConfidence" : [ + 16.11662717553986, + 16.922476616934752 + ], + "scorePercentiles" : { + "0.0" : 16.38455625351044, + "50.0" : 16.51516518404042, + "90.0" : 16.66493061806253, + "95.0" : 16.66493061806253, + "99.0" : 16.66493061806253, + "99.9" : 16.66493061806253, + "99.99" : 16.66493061806253, + "99.999" : 16.66493061806253, + "99.9999" : 16.66493061806253, + "100.0" : 16.66493061806253 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.38455625351044, + 16.393312325187626, + 16.388104964946315 + ], + [ + 16.637018042893214, + 16.649389172823717, + 16.66493061806253 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2809.518893438351, + "scoreError" : 195.6415793306292, + "scoreConfidence" : [ + 2613.8773141077218, + 3005.16047276898 + ], + "scorePercentiles" : { + "0.0" : 2745.2180171931586, + "50.0" : 2808.9306875725015, + "90.0" : 2874.4506560017962, + "95.0" : 2874.4506560017962, + "99.0" : 2874.4506560017962, + "99.9" : 2874.4506560017962, + "99.99" : 2874.4506560017962, + "99.999" : 2874.4506560017962, + "99.9999" : 2874.4506560017962, + "100.0" : 2874.4506560017962 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2746.338280691674, + 2745.2180171931586, + 2745.954190218494 + ], + [ + 2871.5230944533287, + 2874.4506560017962, + 2873.629122071654 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73853.73486527042, + "scoreError" : 1634.5047185256708, + "scoreConfidence" : [ + 72219.23014674475, + 75488.2395837961 + ], + "scorePercentiles" : { + "0.0" : 73315.98387712146, + "50.0" : 73839.14186242627, + "90.0" : 74402.75239762344, + "95.0" : 74402.75239762344, + "99.0" : 74402.75239762344, + "99.9" : 74402.75239762344, + "99.99" : 74402.75239762344, + "99.999" : 74402.75239762344, + "99.9999" : 74402.75239762344, + "100.0" : 74402.75239762344 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73315.98387712146, + 73323.64615468426, + 73326.10339773809 + ], + [ + 74401.74303734089, + 74352.18032711446, + 74402.75239762344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 369.26725142293543, + "scoreError" : 11.908843027218001, + "scoreConfidence" : [ + 357.35840839571745, + 381.1760944501534 + ], + "scorePercentiles" : { + "0.0" : 364.4323781873843, + "50.0" : 369.6336047812931, + "90.0" : 373.35143257889297, + "95.0" : 373.35143257889297, + "99.0" : 373.35143257889297, + "99.9" : 373.35143257889297, + "99.99" : 373.35143257889297, + "99.999" : 373.35143257889297, + "99.9999" : 373.35143257889297, + "100.0" : 373.35143257889297 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.28998310446104, + 365.5686735429993, + 364.4323781873843 + ], + [ + 372.9838146657496, + 373.35143257889297, + 372.97722645812513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.36974167547804, + "scoreError" : 3.988736019630814, + "scoreConfidence" : [ + 110.38100565584722, + 118.35847769510886 + ], + "scorePercentiles" : { + "0.0" : 112.81993133370868, + "50.0" : 114.35996027143432, + "90.0" : 115.82432564404856, + "95.0" : 115.82432564404856, + "99.0" : 115.82432564404856, + "99.9" : 115.82432564404856, + "99.99" : 115.82432564404856, + "99.999" : 115.82432564404856, + "99.9999" : 115.82432564404856, + "100.0" : 115.82432564404856 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.66071959556275, + 115.82432564404856, + 115.4887772163897 + ], + [ + 112.81993133370868, + 113.19355293667958, + 113.23114332647894 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060717858666894636, + "scoreError" : 6.059387690707904E-4, + "scoreConfidence" : [ + 0.06011191989782384, + 0.06132379743596543 + ], + "scorePercentiles" : { + "0.0" : 0.06050704320124884, + "50.0" : 0.06070412478012961, + "90.0" : 0.0609398462086911, + "95.0" : 0.0609398462086911, + "99.0" : 0.0609398462086911, + "99.9" : 0.0609398462086911, + "99.99" : 0.0609398462086911, + "99.999" : 0.0609398462086911, + "99.9999" : 0.0609398462086911, + "100.0" : 0.0609398462086911 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06053004971854004, + 0.06052773307064691, + 0.06050704320124884 + ], + [ + 0.060878199841719174, + 0.0609398462086911, + 0.06092427996052174 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5929797998013124E-4, + "scoreError" : 4.8201780241922105E-5, + "scoreConfidence" : [ + 3.110961997382091E-4, + 4.0749976022205335E-4 + ], + "scorePercentiles" : { + "0.0" : 3.433042501300425E-4, + "50.0" : 3.582602790223153E-4, + "90.0" : 3.8034456002248874E-4, + "95.0" : 3.8034456002248874E-4, + "99.0" : 3.8034456002248874E-4, + "99.9" : 3.8034456002248874E-4, + "99.99" : 3.8034456002248874E-4, + "99.999" : 3.8034456002248874E-4, + "99.9999" : 3.8034456002248874E-4, + "100.0" : 3.8034456002248874E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4479450895260054E-4, + 3.433042501300425E-4, + 3.4350282059581757E-4 + ], + [ + 3.721156910878079E-4, + 3.7172604909203004E-4, + 3.8034456002248874E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.4116853284428106, + "scoreError" : 0.3601896999024966, + "scoreConfidence" : [ + 2.051495628540314, + 2.771875028345307 + ], + "scorePercentiles" : { + "0.0" : 2.177098801915542, + "50.0" : 2.2890667546767487, + "90.0" : 2.727156159129847, + "95.0" : 2.730167951678952, + "99.0" : 2.730167951678952, + "99.9" : 2.730167951678952, + "99.99" : 2.730167951678952, + "99.999" : 2.730167951678952, + "99.9999" : 2.730167951678952, + "100.0" : 2.730167951678952 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.700050026187905, + 2.730167951678952, + 2.675195960417224, + 2.6286456739358908, + 2.2997501478500806 + ], + [ + 2.278383361503417, + 2.224587737322064, + 2.2243038318505337, + 2.1786697917664997, + 2.177098801915542 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01365911281066772, + "scoreError" : 1.7220565428795008E-4, + "scoreConfidence" : [ + 0.01348690715637977, + 0.01383131846495567 + ], + "scorePercentiles" : { + "0.0" : 0.013600119455131735, + "50.0" : 0.013658907414950613, + "90.0" : 0.013717556483306654, + "95.0" : 0.013717556483306654, + "99.0" : 0.013717556483306654, + "99.9" : 0.013717556483306654, + "99.99" : 0.013717556483306654, + "99.999" : 0.013717556483306654, + "99.9999" : 0.013717556483306654, + "100.0" : 0.013717556483306654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013717556483306654, + 0.013714814521880331, + 0.01371304064631494 + ], + [ + 0.013604371573786371, + 0.013600119455131735, + 0.013604774183586289 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0431899206108504, + "scoreError" : 0.2893457720961509, + "scoreConfidence" : [ + 0.7538441485146994, + 1.3325356927070013 + ], + "scorePercentiles" : { + "0.0" : 0.9489547735079229, + "50.0" : 1.042728844238851, + "90.0" : 1.1382137088549966, + "95.0" : 1.1382137088549966, + "99.0" : 1.1382137088549966, + "99.9" : 1.1382137088549966, + "99.99" : 1.1382137088549966, + "99.999" : 1.1382137088549966, + "99.9999" : 1.1382137088549966, + "100.0" : 1.1382137088549966 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9489547735079229, + 0.9489822451129246, + 0.9490575880231565 + ], + [ + 1.1364001004545454, + 1.1382137088549966, + 1.137531107711556 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01032750098793153, + "scoreError" : 7.773222868154133E-5, + "scoreConfidence" : [ + 0.010249768759249989, + 0.010405233216613071 + ], + "scorePercentiles" : { + "0.0" : 0.010300805985031242, + "50.0" : 0.010326478235850173, + "90.0" : 0.010357986808388108, + "95.0" : 0.010357986808388108, + "99.0" : 0.010357986808388108, + "99.9" : 0.010357986808388108, + "99.99" : 0.010357986808388108, + "99.999" : 0.010357986808388108, + "99.9999" : 0.010357986808388108, + "100.0" : 0.010357986808388108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010349764649751405, + 0.010357986808388108, + 0.010350206619815979 + ], + [ + 0.010300805985031242, + 0.010303191821948943, + 0.010303050042653502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1554392668319546, + "scoreError" : 0.2005836854224783, + "scoreConfidence" : [ + 2.9548555814094764, + 3.356022952254433 + ], + "scorePercentiles" : { + "0.0" : 3.0841508353884093, + "50.0" : 3.155915943811939, + "90.0" : 3.2321467756948934, + "95.0" : 3.2321467756948934, + "99.0" : 3.2321467756948934, + "99.9" : 3.2321467756948934, + "99.99" : 3.2321467756948934, + "99.999" : 3.2321467756948934, + "99.9999" : 3.2321467756948934, + "100.0" : 3.2321467756948934 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.087758537654321, + 3.0998943744575325, + 3.0841508353884093 + ], + [ + 3.2119375131663457, + 3.2321467756948934, + 3.216747564630225 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7290293519755466, + "scoreError" : 0.038378126900840116, + "scoreConfidence" : [ + 2.6906512250747063, + 2.767407478876387 + ], + "scorePercentiles" : { + "0.0" : 2.7159294238392615, + "50.0" : 2.7251748647356013, + "90.0" : 2.7486795399835118, + "95.0" : 2.7486795399835118, + "99.0" : 2.7486795399835118, + "99.9" : 2.7486795399835118, + "99.99" : 2.7486795399835118, + "99.999" : 2.7486795399835118, + "99.9999" : 2.7486795399835118, + "100.0" : 2.7486795399835118 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7179188779891303, + 2.7190467922784123, + 2.7159294238392615 + ], + [ + 2.7486795399835118, + 2.7412985405701753, + 2.731302937192791 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1773765244219865, + "scoreError" : 0.004916984970571826, + "scoreConfidence" : [ + 0.17245953945141468, + 0.18229350939255834 + ], + "scorePercentiles" : { + "0.0" : 0.1753744505980148, + "50.0" : 0.17777417786064187, + "90.0" : 0.1789701104926893, + "95.0" : 0.1789701104926893, + "99.0" : 0.1789701104926893, + "99.9" : 0.1789701104926893, + "99.99" : 0.1789701104926893, + "99.999" : 0.1789701104926893, + "99.9999" : 0.1789701104926893, + "100.0" : 0.1789701104926893 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17668079446996465, + 0.17544487275215354, + 0.1753744505980148 + ], + [ + 0.17892135696777772, + 0.1789701104926893, + 0.1788675612513191 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32314382211508047, + "scoreError" : 0.0054237284500854395, + "scoreConfidence" : [ + 0.31772009366499504, + 0.3285675505651659 + ], + "scorePercentiles" : { + "0.0" : 0.32121306250602255, + "50.0" : 0.3231124482198333, + "90.0" : 0.325214354796748, + "95.0" : 0.325214354796748, + "99.0" : 0.325214354796748, + "99.9" : 0.325214354796748, + "99.99" : 0.325214354796748, + "99.999" : 0.325214354796748, + "99.9999" : 0.325214354796748, + "100.0" : 0.325214354796748 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32151843098736455, + 0.32143152638853173, + 0.32121306250602255 + ], + [ + 0.32477909255951415, + 0.3247064654523021, + 0.325214354796748 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15182382172233433, + "scoreError" : 0.015586652645248441, + "scoreConfidence" : [ + 0.13623716907708588, + 0.16741047436758277 + ], + "scorePercentiles" : { + "0.0" : 0.1465370071801184, + "50.0" : 0.15182155966115324, + "90.0" : 0.15705126049060872, + "95.0" : 0.15705126049060872, + "99.0" : 0.15705126049060872, + "99.9" : 0.15705126049060872, + "99.99" : 0.15705126049060872, + "99.999" : 0.15705126049060872, + "99.9999" : 0.15705126049060872, + "100.0" : 0.15705126049060872 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15705126049060872, + 0.15693600644989172, + 0.15669906689335297 + ], + [ + 0.1467755368910807, + 0.1465370071801184, + 0.14694405242895348 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4128329378796596, + "scoreError" : 0.02903631037840723, + "scoreConfidence" : [ + 0.3837966275012524, + 0.4418692482580668 + ], + "scorePercentiles" : { + "0.0" : 0.40121361652958876, + "50.0" : 0.41319984994189796, + "90.0" : 0.4236124690134282, + "95.0" : 0.4236124690134282, + "99.0" : 0.4236124690134282, + "99.9" : 0.4236124690134282, + "99.99" : 0.4236124690134282, + "99.999" : 0.4236124690134282, + "99.9999" : 0.4236124690134282, + "100.0" : 0.4236124690134282 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4236124690134282, + 0.4232945724021164, + 0.4190277899522333 + ], + [ + 0.40737190993156264, + 0.40247726944902806, + 0.40121361652958876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15804432944876773, + "scoreError" : 0.0025939366761875875, + "scoreConfidence" : [ + 0.15545039277258013, + 0.16063826612495533 + ], + "scorePercentiles" : { + "0.0" : 0.1572182601286022, + "50.0" : 0.15771325656284202, + "90.0" : 0.15980901208130913, + "95.0" : 0.15980901208130913, + "99.0" : 0.15980901208130913, + "99.9" : 0.15980901208130913, + "99.99" : 0.15980901208130913, + "99.999" : 0.15980901208130913, + "99.9999" : 0.15980901208130913, + "100.0" : 0.15980901208130913 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15774099626165275, + 0.15757227985944788, + 0.1576855168640313 + ], + [ + 0.15980901208130913, + 0.1572182601286022, + 0.15823991149756314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046359296190735165, + "scoreError" : 0.0014513607761411132, + "scoreConfidence" : [ + 0.04490793541459405, + 0.04781065696687628 + ], + "scorePercentiles" : { + "0.0" : 0.04586200895211627, + "50.0" : 0.04634238184322376, + "90.0" : 0.04687817887562287, + "95.0" : 0.04687817887562287, + "99.0" : 0.04687817887562287, + "99.9" : 0.04687817887562287, + "99.99" : 0.04687817887562287, + "99.999" : 0.04687817887562287, + "99.9999" : 0.04687817887562287, + "100.0" : 0.04687817887562287 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.045885107566796215, + 0.04591763342287118, + 0.04586200895211627 + ], + [ + 0.04676713026357633, + 0.04687817887562287, + 0.04684571806342812 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8726614.815432435, + "scoreError" : 344208.8043753692, + "scoreConfidence" : [ + 8382406.011057066, + 9070823.619807804 + ], + "scorePercentiles" : { + "0.0" : 8610436.327022376, + "50.0" : 8726611.250357991, + "90.0" : 8846042.899204245, + "95.0" : 8846042.899204245, + "99.0" : 8846042.899204245, + "99.9" : 8846042.899204245, + "99.99" : 8846042.899204245, + "99.999" : 8846042.899204245, + "99.9999" : 8846042.899204245, + "100.0" : 8846042.899204245 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8838834.816254416, + 8846042.899204245, + 8830654.882612534 + ], + [ + 8610436.327022376, + 8622567.618103448, + 8611152.34939759 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-19T00:18:40Z-dcb2f71942850c39d37d1af63587125c53ce56fd-jdk17.json b/performance-results/2025-10-19T00:18:40Z-dcb2f71942850c39d37d1af63587125c53ce56fd-jdk17.json new file mode 100644 index 0000000000..dcc120e001 --- /dev/null +++ b/performance-results/2025-10-19T00:18:40Z-dcb2f71942850c39d37d1af63587125c53ce56fd-jdk17.json @@ -0,0 +1,4 @@ +[ +] + + diff --git a/performance-results/2025-10-19T22:45:44Z-54044bbb4d07d257bf61d46c819678db37f65fa3-jdk17.json b/performance-results/2025-10-19T22:45:44Z-54044bbb4d07d257bf61d46c819678db37f65fa3-jdk17.json new file mode 100644 index 0000000000..7da7037b64 --- /dev/null +++ b/performance-results/2025-10-19T22:45:44Z-54044bbb4d07d257bf61d46c819678db37f65fa3-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3315740875669744, + "scoreError" : 0.043900532423843036, + "scoreConfidence" : [ + 3.2876735551431313, + 3.3754746199908174 + ], + "scorePercentiles" : { + "0.0" : 3.3248169769761087, + "50.0" : 3.3306939442236665, + "90.0" : 3.3400914848444567, + "95.0" : 3.3400914848444567, + "99.0" : 3.3400914848444567, + "99.9" : 3.3400914848444567, + "99.99" : 3.3400914848444567, + "99.999" : 3.3400914848444567, + "99.9999" : 3.3400914848444567, + "100.0" : 3.3400914848444567 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3248169769761087, + 3.3400914848444567 + ], + [ + 3.3276355638924335, + 3.333752324554899 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6888718919173817, + "scoreError" : 0.04556435982128628, + "scoreConfidence" : [ + 1.6433075320960955, + 1.734436251738668 + ], + "scorePercentiles" : { + "0.0" : 1.680180614672038, + "50.0" : 1.689888431095068, + "90.0" : 1.6955300908073525, + "95.0" : 1.6955300908073525, + "99.0" : 1.6955300908073525, + "99.9" : 1.6955300908073525, + "99.99" : 1.6955300908073525, + "99.999" : 1.6955300908073525, + "99.9999" : 1.6955300908073525, + "100.0" : 1.6955300908073525 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6935775301033922, + 1.6955300908073525 + ], + [ + 1.680180614672038, + 1.6861993320867439 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8464616659021951, + "scoreError" : 0.018387306467299042, + "scoreConfidence" : [ + 0.828074359434896, + 0.8648489723694941 + ], + "scorePercentiles" : { + "0.0" : 0.8435975269966616, + "50.0" : 0.8459395660171949, + "90.0" : 0.8503700045777288, + "95.0" : 0.8503700045777288, + "99.0" : 0.8503700045777288, + "99.9" : 0.8503700045777288, + "99.99" : 0.8503700045777288, + "99.999" : 0.8503700045777288, + "99.9999" : 0.8503700045777288, + "100.0" : 0.8503700045777288 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8435975269966616, + 0.8503700045777288 + ], + [ + 0.8455746820687182, + 0.8463044499656716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.02044155340253, + "scoreError" : 0.7269947066741034, + "scoreConfidence" : [ + 15.293446846728427, + 16.747436260076633 + ], + "scorePercentiles" : { + "0.0" : 15.770938259200275, + "50.0" : 16.025175644360306, + "90.0" : 16.260836364686103, + "95.0" : 16.260836364686103, + "99.0" : 16.260836364686103, + "99.9" : 16.260836364686103, + "99.99" : 16.260836364686103, + "99.999" : 16.260836364686103, + "99.9999" : 16.260836364686103, + "100.0" : 16.260836364686103 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.800002569487893, + 15.770938259200275, + 15.780919758224982 + ], + [ + 16.25034871923272, + 16.25960364958323, + 16.260836364686103 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2707.8437849522866, + "scoreError" : 23.646187992860717, + "scoreConfidence" : [ + 2684.197596959426, + 2731.489972945147 + ], + "scorePercentiles" : { + "0.0" : 2700.7376827838043, + "50.0" : 2704.83747660651, + "90.0" : 2720.0176686494356, + "95.0" : 2720.0176686494356, + "99.0" : 2720.0176686494356, + "99.9" : 2720.0176686494356, + "99.99" : 2720.0176686494356, + "99.999" : 2720.0176686494356, + "99.9999" : 2720.0176686494356, + "100.0" : 2720.0176686494356 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2700.8993875900087, + 2700.7376827838043, + 2701.076411680091 + ], + [ + 2708.5985415329283, + 2720.0176686494356, + 2715.7330174774497 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72745.50134303547, + "scoreError" : 1607.3379596723846, + "scoreConfidence" : [ + 71138.16338336309, + 74352.83930270786 + ], + "scorePercentiles" : { + "0.0" : 72201.64592745072, + "50.0" : 72733.85730466901, + "90.0" : 73315.12135860852, + "95.0" : 73315.12135860852, + "99.0" : 73315.12135860852, + "99.9" : 73315.12135860852, + "99.99" : 73315.12135860852, + "99.999" : 73315.12135860852, + "99.9999" : 73315.12135860852, + "100.0" : 73315.12135860852 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73231.0356131689, + 73258.00136157704, + 73315.12135860852 + ], + [ + 72230.52480123856, + 72236.67899616912, + 72201.64592745072 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 346.46241971290624, + "scoreError" : 10.912860118816111, + "scoreConfidence" : [ + 335.5495595940901, + 357.37527983172237 + ], + "scorePercentiles" : { + "0.0" : 342.4273398975916, + "50.0" : 346.1759092515375, + "90.0" : 351.32447184345375, + "95.0" : 351.32447184345375, + "99.0" : 351.32447184345375, + "99.9" : 351.32447184345375, + "99.99" : 351.32447184345375, + "99.999" : 351.32447184345375, + "99.9999" : 351.32447184345375, + "100.0" : 351.32447184345375 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.32447184345375, + 349.83935275938796, + 348.52658635984915 + ], + [ + 342.4273398975916, + 342.8315352739291, + 343.8252321432259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.6935029822577, + "scoreError" : 7.241764642969726, + "scoreConfidence" : [ + 106.45173833928797, + 120.93526762522743 + ], + "scorePercentiles" : { + "0.0" : 111.16071035808464, + "50.0" : 113.64694735773341, + "90.0" : 116.29476403757978, + "95.0" : 116.29476403757978, + "99.0" : 116.29476403757978, + "99.9" : 116.29476403757978, + "99.99" : 116.29476403757978, + "99.999" : 116.29476403757978, + "99.9999" : 116.29476403757978, + "100.0" : 116.29476403757978 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.16071035808464, + 111.39128992517124, + 111.47373344418854 + ], + [ + 115.8201612712783, + 116.29476403757978, + 116.02035885724364 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06139648845147374, + "scoreError" : 5.960544394699803E-4, + "scoreConfidence" : [ + 0.06080043401200376, + 0.06199254289094372 + ], + "scorePercentiles" : { + "0.0" : 0.061174615186977345, + "50.0" : 0.061382167665579614, + "90.0" : 0.06161735014849594, + "95.0" : 0.06161735014849594, + "99.0" : 0.06161735014849594, + "99.9" : 0.06161735014849594, + "99.99" : 0.06161735014849594, + "99.999" : 0.06161735014849594, + "99.9999" : 0.06161735014849594, + "100.0" : 0.06161735014849594 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061225942919942204, + 0.061174615186977345, + 0.06121353190707924 + ], + [ + 0.06153839241121702, + 0.06160909813513064, + 0.06161735014849594 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.626127543844963E-4, + "scoreError" : 5.2543184509612905E-6, + "scoreConfidence" : [ + 3.57358435933535E-4, + 3.678670728354576E-4 + ], + "scorePercentiles" : { + "0.0" : 3.6056127179811864E-4, + "50.0" : 3.624801655632518E-4, + "90.0" : 3.647912004436373E-4, + "95.0" : 3.647912004436373E-4, + "99.0" : 3.647912004436373E-4, + "99.9" : 3.647912004436373E-4, + "99.99" : 3.647912004436373E-4, + "99.999" : 3.647912004436373E-4, + "99.9999" : 3.647912004436373E-4, + "100.0" : 3.647912004436373E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.647912004436373E-4, + 3.64256707096856E-4, + 3.6382093437354007E-4 + ], + [ + 3.6110701584186243E-4, + 3.6113939675296345E-4, + 3.6056127179811864E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2667922308006805, + "scoreError" : 0.05202791333637616, + "scoreConfidence" : [ + 2.2147643174643044, + 2.3188201441370566 + ], + "scorePercentiles" : { + "0.0" : 2.2315042228915662, + "50.0" : 2.2695907637452066, + "90.0" : 2.3266673319967888, + "95.0" : 2.328365140628638, + "99.0" : 2.328365140628638, + "99.9" : 2.328365140628638, + "99.99" : 2.328365140628638, + "99.999" : 2.328365140628638, + "99.9999" : 2.328365140628638, + "100.0" : 2.328365140628638 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.3113870543101456, + 2.2692488772407535, + 2.2849624290610007, + 2.2315042228915662, + 2.2317529419772373 + ], + [ + 2.328365140628638, + 2.2710168410535876, + 2.2699326502496597, + 2.2334025904421617, + 2.2363495601520573 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013606438473996054, + "scoreError" : 4.040560826511415E-4, + "scoreConfidence" : [ + 0.013202382391344913, + 0.014010494556647195 + ], + "scorePercentiles" : { + "0.0" : 0.013471713023235764, + "50.0" : 0.01360433874515516, + "90.0" : 0.013743281382449466, + "95.0" : 0.013743281382449466, + "99.0" : 0.013743281382449466, + "99.9" : 0.013743281382449466, + "99.99" : 0.013743281382449466, + "99.999" : 0.013743281382449466, + "99.9999" : 0.013743281382449466, + "100.0" : 0.013743281382449466 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013741359119628219, + 0.013743281382449466, + 0.013728987506795754 + ], + [ + 0.013479689983514564, + 0.013471713023235764, + 0.013473599828352549 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9754204026656489, + "scoreError" : 0.019739509259656007, + "scoreConfidence" : [ + 0.9556808934059928, + 0.995159911925305 + ], + "scorePercentiles" : { + "0.0" : 0.9684973713926012, + "50.0" : 0.9754340619675017, + "90.0" : 0.9822600787741872, + "95.0" : 0.9822600787741872, + "99.0" : 0.9822600787741872, + "99.9" : 0.9822600787741872, + "99.99" : 0.9822600787741872, + "99.999" : 0.9822600787741872, + "99.9999" : 0.9822600787741872, + "100.0" : 0.9822600787741872 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9813225676577372, + 0.9822600787741872, + 0.9819175085910653 + ], + [ + 0.9684973713926012, + 0.9695455562772661, + 0.9689793333010367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010176133485506203, + "scoreError" : 0.0010086627041381538, + "scoreConfidence" : [ + 0.009167470781368049, + 0.011184796189644358 + ], + "scorePercentiles" : { + "0.0" : 0.009842391703853596, + "50.0" : 0.010178115046449148, + "90.0" : 0.010508054501627652, + "95.0" : 0.010508054501627652, + "99.0" : 0.010508054501627652, + "99.9" : 0.010508054501627652, + "99.99" : 0.010508054501627652, + "99.999" : 0.010508054501627652, + "99.9999" : 0.010508054501627652, + "100.0" : 0.010508054501627652 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01050195138369641, + 0.010508054501627652, + 0.010503399811784081 + ], + [ + 0.009854278709201884, + 0.009846724802873595, + 0.009842391703853596 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.056214959267822, + "scoreError" : 0.1817253953248134, + "scoreConfidence" : [ + 2.8744895639430084, + 3.2379403545926353 + ], + "scorePercentiles" : { + "0.0" : 2.9877507461170847, + "50.0" : 3.0615532435535595, + "90.0" : 3.12271168227216, + "95.0" : 3.12271168227216, + "99.0" : 3.12271168227216, + "99.9" : 3.12271168227216, + "99.99" : 3.12271168227216, + "99.999" : 3.12271168227216, + "99.9999" : 3.12271168227216, + "100.0" : 3.12271168227216 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1143215597758407, + 3.12271168227216, + 3.106227554658385 + ], + [ + 2.9877507461170847, + 3.0168789324487335, + 2.989399280334728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.841375842550949, + "scoreError" : 0.1643556991600567, + "scoreConfidence" : [ + 2.6770201433908927, + 3.0057315417110058 + ], + "scorePercentiles" : { + "0.0" : 2.783482743946563, + "50.0" : 2.832620632437232, + "90.0" : 2.906042618826264, + "95.0" : 2.906042618826264, + "99.0" : 2.906042618826264, + "99.9" : 2.906042618826264, + "99.99" : 2.906042618826264, + "99.999" : 2.906042618826264, + "99.9999" : 2.906042618826264, + "100.0" : 2.906042618826264 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7957030533967013, + 2.783482743946563, + 2.7888392052426103 + ], + [ + 2.906042618826264, + 2.9046492224157956, + 2.869538211477762 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17824132961952385, + "scoreError" : 0.0062354394874895545, + "scoreConfidence" : [ + 0.1720058901320343, + 0.1844767691070134 + ], + "scorePercentiles" : { + "0.0" : 0.1761488206157965, + "50.0" : 0.17826658232813009, + "90.0" : 0.180300912249387, + "95.0" : 0.180300912249387, + "99.0" : 0.180300912249387, + "99.9" : 0.180300912249387, + "99.99" : 0.180300912249387, + "99.999" : 0.180300912249387, + "99.9999" : 0.180300912249387, + "100.0" : 0.180300912249387 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18025644127401852, + 0.180300912249387, + 0.18025506465626015 + ], + [ + 0.1762086389216809, + 0.1761488206157965, + 0.1762781 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3281479274995302, + "scoreError" : 0.009494988208793766, + "scoreConfidence" : [ + 0.31865293929073646, + 0.33764291570832394 + ], + "scorePercentiles" : { + "0.0" : 0.3241930054786527, + "50.0" : 0.32886170433612677, + "90.0" : 0.3312057972046501, + "95.0" : 0.3312057972046501, + "99.0" : 0.3312057972046501, + "99.9" : 0.3312057972046501, + "99.99" : 0.3312057972046501, + "99.999" : 0.3312057972046501, + "99.9999" : 0.3312057972046501, + "100.0" : 0.3312057972046501 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3310179184403032, + 0.3312057972046501, + 0.33118986292432523 + ], + [ + 0.32670549023195034, + 0.3245754907172996, + 0.3241930054786527 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14735763876016833, + "scoreError" : 0.002644237359203861, + "scoreConfidence" : [ + 0.14471340140096448, + 0.15000187611937219 + ], + "scorePercentiles" : { + "0.0" : 0.14545827604363637, + "50.0" : 0.14765267073222946, + "90.0" : 0.14793855684423865, + "95.0" : 0.14793855684423865, + "99.0" : 0.14793855684423865, + "99.9" : 0.14793855684423865, + "99.99" : 0.14793855684423865, + "99.999" : 0.14793855684423865, + "99.9999" : 0.14793855684423865, + "100.0" : 0.14793855684423865 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14754666808799446, + 0.1478969901206815, + 0.14545827604363637 + ], + [ + 0.14793855684423865, + 0.14764530853717947, + 0.14766003292727944 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40426995723344233, + "scoreError" : 0.03429697039329411, + "scoreConfidence" : [ + 0.36997298684014823, + 0.43856692762673644 + ], + "scorePercentiles" : { + "0.0" : 0.39312622033964933, + "50.0" : 0.40286351802594406, + "90.0" : 0.4180215306190695, + "95.0" : 0.4180215306190695, + "99.0" : 0.4180215306190695, + "99.9" : 0.4180215306190695, + "99.99" : 0.4180215306190695, + "99.999" : 0.4180215306190695, + "99.9999" : 0.4180215306190695, + "100.0" : 0.4180215306190695 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3931981737506389, + 0.39335179923691144, + 0.39312622033964933 + ], + [ + 0.4155467826394083, + 0.4180215306190695, + 0.4123752368149767 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15333712559752977, + "scoreError" : 0.007725136591590981, + "scoreConfidence" : [ + 0.14561198900593877, + 0.16106226218912076 + ], + "scorePercentiles" : { + "0.0" : 0.1505838245595543, + "50.0" : 0.15341686330588195, + "90.0" : 0.15596691091425186, + "95.0" : 0.15596691091425186, + "99.0" : 0.15596691091425186, + "99.9" : 0.15596691091425186, + "99.99" : 0.15596691091425186, + "99.999" : 0.15596691091425186, + "99.9999" : 0.15596691091425186, + "100.0" : 0.15596691091425186 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15577898549731287, + 0.1557967629307659, + 0.15596691091425186 + ], + [ + 0.151054741114451, + 0.1505838245595543, + 0.15084152856884275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04721606023294866, + "scoreError" : 5.641411759515206E-4, + "scoreConfidence" : [ + 0.046651919056997136, + 0.04778020140890018 + ], + "scorePercentiles" : { + "0.0" : 0.04700781159100097, + "50.0" : 0.0472298123601346, + "90.0" : 0.04741054001621414, + "95.0" : 0.04741054001621414, + "99.0" : 0.04741054001621414, + "99.9" : 0.04741054001621414, + "99.99" : 0.04741054001621414, + "99.999" : 0.04741054001621414, + "99.9999" : 0.04741054001621414, + "100.0" : 0.04741054001621414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04740084685026307, + 0.04738349724468957, + 0.04741054001621414 + ], + [ + 0.04707612747557962, + 0.04701753821994452, + 0.04700781159100097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8689582.370710716, + "scoreError" : 569350.4993661795, + "scoreConfidence" : [ + 8120231.871344537, + 9258932.870076895 + ], + "scorePercentiles" : { + "0.0" : 8472024.248941574, + "50.0" : 8695699.80039107, + "90.0" : 8880616.475598935, + "95.0" : 8880616.475598935, + "99.0" : 8880616.475598935, + "99.9" : 8880616.475598935, + "99.99" : 8880616.475598935, + "99.999" : 8880616.475598935, + "99.9999" : 8880616.475598935, + "100.0" : 8880616.475598935 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8878482.526175687, + 8880616.475598935, + 8863099.243578387 + ], + [ + 8472024.248941574, + 8528300.357203752, + 8514971.372765958 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-20T21:41:58Z-d11e349d4adaa354708f7717c386be7e72bf8ef5-jdk17.json b/performance-results/2025-10-20T21:41:58Z-d11e349d4adaa354708f7717c386be7e72bf8ef5-jdk17.json new file mode 100644 index 0000000000..661510fda6 --- /dev/null +++ b/performance-results/2025-10-20T21:41:58Z-d11e349d4adaa354708f7717c386be7e72bf8ef5-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3054155981078175, + "scoreError" : 0.09376198144957841, + "scoreConfidence" : [ + 3.2116536166582392, + 3.3991775795573957 + ], + "scorePercentiles" : { + "0.0" : 3.285445739850843, + "50.0" : 3.3082782606159835, + "90.0" : 3.3196601313484595, + "95.0" : 3.3196601313484595, + "99.0" : 3.3196601313484595, + "99.9" : 3.3196601313484595, + "99.99" : 3.3196601313484595, + "99.999" : 3.3196601313484595, + "99.9999" : 3.3196601313484595, + "100.0" : 3.3196601313484595 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.310877171290436, + 3.3196601313484595 + ], + [ + 3.285445739850843, + 3.3056793499415313 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.676087374424178, + "scoreError" : 0.03178200866103777, + "scoreConfidence" : [ + 1.6443053657631401, + 1.7078693830852159 + ], + "scorePercentiles" : { + "0.0" : 1.671119403145298, + "50.0" : 1.6753007632402435, + "90.0" : 1.6826285680709272, + "95.0" : 1.6826285680709272, + "99.0" : 1.6826285680709272, + "99.9" : 1.6826285680709272, + "99.99" : 1.6826285680709272, + "99.999" : 1.6826285680709272, + "99.9999" : 1.6826285680709272, + "100.0" : 1.6826285680709272 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6739108734005115, + 1.6826285680709272 + ], + [ + 1.671119403145298, + 1.6766906530799757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8436356402436871, + "scoreError" : 0.00959422240117759, + "scoreConfidence" : [ + 0.8340414178425095, + 0.8532298626448647 + ], + "scorePercentiles" : { + "0.0" : 0.8420871256845944, + "50.0" : 0.843402010267976, + "90.0" : 0.8456514147542018, + "95.0" : 0.8456514147542018, + "99.0" : 0.8456514147542018, + "99.9" : 0.8456514147542018, + "99.99" : 0.8456514147542018, + "99.999" : 0.8456514147542018, + "99.9999" : 0.8456514147542018, + "100.0" : 0.8456514147542018 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8420871256845944, + 0.8432558264191192 + ], + [ + 0.8435481941168328, + 0.8456514147542018 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.393905218598888, + "scoreError" : 0.9344685569970417, + "scoreConfidence" : [ + 14.459436661601847, + 16.32837377559593 + ], + "scorePercentiles" : { + "0.0" : 14.997329291862652, + "50.0" : 15.392429766861255, + "90.0" : 15.813282366538774, + "95.0" : 15.813282366538774, + "99.0" : 15.813282366538774, + "99.9" : 15.813282366538774, + "99.99" : 15.813282366538774, + "99.999" : 15.813282366538774, + "99.9999" : 15.813282366538774, + "100.0" : 15.813282366538774 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.813282366538774, + 15.666522973574216, + 15.568830011577472 + ], + [ + 15.216029522145039, + 15.101437145895183, + 14.997329291862652 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2535.8009731329826, + "scoreError" : 295.3597740024108, + "scoreConfidence" : [ + 2240.441199130572, + 2831.160747135393 + ], + "scorePercentiles" : { + "0.0" : 2426.4615104511795, + "50.0" : 2527.650345379056, + "90.0" : 2659.363919904804, + "95.0" : 2659.363919904804, + "99.0" : 2659.363919904804, + "99.9" : 2659.363919904804, + "99.99" : 2659.363919904804, + "99.999" : 2659.363919904804, + "99.9999" : 2659.363919904804, + "100.0" : 2659.363919904804 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2426.4615104511795, + 2449.7721015576794, + 2447.4471847015498 + ], + [ + 2626.232532982251, + 2605.5285892004326, + 2659.363919904804 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72237.50456726363, + "scoreError" : 1388.7319582856005, + "scoreConfidence" : [ + 70848.77260897803, + 73626.23652554923 + ], + "scorePercentiles" : { + "0.0" : 71492.71188604925, + "50.0" : 72296.16133779299, + "90.0" : 72725.21768431854, + "95.0" : 72725.21768431854, + "99.0" : 72725.21768431854, + "99.9" : 72725.21768431854, + "99.99" : 72725.21768431854, + "99.999" : 72725.21768431854, + "99.9999" : 72725.21768431854, + "100.0" : 72725.21768431854 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72651.15450924686, + 72596.75188642036, + 72725.21768431854 + ], + [ + 71995.5707891656, + 71963.6206483811, + 71492.71188604925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 339.63248973383867, + "scoreError" : 12.547431652168951, + "scoreConfidence" : [ + 327.08505808166973, + 352.1799213860076 + ], + "scorePercentiles" : { + "0.0" : 334.98765634134037, + "50.0" : 339.10516584609513, + "90.0" : 346.90317495289065, + "95.0" : 346.90317495289065, + "99.0" : 346.90317495289065, + "99.9" : 346.90317495289065, + "99.99" : 346.90317495289065, + "99.999" : 346.90317495289065, + "99.9999" : 346.90317495289065, + "100.0" : 346.90317495289065 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 335.66641036581433, + 334.98765634134037, + 337.7544952487923 + ], + [ + 340.45583644339797, + 346.90317495289065, + 342.02736505079633 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 110.24404594471368, + "scoreError" : 6.498981059130715, + "scoreConfidence" : [ + 103.74506488558296, + 116.74302700384439 + ], + "scorePercentiles" : { + "0.0" : 105.74660546167618, + "50.0" : 110.71420869768458, + "90.0" : 112.17633411392146, + "95.0" : 112.17633411392146, + "99.0" : 112.17633411392146, + "99.9" : 112.17633411392146, + "99.99" : 112.17633411392146, + "99.999" : 112.17633411392146, + "99.9999" : 112.17633411392146, + "100.0" : 112.17633411392146 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.78617927101136, + 112.17633411392146, + 110.89928102899106 + ], + [ + 105.74660546167618, + 110.52913636637811, + 110.32673942630389 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06300509561981359, + "scoreError" : 7.240261937420414E-4, + "scoreConfidence" : [ + 0.06228106942607155, + 0.06372912181355563 + ], + "scorePercentiles" : { + "0.0" : 0.06269206481644014, + "50.0" : 0.06305455682868266, + "90.0" : 0.06331783412901429, + "95.0" : 0.06331783412901429, + "99.0" : 0.06331783412901429, + "99.9" : 0.06331783412901429, + "99.99" : 0.06331783412901429, + "99.999" : 0.06331783412901429, + "99.9999" : 0.06331783412901429, + "100.0" : 0.06331783412901429 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06296597251588286, + 0.06319250588629312, + 0.06269206481644014 + ], + [ + 0.06314314114148245, + 0.06331783412901429, + 0.06271905522976863 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.916348420058627E-4, + "scoreError" : 4.748017203066632E-5, + "scoreConfidence" : [ + 3.4415466997519636E-4, + 4.39115014036529E-4 + ], + "scorePercentiles" : { + "0.0" : 3.768803234424144E-4, + "50.0" : 3.89035121373022E-4, + "90.0" : 4.242737592026761E-4, + "95.0" : 4.242737592026761E-4, + "99.0" : 4.242737592026761E-4, + "99.9" : 4.242737592026761E-4, + "99.99" : 4.242737592026761E-4, + "99.999" : 4.242737592026761E-4, + "99.9999" : 4.242737592026761E-4, + "100.0" : 4.242737592026761E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.893178825886359E-4, + 3.9059887500822693E-4, + 4.242737592026761E-4 + ], + [ + 3.768803234424144E-4, + 3.799858516358144E-4, + 3.887523601574081E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.4297639218442963, + "scoreError" : 0.03037990756592488, + "scoreConfidence" : [ + 2.3993840142783713, + 2.4601438294102214 + ], + "scorePercentiles" : { + "0.0" : 2.3830454822492255, + "50.0" : 2.4300618136540333, + "90.0" : 2.453854872938426, + "95.0" : 2.4541955484662576, + "99.0" : 2.4541955484662576, + "99.9" : 2.4541955484662576, + "99.99" : 2.4541955484662576, + "99.999" : 2.4541955484662576, + "99.9999" : 2.4541955484662576, + "100.0" : 2.4541955484662576 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.4207216732817036, + 2.4541955484662576, + 2.446255717221135, + 2.432871962539528, + 2.3830454822492255 + ], + [ + 2.4248905300678953, + 2.424745884121212, + 2.450788793187944, + 2.430026720845481, + 2.4300969064625852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.014056837374271604, + "scoreError" : 5.667142021386464E-4, + "scoreConfidence" : [ + 0.013490123172132957, + 0.014623551576410251 + ], + "scorePercentiles" : { + "0.0" : 0.013792596786651182, + "50.0" : 0.014146656454890386, + "90.0" : 0.014247481118123923, + "95.0" : 0.014247481118123923, + "99.0" : 0.014247481118123923, + "99.9" : 0.014247481118123923, + "99.99" : 0.014247481118123923, + "99.999" : 0.014247481118123923, + "99.9999" : 0.014247481118123923, + "100.0" : 0.014247481118123923 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.014199109719457374, + 0.0141445008670463, + 0.014247481118123923 + ], + [ + 0.013808523711616371, + 0.013792596786651182, + 0.014148812042734474 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0156810751264758, + "scoreError" : 0.08398491301950424, + "scoreConfidence" : [ + 0.9316961621069715, + 1.09966598814598 + ], + "scorePercentiles" : { + "0.0" : 0.9816506152336082, + "50.0" : 1.0139148560343691, + "90.0" : 1.0506488708897994, + "95.0" : 1.0506488708897994, + "99.0" : 1.0506488708897994, + "99.9" : 1.0506488708897994, + "99.99" : 1.0506488708897994, + "99.999" : 1.0506488708897994, + "99.9999" : 1.0506488708897994, + "100.0" : 1.0506488708897994 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0506488708897994, + 1.0459323294289897, + 1.0283699962982005 + ], + [ + 0.9880249231377198, + 0.9816506152336082, + 0.9994597157705377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011027441312278556, + "scoreError" : 6.296653091615418E-4, + "scoreConfidence" : [ + 0.010397776003117015, + 0.011657106621440098 + ], + "scorePercentiles" : { + "0.0" : 0.010709623359878, + "50.0" : 0.0110429784971375, + "90.0" : 0.011265602926266554, + "95.0" : 0.011265602926266554, + "99.0" : 0.011265602926266554, + "99.9" : 0.011265602926266554, + "99.99" : 0.011265602926266554, + "99.999" : 0.011265602926266554, + "99.9999" : 0.011265602926266554, + "100.0" : 0.011265602926266554 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011265602926266554, + 0.01123061306805803, + 0.0111627968320943 + ], + [ + 0.0109231601621807, + 0.010872851525193747, + 0.010709623359878 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.392844528970533, + "scoreError" : 0.4009873698024673, + "scoreConfidence" : [ + 2.991857159168066, + 3.793831898773 + ], + "scorePercentiles" : { + "0.0" : 3.2545695256994143, + "50.0" : 3.3339629376666666, + "90.0" : 3.620208074529667, + "95.0" : 3.620208074529667, + "99.0" : 3.620208074529667, + "99.9" : 3.620208074529667, + "99.99" : 3.620208074529667, + "99.999" : 3.620208074529667, + "99.9999" : 3.620208074529667, + "100.0" : 3.620208074529667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.2974563902439025, + 3.3344674513333334, + 3.2545695256994143 + ], + [ + 3.620208074529667, + 3.5169073080168776, + 3.333458424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.001755826123597, + "scoreError" : 0.173857245552785, + "scoreConfidence" : [ + 2.8278985805708117, + 3.175613071676382 + ], + "scorePercentiles" : { + "0.0" : 2.939990027042916, + "50.0" : 3.003299494898982, + "90.0" : 3.0656685107296138, + "95.0" : 3.0656685107296138, + "99.0" : 3.0656685107296138, + "99.9" : 3.0656685107296138, + "99.99" : 3.0656685107296138, + "99.999" : 3.0656685107296138, + "99.9999" : 3.0656685107296138, + "100.0" : 3.0656685107296138 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0560461885120684, + 3.0524129032651817, + 3.0656685107296138 + ], + [ + 2.942231240659017, + 2.9541860865327823, + 2.939990027042916 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17909300194621844, + "scoreError" : 0.003575047757765611, + "scoreConfidence" : [ + 0.17551795418845284, + 0.18266804970398404 + ], + "scorePercentiles" : { + "0.0" : 0.17769852693865945, + "50.0" : 0.1791511911922719, + "90.0" : 0.18052178215426828, + "95.0" : 0.18052178215426828, + "99.0" : 0.18052178215426828, + "99.9" : 0.18052178215426828, + "99.99" : 0.18052178215426828, + "99.999" : 0.18052178215426828, + "99.9999" : 0.18052178215426828, + "100.0" : 0.18052178215426828 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18027940635647455, + 0.18052178215426828, + 0.17983628228460447 + ], + [ + 0.17846610009993932, + 0.1777559138433645, + 0.17769852693865945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3343652853640527, + "scoreError" : 0.018902742422715824, + "scoreConfidence" : [ + 0.31546254294133685, + 0.3532680277867685 + ], + "scorePercentiles" : { + "0.0" : 0.3228703011332451, + "50.0" : 0.3350653734175332, + "90.0" : 0.34138355695900047, + "95.0" : 0.34138355695900047, + "99.0" : 0.34138355695900047, + "99.9" : 0.34138355695900047, + "99.99" : 0.34138355695900047, + "99.999" : 0.34138355695900047, + "99.9999" : 0.34138355695900047, + "100.0" : 0.34138355695900047 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3402400753946652, + 0.33156703186233877, + 0.3339508688305617 + ], + [ + 0.3228703011332451, + 0.33617987800450466, + 0.34138355695900047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14822237494444893, + "scoreError" : 0.007460846633585029, + "scoreConfidence" : [ + 0.1407615283108639, + 0.15568322157803396 + ], + "scorePercentiles" : { + "0.0" : 0.1446915859160228, + "50.0" : 0.1490354061633209, + "90.0" : 0.1512626890730881, + "95.0" : 0.1512626890730881, + "99.0" : 0.1512626890730881, + "99.9" : 0.1512626890730881, + "99.99" : 0.1512626890730881, + "99.999" : 0.1512626890730881, + "99.9999" : 0.1512626890730881, + "100.0" : 0.1512626890730881 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14908345429201825, + 0.145234580704659, + 0.1446915859160228 + ], + [ + 0.1489873580346235, + 0.15007458164628198, + 0.1512626890730881 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40873200265399506, + "scoreError" : 0.03658691969404614, + "scoreConfidence" : [ + 0.3721450829599489, + 0.4453189223480412 + ], + "scorePercentiles" : { + "0.0" : 0.3972275969811321, + "50.0" : 0.40545372857322703, + "90.0" : 0.42818524547206166, + "95.0" : 0.42818524547206166, + "99.0" : 0.42818524547206166, + "99.9" : 0.42818524547206166, + "99.99" : 0.42818524547206166, + "99.999" : 0.42818524547206166, + "99.9999" : 0.42818524547206166, + "100.0" : 0.42818524547206166 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3972275969811321, + 0.3972482878366569, + 0.3989281384234881 + ], + [ + 0.42818524547206166, + 0.41882342848766596, + 0.411979318722966 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15735390202964428, + "scoreError" : 0.0036322914071087245, + "scoreConfidence" : [ + 0.15372161062253556, + 0.160986193436753 + ], + "scorePercentiles" : { + "0.0" : 0.1559640685912132, + "50.0" : 0.15741542144184106, + "90.0" : 0.15871133765017695, + "95.0" : 0.15871133765017695, + "99.0" : 0.15871133765017695, + "99.9" : 0.15871133765017695, + "99.99" : 0.15871133765017695, + "99.999" : 0.15871133765017695, + "99.9999" : 0.15871133765017695, + "100.0" : 0.15871133765017695 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15602689611970105, + 0.15660370697026169, + 0.1559640685912132 + ], + [ + 0.15871133765017695, + 0.15822713591342047, + 0.15859026693309228 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04752460524168182, + "scoreError" : 0.0018567239580865274, + "scoreConfidence" : [ + 0.045667881283595294, + 0.04938132919976834 + ], + "scorePercentiles" : { + "0.0" : 0.046708471104219114, + "50.0" : 0.04756924361186725, + "90.0" : 0.048347433363952814, + "95.0" : 0.048347433363952814, + "99.0" : 0.048347433363952814, + "99.9" : 0.048347433363952814, + "99.99" : 0.048347433363952814, + "99.999" : 0.048347433363952814, + "99.9999" : 0.048347433363952814, + "100.0" : 0.048347433363952814 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047321103021412514, + 0.046708471104219114, + 0.04687779061896458 + ], + [ + 0.047817384202321976, + 0.048347433363952814, + 0.04807544913921994 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8853861.58637777, + "scoreError" : 363352.09480054607, + "scoreConfidence" : [ + 8490509.491577223, + 9217213.681178316 + ], + "scorePercentiles" : { + "0.0" : 8711391.552264808, + "50.0" : 8856450.63330895, + "90.0" : 9034318.155374886, + "95.0" : 9034318.155374886, + "99.0" : 9034318.155374886, + "99.9" : 9034318.155374886, + "99.99" : 9034318.155374886, + "99.999" : 9034318.155374886, + "99.9999" : 9034318.155374886, + "100.0" : 9034318.155374886 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8831716.586937334, + 8711391.552264808, + 8712034.959930314 + ], + [ + 8881184.679680567, + 8952523.584078712, + 9034318.155374886 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-24T00:29:41Z-19e43cc8f2b9d2474b2bd241ebc0162290fd16db-jdk17.json b/performance-results/2025-10-24T00:29:41Z-19e43cc8f2b9d2474b2bd241ebc0162290fd16db-jdk17.json new file mode 100644 index 0000000000..e6b4b49d83 --- /dev/null +++ b/performance-results/2025-10-24T00:29:41Z-19e43cc8f2b9d2474b2bd241ebc0162290fd16db-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3293674619856723, + "scoreError" : 0.04906800470483081, + "scoreConfidence" : [ + 3.2802994572808415, + 3.378435466690503 + ], + "scorePercentiles" : { + "0.0" : 3.3225005687649474, + "50.0" : 3.3277383875539064, + "90.0" : 3.3394925040699315, + "95.0" : 3.3394925040699315, + "99.0" : 3.3394925040699315, + "99.9" : 3.3394925040699315, + "99.99" : 3.3394925040699315, + "99.999" : 3.3394925040699315, + "99.9999" : 3.3394925040699315, + "100.0" : 3.3394925040699315 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3225005687649474, + 3.330738173011769 + ], + [ + 3.324738602096043, + 3.3394925040699315 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6674029154769021, + "scoreError" : 0.029957270834028937, + "scoreConfidence" : [ + 1.6374456446428731, + 1.697360186310931 + ], + "scorePercentiles" : { + "0.0" : 1.663328364030914, + "50.0" : 1.6670442552473765, + "90.0" : 1.6721947873819412, + "95.0" : 1.6721947873819412, + "99.0" : 1.6721947873819412, + "99.9" : 1.6721947873819412, + "99.99" : 1.6721947873819412, + "99.999" : 1.6721947873819412, + "99.9999" : 1.6721947873819412, + "100.0" : 1.6721947873819412 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.67055523840381, + 1.663533272090943 + ], + [ + 1.663328364030914, + 1.6721947873819412 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8461700286535581, + "scoreError" : 0.03757490799315342, + "scoreConfidence" : [ + 0.8085951206604046, + 0.8837449366467115 + ], + "scorePercentiles" : { + "0.0" : 0.8383434523406265, + "50.0" : 0.8471983875839716, + "90.0" : 0.8519398871056629, + "95.0" : 0.8519398871056629, + "99.0" : 0.8519398871056629, + "99.9" : 0.8519398871056629, + "99.99" : 0.8519398871056629, + "99.999" : 0.8519398871056629, + "99.9999" : 0.8519398871056629, + "100.0" : 0.8519398871056629 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8383434523406265, + 0.8519398871056629 + ], + [ + 0.8456536148857641, + 0.8487431602821791 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.292971644842336, + "scoreError" : 0.37238663727981264, + "scoreConfidence" : [ + 15.920585007562522, + 16.66535828212215 + ], + "scorePercentiles" : { + "0.0" : 16.152958440583, + "50.0" : 16.29708097418063, + "90.0" : 16.42610556800866, + "95.0" : 16.42610556800866, + "99.0" : 16.42610556800866, + "99.9" : 16.42610556800866, + "99.99" : 16.42610556800866, + "99.999" : 16.42610556800866, + "99.9999" : 16.42610556800866, + "100.0" : 16.42610556800866 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.17366967077022, + 16.152958440583, + 16.190627885736188 + ], + [ + 16.42610556800866, + 16.410934241330896, + 16.40353406262507 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2715.5412171685844, + "scoreError" : 138.59475589647064, + "scoreConfidence" : [ + 2576.9464612721135, + 2854.135973065055 + ], + "scorePercentiles" : { + "0.0" : 2665.222074171529, + "50.0" : 2714.0247866511827, + "90.0" : 2764.834472664056, + "95.0" : 2764.834472664056, + "99.0" : 2764.834472664056, + "99.9" : 2764.834472664056, + "99.99" : 2764.834472664056, + "99.999" : 2764.834472664056, + "99.9999" : 2764.834472664056, + "100.0" : 2764.834472664056 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2764.834472664056, + 2753.402528597827, + 2763.0561933020626 + ], + [ + 2672.0849895714937, + 2665.222074171529, + 2674.647044704539 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73938.19579699199, + "scoreError" : 1128.3106220680852, + "scoreConfidence" : [ + 72809.88517492391, + 75066.50641906007 + ], + "scorePercentiles" : { + "0.0" : 73500.47329180085, + "50.0" : 73953.75252718109, + "90.0" : 74362.64091815453, + "95.0" : 74362.64091815453, + "99.0" : 74362.64091815453, + "99.9" : 74362.64091815453, + "99.99" : 74362.64091815453, + "99.999" : 74362.64091815453, + "99.9999" : 74362.64091815453, + "100.0" : 74362.64091815453 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73650.73302479598, + 73573.29013874497, + 73500.47329180085 + ], + [ + 74285.26537888941, + 74362.64091815453, + 74256.7720295662 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 342.25249083899575, + "scoreError" : 2.9677262834672304, + "scoreConfidence" : [ + 339.2847645555285, + 345.220217122463 + ], + "scorePercentiles" : { + "0.0" : 341.1551178373904, + "50.0" : 341.93942136464386, + "90.0" : 344.1495895875865, + "95.0" : 344.1495895875865, + "99.0" : 344.1495895875865, + "99.9" : 344.1495895875865, + "99.99" : 344.1495895875865, + "99.999" : 344.1495895875865, + "99.9999" : 344.1495895875865, + "100.0" : 344.1495895875865 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 342.1494899078328, + 341.729352821455, + 341.66687689961884 + ], + [ + 341.1551178373904, + 342.6645179800909, + 344.1495895875865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 111.78165809441879, + "scoreError" : 8.915384197811301, + "scoreConfidence" : [ + 102.86627389660748, + 120.6970422922301 + ], + "scorePercentiles" : { + "0.0" : 108.21500558634686, + "50.0" : 111.90101177012917, + "90.0" : 114.80428654122856, + "95.0" : 114.80428654122856, + "99.0" : 114.80428654122856, + "99.9" : 114.80428654122856, + "99.99" : 114.80428654122856, + "99.999" : 114.80428654122856, + "99.9999" : 114.80428654122856, + "100.0" : 114.80428654122856 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.80428654122856, + 114.7322592517242, + 114.44568856247923 + ], + [ + 109.13637364695475, + 108.21500558634686, + 109.35633497777913 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061517816677902876, + "scoreError" : 0.0012288415620532555, + "scoreConfidence" : [ + 0.06028897511584962, + 0.06274665823995614 + ], + "scorePercentiles" : { + "0.0" : 0.06109344563710008, + "50.0" : 0.061507720005121155, + "90.0" : 0.061989358151500126, + "95.0" : 0.061989358151500126, + "99.0" : 0.061989358151500126, + "99.9" : 0.061989358151500126, + "99.99" : 0.061989358151500126, + "99.999" : 0.061989358151500126, + "99.9999" : 0.061989358151500126, + "100.0" : 0.061989358151500126 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.061876423209479316, + 0.061989358151500126, + 0.061882002289589795 + ], + [ + 0.061139016800763, + 0.06109344563710008, + 0.061126653978984945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.664597585138933E-4, + "scoreError" : 1.3572492987186868E-5, + "scoreConfidence" : [ + 3.5288726552670644E-4, + 3.800322515010802E-4 + ], + "scorePercentiles" : { + "0.0" : 3.614254708353374E-4, + "50.0" : 3.667236615728571E-4, + "90.0" : 3.7110035653857717E-4, + "95.0" : 3.7110035653857717E-4, + "99.0" : 3.7110035653857717E-4, + "99.9" : 3.7110035653857717E-4, + "99.99" : 3.7110035653857717E-4, + "99.999" : 3.7110035653857717E-4, + "99.9999" : 3.7110035653857717E-4, + "100.0" : 3.7110035653857717E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.708311149545145E-4, + 3.7064191508186006E-4, + 3.7110035653857717E-4 + ], + [ + 3.6280540806385414E-4, + 3.614254708353374E-4, + 3.619542856092169E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2872196104083966, + "scoreError" : 0.07412844633319081, + "scoreConfidence" : [ + 2.213091164075206, + 2.3613480567415874 + ], + "scorePercentiles" : { + "0.0" : 2.2292657962550155, + "50.0" : 2.273387452077459, + "90.0" : 2.378048491631434, + "95.0" : 2.3831622041934715, + "99.0" : 2.3831622041934715, + "99.9" : 2.3831622041934715, + "99.99" : 2.3831622041934715, + "99.999" : 2.3831622041934715, + "99.9999" : 2.3831622041934715, + "100.0" : 2.3831622041934715 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.322240684699327, + 2.2596399317668325, + 2.282118416609628, + 2.2292657962550155, + 2.233890054277418 + ], + [ + 2.332025078573094, + 2.3831622041934715, + 2.3113784943378786, + 2.26465648754529, + 2.2538189558260084 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013528699301644827, + "scoreError" : 5.473889630938144E-4, + "scoreConfidence" : [ + 0.012981310338551013, + 0.014076088264738641 + ], + "scorePercentiles" : { + "0.0" : 0.013335336667569014, + "50.0" : 0.01352824958300819, + "90.0" : 0.013722437970156955, + "95.0" : 0.013722437970156955, + "99.0" : 0.013722437970156955, + "99.9" : 0.013722437970156955, + "99.99" : 0.013722437970156955, + "99.999" : 0.013722437970156955, + "99.9999" : 0.013722437970156955, + "100.0" : 0.013722437970156955 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013362311777109078, + 0.01335499502666291, + 0.013335336667569014 + ], + [ + 0.0136941873889073, + 0.013702926979463702, + 0.013722437970156955 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0271471908712344, + "scoreError" : 0.28097393522983644, + "scoreConfidence" : [ + 0.746173255641398, + 1.3081211261010708 + ], + "scorePercentiles" : { + "0.0" : 0.9354837229186155, + "50.0" : 1.026985876130871, + "90.0" : 1.1192243538495972, + "95.0" : 1.1192243538495972, + "99.0" : 1.1192243538495972, + "99.9" : 1.1192243538495972, + "99.99" : 1.1192243538495972, + "99.999" : 1.1192243538495972, + "99.9999" : 1.1192243538495972, + "100.0" : 1.1192243538495972 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9354837229186155, + 0.9356085478529329, + 0.9359480321946654 + ], + [ + 1.118594768344519, + 1.1180237200670766, + 1.1192243538495972 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010446841228102835, + "scoreError" : 2.7556202950283364E-5, + "scoreConfidence" : [ + 0.010419285025152552, + 0.010474397431053118 + ], + "scorePercentiles" : { + "0.0" : 0.0104373416329027, + "50.0" : 0.01044416171410963, + "90.0" : 0.010459076265620228, + "95.0" : 0.010459076265620228, + "99.0" : 0.010459076265620228, + "99.9" : 0.010459076265620228, + "99.99" : 0.010459076265620228, + "99.999" : 0.010459076265620228, + "99.9999" : 0.010459076265620228, + "100.0" : 0.010459076265620228 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0104448630470067, + 0.010443460381212561, + 0.010437567480289156 + ], + [ + 0.0104373416329027, + 0.010459076265620228, + 0.010458738561585669 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.144877396489628, + "scoreError" : 0.14260135653996203, + "scoreConfidence" : [ + 3.002276039949666, + 3.28747875302959 + ], + "scorePercentiles" : { + "0.0" : 3.079296945812808, + "50.0" : 3.1496002536473107, + "90.0" : 3.203078624199744, + "95.0" : 3.203078624199744, + "99.0" : 3.203078624199744, + "99.9" : 3.203078624199744, + "99.99" : 3.203078624199744, + "99.999" : 3.203078624199744, + "99.9999" : 3.203078624199744, + "100.0" : 3.203078624199744 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.079296945812808, + 3.10354466191067, + 3.118398291147132 + ], + [ + 3.1841436397199234, + 3.1808022161474887, + 3.203078624199744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9189030338380753, + "scoreError" : 0.049008487358048546, + "scoreConfidence" : [ + 2.8698945464800265, + 2.967911521196124 + ], + "scorePercentiles" : { + "0.0" : 2.8922513603238866, + "50.0" : 2.9228719871736937, + "90.0" : 2.935256690049897, + "95.0" : 2.935256690049897, + "99.0" : 2.935256690049897, + "99.9" : 2.935256690049897, + "99.99" : 2.935256690049897, + "99.999" : 2.935256690049897, + "99.9999" : 2.935256690049897, + "100.0" : 2.935256690049897 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.935256690049897, + 2.9287700740849196, + 2.935009426056338 + ], + [ + 2.8922513603238866, + 2.905156752250944, + 2.9169739002624673 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17457404829406872, + "scoreError" : 0.002186901499397568, + "scoreConfidence" : [ + 0.17238714679467115, + 0.1767609497934663 + ], + "scorePercentiles" : { + "0.0" : 0.1737702649788003, + "50.0" : 0.1745163140671439, + "90.0" : 0.17543465041663012, + "95.0" : 0.17543465041663012, + "99.0" : 0.17543465041663012, + "99.9" : 0.17543465041663012, + "99.99" : 0.17543465041663012, + "99.999" : 0.17543465041663012, + "99.9999" : 0.17543465041663012, + "100.0" : 0.17543465041663012 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.173855739255911, + 0.17400251235384187, + 0.1737702649788003 + ], + [ + 0.17543465041663012, + 0.17535100697878309, + 0.17503011578044597 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32857119250828254, + "scoreError" : 0.030698727794404492, + "scoreConfidence" : [ + 0.29787246471387807, + 0.359269920302687 + ], + "scorePercentiles" : { + "0.0" : 0.3182167640488767, + "50.0" : 0.32859766756867925, + "90.0" : 0.33868487055914925, + "95.0" : 0.33868487055914925, + "99.0" : 0.33868487055914925, + "99.9" : 0.33868487055914925, + "99.99" : 0.33868487055914925, + "99.999" : 0.33868487055914925, + "99.9999" : 0.33868487055914925, + "100.0" : 0.33868487055914925 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3182167640488767, + 0.3186485493101361, + 0.31887520292720256 + ], + [ + 0.33832013221015594, + 0.33868487055914925, + 0.33868163599417483 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1442900670803878, + "scoreError" : 0.002941815164270516, + "scoreConfidence" : [ + 0.14134825191611727, + 0.14723188224465833 + ], + "scorePercentiles" : { + "0.0" : 0.14326695959943267, + "50.0" : 0.14432720178762953, + "90.0" : 0.14531220171754894, + "95.0" : 0.14531220171754894, + "99.0" : 0.14531220171754894, + "99.9" : 0.14531220171754894, + "99.99" : 0.14531220171754894, + "99.999" : 0.14531220171754894, + "99.9999" : 0.14531220171754894, + "100.0" : 0.14531220171754894 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14347273089338747, + 0.14326710064325726, + 0.14326695959943267 + ], + [ + 0.14531220171754894, + 0.14518167268187163, + 0.14523973694682876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40325564690883065, + "scoreError" : 0.0070256249152938115, + "scoreConfidence" : [ + 0.39623002199353685, + 0.41028127182412444 + ], + "scorePercentiles" : { + "0.0" : 0.3989540114896673, + "50.0" : 0.40379671858284355, + "90.0" : 0.40535863627888125, + "95.0" : 0.40535863627888125, + "99.0" : 0.40535863627888125, + "99.9" : 0.40535863627888125, + "99.99" : 0.40535863627888125, + "99.999" : 0.40535863627888125, + "99.9999" : 0.40535863627888125, + "100.0" : 0.40535863627888125 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40535863627888125, + 0.40492615224521195, + 0.4053466418061692 + ], + [ + 0.40228115471257897, + 0.40266728492047515, + 0.3989540114896673 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15931643362895745, + "scoreError" : 0.0014884631328600617, + "scoreConfidence" : [ + 0.1578279704960974, + 0.1608048967618175 + ], + "scorePercentiles" : { + "0.0" : 0.15845256862403345, + "50.0" : 0.1594386966503521, + "90.0" : 0.15988474033926486, + "95.0" : 0.15988474033926486, + "99.0" : 0.15988474033926486, + "99.9" : 0.15988474033926486, + "99.99" : 0.15988474033926486, + "99.999" : 0.15988474033926486, + "99.9999" : 0.15988474033926486, + "100.0" : 0.15988474033926486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15988474033926486, + 0.15966943127205377, + 0.15965528676799284 + ], + [ + 0.15845256862403345, + 0.15922210653271132, + 0.15901446823768864 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046874457952116914, + "scoreError" : 0.002718500300690323, + "scoreConfidence" : [ + 0.04415595765142659, + 0.04959295825280724 + ], + "scorePercentiles" : { + "0.0" : 0.04593866457955302, + "50.0" : 0.04688006076861495, + "90.0" : 0.04778700371297774, + "95.0" : 0.04778700371297774, + "99.0" : 0.04778700371297774, + "99.9" : 0.04778700371297774, + "99.99" : 0.04778700371297774, + "99.999" : 0.04778700371297774, + "99.9999" : 0.04778700371297774, + "100.0" : 0.04778700371297774 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04600789939592468, + 0.04593866457955302, + 0.04602340212533884 + ], + [ + 0.04775305848701615, + 0.04773671941189107, + 0.04778700371297774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8580575.32143429, + "scoreError" : 79388.17243678583, + "scoreConfidence" : [ + 8501187.148997504, + 8659963.493871074 + ], + "scorePercentiles" : { + "0.0" : 8552452.967521368, + "50.0" : 8574542.189034205, + "90.0" : 8631861.628127696, + "95.0" : 8631861.628127696, + "99.0" : 8631861.628127696, + "99.9" : 8631861.628127696, + "99.99" : 8631861.628127696, + "99.999" : 8631861.628127696, + "99.9999" : 8631861.628127696, + "100.0" : 8631861.628127696 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8571343.172236504, + 8577741.205831904, + 8552452.967521368 + ], + [ + 8631861.628127696, + 8589714.06609442, + 8560338.888793841 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-24T02:09:57Z-01b880b701b2006782daf6e18da00714e889c7ef-jdk17.json b/performance-results/2025-10-24T02:09:57Z-01b880b701b2006782daf6e18da00714e889c7ef-jdk17.json new file mode 100644 index 0000000000..483f054d9b --- /dev/null +++ b/performance-results/2025-10-24T02:09:57Z-01b880b701b2006782daf6e18da00714e889c7ef-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3210369125033576, + "scoreError" : 0.04172593721389455, + "scoreConfidence" : [ + 3.279310975289463, + 3.362762849717252 + ], + "scorePercentiles" : { + "0.0" : 3.312460156310484, + "50.0" : 3.321867190137172, + "90.0" : 3.3279531134286016, + "95.0" : 3.3279531134286016, + "99.0" : 3.3279531134286016, + "99.9" : 3.3279531134286016, + "99.99" : 3.3279531134286016, + "99.999" : 3.3279531134286016, + "99.9999" : 3.3279531134286016, + "100.0" : 3.3279531134286016 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3207923710367173, + 3.3279531134286016 + ], + [ + 3.312460156310484, + 3.322942009237627 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6636856359533012, + "scoreError" : 0.02051861975080529, + "scoreConfidence" : [ + 1.6431670162024958, + 1.6842042557041066 + ], + "scorePercentiles" : { + "0.0" : 1.6600188652824415, + "50.0" : 1.663868808095271, + "90.0" : 1.666986062340221, + "95.0" : 1.666986062340221, + "99.0" : 1.666986062340221, + "99.9" : 1.666986062340221, + "99.99" : 1.666986062340221, + "99.999" : 1.666986062340221, + "99.9999" : 1.666986062340221, + "100.0" : 1.666986062340221 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6600188652824415, + 1.6655779112077924 + ], + [ + 1.66215970498275, + 1.666986062340221 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8450150471480917, + "scoreError" : 0.015595597201265457, + "scoreConfidence" : [ + 0.8294194499468263, + 0.8606106443493572 + ], + "scorePercentiles" : { + "0.0" : 0.8417839617612871, + "50.0" : 0.8455979320504843, + "90.0" : 0.8470803627301118, + "95.0" : 0.8470803627301118, + "99.0" : 0.8470803627301118, + "99.9" : 0.8470803627301118, + "99.99" : 0.8470803627301118, + "99.999" : 0.8470803627301118, + "99.9999" : 0.8470803627301118, + "100.0" : 0.8470803627301118 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8445759075600573, + 0.8470803627301118 + ], + [ + 0.8417839617612871, + 0.8466199565409112 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.0330502002778, + "scoreError" : 0.2526522014500542, + "scoreConfidence" : [ + 15.780397998827745, + 16.285702401727853 + ], + "scorePercentiles" : { + "0.0" : 15.875205675542759, + "50.0" : 16.05725843700849, + "90.0" : 16.117934590806474, + "95.0" : 16.117934590806474, + "99.0" : 16.117934590806474, + "99.9" : 16.117934590806474, + "99.99" : 16.117934590806474, + "99.999" : 16.117934590806474, + "99.9999" : 16.117934590806474, + "100.0" : 16.117934590806474 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.09737309293749, + 16.117934590806474, + 16.085332296640185 + ], + [ + 15.875205675542759, + 16.029184577376792, + 15.993270968363097 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2649.372942283631, + "scoreError" : 39.101747123538004, + "scoreConfidence" : [ + 2610.2711951600927, + 2688.474689407169 + ], + "scorePercentiles" : { + "0.0" : 2632.885352682765, + "50.0" : 2649.8334448692594, + "90.0" : 2667.3853176243624, + "95.0" : 2667.3853176243624, + "99.0" : 2667.3853176243624, + "99.9" : 2667.3853176243624, + "99.99" : 2667.3853176243624, + "99.999" : 2667.3853176243624, + "99.9999" : 2667.3853176243624, + "100.0" : 2667.3853176243624 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2636.34554134594, + 2642.9854540551223, + 2632.885352682765 + ], + [ + 2667.3853176243624, + 2659.9545523101983, + 2656.681435683396 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72020.95334279427, + "scoreError" : 480.03649832264887, + "scoreConfidence" : [ + 71540.91684447162, + 72500.98984111691 + ], + "scorePercentiles" : { + "0.0" : 71816.12917198088, + "50.0" : 72025.47165686978, + "90.0" : 72205.94105779473, + "95.0" : 72205.94105779473, + "99.0" : 72205.94105779473, + "99.9" : 72205.94105779473, + "99.99" : 72205.94105779473, + "99.999" : 72205.94105779473, + "99.9999" : 72205.94105779473, + "100.0" : 72205.94105779473 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 71816.12917198088, + 71873.1282681185, + 71917.54974622345 + ], + [ + 72179.57824513194, + 72205.94105779473, + 72133.39356751609 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 343.98378260632876, + "scoreError" : 6.630130206609123, + "scoreConfidence" : [ + 337.35365239971964, + 350.6139128129379 + ], + "scorePercentiles" : { + "0.0" : 340.9598935355472, + "50.0" : 343.9791877403902, + "90.0" : 347.0027757906712, + "95.0" : 347.0027757906712, + "99.0" : 347.0027757906712, + "99.9" : 347.0027757906712, + "99.99" : 347.0027757906712, + "99.999" : 347.0027757906712, + "99.9999" : 347.0027757906712, + "100.0" : 347.0027757906712 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.57465203015863, + 345.5082082469511, + 347.0027757906712 + ], + [ + 340.9598935355472, + 342.406998800815, + 342.4501672338294 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 110.87397842787352, + "scoreError" : 2.9428523185119047, + "scoreConfidence" : [ + 107.93112610936161, + 113.81683074638543 + ], + "scorePercentiles" : { + "0.0" : 109.64169676686471, + "50.0" : 110.89318100447663, + "90.0" : 111.92355117798563, + "95.0" : 111.92355117798563, + "99.0" : 111.92355117798563, + "99.9" : 111.92355117798563, + "99.99" : 111.92355117798563, + "99.999" : 111.92355117798563, + "99.9999" : 111.92355117798563, + "100.0" : 111.92355117798563 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 109.64169676686471, + 110.09758246627445, + 110.04905262601321 + ], + [ + 111.68877954267882, + 111.92355117798563, + 111.84320798742445 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06213138526714118, + "scoreError" : 2.1302783412955383E-4, + "scoreConfidence" : [ + 0.06191835743301163, + 0.062344413101270736 + ], + "scorePercentiles" : { + "0.0" : 0.06202080837762576, + "50.0" : 0.06213158856154434, + "90.0" : 0.06224537931742781, + "95.0" : 0.06224537931742781, + "99.0" : 0.06224537931742781, + "99.9" : 0.06224537931742781, + "99.99" : 0.06224537931742781, + "99.999" : 0.06224537931742781, + "99.9999" : 0.06224537931742781, + "100.0" : 0.06224537931742781 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0621116641553263, + 0.06224537931742781, + 0.06215151296776238 + ], + [ + 0.06202080837762576, + 0.0620918418418667, + 0.062167104942838135 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.829556980338355E-4, + "scoreError" : 3.057320762055153E-5, + "scoreConfidence" : [ + 3.5238249041328397E-4, + 4.1352890565438707E-4 + ], + "scorePercentiles" : { + "0.0" : 3.725302904423343E-4, + "50.0" : 3.8266317501775327E-4, + "90.0" : 3.9335144143207905E-4, + "95.0" : 3.9335144143207905E-4, + "99.0" : 3.9335144143207905E-4, + "99.9" : 3.9335144143207905E-4, + "99.99" : 3.9335144143207905E-4, + "99.999" : 3.9335144143207905E-4, + "99.9999" : 3.9335144143207905E-4, + "100.0" : 3.9335144143207905E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.932982616769802E-4, + 3.9335144143207905E-4, + 3.9203901834775274E-4 + ], + [ + 3.732278446161132E-4, + 3.732873316877538E-4, + 3.725302904423343E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.314442903550668, + "scoreError" : 0.06262821452443151, + "scoreConfidence" : [ + 2.2518146890262365, + 2.3770711180751 + ], + "scorePercentiles" : { + "0.0" : 2.2496335773729195, + "50.0" : 2.317720862411553, + "90.0" : 2.3701061520434026, + "95.0" : 2.3717347998577187, + "99.0" : 2.3717347998577187, + "99.9" : 2.3717347998577187, + "99.99" : 2.3717347998577187, + "99.999" : 2.3717347998577187, + "99.9999" : 2.3717347998577187, + "100.0" : 2.3717347998577187 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.3717347998577187, + 2.351482994827181, + 2.33543129705745, + 2.3106805311922365, + 2.324761193630869 + ], + [ + 2.355448321714555, + 2.3014212128393927, + 2.288658347826087, + 2.2496335773729195, + 2.255176759188275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013589157505479966, + "scoreError" : 6.954534819397564E-4, + "scoreConfidence" : [ + 0.01289370402354021, + 0.014284610987419722 + ], + "scorePercentiles" : { + "0.0" : 0.013359860629160706, + "50.0" : 0.013587748121937929, + "90.0" : 0.013819611469263606, + "95.0" : 0.013819611469263606, + "99.0" : 0.013819611469263606, + "99.9" : 0.013819611469263606, + "99.99" : 0.013819611469263606, + "99.999" : 0.013819611469263606, + "99.9999" : 0.013819611469263606, + "100.0" : 0.013819611469263606 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013361712180548374, + 0.013359860629160706, + 0.01336681604586289 + ], + [ + 0.013819611469263606, + 0.013818264510031243, + 0.013808680198012966 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9890004632001608, + "scoreError" : 0.022754092046625908, + "scoreConfidence" : [ + 0.9662463711535348, + 1.0117545552467866 + ], + "scorePercentiles" : { + "0.0" : 0.9807814896538197, + "50.0" : 0.9889291942160152, + "90.0" : 0.9968365565191387, + "95.0" : 0.9968365565191387, + "99.0" : 0.9968365565191387, + "99.9" : 0.9968365565191387, + "99.99" : 0.9968365565191387, + "99.999" : 0.9968365565191387, + "99.9999" : 0.9968365565191387, + "100.0" : 0.9968365565191387 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9821383520919269, + 0.9807814896538197, + 0.9819189065292097 + ], + [ + 0.9957200363401035, + 0.9968365565191387, + 0.9966074380667663 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010590792200904897, + "scoreError" : 2.0682118072503017E-4, + "scoreConfidence" : [ + 0.010383971020179867, + 0.010797613381629927 + ], + "scorePercentiles" : { + "0.0" : 0.010516604925418338, + "50.0" : 0.010595347755324749, + "90.0" : 0.010658605101488325, + "95.0" : 0.010658605101488325, + "99.0" : 0.010658605101488325, + "99.9" : 0.010658605101488325, + "99.99" : 0.010658605101488325, + "99.999" : 0.010658605101488325, + "99.9999" : 0.010658605101488325, + "100.0" : 0.010658605101488325 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010516604925418338, + 0.010520794982556989, + 0.010533577432803372 + ], + [ + 0.010657118077846124, + 0.010658605101488325, + 0.010658052685316236 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1920085519040042, + "scoreError" : 0.12860164165527976, + "scoreConfidence" : [ + 3.0634069102487245, + 3.320610193559284 + ], + "scorePercentiles" : { + "0.0" : 3.1460579157232704, + "50.0" : 3.1932998885685455, + "90.0" : 3.242655664072633, + "95.0" : 3.242655664072633, + "99.0" : 3.242655664072633, + "99.9" : 3.242655664072633, + "99.99" : 3.242655664072633, + "99.999" : 3.242655664072633, + "99.9999" : 3.242655664072633, + "100.0" : 3.242655664072633 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.147572612334802, + 3.158080148989899, + 3.1460579157232704 + ], + [ + 3.242655664072633, + 3.228519628147192, + 3.2291653421562296 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.9291783017743267, + "scoreError" : 0.10761966492112027, + "scoreConfidence" : [ + 2.8215586368532066, + 3.0367979666954468 + ], + "scorePercentiles" : { + "0.0" : 2.888735502888504, + "50.0" : 2.9270577828780393, + "90.0" : 2.9703944018414017, + "95.0" : 2.9703944018414017, + "99.0" : 2.9703944018414017, + "99.9" : 2.9703944018414017, + "99.99" : 2.9703944018414017, + "99.999" : 2.9703944018414017, + "99.9999" : 2.9703944018414017, + "100.0" : 2.9703944018414017 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9015838630693356, + 2.888735502888504, + 2.894052972800926 + ], + [ + 2.9703944018414017, + 2.9677713673590502, + 2.9525317026867435 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17664737522600174, + "scoreError" : 0.003692460381228464, + "scoreConfidence" : [ + 0.17295491484477327, + 0.18033983560723021 + ], + "scorePercentiles" : { + "0.0" : 0.17535345736379737, + "50.0" : 0.17661367730410205, + "90.0" : 0.17802446935360405, + "95.0" : 0.17802446935360405, + "99.0" : 0.17802446935360405, + "99.9" : 0.17802446935360405, + "99.99" : 0.17802446935360405, + "99.999" : 0.17802446935360405, + "99.9999" : 0.17802446935360405, + "100.0" : 0.17802446935360405 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17802446935360405, + 0.1778656540452096, + 0.17763577994884183 + ], + [ + 0.17559157465936226, + 0.17535345736379737, + 0.17541331598519533 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3301453077998189, + "scoreError" : 0.007931341498795107, + "scoreConfidence" : [ + 0.3222139663010238, + 0.338076649298614 + ], + "scorePercentiles" : { + "0.0" : 0.3273475501980425, + "50.0" : 0.3300948131157766, + "90.0" : 0.3328700934993176, + "95.0" : 0.3328700934993176, + "99.0" : 0.3328700934993176, + "99.9" : 0.3328700934993176, + "99.99" : 0.3328700934993176, + "99.999" : 0.3328700934993176, + "99.9999" : 0.3328700934993176, + "100.0" : 0.3328700934993176 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3328700934993176, + 0.33282991782600013, + 0.33246457432095483 + ], + [ + 0.3273475501980425, + 0.32763465904399963, + 0.3277250519105984 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14957535930308802, + "scoreError" : 0.002576310695993399, + "scoreConfidence" : [ + 0.14699904860709462, + 0.15215166999908142 + ], + "scorePercentiles" : { + "0.0" : 0.14857441209068759, + "50.0" : 0.14958852113247872, + "90.0" : 0.15054726929214465, + "95.0" : 0.15054726929214465, + "99.0" : 0.15054726929214465, + "99.9" : 0.15054726929214465, + "99.99" : 0.15054726929214465, + "99.999" : 0.15054726929214465, + "99.9999" : 0.15054726929214465, + "100.0" : 0.15054726929214465 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15035705778078484, + 0.15054726929214465, + 0.150315043500481 + ], + [ + 0.14879637438995358, + 0.14886199876447648, + 0.14857441209068759 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4029479850071576, + "scoreError" : 0.0336924683190746, + "scoreConfidence" : [ + 0.369255516688083, + 0.43664045332623225 + ], + "scorePercentiles" : { + "0.0" : 0.3919055269036329, + "50.0" : 0.4029302259477193, + "90.0" : 0.4139810925611624, + "95.0" : 0.4139810925611624, + "99.0" : 0.4139810925611624, + "99.9" : 0.4139810925611624, + "99.99" : 0.4139810925611624, + "99.999" : 0.4139810925611624, + "99.9999" : 0.4139810925611624, + "100.0" : 0.4139810925611624 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3919055269036329, + 0.39201086177969424, + 0.39202340695440824 + ], + [ + 0.4139299769030175, + 0.4138370449410304, + 0.4139810925611624 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15362750503700207, + "scoreError" : 0.0016445278876601435, + "scoreConfidence" : [ + 0.15198297714934192, + 0.1552720329246622 + ], + "scorePercentiles" : { + "0.0" : 0.15296614901720842, + "50.0" : 0.15365937055787976, + "90.0" : 0.15433506208716588, + "95.0" : 0.15433506208716588, + "99.0" : 0.15433506208716588, + "99.9" : 0.15433506208716588, + "99.99" : 0.15433506208716588, + "99.999" : 0.15433506208716588, + "99.9999" : 0.15433506208716588, + "100.0" : 0.15433506208716588 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15306992573317824, + 0.15329310425225337, + 0.15296614901720842 + ], + [ + 0.15407515226870042, + 0.15402563686350615, + 0.15433506208716588 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046832601695245696, + "scoreError" : 4.4133402273143716E-4, + "scoreConfidence" : [ + 0.04639126767251426, + 0.04727393571797713 + ], + "scorePercentiles" : { + "0.0" : 0.046661237833272674, + "50.0" : 0.046836549044438874, + "90.0" : 0.046983828215295856, + "95.0" : 0.046983828215295856, + "99.0" : 0.046983828215295856, + "99.9" : 0.046983828215295856, + "99.99" : 0.046983828215295856, + "99.999" : 0.046983828215295856, + "99.9999" : 0.046983828215295856, + "100.0" : 0.046983828215295856 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046710812351111235, + 0.046661237833272674, + 0.04669749980620789 + ], + [ + 0.04696228573776651, + 0.046979946227820035, + 0.046983828215295856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8909363.898800766, + "scoreError" : 206938.47181179698, + "scoreConfidence" : [ + 8702425.426988969, + 9116302.370612564 + ], + "scorePercentiles" : { + "0.0" : 8807268.819542253, + "50.0" : 8913634.1669885, + "90.0" : 8987508.461814914, + "95.0" : 8987508.461814914, + "99.0" : 8987508.461814914, + "99.9" : 8987508.461814914, + "99.99" : 8987508.461814914, + "99.999" : 8987508.461814914, + "99.9999" : 8987508.461814914, + "100.0" : 8987508.461814914 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8987508.461814914, + 8959840.611459266, + 8973078.626008969 + ], + [ + 8867427.72251773, + 8861059.15146147, + 8807268.819542253 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-24T08:09:44Z-031fb5f2f8f918d8e57044f1b1474e5cf2fa1485-jdk17.json b/performance-results/2025-10-24T08:09:44Z-031fb5f2f8f918d8e57044f1b1474e5cf2fa1485-jdk17.json new file mode 100644 index 0000000000..b8f36dd80b --- /dev/null +++ b/performance-results/2025-10-24T08:09:44Z-031fb5f2f8f918d8e57044f1b1474e5cf2fa1485-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3474525734051666, + "scoreError" : 0.04271315127368843, + "scoreConfidence" : [ + 3.3047394221314783, + 3.390165724678855 + ], + "scorePercentiles" : { + "0.0" : 3.3406016483522656, + "50.0" : 3.3465326527210797, + "90.0" : 3.356143339826241, + "95.0" : 3.356143339826241, + "99.0" : 3.356143339826241, + "99.9" : 3.356143339826241, + "99.99" : 3.356143339826241, + "99.999" : 3.356143339826241, + "99.9999" : 3.356143339826241, + "100.0" : 3.356143339826241 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3406016483522656, + 3.356143339826241 + ], + [ + 3.344673146616353, + 3.3483921588258068 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6868907052069833, + "scoreError" : 0.017008658111480907, + "scoreConfidence" : [ + 1.6698820470955023, + 1.7038993633184643 + ], + "scorePercentiles" : { + "0.0" : 1.6837871469518557, + "50.0" : 1.6872702568111806, + "90.0" : 1.689235160253716, + "95.0" : 1.689235160253716, + "99.0" : 1.689235160253716, + "99.9" : 1.689235160253716, + "99.99" : 1.689235160253716, + "99.999" : 1.689235160253716, + "99.9999" : 1.689235160253716, + "100.0" : 1.689235160253716 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6837871469518557, + 1.689235160253716 + ], + [ + 1.6856320678713113, + 1.6889084457510501 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8472157668168813, + "scoreError" : 0.030873809850010613, + "scoreConfidence" : [ + 0.8163419569668706, + 0.8780895766668919 + ], + "scorePercentiles" : { + "0.0" : 0.8427208155376084, + "50.0" : 0.8461946693762439, + "90.0" : 0.8537529129774293, + "95.0" : 0.8537529129774293, + "99.0" : 0.8537529129774293, + "99.9" : 0.8537529129774293, + "99.99" : 0.8537529129774293, + "99.999" : 0.8537529129774293, + "99.9999" : 0.8537529129774293, + "100.0" : 0.8537529129774293 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8448799988005258, + 0.8537529129774293 + ], + [ + 0.8427208155376084, + 0.8475093399519619 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.45764984708954, + "scoreError" : 0.381515846756941, + "scoreConfidence" : [ + 16.0761340003326, + 16.839165693846482 + ], + "scorePercentiles" : { + "0.0" : 16.330631067167587, + "50.0" : 16.456527283308255, + "90.0" : 16.58924738557651, + "95.0" : 16.58924738557651, + "99.0" : 16.58924738557651, + "99.9" : 16.58924738557651, + "99.99" : 16.58924738557651, + "99.999" : 16.58924738557651, + "99.9999" : 16.58924738557651, + "100.0" : 16.58924738557651 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.330631067167587, + 16.330736771386277, + 16.33933114118232 + ], + [ + 16.57372342543419, + 16.582229291790366, + 16.58924738557651 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2768.518803928198, + "scoreError" : 95.12815903974456, + "scoreConfidence" : [ + 2673.3906448884536, + 2863.6469629679423 + ], + "scorePercentiles" : { + "0.0" : 2734.6587420539886, + "50.0" : 2769.3846544570397, + "90.0" : 2802.9517895999143, + "95.0" : 2802.9517895999143, + "99.0" : 2802.9517895999143, + "99.9" : 2802.9517895999143, + "99.99" : 2802.9517895999143, + "99.999" : 2802.9517895999143, + "99.9999" : 2802.9517895999143, + "100.0" : 2802.9517895999143 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2734.6587420539886, + 2736.404383414345, + 2741.994276170634 + ], + [ + 2798.3285995868596, + 2802.9517895999143, + 2796.775032743446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74205.63553165675, + "scoreError" : 460.38722592709195, + "scoreConfidence" : [ + 73745.24830572966, + 74666.02275758384 + ], + "scorePercentiles" : { + "0.0" : 73939.03791518132, + "50.0" : 74266.3543593444, + "90.0" : 74341.10318244976, + "95.0" : 74341.10318244976, + "99.0" : 74341.10318244976, + "99.9" : 74341.10318244976, + "99.99" : 74341.10318244976, + "99.999" : 74341.10318244976, + "99.9999" : 74341.10318244976, + "100.0" : 74341.10318244976 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73939.03791518132, + 74218.85829623505, + 74081.22441694753 + ], + [ + 74341.10318244976, + 74339.73895667304, + 74313.85042245376 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 360.7819038885025, + "scoreError" : 4.003600298327854, + "scoreConfidence" : [ + 356.77830359017463, + 364.78550418683034 + ], + "scorePercentiles" : { + "0.0" : 359.02367350574053, + "50.0" : 360.8458229170519, + "90.0" : 362.3021711315208, + "95.0" : 362.3021711315208, + "99.0" : 362.3021711315208, + "99.9" : 362.3021711315208, + "99.99" : 362.3021711315208, + "99.999" : 362.3021711315208, + "99.9999" : 362.3021711315208, + "100.0" : 362.3021711315208 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 359.81270414872677, + 359.68795243187725, + 359.02367350574053 + ], + [ + 361.9859804277724, + 361.878941685377, + 362.3021711315208 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.60697203041325, + "scoreError" : 5.626542349659386, + "scoreConfidence" : [ + 110.98042968075386, + 122.23351438007263 + ], + "scorePercentiles" : { + "0.0" : 114.71319134307444, + "50.0" : 116.59851319432708, + "90.0" : 118.52678317324377, + "95.0" : 118.52678317324377, + "99.0" : 118.52678317324377, + "99.9" : 118.52678317324377, + "99.99" : 118.52678317324377, + "99.999" : 118.52678317324377, + "99.9999" : 118.52678317324377, + "100.0" : 118.52678317324377 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.83536339988358, + 114.78031042485729, + 114.71319134307444 + ], + [ + 118.36166298877059, + 118.42452085264974, + 118.52678317324377 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06101120417621756, + "scoreError" : 2.1524866262934096E-4, + "scoreConfidence" : [ + 0.06079595551358822, + 0.0612264528388469 + ], + "scorePercentiles" : { + "0.0" : 0.060903018087918245, + "50.0" : 0.06099360204599541, + "90.0" : 0.061104474703035636, + "95.0" : 0.061104474703035636, + "99.0" : 0.061104474703035636, + "99.9" : 0.061104474703035636, + "99.99" : 0.061104474703035636, + "99.999" : 0.061104474703035636, + "99.9999" : 0.061104474703035636, + "100.0" : 0.061104474703035636 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0609865047233386, + 0.060903018087918245, + 0.061104474703035636 + ], + [ + 0.060976765093959974, + 0.06100069936865221, + 0.06109576308040078 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.8011075984222177E-4, + "scoreError" : 2.104885598455048E-5, + "scoreConfidence" : [ + 3.590619038576713E-4, + 4.011596158267722E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7300528079021176E-4, + "50.0" : 3.8012161320148696E-4, + "90.0" : 3.874412000415487E-4, + "95.0" : 3.874412000415487E-4, + "99.0" : 3.874412000415487E-4, + "99.9" : 3.874412000415487E-4, + "99.99" : 3.874412000415487E-4, + "99.999" : 3.874412000415487E-4, + "99.9999" : 3.874412000415487E-4, + "100.0" : 3.874412000415487E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.866517019291696E-4, + 3.8677635412697045E-4, + 3.874412000415487E-4 + ], + [ + 3.7319849769162564E-4, + 3.735915244738044E-4, + 3.7300528079021176E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.182654708021226, + "scoreError" : 0.05642952477327827, + "scoreConfidence" : [ + 2.1262251832479477, + 2.239084232794504 + ], + "scorePercentiles" : { + "0.0" : 2.1338573260081075, + "50.0" : 2.1725456195660278, + "90.0" : 2.246977753770333, + "95.0" : 2.2494558544759333, + "99.0" : 2.2494558544759333, + "99.9" : 2.2494558544759333, + "99.99" : 2.2494558544759333, + "99.999" : 2.2494558544759333, + "99.9999" : 2.2494558544759333, + "100.0" : 2.2494558544759333 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2494558544759333, + 2.200670472387239, + 2.2246748474199287, + 2.1669079947995664, + 2.1656597784755305 + ], + [ + 2.2055932304808117, + 2.168595599306158, + 2.1764956398258977, + 2.1338573260081075, + 2.1346363370330845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013668940878112617, + "scoreError" : 2.2369975428687934E-5, + "scoreConfidence" : [ + 0.013646570902683928, + 0.013691310853541305 + ], + "scorePercentiles" : { + "0.0" : 0.01365564617483354, + "50.0" : 0.01366815747229495, + "90.0" : 0.013677514691541234, + "95.0" : 0.013677514691541234, + "99.0" : 0.013677514691541234, + "99.9" : 0.013677514691541234, + "99.99" : 0.013677514691541234, + "99.999" : 0.013677514691541234, + "99.9999" : 0.013677514691541234, + "100.0" : 0.013677514691541234 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013677514691541234, + 0.013676906328085572, + 0.01365564617483354 + ], + [ + 0.013667263129625453, + 0.013668626710606169, + 0.013667688233983729 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0418822297914916, + "scoreError" : 0.22416642914069096, + "scoreConfidence" : [ + 0.8177158006508006, + 1.2660486589321827 + ], + "scorePercentiles" : { + "0.0" : 0.9684818112531474, + "50.0" : 1.041625272999146, + "90.0" : 1.115485827997769, + "95.0" : 1.115485827997769, + "99.0" : 1.115485827997769, + "99.9" : 1.115485827997769, + "99.99" : 1.115485827997769, + "99.999" : 1.115485827997769, + "99.9999" : 1.115485827997769, + "100.0" : 1.115485827997769 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1137514311170509, + 1.1153256847329096, + 1.115485827997769 + ], + [ + 0.9687495087668313, + 0.9684818112531474, + 0.969499114881241 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.0104744369113848, + "scoreError" : 9.902702598763213E-4, + "scoreConfidence" : [ + 0.009484166651508478, + 0.011464707171261121 + ], + "scorePercentiles" : { + "0.0" : 0.010150016531945387, + "50.0" : 0.010473615322279058, + "90.0" : 0.010804194996942504, + "95.0" : 0.010804194996942504, + "99.0" : 0.010804194996942504, + "99.9" : 0.010804194996942504, + "99.99" : 0.010804194996942504, + "99.999" : 0.010804194996942504, + "99.9999" : 0.010804194996942504, + "100.0" : 0.010804194996942504 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010150833869284708, + 0.0101554264785929, + 0.010150016531945387 + ], + [ + 0.010804194996942504, + 0.010794345425578077, + 0.010791804165965216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.9599213552284134, + "scoreError" : 0.12017356487660469, + "scoreConfidence" : [ + 2.839747790351809, + 3.080094920105018 + ], + "scorePercentiles" : { + "0.0" : 2.9185440624270713, + "50.0" : 2.95837221264219, + "90.0" : 3.0039103021021023, + "95.0" : 3.0039103021021023, + "99.0" : 3.0039103021021023, + "99.9" : 3.0039103021021023, + "99.99" : 3.0039103021021023, + "99.999" : 3.0039103021021023, + "99.9999" : 3.0039103021021023, + "100.0" : 3.0039103021021023 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9261447817437096, + 2.9185440624270713, + 2.918610270128355 + ], + [ + 2.9905996435406696, + 3.0039103021021023, + 3.0017190714285715 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7343163787222617, + "scoreError" : 0.01861488566180693, + "scoreConfidence" : [ + 2.715701493060455, + 2.7529312643840687 + ], + "scorePercentiles" : { + "0.0" : 2.7245300190683737, + "50.0" : 2.735662783320242, + "90.0" : 2.741873180921053, + "95.0" : 2.741873180921053, + "99.0" : 2.741873180921053, + "99.9" : 2.741873180921053, + "99.99" : 2.741873180921053, + "99.999" : 2.741873180921053, + "99.9999" : 2.741873180921053, + "100.0" : 2.741873180921053 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.733653010385351, + 2.7245300190683737, + 2.728810178396072 + ], + [ + 2.741873180921053, + 2.737672556255133, + 2.739359327307587 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18013322147568314, + "scoreError" : 0.012649604156886193, + "scoreConfidence" : [ + 0.16748361731879696, + 0.19278282563256932 + ], + "scorePercentiles" : { + "0.0" : 0.17520214846090507, + "50.0" : 0.1808590974331582, + "90.0" : 0.18454827694834555, + "95.0" : 0.18454827694834555, + "99.0" : 0.18454827694834555, + "99.9" : 0.18454827694834555, + "99.99" : 0.18454827694834555, + "99.999" : 0.18454827694834555, + "99.9999" : 0.18454827694834555, + "100.0" : 0.18454827694834555 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17520778717849883, + 0.17520214846090507, + 0.1779690553113488 + ], + [ + 0.18454827694834555, + 0.18374913955496758, + 0.18412292140003314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32560400190749145, + "scoreError" : 0.007574676886122166, + "scoreConfidence" : [ + 0.31802932502136927, + 0.3331786787936136 + ], + "scorePercentiles" : { + "0.0" : 0.32299085168916736, + "50.0" : 0.32510495034654974, + "90.0" : 0.3292063348586101, + "95.0" : 0.3292063348586101, + "99.0" : 0.3292063348586101, + "99.9" : 0.3292063348586101, + "99.99" : 0.3292063348586101, + "99.999" : 0.3292063348586101, + "99.9999" : 0.3292063348586101, + "100.0" : 0.3292063348586101 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3280138916259389, + 0.32662264555639026, + 0.3292063348586101 + ], + [ + 0.32299085168916736, + 0.3232030325781326, + 0.3235872551367093 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14713104252054773, + "scoreError" : 0.015982822334303284, + "scoreConfidence" : [ + 0.13114822018624445, + 0.16311386485485102 + ], + "scorePercentiles" : { + "0.0" : 0.14187851711026617, + "50.0" : 0.14712708715206405, + "90.0" : 0.1524288398317227, + "95.0" : 0.1524288398317227, + "99.0" : 0.1524288398317227, + "99.9" : 0.1524288398317227, + "99.99" : 0.1524288398317227, + "99.999" : 0.1524288398317227, + "99.9999" : 0.1524288398317227, + "100.0" : 0.1524288398317227 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15233782644527383, + 0.1524288398317227, + 0.15223401639518952 + ], + [ + 0.14202015790893857, + 0.14187851711026617, + 0.1418868974318956 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4080858313477824, + "scoreError" : 0.025077490827759587, + "scoreConfidence" : [ + 0.38300834052002286, + 0.433163322175542 + ], + "scorePercentiles" : { + "0.0" : 0.39792475536190364, + "50.0" : 0.40794221576411777, + "90.0" : 0.4189350280256378, + "95.0" : 0.4189350280256378, + "99.0" : 0.4189350280256378, + "99.9" : 0.4189350280256378, + "99.99" : 0.4189350280256378, + "99.999" : 0.4189350280256378, + "99.9999" : 0.4189350280256378, + "100.0" : 0.4189350280256378 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40137505823800923, + 0.40108296819476197, + 0.39792475536190364 + ], + [ + 0.4189350280256378, + 0.4145093732902263, + 0.4146878049761559 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1583688499103881, + "scoreError" : 0.005694230622413238, + "scoreConfidence" : [ + 0.15267461928797488, + 0.16406308053280133 + ], + "scorePercentiles" : { + "0.0" : 0.15542731462542742, + "50.0" : 0.15854511418215056, + "90.0" : 0.16027232819937495, + "95.0" : 0.16027232819937495, + "99.0" : 0.16027232819937495, + "99.9" : 0.16027232819937495, + "99.99" : 0.16027232819937495, + "99.999" : 0.16027232819937495, + "99.9999" : 0.16027232819937495, + "100.0" : 0.16027232819937495 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15723555223974467, + 0.15719270666645707, + 0.15542731462542742 + ], + [ + 0.15985467612455642, + 0.16027232819937495, + 0.16023052160676804 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04765522074328293, + "scoreError" : 0.0014421212788623947, + "scoreConfidence" : [ + 0.04621309946442054, + 0.04909734202214533 + ], + "scorePercentiles" : { + "0.0" : 0.047159967511919525, + "50.0" : 0.04767252795705185, + "90.0" : 0.0481306597937152, + "95.0" : 0.0481306597937152, + "99.0" : 0.0481306597937152, + "99.9" : 0.0481306597937152, + "99.99" : 0.0481306597937152, + "99.999" : 0.0481306597937152, + "99.9999" : 0.0481306597937152, + "100.0" : 0.0481306597937152 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.048125524598999964, + 0.04811635317298023, + 0.0481306597937152 + ], + [ + 0.047228702741123466, + 0.04717011664095924, + 0.047159967511919525 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8907239.858514825, + "scoreError" : 375232.46617757285, + "scoreConfidence" : [ + 8532007.392337251, + 9282472.324692398 + ], + "scorePercentiles" : { + "0.0" : 8780151.30904302, + "50.0" : 8910261.341025963, + "90.0" : 9034700.886178862, + "95.0" : 9034700.886178862, + "99.0" : 9034700.886178862, + "99.9" : 9034700.886178862, + "99.99" : 9034700.886178862, + "99.999" : 9034700.886178862, + "99.9999" : 9034700.886178862, + "100.0" : 9034700.886178862 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8794559.44288225, + 8780151.30904302, + 8780912.08428446 + ], + [ + 9025963.239169676, + 9034700.886178862, + 9027152.189530686 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-25T05:50:56Z-0269e6dbc85d1ec095f80111709462eb06c7737f-jdk17.json b/performance-results/2025-10-25T05:50:56Z-0269e6dbc85d1ec095f80111709462eb06c7737f-jdk17.json new file mode 100644 index 0000000000..94ae88597e --- /dev/null +++ b/performance-results/2025-10-25T05:50:56Z-0269e6dbc85d1ec095f80111709462eb06c7737f-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3553595256001887, + "scoreError" : 0.06388683438179214, + "scoreConfidence" : [ + 3.2914726912183965, + 3.419246359981981 + ], + "scorePercentiles" : { + "0.0" : 3.3426204828635293, + "50.0" : 3.356237832860183, + "90.0" : 3.366341953816858, + "95.0" : 3.366341953816858, + "99.0" : 3.366341953816858, + "99.9" : 3.366341953816858, + "99.99" : 3.366341953816858, + "99.999" : 3.366341953816858, + "99.9999" : 3.366341953816858, + "100.0" : 3.366341953816858 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3426204828635293, + 3.354141130603727 + ], + [ + 3.358334535116639, + 3.366341953816858 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6932745213310365, + "scoreError" : 0.00902711585640254, + "scoreConfidence" : [ + 1.684247405474634, + 1.702301637187439 + ], + "scorePercentiles" : { + "0.0" : 1.6913198406181882, + "50.0" : 1.6937057133845923, + "90.0" : 1.6943668179367728, + "95.0" : 1.6943668179367728, + "99.0" : 1.6943668179367728, + "99.9" : 1.6943668179367728, + "99.99" : 1.6943668179367728, + "99.999" : 1.6943668179367728, + "99.9999" : 1.6943668179367728, + "100.0" : 1.6943668179367728 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.694189819723356, + 1.6932216070458284 + ], + [ + 1.6913198406181882, + 1.6943668179367728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8505325872234646, + "scoreError" : 0.021813275256625273, + "scoreConfidence" : [ + 0.8287193119668393, + 0.8723458624800898 + ], + "scorePercentiles" : { + "0.0" : 0.8468304804126937, + "50.0" : 0.8501384787932513, + "90.0" : 0.8550229108946623, + "95.0" : 0.8550229108946623, + "99.0" : 0.8550229108946623, + "99.9" : 0.8550229108946623, + "99.99" : 0.8550229108946623, + "99.999" : 0.8550229108946623, + "99.9999" : 0.8550229108946623, + "100.0" : 0.8550229108946623 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8501902413456917, + 0.8550229108946623 + ], + [ + 0.8468304804126937, + 0.850086716240811 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.21121936206457, + "scoreError" : 0.5591508617011858, + "scoreConfidence" : [ + 15.652068500363383, + 16.770370223765752 + ], + "scorePercentiles" : { + "0.0" : 15.923288939989758, + "50.0" : 16.246720649195552, + "90.0" : 16.40514380086926, + "95.0" : 16.40514380086926, + "99.0" : 16.40514380086926, + "99.9" : 16.40514380086926, + "99.99" : 16.40514380086926, + "99.999" : 16.40514380086926, + "99.9999" : 16.40514380086926, + "100.0" : 16.40514380086926 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.15930492971868, + 15.923288939989758, + 16.049198614655783 + ], + [ + 16.40514380086926, + 16.396243518481512, + 16.334136368672425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2623.975367749841, + "scoreError" : 117.38269572474653, + "scoreConfidence" : [ + 2506.5926720250945, + 2741.3580634745877 + ], + "scorePercentiles" : { + "0.0" : 2578.0529564305216, + "50.0" : 2610.8889001705747, + "90.0" : 2675.2406469579296, + "95.0" : 2675.2406469579296, + "99.0" : 2675.2406469579296, + "99.9" : 2675.2406469579296, + "99.99" : 2675.2406469579296, + "99.999" : 2675.2406469579296, + "99.9999" : 2675.2406469579296, + "100.0" : 2675.2406469579296 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2674.5744912855753, + 2675.2406469579296, + 2621.7341366310566 + ], + [ + 2594.2063114838716, + 2600.0436637100925, + 2578.0529564305216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73983.72534361202, + "scoreError" : 600.8367788374738, + "scoreConfidence" : [ + 73382.88856477455, + 74584.5621224495 + ], + "scorePercentiles" : { + "0.0" : 73787.17541230674, + "50.0" : 73965.54300046922, + "90.0" : 74228.27441053223, + "95.0" : 74228.27441053223, + "99.0" : 74228.27441053223, + "99.9" : 74228.27441053223, + "99.99" : 74228.27441053223, + "99.999" : 74228.27441053223, + "99.9999" : 74228.27441053223, + "100.0" : 74228.27441053223 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74137.04272026329, + 74228.27441053223, + 74167.05937626946 + ], + [ + 73794.04328067513, + 73788.7568616253, + 73787.17541230674 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 366.5402341884121, + "scoreError" : 6.591803781870206, + "scoreConfidence" : [ + 359.9484304065419, + 373.13203797028234 + ], + "scorePercentiles" : { + "0.0" : 364.29507662489846, + "50.0" : 366.4864561823265, + "90.0" : 368.86186831418405, + "95.0" : 368.86186831418405, + "99.0" : 368.86186831418405, + "99.9" : 368.86186831418405, + "99.99" : 368.86186831418405, + "99.999" : 368.86186831418405, + "99.9999" : 368.86186831418405, + "100.0" : 368.86186831418405 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 368.3627036446187, + 368.8087026596062, + 368.86186831418405 + ], + [ + 364.29507662489846, + 364.6102087200342, + 364.3028451671309 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.43213549074261, + "scoreError" : 8.60960210358748, + "scoreConfidence" : [ + 106.82253338715513, + 124.04173759433009 + ], + "scorePercentiles" : { + "0.0" : 112.5818149183744, + "50.0" : 115.41868694216726, + "90.0" : 118.34604745711687, + "95.0" : 118.34604745711687, + "99.0" : 118.34604745711687, + "99.9" : 118.34604745711687, + "99.99" : 118.34604745711687, + "99.999" : 118.34604745711687, + "99.9999" : 118.34604745711687, + "100.0" : 118.34604745711687 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.5818149183744, + 112.62896766950055, + 112.67952638921798 + ], + [ + 118.34604745711687, + 118.15784749511653, + 118.19860901512939 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06058382837859296, + "scoreError" : 0.001218898930340094, + "scoreConfidence" : [ + 0.05936492944825287, + 0.061802727308933054 + ], + "scorePercentiles" : { + "0.0" : 0.06014271138001131, + "50.0" : 0.06047994523867374, + "90.0" : 0.06128982283252228, + "95.0" : 0.06128982283252228, + "99.0" : 0.06128982283252228, + "99.9" : 0.06128982283252228, + "99.99" : 0.06128982283252228, + "99.999" : 0.06128982283252228, + "99.9999" : 0.06128982283252228, + "100.0" : 0.06128982283252228 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06014271138001131, + 0.060223666732911775, + 0.060414588372823604 + ], + [ + 0.06054530210452388, + 0.06128982283252228, + 0.060886878848764925 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7354492431256747E-4, + "scoreError" : 3.337431688153503E-5, + "scoreConfidence" : [ + 3.4017060743103244E-4, + 4.069192411941025E-4 + ], + "scorePercentiles" : { + "0.0" : 3.613204736531253E-4, + "50.0" : 3.7420168966276603E-4, + "90.0" : 3.869323420529169E-4, + "95.0" : 3.869323420529169E-4, + "99.0" : 3.869323420529169E-4, + "99.9" : 3.869323420529169E-4, + "99.99" : 3.869323420529169E-4, + "99.999" : 3.869323420529169E-4, + "99.9999" : 3.869323420529169E-4, + "100.0" : 3.869323420529169E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.657565265037708E-4, + 3.613204736531253E-4, + 3.615129307904831E-4 + ], + [ + 3.869323420529169E-4, + 3.8310042005334767E-4, + 3.8264685282176123E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2183507574305956, + "scoreError" : 0.05865965581939143, + "scoreConfidence" : [ + 2.1596911016112044, + 2.277010413249987 + ], + "scorePercentiles" : { + "0.0" : 2.176182914273281, + "50.0" : 2.210085909771697, + "90.0" : 2.293977419221665, + "95.0" : 2.2975017169767975, + "99.0" : 2.2975017169767975, + "99.9" : 2.2975017169767975, + "99.99" : 2.2975017169767975, + "99.999" : 2.2975017169767975, + "99.9999" : 2.2975017169767975, + "100.0" : 2.2975017169767975 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2622587394254694, + 2.2975017169767975, + 2.2298677030100333, + 2.183130996944566, + 2.184415633901267 + ], + [ + 2.2361148023697743, + 2.193863247861373, + 2.210916690981432, + 2.176182914273281, + 2.2092551285619617 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013549706587438011, + "scoreError" : 2.5798092109804673E-4, + "scoreConfidence" : [ + 0.013291725666339965, + 0.013807687508536058 + ], + "scorePercentiles" : { + "0.0" : 0.013459444804845223, + "50.0" : 0.013539954841749899, + "90.0" : 0.013676991396099457, + "95.0" : 0.013676991396099457, + "99.0" : 0.013676991396099457, + "99.9" : 0.013676991396099457, + "99.99" : 0.013676991396099457, + "99.999" : 0.013676991396099457, + "99.9999" : 0.013676991396099457, + "100.0" : 0.013676991396099457 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013676991396099457, + 0.013610388848436678, + 0.013603128967973274 + ], + [ + 0.013476780715526524, + 0.013471504791746934, + 0.013459444804845223 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9700014501810363, + "scoreError" : 0.02083309811539651, + "scoreConfidence" : [ + 0.9491683520656399, + 0.9908345482964328 + ], + "scorePercentiles" : { + "0.0" : 0.9599354371280476, + "50.0" : 0.972084027889506, + "90.0" : 0.9768789005568037, + "95.0" : 0.9768789005568037, + "99.0" : 0.9768789005568037, + "99.9" : 0.9768789005568037, + "99.99" : 0.9768789005568037, + "99.999" : 0.9768789005568037, + "99.9999" : 0.9768789005568037, + "100.0" : 0.9768789005568037 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9599354371280476, + 0.9627444702541393, + 0.9684394400116201 + ], + [ + 0.9757286157673919, + 0.9762818373682155, + 0.9768789005568037 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010627361797033186, + "scoreError" : 0.0018683468522038779, + "scoreConfidence" : [ + 0.008759014944829308, + 0.012495708649237065 + ], + "scorePercentiles" : { + "0.0" : 0.010015794936561798, + "50.0" : 0.010627084950899169, + "90.0" : 0.011244179801028141, + "95.0" : 0.011244179801028141, + "99.0" : 0.011244179801028141, + "99.9" : 0.011244179801028141, + "99.99" : 0.011244179801028141, + "99.999" : 0.011244179801028141, + "99.9999" : 0.011244179801028141, + "100.0" : 0.011244179801028141 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011244179801028141, + 0.011228467308020516, + 0.011234016625888306 + ], + [ + 0.010015794936561798, + 0.010016009516922535, + 0.010025702593777821 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1027288738432133, + "scoreError" : 0.03032957037427941, + "scoreConfidence" : [ + 3.072399303468934, + 3.1330584442174927 + ], + "scorePercentiles" : { + "0.0" : 3.091941803461063, + "50.0" : 3.0985579476265706, + "90.0" : 3.117482646508728, + "95.0" : 3.117482646508728, + "99.0" : 3.117482646508728, + "99.9" : 3.117482646508728, + "99.99" : 3.117482646508728, + "99.999" : 3.117482646508728, + "99.9999" : 3.117482646508728, + "100.0" : 3.117482646508728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.095666652227723, + 3.1014492430254186, + 3.091941803461063 + ], + [ + 3.0951750068027213, + 3.114657891033624, + 3.117482646508728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6992912577710406, + "scoreError" : 0.036506395066302155, + "scoreConfidence" : [ + 2.6627848627047386, + 2.7357976528373427 + ], + "scorePercentiles" : { + "0.0" : 2.6829072583154505, + "50.0" : 2.7005371957744746, + "90.0" : 2.716617763172189, + "95.0" : 2.716617763172189, + "99.0" : 2.716617763172189, + "99.9" : 2.716617763172189, + "99.99" : 2.716617763172189, + "99.999" : 2.716617763172189, + "99.9999" : 2.716617763172189, + "100.0" : 2.716617763172189 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.6872034363245567, + 2.6953091223389922, + 2.6829072583154505 + ], + [ + 2.7057652692099565, + 2.7079446972650962, + 2.716617763172189 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1756723636494308, + "scoreError" : 0.007265169152717635, + "scoreConfidence" : [ + 0.16840719449671318, + 0.18293753280214844 + ], + "scorePercentiles" : { + "0.0" : 0.17310405667301368, + "50.0" : 0.17569230015300794, + "90.0" : 0.1782144843176391, + "95.0" : 0.1782144843176391, + "99.0" : 0.1782144843176391, + "99.9" : 0.1782144843176391, + "99.99" : 0.1782144843176391, + "99.999" : 0.1782144843176391, + "99.9999" : 0.1782144843176391, + "100.0" : 0.1782144843176391 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17327243363828534, + 0.17356523784646893, + 0.17310405667301368 + ], + [ + 0.17805860696163092, + 0.1782144843176391, + 0.17781936245954694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3219323058089911, + "scoreError" : 0.0027612036160313902, + "scoreConfidence" : [ + 0.31917110219295974, + 0.3246935094250225 + ], + "scorePercentiles" : { + "0.0" : 0.3212567948536734, + "50.0" : 0.32151928342301533, + "90.0" : 0.3237682216466475, + "95.0" : 0.3237682216466475, + "99.0" : 0.3237682216466475, + "99.9" : 0.3237682216466475, + "99.99" : 0.3237682216466475, + "99.999" : 0.3237682216466475, + "99.9999" : 0.3237682216466475, + "100.0" : 0.3237682216466475 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3212567948536734, + 0.32125868523515805, + 0.3212837483775622 + ], + [ + 0.3237682216466475, + 0.3217548184684685, + 0.32227156627243725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14456478868818165, + "scoreError" : 0.0037917956243987134, + "scoreConfidence" : [ + 0.14077299306378294, + 0.14835658431258036 + ], + "scorePercentiles" : { + "0.0" : 0.14317895041807457, + "50.0" : 0.14460385058163097, + "90.0" : 0.14582462665325108, + "95.0" : 0.14582462665325108, + "99.0" : 0.14582462665325108, + "99.9" : 0.14582462665325108, + "99.99" : 0.14582462665325108, + "99.999" : 0.14582462665325108, + "99.9999" : 0.14582462665325108, + "100.0" : 0.14582462665325108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14317895041807457, + 0.14342782809116073, + 0.14339204288786922 + ], + [ + 0.14582462665325108, + 0.14577987307210122, + 0.14578541100663314 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4005145995882278, + "scoreError" : 0.005530552924669233, + "scoreConfidence" : [ + 0.3949840466635586, + 0.4060451525128971 + ], + "scorePercentiles" : { + "0.0" : 0.398679937091373, + "50.0" : 0.4004251666239806, + "90.0" : 0.40252414260988567, + "95.0" : 0.40252414260988567, + "99.0" : 0.40252414260988567, + "99.9" : 0.40252414260988567, + "99.99" : 0.40252414260988567, + "99.999" : 0.40252414260988567, + "99.9999" : 0.40252414260988567, + "100.0" : 0.40252414260988567 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40230237509051414, + 0.4021060183755529, + 0.40252414260988567 + ], + [ + 0.3987308094896332, + 0.3987443148724083, + 0.398679937091373 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15721586362647166, + "scoreError" : 7.063322655492045E-4, + "scoreConfidence" : [ + 0.15650953136092247, + 0.15792219589202086 + ], + "scorePercentiles" : { + "0.0" : 0.15688673408427725, + "50.0" : 0.15720894857328935, + "90.0" : 0.15759771714943108, + "95.0" : 0.15759771714943108, + "99.0" : 0.15759771714943108, + "99.9" : 0.15759771714943108, + "99.99" : 0.15759771714943108, + "99.999" : 0.15759771714943108, + "99.9999" : 0.15759771714943108, + "100.0" : 0.15759771714943108 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15759771714943108, + 0.15734182524348223, + 0.15730882930896165 + ], + [ + 0.15710906783761705, + 0.15705100813506084, + 0.15688673408427725 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04579103534441176, + "scoreError" : 0.0010769215708082223, + "scoreConfidence" : [ + 0.044714113773603535, + 0.04686795691521998 + ], + "scorePercentiles" : { + "0.0" : 0.045334554359257984, + "50.0" : 0.04587706442073404, + "90.0" : 0.04630675579058503, + "95.0" : 0.04630675579058503, + "99.0" : 0.04630675579058503, + "99.9" : 0.04630675579058503, + "99.99" : 0.04630675579058503, + "99.999" : 0.04630675579058503, + "99.9999" : 0.04630675579058503, + "100.0" : 0.04630675579058503 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04630675579058503, + 0.04588999455753593, + 0.045864134283932156 + ], + [ + 0.04600795817940071, + 0.045342814895758705, + 0.045334554359257984 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8576608.991116704, + "scoreError" : 97079.22382924934, + "scoreConfidence" : [ + 8479529.767287455, + 8673688.214945953 + ], + "scorePercentiles" : { + "0.0" : 8535263.148464164, + "50.0" : 8574938.285896175, + "90.0" : 8625042.240517242, + "95.0" : 8625042.240517242, + "99.0" : 8625042.240517242, + "99.9" : 8625042.240517242, + "99.99" : 8625042.240517242, + "99.999" : 8625042.240517242, + "99.9999" : 8625042.240517242, + "100.0" : 8625042.240517242 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8549608.623931624, + 8535263.148464164, + 8556746.486740803 + ], + [ + 8625042.240517242, + 8593130.085051546, + 8599863.36199484 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-25T05:53:19Z-0269e6dbc85d1ec095f80111709462eb06c7737f-jdk17.json b/performance-results/2025-10-25T05:53:19Z-0269e6dbc85d1ec095f80111709462eb06c7737f-jdk17.json new file mode 100644 index 0000000000..76331c0bee --- /dev/null +++ b/performance-results/2025-10-25T05:53:19Z-0269e6dbc85d1ec095f80111709462eb06c7737f-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.352768079717045, + "scoreError" : 0.04264693482798888, + "scoreConfidence" : [ + 3.3101211448890564, + 3.395415014545034 + ], + "scorePercentiles" : { + "0.0" : 3.344100996591639, + "50.0" : 3.3534700904693473, + "90.0" : 3.3600311413378465, + "95.0" : 3.3600311413378465, + "99.0" : 3.3600311413378465, + "99.9" : 3.3600311413378465, + "99.99" : 3.3600311413378465, + "99.999" : 3.3600311413378465, + "99.9999" : 3.3600311413378465, + "100.0" : 3.3600311413378465 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.352518639243401, + 3.3600311413378465 + ], + [ + 3.344100996591639, + 3.354421541695294 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.681359989539579, + "scoreError" : 0.021152097488946805, + "scoreConfidence" : [ + 1.6602078920506322, + 1.7025120870285257 + ], + "scorePercentiles" : { + "0.0" : 1.6766806821496374, + "50.0" : 1.6823451114193313, + "90.0" : 1.684069053170016, + "95.0" : 1.684069053170016, + "99.0" : 1.684069053170016, + "99.9" : 1.684069053170016, + "99.99" : 1.684069053170016, + "99.999" : 1.684069053170016, + "99.9999" : 1.684069053170016, + "100.0" : 1.684069053170016 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6766806821496374, + 1.6830407446761644 + ], + [ + 1.6816494781624984, + 1.684069053170016 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8540486134924351, + "scoreError" : 0.025046997463115436, + "scoreConfidence" : [ + 0.8290016160293197, + 0.8790956109555506 + ], + "scorePercentiles" : { + "0.0" : 0.8501402349438542, + "50.0" : 0.8539655861519894, + "90.0" : 0.8581230467219072, + "95.0" : 0.8581230467219072, + "99.0" : 0.8581230467219072, + "99.9" : 0.8581230467219072, + "99.99" : 0.8581230467219072, + "99.999" : 0.8581230467219072, + "99.9999" : 0.8581230467219072, + "100.0" : 0.8581230467219072 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8501402349438542, + 0.8581230467219072 + ], + [ + 0.8565327916619959, + 0.8513983806419828 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.34183649826462, + "scoreError" : 0.39516512789592645, + "scoreConfidence" : [ + 15.946671370368692, + 16.737001626160545 + ], + "scorePercentiles" : { + "0.0" : 16.191739585013906, + "50.0" : 16.329633360332878, + "90.0" : 16.538321961038854, + "95.0" : 16.538321961038854, + "99.0" : 16.538321961038854, + "99.9" : 16.538321961038854, + "99.99" : 16.538321961038854, + "99.999" : 16.538321961038854, + "99.9999" : 16.538321961038854, + "100.0" : 16.538321961038854 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.437177951806767, + 16.538321961038854, + 16.416245985296953 + ], + [ + 16.191739585013906, + 16.224512771062443, + 16.2430207353688 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2791.789508326479, + "scoreError" : 214.06152423268296, + "scoreConfidence" : [ + 2577.727984093796, + 3005.851032559162 + ], + "scorePercentiles" : { + "0.0" : 2710.559635085139, + "50.0" : 2794.1724357095377, + "90.0" : 2863.6065705920532, + "95.0" : 2863.6065705920532, + "99.0" : 2863.6065705920532, + "99.9" : 2863.6065705920532, + "99.99" : 2863.6065705920532, + "99.999" : 2863.6065705920532, + "99.9999" : 2863.6065705920532, + "100.0" : 2863.6065705920532 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2710.559635085139, + 2728.202855790939, + 2728.332463470018 + ], + [ + 2863.6065705920532, + 2860.0124079490574, + 2860.023117071664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73893.22825198968, + "scoreError" : 547.5943937728342, + "scoreConfidence" : [ + 73345.63385821685, + 74440.82264576251 + ], + "scorePercentiles" : { + "0.0" : 73670.0739524364, + "50.0" : 73855.73534465821, + "90.0" : 74128.47536670328, + "95.0" : 74128.47536670328, + "99.0" : 74128.47536670328, + "99.9" : 74128.47536670328, + "99.99" : 74128.47536670328, + "99.999" : 74128.47536670328, + "99.9999" : 74128.47536670328, + "100.0" : 74128.47536670328 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73745.47532023405, + 73670.0739524364, + 73764.86933077312 + ], + [ + 73946.60135854331, + 74103.87418324788, + 74128.47536670328 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.09928492101216, + "scoreError" : 6.9567457516349585, + "scoreConfidence" : [ + 349.1425391693772, + 363.0560306726471 + ], + "scorePercentiles" : { + "0.0" : 351.33753106269694, + "50.0" : 356.80451622649866, + "90.0" : 358.0188896748837, + "95.0" : 358.0188896748837, + "99.0" : 358.0188896748837, + "99.9" : 358.0188896748837, + "99.99" : 358.0188896748837, + "99.999" : 358.0188896748837, + "99.9999" : 358.0188896748837, + "100.0" : 358.0188896748837 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 356.9154477297961, + 357.9035994528753, + 358.0188896748837 + ], + [ + 355.72665688261924, + 356.6935847232013, + 351.33753106269694 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.25164099813007, + "scoreError" : 1.101592828148412, + "scoreConfidence" : [ + 115.15004816998166, + 117.35323382627848 + ], + "scorePercentiles" : { + "0.0" : 115.73740074170115, + "50.0" : 116.31928447897604, + "90.0" : 116.63391251925982, + "95.0" : 116.63391251925982, + "99.0" : 116.63391251925982, + "99.9" : 116.63391251925982, + "99.99" : 116.63391251925982, + "99.999" : 116.63391251925982, + "99.9999" : 116.63391251925982, + "100.0" : 116.63391251925982 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.73740074170115, + 116.072669146283, + 115.91068754656398 + ], + [ + 116.58927622330333, + 116.5658998116691, + 116.63391251925982 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06143870021377751, + "scoreError" : 0.001956142052680842, + "scoreConfidence" : [ + 0.05948255816109667, + 0.06339484226645835 + ], + "scorePercentiles" : { + "0.0" : 0.06076186305664757, + "50.0" : 0.06146070731145759, + "90.0" : 0.06210202618178205, + "95.0" : 0.06210202618178205, + "99.0" : 0.06210202618178205, + "99.9" : 0.06210202618178205, + "99.99" : 0.06210202618178205, + "99.999" : 0.06210202618178205, + "99.9999" : 0.06210202618178205, + "100.0" : 0.06210202618178205 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06207180052263727, + 0.06204927299972078, + 0.06210202618178205 + ], + [ + 0.060872141623194403, + 0.06077509689868302, + 0.06076186305664757 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.628211296939751E-4, + "scoreError" : 7.168022562586908E-7, + "scoreConfidence" : [ + 3.621043274377164E-4, + 3.635379319502338E-4 + ], + "scorePercentiles" : { + "0.0" : 3.624866944966299E-4, + "50.0" : 3.6280004100307207E-4, + "90.0" : 3.632627909243302E-4, + "95.0" : 3.632627909243302E-4, + "99.0" : 3.632627909243302E-4, + "99.9" : 3.632627909243302E-4, + "99.99" : 3.632627909243302E-4, + "99.999" : 3.632627909243302E-4, + "99.9999" : 3.632627909243302E-4, + "100.0" : 3.632627909243302E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6284127395572684E-4, + 3.627067905436995E-4, + 3.632627909243302E-4 + ], + [ + 3.6287042019304697E-4, + 3.6275880805041724E-4, + 3.624866944966299E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.248039924640726, + "scoreError" : 0.08365304972189293, + "scoreConfidence" : [ + 2.1643868749188333, + 2.331692974362619 + ], + "scorePercentiles" : { + "0.0" : 2.16292664900519, + "50.0" : 2.247864890761969, + "90.0" : 2.3232531418430074, + "95.0" : 2.3258217669767443, + "99.0" : 2.3258217669767443, + "99.9" : 2.3258217669767443, + "99.99" : 2.3258217669767443, + "99.999" : 2.3258217669767443, + "99.9999" : 2.3258217669767443, + "100.0" : 2.3258217669767443 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.3258217669767443, + 2.3001355156393744, + 2.2984059715008045, + 2.247864054394246, + 2.247865727129692 + ], + [ + 2.2425950367713003, + 2.275859426490669, + 2.215373581302614, + 2.1635515171966255, + 2.16292664900519 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013531555623131962, + "scoreError" : 4.463118873289947E-4, + "scoreConfidence" : [ + 0.013085243735802967, + 0.013977867510460956 + ], + "scorePercentiles" : { + "0.0" : 0.013383061842314812, + "50.0" : 0.013528407249982315, + "90.0" : 0.013686975206464523, + "95.0" : 0.013686975206464523, + "99.0" : 0.013686975206464523, + "99.9" : 0.013686975206464523, + "99.99" : 0.013686975206464523, + "99.999" : 0.013686975206464523, + "99.9999" : 0.013686975206464523, + "100.0" : 0.013686975206464523 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013675307974225169, + 0.0136679097970341, + 0.013686975206464523 + ], + [ + 0.013388904702930528, + 0.013387174215822637, + 0.013383061842314812 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0248621880247188, + "scoreError" : 0.20183541777864986, + "scoreConfidence" : [ + 0.823026770246069, + 1.2266976058033687 + ], + "scorePercentiles" : { + "0.0" : 0.9589538909770832, + "50.0" : 1.0244934698463535, + "90.0" : 1.0910909182849662, + "95.0" : 1.0910909182849662, + "99.0" : 1.0910909182849662, + "99.9" : 1.0910909182849662, + "99.99" : 1.0910909182849662, + "99.999" : 1.0910909182849662, + "99.9999" : 1.0910909182849662, + "100.0" : 1.0910909182849662 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9589538909770832, + 0.9593017149160672, + 0.9592200523690773 + ], + [ + 1.090921326824479, + 1.0910909182849662, + 1.0896852247766398 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010819306772369272, + "scoreError" : 4.1644975375780183E-4, + "scoreConfidence" : [ + 0.01040285701861147, + 0.011235756526127074 + ], + "scorePercentiles" : { + "0.0" : 0.010682092355218295, + "50.0" : 0.01081240089970182, + "90.0" : 0.010985899056046291, + "95.0" : 0.010985899056046291, + "99.0" : 0.010985899056046291, + "99.9" : 0.010985899056046291, + "99.99" : 0.010985899056046291, + "99.999" : 0.010985899056046291, + "99.9999" : 0.010985899056046291, + "100.0" : 0.010985899056046291 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010940291148657223, + 0.01093552008249515, + 0.010985899056046291 + ], + [ + 0.010682092355218295, + 0.010682756274890183, + 0.010689281716908488 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.0281492219550645, + "scoreError" : 0.21281379774612394, + "scoreConfidence" : [ + 2.8153354242089406, + 3.2409630197011885 + ], + "scorePercentiles" : { + "0.0" : 2.952864507083825, + "50.0" : 3.0274383635991775, + "90.0" : 3.1000338195908244, + "95.0" : 3.1000338195908244, + "99.0" : 3.1000338195908244, + "99.9" : 3.1000338195908244, + "99.99" : 3.1000338195908244, + "99.999" : 3.1000338195908244, + "99.9999" : 3.1000338195908244, + "100.0" : 3.1000338195908244 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9618375938425103, + 2.9622303678909954, + 2.952864507083825 + ], + [ + 3.0992826840148697, + 3.1000338195908244, + 3.092646359307359 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.719699264036118, + "scoreError" : 0.17781555270053628, + "scoreConfidence" : [ + 2.541883711335582, + 2.8975148167366545 + ], + "scorePercentiles" : { + "0.0" : 2.6578408700504914, + "50.0" : 2.7206783482821892, + "90.0" : 2.7812192716907673, + "95.0" : 2.7812192716907673, + "99.0" : 2.7812192716907673, + "99.9" : 2.7812192716907673, + "99.99" : 2.7812192716907673, + "99.999" : 2.7812192716907673, + "99.9999" : 2.7812192716907673, + "100.0" : 2.7812192716907673 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7812192716907673, + 2.776403994447529, + 2.7748740327413985 + ], + [ + 2.6664826638229804, + 2.6613747514635446, + 2.6578408700504914 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17798650905692645, + "scoreError" : 0.002330358843276353, + "scoreConfidence" : [ + 0.1756561502136501, + 0.1803168679002028 + ], + "scorePercentiles" : { + "0.0" : 0.1770504662641857, + "50.0" : 0.17796050225724158, + "90.0" : 0.17905542981199643, + "95.0" : 0.17905542981199643, + "99.0" : 0.17905542981199643, + "99.9" : 0.17905542981199643, + "99.99" : 0.17905542981199643, + "99.999" : 0.17905542981199643, + "99.9999" : 0.17905542981199643, + "100.0" : 0.17905542981199643 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17747519282304294, + 0.1770504662641857, + 0.17725376166758247 + ], + [ + 0.178638392083311, + 0.17905542981199643, + 0.1784458116914402 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3321164150319755, + "scoreError" : 0.034066562891181866, + "scoreConfidence" : [ + 0.2980498521407936, + 0.36618297792315735 + ], + "scorePercentiles" : { + "0.0" : 0.3206518963029467, + "50.0" : 0.33216007612172277, + "90.0" : 0.34344363599835154, + "95.0" : 0.34344363599835154, + "99.0" : 0.34344363599835154, + "99.9" : 0.34344363599835154, + "99.99" : 0.34344363599835154, + "99.999" : 0.34344363599835154, + "99.9999" : 0.34344363599835154, + "100.0" : 0.34344363599835154 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3206518963029467, + 0.320868837515241, + 0.3215761660556949 + ], + [ + 0.34344363599835154, + 0.34274398618775065, + 0.34341396813186814 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14412094691175026, + "scoreError" : 0.007124005926364263, + "scoreConfidence" : [ + 0.136996940985386, + 0.1512449528381145 + ], + "scorePercentiles" : { + "0.0" : 0.14162737747312665, + "50.0" : 0.14417933512641584, + "90.0" : 0.1467884951781232, + "95.0" : 0.1467884951781232, + "99.0" : 0.1467884951781232, + "99.9" : 0.1467884951781232, + "99.99" : 0.1467884951781232, + "99.999" : 0.1467884951781232, + "99.9999" : 0.1467884951781232, + "100.0" : 0.1467884951781232 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14211552690892038, + 0.14162737747312665, + 0.14169861664352312 + ], + [ + 0.14625252192289692, + 0.1462431433439113, + 0.1467884951781232 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4074762850985379, + "scoreError" : 0.013224964845848128, + "scoreConfidence" : [ + 0.3942513202526898, + 0.420701249944386 + ], + "scorePercentiles" : { + "0.0" : 0.4026791133123943, + "50.0" : 0.4072955228941181, + "90.0" : 0.4139871829359165, + "95.0" : 0.4139871829359165, + "99.0" : 0.4139871829359165, + "99.9" : 0.4139871829359165, + "99.99" : 0.4139871829359165, + "99.999" : 0.4139871829359165, + "99.9999" : 0.4139871829359165, + "100.0" : 0.4139871829359165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4107859019470917, + 0.4139871829359165, + 0.40985034524590164 + ], + [ + 0.40474070054233446, + 0.4028144666075888, + 0.4026791133123943 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.157342276758176, + "scoreError" : 0.001745010919274208, + "scoreConfidence" : [ + 0.1555972658389018, + 0.1590872876774502 + ], + "scorePercentiles" : { + "0.0" : 0.15665487754558557, + "50.0" : 0.15738705791749386, + "90.0" : 0.15809931430920274, + "95.0" : 0.15809931430920274, + "99.0" : 0.15809931430920274, + "99.9" : 0.15809931430920274, + "99.99" : 0.15809931430920274, + "99.999" : 0.15809931430920274, + "99.9999" : 0.15809931430920274, + "100.0" : 0.15809931430920274 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1578608358458697, + 0.15809931430920274, + 0.15766840636332102 + ], + [ + 0.1571057094716667, + 0.1566645170134102, + 0.15665487754558557 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047108931074722166, + "scoreError" : 0.0025784569792767853, + "scoreConfidence" : [ + 0.04453047409544538, + 0.04968738805399895 + ], + "scorePercentiles" : { + "0.0" : 0.04625512065496427, + "50.0" : 0.047090830759458496, + "90.0" : 0.048037058839635695, + "95.0" : 0.048037058839635695, + "99.0" : 0.048037058839635695, + "99.9" : 0.048037058839635695, + "99.99" : 0.048037058839635695, + "99.999" : 0.048037058839635695, + "99.9999" : 0.048037058839635695, + "100.0" : 0.048037058839635695 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047901275605562024, + 0.047902888206017465, + 0.048037058839635695 + ], + [ + 0.04628038591335496, + 0.046276857228798575, + 0.04625512065496427 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8735155.287903985, + "scoreError" : 545987.7141178759, + "scoreConfidence" : [ + 8189167.573786109, + 9281143.00202186 + ], + "scorePercentiles" : { + "0.0" : 8536880.263651878, + "50.0" : 8738094.22370287, + "90.0" : 8919706.523172906, + "95.0" : 8919706.523172906, + "99.0" : 8919706.523172906, + "99.9" : 8919706.523172906, + "99.99" : 8919706.523172906, + "99.999" : 8919706.523172906, + "99.9999" : 8919706.523172906, + "100.0" : 8919706.523172906 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8567793.869863013, + 8568606.323630137, + 8536880.263651878 + ], + [ + 8919706.523172906, + 8907582.123775601, + 8910362.623330366 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-10-27T00:14:29Z-fce33a1fb9a54b8513f5a5e4a31c825f2a9eaff4-jdk17.json b/performance-results/2025-10-27T00:14:29Z-fce33a1fb9a54b8513f5a5e4a31c825f2a9eaff4-jdk17.json new file mode 100644 index 0000000000..63fd127812 --- /dev/null +++ b/performance-results/2025-10-27T00:14:29Z-fce33a1fb9a54b8513f5a5e4a31c825f2a9eaff4-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.318116433132777, + "scoreError" : 0.052895869285582146, + "scoreConfidence" : [ + 3.265220563847195, + 3.371012302418359 + ], + "scorePercentiles" : { + "0.0" : 3.310923570794055, + "50.0" : 3.3158300804974, + "90.0" : 3.3298820007422534, + "95.0" : 3.3298820007422534, + "99.0" : 3.3298820007422534, + "99.9" : 3.3298820007422534, + "99.99" : 3.3298820007422534, + "99.999" : 3.3298820007422534, + "99.9999" : 3.3298820007422534, + "100.0" : 3.3298820007422534 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.316275113169961, + 3.315385047824839 + ], + [ + 3.310923570794055, + 3.3298820007422534 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6719676834936277, + "scoreError" : 0.027662077333330256, + "scoreConfidence" : [ + 1.6443056061602974, + 1.699629760826958 + ], + "scorePercentiles" : { + "0.0" : 1.6678421526590803, + "50.0" : 1.6710409905704129, + "90.0" : 1.6779466001746044, + "95.0" : 1.6779466001746044, + "99.0" : 1.6779466001746044, + "99.9" : 1.6779466001746044, + "99.99" : 1.6779466001746044, + "99.999" : 1.6779466001746044, + "99.9999" : 1.6779466001746044, + "100.0" : 1.6779466001746044 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.671535541448086, + 1.6779466001746044 + ], + [ + 1.6678421526590803, + 1.6705464396927399 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8421445491293048, + "scoreError" : 0.020733550046580385, + "scoreConfidence" : [ + 0.8214109990827244, + 0.8628780991758852 + ], + "scorePercentiles" : { + "0.0" : 0.8375691044823509, + "50.0" : 0.842966617850788, + "90.0" : 0.8450758563332925, + "95.0" : 0.8450758563332925, + "99.0" : 0.8450758563332925, + "99.9" : 0.8450758563332925, + "99.99" : 0.8450758563332925, + "99.999" : 0.8450758563332925, + "99.9999" : 0.8450758563332925, + "100.0" : 0.8450758563332925 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8430182595447957, + 0.8450758563332925 + ], + [ + 0.8429149761567801, + 0.8375691044823509 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.226728646999888, + "scoreError" : 0.2437865854836192, + "scoreConfidence" : [ + 15.982942061516269, + 16.470515232483507 + ], + "scorePercentiles" : { + "0.0" : 16.127192620663525, + "50.0" : 16.22949487531681, + "90.0" : 16.31126535266114, + "95.0" : 16.31126535266114, + "99.0" : 16.31126535266114, + "99.9" : 16.31126535266114, + "99.99" : 16.31126535266114, + "99.999" : 16.31126535266114, + "99.9999" : 16.31126535266114, + "100.0" : 16.31126535266114 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.295716721778795, + 16.308615320072697, + 16.31126535266114 + ], + [ + 16.127192620663525, + 16.16327302885482, + 16.154308837968365 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2767.979382412242, + "scoreError" : 60.16236489409217, + "scoreConfidence" : [ + 2707.81701751815, + 2828.1417473063343 + ], + "scorePercentiles" : { + "0.0" : 2742.2462164985386, + "50.0" : 2768.0503583014215, + "90.0" : 2802.0461603983485, + "95.0" : 2802.0461603983485, + "99.0" : 2802.0461603983485, + "99.9" : 2802.0461603983485, + "99.99" : 2802.0461603983485, + "99.999" : 2802.0461603983485, + "99.9999" : 2802.0461603983485, + "100.0" : 2802.0461603983485 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2765.762907774518, + 2778.4443145465443, + 2770.3378088283253 + ], + [ + 2802.0461603983485, + 2742.2462164985386, + 2749.038886427176 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73793.60221919957, + "scoreError" : 1694.9332203010924, + "scoreConfidence" : [ + 72098.66899889849, + 75488.53543950066 + ], + "scorePercentiles" : { + "0.0" : 73137.66363424751, + "50.0" : 73804.1715184138, + "90.0" : 74520.04589189493, + "95.0" : 74520.04589189493, + "99.0" : 74520.04589189493, + "99.9" : 74520.04589189493, + "99.99" : 74520.04589189493, + "99.999" : 74520.04589189493, + "99.9999" : 74520.04589189493, + "100.0" : 74520.04589189493 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73137.66363424751, + 73486.83198559505, + 73172.07737631541 + ], + [ + 74323.48337591188, + 74520.04589189493, + 74121.51105123255 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 355.3533822489787, + "scoreError" : 11.140909107564008, + "scoreConfidence" : [ + 344.21247314141465, + 366.4942913565427 + ], + "scorePercentiles" : { + "0.0" : 350.0014823177603, + "50.0" : 354.1664246076142, + "90.0" : 360.81107179716184, + "95.0" : 360.81107179716184, + "99.0" : 360.81107179716184, + "99.9" : 360.81107179716184, + "99.99" : 360.81107179716184, + "99.999" : 360.81107179716184, + "99.9999" : 360.81107179716184, + "100.0" : 360.81107179716184 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.81107179716184, + 350.0014823177603, + 359.2234657881859 + ], + [ + 353.9103808668498, + 353.75142437553586, + 354.4224683483787 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.13338262280293, + "scoreError" : 2.3561485847231736, + "scoreConfidence" : [ + 109.77723403807975, + 114.4895312075261 + ], + "scorePercentiles" : { + "0.0" : 111.13231377519854, + "50.0" : 112.11209574524487, + "90.0" : 113.1994518999635, + "95.0" : 113.1994518999635, + "99.0" : 113.1994518999635, + "99.9" : 113.1994518999635, + "99.99" : 113.1994518999635, + "99.999" : 113.1994518999635, + "99.9999" : 113.1994518999635, + "100.0" : 113.1994518999635 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.60128641897656, + 111.13231377519854, + 111.463291448691 + ], + [ + 112.62290507151319, + 112.78104712247486, + 113.1994518999635 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06167465778337048, + "scoreError" : 0.00296056466422145, + "scoreConfidence" : [ + 0.05871409311914903, + 0.06463522244759193 + ], + "scorePercentiles" : { + "0.0" : 0.06112820517381551, + "50.0" : 0.06120152701463895, + "90.0" : 0.06380782261810572, + "95.0" : 0.06380782261810572, + "99.0" : 0.06380782261810572, + "99.9" : 0.06380782261810572, + "99.99" : 0.06380782261810572, + "99.999" : 0.06380782261810572, + "99.9999" : 0.06380782261810572, + "100.0" : 0.06380782261810572 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06112820517381551, + 0.0611661318107308, + 0.061217291561323495 + ], + [ + 0.06154273306829301, + 0.0611857624679544, + 0.06380782261810572 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.9395152765222185E-4, + "scoreError" : 3.842493331368884E-5, + "scoreConfidence" : [ + 3.5552659433853303E-4, + 4.323764609659107E-4 + ], + "scorePercentiles" : { + "0.0" : 3.791762182405829E-4, + "50.0" : 3.916302999459161E-4, + "90.0" : 4.102772299666478E-4, + "95.0" : 4.102772299666478E-4, + "99.0" : 4.102772299666478E-4, + "99.9" : 4.102772299666478E-4, + "99.99" : 4.102772299666478E-4, + "99.999" : 4.102772299666478E-4, + "99.9999" : 4.102772299666478E-4, + "100.0" : 4.102772299666478E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.998012872042821E-4, + 4.102772299666478E-4, + 4.0784452438432603E-4 + ], + [ + 3.8345931268755006E-4, + 3.8315059342994257E-4, + 3.791762182405829E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.5312022982651055, + "scoreError" : 0.3657819194495139, + "scoreConfidence" : [ + 2.1654203788155915, + 2.8969842177146194 + ], + "scorePercentiles" : { + "0.0" : 2.2720759352567015, + "50.0" : 2.484396389269522, + "90.0" : 2.81751212106385, + "95.0" : 2.8190098441375424, + "99.0" : 2.8190098441375424, + "99.9" : 2.8190098441375424, + "99.99" : 2.8190098441375424, + "99.999" : 2.8190098441375424, + "99.9999" : 2.8190098441375424, + "100.0" : 2.8190098441375424 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7978571104277328, + 2.8190098441375424, + 2.736778631463748, + 2.804032613400617, + 2.6052459283854166 + ], + [ + 2.363546850153628, + 2.310162743127743, + 2.326249732263317, + 2.2770635940346082, + 2.2720759352567015 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01354327057280267, + "scoreError" : 3.2678221540545873E-4, + "scoreConfidence" : [ + 0.013216488357397211, + 0.013870052788208128 + ], + "scorePercentiles" : { + "0.0" : 0.013425996720127382, + "50.0" : 0.013550395275020756, + "90.0" : 0.013654580711803541, + "95.0" : 0.013654580711803541, + "99.0" : 0.013654580711803541, + "99.9" : 0.013654580711803541, + "99.99" : 0.013654580711803541, + "99.999" : 0.013654580711803541, + "99.9999" : 0.013654580711803541, + "100.0" : 0.013654580711803541 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013425996720127382, + 0.0134292365893913, + 0.013456935597385086 + ], + [ + 0.013654580711803541, + 0.013643854952656425, + 0.013649018865452282 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.013825197687308, + "scoreError" : 0.0885718886545728, + "scoreConfidence" : [ + 0.9252533090327353, + 1.1023970863418808 + ], + "scorePercentiles" : { + "0.0" : 0.9840148028141297, + "50.0" : 1.0125766433496355, + "90.0" : 1.0488805943366544, + "95.0" : 1.0488805943366544, + "99.0" : 1.0488805943366544, + "99.9" : 1.0488805943366544, + "99.99" : 1.0488805943366544, + "99.999" : 1.0488805943366544, + "99.9999" : 1.0488805943366544, + "100.0" : 1.0488805943366544 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9840148028141297, + 0.9862010858889656, + 0.9853175700492611 + ], + [ + 1.0488805943366544, + 1.0389522008103054, + 1.0395849322245323 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010247405796104744, + "scoreError" : 8.816517569246826E-4, + "scoreConfidence" : [ + 0.00936575403918006, + 0.011129057553029427 + ], + "scorePercentiles" : { + "0.0" : 0.009958100972482509, + "50.0" : 0.010244378657187907, + "90.0" : 0.010546960365589992, + "95.0" : 0.010546960365589992, + "99.0" : 0.010546960365589992, + "99.9" : 0.010546960365589992, + "99.99" : 0.010546960365589992, + "99.999" : 0.010546960365589992, + "99.9999" : 0.010546960365589992, + "100.0" : 0.010546960365589992 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.009961742210613767, + 0.009958100972482509, + 0.009961556365078037 + ], + [ + 0.010529059759102108, + 0.010546960365589992, + 0.010527015103762045 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1214476061491485, + "scoreError" : 0.11936972671723725, + "scoreConfidence" : [ + 3.002077879431911, + 3.240817332866386 + ], + "scorePercentiles" : { + "0.0" : 3.055012532070861, + "50.0" : 3.1208049446080235, + "90.0" : 3.168293920835972, + "95.0" : 3.168293920835972, + "99.0" : 3.168293920835972, + "99.9" : 3.168293920835972, + "99.99" : 3.168293920835972, + "99.999" : 3.168293920835972, + "99.9999" : 3.168293920835972, + "100.0" : 3.168293920835972 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.168293920835972, + 3.0986753605947954, + 3.055012532070861 + ], + [ + 3.1650939341772153, + 3.124529297938788, + 3.117080591277259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.774418060674177, + "scoreError" : 0.2881676951223225, + "scoreConfidence" : [ + 2.4862503655518546, + 3.0625857557964995 + ], + "scorePercentiles" : { + "0.0" : 2.6759237512038525, + "50.0" : 2.766151644867291, + "90.0" : 2.8804170008640555, + "95.0" : 2.8804170008640555, + "99.0" : 2.8804170008640555, + "99.9" : 2.8804170008640555, + "99.99" : 2.8804170008640555, + "99.999" : 2.8804170008640555, + "99.9999" : 2.8804170008640555, + "100.0" : 2.8804170008640555 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8804170008640555, + 2.8754172492811962, + 2.846986312553373 + ], + [ + 2.685316977181208, + 2.682447072961373, + 2.6759237512038525 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18775865622520857, + "scoreError" : 0.02346067632710101, + "scoreConfidence" : [ + 0.16429797989810757, + 0.21121933255230957 + ], + "scorePercentiles" : { + "0.0" : 0.1799133703830308, + "50.0" : 0.1876751842039233, + "90.0" : 0.1957628340348061, + "95.0" : 0.1957628340348061, + "99.0" : 0.1957628340348061, + "99.9" : 0.1957628340348061, + "99.99" : 0.1957628340348061, + "99.999" : 0.1957628340348061, + "99.9999" : 0.1957628340348061, + "100.0" : 0.1957628340348061 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1801090709976046, + 0.18035431425840426, + 0.1799133703830308 + ], + [ + 0.19499605414944232, + 0.19541629352796341, + 0.1957628340348061 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32882556728471046, + "scoreError" : 0.012768660420702396, + "scoreConfidence" : [ + 0.31605690686400806, + 0.34159422770541287 + ], + "scorePercentiles" : { + "0.0" : 0.322700623297838, + "50.0" : 0.3300341939203026, + "90.0" : 0.33391614845732603, + "95.0" : 0.33391614845732603, + "99.0" : 0.33391614845732603, + "99.9" : 0.33391614845732603, + "99.99" : 0.33391614845732603, + "99.999" : 0.33391614845732603, + "99.9999" : 0.33391614845732603, + "100.0" : 0.33391614845732603 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3281901492238522, + 0.32428959384525585, + 0.322700623297838 + ], + [ + 0.33391614845732603, + 0.331878238616753, + 0.33197865026723766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1477876931733991, + "scoreError" : 0.009745291084649884, + "scoreConfidence" : [ + 0.1380424020887492, + 0.15753298425804899 + ], + "scorePercentiles" : { + "0.0" : 0.14354601085193425, + "50.0" : 0.1489091529610974, + "90.0" : 0.15101524845967987, + "95.0" : 0.15101524845967987, + "99.0" : 0.15101524845967987, + "99.9" : 0.15101524845967987, + "99.99" : 0.15101524845967987, + "99.999" : 0.15101524845967987, + "99.9999" : 0.15101524845967987, + "100.0" : 0.15101524845967987 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15043355863770383, + 0.15101524845967987, + 0.15064175519703543 + ], + [ + 0.14370483860955036, + 0.14354601085193425, + 0.14738474728449102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3986982069089043, + "scoreError" : 0.0391469628991468, + "scoreConfidence" : [ + 0.35955124400975746, + 0.4378451698080511 + ], + "scorePercentiles" : { + "0.0" : 0.38572116111239685, + "50.0" : 0.39854315509724103, + "90.0" : 0.4122581619738632, + "95.0" : 0.4122581619738632, + "99.0" : 0.4122581619738632, + "99.9" : 0.4122581619738632, + "99.99" : 0.4122581619738632, + "99.999" : 0.4122581619738632, + "99.9999" : 0.4122581619738632, + "100.0" : 0.4122581619738632 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4122581619738632, + 0.4109925693736643, + 0.41105373093838626 + ], + [ + 0.3860937408208177, + 0.3860698772342972, + 0.38572116111239685 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1591783976311689, + "scoreError" : 0.004138488725661054, + "scoreConfidence" : [ + 0.15503990890550784, + 0.16331688635682995 + ], + "scorePercentiles" : { + "0.0" : 0.15774553940436004, + "50.0" : 0.15914387254308793, + "90.0" : 0.16071820844717302, + "95.0" : 0.16071820844717302, + "99.0" : 0.16071820844717302, + "99.9" : 0.16071820844717302, + "99.99" : 0.16071820844717302, + "99.999" : 0.16071820844717302, + "99.9999" : 0.16071820844717302, + "100.0" : 0.16071820844717302 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1603960745986174, + 0.16071820844717302, + 0.16044922820331803 + ], + [ + 0.15786966464598626, + 0.15789167048755842, + 0.15774553940436004 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04602919991622715, + "scoreError" : 3.298953382579348E-4, + "scoreConfidence" : [ + 0.04569930457796922, + 0.04635909525448508 + ], + "scorePercentiles" : { + "0.0" : 0.04590731049331142, + "50.0" : 0.04603060817759103, + "90.0" : 0.046171805452824524, + "95.0" : 0.046171805452824524, + "99.0" : 0.046171805452824524, + "99.9" : 0.046171805452824524, + "99.99" : 0.046171805452824524, + "99.999" : 0.046171805452824524, + "99.9999" : 0.046171805452824524, + "100.0" : 0.046171805452824524 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046171805452824524, + 0.04612034924617322, + 0.04610980064276064 + ], + [ + 0.04590731049331142, + 0.04591451794987167, + 0.04595141571242142 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8771636.614182353, + "scoreError" : 140641.71712423506, + "scoreConfidence" : [ + 8630994.897058118, + 8912278.331306588 + ], + "scorePercentiles" : { + "0.0" : 8703980.281984335, + "50.0" : 8777784.474397104, + "90.0" : 8834836.232332155, + "95.0" : 8834836.232332155, + "99.0" : 8834836.232332155, + "99.9" : 8834836.232332155, + "99.99" : 8834836.232332155, + "99.999" : 8834836.232332155, + "99.9999" : 8834836.232332155, + "100.0" : 8834836.232332155 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8834836.232332155, + 8703980.281984335, + 8811226.884581497 + ], + [ + 8785305.287093943, + 8770263.661700264, + 8724207.337401917 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-01T00:24:50Z-472823edc35c10c3dae982746566e5ac7d1620ce-jdk17.json b/performance-results/2025-11-01T00:24:50Z-472823edc35c10c3dae982746566e5ac7d1620ce-jdk17.json new file mode 100644 index 0000000000..0aeec95322 --- /dev/null +++ b/performance-results/2025-11-01T00:24:50Z-472823edc35c10c3dae982746566e5ac7d1620ce-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3332668156780283, + "scoreError" : 0.042580806435155674, + "scoreConfidence" : [ + 3.2906860092428727, + 3.375847622113184 + ], + "scorePercentiles" : { + "0.0" : 3.323757951961249, + "50.0" : 3.3353035341388573, + "90.0" : 3.338702242473151, + "95.0" : 3.338702242473151, + "99.0" : 3.338702242473151, + "99.9" : 3.338702242473151, + "99.99" : 3.338702242473151, + "99.999" : 3.338702242473151, + "99.9999" : 3.338702242473151, + "100.0" : 3.338702242473151 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.323757951961249, + 3.3343028233945744 + ], + [ + 3.3363042448831397, + 3.338702242473151 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.68397499269957, + "scoreError" : 0.025181198641415173, + "scoreConfidence" : [ + 1.6587937940581547, + 1.7091561913409852 + ], + "scorePercentiles" : { + "0.0" : 1.679515374882242, + "50.0" : 1.6842585169310396, + "90.0" : 1.6878675620539585, + "95.0" : 1.6878675620539585, + "99.0" : 1.6878675620539585, + "99.9" : 1.6878675620539585, + "99.99" : 1.6878675620539585, + "99.999" : 1.6878675620539585, + "99.9999" : 1.6878675620539585, + "100.0" : 1.6878675620539585 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.679515374882242, + 1.6878675620539585 + ], + [ + 1.686533876335918, + 1.681983157526161 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8471424796689891, + "scoreError" : 0.016476646879735348, + "scoreConfidence" : [ + 0.8306658327892538, + 0.8636191265487245 + ], + "scorePercentiles" : { + "0.0" : 0.8454064384132701, + "50.0" : 0.8461410652649735, + "90.0" : 0.8508813497327395, + "95.0" : 0.8508813497327395, + "99.0" : 0.8508813497327395, + "99.9" : 0.8508813497327395, + "99.99" : 0.8508813497327395, + "99.999" : 0.8508813497327395, + "99.9999" : 0.8508813497327395, + "100.0" : 0.8508813497327395 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8466437947570158, + 0.845638335772931 + ], + [ + 0.8454064384132701, + 0.8508813497327395 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.345039711573794, + "scoreError" : 0.136392089430829, + "scoreConfidence" : [ + 16.208647622142966, + 16.48143180100462 + ], + "scorePercentiles" : { + "0.0" : 16.278891192259856, + "50.0" : 16.35080675673555, + "90.0" : 16.39424258416064, + "95.0" : 16.39424258416064, + "99.0" : 16.39424258416064, + "99.9" : 16.39424258416064, + "99.99" : 16.39424258416064, + "99.999" : 16.39424258416064, + "99.9999" : 16.39424258416064, + "100.0" : 16.39424258416064 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.304165922720266, + 16.32680087178319, + 16.278891192259856 + ], + [ + 16.374812641687914, + 16.39424258416064, + 16.391325056830894 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2838.419894846654, + "scoreError" : 62.64968987099645, + "scoreConfidence" : [ + 2775.7702049756576, + 2901.0695847176507 + ], + "scorePercentiles" : { + "0.0" : 2813.4609533014263, + "50.0" : 2838.782496957513, + "90.0" : 2862.8327887871246, + "95.0" : 2862.8327887871246, + "99.0" : 2862.8327887871246, + "99.9" : 2862.8327887871246, + "99.99" : 2862.8327887871246, + "99.999" : 2862.8327887871246, + "99.9999" : 2862.8327887871246, + "100.0" : 2862.8327887871246 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2819.6919321771506, + 2821.727975725238, + 2813.4609533014263 + ], + [ + 2856.9687008991946, + 2862.8327887871246, + 2855.837018189788 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 68681.17674779969, + "scoreError" : 10938.812142103745, + "scoreConfidence" : [ + 57742.36460569595, + 79619.98888990344 + ], + "scorePercentiles" : { + "0.0" : 63835.9496997512, + "50.0" : 69059.08291745286, + "90.0" : 72196.55567627141, + "95.0" : 72196.55567627141, + "99.0" : 72196.55567627141, + "99.9" : 72196.55567627141, + "99.99" : 72196.55567627141, + "99.999" : 72196.55567627141, + "99.9999" : 72196.55567627141, + "100.0" : 72196.55567627141 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72185.73562132826, + 72148.978604371, + 72196.55567627141 + ], + [ + 63835.9496997512, + 65969.18723053472, + 65750.65365454159 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 344.3073140667022, + "scoreError" : 15.899178106774404, + "scoreConfidence" : [ + 328.4081359599278, + 360.2064921734766 + ], + "scorePercentiles" : { + "0.0" : 333.14341798908714, + "50.0" : 346.31037055003674, + "90.0" : 347.94255858053504, + "95.0" : 347.94255858053504, + "99.0" : 347.94255858053504, + "99.9" : 347.94255858053504, + "99.99" : 347.94255858053504, + "99.999" : 347.94255858053504, + "99.9999" : 347.94255858053504, + "100.0" : 347.94255858053504 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 333.14341798908714, + 345.16232304727066, + 344.3335112994025 + ], + [ + 347.45841805280287, + 347.8036554311145, + 347.94255858053504 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.411176902201, + "scoreError" : 5.97825819033905, + "scoreConfidence" : [ + 109.43291871186196, + 121.38943509254005 + ], + "scorePercentiles" : { + "0.0" : 113.2650585336243, + "50.0" : 115.46814973560717, + "90.0" : 117.4515968462463, + "95.0" : 117.4515968462463, + "99.0" : 117.4515968462463, + "99.9" : 117.4515968462463, + "99.99" : 117.4515968462463, + "99.999" : 117.4515968462463, + "99.9999" : 117.4515968462463, + "100.0" : 117.4515968462463 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.2650585336243, + 113.38999281154041, + 113.7633984581368 + ], + [ + 117.4241137505806, + 117.17290101307755, + 117.4515968462463 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061465860645767485, + "scoreError" : 9.062290132979142E-4, + "scoreConfidence" : [ + 0.06055963163246957, + 0.0623720896590654 + ], + "scorePercentiles" : { + "0.0" : 0.06111634637738732, + "50.0" : 0.061464616156439646, + "90.0" : 0.061807388139312094, + "95.0" : 0.061807388139312094, + "99.0" : 0.061807388139312094, + "99.9" : 0.061807388139312094, + "99.99" : 0.061807388139312094, + "99.999" : 0.061807388139312094, + "99.9999" : 0.061807388139312094, + "100.0" : 0.061807388139312094 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06174453941714003, + 0.061807388139312094, + 0.06172326182599249 + ], + [ + 0.0611976576278862, + 0.0612059704868868, + 0.06111634637738732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.763984642247905E-4, + "scoreError" : 2.3155070012137825E-5, + "scoreConfidence" : [ + 3.532433942126527E-4, + 3.995535342369283E-4 + ], + "scorePercentiles" : { + "0.0" : 3.686848264511805E-4, + "50.0" : 3.7632877443613717E-4, + "90.0" : 3.846354969359411E-4, + "95.0" : 3.846354969359411E-4, + "99.0" : 3.846354969359411E-4, + "99.9" : 3.846354969359411E-4, + "99.99" : 3.846354969359411E-4, + "99.999" : 3.846354969359411E-4, + "99.9999" : 3.846354969359411E-4, + "100.0" : 3.846354969359411E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8355957594942824E-4, + 3.8358600288437557E-4, + 3.846354969359411E-4 + ], + [ + 3.688269102049716E-4, + 3.686848264511805E-4, + 3.6909797292284605E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.24675389279762, + "scoreError" : 0.05109200128508905, + "scoreConfidence" : [ + 2.1956618915125308, + 2.297845894082709 + ], + "scorePercentiles" : { + "0.0" : 2.201299265903588, + "50.0" : 2.248579403682282, + "90.0" : 2.3022335259096915, + "95.0" : 2.304681170046083, + "99.0" : 2.304681170046083, + "99.9" : 2.304681170046083, + "99.99" : 2.304681170046083, + "99.999" : 2.304681170046083, + "99.9999" : 2.304681170046083, + "100.0" : 2.304681170046083 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2802047286821705, + 2.250621548379838, + 2.2594129909624945, + 2.202413606254129, + 2.201299265903588 + ], + [ + 2.304681170046083, + 2.246537258984726, + 2.2719469770558836, + 2.221115097712636, + 2.22930628399465 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013513792954655638, + "scoreError" : 1.9845516318258937E-4, + "scoreConfidence" : [ + 0.013315337791473049, + 0.013712248117838227 + ], + "scorePercentiles" : { + "0.0" : 0.01344380711867779, + "50.0" : 0.01351694006709887, + "90.0" : 0.013583441678450102, + "95.0" : 0.013583441678450102, + "99.0" : 0.013583441678450102, + "99.9" : 0.013583441678450102, + "99.99" : 0.013583441678450102, + "99.999" : 0.013583441678450102, + "99.9999" : 0.013583441678450102, + "100.0" : 0.013583441678450102 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013445930553818807, + 0.01344380711867779, + 0.01345847491642397 + ], + [ + 0.013575698242789381, + 0.013575405217773772, + 0.013583441678450102 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9730092350198404, + "scoreError" : 0.009095101085314592, + "scoreConfidence" : [ + 0.9639141339345257, + 0.982104336105155 + ], + "scorePercentiles" : { + "0.0" : 0.969856518281447, + "50.0" : 0.9729823274658758, + "90.0" : 0.9761461142020498, + "95.0" : 0.9761461142020498, + "99.0" : 0.9761461142020498, + "99.9" : 0.9761461142020498, + "99.99" : 0.9761461142020498, + "99.999" : 0.9761461142020498, + "99.9999" : 0.9761461142020498, + "100.0" : 0.9761461142020498 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9700346527643064, + 0.969856518281447, + 0.9702710868341904 + ], + [ + 0.9761461142020498, + 0.9760534699394886, + 0.975693568097561 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010776690458907804, + "scoreError" : 5.493932674132044E-5, + "scoreConfidence" : [ + 0.010721751132166484, + 0.010831629785649124 + ], + "scorePercentiles" : { + "0.0" : 0.010758011244005241, + "50.0" : 0.01077492144316085, + "90.0" : 0.010803854073710753, + "95.0" : 0.010803854073710753, + "99.0" : 0.010803854073710753, + "99.9" : 0.010803854073710753, + "99.99" : 0.010803854073710753, + "99.999" : 0.010803854073710753, + "99.9999" : 0.010803854073710753, + "100.0" : 0.010803854073710753 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010758011244005241, + 0.010758450746833863, + 0.010762336185279652 + ], + [ + 0.010789983802575275, + 0.010787506701042048, + 0.010803854073710753 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1483333549644374, + "scoreError" : 0.1225780988414299, + "scoreConfidence" : [ + 3.0257552561230074, + 3.2709114538058675 + ], + "scorePercentiles" : { + "0.0" : 3.1056007492240845, + "50.0" : 3.148381890522329, + "90.0" : 3.1920120363752393, + "95.0" : 3.1920120363752393, + "99.0" : 3.1920120363752393, + "99.9" : 3.1920120363752393, + "99.99" : 3.1920120363752393, + "99.999" : 3.1920120363752393, + "99.9999" : 3.1920120363752393, + "100.0" : 3.1920120363752393 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1072272055900623, + 3.1128483883011824, + 3.1056007492240845 + ], + [ + 3.1883963575525813, + 3.1839153927434753, + 3.1920120363752393 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8612607743489176, + "scoreError" : 0.02738533701871313, + "scoreConfidence" : [ + 2.8338754373302044, + 2.8886461113676307 + ], + "scorePercentiles" : { + "0.0" : 2.851486233818078, + "50.0" : 2.858391421964061, + "90.0" : 2.8764853692838654, + "95.0" : 2.8764853692838654, + "99.0" : 2.8764853692838654, + "99.9" : 2.8764853692838654, + "99.99" : 2.8764853692838654, + "99.999" : 2.8764853692838654, + "99.9999" : 2.8764853692838654, + "100.0" : 2.8764853692838654 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8764853692838654, + 2.8588288742138364, + 2.853261363195435 + ], + [ + 2.851486233818078, + 2.869548835868006, + 2.8579539697142855 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17398553107952974, + "scoreError" : 0.00781891509952943, + "scoreConfidence" : [ + 0.16616661598000032, + 0.18180444617905916 + ], + "scorePercentiles" : { + "0.0" : 0.17142901676437314, + "50.0" : 0.1738310700618565, + "90.0" : 0.17695231535548714, + "95.0" : 0.17695231535548714, + "99.0" : 0.17695231535548714, + "99.9" : 0.17695231535548714, + "99.99" : 0.17695231535548714, + "99.999" : 0.17695231535548714, + "99.9999" : 0.17695231535548714, + "100.0" : 0.17695231535548714 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17695231535548714, + 0.17641606670077267, + 0.17619431659530982 + ], + [ + 0.17142901676437314, + 0.1714536475328327, + 0.17146782352840315 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33206001508497934, + "scoreError" : 0.01770927126785185, + "scoreConfidence" : [ + 0.31435074381712746, + 0.3497692863528312 + ], + "scorePercentiles" : { + "0.0" : 0.32610508044740105, + "50.0" : 0.3320138531253267, + "90.0" : 0.3381192184879632, + "95.0" : 0.3381192184879632, + "99.0" : 0.3381192184879632, + "99.9" : 0.3381192184879632, + "99.99" : 0.3381192184879632, + "99.999" : 0.3381192184879632, + "99.9999" : 0.3381192184879632, + "100.0" : 0.3381192184879632 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3377350236744343, + 0.33761243543432023, + 0.3381192184879632 + ], + [ + 0.3264152708163332, + 0.326373061649424, + 0.32610508044740105 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14570984196706474, + "scoreError" : 0.004519529055515116, + "scoreConfidence" : [ + 0.14119031291154963, + 0.15022937102257986 + ], + "scorePercentiles" : { + "0.0" : 0.14418146164825976, + "50.0" : 0.14572527442519906, + "90.0" : 0.14720866813872696, + "95.0" : 0.14720866813872696, + "99.0" : 0.14720866813872696, + "99.9" : 0.14720866813872696, + "99.99" : 0.14720866813872696, + "99.999" : 0.14720866813872696, + "99.9999" : 0.14720866813872696, + "100.0" : 0.14720866813872696 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1442916409113208, + 0.14424383793217846, + 0.14418146164825976 + ], + [ + 0.1471745352328251, + 0.14715890793907732, + 0.14720866813872696 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40789399450130376, + "scoreError" : 0.015523477131468538, + "scoreConfidence" : [ + 0.3923705173698352, + 0.4234174716327723 + ], + "scorePercentiles" : { + "0.0" : 0.40280403907036694, + "50.0" : 0.4078683683210663, + "90.0" : 0.4130463018049647, + "95.0" : 0.4130463018049647, + "99.0" : 0.4130463018049647, + "99.9" : 0.4130463018049647, + "99.99" : 0.4130463018049647, + "99.999" : 0.4130463018049647, + "99.9999" : 0.4130463018049647, + "100.0" : 0.4130463018049647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4028727405229022, + 0.4028456919513374, + 0.40280403907036694 + ], + [ + 0.41286399611923047, + 0.4130463018049647, + 0.4129311975390206 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15561644149062026, + "scoreError" : 0.0045629985716752084, + "scoreConfidence" : [ + 0.15105344291894504, + 0.16017944006229548 + ], + "scorePercentiles" : { + "0.0" : 0.15372625049191416, + "50.0" : 0.15569463015741808, + "90.0" : 0.15720485867668557, + "95.0" : 0.15720485867668557, + "99.0" : 0.15720485867668557, + "99.9" : 0.15720485867668557, + "99.99" : 0.15720485867668557, + "99.999" : 0.15720485867668557, + "99.9999" : 0.15720485867668557, + "100.0" : 0.15720485867668557 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.154253806540182, + 0.15372625049191416, + 0.1544698855404007 + ], + [ + 0.1569193747744355, + 0.15720485867668557, + 0.1571244729201037 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046992378970760106, + "scoreError" : 0.0034973328879974383, + "scoreConfidence" : [ + 0.04349504608276267, + 0.050489711858757544 + ], + "scorePercentiles" : { + "0.0" : 0.04582895578031768, + "50.0" : 0.04698664696846963, + "90.0" : 0.04815230945169662, + "95.0" : 0.04815230945169662, + "99.0" : 0.04815230945169662, + "99.9" : 0.04815230945169662, + "99.99" : 0.04815230945169662, + "99.999" : 0.04815230945169662, + "99.9999" : 0.04815230945169662, + "100.0" : 0.04815230945169662 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04813857737705549, + 0.04815230945169662, + 0.04810127373519707 + ], + [ + 0.04587202020174219, + 0.045861137278551546, + 0.04582895578031768 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8661823.956667257, + "scoreError" : 407197.30272051884, + "scoreConfidence" : [ + 8254626.653946739, + 9069021.259387776 + ], + "scorePercentiles" : { + "0.0" : 8518651.694207836, + "50.0" : 8660609.716732962, + "90.0" : 8804014.860915493, + "95.0" : 8804014.860915493, + "99.0" : 8804014.860915493, + "99.9" : 8804014.860915493, + "99.99" : 8804014.860915493, + "99.999" : 8804014.860915493, + "99.9999" : 8804014.860915493, + "100.0" : 8804014.860915493 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8799311.872471416, + 8804014.860915493, + 8778573.825438596 + ], + [ + 8542645.608027328, + 8527745.87894288, + 8518651.694207836 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-01T00:25:16Z-472823edc35c10c3dae982746566e5ac7d1620ce-jdk17.json b/performance-results/2025-11-01T00:25:16Z-472823edc35c10c3dae982746566e5ac7d1620ce-jdk17.json new file mode 100644 index 0000000000..904cd44ddf --- /dev/null +++ b/performance-results/2025-11-01T00:25:16Z-472823edc35c10c3dae982746566e5ac7d1620ce-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.339898881721718, + "scoreError" : 0.08348715839408095, + "scoreConfidence" : [ + 3.2564117233276373, + 3.423386040115799 + ], + "scorePercentiles" : { + "0.0" : 3.321382722492788, + "50.0" : 3.3439306512341336, + "90.0" : 3.350351501925818, + "95.0" : 3.350351501925818, + "99.0" : 3.350351501925818, + "99.9" : 3.350351501925818, + "99.99" : 3.350351501925818, + "99.999" : 3.350351501925818, + "99.9999" : 3.350351501925818, + "100.0" : 3.350351501925818 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3467716485016026, + 3.350351501925818 + ], + [ + 3.321382722492788, + 3.341089653966664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.689104011794499, + "scoreError" : 0.012970331054300923, + "scoreConfidence" : [ + 1.676133680740198, + 1.7020743428488 + ], + "scorePercentiles" : { + "0.0" : 1.68705241610597, + "50.0" : 1.6888460408196164, + "90.0" : 1.6916715494327943, + "95.0" : 1.6916715494327943, + "99.0" : 1.6916715494327943, + "99.9" : 1.6916715494327943, + "99.99" : 1.6916715494327943, + "99.999" : 1.6916715494327943, + "99.9999" : 1.6916715494327943, + "100.0" : 1.6916715494327943 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.68705241610597, + 1.688087147225704 + ], + [ + 1.6916715494327943, + 1.6896049344135289 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8506994510579455, + "scoreError" : 0.02031016368849518, + "scoreConfidence" : [ + 0.8303892873694504, + 0.8710096147464407 + ], + "scorePercentiles" : { + "0.0" : 0.8468664538092489, + "50.0" : 0.8510241503156757, + "90.0" : 0.8538830497911821, + "95.0" : 0.8538830497911821, + "99.0" : 0.8538830497911821, + "99.9" : 0.8538830497911821, + "99.99" : 0.8538830497911821, + "99.999" : 0.8538830497911821, + "99.9999" : 0.8538830497911821, + "100.0" : 0.8538830497911821 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8525403465498131, + 0.8538830497911821 + ], + [ + 0.8468664538092489, + 0.8495079540815382 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.264091804745693, + "scoreError" : 0.2657622742204209, + "scoreConfidence" : [ + 15.998329530525272, + 16.529854078966114 + ], + "scorePercentiles" : { + "0.0" : 16.17018400191614, + "50.0" : 16.23181068116692, + "90.0" : 16.42485104853266, + "95.0" : 16.42485104853266, + "99.0" : 16.42485104853266, + "99.9" : 16.42485104853266, + "99.99" : 16.42485104853266, + "99.999" : 16.42485104853266, + "99.9999" : 16.42485104853266, + "100.0" : 16.42485104853266 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.42485104853266, + 16.326053747600902, + 16.24171350429464 + ], + [ + 16.199840668090633, + 16.221907858039195, + 16.17018400191614 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2723.8352683019075, + "scoreError" : 339.89188458320183, + "scoreConfidence" : [ + 2383.9433837187057, + 3063.7271528851093 + ], + "scorePercentiles" : { + "0.0" : 2613.1500228630425, + "50.0" : 2721.84105788757, + "90.0" : 2836.640247136588, + "95.0" : 2836.640247136588, + "99.0" : 2836.640247136588, + "99.9" : 2836.640247136588, + "99.99" : 2836.640247136588, + "99.999" : 2836.640247136588, + "99.9999" : 2836.640247136588, + "100.0" : 2836.640247136588 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2613.1500228630425, + 2613.2283953037027, + 2613.238579286954 + ], + [ + 2836.3108287329715, + 2836.640247136588, + 2830.4435364881865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72721.90090956341, + "scoreError" : 7482.016668066584, + "scoreConfidence" : [ + 65239.884241496824, + 80203.91757763 + ], + "scorePercentiles" : { + "0.0" : 70038.52796328581, + "50.0" : 72745.38932586942, + "90.0" : 75262.31931483952, + "95.0" : 75262.31931483952, + "99.0" : 75262.31931483952, + "99.9" : 75262.31931483952, + "99.99" : 75262.31931483952, + "99.999" : 75262.31931483952, + "99.9999" : 75262.31931483952, + "100.0" : 75262.31931483952 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75060.14732646983, + 75138.35272163976, + 75262.31931483952 + ], + [ + 70430.631325269, + 70401.42680587654, + 70038.52796328581 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.847648883529, + "scoreError" : 21.72366914330137, + "scoreConfidence" : [ + 340.12397974022764, + 383.5713180268304 + ], + "scorePercentiles" : { + "0.0" : 354.701776728862, + "50.0" : 360.99409706732325, + "90.0" : 369.8835097424036, + "95.0" : 369.8835097424036, + "99.0" : 369.8835097424036, + "99.9" : 369.8835097424036, + "99.99" : 369.8835097424036, + "99.999" : 369.8835097424036, + "99.9999" : 369.8835097424036, + "100.0" : 369.8835097424036 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 366.9436563519826, + 369.8835097424036, + 369.7343728882811 + ], + [ + 354.7780398069808, + 354.701776728862, + 355.0445377826639 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.80510095070849, + "scoreError" : 5.090612574340337, + "scoreConfidence" : [ + 110.71448837636815, + 120.89571352504883 + ], + "scorePercentiles" : { + "0.0" : 113.8040783206789, + "50.0" : 115.97103446413846, + "90.0" : 117.52416186988886, + "95.0" : 117.52416186988886, + "99.0" : 117.52416186988886, + "99.9" : 117.52416186988886, + "99.99" : 117.52416186988886, + "99.999" : 117.52416186988886, + "99.9999" : 117.52416186988886, + "100.0" : 117.52416186988886 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 117.52416186988886, + 117.41879013533762, + 117.401387084779 + ], + [ + 113.8040783206789, + 114.14150645006876, + 114.54068184349791 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06134106325257765, + "scoreError" : 0.0026637661337922357, + "scoreConfidence" : [ + 0.058677297118785415, + 0.06400482938636988 + ], + "scorePercentiles" : { + "0.0" : 0.060407896371961534, + "50.0" : 0.06129826636624154, + "90.0" : 0.06236315404763241, + "95.0" : 0.06236315404763241, + "99.0" : 0.06236315404763241, + "99.9" : 0.06236315404763241, + "99.99" : 0.06236315404763241, + "99.999" : 0.06236315404763241, + "99.9999" : 0.06236315404763241, + "100.0" : 0.06236315404763241 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.060514218731278706, + 0.060407896371961534, + 0.06051381225870478 + ], + [ + 0.062082314001204376, + 0.06216498410468405, + 0.06236315404763241 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6394038693937365E-4, + "scoreError" : 3.811584900824561E-5, + "scoreConfidence" : [ + 3.2582453793112803E-4, + 4.0205623594761927E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5082607572869566E-4, + "50.0" : 3.638879025044674E-4, + "90.0" : 3.7707990114591326E-4, + "95.0" : 3.7707990114591326E-4, + "99.0" : 3.7707990114591326E-4, + "99.9" : 3.7707990114591326E-4, + "99.99" : 3.7707990114591326E-4, + "99.999" : 3.7707990114591326E-4, + "99.9999" : 3.7707990114591326E-4, + "100.0" : 3.7707990114591326E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5082607572869566E-4, + 3.51915902447092E-4, + 3.518873139956693E-4 + ], + [ + 3.7607322575702884E-4, + 3.758599025618428E-4, + 3.7707990114591326E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.252708664061074, + "scoreError" : 0.06676230515802696, + "scoreConfidence" : [ + 2.185946358903047, + 2.319470969219101 + ], + "scorePercentiles" : { + "0.0" : 2.1836971737991266, + "50.0" : 2.2478640335803024, + "90.0" : 2.3086575862501584, + "95.0" : 2.3096542457274825, + "99.0" : 2.3096542457274825, + "99.9" : 2.3096542457274825, + "99.99" : 2.3096542457274825, + "99.999" : 2.3096542457274825, + "99.9999" : 2.3096542457274825, + "100.0" : 2.3096542457274825 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.250790472772277, + 2.2786407486899067, + 2.231847486275385, + 2.1877154251968505, + 2.1836971737991266 + ], + [ + 2.3096542457274825, + 2.2996876509542425, + 2.295942320707071, + 2.244173522100067, + 2.2449375943883276 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013521038877782025, + "scoreError" : 2.3114037456095684E-4, + "scoreConfidence" : [ + 0.013289898503221069, + 0.013752179252342981 + ], + "scorePercentiles" : { + "0.0" : 0.013439145921414422, + "50.0" : 0.013514267078967088, + "90.0" : 0.013611825855558852, + "95.0" : 0.013611825855558852, + "99.0" : 0.013611825855558852, + "99.9" : 0.013611825855558852, + "99.99" : 0.013611825855558852, + "99.999" : 0.013611825855558852, + "99.9999" : 0.013611825855558852, + "100.0" : 0.013611825855558852 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013450893606146364, + 0.013449582548337117, + 0.013439145921414422 + ], + [ + 0.013577640551787812, + 0.013597144783447571, + 0.013611825855558852 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9957757613052959, + "scoreError" : 0.09639728441147183, + "scoreConfidence" : [ + 0.899378476893824, + 1.0921730457167678 + ], + "scorePercentiles" : { + "0.0" : 0.9635195726948647, + "50.0" : 0.9959847180209875, + "90.0" : 1.0279118206393256, + "95.0" : 1.0279118206393256, + "99.0" : 1.0279118206393256, + "99.9" : 1.0279118206393256, + "99.99" : 1.0279118206393256, + "99.999" : 1.0279118206393256, + "99.9999" : 1.0279118206393256, + "100.0" : 1.0279118206393256 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0275207903010377, + 1.025991814096645, + 1.0279118206393256 + ], + [ + 0.9635195726948647, + 0.9659776219453299, + 0.9637329481545727 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010717058836746873, + "scoreError" : 8.101079610502865E-4, + "scoreConfidence" : [ + 0.009906950875696586, + 0.01152716679779716 + ], + "scorePercentiles" : { + "0.0" : 0.010449105961247502, + "50.0" : 0.010712658068898099, + "90.0" : 0.010994778252743144, + "95.0" : 0.010994778252743144, + "99.0" : 0.010994778252743144, + "99.9" : 0.010994778252743144, + "99.99" : 0.010994778252743144, + "99.999" : 0.010994778252743144, + "99.9999" : 0.010994778252743144, + "100.0" : 0.010994778252743144 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010966512408294861, + 0.010980625330782964, + 0.010994778252743144 + ], + [ + 0.010449105961247502, + 0.010458803729501339, + 0.010452527337911428 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.032561986040744, + "scoreError" : 0.07008814334921284, + "scoreConfidence" : [ + 2.9624738426915314, + 3.1026501293899567 + ], + "scorePercentiles" : { + "0.0" : 3.0049176580528845, + "50.0" : 3.0348772528664614, + "90.0" : 3.056907945599022, + "95.0" : 3.056907945599022, + "99.0" : 3.056907945599022, + "99.9" : 3.056907945599022, + "99.99" : 3.056907945599022, + "99.999" : 3.056907945599022, + "99.9999" : 3.056907945599022, + "100.0" : 3.056907945599022 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.052451710799268, + 3.0557418772144165, + 3.056907945599022 + ], + [ + 3.0080499296452197, + 3.0049176580528845, + 3.017302794933655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.6946373979157587, + "scoreError" : 0.04118820365745651, + "scoreConfidence" : [ + 2.653449194258302, + 2.7358256015732154 + ], + "scorePercentiles" : { + "0.0" : 2.669587230912974, + "50.0" : 2.7022787700621453, + "90.0" : 2.7055171760887204, + "95.0" : 2.7055171760887204, + "99.0" : 2.7055171760887204, + "99.9" : 2.7055171760887204, + "99.99" : 2.7055171760887204, + "99.999" : 2.7055171760887204, + "99.9999" : 2.7055171760887204, + "100.0" : 2.7055171760887204 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7055171760887204, + 2.7024976357741153, + 2.702059904350176 + ], + [ + 2.6837051212771668, + 2.669587230912974, + 2.704457319091401 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17654081685676146, + "scoreError" : 0.004131968062082881, + "scoreConfidence" : [ + 0.17240884879467858, + 0.18067278491884434 + ], + "scorePercentiles" : { + "0.0" : 0.1751191878644602, + "50.0" : 0.17660002087603346, + "90.0" : 0.17790238559382338, + "95.0" : 0.17790238559382338, + "99.0" : 0.17790238559382338, + "99.9" : 0.17790238559382338, + "99.99" : 0.17790238559382338, + "99.999" : 0.17790238559382338, + "99.9999" : 0.17790238559382338, + "100.0" : 0.17790238559382338 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17786198553998292, + 0.1778877398118007, + 0.17790238559382338 + ], + [ + 0.17513554611841758, + 0.175338056212084, + 0.1751191878644602 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32369955815859175, + "scoreError" : 0.006290086193241131, + "scoreConfidence" : [ + 0.31740947196535063, + 0.32998964435183287 + ], + "scorePercentiles" : { + "0.0" : 0.3213327693197519, + "50.0" : 0.3237605855857443, + "90.0" : 0.32583304398683655, + "95.0" : 0.32583304398683655, + "99.0" : 0.32583304398683655, + "99.9" : 0.32583304398683655, + "99.99" : 0.32583304398683655, + "99.999" : 0.32583304398683655, + "99.9999" : 0.32583304398683655, + "100.0" : 0.32583304398683655 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3257978606613455, + 0.32583304398683655, + 0.3255834198274459 + ], + [ + 0.321712503812128, + 0.32193775134404273, + 0.3213327693197519 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14362765804657898, + "scoreError" : 0.009171072219787045, + "scoreConfidence" : [ + 0.13445658582679193, + 0.15279873026636603 + ], + "scorePercentiles" : { + "0.0" : 0.14063578600157506, + "50.0" : 0.1436191319340258, + "90.0" : 0.14664151525771685, + "95.0" : 0.14664151525771685, + "99.0" : 0.14664151525771685, + "99.9" : 0.14664151525771685, + "99.99" : 0.14664151525771685, + "99.999" : 0.14664151525771685, + "99.9999" : 0.14664151525771685, + "100.0" : 0.14664151525771685 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14660925247031228, + 0.14664151525771685, + 0.14658869271474642 + ], + [ + 0.14063578600157506, + 0.1406495711533052, + 0.1406411306818182 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4056662162235345, + "scoreError" : 0.006732867758196177, + "scoreConfidence" : [ + 0.3989333484653383, + 0.4123990839817307 + ], + "scorePercentiles" : { + "0.0" : 0.40316832023060795, + "50.0" : 0.40585907968151874, + "90.0" : 0.408018060750714, + "95.0" : 0.408018060750714, + "99.0" : 0.408018060750714, + "99.9" : 0.408018060750714, + "99.99" : 0.408018060750714, + "99.999" : 0.408018060750714, + "99.9999" : 0.408018060750714, + "100.0" : 0.408018060750714 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4039929088228165, + 0.4033119683000605, + 0.40316832023060795 + ], + [ + 0.4077807886967868, + 0.40772525054022096, + 0.408018060750714 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15635632073729863, + "scoreError" : 0.00492223042592804, + "scoreConfidence" : [ + 0.1514340903113706, + 0.16127855116322667 + ], + "scorePercentiles" : { + "0.0" : 0.15451648358287365, + "50.0" : 0.1563471294223619, + "90.0" : 0.1582164569819321, + "95.0" : 0.1582164569819321, + "99.0" : 0.1582164569819321, + "99.9" : 0.1582164569819321, + "99.99" : 0.1582164569819321, + "99.999" : 0.1582164569819321, + "99.9999" : 0.1582164569819321, + "100.0" : 0.1582164569819321 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15492956690473608, + 0.15451648358287365, + 0.1548484775398337 + ], + [ + 0.1582164569819321, + 0.1578622474744286, + 0.15776469193998768 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046613423181111446, + "scoreError" : 0.003349967544519245, + "scoreConfidence" : [ + 0.0432634556365922, + 0.04996339072563069 + ], + "scorePercentiles" : { + "0.0" : 0.04551597461607785, + "50.0" : 0.04661306857918751, + "90.0" : 0.04771895480595334, + "95.0" : 0.04771895480595334, + "99.0" : 0.04771895480595334, + "99.9" : 0.04771895480595334, + "99.99" : 0.04771895480595334, + "99.999" : 0.04771895480595334, + "99.9999" : 0.04771895480595334, + "100.0" : 0.04771895480595334 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04553507612902638, + 0.04551772982002567, + 0.04551597461607785 + ], + [ + 0.04771895480595334, + 0.047701742686236816, + 0.04769106102934865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8699319.35916636, + "scoreError" : 296388.9607061089, + "scoreConfidence" : [ + 8402930.39846025, + 8995708.319872469 + ], + "scorePercentiles" : { + "0.0" : 8594989.73281787, + "50.0" : 8694129.473043535, + "90.0" : 8817211.433480177, + "95.0" : 8817211.433480177, + "99.0" : 8817211.433480177, + "99.9" : 8817211.433480177, + "99.99" : 8817211.433480177, + "99.999" : 8817211.433480177, + "99.9999" : 8817211.433480177, + "100.0" : 8817211.433480177 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8594989.73281787, + 8622796.606034482, + 8595653.464776631 + ], + [ + 8817211.433480177, + 8799802.577836411, + 8765462.340052586 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-01T04:03:47Z-bb406240212aecc2dd8bd202451de0056f0a1cdc-jdk17.json b/performance-results/2025-11-01T04:03:47Z-bb406240212aecc2dd8bd202451de0056f0a1cdc-jdk17.json new file mode 100644 index 0000000000..b6f6710863 --- /dev/null +++ b/performance-results/2025-11-01T04:03:47Z-bb406240212aecc2dd8bd202451de0056f0a1cdc-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3570418103356245, + "scoreError" : 0.038696940427636134, + "scoreConfidence" : [ + 3.3183448699079885, + 3.3957387507632606 + ], + "scorePercentiles" : { + "0.0" : 3.349244441798918, + "50.0" : 3.35797427705121, + "90.0" : 3.36297424544116, + "95.0" : 3.36297424544116, + "99.0" : 3.36297424544116, + "99.9" : 3.36297424544116, + "99.99" : 3.36297424544116, + "99.999" : 3.36297424544116, + "99.9999" : 3.36297424544116, + "100.0" : 3.36297424544116 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3557549448857764, + 3.3601936092166436 + ], + [ + 3.349244441798918, + 3.36297424544116 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6925357460922603, + "scoreError" : 0.061397580117481046, + "scoreConfidence" : [ + 1.6311381659747792, + 1.7539333262097414 + ], + "scorePercentiles" : { + "0.0" : 1.6826108556937471, + "50.0" : 1.6930218676324449, + "90.0" : 1.7014883934104041, + "95.0" : 1.7014883934104041, + "99.0" : 1.7014883934104041, + "99.9" : 1.7014883934104041, + "99.99" : 1.7014883934104041, + "99.999" : 1.7014883934104041, + "99.9999" : 1.7014883934104041, + "100.0" : 1.7014883934104041 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6826108556937471, + 1.686250582215458 + ], + [ + 1.699793153049432, + 1.7014883934104041 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8524943525901215, + "scoreError" : 0.013004060386869559, + "scoreConfidence" : [ + 0.839490292203252, + 0.865498412976991 + ], + "scorePercentiles" : { + "0.0" : 0.8495812087888298, + "50.0" : 0.8531459748609425, + "90.0" : 0.8541042518497716, + "95.0" : 0.8541042518497716, + "99.0" : 0.8541042518497716, + "99.9" : 0.8541042518497716, + "99.99" : 0.8541042518497716, + "99.999" : 0.8541042518497716, + "99.9999" : 0.8541042518497716, + "100.0" : 0.8541042518497716 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8495812087888298, + 0.8534789673630445 + ], + [ + 0.8528129823588403, + 0.8541042518497716 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.47352455872438, + "scoreError" : 0.10407167849004768, + "scoreConfidence" : [ + 16.369452880234334, + 16.57759623721443 + ], + "scorePercentiles" : { + "0.0" : 16.438123713797026, + "50.0" : 16.459100757046457, + "90.0" : 16.524775076329004, + "95.0" : 16.524775076329004, + "99.0" : 16.524775076329004, + "99.9" : 16.524775076329004, + "99.99" : 16.524775076329004, + "99.999" : 16.524775076329004, + "99.9999" : 16.524775076329004, + "100.0" : 16.524775076329004 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.465686132737506, + 16.524775076329004, + 16.514806603357272 + ], + [ + 16.438123713797026, + 16.45251538135541, + 16.44524044477006 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2685.495151131999, + "scoreError" : 34.79311086621372, + "scoreConfidence" : [ + 2650.7020402657854, + 2720.288261998213 + ], + "scorePercentiles" : { + "0.0" : 2673.3276757991703, + "50.0" : 2684.6217183675044, + "90.0" : 2697.9195934598306, + "95.0" : 2697.9195934598306, + "99.0" : 2697.9195934598306, + "99.9" : 2697.9195934598306, + "99.99" : 2697.9195934598306, + "99.999" : 2697.9195934598306, + "99.9999" : 2697.9195934598306, + "100.0" : 2697.9195934598306 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2674.736558661194, + 2674.6371937962654, + 2673.3276757991703 + ], + [ + 2694.506878073815, + 2697.8430070017203, + 2697.9195934598306 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73071.31538741344, + "scoreError" : 2080.131187609566, + "scoreConfidence" : [ + 70991.18419980387, + 75151.44657502302 + ], + "scorePercentiles" : { + "0.0" : 72368.11484735468, + "50.0" : 73093.01092677476, + "90.0" : 73756.7359767164, + "95.0" : 73756.7359767164, + "99.0" : 73756.7359767164, + "99.9" : 73756.7359767164, + "99.99" : 73756.7359767164, + "99.999" : 73756.7359767164, + "99.9999" : 73756.7359767164, + "100.0" : 73756.7359767164 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73756.7359767164, + 73745.46279841148, + 73741.82802371318 + ], + [ + 72368.11484735468, + 72444.19382983632, + 72371.5568484486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 361.95722779284165, + "scoreError" : 9.008018009123036, + "scoreConfidence" : [ + 352.94920978371863, + 370.96524580196467 + ], + "scorePercentiles" : { + "0.0" : 358.7918726106224, + "50.0" : 361.9333701667848, + "90.0" : 365.1806838407644, + "95.0" : 365.1806838407644, + "99.0" : 365.1806838407644, + "99.9" : 365.1806838407644, + "99.99" : 365.1806838407644, + "99.999" : 365.1806838407644, + "99.9999" : 365.1806838407644, + "100.0" : 365.1806838407644 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 358.7918726106224, + 359.1037371439855, + 359.198512016495 + ], + [ + 364.80033282810797, + 364.6682283170747, + 365.1806838407644 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 117.50678845690676, + "scoreError" : 1.7015780182126163, + "scoreConfidence" : [ + 115.80521043869415, + 119.20836647511938 + ], + "scorePercentiles" : { + "0.0" : 116.79993396921057, + "50.0" : 117.5774675546032, + "90.0" : 118.07291846481674, + "95.0" : 118.07291846481674, + "99.0" : 118.07291846481674, + "99.9" : 118.07291846481674, + "99.99" : 118.07291846481674, + "99.999" : 118.07291846481674, + "99.9999" : 118.07291846481674, + "100.0" : 118.07291846481674 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 118.07291846481674, + 118.06302649714945, + 118.01983696126939 + ], + [ + 117.135098147937, + 116.79993396921057, + 116.94991670105742 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06033017674644498, + "scoreError" : 4.4570332830211345E-4, + "scoreConfidence" : [ + 0.05988447341814287, + 0.060775880074747095 + ], + "scorePercentiles" : { + "0.0" : 0.060186168590584635, + "50.0" : 0.060293016065657304, + "90.0" : 0.06060401705371861, + "95.0" : 0.06060401705371861, + "99.0" : 0.06060401705371861, + "99.9" : 0.06060401705371861, + "99.99" : 0.06060401705371861, + "99.999" : 0.06060401705371861, + "99.9999" : 0.06060401705371861, + "100.0" : 0.06060401705371861 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06021771590211121, + 0.060186168590584635, + 0.06021598262189064 + ], + [ + 0.06038886008116138, + 0.06060401705371861, + 0.06036831622920339 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.628476219294533E-4, + "scoreError" : 4.6784382792974576E-5, + "scoreConfidence" : [ + 3.1606323913647874E-4, + 4.096320047224279E-4 + ], + "scorePercentiles" : { + "0.0" : 3.471615489770117E-4, + "50.0" : 3.6270047532149037E-4, + "90.0" : 3.786156037265357E-4, + "95.0" : 3.786156037265357E-4, + "99.0" : 3.786156037265357E-4, + "99.9" : 3.786156037265357E-4, + "99.99" : 3.786156037265357E-4, + "99.999" : 3.786156037265357E-4, + "99.9999" : 3.786156037265357E-4, + "100.0" : 3.786156037265357E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.4769066973196585E-4, + 3.480194610979542E-4, + 3.471615489770117E-4 + ], + [ + 3.782169584982259E-4, + 3.773814895450265E-4, + 3.786156037265357E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.229249616156044, + "scoreError" : 0.09085326015117651, + "scoreConfidence" : [ + 2.138396356004867, + 2.3201028763072205 + ], + "scorePercentiles" : { + "0.0" : 2.1483050792696026, + "50.0" : 2.2316555325252514, + "90.0" : 2.3162692301086283, + "95.0" : 2.318206156235512, + "99.0" : 2.318206156235512, + "99.9" : 2.318206156235512, + "99.99" : 2.318206156235512, + "99.999" : 2.318206156235512, + "99.9999" : 2.318206156235512, + "100.0" : 2.318206156235512 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2193437157123834, + 2.186857992127706, + 2.1962009964866054, + 2.149104738719381, + 2.1483050792696026 + ], + [ + 2.318206156235512, + 2.2869233212897324, + 2.298836894966674, + 2.24396734933812, + 2.2447499174147216 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013525443455558277, + "scoreError" : 2.5011915896881268E-5, + "scoreConfidence" : [ + 0.013500431539661396, + 0.013550455371455158 + ], + "scorePercentiles" : { + "0.0" : 0.013514175606169947, + "50.0" : 0.013526590714408109, + "90.0" : 0.013537222556435762, + "95.0" : 0.013537222556435762, + "99.0" : 0.013537222556435762, + "99.9" : 0.013537222556435762, + "99.99" : 0.013537222556435762, + "99.999" : 0.013537222556435762, + "99.9999" : 0.013537222556435762, + "100.0" : 0.013537222556435762 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013523740983163161, + 0.013514175606169947, + 0.013516649212395145 + ], + [ + 0.013529440445653056, + 0.013537222556435762, + 0.013531431929532585 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0924664437566836, + "scoreError" : 0.27604402785507937, + "scoreConfidence" : [ + 0.8164224159016042, + 1.3685104716117629 + ], + "scorePercentiles" : { + "0.0" : 1.0013084754705648, + "50.0" : 1.0932055449001488, + "90.0" : 1.1827943651094026, + "95.0" : 1.1827943651094026, + "99.0" : 1.1827943651094026, + "99.9" : 1.1827943651094026, + "99.99" : 1.1827943651094026, + "99.999" : 1.1827943651094026, + "99.9999" : 1.1827943651094026, + "100.0" : 1.1827943651094026 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1822855365882492, + 1.1827943651094026, + 1.1818913233278185 + ], + [ + 1.004519766472479, + 1.0013084754705648, + 1.0019991955715861 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.009959569332811552, + "scoreError" : 7.207322938912672E-4, + "scoreConfidence" : [ + 0.009238837038920285, + 0.01068030162670282 + ], + "scorePercentiles" : { + "0.0" : 0.009723977425389824, + "50.0" : 0.009957334962364454, + "90.0" : 0.010197496561499398, + "95.0" : 0.010197496561499398, + "99.0" : 0.010197496561499398, + "99.9" : 0.010197496561499398, + "99.99" : 0.010197496561499398, + "99.999" : 0.010197496561499398, + "99.9999" : 0.010197496561499398, + "100.0" : 0.010197496561499398 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010195873301672686, + 0.010197496561499398, + 0.010189173586289813 + ], + [ + 0.009725496338439096, + 0.009725398783578504, + 0.009723977425389824 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.049996558668877, + "scoreError" : 0.30997853919162127, + "scoreConfidence" : [ + 2.740018019477256, + 3.3599750978604983 + ], + "scorePercentiles" : { + "0.0" : 2.944192894643908, + "50.0" : 3.0483202383683268, + "90.0" : 3.1613380613147912, + "95.0" : 3.1613380613147912, + "99.0" : 3.1613380613147912, + "99.9" : 3.1613380613147912, + "99.99" : 3.1613380613147912, + "99.999" : 3.1613380613147912, + "99.9999" : 3.1613380613147912, + "100.0" : 3.1613380613147912 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.140455865034526, + 3.1613380613147912, + 3.150194707178841 + ], + [ + 2.947613212139069, + 2.9561846117021275, + 2.944192894643908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7795844062815207, + "scoreError" : 0.13912714452355146, + "scoreConfidence" : [ + 2.640457261757969, + 2.9187115508050723 + ], + "scorePercentiles" : { + "0.0" : 2.7314059290005464, + "50.0" : 2.7794528740653277, + "90.0" : 2.830839760260402, + "95.0" : 2.830839760260402, + "99.0" : 2.830839760260402, + "99.9" : 2.830839760260402, + "99.99" : 2.830839760260402, + "99.999" : 2.830839760260402, + "99.9999" : 2.830839760260402, + "100.0" : 2.830839760260402 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.830839760260402, + 2.8227692593847022, + 2.8205543601240834 + ], + [ + 2.738351388006572, + 2.7314059290005464, + 2.733585740912818 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17930671254479127, + "scoreError" : 0.001332213279766144, + "scoreConfidence" : [ + 0.17797449926502512, + 0.18063892582455743 + ], + "scorePercentiles" : { + "0.0" : 0.1788006407588192, + "50.0" : 0.1792172042339652, + "90.0" : 0.18004350513088252, + "95.0" : 0.18004350513088252, + "99.0" : 0.18004350513088252, + "99.9" : 0.18004350513088252, + "99.99" : 0.18004350513088252, + "99.999" : 0.18004350513088252, + "99.9999" : 0.18004350513088252, + "100.0" : 0.18004350513088252 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17897435452348992, + 0.178969234568785, + 0.1788006407588192 + ], + [ + 0.18004350513088252, + 0.17946005394444045, + 0.1795924863423307 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3298636927699552, + "scoreError" : 0.00593593183700658, + "scoreConfidence" : [ + 0.3239277609329486, + 0.3357996246069618 + ], + "scorePercentiles" : { + "0.0" : 0.32761794027650376, + "50.0" : 0.329992924226164, + "90.0" : 0.33224702687796936, + "95.0" : 0.33224702687796936, + "99.0" : 0.33224702687796936, + "99.9" : 0.33224702687796936, + "99.99" : 0.33224702687796936, + "99.999" : 0.33224702687796936, + "99.9999" : 0.33224702687796936, + "100.0" : 0.33224702687796936 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32761794027650376, + 0.32770844281688294, + 0.3285951689613249 + ], + [ + 0.33224702687796936, + 0.33162289819604723, + 0.3313906794910031 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14397150446552284, + "scoreError" : 0.002158343904585973, + "scoreConfidence" : [ + 0.14181316056093687, + 0.1461298483701088 + ], + "scorePercentiles" : { + "0.0" : 0.14313087653861567, + "50.0" : 0.14402673570557267, + "90.0" : 0.14473396373056996, + "95.0" : 0.14473396373056996, + "99.0" : 0.14473396373056996, + "99.9" : 0.14473396373056996, + "99.99" : 0.14473396373056996, + "99.999" : 0.14473396373056996, + "99.9999" : 0.14473396373056996, + "100.0" : 0.14473396373056996 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14473396373056996, + 0.14463301132452056, + 0.14463811751688627 + ], + [ + 0.1434204600866248, + 0.14327259759591965, + 0.14313087653861567 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4027640561153735, + "scoreError" : 0.0047269496985690275, + "scoreConfidence" : [ + 0.3980371064168045, + 0.40749100581394254 + ], + "scorePercentiles" : { + "0.0" : 0.4008251837749008, + "50.0" : 0.40292732038261947, + "90.0" : 0.4044212487159785, + "95.0" : 0.4044212487159785, + "99.0" : 0.4044212487159785, + "99.9" : 0.4044212487159785, + "99.99" : 0.4044212487159785, + "99.999" : 0.4044212487159785, + "99.9999" : 0.4044212487159785, + "100.0" : 0.4044212487159785 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40126023950726264, + 0.4016508723241897, + 0.4008251837749008 + ], + [ + 0.4044212487159785, + 0.40420376844104927, + 0.40422302392886017 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15560499162846134, + "scoreError" : 0.006508857189332861, + "scoreConfidence" : [ + 0.14909613443912847, + 0.1621138488177942 + ], + "scorePercentiles" : { + "0.0" : 0.1533296514412757, + "50.0" : 0.1556761305654506, + "90.0" : 0.15782157366959157, + "95.0" : 0.15782157366959157, + "99.0" : 0.15782157366959157, + "99.9" : 0.15782157366959157, + "99.99" : 0.15782157366959157, + "99.999" : 0.15782157366959157, + "99.9999" : 0.15782157366959157, + "100.0" : 0.15782157366959157 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1533296514412757, + 0.15370897837347638, + 0.15343078905135246 + ], + [ + 0.15769567447764724, + 0.15782157366959157, + 0.1576432827574248 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04690115382714879, + "scoreError" : 0.001623051153752824, + "scoreConfidence" : [ + 0.045278102673395965, + 0.04852420498090161 + ], + "scorePercentiles" : { + "0.0" : 0.046363474875979416, + "50.0" : 0.046903627917283475, + "90.0" : 0.0474385331189131, + "95.0" : 0.0474385331189131, + "99.0" : 0.0474385331189131, + "99.9" : 0.0474385331189131, + "99.99" : 0.0474385331189131, + "99.999" : 0.0474385331189131, + "99.9999" : 0.0474385331189131, + "100.0" : 0.0474385331189131 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0463892805817136, + 0.046365904802971085, + 0.046363474875979416 + ], + [ + 0.047417975252853344, + 0.0474385331189131, + 0.04743175433046217 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8570122.92481445, + "scoreError" : 49279.656155038145, + "scoreConfidence" : [ + 8520843.268659411, + 8619402.580969488 + ], + "scorePercentiles" : { + "0.0" : 8545014.417591803, + "50.0" : 8573582.540274207, + "90.0" : 8589274.05751073, + "95.0" : 8589274.05751073, + "99.0" : 8589274.05751073, + "99.9" : 8589274.05751073, + "99.99" : 8589274.05751073, + "99.999" : 8589274.05751073, + "99.9999" : 8589274.05751073, + "100.0" : 8589274.05751073 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8572620.763496144, + 8553506.576068375, + 8545014.417591803 + ], + [ + 8585777.417167382, + 8574544.317052271, + 8589274.05751073 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-01T04:49:13Z-45620c05914d15f4c26ee00375396665caf3d881-jdk17.json b/performance-results/2025-11-01T04:49:13Z-45620c05914d15f4c26ee00375396665caf3d881-jdk17.json new file mode 100644 index 0000000000..5f68318c3f --- /dev/null +++ b/performance-results/2025-11-01T04:49:13Z-45620c05914d15f4c26ee00375396665caf3d881-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3477698621961447, + "scoreError" : 0.02337445789816345, + "scoreConfidence" : [ + 3.3243954042979813, + 3.371144320094308 + ], + "scorePercentiles" : { + "0.0" : 3.3430315008197784, + "50.0" : 3.348200788017799, + "90.0" : 3.351646371929201, + "95.0" : 3.351646371929201, + "99.0" : 3.351646371929201, + "99.9" : 3.351646371929201, + "99.99" : 3.351646371929201, + "99.999" : 3.351646371929201, + "99.9999" : 3.351646371929201, + "100.0" : 3.351646371929201 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3430315008197784, + 3.349038081692665 + ], + [ + 3.3473634943429333, + 3.351646371929201 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.684317011370639, + "scoreError" : 0.049974544199096534, + "scoreConfidence" : [ + 1.6343424671715423, + 1.7342915555697356 + ], + "scorePercentiles" : { + "0.0" : 1.6746761065881235, + "50.0" : 1.6848854242402518, + "90.0" : 1.6928210904139285, + "95.0" : 1.6928210904139285, + "99.0" : 1.6928210904139285, + "99.9" : 1.6928210904139285, + "99.99" : 1.6928210904139285, + "99.999" : 1.6928210904139285, + "99.9999" : 1.6928210904139285, + "100.0" : 1.6928210904139285 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6746761065881235, + 1.6822860147814667 + ], + [ + 1.6874848336990371, + 1.6928210904139285 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8482168370479347, + "scoreError" : 0.006544992967447337, + "scoreConfidence" : [ + 0.8416718440804873, + 0.8547618300153821 + ], + "scorePercentiles" : { + "0.0" : 0.8471017847847564, + "50.0" : 0.8482363658182547, + "90.0" : 0.8492928317704731, + "95.0" : 0.8492928317704731, + "99.0" : 0.8492928317704731, + "99.9" : 0.8492928317704731, + "99.99" : 0.8492928317704731, + "99.999" : 0.8492928317704731, + "99.9999" : 0.8492928317704731, + "100.0" : 0.8492928317704731 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8476551191081338, + 0.8492928317704731 + ], + [ + 0.8471017847847564, + 0.8488176125283755 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.332941660913594, + "scoreError" : 0.21532491358643763, + "scoreConfidence" : [ + 16.117616747327155, + 16.548266574500033 + ], + "scorePercentiles" : { + "0.0" : 16.241053712540975, + "50.0" : 16.338029469198265, + "90.0" : 16.40915551999191, + "95.0" : 16.40915551999191, + "99.0" : 16.40915551999191, + "99.9" : 16.40915551999191, + "99.99" : 16.40915551999191, + "99.999" : 16.40915551999191, + "99.9999" : 16.40915551999191, + "100.0" : 16.40915551999191 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.272271343670305, + 16.278371047966885, + 16.241053712540975 + ], + [ + 16.397687890429644, + 16.399110450881853, + 16.40915551999191 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2667.971279872579, + "scoreError" : 163.20559208081158, + "scoreConfidence" : [ + 2504.7656877917675, + 2831.1768719533907 + ], + "scorePercentiles" : { + "0.0" : 2613.502201620675, + "50.0" : 2665.880971923183, + "90.0" : 2723.8536125298388, + "95.0" : 2723.8536125298388, + "99.0" : 2723.8536125298388, + "99.9" : 2723.8536125298388, + "99.99" : 2723.8536125298388, + "99.999" : 2723.8536125298388, + "99.9999" : 2723.8536125298388, + "100.0" : 2723.8536125298388 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2723.5892246331605, + 2715.6384092563126, + 2723.8536125298388 + ], + [ + 2616.123534590053, + 2615.1206966054337, + 2613.502201620675 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74298.24183616, + "scoreError" : 2520.890311093483, + "scoreConfidence" : [ + 71777.35152506652, + 76819.13214725348 + ], + "scorePercentiles" : { + "0.0" : 73412.43293067976, + "50.0" : 74335.59546539557, + "90.0" : 75137.06253757878, + "95.0" : 75137.06253757878, + "99.0" : 75137.06253757878, + "99.9" : 75137.06253757878, + "99.99" : 75137.06253757878, + "99.999" : 75137.06253757878, + "99.9999" : 75137.06253757878, + "100.0" : 75137.06253757878 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 75137.06253757878, + 75096.45244047276, + 75118.50165482805 + ], + [ + 73574.7384903184, + 73450.26296308225, + 73412.43293067976 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 356.059297064909, + "scoreError" : 12.714796379320177, + "scoreConfidence" : [ + 343.34450068558886, + 368.77409344422915 + ], + "scorePercentiles" : { + "0.0" : 350.20785961172044, + "50.0" : 357.9517522131721, + "90.0" : 360.84132164414433, + "95.0" : 360.84132164414433, + "99.0" : 360.84132164414433, + "99.9" : 360.84132164414433, + "99.99" : 360.84132164414433, + "99.999" : 360.84132164414433, + "99.9999" : 360.84132164414433, + "100.0" : 360.84132164414433 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 358.46266281581126, + 358.8438200215719, + 360.84132164414433 + ], + [ + 350.20785961172044, + 350.559276685673, + 357.4408416105329 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.7430103926024, + "scoreError" : 1.041994337392339, + "scoreConfidence" : [ + 114.70101605521006, + 116.78500472999474 + ], + "scorePercentiles" : { + "0.0" : 115.15317263991709, + "50.0" : 115.73671697975331, + "90.0" : 116.1464559030964, + "95.0" : 116.1464559030964, + "99.0" : 116.1464559030964, + "99.9" : 116.1464559030964, + "99.99" : 116.1464559030964, + "99.999" : 116.1464559030964, + "99.9999" : 116.1464559030964, + "100.0" : 116.1464559030964 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.11771362348803, + 116.1464559030964, + 115.80129372172226 + ], + [ + 115.67214023778438, + 115.56728622960624, + 115.15317263991709 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06089329375592398, + "scoreError" : 5.288895363507938E-4, + "scoreConfidence" : [ + 0.06036440421957318, + 0.06142218329227477 + ], + "scorePercentiles" : { + "0.0" : 0.06069182257085635, + "50.0" : 0.060852542791584016, + "90.0" : 0.06113383820562667, + "95.0" : 0.06113383820562667, + "99.0" : 0.06113383820562667, + "99.9" : 0.06113383820562667, + "99.99" : 0.06113383820562667, + "99.999" : 0.06113383820562667, + "99.9999" : 0.06113383820562667, + "100.0" : 0.06113383820562667 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06075168266841629, + 0.06069182257085635, + 0.060748912164214464 + ], + [ + 0.061080104011678335, + 0.06095340291475174, + 0.06113383820562667 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.5833250066176617E-4, + "scoreError" : 2.6420738191710447E-5, + "scoreConfidence" : [ + 3.3191176247005574E-4, + 3.847532388534766E-4 + ], + "scorePercentiles" : { + "0.0" : 3.491182044597868E-4, + "50.0" : 3.584910531158554E-4, + "90.0" : 3.6700913125087254E-4, + "95.0" : 3.6700913125087254E-4, + "99.0" : 3.6700913125087254E-4, + "99.9" : 3.6700913125087254E-4, + "99.99" : 3.6700913125087254E-4, + "99.999" : 3.6700913125087254E-4, + "99.9999" : 3.6700913125087254E-4, + "100.0" : 3.6700913125087254E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6685989362878016E-4, + 3.6700913125087254E-4, + 3.6691400510862704E-4 + ], + [ + 3.491182044597868E-4, + 3.5012221260293067E-4, + 3.499715569195997E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.242600327506432, + "scoreError" : 0.053480477988934884, + "scoreConfidence" : [ + 2.189119849517497, + 2.296080805495367 + ], + "scorePercentiles" : { + "0.0" : 2.20269414030837, + "50.0" : 2.2444634133862853, + "90.0" : 2.2956833527113867, + "95.0" : 2.2964620197428833, + "99.0" : 2.2964620197428833, + "99.9" : 2.2964620197428833, + "99.99" : 2.2964620197428833, + "99.999" : 2.2964620197428833, + "99.9999" : 2.2964620197428833, + "100.0" : 2.2964620197428833 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2964620197428833, + 2.2566467624097473, + 2.267719983219955, + 2.210037549834254, + 2.2104139893922654 + ], + [ + 2.2886753494279177, + 2.2331356686760437, + 2.255791158096527, + 2.2044266539563586, + 2.20269414030837 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013424362970768317, + "scoreError" : 2.0879102880618964E-4, + "scoreConfidence" : [ + 0.013215571941962127, + 0.013633153999574507 + ], + "scorePercentiles" : { + "0.0" : 0.013355831342229084, + "50.0" : 0.013420079437107713, + "90.0" : 0.013499268325344125, + "95.0" : 0.013499268325344125, + "99.0" : 0.013499268325344125, + "99.9" : 0.013499268325344125, + "99.99" : 0.013499268325344125, + "99.999" : 0.013499268325344125, + "99.9999" : 0.013499268325344125, + "100.0" : 0.013499268325344125 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013355946686718023, + 0.013355831342229084, + 0.013357996656595043 + ], + [ + 0.013499268325344125, + 0.01348216221762038, + 0.01349497259610324 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.166441011100209, + "scoreError" : 0.03473682554077747, + "scoreConfidence" : [ + 1.1317041855594316, + 1.2011778366409864 + ], + "scorePercentiles" : { + "0.0" : 1.1547661139722865, + "50.0" : 1.1662165984028365, + "90.0" : 1.1783749528690939, + "95.0" : 1.1783749528690939, + "99.0" : 1.1783749528690939, + "99.9" : 1.1783749528690939, + "99.99" : 1.1783749528690939, + "99.999" : 1.1783749528690939, + "99.9999" : 1.1783749528690939, + "100.0" : 1.1783749528690939 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.1770702409369116, + 1.1777787901307266, + 1.1783749528690939 + ], + [ + 1.1553629558687615, + 1.1547661139722865, + 1.155293012823475 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010642173821088681, + "scoreError" : 9.457847564693583E-4, + "scoreConfidence" : [ + 0.009696389064619323, + 0.011587958577558038 + ], + "scorePercentiles" : { + "0.0" : 0.010329407786525418, + "50.0" : 0.010643935805756989, + "90.0" : 0.010956223244042728, + "95.0" : 0.010956223244042728, + "99.0" : 0.010956223244042728, + "99.9" : 0.010956223244042728, + "99.99" : 0.010956223244042728, + "99.999" : 0.010956223244042728, + "99.9999" : 0.010956223244042728, + "100.0" : 0.010956223244042728 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010956223244042728, + 0.010946212451317572, + 0.010947638304906618 + ], + [ + 0.010329407786525418, + 0.010331901979543342, + 0.010341659160196404 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.940190498434172, + "scoreError" : 0.06142933203096586, + "scoreConfidence" : [ + 2.8787611664032062, + 3.001619830465138 + ], + "scorePercentiles" : { + "0.0" : 2.9156215037900877, + "50.0" : 2.942321784469356, + "90.0" : 2.9657602829181493, + "95.0" : 2.9657602829181493, + "99.0" : 2.9657602829181493, + "99.9" : 2.9657602829181493, + "99.99" : 2.9657602829181493, + "99.999" : 2.9657602829181493, + "99.9999" : 2.9657602829181493, + "100.0" : 2.9657602829181493 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9301669847686, + 2.9172664037339557, + 2.9156215037900877 + ], + [ + 2.9544765841701124, + 2.9657602829181493, + 2.9578512312241276 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7532438195802533, + "scoreError" : 0.18973399140734085, + "scoreConfidence" : [ + 2.5635098281729123, + 2.9429778109875944 + ], + "scorePercentiles" : { + "0.0" : 2.6895095700457112, + "50.0" : 2.7473748944497993, + "90.0" : 2.8248451107031913, + "95.0" : 2.8248451107031913, + "99.0" : 2.8248451107031913, + "99.9" : 2.8248451107031913, + "99.99" : 2.8248451107031913, + "99.999" : 2.8248451107031913, + "99.9999" : 2.8248451107031913, + "100.0" : 2.8248451107031913 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8015469442577032, + 2.8248451107031913, + 2.8174513369014083 + ], + [ + 2.6895095700457112, + 2.69290711093161, + 2.6932028446418954 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17815129784106434, + "scoreError" : 4.361238840332713E-4, + "scoreConfidence" : [ + 0.17771517395703107, + 0.17858742172509762 + ], + "scorePercentiles" : { + "0.0" : 0.1779504766268662, + "50.0" : 0.17813149960763708, + "90.0" : 0.1784264714079255, + "95.0" : 0.1784264714079255, + "99.0" : 0.1784264714079255, + "99.9" : 0.1784264714079255, + "99.99" : 0.1784264714079255, + "99.999" : 0.1784264714079255, + "99.9999" : 0.1784264714079255, + "100.0" : 0.1784264714079255 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17811622784269024, + 0.17817289179895593, + 0.1779504766268662 + ], + [ + 0.17814677137258395, + 0.1784264714079255, + 0.17809494799736425 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33124873443413755, + "scoreError" : 0.023368261633373952, + "scoreConfidence" : [ + 0.3078804728007636, + 0.3546169960675115 + ], + "scorePercentiles" : { + "0.0" : 0.323503151392618, + "50.0" : 0.3312562012230619, + "90.0" : 0.3389621482222147, + "95.0" : 0.3389621482222147, + "99.0" : 0.3389621482222147, + "99.9" : 0.3389621482222147, + "99.99" : 0.3389621482222147, + "99.999" : 0.3389621482222147, + "99.9999" : 0.3389621482222147, + "100.0" : 0.3389621482222147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32369884437107527, + 0.323503151392618, + 0.3237239297853744 + ], + [ + 0.33878847266074935, + 0.3389621482222147, + 0.33881586017279347 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14417557613560647, + "scoreError" : 0.00203271610776868, + "scoreConfidence" : [ + 0.1421428600278378, + 0.14620829224337514 + ], + "scorePercentiles" : { + "0.0" : 0.14348456741516608, + "50.0" : 0.1441196258590285, + "90.0" : 0.14513379388415598, + "95.0" : 0.14513379388415598, + "99.0" : 0.14513379388415598, + "99.9" : 0.14513379388415598, + "99.99" : 0.14513379388415598, + "99.999" : 0.14513379388415598, + "99.9999" : 0.14513379388415598, + "100.0" : 0.14513379388415598 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14348456741516608, + 0.14360080093051308, + 0.14351699786165328 + ], + [ + 0.14513379388415598, + 0.14467884593460648, + 0.14463845078754392 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40567663052668906, + "scoreError" : 0.012223461444932478, + "scoreConfidence" : [ + 0.3934531690817566, + 0.41790009197162153 + ], + "scorePercentiles" : { + "0.0" : 0.40142238764450866, + "50.0" : 0.40571418603360265, + "90.0" : 0.4098885288958111, + "95.0" : 0.4098885288958111, + "99.0" : 0.4098885288958111, + "99.9" : 0.4098885288958111, + "99.99" : 0.4098885288958111, + "99.999" : 0.4098885288958111, + "99.9999" : 0.4098885288958111, + "100.0" : 0.4098885288958111 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40199469304980506, + 0.40169204241645246, + 0.40142238764450866 + ], + [ + 0.40962845213615695, + 0.4094336790174002, + 0.4098885288958111 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15890190123618497, + "scoreError" : 0.002754464588329338, + "scoreConfidence" : [ + 0.15614743664785563, + 0.16165636582451431 + ], + "scorePercentiles" : { + "0.0" : 0.15784463639807433, + "50.0" : 0.1589100640049304, + "90.0" : 0.1599444591750236, + "95.0" : 0.1599444591750236, + "99.0" : 0.1599444591750236, + "99.9" : 0.1599444591750236, + "99.99" : 0.1599444591750236, + "99.999" : 0.1599444591750236, + "99.9999" : 0.1599444591750236, + "100.0" : 0.1599444591750236 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1599444591750236, + 0.15980733256627835, + 0.1596089356954752 + ], + [ + 0.15799485126787266, + 0.15784463639807433, + 0.1582111923143856 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04700158852626916, + "scoreError" : 0.0021264963876325964, + "scoreConfidence" : [ + 0.04487509213863656, + 0.049128084913901755 + ], + "scorePercentiles" : { + "0.0" : 0.04630083734755674, + "50.0" : 0.046896972994682304, + "90.0" : 0.04798373915943322, + "95.0" : 0.04798373915943322, + "99.0" : 0.04798373915943322, + "99.9" : 0.04798373915943322, + "99.99" : 0.04798373915943322, + "99.999" : 0.04798373915943322, + "99.9999" : 0.04798373915943322, + "100.0" : 0.04798373915943322 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046381039144933654, + 0.04630870353099169, + 0.04630083734755674 + ], + [ + 0.04798373915943322, + 0.04762230513026873, + 0.04741290684443096 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8555942.139944317, + "scoreError" : 261339.54566526916, + "scoreConfidence" : [ + 8294602.594279048, + 8817281.685609587 + ], + "scorePercentiles" : { + "0.0" : 8456880.835164836, + "50.0" : 8560133.361073758, + "90.0" : 8663657.688311689, + "95.0" : 8663657.688311689, + "99.0" : 8663657.688311689, + "99.9" : 8663657.688311689, + "99.99" : 8663657.688311689, + "99.999" : 8663657.688311689, + "99.9999" : 8663657.688311689, + "100.0" : 8663657.688311689 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8459343.604395604, + 8456880.835164836, + 8503940.039115647 + ], + [ + 8635503.989646247, + 8616326.683031868, + 8663657.688311689 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-01T05:59:55Z-4531f09593eb3f2f72d47d686d25d1155835c4d5-jdk17.json b/performance-results/2025-11-01T05:59:55Z-4531f09593eb3f2f72d47d686d25d1155835c4d5-jdk17.json new file mode 100644 index 0000000000..122878a46f --- /dev/null +++ b/performance-results/2025-11-01T05:59:55Z-4531f09593eb3f2f72d47d686d25d1155835c4d5-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.331891384863794, + "scoreError" : 0.03251362551583261, + "scoreConfidence" : [ + 3.299377759347961, + 3.3644050103796266 + ], + "scorePercentiles" : { + "0.0" : 3.3251371545140835, + "50.0" : 3.3333284949645576, + "90.0" : 3.3357713950119763, + "95.0" : 3.3357713950119763, + "99.0" : 3.3357713950119763, + "99.9" : 3.3357713950119763, + "99.99" : 3.3357713950119763, + "99.999" : 3.3357713950119763, + "99.9999" : 3.3357713950119763, + "100.0" : 3.3357713950119763 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.33096799826232, + 3.335688991666795 + ], + [ + 3.3251371545140835, + 3.3357713950119763 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6801623357953641, + "scoreError" : 0.036664699351752456, + "scoreConfidence" : [ + 1.6434976364436116, + 1.7168270351471167 + ], + "scorePercentiles" : { + "0.0" : 1.6749049157267533, + "50.0" : 1.6794848939734095, + "90.0" : 1.6867746395078844, + "95.0" : 1.6867746395078844, + "99.0" : 1.6867746395078844, + "99.9" : 1.6867746395078844, + "99.99" : 1.6867746395078844, + "99.999" : 1.6867746395078844, + "99.9999" : 1.6867746395078844, + "100.0" : 1.6867746395078844 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6749049157267533, + 1.675999306628045 + ], + [ + 1.6829704813187738, + 1.6867746395078844 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8410273664978456, + "scoreError" : 0.014486152847996443, + "scoreConfidence" : [ + 0.8265412136498491, + 0.8555135193458421 + ], + "scorePercentiles" : { + "0.0" : 0.8382979167801241, + "50.0" : 0.8412632000283302, + "90.0" : 0.8432851491545976, + "95.0" : 0.8432851491545976, + "99.0" : 0.8432851491545976, + "99.9" : 0.8432851491545976, + "99.99" : 0.8432851491545976, + "99.999" : 0.8432851491545976, + "99.9999" : 0.8432851491545976, + "100.0" : 0.8432851491545976 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8432851491545976, + 0.8382979167801241 + ], + [ + 0.8401637475223157, + 0.8423626525343447 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.92852306781342, + "scoreError" : 0.32470145698488584, + "scoreConfidence" : [ + 15.603821610828534, + 16.253224524798306 + ], + "scorePercentiles" : { + "0.0" : 15.782638612674088, + "50.0" : 15.89632930446573, + "90.0" : 16.095992199560367, + "95.0" : 16.095992199560367, + "99.0" : 16.095992199560367, + "99.9" : 16.095992199560367, + "99.99" : 16.095992199560367, + "99.999" : 16.095992199560367, + "99.9999" : 16.095992199560367, + "100.0" : 16.095992199560367 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.782638612674088, + 15.912006046967093, + 15.865574248029539 + ], + [ + 16.034274737685067, + 15.880652561964366, + 16.095992199560367 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2621.6783029837075, + "scoreError" : 347.83063619223327, + "scoreConfidence" : [ + 2273.8476667914742, + 2969.5089391759407 + ], + "scorePercentiles" : { + "0.0" : 2477.5846469216513, + "50.0" : 2627.644437491162, + "90.0" : 2738.433113903462, + "95.0" : 2738.433113903462, + "99.0" : 2738.433113903462, + "99.9" : 2738.433113903462, + "99.99" : 2738.433113903462, + "99.999" : 2738.433113903462, + "99.9999" : 2738.433113903462, + "100.0" : 2738.433113903462 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2738.433113903462, + 2725.6591062410125, + 2736.924642417969 + ], + [ + 2521.83853967684, + 2529.6297687413116, + 2477.5846469216513 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72166.13397572777, + "scoreError" : 1163.099037645591, + "scoreConfidence" : [ + 71003.03493808219, + 73329.23301337336 + ], + "scorePercentiles" : { + "0.0" : 71532.15604150001, + "50.0" : 72230.40405532901, + "90.0" : 72613.06782430779, + "95.0" : 72613.06782430779, + "99.0" : 72613.06782430779, + "99.9" : 72613.06782430779, + "99.99" : 72613.06782430779, + "99.999" : 72613.06782430779, + "99.9999" : 72613.06782430779, + "100.0" : 72613.06782430779 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72613.06782430779, + 72431.70057290916, + 72484.77260807382 + ], + [ + 71905.99926982696, + 71532.15604150001, + 72029.10753774887 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 344.0893615237961, + "scoreError" : 12.155044598705157, + "scoreConfidence" : [ + 331.9343169250909, + 356.24440612250123 + ], + "scorePercentiles" : { + "0.0" : 338.764867948975, + "50.0" : 343.1742960285771, + "90.0" : 350.76979770318536, + "95.0" : 350.76979770318536, + "99.0" : 350.76979770318536, + "99.9" : 350.76979770318536, + "99.99" : 350.76979770318536, + "99.999" : 350.76979770318536, + "99.9999" : 350.76979770318536, + "100.0" : 350.76979770318536 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 338.764867948975, + 347.11184174932396, + 350.76979770318536 + ], + [ + 344.52738851008525, + 341.82120354706893, + 341.5410696841381 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 111.92745851150347, + "scoreError" : 1.6475043111780345, + "scoreConfidence" : [ + 110.27995420032543, + 113.57496282268151 + ], + "scorePercentiles" : { + "0.0" : 111.36897514273787, + "50.0" : 111.79602064537337, + "90.0" : 112.9329983879452, + "95.0" : 112.9329983879452, + "99.0" : 112.9329983879452, + "99.9" : 112.9329983879452, + "99.99" : 112.9329983879452, + "99.999" : 112.9329983879452, + "99.9999" : 112.9329983879452, + "100.0" : 112.9329983879452 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.58840398971071, + 112.9329983879452, + 112.19946847962603 + ], + [ + 111.47126776796497, + 111.36897514273787, + 112.00363730103605 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06279068040235579, + "scoreError" : 6.119917721056596E-4, + "scoreConfidence" : [ + 0.06217868863025013, + 0.06340267217446145 + ], + "scorePercentiles" : { + "0.0" : 0.06258484192607612, + "50.0" : 0.06273629360471389, + "90.0" : 0.06305487835605382, + "95.0" : 0.06305487835605382, + "99.0" : 0.06305487835605382, + "99.9" : 0.06305487835605382, + "99.99" : 0.06305487835605382, + "99.999" : 0.06305487835605382, + "99.9999" : 0.06305487835605382, + "100.0" : 0.06305487835605382 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06305487835605382, + 0.06261993746869052, + 0.06285264974073725 + ], + [ + 0.06260174495283048, + 0.06303002996974663, + 0.06258484192607612 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.830771716436987E-4, + "scoreError" : 1.2042647431225331E-5, + "scoreConfidence" : [ + 3.710345242124734E-4, + 3.95119819074924E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7853053682702437E-4, + "50.0" : 3.826497725795037E-4, + "90.0" : 3.8792826009776603E-4, + "95.0" : 3.8792826009776603E-4, + "99.0" : 3.8792826009776603E-4, + "99.9" : 3.8792826009776603E-4, + "99.99" : 3.8792826009776603E-4, + "99.999" : 3.8792826009776603E-4, + "99.9999" : 3.8792826009776603E-4, + "100.0" : 3.8792826009776603E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.876485373668257E-4, + 3.849495988618241E-4, + 3.8792826009776603E-4 + ], + [ + 3.7853053682702437E-4, + 3.790561504115684E-4, + 3.803499462971833E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.346785363021913, + "scoreError" : 0.05997008187668316, + "scoreConfidence" : [ + 2.28681528114523, + 2.406755444898596 + ], + "scorePercentiles" : { + "0.0" : 2.296827368856224, + "50.0" : 2.3461829009485475, + "90.0" : 2.418269725522952, + "95.0" : 2.4232333033680638, + "99.0" : 2.4232333033680638, + "99.9" : 2.4232333033680638, + "99.99" : 2.4232333033680638, + "99.999" : 2.4232333033680638, + "99.9999" : 2.4232333033680638, + "100.0" : 2.4232333033680638 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.4232333033680638, + 2.3735975249169434, + 2.3535371819251587, + 2.3364703919644945, + 2.304362129032258 + ], + [ + 2.372712674970344, + 2.3665069159962138, + 2.3388286199719364, + 2.301777519217491, + 2.296827368856224 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013806770964828997, + "scoreError" : 3.268550197256487E-4, + "scoreConfidence" : [ + 0.013479915945103348, + 0.014133625984554646 + ], + "scorePercentiles" : { + "0.0" : 0.013696704500536219, + "50.0" : 0.013780107329397107, + "90.0" : 0.014014539573789467, + "95.0" : 0.014014539573789467, + "99.0" : 0.014014539573789467, + "99.9" : 0.014014539573789467, + "99.99" : 0.014014539573789467, + "99.999" : 0.014014539573789467, + "99.9999" : 0.014014539573789467, + "100.0" : 0.014014539573789467 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013768856228831061, + 0.013696704500536219, + 0.013713912816546398 + ], + [ + 0.013855254239307689, + 0.01379135842996315, + 0.014014539573789467 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0857069580066923, + "scoreError" : 0.17271268983677865, + "scoreConfidence" : [ + 0.9129942681699136, + 1.2584196478434708 + ], + "scorePercentiles" : { + "0.0" : 1.025855275105139, + "50.0" : 1.0857095735582911, + "90.0" : 1.145439935517123, + "95.0" : 1.145439935517123, + "99.0" : 1.145439935517123, + "99.9" : 1.145439935517123, + "99.99" : 1.145439935517123, + "99.999" : 1.145439935517123, + "99.9999" : 1.145439935517123, + "100.0" : 1.145439935517123 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.025855275105139, + 1.031436192141089, + 1.0313311540682686 + ], + [ + 1.145439935517123, + 1.139982954975493, + 1.1401962362330407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010729017744437743, + "scoreError" : 7.247708949146882E-4, + "scoreConfidence" : [ + 0.010004246849523054, + 0.011453788639352432 + ], + "scorePercentiles" : { + "0.0" : 0.01041045969906246, + "50.0" : 0.010765281796947097, + "90.0" : 0.011004608724167529, + "95.0" : 0.011004608724167529, + "99.0" : 0.011004608724167529, + "99.9" : 0.011004608724167529, + "99.99" : 0.011004608724167529, + "99.999" : 0.011004608724167529, + "99.9999" : 0.011004608724167529, + "100.0" : 0.011004608724167529 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.011004608724167529, + 0.010980254617043423, + 0.010842681332740618 + ], + [ + 0.010448219832458852, + 0.010687882261153577, + 0.01041045969906246 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1958591348409158, + "scoreError" : 0.4944777383834739, + "scoreConfidence" : [ + 2.701381396457442, + 3.6903368732243895 + ], + "scorePercentiles" : { + "0.0" : 3.019203842486421, + "50.0" : 3.180597427187406, + "90.0" : 3.4302976275720165, + "95.0" : 3.4302976275720165, + "99.0" : 3.4302976275720165, + "99.9" : 3.4302976275720165, + "99.99" : 3.4302976275720165, + "99.999" : 3.4302976275720165, + "99.9999" : 3.4302976275720165, + "100.0" : 3.4302976275720165 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.3142256852220013, + 3.310249033752482, + 3.4302976275720165 + ], + [ + 3.0509458206223306, + 3.019203842486421, + 3.050232799390244 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.863354274052144, + "scoreError" : 0.08391199928131193, + "scoreConfidence" : [ + 2.779442274770832, + 2.947266273333456 + ], + "scorePercentiles" : { + "0.0" : 2.8281498331447965, + "50.0" : 2.861301315594676, + "90.0" : 2.897399832271147, + "95.0" : 2.897399832271147, + "99.0" : 2.897399832271147, + "99.9" : 2.897399832271147, + "99.99" : 2.897399832271147, + "99.999" : 2.897399832271147, + "99.9999" : 2.897399832271147, + "100.0" : 2.897399832271147 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8281498331447965, + 2.8410609488636362, + 2.8411289008522727 + ], + [ + 2.8814737303370785, + 2.897399832271147, + 2.8909123988439305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1817232191628542, + "scoreError" : 0.010306240285060927, + "scoreConfidence" : [ + 0.17141697887779328, + 0.1920294594479151 + ], + "scorePercentiles" : { + "0.0" : 0.1778002790342081, + "50.0" : 0.18191503704204776, + "90.0" : 0.18548494385502837, + "95.0" : 0.18548494385502837, + "99.0" : 0.18548494385502837, + "99.9" : 0.18548494385502837, + "99.99" : 0.18548494385502837, + "99.999" : 0.18548494385502837, + "99.9999" : 0.18548494385502837, + "100.0" : 0.18548494385502837 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18485091010924418, + 0.18548494385502837, + 0.18482364512909605 + ], + [ + 0.17900642895499946, + 0.17837310789454908, + 0.1778002790342081 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32784405908654923, + "scoreError" : 0.006129186006338858, + "scoreConfidence" : [ + 0.32171487308021035, + 0.3339732450928881 + ], + "scorePercentiles" : { + "0.0" : 0.32519039831555674, + "50.0" : 0.3279427160795765, + "90.0" : 0.33076220493484154, + "95.0" : 0.33076220493484154, + "99.0" : 0.33076220493484154, + "99.9" : 0.33076220493484154, + "99.99" : 0.33076220493484154, + "99.999" : 0.33076220493484154, + "99.9999" : 0.33076220493484154, + "100.0" : 0.33076220493484154 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32597855632700956, + 0.32519039831555674, + 0.3267469807554074 + ], + [ + 0.32913845140374554, + 0.32924776278273465, + 0.33076220493484154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14746814073815903, + "scoreError" : 0.0020280931125989934, + "scoreConfidence" : [ + 0.14544004762556004, + 0.14949623385075803 + ], + "scorePercentiles" : { + "0.0" : 0.1465289295353642, + "50.0" : 0.14734827175724274, + "90.0" : 0.14866888964543223, + "95.0" : 0.14866888964543223, + "99.0" : 0.14866888964543223, + "99.9" : 0.14866888964543223, + "99.99" : 0.14866888964543223, + "99.999" : 0.14866888964543223, + "99.9999" : 0.14866888964543223, + "100.0" : 0.14866888964543223 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14747957351639923, + 0.14779487381582254, + 0.1465289295353642 + ], + [ + 0.14866888964543223, + 0.14721696999808623, + 0.14711960791784973 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40202878378538687, + "scoreError" : 0.024456529965787052, + "scoreConfidence" : [ + 0.3775722538195998, + 0.42648531375117393 + ], + "scorePercentiles" : { + "0.0" : 0.39359629990554157, + "50.0" : 0.40145676220206644, + "90.0" : 0.4123902381030928, + "95.0" : 0.4123902381030928, + "99.0" : 0.4123902381030928, + "99.9" : 0.4123902381030928, + "99.99" : 0.4123902381030928, + "99.999" : 0.4123902381030928, + "99.9999" : 0.4123902381030928, + "100.0" : 0.4123902381030928 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3952085714116345, + 0.3938002400866312, + 0.39359629990554157 + ], + [ + 0.4123902381030928, + 0.40770495299249837, + 0.40947240021292275 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15968802554611805, + "scoreError" : 0.00289990376059485, + "scoreConfidence" : [ + 0.1567881217855232, + 0.1625879293067129 + ], + "scorePercentiles" : { + "0.0" : 0.15787117648080323, + "50.0" : 0.16023359604230092, + "90.0" : 0.1604711242658622, + "95.0" : 0.1604711242658622, + "99.0" : 0.1604711242658622, + "99.9" : 0.1604711242658622, + "99.99" : 0.1604711242658622, + "99.999" : 0.1604711242658622, + "99.9999" : 0.1604711242658622, + "100.0" : 0.1604711242658622 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16030587328075407, + 0.15901278716468698, + 0.15787117648080323 + ], + [ + 0.16023410626502163, + 0.1604711242658622, + 0.1602330858195802 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04731617293218265, + "scoreError" : 0.0019227948116767978, + "scoreConfidence" : [ + 0.045393378120505846, + 0.04923896774385945 + ], + "scorePercentiles" : { + "0.0" : 0.04663350619747997, + "50.0" : 0.04727615638843023, + "90.0" : 0.04808685457780342, + "95.0" : 0.04808685457780342, + "99.0" : 0.04808685457780342, + "99.9" : 0.04808685457780342, + "99.99" : 0.04808685457780342, + "99.999" : 0.04808685457780342, + "99.9999" : 0.04808685457780342, + "100.0" : 0.04808685457780342 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04671782441346576, + 0.046737132338782794, + 0.04663350619747997 + ], + [ + 0.0479065396274863, + 0.04808685457780342, + 0.04781518043807766 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8840004.978480019, + "scoreError" : 141673.3435806348, + "scoreConfidence" : [ + 8698331.634899383, + 8981678.322060654 + ], + "scorePercentiles" : { + "0.0" : 8756502.923884515, + "50.0" : 8848451.234890025, + "90.0" : 8909324.657168299, + "95.0" : 8909324.657168299, + "99.0" : 8909324.657168299, + "99.9" : 8909324.657168299, + "99.99" : 8909324.657168299, + "99.999" : 8909324.657168299, + "99.9999" : 8909324.657168299, + "100.0" : 8909324.657168299 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8909324.657168299, + 8853233.321238939, + 8818743.833333334 + ], + [ + 8843669.148541113, + 8858555.986713907, + 8756502.923884515 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-01T06:00:20Z-4531f09593eb3f2f72d47d686d25d1155835c4d5-jdk17.json b/performance-results/2025-11-01T06:00:20Z-4531f09593eb3f2f72d47d686d25d1155835c4d5-jdk17.json new file mode 100644 index 0000000000..63f025e4b2 --- /dev/null +++ b/performance-results/2025-11-01T06:00:20Z-4531f09593eb3f2f72d47d686d25d1155835c4d5-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3516421209171643, + "scoreError" : 0.020266879680893895, + "scoreConfidence" : [ + 3.3313752412362705, + 3.371909000598058 + ], + "scorePercentiles" : { + "0.0" : 3.3481196017623884, + "50.0" : 3.3516027833167685, + "90.0" : 3.355243315272732, + "95.0" : 3.355243315272732, + "99.0" : 3.355243315272732, + "99.9" : 3.355243315272732, + "99.99" : 3.355243315272732, + "99.999" : 3.355243315272732, + "99.9999" : 3.355243315272732, + "100.0" : 3.355243315272732 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3501658227389575, + 3.3530397438945796 + ], + [ + 3.3481196017623884, + 3.355243315272732 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6946104900202834, + "scoreError" : 0.015262060789982762, + "scoreConfidence" : [ + 1.6793484292303007, + 1.7098725508102661 + ], + "scorePercentiles" : { + "0.0" : 1.6921948024089524, + "50.0" : 1.6942917162049038, + "90.0" : 1.6976637252623739, + "95.0" : 1.6976637252623739, + "99.0" : 1.6976637252623739, + "99.9" : 1.6976637252623739, + "99.99" : 1.6976637252623739, + "99.999" : 1.6976637252623739, + "99.9999" : 1.6976637252623739, + "100.0" : 1.6976637252623739 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6921948024089524, + 1.6951204402008255 + ], + [ + 1.693462992208982, + 1.6976637252623739 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8518091300945192, + "scoreError" : 0.009963066921643438, + "scoreConfidence" : [ + 0.8418460631728758, + 0.8617721970161626 + ], + "scorePercentiles" : { + "0.0" : 0.8505252586146297, + "50.0" : 0.8513591371942701, + "90.0" : 0.8539929873749069, + "95.0" : 0.8539929873749069, + "99.0" : 0.8539929873749069, + "99.9" : 0.8539929873749069, + "99.99" : 0.8539929873749069, + "99.999" : 0.8539929873749069, + "99.9999" : 0.8539929873749069, + "100.0" : 0.8539929873749069 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.85096616421951, + 0.8539929873749069 + ], + [ + 0.8517521101690302, + 0.8505252586146297 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.132278648136566, + "scoreError" : 0.5965023787437737, + "scoreConfidence" : [ + 15.535776269392793, + 16.72878102688034 + ], + "scorePercentiles" : { + "0.0" : 15.93017405119031, + "50.0" : 16.121098467605933, + "90.0" : 16.34539481625887, + "95.0" : 16.34539481625887, + "99.0" : 16.34539481625887, + "99.9" : 16.34539481625887, + "99.99" : 16.34539481625887, + "99.999" : 16.34539481625887, + "99.9999" : 16.34539481625887, + "100.0" : 16.34539481625887 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.34539481625887, + 16.334315207947487, + 16.297946467514958 + ], + [ + 15.944250467696905, + 15.94159087821086, + 15.93017405119031 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2659.649167351619, + "scoreError" : 48.51515620270553, + "scoreConfidence" : [ + 2611.1340111489135, + 2708.1643235543243 + ], + "scorePercentiles" : { + "0.0" : 2642.4541441188912, + "50.0" : 2657.871324692631, + "90.0" : 2678.929957872718, + "95.0" : 2678.929957872718, + "99.0" : 2678.929957872718, + "99.9" : 2678.929957872718, + "99.99" : 2678.929957872718, + "99.999" : 2678.929957872718, + "99.9999" : 2678.929957872718, + "100.0" : 2678.929957872718 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2670.826305970804, + 2675.974758238456, + 2678.929957872718 + ], + [ + 2644.916343414458, + 2644.7934944943863, + 2642.4541441188912 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74269.04404589452, + "scoreError" : 909.8190264036471, + "scoreConfidence" : [ + 73359.22501949087, + 75178.86307229818 + ], + "scorePercentiles" : { + "0.0" : 73968.07965727508, + "50.0" : 74264.35709327293, + "90.0" : 74582.90341654317, + "95.0" : 74582.90341654317, + "99.0" : 74582.90341654317, + "99.9" : 74582.90341654317, + "99.99" : 74582.90341654317, + "99.999" : 74582.90341654317, + "99.9999" : 74582.90341654317, + "100.0" : 74582.90341654317 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73982.80358736034, + 73968.40426692912, + 73968.07965727508 + ], + [ + 74566.16274807396, + 74545.91059918552, + 74582.90341654317 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 358.50599781778834, + "scoreError" : 11.310423788100827, + "scoreConfidence" : [ + 347.1955740296875, + 369.81642160588916 + ], + "scorePercentiles" : { + "0.0" : 354.1872944162811, + "50.0" : 358.6259102566306, + "90.0" : 362.3576173485875, + "95.0" : 362.3576173485875, + "99.0" : 362.3576173485875, + "99.9" : 362.3576173485875, + "99.99" : 362.3576173485875, + "99.999" : 362.3576173485875, + "99.9999" : 362.3576173485875, + "100.0" : 362.3576173485875 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 354.1872944162811, + 355.01996809710585, + 355.31789147164466 + ], + [ + 362.3576173485875, + 361.9339290416166, + 362.21928653149445 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.66894571506573, + "scoreError" : 5.077425707609744, + "scoreConfidence" : [ + 110.59152000745598, + 120.74637142267548 + ], + "scorePercentiles" : { + "0.0" : 113.22014526544356, + "50.0" : 115.87076230118706, + "90.0" : 117.40345355174001, + "95.0" : 117.40345355174001, + "99.0" : 117.40345355174001, + "99.9" : 117.40345355174001, + "99.99" : 117.40345355174001, + "99.999" : 117.40345355174001, + "99.9999" : 117.40345355174001, + "100.0" : 117.40345355174001 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.22014526544356, + 114.42486420592014, + 114.57830931775703 + ], + [ + 117.40345355174001, + 117.16321528461707, + 117.22368666491666 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061308036583078034, + "scoreError" : 0.0012960963013278312, + "scoreConfidence" : [ + 0.0600119402817502, + 0.06260413288440586 + ], + "scorePercentiles" : { + "0.0" : 0.06083194671273541, + "50.0" : 0.06130769536717939, + "90.0" : 0.06176275952369188, + "95.0" : 0.06176275952369188, + "99.0" : 0.06176275952369188, + "99.9" : 0.06176275952369188, + "99.99" : 0.06176275952369188, + "99.999" : 0.06176275952369188, + "99.9999" : 0.06176275952369188, + "100.0" : 0.06176275952369188 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06169039015558105, + 0.06176275952369188, + 0.06173231526053595 + ], + [ + 0.060905807267146186, + 0.06083194671273541, + 0.06092500057877774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6978574528622545E-4, + "scoreError" : 2.8804646310127816E-5, + "scoreConfidence" : [ + 3.4098109897609763E-4, + 3.9859039159635326E-4 + ], + "scorePercentiles" : { + "0.0" : 3.599732699750661E-4, + "50.0" : 3.700691248737965E-4, + "90.0" : 3.7919445184600925E-4, + "95.0" : 3.7919445184600925E-4, + "99.0" : 3.7919445184600925E-4, + "99.9" : 3.7919445184600925E-4, + "99.99" : 3.7919445184600925E-4, + "99.999" : 3.7919445184600925E-4, + "99.9999" : 3.7919445184600925E-4, + "100.0" : 3.7919445184600925E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.7908868919217677E-4, + 3.7918802546846173E-4, + 3.7919445184600925E-4 + ], + [ + 3.602204746802226E-4, + 3.610495605554163E-4, + 3.599732699750661E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2984450825409515, + "scoreError" : 0.06247796819270518, + "scoreConfidence" : [ + 2.2359671143482465, + 2.3609230507336565 + ], + "scorePercentiles" : { + "0.0" : 2.2550255170236753, + "50.0" : 2.2963708047992473, + "90.0" : 2.3735609150681896, + "95.0" : 2.3766705962452472, + "99.0" : 2.3766705962452472, + "99.9" : 2.3766705962452472, + "99.99" : 2.3766705962452472, + "99.999" : 2.3766705962452472, + "99.9999" : 2.3766705962452472, + "100.0" : 2.3766705962452472 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.320249714153132, + 2.3766705962452472, + 2.3129362430619795, + 2.2550255170236753, + 2.2565208264891696 + ], + [ + 2.345573784474672, + 2.3030489090490445, + 2.2896927005494505, + 2.2620621149061297, + 2.2626704194570135 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013606860141480201, + "scoreError" : 3.7307320519917636E-4, + "scoreConfidence" : [ + 0.013233786936281024, + 0.013979933346679378 + ], + "scorePercentiles" : { + "0.0" : 0.013483910160779681, + "50.0" : 0.013605018602527467, + "90.0" : 0.01373194384261211, + "95.0" : 0.01373194384261211, + "99.0" : 0.01373194384261211, + "99.9" : 0.01373194384261211, + "99.99" : 0.01373194384261211, + "99.999" : 0.01373194384261211, + "99.9999" : 0.01373194384261211, + "100.0" : 0.01373194384261211 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013730945973444644, + 0.01373194384261211, + 0.013721890986331784 + ], + [ + 0.013484323666989838, + 0.01348814621872315, + 0.013483910160779681 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0094466817045884, + "scoreError" : 0.012517406569889786, + "scoreConfidence" : [ + 0.9969292751346986, + 1.0219640882744783 + ], + "scorePercentiles" : { + "0.0" : 1.0048441890072348, + "50.0" : 1.009483349726306, + "90.0" : 1.013677873809041, + "95.0" : 1.013677873809041, + "99.0" : 1.013677873809041, + "99.9" : 1.013677873809041, + "99.99" : 1.013677873809041, + "99.999" : 1.013677873809041, + "99.9999" : 1.013677873809041, + "100.0" : 1.013677873809041 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0133115514236497, + 1.013677873809041, + 1.013544431438127 + ], + [ + 1.0056551480289622, + 1.0048441890072348, + 1.005646896520515 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010940957687832716, + "scoreError" : 3.274447266980534E-4, + "scoreConfidence" : [ + 0.010613512961134662, + 0.01126840241453077 + ], + "scorePercentiles" : { + "0.0" : 0.01083395779210227, + "50.0" : 0.010940101542594474, + "90.0" : 0.011051805549170254, + "95.0" : 0.011051805549170254, + "99.0" : 0.011051805549170254, + "99.9" : 0.011051805549170254, + "99.99" : 0.011051805549170254, + "99.999" : 0.011051805549170254, + "99.9999" : 0.011051805549170254, + "100.0" : 0.011051805549170254 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010834255077343768, + 0.010834938060691161, + 0.01083395779210227 + ], + [ + 0.011045265024497784, + 0.011045524623191062, + 0.011051805549170254 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.005894334878715, + "scoreError" : 0.13420488329212987, + "scoreConfidence" : [ + 2.871689451586585, + 3.140099218170845 + ], + "scorePercentiles" : { + "0.0" : 2.961421139135583, + "50.0" : 3.0048807512100897, + "90.0" : 3.0515776955460647, + "95.0" : 3.0515776955460647, + "99.0" : 3.0515776955460647, + "99.9" : 3.0515776955460647, + "99.99" : 3.0515776955460647, + "99.999" : 3.0515776955460647, + "99.9999" : 3.0515776955460647, + "100.0" : 3.0515776955460647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.961421139135583, + 2.96166996625222, + 2.9636442831753556 + ], + [ + 3.0515776955460647, + 3.0461172192448234, + 3.050935705918243 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7748131192422254, + "scoreError" : 0.010805884825145603, + "scoreConfidence" : [ + 2.76400723441708, + 2.785619004067371 + ], + "scorePercentiles" : { + "0.0" : 2.770273811357341, + "50.0" : 2.7746606380087213, + "90.0" : 2.7808075665832637, + "95.0" : 2.7808075665832637, + "99.0" : 2.7808075665832637, + "99.9" : 2.7808075665832637, + "99.99" : 2.7808075665832637, + "99.999" : 2.7808075665832637, + "99.9999" : 2.7808075665832637, + "100.0" : 2.7808075665832637 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.770273811357341, + 2.773268169717138, + 2.771676582317073 + ], + [ + 2.776053106300305, + 2.7767994791782344, + 2.7808075665832637 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1848705224547488, + "scoreError" : 0.03374183665216868, + "scoreConfidence" : [ + 0.15112868580258013, + 0.21861235910691748 + ], + "scorePercentiles" : { + "0.0" : 0.1738388615930188, + "50.0" : 0.18486622901291733, + "90.0" : 0.1959017577722491, + "95.0" : 0.1959017577722491, + "99.0" : 0.1959017577722491, + "99.9" : 0.1959017577722491, + "99.99" : 0.1959017577722491, + "99.999" : 0.1959017577722491, + "99.9999" : 0.1959017577722491, + "100.0" : 0.1959017577722491 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1957884436243319, + 0.19587388537626826, + 0.1959017577722491 + ], + [ + 0.17394401440150276, + 0.1738388615930188, + 0.17387617196112184 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32782790137313605, + "scoreError" : 0.014024198854110981, + "scoreConfidence" : [ + 0.31380370251902506, + 0.34185210022724705 + ], + "scorePercentiles" : { + "0.0" : 0.3231566922704065, + "50.0" : 0.3276213205926992, + "90.0" : 0.3330608998168193, + "95.0" : 0.3330608998168193, + "99.0" : 0.3330608998168193, + "99.9" : 0.3330608998168193, + "99.99" : 0.3330608998168193, + "99.999" : 0.3330608998168193, + "99.9999" : 0.3330608998168193, + "100.0" : 0.3330608998168193 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3234106920862844, + 0.3231566922704065, + 0.3232647914983029 + ], + [ + 0.3330608998168193, + 0.33183194909911407, + 0.3322423834678893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14500696484986755, + "scoreError" : 0.003669228959419107, + "scoreConfidence" : [ + 0.14133773589044846, + 0.14867619380928665 + ], + "scorePercentiles" : { + "0.0" : 0.1436726480518361, + "50.0" : 0.14505250257753702, + "90.0" : 0.14625810623765997, + "95.0" : 0.14625810623765997, + "99.0" : 0.14625810623765997, + "99.9" : 0.14625810623765997, + "99.99" : 0.14625810623765997, + "99.999" : 0.14625810623765997, + "99.9999" : 0.14625810623765997, + "100.0" : 0.14625810623765997 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14625810623765997, + 0.14616711723694403, + 0.14617048313966235 + ], + [ + 0.14383554651497282, + 0.14393788791813, + 0.1436726480518361 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3990304949743202, + "scoreError" : 0.023773515064168343, + "scoreConfidence" : [ + 0.37525697991015183, + 0.42280401003848855 + ], + "scorePercentiles" : { + "0.0" : 0.3913256195656427, + "50.0" : 0.398245167759847, + "90.0" : 0.4093590786769823, + "95.0" : 0.4093590786769823, + "99.0" : 0.4093590786769823, + "99.9" : 0.4093590786769823, + "99.99" : 0.4093590786769823, + "99.999" : 0.4093590786769823, + "99.9999" : 0.4093590786769823, + "100.0" : 0.4093590786769823 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4093590786769823, + 0.4050236961240938, + 0.4055623443507178 + ], + [ + 0.3913256195656427, + 0.3914666393956001, + 0.3914455917328845 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1573914933575806, + "scoreError" : 0.0025462428469788323, + "scoreConfidence" : [ + 0.15484525051060177, + 0.15993773620455942 + ], + "scorePercentiles" : { + "0.0" : 0.1564783146241472, + "50.0" : 0.15740681349678315, + "90.0" : 0.1583921985396604, + "95.0" : 0.1583921985396604, + "99.0" : 0.1583921985396604, + "99.9" : 0.1583921985396604, + "99.99" : 0.1583921985396604, + "99.999" : 0.1583921985396604, + "99.9999" : 0.1583921985396604, + "100.0" : 0.1583921985396604 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15671211301772367, + 0.15652170694944437, + 0.1564783146241472 + ], + [ + 0.15810151397584266, + 0.1583921985396604, + 0.1581431130386653 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04673965841320554, + "scoreError" : 5.522774934194014E-4, + "scoreConfidence" : [ + 0.04618738091978614, + 0.04729193590662494 + ], + "scorePercentiles" : { + "0.0" : 0.04645369147260894, + "50.0" : 0.0467052195842247, + "90.0" : 0.04703625385103831, + "95.0" : 0.04703625385103831, + "99.0" : 0.04703625385103831, + "99.9" : 0.04703625385103831, + "99.99" : 0.04703625385103831, + "99.999" : 0.04703625385103831, + "99.9999" : 0.04703625385103831, + "100.0" : 0.04703625385103831 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04703625385103831, + 0.04686860591190724, + 0.04645369147260894 + ], + [ + 0.04671516480898415, + 0.046668960075229374, + 0.04669527435946525 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8715377.581151882, + "scoreError" : 198578.84507244098, + "scoreConfidence" : [ + 8516798.736079441, + 8913956.426224323 + ], + "scorePercentiles" : { + "0.0" : 8646876.089023337, + "50.0" : 8718291.34030531, + "90.0" : 8782186.192273924, + "95.0" : 8782186.192273924, + "99.0" : 8782186.192273924, + "99.9" : 8782186.192273924, + "99.99" : 8782186.192273924, + "99.999" : 8782186.192273924, + "99.9999" : 8782186.192273924, + "100.0" : 8782186.192273924 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8782186.192273924, + 8777885.87368421, + 8779603.260526316 + ], + [ + 8658696.806926407, + 8646876.089023337, + 8647017.264477096 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-03T00:31:23Z-7afaeef534eb67767fc67dcded65e4a7759b71f8-jdk17.json b/performance-results/2025-11-03T00:31:23Z-7afaeef534eb67767fc67dcded65e4a7759b71f8-jdk17.json new file mode 100644 index 0000000000..b0f32d8e5e --- /dev/null +++ b/performance-results/2025-11-03T00:31:23Z-7afaeef534eb67767fc67dcded65e4a7759b71f8-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.338851040015466, + "scoreError" : 0.047754666231120485, + "scoreConfidence" : [ + 3.2910963737843457, + 3.3866057062465864 + ], + "scorePercentiles" : { + "0.0" : 3.3313057804470665, + "50.0" : 3.339162959616608, + "90.0" : 3.3457724603815806, + "95.0" : 3.3457724603815806, + "99.0" : 3.3457724603815806, + "99.9" : 3.3457724603815806, + "99.99" : 3.3457724603815806, + "99.999" : 3.3457724603815806, + "99.9999" : 3.3457724603815806, + "100.0" : 3.3457724603815806 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3313057804470665, + 3.3457724603815806 + ], + [ + 3.333740386956628, + 3.3445855322765876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6800604945260473, + "scoreError" : 0.019392526322408534, + "scoreConfidence" : [ + 1.6606679682036387, + 1.699453020848456 + ], + "scorePercentiles" : { + "0.0" : 1.6760121933069514, + "50.0" : 1.6807048427156537, + "90.0" : 1.6828200993659297, + "95.0" : 1.6828200993659297, + "99.0" : 1.6828200993659297, + "99.9" : 1.6828200993659297, + "99.99" : 1.6828200993659297, + "99.999" : 1.6828200993659297, + "99.9999" : 1.6828200993659297, + "100.0" : 1.6828200993659297 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6760121933069514, + 1.679659916703582 + ], + [ + 1.6817497687277256, + 1.6828200993659297 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8435235397020698, + "scoreError" : 0.028135573439379998, + "scoreConfidence" : [ + 0.8153879662626898, + 0.8716591131414498 + ], + "scorePercentiles" : { + "0.0" : 0.8392332772388195, + "50.0" : 0.8428235337044931, + "90.0" : 0.8492138141604734, + "95.0" : 0.8492138141604734, + "99.0" : 0.8492138141604734, + "99.9" : 0.8492138141604734, + "99.99" : 0.8492138141604734, + "99.999" : 0.8492138141604734, + "99.9999" : 0.8492138141604734, + "100.0" : 0.8492138141604734 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8412256215269625, + 0.844421445882024 + ], + [ + 0.8392332772388195, + 0.8492138141604734 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.03161159787452, + "scoreError" : 0.243417215367289, + "scoreConfidence" : [ + 15.78819438250723, + 16.275028813241807 + ], + "scorePercentiles" : { + "0.0" : 15.888823474094021, + "50.0" : 16.065117484217957, + "90.0" : 16.114313785615696, + "95.0" : 16.114313785615696, + "99.0" : 16.114313785615696, + "99.9" : 16.114313785615696, + "99.99" : 16.114313785615696, + "99.999" : 16.114313785615696, + "99.9999" : 16.114313785615696, + "100.0" : 16.114313785615696 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.07842885980708, + 16.114313785615696, + 16.090693527438795 + ], + [ + 15.888823474094021, + 16.051806108628835, + 15.965603831662682 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2693.1539295752973, + "scoreError" : 210.29242172306684, + "scoreConfidence" : [ + 2482.8615078522303, + 2903.4463512983643 + ], + "scorePercentiles" : { + "0.0" : 2584.0895296204944, + "50.0" : 2692.8387653481313, + "90.0" : 2776.8278413028997, + "95.0" : 2776.8278413028997, + "99.0" : 2776.8278413028997, + "99.9" : 2776.8278413028997, + "99.99" : 2776.8278413028997, + "99.999" : 2776.8278413028997, + "99.9999" : 2776.8278413028997, + "100.0" : 2776.8278413028997 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2584.0895296204944, + 2681.006917139994, + 2640.574187752328 + ], + [ + 2771.754488079799, + 2704.6706135562686, + 2776.8278413028997 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73500.41533106759, + "scoreError" : 2258.5840663723475, + "scoreConfidence" : [ + 71241.83126469524, + 75758.99939743994 + ], + "scorePercentiles" : { + "0.0" : 72528.0723787537, + "50.0" : 73555.08735753338, + "90.0" : 74299.894113401, + "95.0" : 74299.894113401, + "99.0" : 74299.894113401, + "99.9" : 74299.894113401, + "99.99" : 74299.894113401, + "99.999" : 74299.894113401, + "99.9999" : 74299.894113401, + "100.0" : 74299.894113401 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72829.2712846707, + 72979.3924319122, + 72528.0723787537 + ], + [ + 74130.78228315456, + 74235.07949451337, + 74299.894113401 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 346.9140217646739, + "scoreError" : 14.238212631464789, + "scoreConfidence" : [ + 332.67580913320916, + 361.1522343961387 + ], + "scorePercentiles" : { + "0.0" : 340.0957261190386, + "50.0" : 348.34802506179386, + "90.0" : 352.0222681676523, + "95.0" : 352.0222681676523, + "99.0" : 352.0222681676523, + "99.9" : 352.0222681676523, + "99.99" : 352.0222681676523, + "99.999" : 352.0222681676523, + "99.9999" : 352.0222681676523, + "100.0" : 352.0222681676523 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 349.606978882465, + 351.25275485358424, + 352.0222681676523 + ], + [ + 341.4173313241806, + 340.0957261190386, + 347.0890712411227 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.72182295421091, + "scoreError" : 2.3848719718328297, + "scoreConfidence" : [ + 111.33695098237808, + 116.10669492604373 + ], + "scorePercentiles" : { + "0.0" : 112.44458552038664, + "50.0" : 113.83317053044219, + "90.0" : 114.86895202500958, + "95.0" : 114.86895202500958, + "99.0" : 114.86895202500958, + "99.9" : 114.86895202500958, + "99.99" : 114.86895202500958, + "99.999" : 114.86895202500958, + "99.9999" : 114.86895202500958, + "100.0" : 114.86895202500958 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.13672828470678, + 114.21433083427812, + 114.00571746546578 + ], + [ + 112.44458552038664, + 113.6606235954186, + 114.86895202500958 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062395982043706937, + "scoreError" : 0.0011444521084475385, + "scoreConfidence" : [ + 0.0612515299352594, + 0.06354043415215448 + ], + "scorePercentiles" : { + "0.0" : 0.06184447802693911, + "50.0" : 0.0626117205685088, + "90.0" : 0.06272703167653552, + "95.0" : 0.06272703167653552, + "99.0" : 0.06272703167653552, + "99.9" : 0.06272703167653552, + "99.99" : 0.06272703167653552, + "99.999" : 0.06272703167653552, + "99.9999" : 0.06272703167653552, + "100.0" : 0.06272703167653552 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06261038335837717, + 0.06261305777864043, + 0.06272703167653552 + ], + [ + 0.06190078182741054, + 0.06184447802693911, + 0.0626801595943388 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.834644697716739E-4, + "scoreError" : 1.8133161136988404E-5, + "scoreConfidence" : [ + 3.653313086346855E-4, + 4.015976309086623E-4 + ], + "scorePercentiles" : { + "0.0" : 3.758408125828908E-4, + "50.0" : 3.8358266583541354E-4, + "90.0" : 3.9165436489979686E-4, + "95.0" : 3.9165436489979686E-4, + "99.0" : 3.9165436489979686E-4, + "99.9" : 3.9165436489979686E-4, + "99.99" : 3.9165436489979686E-4, + "99.999" : 3.9165436489979686E-4, + "99.9999" : 3.9165436489979686E-4, + "100.0" : 3.9165436489979686E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.758408125828908E-4, + 3.797167618284504E-4, + 3.7788432697965347E-4 + ], + [ + 3.8744856984237666E-4, + 3.8824198249687525E-4, + 3.9165436489979686E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.287399423749537, + "scoreError" : 0.05648190036612994, + "scoreConfidence" : [ + 2.230917523383407, + 2.343881324115667 + ], + "scorePercentiles" : { + "0.0" : 2.2303623320695807, + "50.0" : 2.2864320740596065, + "90.0" : 2.34749072976074, + "95.0" : 2.3501509534774434, + "99.0" : 2.3501509534774434, + "99.9" : 2.3501509534774434, + "99.99" : 2.3501509534774434, + "99.999" : 2.3501509534774434, + "99.9999" : 2.3501509534774434, + "100.0" : 2.3501509534774434 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.299269732643678, + 2.27613740873919, + 2.296726739380023, + 2.2730379295454544, + 2.273541474426006 + ], + [ + 2.323548716310409, + 2.3501509534774434, + 2.314549489932886, + 2.2366694609707, + 2.2303623320695807 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01363144268594813, + "scoreError" : 3.210461024017795E-4, + "scoreConfidence" : [ + 0.01331039658354635, + 0.01395248878834991 + ], + "scorePercentiles" : { + "0.0" : 0.013480149203131129, + "50.0" : 0.013644903103147591, + "90.0" : 0.013755843276160187, + "95.0" : 0.013755843276160187, + "99.0" : 0.013755843276160187, + "99.9" : 0.013755843276160187, + "99.99" : 0.013755843276160187, + "99.999" : 0.013755843276160187, + "99.9999" : 0.013755843276160187, + "100.0" : 0.013755843276160187 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013709053226038617, + 0.013755843276160187, + 0.0137278123115909 + ], + [ + 0.013580752980256565, + 0.01353504511851138, + 0.013480149203131129 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0274229580074778, + "scoreError" : 0.020567815223362575, + "scoreConfidence" : [ + 1.0068551427841153, + 1.0479907732308404 + ], + "scorePercentiles" : { + "0.0" : 1.017064719007424, + "50.0" : 1.0277226276139957, + "90.0" : 1.036484477458804, + "95.0" : 1.036484477458804, + "99.0" : 1.036484477458804, + "99.9" : 1.036484477458804, + "99.99" : 1.036484477458804, + "99.999" : 1.036484477458804, + "99.9999" : 1.036484477458804, + "100.0" : 1.036484477458804 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.036484477458804, + 1.0306988530351437, + 1.033314430460839 + ], + [ + 1.0222288658898089, + 1.017064719007424, + 1.0247464021928476 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010579283252758502, + "scoreError" : 7.87971924020664E-4, + "scoreConfidence" : [ + 0.009791311328737838, + 0.011367255176779166 + ], + "scorePercentiles" : { + "0.0" : 0.010289162674936158, + "50.0" : 0.010581860290922916, + "90.0" : 0.010874904633586707, + "95.0" : 0.010874904633586707, + "99.0" : 0.010874904633586707, + "99.9" : 0.010874904633586707, + "99.99" : 0.010874904633586707, + "99.999" : 0.010874904633586707, + "99.9999" : 0.010874904633586707, + "100.0" : 0.010874904633586707 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010289162674936158, + 0.010301363718210737, + 0.010388785761479327 + ], + [ + 0.010846547907971574, + 0.010774934820366507, + 0.010874904633586707 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.198229494752843, + "scoreError" : 0.3974107624382248, + "scoreConfidence" : [ + 2.8008187323146183, + 3.595640257191068 + ], + "scorePercentiles" : { + "0.0" : 3.0548731111789857, + "50.0" : 3.1678394153920157, + "90.0" : 3.3912169545762714, + "95.0" : 3.3912169545762714, + "99.0" : 3.3912169545762714, + "99.9" : 3.3912169545762714, + "99.99" : 3.3912169545762714, + "99.999" : 3.3912169545762714, + "99.9999" : 3.3912169545762714, + "100.0" : 3.3912169545762714 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.085570961752005, + 3.0879616574074076, + 3.0548731111789857 + ], + [ + 3.3220371102257635, + 3.3912169545762714, + 3.2477171733766235 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.867815433534951, + "scoreError" : 0.05507173609449702, + "scoreConfidence" : [ + 2.8127436974404536, + 2.922887169629448 + ], + "scorePercentiles" : { + "0.0" : 2.8462401346044395, + "50.0" : 2.8657226108916256, + "90.0" : 2.8929361298814, + "95.0" : 2.8929361298814, + "99.0" : 2.8929361298814, + "99.9" : 2.8929361298814, + "99.99" : 2.8929361298814, + "99.999" : 2.8929361298814, + "99.9999" : 2.8929361298814, + "100.0" : 2.8929361298814 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8462401346044395, + 2.849602194017094, + 2.8574765597142857 + ], + [ + 2.886668920923521, + 2.8929361298814, + 2.8739686620689655 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1811501483612857, + "scoreError" : 0.01407224194100451, + "scoreConfidence" : [ + 0.1670779064202812, + 0.19522239030229022 + ], + "scorePercentiles" : { + "0.0" : 0.1746134868083323, + "50.0" : 0.18238340268334705, + "90.0" : 0.18574356217611768, + "95.0" : 0.18574356217611768, + "99.0" : 0.18574356217611768, + "99.9" : 0.18574356217611768, + "99.99" : 0.18574356217611768, + "99.999" : 0.18574356217611768, + "99.9999" : 0.18574356217611768, + "100.0" : 0.18574356217611768 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1795984258903396, + 0.1746134868083323, + 0.17623028830733986 + ], + [ + 0.18554674750923023, + 0.18516837947635448, + 0.18574356217611768 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3452374280541257, + "scoreError" : 0.06544022307005015, + "scoreConfidence" : [ + 0.27979720498407556, + 0.41067765112417587 + ], + "scorePercentiles" : { + "0.0" : 0.3228209660726968, + "50.0" : 0.34423442750593003, + "90.0" : 0.3715529136912502, + "95.0" : 0.3715529136912502, + "99.0" : 0.3715529136912502, + "99.9" : 0.3715529136912502, + "99.99" : 0.3715529136912502, + "99.999" : 0.3715529136912502, + "99.9999" : 0.3715529136912502, + "100.0" : 0.3715529136912502 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3228209660726968, + 0.3251469417693533, + 0.32434703064997406 + ], + [ + 0.3715529136912502, + 0.364234802898973, + 0.3633219132425068 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1455967067783341, + "scoreError" : 0.0031735430006814046, + "scoreConfidence" : [ + 0.1424231637776527, + 0.1487702497790155 + ], + "scorePercentiles" : { + "0.0" : 0.14426401736897532, + "50.0" : 0.1456170108735834, + "90.0" : 0.14692406889104373, + "95.0" : 0.14692406889104373, + "99.0" : 0.14692406889104373, + "99.9" : 0.14692406889104373, + "99.99" : 0.14692406889104373, + "99.999" : 0.14692406889104373, + "99.9999" : 0.14692406889104373, + "100.0" : 0.14692406889104373 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14426401736897532, + 0.14444310967313276, + 0.14524037285230854 + ], + [ + 0.1467150229896862, + 0.14599364889485825, + 0.14692406889104373 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3970719375983826, + "scoreError" : 0.007360635333864862, + "scoreConfidence" : [ + 0.3897113022645177, + 0.4044325729322475 + ], + "scorePercentiles" : { + "0.0" : 0.39446546197538657, + "50.0" : 0.3969462258287454, + "90.0" : 0.4001840756332786, + "95.0" : 0.4001840756332786, + "99.0" : 0.4001840756332786, + "99.9" : 0.4001840756332786, + "99.99" : 0.4001840756332786, + "99.999" : 0.4001840756332786, + "99.9999" : 0.4001840756332786, + "100.0" : 0.4001840756332786 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.39446546197538657, + 0.39473431976790085, + 0.3949295263802227 + ], + [ + 0.4001840756332786, + 0.39915531655623854, + 0.398962925277268 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15628538885826707, + "scoreError" : 0.003218721364228217, + "scoreConfidence" : [ + 0.15306666749403885, + 0.15950411022249528 + ], + "scorePercentiles" : { + "0.0" : 0.15508311317711646, + "50.0" : 0.1563108235778879, + "90.0" : 0.15745303358208956, + "95.0" : 0.15745303358208956, + "99.0" : 0.15745303358208956, + "99.9" : 0.15745303358208956, + "99.99" : 0.15745303358208956, + "99.999" : 0.15745303358208956, + "99.9999" : 0.15745303358208956, + "100.0" : 0.15745303358208956 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15538224018396807, + 0.15526417690802957, + 0.15508311317711646 + ], + [ + 0.15729036232659097, + 0.15745303358208956, + 0.15723940697180774 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.047176598701910065, + "scoreError" : 0.0012509597036877182, + "scoreConfidence" : [ + 0.04592563899822235, + 0.04842755840559778 + ], + "scorePercentiles" : { + "0.0" : 0.04653195050463219, + "50.0" : 0.04724167716329663, + "90.0" : 0.04758861540804332, + "95.0" : 0.04758861540804332, + "99.0" : 0.04758861540804332, + "99.9" : 0.04758861540804332, + "99.99" : 0.04758861540804332, + "99.999" : 0.04758861540804332, + "99.9999" : 0.04758861540804332, + "100.0" : 0.04758861540804332 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.046960089691994875, + 0.04688329851054154, + 0.04653195050463219 + ], + [ + 0.04752326463459838, + 0.04758861540804332, + 0.04757237346165007 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8711442.049987761, + "scoreError" : 170063.394430552, + "scoreConfidence" : [ + 8541378.65555721, + 8881505.444418313 + ], + "scorePercentiles" : { + "0.0" : 8634824.708369283, + "50.0" : 8727806.282404942, + "90.0" : 8793714.970123023, + "95.0" : 8793714.970123023, + "99.0" : 8793714.970123023, + "99.9" : 8793714.970123023, + "99.99" : 8793714.970123023, + "99.999" : 8793714.970123023, + "99.9999" : 8793714.970123023, + "100.0" : 8793714.970123023 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8645903.43042351, + 8737359.46724891, + 8634824.708369283 + ], + [ + 8718253.097560976, + 8793714.970123023, + 8738596.626200873 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-03T05:39:19Z-f28e60c1f83f6218e8a5ccdd7c544c95d676684d-jdk17.json b/performance-results/2025-11-03T05:39:19Z-f28e60c1f83f6218e8a5ccdd7c544c95d676684d-jdk17.json new file mode 100644 index 0000000000..21738ca05e --- /dev/null +++ b/performance-results/2025-11-03T05:39:19Z-f28e60c1f83f6218e8a5ccdd7c544c95d676684d-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.34878606965172, + "scoreError" : 0.054919289121376676, + "scoreConfidence" : [ + 3.2938667805303434, + 3.4037053587730965 + ], + "scorePercentiles" : { + "0.0" : 3.339189284968844, + "50.0" : 3.3481622829193225, + "90.0" : 3.359630427799391, + "95.0" : 3.359630427799391, + "99.0" : 3.359630427799391, + "99.9" : 3.359630427799391, + "99.99" : 3.359630427799391, + "99.999" : 3.359630427799391, + "99.9999" : 3.359630427799391, + "100.0" : 3.359630427799391 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.346399718811323, + 3.359630427799391 + ], + [ + 3.339189284968844, + 3.349924847027322 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.693938428811356, + "scoreError" : 0.03404838941527292, + "scoreConfidence" : [ + 1.659890039396083, + 1.727986818226629 + ], + "scorePercentiles" : { + "0.0" : 1.6874096924326163, + "50.0" : 1.694619467333157, + "90.0" : 1.6991050881464935, + "95.0" : 1.6991050881464935, + "99.0" : 1.6991050881464935, + "99.9" : 1.6991050881464935, + "99.99" : 1.6991050881464935, + "99.999" : 1.6991050881464935, + "99.9999" : 1.6991050881464935, + "100.0" : 1.6991050881464935 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6971730441482407, + 1.6991050881464935 + ], + [ + 1.6920658905180732, + 1.6874096924326163 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8491484239698657, + "scoreError" : 0.04400095492111771, + "scoreConfidence" : [ + 0.805147469048748, + 0.8931493788909833 + ], + "scorePercentiles" : { + "0.0" : 0.8392460794092773, + "50.0" : 0.8512692893724247, + "90.0" : 0.854809037725336, + "95.0" : 0.854809037725336, + "99.0" : 0.854809037725336, + "99.9" : 0.854809037725336, + "99.99" : 0.854809037725336, + "99.999" : 0.854809037725336, + "99.9999" : 0.854809037725336, + "100.0" : 0.854809037725336 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8512559830154341, + 0.8512825957294153 + ], + [ + 0.8392460794092773, + 0.854809037725336 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.399613036279742, + "scoreError" : 0.10388828914932066, + "scoreConfidence" : [ + 16.29572474713042, + 16.503501325429063 + ], + "scorePercentiles" : { + "0.0" : 16.35411569024037, + "50.0" : 16.396037208898328, + "90.0" : 16.445764541055336, + "95.0" : 16.445764541055336, + "99.0" : 16.445764541055336, + "99.9" : 16.445764541055336, + "99.99" : 16.445764541055336, + "99.999" : 16.445764541055336, + "99.9999" : 16.445764541055336, + "100.0" : 16.445764541055336 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.445764541055336, + 16.435694396037384, + 16.41120292276357 + ], + [ + 16.37002917254871, + 16.38087149503308, + 16.35411569024037 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2754.850209368849, + "scoreError" : 44.099312945455075, + "scoreConfidence" : [ + 2710.750896423394, + 2798.949522314304 + ], + "scorePercentiles" : { + "0.0" : 2736.8428169579456, + "50.0" : 2754.0594272191156, + "90.0" : 2774.0030909413963, + "95.0" : 2774.0030909413963, + "99.0" : 2774.0030909413963, + "99.9" : 2774.0030909413963, + "99.99" : 2774.0030909413963, + "99.999" : 2774.0030909413963, + "99.9999" : 2774.0030909413963, + "100.0" : 2774.0030909413963 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2774.0030909413963, + 2763.4022542780353, + 2768.661470436311 + ], + [ + 2741.4750234392086, + 2744.716600160196, + 2736.8428169579456 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 71742.34723503793, + "scoreError" : 1296.2451233409079, + "scoreConfidence" : [ + 70446.10211169702, + 73038.59235837884 + ], + "scorePercentiles" : { + "0.0" : 71279.37123475065, + "50.0" : 71761.52672694647, + "90.0" : 72220.81173347631, + "95.0" : 72220.81173347631, + "99.0" : 72220.81173347631, + "99.9" : 72220.81173347631, + "99.99" : 72220.81173347631, + "99.999" : 72220.81173347631, + "99.9999" : 72220.81173347631, + "100.0" : 72220.81173347631 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72220.81173347631, + 72125.57245792563, + 72138.43197988952 + ], + [ + 71279.37123475065, + 71292.41500821811, + 71397.4809959673 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 369.37929912629926, + "scoreError" : 18.243374911111466, + "scoreConfidence" : [ + 351.1359242151878, + 387.6226740374107 + ], + "scorePercentiles" : { + "0.0" : 363.05767368353474, + "50.0" : 369.3683557305564, + "90.0" : 375.6515112410154, + "95.0" : 375.6515112410154, + "99.0" : 375.6515112410154, + "99.9" : 375.6515112410154, + "99.99" : 375.6515112410154, + "99.999" : 375.6515112410154, + "99.9999" : 375.6515112410154, + "100.0" : 375.6515112410154 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 363.6373850241265, + 363.05767368353474, + 363.6430650598611 + ], + [ + 375.0936464012517, + 375.192513348006, + 375.6515112410154 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.17908600423998, + "scoreError" : 4.559808918512926, + "scoreConfidence" : [ + 110.61927708572705, + 119.7388949227529 + ], + "scorePercentiles" : { + "0.0" : 113.5002174415385, + "50.0" : 115.2346315387374, + "90.0" : 116.9522325096579, + "95.0" : 116.9522325096579, + "99.0" : 116.9522325096579, + "99.9" : 116.9522325096579, + "99.99" : 116.9522325096579, + "99.999" : 116.9522325096579, + "99.9999" : 116.9522325096579, + "100.0" : 116.9522325096579 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 116.9522325096579, + 116.64181400092161, + 116.31389231373902 + ], + [ + 113.5002174415385, + 113.51098899584704, + 114.15537076373579 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060782098381352366, + "scoreError" : 5.805433432615847E-4, + "scoreConfidence" : [ + 0.060201555038090784, + 0.06136264172461395 + ], + "scorePercentiles" : { + "0.0" : 0.06052403259172285, + "50.0" : 0.060793818844840405, + "90.0" : 0.061002763222106994, + "95.0" : 0.061002763222106994, + "99.0" : 0.061002763222106994, + "99.9" : 0.061002763222106994, + "99.99" : 0.061002763222106994, + "99.999" : 0.061002763222106994, + "99.9999" : 0.061002763222106994, + "100.0" : 0.061002763222106994 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06093795618632087, + 0.06095802715025907, + 0.061002763222106994 + ], + [ + 0.06064968150335994, + 0.06052403259172285, + 0.06062012963434446 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.721377179285996E-4, + "scoreError" : 5.920970720784705E-5, + "scoreConfidence" : [ + 3.1292801072075254E-4, + 4.313474251364466E-4 + ], + "scorePercentiles" : { + "0.0" : 3.522345232547696E-4, + "50.0" : 3.7216431256680016E-4, + "90.0" : 3.9180112321753215E-4, + "95.0" : 3.9180112321753215E-4, + "99.0" : 3.9180112321753215E-4, + "99.9" : 3.9180112321753215E-4, + "99.99" : 3.9180112321753215E-4, + "99.999" : 3.9180112321753215E-4, + "99.9999" : 3.9180112321753215E-4, + "100.0" : 3.9180112321753215E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5340331120211124E-4, + 3.529643639188084E-4, + 3.522345232547696E-4 + ], + [ + 3.909253139314891E-4, + 3.9149767204688676E-4, + 3.9180112321753215E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2314491388984314, + "scoreError" : 0.052739180611990705, + "scoreConfidence" : [ + 2.178709958286441, + 2.284188319510422 + ], + "scorePercentiles" : { + "0.0" : 2.1795928640226627, + "50.0" : 2.2286018949347404, + "90.0" : 2.2877012800566874, + "95.0" : 2.289715370650183, + "99.0" : 2.289715370650183, + "99.9" : 2.289715370650183, + "99.99" : 2.289715370650183, + "99.999" : 2.289715370650183, + "99.9999" : 2.289715370650183, + "100.0" : 2.289715370650183 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.253824037863421, + 2.2216473258551757, + 2.235556464014305, + 2.184422264525994, + 2.1795928640226627 + ], + [ + 2.289715370650183, + 2.245367233722497, + 2.269574464715226, + 2.2178781332889774, + 2.2169132303258703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01330657690880029, + "scoreError" : 4.72080511413149E-5, + "scoreConfidence" : [ + 0.013259368857658976, + 0.013353784959941606 + ], + "scorePercentiles" : { + "0.0" : 0.013287191297011088, + "50.0" : 0.013302617131281133, + "90.0" : 0.013328422127028894, + "95.0" : 0.013328422127028894, + "99.0" : 0.013328422127028894, + "99.9" : 0.013328422127028894, + "99.99" : 0.013328422127028894, + "99.999" : 0.013328422127028894, + "99.9999" : 0.013328422127028894, + "100.0" : 0.013328422127028894 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013309592061447056, + 0.013323806541096028, + 0.013328422127028894 + ], + [ + 0.013294807225103466, + 0.013287191297011088, + 0.01329564220111521 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0224144251013123, + "scoreError" : 0.08695241366628681, + "scoreConfidence" : [ + 0.9354620114350255, + 1.109366838767599 + ], + "scorePercentiles" : { + "0.0" : 0.9934269251018178, + "50.0" : 1.0218864224021, + "90.0" : 1.0535551176780447, + "95.0" : 1.0535551176780447, + "99.0" : 1.0535551176780447, + "99.9" : 1.0535551176780447, + "99.99" : 1.0535551176780447, + "99.999" : 1.0535551176780447, + "99.9999" : 1.0535551176780447, + "100.0" : 1.0535551176780447 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0483554215932913, + 1.0501068327207812, + 1.0535551176780447 + ], + [ + 0.9936248303030303, + 0.9934269251018178, + 0.9954174232109088 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010743469306970834, + "scoreError" : 5.812565370481378E-4, + "scoreConfidence" : [ + 0.010162212769922697, + 0.011324725844018972 + ], + "scorePercentiles" : { + "0.0" : 0.01055238825763971, + "50.0" : 0.01074301251495343, + "90.0" : 0.010934640921904078, + "95.0" : 0.010934640921904078, + "99.0" : 0.010934640921904078, + "99.9" : 0.010934640921904078, + "99.99" : 0.010934640921904078, + "99.999" : 0.010934640921904078, + "99.9999" : 0.010934640921904078, + "100.0" : 0.010934640921904078 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010933654741601729, + 0.010934640921904078, + 0.010929748799398443 + ], + [ + 0.01055238825763971, + 0.010554106890772621, + 0.010556276230508418 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.99824403795847, + "scoreError" : 0.04669198008056282, + "scoreConfidence" : [ + 2.951552057877907, + 3.044936018039033 + ], + "scorePercentiles" : { + "0.0" : 2.982036313059034, + "50.0" : 2.9951447591789404, + "90.0" : 3.0231775362756954, + "95.0" : 3.0231775362756954, + "99.0" : 3.0231775362756954, + "99.9" : 3.0231775362756954, + "99.99" : 3.0231775362756954, + "99.999" : 3.0231775362756954, + "99.9999" : 3.0231775362756954, + "100.0" : 3.0231775362756954 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9876025519713263, + 2.9834581628878283, + 2.982036313059034 + ], + [ + 3.0105026971703794, + 3.0231775362756954, + 3.0026869663865545 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7203368005928628, + "scoreError" : 0.21779713240122703, + "scoreConfidence" : [ + 2.502539668191636, + 2.9381339329940896 + ], + "scorePercentiles" : { + "0.0" : 2.6395366215360254, + "50.0" : 2.720006403100175, + "90.0" : 2.801366812044818, + "95.0" : 2.801366812044818, + "99.0" : 2.801366812044818, + "99.9" : 2.801366812044818, + "99.99" : 2.801366812044818, + "99.999" : 2.801366812044818, + "99.9999" : 2.801366812044818, + "100.0" : 2.801366812044818 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.801366812044818, + 2.788420324783942, + 2.7826763208124654 + ], + [ + 2.6573364853878854, + 2.6395366215360254, + 2.6526842389920424 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17783119663908956, + "scoreError" : 0.006615158104344093, + "scoreConfidence" : [ + 0.17121603853474546, + 0.18444635474343365 + ], + "scorePercentiles" : { + "0.0" : 0.17552657107752795, + "50.0" : 0.17784160479584976, + "90.0" : 0.18044190271187052, + "95.0" : 0.18044190271187052, + "99.0" : 0.18044190271187052, + "99.9" : 0.18044190271187052, + "99.99" : 0.18044190271187052, + "99.999" : 0.18044190271187052, + "99.9999" : 0.18044190271187052, + "100.0" : 0.18044190271187052 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17597202289364397, + 0.17558764173968008, + 0.17552657107752795 + ], + [ + 0.18044190271187052, + 0.17974785471375931, + 0.17971118669805555 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32775898600507747, + "scoreError" : 0.014894209038956215, + "scoreConfidence" : [ + 0.31286477696612125, + 0.3426531950440337 + ], + "scorePercentiles" : { + "0.0" : 0.32217470911726803, + "50.0" : 0.3282566234125877, + "90.0" : 0.3336024789672082, + "95.0" : 0.3336024789672082, + "99.0" : 0.3336024789672082, + "99.9" : 0.3336024789672082, + "99.99" : 0.3336024789672082, + "99.999" : 0.3336024789672082, + "99.9999" : 0.3336024789672082, + "100.0" : 0.3336024789672082 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32460995296523515, + 0.322240590416962, + 0.32217470911726803 + ], + [ + 0.33202289070385127, + 0.3336024789672082, + 0.3319032938599403 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14693683787283682, + "scoreError" : 0.008757927502277536, + "scoreConfidence" : [ + 0.1381789103705593, + 0.15569476537511434 + ], + "scorePercentiles" : { + "0.0" : 0.1439829489446252, + "50.0" : 0.14697574673266522, + "90.0" : 0.1498390602637099, + "95.0" : 0.1498390602637099, + "99.0" : 0.1498390602637099, + "99.9" : 0.1498390602637099, + "99.99" : 0.1498390602637099, + "99.999" : 0.1498390602637099, + "99.9999" : 0.1498390602637099, + "100.0" : 0.1498390602637099 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1442613120744374, + 0.1439829489446252, + 0.14401836664890477 + ], + [ + 0.14982915791445053, + 0.1498390602637099, + 0.14969018139089305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4080560238612739, + "scoreError" : 0.006385642299664086, + "scoreConfidence" : [ + 0.4016703815616098, + 0.41444166616093797 + ], + "scorePercentiles" : { + "0.0" : 0.40645890355226794, + "50.0" : 0.4068837434540745, + "90.0" : 0.41232288171023335, + "95.0" : 0.41232288171023335, + "99.0" : 0.41232288171023335, + "99.9" : 0.41232288171023335, + "99.99" : 0.41232288171023335, + "99.999" : 0.41232288171023335, + "99.9999" : 0.41232288171023335, + "100.0" : 0.41232288171023335 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41232288171023335, + 0.4089799215197121, + 0.40645890355226794 + ], + [ + 0.406806949477281, + 0.40681796489301114, + 0.40694952201513795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15853079979898202, + "scoreError" : 0.014277353656815107, + "scoreConfidence" : [ + 0.14425344614216692, + 0.17280815345579711 + ], + "scorePercentiles" : { + "0.0" : 0.15373089412759416, + "50.0" : 0.1582324745447997, + "90.0" : 0.16398364462227177, + "95.0" : 0.16398364462227177, + "99.0" : 0.16398364462227177, + "99.9" : 0.16398364462227177, + "99.99" : 0.16398364462227177, + "99.999" : 0.16398364462227177, + "99.9999" : 0.16398364462227177, + "100.0" : 0.16398364462227177 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15408377120537434, + 0.15373089412759416, + 0.15390710162213742 + ], + [ + 0.16309820933228952, + 0.16398364462227177, + 0.16238117788422504 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046879353624185015, + "scoreError" : 0.001446976764769169, + "scoreConfidence" : [ + 0.04543237685941585, + 0.04832633038895418 + ], + "scorePercentiles" : { + "0.0" : 0.04622852423261834, + "50.0" : 0.04711900832021206, + "90.0" : 0.04729292747763086, + "95.0" : 0.04729292747763086, + "99.0" : 0.04729292747763086, + "99.9" : 0.04729292747763086, + "99.99" : 0.04729292747763086, + "99.999" : 0.04729292747763086, + "99.9999" : 0.04729292747763086, + "100.0" : 0.04729292747763086 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04696899968061622, + 0.04622852423261834, + 0.04623510637619112 + ], + [ + 0.04729292747763086, + 0.04728154701824561, + 0.047269016959807904 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8663474.17094701, + "scoreError" : 260291.04713927515, + "scoreConfidence" : [ + 8403183.123807734, + 8923765.218086286 + ], + "scorePercentiles" : { + "0.0" : 8563190.721746575, + "50.0" : 8654325.470320448, + "90.0" : 8775574.314035088, + "95.0" : 8775574.314035088, + "99.0" : 8775574.314035088, + "99.9" : 8775574.314035088, + "99.99" : 8775574.314035088, + "99.999" : 8775574.314035088, + "99.9999" : 8775574.314035088, + "100.0" : 8775574.314035088 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8775574.314035088, + 8750551.975503063, + 8710051.79373368 + ], + [ + 8582877.073756432, + 8563190.721746575, + 8598599.146907216 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-06T00:14:45Z-71e6199af4a1fd32da0685cd24093765b47cead1-jdk17.json b/performance-results/2025-11-06T00:14:45Z-71e6199af4a1fd32da0685cd24093765b47cead1-jdk17.json new file mode 100644 index 0000000000..341fca9542 --- /dev/null +++ b/performance-results/2025-11-06T00:14:45Z-71e6199af4a1fd32da0685cd24093765b47cead1-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3252757104157276, + "scoreError" : 0.06472528322216695, + "scoreConfidence" : [ + 3.260550427193561, + 3.3900009936378943 + ], + "scorePercentiles" : { + "0.0" : 3.3129222498085946, + "50.0" : 3.3256795310412564, + "90.0" : 3.3368215297718034, + "95.0" : 3.3368215297718034, + "99.0" : 3.3368215297718034, + "99.9" : 3.3368215297718034, + "99.99" : 3.3368215297718034, + "99.999" : 3.3368215297718034, + "99.9999" : 3.3368215297718034, + "100.0" : 3.3368215297718034 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3368215297718034, + 3.3129222498085946 + ], + [ + 3.3229648233487823, + 3.328394238733731 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6751096195277564, + "scoreError" : 0.041776852007068814, + "scoreConfidence" : [ + 1.6333327675206877, + 1.716886471534825 + ], + "scorePercentiles" : { + "0.0" : 1.6685044407193181, + "50.0" : 1.6747552731318907, + "90.0" : 1.6824234911279259, + "95.0" : 1.6824234911279259, + "99.0" : 1.6824234911279259, + "99.9" : 1.6824234911279259, + "99.99" : 1.6824234911279259, + "99.999" : 1.6824234911279259, + "99.9999" : 1.6824234911279259, + "100.0" : 1.6824234911279259 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6824234911279259, + 1.6784980658076352 + ], + [ + 1.6685044407193181, + 1.6710124804561464 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8434749232028882, + "scoreError" : 0.03552907308030231, + "scoreConfidence" : [ + 0.8079458501225859, + 0.8790039962831905 + ], + "scorePercentiles" : { + "0.0" : 0.8356147758363387, + "50.0" : 0.8449282249692869, + "90.0" : 0.84842846703664, + "95.0" : 0.84842846703664, + "99.0" : 0.84842846703664, + "99.9" : 0.84842846703664, + "99.99" : 0.84842846703664, + "99.999" : 0.84842846703664, + "99.9999" : 0.84842846703664, + "100.0" : 0.84842846703664 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8356147758363387, + 0.8451981478476167 + ], + [ + 0.8446583020909572, + 0.84842846703664 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.868495055785246, + "scoreError" : 0.8309093421598696, + "scoreConfidence" : [ + 15.037585713625376, + 16.699404397945116 + ], + "scorePercentiles" : { + "0.0" : 15.525602218949441, + "50.0" : 15.872134635576593, + "90.0" : 16.252404455250627, + "95.0" : 16.252404455250627, + "99.0" : 16.252404455250627, + "99.9" : 16.252404455250627, + "99.99" : 16.252404455250627, + "99.999" : 16.252404455250627, + "99.9999" : 16.252404455250627, + "100.0" : 16.252404455250627 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.569393434629545, + 15.525602218949441, + 15.768103147846682 + ], + [ + 16.252404455250627, + 15.976166123306504, + 16.119300954728686 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2692.621747523342, + "scoreError" : 104.8033504903957, + "scoreConfidence" : [ + 2587.8183970329465, + 2797.4250980137376 + ], + "scorePercentiles" : { + "0.0" : 2651.0399838499584, + "50.0" : 2681.8023326221028, + "90.0" : 2746.3300042556884, + "95.0" : 2746.3300042556884, + "99.0" : 2746.3300042556884, + "99.9" : 2746.3300042556884, + "99.99" : 2746.3300042556884, + "99.999" : 2746.3300042556884, + "99.9999" : 2746.3300042556884, + "100.0" : 2746.3300042556884 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2665.048706172474, + 2651.0399838499584, + 2681.2111914805373 + ], + [ + 2682.393473763668, + 2729.707125617724, + 2746.3300042556884 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72738.70926471605, + "scoreError" : 1238.1413004583924, + "scoreConfidence" : [ + 71500.56796425766, + 73976.85056517443 + ], + "scorePercentiles" : { + "0.0" : 72108.79340450934, + "50.0" : 72700.32146032978, + "90.0" : 73396.41457712303, + "95.0" : 73396.41457712303, + "99.0" : 73396.41457712303, + "99.9" : 73396.41457712303, + "99.99" : 73396.41457712303, + "99.999" : 73396.41457712303, + "99.9999" : 73396.41457712303, + "100.0" : 73396.41457712303 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72108.79340450934, + 72662.2231436045, + 72500.20314489643 + ], + [ + 72738.41977705508, + 73396.41457712303, + 73026.2015411079 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 353.85498851942856, + "scoreError" : 13.419519871851167, + "scoreConfidence" : [ + 340.4354686475774, + 367.2745083912797 + ], + "scorePercentiles" : { + "0.0" : 345.8897868430859, + "50.0" : 354.31505696571884, + "90.0" : 359.2356186186731, + "95.0" : 359.2356186186731, + "99.0" : 359.2356186186731, + "99.9" : 359.2356186186731, + "99.99" : 359.2356186186731, + "99.999" : 359.2356186186731, + "99.9999" : 359.2356186186731, + "100.0" : 359.2356186186731 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 345.8897868430859, + 352.68449711809706, + 351.9499697134903 + ], + [ + 355.9456168133406, + 357.4244420098842, + 359.2356186186731 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 111.6344897214568, + "scoreError" : 2.550967283187546, + "scoreConfidence" : [ + 109.08352243826926, + 114.18545700464435 + ], + "scorePercentiles" : { + "0.0" : 110.16476093693053, + "50.0" : 111.75865956817216, + "90.0" : 112.50203199301812, + "95.0" : 112.50203199301812, + "99.0" : 112.50203199301812, + "99.9" : 112.50203199301812, + "99.99" : 112.50203199301812, + "99.999" : 112.50203199301812, + "99.9999" : 112.50203199301812, + "100.0" : 112.50203199301812 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.15547982936997, + 112.12682840886913, + 110.16476093693053 + ], + [ + 112.50203199301812, + 111.39049072747518, + 112.46734643307785 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06262044897520276, + "scoreError" : 0.001452351480495483, + "scoreConfidence" : [ + 0.06116809749470728, + 0.06407280045569824 + ], + "scorePercentiles" : { + "0.0" : 0.06184608550100808, + "50.0" : 0.06274666092628206, + "90.0" : 0.0631932205904656, + "95.0" : 0.0631932205904656, + "99.0" : 0.0631932205904656, + "99.9" : 0.0631932205904656, + "99.99" : 0.0631932205904656, + "99.999" : 0.0631932205904656, + "99.9999" : 0.0631932205904656, + "100.0" : 0.0631932205904656 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06281132435980379, + 0.0631932205904656, + 0.06302630956657654 + ], + [ + 0.062163756340602234, + 0.06268199749276035, + 0.06184608550100808 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 4.049967617749583E-4, + "scoreError" : 5.8395599119734644E-5, + "scoreConfidence" : [ + 3.4660116265522364E-4, + 4.6339236089469295E-4 + ], + "scorePercentiles" : { + "0.0" : 3.858400611729819E-4, + "50.0" : 4.023530067271767E-4, + "90.0" : 4.2947091715562645E-4, + "95.0" : 4.2947091715562645E-4, + "99.0" : 4.2947091715562645E-4, + "99.9" : 4.2947091715562645E-4, + "99.99" : 4.2947091715562645E-4, + "99.999" : 4.2947091715562645E-4, + "99.9999" : 4.2947091715562645E-4, + "100.0" : 4.2947091715562645E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 4.179272262588647E-4, + 4.237331849554373E-4, + 4.2947091715562645E-4 + ], + [ + 3.858400611729819E-4, + 3.867787871954887E-4, + 3.862303939113504E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.5268449773627024, + "scoreError" : 0.23233352104652552, + "scoreConfidence" : [ + 2.294511456316177, + 2.759178498409228 + ], + "scorePercentiles" : { + "0.0" : 2.3110673911737525, + "50.0" : 2.5411378190594025, + "90.0" : 2.7107896177794957, + "95.0" : 2.7113587820547576, + "99.0" : 2.7113587820547576, + "99.9" : 2.7113587820547576, + "99.99" : 2.7113587820547576, + "99.999" : 2.7113587820547576, + "99.9999" : 2.7113587820547576, + "100.0" : 2.7113587820547576 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.705667139302137, + 2.7113587820547576, + 2.643921308485329, + 2.6371633996836277, + 2.6298799463581384 + ], + [ + 2.4401083125152474, + 2.452395691760667, + 2.378891284490961, + 2.3110673911737525, + 2.357996517802405 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013748809439801946, + "scoreError" : 6.150439167861335E-4, + "scoreConfidence" : [ + 0.013133765523015812, + 0.01436385335658808 + ], + "scorePercentiles" : { + "0.0" : 0.013462063923443172, + "50.0" : 0.013769455643650966, + "90.0" : 0.013985409888384023, + "95.0" : 0.013985409888384023, + "99.0" : 0.013985409888384023, + "99.9" : 0.013985409888384023, + "99.99" : 0.013985409888384023, + "99.999" : 0.013985409888384023, + "99.9999" : 0.013985409888384023, + "100.0" : 0.013985409888384023 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01392866188733803, + 0.013910676045131253, + 0.013985409888384023 + ], + [ + 0.013628235242170678, + 0.013577809652344518, + 0.013462063923443172 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0285888079379262, + "scoreError" : 0.014867831220400838, + "scoreConfidence" : [ + 1.0137209767175253, + 1.043456639158327 + ], + "scorePercentiles" : { + "0.0" : 1.0206090354117767, + "50.0" : 1.0284222566239403, + "90.0" : 1.0362132003937417, + "95.0" : 1.0362132003937417, + "99.0" : 1.0362132003937417, + "99.9" : 1.0362132003937417, + "99.99" : 1.0362132003937417, + "99.999" : 1.0362132003937417, + "99.9999" : 1.0362132003937417, + "100.0" : 1.0362132003937417 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0276546513563503, + 1.0318722327692942, + 1.0206090354117767 + ], + [ + 1.025993865804863, + 1.0362132003937417, + 1.0291898618915303 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.011076871219711354, + "scoreError" : 3.8401532825164676E-4, + "scoreConfidence" : [ + 0.010692855891459708, + 0.011460886547963 + ], + "scorePercentiles" : { + "0.0" : 0.010918657431165013, + "50.0" : 0.01102912658521347, + "90.0" : 0.011272657752467524, + "95.0" : 0.011272657752467524, + "99.0" : 0.011272657752467524, + "99.9" : 0.011272657752467524, + "99.99" : 0.011272657752467524, + "99.999" : 0.011272657752467524, + "99.9999" : 0.011272657752467524, + "100.0" : 0.011272657752467524 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010918657431165013, + 0.01103771664930111, + 0.01102053652112583 + ], + [ + 0.010996239586288495, + 0.011215419377920135, + 0.011272657752467524 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1106708456208594, + "scoreError" : 0.08235553134905174, + "scoreConfidence" : [ + 3.028315314271808, + 3.193026376969911 + ], + "scorePercentiles" : { + "0.0" : 3.0847934194941393, + "50.0" : 3.1004373022028906, + "90.0" : 3.158215380050505, + "95.0" : 3.158215380050505, + "99.0" : 3.158215380050505, + "99.9" : 3.158215380050505, + "99.99" : 3.158215380050505, + "99.999" : 3.158215380050505, + "99.9999" : 3.158215380050505, + "100.0" : 3.158215380050505 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0898210105003088, + 3.088311711728395, + 3.0847934194941393 + ], + [ + 3.1110535939054724, + 3.1318299580463367, + 3.158215380050505 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8598359598135876, + "scoreError" : 0.06665401379218214, + "scoreConfidence" : [ + 2.7931819460214053, + 2.92648997360577 + ], + "scorePercentiles" : { + "0.0" : 2.8339095848682345, + "50.0" : 2.8585101837086606, + "90.0" : 2.8850892177675225, + "95.0" : 2.8850892177675225, + "99.0" : 2.8850892177675225, + "99.9" : 2.8850892177675225, + "99.99" : 2.8850892177675225, + "99.999" : 2.8850892177675225, + "99.9999" : 2.8850892177675225, + "100.0" : 2.8850892177675225 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8389182171444793, + 2.8339095848682345, + 2.842917378624218 + ], + [ + 2.8840783716839677, + 2.8850892177675225, + 2.8741029887931036 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17927078875273736, + "scoreError" : 0.0036462522880476547, + "scoreConfidence" : [ + 0.1756245364646897, + 0.18291704104078502 + ], + "scorePercentiles" : { + "0.0" : 0.17782959429181114, + "50.0" : 0.17891155434168857, + "90.0" : 0.18168540676210893, + "95.0" : 0.18168540676210893, + "99.0" : 0.18168540676210893, + "99.9" : 0.18168540676210893, + "99.99" : 0.18168540676210893, + "99.999" : 0.18168540676210893, + "99.9999" : 0.18168540676210893, + "100.0" : 0.18168540676210893 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18168540676210893, + 0.1789295917695473, + 0.17782959429181114 + ], + [ + 0.17878618297370255, + 0.17889351691382982, + 0.17950043980542443 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32775948015502393, + "scoreError" : 0.003472351474260248, + "scoreConfidence" : [ + 0.3242871286807637, + 0.33123183162928416 + ], + "scorePercentiles" : { + "0.0" : 0.3260457674350363, + "50.0" : 0.32777740607739136, + "90.0" : 0.3291492522217102, + "95.0" : 0.3291492522217102, + "99.0" : 0.3291492522217102, + "99.9" : 0.3291492522217102, + "99.99" : 0.3291492522217102, + "99.999" : 0.3291492522217102, + "99.9999" : 0.3291492522217102, + "100.0" : 0.3291492522217102 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3276673376802097, + 0.32907227694231467, + 0.3291492522217102 + ], + [ + 0.32673477217629954, + 0.3260457674350363, + 0.32788747447457295 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14596437023710027, + "scoreError" : 0.00724584985826108, + "scoreConfidence" : [ + 0.1387185203788392, + 0.15321022009536134 + ], + "scorePercentiles" : { + "0.0" : 0.1431149839000515, + "50.0" : 0.1462734980820382, + "90.0" : 0.1487656560798548, + "95.0" : 0.1487656560798548, + "99.0" : 0.1487656560798548, + "99.9" : 0.1487656560798548, + "99.99" : 0.1487656560798548, + "99.999" : 0.1487656560798548, + "99.9999" : 0.1487656560798548, + "100.0" : 0.1487656560798548 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1487656560798548, + 0.1478452815641632, + 0.1481412893859714 + ], + [ + 0.1431149839000515, + 0.14470171459991318, + 0.14321729589264745 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4005924655150199, + "scoreError" : 0.011973160973363506, + "scoreConfidence" : [ + 0.38861930454165644, + 0.4125656264883834 + ], + "scorePercentiles" : { + "0.0" : 0.3958047031188158, + "50.0" : 0.40076383835291796, + "90.0" : 0.4078505327079935, + "95.0" : 0.4078505327079935, + "99.0" : 0.4078505327079935, + "99.9" : 0.4078505327079935, + "99.99" : 0.4078505327079935, + "99.999" : 0.4078505327079935, + "99.9999" : 0.4078505327079935, + "100.0" : 0.4078505327079935 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40059628220637716, + 0.3967901241122089, + 0.3958047031188158 + ], + [ + 0.4078505327079935, + 0.40158175644526545, + 0.40093139449945875 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15795696320790106, + "scoreError" : 0.00621714164070581, + "scoreConfidence" : [ + 0.15173982156719526, + 0.16417410484860687 + ], + "scorePercentiles" : { + "0.0" : 0.15541324264134523, + "50.0" : 0.15794075923534617, + "90.0" : 0.1604735391626683, + "95.0" : 0.1604735391626683, + "99.0" : 0.1604735391626683, + "99.9" : 0.1604735391626683, + "99.99" : 0.1604735391626683, + "99.999" : 0.1604735391626683, + "99.9999" : 0.1604735391626683, + "100.0" : 0.1604735391626683 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1598801501087165, + 0.1604735391626683, + 0.15945758538763274 + ], + [ + 0.15609332886398403, + 0.15541324264134523, + 0.1564239330830596 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04689798592153349, + "scoreError" : 6.687616980002682E-4, + "scoreConfidence" : [ + 0.046229224223533226, + 0.04756674761953376 + ], + "scorePercentiles" : { + "0.0" : 0.04659923983336362, + "50.0" : 0.046839958484034126, + "90.0" : 0.04719165077275194, + "95.0" : 0.04719165077275194, + "99.0" : 0.04719165077275194, + "99.9" : 0.04719165077275194, + "99.99" : 0.04719165077275194, + "99.999" : 0.04719165077275194, + "99.9999" : 0.04719165077275194, + "100.0" : 0.04719165077275194 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04717612, + 0.046740987955017105, + 0.04659923983336362 + ], + [ + 0.04719165077275194, + 0.04684862903067128, + 0.04683128793739697 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8837974.717597118, + "scoreError" : 387665.8953735547, + "scoreConfidence" : [ + 8450308.822223563, + 9225640.612970673 + ], + "scorePercentiles" : { + "0.0" : 8625197.588793103, + "50.0" : 8861546.72299222, + "90.0" : 8988541.389937107, + "95.0" : 8988541.389937107, + "99.0" : 8988541.389937107, + "99.9" : 8988541.389937107, + "99.99" : 8988541.389937107, + "99.999" : 8988541.389937107, + "99.9999" : 8988541.389937107, + "100.0" : 8988541.389937107 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8988541.389937107, + 8908523.016028496, + 8950332.05903399 + ], + [ + 8740683.821834061, + 8814570.429955946, + 8625197.588793103 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-08T05:56:43Z-6ce63f3531d032fa4c15ea8d5b4c4c3bbf0a95b7-jdk17.json b/performance-results/2025-11-08T05:56:43Z-6ce63f3531d032fa4c15ea8d5b4c4c3bbf0a95b7-jdk17.json new file mode 100644 index 0000000000..0a5017cc50 --- /dev/null +++ b/performance-results/2025-11-08T05:56:43Z-6ce63f3531d032fa4c15ea8d5b4c4c3bbf0a95b7-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3594005063950316, + "scoreError" : 0.05526945491621342, + "scoreConfidence" : [ + 3.304131051478818, + 3.4146699613112452 + ], + "scorePercentiles" : { + "0.0" : 3.348505528093966, + "50.0" : 3.360982329148857, + "90.0" : 3.367131839188446, + "95.0" : 3.367131839188446, + "99.0" : 3.367131839188446, + "99.9" : 3.367131839188446, + "99.99" : 3.367131839188446, + "99.999" : 3.367131839188446, + "99.9999" : 3.367131839188446, + "100.0" : 3.367131839188446 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3652239986488364, + 3.367131839188446 + ], + [ + 3.348505528093966, + 3.3567406596488776 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6942069299215068, + "scoreError" : 0.04807019269754271, + "scoreConfidence" : [ + 1.6461367372239641, + 1.7422771226190494 + ], + "scorePercentiles" : { + "0.0" : 1.6882447851570228, + "50.0" : 1.6920894032795653, + "90.0" : 1.704404127969874, + "95.0" : 1.704404127969874, + "99.0" : 1.704404127969874, + "99.9" : 1.704404127969874, + "99.99" : 1.704404127969874, + "99.999" : 1.704404127969874, + "99.9999" : 1.704404127969874, + "100.0" : 1.704404127969874 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6882447851570228, + 1.6891301350916106 + ], + [ + 1.69504867146752, + 1.704404127969874 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8538762986747745, + "scoreError" : 0.02206920080077257, + "scoreConfidence" : [ + 0.831807097874002, + 0.8759454994755471 + ], + "scorePercentiles" : { + "0.0" : 0.8508833529624418, + "50.0" : 0.8537160805690689, + "90.0" : 0.8571896805985186, + "95.0" : 0.8571896805985186, + "99.0" : 0.8571896805985186, + "99.9" : 0.8571896805985186, + "99.99" : 0.8571896805985186, + "99.999" : 0.8571896805985186, + "99.9999" : 0.8571896805985186, + "100.0" : 0.8571896805985186 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8571896805985186, + 0.8564550485339744 + ], + [ + 0.8508833529624418, + 0.8509771126041635 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.473431108381195, + "scoreError" : 0.07380222387260409, + "scoreConfidence" : [ + 16.39962888450859, + 16.5472333322538 + ], + "scorePercentiles" : { + "0.0" : 16.443510549816846, + "50.0" : 16.464783905525067, + "90.0" : 16.517475596880036, + "95.0" : 16.517475596880036, + "99.0" : 16.517475596880036, + "99.9" : 16.517475596880036, + "99.99" : 16.517475596880036, + "99.999" : 16.517475596880036, + "99.9999" : 16.517475596880036, + "100.0" : 16.517475596880036 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.490404780528415, + 16.517475596880036, + 16.464767937328308 + ], + [ + 16.46479987372183, + 16.45962791201173, + 16.443510549816846 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2754.845630443546, + "scoreError" : 167.06791644507962, + "scoreConfidence" : [ + 2587.7777139984664, + 2921.913546888625 + ], + "scorePercentiles" : { + "0.0" : 2699.483376401566, + "50.0" : 2753.7120586850383, + "90.0" : 2811.1564890745117, + "95.0" : 2811.1564890745117, + "99.0" : 2811.1564890745117, + "99.9" : 2811.1564890745117, + "99.99" : 2811.1564890745117, + "99.999" : 2811.1564890745117, + "99.9999" : 2811.1564890745117, + "100.0" : 2811.1564890745117 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2806.3356057070364, + 2811.1564890745117, + 2810.1395991082954 + ], + [ + 2699.483376401566, + 2701.08851166304, + 2700.870200706825 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74419.30590171668, + "scoreError" : 1553.1624701460244, + "scoreConfidence" : [ + 72866.14343157066, + 75972.4683718627 + ], + "scorePercentiles" : { + "0.0" : 73857.34089595686, + "50.0" : 74442.50046543565, + "90.0" : 74940.98571747156, + "95.0" : 74940.98571747156, + "99.0" : 74940.98571747156, + "99.9" : 74940.98571747156, + "99.99" : 74940.98571747156, + "99.999" : 74940.98571747156, + "99.9999" : 74940.98571747156, + "100.0" : 74940.98571747156 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73910.87124795647, + 73976.66658295617, + 73857.34089595686 + ], + [ + 74921.63661804394, + 74940.98571747156, + 74908.33434791514 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 364.23902627199254, + "scoreError" : 30.656721370040824, + "scoreConfidence" : [ + 333.5823049019517, + 394.89574764203337 + ], + "scorePercentiles" : { + "0.0" : 353.63476457061796, + "50.0" : 364.3511006158385, + "90.0" : 374.42273865416644, + "95.0" : 374.42273865416644, + "99.0" : 374.42273865416644, + "99.9" : 374.42273865416644, + "99.99" : 374.42273865416644, + "99.999" : 374.42273865416644, + "99.9999" : 374.42273865416644, + "100.0" : 374.42273865416644 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 374.3219560058079, + 373.89058214490444, + 374.42273865416644 + ], + [ + 353.63476457061796, + 354.35249716968616, + 354.8116190867726 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 116.12867053766718, + "scoreError" : 2.093889117785237, + "scoreConfidence" : [ + 114.03478141988194, + 118.22255965545241 + ], + "scorePercentiles" : { + "0.0" : 115.40202360118118, + "50.0" : 116.1078736860909, + "90.0" : 116.86250849723893, + "95.0" : 116.86250849723893, + "99.0" : 116.86250849723893, + "99.9" : 116.86250849723893, + "99.99" : 116.86250849723893, + "99.999" : 116.86250849723893, + "99.9999" : 116.86250849723893, + "100.0" : 116.86250849723893 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 115.40202360118118, + 115.49644493857728, + 115.44868782629202 + ], + [ + 116.7193024336045, + 116.84305592910906, + 116.86250849723893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.060792348591181135, + "scoreError" : 1.41737577453612E-4, + "scoreConfidence" : [ + 0.060650611013727526, + 0.060934086168634743 + ], + "scorePercentiles" : { + "0.0" : 0.06075159138432752, + "50.0" : 0.060781467880800764, + "90.0" : 0.060890042634549696, + "95.0" : 0.060890042634549696, + "99.0" : 0.060890042634549696, + "99.9" : 0.060890042634549696, + "99.99" : 0.060890042634549696, + "99.999" : 0.060890042634549696, + "99.9999" : 0.060890042634549696, + "100.0" : 0.060890042634549696 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06075705164861203, + 0.060890042634549696, + 0.06075159138432752 + ], + [ + 0.06079247011799607, + 0.06077490917930766, + 0.06078802658229387 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.6197912738362227E-4, + "scoreError" : 1.092119867764769E-5, + "scoreConfidence" : [ + 3.510579287059746E-4, + 3.7290032606126995E-4 + ], + "scorePercentiles" : { + "0.0" : 3.5833278182987634E-4, + "50.0" : 3.6192969931376855E-4, + "90.0" : 3.6569638771764536E-4, + "95.0" : 3.6569638771764536E-4, + "99.0" : 3.6569638771764536E-4, + "99.9" : 3.6569638771764536E-4, + "99.99" : 3.6569638771764536E-4, + "99.999" : 3.6569638771764536E-4, + "99.9999" : 3.6569638771764536E-4, + "100.0" : 3.6569638771764536E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.6529613109648635E-4, + 3.6569638771764536E-4, + 3.6560245148297023E-4 + ], + [ + 3.585632675310508E-4, + 3.5838374464370465E-4, + 3.5833278182987634E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.232168097367838, + "scoreError" : 0.0463355360655884, + "scoreConfidence" : [ + 2.1858325613022496, + 2.2785036334334263 + ], + "scorePercentiles" : { + "0.0" : 2.199888549593138, + "50.0" : 2.2292098479191997, + "90.0" : 2.2760427719804777, + "95.0" : 2.2762817139280838, + "99.0" : 2.2762817139280838, + "99.9" : 2.2762817139280838, + "99.99" : 2.2762817139280838, + "99.999" : 2.2762817139280838, + "99.9999" : 2.2762817139280838, + "100.0" : 2.2762817139280838 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2738922944520237, + 2.226303540739092, + 2.2519210466111237, + 2.2000990761108667, + 2.199888549593138 + ], + [ + 2.2762817139280838, + 2.255564209968426, + 2.232116155099308, + 2.203230583829037, + 2.2023838033472805 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013684476420215258, + "scoreError" : 1.689158775577832E-4, + "scoreConfidence" : [ + 0.013515560542657474, + 0.013853392297773041 + ], + "scorePercentiles" : { + "0.0" : 0.013624716590210213, + "50.0" : 0.013683162208824208, + "90.0" : 0.013746661037475703, + "95.0" : 0.013746661037475703, + "99.0" : 0.013746661037475703, + "99.9" : 0.013746661037475703, + "99.99" : 0.013746661037475703, + "99.999" : 0.013746661037475703, + "99.9999" : 0.013746661037475703, + "100.0" : 0.013746661037475703 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013635306892987843, + 0.013624716590210213, + 0.01362925827352445 + ], + [ + 0.013739898202432755, + 0.013731017524660574, + 0.013746661037475703 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0266616487063076, + "scoreError" : 0.03638582633034947, + "scoreConfidence" : [ + 0.9902758223759581, + 1.063047475036657 + ], + "scorePercentiles" : { + "0.0" : 1.0146300498173701, + "50.0" : 1.0266499891334449, + "90.0" : 1.0386595916078105, + "95.0" : 1.0386595916078105, + "99.0" : 1.0386595916078105, + "99.9" : 1.0386595916078105, + "99.99" : 1.0386595916078105, + "99.999" : 1.0386595916078105, + "99.9999" : 1.0386595916078105, + "100.0" : 1.0386595916078105 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0386512508309098, + 1.0386595916078105, + 1.0382036524447213 + ], + [ + 1.0146300498173701, + 1.0147290217148655, + 1.0150963258221681 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010329842606944065, + "scoreError" : 2.4007169641690704E-4, + "scoreConfidence" : [ + 0.010089770910527159, + 0.010569914303360971 + ], + "scorePercentiles" : { + "0.0" : 0.010249575436618563, + "50.0" : 0.010330546994798484, + "90.0" : 0.010412314042547874, + "95.0" : 0.010412314042547874, + "99.0" : 0.010412314042547874, + "99.9" : 0.010412314042547874, + "99.99" : 0.010412314042547874, + "99.999" : 0.010412314042547874, + "99.9999" : 0.010412314042547874, + "100.0" : 0.010412314042547874 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010406178092683202, + 0.010405322484314358, + 0.010412314042547874 + ], + [ + 0.010255771505282611, + 0.010249575436618563, + 0.010249894080217785 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.012926673991302, + "scoreError" : 0.21036862062023617, + "scoreConfidence" : [ + 2.802558053371066, + 3.223295294611538 + ], + "scorePercentiles" : { + "0.0" : 2.938330124559342, + "50.0" : 3.0133914302333933, + "90.0" : 3.086112232572486, + "95.0" : 3.086112232572486, + "99.0" : 3.086112232572486, + "99.9" : 3.086112232572486, + "99.99" : 3.086112232572486, + "99.999" : 3.086112232572486, + "99.9999" : 3.086112232572486, + "100.0" : 3.086112232572486 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.0717505810810812, + 3.085301695249846, + 3.086112232572486 + ], + [ + 2.938330124559342, + 2.955032279385706, + 2.941033131099353 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.740812395400416, + "scoreError" : 0.024136735024319705, + "scoreConfidence" : [ + 2.7166756603760964, + 2.7649491304247356 + ], + "scorePercentiles" : { + "0.0" : 2.7320954550669216, + "50.0" : 2.739419123337621, + "90.0" : 2.7528915218827414, + "95.0" : 2.7528915218827414, + "99.0" : 2.7528915218827414, + "99.9" : 2.7528915218827414, + "99.99" : 2.7528915218827414, + "99.999" : 2.7528915218827414, + "99.9999" : 2.7528915218827414, + "100.0" : 2.7528915218827414 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.7528915218827414, + 2.7477991777472526, + 2.743815590946502 + ], + [ + 2.7350226557287396, + 2.7320954550669216, + 2.733249971030336 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17637212638578423, + "scoreError" : 0.00904187723525529, + "scoreConfidence" : [ + 0.16733024915052894, + 0.18541400362103952 + ], + "scorePercentiles" : { + "0.0" : 0.17312876984868944, + "50.0" : 0.17653220771380693, + "90.0" : 0.17955134807433343, + "95.0" : 0.17955134807433343, + "99.0" : 0.17955134807433343, + "99.9" : 0.17955134807433343, + "99.99" : 0.17955134807433343, + "99.999" : 0.17955134807433343, + "99.9999" : 0.17955134807433343, + "100.0" : 0.17955134807433343 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17390793779454986, + 0.17328607140876798, + 0.17312876984868944 + ], + [ + 0.17955134807433343, + 0.179156477633064, + 0.1792021535553007 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.3248439071496512, + "scoreError" : 0.02391998646650746, + "scoreConfidence" : [ + 0.3009239206831438, + 0.34876389361615867 + ], + "scorePercentiles" : { + "0.0" : 0.3152782435133516, + "50.0" : 0.32622288268035976, + "90.0" : 0.33387898818108974, + "95.0" : 0.33387898818108974, + "99.0" : 0.33387898818108974, + "99.9" : 0.33387898818108974, + "99.99" : 0.33387898818108974, + "99.999" : 0.33387898818108974, + "99.9999" : 0.33387898818108974, + "100.0" : 0.33387898818108974 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33387898818108974, + 0.33109160137730104, + 0.33200626181069687 + ], + [ + 0.3213541639834185, + 0.3152782435133516, + 0.31545418403204945 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14793487823051077, + "scoreError" : 0.004457507397176232, + "scoreConfidence" : [ + 0.14347737083333453, + 0.152392385627687 + ], + "scorePercentiles" : { + "0.0" : 0.1468460868575624, + "50.0" : 0.14753649347943615, + "90.0" : 0.15112139958291776, + "95.0" : 0.15112139958291776, + "99.0" : 0.15112139958291776, + "99.9" : 0.15112139958291776, + "99.99" : 0.15112139958291776, + "99.999" : 0.15112139958291776, + "99.9999" : 0.15112139958291776, + "100.0" : 0.15112139958291776 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14754023332841545, + 0.14753297587890768, + 0.1475400110799646 + ], + [ + 0.15112139958291776, + 0.14702856265529662, + 0.1468460868575624 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4096493153763896, + "scoreError" : 0.015528988418896375, + "scoreConfidence" : [ + 0.3941203269574932, + 0.425178303795286 + ], + "scorePercentiles" : { + "0.0" : 0.4040386179952325, + "50.0" : 0.4099445158465487, + "90.0" : 0.41492897327911704, + "95.0" : 0.41492897327911704, + "99.0" : 0.41492897327911704, + "99.9" : 0.41492897327911704, + "99.99" : 0.41492897327911704, + "99.999" : 0.41492897327911704, + "99.9999" : 0.41492897327911704, + "100.0" : 0.41492897327911704 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4044591147017189, + 0.4053317585927367, + 0.4040386179952325 + ], + [ + 0.4145801545891717, + 0.41455727310036067, + 0.41492897327911704 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15633569705068795, + "scoreError" : 0.004814089202509768, + "scoreConfidence" : [ + 0.15152160784817817, + 0.16114978625319773 + ], + "scorePercentiles" : { + "0.0" : 0.15473251883829242, + "50.0" : 0.15621713556605588, + "90.0" : 0.15817527477776724, + "95.0" : 0.15817527477776724, + "99.0" : 0.15817527477776724, + "99.9" : 0.15817527477776724, + "99.99" : 0.15817527477776724, + "99.999" : 0.15817527477776724, + "99.9999" : 0.15817527477776724, + "100.0" : 0.15817527477776724 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15473251883829242, + 0.15485897948185887, + 0.15474473127630603 + ], + [ + 0.1575752916502529, + 0.15792738627965006, + 0.15817527477776724 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04736390409485358, + "scoreError" : 8.02947926079999E-4, + "scoreConfidence" : [ + 0.046560956168773586, + 0.04816685202093358 + ], + "scorePercentiles" : { + "0.0" : 0.04703275623647822, + "50.0" : 0.047416993026451706, + "90.0" : 0.04764231262982373, + "95.0" : 0.04764231262982373, + "99.0" : 0.04764231262982373, + "99.9" : 0.04764231262982373, + "99.99" : 0.04764231262982373, + "99.999" : 0.04764231262982373, + "99.9999" : 0.04764231262982373, + "100.0" : 0.04764231262982373 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04764231262982373, + 0.0476160489105592, + 0.04759046454320917 + ], + [ + 0.04724352150969424, + 0.047058320739356924, + 0.04703275623647822 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8640667.74035131, + "scoreError" : 16969.958023406107, + "scoreConfidence" : [ + 8623697.782327903, + 8657637.698374717 + ], + "scorePercentiles" : { + "0.0" : 8632319.877480587, + "50.0" : 8640460.054835923, + "90.0" : 8650352.838375108, + "95.0" : 8650352.838375108, + "99.0" : 8650352.838375108, + "99.9" : 8650352.838375108, + "99.99" : 8650352.838375108, + "99.999" : 8650352.838375108, + "99.9999" : 8650352.838375108, + "100.0" : 8650352.838375108 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8641967.005181348, + 8638953.1044905, + 8642906.0164076 + ], + [ + 8650352.838375108, + 8632319.877480587, + 8637507.600172712 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-08T05:57:33Z-6ce63f3531d032fa4c15ea8d5b4c4c3bbf0a95b7-jdk17.json b/performance-results/2025-11-08T05:57:33Z-6ce63f3531d032fa4c15ea8d5b4c4c3bbf0a95b7-jdk17.json new file mode 100644 index 0000000000..f694da41dc --- /dev/null +++ b/performance-results/2025-11-08T05:57:33Z-6ce63f3531d032fa4c15ea8d5b4c4c3bbf0a95b7-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3217173660367996, + "scoreError" : 0.03563332143594775, + "scoreConfidence" : [ + 3.2860840446008517, + 3.3573506874727475 + ], + "scorePercentiles" : { + "0.0" : 3.315097655201924, + "50.0" : 3.321586882973614, + "90.0" : 3.328598042998047, + "95.0" : 3.328598042998047, + "99.0" : 3.328598042998047, + "99.9" : 3.328598042998047, + "99.99" : 3.328598042998047, + "99.999" : 3.328598042998047, + "99.9999" : 3.328598042998047, + "100.0" : 3.328598042998047 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.321477246383218, + 3.328598042998047 + ], + [ + 3.315097655201924, + 3.32169651956401 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.673332979891782, + "scoreError" : 0.055262602516705554, + "scoreConfidence" : [ + 1.6180703773750764, + 1.7285955824084875 + ], + "scorePercentiles" : { + "0.0" : 1.6623393896060727, + "50.0" : 1.6751067578585705, + "90.0" : 1.6807790142439143, + "95.0" : 1.6807790142439143, + "99.0" : 1.6807790142439143, + "99.9" : 1.6807790142439143, + "99.99" : 1.6807790142439143, + "99.999" : 1.6807790142439143, + "99.9999" : 1.6807790142439143, + "100.0" : 1.6807790142439143 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6793970060481909, + 1.6807790142439143 + ], + [ + 1.6623393896060727, + 1.6708165096689502 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8430436040330936, + "scoreError" : 0.013863109395345715, + "scoreConfidence" : [ + 0.8291804946377479, + 0.8569067134284394 + ], + "scorePercentiles" : { + "0.0" : 0.8405797830574405, + "50.0" : 0.8428902408147322, + "90.0" : 0.8458141514454699, + "95.0" : 0.8458141514454699, + "99.0" : 0.8458141514454699, + "99.9" : 0.8458141514454699, + "99.99" : 0.8458141514454699, + "99.999" : 0.8458141514454699, + "99.9999" : 0.8458141514454699, + "100.0" : 0.8458141514454699 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8429737714429187, + 0.8458141514454699 + ], + [ + 0.8405797830574405, + 0.8428067101865456 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.19408119764227, + "scoreError" : 0.20843977193522417, + "scoreConfidence" : [ + 15.985641425707046, + 16.402520969577495 + ], + "scorePercentiles" : { + "0.0" : 16.077466469742593, + "50.0" : 16.209684200672093, + "90.0" : 16.25918836227468, + "95.0" : 16.25918836227468, + "99.0" : 16.25918836227468, + "99.9" : 16.25918836227468, + "99.99" : 16.25918836227468, + "99.999" : 16.25918836227468, + "99.9999" : 16.25918836227468, + "100.0" : 16.25918836227468 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.151333373788667, + 16.077466469742593, + 16.16786010129182 + ], + [ + 16.25150830005237, + 16.25918836227468, + 16.257130578703485 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2587.1295394693457, + "scoreError" : 84.88095498522746, + "scoreConfidence" : [ + 2502.248584484118, + 2672.0104944545733 + ], + "scorePercentiles" : { + "0.0" : 2552.229260903395, + "50.0" : 2586.835506661164, + "90.0" : 2621.3143063723173, + "95.0" : 2621.3143063723173, + "99.0" : 2621.3143063723173, + "99.9" : 2621.3143063723173, + "99.99" : 2621.3143063723173, + "99.999" : 2621.3143063723173, + "99.9999" : 2621.3143063723173, + "100.0" : 2621.3143063723173 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2621.3143063723173, + 2609.65913940441, + 2611.778056343531 + ], + [ + 2564.0118739179184, + 2552.229260903395, + 2563.7845998745047 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72861.35535029546, + "scoreError" : 2067.96163443678, + "scoreConfidence" : [ + 70793.39371585868, + 74929.31698473224 + ], + "scorePercentiles" : { + "0.0" : 72145.21974712652, + "50.0" : 72878.74334106712, + "90.0" : 73552.82552803571, + "95.0" : 73552.82552803571, + "99.0" : 73552.82552803571, + "99.9" : 73552.82552803571, + "99.99" : 73552.82552803571, + "99.999" : 73552.82552803571, + "99.9999" : 73552.82552803571, + "100.0" : 73552.82552803571 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73529.05232178683, + 73552.82552803571, + 73519.98100930687 + ], + [ + 72183.54782268946, + 72145.21974712652, + 72237.50567282738 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 340.91610321530027, + "scoreError" : 8.372565683754177, + "scoreConfidence" : [ + 332.54353753154606, + 349.28866889905447 + ], + "scorePercentiles" : { + "0.0" : 337.202504606123, + "50.0" : 340.8787875957295, + "90.0" : 344.61567109789655, + "95.0" : 344.61567109789655, + "99.0" : 344.61567109789655, + "99.9" : 344.61567109789655, + "99.99" : 344.61567109789655, + "99.999" : 344.61567109789655, + "99.9999" : 344.61567109789655, + "100.0" : 344.61567109789655 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 337.202504606123, + 338.72682274437625, + 338.9932145271762 + ], + [ + 342.7643606642827, + 344.61567109789655, + 343.19404565194674 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 112.2301300708791, + "scoreError" : 1.7992527411719943, + "scoreConfidence" : [ + 110.4308773297071, + 114.0293828120511 + ], + "scorePercentiles" : { + "0.0" : 111.40614267546553, + "50.0" : 112.33121734801375, + "90.0" : 112.8834696494899, + "95.0" : 112.8834696494899, + "99.0" : 112.8834696494899, + "99.9" : 112.8834696494899, + "99.99" : 112.8834696494899, + "99.999" : 112.8834696494899, + "99.9999" : 112.8834696494899, + "100.0" : 112.8834696494899 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 111.40614267546553, + 111.63332991849941, + 111.97309639208952 + ], + [ + 112.7954034857921, + 112.68933830393799, + 112.8834696494899 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06165637323698698, + "scoreError" : 0.00166087876455846, + "scoreConfidence" : [ + 0.059995494472428516, + 0.06331725200154543 + ], + "scorePercentiles" : { + "0.0" : 0.061094191191564236, + "50.0" : 0.061613096056593986, + "90.0" : 0.06232337207708032, + "95.0" : 0.06232337207708032, + "99.0" : 0.06232337207708032, + "99.9" : 0.06232337207708032, + "99.99" : 0.06232337207708032, + "99.999" : 0.06232337207708032, + "99.9999" : 0.06232337207708032, + "100.0" : 0.06232337207708032 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06111981267724428, + 0.061094191191564236, + 0.061147909178182705 + ], + [ + 0.06207828293500527, + 0.06232337207708032, + 0.06217467136284506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.577837515499256E-4, + "scoreError" : 1.5586686948099576E-6, + "scoreConfidence" : [ + 3.5622508285511567E-4, + 3.5934242024473557E-4 + ], + "scorePercentiles" : { + "0.0" : 3.573248871880158E-4, + "50.0" : 3.576655250774589E-4, + "90.0" : 3.588122316477025E-4, + "95.0" : 3.588122316477025E-4, + "99.0" : 3.588122316477025E-4, + "99.9" : 3.588122316477025E-4, + "99.99" : 3.588122316477025E-4, + "99.999" : 3.588122316477025E-4, + "99.9999" : 3.588122316477025E-4, + "100.0" : 3.588122316477025E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.573248871880158E-4, + 3.577804001697863E-4, + 3.5790578381902086E-4 + ], + [ + 3.5755064998513146E-4, + 3.588122316477025E-4, + 3.5732855648989693E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.33360719644346, + "scoreError" : 0.04666488736616923, + "scoreConfidence" : [ + 2.2869423090772907, + 2.380272083809629 + ], + "scorePercentiles" : { + "0.0" : 2.2917868609074246, + "50.0" : 2.3340543498658146, + "90.0" : 2.378974474762125, + "95.0" : 2.379878364350309, + "99.0" : 2.379878364350309, + "99.9" : 2.379878364350309, + "99.99" : 2.379878364350309, + "99.999" : 2.379878364350309, + "99.9999" : 2.379878364350309, + "100.0" : 2.379878364350309 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.379878364350309, + 2.3232818411149827, + 2.344826858616647, + 2.2917868609074246, + 2.300799769726248 + ], + [ + 2.3588109504716983, + 2.34701823421732, + 2.3708394684684686, + 2.308054704361874, + 2.3107749121996304 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013488721951660934, + "scoreError" : 1.60584445178182E-4, + "scoreConfidence" : [ + 0.013328137506482752, + 0.013649306396839117 + ], + "scorePercentiles" : { + "0.0" : 0.013430144272854124, + "50.0" : 0.013486704314671066, + "90.0" : 0.013552767914813916, + "95.0" : 0.013552767914813916, + "99.0" : 0.013552767914813916, + "99.9" : 0.013552767914813916, + "99.99" : 0.013552767914813916, + "99.999" : 0.013552767914813916, + "99.9999" : 0.013552767914813916, + "100.0" : 0.013552767914813916 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013442156051143772, + 0.013430144272854124, + 0.013438581479510521 + ], + [ + 0.013537429413444916, + 0.013552767914813916, + 0.01353125257819836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9926818283940871, + "scoreError" : 0.014524784611150119, + "scoreConfidence" : [ + 0.978157043782937, + 1.0072066130052373 + ], + "scorePercentiles" : { + "0.0" : 0.9874386994470774, + "50.0" : 0.9927300848496741, + "90.0" : 0.997791227776115, + "95.0" : 0.997791227776115, + "99.0" : 0.997791227776115, + "99.9" : 0.997791227776115, + "99.99" : 0.997791227776115, + "99.999" : 0.997791227776115, + "99.9999" : 0.997791227776115, + "100.0" : 0.997791227776115 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.9876471212719732, + 0.9874386994470774, + 0.9888913598338772 + ], + [ + 0.9965688098654708, + 0.997753752170009, + 0.997791227776115 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010453675723455479, + "scoreError" : 3.230543036164259E-4, + "scoreConfidence" : [ + 0.010130621419839054, + 0.010776730027071904 + ], + "scorePercentiles" : { + "0.0" : 0.01033481321824826, + "50.0" : 0.010455363339615675, + "90.0" : 0.010567539642954512, + "95.0" : 0.010567539642954512, + "99.0" : 0.010567539642954512, + "99.9" : 0.010567539642954512, + "99.99" : 0.010567539642954512, + "99.999" : 0.010567539642954512, + "99.9999" : 0.010567539642954512, + "100.0" : 0.010567539642954512 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010563508168529665, + 0.01054336552682463, + 0.010567539642954512 + ], + [ + 0.010367361152406721, + 0.01033481321824826, + 0.01034546663176908 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.1667128566214164, + "scoreError" : 0.06042414429492609, + "scoreConfidence" : [ + 3.1062887123264904, + 3.2271370009163425 + ], + "scorePercentiles" : { + "0.0" : 3.139436860640301, + "50.0" : 3.16711050842804, + "90.0" : 3.1978320319693094, + "95.0" : 3.1978320319693094, + "99.0" : 3.1978320319693094, + "99.9" : 3.1978320319693094, + "99.99" : 3.1978320319693094, + "99.999" : 3.1978320319693094, + "99.9999" : 3.1978320319693094, + "100.0" : 3.1978320319693094 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.1978320319693094, + 3.1753865853968253, + 3.1795775104895103 + ], + [ + 3.1492097197732996, + 3.1588344314592547, + 3.139436860640301 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.926723305194503, + "scoreError" : 0.05748798980795705, + "scoreConfidence" : [ + 2.869235315386546, + 2.98421129500246 + ], + "scorePercentiles" : { + "0.0" : 2.9013312323759792, + "50.0" : 2.931681763542504, + "90.0" : 2.9473431040377247, + "95.0" : 2.9473431040377247, + "99.0" : 2.9473431040377247, + "99.9" : 2.9473431040377247, + "99.99" : 2.9473431040377247, + "99.999" : 2.9473431040377247, + "99.9999" : 2.9473431040377247, + "100.0" : 2.9473431040377247 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.9349867136150234, + 2.9459135997054493, + 2.9473431040377247 + ], + [ + 2.9283768134699852, + 2.9023883679628555, + 2.9013312323759792 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17765003401732937, + "scoreError" : 0.0019788478352611265, + "scoreConfidence" : [ + 0.17567118618206826, + 0.1796288818525905 + ], + "scorePercentiles" : { + "0.0" : 0.17685811246109226, + "50.0" : 0.1777649717725917, + "90.0" : 0.17829940499581007, + "95.0" : 0.17829940499581007, + "99.0" : 0.17829940499581007, + "99.9" : 0.17829940499581007, + "99.99" : 0.17829940499581007, + "99.999" : 0.17829940499581007, + "99.9999" : 0.17829940499581007, + "100.0" : 0.17829940499581007 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17725992152935338, + 0.176935295405085, + 0.17685811246109226 + ], + [ + 0.17827744769680548, + 0.17829940499581007, + 0.17827002201583 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32323956477272464, + "scoreError" : 0.0022482369968709146, + "scoreConfidence" : [ + 0.3209913277758537, + 0.3254878017695956 + ], + "scorePercentiles" : { + "0.0" : 0.32173737510456213, + "50.0" : 0.3235869041747599, + "90.0" : 0.3238111152737752, + "95.0" : 0.3238111152737752, + "99.0" : 0.3238111152737752, + "99.9" : 0.3238111152737752, + "99.99" : 0.3238111152737752, + "99.999" : 0.3238111152737752, + "99.9999" : 0.3238111152737752, + "100.0" : 0.3238111152737752 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.32173737510456213, + 0.32294230375250277, + 0.3238111152737752 + ], + [ + 0.323772786155988, + 0.323495425484424, + 0.3236783828650958 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.1499221167176389, + "scoreError" : 0.007489774443286479, + "scoreConfidence" : [ + 0.14243234227435242, + 0.15741189116092535 + ], + "scorePercentiles" : { + "0.0" : 0.14667441535640952, + "50.0" : 0.15018825969500682, + "90.0" : 0.15291169406260036, + "95.0" : 0.15291169406260036, + "99.0" : 0.15291169406260036, + "99.9" : 0.15291169406260036, + "99.99" : 0.15291169406260036, + "99.999" : 0.15291169406260036, + "99.9999" : 0.15291169406260036, + "100.0" : 0.15291169406260036 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15291169406260036, + 0.15140724459484012, + 0.1523377783075634 + ], + [ + 0.14896927479517355, + 0.1472322931892465, + 0.14667441535640952 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4106929383564373, + "scoreError" : 0.015760203502452642, + "scoreConfidence" : [ + 0.3949327348539846, + 0.42645314185888994 + ], + "scorePercentiles" : { + "0.0" : 0.40414945514064016, + "50.0" : 0.4113604375891287, + "90.0" : 0.4174321183370205, + "95.0" : 0.4174321183370205, + "99.0" : 0.4174321183370205, + "99.9" : 0.4174321183370205, + "99.99" : 0.4174321183370205, + "99.999" : 0.4174321183370205, + "99.9999" : 0.4174321183370205, + "100.0" : 0.4174321183370205 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4097834942632355, + 0.4043300169004973, + 0.40414945514064016 + ], + [ + 0.415525164582208, + 0.4174321183370205, + 0.4129373809150219 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.160500655717378, + "scoreError" : 0.0060130551966752896, + "scoreConfidence" : [ + 0.15448760052070273, + 0.1665137109140533 + ], + "scorePercentiles" : { + "0.0" : 0.1580453592628884, + "50.0" : 0.16042055711352468, + "90.0" : 0.1632064869602115, + "95.0" : 0.1632064869602115, + "99.0" : 0.1632064869602115, + "99.9" : 0.1632064869602115, + "99.99" : 0.1632064869602115, + "99.999" : 0.1632064869602115, + "99.9999" : 0.1632064869602115, + "100.0" : 0.1632064869602115 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.15987815501446867, + 0.15833003586130462, + 0.1580453592628884 + ], + [ + 0.1632064869602115, + 0.16258093799281406, + 0.1609629592125807 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04628679498355103, + "scoreError" : 5.941087789864789E-4, + "scoreConfidence" : [ + 0.045692686204564556, + 0.04688090376253751 + ], + "scorePercentiles" : { + "0.0" : 0.04602433796179106, + "50.0" : 0.04634115500947737, + "90.0" : 0.0465945009621612, + "95.0" : 0.0465945009621612, + "99.0" : 0.0465945009621612, + "99.9" : 0.0465945009621612, + "99.99" : 0.0465945009621612, + "99.999" : 0.0465945009621612, + "99.9999" : 0.0465945009621612, + "100.0" : 0.0465945009621612 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.0465945009621612, + 0.046063310991450786, + 0.04602433796179106 + ], + [ + 0.04635063124913094, + 0.04635630996694835, + 0.0463316787698238 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8764699.034843305, + "scoreError" : 422901.5549446551, + "scoreConfidence" : [ + 8341797.47989865, + 9187600.58978796 + ], + "scorePercentiles" : { + "0.0" : 8622612.279310346, + "50.0" : 8711866.694814844, + "90.0" : 8950869.188729875, + "95.0" : 8950869.188729875, + "99.0" : 8950869.188729875, + "99.9" : 8950869.188729875, + "99.99" : 8950869.188729875, + "99.999" : 8950869.188729875, + "99.9999" : 8950869.188729875, + "100.0" : 8950869.188729875 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8950869.188729875, + 8945343.937388193, + 8768788.694127958 + ], + [ + 8622612.279310346, + 8654944.69550173, + 8645635.41400173 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-10T01:16:16Z-bbe6a653939113bedffe947fbf70315ff448f127-jdk17.json b/performance-results/2025-11-10T01:16:16Z-bbe6a653939113bedffe947fbf70315ff448f127-jdk17.json new file mode 100644 index 0000000000..60fb290575 --- /dev/null +++ b/performance-results/2025-11-10T01:16:16Z-bbe6a653939113bedffe947fbf70315ff448f127-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3534362036051895, + "scoreError" : 0.014026906108698223, + "scoreConfidence" : [ + 3.3394092974964913, + 3.3674631097138876 + ], + "scorePercentiles" : { + "0.0" : 3.3508071596310645, + "50.0" : 3.353837873365009, + "90.0" : 3.355261908059676, + "95.0" : 3.355261908059676, + "99.0" : 3.355261908059676, + "99.9" : 3.355261908059676, + "99.99" : 3.355261908059676, + "99.999" : 3.355261908059676, + "99.9999" : 3.355261908059676, + "100.0" : 3.355261908059676 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3525022463554697, + 3.3551735003745486 + ], + [ + 3.3508071596310645, + 3.355261908059676 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6918985881401423, + "scoreError" : 0.03299784355850022, + "scoreConfidence" : [ + 1.6589007445816422, + 1.7248964316986424 + ], + "scorePercentiles" : { + "0.0" : 1.687584402567114, + "50.0" : 1.6904889085351644, + "90.0" : 1.6990321329231264, + "95.0" : 1.6990321329231264, + "99.0" : 1.6990321329231264, + "99.9" : 1.6990321329231264, + "99.99" : 1.6990321329231264, + "99.999" : 1.6990321329231264, + "99.9999" : 1.6990321329231264, + "100.0" : 1.6990321329231264 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.688947232562085, + 1.6990321329231264 + ], + [ + 1.692030584508244, + 1.687584402567114 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8515570329183769, + "scoreError" : 0.018086275771559787, + "scoreConfidence" : [ + 0.8334707571468172, + 0.8696433086899367 + ], + "scorePercentiles" : { + "0.0" : 0.8476730191566222, + "50.0" : 0.8522787662233744, + "90.0" : 0.8539975800701368, + "95.0" : 0.8539975800701368, + "99.0" : 0.8539975800701368, + "99.9" : 0.8539975800701368, + "99.99" : 0.8539975800701368, + "99.999" : 0.8539975800701368, + "99.9999" : 0.8539975800701368, + "100.0" : 0.8539975800701368 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8476730191566222, + 0.8531206120185655 + ], + [ + 0.8514369204281832, + 0.8539975800701368 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.45233460599521, + "scoreError" : 0.12388411044122191, + "scoreConfidence" : [ + 16.328450495553987, + 16.57621871643643 + ], + "scorePercentiles" : { + "0.0" : 16.39619097279064, + "50.0" : 16.45729861247805, + "90.0" : 16.500485487269433, + "95.0" : 16.500485487269433, + "99.0" : 16.500485487269433, + "99.9" : 16.500485487269433, + "99.99" : 16.500485487269433, + "99.999" : 16.500485487269433, + "99.9999" : 16.500485487269433, + "100.0" : 16.500485487269433 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.39619097279064, + 16.408036478730132, + 16.441778266178304 + ], + [ + 16.500485487269433, + 16.494697472224956, + 16.472818958777797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2731.7962617179587, + "scoreError" : 22.873285602882046, + "scoreConfidence" : [ + 2708.922976115077, + 2754.6695473208406 + ], + "scorePercentiles" : { + "0.0" : 2723.465253682258, + "50.0" : 2731.356136960222, + "90.0" : 2741.3126132637994, + "95.0" : 2741.3126132637994, + "99.0" : 2741.3126132637994, + "99.9" : 2741.3126132637994, + "99.99" : 2741.3126132637994, + "99.999" : 2741.3126132637994, + "99.9999" : 2741.3126132637994, + "100.0" : 2741.3126132637994 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2738.674650823369, + 2737.414229730505, + 2741.3126132637994 + ], + [ + 2723.465253682258, + 2725.2980441899385, + 2724.6127786178836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 74796.25638944522, + "scoreError" : 249.69907600820702, + "scoreConfidence" : [ + 74546.557313437, + 75045.95546545343 + ], + "scorePercentiles" : { + "0.0" : 74692.39569169612, + "50.0" : 74797.01046734903, + "90.0" : 74891.40044445868, + "95.0" : 74891.40044445868, + "99.0" : 74891.40044445868, + "99.9" : 74891.40044445868, + "99.99" : 74891.40044445868, + "99.999" : 74891.40044445868, + "99.9999" : 74891.40044445868, + "100.0" : 74891.40044445868 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 74864.55142121477, + 74891.40044445868, + 74872.85046251044 + ], + [ + 74729.4695134833, + 74692.39569169612, + 74726.87080330795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 360.9385356941964, + "scoreError" : 1.2650266388163631, + "scoreConfidence" : [ + 359.67350905538, + 362.20356233301277 + ], + "scorePercentiles" : { + "0.0" : 360.13711238925634, + "50.0" : 361.00824105406446, + "90.0" : 361.43067853557665, + "95.0" : 361.43067853557665, + "99.0" : 361.43067853557665, + "99.9" : 361.43067853557665, + "99.99" : 361.43067853557665, + "99.999" : 361.43067853557665, + "99.9999" : 361.43067853557665, + "100.0" : 361.43067853557665 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 360.13711238925634, + 360.8584409798418, + 360.8445294994628 + ], + [ + 361.43067853557665, + 361.15804112828715, + 361.20241163275375 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 115.05301962786608, + "scoreError" : 2.9450336038538127, + "scoreConfidence" : [ + 112.10798602401226, + 117.9980532317199 + ], + "scorePercentiles" : { + "0.0" : 113.6321683225358, + "50.0" : 114.89515472282648, + "90.0" : 116.43118630468675, + "95.0" : 116.43118630468675, + "99.0" : 116.43118630468675, + "99.9" : 116.43118630468675, + "99.99" : 116.43118630468675, + "99.999" : 116.43118630468675, + "99.9999" : 116.43118630468675, + "100.0" : 116.43118630468675 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 114.37142636924446, + 116.43118630468675, + 116.09302732507652 + ], + [ + 113.6321683225358, + 114.91383099048667, + 114.87647845516626 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06116252179412316, + "scoreError" : 4.025873432820136E-4, + "scoreConfidence" : [ + 0.060759934450841144, + 0.06156510913740518 + ], + "scorePercentiles" : { + "0.0" : 0.06102103047943325, + "50.0" : 0.061142404724427835, + "90.0" : 0.06140113519703314, + "95.0" : 0.06140113519703314, + "99.0" : 0.06140113519703314, + "99.9" : 0.06140113519703314, + "99.99" : 0.06140113519703314, + "99.999" : 0.06140113519703314, + "99.9999" : 0.06140113519703314, + "100.0" : 0.06140113519703314 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06122180725834594, + 0.06120674820055819, + 0.06140113519703314 + ], + [ + 0.06102103047943325, + 0.06107806124829747, + 0.06104634838107098 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.7891116213767005E-4, + "scoreError" : 9.920388253321774E-6, + "scoreConfidence" : [ + 3.689907738843483E-4, + 3.888315503909918E-4 + ], + "scorePercentiles" : { + "0.0" : 3.752768928502539E-4, + "50.0" : 3.7898629176869665E-4, + "90.0" : 3.8235559455817154E-4, + "95.0" : 3.8235559455817154E-4, + "99.0" : 3.8235559455817154E-4, + "99.9" : 3.8235559455817154E-4, + "99.99" : 3.8235559455817154E-4, + "99.999" : 3.8235559455817154E-4, + "99.9999" : 3.8235559455817154E-4, + "100.0" : 3.8235559455817154E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.8231771145017744E-4, + 3.8168373738181046E-4, + 3.8235559455817154E-4 + ], + [ + 3.7628884615558284E-4, + 3.755441904300241E-4, + 3.752768928502539E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.2801828382365965, + "scoreError" : 0.06252674262719322, + "scoreConfidence" : [ + 2.2176560956094034, + 2.3427095808637897 + ], + "scorePercentiles" : { + "0.0" : 2.224180704692017, + "50.0" : 2.2714915270144544, + "90.0" : 2.3503174295140443, + "95.0" : 2.3535823532595903, + "99.0" : 2.3535823532595903, + "99.9" : 2.3535823532595903, + "99.99" : 2.3535823532595903, + "99.999" : 2.3535823532595903, + "99.9999" : 2.3535823532595903, + "100.0" : 2.3535823532595903 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.3535823532595903, + 2.311263704645251, + 2.320933115804131, + 2.265789713864975, + 2.261194267465521 + ], + [ + 2.299530068291561, + 2.262600461085973, + 2.2771933401639344, + 2.224180704692017, + 2.2255606530930128 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.01355827395809932, + "scoreError" : 2.194294587722317E-4, + "scoreConfidence" : [ + 0.013338844499327087, + 0.013777703416871552 + ], + "scorePercentiles" : { + "0.0" : 0.01348539579450721, + "50.0" : 0.013558445306233112, + "90.0" : 0.013631206088983397, + "95.0" : 0.013631206088983397, + "99.0" : 0.013631206088983397, + "99.9" : 0.013631206088983397, + "99.99" : 0.013631206088983397, + "99.999" : 0.013631206088983397, + "99.9999" : 0.013631206088983397, + "100.0" : 0.013631206088983397 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.01362976056349546, + 0.013628115628922289, + 0.013631206088983397 + ], + [ + 0.013488774983543936, + 0.013486390689143628, + 0.01348539579450721 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0228747715573396, + "scoreError" : 0.10595314869486147, + "scoreConfidence" : [ + 0.9169216228624781, + 1.1288279202522011 + ], + "scorePercentiles" : { + "0.0" : 0.98800886455246, + "50.0" : 1.0224519138388233, + "90.0" : 1.0583589339612658, + "95.0" : 1.0583589339612658, + "99.0" : 1.0583589339612658, + "99.9" : 1.0583589339612658, + "99.99" : 1.0583589339612658, + "99.999" : 1.0583589339612658, + "99.9999" : 1.0583589339612658, + "100.0" : 1.0583589339612658 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.98800886455246, + 0.9886026736852511, + 0.9885542327995255 + ], + [ + 1.0563011539923954, + 1.0574227703531403, + 1.0583589339612658 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010487139695487648, + "scoreError" : 8.744670276453759E-5, + "scoreConfidence" : [ + 0.01039969299272311, + 0.010574586398252185 + ], + "scorePercentiles" : { + "0.0" : 0.010455218948904743, + "50.0" : 0.01048722333994811, + "90.0" : 0.010518294883607433, + "95.0" : 0.010518294883607433, + "99.0" : 0.010518294883607433, + "99.9" : 0.010518294883607433, + "99.99" : 0.010518294883607433, + "99.999" : 0.010518294883607433, + "99.9999" : 0.010518294883607433, + "100.0" : 0.010518294883607433 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010461154608828096, + 0.01045993079513838, + 0.010455218948904743 + ], + [ + 0.010518294883607433, + 0.010514946865379115, + 0.010513292071068124 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.9518212589690296, + "scoreError" : 0.34192688170158997, + "scoreConfidence" : [ + 2.6098943772674397, + 3.2937481406706195 + ], + "scorePercentiles" : { + "0.0" : 2.8356830164399094, + "50.0" : 2.9505404365628882, + "90.0" : 3.0710113738489873, + "95.0" : 3.0710113738489873, + "99.0" : 3.0710113738489873, + "99.9" : 3.0710113738489873, + "99.99" : 3.0710113738489873, + "99.999" : 3.0710113738489873, + "99.9999" : 3.0710113738489873, + "100.0" : 3.0710113738489873 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8428890198976693, + 2.8432640289937465, + 2.8356830164399094 + ], + [ + 3.0578168441320295, + 3.0710113738489873, + 3.060263270501836 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7332595804318456, + "scoreError" : 0.1452925481449267, + "scoreConfidence" : [ + 2.587967032286919, + 2.8785521285767723 + ], + "scorePercentiles" : { + "0.0" : 2.683292622752884, + "50.0" : 2.7343599741098332, + "90.0" : 2.784299445155902, + "95.0" : 2.784299445155902, + "99.0" : 2.784299445155902, + "99.9" : 2.784299445155902, + "99.99" : 2.784299445155902, + "99.999" : 2.784299445155902, + "99.9999" : 2.784299445155902, + "100.0" : 2.784299445155902 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.784299445155902, + 2.7788298113364824, + 2.7782702780555555 + ], + [ + 2.690449670164111, + 2.6844156551261404, + 2.683292622752884 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18080761564094674, + "scoreError" : 0.00856995462947624, + "scoreConfidence" : [ + 0.1722376610114705, + 0.18937757027042298 + ], + "scorePercentiles" : { + "0.0" : 0.17841730801070474, + "50.0" : 0.179962581219319, + "90.0" : 0.18616668705785985, + "95.0" : 0.18616668705785985, + "99.0" : 0.18616668705785985, + "99.9" : 0.18616668705785985, + "99.99" : 0.18616668705785985, + "99.999" : 0.18616668705785985, + "99.9999" : 0.18616668705785985, + "100.0" : 0.18616668705785985 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18616668705785985, + 0.18185579523549736, + 0.18143315836931673 + ], + [ + 0.17849200406932125, + 0.17841730801070474, + 0.17848074110298054 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32580763252364614, + "scoreError" : 8.221381126396146E-4, + "scoreConfidence" : [ + 0.32498549441100655, + 0.32662977063628573 + ], + "scorePercentiles" : { + "0.0" : 0.325442810921635, + "50.0" : 0.325789780638358, + "90.0" : 0.3262663136276141, + "95.0" : 0.3262663136276141, + "99.0" : 0.3262663136276141, + "99.9" : 0.3262663136276141, + "99.99" : 0.3262663136276141, + "99.999" : 0.3262663136276141, + "99.9999" : 0.3262663136276141, + "100.0" : 0.3262663136276141 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3262663136276141, + 0.32593867700932144, + 0.325442810921635 + ], + [ + 0.32591762741583286, + 0.32561843230659027, + 0.32566193386088316 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14531407758730455, + "scoreError" : 0.0010929333087624006, + "scoreConfidence" : [ + 0.14422114427854216, + 0.14640701089606695 + ], + "scorePercentiles" : { + "0.0" : 0.14491489538894042, + "50.0" : 0.14527776121381342, + "90.0" : 0.14586640892979563, + "95.0" : 0.14586640892979563, + "99.0" : 0.14586640892979563, + "99.9" : 0.14586640892979563, + "99.99" : 0.14586640892979563, + "99.999" : 0.14586640892979563, + "99.9999" : 0.14586640892979563, + "100.0" : 0.14586640892979563 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14586640892979563, + 0.1455502984892149, + 0.1455388651327279 + ], + [ + 0.14499734028824962, + 0.14491489538894042, + 0.14501665729489893 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.40137883165507976, + "scoreError" : 0.01247182447286934, + "scoreConfidence" : [ + 0.38890700718221044, + 0.4138506561279491 + ], + "scorePercentiles" : { + "0.0" : 0.3974426656068675, + "50.0" : 0.40082812017306735, + "90.0" : 0.40744287671121254, + "95.0" : 0.40744287671121254, + "99.0" : 0.40744287671121254, + "99.9" : 0.40744287671121254, + "99.99" : 0.40744287671121254, + "99.999" : 0.40744287671121254, + "99.9999" : 0.40744287671121254, + "100.0" : 0.40744287671121254 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.40744287671121254, + 0.4042794588858344, + 0.40415950753748536 + ], + [ + 0.3974426656068675, + 0.39745174838043, + 0.39749673280864933 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15712028535164976, + "scoreError" : 0.00405298043017915, + "scoreConfidence" : [ + 0.1530673049214706, + 0.16117326578182892 + ], + "scorePercentiles" : { + "0.0" : 0.1547631281261607, + "50.0" : 0.15752608547193903, + "90.0" : 0.1586554193174787, + "95.0" : 0.1586554193174787, + "99.0" : 0.1586554193174787, + "99.9" : 0.1586554193174787, + "99.99" : 0.1586554193174787, + "99.999" : 0.1586554193174787, + "99.9999" : 0.1586554193174787, + "100.0" : 0.1586554193174787 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1571647070675321, + 0.1561402293820067, + 0.1547631281261607 + ], + [ + 0.1586554193174787, + 0.15788746387634595, + 0.1581107643403744 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04648459384877703, + "scoreError" : 4.7733442409830443E-4, + "scoreConfidence" : [ + 0.04600725942467873, + 0.04696192827287533 + ], + "scorePercentiles" : { + "0.0" : 0.04624192319323767, + "50.0" : 0.04657238597760258, + "90.0" : 0.04662558920262218, + "95.0" : 0.04662558920262218, + "99.0" : 0.04662558920262218, + "99.9" : 0.04662558920262218, + "99.99" : 0.04662558920262218, + "99.999" : 0.04662558920262218, + "99.9999" : 0.04662558920262218, + "100.0" : 0.04662558920262218 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04662558920262218, + 0.04624192319323767, + 0.04629310755535393 + ], + [ + 0.046582452123199614, + 0.04660217118624321, + 0.04656231983200555 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8655553.070426846, + "scoreError" : 384360.397660727, + "scoreConfidence" : [ + 8271192.672766119, + 9039913.468087573 + ], + "scorePercentiles" : { + "0.0" : 8522752.352640545, + "50.0" : 8640619.287938498, + "90.0" : 8845249.438549956, + "95.0" : 8845249.438549956, + "99.0" : 8845249.438549956, + "99.9" : 8845249.438549956, + "99.99" : 8845249.438549956, + "99.999" : 8845249.438549956, + "99.9999" : 8845249.438549956, + "100.0" : 8845249.438549956 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8845249.438549956, + 8734361.513537118, + 8746750.64423077 + ], + [ + 8546877.06233988, + 8537327.411262799, + 8522752.352640545 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-10T02:38:55Z-aed1e8071dff708221d62f697d9cc2ccb8abeec9-jdk17.json b/performance-results/2025-11-10T02:38:55Z-aed1e8071dff708221d62f697d9cc2ccb8abeec9-jdk17.json new file mode 100644 index 0000000000..782d562ce9 --- /dev/null +++ b/performance-results/2025-11-10T02:38:55Z-aed1e8071dff708221d62f697d9cc2ccb8abeec9-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.338044625229986, + "scoreError" : 0.09054041694677148, + "scoreConfidence" : [ + 3.2475042082832144, + 3.4285850421767576 + ], + "scorePercentiles" : { + "0.0" : 3.3189585959882937, + "50.0" : 3.3402727761830593, + "90.0" : 3.3526743525655314, + "95.0" : 3.3526743525655314, + "99.0" : 3.3526743525655314, + "99.9" : 3.3526743525655314, + "99.99" : 3.3526743525655314, + "99.999" : 3.3526743525655314, + "99.9999" : 3.3526743525655314, + "100.0" : 3.3526743525655314 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3408681455663123, + 3.3526743525655314 + ], + [ + 3.3189585959882937, + 3.3396774067998063 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6890051397807382, + "scoreError" : 0.020880868956775756, + "scoreConfidence" : [ + 1.6681242708239625, + 1.7098860087375138 + ], + "scorePercentiles" : { + "0.0" : 1.68528380102628, + "50.0" : 1.688841751533499, + "90.0" : 1.6930532550296746, + "95.0" : 1.6930532550296746, + "99.0" : 1.6930532550296746, + "99.9" : 1.6930532550296746, + "99.99" : 1.6930532550296746, + "99.999" : 1.6930532550296746, + "99.9999" : 1.6930532550296746, + "100.0" : 1.6930532550296746 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.688122155421942, + 1.68528380102628 + ], + [ + 1.6895613476450562, + 1.6930532550296746 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.846051952914502, + "scoreError" : 0.026721360269501077, + "scoreConfidence" : [ + 0.8193305926450009, + 0.8727733131840031 + ], + "scorePercentiles" : { + "0.0" : 0.8427957494904019, + "50.0" : 0.8446666033592609, + "90.0" : 0.8520788554490841, + "95.0" : 0.8520788554490841, + "99.0" : 0.8520788554490841, + "99.9" : 0.8520788554490841, + "99.99" : 0.8520788554490841, + "99.999" : 0.8520788554490841, + "99.9999" : 0.8520788554490841, + "100.0" : 0.8520788554490841 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8441499579335127, + 0.8451832487850092 + ], + [ + 0.8427957494904019, + 0.8520788554490841 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.252088060357288, + "scoreError" : 0.4771648154313855, + "scoreConfidence" : [ + 15.774923244925903, + 16.729252875788674 + ], + "scorePercentiles" : { + "0.0" : 16.029608992066514, + "50.0" : 16.296599252695735, + "90.0" : 16.420465351550128, + "95.0" : 16.420465351550128, + "99.0" : 16.420465351550128, + "99.9" : 16.420465351550128, + "99.99" : 16.420465351550128, + "99.999" : 16.420465351550128, + "99.9999" : 16.420465351550128, + "100.0" : 16.420465351550128 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 16.208576632847137, + 16.081561151829305, + 16.029608992066514 + ], + [ + 16.38462187254433, + 16.420465351550128, + 16.387694361306316 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2698.663645759781, + "scoreError" : 288.62368282476183, + "scoreConfidence" : [ + 2410.039962935019, + 2987.287328584543 + ], + "scorePercentiles" : { + "0.0" : 2578.736405499461, + "50.0" : 2706.2046102896543, + "90.0" : 2811.9951768453902, + "95.0" : 2811.9951768453902, + "99.0" : 2811.9951768453902, + "99.9" : 2811.9951768453902, + "99.99" : 2811.9951768453902, + "99.999" : 2811.9951768453902, + "99.9999" : 2811.9951768453902, + "100.0" : 2811.9951768453902 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2778.2800974206293, + 2781.6063194935978, + 2811.9951768453902 + ], + [ + 2634.1291231586792, + 2578.736405499461, + 2607.2347521409283 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73698.75873160781, + "scoreError" : 992.867119322088, + "scoreConfidence" : [ + 72705.89161228572, + 74691.62585092991 + ], + "scorePercentiles" : { + "0.0" : 73258.00645744364, + "50.0" : 73757.72794435843, + "90.0" : 74111.34667025204, + "95.0" : 74111.34667025204, + "99.0" : 74111.34667025204, + "99.9" : 74111.34667025204, + "99.99" : 74111.34667025204, + "99.999" : 74111.34667025204, + "99.9999" : 74111.34667025204, + "100.0" : 74111.34667025204 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73959.93202597754, + 74111.34667025204, + 73936.60209172322 + ], + [ + 73347.81134725684, + 73258.00645744364, + 73578.85379699363 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 357.09273416120294, + "scoreError" : 13.107932920180547, + "scoreConfidence" : [ + 343.9848012410224, + 370.2006670813835 + ], + "scorePercentiles" : { + "0.0" : 350.5880334137143, + "50.0" : 356.85041446282776, + "90.0" : 362.5048329112332, + "95.0" : 362.5048329112332, + "99.0" : 362.5048329112332, + "99.9" : 362.5048329112332, + "99.99" : 362.5048329112332, + "99.999" : 362.5048329112332, + "99.9999" : 362.5048329112332, + "100.0" : 362.5048329112332 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 362.5048329112332, + 358.11616529219805, + 361.94849802246273 + ], + [ + 353.8142116941517, + 355.58466363345747, + 350.5880334137143 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 114.42890177800757, + "scoreError" : 3.936705964118912, + "scoreConfidence" : [ + 110.49219581388866, + 118.36560774212649 + ], + "scorePercentiles" : { + "0.0" : 112.77024860342567, + "50.0" : 114.32655619066726, + "90.0" : 116.24946385869715, + "95.0" : 116.24946385869715, + "99.0" : 116.24946385869715, + "99.9" : 116.24946385869715, + "99.99" : 116.24946385869715, + "99.999" : 116.24946385869715, + "99.9999" : 116.24946385869715, + "100.0" : 116.24946385869715 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.77024860342567, + 113.49250606090219, + 113.36045433020341 + ], + [ + 115.16060632043234, + 115.54013149438461, + 116.24946385869715 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.06157939679865463, + "scoreError" : 9.618583003999885E-4, + "scoreConfidence" : [ + 0.060617538498254644, + 0.06254125509905462 + ], + "scorePercentiles" : { + "0.0" : 0.061229960868473744, + "50.0" : 0.06147676479370781, + "90.0" : 0.062097512732940466, + "95.0" : 0.062097512732940466, + "99.0" : 0.062097512732940466, + "99.9" : 0.062097512732940466, + "99.99" : 0.062097512732940466, + "99.999" : 0.062097512732940466, + "99.9999" : 0.062097512732940466, + "100.0" : 0.062097512732940466 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06140025590048383, + 0.061884289181529016, + 0.062097512732940466 + ], + [ + 0.061311088421568925, + 0.061229960868473744, + 0.061553273686931795 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.724632635424617E-4, + "scoreError" : 2.6344581985985653E-5, + "scoreConfidence" : [ + 3.4611868155647605E-4, + 3.988078455284473E-4 + ], + "scorePercentiles" : { + "0.0" : 3.625593599814025E-4, + "50.0" : 3.728100420698519E-4, + "90.0" : 3.821870424103129E-4, + "95.0" : 3.821870424103129E-4, + "99.0" : 3.821870424103129E-4, + "99.9" : 3.821870424103129E-4, + "99.99" : 3.821870424103129E-4, + "99.999" : 3.821870424103129E-4, + "99.9999" : 3.821870424103129E-4, + "100.0" : 3.821870424103129E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.821870424103129E-4, + 3.8139131156599243E-4, + 3.791177213093357E-4 + ], + [ + 3.625593599814025E-4, + 3.6650236283036807E-4, + 3.630217831573588E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.269559016282703, + "scoreError" : 0.038937029374821984, + "scoreConfidence" : [ + 2.230621986907881, + 2.3084960456575248 + ], + "scorePercentiles" : { + "0.0" : 2.2346375109472745, + "50.0" : 2.26701463722846, + "90.0" : 2.3134616884494674, + "95.0" : 2.3147344126359637, + "99.0" : 2.3147344126359637, + "99.9" : 2.3147344126359637, + "99.99" : 2.3147344126359637, + "99.999" : 2.3147344126359637, + "99.9999" : 2.3147344126359637, + "100.0" : 2.3147344126359637 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.2730313879545454, + 2.3147344126359637, + 2.281271373859489, + 2.248245282598921, + 2.2346375109472745 + ], + [ + 2.302007170771001, + 2.257334576844956, + 2.280447496124031, + 2.260997886502374, + 2.2428830645884728 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013697955450872107, + "scoreError" : 1.6732340910096316E-4, + "scoreConfidence" : [ + 0.013530632041771143, + 0.01386527885997307 + ], + "scorePercentiles" : { + "0.0" : 0.013631215790191107, + "50.0" : 0.01369503703284702, + "90.0" : 0.013766701071858282, + "95.0" : 0.013766701071858282, + "99.0" : 0.013766701071858282, + "99.9" : 0.013766701071858282, + "99.99" : 0.013766701071858282, + "99.999" : 0.013766701071858282, + "99.9999" : 0.013766701071858282, + "100.0" : 0.013766701071858282 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013631215790191107, + 0.01364387506873014, + 0.013660930930048932 + ], + [ + 0.013755866708759073, + 0.013766701071858282, + 0.01372914313564511 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0378782012816015, + "scoreError" : 0.08766788535217386, + "scoreConfidence" : [ + 0.9502103159294276, + 1.1255460866337754 + ], + "scorePercentiles" : { + "0.0" : 1.007746763401854, + "50.0" : 1.0387699109643656, + "90.0" : 1.068172570925016, + "95.0" : 1.068172570925016, + "99.0" : 1.068172570925016, + "99.9" : 1.068172570925016, + "99.99" : 1.068172570925016, + "99.999" : 1.068172570925016, + "99.9999" : 1.068172570925016, + "100.0" : 1.068172570925016 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0122736328575768, + 1.0081500267137096, + 1.007746763401854 + ], + [ + 1.0652661890711546, + 1.0656600247202983, + 1.068172570925016 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010652945232675425, + "scoreError" : 3.803584764238686E-4, + "scoreConfidence" : [ + 0.010272586756251556, + 0.011033303709099293 + ], + "scorePercentiles" : { + "0.0" : 0.010503102322806693, + "50.0" : 0.010668442017940065, + "90.0" : 0.010807558290284233, + "95.0" : 0.010807558290284233, + "99.0" : 0.010807558290284233, + "99.9" : 0.010807558290284233, + "99.99" : 0.010807558290284233, + "99.999" : 0.010807558290284233, + "99.9999" : 0.010807558290284233, + "100.0" : 0.010807558290284233 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010513685606928759, + 0.010581702974843872, + 0.010503102322806693 + ], + [ + 0.010755181061036257, + 0.010756441140152737, + 0.010807558290284233 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 2.9375419162556966, + "scoreError" : 0.1109063733466398, + "scoreConfidence" : [ + 2.826635542909057, + 3.0484482896023364 + ], + "scorePercentiles" : { + "0.0" : 2.894246222800926, + "50.0" : 2.931331565912193, + "90.0" : 3.002136018007203, + "95.0" : 3.002136018007203, + "99.0" : 3.002136018007203, + "99.9" : 3.002136018007203, + "99.99" : 3.002136018007203, + "99.999" : 3.002136018007203, + "99.9999" : 3.002136018007203, + "100.0" : 3.002136018007203 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.958260201064459, + 3.002136018007203, + 2.945329809187279 + ], + [ + 2.917333322637106, + 2.907945923837209, + 2.894246222800926 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7796126456285033, + "scoreError" : 0.23283875805603949, + "scoreConfidence" : [ + 2.546773887572464, + 3.0124514036845427 + ], + "scorePercentiles" : { + "0.0" : 2.670534453137517, + "50.0" : 2.789565300194353, + "90.0" : 2.8773518420598387, + "95.0" : 2.8773518420598387, + "99.0" : 2.8773518420598387, + "99.9" : 2.8773518420598387, + "99.99" : 2.8773518420598387, + "99.999" : 2.8773518420598387, + "99.9999" : 2.8773518420598387, + "100.0" : 2.8773518420598387 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8773518420598387, + 2.8383128785471055, + 2.838707560885609 + ], + [ + 2.670534453137517, + 2.7119514172993493, + 2.7408177218416006 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18599123334867573, + "scoreError" : 0.0011423937507426631, + "scoreConfidence" : [ + 0.18484883959793308, + 0.1871336270994184 + ], + "scorePercentiles" : { + "0.0" : 0.18543118206934917, + "50.0" : 0.18608913251624842, + "90.0" : 0.18654264109834354, + "95.0" : 0.18654264109834354, + "99.0" : 0.18654264109834354, + "99.9" : 0.18654264109834354, + "99.99" : 0.18654264109834354, + "99.999" : 0.18654264109834354, + "99.9999" : 0.18654264109834354, + "100.0" : 0.18654264109834354 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18654264109834354, + 0.1861797835160948, + 0.1859990059518274 + ], + [ + 0.18561552837577017, + 0.18617925908066948, + 0.18543118206934917 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.32810876796822175, + "scoreError" : 0.015056919358553808, + "scoreConfidence" : [ + 0.31305184860966795, + 0.34316568732677555 + ], + "scorePercentiles" : { + "0.0" : 0.32172933050220376, + "50.0" : 0.32864011410203586, + "90.0" : 0.33372230854968965, + "95.0" : 0.33372230854968965, + "99.0" : 0.33372230854968965, + "99.9" : 0.33372230854968965, + "99.99" : 0.33372230854968965, + "99.999" : 0.33372230854968965, + "99.9999" : 0.33372230854968965, + "100.0" : 0.33372230854968965 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3319940365181595, + 0.3329019899800266, + 0.33372230854968965 + ], + [ + 0.32172933050220376, + 0.3252861916859122, + 0.32301875057333895 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14600779372912423, + "scoreError" : 0.004776046754015337, + "scoreConfidence" : [ + 0.1412317469751089, + 0.15078384048313956 + ], + "scorePercentiles" : { + "0.0" : 0.14385533641176132, + "50.0" : 0.14608959001721966, + "90.0" : 0.14786604679875795, + "95.0" : 0.14786604679875795, + "99.0" : 0.14786604679875795, + "99.9" : 0.14786604679875795, + "99.99" : 0.14786604679875795, + "99.999" : 0.14786604679875795, + "99.9999" : 0.14786604679875795, + "100.0" : 0.14786604679875795 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14786604679875795, + 0.14740259283934967, + 0.14728562320868374 + ], + [ + 0.1448935568257556, + 0.14474360629043698, + 0.14385533641176132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4079880299513116, + "scoreError" : 0.03205713356793089, + "scoreConfidence" : [ + 0.37593089638338073, + 0.4400451635192425 + ], + "scorePercentiles" : { + "0.0" : 0.3966877857199524, + "50.0" : 0.40782736912460515, + "90.0" : 0.4199952694132964, + "95.0" : 0.4199952694132964, + "99.0" : 0.4199952694132964, + "99.9" : 0.4199952694132964, + "99.99" : 0.4199952694132964, + "99.999" : 0.4199952694132964, + "99.9999" : 0.4199952694132964, + "100.0" : 0.4199952694132964 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.4167199247020585, + 0.4199952694132964, + 0.41836139633534136 + ], + [ + 0.39893481354715177, + 0.3972289899900695, + 0.3966877857199524 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15616937704345435, + "scoreError" : 0.0028553900692412384, + "scoreConfidence" : [ + 0.1533139869742131, + 0.1590247671126956 + ], + "scorePercentiles" : { + "0.0" : 0.1551964147371035, + "50.0" : 0.15608924906496224, + "90.0" : 0.15729753432953206, + "95.0" : 0.15729753432953206, + "99.0" : 0.15729753432953206, + "99.9" : 0.15729753432953206, + "99.99" : 0.15729753432953206, + "99.999" : 0.15729753432953206, + "99.9999" : 0.15729753432953206, + "100.0" : 0.15729753432953206 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.1553434619961165, + 0.15521284077046052, + 0.1551964147371035 + ], + [ + 0.15729753432953206, + 0.156835036133808, + 0.15713097429370543 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046545122453364195, + "scoreError" : 0.0013062904647217822, + "scoreConfidence" : [ + 0.04523883198864241, + 0.04785141291808598 + ], + "scorePercentiles" : { + "0.0" : 0.045753262881692486, + "50.0" : 0.04659668735039607, + "90.0" : 0.04721084632634466, + "95.0" : 0.04721084632634466, + "99.0" : 0.04721084632634466, + "99.9" : 0.04721084632634466, + "99.99" : 0.04721084632634466, + "99.999" : 0.04721084632634466, + "99.9999" : 0.04721084632634466, + "100.0" : 0.04721084632634466 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04721084632634466, + 0.04662441498393812, + 0.04659428227301954 + ], + [ + 0.0465990924277726, + 0.04648883582741773, + 0.045753262881692486 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8622900.335059777, + "scoreError" : 277916.9358002958, + "scoreConfidence" : [ + 8344983.399259482, + 8900817.270860072 + ], + "scorePercentiles" : { + "0.0" : 8503745.420068027, + "50.0" : 8625339.583503839, + "90.0" : 8735112.358951965, + "95.0" : 8735112.358951965, + "99.0" : 8735112.358951965, + "99.9" : 8735112.358951965, + "99.99" : 8735112.358951965, + "99.999" : 8735112.358951965, + "99.9999" : 8735112.358951965, + "100.0" : 8735112.358951965 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8503745.420068027, + 8560569.320786998, + 8540511.912894962 + ], + [ + 8690109.846220678, + 8707353.15143603, + 8735112.358951965 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-16T05:25:16Z-1846e706cdbc72dc6bd34f28103e4920bf007e7a-jdk17.json b/performance-results/2025-11-16T05:25:16Z-1846e706cdbc72dc6bd34f28103e4920bf007e7a-jdk17.json new file mode 100644 index 0000000000..d622bcca10 --- /dev/null +++ b/performance-results/2025-11-16T05:25:16Z-1846e706cdbc72dc6bd34f28103e4920bf007e7a-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.327378099396822, + "scoreError" : 0.03183314961136015, + "scoreConfidence" : [ + 3.295544949785462, + 3.359211249008182 + ], + "scorePercentiles" : { + "0.0" : 3.320861425421507, + "50.0" : 3.3280309675102933, + "90.0" : 3.332589037145195, + "95.0" : 3.332589037145195, + "99.0" : 3.332589037145195, + "99.9" : 3.332589037145195, + "99.99" : 3.332589037145195, + "99.999" : 3.332589037145195, + "99.9999" : 3.332589037145195, + "100.0" : 3.332589037145195 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3269517545246052, + 3.3291101804959813 + ], + [ + 3.320861425421507, + 3.332589037145195 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.673722884212292, + "scoreError" : 0.055329545142390364, + "scoreConfidence" : [ + 1.6183933390699017, + 1.7290524293546823 + ], + "scorePercentiles" : { + "0.0" : 1.6626785964307167, + "50.0" : 1.6751245793092413, + "90.0" : 1.6819637817999684, + "95.0" : 1.6819637817999684, + "99.0" : 1.6819637817999684, + "99.9" : 1.6819637817999684, + "99.99" : 1.6819637817999684, + "99.999" : 1.6819637817999684, + "99.9999" : 1.6819637817999684, + "100.0" : 1.6819637817999684 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6626785964307167, + 1.671510634840157 + ], + [ + 1.6819637817999684, + 1.6787385237783259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8412974822060514, + "scoreError" : 0.023214019611741347, + "scoreConfidence" : [ + 0.8180834625943101, + 0.8645115018177927 + ], + "scorePercentiles" : { + "0.0" : 0.8376630575467057, + "50.0" : 0.8409841132577003, + "90.0" : 0.8455586447620994, + "95.0" : 0.8455586447620994, + "99.0" : 0.8455586447620994, + "99.9" : 0.8455586447620994, + "99.99" : 0.8455586447620994, + "99.999" : 0.8455586447620994, + "99.9999" : 0.8455586447620994, + "100.0" : 0.8455586447620994 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.8376630575467057, + 0.8455586447620994 + ], + [ + 0.8390929547022318, + 0.8428752718131687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 16.16522528726286, + "scoreError" : 0.40949754560731466, + "scoreConfidence" : [ + 15.755727741655546, + 16.574722832870176 + ], + "scorePercentiles" : { + "0.0" : 15.963690598134303, + "50.0" : 16.157867252381752, + "90.0" : 16.324350639724614, + "95.0" : 16.324350639724614, + "99.0" : 16.324350639724614, + "99.9" : 16.324350639724614, + "99.99" : 16.324350639724614, + "99.999" : 16.324350639724614, + "99.9999" : 16.324350639724614, + "100.0" : 16.324350639724614 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.963690598134303, + 16.07387247272776, + 16.08649352020377 + ], + [ + 16.31370350822696, + 16.324350639724614, + 16.229240984559734 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2655.2596867611664, + "scoreError" : 45.567783081374444, + "scoreConfidence" : [ + 2609.691903679792, + 2700.8274698425407 + ], + "scorePercentiles" : { + "0.0" : 2632.926827718069, + "50.0" : 2652.48199722392, + "90.0" : 2679.7330804823773, + "95.0" : 2679.7330804823773, + "99.0" : 2679.7330804823773, + "99.9" : 2679.7330804823773, + "99.99" : 2679.7330804823773, + "99.999" : 2679.7330804823773, + "99.9999" : 2679.7330804823773, + "100.0" : 2679.7330804823773 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2666.991799009253, + 2632.926827718069, + 2652.896621728474 + ], + [ + 2652.0673727193666, + 2679.7330804823773, + 2646.9424189094584 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 72716.70428481487, + "scoreError" : 773.51522606465, + "scoreConfidence" : [ + 71943.18905875023, + 73490.21951087951 + ], + "scorePercentiles" : { + "0.0" : 72361.96984601567, + "50.0" : 72743.6495886003, + "90.0" : 73062.02595898345, + "95.0" : 73062.02595898345, + "99.0" : 73062.02595898345, + "99.9" : 73062.02595898345, + "99.99" : 73062.02595898345, + "99.999" : 73062.02595898345, + "99.9999" : 73062.02595898345, + "100.0" : 73062.02595898345 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 73062.02595898345, + 72771.50004473145, + 72950.75683425504 + ], + [ + 72438.17389243442, + 72361.96984601567, + 72715.79913246915 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 354.8020048520273, + "scoreError" : 5.589346398060289, + "scoreConfidence" : [ + 349.21265845396704, + 360.3913512500876 + ], + "scorePercentiles" : { + "0.0" : 351.3893597193541, + "50.0" : 355.15810343396356, + "90.0" : 356.68610308140063, + "95.0" : 356.68610308140063, + "99.0" : 356.68610308140063, + "99.9" : 356.68610308140063, + "99.99" : 356.68610308140063, + "99.999" : 356.68610308140063, + "99.9999" : 356.68610308140063, + "100.0" : 356.68610308140063 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 351.3893597193541, + 356.68610308140063, + 355.56759633412054 + ], + [ + 354.74861053380664, + 353.84153844255513, + 356.57882100092667 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.67117331897435, + "scoreError" : 2.141232590269903, + "scoreConfidence" : [ + 111.52994072870445, + 115.81240590924426 + ], + "scorePercentiles" : { + "0.0" : 112.21291599952424, + "50.0" : 113.9334653575641, + "90.0" : 114.30750900497944, + "95.0" : 114.30750900497944, + "99.0" : 114.30750900497944, + "99.9" : 114.30750900497944, + "99.99" : 114.30750900497944, + "99.999" : 114.30750900497944, + "99.9999" : 114.30750900497944, + "100.0" : 114.30750900497944 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 112.21291599952424, + 113.83810797380151, + 114.12305926055407 + ], + [ + 114.02882274132669, + 113.51662493366017, + 114.30750900497944 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.062188169191476565, + "scoreError" : 0.0023936540451980092, + "scoreConfidence" : [ + 0.05979451514627856, + 0.06458182323667458 + ], + "scorePercentiles" : { + "0.0" : 0.06124934209591474, + "50.0" : 0.06218335943952324, + "90.0" : 0.06310011249929014, + "95.0" : 0.06310011249929014, + "99.0" : 0.06310011249929014, + "99.9" : 0.06310011249929014, + "99.99" : 0.06310011249929014, + "99.999" : 0.06310011249929014, + "99.9999" : 0.06310011249929014, + "100.0" : 0.06310011249929014 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06171534671710782, + 0.06124934209591474, + 0.06134289772420562 + ], + [ + 0.06310011249929014, + 0.06265137216193865, + 0.06306994395040239 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.885695361014419E-4, + "scoreError" : 2.1193939375008083E-5, + "scoreConfidence" : [ + 3.673755967264338E-4, + 4.0976347547645E-4 + ], + "scorePercentiles" : { + "0.0" : 3.7943277669210106E-4, + "50.0" : 3.880578797527108E-4, + "90.0" : 3.9682762402683697E-4, + "95.0" : 3.9682762402683697E-4, + "99.0" : 3.9682762402683697E-4, + "99.9" : 3.9682762402683697E-4, + "99.99" : 3.9682762402683697E-4, + "99.999" : 3.9682762402683697E-4, + "99.9999" : 3.9682762402683697E-4, + "100.0" : 3.9682762402683697E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.841483443532056E-4, + 3.824129146613142E-4, + 3.7943277669210106E-4 + ], + [ + 3.9662814172297754E-4, + 3.9196741515221605E-4, + 3.9682762402683697E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.283195489673956, + "scoreError" : 0.08190031629242615, + "scoreConfidence" : [ + 2.20129517338153, + 2.3650958059663822 + ], + "scorePercentiles" : { + "0.0" : 2.2148474663418956, + "50.0" : 2.2721119023953036, + "90.0" : 2.3884783060226558, + "95.0" : 2.394353457026574, + "99.0" : 2.394353457026574, + "99.9" : 2.394353457026574, + "99.99" : 2.394353457026574, + "99.999" : 2.394353457026574, + "99.9999" : 2.394353457026574, + "100.0" : 2.394353457026574 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.335601946987389, + 2.394353457026574, + 2.3170578288163077, + 2.256142710128581, + 2.271859116537937 + ], + [ + 2.2815659466240876, + 2.27236468825267, + 2.271011917801998, + 2.217149818222124, + 2.2148474663418956 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013910520126715792, + "scoreError" : 2.4229036072343765E-4, + "scoreConfidence" : [ + 0.013668229765992353, + 0.01415281048743923 + ], + "scorePercentiles" : { + "0.0" : 0.013824107031821317, + "50.0" : 0.013899307881602922, + "90.0" : 0.014015726485819802, + "95.0" : 0.014015726485819802, + "99.0" : 0.014015726485819802, + "99.9" : 0.014015726485819802, + "99.99" : 0.014015726485819802, + "99.999" : 0.014015726485819802, + "99.9999" : 0.014015726485819802, + "100.0" : 0.014015726485819802 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013824107031821317, + 0.013844417641415268, + 0.013833253634986617 + ], + [ + 0.014015726485819802, + 0.013991417844461172, + 0.013954198121790579 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.9900315466248917, + "scoreError" : 0.027514047175033664, + "scoreConfidence" : [ + 0.962517499449858, + 1.0175455937999254 + ], + "scorePercentiles" : { + "0.0" : 0.9789323362372748, + "50.0" : 0.9907887843401966, + "90.0" : 1.0000819201, + "95.0" : 1.0000819201, + "99.0" : 1.0000819201, + "99.9" : 1.0000819201, + "99.99" : 1.0000819201, + "99.999" : 1.0000819201, + "99.9999" : 1.0000819201, + "100.0" : 1.0000819201 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0000819201, + 0.9971159973080758, + 0.9991750170846239 + ], + [ + 0.9789323362372748, + 0.9844615713723174, + 0.9804224376470588 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.01061439932673366, + "scoreError" : 2.0629379472911498E-4, + "scoreConfidence" : [ + 0.010408105532004544, + 0.010820693121462775 + ], + "scorePercentiles" : { + "0.0" : 0.010498731685910397, + "50.0" : 0.010612826508393892, + "90.0" : 0.010706867523051293, + "95.0" : 0.010706867523051293, + "99.0" : 0.010706867523051293, + "99.9" : 0.010706867523051293, + "99.99" : 0.010706867523051293, + "99.999" : 0.010706867523051293, + "99.9999" : 0.010706867523051293, + "100.0" : 0.010706867523051293 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010669737240466893, + 0.010706867523051293, + 0.010637553573707994 + ], + [ + 0.010498731685910397, + 0.01058809944307979, + 0.01058540649418559 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.11285542775532, + "scoreError" : 0.2942878379339343, + "scoreConfidence" : [ + 2.8185675898213858, + 3.4071432656892546 + ], + "scorePercentiles" : { + "0.0" : 3.0090079386281587, + "50.0" : 3.106764922887427, + "90.0" : 3.230603739018088, + "95.0" : 3.230603739018088, + "99.0" : 3.230603739018088, + "99.9" : 3.230603739018088, + "99.99" : 3.230603739018088, + "99.999" : 3.230603739018088, + "99.9999" : 3.230603739018088, + "100.0" : 3.230603739018088 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.183559154678549, + 3.230603739018088, + 3.208299325208467 + ], + [ + 3.0090079386281587, + 3.015691717902351, + 3.029970691096305 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.7859016069509877, + "scoreError" : 0.11239032496128941, + "scoreConfidence" : [ + 2.6735112819896982, + 2.898291931912277 + ], + "scorePercentiles" : { + "0.0" : 2.7253621708446865, + "50.0" : 2.7929375539885237, + "90.0" : 2.826023061599322, + "95.0" : 2.826023061599322, + "99.0" : 2.826023061599322, + "99.9" : 2.826023061599322, + "99.99" : 2.826023061599322, + "99.999" : 2.826023061599322, + "99.9999" : 2.826023061599322, + "100.0" : 2.826023061599322 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.8099440691205393, + 2.8211641935119887, + 2.826023061599322 + ], + [ + 2.7759310388565086, + 2.7569851077728775, + 2.7253621708446865 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.18206567706696045, + "scoreError" : 0.009759337338625104, + "scoreConfidence" : [ + 0.17230633972833534, + 0.19182501440558555 + ], + "scorePercentiles" : { + "0.0" : 0.17867768248494703, + "50.0" : 0.18196781425481853, + "90.0" : 0.18580717712417086, + "95.0" : 0.18580717712417086, + "99.0" : 0.18580717712417086, + "99.9" : 0.18580717712417086, + "99.99" : 0.18580717712417086, + "99.999" : 0.18580717712417086, + "99.9999" : 0.18580717712417086, + "100.0" : 0.18580717712417086 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.18580717712417086, + 0.18460062992634707, + 0.18524171856997315 + ], + [ + 0.17867768248494703, + 0.17873185571303463, + 0.17933499858329 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33441093559191254, + "scoreError" : 0.02075850677141205, + "scoreConfidence" : [ + 0.3136524288205005, + 0.3551694423633246 + ], + "scorePercentiles" : { + "0.0" : 0.32701770281229564, + "50.0" : 0.334749931126727, + "90.0" : 0.3418399474601764, + "95.0" : 0.3418399474601764, + "99.0" : 0.3418399474601764, + "99.9" : 0.3418399474601764, + "99.99" : 0.3418399474601764, + "99.999" : 0.3418399474601764, + "99.9999" : 0.3418399474601764, + "100.0" : 0.3418399474601764 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.3418399474601764, + 0.34048287031425556, + 0.34105157693881727 + ], + [ + 0.32901699193919853, + 0.32705652408673186, + 0.32701770281229564 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14688081130821792, + "scoreError" : 9.95243265407193E-4, + "scoreConfidence" : [ + 0.14588556804281072, + 0.14787605457362513 + ], + "scorePercentiles" : { + "0.0" : 0.14637150941877314, + "50.0" : 0.1469702237968893, + "90.0" : 0.14730876705064372, + "95.0" : 0.14730876705064372, + "99.0" : 0.14730876705064372, + "99.9" : 0.14730876705064372, + "99.99" : 0.14730876705064372, + "99.999" : 0.14730876705064372, + "99.9999" : 0.14730876705064372, + "100.0" : 0.14730876705064372 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.14696345241454312, + 0.14712056010474747, + 0.14637150941877314 + ], + [ + 0.14697699517923543, + 0.14654358368136458, + 0.14730876705064372 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4071153460605485, + "scoreError" : 0.010540961127230457, + "scoreConfidence" : [ + 0.39657438493331804, + 0.41765630718777896 + ], + "scorePercentiles" : { + "0.0" : 0.40016624413765506, + "50.0" : 0.4076376666386089, + "90.0" : 0.41121837855174964, + "95.0" : 0.41121837855174964, + "99.0" : 0.41121837855174964, + "99.9" : 0.41121837855174964, + "99.99" : 0.41121837855174964, + "99.999" : 0.41121837855174964, + "99.9999" : 0.41121837855174964, + "100.0" : 0.41121837855174964 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41121837855174964, + 0.40824708613651206, + 0.4091594825498138 + ], + [ + 0.4068726378468549, + 0.4070282471407058, + 0.40016624413765506 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.16088992989651651, + "scoreError" : 0.0025937778570492473, + "scoreConfidence" : [ + 0.15829615203946726, + 0.16348370775356577 + ], + "scorePercentiles" : { + "0.0" : 0.15933190744546946, + "50.0" : 0.16100376340478484, + "90.0" : 0.16192922300667142, + "95.0" : 0.16192922300667142, + "99.0" : 0.16192922300667142, + "99.9" : 0.16192922300667142, + "99.99" : 0.16192922300667142, + "99.999" : 0.16192922300667142, + "99.9999" : 0.16192922300667142, + "100.0" : 0.16192922300667142 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16044997558001475, + 0.15933190744546946, + 0.1609132463192109 + ], + [ + 0.16162094653737374, + 0.16192922300667142, + 0.16109428049035876 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.04744451404896547, + "scoreError" : 6.62743760118256E-4, + "scoreConfidence" : [ + 0.04678177028884722, + 0.048107257809083724 + ], + "scorePercentiles" : { + "0.0" : 0.047186734389671914, + "50.0" : 0.047450652044874725, + "90.0" : 0.04767438158007647, + "95.0" : 0.04767438158007647, + "99.0" : 0.04767438158007647, + "99.9" : 0.04767438158007647, + "99.99" : 0.04767438158007647, + "99.999" : 0.04767438158007647, + "99.9999" : 0.04767438158007647, + "100.0" : 0.04767438158007647 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.047270189243357456, + 0.047186734389671914, + 0.04723477268175635 + ], + [ + 0.04767438158007647, + 0.047631114846392, + 0.047669891552538625 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8897667.018465847, + "scoreError" : 441879.25162602786, + "scoreConfidence" : [ + 8455787.766839819, + 9339546.270091875 + ], + "scorePercentiles" : { + "0.0" : 8742629.097027972, + "50.0" : 8900571.31654723, + "90.0" : 9062588.54076087, + "95.0" : 9062588.54076087, + "99.0" : 9062588.54076087, + "99.9" : 9062588.54076087, + "99.99" : 9062588.54076087, + "99.999" : 9062588.54076087, + "99.9999" : 9062588.54076087, + "100.0" : 9062588.54076087 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8777410.319298245, + 8744147.249125874, + 8742629.097027972 + ], + [ + 9023732.313796213, + 9062588.54076087, + 9035494.590785908 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/performance-results/2025-11-20T02:37:33Z-09b4ae614a7ea82407e31f305bbe9dac2bdba994-jdk17.json b/performance-results/2025-11-20T02:37:33Z-09b4ae614a7ea82407e31f305bbe9dac2bdba994-jdk17.json new file mode 100644 index 0000000000..57e04b04e2 --- /dev/null +++ b/performance-results/2025-11-20T02:37:33Z-09b4ae614a7ea82407e31f305bbe9dac2bdba994-jdk17.json @@ -0,0 +1,1283 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "5" + }, + "primaryMetric" : { + "score" : 3.3326121799410506, + "scoreError" : 0.0533259641710732, + "scoreConfidence" : [ + 3.2792862157699774, + 3.385938144112124 + ], + "scorePercentiles" : { + "0.0" : 3.3234316308114926, + "50.0" : 3.3318518843464564, + "90.0" : 3.3433133202597984, + "95.0" : 3.3433133202597984, + "99.0" : 3.3433133202597984, + "99.9" : 3.3433133202597984, + "99.99" : 3.3433133202597984, + "99.999" : 3.3433133202597984, + "99.9999" : 3.3433133202597984, + "100.0" : 3.3433133202597984 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 3.3234316308114926, + 3.333325994787398 + ], + [ + 3.3303777739055147, + 3.3433133202597984 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "10" + }, + "primaryMetric" : { + "score" : 1.6774785117316764, + "scoreError" : 0.05056351626412096, + "scoreConfidence" : [ + 1.6269149954675555, + 1.7280420279957973 + ], + "scorePercentiles" : { + "0.0" : 1.6702908421203708, + "50.0" : 1.6773979495401985, + "90.0" : 1.6848273057259373, + "95.0" : 1.6848273057259373, + "99.0" : 1.6848273057259373, + "99.9" : 1.6848273057259373, + "99.99" : 1.6848273057259373, + "99.999" : 1.6848273057259373, + "99.9999" : 1.6848273057259373, + "100.0" : 1.6848273057259373 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 1.6702908421203708, + 1.6711529409613788 + ], + [ + 1.6836429581190182, + 1.6848273057259373 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ComplexQueryPerformance.benchMarkSimpleQueriesThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 2, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "howManyItems" : "20" + }, + "primaryMetric" : { + "score" : 0.8488397672830397, + "scoreError" : 0.02242793414311625, + "scoreConfidence" : [ + 0.8264118331399234, + 0.871267701426156 + ], + "scorePercentiles" : { + "0.0" : 0.8442988686156693, + "50.0" : 0.849155810320029, + "90.0" : 0.8527485798764316, + "95.0" : 0.8527485798764316, + "99.0" : 0.8527485798764316, + "99.9" : 0.8527485798764316, + "99.99" : 0.8527485798764316, + "99.999" : 0.8527485798764316, + "99.9999" : 0.8527485798764316, + "100.0" : 0.8527485798764316 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 0.849014522609059, + 0.8527485798764316 + ], + [ + 0.8442988686156693, + 0.8492970980309988 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 15.899122127589441, + "scoreError" : 0.27253274998355265, + "scoreConfidence" : [ + 15.626589377605889, + 16.171654877572994 + ], + "scorePercentiles" : { + "0.0" : 15.801665169873743, + "50.0" : 15.902694269895637, + "90.0" : 15.992728398692151, + "95.0" : 15.992728398692151, + "99.0" : 15.992728398692151, + "99.9" : 15.992728398692151, + "99.99" : 15.992728398692151, + "99.999" : 15.992728398692151, + "99.9999" : 15.992728398692151, + "100.0" : 15.992728398692151 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 15.80828302499217, + 15.801665169873743, + 15.821991496481004 + ], + [ + 15.983397043310271, + 15.986667632187299, + 15.992728398692151 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkThroughput_getImmediateFields", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2796.687529758879, + "scoreError" : 37.706857594543095, + "scoreConfidence" : [ + 2758.980672164336, + 2834.394387353422 + ], + "scorePercentiles" : { + "0.0" : 2773.7580170020374, + "50.0" : 2800.250995170519, + "90.0" : 2808.1397930766097, + "95.0" : 2808.1397930766097, + "99.0" : 2808.1397930766097, + "99.9" : 2808.1397930766097, + "99.99" : 2808.1397930766097, + "99.999" : 2808.1397930766097, + "99.9999" : 2808.1397930766097, + "100.0" : 2808.1397930766097 + }, + "scoreUnit" : "ops/ms", + "rawData" : [ + [ + 2808.1397930766097, + 2805.69201451705, + 2807.6112212161775 + ], + [ + 2794.809975823988, + 2790.114156917409, + 2773.7580170020374 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 73420.24655182673, + "scoreError" : 3271.465487640519, + "scoreConfidence" : [ + 70148.7810641862, + 76691.71203946725 + ], + "scorePercentiles" : { + "0.0" : 72340.86073027016, + "50.0" : 73426.31897810308, + "90.0" : 74498.83382483949, + "95.0" : 74498.83382483949, + "99.0" : 74498.83382483949, + "99.9" : 74498.83382483949, + "99.99" : 74498.83382483949, + "99.999" : 74498.83382483949, + "99.9999" : 74498.83382483949, + "100.0" : 74498.83382483949 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 72349.98456796659, + 72340.86073027016, + 72375.14394606101 + ], + [ + 74498.83382483949, + 74479.16223167797, + 74477.49401014515 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 348.28449094473893, + "scoreError" : 2.944282103546426, + "scoreConfidence" : [ + 345.3402088411925, + 351.22877304828535 + ], + "scorePercentiles" : { + "0.0" : 347.22962679792204, + "50.0" : 347.8858816876976, + "90.0" : 349.6384360837405, + "95.0" : 349.6384360837405, + "99.0" : 349.6384360837405, + "99.9" : 349.6384360837405, + "99.99" : 349.6384360837405, + "99.999" : 349.6384360837405, + "99.9999" : 349.6384360837405, + "100.0" : 349.6384360837405 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 347.77980623510695, + 349.5586973328227, + 349.6384360837405 + ], + [ + 347.9919571402882, + 347.5084220785532, + 347.22962679792204 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationThroughput", + "mode" : "thrpt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 113.5994046390989, + "scoreError" : 1.974937366634112, + "scoreConfidence" : [ + 111.6244672724648, + 115.57434200573302 + ], + "scorePercentiles" : { + "0.0" : 112.88383951566979, + "50.0" : 113.41914024034145, + "90.0" : 114.80140033760979, + "95.0" : 114.80140033760979, + "99.0" : 114.80140033760979, + "99.9" : 114.80140033760979, + "99.99" : 114.80140033760979, + "99.999" : 114.80140033760979, + "99.9999" : 114.80140033760979, + "100.0" : 114.80140033760979 + }, + "scoreUnit" : "ops/s", + "rawData" : [ + [ + 113.46228762041908, + 113.37599286026382, + 113.06390911831095 + ], + [ + 112.88383951566979, + 114.00899838232003, + 114.80140033760979 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.061715292701327217, + "scoreError" : 0.0010679257974093729, + "scoreConfidence" : [ + 0.060647366903917845, + 0.0627832184987366 + ], + "scorePercentiles" : { + "0.0" : 0.06133311753738209, + "50.0" : 0.06169531959481761, + "90.0" : 0.062112434071838064, + "95.0" : 0.062112434071838064, + "99.0" : 0.062112434071838064, + "99.9" : 0.062112434071838064, + "99.99" : 0.062112434071838064, + "99.999" : 0.062112434071838064, + "99.9999" : 0.062112434071838064, + "100.0" : 0.062112434071838064 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.06207946847355777, + 0.06198935421302868, + 0.062112434071838064 + ], + [ + 0.0613760969355502, + 0.06140128497660653, + 0.06133311753738209 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DFSelectionSetPerformance.benchMarkAvgTime_getImmediateFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3.55042230292301E-4, + "scoreError" : 9.637342642250621E-7, + "scoreConfidence" : [ + 3.540784960280759E-4, + 3.5600596455652607E-4 + ], + "scorePercentiles" : { + "0.0" : 3.545310466418344E-4, + "50.0" : 3.5504888349907946E-4, + "90.0" : 3.5553672322892135E-4, + "95.0" : 3.5553672322892135E-4, + "99.0" : 3.5553672322892135E-4, + "99.9" : 3.5553672322892135E-4, + "99.99" : 3.5553672322892135E-4, + "99.999" : 3.5553672322892135E-4, + "99.9999" : 3.5553672322892135E-4, + "100.0" : 3.5553672322892135E-4 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.5553672322892135E-4, + 3.550015089536837E-4, + 3.552441150918679E-4 + ], + [ + 3.548437297930234E-4, + 3.545310466418344E-4, + 3.550962580444752E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.DataLoaderPerformance.executeRequestWithDataLoaders", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.302143630427227, + "scoreError" : 0.052317498216517766, + "scoreConfidence" : [ + 2.249826132210709, + 2.3544611286437447 + ], + "scorePercentiles" : { + "0.0" : 2.26184855269109, + "50.0" : 2.306344401854405, + "90.0" : 2.3549109678331117, + "95.0" : 2.3567763475494816, + "99.0" : 2.3567763475494816, + "99.9" : 2.3567763475494816, + "99.99" : 2.3567763475494816, + "99.999" : 2.3567763475494816, + "99.9999" : 2.3567763475494816, + "100.0" : 2.3567763475494816 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.3567763475494816, + 2.314865398148148, + 2.3296003265781504, + 2.2705494022701473, + 2.2654343877689693 + ], + [ + 2.3381225503857843, + 2.319991144514034, + 2.2978234055606617, + 2.26184855269109, + 2.266424788805801 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF1Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 0.013627935993796006, + "scoreError" : 3.307157778531404E-4, + "scoreConfidence" : [ + 0.013297220215942866, + 0.013958651771649146 + ], + "scorePercentiles" : { + "0.0" : 0.013499447578974083, + "50.0" : 0.013636207227776136, + "90.0" : 0.013738793438433797, + "95.0" : 0.013738793438433797, + "99.0" : 0.013738793438433797, + "99.9" : 0.013738793438433797, + "99.99" : 0.013738793438433797, + "99.999" : 0.013738793438433797, + "99.9999" : 0.013738793438433797, + "100.0" : 0.013738793438433797 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.013734436426664323, + 0.013738793438433797, + 0.013731484508577816 + ], + [ + 0.013499447578974083, + 0.013540929946974457, + 0.013522524063151575 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENF2Performance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.0020056461280555, + "scoreError" : 0.022476500791931805, + "scoreConfidence" : [ + 0.9795291453361238, + 1.0244821469199874 + ], + "scorePercentiles" : { + "0.0" : 0.9941846916194452, + "50.0" : 1.0019669453453228, + "90.0" : 1.0097236476171243, + "95.0" : 1.0097236476171243, + "99.0" : 1.0097236476171243, + "99.9" : 1.0097236476171243, + "99.99" : 1.0097236476171243, + "99.999" : 1.0097236476171243, + "99.9999" : 1.0097236476171243, + "100.0" : 1.0097236476171243 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 1.0095309820310923, + 1.0086718245083208, + 1.0097236476171243 + ], + [ + 0.9941846916194452, + 0.9952620661823248, + 0.9946606648100259 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "2" + }, + "primaryMetric" : { + "score" : 0.010475178566971985, + "scoreError" : 4.2114359024176E-4, + "scoreConfidence" : [ + 0.010054034976730224, + 0.010896322157213745 + ], + "scorePercentiles" : { + "0.0" : 0.010328362365631378, + "50.0" : 0.01047641341280271, + "90.0" : 0.010618157349540355, + "95.0" : 0.010618157349540355, + "99.0" : 0.010618157349540355, + "99.9" : 0.010618157349540355, + "99.99" : 0.010618157349540355, + "99.999" : 0.010618157349540355, + "99.9999" : 0.010618157349540355, + "100.0" : 0.010618157349540355 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.010618157349540355, + 0.010605451926747944, + 0.010612742250776833 + ], + [ + 0.010347374898857477, + 0.010338982610277925, + 0.010328362365631378 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFDeepIntrospectionPerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "5 s", + "measurementBatchSize" : 1, + "params" : { + "howDeep" : "10" + }, + "primaryMetric" : { + "score" : 3.129938372235572, + "scoreError" : 0.2796094491523664, + "scoreConfidence" : [ + 2.8503289230832056, + 3.409547821387938 + ], + "scorePercentiles" : { + "0.0" : 3.0270567263922517, + "50.0" : 3.13591966013266, + "90.0" : 3.2233045837628866, + "95.0" : 3.2233045837628866, + "99.0" : 3.2233045837628866, + "99.9" : 3.2233045837628866, + "99.99" : 3.2233045837628866, + "99.999" : 3.2233045837628866, + "99.9999" : 3.2233045837628866, + "100.0" : 3.2233045837628866 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 3.220407182227946, + 3.218140173745174, + 3.2233045837628866 + ], + [ + 3.037022420765027, + 3.0270567263922517, + 3.0536991465201466 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.ENFExtraLargePerformance.benchMarkAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.8905156273330963, + "scoreError" : 0.02328378849501425, + "scoreConfidence" : [ + 2.867231838838082, + 2.9137994158281106 + ], + "scorePercentiles" : { + "0.0" : 2.882803729682997, + "50.0" : 2.888308531331263, + "90.0" : 2.906259704532249, + "95.0" : 2.906259704532249, + "99.0" : 2.906259704532249, + "99.9" : 2.906259704532249, + "99.99" : 2.906259704532249, + "99.999" : 2.906259704532249, + "99.9999" : 2.906259704532249, + "100.0" : 2.906259704532249 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 2.88566757559146, + 2.887166375, + 2.889450687662525 + ], + [ + 2.906259704532249, + 2.882803729682997, + 2.891745691529344 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkDeepAbstractConcrete", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.17917726512401685, + "scoreError" : 0.0012261384702520679, + "scoreConfidence" : [ + 0.17795112665376478, + 0.18040340359426893 + ], + "scorePercentiles" : { + "0.0" : 0.17867455089424503, + "50.0" : 0.17922075401153353, + "90.0" : 0.17965633972297576, + "95.0" : 0.17965633972297576, + "99.0" : 0.17965633972297576, + "99.9" : 0.17965633972297576, + "99.99" : 0.17965633972297576, + "99.999" : 0.17965633972297576, + "99.9999" : 0.17965633972297576, + "100.0" : 0.17965633972297576 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.17895480598056585, + 0.17874157203882107, + 0.17867455089424503 + ], + [ + 0.1795496200649922, + 0.17965633972297576, + 0.17948670204250125 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.33430754270456425, + "scoreError" : 0.011186792367567826, + "scoreConfidence" : [ + 0.32312075033699644, + 0.34549433507213206 + ], + "scorePercentiles" : { + "0.0" : 0.3295819205391866, + "50.0" : 0.33542790244649223, + "90.0" : 0.33800336926248903, + "95.0" : 0.33800336926248903, + "99.0" : 0.33800336926248903, + "99.9" : 0.33800336926248903, + "99.99" : 0.33800336926248903, + "99.999" : 0.33800336926248903, + "99.9999" : 0.33800336926248903, + "100.0" : 0.33800336926248903 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.33800336926248903, + 0.33764448254439866, + 0.3375789492641102 + ], + [ + 0.3332768556288742, + 0.3295819205391866, + 0.32975967898832687 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkNoOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.14627044433358438, + "scoreError" : 0.004956424273074186, + "scoreConfidence" : [ + 0.1413140200605102, + 0.15122686860665857 + ], + "scorePercentiles" : { + "0.0" : 0.14507583078730904, + "50.0" : 0.14515113705021365, + "90.0" : 0.1485801867320407, + "95.0" : 0.1485801867320407, + "99.0" : 0.1485801867320407, + "99.9" : 0.1485801867320407, + "99.99" : 0.1485801867320407, + "99.999" : 0.1485801867320407, + "99.9999" : 0.1485801867320407, + "100.0" : 0.1485801867320407 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.145159835493751, + 0.14514243860667633, + 0.14514081740203194 + ], + [ + 0.14507583078730904, + 0.14852355697969732, + 0.1485801867320407 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.4058748977538484, + "scoreError" : 0.01585443709450083, + "scoreConfidence" : [ + 0.39002046065934753, + 0.42172933484834924 + ], + "scorePercentiles" : { + "0.0" : 0.40091500797787044, + "50.0" : 0.4045229172737388, + "90.0" : 0.41416803661061874, + "95.0" : 0.41416803661061874, + "99.0" : 0.41416803661061874, + "99.9" : 0.41416803661061874, + "99.99" : 0.41416803661061874, + "99.999" : 0.41416803661061874, + "99.9999" : 0.41416803661061874, + "100.0" : 0.41416803661061874 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.41416803661061874, + 0.4100750950916472, + 0.4078268442967253 + ], + [ + 0.40121899025075225, + 0.4010454122954764, + 0.40091500797787044 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkOverlapNoFrag", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.15889447440725357, + "scoreError" : 0.0048813889177607905, + "scoreConfidence" : [ + 0.15401308548949277, + 0.16377586332501437 + ], + "scorePercentiles" : { + "0.0" : 0.15678026067257192, + "50.0" : 0.15937500256557674, + "90.0" : 0.1604771103568907, + "95.0" : 0.1604771103568907, + "99.0" : 0.1604771103568907, + "99.9" : 0.1604771103568907, + "99.99" : 0.1604771103568907, + "99.999" : 0.1604771103568907, + "99.9999" : 0.1604771103568907, + "100.0" : 0.1604771103568907 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.16039131121589761, + 0.1604771103568907, + 0.1603139903493163 + ], + [ + 0.1584360147818372, + 0.15678026067257192, + 0.1569681590670078 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.benchmarkRepeatedFields", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 0.046874595405080044, + "scoreError" : 7.112796634006733E-5, + "scoreConfidence" : [ + 0.046803467438739976, + 0.04694572337142011 + ], + "scorePercentiles" : { + "0.0" : 0.04684279002075107, + "50.0" : 0.04687867667457685, + "90.0" : 0.04690527301466691, + "95.0" : 0.04690527301466691, + "99.0" : 0.04690527301466691, + "99.9" : 0.04690527301466691, + "99.99" : 0.04690527301466691, + "99.999" : 0.04690527301466691, + "99.9999" : 0.04690527301466691, + "100.0" : 0.04690527301466691 + }, + "scoreUnit" : "ms/op", + "rawData" : [ + [ + 0.04684279002075107, + 0.04687845594198414, + 0.04684652153504539 + ], + [ + 0.04690527301466691, + 0.04689563451086319, + 0.046878897407169544 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "performance.OverlappingFieldValidationPerformance.overlappingFieldValidationAvgTime", + "mode" : "avgt", + "threads" : 1, + "forks" : 2, + "jvm" : "/home/ec2-user/.sdkman/candidates/java/17.0.10-amzn/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.10", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.10+7-LTS", + "warmupIterations" : 2, + "warmupTime" : "5 s", + "warmupBatchSize" : 1, + "measurementIterations" : 3, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "params" : { + "size" : "100" + }, + "primaryMetric" : { + "score" : 8755460.501280613, + "scoreError" : 231832.52216371533, + "scoreConfidence" : [ + 8523627.979116898, + 8987293.023444328 + ], + "scorePercentiles" : { + "0.0" : 8705755.225413403, + "50.0" : 8723361.412629273, + "90.0" : 8922448.074041035, + "95.0" : 8922448.074041035, + "99.0" : 8922448.074041035, + "99.9" : 8922448.074041035, + "99.99" : 8922448.074041035, + "99.999" : 8922448.074041035, + "99.9999" : 8922448.074041035, + "100.0" : 8922448.074041035 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8720436.253705319, + 8726286.571553228, + 8705755.225413403 + ], + [ + 8922448.074041035, + 8741811.662587412, + 8716025.220383275 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + diff --git a/security/SECURITY_README.md b/security/SECURITY_README.md new file mode 100644 index 0000000000..ecb543ef05 --- /dev/null +++ b/security/SECURITY_README.md @@ -0,0 +1,9 @@ +## Submitting CVE records + +Use https://vulnogram.github.io/ as a UI to write, validate, and submit CVE records. + +In this Vulnogram UI, you'll be able to view a JSON preview of the CVE payload. You'll find a sample payload in this directory. + +It's better to use the Vulnogram UI as it'll provide extra validation of input. + +Also note, as a CNA we do not need to provide a CVSS score for CVEs. This will be done by security vendors instead. diff --git a/security/cve-sample.json b/security/cve-sample.json new file mode 100644 index 0000000000..715d583209 --- /dev/null +++ b/security/cve-sample.json @@ -0,0 +1,75 @@ +{ + "dataType": "CVE_RECORD", + "dataVersion": "5.1", + "cveMetadata": { + "cveId": "", + "assignerOrgId": "00000000-0000-4000-9000-000000000000", + "requesterUserId": "00000000-0000-4000-9000-000000000000", + "serial": 1, + "state": "PUBLISHED" + }, + "containers": { + "cna": { + "providerMetadata": { + "orgId": "00000000-0000-4000-9000-000000000000" + }, + "problemTypes": [ + { + "descriptions": [ + { + "lang": "en", + "description": "" + } + ] + } + ], + "impacts": [ + { + "descriptions": [ + { + "lang": "en", + "value": "" + } + ] + } + ], + "affected": [ + { + "vendor": "GraphQL Java", + "product": "GraphQL Java [or other library]", + "versions": [ + { + "status": "affected", + "version": "" + } + ], + "defaultStatus": "unaffected" + } + ], + "descriptions": [ + { + "lang": "en", + "value": "[PROBLEMTYPE] in [COMPONENT] in [VENDOR] [PRODUCT] [VERSION] on [PLATFORMS] allows [ATTACKER] to [IMPACT] via [VECTOR]", + "supportingMedia": [ + { + "type": "text/html", + "base64": false, + "value": "[PROBLEMTYPE] in [COMPONENT] in [VENDOR] [PRODUCT] [VERSION] on [PLATFORMS] allows [ATTACKER] to [IMPACT] via [VECTOR]" + } + ] + } + ], + "references": [ + { + "url": "https://add-github-links-here" + } + ], + "source": { + "discovery": "UNKNOWN" + }, + "x_generator": { + "engine": "Vulnogram 0.2.0" + } + } + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 72827aa7ad..62e3428491 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,19 @@ -rootProject.name = 'graphql-java' +pluginManagement { + repositories { + mavenCentral() + maven { + url = 'https://plugins.gradle.org/m2' + metadataSources { + // Avoid redirection to defunct JCenter when Gradle module metadata is not published by a plugin (e.g. JMH plugin) + ignoreGradleMetadataRedirection() + mavenPom() + artifact() + } + } + } +} +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} +rootProject.name = 'graphql-java' diff --git a/src/jmh/java/benchmark/AssertBenchmark.java b/src/jmh/java/benchmark/AssertBenchmark.java new file mode 100644 index 0000000000..d3ecc838a7 --- /dev/null +++ b/src/jmh/java/benchmark/AssertBenchmark.java @@ -0,0 +1,90 @@ +package benchmark; + +import graphql.Assert; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 2, time = 5, batchSize = 50) +@Measurement(iterations = 3, batchSize = 50) +@Fork(2) +public class AssertBenchmark { + + private static final int LOOPS = 100; + private static final boolean BOOL = new Random().nextBoolean(); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAssertWithString() { + for (int i = 0; i < LOOPS; i++) { + Assert.assertTrue(jitTrue(), "This string is constant"); + } + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAssertWithStringSupplier() { + for (int i = 0; i < LOOPS; i++) { + Assert.assertTrue(jitTrue(), () -> "This string is constant"); + } + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAssertWithStringSupplierFormatted() { + for (int i = 0; i < LOOPS; i++) { + final int captured = i; + Assert.assertTrue(jitTrue(), () -> String.format("This string is not constant %d", captured)); + } + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAssertWithStringFormatted() { + for (int i = 0; i < LOOPS; i++) { + Assert.assertTrue(jitTrue(), "This string is not constant %d", i); + } + } + + private boolean jitTrue() { + // can you jit this away, Mr JIT?? + //noinspection ConstantValue,SimplifiableConditionalExpression + return BOOL ? BOOL : !BOOL; + } + + public static void main(String[] args) throws RunnerException { + runAtStartup(); + Options opt = new OptionsBuilder() + .include("benchmark.AssertBenchmark") + .build(); + + new Runner(opt).run(); + } + + private static void runAtStartup() { + AssertBenchmark benchMark = new AssertBenchmark(); + BenchmarkUtils.runInToolingForSomeTimeThenExit( + () -> { + }, + benchMark::benchMarkAssertWithStringSupplier, + () -> { + } + + ); + } +} diff --git a/src/jmh/java/benchmark/AstPrinterBenchmark.java b/src/jmh/java/benchmark/AstPrinterBenchmark.java new file mode 100644 index 0000000000..f3eb10d068 --- /dev/null +++ b/src/jmh/java/benchmark/AstPrinterBenchmark.java @@ -0,0 +1,248 @@ +package benchmark; + +import graphql.language.AstPrinter; +import graphql.language.Document; +import graphql.parser.Parser; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3, time = 10) +@Fork(2) +public class AstPrinterBenchmark { + /** + * Note: this query is a redacted version of a real query + */ + private static final Document document = Parser.parse("query fang($slip: dinner!) {\n" + + " instinctive(thin: $slip) {\n" + + " annoy {\n" + + " ...account\n" + + " }\n" + + " massive {\n" + + " ...cellar\n" + + " }\n" + + " used {\n" + + " ...rinse\n" + + " }\n" + + " distinct(sedate: [disarm]) {\n" + + " ...lamp\n" + + " }\n" + + " venomous {\n" + + " uninterested\n" + + " }\n" + + " correct {\n" + + " ...plane\n" + + " }\n" + + " drown\n" + + " talk {\n" + + " house\n" + + " womanly\n" + + " royal {\n" + + " ...snore\n" + + " }\n" + + " gray\n" + + " normal\n" + + " proud\n" + + " crate\n" + + " billowy {\n" + + " frogs\n" + + " abstracted\n" + + " market\n" + + " corn\n" + + " }\n" + + " tip {\n" + + " ...public\n" + + " }\n" + + " stick {\n" + + " ...precious\n" + + " }\n" + + " null {\n" + + " ...precious\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n" + + "\n" + + "fragment account on bath {\n" + + " purpose\n" + + " festive\n" + + " ruddy\n" + + "}\n" + + "\n" + + "fragment cellar on thunder {\n" + + " debonair\n" + + " immense\n" + + " object\n" + + " moon\n" + + " icy {\n" + + " furniture\n" + + " historical\n" + + " team\n" + + " root\n" + + " }\n" + + "}\n" + + "\n" + + "fragment rinse on song {\n" + + " reply {\n" + + " sticks\n" + + " unbecoming\n" + + " }\n" + + " love {\n" + + " annoying\n" + + " sign\n" + + " }\n" + + "}\n" + + "\n" + + "fragment lamp on heartbreaking {\n" + + " innocent\n" + + " decorate\n" + + " pancake\n" + + " arithmetic\n" + + " grey\n" + + " brass\n" + + " pocket\n" + + "}\n" + + "\n" + + "fragment snore on tired {\n" + + " share\n" + + " baseball\n" + + " suspend\n" + + "}\n" + + "\n" + + "fragment settle on incompetent {\n" + + " name\n" + + " juggle\n" + + " depressed\n" + + "}\n" + + "\n" + + "fragment few on puffy {\n" + + " ticket\n" + + " puny\n" + + " copy\n" + + " coast\n" + + "}\n" + + "\n" + + "fragment plane on seat {\n" + + " ice\n" + + " mug\n" + + " wobble\n" + + " clear\n" + + " toys {\n" + + " ...few\n" + + " }\n" + + "}\n" + + "\n" + + "fragment public on basin {\n" + + " different\n" + + " fang\n" + + " slip\n" + + " dinner\n" + + " instinctive\n" + + " thin {\n" + + " annoy {\n" + + " account\n" + + " massive\n" + + " cellar\n" + + " used\n" + + " rinse {\n" + + " distinct\n" + + " }\n" + + " sedate {\n" + + " disarm\n" + + " }\n" + + " lamp {\n" + + " venomous\n" + + " }\n" + + " }\n" + + " uninterested {\n" + + " ...settle\n" + + " }\n" + + " }\n" + + "}\n" + + "\n" + + "fragment precious on drown {\n" + + " talk\n" + + " house\n" + + " womanly\n" + + " royal {\n" + + " snore {\n" + + " gray\n" + + " }\n" + + " normal {\n" + + " proud\n" + + " crate\n" + + " billowy\n" + + " frogs\n" + + " abstracted {\n" + + " ...snore\n" + + " }\n" + + " corn {\n" + + " tip\n" + + " public\n" + + " }\n" + + " stick {\n" + + " ...settle\n" + + " }\n" + + " null {\n" + + " ...few\n" + + " }\n" + + " marry\n" + + " bath {\n" + + " purpose\n" + + " festive\n" + + " }\n" + + " ruddy\n" + + " help\n" + + " thunder\n" + + " debonair {\n" + + " immense\n" + + " }\n" + + " object\n" + + " }\n" + + " }\n" + + "}"); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkAstPrinterThroughput(Blackhole blackhole) { + printAst(blackhole); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAstPrinterAvgTime(Blackhole blackhole) { + printAst(blackhole); + } + + public static void printAst(Blackhole blackhole) { + blackhole.consume(AstPrinter.printAst(document)); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkAstPrinterCompactThroughput(Blackhole blackhole) { + printAstCompact(blackhole); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAstPrinterCompactAvgTime(Blackhole blackhole) { + printAstCompact(blackhole); + } + + public static void printAstCompact(Blackhole blackhole) { + blackhole.consume(AstPrinter.printAstCompact(document)); + } +} diff --git a/src/jmh/java/benchmark/AsyncBenchmark.java b/src/jmh/java/benchmark/AsyncBenchmark.java new file mode 100644 index 0000000000..a2fa43addd --- /dev/null +++ b/src/jmh/java/benchmark/AsyncBenchmark.java @@ -0,0 +1,68 @@ +package benchmark; + +import graphql.execution.Async; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 2) +@Measurement(iterations = 2, timeUnit = TimeUnit.NANOSECONDS) +@Fork(2) +public class AsyncBenchmark { + + @Param({"1", "5", "20"}) + public int numberOfFieldCFs; + + List> futures; + + @Setup(Level.Trial) + public void setUp() throws ExecutionException, InterruptedException { + futures = new ArrayList<>(); + for (int i = 0; i < numberOfFieldCFs; i++) { + futures.add(mkFuture(i)); + } + + } + + private CompletableFuture mkFuture(int i) { + return CompletableFuture.completedFuture(i); + } + + + @Benchmark + @Warmup(iterations = 2, batchSize = 100) + @Measurement(iterations = 2, batchSize = 100) + public List benchmarkAsync() { + Async.CombinedBuilder builder = Async.ofExpectedSize(futures.size()); + futures.forEach(builder::add); + return builder.await().join(); + } + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder() + .include("benchmark.AsyncBenchmark") + .build(); + + new Runner(opt).run(); + } + +} diff --git a/src/jmh/java/benchmark/BenchmarkUtils.java b/src/jmh/java/benchmark/BenchmarkUtils.java new file mode 100644 index 0000000000..c8dda196d0 --- /dev/null +++ b/src/jmh/java/benchmark/BenchmarkUtils.java @@ -0,0 +1,84 @@ +package benchmark; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.Charset; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.Callable; + +public class BenchmarkUtils { + + @SuppressWarnings("UnstableApiUsage") + static String loadResource(String name) { + return asRTE(() -> { + URL resource = BenchmarkUtils.class.getClassLoader().getResource(name); + if (resource == null) { + throw new IllegalArgumentException("missing resource: " + name); + } + byte[] bytes; + try (InputStream inputStream = resource.openStream()) { + bytes = inputStream.readAllBytes(); + } + return new String(bytes, Charset.defaultCharset()); + }); + } + + static T asRTE(Callable callable) { + try { + return callable.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void runInToolingForSomeTimeThenExit(Runnable setup, Runnable r, Runnable tearDown) { + int runForMillis = getRunForMillis(); + if (runForMillis <= 0) { + System.out.print("'runForMillis' environment var is not set - continuing \n"); + return; + } + System.out.printf("Running initial code in some tooling - runForMillis=%d \n", runForMillis); + System.out.print("Get your tooling in order and press enter..."); + readLine(); + System.out.print("Lets go...\n"); + setup.run(); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss"); + long now, then = System.currentTimeMillis(); + do { + now = System.currentTimeMillis(); + long msLeft = runForMillis - (now - then); + System.out.printf("\t%s Running in loop... %s ms left\n", dtf.format(LocalDateTime.now()), msLeft); + r.run(); + now = System.currentTimeMillis(); + } while ((now - then) < runForMillis); + + tearDown.run(); + + System.out.printf("This ran for %d millis. Exiting...\n", System.currentTimeMillis() - then); + System.exit(0); + } + + private static void readLine() { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + try { + br.readLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static int getRunForMillis() { + String runFor = System.getenv("runForMillis"); + try { + return Integer.parseInt(runFor); + } catch (NumberFormatException e) { + return -1; + } + } + +} diff --git a/src/jmh/java/benchmark/ChainedInstrumentationBenchmark.java b/src/jmh/java/benchmark/ChainedInstrumentationBenchmark.java new file mode 100644 index 0000000000..da28bdbade --- /dev/null +++ b/src/jmh/java/benchmark/ChainedInstrumentationBenchmark.java @@ -0,0 +1,85 @@ +package benchmark; + +import graphql.ExecutionInput; +import graphql.execution.instrumentation.ChainedInstrumentation; +import graphql.execution.instrumentation.Instrumentation; +import graphql.execution.instrumentation.InstrumentationState; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import static graphql.Scalars.GraphQLString; +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; +import static graphql.schema.GraphQLObjectType.newObject; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class ChainedInstrumentationBenchmark { + + @Param({"0", "1", "10"}) + public int num; + + ChainedInstrumentation chainedInstrumentation; + GraphQLSchema schema; + InstrumentationExecutionParameters parameters; + InstrumentationState instrumentationState; + + @Setup(Level.Trial) + public void setUp() throws ExecutionException, InterruptedException { + GraphQLObjectType queryType = newObject() + .name("benchmarkQuery") + .field(newFieldDefinition() + .type(GraphQLString) + .name("benchmark")) + .build(); + schema = GraphQLSchema.newSchema() + .query(queryType) + .build(); + + ExecutionInput executionInput = ExecutionInput.newExecutionInput().query("benchmark").build(); + InstrumentationCreateStateParameters createStateParameters = new InstrumentationCreateStateParameters(schema, executionInput); + + List instrumentations = Collections.nCopies(num, new SimplePerformantInstrumentation()); + chainedInstrumentation = new ChainedInstrumentation(instrumentations); + instrumentationState = chainedInstrumentation.createStateAsync(createStateParameters).get(); + parameters = new InstrumentationExecutionParameters(executionInput, schema); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + public GraphQLSchema benchmarkInstrumentSchema() { + return chainedInstrumentation.instrumentSchema(schema, parameters, instrumentationState); + } + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder() + .include("benchmark.ChainedInstrumentationBenchmark") + .forks(1) + .build(); + + new Runner(opt).run(); + } + +} diff --git a/src/jmh/java/benchmark/CompletableFuturesBenchmark.java b/src/jmh/java/benchmark/CompletableFuturesBenchmark.java new file mode 100644 index 0000000000..746a1fb194 --- /dev/null +++ b/src/jmh/java/benchmark/CompletableFuturesBenchmark.java @@ -0,0 +1,108 @@ +package benchmark; + +import com.google.common.collect.ImmutableList; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 1) +@Measurement(iterations = 3, time = 10, batchSize = 10) +@Fork(2) +public class CompletableFuturesBenchmark { + + + @Param({"2", "5"}) + public int depth; + public int howMany = 10; + + @Setup(Level.Trial) + public void setUp() { + } + + private List> mkCFObjects(int howMany, int depth) { + if (depth <= 0) { + return Collections.emptyList(); + } + ImmutableList.Builder> builder = ImmutableList.builder(); + for (int i = 0; i < howMany; i++) { + CompletableFuture cf = CompletableFuture.completedFuture(mkCFObjects(howMany, depth - 1)); + builder.add(cf); + } + return builder.build(); + } + + private List mkObjects(int howMany, int depth) { + if (depth <= 0) { + return Collections.emptyList(); + } + ImmutableList.Builder builder = ImmutableList.builder(); + for (int i = 0; i < howMany; i++) { + Object obj = mkObjects(howMany, depth - 1); + builder.add(obj); + } + return builder.build(); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void benchmarkCFApproach() { + // make results + List> completableFutures = mkCFObjects(howMany, depth); + // traverse results + traverseCFS(completableFutures); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void benchmarkMaterializedApproach() { + // make results + List objects = mkObjects(howMany, depth); + // traverse results + traverseObjects(objects); + } + + @SuppressWarnings("unchecked") + private void traverseCFS(List> completableFutures) { + for (CompletableFuture completableFuture : completableFutures) { + // and when it's done - visit its child results - which are always immediate on completed CFs + // so this whenComplete executed now + completableFuture.whenComplete((list, t) -> { + List> cfs = (List>) list; + traverseCFS(cfs); + }); + } + } + + @SuppressWarnings("unchecked") + private void traverseObjects(List objects) { + for (Object object : objects) { + List list = (List) object; + traverseObjects(list); + } + } + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder() + .include("benchmark.CompletableFuturesBenchmark") + .build(); + + new Runner(opt).run(); + } + +} diff --git a/src/jmh/java/benchmark/ComplexQueryBenchmark.java b/src/jmh/java/benchmark/ComplexQueryBenchmark.java new file mode 100644 index 0000000000..07e9a6c1b8 --- /dev/null +++ b/src/jmh/java/benchmark/ComplexQueryBenchmark.java @@ -0,0 +1,272 @@ +package benchmark; + +import com.google.common.collect.ImmutableList; +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.profile.GCProfiler; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; + +/** + * This benchmark is an attempt to have a more complex query that involves async and sync work together + * along with multiple threads happening. + *

+ * It can also be run in a forever mode say if you want to connect a profiler to it say + */ +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 2) +@Fork(2) +public class ComplexQueryBenchmark { + + @Param({"5", "10", "20"}) + int howManyItems = 5; + int howLongToSleep = 5; + int howManyQueries = 10; + int howManyQueryThreads = 10; + int howManyFetcherThreads = 10; + + ExecutorService queryExecutorService; + ExecutorService fetchersExecutorService; + GraphQL graphQL; + volatile boolean shutDown; + + @Setup(Level.Trial) + public void setUp() { + shutDown = false; + queryExecutorService = Executors.newFixedThreadPool(howManyQueryThreads); + fetchersExecutorService = Executors.newFixedThreadPool(howManyFetcherThreads); + graphQL = buildGraphQL(); + } + + @TearDown(Level.Trial) + public void tearDown() { + shutDown = true; + queryExecutorService.shutdownNow(); + fetchersExecutorService.shutdownNow(); + } + + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public Object benchMarkSimpleQueriesThroughput() { + return runManyQueriesToCompletion(); + } + + + public static void main(String[] args) throws Exception { + // just to make sure it's all valid before testing + runAtStartup(); + + Options opt = new OptionsBuilder() + .include("benchmark.ComplexQueryBenchmark") + .addProfiler(GCProfiler.class) + .build(); + + new Runner(opt).run(); + } + + @SuppressWarnings({"ConstantValue", "LoopConditionNotUpdatedInsideLoop"}) + private static void runAtStartup() { + + ComplexQueryBenchmark complexQueryBenchmark = new ComplexQueryBenchmark(); + complexQueryBenchmark.howManyQueries = 5; + complexQueryBenchmark.howManyItems = 10; + + BenchmarkUtils.runInToolingForSomeTimeThenExit( + complexQueryBenchmark::setUp, + complexQueryBenchmark::runManyQueriesToCompletion, + complexQueryBenchmark::tearDown + + ); + } + + + + @SuppressWarnings("UnnecessaryLocalVariable") + private Void runManyQueriesToCompletion() { + CompletableFuture[] cfs = new CompletableFuture[howManyQueries]; + for (int i = 0; i < howManyQueries; i++) { + cfs[i] = CompletableFuture.supplyAsync(() -> executeQuery(howManyItems, howLongToSleep), queryExecutorService).thenCompose(cf -> cf); + } + Void result = CompletableFuture.allOf(cfs).join(); + return result; + } + + public CompletableFuture executeQuery(int howMany, int howLong) { + String fields = "id name f1 f2 f3 f4 f5 f6 f7 f8 f9 f10"; + String query = "query q {" + + String.format("shops(howMany : %d) { %s departments( howMany : %d) { %s products(howMany : %d) { %s }}}\n" + , howMany, fields, 10, fields, 5, fields) + + String.format("expensiveShops(howMany : %d howLong : %d) { %s expensiveDepartments( howMany : %d howLong : %d) { %s expensiveProducts(howMany : %d howLong : %d) { %s }}}\n" + , howMany, howLong, fields, 10, howLong, fields, 5, howLong, fields) + + "}"; + return graphQL.executeAsync(ExecutionInput.newExecutionInput(query).build()); + } + + private GraphQL buildGraphQL() { + TypeDefinitionRegistry definitionRegistry = new SchemaParser().parse(BenchmarkUtils.loadResource("storesanddepartments.graphqls")); + + DataFetcher shopsDF = env -> mkHowManyThings(env.getArgument("howMany")); + DataFetcher expensiveShopsDF = env -> supplyAsync(() -> sleepAndReturnThings(env)); + DataFetcher departmentsDF = env -> mkHowManyThings(env.getArgument("howMany")); + DataFetcher expensiveDepartmentsDF = env -> supplyAsyncListItems(env, () -> sleepAndReturnThings(env)); + DataFetcher productsDF = env -> mkHowManyThings(env.getArgument("howMany")); + DataFetcher expensiveProductsDF = env -> supplyAsyncListItems(env, () -> sleepAndReturnThings(env)); + + RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("shops", shopsDF) + .dataFetcher("expensiveShops", expensiveShopsDF)) + .type(newTypeWiring("Shop") + .dataFetcher("departments", departmentsDF) + .dataFetcher("expensiveDepartments", expensiveDepartmentsDF)) + .type(newTypeWiring("Department") + .dataFetcher("products", productsDF) + .dataFetcher("expensiveProducts", expensiveProductsDF)) + .build(); + + GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(definitionRegistry, runtimeWiring); + + return GraphQL.newGraphQL(graphQLSchema).build(); + } + + private CompletableFuture supplyAsyncListItems(DataFetchingEnvironment environment, Supplier codeToRun) { + return supplyAsync(codeToRun); + } + + private CompletableFuture supplyAsync(Supplier codeToRun) { + if (!shutDown) { + //logEvery(100, "async fetcher"); + return CompletableFuture.supplyAsync(codeToRun, fetchersExecutorService); + } else { + // if we have shutdown - get on with it, so we shut down quicker + return CompletableFuture.completedFuture(codeToRun.get()); + } + } + + private List sleepAndReturnThings(DataFetchingEnvironment env) { + // by sleeping, we hope to cause the objects to stay longer in GC land and hence have a longer lifecycle + // then a simple stack say or young gen gc. I don't know this will work, but I am trying it + // to represent work that takes some tie to complete + sleep(env.getArgument("howLong")); + return mkHowManyThings(env.getArgument("howMany")); + } + + private void sleep(Integer howLong) { + if (howLong > 0) { + try { + Thread.sleep(howLong); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + AtomicInteger logCount = new AtomicInteger(); + + private void logEvery(int every, String s) { + int count = logCount.getAndIncrement(); + if (count == 0 || count % every == 0) { + System.out.println("\t" + count + "\t" + s); + } + } + + private List mkHowManyThings(Integer howMany) { + ImmutableList.Builder builder = ImmutableList.builder(); + for (int i = 0; i < howMany; i++) { + builder.add(new IdAndNamedThing(i)); + } + return builder.build(); + } + + @SuppressWarnings("unused") + static class IdAndNamedThing { + private final int i; + + public IdAndNamedThing(int i) { + this.i = i; + } + + public String getId() { + return "id" + i; + } + + public String getName() { + return "name" + i; + } + + public String getF1() { + return "f1" + i; + } + + public String getF2() { + return "f2" + i; + } + + public String getF3() { + return "f3" + i; + } + + public String getF4() { + return "f4" + i; + } + + public String getF5() { + return "f5" + i; + } + + public String getF6() { + return "f6" + i; + } + + public String getF7() { + return "f7" + i; + } + + public String getF8() { + return "f8" + i; + } + + public String getF9() { + return "f9" + i; + } + + public String getF10() { + return "f10" + i; + } + } +} diff --git a/src/jmh/java/benchmark/CreateExtendedSchemaBenchmark.java b/src/jmh/java/benchmark/CreateExtendedSchemaBenchmark.java new file mode 100644 index 0000000000..54ade0d761 --- /dev/null +++ b/src/jmh/java/benchmark/CreateExtendedSchemaBenchmark.java @@ -0,0 +1,121 @@ +package benchmark; + +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; + +import static benchmark.BenchmarkUtils.runInToolingForSomeTimeThenExit; + +/** + * This JMH + */ +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class CreateExtendedSchemaBenchmark { + + private static final String SDL = mkSDL(); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MINUTES) + public void benchmarkLargeSchemaCreate(Blackhole blackhole) { + blackhole.consume(createSchema(SDL)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkLargeSchemaCreateAvgTime(Blackhole blackhole) { + blackhole.consume(createSchema(SDL)); + } + + private static GraphQLSchema createSchema(String sdl) { + TypeDefinitionRegistry registry = new SchemaParser().parse(sdl); + return new SchemaGenerator().makeExecutableSchema(registry, RuntimeWiring.MOCKED_WIRING); + } + + /* something like + type Query { q : String } interface I { f : String } + interface I1 implements I { + f : String + f1 : String + } + type O1_1 implements I1 & I { + f : String + f1 : String + } + type O1_2 implements I1 & I { + f : String + f1 : String + } + */ + private static String mkSDL() { + int numTypes = 10000; + int numExtends = 10; + + StringBuilder sb = new StringBuilder(); + sb.append("type Query { q : String } interface I { f : String } interface X { x : String }\n"); + for (int i = 0; i < numTypes; i++) { + sb.append("interface I").append(i).append(" implements I { \n") + .append("\tf : String \n") + .append("\tf").append(i).append(" : String \n").append("}\n"); + + sb.append("type O").append(i).append(" implements I").append(i).append(" & I { \n") + .append("\tf : String \n") + .append("\tf").append(i).append(" : String \n") + .append("}\n"); + + sb.append("extend type O").append(i).append(" implements X").append(" { \n") + .append("\tx : String \n") + .append("}\n"); + + for (int j = 0; j < numExtends; j++) { + sb.append("extend type O").append(i).append(" { \n") + .append("\textendedF").append(j).append(" : String \n") + .append("}\n"); + + } + } + return sb.toString(); + } + + public static void main(String[] args) throws RunnerException { + try { + runAtStartup(); + } catch (Throwable e) { + throw new RuntimeException(e); + } + Options opt = new OptionsBuilder() + .include("benchmark.CreateExtendedSchemaBenchmark") + .build(); + + new Runner(opt).run(); + } + + private static void runAtStartup() { + runInToolingForSomeTimeThenExit( + () -> { + }, + () -> createSchema(SDL), + () -> { + } + ); + } +} \ No newline at end of file diff --git a/src/jmh/java/benchmark/CreateSchemaBenchmark.java b/src/jmh/java/benchmark/CreateSchemaBenchmark.java new file mode 100644 index 0000000000..6d20990415 --- /dev/null +++ b/src/jmh/java/benchmark/CreateSchemaBenchmark.java @@ -0,0 +1,57 @@ +package benchmark; + +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class CreateSchemaBenchmark { + + static String largeSDL = BenchmarkUtils.loadResource("large-schema-3.graphqls"); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MINUTES) + public void benchmarkLargeSchemaCreate(Blackhole blackhole) { + blackhole.consume(createSchema(largeSDL)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkLargeSchemaCreateAvgTime(Blackhole blackhole) { + blackhole.consume(createSchema(largeSDL)); + } + + private static GraphQLSchema createSchema(String sdl) { + TypeDefinitionRegistry registry = new SchemaParser().parse(sdl); + return new SchemaGenerator().makeExecutableSchema(registry, RuntimeWiring.MOCKED_WIRING); + } + + @SuppressWarnings("InfiniteLoopStatement") + /// make this a main method if you want to run it in JProfiler etc.. + public static void mainXXX(String[] args) { + int i = 0; + while (true) { + createSchema(largeSDL); + i++; + if (i % 100 == 0) { + System.out.printf("%d\n", i); + } + } + } +} \ No newline at end of file diff --git a/src/jmh/java/benchmark/GetterAccessBenchmark.java b/src/jmh/java/benchmark/GetterAccessBenchmark.java new file mode 100644 index 0000000000..5bf8811609 --- /dev/null +++ b/src/jmh/java/benchmark/GetterAccessBenchmark.java @@ -0,0 +1,74 @@ +package benchmark; + +import graphql.schema.fetching.LambdaFetchingSupport; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.function.Function; + +@Warmup(iterations = 2, time = 5, batchSize = 500) +@Measurement(iterations = 3, batchSize = 500) +@Fork(2) +public class GetterAccessBenchmark { + + public static class Pojo { + final String name; + final int age; + + public Pojo(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + } + + static Pojo pojo = new Pojo("Brad", 42); + + static Function getter = LambdaFetchingSupport.createGetter(Pojo.class, "name").get(); + + static Method getterMethod; + + static { + try { + getterMethod = Pojo.class.getMethod("getName"); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + + @Benchmark + public void measureDirectAccess(Blackhole bh) { + Object name = pojo.getName(); + bh.consume(name); + } + + @Benchmark + public void measureLambdaAccess(Blackhole bh) { + Object value = getter.apply(pojo); + bh.consume(value); + } + + @Benchmark + public void measureReflectionAccess(Blackhole bh) { + try { + Object name = getterMethod.invoke(pojo); + bh.consume(name); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } +} + diff --git a/src/jmh/java/benchmark/IntrospectionBenchmark.java b/src/jmh/java/benchmark/IntrospectionBenchmark.java new file mode 100644 index 0000000000..261a64047a --- /dev/null +++ b/src/jmh/java/benchmark/IntrospectionBenchmark.java @@ -0,0 +1,57 @@ +package benchmark; + +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.introspection.IntrospectionQuery; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class IntrospectionBenchmark { + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public ExecutionResult benchMarkIntrospectionAvgTime() { + return graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + public ExecutionResult benchMarkIntrospectionThroughput() { + return graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY); + } + + private final GraphQL graphQL; + + + public IntrospectionBenchmark() { + String largeSchema = BenchmarkUtils.loadResource("large-schema-4.graphqls"); + GraphQLSchema graphQLSchema = SchemaGenerator.createdMockedSchema(largeSchema); + graphQL = GraphQL.newGraphQL(graphQLSchema) + .build(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include("benchmark.IntrospectionBenchmark") + .build(); + + new Runner(opt).run(); + } + +} diff --git a/src/jmh/java/benchmark/MapBenchmark.java b/src/jmh/java/benchmark/MapBenchmark.java new file mode 100644 index 0000000000..50cbe576f5 --- /dev/null +++ b/src/jmh/java/benchmark/MapBenchmark.java @@ -0,0 +1,92 @@ +package benchmark; + +import com.google.common.collect.ImmutableMap; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Random; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 1) +@Measurement(iterations = 3, time = 1, batchSize = 1000) +@Fork(2) +public class MapBenchmark { + + @Param({"10", "50", "300"}) + int numberEntries = 300; + + Map hashMap; + Map linkedHashMap; + Map immutableMap; + + Random random; + + @Setup(Level.Trial) + public void setUp() { + random = new Random(); + linkedHashMap = new LinkedHashMap<>(); + for (int i = 0; i < numberEntries; i++) { + linkedHashMap.put("string" + i, i); + } + hashMap = new HashMap<>(); + for (int i = 0; i < numberEntries; i++) { + hashMap.put("string" + i, i); + } + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (int i = 0; i < numberEntries; i++) { + builder.put("string" + i, i); + } + immutableMap = builder.build(); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void benchmarkLinkedHashMap(Blackhole blackhole) { + mapGet(blackhole, linkedHashMap); + } + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void benchmarkHashMap(Blackhole blackhole) { + mapGet(blackhole, hashMap); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void benchmarkImmutableMap(Blackhole blackhole) { + mapGet(blackhole, immutableMap); + } + + private void mapGet(Blackhole blackhole, Map mapp) { + int index = rand(0, numberEntries); + blackhole.consume(mapp.get("string" + index)); + } + + private int rand(int loInc, int hiExc) { + return random.nextInt(hiExc - loInc) + loInc; + } + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder() + .include("benchmark.MapBenchmark") + .build(); + + new Runner(opt).run(); + } +} + diff --git a/src/jmh/java/benchmark/OverlappingFieldValidationBenchmark.java b/src/jmh/java/benchmark/OverlappingFieldValidationBenchmark.java new file mode 100644 index 0000000000..837a0f639e --- /dev/null +++ b/src/jmh/java/benchmark/OverlappingFieldValidationBenchmark.java @@ -0,0 +1,86 @@ +package benchmark; + +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.i18n.I18n; +import graphql.language.Document; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import graphql.validation.LanguageTraversal; +import graphql.validation.RulesVisitor; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationError; +import graphql.validation.ValidationErrorCollector; +import graphql.validation.rules.OverlappingFieldsCanBeMerged; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import static graphql.Assert.assertTrue; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class OverlappingFieldValidationBenchmark { + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + Document document; + + @Setup + public void setup() { + try { + String schemaString = BenchmarkUtils.loadResource("large-schema-4.graphqls"); + String query = BenchmarkUtils.loadResource("large-schema-4-query.graphql"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + document = Parser.parse(query); + + // make sure this is a valid query overall + GraphQL graphQL = GraphQL.newGraphQL(schema).build(); + ExecutionResult executionResult = graphQL.execute(query); + assertTrue(executionResult.getErrors().size() == 0); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public void overlappingFieldValidationAbgTime(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema, myState.document)); + } + + @Benchmark + @OutputTimeUnit(TimeUnit.SECONDS) + public void overlappingFieldValidationThroughput(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema, myState.document)); + } + + private List validateQuery(GraphQLSchema schema, Document document) { + ValidationErrorCollector errorCollector = new ValidationErrorCollector(); + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH); + ValidationContext validationContext = new ValidationContext(schema, document, i18n); + OverlappingFieldsCanBeMerged overlappingFieldsCanBeMerged = new OverlappingFieldsCanBeMerged(validationContext, errorCollector); + LanguageTraversal languageTraversal = new LanguageTraversal(); + languageTraversal.traverse(document, new RulesVisitor(validationContext, Collections.singletonList(overlappingFieldsCanBeMerged))); + return errorCollector.getErrors(); + } +} diff --git a/src/jmh/java/benchmark/PropertyFetcherBenchMark.java b/src/jmh/java/benchmark/PropertyFetcherBenchMark.java new file mode 100644 index 0000000000..7bb85410ef --- /dev/null +++ b/src/jmh/java/benchmark/PropertyFetcherBenchMark.java @@ -0,0 +1,63 @@ +package benchmark; + +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.DataFetchingEnvironmentImpl; +import graphql.schema.PropertyDataFetcher; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 2, time = 5, batchSize = 50) +@Measurement(iterations = 3, batchSize = 50) +@Fork(2) +public class PropertyFetcherBenchMark { + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkThroughputInDirectClassHierarchy(Blackhole blackhole) { + executeTest(blackhole, dfeFoo); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkThroughputDirectClassHierarchy(Blackhole blackhole) { + executeTest(blackhole, dfeBar); + } + + static PropertyDataFetcher nameFetcher = PropertyDataFetcher.fetching("name"); + + static DataFetchingEnvironment dfeFoo = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().source(new Foo("brad")).build(); + static DataFetchingEnvironment dfeBar = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().source(new Bar("brad")).build(); + + public static void executeTest(Blackhole blackhole, DataFetchingEnvironment dfe) { + blackhole.consume(nameFetcher.get(dfe)); + } + + static class Foo extends Bar { + + Foo(String name) { + super(name); + } + } + + static class Bar { + private final String name; + + Bar(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } +} diff --git a/src/jmh/java/benchmark/QueryExecutionOrientedBenchmarks.java b/src/jmh/java/benchmark/QueryExecutionOrientedBenchmarks.java new file mode 100644 index 0000000000..96166a0f5f --- /dev/null +++ b/src/jmh/java/benchmark/QueryExecutionOrientedBenchmarks.java @@ -0,0 +1,23 @@ +package benchmark; + +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +/** + * A runner of benchmarks that are whole query runners and they do + * so from the top of the stack all the way in + */ +public class QueryExecutionOrientedBenchmarks { + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include("benchmark.ComplexQueryBenchmark") + .include("benchmark.IntrospectionBenchmark") + .include("benchmark.TwitterBenchmark") + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/jmh/java/benchmark/SchemaTransformerBenchmark.java b/src/jmh/java/benchmark/SchemaTransformerBenchmark.java new file mode 100644 index 0000000000..353dd0253e --- /dev/null +++ b/src/jmh/java/benchmark/SchemaTransformerBenchmark.java @@ -0,0 +1,117 @@ +package benchmark; + +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.SchemaTransformer; +import graphql.schema.idl.SchemaGenerator; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3, time = 10) +@Fork(2) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class SchemaTransformerBenchmark { + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + GraphQLSchema txSchema; + + GraphQLDirective infoDirective = GraphQLDirective.newDirective() + .name("Info") + .build(); + GraphQLTypeVisitor directiveAdder = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + // add directive + GraphQLFieldDefinition changedNode = node.transform(builder -> { + builder.withDirective(infoDirective); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + // add directive info + GraphQLObjectType changedNode = node.transform(builder -> { + builder.withDirective(infoDirective); + }); + return changeNode(context, changedNode); + } + }; + + GraphQLTypeVisitor directiveRemover = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + List filteredDirectives = node.getDirectives().stream() + .filter(d -> !d.getName().equals(infoDirective.getName())) + .collect(Collectors.toList()); + // remove directive info + GraphQLFieldDefinition changedNode = node.transform(builder -> { + builder.replaceDirectives(filteredDirectives); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + List filteredDirectives = node.getDirectives().stream() + .filter(d -> !d.getName().equals(infoDirective.getName())) + .collect(Collectors.toList()); + // remove directive info + GraphQLObjectType changedNode = node.transform(builder -> { + builder.replaceDirectives(filteredDirectives); + }); + return changeNode(context, changedNode); + } + }; + + @Setup + public void setup() { + try { + String schemaString = BenchmarkUtils.loadResource("large-schema-3.graphqls"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + txSchema = SchemaTransformer.transformSchema(schema, directiveAdder); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + } + + @Benchmark + public GraphQLSchema benchMarkSchemaTransformerAdd(MyState myState) { + GraphQLSchema schema = myState.schema; + return SchemaTransformer.transformSchema(schema, myState.directiveAdder); + } + + + @Benchmark + public GraphQLSchema benchMarkSchemaTransformerRemove(MyState myState) { + GraphQLSchema schema = myState.txSchema; + return SchemaTransformer.transformSchema(schema, myState.directiveRemover); + } +} diff --git a/src/jmh/java/benchmark/SimpleQueryBenchmark.java b/src/jmh/java/benchmark/SimpleQueryBenchmark.java new file mode 100644 index 0000000000..fe95a7b833 --- /dev/null +++ b/src/jmh/java/benchmark/SimpleQueryBenchmark.java @@ -0,0 +1,102 @@ +package benchmark; + +import graphql.Assert; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.execution.ExecutionStepInfo; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLSchema; +import graphql.schema.TypeResolver; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; + +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class SimpleQueryBenchmark { + + private static final int NUMBER_OF_FRIENDS = 10 * 100; + private static final GraphQL GRAPHQL = buildGraphQL(); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public ExecutionResult benchMarkSimpleQueriesThroughput() { + return executeQuery(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public ExecutionResult benchMarkSimpleQueriesAvgTime() { + return executeQuery(); + } + + public static ExecutionResult executeQuery() { + String query = "{ hero { name friends { name friends { name } } } }"; + return GRAPHQL.execute(query); + } + + private static GraphQL buildGraphQL() { + TypeDefinitionRegistry definitionRegistry = new SchemaParser().parse(BenchmarkUtils.loadResource("starWarsSchema.graphqls")); + + DataFetcher heroDataFetcher = environment -> CharacterDTO.mkCharacter(environment, "r2d2", NUMBER_OF_FRIENDS); + TypeResolver typeResolver = env -> env.getSchema().getObjectType("Human"); + + RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("QueryType").dataFetcher("hero", heroDataFetcher)) + .type(newTypeWiring("Character").typeResolver(typeResolver)) + .build(); + + GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(definitionRegistry, runtimeWiring); + + return GraphQL.newGraphQL(graphQLSchema) + .build(); + } + + static class CharacterDTO { + private final String name; + private final List friends; + + CharacterDTO(String name, List friends) { + this.name = name; + this.friends = friends; + } + + public String getName() { + return name; + } + + public List getFriends() { + return friends; + } + + public static CharacterDTO mkCharacter(DataFetchingEnvironment environment, String name, int friendCount) { + Object sideEffect = environment.getArgument("episode"); + Assert.assertNull(sideEffect); + ExecutionStepInfo anotherSideEffect = environment.getExecutionStepInfo(); + Assert.assertNotNull(anotherSideEffect); + List friends = new ArrayList<>(friendCount); + for (int i = 0; i < friendCount; i++) { + friends.add(mkCharacter(environment, "friend" + i, 0)); + } + return new CharacterDTO(name, friends); + } + } +} diff --git a/src/jmh/java/benchmark/TwitterBenchmark.java b/src/jmh/java/benchmark/TwitterBenchmark.java new file mode 100644 index 0000000000..8fe58b0822 --- /dev/null +++ b/src/jmh/java/benchmark/TwitterBenchmark.java @@ -0,0 +1,148 @@ +package benchmark; + +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.execution.preparsed.persisted.InMemoryPersistedQueryCache; +import graphql.execution.preparsed.persisted.PersistedQueryCache; +import graphql.execution.preparsed.persisted.PersistedQuerySupport; +import graphql.parser.ParserOptions; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLTypeReference; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import static graphql.Scalars.GraphQLString; + +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class TwitterBenchmark { + private static final int BREADTH = 150; + private static final int DEPTH = 150; + + static String query = mkQuery(); + static Object queryId = "QUERY_ID"; + static GraphQL graphQL = buildGraphQL(); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchmarkThroughput(Blackhole bh) { + bh.consume(execute()); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public void benchmarkAvgTime(Blackhole bh) { + bh.consume(execute()); + } + + private static ExecutionResult execute() { + return graphQL.execute(query); + } + + public static String mkQuery() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + for (int d = 1; d <= DEPTH; d++) { + for (int b = 1; b <= BREADTH; b++) { + sb.append("leaf_"); + sb.append(b); + sb.append(" "); + } + if (d < DEPTH) { + sb.append("branch { "); + } + } + for (int d = 1; d <= DEPTH; d++) { + sb.append("}"); + } + return sb.toString(); + } + + private static GraphQL buildGraphQL() { + ParserOptions.setDefaultOperationParserOptions(ParserOptions.newParserOptions().maxTokens(100_000).build()); + + List leafFields = new ArrayList<>(BREADTH); + for (int i = 1; i <= BREADTH; i++) { + leafFields.add( + GraphQLFieldDefinition.newFieldDefinition() + .name("leaf_" + i) + .type(GraphQLString) + .build() + ); + } + + GraphQLObjectType branchType = GraphQLObjectType.newObject() + .name("Branch") + .fields(leafFields) + .field(GraphQLFieldDefinition.newFieldDefinition() + .name("branch") + .type(GraphQLTypeReference.typeRef("Branch"))) + .build(); + + + DataFetcher simpleFetcher = env -> env.getField().getName(); + GraphQLCodeRegistry codeReg = GraphQLCodeRegistry.newCodeRegistry() + .defaultDataFetcher( + environment -> simpleFetcher + ) + .build(); + + GraphQLSchema graphQLSchema = GraphQLSchema.newSchema() + .query(branchType) + .codeRegistry(codeReg) + .build(); + + return GraphQL + .newGraphQL(graphQLSchema) + .preparsedDocumentProvider( + new PersistedQuery( + InMemoryPersistedQueryCache + .newInMemoryPersistedQueryCache() + .addQuery(queryId, query) + .build() + ) + ) + .build(); + } + + static class PersistedQuery extends PersistedQuerySupport { + public PersistedQuery(PersistedQueryCache persistedQueryCache) { + super(persistedQueryCache); + } + + @Override + protected Optional getPersistedQueryId(ExecutionInput executionInput) { + return Optional.of(queryId); + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include("benchmark.TwitterBenchmark") + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/jmh/java/benchmark/TypeDefinitionParserVersusSerializeBenchmark.java b/src/jmh/java/benchmark/TypeDefinitionParserVersusSerializeBenchmark.java new file mode 100644 index 0000000000..a27444b558 --- /dev/null +++ b/src/jmh/java/benchmark/TypeDefinitionParserVersusSerializeBenchmark.java @@ -0,0 +1,65 @@ +package benchmark; + +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.concurrent.TimeUnit; + +import static benchmark.BenchmarkUtils.asRTE; + +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class TypeDefinitionParserVersusSerializeBenchmark { + + static SchemaParser schemaParser = new SchemaParser(); + static String SDL = BenchmarkUtils.loadResource("large-schema-2.graphqls"); + static TypeDefinitionRegistry registryOut = schemaParser.parse(SDL); + static ByteArrayOutputStream baOS = serialisedRegistryStream(registryOut); + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkParsing(Blackhole blackhole) { + blackhole.consume(schemaParser.parse(SDL)); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkSerializing(Blackhole blackhole) { + blackhole.consume(serialise()); + } + + static TypeDefinitionRegistry serialise() { + return asRTE(() -> { + + ByteArrayInputStream baIS = new ByteArrayInputStream(baOS.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(baIS); + + return (TypeDefinitionRegistry) ois.readObject(); + }); + } + + private static ByteArrayOutputStream serialisedRegistryStream(TypeDefinitionRegistry registryOut) { + return asRTE(() -> { + ByteArrayOutputStream baOS = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baOS); + + oos.writeObject(registryOut); + return baOS; + }); + } +} diff --git a/src/jmh/java/benchmark/ValidatorBenchmark.java b/src/jmh/java/benchmark/ValidatorBenchmark.java new file mode 100644 index 0000000000..f9dd34a0c8 --- /dev/null +++ b/src/jmh/java/benchmark/ValidatorBenchmark.java @@ -0,0 +1,96 @@ +package benchmark; + +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.language.Document; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import graphql.validation.Validator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import static graphql.Assert.assertTrue; + + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class ValidatorBenchmark { + + private static class Scenario { + public final GraphQLSchema schema; + public final Document document; + + Scenario(GraphQLSchema schema, Document document) { + this.schema = schema; + this.document = document; + } + } + + @State(Scope.Benchmark) + public static class MyState { + Scenario largeSchema1; + Scenario largeSchema4; + Scenario manyFragments; + + @Setup + public void setup() { + largeSchema1 = load("large-schema-1.graphqls", "large-schema-1-query.graphql"); + largeSchema4 = load("large-schema-4.graphqls", "large-schema-4-query.graphql"); + manyFragments = load("many-fragments.graphqls", "many-fragments-query.graphql"); + } + + private Scenario load(String schemaPath, String queryPath) { + try { + String schemaString = BenchmarkUtils.loadResource(schemaPath); + String query = BenchmarkUtils.loadResource(queryPath); + GraphQLSchema schema = SchemaGenerator.createdMockedSchema(schemaString); + Document document = Parser.parse(query); + + // make sure this is a valid query overall + GraphQL graphQL = GraphQL.newGraphQL(schema).build(); + ExecutionResult executionResult = graphQL.execute(query); + assertTrue(executionResult.getErrors().size() == 0); + return new Scenario(schema, document); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + } + + private void run(Scenario scenario) { + Validator validator = new Validator(); + validator.validateDocument(scenario.schema, scenario.document, Locale.ENGLISH); + } + + @Benchmark + public void largeSchema1(MyState state) { + run(state.largeSchema1); + } + + @Benchmark + public void largeSchema4(MyState state) { + run(state.largeSchema4); + } + + @Benchmark + public void manyFragments(MyState state) { + run(state.manyFragments); + } +} diff --git a/src/jmh/java/graphql/execution/ExecutionStepInfoBenchmark.java b/src/jmh/java/graphql/execution/ExecutionStepInfoBenchmark.java new file mode 100644 index 0000000000..e2678c67f8 --- /dev/null +++ b/src/jmh/java/graphql/execution/ExecutionStepInfoBenchmark.java @@ -0,0 +1,86 @@ +package graphql.execution; + +import graphql.Scalars; +import graphql.language.Field; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.profile.GCProfiler; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; + +import static graphql.execution.ExecutionStepInfo.newExecutionStepInfo; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 2) +@Fork(2) +public class ExecutionStepInfoBenchmark { + @Param({"1000000", "2000000"}) + int howManyItems = 1000000; + + @Setup(Level.Trial) + public void setUp() { + } + + @TearDown(Level.Trial) + public void tearDown() { + } + + + MergedField mergedField = MergedField.newMergedField().addField(Field.newField("f").build()).build(); + + ResultPath path = ResultPath.rootPath().segment("f"); + ExecutionStepInfo rootStepInfo = newExecutionStepInfo() + .path(path).type(Scalars.GraphQLString) + .field(mergedField) + .build(); + + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkDirectConstructorThroughput(Blackhole blackhole) { + for (int i = 0; i < howManyItems; i++) { + ResultPath newPath = path.segment(1); + ExecutionStepInfo newOne = rootStepInfo.transform(Scalars.GraphQLInt, rootStepInfo, newPath); + blackhole.consume(newOne); + } + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkBuilderThroughput(Blackhole blackhole) { + for (int i = 0; i < howManyItems; i++) { + ResultPath newPath = path.segment(1); + ExecutionStepInfo newOne = newExecutionStepInfo(rootStepInfo).parentInfo(rootStepInfo) + .type(Scalars.GraphQLInt).path(newPath).build(); + blackhole.consume(newOne); + } + } + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder() + .include("graphql.execution.ExecutionStepInfoBenchmark") + .addProfiler(GCProfiler.class) + .build(); + + new Runner(opt).run(); + } + +} diff --git a/src/jmh/java/performance/ComplexQueryPerformance.java b/src/jmh/java/performance/ComplexQueryPerformance.java new file mode 100644 index 0000000000..e8b2c3da0e --- /dev/null +++ b/src/jmh/java/performance/ComplexQueryPerformance.java @@ -0,0 +1,272 @@ +package performance; + +import benchmark.BenchmarkUtils; +import com.google.common.collect.ImmutableList; +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.profile.GCProfiler; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; + +/** + * This benchmark is an attempt to have a more complex query that involves async and sync work together + * along with multiple threads happening. + *

+ * It can also be run in a forever mode say if you want to connect a profiler to it say + */ +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 2) +@Fork(2) +public class ComplexQueryPerformance { + + @Param({"5", "10", "20"}) + int howManyItems = 5; + int howLongToSleep = 5; + int howManyQueries = 10; + int howManyQueryThreads = 10; + int howManyFetcherThreads = 10; + + ExecutorService queryExecutorService; + ExecutorService fetchersExecutorService; + GraphQL graphQL; + volatile boolean shutDown; + + @Setup(Level.Trial) + public void setUp() { + shutDown = false; + queryExecutorService = Executors.newFixedThreadPool(howManyQueryThreads); + fetchersExecutorService = Executors.newFixedThreadPool(howManyFetcherThreads); + graphQL = buildGraphQL(); + } + + @TearDown(Level.Trial) + public void tearDown() { + shutDown = true; + queryExecutorService.shutdownNow(); + fetchersExecutorService.shutdownNow(); + } + + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public Object benchMarkSimpleQueriesThroughput() { + return runManyQueriesToCompletion(); + } + + + public static void main(String[] args) throws Exception { + // just to make sure it's all valid before testing + runAtStartup(); + + Options opt = new OptionsBuilder() + .include("benchmark.ComplexQueryBenchmark") + .addProfiler(GCProfiler.class) + .build(); + + new Runner(opt).run(); + } + + @SuppressWarnings({"ConstantValue", "LoopConditionNotUpdatedInsideLoop"}) + private static void runAtStartup() { + + ComplexQueryPerformance complexQueryBenchmark = new ComplexQueryPerformance(); + complexQueryBenchmark.howManyQueries = 5; + complexQueryBenchmark.howManyItems = 10; + + BenchmarkUtils.runInToolingForSomeTimeThenExit( + complexQueryBenchmark::setUp, + complexQueryBenchmark::runManyQueriesToCompletion, + complexQueryBenchmark::tearDown + + ); + } + + + @SuppressWarnings("UnnecessaryLocalVariable") + private Void runManyQueriesToCompletion() { + CompletableFuture[] cfs = new CompletableFuture[howManyQueries]; + for (int i = 0; i < howManyQueries; i++) { + cfs[i] = CompletableFuture.supplyAsync(() -> executeQuery(howManyItems, howLongToSleep), queryExecutorService).thenCompose(cf -> cf); + } + Void result = CompletableFuture.allOf(cfs).join(); + return result; + } + + public CompletableFuture executeQuery(int howMany, int howLong) { + String fields = "id name f1 f2 f3 f4 f5 f6 f7 f8 f9 f10"; + String query = "query q {" + + String.format("shops(howMany : %d) { %s departments( howMany : %d) { %s products(howMany : %d) { %s }}}\n" + , howMany, fields, 10, fields, 5, fields) + + String.format("expensiveShops(howMany : %d howLong : %d) { %s expensiveDepartments( howMany : %d howLong : %d) { %s expensiveProducts(howMany : %d howLong : %d) { %s }}}\n" + , howMany, howLong, fields, 10, howLong, fields, 5, howLong, fields) + + "}"; + return graphQL.executeAsync(ExecutionInput.newExecutionInput(query).build()); + } + + private GraphQL buildGraphQL() { + TypeDefinitionRegistry definitionRegistry = new SchemaParser().parse(PerformanceTestingUtils.loadResource("storesanddepartments.graphqls")); + + DataFetcher shopsDF = env -> mkHowManyThings(env.getArgument("howMany")); + DataFetcher expensiveShopsDF = env -> supplyAsync(() -> sleepAndReturnThings(env)); + DataFetcher departmentsDF = env -> mkHowManyThings(env.getArgument("howMany")); + DataFetcher expensiveDepartmentsDF = env -> supplyAsyncListItems(env, () -> sleepAndReturnThings(env)); + DataFetcher productsDF = env -> mkHowManyThings(env.getArgument("howMany")); + DataFetcher expensiveProductsDF = env -> supplyAsyncListItems(env, () -> sleepAndReturnThings(env)); + + RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("shops", shopsDF) + .dataFetcher("expensiveShops", expensiveShopsDF)) + .type(newTypeWiring("Shop") + .dataFetcher("departments", departmentsDF) + .dataFetcher("expensiveDepartments", expensiveDepartmentsDF)) + .type(newTypeWiring("Department") + .dataFetcher("products", productsDF) + .dataFetcher("expensiveProducts", expensiveProductsDF)) + .build(); + + GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(definitionRegistry, runtimeWiring); + + return GraphQL.newGraphQL(graphQLSchema).build(); + } + + private CompletableFuture supplyAsyncListItems(DataFetchingEnvironment environment, Supplier codeToRun) { + return supplyAsync(codeToRun); + } + + private CompletableFuture supplyAsync(Supplier codeToRun) { + if (!shutDown) { + //logEvery(100, "async fetcher"); + return CompletableFuture.supplyAsync(codeToRun, fetchersExecutorService); + } else { + // if we have shutdown - get on with it, so we shut down quicker + return CompletableFuture.completedFuture(codeToRun.get()); + } + } + + private List sleepAndReturnThings(DataFetchingEnvironment env) { + // by sleeping, we hope to cause the objects to stay longer in GC land and hence have a longer lifecycle + // then a simple stack say or young gen gc. I don't know this will work, but I am trying it + // to represent work that takes some tie to complete + sleep(env.getArgument("howLong")); + return mkHowManyThings(env.getArgument("howMany")); + } + + private void sleep(Integer howLong) { + if (howLong > 0) { + try { + Thread.sleep(howLong); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + AtomicInteger logCount = new AtomicInteger(); + + private void logEvery(int every, String s) { + int count = logCount.getAndIncrement(); + if (count == 0 || count % every == 0) { + System.out.println("\t" + count + "\t" + s); + } + } + + private List mkHowManyThings(Integer howMany) { + ImmutableList.Builder builder = ImmutableList.builder(); + for (int i = 0; i < howMany; i++) { + builder.add(new IdAndNamedThing(i)); + } + return builder.build(); + } + + @SuppressWarnings("unused") + static class IdAndNamedThing { + private final int i; + + public IdAndNamedThing(int i) { + this.i = i; + } + + public String getId() { + return "id" + i; + } + + public String getName() { + return "name" + i; + } + + public String getF1() { + return "f1" + i; + } + + public String getF2() { + return "f2" + i; + } + + public String getF3() { + return "f3" + i; + } + + public String getF4() { + return "f4" + i; + } + + public String getF5() { + return "f5" + i; + } + + public String getF6() { + return "f6" + i; + } + + public String getF7() { + return "f7" + i; + } + + public String getF8() { + return "f8" + i; + } + + public String getF9() { + return "f9" + i; + } + + public String getF10() { + return "f10" + i; + } + } +} diff --git a/src/jmh/java/performance/DFSelectionSetPerformance.java b/src/jmh/java/performance/DFSelectionSetPerformance.java new file mode 100644 index 0000000000..bbc34b03f0 --- /dev/null +++ b/src/jmh/java/performance/DFSelectionSetPerformance.java @@ -0,0 +1,118 @@ +package performance; + +import graphql.execution.CoercedVariables; +import graphql.language.Document; +import graphql.normalized.ExecutableNormalizedField; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.ExecutableNormalizedOperationFactory; +import graphql.parser.Parser; +import graphql.schema.DataFetchingFieldSelectionSet; +import graphql.schema.DataFetchingFieldSelectionSetImpl; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchema; +import graphql.schema.SelectedField; +import graphql.schema.idl.SchemaGenerator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class DFSelectionSetPerformance { + + @State(Scope.Benchmark) + public static class MyState { + + public ExecutableNormalizedField normalisedField; + public GraphQLOutputType outputFieldType; + GraphQLSchema schema; + Document document; + + @Setup + public void setup() { + try { + String schemaString = PerformanceTestingUtils.loadResource("large-schema-2.graphqls"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + + String query = PerformanceTestingUtils.loadResource("large-schema-2-query.graphql"); + document = Parser.parse(query); + + ExecutableNormalizedOperation executableNormalizedOperation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(schema, document, null, CoercedVariables.emptyVariables()); + + normalisedField = executableNormalizedOperation.getTopLevelFields().get(0); + + outputFieldType = schema.getObjectType("Object42"); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAvgTime(MyState myState, Blackhole blackhole) { + List fields = getSelectedFields(myState); + blackhole.consume(fields); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkThroughput(MyState myState, Blackhole blackhole) { + List fields = getSelectedFields(myState); + blackhole.consume(fields); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAvgTime_getImmediateFields(MyState myState, Blackhole blackhole) { + List fields = getImmediateFields(myState); + blackhole.consume(fields); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkThroughput_getImmediateFields(MyState myState, Blackhole blackhole) { + List fields = getImmediateFields(myState); + blackhole.consume(fields); + } + + private List getSelectedFields(MyState myState) { + DataFetchingFieldSelectionSet dataFetchingFieldSelectionSet = DataFetchingFieldSelectionSetImpl.newCollector(myState.schema, myState.outputFieldType, () -> myState.normalisedField); + return dataFetchingFieldSelectionSet.getFields("wontBeFound"); + } + + private List getImmediateFields(MyState myState) { + DataFetchingFieldSelectionSet dataFetchingFieldSelectionSet = DataFetchingFieldSelectionSetImpl.newCollector(myState.schema, myState.outputFieldType, () -> myState.normalisedField); + return dataFetchingFieldSelectionSet.getImmediateFields(); + } + + public static void mainX(String[] args) throws InterruptedException { + MyState myState = new MyState(); + myState.setup(); + + while (true) { + List selectedFields = new DFSelectionSetPerformance().getSelectedFields(myState); + Thread.sleep(500); + } + } + +} diff --git a/src/jmh/java/performance/DataLoaderPerformance.java b/src/jmh/java/performance/DataLoaderPerformance.java new file mode 100644 index 0000000000..83a62b5072 --- /dev/null +++ b/src/jmh/java/performance/DataLoaderPerformance.java @@ -0,0 +1,616 @@ +package performance; + +import graphql.Assert; +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.dataloader.BatchLoader; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderFactory; +import org.dataloader.DataLoaderRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 5) +@Fork(2) +public class DataLoaderPerformance { + + static Owner o1 = new Owner("O-1", "Andi", List.of("P-1", "P-2", "P-3")); + static Owner o2 = new Owner("O-2", "George", List.of("P-4", "P-5", "P-6")); + static Owner o3 = new Owner("O-3", "Peppa", List.of("P-7", "P-8", "P-9", "P-10")); + + // Additional 100 owners with variety of names and different pets + static Owner o4 = new Owner("O-4", "Emma", List.of("P-11", "P-12")); + static Owner o5 = new Owner("O-5", "Liam", List.of("P-13", "P-14", "P-15")); + static Owner o6 = new Owner("O-6", "Olivia", List.of("P-16", "P-17", "P-18")); + static Owner o7 = new Owner("O-7", "Noah", List.of("P-19", "P-20")); + static Owner o8 = new Owner("O-8", "Sophia", List.of("P-21", "P-22", "P-23", "P-24")); + static Owner o9 = new Owner("O-9", "Jackson", List.of("P-25", "P-26")); + static Owner o10 = new Owner("O-10", "Isabella", List.of("P-27", "P-28", "P-29")); + static Owner o11 = new Owner("O-11", "Mason", List.of("P-30", "P-31")); + static Owner o12 = new Owner("O-12", "Mia", List.of("P-32", "P-33", "P-34")); + static Owner o13 = new Owner("O-13", "Ethan", List.of("P-35", "P-36")); + static Owner o14 = new Owner("O-14", "Charlotte", List.of("P-37", "P-38", "P-39")); + static Owner o15 = new Owner("O-15", "Alexander", List.of("P-40", "P-41")); + static Owner o16 = new Owner("O-16", "Amelia", List.of("P-42", "P-43", "P-44")); + static Owner o17 = new Owner("O-17", "Michael", List.of("P-45", "P-46")); + static Owner o18 = new Owner("O-18", "Harper", List.of("P-47", "P-48", "P-49")); + static Owner o19 = new Owner("O-19", "Benjamin", List.of("P-50", "P-51")); + static Owner o20 = new Owner("O-20", "Evelyn", List.of("P-52", "P-53", "P-54")); + static Owner o21 = new Owner("O-21", "Lucas", List.of("P-55", "P-56")); + static Owner o22 = new Owner("O-22", "Abigail", List.of("P-57", "P-58", "P-59")); + static Owner o23 = new Owner("O-23", "Henry", List.of("P-60", "P-61")); + static Owner o24 = new Owner("O-24", "Emily", List.of("P-62", "P-63", "P-64")); + static Owner o25 = new Owner("O-25", "Sebastian", List.of("P-65", "P-66")); + static Owner o26 = new Owner("O-26", "Elizabeth", List.of("P-67", "P-68", "P-69")); + static Owner o27 = new Owner("O-27", "Mateo", List.of("P-70", "P-71")); + static Owner o28 = new Owner("O-28", "Camila", List.of("P-72", "P-73", "P-74")); + static Owner o29 = new Owner("O-29", "Daniel", List.of("P-75", "P-76")); + static Owner o30 = new Owner("O-30", "Sofia", List.of("P-77", "P-78", "P-79")); + static Owner o31 = new Owner("O-31", "Matthew", List.of("P-80", "P-81")); + static Owner o32 = new Owner("O-32", "Avery", List.of("P-82", "P-83", "P-84")); + static Owner o33 = new Owner("O-33", "Aiden", List.of("P-85", "P-86")); + static Owner o34 = new Owner("O-34", "Ella", List.of("P-87", "P-88", "P-89")); + static Owner o35 = new Owner("O-35", "Joseph", List.of("P-90", "P-91")); + static Owner o36 = new Owner("O-36", "Scarlett", List.of("P-92", "P-93", "P-94")); + static Owner o37 = new Owner("O-37", "David", List.of("P-95", "P-96")); + static Owner o38 = new Owner("O-38", "Grace", List.of("P-97", "P-98", "P-99")); + static Owner o39 = new Owner("O-39", "Carter", List.of("P-100", "P-101")); + static Owner o40 = new Owner("O-40", "Chloe", List.of("P-102", "P-103", "P-104")); + static Owner o41 = new Owner("O-41", "Wyatt", List.of("P-105", "P-106")); + static Owner o42 = new Owner("O-42", "Victoria", List.of("P-107", "P-108", "P-109")); + static Owner o43 = new Owner("O-43", "Jayden", List.of("P-110", "P-111")); + static Owner o44 = new Owner("O-44", "Madison", List.of("P-112", "P-113", "P-114")); + static Owner o45 = new Owner("O-45", "Luke", List.of("P-115", "P-116")); + static Owner o46 = new Owner("O-46", "Aria", List.of("P-117", "P-118", "P-119")); + static Owner o47 = new Owner("O-47", "Gabriel", List.of("P-120", "P-121")); + static Owner o48 = new Owner("O-48", "Luna", List.of("P-122", "P-123", "P-124")); + static Owner o49 = new Owner("O-49", "Anthony", List.of("P-125", "P-126")); + static Owner o50 = new Owner("O-50", "Layla", List.of("P-127", "P-128", "P-129")); + static Owner o51 = new Owner("O-51", "Isaac", List.of("P-130", "P-131")); + static Owner o52 = new Owner("O-52", "Penelope", List.of("P-132", "P-133", "P-134")); + static Owner o53 = new Owner("O-53", "Grayson", List.of("P-135", "P-136")); + static Owner o54 = new Owner("O-54", "Riley", List.of("P-137", "P-138", "P-139")); + static Owner o55 = new Owner("O-55", "Jack", List.of("P-140", "P-141")); + static Owner o56 = new Owner("O-56", "Nora", List.of("P-142", "P-143", "P-144")); + static Owner o57 = new Owner("O-57", "Julian", List.of("P-145", "P-146")); + static Owner o58 = new Owner("O-58", "Lillian", List.of("P-147", "P-148", "P-149")); + static Owner o59 = new Owner("O-59", "Levi", List.of("P-150", "P-151")); + static Owner o60 = new Owner("O-60", "Addison", List.of("P-152", "P-153", "P-154")); + static Owner o61 = new Owner("O-61", "Christopher", List.of("P-155", "P-156")); + static Owner o62 = new Owner("O-62", "Aubrey", List.of("P-157", "P-158", "P-159")); + static Owner o63 = new Owner("O-63", "Andrew", List.of("P-160", "P-161")); + static Owner o64 = new Owner("O-64", "Zoey", List.of("P-162", "P-163", "P-164")); + static Owner o65 = new Owner("O-65", "Joshua", List.of("P-165", "P-166")); + static Owner o66 = new Owner("O-66", "Hannah", List.of("P-167", "P-168", "P-169")); + static Owner o67 = new Owner("O-67", "Nathan", List.of("P-170", "P-171")); + static Owner o68 = new Owner("O-68", "Leah", List.of("P-172", "P-173", "P-174")); + static Owner o69 = new Owner("O-69", "Aaron", List.of("P-175", "P-176")); + static Owner o70 = new Owner("O-70", "Zoe", List.of("P-177", "P-178", "P-179")); + static Owner o71 = new Owner("O-71", "Eli", List.of("P-180", "P-181")); + static Owner o72 = new Owner("O-72", "Hazel", List.of("P-182", "P-183", "P-184")); + static Owner o73 = new Owner("O-73", "Adrian", List.of("P-185", "P-186")); + static Owner o74 = new Owner("O-74", "Violet", List.of("P-187", "P-188", "P-189")); + static Owner o75 = new Owner("O-75", "Christian", List.of("P-190", "P-191")); + static Owner o76 = new Owner("O-76", "Aurora", List.of("P-192", "P-193", "P-194")); + static Owner o77 = new Owner("O-77", "Ryan", List.of("P-195", "P-196")); + static Owner o78 = new Owner("O-78", "Savannah", List.of("P-197", "P-198", "P-199")); + static Owner o79 = new Owner("O-79", "Thomas", List.of("P-200", "P-201")); + static Owner o80 = new Owner("O-80", "Audrey", List.of("P-202", "P-203", "P-204")); + static Owner o81 = new Owner("O-81", "Caleb", List.of("P-205", "P-206")); + static Owner o82 = new Owner("O-82", "Brooklyn", List.of("P-207", "P-208", "P-209")); + static Owner o83 = new Owner("O-83", "Jose", List.of("P-210", "P-211")); + static Owner o84 = new Owner("O-84", "Bella", List.of("P-212", "P-213", "P-214")); + static Owner o85 = new Owner("O-85", "Colton", List.of("P-215", "P-216")); + static Owner o86 = new Owner("O-86", "Claire", List.of("P-217", "P-218", "P-219")); + static Owner o87 = new Owner("O-87", "Jordan", List.of("P-220", "P-221")); + static Owner o88 = new Owner("O-88", "Skylar", List.of("P-222", "P-223", "P-224")); + static Owner o89 = new Owner("O-89", "Jeremiah", List.of("P-225", "P-226")); + static Owner o90 = new Owner("O-90", "Lucy", List.of("P-227", "P-228", "P-229")); + static Owner o91 = new Owner("O-91", "Cameron", List.of("P-230", "P-231")); + static Owner o92 = new Owner("O-92", "Paisley", List.of("P-232", "P-233", "P-234")); + static Owner o93 = new Owner("O-93", "Cooper", List.of("P-235", "P-236")); + static Owner o94 = new Owner("O-94", "Sarah", List.of("P-237", "P-238", "P-239")); + static Owner o95 = new Owner("O-95", "Robert", List.of("P-240", "P-241")); + static Owner o96 = new Owner("O-96", "Natalie", List.of("P-242", "P-243", "P-244")); + static Owner o97 = new Owner("O-97", "Brayden", List.of("P-245", "P-246")); + static Owner o98 = new Owner("O-98", "Mila", List.of("P-247", "P-248", "P-249")); + static Owner o99 = new Owner("O-99", "Jonathan", List.of("P-250", "P-251")); + static Owner o100 = new Owner("O-100", "Naomi", List.of("P-252", "P-253", "P-254")); + static Owner o101 = new Owner("O-101", "Carlos", List.of("P-255", "P-256")); + static Owner o102 = new Owner("O-102", "Elena", List.of("P-257", "P-258", "P-259")); + static Owner o103 = new Owner("O-103", "Hunter", List.of("P-260", "P-261")); + + static Pet p1 = new Pet("P-1", "Bella", "O-1", List.of("P-2", "P-3", "P-4")); + static Pet p2 = new Pet("P-2", "Charlie", "O-2", List.of("P-1", "P-5", "P-6")); + static Pet p3 = new Pet("P-3", "Luna", "O-3", List.of("P-1", "P-2", "P-7", "P-8")); + static Pet p4 = new Pet("P-4", "Max", "O-1", List.of("P-1", "P-9", "P-10")); + static Pet p5 = new Pet("P-5", "Lucy", "O-2", List.of("P-2", "P-6")); + static Pet p6 = new Pet("P-6", "Cooper", "O-3", List.of("P-3", "P-5", "P-7")); + static Pet p7 = new Pet("P-7", "Daisy", "O-1", List.of("P-4", "P-6", "P-8")); + static Pet p8 = new Pet("P-8", "Milo", "O-2", List.of("P-3", "P-7", "P-9")); + static Pet p9 = new Pet("P-9", "Lola", "O-3", List.of("P-4", "P-8", "P-10")); + static Pet p10 = new Pet("P-10", "Rocky", "O-1", List.of("P-4", "P-9")); + + // Additional pets for the new owners + static Pet p11 = new Pet("P-11", "Buddy", "O-4", List.of("P-12", "P-13", "P-14")); + static Pet p12 = new Pet("P-12", "Oscar", "O-4", List.of("P-11", "P-15", "P-16")); + static Pet p13 = new Pet("P-13", "Tucker", "O-5", List.of("P-14", "P-15", "P-11")); + static Pet p14 = new Pet("P-14", "Bailey", "O-5", List.of("P-13", "P-16", "P-17")); + static Pet p15 = new Pet("P-15", "Ollie", "O-5", List.of("P-12", "P-13", "P-18")); + static Pet p16 = new Pet("P-16", "Coco", "O-6", List.of("P-17", "P-18", "P-12")); + static Pet p17 = new Pet("P-17", "Ruby", "O-6", List.of("P-16", "P-19", "P-20")); + static Pet p18 = new Pet("P-18", "Sadie", "O-6", List.of("P-15", "P-16", "P-21")); + static Pet p19 = new Pet("P-19", "Zeus", "O-7", List.of("P-20", "P-17", "P-22")); + static Pet p20 = new Pet("P-20", "Sophie", "O-7", List.of("P-19", "P-23", "P-24")); + static Pet p21 = new Pet("P-21", "Maggie", "O-8", List.of("P-22", "P-23", "P-18")); + static Pet p22 = new Pet("P-22", "Shadow", "O-8", List.of("P-21", "P-24", "P-19")); + static Pet p23 = new Pet("P-23", "Bear", "O-8", List.of("P-20", "P-21", "P-25")); + static Pet p24 = new Pet("P-24", "Stella", "O-8", List.of("P-22", "P-25", "P-20")); + static Pet p25 = new Pet("P-25", "Duke", "O-9", List.of("P-26", "P-23", "P-24")); + static Pet p26 = new Pet("P-26", "Zoe", "O-9", List.of("P-25", "P-27", "P-28")); + static Pet p27 = new Pet("P-27", "Toby", "O-10", List.of("P-28", "P-29", "P-26")); + static Pet p28 = new Pet("P-28", "Lily", "O-10", List.of("P-27", "P-29", "P-30")); + static Pet p29 = new Pet("P-29", "Jake", "O-10", List.of("P-27", "P-28", "P-31")); + static Pet p30 = new Pet("P-30", "Molly", "O-11", List.of("P-31", "P-32", "P-28")); + static Pet p31 = new Pet("P-31", "Gus", "O-11", List.of("P-30", "P-33", "P-29")); + static Pet p32 = new Pet("P-32", "Penny", "O-12", List.of("P-33", "P-34", "P-30")); + static Pet p33 = new Pet("P-33", "Buster", "O-12", List.of("P-32", "P-34", "P-31")); + static Pet p34 = new Pet("P-34", "Rosie", "O-12", List.of("P-32", "P-33", "P-35")); + static Pet p35 = new Pet("P-35", "Finn", "O-13", List.of("P-36", "P-37", "P-34")); + static Pet p36 = new Pet("P-36", "Nala", "O-13", List.of("P-35", "P-38", "P-39")); + static Pet p37 = new Pet("P-37", "Mochi", "O-14", List.of("P-38", "P-39", "P-35")); + static Pet p38 = new Pet("P-38", "Leo", "O-14", List.of("P-37", "P-39", "P-36")); + static Pet p39 = new Pet("P-39", "Cleo", "O-14", List.of("P-37", "P-38", "P-40")); + static Pet p40 = new Pet("P-40", "Bandit", "O-15", List.of("P-41", "P-42", "P-39")); + static Pet p41 = new Pet("P-41", "Kona", "O-15", List.of("P-40", "P-43", "P-44")); + static Pet p42 = new Pet("P-42", "Maya", "O-16", List.of("P-43", "P-44", "P-40")); + static Pet p43 = new Pet("P-43", "Scout", "O-16", List.of("P-42", "P-44", "P-41")); + static Pet p44 = new Pet("P-44", "Hazel", "O-16", List.of("P-42", "P-43", "P-45")); + static Pet p45 = new Pet("P-45", "Oliver", "O-17", List.of("P-46", "P-47", "P-44")); + static Pet p46 = new Pet("P-46", "Piper", "O-17", List.of("P-45", "P-48", "P-49")); + static Pet p47 = new Pet("P-47", "Rusty", "O-18", List.of("P-48", "P-49", "P-45")); + static Pet p48 = new Pet("P-48", "Luna", "O-18", List.of("P-47", "P-49", "P-46")); + static Pet p49 = new Pet("P-49", "Jasper", "O-18", List.of("P-47", "P-48", "P-50")); + static Pet p50 = new Pet("P-50", "Willow", "O-19", List.of("P-51", "P-52", "P-49")); + static Pet p51 = new Pet("P-51", "Murphy", "O-19", List.of("P-50", "P-53", "P-54")); + static Pet p52 = new Pet("P-52", "Maple", "O-20", List.of("P-53", "P-54", "P-50")); + static Pet p53 = new Pet("P-53", "Ace", "O-20", List.of("P-52", "P-54", "P-51")); + static Pet p54 = new Pet("P-54", "Honey", "O-20", List.of("P-52", "P-53", "P-55")); + static Pet p55 = new Pet("P-55", "Ziggy", "O-21", List.of("P-56", "P-57", "P-54")); + static Pet p56 = new Pet("P-56", "Pearl", "O-21", List.of("P-55", "P-58", "P-59")); + static Pet p57 = new Pet("P-57", "Rocco", "O-22", List.of("P-58", "P-59", "P-55")); + static Pet p58 = new Pet("P-58", "Ivy", "O-22", List.of("P-57", "P-59", "P-56")); + static Pet p59 = new Pet("P-59", "Koda", "O-22", List.of("P-57", "P-58", "P-60")); + static Pet p60 = new Pet("P-60", "Nova", "O-23", List.of("P-61", "P-62", "P-59")); + static Pet p61 = new Pet("P-61", "Tank", "O-23", List.of("P-60", "P-63", "P-64")); + static Pet p62 = new Pet("P-62", "Poppy", "O-24", List.of("P-63", "P-64", "P-60")); + static Pet p63 = new Pet("P-63", "Diesel", "O-24", List.of("P-62", "P-64", "P-61")); + static Pet p64 = new Pet("P-64", "Roxy", "O-24", List.of("P-62", "P-63", "P-65")); + static Pet p65 = new Pet("P-65", "Bruno", "O-25", List.of("P-66", "P-67", "P-64")); + static Pet p66 = new Pet("P-66", "Athena", "O-25", List.of("P-65", "P-68", "P-69")); + static Pet p67 = new Pet("P-67", "Oreo", "O-26", List.of("P-68", "P-69", "P-65")); + static Pet p68 = new Pet("P-68", "Sage", "O-26", List.of("P-67", "P-69", "P-66")); + static Pet p69 = new Pet("P-69", "Beau", "O-26", List.of("P-67", "P-68", "P-70")); + static Pet p70 = new Pet("P-70", "Aria", "O-27", List.of("P-71", "P-72", "P-69")); + static Pet p71 = new Pet("P-71", "Ranger", "O-27", List.of("P-70", "P-73", "P-74")); + static Pet p72 = new Pet("P-72", "Mia", "O-28", List.of("P-73", "P-74", "P-70")); + static Pet p73 = new Pet("P-73", "Rex", "O-28", List.of("P-72", "P-74", "P-71")); + static Pet p74 = new Pet("P-74", "Zara", "O-28", List.of("P-72", "P-73", "P-75")); + static Pet p75 = new Pet("P-75", "Hank", "O-29", List.of("P-76", "P-77", "P-74")); + static Pet p76 = new Pet("P-76", "Lola", "O-29", List.of("P-75", "P-78", "P-79")); + static Pet p77 = new Pet("P-77", "Cash", "O-30", List.of("P-78", "P-79", "P-75")); + static Pet p78 = new Pet("P-78", "Belle", "O-30", List.of("P-77", "P-79", "P-76")); + static Pet p79 = new Pet("P-79", "Copper", "O-30", List.of("P-77", "P-78", "P-80")); + static Pet p80 = new Pet("P-80", "Tessa", "O-31", List.of("P-81", "P-82", "P-79")); + static Pet p81 = new Pet("P-81", "Gunner", "O-31", List.of("P-80", "P-83", "P-84")); + static Pet p82 = new Pet("P-82", "Freya", "O-32", List.of("P-83", "P-84", "P-80")); + static Pet p83 = new Pet("P-83", "Boomer", "O-32", List.of("P-82", "P-84", "P-81")); + static Pet p84 = new Pet("P-84", "Violet", "O-32", List.of("P-82", "P-83", "P-85")); + static Pet p85 = new Pet("P-85", "Apollo", "O-33", List.of("P-86", "P-87", "P-84")); + static Pet p86 = new Pet("P-86", "Raven", "O-33", List.of("P-85", "P-88", "P-89")); + static Pet p87 = new Pet("P-87", "Jax", "O-34", List.of("P-88", "P-89", "P-85")); + static Pet p88 = new Pet("P-88", "Storm", "O-34", List.of("P-87", "P-89", "P-86")); + static Pet p89 = new Pet("P-89", "Ember", "O-34", List.of("P-87", "P-88", "P-90")); + static Pet p90 = new Pet("P-90", "Thor", "O-35", List.of("P-91", "P-92", "P-89")); + static Pet p91 = new Pet("P-91", "Misty", "O-35", List.of("P-90", "P-93", "P-94")); + static Pet p92 = new Pet("P-92", "Blaze", "O-36", List.of("P-93", "P-94", "P-90")); + static Pet p93 = new Pet("P-93", "Sunny", "O-36", List.of("P-92", "P-94", "P-91")); + static Pet p94 = new Pet("P-94", "Ghost", "O-36", List.of("P-92", "P-93", "P-95")); + static Pet p95 = new Pet("P-95", "Clover", "O-37", List.of("P-96", "P-97", "P-94")); + static Pet p96 = new Pet("P-96", "Ridge", "O-37", List.of("P-95", "P-98", "P-99")); + static Pet p97 = new Pet("P-97", "Indie", "O-38", List.of("P-98", "P-99", "P-95")); + static Pet p98 = new Pet("P-98", "Forest", "O-38", List.of("P-97", "P-99", "P-96")); + static Pet p99 = new Pet("P-99", "River", "O-38", List.of("P-97", "P-98", "P-100")); + static Pet p100 = new Pet("P-100", "Onyx", "O-39", List.of("P-101", "P-102", "P-99")); + static Pet p101 = new Pet("P-101", "Star", "O-39", List.of("P-100", "P-103", "P-104")); + static Pet p102 = new Pet("P-102", "Atlas", "O-40", List.of("P-103", "P-104", "P-100")); + static Pet p103 = new Pet("P-103", "Echo", "O-40", List.of("P-102", "P-104", "P-101")); + static Pet p104 = new Pet("P-104", "Phoenix", "O-40", List.of("P-102", "P-103", "P-105")); + static Pet p105 = new Pet("P-105", "Aspen", "O-41", List.of("P-106", "P-107", "P-104")); + static Pet p106 = new Pet("P-106", "Knox", "O-41", List.of("P-105", "P-108", "P-109")); + static Pet p107 = new Pet("P-107", "Jade", "O-42", List.of("P-108", "P-109", "P-105")); + static Pet p108 = new Pet("P-108", "Blaze", "O-42", List.of("P-107", "P-109", "P-106")); + static Pet p109 = new Pet("P-109", "Sky", "O-42", List.of("P-107", "P-108", "P-110")); + static Pet p110 = new Pet("P-110", "Neo", "O-43", List.of("P-111", "P-112", "P-109")); + static Pet p111 = new Pet("P-111", "Fern", "O-43", List.of("P-110", "P-113", "P-114")); + static Pet p112 = new Pet("P-112", "Axel", "O-44", List.of("P-113", "P-114", "P-110")); + static Pet p113 = new Pet("P-113", "Iris", "O-44", List.of("P-112", "P-114", "P-111")); + static Pet p114 = new Pet("P-114", "Rebel", "O-44", List.of("P-112", "P-113", "P-115")); + static Pet p115 = new Pet("P-115", "Wren", "O-45", List.of("P-116", "P-117", "P-114")); + static Pet p116 = new Pet("P-116", "Cruz", "O-45", List.of("P-115", "P-118", "P-119")); + static Pet p117 = new Pet("P-117", "Ocean", "O-46", List.of("P-118", "P-119", "P-115")); + static Pet p118 = new Pet("P-118", "Titan", "O-46", List.of("P-117", "P-119", "P-116")); + static Pet p119 = new Pet("P-119", "Luna", "O-46", List.of("P-117", "P-118", "P-120")); + static Pet p120 = new Pet("P-120", "Cosmos", "O-47", List.of("P-121", "P-122", "P-119")); + static Pet p121 = new Pet("P-121", "Maple", "O-47", List.of("P-120", "P-123", "P-124")); + static Pet p122 = new Pet("P-122", "Orion", "O-48", List.of("P-123", "P-124", "P-120")); + static Pet p123 = new Pet("P-123", "Vega", "O-48", List.of("P-122", "P-124", "P-121")); + static Pet p124 = new Pet("P-124", "Nova", "O-48", List.of("P-122", "P-123", "P-125")); + static Pet p125 = new Pet("P-125", "Blitz", "O-49", List.of("P-126", "P-127", "P-124")); + static Pet p126 = new Pet("P-126", "Dawn", "O-49", List.of("P-125", "P-128", "P-129")); + static Pet p127 = new Pet("P-127", "Storm", "O-50", List.of("P-128", "P-129", "P-125")); + static Pet p128 = new Pet("P-128", "Ember", "O-50", List.of("P-127", "P-129", "P-126")); + static Pet p129 = new Pet("P-129", "Thunder", "O-50", List.of("P-127", "P-128", "P-130")); + static Pet p130 = new Pet("P-130", "Frost", "O-51", List.of("P-131", "P-132", "P-129")); + static Pet p131 = new Pet("P-131", "Crimson", "O-51", List.of("P-130", "P-133", "P-134")); + static Pet p132 = new Pet("P-132", "Sage", "O-52", List.of("P-133", "P-134", "P-130")); + static Pet p133 = new Pet("P-133", "Dash", "O-52", List.of("P-132", "P-134", "P-131")); + static Pet p134 = new Pet("P-134", "Amber", "O-52", List.of("P-132", "P-133", "P-135")); + static Pet p135 = new Pet("P-135", "Blaze", "O-53", List.of("P-136", "P-137", "P-134")); + static Pet p136 = new Pet("P-136", "Stellar", "O-53", List.of("P-135", "P-138", "P-139")); + static Pet p137 = new Pet("P-137", "Midnight", "O-54", List.of("P-138", "P-139", "P-135")); + static Pet p138 = new Pet("P-138", "Aurora", "O-54", List.of("P-137", "P-139", "P-136")); + static Pet p139 = new Pet("P-139", "Galaxy", "O-54", List.of("P-137", "P-138", "P-140")); + static Pet p140 = new Pet("P-140", "Comet", "O-55", List.of("P-141", "P-142", "P-139")); + static Pet p141 = new Pet("P-141", "Nebula", "O-55", List.of("P-140", "P-143", "P-144")); + static Pet p142 = new Pet("P-142", "Zeus", "O-56", List.of("P-143", "P-144", "P-140")); + static Pet p143 = new Pet("P-143", "Hera", "O-56", List.of("P-142", "P-144", "P-141")); + static Pet p144 = new Pet("P-144", "Atlas", "O-56", List.of("P-142", "P-143", "P-145")); + static Pet p145 = new Pet("P-145", "Artemis", "O-57", List.of("P-146", "P-147", "P-144")); + static Pet p146 = new Pet("P-146", "Apollo", "O-57", List.of("P-145", "P-148", "P-149")); + static Pet p147 = new Pet("P-147", "Persephone", "O-58", List.of("P-148", "P-149", "P-145")); + static Pet p148 = new Pet("P-148", "Hades", "O-58", List.of("P-147", "P-149", "P-146")); + static Pet p149 = new Pet("P-149", "Demeter", "O-58", List.of("P-147", "P-148", "P-150")); + static Pet p150 = new Pet("P-150", "Poseidon", "O-59", List.of("P-151", "P-152", "P-149")); + static Pet p151 = new Pet("P-151", "Athena", "O-59", List.of("P-150", "P-153", "P-154")); + static Pet p152 = new Pet("P-152", "Hermes", "O-60", List.of("P-153", "P-154", "P-150")); + static Pet p153 = new Pet("P-153", "Aphrodite", "O-60", List.of("P-152", "P-154", "P-151")); + static Pet p154 = new Pet("P-154", "Ares", "O-60", List.of("P-152", "P-153", "P-155")); + static Pet p155 = new Pet("P-155", "Hestia", "O-61", List.of("P-156", "P-157", "P-154")); + static Pet p156 = new Pet("P-156", "Dionysus", "O-61", List.of("P-155", "P-158", "P-159")); + static Pet p157 = new Pet("P-157", "Hephaestus", "O-62", List.of("P-158", "P-159", "P-155")); + static Pet p158 = new Pet("P-158", "Iris", "O-62", List.of("P-157", "P-159", "P-156")); + static Pet p159 = new Pet("P-159", "Hecate", "O-62", List.of("P-157", "P-158", "P-160")); + static Pet p160 = new Pet("P-160", "Helios", "O-63", List.of("P-161", "P-162", "P-159")); + static Pet p161 = new Pet("P-161", "Selene", "O-63", List.of("P-160", "P-163", "P-164")); + static Pet p162 = new Pet("P-162", "Eos", "O-64", List.of("P-163", "P-164", "P-160")); + static Pet p163 = new Pet("P-163", "Nyx", "O-64", List.of("P-162", "P-164", "P-161")); + static Pet p164 = new Pet("P-164", "Chaos", "O-64", List.of("P-162", "P-163", "P-165")); + static Pet p165 = new Pet("P-165", "Gaia", "O-65", List.of("P-166", "P-167", "P-164")); + static Pet p166 = new Pet("P-166", "Uranus", "O-65", List.of("P-165", "P-168", "P-169")); + static Pet p167 = new Pet("P-167", "Chronos", "O-66", List.of("P-168", "P-169", "P-165")); + static Pet p168 = new Pet("P-168", "Rhea", "O-66", List.of("P-167", "P-169", "P-166")); + static Pet p169 = new Pet("P-169", "Oceanus", "O-66", List.of("P-167", "P-168", "P-170")); + static Pet p170 = new Pet("P-170", "Tethys", "O-67", List.of("P-171", "P-172", "P-169")); + static Pet p171 = new Pet("P-171", "Hyperion", "O-67", List.of("P-170", "P-173", "P-174")); + static Pet p172 = new Pet("P-172", "Theia", "O-68", List.of("P-173", "P-174", "P-170")); + static Pet p173 = new Pet("P-173", "Coeus", "O-68", List.of("P-172", "P-174", "P-171")); + static Pet p174 = new Pet("P-174", "Phoebe", "O-68", List.of("P-172", "P-173", "P-175")); + static Pet p175 = new Pet("P-175", "Mnemosyne", "O-69", List.of("P-176", "P-177", "P-174")); + static Pet p176 = new Pet("P-176", "Themis", "O-69", List.of("P-175", "P-178", "P-179")); + static Pet p177 = new Pet("P-177", "Iapetus", "O-70", List.of("P-178", "P-179", "P-175")); + static Pet p178 = new Pet("P-178", "Crius", "O-70", List.of("P-177", "P-179", "P-176")); + static Pet p179 = new Pet("P-179", "Prometheus", "O-70", List.of("P-177", "P-178", "P-180")); + static Pet p180 = new Pet("P-180", "Epimetheus", "O-71", List.of("P-181", "P-182", "P-179")); + static Pet p181 = new Pet("P-181", "Pandora", "O-71", List.of("P-180", "P-183", "P-184")); + static Pet p182 = new Pet("P-182", "Perseus", "O-72", List.of("P-183", "P-184", "P-180")); + static Pet p183 = new Pet("P-183", "Andromeda", "O-72", List.of("P-182", "P-184", "P-181")); + static Pet p184 = new Pet("P-184", "Medusa", "O-72", List.of("P-182", "P-183", "P-185")); + static Pet p185 = new Pet("P-185", "Pegasus", "O-73", List.of("P-186", "P-187", "P-184")); + static Pet p186 = new Pet("P-186", "Hercules", "O-73", List.of("P-185", "P-188", "P-189")); + static Pet p187 = new Pet("P-187", "Achilles", "O-74", List.of("P-188", "P-189", "P-185")); + static Pet p188 = new Pet("P-188", "Hector", "O-74", List.of("P-187", "P-189", "P-186")); + static Pet p189 = new Pet("P-189", "Odysseus", "O-74", List.of("P-187", "P-188", "P-190")); + static Pet p190 = new Pet("P-190", "Penelope", "O-75", List.of("P-191", "P-192", "P-189")); + static Pet p191 = new Pet("P-191", "Telemachus", "O-75", List.of("P-190", "P-193", "P-194")); + static Pet p192 = new Pet("P-192", "Circe", "O-76", List.of("P-193", "P-194", "P-190")); + static Pet p193 = new Pet("P-193", "Calypso", "O-76", List.of("P-192", "P-194", "P-191")); + static Pet p194 = new Pet("P-194", "Nausicaa", "O-76", List.of("P-192", "P-193", "P-195")); + static Pet p195 = new Pet("P-195", "Ariadne", "O-77", List.of("P-196", "P-197", "P-194")); + static Pet p196 = new Pet("P-196", "Theseus", "O-77", List.of("P-195", "P-198", "P-199")); + static Pet p197 = new Pet("P-197", "Minotaur", "O-78", List.of("P-198", "P-199", "P-195")); + static Pet p198 = new Pet("P-198", "Icarus", "O-78", List.of("P-197", "P-199", "P-196")); + static Pet p199 = new Pet("P-199", "Daedalus", "O-78", List.of("P-197", "P-198", "P-200")); + static Pet p200 = new Pet("P-200", "Phoenix", "O-79", List.of("P-201", "P-202", "P-199")); + static Pet p201 = new Pet("P-201", "Griffin", "O-79", List.of("P-200", "P-203", "P-204")); + static Pet p202 = new Pet("P-202", "Dragon", "O-80", List.of("P-203", "P-204", "P-200")); + static Pet p203 = new Pet("P-203", "Sphinx", "O-80", List.of("P-202", "P-204", "P-201")); + static Pet p204 = new Pet("P-204", "Chimera", "O-80", List.of("P-202", "P-203", "P-205")); + static Pet p205 = new Pet("P-205", "Hydra", "O-81", List.of("P-206", "P-207", "P-204")); + static Pet p206 = new Pet("P-206", "Kraken", "O-81", List.of("P-205", "P-208", "P-209")); + static Pet p207 = new Pet("P-207", "Cerberus", "O-82", List.of("P-208", "P-209", "P-205")); + static Pet p208 = new Pet("P-208", "Fenrir", "O-82", List.of("P-207", "P-209", "P-206")); + static Pet p209 = new Pet("P-209", "Jormungandr", "O-82", List.of("P-207", "P-208", "P-210")); + static Pet p210 = new Pet("P-210", "Sleipnir", "O-83", List.of("P-211", "P-212", "P-209")); + static Pet p211 = new Pet("P-211", "Odin", "O-83", List.of("P-210", "P-213", "P-214")); + static Pet p212 = new Pet("P-212", "Freya", "O-84", List.of("P-213", "P-214", "P-210")); + static Pet p213 = new Pet("P-213", "Thor", "O-84", List.of("P-212", "P-214", "P-211")); + static Pet p214 = new Pet("P-214", "Loki", "O-84", List.of("P-212", "P-213", "P-215")); + static Pet p215 = new Pet("P-215", "Balder", "O-85", List.of("P-216", "P-217", "P-214")); + static Pet p216 = new Pet("P-216", "Frigg", "O-85", List.of("P-215", "P-218", "P-219")); + static Pet p217 = new Pet("P-217", "Heimdall", "O-86", List.of("P-218", "P-219", "P-215")); + static Pet p218 = new Pet("P-218", "Tyr", "O-86", List.of("P-217", "P-219", "P-216")); + static Pet p219 = new Pet("P-219", "Vidar", "O-86", List.of("P-217", "P-218", "P-220")); + static Pet p220 = new Pet("P-220", "Vali", "O-87", List.of("P-221", "P-222", "P-219")); + static Pet p221 = new Pet("P-221", "Hod", "O-87", List.of("P-220", "P-223", "P-224")); + static Pet p222 = new Pet("P-222", "Bragi", "O-88", List.of("P-223", "P-224", "P-220")); + static Pet p223 = new Pet("P-223", "Idunn", "O-88", List.of("P-222", "P-224", "P-221")); + static Pet p224 = new Pet("P-224", "Sigyn", "O-88", List.of("P-222", "P-223", "P-225")); + static Pet p225 = new Pet("P-225", "Sif", "O-89", List.of("P-226", "P-227", "P-224")); + static Pet p226 = new Pet("P-226", "Angrboda", "O-89", List.of("P-225", "P-228", "P-229")); + static Pet p227 = new Pet("P-227", "Hel", "O-90", List.of("P-228", "P-229", "P-225")); + static Pet p228 = new Pet("P-228", "Mimir", "O-90", List.of("P-227", "P-229", "P-226")); + static Pet p229 = new Pet("P-229", "Ymir", "O-90", List.of("P-227", "P-228", "P-230")); + static Pet p230 = new Pet("P-230", "Surtr", "O-91", List.of("P-231", "P-232", "P-229")); + static Pet p231 = new Pet("P-231", "Jotun", "O-91", List.of("P-230", "P-233", "P-234")); + static Pet p232 = new Pet("P-232", "Ragnar", "O-92", List.of("P-233", "P-234", "P-230")); + static Pet p233 = new Pet("P-233", "Bjorn", "O-92", List.of("P-232", "P-234", "P-231")); + static Pet p234 = new Pet("P-234", "Erik", "O-92", List.of("P-232", "P-233", "P-235")); + static Pet p235 = new Pet("P-235", "Olaf", "O-93", List.of("P-236", "P-237", "P-234")); + static Pet p236 = new Pet("P-236", "Magnus", "O-93", List.of("P-235", "P-238", "P-239")); + static Pet p237 = new Pet("P-237", "Astrid", "O-94", List.of("P-238", "P-239", "P-235")); + static Pet p238 = new Pet("P-238", "Ingrid", "O-94", List.of("P-237", "P-239", "P-236")); + static Pet p239 = new Pet("P-239", "Sigrid", "O-94", List.of("P-237", "P-238", "P-240")); + static Pet p240 = new Pet("P-240", "Gunnar", "O-95", List.of("P-241", "P-242", "P-239")); + static Pet p241 = new Pet("P-241", "Leif", "O-95", List.of("P-240", "P-243", "P-244")); + static Pet p242 = new Pet("P-242", "Helga", "O-96", List.of("P-243", "P-244", "P-240")); + static Pet p243 = new Pet("P-243", "Solveig", "O-96", List.of("P-242", "P-244", "P-241")); + static Pet p244 = new Pet("P-244", "Ragnhild", "O-96", List.of("P-242", "P-243", "P-245")); + static Pet p245 = new Pet("P-245", "Svein", "O-97", List.of("P-246", "P-247", "P-244")); + static Pet p246 = new Pet("P-246", "Hakon", "O-97", List.of("P-245", "P-248", "P-249")); + static Pet p247 = new Pet("P-247", "Valdis", "O-98", List.of("P-248", "P-249", "P-245")); + static Pet p248 = new Pet("P-248", "Thora", "O-98", List.of("P-247", "P-249", "P-246")); + static Pet p249 = new Pet("P-249", "Eirik", "O-98", List.of("P-247", "P-248", "P-250")); + static Pet p250 = new Pet("P-250", "Knut", "O-99", List.of("P-251", "P-252", "P-249")); + static Pet p251 = new Pet("P-251", "Rune", "O-99", List.of("P-250", "P-253", "P-254")); + static Pet p252 = new Pet("P-252", "Saga", "O-100", List.of("P-253", "P-254", "P-250")); + static Pet p253 = new Pet("P-253", "Urd", "O-100", List.of("P-252", "P-254", "P-251")); + static Pet p254 = new Pet("P-254", "Verdandi", "O-100", List.of("P-252", "P-253", "P-255")); + static Pet p255 = new Pet("P-255", "Skuld", "O-101", List.of("P-256", "P-257", "P-254")); + static Pet p256 = new Pet("P-256", "Norns", "O-101", List.of("P-255", "P-258", "P-259")); + static Pet p257 = new Pet("P-257", "Eir", "O-102", List.of("P-258", "P-259", "P-255")); + static Pet p258 = new Pet("P-258", "Vara", "O-102", List.of("P-257", "P-259", "P-256")); + static Pet p259 = new Pet("P-259", "Vor", "O-102", List.of("P-257", "P-258", "P-260")); + static Pet p260 = new Pet("P-260", "Syn", "O-103", List.of("P-261", "P-1", "P-259")); + static Pet p261 = new Pet("P-261", "Lofn", "O-103", List.of("P-260", "P-2", "P-3")); + + static Map owners = Map.ofEntries( + Map.entry(o1.id, o1), Map.entry(o2.id, o2), Map.entry(o3.id, o3), + Map.entry(o4.id, o4), Map.entry(o5.id, o5), Map.entry(o6.id, o6), Map.entry(o7.id, o7), Map.entry(o8.id, o8), Map.entry(o9.id, o9), Map.entry(o10.id, o10), + Map.entry(o11.id, o11), Map.entry(o12.id, o12), Map.entry(o13.id, o13), Map.entry(o14.id, o14), Map.entry(o15.id, o15), Map.entry(o16.id, o16), Map.entry(o17.id, o17), Map.entry(o18.id, o18), Map.entry(o19.id, o19), Map.entry(o20.id, o20), + Map.entry(o21.id, o21), Map.entry(o22.id, o22), Map.entry(o23.id, o23), Map.entry(o24.id, o24), Map.entry(o25.id, o25), Map.entry(o26.id, o26), Map.entry(o27.id, o27), Map.entry(o28.id, o28), Map.entry(o29.id, o29), Map.entry(o30.id, o30), + Map.entry(o31.id, o31), Map.entry(o32.id, o32), Map.entry(o33.id, o33), Map.entry(o34.id, o34), Map.entry(o35.id, o35), Map.entry(o36.id, o36), Map.entry(o37.id, o37), Map.entry(o38.id, o38), Map.entry(o39.id, o39), Map.entry(o40.id, o40), + Map.entry(o41.id, o41), Map.entry(o42.id, o42), Map.entry(o43.id, o43), Map.entry(o44.id, o44), Map.entry(o45.id, o45), Map.entry(o46.id, o46), Map.entry(o47.id, o47), Map.entry(o48.id, o48), Map.entry(o49.id, o49), Map.entry(o50.id, o50), + Map.entry(o51.id, o51), Map.entry(o52.id, o52), Map.entry(o53.id, o53), Map.entry(o54.id, o54), Map.entry(o55.id, o55), Map.entry(o56.id, o56), Map.entry(o57.id, o57), Map.entry(o58.id, o58), Map.entry(o59.id, o59), Map.entry(o60.id, o60), + Map.entry(o61.id, o61), Map.entry(o62.id, o62), Map.entry(o63.id, o63), Map.entry(o64.id, o64), Map.entry(o65.id, o65), Map.entry(o66.id, o66), Map.entry(o67.id, o67), Map.entry(o68.id, o68), Map.entry(o69.id, o69), Map.entry(o70.id, o70), + Map.entry(o71.id, o71), Map.entry(o72.id, o72), Map.entry(o73.id, o73), Map.entry(o74.id, o74), Map.entry(o75.id, o75), Map.entry(o76.id, o76), Map.entry(o77.id, o77), Map.entry(o78.id, o78), Map.entry(o79.id, o79), Map.entry(o80.id, o80), + Map.entry(o81.id, o81), Map.entry(o82.id, o82), Map.entry(o83.id, o83), Map.entry(o84.id, o84), Map.entry(o85.id, o85), Map.entry(o86.id, o86), Map.entry(o87.id, o87), Map.entry(o88.id, o88), Map.entry(o89.id, o89), Map.entry(o90.id, o90), + Map.entry(o91.id, o91), Map.entry(o92.id, o92), Map.entry(o93.id, o93), Map.entry(o94.id, o94), Map.entry(o95.id, o95), Map.entry(o96.id, o96), Map.entry(o97.id, o97), Map.entry(o98.id, o98), Map.entry(o99.id, o99), Map.entry(o100.id, o100), + Map.entry(o101.id, o101), Map.entry(o102.id, o102), Map.entry(o103.id, o103) + ); + static Map pets = Map.ofEntries( + Map.entry(p1.id, p1), Map.entry(p2.id, p2), Map.entry(p3.id, p3), Map.entry(p4.id, p4), Map.entry(p5.id, p5), Map.entry(p6.id, p6), Map.entry(p7.id, p7), Map.entry(p8.id, p8), Map.entry(p9.id, p9), Map.entry(p10.id, p10), + Map.entry(p11.id, p11), Map.entry(p12.id, p12), Map.entry(p13.id, p13), Map.entry(p14.id, p14), Map.entry(p15.id, p15), Map.entry(p16.id, p16), Map.entry(p17.id, p17), Map.entry(p18.id, p18), Map.entry(p19.id, p19), Map.entry(p20.id, p20), + Map.entry(p21.id, p21), Map.entry(p22.id, p22), Map.entry(p23.id, p23), Map.entry(p24.id, p24), Map.entry(p25.id, p25), Map.entry(p26.id, p26), Map.entry(p27.id, p27), Map.entry(p28.id, p28), Map.entry(p29.id, p29), Map.entry(p30.id, p30), + Map.entry(p31.id, p31), Map.entry(p32.id, p32), Map.entry(p33.id, p33), Map.entry(p34.id, p34), Map.entry(p35.id, p35), Map.entry(p36.id, p36), Map.entry(p37.id, p37), Map.entry(p38.id, p38), Map.entry(p39.id, p39), Map.entry(p40.id, p40), + Map.entry(p41.id, p41), Map.entry(p42.id, p42), Map.entry(p43.id, p43), Map.entry(p44.id, p44), Map.entry(p45.id, p45), Map.entry(p46.id, p46), Map.entry(p47.id, p47), Map.entry(p48.id, p48), Map.entry(p49.id, p49), Map.entry(p50.id, p50), + Map.entry(p51.id, p51), Map.entry(p52.id, p52), Map.entry(p53.id, p53), Map.entry(p54.id, p54), Map.entry(p55.id, p55), Map.entry(p56.id, p56), Map.entry(p57.id, p57), Map.entry(p58.id, p58), Map.entry(p59.id, p59), Map.entry(p60.id, p60), + Map.entry(p61.id, p61), Map.entry(p62.id, p62), Map.entry(p63.id, p63), Map.entry(p64.id, p64), Map.entry(p65.id, p65), Map.entry(p66.id, p66), Map.entry(p67.id, p67), Map.entry(p68.id, p68), Map.entry(p69.id, p69), Map.entry(p70.id, p70), + Map.entry(p71.id, p71), Map.entry(p72.id, p72), Map.entry(p73.id, p73), Map.entry(p74.id, p74), Map.entry(p75.id, p75), Map.entry(p76.id, p76), Map.entry(p77.id, p77), Map.entry(p78.id, p78), Map.entry(p79.id, p79), Map.entry(p80.id, p80), + Map.entry(p81.id, p81), Map.entry(p82.id, p82), Map.entry(p83.id, p83), Map.entry(p84.id, p84), Map.entry(p85.id, p85), Map.entry(p86.id, p86), Map.entry(p87.id, p87), Map.entry(p88.id, p88), Map.entry(p89.id, p89), Map.entry(p90.id, p90), + Map.entry(p91.id, p91), Map.entry(p92.id, p92), Map.entry(p93.id, p93), Map.entry(p94.id, p94), Map.entry(p95.id, p95), Map.entry(p96.id, p96), Map.entry(p97.id, p97), Map.entry(p98.id, p98), Map.entry(p99.id, p99), Map.entry(p100.id, p100), + Map.entry(p101.id, p101), Map.entry(p102.id, p102), Map.entry(p103.id, p103), Map.entry(p104.id, p104), Map.entry(p105.id, p105), Map.entry(p106.id, p106), Map.entry(p107.id, p107), Map.entry(p108.id, p108), Map.entry(p109.id, p109), Map.entry(p110.id, p110), + Map.entry(p111.id, p111), Map.entry(p112.id, p112), Map.entry(p113.id, p113), Map.entry(p114.id, p114), Map.entry(p115.id, p115), Map.entry(p116.id, p116), Map.entry(p117.id, p117), Map.entry(p118.id, p118), Map.entry(p119.id, p119), Map.entry(p120.id, p120), + Map.entry(p121.id, p121), Map.entry(p122.id, p122), Map.entry(p123.id, p123), Map.entry(p124.id, p124), Map.entry(p125.id, p125), Map.entry(p126.id, p126), Map.entry(p127.id, p127), Map.entry(p128.id, p128), Map.entry(p129.id, p129), Map.entry(p130.id, p130), + Map.entry(p131.id, p131), Map.entry(p132.id, p132), Map.entry(p133.id, p133), Map.entry(p134.id, p134), Map.entry(p135.id, p135), Map.entry(p136.id, p136), Map.entry(p137.id, p137), Map.entry(p138.id, p138), Map.entry(p139.id, p139), Map.entry(p140.id, p140), + Map.entry(p141.id, p141), Map.entry(p142.id, p142), Map.entry(p143.id, p143), Map.entry(p144.id, p144), Map.entry(p145.id, p145), Map.entry(p146.id, p146), Map.entry(p147.id, p147), Map.entry(p148.id, p148), Map.entry(p149.id, p149), Map.entry(p150.id, p150), + Map.entry(p151.id, p151), Map.entry(p152.id, p152), Map.entry(p153.id, p153), Map.entry(p154.id, p154), Map.entry(p155.id, p155), Map.entry(p156.id, p156), Map.entry(p157.id, p157), Map.entry(p158.id, p158), Map.entry(p159.id, p159), Map.entry(p160.id, p160), + Map.entry(p161.id, p161), Map.entry(p162.id, p162), Map.entry(p163.id, p163), Map.entry(p164.id, p164), Map.entry(p165.id, p165), Map.entry(p166.id, p166), Map.entry(p167.id, p167), Map.entry(p168.id, p168), Map.entry(p169.id, p169), Map.entry(p170.id, p170), + Map.entry(p171.id, p171), Map.entry(p172.id, p172), Map.entry(p173.id, p173), Map.entry(p174.id, p174), Map.entry(p175.id, p175), Map.entry(p176.id, p176), Map.entry(p177.id, p177), Map.entry(p178.id, p178), Map.entry(p179.id, p179), Map.entry(p180.id, p180), + Map.entry(p181.id, p181), Map.entry(p182.id, p182), Map.entry(p183.id, p183), Map.entry(p184.id, p184), Map.entry(p185.id, p185), Map.entry(p186.id, p186), Map.entry(p187.id, p187), Map.entry(p188.id, p188), Map.entry(p189.id, p189), Map.entry(p190.id, p190), + Map.entry(p191.id, p191), Map.entry(p192.id, p192), Map.entry(p193.id, p193), Map.entry(p194.id, p194), Map.entry(p195.id, p195), Map.entry(p196.id, p196), Map.entry(p197.id, p197), Map.entry(p198.id, p198), Map.entry(p199.id, p199), Map.entry(p200.id, p200), + Map.entry(p201.id, p201), Map.entry(p202.id, p202), Map.entry(p203.id, p203), Map.entry(p204.id, p204), Map.entry(p205.id, p205), Map.entry(p206.id, p206), Map.entry(p207.id, p207), Map.entry(p208.id, p208), Map.entry(p209.id, p209), Map.entry(p210.id, p210), + Map.entry(p211.id, p211), Map.entry(p212.id, p212), Map.entry(p213.id, p213), Map.entry(p214.id, p214), Map.entry(p215.id, p215), Map.entry(p216.id, p216), Map.entry(p217.id, p217), Map.entry(p218.id, p218), Map.entry(p219.id, p219), Map.entry(p220.id, p220), + Map.entry(p221.id, p221), Map.entry(p222.id, p222), Map.entry(p223.id, p223), Map.entry(p224.id, p224), Map.entry(p225.id, p225), Map.entry(p226.id, p226), Map.entry(p227.id, p227), Map.entry(p228.id, p228), Map.entry(p229.id, p229), Map.entry(p230.id, p230), + Map.entry(p231.id, p231), Map.entry(p232.id, p232), Map.entry(p233.id, p233), Map.entry(p234.id, p234), Map.entry(p235.id, p235), Map.entry(p236.id, p236), Map.entry(p237.id, p237), Map.entry(p238.id, p238), Map.entry(p239.id, p239), Map.entry(p240.id, p240), + Map.entry(p241.id, p241), Map.entry(p242.id, p242), Map.entry(p243.id, p243), Map.entry(p244.id, p244), Map.entry(p245.id, p245), Map.entry(p246.id, p246), Map.entry(p247.id, p247), Map.entry(p248.id, p248), Map.entry(p249.id, p249), Map.entry(p250.id, p250), + Map.entry(p251.id, p251), Map.entry(p252.id, p252), Map.entry(p253.id, p253), Map.entry(p254.id, p254), Map.entry(p255.id, p255), Map.entry(p256.id, p256), Map.entry(p257.id, p257), Map.entry(p258.id, p258), Map.entry(p259.id, p259), Map.entry(p260.id, p260), + Map.entry(p261.id, p261) + ); + + static class Owner { + public Owner(String id, String name, List petIds) { + this.id = id; + this.name = name; + this.petIds = petIds; + } + + String id; + String name; + List petIds; + } + + static class Pet { + public Pet(String id, String name, String ownerId, List friendsIds) { + this.id = id; + this.name = name; + this.ownerId = ownerId; + this.friendsIds = friendsIds; + } + + String id; + String name; + String ownerId; + List friendsIds; + } + + + static BatchLoader ownerBatchLoader = list -> { +// System.out.println("OwnerBatchLoader with " + list.size() ); + List collect = list.stream().map(key -> { + Owner owner = owners.get(key); + return owner; + }).collect(Collectors.toList()); + return CompletableFuture.completedFuture(collect); + }; + static BatchLoader petBatchLoader = list -> { +// System.out.println("PetBatchLoader with list: " + list.size()); + List collect = list.stream().map(key -> { + Pet owner = pets.get(key); + return owner; + }).collect(Collectors.toList()); + return CompletableFuture.completedFuture(collect); + }; + + static final String ownerDLName = "ownerDL"; + static final String petDLName = "petDL"; + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + GraphQL graphQL; + private String query; + + @Setup + public void setup() { + try { + String sdl = PerformanceTestingUtils.loadResource("dataLoaderPerformanceSchema.graphqls"); + + DataFetcher ownersDF = (env -> { + // Load all 103 owners (O-1 through O-103) + List allOwnerIds = List.of( + "O-1", "O-2", "O-3", "O-4", "O-5", "O-6", "O-7", "O-8", "O-9", "O-10", + "O-11", "O-12", "O-13", "O-14", "O-15", "O-16", "O-17", "O-18", "O-19", "O-20", + "O-21", "O-22", "O-23", "O-24", "O-25", "O-26", "O-27", "O-28", "O-29", "O-30", + "O-31", "O-32", "O-33", "O-34", "O-35", "O-36", "O-37", "O-38", "O-39", "O-40", + "O-41", "O-42", "O-43", "O-44", "O-45", "O-46", "O-47", "O-48", "O-49", "O-50", + "O-51", "O-52", "O-53", "O-54", "O-55", "O-56", "O-57", "O-58", "O-59", "O-60", + "O-61", "O-62", "O-63", "O-64", "O-65", "O-66", "O-67", "O-68", "O-69", "O-70", + "O-71", "O-72", "O-73", "O-74", "O-75", "O-76", "O-77", "O-78", "O-79", "O-80", + "O-81", "O-82", "O-83", "O-84", "O-85", "O-86", "O-87", "O-88", "O-89", "O-90", + "O-91", "O-92", "O-93", "O-94", "O-95", "O-96", "O-97", "O-98", "O-99", "O-100", + "O-101", "O-102", "O-103" + ); + return env.getDataLoader(ownerDLName).loadMany(allOwnerIds); + }); + DataFetcher petsDf = (env -> { + Owner owner = env.getSource(); + return env.getDataLoader(petDLName).loadMany((List) owner.petIds) + .thenCompose((result) -> CompletableFuture.supplyAsync(() -> null).thenApply((__) -> result)); + }); + + DataFetcher petFriendsDF = (env -> { + Pet pet = env.getSource(); + return env.getDataLoader(petDLName).loadMany((List) pet.friendsIds) + .thenCompose((result) -> CompletableFuture.supplyAsync(() -> null).thenApply((__) -> result)); + }); + + DataFetcher petOwnerDF = (env -> { + Pet pet = env.getSource(); + return env.getDataLoader(ownerDLName).load(pet.ownerId) + .thenCompose((result) -> CompletableFuture.supplyAsync(() -> null).thenApply((__) -> result)); + }); + + + TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(sdl); + RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type("Query", builder -> builder + .dataFetcher("owners", ownersDF)) + .type("Owner", builder -> builder + .dataFetcher("pets", petsDf)) + .type("Pet", builder -> builder + .dataFetcher("friends", petFriendsDF) + .dataFetcher("owner", petOwnerDF)) + .build(); + + query = "{owners{name pets { name friends{name owner {name }}}}}"; + + schema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); + + graphQL = GraphQL.newGraphQL(schema).build(); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void executeRequestWithDataLoaders(MyState myState, Blackhole blackhole) { + DataLoader ownerDL = DataLoaderFactory.newDataLoader(ownerBatchLoader); + DataLoader petDL = DataLoaderFactory.newDataLoader(petBatchLoader); + + DataLoaderRegistry registry = DataLoaderRegistry.newRegistry().register(ownerDLName, ownerDL).register(petDLName, petDL).build(); + + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(myState.query) + .dataLoaderRegistry(registry) +// .profileExecution(true) + .build(); + executionInput.getGraphQLContext().put(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, true); +// executionInput.getGraphQLContext().put(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, true); + ExecutionResult execute = myState.graphQL.execute(executionInput); +// ProfilerResult profilerResult = executionInput.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY); +// System.out.println("execute: " + execute); + Assert.assertTrue(execute.isDataPresent()); + Assert.assertTrue(execute.getErrors().isEmpty()); + blackhole.consume(execute); + } + + public static void main(String[] args) { + DataLoaderPerformance dataLoaderPerformance = new DataLoaderPerformance(); + MyState myState = new MyState(); + myState.setup(); + Blackhole blackhole = new Blackhole("Today's password is swordfish. I understand instantiating Blackholes directly is dangerous."); + for (int i = 0; i < 1; i++) { + dataLoaderPerformance.executeRequestWithDataLoaders(myState, blackhole); + } +// System.out.println(PerLevelDataLoaderDispatchStrategy.fieldFetchedCount); +// System.out.println(PerLevelDataLoaderDispatchStrategy.onCompletionFinishedCount); +// System.out.println(PerLevelDataLoaderDispatchStrategy.isReadyCounter); +// System.out.println(Duration.ofNanos(PerLevelDataLoaderDispatchStrategy.isReadyCounterNS.get()).toMillis()); + + + } + + +} diff --git a/src/jmh/java/performance/ENF1Performance.java b/src/jmh/java/performance/ENF1Performance.java new file mode 100644 index 0000000000..06cc1a234d --- /dev/null +++ b/src/jmh/java/performance/ENF1Performance.java @@ -0,0 +1,70 @@ +package performance; + +import graphql.execution.CoercedVariables; +import graphql.language.Document; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.ExecutableNormalizedOperationFactory; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class ENF1Performance { + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + Document document; + + @Setup + public void setup() { + try { + String schemaString = PerformanceTestingUtils.loadResource("large-schema-1.graphqls"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + + String query = PerformanceTestingUtils.loadResource("large-schema-1-query.graphql"); + document = Parser.parse(query); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAvgTime(MyState myState, Blackhole blackhole) { + runImpl(myState, blackhole); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkThroughput(MyState myState, Blackhole blackhole) { + runImpl(myState, blackhole); + } + + private void runImpl(MyState myState, Blackhole blackhole) { + ExecutableNormalizedOperation executableNormalizedOperation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(myState.schema, myState.document, null, CoercedVariables.emptyVariables()); + blackhole.consume(executableNormalizedOperation); + } + + +} diff --git a/src/jmh/java/performance/ENF2Performance.java b/src/jmh/java/performance/ENF2Performance.java new file mode 100644 index 0000000000..f6240d625c --- /dev/null +++ b/src/jmh/java/performance/ENF2Performance.java @@ -0,0 +1,59 @@ +package performance; + +import graphql.execution.CoercedVariables; +import graphql.language.Document; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.ExecutableNormalizedOperationFactory; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class ENF2Performance { + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + Document document; + + @Setup + public void setup() { + try { + String schemaString = PerformanceTestingUtils.loadResource("large-schema-2.graphqls"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + + String query = PerformanceTestingUtils.loadResource("large-schema-2-query.graphql"); + document = Parser.parse(query); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public ExecutableNormalizedOperation benchMarkAvgTime(MyState myState) { + ExecutableNormalizedOperation executableNormalizedOperation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(myState.schema, myState.document, null, CoercedVariables.emptyVariables()); +// System.out.println("fields size:" + normalizedQuery.getFieldToNormalizedField().size()); + return executableNormalizedOperation; + } + +} diff --git a/src/jmh/java/performance/ENFDeepIntrospectionPerformance.java b/src/jmh/java/performance/ENFDeepIntrospectionPerformance.java new file mode 100644 index 0000000000..02d3626d0c --- /dev/null +++ b/src/jmh/java/performance/ENFDeepIntrospectionPerformance.java @@ -0,0 +1,128 @@ +package performance; + +import benchmark.BenchmarkUtils; +import graphql.execution.CoercedVariables; +import graphql.language.Document; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.ExecutableNormalizedOperationFactory; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; + +import static graphql.normalized.ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3, time = 5) +@Fork(2) +public class ENFDeepIntrospectionPerformance { + + @Param({"2", "10"}) + int howDeep = 2; + + String query = ""; + + GraphQLSchema schema; + Document document; + + @Setup(Level.Trial) + public void setUp() { + String schemaString = PerformanceTestingUtils.loadResource("large-schema-2.graphqls"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + + query = createDeepQuery(howDeep); + document = Parser.parse(query); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public ExecutableNormalizedOperation benchMarkAvgTime() { + ExecutableNormalizedOperationFactory.Options options = ExecutableNormalizedOperationFactory.Options.defaultOptions(); + ExecutableNormalizedOperation executableNormalizedOperation = createExecutableNormalizedOperation(schema, + document, + null, + CoercedVariables.emptyVariables(), + options); + return executableNormalizedOperation; + } + + public static void main(String[] args) throws RunnerException { + runAtStartup(); + + Options opt = new OptionsBuilder() + .include("performance.ENFDeepIntrospectionPerformance") + .build(); + + new Runner(opt).run(); + } + + private static void runAtStartup() { + + ENFDeepIntrospectionPerformance benchmarkIntrospection = new ENFDeepIntrospectionPerformance(); + benchmarkIntrospection.howDeep = 2; + + BenchmarkUtils.runInToolingForSomeTimeThenExit( + benchmarkIntrospection::setUp, + () -> { + while (true) { + benchmarkIntrospection.benchMarkAvgTime(); + } + }, + () -> { + } + ); + } + + + private static String createDeepQuery(int depth) { + String result = "query test {\n" + + " __schema {\n" + + " types {\n" + + " ...F1\n" + + " }\n" + + " }\n" + + "}\n"; + + for (int i = 1; i < depth; i++) { + result += " fragment F" + i + " on __Type {\n" + + " fields {\n" + + " type {\n" + + " ...F" + (i + 1) + "\n" + + " }\n" + + " }\n" + + "\n" + + " ofType {\n" + + " ...F" + (i + 1) + "\n" + + " }\n" + + " }\n"; + } + result += " fragment F" + depth + " on __Type {\n" + + " fields {\n" + + " type {\n" + + "name\n" + + " }\n" + + " }\n" + + "}\n"; + return result; + } + +} diff --git a/src/jmh/java/performance/ENFExtraLargePerformance.java b/src/jmh/java/performance/ENFExtraLargePerformance.java new file mode 100644 index 0000000000..ce8d3d6da4 --- /dev/null +++ b/src/jmh/java/performance/ENFExtraLargePerformance.java @@ -0,0 +1,68 @@ +package performance; + +import graphql.execution.CoercedVariables; +import graphql.language.Document; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.ExecutableNormalizedOperationFactory; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class ENFExtraLargePerformance { + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + Document document; + + @Setup + public void setup() { + try { + String schemaString = PerformanceTestingUtils.loadResource("extra-large-schema-1.graphqls"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + + String query = PerformanceTestingUtils.loadResource("extra-large-schema-1-query.graphql"); + document = Parser.parse(query); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchMarkAvgTime(MyState myState, Blackhole blackhole) { + runImpl(myState, blackhole); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void benchMarkThroughput(MyState myState, Blackhole blackhole) { + runImpl(myState, blackhole); + } + + private void runImpl(MyState myState, Blackhole blackhole) { + ExecutableNormalizedOperation executableNormalizedOperation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(myState.schema, myState.document, null, CoercedVariables.emptyVariables()); + blackhole.consume(executableNormalizedOperation); + } +} diff --git a/src/jmh/java/performance/LargeInMemoryQueryPerformance.java b/src/jmh/java/performance/LargeInMemoryQueryPerformance.java new file mode 100644 index 0000000000..502cc67b52 --- /dev/null +++ b/src/jmh/java/performance/LargeInMemoryQueryPerformance.java @@ -0,0 +1,140 @@ +package performance; + +import benchmark.BenchmarkUtils; +import graphql.GraphQL; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.profile.GCProfiler; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; + +/** + * This benchmark is an attempt to have a large in memory query that involves only sync work but lots of + * data fetching invocation + *

+ * It can also be run in a forever mode say if you want to connect a profiler to it say + */ +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 2) +@Fork(2) +public class LargeInMemoryQueryPerformance { + + GraphQL graphQL; + volatile boolean shutDown; + + @Setup(Level.Trial) + public void setUp() { + shutDown = false; + graphQL = buildGraphQL(); + } + + @TearDown(Level.Trial) + public void tearDown() { + shutDown = true; + } + + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public Object benchMarkSimpleQueriesThroughput() { + return runManyQueriesToCompletion(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.SECONDS) + public Object benchMarkSimpleQueriesAvgTime() { + return runManyQueriesToCompletion(); + } + + + public static void main(String[] args) throws Exception { + // just to make sure it's all valid before testing + runAtStartup(); + + Options opt = new OptionsBuilder() + .include("performance.LargeInMemoryQueryPerformance") + .addProfiler(GCProfiler.class) + .build(); + + new Runner(opt).run(); + } + + private static void runAtStartup() { + + LargeInMemoryQueryPerformance complexQueryBenchmark = new LargeInMemoryQueryPerformance(); + BenchmarkUtils.runInToolingForSomeTimeThenExit( + complexQueryBenchmark::setUp, + complexQueryBenchmark::runManyQueriesToCompletion, + complexQueryBenchmark::tearDown + + ); + } + + + private Object runManyQueriesToCompletion() { + return graphQL.execute( + "query {\n" + + "\n" + + " giveMeLargeResponse {\n" + + " someValue\n" + + " }\n" + + "}" + ); + } + + private static final List manyObjects = IntStream + .range(0, 10_000_000) + .mapToObj(i -> new SomeWrapper("value #" + i)) + .collect(Collectors.toList()); + + public static class SomeWrapper { + String someValue; + + public SomeWrapper(String someValue) { + this.someValue = someValue; + } + } + + private GraphQL buildGraphQL() { + TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse("\n" + + "type Query {\n" + + " giveMeLargeResponse: [SomeWrapper]\n" + + "}\n" + + "type SomeWrapper {\n" + + " someValue: String\n" + + "}\n" + ); + RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("giveMeLargeResponse", env -> manyObjects)) + .build(); + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, wiring); + return GraphQL.newGraphQL(schema).build(); + } +} diff --git a/src/jmh/java/performance/OverlappingFieldValidationPerformance.java b/src/jmh/java/performance/OverlappingFieldValidationPerformance.java new file mode 100644 index 0000000000..37fab1cf81 --- /dev/null +++ b/src/jmh/java/performance/OverlappingFieldValidationPerformance.java @@ -0,0 +1,246 @@ +package performance; + +import graphql.Assert; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.i18n.I18n; +import graphql.language.Document; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaGenerator; +import graphql.validation.LanguageTraversal; +import graphql.validation.RulesVisitor; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationError; +import graphql.validation.ValidationErrorCollector; +import graphql.validation.rules.OverlappingFieldsCanBeMerged; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import static graphql.Assert.assertTrue; + +@State(Scope.Benchmark) +@Warmup(iterations = 2, time = 5) +@Measurement(iterations = 3) +@Fork(2) +public class OverlappingFieldValidationPerformance { + + + static String schemaSdl = " type Query { viewer: Viewer } interface Abstract { field: Abstract leaf: Int } interface Abstract1 { field: Abstract leaf: Int } interface Abstract2 { field: Abstract leaf: Int }" + + " type Concrete1 implements Abstract1{ field: Abstract leaf: Int} " + + "type Concrete2 implements Abstract2{ field: Abstract leaf: Int} " + + "type Viewer { xingId: XingId } type XingId { firstName: String! lastName: String! }"; + + @State(Scope.Benchmark) + public static class MyState { + + GraphQLSchema schema; + GraphQLSchema schema2; + Document document; + + @Param({"100"}) + int size; + + Document overlapFrag; + Document overlapNoFrag; + Document noOverlapFrag; + Document noOverlapNoFrag; + Document repeatedFields; + Document deepAbstractConcrete; + + @Setup + public void setup() { + try { + overlapFrag = makeQuery(size, true, true); + overlapNoFrag = makeQuery(size, true, false); + noOverlapFrag = makeQuery(size, false, true); + noOverlapNoFrag = makeQuery(size, false, false); + repeatedFields = makeRepeatedFieldsQuery(size); + deepAbstractConcrete = makeDeepAbstractConcreteQuery(size); + + + schema2 = SchemaGenerator.createdMockedSchema(schemaSdl); + + String schemaString = PerformanceTestingUtils.loadResource("large-schema-4.graphqls"); + String query = PerformanceTestingUtils.loadResource("large-schema-4-query.graphql"); + schema = SchemaGenerator.createdMockedSchema(schemaString); + document = Parser.parse(query); + + // make sure this is a valid query overall + GraphQL graphQL = GraphQL.newGraphQL(schema).build(); + ExecutionResult executionResult = graphQL.execute(query); + assertTrue(executionResult.getErrors().size() == 0); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void overlappingFieldValidationAvgTime(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema, myState.document)); + } + + @Benchmark + @BenchmarkMode(Mode.Throughput) + @OutputTimeUnit(TimeUnit.SECONDS) + public void overlappingFieldValidationThroughput(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema, myState.document)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkRepeatedFields(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema2, myState.repeatedFields)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkOverlapFrag(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema2, myState.overlapFrag)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkOverlapNoFrag(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema2, myState.overlapNoFrag)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkNoOverlapFrag(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema2, myState.noOverlapFrag)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkNoOverlapNoFrag(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema2, myState.noOverlapNoFrag)); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void benchmarkDeepAbstractConcrete(MyState myState, Blackhole blackhole) { + blackhole.consume(validateQuery(myState.schema2, myState.deepAbstractConcrete)); + } + + private List validateQuery(GraphQLSchema schema, Document document) { + ValidationErrorCollector errorCollector = new ValidationErrorCollector(); + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH); + ValidationContext validationContext = new ValidationContext(schema, document, i18n); + OverlappingFieldsCanBeMerged overlappingFieldsCanBeMerged = new OverlappingFieldsCanBeMerged(validationContext, errorCollector); + LanguageTraversal languageTraversal = new LanguageTraversal(); + languageTraversal.traverse(document, new RulesVisitor(validationContext, Collections.singletonList(overlappingFieldsCanBeMerged))); + Assert.assertTrue(errorCollector.getErrors().size() == 0); + return errorCollector.getErrors(); + } + + + private static Document makeQuery(int size, boolean overlapping, boolean fragments) { + if (fragments) { + return makeQueryWithFragments(size, overlapping); + } else { + return makeQueryWithoutFragments(size, overlapping); + } + } + + private static Document makeRepeatedFieldsQuery(int size) { + StringBuilder b = new StringBuilder(); + + b.append(" query testQuery { viewer { xingId {"); + + b.append("firstName\n".repeat(Math.max(0, size))); + + b.append("} } }"); + + return Parser.parse(b.toString()); + } + + + private static Document makeQueryWithFragments(int size, boolean overlapping) { + StringBuilder b = new StringBuilder(); + + for (int i = 1; i <= size; i++) { + if (overlapping) { + b.append(" fragment mergeIdenticalFields" + i + " on Query {viewer { xingId { firstName lastName }}}"); + } else { + b.append("fragment mergeIdenticalFields" + i + " on Query {viewer" + i + " { xingId" + i + " { firstName" + i + " lastName" + i + " } }}"); + } + + b.append("\n\n"); + } + + b.append("query testQuery {"); + for (int i = 1; i <= size; i++) { + b.append("...mergeIdenticalFields" + i + "\n"); + } + b.append("}"); + return Parser.parse(b.toString()); + } + + private static Document makeQueryWithoutFragments(int size, boolean overlapping) { + StringBuilder b = new StringBuilder(); + + b.append("query testQuery {"); + + for (int i = 1; i <= size; i++) { + if (overlapping) { + b.append(" viewer { xingId { firstName } } "); + } else { + b.append(" viewer" + i + " { xingId" + i + " { firstName" + i + " } } "); + } + + b.append("\n\n"); + } + + b.append("}"); + + return Parser.parse(b.toString()); + } + + private static Document makeDeepAbstractConcreteQuery(int depth) { + StringBuilder q = new StringBuilder(); + + q.append("fragment multiply on Whatever { field { " + + "... on Abstract1 { field { leaf } } " + + "... on Abstract2 { field { leaf } } " + + "... on Concrete1 { field { leaf } } " + + "... on Concrete2 { field { leaf } } } } " + + "query DeepAbstractConcrete { "); + + for (int i = 1; i <= depth; i++) { + q.append("field { ...multiply "); + } + + for (int i = 1; i <= depth; i++) { + q.append(" }"); + } + + q.append("\n}"); + + return Parser.parse(q.toString()); + } +} diff --git a/src/jmh/java/performance/PerformanceTestingUtils.java b/src/jmh/java/performance/PerformanceTestingUtils.java new file mode 100644 index 0000000000..9e05fd661c --- /dev/null +++ b/src/jmh/java/performance/PerformanceTestingUtils.java @@ -0,0 +1,84 @@ +package performance; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.Charset; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.Callable; + +public class PerformanceTestingUtils { + + @SuppressWarnings("UnstableApiUsage") + static String loadResource(String name) { + return asRTE(() -> { + URL resource = PerformanceTestingUtils.class.getClassLoader().getResource(name); + if (resource == null) { + throw new IllegalArgumentException("missing resource: " + name); + } + byte[] bytes; + try (InputStream inputStream = resource.openStream()) { + bytes = inputStream.readAllBytes(); + } + return new String(bytes, Charset.defaultCharset()); + }); + } + + static T asRTE(Callable callable) { + try { + return callable.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void runInToolingForSomeTimeThenExit(Runnable setup, Runnable r, Runnable tearDown) { + int runForMillis = getRunForMillis(); + if (runForMillis <= 0) { + System.out.print("'runForMillis' environment var is not set - continuing \n"); + return; + } + System.out.printf("Running initial code in some tooling - runForMillis=%d \n", runForMillis); + System.out.print("Get your tooling in order and press enter..."); + readLine(); + System.out.print("Lets go...\n"); + setup.run(); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss"); + long now, then = System.currentTimeMillis(); + do { + now = System.currentTimeMillis(); + long msLeft = runForMillis - (now - then); + System.out.printf("\t%s Running in loop... %s ms left\n", dtf.format(LocalDateTime.now()), msLeft); + r.run(); + now = System.currentTimeMillis(); + } while ((now - then) < runForMillis); + + tearDown.run(); + + System.out.printf("This ran for %d millis. Exiting...\n", System.currentTimeMillis() - then); + System.exit(0); + } + + private static void readLine() { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + try { + br.readLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static int getRunForMillis() { + String runFor = System.getenv("runForMillis"); + try { + return Integer.parseInt(runFor); + } catch (NumberFormatException e) { + return -1; + } + } + +} diff --git a/src/main/antlr/Graphql.g4 b/src/main/antlr/Graphql.g4 index c2d7202a2f..e3dd7f4cda 100644 --- a/src/main/antlr/Graphql.g4 +++ b/src/main/antlr/Graphql.g4 @@ -5,13 +5,28 @@ import GraphqlSDL, GraphqlOperation, GraphqlCommon; package graphql.parser.antlr; } +@lexer::members { + public boolean isDigit(int c) { + return c >= '0' && c <= '9'; + } + public boolean isNameStart(int c) { + return '_' == c || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z'); + } + public boolean isDot(int c) { + return '.' == c; + } +} + document : definition+; definition: operationDefinition | fragmentDefinition | -typeSystemDefinition +typeSystemDefinition | +typeSystemExtension ; diff --git a/src/main/antlr/GraphqlCommon.g4 b/src/main/antlr/GraphqlCommon.g4 index a598a208ea..5ee4110a77 100644 --- a/src/main/antlr/GraphqlCommon.g4 +++ b/src/main/antlr/GraphqlCommon.g4 @@ -1,10 +1,11 @@ grammar GraphqlCommon; + operationType : SUBSCRIPTION | MUTATION | QUERY; -description : stringValue; +description : StringValue; -enumValue : name ; +enumValue : enumValueName ; arrayValue: '[' value* ']'; @@ -28,10 +29,14 @@ arguments : '(' argument+ ')'; argument : name ':' valueWithVariable; -name: NAME | FRAGMENT | QUERY | MUTATION | SUBSCRIPTION | SCHEMA | SCALAR | TYPE | INTERFACE | IMPLEMENTS | ENUM | UNION | INPUT | EXTEND | DIRECTIVE; +baseName: NAME | FRAGMENT | QUERY | MUTATION | SUBSCRIPTION | SCHEMA | SCALAR | TYPE | INTERFACE | IMPLEMENTS | ENUM | UNION | INPUT | EXTEND | DIRECTIVE | REPEATABLE; +fragmentName: baseName | BooleanValue | NullValue; +enumValueName: baseName | ON_KEYWORD; + +name: baseName | BooleanValue | NullValue | ON_KEYWORD; value : -stringValue | +StringValue | IntValue | FloatValue | BooleanValue | @@ -43,7 +48,7 @@ objectValue; valueWithVariable : variable | -stringValue | +StringValue | IntValue | FloatValue | BooleanValue | @@ -57,10 +62,6 @@ variable : '$' name; defaultValue : '=' value; -stringValue - : TripleQuotedStringValue - | StringValue - ; type : typeName | listType | nonNullType; typeName : name; @@ -86,48 +87,65 @@ UNION: 'union'; INPUT: 'input'; EXTEND: 'extend'; DIRECTIVE: 'directive'; +ON_KEYWORD: 'on'; +REPEATABLE: 'repeatable'; NAME: [_A-Za-z][_0-9A-Za-z]*; -IntValue : Sign? IntegerPart; - -FloatValue : Sign? IntegerPart ('.' Digit+)? ExponentPart?; - -Sign : '-'; - -IntegerPart : '0' | NonZeroDigit | NonZeroDigit Digit+; - -NonZeroDigit: '1'.. '9'; - -ExponentPart : ('e'|'E') Sign? Digit+; - -Digit : '0'..'9'; - - -StringValue - : '"' ( ~["\\\n\r\u2028\u2029] | EscapedChar )* '"' - ; - -TripleQuotedStringValue - : '"""' TripleQuotedStringPart? '"""' - ; - - -// Fragments never become a token of their own: they are only used inside other lexer rules -fragment TripleQuotedStringPart : ( EscapedTripleQuote | SourceCharacter )+?; -fragment EscapedTripleQuote : '\\"""'; -fragment SourceCharacter :[\u0009\u000A\u000D\u0020-\uFFFF]; - -Comment: '#' ~[\n\r\u2028\u2029]* -> channel(2); - -Ignored: (UnicodeBOM|Whitespace|LineTerminator|Comma) -> skip; - -fragment EscapedChar : '\\' (["\\/bfnrt] | Unicode) ; -fragment Unicode : 'u' Hex Hex Hex Hex ; -fragment Hex : [0-9a-fA-F] ; - -fragment LineTerminator: [\n\r\u2028\u2029]; -fragment Whitespace : [\u0009\u0020]; -fragment Comma : ','; -fragment UnicodeBOM : [\ufeff]; +// Int Value +IntValue : IntegerPart { !isDigit(_input.LA(1)) && !isDot(_input.LA(1)) && !isNameStart(_input.LA(1)) }?; +fragment IntegerPart : NegativeSign? '0' | NegativeSign? NonZeroDigit Digit*; +fragment NegativeSign : '-'; +fragment NonZeroDigit: '1'..'9'; + +// Float Value +FloatValue : ((IntegerPart FractionalPart ExponentPart) { !isDigit(_input.LA(1)) && !isDot(_input.LA(1)) && !isNameStart(_input.LA(1)) }?) | + ((IntegerPart FractionalPart ) { !isDigit(_input.LA(1)) && !isDot(_input.LA(1)) && !isNameStart(_input.LA(1)) }?) | + ((IntegerPart ExponentPart) { !isDigit(_input.LA(1)) && !isDot(_input.LA(1)) && !isNameStart(_input.LA(1)) }?); +fragment FractionalPart: '.' Digit+; +fragment ExponentPart : ExponentIndicator Sign? Digit+; +fragment ExponentIndicator: 'e' | 'E'; +fragment Sign: '+'|'-'; +fragment Digit : '0'..'9'; + +// StringValue +StringValue: +'""' { _input.LA(1) != '"'}? | +'"' StringCharacter+ '"' | +'"""' BlockStringCharacter*? '"""'; + +fragment BlockStringCharacter: +'\\"""'| +SourceCharacter; + +// this is SourceCharacter without +// \u000a New line +// \u000d Carriage return +// \u0022 '"' +// \u005c '\' +fragment StringCharacter: +([\u0000-\u0009] | [\u000b\u000c\u000e-\u0021] | [\u0023-\u005b] | [\u005d-\ud7ff] | [\ue000-\u{10ffff}]) | +'\\u' EscapedUnicode | +'\\' EscapedCharacter; + +fragment EscapedCharacter : ["\\/bfnrt]; +fragment EscapedUnicode : Hex Hex Hex Hex | '{' Hex+ '}'; +fragment Hex : [0-9a-fA-F]; + +// this is the spec definition. Excludes surrogate leading and trailing values. +fragment SourceCharacter : [\u0000-\ud7ff] | [\ue000-\u{10ffff}]; + +// CommentChar +fragment SourceCharacterWithoutLineFeed : [\u0000-\u0009] | [\u000b\u000c\u000e-\ud7ff] | [\ue000-\u{10ffff}]; + +Comment: '#' SourceCharacterWithoutLineFeed* -> channel(2); + +LF: [\n] -> channel(3); +CR: [\r] -> channel(3); +LineTerminator: [\u2028\u2029] -> channel(3); + +Space : [\u0020] -> channel(3); +Tab : [\u0009] -> channel(3); +Comma : ',' -> channel(3); +UnicodeBOM : [\ufeff] -> channel(3); diff --git a/src/main/antlr/GraphqlOperation.g4 b/src/main/antlr/GraphqlOperation.g4 index fc03d97ffd..e5c862940a 100644 --- a/src/main/antlr/GraphqlOperation.g4 +++ b/src/main/antlr/GraphqlOperation.g4 @@ -7,7 +7,7 @@ operationType name? variableDefinitions? directives? selectionSet; variableDefinitions : '(' variableDefinition+ ')'; -variableDefinition : variable ':' type defaultValue?; +variableDefinition : variable ':' type defaultValue? directives?; selectionSet : '{' selection+ '}'; @@ -23,13 +23,11 @@ alias : name ':'; - fragmentSpread : '...' fragmentName directives?; inlineFragment : '...' typeCondition? directives? selectionSet; -fragmentDefinition : 'fragment' fragmentName typeCondition directives? selectionSet; +fragmentDefinition : FRAGMENT fragmentName typeCondition directives? selectionSet; -fragmentName : name; -typeCondition : 'on' typeName; +typeCondition : ON_KEYWORD typeName; diff --git a/src/main/antlr/GraphqlSDL.g4 b/src/main/antlr/GraphqlSDL.g4 index 9dd97dc29d..9c4ef2a4f1 100644 --- a/src/main/antlr/GraphqlSDL.g4 +++ b/src/main/antlr/GraphqlSDL.g4 @@ -1,15 +1,24 @@ grammar GraphqlSDL; import GraphqlCommon; -typeSystemDefinition: description? +typeSystemDefinition: schemaDefinition | typeDefinition | -typeExtension | directiveDefinition ; +typeSystemExtension : +schemaExtension | +typeExtension +; + schemaDefinition : description? SCHEMA directives? '{' operationTypeDefinition+ '}'; +schemaExtension : + EXTEND SCHEMA directives? '{' operationTypeDefinition+ '}' | + EXTEND SCHEMA directives +; + operationTypeDefinition : description? operationType ':' typeName; typeDefinition: @@ -35,35 +44,49 @@ typeExtension : inputObjectTypeExtensionDefinition ; +emptyParentheses : '{' '}'; scalarTypeDefinition : description? SCALAR name directives?; -scalarTypeExtensionDefinition : EXTEND SCALAR name directives?; +scalarTypeExtensionDefinition : EXTEND SCALAR name directives; objectTypeDefinition : description? TYPE name implementsInterfaces? directives? fieldsDefinition?; -objectTypeExtensionDefinition : EXTEND TYPE name implementsInterfaces? directives? fieldsDefinition?; +objectTypeExtensionDefinition : + EXTEND TYPE name implementsInterfaces? directives? extensionFieldsDefinition | + EXTEND TYPE name implementsInterfaces? directives emptyParentheses? | + EXTEND TYPE name implementsInterfaces +; implementsInterfaces : - IMPLEMENTS '&'? typeName+ | + IMPLEMENTS '&'? typeName | implementsInterfaces '&' typeName ; fieldsDefinition : '{' fieldDefinition* '}'; +extensionFieldsDefinition : '{' fieldDefinition+ '}'; + fieldDefinition : description? name argumentsDefinition? ':' type directives?; argumentsDefinition : '(' inputValueDefinition+ ')'; inputValueDefinition : description? name ':' type defaultValue? directives?; -interfaceTypeDefinition : description? INTERFACE name directives? fieldsDefinition?; +interfaceTypeDefinition : description? INTERFACE name implementsInterfaces? directives? fieldsDefinition?; -interfaceTypeExtensionDefinition : EXTEND INTERFACE name directives? fieldsDefinition?; +interfaceTypeExtensionDefinition : + EXTEND INTERFACE name implementsInterfaces? directives? extensionFieldsDefinition | + EXTEND INTERFACE name implementsInterfaces? directives emptyParentheses? | + EXTEND INTERFACE name implementsInterfaces +; -unionTypeDefinition : description? UNION name directives? unionMembership; +unionTypeDefinition : description? UNION name directives? unionMembership?; -unionTypeExtensionDefinition : EXTEND UNION name directives? unionMembership?; +unionTypeExtensionDefinition : + EXTEND UNION name directives? unionMembership | + EXTEND UNION name directives +; unionMembership : '=' unionMembers; @@ -72,27 +95,37 @@ unionMembers: unionMembers '|' typeName ; -enumTypeDefinition : description? ENUM name directives? enumValueDefinitions; +enumTypeDefinition : description? ENUM name directives? enumValueDefinitions?; + +enumTypeExtensionDefinition : + EXTEND ENUM name directives? extensionEnumValueDefinitions | + EXTEND ENUM name directives emptyParentheses? +; -enumTypeExtensionDefinition : EXTEND ENUM name directives? enumValueDefinitions?; +enumValueDefinitions : '{' enumValueDefinition* '}'; -enumValueDefinitions : '{' enumValueDefinition+ '}'; +extensionEnumValueDefinitions : '{' enumValueDefinition+ '}'; enumValueDefinition : description? enumValue directives?; -inputObjectTypeDefinition : description? INPUT name directives? inputObjectValueDefinitions; +inputObjectTypeDefinition : description? INPUT name directives? inputObjectValueDefinitions?; + +inputObjectTypeExtensionDefinition : + EXTEND INPUT name directives? extensionInputObjectValueDefinitions | + EXTEND INPUT name directives emptyParentheses? +; -inputObjectTypeExtensionDefinition : EXTEND INPUT name directives? inputObjectValueDefinitions?; +inputObjectValueDefinitions : '{' inputValueDefinition* '}'; -inputObjectValueDefinitions : '{' inputValueDefinition+ '}'; +extensionInputObjectValueDefinitions : '{' inputValueDefinition+ '}'; -directiveDefinition : description? DIRECTIVE '@' name argumentsDefinition? 'on' directiveLocations; +directiveDefinition : description? DIRECTIVE '@' name argumentsDefinition? REPEATABLE? ON_KEYWORD directiveLocations; directiveLocation : name; directiveLocations : -directiveLocation | +'|'? directiveLocation | directiveLocations '|' directiveLocation ; diff --git a/src/main/java/graphql/Assert.java b/src/main/java/graphql/Assert.java index e984063c1a..8a29252782 100644 --- a/src/main/java/graphql/Assert.java +++ b/src/main/java/graphql/Assert.java @@ -1,48 +1,231 @@ package graphql; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + import java.util.Collection; +import java.util.function.Supplier; +import java.util.regex.Pattern; import static java.lang.String.format; @SuppressWarnings("TypeParameterUnusedInFormals") @Internal +@NullMarked public class Assert { - public static T assertNotNull(T object, String format, Object... args) { - if (object != null) return object; - throw new AssertException(format(format, args)); + public static T assertNotNullWithNPE(T object, Supplier msg) { + if (object != null) { + return object; + } + throw new NullPointerException(msg.get()); + } + + public static T assertNotNullWithNPE(T object, String constantMsg) { + if (object != null) { + return object; + } + throw new NullPointerException(constantMsg); + } + + @Contract("null -> fail") + public static T assertNotNull(@Nullable T object) { + if (object != null) { + return object; + } + return throwAssert("Object required to be not null"); + } + + @Contract("null,_ -> fail") + public static T assertNotNull(@Nullable T object, Supplier msg) { + if (object != null) { + return object; + } + return throwAssert(msg.get()); + } + + @Contract("null,_ -> fail") + public static T assertNotNull(@Nullable T object, String constantMsg) { + if (object != null) { + return object; + } + return throwAssert(constantMsg); } - public static T assertNotNull(T object) { - if (object != null) return object; - throw new AssertException("Object required to be not null"); + @Contract("null,_,_ -> fail") + public static T assertNotNull(@Nullable T object, String msgFmt, Object arg1) { + if (object != null) { + return object; + } + return throwAssert(msgFmt, arg1); } + @Contract("null,_,_,_ -> fail") + public static T assertNotNull(@Nullable T object, String msgFmt, Object arg1, Object arg2) { + if (object != null) { + return object; + } + return throwAssert(msgFmt, arg1, arg2); + } + + @Contract("null,_,_,_,_ -> fail") + public static T assertNotNull(@Nullable T object, String msgFmt, Object arg1, Object arg2, Object arg3) { + if (object != null) { + return object; + } + return throwAssert(msgFmt, arg1, arg2, arg3); + } + + + @Contract("!null,_ -> fail") + public static void assertNull(@Nullable T object, Supplier msg) { + if (object == null) { + return; + } + throwAssert(msg.get()); + } + + @Contract("!null,_ -> fail") + public static void assertNull(@Nullable T object, String constantMsg) { + if (object == null) { + return; + } + throwAssert(constantMsg); + } + + @Contract("!null -> fail") + public static void assertNull(@Nullable Object object) { + if (object == null) { + return; + } + throwAssert("Object required to be null"); + } + + @Contract("-> fail") public static T assertNeverCalled() { - throw new AssertException("Should never been called"); + return throwAssert("Should never been called"); } + @Contract("_,_-> fail") public static T assertShouldNeverHappen(String format, Object... args) { - throw new AssertException("Internal error: should never happen: " + format(format, args)); + return throwAssert("Internal error: should never happen: %s", format(format, args)); } + @Contract("-> fail") public static T assertShouldNeverHappen() { - throw new AssertException("Internal error: should never happen"); + return throwAssert("Internal error: should never happen"); } - public static Collection assertNotEmpty(Collection c, String format, Object... args) { - if (c == null || c.isEmpty()) - throw new AssertException(format(format, args)); - return c; + public static Collection assertNotEmpty(Collection collection) { + if (collection == null || collection.isEmpty()) { + throwAssert("collection must be not null and not empty"); + } + return collection; } - public static void assertTrue(boolean condition, String format, Object... args) { - if (condition) return; - throw new AssertException(format(format, args)); + // @Contract("null,_-> fail") + public static Collection assertNotEmpty(Collection collection, Supplier msg) { + if (collection == null || collection.isEmpty()) { + throwAssert(msg.get()); + } + return collection; + } + + public static Collection assertNotEmpty(Collection collection, String constantMsg) { + if (collection == null || collection.isEmpty()) { + throwAssert(constantMsg); + } + return collection; + } + + public static void assertTrue(boolean condition, Supplier msg) { + if (condition) { + return; + } + throwAssert(msg.get()); + } + + public static void assertTrue(boolean condition) { + if (condition) { + return; + } + throwAssert("condition expected to be true"); + } + + public static void assertTrue(boolean condition, String constantMsg) { + if (condition) { + return; + } + throwAssert(constantMsg); + } + + public static void assertTrue(boolean condition, String msgFmt, Object arg1) { + if (condition) { + return; + } + throwAssert(msgFmt, arg1); + } + + public static void assertTrue(boolean condition, String msgFmt, Object arg1, Object arg2) { + if (condition) { + return; + } + throwAssert(msgFmt, arg1, arg2); + } + + public static void assertTrue(boolean condition, String msgFmt, Object arg1, Object arg2, Object arg3) { + if (condition) { + return; + } + throwAssert(msgFmt, arg1, arg2, arg3); + } + + public static void assertFalse(boolean condition, Supplier msg) { + if (!condition) { + return; + } + throwAssert(msg.get()); + } + + public static void assertFalse(boolean condition) { + if (!condition) { + return; + } + throwAssert("condition expected to be false"); + } + + public static void assertFalse(boolean condition, String constantMsg) { + if (!condition) { + return; + } + throwAssert(constantMsg); + } + + public static void assertFalse(boolean condition, String msgFmt, Object arg1) { + if (!condition) { + return; + } + throwAssert(msgFmt, arg1); + } + + public static void assertFalse(boolean condition, String msgFmt, Object arg1, Object arg2) { + if (!condition) { + return; + } + throwAssert(msgFmt, arg1, arg2); + } + + public static void assertFalse(boolean condition, String msgFmt, Object arg1, Object arg2, Object arg3) { + if (!condition) { + return; + } + throwAssert(msgFmt, arg1, arg2, arg3); } private static final String invalidNameErrorMessage = "Name must be non-null, non-empty and match [_A-Za-z][_0-9A-Za-z]* - was '%s'"; + private static final Pattern validNamePattern = Pattern.compile("[_A-Za-z][_0-9A-Za-z]*"); + /** * Validates that the Lexical token name matches the current spec. * currently non null, non empty, @@ -52,10 +235,13 @@ public static void assertTrue(boolean condition, String format, Object... args) * @return the name if valid, or AssertException if invalid. */ public static String assertValidName(String name) { - if (name != null && !name.isEmpty() && name.matches("[_A-Za-z][_0-9A-Za-z]*")) { + if (name != null && !name.isEmpty() && validNamePattern.matcher(name).matches()) { return name; } - throw new AssertException(String.format(invalidNameErrorMessage,name)); + return throwAssert(invalidNameErrorMessage, name); } + private static T throwAssert(String format, Object... args) { + throw new AssertException(format(format, args)); + } } diff --git a/src/main/java/graphql/Contract.java b/src/main/java/graphql/Contract.java new file mode 100644 index 0000000000..93ba900bf2 --- /dev/null +++ b/src/main/java/graphql/Contract.java @@ -0,0 +1,27 @@ +package graphql; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +/** + * Custom contract annotation used for jspecify and NullAway checks. + * + * This is the same as Spring does: we don't want any additional dependencies, therefore we define our own Contract annotation. + * + * @see Spring Framework Contract + * @see org.jetbrains.annotations.Contract + * @see + * NullAway custom contract annotations + */ +@Documented +@Target(ElementType.METHOD) +@Internal +public @interface Contract { + + /** + * Describing the contract between call arguments and the returned value. + */ + String value() default ""; + +} diff --git a/src/main/java/graphql/Directives.java b/src/main/java/graphql/Directives.java index ad904c0103..37f2b28550 100644 --- a/src/main/java/graphql/Directives.java +++ b/src/main/java/graphql/Directives.java @@ -1,60 +1,275 @@ package graphql; +import graphql.language.BooleanValue; +import graphql.language.Description; +import graphql.language.DirectiveDefinition; +import graphql.language.StringValue; import graphql.schema.GraphQLDirective; +import java.util.concurrent.atomic.AtomicBoolean; + import static graphql.Scalars.GraphQLBoolean; import static graphql.Scalars.GraphQLString; +import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION; +import static graphql.introspection.Introspection.DirectiveLocation.ENUM_VALUE; import static graphql.introspection.Introspection.DirectiveLocation.FIELD; import static graphql.introspection.Introspection.DirectiveLocation.FIELD_DEFINITION; import static graphql.introspection.Introspection.DirectiveLocation.FRAGMENT_SPREAD; import static graphql.introspection.Introspection.DirectiveLocation.INLINE_FRAGMENT; +import static graphql.introspection.Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION; +import static graphql.introspection.Introspection.DirectiveLocation.INPUT_OBJECT; +import static graphql.introspection.Introspection.DirectiveLocation.MUTATION; +import static graphql.introspection.Introspection.DirectiveLocation.QUERY; +import static graphql.introspection.Introspection.DirectiveLocation.SCALAR; +import static graphql.introspection.Introspection.DirectiveLocation.SUBSCRIPTION; +import static graphql.language.DirectiveLocation.newDirectiveLocation; +import static graphql.language.InputValueDefinition.newInputValueDefinition; +import static graphql.language.NonNullType.newNonNullType; +import static graphql.language.TypeName.newTypeName; import static graphql.schema.GraphQLArgument.newArgument; import static graphql.schema.GraphQLNonNull.nonNull; /** - * The query directives that are under stood by graphql-java + * The directives that are understood by graphql-java */ +@PublicApi public class Directives { + private static final String DEPRECATED = "deprecated"; + private static final String INCLUDE = "include"; + private static final String SKIP = "skip"; + private static final String SPECIFIED_BY = "specifiedBy"; + private static final String ONE_OF = "oneOf"; + private static final String DEFER = "defer"; + private static final String EXPERIMENTAL_DISABLE_ERROR_PROPAGATION = "experimental_disableErrorPropagation"; + + public static final DirectiveDefinition DEPRECATED_DIRECTIVE_DEFINITION; + public static final DirectiveDefinition INCLUDE_DIRECTIVE_DEFINITION; + public static final DirectiveDefinition SKIP_DIRECTIVE_DEFINITION; + public static final DirectiveDefinition SPECIFIED_BY_DIRECTIVE_DEFINITION; + @ExperimentalApi + public static final DirectiveDefinition ONE_OF_DIRECTIVE_DEFINITION; + @ExperimentalApi + public static final DirectiveDefinition DEFER_DIRECTIVE_DEFINITION; + @ExperimentalApi + public static final DirectiveDefinition EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_DEFINITION; + + public static final String BOOLEAN = "Boolean"; + public static final String STRING = "String"; + public static final String NO_LONGER_SUPPORTED = "No longer supported"; + + static { + DEPRECATED_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(DEPRECATED) + .directiveLocation(newDirectiveLocation().name(FIELD_DEFINITION.name()).build()) + .directiveLocation(newDirectiveLocation().name(ENUM_VALUE.name()).build()) + .directiveLocation(newDirectiveLocation().name(ARGUMENT_DEFINITION.name()).build()) + .directiveLocation(newDirectiveLocation().name(INPUT_FIELD_DEFINITION.name()).build()) + .description(createDescription("Marks the field, argument, input field or enum value as deprecated")) + .inputValueDefinition( + newInputValueDefinition() + .name("reason") + .description(createDescription("The reason for the deprecation")) + .type(newNonNullType(newTypeName().name(STRING).build()).build()) + .defaultValue(StringValue.newStringValue().value(NO_LONGER_SUPPORTED).build()) + .build()) + .build(); + + INCLUDE_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(INCLUDE) + .directiveLocation(newDirectiveLocation().name(FRAGMENT_SPREAD.name()).build()) + .directiveLocation(newDirectiveLocation().name(INLINE_FRAGMENT.name()).build()) + .directiveLocation(newDirectiveLocation().name(FIELD.name()).build()) + .description(createDescription("Directs the executor to include this field or fragment only when the `if` argument is true")) + .inputValueDefinition( + newInputValueDefinition() + .name("if") + .description(createDescription("Included when true.")) + .type(newNonNullType(newTypeName().name(BOOLEAN).build()).build()) + .build()) + .build(); + + SKIP_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(SKIP) + .directiveLocation(newDirectiveLocation().name(FRAGMENT_SPREAD.name()).build()) + .directiveLocation(newDirectiveLocation().name(INLINE_FRAGMENT.name()).build()) + .directiveLocation(newDirectiveLocation().name(FIELD.name()).build()) + .description(createDescription("Directs the executor to skip this field or fragment when the `if` argument is true.")) + .inputValueDefinition( + newInputValueDefinition() + .name("if") + .description(createDescription("Skipped when true.")) + .type(newNonNullType(newTypeName().name(BOOLEAN).build()).build()) + .build()) + .build(); + + SPECIFIED_BY_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(SPECIFIED_BY) + .directiveLocation(newDirectiveLocation().name(SCALAR.name()).build()) + .description(createDescription("Exposes a URL that specifies the behaviour of this scalar.")) + .inputValueDefinition( + newInputValueDefinition() + .name("url") + .description(createDescription("The URL that specifies the behaviour of this scalar.")) + .type(newNonNullType(newTypeName().name(STRING).build()).build()) + .build()) + .build(); + + ONE_OF_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(ONE_OF) + .directiveLocation(newDirectiveLocation().name(INPUT_OBJECT.name()).build()) + .description(createDescription("Indicates an Input Object is a OneOf Input Object.")) + .build(); + + DEFER_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(DEFER) + .directiveLocation(newDirectiveLocation().name(FRAGMENT_SPREAD.name()).build()) + .directiveLocation(newDirectiveLocation().name(INLINE_FRAGMENT.name()).build()) + .description(createDescription("This directive allows results to be deferred during execution")) + .inputValueDefinition( + newInputValueDefinition() + .name("if") + .description(createDescription("Deferred behaviour is controlled by this argument")) + .type(newNonNullType(newTypeName().name(BOOLEAN).build()).build()) + .defaultValue(BooleanValue.newBooleanValue(true).build()) + .build()) + .inputValueDefinition( + newInputValueDefinition() + .name("label") + .description(createDescription("A unique label that represents the fragment being deferred")) + .type(newTypeName().name(STRING).build()) + .build()) + .build(); + EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_DEFINITION = DirectiveDefinition.newDirectiveDefinition() + .name(EXPERIMENTAL_DISABLE_ERROR_PROPAGATION) + .directiveLocation(newDirectiveLocation().name(QUERY.name()).build()) + .directiveLocation(newDirectiveLocation().name(MUTATION.name()).build()) + .directiveLocation(newDirectiveLocation().name(SUBSCRIPTION.name()).build()) + .description(createDescription("This directive allows returning null in non-null positions that have an associated error")) + .build(); + } + + /** + * The @defer directive can be used to defer sending data for a fragment until later in the query. + * This is an opt-in directive that is not available unless it is explicitly put into the schema. + *

+ * This implementation is based on the state of Defer/Stream PR + * More specifically at the state of this + * commit + *

+ * The execution behaviour should match what we get from running Apollo Server 4.9.5 with graphql-js v17.0.0-alpha.2 + */ + @ExperimentalApi + public static final GraphQLDirective DeferDirective = GraphQLDirective.newDirective() + .name(DEFER) + .description("This directive allows results to be deferred during execution") + .validLocations(FRAGMENT_SPREAD, INLINE_FRAGMENT) + .argument(newArgument() + .name("if") + .type(nonNull(GraphQLBoolean)) + .description("Deferred behaviour is controlled by this argument") + .defaultValueLiteral(BooleanValue.newBooleanValue(true).build()) + ) + .argument(newArgument() + .name("label") + .type(GraphQLString) + .description("A unique label that represents the fragment being deferred") + ) + .definition(DEFER_DIRECTIVE_DEFINITION) + .build(); + public static final GraphQLDirective IncludeDirective = GraphQLDirective.newDirective() - .name("include") + .name(INCLUDE) .description("Directs the executor to include this field or fragment only when the `if` argument is true") .argument(newArgument() .name("if") .type(nonNull(GraphQLBoolean)) .description("Included when true.")) .validLocations(FRAGMENT_SPREAD, INLINE_FRAGMENT, FIELD) + .definition(INCLUDE_DIRECTIVE_DEFINITION) .build(); public static final GraphQLDirective SkipDirective = GraphQLDirective.newDirective() - .name("skip") - .description("Directs the executor to skip this field or fragment when the `if`'argument is true.") + .name(SKIP) + .description("Directs the executor to skip this field or fragment when the `if` argument is true.") .argument(newArgument() .name("if") .type(nonNull(GraphQLBoolean)) .description("Skipped when true.")) .validLocations(FRAGMENT_SPREAD, INLINE_FRAGMENT, FIELD) + .definition(SKIP_DIRECTIVE_DEFINITION) .build(); + /** - * @deprecated - this is no longer needed and will be removed in a future version + * The "deprecated" directive is special and is always available in a graphql schema + *

+ * See the GraphQL specification for @deprecated */ - @Deprecated - public static final GraphQLDirective FetchDirective = GraphQLDirective.newDirective() - .name("fetch") - .description("Directs the SDL type generation to create a data fetcher that uses this `from` argument as the property name") + public static final GraphQLDirective DeprecatedDirective = GraphQLDirective.newDirective() + .name(DEPRECATED) + .description("Marks the field, argument, input field or enum value as deprecated") .argument(newArgument() - .name("from") + .name("reason") .type(nonNull(GraphQLString)) - .description("The `name` used to fetch values from the underlying object")) - .validLocations(FIELD_DEFINITION) + .defaultValueProgrammatic(NO_LONGER_SUPPORTED) + .description("The reason for the deprecation")) + .validLocations(FIELD_DEFINITION, ENUM_VALUE, ARGUMENT_DEFINITION, INPUT_FIELD_DEFINITION) + .definition(DEPRECATED_DIRECTIVE_DEFINITION) .build(); - public static final GraphQLDirective DeferDirective = GraphQLDirective.newDirective() - .name("defer") - .description("This directive allows results to be deferred during execution") - .validLocations(FIELD) + /** + * The "specifiedBy" directive allows to provide a specification URL for a Scalar + */ + public static final GraphQLDirective SpecifiedByDirective = GraphQLDirective.newDirective() + .name(SPECIFIED_BY) + .description("Exposes a URL that specifies the behaviour of this scalar.") + .argument(newArgument() + .name("url") + .type(nonNull(GraphQLString)) + .description("The URL that specifies the behaviour of this scalar.")) + .validLocations(SCALAR) + .definition(SPECIFIED_BY_DIRECTIVE_DEFINITION) + .build(); + + @ExperimentalApi + public static final GraphQLDirective OneOfDirective = GraphQLDirective.newDirective() + .name(ONE_OF) + .description("Indicates an Input Object is a OneOf Input Object.") + .validLocations(INPUT_OBJECT) + .definition(ONE_OF_DIRECTIVE_DEFINITION) .build(); + @ExperimentalApi + public static final GraphQLDirective ExperimentalDisableErrorPropagationDirective = GraphQLDirective.newDirective() + .name(EXPERIMENTAL_DISABLE_ERROR_PROPAGATION) + .description("This directive disables error propagation when a non nullable field returns null for the given operation.") + .validLocations(QUERY, MUTATION, SUBSCRIPTION) + .definition(EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_DEFINITION) + .build(); + + private static Description createDescription(String s) { + return new Description(s, null, false); + } + + private static final AtomicBoolean EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_ENABLED = new AtomicBoolean(true); + + /** + * This can be used to get the state the `@experimental_disableErrorPropagation` directive support on a JVM wide basis . + * @return true if the `@experimental_disableErrorPropagation` directive will be respected + */ + public static boolean isExperimentalDisableErrorPropagationDirectiveEnabled() { + return EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_ENABLED.get(); + } + + /** + * This can be used to disable the `@experimental_disableErrorPropagation` directive support on a JVM wide basis in case your server + * implementation does NOT want to act on this directive ever. + * + * @param flag the desired state of the flag + */ + public static void setExperimentalDisableErrorPropagationEnabled(boolean flag) { + EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_ENABLED.set(flag); + } } diff --git a/src/main/java/graphql/DirectivesUtil.java b/src/main/java/graphql/DirectivesUtil.java index 39abe7dbed..a618489f85 100644 --- a/src/main/java/graphql/DirectivesUtil.java +++ b/src/main/java/graphql/DirectivesUtil.java @@ -1,26 +1,207 @@ package graphql; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.schema.GraphQLAppliedDirective; import graphql.schema.GraphQLArgument; import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; import graphql.util.FpKit; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static java.util.stream.Collectors.toSet; @Internal public class DirectivesUtil { - public static Map directivesByName(List directiveList) { - return FpKit.getByName(directiveList, GraphQLDirective::getName, FpKit.mergeFirst()); + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static Map nonRepeatableDirectivesByName(List directives) { + // filter the repeatable directives + List singletonDirectives = directives.stream() + .filter(d -> !d.isRepeatable()).collect(Collectors.toList()); + + return FpKit.getByName(singletonDirectives, GraphQLDirective::getName); } - public static Optional directiveWithArg(List directiveList, String directiveName, String argumentName) { - GraphQLDirective directive = directivesByName(directiveList).get(directiveName); + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static Map> allDirectivesByName(List directives) { + + return ImmutableMap.copyOf(FpKit.groupingBy(directives, GraphQLDirective::getName)); + } + + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static Optional directiveWithArg(List directives, String directiveName, String argumentName) { + GraphQLDirective directive = nonRepeatableDirectivesByName(directives).get(directiveName); GraphQLArgument argument = null; if (directive != null) { argument = directive.getArgument(argumentName); } return Optional.ofNullable(argument); } + + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static boolean isAllNonRepeatable(List directives) { + if (directives == null || directives.isEmpty()) { + return false; + } + for (GraphQLDirective graphQLDirective : directives) { + if (graphQLDirective.isRepeatable()) { + return false; + } + } + return true; + } + + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static List add(List targetList, GraphQLDirective newDirective) { + assertNotNull(targetList, "directive list can't be null"); + assertNotNull(newDirective, "directive can't be null"); + targetList.add(newDirective); + return targetList; + } + + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static List addAll(List targetList, List newDirectives) { + assertNotNull(targetList, "directive list can't be null"); + assertNotNull(newDirectives, "directive list can't be null"); + targetList.addAll(newDirectives); + return targetList; + } + + @Deprecated(since = "2022-02-24") // use GraphQLAppliedDirectives eventually + public static GraphQLDirective getFirstDirective(String name, Map> allDirectivesByName) { + List directives = allDirectivesByName.getOrDefault(name, emptyList()); + if (directives.isEmpty()) { + return null; + } + return directives.get(0); + } + + /** + * This can take a collection of legacy directives and turn them applied directives, and combine them with any applied directives. The applied + * directives collection takes precedence. + * + * @param directiveContainer the schema element holding applied directives + * @return a combined list unique by name + */ + public static List toAppliedDirectives(GraphQLDirectiveContainer directiveContainer) { + return toAppliedDirectives(directiveContainer.getAppliedDirectives(), directiveContainer.getDirectives()); + } + + /** + * This can take a collection of legacy directives and turn them applied directives, and combine them with any applied directives. The applied + * directives collection takes precedence. + * + * @param appliedDirectives the applied directives to use + * @param directives the legacy directives to use + * @return a combined list unique by name + */ + public static List toAppliedDirectives(Collection appliedDirectives, Collection directives) { + Set named = appliedDirectives.stream() + .map(GraphQLAppliedDirective::getName).collect(toSet()); + + ImmutableList.Builder list = ImmutableList.builder() + .addAll(appliedDirectives); + // we only put in legacy directives if the list does not already contain them. We need this mechanism + // (and not a map) because of repeated directives + directives.forEach(directive -> { + if (!named.contains(directive.getName())) { + list.add(directive.toAppliedDirective()); + } + }); + return list.build(); + } + + /** + * A holder class that breaks a list of directives into maps to be more easily accessible in using classes + */ + public static class DirectivesHolder { + private static final DirectivesHolder EMPTY_HOLDER = new DirectivesHolder(Collections.emptyList(), Collections.emptyList()); + + private final ImmutableMap> allDirectivesByName; + private final ImmutableMap nonRepeatableDirectivesByName; + private final List allDirectives; + + private final ImmutableMap> allAppliedDirectivesByName; + private final List allAppliedDirectives; + + public DirectivesHolder(Collection allDirectives, Collection allAppliedDirectives) { + this.allDirectives = ImmutableList.copyOf(allDirectives); + this.allDirectivesByName = ImmutableMap.copyOf(FpKit.groupingBy(allDirectives, GraphQLDirective::getName)); + // filter out the repeatable directives + List nonRepeatableDirectives = allDirectives.stream() + .filter(d -> !d.isRepeatable()).collect(Collectors.toList()); + this.nonRepeatableDirectivesByName = ImmutableMap.copyOf(FpKit.getByName(nonRepeatableDirectives, GraphQLDirective::getName)); + + this.allAppliedDirectives = ImmutableList.copyOf(allAppliedDirectives); + this.allAppliedDirectivesByName = ImmutableMap.copyOf(FpKit.groupingBy(allAppliedDirectives, GraphQLAppliedDirective::getName)); + } + + public static DirectivesHolder create(List directives, List appliedDirectives) { + if (directives.isEmpty() && appliedDirectives.isEmpty()) { + return EMPTY_HOLDER; + } + + return new DirectivesHolder(directives, appliedDirectives); + } + + public ImmutableMap> getAllDirectivesByName() { + return allDirectivesByName; + } + + public ImmutableMap getDirectivesByName() { + return nonRepeatableDirectivesByName; + } + + public List getDirectives() { + return allDirectives; + } + + public GraphQLDirective getDirective(String directiveName) { + List directiveList = allDirectivesByName.get(directiveName); + if (directiveList == null || directiveList.isEmpty()) { + return null; + } + return directiveList.get(0); + } + + public List getDirectives(String directiveName) { + return allDirectivesByName.getOrDefault(directiveName, emptyList()); + } + + public ImmutableMap> getAllAppliedDirectivesByName() { + return allAppliedDirectivesByName; + } + + public List getAppliedDirectives() { + return allAppliedDirectives; + } + + public List getAppliedDirectives(String directiveName) { + return allAppliedDirectivesByName.getOrDefault(directiveName, emptyList()); + } + + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + List list = allAppliedDirectivesByName.getOrDefault(directiveName, emptyList()); + return list.isEmpty() ? null : list.get(0); + } + + @Override + public String toString() { + return new StringJoiner(", ", DirectivesHolder.class.getSimpleName() + "[", "]") + .add("allDirectivesByName=" + String.join(",", allDirectivesByName.keySet())) + .add("allAppliedDirectivesByName=" + String.join(",", allAppliedDirectivesByName.keySet())) + .toString(); + } + } } diff --git a/src/main/java/graphql/DuckTyped.java b/src/main/java/graphql/DuckTyped.java new file mode 100644 index 0000000000..83e298b6e1 --- /dev/null +++ b/src/main/java/graphql/DuckTyped.java @@ -0,0 +1,22 @@ +package graphql; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; + +/** + * An annotation that marks a method return value or method parameter as returning a duck type value. + *

+ * For efficiency reasons, the graphql engine methods can return {@link Object} values + * which maybe two well known types of values. Often a {@link java.util.concurrent.CompletableFuture} + * or a plain old {@link Object}, to represent an async value or a materialised value. + */ +@Internal +@Retention(RetentionPolicy.RUNTIME) +@Target(value = {METHOD, PARAMETER}) +public @interface DuckTyped { + String shape(); +} diff --git a/src/main/java/graphql/EngineRunningState.java b/src/main/java/graphql/EngineRunningState.java new file mode 100644 index 0000000000..df1ee017ba --- /dev/null +++ b/src/main/java/graphql/EngineRunningState.java @@ -0,0 +1,259 @@ +package graphql; + +import graphql.execution.AbortExecutionException; +import graphql.execution.EngineRunningObserver; +import graphql.execution.ExecutionId; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +import static graphql.Assert.assertTrue; +import static graphql.execution.EngineRunningObserver.RunningState.CANCELLED; +import static graphql.execution.EngineRunningObserver.RunningState.NOT_RUNNING; +import static graphql.execution.EngineRunningObserver.RunningState.NOT_RUNNING_FINISH; +import static graphql.execution.EngineRunningObserver.RunningState.RUNNING; +import static graphql.execution.EngineRunningObserver.RunningState.RUNNING_START; + +@Internal +@NullMarked +public class EngineRunningState { + + @Nullable + private final EngineRunningObserver engineRunningObserver; + private volatile ExecutionInput executionInput; + private final GraphQLContext graphQLContext; + + // will be null after updateExecutionInput is called + @Nullable + private volatile ExecutionId executionId; + + // if true the last decrementRunning() call will be ignored + private volatile boolean finished; + + private final AtomicInteger isRunning = new AtomicInteger(0); + + + public EngineRunningState(ExecutionInput executionInput, Profiler profiler) { + EngineRunningObserver engineRunningObserver = executionInput.getGraphQLContext().get(EngineRunningObserver.ENGINE_RUNNING_OBSERVER_KEY); + EngineRunningObserver wrappedObserver = profiler.wrapEngineRunningObserver(engineRunningObserver); + this.engineRunningObserver = wrappedObserver; + this.executionInput = executionInput; + this.graphQLContext = executionInput.getGraphQLContext(); + this.executionId = executionInput.getExecutionId(); + } + + + + public CompletableFuture handle(CompletableFuture src, BiFunction fn) { + if (engineRunningObserver == null) { + return src.handle(fn); + } + src = observeCompletableFutureStart(src); + CompletableFuture result = src.handle((t, throwable) -> { + // because we added an artificial dependent CF on src (in observeCompletableFutureStart) , a throwable is a CompletionException + // that needs to be unwrapped + if (throwable != null) { + throwable = throwable.getCause(); + } + //noinspection DataFlowIssue + return fn.apply(t, throwable); + }); + observerCompletableFutureEnd(src); + return result; + } + + public CompletableFuture whenComplete(CompletableFuture src, BiConsumer fn) { + if (engineRunningObserver == null) { + return src.whenComplete(fn); + } + src = observeCompletableFutureStart(src); + CompletableFuture result = src.whenComplete((t, throwable) -> { + // because we added an artificial dependent CF on src (in observeCompletableFutureStart) , a throwable is a CompletionException + // that needs to be unwrapped + if (throwable != null) { + throwable = throwable.getCause(); + } + fn.accept(t, throwable); + }); + observerCompletableFutureEnd(src); + return result; + } + + public CompletableFuture compose(CompletableFuture src, Function> fn) { + if (engineRunningObserver == null) { + return src.thenCompose(fn); + } + CompletableFuture result = new CompletableFuture<>(); + src = observeCompletableFutureStart(src); + src.whenComplete((u, t) -> { + CompletionStage innerCF; + try { + innerCF = fn.apply(u).toCompletableFuture(); + } catch (Throwable e) { + innerCF = CompletableFuture.failedFuture(e); + } + // this run is needed to wrap around the result.complete()/result.completeExceptionally() call + innerCF.whenComplete((u1, t1) -> run(() -> { + if (t1 != null) { + result.completeExceptionally(t1); + } else { + result.complete(u1); + } + })); + }); + observerCompletableFutureEnd(src); + return result; + } + + + private CompletableFuture observeCompletableFutureStart(CompletableFuture future) { + if (engineRunningObserver == null) { + return future; + } + // the completion order of dependent CFs is in stack order for + // directly dependent CFs, but in reverse stack order for indirect dependent ones + // By creating one dependent CF on originalFetchValue, we make sure the order it is always + // in reverse stack order + future = future.thenApply(Function.identity()); + incrementRunningWhenCompleted(future); + return future; + } + + private void observerCompletableFutureEnd(CompletableFuture future) { + if (engineRunningObserver == null) { + return; + } + decrementRunningWhenCompleted(future); + } + + + private void incrementRunningWhenCompleted(CompletableFuture cf) { + cf.whenComplete((result, throwable) -> { + incrementRunning(); + }); + } + + private void decrementRunningWhenCompleted(CompletableFuture cf) { + cf.whenComplete((result, throwable) -> { + decrementRunning(); + }); + + } + + private void decrementRunning() { + if (engineRunningObserver == null) { + return; + } + assertTrue(isRunning.get() > 0); + if (isRunning.decrementAndGet() == 0 && !finished) { + changeOfState(NOT_RUNNING); + } + } + + + private void incrementRunning() { + if (engineRunningObserver == null) { + return; + } + assertTrue(isRunning.get() >= 0); + if (isRunning.incrementAndGet() == 1) { + changeOfState(RUNNING); + } + + } + + + public void updateExecutionInput(ExecutionInput executionInput) { + this.executionInput = executionInput; + this.executionId = executionInput.getExecutionIdNonNull(); + } + + private void changeOfState(EngineRunningObserver.RunningState runningState) { + if (engineRunningObserver != null) { + engineRunningObserver.runningStateChanged(executionId, graphQLContext, runningState); + } + } + + private void run(Runnable runnable) { + if (engineRunningObserver == null) { + runnable.run(); + return; + } + incrementRunning(); + try { + runnable.run(); + } finally { + decrementRunning(); + } + } + + /** + * Only used once outside of this class: when the execution starts + */ + public CompletableFuture engineRun(Supplier> engineRun) { + if (engineRunningObserver == null) { + return engineRun.get(); + } + isRunning.incrementAndGet(); + changeOfState(RUNNING_START); + + CompletableFuture erCF = engineRun.get(); + erCF = erCF.whenComplete((result, throwable) -> { + finished = true; + changeOfState(NOT_RUNNING_FINISH); + }); + decrementRunning(); + return erCF; + } + + + /** + * This will abort the execution via throwing {@link AbortExecutionException} if the {@link ExecutionInput} has been cancelled + */ + public void throwIfCancelled() throws AbortExecutionException { + AbortExecutionException abortExecutionException = ifCancelledMakeException(); + if (abortExecutionException != null) { + throw abortExecutionException; + } + } + + /** + * if the passed in {@link Throwable}is non-null then it is returned as id and if there is no exception then + * the cancellation state is checked in {@link ExecutionInput#isCancelled()} and a {@link AbortExecutionException} + * is made as the returned {@link Throwable} + * + * @param currentThrowable the current exception state + * + * @return a current throwable or a cancellation exception or null if none are in error + */ + @Internal + @Nullable + public Throwable possibleCancellation(@Nullable Throwable currentThrowable) { + // no need to check we are cancelled if we already have an exception in play + // since it can lead to an exception being thrown when an exception has already been + // thrown + if (currentThrowable == null) { + return ifCancelledMakeException(); + } + return currentThrowable; + } + + /** + * @return a AbortExecutionException if the current operation has been cancelled via {@link ExecutionInput#cancel()} + */ + public @Nullable AbortExecutionException ifCancelledMakeException() { + if (executionInput.isCancelled()) { + changeOfState(CANCELLED); + return new AbortExecutionException("Execution has been asked to be cancelled"); + } + return null; + } + +} diff --git a/src/main/java/graphql/ErrorClassification.java b/src/main/java/graphql/ErrorClassification.java new file mode 100644 index 0000000000..db9764f2ce --- /dev/null +++ b/src/main/java/graphql/ErrorClassification.java @@ -0,0 +1,43 @@ +package graphql; + +/** + * Errors in graphql-java can have a classification to help with the processing + * of errors. Custom {@link graphql.GraphQLError} implementations could use + * custom classifications. + *

+ * graphql-java ships with a standard set of error classifications via {@link graphql.ErrorType} + */ +@PublicApi +public interface ErrorClassification { + + /** + * This is called to create a representation of the error classification + * that can be put into the `extensions` map of the graphql error under the key 'classification' + * when {@link GraphQLError#toSpecification()} is called + * + * @param error the error associated with this classification + * + * @return an object representation of this error classification + */ + @SuppressWarnings("unused") + default Object toSpecification(GraphQLError error) { + return String.valueOf(this); + } + + /** + * This produces a simple ErrorClassification that represents the provided String. You can + * use this factory method to give out simple but custom error classifications. + * + * @param errorClassification the string that represents the error classification + * + * @return a ErrorClassification that is that provided string + */ + static ErrorClassification errorClassification(String errorClassification) { + return new ErrorClassification() { + @Override + public String toString() { + return errorClassification; + } + }; + } +} diff --git a/src/main/java/graphql/ErrorType.java b/src/main/java/graphql/ErrorType.java index cb45424a2c..9adee6d461 100644 --- a/src/main/java/graphql/ErrorType.java +++ b/src/main/java/graphql/ErrorType.java @@ -5,10 +5,11 @@ * All the errors in graphql belong to one of these categories */ @PublicApi -public enum ErrorType { +public enum ErrorType implements ErrorClassification { InvalidSyntax, ValidationError, DataFetchingException, + NullValueInNonNullableField, OperationNotSupported, ExecutionAborted } diff --git a/src/main/java/graphql/ExceptionWhileDataFetching.java b/src/main/java/graphql/ExceptionWhileDataFetching.java index c9a3d09500..73413f55e0 100644 --- a/src/main/java/graphql/ExceptionWhileDataFetching.java +++ b/src/main/java/graphql/ExceptionWhileDataFetching.java @@ -1,7 +1,7 @@ package graphql; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import graphql.language.SourceLocation; import java.util.Collections; @@ -24,7 +24,7 @@ public class ExceptionWhileDataFetching implements GraphQLError { private final List locations; private final Map extensions; - public ExceptionWhileDataFetching(ExecutionPath path, Throwable exception, SourceLocation sourceLocation) { + public ExceptionWhileDataFetching(ResultPath path, Throwable exception, SourceLocation sourceLocation) { this.path = assertNotNull(path).toList(); this.exception = assertNotNull(exception); this.locations = Collections.singletonList(sourceLocation); @@ -32,7 +32,7 @@ public ExceptionWhileDataFetching(ExecutionPath path, Throwable exception, Sourc this.message = mkMessage(path, exception); } - private String mkMessage(ExecutionPath path, Throwable exception) { + private String mkMessage(ResultPath path, Throwable exception) { return format("Exception while fetching data (%s) : %s", path, exception.getMessage()); } @@ -46,8 +46,7 @@ private Map mkExtensions(Throwable exception) { if (exception instanceof GraphQLError) { Map map = ((GraphQLError) exception).getExtensions(); if (map != null) { - extensions = new LinkedHashMap<>(); - extensions.putAll(map); + extensions = new LinkedHashMap<>(map); } } return extensions; @@ -87,8 +86,8 @@ public ErrorType getErrorType() { public String toString() { return "ExceptionWhileDataFetching{" + "path=" + path + - "exception=" + exception + - "locations=" + locations + + ", exception=" + exception + + ", locations=" + locations + '}'; } diff --git a/src/main/java/graphql/ExecutionInput.java b/src/main/java/graphql/ExecutionInput.java index 570cc6931f..669ff4ff1d 100644 --- a/src/main/java/graphql/ExecutionInput.java +++ b/src/main/java/graphql/ExecutionInput.java @@ -1,27 +1,91 @@ package graphql; -import java.util.Collections; +import graphql.collect.ImmutableKit; +import graphql.execution.ExecutionId; +import graphql.execution.RawVariables; +import graphql.execution.preparsed.persisted.PersistedQuerySupport; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; + +import java.util.Locale; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.execution.instrumentation.dataloader.EmptyDataLoaderRegistryInstance.EMPTY_DATALOADER_REGISTRY; + /** * This represents the series of values that can be input on a graphql query execution */ @PublicApi +@NullMarked public class ExecutionInput { private final String query; private final String operationName; private final Object context; + private final GraphQLContext graphQLContext; + private final Object localContext; private final Object root; - private final Map variables; + private final RawVariables rawVariables; + private final Map extensions; + private final DataLoaderRegistry dataLoaderRegistry; + private final ExecutionId executionId; + private final Locale locale; + private final AtomicBoolean cancelled; + private final boolean profileExecution; + + /** + * In order for {@link #getQuery()} to never be null, use this to mark + * them so that invariant can be satisfied while assuming that the persisted query + * id is elsewhere. + */ + public final static String PERSISTED_QUERY_MARKER = PersistedQuerySupport.PERSISTED_QUERY_MARKER; + + private final static String APOLLO_AUTOMATIC_PERSISTED_QUERY_EXTENSION = "persistedQuery"; + + @Internal + private ExecutionInput(Builder builder) { + this.query = assertQuery(builder); + this.operationName = builder.operationName; + this.context = builder.context; + this.graphQLContext = assertNotNull(builder.graphQLContext); + this.root = builder.root; + this.rawVariables = builder.rawVariables; + this.dataLoaderRegistry = builder.dataLoaderRegistry; + this.executionId = builder.executionId; + this.locale = builder.locale != null ? builder.locale : Locale.getDefault(); // always have a locale in place + this.localContext = builder.localContext; + this.extensions = builder.extensions; + this.cancelled = builder.cancelled; + this.profileExecution = builder.profileExecution; + } + + private static String assertQuery(Builder builder) { + if ((builder.query == null || builder.query.isEmpty()) && isPersistedQuery(builder)) { + return PERSISTED_QUERY_MARKER; + } - public ExecutionInput(String query, String operationName, Object context, Object root, Map variables) { - this.query = query; - this.operationName = operationName; - this.context = context; - this.root = root; - this.variables = variables; + return assertNotNull(builder.query, "query can't be null"); + } + + /** + * This is used to determine if this execution input is a persisted query or not. + * + * @implNote The current implementation supports Apollo Persisted Queries (APQ) by checking for + * the extensions property for the persisted query extension. + * See Apollo Persisted Queries for more details. + * + * @param builder the builder to check + * + * @return true if this is a persisted query + */ + private static boolean isPersistedQuery(Builder builder) { + return builder.extensions != null && + builder.extensions.containsKey(APOLLO_AUTOMATIC_PERSISTED_QUERY_EXTENSION); } /** @@ -34,29 +98,133 @@ public String getQuery() { /** * @return the name of the query operation */ + @Nullable public String getOperationName() { return operationName; } /** + * The legacy context object has been deprecated in favour of the more shareable + * {@link #getGraphQLContext()} + * * @return the context object to pass to all data fetchers + * + * @deprecated - use {@link #getGraphQLContext()} */ + @Deprecated(since = "2021-07-05") + @Nullable public Object getContext() { return context; } + /** + * @return the shared {@link GraphQLContext} object to pass to all data fetchers + */ + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + /** + * @return the local context object to pass to all top level (i.e. query, mutation, subscription) data fetchers + */ + @Nullable + public Object getLocalContext() { + return localContext; + } + /** * @return the root object to start the query execution on */ + @Nullable public Object getRoot() { return root; } /** - * @return a map of variables that can be referenced via $syntax in the query + * @return a map of raw variables that can be referenced via $syntax in the query. */ public Map getVariables() { - return variables; + return rawVariables.toMap(); + } + + /** + * @return a map of raw variables that can be referenced via $syntax in the query. + */ + public RawVariables getRawVariables() { + return rawVariables; + } + + /** + * @return the data loader registry associated with this execution + */ + public DataLoaderRegistry getDataLoaderRegistry() { + return dataLoaderRegistry; + } + + + /** + * This value can be null before the execution starts, but once the execution starts, it will be set to a non-null value. + * See #getExecutionIdNonNull() for a non-null version of this. + * + * @return Id that will be/was used to execute this operation. + */ + @Nullable + public ExecutionId getExecutionId() { + return executionId; + } + + + /** + * Once the execution starts, GraphQL Java will make sure that this execution id is non-null. + * Therefore use this method if you are sue that the execution has started to get a guaranteed non-null execution id. + * + * @return the non null execution id of this operation. + */ + public ExecutionId getExecutionIdNonNull() { + return Assert.assertNotNull(this.executionId); + } + + /** + * This returns the locale of this operation. + * + * @return the locale of this operation + */ + public Locale getLocale() { + return locale; + } + + /** + * @return a map of extension values that can be sent in to a request + */ + public Map getExtensions() { + return extensions; + } + + + /** + * The graphql engine will check this frequently and if that is true, it will + * throw a {@link graphql.execution.AbortExecutionException} to cancel the execution. + *

+ * This is a cooperative cancellation. Some asynchronous data fetching code may still continue to + * run but there will be no more efforts run future field fetches say. + * + * @return true if the execution should be cancelled + */ + public boolean isCancelled() { + return cancelled.get(); + } + + /** + * This can be called to cancel the graphql execution. Remember this is a cooperative cancellation + * and the graphql engine needs to be running on a thread to allow is to respect this flag. + */ + public void cancel() { + cancelled.set(true); + } + + + public boolean isProfileExecution() { + return profileExecution; } /** @@ -72,23 +240,33 @@ public ExecutionInput transform(Consumer builderConsumer) { .query(this.query) .operationName(this.operationName) .context(this.context) + .internalTransferContext(this.graphQLContext) + .internalTransferCancelBoolean(this.cancelled) + .localContext(this.localContext) .root(this.root) - .variables(this.variables); + .dataLoaderRegistry(this.dataLoaderRegistry) + .variables(this.rawVariables.toMap()) + .extensions(this.extensions) + .executionId(this.executionId) + .locale(this.locale); builderConsumer.accept(builder); return builder.build(); } - @Override public String toString() { return "ExecutionInput{" + "query='" + query + '\'' + ", operationName='" + operationName + '\'' + ", context=" + context + + ", graphQLContext=" + graphQLContext + ", root=" + root + - ", variables=" + variables + + ", rawVariables=" + rawVariables + + ", dataLoaderRegistry=" + dataLoaderRegistry + + ", executionId= " + executionId + + ", locale= " + locale + '}'; } @@ -99,13 +277,46 @@ public static Builder newExecutionInput() { return new Builder(); } + /** + * Creates a new builder of ExecutionInput objects with the given query + * + * @param query the query to execute + * + * @return a new builder of ExecutionInput objects + */ + public static Builder newExecutionInput(String query) { + return new Builder().query(query); + } + + @NullUnmarked public static class Builder { private String query; private String operationName; - private Object context; + private GraphQLContext graphQLContext = GraphQLContext.newContext().build(); + private Object context = graphQLContext; // we make these the same object on purpose - legacy code will get the same object if this change nothing + private Object localContext; private Object root; - private Map variables = Collections.emptyMap(); + private RawVariables rawVariables = RawVariables.emptyVariables(); + private Map extensions = ImmutableKit.emptyMap(); + // + // this is important - it allows code to later known if we never really set a dataloader and hence it can optimize + // dataloader field tracking away. + // + private DataLoaderRegistry dataLoaderRegistry = EMPTY_DATALOADER_REGISTRY; + private Locale locale = Locale.getDefault(); + private ExecutionId executionId; + private AtomicBoolean cancelled = new AtomicBoolean(false); + private boolean profileExecution; + + /** + * Package level access to the graphql context + * + * @return shhh but it's the graphql context + */ + GraphQLContext graphQLContext() { + return graphQLContext; + } public Builder query(String query) { this.query = query; @@ -117,23 +328,141 @@ public Builder operationName(String operationName) { return this; } + /** + * A default one will be assigned, but you can set your own. + * + * @param executionId an execution id object + * + * @return this builder + */ + public Builder executionId(ExecutionId executionId) { + this.executionId = executionId; + return this; + } + + /** + * Sets the locale to use for this operation + * + * @param locale the locale to use + * + * @return this builder + */ + public Builder locale(Locale locale) { + this.locale = locale; + return this; + } + + /** + * Sets initial localContext in root data fetchers + * + * @param localContext the local context to use + * + * @return this builder + */ + public Builder localContext(Object localContext) { + this.localContext = localContext; + return this; + } + + /** + * The legacy context object + * + * @param context the context object to use + * + * @return this builder + * + * @deprecated - the {@link ExecutionInput#getGraphQLContext()} is a fixed mutable instance now + */ + @Deprecated(since = "2021-07-05") public Builder context(Object context) { this.context = context; return this; } + /** + * This will give you a builder of {@link GraphQLContext} and any values you set will be copied + * into the underlying {@link GraphQLContext} of this execution input + * + * @param builderFunction a builder function you can use to put values into the context + * + * @return this builder + */ + public Builder graphQLContext(Consumer builderFunction) { + GraphQLContext.Builder builder = GraphQLContext.newContext(); + builderFunction.accept(builder); + this.graphQLContext.putAll(builder); + return this; + } + + /** + * This will put all the values from the map into the underlying {@link GraphQLContext} of this execution input + * + * @param mapOfContext a map of values to put in the context + * + * @return this builder + */ + public Builder graphQLContext(Map mapOfContext) { + this.graphQLContext.putAll(mapOfContext); + return this; + } + + // hidden on purpose + private Builder internalTransferContext(GraphQLContext graphQLContext) { + this.graphQLContext = Assert.assertNotNull(graphQLContext); + return this; + } + + // hidden on purpose + private Builder internalTransferCancelBoolean(AtomicBoolean cancelled) { + this.cancelled = cancelled; + return this; + } + + public Builder root(Object root) { this.root = root; return this; } - public Builder variables(Map variables) { - this.variables = variables; + /** + * Adds raw (not coerced) variables + * + * @param rawVariables the map of raw variables + * + * @return this builder + */ + public Builder variables(Map rawVariables) { + assertNotNull(rawVariables, "variables map can't be null"); + this.rawVariables = RawVariables.of(rawVariables); + return this; + } + + public Builder extensions(Map extensions) { + this.extensions = assertNotNull(extensions, "extensions map can't be null"); + return this; + } + + /** + * You should create new {@link org.dataloader.DataLoaderRegistry}s and new {@link org.dataloader.DataLoader}s for each execution. Do not + * re-use + * instances as this will create unexpected results. + * + * @param dataLoaderRegistry a registry of {@link org.dataloader.DataLoader}s + * + * @return this builder + */ + public Builder dataLoaderRegistry(DataLoaderRegistry dataLoaderRegistry) { + this.dataLoaderRegistry = assertNotNull(dataLoaderRegistry); + return this; + } + + public Builder profileExecution(boolean profileExecution) { + this.profileExecution = profileExecution; return this; } public ExecutionInput build() { - return new ExecutionInput(query, operationName, context, root, variables); + return new ExecutionInput(this); } } -} +} \ No newline at end of file diff --git a/src/main/java/graphql/ExecutionResult.java b/src/main/java/graphql/ExecutionResult.java index 308a954158..f2e94765bb 100644 --- a/src/main/java/graphql/ExecutionResult.java +++ b/src/main/java/graphql/ExecutionResult.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Map; +import java.util.function.Consumer; /** * This simple value class represents the result of performing a graphql query. @@ -11,6 +12,11 @@ @SuppressWarnings("TypeParameterUnusedInFormals") public interface ExecutionResult { + /** + * @return the errors that occurred during execution or empty list if there is none + */ + List getErrors(); + /** * @param allows type coercion * @@ -19,9 +25,19 @@ public interface ExecutionResult { T getData(); /** - * @return the errors that occurred during execution or empty list if there is none + * The graphql specification specifies: + * + * "If an error was encountered before execution begins, the data entry should not be present in the result. + * If an error was encountered during the execution that prevented a valid response, the data entry in the response should be null." + * + * This allows to distinguish between the cases where {@link #getData()} returns null. + * + * See : https://graphql.github.io/graphql-spec/June2018/#sec-Data + * + * @return true if the entry "data" should be present in the result + * false otherwise */ - List getErrors(); + boolean isDataPresent(); /** * @return a map of extensions or null if there are none @@ -34,9 +50,113 @@ public interface ExecutionResult { * should be present. Certain JSON serializers may or may interpret {@link ExecutionResult} to spec, so this method * is provided to produce a map that strictly follows the specification. * - * See : http://facebook.github.io/graphql/#sec-Response-Format + * See : https://spec.graphql.org/October2021/#sec-Response-Format * * @return a map of the result that strictly follows the spec */ Map toSpecification(); + + /** + * This allows you to turn a map of results from {@link #toSpecification()} and turn it back into a {@link ExecutionResult} + * + * @param specificationMap the specification result map + * + * @return a new {@link ExecutionResult} from that map + */ + static ExecutionResult fromSpecification(Map specificationMap) { + return ExecutionResultImpl.fromSpecification(specificationMap); + } + + /** + * This helps you transform the current {@link ExecutionResult} object into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new {@link ExecutionResult} object based on calling build on that builder + */ + default ExecutionResult transform(Consumer> builderConsumer) { + Builder builder = newExecutionResult().from(this); + builderConsumer.accept(builder); + return builder.build(); + } + + /** + * @return a builder that allows you to build a new execution result + */ + static Builder newExecutionResult() { + return ExecutionResultImpl.newExecutionResult(); + } + + interface Builder> { + + /** + * Sets values into the builder based on a previous {@link ExecutionResult} + * + * @param executionResult the previous {@link ExecutionResult} + * + * @return the builder + */ + B from(ExecutionResult executionResult); + + /** + * Sets new data into the builder + * + * @param data the data to use + * + * @return the builder + */ + B data(Object data); + + /** + * Sets error list as the errors for this builder + * + * @param errors the errors to use + * + * @return the builder + */ + B errors(List errors); + + /** + * Adds the error list to any existing the errors for this builder + * + * @param errors the errors to add + * + * @return the builder + */ + B addErrors(List errors); + + /** + * Adds the error to any existing the errors for this builder + * + * @param error the error to add + * + * @return the builder + */ + B addError(GraphQLError error); + + /** + * Sets the extension map for this builder + * + * @param extensions the extensions to use + * + * @return the builder + */ + B extensions(Map extensions); + + /** + * Adds a new entry into the extensions map for this builder + * + * @param key the key of the extension entry + * @param value the value of the extension entry + * + * @return the builder + */ + B addExtension(String key, Object value); + + /** + * @return a newly built {@link ExecutionResult} + */ + ExecutionResult build(); + } } diff --git a/src/main/java/graphql/ExecutionResultImpl.java b/src/main/java/graphql/ExecutionResultImpl.java index 3ade47ad0a..d39dbda157 100644 --- a/src/main/java/graphql/ExecutionResultImpl.java +++ b/src/main/java/graphql/ExecutionResultImpl.java @@ -1,22 +1,24 @@ package graphql; +import com.google.common.collect.ImmutableList; +import graphql.collect.ImmutableKit; + import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.function.Consumer; -import static java.util.stream.Collectors.toList; +import static graphql.collect.ImmutableKit.map; @Internal public class ExecutionResultImpl implements ExecutionResult { - private final Object data; private final List errors; - private final transient boolean dataPresent; + private final Object data; private final transient Map extensions; + private final transient boolean dataPresent; public ExecutionResultImpl(GraphQLError error) { this(false, null, Collections.singletonList(error), null); @@ -34,14 +36,22 @@ public ExecutionResultImpl(Object data, List errors, Map this(true, data, errors, extensions); } + public ExecutionResultImpl(ExecutionResultImpl other) { + this(other.dataPresent, other.data, other.errors, other.extensions); + } + + public > ExecutionResultImpl(Builder builder) { + this(builder.dataPresent, builder.data, builder.errors, builder.extensions); + } + private ExecutionResultImpl(boolean dataPresent, Object data, List errors, Map extensions) { this.dataPresent = dataPresent; this.data = data; - if (errors != null && !errors.isEmpty()) { - this.errors = Collections.unmodifiableList(new ArrayList<>(errors)); + if (errors != null) { + this.errors = ImmutableList.copyOf(errors); } else { - this.errors = Collections.emptyList(); + this.errors = ImmutableKit.emptyList(); } this.extensions = extensions; @@ -51,6 +61,11 @@ public boolean isDataPresent() { return dataPresent; } + @Override + public List getErrors() { + return errors; + } + @Override @SuppressWarnings("TypeParameterUnusedInFormals") public T getData() { @@ -58,11 +73,6 @@ public T getData() { return (T) data; } - @Override - public List getErrors() { - return errors; - } - @Override public Map getExtensions() { return extensions; @@ -71,12 +81,12 @@ public Map getExtensions() { @Override public Map toSpecification() { Map result = new LinkedHashMap<>(); - if (dataPresent) { - result.put("data", data); - } if (errors != null && !errors.isEmpty()) { result.put("errors", errorsToSpec(errors)); } + if (dataPresent) { + result.put("data", data); + } if (extensions != null) { result.put("extensions", extensions); } @@ -84,76 +94,96 @@ public Map toSpecification() { } private Object errorsToSpec(List errors) { - return errors.stream().map(GraphQLError::toSpecification).collect(toList()); + return map(errors, GraphQLError::toSpecification); + } + + @SuppressWarnings("unchecked") + static ExecutionResult fromSpecification(Map specificationMap) { + ExecutionResult.Builder builder = ExecutionResult.newExecutionResult(); + Object data = specificationMap.get("data"); + if (data != null) { + builder.data(data); + } + List> errors = (List>) specificationMap.get("errors"); + if (errors != null) { + builder.errors(GraphqlErrorHelper.fromSpecification(errors)); + } + Map extensions = (Map) specificationMap.get("extensions"); + if (extensions != null) { + builder.extensions(extensions); + } + return builder.build(); } @Override public String toString() { return "ExecutionResultImpl{" + - "data=" + data + - ", errors=" + errors + + "errors=" + errors + + ", data=" + data + ", dataPresent=" + dataPresent + ", extensions=" + extensions + '}'; } - public ExecutionResultImpl transform(Consumer builderConsumer) { - Builder builder = newExecutionResult().from(this); - builderConsumer.accept(builder); - return builder.build(); - } - - public static Builder newExecutionResult() { - return new Builder(); + public static > Builder newExecutionResult() { + return new Builder<>(); } - public static class Builder { + public static class Builder> implements ExecutionResult.Builder { private boolean dataPresent; private Object data; private List errors = new ArrayList<>(); private Map extensions; - public Builder from(ExecutionResultImpl executionResult) { + @Override + public T from(ExecutionResult executionResult) { dataPresent = executionResult.isDataPresent(); data = executionResult.getData(); errors = new ArrayList<>(executionResult.getErrors()); extensions = executionResult.getExtensions(); - return this; + return (T) this; } - public Builder data(Object data) { + @Override + public T data(Object data) { dataPresent = true; this.data = data; - return this; + return (T) this; } - public Builder errors(List errors) { + @Override + public T errors(List errors) { this.errors = errors; - return this; + return (T) this; } - public Builder addErrors(List errors) { + @Override + public T addErrors(List errors) { this.errors.addAll(errors); - return this; + return (T) this; } - public Builder addError(GraphQLError error) { + @Override + public T addError(GraphQLError error) { this.errors.add(error); - return this; + return (T) this; } - public Builder extensions(Map extensions) { + @Override + public T extensions(Map extensions) { this.extensions = extensions; - return this; + return (T) this; } - public Builder addExtension(String key, Object value) { + @Override + public T addExtension(String key, Object value) { this.extensions = (this.extensions == null ? new LinkedHashMap<>() : this.extensions); this.extensions.put(key, value); - return this; + return (T) this; } - public ExecutionResultImpl build() { + @Override + public ExecutionResult build() { return new ExecutionResultImpl(dataPresent, data, errors, extensions); } } diff --git a/src/main/java/graphql/ExperimentalApi.java b/src/main/java/graphql/ExperimentalApi.java index 9f07b7f897..80be253cd1 100644 --- a/src/main/java/graphql/ExperimentalApi.java +++ b/src/main/java/graphql/ExperimentalApi.java @@ -11,14 +11,17 @@ import static java.lang.annotation.ElementType.TYPE; /** - * This represents code that the graphql-java project considers experimental API and may not be stable between - * releases. - * - * In general unnecessary changes will be avoided and the code is aiming to be public one day but you should be aware that things - * might change. + * This represents code that the graphql-java project considers experimental API and while our intention is that it will + * progress to be {@link PublicApi}, its existence, signature or behavior may change between releases. + *

+ * In general unnecessary changes will be avoided, but you should not depend on experimental classes being stable. */ @Retention(RetentionPolicy.RUNTIME) @Target(value = {CONSTRUCTOR, METHOD, TYPE, FIELD}) @Documented public @interface ExperimentalApi { + /** + * The key that should be associated with a boolean value which indicates whether @defer and @stream behaviour is enabled for this execution. + */ + String ENABLE_INCREMENTAL_SUPPORT = "ENABLE_INCREMENTAL_SUPPORT"; } diff --git a/src/main/java/graphql/GraphQL.java b/src/main/java/graphql/GraphQL.java index 5388c21419..5c0bd83494 100644 --- a/src/main/java/graphql/GraphQL.java +++ b/src/main/java/graphql/GraphQL.java @@ -1,55 +1,62 @@ package graphql; import graphql.execution.AbortExecutionException; +import graphql.execution.Async; import graphql.execution.AsyncExecutionStrategy; import graphql.execution.AsyncSerialExecutionStrategy; +import graphql.execution.DataFetcherExceptionHandler; import graphql.execution.Execution; import graphql.execution.ExecutionId; import graphql.execution.ExecutionIdProvider; import graphql.execution.ExecutionStrategy; +import graphql.execution.SimpleDataFetcherExceptionHandler; import graphql.execution.SubscriptionExecutionStrategy; +import graphql.execution.ValueUnboxer; +import graphql.execution.instrumentation.DocumentAndVariables; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationContext; import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.SimpleInstrumentation; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; import graphql.execution.preparsed.NoOpPreparsedDocumentProvider; import graphql.execution.preparsed.PreparsedDocumentEntry; import graphql.execution.preparsed.PreparsedDocumentProvider; import graphql.language.Document; -import graphql.parser.Parser; import graphql.schema.GraphQLSchema; import graphql.validation.ValidationError; -import graphql.validation.Validator; -import org.antlr.v4.runtime.misc.ParseCancellationException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import java.util.List; -import java.util.Map; +import java.util.Locale; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.function.UnaryOperator; import static graphql.Assert.assertNotNull; -import static graphql.InvalidSyntaxError.toInvalidSyntaxError; +import static graphql.execution.ExecutionIdProvider.DEFAULT_EXECUTION_ID_PROVIDER; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.completeInstrumentationCtxCF; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.nonNullCtx; /** * This class is where all graphql-java query execution begins. It combines the objects that are needed * to make a successful graphql query, with the most important being the {@link graphql.schema.GraphQLSchema schema} * and the {@link graphql.execution.ExecutionStrategy execution strategy} - * + *

* Building this object is very cheap and can be done on each execution if necessary. Building the schema is often not - * as cheap, especially if its parsed from graphql IDL schema format via {@link graphql.schema.idl.SchemaParser}. - * + * as cheap, especially if it's parsed from graphql IDL schema format via {@link graphql.schema.idl.SchemaParser}. + *

* The data for a query is returned via {@link ExecutionResult#getData()} and any errors encountered as placed in * {@link ExecutionResult#getErrors()}. * *

Runtime Exceptions

- * + *

* Runtime exceptions can be thrown by the graphql engine if certain situations are encountered. These are not errors * in execution but rather totally unacceptable conditions in which to execute a graphql query. *

    @@ -58,7 +65,7 @@ * * *
  • {@link graphql.execution.UnresolvedTypeException} - is thrown if a {@link graphql.schema.TypeResolver} fails to provide a concrete - * object type given a interface or union type. + * object type given an interface or union type. *
  • * *
  • {@link graphql.schema.validation.InvalidSchemaException} - is thrown if the schema is not valid when built via @@ -74,18 +81,76 @@ * *
*/ +@SuppressWarnings("Duplicates") @PublicApi +@NullMarked public class GraphQL { /** - * When @defer directives are used, this is the extension key name used to contain the {@link org.reactivestreams.Publisher} - * of deferred results + * This allows you to control "unusual" aspects of the GraphQL system + * including some JVM wide settings + *

+ * This is named unusual because in general we don't expect you to + * have to make ths configuration by default, but you can opt into certain features + * or disable them if you want to. + * + * @return a {@link GraphQLUnusualConfiguration} object */ - public static final String DEFERRED_RESULTS = "deferredResults"; + public static GraphQLUnusualConfiguration unusualConfiguration() { + return new GraphQLUnusualConfiguration(); + } - private static final Logger log = LoggerFactory.getLogger(GraphQL.class); + /** + * This allows you to control "unusual" per execution aspects of the GraphQL system + *

+ * This is named unusual because in general we don't expect you to + * have to make ths configuration by default, but you can opt into certain features + * or disable them if you want to. + * + * @return a {@link GraphQLUnusualConfiguration.GraphQLContextConfiguration} object + */ + public static GraphQLUnusualConfiguration.GraphQLContextConfiguration unusualConfiguration(ExecutionInput executionInput) { + return new GraphQLUnusualConfiguration.GraphQLContextConfiguration(executionInput.getGraphQLContext()); + } - private static final ExecutionIdProvider DEFAULT_EXECUTION_ID_PROVIDER = (query, operationName, context) -> ExecutionId.generate(); + /** + * This allows you to control "unusual" per execution aspects of the GraphQL system + *

+ * This is named unusual because in general we don't expect you to + * have to make ths configuration by default, but you can opt into certain features + * or disable them if you want to. + * + * @return a {@link GraphQLUnusualConfiguration.GraphQLContextConfiguration} object + */ + public static GraphQLUnusualConfiguration.GraphQLContextConfiguration unusualConfiguration(ExecutionInput.Builder executionInputBuilder) { + return new GraphQLUnusualConfiguration.GraphQLContextConfiguration(executionInputBuilder.graphQLContext()); + } + + /** + * This allows you to control "unusual" per execution aspects of the GraphQL system + *

+ * This is named unusual because in general we don't expect you to + * have to make ths configuration by default, but you can opt into certain features + * or disable them if you want to. + * + * @return a {@link GraphQLUnusualConfiguration.GraphQLContextConfiguration} object + */ + public static GraphQLUnusualConfiguration.GraphQLContextConfiguration unusualConfiguration(GraphQLContext graphQLContext) { + return new GraphQLUnusualConfiguration.GraphQLContextConfiguration(graphQLContext); + } + + /** + * This allows you to control "unusual" per execution aspects of the GraphQL system + *

+ * This is named unusual because in general we don't expect you to + * have to make ths configuration by default, but you can opt into certain features + * or disable them if you want to. + * + * @return a {@link GraphQLUnusualConfiguration.GraphQLContextConfiguration} object + */ + public static GraphQLUnusualConfiguration.GraphQLContextConfiguration unusualConfiguration(GraphQLContext.Builder graphQLContextBuilder) { + return new GraphQLUnusualConfiguration.GraphQLContextConfiguration(graphQLContextBuilder); + } private final GraphQLSchema graphQLSchema; private final ExecutionStrategy queryStrategy; @@ -94,72 +159,80 @@ public class GraphQL { private final ExecutionIdProvider idProvider; private final Instrumentation instrumentation; private final PreparsedDocumentProvider preparsedDocumentProvider; + private final ValueUnboxer valueUnboxer; + private final boolean doNotAutomaticallyDispatchDataLoader; + + + private GraphQL(Builder builder) { + this.graphQLSchema = assertNotNull(builder.graphQLSchema, "graphQLSchema must be non null"); + this.queryStrategy = assertNotNull(builder.queryExecutionStrategy, "queryStrategy must not be null"); + this.mutationStrategy = assertNotNull(builder.mutationExecutionStrategy, "mutationStrategy must not be null"); + this.subscriptionStrategy = assertNotNull(builder.subscriptionExecutionStrategy, "subscriptionStrategy must not be null"); + this.idProvider = assertNotNull(builder.idProvider, "idProvider must be non null"); + this.instrumentation = assertNotNull(builder.instrumentation, "instrumentation must not be null"); + this.preparsedDocumentProvider = assertNotNull(builder.preparsedDocumentProvider, "preparsedDocumentProvider must be non null"); + this.valueUnboxer = assertNotNull(builder.valueUnboxer, "valueUnboxer must not be null"); + this.doNotAutomaticallyDispatchDataLoader = builder.doNotAutomaticallyDispatchDataLoader; + } + /** + * @return the schema backing this {@link GraphQL} instance + */ + public GraphQLSchema getGraphQLSchema() { + return graphQLSchema; + } /** - * A GraphQL object ready to execute queries - * - * @param graphQLSchema the schema to use - * - * @deprecated use the {@link #newGraphQL(GraphQLSchema)} builder instead. This will be removed in a future version. + * @return the execution strategy used for queries in this {@link GraphQL} instance */ - @Internal - public GraphQL(GraphQLSchema graphQLSchema) { - //noinspection deprecation - this(graphQLSchema, null, null); + public ExecutionStrategy getQueryStrategy() { + return queryStrategy; } /** - * A GraphQL object ready to execute queries - * - * @param graphQLSchema the schema to use - * @param queryStrategy the query execution strategy to use - * - * @deprecated use the {@link #newGraphQL(GraphQLSchema)} builder instead. This will be removed in a future version. + * @return the execution strategy used for mutation in this {@link GraphQL} instance */ - @Internal - public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy) { - //noinspection deprecation - this(graphQLSchema, queryStrategy, null); + public ExecutionStrategy getMutationStrategy() { + return mutationStrategy; } /** - * A GraphQL object ready to execute queries - * - * @param graphQLSchema the schema to use - * @param queryStrategy the query execution strategy to use - * @param mutationStrategy the mutation execution strategy to use - * - * @deprecated use the {@link #newGraphQL(GraphQLSchema)} builder instead. This will be removed in a future version. + * @return the execution strategy used for subscriptions in this {@link GraphQL} instance */ - @Internal - public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy) { - this(graphQLSchema, queryStrategy, mutationStrategy, null, DEFAULT_EXECUTION_ID_PROVIDER, SimpleInstrumentation.INSTANCE, NoOpPreparsedDocumentProvider.INSTANCE); + public ExecutionStrategy getSubscriptionStrategy() { + return subscriptionStrategy; } /** - * A GraphQL object ready to execute queries - * - * @param graphQLSchema the schema to use - * @param queryStrategy the query execution strategy to use - * @param mutationStrategy the mutation execution strategy to use - * @param subscriptionStrategy the subscription execution strategy to use - * - * @deprecated use the {@link #newGraphQL(GraphQLSchema)} builder instead. This will be removed in a future version. + * @return the provider of execution ids for this {@link GraphQL} instance + */ + public ExecutionIdProvider getIdProvider() { + return idProvider; + } + + /** + * @return the Instrumentation for this {@link GraphQL} instance, if any + */ + public Instrumentation getInstrumentation() { + return instrumentation; + } + + public boolean isDoNotAutomaticallyDispatchDataLoader() { + return doNotAutomaticallyDispatchDataLoader; + } + + /** + * @return the PreparsedDocumentProvider for this {@link GraphQL} instance */ - @Internal - public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy) { - this(graphQLSchema, queryStrategy, mutationStrategy, subscriptionStrategy, DEFAULT_EXECUTION_ID_PROVIDER, SimpleInstrumentation.INSTANCE, NoOpPreparsedDocumentProvider.INSTANCE); + public PreparsedDocumentProvider getPreparsedDocumentProvider() { + return preparsedDocumentProvider; } - private GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, ExecutionIdProvider idProvider, Instrumentation instrumentation, PreparsedDocumentProvider preparsedDocumentProvider) { - this.graphQLSchema = assertNotNull(graphQLSchema, "queryStrategy must be non null"); - this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); - this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); - this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new SubscriptionExecutionStrategy(); - this.idProvider = assertNotNull(idProvider, "idProvider must be non null"); - this.instrumentation = instrumentation; - this.preparsedDocumentProvider = assertNotNull(preparsedDocumentProvider, "preparsedDocumentProvider must be non null"); + /** + * @return the ValueUnboxer for this {@link GraphQL} instance + */ + public ValueUnboxer getValueUnboxer() { + return valueUnboxer; } /** @@ -184,32 +257,31 @@ public static Builder newGraphQL(GraphQLSchema graphQLSchema) { public GraphQL transform(Consumer builderConsumer) { Builder builder = new Builder(this.graphQLSchema); builder - .queryExecutionStrategy(nvl(this.queryStrategy, builder.queryExecutionStrategy)) - .mutationExecutionStrategy(nvl(this.mutationStrategy, builder.mutationExecutionStrategy)) - .subscriptionExecutionStrategy(nvl(this.subscriptionStrategy, builder.subscriptionExecutionStrategy)) - .executionIdProvider(nvl(this.idProvider, builder.idProvider)) - .instrumentation(nvl(this.instrumentation, builder.instrumentation)) - .preparsedDocumentProvider(nvl(this.preparsedDocumentProvider, builder.preparsedDocumentProvider)); + .queryExecutionStrategy(this.queryStrategy) + .mutationExecutionStrategy(this.mutationStrategy) + .subscriptionExecutionStrategy(this.subscriptionStrategy) + .executionIdProvider(this.idProvider) + .instrumentation(this.instrumentation) + .preparsedDocumentProvider(this.preparsedDocumentProvider); builderConsumer.accept(builder); return builder.build(); } - private static T nvl(T obj, T elseObj) { - return obj == null ? elseObj : obj; - } - @PublicApi + @NullUnmarked public static class Builder { private GraphQLSchema graphQLSchema; - private ExecutionStrategy queryExecutionStrategy = new AsyncExecutionStrategy(); - private ExecutionStrategy mutationExecutionStrategy = new AsyncSerialExecutionStrategy(); - private ExecutionStrategy subscriptionExecutionStrategy = new SubscriptionExecutionStrategy(); + private ExecutionStrategy queryExecutionStrategy; + private ExecutionStrategy mutationExecutionStrategy; + private ExecutionStrategy subscriptionExecutionStrategy; + private DataFetcherExceptionHandler defaultExceptionHandler = new SimpleDataFetcherExceptionHandler(); private ExecutionIdProvider idProvider = DEFAULT_EXECUTION_ID_PROVIDER; - private Instrumentation instrumentation = SimpleInstrumentation.INSTANCE; + private Instrumentation instrumentation = null; // deliberate default here private PreparsedDocumentProvider preparsedDocumentProvider = NoOpPreparsedDocumentProvider.INSTANCE; - + private boolean doNotAutomaticallyDispatchDataLoader = false; + private ValueUnboxer valueUnboxer = ValueUnboxer.DEFAULT; public Builder(GraphQLSchema graphQLSchema) { this.graphQLSchema = graphQLSchema; @@ -235,6 +307,19 @@ public Builder subscriptionExecutionStrategy(ExecutionStrategy executionStrategy return this; } + /** + * This allows you to set a default {@link graphql.execution.DataFetcherExceptionHandler} that will be used to handle exceptions that happen + * in {@link graphql.schema.DataFetcher} invocations. + * + * @param dataFetcherExceptionHandler the default handler for data fetching exception + * + * @return this builder + */ + public Builder defaultDataFetcherExceptionHandler(DataFetcherExceptionHandler dataFetcherExceptionHandler) { + this.defaultExceptionHandler = assertNotNull(dataFetcherExceptionHandler, "The DataFetcherExceptionHandler must be non null"); + return this; + } + public Builder instrumentation(Instrumentation instrumentation) { this.instrumentation = assertNotNull(instrumentation, "Instrumentation must be non null"); return this; @@ -250,11 +335,39 @@ public Builder executionIdProvider(ExecutionIdProvider executionIdProvider) { return this; } + + /** + * Deactivates the automatic dispatching of DataLoaders. + * If deactivated the user is responsible for dispatching the DataLoaders manually. + * + * @return this builder + */ + public Builder doNotAutomaticallyDispatchDataLoader() { + this.doNotAutomaticallyDispatchDataLoader = true; + return this; + } + + public Builder valueUnboxer(ValueUnboxer valueUnboxer) { + this.valueUnboxer = valueUnboxer; + return this; + } + public GraphQL build() { - assertNotNull(graphQLSchema, "queryStrategy must be non null"); - assertNotNull(queryExecutionStrategy, "queryStrategy must be non null"); - assertNotNull(idProvider, "idProvider must be non null"); - return new GraphQL(graphQLSchema, queryExecutionStrategy, mutationExecutionStrategy, subscriptionExecutionStrategy, idProvider, instrumentation, preparsedDocumentProvider); + // we use the data fetcher exception handler unless they set their own strategy in which case bets are off + if (queryExecutionStrategy == null) { + this.queryExecutionStrategy = new AsyncExecutionStrategy(this.defaultExceptionHandler); + } + if (mutationExecutionStrategy == null) { + this.mutationExecutionStrategy = new AsyncSerialExecutionStrategy(this.defaultExceptionHandler); + } + if (subscriptionExecutionStrategy == null) { + this.subscriptionExecutionStrategy = new SubscriptionExecutionStrategy(this.defaultExceptionHandler); + } + + if (instrumentation == null) { + this.instrumentation = SimplePerformantInstrumentation.INSTANCE; + } + return new GraphQL(this); } } @@ -272,93 +385,6 @@ public ExecutionResult execute(String query) { return execute(executionInput); } - /** - * Info: This sets context = root to be backwards compatible. - * - * @param query the query/mutation/subscription - * @param context custom object provided to each {@link graphql.schema.DataFetcher} - * - * @return an {@link ExecutionResult} which can include errors - * - * @deprecated Use {@link #execute(ExecutionInput)} - */ - @Deprecated - public ExecutionResult execute(String query, Object context) { - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query(query) - .context(context) - .root(context) // This we are doing do be backwards compatible - .build(); - return execute(executionInput); - } - - /** - * Info: This sets context = root to be backwards compatible. - * - * @param query the query/mutation/subscription - * @param operationName the name of the operation to execute - * @param context custom object provided to each {@link graphql.schema.DataFetcher} - * - * @return an {@link ExecutionResult} which can include errors - * - * @deprecated Use {@link #execute(ExecutionInput)} - */ - @Deprecated - public ExecutionResult execute(String query, String operationName, Object context) { - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query(query) - .operationName(operationName) - .context(context) - .root(context) // This we are doing do be backwards compatible - .build(); - return execute(executionInput); - } - - /** - * Info: This sets context = root to be backwards compatible. - * - * @param query the query/mutation/subscription - * @param context custom object provided to each {@link graphql.schema.DataFetcher} - * @param variables variable values uses as argument - * - * @return an {@link ExecutionResult} which can include errors - * - * @deprecated Use {@link #execute(ExecutionInput)} - */ - @Deprecated - public ExecutionResult execute(String query, Object context, Map variables) { - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query(query) - .context(context) - .root(context) // This we are doing do be backwards compatible - .variables(variables) - .build(); - return execute(executionInput); - } - - /** - * Info: This sets context = root to be backwards compatible. - * - * @param query the query/mutation/subscription - * @param operationName name of the operation to execute - * @param context custom object provided to each {@link graphql.schema.DataFetcher} - * @param variables variable values uses as argument - * - * @return an {@link ExecutionResult} which can include errors - * - * @deprecated Use {@link #execute(ExecutionInput)} - */ - @Deprecated - public ExecutionResult execute(String query, String operationName, Object context, Map variables) { - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query(query) - .operationName(operationName) - .context(context) - .root(context) // This we are doing do be backwards compatible - .variables(variables) - .build(); - return execute(executionInput); - } /** * Executes the graphql query using the provided input object builder @@ -454,146 +480,144 @@ public CompletableFuture executeAsync(UnaryOperator executeAsync(ExecutionInput executionInput) { - try { - log.debug("Executing request. operation name: '{}'. query: '{}'. variables '{}'", executionInput.getOperationName(), executionInput.getQuery(), executionInput.getVariables()); - - InstrumentationState instrumentationState = instrumentation.createState(); - - InstrumentationExecutionParameters inputInstrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema, instrumentationState); - executionInput = instrumentation.instrumentExecutionInput(executionInput, inputInstrumentationParameters); + Profiler profiler = executionInput.isProfileExecution() ? new ProfilerImpl(executionInput.getGraphQLContext()) : Profiler.NO_OP; + EngineRunningState engineRunningState = new EngineRunningState(executionInput, profiler); + return engineRunningState.engineRun(() -> { + ExecutionInput executionInputWithId = ensureInputHasId(executionInput); + profiler.setExecutionInputAndInstrumentation(executionInputWithId, instrumentation); + engineRunningState.updateExecutionInput(executionInputWithId); + + CompletableFuture instrumentationStateCF = instrumentation.createStateAsync(new InstrumentationCreateStateParameters(this.graphQLSchema, executionInputWithId)); + instrumentationStateCF = Async.orNullCompletedFuture(instrumentationStateCF); + + return engineRunningState.compose(instrumentationStateCF, (instrumentationState -> { + try { + InstrumentationExecutionParameters inputInstrumentationParameters = new InstrumentationExecutionParameters(executionInputWithId, this.graphQLSchema); + ExecutionInput instrumentedExecutionInput = instrumentation.instrumentExecutionInput(executionInputWithId, inputInstrumentationParameters, instrumentationState); + + InstrumentationExecutionParameters instrumentationParameters = new InstrumentationExecutionParameters(instrumentedExecutionInput, this.graphQLSchema); + InstrumentationContext executionInstrumentation = nonNullCtx(instrumentation.beginExecution(instrumentationParameters, instrumentationState)); + executionInstrumentation.onDispatched(); + + GraphQLSchema graphQLSchema = instrumentation.instrumentSchema(this.graphQLSchema, instrumentationParameters, instrumentationState); + + CompletableFuture executionResult = parseValidateAndExecute(instrumentedExecutionInput, graphQLSchema, instrumentationState, engineRunningState, profiler); + // + // finish up instrumentation + executionResult = executionResult.whenComplete(completeInstrumentationCtxCF(executionInstrumentation)); + // + // allow instrumentation to tweak the result + executionResult = engineRunningState.compose(executionResult, (result -> instrumentation.instrumentExecutionResult(result, instrumentationParameters, instrumentationState))); + return executionResult; + } catch (AbortExecutionException abortException) { + return handleAbortException(executionInput, instrumentationState, abortException); + } + })); + }); + } - InstrumentationExecutionParameters instrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema, instrumentationState); - InstrumentationContext executionInstrumentation = instrumentation.beginExecution(instrumentationParameters); - GraphQLSchema graphQLSchema = instrumentation.instrumentSchema(this.graphQLSchema, instrumentationParameters); + private CompletableFuture handleAbortException(ExecutionInput executionInput, InstrumentationState instrumentationState, AbortExecutionException abortException) { + InstrumentationExecutionParameters instrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema); + return instrumentation.instrumentExecutionResult(abortException.toExecutionResult(), instrumentationParameters, instrumentationState); + } - CompletableFuture executionResult = parseValidateAndExecute(executionInput, graphQLSchema, instrumentationState); - // - // finish up instrumentation - executionResult = executionResult.whenComplete(executionInstrumentation::onCompleted); - // - // allow instrumentation to tweak the result - executionResult = executionResult.thenCompose(result -> instrumentation.instrumentExecutionResult(result, instrumentationParameters)); - return executionResult; - } catch (AbortExecutionException abortException) { - return CompletableFuture.completedFuture(abortException.toExecutionResult()); + private ExecutionInput ensureInputHasId(ExecutionInput executionInput) { + if (executionInput.getExecutionId() != null) { + return executionInput; } + String queryString = executionInput.getQuery(); + String operationName = executionInput.getOperationName(); + Object context = executionInput.getGraphQLContext(); + return executionInput.transform(builder -> builder.executionId(idProvider.provide(queryString, operationName, context))); } - private CompletableFuture parseValidateAndExecute(ExecutionInput executionInput, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { + private CompletableFuture parseValidateAndExecute(ExecutionInput executionInput, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState, EngineRunningState engineRunningState, Profiler profiler) { AtomicReference executionInputRef = new AtomicReference<>(executionInput); - PreparsedDocumentEntry preparsedDoc = preparsedDocumentProvider.get(executionInput.getQuery(), - transformedQuery -> { - // if they change the original query in the pre-parser, then we want to see it downstream from then on - executionInputRef.set(executionInput.transform(bldr -> bldr.query(transformedQuery))); - return parseAndValidate(executionInputRef.get(), graphQLSchema, instrumentationState); - }); - if (preparsedDoc.hasErrors()) { - return CompletableFuture.completedFuture(new ExecutionResultImpl(preparsedDoc.getErrors())); - } - - return execute(executionInputRef.get(), preparsedDoc.getDocument(), graphQLSchema, instrumentationState); + Function computeFunction = transformedInput -> { + // if they change the original query in the pre-parser, then we want to see it downstream from then on + executionInputRef.set(transformedInput); + return parseAndValidate(executionInputRef, graphQLSchema, instrumentationState); + }; + CompletableFuture preparsedDoc = preparsedDocumentProvider.getDocumentAsync(executionInput, computeFunction); + return engineRunningState.compose(preparsedDoc, (preparsedDocumentEntry -> { + if (preparsedDocumentEntry.hasErrors()) { + return CompletableFuture.completedFuture(new ExecutionResultImpl(preparsedDocumentEntry.getErrors())); + } + try { + return execute(Assert.assertNotNull(executionInputRef.get()), preparsedDocumentEntry.getDocument(), graphQLSchema, instrumentationState, engineRunningState, profiler); + } catch (AbortExecutionException e) { + return CompletableFuture.completedFuture(e.toExecutionResult()); + } + })); } - private PreparsedDocumentEntry parseAndValidate(ExecutionInput executionInput, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { - log.debug("Parsing query: '{}'...", executionInput.getQuery()); - ParseResult parseResult = parse(executionInput, graphQLSchema, instrumentationState); + private PreparsedDocumentEntry parseAndValidate(AtomicReference executionInputRef, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { + + ExecutionInput executionInput = assertNotNull(executionInputRef.get()); + + ParseAndValidateResult parseResult = parse(executionInput, graphQLSchema, instrumentationState); if (parseResult.isFailure()) { - log.warn("Query failed to parse : '{}'", executionInput.getQuery()); - return new PreparsedDocumentEntry(toInvalidSyntaxError(parseResult.getException())); + return new PreparsedDocumentEntry(parseResult.getSyntaxException().toInvalidSyntaxError()); } else { final Document document = parseResult.getDocument(); + // they may have changed the document and the variables via instrumentation so update the reference to it + executionInput = executionInput.transform(builder -> builder.variables(parseResult.getVariables())); + executionInputRef.set(executionInput); - log.debug("Validating query: '{}'", executionInput.getQuery()); final List errors = validate(executionInput, document, graphQLSchema, instrumentationState); if (!errors.isEmpty()) { - log.warn("Query failed to validate : '{}'", executionInput.getQuery()); - return new PreparsedDocumentEntry(errors); + return new PreparsedDocumentEntry(document, errors); } return new PreparsedDocumentEntry(document); } } - private ParseResult parse(ExecutionInput executionInput, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { - InstrumentationContext parseInstrumentation = instrumentation.beginParse(new InstrumentationExecutionParameters(executionInput, graphQLSchema, instrumentationState)); + private ParseAndValidateResult parse(ExecutionInput executionInput, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { + InstrumentationExecutionParameters parameters = new InstrumentationExecutionParameters(executionInput, graphQLSchema); + InstrumentationContext parseInstrumentationCtx = nonNullCtx(instrumentation.beginParse(parameters, instrumentationState)); + parseInstrumentationCtx.onDispatched(); - Parser parser = new Parser(); - Document document; - try { - document = parser.parseDocument(executionInput.getQuery()); - } catch (ParseCancellationException e) { - parseInstrumentation.onCompleted(null, e); - return ParseResult.ofError(e); - } + ParseAndValidateResult parseResult = ParseAndValidate.parse(executionInput); + if (parseResult.isFailure()) { + parseInstrumentationCtx.onCompleted(null, parseResult.getSyntaxException()); + return parseResult; + } else { + parseInstrumentationCtx.onCompleted(parseResult.getDocument(), null); - parseInstrumentation.onCompleted(document, null); - return ParseResult.of(document); + DocumentAndVariables documentAndVariables = parseResult.getDocumentAndVariables(); + documentAndVariables = instrumentation.instrumentDocumentAndVariables(documentAndVariables, parameters, instrumentationState); + return ParseAndValidateResult.newResult() + .document(documentAndVariables.getDocument()).variables(documentAndVariables.getVariables()).build(); + } } private List validate(ExecutionInput executionInput, Document document, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { - InstrumentationContext> validationCtx = instrumentation.beginValidation(new InstrumentationValidationParameters(executionInput, document, graphQLSchema, instrumentationState)); + InstrumentationContext> validationCtx = nonNullCtx(instrumentation.beginValidation(new InstrumentationValidationParameters(executionInput, document, graphQLSchema), instrumentationState)); + validationCtx.onDispatched(); - Validator validator = new Validator(); - List validationErrors = validator.validateDocument(graphQLSchema, document); + Predicate> validationRulePredicate = executionInput.getGraphQLContext().getOrDefault(ParseAndValidate.INTERNAL_VALIDATION_PREDICATE_HINT, r -> true); + Locale locale = executionInput.getLocale() != null ? executionInput.getLocale() : Locale.getDefault(); + List validationErrors = ParseAndValidate.validate(graphQLSchema, document, validationRulePredicate, locale); validationCtx.onCompleted(validationErrors, null); return validationErrors; } - private CompletableFuture execute(ExecutionInput executionInput, Document document, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) { - String query = executionInput.getQuery(); - String operationName = executionInput.getOperationName(); - Object context = executionInput.getContext(); + private CompletableFuture execute(ExecutionInput executionInput, + Document document, + GraphQLSchema graphQLSchema, + InstrumentationState instrumentationState, + EngineRunningState engineRunningState, + Profiler profiler + ) { - Execution execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, instrumentation); - ExecutionId executionId = idProvider.provide(query, operationName, context); + Execution execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, instrumentation, valueUnboxer, doNotAutomaticallyDispatchDataLoader); + ExecutionId executionId = executionInput.getExecutionId(); - log.debug("Executing '{}'. operation name: '{}'. query: '{}'. variables '{}'", executionId, executionInput.getOperationName(), executionInput.getQuery(), executionInput.getVariables()); - CompletableFuture future = execution.execute(document, graphQLSchema, executionId, executionInput, instrumentationState); - future = future.whenComplete((result, throwable) -> { - if (throwable != null) { - log.error(String.format("Execution '%s' threw exception when executing : query : '%s'. variables '%s'", executionId, executionInput.getQuery(), executionInput.getVariables()), throwable); - } else { - int errorCount = result.getErrors().size(); - if (errorCount > 0) { - log.debug("Execution '{}' completed with '{}' errors", executionId, errorCount); - } else { - log.debug("Execution '{}' completed with zero errors", executionId); - } - } - }); - return future; + return execution.execute(document, graphQLSchema, executionId, executionInput, instrumentationState, engineRunningState, profiler); } - private static class ParseResult { - private final Document document; - private final Exception exception; - - private ParseResult(Document document, Exception exception) { - this.document = document; - this.exception = exception; - } - - private boolean isFailure() { - return document == null; - } - - private Document getDocument() { - return document; - } - - private Exception getException() { - return exception; - } - - private static ParseResult of(Document document) { - return new ParseResult(document, null); - } - - private static ParseResult ofError(Exception e) { - return new ParseResult(null, e); - } - } } diff --git a/src/main/java/graphql/GraphQLContext.java b/src/main/java/graphql/GraphQLContext.java new file mode 100644 index 0000000000..64ec5c406b --- /dev/null +++ b/src/main/java/graphql/GraphQLContext.java @@ -0,0 +1,461 @@ +package graphql; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Stream; + +import static graphql.Assert.assertNotNull; + + +/** + * This context object can be used to contain key values that can be useful as "context" when executing + * {@link graphql.schema.DataFetcher}s + * + *

+ * {@code
+ *     DataFetcher df = new DataFetcher() {
+ *        public Object get(DataFetchingEnvironment env) {
+ *            GraphQLContext ctx = env.getGraphqlContext()
+ *            User currentUser = ctx.getOrDefault("userKey",new AnonymousUser())
+ *            ...
+ *        }
+ *     }
+ * }
+ * 
+ * + * You can set this up via {@link ExecutionInput#getGraphQLContext()} + * + * All keys and values in the context MUST be non null. + * + * The class is mutable via a thread safe implementation but it is recommended to try to use this class in an immutable way if you can. + */ +@PublicApi +@ThreadSafe +@SuppressWarnings("unchecked") +public class GraphQLContext { + + private final ConcurrentMap map; + + private GraphQLContext(ConcurrentMap map) { + this.map = map; + } + + /** + * Deletes a key in the context + * + * @param key the key to delete + * + * @return this GraphQLContext object + */ + public GraphQLContext delete(Object key) { + map.remove(assertNotNull(key)); + return this; + } + + /** + * Returns a value in the context by key + * + * @param key the key to look up + * @param for two + * + * @return a value or null + */ + public T get(Object key) { + return (T) map.get(assertNotNull(key)); + } + + /** + * Returns a value in the context by key + * + * @param key the key to look up + * @param defaultValue the default value to use if these is no key entry + * @param for two + * + * @return a value or default value + */ + public T getOrDefault(Object key, T defaultValue) { + return (T) map.getOrDefault(assertNotNull(key), defaultValue); + } + + /** + * Returns a {@link Optional} value in the context by key + * + * @param key the key to look up + * @param for two + * + * @return a value or an empty optional value + */ + public Optional getOrEmpty(Object key) { + T t = (T) map.get(assertNotNull(key)); + return Optional.ofNullable(t); + } + + /** + * This returns true if the value at the specified key is equal to + * {@link Boolean#TRUE} + * + * @param key the key to look up + * + * @return true if the value is equal to {@link Boolean#TRUE} + */ + public boolean getBoolean(Object key) { + Object val = map.get(assertNotNull(key)); + return Boolean.TRUE.equals(val); + } + + /** + * This returns true if the value at the specified key is equal to + * {@link Boolean#TRUE} or the default value if the key is missing + * + * @param key the key to look up + * @param defaultValue the value to use if the key is not present + * + * @return true if the value is equal to {@link Boolean#TRUE} + */ + public boolean getBoolean(Object key, Boolean defaultValue) { + Object val = map.getOrDefault(assertNotNull(key), defaultValue); + return Boolean.TRUE.equals(val); + } + + /** + * Returns true if the context contains a value for that key + * + * @param key the key to lookup + * + * @return true if there is a value for that key + */ + public boolean hasKey(Object key) { + return map.containsKey(assertNotNull(key)); + } + + /** + * Puts a value into the context + * + * @param key the key to set + * @param value the new value (which not must be null) + * + * @return this {@link GraphQLContext} object + */ + public GraphQLContext put(Object key, Object value) { + map.put(assertNotNull(key), assertNotNull(value)); + return this; + } + + /** + * Puts all of the values into the context + * + * @param map the map of values to use + * + * @return this {@link GraphQLContext} object + */ + public GraphQLContext putAll(Map map) { + assertNotNull(map); + for (Map.Entry entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + return this; + } + + /** + * Puts all of the values into the context + * + * @param context the other context to use + * + * @return this {@link GraphQLContext} object + */ + public GraphQLContext putAll(GraphQLContext context) { + assertNotNull(context); + return putAll(context.map); + } + + /** + * Puts all of the values into the context + * + * @param contextBuilder the other context to use + * + * @return this {@link GraphQLContext} object + */ + public GraphQLContext putAll(GraphQLContext.Builder contextBuilder) { + assertNotNull(contextBuilder); + return putAll(contextBuilder.build()); + } + + /** + * Puts all of the values into the context + * + * @param contextBuilderConsumer a call back to that gives out a builder to use + * + * @return this {@link GraphQLContext} object + */ + public GraphQLContext putAll(Consumer contextBuilderConsumer) { + assertNotNull(contextBuilderConsumer); + Builder builder = newContext(); + contextBuilderConsumer.accept(builder); + return putAll(builder); + } + + /** + * Attempts to compute a mapping for the specified key and its + * current mapped value (or null if there is no current mapping). + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @param for two + * + * @return the new value associated with the specified key, or null if none + */ + public T compute(Object key, BiFunction remappingFunction) { + assertNotNull(remappingFunction); + return (T) map.compute(assertNotNull(key), (k, v) -> remappingFunction.apply(k, (T) v)); + } + + /** + * If the specified key is not already associated with a value (or is mapped to null), + * attempts to compute its value using the given mapping function and enters it into this map unless null. + * + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @param for two + * + * @return the current (existing or computed) value associated with the specified key, or null if the computed value is null + */ + + public T computeIfAbsent(Object key, Function mappingFunction) { + return (T) map.computeIfAbsent(assertNotNull(key), assertNotNull(mappingFunction)); + } + + /** + * If the value for the specified key is present and non-null, + * attempts to compute a new mapping given the key and its current mapped value. + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @param for two + * + * @return the new value associated with the specified key, or null if none + */ + + public T computeIfPresent(Object key, BiFunction remappingFunction) { + assertNotNull(remappingFunction); + return (T) map.computeIfPresent(assertNotNull(key), (k, v) -> remappingFunction.apply(k, (T) v)); + } + + /** + * @return a stream of entries in the context + */ + public Stream> stream() { + return map.entrySet().stream(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GraphQLContext that = (GraphQLContext) o; + return map.equals(that.map); + } + + @Override + public int hashCode() { + return Objects.hash(map); + } + + @Override + public String toString() { + return map.toString(); + } + + /** + * Creates a new GraphqlContext with the map of context added to it + * + * @param mapOfContext the map of context value to use + * + * @return the new GraphqlContext + */ + public static GraphQLContext of(Map mapOfContext) { + return new Builder().of(mapOfContext).build(); + } + + /** + * Creates a new GraphqlContext with the map of context added to it + * + * @param contextBuilderConsumer a callback that is given a new builder + * + * @return the new GraphqlContext + */ + public static GraphQLContext of(Consumer contextBuilderConsumer) { + Builder builder = GraphQLContext.newContext(); + contextBuilderConsumer.accept(builder); + return of(builder.map); + } + + /** + * @return a new and empty graphql context object + */ + public static GraphQLContext getDefault() { + return GraphQLContext.newContext().build(); + } + + /** + * Creates a new GraphqlContext builder + * + * @return the new builder + */ + public static Builder newContext() { + return new Builder(); + } + + public static class Builder { + private final ConcurrentMap map = new ConcurrentHashMap<>(); + + public Builder put( + Object key1, Object value1 + ) { + return putImpl( + key1, value1 + ); + } + + public Object get(Object key) { + return map.get(key); + } + + public boolean getBoolean(Object key) { + return Boolean.parseBoolean(String.valueOf(get(key))); + } + + + public Builder of( + Object key1, Object value1 + ) { + return putImpl( + key1, value1 + ); + } + + public Builder of( + Object key1, Object value1, + Object key2, Object value2 + ) { + return putImpl( + key1, value1, + key2, value2 + ); + } + + public Builder of( + Object key1, Object value1, + Object key2, Object value2, + Object key3, Object value3 + ) { + return putImpl( + key1, value1, + key2, value2, + key3, value3 + ); + } + + public Builder of( + Object key1, Object value1, + Object key2, Object value2, + Object key3, Object value3, + Object key4, Object value4 + ) { + return putImpl( + key1, value1, + key2, value2, + key3, value3, + key4, value4 + ); + } + + public Builder of( + Object key1, Object value1, + Object key2, Object value2, + Object key3, Object value3, + Object key4, Object value4, + Object key5, Object value5 + ) { + return putImpl( + key1, value1, + key2, value2, + key3, value3, + key4, value4, + key5, value5 + ); + } + + /** + * Adds all of the values in the map into the context builder. All keys and values MUST be non null + * + * @param mapOfContext the map to put into context + * + * @return this builder + */ + public Builder of(Map mapOfContext) { + assertNotNull(mapOfContext); + for (Map.Entry entry : mapOfContext.entrySet()) { + map.put(assertNotNull(entry.getKey()), assertNotNull(entry.getValue())); + } + return this; + } + + /** + * Adds all of the values in the map into the context builder. All keys and values MUST be non null + * + * @param mapOfContext the map to put into context + * + * @return this builder + */ + public Builder putAll(Map mapOfContext) { + return of(mapOfContext); + } + + /** + * Adds all of the values in the map into the context builder. All keys and values MUST be non null + * + * @param graphQLContext a previous graphql context + * + * @return this builder + */ + public Builder of(GraphQLContext graphQLContext) { + assertNotNull(graphQLContext); + return of(graphQLContext.map); + } + + /** + * Adds all of the values in the map into the context builder. All keys and values MUST be non null + * + * @param graphQLContextBuilder a graphql context builder + * + * @return this builder + */ + public Builder of(GraphQLContext.Builder graphQLContextBuilder) { + assertNotNull(graphQLContextBuilder); + return of(graphQLContextBuilder.build()); + } + + private Builder putImpl(Object... kvs) { + for (int i = 0; i < kvs.length; i = i + 2) { + Object k = kvs[i]; + Object v = kvs[i + 1]; + map.put(assertNotNull(k), assertNotNull(v)); + } + return this; + } + + public GraphQLContext build() { + return new GraphQLContext(map); + } + } +} diff --git a/src/main/java/graphql/GraphQLError.java b/src/main/java/graphql/GraphQLError.java index 034fd505ed..90c3527b50 100644 --- a/src/main/java/graphql/GraphQLError.java +++ b/src/main/java/graphql/GraphQLError.java @@ -1,7 +1,9 @@ package graphql; +import graphql.execution.ResultPath; import graphql.language.SourceLocation; +import org.jspecify.annotations.Nullable; import java.io.Serializable; import java.util.List; @@ -15,7 +17,7 @@ * with times frames that cross graphql-java versions. While we don't change things unnecessarily, we may inadvertently break * the serialised compatibility across versions. * - * @see GraphQL Spec - 7.2.2 Errors + * @see GraphQL Spec - 7.1.2 Errors */ @PublicApi public interface GraphQLError extends Serializable { @@ -32,13 +34,15 @@ public interface GraphQLError extends Serializable { List getLocations(); /** - * @return an enum classifying this error + * @return an object classifying this error */ - ErrorType getErrorType(); + ErrorClassification getErrorType(); /** - * The graphql spec says that the (optional) path field of any error should be a list - * of path entries - http://facebook.github.io/graphql/#sec-Errors + * The graphql spec says that the (optional) path field of any error must be + * a list of path entries starting at the root of the response + * and ending with the field associated with the error + * https://spec.graphql.org/draft/#sec-Errors.Error-Result-Format * * @return the path in list format */ @@ -51,7 +55,7 @@ default List getPath() { * should be present. Certain JSON serializers may or may interpret the error to spec, so this method * is provided to produce a map that strictly follows the specification. * - * See : http://facebook.github.io/graphql/#sec-Errors + * See : GraphQL Spec - 7.1.2 Errors * * @return a map of the error that strictly follows the specification */ @@ -66,5 +70,96 @@ default Map getExtensions() { return null; } + /** + * This can be called to turn a specification error map into {@link GraphQLError} + * + * @param specificationMap the map of values that should have come via {@link GraphQLError#toSpecification()} + * + * @return a {@link GraphQLError} + */ + static GraphQLError fromSpecification(Map specificationMap) { + return GraphqlErrorHelper.fromSpecification(specificationMap); + } + + /** + * @return a new builder of {@link GraphQLError}s + */ + static Builder newError() { + return new GraphqlErrorBuilder<>(); + } + + /** + * A builder of {@link GraphQLError}s + */ + interface Builder> { + + /** + * Sets the message of the error using {@link String#format(String, Object...)} with the arguments + * + * @param message the message + * @param formatArgs the arguments to use + * + * @return this builder + */ + B message(String message, Object... formatArgs); + + /** + * This adds locations to the error + * + * @param locations the locations to add + * + * @return this builder + */ + B locations(@Nullable List locations); + + /** + * This adds a location to the error + * + * @param location the locations to add + * + * @return this builder + */ + B location(@Nullable SourceLocation location); + /** + * Sets the path of the message + * + * @param path can be null + * + * @return this builder + */ + B path(@Nullable ResultPath path); + + /** + * Sets the path of the message + * + * @param path can be null + * + * @return this builder + */ + B path(@Nullable List path); + + /** + * Sets the {@link ErrorClassification} of the message + * + * @param errorType the error classification to use + * + * @return this builder + */ + B errorType(ErrorClassification errorType); + + /** + * Sets the extensions of the message + * + * @param extensions the extensions to use + * + * @return this builder + */ + B extensions(@Nullable Map extensions); + + /** + * @return a newly built GraphqlError + */ + GraphQLError build(); + } } diff --git a/src/main/java/graphql/GraphQLException.java b/src/main/java/graphql/GraphQLException.java index 1ad66921cf..a658769c82 100644 --- a/src/main/java/graphql/GraphQLException.java +++ b/src/main/java/graphql/GraphQLException.java @@ -1,6 +1,7 @@ package graphql; +@Internal public class GraphQLException extends RuntimeException { public GraphQLException() { @@ -18,5 +19,4 @@ public GraphQLException(Throwable cause) { super(cause); } - } diff --git a/src/main/java/graphql/GraphQLUnusualConfiguration.java b/src/main/java/graphql/GraphQLUnusualConfiguration.java new file mode 100644 index 0000000000..e96b0b7380 --- /dev/null +++ b/src/main/java/graphql/GraphQLUnusualConfiguration.java @@ -0,0 +1,413 @@ +package graphql; + +import graphql.execution.ResponseMapFactory; +import graphql.execution.incremental.IncrementalExecutionContextKeys; +import graphql.introspection.GoodFaithIntrospection; +import graphql.parser.ParserOptions; +import graphql.schema.PropertyDataFetcherHelper; + +import static graphql.Assert.assertNotNull; +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING; +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING; + +/** + * This allows you to control "unusual" aspects of the GraphQL system + * including some JVM wide settings and some per execution settings + * as well as experimental ones. + *

+ * This is named unusual because in general we don't expect you to + * have to make ths configuration by default, but you can opt into certain features + * or disable them if you want to. + */ +public class GraphQLUnusualConfiguration { + GraphQLUnusualConfiguration() { + } + + /** + * @return an element that allows you to control JVM wide parsing configuration + */ + public ParserConfig parsing() { + return new ParserConfig(this); + } + + /** + * @return an element that allows you to control JVM wide {@link graphql.schema.PropertyDataFetcher} configuration + */ + public PropertyDataFetcherConfig propertyDataFetching() { + return new PropertyDataFetcherConfig(this); + } + + /** + * @return an element that allows you to control JVM wide configuration + * of {@link graphql.introspection.GoodFaithIntrospection} + */ + public GoodFaithIntrospectionConfig goodFaithIntrospection() { + return new GoodFaithIntrospectionConfig(this); + } + + private static class BaseConfig { + protected final GraphQLUnusualConfiguration configuration; + + private BaseConfig(GraphQLUnusualConfiguration configuration) { + this.configuration = configuration; + } + + /** + * @return an element that allows you to chain multiple configuration elements + */ + public GraphQLUnusualConfiguration then() { + return configuration; + } + } + + public static class ParserConfig extends BaseConfig { + + private ParserConfig(GraphQLUnusualConfiguration configuration) { + super(configuration); + } + + /** + * By default, the Parser will not capture ignored characters. A static holds this default + * value in a JVM wide basis options object. + *

+ * Significant memory savings can be made if we do NOT capture ignored characters, + * especially in SDL parsing. + * + * @return the static default JVM value + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public ParserOptions getDefaultParserOptions() { + return ParserOptions.getDefaultParserOptions(); + } + + /** + * By default, the Parser will not capture ignored characters. A static holds this default + * value in a JVM wide basis options object. + *

+ * Significant memory savings can be made if we do NOT capture ignored characters, + * especially in SDL parsing. So we have set this to false by default. + *

+ * This static can be set to true to allow the behavior of version 16.x or before. + * + * @param options - the new default JVM parser options + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public ParserConfig setDefaultParserOptions(ParserOptions options) { + ParserOptions.setDefaultParserOptions(options); + return this; + } + + + /** + * By default, for operation parsing, the Parser will not capture ignored characters, and it will not capture line comments into AST + * elements . A static holds this default value for operation parsing in a JVM wide basis options object. + * + * @return the static default JVM value for operation parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public ParserOptions getDefaultOperationParserOptions() { + return ParserOptions.getDefaultOperationParserOptions(); + } + + /** + * By default, the Parser will not capture ignored characters or line comments. A static holds this default + * value in a JVM wide basis options object for operation parsing. + *

+ * This static can be set to true to allow the behavior of version 16.x or before. + * + * @param options - the new default JVM parser options for operation parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public ParserConfig setDefaultOperationParserOptions(ParserOptions options) { + ParserOptions.setDefaultOperationParserOptions(options); + return this; + } + + /** + * By default, for SDL parsing, the Parser will not capture ignored characters, but it will capture line comments into AST + * elements. The SDL default options allow unlimited tokens and whitespace, since a DOS attack vector is + * not commonly available via schema SDL parsing. + *

+ * A static holds this default value for SDL parsing in a JVM wide basis options object. + * + * @return the static default JVM value for SDL parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + * @see graphql.schema.idl.SchemaParser + */ + public ParserOptions getDefaultSdlParserOptions() { + return ParserOptions.getDefaultSdlParserOptions(); + } + + /** + * By default, for SDL parsing, the Parser will not capture ignored characters, but it will capture line comments into AST + * elements . A static holds this default value for operation parsing in a JVM wide basis options object. + *

+ * This static can be set to true to allow the behavior of version 16.x or before. + * + * @param options - the new default JVM parser options for SDL parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public ParserConfig setDefaultSdlParserOptions(ParserOptions options) { + ParserOptions.setDefaultSdlParserOptions(options); + return this; + } + } + + public static class PropertyDataFetcherConfig extends BaseConfig { + private PropertyDataFetcherConfig(GraphQLUnusualConfiguration configuration) { + super(configuration); + } + + /** + * PropertyDataFetcher caches the methods and fields that map from a class to a property for runtime performance reasons + * as well as negative misses. + *

+ * However during development you might be using an assistance tool like JRebel to allow you to tweak your code base and this + * caching may interfere with this. So you can call this method to clear the cache. A JRebel plugin could + * be developed to do just that. + */ + @SuppressWarnings("unused") + public PropertyDataFetcherConfig clearReflectionCache() { + PropertyDataFetcherHelper.clearReflectionCache(); + return this; + } + + /** + * This can be used to control whether PropertyDataFetcher will use {@link java.lang.reflect.Method#setAccessible(boolean)} to gain access to property + * values. By default, it PropertyDataFetcher WILL use setAccessible. + * + * @param flag whether to use setAccessible + * + * @return the previous value of the flag + */ + public boolean setUseSetAccessible(boolean flag) { + return PropertyDataFetcherHelper.setUseSetAccessible(flag); + } + + /** + * This can be used to control whether PropertyDataFetcher will cache negative lookups for a property for performance reasons. By default it PropertyDataFetcher WILL cache misses. + * + * @param flag whether to cache misses + * + * @return the previous value of the flag + */ + public boolean setUseNegativeCache(boolean flag) { + return PropertyDataFetcherHelper.setUseNegativeCache(flag); + } + } + + public static class GoodFaithIntrospectionConfig extends BaseConfig { + private GoodFaithIntrospectionConfig(GraphQLUnusualConfiguration configuration) { + super(configuration); + } + + /** + * @return true if good faith introspection is enabled + */ + public boolean isEnabledJvmWide() { + return GoodFaithIntrospection.isEnabledJvmWide(); + } + + /** + * This allows you to disable good faith introspection, which is on by default. + * + * @param enabled the desired state + * + * @return the previous state + */ + public GoodFaithIntrospectionConfig enabledJvmWide(boolean enabled) { + GoodFaithIntrospection.enabledJvmWide(enabled); + return this; + } + } + + /* + * =============================================== + * Per GraphqlContext code down here + * =============================================== + */ + + @SuppressWarnings("DataFlowIssue") + public static class GraphQLContextConfiguration { + // it will be one or the other types of GraphQLContext + private final GraphQLContext graphQLContext; + private final GraphQLContext.Builder graphQLContextBuilder; + + GraphQLContextConfiguration(GraphQLContext graphQLContext) { + this.graphQLContext = graphQLContext; + this.graphQLContextBuilder = null; + } + + GraphQLContextConfiguration(GraphQLContext.Builder graphQLContextBuilder) { + this.graphQLContextBuilder = graphQLContextBuilder; + this.graphQLContext = null; + } + + /** + * @return an element that allows you to control incremental support, that is @defer configuration + */ + public IncrementalSupportConfig incrementalSupport() { + return new IncrementalSupportConfig(this); + } + + /** + * @return an element that allows you to precisely control {@link org.dataloader.DataLoader} behavior + * in graphql-java. + */ + public DataloaderConfig dataloaderConfig() { + return new DataloaderConfig(this); + } + + /** + * @return an element that allows you to control the {@link ResponseMapFactory} used + */ + public ResponseMapFactoryConfig responseMapFactory() { + return new ResponseMapFactoryConfig(this); + } + + private void put(String named, Object value) { + if (graphQLContext != null) { + graphQLContext.put(named, value); + } else { + assertNotNull(graphQLContextBuilder).put(named, value); + } + } + + private boolean getBoolean(String named) { + if (graphQLContext != null) { + return graphQLContext.getBoolean(named); + } else { + return assertNotNull(graphQLContextBuilder).getBoolean(named); + } + } + + private T get(String named) { + if (graphQLContext != null) { + return graphQLContext.get(named); + } else { + //noinspection unchecked + return (T) assertNotNull(graphQLContextBuilder).get(named); + } + } + } + + private static class BaseContextConfig { + protected final GraphQLContextConfiguration contextConfig; + + private BaseContextConfig(GraphQLContextConfiguration contextConfig) { + this.contextConfig = contextConfig; + } + + /** + * @return an element that allows you to chain multiple configuration elements + */ + public GraphQLContextConfiguration then() { + return contextConfig; + } + } + + public static class IncrementalSupportConfig extends BaseContextConfig { + private IncrementalSupportConfig(GraphQLContextConfiguration contextConfig) { + super(contextConfig); + } + + /** + * @return true if @defer and @stream behaviour is enabled for this execution. + */ + public boolean isIncrementalSupportEnabled() { + return contextConfig.getBoolean(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT); + } + + /** + * This controls whether @defer and @stream behaviour is enabled for this execution. + */ + @ExperimentalApi + public IncrementalSupportConfig enableIncrementalSupport(boolean enable) { + contextConfig.put(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT, enable); + return this; + } + + /** + * This controls whether @defer field execution starts as early as possible. + */ + @ExperimentalApi + public IncrementalSupportConfig enableEarlyIncrementalFieldExecution(boolean enable) { + contextConfig.put(IncrementalExecutionContextKeys.ENABLE_EAGER_DEFER_START, enable); + return this; + } + } + + public static class DataloaderConfig extends BaseContextConfig { + private DataloaderConfig(GraphQLContextConfiguration contextConfig) { + super(contextConfig); + } + + /** + * returns true if chained data loader dispatching is enabled + */ + public boolean isDataLoaderChainingEnabled() { + return contextConfig.getBoolean(ENABLE_DATA_LOADER_CHAINING); + } + + public boolean isDataLoaderExhaustedDispatchingEnabled() { + return contextConfig.get(ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING); + } + + /** + * Enables the ability that chained DataLoaders are dispatched automatically. + */ + @ExperimentalApi + public DataloaderConfig enableDataLoaderChaining(boolean enable) { + contextConfig.put(ENABLE_DATA_LOADER_CHAINING, enable); + return this; + } + + /** + * Enables a dispatching strategy that will dispatch as long as there is no + * other data fetcher or batch loader running. + */ + @ExperimentalApi + public DataloaderConfig enableDataLoaderExhaustedDispatching(boolean enable) { + contextConfig.put(ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, enable); + return this; + } + + + } + + public static class ResponseMapFactoryConfig extends BaseContextConfig { + private ResponseMapFactoryConfig(GraphQLContextConfiguration contextConfig) { + super(contextConfig); + } + + /** + * @return the {@link ResponseMapFactory} in play - this can be null + */ + @ExperimentalApi + public ResponseMapFactory getOr(ResponseMapFactory defaultFactory) { + ResponseMapFactory responseMapFactory = contextConfig.get(ResponseMapFactory.class.getCanonicalName()); + return responseMapFactory != null ? responseMapFactory : defaultFactory; + } + + /** + * This controls the {@link ResponseMapFactory} to use for this request + */ + @ExperimentalApi + public ResponseMapFactoryConfig setFactory(ResponseMapFactory factory) { + contextConfig.put(ResponseMapFactory.class.getCanonicalName(), factory); + return this; + } + } +} diff --git a/src/main/java/graphql/GraphqlErrorBuilder.java b/src/main/java/graphql/GraphqlErrorBuilder.java new file mode 100644 index 0000000000..efca0a3d69 --- /dev/null +++ b/src/main/java/graphql/GraphqlErrorBuilder.java @@ -0,0 +1,227 @@ +package graphql; + +import graphql.execution.DataFetcherResult; +import graphql.execution.ResultPath; +import graphql.language.SourceLocation; +import graphql.schema.DataFetchingEnvironment; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static graphql.Assert.assertNotNull; + +/** + * This helps you build {@link graphql.GraphQLError}s and also has a quick way to make a {@link graphql.execution.DataFetcherResult}s + * from that error. + * + * @param this base class allows you to derive new classes from this base error builder + */ +@SuppressWarnings("unchecked") +@PublicApi +public class GraphqlErrorBuilder> implements GraphQLError.Builder { + + private String message; + private List path; + private List locations = new ArrayList<>(); + private ErrorClassification errorType = ErrorType.DataFetchingException; + private Map extensions = null; + + public String getMessage() { + return message; + } + + @Nullable + public List getPath() { + return path; + } + + @Nullable + public List getLocations() { + return locations; + } + + public ErrorClassification getErrorType() { + return errorType; + } + + @Nullable + public Map getExtensions() { + return extensions; + } + + /** + * @return a builder of {@link graphql.GraphQLError}s + */ + public static GraphqlErrorBuilder newError() { + return new GraphqlErrorBuilder<>(); + } + + /** + * This will set up the {@link GraphQLError#getLocations()} and {@link graphql.GraphQLError#getPath()} for you from the + * fetching environment. + * + * @param dataFetchingEnvironment the data fetching environment + * + * @return a builder of {@link graphql.GraphQLError}s + */ + public static GraphqlErrorBuilder newError(DataFetchingEnvironment dataFetchingEnvironment) { + return new GraphqlErrorBuilder<>() + .location(dataFetchingEnvironment.getField().getSourceLocation()) + .path(dataFetchingEnvironment.getExecutionStepInfo().getPath()); + } + + protected GraphqlErrorBuilder() { + } + + public B message(String message, Object... formatArgs) { + if (formatArgs == null || formatArgs.length == 0) { + this.message = assertNotNull(message); + } else { + this.message = String.format(assertNotNull(message), formatArgs); + } + return (B) this; + } + + public B locations(@Nullable List locations) { + if (locations != null) { + this.locations.addAll(locations); + } else { + this.locations = null; + } + return (B) this; + } + + public B location(@Nullable SourceLocation location) { + if (locations != null) { + this.locations.add(location); + } + return (B) this; + } + + public B path(@Nullable ResultPath path) { + if (path != null) { + this.path = path.toList(); + } else { + this.path = null; + } + return (B) this; + } + + public B path(@Nullable List path) { + this.path = path; + return (B) this; + } + + public B errorType(ErrorClassification errorType) { + this.errorType = assertNotNull(errorType); + return (B) this; + } + + public B extensions(@Nullable Map extensions) { + this.extensions = extensions; + return (B) this; + } + + /** + * @return a newly built GraphqlError + */ + public GraphQLError build() { + assertNotNull(message, "You must provide error message"); + return new GraphqlErrorImpl(message, locations, errorType, path, extensions); + } + + /** + * A simple implementation of a {@link GraphQLError}. + *

+ * This provides {@link #hashCode()} and {@link #equals(Object)} methods that afford comparison with other + * {@link GraphQLError} implementations. However, the values provided in the following fields must + * in turn implement {@link #hashCode()} and {@link #equals(Object)} for this to function correctly: + *

    + *
  • the values in the {@link #getPath()} {@link List}. + *
  • the {@link #getErrorType()} {@link ErrorClassification}. + *
  • the values in the {@link #getExtensions()} {@link Map}. + *
+ */ + private static class GraphqlErrorImpl implements GraphQLError { + private final String message; + private final List locations; + private final ErrorClassification errorType; + private final List path; + private final Map extensions; + + public GraphqlErrorImpl(String message, List locations, ErrorClassification errorType, List path, Map extensions) { + this.message = message; + this.locations = locations; + this.errorType = errorType; + this.path = path; + this.extensions = extensions; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public List getLocations() { + return locations; + } + + @Override + public ErrorClassification getErrorType() { + return errorType; + } + + @Override + public List getPath() { + return path; + } + + @Override + public Map getExtensions() { + return extensions; + } + + @Override + public String toString() { + return message; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GraphQLError)) return false; + GraphQLError that = (GraphQLError) o; + return Objects.equals(getMessage(), that.getMessage()) + && Objects.equals(getLocations(), that.getLocations()) + && Objects.equals(getErrorType(), that.getErrorType()) + && Objects.equals(getPath(), that.getPath()) + && Objects.equals(getExtensions(), that.getExtensions()); + } + + @Override + public int hashCode() { + return Objects.hash( + getMessage(), + getLocations(), + getErrorType(), + getPath(), + getExtensions()); + } + } + + /** + * A helper method that allows you to return this error as a {@link graphql.execution.DataFetcherResult} + * + * @return a new data fetcher result that contains the built error + */ + public DataFetcherResult toResult() { + return DataFetcherResult.newResult() + .error(build()) + .build(); + } + +} diff --git a/src/main/java/graphql/GraphqlErrorException.java b/src/main/java/graphql/GraphqlErrorException.java new file mode 100644 index 0000000000..bfe2cb1d56 --- /dev/null +++ b/src/main/java/graphql/GraphqlErrorException.java @@ -0,0 +1,118 @@ +package graphql; + +import graphql.language.SourceLocation; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * A base class for graphql runtime exceptions that also implement {@link graphql.GraphQLError} and can be used + * in a general sense direct or have specialisations made of it. + *

+ * This is aimed amongst other reasons at Kotlin consumers due to https://github.com/graphql-java/graphql-java/issues/1690 + * as well as being a way to share common code. + */ +@PublicApi +public class GraphqlErrorException extends GraphQLException implements GraphQLError { + + private final List locations; + private final Map extensions; + private final List path; + private final ErrorClassification errorClassification; + + protected GraphqlErrorException(BuilderBase builder) { + super(builder.message, builder.cause); + this.locations = builder.sourceLocations; + this.extensions = builder.extensions; + this.path = builder.path; + this.errorClassification = builder.errorClassification; + } + + @Override + public List getLocations() { + return locations; + } + + @Override + public ErrorClassification getErrorType() { + return errorClassification; + } + + @Override + public List getPath() { + return path; + } + + @Override + public Map getExtensions() { + return extensions; + } + + public static Builder newErrorException() { + return new Builder(); + } + + public static class Builder extends BuilderBase { + public GraphqlErrorException build() { + return new GraphqlErrorException(this); + } + } + + /** + * A trait like base class that contains the properties that GraphqlErrorException handles and can + * be used by other classes to derive their own builders. + * + * @param the derived class + * @param the class to be built + */ + protected abstract static class BuilderBase, B extends GraphqlErrorException> { + protected String message; + protected Throwable cause; + protected ErrorClassification errorClassification = ErrorType.DataFetchingException; + protected List sourceLocations; + protected Map extensions; + protected List path; + + private T asDerivedType() { + //noinspection unchecked + return (T) this; + } + + public T message(String message) { + this.message = message; + return asDerivedType(); + } + + public T cause(Throwable cause) { + this.cause = cause; + return asDerivedType(); + } + + public T sourceLocation(SourceLocation sourceLocation) { + return sourceLocations(sourceLocation == null ? null : Collections.singletonList(sourceLocation)); + } + + public T sourceLocations(List sourceLocations) { + this.sourceLocations = sourceLocations; + return asDerivedType(); + } + + public T errorClassification(ErrorClassification errorClassification) { + this.errorClassification = errorClassification; + return asDerivedType(); + } + + public T path(List path) { + this.path = path; + return asDerivedType(); + } + + public T extensions(Map extensions) { + this.extensions = extensions; + return asDerivedType(); + } + + public abstract B build(); + } +} diff --git a/src/main/java/graphql/GraphqlErrorHelper.java b/src/main/java/graphql/GraphqlErrorHelper.java index bb2345541a..0f4f834a72 100644 --- a/src/main/java/graphql/GraphqlErrorHelper.java +++ b/src/main/java/graphql/GraphqlErrorHelper.java @@ -1,22 +1,27 @@ package graphql; +import com.google.common.collect.Maps; import graphql.language.SourceLocation; +import graphql.util.FpKit; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; -import static java.util.stream.Collectors.toList; +import static graphql.collect.ImmutableKit.mapAndDropNulls; /** * This little helper allows GraphQlErrors to implement * common things (hashcode/ equals ) and to specification more easily */ -@SuppressWarnings("SimplifiableIfStatement") +@SuppressWarnings({"SimplifiableIfStatement", "unchecked"}) +@Internal public class GraphqlErrorHelper { public static Map toSpecification(GraphQLError error) { - Map errorMap = new LinkedHashMap<>(); + Map errorMap = Maps.newLinkedHashMapWithExpectedSize(4); errorMap.put("message", error.getMessage()); if (error.getLocations() != null) { errorMap.put("locations", locations(error.getLocations())); @@ -24,28 +29,119 @@ public static Map toSpecification(GraphQLError error) { if (error.getPath() != null) { errorMap.put("path", error.getPath()); } - if (error.getExtensions() != null) { - errorMap.put("extensions", error.getExtensions()); + + Map extensions = error.getExtensions(); + ErrorClassification errorClassification = error.getErrorType(); + // + // we move the ErrorClassification into extensions which allows + // downstream people to see them but still be spec compliant + if (errorClassification != null) { + if (extensions != null) { + extensions = new LinkedHashMap<>(extensions); + } else { + extensions = new LinkedHashMap<>(); + } + // put in the classification unless it's already there + if (!extensions.containsKey("classification")) { + extensions.put("classification", errorClassification.toSpecification(error)); + } + } + + if (extensions != null) { + errorMap.put("extensions", extensions); } return errorMap; } public static Object locations(List locations) { - return locations.stream().map(GraphqlErrorHelper::location).collect(toList()); + return mapAndDropNulls(locations, GraphqlErrorHelper::location); } + /** + * Positive integers starting from 1 required for error locations, + * from the spec ... + * + * @param location the source location in play + * + * @return a value for source location of the error + */ public static Object location(SourceLocation location) { - Map map = new LinkedHashMap<>(); - map.put("line", location.getLine()); - map.put("column", location.getColumn()); + if (location == null) { + return null; + } + int line = location.getLine(); + int column = location.getColumn(); + if (line < 1 || column < 1) { + return null; + } + Map map = Maps.newLinkedHashMapWithExpectedSize(2); + map.put("line", line); + map.put("column", column); return map; } + static List fromSpecification(List> specificationMaps) { + List list = FpKit.arrayListSizedTo(specificationMaps); + for (Map specificationMap : specificationMaps) { + list.add(fromSpecification(specificationMap)); + } + return list; + } + + static GraphQLError fromSpecification(Map specificationMap) { + GraphQLError.Builder errorBuilder = GraphQLError.newError(); + // builder will enforce not null message + errorBuilder.message((String) specificationMap.get("message")); + extractLocations(errorBuilder, specificationMap); + extractPath(errorBuilder, specificationMap); + extractExtensions(errorBuilder, specificationMap); + return errorBuilder.build(); + } + + private static void extractPath(GraphQLError.Builder errorBuilder, Map rawError) { + List path = (List) rawError.get("path"); + if (path != null) { + errorBuilder.path(path); + } + } + + private static void extractExtensions(GraphQLError.Builder errorBuilder, Map rawError) { + Map extensions = (Map) rawError.get("extensions"); + if (extensions != null) { + errorBuilder.extensions(extensions); + Object classification = extensions.get("classification"); + if (classification != null) { + ErrorClassification errorClassification = ErrorClassification.errorClassification((String) classification); + errorBuilder.errorType(errorClassification); + } + } + + } + + private static void extractLocations(GraphQLError.Builder errorBuilder, Map rawError) { + List locations = (List) rawError.get("locations"); + if (locations != null) { + List sourceLocations = new ArrayList<>(locations.size()); + for (Object locationObj : locations) { + Map location = (Map) locationObj; + if (location != null) { + Integer line = (Integer) location.get("line"); + Integer column = (Integer) location.get("column"); + if (line != null && column != null) { + sourceLocations.add(new SourceLocation(line, column)); + } + } + } + errorBuilder.locations(sourceLocations); + } + } + public static int hashCode(GraphQLError dis) { - int result = dis.getMessage() != null ? dis.getMessage().hashCode() : 0; - result = 31 * result + (dis.getLocations() != null ? dis.getLocations().hashCode() : 0); - result = 31 * result + (dis.getPath() != null ? dis.getPath().hashCode() : 0); - result = 31 * result + dis.getErrorType().hashCode(); + int result = 1; + result = 31 * result + Objects.hashCode(dis.getMessage()); + result = 31 * result + Objects.hashCode(dis.getLocations()); + result = 31 * result + Objects.hashCode(dis.getPath()); + result = 31 * result + Objects.hashCode(dis.getErrorType()); return result; } @@ -53,16 +149,21 @@ public static boolean equals(GraphQLError dis, Object o) { if (dis == o) { return true; } - if (o == null || dis.getClass() != o.getClass()) return false; + if (o == null || dis.getClass() != o.getClass()) { + return false; + } GraphQLError dat = (GraphQLError) o; - if (dis.getMessage() != null ? !dis.getMessage().equals(dat.getMessage()) : dat.getMessage() != null) + if (!Objects.equals(dis.getMessage(), dat.getMessage())) { return false; - if (dis.getLocations() != null ? !dis.getLocations().equals(dat.getLocations()) : dat.getLocations() != null) + } + if (!Objects.equals(dis.getLocations(), dat.getLocations())) { return false; - if (dis.getPath() != null ? !dis.getPath().equals(dat.getPath()) : dat.getPath() != null) + } + if (!Objects.equals(dis.getPath(), dat.getPath())) { return false; + } return dis.getErrorType() == dat.getErrorType(); } } diff --git a/src/main/java/graphql/Internal.java b/src/main/java/graphql/Internal.java index 0e78b82a74..cf9d0c3e4b 100644 --- a/src/main/java/graphql/Internal.java +++ b/src/main/java/graphql/Internal.java @@ -4,8 +4,11 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.TYPE; /** @@ -15,6 +18,6 @@ * In general unnecessary changes will be avoided but you should not depend on internal classes being stable */ @Retention(RetentionPolicy.RUNTIME) -@Target(value = {CONSTRUCTOR, METHOD, TYPE}) -public @interface Internal { +@Target(value = {CONSTRUCTOR, METHOD, TYPE, FIELD, PACKAGE, ANNOTATION_TYPE}) +public @interface Internal { } diff --git a/src/main/java/graphql/InvalidSyntaxError.java b/src/main/java/graphql/InvalidSyntaxError.java index a7fb548a15..69451cb689 100644 --- a/src/main/java/graphql/InvalidSyntaxError.java +++ b/src/main/java/graphql/InvalidSyntaxError.java @@ -2,35 +2,37 @@ import graphql.language.SourceLocation; -import org.antlr.v4.runtime.RecognitionException; import java.util.ArrayList; import java.util.List; +import static java.util.Collections.singletonList; + +@Internal public class InvalidSyntaxError implements GraphQLError { private final String message; + private final String sourcePreview; + private final String offendingToken; private final List locations = new ArrayList<>(); public InvalidSyntaxError(SourceLocation sourceLocation, String msg) { - this.message = mkMessage(msg); - if (sourceLocation != null) { - this.locations.add(sourceLocation); - } + this(singletonList(sourceLocation), msg); } public InvalidSyntaxError(List sourceLocations, String msg) { - this.message = mkMessage(msg); + this(sourceLocations, msg, null, null); + } + + public InvalidSyntaxError(List sourceLocations, String msg, String sourcePreview, String offendingToken) { + this.message = msg; + this.sourcePreview = sourcePreview; + this.offendingToken = offendingToken; if (sourceLocations != null) { this.locations.addAll(sourceLocations); } } - private String mkMessage(String msg) { - return "Invalid Syntax" + (msg == null ? "" : " : " + msg); - } - - @Override public String getMessage() { return message; @@ -41,6 +43,14 @@ public List getLocations() { return locations; } + public String getSourcePreview() { + return sourcePreview; + } + + public String getOffendingToken() { + return offendingToken; + } + @Override public ErrorType getErrorType() { return ErrorType.InvalidSyntax; @@ -50,30 +60,13 @@ public ErrorType getErrorType() { public String toString() { return "InvalidSyntaxError{" + " message=" + message + + " ,offendingToken=" + offendingToken + " ,locations=" + locations + + " ,sourcePreview=" + sourcePreview + '}'; } - /** - * Creates an invalid syntax error object from an exception - * - * @param parseException the parse exception - * - * @return a new invalid syntax error object - */ - public static InvalidSyntaxError toInvalidSyntaxError(Exception parseException) { - String msg = parseException.getMessage(); - SourceLocation sourceLocation = null; - if (parseException.getCause() instanceof RecognitionException) { - RecognitionException recognitionException = (RecognitionException) parseException.getCause(); - msg = recognitionException.getMessage(); - sourceLocation = new SourceLocation(recognitionException.getOffendingToken().getLine(), recognitionException.getOffendingToken().getCharPositionInLine()); - } - return new InvalidSyntaxError(sourceLocation, msg); - } - - @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override public boolean equals(Object o) { diff --git a/src/main/java/graphql/Mutable.java b/src/main/java/graphql/Mutable.java new file mode 100644 index 0000000000..5cc1b30e4c --- /dev/null +++ b/src/main/java/graphql/Mutable.java @@ -0,0 +1,16 @@ +package graphql; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; + +/** + * This marks a type as mutable which means after constructing it can be changed. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = {TYPE,METHOD}) +public @interface Mutable { +} diff --git a/src/main/java/graphql/ParseAndValidate.java b/src/main/java/graphql/ParseAndValidate.java new file mode 100644 index 0000000000..0ecb17947d --- /dev/null +++ b/src/main/java/graphql/ParseAndValidate.java @@ -0,0 +1,134 @@ +package graphql; + +import graphql.language.Document; +import graphql.parser.InvalidSyntaxException; +import graphql.parser.Parser; +import graphql.parser.ParserEnvironment; +import graphql.parser.ParserOptions; +import graphql.schema.GraphQLSchema; +import graphql.validation.ValidationError; +import graphql.validation.Validator; +import org.jspecify.annotations.NonNull; + +import java.util.List; +import java.util.Locale; +import java.util.function.Predicate; + +import static java.util.Optional.ofNullable; + +/** + * This class allows you to parse and validate a graphql query without executing it. It will tell you + * if it's syntactically valid and also semantically valid according to the graphql specification + * and the provided schema. + */ +@PublicApi +public class ParseAndValidate { + + /** + * This {@link GraphQLContext} hint can be used to supply a Predicate to the Validator so that certain rules can be skipped. + * + * This is an internal capability that you should use at your own risk. While we intend for this to be present for some time, the validation + * rule class names may change, as may this mechanism. + */ + @Internal + public static final String INTERNAL_VALIDATION_PREDICATE_HINT = "graphql.ParseAndValidate.Predicate"; + + /** + * This can be called to parse and validate a graphql query against a schema, which is useful if you want to know if it would be acceptable + * for execution. + * + * @param graphQLSchema the schema to validate against + * @param executionInput the execution input containing the query + * + * @return a result object that indicates how this operation went + */ + public static ParseAndValidateResult parseAndValidate(@NonNull GraphQLSchema graphQLSchema, @NonNull ExecutionInput executionInput) { + ParseAndValidateResult result = parse(executionInput); + if (!result.isFailure()) { + List errors = validate(graphQLSchema, result.getDocument(), executionInput.getLocale()); + return result.transform(builder -> builder.validationErrors(errors)); + } + return result; + } + + /** + * This can be called to parse (but not validate) a graphql query. + * + * @param executionInput the input containing the query + * + * @return a result object that indicates how this operation went + */ + public static ParseAndValidateResult parse(@NonNull ExecutionInput executionInput) { + try { + // + // we allow the caller to specify new parser options by context + ParserOptions parserOptions = executionInput.getGraphQLContext().get(ParserOptions.class); + // we use the query parser options by default if they are not specified + parserOptions = ofNullable(parserOptions).orElse(ParserOptions.getDefaultOperationParserOptions()); + Parser parser = new Parser(); + Locale locale = executionInput.getLocale() == null ? Locale.getDefault() : executionInput.getLocale(); + ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment() + .document(executionInput.getQuery()).parserOptions(parserOptions) + .locale(locale) + .build(); + Document document = parser.parseDocument(parserEnvironment); + return ParseAndValidateResult.newResult().document(document).variables(executionInput.getVariables()).build(); + } catch (InvalidSyntaxException e) { + return ParseAndValidateResult.newResult().syntaxException(e).variables(executionInput.getVariables()).build(); + } + } + + /** + * This can be called to validate a parsed graphql query. + * + * @param graphQLSchema the graphql schema to validate against + * @param parsedDocument the previously parsed document + * @param locale the current locale + * + * @return a result object that indicates how this operation went + */ + public static List validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument, @NonNull Locale locale) { + return validate(graphQLSchema, parsedDocument, ruleClass -> true, locale); + } + + /** + * This can be called to validate a parsed graphql query, with the JVM default locale. + * + * @param graphQLSchema the graphql schema to validate against + * @param parsedDocument the previously parsed document + * + * @return a result object that indicates how this operation went + */ + public static List validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument) { + return validate(graphQLSchema, parsedDocument, ruleClass -> true, Locale.getDefault()); + } + + /** + * This can be called to validate a parsed graphql query. + * + * @param graphQLSchema the graphql schema to validate against + * @param parsedDocument the previously parsed document + * @param rulePredicate this predicate is used to decide what validation rules will be applied + * @param locale the current locale + * + * @return a result object that indicates how this operation went + */ + public static List validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument, @NonNull Predicate> rulePredicate, @NonNull Locale locale) { + Validator validator = new Validator(); + return validator.validateDocument(graphQLSchema, parsedDocument, rulePredicate, locale); + } + + /** + * This can be called to validate a parsed graphql query, with the JVM default locale. + * + * @param graphQLSchema the graphql schema to validate against + * @param parsedDocument the previously parsed document + * @param rulePredicate this predicate is used to decide what validation rules will be applied + * + * @return a result object that indicates how this operation went + */ + public static List validate(@NonNull GraphQLSchema graphQLSchema, @NonNull Document parsedDocument, @NonNull Predicate> rulePredicate) { + Validator validator = new Validator(); + return validator.validateDocument(graphQLSchema, parsedDocument, rulePredicate, Locale.getDefault()); + } +} diff --git a/src/main/java/graphql/ParseAndValidateResult.java b/src/main/java/graphql/ParseAndValidateResult.java new file mode 100644 index 0000000000..d7f1332e90 --- /dev/null +++ b/src/main/java/graphql/ParseAndValidateResult.java @@ -0,0 +1,133 @@ +package graphql; + +import graphql.collect.ImmutableKit; +import graphql.execution.instrumentation.DocumentAndVariables; +import graphql.language.Document; +import graphql.parser.InvalidSyntaxException; +import graphql.validation.ValidationError; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +/** + * A result object used in {@link graphql.ParseAndValidate} helper that indicates the outcomes of a parse + * and validate operation. + */ +@PublicApi +public class ParseAndValidateResult { + + private final Document document; + private final Map variables; + private final InvalidSyntaxException syntaxException; + private final List validationErrors; + + private ParseAndValidateResult(Builder builder) { + this.document = builder.document; + this.variables = builder.variables == null ? ImmutableKit.emptyMap() : builder.variables; + this.syntaxException = builder.syntaxException; + this.validationErrors = builder.validationErrors == null ? ImmutableKit.emptyList() : builder.validationErrors; + } + + /** + * @return true if there was a parse exception or the validation failed + */ + public boolean isFailure() { + return syntaxException != null || !validationErrors.isEmpty(); + } + + /** + * @return the parsed document or null if it's syntactically invalid. + */ + public Document getDocument() { + return document; + } + + /** + * @return the document variables or null if it's syntactically invalid. + */ + public Map getVariables() { + return variables; + } + + /** + * @return the parsed document and variables or null if it's syntactically invalid. + */ + public DocumentAndVariables getDocumentAndVariables() { + if (document != null) { + return DocumentAndVariables.newDocumentAndVariables().document(document).variables(variables).build(); + } + return null; + } + + /** + * @return the syntax exception or null if it's syntactically valid. + */ + public InvalidSyntaxException getSyntaxException() { + return syntaxException; + } + + /** + * @return a list of validation errors, which might be empty if it's syntactically invalid. + */ + public List getValidationErrors() { + return validationErrors; + } + + /** + * A list of all the errors (parse and validate) that have occurred + * + * @return the errors that have occurred or empty list if there are none + */ + public List getErrors() { + List errors = new ArrayList<>(); + if (syntaxException != null) { + errors.add(syntaxException.toInvalidSyntaxError()); + } + errors.addAll(validationErrors); + return errors; + } + + public ParseAndValidateResult transform(Consumer builderConsumer) { + Builder builder = new Builder() + .document(document).variables(variables).syntaxException(syntaxException).validationErrors(validationErrors); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newResult() { + return new Builder(); + } + + public static class Builder { + private Document document; + private Map variables = ImmutableKit.emptyMap(); + private InvalidSyntaxException syntaxException; + private List validationErrors = ImmutableKit.emptyList(); + + public Builder document(Document document) { + this.document = document; + return this; + } + + public Builder variables(Map variables) { + this.variables = variables; + return this; + } + + public Builder validationErrors(List validationErrors) { + this.validationErrors = validationErrors; + return this; + } + + public Builder syntaxException(InvalidSyntaxException syntaxException) { + this.syntaxException = syntaxException; + return this; + } + + public ParseAndValidateResult build() { + return new ParseAndValidateResult(this); + } + } +} diff --git a/src/main/java/graphql/Profiler.java b/src/main/java/graphql/Profiler.java new file mode 100644 index 0000000000..cdfed60638 --- /dev/null +++ b/src/main/java/graphql/Profiler.java @@ -0,0 +1,59 @@ +package graphql; + +import graphql.execution.EngineRunningObserver; +import graphql.execution.ResultPath; +import graphql.execution.instrumentation.Instrumentation; +import graphql.language.OperationDefinition; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLOutputType; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@Internal +@NullMarked +public interface Profiler { + + + Profiler NO_OP = new Profiler() { + }; + + + default void setExecutionInputAndInstrumentation(ExecutionInput executionInput, Instrumentation instrumentation) { + + } + + default void dataLoaderUsed(String dataLoaderName) { + + + } + + default void fieldFetched(Object fetchedObject, DataFetcher originalDataFetcher, DataFetcher dataFetcher, ResultPath path, GraphQLFieldDefinition fieldDef, GraphQLOutputType parentType) { + + } + + default @Nullable EngineRunningObserver wrapEngineRunningObserver(@Nullable EngineRunningObserver engineRunningObserver) { + return engineRunningObserver; + } + + default void operationDefinition(OperationDefinition operationDefinition) { + + } + + default void oldStrategyDispatchingAll(int level) { + + } + + default void batchLoadedOldStrategy(String name, int level, int count) { + + } + + + default void batchLoadedNewStrategy(String dataLoaderName, Integer level, int count, boolean delayed, boolean chained) { + + } + + default void manualDispatch(String dataLoaderName, int level, int count) { + + } +} diff --git a/src/main/java/graphql/ProfilerImpl.java b/src/main/java/graphql/ProfilerImpl.java new file mode 100644 index 0000000000..1f42c6781d --- /dev/null +++ b/src/main/java/graphql/ProfilerImpl.java @@ -0,0 +1,172 @@ +package graphql; + +import graphql.execution.EngineRunningObserver; +import graphql.execution.ExecutionId; +import graphql.execution.ResultPath; +import graphql.execution.instrumentation.ChainedInstrumentation; +import graphql.execution.instrumentation.Instrumentation; +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys; +import graphql.introspection.Introspection; +import graphql.language.OperationDefinition; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.PropertyDataFetcher; +import graphql.schema.SingletonPropertyDataFetcher; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicLong; + +@Internal +@NullMarked +public class ProfilerImpl implements Profiler { + + private volatile long startTime; + private volatile long endTime; + private volatile long lastStartTime; + private final AtomicLong engineTotalRunningTime = new AtomicLong(); + + final ProfilerResult profilerResult = new ProfilerResult(); + + public ProfilerImpl(GraphQLContext graphQLContext) { + // No real work can happen here, since the engine didn't "officially" start yet. + graphQLContext.put(ProfilerResult.PROFILER_CONTEXT_KEY, profilerResult); + } + + @Override + public void setExecutionInputAndInstrumentation(ExecutionInput executionInput, Instrumentation instrumentation) { + profilerResult.setExecutionId(executionInput.getExecutionIdNonNull()); + boolean dataLoaderChainingEnabled = executionInput.getGraphQLContext().getBoolean(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, false); + profilerResult.setDataLoaderChainingEnabled(dataLoaderChainingEnabled); + + List instrumentationClasses = new ArrayList<>(); + collectInstrumentationClasses(instrumentationClasses, instrumentation); + profilerResult.setInstrumentationClasses(instrumentationClasses); + } + + private void collectInstrumentationClasses(List result, Instrumentation instrumentation) { + if (instrumentation instanceof ChainedInstrumentation) { + ChainedInstrumentation chainedInstrumentation = (ChainedInstrumentation) instrumentation; + for (Instrumentation child : chainedInstrumentation.getInstrumentations()) { + collectInstrumentationClasses(result, child); + } + } else { + result.add(instrumentation.getClass().getName()); + } + } + + + @Override + public void fieldFetched(Object fetchedObject, DataFetcher originalDataFetcher, DataFetcher dataFetcher, ResultPath path, GraphQLFieldDefinition fieldDef, GraphQLOutputType parentType) { + String key = "/" + String.join("/", path.getKeysOnly()); + if (Introspection.isIntrospectionTypes(GraphQLTypeUtil.unwrapAll(fieldDef.getType())) + || Introspection.isIntrospectionTypes(GraphQLTypeUtil.unwrapAll(parentType)) + || fieldDef.getName().equals(Introspection.SchemaMetaFieldDef.getName()) + || fieldDef.getName().equals(Introspection.TypeMetaFieldDef.getName()) + || fieldDef.getName().equals(Introspection.TypeNameMetaFieldDef.getName())) { + return; + } + profilerResult.addFieldFetched(key); + profilerResult.incrementDataFetcherInvocationCount(key); + ProfilerResult.DataFetcherType dataFetcherType; + if (dataFetcher instanceof PropertyDataFetcher || dataFetcher instanceof SingletonPropertyDataFetcher) { + dataFetcherType = ProfilerResult.DataFetcherType.TRIVIAL_DATA_FETCHER; + } else if (originalDataFetcher instanceof PropertyDataFetcher || originalDataFetcher instanceof SingletonPropertyDataFetcher) { + dataFetcherType = ProfilerResult.DataFetcherType.WRAPPED_TRIVIAL_DATA_FETCHER; + } else { + dataFetcherType = ProfilerResult.DataFetcherType.CUSTOM; + // we only record the type of the result if it is not a PropertyDataFetcher + ProfilerResult.DataFetcherResultType dataFetcherResultType; + if (fetchedObject instanceof CompletableFuture) { + CompletableFuture completableFuture = (CompletableFuture) fetchedObject; + if (completableFuture.isDone()) { + dataFetcherResultType = ProfilerResult.DataFetcherResultType.COMPLETABLE_FUTURE_COMPLETED; + } else { + dataFetcherResultType = ProfilerResult.DataFetcherResultType.COMPLETABLE_FUTURE_NOT_COMPLETED; + } + } else { + dataFetcherResultType = ProfilerResult.DataFetcherResultType.MATERIALIZED; + } + profilerResult.setDataFetcherResultType(key, dataFetcherResultType); + } + + profilerResult.setDataFetcherType(key, dataFetcherType); + } + + @Override + public EngineRunningObserver wrapEngineRunningObserver(@Nullable EngineRunningObserver engineRunningObserver) { + // nothing to wrap here + return new EngineRunningObserver() { + @Override + public void runningStateChanged(@Nullable ExecutionId executionId, GraphQLContext graphQLContext, RunningState runningState) { + runningStateChangedImpl(executionId, graphQLContext, runningState); + if (engineRunningObserver != null) { + engineRunningObserver.runningStateChanged(executionId, graphQLContext, runningState); + } + } + }; + } + + private void runningStateChangedImpl(@Nullable ExecutionId executionId, GraphQLContext graphQLContext, EngineRunningObserver.RunningState runningState) { + long now = System.nanoTime(); + if (runningState == EngineRunningObserver.RunningState.RUNNING_START) { + startTime = now; + lastStartTime = startTime; + } else if (runningState == EngineRunningObserver.RunningState.NOT_RUNNING_FINISH) { + endTime = now; + engineTotalRunningTime.set(engineTotalRunningTime.get() + (endTime - lastStartTime)); + profilerResult.setTimes(startTime, endTime, engineTotalRunningTime.get()); + } else if (runningState == EngineRunningObserver.RunningState.RUNNING) { + lastStartTime = now; + } else if (runningState == EngineRunningObserver.RunningState.NOT_RUNNING) { + engineTotalRunningTime.set(engineTotalRunningTime.get() + (now - lastStartTime)); + } else { + Assert.assertShouldNeverHappen(); + } + } + + @Override + public void operationDefinition(OperationDefinition operationDefinition) { + profilerResult.setOperation(operationDefinition); + } + + @Override + public void dataLoaderUsed(String dataLoaderName) { + profilerResult.addDataLoaderUsed(dataLoaderName); + } + + @Override + public void oldStrategyDispatchingAll(int level) { + profilerResult.oldStrategyDispatchingAll(level); + } + + @Override + public void batchLoadedOldStrategy(String name, int level, int count) { + profilerResult.addDispatchEvent(name, level, count, ProfilerResult.DispatchEventType.LEVEL_STRATEGY_DISPATCH); + } + + @Override + public void batchLoadedNewStrategy(String dataLoaderName, Integer level, int count, boolean delayed, boolean chained) { + ProfilerResult.DispatchEventType dispatchEventType = null; + if (delayed && !chained) { + dispatchEventType = ProfilerResult.DispatchEventType.DELAYED_DISPATCH; + } else if (delayed) { + dispatchEventType = ProfilerResult.DispatchEventType.CHAINED_DELAYED_DISPATCH; + } else if (!chained) { + dispatchEventType = ProfilerResult.DispatchEventType.LEVEL_STRATEGY_DISPATCH; + } else { + dispatchEventType = ProfilerResult.DispatchEventType.CHAINED_STRATEGY_DISPATCH; + } + profilerResult.addDispatchEvent(dataLoaderName, level, count, dispatchEventType); + } + + @Override + public void manualDispatch(String dataLoaderName, int level, int count) { + profilerResult.addDispatchEvent(dataLoaderName, level, count, ProfilerResult.DispatchEventType.MANUAL_DISPATCH); + } +} diff --git a/src/main/java/graphql/ProfilerResult.java b/src/main/java/graphql/ProfilerResult.java new file mode 100644 index 0000000000..c18533ab7a --- /dev/null +++ b/src/main/java/graphql/ProfilerResult.java @@ -0,0 +1,347 @@ +package graphql; + +import graphql.execution.ExecutionId; +import graphql.language.OperationDefinition; +import graphql.language.OperationDefinition.Operation; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +@ExperimentalApi +@NullMarked +public class ProfilerResult { + + public static final String PROFILER_CONTEXT_KEY = "__GJ_PROFILER"; + + @Nullable + private volatile ExecutionId executionId; + private long startTime; + private long endTime; + private long engineTotalRunningTime; + private final AtomicInteger totalDataFetcherInvocations = new AtomicInteger(); + private final AtomicInteger totalTrivialDataFetcherInvocations = new AtomicInteger(); + private final AtomicInteger totalWrappedTrivialDataFetcherInvocations = new AtomicInteger(); + + // this is the count of how many times a data loader was invoked per data loader name + private final Map dataLoaderLoadInvocations = new ConcurrentHashMap<>(); + + @Nullable + private volatile String operationName; + @Nullable + private volatile Operation operationType; + private volatile boolean dataLoaderChainingEnabled; + private final Set oldStrategyDispatchingAll = ConcurrentHashMap.newKeySet(); + + private final List instrumentationClasses = Collections.synchronizedList(new ArrayList<>()); + + private final List dispatchEvents = Collections.synchronizedList(new ArrayList<>()); + + /** + * the following fields can contain a lot of data for large requests + */ + // all fields fetched during the execution, key is the field path + private final Set fieldsFetched = ConcurrentHashMap.newKeySet(); + // this is the count of how many times a data fetcher was invoked per field + private final Map dataFetcherInvocationCount = new ConcurrentHashMap<>(); + // the type of the data fetcher per field, key is the field path + private final Map dataFetcherTypeMap = new ConcurrentHashMap<>(); + // the type of the data fetcher result field, key is the field path + // in theory different DataFetcher invocations can return different types, but we only record the first one + private final Map dataFetcherResultType = new ConcurrentHashMap<>(); + + public void setInstrumentationClasses(List instrumentationClasses) { + this.instrumentationClasses.addAll(instrumentationClasses); + } + + + public enum DispatchEventType { + LEVEL_STRATEGY_DISPATCH, + CHAINED_STRATEGY_DISPATCH, + DELAYED_DISPATCH, + CHAINED_DELAYED_DISPATCH, + MANUAL_DISPATCH, + } + + public static class DispatchEvent { + final String dataLoaderName; + final Integer level; // is null for delayed dispatching + final int keyCount; // how many + final DispatchEventType type; + + public DispatchEvent(String dataLoaderName, Integer level, int keyCount, DispatchEventType type) { + this.dataLoaderName = dataLoaderName; + this.level = level; + this.keyCount = keyCount; + this.type = type; + } + + public String getDataLoaderName() { + return dataLoaderName; + } + + public Integer getLevel() { + return level; + } + + public int getKeyCount() { + return keyCount; + } + + public DispatchEventType getType() { + return type; + } + + @Override + public String toString() { + return "DispatchEvent{" + + "type=" + type + + ", dataLoaderName='" + dataLoaderName + '\'' + + ", level=" + level + + ", keyCount=" + keyCount + + '}'; + } + } + + public enum DataFetcherType { + WRAPPED_TRIVIAL_DATA_FETCHER, + TRIVIAL_DATA_FETCHER, + CUSTOM + } + + public enum DataFetcherResultType { + COMPLETABLE_FUTURE_COMPLETED, + COMPLETABLE_FUTURE_NOT_COMPLETED, + MATERIALIZED + + } + + + // setters are package private to prevent exposure + + void setDataLoaderChainingEnabled(boolean dataLoaderChainingEnabled) { + this.dataLoaderChainingEnabled = dataLoaderChainingEnabled; + } + + + void setDataFetcherType(String key, DataFetcherType dataFetcherType) { + dataFetcherTypeMap.putIfAbsent(key, dataFetcherType); + totalDataFetcherInvocations.incrementAndGet(); + if (dataFetcherType == DataFetcherType.TRIVIAL_DATA_FETCHER) { + totalTrivialDataFetcherInvocations.incrementAndGet(); + } else if (dataFetcherType == DataFetcherType.WRAPPED_TRIVIAL_DATA_FETCHER) { + totalWrappedTrivialDataFetcherInvocations.incrementAndGet(); + } + } + + void setDataFetcherResultType(String key, DataFetcherResultType fetchedType) { + dataFetcherResultType.putIfAbsent(key, fetchedType); + } + + void incrementDataFetcherInvocationCount(String key) { + dataFetcherInvocationCount.compute(key, (k, v) -> v == null ? 1 : v + 1); + } + + void addFieldFetched(String fieldPath) { + fieldsFetched.add(fieldPath); + } + + void setExecutionId(ExecutionId executionId) { + this.executionId = executionId; + } + + void setTimes(long startTime, long endTime, long engineTotalRunningTime) { + this.startTime = startTime; + this.endTime = endTime; + this.engineTotalRunningTime = engineTotalRunningTime; + } + + void setOperation(OperationDefinition operationDefinition) { + this.operationName = operationDefinition.getName(); + this.operationType = operationDefinition.getOperation(); + } + + void addDataLoaderUsed(String dataLoaderName) { + dataLoaderLoadInvocations.compute(dataLoaderName, (k, v) -> v == null ? 1 : v + 1); + } + + void oldStrategyDispatchingAll(int level) { + oldStrategyDispatchingAll.add(level); + } + + + void addDispatchEvent(String dataLoaderName, Integer level, int count, DispatchEventType type) { + dispatchEvents.add(new DispatchEvent(dataLoaderName, level, count, type)); + } + + // public getters + + public @Nullable String getOperationName() { + return operationName; + } + + public Operation getOperationType() { + return Assert.assertNotNull(operationType); + } + + public Set getFieldsFetched() { + return fieldsFetched; + } + + public Set getCustomDataFetcherFields() { + Set result = new LinkedHashSet<>(fieldsFetched); + for (String field : fieldsFetched) { + if (dataFetcherTypeMap.get(field) == DataFetcherType.CUSTOM) { + result.add(field); + } + } + return result; + } + + public Set getTrivialDataFetcherFields() { + Set result = new LinkedHashSet<>(fieldsFetched); + for (String field : fieldsFetched) { + if (dataFetcherTypeMap.get(field) == DataFetcherType.TRIVIAL_DATA_FETCHER) { + result.add(field); + } + } + return result; + } + + + public int getTotalDataFetcherInvocations() { + return totalDataFetcherInvocations.get(); + } + + public int getTotalTrivialDataFetcherInvocations() { + return totalTrivialDataFetcherInvocations.get(); + } + + public int getTotalCustomDataFetcherInvocations() { + return totalDataFetcherInvocations.get() - totalTrivialDataFetcherInvocations.get() - totalWrappedTrivialDataFetcherInvocations.get(); + } + + public long getStartTime() { + return startTime; + } + + public long getEndTime() { + return endTime; + } + + public long getEngineTotalRunningTime() { + return engineTotalRunningTime; + } + + public long getTotalExecutionTime() { + return endTime - startTime; + } + + public Map getDataFetcherResultType() { + return dataFetcherResultType; + } + + public Map getDataLoaderLoadInvocations() { + return dataLoaderLoadInvocations; + } + + + public Set getOldStrategyDispatchingAll() { + return oldStrategyDispatchingAll; + } + + public boolean isDataLoaderChainingEnabled() { + return dataLoaderChainingEnabled; + } + + public List getDispatchEvents() { + return dispatchEvents; + } + + public List getInstrumentationClasses() { + return instrumentationClasses; + } + + + public Map shortSummaryMap() { + Map result = new LinkedHashMap<>(); + result.put("executionId", Assert.assertNotNull(executionId).toString()); + result.put("operationName", operationName); + result.put("operationType", Assert.assertNotNull(operationType).toString()); + result.put("startTimeNs", startTime); + result.put("endTimeNs", endTime); + result.put("totalRunTimeNs", endTime - startTime); + result.put("engineTotalRunningTimeNs", engineTotalRunningTime); + result.put("totalDataFetcherInvocations", totalDataFetcherInvocations); + result.put("totalCustomDataFetcherInvocations", getTotalCustomDataFetcherInvocations()); + result.put("totalTrivialDataFetcherInvocations", totalTrivialDataFetcherInvocations); + result.put("totalWrappedTrivialDataFetcherInvocations", totalWrappedTrivialDataFetcherInvocations); + result.put("fieldsFetchedCount", fieldsFetched.size()); + result.put("dataLoaderChainingEnabled", dataLoaderChainingEnabled); + result.put("dataLoaderLoadInvocations", dataLoaderLoadInvocations); + result.put("oldStrategyDispatchingAll", oldStrategyDispatchingAll); + result.put("dispatchEvents", getDispatchEventsAsMap()); + result.put("instrumentationClasses", instrumentationClasses); + int completedCount = 0; + int completedInvokeCount = 0; + int notCompletedCount = 0; + int notCompletedInvokeCount = 0; + int materializedCount = 0; + int materializedInvokeCount = 0; + for (String field : dataFetcherResultType.keySet()) { + DataFetcherResultType dFRT = dataFetcherResultType.get(field); + if (dFRT == DataFetcherResultType.COMPLETABLE_FUTURE_COMPLETED) { + completedInvokeCount += Assert.assertNotNull(dataFetcherInvocationCount.get(field)); + completedCount++; + } else if (dFRT == DataFetcherResultType.COMPLETABLE_FUTURE_NOT_COMPLETED) { + notCompletedInvokeCount += Assert.assertNotNull(dataFetcherInvocationCount.get(field)); + notCompletedCount++; + } else if (dFRT == DataFetcherResultType.MATERIALIZED) { + materializedInvokeCount += Assert.assertNotNull(dataFetcherInvocationCount.get(field)); + materializedCount++; + } else { + Assert.assertShouldNeverHappen(); + } + } + LinkedHashMap dFRTinfo = new LinkedHashMap<>(3); + dFRTinfo.put(DataFetcherResultType.COMPLETABLE_FUTURE_COMPLETED.name(), createCountMap(completedCount, completedInvokeCount)); + dFRTinfo.put(DataFetcherResultType.COMPLETABLE_FUTURE_NOT_COMPLETED.name(), createCountMap(notCompletedCount, notCompletedInvokeCount)); + dFRTinfo.put(DataFetcherResultType.MATERIALIZED.name(), createCountMap(materializedCount, materializedInvokeCount)); + result.put("dataFetcherResultTypes", dFRTinfo); + return result; + } + + private LinkedHashMap createCountMap(int count, int invocations) { + LinkedHashMap map = new LinkedHashMap<>(2); + map.put("count", count); + map.put("invocations", invocations); + return map; + } + + public List> getDispatchEventsAsMap() { + List> result = new ArrayList<>(); + for (DispatchEvent event : dispatchEvents) { + Map eventMap = new LinkedHashMap<>(); + eventMap.put("type", event.getType().name()); + eventMap.put("dataLoader", event.getDataLoaderName()); + eventMap.put("level", event.getLevel()); + eventMap.put("keyCount", event.getKeyCount()); + result.add(eventMap); + } + return result; + } + + @Override + public String toString() { + return "ProfilerResult" + shortSummaryMap(); + } + +} diff --git a/src/main/java/graphql/PublicApi.java b/src/main/java/graphql/PublicApi.java index 30cb05a2dd..73290b8aa3 100644 --- a/src/main/java/graphql/PublicApi.java +++ b/src/main/java/graphql/PublicApi.java @@ -6,6 +6,7 @@ import java.lang.annotation.Target; import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; @@ -17,7 +18,7 @@ * maybe be added which would break derivations but not callers. */ @Retention(RetentionPolicy.RUNTIME) -@Target(value = {CONSTRUCTOR, METHOD, TYPE}) +@Target(value = {CONSTRUCTOR, METHOD, TYPE, FIELD}) @Documented public @interface PublicApi { } diff --git a/src/main/java/graphql/PublicSpi.java b/src/main/java/graphql/PublicSpi.java index 597fe94f2c..1b05060ccb 100644 --- a/src/main/java/graphql/PublicSpi.java +++ b/src/main/java/graphql/PublicSpi.java @@ -15,7 +15,7 @@ * * The guarantee is for callers of code with this annotation as well as derivations that inherit / implement this code. * - * New methods will not be added (without using default methods say) that would nominally breaks SPI implementations + * New methods will not be added (without using default methods say) that would nominally break SPI implementations * within a major release. */ @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/graphql/Scalars.java b/src/main/java/graphql/Scalars.java index bce3b2e92a..25f9dc640c 100644 --- a/src/main/java/graphql/Scalars.java +++ b/src/main/java/graphql/Scalars.java @@ -1,712 +1,59 @@ package graphql; -import graphql.language.BooleanValue; -import graphql.language.FloatValue; -import graphql.language.IntValue; -import graphql.language.StringValue; -import graphql.schema.Coercing; -import graphql.schema.CoercingParseLiteralException; -import graphql.schema.CoercingParseValueException; -import graphql.schema.CoercingSerializeException; +import graphql.scalar.GraphqlBooleanCoercing; +import graphql.scalar.GraphqlFloatCoercing; +import graphql.scalar.GraphqlIDCoercing; +import graphql.scalar.GraphqlIntCoercing; +import graphql.scalar.GraphqlStringCoercing; import graphql.schema.GraphQLScalarType; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.UUID; - -import static graphql.Assert.assertShouldNeverHappen; - /** * This contains the implementations of the Scalar types that ship with graphql-java. Some are proscribed * by the graphql specification (Int, Float, String, Boolean and ID) while others are offer because they are common on * Java platforms. - * - * For more info see http://graphql.org/learn/schema/#scalar-types and more specifically http://facebook.github.io/graphql/#sec-Scalars + *

+ * For more info see https://graphql.org/learn/schema/#scalar-types and + * more specifically https://spec.graphql.org/draft/#sec-Scalars */ +@PublicApi public class Scalars { - private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE); - private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE); - private static final BigInteger INT_MAX = BigInteger.valueOf(Integer.MAX_VALUE); - private static final BigInteger INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE); - private static final BigInteger BYTE_MAX = BigInteger.valueOf(Byte.MAX_VALUE); - private static final BigInteger BYTE_MIN = BigInteger.valueOf(Byte.MIN_VALUE); - private static final BigInteger SHORT_MAX = BigInteger.valueOf(Short.MAX_VALUE); - private static final BigInteger SHORT_MIN = BigInteger.valueOf(Short.MIN_VALUE); - - - private static boolean isNumberIsh(Object input) { - return input instanceof Number || input instanceof String; - } - - private static String typeName(Object input) { - if (input == null) { - return "null"; - } - - return input.getClass().getSimpleName(); - } - /** - * This represents the "Int" type as defined in the graphql specification : http://facebook.github.io/graphql/#sec-Int - * + * This represents the "Int" type as defined in the graphql specification : https://spec.graphql.org/October2021/#sec-Int + *

* The Int scalar type represents a signed 32‐bit numeric non‐fractional value. */ - public static final GraphQLScalarType GraphQLInt = new GraphQLScalarType("Int", "Built-in Int", new Coercing() { - - private Integer convertImpl(Object input) { - if (input instanceof Integer) { - return (Integer) input; - } else if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - try { - return value.intValueExact(); - } catch (ArithmeticException e) { - return null; - } - } else { - return null; - } - } - - @Override - public Integer serialize(Object input) { - Integer result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Int' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Integer parseValue(Object input) { - Integer result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Int' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Integer parseLiteral(Object input) { - if (!(input instanceof IntValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue' but was '" + typeName(input) + "'." - ); - } - BigInteger value = ((IntValue) input).getValue(); - if (value.compareTo(INT_MIN) < 0 || value.compareTo(INT_MAX) > 0) { - throw new CoercingParseLiteralException( - "Expected value to be in the Integer range but it was '" + value.toString() + "'" - ); - } - return value.intValue(); - } - }); + public static final GraphQLScalarType GraphQLInt = GraphQLScalarType.newScalar() + .name("Int").description("Built-in Int").coercing(new GraphqlIntCoercing()).build(); /** - * This represents the "Float" type as defined in the graphql specification : http://facebook.github.io/graphql/#sec-Float - * + * This represents the "Float" type as defined in the graphql specification : https://spec.graphql.org/October2021/#sec-Float + *

* Note: The Float type in GraphQL is equivalent to Double in Java. (double precision IEEE 754) */ - public static final GraphQLScalarType GraphQLFloat = new GraphQLScalarType("Float", "Built-in Float", new Coercing() { - - private Double convertImpl(Object input) { - if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - return value.doubleValue(); - } else { - return null; - } - - } - - @Override - public Double serialize(Object input) { - Double result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Float' but was '" + typeName(input) + "'." - ); - } - return result; - - } - - @Override - public Double parseValue(Object input) { - Double result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Float' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Double parseLiteral(Object input) { - if (input instanceof IntValue) { - return ((IntValue) input).getValue().doubleValue(); - } else if (input instanceof FloatValue) { - return ((FloatValue) input).getValue().doubleValue(); - } else { - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue' or 'FloatValue' but was '" + typeName(input) + "'." - ); - } - } - }); + public static final GraphQLScalarType GraphQLFloat = GraphQLScalarType.newScalar() + .name("Float").description("Built-in Float").coercing(new GraphqlFloatCoercing()).build(); /** - * This represents the "String" type as defined in the graphql specification : http://facebook.github.io/graphql/#sec-String + * This represents the "String" type as defined in the graphql specification : https://spec.graphql.org/October2021/#sec-String */ - public static final GraphQLScalarType GraphQLString = new GraphQLScalarType("String", "Built-in String", new Coercing() { - @Override - public String serialize(Object input) { - return input.toString(); - } - - @Override - public String parseValue(Object input) { - return serialize(input); - } - - @Override - public String parseLiteral(Object input) { - if (!(input instanceof StringValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'StringValue' but was '" + typeName(input) + "'." - ); - } - return ((StringValue) input).getValue(); - } - }); + public static final GraphQLScalarType GraphQLString = GraphQLScalarType.newScalar() + .name("String").description("Built-in String").coercing(new GraphqlStringCoercing()).build(); /** - * This represents the "Boolean" type as defined in the graphql specification : http://facebook.github.io/graphql/#sec-Boolean + * This represents the "Boolean" type as defined in the graphql specification : https://spec.graphql.org/October2021/#sec-Boolean */ - public static final GraphQLScalarType GraphQLBoolean = new GraphQLScalarType("Boolean", "Built-in Boolean", new Coercing() { - - private Boolean convertImpl(Object input) { - if (input instanceof Boolean) { - return (Boolean) input; - } else if (input instanceof String) { - return Boolean.parseBoolean((String) input); - } else if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - // this should never happen because String is handled above - return assertShouldNeverHappen(); - } - return value.compareTo(BigDecimal.ZERO) != 0; - } else { - return null; - } - - } - - @Override - public Boolean serialize(Object input) { - Boolean result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Boolean' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Boolean parseValue(Object input) { - Boolean result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Boolean' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Boolean parseLiteral(Object input) { - if (!(input instanceof BooleanValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'BooleanValue' but was '" + typeName(input) + "'." - ); - } - return ((BooleanValue) input).isValue(); - } - }); + public static final GraphQLScalarType GraphQLBoolean = GraphQLScalarType.newScalar() + .name("Boolean").description("Built-in Boolean").coercing(new GraphqlBooleanCoercing()).build(); /** - * This represents the "ID" type as defined in the graphql specification : http://facebook.github.io/graphql/#sec-ID - * + * This represents the "ID" type as defined in the graphql specification : https://spec.graphql.org/October2021/#sec-ID + *

* The ID scalar type represents a unique identifier, often used to re-fetch an object or as the key for a cache. The * ID type is serialized in the same way as a String; however, it is not intended to be human‐readable. While it is * often numeric, it should always serialize as a String. */ - public static final GraphQLScalarType GraphQLID = new GraphQLScalarType("ID", "Built-in ID", new Coercing() { - - private String convertImpl(Object input) { - if (input instanceof String) { - return (String) input; - } - if (input instanceof Integer) { - return String.valueOf(input); - } - if (input instanceof Long) { - return String.valueOf(input); - } - if (input instanceof UUID) { - return String.valueOf(input); - } - return null; - - } - - @Override - public String serialize(Object input) { - String result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'ID' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public String parseValue(Object input) { - String result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'ID' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public String parseLiteral(Object input) { - if (input instanceof StringValue) { - return ((StringValue) input).getValue(); - } - if (input instanceof IntValue) { - return ((IntValue) input).getValue().toString(); - } - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue' or 'StringValue' but was '" + typeName(input) + "'." - ); - } - }); - - /** - * This represents the "Long" type which is a representation of java.lang.Long - */ - public static final GraphQLScalarType GraphQLLong = new GraphQLScalarType("Long", "Long type", new Coercing() { - - private Long convertImpl(Object input) { - if (input instanceof Long) { - return (Long) input; - } else if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - try { - return value.longValueExact(); - } catch (ArithmeticException e) { - return null; - } - } else { - return null; - } - - } - - @Override - public Long serialize(Object input) { - Long result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Long' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Long parseValue(Object input) { - Long result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Long' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Long parseLiteral(Object input) { - if (input instanceof StringValue) { - try { - return Long.parseLong(((StringValue) input).getValue()); - } catch (NumberFormatException e) { - throw new CoercingParseLiteralException( - "Expected value to be a Long but it was '" + String.valueOf(input) + "'" - ); - } - } else if (input instanceof IntValue) { - BigInteger value = ((IntValue) input).getValue(); - if (value.compareTo(LONG_MIN) < 0 || value.compareTo(LONG_MAX) > 0) { - throw new CoercingParseLiteralException( - "Expected value to be in the Long range but it was '" + value.toString() + "'" - ); - } - return value.longValue(); - } - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue' or 'StringValue' but was '" + typeName(input) + "'." - ); - } - }); - - /** - * This represents the "Short" type which is a representation of java.lang.Short - */ - public static final GraphQLScalarType GraphQLShort = new GraphQLScalarType("Short", "Built-in Short as Int", new Coercing() { - - private Short convertImpl(Object input) { - if (input instanceof Short) { - return (Short) input; - } else if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - try { - return value.shortValueExact(); - } catch (ArithmeticException e) { - return null; - } - } else { - return null; - } - - } - - @Override - public Short serialize(Object input) { - Short result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Short' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Short parseValue(Object input) { - Short result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Short' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Short parseLiteral(Object input) { - if (!(input instanceof IntValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue' but was '" + typeName(input) + "'." - ); - } - BigInteger value = ((IntValue) input).getValue(); - if (value.compareTo(SHORT_MIN) < 0 || value.compareTo(SHORT_MAX) > 0) { - throw new CoercingParseLiteralException( - "Expected value to be in the Short range but it was '" + value.toString() + "'" - ); - } - return value.shortValue(); - } - }); - - /** - * This represents the "Byte" type which is a representation of java.lang.Byte - */ - public static final GraphQLScalarType GraphQLByte = new GraphQLScalarType("Byte", "Built-in Byte as Int", new Coercing() { - - private Byte convertImpl(Object input) { - if (input instanceof Byte) { - return (Byte) input; - } else if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - try { - return value.byteValueExact(); - } catch (ArithmeticException e) { - return null; - } - } else { - return null; - } - - } - - @Override - public Byte serialize(Object input) { - Byte result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Byte' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Byte parseValue(Object input) { - Byte result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Byte' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Byte parseLiteral(Object input) { - if (!(input instanceof IntValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue' but was '" + typeName(input) + "'." - ); - } - BigInteger value = ((IntValue) input).getValue(); - if (value.compareTo(BYTE_MIN) < 0 || value.compareTo(BYTE_MAX) > 0) { - throw new CoercingParseLiteralException( - "Expected value to be in the Byte range but it was '" + value.toString() + "'" - ); - } - return value.byteValue(); - } - }); - - - /** - * This represents the "BigInteger" type which is a representation of java.math.BigInteger - */ - public static final GraphQLScalarType GraphQLBigInteger = new GraphQLScalarType("BigInteger", "Built-in java.math.BigInteger", new Coercing() { - - private BigInteger convertImpl(Object input) { - if (isNumberIsh(input)) { - BigDecimal value; - try { - value = new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - try { - return value.toBigIntegerExact(); - } catch (ArithmeticException e) { - return null; - } - } - return null; - - } - - @Override - public BigInteger serialize(Object input) { - BigInteger result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'BigInteger' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public BigInteger parseValue(Object input) { - BigInteger result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'BigInteger' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public BigInteger parseLiteral(Object input) { - if (input instanceof StringValue) { - try { - return new BigDecimal(((StringValue) input).getValue()).toBigIntegerExact(); - } catch (NumberFormatException | ArithmeticException e) { - throw new CoercingParseLiteralException( - "Unable to turn AST input into a 'BigInteger' : '" + String.valueOf(input) + "'" - ); - } - } else if (input instanceof IntValue) { - return ((IntValue) input).getValue(); - } else if (input instanceof FloatValue) { - try { - return ((FloatValue) input).getValue().toBigIntegerExact(); - } catch (ArithmeticException e) { - throw new CoercingParseLiteralException( - "Unable to turn AST input into a 'BigInteger' : '" + String.valueOf(input) + "'" - ); - } - } - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue', 'StringValue' or 'FloatValue' but was '" + typeName(input) + "'." - ); - } - }); - - /** - * This represents the "BigDecimal" type which is a representation of java.math.BigDecimal - */ - public static final GraphQLScalarType GraphQLBigDecimal = new GraphQLScalarType("BigDecimal", "Built-in java.math.BigDecimal", new Coercing() { - - private BigDecimal convertImpl(Object input) { - if (isNumberIsh(input)) { - try { - return new BigDecimal(input.toString()); - } catch (NumberFormatException e) { - return null; - } - } - return null; - - } - - @Override - public BigDecimal serialize(Object input) { - BigDecimal result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'BigDecimal' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public BigDecimal parseValue(Object input) { - BigDecimal result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'BigDecimal' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public BigDecimal parseLiteral(Object input) { - if (input instanceof StringValue) { - try { - return new BigDecimal(((StringValue) input).getValue()); - } catch (NumberFormatException e) { - throw new CoercingParseLiteralException( - "Unable to turn AST input into a 'BigDecimal' : '" + String.valueOf(input) + "'" - ); - } - } else if (input instanceof IntValue) { - return new BigDecimal(((IntValue) input).getValue()); - } else if (input instanceof FloatValue) { - return ((FloatValue) input).getValue(); - } - throw new CoercingParseLiteralException( - "Expected AST type 'IntValue', 'StringValue' or 'FloatValue' but was '" + typeName(input) + "'." - ); - } - }); - - - /** - * This represents the "Char" type which is a representation of java.lang.Character - */ - public static final GraphQLScalarType GraphQLChar = new GraphQLScalarType("Char", "Built-in Char as Character", new Coercing() { - - private Character convertImpl(Object input) { - if (input instanceof String && ((String) input).length() == 1) { - return ((String) input).charAt(0); - } else if (input instanceof Character) { - return (Character) input; - } else { - return null; - } - - } - - @Override - public Character serialize(Object input) { - Character result = convertImpl(input); - if (result == null) { - throw new CoercingSerializeException( - "Expected type 'Char' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Character parseValue(Object input) { - Character result = convertImpl(input); - if (result == null) { - throw new CoercingParseValueException( - "Expected type 'Char' but was '" + typeName(input) + "'." - ); - } - return result; - } - - @Override - public Character parseLiteral(Object input) { - if (!(input instanceof StringValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'StringValue' but was '" + typeName(input) + "'." - ); - } - String value = ((StringValue) input).getValue(); - if (value.length() != 1) { - throw new CoercingParseLiteralException( - "Empty 'StringValue' provided." - ); - } - return value.charAt(0); - } - }); + public static final GraphQLScalarType GraphQLID = GraphQLScalarType.newScalar() + .name("ID").description("Built-in ID").coercing(new GraphqlIDCoercing()).build(); } diff --git a/src/main/java/graphql/SerializationError.java b/src/main/java/graphql/SerializationError.java index 511e7760ca..9e03017565 100644 --- a/src/main/java/graphql/SerializationError.java +++ b/src/main/java/graphql/SerializationError.java @@ -1,11 +1,12 @@ package graphql; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import graphql.language.SourceLocation; import graphql.schema.CoercingSerializeException; import java.util.List; +import java.util.Map; import static graphql.Assert.assertNotNull; import static java.lang.String.format; @@ -17,13 +18,13 @@ public class SerializationError implements GraphQLError { private final List path; private final CoercingSerializeException exception; - public SerializationError(ExecutionPath path, CoercingSerializeException exception) { + public SerializationError(ResultPath path, CoercingSerializeException exception) { this.path = assertNotNull(path).toList(); this.exception = assertNotNull(exception); this.message = mkMessage(path, exception); } - private String mkMessage(ExecutionPath path, CoercingSerializeException exception) { + private String mkMessage(ResultPath path, CoercingSerializeException exception) { return format("Can't serialize value (%s) : %s", path, exception.getMessage()); } @@ -31,7 +32,6 @@ public CoercingSerializeException getException() { return exception; } - @Override public String getMessage() { return message; @@ -39,7 +39,7 @@ public String getMessage() { @Override public List getLocations() { - return null; + return exception.getLocations(); } @Override @@ -52,11 +52,16 @@ public List getPath() { return path; } + @Override + public Map getExtensions() { + return exception.getExtensions(); + } + @Override public String toString() { return "SerializationError{" + "path=" + path + - "exception=" + exception + + ", exception=" + exception + '}'; } diff --git a/src/main/java/graphql/ThreadSafe.java b/src/main/java/graphql/ThreadSafe.java new file mode 100644 index 0000000000..8d80507b93 --- /dev/null +++ b/src/main/java/graphql/ThreadSafe.java @@ -0,0 +1,19 @@ +package graphql; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; + +/** + * This represents code that is known to be mutable but thread safe. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = {CONSTRUCTOR, METHOD, TYPE}) +@Documented +public @interface ThreadSafe { +} diff --git a/src/main/java/graphql/TrivialDataFetcher.java b/src/main/java/graphql/TrivialDataFetcher.java new file mode 100644 index 0000000000..eef8cace34 --- /dev/null +++ b/src/main/java/graphql/TrivialDataFetcher.java @@ -0,0 +1,13 @@ +package graphql; + +import graphql.schema.DataFetcher; + + +/** + * Mark a DataFetcher as trivial: + * If a data fetcher is simply mapping data from an object to a field, it can be considered a trivial data fetcher for the purposes + * of tracing and so on. + */ +@PublicSpi +public interface TrivialDataFetcher extends DataFetcher { +} diff --git a/src/main/java/graphql/TypeMismatchError.java b/src/main/java/graphql/TypeMismatchError.java index 3f27e84acf..f5e41b3391 100644 --- a/src/main/java/graphql/TypeMismatchError.java +++ b/src/main/java/graphql/TypeMismatchError.java @@ -1,10 +1,6 @@ package graphql; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import graphql.introspection.Introspection; import graphql.language.SourceLocation; import graphql.schema.GraphQLEnumType; @@ -17,6 +13,10 @@ import graphql.schema.GraphQLType; import graphql.schema.GraphQLUnionType; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + import static graphql.Assert.assertNotNull; import static java.lang.String.format; @@ -27,20 +27,20 @@ public class TypeMismatchError implements GraphQLError { private final List path; private final GraphQLType expectedType; - public TypeMismatchError(ExecutionPath path, GraphQLType expectedType) { + public TypeMismatchError(ResultPath path, GraphQLType expectedType) { this.path = assertNotNull(path).toList(); this.expectedType = assertNotNull(expectedType); this.message = mkMessage(path, expectedType); } - private String mkMessage(ExecutionPath path, GraphQLType expectedType) { + private String mkMessage(ResultPath path, GraphQLType expectedType) { String expectedTypeKind = GraphQLTypeToTypeKindMapping.getTypeKindFromGraphQLType(expectedType).name(); return format("Can't resolve value (%s) : type mismatch error, expected type %s", path, expectedTypeKind); } static class GraphQLTypeToTypeKindMapping { - private static final Map, Introspection.TypeKind> registry = new HashMap, Introspection.TypeKind>() {{ + private static final Map, Introspection.TypeKind> registry = new LinkedHashMap, Introspection.TypeKind>() {{ put(GraphQLEnumType.class, Introspection.TypeKind.ENUM); put(GraphQLList.class, Introspection.TypeKind.LIST); put(GraphQLObjectType.class, Introspection.TypeKind.OBJECT); @@ -83,7 +83,7 @@ public List getPath() { public String toString() { return "TypeMismatchError{" + "path=" + path + - "expectedType=" + expectedType + + ", expectedType=" + expectedType + '}'; } diff --git a/src/main/java/graphql/TypeResolutionEnvironment.java b/src/main/java/graphql/TypeResolutionEnvironment.java index ffcc58370a..ca57979bf5 100644 --- a/src/main/java/graphql/TypeResolutionEnvironment.java +++ b/src/main/java/graphql/TypeResolutionEnvironment.java @@ -1,37 +1,51 @@ package graphql; -import graphql.language.Field; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.execution.DataFetcherResult; +import graphql.execution.MergedField; +import graphql.execution.TypeResolutionParameters; +import graphql.schema.DataFetchingFieldSelectionSet; import graphql.schema.GraphQLSchema; import graphql.schema.GraphQLType; import java.util.Map; +import java.util.function.Supplier; /** * This is passed to a {@link graphql.schema.TypeResolver} to help with object type resolution. * - * See {@link graphql.schema.TypeResolver#getType(TypeResolutionEnvironment)} for how this is used + * See {@link graphql.schema.TypeResolver#getType} for how this is used */ @SuppressWarnings("TypeParameterUnusedInFormals") +@PublicApi public class TypeResolutionEnvironment { private final Object object; - private final Map arguments; - private final Field field; + private final Supplier> arguments; + private final MergedField field; private final GraphQLType fieldType; private final GraphQLSchema schema; private final Object context; + private final GraphQLContext graphQLContext; + private final Object localContext; + private final DataFetchingFieldSelectionSet fieldSelectionSet; - public TypeResolutionEnvironment(Object object, Map arguments, Field field, GraphQLType fieldType, GraphQLSchema schema, final Object context) { - this.object = object; - this.arguments = arguments; - this.field = field; - this.fieldType = fieldType; - this.schema = schema; - this.context = context; + @Internal + public TypeResolutionEnvironment(TypeResolutionParameters parameters) { + this.object = parameters.getValue(); + this.arguments = () -> ImmutableMapWithNullValues.copyOf(parameters.getArgumentValues()); + this.field = parameters.getField(); + this.fieldType = parameters.getFieldType(); + this.schema = parameters.getSchema(); + this.context = parameters.getContext(); + this.graphQLContext = parameters.getGraphQLContext(); + this.localContext = parameters.getLocalContext(); + this.fieldSelectionSet = parameters.getSelectionSet(); } + /** - * You will be passed the specific source object that needs to be resolve into a concrete graphql object type + * You will be passed the specific source object that needs to be resolved into a concrete graphql object type * * @param you decide what type it is * @@ -46,13 +60,13 @@ public T getObject() { * @return the runtime arguments to this the graphql field */ public Map getArguments() { - return arguments; + return arguments.get(); } /** * @return the graphql field in question */ - public Field getField() { + public MergedField getField() { return field; } @@ -71,7 +85,44 @@ public GraphQLSchema getSchema() { return schema; } + /** + * Returns the context object set in via {@link ExecutionInput#getContext()} + * + * @param the type to cast the result to + * + * @return the context object + * + * @deprecated use {@link #getGraphQLContext()} instead + */ + @Deprecated(since = "2021-12-27") public T getContext() { + //noinspection unchecked return (T) context; } + + /** + * @return the {@link GraphQLContext} object set in via {@link ExecutionInput#getGraphQLContext()} + */ + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + /** + * Returns the local context object set in via {@link DataFetcherResult#getLocalContext()} + * + * @param the type to cast the result to + * + * @return the local context object + */ + public T getLocalContext() { + //noinspection unchecked + return (T) localContext; + } + + /** + * @return the {@link DataFetchingFieldSelectionSet} for the current field fetch that needs type resolution + */ + public DataFetchingFieldSelectionSet getSelectionSet() { + return fieldSelectionSet; + } } diff --git a/src/main/java/graphql/UnresolvedTypeError.java b/src/main/java/graphql/UnresolvedTypeError.java index a7a0789def..8f38b1fc4e 100644 --- a/src/main/java/graphql/UnresolvedTypeError.java +++ b/src/main/java/graphql/UnresolvedTypeError.java @@ -1,13 +1,14 @@ package graphql; -import graphql.execution.ExecutionPath; -import graphql.execution.ExecutionTypeInfo; +import graphql.execution.ExecutionStepInfo; +import graphql.execution.ResultPath; import graphql.execution.UnresolvedTypeException; import graphql.language.SourceLocation; import java.util.List; import static graphql.Assert.assertNotNull; +import static graphql.schema.GraphQLTypeUtil.simplePrint; import static java.lang.String.format; @PublicApi @@ -17,18 +18,18 @@ public class UnresolvedTypeError implements GraphQLError { private final List path; private final UnresolvedTypeException exception; - public UnresolvedTypeError(ExecutionPath path, ExecutionTypeInfo info, + public UnresolvedTypeError(ResultPath path, ExecutionStepInfo info, UnresolvedTypeException exception) { this.path = assertNotNull(path).toList(); this.exception = assertNotNull(exception); this.message = mkMessage(path, exception, assertNotNull(info)); } - private String mkMessage(ExecutionPath path, UnresolvedTypeException exception, ExecutionTypeInfo info) { + private String mkMessage(ResultPath path, UnresolvedTypeException exception, ExecutionStepInfo info) { return format("Can't resolve '%s'. Abstract type '%s' must resolve to an Object type at runtime for field '%s.%s'. %s", path, exception.getInterfaceOrUnionType().getName(), - info.getParentTypeInfo().getType().getName(), + simplePrint(info.getParent().getUnwrappedNonNullType()), info.getFieldDefinition().getName(), exception.getMessage()); } @@ -62,7 +63,7 @@ public List getPath() { public String toString() { return "UnresolvedTypeError{" + "path=" + path + - "exception=" + exception + + ", exception=" + exception + '}'; } @@ -76,4 +77,4 @@ public boolean equals(Object o) { public int hashCode() { return GraphqlErrorHelper.hashCode(this); } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/VisibleForTesting.java b/src/main/java/graphql/VisibleForTesting.java new file mode 100644 index 0000000000..864fa70d1c --- /dev/null +++ b/src/main/java/graphql/VisibleForTesting.java @@ -0,0 +1,18 @@ +package graphql; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; + +/** + * Marks fields, methods etc as more visible than actually needed for testing purposes. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(value = {CONSTRUCTOR, METHOD, FIELD}) +@Internal +public @interface VisibleForTesting { +} diff --git a/src/main/java/graphql/analysis/ChildrenOfSelectionProvider.java b/src/main/java/graphql/analysis/ChildrenOfSelectionProvider.java deleted file mode 100644 index 15d2d825d4..0000000000 --- a/src/main/java/graphql/analysis/ChildrenOfSelectionProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -package graphql.analysis; - -import graphql.Internal; -import graphql.language.Field; -import graphql.language.FragmentDefinition; -import graphql.language.FragmentSpread; -import graphql.language.InlineFragment; -import graphql.language.Node; -import graphql.language.NodeTraverser; -import graphql.language.NodeVisitorStub; -import graphql.language.Selection; -import graphql.language.SelectionSet; -import graphql.util.TraversalControl; -import graphql.util.TraverserContext; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * QueryTraversal helper class responsible for obtaining Selection - * nodes from selection parent. - * Uses double dispatch in order to avoid reflection based {@code instanceof} check. - */ -@Internal -public class ChildrenOfSelectionProvider extends NodeVisitorStub { - - private Map fragmentDefinitionMap; - - public ChildrenOfSelectionProvider(Map fragmentDefinitionMap) { - this.fragmentDefinitionMap = fragmentDefinitionMap; - } - - @Override - public TraversalControl visitInlineFragment(InlineFragment node, TraverserContext context) { - getSelectionSetChildren(node.getSelectionSet(), context); - return TraversalControl.CONTINUE; - } - - @Override - public TraversalControl visitFragmentSpread(FragmentSpread fragmentSpread, TraverserContext context) { - getSelectionSetChildren(fragmentDefinitionMap.get(fragmentSpread.getName()).getSelectionSet(), context); - return TraversalControl.CONTINUE; - } - - @Override - public TraversalControl visitField(Field node, TraverserContext context) { - getSelectionSetChildren(node.getSelectionSet(), context); - return TraversalControl.CONTINUE; - } - - @Override - public TraversalControl visitSelectionSet(SelectionSet node, TraverserContext context) { - context.setResult(node.getSelections()); - return TraversalControl.CONTINUE; - } - - private void getSelectionSetChildren(SelectionSet node, TraverserContext context) { - if (node == null) { - context.setResult(Collections.emptyList()); - } else { - context.setResult(node.getSelections()); - } - } - - public List getSelections(Selection selection) { - return NodeTraverser.oneVisitWithResult(selection, this); - } -} diff --git a/src/main/java/graphql/analysis/FieldComplexityEnvironment.java b/src/main/java/graphql/analysis/FieldComplexityEnvironment.java index 95626f5f81..e813c56d75 100644 --- a/src/main/java/graphql/analysis/FieldComplexityEnvironment.java +++ b/src/main/java/graphql/analysis/FieldComplexityEnvironment.java @@ -6,6 +6,7 @@ import graphql.schema.GraphQLFieldDefinition; import java.util.Map; +import java.util.Objects; @PublicApi public class FieldComplexityEnvironment { @@ -46,12 +47,11 @@ public Map getArguments() { @Override public String toString() { return "FieldComplexityEnvironment{" + - "field=" + field + - ", fieldDefinition=" + fieldDefinition + - ", parentType=" + parentType + - ", parentEnvironment=" + parentEnvironment + - ", arguments=" + arguments + - '}'; + "field=" + field + + ", fieldDefinition=" + fieldDefinition + + ", parentType=" + parentType + + ", arguments=" + arguments + + '}'; } @Override @@ -60,23 +60,21 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; FieldComplexityEnvironment that = (FieldComplexityEnvironment) o; - - if (field != null ? !field.equals(that.field) : that.field != null) return false; - if (fieldDefinition != null ? !fieldDefinition.equals(that.fieldDefinition) : that.fieldDefinition != null) - return false; - if (parentType != null ? !parentType.equals(that.parentType) : that.parentType != null) return false; - if (parentEnvironment != null ? !parentEnvironment.equals(that.parentEnvironment) : that.parentEnvironment != null) - return false; - return arguments != null ? arguments.equals(that.arguments) : that.arguments == null; + return Objects.equals(field, that.field) + && Objects.equals(fieldDefinition, that.fieldDefinition) + && Objects.equals(parentType, that.parentType) + && Objects.equals(parentEnvironment, that.parentEnvironment) + && Objects.equals(arguments, that.arguments); } @Override public int hashCode() { - int result = field != null ? field.hashCode() : 0; - result = 31 * result + (fieldDefinition != null ? fieldDefinition.hashCode() : 0); - result = 31 * result + (parentType != null ? parentType.hashCode() : 0); - result = 31 * result + (parentEnvironment != null ? parentEnvironment.hashCode() : 0); - result = 31 * result + (arguments != null ? arguments.hashCode() : 0); + int result = 1; + result = 31 * result + Objects.hashCode(field); + result = 31 * result + Objects.hashCode(fieldDefinition); + result = 31 * result + Objects.hashCode(parentType); + result = 31 * result + Objects.hashCode(parentEnvironment); + result = 31 * result + Objects.hashCode(arguments); return result; } } diff --git a/src/main/java/graphql/analysis/MaxQueryComplexityInstrumentation.java b/src/main/java/graphql/analysis/MaxQueryComplexityInstrumentation.java index 70b0c73de1..0872e47b68 100644 --- a/src/main/java/graphql/analysis/MaxQueryComplexityInstrumentation.java +++ b/src/main/java/graphql/analysis/MaxQueryComplexityInstrumentation.java @@ -1,29 +1,39 @@ package graphql.analysis; +import graphql.ExecutionResult; import graphql.PublicApi; import graphql.execution.AbortExecutionException; +import graphql.execution.ExecutionContext; import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.SimpleInstrumentation; +import graphql.execution.instrumentation.InstrumentationState; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; import graphql.validation.ValidationError; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import static graphql.Assert.assertNotNull; -import static graphql.execution.instrumentation.SimpleInstrumentationContext.whenCompleted; +import static graphql.execution.instrumentation.InstrumentationState.ofState; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp; /** - * Prevents execution if the query complexity is greater than the specified maxComplexity + * Prevents execution if the query complexity is greater than the specified maxComplexity. + *

+ * Use the {@code Function} parameter to supply a function to perform a custom action when the max complexity + * is exceeded. If the function returns {@code true} a {@link AbortExecutionException} is thrown. */ @PublicApi -public class MaxQueryComplexityInstrumentation extends SimpleInstrumentation { - +public class MaxQueryComplexityInstrumentation extends SimplePerformantInstrumentation { private final int maxComplexity; private final FieldComplexityCalculator fieldComplexityCalculator; + private final Function maxQueryComplexityExceededFunction; /** * new Instrumentation with default complexity calculator which is `1 + childComplexity` @@ -31,7 +41,17 @@ public class MaxQueryComplexityInstrumentation extends SimpleInstrumentation { * @param maxComplexity max allowed complexity, otherwise execution will be aborted */ public MaxQueryComplexityInstrumentation(int maxComplexity) { - this(maxComplexity, (env, childComplexity) -> 1 + childComplexity); + this(maxComplexity, (queryComplexityInfo) -> true); + } + + /** + * new Instrumentation with default complexity calculator which is `1 + childComplexity` + * + * @param maxComplexity max allowed complexity, otherwise execution will be aborted + * @param maxQueryComplexityExceededFunction the function to perform when the max complexity is exceeded + */ + public MaxQueryComplexityInstrumentation(int maxComplexity, Function maxQueryComplexityExceededFunction) { + this(maxComplexity, (env, childComplexity) -> 1 + childComplexity, maxQueryComplexityExceededFunction); } /** @@ -41,37 +61,63 @@ public MaxQueryComplexityInstrumentation(int maxComplexity) { * @param fieldComplexityCalculator custom complexity calculator */ public MaxQueryComplexityInstrumentation(int maxComplexity, FieldComplexityCalculator fieldComplexityCalculator) { + this(maxComplexity, fieldComplexityCalculator, (queryComplexityInfo) -> true); + } + + /** + * new Instrumentation with custom complexity calculator + * + * @param maxComplexity max allowed complexity, otherwise execution will be aborted + * @param fieldComplexityCalculator custom complexity calculator + * @param maxQueryComplexityExceededFunction the function to perform when the max complexity is exceeded + */ + public MaxQueryComplexityInstrumentation(int maxComplexity, FieldComplexityCalculator fieldComplexityCalculator, + Function maxQueryComplexityExceededFunction) { this.maxComplexity = maxComplexity; this.fieldComplexityCalculator = assertNotNull(fieldComplexityCalculator, "calculator can't be null"); + this.maxQueryComplexityExceededFunction = maxQueryComplexityExceededFunction; + } + + @Override + public @Nullable CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.completedFuture(new State()); } + @Override + public @Nullable InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState rawState) { + State state = ofState(rawState); + // for API backwards compatibility reasons we capture the validation parameters, so we can put them into QueryComplexityInfo + state.instrumentationValidationParameters.set(parameters); + return noOp(); + } @Override - public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - return whenCompleted((errors, throwable) -> { - if ((errors != null && errors.size() > 0) || throwable != null) { - return; - } - QueryTraversal queryTraversal = newQueryTraversal(parameters); - - Map> valuesByParent = new LinkedHashMap<>(); - queryTraversal.visitPostOrder(new QueryVisitorStub() { - @Override - public void visitField(QueryVisitorFieldEnvironment env) { - int childsComplexity = 0; - if (valuesByParent.containsKey(env)) { - childsComplexity = valuesByParent.get(env).stream().mapToInt(Integer::intValue).sum(); - } - int value = calculateComplexity(env, childsComplexity); - valuesByParent.putIfAbsent(env.getParentEnvironment(), new ArrayList<>()); - valuesByParent.get(env.getParentEnvironment()).add(value); - } - }); - int totalComplexity = valuesByParent.get(null).stream().mapToInt(Integer::intValue).sum(); - if (totalComplexity > maxComplexity) { + public @Nullable InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters instrumentationExecuteOperationParameters, InstrumentationState rawState) { + State state = ofState(rawState); + QueryComplexityCalculator queryComplexityCalculator = newQueryComplexityCalculator(instrumentationExecuteOperationParameters.getExecutionContext()); + int totalComplexity = queryComplexityCalculator.calculate(); + if (totalComplexity > maxComplexity) { + QueryComplexityInfo queryComplexityInfo = QueryComplexityInfo.newQueryComplexityInfo() + .complexity(totalComplexity) + .instrumentationValidationParameters(state.instrumentationValidationParameters.get()) + .instrumentationExecuteOperationParameters(instrumentationExecuteOperationParameters) + .build(); + boolean throwAbortException = maxQueryComplexityExceededFunction.apply(queryComplexityInfo); + if (throwAbortException) { throw mkAbortException(totalComplexity, maxComplexity); } - }); + } + return noOp(); + } + + private QueryComplexityCalculator newQueryComplexityCalculator(ExecutionContext executionContext) { + return QueryComplexityCalculator.newCalculator() + .fieldComplexityCalculator(fieldComplexityCalculator) + .schema(executionContext.getGraphQLSchema()) + .document(executionContext.getDocument()) + .operationName(executionContext.getExecutionInput().getOperationName()) + .variables(executionContext.getCoercedVariables()) + .build(); } /** @@ -80,39 +126,14 @@ public void visitField(QueryVisitorFieldEnvironment env) { * @param totalComplexity the complexity of the query * @param maxComplexity the maximum complexity allowed * - * @return a instance of AbortExecutionException + * @return an instance of AbortExecutionException */ protected AbortExecutionException mkAbortException(int totalComplexity, int maxComplexity) { return new AbortExecutionException("maximum query complexity exceeded " + totalComplexity + " > " + maxComplexity); } - QueryTraversal newQueryTraversal(InstrumentationValidationParameters parameters) { - return QueryTraversal.newQueryTraversal() - .schema(parameters.getSchema()) - .document(parameters.getDocument()) - .operationName(parameters.getOperation()) - .variables(parameters.getVariables()) - .build(); - } - - private int calculateComplexity(QueryVisitorFieldEnvironment QueryVisitorFieldEnvironment, int childsComplexity) { - FieldComplexityEnvironment fieldComplexityEnvironment = convertEnv(QueryVisitorFieldEnvironment); - return fieldComplexityCalculator.calculate(fieldComplexityEnvironment, childsComplexity); + private static class State implements InstrumentationState { + AtomicReference instrumentationValidationParameters = new AtomicReference<>(); } - private FieldComplexityEnvironment convertEnv(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment) { - FieldComplexityEnvironment parentEnv = null; - if (queryVisitorFieldEnvironment.getParentEnvironment() != null) { - parentEnv = convertEnv(queryVisitorFieldEnvironment.getParentEnvironment()); - } - return new FieldComplexityEnvironment( - queryVisitorFieldEnvironment.getField(), - queryVisitorFieldEnvironment.getFieldDefinition(), - queryVisitorFieldEnvironment.getFieldsContainer(), - queryVisitorFieldEnvironment.getArguments(), - parentEnv - ); - } - - } diff --git a/src/main/java/graphql/analysis/MaxQueryDepthInstrumentation.java b/src/main/java/graphql/analysis/MaxQueryDepthInstrumentation.java index 2e60963a08..f242baf33d 100644 --- a/src/main/java/graphql/analysis/MaxQueryDepthInstrumentation.java +++ b/src/main/java/graphql/analysis/MaxQueryDepthInstrumentation.java @@ -1,40 +1,66 @@ package graphql.analysis; +import graphql.ExecutionResult; import graphql.PublicApi; import graphql.execution.AbortExecutionException; +import graphql.execution.ExecutionContext; import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.SimpleInstrumentation; -import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; -import graphql.validation.ValidationError; +import graphql.execution.instrumentation.InstrumentationState; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; +import org.jspecify.annotations.Nullable; -import java.util.List; +import java.util.function.Function; -import static graphql.execution.instrumentation.SimpleInstrumentationContext.whenCompleted; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp; /** - * Prevents execution if the query depth is greater than the specified maxDepth + * Prevents execution if the query depth is greater than the specified maxDepth. + *

+ * Use the {@code Function} parameter to supply a function to perform a custom action when the max depth is + * exceeded. If the function returns {@code true} a {@link AbortExecutionException} is thrown. */ @PublicApi -public class MaxQueryDepthInstrumentation extends SimpleInstrumentation { +public class MaxQueryDepthInstrumentation extends SimplePerformantInstrumentation { + private final int maxDepth; + private final Function maxQueryDepthExceededFunction; + /** + * Creates a new instrumentation that tracks the query depth. + * + * @param maxDepth max allowed depth, otherwise execution will be aborted + */ public MaxQueryDepthInstrumentation(int maxDepth) { + this(maxDepth, (queryDepthInfo) -> true); + } + + /** + * Creates a new instrumentation that tracks the query depth. + * + * @param maxDepth max allowed depth, otherwise execution will be aborted + * @param maxQueryDepthExceededFunction the function to perform when the max depth is exceeded + */ + public MaxQueryDepthInstrumentation(int maxDepth, Function maxQueryDepthExceededFunction) { this.maxDepth = maxDepth; + this.maxQueryDepthExceededFunction = maxQueryDepthExceededFunction; } @Override - public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - return whenCompleted((errors, throwable) -> { - if ((errors != null && errors.size() > 0) || throwable != null) { - return; - } - QueryTraversal queryTraversal = newQueryTraversal(parameters); - int depth = queryTraversal.reducePreOrder((env, acc) -> Math.max(getPathLength(env.getParentEnvironment()), acc), 0); - if (depth > maxDepth) { + public @Nullable InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + QueryTraverser queryTraverser = newQueryTraverser(parameters.getExecutionContext()); + int depth = queryTraverser.reducePreOrder((env, acc) -> Math.max(getPathLength(env.getParentEnvironment()), acc), 0); + if (depth > maxDepth) { + QueryDepthInfo queryDepthInfo = QueryDepthInfo.newQueryDepthInfo() + .depth(depth) + .build(); + boolean throwAbortException = maxQueryDepthExceededFunction.apply(queryDepthInfo); + if (throwAbortException) { throw mkAbortException(depth, maxDepth); } - }); + } + return noOp(); } /** @@ -43,18 +69,18 @@ public InstrumentationContext> beginValidation(Instrumenta * @param depth the depth of the query * @param maxDepth the maximum depth allowed * - * @return a instance of AbortExecutionException + * @return an instance of AbortExecutionException */ protected AbortExecutionException mkAbortException(int depth, int maxDepth) { return new AbortExecutionException("maximum query depth exceeded " + depth + " > " + maxDepth); } - QueryTraversal newQueryTraversal(InstrumentationValidationParameters parameters) { - return QueryTraversal.newQueryTraversal() - .schema(parameters.getSchema()) - .document(parameters.getDocument()) - .operationName(parameters.getOperation()) - .variables(parameters.getVariables()) + QueryTraverser newQueryTraverser(ExecutionContext executionContext) { + return QueryTraverser.newQueryTraverser() + .schema(executionContext.getGraphQLSchema()) + .document(executionContext.getDocument()) + .operationName(executionContext.getExecutionInput().getOperationName()) + .coercedVariables(executionContext.getCoercedVariables()) .build(); } diff --git a/src/main/java/graphql/analysis/NodeVisitorWithTypeTracking.java b/src/main/java/graphql/analysis/NodeVisitorWithTypeTracking.java new file mode 100644 index 0000000000..c2f0bebd3f --- /dev/null +++ b/src/main/java/graphql/analysis/NodeVisitorWithTypeTracking.java @@ -0,0 +1,278 @@ +package graphql.analysis; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.execution.ValuesResolver; +import graphql.execution.conditional.ConditionalNodes; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.Field; +import graphql.language.FragmentDefinition; +import graphql.language.FragmentSpread; +import graphql.language.InlineFragment; +import graphql.language.Node; +import graphql.language.NodeVisitorStub; +import graphql.language.ObjectField; +import graphql.language.TypeName; +import graphql.language.Value; +import graphql.language.VariableDefinition; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLUnmodifiedType; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.Collections; +import java.util.Locale; +import java.util.Map; + +import static graphql.Assert.assertNotNull; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; +import static graphql.util.TraverserContext.Phase.LEAVE; + +/** + * Internally used node visitor which delegates to a {@link QueryVisitor} with type + * information about the visited field. + */ +@Internal +public class NodeVisitorWithTypeTracking extends NodeVisitorStub { + + private final QueryVisitor preOrderCallback; + private final QueryVisitor postOrderCallback; + private final Map variables; + private final GraphQLSchema schema; + private final Map fragmentsByName; + private final ConditionalNodes conditionalNodes = new ConditionalNodes(); + private final QueryTraversalOptions options; + + public NodeVisitorWithTypeTracking(QueryVisitor preOrderCallback, + QueryVisitor postOrderCallback, + Map variables, + GraphQLSchema schema, + Map fragmentsByName, + QueryTraversalOptions options) { + this.preOrderCallback = preOrderCallback; + this.postOrderCallback = postOrderCallback; + this.variables = variables; + this.schema = schema; + this.fragmentsByName = fragmentsByName; + this.options = options; + } + + @Override + public TraversalControl visitDirective(Directive node, TraverserContext context) { + // to avoid visiting arguments for directives we abort the traversal here + return TraversalControl.ABORT; + } + + @Override + public TraversalControl visitInlineFragment(InlineFragment inlineFragment, TraverserContext context) { + QueryTraversalContext parentEnv = context.getVarFromParents(QueryTraversalContext.class); + GraphQLContext graphQLContext = parentEnv.getGraphQLContext(); + if (!conditionalNodes.shouldInclude(inlineFragment, variables, null, graphQLContext)) { + return TraversalControl.ABORT; + } + + QueryVisitorInlineFragmentEnvironment inlineFragmentEnvironment = new QueryVisitorInlineFragmentEnvironmentImpl(inlineFragment, context, schema); + + if (context.getPhase() == LEAVE) { + postOrderCallback.visitInlineFragment(inlineFragmentEnvironment); + return TraversalControl.CONTINUE; + } + + preOrderCallback.visitInlineFragment(inlineFragmentEnvironment); + + // inline fragments are allowed not have type conditions, if so the parent type counts + + GraphQLCompositeType fragmentCondition; + if (inlineFragment.getTypeCondition() != null) { + TypeName typeCondition = inlineFragment.getTypeCondition(); + fragmentCondition = (GraphQLCompositeType) schema.getType(typeCondition.getName()); + } else { + fragmentCondition = parentEnv.getUnwrappedOutputType(); + } + // for unions we only have other fragments inside + context.setVar(QueryTraversalContext.class, new QueryTraversalContext(fragmentCondition, parentEnv.getEnvironment(), inlineFragment, graphQLContext)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitFragmentDefinition(FragmentDefinition fragmentDefinition, TraverserContext context) { + QueryTraversalContext parentEnv = context.getVarFromParents(QueryTraversalContext.class); + GraphQLContext graphQLContext = parentEnv.getGraphQLContext(); + if (!conditionalNodes.shouldInclude(fragmentDefinition, variables, null, graphQLContext)) { + return TraversalControl.ABORT; + } + + QueryVisitorFragmentDefinitionEnvironment fragmentEnvironment = new QueryVisitorFragmentDefinitionEnvironmentImpl(fragmentDefinition, context, schema); + + if (context.getPhase() == LEAVE) { + postOrderCallback.visitFragmentDefinition(fragmentEnvironment); + return TraversalControl.CONTINUE; + } + preOrderCallback.visitFragmentDefinition(fragmentEnvironment); + + GraphQLCompositeType typeCondition = (GraphQLCompositeType) schema.getType(fragmentDefinition.getTypeCondition().getName()); + context.setVar(QueryTraversalContext.class, new QueryTraversalContext(typeCondition, parentEnv.getEnvironment(), fragmentDefinition, graphQLContext)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitFragmentSpread(FragmentSpread fragmentSpread, TraverserContext context) { + QueryTraversalContext parentEnv = context.getVarFromParents(QueryTraversalContext.class); + GraphQLContext graphQLContext = parentEnv.getGraphQLContext(); + if (!conditionalNodes.shouldInclude(fragmentSpread, variables, null, graphQLContext)) { + return TraversalControl.ABORT; + } + + FragmentDefinition fragmentDefinition = fragmentsByName.get(fragmentSpread.getName()); + if (!conditionalNodes.shouldInclude(fragmentDefinition, variables, null, graphQLContext)) { + return TraversalControl.ABORT; + } + + QueryVisitorFragmentSpreadEnvironment fragmentSpreadEnvironment = new QueryVisitorFragmentSpreadEnvironmentImpl(fragmentSpread, fragmentDefinition, context, schema); + if (context.getPhase() == LEAVE) { + postOrderCallback.visitFragmentSpread(fragmentSpreadEnvironment); + return TraversalControl.CONTINUE; + } + + preOrderCallback.visitFragmentSpread(fragmentSpreadEnvironment); + + + GraphQLCompositeType typeCondition = (GraphQLCompositeType) schema.getType(fragmentDefinition.getTypeCondition().getName()); + assertNotNull(typeCondition, + "Invalid type condition '%s' in fragment '%s'", fragmentDefinition.getTypeCondition().getName(), + fragmentDefinition.getName()); + context.setVar(QueryTraversalContext.class, new QueryTraversalContext(typeCondition, parentEnv.getEnvironment(), fragmentDefinition, graphQLContext)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitField(Field field, TraverserContext context) { + QueryTraversalContext parentEnv = context.getVarFromParents(QueryTraversalContext.class); + GraphQLContext graphQLContext = parentEnv.getGraphQLContext(); + + GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(schema, (GraphQLCompositeType) unwrapAll(parentEnv.getOutputType()), field.getName()); + boolean isTypeNameIntrospectionField = fieldDefinition == schema.getIntrospectionTypenameFieldDefinition(); + GraphQLFieldsContainer fieldsContainer = !isTypeNameIntrospectionField ? (GraphQLFieldsContainer) unwrapAll(parentEnv.getOutputType()) : null; + GraphQLCodeRegistry codeRegistry = schema.getCodeRegistry(); + Map argumentValues; + if (options.isCoerceFieldArguments()) { + argumentValues = ValuesResolver.getArgumentValues(codeRegistry, + fieldDefinition.getArguments(), + field.getArguments(), + CoercedVariables.of(variables), + GraphQLContext.getDefault(), + Locale.getDefault()); + } else { + argumentValues = Collections.emptyMap(); + } + QueryVisitorFieldEnvironment environment = new QueryVisitorFieldEnvironmentImpl(isTypeNameIntrospectionField, + field, + fieldDefinition, + parentEnv.getOutputType(), + fieldsContainer, + parentEnv.getEnvironment(), + argumentValues, + parentEnv.getSelectionSetContainer(), + context, schema); + + if (context.getPhase() == LEAVE) { + postOrderCallback.visitField(environment); + return TraversalControl.CONTINUE; + } + + if (!conditionalNodes.shouldInclude(field, variables, null, graphQLContext)) { + return TraversalControl.ABORT; + } + + TraversalControl traversalControl = preOrderCallback.visitFieldWithControl(environment); + + GraphQLUnmodifiedType unmodifiedType = unwrapAll(fieldDefinition.getType()); + QueryTraversalContext fieldEnv = (unmodifiedType instanceof GraphQLCompositeType) + ? new QueryTraversalContext(fieldDefinition.getType(), environment, field, graphQLContext) + : new QueryTraversalContext(null, environment, field, graphQLContext);// Terminal (scalar) node, EMPTY FRAME + + + context.setVar(QueryTraversalContext.class, fieldEnv); + return traversalControl; + } + + + @Override + public TraversalControl visitArgument(Argument argument, TraverserContext context) { + + QueryTraversalContext fieldCtx = context.getVarFromParents(QueryTraversalContext.class); + Field field = (Field) fieldCtx.getSelectionSetContainer(); + + QueryVisitorFieldEnvironment fieldEnv = fieldCtx.getEnvironment(); + GraphQLFieldsContainer fieldsContainer = fieldEnv.getFieldsContainer(); + + GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDefinition(schema, fieldsContainer, field.getName()); + GraphQLArgument graphQLArgument = fieldDefinition.getArgument(argument.getName()); + String argumentName = graphQLArgument.getName(); + + Object argumentValue = fieldEnv.getArguments().getOrDefault(argumentName, null); + + QueryVisitorFieldArgumentEnvironment environment = new QueryVisitorFieldArgumentEnvironmentImpl( + fieldDefinition, argument, graphQLArgument, argumentValue, variables, fieldEnv, context, schema); + + QueryVisitorFieldArgumentInputValue inputValue = QueryVisitorFieldArgumentInputValueImpl + .incompleteArgumentInputValue(graphQLArgument); + + context.setVar(QueryVisitorFieldArgumentEnvironment.class, environment); + context.setVar(QueryVisitorFieldArgumentInputValue.class, inputValue); + if (context.getPhase() == LEAVE) { + return postOrderCallback.visitArgument(environment); + } + return preOrderCallback.visitArgument(environment); + } + + @Override + public TraversalControl visitObjectField(ObjectField node, TraverserContext context) { + + QueryVisitorFieldArgumentInputValueImpl inputValue = context.getVarFromParents(QueryVisitorFieldArgumentInputValue.class); + GraphQLUnmodifiedType unmodifiedType = unwrapAll(inputValue.getInputType()); + // + // technically a scalar type can have an AST object field - eg field( arg : Json) -> field(arg : { ast : "here" }) + if (unmodifiedType instanceof GraphQLInputObjectType) { + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) unmodifiedType; + GraphQLInputObjectField inputObjectTypeField = inputObjectType.getField(node.getName()); + + inputValue = inputValue.incompleteNewChild(inputObjectTypeField); + context.setVar(QueryVisitorFieldArgumentInputValue.class, inputValue); + } + return TraversalControl.CONTINUE; + } + + @Override + protected TraversalControl visitValue(Value value, TraverserContext context) { + if (context.getParentNode() instanceof VariableDefinition) { + visitVariableDefinition(((VariableDefinition) context.getParentNode()), context); + return TraversalControl.ABORT; + } + + QueryVisitorFieldArgumentEnvironment fieldArgEnv = context.getVarFromParents(QueryVisitorFieldArgumentEnvironment.class); + QueryVisitorFieldArgumentInputValueImpl inputValue = context.getVarFromParents(QueryVisitorFieldArgumentInputValue.class); + // previous visits have set up the previous information + inputValue = inputValue.completeArgumentInputValue(value); + context.setVar(QueryVisitorFieldArgumentInputValue.class, inputValue); + + QueryVisitorFieldArgumentValueEnvironment environment = new QueryVisitorFieldArgumentValueEnvironmentImpl( + schema, fieldArgEnv.getFieldDefinition(), fieldArgEnv.getGraphQLArgument(), inputValue, context, + variables); + + if (context.getPhase() == LEAVE) { + return postOrderCallback.visitArgumentValue(environment); + } + return preOrderCallback.visitArgumentValue(environment); + } +} diff --git a/src/main/java/graphql/analysis/QueryComplexityCalculator.java b/src/main/java/graphql/analysis/QueryComplexityCalculator.java new file mode 100644 index 0000000000..e16035cc7a --- /dev/null +++ b/src/main/java/graphql/analysis/QueryComplexityCalculator.java @@ -0,0 +1,134 @@ +package graphql.analysis; + +import graphql.PublicApi; +import graphql.execution.CoercedVariables; +import graphql.language.Document; +import graphql.schema.GraphQLSchema; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static graphql.Assert.assertNotNull; +import static java.util.Optional.ofNullable; + +/** + * This can calculate the complexity of an operation using the specified {@link FieldComplexityCalculator} you pass + * into it. + */ +@PublicApi +public class QueryComplexityCalculator { + + private final FieldComplexityCalculator fieldComplexityCalculator; + private final GraphQLSchema schema; + private final Document document; + private final String operationName; + private final CoercedVariables variables; + + public QueryComplexityCalculator(Builder builder) { + this.fieldComplexityCalculator = assertNotNull(builder.fieldComplexityCalculator, "fieldComplexityCalculator can't be null"); + this.schema = assertNotNull(builder.schema, "schema can't be null"); + this.document = assertNotNull(builder.document, "document can't be null"); + this.variables = assertNotNull(builder.variables, "variables can't be null"); + this.operationName = builder.operationName; + } + + + public int calculate() { + Map valuesByParent = calculateByParents(); + return valuesByParent.getOrDefault(null, 0); + } + + /** + * @return a map that shows the field complexity for each field level in the operation + */ + public Map calculateByParents() { + QueryTraverser queryTraverser = QueryTraverser.newQueryTraverser() + .schema(this.schema) + .document(this.document) + .operationName(this.operationName) + .coercedVariables(this.variables) + .build(); + + + Map valuesByParent = new LinkedHashMap<>(); + queryTraverser.visitPostOrder(new QueryVisitorStub() { + @Override + public void visitField(QueryVisitorFieldEnvironment env) { + int childComplexity = valuesByParent.getOrDefault(env, 0); + int value = calculateComplexity(env, childComplexity); + + QueryVisitorFieldEnvironment parentEnvironment = env.getParentEnvironment(); + valuesByParent.compute(parentEnvironment, (key, oldValue) -> { + Integer currentValue = ofNullable(oldValue).orElse(0); + return currentValue + value; + } + ); + } + }); + + return valuesByParent; + } + + private int calculateComplexity(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment, int childComplexity) { + if (queryVisitorFieldEnvironment.isTypeNameIntrospectionField()) { + return 0; + } + FieldComplexityEnvironment fieldComplexityEnvironment = convertEnv(queryVisitorFieldEnvironment); + return fieldComplexityCalculator.calculate(fieldComplexityEnvironment, childComplexity); + } + + private FieldComplexityEnvironment convertEnv(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment) { + FieldComplexityEnvironment parentEnv = null; + if (queryVisitorFieldEnvironment.getParentEnvironment() != null) { + parentEnv = convertEnv(queryVisitorFieldEnvironment.getParentEnvironment()); + } + return new FieldComplexityEnvironment( + queryVisitorFieldEnvironment.getField(), + queryVisitorFieldEnvironment.getFieldDefinition(), + queryVisitorFieldEnvironment.getFieldsContainer(), + queryVisitorFieldEnvironment.getArguments(), + parentEnv + ); + } + + public static Builder newCalculator() { + return new Builder(); + } + + public static class Builder { + private FieldComplexityCalculator fieldComplexityCalculator; + private GraphQLSchema schema; + private Document document; + private String operationName; + private CoercedVariables variables = CoercedVariables.emptyVariables(); + + public Builder schema(GraphQLSchema graphQLSchema) { + this.schema = graphQLSchema; + return this; + } + + public Builder fieldComplexityCalculator(FieldComplexityCalculator complexityCalculator) { + this.fieldComplexityCalculator = complexityCalculator; + return this; + } + + public Builder document(Document document) { + this.document = document; + return this; + } + + public Builder operationName(String operationName) { + this.operationName = operationName; + return this; + } + + public Builder variables(CoercedVariables variables) { + this.variables = variables; + return this; + } + + public QueryComplexityCalculator build() { + return new QueryComplexityCalculator(this); + } + } +} \ No newline at end of file diff --git a/src/main/java/graphql/analysis/QueryComplexityInfo.java b/src/main/java/graphql/analysis/QueryComplexityInfo.java new file mode 100644 index 0000000000..29914e960a --- /dev/null +++ b/src/main/java/graphql/analysis/QueryComplexityInfo.java @@ -0,0 +1,112 @@ +package graphql.analysis; + +import graphql.PublicApi; +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; +import org.jspecify.annotations.NullUnmarked; + +/** + * The query complexity info. + */ +@PublicApi +public class QueryComplexityInfo { + + private final int complexity; + private final InstrumentationValidationParameters instrumentationValidationParameters; + private final InstrumentationExecuteOperationParameters instrumentationExecuteOperationParameters; + + private QueryComplexityInfo(Builder builder) { + this.complexity = builder.complexity; + this.instrumentationValidationParameters = builder.instrumentationValidationParameters; + this.instrumentationExecuteOperationParameters = builder.instrumentationExecuteOperationParameters; + } + + /** + * This returns the query complexity. + * + * @return the query complexity + */ + public int getComplexity() { + return complexity; + } + + /** + * This returns the instrumentation validation parameters. + * + * @return the instrumentation validation parameters. + */ + public InstrumentationValidationParameters getInstrumentationValidationParameters() { + return instrumentationValidationParameters; + } + + /** + * This returns the instrumentation execute operation parameters. + * + * @return the instrumentation execute operation parameters. + */ + public InstrumentationExecuteOperationParameters getInstrumentationExecuteOperationParameters() { + return instrumentationExecuteOperationParameters; + } + + @Override + public String toString() { + return "QueryComplexityInfo{" + + "complexity=" + complexity + + '}'; + } + + /** + * @return a new {@link QueryComplexityInfo} builder + */ + public static Builder newQueryComplexityInfo() { + return new Builder(); + } + + @PublicApi + @NullUnmarked + public static class Builder { + + private int complexity; + private InstrumentationValidationParameters instrumentationValidationParameters; + private InstrumentationExecuteOperationParameters instrumentationExecuteOperationParameters; + + private Builder() { + } + + /** + * The query complexity. + * + * @param complexity the query complexity + * + * @return this builder + */ + public Builder complexity(int complexity) { + this.complexity = complexity; + return this; + } + + /** + * The instrumentation validation parameters. + * + * @param parameters the instrumentation validation parameters. + * + * @return this builder + */ + public Builder instrumentationValidationParameters(InstrumentationValidationParameters parameters) { + this.instrumentationValidationParameters = parameters; + return this; + } + + public Builder instrumentationExecuteOperationParameters(InstrumentationExecuteOperationParameters instrumentationExecuteOperationParameters) { + this.instrumentationExecuteOperationParameters = instrumentationExecuteOperationParameters; + return this; + } + + /** + * @return a built {@link QueryComplexityInfo} object + */ + public QueryComplexityInfo build() { + return new QueryComplexityInfo(this); + } + } +} diff --git a/src/main/java/graphql/analysis/QueryDepthInfo.java b/src/main/java/graphql/analysis/QueryDepthInfo.java new file mode 100644 index 0000000000..a8d4a0ac03 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryDepthInfo.java @@ -0,0 +1,68 @@ +package graphql.analysis; + +import graphql.PublicApi; +import org.jspecify.annotations.NullUnmarked; + +/** + * The query depth info. + */ +@PublicApi +public class QueryDepthInfo { + + private final int depth; + + private QueryDepthInfo(int depth) { + this.depth = depth; + } + + /** + * This returns the query depth. + * + * @return the query depth + */ + public int getDepth() { + return depth; + } + + @Override + public String toString() { + return "QueryDepthInfo{" + + "depth=" + depth + + '}'; + } + + /** + * @return a new {@link QueryDepthInfo} builder + */ + public static Builder newQueryDepthInfo() { + return new Builder(); + } + + @PublicApi + @NullUnmarked + public static class Builder { + + private int depth; + + private Builder() { + } + + /** + * The query depth. + * + * @param depth the depth complexity + * @return this builder + */ + public Builder depth(int depth) { + this.depth = depth; + return this; + } + + /** + * @return a built {@link QueryDepthInfo} object + */ + public QueryDepthInfo build() { + return new QueryDepthInfo(depth); + } + } +} diff --git a/src/main/java/graphql/analysis/QueryReducer.java b/src/main/java/graphql/analysis/QueryReducer.java index ed94057bed..f19ee7fd93 100644 --- a/src/main/java/graphql/analysis/QueryReducer.java +++ b/src/main/java/graphql/analysis/QueryReducer.java @@ -3,11 +3,11 @@ import graphql.PublicApi; /** - * Used by {@link QueryTraversal} to reduce the fields of a Document (or part of it) to a single value. + * Used by {@link QueryTraverser} to reduce the fields of a Document (or part of it) to a single value. *

- * How this happens in detail (pre vs post-order for example) is defined by {@link QueryTraversal}. + * How this happens in detail (pre vs post-order for example) is defined by {@link QueryTraverser}. *

- * See {@link QueryTraversal#reducePostOrder(QueryReducer, Object)} and {@link QueryTraversal#reducePreOrder(QueryReducer, Object)} + * See {@link QueryTraverser#reducePostOrder(QueryReducer, Object)} and {@link QueryTraverser#reducePreOrder(QueryReducer, Object)} */ @PublicApi @FunctionalInterface diff --git a/src/main/java/graphql/analysis/QueryTransformer.java b/src/main/java/graphql/analysis/QueryTransformer.java new file mode 100644 index 0000000000..fbf5052a91 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryTransformer.java @@ -0,0 +1,194 @@ +package graphql.analysis; + +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.language.FragmentDefinition; +import graphql.language.Node; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLSchema; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.util.TraverserVisitor; +import graphql.util.TreeTransformer; + +import java.util.LinkedHashMap; +import java.util.Map; +import org.jspecify.annotations.NullUnmarked; + +import static graphql.Assert.assertNotNull; +import static graphql.language.AstNodeAdapter.AST_NODE_ADAPTER; + +/** + * Helps to transform a Document (or parts of it) and tracks at the same time the corresponding Schema types. + *

+ * This is an important distinction to just traversing the Document without any type information: Each field has a clearly + * defined type. See {@link QueryVisitorFieldEnvironment}. + *

+ * Furthermore are the built in Directives skip/include automatically evaluated: if parts of the Document should be ignored they will not + * be visited. But this is not a full evaluation of a Query: every fragment will be visited/followed regardless of the type condition. + *

+ * It also doesn't consider field merging, which means for example {@code { user{firstName} user{firstName}} } will result in four + * visitField calls. + */ +@PublicApi +public class QueryTransformer { + + private final Node root; + private final GraphQLSchema schema; + private final Map fragmentsByName; + private final Map variables; + private final GraphQLCompositeType rootParentType; + private final QueryTraversalOptions options; + + + private QueryTransformer(GraphQLSchema schema, + Node root, + GraphQLCompositeType rootParentType, + Map fragmentsByName, + Map variables, + QueryTraversalOptions options) { + this.schema = assertNotNull(schema, "schema can't be null"); + this.variables = assertNotNull(variables, "variables can't be null"); + this.root = assertNotNull(root, "root can't be null"); + this.rootParentType = assertNotNull(rootParentType); + this.fragmentsByName = assertNotNull(fragmentsByName, "fragmentsByName can't be null"); + this.options = assertNotNull(options, "options can't be null"); + } + + /** + * Visits the Document in pre-order and allows to transform it using {@link graphql.util.TreeTransformerUtil} + * methods. Please note that fragment spreads are not followed and need to be + * processed explicitly by supplying them as root. + * + * @param queryVisitor the query visitor that will be called back. + * + * @return changed root + * + * @throws IllegalArgumentException if there are multiple root nodes. + */ + public Node transform(QueryVisitor queryVisitor) { + QueryVisitor noOp = new QueryVisitorStub(); + NodeVisitorWithTypeTracking nodeVisitor = new NodeVisitorWithTypeTracking(queryVisitor, + noOp, + variables, + schema, + fragmentsByName, + options); + + Map, Object> rootVars = new LinkedHashMap<>(); + rootVars.put(QueryTraversalContext.class, new QueryTraversalContext(rootParentType, null, null, GraphQLContext.getDefault())); + + TraverserVisitor nodeTraverserVisitor = new TraverserVisitor<>() { + + @Override + public TraversalControl enter(TraverserContext context) { + return context.thisNode().accept(context, nodeVisitor); + } + + @Override + public TraversalControl leave(TraverserContext context) { + //Transformations are applied preOrder only + return TraversalControl.CONTINUE; + } + }; + return new TreeTransformer<>(AST_NODE_ADAPTER).transform(root, nodeTraverserVisitor, rootVars); + } + + public static Builder newQueryTransformer() { + return new Builder(); + } + + @PublicApi + @NullUnmarked + public static class Builder { + private GraphQLSchema schema; + private Map variables; + + private Node root; + private GraphQLCompositeType rootParentType; + private Map fragmentsByName; + private QueryTraversalOptions options = QueryTraversalOptions.defaultOptions(); + + + /** + * The schema used to identify the types of the query. + * + * @param schema the schema to use + * + * @return this builder + */ + public Builder schema(GraphQLSchema schema) { + this.schema = schema; + return this; + } + + /** + * Variables used in the query. + * + * @param variables the variables to use + * + * @return this builder + */ + public Builder variables(Map variables) { + this.variables = variables; + return this; + } + + /** + * Specify the root node for the transformation. + * + * @param root the root node to use + * + * @return this builder + */ + public Builder root(Node root) { + this.root = root; + return this; + } + + /** + * The type of the parent of the root node. (See {@link Builder#root(Node)} + * + * @param rootParentType the root parent type + * + * @return this builder + */ + public Builder rootParentType(GraphQLCompositeType rootParentType) { + this.rootParentType = rootParentType; + return this; + } + + /** + * Fragment by name map. Needs to be provided together with a {@link Builder#root(Node)} and {@link Builder#rootParentType(GraphQLCompositeType)} + * + * @param fragmentsByName the map of fragments + * + * @return this builder + */ + public Builder fragmentsByName(Map fragmentsByName) { + this.fragmentsByName = fragmentsByName; + return this; + } + + /** + * Sets the options to use while traversing + * + * @param options the options to use + * @return this builder + */ + public Builder options(QueryTraversalOptions options) { + this.options = assertNotNull(options, "options can't be null"); + return this; + } + + public QueryTransformer build() { + return new QueryTransformer( + schema, + root, + rootParentType, + fragmentsByName, + variables, + options); + } + } +} diff --git a/src/main/java/graphql/analysis/QueryTraversal.java b/src/main/java/graphql/analysis/QueryTraversal.java deleted file mode 100644 index f9eee6ebc5..0000000000 --- a/src/main/java/graphql/analysis/QueryTraversal.java +++ /dev/null @@ -1,416 +0,0 @@ -package graphql.analysis; - -import graphql.PublicApi; -import graphql.execution.ConditionalNodes; -import graphql.execution.ValuesResolver; -import graphql.introspection.Introspection; -import graphql.language.Document; -import graphql.language.Field; -import graphql.language.FragmentDefinition; -import graphql.language.FragmentSpread; -import graphql.language.InlineFragment; -import graphql.language.Node; -import graphql.language.NodeTraverser; -import graphql.language.NodeTraverser.LeaveOrEnter; -import graphql.language.NodeUtil; -import graphql.language.NodeVisitorStub; -import graphql.language.OperationDefinition; -import graphql.language.Selection; -import graphql.language.TypeName; -import graphql.schema.GraphQLCompositeType; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLFieldsContainer; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLSchema; -import graphql.schema.GraphQLUnmodifiedType; -import graphql.util.TraversalControl; -import graphql.util.TraverserContext; - -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static graphql.Assert.assertNotNull; -import static graphql.Assert.assertShouldNeverHappen; -import static graphql.language.NodeTraverser.LeaveOrEnter.LEAVE; -import static graphql.schema.GraphQLTypeUtil.unwrapAll; - -/** - * Helps to traverse (or reduce) a Document (or parts of it) and tracks at the same time the corresponding Schema types. - *

- * This is an important distinction to just traversing the Document without any type information: Each field has a clearly - * defined type. See {@link QueryVisitorFieldEnvironment}. - *

- * Further are the built in Directives skip/include automatically evaluated: if parts of the Document should be ignored they will not - * be visited. But this is not a full evaluation of a Query: every fragment will be visited/followed regardless of the type condition. - */ -@PublicApi -public class QueryTraversal { - - private final Collection roots; - private final GraphQLSchema schema; - private final Map fragmentsByName; - private final Map variables; - - private final ConditionalNodes conditionalNodes = new ConditionalNodes(); - private final ValuesResolver valuesResolver = new ValuesResolver(); - private final ChildrenOfSelectionProvider childrenOfSelectionProvider; - private final GraphQLObjectType rootParentType; - - private QueryTraversal(GraphQLSchema schema, - Document document, - String operation, - Map variables) { - assertNotNull(document, "document can't be null"); - NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, operation); - this.schema = assertNotNull(schema, "schema can't be null"); - this.variables = assertNotNull(variables, "variables can't be null"); - this.fragmentsByName = getOperationResult.fragmentsByName; - this.roots = getOperationResult.operationDefinition.getSelectionSet().getChildren(); - this.rootParentType = getRootTypeFromOperation(getOperationResult.operationDefinition); - this.childrenOfSelectionProvider = new ChildrenOfSelectionProvider(fragmentsByName); - } - - private QueryTraversal(GraphQLSchema schema, - Node root, - GraphQLObjectType rootParentType, - Map fragmentsByName, - Map variables) { - this.schema = assertNotNull(schema, "schema can't be null"); - this.variables = assertNotNull(variables, "variables can't be null"); - assertNotNull(root, "root can't be null"); - this.roots = Collections.singleton(root); - this.rootParentType = assertNotNull(rootParentType, "rootParentType can't be null"); - this.fragmentsByName = assertNotNull(fragmentsByName, "fragmentsByName can't be null"); - this.childrenOfSelectionProvider = new ChildrenOfSelectionProvider(fragmentsByName); - } - - /** - * Visits the Document (or parts of it) in post-order. - * - * @param visitor the query visitor that will be called back - */ - public void visitPostOrder(QueryVisitor visitor) { - visitImpl(visitor, false); - } - - /** - * Visits the Document (or parts of it) in pre-order. - * - * @param visitor the query visitor that will be called back - */ - public void visitPreOrder(QueryVisitor visitor) { - visitImpl(visitor, true); - } - - /** - * Reduces the fields of a Document (or parts of it) to a single value. The fields are visited in post-order. - * - * @param queryReducer the query reducer - * @param initialValue the initial value to pass to the reducer - * @param the type of reduced value - * - * @return the calculated overall value - */ - @SuppressWarnings("unchecked") - public T reducePostOrder(QueryReducer queryReducer, T initialValue) { - // compiler hack to make acc final and mutable :-) - final Object[] acc = {initialValue}; - visitPostOrder(new QueryVisitorStub() { - @Override - public void visitField(QueryVisitorFieldEnvironment env) { - acc[0] = queryReducer.reduceField(env, (T) acc[0]); - } - }); - return (T) acc[0]; - } - - /** - * Reduces the fields of a Document (or parts of it) to a single value. The fields are visited in pre-order. - * - * @param queryReducer the query reducer - * @param initialValue the initial value to pass to the reducer - * @param the type of reduced value - * - * @return the calucalated overall value - */ - @SuppressWarnings("unchecked") - public T reducePreOrder(QueryReducer queryReducer, T initialValue) { - // compiler hack to make acc final and mutable :-) - final Object[] acc = {initialValue}; - visitPreOrder(new QueryVisitorStub() { - @Override - public void visitField(QueryVisitorFieldEnvironment env) { - acc[0] = queryReducer.reduceField(env, (T) acc[0]); - } - }); - return (T) acc[0]; - } - - private GraphQLObjectType getRootTypeFromOperation(OperationDefinition operationDefinition) { - switch (operationDefinition.getOperation()) { - case MUTATION: - return assertNotNull(schema.getMutationType()); - case QUERY: - return assertNotNull(schema.getQueryType()); - case SUBSCRIPTION: - return assertNotNull(schema.getSubscriptionType()); - default: - return assertShouldNeverHappen(); - } - } - - private List childrenOf(Node selection) { - return childrenOfSelectionProvider.getSelections((Selection) selection); - } - - private void visitImpl(QueryVisitor visitFieldCallback, boolean preOrder) { - Map, Object> rootVars = new LinkedHashMap<>(); - rootVars.put(QueryTraversalContext.class, new QueryTraversalContext(rootParentType, rootParentType, null, null)); - - QueryVisitor noOp = new QueryVisitorStub(); - QueryVisitor preOrderCallback = preOrder ? visitFieldCallback : noOp; - QueryVisitor postOrderCallback = !preOrder ? visitFieldCallback : noOp; - - NodeTraverser nodeTraverser = new NodeTraverser(rootVars, this::childrenOf); - nodeTraverser.depthFirst(new NodeVisitorImpl(preOrderCallback, postOrderCallback), roots); - } - - private class NodeVisitorImpl extends NodeVisitorStub { - - final QueryVisitor preOrderCallback; - final QueryVisitor postOrderCallback; - - NodeVisitorImpl(QueryVisitor preOrderCallback, QueryVisitor postOrderCallback) { - this.preOrderCallback = preOrderCallback; - this.postOrderCallback = postOrderCallback; - } - - @Override - public TraversalControl visitInlineFragment(InlineFragment inlineFragment, TraverserContext context) { - if (!conditionalNodes.shouldInclude(variables, inlineFragment.getDirectives())) - return TraversalControl.ABORT; - - QueryVisitorInlineFragmentEnvironment inlineFragmentEnvironment = new QueryVisitorInlineFragmentEnvironmentImpl(inlineFragment); - - if (context.getVar(LeaveOrEnter.class) == LEAVE) { - postOrderCallback.visitInlineFragment(inlineFragmentEnvironment); - return TraversalControl.CONTINUE; - } - - preOrderCallback.visitInlineFragment(inlineFragmentEnvironment); - - // inline fragments are allowed not have type conditions, if so the parent type counts - QueryTraversalContext parentEnv = context - .getParentContext() - .getVar(QueryTraversalContext.class); - - GraphQLCompositeType fragmentCondition; - if (inlineFragment.getTypeCondition() != null) { - TypeName typeCondition = inlineFragment.getTypeCondition(); - fragmentCondition = (GraphQLCompositeType) schema.getType(typeCondition.getName()); - } else { - fragmentCondition = parentEnv.getRawType(); - } - // for unions we only have other fragments inside - context.setVar(QueryTraversalContext.class, new QueryTraversalContext(fragmentCondition, fragmentCondition, parentEnv.getEnvironment(), inlineFragment)); - return TraversalControl.CONTINUE; - } - - @Override - public TraversalControl visitFragmentSpread(FragmentSpread fragmentSpread, TraverserContext context) { - if (!conditionalNodes.shouldInclude(variables, fragmentSpread.getDirectives())) - return TraversalControl.ABORT; - - FragmentDefinition fragmentDefinition = fragmentsByName.get(fragmentSpread.getName()); - if (!conditionalNodes.shouldInclude(variables, fragmentDefinition.getDirectives())) - return TraversalControl.ABORT; - - QueryVisitorFragmentSpreadEnvironment fragmentSpreadEnvironment = new QueryVisitorFragmentSpreadEnvironmentImpl(fragmentSpread, fragmentDefinition); - if (context.getVar(LeaveOrEnter.class) == LEAVE) { - postOrderCallback.visitFragmentSpread(fragmentSpreadEnvironment); - return TraversalControl.CONTINUE; - } - - preOrderCallback.visitFragmentSpread(fragmentSpreadEnvironment); - - QueryTraversalContext parentEnv = context - .getParentContext() - .getVar(QueryTraversalContext.class); - - GraphQLCompositeType typeCondition = (GraphQLCompositeType) schema.getType(fragmentDefinition.getTypeCondition().getName()); - - context - .setVar(QueryTraversalContext.class, new QueryTraversalContext(typeCondition, typeCondition, parentEnv.getEnvironment(), fragmentDefinition)); - return TraversalControl.CONTINUE; - } - - @Override - public TraversalControl visitField(Field field, TraverserContext context) { - QueryTraversalContext parentEnv = context - .getParentContext() - .getVar(QueryTraversalContext.class); - - GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(schema, parentEnv.getRawType(), field.getName()); - boolean isTypeNameIntrospectionField = fieldDefinition == Introspection.TypeNameMetaFieldDef; - GraphQLFieldsContainer fieldsContainer = !isTypeNameIntrospectionField ? (GraphQLFieldsContainer) unwrapAll(parentEnv.getOutputType()) : null; - Map argumentValues = valuesResolver.getArgumentValues(schema.getFieldVisibility(), fieldDefinition.getArguments(), field.getArguments(), variables); - QueryVisitorFieldEnvironment environment = new QueryVisitorFieldEnvironmentImpl(isTypeNameIntrospectionField, - field, - fieldDefinition, - parentEnv.getOutputType(), - fieldsContainer, - parentEnv.getEnvironment(), - argumentValues, - parentEnv.getSelectionSetContainer()); - - LeaveOrEnter leaveOrEnter = context.getVar(LeaveOrEnter.class); - if (leaveOrEnter == LEAVE) { - postOrderCallback.visitField(environment); - return TraversalControl.CONTINUE; - } - - if (!conditionalNodes.shouldInclude(variables, field.getDirectives())) - return TraversalControl.ABORT; - - preOrderCallback.visitField(environment); - - GraphQLUnmodifiedType unmodifiedType = unwrapAll(fieldDefinition.getType()); - QueryTraversalContext fieldEnv = (unmodifiedType instanceof GraphQLCompositeType) - ? new QueryTraversalContext(fieldDefinition.getType(), (GraphQLCompositeType) unmodifiedType, environment, field) - : new QueryTraversalContext(null, null, environment, field);// Terminal (scalar) node, EMPTY FRAME - - - context.setVar(QueryTraversalContext.class, fieldEnv); - return TraversalControl.CONTINUE; - } - - } - - public static Builder newQueryTraversal() { - return new Builder(); - } - - @PublicApi - public static class Builder { - private GraphQLSchema schema; - private Document document; - private String operation; - private Map variables; - - private Node root; - private GraphQLObjectType rootParentType; - private Map fragmentsByName; - - - /** - * The schema used to identify the types of the query. - * - * @param schema the schema to use - * - * @return this builder - */ - public Builder schema(GraphQLSchema schema) { - this.schema = schema; - return this; - } - - /** - * specify the operation if a document is traversed and there - * are more than one operation. - * - * @param operationName the operation name to use - * - * @return this builder - */ - public Builder operationName(String operationName) { - this.operation = operationName; - return this; - } - - /** - * document to be used to traverse the whole query. - * If set a {@link Builder#operationName(String)} might be required. - * - * @param document the document to use - * - * @return this builder - */ - public Builder document(Document document) { - this.document = document; - return this; - } - - /** - * Variables used in the query. - * - * @param variables the variables to use - * - * @return this builder - */ - public Builder variables(Map variables) { - this.variables = variables; - return this; - } - - /** - * Specify the root node for the traversal. Needs to be provided if there is - * no {@link Builder#document(Document)}. - * - * @param root the root node to use - * - * @return this builder - */ - public Builder root(Node root) { - this.root = root; - return this; - } - - /** - * The type of the parent of the root node. (See {@link Builder#root(Node)} - * - * @param rootParentType the root parent type - * - * @return this builder - */ - public Builder rootParentType(GraphQLObjectType rootParentType) { - this.rootParentType = rootParentType; - return this; - } - - /** - * Fragment by name map. Needs to be provided together with a {@link Builder#root(Node)} and {@link Builder#rootParentType(GraphQLObjectType)} - * - * @param fragmentsByName the map of fragments - * - * @return this builder - */ - public Builder fragmentsByName(Map fragmentsByName) { - this.fragmentsByName = fragmentsByName; - return this; - } - - /** - * @return a built {@link graphql.analysis.QueryTraversal} object - */ - public QueryTraversal build() { - checkState(); - if (document != null) { - return new QueryTraversal(schema, document, operation, variables); - } else { - return new QueryTraversal(schema, root, rootParentType, fragmentsByName, variables); - } - } - - private void checkState() { - if (document != null || operation != null) { - if (root != null || rootParentType != null || fragmentsByName != null) { - throw new IllegalStateException("ambiguous builder"); - } - } - } - - } -} diff --git a/src/main/java/graphql/analysis/QueryTraversalContext.java b/src/main/java/graphql/analysis/QueryTraversalContext.java index 31f1eb1baf..8fc02fd582 100644 --- a/src/main/java/graphql/analysis/QueryTraversalContext.java +++ b/src/main/java/graphql/analysis/QueryTraversalContext.java @@ -1,47 +1,52 @@ package graphql.analysis; +import graphql.GraphQLContext; import graphql.Internal; import graphql.language.SelectionSetContainer; import graphql.schema.GraphQLCompositeType; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLTypeUtil; /** - * QueryTraversal helper class that maintains traversal context as + * QueryTraverser helper class that maintains traversal context as * the query traversal algorithm traverses down the Selection AST */ @Internal class QueryTraversalContext { + // never used for scalars/enums, always a possibly wrapped composite type private final GraphQLOutputType outputType; - private final GraphQLCompositeType rawType; private final QueryVisitorFieldEnvironment environment; - private final SelectionSetContainer selectionSetContainer; + private final SelectionSetContainer selectionSetContainer; + private final GraphQLContext graphQLContext; QueryTraversalContext(GraphQLOutputType outputType, - GraphQLCompositeType rawType - , QueryVisitorFieldEnvironment environment, - SelectionSetContainer selectionSetContainer) { + SelectionSetContainer selectionSetContainer, + GraphQLContext graphQLContext) { this.outputType = outputType; - this.rawType = rawType; this.environment = environment; this.selectionSetContainer = selectionSetContainer; + this.graphQLContext = graphQLContext; } public GraphQLOutputType getOutputType() { return outputType; } - public GraphQLCompositeType getRawType() { - return rawType; + public GraphQLCompositeType getUnwrappedOutputType() { + return (GraphQLCompositeType) GraphQLTypeUtil.unwrapAll(outputType); } public QueryVisitorFieldEnvironment getEnvironment() { return environment; } - public SelectionSetContainer getSelectionSetContainer() { - + public SelectionSetContainer getSelectionSetContainer() { return selectionSetContainer; } + + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } } diff --git a/src/main/java/graphql/analysis/QueryTraversalOptions.java b/src/main/java/graphql/analysis/QueryTraversalOptions.java new file mode 100644 index 0000000000..7ce73f05ce --- /dev/null +++ b/src/main/java/graphql/analysis/QueryTraversalOptions.java @@ -0,0 +1,31 @@ +package graphql.analysis; + +import graphql.PublicApi; + +/** + * This options object controls how {@link QueryTraverser} works + */ +@PublicApi +public class QueryTraversalOptions { + + private final boolean coerceFieldArguments; + + private QueryTraversalOptions(boolean coerceFieldArguments) { + this.coerceFieldArguments = coerceFieldArguments; + } + + /** + * @return true if field arguments should be coerced. This is true by default. + */ + public boolean isCoerceFieldArguments() { + return coerceFieldArguments; + } + + public static QueryTraversalOptions defaultOptions() { + return new QueryTraversalOptions(true); + } + + public QueryTraversalOptions coerceFieldArguments(boolean coerceFieldArguments) { + return new QueryTraversalOptions(coerceFieldArguments); + } +} diff --git a/src/main/java/graphql/analysis/QueryTraverser.java b/src/main/java/graphql/analysis/QueryTraverser.java new file mode 100644 index 0000000000..4825dbf746 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryTraverser.java @@ -0,0 +1,393 @@ +package graphql.analysis; + +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.execution.CoercedVariables; +import graphql.execution.RawVariables; +import graphql.execution.ValuesResolver; +import graphql.language.Document; +import graphql.language.FragmentDefinition; +import graphql.language.FragmentSpread; +import graphql.language.Node; +import graphql.language.NodeTraverser; +import graphql.language.NodeUtil; +import graphql.language.OperationDefinition; +import graphql.language.VariableDefinition; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import org.jspecify.annotations.NullUnmarked; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; +import static java.util.Collections.singletonList; + +/** + * Helps to traverse (or reduce) a Document (or parts of it) and tracks at the same time the corresponding Schema types. + *

+ * This is an important distinction to just traversing the Document without any type information: Each field has a clearly + * defined type. See {@link QueryVisitorFieldEnvironment}. + *

+ * Furthermore are the built in Directives skip/include automatically evaluated: if parts of the Document should be ignored they will not + * be visited. But this is not a full evaluation of a Query: every fragment will be visited/followed regardless of the type condition. + *

+ * It also doesn't consider field merging, which means for example {@code { user{firstName} user{firstName}} } will result in four + * visitField calls. + */ +@PublicApi +public class QueryTraverser { + + private final Collection roots; + private final GraphQLSchema schema; + private final Map fragmentsByName; + private CoercedVariables coercedVariables; + + private final GraphQLCompositeType rootParentType; + private final QueryTraversalOptions options; + + private QueryTraverser(GraphQLSchema schema, + Document document, + String operation, + CoercedVariables coercedVariables, + QueryTraversalOptions options + ) { + this.schema = schema; + NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, operation); + this.fragmentsByName = getOperationResult.fragmentsByName; + this.roots = singletonList(getOperationResult.operationDefinition); + this.rootParentType = getRootTypeFromOperation(getOperationResult.operationDefinition); + this.coercedVariables = coercedVariables; + this.options = options; + } + + private QueryTraverser(GraphQLSchema schema, + Document document, + String operation, + RawVariables rawVariables, + QueryTraversalOptions options + ) { + this.schema = schema; + NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, operation); + List variableDefinitions = getOperationResult.operationDefinition.getVariableDefinitions(); + this.fragmentsByName = getOperationResult.fragmentsByName; + this.roots = singletonList(getOperationResult.operationDefinition); + this.rootParentType = getRootTypeFromOperation(getOperationResult.operationDefinition); + this.coercedVariables = ValuesResolver.coerceVariableValues(schema, variableDefinitions, rawVariables, GraphQLContext.getDefault(), Locale.getDefault()); + this.options = options; + } + + private QueryTraverser(GraphQLSchema schema, + Node root, + GraphQLCompositeType rootParentType, + Map fragmentsByName, + CoercedVariables coercedVariables, + QueryTraversalOptions options + ) { + this.schema = schema; + this.roots = Collections.singleton(root); + this.rootParentType = rootParentType; + this.fragmentsByName = fragmentsByName; + this.coercedVariables = coercedVariables; + this.options = options; + } + + public Object visitDepthFirst(QueryVisitor queryVisitor) { + return visitImpl(queryVisitor, null); + } + + /** + * Visits the Document (or parts of it) in post-order. + * + * @param visitor the query visitor that will be called back + */ + public void visitPostOrder(QueryVisitor visitor) { + visitImpl(visitor, false); + } + + /** + * Visits the Document (or parts of it) in pre-order. + * + * @param visitor the query visitor that will be called back + */ + public void visitPreOrder(QueryVisitor visitor) { + visitImpl(visitor, true); + } + + + /** + * Reduces the fields of a Document (or parts of it) to a single value. The fields are visited in post-order. + * + * @param queryReducer the query reducer + * @param initialValue the initial value to pass to the reducer + * @param the type of reduced value + * + * @return the calculated overall value + */ + @SuppressWarnings("unchecked") + public T reducePostOrder(QueryReducer queryReducer, T initialValue) { + // compiler hack to make acc final and mutable :-) + final Object[] acc = {initialValue}; + visitPostOrder(new QueryVisitorStub() { + @Override + public void visitField(QueryVisitorFieldEnvironment env) { + acc[0] = queryReducer.reduceField(env, (T) acc[0]); + } + }); + return (T) acc[0]; + } + + /** + * Reduces the fields of a Document (or parts of it) to a single value. The fields are visited in pre-order. + * + * @param queryReducer the query reducer + * @param initialValue the initial value to pass to the reducer + * @param the type of reduced value + * + * @return the calculated overall value + */ + @SuppressWarnings("unchecked") + public T reducePreOrder(QueryReducer queryReducer, T initialValue) { + // compiler hack to make acc final and mutable :-) + final Object[] acc = {initialValue}; + visitPreOrder(new QueryVisitorStub() { + @Override + public void visitField(QueryVisitorFieldEnvironment env) { + acc[0] = queryReducer.reduceField(env, (T) acc[0]); + } + }); + return (T) acc[0]; + } + + private GraphQLObjectType getRootTypeFromOperation(OperationDefinition operationDefinition) { + switch (operationDefinition.getOperation()) { + case MUTATION: + return assertNotNull(schema.getMutationType()); + case QUERY: + return assertNotNull(schema.getQueryType()); + case SUBSCRIPTION: + return assertNotNull(schema.getSubscriptionType()); + default: + return assertShouldNeverHappen(); + } + } + + private List childrenOf(Node node) { + if (!(node instanceof FragmentSpread)) { + return node.getChildren(); + } + FragmentSpread fragmentSpread = (FragmentSpread) node; + return singletonList(fragmentsByName.get(fragmentSpread.getName())); + } + + private Object visitImpl(QueryVisitor visitFieldCallback, Boolean preOrder) { + Map, Object> rootVars = new LinkedHashMap<>(); + rootVars.put(QueryTraversalContext.class, new QueryTraversalContext(rootParentType, null, null, GraphQLContext.getDefault())); + + QueryVisitor preOrderCallback; + QueryVisitor postOrderCallback; + if (preOrder == null) { + preOrderCallback = visitFieldCallback; + postOrderCallback = visitFieldCallback; + } else { + QueryVisitor noOp = new QueryVisitorStub(); + preOrderCallback = preOrder ? visitFieldCallback : noOp; + postOrderCallback = !preOrder ? visitFieldCallback : noOp; + } + + NodeTraverser nodeTraverser = new NodeTraverser(rootVars, this::childrenOf); + NodeVisitorWithTypeTracking nodeVisitorWithTypeTracking = new NodeVisitorWithTypeTracking(preOrderCallback, + postOrderCallback, + coercedVariables.toMap(), + schema, + fragmentsByName, + options); + return nodeTraverser.depthFirst(nodeVisitorWithTypeTracking, roots); + } + + public static Builder newQueryTraverser() { + return new Builder(); + } + + @PublicApi + @NullUnmarked + public static class Builder { + private GraphQLSchema schema; + private Document document; + private String operation; + private CoercedVariables coercedVariables = CoercedVariables.emptyVariables(); + private RawVariables rawVariables; + + private Node root; + private GraphQLCompositeType rootParentType; + private Map fragmentsByName; + private QueryTraversalOptions options = QueryTraversalOptions.defaultOptions(); + + + /** + * The schema used to identify the types of the query. + * + * @param schema the schema to use + * + * @return this builder + */ + public Builder schema(GraphQLSchema schema) { + this.schema = assertNotNull(schema, "schema can't be null"); + return this; + } + + /** + * specify the operation if a document is traversed and there + * are more than one operation. + * + * @param operationName the operation name to use + * + * @return this builder + */ + public Builder operationName(String operationName) { + this.operation = operationName; + return this; + } + + /** + * document to be used to traverse the whole query. + * If set a {@link Builder#operationName(String)} might be required. + * + * @param document the document to use + * + * @return this builder + */ + public Builder document(Document document) { + this.document = assertNotNull(document, "document can't be null"); + return this; + } + + /** + * Raw variables used in the query. + * + * @param variables the variables to use + * + * @return this builder + */ + public Builder variables(Map variables) { + assertNotNull(variables, "variables can't be null"); + this.rawVariables = RawVariables.of(variables); + return this; + } + + /** + * Variables (already coerced) used in the query. + * + * @param coercedVariables the variables to use + * + * @return this builder + */ + public Builder coercedVariables(CoercedVariables coercedVariables) { + assertNotNull(coercedVariables, "coercedVariables can't be null"); + this.coercedVariables = coercedVariables; + return this; + } + + /** + * Specify the root node for the traversal. Needs to be provided if there is + * no {@link Builder#document(Document)}. + * + * @param root the root node to use + * + * @return this builder + */ + public Builder root(Node root) { + this.root = assertNotNull(root, "root can't be null"); + return this; + } + + /** + * The type of the parent of the root node. (See {@link Builder#root(Node)} + * + * @param rootParentType the root parent type + * + * @return this builder + */ + public Builder rootParentType(GraphQLCompositeType rootParentType) { + this.rootParentType = assertNotNull(rootParentType, "rootParentType can't be null"); + return this; + } + + /** + * Fragment by name map. Needs to be provided together with a {@link Builder#root(Node)} and {@link Builder#rootParentType(GraphQLCompositeType)} + * + * @param fragmentsByName the map of fragments + * + * @return this builder + */ + public Builder fragmentsByName(Map fragmentsByName) { + this.fragmentsByName = assertNotNull(fragmentsByName, "fragmentsByName can't be null"); + return this; + } + + /** + * Sets the options to use while traversing + * + * @param options the options to use + * @return this builder + */ + public Builder options(QueryTraversalOptions options) { + this.options = assertNotNull(options, "options can't be null"); + return this; + } + + /** + * @return a built {@link QueryTraverser} object + */ + public QueryTraverser build() { + checkState(); + if (document != null) { + if (rawVariables != null) { + return new QueryTraverser(schema, + document, + operation, + rawVariables, + options); + } + return new QueryTraverser(schema, + document, + operation, + coercedVariables, + options); + } else { + if (rawVariables != null) { + // When traversing with an arbitrary root, there is no variable definition context available + // Thus, the variables must have already been coerced + // Retaining this builder for backwards compatibility + return new QueryTraverser(schema, + root, + rootParentType, + fragmentsByName, + CoercedVariables.of(rawVariables.toMap()), + options); + } + return new QueryTraverser(schema, + root, + rootParentType, + fragmentsByName, + coercedVariables, + options); + } + } + + private void checkState() { + if (document != null || operation != null) { + if (root != null || rootParentType != null || fragmentsByName != null) { + throw new IllegalStateException("ambiguous builder"); + } + } + } + + } +} diff --git a/src/main/java/graphql/analysis/QueryVisitor.java b/src/main/java/graphql/analysis/QueryVisitor.java index 9a39344b54..69d86f2449 100644 --- a/src/main/java/graphql/analysis/QueryVisitor.java +++ b/src/main/java/graphql/analysis/QueryVisitor.java @@ -1,19 +1,43 @@ package graphql.analysis; import graphql.PublicApi; +import graphql.util.TraversalControl; /** - * Used by {@link QueryTraversal} to visit the nodes of a Query. + * Used by {@link QueryTraverser} to visit the nodes of a Query. *

- * How this happens in detail (pre vs post-order for example) is defined by {@link QueryTraversal}. + * How this happens in detail (pre vs post-order for example) is defined by {@link QueryTraverser}. */ @PublicApi public interface QueryVisitor { void visitField(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment); + /** + * visitField variant which lets you control the traversal. + * default implementation calls visitField for backwards compatibility reason + * + * @param queryVisitorFieldEnvironment the environment in play + * @return traversal control + */ + default TraversalControl visitFieldWithControl(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment) { + visitField(queryVisitorFieldEnvironment); + return TraversalControl.CONTINUE; + } + void visitInlineFragment(QueryVisitorInlineFragmentEnvironment queryVisitorInlineFragmentEnvironment); void visitFragmentSpread(QueryVisitorFragmentSpreadEnvironment queryVisitorFragmentSpreadEnvironment); + default void visitFragmentDefinition(QueryVisitorFragmentDefinitionEnvironment queryVisitorFragmentDefinitionEnvironment) { + + } + + default TraversalControl visitArgument(QueryVisitorFieldArgumentEnvironment environment) { + return TraversalControl.CONTINUE; + } + + default TraversalControl visitArgumentValue(QueryVisitorFieldArgumentValueEnvironment environment) { + return TraversalControl.CONTINUE; + } } diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldArgumentEnvironment.java b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentEnvironment.java new file mode 100644 index 0000000000..adf31abe42 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentEnvironment.java @@ -0,0 +1,31 @@ +package graphql.analysis; + +import graphql.PublicApi; +import graphql.language.Argument; +import graphql.language.Node; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; + +import java.util.Map; + +@PublicApi +public interface QueryVisitorFieldArgumentEnvironment { + + GraphQLSchema getSchema(); + + GraphQLFieldDefinition getFieldDefinition(); + + GraphQLArgument getGraphQLArgument(); + + Argument getArgument(); + + Object getArgumentValue(); + + Map getVariables(); + + QueryVisitorFieldEnvironment getParentEnvironment(); + + TraverserContext getTraverserContext(); +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldArgumentEnvironmentImpl.java b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentEnvironmentImpl.java new file mode 100644 index 0000000000..22f1de9afd --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentEnvironmentImpl.java @@ -0,0 +1,87 @@ +package graphql.analysis; + +import graphql.Internal; +import graphql.language.Argument; +import graphql.language.Node; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; + +import java.util.Map; + +@Internal +public class QueryVisitorFieldArgumentEnvironmentImpl implements QueryVisitorFieldArgumentEnvironment { + + private final GraphQLFieldDefinition fieldDefinition; + private final Argument argument; + private final GraphQLArgument graphQLArgument; + private final Object argumentValue; + private final Map variables; + private final QueryVisitorFieldEnvironment parentEnvironment; + private final TraverserContext traverserContext; + private final GraphQLSchema schema; + + public QueryVisitorFieldArgumentEnvironmentImpl(GraphQLFieldDefinition fieldDefinition, Argument argument, GraphQLArgument graphQLArgument, Object argumentValue, Map variables, QueryVisitorFieldEnvironment parentEnvironment, TraverserContext traverserContext, GraphQLSchema schema) { + this.fieldDefinition = fieldDefinition; + this.argument = argument; + this.graphQLArgument = graphQLArgument; + this.argumentValue = argumentValue; + this.variables = variables; + this.parentEnvironment = parentEnvironment; + this.traverserContext = traverserContext; + this.schema = schema; + } + + @Override + public GraphQLSchema getSchema() { + return schema; + } + + @Override + public Argument getArgument() { + return argument; + } + + public GraphQLFieldDefinition getFieldDefinition() { + return fieldDefinition; + } + + @Override + public GraphQLArgument getGraphQLArgument() { + return graphQLArgument; + } + + @Override + public Object getArgumentValue() { + return argumentValue; + } + + @Override + public Map getVariables() { + return variables; + } + + @Override + public QueryVisitorFieldEnvironment getParentEnvironment() { + return parentEnvironment; + } + + @Override + public TraverserContext getTraverserContext() { + return traverserContext; + } + + @Override + public String toString() { + return "QueryVisitorFieldArgumentEnvironmentImpl{" + + "fieldDefinition=" + fieldDefinition + + ", argument=" + argument + + ", graphQLArgument=" + graphQLArgument + + ", argumentValue=" + argumentValue + + ", variables=" + variables + + ", traverserContext=" + traverserContext + + ", schema=" + schema + + '}'; + } +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldArgumentInputValue.java b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentInputValue.java new file mode 100644 index 0000000000..106e596ae0 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentInputValue.java @@ -0,0 +1,25 @@ +package graphql.analysis; + +import graphql.PublicApi; +import graphql.language.Value; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLInputValueDefinition; + +/** + * This describes the tree structure that forms from a argument input type, + * especially with `input ComplexType { ....}` types that might in turn contain other complex + * types and hence form a tree of values. + */ +@PublicApi +public interface QueryVisitorFieldArgumentInputValue { + + QueryVisitorFieldArgumentInputValue getParent(); + + GraphQLInputValueDefinition getInputValueDefinition(); + + String getName(); + + GraphQLInputType getInputType(); + + Value getValue(); +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldArgumentInputValueImpl.java b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentInputValueImpl.java new file mode 100644 index 0000000000..f12751bb42 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentInputValueImpl.java @@ -0,0 +1,69 @@ +package graphql.analysis; + +import graphql.Internal; +import graphql.language.Value; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLInputValueDefinition; + +@Internal +public class QueryVisitorFieldArgumentInputValueImpl implements QueryVisitorFieldArgumentInputValue { + private final GraphQLInputValueDefinition inputValueDefinition; + private final Value value; + private final QueryVisitorFieldArgumentInputValue parent; + + private QueryVisitorFieldArgumentInputValueImpl(QueryVisitorFieldArgumentInputValue parent, GraphQLInputValueDefinition inputValueDefinition, Value value) { + this.parent = parent; + this.inputValueDefinition = inputValueDefinition; + this.value = value; + } + + static QueryVisitorFieldArgumentInputValue incompleteArgumentInputValue(GraphQLArgument graphQLArgument) { + return new QueryVisitorFieldArgumentInputValueImpl( + null, graphQLArgument, null); + } + + QueryVisitorFieldArgumentInputValueImpl incompleteNewChild(GraphQLInputObjectField inputObjectField) { + return new QueryVisitorFieldArgumentInputValueImpl( + this, inputObjectField, null); + } + + QueryVisitorFieldArgumentInputValueImpl completeArgumentInputValue(Value value) { + return new QueryVisitorFieldArgumentInputValueImpl( + this.parent, this.inputValueDefinition, value); + } + + + @Override + public QueryVisitorFieldArgumentInputValue getParent() { + return parent; + } + + public GraphQLInputValueDefinition getInputValueDefinition() { + return inputValueDefinition; + } + + @Override + public String getName() { + return inputValueDefinition.getName(); + } + + @Override + public GraphQLInputType getInputType() { + return inputValueDefinition.getType(); + } + + @Override + public Value getValue() { + return value; + } + + @Override + public String toString() { + return "QueryVisitorFieldArgumentInputValueImpl{" + + "inputValue=" + inputValueDefinition + + ", value=" + value + + '}'; + } +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldArgumentValueEnvironment.java b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentValueEnvironment.java new file mode 100644 index 0000000000..5da2d02e8a --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentValueEnvironment.java @@ -0,0 +1,27 @@ +package graphql.analysis; + +import graphql.PublicApi; +import graphql.language.Node; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; + +import java.util.Map; + +@PublicApi +public interface QueryVisitorFieldArgumentValueEnvironment { + + GraphQLSchema getSchema(); + + GraphQLFieldDefinition getFieldDefinition(); + + GraphQLArgument getGraphQLArgument(); + + QueryVisitorFieldArgumentInputValue getArgumentInputValue(); + + Map getVariables(); + + TraverserContext getTraverserContext(); + +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldArgumentValueEnvironmentImpl.java b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentValueEnvironmentImpl.java new file mode 100644 index 0000000000..f6e87d8a06 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFieldArgumentValueEnvironmentImpl.java @@ -0,0 +1,71 @@ +package graphql.analysis; + +import graphql.Internal; +import graphql.language.Node; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; + +import java.util.Map; + +@Internal +public class QueryVisitorFieldArgumentValueEnvironmentImpl implements QueryVisitorFieldArgumentValueEnvironment { + + private final GraphQLFieldDefinition fieldDefinition; + private final GraphQLArgument graphQLArgument; + private final QueryVisitorFieldArgumentInputValue argumentInputValue; + private final TraverserContext traverserContext; + private final GraphQLSchema schema; + private final Map variables; + + public QueryVisitorFieldArgumentValueEnvironmentImpl(GraphQLSchema schema, GraphQLFieldDefinition fieldDefinition, GraphQLArgument graphQLArgument, QueryVisitorFieldArgumentInputValue argumentInputValue, TraverserContext traverserContext, Map variables) { + this.fieldDefinition = fieldDefinition; + this.graphQLArgument = graphQLArgument; + this.argumentInputValue = argumentInputValue; + this.traverserContext = traverserContext; + this.schema = schema; + this.variables = variables; + } + + @Override + public GraphQLSchema getSchema() { + return schema; + } + + @Override + public GraphQLFieldDefinition getFieldDefinition() { + return fieldDefinition; + } + + @Override + public GraphQLArgument getGraphQLArgument() { + return graphQLArgument; + } + + @Override + public QueryVisitorFieldArgumentInputValue getArgumentInputValue() { + return argumentInputValue; + } + + @Override + public Map getVariables() { + return variables; + } + + @Override + public TraverserContext getTraverserContext() { + return traverserContext; + } + + @Override + public String toString() { + return "QueryVisitorFieldArgumentValueEnvironmentImpl{" + + "fieldDefinition=" + fieldDefinition + + ", graphQLArgument=" + graphQLArgument + + ", argumentInputValue=" + argumentInputValue + + ", traverserContext=" + traverserContext + + ", schema=" + schema + + '}'; + } +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldEnvironment.java b/src/main/java/graphql/analysis/QueryVisitorFieldEnvironment.java index faed5ecb09..608c5205df 100644 --- a/src/main/java/graphql/analysis/QueryVisitorFieldEnvironment.java +++ b/src/main/java/graphql/analysis/QueryVisitorFieldEnvironment.java @@ -2,16 +2,24 @@ import graphql.PublicApi; import graphql.language.Field; +import graphql.language.Node; import graphql.language.SelectionSetContainer; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; import java.util.Map; @PublicApi public interface QueryVisitorFieldEnvironment { + /** + * @return the graphql schema in play + */ + GraphQLSchema getSchema(); + /** * @return true if the current field is __typename */ @@ -30,7 +38,9 @@ public interface QueryVisitorFieldEnvironment { GraphQLOutputType getParentType(); /** - * @return the unmodified fields container fot the current type + * @return the unmodified fields container fot the current type. This is the unwrapped version of {@link #getParentType()} + * It is either {@link graphql.schema.GraphQLObjectType} or {@link graphql.schema.GraphQLInterfaceType}. because these + * are the only {@link GraphQLFieldsContainer} * * @throws IllegalStateException if the current field is __typename see {@link #isTypeNameIntrospectionField()} */ @@ -41,4 +51,6 @@ public interface QueryVisitorFieldEnvironment { Map getArguments(); SelectionSetContainer getSelectionSetContainer(); + + TraverserContext getTraverserContext(); } diff --git a/src/main/java/graphql/analysis/QueryVisitorFieldEnvironmentImpl.java b/src/main/java/graphql/analysis/QueryVisitorFieldEnvironmentImpl.java index fc3ea57927..77da33450b 100644 --- a/src/main/java/graphql/analysis/QueryVisitorFieldEnvironmentImpl.java +++ b/src/main/java/graphql/analysis/QueryVisitorFieldEnvironmentImpl.java @@ -2,10 +2,13 @@ import graphql.Internal; import graphql.language.Field; +import graphql.language.Node; import graphql.language.SelectionSetContainer; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; import java.util.Map; import java.util.Objects; @@ -21,6 +24,8 @@ public class QueryVisitorFieldEnvironmentImpl implements QueryVisitorFieldEnviro private final Map arguments; private final QueryVisitorFieldEnvironment parentEnvironment; private final SelectionSetContainer selectionSetContainer; + private final TraverserContext traverserContext; + private final GraphQLSchema schema; public QueryVisitorFieldEnvironmentImpl(boolean typeNameIntrospectionField, Field field, @@ -29,7 +34,9 @@ public QueryVisitorFieldEnvironmentImpl(boolean typeNameIntrospectionField, GraphQLFieldsContainer unmodifiedParentType, QueryVisitorFieldEnvironment parentEnvironment, Map arguments, - SelectionSetContainer selectionSetContainer) { + SelectionSetContainer selectionSetContainer, + TraverserContext traverserContext, + GraphQLSchema schema) { this.typeNameIntrospectionField = typeNameIntrospectionField; this.field = field; this.fieldDefinition = fieldDefinition; @@ -38,6 +45,13 @@ public QueryVisitorFieldEnvironmentImpl(boolean typeNameIntrospectionField, this.parentEnvironment = parentEnvironment; this.arguments = arguments; this.selectionSetContainer = selectionSetContainer; + this.traverserContext = traverserContext; + this.schema = schema; + } + + @Override + public GraphQLSchema getSchema() { + return schema; } @Override @@ -83,6 +97,11 @@ public boolean isTypeNameIntrospectionField() { return typeNameIntrospectionField; } + @Override + public TraverserContext getTraverserContext() { + return traverserContext; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -100,8 +119,16 @@ public boolean equals(Object o) { @Override public int hashCode() { - - return Objects.hash(typeNameIntrospectionField, field, fieldDefinition, parentType, unmodifiedParentType, arguments, parentEnvironment, selectionSetContainer); + int result = 1; + result = 31 * result + Objects.hashCode(typeNameIntrospectionField); + result = 31 * result + Objects.hashCode(field); + result = 31 * result + Objects.hashCode(fieldDefinition); + result = 31 * result + Objects.hashCode(parentType); + result = 31 * result + Objects.hashCode(unmodifiedParentType); + result = 31 * result + Objects.hashCode(arguments); + result = 31 * result + Objects.hashCode(parentEnvironment); + result = 31 * result + Objects.hashCode(selectionSetContainer); + return result; } @Override @@ -110,7 +137,6 @@ public String toString() { "field=" + field + ", fieldDefinition=" + fieldDefinition + ", parentType=" + parentType + - ", parentEnvironment=" + parentEnvironment + ", arguments=" + arguments + '}'; } diff --git a/src/main/java/graphql/analysis/QueryVisitorFragmentDefinitionEnvironment.java b/src/main/java/graphql/analysis/QueryVisitorFragmentDefinitionEnvironment.java new file mode 100644 index 0000000000..da9ab15600 --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFragmentDefinitionEnvironment.java @@ -0,0 +1,20 @@ +package graphql.analysis; + +import graphql.PublicApi; +import graphql.language.FragmentDefinition; +import graphql.language.Node; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; + +@PublicApi +public interface QueryVisitorFragmentDefinitionEnvironment { + + /** + * @return the graphql schema in play + */ + GraphQLSchema getSchema(); + + FragmentDefinition getFragmentDefinition(); + + TraverserContext getTraverserContext(); +} diff --git a/src/main/java/graphql/analysis/QueryVisitorFragmentDefinitionEnvironmentImpl.java b/src/main/java/graphql/analysis/QueryVisitorFragmentDefinitionEnvironmentImpl.java new file mode 100644 index 0000000000..926a0d22ca --- /dev/null +++ b/src/main/java/graphql/analysis/QueryVisitorFragmentDefinitionEnvironmentImpl.java @@ -0,0 +1,64 @@ +package graphql.analysis; + +import graphql.Internal; +import graphql.language.FragmentDefinition; +import graphql.language.Node; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; + +import java.util.Objects; + +@Internal +public class QueryVisitorFragmentDefinitionEnvironmentImpl implements QueryVisitorFragmentDefinitionEnvironment { + + private final FragmentDefinition fragmentDefinition; + private final TraverserContext traverserContext; + private final GraphQLSchema schema; + + + public QueryVisitorFragmentDefinitionEnvironmentImpl(FragmentDefinition fragmentDefinition, TraverserContext traverserContext, GraphQLSchema schema) { + this.fragmentDefinition = fragmentDefinition; + this.traverserContext = traverserContext; + this.schema = schema; + } + + @Override + public GraphQLSchema getSchema() { + return schema; + } + + @Override + public FragmentDefinition getFragmentDefinition() { + return fragmentDefinition; + } + + @Override + public TraverserContext getTraverserContext() { + return traverserContext; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + QueryVisitorFragmentDefinitionEnvironmentImpl that = (QueryVisitorFragmentDefinitionEnvironmentImpl) o; + return Objects.equals(fragmentDefinition, that.fragmentDefinition); + } + + @Override + public int hashCode() { + return Objects.hashCode(fragmentDefinition); + } + + @Override + public String toString() { + return "QueryVisitorFragmentDefinitionEnvironmentImpl{" + + "fragmentDefinition=" + fragmentDefinition + + '}'; + } +} + diff --git a/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironment.java b/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironment.java index 7621046b13..4d70f24753 100644 --- a/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironment.java +++ b/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironment.java @@ -3,10 +3,21 @@ import graphql.PublicApi; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; +import graphql.language.Node; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; @PublicApi public interface QueryVisitorFragmentSpreadEnvironment { + + /** + * @return the graphql schema in play + */ + GraphQLSchema getSchema(); + FragmentSpread getFragmentSpread(); FragmentDefinition getFragmentDefinition(); + + TraverserContext getTraverserContext(); } diff --git a/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironmentImpl.java b/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironmentImpl.java index ca0ab18122..b068fcb380 100644 --- a/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironmentImpl.java +++ b/src/main/java/graphql/analysis/QueryVisitorFragmentSpreadEnvironmentImpl.java @@ -3,6 +3,9 @@ import graphql.Internal; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; +import graphql.language.Node; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; import java.util.Objects; @@ -11,10 +14,20 @@ public class QueryVisitorFragmentSpreadEnvironmentImpl implements QueryVisitorFr private final FragmentSpread fragmentSpread; private final FragmentDefinition fragmentDefinition; + private final TraverserContext traverserContext; + private final GraphQLSchema schema; - public QueryVisitorFragmentSpreadEnvironmentImpl(FragmentSpread fragmentSpread, FragmentDefinition fragmentDefinition) { + + public QueryVisitorFragmentSpreadEnvironmentImpl(FragmentSpread fragmentSpread, FragmentDefinition fragmentDefinition, TraverserContext traverserContext, GraphQLSchema schema) { this.fragmentSpread = fragmentSpread; this.fragmentDefinition = fragmentDefinition; + this.traverserContext = traverserContext; + this.schema = schema; + } + + @Override + public GraphQLSchema getSchema() { + return schema; } @Override @@ -27,6 +40,11 @@ public FragmentDefinition getFragmentDefinition() { return fragmentDefinition; } + @Override + public TraverserContext getTraverserContext() { + return traverserContext; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -37,7 +55,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(fragmentSpread); + return Objects.hashCode(fragmentSpread); } } diff --git a/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironment.java b/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironment.java index faa7a5f43b..699b5b453a 100644 --- a/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironment.java +++ b/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironment.java @@ -2,8 +2,19 @@ import graphql.PublicApi; import graphql.language.InlineFragment; +import graphql.language.Node; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; @PublicApi public interface QueryVisitorInlineFragmentEnvironment { + + /** + * @return the graphql schema in play + */ + GraphQLSchema getSchema(); + InlineFragment getInlineFragment(); + + TraverserContext getTraverserContext(); } diff --git a/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironmentImpl.java b/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironmentImpl.java index 98ad258512..5a5d339f06 100644 --- a/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironmentImpl.java +++ b/src/main/java/graphql/analysis/QueryVisitorInlineFragmentEnvironmentImpl.java @@ -2,15 +2,27 @@ import graphql.Internal; import graphql.language.InlineFragment; +import graphql.language.Node; +import graphql.schema.GraphQLSchema; +import graphql.util.TraverserContext; import java.util.Objects; @Internal public class QueryVisitorInlineFragmentEnvironmentImpl implements QueryVisitorInlineFragmentEnvironment { private final InlineFragment inlineFragment; + private final TraverserContext traverserContext; + private final GraphQLSchema schema; - public QueryVisitorInlineFragmentEnvironmentImpl(InlineFragment inlineFragment) { + public QueryVisitorInlineFragmentEnvironmentImpl(InlineFragment inlineFragment, TraverserContext traverserContext, GraphQLSchema schema) { this.inlineFragment = inlineFragment; + this.traverserContext = traverserContext; + this.schema = schema; + } + + @Override + public GraphQLSchema getSchema() { + return schema; } @Override @@ -18,6 +30,11 @@ public InlineFragment getInlineFragment() { return inlineFragment; } + @Override + public TraverserContext getTraverserContext() { + return traverserContext; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -28,8 +45,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - - return Objects.hash(inlineFragment); + return Objects.hashCode(inlineFragment); } @Override diff --git a/src/main/java/graphql/analysis/values/ValueTraverser.java b/src/main/java/graphql/analysis/values/ValueTraverser.java new file mode 100644 index 0000000000..664cda26be --- /dev/null +++ b/src/main/java/graphql/analysis/values/ValueTraverser.java @@ -0,0 +1,321 @@ +package graphql.analysis.values; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.DataFetchingEnvironmentImpl; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputSchemaElement; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLInputValueDefinition; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLTypeUtil; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Assert.assertTrue; +import static graphql.analysis.values.ValueVisitor.ABSENCE_SENTINEL; + +/** + * This class allows you to traverse a set of input values according to the type system and optional + * change the values present. + *

+ * If you just want to traverse without changing anything, just return the value presented to you and nothing will change. + *

+ * If you want to change a value, perhaps in the presence of a directive say on the containing element, then return + * a new value back in your visitor. + *

+ * This class is intended to be used say inside a DataFetcher, allowing you to change the {@link DataFetchingEnvironment#getArguments()} + * say before further processing. + *

+ * The values passed in are assumed to be valid and coerced. This classes does not check for non nullness say or the right coerced objects given + * the type system. This is assumed to have occurred earlier in the graphql validation phase. This also means if you are not careful you can undo the + * validation that has gone before you. For example, it would be possible to change values that are illegal according to the type system, such as + * null values for non-nullable types say, so you need to be careful. + */ +@PublicApi +public class ValueTraverser { + + private static class InputElements implements ValueVisitor.InputElements { + + private final ImmutableList inputElements; + private final List unwrappedInputElements; + private final GraphQLInputValueDefinition lastElement; + + private InputElements(GraphQLInputSchemaElement startElement) { + this.inputElements = ImmutableList.of(startElement); + this.unwrappedInputElements = ImmutableList.of(startElement); + this.lastElement = startElement instanceof GraphQLInputValueDefinition ? (GraphQLInputValueDefinition) startElement : null; + } + + private InputElements(ImmutableList inputElements) { + this.inputElements = inputElements; + this.unwrappedInputElements = ImmutableKit.filter(inputElements, + it -> !(it instanceof GraphQLNonNull || it instanceof GraphQLList)); + + List inputValDefs = ImmutableKit.filterAndMap(unwrappedInputElements, + it -> it instanceof GraphQLInputValueDefinition, + GraphQLInputValueDefinition.class::cast); + this.lastElement = inputValDefs.isEmpty() ? null : inputValDefs.get(inputValDefs.size() - 1); + } + + + private InputElements push(GraphQLInputSchemaElement inputElement) { + ImmutableList newSchemaElements = ImmutableList.builder() + .addAll(inputElements).add(inputElement).build(); + return new InputElements(newSchemaElements); + } + + @Override + public List getInputElements() { + return inputElements; + } + + public List getUnwrappedInputElements() { + return unwrappedInputElements; + } + + @Override + public GraphQLInputValueDefinition getLastInputValueDefinition() { + return lastElement; + } + } + + /** + * This will visit the arguments of a {@link DataFetchingEnvironment} and if the values are changed by the visitor a new environment will be built + * + * @param environment the starting data fetching environment + * @param visitor the visitor to use + * + * @return the same environment if nothing changes or a new one with the {@link DataFetchingEnvironment#getArguments()} changed + */ + public static DataFetchingEnvironment visitPreOrder(DataFetchingEnvironment environment, ValueVisitor visitor) { + GraphQLFieldDefinition fieldDefinition = environment.getFieldDefinition(); + Map originalArgs = environment.getArguments(); + Map newArgs = visitPreOrder(originalArgs, fieldDefinition, visitor); + if (newArgs != originalArgs) { + return DataFetchingEnvironmentImpl.newDataFetchingEnvironment(environment).arguments(newArgs).build(); + } + return environment; + } + + /** + * This will visit the arguments of a {@link GraphQLFieldDefinition} and if the visitor changes the values, it will return a new set of arguments + * + * @param coercedArgumentValues the starting coerced arguments + * @param fieldDefinition the field definition + * @param visitor the visitor to use + * + * @return the same set of arguments if nothing changes or new ones if the visitor changes anything + */ + public static Map visitPreOrder(Map coercedArgumentValues, GraphQLFieldDefinition fieldDefinition, ValueVisitor visitor) { + List fieldArguments = fieldDefinition.getArguments(); + boolean copied = false; + for (GraphQLArgument fieldArgument : fieldArguments) { + String key = fieldArgument.getName(); + Object argValue = coercedArgumentValues.get(key); + InputElements inputElements = new InputElements(fieldArgument); + Object newValue = visitor.visitArgumentValue(argValue, fieldArgument, inputElements); + if (hasChanged(newValue, argValue)) { + if (!copied) { + coercedArgumentValues = new LinkedHashMap<>(coercedArgumentValues); + copied = true; + } + setNewValue(coercedArgumentValues, key, newValue); + } + if (newValue != ABSENCE_SENTINEL) { + newValue = visitPreOrderImpl(argValue, fieldArgument.getType(), inputElements, visitor); + if (hasChanged(newValue, argValue)) { + if (!copied) { + coercedArgumentValues = new LinkedHashMap<>(coercedArgumentValues); + copied = true; + } + setNewValue(coercedArgumentValues, key, newValue); + } + } + } + return coercedArgumentValues; + } + + /** + * This will visit a single argument of a {@link GraphQLArgument} and if the visitor changes the value, it will return a new argument value + *

+ * Note you cannot return the ABSENCE_SENTINEL from this method as its makes no sense to be somehow make the argument disappear. Use + * {@link #visitPreOrder(Map, GraphQLFieldDefinition, ValueVisitor)} say to remove arguments in the fields map of arguments. + * + * @param coercedArgumentValue the starting coerced argument value + * @param argument the argument definition + * @param visitor the visitor to use + * + * @return the same value if nothing changes or a new value if the visitor changes anything + */ + public static Object visitPreOrder(Object coercedArgumentValue, GraphQLArgument argument, ValueVisitor visitor) { + InputElements inputElements = new InputElements(argument); + Object newValue = visitor.visitArgumentValue(coercedArgumentValue, argument, inputElements); + if (newValue == ABSENCE_SENTINEL) { + assertShouldNeverHappen("It makes no sense to return the ABSENCE_SENTINEL during the visitPreOrder GraphQLArgument method"); + } + newValue = visitPreOrderImpl(newValue, argument.getType(), inputElements, visitor); + if (newValue == ABSENCE_SENTINEL) { + assertShouldNeverHappen("It makes no sense to return the ABSENCE_SENTINEL during the visitPreOrder GraphQLArgument method"); + } + return newValue; + } + + /** + * This will visit a single argument of a {@link GraphQLAppliedDirective} and if the visitor changes the value, it will return a new argument value + *

+ * Note you cannot return the ABSENCE_SENTINEL from this method as its makes no sense to be somehow make the argument disappear. + * + * @param coercedArgumentValue the starting coerced argument value + * @param argument the applied argument + * @param visitor the visitor to use + * + * @return the same value if nothing changes or a new value if the visitor changes anything + */ + public static Object visitPreOrder(Object coercedArgumentValue, GraphQLAppliedDirectiveArgument argument, ValueVisitor visitor) { + InputElements inputElements = new InputElements(argument); + Object newValue = visitor.visitAppliedDirectiveArgumentValue(coercedArgumentValue, argument, inputElements); + if (newValue == ABSENCE_SENTINEL) { + assertShouldNeverHappen("It makes no sense to return the ABSENCE_SENTINEL during the visitPreOrder GraphQLAppliedDirectiveArgument method"); + } + newValue = visitPreOrderImpl(newValue, argument.getType(), inputElements, visitor); + if (newValue == ABSENCE_SENTINEL) { + assertShouldNeverHappen("It makes no sense to return the ABSENCE_SENTINEL during the visitPreOrder GraphQLAppliedDirectiveArgument method"); + } + return newValue; + } + + private static Object visitPreOrderImpl(Object coercedValue, GraphQLInputType startingInputType, InputElements containingElements, ValueVisitor visitor) { + if (startingInputType instanceof GraphQLNonNull) { + containingElements = containingElements.push(startingInputType); + } + GraphQLInputType inputType = GraphQLTypeUtil.unwrapNonNullAs(startingInputType); + containingElements = containingElements.push(inputType); + if (inputType instanceof GraphQLList) { + return visitListValue(coercedValue, (GraphQLList) inputType, containingElements, visitor); + } else if (inputType instanceof GraphQLInputObjectType) { + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) inputType; + return visitObjectValue(coercedValue, inputObjectType, containingElements, visitor); + } else if (inputType instanceof GraphQLScalarType) { + return visitor.visitScalarValue(coercedValue, (GraphQLScalarType) inputType, containingElements); + } else if (inputType instanceof GraphQLEnumType) { + return visitor.visitEnumValue(coercedValue, (GraphQLEnumType) inputType, containingElements); + } else { + return assertShouldNeverHappen("ValueTraverser can only be called on full materialised schemas"); + } + } + + private static Object visitObjectValue(Object coercedValue, GraphQLInputObjectType inputObjectType, InputElements containingElements, ValueVisitor visitor) { + if (coercedValue != null) { + assertTrue(coercedValue instanceof Map, "A input object type MUST have an Map value"); + } + @SuppressWarnings("unchecked") + Map map = (Map) coercedValue; + Map newMap = visitor.visitInputObjectValue(map, inputObjectType, containingElements); + if (newMap == ABSENCE_SENTINEL) { + return ABSENCE_SENTINEL; + } + if (newMap != null) { + boolean copied = false; + for (Map.Entry entry : newMap.entrySet()) { + String key = entry.getKey(); + GraphQLInputObjectField inputField = inputObjectType.getField(key); + /// should we assert if the map contain a key that's not a field ? + if (inputField != null) { + InputElements inputElementsWithField = containingElements.push(inputField); + Object newValue = visitor.visitInputObjectFieldValue(entry.getValue(), inputObjectType, inputField, inputElementsWithField); + if (hasChanged(newValue, entry.getValue())) { + if (!copied) { + newMap = new LinkedHashMap<>(newMap); + copied = true; + } + setNewValue(newMap, key, newValue); + } + // if the value has gone - then we cant descend into it + if (newValue != ABSENCE_SENTINEL) { + newValue = visitPreOrderImpl(newValue, inputField.getType(), inputElementsWithField, visitor); + if (hasChanged(newValue, entry.getValue())) { + if (!copied) { + newMap = new LinkedHashMap<>(newMap); + copied = true; + } + setNewValue(newMap, key, newValue); + } + } + } + } + return newMap; + } else { + return null; + } + } + + private static Object visitListValue(Object coercedValue, GraphQLList listInputType, InputElements containingElements, ValueVisitor visitor) { + if (coercedValue != null) { + assertTrue(coercedValue instanceof List, "A list type MUST have an List value"); + } + @SuppressWarnings("unchecked") + List list = (List) coercedValue; + List newList = visitor.visitListValue(list, listInputType, containingElements); + if (newList == ABSENCE_SENTINEL) { + return ABSENCE_SENTINEL; + } + if (newList != null) { + GraphQLInputType inputType = GraphQLTypeUtil.unwrapOneAs(listInputType); + ImmutableList.Builder copiedList = null; + int i = 0; + for (Object subValue : newList) { + Object newValue = visitPreOrderImpl(subValue, inputType, containingElements, visitor); + if (copiedList != null) { + if (newValue != ABSENCE_SENTINEL) { + copiedList.add(newValue); + } + } else if (hasChanged(newValue, subValue)) { + // go into copy mode because something has changed + // copy previous values up to this point + copiedList = ImmutableList.builder(); + for (int j = 0; j < i; j++) { + copiedList.add(newList.get(j)); + } + if (newValue != ABSENCE_SENTINEL) { + copiedList.add(newValue); + } + } + i++; + } + if (copiedList != null) { + return copiedList.build(); + } else { + return newList; + } + } else { + return null; + } + } + + private static boolean hasChanged(Object newValue, Object oldValue) { + return newValue != oldValue || newValue == ABSENCE_SENTINEL; + } + + private static void setNewValue(Map newMap, String key, Object newValue) { + if (newValue == ABSENCE_SENTINEL) { + newMap.remove(key); + } else { + newMap.put(key, newValue); + } + } + +} diff --git a/src/main/java/graphql/analysis/values/ValueVisitor.java b/src/main/java/graphql/analysis/values/ValueVisitor.java new file mode 100644 index 0000000000..b8ea0a221b --- /dev/null +++ b/src/main/java/graphql/analysis/values/ValueVisitor.java @@ -0,0 +1,156 @@ +package graphql.analysis.values; + +import graphql.PublicSpi; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputSchemaElement; +import graphql.schema.GraphQLInputValueDefinition; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLScalarType; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +/** + * A visitor callback used by {@link ValueTraverser} + */ +@PublicSpi +public interface ValueVisitor { + + /** + * This magic sentinel value indicates that a value should be removed from a list or object versus being set to null, + * that is the difference between a value not being present and a value being null + */ + Object ABSENCE_SENTINEL = new Object() { + @Override + public String toString() { + return "ABSENCE_SENTINEL"; + } + }; + + /** + * Represents the elements that leads to a value and type + */ + interface InputElements { + + /** + * @return then list of input schema elements that lead to an input value. + */ + List getInputElements(); + + /** + * This is the list of input schema elements that are unwrapped, e.g. + * {@link GraphQLList} and {@link graphql.schema.GraphQLNonNull} types have been removed + * + * @return then list of {@link GraphQLInputValueDefinition} elements that lead to an input value. + */ + List getUnwrappedInputElements(); + + /** + * This is the last {@link GraphQLInputValueDefinition} that pointed to the value during a callback. This will + * be either a {@link graphql.schema.GraphQLArgument} or a {@link GraphQLInputObjectField} + * + * @return the last {@link GraphQLInputValueDefinition} that contains this value + */ + GraphQLInputValueDefinition getLastInputValueDefinition(); + } + + /** + * This is called when a scalar value is encountered + * + * @param coercedValue the value that is in coerced form + * @param inputType the type of scalar + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable Object visitScalarValue(@Nullable Object coercedValue, GraphQLScalarType inputType, InputElements inputElements) { + return coercedValue; + } + + /** + * This is called when an enum value is encountered + * + * @param coercedValue the value that is in coerced form + * @param inputType the type of enum + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable Object visitEnumValue(@Nullable Object coercedValue, GraphQLEnumType inputType, InputElements inputElements) { + return coercedValue; + } + + /** + * This is called when an input object field value is encountered + * + * @param coercedValue the value that is in coerced form + * @param inputObjectType the input object type containing the input field + * @param inputObjectField the input object field + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable Object visitInputObjectFieldValue(@Nullable Object coercedValue, GraphQLInputObjectType inputObjectType, GraphQLInputObjectField inputObjectField, InputElements inputElements) { + return coercedValue; + } + + /** + * This is called when an input object value is encountered. + * + * @param coercedValue the value that is in coerced form + * @param inputObjectType the input object type + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable Map visitInputObjectValue(@Nullable Map coercedValue, GraphQLInputObjectType inputObjectType, InputElements inputElements) { + return coercedValue; + } + + /** + * This is called when an input list value is encountered. + * + * @param coercedValue the value that is in coerced form + * @param listInputType the input list type + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable List visitListValue(@Nullable List coercedValue, GraphQLList listInputType, InputElements inputElements) { + return coercedValue; + } + + + /** + * This is called when a {@link GraphQLArgument} is encountered + * + * @param coercedValue the value that is in coerced form + * @param graphQLArgument the {@link GraphQLArgument} in play + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable Object visitArgumentValue(@Nullable Object coercedValue, GraphQLArgument graphQLArgument, InputElements inputElements) { + return coercedValue; + } + + + /** + * This is called when a {@link GraphQLAppliedDirectiveArgument} is encountered + * + * @param coercedValue the value that is in coerced form + * @param graphQLAppliedDirectiveArgument the {@link GraphQLAppliedDirectiveArgument} in play + * @param inputElements the elements that lead to this value and type + * + * @return the same value or a new value + */ + default @Nullable Object visitAppliedDirectiveArgumentValue(@Nullable Object coercedValue, GraphQLAppliedDirectiveArgument graphQLAppliedDirectiveArgument, InputElements inputElements) { + return coercedValue; + } + +} diff --git a/src/main/java/graphql/collect/ImmutableKit.java b/src/main/java/graphql/collect/ImmutableKit.java new file mode 100644 index 0000000000..15b148c2fa --- /dev/null +++ b/src/main/java/graphql/collect/ImmutableKit.java @@ -0,0 +1,223 @@ +package graphql.collect; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import graphql.Internal; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Predicate; + +import static graphql.Assert.assertNotNull; + +@Internal +@NullMarked +public final class ImmutableKit { + + public static ImmutableList emptyList() { + return ImmutableList.of(); + } + + public static ImmutableList nonNullCopyOf(@Nullable Collection collection) { + return collection == null ? emptyList() : ImmutableList.copyOf(collection); + } + + public static ImmutableMap emptyMap() { + return ImmutableMap.of(); + } + + public static ImmutableMap addToMap(Map existing, K newKey, V newVal) { + return ImmutableMap.builder().putAll(existing).put(newKey, newVal).build(); + } + + public static ImmutableList concatLists(List l1, List l2) { + return ImmutableList.builderWithExpectedSize(l1.size() + l2.size()).addAll(l1).addAll(l2).build(); + } + + /** + * This is more efficient than `c.stream().map().collect()` because it does not create the intermediate objects needed + * for the flexible style. Benchmarking has shown this to outperform `stream()`. + * + * @param collection the collection to map + * @param mapper the mapper function + * @param for two + * @param for result + * + * @return a map immutable list of results + */ + public static ImmutableList map(Collection collection, Function mapper) { + assertNotNull(collection); + assertNotNull(mapper); + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(collection.size()); + for (T t : collection) { + R r = mapper.apply(t); + builder.add(r); + } + return builder.build(); + } + + public static ImmutableSet mapToSet(Collection collection, Function mapper) { + assertNotNull(collection); + assertNotNull(mapper); + ImmutableSet.Builder builder = ImmutableSet.builderWithExpectedSize(collection.size()); + for (T t : collection) { + R r = mapper.apply(t); + builder.add(r); + } + return builder.build(); + } + + + /** + * This is more efficient than `c.stream().filter().collect()` because it does not create the intermediate objects needed + * for the flexible style. Benchmarking has shown this to outperform `stream()`. + * + * @param collection the collection to map + * @param filter the filter predicate + * @param for two + * + * @return a map immutable list of results + */ + public static ImmutableList filter(Collection collection, Predicate filter) { + assertNotNull(collection); + assertNotNull(filter); + return filterAndMap(collection, filter, Function.identity()); + } + + /** + * This is more efficient than `c.stream().filter().map().collect()` because it does not create the intermediate objects needed + * for the flexible style. Benchmarking has shown this to outperform `stream()`. + * + * @param collection the collection to map + * @param filter the filter predicate + * @param mapper the mapper function + * @param for two + * @param for result + * + * @return a map immutable list of results + */ + public static ImmutableList filterAndMap(Collection collection, Predicate filter, Function mapper) { + assertNotNull(collection); + assertNotNull(mapper); + assertNotNull(filter); + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(collection.size()); + for (T t : collection) { + if (filter.test(t)) { + R r = mapper.apply(t); + builder.add(r); + } + } + return builder.build(); + } + + public static ImmutableList flatMapList(Collection> listLists) { + ImmutableList.Builder builder = ImmutableList.builder(); + for (List t : listLists) { + builder.addAll(t); + } + return builder.build(); + } + + + /** + * This will map a collection of items but drop any that are null from the input. + * This is more efficient than `c.stream().map().collect()` because it does not create the intermediate objects needed + * for the flexible style. Benchmarking has shown this to outperform `stream()`. + * + * @param collection the collection to map + * @param mapper the mapper function + * @param for two + * @param for result + * + * @return a map immutable list of results + */ + public static ImmutableList mapAndDropNulls(Collection collection, Function mapper) { + assertNotNull(collection); + assertNotNull(mapper); + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(collection.size()); + for (T t : collection) { + R r = mapper.apply(t); + if (r != null) { + builder.add(r); + } + } + return builder.build(); + } + + /** + * This constructs a new Immutable list from an existing collection and adds a new element to it. + * + * @param existing the existing collection + * @param newValue the new value to add + * @param extraValues more values to add + * @param for two + * + * @return an Immutable list with the extra items. + */ + @SafeVarargs + public static ImmutableList addToList(Collection existing, T newValue, T... extraValues) { + assertNotNull(existing); + assertNotNull(newValue); + int expectedSize = existing.size() + 1 + extraValues.length; + ImmutableList.Builder newList = ImmutableList.builderWithExpectedSize(expectedSize); + newList.addAll(existing); + newList.add(newValue); + for (T extraValue : extraValues) { + newList.add(extraValue); + } + return newList.build(); + } + + /** + * This constructs a new Immutable set from an existing collection and adds a new element to it. + * + * @param existing the existing collection + * @param newValue the new value to add + * @param extraValues more values to add + * @param for two + * + * @return an Immutable Set with the extra items. + */ + @SafeVarargs + public static ImmutableSet addToSet(Collection existing, T newValue, T... extraValues) { + assertNotNull(existing); + assertNotNull(newValue); + int expectedSize = existing.size() + 1 + extraValues.length; + ImmutableSet.Builder newSet = ImmutableSet.builderWithExpectedSize(expectedSize); + newSet.addAll(existing); + newSet.add(newValue); + for (T extraValue : extraValues) { + newSet.add(extraValue); + } + return newSet.build(); + } + + + /** + * Filters a variable args array to a list + * + * @param filter the predicate the filter with + * @param args the variable args + * @param fot two + * + * @return a filtered list + */ + @SafeVarargs + public static List filterVarArgs(Predicate filter, T... args) { + if (args.length == 0) { + return ImmutableList.of(); + } + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(args.length); + for (T arg : args) { + if (filter.test(arg)) { + builder.add(arg); + } + } + return builder.build(); + } +} \ No newline at end of file diff --git a/src/main/java/graphql/collect/ImmutableMapWithNullValues.java b/src/main/java/graphql/collect/ImmutableMapWithNullValues.java new file mode 100644 index 0000000000..e9ca664efb --- /dev/null +++ b/src/main/java/graphql/collect/ImmutableMapWithNullValues.java @@ -0,0 +1,200 @@ +package graphql.collect; + +import graphql.Assert; +import graphql.Internal; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * The standard ImmutableMap does not allow null values. The implementation does. + * We have cases in graphql, around arguments where a map entry can be explicitly set to null + * and we want immutable smart maps for these cases. + * + * @param for key + * @param for victory + */ +@SuppressWarnings({"NullableProblems", "unchecked", "rawtypes"}) +@Internal +public final class ImmutableMapWithNullValues implements Map { + + private final Map delegate; + + private static final ImmutableMapWithNullValues emptyMap = new ImmutableMapWithNullValues(); + + private ImmutableMapWithNullValues(Map values) { + this.delegate = Collections.unmodifiableMap(new LinkedHashMap<>(values)); + } + + /** + * Only used to construct the singleton empty map + */ + private ImmutableMapWithNullValues() { + this(ImmutableKit.emptyMap()); + } + + + public static ImmutableMapWithNullValues emptyMap() { + return emptyMap; + } + + public static ImmutableMapWithNullValues copyOf(Map map) { + Assert.assertNotNull(map); + if (map instanceof ImmutableMapWithNullValues) { + return (ImmutableMapWithNullValues) map; + } + if (map.isEmpty()) { + return emptyMap(); + } + return new ImmutableMapWithNullValues<>(map); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return delegate.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + @Override + public V get(Object key) { + return delegate.get(key); + } + + @Override + @Deprecated(since = "2020-11-10") + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public void putAll(Map m) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public Set keySet() { + return delegate.keySet(); + } + + @Override + public Collection values() { + return delegate.values(); + } + + @Override + public Set> entrySet() { + return delegate.entrySet(); + } + + @Override + public boolean equals(Object o) { + return delegate.equals(o); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + + @Override + public V getOrDefault(Object key, V defaultValue) { + return delegate.getOrDefault(key, defaultValue); + } + + @Override + public void forEach(BiConsumer action) { + delegate.forEach(action); + } + + @Override + @Deprecated(since = "2020-11-10") + public void replaceAll(BiFunction function) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V putIfAbsent(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public boolean remove(Object key, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public boolean replace(K key, V oldValue, V newValue) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V replace(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V computeIfAbsent(K key, Function mappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V computeIfPresent(K key, BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V compute(K key, BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + @Deprecated(since = "2020-11-10") + public V merge(K key, V value, BiFunction remappingFunction) { + throw new UnsupportedOperationException(); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/src/main/java/graphql/execution/AbortExecutionException.java b/src/main/java/graphql/execution/AbortExecutionException.java index ca855a0456..950dfde9a0 100644 --- a/src/main/java/graphql/execution/AbortExecutionException.java +++ b/src/main/java/graphql/execution/AbortExecutionException.java @@ -13,7 +13,7 @@ import java.util.List; import static graphql.Assert.assertNotNull; -import static java.util.Collections.emptyList; +import static graphql.collect.ImmutableKit.emptyList; /** * This Exception indicates that the current execution should be aborted. @@ -67,13 +67,13 @@ public List getUnderlyingErrors() { * This is useful for turning this abort signal into an execution result which * is an error state with the underlying errors in it. * - * @return an excution result with the errors from this exception + * @return an execution result with the errors from this exception */ public ExecutionResult toExecutionResult() { - ExecutionResult executionResult = new ExecutionResultImpl(this); if (!this.getUnderlyingErrors().isEmpty()) { - executionResult = new ExecutionResultImpl(this.getUnderlyingErrors()); + return new ExecutionResultImpl(this.getUnderlyingErrors()); } - return executionResult; + + return new ExecutionResultImpl(this); } } diff --git a/src/main/java/graphql/execution/AbsoluteGraphQLError.java b/src/main/java/graphql/execution/AbsoluteGraphQLError.java deleted file mode 100644 index 84cdf15a12..0000000000 --- a/src/main/java/graphql/execution/AbsoluteGraphQLError.java +++ /dev/null @@ -1,127 +0,0 @@ -package graphql.execution; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - -import graphql.ErrorType; -import graphql.GraphQLError; -import graphql.language.Field; -import graphql.language.SourceLocation; -import graphql.schema.DataFetcher; - -import static graphql.Assert.assertNotNull; - -/** - * A {@link GraphQLError} that has been changed from a {@link DataFetcher} relative error to an absolute one. - */ -class AbsoluteGraphQLError implements GraphQLError { - - private final List locations; - private final List absolutePath; - private final String message; - private final ErrorType errorType; - private final Map extensions; - - AbsoluteGraphQLError(ExecutionStrategyParameters executionStrategyParameters, GraphQLError relativeError) { - assertNotNull(executionStrategyParameters); - assertNotNull(relativeError); - this.absolutePath = createAbsolutePath(executionStrategyParameters, relativeError); - this.locations = createAbsoluteLocations(relativeError, executionStrategyParameters.getField()); - this.message = relativeError.getMessage(); - this.errorType = relativeError.getErrorType(); - if (relativeError.getExtensions() != null) { - this.extensions = new HashMap<>(); - this.extensions.putAll(relativeError.getExtensions()); - } else { - this.extensions = null; - } - } - - @Override - public String getMessage() { - return message; - } - - @Override - public List getLocations() { - return locations; - } - - @Override - public ErrorType getErrorType() { - return errorType; - } - - @Override - public List getPath() { - return absolutePath; - } - - @Override - public Map getExtensions() { - return extensions; - } - - /** - * Creating absolute paths follows the following logic: - * Relative path is null -> Absolute path null - * Relative path is empty -> Absolute paths is path up to the field. - * Relative path is not empty -> Absolute paths [base Path, relative Path] - * @param relativeError relative error - * @param executionStrategyParameters execution strategy params. - * @return List of paths from the root. - */ - private List createAbsolutePath(ExecutionStrategyParameters executionStrategyParameters, - GraphQLError relativeError) { - return Optional.ofNullable(relativeError.getPath()) - .map(originalPath -> { - List path = new ArrayList<>(); - path.addAll(executionStrategyParameters.getPath().toList()); - path.addAll(relativeError.getPath()); - return path; - }) - .map(Collections::unmodifiableList) - .orElse(null); - } - - /** - * Creating absolute locations follows the following logic: - * Relative locations is null -> Absolute locations null - * Relative locations is empty -> Absolute locations base locations of the field. - * Relative locations is not empty -> Absolute locations [base line + relative line location] - * @param relativeError relative error - * @param fields fields on the current field. - * @return List of locations from the root. - */ - private List createAbsoluteLocations(GraphQLError relativeError, List fields) { - Optional baseLocation; - if (!fields.isEmpty()) { - baseLocation = Optional.ofNullable(fields.get(0).getSourceLocation()); - } else { - baseLocation = Optional.empty(); - } - - // relative error empty path should yield an absolute error with the base path - if (relativeError.getLocations() != null && relativeError.getLocations().isEmpty()) { - return baseLocation.map(Collections::singletonList).orElse(null); - } - - return Optional.ofNullable( - relativeError.getLocations()) - .map(locations -> locations.stream() - .map(l -> - baseLocation - .map(base -> new SourceLocation( - base.getLine() + l.getLine(), - base.getColumn() + l.getColumn())) - .orElse(null)) - .collect(Collectors.toList())) - .map(Collections::unmodifiableList) - .orElse(null); - } -} diff --git a/src/main/java/graphql/execution/AbstractAsyncExecutionStrategy.java b/src/main/java/graphql/execution/AbstractAsyncExecutionStrategy.java index c2bb3b096e..25f2036cbf 100644 --- a/src/main/java/graphql/execution/AbstractAsyncExecutionStrategy.java +++ b/src/main/java/graphql/execution/AbstractAsyncExecutionStrategy.java @@ -2,14 +2,15 @@ import graphql.ExecutionResult; import graphql.ExecutionResultImpl; +import graphql.PublicSpi; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; +@PublicSpi public abstract class AbstractAsyncExecutionStrategy extends ExecutionStrategy { public AbstractAsyncExecutionStrategy() { @@ -19,19 +20,16 @@ public AbstractAsyncExecutionStrategy(DataFetcherExceptionHandler dataFetcherExc super(dataFetcherExceptionHandler); } - protected BiConsumer, Throwable> handleResults(ExecutionContext executionContext, List fieldNames, CompletableFuture overallResult) { - return (List results, Throwable exception) -> { + protected BiConsumer, Throwable> handleResults(ExecutionContext executionContext, List fieldNames, CompletableFuture overallResult) { + return (List results, Throwable exception) -> { + exception = executionContext.possibleCancellation(exception); + if (exception != null) { handleNonNullException(executionContext, overallResult, exception); return; } - Map resolvedValuesByField = new LinkedHashMap<>(); - int ix = 0; - for (ExecutionResult executionResult : results) { - String fieldName = fieldNames.get(ix++); - resolvedValuesByField.put(fieldName, executionResult.getData()); - } + Map resolvedValuesByField = executionContext.getResponseMapFactory().createInsertionOrdered(fieldNames, results); overallResult.complete(new ExecutionResultImpl(resolvedValuesByField, executionContext.getErrors())); }; } diff --git a/src/main/java/graphql/execution/Async.java b/src/main/java/graphql/execution/Async.java index 099cfd6868..f268347341 100644 --- a/src/main/java/graphql/execution/Async.java +++ b/src/main/java/graphql/execution/Async.java @@ -2,107 +2,385 @@ import graphql.Assert; import graphql.Internal; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.function.BiFunction; +import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static graphql.Assert.assertTrue; +import static java.util.stream.Collectors.toList; @Internal @SuppressWarnings("FutureReturnValueIgnored") public class Async { - @FunctionalInterface - public interface CFFactory { - CompletableFuture apply(T input, int index, List previousResults); + /** + * A builder of materialized objects or {@link CompletableFuture}s than can present a promise to the list of them + *

+ * This builder has a strict contract on size whereby if the expectedSize is five, then there MUST be five elements presented to it. + * + * @param for two + */ + public interface CombinedBuilder { + + /** + * This adds a {@link CompletableFuture} into the collection of results + * + * @param completableFuture the CF to add + */ + void add(CompletableFuture completableFuture); + + /** + * This adds a new value which can be either a materialized value or a {@link CompletableFuture} + * + * @param object the object to add + */ + void addObject(Object object); + + /** + * This will return a {@code CompletableFuture>} even if the inputs are all materialized values + * + * @return a CompletableFuture to a List of values + */ + CompletableFuture> await(); + + /** + * This will return a {@code CompletableFuture>} if ANY of the input values are async + * otherwise it just return a materialised {@code List} + * + * @return either a CompletableFuture or a materialized list + */ + /* CompletableFuture> | List */ Object awaitPolymorphic(); + } + + /** + * Combines zero or more CFs into one. It is a wrapper around CompletableFuture.allOf. + * + * @param expectedSize how many we expect + * @param for two + * + * @return a combined builder of CFs + */ + public static CombinedBuilder ofExpectedSize(int expectedSize) { + if (expectedSize == 0) { + return new Empty<>(); + } else if (expectedSize == 1) { + return new Single<>(); + } else { + return new Many<>(expectedSize); + } } - public static CompletableFuture> each(List> futures) { - CompletableFuture> overallResult = new CompletableFuture<>(); + private static class Empty implements CombinedBuilder { - CompletableFuture - .allOf(futures.toArray(new CompletableFuture[0])) - .whenComplete((noUsed, exception) -> { - if (exception != null) { - overallResult.completeExceptionally(exception); - return; - } - List results = new ArrayList<>(); - for (CompletableFuture future : futures) { - results.add(future.join()); + private int ix; + + @Override + public void add(CompletableFuture completableFuture) { + this.ix++; + } + + @Override + public void addObject(Object object) { + this.ix++; + } + + @Override + public CompletableFuture> await() { + assertTrue(ix == 0, "expected size was 0 got %d", ix); + return typedEmpty(); + } + + @Override + public Object awaitPolymorphic() { + Assert.assertTrue(ix == 0, () -> "expected size was " + 0 + " got " + ix); + return Collections.emptyList(); + } + + // implementation details: infer the type of Completable> from a singleton empty + private static final CompletableFuture> EMPTY = CompletableFuture.completedFuture(Collections.emptyList()); + + @SuppressWarnings("unchecked") + private static CompletableFuture typedEmpty() { + return (CompletableFuture) EMPTY; + } + } + + private static class Single implements CombinedBuilder { + + // avoiding array allocation as there is only 1 CF + private Object value; + private int ix; + + @Override + public void add(CompletableFuture completableFuture) { + this.value = completableFuture; + this.ix++; + } + + @Override + public void addObject(Object object) { + this.value = object; + this.ix++; + } + + @Override + public CompletableFuture> await() { + commonSizeAssert(); + if (value instanceof CompletableFuture) { + @SuppressWarnings("unchecked") + CompletableFuture cf = (CompletableFuture) value; + return cf.thenApply(Collections::singletonList); + } + //noinspection unchecked + return CompletableFuture.completedFuture(Collections.singletonList((T) value)); + } + + @Override + public Object awaitPolymorphic() { + commonSizeAssert(); + if (value instanceof CompletableFuture) { + @SuppressWarnings("unchecked") + CompletableFuture cf = (CompletableFuture) value; + return cf.thenApply(Collections::singletonList); + } + //noinspection unchecked + return Collections.singletonList((T) value); + } + + private void commonSizeAssert() { + Assert.assertTrue(ix == 1, () -> "expected size was " + 1 + " got " + ix); + } + } + + private static class Many implements CombinedBuilder { + + private final Object[] array; + private int ix; + private int cfCount; + + private Many(int size) { + this.array = new Object[size]; + this.ix = 0; + cfCount = 0; + } + + @Override + public void add(CompletableFuture completableFuture) { + array[ix++] = completableFuture; + cfCount++; + } + + @Override + public void addObject(Object object) { + array[ix++] = object; + if (object instanceof CompletableFuture) { + cfCount++; + } + } + + @SuppressWarnings("unchecked") + @Override + public CompletableFuture> await() { + commonSizeAssert(); + + CompletableFuture> overallResult = new CompletableFuture<>(); + if (cfCount == 0) { + overallResult.complete(materialisedList(array)); + } else { + CompletableFuture[] cfsArr = copyOnlyCFsToArray(); + CompletableFuture.allOf(cfsArr) + .whenComplete((ignored, exception) -> { + if (exception != null) { + overallResult.completeExceptionally(exception); + return; + } + List results = new ArrayList<>(array.length); + if (cfsArr.length == array.length) { + // they are all CFs + for (CompletableFuture cf : cfsArr) { + results.add(cf.join()); + } + } else { + // it's a mixed bag of CFs and materialized objects + for (Object object : array) { + if (object instanceof CompletableFuture) { + CompletableFuture cf = (CompletableFuture) object; + // join is safe since they are all completed earlier via CompletableFuture.allOf() + results.add(cf.join()); + } else { + results.add((T) object); + } + } + } + overallResult.complete(results); + }); + } + return overallResult; + } + + @SuppressWarnings("unchecked") + @NonNull + private CompletableFuture[] copyOnlyCFsToArray() { + if (cfCount == array.length) { + // if it's all CFs - make a type safe copy via C code + return Arrays.copyOf(array, array.length, CompletableFuture[].class); + } else { + int i = 0; + CompletableFuture[] dest = new CompletableFuture[cfCount]; + for (Object o : array) { + if (o instanceof CompletableFuture) { + dest[i] = (CompletableFuture) o; + i++; } - overallResult.complete(results); - }); - return overallResult; + } + return dest; + } + } + + @Override + public Object awaitPolymorphic() { + if (cfCount == 0) { + commonSizeAssert(); + return materialisedList(array); + } else { + return await(); + } + } + + @NonNull + private List materialisedList(Object[] array) { + List results = new ArrayList<>(array.length); + for (Object object : array) { + //noinspection unchecked + results.add((T) object); + } + return results; + } + + private void commonSizeAssert() { + Assert.assertTrue(ix == array.length, () -> "expected size was " + array.length + " got " + ix); + } + } - public static CompletableFuture> each(Iterable list, BiFunction> cfFactory) { - List> futures = new ArrayList<>(); - int index = 0; + @SuppressWarnings("unchecked") + public static CompletableFuture> each(Collection list, Function cfOrMaterialisedValueFactory) { + Object l = eachPolymorphic(list, cfOrMaterialisedValueFactory); + if (l instanceof CompletableFuture) { + return (CompletableFuture>) l; + } else { + return CompletableFuture.completedFuture((List) l); + } + } + + /** + * This will run the value factory for each of the values in the provided list. + *

+ * If any of the values provided is a {@link CompletableFuture} it will return a {@link CompletableFuture} result object + * that joins on all values otherwise if none of the values are a {@link CompletableFuture} then it will return a materialized list. + * + * @param list the list to work over + * @param cfOrMaterialisedValueFactory the value factory to call for each iterm in the list + * @param for two + * + * @return a {@link CompletableFuture} to the list of resolved values or the list of values in a materialized fashion + */ + public static /* CompletableFuture> | List */ Object eachPolymorphic(Collection list, Function cfOrMaterialisedValueFactory) { + CombinedBuilder futures = ofExpectedSize(list.size()); for (T t : list) { - CompletableFuture cf; try { - cf = cfFactory.apply(t, index++); - Assert.assertNotNull(cf, "cfFactory must return a non null value"); + Object value = cfOrMaterialisedValueFactory.apply(t); + futures.addObject(value); } catch (Exception e) { - cf = new CompletableFuture<>(); + CompletableFuture cf = new CompletableFuture<>(); // Async.each makes sure that it is not a CompletionException inside a CompletionException cf.completeExceptionally(new CompletionException(e)); + futures.add(cf); } - futures.add(cf); } - return each(futures); - + return futures.awaitPolymorphic(); } - public static CompletableFuture> eachSequentially(Iterable list, CFFactory cfFactory) { + public static CompletableFuture> eachSequentially(Iterable list, BiFunction, Object> cfOrMaterialisedValueFactory) { CompletableFuture> result = new CompletableFuture<>(); - eachSequentiallyImpl(list.iterator(), cfFactory, 0, new ArrayList<>(), result); + eachSequentiallyPolymorphicImpl(list.iterator(), cfOrMaterialisedValueFactory, new ArrayList<>(), result); return result; } - private static void eachSequentiallyImpl(Iterator iterator, CFFactory cfFactory, int index, List tmpResult, CompletableFuture> overallResult) { + @SuppressWarnings("unchecked") + private static void eachSequentiallyPolymorphicImpl(Iterator iterator, BiFunction, Object> cfOrMaterialisedValueFactory, List tmpResult, CompletableFuture> overallResult) { if (!iterator.hasNext()) { overallResult.complete(tmpResult); return; } - CompletableFuture cf; + Object value; try { - cf = cfFactory.apply(iterator.next(), index, tmpResult); - Assert.assertNotNull(cf, "cfFactory must return a non null value"); + value = cfOrMaterialisedValueFactory.apply(iterator.next(), tmpResult); } catch (Exception e) { - cf = new CompletableFuture<>(); - cf.completeExceptionally(new CompletionException(e)); + overallResult.completeExceptionally(new CompletionException(e)); + return; + } + if (value instanceof CompletableFuture) { + CompletableFuture cf = (CompletableFuture) value; + cf.whenComplete((cfResult, exception) -> { + if (exception != null) { + overallResult.completeExceptionally(exception); + return; + } + tmpResult.add(cfResult); + eachSequentiallyPolymorphicImpl(iterator, cfOrMaterialisedValueFactory, tmpResult, overallResult); + }); + } else { + tmpResult.add((U) value); + eachSequentiallyPolymorphicImpl(iterator, cfOrMaterialisedValueFactory, tmpResult, overallResult); } - cf.whenComplete((cfResult, exception) -> { - if (exception != null) { - overallResult.completeExceptionally(exception); - return; - } - tmpResult.add(cfResult); - eachSequentiallyImpl(iterator, cfFactory, index + 1, tmpResult, overallResult); - }); } /** - * Turns an object T into a CompletableFuture if its not already + * Turns an object T into a CompletableFuture if it's not already * * @param t - the object to check * @param for two * * @return a CompletableFuture */ - public static CompletableFuture toCompletableFuture(T t) { + @SuppressWarnings("unchecked") + public static CompletableFuture toCompletableFuture(Object t) { if (t instanceof CompletionStage) { - //noinspection unchecked return ((CompletionStage) t).toCompletableFuture(); } else { - return CompletableFuture.completedFuture(t); + return CompletableFuture.completedFuture((T) t); + } + } + + /** + * Turns a CompletionStage into a CompletableFuture if it's not already, otherwise leaves it alone + * as a materialized object. + * + * @param object - the object to check + * + * @return a CompletableFuture from a CompletionStage or the materialized object itself + */ + public static Object toCompletableFutureOrMaterializedObject(Object object) { + if (object instanceof CompletionStage) { + return ((CompletionStage) object).toCompletableFuture(); + } else { + return object; } } @@ -122,14 +400,35 @@ public static CompletableFuture exceptionallyCompletedFuture(Throwable ex return result; } - public static void copyResults(CompletableFuture source, CompletableFuture target) { - source.whenComplete((o, throwable) -> { - if (throwable != null) { - target.completeExceptionally(throwable); - return; - } - target.complete(o); - }); + /** + * If the passed in CompletableFuture is null, then it creates a CompletableFuture that resolves to null + * + * @param completableFuture the CF to use + * @param for two + * + * @return the completableFuture if it's not null or one that always resoles to null + */ + public static @NonNull CompletableFuture orNullCompletedFuture(@Nullable CompletableFuture completableFuture) { + return completableFuture != null ? completableFuture : CompletableFuture.completedFuture(null); + } + + public static CompletableFuture> allOf(List> cfs) { + return CompletableFuture.allOf(cfs.toArray(CompletableFuture[]::new)) + .thenApply(v -> cfs.stream() + .map(CompletableFuture::join) + .collect(toList()) + ); + } + + public static CompletableFuture> allOf(Map> cfs) { + return CompletableFuture.allOf(cfs.values().toArray(CompletableFuture[]::new)) + .thenApply(v -> cfs.entrySet().stream() + .collect( + Collectors.toMap( + Map.Entry::getKey, + task -> task.getValue().join()) + ) + ); } } diff --git a/src/main/java/graphql/execution/AsyncExecutionStrategy.java b/src/main/java/graphql/execution/AsyncExecutionStrategy.java index 37ff1275b0..8d1d430581 100644 --- a/src/main/java/graphql/execution/AsyncExecutionStrategy.java +++ b/src/main/java/graphql/execution/AsyncExecutionStrategy.java @@ -1,29 +1,22 @@ package graphql.execution; import graphql.ExecutionResult; -import graphql.execution.defer.DeferSupport; -import graphql.execution.defer.DeferredCall; -import graphql.execution.defer.DeferredErrorSupport; -import graphql.execution.instrumentation.DeferredFieldInstrumentationContext; +import graphql.PublicApi; +import graphql.execution.incremental.DeferredExecutionSupport; import graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext; import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.language.Field; -import graphql.schema.GraphQLFieldDefinition; +import graphql.introspection.Introspection; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; /** * The standard graphql execution strategy that runs fields asynchronously non-blocking. */ +@PublicApi public class AsyncExecutionStrategy extends AbstractAsyncExecutionStrategy { /** @@ -45,47 +38,54 @@ public AsyncExecutionStrategy(DataFetcherExceptionHandler exceptionHandler) { @Override @SuppressWarnings("FutureReturnValueIgnored") public CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { - + DataLoaderDispatchStrategy dataLoaderDispatcherStrategy = executionContext.getDataLoaderDispatcherStrategy(); Instrumentation instrumentation = executionContext.getInstrumentation(); InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters); - ExecutionStrategyInstrumentationContext executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters); - - Map> fields = parameters.getFields(); - List fieldNames = new ArrayList<>(fields.keySet()); - List> futures = new ArrayList<>(); - List resolvedFields = new ArrayList<>(); - for (String fieldName : fieldNames) { - List currentField = fields.get(fieldName); + ExecutionStrategyInstrumentationContext executionStrategyCtx = ExecutionStrategyInstrumentationContext.nonNullCtx(instrumentation.beginExecutionStrategy(instrumentationParameters, executionContext.getInstrumentationState())); - ExecutionPath fieldPath = parameters.getPath().segment(fieldName); - ExecutionStrategyParameters newParameters = parameters - .transform(builder -> builder.field(currentField).path(fieldPath).parent(parameters)); + MergedSelectionSet fields = parameters.getFields(); + List fieldNames = fields.getKeys(); - if (isDeferred(executionContext, newParameters, currentField)) { - executionStrategyCtx.onDeferredField(currentField); - continue; - } - resolvedFields.add(fieldName); - CompletableFuture future = resolveFieldWithInfo(executionContext, newParameters); - futures.add(future); + Optional isNotSensible = Introspection.isIntrospectionSensible(fields, executionContext); + if (isNotSensible.isPresent()) { + return CompletableFuture.completedFuture(isNotSensible.get()); } + + DeferredExecutionSupport deferredExecutionSupport = createDeferredExecutionSupport(executionContext, parameters); + + dataLoaderDispatcherStrategy.executionStrategy(executionContext, parameters, deferredExecutionSupport.getNonDeferredFieldNames(fieldNames).size()); + Async.CombinedBuilder futures = getAsyncFieldValueInfo(executionContext, parameters, deferredExecutionSupport); + dataLoaderDispatcherStrategy.finishedFetching(executionContext, parameters); + + CompletableFuture overallResult = new CompletableFuture<>(); - executionStrategyCtx.onDispatched(overallResult); + executionStrategyCtx.onDispatched(); + + futures.await().whenComplete((completeValueInfos, throwable) -> { + List fieldsExecutedOnInitialResult = deferredExecutionSupport.getNonDeferredFieldNames(fieldNames); + + BiConsumer, Throwable> handleResultsConsumer = handleResults(executionContext, fieldsExecutedOnInitialResult, overallResult); + throwable = executionContext.possibleCancellation(throwable); - Async.each(futures).whenComplete((completeValueInfos, throwable) -> { - BiConsumer, Throwable> handleResultsConsumer = handleResults(executionContext, resolvedFields, overallResult); if (throwable != null) { handleResultsConsumer.accept(null, throwable.getCause()); return; } - List> executionResultFuture = completeValueInfos.stream().map(FieldValueInfo::getFieldValue).collect(Collectors.toList()); + + Async.CombinedBuilder fieldValuesFutures = Async.ofExpectedSize(completeValueInfos.size()); + for (FieldValueInfo completeValueInfo : completeValueInfos) { + fieldValuesFutures.addObject(completeValueInfo.getFieldValueObject()); + } + dataLoaderDispatcherStrategy.executionStrategyOnFieldValuesInfo(completeValueInfos, parameters); executionStrategyCtx.onFieldValuesInfo(completeValueInfos); - Async.each(executionResultFuture).whenComplete(handleResultsConsumer); + fieldValuesFutures.await().whenComplete(handleResultsConsumer); }).exceptionally((ex) -> { // if there are any issues with combining/handling the field results, // complete the future at all costs and bubble up any thrown exception so // the execution does not hang. + dataLoaderDispatcherStrategy.executionStrategyOnFieldValuesException(ex, parameters); + executionStrategyCtx.onFieldValuesException(); overallResult.completeExceptionally(ex); return null; }); @@ -94,52 +94,4 @@ public CompletableFuture execute(ExecutionContext executionCont return overallResult; } - private boolean isDeferred(ExecutionContext executionContext, ExecutionStrategyParameters parameters, List currentField) { - DeferSupport deferSupport = executionContext.getDeferSupport(); - if (deferSupport.checkForDeferDirective(currentField)) { - DeferredErrorSupport errorSupport = new DeferredErrorSupport(); - - // with a deferred field we are really resetting where we execute from, that is from this current field onwards - Map> fields = new HashMap<>(); - fields.put(currentField.get(0).getName(), currentField); - - ExecutionStrategyParameters callParameters = parameters.transform(builder -> - builder.deferredErrorSupport(errorSupport) - .field(currentField) - .fields(fields) - .parent(null) // this is a break in the parent -> child chain - its a new start effectively - .listSize(0) - .currentListIndex(0) - ); - - DeferredCall call = new DeferredCall(deferredExecutionResult(executionContext, callParameters), errorSupport); - deferSupport.enqueue(call); - return true; - } - return false; - } - - @SuppressWarnings("FutureReturnValueIgnored") - private Supplier> deferredExecutionResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - return () -> { - GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().get(0)); - - Instrumentation instrumentation = executionContext.getInstrumentation(); - DeferredFieldInstrumentationContext fieldCtx = instrumentation.beginDeferredField( - new InstrumentationDeferredFieldParameters(executionContext, parameters, fieldDef, fieldTypeInfo(parameters, fieldDef)) - ); - CompletableFuture result = new CompletableFuture<>(); - fieldCtx.onDispatched(result); - CompletableFuture fieldValueInfoFuture = resolveFieldWithInfo(executionContext, parameters); - - fieldValueInfoFuture.whenComplete((fieldValueInfo, throwable) -> { - fieldCtx.onFieldValueInfo(fieldValueInfo); - - CompletableFuture execResultFuture = fieldValueInfo.getFieldValue(); - execResultFuture = execResultFuture.whenComplete(fieldCtx::onCompleted); - Async.copyResults(execResultFuture, result); - }); - return result; - }; - } } diff --git a/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java b/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java index 5a1479b139..b5ff7cd5fa 100644 --- a/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java +++ b/src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java @@ -1,20 +1,24 @@ package graphql.execution; +import com.google.common.collect.ImmutableList; import graphql.ExecutionResult; +import graphql.PublicApi; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationContext; import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.language.Field; +import graphql.introspection.Introspection; -import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.nonNullCtx; + /** - * Async non-blocking execution, but serial: only one field at the the time will be resolved. - * See {@link AsyncExecutionStrategy} for a non serial (parallel) execution of every field. + * Async non-blocking execution, but serial: only one field at the time will be resolved. + * See {@link AsyncExecutionStrategy} for a non-serial (parallel) execution of every field. */ +@PublicApi public class AsyncSerialExecutionStrategy extends AbstractAsyncExecutionStrategy { public AsyncSerialExecutionStrategy() { @@ -26,29 +30,59 @@ public AsyncSerialExecutionStrategy(DataFetcherExceptionHandler exceptionHandler } @Override - @SuppressWarnings({"TypeParameterUnusedInFormals","FutureReturnValueIgnored"}) + @SuppressWarnings({"TypeParameterUnusedInFormals", "FutureReturnValueIgnored"}) public CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { + DataLoaderDispatchStrategy dataLoaderDispatcherStrategy = executionContext.getDataLoaderDispatcherStrategy(); Instrumentation instrumentation = executionContext.getInstrumentation(); InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters); - InstrumentationContext executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters); - Map> fields = parameters.getFields(); - List fieldNames = new ArrayList<>(fields.keySet()); - - CompletableFuture> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, index, prevResults) -> { - List currentField = fields.get(fieldName); - ExecutionPath fieldPath = parameters.getPath().segment(fieldName); - ExecutionStrategyParameters newParameters = parameters - .transform(builder -> builder.field(currentField).path(fieldPath)); - return resolveField(executionContext, newParameters); + InstrumentationContext executionStrategyCtx = nonNullCtx(instrumentation.beginExecutionStrategy(instrumentationParameters, + executionContext.getInstrumentationState()) + ); + MergedSelectionSet fields = parameters.getFields(); + ImmutableList fieldNames = ImmutableList.copyOf(fields.keySet()); + + // this is highly unlikely since Mutations cant do introspection BUT in theory someone could make the query strategy this code + // so belts and braces + Optional isNotSensible = Introspection.isIntrospectionSensible(fields, executionContext); + if (isNotSensible.isPresent()) { + return CompletableFuture.completedFuture(isNotSensible.get()); + } + + CompletableFuture> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, prevResults) -> { + MergedField currentField = fields.getSubField(fieldName); + ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); + ExecutionStrategyParameters newParameters = parameters.transform(currentField, fieldPath); + + return resolveSerialField(executionContext, dataLoaderDispatcherStrategy, newParameters); }); CompletableFuture overallResult = new CompletableFuture<>(); - executionStrategyCtx.onDispatched(overallResult); + executionStrategyCtx.onDispatched(); resultsFuture.whenComplete(handleResults(executionContext, fieldNames, overallResult)); overallResult.whenComplete(executionStrategyCtx::onCompleted); return overallResult; } + private Object resolveSerialField(ExecutionContext executionContext, + DataLoaderDispatchStrategy dataLoaderDispatcherStrategy, + ExecutionStrategyParameters newParameters) { + dataLoaderDispatcherStrategy.executionSerialStrategy(executionContext, newParameters); + + Object fieldWithInfo = resolveFieldWithInfo(executionContext, newParameters); + dataLoaderDispatcherStrategy.finishedFetching(executionContext, newParameters); + if (fieldWithInfo instanceof CompletableFuture) { + //noinspection unchecked + return ((CompletableFuture) fieldWithInfo).thenCompose(fvi -> { + dataLoaderDispatcherStrategy.executionStrategyOnFieldValuesInfo(List.of(fvi), newParameters); + CompletableFuture fieldValueFuture = fvi.getFieldValueFuture(); + return fieldValueFuture; + }); + } else { + FieldValueInfo fvi = (FieldValueInfo) fieldWithInfo; + dataLoaderDispatcherStrategy.executionStrategyOnFieldValuesInfo(List.of(fvi), newParameters); + return fvi.getFieldValueObject(); + } + } } diff --git a/src/main/java/graphql/execution/CoercedVariables.java b/src/main/java/graphql/execution/CoercedVariables.java new file mode 100644 index 0000000000..6123aeec82 --- /dev/null +++ b/src/main/java/graphql/execution/CoercedVariables.java @@ -0,0 +1,45 @@ +package graphql.execution; + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.collect.ImmutableMapWithNullValues; + +import java.util.Map; + +/** + * Holds coerced variables, that is their values are now in a canonical form. + */ +@PublicApi +public class CoercedVariables { + private static final CoercedVariables EMPTY = CoercedVariables.of(ImmutableKit.emptyMap()); + private final ImmutableMapWithNullValues coercedVariables; + + public CoercedVariables(Map coercedVariables) { + this.coercedVariables = ImmutableMapWithNullValues.copyOf(coercedVariables); + } + + public Map toMap() { + return coercedVariables; + } + + public boolean containsKey(String key) { + return coercedVariables.containsKey(key); + } + + public Object get(String key) { + return coercedVariables.get(key); + } + + public static CoercedVariables emptyVariables() { + return EMPTY; + } + + public static CoercedVariables of(Map coercedVariables) { + return new CoercedVariables(coercedVariables); + } + + @Override + public String toString() { + return coercedVariables.toString(); + } +} diff --git a/src/main/java/graphql/execution/ConditionalNodes.java b/src/main/java/graphql/execution/ConditionalNodes.java deleted file mode 100644 index 0eb5cb8254..0000000000 --- a/src/main/java/graphql/execution/ConditionalNodes.java +++ /dev/null @@ -1,45 +0,0 @@ -package graphql.execution; - -import graphql.language.Directive; - -import java.util.List; -import java.util.Map; - -import static graphql.Directives.IncludeDirective; -import static graphql.Directives.SkipDirective; -import static graphql.language.NodeUtil.directivesByName; - - -public class ConditionalNodes { - - private final ValuesResolver valuesResolver; - - public ConditionalNodes() { - valuesResolver = new ValuesResolver(); - } - - public boolean - shouldInclude(Map variables, List directives) { - boolean skip = getDirectiveResult(variables, directives, SkipDirective.getName(), false); - boolean include = getDirectiveResult(variables, directives, IncludeDirective.getName(), true); - return !skip && include; - } - - private Directive getDirectiveByName(List directives, String name) { - if (directives.isEmpty()) { - return null; - } - return directivesByName(directives).get(name); - } - - private boolean getDirectiveResult(Map variables, List directives, String directiveName, boolean defaultValue) { - Directive directive = getDirectiveByName(directives, directiveName); - if (directive != null) { - Map argumentValues = valuesResolver.getArgumentValues(SkipDirective.getArguments(), directive.getArguments(), variables); - return (Boolean) argumentValues.get("if"); - } - - return defaultValue; - } - -} diff --git a/src/main/java/graphql/execution/DataFetcherExceptionHandler.java b/src/main/java/graphql/execution/DataFetcherExceptionHandler.java index e527045c50..6daafd94dd 100644 --- a/src/main/java/graphql/execution/DataFetcherExceptionHandler.java +++ b/src/main/java/graphql/execution/DataFetcherExceptionHandler.java @@ -1,25 +1,26 @@ package graphql.execution; -import graphql.GraphQLError; +import graphql.ExecutionResult; import graphql.PublicSpi; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; -import java.util.function.Consumer; +import java.util.concurrent.CompletableFuture; /** * This is called when an exception is thrown during {@link graphql.schema.DataFetcher#get(DataFetchingEnvironment)} execution */ @PublicSpi -public interface DataFetcherExceptionHandler extends Consumer { +public interface DataFetcherExceptionHandler { /** - * When an exception during a call to a {@link DataFetcher} then this handler - * is called back to shape the error that should be placed in the list of errors - * via {@link ExecutionContext#addError(GraphQLError)} + * When an exception occurs during a call to a {@link DataFetcher} then this handler + * is called to shape the errors that should be placed in the {@link ExecutionResult#getErrors()} + * list of errors. * * @param handlerParameters the parameters to this callback + * + * @return a result that can contain custom formatted {@link graphql.GraphQLError}s */ - @Override - void accept(DataFetcherExceptionHandlerParameters handlerParameters); + CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters); } diff --git a/src/main/java/graphql/execution/DataFetcherExceptionHandlerParameters.java b/src/main/java/graphql/execution/DataFetcherExceptionHandlerParameters.java index 3ed6d585b7..b17e3582b5 100644 --- a/src/main/java/graphql/execution/DataFetcherExceptionHandlerParameters.java +++ b/src/main/java/graphql/execution/DataFetcherExceptionHandlerParameters.java @@ -1,6 +1,7 @@ package graphql.execution; -import graphql.language.Field; +import graphql.PublicApi; +import graphql.language.SourceLocation; import graphql.schema.DataFetchingEnvironment; import graphql.schema.GraphQLFieldDefinition; @@ -9,107 +10,68 @@ /** * The parameters available to {@link DataFetcherExceptionHandler}s */ +@PublicApi public class DataFetcherExceptionHandlerParameters { - private final ExecutionContext executionContext; private final DataFetchingEnvironment dataFetchingEnvironment; - private final Field field; - private final GraphQLFieldDefinition fieldDefinition; - private final Map argumentValues; - private final ExecutionPath path; private final Throwable exception; - public DataFetcherExceptionHandlerParameters(ExecutionContext executionContext, DataFetchingEnvironment dataFetchingEnvironment, Field field, GraphQLFieldDefinition fieldDefinition, Map argumentValues, ExecutionPath path, Throwable exception) { - this.executionContext = executionContext; - this.dataFetchingEnvironment = dataFetchingEnvironment; - this.field = field; - this.fieldDefinition = fieldDefinition; - this.argumentValues = argumentValues; - this.path = path; - this.exception = exception; + private DataFetcherExceptionHandlerParameters(Builder builder) { + this.exception = builder.exception; + this.dataFetchingEnvironment = builder.dataFetchingEnvironment; } - public static Builder newExceptionParameters() { - return new Builder(); + public Throwable getException() { + return exception; } - public ExecutionContext getExecutionContext() { - return executionContext; + public ResultPath getPath() { + return dataFetchingEnvironment.getExecutionStepInfo().getPath(); } public DataFetchingEnvironment getDataFetchingEnvironment() { return dataFetchingEnvironment; } - public Field getField() { - return field; + public MergedField getField() { + return dataFetchingEnvironment.getMergedField(); } public GraphQLFieldDefinition getFieldDefinition() { - return fieldDefinition; + return dataFetchingEnvironment.getFieldDefinition(); } public Map getArgumentValues() { - return argumentValues; + return dataFetchingEnvironment.getArguments(); } - public ExecutionPath getPath() { - return path; + public SourceLocation getSourceLocation() { + return getField().getSingleField().getSourceLocation(); } - public Throwable getException() { - return exception; + public static Builder newExceptionParameters() { + return new Builder(); } public static class Builder { - ExecutionContext executionContext; DataFetchingEnvironment dataFetchingEnvironment; - Field field; - GraphQLFieldDefinition fieldDefinition; - Map argumentValues; - ExecutionPath path; Throwable exception; private Builder() { } - public Builder executionContext(ExecutionContext executionContext) { - this.executionContext = executionContext; - return this; - } - public Builder dataFetchingEnvironment(DataFetchingEnvironment dataFetchingEnvironment) { this.dataFetchingEnvironment = dataFetchingEnvironment; return this; } - public Builder field(Field field) { - this.field = field; - return this; - } - - public Builder fieldDefinition(GraphQLFieldDefinition fieldDefinition) { - this.fieldDefinition = fieldDefinition; - return this; - } - - public Builder argumentValues(Map argumentValues) { - this.argumentValues = argumentValues; - return this; - } - - public Builder path(ExecutionPath path) { - this.path = path; - return this; - } - public Builder exception(Throwable exception) { this.exception = exception; return this; } public DataFetcherExceptionHandlerParameters build() { - return new DataFetcherExceptionHandlerParameters(executionContext, dataFetchingEnvironment, field, fieldDefinition, argumentValues, path, exception); + return new DataFetcherExceptionHandlerParameters(this); } } } diff --git a/src/main/java/graphql/execution/DataFetcherExceptionHandlerResult.java b/src/main/java/graphql/execution/DataFetcherExceptionHandlerResult.java new file mode 100644 index 0000000000..4059e91824 --- /dev/null +++ b/src/main/java/graphql/execution/DataFetcherExceptionHandlerResult.java @@ -0,0 +1,53 @@ +package graphql.execution; + +import graphql.GraphQLError; +import graphql.PublicApi; + +import java.util.ArrayList; +import java.util.List; + +import static graphql.Assert.assertNotNull; + +/** + * The result object for {@link graphql.execution.DataFetcherExceptionHandler}s + */ +@PublicApi +public class DataFetcherExceptionHandlerResult { + + private final List errors; + + private DataFetcherExceptionHandlerResult(Builder builder) { + this.errors = builder.errors; + } + + public List getErrors() { + return errors; + } + + public static Builder newResult() { + return new Builder(); + } + + public static Builder newResult(GraphQLError error) { + return new Builder().error(error); + } + + public static class Builder { + + private final List errors = new ArrayList<>(); + + public Builder errors(List errors) { + this.errors.addAll(assertNotNull(errors)); + return this; + } + + public Builder error(GraphQLError error) { + errors.add(assertNotNull(error)); + return this; + } + + public DataFetcherExceptionHandlerResult build() { + return new DataFetcherExceptionHandlerResult(this); + } + } +} diff --git a/src/main/java/graphql/execution/DataFetcherResult.java b/src/main/java/graphql/execution/DataFetcherResult.java index f284bcde96..c7a58d84a1 100644 --- a/src/main/java/graphql/execution/DataFetcherResult.java +++ b/src/main/java/graphql/execution/DataFetcherResult.java @@ -1,37 +1,67 @@ package graphql.execution; +import com.google.common.collect.ImmutableList; +import graphql.ExecutionResult; import graphql.GraphQLError; import graphql.PublicApi; import graphql.schema.DataFetcher; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; import static graphql.Assert.assertNotNull; -import static java.util.Collections.unmodifiableList; /** - * An object that can be returned from a {@link DataFetcher} that contains both data and errors to be relativized and - * added to the final result. This is a useful when your ``DataFetcher`` retrieves data from multiple sources - * or from another GraphQL resource. + * An object that can be returned from a {@link DataFetcher} that contains both data, local context and errors to be added to the final result. + * This is a useful when your ``DataFetcher`` retrieves data from multiple sources + * or from another GraphQL resource, or you want to pass extra context to lower levels. + *

+ * This also allows you to pass down new local context objects between parent and child fields. If you return a + * {@link #getLocalContext()} value then it will be passed down into any child fields via + * {@link graphql.schema.DataFetchingEnvironment#getLocalContext()} + *

+ * You can also have {@link DataFetcher}s contribute to the {@link ExecutionResult#getExtensions()} by returning + * extensions maps that will be merged together via the {@link graphql.extensions.ExtensionsBuilder} and its {@link graphql.extensions.ExtensionsMerger} + * in place. + *

+ * This provides {@link #hashCode()} and {@link #equals(Object)} methods that afford comparison with other {@link DataFetcherResult} object.s + * However, to function correctly, this relies on the values provided in the following fields in turn also implementing {@link #hashCode()}} and {@link #equals(Object)} as appropriate: + *

    + *
  • The data returned in {@link #getData()}. + *
  • The individual errors returned in {@link #getErrors()}. + *
  • The context returned in {@link #getLocalContext()}. + *
  • The keys/values in the {@link #getExtensions()} {@link Map}. + *
* * @param The type of the data fetched */ @PublicApi -public class DataFetcherResult { +@NullMarked +public class DataFetcherResult { - private final T data; + private final @Nullable T data; private final List errors; + private final @Nullable Object localContext; + private final @Nullable Map extensions; - public DataFetcherResult(T data, List errors) { + private DataFetcherResult(@Nullable T data, List errors, @Nullable Object localContext, @Nullable Map extensions) { this.data = data; - this.errors = unmodifiableList(assertNotNull(errors)); + this.errors = ImmutableList.copyOf(assertNotNull(errors)); + this.localContext = localContext; + this.extensions = extensions; } /** * @return The data fetched. May be null. */ - public T getData() { + public @Nullable T getData() { return data; } @@ -41,4 +71,169 @@ public T getData() { public List getErrors() { return errors; } + + /** + * @return true if there are any errors present + */ + public boolean hasErrors() { + return !errors.isEmpty(); + } + + /** + * A data fetcher result can supply a context object for that field that is passed down to child fields + * + * @return a local context object + */ + public @Nullable Object getLocalContext() { + return localContext; + } + + /** + * A data fetcher result can supply extension values that will be merged into the result + * via the {@link graphql.extensions.ExtensionsBuilder} at the end of the operation. + *

+ * The {@link graphql.extensions.ExtensionsMerger} in place inside the {@link graphql.extensions.ExtensionsBuilder} + * will control how these extension values get merged. + * + * @return a map of extension values to be merged + * + * @see graphql.extensions.ExtensionsBuilder + * @see graphql.extensions.ExtensionsMerger + */ + public @Nullable Map getExtensions() { + return extensions; + } + + /** + * This helps you transform the current DataFetcherResult into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new instance produced by calling {@code build} on that builder + */ + public DataFetcherResult transform(Consumer> builderConsumer) { + Builder builder = new Builder<>(this); + builderConsumer.accept(builder); + return builder.build(); + } + + /** + * Transforms the data of the current DataFetcherResult using the provided function. + * All other values are left unmodified. + * + * @param transformation the transformation that should be applied to the data + * @param the result type + * + * @return a new instance with where the data value has been transformed + */ + public DataFetcherResult map(Function<@Nullable T, @Nullable R> transformation) { + return new Builder<>(transformation.apply(this.data)) + .errors(this.errors) + .extensions(this.extensions) + .localContext(this.localContext) + .build(); + } + + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + + DataFetcherResult that = (DataFetcherResult) o; + return Objects.equals(data, that.data) + && errors.equals(that.errors) + && Objects.equals(localContext, that.localContext) + && Objects.equals(extensions, that.extensions); + } + + @Override + public int hashCode() { + return Objects.hash(data, errors, localContext, extensions); + } + + @Override + public String toString() { + return "DataFetcherResult{" + + "data=" + data + + ", errors=" + errors + + ", localContext=" + localContext + + ", extensions=" + extensions + + '}'; + } + + /** + * Creates a new data fetcher result builder + * + * @param the type of the result + * + * @return a new builder + */ + public static Builder newResult() { + return new Builder<>(); + } + + public static class Builder { + private @Nullable T data; + private @Nullable Object localContext; + private final List errors = new ArrayList<>(); + private @Nullable Map extensions; + + public Builder(DataFetcherResult existing) { + data = existing.getData(); + localContext = existing.getLocalContext(); + errors.addAll(existing.getErrors()); + extensions = existing.extensions; + } + + public Builder(@Nullable T data) { + this.data = data; + } + + public Builder() { + } + + public Builder data(@Nullable T data) { + this.data = data; + return this; + } + + public Builder errors(List errors) { + this.errors.addAll(errors); + return this; + } + + public Builder error(GraphQLError error) { + this.errors.add(error); + return this; + } + + public Builder clearErrors() { + this.errors.clear(); + return this; + } + + /** + * @return true if there are any errors present + */ + public boolean hasErrors() { + return !errors.isEmpty(); + } + + public Builder localContext(@Nullable Object localContext) { + this.localContext = localContext; + return this; + } + + public Builder extensions(@Nullable Map extensions) { + this.extensions = extensions; + return this; + } + + public DataFetcherResult build() { + return new DataFetcherResult<>(data, errors, localContext, extensions); + } + } } diff --git a/src/main/java/graphql/execution/DataLoaderDispatchStrategy.java b/src/main/java/graphql/execution/DataLoaderDispatchStrategy.java new file mode 100644 index 0000000000..ae73dc2fe2 --- /dev/null +++ b/src/main/java/graphql/execution/DataLoaderDispatchStrategy.java @@ -0,0 +1,83 @@ +package graphql.execution; + +import graphql.Internal; +import graphql.execution.incremental.AlternativeCallContext; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; + +import java.util.List; +import java.util.function.Supplier; + +@Internal +public interface DataLoaderDispatchStrategy { + + DataLoaderDispatchStrategy NO_OP = new DataLoaderDispatchStrategy() { + }; + + + default void executionStrategy(ExecutionContext executionContext, ExecutionStrategyParameters parameters, int fieldCount) { + + } + + default void executionSerialStrategy(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + + } + + default void executionStrategyOnFieldValuesInfo(List fieldValueInfoList, ExecutionStrategyParameters parameters) { + + } + + default void executionStrategyOnFieldValuesException(Throwable t, ExecutionStrategyParameters parameters) { + + } + + + default void executeObject(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, int fieldCount) { + + } + + default void executeObjectOnFieldValuesInfo(List fieldValueInfoList, ExecutionStrategyParameters parameters) { + + } + + default void deferredOnFieldValue(String resultKey, FieldValueInfo fieldValueInfo, Throwable throwable, ExecutionStrategyParameters parameters) { + + } + + default void executeObjectOnFieldValuesException(Throwable t, ExecutionStrategyParameters parameters) { + + } + + default void fieldFetched(ExecutionContext executionContext, + ExecutionStrategyParameters executionStrategyParameters, + DataFetcher dataFetcher, + Object fetchedValue, + Supplier dataFetchingEnvironment) { + + } + + + default void newSubscriptionExecution(AlternativeCallContext alternativeCallContext) { + + } + + default void subscriptionEventCompletionDone(AlternativeCallContext alternativeCallContext) { + + } + + default void finishedFetching(ExecutionContext executionContext, ExecutionStrategyParameters newParameters) { + + } + + default void deferFieldFetched(ExecutionStrategyParameters executionStrategyParameters) { + + } + + default void startComplete(ExecutionStrategyParameters parameters) { + + } + + default void stopComplete(ExecutionStrategyParameters parameters) { + + } +} diff --git a/src/main/java/graphql/execution/DefaultResponseMapFactory.java b/src/main/java/graphql/execution/DefaultResponseMapFactory.java new file mode 100644 index 0000000000..3f3392c903 --- /dev/null +++ b/src/main/java/graphql/execution/DefaultResponseMapFactory.java @@ -0,0 +1,26 @@ +package graphql.execution; + +import com.google.common.collect.Maps; +import graphql.Internal; + +import java.util.List; +import java.util.Map; + +/** + * Implements the contract of {@link ResponseMapFactory} with {@link java.util.LinkedHashMap}. + * This is the default of graphql-java since a long time and changing it could cause breaking changes. + */ +@Internal +public class DefaultResponseMapFactory implements ResponseMapFactory { + + @Override + public Map createInsertionOrdered(List keys, List values) { + Map result = Maps.newLinkedHashMapWithExpectedSize(keys.size()); + int ix = 0; + for (Object fieldValue : values) { + String fieldName = keys.get(ix++); + result.put(fieldName, fieldValue); + } + return result; + } +} diff --git a/src/main/java/graphql/execution/DefaultValueUnboxer.java b/src/main/java/graphql/execution/DefaultValueUnboxer.java new file mode 100644 index 0000000000..db03d1cfad --- /dev/null +++ b/src/main/java/graphql/execution/DefaultValueUnboxer.java @@ -0,0 +1,53 @@ +package graphql.execution; + +import graphql.Internal; +import graphql.PublicApi; + +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; + +/** + * Public API because it should be used as a delegate when implementing a custom {@link ValueUnboxer} + */ +@PublicApi +public class DefaultValueUnboxer implements ValueUnboxer { + + + @Override + public Object unbox(final Object object) { + return unboxValue(object); + } + + @Internal // used by next-gen at the moment + public static Object unboxValue(Object result) { + if (result instanceof Optional) { + Optional optional = (Optional) result; + return optional.orElse(null); + } else if (result instanceof OptionalInt) { + OptionalInt optional = (OptionalInt) result; + if (optional.isPresent()) { + return optional.getAsInt(); + } else { + return null; + } + } else if (result instanceof OptionalDouble) { + OptionalDouble optional = (OptionalDouble) result; + if (optional.isPresent()) { + return optional.getAsDouble(); + } else { + return null; + } + } else if (result instanceof OptionalLong) { + OptionalLong optional = (OptionalLong) result; + if (optional.isPresent()) { + return optional.getAsLong(); + } else { + return null; + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/main/java/graphql/execution/EngineRunningObserver.java b/src/main/java/graphql/execution/EngineRunningObserver.java new file mode 100644 index 0000000000..008cb53b4d --- /dev/null +++ b/src/main/java/graphql/execution/EngineRunningObserver.java @@ -0,0 +1,55 @@ +package graphql.execution; + +import graphql.ExecutionInput; +import graphql.ExperimentalApi; +import graphql.GraphQLContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * This class lets you observe the running state of the graphql-java engine. As it processes and dispatches graphql fields, + * the engine moves in and out of a running and not running state. As it does this, the callback is called with information telling you the current + * state. + *

+ * If the engine is cancelled via {@link ExecutionInput#cancel()} then the observer will also be called to indicate that. + */ +@ExperimentalApi +@NullMarked +public interface EngineRunningObserver { + + enum RunningState { + /** + * Represents that the engine is running, for the first time + */ + RUNNING_START, + /** + * Represents that the engine code is actively running its own code + */ + RUNNING, + /** + * Represents that the engine code is asynchronously waiting for fetching to happen + */ + NOT_RUNNING, + /** + * Represents that the engine is finished + */ + NOT_RUNNING_FINISH, + /** + * Represents that the engine code has been cancelled via {@link ExecutionInput#cancel()} + */ + CANCELLED + } + + + String ENGINE_RUNNING_OBSERVER_KEY = "__ENGINE_RUNNING_OBSERVER"; + + + /** + * This will be called when the running state of the graphql-java engine changes. + * + * @param executionId the id of the current execution. This could be null when the engine starts, + * if there is no execution id provided in the execution input + * @param graphQLContext the graphql context + */ + void runningStateChanged(@Nullable ExecutionId executionId, GraphQLContext graphQLContext, RunningState runningState); +} diff --git a/src/main/java/graphql/execution/Execution.java b/src/main/java/graphql/execution/Execution.java index d1fed6c6f5..38c82f5a53 100644 --- a/src/main/java/graphql/execution/Execution.java +++ b/src/main/java/graphql/execution/Execution.java @@ -1,74 +1,90 @@ package graphql.execution; +import graphql.Directives; +import graphql.EngineRunningState; import graphql.ExecutionInput; import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.GraphQL; +import graphql.GraphQLContext; import graphql.GraphQLError; +import graphql.GraphQLException; import graphql.Internal; -import graphql.execution.defer.DeferSupport; +import graphql.Profiler; +import graphql.execution.incremental.IncrementalCallState; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationContext; import graphql.execution.instrumentation.InstrumentationState; +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys; +import graphql.execution.instrumentation.dataloader.ExhaustedDataLoaderDispatchStrategy; +import graphql.execution.instrumentation.dataloader.PerLevelDataLoaderDispatchStrategy; import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; +import graphql.execution.instrumentation.parameters.InstrumentationReactiveResultsParameters; +import graphql.execution.reactive.ReactiveSupport; +import graphql.extensions.ExtensionsBuilder; +import graphql.incremental.DelayedIncrementalPartialResult; +import graphql.incremental.IncrementalExecutionResultImpl; +import graphql.language.Directive; import graphql.language.Document; -import graphql.language.Field; -import graphql.language.FragmentDefinition; import graphql.language.NodeUtil; import graphql.language.OperationDefinition; import graphql.language.VariableDefinition; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; +import graphql.schema.impl.SchemaUtil; +import graphql.util.FpKit; +import org.jspecify.annotations.NonNull; import org.reactivestreams.Publisher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; -import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Directives.EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_DEFINITION; import static graphql.execution.ExecutionContextBuilder.newExecutionContextBuilder; +import static graphql.execution.ExecutionStepInfo.newExecutionStepInfo; import static graphql.execution.ExecutionStrategyParameters.newParameters; -import static graphql.execution.ExecutionTypeInfo.newTypeInfo; -import static graphql.language.OperationDefinition.Operation.MUTATION; -import static graphql.language.OperationDefinition.Operation.QUERY; -import static graphql.language.OperationDefinition.Operation.SUBSCRIPTION; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.nonNullCtx; +import static graphql.execution.instrumentation.dataloader.EmptyDataLoaderRegistryInstance.EMPTY_DATALOADER_REGISTRY; import static java.util.concurrent.CompletableFuture.completedFuture; @Internal public class Execution { - private static final Logger log = LoggerFactory.getLogger(Execution.class); - private final FieldCollector fieldCollector = new FieldCollector(); private final ExecutionStrategy queryStrategy; private final ExecutionStrategy mutationStrategy; private final ExecutionStrategy subscriptionStrategy; private final Instrumentation instrumentation; + private final ValueUnboxer valueUnboxer; + private final boolean doNotAutomaticallyDispatchDataLoader; + - public Execution(ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Instrumentation instrumentation) { + public Execution(ExecutionStrategy queryStrategy, + ExecutionStrategy mutationStrategy, + ExecutionStrategy subscriptionStrategy, + Instrumentation instrumentation, + ValueUnboxer valueUnboxer, + boolean doNotAutomaticallyDispatchDataLoader) { this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new AsyncExecutionStrategy(); this.instrumentation = instrumentation; + this.valueUnboxer = valueUnboxer; + this.doNotAutomaticallyDispatchDataLoader = doNotAutomaticallyDispatchDataLoader; } - public CompletableFuture execute(Document document, GraphQLSchema graphQLSchema, ExecutionId executionId, ExecutionInput executionInput, InstrumentationState instrumentationState) { - - NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, executionInput.getOperationName()); - Map fragmentsByName = getOperationResult.fragmentsByName; - OperationDefinition operationDefinition = getOperationResult.operationDefinition; - - ValuesResolver valuesResolver = new ValuesResolver(); - Map inputVariables = executionInput.getVariables(); - List variableDefinitions = operationDefinition.getVariableDefinitions(); - - Map coercedVariables; + public CompletableFuture execute(Document document, GraphQLSchema graphQLSchema, ExecutionId executionId, ExecutionInput executionInput, InstrumentationState instrumentationState, EngineRunningState engineRunningState, Profiler profiler) { + NodeUtil.GetOperationResult getOperationResult; + CoercedVariables coercedVariables; + Supplier normalizedVariableValues; try { - coercedVariables = valuesResolver.coerceArgumentValues(graphQLSchema, variableDefinitions, inputVariables); + getOperationResult = NodeUtil.getOperation(document, executionInput.getOperationName()); + coercedVariables = coerceVariableValues(graphQLSchema, executionInput, getOperationResult.operationDefinition); + normalizedVariableValues = normalizedVariableValues(graphQLSchema, executionInput, getOperationResult); } catch (RuntimeException rte) { if (rte instanceof GraphQLError) { return completedFuture(new ExecutionResultImpl((GraphQLError) rte)); @@ -76,6 +92,17 @@ public CompletableFuture execute(Document document, GraphQLSche throw rte; } + // before we get started - did they ask us to cancel? + AbortExecutionException abortExecutionException = engineRunningState.ifCancelledMakeException(); + if (abortExecutionException != null) { + return completedFuture(abortExecutionException.toExecutionResult()); + } + + boolean propagateErrorsOnNonNullContractFailure = propagateErrorsOnNonNullContractFailure(getOperationResult.operationDefinition.getDirectives()); + + ResponseMapFactory responseMapFactory = GraphQL.unusualConfiguration(executionInput.getGraphQLContext()) + .responseMapFactory().getOr(ResponseMapFactory.DEFAULT); + ExecutionContext executionContext = newExecutionContextBuilder() .instrumentation(instrumentation) .instrumentationState(instrumentationState) @@ -85,38 +112,72 @@ public CompletableFuture execute(Document document, GraphQLSche .mutationStrategy(mutationStrategy) .subscriptionStrategy(subscriptionStrategy) .context(executionInput.getContext()) + .graphQLContext(executionInput.getGraphQLContext()) + .localContext(executionInput.getLocalContext()) .root(executionInput.getRoot()) - .fragmentsByName(fragmentsByName) - .variables(coercedVariables) + .fragmentsByName(getOperationResult.fragmentsByName) + .coercedVariables(coercedVariables) + .normalizedVariableValues(normalizedVariableValues) .document(document) - .operationDefinition(operationDefinition) + .operationDefinition(getOperationResult.operationDefinition) + .dataLoaderRegistry(executionInput.getDataLoaderRegistry()) + .locale(executionInput.getLocale()) + .valueUnboxer(valueUnboxer) + .responseMapFactory(responseMapFactory) + .executionInput(executionInput) + .propagapropagateErrorsOnNonNullContractFailureeErrors(propagateErrorsOnNonNullContractFailure) + .engineRunningState(engineRunningState) + .profiler(profiler) .build(); + executionContext.getGraphQLContext().put(ResultNodesInfo.RESULT_NODES_INFO, executionContext.getResultNodesInfo()); InstrumentationExecutionParameters parameters = new InstrumentationExecutionParameters( - executionInput, graphQLSchema, instrumentationState + executionInput, graphQLSchema ); - executionContext = instrumentation.instrumentExecutionContext(executionContext, parameters); - return executeOperation(executionContext, parameters, executionInput.getRoot(), executionContext.getOperationDefinition()); + executionContext = instrumentation.instrumentExecutionContext(executionContext, parameters, instrumentationState); + return executeOperation(executionContext, executionInput.getRoot(), executionContext.getOperationDefinition()); } + private static @NonNull CoercedVariables coerceVariableValues(GraphQLSchema graphQLSchema, ExecutionInput executionInput, OperationDefinition operationDefinition) { + RawVariables inputVariables = executionInput.getRawVariables(); + List variableDefinitions = operationDefinition.getVariableDefinitions(); + return ValuesResolver.coerceVariableValues(graphQLSchema, variableDefinitions, inputVariables, executionInput.getGraphQLContext(), executionInput.getLocale()); + } + + private static @NonNull Supplier normalizedVariableValues(GraphQLSchema graphQLSchema, ExecutionInput executionInput, NodeUtil.GetOperationResult getOperationResult) { + Supplier normalizedVariableValues; + RawVariables inputVariables = executionInput.getRawVariables(); + List variableDefinitions = getOperationResult.operationDefinition.getVariableDefinitions(); + + normalizedVariableValues = FpKit.intraThreadMemoize(() -> + ValuesResolver.getNormalizedVariableValues(graphQLSchema, + variableDefinitions, + inputVariables, + executionInput.getGraphQLContext(), executionInput.getLocale())); + return normalizedVariableValues; + } - private CompletableFuture executeOperation(ExecutionContext executionContext, InstrumentationExecutionParameters instrumentationExecutionParameters, Object root, OperationDefinition operationDefinition) { + + private CompletableFuture executeOperation(ExecutionContext executionContext, Object root, OperationDefinition operationDefinition) { + + GraphQLContext graphQLContext = executionContext.getGraphQLContext(); + addExtensionsBuilderNotPresent(graphQLContext); InstrumentationExecuteOperationParameters instrumentationParams = new InstrumentationExecuteOperationParameters(executionContext); - InstrumentationContext executeOperationCtx = instrumentation.beginExecuteOperation(instrumentationParams); + InstrumentationContext executeOperationCtx = nonNullCtx(instrumentation.beginExecuteOperation(instrumentationParams, executionContext.getInstrumentationState())); OperationDefinition.Operation operation = operationDefinition.getOperation(); GraphQLObjectType operationRootType; - + executionContext.getProfiler().operationDefinition(operationDefinition); try { - operationRootType = getOperationRootType(executionContext.getGraphQLSchema(), operationDefinition); + operationRootType = SchemaUtil.getOperationRootType(executionContext.getGraphQLSchema(), operationDefinition); } catch (RuntimeException rte) { if (rte instanceof GraphQLError) { ExecutionResult executionResult = new ExecutionResultImpl(Collections.singletonList((GraphQLError) rte)); CompletableFuture resultCompletableFuture = completedFuture(executionResult); - executeOperationCtx.onDispatched(resultCompletableFuture); + executeOperationCtx.onDispatched(); executeOperationCtx.onCompleted(executionResult, rte); return resultCompletableFuture; } @@ -127,95 +188,129 @@ private CompletableFuture executeOperation(ExecutionContext exe .schema(executionContext.getGraphQLSchema()) .objectType(operationRootType) .fragments(executionContext.getFragmentsByName()) - .variables(executionContext.getVariables()) + .variables(executionContext.getCoercedVariables().toMap()) + .graphQLContext(graphQLContext) .build(); - Map> fields = fieldCollector.collectFields(collectorParameters, operationDefinition.getSelectionSet()); + MergedSelectionSet fields = fieldCollector.collectFields( + collectorParameters, + operationDefinition.getSelectionSet(), + executionContext.hasIncrementalSupport() + ); - ExecutionPath path = ExecutionPath.rootPath(); - ExecutionTypeInfo typeInfo = newTypeInfo().type(operationRootType).path(path).build(); - NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo); + ResultPath path = ResultPath.rootPath(); + ExecutionStepInfo executionStepInfo = newExecutionStepInfo().type(operationRootType).path(path).build(); + NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext); ExecutionStrategyParameters parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .source(root) + .localContext(executionContext.getLocalContext()) .fields(fields) .nonNullFieldValidator(nonNullableFieldValidator) .path(path) .build(); + CompletableFuture result; try { - ExecutionStrategy executionStrategy; - if (operation == OperationDefinition.Operation.MUTATION) { - executionStrategy = mutationStrategy; - } else if (operation == SUBSCRIPTION) { - executionStrategy = subscriptionStrategy; - } else { - executionStrategy = queryStrategy; - } - log.debug("Executing '{}' query operation: '{}' using '{}' execution strategy", executionContext.getExecutionId(), operation, executionStrategy.getClass().getName()); + ExecutionStrategy executionStrategy = executionContext.getStrategy(operation); + DataLoaderDispatchStrategy dataLoaderDispatchStrategy = createDataLoaderDispatchStrategy(executionContext, executionStrategy); + executionContext.setDataLoaderDispatcherStrategy(dataLoaderDispatchStrategy); result = executionStrategy.execute(executionContext, parameters); } catch (NonNullableFieldWasNullException e) { - // this means it was non null types all the way from an offending non null type - // up to the root object type and there was a a null value some where. + // this means it was non-null types all the way from an offending non-null type + // up to the root object type and there was a null value somewhere. // // The spec says we should return null for the data in this case // - // http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability + // https://spec.graphql.org/October2021/#sec-Handling-Field-Errors // result = completedFuture(new ExecutionResultImpl(null, executionContext.getErrors())); } // note this happens NOW - not when the result completes - executeOperationCtx.onDispatched(result); + executeOperationCtx.onDispatched(); + + // fill out extensions if we have them + result = result.thenApply(er -> mergeExtensionsBuilderIfPresent(er, graphQLContext)); result = result.whenComplete(executeOperationCtx::onCompleted); - return deferSupport(executionContext, result); + return incrementalSupport(executionContext, result); } /* - * Adds the deferred publisher if its needed at the end of the query. This is also a good time for the deferred code to start running + * Adds the deferred publisher if it's needed at the end of the query. This is also a good time for the deferred code to start running */ - private CompletableFuture deferSupport(ExecutionContext executionContext, CompletableFuture result) { + private CompletableFuture incrementalSupport(ExecutionContext executionContext, CompletableFuture result) { return result.thenApply(er -> { - DeferSupport deferSupport = executionContext.getDeferSupport(); - if (deferSupport.isDeferDetected()) { - // we start the rest of the query now to maximize throughput. We have the initial important results - // and now we can start the rest of the calls as early as possible (even before some one subscribes) - Publisher publisher = deferSupport.startDeferredCalls(); - return ExecutionResultImpl.newExecutionResult().from((ExecutionResultImpl) er) - .addExtension(GraphQL.DEFERRED_RESULTS, publisher) + IncrementalCallState incrementalCallState = executionContext.getIncrementalCallState(); + if (incrementalCallState.getIncrementalCallsDetected()) { + InstrumentationReactiveResultsParameters parameters = new InstrumentationReactiveResultsParameters(executionContext, InstrumentationReactiveResultsParameters.ResultType.DEFER); + InstrumentationContext ctx = nonNullCtx(executionContext.getInstrumentation().beginReactiveResults(parameters, executionContext.getInstrumentationState())); + + // we start the rest of the query now to maximize throughput. We have the initial important results, + // and now we can start the rest of the calls as early as possible (even before someone subscribes) + Publisher publisher = incrementalCallState.startDeferredCalls(); + ctx.onDispatched(); + + // + // wrap this Publisher into one that can call us back when the publishing is done either in error or successful + publisher = ReactiveSupport.whenPublisherFinishes(publisher, throwable -> ctx.onCompleted(null, throwable)); + + return IncrementalExecutionResultImpl.fromExecutionResult(er) + // "hasNext" can, in theory, be "false" when all the incremental items are delivered in the + // first response payload. However, the current implementation will never result in this. + // The behaviour might change if we decide to make optimizations in the future. + .hasNext(true) + .incrementalItemPublisher(publisher) .build(); } return er; }); - } - private GraphQLObjectType getOperationRootType(GraphQLSchema graphQLSchema, OperationDefinition operationDefinition) { - OperationDefinition.Operation operation = operationDefinition.getOperation(); - if (operation == MUTATION) { - GraphQLObjectType mutationType = graphQLSchema.getMutationType(); - if (mutationType == null) { - throw new MissingRootTypeException("Schema is not configured for mutations.", operationDefinition.getSourceLocation()); - } - return mutationType; - } else if (operation == QUERY) { - GraphQLObjectType queryType = graphQLSchema.getQueryType(); - if (queryType == null) { - throw new MissingRootTypeException("Schema does not define the required query root type.", operationDefinition.getSourceLocation()); + private DataLoaderDispatchStrategy createDataLoaderDispatchStrategy(ExecutionContext executionContext, ExecutionStrategy executionStrategy) { + if (executionContext.getDataLoaderRegistry() == EMPTY_DATALOADER_REGISTRY || doNotAutomaticallyDispatchDataLoader) { + return DataLoaderDispatchStrategy.NO_OP; + } + if (executionContext.getGraphQLContext().getBoolean(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, false)) { + if (executionContext.getGraphQLContext().getBoolean(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, false)) { + throw new GraphQLException("enabling data loader chaining and exhausted dispatching at the same time ambiguous"); } - return queryType; - } else if (operation == SUBSCRIPTION) { - GraphQLObjectType subscriptionType = graphQLSchema.getSubscriptionType(); - if (subscriptionType == null) { - throw new MissingRootTypeException("Schema is not configured for subscriptions.", operationDefinition.getSourceLocation()); + return new ExhaustedDataLoaderDispatchStrategy(executionContext); + } + return new PerLevelDataLoaderDispatchStrategy(executionContext); + } + + + private void addExtensionsBuilderNotPresent(GraphQLContext graphQLContext) { + Object builder = graphQLContext.get(ExtensionsBuilder.class); + if (builder == null) { + graphQLContext.put(ExtensionsBuilder.class, ExtensionsBuilder.newExtensionsBuilder()); + } + } + + private ExecutionResult mergeExtensionsBuilderIfPresent(ExecutionResult executionResult, GraphQLContext graphQLContext) { + Object builder = graphQLContext.get(ExtensionsBuilder.class); + if (builder instanceof ExtensionsBuilder) { + ExtensionsBuilder extensionsBuilder = (ExtensionsBuilder) builder; + Map currentExtensions = executionResult.getExtensions(); + if (currentExtensions != null) { + extensionsBuilder.addValues(currentExtensions); } - return subscriptionType; - } else { - return assertShouldNeverHappen("Unhandled case. An extra operation enum has been added without code support"); + executionResult = extensionsBuilder.setExtensions(executionResult); + } + return executionResult; + } + + private boolean propagateErrorsOnNonNullContractFailure(List directives) { + boolean jvmWideEnabled = Directives.isExperimentalDisableErrorPropagationDirectiveEnabled(); + if (!jvmWideEnabled) { + return true; } + Directive foundDirective = NodeUtil.findNodeByName(directives, EXPERIMENTAL_DISABLE_ERROR_PROPAGATION_DIRECTIVE_DEFINITION.getName()); + return foundDirective == null; } } diff --git a/src/main/java/graphql/execution/ExecutionContext.java b/src/main/java/graphql/execution/ExecutionContext.java index 0d04038f8e..c6a7edc916 100644 --- a/src/main/java/graphql/execution/ExecutionContext.java +++ b/src/main/java/graphql/execution/ExecutionContext.java @@ -1,21 +1,39 @@ package graphql.execution; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.EngineRunningState; +import graphql.ExecutionInput; +import graphql.ExperimentalApi; +import graphql.GraphQLContext; import graphql.GraphQLError; +import graphql.Internal; +import graphql.Profiler; import graphql.PublicApi; -import graphql.execution.defer.DeferSupport; +import graphql.collect.ImmutableKit; +import graphql.execution.incremental.IncrementalCallState; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationState; import graphql.language.Document; import graphql.language.FragmentDefinition; import graphql.language.OperationDefinition; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.ExecutableNormalizedOperationFactory; import graphql.schema.GraphQLSchema; +import graphql.util.FpKit; +import graphql.util.LockKit; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.Nullable; -import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.function.Supplier; @SuppressWarnings("TypeParameterUnusedInFormals") @PublicApi @@ -27,42 +45,75 @@ public class ExecutionContext { private final ExecutionStrategy queryStrategy; private final ExecutionStrategy mutationStrategy; private final ExecutionStrategy subscriptionStrategy; - private final Map fragmentsByName; + private final ImmutableMap fragmentsByName; private final OperationDefinition operationDefinition; private final Document document; - private final Map variables; + private final CoercedVariables coercedVariables; + private final Supplier normalizedVariables; private final Object root; private final Object context; + private final GraphQLContext graphQLContext; + private final Object localContext; private final Instrumentation instrumentation; - private final List errors = new CopyOnWriteArrayList<>(); - private final DeferSupport deferSupport = new DeferSupport(); + private final AtomicReference> errors = new AtomicReference<>(ImmutableKit.emptyList()); + private final LockKit.ReentrantLock errorsLock = new LockKit.ReentrantLock(); + private final Set errorPaths = new HashSet<>(); + private final DataLoaderRegistry dataLoaderRegistry; + private final Locale locale; + private final IncrementalCallState incrementalCallState = new IncrementalCallState(); + private final ValueUnboxer valueUnboxer; + private final ResponseMapFactory responseMapFactory; - public ExecutionContext(Instrumentation instrumentation, ExecutionId executionId, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Map fragmentsByName, Document document, OperationDefinition operationDefinition, Map variables, Object context, Object root) { - this(instrumentation, executionId, graphQLSchema, instrumentationState, queryStrategy, mutationStrategy, subscriptionStrategy, fragmentsByName, document, operationDefinition, variables, context, root, Collections.emptyList()); - } + private final ExecutionInput executionInput; + private final Supplier queryTree; + private final boolean propagateErrorsOnNonNullContractFailure; - ExecutionContext(Instrumentation instrumentation, ExecutionId executionId, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Map fragmentsByName, Document document, OperationDefinition operationDefinition, Map variables, Object context, Object root, List startingErrors) { - this.graphQLSchema = graphQLSchema; - this.executionId = executionId; - this.instrumentationState = instrumentationState; - this.queryStrategy = queryStrategy; - this.mutationStrategy = mutationStrategy; - this.subscriptionStrategy = subscriptionStrategy; - this.fragmentsByName = fragmentsByName; - this.document = document; - this.operationDefinition = operationDefinition; - this.variables = variables; - this.context = context; - this.root = root; - this.instrumentation = instrumentation; - this.errors.addAll(startingErrors); - } + // this is modified after creation so it needs to be volatile to ensure visibility across Threads + private volatile DataLoaderDispatchStrategy dataLoaderDispatcherStrategy = DataLoaderDispatchStrategy.NO_OP; + + private final ResultNodesInfo resultNodesInfo = new ResultNodesInfo(); + private final EngineRunningState engineRunningState; + private final Profiler profiler; + + ExecutionContext(ExecutionContextBuilder builder) { + this.graphQLSchema = builder.graphQLSchema; + this.executionId = builder.executionId; + this.instrumentationState = builder.instrumentationState; + this.queryStrategy = builder.queryStrategy; + this.mutationStrategy = builder.mutationStrategy; + this.subscriptionStrategy = builder.subscriptionStrategy; + this.fragmentsByName = builder.fragmentsByName; + this.coercedVariables = builder.coercedVariables; + this.normalizedVariables = builder.normalizedVariables; + this.document = builder.document; + this.operationDefinition = builder.operationDefinition; + this.context = builder.context; + this.graphQLContext = builder.graphQLContext; + this.root = builder.root; + this.instrumentation = builder.instrumentation; + this.dataLoaderRegistry = builder.dataLoaderRegistry; + this.locale = builder.locale; + this.valueUnboxer = builder.valueUnboxer; + this.responseMapFactory = builder.responseMapFactory; + this.errors.set(builder.errors); + this.localContext = builder.localContext; + this.executionInput = builder.executionInput; + this.dataLoaderDispatcherStrategy = builder.dataLoaderDispatcherStrategy; + this.queryTree = FpKit.interThreadMemoize(() -> ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(graphQLSchema, operationDefinition, fragmentsByName, coercedVariables)); + this.propagateErrorsOnNonNullContractFailure = builder.propagateErrorsOnNonNullContractFailure; + this.engineRunningState = builder.engineRunningState; + this.profiler = builder.profiler; + } public ExecutionId getExecutionId() { return executionId; } + public ExecutionInput getExecutionInput() { + return executionInput; + } + public InstrumentationState getInstrumentationState() { return instrumentationState; } @@ -87,12 +138,37 @@ public OperationDefinition getOperationDefinition() { return operationDefinition; } - public Map getVariables() { - return variables; + public CoercedVariables getCoercedVariables() { + return coercedVariables; } - public Object getContext() { - return context; + /** + * @return a supplier that will give out the operations variables in normalized form + */ + public Supplier getNormalizedVariables() { + return normalizedVariables; + } + + /** + * @param for two + * + * @return the legacy context + * + * @deprecated use {@link #getGraphQLContext()} instead + */ + @Deprecated(since = "2021-07-05") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) + public T getContext() { + return (T) context; + } + + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + @SuppressWarnings("unchecked") + public T getLocalContext() { + return (T) localContext; } @SuppressWarnings("unchecked") @@ -104,27 +180,76 @@ public FragmentDefinition getFragment(String name) { return fragmentsByName.get(name); } + public DataLoaderRegistry getDataLoaderRegistry() { + return dataLoaderRegistry; + } + + public Locale getLocale() { + return locale; + } + + public ValueUnboxer getValueUnboxer() { + return valueUnboxer; + } + + /** + * @return true if the current operation should propagate errors in non-null positions + * Propagating errors is the default. Error aware clients may opt in returning null in non-null positions + * by using the `@experimental_disableErrorPropagation` directive. + * + * @see graphql.Directives#setExperimentalDisableErrorPropagationEnabled(boolean) to change the JVM wide default + */ + @ExperimentalApi + public boolean propagateErrorsOnNonNullContractFailure() { + return propagateErrorsOnNonNullContractFailure; + } + + /** + * @return true if the current operation is a Query + */ + public boolean isQueryOperation() { + return isOpType(OperationDefinition.Operation.QUERY); + } + + /** + * @return true if the current operation is a Mutation + */ + public boolean isMutationOperation() { + return isOpType(OperationDefinition.Operation.MUTATION); + } + + /** + * @return true if the current operation is a Subscription + */ + public boolean isSubscriptionOperation() { + return isOpType(OperationDefinition.Operation.SUBSCRIPTION); + } + + private boolean isOpType(OperationDefinition.Operation operation) { + if (operationDefinition != null) { + return operation.equals(operationDefinition.getOperation()); + } + return false; + } + /** * This method will only put one error per field path. * * @param error the error to add * @param fieldPath the field path to put it under */ - public void addError(GraphQLError error, ExecutionPath fieldPath) { - // - // see http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability about how per - // field errors should be handled - ie only once per field if its already there for nullability - // but unclear if its not that error path - // - for (GraphQLError graphQLError : errors) { - List path = graphQLError.getPath(); - if (path != null) { - if (fieldPath.equals(ExecutionPath.fromList(path))) { - return; - } + public void addError(GraphQLError error, ResultPath fieldPath) { + errorsLock.runLocked(() -> { + // + // see https://spec.graphql.org/October2021/#sec-Handling-Field-Errors about how per + // field errors should be handled - ie only once per field if it's already there for nullability + // but unclear if it's not that error path + // + if (!errorPaths.add(fieldPath)) { + return; } - } - this.errors.add(error); + this.errors.set(ImmutableKit.addToList(this.errors.get(), error)); + }); } /** @@ -134,17 +259,56 @@ public void addError(GraphQLError error, ExecutionPath fieldPath) { * @param error the error to add */ public void addError(GraphQLError error) { - // see https://github.com/graphql-java/graphql-java/issues/888 on how the spec is unclear - // on how exactly multiple errors should be handled - ie only once per field or not outside the nullability - // aspect. - this.errors.add(error); + errorsLock.runLocked(() -> { + // see https://github.com/graphql-java/graphql-java/issues/888 on how the spec is unclear + // on how exactly multiple errors should be handled - ie only once per field or not outside the nullability + // aspect. + if (error.getPath() != null) { + ResultPath path = ResultPath.fromList(error.getPath()); + this.errorPaths.add(path); + } + this.errors.set(ImmutableKit.addToList(this.errors.get(), error)); + }); + } + + /** + * This method will allow you to add errors into the running execution context, without a check + * for per field unique-ness + * + * @param errors the errors to add + */ + public void addErrors(List errors) { + if (errors.isEmpty()) { + return; + } + // we are locked because we set two fields at once - but we only ever read one of them later + // in getErrors so no need for synchronised there. + errorsLock.runLocked(() -> { + Set newErrorPaths = new HashSet<>(); + for (GraphQLError error : errors) { + // see https://github.com/graphql-java/graphql-java/issues/888 on how the spec is unclear + // on how exactly multiple errors should be handled - ie only once per field or not outside the nullability + // aspect. + if (error.getPath() != null) { + ResultPath path = ResultPath.fromList(error.getPath()); + newErrorPaths.add(path); + } + } + this.errorPaths.addAll(newErrorPaths); + this.errors.set(ImmutableKit.concatLists(this.errors.get(), errors)); + }); + } + + @Internal + public ResponseMapFactory getResponseMapFactory() { + return responseMapFactory; } /** * @return the total list of errors for this execution context */ public List getErrors() { - return Collections.unmodifiableList(errors); + return errors.get(); } public ExecutionStrategy getQueryStrategy() { @@ -159,8 +323,32 @@ public ExecutionStrategy getSubscriptionStrategy() { return subscriptionStrategy; } - public DeferSupport getDeferSupport() { - return deferSupport; + public IncrementalCallState getIncrementalCallState() { + return incrementalCallState; + } + + public ExecutionStrategy getStrategy(OperationDefinition.Operation operation) { + if (operation == OperationDefinition.Operation.MUTATION) { + return getMutationStrategy(); + } else if (operation == OperationDefinition.Operation.SUBSCRIPTION) { + return getSubscriptionStrategy(); + } else { + return getQueryStrategy(); + } + } + + public Supplier getNormalizedQueryTree() { + return queryTree; + } + + @Internal + public void setDataLoaderDispatcherStrategy(DataLoaderDispatchStrategy dataLoaderDispatcherStrategy) { + this.dataLoaderDispatcherStrategy = dataLoaderDispatcherStrategy; + } + + @Internal + public DataLoaderDispatchStrategy getDataLoaderDispatcherStrategy() { + return dataLoaderDispatcherStrategy; } /** @@ -176,4 +364,36 @@ public ExecutionContext transform(Consumer builderConsu builderConsumer.accept(builder); return builder.build(); } + + public ResultNodesInfo getResultNodesInfo() { + return resultNodesInfo; + } + + @Internal + public boolean hasIncrementalSupport() { + GraphQLContext graphqlContext = getGraphQLContext(); + return graphqlContext != null && graphqlContext.getBoolean(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT); + } + + @Internal + public EngineRunningState getEngineRunningState() { + return engineRunningState; + } + + @Internal + @Nullable + Throwable possibleCancellation(@Nullable Throwable currentThrowable) { + return engineRunningState.possibleCancellation(currentThrowable); + } + + + @Internal + public Profiler getProfiler() { + return profiler; + } + + @Internal + void throwIfCancelled() throws AbortExecutionException { + engineRunningState.throwIfCancelled(); + } } diff --git a/src/main/java/graphql/execution/ExecutionContextBuilder.java b/src/main/java/graphql/execution/ExecutionContextBuilder.java index b1f41af070..f8dd44898e 100644 --- a/src/main/java/graphql/execution/ExecutionContextBuilder.java +++ b/src/main/java/graphql/execution/ExecutionContextBuilder.java @@ -1,39 +1,60 @@ package graphql.execution; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.EngineRunningState; +import graphql.ExecutionInput; +import graphql.ExperimentalApi; +import graphql.GraphQLContext; import graphql.GraphQLError; import graphql.Internal; -import graphql.PublicApi; +import graphql.Profiler; +import graphql.collect.ImmutableKit; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationState; import graphql.language.Document; import graphql.language.FragmentDefinition; import graphql.language.OperationDefinition; import graphql.schema.GraphQLSchema; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.function.Supplier; import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; -@PublicApi +@Internal public class ExecutionContextBuilder { - private Instrumentation instrumentation; - private ExecutionId executionId; - private InstrumentationState instrumentationState; - private GraphQLSchema graphQLSchema; - private ExecutionStrategy queryStrategy; - private ExecutionStrategy mutationStrategy; - private ExecutionStrategy subscriptionStrategy; - private Object context; - private Object root; - private Document document; - private OperationDefinition operationDefinition; - private Map variables = new HashMap<>(); - private Map fragmentsByName = new HashMap<>(); - private List errors = new ArrayList<>(); + Instrumentation instrumentation; + ExecutionId executionId; + InstrumentationState instrumentationState; + GraphQLSchema graphQLSchema; + ExecutionStrategy queryStrategy; + ExecutionStrategy mutationStrategy; + ExecutionStrategy subscriptionStrategy; + Object context; + GraphQLContext graphQLContext; + Object root; + Document document; + OperationDefinition operationDefinition; + CoercedVariables coercedVariables = CoercedVariables.emptyVariables(); + Supplier normalizedVariables = NormalizedVariables::emptyVariables; + ImmutableMap fragmentsByName = ImmutableKit.emptyMap(); + DataLoaderRegistry dataLoaderRegistry; + Locale locale; + ImmutableList errors = emptyList(); + ValueUnboxer valueUnboxer; + Object localContext; + ExecutionInput executionInput; + DataLoaderDispatchStrategy dataLoaderDispatcherStrategy = DataLoaderDispatchStrategy.NO_OP; + boolean propagateErrorsOnNonNullContractFailure = true; + EngineRunningState engineRunningState; + ResponseMapFactory responseMapFactory = ResponseMapFactory.DEFAULT; + Profiler profiler; /** * @return a new builder of {@link graphql.execution.ExecutionContext}s @@ -67,12 +88,23 @@ public ExecutionContextBuilder() { mutationStrategy = other.getMutationStrategy(); subscriptionStrategy = other.getSubscriptionStrategy(); context = other.getContext(); + graphQLContext = other.getGraphQLContext(); + localContext = other.getLocalContext(); root = other.getRoot(); document = other.getDocument(); operationDefinition = other.getOperationDefinition(); - variables = new HashMap<>(other.getVariables()); - fragmentsByName = new HashMap<>(other.getFragmentsByName()); - errors = new ArrayList<>(other.getErrors()); + coercedVariables = other.getCoercedVariables(); + fragmentsByName = ImmutableMap.copyOf(other.getFragmentsByName()); + dataLoaderRegistry = other.getDataLoaderRegistry(); + locale = other.getLocale(); + errors = ImmutableList.copyOf(other.getErrors()); + valueUnboxer = other.getValueUnboxer(); + executionInput = other.getExecutionInput(); + dataLoaderDispatcherStrategy = other.getDataLoaderDispatcherStrategy(); + propagateErrorsOnNonNullContractFailure = other.propagateErrorsOnNonNullContractFailure(); + engineRunningState = other.getEngineRunningState(); + responseMapFactory = other.getResponseMapFactory(); + profiler = other.getProfiler(); } public ExecutionContextBuilder instrumentation(Instrumentation instrumentation) { @@ -110,23 +142,54 @@ public ExecutionContextBuilder subscriptionStrategy(ExecutionStrategy subscripti return this; } - public ExecutionContextBuilder context(Object context) { + /* + * @deprecated use {@link #graphQLContext(GraphQLContext)} instead + */ + @Deprecated(since = "2021-07-05") + public ExecutionContextBuilder context(@Nullable Object context) { this.context = context; return this; } + public ExecutionContextBuilder graphQLContext(GraphQLContext context) { + this.graphQLContext = context; + return this; + } + + public ExecutionContextBuilder localContext(Object localContext) { + this.localContext = localContext; + return this; + } + public ExecutionContextBuilder root(Object root) { this.root = root; return this; } + /** + * @param variables map of already coerced variables + * @return this builder + * + * @deprecated use {@link #coercedVariables(CoercedVariables)} instead + */ + @Deprecated(since = "2022-05-24") public ExecutionContextBuilder variables(Map variables) { - this.variables = variables; + this.coercedVariables = CoercedVariables.of(variables); + return this; + } + + public ExecutionContextBuilder coercedVariables(CoercedVariables coercedVariables) { + this.coercedVariables = coercedVariables; + return this; + } + + public ExecutionContextBuilder normalizedVariableValues(Supplier normalizedVariables) { + this.normalizedVariables = normalizedVariables; return this; } public ExecutionContextBuilder fragmentsByName(Map fragmentsByName) { - this.fragmentsByName = fragmentsByName; + this.fragmentsByName = ImmutableMap.copyOf(fragmentsByName); return this; } @@ -140,25 +203,63 @@ public ExecutionContextBuilder operationDefinition(OperationDefinition operation return this; } + public ExecutionContextBuilder dataLoaderRegistry(DataLoaderRegistry dataLoaderRegistry) { + this.dataLoaderRegistry = assertNotNull(dataLoaderRegistry); + return this; + } + + public ExecutionContextBuilder locale(Locale locale) { + this.locale = locale; + return this; + } + + public ExecutionContextBuilder valueUnboxer(ValueUnboxer valueUnboxer) { + this.valueUnboxer = valueUnboxer; + return this; + } + + public ExecutionContextBuilder executionInput(ExecutionInput executionInput) { + this.executionInput = executionInput; + return this; + } + + @Internal + public ExecutionContextBuilder dataLoaderDispatcherStrategy(DataLoaderDispatchStrategy dataLoaderDispatcherStrategy) { + this.dataLoaderDispatcherStrategy = dataLoaderDispatcherStrategy; + return this; + } + + @Internal + public ExecutionContextBuilder responseMapFactory(ResponseMapFactory responseMapFactory) { + this.responseMapFactory = responseMapFactory; + return this; + } + + public ExecutionContextBuilder resetErrors() { + this.errors = emptyList(); + return this; + } + + @ExperimentalApi + public ExecutionContextBuilder propagapropagateErrorsOnNonNullContractFailureeErrors(boolean propagateErrorsOnNonNullContractFailure) { + this.propagateErrorsOnNonNullContractFailure = propagateErrorsOnNonNullContractFailure; + return this; + } + public ExecutionContext build() { // preconditions assertNotNull(executionId, "You must provide a query identifier"); + return new ExecutionContext(this); + } - return new ExecutionContext( - instrumentation, - executionId, - graphQLSchema, - instrumentationState, - queryStrategy, - mutationStrategy, - subscriptionStrategy, - fragmentsByName, - document, - operationDefinition, - variables, - context, - root, - errors); + public ExecutionContextBuilder engineRunningState(EngineRunningState engineRunningState) { + this.engineRunningState = engineRunningState; + return this; + } + + public ExecutionContextBuilder profiler(Profiler profiler) { + this.profiler = profiler; + return this; } } diff --git a/src/main/java/graphql/execution/ExecutionId.java b/src/main/java/graphql/execution/ExecutionId.java index 45307e218f..40ffd3466f 100644 --- a/src/main/java/graphql/execution/ExecutionId.java +++ b/src/main/java/graphql/execution/ExecutionId.java @@ -1,12 +1,13 @@ package graphql.execution; import graphql.Assert; - -import java.util.UUID; +import graphql.PublicApi; +import graphql.util.IdGenerator; /** * This opaque identifier is used to identify a unique query execution */ +@PublicApi public class ExecutionId { /** @@ -15,7 +16,7 @@ public class ExecutionId { * @return a query execution identifier */ public static ExecutionId generate() { - return new ExecutionId(UUID.randomUUID().toString()); + return new ExecutionId(IdGenerator.uuid().toString()); } /** diff --git a/src/main/java/graphql/execution/ExecutionIdProvider.java b/src/main/java/graphql/execution/ExecutionIdProvider.java index a9d8702166..655d60560a 100644 --- a/src/main/java/graphql/execution/ExecutionIdProvider.java +++ b/src/main/java/graphql/execution/ExecutionIdProvider.java @@ -1,10 +1,16 @@ package graphql.execution; +import graphql.PublicSpi; + /** * A provider of {@link ExecutionId}s */ +@PublicSpi public interface ExecutionIdProvider { + ExecutionIdProvider DEFAULT_EXECUTION_ID_PROVIDER = (query, operationName, context) -> ExecutionId.generate(); + + /** * Allows provision of a unique identifier per query execution. * diff --git a/src/main/java/graphql/execution/ExecutionPath.java b/src/main/java/graphql/execution/ExecutionPath.java deleted file mode 100644 index 58ac1a3e25..0000000000 --- a/src/main/java/graphql/execution/ExecutionPath.java +++ /dev/null @@ -1,245 +0,0 @@ -package graphql.execution; - -import graphql.AssertException; -import graphql.PublicApi; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.StringTokenizer; - -import static graphql.Assert.assertNotNull; -import static graphql.Assert.assertTrue; -import static java.lang.String.format; - - -/** - * As a graphql query is executed, each field forms a hierarchical path from parent field to child field and this - * class represents that path as a series of segments. - */ -@PublicApi -public class ExecutionPath { - private static final ExecutionPath ROOT_PATH = new ExecutionPath(); - - /** - * All paths start from here - * - * @return the root path - */ - public static ExecutionPath rootPath() { - return ROOT_PATH; - } - - private final ExecutionPath parent; - private final PathSegment segment; - private final List pathList; - - private ExecutionPath() { - parent = null; - segment = null; - pathList = toListImpl(); - } - - private ExecutionPath(ExecutionPath parent, PathSegment segment) { - this.parent = assertNotNull(parent, "Must provide a parent path"); - this.segment = assertNotNull(segment, "Must provide a sub path"); - pathList = toListImpl(); - } - - public int getLevel() { - int counter = 0; - ExecutionPath currentPath = this; - while (currentPath != null) { - if (currentPath.segment instanceof StringPathSegment) { - counter++; - } - currentPath = currentPath.parent; - } - return counter; - } - - public ExecutionPath getPathWithoutListEnd() { - if(ROOT_PATH.equals(this)) { - return ROOT_PATH; - } - if (segment instanceof StringPathSegment) { - return this; - } - return parent; - } - - public String getSegmentName() { - if (segment instanceof StringPathSegment) { - return ((StringPathSegment) segment).getValue(); - } else { - if (parent == null) { - return null; - } - return ((StringPathSegment) parent.segment).getValue(); - } - } - - /** - * Parses an execution path from the provided path string in the format /segment1/segment2[index]/segmentN - * - * @param pathString the path string - * @return a parsed execution path - */ - public static ExecutionPath parse(String pathString) { - pathString = pathString == null ? "" : pathString; - pathString = pathString.trim(); - StringTokenizer st = new StringTokenizer(pathString, "/[]", true); - ExecutionPath path = ExecutionPath.rootPath(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if ("/".equals(token)) { - assertTrue(st.hasMoreTokens(), mkErrMsg(), pathString); - path = path.segment(st.nextToken()); - } else if ("[".equals(token)) { - assertTrue(st.countTokens() >= 2, mkErrMsg(), pathString); - path = path.segment(Integer.parseInt(st.nextToken())); - String closingBrace = st.nextToken(); - assertTrue(closingBrace.equals("]"), mkErrMsg(), pathString); - } else { - throw new AssertException(format(mkErrMsg(), pathString)); - } - } - return path; - } - - /** - * This will create an execution path from the list of objects - * - * @param objects the path objects - * @return a new execution path - */ - public static ExecutionPath fromList(List objects) { - assertNotNull(objects); - ExecutionPath path = ExecutionPath.rootPath(); - for (Object object : objects) { - if (object instanceof Number) { - path = path.segment(((Number) object).intValue()); - } else { - path = path.segment(String.valueOf(object)); - } - } - return path; - } - - private static String mkErrMsg() { - return "Invalid path string : '%s'"; - } - - /** - * Takes the current path and adds a new segment to it, returning a new path - * - * @param segment the string path segment to add - * @return a new path containing that segment - */ - public ExecutionPath segment(String segment) { - return new ExecutionPath(this, new StringPathSegment(segment)); - } - - /** - * Takes the current path and adds a new segment to it, returning a new path - * - * @param segment the int path segment to add - * @return a new path containing that segment - */ - public ExecutionPath segment(int segment) { - return new ExecutionPath(this, new IntPathSegment(segment)); - } - - /** - * @return converts the path into a list of segments - */ - public List toList() { - return new ArrayList<>(pathList); - } - - private List toListImpl() { - if (parent == null) { - return Collections.emptyList(); - } - List list = new ArrayList<>(); - ExecutionPath p = this; - while (p.segment != null) { - list.add(p.segment.getValue()); - p = p.parent; - } - Collections.reverse(list); - return list; - } - - /** - * @return the path as a string which represents the call hierarchy - */ - @Override - public String toString() { - if (parent == null) { - return ""; - } - - if (ROOT_PATH.equals(parent)) { - return segment.toString(); - } - - return parent.toString() + segment.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ExecutionPath that = (ExecutionPath) o; - - return pathList.equals(that.pathList); - } - - @Override - public int hashCode() { - return pathList.hashCode(); - } - - public interface PathSegment { - T getValue(); - } - - private static class StringPathSegment implements PathSegment { - private final String value; - - StringPathSegment(String value) { - assertTrue(value != null && !value.isEmpty(), "empty path component"); - this.value = value; - } - - @Override - public String getValue() { - return value; - } - - @Override - public String toString() { - return '/' + value; - } - } - - private static class IntPathSegment implements PathSegment { - private final int value; - - IntPathSegment(int value) { - this.value = value; - } - - @Override - public Integer getValue() { - return value; - } - - @Override - public String toString() { - return "[" + value + ']'; - } - } -} diff --git a/src/main/java/graphql/execution/ExecutionStepInfo.java b/src/main/java/graphql/execution/ExecutionStepInfo.java new file mode 100644 index 0000000000..26737cd127 --- /dev/null +++ b/src/main/java/graphql/execution/ExecutionStepInfo.java @@ -0,0 +1,346 @@ +package graphql.execution; + +import graphql.Internal; +import graphql.PublicApi; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLTypeUtil; + +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.schema.GraphQLTypeUtil.isList; + +/** + * As the graphql query executes, it forms a hierarchy from parent fields (and their type) to their child fields (and their type) + * until a scalar type is encountered; this class captures that execution type information. + *

+ * The static graphql type system (rightly) does not contain a hierarchy of child to parent types nor the nonnull ness of + * type instances, so this helper class adds this information during query execution. + */ +@PublicApi +public class ExecutionStepInfo { + + /* + * An ExecutionStepInfo represent either a field or a list element inside a list of objects/interfaces/unions. + * + * A StepInfo never represent a Scalar/Enum inside a list (e.g. [String]) because GraphQL execution doesn't descend down + * scalar/enums lists. + * + */ + + /** + * If this StepInfo represent a field the type is equal to fieldDefinition.getType() + *

+ * if this StepInfo is a list element this type is the actual current list element. For example: + * Query.pets: [[Pet]] with Pet either a Dog or Cat and the actual result is [[Dog1],[[Cat1]] + * Then the type is (for a query "{pets{name}}"): + * [[Pet]] for /pets (representing the field Query.pets, not a list element) + * [Pet] fot /pets[0] + * [Pet] for /pets[1] + * Dog for /pets[0][0] + * Cat for /pets[1][0] + * String for /pets[0][0]/name (representing the field Dog.name, not a list element) + * String for /pets[1][0]/name (representing the field Cat.name, not a list element) + */ + private final GraphQLOutputType type; + + /** + * A list element is characterized by having a path ending with an index segment. (ResultPath.isListSegment()) + */ + private final ResultPath path; + private final ExecutionStepInfo parent; + + /** + * field, fieldDefinition, fieldContainer and arguments differ per field StepInfo. + *

+ * But for list StepInfos these properties are the same as the field returning the list. + */ + private final MergedField field; + private final GraphQLFieldDefinition fieldDefinition; + private final GraphQLObjectType fieldContainer; + private final Supplier> arguments; + + private ExecutionStepInfo(Builder builder) { + this.fieldDefinition = builder.fieldDefinition; + this.field = builder.field; + this.path = builder.path; + this.parent = builder.parentInfo; + this.type = assertNotNull(builder.type, "you must provide a graphql type"); + this.arguments = builder.arguments; + this.fieldContainer = builder.fieldContainer; + } + + /* + * This constructor allows for a slightly ( 1% ish) faster transformation without an intermediate Builder object + */ + private ExecutionStepInfo(GraphQLOutputType type, + ResultPath path, + ExecutionStepInfo parent, + MergedField field, + GraphQLFieldDefinition fieldDefinition, + GraphQLObjectType fieldContainer, + Supplier> arguments) { + this.type = assertNotNull(type, "you must provide a graphql type"); + this.path = path; + this.parent = parent; + this.field = field; + this.fieldDefinition = fieldDefinition; + this.fieldContainer = fieldContainer; + this.arguments = arguments; + } + + /** + * The GraphQLObjectType where fieldDefinition is defined. + * Note: + * For the Introspection field __typename the returned object type doesn't actually contain the fieldDefinition. + * + * @return the GraphQLObjectType defining the {@link #getFieldDefinition()} + */ + public GraphQLObjectType getObjectType() { + return fieldContainer; + } + + /** + * This returns the type for the current step. + * + * @return the graphql type in question + */ + public GraphQLOutputType getType() { + return type; + } + + /** + * This returns the type which is unwrapped if it was {@link GraphQLNonNull} wrapped + * + * @return the graphql type in question + */ + public GraphQLOutputType getUnwrappedNonNullType() { + return (GraphQLOutputType) GraphQLTypeUtil.unwrapNonNull(this.type); + } + + /** + * This returns the type which is unwrapped if it was {@link GraphQLNonNull} wrapped + * and then cast to the target type. + * + * @param for two + * + * @return the graphql type in question + */ + public T getUnwrappedNonNullTypeAs() { + return GraphQLTypeUtil.unwrapNonNullAs(this.type); + } + + /** + * This returns the field definition that is in play when this type info was created or null + * if the type is a root query type + * + * @return the field definition or null if there is not one + */ + public GraphQLFieldDefinition getFieldDefinition() { + return fieldDefinition; + } + + /** + * This returns the AST fields that matches the {@link #getFieldDefinition()} during execution + * + * @return the merged fields + */ + public MergedField getField() { + return field; + } + + /** + * @return the {@link ResultPath} to this info + */ + public ResultPath getPath() { + return path; + } + + /** + * @return true if the type must be nonnull + */ + public boolean isNonNullType() { + return GraphQLTypeUtil.isNonNull(this.type); + } + + /** + * @return true if the type is a list + */ + public boolean isListType() { + return isList(type); + } + + /** + * @return the resolved arguments that have been passed to this field + */ + public Map getArguments() { + return arguments.get(); + } + + /** + * Returns the named argument + * + * @param name the name of the argument + * @param you decide what type it is + * + * @return the named argument or null if it's not present + */ + @SuppressWarnings("unchecked") + public T getArgument(String name) { + return (T) getArguments().get(name); + } + + /** + * @return the parent type information + */ + public ExecutionStepInfo getParent() { + return parent; + } + + /** + * @return true if the type has a parent (most do) + */ + public boolean hasParent() { + return parent != null; + } + + /** + * This allows you to morph a type into a more specialized form yet return the same + * parent and non-null ness, for example taking a {@link GraphQLInterfaceType} + * and turning it into a specific {@link graphql.schema.GraphQLObjectType} + * after type resolution has occurred + * + * @param newType the new type to be + * + * @return a new type info with the same + */ + public ExecutionStepInfo changeTypeWithPreservedNonNull(GraphQLOutputType newType) { + assertTrue(!GraphQLTypeUtil.isNonNull(newType), "newType can't be non null"); + if (isNonNullType()) { + return transform(GraphQLNonNull.nonNull(newType)); + } else { + return transform(newType); + } + } + + /** + * @return the type in graphql SDL format, eg [typeName!]! + */ + public String simplePrint() { + return GraphQLTypeUtil.simplePrint(type); + } + + @Override + public String toString() { + return "ExecutionStepInfo{" + + " path=" + path + + ", type=" + type + + ", fieldDefinition=" + fieldDefinition + + '}'; + } + + @Internal + ExecutionStepInfo transform(GraphQLOutputType type) { + return new ExecutionStepInfo(type, path, parent, field, fieldDefinition, fieldContainer, arguments); + } + + @Internal + ExecutionStepInfo transform(GraphQLOutputType type, ExecutionStepInfo parent, ResultPath path) { + return new ExecutionStepInfo(type, path, parent, field, fieldDefinition, fieldContainer, arguments); + } + + public ExecutionStepInfo transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public String getResultKey() { + return field.getResultKey(); + } + + /** + * @return a builder of type info + */ + public static ExecutionStepInfo.Builder newExecutionStepInfo() { + return new Builder(); + } + + public static ExecutionStepInfo.Builder newExecutionStepInfo(ExecutionStepInfo existing) { + return new Builder(existing); + } + + public static class Builder { + GraphQLOutputType type; + ExecutionStepInfo parentInfo; + GraphQLFieldDefinition fieldDefinition; + GraphQLObjectType fieldContainer; + MergedField field; + ResultPath path; + Supplier> arguments; + + /** + * @see ExecutionStepInfo#newExecutionStepInfo() + */ + private Builder() { + arguments = ImmutableMapWithNullValues::emptyMap; + } + + private Builder(ExecutionStepInfo existing) { + this.type = existing.type; + this.parentInfo = existing.parent; + this.fieldDefinition = existing.fieldDefinition; + this.fieldContainer = existing.fieldContainer; + this.field = existing.field; + this.path = existing.path; + this.arguments = existing.arguments; + } + + public Builder type(GraphQLOutputType type) { + this.type = type; + return this; + } + + public Builder parentInfo(ExecutionStepInfo executionStepInfo) { + this.parentInfo = executionStepInfo; + return this; + } + + public Builder fieldDefinition(GraphQLFieldDefinition fieldDefinition) { + this.fieldDefinition = fieldDefinition; + return this; + } + + public Builder field(MergedField field) { + this.field = field; + return this; + } + + public Builder path(ResultPath resultPath) { + this.path = resultPath; + return this; + } + + public Builder arguments(Supplier> arguments) { + this.arguments = arguments; + return this; + } + + public Builder fieldContainer(GraphQLObjectType fieldContainer) { + this.fieldContainer = fieldContainer; + return this; + } + + public ExecutionStepInfo build() { + return new ExecutionStepInfo(this); + } + } +} diff --git a/src/main/java/graphql/execution/ExecutionStepInfoFactory.java b/src/main/java/graphql/execution/ExecutionStepInfoFactory.java new file mode 100644 index 0000000000..286106a7dc --- /dev/null +++ b/src/main/java/graphql/execution/ExecutionStepInfoFactory.java @@ -0,0 +1,92 @@ +package graphql.execution; + +import graphql.Internal; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.language.Argument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.util.FpKit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import static graphql.execution.ExecutionStepInfo.newExecutionStepInfo; + +@Internal +@NullMarked +public class ExecutionStepInfoFactory { + + public ExecutionStepInfo newExecutionStepInfoForListElement(ExecutionStepInfo executionInfo, ResultPath indexedPath) { + GraphQLList fieldType = executionInfo.getUnwrappedNonNullTypeAs(); + GraphQLOutputType typeInList = (GraphQLOutputType) fieldType.getWrappedType(); + return executionInfo.transform(typeInList, executionInfo, indexedPath); + } + + /** + * Builds the type info hierarchy for the current field + * + * @param executionContext the execution context in play + * @param parameters contains the parameters holding the fields to be executed and source object + * @param fieldDefinition the field definition to build type info for + * @param fieldContainer the field container + * + * @return a new type info + */ + public ExecutionStepInfo createExecutionStepInfo(ExecutionContext executionContext, + ExecutionStrategyParameters parameters, + GraphQLFieldDefinition fieldDefinition, + @Nullable GraphQLObjectType fieldContainer) { + MergedField field = parameters.getField(); + ExecutionStepInfo parentStepInfo = parameters.getExecutionStepInfo(); + GraphQLOutputType fieldType = fieldDefinition.getType(); + List fieldArgDefs = fieldDefinition.getArguments(); + Supplier> argumentValues = ImmutableMapWithNullValues::emptyMap; + // + // no need to create args at all if there are none on the field def + // + if (!fieldArgDefs.isEmpty()) { + argumentValues = getArgumentValues(executionContext, fieldArgDefs, field.getArguments()); + } + + + return newExecutionStepInfo() + .type(fieldType) + .fieldDefinition(fieldDefinition) + .fieldContainer(fieldContainer) + .field(field) + .path(parameters.getPath()) + .parentInfo(parentStepInfo) + .arguments(argumentValues) + .build(); + } + + @NonNull + private static Supplier> getArgumentValues(ExecutionContext executionContext, + List fieldArgDefs, + List fieldArgs) { + Supplier> argumentValues; + GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry(); + Supplier> argValuesSupplier = () -> { + Map resolvedValues = ValuesResolver.getArgumentValues(codeRegistry, + fieldArgDefs, + fieldArgs, + executionContext.getCoercedVariables(), + executionContext.getGraphQLContext(), + executionContext.getLocale()); + + return ImmutableMapWithNullValues.copyOf(resolvedValues); + }; + argumentValues = FpKit.intraThreadMemoize(argValuesSupplier); + return argumentValues; + } + + +} diff --git a/src/main/java/graphql/execution/ExecutionStrategy.java b/src/main/java/graphql/execution/ExecutionStrategy.java index 27bb94e650..06d3b644b1 100644 --- a/src/main/java/graphql/execution/ExecutionStrategy.java +++ b/src/main/java/graphql/execution/ExecutionStrategy.java @@ -1,62 +1,75 @@ package graphql.execution; +import com.google.common.collect.ImmutableList; +import graphql.DuckTyped; +import graphql.EngineRunningState; import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.GraphQLError; +import graphql.Internal; import graphql.PublicSpi; import graphql.SerializationError; +import graphql.TrivialDataFetcher; import graphql.TypeMismatchError; -import graphql.TypeResolutionEnvironment; import graphql.UnresolvedTypeError; +import graphql.execution.directives.QueryDirectives; +import graphql.execution.directives.QueryDirectivesImpl; +import graphql.execution.incremental.DeferredExecutionSupport; +import graphql.execution.incremental.IncrementalExecutionContextKeys; +import graphql.execution.instrumentation.ExecuteObjectInstrumentationContext; +import graphql.execution.instrumentation.FieldFetchingInstrumentationContext; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationContext; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.execution.reactive.ReactiveSupport; +import graphql.extensions.ExtensionsBuilder; import graphql.introspection.Introspection; import graphql.language.Field; +import graphql.normalized.ExecutableNormalizedField; +import graphql.normalized.ExecutableNormalizedOperation; import graphql.schema.CoercingSerializeException; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingFieldSelectionSet; import graphql.schema.DataFetchingFieldSelectionSetImpl; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLEnumType; import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLInterfaceType; -import graphql.schema.GraphQLList; import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; import graphql.schema.GraphQLType; -import graphql.schema.GraphQLUnionType; -import graphql.schema.visibility.GraphqlFieldVisibility; +import graphql.schema.LightDataFetcher; import graphql.util.FpKit; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jspecify.annotations.NonNull; import java.util.ArrayList; -import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.OptionalDouble; import java.util.OptionalInt; -import java.util.OptionalLong; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; import static graphql.execution.Async.exceptionallyCompletedFuture; -import static graphql.execution.ExecutionTypeInfo.newTypeInfo; import static graphql.execution.FieldCollectorParameters.newParameters; import static graphql.execution.FieldValueInfo.CompleteValueType.ENUM; import static graphql.execution.FieldValueInfo.CompleteValueType.LIST; import static graphql.execution.FieldValueInfo.CompleteValueType.NULL; import static graphql.execution.FieldValueInfo.CompleteValueType.OBJECT; import static graphql.execution.FieldValueInfo.CompleteValueType.SCALAR; -import static graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment; +import static graphql.execution.ResultNodesInfo.MAX_RESULT_NODES; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.nonNullCtx; +import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment; +import static graphql.schema.GraphQLTypeUtil.isEnum; import static graphql.schema.GraphQLTypeUtil.isList; -import static java.util.concurrent.CompletableFuture.completedFuture; +import static graphql.schema.GraphQLTypeUtil.isScalar; /** * An execution strategy is give a list of fields from the graphql query to execute and find values for using a recursive strategy. @@ -89,7 +102,7 @@ *

* The execution of a field has two phases, first a raw object must be fetched for a field via a {@link DataFetcher} which * is defined on the {@link GraphQLFieldDefinition}. This object must then be 'completed' into a suitable value, either as a scalar/enum type via - * coercion or if its a complex object type by recursively calling the execution strategy for the lower level fields. + * coercion or if it's a complex object type by recursively calling the execution strategy for the lower level fields. *

* The first phase (data fetching) is handled by the method {@link #fetchField(ExecutionContext, ExecutionStrategyParameters)} *

@@ -97,7 +110,7 @@ * and the other "completeXXX" methods. *

* The order of fields fetching and completion is up to the execution strategy. As the graphql specification - * http://facebook.github.io/graphql/#sec-Normal-and-Serial-Execution says: + * https://spec.graphql.org/October2021/#sec-Normal-and-Serial-Execution says: *

* Normally the executor can execute the entries in a grouped field set in whatever order it chooses (often in parallel). Because * the resolution of fields other than top-level mutation fields must always be side effect-free and idempotent, the @@ -115,12 +128,11 @@ @SuppressWarnings("FutureReturnValueIgnored") public abstract class ExecutionStrategy { - private static final Logger log = LoggerFactory.getLogger(ExecutionStrategy.class); - - protected final ValuesResolver valuesResolver = new ValuesResolver(); protected final FieldCollector fieldCollector = new FieldCollector(); - + protected final ExecutionStepInfoFactory executionStepInfoFactory = new ExecutionStepInfoFactory(); protected final DataFetcherExceptionHandler dataFetcherExceptionHandler; + private final ResolveType resolvedType = new ResolveType(); + /** * The default execution strategy constructor uses the {@link SimpleDataFetcherExceptionHandler} @@ -130,6 +142,7 @@ protected ExecutionStrategy() { dataFetcherExceptionHandler = new SimpleDataFetcherExceptionHandler(); } + /** * The consumers of the execution strategy can pass in a {@link DataFetcherExceptionHandler} to better * decide what do when a data fetching error happens @@ -140,6 +153,23 @@ protected ExecutionStrategy(DataFetcherExceptionHandler dataFetcherExceptionHand this.dataFetcherExceptionHandler = dataFetcherExceptionHandler; } + + @Internal + public static String mkNameForPath(Field currentField) { + return mkNameForPath(Collections.singletonList(currentField)); + } + + @Internal + public static String mkNameForPath(MergedField mergedField) { + return mergedField.getResultKey(); + } + + @Internal + public static String mkNameForPath(List currentField) { + Field field = currentField.get(0); + return field.getResultKey(); + } + /** * This is the entry point to an execution strategy. It will be passed the fields to execute and get values for. * @@ -148,28 +178,165 @@ protected ExecutionStrategy(DataFetcherExceptionHandler dataFetcherExceptionHand * * @return a promise to an {@link ExecutionResult} * - * @throws NonNullableFieldWasNullException in the future if a non null field resolves to a null value + * @throws NonNullableFieldWasNullException in the future if a non-null field resolves to a null value */ public abstract CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException; /** - * Called to fetch a value for a field and resolve it further in terms of the graphql query. This will call - * #fetchField followed by #completeField and the completed {@link ExecutionResult} is returned. - *

- * An execution strategy can iterate the fields to be executed and call this method for each one - *

- * Graphql fragments mean that for any give logical field can have one or more {@link Field} values associated with it - * in the query, hence the fieldList. However the first entry is representative of the field for most purposes. + * This is the re-entry point for an execution strategy when an object type needs to be resolved. * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * - * @return a promise to an {@link ExecutionResult} + * @return a {@link CompletableFuture} promise to a map of object field values or a materialized map of object field values * - * @throws NonNullableFieldWasNullException in the future if a non null field resolves to a null value + * @throws NonNullableFieldWasNullException in the {@link CompletableFuture} if a non-null field resolved to a null value */ - protected CompletableFuture resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - return resolveFieldWithInfo(executionContext, parameters).thenCompose(FieldValueInfo::getFieldValue); + @SuppressWarnings("unchecked") + @DuckTyped(shape = "CompletableFuture> | Map") + protected Object executeObject(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { + executionContext.throwIfCancelled(); + + DataLoaderDispatchStrategy dataLoaderDispatcherStrategy = executionContext.getDataLoaderDispatcherStrategy(); + Instrumentation instrumentation = executionContext.getInstrumentation(); + InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters); + + ExecuteObjectInstrumentationContext resolveObjectCtx = ExecuteObjectInstrumentationContext.nonNullCtx( + instrumentation.beginExecuteObject(instrumentationParameters, executionContext.getInstrumentationState()) + ); + + List fieldNames = parameters.getFields().getKeys(); + + DeferredExecutionSupport deferredExecutionSupport = createDeferredExecutionSupport(executionContext, parameters); + List fieldsExecutedOnInitialResult = deferredExecutionSupport.getNonDeferredFieldNames(fieldNames); + dataLoaderDispatcherStrategy.executeObject(executionContext, parameters, fieldsExecutedOnInitialResult.size()); + Async.CombinedBuilder resolvedFieldFutures = getAsyncFieldValueInfo(executionContext, parameters, deferredExecutionSupport); + + CompletableFuture> overallResult = new CompletableFuture<>(); + BiConsumer, Throwable> handleResultsConsumer = buildFieldValueMap(fieldsExecutedOnInitialResult, overallResult, executionContext); + + resolveObjectCtx.onDispatched(); + + Object fieldValueInfosResult = resolvedFieldFutures.awaitPolymorphic(); + if (fieldValueInfosResult instanceof CompletableFuture) { + CompletableFuture> fieldValueInfos = (CompletableFuture>) fieldValueInfosResult; + fieldValueInfos.whenComplete((completeValueInfos, throwable) -> { + throwable = executionContext.possibleCancellation(throwable); + + if (throwable != null) { + handleResultsConsumer.accept(null, throwable); + return; + } + + Async.CombinedBuilder resultFutures = fieldValuesCombinedBuilder(completeValueInfos); + dataLoaderDispatcherStrategy.executeObjectOnFieldValuesInfo(completeValueInfos, parameters); + resolveObjectCtx.onFieldValuesInfo(completeValueInfos); + resultFutures.await().whenComplete(handleResultsConsumer); + }).exceptionally((ex) -> { + // if there are any issues with combining/handling the field results, + // complete the future at all costs and bubble up any thrown exception so + // the execution does not hang. + dataLoaderDispatcherStrategy.executeObjectOnFieldValuesException(ex, parameters); + resolveObjectCtx.onFieldValuesException(); + overallResult.completeExceptionally(ex); + return null; + }); + overallResult.whenComplete(resolveObjectCtx::onCompleted); + return overallResult; + } else { + List completeValueInfos = (List) fieldValueInfosResult; + + Async.CombinedBuilder resultFutures = fieldValuesCombinedBuilder(completeValueInfos); + dataLoaderDispatcherStrategy.executeObjectOnFieldValuesInfo(completeValueInfos, parameters); + resolveObjectCtx.onFieldValuesInfo(completeValueInfos); + + Object completedValuesObject = resultFutures.awaitPolymorphic(); + if (completedValuesObject instanceof CompletableFuture) { + CompletableFuture> completedValues = (CompletableFuture>) completedValuesObject; + completedValues.whenComplete(handleResultsConsumer); + overallResult.whenComplete(resolveObjectCtx::onCompleted); + return overallResult; + } else { + Map fieldValueMap = executionContext.getResponseMapFactory().createInsertionOrdered(fieldsExecutedOnInitialResult, (List) completedValuesObject); + resolveObjectCtx.onCompleted(fieldValueMap, null); + return fieldValueMap; + } + } + } + + private static Async.@NonNull CombinedBuilder fieldValuesCombinedBuilder(List completeValueInfos) { + Async.CombinedBuilder resultFutures = Async.ofExpectedSize(completeValueInfos.size()); + for (FieldValueInfo completeValueInfo : completeValueInfos) { + resultFutures.addObject(completeValueInfo.getFieldValueObject()); + } + return resultFutures; + } + + private BiConsumer, Throwable> buildFieldValueMap(List fieldNames, CompletableFuture> overallResult, ExecutionContext executionContext) { + return (List results, Throwable exception) -> { + exception = executionContext.possibleCancellation(exception); + + if (exception != null) { + handleValueException(overallResult, exception, executionContext); + return; + } + Map resolvedValuesByField = executionContext.getResponseMapFactory().createInsertionOrdered(fieldNames, results); + overallResult.complete(resolvedValuesByField); + }; + } + + DeferredExecutionSupport createDeferredExecutionSupport(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + MergedSelectionSet fields = parameters.getFields(); + + return executionContext.hasIncrementalSupport() ? + new DeferredExecutionSupport.DeferredExecutionSupportImpl( + fields, + parameters, + executionContext, + (ec, esp) -> Async.toCompletableFuture(resolveFieldWithInfo(ec, esp)), + this::createExecutionStepInfo + ) : DeferredExecutionSupport.NOOP; + + } + + Async.@NonNull CombinedBuilder getAsyncFieldValueInfo( + ExecutionContext executionContext, + ExecutionStrategyParameters parameters, + DeferredExecutionSupport deferredExecutionSupport + ) { + executionContext.throwIfCancelled(); + + MergedSelectionSet fields = parameters.getFields(); + + executionContext.getIncrementalCallState().enqueue(deferredExecutionSupport.createCalls()); + + // Only non-deferred fields should be considered for calculating the expected size of futures. + Async.CombinedBuilder futures = Async + .ofExpectedSize(fields.size() - deferredExecutionSupport.deferredFieldsCount()); + + for (String fieldName : fields.getKeys()) { + executionContext.throwIfCancelled(); + + MergedField currentField = fields.getSubField(fieldName); + + ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); + ExecutionStrategyParameters newParameters = parameters.transform(currentField, fieldPath, parameters); + + if (!deferredExecutionSupport.isDeferredField(currentField)) { + Object fieldValueInfo = resolveFieldWithInfo(executionContext, newParameters); + futures.addObject(fieldValueInfo); + } + + } + + if (executionContext.hasIncrementalSupport() + && deferredExecutionSupport.deferredFieldsCount() > 0 + && executionContext.getGraphQLContext().getBoolean(IncrementalExecutionContextKeys.ENABLE_EAGER_DEFER_START, false)) { + + executionContext.getIncrementalCallState().startDrainingNow(); + } + + return futures; } /** @@ -184,27 +351,45 @@ protected CompletableFuture resolveField(ExecutionContext execu * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * - * @return a promise to a {@link FieldValueInfo} + * @return a {@link CompletableFuture} promise to a {@link FieldValueInfo} or a materialised {@link FieldValueInfo} * - * @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValue()} future if a non null field resolves to a null value + * @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValueFuture()} future + * if a nonnull field resolves to a null value */ - protected CompletableFuture resolveFieldWithInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().get(0)); + @SuppressWarnings("unchecked") + @DuckTyped(shape = "CompletableFuture | FieldValueInfo") + protected Object resolveFieldWithInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); + Supplier executionStepInfo = FpKit.intraThreadMemoize(() -> createExecutionStepInfo(executionContext, parameters, fieldDef, null)); Instrumentation instrumentation = executionContext.getInstrumentation(); - InstrumentationContext fieldCtx = instrumentation.beginField( - new InstrumentationFieldParameters(executionContext, fieldDef, fieldTypeInfo(parameters, fieldDef)) - ); - - CompletableFuture fetchFieldFuture = fetchField(executionContext, parameters); - CompletableFuture result = fetchFieldFuture.thenApply((fetchedValue) -> - completeField(executionContext, parameters, fetchedValue)); - - CompletableFuture executionResultFuture = result.thenCompose(FieldValueInfo::getFieldValue); - - fieldCtx.onDispatched(executionResultFuture); - executionResultFuture.whenComplete(fieldCtx::onCompleted); - return result; + InstrumentationContext fieldCtx = nonNullCtx(instrumentation.beginFieldExecution( + new InstrumentationFieldParameters(executionContext, executionStepInfo), executionContext.getInstrumentationState() + )); + + Object fetchedValueObj = fetchField(executionContext, parameters); + if (fetchedValueObj instanceof CompletableFuture) { + CompletableFuture fetchFieldFuture = (CompletableFuture) fetchedValueObj; + CompletableFuture result = fetchFieldFuture.thenApply((fetchedValue) -> { + executionContext.getDataLoaderDispatcherStrategy().startComplete(parameters); + FieldValueInfo completeFieldResult = completeField(fieldDef, executionContext, parameters, fetchedValue); + executionContext.getDataLoaderDispatcherStrategy().stopComplete(parameters); + return completeFieldResult; + }); + + fieldCtx.onDispatched(); + result.whenComplete(fieldCtx::onCompleted); + return result; + } else { + try { + FieldValueInfo fieldValueInfo = completeField(fieldDef, executionContext, parameters, fetchedValueObj); + fieldCtx.onDispatched(); + fieldCtx.onCompleted(FetchedValue.getFetchedValue(fetchedValueObj), null); + return fieldValueInfo; + } catch (Exception e) { + return Async.exceptionallyCompletedFuture(e); + } + } } /** @@ -212,163 +397,272 @@ protected CompletableFuture resolveFieldWithInfo(ExecutionContex * {@link GraphQLFieldDefinition}. *

* Graphql fragments mean that for any give logical field can have one or more {@link Field} values associated with it - * in the query, hence the fieldList. However the first entry is representative of the field for most purposes. + * in the query, hence the fieldList. However, the first entry is representative of the field for most purposes. * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * - * @return a promise to a fetched object + * @return a promise to a value object or the value itself. The value maybe a raw object OR a {@link FetchedValue} * - * @throws NonNullableFieldWasNullException in the future if a non null field resolves to a null value + * @throws NonNullableFieldWasNullException in the future if a non-null field resolves to a null value */ - protected CompletableFuture fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - Field field = parameters.getField().get(0); - GraphQLObjectType parentType = parameters.getTypeInfo().castType(GraphQLObjectType.class); - GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field); + @DuckTyped(shape = "CompletableFuture | ") + protected Object fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + MergedField field = parameters.getField(); + GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs(); + GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getSingleField()); + return fetchField(fieldDef, executionContext, parameters); + } - GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility(); - Map argumentValues = valuesResolver.getArgumentValues(fieldVisibility, fieldDef.getArguments(), field.getArguments(), executionContext.getVariables()); - - GraphQLOutputType fieldType = fieldDef.getType(); - DataFetchingFieldSelectionSet fieldCollector = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, fieldType, parameters.getField()); - ExecutionTypeInfo fieldTypeInfo = fieldTypeInfo(parameters, fieldDef); - - DataFetchingEnvironment environment = newDataFetchingEnvironment(executionContext) - .source(parameters.getSource()) - .arguments(argumentValues) - .fieldDefinition(fieldDef) - .fields(parameters.getField()) - .fieldType(fieldType) - .fieldTypeInfo(fieldTypeInfo) - .parentType(parentType) - .selectionSet(fieldCollector) - .build(); + @DuckTyped(shape = "CompletableFuture | ") + private Object fetchField(GraphQLFieldDefinition fieldDef, ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + executionContext.throwIfCancelled(); + + if (incrementAndCheckMaxNodesExceeded(executionContext)) { + return null; + } + + MergedField field = parameters.getField(); + GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs(); + + // if the DF (like PropertyDataFetcher) does not use the arguments or execution step info then dont build any + + Supplier dataFetchingEnvironment = FpKit.intraThreadMemoize(() -> { + + Supplier executionStepInfo = FpKit.intraThreadMemoize( + () -> createExecutionStepInfo(executionContext, parameters, fieldDef, parentType)); + + Supplier> argumentValues = () -> executionStepInfo.get().getArguments(); + + Supplier normalizedFieldSupplier = getNormalizedField(executionContext, parameters, executionStepInfo); + + // DataFetchingFieldSelectionSet and QueryDirectives is a supplier of sorts - eg a lazy pattern + DataFetchingFieldSelectionSet fieldCollector = DataFetchingFieldSelectionSetImpl.newCollector(executionContext.getGraphQLSchema(), fieldDef.getType(), normalizedFieldSupplier); + QueryDirectives queryDirectives = new QueryDirectivesImpl(field, + executionContext.getGraphQLSchema(), + executionContext.getCoercedVariables(), + executionContext.getNormalizedVariables(), + executionContext.getGraphQLContext(), + executionContext.getLocale()); + + + return newDataFetchingEnvironment(executionContext) + .source(parameters.getSource()) + .localContext(parameters.getLocalContext()) + .arguments(argumentValues) + .fieldDefinition(fieldDef) + .mergedField(parameters.getField()) + .fieldType(fieldDef.getType()) + .executionStepInfo(executionStepInfo) + .parentType(parentType) + .selectionSet(fieldCollector) + .queryDirectives(queryDirectives) + .deferredCallContext(parameters.getDeferredCallContext()) + .level(parameters.getPath().getLevel()) + .build(); + }); + + GraphQLCodeRegistry codeRegistry = executionContext.getGraphQLSchema().getCodeRegistry(); + DataFetcher originalDataFetcher = codeRegistry.getDataFetcher(parentType, fieldDef); Instrumentation instrumentation = executionContext.getInstrumentation(); - InstrumentationFieldFetchParameters instrumentationFieldFetchParams = new InstrumentationFieldFetchParameters(executionContext, fieldDef, environment, parameters); - InstrumentationContext fetchCtx = instrumentation.beginFieldFetch(instrumentationFieldFetchParams); + InstrumentationFieldFetchParameters instrumentationFieldFetchParams = new InstrumentationFieldFetchParameters(executionContext, dataFetchingEnvironment, parameters, originalDataFetcher instanceof TrivialDataFetcher); + FieldFetchingInstrumentationContext fetchCtx = FieldFetchingInstrumentationContext.nonNullCtx(instrumentation.beginFieldFetching(instrumentationFieldFetchParams, + executionContext.getInstrumentationState()) + ); - CompletableFuture fetchedValue; - DataFetcher dataFetcher = fieldDef.getDataFetcher(); - dataFetcher = instrumentation.instrumentDataFetcher(dataFetcher, instrumentationFieldFetchParams); - ExecutionId executionId = executionContext.getExecutionId(); - try { - log.debug("'{}' fetching field '{}' using data fetcher '{}'...", executionId, fieldTypeInfo.getPath(), dataFetcher.getClass().getName()); - Object fetchedValueRaw = dataFetcher.get(environment); - log.debug("'{}' field '{}' fetch returned '{}'", executionId, fieldTypeInfo.getPath(), fetchedValueRaw == null ? "null" : fetchedValueRaw.getClass().getName()); + DataFetcher dataFetcher = instrumentation.instrumentDataFetcher(originalDataFetcher, instrumentationFieldFetchParams, executionContext.getInstrumentationState()); + Object fetchedObject = invokeDataFetcher(executionContext, parameters, fieldDef, dataFetchingEnvironment, originalDataFetcher, dataFetcher); + executionContext.getDataLoaderDispatcherStrategy().fieldFetched(executionContext, parameters, dataFetcher, fetchedObject, dataFetchingEnvironment); + fetchCtx.onDispatched(); + fetchCtx.onFetchedValue(fetchedObject); + // if it's a subscription, leave any reactive objects alone + if (!executionContext.isSubscriptionOperation()) { + // possible convert reactive objects into CompletableFutures + fetchedObject = ReactiveSupport.fetchedObject(fetchedObject); + } + if (fetchedObject instanceof CompletableFuture) { + @SuppressWarnings("unchecked") + CompletableFuture fetchedValue = (CompletableFuture) fetchedObject; + EngineRunningState engineRunningState = executionContext.getEngineRunningState(); + + CompletableFuture> handleCF = engineRunningState.handle(fetchedValue, (result, exception) -> { + // because we added an artificial CF, we need to unwrap the exception + fetchCtx.onCompleted(result, exception); + exception = engineRunningState.possibleCancellation(exception); + + if (exception != null) { + return handleFetchingException(dataFetchingEnvironment.get(), parameters, exception); + } else { + // we can simply return the fetched value CF and avoid a allocation + return fetchedValue; + } + }); + CompletableFuture rawResultCF = engineRunningState.compose(handleCF, Function.identity()); + return rawResultCF + .thenApply(result -> unboxPossibleDataFetcherResult(executionContext, parameters, result)); + } else { + fetchCtx.onCompleted(fetchedObject, null); + return unboxPossibleDataFetcherResult(executionContext, parameters, fetchedObject); + } + } - fetchedValue = Async.toCompletableFuture(fetchedValueRaw); + /* + * ExecutionContext is not used in the method, but the java agent uses it, so it needs to be present + */ + @SuppressWarnings("unused") + private Object invokeDataFetcher(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLFieldDefinition fieldDef, Supplier dataFetchingEnvironment, DataFetcher originalDataFetcher, DataFetcher dataFetcher) { + Object fetchedValue; + try { + Object fetchedValueRaw; + if (dataFetcher instanceof LightDataFetcher) { + fetchedValueRaw = ((LightDataFetcher) dataFetcher).get(fieldDef, parameters.getSource(), dataFetchingEnvironment); + } else { + fetchedValueRaw = dataFetcher.get(dataFetchingEnvironment.get()); + } + executionContext.getProfiler().fieldFetched(fetchedValueRaw, originalDataFetcher, dataFetcher, parameters.getPath(), fieldDef, parameters.getExecutionStepInfo().getType()); + fetchedValue = Async.toCompletableFutureOrMaterializedObject(fetchedValueRaw); } catch (Exception e) { - log.debug(String.format("'%s', field '%s' fetch threw exception", executionId, fieldTypeInfo.getPath()), e); - - fetchedValue = new CompletableFuture<>(); - fetchedValue.completeExceptionally(e); - } - fetchCtx.onDispatched(fetchedValue); - return fetchedValue - .handle((result, exception) -> { - fetchCtx.onCompleted(result, exception); - if (exception != null) { - handleFetchingException(executionContext, parameters, field, fieldDef, argumentValues, environment, exception); - return null; - } else { - return result; - } - }) - .thenApply(result -> unboxPossibleDataFetcherResult(executionContext, parameters, result)) - .thenApply(this::unboxPossibleOptional); - } - - Object unboxPossibleDataFetcherResult(ExecutionContext executionContext, - ExecutionStrategyParameters parameters, - Object result) { + fetchedValue = Async.exceptionallyCompletedFuture(e); + } + return fetchedValue; + } + + protected Supplier getNormalizedField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Supplier executionStepInfo) { + Supplier normalizedQuery = executionContext.getNormalizedQueryTree(); + return () -> normalizedQuery.get().getNormalizedField(parameters.getField(), executionStepInfo.get().getObjectType(), executionStepInfo.get().getPath()); + } + + /** + * If the data fetching returned a {@link DataFetcherResult} then it can contain errors and new local context + * and hence it gets turned into a {@link FetchedValue} but otherwise this method returns the unboxed + * value without the wrapper. This means its more efficient overall by default. + * + * @param executionContext the execution context in play + * @param parameters the parameters in play + * @param result the fetched raw object + * + * @return an unboxed value which can be a FetchedValue or an Object + */ + @DuckTyped(shape = "FetchedValue | Object") + protected Object unboxPossibleDataFetcherResult(ExecutionContext executionContext, + ExecutionStrategyParameters parameters, + Object result) { if (result instanceof DataFetcherResult) { - //noinspection unchecked - DataFetcherResult dataFetcherResult = (DataFetcherResult) result; - dataFetcherResult.getErrors().stream() - .map(relError -> new AbsoluteGraphQLError(parameters, relError)) - .forEach(executionContext::addError); - return dataFetcherResult.getData(); + DataFetcherResult dataFetcherResult = (DataFetcherResult) result; + + addErrorsToRightContext(dataFetcherResult.getErrors(), parameters, executionContext); + + addExtensionsIfPresent(executionContext, dataFetcherResult); + + Object localContext = dataFetcherResult.getLocalContext(); + if (localContext == null) { + // if the field returns nothing then they get the context of their parent field + localContext = parameters.getLocalContext(); + } + Object unBoxedValue = executionContext.getValueUnboxer().unbox(dataFetcherResult.getData()); + return new FetchedValue(unBoxedValue, dataFetcherResult.getErrors(), localContext); } else { - return result; + return executionContext.getValueUnboxer().unbox(result); + } + } + + private void addExtensionsIfPresent(ExecutionContext executionContext, DataFetcherResult dataFetcherResult) { + Map extensions = dataFetcherResult.getExtensions(); + if (extensions != null) { + ExtensionsBuilder extensionsBuilder = executionContext.getGraphQLContext().get(ExtensionsBuilder.class); + if (extensionsBuilder != null) { + extensionsBuilder.addValues(extensions); + } } } - private void handleFetchingException(ExecutionContext executionContext, - ExecutionStrategyParameters parameters, - Field field, - GraphQLFieldDefinition fieldDef, - Map argumentValues, - DataFetchingEnvironment environment, - Throwable e) { + protected CompletableFuture handleFetchingException( + DataFetchingEnvironment environment, + ExecutionStrategyParameters parameters, + Throwable e + ) { DataFetcherExceptionHandlerParameters handlerParameters = DataFetcherExceptionHandlerParameters.newExceptionParameters() - .executionContext(executionContext) .dataFetchingEnvironment(environment) - .argumentValues(argumentValues) - .field(field) - .fieldDefinition(fieldDef) - .path(parameters.getPath()) .exception(e) .build(); - dataFetcherExceptionHandler.accept(handlerParameters); + try { + return asyncHandleException(dataFetcherExceptionHandler, handlerParameters); + } catch (Exception handlerException) { + handlerParameters = DataFetcherExceptionHandlerParameters.newExceptionParameters() + .dataFetchingEnvironment(environment) + .exception(handlerException) + .build(); + return asyncHandleException(new SimpleDataFetcherExceptionHandler(), handlerParameters); + } + } - parameters.deferredErrorSupport().onFetchingException(parameters, e); + private CompletableFuture asyncHandleException(DataFetcherExceptionHandler handler, DataFetcherExceptionHandlerParameters handlerParameters) { + //noinspection unchecked + return handler.handleException(handlerParameters).thenApply( + handlerResult -> (T) DataFetcherResult.newResult().errors(handlerResult.getErrors()).build() + ); } /** * Called to complete a field based on the type of the field. *

- * If the field is a scalar type, then it will be coerced and returned. However if the field type is an complex object type, then + * If the field is a scalar type, then it will be coerced and returned. However, if the field type is an complex object type, then * the execution strategy will be called recursively again to execute the fields of that type before returning. *

* Graphql fragments mean that for any give logical field can have one or more {@link Field} values associated with it - * in the query, hence the fieldList. However the first entry is representative of the field for most purposes. + * in the query, hence the fieldList. However, the first entry is representative of the field for most purposes. * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object - * @param fetchedValue the fetched raw value + * @param fetchedValue the fetched raw value or perhaps a {@link FetchedValue} wrapper of that value * * @return a {@link FieldValueInfo} * - * @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValue()} future if a non null field resolves to a null value + * @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValueFuture()} future + * if a nonnull field resolves to a null value */ - protected FieldValueInfo completeField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object fetchedValue) { - Field field = parameters.getField().get(0); - GraphQLObjectType parentType = parameters.getTypeInfo().castType(GraphQLObjectType.class); + protected FieldValueInfo completeField(ExecutionContext executionContext, + ExecutionStrategyParameters parameters, + @DuckTyped(shape = "Object | FetchedValue") + Object fetchedValue) { + executionContext.throwIfCancelled(); + + Field field = parameters.getField().getSingleField(); + GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field); - ExecutionTypeInfo fieldTypeInfo = fieldTypeInfo(parameters, fieldDef); - - Instrumentation instrumentation = executionContext.getInstrumentation(); - InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, fieldDef, fieldTypeInfo, fetchedValue); - InstrumentationContext ctxCompleteField = instrumentation.beginFieldComplete( - instrumentationParams - ); - - GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility(); - Map argumentValues = valuesResolver.getArgumentValues(fieldVisibility, fieldDef.getArguments(), field.getArguments(), executionContext.getVariables()); + return completeField(fieldDef, executionContext, parameters, fetchedValue); + } - NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, fieldTypeInfo); + private FieldValueInfo completeField(GraphQLFieldDefinition fieldDef, ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object fetchedValue) { + GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs(); + ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType); - ExecutionStrategyParameters newParameters = parameters.transform(builder -> - builder.typeInfo(fieldTypeInfo) - .arguments(argumentValues) - .source(fetchedValue) - .nonNullFieldValidator(nonNullableFieldValidator) + Instrumentation instrumentation = executionContext.getInstrumentation(); + InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, () -> executionStepInfo, fetchedValue); + InstrumentationContext ctxCompleteField = nonNullCtx(instrumentation.beginFieldCompletion( + instrumentationParams, executionContext.getInstrumentationState() + )); + + ExecutionStrategyParameters newParameters = parameters.transform( + executionStepInfo, + FetchedValue.getLocalContext(fetchedValue, parameters.getLocalContext()), + FetchedValue.getFetchedValue(fetchedValue) ); - log.debug("'{}' completing field '{}'...", executionContext.getExecutionId(), fieldTypeInfo.getPath()); - FieldValueInfo fieldValueInfo = completeValue(executionContext, newParameters); - - CompletableFuture executionResultFuture = fieldValueInfo.getFieldValue(); - ctxCompleteField.onDispatched(executionResultFuture); - executionResultFuture.whenComplete(ctxCompleteField::onCompleted); + ctxCompleteField.onDispatched(); + if (fieldValueInfo.isFutureValue()) { + CompletableFuture executionResultFuture = fieldValueInfo.getFieldValueFuture(); + executionResultFuture.whenComplete(ctxCompleteField::onCompleted); + } else { + ctxCompleteField.onCompleted(fieldValueInfo.getFieldValueObject(), null); + } return fieldValueInfo; } - /** * Called to complete a value for a field based on the type of the field. *

@@ -386,22 +680,21 @@ protected FieldValueInfo completeField(ExecutionContext executionContext, Execut * @throws NonNullableFieldWasNullException if a non null field resolves to a null value */ protected FieldValueInfo completeValue(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { - ExecutionTypeInfo typeInfo = parameters.getTypeInfo(); - Object result = unboxPossibleOptional(parameters.getSource()); - GraphQLType fieldType = typeInfo.getType(); - CompletableFuture fieldValue; + ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); + Object result = executionContext.getValueUnboxer().unbox(parameters.getSource()); + GraphQLType fieldType = executionStepInfo.getUnwrappedNonNullType(); + Object fieldValue; if (result == null) { - fieldValue = completeValueForNull(parameters); - return FieldValueInfo.newFieldValueInfo(NULL).fieldValue(fieldValue).build(); + return getFieldValueInfoForNull(parameters); } else if (isList(fieldType)) { return completeValueForList(executionContext, parameters, result); - } else if (fieldType instanceof GraphQLScalarType) { + } else if (isScalar(fieldType)) { fieldValue = completeValueForScalar(executionContext, parameters, (GraphQLScalarType) fieldType, result); - return FieldValueInfo.newFieldValueInfo(SCALAR).fieldValue(fieldValue).build(); - } else if (fieldType instanceof GraphQLEnumType) { + return new FieldValueInfo(SCALAR, fieldValue); + } else if (isEnum(fieldType)) { fieldValue = completeValueForEnum(executionContext, parameters, (GraphQLEnumType) fieldType, result); - return FieldValueInfo.newFieldValueInfo(ENUM).fieldValue(fieldValue).build(); + return new FieldValueInfo(ENUM, fieldValue); } // when we are here, we have a complex type: Interface, Union or Object @@ -414,27 +707,48 @@ protected FieldValueInfo completeValue(ExecutionContext executionContext, Execut } catch (UnresolvedTypeException ex) { // consider the result to be null and add the error on the context handleUnresolvedTypeProblem(executionContext, parameters, ex); - // and validate the field is nullable, if non-nullable throw exception - parameters.getNonNullFieldValidator().validate(parameters.getPath(), null); - // complete the field as null - fieldValue = completedFuture(new ExecutionResultImpl(null, null)); + // complete field as null, validating it is nullable + return getFieldValueInfoForNull(parameters); } - return FieldValueInfo.newFieldValueInfo(OBJECT).fieldValue(fieldValue).build(); + return new FieldValueInfo(OBJECT, fieldValue); } private void handleUnresolvedTypeProblem(ExecutionContext context, ExecutionStrategyParameters parameters, UnresolvedTypeException e) { - UnresolvedTypeError error = new UnresolvedTypeError(parameters.getPath(), parameters.getTypeInfo(), e); - log.warn(error.getMessage(), e); - context.addError(error); + UnresolvedTypeError error = new UnresolvedTypeError(parameters.getPath(), parameters.getExecutionStepInfo(), e); - parameters.deferredErrorSupport().onError(error); + addErrorToRightContext(error, parameters, context); } - private CompletableFuture completeValueForNull(ExecutionStrategyParameters parameters) { - return Async.tryCatch(() -> { - Object nullValue = parameters.getNonNullFieldValidator().validate(parameters.getPath(), null); - return completedFuture(new ExecutionResultImpl(nullValue, null)); - }); + /** + * Called to complete a null value. + * + * @param parameters contains the parameters holding the fields to be executed and source object + * + * @return a {@link FieldValueInfo} + * + * @throws NonNullableFieldWasNullException inside a {@link CompletableFuture} if a non null field resolves to a null value + */ + private FieldValueInfo getFieldValueInfoForNull(ExecutionStrategyParameters parameters) { + Object fieldValue = completeValueForNull(parameters); + return new FieldValueInfo(NULL, fieldValue); + } + + /** + * Called to complete a null value. + * + * @param parameters contains the parameters holding the fields to be executed and source object + * + * @return a null value or a {@link CompletableFuture} exceptionally completed + * + * @throws NonNullableFieldWasNullException inside the {@link CompletableFuture} if a non-null field resolves to a null value + */ + @DuckTyped(shape = "CompletableFuture | Object") + protected Object completeValueForNull(ExecutionStrategyParameters parameters) { + try { + return parameters.getNonNullFieldValidator().validate(parameters, null); + } catch (Exception e) { + return Async.exceptionallyCompletedFuture(e); + } } /** @@ -450,12 +764,12 @@ private CompletableFuture completeValueForNull(ExecutionStrateg protected FieldValueInfo completeValueForList(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object result) { Iterable resultIterable = toIterable(executionContext, parameters, result); try { - resultIterable = parameters.getNonNullFieldValidator().validate(parameters.getPath(), resultIterable); + resultIterable = parameters.getNonNullFieldValidator().validate(parameters, resultIterable); } catch (NonNullableFieldWasNullException e) { - return FieldValueInfo.newFieldValueInfo(LIST).fieldValue(exceptionallyCompletedFuture(e)).build(); + return new FieldValueInfo(LIST, exceptionallyCompletedFuture(e)); } if (resultIterable == null) { - return FieldValueInfo.newFieldValueInfo(LIST).fieldValue(completedFuture(new ExecutionResultImpl(null, null))).build(); + return new FieldValueInfo(LIST, null); } return completeValueForList(executionContext, parameters, resultIterable); } @@ -472,71 +786,90 @@ protected FieldValueInfo completeValueForList(ExecutionContext executionContext, */ protected FieldValueInfo completeValueForList(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Iterable iterableValues) { - Collection values = FpKit.toCollection(iterableValues); - ExecutionTypeInfo typeInfo = parameters.getTypeInfo(); - GraphQLList fieldType = typeInfo.castType(GraphQLList.class); - GraphQLFieldDefinition fieldDef = parameters.getTypeInfo().getFieldDefinition(); + OptionalInt size = FpKit.toSize(iterableValues); + ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); - InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, fieldDef, fieldTypeInfo(parameters, fieldDef), values); + InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, () -> executionStepInfo, iterableValues); Instrumentation instrumentation = executionContext.getInstrumentation(); - InstrumentationContext completeListCtx = instrumentation.beginFieldListComplete( - instrumentationParams - ); + InstrumentationContext completeListCtx = nonNullCtx(instrumentation.beginFieldListCompletion( + instrumentationParams, executionContext.getInstrumentationState() + )); - List fieldValueInfos = new ArrayList<>(); + List fieldValueInfos = new ArrayList<>(size.orElse(1)); int index = 0; - for (Object item : values) { - ExecutionPath indexedPath = parameters.getPath().segment(index); + for (Object item : iterableValues) { + if (incrementAndCheckMaxNodesExceeded(executionContext)) { + return new FieldValueInfo(NULL, null, fieldValueInfos); + } - ExecutionTypeInfo wrappedTypeInfo = ExecutionTypeInfo.newTypeInfo() - .parentInfo(typeInfo) - .type(fieldType.getWrappedType()) - .path(indexedPath) - .fieldDefinition(fieldDef) - .build(); + ResultPath indexedPath = parameters.getPath().segment(index); + + ExecutionStepInfo stepInfoForListElement = executionStepInfoFactory.newExecutionStepInfoForListElement(executionStepInfo, indexedPath); - NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, wrappedTypeInfo); + Object fetchedValue = unboxPossibleDataFetcherResult(executionContext, parameters, item); - int finalIndex = index; - ExecutionStrategyParameters newParameters = parameters.transform(builder -> - builder.typeInfo(wrappedTypeInfo) - .nonNullFieldValidator(nonNullableFieldValidator) - .listSize(values.size()) - .currentListIndex(finalIndex) - .path(indexedPath) - .source(item) + ExecutionStrategyParameters newParameters = parameters.transform( + stepInfoForListElement, + indexedPath, + FetchedValue.getLocalContext(fetchedValue, parameters.getLocalContext()), + FetchedValue.getFetchedValue(fetchedValue) ); + fieldValueInfos.add(completeValue(executionContext, newParameters)); index++; } - CompletableFuture> resultsFuture = Async.each(fieldValueInfos, (item, i) -> item.getFieldValue()); - - CompletableFuture overallResult = new CompletableFuture<>(); - completeListCtx.onDispatched(overallResult); + Object listResults = Async.eachPolymorphic(fieldValueInfos, FieldValueInfo::getFieldValueObject); + Object listOrPromiseToList; + if (listResults instanceof CompletableFuture) { + @SuppressWarnings("unchecked") + CompletableFuture> resultsFuture = (CompletableFuture>) listResults; + CompletableFuture overallResult = new CompletableFuture<>(); + completeListCtx.onDispatched(); + overallResult.whenComplete(completeListCtx::onCompleted); + + resultsFuture.whenComplete((results, exception) -> { + exception = executionContext.possibleCancellation(exception); + + if (exception != null) { + handleValueException(overallResult, exception, executionContext); + return; + } + List completedResults = new ArrayList<>(results.size()); + completedResults.addAll(results); + overallResult.complete(completedResults); + }); + listOrPromiseToList = overallResult; + } else { + completeListCtx.onCompleted(listResults, null); + listOrPromiseToList = listResults; + } + return new FieldValueInfo(LIST, listOrPromiseToList, fieldValueInfos); + } - resultsFuture.whenComplete((results, exception) -> { - if (exception != null) { - ExecutionResult executionResult = handleNonNullException(executionContext, overallResult, exception); - completeListCtx.onCompleted(executionResult, exception); - return; + protected void handleValueException(CompletableFuture overallResult, Throwable e, ExecutionContext executionContext) { + Throwable underlyingException = e; + if (e instanceof CompletionException) { + underlyingException = e.getCause(); + } + if (underlyingException instanceof NonNullableFieldWasNullException) { + assertNonNullFieldPrecondition((NonNullableFieldWasNullException) underlyingException, overallResult); + if (!overallResult.isDone()) { + overallResult.complete(null); } - List completedResults = new ArrayList<>(); - for (ExecutionResult completedValue : results) { - completedResults.add(completedValue.getData()); + } else if (underlyingException instanceof AbortExecutionException) { + AbortExecutionException abortException = (AbortExecutionException) underlyingException; + executionContext.addError(abortException); + if (!overallResult.isDone()) { + overallResult.complete(null); } - ExecutionResultImpl executionResult = new ExecutionResultImpl(completedResults, null); - overallResult.complete(executionResult); - }); - overallResult.whenComplete(completeListCtx::onCompleted); - - return FieldValueInfo.newFieldValueInfo(LIST) - .fieldValue(overallResult) - .fieldValueInfos(fieldValueInfos) - .build(); + } else { + overallResult.completeExceptionally(e); + } } + /** * Called to turn an object into a scalar value according to the {@link GraphQLScalarType} by asking that scalar type to coerce the object * into a valid value @@ -546,249 +879,141 @@ protected FieldValueInfo completeValueForList(ExecutionContext executionContext, * @param scalarType the type of the scalar * @param result the result to be coerced * - * @return a promise to an {@link ExecutionResult} + * @return a materialized scalar value or exceptionally completed {@link CompletableFuture} if there is a problem */ - protected CompletableFuture completeValueForScalar(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLScalarType scalarType, Object result) { + @DuckTyped(shape = "CompletableFuture | Object") + protected Object completeValueForScalar(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLScalarType scalarType, Object result) { Object serialized; try { - serialized = scalarType.getCoercing().serialize(result); + serialized = scalarType.getCoercing().serialize(result, executionContext.getGraphQLContext(), executionContext.getLocale()); } catch (CoercingSerializeException e) { serialized = handleCoercionProblem(executionContext, parameters, e); } - // TODO: fix that: this should not be handled here - //6.6.1 http://facebook.github.io/graphql/#sec-Field-entries - if (serialized instanceof Double && ((Double) serialized).isNaN()) { - serialized = null; - } try { - serialized = parameters.getNonNullFieldValidator().validate(parameters.getPath(), serialized); + serialized = parameters.getNonNullFieldValidator().validate(parameters, serialized); } catch (NonNullableFieldWasNullException e) { return exceptionallyCompletedFuture(e); } - return completedFuture(new ExecutionResultImpl(serialized, null)); + return serialized; } /** - * Called to turn an object into a enum value according to the {@link GraphQLEnumType} by asking that enum type to coerce the object into a valid value + * Called to turn an object into an enum value according to the {@link GraphQLEnumType} by asking that enum type to coerce the object into a valid value * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param enumType the type of the enum * @param result the result to be coerced * - * @return a promise to an {@link ExecutionResult} + * @return a materialized enum value or exceptionally completed {@link CompletableFuture} if there is a problem */ - protected CompletableFuture completeValueForEnum(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLEnumType enumType, Object result) { + @DuckTyped(shape = "CompletableFuture | Object") + protected Object completeValueForEnum(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLEnumType enumType, Object result) { Object serialized; try { - serialized = enumType.getCoercing().serialize(result); + serialized = enumType.serialize(result, executionContext.getGraphQLContext(), executionContext.getLocale()); } catch (CoercingSerializeException e) { serialized = handleCoercionProblem(executionContext, parameters, e); } try { - serialized = parameters.getNonNullFieldValidator().validate(parameters.getPath(), serialized); + serialized = parameters.getNonNullFieldValidator().validate(parameters, serialized); } catch (NonNullableFieldWasNullException e) { return exceptionallyCompletedFuture(e); } - return completedFuture(new ExecutionResultImpl(serialized, null)); + return serialized; } /** - * Called to turn an java object value into an graphql object value + * Called to turn a java object value into an graphql object value * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param resolvedObjectType the resolved object type * @param result the result to be coerced * - * @return a promise to an {@link ExecutionResult} + * @return a {@link CompletableFuture} promise to a map of object field values or a materialized map of object field values */ - protected CompletableFuture completeValueForObject(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLObjectType resolvedObjectType, Object result) { - ExecutionTypeInfo typeInfo = parameters.getTypeInfo(); + @DuckTyped(shape = "CompletableFuture> | Map") + protected Object completeValueForObject(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLObjectType resolvedObjectType, Object result) { + ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); FieldCollectorParameters collectorParameters = newParameters() .schema(executionContext.getGraphQLSchema()) .objectType(resolvedObjectType) .fragments(executionContext.getFragmentsByName()) - .variables(executionContext.getVariables()) + .variables(executionContext.getCoercedVariables().toMap()) + .graphQLContext(executionContext.getGraphQLContext()) .build(); - Map> subFields = fieldCollector.collectFields(collectorParameters, parameters.getField()); + MergedSelectionSet subFields = fieldCollector.collectFields( + collectorParameters, + parameters.getField(), + executionContext.hasIncrementalSupport() + ); - ExecutionTypeInfo newTypeInfo = typeInfo.treatAs(resolvedObjectType); - NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, newTypeInfo); + ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedObjectType); - ExecutionStrategyParameters newParameters = parameters.transform(builder -> - builder.typeInfo(newTypeInfo) - .fields(subFields) - .nonNullFieldValidator(nonNullableFieldValidator) - .source(result) - ); + ExecutionStrategyParameters newParameters = parameters.transform(newExecutionStepInfo, + subFields, + result); // Calling this from the executionContext to ensure we shift back from mutation strategy to the query strategy. - - return executionContext.getQueryStrategy().execute(executionContext, newParameters); + return executionContext.getQueryStrategy().executeObject(executionContext, newParameters); } @SuppressWarnings("SameReturnValue") private Object handleCoercionProblem(ExecutionContext context, ExecutionStrategyParameters parameters, CoercingSerializeException e) { SerializationError error = new SerializationError(parameters.getPath(), e); - log.warn(error.getMessage(), e); - context.addError(error); - parameters.deferredErrorSupport().onError(error); + addErrorToRightContext(error, parameters, context); return null; } - /** - * We treat Optional objects as "boxed" values where an empty Optional - * equals a null object and a present Optional is the underlying value. - * - * @param result the incoming value - * - * @return an un-boxed result - */ - protected Object unboxPossibleOptional(Object result) { - if (result instanceof Optional) { - Optional optional = (Optional) result; - if (optional.isPresent()) { - return optional.get(); - } else { - return null; - } - } else if (result instanceof OptionalInt) { - OptionalInt optional = (OptionalInt) result; - if (optional.isPresent()) { - return optional.getAsInt(); - } else { - return null; - } - } else if (result instanceof OptionalDouble) { - OptionalDouble optional = (OptionalDouble) result; - if (optional.isPresent()) { - return optional.getAsDouble(); - } else { - return null; - } - } else if (result instanceof OptionalLong) { - OptionalLong optional = (OptionalLong) result; - if (optional.isPresent()) { - return optional.getAsLong(); - } else { - return null; - } + protected GraphQLObjectType resolveType(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLType fieldType) { + // we can avoid a method call and type resolver environment allocation if we know it's an object type + if (fieldType instanceof GraphQLObjectType) { + return (GraphQLObjectType) fieldType; } - - return result; + return resolvedType.resolveType(executionContext, parameters.getField(), parameters.getSource(), parameters.getExecutionStepInfo(), fieldType, parameters.getLocalContext()); } - /** - * Converts an object that is known to should be an Iterable into one - * - * @param result the result object - * - * @return an Iterable from that object - * - * @throws java.lang.ClassCastException if its not an Iterable - */ - @SuppressWarnings("unchecked") - protected Iterable toIterable(Object result) { - return FpKit.toCollection(result); - } - - protected GraphQLObjectType resolveType(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLType fieldType) { - GraphQLObjectType resolvedType; - if (fieldType instanceof GraphQLInterfaceType) { - TypeResolutionParameters resolutionParams = TypeResolutionParameters.newParameters() - .graphQLInterfaceType((GraphQLInterfaceType) fieldType) - .field(parameters.getField().get(0)) - .value(parameters.getSource()) - .argumentValues(parameters.getArguments()) - .context(executionContext.getContext()) - .schema(executionContext.getGraphQLSchema()).build(); - resolvedType = resolveTypeForInterface(resolutionParams); - - } else if (fieldType instanceof GraphQLUnionType) { - TypeResolutionParameters resolutionParams = TypeResolutionParameters.newParameters() - .graphQLUnionType((GraphQLUnionType) fieldType) - .field(parameters.getField().get(0)) - .value(parameters.getSource()) - .argumentValues(parameters.getArguments()) - .context(executionContext.getContext()) - .schema(executionContext.getGraphQLSchema()).build(); - resolvedType = resolveTypeForUnion(resolutionParams); - } else { - resolvedType = (GraphQLObjectType) fieldType; + protected Iterable toIterable(ExecutionContext context, ExecutionStrategyParameters parameters, Object result) { + if (FpKit.isIterable(result)) { + return FpKit.toIterable(result); } - return resolvedType; + handleTypeMismatchProblem(context, parameters); + return null; } - /** - * Called to resolve a {@link GraphQLInterfaceType} into a specific {@link GraphQLObjectType} so the object can be executed in terms of that type - * - * @param params the params needed for type resolution - * - * @return a {@link GraphQLObjectType} - */ - protected GraphQLObjectType resolveTypeForInterface(TypeResolutionParameters params) { - TypeResolutionEnvironment env = new TypeResolutionEnvironment(params.getValue(), params.getArgumentValues(), params.getField(), params.getGraphQLInterfaceType(), params.getSchema(), params.getContext()); - GraphQLInterfaceType abstractType = params.getGraphQLInterfaceType(); - GraphQLObjectType result = abstractType.getTypeResolver().getType(env); - if (result == null) { - throw new UnresolvedTypeException(abstractType); - } + private void handleTypeMismatchProblem(ExecutionContext context, ExecutionStrategyParameters parameters) { + TypeMismatchError error = new TypeMismatchError(parameters.getPath(), parameters.getExecutionStepInfo().getUnwrappedNonNullType()); - if (!params.getSchema().isPossibleType(abstractType, result)) { - throw new UnresolvedTypeException(abstractType, result); - } - - return result; + addErrorToRightContext(error, parameters, context); } /** - * Called to resolve a {@link GraphQLUnionType} into a specific {@link GraphQLObjectType} so the object can be executed in terms of that type + * This has a side effect of incrementing the number of nodes returned and also checks + * if max nodes were exceeded for this request. * - * @param params the params needed for type resolution + * @param executionContext the execution context in play * - * @return a {@link GraphQLObjectType} + * @return true if max nodes were exceeded */ - protected GraphQLObjectType resolveTypeForUnion(TypeResolutionParameters params) { - TypeResolutionEnvironment env = new TypeResolutionEnvironment(params.getValue(), params.getArgumentValues(), params.getField(), params.getGraphQLUnionType(), params.getSchema(), params.getContext()); - GraphQLUnionType abstractType = params.getGraphQLUnionType(); - GraphQLObjectType result = abstractType.getTypeResolver().getType(env); - if (result == null) { - throw new UnresolvedTypeException(abstractType); - } - - if (!params.getSchema().isPossibleType(abstractType, result)) { - throw new UnresolvedTypeException(abstractType, result); - } - - return result; - } - - - protected Iterable toIterable(ExecutionContext context, ExecutionStrategyParameters parameters, Object result) { - if (result.getClass().isArray() || result instanceof Iterable) { - return toIterable(result); + private boolean incrementAndCheckMaxNodesExceeded(ExecutionContext executionContext) { + int resultNodesCount = executionContext.getResultNodesInfo().incrementAndGetResultNodesCount(); + Integer maxNodes; + if ((maxNodes = executionContext.getGraphQLContext().get(MAX_RESULT_NODES)) != null) { + if (resultNodesCount > maxNodes) { + executionContext.getResultNodesInfo().maxResultNodesExceeded(); + return true; + } } - - handleTypeMismatchProblem(context, parameters, result); - return null; - } - - private void handleTypeMismatchProblem(ExecutionContext context, ExecutionStrategyParameters parameters, Object result) { - TypeMismatchError error = new TypeMismatchError(parameters.getPath(), parameters.getTypeInfo().getType()); - log.warn("{} got {}", error.getMessage(), result.getClass()); - context.addError(error); - - parameters.deferredErrorSupport().onError(error); + return false; } - /** * Called to discover the field definition give the current parameters and the AST {@link Field} * @@ -799,7 +1024,7 @@ private void handleTypeMismatchProblem(ExecutionContext context, ExecutionStrate * @return a {@link GraphQLFieldDefinition} */ protected GraphQLFieldDefinition getFieldDef(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Field field) { - GraphQLObjectType parentType = parameters.getTypeInfo().castType(GraphQLObjectType.class); + GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs(); return getFieldDef(executionContext.getGraphQLSchema(), parentType, field); } @@ -813,11 +1038,11 @@ protected GraphQLFieldDefinition getFieldDef(ExecutionContext executionContext, * @return a {@link GraphQLFieldDefinition} */ protected GraphQLFieldDefinition getFieldDef(GraphQLSchema schema, GraphQLObjectType parentType, Field field) { - return Introspection.getFieldDef(schema, parentType, field.getName()); + return Introspection.getFieldDefinition(schema, parentType, field.getName()); } /** - * See (http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability), + * See (...), *

* If a non nullable child field type actually resolves to a null value and the parent type is nullable * then the parent must in fact become null @@ -831,22 +1056,22 @@ protected GraphQLFieldDefinition getFieldDef(GraphQLSchema schema, GraphQLObject * @throws NonNullableFieldWasNullException if a non null field resolves to a null value */ protected void assertNonNullFieldPrecondition(NonNullableFieldWasNullException e) throws NonNullableFieldWasNullException { - ExecutionTypeInfo typeInfo = e.getTypeInfo(); - if (typeInfo.hasParentType() && typeInfo.getParentTypeInfo().isNonNullType()) { + ExecutionStepInfo executionStepInfo = e.getExecutionStepInfo(); + if (executionStepInfo.hasParent() && executionStepInfo.getParent().isNonNullType()) { throw new NonNullableFieldWasNullException(e); } } protected void assertNonNullFieldPrecondition(NonNullableFieldWasNullException e, CompletableFuture completableFuture) throws NonNullableFieldWasNullException { - ExecutionTypeInfo typeInfo = e.getTypeInfo(); - if (typeInfo.hasParentType() && typeInfo.getParentTypeInfo().isNonNullType()) { + ExecutionStepInfo executionStepInfo = e.getExecutionStepInfo(); + if (executionStepInfo.hasParent() && executionStepInfo.getParent().isNonNullType()) { completableFuture.completeExceptionally(new NonNullableFieldWasNullException(e)); } } protected ExecutionResult handleNonNullException(ExecutionContext executionContext, CompletableFuture result, Throwable e) { ExecutionResult executionResult = null; - List errors = new ArrayList<>(executionContext.getErrors()); + List errors = ImmutableList.copyOf(executionContext.getErrors()); Throwable underlyingException = e; if (e instanceof CompletionException) { underlyingException = e.getCause(); @@ -867,23 +1092,45 @@ protected ExecutionResult handleNonNullException(ExecutionContext executionConte return executionResult; } - /** * Builds the type info hierarchy for the current field * - * @param parameters contains the parameters holding the fields to be executed and source object - * @param fieldDefinition the field definition to build type info for + * @param executionContext the execution context in play + * @param parameters contains the parameters holding the fields to be executed and source object + * @param fieldDefinition the field definition to build type info for + * @param fieldContainer the field container * * @return a new type info */ - protected ExecutionTypeInfo fieldTypeInfo(ExecutionStrategyParameters parameters, GraphQLFieldDefinition fieldDefinition) { - GraphQLOutputType fieldType = fieldDefinition.getType(); - return newTypeInfo() - .type(fieldType) - .fieldDefinition(fieldDefinition) - .path(parameters.getPath()) - .parentInfo(parameters.getTypeInfo()) - .build(); + protected ExecutionStepInfo createExecutionStepInfo(ExecutionContext executionContext, + ExecutionStrategyParameters parameters, + GraphQLFieldDefinition fieldDefinition, + GraphQLObjectType fieldContainer) { + return executionStepInfoFactory.createExecutionStepInfo(executionContext, + parameters, + fieldDefinition, + fieldContainer); + } + private Supplier createExecutionStepInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); + return FpKit.intraThreadMemoize(() -> createExecutionStepInfo(executionContext, parameters, fieldDef, null)); + } + + // Errors that result from the execution of deferred fields are kept in the deferred context only. + private static void addErrorToRightContext(GraphQLError error, ExecutionStrategyParameters parameters, ExecutionContext executionContext) { + if (parameters.getDeferredCallContext() != null) { + parameters.getDeferredCallContext().addError(error); + } else { + executionContext.addError(error); + } + } + + private static void addErrorsToRightContext(List errors, ExecutionStrategyParameters parameters, ExecutionContext executionContext) { + if (parameters.getDeferredCallContext() != null) { + parameters.getDeferredCallContext().addErrors(errors); + } else { + executionContext.addErrors(errors); + } } } diff --git a/src/main/java/graphql/execution/ExecutionStrategyParameters.java b/src/main/java/graphql/execution/ExecutionStrategyParameters.java index 933da61e8e..71d7fd9f8b 100644 --- a/src/main/java/graphql/execution/ExecutionStrategyParameters.java +++ b/src/main/java/graphql/execution/ExecutionStrategyParameters.java @@ -1,12 +1,10 @@ package graphql.execution; -import graphql.Assert; +import graphql.Internal; import graphql.PublicApi; -import graphql.execution.defer.DeferredErrorSupport; -import graphql.language.Field; +import graphql.execution.incremental.AlternativeCallContext; +import org.jspecify.annotations.Nullable; -import java.util.List; -import java.util.Map; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; @@ -16,93 +14,184 @@ */ @PublicApi public class ExecutionStrategyParameters { - private final ExecutionTypeInfo typeInfo; + private final ExecutionStepInfo executionStepInfo; private final Object source; - private final Map arguments; - private final Map> fields; + private final Object localContext; + private final MergedSelectionSet fields; private final NonNullableFieldValidator nonNullableFieldValidator; - private final ExecutionPath path; - private final List currentField; - private final int listSize; - private final int currentListIndex; + private final ResultPath path; + private final MergedField currentField; private final ExecutionStrategyParameters parent; - private final DeferredErrorSupport deferredErrorSupport; + private final AlternativeCallContext alternativeCallContext; - private ExecutionStrategyParameters(ExecutionTypeInfo typeInfo, + private ExecutionStrategyParameters(ExecutionStepInfo executionStepInfo, Object source, - Map> fields, - Map arguments, + Object localContext, + MergedSelectionSet fields, NonNullableFieldValidator nonNullableFieldValidator, - ExecutionPath path, - List currentField, - int listSize, - int currentListIndex, + ResultPath path, + MergedField currentField, ExecutionStrategyParameters parent, - DeferredErrorSupport deferredErrorSupport) { + AlternativeCallContext alternativeCallContext) { - this.typeInfo = assertNotNull(typeInfo, "typeInfo is null"); + this.executionStepInfo = assertNotNull(executionStepInfo, "executionStepInfo is null"); + this.localContext = localContext; this.fields = assertNotNull(fields, "fields is null"); this.source = source; - this.arguments = arguments; - this.nonNullableFieldValidator = nonNullableFieldValidator; + this.nonNullableFieldValidator = assertNotNull(nonNullableFieldValidator, "requires a NonNullValidator");; this.path = path; this.currentField = currentField; - this.listSize = listSize; - this.currentListIndex = currentListIndex; this.parent = parent; - this.deferredErrorSupport = deferredErrorSupport; + this.alternativeCallContext = alternativeCallContext; } - public ExecutionTypeInfo getTypeInfo() { - return typeInfo; + public ExecutionStepInfo getExecutionStepInfo() { + return executionStepInfo; } public Object getSource() { return source; } - public Map> getFields() { + public MergedSelectionSet getFields() { return fields; } - public Map getArguments() { - return arguments; - } - public NonNullableFieldValidator getNonNullFieldValidator() { return nonNullableFieldValidator; } - public ExecutionPath getPath() { + public ResultPath getPath() { return path; } - public int getListSize() { - return listSize; - } - - public int getCurrentListIndex() { - return currentListIndex; + public Object getLocalContext() { + return localContext; } public ExecutionStrategyParameters getParent() { return parent; } - public DeferredErrorSupport deferredErrorSupport() { - return deferredErrorSupport; + + /** + * Returns the deferred call context if we're in the scope of a deferred call. + * A new DeferredCallContext is created for each @defer block, and is passed down to all fields within the deferred call. + * + *

+     *     query {
+     *        ... @defer {
+     *            field1 {        # new DeferredCallContext created here
+     *                field1a     # DeferredCallContext passed down to this field
+     *            }
+     *        }
+     *
+     *        ... @defer {
+     *            field2          # new DeferredCallContext created here
+     *        }
+     *     }
+     * 
+ * + * @return the deferred call context or null if we're not in the scope of a deferred call + */ + @Nullable + @Internal + public AlternativeCallContext getDeferredCallContext() { + return alternativeCallContext; + } + + /** + * Returns true if we're in the scope of a deferred call. + * + * @return true if we're in the scope of a deferred call + */ + public boolean isInDeferredContext() { + return alternativeCallContext != null; } /** - * This returns the current field in its query representations. Global fragments mean that - * a single named field can have multiple representations and different field subselections - * hence the use of a list of Field + * This returns the current field in its query representations. * - * @return the current field in list form or null if this has not be computed yet + * @return the current merged fields */ - public List getField() { + public MergedField getField() { return currentField; } + @Internal + ExecutionStrategyParameters transform(MergedField currentField, + ResultPath path) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + alternativeCallContext); + } + + @Internal + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, + MergedSelectionSet fields, + Object source) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + alternativeCallContext); + } + + @Internal + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, + ResultPath path, + Object localContext, + Object source) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + alternativeCallContext); + } + + @Internal + ExecutionStrategyParameters transform(ExecutionStepInfo executionStepInfo, + Object localContext, + Object source) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + alternativeCallContext); + } + + @Internal + ExecutionStrategyParameters transform(MergedField currentField, + ResultPath path, + ExecutionStrategyParameters parent) { + return new ExecutionStrategyParameters(executionStepInfo, + source, + localContext, + fields, + nonNullableFieldValidator, + path, + currentField, + parent, + alternativeCallContext); + } + public ExecutionStrategyParameters transform(Consumer builderConsumer) { Builder builder = newParameters(this); builderConsumer.accept(builder); @@ -111,8 +200,8 @@ public ExecutionStrategyParameters transform(Consumer builderConsumer) @Override public String toString() { - return String.format("ExecutionStrategyParameters { path=%s, typeInfo=%s, source=%s, fields=%s }", - path, typeInfo, source, fields); + return String.format("ExecutionStrategyParameters { path=%s, executionStepInfo=%s, source=%s, fields=%s }", + path, executionStepInfo, source, fields); } public static Builder newParameters() { @@ -124,17 +213,15 @@ public static Builder newParameters(ExecutionStrategyParameters oldParameters) { } public static class Builder { - ExecutionTypeInfo typeInfo; + ExecutionStepInfo executionStepInfo; Object source; - Map> fields; - Map arguments; + Object localContext; + MergedSelectionSet fields; NonNullableFieldValidator nonNullableFieldValidator; - ExecutionPath path = ExecutionPath.rootPath(); - List currentField; - int listSize; - int currentListIndex; + ResultPath path = ResultPath.rootPath(); + MergedField currentField; ExecutionStrategyParameters parent; - DeferredErrorSupport deferredErrorSupport = new DeferredErrorSupport(); + AlternativeCallContext alternativeCallContext; /** * @see ExecutionStrategyParameters#newParameters() @@ -146,35 +233,33 @@ private Builder() { * @see ExecutionStrategyParameters#newParameters(ExecutionStrategyParameters) */ private Builder(ExecutionStrategyParameters oldParameters) { - this.typeInfo = oldParameters.typeInfo; + this.executionStepInfo = oldParameters.executionStepInfo; this.source = oldParameters.source; + this.localContext = oldParameters.localContext; this.fields = oldParameters.fields; - this.arguments = oldParameters.arguments; this.nonNullableFieldValidator = oldParameters.nonNullableFieldValidator; this.currentField = oldParameters.currentField; - this.deferredErrorSupport = oldParameters.deferredErrorSupport; + this.alternativeCallContext = oldParameters.alternativeCallContext; this.path = oldParameters.path; this.parent = oldParameters.parent; - this.listSize = oldParameters.listSize; - this.currentListIndex = oldParameters.currentListIndex; } - public Builder typeInfo(ExecutionTypeInfo type) { - this.typeInfo = type; + public Builder executionStepInfo(ExecutionStepInfo executionStepInfo) { + this.executionStepInfo = executionStepInfo; return this; } - public Builder typeInfo(ExecutionTypeInfo.Builder type) { - this.typeInfo = type.build(); + public Builder executionStepInfo(ExecutionStepInfo.Builder executionStepInfoBuilder) { + this.executionStepInfo = executionStepInfoBuilder.build(); return this; } - public Builder fields(Map> fields) { + public Builder fields(MergedSelectionSet fields) { this.fields = fields; return this; } - public Builder field(List currentField) { + public Builder field(MergedField currentField) { this.currentField = currentField; return this; } @@ -184,43 +269,33 @@ public Builder source(Object source) { return this; } - public Builder arguments(Map arguments) { - this.arguments = arguments; + public Builder localContext(Object localContext) { + this.localContext = localContext; return this; } public Builder nonNullFieldValidator(NonNullableFieldValidator nonNullableFieldValidator) { - this.nonNullableFieldValidator = Assert.assertNotNull(nonNullableFieldValidator, "requires a NonNullValidator"); + this.nonNullableFieldValidator = assertNotNull(nonNullableFieldValidator, "requires a NonNullValidator"); return this; } - public Builder path(ExecutionPath path) { + public Builder path(ResultPath path) { this.path = path; return this; } - public Builder listSize(int listSize) { - this.listSize = listSize; - return this; - } - - public Builder currentListIndex(int currentListIndex) { - this.currentListIndex = currentListIndex; - return this; - } - public Builder parent(ExecutionStrategyParameters parent) { this.parent = parent; return this; } - public Builder deferredErrorSupport(DeferredErrorSupport deferredErrorSupport) { - this.deferredErrorSupport = deferredErrorSupport; + public Builder deferredCallContext(AlternativeCallContext alternativeCallContext) { + this.alternativeCallContext = alternativeCallContext; return this; } public ExecutionStrategyParameters build() { - return new ExecutionStrategyParameters(typeInfo, source, fields, arguments, nonNullableFieldValidator, path, currentField, listSize, currentListIndex, parent, deferredErrorSupport); + return new ExecutionStrategyParameters(executionStepInfo, source, localContext, fields, nonNullableFieldValidator, path, currentField, parent, alternativeCallContext); } } } diff --git a/src/main/java/graphql/execution/ExecutionTypeInfo.java b/src/main/java/graphql/execution/ExecutionTypeInfo.java deleted file mode 100644 index 2130e8979e..0000000000 --- a/src/main/java/graphql/execution/ExecutionTypeInfo.java +++ /dev/null @@ -1,243 +0,0 @@ -package graphql.execution; - -import graphql.PublicApi; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLInterfaceType; -import graphql.schema.GraphQLList; -import graphql.schema.GraphQLNonNull; -import graphql.schema.GraphQLType; -import graphql.schema.GraphQLTypeUtil; - -import java.util.Stack; - -import static graphql.Assert.assertNotNull; -import static graphql.schema.GraphQLNonNull.nonNull; -import static graphql.schema.GraphQLTypeUtil.isList; -import static graphql.schema.GraphQLTypeUtil.isNonNull; -import static graphql.schema.GraphQLTypeUtil.isNotWrapped; -import static graphql.schema.GraphQLTypeUtil.unwrapAll; -import static graphql.schema.GraphQLTypeUtil.unwrapOne; - -/** - * As the graphql query executes, it forms a hierarchy from parent fields (and their type) to their child fields (and their type) - * until a scalar type is encountered; this class captures that execution type information. - *

- * The static graphql type system (rightly) does not contain a hierarchy of child to parent types nor the nonnull ness of - * type instances, so this helper class adds this information during query execution. - */ -@PublicApi -public class ExecutionTypeInfo { - - private final GraphQLType type; - private final GraphQLFieldDefinition fieldDefinition; - private final ExecutionPath path; - private final boolean typeIsNonNull; - private final ExecutionTypeInfo parentType; - - private ExecutionTypeInfo(GraphQLType type, GraphQLFieldDefinition fieldDefinition, ExecutionPath path, ExecutionTypeInfo parentType, boolean nonNull) { - this.fieldDefinition = fieldDefinition; - this.path = path; - this.parentType = parentType; - this.type = type; - this.typeIsNonNull = nonNull; - assertNotNull(this.type, "you must provide a graphql type"); - } - - /** - * This returns the type which is unwrapped if it was {@link GraphQLNonNull} wrapped - * - * @return the graphql type in question - */ - public GraphQLType getType() { - return type; - } - - /** - * This returns the field definition that is in play when this type info was created or null - * if the type is a root query type - * - * @return the field definition or null if there is not one - */ - public GraphQLFieldDefinition getFieldDefinition() { - return fieldDefinition; - } - - /** - * @return the {@link ExecutionPath} to this info - */ - public ExecutionPath getPath() { - return path; - } - - /** - * This will cast the type to a specific graphql type such - * as {@link graphql.schema.GraphQLObjectType} say - * - * @param clazz the class to cast to - * @param the type you want to become - * - * @return this type cast as that - */ - @SuppressWarnings("unchecked") - public T castType(Class clazz) { - return clazz.cast(type); - } - - /** - * @return true if the type must be nonnull - */ - public boolean isNonNullType() { - return typeIsNonNull; - } - - /** - * @return true if the type is a list - */ - public boolean isListType() { - return isList(type); - } - - /** - * @return the parent type information - */ - public ExecutionTypeInfo getParentTypeInfo() { - return parentType; - } - - /** - * @return true if the type has a parent (most do) - */ - public boolean hasParentType() { - return parentType != null; - } - - /** - * This allows you to morph a type into a more specialized form yet return the same - * parent and non-null ness, for example taking a {@link GraphQLInterfaceType} - * and turning it into a specific {@link graphql.schema.GraphQLObjectType} - * after type resolution has occurred - * - * @param newType the new type to be - * - * @return a new type info with the same - */ - public ExecutionTypeInfo treatAs(GraphQLType newType) { - return new ExecutionTypeInfo(unwrapNonNull(newType), fieldDefinition, path, this.parentType, this.typeIsNonNull); - } - - - /** - * graphql types can be wrapped in {@link GraphQLNonNull} and {@link GraphQLList} type wrappers - * so this method will unwrap the type down to the raw unwrapped type and return that wrapping - * as a stack, with the top of the stack being the raw underling type. - * - * @param type the type to unwrap - * - * @return a stack of the type wrapping which will be at least 1 later deep - */ - public static Stack unwrapType(GraphQLType type) { - type = assertNotNull(type); - Stack decoration = new Stack<>(); - while (true) { - decoration.push(type); - if (isNotWrapped(type)) { - break; - } - type = unwrapOne(type); - } - return decoration; - } - - /** - * graphql types can be wrapped in {@link GraphQLNonNull} and {@link GraphQLList} type wrappers - * so this method will unwrap the type down to the raw underlying type. - * - * @param type the type to unwrap - * - * @return the underlying raw type with {@link GraphQLNonNull} and {@link GraphQLList} type wrappers removed - */ - public static GraphQLType unwrapBaseType(GraphQLType type) { - return unwrapAll(type); - } - - - /** - * @return the type in graphql AST format, eg [typeName!]! - */ - public String toAst() { - // type info unwraps non nulls - we need it back here - GraphQLType type = this.getType(); - if (isNonNullType()) { - type = nonNull(type); - } - return GraphQLTypeUtil.getUnwrappedTypeName(type); - - } - - @Override - public String toString() { - return "ExecutionTypeInfo{" + - " path=" + path + - ", type=" + type + - ", parentType=" + parentType + - ", typeIsNonNull=" + typeIsNonNull + - ", fieldDefinition=" + fieldDefinition + - '}'; - } - - private static GraphQLType unwrapNonNull(GraphQLType type) { - // its possible to have non nulls wrapping non nulls of things but it must end at some point - while (isNonNull(type)) { - type = unwrapOne(type); - } - return type; - } - - /** - * @return a builder of type info - */ - public static ExecutionTypeInfo.Builder newTypeInfo() { - return new Builder(); - } - - public static class Builder { - GraphQLType type; - ExecutionTypeInfo parentType; - GraphQLFieldDefinition fieldDefinition; - ExecutionPath executionPath; - - /** - * @see ExecutionTypeInfo#newTypeInfo() - */ - private Builder() { - } - - public Builder type(GraphQLType type) { - this.type = type; - return this; - } - - public Builder parentInfo(ExecutionTypeInfo typeInfo) { - this.parentType = typeInfo; - return this; - } - - public Builder fieldDefinition(GraphQLFieldDefinition fieldDefinition) { - this.fieldDefinition = fieldDefinition; - return this; - } - - public Builder path(ExecutionPath executionPath) { - this.executionPath = executionPath; - return this; - } - - - public ExecutionTypeInfo build() { - if (isNonNull(type)) { - return new ExecutionTypeInfo(unwrapNonNull(type), fieldDefinition, executionPath, parentType, true); - } - return new ExecutionTypeInfo(type, fieldDefinition, executionPath, parentType, false); - } - } -} diff --git a/src/main/java/graphql/execution/ExecutorServiceExecutionStrategy.java b/src/main/java/graphql/execution/ExecutorServiceExecutionStrategy.java deleted file mode 100644 index 335ecc2ce5..0000000000 --- a/src/main/java/graphql/execution/ExecutorServiceExecutionStrategy.java +++ /dev/null @@ -1,105 +0,0 @@ -package graphql.execution; - -import graphql.ExecutionResult; -import graphql.ExecutionResultImpl; -import graphql.GraphQLException; -import graphql.PublicApi; -import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.language.Field; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - -/** - *

ExecutorServiceExecutionStrategy uses an {@link ExecutorService} to parallelize the resolve.

- * - * Due to the nature of {@link #execute(ExecutionContext, ExecutionStrategyParameters)} implementation, {@link ExecutorService} - * MUST have the following 2 characteristics: - *
    - *
  • 1. The underlying {@link java.util.concurrent.ThreadPoolExecutor} MUST have a reasonable {@code maximumPoolSize} - *
  • 2. The underlying {@link java.util.concurrent.ThreadPoolExecutor} SHALL NOT use its task queue. - *
- * - *

Failure to follow 1. and 2. can result in a very large number of threads created or hanging. (deadlock)

- * - * See {@code graphql.execution.ExecutorServiceExecutionStrategyTest} for example usage. - */ -@PublicApi -public class ExecutorServiceExecutionStrategy extends ExecutionStrategy { - - final ExecutorService executorService; - - public ExecutorServiceExecutionStrategy(ExecutorService executorService) { - this(executorService, new SimpleDataFetcherExceptionHandler()); - } - - public ExecutorServiceExecutionStrategy(ExecutorService executorService, DataFetcherExceptionHandler dataFetcherExceptionHandler) { - super(dataFetcherExceptionHandler); - this.executorService = executorService; - } - - - @Override - public CompletableFuture execute(final ExecutionContext executionContext, final ExecutionStrategyParameters parameters) { - if (executorService == null) { - return new AsyncExecutionStrategy().execute(executionContext, parameters); - } - - Instrumentation instrumentation = executionContext.getInstrumentation(); - InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters); - InstrumentationContext executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters); - - Map> fields = parameters.getFields(); - Map>> futures = new LinkedHashMap<>(); - for (String fieldName : fields.keySet()) { - final List currentField = fields.get(fieldName); - - ExecutionPath fieldPath = parameters.getPath().segment(fieldName); - ExecutionStrategyParameters newParameters = parameters - .transform(builder -> builder.field(currentField).path(fieldPath)); - - Callable> resolveField = () -> resolveField(executionContext, newParameters); - futures.put(fieldName, executorService.submit(resolveField)); - } - - CompletableFuture overallResult = new CompletableFuture<>(); - executionStrategyCtx.onDispatched(overallResult); - - try { - Map results = new LinkedHashMap<>(); - for (String fieldName : futures.keySet()) { - ExecutionResult executionResult; - try { - executionResult = futures.get(fieldName).get().join(); - } catch (CompletionException e) { - if (e.getCause() instanceof NonNullableFieldWasNullException) { - assertNonNullFieldPrecondition((NonNullableFieldWasNullException) e.getCause()); - results = null; - break; - } else { - throw e; - } - } - results.put(fieldName, executionResult != null ? executionResult.getData() : null); - } - - ExecutionResultImpl executionResult = new ExecutionResultImpl(results, executionContext.getErrors()); - overallResult.complete(executionResult); - - overallResult = overallResult.whenComplete(executionStrategyCtx::onCompleted); - return overallResult; - } catch (InterruptedException | ExecutionException e) { - executionStrategyCtx.onCompleted(null, e); - throw new GraphQLException(e); - } - } -} diff --git a/src/main/java/graphql/execution/FetchedValue.java b/src/main/java/graphql/execution/FetchedValue.java new file mode 100644 index 0000000000..fe56fa0a10 --- /dev/null +++ b/src/main/java/graphql/execution/FetchedValue.java @@ -0,0 +1,83 @@ +package graphql.execution; + +import com.google.common.collect.ImmutableList; +import graphql.GraphQLError; +import graphql.PublicApi; +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; + +import java.util.List; + +/** + * Note: This MAY be returned by {@link InstrumentationFieldCompleteParameters#getFetchedObject()} + * and therefore part of the public despite never used in a method signature. + */ +@PublicApi +public class FetchedValue { + private final Object fetchedValue; + private final Object localContext; + private final ImmutableList errors; + + /** + * This allows you to get to the underlying fetched value depending on whether the source + * value is a {@link FetchedValue} or not + * + * @param sourceValue the source value in play + * + * @return the {@link FetchedValue#getFetchedValue()} if its wrapped otherwise the source value itself + */ + public static Object getFetchedValue(Object sourceValue) { + if (sourceValue instanceof FetchedValue) { + return ((FetchedValue) sourceValue).fetchedValue; + } else { + return sourceValue; + } + } + + /** + * This allows you to get to the local context depending on whether the source + * value is a {@link FetchedValue} or not + * + * @param sourceValue the source value in play + * @param defaultLocalContext the default local context to use + * + * @return the {@link FetchedValue#getFetchedValue()} if its wrapped otherwise the default local context + */ + public static Object getLocalContext(Object sourceValue, Object defaultLocalContext) { + if (sourceValue instanceof FetchedValue) { + return ((FetchedValue) sourceValue).localContext; + } else { + return defaultLocalContext; + } + } + + public FetchedValue(Object fetchedValue, List errors, Object localContext) { + this.fetchedValue = fetchedValue; + this.errors = ImmutableList.copyOf(errors); + this.localContext = localContext; + } + + /* + * the unboxed value meaning not Optional, not DataFetcherResult etc + */ + public Object getFetchedValue() { + return fetchedValue; + } + + public List getErrors() { + return errors; + } + + public Object getLocalContext() { + return localContext; + } + + @Override + public String toString() { + return "FetchedValue{" + + "fetchedValue=" + fetchedValue + + ", localContext=" + localContext + + ", errors=" + errors + + '}'; + } + +} \ No newline at end of file diff --git a/src/main/java/graphql/execution/FieldCollector.java b/src/main/java/graphql/execution/FieldCollector.java index 9b0a511adc..9a63e009b3 100644 --- a/src/main/java/graphql/execution/FieldCollector.java +++ b/src/main/java/graphql/execution/FieldCollector.java @@ -2,6 +2,9 @@ import graphql.Internal; +import graphql.execution.conditional.ConditionalNodes; +import graphql.execution.incremental.DeferredExecution; +import graphql.execution.incremental.IncrementalUtils; import graphql.language.Field; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; @@ -12,49 +15,38 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLType; import graphql.schema.GraphQLUnionType; -import graphql.schema.SchemaUtil; -import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import static graphql.execution.MergedSelectionSet.newMergedSelectionSet; import static graphql.execution.TypeFromAST.getTypeFromAST; /** * A field collector can iterate over field selection sets and build out the sub fields that have been selected, - * expanding named and inline fragments as it goes.s + * expanding named and inline fragments as it goes. */ @Internal public class FieldCollector { - private final ConditionalNodes conditionalNodes; + private final ConditionalNodes conditionalNodes = new ConditionalNodes(); - private final SchemaUtil schemaUtil = new SchemaUtil(); - - public FieldCollector() { - conditionalNodes = new ConditionalNodes(); + public MergedSelectionSet collectFields(FieldCollectorParameters parameters, MergedField mergedField) { + return collectFields(parameters, mergedField, false); } - - /** - * Given a list of fields this will collect the sub-field selections and return it as a map - * - * @param parameters the parameters to this method - * @param fields the list of fields to collect for - * - * @return a map of the sub field selections - */ - public Map> collectFields(FieldCollectorParameters parameters, List fields) { - Map> subFields = new LinkedHashMap<>(); - List visitedFragments = new ArrayList<>(); - for (Field field : fields) { - if (field.getSelectionSet() == null) { - continue; + public MergedSelectionSet collectFields(FieldCollectorParameters parameters, MergedField mergedField, boolean incrementalSupport) { + Map subFields = new LinkedHashMap<>(); + Set visitedFragments = new LinkedHashSet<>(); + mergedField.forEach(field -> { + if (field.getSelectionSet() != null) { + this.collectFields(parameters, field.getSelectionSet(), visitedFragments, subFields, null, incrementalSupport); } - this.collectFields(parameters, field.getSelectionSet(), visitedFragments, subFields); - } - return subFields; + }); + return newMergedSelectionSet().subFields(subFields).build(); } /** @@ -65,69 +57,97 @@ public Map> collectFields(FieldCollectorParameters parameter * * @return a map of the sub field selections */ - public Map> collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet) { - Map> subFields = new LinkedHashMap<>(); - List visitedFragments = new ArrayList<>(); - this.collectFields(parameters, selectionSet, visitedFragments, subFields); - return subFields; + public MergedSelectionSet collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet) { + return collectFields(parameters, selectionSet, false); + } + + public MergedSelectionSet collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet, boolean incrementalSupport) { + Map subFields = new LinkedHashMap<>(); + Set visitedFragments = new LinkedHashSet<>(); + this.collectFields(parameters, selectionSet, visitedFragments, subFields, null, incrementalSupport); + return newMergedSelectionSet().subFields(subFields).build(); } - private void collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet, List visitedFragments, Map> fields) { + private void collectFields(FieldCollectorParameters parameters, SelectionSet selectionSet, Set visitedFragments, Map fields, DeferredExecution deferredExecution, boolean incrementalSupport) { for (Selection selection : selectionSet.getSelections()) { if (selection instanceof Field) { - collectField(parameters, fields, (Field) selection); + collectField(parameters, fields, (Field) selection, deferredExecution); } else if (selection instanceof InlineFragment) { - collectInlineFragment(parameters, visitedFragments, fields, (InlineFragment) selection); + collectInlineFragment(parameters, visitedFragments, fields, (InlineFragment) selection, incrementalSupport); } else if (selection instanceof FragmentSpread) { - collectFragmentSpread(parameters, visitedFragments, fields, (FragmentSpread) selection); + collectFragmentSpread(parameters, visitedFragments, fields, (FragmentSpread) selection, incrementalSupport); } } } - private void collectFragmentSpread(FieldCollectorParameters parameters, List visitedFragments, Map> fields, FragmentSpread fragmentSpread) { + private void collectFragmentSpread(FieldCollectorParameters parameters, Set visitedFragments, Map fields, FragmentSpread fragmentSpread, boolean incrementalSupport) { if (visitedFragments.contains(fragmentSpread.getName())) { return; } - if (!conditionalNodes.shouldInclude(parameters.getVariables(), fragmentSpread.getDirectives())) { + if (!conditionalNodes.shouldInclude(fragmentSpread, + parameters.getVariables(), + parameters.getGraphQLSchema(), + parameters.getGraphQLContext())) { return; } visitedFragments.add(fragmentSpread.getName()); FragmentDefinition fragmentDefinition = parameters.getFragmentsByName().get(fragmentSpread.getName()); - if (!conditionalNodes.shouldInclude(parameters.getVariables(), fragmentDefinition.getDirectives())) { + if (!conditionalNodes.shouldInclude(fragmentDefinition, + parameters.getVariables(), + parameters.getGraphQLSchema(), + parameters.getGraphQLContext())) { return; } if (!doesFragmentConditionMatch(parameters, fragmentDefinition)) { return; } - collectFields(parameters, fragmentDefinition.getSelectionSet(), visitedFragments, fields); + + DeferredExecution deferredExecution = incrementalSupport ? IncrementalUtils.createDeferredExecution( + parameters.getVariables(), + fragmentSpread.getDirectives(), + DeferredExecution::new + ) : null; + + collectFields(parameters, fragmentDefinition.getSelectionSet(), visitedFragments, fields, deferredExecution, incrementalSupport); } - private void collectInlineFragment(FieldCollectorParameters parameters, List visitedFragments, Map> fields, InlineFragment inlineFragment) { - if (!conditionalNodes.shouldInclude(parameters.getVariables(), inlineFragment.getDirectives()) || + private void collectInlineFragment(FieldCollectorParameters parameters, Set visitedFragments, Map fields, InlineFragment inlineFragment, boolean incrementalSupport) { + if (!conditionalNodes.shouldInclude(inlineFragment, + parameters.getVariables(), + parameters.getGraphQLSchema(), + parameters.getGraphQLContext()) || !doesFragmentConditionMatch(parameters, inlineFragment)) { return; } - collectFields(parameters, inlineFragment.getSelectionSet(), visitedFragments, fields); + + DeferredExecution deferredExecution = incrementalSupport ? IncrementalUtils.createDeferredExecution( + parameters.getVariables(), + inlineFragment.getDirectives(), + DeferredExecution::new + ) : null; + + collectFields(parameters, inlineFragment.getSelectionSet(), visitedFragments, fields, deferredExecution, incrementalSupport); } - private void collectField(FieldCollectorParameters parameters, Map> fields, Field field) { - if (!conditionalNodes.shouldInclude(parameters.getVariables(), field.getDirectives())) { + private void collectField(FieldCollectorParameters parameters, Map fields, Field field, DeferredExecution deferredExecution) { + if (!conditionalNodes.shouldInclude(field, + parameters.getVariables(), + parameters.getGraphQLSchema(), + parameters.getGraphQLContext())) { return; } - String name = getFieldEntryKey(field); - fields.putIfAbsent(name, new ArrayList<>()); - fields.get(name).add(field); - } - - private String getFieldEntryKey(Field field) { - if (field.getAlias() != null) return field.getAlias(); - else return field.getName(); + String name = field.getResultKey(); + if (fields.containsKey(name)) { + MergedField currentMergedField = fields.get(name); + fields.put(name, currentMergedField.newMergedFieldWith(field,deferredExecution)); + } else { + fields.put(name, MergedField.newSingletonMergedField(field, deferredExecution)); + } } - private boolean doesFragmentConditionMatch(FieldCollectorParameters parameters, InlineFragment inlineFragment) { if (inlineFragment.getTypeCondition() == null) { return true; @@ -150,7 +170,7 @@ private boolean checkTypeCondition(FieldCollectorParameters parameters, GraphQLT } if (conditionType instanceof GraphQLInterfaceType) { - List implementations = parameters.getGraphQLSchema().getImplementations((GraphQLInterfaceType)conditionType); + List implementations = parameters.getGraphQLSchema().getImplementations((GraphQLInterfaceType) conditionType); return implementations.contains(type); } else if (conditionType instanceof GraphQLUnionType) { return ((GraphQLUnionType) conditionType).getTypes().contains(type); diff --git a/src/main/java/graphql/execution/FieldCollectorParameters.java b/src/main/java/graphql/execution/FieldCollectorParameters.java index 9c3eacb289..75dafc1eff 100644 --- a/src/main/java/graphql/execution/FieldCollectorParameters.java +++ b/src/main/java/graphql/execution/FieldCollectorParameters.java @@ -1,12 +1,12 @@ package graphql.execution; import graphql.Assert; +import graphql.GraphQLContext; import graphql.Internal; import graphql.language.FragmentDefinition; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; -import java.util.LinkedHashMap; import java.util.Map; /** @@ -18,6 +18,7 @@ public class FieldCollectorParameters { private final Map fragmentsByName; private final Map variables; private final GraphQLObjectType objectType; + private final GraphQLContext graphQLContext; public GraphQLSchema getGraphQLSchema() { return graphQLSchema; @@ -35,11 +36,16 @@ public GraphQLObjectType getObjectType() { return objectType; } - private FieldCollectorParameters(GraphQLSchema graphQLSchema, Map variables, Map fragmentsByName, GraphQLObjectType objectType) { - this.fragmentsByName = fragmentsByName; - this.graphQLSchema = graphQLSchema; - this.variables = variables; - this.objectType = objectType; + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + private FieldCollectorParameters(Builder builder) { + this.fragmentsByName = builder.fragmentsByName; + this.graphQLSchema = builder.graphQLSchema; + this.variables = builder.variables; + this.objectType = builder.objectType; + this.graphQLContext = builder.graphQLContext; } public static Builder newParameters() { @@ -48,9 +54,10 @@ public static Builder newParameters() { public static class Builder { private GraphQLSchema graphQLSchema; - private final Map fragmentsByName = new LinkedHashMap<>(); - private final Map variables = new LinkedHashMap<>(); + private Map fragmentsByName; + private Map variables; private GraphQLObjectType objectType; + private GraphQLContext graphQLContext = GraphQLContext.getDefault(); /** * @see FieldCollectorParameters#newParameters() @@ -69,19 +76,24 @@ public Builder objectType(GraphQLObjectType objectType) { return this; } + public Builder graphQLContext(GraphQLContext graphQLContext) { + this.graphQLContext = graphQLContext; + return this; + } + public Builder fragments(Map fragmentsByName) { - this.fragmentsByName.putAll(fragmentsByName); + this.fragmentsByName = fragmentsByName; return this; } public Builder variables(Map variables) { - this.variables.putAll(variables); + this.variables = variables; return this; } public FieldCollectorParameters build() { Assert.assertNotNull(graphQLSchema, "You must provide a schema"); - return new FieldCollectorParameters(graphQLSchema, variables, fragmentsByName, objectType); + return new FieldCollectorParameters(this); } } diff --git a/src/main/java/graphql/execution/FieldValueInfo.java b/src/main/java/graphql/execution/FieldValueInfo.java index e4da4ba0c8..2839a8cd5b 100644 --- a/src/main/java/graphql/execution/FieldValueInfo.java +++ b/src/main/java/graphql/execution/FieldValueInfo.java @@ -1,14 +1,23 @@ package graphql.execution; -import graphql.ExecutionResult; +import com.google.common.collect.ImmutableList; import graphql.PublicApi; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import static graphql.Assert.assertNotNull; +/** + * The {@link FieldValueInfo} holds the type of field that was fetched and completed along with the completed value. + *

+ * A field value is considered when its is both fetch via a {@link graphql.schema.DataFetcher} to a raw value, and then + * it is serialized into scalar or enum or if it's an object type, it is completed as an object given its field sub selection + *

+ * The {@link #getFieldValueObject()} method returns either a materialized value or a {@link CompletableFuture} + * promise to a materialized value. Simple in-memory values will tend to be materialized, while complicated + * values might need a call to a database or other systems will tend to be {@link CompletableFuture} promises. + */ @PublicApi public class FieldValueInfo { @@ -18,73 +27,76 @@ public enum CompleteValueType { NULL, SCALAR, ENUM - } private final CompleteValueType completeValueType; - private final CompletableFuture fieldValue; + private final Object /* CompletableFuture | Object */ fieldValueObject; private final List fieldValueInfos; - private FieldValueInfo(CompleteValueType completeValueType, CompletableFuture fieldValue, List fieldValueInfos) { + public FieldValueInfo(CompleteValueType completeValueType, Object fieldValueObject) { + this(completeValueType, fieldValueObject, ImmutableList.of()); + } + + public FieldValueInfo(CompleteValueType completeValueType, Object fieldValueObject, List fieldValueInfos) { assertNotNull(fieldValueInfos, "fieldValueInfos can't be null"); this.completeValueType = completeValueType; - this.fieldValue = fieldValue; + this.fieldValueObject = fieldValueObject; this.fieldValueInfos = fieldValueInfos; } + /** + * This is an enum that represents the type of field value that was completed for a field + * + * @return the type of field value + */ public CompleteValueType getCompleteValueType() { return completeValueType; } - public CompletableFuture getFieldValue() { - return fieldValue; + /** + * This value can be either an object that is materialized or a {@link CompletableFuture} promise to a value + * + * @return either an object that is materialized or a {@link CompletableFuture} promise to a value + */ + public Object /* CompletableFuture | Object */ getFieldValueObject() { + return fieldValueObject; + } + + /** + * This returns the value in {@link CompletableFuture} form. If it is already a {@link CompletableFuture} it is returned + * directly, otherwise the materialized value is wrapped in a {@link CompletableFuture} and returned + * + * @return a {@link CompletableFuture} promise to the value + */ + public CompletableFuture getFieldValueFuture() { + return Async.toCompletableFuture(fieldValueObject); } + /** + * @return true if the value is a {@link CompletableFuture} promise to a value + */ + public boolean isFutureValue() { + return fieldValueObject instanceof CompletableFuture; + } + + /** + * When the {@link #getCompleteValueType()} is {@link CompleteValueType#LIST} this holds the list + * of completed values inside that list object. + * + * @return the list of completed field values inside a list + */ public List getFieldValueInfos() { return fieldValueInfos; } - public static Builder newFieldValueInfo(CompleteValueType completeValueType) { - return new Builder(completeValueType); - } @Override public String toString() { return "FieldValueInfo{" + "completeValueType=" + completeValueType + - ", fieldValue=" + fieldValue + + ", fieldValueObject=" + fieldValueObject + ", fieldValueInfos=" + fieldValueInfos + '}'; } - @SuppressWarnings("unused") - public static class Builder { - private CompleteValueType completeValueType; - private CompletableFuture executionResultFuture; - private List listInfos = new ArrayList<>(); - - public Builder(CompleteValueType completeValueType) { - this.completeValueType = completeValueType; - } - - public Builder completeValueType(CompleteValueType completeValueType) { - this.completeValueType = completeValueType; - return this; - } - - public Builder fieldValue(CompletableFuture executionResultFuture) { - this.executionResultFuture = executionResultFuture; - return this; - } - - public Builder fieldValueInfos(List listInfos) { - assertNotNull(listInfos, "fieldValueInfos can't be null"); - this.listInfos = listInfos; - return this; - } - - public FieldValueInfo build() { - return new FieldValueInfo(completeValueType, executionResultFuture, listInfos); - } - } } \ No newline at end of file diff --git a/src/main/java/graphql/execution/InputMapDefinesTooManyFieldsException.java b/src/main/java/graphql/execution/InputMapDefinesTooManyFieldsException.java index 03353cc152..654c069c34 100644 --- a/src/main/java/graphql/execution/InputMapDefinesTooManyFieldsException.java +++ b/src/main/java/graphql/execution/InputMapDefinesTooManyFieldsException.java @@ -19,7 +19,7 @@ public class InputMapDefinesTooManyFieldsException extends GraphQLException implements GraphQLError { public InputMapDefinesTooManyFieldsException(GraphQLType graphQLType, String fieldName) { - super(String.format("The variables input contains a field name '%s' that is not defined for input object type '%s' ", fieldName, GraphQLTypeUtil.getUnwrappedTypeName(graphQLType))); + super(String.format("The variables input contains a field name '%s' that is not defined for input object type '%s' ", fieldName, GraphQLTypeUtil.simplePrint(graphQLType))); } @Override diff --git a/src/main/java/graphql/execution/MergedField.java b/src/main/java/graphql/execution/MergedField.java new file mode 100644 index 0000000000..59238b1c90 --- /dev/null +++ b/src/main/java/graphql/execution/MergedField.java @@ -0,0 +1,436 @@ +package graphql.execution; + +import com.google.common.collect.ImmutableList; +import graphql.ExperimentalApi; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.execution.incremental.DeferredExecution; +import graphql.language.Argument; +import graphql.language.Field; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotEmpty; +import static graphql.Assert.assertNotNull; + +/** + * This represents all Fields in a query which overlap and are merged into one. + * This means they all represent the same field actually when the query is executed. + *

+ * Example query with more than one Field merged together: + * + *

+ * {@code
+ *
+ *      query Foo {
+ *          bar
+ *          ...BarFragment
+ *      }
+ *
+ *      fragment BarFragment on Query {
+ *          bar
+ *      }
+ * }
+ * 
+ * + * Another example: + *
+ * {@code
+ *     {
+ *          me{fistName}
+ *          me{lastName}
+ *     }
+ * }
+ * 
+ * + * Here the field is merged together including the sub selections. + *

+ * A third example with different directives: + *

+ * {@code
+ *     {
+ *          foo @someDirective
+ *          foo @anotherDirective
+ *     }
+ * }
+ * 
+ * These examples make clear that you need to consider all merged fields together to have the full picture. + *

+ * The actual logic when fields can be successfully merged together is implemented in {#graphql.validation.rules.OverlappingFieldsCanBeMerged} + */ +@PublicApi +@NullMarked +public class MergedField { + + private final Field singleField; + private final ImmutableList deferredExecutions; + + private MergedField(Field field, ImmutableList deferredExecutions) { + this.singleField = field; + this.deferredExecutions = deferredExecutions; + } + + /** + * All merged fields have the same name. + *

+ * WARNING: This is not always the key in the execution result, because of possible aliases. See {@link #getResultKey()} + * + * @return the name of the merged fields. + */ + public String getName() { + return singleField.getName(); + } + + /** + * Returns the key of this MergedField for the overall result. + * This is either an alias or the field name. + * + * @return the key for this MergedField. + */ + public String getResultKey() { + return singleField.getResultKey(); + } + + /** + * The first of the merged fields. + *

+ * Because all fields are almost identically + * often only one of the merged fields are used. + * + * @return the fist of the merged Fields + */ + public Field getSingleField() { + return singleField; + } + + /** + * All merged fields share the same arguments. + * + * @return the list of arguments + */ + public List getArguments() { + return singleField.getArguments(); + } + + + /** + * All merged fields + * + * @return all merged fields + */ + public List getFields() { + return ImmutableList.of(singleField); + } + + /** + * @return how many fields are in this merged field + */ + public int getFieldsCount() { + return 1; + } + + /** + * @return true if the field has a sub selection + */ + public boolean hasSubSelection() { + return singleField.getSelectionSet() != null; + } + + /** + * @return true if this {@link MergedField} represents a single {@link Field} in the operation + */ + public boolean isSingleField() { + return true; + } + + /** + * Get a list of all {@link DeferredExecution}s that this field is part of + * + * @return all defer executions. + */ + @ExperimentalApi + public List getDeferredExecutions() { + return deferredExecutions; + } + + /** + * Returns true if this field is part of a deferred execution + * + * @return true if this field is part of a deferred execution + */ + @ExperimentalApi + public boolean isDeferred() { + return !deferredExecutions.isEmpty(); + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MergedField that = (MergedField) o; + return this.singleField.equals(that.singleField); + } + + @Override + public int hashCode() { + return Objects.hashCode(singleField); + } + + @Override + public String toString() { + return "MergedField{" + + "field(s)=" + singleField + + '}'; + } + + /** + * This is an important method because it creates a new MergedField from the existing one without using a builder + * to save memory. + * + * @param field the new field to add to the current merged field + * @param deferredExecution the deferred execution + * + * @return a new {@link MergedField} instance + */ + MergedField newMergedFieldWith(Field field, @Nullable DeferredExecution deferredExecution) { + ImmutableList deferredExecutions = mkDeferredExecutions(deferredExecution); + ImmutableList fields = ImmutableList.of(singleField, field); + return new MultiMergedField(fields, deferredExecutions); + } + + ImmutableList mkDeferredExecutions(@Nullable DeferredExecution deferredExecution) { + ImmutableList deferredExecutions = this.deferredExecutions; + if (deferredExecution != null) { + deferredExecutions = ImmutableKit.addToList(deferredExecutions, deferredExecution); + } + return deferredExecutions; + } + + /** + * Most of the time we have a single field inside a MergedField but when we need more than one field + * represented then this {@link MultiMergedField} is used + */ + static final class MultiMergedField extends MergedField { + private final ImmutableList fields; + + MultiMergedField(ImmutableList fields, ImmutableList deferredExecutions) { + super(fields.get(0), deferredExecutions); + this.fields = fields; + } + + @Override + public List getFields() { + return fields; + } + + @Override + public boolean hasSubSelection() { + for (Field field : this.fields) { + if (field.getSelectionSet() != null) { + return true; + } + } + return false; + } + + @Override + public int getFieldsCount() { + return fields.size(); + } + + @Override + public boolean isSingleField() { + return fields.size() == 1; + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MultiMergedField that = (MultiMergedField) o; + return fields.equals(that.fields); + } + + @Override + public int hashCode() { + return Objects.hashCode(fields); + } + + @Override + public String toString() { + return "MultiMergedField{" + + "field(s)=" + fields + + '}'; + } + + + @Override + public void forEach(Consumer fieldConsumer) { + fields.forEach(fieldConsumer); + } + + @Override + MergedField newMergedFieldWith(Field field, @Nullable DeferredExecution deferredExecution) { + ImmutableList deferredExecutions = mkDeferredExecutions(deferredExecution); + ImmutableList fields = ImmutableKit.addToList(this.fields, field); + return new MultiMergedField(fields, deferredExecutions); + } + } + + + public static Builder newMergedField() { + return new Builder(); + } + + public static Builder newMergedField(Field field) { + return new Builder().addField(field); + } + + public static Builder newMergedField(Collection fields) { + return new Builder().fields(fields); + } + + + /** + * This is an important method in that it creates a MergedField direct without the list and without a builder and hence + * saves some micro memory in not allocating a list of 1 + * + * @param field the field to wrap + * @param deferredExecution the deferred execution + * + * @return a new {@link MergedField} + */ + static MergedField newSingletonMergedField(Field field, @Nullable DeferredExecution deferredExecution) { + return new MergedField(field, deferredExecution == null ? ImmutableList.of() : ImmutableList.of(deferredExecution)); + } + + public MergedField transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + /** + * Runs a consumer for each field + * + * @param fieldConsumer the consumer to run + */ + public void forEach(Consumer fieldConsumer) { + fieldConsumer.accept(singleField); + } + + public static class Builder { + + /* + The builder logic is complicated by these dual singleton / list duality code, + but it prevents memory allocation and every bit counts + when the CPU is running hot and an operation has lots of fields! + */ + private ImmutableList.@Nullable Builder fields; + private @Nullable Field singleField; + private ImmutableList.@Nullable Builder deferredExecutions; + + private Builder() { + } + + private Builder(MergedField existing) { + if (existing instanceof MultiMergedField) { + this.singleField = null; + this.fields = new ImmutableList.Builder<>(); + this.fields.addAll(existing.getFields()); + } else { + this.singleField = existing.singleField; + } + if (!existing.deferredExecutions.isEmpty()) { + this.deferredExecutions = ensureDeferredExecutionsListBuilder(); + this.deferredExecutions.addAll(existing.deferredExecutions); + } + } + + private ImmutableList.Builder ensureDeferredExecutionsListBuilder() { + if (this.deferredExecutions == null) { + this.deferredExecutions = new ImmutableList.Builder<>(); + } + return this.deferredExecutions; + } + + private ImmutableList.Builder ensureFieldsListBuilder() { + if (this.fields == null) { + this.fields = new ImmutableList.Builder<>(); + if (this.singleField != null) { + this.fields.add(this.singleField); + this.singleField = null; + } + } + return this.fields; + } + + public Builder fields(Collection fields) { + if (singleField == null && this.fields == null && fields.size() == 1) { + // even if you present a list - if its a list of one, we dont allocate a list + singleField = fields.iterator().next(); + return this; + } else { + this.fields = ensureFieldsListBuilder(); + this.fields.addAll(fields); + } + return this; + } + + public Builder addField(Field field) { + if (singleField == null && this.fields == null) { + singleField = field; + return this; + } else { + this.fields = ensureFieldsListBuilder(); + } + this.fields.add(field); + return this; + } + + public Builder addDeferredExecutions(List deferredExecutions) { + if (!deferredExecutions.isEmpty()) { + this.deferredExecutions = ensureDeferredExecutionsListBuilder(); + this.deferredExecutions.addAll(deferredExecutions); + } + return this; + } + + @SuppressWarnings("UnusedReturnValue") + public Builder addDeferredExecution(@Nullable DeferredExecution deferredExecution) { + if (deferredExecution != null) { + this.deferredExecutions = ensureDeferredExecutionsListBuilder(); + this.deferredExecutions.add(deferredExecution); + } + return this; + } + + public MergedField build() { + ImmutableList deferredExecutions; + if (this.deferredExecutions == null) { + deferredExecutions = ImmutableList.of(); + } else { + deferredExecutions = this.deferredExecutions.build(); + } + if (this.singleField != null && this.fields == null) { + return new MergedField(singleField, deferredExecutions); + } + ImmutableList fields = assertNotNull(this.fields, "You MUST add at least one field via the builder").build(); + assertNotEmpty(fields); + return new MultiMergedField(fields, deferredExecutions); + } + } +} diff --git a/src/main/java/graphql/execution/MergedSelectionSet.java b/src/main/java/graphql/execution/MergedSelectionSet.java new file mode 100644 index 0000000000..434b8da4f5 --- /dev/null +++ b/src/main/java/graphql/execution/MergedSelectionSet.java @@ -0,0 +1,73 @@ +package graphql.execution; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.PublicApi; + +import java.util.List; +import java.util.Map; +import java.util.Set; + + +@PublicApi +public class MergedSelectionSet { + + private final Map subFields; + private final List keys; + + protected MergedSelectionSet(Map subFields) { + this.subFields = subFields == null ? ImmutableMap.of() : subFields; + this.keys = ImmutableList.copyOf(this.subFields.keySet()); + } + + public Map getSubFields() { + return subFields; + } + + public List getSubFieldsList() { + return ImmutableList.copyOf(subFields.values()); + } + + public int size() { + return subFields.size(); + } + + public Set keySet() { + return subFields.keySet(); + } + + public MergedField getSubField(String key) { + return subFields.get(key); + } + + public List getKeys() { + return keys; + } + + public boolean isEmpty() { + return subFields.isEmpty(); + } + + public static Builder newMergedSelectionSet() { + return new Builder(); + } + + public static class Builder { + + private Map subFields; + + private Builder() { + } + + public Builder subFields(Map subFields) { + this.subFields = subFields; + return this; + } + + public MergedSelectionSet build() { + return new MergedSelectionSet(subFields); + } + + } + +} diff --git a/src/main/java/graphql/execution/NonNullableFieldValidator.java b/src/main/java/graphql/execution/NonNullableFieldValidator.java index 61419a579e..b59f633bac 100644 --- a/src/main/java/graphql/execution/NonNullableFieldValidator.java +++ b/src/main/java/graphql/execution/NonNullableFieldValidator.java @@ -1,29 +1,28 @@ package graphql.execution; +import graphql.GraphQLError; import graphql.Internal; /** - * This will check that a value is non null when the type definition says it must be and it will throw {@link NonNullableFieldWasNullException} + * This will check that a value is non-null when the type definition says it must be and, it will throw {@link NonNullableFieldWasNullException} * if this is not the case. * - * See: http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability + * See: https://spec.graphql.org/October2021/#sec-Errors-and-Non-Nullability */ @Internal public class NonNullableFieldValidator { private final ExecutionContext executionContext; - private final ExecutionTypeInfo typeInfo; - public NonNullableFieldValidator(ExecutionContext executionContext, ExecutionTypeInfo typeInfo) { + public NonNullableFieldValidator(ExecutionContext executionContext) { this.executionContext = executionContext; - this.typeInfo = typeInfo; } /** - * Called to check that a value is non null if the type requires it to be non null + * Called to check that a value is non-null if the type requires it to be non null * - * @param path the path to this place + * @param parameters the execution strategy parameters * @param result the result to check * @param the type of the result * @@ -31,10 +30,11 @@ public NonNullableFieldValidator(ExecutionContext executionContext, ExecutionTyp * * @throws NonNullableFieldWasNullException if the value is null but the type requires it to be non null */ - public T validate(ExecutionPath path, T result) throws NonNullableFieldWasNullException { + public T validate(ExecutionStrategyParameters parameters, T result) throws NonNullableFieldWasNullException { if (result == null) { - if (typeInfo.isNonNullType()) { - // see http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability + ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); + if (executionStepInfo.isNonNullType()) { + // see https://spec.graphql.org/October2021/#sec-Errors-and-Non-Nullability // // > If the field returns null because of an error which has already been added to the "errors" list in the response, // > the "errors" list must not be further affected. That is, only one error should be added to the errors list per field. @@ -46,9 +46,18 @@ public T validate(ExecutionPath path, T result) throws NonNullableFieldWasNu // // We will do this until the spec makes this more explicit. // - NonNullableFieldWasNullException nonNullException = new NonNullableFieldWasNullException(typeInfo, path); - executionContext.addError(new NonNullableFieldWasNullError(nonNullException), path); - throw nonNullException; + final ResultPath path = parameters.getPath(); + + NonNullableFieldWasNullException nonNullException = new NonNullableFieldWasNullException(executionStepInfo, path); + final GraphQLError error = new NonNullableFieldWasNullError(nonNullException); + if(parameters.getDeferredCallContext() != null) { + parameters.getDeferredCallContext().addError(error); + } else { + executionContext.addError(error, path); + } + if (executionContext.propagateErrorsOnNonNullContractFailure()) { + throw nonNullException; + } } } return result; diff --git a/src/main/java/graphql/execution/NonNullableFieldWasNullError.java b/src/main/java/graphql/execution/NonNullableFieldWasNullError.java index a2fce14dbd..2aab5529f2 100644 --- a/src/main/java/graphql/execution/NonNullableFieldWasNullError.java +++ b/src/main/java/graphql/execution/NonNullableFieldWasNullError.java @@ -3,6 +3,7 @@ import graphql.ErrorType; import graphql.GraphQLError; import graphql.GraphqlErrorHelper; +import graphql.Internal; import graphql.language.SourceLocation; import java.util.List; @@ -12,6 +13,7 @@ * * @see graphql.execution.NonNullableFieldWasNullException for details */ +@Internal public class NonNullableFieldWasNullError implements GraphQLError { private final String message; @@ -39,7 +41,7 @@ public List getLocations() { @Override public ErrorType getErrorType() { - return ErrorType.DataFetchingException; + return ErrorType.NullValueInNonNullableField; } @Override diff --git a/src/main/java/graphql/execution/NonNullableFieldWasNullException.java b/src/main/java/graphql/execution/NonNullableFieldWasNullException.java index e4b43c76fd..87324bb005 100644 --- a/src/main/java/graphql/execution/NonNullableFieldWasNullException.java +++ b/src/main/java/graphql/execution/NonNullableFieldWasNullException.java @@ -1,60 +1,75 @@ package graphql.execution; +import graphql.Internal; +import graphql.schema.GraphQLType; + import static graphql.Assert.assertNotNull; +import static graphql.schema.GraphQLTypeUtil.simplePrint; /** - * See (http://facebook.github.io/graphql/#sec-Errors-and-Non-Nullability), but if a non nullable field + * See (https://spec.graphql.org/October2021/#sec-Errors-and-Non-Nullability), but if a non nullable field * actually resolves to a null value and the parent type is nullable then the parent must in fact become null * so we use exceptions to indicate this special case */ +@Internal public class NonNullableFieldWasNullException extends RuntimeException { - private final ExecutionTypeInfo typeInfo; - private final ExecutionPath path; + private final ExecutionStepInfo executionStepInfo; + private final ResultPath path; - public NonNullableFieldWasNullException(ExecutionTypeInfo typeInfo, ExecutionPath path) { + public NonNullableFieldWasNullException(ExecutionStepInfo executionStepInfo, ResultPath path) { super( - mkMessage(assertNotNull(typeInfo), + mkMessage(assertNotNull(executionStepInfo), assertNotNull(path)) ); - this.typeInfo = typeInfo; + this.executionStepInfo = executionStepInfo; this.path = path; } public NonNullableFieldWasNullException(NonNullableFieldWasNullException previousException) { super( mkMessage( - assertNotNull(previousException.typeInfo.getParentTypeInfo()), - assertNotNull(previousException.typeInfo.getParentTypeInfo().getPath()) + assertNotNull(previousException.executionStepInfo.getParent()), + assertNotNull(previousException.executionStepInfo.getParent().getPath()) ), previousException ); - this.typeInfo = previousException.typeInfo.getParentTypeInfo(); - this.path = previousException.typeInfo.getParentTypeInfo().getPath(); + this.executionStepInfo = previousException.executionStepInfo.getParent(); + this.path = previousException.executionStepInfo.getParent().getPath(); } - private static String mkMessage(ExecutionTypeInfo typeInfo, ExecutionPath path) { - if (typeInfo.hasParentType()) { - return String.format("Cannot return null for non-nullable type: '%s' within parent '%s' (%s)", typeInfo.getType().getName(), typeInfo.getParentTypeInfo().getType().getName(), path); + private static String mkMessage(ExecutionStepInfo executionStepInfo, ResultPath path) { + GraphQLType unwrappedTyped = executionStepInfo.getUnwrappedNonNullType(); + if (executionStepInfo.hasParent()) { + GraphQLType unwrappedParentType = executionStepInfo.getParent().getUnwrappedNonNullType(); + return String.format( + "The field at path '%s' was declared as a non null type, but the code involved in retrieving" + + " data has wrongly returned a null value. The graphql specification requires that the" + + " parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on." + + " The non-nullable type is '%s' within parent type '%s'", + path, simplePrint(unwrappedTyped), simplePrint(unwrappedParentType)); + } else { + return String.format( + "The field at path '%s' was declared as a non null type, but the code involved in retrieving" + + " data has wrongly returned a null value. The graphql specification requires that the" + + " parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on." + + " The non-nullable type is '%s'", + path, simplePrint(unwrappedTyped)); } - return String.format("Cannot return null for non-nullable type: '%s' (%s)", typeInfo.getType().getName(), path); } - public ExecutionTypeInfo getTypeInfo() { - return typeInfo; + public ExecutionStepInfo getExecutionStepInfo() { + return executionStepInfo; } - public ExecutionPath getPath() { + public ResultPath getPath() { return path; } @Override public String toString() { - return "NonNullableFieldWasNullException{" + - " path=" + path + - " typeInfo=" + typeInfo + - '}'; + return getMessage(); } } diff --git a/src/main/java/graphql/execution/NonNullableValueCoercedAsNullException.java b/src/main/java/graphql/execution/NonNullableValueCoercedAsNullException.java index c0b2fe13e5..4dfb680815 100644 --- a/src/main/java/graphql/execution/NonNullableValueCoercedAsNullException.java +++ b/src/main/java/graphql/execution/NonNullableValueCoercedAsNullException.java @@ -1,36 +1,76 @@ package graphql.execution; -import static java.lang.String.format; - -import java.util.Collections; -import java.util.List; - import graphql.ErrorType; import graphql.GraphQLError; import graphql.GraphQLException; import graphql.PublicApi; import graphql.language.SourceLocation; import graphql.language.VariableDefinition; +import graphql.schema.GraphQLArgument; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLType; import graphql.schema.GraphQLTypeUtil; +import java.util.Collections; +import java.util.List; + +import static java.lang.String.format; + /** * This is thrown if a non nullable value is coerced to a null value */ @PublicApi public class NonNullableValueCoercedAsNullException extends GraphQLException implements GraphQLError { private List sourceLocations; + private List path; public NonNullableValueCoercedAsNullException(VariableDefinition variableDefinition, GraphQLType graphQLType) { super(format("Variable '%s' has coerced Null value for NonNull type '%s'", - variableDefinition.getName(), GraphQLTypeUtil.getUnwrappedTypeName(graphQLType))); + variableDefinition.getName(), GraphQLTypeUtil.simplePrint(graphQLType))); + this.sourceLocations = Collections.singletonList(variableDefinition.getSourceLocation()); + } + + public NonNullableValueCoercedAsNullException(VariableDefinition variableDefinition, String fieldName, GraphQLType graphQLType) { + super(format("Field '%s' of variable '%s' has coerced Null value for NonNull type '%s'", + fieldName, variableDefinition.getName(), GraphQLTypeUtil.simplePrint(graphQLType))); + this.sourceLocations = Collections.singletonList(variableDefinition.getSourceLocation()); + } + + public NonNullableValueCoercedAsNullException(VariableDefinition variableDefinition, String fieldName, List path, GraphQLType graphQLType) { + super(format("Field '%s' of variable '%s' has coerced Null value for NonNull type '%s'", + fieldName, variableDefinition.getName(), GraphQLTypeUtil.simplePrint(graphQLType))); this.sourceLocations = Collections.singletonList(variableDefinition.getSourceLocation()); + this.path = path; + } + + public NonNullableValueCoercedAsNullException(GraphQLType graphQLType) { + super(format("Coerced Null value for NonNull type '%s'", GraphQLTypeUtil.simplePrint(graphQLType))); + } + + public NonNullableValueCoercedAsNullException(VariableDefinition variableDefinition, String causeMessage) { + super(format("Variable '%s' has an invalid value: %s", variableDefinition.getName(), causeMessage)); + this.sourceLocations = Collections.singletonList(variableDefinition.getSourceLocation()); + } + + public NonNullableValueCoercedAsNullException(String fieldName, List path, GraphQLType graphQLType) { + super(format("Field '%s' has coerced Null value for NonNull type '%s'", + fieldName, GraphQLTypeUtil.simplePrint(graphQLType))); + this.path = path; } public NonNullableValueCoercedAsNullException(GraphQLInputObjectField inputTypeField) { super(format("Input field '%s' has coerced Null value for NonNull type '%s'", - inputTypeField.getName(), GraphQLTypeUtil.getUnwrappedTypeName(inputTypeField.getType()))); + inputTypeField.getName(), GraphQLTypeUtil.simplePrint(inputTypeField.getType()))); + } + + public NonNullableValueCoercedAsNullException(GraphQLInputObjectField inputTypeField, List path) { + super(format("Input field '%s' has coerced Null value for NonNull type '%s'", + inputTypeField.getName(), GraphQLTypeUtil.simplePrint(inputTypeField.getType()))); + this.path = path; + } + + public NonNullableValueCoercedAsNullException(GraphQLArgument graphQLArgument) { + super(format("Argument '%s' has coerced Null value for NonNull type '%s'", graphQLArgument.getName(), graphQLArgument.getType())); } @Override @@ -38,6 +78,11 @@ public List getLocations() { return sourceLocations; } + @Override + public List getPath() { + return path; + } + @Override public ErrorType getErrorType() { return ErrorType.ValidationError; diff --git a/src/main/java/graphql/execution/NormalizedVariables.java b/src/main/java/graphql/execution/NormalizedVariables.java new file mode 100644 index 0000000000..ef16fec3cf --- /dev/null +++ b/src/main/java/graphql/execution/NormalizedVariables.java @@ -0,0 +1,45 @@ +package graphql.execution; + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.normalized.NormalizedInputValue; + +import java.util.Map; + +/** + * Holds coerced variables, that is their values are now in a normalized {@link graphql.normalized.NormalizedInputValue} form. + */ +@PublicApi +public class NormalizedVariables { + private final ImmutableMapWithNullValues normalisedVariables; + + public NormalizedVariables(Map normalisedVariables) { + this.normalisedVariables = ImmutableMapWithNullValues.copyOf(normalisedVariables); + } + + public Map toMap() { + return normalisedVariables; + } + + public boolean containsKey(String key) { + return normalisedVariables.containsKey(key); + } + + public Object get(String key) { + return normalisedVariables.get(key); + } + + public static NormalizedVariables emptyVariables() { + return new NormalizedVariables(ImmutableKit.emptyMap()); + } + + public static NormalizedVariables of(Map normalisedVariables) { + return new NormalizedVariables(normalisedVariables); + } + + @Override + public String toString() { + return normalisedVariables.toString(); + } +} diff --git a/src/main/java/graphql/execution/OneOfNullValueException.java b/src/main/java/graphql/execution/OneOfNullValueException.java new file mode 100644 index 0000000000..40e5bbccae --- /dev/null +++ b/src/main/java/graphql/execution/OneOfNullValueException.java @@ -0,0 +1,30 @@ +package graphql.execution; + +import graphql.ErrorType; +import graphql.GraphQLError; +import graphql.GraphQLException; +import graphql.PublicApi; +import graphql.language.SourceLocation; + +import java.util.List; + +/** + * The input map to One Of Input Types MUST only have 1 entry with a non null value + */ +@PublicApi +public class OneOfNullValueException extends GraphQLException implements GraphQLError { + + public OneOfNullValueException(String message) { + super(message); + } + + @Override + public List getLocations() { + return null; + } + + @Override + public ErrorType getErrorType() { + return ErrorType.ValidationError; + } +} diff --git a/src/main/java/graphql/execution/OneOfTooManyKeysException.java b/src/main/java/graphql/execution/OneOfTooManyKeysException.java new file mode 100644 index 0000000000..f8d3c0053a --- /dev/null +++ b/src/main/java/graphql/execution/OneOfTooManyKeysException.java @@ -0,0 +1,30 @@ +package graphql.execution; + +import graphql.ErrorType; +import graphql.GraphQLError; +import graphql.GraphQLException; +import graphql.PublicApi; +import graphql.language.SourceLocation; + +import java.util.List; + +/** + * The input map to One Of Input Types MUST only have 1 entry + */ +@PublicApi +public class OneOfTooManyKeysException extends GraphQLException implements GraphQLError { + + public OneOfTooManyKeysException(String message) { + super(message); + } + + @Override + public List getLocations() { + return null; + } + + @Override + public ErrorType getErrorType() { + return ErrorType.ValidationError; + } +} diff --git a/src/main/java/graphql/execution/RawVariables.java b/src/main/java/graphql/execution/RawVariables.java new file mode 100644 index 0000000000..4ebfa27f2a --- /dev/null +++ b/src/main/java/graphql/execution/RawVariables.java @@ -0,0 +1,48 @@ +package graphql.execution; + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.collect.ImmutableMapWithNullValues; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.Map; + +/** + * Holds raw variables, which have not been coerced yet into {@link CoercedVariables} + */ +@PublicApi +@NullMarked +public class RawVariables { + private static final RawVariables EMPTY = RawVariables.of(ImmutableKit.emptyMap()); + private final ImmutableMapWithNullValues rawVariables; + + public RawVariables(Map rawVariables) { + this.rawVariables = ImmutableMapWithNullValues.copyOf(rawVariables); + } + + public Map toMap() { + return rawVariables; + } + + public boolean containsKey(String key) { + return rawVariables.containsKey(key); + } + + public @Nullable Object get(String key) { + return rawVariables.get(key); + } + + public static RawVariables emptyVariables() { + return EMPTY; + } + + public static RawVariables of(Map rawVariables) { + return new RawVariables(rawVariables); + } + + @Override + public String toString() { + return rawVariables.toString(); + } +} diff --git a/src/main/java/graphql/execution/ResolveType.java b/src/main/java/graphql/execution/ResolveType.java new file mode 100644 index 0000000000..3ef9c556fb --- /dev/null +++ b/src/main/java/graphql/execution/ResolveType.java @@ -0,0 +1,72 @@ +package graphql.execution; + +import graphql.Assert; +import graphql.Internal; +import graphql.TypeResolutionEnvironment; +import graphql.normalized.ExecutableNormalizedField; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.schema.DataFetchingFieldSelectionSet; +import graphql.schema.DataFetchingFieldSelectionSetImpl; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLUnionType; +import graphql.schema.TypeResolver; + +import java.util.function.Supplier; + +@Internal +public class ResolveType { + + public GraphQLObjectType resolveType(ExecutionContext executionContext, MergedField field, Object source, ExecutionStepInfo executionStepInfo, GraphQLType fieldType, Object localContext) { + Assert.assertTrue(fieldType instanceof GraphQLInterfaceType || fieldType instanceof GraphQLUnionType, + () -> "The passed in fieldType MUST be an interface or union type : " + fieldType.getClass().getName()); + DataFetchingFieldSelectionSet fieldSelectionSet = buildSelectionSet(executionContext, field, (GraphQLOutputType) fieldType, executionStepInfo); + TypeResolutionEnvironment env = TypeResolutionParameters.newParameters() + .field(field) + .fieldType(fieldType) + .value(source) + .argumentValues(executionStepInfo::getArguments) + .selectionSet(fieldSelectionSet) + .context(executionContext.getContext()) + .graphQLContext(executionContext.getGraphQLContext()) + .localContext(localContext) + .schema(executionContext.getGraphQLSchema()) + .build(); + if (fieldType instanceof GraphQLInterfaceType) { + return resolveTypeForInterface(env, (GraphQLInterfaceType) fieldType); + } else { + return resolveTypeForUnion(env, (GraphQLUnionType) fieldType); + } + } + + private DataFetchingFieldSelectionSet buildSelectionSet(ExecutionContext executionContext, MergedField field, GraphQLOutputType fieldType, ExecutionStepInfo executionStepInfo) { + Supplier normalizedQuery = executionContext.getNormalizedQueryTree(); + Supplier normalizedFieldSupplier = () -> normalizedQuery.get().getNormalizedField(field, executionStepInfo.getObjectType(), executionStepInfo.getPath()); + return DataFetchingFieldSelectionSetImpl.newCollector(executionContext.getGraphQLSchema(), fieldType, normalizedFieldSupplier); + } + + public GraphQLObjectType resolveTypeForInterface(TypeResolutionEnvironment env, GraphQLInterfaceType abstractType) { + TypeResolver typeResolver = env.getSchema().getCodeRegistry().getTypeResolver(abstractType); + return resolveAbstractType(env, typeResolver, abstractType); + } + + public GraphQLObjectType resolveTypeForUnion(TypeResolutionEnvironment env, GraphQLUnionType abstractType) { + TypeResolver typeResolver = env.getSchema().getCodeRegistry().getTypeResolver(abstractType); + return resolveAbstractType(env, typeResolver, abstractType); + } + + private GraphQLObjectType resolveAbstractType(TypeResolutionEnvironment env, TypeResolver typeResolver, GraphQLNamedOutputType abstractType) { + GraphQLObjectType result = typeResolver.getType(env); + if (result == null) { + throw new UnresolvedTypeException(abstractType); + } + if (!env.getSchema().isPossibleType(abstractType, result)) { + throw new UnresolvedTypeException(abstractType, result); + } + return result; + } + +} diff --git a/src/main/java/graphql/execution/ResponseMapFactory.java b/src/main/java/graphql/execution/ResponseMapFactory.java new file mode 100644 index 0000000000..01a37d8491 --- /dev/null +++ b/src/main/java/graphql/execution/ResponseMapFactory.java @@ -0,0 +1,32 @@ +package graphql.execution; + +import graphql.ExperimentalApi; +import graphql.PublicSpi; + +import java.util.List; +import java.util.Map; + +/** + * Allows to customize the concrete class {@link Map} implementation. For example, it could be possible to use + * memory-efficient implementations, like eclipse-collections. + */ +@ExperimentalApi +@PublicSpi +public interface ResponseMapFactory { + + /** + * The default implementation uses JDK's {@link java.util.LinkedHashMap}. + */ + ResponseMapFactory DEFAULT = new DefaultResponseMapFactory(); + + /** + * The general contract is that the resulting map keeps the insertion orders of keys. Values are nullable but keys are not. + * Implementations are free to create or to reuse map instances. + * + * @param keys the keys like k1, k2, ..., kn + * @param values the values like v1, v2, ..., vn + * @return a new or reused map instance with (k1,v1), (k2, v2), ... (kn, vn) + */ + Map createInsertionOrdered(List keys, List values); + +} diff --git a/src/main/java/graphql/execution/ResultNodesInfo.java b/src/main/java/graphql/execution/ResultNodesInfo.java new file mode 100644 index 0000000000..afc366f6be --- /dev/null +++ b/src/main/java/graphql/execution/ResultNodesInfo.java @@ -0,0 +1,55 @@ +package graphql.execution; + +import graphql.Internal; +import graphql.PublicApi; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * This class is used to track the number of result nodes that have been created during execution. + * After each execution the GraphQLContext contains a ResultNodeInfo object under the key {@link ResultNodesInfo#RESULT_NODES_INFO} + *

+ * The number of result can be limited (and should be for security reasons) by setting the maximum number of result nodes + * in the GraphQLContext under the key {@link ResultNodesInfo#MAX_RESULT_NODES} to an Integer + *

+ */ +@PublicApi +public class ResultNodesInfo { + + public static final String MAX_RESULT_NODES = "__MAX_RESULT_NODES"; + public static final String RESULT_NODES_INFO = "__RESULT_NODES_INFO"; + + private volatile boolean maxResultNodesExceeded = false; + private final AtomicInteger resultNodesCount = new AtomicInteger(0); + + @Internal + public int incrementAndGetResultNodesCount() { + return resultNodesCount.incrementAndGet(); + } + + @Internal + public void maxResultNodesExceeded() { + this.maxResultNodesExceeded = true; + } + + /** + * The number of result nodes created. + * Note: this can be higher than max result nodes because + * a each node that exceeds the number of max nodes is set to null, + * but still is a result node (with value null) + * + * @return number of result nodes created + */ + public int getResultNodesCount() { + return resultNodesCount.get(); + } + + /** + * If the number of result nodes has exceeded the maximum allowed numbers. + * + * @return true if the number of result nodes has exceeded the maximum allowed numbers + */ + public boolean isMaxResultNodesExceeded() { + return maxResultNodesExceeded; + } +} diff --git a/src/main/java/graphql/execution/ResultPath.java b/src/main/java/graphql/execution/ResultPath.java new file mode 100644 index 0000000000..696bfbc7f1 --- /dev/null +++ b/src/main/java/graphql/execution/ResultPath.java @@ -0,0 +1,359 @@ +package graphql.execution; + +import com.google.common.collect.ImmutableList; +import graphql.AssertException; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.StringTokenizer; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static java.lang.String.format; + + +/** + * As a graphql query is executed, each field forms a hierarchical path from parent field to child field and this + * class represents that path as a series of segments. + */ +@PublicApi +public class ResultPath { + private static final ResultPath ROOT_PATH = new ResultPath(); + + /** + * All paths start from here + * + * @return the root path + */ + public static ResultPath rootPath() { + return ROOT_PATH; + } + + private final ResultPath parent; + private final Object segment; + + // hash is effective immutable but lazily initialized similar to the hash code of java.lang.String + private int hash; + private final String toStringValue; + private final int level; + + private ResultPath() { + parent = null; + segment = null; + this.level = 0; + this.toStringValue = initString(); + } + + private ResultPath(ResultPath parent, String segment) { + this.parent = assertNotNull(parent, "Must provide a parent path"); + this.segment = assertNotNull(segment, "Must provide a sub path"); + this.toStringValue = initString(); + this.level = parent.level + 1; + } + + private ResultPath(ResultPath parent, int segment) { + this.parent = assertNotNull(parent, "Must provide a parent path"); + this.segment = segment; + this.toStringValue = initString(); + this.level = parent.level; + } + + private String initString() { + if (parent == null) { + return ""; + } + + if (ROOT_PATH.equals(parent)) { + return segmentToString(); + } + return parent + segmentToString(); + + } + + public int getLevel() { + return level; + } + + public ResultPath getPathWithoutListEnd() { + if (ROOT_PATH.equals(this)) { + return ROOT_PATH; + } + if (segment instanceof String) { + return this; + } + return parent; + } + + /** + * @return true if the end of the path has a list style segment eg 'a/b[2]' + */ + public boolean isListSegment() { + return segment instanceof Integer; + } + + /** + * @return true if the end of the path has a named style segment eg 'a/b[2]/c' + */ + public boolean isNamedSegment() { + return segment instanceof String; + } + + + public String getSegmentName() { + return (String) segment; + } + + public int getSegmentIndex() { + return (int) segment; + } + + public Object getSegmentValue() { + return segment; + } + + public ResultPath getParent() { + return parent; + } + + /** + * Parses an execution path from the provided path string in the format /segment1/segment2[index]/segmentN + * + * @param pathString the path string + * + * @return a parsed execution path + */ + public static ResultPath parse(String pathString) { + pathString = pathString == null ? "" : pathString; + String finalPathString = pathString.trim(); + StringTokenizer st = new StringTokenizer(finalPathString, "/[]", true); + ResultPath path = ResultPath.rootPath(); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if ("/".equals(token)) { + assertTrue(st.hasMoreTokens(), mkErrMsg(), finalPathString); + path = path.segment(st.nextToken()); + } else if ("[".equals(token)) { + assertTrue(st.countTokens() >= 2, mkErrMsg(), finalPathString); + path = path.segment(Integer.parseInt(st.nextToken())); + String closingBrace = st.nextToken(); + assertTrue(closingBrace.equals("]"), mkErrMsg(), finalPathString); + } else { + throw new AssertException(format(mkErrMsg(), pathString)); + } + } + return path; + } + + /** + * This will create an execution path from the list of objects + * + * @param objects the path objects + * + * @return a new execution path + */ + public static ResultPath fromList(List objects) { + assertNotNull(objects); + ResultPath path = ResultPath.rootPath(); + for (Object object : objects) { + if (object instanceof String) { + path = path.segment(((String) object)); + } else if (object instanceof Integer) { + path = path.segment((int) object); + } else if (object != null) { + path = path.segment(object.toString()); + } + } + return path; + } + + private static String mkErrMsg() { + return "Invalid path string : '%s'"; + } + + /** + * Takes the current path and adds a new segment to it, returning a new path + * + * @param segment the string path segment to add + * + * @return a new path containing that segment + */ + public ResultPath segment(String segment) { + return new ResultPath(this, segment); + } + + /** + * Takes the current path and adds a new segment to it, returning a new path + * + * @param segment the int path segment to add + * + * @return a new path containing that segment + */ + public ResultPath segment(int segment) { + return new ResultPath(this, segment); + } + + /** + * Drops the last segment off the path + * + * @return a new path with the last segment dropped off + */ + public ResultPath dropSegment() { + if (this == rootPath()) { + return null; + } + return this.parent; + } + + /** + * Replaces the last segment on the path eg ResultPath.parse("/a/b[1]").replaceSegment(9) + * equals "/a/b[9]" + * + * @param segment the integer segment to use + * + * @return a new path with the last segment replaced + */ + public ResultPath replaceSegment(int segment) { + assertTrue(!ROOT_PATH.equals(this), "You MUST not call this with the root path"); + return new ResultPath(parent, segment); + } + + /** + * Replaces the last segment on the path eg ResultPath.parse("/a/b[1]").replaceSegment("x") + * equals "/a/b/x" + * + * @param segment the string segment to use + * + * @return a new path with the last segment replaced + */ + public ResultPath replaceSegment(String segment) { + assertTrue(!ROOT_PATH.equals(this), "You MUST not call this with the root path"); + return new ResultPath(parent, segment); + } + + + /** + * @return true if the path is the {@link #rootPath()} + */ + public boolean isRootPath() { + return this == ROOT_PATH; + } + + /** + * Appends the provided path to the current one + * + * @param path the path to append + * + * @return a new path + */ + public ResultPath append(ResultPath path) { + List objects = new ArrayList<>(this.toList()); + objects.addAll(assertNotNull(path).toList()); + return fromList(objects); + } + + + public ResultPath sibling(String siblingField) { + assertTrue(!ROOT_PATH.equals(this), "You MUST not call this with the root path"); + return new ResultPath(this.parent, siblingField); + } + + public ResultPath sibling(int siblingField) { + assertTrue(!ROOT_PATH.equals(this), "You MUST not call this with the root path"); + return new ResultPath(this.parent, siblingField); + } + + /** + * @return converts the path into a list of segments + */ + public List toList() { + if (parent == null) { + return ImmutableKit.emptyList(); + } + LinkedList list = new LinkedList<>(); + ResultPath p = this; + while (p.segment != null) { + list.addFirst(p.segment); + p = p.parent; + } + return ImmutableList.copyOf(list); + } + + /** + * @return this path as a list of result keys, without any indices + */ + public List getKeysOnly() { + if (parent == null) { + return new LinkedList<>(); + } + LinkedList list = new LinkedList<>(); + ResultPath p = this; + while (p.segment != null) { + if (p.segment instanceof String) { + list.addFirst((String) p.segment); + } + p = p.parent; + } + return list; + } + + + /** + * @return the path as a string which represents the call hierarchy + */ + @Override + public String toString() { + return toStringValue; + } + + public String segmentToString() { + if (segment instanceof String) { + return "/" + segment; + } else { + return "[" + segment + "]"; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ResultPath self = this; + ResultPath that = (ResultPath) o; + while (self.segment != null && that.segment != null) { + if (!Objects.equals(self.segment, that.segment)) { + return false; + } + self = self.parent; + that = that.parent; + } + + return self.isRootPath() && that.isRootPath(); + } + + @Override + public int hashCode() { + int h = hash; + if (h == 0) { + h = 1; + ResultPath self = this; + while (self != null) { + Object value = self.segment; + h = 31 * h + (value == null ? 0 : value.hashCode()); + self = self.parent; + } + hash = h; + } + return h; + } + + +} diff --git a/src/main/java/graphql/execution/SimpleDataFetcherExceptionHandler.java b/src/main/java/graphql/execution/SimpleDataFetcherExceptionHandler.java index 222a81ac62..79e201a333 100644 --- a/src/main/java/graphql/execution/SimpleDataFetcherExceptionHandler.java +++ b/src/main/java/graphql/execution/SimpleDataFetcherExceptionHandler.java @@ -1,25 +1,59 @@ package graphql.execution; import graphql.ExceptionWhileDataFetching; +import graphql.PublicApi; import graphql.language.SourceLocation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; /** * The standard handling of data fetcher error involves placing a {@link ExceptionWhileDataFetching} error * into the error collection */ +@PublicApi public class SimpleDataFetcherExceptionHandler implements DataFetcherExceptionHandler { - private static final Logger log = LoggerFactory.getLogger(SimpleDataFetcherExceptionHandler.class); - @Override - public void accept(DataFetcherExceptionHandlerParameters handlerParameters) { - Throwable exception = handlerParameters.getException(); - SourceLocation sourceLocation = handlerParameters.getField().getSourceLocation(); - ExecutionPath path = handlerParameters.getPath(); + static final SimpleDataFetcherExceptionHandler defaultImpl = new SimpleDataFetcherExceptionHandler(); + + private DataFetcherExceptionHandlerResult handleExceptionImpl(DataFetcherExceptionHandlerParameters handlerParameters) { + Throwable exception = unwrap(handlerParameters.getException()); + SourceLocation sourceLocation = handlerParameters.getSourceLocation(); + ResultPath path = handlerParameters.getPath(); ExceptionWhileDataFetching error = new ExceptionWhileDataFetching(path, exception, sourceLocation); - handlerParameters.getExecutionContext().addError(error); - log.warn(error.getMessage(), exception); + logException(error, exception); + + return DataFetcherExceptionHandlerResult.newResult().error(error).build(); + } + + @Override + public CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { + return CompletableFuture.completedFuture(handleExceptionImpl(handlerParameters)); + } + + /** + * Called to log the exception - a subclass could choose to something different in logging terms + * + * @param error the graphql error + * @param exception the exception that happened + */ + protected void logException(ExceptionWhileDataFetching error, Throwable exception) { + } + + /** + * Called to unwrap an exception to a more suitable cause if required. + * + * @param exception the exception to unwrap + * + * @return the suitable exception + */ + protected Throwable unwrap(Throwable exception) { + if (exception.getCause() != null) { + if (exception instanceof CompletionException) { + return exception.getCause(); + } + } + return exception; } } diff --git a/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java b/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java index 9509183af6..f1e1a9a919 100644 --- a/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java +++ b/src/main/java/graphql/execution/SubscriptionExecutionStrategy.java @@ -1,31 +1,55 @@ package graphql.execution; +import graphql.Assert; import graphql.ExecutionResult; import graphql.ExecutionResultImpl; -import graphql.execution.reactive.CompletionStageMappingPublisher; +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.execution.incremental.AlternativeCallContext; +import graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext; +import graphql.execution.instrumentation.Instrumentation; +import graphql.execution.instrumentation.InstrumentationContext; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationReactiveResultsParameters; +import graphql.execution.reactive.SubscriptionPublisher; import graphql.language.Field; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import org.reactivestreams.FlowAdapters; import org.reactivestreams.Publisher; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; +import java.util.function.Function; -import static graphql.Assert.assertTrue; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.nonNullCtx; import static java.util.Collections.singletonMap; /** * An execution strategy that implements graphql subscriptions by using reactive-streams * as the output result of the subscription query. - * + *

* Afterwards each object delivered on that stream will be mapped via running the original selection set over that object and hence producing an ExecutionResult * just like a normal graphql query. - * - * See https://github.com/facebook/graphql/blob/master/spec/Section%206%20--%20Execution.md - * See http://www.reactive-streams.org/ + *

+ * See https://spec.graphql.org/draft/#sec-Subscription + *

+ * See https://www.reactive-streams.org/ */ +@PublicApi public class SubscriptionExecutionStrategy extends ExecutionStrategy { + /** + * If a boolean value is placed into the {@link GraphQLContext} with this key then the order + * of the subscription events can be controlled. By default, subscription events are published + * as the graphql subselection calls complete, and not in the order they originally arrived from the + * source publisher. But this can be changed to {@link Boolean#TRUE} to keep them in order. + */ + public static final String KEEP_SUBSCRIPTION_EVENTS_ORDERED = "KEEP_SUBSCRIPTION_EVENTS_ORDERED"; + public SubscriptionExecutionStrategy() { super(); } @@ -36,23 +60,45 @@ public SubscriptionExecutionStrategy(DataFetcherExceptionHandler dataFetcherExce @Override public CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { + Instrumentation instrumentation = executionContext.getInstrumentation(); + InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters); + ExecutionStrategyInstrumentationContext executionStrategyCtx = ExecutionStrategyInstrumentationContext.nonNullCtx(instrumentation.beginExecutionStrategy( + instrumentationParameters, + executionContext.getInstrumentationState() + )); CompletableFuture> sourceEventStream = createSourceEventStream(executionContext, parameters); // // when the upstream source event stream completes, subscribe to it and wire in our adapter - return sourceEventStream.thenApply((publisher) -> { + CompletableFuture overallResult = sourceEventStream.thenApply((publisher) -> + { if (publisher == null) { return new ExecutionResultImpl(null, executionContext.getErrors()); } - CompletionStageMappingPublisher mapSourceToResponse = new CompletionStageMappingPublisher<>( - publisher, - eventPayload -> executeSubscriptionEvent(executionContext, parameters, eventPayload) - ); + Function> mapperFunction = eventPayload -> executeSubscriptionEvent(executionContext, parameters, eventPayload); + boolean keepOrdered = keepOrdered(executionContext.getGraphQLContext()); + + InstrumentationReactiveResultsParameters instrumentationReactiveResultsParameters = new InstrumentationReactiveResultsParameters(executionContext, InstrumentationReactiveResultsParameters.ResultType.SUBSCRIPTION); + InstrumentationContext reactiveCtx = nonNullCtx(executionContext.getInstrumentation().beginReactiveResults(instrumentationReactiveResultsParameters, executionContext.getInstrumentationState())); + reactiveCtx.onDispatched(); + + SubscriptionPublisher mapSourceToResponse = new SubscriptionPublisher(publisher, mapperFunction, keepOrdered, + throwable -> reactiveCtx.onCompleted(null, throwable)); return new ExecutionResultImpl(mapSourceToResponse, executionContext.getErrors()); }); + + // dispatched the subscription query + executionStrategyCtx.onDispatched(); + overallResult.whenComplete(executionStrategyCtx::onCompleted); + return overallResult; } + private boolean keepOrdered(GraphQLContext graphQLContext) { + return graphQLContext.getOrDefault(KEEP_SUBSCRIPTION_EVENTS_ORDERED, false); + } + + /* https://github.com/facebook/graphql/blob/master/spec/Section%206%20--%20Execution.md @@ -68,18 +114,38 @@ public CompletableFuture execute(ExecutionContext executionCont */ private CompletableFuture> createSourceEventStream(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(parameters); + ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(executionContext, parameters, false); - CompletableFuture fieldFetched = fetchField(executionContext, newParameters); - return fieldFetched.thenApply(publisher -> { - if (publisher != null) { - assertTrue(publisher instanceof Publisher, "You data fetcher must return a Publisher of events when using graphql subscriptions"); - } - //noinspection unchecked - return (Publisher) publisher; + CompletableFuture fieldFetched = Async.toCompletableFuture(fetchField(executionContext, newParameters)); + return fieldFetched.thenApply(fetchedValue -> { + Object publisher = FetchedValue.getFetchedValue(fetchedValue); + return mkReactivePublisher(publisher); }); } + /** + * The user code can return either a reactive stream {@link Publisher} or a JDK {@link Flow.Publisher} + * and we adapt it to a reactive streams one since we use reactive streams in our implementation. + * + * @param publisherObj - the object returned from the data fetcher as the source of events + * + * @return a reactive streams {@link Publisher} always + */ + @SuppressWarnings("unchecked") + private static Publisher mkReactivePublisher(Object publisherObj) { + if (publisherObj != null) { + if (publisherObj instanceof Publisher) { + return (Publisher) publisherObj; + } else if (publisherObj instanceof Flow.Publisher) { + Flow.Publisher flowPublisher = (Flow.Publisher) publisherObj; + return FlowAdapters.toPublisher(flowPublisher); + } else { + return Assert.assertShouldNeverHappen("Your data fetcher must return a Publisher of events when using graphql subscriptions"); + } + } + return null; // null is valid - we return null data in this case + } + /* ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue): @@ -94,12 +160,41 @@ private CompletableFuture> createSourceEventStream(ExecutionCo */ private CompletableFuture executeSubscriptionEvent(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object eventPayload) { - ExecutionContext newExecutionContext = executionContext.transform(builder -> builder.root(eventPayload)); - ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(parameters); + Instrumentation instrumentation = executionContext.getInstrumentation(); - return completeField(newExecutionContext, newParameters, eventPayload).getFieldValue() + ExecutionContext newExecutionContext = executionContext.transform(builder -> builder + .root(eventPayload) + .resetErrors() + ); + ExecutionStrategyParameters newParameters = firstFieldOfSubscriptionSelection(newExecutionContext, parameters, true); + ExecutionStepInfo subscribedFieldStepInfo = createSubscribedFieldStepInfo(executionContext, newParameters); + + InstrumentationFieldParameters i13nFieldParameters = new InstrumentationFieldParameters(executionContext, () -> subscribedFieldStepInfo); + InstrumentationContext subscribedFieldCtx = nonNullCtx(instrumentation.beginSubscribedFieldEvent( + i13nFieldParameters, executionContext.getInstrumentationState() + )); + + + executionContext.getDataLoaderDispatcherStrategy().newSubscriptionExecution(newParameters.getDeferredCallContext()); + Object fetchedValue = unboxPossibleDataFetcherResult(newExecutionContext, newParameters, eventPayload); + FieldValueInfo fieldValueInfo = completeField(newExecutionContext, newParameters, fetchedValue); + executionContext.getDataLoaderDispatcherStrategy().subscriptionEventCompletionDone(newParameters.getDeferredCallContext()); + CompletableFuture overallResult = fieldValueInfo + .getFieldValueFuture() + .thenApply(val -> new ExecutionResultImpl(val, newParameters.getDeferredCallContext().getErrors())) .thenApply(executionResult -> wrapWithRootFieldName(newParameters, executionResult)); + + // dispatch instrumentation so they can know about each subscription event + subscribedFieldCtx.onDispatched(); + overallResult.whenComplete(subscribedFieldCtx::onCompleted); + + // allow them to instrument each ER should they want to + InstrumentationExecutionParameters i13nExecutionParameters = new InstrumentationExecutionParameters( + executionContext.getExecutionInput(), executionContext.getGraphQLSchema()); + + overallResult = overallResult.thenCompose(executionResult -> instrumentation.instrumentExecutionResult(executionResult, i13nExecutionParameters, executionContext.getInstrumentationState())); + return overallResult; } private ExecutionResult wrapWithRootFieldName(ExecutionStrategyParameters parameters, ExecutionResult executionResult) { @@ -111,18 +206,37 @@ private ExecutionResult wrapWithRootFieldName(ExecutionStrategyParameters parame } private String getRootFieldName(ExecutionStrategyParameters parameters) { - Field rootField = parameters.getField().get(0); - return rootField.getAlias() != null ? rootField.getAlias() : rootField.getName(); + Field rootField = parameters.getField().getSingleField(); + return rootField.getResultKey(); } - private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionStrategyParameters parameters) { - Map> fields = parameters.getFields(); - List fieldNames = new ArrayList<>(fields.keySet()); + private ExecutionStrategyParameters firstFieldOfSubscriptionSelection(ExecutionContext executionContext, + ExecutionStrategyParameters parameters, + boolean newCallContext) { + MergedSelectionSet fields = parameters.getFields(); + MergedField firstField = fields.getSubField(fields.getKeys().get(0)); - List firstField = fields.get(fieldNames.get(0)); + ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(firstField.getSingleField())); + NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext); + + + return parameters.transform(builder -> { + builder + .field(firstField) + .path(fieldPath) + .nonNullFieldValidator(nonNullableFieldValidator); + if (newCallContext) { + builder.deferredCallContext(new AlternativeCallContext(1, 1)); + } + }); - ExecutionPath fieldPath = parameters.getPath().segment(firstField.get(0).getName()); - return parameters.transform(builder -> builder.field(firstField).path(fieldPath)); } + private ExecutionStepInfo createSubscribedFieldStepInfo(ExecutionContext + executionContext, ExecutionStrategyParameters parameters) { + Field field = parameters.getField().getSingleField(); + GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs(); + GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field); + return createExecutionStepInfo(executionContext, parameters, fieldDef, parentType); + } } diff --git a/src/main/java/graphql/execution/TypeResolutionParameters.java b/src/main/java/graphql/execution/TypeResolutionParameters.java index f5e3934660..4f20fac4fd 100644 --- a/src/main/java/graphql/execution/TypeResolutionParameters.java +++ b/src/main/java/graphql/execution/TypeResolutionParameters.java @@ -1,43 +1,51 @@ package graphql.execution; -import graphql.language.Field; -import graphql.schema.GraphQLInterfaceType; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.TypeResolutionEnvironment; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.schema.DataFetchingFieldSelectionSet; import graphql.schema.GraphQLSchema; -import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphQLType; import java.util.Map; +import java.util.function.Supplier; +/** + * This class is a classic builder style one that SHOULD have been on have been on {@link TypeResolutionEnvironment} + * but for legacy reasons was not. So it acts as the builder of {@link TypeResolutionEnvironment} objects + */ +@Internal public class TypeResolutionParameters { - private final GraphQLInterfaceType graphQLInterfaceType; - private final GraphQLUnionType graphQLUnionType; - private final Field field; + private final MergedField field; + private final GraphQLType fieldType; private final Object value; - private final Map argumentValues; + private final Supplier> argumentValues; private final GraphQLSchema schema; private final Object context; - - private TypeResolutionParameters(GraphQLInterfaceType graphQLInterfaceType, GraphQLUnionType graphQLUnionType, - Field field, Object value, Map argumentValues, GraphQLSchema schema, final Object context) { - this.graphQLInterfaceType = graphQLInterfaceType; - this.graphQLUnionType = graphQLUnionType; - this.field = field; - this.value = value; - this.argumentValues = argumentValues; - this.schema = schema; - this.context = context; - } - - public GraphQLInterfaceType getGraphQLInterfaceType() { - return graphQLInterfaceType; + private final Object localContext; + private final GraphQLContext graphQLContext; + private final DataFetchingFieldSelectionSet selectionSet; + + private TypeResolutionParameters(Builder builder) { + this.field = builder.field; + this.fieldType = builder.fieldType; + this.value = builder.value; + this.argumentValues = builder.argumentValues; + this.schema = builder.schema; + this.context = builder.context; + this.graphQLContext = builder.graphQLContext; + this.localContext = builder.localContext; + this.selectionSet = builder.selectionSet; } - public GraphQLUnionType getGraphQLUnionType() { - return graphQLUnionType; + public MergedField getField() { + return field; } - public Field getField() { - return field; + public GraphQLType getFieldType() { + return fieldType; } public Object getValue() { @@ -45,43 +53,58 @@ public Object getValue() { } public Map getArgumentValues() { - return argumentValues; + return argumentValues.get(); } public GraphQLSchema getSchema() { return schema; } + public DataFetchingFieldSelectionSet getSelectionSet() { + return selectionSet; + } + public static Builder newParameters() { return new Builder(); } + /** + * @return the legacy context object + * + * @deprecated use {@link #getGraphQLContext()} instead + */ + @Deprecated(since = "2021-07-05") public Object getContext() { return context; } + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + public Object getLocalContext() { + return localContext; + } + public static class Builder { - private Field field; - private GraphQLInterfaceType graphQLInterfaceType; - private GraphQLUnionType graphQLUnionType; + private MergedField field; + private GraphQLType fieldType; private Object value; - private Map argumentValues; + private Supplier> argumentValues; private GraphQLSchema schema; private Object context; + private GraphQLContext graphQLContext; + private Object localContext; + private DataFetchingFieldSelectionSet selectionSet; - public Builder field(Field field) { + public Builder field(MergedField field) { this.field = field; return this; } - public Builder graphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType) { - this.graphQLInterfaceType = graphQLInterfaceType; - return this; - } - - public Builder graphQLUnionType(GraphQLUnionType graphQLUnionType) { - this.graphQLUnionType = graphQLUnionType; + public Builder fieldType(GraphQLType fieldType) { + this.fieldType = fieldType; return this; } @@ -90,8 +113,8 @@ public Builder value(Object value) { return this; } - public Builder argumentValues(Map argumentValues) { - this.argumentValues = argumentValues; + public Builder argumentValues(Supplier> argumentValues) { + this.argumentValues = () -> ImmutableMapWithNullValues.copyOf(argumentValues.get()); return this; } @@ -100,13 +123,31 @@ public Builder schema(GraphQLSchema schema) { return this; } + @Deprecated(since = "2021-07-05") public Builder context(Object context) { this.context = context; return this; } - public TypeResolutionParameters build() { - return new TypeResolutionParameters(graphQLInterfaceType, graphQLUnionType, field, value, argumentValues, schema, context); + public Builder graphQLContext(GraphQLContext context) { + this.graphQLContext = context; + return this; + } + + public Builder localContext(Object localContext) { + this.localContext = localContext; + return this; + } + + public Builder selectionSet(DataFetchingFieldSelectionSet selectionSet) { + this.selectionSet = selectionSet; + return this; + } + + public TypeResolutionEnvironment build() { + // this build should have always been in TypeResolutionEnvironment but this little workaround improves it a smidge, + // and we can fix it up later so this class is redundant + return new TypeResolutionEnvironment(new TypeResolutionParameters(this)); } } } diff --git a/src/main/java/graphql/execution/UnknownOperationException.java b/src/main/java/graphql/execution/UnknownOperationException.java index 5eb5b67e66..6ef523c9b1 100644 --- a/src/main/java/graphql/execution/UnknownOperationException.java +++ b/src/main/java/graphql/execution/UnknownOperationException.java @@ -1,7 +1,13 @@ package graphql.execution; +import graphql.ErrorClassification; +import graphql.ErrorType; +import graphql.GraphQLError; import graphql.GraphQLException; import graphql.PublicApi; +import graphql.language.SourceLocation; + +import java.util.List; /** * This is thrown if multiple operations are defined in the query and @@ -9,9 +15,18 @@ * contained in the GraphQL query. */ @PublicApi -public class UnknownOperationException extends GraphQLException { - +public class UnknownOperationException extends GraphQLException implements GraphQLError { public UnknownOperationException(String message) { super(message); } + + @Override + public List getLocations() { + return null; + } + + @Override + public ErrorClassification getErrorType() { + return ErrorType.ValidationError; + } } diff --git a/src/main/java/graphql/execution/UnresolvedTypeException.java b/src/main/java/graphql/execution/UnresolvedTypeException.java index 929c33dd53..4a6aad47d6 100644 --- a/src/main/java/graphql/execution/UnresolvedTypeException.java +++ b/src/main/java/graphql/execution/UnresolvedTypeException.java @@ -2,8 +2,9 @@ import graphql.GraphQLException; import graphql.PublicApi; -import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLNamedOutputType; import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; /** * This is thrown if a {@link graphql.schema.TypeResolver} fails to give back a concrete type @@ -12,7 +13,7 @@ @PublicApi public class UnresolvedTypeException extends GraphQLException { - private final GraphQLOutputType interfaceOrUnionType; + private final GraphQLNamedOutputType interfaceOrUnionType; /** * Constructor to use a custom error message @@ -21,21 +22,21 @@ public class UnresolvedTypeException extends GraphQLException { * @param message custom error message. * @param interfaceOrUnionType expected type. */ - public UnresolvedTypeException(String message, GraphQLOutputType interfaceOrUnionType) { + public UnresolvedTypeException(String message, GraphQLNamedOutputType interfaceOrUnionType) { super(message); this.interfaceOrUnionType = interfaceOrUnionType; } - public UnresolvedTypeException(GraphQLOutputType interfaceOrUnionType) { + public UnresolvedTypeException(GraphQLNamedOutputType interfaceOrUnionType) { this("Could not determine the exact type of '" + interfaceOrUnionType.getName() + "'", interfaceOrUnionType); } - public UnresolvedTypeException(GraphQLOutputType interfaceOrUnionType, GraphQLType providedType) { - this("Runtime Object type '" + providedType.getName() + "' is not a possible type for " + public UnresolvedTypeException(GraphQLNamedOutputType interfaceOrUnionType, GraphQLType providedType) { + this("Runtime Object type '" + GraphQLTypeUtil.simplePrint(providedType) + "' is not a possible type for " + "'" + interfaceOrUnionType.getName() + "'.", interfaceOrUnionType); } - public GraphQLOutputType getInterfaceOrUnionType() { + public GraphQLNamedOutputType getInterfaceOrUnionType() { return interfaceOrUnionType; } diff --git a/src/main/java/graphql/execution/ValueUnboxer.java b/src/main/java/graphql/execution/ValueUnboxer.java new file mode 100644 index 0000000000..e012d37225 --- /dev/null +++ b/src/main/java/graphql/execution/ValueUnboxer.java @@ -0,0 +1,27 @@ +package graphql.execution; + +import graphql.PublicSpi; + +/** + * A value unboxer takes values that are wrapped in classes like {@link java.util.Optional} / {@link java.util.OptionalInt} etc.. + * and returns value from them. You can provide your own implementation if you have your own specific + * holder classes. + */ +@PublicSpi +public interface ValueUnboxer { + + /** + * The default value unboxer handles JDK classes such as {@link java.util.Optional} and {@link java.util.OptionalInt} etc.. + */ + ValueUnboxer DEFAULT = new DefaultValueUnboxer(); + + /** + * Unboxes 'object' if it is boxed in an {@link java.util.Optional } like + * type that this unboxer can handle. Otherwise returns its input + * unmodified + * + * @param object to unbox + * @return unboxed object, or original if cannot unbox + */ + Object unbox(final Object object); +} \ No newline at end of file diff --git a/src/main/java/graphql/execution/ValuesResolver.java b/src/main/java/graphql/execution/ValuesResolver.java index 379616b093..357e19d64b 100644 --- a/src/main/java/graphql/execution/ValuesResolver.java +++ b/src/main/java/graphql/execution/ValuesResolver.java @@ -1,7 +1,11 @@ package graphql.execution; +import com.google.common.collect.Maps; +import graphql.GraphQLContext; import graphql.Internal; +import graphql.collect.ImmutableKit; +import graphql.execution.values.InputInterceptor; import graphql.language.Argument; import graphql.language.ArrayValue; import graphql.language.NullValue; @@ -10,332 +14,487 @@ import graphql.language.Value; import graphql.language.VariableDefinition; import graphql.language.VariableReference; -import graphql.schema.Coercing; +import graphql.normalized.NormalizedInputValue; +import graphql.schema.CoercingParseLiteralException; import graphql.schema.CoercingParseValueException; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLEnumType; -import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; import graphql.schema.GraphQLList; import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; import graphql.schema.GraphQLType; +import graphql.schema.InputValueWithState; import graphql.schema.visibility.GraphqlFieldVisibility; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; -import java.util.stream.Collectors; import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Assert.assertTrue; +import static graphql.execution.ValuesResolver.ValueMode.NORMALIZED; +import static graphql.execution.ValuesResolverConversion.externalValueToInternalValueImpl; import static graphql.schema.GraphQLTypeUtil.isList; import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.schema.GraphQLTypeUtil.simplePrint; import static graphql.schema.GraphQLTypeUtil.unwrapOne; import static graphql.schema.visibility.DefaultGraphqlFieldVisibility.DEFAULT_FIELD_VISIBILITY; +@SuppressWarnings("rawtypes") @Internal public class ValuesResolver { + private ValuesResolver() { + } + + public enum ValueMode { + LITERAL, + NORMALIZED + } + /** - * The http://facebook.github.io/graphql/#sec-Coercing-Variable-Values says : + * This method coerces the "raw" variables values provided to the engine. The coerced values will be used to + * provide arguments to {@link graphql.schema.DataFetchingEnvironment} * - *
-     * 1. Let coercedValues be an empty unordered Map.
-     * 2. Let variableDefinitions be the variables defined by operation.
-     * 3. For each variableDefinition in variableDefinitions:
-     *      a. Let variableName be the name of variableDefinition.
-     *      b. Let variableType be the expected type of variableDefinition.
-     *      c. Let defaultValue be the default value for variableDefinition.
-     *      d. Let value be the value provided in variableValues for the name variableName.
-     *      e. If value does not exist (was not provided in variableValues):
-     *          i. If defaultValue exists (including null):
-     *              1. Add an entry to coercedValues named variableName with the value defaultValue.
-     *          ii. Otherwise if variableType is a Non‐Nullable type, throw a query error.
-     *          iii. Otherwise, continue to the next variable definition.
-     *      f. Otherwise, if value cannot be coerced according to the input coercion rules of variableType, throw a query error.
-     *      g. Let coercedValue be the result of coercing value according to the input coercion rules of variableType.
-     *      h. Add an entry to coercedValues named variableName with the value coercedValue.
-     * 4. Return coercedValues.
-     * 
+ * This method is called once per execution and also performs validation. * * @param schema the schema * @param variableDefinitions the variable definitions - * @param variableValues the supplied variables + * @param rawVariables the supplied variables + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use * * @return coerced variable values as a map */ - public Map coerceArgumentValues(GraphQLSchema schema, List variableDefinitions, Map variableValues) { - GraphqlFieldVisibility fieldVisibility = schema.getFieldVisibility(); - Map coercedValues = new LinkedHashMap<>(); + public static CoercedVariables coerceVariableValues(GraphQLSchema schema, + List variableDefinitions, + RawVariables rawVariables, + GraphQLContext graphqlContext, + Locale locale) throws CoercingParseValueException, NonNullableValueCoercedAsNullException { + + InputInterceptor inputInterceptor = graphqlContext.get(InputInterceptor.class); + return ValuesResolverConversion.externalValueToInternalValueForVariables( + inputInterceptor, + schema, + variableDefinitions, + rawVariables, + graphqlContext, + locale); + } + + + /** + * Normalized variables values are Literals with type information. No validation here! + * + * @param schema the schema to use + * @param variableDefinitions the list of variable definitions + * @param rawVariables the raw variables + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use + * + * @return a map of the normalised values + */ + public static NormalizedVariables getNormalizedVariableValues( + GraphQLSchema schema, + List variableDefinitions, + RawVariables rawVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + GraphqlFieldVisibility fieldVisibility = schema.getCodeRegistry().getFieldVisibility(); + Map result = Maps.newLinkedHashMapWithExpectedSize(variableDefinitions.size()); for (VariableDefinition variableDefinition : variableDefinitions) { String variableName = variableDefinition.getName(); GraphQLType variableType = TypeFromAST.getTypeFromAST(schema, variableDefinition.getType()); - - // 3.e - if (!variableValues.containsKey(variableName)) { - Value defaultValue = variableDefinition.getDefaultValue(); - if (defaultValue != null) { - // 3.e.i - Object coercedValue = coerceValueAst(fieldVisibility, variableType, variableDefinition.getDefaultValue(), null); - coercedValues.put(variableName, coercedValue); - } else if (isNonNull(variableType)) { - // 3.e.ii - throw new NonNullableValueCoercedAsNullException(variableDefinition, variableType); + assertTrue(variableType instanceof GraphQLInputType); + // can be NullValue + Value defaultValue = variableDefinition.getDefaultValue(); + boolean hasValue = rawVariables.containsKey(variableName); + Object value = rawVariables.get(variableName); + if (!hasValue && defaultValue != null) { + result.put(variableName, new NormalizedInputValue(simplePrint(variableType), defaultValue)); + } else if (isNonNull(variableType) && (!hasValue || value == null)) { + return assertShouldNeverHappen("variable values are expected to be valid"); + } else if (hasValue) { + if (value == null) { + result.put(variableName, new NormalizedInputValue(simplePrint(variableType), null)); + } else { + Object literal = ValuesResolverConversion.externalValueToLiteral(fieldVisibility, value, (GraphQLInputType) variableType, NORMALIZED, graphqlContext, locale); + result.put(variableName, new NormalizedInputValue(simplePrint(variableType), literal)); } - } else { - Object value = variableValues.get(variableName); - // 3.f - Object coercedValue = getVariableValue(fieldVisibility, variableDefinition, variableType, value); - // 3.g - coercedValues.put(variableName, coercedValue); } } - - return coercedValues; + return NormalizedVariables.of(result); } - private Object getVariableValue(GraphqlFieldVisibility fieldVisibility, VariableDefinition variableDefinition, GraphQLType variableType, Object value) { - - if (value == null && variableDefinition.getDefaultValue() != null) { - return coerceValueAst(fieldVisibility, variableType, variableDefinition.getDefaultValue(), null); - } - return coerceValue(fieldVisibility, variableDefinition, variableDefinition.getName(), variableType, value); - } - - public Map getArgumentValues(List argumentTypes, List arguments, Map variables) { - return getArgumentValues(DEFAULT_FIELD_VISIBILITY, argumentTypes, arguments, variables); + /** + * This is not used for validation: the argument literals are all validated and the variables are validated (when coerced) + * + * @param argumentTypes the list of argument types + * @param arguments the AST arguments + * @param coercedVariables the coerced variables + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use + * + * @return a map of named argument values + */ + public static Map getArgumentValues( + List argumentTypes, + List arguments, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + InputInterceptor inputInterceptor = graphqlContext.get(InputInterceptor.class); + return getArgumentValuesImpl(inputInterceptor, DEFAULT_FIELD_VISIBILITY, argumentTypes, arguments, coercedVariables, graphqlContext, locale); } - public Map getArgumentValues(GraphqlFieldVisibility fieldVisibility, List argumentTypes, List arguments, Map variables) { + /** + * No validation as the arguments are assumed valid + * + * @param argumentTypes the list of argument types + * @param arguments the AST arguments + * @param normalizedVariables the normalised variables + * + * @return a map of named normalised values + */ + public static Map getNormalizedArgumentValues( + List argumentTypes, + List arguments, + Map normalizedVariables + ) { if (argumentTypes.isEmpty()) { - return Collections.emptyMap(); + return ImmutableKit.emptyMap(); } - Map result = new LinkedHashMap<>(); + Map result = new LinkedHashMap<>(); Map argumentMap = argumentMap(arguments); - for (GraphQLArgument fieldArgument : argumentTypes) { - String argName = fieldArgument.getName(); - Argument argument = argumentMap.get(argName); - Object value; - if (argument != null) { - value = coerceValueAst(fieldVisibility, fieldArgument.getType(), argument.getValue(), variables); - } else { - value = fieldArgument.getDefaultValue(); + for (GraphQLArgument argumentDefinition : argumentTypes) { + String argumentName = argumentDefinition.getName(); + Argument argument = argumentMap.get(argumentName); + if (argument == null) { + continue; } - // only put an arg into the result IF they specified a variable at all or - // the default value ended up being something non null - if (argumentMap.containsKey(argName) || value != null) { - result.put(argName, value); + + // If a variable doesn't exist then we can't put it into the result Map + if (isVariableAbsent(argument.getValue(), normalizedVariables)) { + continue; } + + GraphQLInputType argumentType = argumentDefinition.getType(); + Object value = literalToNormalizedValue(DEFAULT_FIELD_VISIBILITY, argumentType, argument.getValue(), normalizedVariables); + result.put(argumentName, new NormalizedInputValue(simplePrint(argumentType), value)); } return result; } + @NonNull + public static Map getArgumentValues( + GraphQLCodeRegistry codeRegistry, + List argumentTypes, + List arguments, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + InputInterceptor inputInterceptor = graphqlContext.get(InputInterceptor.class); + return getArgumentValuesImpl(inputInterceptor, codeRegistry.getFieldVisibility(), argumentTypes, arguments, coercedVariables, graphqlContext, locale); + } - private Map argumentMap(List arguments) { - Map result = new LinkedHashMap<>(); - for (Argument argument : arguments) { - result.put(argument.getName(), argument); - } - return result; + /** + * Takes a value which can be in different states (internal, literal, external value) and converts into Literal + *

+ * This assumes the value is valid! + * + * @param fieldVisibility the field visibility to use + * @param inputValueWithState the input value + * @param type the type of input value + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use + * + * @return a value converted to a literal + */ + public static Value valueToLiteral( + @NonNull GraphqlFieldVisibility fieldVisibility, + @NonNull InputValueWithState inputValueWithState, + @NonNull GraphQLType type, + GraphQLContext graphqlContext, + Locale locale + ) { + return (Value) ValuesResolverConversion.valueToLiteralImpl( + fieldVisibility, + inputValueWithState, + type, + ValueMode.LITERAL, + graphqlContext, + locale); } + public static Value valueToLiteral( + @NonNull InputValueWithState inputValueWithState, + @NonNull GraphQLType type, + GraphQLContext graphqlContext, + Locale locale + ) { + return (Value) ValuesResolverConversion.valueToLiteralImpl( + DEFAULT_FIELD_VISIBILITY, + inputValueWithState, + type, + ValueMode.LITERAL, + graphqlContext, + locale); + } - @SuppressWarnings("unchecked") - private Object coerceValue(GraphqlFieldVisibility fieldVisibility, VariableDefinition variableDefinition, String inputName, GraphQLType graphQLType, Object value) { - try { - if (isNonNull(graphQLType)) { - Object returnValue = - coerceValue(fieldVisibility, variableDefinition, inputName, unwrapOne(graphQLType), value); - if (returnValue == null) { - throw new NonNullableValueCoercedAsNullException(variableDefinition, graphQLType); - } - return returnValue; - } + public static Object valueToInternalValue( + InputValueWithState inputValueWithState, + GraphQLInputType inputType, + GraphQLContext graphqlContext, + Locale locale + ) throws CoercingParseValueException, CoercingParseLiteralException { + InputInterceptor inputInterceptor = graphqlContext.get(InputInterceptor.class); + return ValuesResolverConversion.valueToInternalValueImpl( + inputInterceptor, + inputValueWithState, + inputType, + graphqlContext, + locale); + } - if (value == null) { - return null; - } + /** + * Converts an external value to an internal value + * + * @param fieldVisibility the field visibility to use + * @param externalValue the input external value + * @param type the type of input value + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use + * + * @return a value converted to an internal value + */ + public static Object externalValueToInternalValue( + GraphqlFieldVisibility fieldVisibility, + Object externalValue, + GraphQLInputType type, + GraphQLContext graphqlContext, + Locale locale + ) { + InputInterceptor inputInterceptor = graphqlContext.get(InputInterceptor.class); + return externalValueToInternalValueImpl( + inputInterceptor, + fieldVisibility, + type, + externalValue, + graphqlContext, + locale); + } - if (graphQLType instanceof GraphQLScalarType) { - return coerceValueForScalar((GraphQLScalarType) graphQLType, value); - } else if (graphQLType instanceof GraphQLEnumType) { - return coerceValueForEnum((GraphQLEnumType) graphQLType, value); - } else if (graphQLType instanceof GraphQLList) { - return coerceValueForList(fieldVisibility, variableDefinition, inputName, (GraphQLList) graphQLType, value); - } else if (graphQLType instanceof GraphQLInputObjectType) { - if (value instanceof Map) { - return coerceValueForInputObjectType(fieldVisibility, variableDefinition, (GraphQLInputObjectType) graphQLType, (Map) value); - } else { - throw new CoercingParseValueException( - "Expected type 'Map' but was '" + value.getClass().getSimpleName() + - "'. Variables for input objects must be an instance of type 'Map'." - ); - } - } else { - return assertShouldNeverHappen("unhandled type %s", graphQLType); - } - } catch (CoercingParseValueException e) { - if (e.getLocations() != null) { - throw e; - } - throw new CoercingParseValueException( - "Variable '" + inputName + "' has an invalid value. " + e.getMessage(), - e.getCause(), - variableDefinition.getSourceLocation() - ); + @Nullable + @SuppressWarnings("unchecked") + public static T getInputValueImpl( + GraphQLInputType inputType, + InputValueWithState inputValue, + GraphQLContext graphqlContext, + Locale locale + ) { + if (inputValue.isNotSet()) { + return null; } + return (T) valueToInternalValue( + inputValue, + inputType, + graphqlContext, + locale); } - private Object coerceValueForInputObjectType(GraphqlFieldVisibility fieldVisibility, VariableDefinition variableDefinition, GraphQLInputObjectType inputObjectType, Map input) { - Map result = new LinkedHashMap<>(); - List fields = fieldVisibility.getFieldDefinitions(inputObjectType); - List fieldNames = fields.stream().map(GraphQLInputObjectField::getName).collect(Collectors.toList()); - for (String inputFieldName : input.keySet()) { - if (!fieldNames.contains(inputFieldName)) { - throw new InputMapDefinesTooManyFieldsException(inputObjectType, inputFieldName); - } + + @NonNull + private static Map getArgumentValuesImpl( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + List argumentTypes, + List arguments, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + if (argumentTypes.isEmpty()) { + return ImmutableKit.emptyMap(); } - for (GraphQLInputObjectField inputField : fields) { - if (input.containsKey(inputField.getName()) || alwaysHasValue(inputField)) { - Object value = coerceValue(fieldVisibility, variableDefinition, - inputField.getName(), - inputField.getType(), - input.get(inputField.getName())); - result.put(inputField.getName(), value == null ? inputField.getDefaultValue() : value); + Map coercedValues = Maps.newLinkedHashMapWithExpectedSize(arguments.size()); + Map argumentMap = argumentMap(arguments); + for (GraphQLArgument argumentDefinition : argumentTypes) { + GraphQLInputType argumentType = argumentDefinition.getType(); + String argumentName = argumentDefinition.getName(); + Argument argument = argumentMap.get(argumentName); + InputValueWithState defaultValue = argumentDefinition.getArgumentDefaultValue(); + boolean hasValue = argument != null; + Object value; + Value argumentValue = argument != null ? argument.getValue() : null; + if (argumentValue instanceof VariableReference) { + String variableName = ((VariableReference) argumentValue).getName(); + hasValue = coercedVariables.containsKey(variableName); + value = coercedVariables.get(variableName); + } else { + value = argumentValue; } - } - return result; - } + if (!hasValue && argumentDefinition.hasSetDefaultValue()) { + Object coercedDefaultValue = ValuesResolverConversion.defaultValueToInternalValue( + inputInterceptor, + fieldVisibility, + defaultValue, + argumentType, + graphqlContext, + locale); + coercedValues.put(argumentName, coercedDefaultValue); + } else if (isNonNull(argumentType) && (!hasValue || ValuesResolverConversion.isNullValue(value))) { + throw new NonNullableValueCoercedAsNullException(argumentDefinition); + } else if (hasValue) { + if (ValuesResolverConversion.isNullValue(value)) { + coercedValues.put(argumentName, value); + } else if (argumentValue instanceof VariableReference) { + coercedValues.put(argumentName, value); + } else { + value = ValuesResolverConversion.literalToInternalValue(inputInterceptor, + fieldVisibility, + argumentType, + argument.getValue(), + coercedVariables, + graphqlContext, + locale); + coercedValues.put(argumentName, value); + } - private boolean alwaysHasValue(GraphQLInputObjectField inputField) { - return inputField.getDefaultValue() != null - || isNonNull(inputField.getType()); - } + ValuesResolverOneOfValidation.validateOneOfInputTypes(argumentType, value, argumentValue, argumentName, locale); + + } + } - private Object coerceValueForScalar(GraphQLScalarType graphQLScalarType, Object value) { - return graphQLScalarType.getCoercing().parseValue(value); - } - private Object coerceValueForEnum(GraphQLEnumType graphQLEnumType, Object value) { - return graphQLEnumType.getCoercing().parseValue(value); + return coercedValues; } - private List coerceValueForList(GraphqlFieldVisibility fieldVisibility, VariableDefinition variableDefinition, String inputName, GraphQLList graphQLList, Object value) { - if (value instanceof Iterable) { - List result = new ArrayList<>(); - for (Object val : (Iterable) value) { - result.add(coerceValue(fieldVisibility, variableDefinition, inputName, graphQLList.getWrappedType(), val)); - } - return result; - } else { - return Collections.singletonList(coerceValue(fieldVisibility, variableDefinition, inputName, graphQLList.getWrappedType(), value)); + private static Map argumentMap(List arguments) { + Map result = Maps.newLinkedHashMapWithExpectedSize(arguments.size()); + for (Argument argument : arguments) { + result.put(argument.getName(), argument); } + return result; } - private Object coerceValueAst(GraphqlFieldVisibility fieldVisibility, GraphQLType type, Value inputValue, Map variables) { + + public static Object literalToNormalizedValue(GraphqlFieldVisibility fieldVisibility, + GraphQLType type, + Value inputValue, + Map normalizedVariables + ) { if (inputValue instanceof VariableReference) { - return variables.get(((VariableReference) inputValue).getName()); + String varName = ((VariableReference) inputValue).getName(); + return normalizedVariables.get(varName).getValue(); } + if (inputValue instanceof NullValue) { return null; } if (type instanceof GraphQLScalarType) { - return parseLiteral(inputValue, ((GraphQLScalarType) type).getCoercing()); + return inputValue; } if (isNonNull(type)) { - return coerceValueAst(fieldVisibility, unwrapOne(type), inputValue, variables); + return literalToNormalizedValue( + fieldVisibility, + unwrapOne(type), + inputValue, + normalizedVariables); } if (type instanceof GraphQLInputObjectType) { - return coerceValueAstForInputObject(fieldVisibility, (GraphQLInputObjectType) type, (ObjectValue) inputValue, variables); + return literalToNormalizedValueForInputObject( + fieldVisibility, + (GraphQLInputObjectType) type, + (ObjectValue) inputValue, + normalizedVariables); } if (type instanceof GraphQLEnumType) { - return parseLiteral(inputValue, ((GraphQLEnumType) type).getCoercing()); + return inputValue; } if (isList(type)) { - return coerceValueAstForList(fieldVisibility, (GraphQLList) type, inputValue, variables); + return literalToNormalizedValueForList( + fieldVisibility, + (GraphQLList) type, + inputValue, + normalizedVariables); } return null; } - private Object parseLiteral(Value inputValue, Coercing coercing) { - // the CoercingParseLiteralException exception that could happen here has been validated earlier via ValidationUtil - return coercing.parseLiteral(inputValue); + private static Object literalToNormalizedValueForInputObject(GraphqlFieldVisibility fieldVisibility, + GraphQLInputObjectType type, + ObjectValue inputObjectLiteral, + Map normalizedVariables) { + Map result = new LinkedHashMap<>(); + + for (ObjectField field : inputObjectLiteral.getObjectFields()) { + // If a variable doesn't exist then we can't put it into the result Map + if (isVariableAbsent(field.getValue(), normalizedVariables)) { + continue; + } + + GraphQLInputType fieldType = type.getField(field.getName()).getType(); + Object fieldValue = literalToNormalizedValue( + fieldVisibility, + fieldType, + field.getValue(), + normalizedVariables); + result.put(field.getName(), new NormalizedInputValue(simplePrint(fieldType), fieldValue)); + } + return result; } - private Object coerceValueAstForList(GraphqlFieldVisibility fieldVisibility, GraphQLList graphQLList, Value value, Map variables) { + private static List literalToNormalizedValueForList(GraphqlFieldVisibility fieldVisibility, + GraphQLList type, + Value value, + Map normalizedVariables) { if (value instanceof ArrayValue) { - ArrayValue arrayValue = (ArrayValue) value; - List result = new ArrayList<>(); - for (Value singleValue : arrayValue.getValues()) { - result.add(coerceValueAst(fieldVisibility, graphQLList.getWrappedType(), singleValue, variables)); + List values = ((ArrayValue) value).getValues(); + List result = new ArrayList<>(values.size()); + for (Value valueInArray : values) { + Object normalisedValue = literalToNormalizedValue( + fieldVisibility, + type.getWrappedType(), + valueInArray, + normalizedVariables); + result.add(normalisedValue); } return result; } else { - return Collections.singletonList(coerceValueAst(fieldVisibility, graphQLList.getWrappedType(), value, variables)); + return Collections.singletonList(literalToNormalizedValue( + fieldVisibility, + type.getWrappedType(), + value, + normalizedVariables)); } } - private Object coerceValueAstForInputObject(GraphqlFieldVisibility fieldVisibility, GraphQLInputObjectType type, ObjectValue inputValue, Map variables) { - Map result = new LinkedHashMap<>(); - - Map inputValueFieldsByName = mapObjectValueFieldsByName(inputValue); - - List inputFields = fieldVisibility.getFieldDefinitions(type); - for (GraphQLInputObjectField inputTypeField : inputFields) { - if (inputValueFieldsByName.containsKey(inputTypeField.getName())) { - boolean putObjectInMap = true; - - ObjectField field = inputValueFieldsByName.get(inputTypeField.getName()); - Value fieldInputValue = field.getValue(); - - Object fieldObject = null; - if (fieldInputValue instanceof VariableReference) { - String varName = ((VariableReference) fieldInputValue).getName(); - if (!variables.containsKey(varName)) { - putObjectInMap = false; - } else { - fieldObject = variables.get(varName); - } - } else { - fieldObject = coerceValueAst(fieldVisibility, inputTypeField.getType(), fieldInputValue, variables); - } - - if (fieldObject == null) { - if (!field.getValue().isEqualTo(NullValue.Null)) { - fieldObject = inputTypeField.getDefaultValue(); - } - } - if (putObjectInMap) { - result.put(field.getName(), fieldObject); - } else { - assertNonNullInputField(inputTypeField); - } - } else if (inputTypeField.getDefaultValue() != null) { - result.put(inputTypeField.getName(), inputTypeField.getDefaultValue()); - } else { - assertNonNullInputField(inputTypeField); - } - } - return result; - } - private void assertNonNullInputField(GraphQLInputObjectField inputTypeField) { - if (isNonNull(inputTypeField.getType())) { - throw new NonNullableValueCoercedAsNullException(inputTypeField); + /** + * @return true if variable is absent from input, and if value is NOT a variable then false + */ + private static boolean isVariableAbsent(Value value, Map variables) { + if (value instanceof VariableReference) { + VariableReference varRef = (VariableReference) value; + return !variables.containsKey(varRef.getName()); } - } - private Map mapObjectValueFieldsByName(ObjectValue inputValue) { - Map inputValueFieldsByName = new LinkedHashMap<>(); - for (ObjectField objectField : inputValue.getObjectFields()) { - inputValueFieldsByName.put(objectField.getName(), objectField); - } - return inputValueFieldsByName; + // Not variable, return false + return false; } } diff --git a/src/main/java/graphql/execution/ValuesResolverConversion.java b/src/main/java/graphql/execution/ValuesResolverConversion.java new file mode 100644 index 0000000000..20e9feb552 --- /dev/null +++ b/src/main/java/graphql/execution/ValuesResolverConversion.java @@ -0,0 +1,885 @@ +package graphql.execution; + +import com.google.common.collect.ImmutableList; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.values.InputInterceptor; +import graphql.language.ArrayValue; +import graphql.language.NullValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.Value; +import graphql.language.VariableDefinition; +import graphql.language.VariableReference; +import graphql.normalized.NormalizedInputValue; +import graphql.schema.CoercingParseValueException; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.InputValueWithState; +import graphql.schema.visibility.DefaultGraphqlFieldVisibility; +import graphql.schema.visibility.GraphqlFieldVisibility; +import graphql.util.FpKit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Assert.assertTrue; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.map; +import static graphql.execution.ValuesResolver.ValueMode.NORMALIZED; +import static graphql.language.NullValue.newNullValue; +import static graphql.language.ObjectField.newObjectField; +import static graphql.schema.GraphQLTypeUtil.isList; +import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.schema.GraphQLTypeUtil.unwrapNonNull; +import static graphql.schema.GraphQLTypeUtil.unwrapOneAs; +import static graphql.schema.visibility.DefaultGraphqlFieldVisibility.DEFAULT_FIELD_VISIBILITY; + +/** + * This class, originally broken out from {@link ValuesResolver} contains code for the conversion of values + * from one form (literal, external etc..) to another. + */ +@SuppressWarnings("rawtypes") +@Internal +class ValuesResolverConversion { + + static Object valueToLiteralImpl(GraphqlFieldVisibility fieldVisibility, + InputValueWithState inputValueWithState, + GraphQLType type, + ValuesResolver.ValueMode valueMode, + GraphQLContext graphqlContext, + Locale locale) { + if (inputValueWithState.isInternal()) { + if (valueMode == NORMALIZED) { + return assertShouldNeverHappen("can't infer normalized structure"); + } + Value value = ValuesResolverLegacy.valueToLiteralLegacy( + inputValueWithState.getValue(), + type, + graphqlContext, + locale); + // + // the valueToLiteralLegacy() nominally cant know if null means never set or is set to a null value + // but this code can know - its is SET to a value so, it MUST be a Null Literal + // this method would assert at the end of it if inputValueWithState.isNotSet() were true + // + return value == null ? NullValue.of() : value; + } + if (inputValueWithState.isLiteral()) { + return inputValueWithState.getValue(); + } + if (inputValueWithState.isExternal()) { + return externalValueToLiteral( + fieldVisibility, + inputValueWithState.getValue(), + (GraphQLInputType) type, + valueMode, + graphqlContext, + locale); + } + return assertShouldNeverHappen("unexpected value state " + inputValueWithState); + } + + /** + * Converts an external value to an internal value + * + * @param fieldVisibility the field visibility to use + * @param externalValue the input external value + * @param type the type of input value + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use + * + * @return a value converted to an internal value + */ + static Object externalValueToInternalValue(GraphqlFieldVisibility fieldVisibility, + Object externalValue, + GraphQLInputType type, + GraphQLContext graphqlContext, + Locale locale) { + InputInterceptor inputInterceptor = graphqlContext.get(InputInterceptor.class); + return externalValueToInternalValueImpl( + inputInterceptor, + fieldVisibility, + type, + externalValue, + graphqlContext, + locale); + } + + @Nullable + static Object valueToInternalValueImpl( + InputInterceptor inputInterceptor, + InputValueWithState inputValueWithState, + GraphQLInputType inputType, + GraphQLContext graphqlContext, + Locale locale + ) { + DefaultGraphqlFieldVisibility fieldVisibility = DEFAULT_FIELD_VISIBILITY; + + if (inputValueWithState.isInternal()) { + return inputValueWithState.getValue(); + } + if (inputValueWithState.isLiteral()) { + return literalToInternalValue( + inputInterceptor, + fieldVisibility, + inputType, + (Value) inputValueWithState.getValue(), + CoercedVariables.emptyVariables(), + graphqlContext, + locale); + } + if (inputValueWithState.isExternal()) { + return externalValueToInternalValueImpl( + inputInterceptor, + fieldVisibility, + inputType, + inputValueWithState.getValue(), + graphqlContext, + locale); + } + return assertShouldNeverHappen("unexpected value state " + inputValueWithState); + } + + /** + * No validation: the external value is assumed to be valid. + */ + static Object externalValueToLiteral( + GraphqlFieldVisibility fieldVisibility, + @Nullable Object value, + GraphQLInputType type, + ValuesResolver.ValueMode valueMode, + GraphQLContext graphqlContext, + Locale locale + ) { + if (value == null) { + return newNullValue().build(); + } + if (GraphQLTypeUtil.isNonNull(type)) { + return externalValueToLiteral( + fieldVisibility, + value, + (GraphQLInputType) unwrapNonNull(type), + valueMode, + graphqlContext, + locale); + } + if (type instanceof GraphQLScalarType) { + return externalValueToLiteralForScalar( + (GraphQLScalarType) type, + value, + graphqlContext, + locale); + } else if (type instanceof GraphQLEnumType) { + return externalValueToLiteralForEnum( + (GraphQLEnumType) type, + value, + graphqlContext, + locale); + } else if (type instanceof GraphQLList) { + return externalValueToLiteralForList( + fieldVisibility, + (GraphQLList) type, + value, + valueMode, + graphqlContext, + locale); + } else if (type instanceof GraphQLInputObjectType) { + return externalValueToLiteralForObject( + fieldVisibility, + (GraphQLInputObjectType) type, + value, + valueMode, + graphqlContext, + locale); + } else { + return assertShouldNeverHappen("unexpected type %s", type); + } + } + + /** + * No validation + */ + private static Value externalValueToLiteralForScalar( + GraphQLScalarType scalarType, + Object value, + GraphQLContext graphqlContext, + @NonNull Locale locale + ) { + return scalarType.getCoercing().valueToLiteral(value, graphqlContext, locale); + + } + + /** + * No validation + */ + private static Value externalValueToLiteralForEnum( + GraphQLEnumType enumType, + Object value, + GraphQLContext graphqlContext, + Locale locale) { + return enumType.valueToLiteral( + value, + graphqlContext, + locale); + } + + /** + * No validation + */ + @SuppressWarnings("unchecked") + private static Object externalValueToLiteralForList( + GraphqlFieldVisibility fieldVisibility, + GraphQLList listType, + Object value, + ValuesResolver.ValueMode valueMode, + GraphQLContext graphqlContext, + Locale locale + ) { + GraphQLInputType wrappedType = (GraphQLInputType) listType.getWrappedType(); + List valueList = FpKit.toListOrSingletonList(value); + ImmutableList.Builder resultBuilder = ImmutableList.builderWithExpectedSize(valueList.size()); + for (Object item : valueList) { + resultBuilder.add(externalValueToLiteral( + fieldVisibility, + item, + wrappedType, + valueMode, + graphqlContext, + locale)); + } + ImmutableList result = resultBuilder.build(); + + if (valueMode == NORMALIZED) { + return result; + } else { + return ArrayValue.newArrayValue().values((ImmutableList) result).build(); + } + } + + /** + * No validation + */ + @SuppressWarnings("unchecked") + private static Object externalValueToLiteralForObject( + GraphqlFieldVisibility fieldVisibility, + GraphQLInputObjectType inputObjectType, + Object inputValue, + ValuesResolver.ValueMode valueMode, + GraphQLContext graphqlContext, + Locale locale + ) { + assertTrue(inputValue instanceof Map, "Expect Map as input"); + Map inputMap = (Map) inputValue; + List fieldDefinitions = fieldVisibility.getFieldDefinitions(inputObjectType); + + Map normalizedResult = new LinkedHashMap<>(); + ImmutableList.Builder objectFields = ImmutableList.builder(); + for (GraphQLInputObjectField inputFieldDefinition : fieldDefinitions) { + GraphQLInputType fieldType = inputFieldDefinition.getType(); + String fieldName = inputFieldDefinition.getName(); + boolean hasValue = inputMap.containsKey(fieldName); + Object fieldValue = inputMap.getOrDefault(fieldName, null); + if (!hasValue && inputFieldDefinition.hasSetDefaultValue()) { + //TODO: consider valueMode + Object defaultValueLiteral = valueToLiteralImpl( + fieldVisibility, + inputFieldDefinition.getInputFieldDefaultValue(), + fieldType, + ValuesResolver.ValueMode.LITERAL, + graphqlContext, + locale); + if (valueMode == ValuesResolver.ValueMode.LITERAL) { + normalizedResult.put(fieldName, new NormalizedInputValue(simplePrint(fieldType), defaultValueLiteral)); + } else { + objectFields.add(newObjectField().name(fieldName).value((Value) defaultValueLiteral).build()); + } + } else if (hasValue) { + if (fieldValue == null) { + if (valueMode == NORMALIZED) { + normalizedResult.put(fieldName, new NormalizedInputValue(simplePrint(fieldType), null)); + } else { + objectFields.add(newObjectField().name(fieldName).value(newNullValue().build()).build()); + } + } else { + Object literal = externalValueToLiteral( + fieldVisibility, + fieldValue, + fieldType, + valueMode, + graphqlContext, locale); + if (valueMode == NORMALIZED) { + normalizedResult.put(fieldName, new NormalizedInputValue(simplePrint(fieldType), literal)); + } else { + objectFields.add(newObjectField().name(fieldName).value((Value) literal).build()); + } + } + } + } + if (valueMode == NORMALIZED) { + return normalizedResult; + } + return ObjectValue.newObjectValue().objectFields(objectFields.build()).build(); + } + + /** + * performs validation too + */ + static CoercedVariables externalValueToInternalValueForVariables( + InputInterceptor inputInterceptor, + GraphQLSchema schema, + List variableDefinitions, + RawVariables rawVariables, + GraphQLContext graphqlContext, Locale locale + ) { + GraphqlFieldVisibility fieldVisibility = schema.getCodeRegistry().getFieldVisibility(); + Map coercedValues = new LinkedHashMap<>(); + for (VariableDefinition variableDefinition : variableDefinitions) { + try { + String variableName = variableDefinition.getName(); + GraphQLType variableType = TypeFromAST.getTypeFromAST(schema, variableDefinition.getType()); + assertTrue(variableType instanceof GraphQLInputType); + GraphQLInputType variableInputType = (GraphQLInputType) variableType; + // can be NullValue + Value defaultValue = variableDefinition.getDefaultValue(); + boolean hasValue = rawVariables.containsKey(variableName); + Object value = rawVariables.get(variableName); + if (!hasValue && defaultValue != null) { + Object coercedDefaultValue = literalToInternalValue( + inputInterceptor, + fieldVisibility, + variableInputType, + defaultValue, + CoercedVariables.emptyVariables(), + graphqlContext, + locale); + coercedValues.put(variableName, coercedDefaultValue); + } else if (isNonNull(variableType) && (!hasValue || value == null)) { + throw new NonNullableValueCoercedAsNullException(variableDefinition, variableType); + } else if (hasValue) { + if (value == null) { + coercedValues.put(variableName, null); + } else { + Object coercedValue = externalValueToInternalValueImpl( + variableName, + inputInterceptor, + fieldVisibility, + variableInputType, + value, + graphqlContext, + locale); + coercedValues.put(variableName, coercedValue); + } + } + } catch (CoercingParseValueException e) { + throw CoercingParseValueException.newCoercingParseValueException() + .message(String.format("Variable '%s' has an invalid value: %s", variableDefinition.getName(), e.getMessage())) + .extensions(e.getExtensions()) + .cause(e.getCause()) + .sourceLocation(variableDefinition.getSourceLocation()) + .build(); + } catch (NonNullableValueCoercedAsNullException e) { + throw new NonNullableValueCoercedAsNullException(variableDefinition, e.getMessage()); + } + } + + return CoercedVariables.of(coercedValues); + } + + static Object externalValueToInternalValueImpl( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLInputType graphQLType, + Object originalValue, + GraphQLContext graphqlContext, + Locale locale + ) throws NonNullableValueCoercedAsNullException, CoercingParseValueException { + return externalValueToInternalValueImpl("externalValue", + inputInterceptor, + fieldVisibility, + graphQLType, + originalValue, + graphqlContext, + locale); + } + + /** + * Performs validation too + */ + static Object externalValueToInternalValueImpl( + String variableName, + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLInputType graphQLType, + Object originalValue, + GraphQLContext graphqlContext, + Locale locale + ) throws NonNullableValueCoercedAsNullException, CoercingParseValueException { + if (isNonNull(graphQLType)) { + Object returnValue = externalValueToInternalValueImpl( + variableName, + inputInterceptor, + fieldVisibility, + unwrapOneAs(graphQLType), + originalValue, + graphqlContext, + locale); + if (returnValue == null) { + throw new NonNullableValueCoercedAsNullException(graphQLType); + } + return returnValue; + } + // + // we have a @Internal hook that allows input values to be changed before they are + // presented to scalars and enums - if it's not present then the cost is an extra `if` + // statement. We expect this to be NOT present most of the time + // + Object value = originalValue; + if (inputInterceptor != null) { + value = inputInterceptor.intercept(originalValue, graphQLType, graphqlContext, locale); + } + if (value == null) { + return null; + } + + if (graphQLType instanceof GraphQLScalarType) { + return externalValueToInternalValueForScalar( + (GraphQLScalarType) graphQLType, + value, + graphqlContext, + locale); + } else if (graphQLType instanceof GraphQLEnumType) { + return externalValueToInternalValueForEnum( + (GraphQLEnumType) graphQLType, + value, + graphqlContext, + locale); + } else if (graphQLType instanceof GraphQLList) { + return externalValueToInternalValueForList( + inputInterceptor, + fieldVisibility, + (GraphQLList) graphQLType, + value, + graphqlContext, + locale); + } else if (graphQLType instanceof GraphQLInputObjectType) { + if (value instanceof Map) { + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) graphQLType; + //noinspection unchecked + Map coercedMap = externalValueToInternalValueForObject( + inputInterceptor, + fieldVisibility, + inputObjectType, + (Map) value, + graphqlContext, + locale); + + ValuesResolverOneOfValidation.validateOneOfInputTypes(inputObjectType, coercedMap, null, variableName, locale); + return coercedMap; + } else { + throw CoercingParseValueException.newCoercingParseValueException() + .message("Expected type 'Map' but was '" + value.getClass().getSimpleName() + + "'. Variables for input objects must be an instance of type 'Map'.") + .build(); + } + } else { + return assertShouldNeverHappen("unhandled type %s", graphQLType); + } + } + + /** + * performs validation + */ + private static Map externalValueToInternalValueForObject( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLInputObjectType inputObjectType, + Map inputMap, + GraphQLContext graphqlContext, + Locale locale + ) throws NonNullableValueCoercedAsNullException, CoercingParseValueException { + List fieldDefinitions = fieldVisibility.getFieldDefinitions(inputObjectType); + List fieldNames = map(fieldDefinitions, GraphQLInputObjectField::getName); + for (String providedFieldName : inputMap.keySet()) { + if (!fieldNames.contains(providedFieldName)) { + throw new InputMapDefinesTooManyFieldsException(inputObjectType, providedFieldName); + } + } + + Map coercedValues = new LinkedHashMap<>(); + + for (GraphQLInputObjectField inputFieldDefinition : fieldDefinitions) { + GraphQLInputType fieldType = inputFieldDefinition.getType(); + String fieldName = inputFieldDefinition.getName(); + InputValueWithState defaultValue = inputFieldDefinition.getInputFieldDefaultValue(); + boolean hasValue = inputMap.containsKey(fieldName); + Object value = inputMap.getOrDefault(fieldName, null); + if (!hasValue && inputFieldDefinition.hasSetDefaultValue()) { + Object coercedDefaultValue = defaultValueToInternalValue( + inputInterceptor, + fieldVisibility, + defaultValue, + fieldType, + graphqlContext, + locale); + coercedValues.put(fieldName, coercedDefaultValue); + } else if (isNonNull(fieldType) && (!hasValue || value == null)) { + throw new NonNullableValueCoercedAsNullException(fieldName, emptyList(), fieldType); + } else if (hasValue) { + if (value == null) { + coercedValues.put(fieldName, null); + } else { + value = externalValueToInternalValueImpl( + inputInterceptor, + fieldVisibility, + fieldType, + value, + graphqlContext, + locale); + coercedValues.put(fieldName, value); + } + } + } + return coercedValues; + } + + /** + * including validation + */ + private static Object externalValueToInternalValueForScalar( + GraphQLScalarType graphQLScalarType, + Object value, + GraphQLContext graphqlContext, + Locale locale + ) throws CoercingParseValueException { + return graphQLScalarType.getCoercing().parseValue( + value, + graphqlContext, + locale); + } + + /** + * including validation + */ + private static Object externalValueToInternalValueForEnum( + GraphQLEnumType graphQLEnumType, + Object value, + GraphQLContext graphqlContext, + Locale locale + ) throws CoercingParseValueException { + return graphQLEnumType.parseValue( + value, + graphqlContext, + locale); + } + + /** + * including validation + */ + private static List externalValueToInternalValueForList( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLList graphQLList, + Object value, + GraphQLContext graphqlContext, + Locale locale + ) throws CoercingParseValueException, NonNullableValueCoercedAsNullException { + + GraphQLInputType wrappedType = (GraphQLInputType) graphQLList.getWrappedType(); + List listOrSingletonList = FpKit.toListOrSingletonList(value); + List list = FpKit.arrayListSizedTo(listOrSingletonList); + for (Object val : listOrSingletonList) { + list.add(externalValueToInternalValueImpl( + inputInterceptor, + fieldVisibility, + wrappedType, + val, + graphqlContext, + locale)); + } + return list; + } + + /** + * No validation (it was checked before via ArgumentsOfCorrectType and VariableDefaultValuesOfCorrectType) + * + * @param fieldVisibility the field visibility + * @param type the type of the input value + * @param inputValue the AST literal to be changed + * @param coercedVariables the coerced variable values + * @param graphqlContext the GraphqlContext to use + * @param locale the Locale to use + * + * @return literal converted to an internal value + */ + static Object literalToInternalValue( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLInputType type, + Value inputValue, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + return literalToInternalValueImpl( + inputInterceptor, + fieldVisibility, + type, + inputValue, + coercedVariables, + graphqlContext, + locale); + } + + @Nullable + private static Object literalToInternalValueImpl( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLType type, + Value inputValue, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + if (inputValue instanceof VariableReference) { + String variableName = ((VariableReference) inputValue).getName(); + return coercedVariables.get(variableName); + } + if (inputValue instanceof NullValue) { + return null; + } + if (type instanceof GraphQLScalarType) { + return literalToInternalValueForScalar( + inputValue, + (GraphQLScalarType) type, + coercedVariables, + graphqlContext, + locale); + } + if (isNonNull(type)) { + return literalToInternalValue( + inputInterceptor, + fieldVisibility, + unwrapOneAs(type), + inputValue, + coercedVariables, + graphqlContext, + locale); + } + if (type instanceof GraphQLInputObjectType) { + return literalToInternalValueForInputObject( + inputInterceptor, + fieldVisibility, + (GraphQLInputObjectType) type, + (ObjectValue) inputValue, + coercedVariables, + graphqlContext, + locale); + } + if (type instanceof GraphQLEnumType) { + return ((GraphQLEnumType) type).parseLiteral(inputValue, graphqlContext, locale); + } + if (isList(type)) { + return literalToInternalValueForList( + inputInterceptor, + fieldVisibility, + (GraphQLList) type, + inputValue, + coercedVariables, + graphqlContext, + locale); + } + return null; + } + + /** + * no validation + */ + private static Object literalToInternalValueForScalar( + Value inputValue, + GraphQLScalarType scalarType, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + @NonNull Locale locale + ) { + // the CoercingParseLiteralException exception that could happen here has been validated earlier via ValidationUtil + return scalarType.getCoercing().parseLiteral( + inputValue, + coercedVariables, + graphqlContext, + locale); + } + + /** + * no validation + */ + private static Object literalToInternalValueForList( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLList graphQLList, + Value value, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + + GraphQLInputType inputType = (GraphQLInputType) graphQLList.getWrappedType(); + if (value instanceof ArrayValue) { + ArrayValue arrayValue = (ArrayValue) value; + List result = new ArrayList<>(); + for (Value singleValue : arrayValue.getValues()) { + result.add(literalToInternalValue( + inputInterceptor, + fieldVisibility, + inputType, + singleValue, + coercedVariables, + graphqlContext, + locale)); + } + return result; + } else { + return Collections.singletonList( + literalToInternalValue( + inputInterceptor, + fieldVisibility, + inputType, + value, + coercedVariables, + graphqlContext, + locale)); + } + } + + /** + * no validation + */ + private static Object literalToInternalValueForInputObject( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + GraphQLInputObjectType type, + ObjectValue inputValue, + CoercedVariables coercedVariables, + GraphQLContext graphqlContext, + Locale locale + ) { + Map coercedValues = new LinkedHashMap<>(); + + Map inputFieldsByName = mapObjectValueFieldsByName(inputValue); + + + List inputFieldTypes = fieldVisibility.getFieldDefinitions(type); + for (GraphQLInputObjectField inputFieldDefinition : inputFieldTypes) { + GraphQLInputType fieldType = inputFieldDefinition.getType(); + String fieldName = inputFieldDefinition.getName(); + ObjectField field = inputFieldsByName.get(fieldName); + boolean hasValue = field != null; + Object value; + Value fieldValue = field != null ? field.getValue() : null; + if (fieldValue instanceof VariableReference) { + String variableName = ((VariableReference) fieldValue).getName(); + hasValue = coercedVariables.containsKey(variableName); + value = coercedVariables.get(variableName); + } else { + value = fieldValue; + } + if (!hasValue && inputFieldDefinition.hasSetDefaultValue()) { + Object coercedDefaultValue = defaultValueToInternalValue( + inputInterceptor, + fieldVisibility, + inputFieldDefinition.getInputFieldDefaultValue(), + fieldType, + graphqlContext, + locale); + coercedValues.put(fieldName, coercedDefaultValue); + } else if (isNonNull(fieldType) && (!hasValue || isNullValue(value))) { + return assertShouldNeverHappen("Should have been validated before"); + } else if (hasValue) { + if (isNullValue(value)) { + coercedValues.put(fieldName, value); + } else if (fieldValue instanceof VariableReference) { + coercedValues.put(fieldName, value); + } else { + value = literalToInternalValue( + inputInterceptor, + fieldVisibility, + fieldType, + fieldValue, + coercedVariables, + graphqlContext, + locale); + coercedValues.put(fieldName, value); + } + } + } + return coercedValues; + } + + static boolean isNullValue(Object value) { + if (value == null) { + return true; + } + if (!(value instanceof NormalizedInputValue)) { + return false; + } + return ((NormalizedInputValue) value).getValue() == null; + } + + private static Map mapObjectValueFieldsByName(ObjectValue inputValue) { + Map inputValueFieldsByName = new LinkedHashMap<>(); + for (ObjectField objectField : inputValue.getObjectFields()) { + inputValueFieldsByName.put(objectField.getName(), objectField); + } + return inputValueFieldsByName; + } + + static Object defaultValueToInternalValue( + InputInterceptor inputInterceptor, + GraphqlFieldVisibility fieldVisibility, + InputValueWithState defaultValue, + GraphQLInputType type, + GraphQLContext graphqlContext, + Locale locale + ) { + if (defaultValue.isInternal()) { + return defaultValue.getValue(); + } + if (defaultValue.isLiteral()) { + // default value literals can't reference variables, this is why the variables are empty + return literalToInternalValue( + inputInterceptor, + fieldVisibility, + type, + (Value) defaultValue.getValue(), + CoercedVariables.emptyVariables(), + graphqlContext, + locale); + } + if (defaultValue.isExternal()) { + // performs validation too + return externalValueToInternalValueImpl( + inputInterceptor, + fieldVisibility, + type, + defaultValue.getValue(), + graphqlContext, + locale); + } + return assertShouldNeverHappen(); + } +} diff --git a/src/main/java/graphql/execution/ValuesResolverLegacy.java b/src/main/java/graphql/execution/ValuesResolverLegacy.java new file mode 100644 index 0000000000..704b365132 --- /dev/null +++ b/src/main/java/graphql/execution/ValuesResolverLegacy.java @@ -0,0 +1,157 @@ +package graphql.execution; + +import graphql.AssertException; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.Scalars; +import graphql.VisibleForTesting; +import graphql.language.ArrayValue; +import graphql.language.BooleanValue; +import graphql.language.EnumValue; +import graphql.language.FloatValue; +import graphql.language.IntValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLType; +import graphql.schema.PropertyDataFetcherHelper; +import graphql.util.FpKit; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static graphql.Assert.assertTrue; +import static graphql.language.ObjectField.newObjectField; +import static graphql.schema.GraphQLTypeUtil.isList; +import static graphql.schema.GraphQLTypeUtil.isNonNull; + +/* + * ======================LEGACY=======+TO BE REMOVED IN THE FUTURE =============== + */ + +@Internal +class ValuesResolverLegacy { + /** + * Legacy logic to convert an arbitrary java object to an Ast Literal. + * Only provided here to preserve backwards compatibility. + */ + @VisibleForTesting + static Value valueToLiteralLegacy(Object value, GraphQLType type, GraphQLContext graphqlContext, Locale locale) { + assertTrue(!(value instanceof Value), "Unexpected literal %s", value); + if (value == null) { + return null; + } + + if (isNonNull(type)) { + return handleNonNullLegacy(value, (GraphQLNonNull) type, graphqlContext, locale); + } + + // Convert JavaScript array to GraphQL list. If the GraphQLType is a list, but + // the value is not an array, convert the value using the list's item type. + if (isList(type)) { + return handleListLegacy(value, (GraphQLList) type, graphqlContext, locale); + } + + // Populate the fields of the input object by creating ASTs from each value + // in the JavaScript object according to the fields in the input type. + if (type instanceof GraphQLInputObjectType) { + return handleInputObjectLegacy(value, (GraphQLInputObjectType) type, graphqlContext, locale); + } + + if (!(type instanceof GraphQLScalarType || type instanceof GraphQLEnumType)) { + throw new AssertException("Must provide Input Type, cannot use: " + type.getClass()); + } + + // Since value is an internally represented value, it must be serialized + // to an externally represented value before converting into an AST. + final Object serialized = serializeLegacy(type, value, graphqlContext, locale); + + // Others serialize based on their corresponding JavaScript scalar types. + if (serialized instanceof Boolean) { + return BooleanValue.newBooleanValue().value((Boolean) serialized).build(); + } + + String stringValue = serialized.toString(); + // numbers can be Int or Float values. + if (serialized instanceof Number) { + return handleNumberLegacy(stringValue); + } + + if (serialized instanceof String) { + // Enum types use Enum literals. + if (type instanceof GraphQLEnumType) { + return EnumValue.newEnumValue().name(stringValue).build(); + } + + // ID types can use Int literals. + if (type == Scalars.GraphQLID && stringValue.matches("^[0-9]+$")) { + return IntValue.newIntValue().value(new BigInteger(stringValue)).build(); + } + + return StringValue.newStringValue().value(stringValue).build(); + } + + throw new AssertException("'Cannot convert value to AST: " + serialized); + } + + private static Value handleInputObjectLegacy(Object javaValue, GraphQLInputObjectType type, GraphQLContext graphqlContext, Locale locale) { + List fields = type.getFields(); + List fieldNodes = new ArrayList<>(); + fields.forEach(field -> { + String fieldName = field.getName(); + GraphQLInputType fieldType = field.getType(); + Object fieldValueObj = PropertyDataFetcherHelper.getPropertyValue(fieldName, javaValue, fieldType); + Value nodeValue = valueToLiteralLegacy(fieldValueObj, fieldType, graphqlContext, locale); + if (nodeValue != null) { + fieldNodes.add(newObjectField().name(fieldName).value(nodeValue).build()); + } + }); + return ObjectValue.newObjectValue().objectFields(fieldNodes).build(); + } + + private static Value handleNumberLegacy(String stringValue) { + if (stringValue.matches("^[0-9]+$")) { + return IntValue.newIntValue().value(new BigInteger(stringValue)).build(); + } else { + return FloatValue.newFloatValue().value(new BigDecimal(stringValue)).build(); + } + } + + @SuppressWarnings("rawtypes") + private static Value handleListLegacy(Object value, GraphQLList type, GraphQLContext graphqlContext, Locale locale) { + GraphQLType itemType = type.getWrappedType(); + if (FpKit.isIterable(value)) { + List listOrSingletonList = FpKit.toListOrSingletonList(value); + List valuesNodes = FpKit.arrayListSizedTo(listOrSingletonList); + for (Object item : listOrSingletonList) { + valuesNodes.add(valueToLiteralLegacy(item, itemType, graphqlContext, locale)); + } + return ArrayValue.newArrayValue().values(valuesNodes).build(); + } + return valueToLiteralLegacy(value, itemType, graphqlContext, locale); + } + + private static Value handleNonNullLegacy(Object _value, GraphQLNonNull type, GraphQLContext graphqlContext, Locale locale) { + GraphQLType wrappedType = type.getWrappedType(); + return valueToLiteralLegacy(_value, wrappedType, graphqlContext, locale); + } + + private static Object serializeLegacy(GraphQLType type, Object value, GraphQLContext graphqlContext, Locale locale) { + if (type instanceof GraphQLScalarType) { + return ((GraphQLScalarType) type).getCoercing().serialize(value, graphqlContext, locale); + } else { + return ((GraphQLEnumType) type).serialize(value, graphqlContext, locale); + } + } +} diff --git a/src/main/java/graphql/execution/ValuesResolverOneOfValidation.java b/src/main/java/graphql/execution/ValuesResolverOneOfValidation.java new file mode 100644 index 0000000000..9955ce050d --- /dev/null +++ b/src/main/java/graphql/execution/ValuesResolverOneOfValidation.java @@ -0,0 +1,110 @@ +package graphql.execution; + +import graphql.Assert; +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.ArrayValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.Value; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +import static graphql.schema.GraphQLTypeUtil.isList; + +@Internal +final class ValuesResolverOneOfValidation { + + @SuppressWarnings("unchecked") + static void validateOneOfInputTypes(GraphQLType type, Object inputValue, Value argumentValue, String argumentName, Locale locale) { + GraphQLType unwrappedNonNullType = GraphQLTypeUtil.unwrapNonNull(type); + + if (isList(unwrappedNonNullType) + && !ValuesResolverConversion.isNullValue(inputValue) + && inputValue instanceof List + && argumentValue instanceof ArrayValue) { + GraphQLType elementType = ((GraphQLList) unwrappedNonNullType).getWrappedType(); + List inputList = (List) inputValue; + List argumentList = ((ArrayValue) argumentValue).getValues(); + + for (int i = 0; i < argumentList.size(); i++) { + validateOneOfInputTypes(elementType, inputList.get(i), argumentList.get(i), argumentName, locale); + } + } + + if (unwrappedNonNullType instanceof GraphQLInputObjectType && !ValuesResolverConversion.isNullValue(inputValue)) { + Assert.assertTrue(inputValue instanceof Map, "The coerced argument %s GraphQLInputObjectType is unexpectedly not a map", argumentName); + Map objectMap = (Map) inputValue; + + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) unwrappedNonNullType; + + if (inputObjectType.isOneOf()) { + validateOneOfInputTypesInternal(inputObjectType, argumentValue, objectMap, locale); + } + + for (GraphQLInputObjectField fieldDefinition : inputObjectType.getFields()) { + GraphQLInputType childFieldType = fieldDefinition.getType(); + String childFieldName = fieldDefinition.getName(); + Object childFieldInputValue = objectMap.get(childFieldName); + + if (argumentValue instanceof ObjectValue) { + List values = ((ObjectValue) argumentValue).getObjectFields().stream() + .filter(of -> of.getName().equals(childFieldName)) + .map(ObjectField::getValue) + .collect(Collectors.toList()); + + if (values.size() > 1) { + Assert.assertShouldNeverHappen("argument %s has %s object fields with the same name: '%s'. A maximum of 1 is expected", argumentName, values.size(), childFieldName); + } else if (!values.isEmpty()) { + validateOneOfInputTypes(childFieldType, childFieldInputValue, values.get(0), argumentName, locale); + } + } else { + validateOneOfInputTypes(childFieldType, childFieldInputValue, argumentValue, argumentName, locale); + } + } + } + } + + private static void validateOneOfInputTypesInternal(GraphQLInputObjectType oneOfInputType, Value argumentValue, Map objectMap, Locale locale) { + final String fieldName; + if (argumentValue instanceof ObjectValue) { + List objectFields = ((ObjectValue) argumentValue).getObjectFields(); + if (objectFields.size() != 1) { + throwNotOneFieldError(oneOfInputType, locale); + } + + fieldName = objectFields.iterator().next().getName(); + } else { + if (objectMap.size() != 1) { + throwNotOneFieldError(oneOfInputType, locale); + } + + fieldName = objectMap.keySet().iterator().next(); + } + + if (objectMap.get(fieldName) == null) { + throwValueIsNullError(oneOfInputType, locale, fieldName); + } + } + + private static void throwValueIsNullError(GraphQLInputObjectType oneOfInputType, Locale locale, String fieldName) { + String msg = I18n.i18n(I18n.BundleType.Execution, locale) + .msg("Execution.handleOneOfValueIsNullError", oneOfInputType.getName() + "." + fieldName); + throw new OneOfNullValueException(msg); + } + + private static void throwNotOneFieldError(GraphQLInputObjectType oneOfInputType, Locale locale) { + String msg = I18n.i18n(I18n.BundleType.Execution, locale) + .msg("Execution.handleOneOfNotOneFieldError", oneOfInputType.getName()); + throw new OneOfTooManyKeysException(msg); + } +} diff --git a/src/main/java/graphql/execution/batched/BatchAssertionFailed.java b/src/main/java/graphql/execution/batched/BatchAssertionFailed.java deleted file mode 100644 index f81123c1bf..0000000000 --- a/src/main/java/graphql/execution/batched/BatchAssertionFailed.java +++ /dev/null @@ -1,22 +0,0 @@ -package graphql.execution.batched; - -import graphql.GraphQLException; - - -public class BatchAssertionFailed extends GraphQLException { - public BatchAssertionFailed() { - super(); - } - - public BatchAssertionFailed(String message) { - super(message); - } - - public BatchAssertionFailed(String message, Throwable cause) { - super(message, cause); - } - - public BatchAssertionFailed(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/graphql/execution/batched/Batched.java b/src/main/java/graphql/execution/batched/Batched.java deleted file mode 100644 index 341c9877aa..0000000000 --- a/src/main/java/graphql/execution/batched/Batched.java +++ /dev/null @@ -1,58 +0,0 @@ -package graphql.execution.batched; - -import graphql.schema.DataFetchingEnvironment; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - *

- * When placed on {@link graphql.schema.DataFetcher#get(DataFetchingEnvironment)}, indicates that this DataFetcher is batched. - * This annotation must be used in conjunction with {@link BatchedExecutionStrategy}. Batching is valuable in many - * situations, such as when a {@link graphql.schema.DataFetcher} must make a network or file system request. - *

- *

- * When a {@link graphql.schema.DataFetcher} is batched, the {@link DataFetchingEnvironment#getSource()} method is - * guaranteed to return a {@link java.util.List}. The {@link graphql.schema.DataFetcher#get(DataFetchingEnvironment)} - * method MUST return a parallel {@link java.util.List} which is equivalent to running a {@link graphql.schema.DataFetcher} - * over each input element individually. - *

- *

- * Using the {@link Batched} annotation is equivalent to implementing {@link BatchedDataFetcher} instead of {@link graphql.schema.DataFetcher}. - * It is preferred to use the {@link Batched} annotation. - *

- * For example, the following two {@link graphql.schema.DataFetcher} objects are interchangeable if used with a - * {@link BatchedExecutionStrategy}. - *
- * 
- * new DataFetcher() {
- *   {@literal @}Override
- *   {@literal @}Batched
- *   public Object get(DataFetchingEnvironment environment) {
- *     {@literal List retVal = new ArrayList<>();}
- *     {@literal for (String s: (List) environment.getSource()) {}
- *       retVal.add(s + environment.getArgument("text"));
- *     }
- *     return retVal;
- *   }
- * }
- * 
- * 
- *
- * 
- * new DataFetcher() {
- *   {@literal @}Override
- *   public Object get(DataFetchingEnvironment e) {
- *     return ((String)e.getSource()) + e.getArgument("text");
- *   }
- * }
- * 
- * 
- */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Batched { -} diff --git a/src/main/java/graphql/execution/batched/BatchedDataFetcher.java b/src/main/java/graphql/execution/batched/BatchedDataFetcher.java deleted file mode 100644 index 8f197613cc..0000000000 --- a/src/main/java/graphql/execution/batched/BatchedDataFetcher.java +++ /dev/null @@ -1,10 +0,0 @@ -package graphql.execution.batched; - -import graphql.schema.DataFetcher; - -/** - * See {@link Batched}. - */ -public interface BatchedDataFetcher extends DataFetcher { - // Marker interface -} diff --git a/src/main/java/graphql/execution/batched/BatchedDataFetcherFactory.java b/src/main/java/graphql/execution/batched/BatchedDataFetcherFactory.java deleted file mode 100644 index 69f266d12c..0000000000 --- a/src/main/java/graphql/execution/batched/BatchedDataFetcherFactory.java +++ /dev/null @@ -1,33 +0,0 @@ -package graphql.execution.batched; - -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; - -import java.lang.reflect.Method; - -/** - * Produces a BatchedDataFetcher for a given DataFetcher. - * If that fetcher is already a BatchedDataFetcher we return it. - * If that fetcher's get method is annotated @Batched then we delegate to it directly. - * Otherwise we wrap the fetcher in a BatchedDataFetcher that iterates over the sources and invokes the delegate - * on each source. Note that this forgoes any performance benefits of batching, - * so regular DataFetchers should normally only be used if they are in-memory. - */ - -public class BatchedDataFetcherFactory { - public BatchedDataFetcher create(final DataFetcher supplied) { - if (supplied instanceof BatchedDataFetcher) { - return (BatchedDataFetcher) supplied; - } - try { - Method getMethod = supplied.getClass().getMethod("get", DataFetchingEnvironment.class); - Batched batched = getMethod.getAnnotation(Batched.class); - if (batched != null) { - return supplied::get; - } - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException(e); - } - return new UnbatchedDataFetcher(supplied); - } -} diff --git a/src/main/java/graphql/execution/batched/BatchedExecutionStrategy.java b/src/main/java/graphql/execution/batched/BatchedExecutionStrategy.java deleted file mode 100644 index c7c8fac5b4..0000000000 --- a/src/main/java/graphql/execution/batched/BatchedExecutionStrategy.java +++ /dev/null @@ -1,512 +0,0 @@ -package graphql.execution.batched; - -import graphql.Assert; -import graphql.ExecutionResult; -import graphql.ExecutionResultImpl; -import graphql.PublicApi; -import graphql.execution.Async; -import graphql.execution.DataFetcherExceptionHandler; -import graphql.execution.DataFetcherExceptionHandlerParameters; -import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionPath; -import graphql.execution.ExecutionStrategy; -import graphql.execution.ExecutionStrategyParameters; -import graphql.execution.ExecutionTypeInfo; -import graphql.execution.FieldCollectorParameters; -import graphql.execution.NonNullableFieldValidator; -import graphql.execution.SimpleDataFetcherExceptionHandler; -import graphql.execution.TypeResolutionParameters; -import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; -import graphql.language.Field; -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; -import graphql.schema.DataFetchingFieldSelectionSet; -import graphql.schema.DataFetchingFieldSelectionSetImpl; -import graphql.schema.GraphQLEnumType; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLInterfaceType; -import graphql.schema.GraphQLList; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLOutputType; -import graphql.schema.GraphQLScalarType; -import graphql.schema.GraphQLType; -import graphql.schema.GraphQLUnionType; -import graphql.schema.visibility.GraphqlFieldVisibility; - -import java.lang.reflect.Array; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.function.BiFunction; -import java.util.stream.IntStream; - -import static graphql.execution.ExecutionTypeInfo.newTypeInfo; -import static graphql.execution.FieldCollectorParameters.newParameters; -import static graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment; -import static java.util.Collections.singletonList; -import static java.util.stream.Collectors.toList; - -/** - *
- * BatchedExecutionStrategy has been deprecated in favour of {@link graphql.execution.AsyncExecutionStrategy} - * and {@link graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation}. - * - * BatchedExecutionStrategy does not properly implement the graphql runtime specification. Specifically it - * does not correctly handle non null fields and how they are to cascade up their parent fields. It has proven - * an intractable problem to make this code handle these cases. - * - * See http://facebook.github.io/graphql/October2016/#sec-Errors-and-Non-Nullability - * - * We will remove it once we are sure the alternative is as least good as the BatchedExecutionStrategy. - * - *
- * - * Execution Strategy that minimizes calls to the data fetcher when used in conjunction with {@link DataFetcher}s that have - * {@link DataFetcher#get(DataFetchingEnvironment)} methods annotated with {@link Batched}. See the javadoc comment on - * {@link Batched} for a more detailed description of batched data fetchers. - *

- * The strategy runs a BFS over terms of the query and passes a list of all the relevant sources to the batched data fetcher. - *

- * Normal DataFetchers can be used, however they will not see benefits of batching as they expect a single source object - * at a time. - * - * @deprecated This has been deprecated in favour of using {@link graphql.execution.AsyncExecutionStrategy} and {@link graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation} - */ -@PublicApi -@Deprecated -public class BatchedExecutionStrategy extends ExecutionStrategy { - - private final BatchedDataFetcherFactory batchingFactory = new BatchedDataFetcherFactory(); - - public BatchedExecutionStrategy() { - this(new SimpleDataFetcherExceptionHandler()); - } - - public BatchedExecutionStrategy(DataFetcherExceptionHandler dataFetcherExceptionHandler) { - super(dataFetcherExceptionHandler); - } - - @Override - @SuppressWarnings("FutureReturnValueIgnored") - public CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - InstrumentationContext executionStrategyCtx = executionContext.getInstrumentation() - .beginExecutionStrategy(new InstrumentationExecutionStrategyParameters(executionContext, parameters)); - - GraphQLObjectType type = parameters.getTypeInfo().castType(GraphQLObjectType.class); - - ExecutionNode root = new ExecutionNode(type, - parameters.getTypeInfo(), - parameters.getFields(), - singletonList(MapOrList.createMap(new LinkedHashMap<>())), - Collections.singletonList(parameters.getSource()) - ); - - Queue nodes = new ArrayDeque<>(); - CompletableFuture result = new CompletableFuture<>(); - executeImpl(executionContext, - parameters, - root, - root, - nodes, - root.getFields().keySet().iterator(), - result); - - executionStrategyCtx.onDispatched(result); - result.whenComplete(executionStrategyCtx::onCompleted); - return result; - } - - @SuppressWarnings("FutureReturnValueIgnored") - private void executeImpl(ExecutionContext executionContext, - ExecutionStrategyParameters parameters, - ExecutionNode root, - ExecutionNode curNode, - Queue queueOfNodes, - Iterator curFieldNames, - CompletableFuture overallResult) { - - if (!curFieldNames.hasNext() && queueOfNodes.isEmpty()) { - overallResult.complete(new ExecutionResultImpl(root.getParentResults().get(0).toObject(), executionContext.getErrors())); - return; - } - - if (!curFieldNames.hasNext()) { - curNode = queueOfNodes.poll(); - curFieldNames = curNode.getFields().keySet().iterator(); - } - - String fieldName = curFieldNames.next(); - List currentField = curNode.getFields().get(fieldName); - - - // - // once an object is resolved from a interface / union to a node with an object type, the - // parent type info has effectively changed (it has got more specific), even though the path etc... - // has not changed - ExecutionTypeInfo currentParentTypeInfo = parameters.getTypeInfo(); - ExecutionTypeInfo newParentTypeInfo = newTypeInfo() - .type(curNode.getType()) - .fieldDefinition(currentParentTypeInfo.getFieldDefinition()) - .path(currentParentTypeInfo.getPath()) - .parentInfo(currentParentTypeInfo.getParentTypeInfo()) - .build(); - - ExecutionPath fieldPath = curNode.getTypeInfo().getPath().segment(fieldName); - GraphQLFieldDefinition fieldDefinition = getFieldDef(executionContext.getGraphQLSchema(), curNode.getType(), currentField.get(0)); - - ExecutionTypeInfo typeInfo = newTypeInfo() - .type(fieldDefinition.getType()) - .fieldDefinition(fieldDefinition) - .path(fieldPath) - .parentInfo(newParentTypeInfo) - .build(); - - ExecutionStrategyParameters newParameters = parameters - .transform(builder -> builder - .path(fieldPath) - .field(currentField) - .typeInfo(typeInfo) - ); - - ExecutionNode finalCurNode = curNode; - Iterator finalCurFieldNames = curFieldNames; - - resolveField(executionContext, newParameters, fieldName, curNode) - .whenComplete((childNodes, exception) -> { - if (exception != null) { - handleNonNullException(executionContext, overallResult, exception); - return; - } - queueOfNodes.addAll(childNodes); - executeImpl(executionContext, newParameters, root, finalCurNode, queueOfNodes, finalCurFieldNames, overallResult); - }); - } - - - private CompletableFuture> resolveField(ExecutionContext executionContext, - ExecutionStrategyParameters parameters, - String fieldName, - ExecutionNode node) { - GraphQLObjectType parentType = node.getType(); - List fields = node.getFields().get(fieldName); - - GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, fields.get(0)); - - Instrumentation instrumentation = executionContext.getInstrumentation(); - ExecutionTypeInfo typeInfo = parameters.getTypeInfo(); - InstrumentationContext fieldCtx = instrumentation.beginField( - new InstrumentationFieldParameters(executionContext, fieldDef, typeInfo) - ); - - CompletableFuture fetchedData = fetchData(executionContext, parameters, fieldName, node, fieldDef); - - CompletableFuture> result = fetchedData.thenApply((fetchedValues) -> { - - GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility(); - Map argumentValues = valuesResolver.getArgumentValues( - fieldVisibility, - fieldDef.getArguments(), fields.get(0).getArguments(), executionContext.getVariables()); - - return completeValues(executionContext, fetchedValues, typeInfo, fieldName, fields, argumentValues); - }); - fieldCtx.onDispatched(null); - result = result.whenComplete((nodes, throwable) -> fieldCtx.onCompleted(null, throwable)); - return result; - - } - - private CompletableFuture fetchData(ExecutionContext executionContext, - ExecutionStrategyParameters parameters, - String fieldName, - ExecutionNode node, - GraphQLFieldDefinition fieldDef) { - GraphQLObjectType parentType = node.getType(); - List fields = node.getFields().get(fieldName); - List parentResults = node.getParentResults(); - - GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility(); - Map argumentValues = valuesResolver.getArgumentValues( - fieldVisibility, - fieldDef.getArguments(), fields.get(0).getArguments(), executionContext.getVariables()); - - GraphQLOutputType fieldType = fieldDef.getType(); - DataFetchingFieldSelectionSet fieldCollector = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, fieldType, fields); - - DataFetchingEnvironment environment = newDataFetchingEnvironment(executionContext) - .source(node.getSources()) - .arguments(argumentValues) - .fieldDefinition(fieldDef) - .fields(fields) - .fieldType(fieldDef.getType()) - .fieldTypeInfo(parameters.getTypeInfo()) - .parentType(parentType) - .selectionSet(fieldCollector) - .build(); - - Instrumentation instrumentation = executionContext.getInstrumentation(); - InstrumentationFieldFetchParameters instrumentationFieldFetchParameters = - new InstrumentationFieldFetchParameters(executionContext, fieldDef, environment, parameters); - InstrumentationContext fetchCtx = instrumentation.beginFieldFetch(instrumentationFieldFetchParameters); - - CompletableFuture fetchedValue; - try { - DataFetcher dataFetcher = instrumentation.instrumentDataFetcher( - getDataFetcher(fieldDef), instrumentationFieldFetchParameters); - Object fetchedValueRaw = dataFetcher.get(environment); - fetchedValue = Async.toCompletableFuture(fetchedValueRaw); - } catch (Exception e) { - fetchedValue = new CompletableFuture<>(); - fetchedValue.completeExceptionally(e); - } - return fetchedValue - .thenApply((result) -> assertResult(parentResults, result)) - .whenComplete(fetchCtx::onCompleted) - .handle(handleResult(executionContext, parameters, parentResults, fields, fieldDef, argumentValues, environment)); - } - - private BiFunction, Throwable, FetchedValues> handleResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters, List parentResults, List fields, GraphQLFieldDefinition fieldDef, Map argumentValues, DataFetchingEnvironment environment) { - return (result, exception) -> { - if (exception != null) { - if (exception instanceof CompletionException) { - exception = exception.getCause(); - } - DataFetcherExceptionHandlerParameters handlerParameters = DataFetcherExceptionHandlerParameters.newExceptionParameters() - .executionContext(executionContext) - .dataFetchingEnvironment(environment) - .argumentValues(argumentValues) - .field(fields.get(0)) - .fieldDefinition(fieldDef) - .path(parameters.getPath()) - .exception(exception) - .build(); - dataFetcherExceptionHandler.accept(handlerParameters); - result = Collections.nCopies(parentResults.size(), null); - } - List values = result; - List retVal = new ArrayList<>(); - for (int i = 0; i < parentResults.size(); i++) { - Object value = unboxPossibleOptional(values.get(i)); - retVal.add(new FetchedValue(parentResults.get(i), value)); - } - return new FetchedValues(retVal, parameters.getTypeInfo(), parameters.getPath()); - }; - } - - private List assertResult(List parentResults, Object result) { - result = convertPossibleArray(result); - if (result != null && !(result instanceof Iterable)) { - throw new BatchAssertionFailed(String.format("BatchedDataFetcher provided an invalid result: Iterable expected but got '%s'. Affected fields are set to null.", result.getClass().getName())); - } - @SuppressWarnings("unchecked") - Iterable iterableResult = (Iterable) result; - if (iterableResult == null) { - throw new BatchAssertionFailed("BatchedDataFetcher provided a null Iterable of result values. Affected fields are set to null."); - } - List resultList = new ArrayList<>(); - iterableResult.forEach(resultList::add); - - long size = resultList.size(); - if (size != parentResults.size()) { - throw new BatchAssertionFailed(String.format("BatchedDataFetcher provided invalid number of result values, expected %d but got %d. Affected fields are set to null.", parentResults.size(), size)); - } - return resultList; - } - - private List completeValues(ExecutionContext executionContext, - FetchedValues fetchedValues, ExecutionTypeInfo typeInfo, - String fieldName, List fields, - Map argumentValues) { - - handleNonNullType(executionContext, fetchedValues); - - GraphQLType unwrappedFieldType = typeInfo.getType(); - - if (isPrimitive(unwrappedFieldType)) { - handlePrimitives(fetchedValues, fieldName, unwrappedFieldType); - return Collections.emptyList(); - } else if (isObject(unwrappedFieldType)) { - return handleObject(executionContext, argumentValues, fetchedValues, fieldName, fields, typeInfo); - } else if (isList(unwrappedFieldType)) { - return handleList(executionContext, argumentValues, fetchedValues, fieldName, fields, typeInfo); - } else { - return Assert.assertShouldNeverHappen("can't handle type: %s", unwrappedFieldType); - } - } - - @SuppressWarnings("unchecked") - private List handleList(ExecutionContext executionContext, Map argumentValues, - FetchedValues fetchedValues, String fieldName, List fields, - ExecutionTypeInfo typeInfo) { - - GraphQLList listType = (GraphQLList) typeInfo.getType(); - List flattenedValues = new ArrayList<>(); - - for (FetchedValue value : fetchedValues.getValues()) { - MapOrList mapOrList = value.getParentResult(); - - if (value.getValue() == null) { - mapOrList.putOrAdd(fieldName, null); - continue; - } - - MapOrList listResult = mapOrList.createAndPutList(fieldName); - for (Object rawValue : toIterable(value.getValue())) { - rawValue = unboxPossibleOptional(rawValue); - flattenedValues.add(new FetchedValue(listResult, rawValue)); - } - } - GraphQLOutputType innerSubType = (GraphQLOutputType) listType.getWrappedType(); - ExecutionTypeInfo newTypeInfo = typeInfo.treatAs(innerSubType); - FetchedValues flattenedFetchedValues = new FetchedValues(flattenedValues, newTypeInfo, fetchedValues.getPath()); - - return completeValues(executionContext, flattenedFetchedValues, newTypeInfo, fieldName, fields, argumentValues); - } - - @SuppressWarnings("UnnecessaryLocalVariable") - private List handleObject(ExecutionContext executionContext, Map argumentValues, - FetchedValues fetchedValues, String fieldName, List fields, - ExecutionTypeInfo typeInfo) { - - // collect list of values by actual type (needed because of interfaces and unions) - Map> resultsByType = new LinkedHashMap<>(); - Map> sourceByType = new LinkedHashMap<>(); - - for (FetchedValue value : fetchedValues.getValues()) { - MapOrList mapOrList = value.getParentResult(); - if (value.getValue() == null) { - mapOrList.putOrAdd(fieldName, null); - continue; - } - MapOrList childResult = mapOrList.createAndPutMap(fieldName); - - GraphQLObjectType resolvedType = getGraphQLObjectType(executionContext, fields.get(0), typeInfo.getType(), value.getValue(), argumentValues); - resultsByType.putIfAbsent(resolvedType, new ArrayList<>()); - resultsByType.get(resolvedType).add(childResult); - - sourceByType.putIfAbsent(resolvedType, new ArrayList<>()); - sourceByType.get(resolvedType).add(value.getValue()); - } - - List childNodes = new ArrayList<>(); - for (GraphQLObjectType resolvedType : resultsByType.keySet()) { - List results = resultsByType.get(resolvedType); - List sources = sourceByType.get(resolvedType); - Map> childFields = getChildFields(executionContext, resolvedType, fields); - - ExecutionTypeInfo newTypeInfo = typeInfo.treatAs(resolvedType); - - childNodes.add(new ExecutionNode(resolvedType, newTypeInfo, childFields, results, sources)); - } - return childNodes; - } - - - private void handleNonNullType(ExecutionContext executionContext, FetchedValues fetchedValues) { - - ExecutionTypeInfo typeInfo = fetchedValues.getExecutionTypeInfo(); - NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo); - ExecutionPath path = fetchedValues.getPath(); - for (FetchedValue value : fetchedValues.getValues()) { - nonNullableFieldValidator.validate(path, value.getValue()); - } - } - - private Map> getChildFields(ExecutionContext executionContext, GraphQLObjectType resolvedType, - List fields) { - - FieldCollectorParameters collectorParameters = newParameters() - .schema(executionContext.getGraphQLSchema()) - .objectType(resolvedType) - .fragments(executionContext.getFragmentsByName()) - .variables(executionContext.getVariables()) - .build(); - - return fieldCollector.collectFields(collectorParameters, fields); - } - - private GraphQLObjectType getGraphQLObjectType(ExecutionContext executionContext, Field field, GraphQLType fieldType, Object value, Map argumentValues) { - GraphQLObjectType resolvedType = null; - if (fieldType instanceof GraphQLInterfaceType) { - resolvedType = resolveTypeForInterface(TypeResolutionParameters.newParameters() - .graphQLInterfaceType((GraphQLInterfaceType) fieldType) - .field(field) - .value(value) - .argumentValues(argumentValues) - .context(executionContext.getContext()) - .schema(executionContext.getGraphQLSchema()) - .build()); - } else if (fieldType instanceof GraphQLUnionType) { - resolvedType = resolveTypeForUnion(TypeResolutionParameters.newParameters() - .graphQLUnionType((GraphQLUnionType) fieldType) - .field(field) - .value(value) - .argumentValues(argumentValues) - .context(executionContext.getContext()) - .schema(executionContext.getGraphQLSchema()) - .build()); - } else if (fieldType instanceof GraphQLObjectType) { - resolvedType = (GraphQLObjectType) fieldType; - } - return resolvedType; - } - - private void handlePrimitives(FetchedValues fetchedValues, String fieldName, GraphQLType fieldType) { - for (FetchedValue value : fetchedValues.getValues()) { - Object coercedValue = coerce(fieldType, value.getValue()); - //6.6.1 http://facebook.github.io/graphql/#sec-Field-entries - if (coercedValue instanceof Double && ((Double) coercedValue).isNaN()) { - coercedValue = null; - } - value.getParentResult().putOrAdd(fieldName, coercedValue); - } - } - - private Object coerce(GraphQLType type, Object value) { - if (value == null) return null; - if (type instanceof GraphQLEnumType) { - return ((GraphQLEnumType) type).getCoercing().serialize(value); - } else { - return ((GraphQLScalarType) type).getCoercing().serialize(value); - } - } - - private boolean isList(GraphQLType type) { - return type instanceof GraphQLList; - } - - private boolean isPrimitive(GraphQLType type) { - return type instanceof GraphQLScalarType || type instanceof GraphQLEnumType; - } - - private boolean isObject(GraphQLType type) { - return type instanceof GraphQLObjectType || - type instanceof GraphQLInterfaceType || - type instanceof GraphQLUnionType; - } - - - private Object convertPossibleArray(Object result) { - if (result != null && result.getClass().isArray()) { - return IntStream.range(0, Array.getLength(result)) - .mapToObj(i -> Array.get(result, i)) - .collect(toList()); - } - return result; - } - - private BatchedDataFetcher getDataFetcher(GraphQLFieldDefinition fieldDef) { - DataFetcher supplied = fieldDef.getDataFetcher(); - return batchingFactory.create(supplied); - } -} diff --git a/src/main/java/graphql/execution/batched/ExecutionNode.java b/src/main/java/graphql/execution/batched/ExecutionNode.java deleted file mode 100644 index 6b99f39f5e..0000000000 --- a/src/main/java/graphql/execution/batched/ExecutionNode.java +++ /dev/null @@ -1,49 +0,0 @@ -package graphql.execution.batched; - -import graphql.execution.ExecutionTypeInfo; -import graphql.language.Field; -import graphql.schema.GraphQLObjectType; - -import java.util.List; -import java.util.Map; - -class ExecutionNode { - - private final GraphQLObjectType type; - private final ExecutionTypeInfo typeInfo; - private final Map> fields; - private final List parentResults; - private final List sources; - - public ExecutionNode(GraphQLObjectType type, - ExecutionTypeInfo typeInfo, - Map> fields, - List parentResults, - List sources) { - this.type = type; - this.typeInfo = typeInfo; - this.fields = fields; - this.parentResults = parentResults; - this.sources = sources; - } - - public GraphQLObjectType getType() { - return type; - } - - public ExecutionTypeInfo getTypeInfo() { - return typeInfo; - } - - public Map> getFields() { - return fields; - } - - public List getParentResults() { - return parentResults; - } - - public List getSources() { - return sources; - } -} diff --git a/src/main/java/graphql/execution/batched/FetchedValue.java b/src/main/java/graphql/execution/batched/FetchedValue.java deleted file mode 100644 index 537d2f9ade..0000000000 --- a/src/main/java/graphql/execution/batched/FetchedValue.java +++ /dev/null @@ -1,20 +0,0 @@ -package graphql.execution.batched; - -public class FetchedValue { - - private final MapOrList mapOrList; - private final Object value; - - public FetchedValue(MapOrList parentResult, Object value) { - this.mapOrList = parentResult; - this.value = value; - } - - public MapOrList getParentResult() { - return mapOrList; - } - - public Object getValue() { - return value; - } -} diff --git a/src/main/java/graphql/execution/batched/FetchedValues.java b/src/main/java/graphql/execution/batched/FetchedValues.java deleted file mode 100644 index 48d1299ad3..0000000000 --- a/src/main/java/graphql/execution/batched/FetchedValues.java +++ /dev/null @@ -1,31 +0,0 @@ -package graphql.execution.batched; - -import graphql.execution.ExecutionPath; -import graphql.execution.ExecutionTypeInfo; - -import java.util.List; - -public class FetchedValues { - - private final List fetchedValues; - private final ExecutionTypeInfo executionTypeInfo; - private final ExecutionPath path; - - public FetchedValues(List fetchedValues, ExecutionTypeInfo executionTypeInfo, ExecutionPath path) { - this.fetchedValues = fetchedValues; - this.executionTypeInfo = executionTypeInfo; - this.path = path; - } - - public List getValues() { - return fetchedValues; - } - - public ExecutionTypeInfo getExecutionTypeInfo() { - return executionTypeInfo; - } - - public ExecutionPath getPath() { - return path; - } -} diff --git a/src/main/java/graphql/execution/batched/MapOrList.java b/src/main/java/graphql/execution/batched/MapOrList.java deleted file mode 100644 index 926e1c5ff9..0000000000 --- a/src/main/java/graphql/execution/batched/MapOrList.java +++ /dev/null @@ -1,57 +0,0 @@ -package graphql.execution.batched; - -import graphql.Internal; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -@Internal -public class MapOrList { - - - private Map map; - private List list; - - public static MapOrList createList(List list) { - MapOrList mapOrList = new MapOrList(); - mapOrList.list = list; - return mapOrList; - } - - public static MapOrList createMap(Map map) { - MapOrList mapOrList = new MapOrList(); - mapOrList.map = map; - return mapOrList; - } - - public MapOrList createAndPutMap(String key) { - Map map = new LinkedHashMap<>(); - putOrAdd(key, map); - return createMap(map); - } - - public MapOrList createAndPutList(String key) { - List resultList = new ArrayList<>(); - putOrAdd(key, resultList); - return createList(resultList); - } - - public void putOrAdd(String fieldName, Object value) { - if (this.map != null) { - this.map.put(fieldName, value); - } else { - this.list.add(value); - } - } - - - public Object toObject() { - if (this.map != null) { - return this.map; - } else { - return this.list; - } - } -} diff --git a/src/main/java/graphql/execution/batched/UnbatchedDataFetcher.java b/src/main/java/graphql/execution/batched/UnbatchedDataFetcher.java deleted file mode 100644 index ce5ac58686..0000000000 --- a/src/main/java/graphql/execution/batched/UnbatchedDataFetcher.java +++ /dev/null @@ -1,41 +0,0 @@ -package graphql.execution.batched; - - -import graphql.execution.Async; -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import static graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment; - -/** - * Given a normal data fetcher as a delegate, - * uses that fetcher in a batched context by iterating through each source value and calling - * the delegate. - */ -public class UnbatchedDataFetcher implements BatchedDataFetcher { - - private final DataFetcher delegate; - - public UnbatchedDataFetcher(DataFetcher delegate) { - this.delegate = delegate; - } - - - @Override - public CompletableFuture> get(DataFetchingEnvironment environment) { - List sources = environment.getSource(); - List> results = new ArrayList<>(); - for (Object source : sources) { - - DataFetchingEnvironment singleEnv = newDataFetchingEnvironment(environment) - .source(source).build(); - CompletableFuture cf = Async.toCompletableFuture(delegate.get(singleEnv)); - results.add(cf); - } - return Async.each(results); - } -} diff --git a/src/main/java/graphql/execution/conditional/ConditionalNodeDecision.java b/src/main/java/graphql/execution/conditional/ConditionalNodeDecision.java new file mode 100644 index 0000000000..69afc6bbc2 --- /dev/null +++ b/src/main/java/graphql/execution/conditional/ConditionalNodeDecision.java @@ -0,0 +1,23 @@ +package graphql.execution.conditional; + +import graphql.ExperimentalApi; + +/** + * This callback interface allows custom implementations to decide if a field is included in a query or not. + *

+ * The default `@skip / @include` is built in, but you can create your own implementations to allow you to make + * decisions on whether fields are considered part of a query. + */ +@ExperimentalApi +public interface ConditionalNodeDecision { + + /** + * This is called to decide if a {@link graphql.language.Node} should be included or not + * + * @param decisionEnv ghe environment you can use to make the decision + * + * @return true if the node should be included or false if it should be excluded + */ + boolean shouldInclude(ConditionalNodeDecisionEnvironment decisionEnv); +} + diff --git a/src/main/java/graphql/execution/conditional/ConditionalNodeDecisionEnvironment.java b/src/main/java/graphql/execution/conditional/ConditionalNodeDecisionEnvironment.java new file mode 100644 index 0000000000..8851e2df4a --- /dev/null +++ b/src/main/java/graphql/execution/conditional/ConditionalNodeDecisionEnvironment.java @@ -0,0 +1,49 @@ +package graphql.execution.conditional; + +import graphql.GraphQLContext; +import graphql.execution.CoercedVariables; +import graphql.language.Directive; +import graphql.language.DirectivesContainer; +import graphql.schema.GraphQLSchema; +import org.jspecify.annotations.Nullable; + +import java.util.List; + +/** + * The parameters given to a {@link ConditionalNodeDecision} + */ +public interface ConditionalNodeDecisionEnvironment { + + /** + * This is an AST {@link graphql.language.Node} that has directives on it. + * {@link graphql.language.Field}, @{@link graphql.language.FragmentSpread} and + * {@link graphql.language.InlineFragment} are examples of nodes + * that can be conditionally included. + * + * @return the AST element in question + */ + DirectivesContainer getDirectivesContainer(); + + /** + * @return the list of directives associated with the {@link #getDirectivesContainer()} + */ + default List getDirectives() { + return getDirectivesContainer().getDirectives(); + } + + /** + * @return a map of the current variables + */ + CoercedVariables getVariables(); + + /** + * @return the {@link GraphQLSchema} in question - this can be null for certain call paths + */ + @Nullable + GraphQLSchema getGraphQlSchema(); + + /** + * @return a graphql context + */ + GraphQLContext getGraphQLContext(); +} diff --git a/src/main/java/graphql/execution/conditional/ConditionalNodes.java b/src/main/java/graphql/execution/conditional/ConditionalNodes.java new file mode 100644 index 0000000000..e922eeb427 --- /dev/null +++ b/src/main/java/graphql/execution/conditional/ConditionalNodes.java @@ -0,0 +1,156 @@ +package graphql.execution.conditional; + +import graphql.Assert; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.language.Argument; +import graphql.language.BooleanValue; +import graphql.language.Directive; +import graphql.language.DirectivesContainer; +import graphql.language.NodeUtil; +import graphql.language.VariableReference; +import graphql.schema.GraphQLSchema; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +import static graphql.Directives.IncludeDirective; +import static graphql.Directives.SkipDirective; + +@Internal +public class ConditionalNodes { + + /** + * return null if skip/include argument contains a variable and therefore could not be resolved + */ + public Boolean shouldIncludeWithoutVariables(DirectivesContainer element) { + return shouldInclude(null, element.getDirectives()); + } + + public boolean shouldInclude(DirectivesContainer element, + Map variables, + GraphQLSchema graphQLSchema, + @Nullable GraphQLContext graphQLContext + ) { + // + // call the base @include / @skip first + if (!shouldInclude(variables, element.getDirectives())) { + return false; + } + // + // if they have declared a decision callback, then we will use it but we expect this to be mostly + // empty and hence the cost is a map lookup. + if (graphQLContext != null) { + ConditionalNodeDecision conditionalDecision = graphQLContext.get(ConditionalNodeDecision.class); + if (conditionalDecision != null) { + return customShouldInclude(variables, element, graphQLSchema, graphQLContext, conditionalDecision); + } + } + // if no one says otherwise, the node is considered included + return true; + } + + private boolean customShouldInclude(Map variables, + DirectivesContainer element, + GraphQLSchema graphQLSchema, + GraphQLContext graphQLContext, + ConditionalNodeDecision conditionalDecision + ) { + CoercedVariables coercedVariables = CoercedVariables.of(variables); + return conditionalDecision.shouldInclude(new ConditionalNodeDecisionEnvironment() { + @Override + public DirectivesContainer getDirectivesContainer() { + return element; + } + + @Override + public CoercedVariables getVariables() { + return coercedVariables; + } + + @Override + public GraphQLSchema getGraphQlSchema() { + return graphQLSchema; + } + + @Override + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + }); + } + + + private @Nullable Boolean shouldInclude(Map variables, List directives) { + // shortcut on no directives + if (directives.isEmpty()) { + return true; + } + Boolean skip = getDirectiveResult(variables, directives, SkipDirective.getName(), false); + if (skip == null) { + return null; + } + if (skip) { + return false; + } + + return getDirectiveResult(variables, directives, IncludeDirective.getName(), true); + } + + public boolean containsSkipOrIncludeDirective(DirectivesContainer directivesContainer) { + return NodeUtil.findNodeByName(directivesContainer.getDirectives(), SkipDirective.getName()) != null || + NodeUtil.findNodeByName(directivesContainer.getDirectives(), IncludeDirective.getName()) != null; + } + + + public String getSkipVariableName(DirectivesContainer directivesContainer) { + Directive skipDirective = NodeUtil.findNodeByName(directivesContainer.getDirectives(), SkipDirective.getName()); + if (skipDirective == null) { + return null; + } + Argument argument = skipDirective.getArgument("if"); + if (argument.getValue() instanceof VariableReference) { + return ((VariableReference) argument.getValue()).getName(); + } + return null; + } + + public String getIncludeVariableName(DirectivesContainer directivesContainer) { + Directive skipDirective = NodeUtil.findNodeByName(directivesContainer.getDirectives(), IncludeDirective.getName()); + if (skipDirective == null) { + return null; + } + Argument argument = skipDirective.getArgument("if"); + if (argument.getValue() instanceof VariableReference) { + return ((VariableReference) argument.getValue()).getName(); + } + return null; + } + + + private @Nullable Boolean getDirectiveResult(Map variables, List directives, String directiveName, boolean defaultValue) { + Directive foundDirective = NodeUtil.findNodeByName(directives, directiveName); + if (foundDirective != null) { + return getIfValue(foundDirective.getArguments(), variables); + } + return defaultValue; + } + + private @Nullable Boolean getIfValue(List arguments, @Nullable Map variables) { + for (Argument argument : arguments) { + if (argument.getName().equals("if")) { + Object value = argument.getValue(); + if (value instanceof BooleanValue) { + return ((BooleanValue) value).isValue(); + } + if (value instanceof VariableReference && variables != null) { + return (boolean) variables.get(((VariableReference) value).getName()); + } + return null; + } + } + return Assert.assertShouldNeverHappen("The 'if' argument must be present"); + } +} diff --git a/src/main/java/graphql/execution/defer/DeferSupport.java b/src/main/java/graphql/execution/defer/DeferSupport.java deleted file mode 100644 index f5163a5af8..0000000000 --- a/src/main/java/graphql/execution/defer/DeferSupport.java +++ /dev/null @@ -1,72 +0,0 @@ -package graphql.execution.defer; - -import graphql.Directives; -import graphql.ExecutionResult; -import graphql.Internal; -import graphql.execution.reactive.SingleSubscriberPublisher; -import graphql.language.Field; -import org.reactivestreams.Publisher; - -import java.util.Deque; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * This provides support for @defer directives on fields that mean that results will be sent AFTER - * the main result is sent via a Publisher stream. - */ -@Internal -public class DeferSupport { - - private final AtomicBoolean deferDetected = new AtomicBoolean(false); - private final Deque deferredCalls = new ConcurrentLinkedDeque<>(); - private final SingleSubscriberPublisher publisher = new SingleSubscriberPublisher<>(); - - public boolean checkForDeferDirective(List currentField) { - for (Field field : currentField) { - if (field.getDirective(Directives.DeferDirective.getName()) != null) { - return true; - } - } - return false; - } - - @SuppressWarnings("FutureReturnValueIgnored") - private void drainDeferredCalls() { - if (deferredCalls.isEmpty()) { - publisher.noMoreData(); - return; - } - DeferredCall deferredCall = deferredCalls.pop(); - CompletableFuture future = deferredCall.invoke(); - future.whenComplete((executionResult, exception) -> { - if (exception != null) { - publisher.offerError(exception); - return; - } - publisher.offer(executionResult); - drainDeferredCalls(); - }); - } - - public void enqueue(DeferredCall deferredCall) { - deferDetected.set(true); - deferredCalls.offer(deferredCall); - } - - public boolean isDeferDetected() { - return deferDetected.get(); - } - - /** - * When this is called the deferred execution will begin - * - * @return the publisher of deferred results - */ - public Publisher startDeferredCalls() { - drainDeferredCalls(); - return publisher; - } -} diff --git a/src/main/java/graphql/execution/defer/DeferredCall.java b/src/main/java/graphql/execution/defer/DeferredCall.java deleted file mode 100644 index 0ac99d807c..0000000000 --- a/src/main/java/graphql/execution/defer/DeferredCall.java +++ /dev/null @@ -1,42 +0,0 @@ -package graphql.execution.defer; - -import graphql.ExecutionResult; -import graphql.ExecutionResultImpl; -import graphql.GraphQLError; -import graphql.Internal; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; - -/** - * This represents a deferred call (aka @defer) to get an execution result sometime after - * the initial query has returned - */ -@Internal -public class DeferredCall { - private final Supplier> call; - private final DeferredErrorSupport errorSupport; - - public DeferredCall(Supplier> call, DeferredErrorSupport deferredErrorSupport) { - this.call = call; - this.errorSupport = deferredErrorSupport; - } - - CompletableFuture invoke() { - CompletableFuture future = call.get(); - return future.thenApply(this::addErrorsEncountered); - } - - private ExecutionResult addErrorsEncountered(ExecutionResult executionResult) { - List errorsEncountered = errorSupport.getErrors(); - if (errorsEncountered.isEmpty()) { - return executionResult; - } - ExecutionResultImpl sourceResult = (ExecutionResultImpl) executionResult; - ExecutionResultImpl.Builder builder = ExecutionResultImpl.newExecutionResult().from(sourceResult); - builder.addErrors(errorsEncountered); - return builder.build(); - } - -} diff --git a/src/main/java/graphql/execution/defer/DeferredErrorSupport.java b/src/main/java/graphql/execution/defer/DeferredErrorSupport.java deleted file mode 100644 index b1b1043760..0000000000 --- a/src/main/java/graphql/execution/defer/DeferredErrorSupport.java +++ /dev/null @@ -1,31 +0,0 @@ -package graphql.execution.defer; - -import graphql.ExceptionWhileDataFetching; -import graphql.GraphQLError; -import graphql.Internal; -import graphql.execution.ExecutionStrategyParameters; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * This captures errors that occur while a deferred call is being made - */ -@Internal -public class DeferredErrorSupport { - - private final List errors = new CopyOnWriteArrayList<>(); - - public void onFetchingException(ExecutionStrategyParameters parameters, Throwable e) { - ExceptionWhileDataFetching error = new ExceptionWhileDataFetching(parameters.getPath(), e, parameters.getField().get(0).getSourceLocation()); - onError(error); - } - - public void onError(GraphQLError gError) { - errors.add(gError); - } - - public List getErrors() { - return errors; - } -} diff --git a/src/main/java/graphql/execution/directives/DirectivesResolver.java b/src/main/java/graphql/execution/directives/DirectivesResolver.java new file mode 100644 index 0000000000..4f177052e4 --- /dev/null +++ b/src/main/java/graphql/execution/directives/DirectivesResolver.java @@ -0,0 +1,64 @@ +package graphql.execution.directives; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.ImmutableBiMap; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.execution.ValuesResolver; +import graphql.language.Directive; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLSchema; + +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * This turns AST directives into runtime directives with resolved types and so on + */ +@Internal +public class DirectivesResolver { + + public DirectivesResolver() { + } + + public BiMap resolveDirectives(List directives, GraphQLSchema schema, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) { + GraphQLCodeRegistry codeRegistry = schema.getCodeRegistry(); + BiMap directiveMap = HashBiMap.create(); + directives.forEach(directive -> { + GraphQLDirective protoType = schema.getDirective(directive.getName()); + if (protoType != null) { + GraphQLDirective graphQLDirective = protoType.transform(builder -> buildArguments(builder, codeRegistry, protoType, directive, variables, graphQLContext, locale)); + directiveMap.put(graphQLDirective, directive); + } + }); + return ImmutableBiMap.copyOf(directiveMap); + } + + private void buildArguments(GraphQLDirective.Builder directiveBuilder, + GraphQLCodeRegistry codeRegistry, + GraphQLDirective protoType, + Directive fieldDirective, + CoercedVariables variables, + GraphQLContext graphQLContext, + Locale locale) { + Map argumentValues = ValuesResolver.getArgumentValues(codeRegistry, protoType.getArguments(), fieldDirective.getArguments(), variables, graphQLContext, locale); + directiveBuilder.clearArguments(); + protoType.getArguments().forEach(protoArg -> { + if (argumentValues.containsKey(protoArg.getName())) { + Object argValue = argumentValues.get(protoArg.getName()); + GraphQLArgument newArgument = protoArg.transform(argBuilder -> argBuilder.value(argValue)); + directiveBuilder.argument(newArgument); + } else { + // this means they can ask for the argument default value because the argument on the directive + // object is present - but null + GraphQLArgument newArgument = protoArg.transform(argBuilder -> argBuilder.value(null)); + directiveBuilder.argument(newArgument); + } + }); + } +} diff --git a/src/main/java/graphql/execution/directives/QueryAppliedDirective.java b/src/main/java/graphql/execution/directives/QueryAppliedDirective.java new file mode 100644 index 0000000000..84492143fd --- /dev/null +++ b/src/main/java/graphql/execution/directives/QueryAppliedDirective.java @@ -0,0 +1,190 @@ +package graphql.execution.directives; + + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.language.Directive; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphqlTypeBuilder; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertValidName; +import static graphql.util.FpKit.getByName; + +/** + * An applied directive represents the instance of a directive that is applied to a query element such as a field or fragment. + *

+ * Originally graphql-java re-used the {@link GraphQLDirective} and {@link GraphQLArgument} + * classes to do both purposes. This was a modelling mistake. New {@link QueryAppliedDirective} and {@link QueryAppliedDirectiveArgument} + * classes have been introduced to better model when a directive is applied to a query element, + * as opposed to its schema definition itself. + *

+ * See https://graphql.org/learn/queries/#directives for more details on the concept. + */ +@PublicApi +public class QueryAppliedDirective { + + private final String name; + private final ImmutableList arguments; + private final Directive definition; + + private QueryAppliedDirective(String name, Directive definition, Collection arguments) { + assertValidName(name); + assertNotNull(arguments, "arguments can't be null"); + this.name = name; + this.arguments = ImmutableList.copyOf(arguments); + this.definition = definition; + } + + @NonNull + public String getName() { + return name; + } + + @Nullable + public String getDescription() { + return null; + } + + public List getArguments() { + return arguments; + } + + @Nullable + public QueryAppliedDirectiveArgument getArgument(String name) { + for (QueryAppliedDirectiveArgument argument : arguments) { + if (argument.getName().equals(name)) { + return argument; + } + } + return null; + } + + @Nullable + public Directive getDefinition() { + return definition; + } + + @Override + public String toString() { + return new StringJoiner(", ", QueryAppliedDirective.class.getSimpleName() + "[", "]") + .add("name='" + name + "'") + .add("arguments=" + arguments) + .add("definition=" + definition) + .toString(); + } + + /** + * This helps you transform the current GraphQLDirective into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new field based on calling build on that builder + */ + public QueryAppliedDirective transform(Consumer builderConsumer) { + Builder builder = newDirective(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newDirective() { + return new Builder(); + } + + public static Builder newDirective(QueryAppliedDirective existing) { + return new Builder(existing); + } + + public static class Builder extends GraphqlTypeBuilder { + + private final Map arguments = new LinkedHashMap<>(); + private Directive definition; + + public Builder() { + } + + public Builder(QueryAppliedDirective existing) { + this.name = existing.getName(); + this.description = existing.getDescription(); + this.arguments.putAll(getByName(existing.getArguments(), QueryAppliedDirectiveArgument::getName)); + } + + public Builder argument(QueryAppliedDirectiveArgument argument) { + assertNotNull(argument,"argument must not be null"); + arguments.put(argument.getName(), argument); + return this; + } + + public Builder replaceArguments(List arguments) { + assertNotNull(arguments, "arguments must not be null"); + this.arguments.clear(); + for (QueryAppliedDirectiveArgument argument : arguments) { + this.arguments.put(argument.getName(), argument); + } + return this; + } + + /** + * Take an argument builder in a function definition and apply. Can be used in a jdk8 lambda + * e.g.: + *

+         *     {@code
+         *      argument(a -> a.name("argumentName"))
+         *     }
+         * 
+ * + * @param builderFunction a supplier for the builder impl + * + * @return this + */ + public Builder argument(UnaryOperator builderFunction) { + QueryAppliedDirectiveArgument.Builder builder = QueryAppliedDirectiveArgument.newArgument(); + builder = builderFunction.apply(builder); + return argument(builder); + } + + /** + * Same effect as the argument(GraphQLAppliedDirectiveArgument). Builder.build() is called + * from within + * + * @param builder an un-built/incomplete GraphQLAppliedDirectiveArgument + * + * @return this + */ + public Builder argument(QueryAppliedDirectiveArgument.Builder builder) { + return argument(builder.build()); + } + + /** + * This is used to clear all the arguments in the builder so far. + * + * @return the builder + */ + public Builder clearArguments() { + arguments.clear(); + return this; + } + + + public Builder definition(Directive definition) { + this.definition = definition; + return this; + } + + public QueryAppliedDirective build() { + return new QueryAppliedDirective(name, this.definition, arguments.values()); + } + } +} diff --git a/src/main/java/graphql/execution/directives/QueryAppliedDirectiveArgument.java b/src/main/java/graphql/execution/directives/QueryAppliedDirectiveArgument.java new file mode 100644 index 0000000000..8b772e91f7 --- /dev/null +++ b/src/main/java/graphql/execution/directives/QueryAppliedDirectiveArgument.java @@ -0,0 +1,209 @@ +package graphql.execution.directives; + + +import graphql.Assert; +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.language.Argument; +import graphql.language.Value; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphqlTypeBuilder; +import graphql.schema.InputValueWithState; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Locale; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertValidName; +import static graphql.execution.ValuesResolver.getInputValueImpl; + +/** + * This represents the argument values that can be placed on an {@link QueryAppliedDirective}. + *

+ * You can think of them as 'instances' of {@link GraphQLArgument}, when applied to a directive on a query element + */ +@PublicApi +public class QueryAppliedDirectiveArgument { + + private final String name; + private final InputValueWithState value; + private final GraphQLInputType originalType; + + private final Argument definition; + + + private QueryAppliedDirectiveArgument(String name, + InputValueWithState value, + GraphQLInputType type, + Argument definition + ) { + assertValidName(name); + this.name = name; + this.value = assertNotNull(value); + this.originalType = assertNotNull(type); + this.definition = definition; + } + + @NonNull + public String getName() { + return name; + } + + @NonNull + public GraphQLInputType getType() { + return originalType; + } + + public boolean hasSetValue() { + return value.isSet(); + } + + /** + * @return an input value with state for an applied directive argument + */ + public @NonNull InputValueWithState getArgumentValue() { + return value; + } + + /** + * This swill give out an internal java value based on the semantics captured + * in the {@link InputValueWithState} from {@link QueryAppliedDirectiveArgument#getArgumentValue()} + * + * Note : You MUST only call this on a {@link QueryAppliedDirectiveArgument} that is part of a fully formed schema. We need + * all the types to be resolved in order for this work correctly. + * + * Note: This method will return null if the value is not set or explicitly set to null. If you want to know the difference + * when "not set" and "set to null" then you can't use this method. Rather you should use {@link QueryAppliedDirectiveArgument#getArgumentValue()} + * and use the {@link InputValueWithState#isNotSet()} methods to decide how to handle those values. + * + * @param the type you want it cast as + * + * @return a value of type T which is the java value of the argument + */ + @Nullable + public T getValue() { + return getInputValueImpl(getType(), value, GraphQLContext.getDefault(), Locale.getDefault()); + } + + /** + * This will always be null. Applied arguments have no description + * + * @return always null + */ + public @Nullable String getDescription() { + return null; + } + + @Nullable + public Argument getDefinition() { + return definition; + } + + + /** + * This helps you transform the current GraphQLArgument into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new field based on calling build on that builder + */ + public QueryAppliedDirectiveArgument transform(Consumer builderConsumer) { + Builder builder = newArgument(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newArgument() { + return new Builder(); + } + + public static Builder newArgument(QueryAppliedDirectiveArgument existing) { + return new Builder(existing); + } + + @Override + public String toString() { + return "QueryAppliedDirectiveArgument{" + + "name='" + name + '\'' + + ", type=" + getType() + + ", value=" + value + + '}'; + } + + public static class Builder extends GraphqlTypeBuilder { + + private InputValueWithState value = InputValueWithState.NOT_SET; + private Argument definition; + private GraphQLInputType type; + + public Builder() { + } + + public Builder(QueryAppliedDirectiveArgument existing) { + this.name = existing.getName(); + this.value = existing.getArgumentValue(); + this.type = existing.getType(); + } + + public Builder type(GraphQLInputType type) { + this.type = assertNotNull(type); + return this; + } + + public Builder definition(Argument definition) { + this.definition = definition; + return this; + } + + /** + * Sets a literal AST value as the arguments value + * + * @param value can't be null as a `null` is represented a @{@link graphql.language.NullValue} Literal + * + * @return this builder + */ + public Builder valueLiteral(@NonNull Value value) { + this.value = InputValueWithState.newLiteralValue(value); + return this; + } + + /** + * @param value values can be null to represent null value + * + * @return this builder + */ + public Builder valueProgrammatic(@Nullable Object value) { + this.value = InputValueWithState.newExternalValue(value); + return this; + } + + public Builder inputValueWithState(@NonNull InputValueWithState value) { + this.value = Assert.assertNotNull(value); + return this; + } + + /** + * Removes the value to represent a missing value (which is different from null) + * + * @return this builder + */ + public Builder clearValue() { + this.value = InputValueWithState.NOT_SET; + return this; + } + + + public QueryAppliedDirectiveArgument build() { + return new QueryAppliedDirectiveArgument( + name, + value, + type, + definition + ); + } + } +} diff --git a/src/main/java/graphql/execution/directives/QueryDirectives.java b/src/main/java/graphql/execution/directives/QueryDirectives.java new file mode 100644 index 0000000000..6eee9f9323 --- /dev/null +++ b/src/main/java/graphql/execution/directives/QueryDirectives.java @@ -0,0 +1,132 @@ +package graphql.execution.directives; + +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.execution.CoercedVariables; +import graphql.execution.MergedField; +import graphql.execution.NormalizedVariables; +import graphql.language.Field; +import graphql.normalized.NormalizedInputValue; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLSchema; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.Supplier; + +/** + * This gives you access to the immediate directives on a {@link graphql.execution.MergedField}. This does not include directives on parent + * fields or fragment containers. + *

+ * Because a {@link graphql.execution.MergedField} can actually have multiple fields and hence + * directives on each field instance its possible that there is more than one directive named "foo" + * on the merged field. How you decide which one to use is up to your code. + *

+ * NOTE: A future version of the interface will try to add access to the inherited directives from + * parent fields and fragments. This proved to be a non-trivial problem and hence we decide + * to give access to immediate field directives and provide this holder interface, so we can + * add the other directives in the future + * + * @see graphql.execution.MergedField + */ +@PublicApi +public interface QueryDirectives { + + /** + * This will return a map of the applied directives that are immediately on a merged field + * + * @return a map of all the applied directives immediately on this merged field + */ + Map> getImmediateAppliedDirectivesByName(); + + /** + * This will return a list of the named applied directives that are immediately on this merged field. + * + * Read above for why this is a list of applied directives and not just one + * + * @param directiveName the named directive + * + * @return a list of the named applied directives that are immediately on this merged field + */ + List getImmediateAppliedDirective(String directiveName); + + /** + * This will return a map of the directives that are immediately on a merged field + * + * @return a map of all the directives immediately on this merged field + * + * @deprecated - use the {@link QueryAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + Map> getImmediateDirectivesByName(); + + /** + * This will return a map of the {@link graphql.language.Field}s inside a {@link graphql.execution.MergedField} + * and the immediate applied directives that are on each specific field + * + * @return a map of all directives on each field inside this + */ + Map> getImmediateAppliedDirectivesByField(); + + /** + * This will return a map of {@link QueryAppliedDirective} to a map of their argument values in {@link NormalizedInputValue} form + *

+ * NOTE : This will only be available when {@link graphql.normalized.ExecutableNormalizedOperationFactory} is used + * to create the {@link QueryAppliedDirective} information + * + * @return a map of applied directive to named argument values + */ + Map> getNormalizedInputValueByImmediateAppliedDirectives(); + + /** + * This will return a list of the named directives that are immediately on this merged field. + * + * Read above for why this is a list of directives and not just one + * + * @param directiveName the named directive + * + * @return a list of the named directives that are immediately on this merged field + * + * @deprecated - use the {@link QueryAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + List getImmediateDirective(String directiveName); + + /** + * This will return a map of the {@link graphql.language.Field}s inside a {@link graphql.execution.MergedField} + * and the immediate directives that are on each specific field + * + * @return a map of all directives on each field inside this + * + * @deprecated - use the {@link QueryAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + Map> getImmediateDirectivesByField(); + + /** + * @return a builder of {@link QueryDirectives} + */ + static Builder newQueryDirectives() { + return new QueryDirectivesBuilder(); + } + + interface Builder { + + Builder schema(GraphQLSchema schema); + + Builder mergedField(MergedField mergedField); + + Builder field(Field field); + + Builder coercedVariables(CoercedVariables coercedVariables); + + Builder normalizedVariables(Supplier normalizedVariables); + + Builder graphQLContext(GraphQLContext graphQLContext); + + Builder locale(Locale locale); + + QueryDirectives build(); + } +} diff --git a/src/main/java/graphql/execution/directives/QueryDirectivesBuilder.java b/src/main/java/graphql/execution/directives/QueryDirectivesBuilder.java new file mode 100644 index 0000000000..78b6998588 --- /dev/null +++ b/src/main/java/graphql/execution/directives/QueryDirectivesBuilder.java @@ -0,0 +1,71 @@ +package graphql.execution.directives; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.execution.MergedField; +import graphql.execution.NormalizedVariables; +import graphql.language.Field; +import graphql.schema.GraphQLSchema; + +import java.util.Locale; +import java.util.function.Supplier; + +@Internal +public class QueryDirectivesBuilder implements QueryDirectives.Builder { + + private MergedField mergedField; + private GraphQLSchema schema; + private CoercedVariables coercedVariables = CoercedVariables.emptyVariables(); + private Supplier normalizedVariables = NormalizedVariables::emptyVariables; + private GraphQLContext graphQLContext = GraphQLContext.getDefault(); + private Locale locale = Locale.getDefault(); + + @Override + public QueryDirectives.Builder schema(GraphQLSchema schema) { + this.schema = schema; + return this; + } + + @Override + public QueryDirectives.Builder mergedField(MergedField mergedField) { + this.mergedField = mergedField; + return this; + } + + @Override + public QueryDirectives.Builder field(Field field) { + this.mergedField = MergedField.newMergedField(field).build(); + return this; + } + + @Override + public QueryDirectives.Builder coercedVariables(CoercedVariables coercedVariables) { + this.coercedVariables = coercedVariables; + return this; + } + + @Override + public QueryDirectives.Builder normalizedVariables(Supplier normalizedVariables) { + this.normalizedVariables = normalizedVariables; + return this; + } + + @Override + public QueryDirectives.Builder graphQLContext(GraphQLContext graphQLContext) { + this.graphQLContext = graphQLContext; + return this; + } + + @Override + public QueryDirectives.Builder locale(Locale locale) { + this.locale = locale; + return this; + } + + + @Override + public QueryDirectives build() { + return new QueryDirectivesImpl(mergedField, schema, coercedVariables, normalizedVariables, graphQLContext, locale); + } +} diff --git a/src/main/java/graphql/execution/directives/QueryDirectivesImpl.java b/src/main/java/graphql/execution/directives/QueryDirectivesImpl.java new file mode 100644 index 0000000000..87f00d6f97 --- /dev/null +++ b/src/main/java/graphql/execution/directives/QueryDirectivesImpl.java @@ -0,0 +1,187 @@ +package graphql.execution.directives; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.execution.MergedField; +import graphql.execution.NormalizedVariables; +import graphql.execution.ValuesResolver; +import graphql.language.Directive; +import graphql.language.Field; +import graphql.normalized.NormalizedInputValue; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLSchema; +import graphql.util.LockKit; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.Supplier; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + +/** + * These objects are ALWAYS in the context of a single MergedField + *

+ * Also note we compute these values lazily + */ +@Internal +public class QueryDirectivesImpl implements QueryDirectives { + + private final DirectivesResolver directivesResolver = new DirectivesResolver(); + private final MergedField mergedField; + private final GraphQLSchema schema; + private final CoercedVariables coercedVariables; + private final Supplier normalizedVariableValues; + private final GraphQLContext graphQLContext; + private final Locale locale; + + private final LockKit.ComputedOnce computedOnce = new LockKit.ComputedOnce(); + private volatile ImmutableMap> fieldDirectivesByField; + private volatile ImmutableMap> fieldDirectivesByName; + private volatile ImmutableMap> fieldAppliedDirectivesByField; + private volatile ImmutableMap> fieldAppliedDirectivesByName; + private volatile ImmutableMap> normalizedValuesByAppliedDirective; + + public QueryDirectivesImpl(MergedField mergedField, GraphQLSchema schema, CoercedVariables coercedVariables, Supplier normalizedVariableValues, GraphQLContext graphQLContext, Locale locale) { + this.mergedField = assertNotNull(mergedField); + this.schema = assertNotNull(schema); + this.coercedVariables = assertNotNull(coercedVariables); + this.normalizedVariableValues = assertNotNull(normalizedVariableValues); + this.graphQLContext = assertNotNull(graphQLContext); + this.locale = assertNotNull(locale); + } + + private void computeValuesLazily() { + computedOnce.runOnce(() -> { + + final Map> byField = new LinkedHashMap<>(); + final Map> byFieldApplied = new LinkedHashMap<>(); + + BiMap directiveCounterParts = HashBiMap.create(); + BiMap gqlDirectiveCounterParts = HashBiMap.create(); + BiMap gqlDirectiveCounterPartsInverse = gqlDirectiveCounterParts.inverse(); + mergedField.forEach(field -> { + List directives = field.getDirectives(); + BiMap directivesMap = directivesResolver + .resolveDirectives(directives, schema, coercedVariables, graphQLContext, locale); + + directiveCounterParts.putAll(directivesMap); + + ImmutableList resolvedDirectives = ImmutableList.copyOf(directivesMap.keySet()); + + ImmutableList.Builder appliedDirectiveBuilder = ImmutableList.builder(); + for (GraphQLDirective resolvedDirective : resolvedDirectives) { + QueryAppliedDirective appliedDirective = toAppliedDirective(resolvedDirective); + appliedDirectiveBuilder.add(appliedDirective); + gqlDirectiveCounterParts.put(resolvedDirective, appliedDirective); + } + byField.put(field, resolvedDirectives); + // at some point we will only use applied + byFieldApplied.put(field, appliedDirectiveBuilder.build()); + }); + + Map> byName = new LinkedHashMap<>(); + Map> byNameApplied = new LinkedHashMap<>(); + byField.forEach((field, directiveList) -> directiveList.forEach(directive -> { + String name = directive.getName(); + byName.computeIfAbsent(name, k -> new ArrayList<>()).add(directive); + // at some point we will only use applied + QueryAppliedDirective appliedDirective = gqlDirectiveCounterParts.get(directive); + byNameApplied.computeIfAbsent(name, k -> new ArrayList<>()).add(appliedDirective); + })); + + // create NormalizedInputValue values for directive arguments + Map> normalizedValuesByAppliedDirective = new LinkedHashMap<>(); + NormalizedVariables normalizedVariableValues = this.normalizedVariableValues.get(); + if (normalizedVariableValues != null) { + byNameApplied.values().forEach(directiveList -> { + for (QueryAppliedDirective queryAppliedDirective : directiveList) { + GraphQLDirective graphQLDirective = gqlDirectiveCounterPartsInverse.get(queryAppliedDirective); + // we need this counterpart because the ValuesResolver needs the runtime and AST element + Directive directive = directiveCounterParts.get(graphQLDirective); + if (directive != null) { + Map normalizedVariables = normalizedVariableValues.toMap(); + Map normalizedArgumentValues = ValuesResolver.getNormalizedArgumentValues(graphQLDirective.getArguments(), directive.getArguments(), normalizedVariables); + normalizedValuesByAppliedDirective.put(queryAppliedDirective, normalizedArgumentValues); + } + } + }); + } + + this.fieldDirectivesByName = ImmutableMap.copyOf(byName); + this.fieldDirectivesByField = ImmutableMap.copyOf(byField); + this.fieldAppliedDirectivesByName = ImmutableMap.copyOf(byNameApplied); + this.fieldAppliedDirectivesByField = ImmutableMap.copyOf(byFieldApplied); + this.normalizedValuesByAppliedDirective = ImmutableMap.copyOf(normalizedValuesByAppliedDirective); + }); + } + + private QueryAppliedDirective toAppliedDirective(GraphQLDirective directive) { + QueryAppliedDirective.Builder builder = QueryAppliedDirective.newDirective(); + builder.name(directive.getName()); + for (GraphQLArgument argument : directive.getArguments()) { + builder.argument(toAppliedArgument(argument)); + } + return builder.build(); + } + + private QueryAppliedDirectiveArgument toAppliedArgument(GraphQLArgument argument) { + return QueryAppliedDirectiveArgument.newArgument() + .name(argument.getName()) + .type(argument.getType()) + .inputValueWithState(argument.getArgumentValue()) + .build(); + } + + + @Override + public Map> getImmediateDirectivesByField() { + computeValuesLazily(); + return fieldDirectivesByField; + } + + @Override + public Map> getImmediateAppliedDirectivesByField() { + computeValuesLazily(); + return fieldAppliedDirectivesByField; + } + + @Override + public Map> getNormalizedInputValueByImmediateAppliedDirectives() { + computeValuesLazily(); + return normalizedValuesByAppliedDirective; + } + + @Override + public Map> getImmediateDirectivesByName() { + computeValuesLazily(); + return fieldDirectivesByName; + } + + @Override + public Map> getImmediateAppliedDirectivesByName() { + computeValuesLazily(); + return fieldAppliedDirectivesByName; + } + + @Override + public List getImmediateDirective(String directiveName) { + computeValuesLazily(); + return getImmediateDirectivesByName().getOrDefault(directiveName, emptyList()); + } + + @Override + public List getImmediateAppliedDirective(String directiveName) { + computeValuesLazily(); + return getImmediateAppliedDirectivesByName().getOrDefault(directiveName, emptyList()); + } +} diff --git a/src/main/java/graphql/execution/incremental/AlternativeCallContext.java b/src/main/java/graphql/execution/incremental/AlternativeCallContext.java new file mode 100644 index 0000000000..47e956798e --- /dev/null +++ b/src/main/java/graphql/execution/incremental/AlternativeCallContext.java @@ -0,0 +1,64 @@ +package graphql.execution.incremental; + +import graphql.GraphQLError; +import graphql.Internal; +import graphql.VisibleForTesting; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Contains data relevant to the execution of a {@link DeferredFragmentCall} and Subscription events. + *

+ * The responsibilities of this class are similar to {@link graphql.execution.ExecutionContext}, but restricted to the + * execution of a deferred call (instead of the whole GraphQL execution like {@link graphql.execution.ExecutionContext}). + *

+ * Some behaviours, like error capturing, need to be scoped to a single {@link DeferredFragmentCall} for deferred, because each defer payload + * contains its own distinct list of errors. + */ +@Internal +public class AlternativeCallContext { + + private final int startLevel; + private final int fields; + + private final List errors = Collections.synchronizedList(new ArrayList<>()); + + public AlternativeCallContext(int startLevel, int fields) { + this.startLevel = startLevel; + this.fields = fields; + } + + @VisibleForTesting + public AlternativeCallContext() { + this.startLevel = 0; + this.fields = 0; + } + + public int getStartLevel() { + return startLevel; + } + + public int getFields() { + return fields; + } + + + public void addErrors(List errors) { + this.errors.addAll(errors); + } + + public void addError(GraphQLError graphqlError) { + errors.add(graphqlError); + } + + /** + * @return a list of errors that were encountered while executing this deferred call + */ + public List getErrors() { + return errors; + } + + +} diff --git a/src/main/java/graphql/execution/incremental/DeferredExecution.java b/src/main/java/graphql/execution/incremental/DeferredExecution.java new file mode 100644 index 0000000000..ae63808989 --- /dev/null +++ b/src/main/java/graphql/execution/incremental/DeferredExecution.java @@ -0,0 +1,39 @@ +package graphql.execution.incremental; + +import graphql.ExperimentalApi; +import graphql.normalized.incremental.NormalizedDeferredExecution; +import org.jspecify.annotations.Nullable; + +/** + * Represents details about the defer execution that can be associated with a {@link graphql.execution.MergedField}. + *

+ * This representation is used during graphql execution. Check {@link NormalizedDeferredExecution} + * for the normalized representation of @defer. + */ +@ExperimentalApi +public class DeferredExecution { + private final String label; + + public DeferredExecution(String label) { + this.label = label; + } + + @Nullable + public String getLabel() { + return label; + } + + // this class uses object identity - do not put .equals() / .hashCode() implementations on it + // otherwise it will break defer handling. I have put the code just to be explicit that object identity + // is needed + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } +} diff --git a/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java b/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java new file mode 100644 index 0000000000..86965d701e --- /dev/null +++ b/src/main/java/graphql/execution/incremental/DeferredExecutionSupport.java @@ -0,0 +1,237 @@ +package graphql.execution.incremental; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import graphql.ExecutionResult; +import graphql.ExecutionResultImpl; +import graphql.Internal; +import graphql.execution.ExecutionContext; +import graphql.execution.ExecutionStepInfo; +import graphql.execution.ExecutionStrategyParameters; +import graphql.execution.FieldValueInfo; +import graphql.execution.MergedField; +import graphql.execution.MergedSelectionSet; +import graphql.execution.ResultPath; +import graphql.execution.instrumentation.Instrumentation; +import graphql.execution.instrumentation.InstrumentationContext; +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.incremental.IncrementalPayload; +import graphql.util.FpKit; +import org.jspecify.annotations.NonNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +import static graphql.execution.instrumentation.SimpleInstrumentationContext.nonNullCtx; + +/** + * The purpose of this class hierarchy is to encapsulate most of the logic for deferring field execution, thus + * keeping the main execution strategy code clean and focused on the main execution logic. + *

+ * The {@link NoOp} instance should be used when incremental support is not enabled for the current execution. The + * methods in this class will return empty or no-op results, that should not impact the main execution. + *

+ * {@link DeferredExecutionSupportImpl} is the actual implementation that will be used when incremental support is enabled. + */ +@Internal +public interface DeferredExecutionSupport { + + boolean isDeferredField(MergedField mergedField); + + int deferredFieldsCount(); + + List getNonDeferredFieldNames(List allFieldNames); + + Set> createCalls(); + + DeferredExecutionSupport NOOP = new DeferredExecutionSupport.NoOp(); + + /** + * An implementation that actually executes the deferred fields. + */ + class DeferredExecutionSupportImpl implements DeferredExecutionSupport { + private final ImmutableListMultimap deferredExecutionToFields; + private final ImmutableSet deferredFields; + private final ImmutableList nonDeferredFieldNames; + private final ExecutionStrategyParameters parameters; + private final ExecutionContext executionContext; + private final BiFunction> resolveFieldWithInfoFn; + private final BiFunction> executionStepInfoFn; + private final Map>> dfCache = new HashMap<>(); + + public DeferredExecutionSupportImpl( + MergedSelectionSet mergedSelectionSet, + ExecutionStrategyParameters parameters, + ExecutionContext executionContext, + BiFunction> resolveFieldWithInfoFn, + BiFunction> executionStepInfoFn + ) { + this.executionContext = executionContext; + this.resolveFieldWithInfoFn = resolveFieldWithInfoFn; + this.executionStepInfoFn = executionStepInfoFn; + ImmutableListMultimap.Builder deferredExecutionToFieldsBuilder = ImmutableListMultimap.builder(); + ImmutableSet.Builder deferredFieldsBuilder = ImmutableSet.builder(); + ImmutableList.Builder nonDeferredFieldNamesBuilder = ImmutableList.builder(); + + mergedSelectionSet.getSubFields().values().forEach(mergedField -> { + if (mergedField.getFieldsCount() > mergedField.getDeferredExecutions().size()) { + nonDeferredFieldNamesBuilder.add(mergedField.getSingleField().getResultKey()); + return; + } + mergedField.getDeferredExecutions().forEach(de -> { + deferredExecutionToFieldsBuilder.put(de, mergedField); + deferredFieldsBuilder.add(mergedField); + }); + }); + + this.deferredExecutionToFields = deferredExecutionToFieldsBuilder.build(); + this.deferredFields = deferredFieldsBuilder.build(); + this.parameters = parameters; + this.nonDeferredFieldNames = nonDeferredFieldNamesBuilder.build(); + } + + @Override + public boolean isDeferredField(MergedField mergedField) { + return deferredFields.contains(mergedField); + } + + @Override + public int deferredFieldsCount() { + return deferredFields.size(); + } + + @Override + public List getNonDeferredFieldNames(List allFieldNames) { + return this.nonDeferredFieldNames; + } + + @Override + public Set> createCalls() { + ImmutableSet deferredExecutions = deferredExecutionToFields.keySet(); + Set> set = Sets.newHashSetWithExpectedSize(deferredExecutions.size()); + + for (DeferredExecution deferredExecution : deferredExecutions) { + set.add(this.createDeferredFragmentCall(deferredExecution)); + } + return set; + } + + private DeferredFragmentCall createDeferredFragmentCall(DeferredExecution deferredExecution) { + int level = parameters.getPath().getLevel() + 1; + AlternativeCallContext alternativeCallContext = new AlternativeCallContext(level, deferredFields.size()); + + List mergedFields = deferredExecutionToFields.get(deferredExecution); + + List>> calls = FpKit.arrayListSizedTo(mergedFields); + for (MergedField currentField : mergedFields) { + calls.add(this.createResultSupplier(currentField, alternativeCallContext)); + } + + return new DeferredFragmentCall( + deferredExecution.getLabel(), + this.parameters.getPath(), + calls, + alternativeCallContext + ); + } + + private Supplier> createResultSupplier( + MergedField currentField, + AlternativeCallContext alternativeCallContext + ) { + Map fields = new LinkedHashMap<>(); + fields.put(currentField.getResultKey(), currentField); + + ExecutionStrategyParameters executionStrategyParameters = parameters.transform(builder -> + { + MergedSelectionSet mergedSelectionSet = MergedSelectionSet.newMergedSelectionSet().subFields(fields).build(); + ResultPath path = parameters.getPath().segment(currentField.getResultKey()); + builder.deferredCallContext(alternativeCallContext) + .field(currentField) + .fields(mergedSelectionSet) + .path(path) + .parent(null); // this is a break in the parent -> child chain - it's a new start effectively + } + ); + + // todo: handle cached computations + return dfCache.computeIfAbsent( + currentField.getResultKey(), + // The same field can be associated with multiple defer executions, so + // we memoize the field resolution to avoid multiple calls to the same data fetcher + key -> FpKit.interThreadMemoize(resolveDeferredFieldValue(currentField, executionContext, executionStrategyParameters) + ) + ); + } + + @NonNull + private Supplier> resolveDeferredFieldValue(MergedField currentField, ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters) { + return () -> { + + Instrumentation instrumentation = executionContext.getInstrumentation(); + Supplier executionStepInfo = executionStepInfoFn.apply(executionContext, executionStrategyParameters); + InstrumentationFieldParameters fieldParameters = new InstrumentationFieldParameters(executionContext, executionStepInfo); + InstrumentationContext deferredFieldCtx = nonNullCtx(instrumentation.beginDeferredField(fieldParameters, executionContext.getInstrumentationState())); + + CompletableFuture fieldValueResult = resolveFieldWithInfoFn.apply(this.executionContext, executionStrategyParameters); + executionContext.getDataLoaderDispatcherStrategy().deferFieldFetched(executionStrategyParameters); + + + deferredFieldCtx.onDispatched(); + + fieldValueResult.whenComplete((fieldValueInfo, throwable) -> { + this.executionContext.getDataLoaderDispatcherStrategy().deferredOnFieldValue(currentField.getResultKey(), fieldValueInfo, throwable, executionStrategyParameters); + deferredFieldCtx.onCompleted(fieldValueInfo, throwable); + }); + + + CompletableFuture executionResultCF = fieldValueResult + .thenCompose(fvi -> fvi + .getFieldValueFuture() + .thenApply(fv -> ExecutionResultImpl.newExecutionResult().data(fv).build()) + ); + + return executionResultCF + .thenApply(executionResult -> + new DeferredFragmentCall.FieldWithExecutionResult(currentField.getResultKey(), executionResult) + ); + }; + } + } + + /** + * A no-op implementation that should be used when incremental support is not enabled for the current execution. + */ + class NoOp implements DeferredExecutionSupport { + + @Override + public boolean isDeferredField(MergedField mergedField) { + return false; + } + + @Override + public int deferredFieldsCount() { + return 0; + } + + @Override + public List getNonDeferredFieldNames(List allFieldNames) { + return allFieldNames; + } + + @Override + public Set> createCalls() { + return Collections.emptySet(); + } + } +} diff --git a/src/main/java/graphql/execution/incremental/DeferredFragmentCall.java b/src/main/java/graphql/execution/incremental/DeferredFragmentCall.java new file mode 100644 index 0000000000..79f4c9b78d --- /dev/null +++ b/src/main/java/graphql/execution/incremental/DeferredFragmentCall.java @@ -0,0 +1,135 @@ +package graphql.execution.incremental; + +import com.google.common.collect.ImmutableList; +import graphql.ExecutionResult; +import graphql.GraphQLError; +import graphql.Internal; +import graphql.execution.Async; +import graphql.execution.NonNullableFieldWasNullError; +import graphql.execution.NonNullableFieldWasNullException; +import graphql.execution.ResultPath; +import graphql.incremental.DeferPayload; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.function.Supplier; + +/** + * Represents a deferred call (aka @defer) to get an execution result sometime after the initial query has returned. + *

+ * A deferred call can encompass multiple fields. The deferred call will resolve once all sub-fields resolve. + *

+ * For example, this query: + *

+ * {
+ *     post {
+ *         ... @defer(label: "defer-post") {
+ *             text
+ *             summary
+ *         }
+ *     }
+ * }
+ * 
+ * Will result on 1 instance of `DeferredCall`, containing calls for the 2 fields: "text" and "summary". + */ +@Internal +public class DeferredFragmentCall implements IncrementalCall { + private final String label; + + public ResultPath getPath() { + return path; + } + + private final ResultPath path; + private final List>> calls; + private final AlternativeCallContext alternativeCallContext; + + public DeferredFragmentCall( + String label, + ResultPath path, + List>> calls, + AlternativeCallContext alternativeCallContext + ) { + this.label = label; + this.path = path; + this.calls = calls; + this.alternativeCallContext = alternativeCallContext; + } + + @Override + public CompletableFuture invoke() { + Async.CombinedBuilder futures = Async.ofExpectedSize(calls.size()); + + calls.forEach(call -> { + CompletableFuture cf = call.get(); + futures.add(cf); + }); + + return futures.await() + .thenApply(this::transformToDeferredPayload) + .handle(this::handleNonNullableFieldError); + } + + /** + * Non-nullable errors need special treatment. + * When they happen, all the sibling fields will be ignored in the result. So as soon as one of the field calls + * throw this error, we can ignore the {@link ExecutionResult} from all the fields associated with this {@link DeferredFragmentCall} + * and build a special {@link DeferPayload} that captures the details of the error. + */ + private DeferPayload handleNonNullableFieldError(DeferPayload result, Throwable throwable) { + if (throwable != null) { + Throwable cause = throwable.getCause(); + if (cause instanceof NonNullableFieldWasNullException) { + GraphQLError error = new NonNullableFieldWasNullError((NonNullableFieldWasNullException) cause); + return DeferPayload.newDeferredItem() + .errors(Collections.singletonList(error)) + .label(label) + .path(path) + .build(); + } + if (cause instanceof CompletionException) { + throw (CompletionException) cause; + } + throw new CompletionException(cause); + } + return result; + } + + private DeferPayload transformToDeferredPayload(List fieldWithExecutionResults) { + List errorsEncountered = alternativeCallContext.getErrors(); + + Map dataMap = new HashMap<>(); + + ImmutableList.Builder errorsBuilder = ImmutableList.builder(); + + fieldWithExecutionResults.forEach(entry -> { + dataMap.put(entry.resultKey, entry.executionResult.getData()); + errorsBuilder.addAll(entry.executionResult.getErrors()); + }); + + return DeferPayload.newDeferredItem() + .errors(errorsEncountered) + .path(path) + .label(label) + .data(dataMap) + .build(); + } + + public static class FieldWithExecutionResult { + private final String resultKey; + private final ExecutionResult executionResult; + + public FieldWithExecutionResult(String resultKey, ExecutionResult executionResult) { + this.resultKey = resultKey; + this.executionResult = executionResult; + } + + public ExecutionResult getExecutionResult() { + return executionResult; + } + } +} diff --git a/src/main/java/graphql/execution/incremental/IncrementalCall.java b/src/main/java/graphql/execution/incremental/IncrementalCall.java new file mode 100644 index 0000000000..7d36d48f69 --- /dev/null +++ b/src/main/java/graphql/execution/incremental/IncrementalCall.java @@ -0,0 +1,14 @@ +package graphql.execution.incremental; + +import graphql.incremental.IncrementalPayload; + +import java.util.concurrent.CompletableFuture; + +/** + * Represents an incremental call (resulted from the usage of @defer or @stream). + * + * @param the type of the payload that this call resolves. + */ +public interface IncrementalCall { + CompletableFuture invoke(); +} diff --git a/src/main/java/graphql/execution/incremental/IncrementalCallState.java b/src/main/java/graphql/execution/incremental/IncrementalCallState.java new file mode 100644 index 0000000000..fc1f352ca3 --- /dev/null +++ b/src/main/java/graphql/execution/incremental/IncrementalCallState.java @@ -0,0 +1,111 @@ +package graphql.execution.incremental; + +import graphql.Internal; +import graphql.execution.reactive.SingleSubscriberPublisher; +import graphql.incremental.DelayedIncrementalPartialResult; +import graphql.incremental.IncrementalPayload; +import graphql.util.InterThreadMemoizedSupplier; +import graphql.util.LockKit; +import org.reactivestreams.Publisher; + +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +import static graphql.incremental.DelayedIncrementalPartialResultImpl.newIncrementalExecutionResult; + +/** + * This provides support for @defer directives on fields that mean that results will be sent AFTER + * the main result is sent via a Publisher stream. + */ +@Internal +public class IncrementalCallState { + private final AtomicBoolean incrementalCallsDetected = new AtomicBoolean(false); + private final Deque> incrementalCalls = new ConcurrentLinkedDeque<>(); + private final Supplier> publisher = createPublisher(); + private final AtomicInteger pendingCalls = new AtomicInteger(); + private final LockKit.ReentrantLock publisherLock = new LockKit.ReentrantLock(); + + @SuppressWarnings("FutureReturnValueIgnored") + private void drainIncrementalCalls() { + IncrementalCall incrementalCall = incrementalCalls.poll(); + + while (incrementalCall != null) { + incrementalCall.invoke() + .whenComplete((payload, exception) -> { + if (exception != null) { + publisher.get().offerError(exception); + return; + } + + // The assigment of `remainingCalls` and `publisher.offer` need to be synchronized to ensure + // `hasNext` is `false` precisely on the last event offered to the publisher. + publisherLock.lock(); + final int remainingCalls; + + try { + remainingCalls = pendingCalls.decrementAndGet(); + + DelayedIncrementalPartialResult executionResult = newIncrementalExecutionResult() + .incrementalItems(Collections.singletonList(payload)) + .hasNext(remainingCalls != 0) + .build(); + + publisher.get().offer(executionResult); + } finally { + publisherLock.unlock(); + } + + if (remainingCalls == 0) { + publisher.get().noMoreData(); + } else { + // Nested calls were added, let's try to drain the queue again. + drainIncrementalCalls(); + } + }); + incrementalCall = incrementalCalls.poll(); + } + } + + public void enqueue(IncrementalCall incrementalCall) { + publisherLock.runLocked(() -> { + incrementalCallsDetected.set(true); + incrementalCalls.offer(incrementalCall); + pendingCalls.incrementAndGet(); + }); + } + + public void enqueue(Collection> calls) { + calls.forEach(this::enqueue); + } + + public boolean getIncrementalCallsDetected() { + return incrementalCallsDetected.get(); + } + + private Supplier> createPublisher() { + // this will be created once and once only - any extra calls to .get() will return the previously created + // singleton object + return new InterThreadMemoizedSupplier<>(() -> new SingleSubscriberPublisher<>(this::drainIncrementalCalls)); + } + + /** + * This method will return a {@link Publisher} of deferred results. No field processing will be done + * until a {@link org.reactivestreams.Subscriber} is attached to this publisher. Once a {@link org.reactivestreams.Subscriber} + * is attached the deferred field result processing will be started and published as a series of events. + * + * @return the publisher of deferred results + */ + public Publisher startDeferredCalls() { + return publisher.get(); + } + + public void startDrainingNow() { + drainIncrementalCalls(); + } + +} diff --git a/src/main/java/graphql/execution/incremental/IncrementalExecutionContextKeys.java b/src/main/java/graphql/execution/incremental/IncrementalExecutionContextKeys.java new file mode 100644 index 0000000000..293a4ca4fb --- /dev/null +++ b/src/main/java/graphql/execution/incremental/IncrementalExecutionContextKeys.java @@ -0,0 +1,26 @@ +package graphql.execution.incremental; + + +import graphql.Internal; +import org.jspecify.annotations.NullMarked; + +/** + * GraphQLContext keys for controlling incremental execution behavior. + */ +@Internal +@NullMarked +public final class IncrementalExecutionContextKeys { + private IncrementalExecutionContextKeys() { + } + + /** + * Enables eager start of @defer processing so defered work runs before the initial result is computed. + * Defaults to false. + *

+ * Expects a boolean value. + */ + public static final String ENABLE_EAGER_DEFER_START = "__GJ_enable_eager_defer_start"; + +} + + diff --git a/src/main/java/graphql/execution/incremental/IncrementalUtils.java b/src/main/java/graphql/execution/incremental/IncrementalUtils.java new file mode 100644 index 0000000000..5dc1ac171c --- /dev/null +++ b/src/main/java/graphql/execution/incremental/IncrementalUtils.java @@ -0,0 +1,54 @@ +package graphql.execution.incremental; + +import graphql.Assert; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.execution.ValuesResolver; +import graphql.language.Directive; +import graphql.language.NodeUtil; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.Function; + +import static graphql.Directives.DeferDirective; + +@Internal +public class IncrementalUtils { + private IncrementalUtils() { + } + + public static @Nullable T createDeferredExecution( + Map variables, + List directives, + Function builderFunction + ) { + Directive deferDirective = NodeUtil.findNodeByName(directives, DeferDirective.getName()); + + if (deferDirective != null) { + Map argumentValues = ValuesResolver.getArgumentValues(DeferDirective.getArguments(), deferDirective.getArguments(), CoercedVariables.of(variables), GraphQLContext.getDefault(), Locale.getDefault()); + + Object flag = argumentValues.get("if"); + Assert.assertTrue(flag instanceof Boolean, "The '%s' directive MUST have a value for the 'if' argument", DeferDirective.getName()); + + if (!((Boolean) flag)) { + return null; + } + + Object label = argumentValues.get("label"); + + if (label == null) { + return builderFunction.apply(null); + } + + Assert.assertTrue(label instanceof String, "The 'label' argument from the '%s' directive MUST contain a String value", DeferDirective.getName()); + + return builderFunction.apply((String) label); + } + + return null; + } +} diff --git a/src/main/java/graphql/execution/incremental/StreamedCall.java b/src/main/java/graphql/execution/incremental/StreamedCall.java new file mode 100644 index 0000000000..beae535b3e --- /dev/null +++ b/src/main/java/graphql/execution/incremental/StreamedCall.java @@ -0,0 +1,19 @@ +package graphql.execution.incremental; + +import graphql.Internal; +import graphql.incremental.StreamPayload; + +import java.util.concurrent.CompletableFuture; + +/** + * Represents a call that fetches data that was streamed, via the @stream directive. + *

+ * This is a placeholder class, created to showcase the proposed structure that accommodates both @defer and @stream execution. + */ +@Internal +public class StreamedCall implements IncrementalCall { + @Override + public CompletableFuture invoke() { + throw new UnsupportedOperationException("Not implemented yet."); + } +} diff --git a/src/main/java/graphql/execution/instrumentation/ChainedInstrumentation.java b/src/main/java/graphql/execution/instrumentation/ChainedInstrumentation.java index ff98cf0b7e..2779a10a01 100644 --- a/src/main/java/graphql/execution/instrumentation/ChainedInstrumentation.java +++ b/src/main/java/graphql/execution/instrumentation/ChainedInstrumentation.java @@ -1,33 +1,39 @@ package graphql.execution.instrumentation; +import com.google.common.collect.ImmutableList; import graphql.ExecutionInput; import graphql.ExecutionResult; +import graphql.ExperimentalApi; import graphql.PublicApi; import graphql.execution.Async; import graphql.execution.ExecutionContext; import graphql.execution.FieldValueInfo; -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationReactiveResultsParameters; import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; import graphql.language.Document; -import graphql.language.Field; import graphql.schema.DataFetcher; import graphql.schema.GraphQLSchema; import graphql.validation.ValidationError; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; +import java.util.AbstractMap; +import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; import static graphql.Assert.assertNotNull; -import static java.util.stream.Collectors.toList; /** * This allows you to chain together a number of {@link graphql.execution.instrumentation.Instrumentation} implementations @@ -42,194 +48,254 @@ public class ChainedInstrumentation implements Instrumentation { // This class is inspired from https://github.com/leangen/graphql-spqr/blob/master/src/main/java/io/leangen/graphql/GraphQLRuntime.java#L80 - private final List instrumentations; + protected final ImmutableList instrumentations; public ChainedInstrumentation(List instrumentations) { - this.instrumentations = Collections.unmodifiableList(assertNotNull(instrumentations)); + this.instrumentations = ImmutableList.copyOf(assertNotNull(instrumentations)); } - private InstrumentationState getState(Instrumentation instrumentation, InstrumentationState parametersInstrumentationState) { - ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) parametersInstrumentationState; - return chainedInstrumentationState.getState(instrumentation); + public ChainedInstrumentation(Instrumentation... instrumentations) { + this(Arrays.asList(instrumentations)); + } + + /** + * @return the list of instrumentations in play + */ + public List getInstrumentations() { + return instrumentations; + } + + private InstrumentationContext chainedCtx(InstrumentationState state, BiFunction> mapper) { + // if we have zero or 1 instrumentations (and 1 is the most common), then we can avoid an object allocation + // of the ChainedInstrumentationContext since it won't be needed + if (instrumentations.isEmpty()) { + return SimpleInstrumentationContext.noOp(); + } + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + if (instrumentations.size() == 1) { + return mapper.apply(instrumentations.get(0), chainedInstrumentationState.getState(0)); + } + return new ChainedInstrumentationContext<>(chainedMapAndDropNulls(chainedInstrumentationState, mapper)); + } + + private T chainedInstrument(InstrumentationState state, T input, ChainedInstrumentationFunction mapper) { + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + for (int i = 0; i < instrumentations.size(); i++) { + Instrumentation instrumentation = instrumentations.get(i); + InstrumentationState specificState = chainedInstrumentationState.getState(i); + input = mapper.apply(instrumentation, specificState, input); + } + return input; + } + + protected ImmutableList chainedMapAndDropNulls(InstrumentationState state, BiFunction mapper) { + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + ImmutableList.Builder result = ImmutableList.builderWithExpectedSize(instrumentations.size()); + for (int i = 0; i < instrumentations.size(); i++) { + Instrumentation instrumentation = instrumentations.get(i); + InstrumentationState specificState = chainedInstrumentationState.getState(i); + T value = mapper.apply(instrumentation, specificState); + if (value != null) { + result.add(value); + } + } + return result.build(); + } + + protected void chainedConsume(InstrumentationState state, BiConsumer stateConsumer) { + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + for (int i = 0; i < instrumentations.size(); i++) { + Instrumentation instrumentation = instrumentations.get(i); + InstrumentationState specificState = chainedInstrumentationState.getState(i); + stateConsumer.accept(instrumentation, specificState); + } } @Override - public InstrumentationState createState() { - return new ChainedInstrumentationState(instrumentations); + public @NonNull CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return ChainedInstrumentationState.combineAll(instrumentations, parameters); } @Override - public InstrumentationContext beginExecution(final InstrumentationExecutionParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginExecution(parameters.withNewState(state)); - }) - .collect(toList())); + public InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginExecution(parameters, specificState)); } + @Override - public InstrumentationContext beginParse(InstrumentationExecutionParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginParse(parameters.withNewState(state)); - }) - .collect(toList())); + public InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginParse(parameters, specificState)); } + @Override - public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginValidation(parameters.withNewState(state)); - }) - .collect(toList())); + public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginValidation(parameters, specificState)); } @Override - public InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginExecuteOperation(parameters.withNewState(state)); - }) - .collect(toList())); + public InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginExecuteOperation(parameters, specificState)); } @Override - public ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { - return new ChainedExecutionStrategyInstrumentationContext(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginExecutionStrategy(parameters.withNewState(state)); - }) - .collect(toList())); + public @Nullable InstrumentationContext beginReactiveResults(InstrumentationReactiveResultsParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginReactiveResults(parameters, specificState)); } @Override - public DeferredFieldInstrumentationContext beginDeferredField(InstrumentationDeferredFieldParameters parameters) { - return new ChainedDeferredExecutionStrategyInstrumentationContext(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginDeferredField(parameters.withNewState(state)); - }) - .collect(toList())); + public ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + if (instrumentations.isEmpty()) { + return ExecutionStrategyInstrumentationContext.NOOP; + } + BiFunction mapper = (instrumentation, specificState) -> instrumentation.beginExecutionStrategy(parameters, specificState); + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + if (instrumentations.size() == 1) { + return mapper.apply(instrumentations.get(0), chainedInstrumentationState.getState(0)); + } + return new ChainedExecutionStrategyInstrumentationContext(chainedMapAndDropNulls(chainedInstrumentationState, mapper)); } @Override - public InstrumentationContext beginField(InstrumentationFieldParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginField(parameters.withNewState(state)); - }) - .collect(toList())); + public @Nullable ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + if (instrumentations.isEmpty()) { + return ExecuteObjectInstrumentationContext.NOOP; + } + BiFunction mapper = (instrumentation, specificState) -> instrumentation.beginExecuteObject(parameters, specificState); + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + if (instrumentations.size() == 1) { + return mapper.apply(instrumentations.get(0), chainedInstrumentationState.getState(0)); + } + return new ChainedExecuteObjectInstrumentationContext(chainedMapAndDropNulls(chainedInstrumentationState, mapper)); } + @ExperimentalApi @Override - public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginFieldFetch(parameters.withNewState(state)); - }) - .collect(toList())); + public InstrumentationContext beginDeferredField(InstrumentationFieldParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginDeferredField(parameters, specificState)); } @Override - public InstrumentationContext beginFieldComplete(InstrumentationFieldCompleteParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginFieldComplete(parameters.withNewState(state)); - }) - .collect(toList())); + public InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginSubscribedFieldEvent(parameters, specificState)); } @Override - public InstrumentationContext beginFieldListComplete(InstrumentationFieldCompleteParameters parameters) { - return new ChainedInstrumentationContext<>(instrumentations.stream() - .map(instrumentation -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - return instrumentation.beginFieldListComplete(parameters.withNewState(state)); - }) - .collect(toList())); + public @Nullable InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldExecution(parameters, specificState)); } + @SuppressWarnings("deprecation") @Override - public ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters) { - for (Instrumentation instrumentation : instrumentations) { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - executionInput = instrumentation.instrumentExecutionInput(executionInput, parameters.withNewState(state)); - } - return executionInput; + public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldFetch(parameters, specificState)); } @Override - public GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters) { - for (Instrumentation instrumentation : instrumentations) { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - schema = instrumentation.instrumentSchema(schema, parameters.withNewState(state)); + public FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + if (instrumentations.isEmpty()) { + return FieldFetchingInstrumentationContext.NOOP; } - return schema; + BiFunction mapper = (instrumentation, specificState) -> instrumentation.beginFieldFetching(parameters, specificState); + ChainedInstrumentationState chainedInstrumentationState = (ChainedInstrumentationState) state; + if (instrumentations.size() == 1) { + return mapper.apply(instrumentations.get(0), chainedInstrumentationState.getState(0)); + } + ImmutableList objects = chainedMapAndDropNulls(chainedInstrumentationState, mapper); + return new ChainedFieldFetchingInstrumentationContext(objects); } @Override - public ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters) { - for (Instrumentation instrumentation : instrumentations) { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - executionContext = instrumentation.instrumentExecutionContext(executionContext, parameters.withNewState(state)); - } - return executionContext; + public @Nullable InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldCompletion(parameters, specificState)); } + @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - for (Instrumentation instrumentation : instrumentations) { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - dataFetcher = instrumentation.instrumentDataFetcher(dataFetcher, parameters.withNewState(state)); - } - return dataFetcher; + public @Nullable InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return chainedCtx(state, (instrumentation, specificState) -> instrumentation.beginFieldListCompletion(parameters, specificState)); } + @NonNull @Override - public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { - CompletableFuture> resultsFuture = Async.eachSequentially(instrumentations, (instrumentation, index, prevResults) -> { - InstrumentationState state = getState(instrumentation, parameters.getInstrumentationState()); - ExecutionResult lastResult = prevResults.size() > 0 ? prevResults.get(prevResults.size() - 1) : executionResult; - return instrumentation.instrumentExecutionResult(lastResult, parameters.withNewState(state)); + public ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return chainedInstrument(state, executionInput, (instrumentation, specificState, accumulator) -> instrumentation.instrumentExecutionInput(accumulator, parameters, specificState)); + } + + @NonNull + @Override + public DocumentAndVariables instrumentDocumentAndVariables(DocumentAndVariables documentAndVariables, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return chainedInstrument(state, documentAndVariables, (instrumentation, specificState, accumulator) -> + instrumentation.instrumentDocumentAndVariables(accumulator, parameters, specificState)); + } + + @NonNull + @Override + public GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return chainedInstrument(state, schema, (instrumentation, specificState, accumulator) -> + instrumentation.instrumentSchema(accumulator, parameters, specificState)); + } + + @NonNull + @Override + public ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return chainedInstrument(state, executionContext, (instrumentation, specificState, accumulator) -> + instrumentation.instrumentExecutionContext(accumulator, parameters, specificState)); + } + + @NonNull + @Override + public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return chainedInstrument(state, dataFetcher, (Instrumentation instrumentation, InstrumentationState specificState, DataFetcher accumulator) -> + instrumentation.instrumentDataFetcher(accumulator, parameters, specificState)); + } + + @NonNull + @Override + public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + ImmutableList> entries = chainedMapAndDropNulls(state, AbstractMap.SimpleEntry::new); + CompletableFuture> resultsFuture = Async.eachSequentially(entries, (entry, prevResults) -> { + Instrumentation instrumentation = entry.getKey(); + InstrumentationState specificState = entry.getValue(); + ExecutionResult lastResult = !prevResults.isEmpty() ? prevResults.get(prevResults.size() - 1) : executionResult; + return instrumentation.instrumentExecutionResult(lastResult, parameters, specificState); }); return resultsFuture.thenApply((results) -> results.isEmpty() ? executionResult : results.get(results.size() - 1)); } - private static class ChainedInstrumentationState implements InstrumentationState { - private final Map instrumentationStates; + static class ChainedInstrumentationState implements InstrumentationState { + private final List instrumentationStates; - - private ChainedInstrumentationState(List instrumentations) { - instrumentationStates = new LinkedHashMap<>(instrumentations.size()); - instrumentations.forEach(i -> instrumentationStates.put(i, i.createState())); + private ChainedInstrumentationState(List instrumentationStates) { + this.instrumentationStates = instrumentationStates; } - private InstrumentationState getState(Instrumentation instrumentation) { - return instrumentationStates.get(instrumentation); + private InstrumentationState getState(int index) { + return instrumentationStates.get(index); } + private static CompletableFuture combineAll(List instrumentations, InstrumentationCreateStateParameters parameters) { + Async.CombinedBuilder builder = Async.ofExpectedSize(instrumentations.size()); + for (Instrumentation instrumentation : instrumentations) { + // state can be null including the CF so handle that + CompletableFuture stateCF = Async.orNullCompletedFuture(instrumentation.createStateAsync(parameters)); + builder.add(stateCF); + } + return builder.await().thenApply(ChainedInstrumentationState::new); + } } private static class ChainedInstrumentationContext implements InstrumentationContext { - private final List> contexts; + private final ImmutableList> contexts; - ChainedInstrumentationContext(List> contexts) { - this.contexts = Collections.unmodifiableList(contexts); + ChainedInstrumentationContext(ImmutableList> contexts) { + this.contexts = contexts; } @Override - public void onDispatched(CompletableFuture result) { - contexts.forEach(context -> context.onDispatched(result)); + public void onDispatched() { + contexts.forEach(InstrumentationContext::onDispatched); } @Override @@ -240,15 +306,15 @@ public void onCompleted(T result, Throwable t) { private static class ChainedExecutionStrategyInstrumentationContext implements ExecutionStrategyInstrumentationContext { - private final List contexts; + private final ImmutableList contexts; - ChainedExecutionStrategyInstrumentationContext(List contexts) { - this.contexts = Collections.unmodifiableList(contexts); + ChainedExecutionStrategyInstrumentationContext(ImmutableList contexts) { + this.contexts = contexts; } @Override - public void onDispatched(CompletableFuture result) { - contexts.forEach(context -> context.onDispatched(result)); + public void onDispatched() { + contexts.forEach(InstrumentationContext::onDispatched); } @Override @@ -262,33 +328,89 @@ public void onFieldValuesInfo(List fieldValueInfoList) { } @Override - public void onDeferredField(List field) { - contexts.forEach(context -> context.onDeferredField(field)); + public void onFieldValuesException() { + contexts.forEach(ExecutionStrategyInstrumentationContext::onFieldValuesException); } } - private static class ChainedDeferredExecutionStrategyInstrumentationContext implements DeferredFieldInstrumentationContext { + private static class ChainedExecuteObjectInstrumentationContext implements ExecuteObjectInstrumentationContext { - private final List contexts; + private final ImmutableList contexts; - ChainedDeferredExecutionStrategyInstrumentationContext(List contexts) { - this.contexts = Collections.unmodifiableList(contexts); + ChainedExecuteObjectInstrumentationContext(ImmutableList contexts) { + this.contexts = contexts; } @Override - public void onDispatched(CompletableFuture result) { - contexts.forEach(context -> context.onDispatched(result)); + public void onDispatched() { + contexts.forEach(InstrumentationContext::onDispatched); } @Override - public void onCompleted(ExecutionResult result, Throwable t) { + public void onCompleted(Map result, Throwable t) { + contexts.forEach(context -> context.onCompleted(result, t)); + } + + @Override + public void onFieldValuesInfo(List fieldValueInfoList) { + contexts.forEach(context -> context.onFieldValuesInfo(fieldValueInfoList)); + } + + @Override + public void onFieldValuesException() { + contexts.forEach(ExecuteObjectInstrumentationContext::onFieldValuesException); + } + } + + private static class ChainedFieldFetchingInstrumentationContext implements FieldFetchingInstrumentationContext { + + private final ImmutableList contexts; + + ChainedFieldFetchingInstrumentationContext(ImmutableList contexts) { + this.contexts = contexts; + } + + @Override + public void onDispatched() { + contexts.forEach(FieldFetchingInstrumentationContext::onDispatched); + } + + @Override + public void onFetchedValue(Object fetchedValue) { + contexts.forEach(context -> context.onFetchedValue(fetchedValue)); + } + + @Override + public void onCompleted(Object result, Throwable t) { contexts.forEach(context -> context.onCompleted(result, t)); } + } + + private static class ChainedDeferredExecutionStrategyInstrumentationContext implements InstrumentationContext { + + + private final List> contexts; + + ChainedDeferredExecutionStrategyInstrumentationContext(List> contexts) { + this.contexts = Collections.unmodifiableList(contexts); + } + + @Override + public void onDispatched() { + contexts.forEach(InstrumentationContext::onDispatched); + } @Override - public void onFieldValueInfo(FieldValueInfo fieldValueInfo) { - contexts.forEach(context -> context.onFieldValueInfo(fieldValueInfo)); + public void onCompleted(Object result, Throwable t) { + contexts.forEach(context -> context.onCompleted(result, t)); } } + + @FunctionalInterface + private interface ChainedInstrumentationFunction { + R apply(I instrumentation, S state, V value); + } + + } diff --git a/src/main/java/graphql/execution/instrumentation/DeferredFieldInstrumentationContext.java b/src/main/java/graphql/execution/instrumentation/DeferredFieldInstrumentationContext.java deleted file mode 100644 index 39de62be19..0000000000 --- a/src/main/java/graphql/execution/instrumentation/DeferredFieldInstrumentationContext.java +++ /dev/null @@ -1,12 +0,0 @@ -package graphql.execution.instrumentation; - -import graphql.ExecutionResult; -import graphql.execution.FieldValueInfo; - -public interface DeferredFieldInstrumentationContext extends InstrumentationContext { - - default void onFieldValueInfo(FieldValueInfo fieldValueInfo) { - - } - -} diff --git a/src/main/java/graphql/execution/instrumentation/DocumentAndVariables.java b/src/main/java/graphql/execution/instrumentation/DocumentAndVariables.java new file mode 100644 index 0000000000..7b5c4c4978 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/DocumentAndVariables.java @@ -0,0 +1,58 @@ +package graphql.execution.instrumentation; + +import graphql.PublicApi; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.language.Document; + +import java.util.Map; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; + +@PublicApi +public class DocumentAndVariables { + private final Document document; + private final ImmutableMapWithNullValues variables; + + private DocumentAndVariables(Document document, Map variables) { + this.document = assertNotNull(document); + this.variables = ImmutableMapWithNullValues.copyOf(assertNotNull(variables)); + } + + public Document getDocument() { + return document; + } + + public Map getVariables() { + return variables; + } + + public DocumentAndVariables transform(Consumer builderConsumer) { + Builder builder = new Builder().document(this.document).variables(this.variables); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newDocumentAndVariables() { + return new Builder(); + } + + public static class Builder { + private Document document; + private Map variables; + + public Builder document(Document document) { + this.document = document; + return this; + } + + public Builder variables(Map variables) { + this.variables = variables; + return this; + } + + public DocumentAndVariables build() { + return new DocumentAndVariables(document, variables); + } + } +} diff --git a/src/main/java/graphql/execution/instrumentation/ExecuteObjectInstrumentationContext.java b/src/main/java/graphql/execution/instrumentation/ExecuteObjectInstrumentationContext.java new file mode 100644 index 0000000000..a9d8417756 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/ExecuteObjectInstrumentationContext.java @@ -0,0 +1,44 @@ +package graphql.execution.instrumentation; + +import graphql.Internal; +import graphql.PublicSpi; +import graphql.execution.FieldValueInfo; +import org.jspecify.annotations.NonNull; + +import java.util.List; +import java.util.Map; + +@PublicSpi +public interface ExecuteObjectInstrumentationContext extends InstrumentationContext> { + + @Internal + ExecuteObjectInstrumentationContext NOOP = new ExecuteObjectInstrumentationContext() { + @Override + public void onDispatched() { + } + + @Override + public void onCompleted(Map result, Throwable t) { + } + }; + + /** + * This creates a no-op {@link InstrumentationContext} if the one pass in is null + * + * @param nullableContext a {@link InstrumentationContext} that can be null + * + * @return a non null {@link InstrumentationContext} that maybe a no-op + */ + @NonNull + @Internal + static ExecuteObjectInstrumentationContext nonNullCtx(ExecuteObjectInstrumentationContext nullableContext) { + return nullableContext == null ? NOOP : nullableContext; + } + + default void onFieldValuesInfo(List fieldValueInfoList) { + } + + default void onFieldValuesException() { + } + +} diff --git a/src/main/java/graphql/execution/instrumentation/ExecutionStrategyInstrumentationContext.java b/src/main/java/graphql/execution/instrumentation/ExecutionStrategyInstrumentationContext.java index 79dacde0c5..5b9abac713 100644 --- a/src/main/java/graphql/execution/instrumentation/ExecutionStrategyInstrumentationContext.java +++ b/src/main/java/graphql/execution/instrumentation/ExecutionStrategyInstrumentationContext.java @@ -1,18 +1,46 @@ package graphql.execution.instrumentation; import graphql.ExecutionResult; +import graphql.Internal; +import graphql.PublicSpi; import graphql.execution.FieldValueInfo; -import graphql.language.Field; +import org.jspecify.annotations.NonNull; import java.util.List; +@PublicSpi public interface ExecutionStrategyInstrumentationContext extends InstrumentationContext { default void onFieldValuesInfo(List fieldValueInfoList) { } - default void onDeferredField(List field) { + default void onFieldValuesException() { } + + /** + * This creates a no-op {@link InstrumentationContext} if the one pass in is null + * + * @param nullableContext a {@link InstrumentationContext} that can be null + * + * @return a non null {@link InstrumentationContext} that maybe a no-op + */ + @NonNull + @Internal + static ExecutionStrategyInstrumentationContext nonNullCtx(ExecutionStrategyInstrumentationContext nullableContext) { + return nullableContext == null ? NOOP : nullableContext; + } + + @Internal + ExecutionStrategyInstrumentationContext NOOP = new ExecutionStrategyInstrumentationContext() { + @Override + public void onDispatched() { + } + + @Override + public void onCompleted(ExecutionResult result, Throwable t) { + } + }; + } diff --git a/src/main/java/graphql/execution/instrumentation/FieldFetchingInstrumentationContext.java b/src/main/java/graphql/execution/instrumentation/FieldFetchingInstrumentationContext.java new file mode 100644 index 0000000000..38984c6f92 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/FieldFetchingInstrumentationContext.java @@ -0,0 +1,69 @@ +package graphql.execution.instrumentation; + +import graphql.Internal; +import graphql.PublicSpi; +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +/** + * FieldFetchingInstrumentationContext is returned back from the {@link Instrumentation#beginFieldFetching(InstrumentationFieldFetchParameters, InstrumentationState)} + * method, and it's much like the normal {@link InstrumentationContext} type except it also + * gives the value that was returned by a fields {@link graphql.schema.DataFetcher}. This allows + * you to know if the field value is a completely materialised field or if it's a {@link java.util.concurrent.CompletableFuture} + * promise to a value. + */ +@PublicSpi +public interface FieldFetchingInstrumentationContext extends InstrumentationContext { + + /** + * This is called back with the value fetched for the field by its {@link graphql.schema.DataFetcher}. + * This can be a materialised java object or it maybe a {@link java.util.concurrent.CompletableFuture} + * promise to some async value that has not yet completed. + * + * @param fetchedValue a value that a field's {@link graphql.schema.DataFetcher} returned + */ + default void onFetchedValue(Object fetchedValue) { + } + + @Internal + FieldFetchingInstrumentationContext NOOP = new FieldFetchingInstrumentationContext() { + @Override + public void onDispatched() { + } + + @Override + public void onCompleted(Object result, Throwable t) { + } + }; + + /** + * This creates a no-op {@link InstrumentationContext} if the one passed in is null + * + * @param nullableContext a {@link InstrumentationContext} that can be null + * @return a non-null {@link InstrumentationContext} that maybe a no-op + */ + @NonNull + @Internal + static FieldFetchingInstrumentationContext nonNullCtx(FieldFetchingInstrumentationContext nullableContext) { + return nullableContext == null ? NOOP : nullableContext; + } + + @Internal + static FieldFetchingInstrumentationContext adapter(@Nullable InstrumentationContext context) { + if (context == null) { + return null; + } + return new FieldFetchingInstrumentationContext() { + @Override + public void onDispatched() { + context.onDispatched(); + } + + @Override + public void onCompleted(Object result, Throwable t) { + context.onCompleted(result, t); + } + }; + } +} diff --git a/src/main/java/graphql/execution/instrumentation/Instrumentation.java b/src/main/java/graphql/execution/instrumentation/Instrumentation.java index aa995b04f2..565c4333da 100644 --- a/src/main/java/graphql/execution/instrumentation/Instrumentation.java +++ b/src/main/java/graphql/execution/instrumentation/Instrumentation.java @@ -2,142 +2,271 @@ import graphql.ExecutionInput; import graphql.ExecutionResult; +import graphql.ExperimentalApi; +import graphql.PublicSpi; import graphql.execution.ExecutionContext; -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationReactiveResultsParameters; import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; import graphql.language.Document; import graphql.schema.DataFetcher; import graphql.schema.GraphQLSchema; import graphql.validation.ValidationError; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import java.util.List; import java.util.concurrent.CompletableFuture; +import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp; + /** * Provides the capability to instrument the execution steps of a GraphQL query. - * + *

* For example you might want to track which fields are taking the most time to fetch from the backing database * or log what fields are being asked for. - * + *

* Remember that graphql calls can cross threads so make sure you think about the thread safety of any instrumentation * code when you are writing it. - * + *

* Each step gives back an {@link graphql.execution.instrumentation.InstrumentationContext} object. This has two callbacks on it, * one for the step is `dispatched` and one for when the step has `completed`. This is done because many of the "steps" are asynchronous * operations such as fetching data and resolving it into objects. */ +@PublicSpi public interface Instrumentation { - /** - * This will be called just before execution to create an object that is given back to all instrumentation methods + * This will be called just before execution to create an object, in an asynchronous manner, that is given back to all instrumentation methods * to allow them to have per execution request state * + * @param parameters the parameters to this step + * * @return a state object that is passed to each method */ - default InstrumentationState createState() { + @Nullable + default CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + InstrumentationState state = createState(parameters); + return state == null ? null : CompletableFuture.completedFuture(state); + } + + /** + * This method is retained for backwards compatibility reasons so that previous {@link Instrumentation} implementations + * continue to work. The graphql-java code only called {@link #createStateAsync(InstrumentationCreateStateParameters)} + * but the default implementation calls back to this method. + * + * @param parameters the parameters to this step + * + * @return a state object that is passed to each method + */ + @Nullable + default InstrumentationState createState(InstrumentationCreateStateParameters parameters) { return null; } /** - * This is called right at the start of query execution and its the first step in the instrumentation chain. + * This is called right at the start of query execution, and it's the first step in the instrumentation chain. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters); + @Nullable + default InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return noOp(); + } /** * This is called just before a query is parsed. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - InstrumentationContext beginParse(InstrumentationExecutionParameters parameters); + @Nullable + default InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return noOp(); + } /** * This is called just before the parsed query document is validated. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters); + @Nullable + default InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + return noOp(); + } /** * This is called just before the execution of the query operation is started. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters); + @Nullable + default InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + return noOp(); + } + + /** + * This is called just before the execution of any reactive results, namely incremental deferred results or subscriptions. When the {@link org.reactivestreams.Publisher} + * finally ends (with either a {@link Throwable} or none) then the {@link InstrumentationContext} wil be called back to say the reactive results + * have finished. + * + * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} + * + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) + */ + @Nullable + default InstrumentationContext beginReactiveResults(InstrumentationReactiveResultsParameters parameters, InstrumentationState state) { + return noOp(); + } /** * This is called each time an {@link graphql.execution.ExecutionStrategy} is invoked, which may be multiple times - * per query as the engine recursively descends down over the query. + * per query as the engine recursively descends over the query. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link ExecutionStrategyInstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters); + @Nullable + default ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return ExecutionStrategyInstrumentationContext.NOOP; + } + + /** + * This is called each time an {@link graphql.execution.ExecutionStrategy} object resolution is called, which may be multiple times + * per query as the engine recursively descends over the query. + * + * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} + * + * @return a nullable {@link ExecutionStrategyInstrumentationContext} object that will be called back when the step ends (assuming it's not null) + */ + @Nullable + default ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return ExecuteObjectInstrumentationContext.NOOP; + } /** * This is called just before a deferred field is resolved into a value. + *

+ * This is an EXPERIMENTAL instrumentation callback. The method signature will definitely change. + * + * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} + * + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) + */ + @ExperimentalApi + default InstrumentationContext beginDeferredField(InstrumentationFieldParameters parameters, InstrumentationState state) { + return noOp(); + } + + /** + * This is called each time a subscription field produces a new reactive stream event value and it needs to be mapped over via the graphql field subselection. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - DeferredFieldInstrumentationContext beginDeferredField(InstrumentationDeferredFieldParameters parameters); + @Nullable + default InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + return noOp(); + } /** * This is called just before a field is resolved into a value. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - InstrumentationContext beginField(InstrumentationFieldParameters parameters); + @Nullable + default InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + return noOp(); + } + /** * This is called just before a field {@link DataFetcher} is invoked. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} + * + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @deprecated use {@link #beginFieldFetching(InstrumentationFieldFetchParameters, InstrumentationState)} instead */ - InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters); + @Deprecated(since = "2024-04-18") + @Nullable + default InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return noOp(); + } + /** + * This is called just before a field {@link DataFetcher} is invoked. The {@link FieldFetchingInstrumentationContext#onFetchedValue(Object)} + * callback will be invoked once a value is returned by a {@link DataFetcher} but perhaps before + * its value is completed if it's a {@link CompletableFuture} value. + *

+ * This method is the replacement method for the now deprecated {@link #beginFieldFetch(InstrumentationFieldFetchParameters, InstrumentationState)} + * method, and it should be implemented in new {@link Instrumentation} classes. This default version of this + * method calls back to the deprecated {@link #beginFieldFetch(InstrumentationFieldFetchParameters, InstrumentationState)} method + * so that older implementations continue to work. + * + * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} + * + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) + */ + @Nullable + default FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + InstrumentationContext ctx = beginFieldFetch(parameters, state); + return FieldFetchingInstrumentationContext.adapter(ctx); + } /** * This is called just before the complete field is started. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - default InstrumentationContext beginFieldComplete(InstrumentationFieldCompleteParameters parameters) { - return new SimpleInstrumentationContext<>(); + @Nullable + default InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return noOp(); } /** * This is called just before the complete field list is started. * * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null {@link InstrumentationContext} object that will be called back when the step ends + * @return a nullable {@link InstrumentationContext} object that will be called back when the step ends (assuming it's not null) */ - default InstrumentationContext beginFieldListComplete(InstrumentationFieldCompleteParameters parameters) { - return new SimpleInstrumentationContext<>(); + @Nullable + default InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return noOp(); } /** @@ -146,23 +275,41 @@ default InstrumentationContext beginFieldListComplete(Instrumen * * @param executionInput the execution input to be used * @param parameters the parameters describing the field to be fetched + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null instrumented ExecutionInput, the default is to return to the same object + * @return a non-null instrumented ExecutionInput, the default is to return to the same object */ - default ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters) { + @NonNull + default ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { return executionInput; } + /** + * This is called to instrument a {@link graphql.language.Document} and variables before it is used allowing you to adjust the query AST if you so desire + * + * @param documentAndVariables the document and variables to be used + * @param parameters the parameters describing the execution + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} + * + * @return a non-null instrumented DocumentAndVariables, the default is to return to the same objects + */ + @NonNull + default DocumentAndVariables instrumentDocumentAndVariables(DocumentAndVariables documentAndVariables, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return documentAndVariables; + } + /** * This is called to instrument a {@link graphql.schema.GraphQLSchema} before it is used to parse, validate * and execute a query, allowing you to adjust what types are used. * * @param schema the schema to be used * @param parameters the parameters describing the field to be fetched + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null instrumented GraphQLSchema, the default is to return to the same object + * @return a non-null instrumented GraphQLSchema, the default is to return to the same object */ - default GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters) { + @NonNull + default GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState state) { return schema; } @@ -172,14 +319,15 @@ default GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExec * * @param executionContext the execution context to be used * @param parameters the parameters describing the field to be fetched + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null instrumented ExecutionContext, the default is to return to the same object + * @return a non-null instrumented ExecutionContext, the default is to return to the same object */ - default ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters) { + @NonNull + default ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters, InstrumentationState state) { return executionContext; } - /** * This is called to instrument a {@link DataFetcher} just before it is used to fetch a field, allowing you * to adjust what information is passed back or record information about specific data fetches. Note @@ -188,10 +336,12 @@ default ExecutionContext instrumentExecutionContext(ExecutionContext executionCo * * @param dataFetcher the data fetcher about to be used * @param parameters the parameters describing the field to be fetched + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * - * @return a non null instrumented DataFetcher, the default is to return to the same object + * @return a non-null instrumented DataFetcher, the default is to return to the same object */ - default DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { + @NonNull + default DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { return dataFetcher; } @@ -200,11 +350,12 @@ default DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, Instrum * * @param executionResult {@link java.util.concurrent.CompletableFuture} of the result to instrument * @param parameters the parameters to this step + * @param state the state created during the call to {@link #createStateAsync(InstrumentationCreateStateParameters)} * * @return a new execution result completable future */ - default CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { + @NonNull + default CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { return CompletableFuture.completedFuture(executionResult); } - } diff --git a/src/main/java/graphql/execution/instrumentation/InstrumentationContext.java b/src/main/java/graphql/execution/instrumentation/InstrumentationContext.java index 4f76ca36f4..422d0ece71 100644 --- a/src/main/java/graphql/execution/instrumentation/InstrumentationContext.java +++ b/src/main/java/graphql/execution/instrumentation/InstrumentationContext.java @@ -1,6 +1,8 @@ package graphql.execution.instrumentation; -import java.util.concurrent.CompletableFuture; +import graphql.PublicSpi; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * When a {@link Instrumentation}.'beginXXX()' method is called then it must return a non null InstrumentationContext @@ -10,14 +12,14 @@ * This pattern of construction of an object then call back is intended to allow "timers" to be created that can instrument what has * just happened or "loggers" to be called to record what has happened. */ +@PublicSpi +@NullMarked public interface InstrumentationContext { /** * This is invoked when the instrumentation step is initially dispatched - * - * @param result the result of the step as a completable future */ - void onDispatched(CompletableFuture result); + void onDispatched(); /** * This is invoked when the instrumentation step is fully completed @@ -25,6 +27,6 @@ public interface InstrumentationContext { * @param result the result of the step (which may be null) * @param t this exception will be non null if an exception was thrown during the step */ - void onCompleted(T result, Throwable t); + void onCompleted(@Nullable T result, @Nullable Throwable t); } diff --git a/src/main/java/graphql/execution/instrumentation/InstrumentationState.java b/src/main/java/graphql/execution/instrumentation/InstrumentationState.java index 7aacb0d997..258c865474 100644 --- a/src/main/java/graphql/execution/instrumentation/InstrumentationState.java +++ b/src/main/java/graphql/execution/instrumentation/InstrumentationState.java @@ -1,10 +1,27 @@ package graphql.execution.instrumentation; +import graphql.PublicSpi; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; + /** * An {@link Instrumentation} implementation can create this as a stateful object that is then passed * to each instrumentation method, allowing state to be passed down with the request execution * - * @see Instrumentation#createState() + * @see Instrumentation#createStateAsync(InstrumentationCreateStateParameters) */ +@PublicSpi public interface InstrumentationState { + + /** + * This helper method allows you to cast from {@link InstrumentationState} to a custom classes more easily. + * + * @param rawState the raw InstrumentationState + * @param for two + * + * @return a cast custom InstrumentationState + */ + static T ofState(InstrumentationState rawState) { + //noinspection unchecked + return (T) rawState; + } } diff --git a/src/main/java/graphql/execution/instrumentation/NoContextChainedInstrumentation.java b/src/main/java/graphql/execution/instrumentation/NoContextChainedInstrumentation.java new file mode 100644 index 0000000000..8d56230825 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/NoContextChainedInstrumentation.java @@ -0,0 +1,128 @@ +package graphql.execution.instrumentation; + +import graphql.ExecutionResult; +import graphql.PublicApi; +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationReactiveResultsParameters; +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; +import graphql.language.Document; +import graphql.validation.ValidationError; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.function.BiConsumer; + +/** + * This version of {@link ChainedInstrumentation} will call a list of {@link Instrumentation}s + * but it will never back on the returned {@link InstrumentationContext} objects, hence it is only suitable to + * certain use cases. + * + * Only use this class if you are optimising for memory usage as scale. In most cases the {@link ChainedInstrumentation} + * will do the job required with all the instrumentation features used however some users require the fastest performance and lowest memory + * usage at scale and this class can be used. + * + * At scale, the fact that the graphql engine holds the {@link InstrumentationContext} objects in memory for a (relatively) long time + * (the length of the request or the length of a large field fetch) means that memory pressure can grow + * and objects move into longer tenure GC pools. Holding these contexts is also not necessary if the instrumentation never needs to know when a + * certain execution step finishes. + * + * The {@link InstrumentationContext} is used ot know when an execution step has completed, so instrumentations that do + * timings say need to use this callback mechanism. Putting such an instrumentation into {@link NoContextChainedInstrumentation} would + * be a mistake because no callback will occur. Therefore, use of this class is reserved for very specific us cases. You are fore-warned. + * + * This class never holds onto the returned {@link InstrumentationContext} objects and always returns null + * as itself. + */ +@PublicApi +public class NoContextChainedInstrumentation extends ChainedInstrumentation { + + public NoContextChainedInstrumentation(List instrumentations) { + super(instrumentations); + } + + public NoContextChainedInstrumentation(Instrumentation... instrumentations) { + super(instrumentations); + } + + private T runAll(InstrumentationState state, BiConsumer stateConsumer) { + chainedConsume(state, stateConsumer); + return null; + } + + @Override + public InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginExecution(parameters, specificState)); + } + + @Override + public InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginParse(parameters, specificState)); + } + + @Override + public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginValidation(parameters, specificState)); + } + + @Override + public InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginExecuteOperation(parameters, specificState)); + } + + @Override + public @Nullable InstrumentationContext beginReactiveResults(InstrumentationReactiveResultsParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginReactiveResults(parameters, specificState)); + } + + @Override + public ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginExecutionStrategy(parameters, specificState)); + } + + @Override + public @Nullable ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginExecuteObject(parameters, specificState)); + } + + @Override + public InstrumentationContext beginDeferredField(InstrumentationFieldParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginDeferredField(parameters, specificState)); + } + + @Override + public InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginSubscribedFieldEvent(parameters, specificState)); + } + + @Override + public @Nullable InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldExecution(parameters, specificState)); + } + + @Override + public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldFetch(parameters, specificState)); + } + + @Override + public FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldFetching(parameters, specificState)); + } + + @Override + public @Nullable InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldCompletion(parameters, specificState)); + } + + @Override + public @Nullable InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return runAll(state, (instrumentation, specificState) -> instrumentation.beginFieldListCompletion(parameters, specificState)); + } + + // relies on the other methods from ChainedInstrumentation which this does not change +} diff --git a/src/main/java/graphql/execution/instrumentation/SimpleInstrumentation.java b/src/main/java/graphql/execution/instrumentation/SimpleInstrumentation.java index 398f9d758a..d2df536e75 100644 --- a/src/main/java/graphql/execution/instrumentation/SimpleInstrumentation.java +++ b/src/main/java/graphql/execution/instrumentation/SimpleInstrumentation.java @@ -1,29 +1,17 @@ package graphql.execution.instrumentation; -import graphql.ExecutionResult; import graphql.PublicApi; -import graphql.execution.ExecutionContext; -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; -import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; -import graphql.language.Document; -import graphql.schema.DataFetcher; -import graphql.schema.GraphQLSchema; -import graphql.validation.ValidationError; - -import java.util.List; -import java.util.concurrent.CompletableFuture; /** * An implementation of {@link graphql.execution.instrumentation.Instrumentation} that does nothing. It can be used - * as a base for derived classes where you only implement the methods you want to + * as a base for derived classes where you only implement the methods you want to. With all the methods in {@link Instrumentation} + * now defaulted (post Java 6) this class is really not needed anymore but has been retained for backwards compatibility + * reasons. + * + * @deprecated use {@link SimplePerformantInstrumentation} instead as a base class. */ @PublicApi +@Deprecated(since = "2022-10-05") public class SimpleInstrumentation implements Instrumentation { /** @@ -31,103 +19,4 @@ public class SimpleInstrumentation implements Instrumentation { */ public static final SimpleInstrumentation INSTANCE = new SimpleInstrumentation(); - public SimpleInstrumentation() { - } - - @Override - public InstrumentationState createState() { - return null; - } - - @Override - public InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public InstrumentationContext beginParse(InstrumentationExecutionParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { - return new ExecutionStrategyInstrumentationContext() { - @Override - public void onDispatched(CompletableFuture result) { - - } - - @Override - public void onCompleted(ExecutionResult result, Throwable t) { - - } - }; - } - - @Override - public DeferredFieldInstrumentationContext beginDeferredField(InstrumentationDeferredFieldParameters parameters) { - return new DeferredFieldInstrumentationContext() { - @Override - public void onDispatched(CompletableFuture result) { - - } - - @Override - public void onCompleted(ExecutionResult result, Throwable t) { - - } - }; - } - - @Override - public InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public InstrumentationContext beginField(InstrumentationFieldParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - - @Override - public InstrumentationContext beginFieldComplete(InstrumentationFieldCompleteParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public InstrumentationContext beginFieldListComplete(InstrumentationFieldCompleteParameters parameters) { - return new SimpleInstrumentationContext<>(); - } - - @Override - public GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters) { - return schema; - } - - @Override - public ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters) { - return executionContext; - } - - @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - return dataFetcher; - } - - @Override - public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { - return CompletableFuture.completedFuture(executionResult); - } - } diff --git a/src/main/java/graphql/execution/instrumentation/SimpleInstrumentationContext.java b/src/main/java/graphql/execution/instrumentation/SimpleInstrumentationContext.java index a7d796f416..0abfc744d6 100644 --- a/src/main/java/graphql/execution/instrumentation/SimpleInstrumentationContext.java +++ b/src/main/java/graphql/execution/instrumentation/SimpleInstrumentationContext.java @@ -1,10 +1,9 @@ package graphql.execution.instrumentation; import graphql.PublicApi; +import org.jspecify.annotations.NonNull; -import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; -import java.util.function.Consumer; /** * A simple implementation of {@link InstrumentationContext} @@ -12,22 +11,57 @@ @PublicApi public class SimpleInstrumentationContext implements InstrumentationContext { + private static final InstrumentationContext NO_OP = new InstrumentationContext() { + @Override + public void onDispatched() { + } + + @Override + public void onCompleted(Object result, Throwable t) { + } + }; + + /** + * A context that does nothing + * + * @param the type needed + * + * @return a context that does nothing + */ + @SuppressWarnings("unchecked") + public static InstrumentationContext noOp() { + return (InstrumentationContext) NO_OP; + } + + /** + * This creates a no-op {@link InstrumentationContext} if the one pass in is null + * + * @param nullableContext a {@link InstrumentationContext} that can be null + * @param for two + * + * @return a non null {@link InstrumentationContext} that maybe a no-op + */ + @NonNull + public static InstrumentationContext nonNullCtx(InstrumentationContext nullableContext) { + return nullableContext == null ? noOp() : nullableContext; + } + private final BiConsumer codeToRunOnComplete; - private final Consumer> codeToRunOnDispatch; + private final Runnable codeToRunOnDispatch; public SimpleInstrumentationContext() { this(null, null); } - private SimpleInstrumentationContext(Consumer> codeToRunOnDispatch, BiConsumer codeToRunOnComplete) { + private SimpleInstrumentationContext(Runnable codeToRunOnDispatch, BiConsumer codeToRunOnComplete) { this.codeToRunOnComplete = codeToRunOnComplete; this.codeToRunOnDispatch = codeToRunOnDispatch; } @Override - public void onDispatched(CompletableFuture result) { + public void onDispatched() { if (codeToRunOnDispatch != null) { - codeToRunOnDispatch.accept(result); + codeToRunOnDispatch.run(); } } @@ -47,7 +81,7 @@ public void onCompleted(T result, Throwable t) { * * @return an instrumentation context */ - public static SimpleInstrumentationContext whenDispatched(Consumer> codeToRun) { + public static SimpleInstrumentationContext whenDispatched(Runnable codeToRun) { return new SimpleInstrumentationContext<>(codeToRun, null); } @@ -63,4 +97,12 @@ public static SimpleInstrumentationContext whenDispatched(Consumer SimpleInstrumentationContext whenCompleted(BiConsumer codeToRun) { return new SimpleInstrumentationContext<>(null, codeToRun); } + + public static BiConsumer completeInstrumentationCtxCF( + InstrumentationContext instrumentationContext) { + return (result, throwable) -> { + nonNullCtx(instrumentationContext).onCompleted(result, throwable); + }; + } + } diff --git a/src/main/java/graphql/execution/instrumentation/SimplePerformantInstrumentation.java b/src/main/java/graphql/execution/instrumentation/SimplePerformantInstrumentation.java new file mode 100644 index 0000000000..26f30714fa --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/SimplePerformantInstrumentation.java @@ -0,0 +1,143 @@ +package graphql.execution.instrumentation; + +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.PublicApi; +import graphql.execution.ExecutionContext; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters; +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; +import graphql.language.Document; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLSchema; +import graphql.validation.ValidationError; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp; + +/** + * An implementation of {@link Instrumentation} that does nothing. It can be used + * as a base for derived classes where you only implement the methods you want to. The reason this + * class is designated as more performant is that it does not delegate back to the deprecated methods + * and allocate a new state object per call. + *

+ * This behavior was left in place for backwards compatibility reasons inside {@link Instrumentation} + * and {@link SimpleInstrumentation} but has not been done in this class since no existing classes + * could have derived from it. If you want more performant behavior on methods you don't implement + * then this is the base class to use, since it will not delegate back to old methods + * and cause a new state to be allocated. + */ +@SuppressWarnings("deprecation") +@PublicApi +public class SimplePerformantInstrumentation implements Instrumentation { + + /** + * A singleton instance of a {@link Instrumentation} that does nothing + */ + public static final SimplePerformantInstrumentation INSTANCE = new SimplePerformantInstrumentation(); + + @Override + public @Nullable CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + InstrumentationState state = createState(parameters); + return state == null ? null : CompletableFuture.completedFuture(state); + } + + @Override + public @Nullable InstrumentationState createState(InstrumentationCreateStateParameters parameters) { + return null; + } + + @Override + public @Nullable InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return ExecutionStrategyInstrumentationContext.NOOP; + } + + @Override + public @Nullable ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return ExecuteObjectInstrumentationContext.NOOP; + } + + @Override + public @Nullable InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @Nullable InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + return noOp(); + } + + @Override + public @NonNull ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return executionInput; + } + + @Override + public @NonNull DocumentAndVariables instrumentDocumentAndVariables(DocumentAndVariables documentAndVariables, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return documentAndVariables; + } + + @Override + public @NonNull GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return schema; + } + + @Override + public @NonNull ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return executionContext; + } + + @Override + public @NonNull DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return dataFetcher; + } + + @Override + public @NonNull CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return CompletableFuture.completedFuture(executionResult); + } +} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentation.java b/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentation.java deleted file mode 100644 index 5dc14160a7..0000000000 --- a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentation.java +++ /dev/null @@ -1,173 +0,0 @@ -package graphql.execution.instrumentation.dataloader; - -import graphql.ExecutionResult; -import graphql.ExecutionResultImpl; -import graphql.execution.AsyncExecutionStrategy; -import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionStrategy; -import graphql.execution.instrumentation.DeferredFieldInstrumentationContext; -import graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext; -import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.SimpleInstrumentation; -import graphql.execution.instrumentation.SimpleInstrumentationContext; -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.language.OperationDefinition; -import graphql.schema.DataFetcher; -import org.dataloader.DataLoader; -import org.dataloader.DataLoaderRegistry; -import org.dataloader.stats.Statistics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -/** - * This graphql {@link graphql.execution.instrumentation.Instrumentation} will dispatch - * all the contained {@link org.dataloader.DataLoader}s when each level of the graphql - * query is executed. - * - * This allows you to use {@link org.dataloader.DataLoader}s in your {@link graphql.schema.DataFetcher}s - * to optimal loading of data. - * - * @see org.dataloader.DataLoader - * @see org.dataloader.DataLoaderRegistry - */ -public class DataLoaderDispatcherInstrumentation extends SimpleInstrumentation { - - private static final Logger log = LoggerFactory.getLogger(DataLoaderDispatcherInstrumentation.class); - - private final DataLoaderRegistry dataLoaderRegistry; - private final DataLoaderDispatcherInstrumentationOptions options; - private final FieldLevelTrackingApproach fieldLevelTrackingApproach; - - /** - * You pass in a registry of N data loaders which will be {@link org.dataloader.DataLoader#dispatch() dispatched} as - * each level of the query executes. - * - * @param dataLoaderRegistry the registry of data loaders that will be dispatched - */ - public DataLoaderDispatcherInstrumentation(DataLoaderRegistry dataLoaderRegistry) { - this(dataLoaderRegistry, DataLoaderDispatcherInstrumentationOptions.newOptions()); - } - - /** - * You pass in a registry of N data loaders which will be {@link org.dataloader.DataLoader#dispatch() dispatched} as - * each level of the query executes. - * - * @param dataLoaderRegistry the registry of data loaders that will be dispatched - * @param options the options to control the behaviour - */ - public DataLoaderDispatcherInstrumentation(DataLoaderRegistry dataLoaderRegistry, DataLoaderDispatcherInstrumentationOptions options) { - this.dataLoaderRegistry = dataLoaderRegistry; - this.options = options; - this.fieldLevelTrackingApproach = new FieldLevelTrackingApproach(log, dataLoaderRegistry); - } - - - @Override - public InstrumentationState createState() { - return fieldLevelTrackingApproach.createState(); - } - - - @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - DataLoaderDispatcherInstrumentationState state = parameters.getInstrumentationState(); - if (state.isAggressivelyBatching()) { - return dataFetcher; - } - // - // currently only AsyncExecutionStrategy with DataLoader and hence this allows us to "dispatch" - // on every object if its not using aggressive batching for other execution strategies - // which allows them to work if used. - return (DataFetcher) environment -> { - Object obj = dataFetcher.get(environment); - immediatelyDispatch(); - return obj; - }; - } - - private void immediatelyDispatch() { - fieldLevelTrackingApproach.dispatch(); - } - - @Override - public InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) { - if (!isDataLoaderCompatibleExecution(parameters.getExecutionContext())) { - DataLoaderDispatcherInstrumentationState state = parameters.getInstrumentationState(); - state.setAggressivelyBatching(false); - } - return new SimpleInstrumentationContext<>(); - } - - private boolean isDataLoaderCompatibleExecution(ExecutionContext executionContext) { - // - // currently we only support Query operations and ONLY with AsyncExecutionStrategy as the query ES - // This may change in the future but this is the fix for now - // - if (executionContext.getOperationDefinition().getOperation() == OperationDefinition.Operation.QUERY) { - ExecutionStrategy queryStrategy = executionContext.getQueryStrategy(); - if (queryStrategy instanceof AsyncExecutionStrategy) { - return true; - } - } - return false; - } - - @Override - public ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { - return fieldLevelTrackingApproach.beginExecutionStrategy(parameters); - } - - @Override - public DeferredFieldInstrumentationContext beginDeferredField(InstrumentationDeferredFieldParameters parameters) { - return fieldLevelTrackingApproach.beginDeferredField(parameters); - } - - @Override - public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - return fieldLevelTrackingApproach.beginFieldFetch(parameters); - } - - @Override - public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { - if (!options.isIncludeStatistics()) { - return CompletableFuture.completedFuture(executionResult); - } - Map currentExt = executionResult.getExtensions(); - Map statsMap = new LinkedHashMap<>(); - statsMap.putAll(currentExt == null ? Collections.emptyMap() : currentExt); - Map dataLoaderStats = buildStatsMap(); - statsMap.put("dataloader", dataLoaderStats); - - log.debug("Data loader stats : {}", dataLoaderStats); - - return CompletableFuture.completedFuture(new ExecutionResultImpl(executionResult.getData(), executionResult.getErrors(), statsMap)); - } - - private Map buildStatsMap() { - Statistics allStats = dataLoaderRegistry.getStatistics(); - Map statsMap = new LinkedHashMap<>(); - statsMap.put("overall-statistics", allStats.toMap()); - - Map individualStatsMap = new LinkedHashMap<>(); - - for (String dlKey : dataLoaderRegistry.getKeys()) { - DataLoader dl = dataLoaderRegistry.getDataLoader(dlKey); - Statistics statistics = dl.getStatistics(); - individualStatsMap.put(dlKey, statistics.toMap()); - } - - statsMap.put("individual-statistics", individualStatsMap); - - return statsMap; - } -} \ No newline at end of file diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentationOptions.java b/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentationOptions.java deleted file mode 100644 index 91d1805f2d..0000000000 --- a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentationOptions.java +++ /dev/null @@ -1,35 +0,0 @@ -package graphql.execution.instrumentation.dataloader; - -/** - * The options that control the operation of {@link graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation} - */ -public class DataLoaderDispatcherInstrumentationOptions { - - private final boolean includeStatistics; - - private DataLoaderDispatcherInstrumentationOptions(boolean includeStatistics) { - this.includeStatistics = includeStatistics; - } - - public static DataLoaderDispatcherInstrumentationOptions newOptions() { - return new DataLoaderDispatcherInstrumentationOptions(false); - } - - /** - * This will toggle the ability to include java-dataloader statistics into the extensions - * output of your query - * - * @param flag the switch to follow - * - * @return a new options object - */ - public DataLoaderDispatcherInstrumentationOptions includeStatistics(boolean flag) { - return new DataLoaderDispatcherInstrumentationOptions(flag); - } - - - public boolean isIncludeStatistics() { - return includeStatistics; - } - -} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentationState.java b/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentationState.java deleted file mode 100644 index d12b34428e..0000000000 --- a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherInstrumentationState.java +++ /dev/null @@ -1,20 +0,0 @@ -package graphql.execution.instrumentation.dataloader; - -import graphql.execution.instrumentation.InstrumentationState; - -/** - * A base class that keeps track of whether aggressive batching can be used - */ -public class DataLoaderDispatcherInstrumentationState implements InstrumentationState { - private boolean aggressivelyBatching = true; - - boolean isAggressivelyBatching() { - return aggressivelyBatching; - } - - void setAggressivelyBatching(boolean aggressivelyBatching) { - this.aggressivelyBatching = aggressivelyBatching; - } - - -} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatchingContextKeys.java b/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatchingContextKeys.java new file mode 100644 index 0000000000..c41196e050 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/dataloader/DataLoaderDispatchingContextKeys.java @@ -0,0 +1,54 @@ +package graphql.execution.instrumentation.dataloader; + + +import graphql.GraphQLContext; +import graphql.Internal; +import org.jspecify.annotations.NullMarked; + +/** + * GraphQLContext keys related to DataLoader dispatching. + */ +@Internal +@NullMarked +public final class DataLoaderDispatchingContextKeys { + private DataLoaderDispatchingContextKeys() { + } + + /** + * Enables the ability to chain DataLoader dispatching. + *

+ * Because this requires that all DataLoaders are accessed via DataFetchingEnvironment.getLoader() + * this is not completely backwards compatible and therefore disabled by default. + *

+ * Expects a boolean value. + */ + public static final String ENABLE_DATA_LOADER_CHAINING = "__GJ_enable_data_loader_chaining"; + + + /** + * Enabled a different dispatching strategy that mimics the JS event loop based one: + * DataLoader will be dispatched as soon as there is no data fetcher or batch loader currently running. + * + */ + public static final String ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING = "__GJ_enable_data_loader_exhausted_dispatching"; + + /** + * Enables the ability that chained DataLoaders are dispatched automatically. + * + * @param graphQLContext + */ + public static void setEnableDataLoaderChaining(GraphQLContext graphQLContext, boolean enabled) { + graphQLContext.put(ENABLE_DATA_LOADER_CHAINING, enabled); + } + + /** + * Enables the ability that chained DataLoaders are dispatched automatically. + * + * @param graphQLContext + */ + public static void setEnableDataLoaderExhaustedDispatching(GraphQLContext graphQLContext, boolean enabled) { + graphQLContext.put(ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, enabled); + } + + +} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/DelayedDataLoaderDispatcherExecutorFactory.java b/src/main/java/graphql/execution/instrumentation/dataloader/DelayedDataLoaderDispatcherExecutorFactory.java new file mode 100644 index 0000000000..29cb86076f --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/dataloader/DelayedDataLoaderDispatcherExecutorFactory.java @@ -0,0 +1,29 @@ +package graphql.execution.instrumentation.dataloader; + +import graphql.ExperimentalApi; +import graphql.GraphQLContext; +import graphql.execution.ExecutionId; +import org.jspecify.annotations.NullMarked; + +import java.util.concurrent.ScheduledExecutorService; + +/** + * See {@link DataLoaderDispatchingContextKeys} for how to set it. + */ +@ExperimentalApi +@NullMarked +@FunctionalInterface +public interface DelayedDataLoaderDispatcherExecutorFactory { + + /** + * Called once per execution to create the {@link ScheduledExecutorService} for the delayed DataLoader dispatching. + * + * Will only called if needed, i.e. if there are delayed DataLoaders. + * + * @param executionId + * @param graphQLContext + * + * @return + */ + ScheduledExecutorService createExecutor(ExecutionId executionId, GraphQLContext graphQLContext); +} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/EmptyDataLoaderRegistryInstance.java b/src/main/java/graphql/execution/instrumentation/dataloader/EmptyDataLoaderRegistryInstance.java new file mode 100644 index 0000000000..8684ce6c38 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/dataloader/EmptyDataLoaderRegistryInstance.java @@ -0,0 +1,30 @@ +package graphql.execution.instrumentation.dataloader; + +import graphql.Assert; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderRegistry; + +import java.util.function.Function; + +public class EmptyDataLoaderRegistryInstance { + public static final DataLoaderRegistry EMPTY_DATALOADER_REGISTRY = new DataLoaderRegistry() { + // + private static final String ERROR_MESSAGE = "You MUST set in your own DataLoaderRegistry to use data loader"; + + @Override + public DataLoaderRegistry register(String key, DataLoader dataLoader) { + return Assert.assertShouldNeverHappen(ERROR_MESSAGE); + } + + @Override + public DataLoader computeIfAbsent(final String key, + final Function> mappingFunction) { + return Assert.assertShouldNeverHappen(ERROR_MESSAGE); + } + + @Override + public DataLoaderRegistry unregister(String key) { + return Assert.assertShouldNeverHappen(ERROR_MESSAGE); + } + }; +} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/ExhaustedDataLoaderDispatchStrategy.java b/src/main/java/graphql/execution/instrumentation/dataloader/ExhaustedDataLoaderDispatchStrategy.java new file mode 100644 index 0000000000..f237622ecb --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/dataloader/ExhaustedDataLoaderDispatchStrategy.java @@ -0,0 +1,277 @@ +package graphql.execution.instrumentation.dataloader; + +import graphql.Assert; +import graphql.Internal; +import graphql.Profiler; +import graphql.execution.DataLoaderDispatchStrategy; +import graphql.execution.ExecutionContext; +import graphql.execution.ExecutionStrategyParameters; +import graphql.execution.incremental.AlternativeCallContext; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +@Internal +@NullMarked +public class ExhaustedDataLoaderDispatchStrategy implements DataLoaderDispatchStrategy { + + private final CallStack initialCallStack; + private final ExecutionContext executionContext; + + private final Profiler profiler; + + private final Map alternativeCallContextMap = new ConcurrentHashMap<>(); + + + private static class CallStack { + + // 30 bits for objectRunningCount + // 1 bit for dataLoaderToDispatch + // 1 bit for currentlyDispatching + + // Bit positions (from right to left) + static final int currentlyDispatchingShift = 0; + static final int dataLoaderToDispatchShift = 1; + static final int objectRunningCountShift = 2; + + // mask + static final int booleanMask = 1; + static final int objectRunningCountMask = (1 << 30) - 1; + + public static int getObjectRunningCount(int state) { + return (state >> objectRunningCountShift) & objectRunningCountMask; + } + + public static int setObjectRunningCount(int state, int objectRunningCount) { + return (state & ~(objectRunningCountMask << objectRunningCountShift)) | + (objectRunningCount << objectRunningCountShift); + } + + public static int setDataLoaderToDispatch(int state, boolean dataLoaderToDispatch) { + return (state & ~(booleanMask << dataLoaderToDispatchShift)) | + ((dataLoaderToDispatch ? 1 : 0) << dataLoaderToDispatchShift); + } + + public static int setCurrentlyDispatching(int state, boolean currentlyDispatching) { + return (state & ~(booleanMask << currentlyDispatchingShift)) | + ((currentlyDispatching ? 1 : 0) << currentlyDispatchingShift); + } + + + public static boolean getDataLoaderToDispatch(int state) { + return ((state >> dataLoaderToDispatchShift) & booleanMask) != 0; + } + + public static boolean getCurrentlyDispatching(int state) { + return ((state >> currentlyDispatchingShift) & booleanMask) != 0; + } + + + public int incrementObjectRunningCount() { + while (true) { + int oldState = getState(); + int objectRunningCount = getObjectRunningCount(oldState); + int newState = setObjectRunningCount(oldState, objectRunningCount + 1); + if (tryUpdateState(oldState, newState)) { + return newState; + } + } + } + + public int decrementObjectRunningCount() { + while (true) { + int oldState = getState(); + int objectRunningCount = getObjectRunningCount(oldState); + int newState = setObjectRunningCount(oldState, objectRunningCount - 1); + if (tryUpdateState(oldState, newState)) { + return newState; + } + } + } + + // for debugging + public static String printState(int state) { + return "objectRunningCount: " + getObjectRunningCount(state) + + ",dataLoaderToDispatch: " + getDataLoaderToDispatch(state) + + ",currentlyDispatching: " + getCurrentlyDispatching(state); + } + + private final AtomicInteger state = new AtomicInteger(); + + public int getState() { + return state.get(); + } + + public boolean tryUpdateState(int oldState, int newState) { + return state.compareAndSet(oldState, newState); + } + + private final AtomicInteger deferredFragmentRootFieldsCompleted = new AtomicInteger(); + + public CallStack() { + } + + + public void clear() { + deferredFragmentRootFieldsCompleted.set(0); + state.set(0); + } + } + + public ExhaustedDataLoaderDispatchStrategy(ExecutionContext executionContext) { + this.initialCallStack = new CallStack(); + this.executionContext = executionContext; + + this.profiler = executionContext.getProfiler(); + } + + + @Override + public void executionStrategy(ExecutionContext executionContext, ExecutionStrategyParameters parameters, int fieldCount) { + Assert.assertTrue(parameters.getExecutionStepInfo().getPath().isRootPath()); + initialCallStack.incrementObjectRunningCount(); + } + + @Override + public void finishedFetching(ExecutionContext executionContext, ExecutionStrategyParameters newParameters) { + CallStack callStack = getCallStack(newParameters); + decrementObjectRunningAndMaybeDispatch(callStack); + } + + @Override + public void executionSerialStrategy(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + callStack.clear(); + callStack.incrementObjectRunningCount(); + } + + @Override + public void newSubscriptionExecution(AlternativeCallContext alternativeCallContext) { + CallStack callStack = new CallStack(); + alternativeCallContextMap.put(alternativeCallContext, callStack); + callStack.incrementObjectRunningCount(); + } + + @Override + public void subscriptionEventCompletionDone(AlternativeCallContext alternativeCallContext) { + CallStack callStack = getCallStack(alternativeCallContext); + decrementObjectRunningAndMaybeDispatch(callStack); + } + + @Override + public void deferFieldFetched(ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + int deferredFragmentRootFieldsCompleted = callStack.deferredFragmentRootFieldsCompleted.incrementAndGet(); + Assert.assertNotNull(parameters.getDeferredCallContext()); + if (deferredFragmentRootFieldsCompleted == parameters.getDeferredCallContext().getFields()) { + decrementObjectRunningAndMaybeDispatch(callStack); + } + } + + @Override + public void startComplete(ExecutionStrategyParameters parameters) { + getCallStack(parameters).incrementObjectRunningCount(); + } + + @Override + public void stopComplete(ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + decrementObjectRunningAndMaybeDispatch(callStack); + } + + private CallStack getCallStack(ExecutionStrategyParameters parameters) { + return getCallStack(parameters.getDeferredCallContext()); + } + + private CallStack getCallStack(@Nullable AlternativeCallContext alternativeCallContext) { + if (alternativeCallContext == null) { + return this.initialCallStack; + } else { + return alternativeCallContextMap.computeIfAbsent(alternativeCallContext, k -> { + /* + This is only for handling deferred cases. Subscription cases will also get a new callStack, but + it is explicitly created in `newSubscriptionExecution`. + The reason we are doing this lazily is, because we don't have explicit startDeferred callback. + */ + CallStack callStack = new CallStack(); + callStack.incrementObjectRunningCount(); + return callStack; + }); + } + } + + + private void decrementObjectRunningAndMaybeDispatch(CallStack callStack) { + int newState = callStack.decrementObjectRunningCount(); + if (CallStack.getObjectRunningCount(newState) == 0 && CallStack.getDataLoaderToDispatch(newState) && !CallStack.getCurrentlyDispatching(newState)) { + dispatchImpl(callStack); + } + } + + private void newDataLoaderInvocationMaybeDispatch(CallStack callStack) { + int currentState; + while (true) { + int oldState = callStack.getState(); + if (CallStack.getDataLoaderToDispatch(oldState)) { + return; + } + int newState = CallStack.setDataLoaderToDispatch(oldState, true); + if (callStack.tryUpdateState(oldState, newState)) { + currentState = newState; + break; + } + } + + if (CallStack.getObjectRunningCount(currentState) == 0 && !CallStack.getCurrentlyDispatching(currentState)) { + dispatchImpl(callStack); + } + } + + + private void dispatchImpl(CallStack callStack) { + while (true) { + int oldState = callStack.getState(); + if (!CallStack.getDataLoaderToDispatch(oldState)) { + int newState = CallStack.setCurrentlyDispatching(oldState, false); + if (callStack.tryUpdateState(oldState, newState)) { + return; + } + } + int newState = CallStack.setCurrentlyDispatching(oldState, true); + newState = CallStack.setDataLoaderToDispatch(newState, false); + if (callStack.tryUpdateState(oldState, newState)) { + break; + } + } + + DataLoaderRegistry dataLoaderRegistry = executionContext.getDataLoaderRegistry(); + List> dataLoaders = dataLoaderRegistry.getDataLoaders(); + List>> allDispatchedCFs = new ArrayList<>(); + for (DataLoader dataLoader : dataLoaders) { + CompletableFuture> dispatch = dataLoader.dispatch(); + allDispatchedCFs.add(dispatch); + } + CompletableFuture.allOf(allDispatchedCFs.toArray(new CompletableFuture[0])) + .whenComplete((unused, throwable) -> { + dispatchImpl(callStack); + }); + + } + + + public void newDataLoaderInvocation(@Nullable AlternativeCallContext alternativeCallContext) { + CallStack callStack = getCallStack(alternativeCallContext); + newDataLoaderInvocationMaybeDispatch(callStack); + } + + +} + diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/FieldLevelTrackingApproach.java b/src/main/java/graphql/execution/instrumentation/dataloader/FieldLevelTrackingApproach.java deleted file mode 100644 index dcd4ec0a7c..0000000000 --- a/src/main/java/graphql/execution/instrumentation/dataloader/FieldLevelTrackingApproach.java +++ /dev/null @@ -1,255 +0,0 @@ -package graphql.execution.instrumentation.dataloader; - -import graphql.Assert; -import graphql.ExecutionResult; -import graphql.Internal; -import graphql.execution.ExecutionPath; -import graphql.execution.FieldValueInfo; -import graphql.execution.instrumentation.DeferredFieldInstrumentationContext; -import graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext; -import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.language.Field; -import org.dataloader.DataLoaderRegistry; -import org.slf4j.Logger; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletableFuture; - -/** - * This approach uses field level tracking to achieve its aims of making the data loader more efficient - */ -@Internal -public class FieldLevelTrackingApproach { - private final DataLoaderRegistry dataLoaderRegistry; - private final Logger log; - - private static class CallStack extends DataLoaderDispatcherInstrumentationState { - - private final Map expectedFetchCountPerLevel = new LinkedHashMap<>(); - private final Map fetchCountPerLevel = new LinkedHashMap<>(); - private final Map expectedStrategyCallsPerLevel = new LinkedHashMap<>(); - private final Map happenedStrategyCallsPerLevel = new LinkedHashMap<>(); - private final Map happenedOnFieldValueCallsPerLevel = new LinkedHashMap<>(); - - - private final Set dispatchedLevels = new LinkedHashSet<>(); - - private int deferredRootLevel; - - CallStack() { - expectedStrategyCallsPerLevel.put(1, 1); - } - - - synchronized int increaseExpectedFetchCount(int level, int count) { - expectedFetchCountPerLevel.put(level, expectedFetchCountPerLevel.getOrDefault(level, 0) + count); - return expectedFetchCountPerLevel.get(level); - } - - synchronized void increaseFetchCount(int level) { - fetchCountPerLevel.put(level, fetchCountPerLevel.getOrDefault(level, 0) + 1); - } - - synchronized void increaseExpectedStrategyCalls(int level, int count) { - expectedStrategyCallsPerLevel.put(level, expectedStrategyCallsPerLevel.getOrDefault(level, 0) + count); - } - - synchronized void increaseHappenedStrategyCalls(int level) { - happenedStrategyCallsPerLevel.put(level, happenedStrategyCallsPerLevel.getOrDefault(level, 0) + 1); - } - - synchronized void increaseHappenedOnFieldValueCalls(int level) { - happenedOnFieldValueCallsPerLevel.put(level, happenedOnFieldValueCallsPerLevel.getOrDefault(level, 0) + 1); - } - - synchronized boolean allStrategyCallsHappened(int level) { - return Objects.equals(happenedStrategyCallsPerLevel.get(level), expectedStrategyCallsPerLevel.get(level)); - } - - synchronized boolean allOnFieldCallsHappened(int level) { - return Objects.equals(happenedOnFieldValueCallsPerLevel.get(level), expectedStrategyCallsPerLevel.get(level)); - } - - synchronized boolean allFetchsHappened(int level) { - return Objects.equals(fetchCountPerLevel.get(level), expectedFetchCountPerLevel.get(level)); - } - - @Override - public String toString() { - return "CallStack{" + - "expectedFetchCountPerLevel=" + expectedFetchCountPerLevel + - ", fetchCountPerLevel=" + fetchCountPerLevel + - ", expectedStrategyCallsPerLevel=" + expectedStrategyCallsPerLevel + - ", happenedStrategyCallsPerLevel=" + happenedStrategyCallsPerLevel + - ", happenedOnFieldValueCallsPerLevel=" + happenedOnFieldValueCallsPerLevel + - ", dispatchedLevels" + dispatchedLevels + - '}'; - } - - public synchronized void dispatchIfNotDispatchedBefore(int level, Runnable dispatch) { - if (dispatchedLevels.contains(level)) { - Assert.assertShouldNeverHappen("level " + level + " already dispatched"); - return; - } - dispatchedLevels.add(level); - dispatch.run(); - } - - public void clearAndMarkCurrentLevelAsReady(int level) { - expectedFetchCountPerLevel.clear(); - fetchCountPerLevel.clear(); - expectedStrategyCallsPerLevel.clear(); - happenedStrategyCallsPerLevel.clear(); - happenedOnFieldValueCallsPerLevel.clear(); - dispatchedLevels.clear(); - - // make sure the level is ready - expectedFetchCountPerLevel.put(level, 1); - expectedStrategyCallsPerLevel.put(level, 1); - happenedStrategyCallsPerLevel.put(level, 1); - } - } - - public FieldLevelTrackingApproach(Logger log, DataLoaderRegistry dataLoaderRegistry) { - this.dataLoaderRegistry = dataLoaderRegistry; - this.log = log; - } - - public InstrumentationState createState() { - return new CallStack(); - } - - ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { - CallStack callStack = parameters.getInstrumentationState(); - ExecutionPath path = parameters.getExecutionStrategyParameters().getPath(); - int parentLevel = path.getLevel(); - int curLevel = parentLevel + 1; - int fieldCount = parameters.getExecutionStrategyParameters().getFields().size(); - callStack.increaseExpectedFetchCount(curLevel, fieldCount); - callStack.increaseHappenedStrategyCalls(curLevel); - - return new ExecutionStrategyInstrumentationContext() { - @Override - public void onDispatched(CompletableFuture result) { - - } - - @Override - public void onCompleted(ExecutionResult result, Throwable t) { - - } - - @Override - public void onFieldValuesInfo(List fieldValueInfoList) { - handleOnFieldValuesInfo(fieldValueInfoList, callStack, curLevel); - } - - @Override - public void onDeferredField(List field) { - // fake fetch count for this field - callStack.increaseFetchCount(curLevel); - dispatchIfNeeded(callStack, curLevel); - } - }; - } - - private void handleOnFieldValuesInfo(List fieldValueInfoList, CallStack callStack, int curLevel) { - callStack.increaseHappenedOnFieldValueCalls(curLevel); - int expectedStrategyCalls = 0; - for (FieldValueInfo fieldValueInfo : fieldValueInfoList) { - if (fieldValueInfo.getCompleteValueType() == FieldValueInfo.CompleteValueType.OBJECT) { - expectedStrategyCalls++; - } else if (fieldValueInfo.getCompleteValueType() == FieldValueInfo.CompleteValueType.LIST) { - expectedStrategyCalls += getCountForList(fieldValueInfo); - } - } - callStack.increaseExpectedStrategyCalls(curLevel + 1, expectedStrategyCalls); - dispatchIfNeeded(callStack, curLevel + 1); - } - - private int getCountForList(FieldValueInfo fieldValueInfo) { - int result = 0; - for (FieldValueInfo cvi : fieldValueInfo.getFieldValueInfos()) { - if (cvi.getCompleteValueType() == FieldValueInfo.CompleteValueType.OBJECT) { - result++; - } else if (cvi.getCompleteValueType() == FieldValueInfo.CompleteValueType.LIST) { - result += getCountForList(cvi); - } - } - return result; - } - - DeferredFieldInstrumentationContext beginDeferredField(InstrumentationDeferredFieldParameters parameters) { - CallStack callStack = parameters.getInstrumentationState(); - int level = parameters.getExecutionStrategyParameters().getPath().getLevel(); - callStack.clearAndMarkCurrentLevelAsReady(level); - - return new DeferredFieldInstrumentationContext() { - @Override - public void onDispatched(CompletableFuture result) { - - } - - @Override - public void onCompleted(ExecutionResult result, Throwable t) { - } - - @Override - public void onFieldValueInfo(FieldValueInfo fieldValueInfo) { - handleOnFieldValuesInfo(Collections.singletonList(fieldValueInfo), callStack, level); - } - }; - } - - public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - CallStack callStack = parameters.getInstrumentationState(); - ExecutionPath path = parameters.getEnvironment().getFieldTypeInfo().getPath(); - int level = path.getLevel(); - return new InstrumentationContext() { - - @Override - public void onDispatched(CompletableFuture result) { - callStack.increaseFetchCount(level); - dispatchIfNeeded(callStack, level); - } - - @Override - public void onCompleted(Object result, Throwable t) { - } - }; - } - - - private void dispatchIfNeeded(CallStack callStack, int level) { - if (levelReady(callStack, level)) { - callStack.dispatchIfNotDispatchedBefore(level, this::dispatch); - } - } - - private boolean levelReady(CallStack callStack, int level) { - if (level == 1) { - // level 1 is special: there is only one strategy call and that's it - return callStack.allFetchsHappened(1); - } - if (levelReady(callStack, level - 1) && callStack.allOnFieldCallsHappened(level - 1) - && callStack.allStrategyCallsHappened(level) && callStack.allFetchsHappened(level)) { - return true; - } - return false; - } - - void dispatch() { - log.debug("Dispatching data loaders ({})", dataLoaderRegistry.getKeys()); - dataLoaderRegistry.dispatchAll(); - } -} diff --git a/src/main/java/graphql/execution/instrumentation/dataloader/PerLevelDataLoaderDispatchStrategy.java b/src/main/java/graphql/execution/instrumentation/dataloader/PerLevelDataLoaderDispatchStrategy.java new file mode 100644 index 0000000000..e6bfc3f740 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/dataloader/PerLevelDataLoaderDispatchStrategy.java @@ -0,0 +1,516 @@ +package graphql.execution.instrumentation.dataloader; + +import graphql.Assert; +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.Profiler; +import graphql.execution.DataLoaderDispatchStrategy; +import graphql.execution.ExecutionContext; +import graphql.execution.ExecutionStrategyParameters; +import graphql.execution.FieldValueInfo; +import graphql.execution.incremental.AlternativeCallContext; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; + +@Internal +@NullMarked +public class PerLevelDataLoaderDispatchStrategy implements DataLoaderDispatchStrategy { + + private final CallStack initialCallStack; + private final ExecutionContext executionContext; + private final boolean enableDataLoaderChaining; + + + private final Profiler profiler; + + private final Map alternativeCallContextMap = new ConcurrentHashMap<>(); + + private static class ChainedDLStack { + + private final Map> stateMapPerLevel = new ConcurrentHashMap<>(); + + // a state for level points to a previous one + // all the invocations that are linked together are the relevant invocations for the next dispatch + private static class StateForLevel { + final @Nullable DataLoader dataLoader; + final boolean dispatchingStarted; + final boolean dispatchingFinished; + final boolean currentlyDelayedDispatching; + final @Nullable StateForLevel prev; + + public StateForLevel(@Nullable DataLoader dataLoader, + boolean dispatchingStarted, + boolean dispatchingFinished, + boolean currentlyDelayedDispatching, + @Nullable StateForLevel prev) { + this.dataLoader = dataLoader; + this.dispatchingStarted = dispatchingStarted; + this.dispatchingFinished = dispatchingFinished; + this.currentlyDelayedDispatching = currentlyDelayedDispatching; + this.prev = prev; + } + } + + + public @Nullable StateForLevel aboutToStartDispatching(int level, boolean normalDispatchOrDelayed, boolean chained) { + AtomicReference<@Nullable StateForLevel> currentStateRef = stateMapPerLevel.computeIfAbsent(level, __ -> new AtomicReference<>()); + while (true) { + StateForLevel currentState = currentStateRef.get(); + + + boolean dispatchingStarted = false; + boolean dispatchingFinished = false; + boolean currentlyDelayedDispatching = false; + + if (currentState != null) { + dispatchingStarted = currentState.dispatchingStarted; + dispatchingFinished = currentState.dispatchingFinished; + currentlyDelayedDispatching = currentState.currentlyDelayedDispatching; + + } + + if (!chained) { + if (normalDispatchOrDelayed) { + dispatchingStarted = true; + } else { + currentlyDelayedDispatching = true; + } + } + + if (currentState == null || currentState.dataLoader == null) { + if (normalDispatchOrDelayed) { + dispatchingFinished = true; + } else { + currentlyDelayedDispatching = false; + } + } + + StateForLevel newState = new StateForLevel(null, dispatchingStarted, dispatchingFinished, currentlyDelayedDispatching, null); + + if (currentStateRef.compareAndSet(currentState, newState)) { + return currentState; + } + } + } + + + public boolean newDataLoaderInvocation(int level, DataLoader dataLoader) { + AtomicReference<@Nullable StateForLevel> currentStateRef = stateMapPerLevel.computeIfAbsent(level, __ -> new AtomicReference<>()); + while (true) { + StateForLevel currentState = currentStateRef.get(); + + boolean dispatchingStarted = false; + boolean dispatchingFinished = false; + boolean currentlyDelayedDispatching = false; + + if (currentState != null) { + dispatchingStarted = currentState.dispatchingStarted; + dispatchingFinished = currentState.dispatchingFinished; + currentlyDelayedDispatching = currentState.currentlyDelayedDispatching; + + } + + // we need to start a new delayed dispatching if + // the normal dispatching is finished and there is no currently delayed dispatching for this level + boolean newDelayedInvocation = dispatchingFinished && !currentlyDelayedDispatching; + if (newDelayedInvocation) { + currentlyDelayedDispatching = true; + } + + StateForLevel newState = new StateForLevel(dataLoader, dispatchingStarted, dispatchingFinished, currentlyDelayedDispatching, currentState); + + if (currentStateRef.compareAndSet(currentState, newState)) { + return newDelayedInvocation; + } + } + } + + public void clear() { + stateMapPerLevel.clear(); + } + + } + + private static class CallStack { + + /** + * We track three things per level: + * - the number of execute object calls + * - the number of object completion calls + * - if the level is already dispatched + *

+ * The number of execute object calls is the number of times the execution + * of a field with sub selection (meaning it is an object) started. + *

+ * For each execute object call there will be one matching object completion call, + * indicating that the all fields in the sub selection have been fetched AND completed. + * Completion implies the fetched value is "resolved" (CompletableFuture is completed if it was a CF) + * and it the engine has processed it and called any needed subsequent execute object calls (if the result + * was none null and of Object of [Object] (or [[Object]] etc). + *

+ * Together we know a that a level is ready for dispatch if: + * - the parent was dispatched + * - the #executeObject == #completionFinished in the grandparent level. + *

+ * The second condition implies that all execute object calls in the parent level happened + * which again implies that all fetch fields in the current level have happened. + *

+ * For the first level we track only if all expected fetched field calls have happened. + */ + + /** + * The whole algo is impleted lock free and relies purely on CAS methods to handle concurrency. + */ + + static class StateForLevel { + private final int happenedCompletionFinishedCount; + private final int happenedExecuteObjectCalls; + + + public StateForLevel() { + this.happenedCompletionFinishedCount = 0; + this.happenedExecuteObjectCalls = 0; + } + + public StateForLevel(int happenedCompletionFinishedCount, int happenedExecuteObjectCalls) { + this.happenedCompletionFinishedCount = happenedCompletionFinishedCount; + this.happenedExecuteObjectCalls = happenedExecuteObjectCalls; + } + + public StateForLevel(StateForLevel other) { + this.happenedCompletionFinishedCount = other.happenedCompletionFinishedCount; + this.happenedExecuteObjectCalls = other.happenedExecuteObjectCalls; + } + + public StateForLevel copy() { + return new StateForLevel(this); + } + + public StateForLevel increaseHappenedCompletionFinishedCount() { + return new StateForLevel(happenedCompletionFinishedCount + 1, happenedExecuteObjectCalls); + } + + public StateForLevel increaseHappenedExecuteObjectCalls() { + return new StateForLevel(happenedCompletionFinishedCount, happenedExecuteObjectCalls + 1); + } + + } + + private volatile int expectedFirstLevelFetchCount; + private final AtomicInteger happenedFirstLevelFetchCount = new AtomicInteger(); + + + private final Map> stateForLevelMap = new ConcurrentHashMap<>(); + + private final Set dispatchedLevels = ConcurrentHashMap.newKeySet(); + + public ChainedDLStack chainedDLStack = new ChainedDLStack(); + + private final AtomicInteger deferredFragmentRootFieldsCompleted = new AtomicInteger(); + + public CallStack() { + } + + + public StateForLevel get(int level) { + AtomicReference dataPerLevelAtomicReference = stateForLevelMap.computeIfAbsent(level, __ -> new AtomicReference<>(new StateForLevel())); + return Assert.assertNotNull(dataPerLevelAtomicReference.get()); + } + + public boolean tryUpdateLevel(int level, StateForLevel oldData, StateForLevel newData) { + AtomicReference dataPerLevelAtomicReference = Assert.assertNotNull(stateForLevelMap.get(level)); + return dataPerLevelAtomicReference.compareAndSet(oldData, newData); + } + + + public void clear() { + dispatchedLevels.clear(); + stateForLevelMap.clear(); + expectedFirstLevelFetchCount = 0; + happenedFirstLevelFetchCount.set(0); + deferredFragmentRootFieldsCompleted.set(0); + chainedDLStack.clear(); + } + } + + public PerLevelDataLoaderDispatchStrategy(ExecutionContext executionContext) { + this.initialCallStack = new CallStack(); + this.executionContext = executionContext; + + GraphQLContext graphQLContext = executionContext.getGraphQLContext(); + + this.enableDataLoaderChaining = graphQLContext.getBoolean(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, false); + this.profiler = executionContext.getProfiler(); + } + + + @Override + public void executionStrategy(ExecutionContext executionContext, ExecutionStrategyParameters parameters, int fieldCount) { + Assert.assertTrue(parameters.getExecutionStepInfo().getPath().isRootPath()); + // no concurrency access happening + CallStack.StateForLevel currentState = initialCallStack.get(0); + initialCallStack.tryUpdateLevel(0, currentState, new CallStack.StateForLevel(0, 1)); + initialCallStack.expectedFirstLevelFetchCount = fieldCount; + } + + @Override + public void executionSerialStrategy(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + callStack.clear(); + CallStack.StateForLevel currentState = initialCallStack.get(0); + initialCallStack.tryUpdateLevel(0, currentState, new CallStack.StateForLevel(0, 1)); + // field count is always 1 for serial execution + initialCallStack.expectedFirstLevelFetchCount = 1; + } + + @Override + public void executionStrategyOnFieldValuesInfo(List fieldValueInfoList, ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + onCompletionFinished(0, callStack); + + } + + @Override + public void executionStrategyOnFieldValuesException(Throwable t, ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + onCompletionFinished(0, callStack); + } + + + @Override + public void executeObject(ExecutionContext executionContext, ExecutionStrategyParameters parameters, int fieldCount) { + CallStack callStack = getCallStack(parameters); + int curLevel = parameters.getPath().getLevel(); + while (true) { + CallStack.StateForLevel currentState = callStack.get(curLevel); + if (callStack.tryUpdateLevel(curLevel, currentState, currentState.increaseHappenedExecuteObjectCalls())) { + return; + } + } + } + + @Override + public void executeObjectOnFieldValuesInfo(List fieldValueInfoList, ExecutionStrategyParameters parameters) { + int curLevel = parameters.getPath().getLevel(); + CallStack callStack = getCallStack(parameters); + onCompletionFinished(curLevel, callStack); + } + + @Override + public void executeObjectOnFieldValuesException(Throwable t, ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + int curLevel = parameters.getPath().getLevel(); + onCompletionFinished(curLevel, callStack); + } + + + private void onCompletionFinished(int level, CallStack callStack) { + while (true) { + CallStack.StateForLevel currentState = callStack.get(level); + if (callStack.tryUpdateLevel(level, currentState, currentState.increaseHappenedCompletionFinishedCount())) { + break; + } + } + + // due to synchronous DataFetcher the completion calls on higher levels + // can happen before the completion calls on lower level + // this means sometimes a lower level completion means multiple levels are ready + // hence this loop here until a level is not ready or already dispatched + int currentLevel = level + 2; + while (true) { + boolean levelReady; + if (callStack.dispatchedLevels.contains(currentLevel)) { + break; + } + levelReady = markLevelAsDispatchedIfReady(currentLevel, callStack); + if (levelReady) { + dispatch(currentLevel, callStack); + } else { + break; + } + currentLevel++; + } + + } + + + @Override + public void fieldFetched(ExecutionContext executionContext, + ExecutionStrategyParameters executionStrategyParameters, + DataFetcher dataFetcher, + Object fetchedValue, + Supplier dataFetchingEnvironment) { + CallStack callStack = getCallStack(executionStrategyParameters); + int level = executionStrategyParameters.getPath().getLevel(); + AlternativeCallContext deferredCallContext = executionStrategyParameters.getDeferredCallContext(); + if (level == 1 || (deferredCallContext != null && level == deferredCallContext.getStartLevel())) { + int happenedFirstLevelFetchCount = callStack.happenedFirstLevelFetchCount.incrementAndGet(); + if (happenedFirstLevelFetchCount == callStack.expectedFirstLevelFetchCount) { + callStack.dispatchedLevels.add(level); + dispatch(level, callStack); + } + } + } + + + @Override + public void newSubscriptionExecution(AlternativeCallContext alternativeCallContext) { + CallStack callStack = new CallStack(); + alternativeCallContextMap.put(alternativeCallContext, callStack); + + } + + @Override + public void subscriptionEventCompletionDone(AlternativeCallContext alternativeCallContext) { + CallStack callStack = getCallStack(alternativeCallContext); + // this means the single root field is completed (it was never "fetched" because it is + // the event payload) and we can mark level 1 (root fields) as dispatched and level 0 as completed + callStack.dispatchedLevels.add(1); + while (true) { + CallStack.StateForLevel currentState = callStack.get(0); + if (callStack.tryUpdateLevel(0, currentState, currentState.increaseHappenedExecuteObjectCalls())) { + break; + } + } + onCompletionFinished(0, callStack); + } + + @Override + public void deferredOnFieldValue(String resultKey, FieldValueInfo fieldValueInfo, Throwable throwable, ExecutionStrategyParameters parameters) { + CallStack callStack = getCallStack(parameters); + int deferredFragmentRootFieldsCompleted = callStack.deferredFragmentRootFieldsCompleted.incrementAndGet(); + Assert.assertNotNull(parameters.getDeferredCallContext()); + if (deferredFragmentRootFieldsCompleted == parameters.getDeferredCallContext().getFields()) { + onCompletionFinished(parameters.getDeferredCallContext().getStartLevel() - 1, callStack); + } + + } + + + private CallStack getCallStack(ExecutionStrategyParameters parameters) { + return getCallStack(parameters.getDeferredCallContext()); + } + + private CallStack getCallStack(@Nullable AlternativeCallContext alternativeCallContext) { + if (alternativeCallContext == null) { + return this.initialCallStack; + } else { + return alternativeCallContextMap.computeIfAbsent(alternativeCallContext, k -> { + /* + This is only for handling deferred cases. Subscription cases will also get a new callStack, but + it is explicitly created in `newSubscriptionExecution`. + The reason we are doing this lazily is, because we don't have explicit startDeferred callback. + */ + CallStack callStack = new CallStack(); + // on which level the fields are + int startLevel = k.getStartLevel(); + // how many fields are deferred on this level + int fields = k.getFields(); + if (startLevel > 1) { + // parent level is considered dispatched and all fields completed (meaning the grandparent level has all object completion call happened) + callStack.dispatchedLevels.add(startLevel - 1); + CallStack.StateForLevel stateForLevel = callStack.get(startLevel - 2); + CallStack.StateForLevel newStateForLevel = stateForLevel.increaseHappenedExecuteObjectCalls().increaseHappenedCompletionFinishedCount(); + callStack.tryUpdateLevel(startLevel - 2, stateForLevel, newStateForLevel); + } + // the parent will have one completion therefore we set the expectation to 1 + CallStack.StateForLevel stateForLevel = callStack.get(startLevel - 1); + callStack.tryUpdateLevel(startLevel - 1, stateForLevel, stateForLevel.increaseHappenedExecuteObjectCalls()); + + // for the current level we set the fetch expectations + callStack.expectedFirstLevelFetchCount = fields; + return callStack; + }); + } + } + + + private boolean markLevelAsDispatchedIfReady(int level, CallStack callStack) { + boolean ready = isLevelReady(level, callStack); + if (ready) { + if (!callStack.dispatchedLevels.add(level)) { + // meaning another thread came before us, so they will take care of dispatching + return false; + } + return true; + } + return false; + } + + + private boolean isLevelReady(int level, CallStack callStack) { + Assert.assertTrue(level > 1); + // we expect that parent has been dispatched and that all parents fields are completed + // all parent fields completed means all parent parent on completions finished calls must have happened + int happenedExecuteObjectCalls = callStack.get(level - 2).happenedExecuteObjectCalls; + return callStack.dispatchedLevels.contains(level - 1) && + happenedExecuteObjectCalls > 0 && happenedExecuteObjectCalls == callStack.get(level - 2).happenedCompletionFinishedCount; + + } + + void dispatch(int level, CallStack callStack) { + if (!enableDataLoaderChaining) { + profiler.oldStrategyDispatchingAll(level); + DataLoaderRegistry dataLoaderRegistry = executionContext.getDataLoaderRegistry(); + dispatchAll(dataLoaderRegistry, level); + return; + } + dispatchDLCFImpl(level, callStack, true, false); + } + + private void dispatchAll(DataLoaderRegistry dataLoaderRegistry, int level) { + dataLoaderRegistry.dispatchAll(); + } + + private void dispatchDLCFImpl(Integer level, CallStack callStack, boolean normalOrDelayed, boolean chained) { + + ChainedDLStack.StateForLevel stateForLevel = callStack.chainedDLStack.aboutToStartDispatching(level, normalOrDelayed, chained); + if (stateForLevel == null || stateForLevel.dataLoader == null) { + return; + } + + List allDispatchedCFs = new ArrayList<>(); + while (stateForLevel != null && stateForLevel.dataLoader != null) { + CompletableFuture dispatch = stateForLevel.dataLoader.dispatch(); + allDispatchedCFs.add(dispatch); + stateForLevel = stateForLevel.prev; + } + CompletableFuture.allOf(allDispatchedCFs.toArray(new CompletableFuture[0])) + .whenComplete((unused, throwable) -> { + dispatchDLCFImpl(level, callStack, normalOrDelayed, true); + } + ); + + } + + + public void newDataLoaderInvocation(int level, + DataLoader dataLoader, + @Nullable AlternativeCallContext alternativeCallContext) { + if (!enableDataLoaderChaining) { + return; + } + CallStack callStack = getCallStack(alternativeCallContext); + boolean newDelayedInvocation = callStack.chainedDLStack.newDataLoaderInvocation(level, dataLoader); + if (newDelayedInvocation) { + dispatchDLCFImpl(level, callStack, false, false); + } + } + + +} + diff --git a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldAndArguments.java b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldAndArguments.java index 912314a04a..3ad6bc3e9c 100644 --- a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldAndArguments.java +++ b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldAndArguments.java @@ -1,7 +1,7 @@ package graphql.execution.instrumentation.fieldvalidation; import graphql.PublicApi; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import graphql.language.Field; import graphql.schema.GraphQLCompositeType; import graphql.schema.GraphQLFieldDefinition; @@ -37,7 +37,7 @@ public interface FieldAndArguments { /** * @return the path to this field */ - ExecutionPath getPath(); + ResultPath getPath(); /** * This will be a map of argument names to argument values. This will contain any variables transferred diff --git a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationEnvironment.java b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationEnvironment.java index 2e2998221b..047c3e7831 100644 --- a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationEnvironment.java +++ b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationEnvironment.java @@ -3,7 +3,7 @@ import graphql.GraphQLError; import graphql.PublicApi; import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import java.util.List; import java.util.Map; @@ -36,7 +36,7 @@ public interface FieldValidationEnvironment { /** * @return a map of field paths to {@link FieldAndArguments} */ - Map> getFieldsByPath(); + Map> getFieldsByPath(); /** * This helper method allows you to make error messages to be passed back out in case of validation failure. Note you diff --git a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationInstrumentation.java b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationInstrumentation.java index 19fa513628..408fd261be 100644 --- a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationInstrumentation.java +++ b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationInstrumentation.java @@ -5,8 +5,10 @@ import graphql.PublicApi; import graphql.execution.AbortExecutionException; import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.SimpleInstrumentation; +import graphql.execution.instrumentation.InstrumentationState; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters; +import org.jspecify.annotations.Nullable; import java.util.List; @@ -22,7 +24,7 @@ * @see FieldValidation */ @PublicApi -public class FieldValidationInstrumentation extends SimpleInstrumentation { +public class FieldValidationInstrumentation extends SimplePerformantInstrumentation { private final FieldValidation fieldValidation; @@ -36,12 +38,11 @@ public FieldValidationInstrumentation(FieldValidation fieldValidation) { } @Override - public InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) { - + public @Nullable InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { List errors = FieldValidationSupport.validateFieldsAndArguments(fieldValidation, parameters.getExecutionContext()); if (errors != null && !errors.isEmpty()) { throw new AbortExecutionException(errors); } - return super.beginExecuteOperation(parameters); + return super.beginExecuteOperation(parameters, state); } } diff --git a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationSupport.java b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationSupport.java index d17c027e96..454fb30677 100644 --- a/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationSupport.java +++ b/src/main/java/graphql/execution/instrumentation/fieldvalidation/FieldValidationSupport.java @@ -1,13 +1,15 @@ package graphql.execution.instrumentation.fieldvalidation; +import com.google.common.collect.ImmutableList; import graphql.ErrorType; import graphql.GraphQLError; import graphql.Internal; -import graphql.analysis.QueryTraversal; +import graphql.analysis.QueryTraverser; import graphql.analysis.QueryVisitorFieldEnvironment; import graphql.analysis.QueryVisitorStub; +import graphql.collect.ImmutableKit; import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import graphql.language.Field; import graphql.language.SourceLocation; import graphql.schema.GraphQLCompositeType; @@ -20,23 +22,22 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; @Internal class FieldValidationSupport { static List validateFieldsAndArguments(FieldValidation fieldValidation, ExecutionContext executionContext) { - Map> fieldArgumentsMap = new LinkedHashMap<>(); + Map> fieldArgumentsMap = new LinkedHashMap<>(); - QueryTraversal queryTraversal = QueryTraversal.newQueryTraversal() + QueryTraverser queryTraverser = QueryTraverser.newQueryTraverser() .schema(executionContext.getGraphQLSchema()) .document(executionContext.getDocument()) .operationName(executionContext.getOperationDefinition().getName()) - .variables(executionContext.getVariables()) + .coercedVariables(executionContext.getCoercedVariables()) .build(); - queryTraversal.visitPreOrder(new QueryVisitorStub() { + queryTraverser.visitPreOrder(new QueryVisitorStub() { @Override public void visitField(QueryVisitorFieldEnvironment env) { Field field = env.getField(); @@ -45,7 +46,7 @@ public void visitField(QueryVisitorFieldEnvironment env) { // only fields that have arguments make any sense to placed in play // since only they have variable input FieldAndArguments fieldArguments = new FieldAndArgumentsImpl(env); - ExecutionPath path = fieldArguments.getPath(); + ResultPath path = fieldArguments.getPath(); List list = fieldArgumentsMap.getOrDefault(path, new ArrayList<>()); list.add(fieldArguments); fieldArgumentsMap.put(path, list); @@ -62,7 +63,7 @@ public void visitField(QueryVisitorFieldEnvironment env) { private static class FieldAndArgumentsImpl implements FieldAndArguments { private final QueryVisitorFieldEnvironment traversalEnv; private final FieldAndArguments parentArgs; - private final ExecutionPath path; + private final ResultPath path; FieldAndArgumentsImpl(QueryVisitorFieldEnvironment traversalEnv) { this.traversalEnv = traversalEnv; @@ -74,10 +75,10 @@ private FieldAndArguments mkParentArgs(QueryVisitorFieldEnvironment traversalEnv return traversalEnv.getParentEnvironment() != null ? new FieldAndArgumentsImpl(traversalEnv.getParentEnvironment()) : null; } - private ExecutionPath mkPath(QueryVisitorFieldEnvironment traversalEnv) { + private ResultPath mkPath(QueryVisitorFieldEnvironment traversalEnv) { QueryVisitorFieldEnvironment parentEnvironment = traversalEnv.getParentEnvironment(); if (parentEnvironment == null) { - return ExecutionPath.rootPath().segment(traversalEnv.getField().getName()); + return ResultPath.rootPath().segment(traversalEnv.getField().getName()); } else { Deque stack = new ArrayDeque<>(); stack.push(traversalEnv); @@ -85,7 +86,7 @@ private ExecutionPath mkPath(QueryVisitorFieldEnvironment traversalEnv) { stack.push(parentEnvironment); parentEnvironment = parentEnvironment.getParentEnvironment(); } - ExecutionPath path = ExecutionPath.rootPath(); + ResultPath path = ResultPath.rootPath(); while (!stack.isEmpty()) { QueryVisitorFieldEnvironment environment = stack.pop(); path = path.segment(environment.getField().getName()); @@ -110,7 +111,7 @@ public GraphQLCompositeType getParentType() { } @Override - public ExecutionPath getPath() { + public ResultPath getPath() { return path; } @@ -134,13 +135,13 @@ public FieldAndArguments getParentFieldAndArguments() { private static class FieldValidationEnvironmentImpl implements FieldValidationEnvironment { private final ExecutionContext executionContext; - private final Map> fieldArgumentsMap; - private final List fieldArguments; + private final Map> fieldArgumentsMap; + private final ImmutableList fieldArguments; - FieldValidationEnvironmentImpl(ExecutionContext executionContext, Map> fieldArgumentsMap) { + FieldValidationEnvironmentImpl(ExecutionContext executionContext, Map> fieldArgumentsMap) { this.executionContext = executionContext; this.fieldArgumentsMap = fieldArgumentsMap; - this.fieldArguments = fieldArgumentsMap.values().stream().flatMap(List::stream).collect(Collectors.toList()); + this.fieldArguments = ImmutableKit.flatMapList(fieldArgumentsMap.values()); } @@ -155,7 +156,7 @@ public List getFields() { } @Override - public Map> getFieldsByPath() { + public Map> getFieldsByPath() { return fieldArgumentsMap; } @@ -175,7 +176,7 @@ private static class FieldAndArgError implements GraphQLError { private final List locations; private final List path; - FieldAndArgError(String message, Field field, ExecutionPath path) { + FieldAndArgError(String message, Field field, ResultPath path) { this.message = message; this.locations = field == null ? null : Collections.singletonList(field.getSourceLocation()); this.path = path == null ? null : path.toList(); diff --git a/src/main/java/graphql/execution/instrumentation/fieldvalidation/SimpleFieldValidation.java b/src/main/java/graphql/execution/instrumentation/fieldvalidation/SimpleFieldValidation.java index 47b0e42def..9f0a340f19 100644 --- a/src/main/java/graphql/execution/instrumentation/fieldvalidation/SimpleFieldValidation.java +++ b/src/main/java/graphql/execution/instrumentation/fieldvalidation/SimpleFieldValidation.java @@ -1,8 +1,9 @@ package graphql.execution.instrumentation.fieldvalidation; +import com.google.common.collect.ImmutableList; import graphql.GraphQLError; import graphql.PublicApi; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -15,13 +16,13 @@ * This very simple field validation will run the supplied function for a given field path and if it returns an error * it will be added to the list of problems. * - * Use {@link #addRule(graphql.execution.ExecutionPath, java.util.function.BiFunction)} to supply the rule callbacks where + * Use {@link #addRule(ResultPath, java.util.function.BiFunction)} to supply the rule callbacks where * you implement your specific business logic */ @PublicApi public class SimpleFieldValidation implements FieldValidation { - private final Map>> rules = new LinkedHashMap<>(); + private final Map>> rules = new LinkedHashMap<>(); /** * Adds the rule against the field address path. If the rule returns an error, it will be added to the list of errors @@ -31,7 +32,7 @@ public class SimpleFieldValidation implements FieldValidation { * * @return this validator */ - public SimpleFieldValidation addRule(ExecutionPath fieldPath, BiFunction> rule) { + public SimpleFieldValidation addRule(ResultPath fieldPath, BiFunction> rule) { rules.put(fieldPath, rule); return this; } @@ -39,17 +40,18 @@ public SimpleFieldValidation addRule(ExecutionPath fieldPath, BiFunction validateFields(FieldValidationEnvironment validationEnvironment) { List errors = new ArrayList<>(); - for (ExecutionPath fieldPath : rules.keySet()) { + for (Map.Entry>> entry : rules.entrySet()) { + ResultPath fieldPath = entry.getKey(); + BiFunction> ruleFunction = entry.getValue(); + List fieldAndArguments = validationEnvironment.getFieldsByPath().get(fieldPath); if (fieldAndArguments != null) { - BiFunction> ruleFunction = rules.get(fieldPath); - for (FieldAndArguments fieldAndArgument : fieldAndArguments) { Optional graphQLError = ruleFunction.apply(fieldAndArgument, validationEnvironment); graphQLError.ifPresent(errors::add); } } } - return errors; + return ImmutableList.copyOf(errors); } } diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationCreateStateParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationCreateStateParameters.java new file mode 100644 index 0000000000..da07ee2669 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationCreateStateParameters.java @@ -0,0 +1,27 @@ +package graphql.execution.instrumentation.parameters; + +import graphql.ExecutionInput; +import graphql.PublicApi; +import graphql.schema.GraphQLSchema; + +/** + * Parameters sent to {@link graphql.execution.instrumentation.Instrumentation} methods + */ +@PublicApi +public class InstrumentationCreateStateParameters { + private final GraphQLSchema schema; + private final ExecutionInput executionInput; + + public InstrumentationCreateStateParameters(GraphQLSchema schema, ExecutionInput executionInput) { + this.schema = schema; + this.executionInput = executionInput; + } + + public GraphQLSchema getSchema() { + return schema; + } + + public ExecutionInput getExecutionInput() { + return executionInput; + } +} diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationDeferredFieldParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationDeferredFieldParameters.java deleted file mode 100644 index 84afeea425..0000000000 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationDeferredFieldParameters.java +++ /dev/null @@ -1,41 +0,0 @@ -package graphql.execution.instrumentation.parameters; - -import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionStrategyParameters; -import graphql.execution.ExecutionTypeInfo; -import graphql.execution.instrumentation.InstrumentationState; -import graphql.schema.GraphQLFieldDefinition; - -/** - * Parameters sent to {@link graphql.execution.instrumentation.Instrumentation} methods - */ -public class InstrumentationDeferredFieldParameters extends InstrumentationFieldParameters { - - private final ExecutionStrategyParameters executionStrategyParameters; - - public InstrumentationDeferredFieldParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, GraphQLFieldDefinition fieldDef, ExecutionTypeInfo typeInfo) { - this(executionContext, executionStrategyParameters, fieldDef, typeInfo, executionContext.getInstrumentationState()); - } - - InstrumentationDeferredFieldParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, GraphQLFieldDefinition fieldDef, ExecutionTypeInfo typeInfo, InstrumentationState instrumentationState) { - super(executionContext,fieldDef,typeInfo,instrumentationState); - this.executionStrategyParameters = executionStrategyParameters; - } - - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - @Override - public InstrumentationDeferredFieldParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationDeferredFieldParameters( - this.getExecutionContext(), this.executionStrategyParameters, this.getField(), this.getTypeInfo(), instrumentationState); - } - - public ExecutionStrategyParameters getExecutionStrategyParameters() { - return executionStrategyParameters; - } -} diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecuteOperationParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecuteOperationParameters.java index f7b628a85a..69587f3f44 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecuteOperationParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecuteOperationParameters.java @@ -1,43 +1,23 @@ package graphql.execution.instrumentation.parameters; +import graphql.PublicApi; import graphql.execution.ExecutionContext; import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationState; /** * Parameters sent to {@link Instrumentation} methods */ @SuppressWarnings("TypeParameterUnusedInFormals") +@PublicApi public class InstrumentationExecuteOperationParameters { private final ExecutionContext executionContext; - private final InstrumentationState instrumentationState; - public InstrumentationExecuteOperationParameters(ExecutionContext executionContext) { - this(executionContext, executionContext.getInstrumentationState()); - } - - private InstrumentationExecuteOperationParameters(ExecutionContext executionContext, InstrumentationState instrumentationState) { this.executionContext = executionContext; - this.instrumentationState = instrumentationState; } - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - public InstrumentationExecuteOperationParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationExecuteOperationParameters(executionContext, instrumentationState); - } public ExecutionContext getExecutionContext() { return executionContext; } - public T getInstrumentationState() { - //noinspection unchecked - return (T) instrumentationState; - } } diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionParameters.java index ddcaf6a8ae..58ad4d5aee 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionParameters.java @@ -1,12 +1,12 @@ package graphql.execution.instrumentation.parameters; import graphql.ExecutionInput; +import graphql.GraphQLContext; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationState; import graphql.schema.GraphQLSchema; -import java.util.Collections; import java.util.Map; /** @@ -18,30 +18,20 @@ public class InstrumentationExecutionParameters { private final String query; private final String operation; private final Object context; + private final GraphQLContext graphQLContext; private final Map variables; - private final InstrumentationState instrumentationState; private final GraphQLSchema schema; - public InstrumentationExecutionParameters(ExecutionInput executionInput, GraphQLSchema schema, InstrumentationState instrumentationState) { + public InstrumentationExecutionParameters(ExecutionInput executionInput, GraphQLSchema schema) { this.executionInput = executionInput; this.query = executionInput.getQuery(); this.operation = executionInput.getOperationName(); this.context = executionInput.getContext(); - this.variables = executionInput.getVariables() != null ? executionInput.getVariables() : Collections.emptyMap(); - this.instrumentationState = instrumentationState; + this.graphQLContext = executionInput.getGraphQLContext(); + this.variables = executionInput.getVariables() != null ? executionInput.getVariables() : ImmutableKit.emptyMap(); this.schema = schema; } - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - public InstrumentationExecutionParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationExecutionParameters(this.getExecutionInput(), this.schema, instrumentationState); - } public ExecutionInput getExecutionInput() { return executionInput; @@ -55,20 +45,27 @@ public String getOperation() { return operation; } + /** + * @param for two + * + * @return the legacy context + * + * @deprecated use {@link #getGraphQLContext()} instead + */ + @Deprecated(since = "2021-07-05") @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public T getContext() { return (T) context; } + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + public Map getVariables() { return variables; } - @SuppressWarnings("TypeParameterUnusedInFormals") - public T getInstrumentationState() { - //noinspection unchecked - return (T) instrumentationState; - } public GraphQLSchema getSchema() { return this.schema; diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionStrategyParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionStrategyParameters.java index b9e3f41684..9c93c84d42 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionStrategyParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationExecutionStrategyParameters.java @@ -1,38 +1,23 @@ package graphql.execution.instrumentation.parameters; +import graphql.PublicApi; import graphql.execution.ExecutionContext; import graphql.execution.ExecutionStrategyParameters; -import graphql.execution.instrumentation.InstrumentationState; /** * Parameters sent to {@link graphql.execution.instrumentation.Instrumentation} methods */ +@PublicApi public class InstrumentationExecutionStrategyParameters { private final ExecutionContext executionContext; private final ExecutionStrategyParameters executionStrategyParameters; - private final InstrumentationState instrumentationState; public InstrumentationExecutionStrategyParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters) { - this(executionContext, executionStrategyParameters, executionContext.getInstrumentationState()); - } - - private InstrumentationExecutionStrategyParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, InstrumentationState instrumentationState) { this.executionContext = executionContext; this.executionStrategyParameters = executionStrategyParameters; - this.instrumentationState = instrumentationState; } - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - public InstrumentationExecutionStrategyParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationExecutionStrategyParameters(executionContext, executionStrategyParameters, instrumentationState); - } public ExecutionContext getExecutionContext() { return executionContext; @@ -42,9 +27,4 @@ public ExecutionStrategyParameters getExecutionStrategyParameters() { return executionStrategyParameters; } - @SuppressWarnings("TypeParameterUnusedInFormals") - public T getInstrumentationState() { - //noinspection unchecked - return (T) instrumentationState; - } } diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldCompleteParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldCompleteParameters.java index fcc3cc02f4..ac7e1b27e5 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldCompleteParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldCompleteParameters.java @@ -1,46 +1,30 @@ package graphql.execution.instrumentation.parameters; +import graphql.PublicApi; import graphql.execution.ExecutionContext; +import graphql.execution.ExecutionStepInfo; import graphql.execution.ExecutionStrategyParameters; -import graphql.execution.ExecutionTypeInfo; -import graphql.execution.instrumentation.InstrumentationState; import graphql.schema.GraphQLFieldDefinition; +import java.util.function.Supplier; + /** * Parameters sent to {@link graphql.execution.instrumentation.Instrumentation} methods */ +@PublicApi public class InstrumentationFieldCompleteParameters { private final ExecutionContext executionContext; - private final GraphQLFieldDefinition fieldDef; - private final ExecutionTypeInfo typeInfo; + private final Supplier executionStepInfo; private final Object fetchedValue; - private final InstrumentationState instrumentationState; private final ExecutionStrategyParameters executionStrategyParameters; - public InstrumentationFieldCompleteParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, GraphQLFieldDefinition fieldDef, ExecutionTypeInfo typeInfo, Object fetchedValue) { - this(executionContext, executionStrategyParameters, fieldDef, typeInfo, fetchedValue, executionContext.getInstrumentationState()); - } - - InstrumentationFieldCompleteParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, GraphQLFieldDefinition fieldDef, ExecutionTypeInfo typeInfo, Object fetchedValue, InstrumentationState instrumentationState) { + public InstrumentationFieldCompleteParameters(ExecutionContext executionContext, ExecutionStrategyParameters executionStrategyParameters, Supplier executionStepInfo, Object fetchedValue) { this.executionContext = executionContext; this.executionStrategyParameters = executionStrategyParameters; - this.fieldDef = fieldDef; - this.typeInfo = typeInfo; + this.executionStepInfo = executionStepInfo; this.fetchedValue = fetchedValue; - this.instrumentationState = instrumentationState; } - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - public InstrumentationFieldCompleteParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationFieldCompleteParameters( - this.executionContext, executionStrategyParameters, this.fieldDef, this.typeInfo, this.fetchedValue, instrumentationState); - } public ExecutionContext getExecutionContext() { @@ -52,20 +36,26 @@ public ExecutionStrategyParameters getExecutionStrategyParameters() { } public GraphQLFieldDefinition getField() { - return fieldDef; + return getExecutionStepInfo().getFieldDefinition(); } - public ExecutionTypeInfo getTypeInfo() { - return typeInfo; + @Deprecated(since = "2020-09-08") + public ExecutionStepInfo getTypeInfo() { + return getExecutionStepInfo(); } - public Object getFetchedValue() { - return fetchedValue; + public ExecutionStepInfo getExecutionStepInfo() { + return executionStepInfo.get(); } - @SuppressWarnings("TypeParameterUnusedInFormals") - public T getInstrumentationState() { - //noinspection unchecked - return (T) instrumentationState; + /** + * This returns the object that was fetched, ready to be completed as a value. This can sometimes be a {@link graphql.execution.FetchedValue} object + * but most often it's a simple POJO. + * + * @return the object was fetched, ready to be completed as a value. + */ + public Object getFetchedObject() { + return fetchedValue; } + } diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters.java index 28e50a00ca..fda194d73e 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldFetchParameters.java @@ -1,47 +1,34 @@ package graphql.execution.instrumentation.parameters; +import graphql.PublicApi; import graphql.execution.ExecutionContext; import graphql.execution.ExecutionStrategyParameters; import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationState; import graphql.schema.DataFetchingEnvironment; -import graphql.schema.GraphQLFieldDefinition; + +import java.util.function.Supplier; /** * Parameters sent to {@link Instrumentation} methods */ +@PublicApi public class InstrumentationFieldFetchParameters extends InstrumentationFieldParameters { - private final DataFetchingEnvironment environment; + private final Supplier environment; private final ExecutionStrategyParameters executionStrategyParameters; + private final boolean trivialDataFetcher; - public InstrumentationFieldFetchParameters(ExecutionContext getExecutionContext, GraphQLFieldDefinition fieldDef, DataFetchingEnvironment environment, ExecutionStrategyParameters executionStrategyParameters) { - super(getExecutionContext, fieldDef, environment.getFieldTypeInfo()); - this.environment = environment; - this.executionStrategyParameters = executionStrategyParameters; - } - - private InstrumentationFieldFetchParameters(ExecutionContext getExecutionContext, GraphQLFieldDefinition fieldDef, DataFetchingEnvironment environment, InstrumentationState instrumentationState, ExecutionStrategyParameters executionStrategyParameters) { - super(getExecutionContext, fieldDef, environment.getFieldTypeInfo(), instrumentationState); + public InstrumentationFieldFetchParameters(ExecutionContext getExecutionContext, Supplier environment, ExecutionStrategyParameters executionStrategyParameters, boolean trivialDataFetcher) { + super(getExecutionContext, () -> environment.get().getExecutionStepInfo()); this.environment = environment; this.executionStrategyParameters = executionStrategyParameters; + this.trivialDataFetcher = trivialDataFetcher; } - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - @Override - public InstrumentationFieldFetchParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationFieldFetchParameters( - this.getExecutionContext(), this.getField(), this.getEnvironment(), - instrumentationState, executionStrategyParameters); + public DataFetchingEnvironment getEnvironment() { + return environment.get(); } - - public DataFetchingEnvironment getEnvironment() { - return environment; + public boolean isTrivialDataFetcher() { + return trivialDataFetcher; } } diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldParameters.java index 11e7fa8bea..ebac32ffb1 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationFieldParameters.java @@ -1,59 +1,34 @@ package graphql.execution.instrumentation.parameters; +import graphql.PublicApi; import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionTypeInfo; +import graphql.execution.ExecutionStepInfo; import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationState; import graphql.schema.GraphQLFieldDefinition; +import java.util.function.Supplier; + /** * Parameters sent to {@link Instrumentation} methods */ +@PublicApi public class InstrumentationFieldParameters { private final ExecutionContext executionContext; - private final graphql.schema.GraphQLFieldDefinition fieldDef; - private final ExecutionTypeInfo typeInfo; - private final InstrumentationState instrumentationState; - - public InstrumentationFieldParameters(ExecutionContext executionContext, GraphQLFieldDefinition fieldDef, ExecutionTypeInfo typeInfo) { - this(executionContext, fieldDef, typeInfo, executionContext.getInstrumentationState()); - } - - InstrumentationFieldParameters(ExecutionContext executionContext, GraphQLFieldDefinition fieldDef, ExecutionTypeInfo typeInfo, InstrumentationState instrumentationState) { + private final Supplier executionStepInfo; + public InstrumentationFieldParameters(ExecutionContext executionContext, Supplier executionStepInfo) { this.executionContext = executionContext; - this.fieldDef = fieldDef; - this.typeInfo = typeInfo; - this.instrumentationState = instrumentationState; + this.executionStepInfo = executionStepInfo; } - - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - public InstrumentationFieldParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationFieldParameters( - this.executionContext, this.fieldDef, this.typeInfo, instrumentationState); - } - - public ExecutionContext getExecutionContext() { return executionContext; } public GraphQLFieldDefinition getField() { - return fieldDef; + return executionStepInfo.get().getFieldDefinition(); } - public ExecutionTypeInfo getTypeInfo() { - return typeInfo; + public ExecutionStepInfo getExecutionStepInfo() { + return executionStepInfo.get(); } - @SuppressWarnings("TypeParameterUnusedInFormals") - public T getInstrumentationState() { - //noinspection unchecked - return (T) instrumentationState; - } } diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationReactiveResultsParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationReactiveResultsParameters.java new file mode 100644 index 0000000000..a4e312efd6 --- /dev/null +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationReactiveResultsParameters.java @@ -0,0 +1,39 @@ +package graphql.execution.instrumentation.parameters; + +import graphql.PublicApi; +import graphql.execution.ExecutionContext; +import graphql.execution.instrumentation.Instrumentation; +import org.jspecify.annotations.NullMarked; + +/** + * Parameters sent to {@link Instrumentation} methods + */ +@SuppressWarnings("TypeParameterUnusedInFormals") +@PublicApi +@NullMarked +public class InstrumentationReactiveResultsParameters { + + /** + * What type of reactive results was the {@link org.reactivestreams.Publisher} + */ + public enum ResultType { + DEFER, SUBSCRIPTION + } + + private final ExecutionContext executionContext; + private final ResultType resultType; + + public InstrumentationReactiveResultsParameters(ExecutionContext executionContext, ResultType resultType) { + this.executionContext = executionContext; + this.resultType = resultType; + } + + + public ExecutionContext getExecutionContext() { + return executionContext; + } + + public ResultType getResultType() { + return resultType; + } +} diff --git a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationValidationParameters.java b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationValidationParameters.java index f35c7616c8..c23a413941 100644 --- a/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationValidationParameters.java +++ b/src/main/java/graphql/execution/instrumentation/parameters/InstrumentationValidationParameters.java @@ -1,35 +1,23 @@ package graphql.execution.instrumentation.parameters; import graphql.ExecutionInput; +import graphql.PublicApi; import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.InstrumentationState; import graphql.language.Document; import graphql.schema.GraphQLSchema; /** * Parameters sent to {@link Instrumentation} methods */ +@PublicApi public class InstrumentationValidationParameters extends InstrumentationExecutionParameters { private final Document document; - public InstrumentationValidationParameters(ExecutionInput executionInput, Document document, GraphQLSchema schema, InstrumentationState instrumentationState) { - super(executionInput, schema, instrumentationState); + public InstrumentationValidationParameters(ExecutionInput executionInput, Document document, GraphQLSchema schema) { + super(executionInput, schema); this.document = document; } - /** - * Returns a cloned parameters object with the new state - * - * @param instrumentationState the new state for this parameters object - * - * @return a new parameters object with the new state - */ - @Override - public InstrumentationValidationParameters withNewState(InstrumentationState instrumentationState) { - return new InstrumentationValidationParameters( - this.getExecutionInput(), document, getSchema(), instrumentationState); - } - public Document getDocument() { return document; diff --git a/src/main/java/graphql/execution/instrumentation/tracing/TracingInstrumentation.java b/src/main/java/graphql/execution/instrumentation/tracing/TracingInstrumentation.java index 867a9d09a5..ed18f68ab8 100644 --- a/src/main/java/graphql/execution/instrumentation/tracing/TracingInstrumentation.java +++ b/src/main/java/graphql/execution/instrumentation/tracing/TracingInstrumentation.java @@ -3,22 +3,26 @@ import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationContext; import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.SimpleInstrumentation; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters; import graphql.language.Document; import graphql.validation.ValidationError; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import static graphql.execution.instrumentation.InstrumentationState.ofState; import static graphql.execution.instrumentation.SimpleInstrumentationContext.whenCompleted; /** @@ -26,42 +30,80 @@ * capture tracing information and puts it into the {@link ExecutionResult} */ @PublicApi -public class TracingInstrumentation extends SimpleInstrumentation { +public class TracingInstrumentation extends SimplePerformantInstrumentation { + + public static class Options { + private final boolean includeTrivialDataFetchers; + + private Options(boolean includeTrivialDataFetchers) { + this.includeTrivialDataFetchers = includeTrivialDataFetchers; + } + + public boolean isIncludeTrivialDataFetchers() { + return includeTrivialDataFetchers; + } + + /** + * By default trivial data fetchers (those that simple pull data from an object into field) are included + * in tracing but you can control this behavior. + * + * @param flag the flag on whether to trace trivial data fetchers + * + * @return a new options object + */ + public Options includeTrivialDataFetchers(boolean flag) { + return new Options(flag); + } + + public static Options newOptions() { + return new Options(true); + } + + } + + public TracingInstrumentation() { + this(Options.newOptions()); + } + + public TracingInstrumentation(Options options) { + this.options = options; + } + + private final Options options; @Override - public InstrumentationState createState() { - return new TracingSupport(); + public @Nullable CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.completedFuture(new TracingSupport(options.includeTrivialDataFetchers)); } @Override - public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { + public @NonNull CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState rawState) { Map currentExt = executionResult.getExtensions(); - TracingSupport tracingSupport = parameters.getInstrumentationState(); - Map tracingMap = new LinkedHashMap<>(); - tracingMap.putAll(currentExt == null ? Collections.emptyMap() : currentExt); - tracingMap.put("tracing", tracingSupport.snapshotTracingData()); + TracingSupport tracingSupport = ofState(rawState); + Map withTracingExt = new LinkedHashMap<>(currentExt == null ? ImmutableKit.emptyMap() : currentExt); + withTracingExt.put("tracing", tracingSupport.snapshotTracingData()); - return CompletableFuture.completedFuture(new ExecutionResultImpl(executionResult.getData(), executionResult.getErrors(), tracingMap)); + return CompletableFuture.completedFuture(new ExecutionResultImpl(executionResult.getData(), executionResult.getErrors(), withTracingExt)); } @Override - public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - TracingSupport tracingSupport = parameters.getInstrumentationState(); - TracingSupport.TracingContext ctx = tracingSupport.beginField(parameters.getEnvironment()); + public InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState rawState) { + TracingSupport tracingSupport = ofState(rawState); + TracingSupport.TracingContext ctx = tracingSupport.beginField(parameters.getEnvironment(), parameters.isTrivialDataFetcher()); return whenCompleted((result, t) -> ctx.onEnd()); } @Override - public InstrumentationContext beginParse(InstrumentationExecutionParameters parameters) { - TracingSupport tracingSupport = parameters.getInstrumentationState(); + public InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState rawState) { + TracingSupport tracingSupport = ofState(rawState); TracingSupport.TracingContext ctx = tracingSupport.beginParse(); return whenCompleted((result, t) -> ctx.onEnd()); } @Override - public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - TracingSupport tracingSupport = parameters.getInstrumentationState(); + public InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState rawState) { + TracingSupport tracingSupport = ofState(rawState); TracingSupport.TracingContext ctx = tracingSupport.beginValidation(); return whenCompleted((result, t) -> ctx.onEnd()); } diff --git a/src/main/java/graphql/execution/instrumentation/tracing/TracingSupport.java b/src/main/java/graphql/execution/instrumentation/tracing/TracingSupport.java index e91a3caa2c..4a0f97a15c 100644 --- a/src/main/java/graphql/execution/instrumentation/tracing/TracingSupport.java +++ b/src/main/java/graphql/execution/instrumentation/tracing/TracingSupport.java @@ -1,18 +1,20 @@ package graphql.execution.instrumentation.tracing; +import com.google.common.collect.ImmutableList; import graphql.PublicApi; -import graphql.execution.ExecutionTypeInfo; +import graphql.execution.ExecutionStepInfo; import graphql.execution.instrumentation.InstrumentationState; import graphql.schema.DataFetchingEnvironment; import java.time.Instant; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentLinkedQueue; +import static graphql.schema.GraphQLTypeUtil.simplePrint; + /** * This creates a map of tracing information as outlined in https://github.com/apollographql/apollo-tracing *

@@ -28,11 +30,15 @@ public class TracingSupport implements InstrumentationState { private final ConcurrentLinkedQueue> fieldData; private final Map parseMap = new LinkedHashMap<>(); private final Map validationMap = new LinkedHashMap<>(); + private final boolean includeTrivialDataFetchers; /** * The timer starts as soon as you create this object + * + * @param includeTrivialDataFetchers whether the trace trivial data fetchers */ - public TracingSupport() { + public TracingSupport(boolean includeTrivialDataFetchers) { + this.includeTrivialDataFetchers = includeTrivialDataFetchers; startRequestNanos = System.nanoTime(); startRequestTime = Instant.now(); fieldData = new ConcurrentLinkedQueue<>(); @@ -53,22 +59,28 @@ public interface TracingContext { * end the call. * * @param dataFetchingEnvironment the data fetching that is occurring + * @param trivialDataFetcher if the data fetcher is considered trivial * * @return a context to call end on */ - public TracingContext beginField(DataFetchingEnvironment dataFetchingEnvironment) { + public TracingContext beginField(DataFetchingEnvironment dataFetchingEnvironment, boolean trivialDataFetcher) { + if (!includeTrivialDataFetchers && trivialDataFetcher) { + return () -> { + // nothing to do + }; + } long startFieldFetch = System.nanoTime(); return () -> { long now = System.nanoTime(); long duration = now - startFieldFetch; long startOffset = startFieldFetch - startRequestNanos; - ExecutionTypeInfo typeInfo = dataFetchingEnvironment.getFieldTypeInfo(); + ExecutionStepInfo executionStepInfo = dataFetchingEnvironment.getExecutionStepInfo(); Map fetchMap = new LinkedHashMap<>(); - fetchMap.put("path", typeInfo.getPath().toList()); - fetchMap.put("parentType", typeInfo.getParentTypeInfo().getType().getName()); - fetchMap.put("returnType", typeInfo.toAst()); - fetchMap.put("fieldName", typeInfo.getFieldDefinition().getName()); + fetchMap.put("path", executionStepInfo.getPath().toList()); + fetchMap.put("parentType", simplePrint(executionStepInfo.getParent().getUnwrappedNonNullType())); + fetchMap.put("returnType", executionStepInfo.simplePrint()); + fetchMap.put("fieldName", executionStepInfo.getFieldDefinition().getName()); fetchMap.put("startOffset", startOffset); fetchMap.put("duration", duration); @@ -128,15 +140,12 @@ public Map snapshotTracingData() { } private Object copyMap(Map map) { - Map mapCopy = new LinkedHashMap<>(); - mapCopy.putAll(map); - return mapCopy; - + return new LinkedHashMap<>(map); } private Map executionData() { Map map = new LinkedHashMap<>(); - List> list = new ArrayList<>(fieldData); + List> list = ImmutableList.copyOf(fieldData); map.put("resolvers", list); return map; } diff --git a/src/main/java/graphql/execution/preparsed/NoOpPreparsedDocumentProvider.java b/src/main/java/graphql/execution/preparsed/NoOpPreparsedDocumentProvider.java index 09f9762c76..03a96776b6 100644 --- a/src/main/java/graphql/execution/preparsed/NoOpPreparsedDocumentProvider.java +++ b/src/main/java/graphql/execution/preparsed/NoOpPreparsedDocumentProvider.java @@ -1,13 +1,18 @@ package graphql.execution.preparsed; +import graphql.ExecutionInput; +import graphql.Internal; + +import java.util.concurrent.CompletableFuture; import java.util.function.Function; +@Internal public class NoOpPreparsedDocumentProvider implements PreparsedDocumentProvider { public static final NoOpPreparsedDocumentProvider INSTANCE = new NoOpPreparsedDocumentProvider(); @Override - public PreparsedDocumentEntry get(String query, Function compute) { - return compute.apply(query); + public CompletableFuture getDocumentAsync(ExecutionInput executionInput, Function parseAndValidateFunction) { + return CompletableFuture.completedFuture(parseAndValidateFunction.apply(executionInput)); } } diff --git a/src/main/java/graphql/execution/preparsed/PreparsedDocumentEntry.java b/src/main/java/graphql/execution/preparsed/PreparsedDocumentEntry.java index eb971c55ee..8c14cf9bf8 100644 --- a/src/main/java/graphql/execution/preparsed/PreparsedDocumentEntry.java +++ b/src/main/java/graphql/execution/preparsed/PreparsedDocumentEntry.java @@ -1,6 +1,7 @@ package graphql.execution.preparsed; import graphql.GraphQLError; +import graphql.PublicApi; import graphql.language.Document; import java.io.Serializable; @@ -10,18 +11,28 @@ import static java.util.Collections.singletonList; /** - * An instance of a preparsed document entry represents the result of a query parse and validation, like - * an either implementation it contains either the correct result in th document property or the errors. + * An instance of a preparsed document entry represents the result of a query parse and validation. In the case of + * failed parsing or no validation errors this class acts as an either implementation. In the case of successful + * parsing and failed validation this class provides both the document and the validation errors. * * NOTE: This class implements {@link java.io.Serializable} and hence it can be serialised and placed into a distributed cache. However we * are not aiming to provide long term compatibility and do not intend for you to place this serialised data into permanent storage, * with times frames that cross graphql-java versions. While we don't change things unnecessarily, we may inadvertently break * the serialised compatibility across versions. */ +@PublicApi public class PreparsedDocumentEntry implements Serializable { private final Document document; private final List errors; + public PreparsedDocumentEntry(Document document, + List errors) { + assertNotNull(document); + assertNotNull(errors); + this.document = document; + this.errors = errors; + } + public PreparsedDocumentEntry(Document document) { assertNotNull(document); this.document = document; diff --git a/src/main/java/graphql/execution/preparsed/PreparsedDocumentProvider.java b/src/main/java/graphql/execution/preparsed/PreparsedDocumentProvider.java index 5ad31d0b28..7aac05d09d 100644 --- a/src/main/java/graphql/execution/preparsed/PreparsedDocumentProvider.java +++ b/src/main/java/graphql/execution/preparsed/PreparsedDocumentProvider.java @@ -1,23 +1,30 @@ package graphql.execution.preparsed; +import graphql.ExecutionInput; +import graphql.PublicSpi; + +import java.util.concurrent.CompletableFuture; import java.util.function.Function; /** - * Interface that allows clients to hook in Document caching and/or the whitelisting of queries + * Interface that allows clients to hook in Document caching and/or the whitelisting of queries. */ -@FunctionalInterface +@PublicSpi public interface PreparsedDocumentProvider { /** - * This is called to get a "cached" pre-parsed query and if its not present, then the computeFunction - * can be called to parse the query - * - * @param query The graphql query - * @param computeFunction If the query has not be pre-parsed, this function can be called to parse it + * This is called to get a "cached" pre-parsed query and if it's not present, then the "parseAndValidateFunction" + * can be called to parse and validate the query. + *

+ * Note - the "parseAndValidateFunction" MUST be called if you don't have a per parsed version of the query because it not only parses + * and validates the query, it invokes {@link graphql.execution.instrumentation.Instrumentation} calls as well for parsing and validation. + * if you don't make a call back on this then these won't happen. * - * @return an instance of {@link PreparsedDocumentEntry} + * @param executionInput The {@link graphql.ExecutionInput} containing the query + * @param parseAndValidateFunction If the query has not be pre-parsed, this function MUST be called to parse and validate it + * @return a promise to an {@link PreparsedDocumentEntry} */ - PreparsedDocumentEntry get(String query, Function computeFunction); + CompletableFuture getDocumentAsync(ExecutionInput executionInput, Function parseAndValidateFunction); } diff --git a/src/main/java/graphql/execution/preparsed/persisted/ApolloPersistedQuerySupport.java b/src/main/java/graphql/execution/preparsed/persisted/ApolloPersistedQuerySupport.java new file mode 100644 index 0000000000..b7b1a15302 --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/ApolloPersistedQuerySupport.java @@ -0,0 +1,70 @@ +package graphql.execution.preparsed.persisted; + +import graphql.ExecutionInput; +import graphql.PublicApi; + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.Optional; + +/** + * This persisted query support class supports the Apollo scheme where the persisted + * query id is in {@link graphql.ExecutionInput#getExtensions()}. + *

+ * You need to provide a {@link PersistedQueryCache} cache implementation + * as the backing cache. + *

+ * See Apollo Persisted Queries + *

+ * The Apollo client sends a hash of the persisted query in the input extensions in the following form + *

+ *     {
+ *      "extensions":{
+ *       "persistedQuery":{
+ *        "version":1,
+ *        "sha256Hash":"fcf31818e50ac3e818ca4bdbc433d6ab73176f0b9d5f9d5ad17e200cdab6fba4"
+ *      }
+ *    }
+ *  }
+ * 
+ * + * @see graphql.ExecutionInput#getExtensions() + */ +@PublicApi +public class ApolloPersistedQuerySupport extends PersistedQuerySupport { + + private static final String CHECKSUM_TYPE = "SHA-256"; + + public ApolloPersistedQuerySupport(PersistedQueryCache persistedQueryCache) { + super(persistedQueryCache); + } + + @SuppressWarnings("unchecked") + @Override + protected Optional getPersistedQueryId(ExecutionInput executionInput) { + Map extensions = executionInput.getExtensions(); + Map persistedQuery = (Map) extensions.get("persistedQuery"); + if (persistedQuery != null) { + Object sha256Hash = persistedQuery.get("sha256Hash"); + return Optional.ofNullable(sha256Hash); + } + return Optional.empty(); + } + + @Override + protected boolean persistedQueryIdIsInvalid(Object persistedQueryId, String queryText) { + MessageDigest messageDigest; + try { + messageDigest = MessageDigest.getInstance(CHECKSUM_TYPE); + } catch (NoSuchAlgorithmException e) { + return false; + } + + BigInteger bigInteger = new BigInteger(1, messageDigest.digest(queryText.getBytes(StandardCharsets.UTF_8))); + String calculatedChecksum = String.format("%064x", bigInteger); + return !calculatedChecksum.equalsIgnoreCase(persistedQueryId.toString()); + } +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/InMemoryPersistedQueryCache.java b/src/main/java/graphql/execution/preparsed/persisted/InMemoryPersistedQueryCache.java new file mode 100644 index 0000000000..5226332b85 --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/InMemoryPersistedQueryCache.java @@ -0,0 +1,68 @@ +package graphql.execution.preparsed.persisted; + +import graphql.Assert; +import graphql.ExecutionInput; +import graphql.PublicApi; +import graphql.execution.preparsed.PreparsedDocumentEntry; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A PersistedQueryCache that is just an in memory map of known queries. + */ +@PublicApi +public class InMemoryPersistedQueryCache implements PersistedQueryCache { + + private final Map cache = new ConcurrentHashMap<>(); + private final Map knownQueries; + + public InMemoryPersistedQueryCache(Map knownQueries) { + this.knownQueries = Assert.assertNotNull(knownQueries); + } + + public Map getKnownQueries() { + return knownQueries; + } + + @Override + public CompletableFuture getPersistedQueryDocumentAsync(Object persistedQueryId, ExecutionInput executionInput, PersistedQueryCacheMiss onCacheMiss) throws PersistedQueryNotFound { + PreparsedDocumentEntry documentEntry = cache.compute(persistedQueryId, (k, v) -> { + if (v != null) { + return v; + } + + //get the query from the execution input. Make sure it's not null, empty or the APQ marker. + // if it is, fallback to the known queries. + String queryText = executionInput.getQuery(); + if (queryText == null || queryText.isEmpty() || queryText.equals(PersistedQuerySupport.PERSISTED_QUERY_MARKER)) { + queryText = knownQueries.get(persistedQueryId); + } + + if (queryText == null) { + throw new PersistedQueryNotFound(persistedQueryId); + } + return onCacheMiss.apply(queryText); + }); + return CompletableFuture.completedFuture(documentEntry); + } + + public static Builder newInMemoryPersistedQueryCache() { + return new Builder(); + } + + public static class Builder { + private final Map knownQueries = new HashMap<>(); + + public Builder addQuery(Object key, String queryText) { + knownQueries.put(key, queryText); + return this; + } + + public InMemoryPersistedQueryCache build() { + return new InMemoryPersistedQueryCache(knownQueries); + } + } +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryCache.java b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryCache.java new file mode 100644 index 0000000000..7690280e78 --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryCache.java @@ -0,0 +1,32 @@ +package graphql.execution.preparsed.persisted; + +import graphql.ExecutionInput; +import graphql.PublicSpi; +import graphql.execution.preparsed.PreparsedDocumentEntry; + +import java.util.concurrent.CompletableFuture; + +/** + * This interface is used to abstract an actual cache that can cache parsed persistent queries. + */ +@PublicSpi +public interface PersistedQueryCache { + /** + * This is called to get a persisted query from cache. + *

+ * If its present in cache then it must return a PreparsedDocumentEntry where {@link graphql.execution.preparsed.PreparsedDocumentEntry#getDocument()} + * is already parsed and validated. This will be passed onto the graphql engine as is. + *

+ * If it's a valid query id but its no present in cache, (cache miss) then you need to call back the "onCacheMiss" function with associated query text. + * This will be compiled and validated by the graphql engine and the PreparsedDocumentEntry will be passed back ready for you to cache it. + *

+ * If it's not a valid query id then throw a {@link graphql.execution.preparsed.persisted.PersistedQueryNotFound} to indicate this. + * + * @param persistedQueryId the persisted query id + * @param executionInput the original execution input + * @param onCacheMiss the call back should it be a valid query id but it's not currently in the cache + * @return a promise to parsed and validated {@link PreparsedDocumentEntry} where {@link graphql.execution.preparsed.PreparsedDocumentEntry#getDocument()} is set + * @throws graphql.execution.preparsed.persisted.PersistedQueryNotFound if the query id is not know at all and you have no query text + */ + CompletableFuture getPersistedQueryDocumentAsync(Object persistedQueryId, ExecutionInput executionInput, PersistedQueryCacheMiss onCacheMiss) throws PersistedQueryNotFound; +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryCacheMiss.java b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryCacheMiss.java new file mode 100644 index 0000000000..6e9cc03a3d --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryCacheMiss.java @@ -0,0 +1,23 @@ +package graphql.execution.preparsed.persisted; + +import graphql.PublicApi; +import graphql.execution.preparsed.PreparsedDocumentEntry; + +import java.util.function.Function; + +/** + * The call back when a valid persisted query is not in cache and it needs to be compiled and validated + * by the graphql engine. If you get a cache miss in your {@link graphql.execution.preparsed.persisted.PersistedQueryCache} implementation + * then you are required to call back on the provided instance of this interface + */ +@PublicApi +public interface PersistedQueryCacheMiss extends Function { + /** + * You give back the missing query text and graphql-java will compile and validate it. + * + * @param queryToBeParsedAndValidated the query text to be parsed and validated + * @return a parsed and validated query document ready for caching + */ + @Override + PreparsedDocumentEntry apply(String queryToBeParsedAndValidated); +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryError.java b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryError.java new file mode 100644 index 0000000000..fd34289bee --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryError.java @@ -0,0 +1,13 @@ +package graphql.execution.preparsed.persisted; + +import graphql.ErrorClassification; + +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class PersistedQueryError extends RuntimeException implements ErrorClassification { + + Map getExtensions() { + return new LinkedHashMap<>(); + } +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryIdInvalid.java b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryIdInvalid.java new file mode 100644 index 0000000000..2599069797 --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryIdInvalid.java @@ -0,0 +1,35 @@ +package graphql.execution.preparsed.persisted; + +import graphql.PublicApi; + +import java.util.LinkedHashMap; +import java.util.Map; + +@PublicApi +public class PersistedQueryIdInvalid extends PersistedQueryError { + private final Object persistedQueryId; + + public PersistedQueryIdInvalid(Object persistedQueryId) { + this.persistedQueryId = persistedQueryId; + } + + @Override + public String getMessage() { + return "PersistedQueryIdInvalid"; + } + + public Object getPersistedQueryId() { + return persistedQueryId; + } + + @Override + public String toString() { + return "PersistedQueryIdInvalid"; + } + + public Map getExtensions() { + LinkedHashMap extensions = new LinkedHashMap<>(); + extensions.put("persistedQueryId", getPersistedQueryId()); + return extensions; + } +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryNotFound.java b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryNotFound.java new file mode 100644 index 0000000000..22c38bf8e5 --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/PersistedQueryNotFound.java @@ -0,0 +1,40 @@ +package graphql.execution.preparsed.persisted; + +import graphql.PublicApi; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * An exception that indicates the query id is not valid and can be found ever in cache + */ +@PublicApi +public class PersistedQueryNotFound extends PersistedQueryError { + private final Object persistedQueryId; + + public PersistedQueryNotFound(Object persistedQueryId) { + this.persistedQueryId = persistedQueryId; + } + + @Override + public String getMessage() { + return "PersistedQueryNotFound"; + } + + public Object getPersistedQueryId() { + return persistedQueryId; + } + + @Override + public String toString() { + return "PersistedQueryNotFound"; + } + + @Override + public Map getExtensions() { + LinkedHashMap extensions = new LinkedHashMap<>(); + extensions.put("persistedQueryId", persistedQueryId); + extensions.put("generatedBy", "graphql-java"); + return extensions; + } +} diff --git a/src/main/java/graphql/execution/preparsed/persisted/PersistedQuerySupport.java b/src/main/java/graphql/execution/preparsed/persisted/PersistedQuerySupport.java new file mode 100644 index 0000000000..b65e20b78a --- /dev/null +++ b/src/main/java/graphql/execution/preparsed/persisted/PersistedQuerySupport.java @@ -0,0 +1,95 @@ +package graphql.execution.preparsed.persisted; + +import graphql.ExecutionInput; +import graphql.GraphQLError; +import graphql.GraphqlErrorBuilder; +import graphql.PublicSpi; +import graphql.execution.preparsed.PreparsedDocumentEntry; +import graphql.execution.preparsed.PreparsedDocumentProvider; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; + +import static graphql.Assert.assertNotNull; +import static java.util.concurrent.CompletableFuture.completedFuture; + +/** + * This abstract class forms the basis for persistent query support. Derived classes + * need to implement the method to work out the query id and you also need + * a {@link PersistedQueryCache} implementation. + * + * @see graphql.execution.preparsed.PreparsedDocumentProvider + * @see graphql.GraphQL.Builder#preparsedDocumentProvider(graphql.execution.preparsed.PreparsedDocumentProvider) + */ +@PublicSpi +public abstract class PersistedQuerySupport implements PreparsedDocumentProvider { + + /** + * In order for {@link graphql.ExecutionInput#getQuery()} to never be null, use this to mark + * them so that invariant can be satisfied while assuming that the persisted query id is elsewhere + */ + public static final String PERSISTED_QUERY_MARKER = "PersistedQueryMarker"; + + private final PersistedQueryCache persistedQueryCache; + + public PersistedQuerySupport(PersistedQueryCache persistedQueryCache) { + this.persistedQueryCache = assertNotNull(persistedQueryCache); + } + + @Override + public CompletableFuture getDocumentAsync(ExecutionInput executionInput, Function parseAndValidateFunction) { + Optional queryIdOption = getPersistedQueryId(executionInput); + assertNotNull(queryIdOption, "The class %s MUST return a non null optional query id", this.getClass().getName()); + + try { + if (queryIdOption.isPresent()) { + Object persistedQueryId = queryIdOption.get(); + return persistedQueryCache.getPersistedQueryDocumentAsync(persistedQueryId, executionInput, (queryText) -> { + // we have a miss and they gave us nothing - bah! + if (queryText == null || queryText.isBlank()) { + throw new PersistedQueryNotFound(persistedQueryId); + } + // validate the queryText hash before returning to the cache which we assume will set it + if (persistedQueryIdIsInvalid(persistedQueryId, queryText)) { + throw new PersistedQueryIdInvalid(persistedQueryId); + } + ExecutionInput newEI = executionInput.transform(builder -> builder.query(queryText)); + return parseAndValidateFunction.apply(newEI); + }); + } + // ok there is no query id - we assume the query is indeed ready to go as is - ie its not a persisted query + return completedFuture(parseAndValidateFunction.apply(executionInput)); + } catch (PersistedQueryError e) { + return completedFuture(mkMissingError(e)); + } + } + + /** + * This method is required for concrete types to work out the query id (often a hash) that should be used to look + * up the persisted query in the cache. + * + * @param executionInput the execution input + * + * @return an optional id of the persisted query + */ + abstract protected Optional getPersistedQueryId(ExecutionInput executionInput); + + protected boolean persistedQueryIdIsInvalid(Object persistedQueryId, String queryText) { + return false; + } + + /** + * Allows you to customize the graphql error that is sent back on a missing persisted query + * + * @param persistedQueryError the missing persistent query exception + * + * @return a PreparsedDocumentEntry that holds an error + */ + protected PreparsedDocumentEntry mkMissingError(PersistedQueryError persistedQueryError) { + GraphQLError gqlError = GraphqlErrorBuilder.newError() + .errorType(persistedQueryError).message(persistedQueryError.getMessage()) + .extensions(persistedQueryError.getExtensions()).build(); + return new PreparsedDocumentEntry(gqlError); + } +} diff --git a/src/main/java/graphql/execution/reactive/CompletionStageMappingOrderedPublisher.java b/src/main/java/graphql/execution/reactive/CompletionStageMappingOrderedPublisher.java new file mode 100644 index 0000000000..91915c450e --- /dev/null +++ b/src/main/java/graphql/execution/reactive/CompletionStageMappingOrderedPublisher.java @@ -0,0 +1,36 @@ +package graphql.execution.reactive; + +import graphql.Internal; +import org.jspecify.annotations.NonNull; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; + +import java.util.concurrent.CompletionStage; +import java.util.function.Function; + +/** + * A reactive Publisher that bridges over another Publisher of `D` and maps the results + * to type `U` via a CompletionStage, handling errors in that stage but keeps the results + * in order of downstream publishing. This means it must queue unfinished + * completion stages in memory in arrival order. + * + * @param the downstream type + * @param the upstream type to be mapped to + */ +@Internal +public class CompletionStageMappingOrderedPublisher extends CompletionStageMappingPublisher { + /** + * You need the following : + * + * @param upstreamPublisher an upstream source of data + * @param mapper a mapper function that turns upstream data into a promise of mapped D downstream data + */ + public CompletionStageMappingOrderedPublisher(Publisher upstreamPublisher, Function> mapper) { + super(upstreamPublisher, mapper); + } + + @Override + protected @NonNull Subscriber createSubscriber(Subscriber downstreamSubscriber) { + return new CompletionStageOrderedSubscriber<>(mapper, downstreamSubscriber); + } +} diff --git a/src/main/java/graphql/execution/reactive/CompletionStageMappingPublisher.java b/src/main/java/graphql/execution/reactive/CompletionStageMappingPublisher.java index b686889795..4c334a13cc 100644 --- a/src/main/java/graphql/execution/reactive/CompletionStageMappingPublisher.java +++ b/src/main/java/graphql/execution/reactive/CompletionStageMappingPublisher.java @@ -1,22 +1,26 @@ package graphql.execution.reactive; +import graphql.Internal; +import org.jspecify.annotations.NonNull; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; import java.util.concurrent.CompletionStage; import java.util.function.Function; +import static graphql.Assert.assertNotNullWithNPE; + /** * A reactive Publisher that bridges over another Publisher of `D` and maps the results * to type `U` via a CompletionStage, handling errors in that stage * - * @param the down stream type - * @param the up stream type to be mapped to + * @param the downstream type + * @param the upstream type to be mapped to */ +@Internal public class CompletionStageMappingPublisher implements Publisher { - private final Publisher upstreamPublisher; - private final Function> mapper; + protected final Publisher upstreamPublisher; + protected final Function> mapper; /** * You need the following : @@ -31,53 +35,23 @@ public CompletionStageMappingPublisher(Publisher upstreamPublisher, Function< @Override public void subscribe(Subscriber downstreamSubscriber) { - upstreamPublisher.subscribe(new Subscriber() { - Subscription delegatingSubscription; - - @Override - public void onSubscribe(Subscription subscription) { - delegatingSubscription = new DelegatingSubscription(subscription); - downstreamSubscriber.onSubscribe(delegatingSubscription); - } - - @Override - public void onNext(U u) { - CompletionStage completionStage; - try { - completionStage = mapper.apply(u); - completionStage.whenComplete((d, throwable) -> { - if (throwable != null) { - handleThrowable(throwable); - } else { - downstreamSubscriber.onNext(d); - } - }); - } catch (RuntimeException throwable) { - handleThrowable(throwable); - } - } + assertNotNullWithNPE(downstreamSubscriber, "Subscriber passed to subscribe must not be null"); + upstreamPublisher.subscribe(createSubscriber(downstreamSubscriber)); + } - private void handleThrowable(Throwable throwable) { - downstreamSubscriber.onError(throwable); - // - // reactive semantics say that IF an exception happens on a publisher - // then onError is called and no more messages flow. But since the exception happened - // during the mapping, the upstream publisher does not no about this. - // so we cancel to bring the semantics back together, that is as soon as an exception - // has happened, no more messages flow - // - delegatingSubscription.cancel(); - } + @NonNull + protected Subscriber createSubscriber(Subscriber downstreamSubscriber) { + return new CompletionStageSubscriber<>(mapper, downstreamSubscriber); + } - @Override - public void onError(Throwable t) { - downstreamSubscriber.onError(t); - } - @Override - public void onComplete() { - downstreamSubscriber.onComplete(); - } - }); + /** + * Get instance of an upstreamPublisher + * + * @return upstream instance of {@link Publisher} + */ + public Publisher getUpstreamPublisher() { + return upstreamPublisher; } + } diff --git a/src/main/java/graphql/execution/reactive/CompletionStageOrderedSubscriber.java b/src/main/java/graphql/execution/reactive/CompletionStageOrderedSubscriber.java new file mode 100644 index 0000000000..53a8dd4719 --- /dev/null +++ b/src/main/java/graphql/execution/reactive/CompletionStageOrderedSubscriber.java @@ -0,0 +1,84 @@ +package graphql.execution.reactive; + +import graphql.Internal; +import org.reactivestreams.Subscriber; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import java.util.function.Function; + +/** + * This subscriber can be used to map between a {@link org.reactivestreams.Publisher} of U + * elements and map them into {@link CompletionStage} of D promises, and it keeps them in the order + * the Publisher provided them. + * + * @param published upstream elements + * @param mapped downstream values + */ +@Internal +public class CompletionStageOrderedSubscriber extends CompletionStageSubscriber implements Subscriber { + + public CompletionStageOrderedSubscriber(Function> mapper, Subscriber downstreamSubscriber) { + super(mapper, downstreamSubscriber); + } + + @Override + protected void whenNextFinished(CompletionStage completionStage, D d, Throwable throwable) { + try { + if (throwable != null) { + handleThrowableDuringMapping(throwable); + } else { + emptyInFlightQueueIfWeCan(); + } + } finally { + boolean empty = inFlightQIsEmpty(); + finallyAfterEachPromiseFinishes(empty); + } + } + + private void emptyInFlightQueueIfWeCan() { + // done inside a memory lock, so we cant offer new CFs to the queue + // until we have processed any completed ones from the start of + // the queue. + lock.runLocked(() -> { + // + // from the top of the in flight queue, take all the CFs that have + // completed... but stop if they are not done + while (!inFlightDataQ.isEmpty()) { + CompletionStage cs = inFlightDataQ.peek(); + if (cs != null) { + // + CompletableFuture cf = cs.toCompletableFuture(); + if (cf.isDone()) { + // take it off the queue + inFlightDataQ.poll(); + D value; + try { + //noinspection unchecked + value = (D) cf.join(); + } catch (RuntimeException rte) { + // + // if we get an exception while joining on a value, we + // send it into the exception handling and break out + handleThrowableDuringMapping(cfExceptionUnwrap(rte)); + break; + } + downstreamSubscriber.onNext(value); + } else { + // if the CF is not done, then we have to stop processing + // to keep the results in order inside the inFlightQueue + break; + } + } + } + }); + } + + private Throwable cfExceptionUnwrap(Throwable throwable) { + if (throwable instanceof CompletionException & throwable.getCause() != null) { + return throwable.getCause(); + } + return throwable; + } +} diff --git a/src/main/java/graphql/execution/reactive/CompletionStageSubscriber.java b/src/main/java/graphql/execution/reactive/CompletionStageSubscriber.java new file mode 100644 index 0000000000..b185ce9bba --- /dev/null +++ b/src/main/java/graphql/execution/reactive/CompletionStageSubscriber.java @@ -0,0 +1,201 @@ +package graphql.execution.reactive; + +import graphql.Internal; +import graphql.util.LockKit; +import org.jspecify.annotations.NonNull; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +import java.util.ArrayDeque; +import java.util.Queue; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; +import java.util.function.Function; + +/** + * This subscriber can be used to map between a {@link org.reactivestreams.Publisher} of U + * elements and map them into {@link CompletionStage} of D promises. + * + * @param published upstream elements + * @param mapped downstream values + */ +@Internal +public class CompletionStageSubscriber implements Subscriber { + protected final Function> mapper; + protected final Subscriber downstreamSubscriber; + protected Subscription delegatingSubscription; + protected final Queue> inFlightDataQ; + protected final LockKit.ReentrantLock lock = new LockKit.ReentrantLock(); + protected final AtomicReference onCompleteRun; + protected final AtomicBoolean isTerminal; + + public CompletionStageSubscriber(Function> mapper, Subscriber downstreamSubscriber) { + this.mapper = mapper; + this.downstreamSubscriber = downstreamSubscriber; + inFlightDataQ = new ArrayDeque<>(); + onCompleteRun = new AtomicReference<>(); + isTerminal = new AtomicBoolean(false); + } + + /** + * Get instance of downstream subscriber + * + * @return {@link Subscriber} + */ + public Subscriber getDownstreamSubscriber() { + return downstreamSubscriber; + } + + @Override + public void onSubscribe(Subscription subscription) { + delegatingSubscription = new DelegatingSubscription(subscription); + downstreamSubscriber.onSubscribe(delegatingSubscription); + } + + @Override + public void onNext(U u) { + // for safety - no more data after we have called done/error - we should not get this BUT belts and braces + if (isTerminal()) { + return; + } + try { + CompletionStage completionStage = mapper.apply(u); + offerToInFlightQ(completionStage); + completionStage.whenComplete(whenComplete(completionStage)); + } catch (RuntimeException throwable) { + handleThrowableDuringMapping(throwable); + } + } + + @NonNull + private BiConsumer whenComplete(CompletionStage completionStage) { + return (d, throwable) -> { + if (isTerminal()) { + return; + } + whenNextFinished(completionStage, d, throwable); + }; + } + + /** + * This is called as each mapped {@link CompletionStage} completes with + * a value or exception + * + * @param completionStage the completion stage that has completed + * @param d the value completed + * @param throwable or the throwable that happened during completion + */ + protected void whenNextFinished(CompletionStage completionStage, D d, Throwable throwable) { + try { + if (throwable != null) { + handleThrowableDuringMapping(throwable); + } else { + downstreamSubscriber.onNext(d); + } + } finally { + boolean empty = removeFromInFlightQAndCheckIfEmpty(completionStage); + finallyAfterEachPromiseFinishes(empty); + } + } + + protected void finallyAfterEachPromiseFinishes(boolean isInFlightEmpty) { + // + // if the runOnCompleteOrErrorRun runnable is set, the upstream has + // called onComplete() already, but the CFs have not all completed + // yet, so we have to check whenever a CF completes + // + Runnable runOnCompleteOrErrorRun = onCompleteRun.get(); + if (isInFlightEmpty && runOnCompleteOrErrorRun != null) { + onCompleteRun.set(null); + runOnCompleteOrErrorRun.run(); + } + } + + protected void handleThrowableDuringMapping(Throwable throwable) { + // only do this once + if (isTerminal.compareAndSet(false, true)) { + downstreamSubscriber.onError(throwable); + // + // Reactive semantics say that IF an exception happens on a publisher, + // then onError is called and no more messages flow. But since the exception happened + // during the mapping, the upstream publisher does not know about this. + // So we cancel to bring the semantics back together, that is as soon as an exception + // has happened, no more messages flow + // + delegatingSubscription.cancel(); + + cancelInFlightFutures(); + } + } + + @Override + public void onError(Throwable t) { + // we immediately terminate - we don't wait for any promises to complete + if (isTerminal.compareAndSet(false, true)) { + downstreamSubscriber.onError(t); + cancelInFlightFutures(); + } + } + + @Override + public void onComplete() { + onComplete(() -> { + if (isTerminal.compareAndSet(false, true)) { + downstreamSubscriber.onComplete(); + } + }); + } + + private void onComplete(Runnable doneCodeToRun) { + if (inFlightQIsEmpty()) { + // run right now + doneCodeToRun.run(); + } else { + onCompleteRun.set(doneCodeToRun); + } + } + + protected void offerToInFlightQ(CompletionStage completionStage) { + lock.runLocked(() -> + inFlightDataQ.offer(completionStage) + ); + } + + private boolean removeFromInFlightQAndCheckIfEmpty(CompletionStage completionStage) { + // uncontested locks in java are cheap - we don't expect much contention here + return lock.callLocked(() -> { + inFlightDataQ.remove(completionStage); + return inFlightDataQ.isEmpty(); + }); + } + + /** + * If the promise is backed by frameworks such as Reactor, then the cancel() + * can cause them to propagate the cancel back into the reactive chain + */ + private void cancelInFlightFutures() { + lock.runLocked(() -> { + while (!inFlightDataQ.isEmpty()) { + CompletionStage cs = inFlightDataQ.poll(); + if (cs != null) { + cs.toCompletableFuture().cancel(false); + } + } + }); + } + + protected boolean inFlightQIsEmpty() { + return lock.callLocked(inFlightDataQ::isEmpty); + } + + /** + * The two terminal states are onComplete or onError + * + * @return true if it's in a terminal state + */ + protected boolean isTerminal() { + return isTerminal.get(); + } +} diff --git a/src/main/java/graphql/execution/reactive/DelegatingSubscription.java b/src/main/java/graphql/execution/reactive/DelegatingSubscription.java index 8918de578e..e8a3ff9df3 100644 --- a/src/main/java/graphql/execution/reactive/DelegatingSubscription.java +++ b/src/main/java/graphql/execution/reactive/DelegatingSubscription.java @@ -1,5 +1,6 @@ package graphql.execution.reactive; +import graphql.PublicApi; import org.reactivestreams.Subscription; import static graphql.Assert.assertNotNull; @@ -7,6 +8,7 @@ /** * A simple subscription that delegates to another */ +@PublicApi public class DelegatingSubscription implements Subscription { private final Subscription upstreamSubscription; @@ -23,4 +25,12 @@ public void request(long n) { public void cancel() { upstreamSubscription.cancel(); } + + /** + * Get instance of upstreamSubscription + * @return {@link Subscription} + */ + public Subscription getUpstreamSubscription() { + return upstreamSubscription; + } } diff --git a/src/main/java/graphql/execution/reactive/NonBlockingMutexExecutor.java b/src/main/java/graphql/execution/reactive/NonBlockingMutexExecutor.java index 28a86cf685..0b8397d602 100644 --- a/src/main/java/graphql/execution/reactive/NonBlockingMutexExecutor.java +++ b/src/main/java/graphql/execution/reactive/NonBlockingMutexExecutor.java @@ -2,6 +2,7 @@ import graphql.Internal; +import org.jspecify.annotations.NonNull; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; @@ -12,37 +13,38 @@ /** * Executor that provides mutual exclusion between the operations submitted to it, * without blocking. - * + *

* If an operation is submitted to this executor while no other operation is * running, it will run immediately. - * + *

* If an operation is submitted to this executor while another operation is * running, it will be added to a queue of operations to run, and the executor will * return. The thread currently running an operation will end up running the * operation just submitted. - * + *

* Operations submitted to this executor should run fast, as they can end up running * on other threads and interfere with the operation of other threads. - * + *

* This executor can also be used to address infinite recursion problems, as * operations submitted recursively will run sequentially. + *

* - * - * Inspired by Public Domain CC0 code at h - * https://github.com/jroper/reactive-streams-servlet/tree/master/reactive-streams-servlet/src/main/java/org/reactivestreams/servlet + * Inspired by Public Domain CC0 code at + * ... */ @Internal class NonBlockingMutexExecutor implements Executor { private final AtomicReference last = new AtomicReference<>(); @Override - public void execute(final Runnable command) { - final RunNode newNode = new RunNode(assertNotNull(command, "Runnable must not be null")); + public void execute(final @NonNull Runnable command) { + final RunNode newNode = new RunNode(assertNotNull(command, "Runnable must not be null")); final RunNode prevLast = last.getAndSet(newNode); - if (prevLast != null) + if (prevLast != null) { prevLast.lazySet(newNode); - else + } else { runAll(newNode); + } } private void reportFailure(final Thread runner, final Throwable thrown) { @@ -74,9 +76,9 @@ private void runAll(RunNode next) { if (last.compareAndSet(current, null)) { return; // end-of-queue: we're done. } else { - //noinspection StatementWithEmptyBody while ((next = current.get()) == null) { - // Thread.onSpinWait(); in Java 9 + // hint to the CPU we are actively waiting + Thread.onSpinWait(); } } } @@ -91,4 +93,4 @@ private RunNode(final Runnable runnable) { } } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/execution/reactive/ReactiveSupport.java b/src/main/java/graphql/execution/reactive/ReactiveSupport.java new file mode 100644 index 0000000000..c513cc75a5 --- /dev/null +++ b/src/main/java/graphql/execution/reactive/ReactiveSupport.java @@ -0,0 +1,198 @@ +package graphql.execution.reactive; + +import graphql.DuckTyped; +import graphql.Internal; +import org.reactivestreams.FlowAdapters; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Flow; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +/** + * This provides support for a DataFetcher to be able to + * return a reactive streams {@link Publisher} or Java JDK {@link Flow.Publisher} + * as a value, and it can be turned into a {@link CompletableFuture} + * that we can get an async value from. + */ +@Internal +public class ReactiveSupport { + + @DuckTyped(shape = "CompletableFuture | Object") + public static Object fetchedObject(Object fetchedObject) { + if (fetchedObject instanceof Flow.Publisher) { + return flowPublisherToCF((Flow.Publisher) fetchedObject); + } + if (fetchedObject instanceof Publisher) { + return flowPublisherToCF(FlowAdapters.toFlowPublisher((Publisher) fetchedObject)); + } + return fetchedObject; + } + + private static CompletableFuture flowPublisherToCF(Flow.Publisher publisher) { + FlowPublisherToCompletableFuture cf = new FlowPublisherToCompletableFuture<>(); + publisher.subscribe(cf); + return cf; + } + + /** + * The implementations between reactive Publishers and Flow.Publishers are almost exactly the same except the + * subscription class is different. So this is a common class that contains most of the common logic + * + * @param for two + * @param for subscription + */ + private static abstract class PublisherToCompletableFuture extends CompletableFuture { + + private final AtomicReference subscriptionRef = new AtomicReference<>(); + + abstract void doSubscriptionCancel(S s); + + @SuppressWarnings("SameParameterValue") + abstract void doSubscriptionRequest(S s, long n); + + private boolean validateSubscription(S current, S next) { + Objects.requireNonNull(next, "Subscription cannot be null"); + if (current != null) { + doSubscriptionCancel(next); + return false; + } + return true; + } + + /** + * This overrides the {@link CompletableFuture#cancel(boolean)} method + * such that subscription is also cancelled. + * + * @param mayInterruptIfRunning this value has no effect in this + * implementation because interrupts are not used to control + * processing. + * @return a boolean if it was cancelled + */ + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + boolean cancelled = super.cancel(mayInterruptIfRunning); + if (cancelled) { + S s = subscriptionRef.getAndSet(null); + if (s != null) { + doSubscriptionCancel(s); + } + } + return cancelled; + } + + void onSubscribeImpl(S s) { + if (validateSubscription(subscriptionRef.getAndSet(s), s)) { + doSubscriptionRequest(s, Long.MAX_VALUE); + } + } + + void onNextImpl(T t) { + S s = subscriptionRef.getAndSet(null); + if (s != null) { + complete(t); + doSubscriptionCancel(s); + } + } + + void onErrorImpl(Throwable t) { + if (subscriptionRef.getAndSet(null) != null) { + completeExceptionally(t); + } + } + + void onCompleteImpl() { + if (subscriptionRef.getAndSet(null) != null) { + complete(null); + } + } + } + + private static class FlowPublisherToCompletableFuture extends PublisherToCompletableFuture implements Flow.Subscriber { + + @Override + void doSubscriptionCancel(Flow.Subscription subscription) { + subscription.cancel(); + } + + @Override + void doSubscriptionRequest(Flow.Subscription subscription, long n) { + subscription.request(n); + } + + @Override + public void onSubscribe(Flow.Subscription s) { + onSubscribeImpl(s); + } + + @Override + public void onNext(T t) { + onNextImpl(t); + } + + @Override + public void onError(Throwable t) { + onErrorImpl(t); + } + + @Override + public void onComplete() { + onCompleteImpl(); + } + } + + /** + * Our reactive {@link SingleSubscriberPublisher} supports only a single subscription + * so this can be used a delegate to perform a call back when the given Publisher + * actually finishes without adding an extra subscription to the delegate Publisher + * + * @param publisher the publisher to wrap + * @param atTheEndCallback the callback when the {@link Publisher} has finished + * @param for two + */ + public static Publisher whenPublisherFinishes(Publisher publisher, Consumer atTheEndCallback) { + return new AtTheEndPublisher<>(publisher, atTheEndCallback); + } + + static class AtTheEndPublisher implements Publisher { + + private final Publisher delegatePublisher; + private final Consumer atTheEndCallback; + + public AtTheEndPublisher(Publisher delegatePublisher, Consumer atTheEndCallback) { + this.delegatePublisher = delegatePublisher; + this.atTheEndCallback = atTheEndCallback; + } + + @Override + public void subscribe(Subscriber originalSubscriber) { + delegatePublisher.subscribe(new Subscriber<>() { + @Override + public void onSubscribe(Subscription s) { + originalSubscriber.onSubscribe(s); + } + + @Override + public void onNext(T t) { + originalSubscriber.onNext(t); + } + + @Override + public void onError(Throwable t) { + originalSubscriber.onError(t); + atTheEndCallback.accept(t); + } + + @Override + public void onComplete() { + originalSubscriber.onComplete(); + atTheEndCallback.accept(null); + } + }); + } + } +} diff --git a/src/main/java/graphql/execution/reactive/SingleSubscriberPublisher.java b/src/main/java/graphql/execution/reactive/SingleSubscriberPublisher.java index c6774fa3a5..628d148ddd 100644 --- a/src/main/java/graphql/execution/reactive/SingleSubscriberPublisher.java +++ b/src/main/java/graphql/execution/reactive/SingleSubscriberPublisher.java @@ -9,6 +9,7 @@ import java.util.concurrent.ConcurrentLinkedDeque; import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertNotNullWithNPE; /** * A Publisher of things that are buffered and handles a single subscriber at a time. @@ -59,7 +60,10 @@ public SingleSubscriberPublisher(OnSubscriptionCallback subscriptionCallback) { * @param data the data to offer */ public void offer(T data) { - mutex.execute(() -> dataQ.offer(data)); + mutex.execute(() -> { + dataQ.offer(data); + maybeReadInMutex(); + }); } /** @@ -98,7 +102,7 @@ private void handleOnComplete() { @Override public void subscribe(Subscriber subscriber) { - assertNotNull(subscriber, "Subscriber passed to subscribe must not be null"); + assertNotNullWithNPE(subscriber, "Subscriber passed to subscribe must not be null"); mutex.execute(() -> { if (this.subscriber == null) { this.subscriber = subscriber; diff --git a/src/main/java/graphql/execution/reactive/SubscriptionPublisher.java b/src/main/java/graphql/execution/reactive/SubscriptionPublisher.java new file mode 100644 index 0000000000..4951b451df --- /dev/null +++ b/src/main/java/graphql/execution/reactive/SubscriptionPublisher.java @@ -0,0 +1,60 @@ +package graphql.execution.reactive; + +import graphql.ExecutionResult; +import graphql.Internal; +import graphql.PublicApi; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; + +import java.util.concurrent.CompletionStage; +import java.util.function.Consumer; +import java.util.function.Function; + + +/** + * Subscription queries return an instance of this class in the {@link ExecutionResult} data element + * for the subscribed field. + * + *
{@code
+ *      ExecutionResult er = graphQL.execute("subscription s { onEntityChanged(id : "1") { selection1, selection2 }}")
+ *      SubscriptionPublisher eventPublisher = er.getData("onEntityChanged")
+ * }
+ * 
+ */ +@SuppressWarnings("ReactiveStreamsPublisherImplementation") +@PublicApi +public class SubscriptionPublisher implements Publisher { + + private final CompletionStageMappingPublisher mappingPublisher; + private final Publisher publisher; + + /** + * Subscription consuming code is not expected to create instances of this class + * + * @param upstreamPublisher the original publisher of objects that then have a graphql selection set applied to them + * @param mapper a mapper that turns object into promises to execution results which are then published on this stream + * @param keepOrdered this indicates that the order of results should be kep in the same order as the source events arrive + */ + @Internal + public SubscriptionPublisher(Publisher upstreamPublisher, Function> mapper, boolean keepOrdered, Consumer whenDone) { + if (keepOrdered) { + mappingPublisher = new CompletionStageMappingOrderedPublisher<>(upstreamPublisher, mapper); + } else { + mappingPublisher = new CompletionStageMappingPublisher<>(upstreamPublisher, mapper); + } + publisher = ReactiveSupport.whenPublisherFinishes(mappingPublisher, whenDone); + } + + /** + * @return the underlying Publisher that was providing raw objects to the subscription field, whose published values are then mapped + * to execution results + */ + public Publisher getUpstreamPublisher() { + return mappingPublisher.getUpstreamPublisher(); + } + + @Override + public void subscribe(Subscriber subscriber) { + publisher.subscribe(subscriber); + } +} diff --git a/src/main/java/graphql/execution/values/InputInterceptor.java b/src/main/java/graphql/execution/values/InputInterceptor.java new file mode 100644 index 0000000000..0fb7534d59 --- /dev/null +++ b/src/main/java/graphql/execution/values/InputInterceptor.java @@ -0,0 +1,42 @@ +package graphql.execution.values; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.schema.GraphQLInputType; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Locale; + +/** + * This INTERNAL class can be used to intercept input values before they are coerced into runtime values + * by the {@link graphql.execution.ValuesResolver} code. + *

+ * You could use it to observe input values and optionally change them. Perhaps some sort of migration of data + * needs to happen, and you need to know what data you are getting in type terms. This would help you do that. + *

+ * If this is present in a {@link GraphQLContext} it will be called. By default, it is not present + * so no calls to it will be made. + *

+ * There is a performance aspect to using this code. If you take too long to return values then you + * are going to slow down your system depending on how big your input objects are. + */ +@Internal +public interface InputInterceptor { + + /** + * This is called with a value that is to be presented to the {@link graphql.execution.ValuesResolver} code. The values + * may be scalars, enums and complex input types. + * + * @param value the input value that can be null + * @param graphQLType the input type + * @param graphqlContext the graphql context in play + * @param locale the locale in play + * + * @return a value that may differ from the original value + */ + Object intercept(@Nullable Object value, + @NonNull GraphQLInputType graphQLType, + @NonNull GraphQLContext graphqlContext, + @NonNull Locale locale); +} diff --git a/src/main/java/graphql/execution/values/legacycoercing/LegacyCoercingInputInterceptor.java b/src/main/java/graphql/execution/values/legacycoercing/LegacyCoercingInputInterceptor.java new file mode 100644 index 0000000000..6ac9041be4 --- /dev/null +++ b/src/main/java/graphql/execution/values/legacycoercing/LegacyCoercingInputInterceptor.java @@ -0,0 +1,179 @@ +package graphql.execution.values.legacycoercing; + +import graphql.GraphQLContext; +import graphql.Scalars; +import graphql.execution.values.InputInterceptor; +import graphql.scalar.CoercingUtil; +import graphql.schema.GraphQLInputType; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.math.BigDecimal; +import java.util.Locale; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +import static graphql.Assert.assertNotNull; +import static graphql.scalar.CoercingUtil.isNumberIsh; + +public class LegacyCoercingInputInterceptor implements InputInterceptor { + + /** + * This will ONLY observe legacy values and invoke the callback when it gets one. you can use this to enumerate how many + * legacy values are hitting you graphql implementation + * + * @param observerCallback a callback allowing you to observe a legacy scalar value + * + * @return an InputInterceptor that only observes values + */ + public static LegacyCoercingInputInterceptor observesValues(BiConsumer observerCallback) { + return new LegacyCoercingInputInterceptor(((input, graphQLInputType) -> { + observerCallback.accept(input, graphQLInputType); + return input; + })); + } + + /** + * This will change legacy values as it encounters them to something acceptable to the more strict coercion rules. + * + * @return an InputInterceptor that migrates values to a more strict value + */ + public static LegacyCoercingInputInterceptor migratesValues() { + return migratesValues((input, type) -> { + }); + } + + /** + * This will change legacy values as it encounters them to something acceptable to the more strict coercion rules. + * The observer callback will be invoked if it detects a legacy value that it will change. + * + * @param observerCallback a callback allowing you to observe a legacy scalar value before it is migrated + * + * @return an InputInterceptor that both observes values and migrates them to a more strict value + */ + public static LegacyCoercingInputInterceptor migratesValues(BiConsumer observerCallback) { + return new LegacyCoercingInputInterceptor(((input, graphQLInputType) -> { + observerCallback.accept(input, graphQLInputType); + if (Scalars.GraphQLBoolean.equals(graphQLInputType)) { + return coerceLegacyBooleanValue(input); + } + if (Scalars.GraphQLFloat.equals(graphQLInputType)) { + return coerceLegacyFloatValue(input); + } + if (Scalars.GraphQLInt.equals(graphQLInputType)) { + return coerceLegacyIntValue(input); + } + if (Scalars.GraphQLString.equals(graphQLInputType)) { + return coerceLegacyStringValue(input); + } + return input; + })); + } + + private final BiFunction behavior; + + private LegacyCoercingInputInterceptor(BiFunction behavior) { + this.behavior = assertNotNull(behavior); + } + + @Override + public Object intercept(@Nullable Object input, @NonNull GraphQLInputType graphQLType, @NonNull GraphQLContext graphqlContext, @NonNull Locale locale) { + if (isLegacyValue(input, graphQLType)) { + // we ONLY apply the new behavior IF it's an old acceptable legacy value. + // so for compliant values - we change nothing and invoke no behaviour + // and for values that would not coerce anyway, we also invoke no behavior + return behavior.apply(input, graphQLType); + } + return input; + } + + @SuppressWarnings("RedundantIfStatement") + static boolean isLegacyValue(Object input, GraphQLInputType graphQLType) { + if (Scalars.GraphQLBoolean.equals(graphQLType)) { + return isLegacyBooleanValue(input); + } else if (Scalars.GraphQLFloat.equals(graphQLType)) { + return isLegacyFloatValue(input); + } else if (Scalars.GraphQLInt.equals(graphQLType)) { + return isLegacyIntValue(input); + } else if (Scalars.GraphQLString.equals(graphQLType)) { + return isLegacyStringValue(input); + } else { + return false; + } + } + + static boolean isLegacyBooleanValue(Object input) { + return input instanceof String || CoercingUtil.isNumberIsh(input); + } + + static boolean isLegacyFloatValue(Object input) { + return input instanceof String; + } + + static boolean isLegacyIntValue(Object input) { + return input instanceof String; + } + + static boolean isLegacyStringValue(Object input) { + return !(input instanceof String); + } + + static Object coerceLegacyBooleanValue(Object input) { + if (input instanceof String) { + String lStr = ((String) input).toLowerCase(); + if (lStr.equals("true")) { + return true; + } + if (lStr.equals("false")) { + return false; + } + return input; + } else if (isNumberIsh(input)) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + // this should never happen because String is handled above + return input; + } + return value.compareTo(BigDecimal.ZERO) != 0; + } + // unchanged + return input; + } + + static Object coerceLegacyFloatValue(Object input) { + if (isNumberIsh(input)) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + return input; + } + return value.doubleValue(); + } + return input; + } + + static Object coerceLegacyIntValue(Object input) { + if (isNumberIsh(input)) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + return input; + } + try { + return value.intValueExact(); + } catch (ArithmeticException e) { + return input; + } + } + return input; + } + + + static Object coerceLegacyStringValue(Object input) { + return String.valueOf(input); + } +} diff --git a/src/main/java/graphql/extensions/DefaultExtensionsMerger.java b/src/main/java/graphql/extensions/DefaultExtensionsMerger.java new file mode 100644 index 0000000000..3c3aa3d8a9 --- /dev/null +++ b/src/main/java/graphql/extensions/DefaultExtensionsMerger.java @@ -0,0 +1,74 @@ +package graphql.extensions; + +import com.google.common.collect.Sets; +import graphql.Internal; +import org.jspecify.annotations.NonNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +@Internal +public class DefaultExtensionsMerger implements ExtensionsMerger { + @Override + @NonNull + public Map merge(@NonNull Map leftMap, @NonNull Map rightMap) { + if (leftMap.isEmpty()) { + return mapCast(rightMap); + } + if (rightMap.isEmpty()) { + return mapCast(leftMap); + } + Map targetMap = new LinkedHashMap<>(); + Set leftKeys = leftMap.keySet(); + for (Object key : leftKeys) { + Object leftVal = leftMap.get(key); + if (rightMap.containsKey(key)) { + Object rightVal = rightMap.get(key); + targetMap.put(key, mergeObjects(leftVal, rightVal)); + } else { + targetMap.put(key, leftVal); + } + } + Sets.SetView rightOnlyKeys = Sets.difference(rightMap.keySet(), leftKeys); + for (Object key : rightOnlyKeys) { + Object rightVal = rightMap.get(key); + targetMap.put(key, rightVal); + } + return targetMap; + } + + private Object mergeObjects(Object leftVal, Object rightVal) { + if (leftVal instanceof Map && rightVal instanceof Map) { + return merge(mapCast(leftVal), mapCast(rightVal)); + } else if (leftVal instanceof Collection && rightVal instanceof Collection) { + // we append - no equality or merging here + return appendLists(leftVal, rightVal); + } else { + // we have some primitive - so prefer the right since it was encountered last + // and last write wins here + return rightVal; + } + } + + @NonNull + private List appendLists(Object leftVal, Object rightVal) { + List target = new ArrayList<>(listCast(leftVal)); + target.addAll(listCast(rightVal)); + return target; + } + + private Map mapCast(Object map) { + //noinspection unchecked + return (Map) map; + } + + private Collection listCast(Object collection) { + //noinspection unchecked + return (Collection) collection; + } +} diff --git a/src/main/java/graphql/extensions/ExtensionsBuilder.java b/src/main/java/graphql/extensions/ExtensionsBuilder.java new file mode 100644 index 0000000000..e65e315e2f --- /dev/null +++ b/src/main/java/graphql/extensions/ExtensionsBuilder.java @@ -0,0 +1,133 @@ +package graphql.extensions; + +import com.google.common.collect.ImmutableMap; +import graphql.ExecutionResult; +import graphql.PublicApi; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import static graphql.Assert.assertNotNull; + +/** + * This class can be used to help build the graphql `extensions` map. A series of changes to the extensions can + * be added and these will be merged together via a {@link ExtensionsMerger} implementation and that resultant + * map can be used as the `extensions` + *

+ * The engine will place a {@link ExtensionsBuilder} into the {@link graphql.GraphQLContext} (if one is not manually placed there) + * and hence {@link graphql.schema.DataFetcher}s can use it to build up extensions progressively. + *

+ * At the end of the execution, the {@link ExtensionsBuilder} will be used to build a graphql `extensions` map that + * is placed in the {@link ExecutionResult} + */ +@PublicApi +public class ExtensionsBuilder { + + // thread safe since there can be many changes say in DFs across threads + private final List> changes = new CopyOnWriteArrayList<>(); + private final ExtensionsMerger extensionsMerger; + + + private ExtensionsBuilder(ExtensionsMerger extensionsMerger) { + this.extensionsMerger = extensionsMerger; + } + + /** + * @return a new ExtensionsBuilder using a default merger + */ + public static ExtensionsBuilder newExtensionsBuilder() { + return new ExtensionsBuilder(ExtensionsMerger.DEFAULT); + } + + /** + * This creates a new ExtensionsBuilder with the provided {@link ExtensionsMerger} + * + * @param extensionsMerger the merging code to use + * + * @return a new ExtensionsBuilder using the provided merger + */ + public static ExtensionsBuilder newExtensionsBuilder(ExtensionsMerger extensionsMerger) { + return new ExtensionsBuilder(extensionsMerger); + } + + /** + * @return how many extension changes have been made so far + */ + public int getChangeCount() { + return changes.size(); + } + + /** + * Adds new values into the extension builder + * + * @param newValues the new values to add + * + * @return this builder for fluent style reasons + */ + public ExtensionsBuilder addValues(@NonNull Map newValues) { + assertNotNull(newValues); + if (!newValues.isEmpty()) { + changes.add(newValues); + } + return this; + } + + /** + * Adds a single new value into the extension builder + * + * @param key the key in the extensions + * @param value the value in the extensions + * + * @return this builder for fluent style reasons + */ + public ExtensionsBuilder addValue(@NonNull Object key, @Nullable Object value) { + assertNotNull(key); + return addValues(Collections.singletonMap(key, value)); + } + + /** + * This builds an extensions map from this builder, merging together the values provided + * + * @return a new extensions map + */ + public Map buildExtensions() { + if (changes.isEmpty()) { + return ImmutableMap.of(); + } + Map firstChange = changes.get(0); + if (changes.size() == 1) { + return firstChange; + } + Map outMap = new LinkedHashMap<>(firstChange); + for (int i = 1; i < changes.size(); i++) { + Map newMap = extensionsMerger.merge(outMap, changes.get(i)); + assertNotNull(outMap, "You MUST provide a non null Map from ExtensionsMerger.merge()"); + outMap = newMap; + } + return outMap; + } + + /** + * This sets new extensions into the provided {@link ExecutionResult}, overwriting any previous values + * + * @param executionResult the result to set these extensions into + * + * @return a new ExecutionResult with the extensions values in this builder + */ + public ExecutionResult setExtensions(ExecutionResult executionResult) { + assertNotNull(executionResult); + Map currentExtensions = executionResult.getExtensions(); + Map builderExtensions = buildExtensions(); + // if there was no extensions map before, and we are not adding anything new + // then leave it null + if (currentExtensions == null && builderExtensions.isEmpty()) { + return executionResult; + } + return executionResult.transform(builder -> builder.extensions(builderExtensions)); + } +} diff --git a/src/main/java/graphql/extensions/ExtensionsMerger.java b/src/main/java/graphql/extensions/ExtensionsMerger.java new file mode 100644 index 0000000000..9e4199ff3a --- /dev/null +++ b/src/main/java/graphql/extensions/ExtensionsMerger.java @@ -0,0 +1,45 @@ +package graphql.extensions; + +import graphql.PublicSpi; +import org.jspecify.annotations.NonNull; + +import java.util.Map; + +/** + * This interface is a callback asking code to merge two maps with an eye to creating + * the graphql `extensions` value. + *

+ * How best to merge two maps is hard to know up front. Should it be a shallow clone or a deep one, + * should keys be replaced or not and should lists of value be combined? The {@link ExtensionsMerger} is the + * interface asked to do this. + *

+ * This interface will be called repeatedly for each change that has been added to the {@link ExtensionsBuilder} and it is expected to merge the two maps as it sees fit + */ +@PublicSpi +public interface ExtensionsMerger { + + /** + * A default implementation will do the following + *

    + *
  • It will deep merge the maps
  • + *
  • It concatenate lists when they occur under the same key
  • + *
  • It will add any keys from the right hand side map that are not present in the left
  • + *
  • If a key is in both the left and right side, it will prefer the right hand side
  • + *
  • It will try to maintain key order if the maps are ordered
  • + *
+ */ + ExtensionsMerger DEFAULT = new DefaultExtensionsMerger(); + + /** + * Called to merge the map on the left with the map on the right according to whatever code strategy some-one might envisage + *

+ * The map on the left is guaranteed to have been encountered before the map on the right + * + * @param leftMap the map on the left + * @param rightMap the map on the right + * + * @return a non null merged map + */ + @NonNull + Map merge(@NonNull Map leftMap, @NonNull Map rightMap); +} diff --git a/src/main/java/graphql/i18n/I18n.java b/src/main/java/graphql/i18n/I18n.java new file mode 100644 index 0000000000..6898f7be8b --- /dev/null +++ b/src/main/java/graphql/i18n/I18n.java @@ -0,0 +1,94 @@ +package graphql.i18n; + +import graphql.Internal; +import graphql.VisibleForTesting; + +import java.text.MessageFormat; +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; + +@Internal +public class I18n { + + + /** + * This enum is a type safe way to control what resource bundle to load from + */ + public enum BundleType { + Parsing, + Scalars, + Validation, + Execution, + General; + + private final String baseName; + + BundleType() { + this.baseName = "i18n." + this.name(); + } + } + + private final ResourceBundle resourceBundle; + private final Locale locale; + + @VisibleForTesting + protected I18n(BundleType bundleType, Locale locale) { + assertNotNull(bundleType); + assertNotNull(locale); + this.locale = locale; + // load the resource bundle with this classes class loader - to help avoid confusion in complicated worlds + // like OSGI + this.resourceBundle = ResourceBundle.getBundle(bundleType.baseName, locale, I18n.class.getClassLoader()); } + + public Locale getLocale() { + return locale; + } + + public ResourceBundle getResourceBundle() { + return resourceBundle; + } + + public static I18n i18n(BundleType bundleType, Locale locale) { + return new I18n(bundleType, locale); + } + + + /** + * Creates an I18N message using the key and arguments + * + * @param msgKey the key in the underlying message bundle + * @param msgArgs the message arguments + * + * @return the formatted I18N message + */ + public String msg(String msgKey, Object... msgArgs) { + return msgImpl(msgKey, msgArgs); + } + + /** + * Creates an I18N message using the key and arguments + * + * @param msgKey the key in the underlying message bundle + * @param msgArgs the message arguments + * + * @return the formatted I18N message + */ + public String msg(String msgKey, List msgArgs) { + return msgImpl(msgKey, msgArgs.toArray()); + } + + private String msgImpl(String msgKey, Object[] msgArgs) { + String msgPattern = null; + try { + msgPattern = resourceBundle.getString(msgKey); + } catch (MissingResourceException e) { + assertShouldNeverHappen("There must be a resource bundle key called %s", msgKey); + } + return new MessageFormat(msgPattern).format(msgArgs); + } +} diff --git a/src/main/java/graphql/i18n/I18nMsg.java b/src/main/java/graphql/i18n/I18nMsg.java new file mode 100644 index 0000000000..2db09cc947 --- /dev/null +++ b/src/main/java/graphql/i18n/I18nMsg.java @@ -0,0 +1,42 @@ +package graphql.i18n; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * A class that represents the intention to create a I18n message + */ +public class I18nMsg { + private final String msgKey; + private final List msgArguments; + + public I18nMsg(String msgKey, List msgArguments) { + this.msgKey = msgKey; + this.msgArguments = msgArguments; + } + + public I18nMsg(String msgKey, Object... msgArguments) { + this.msgKey = msgKey; + this.msgArguments = asList(msgArguments); + } + + public String getMsgKey() { + return msgKey; + } + + public Object[] getMsgArguments() { + return msgArguments.toArray(); + } + + public I18nMsg addArgumentAt(int index, Object argument) { + List newArgs = new ArrayList<>(this.msgArguments); + newArgs.add(index, argument); + return new I18nMsg(this.msgKey, newArgs); + } + + public String toI18n(I18n i18n) { + return i18n.msg(msgKey, msgArguments); + } +} diff --git a/src/main/java/graphql/incremental/DeferPayload.java b/src/main/java/graphql/incremental/DeferPayload.java new file mode 100644 index 0000000000..ddec3d531b --- /dev/null +++ b/src/main/java/graphql/incremental/DeferPayload.java @@ -0,0 +1,92 @@ +package graphql.incremental; + +import graphql.ExecutionResult; +import graphql.ExperimentalApi; +import graphql.GraphQLError; +import org.jspecify.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Represents a defer payload + */ +@ExperimentalApi +public class DeferPayload extends IncrementalPayload { + private final Object data; + + private DeferPayload(Object data, List path, String label, List errors, Map extensions) { + super(path, label, errors, extensions); + this.data = data; + } + + /** + * @param the type to cast the result to + * @return the resolved data + */ + @Nullable + public T getData() { + // noinspection unchecked + return (T) this.data; + } + + /** + * @return a map of this payload that strictly follows the spec + */ + @Override + public Map toSpecification() { + Map map = new LinkedHashMap<>(super.toSpecification()); + map.put("data", data); + return map; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), data); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + if (!super.equals(obj)) return false; + DeferPayload that = (DeferPayload) obj; + return Objects.equals(data, that.data); + } + + /** + * @return a {@link DeferPayload.Builder} that can be used to create an instance of {@link DeferPayload} + */ + public static DeferPayload.Builder newDeferredItem() { + return new DeferPayload.Builder(); + } + + public static class Builder extends IncrementalPayload.Builder { + private Object data = null; + + public Builder data(Object data) { + this.data = data; + return this; + } + + public Builder from(DeferPayload deferredItem) { + super.from(deferredItem); + this.data = deferredItem.data; + return this; + } + + public Builder from(ExecutionResult executionResult) { + this.data = executionResult.getData(); + this.errors = executionResult.getErrors(); + this.extensions = executionResult.getExtensions(); + + return this; + } + + public DeferPayload build() { + return new DeferPayload(data, this.path, this.label, this.errors, this.extensions); + } + } +} diff --git a/src/main/java/graphql/incremental/DelayedIncrementalPartialResult.java b/src/main/java/graphql/incremental/DelayedIncrementalPartialResult.java new file mode 100644 index 0000000000..5992e3c83a --- /dev/null +++ b/src/main/java/graphql/incremental/DelayedIncrementalPartialResult.java @@ -0,0 +1,43 @@ +package graphql.incremental; + +import graphql.ExperimentalApi; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +/** + * Represents a result that is delivered asynchronously, after the initial {@link IncrementalExecutionResult}. + *

+ * Multiple defer and/or stream payloads (represented by {@link IncrementalPayload}) can be part of the same + * {@link DelayedIncrementalPartialResult} + */ +@ExperimentalApi +public interface DelayedIncrementalPartialResult { + /** + * @return a list of defer and/or stream payloads. + */ + @Nullable + List getIncremental(); + + /** + * Indicates whether the stream will continue emitting {@link DelayedIncrementalPartialResult}s after this one. + *

+ * The value returned by this method should be "true" for all but the last response in the stream. The value of this + * entry is `false` for the last response of the stream. + * + * @return "true" if there are more responses in the stream, "false" otherwise. + */ + boolean hasNext(); + + /** + * @return a map of extensions or null if there are none + */ + @Nullable + Map getExtensions(); + + /** + * @return a map of the result that strictly follows the spec + */ + Map toSpecification(); +} diff --git a/src/main/java/graphql/incremental/DelayedIncrementalPartialResultImpl.java b/src/main/java/graphql/incremental/DelayedIncrementalPartialResultImpl.java new file mode 100644 index 0000000000..3412d77298 --- /dev/null +++ b/src/main/java/graphql/incremental/DelayedIncrementalPartialResultImpl.java @@ -0,0 +1,89 @@ +package graphql.incremental; + +import graphql.ExperimentalApi; +import graphql.util.FpKit; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@ExperimentalApi +public class DelayedIncrementalPartialResultImpl implements DelayedIncrementalPartialResult { + private final List incrementalItems; + private final boolean hasNext; + private final Map extensions; + + private DelayedIncrementalPartialResultImpl(Builder builder) { + this.incrementalItems = builder.incrementalItems; + this.hasNext = builder.hasNext; + this.extensions = builder.extensions; + } + + @Override + public List getIncremental() { + return this.incrementalItems; + } + + @Override + public boolean hasNext() { + return this.hasNext; + } + + @Override + public Map getExtensions() { + return this.extensions; + } + + @Override + public Map toSpecification() { + Map result = new LinkedHashMap<>(); + result.put("hasNext", hasNext); + + if (extensions != null) { + result.put("extensions", extensions); + } + + if (incrementalItems != null) { + List> list = FpKit.arrayListSizedTo(incrementalItems); + for (IncrementalPayload incrementalItem : incrementalItems) { + list.add(incrementalItem.toSpecification()); + } + result.put("incremental", list); + } + + return result; + } + + /** + * @return a {@link Builder} that can be used to create an instance of {@link DelayedIncrementalPartialResultImpl} + */ + public static Builder newIncrementalExecutionResult() { + return new Builder(); + } + + public static class Builder { + private boolean hasNext = false; + private List incrementalItems = Collections.emptyList(); + private Map extensions; + + public Builder hasNext(boolean hasNext) { + this.hasNext = hasNext; + return this; + } + + public Builder incrementalItems(List incrementalItems) { + this.incrementalItems = incrementalItems; + return this; + } + + public Builder extensions(Map extensions) { + this.extensions = extensions; + return this; + } + + public DelayedIncrementalPartialResultImpl build() { + return new DelayedIncrementalPartialResultImpl(this); + } + } +} diff --git a/src/main/java/graphql/incremental/IncrementalExecutionResult.java b/src/main/java/graphql/incremental/IncrementalExecutionResult.java new file mode 100644 index 0000000000..7d59fbe958 --- /dev/null +++ b/src/main/java/graphql/incremental/IncrementalExecutionResult.java @@ -0,0 +1,116 @@ +package graphql.incremental; + +import graphql.ExecutionResult; +import graphql.ExperimentalApi; +import org.jspecify.annotations.Nullable; +import org.reactivestreams.Publisher; + +import java.util.List; + +/** + * A result that is part of an execution that includes incrementally delivered data (data has been deferred of streamed). + *

+ * For example, this query + *

+ * query {
+ *   person(id: "cGVvcGxlOjE=") {
+ *     ...HomeWorldFragment @defer(label: "homeWorldDefer")
+ *     name
+ *     films @stream(initialCount: 1, label: "filmsStream") {
+ *       title
+ *     }
+ *   }
+ * }
+ * fragment HomeWorldFragment on Person {
+ *   homeWorld {
+ *     name
+ *   }
+ * }
+ * 
+ * Could result on an incremental response with the following payloads (in JSON format here for simplicity). + *

+ * Response 1, the initial response does not contain any deferred or streamed results. + *

+ * {
+ *   "data": {
+ *     "person": {
+ *       "name": "Luke Skywalker",
+ *       "films": [{ "title": "A New Hope" }]
+ *     }
+ *   },
+ *   "hasNext": true
+ * }
+ * 
+ * + * Response 2, contains the defer payload and the first stream payload. + *
+ * {
+ *   "incremental": [
+ *     {
+ *       "label": "homeWorldDefer",
+ *       "path": ["person"],
+ *       "data": { "homeWorld": { "name": "Tatooine" } }
+ *     },
+ *     {
+ *       "label": "filmsStream",
+ *       "path": ["person", "films", 1],
+ *       "items": [{ "title": "The Empire Strikes Back" }]
+ *     }
+ *   ],
+ *   "hasNext": true
+ * }
+ * 
+ * + * Response 3, contains the final stream payload. Note how "hasNext" is "false", indicating this is the final response. + *
+ * {
+ *   "incremental": [
+ *     {
+ *       "label": "filmsStream",
+ *       "path": ["person", "films", 2],
+ *       "items": [{ "title": "Return of the Jedi" }]
+ *     }
+ *   ],
+ *   "hasNext": false
+ * }
+ * 
+ * + *

+ * This implementation is based on the state of Defer/Stream PR + * More specifically at the state of this + * commit + *

+ * The execution behaviour should match what we get from running Apollo Server 4.9.5 with graphql-js v17.0.0-alpha.2 + */ +@ExperimentalApi +public interface IncrementalExecutionResult extends ExecutionResult { + /** + * Indicates whether there are pending incremental data. + * + * @return "true" if there are incremental data, "false" otherwise. + */ + boolean hasNext(); + + /** + * Returns a list of defer and/or stream payloads that the execution engine decided (for whatever reason) to resolve at the same time as the initial payload. + *

+ * (...)this field may appear on both the initial and subsequent values. + *

+ * source + * + * @return a list of Stream and/or Defer payloads that were resolved at the same time as the initial payload. + */ + @Nullable + List getIncremental(); + + /** + * This method will return a {@link Publisher} of deferred results. No field processing will be done + * until a {@link org.reactivestreams.Subscriber} is attached to this publisher. + *

+ * Once a {@link org.reactivestreams.Subscriber} is attached the deferred field result processing will be + * started and published as a series of events. + * + * @return a {@link Publisher} that clients can subscribe to receive incremental payloads. + */ + Publisher getIncrementalItemPublisher(); +} diff --git a/src/main/java/graphql/incremental/IncrementalExecutionResultImpl.java b/src/main/java/graphql/incremental/IncrementalExecutionResultImpl.java new file mode 100644 index 0000000000..d067ec1327 --- /dev/null +++ b/src/main/java/graphql/incremental/IncrementalExecutionResultImpl.java @@ -0,0 +1,114 @@ +package graphql.incremental; + +import graphql.ExecutionResult; +import graphql.ExecutionResultImpl; +import graphql.ExperimentalApi; +import org.jspecify.annotations.Nullable; +import org.reactivestreams.Publisher; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +@ExperimentalApi +public class IncrementalExecutionResultImpl extends ExecutionResultImpl implements IncrementalExecutionResult { + private final boolean hasNext; + private final List incremental; + private final Publisher incrementalItemPublisher; + + private IncrementalExecutionResultImpl(Builder builder) { + super(builder); + this.hasNext = builder.hasNext; + this.incremental = builder.incremental; + this.incrementalItemPublisher = builder.incrementalItemPublisher; + } + + @Override + public boolean hasNext() { + return this.hasNext; + } + + @Nullable + @Override + public List getIncremental() { + return this.incremental; + } + + @Override + public Publisher getIncrementalItemPublisher() { + return incrementalItemPublisher; + } + + /** + * @return a {@link Builder} that can be used to create an instance of {@link IncrementalExecutionResultImpl} + */ + public static Builder newIncrementalExecutionResult() { + return new Builder(); + } + + public static Builder fromExecutionResult(ExecutionResult executionResult) { + return new Builder().from(executionResult); + } + + public static Builder fromIncrementalExecutionResult(IncrementalExecutionResult executionResult) { + return new Builder().from(executionResult); + } + + @Override + public IncrementalExecutionResult transform(Consumer> builderConsumer) { + var builder = fromIncrementalExecutionResult(this); + builderConsumer.accept(builder); + return builder.build(); + } + + @Override + public Map toSpecification() { + Map map = new LinkedHashMap<>(super.toSpecification()); + map.put("hasNext", hasNext); + + if (this.incremental != null) { + LinkedList> linkedList = new LinkedList<>(); + for (IncrementalPayload incrementalPayload : this.incremental) { + linkedList.add(incrementalPayload.toSpecification()); + } + map.put("incremental", linkedList); + } + + return map; + } + + public static class Builder extends ExecutionResultImpl.Builder { + private boolean hasNext = true; + public List incremental; + private Publisher incrementalItemPublisher; + + public Builder hasNext(boolean hasNext) { + this.hasNext = hasNext; + return this; + } + + public Builder incremental(List incremental) { + this.incremental = incremental; + return this; + } + + public Builder incrementalItemPublisher(Publisher incrementalItemPublisher) { + this.incrementalItemPublisher = incrementalItemPublisher; + return this; + } + + public Builder from(IncrementalExecutionResult incrementalExecutionResult) { + super.from(incrementalExecutionResult); + this.hasNext = incrementalExecutionResult.hasNext(); + this.incremental = incrementalExecutionResult.getIncremental(); + this.incrementalItemPublisher = incrementalExecutionResult.getIncrementalItemPublisher(); + return this; + } + + public IncrementalExecutionResult build() { + return new IncrementalExecutionResultImpl(this); + } + } +} diff --git a/src/main/java/graphql/incremental/IncrementalPayload.java b/src/main/java/graphql/incremental/IncrementalPayload.java new file mode 100644 index 0000000000..742d857c89 --- /dev/null +++ b/src/main/java/graphql/incremental/IncrementalPayload.java @@ -0,0 +1,166 @@ +package graphql.incremental; + +import graphql.ExperimentalApi; +import graphql.GraphQLError; +import graphql.execution.ResultPath; +import graphql.util.FpKit; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Represents a payload that can be resolved after the initial response. + */ +@ExperimentalApi +public abstract class IncrementalPayload { + private final List path; + private final String label; + private final List errors; + private final transient Map extensions; + + protected IncrementalPayload(List path, String label, List errors, Map extensions) { + this.path = path; + this.errors = errors; + this.label = label; + this.extensions = extensions; + } + + /** + * @return list of field names and indices from root to the location of the corresponding `@defer` or `@stream` directive. + */ + public List getPath() { + return this.path; + } + + /** + * @return value derived from the corresponding `@defer` or `@stream` directive. + */ + @Nullable + public String getLabel() { + return label; + } + + /** + * @return a list of field errors encountered during execution. + */ + @Nullable + public List getErrors() { + return this.errors; + } + + /** + * @return a map of extensions or null if there are none + */ + @Nullable + public Map getExtensions() { + return this.extensions; + } + + public Map toSpecification() { + Map result = new LinkedHashMap<>(); + + result.put("path", path); + + if (label != null) { + result.put("label", label); + } + + if (errors != null && !errors.isEmpty()) { + result.put("errors", errorsToSpec(errors)); + } + if (extensions != null) { + result.put("extensions", extensions); + } + return result; + } + + protected Object errorsToSpec(List errors) { + List> list = FpKit.arrayListSizedTo(errors); + for (GraphQLError error : errors) { + list.add(error.toSpecification()); + } + return list; + } + + public int hashCode() { + return Objects.hash(path, label, errors, extensions); + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + IncrementalPayload that = (IncrementalPayload) obj; + return Objects.equals(path, that.path) && + Objects.equals(label, that.label) && + Objects.equals(errors, that.errors) && + Objects.equals(extensions, that.extensions); + } + + protected static abstract class Builder> { + protected List path; + protected String label; + protected List errors = new ArrayList<>(); + protected Map extensions; + + public T from(IncrementalPayload incrementalPayload) { + this.path = incrementalPayload.getPath(); + this.label = incrementalPayload.getLabel(); + if (incrementalPayload.getErrors() != null) { + this.errors = new ArrayList<>(incrementalPayload.getErrors()); + } + this.extensions = incrementalPayload.getExtensions(); + return (T) this; + } + + public T path(ResultPath path) { + if (path != null) { + this.path = path.toList(); + } + return (T) this; + } + + public T path(List path) { + this.path = path; + return (T) this; + } + + public T label(String label) { + this.label = label; + return (T) this; + } + + public T errors(List errors) { + this.errors = errors; + return (T) this; + } + + public T addErrors(List errors) { + this.errors.addAll(errors); + return (T) this; + } + + public T addError(GraphQLError error) { + this.errors.add(error); + return (T) this; + } + + public T extensions(Map extensions) { + this.extensions = extensions; + return (T) this; + } + + public T addExtension(String key, Object value) { + this.extensions = (this.extensions == null ? new LinkedHashMap<>() : this.extensions); + this.extensions.put(key, value); + return (T) this; + } + } +} diff --git a/src/main/java/graphql/incremental/StreamPayload.java b/src/main/java/graphql/incremental/StreamPayload.java new file mode 100644 index 0000000000..c8b0f652e8 --- /dev/null +++ b/src/main/java/graphql/incremental/StreamPayload.java @@ -0,0 +1,83 @@ +package graphql.incremental; + +import graphql.ExperimentalApi; +import graphql.GraphQLError; +import org.jspecify.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Represents a stream payload + */ +@ExperimentalApi +public class StreamPayload extends IncrementalPayload { + private final List items; + + private StreamPayload(List items, List path, String label, List errors, Map extensions) { + super(path, label, errors, extensions); + this.items = items; + } + + /** + * @param the type to cast the result to + * @return the resolved list of items + */ + @Nullable + public List getItems() { + // noinspection unchecked + return (List) this.items; + } + + /** + * @return a map of this payload that strictly follows the spec + */ + @Override + public Map toSpecification() { + Map map = new LinkedHashMap<>(super.toSpecification()); + map.put("items", items); + return map; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), items); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + if (!super.equals(obj)) return false; + StreamPayload that = (StreamPayload) obj; + return Objects.equals(items, that.items); + } + + /** + * @return a {@link Builder} that can be used to create an instance of {@link StreamPayload} + */ + public static StreamPayload.Builder newStreamedItem() { + return new StreamPayload.Builder(); + } + + public static class Builder extends IncrementalPayload.Builder { + private List items = null; + + public Builder items(List items) { + this.items = items; + return this; + } + + public Builder from(StreamPayload streamedItem) { + super.from(streamedItem); + this.items = streamedItem.items; + return this; + } + + public StreamPayload build() { + return new StreamPayload(items, this.path, this.label, this.errors, this.extensions); + } + } +} diff --git a/src/main/java/graphql/introspection/GoodFaithIntrospection.java b/src/main/java/graphql/introspection/GoodFaithIntrospection.java new file mode 100644 index 0000000000..ae7da12569 --- /dev/null +++ b/src/main/java/graphql/introspection/GoodFaithIntrospection.java @@ -0,0 +1,177 @@ +package graphql.introspection; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import graphql.ErrorClassification; +import graphql.ExecutionResult; +import graphql.GraphQLContext; +import graphql.GraphQLError; +import graphql.PublicApi; +import graphql.execution.AbortExecutionException; +import graphql.execution.ExecutionContext; +import graphql.language.SourceLocation; +import graphql.normalized.ExecutableNormalizedField; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.schema.FieldCoordinates; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; + +import static graphql.normalized.ExecutableNormalizedOperationFactory.Options; +import static graphql.normalized.ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation; +import static graphql.schema.FieldCoordinates.coordinates; + +/** + * This {@link graphql.execution.instrumentation.Instrumentation} ensure that a submitted introspection query is done in + * good faith. + *

+ * There are attack vectors where a crafted introspection query can cause the engine to spend too much time + * producing introspection data. This is especially true on large schemas with lots of types and fields. + *

+ * Schemas form a cyclic graph and hence it's possible to send in introspection queries that can reference those cycles + * and in large schemas this can be expensive and perhaps a "denial of service". + *

+ * This instrumentation only allows one __schema field or one __type field to be present, and it does not allow the `__Type` fields + * to form a cycle, i.e., that can only be present once. This allows the standard and common introspection queries to work + * so tooling such as graphiql can work. + */ +@PublicApi +public class GoodFaithIntrospection { + + /** + * Placing a boolean value under this key in the per request {@link GraphQLContext} will enable + * or disable Good Faith Introspection on that request. + */ + public static final String GOOD_FAITH_INTROSPECTION_DISABLED = "GOOD_FAITH_INTROSPECTION_DISABLED"; + + private static final AtomicBoolean ENABLED_STATE = new AtomicBoolean(true); + /** + * This is the maximum number of executable fields that can be in a good faith introspection query + */ + public static final int GOOD_FAITH_MAX_FIELDS_COUNT = 500; + /** + * This is the maximum depth a good faith introspection query can be + */ + public static final int GOOD_FAITH_MAX_DEPTH_COUNT = 20; + + /** + * @return true if good faith introspection is enabled + */ + public static boolean isEnabledJvmWide() { + return ENABLED_STATE.get(); + } + + /** + * This allows you to disable good faith introspection, which is on by default. + * + * @param flag the desired state + * + * @return the previous state + */ + public static boolean enabledJvmWide(boolean flag) { + return ENABLED_STATE.getAndSet(flag); + } + + private static final Map ALLOWED_FIELD_INSTANCES = Map.of( + coordinates("Query", "__schema"), 1 + , coordinates("Query", "__type"), 1 + + , coordinates("__Type", "fields"), 1 + , coordinates("__Type", "inputFields"), 1 + , coordinates("__Type", "interfaces"), 1 + , coordinates("__Type", "possibleTypes"), 1 + ); + + public static Optional checkIntrospection(ExecutionContext executionContext) { + if (isIntrospectionEnabled(executionContext.getGraphQLContext())) { + ExecutableNormalizedOperation operation; + try { + operation = mkOperation(executionContext); + } catch (AbortExecutionException e) { + BadFaithIntrospectionError error = BadFaithIntrospectionError.tooBigOperation(e.getMessage()); + return Optional.of(ExecutionResult.newExecutionResult().addError(error).build()); + } + ImmutableListMultimap coordinatesToENFs = operation.getCoordinatesToNormalizedFields(); + for (Map.Entry entry : ALLOWED_FIELD_INSTANCES.entrySet()) { + FieldCoordinates coordinates = entry.getKey(); + Integer allowSize = entry.getValue(); + ImmutableList normalizedFields = coordinatesToENFs.get(coordinates); + if (normalizedFields.size() > allowSize) { + BadFaithIntrospectionError error = BadFaithIntrospectionError.tooManyFields(coordinates.toString()); + return Optional.of(ExecutionResult.newExecutionResult().addError(error).build()); + } + } + } + return Optional.empty(); + } + + /** + * This makes an executable operation limited in size then which suits a good faith introspection query. This helps guard + * against malicious queries. + * + * @param executionContext the execution context + * + * @return an executable operation + */ + private static ExecutableNormalizedOperation mkOperation(ExecutionContext executionContext) throws AbortExecutionException { + Options options = Options.defaultOptions() + .maxFieldsCount(GOOD_FAITH_MAX_FIELDS_COUNT) + .maxChildrenDepth(GOOD_FAITH_MAX_DEPTH_COUNT) + .locale(executionContext.getLocale()) + .graphQLContext(executionContext.getGraphQLContext()); + + return createExecutableNormalizedOperation(executionContext.getGraphQLSchema(), + executionContext.getOperationDefinition(), + executionContext.getFragmentsByName(), + executionContext.getCoercedVariables(), + options); + + } + + private static boolean isIntrospectionEnabled(GraphQLContext graphQlContext) { + if (!isEnabledJvmWide()) { + return false; + } + return !graphQlContext.getBoolean(GOOD_FAITH_INTROSPECTION_DISABLED, false); + } + + public static class BadFaithIntrospectionError implements GraphQLError { + private final String message; + + public static BadFaithIntrospectionError tooManyFields(String fieldCoordinate) { + return new BadFaithIntrospectionError(String.format("This request is not asking for introspection in good faith - %s is present too often!", fieldCoordinate)); + } + + public static BadFaithIntrospectionError tooBigOperation(String message) { + return new BadFaithIntrospectionError(String.format("This request is not asking for introspection in good faith - the query is too big: %s", message)); + } + + private BadFaithIntrospectionError(String message) { + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public ErrorClassification getErrorType() { + return ErrorClassification.errorClassification("BadFaithIntrospection"); + } + + @Override + public List getLocations() { + return null; + } + + @Override + public String toString() { + return "BadFaithIntrospectionError{" + + "message='" + message + '\'' + + '}'; + } + } +} diff --git a/src/main/java/graphql/introspection/Introspection.java b/src/main/java/graphql/introspection/Introspection.java index 74abd25803..a455ec9d78 100644 --- a/src/main/java/graphql/introspection/Introspection.java +++ b/src/main/java/graphql/introspection/Introspection.java @@ -1,13 +1,21 @@ package graphql.introspection; +import com.google.common.collect.ImmutableSet; import graphql.Assert; +import graphql.ExecutionResult; +import graphql.GraphQLContext; +import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.execution.ExecutionContext; +import graphql.execution.MergedField; +import graphql.execution.MergedSelectionSet; +import graphql.execution.ValuesResolver; import graphql.language.AstPrinter; -import graphql.language.AstValueHelper; -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; +import graphql.schema.FieldCoordinates; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLCompositeType; import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLEnumType; @@ -20,30 +28,163 @@ import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLList; import graphql.schema.GraphQLModifiedType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLNamedType; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; -import graphql.schema.GraphQLTypeUtil; import graphql.schema.GraphQLUnionType; -import graphql.schema.visibility.GraphqlFieldVisibility; +import graphql.schema.InputValueWithState; +import org.jspecify.annotations.NonNull; import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import static graphql.Assert.assertTrue; import static graphql.Scalars.GraphQLBoolean; import static graphql.Scalars.GraphQLString; +import static graphql.schema.FieldCoordinates.coordinates; +import static graphql.schema.FieldCoordinates.systemCoordinates; import static graphql.schema.GraphQLArgument.newArgument; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLList.list; import static graphql.schema.GraphQLNonNull.nonNull; import static graphql.schema.GraphQLObjectType.newObject; import static graphql.schema.GraphQLTypeReference.typeRef; - +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.schema.GraphQLTypeUtil.unwrapAllAs; +import static graphql.schema.GraphQLTypeUtil.unwrapOne; + +/** + * GraphQl has a unique capability called Introspection that allow + * consumers to inspect the system and discover the fields and types available and makes the system self documented. + *

+ * Some security recommendations such as OWASP + * recommend that introspection be disabled in production. The {@link Introspection#enabledJvmWide(boolean)} method can be used to disable + * introspection for the whole JVM or you can place {@link Introspection#INTROSPECTION_DISABLED} into the {@link GraphQLContext} of a request + * to disable introspection for that request. + */ @PublicApi public class Introspection { + + /** + * Placing a boolean value under this key in the per request {@link GraphQLContext} will enable + * or disable Introspection on that request. + */ + public static final String INTROSPECTION_DISABLED = "INTROSPECTION_DISABLED"; + private static final AtomicBoolean INTROSPECTION_ENABLED_STATE = new AtomicBoolean(true); + + /** + * This static method will enable / disable Introspection at a JVM wide level. + * + * @param enabled the flag indicating the desired enabled state + * + * @return the previous state of enablement + */ + public static boolean enabledJvmWide(boolean enabled) { + return INTROSPECTION_ENABLED_STATE.getAndSet(enabled); + } + + /** + * @return true if Introspection is enabled at a JVM wide level or false otherwise + */ + public static boolean isEnabledJvmWide() { + return INTROSPECTION_ENABLED_STATE.get(); + } + + /** + * This will look in to the field selection set and see if there are introspection fields, + * and if there is,it checks if introspection should run, and if not it will return an errored {@link ExecutionResult} + * that can be returned to the user. + * + * @param mergedSelectionSet the fields to be executed + * @param executionContext the execution context in play + * + * @return an optional error result + */ + public static Optional isIntrospectionSensible(MergedSelectionSet mergedSelectionSet, ExecutionContext executionContext) { + GraphQLContext graphQLContext = executionContext.getGraphQLContext(); + + boolean isIntrospection = false; + for (String key : mergedSelectionSet.getKeys()) { + String fieldName = mergedSelectionSet.getSubField(key).getName(); + if (fieldName.equals(SchemaMetaFieldDef.getName()) + || fieldName.equals(TypeMetaFieldDef.getName())) { + if (!isIntrospectionEnabled(graphQLContext)) { + return mkDisabledError(mergedSelectionSet.getSubField(key)); + } + isIntrospection = true; + break; + } + } + if (isIntrospection) { + return GoodFaithIntrospection.checkIntrospection(executionContext); + } + return Optional.empty(); + } + + @NonNull + private static Optional mkDisabledError(MergedField schemaField) { + IntrospectionDisabledError error = new IntrospectionDisabledError(schemaField.getSingleField().getSourceLocation()); + return Optional.of(ExecutionResult.newExecutionResult().addError(error).build()); + } + + private static boolean isIntrospectionEnabled(GraphQLContext graphQlContext) { + if (!isEnabledJvmWide()) { + return false; + } + return !graphQlContext.getBoolean(INTROSPECTION_DISABLED, false); + } + + private static final Map> introspectionDataFetchers = new LinkedHashMap<>(); + + private static void register(GraphQLFieldsContainer parentType, String fieldName, IntrospectionDataFetcher introspectionDataFetcher) { + introspectionDataFetchers.put(coordinates(parentType.getName(), fieldName), introspectionDataFetcher); + } + + /** + * To help runtimes such as graalvm, we make sure we have an explicit data fetchers rather then use {@link graphql.schema.PropertyDataFetcher} + * and its reflective mechanisms. This is not reflective because we have the class + * + * @param parentType the containing parent type + * @param fieldName the field name + * @param targetClass the target class of the getter + * @param getter the function to call to get a value of T + * @param for two + */ + private static void register(GraphQLFieldsContainer parentType, String fieldName, Class targetClass, Function getter) { + IntrospectionDataFetcher dataFetcher = env -> { + Object source = env.getSource(); + if (targetClass.isInstance(source)) { + return getter.apply(targetClass.cast(source)); + } + return null; + }; + introspectionDataFetchers.put(coordinates(parentType.getName(), fieldName), dataFetcher); + } + + @Internal + public static void addCodeForIntrospectionTypes(GraphQLCodeRegistry.Builder codeRegistry) { + // place the system __ fields into the mix. They have no parent types + codeRegistry.dataFetcherIfAbsent(systemCoordinates(SchemaMetaFieldDef.getName()), SchemaMetaFieldDefDataFetcher); + codeRegistry.dataFetcherIfAbsent(systemCoordinates(TypeNameMetaFieldDef.getName()), TypeNameMetaFieldDefDataFetcher); + codeRegistry.dataFetcherIfAbsent(systemCoordinates(TypeMetaFieldDef.getName()), TypeMetaFieldDefDataFetcher); + + introspectionDataFetchers.forEach(codeRegistry::dataFetcherIfAbsent); + } + + public enum TypeKind { SCALAR, OBJECT, @@ -58,7 +199,7 @@ public enum TypeKind { public static final GraphQLEnumType __TypeKind = GraphQLEnumType.newEnum() .name("__TypeKind") .description("An enum describing what kind of type a given __Type is") - .value("SCALAR", TypeKind.SCALAR, "Indicates this type is a scalar.") + .value("SCALAR", TypeKind.SCALAR, "Indicates this type is a scalar. `specifiedByURL` is a valid field") .value("OBJECT", TypeKind.OBJECT, "Indicates this type is an object. `fields` and `interfaces` are valid fields.") .value("INTERFACE", TypeKind.INTERFACE, "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.") .value("UNION", TypeKind.UNION, "Indicates this type is a union. `possibleTypes` is a valid field.") @@ -68,7 +209,7 @@ public enum TypeKind { .value("NON_NULL", TypeKind.NON_NULL, "Indicates this type is a non-null. `ofType` is a valid field.") .build(); - public static final DataFetcher kindDataFetcher = environment -> { + private static final IntrospectionDataFetcher kindDataFetcher = environment -> { Object type = environment.getSource(); if (type instanceof GraphQLScalarType) { return TypeKind.SCALAR; @@ -90,6 +231,20 @@ public enum TypeKind { return Assert.assertShouldNeverHappen("Unknown kind of type: %s", type); } }; + private static final IntrospectionDataFetcher nameDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLNamedSchemaElement) { + return ((GraphQLNamedSchemaElement) type).getName(); + } + return null; + }; + private static final IntrospectionDataFetcher descriptionDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLNamedSchemaElement) { + return ((GraphQLNamedSchemaElement) type).getDescription(); + } + return null; + }; public static final GraphQLObjectType __InputValue = newObject() .name("__InputValue") @@ -104,21 +259,69 @@ public enum TypeKind { .type(nonNull(typeRef("__Type")))) .field(newFieldDefinition() .name("defaultValue") - .type(GraphQLString) - .dataFetcher(environment -> { - if (environment.getSource() instanceof GraphQLArgument) { - GraphQLArgument inputField = environment.getSource(); - return inputField.getDefaultValue() != null ? print(inputField.getDefaultValue(), inputField.getType()) : null; - } else if (environment.getSource() instanceof GraphQLInputObjectField) { - GraphQLInputObjectField inputField = environment.getSource(); - return inputField.getDefaultValue() != null ? print(inputField.getDefaultValue(), inputField.getType()) : null; - } - return null; - })) + .type(GraphQLString)) + .field(newFieldDefinition() + .name("isDeprecated") + .type(GraphQLBoolean)) + .field(newFieldDefinition() + .name("deprecationReason") + .type(GraphQLString)) .build(); - private static String print(Object value, GraphQLInputType type) { - return AstPrinter.printAst(AstValueHelper.astFromValue(value, type)); + static { + IntrospectionDataFetcher defaultValueDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLArgument) { + GraphQLArgument inputField = (GraphQLArgument) type; + return inputField.hasSetDefaultValue() + ? printDefaultValue(inputField.getArgumentDefaultValue(), inputField.getType(), environment.getGraphQlContext(), environment.getLocale()) + : null; + } else if (type instanceof GraphQLInputObjectField) { + GraphQLInputObjectField inputField = (GraphQLInputObjectField) type; + return inputField.hasSetDefaultValue() + ? printDefaultValue(inputField.getInputFieldDefaultValue(), inputField.getType(), environment.getGraphQlContext(), environment.getLocale()) + : null; + } + return null; + }; + IntrospectionDataFetcher isDeprecatedDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLArgument) { + return ((GraphQLArgument) type).isDeprecated(); + } else if (type instanceof GraphQLInputObjectField) { + return ((GraphQLInputObjectField) type).isDeprecated(); + } + return null; + }; + IntrospectionDataFetcher typeDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLArgument) { + return ((GraphQLArgument) type).getType(); + } else if (type instanceof GraphQLInputObjectField) { + return ((GraphQLInputObjectField) type).getType(); + } + return null; + }; + IntrospectionDataFetcher deprecationReasonDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLArgument) { + return ((GraphQLArgument) type).getDeprecationReason(); + } else if (type instanceof GraphQLInputObjectField) { + return ((GraphQLInputObjectField) type).getDeprecationReason(); + } + return null; + }; + + register(__InputValue, "name", nameDataFetcher); + register(__InputValue, "description", descriptionDataFetcher); + register(__InputValue, "type", typeDataFetcher); + register(__InputValue, "defaultValue", defaultValueDataFetcher); + register(__InputValue, "isDeprecated", isDeprecatedDataFetcher); + register(__InputValue, "deprecationReason", deprecationReasonDataFetcher); + } + + private static String printDefaultValue(InputValueWithState inputValueWithState, GraphQLInputType type, GraphQLContext graphQLContext, Locale locale) { + return AstPrinter.printAst(ValuesResolver.valueToLiteral(inputValueWithState, type, graphQLContext, locale)); } @@ -133,25 +336,37 @@ private static String print(Object value, GraphQLInputType type) { .field(newFieldDefinition() .name("args") .type(nonNull(list(nonNull(__InputValue)))) - .dataFetcher(environment -> { - Object type = environment.getSource(); - return ((GraphQLFieldDefinition) type).getArguments(); - })) + .argument(newArgument() + .name("includeDeprecated") + .type(GraphQLBoolean) + .defaultValueProgrammatic(false))) .field(newFieldDefinition() .name("type") .type(nonNull(typeRef("__Type")))) .field(newFieldDefinition() .name("isDeprecated") - .type(nonNull(GraphQLBoolean)) - .dataFetcher(environment -> { - Object type = environment.getSource(); - return ((GraphQLFieldDefinition) type).isDeprecated(); - })) + .type(nonNull(GraphQLBoolean))) .field(newFieldDefinition() .name("deprecationReason") .type(GraphQLString)) .build(); + static { + IntrospectionDataFetcher argsDataFetcher = environment -> { + Object type = environment.getSource(); + GraphQLFieldDefinition fieldDef = (GraphQLFieldDefinition) type; + Boolean includeDeprecated = environment.getArgument("includeDeprecated"); + return ImmutableKit.filter(fieldDef.getArguments(), + arg -> includeDeprecated || !arg.isDeprecated()); + }; + register(__Field, "name", nameDataFetcher); + register(__Field, "description", descriptionDataFetcher); + register(__Field, "args", argsDataFetcher); + register(__Field, "type", GraphQLFieldDefinition.class, GraphQLFieldDefinition::getType); + register(__Field, "isDeprecated", GraphQLFieldDefinition.class, GraphQLFieldDefinition::isDeprecated); + register(__Field, "deprecationReason", GraphQLFieldDefinition.class, GraphQLFieldDefinition::getDeprecationReason); + } + public static final GraphQLObjectType __EnumValue = newObject() .name("__EnumValue") @@ -163,45 +378,52 @@ private static String print(Object value, GraphQLInputType type) { .type(GraphQLString)) .field(newFieldDefinition() .name("isDeprecated") - .type(nonNull(GraphQLBoolean)) - .dataFetcher(environment -> { - GraphQLEnumValueDefinition enumValue = environment.getSource(); - return enumValue.isDeprecated(); - })) + .type(nonNull(GraphQLBoolean))) .field(newFieldDefinition() .name("deprecationReason") .type(GraphQLString)) .build(); - public static final DataFetcher fieldsFetcher = environment -> { + static { + register(__EnumValue, "name", nameDataFetcher); + register(__EnumValue, "description", descriptionDataFetcher); + register(__EnumValue, "isDeprecated", GraphQLEnumValueDefinition.class, GraphQLEnumValueDefinition::isDeprecated); + register(__EnumValue, "deprecationReason", GraphQLEnumValueDefinition.class, GraphQLEnumValueDefinition::getDeprecationReason); + } + + + private static final IntrospectionDataFetcher fieldsFetcher = environment -> { Object type = environment.getSource(); - Boolean includeDeprecated = environment.getArgument("includeDeprecated"); if (type instanceof GraphQLFieldsContainer) { GraphQLFieldsContainer fieldsContainer = (GraphQLFieldsContainer) type; + Boolean includeDeprecated = environment.getArgument("includeDeprecated"); List fieldDefinitions = environment .getGraphQLSchema() + .getCodeRegistry() .getFieldVisibility() .getFieldDefinitions(fieldsContainer); - if (includeDeprecated) return fieldDefinitions; - List filtered = new ArrayList<>(fieldDefinitions); - for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { - if (fieldDefinition.isDeprecated()) filtered.remove(fieldDefinition); + if (includeDeprecated) { + return fieldDefinitions; } - return filtered; + return ImmutableKit.filter(fieldDefinitions, + field -> !field.isDeprecated()); } return null; }; - public static final DataFetcher interfacesFetcher = environment -> { + private static final IntrospectionDataFetcher interfacesFetcher = environment -> { Object type = environment.getSource(); if (type instanceof GraphQLObjectType) { return ((GraphQLObjectType) type).getInterfaces(); } + if (type instanceof GraphQLInterfaceType) { + return ((GraphQLInterfaceType) type).getInterfaces(); + } return null; }; - public static final DataFetcher possibleTypesFetcher = environment -> { + private static final IntrospectionDataFetcher possibleTypesFetcher = environment -> { Object type = environment.getSource(); if (type instanceof GraphQLInterfaceType) { return environment.getGraphQLSchema().getImplementations((GraphQLInterfaceType) type); @@ -212,47 +434,67 @@ private static String print(Object value, GraphQLInputType type) { return null; }; - public static final DataFetcher enumValuesTypesFetcher = environment -> { + private static final IntrospectionDataFetcher enumValuesTypesFetcher = environment -> { Object type = environment.getSource(); - Boolean includeDeprecated = environment.getArgument("includeDeprecated"); if (type instanceof GraphQLEnumType) { + Boolean includeDeprecated = environment.getArgument("includeDeprecated"); List values = ((GraphQLEnumType) type).getValues(); - if (includeDeprecated) return values; - List filtered = new ArrayList<>(values); - for (GraphQLEnumValueDefinition valueDefinition : values) { - if (valueDefinition.isDeprecated()) filtered.remove(valueDefinition); + if (includeDeprecated) { + return values; } - return filtered; + return ImmutableKit.filter(values, + enumValue -> !enumValue.isDeprecated()); } return null; }; - public static final DataFetcher inputFieldsFetcher = environment -> { + private static final IntrospectionDataFetcher inputFieldsFetcher = environment -> { Object type = environment.getSource(); if (type instanceof GraphQLInputObjectType) { - GraphqlFieldVisibility fieldVisibility = environment + Boolean includeDeprecated = environment.getArgument("includeDeprecated"); + List inputFields = environment .getGraphQLSchema() - .getFieldVisibility(); - return fieldVisibility.getFieldDefinitions((GraphQLInputObjectType) type); + .getCodeRegistry() + .getFieldVisibility() + .getFieldDefinitions((GraphQLInputObjectType) type); + if (includeDeprecated) { + return inputFields; + } + return ImmutableKit.filter(inputFields, + inputField -> !inputField.isDeprecated()); } return null; }; - public static final DataFetcher OfTypeFetcher = environment -> { + private static final IntrospectionDataFetcher OfTypeFetcher = environment -> { Object type = environment.getSource(); if (type instanceof GraphQLModifiedType) { - return GraphQLTypeUtil.unwrapOne((GraphQLModifiedType) type); + return unwrapOne((GraphQLModifiedType) type); } return null; }; + private static final IntrospectionDataFetcher specifiedByUrlDataFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLScalarType) { + return ((GraphQLScalarType) type).getSpecifiedByUrl(); + } + return null; + }; + + private static final IntrospectionDataFetcher isOneOfFetcher = environment -> { + Object type = environment.getSource(); + if (type instanceof GraphQLInputObjectType) { + return ((GraphQLInputObjectType) type).isOneOf(); + } + return null; + }; public static final GraphQLObjectType __Type = newObject() .name("__Type") .field(newFieldDefinition() .name("kind") - .type(nonNull(__TypeKind)) - .dataFetcher(kindDataFetcher)) + .type(nonNull(__TypeKind))) .field(newFieldDefinition() .name("name") .type(GraphQLString)) @@ -265,41 +507,69 @@ private static String print(Object value, GraphQLInputType type) { .argument(newArgument() .name("includeDeprecated") .type(GraphQLBoolean) - .defaultValue(false)) - .dataFetcher(fieldsFetcher)) + .defaultValueProgrammatic(false))) .field(newFieldDefinition() .name("interfaces") - .type(list(nonNull(typeRef("__Type")))) - .dataFetcher(interfacesFetcher)) + .type(list(nonNull(typeRef("__Type"))))) .field(newFieldDefinition() .name("possibleTypes") - .type(list(nonNull(typeRef("__Type")))) - .dataFetcher(possibleTypesFetcher)) + .type(list(nonNull(typeRef("__Type"))))) .field(newFieldDefinition() .name("enumValues") .type(list(nonNull(__EnumValue))) .argument(newArgument() .name("includeDeprecated") .type(GraphQLBoolean) - .defaultValue(false)) - .dataFetcher(enumValuesTypesFetcher)) + .defaultValueProgrammatic(false))) .field(newFieldDefinition() .name("inputFields") .type(list(nonNull(__InputValue))) - .dataFetcher(inputFieldsFetcher)) + .argument(newArgument() + .name("includeDeprecated") + .type(GraphQLBoolean) + .defaultValueProgrammatic(false))) .field(newFieldDefinition() .name("ofType") - .type(typeRef("__Type")) - .dataFetcher(OfTypeFetcher)) + .type(typeRef("__Type"))) + .field(newFieldDefinition() + .name("isOneOf") + .description("This field is considered experimental because it has not yet been ratified in the graphql specification") + .type(GraphQLBoolean)) + .field(newFieldDefinition() + .name("specifiedByURL") + .type(GraphQLString)) + .field(newFieldDefinition() + .name("specifiedByUrl") + .type(GraphQLString) + .deprecate("This legacy name has been replaced by `specifiedByURL`") + ) .build(); + static { + register(__Type, "kind", kindDataFetcher); + register(__Type, "name", nameDataFetcher); + register(__Type, "description", descriptionDataFetcher); + register(__Type, "fields", fieldsFetcher); + register(__Type, "interfaces", interfacesFetcher); + register(__Type, "possibleTypes", possibleTypesFetcher); + register(__Type, "enumValues", enumValuesTypesFetcher); + register(__Type, "inputFields", inputFieldsFetcher); + register(__Type, "ofType", OfTypeFetcher); + register(__Type, "isOneOf", isOneOfFetcher); + register(__Type, "specifiedByURL", specifiedByUrlDataFetcher); + register(__Type, "specifiedByUrl", specifiedByUrlDataFetcher); // note that this field is deprecated + } + + public enum DirectiveLocation { QUERY, MUTATION, + SUBSCRIPTION, FIELD, FRAGMENT_DEFINITION, FRAGMENT_SPREAD, INLINE_FRAGMENT, + VARIABLE_DEFINITION, // // schema SDL places // @@ -321,10 +591,12 @@ public enum DirectiveLocation { .description("An enum describing valid locations where a directive can be placed") .value("QUERY", DirectiveLocation.QUERY, "Indicates the directive is valid on queries.") .value("MUTATION", DirectiveLocation.MUTATION, "Indicates the directive is valid on mutations.") + .value("SUBSCRIPTION", DirectiveLocation.SUBSCRIPTION, "Indicates the directive is valid on subscriptions.") .value("FIELD", DirectiveLocation.FIELD, "Indicates the directive is valid on fields.") .value("FRAGMENT_DEFINITION", DirectiveLocation.FRAGMENT_DEFINITION, "Indicates the directive is valid on fragment definitions.") .value("FRAGMENT_SPREAD", DirectiveLocation.FRAGMENT_SPREAD, "Indicates the directive is valid on fragment spreads.") .value("INLINE_FRAGMENT", DirectiveLocation.INLINE_FRAGMENT, "Indicates the directive is valid on inline fragments.") + .value("VARIABLE_DEFINITION", DirectiveLocation.VARIABLE_DEFINITION, "Indicates the directive is valid on variable definitions.") // // from schema SDL PR https://github.com/facebook/graphql/pull/90 // @@ -339,172 +611,233 @@ public enum DirectiveLocation { .value("ENUM_VALUE", DirectiveLocation.ENUM_VALUE, "Indicates the directive is valid on an enum value SDL definition.") .value("INPUT_OBJECT", DirectiveLocation.INPUT_OBJECT, "Indicates the directive is valid on an input object SDL definition.") .value("INPUT_FIELD_DEFINITION", DirectiveLocation.INPUT_FIELD_DEFINITION, "Indicates the directive is valid on an input object field SDL definition.") - .build(); - @SuppressWarnings("deprecation") // because graphql spec still has the deprecated fields + public static final GraphQLObjectType __Directive = newObject() .name("__Directive") .field(newFieldDefinition() .name("name") - .type(GraphQLString)) + .description("The __Directive type represents a Directive that a server supports.") + .type(nonNull(GraphQLString))) .field(newFieldDefinition() .name("description") .type(GraphQLString)) + .field(newFieldDefinition() + .name("isRepeatable") + .type(nonNull(GraphQLBoolean))) .field(newFieldDefinition() .name("locations") - .type(list(nonNull(__DirectiveLocation))) - .dataFetcher(environment -> { - GraphQLDirective directive = environment.getSource(); - return new ArrayList<>(directive.validLocations()); - })) + .type(nonNull(list(nonNull(__DirectiveLocation))))) .field(newFieldDefinition() .name("args") .type(nonNull(list(nonNull(__InputValue)))) - .dataFetcher(environment -> { - GraphQLDirective directive = environment.getSource(); - return directive.getArguments(); - })) - .field(newFieldDefinition() - .name("onOperation") - .type(GraphQLBoolean) - .deprecate("Use `locations`.") - .dataFetcher(environment -> { - GraphQLDirective directive = environment.getSource(); - return directive.isOnOperation(); - })) - .field(newFieldDefinition() - .name("onFragment") - .type(GraphQLBoolean) - .deprecate("Use `locations`.") - .dataFetcher(environment -> { - GraphQLDirective directive = environment.getSource(); - return directive.isOnFragment() || - (directive.validLocations().contains(DirectiveLocation.INLINE_FRAGMENT) - && directive.validLocations().contains(DirectiveLocation.FRAGMENT_SPREAD)); - })) - .field(newFieldDefinition() - .name("onField") - .type(GraphQLBoolean) - .deprecate("Use `locations`.") - .dataFetcher(environment -> { - GraphQLDirective directive = environment.getSource(); - return directive.isOnField() || - directive.validLocations().contains(DirectiveLocation.FIELD); - })) + .argument(newArgument() + .name("includeDeprecated") + .type(GraphQLBoolean) + .defaultValueProgrammatic(false))) .build(); + static { + IntrospectionDataFetcher locationsDataFetcher = environment -> { + GraphQLDirective directive = environment.getSource(); + return new ArrayList<>(directive.validLocations()); + }; + IntrospectionDataFetcher argsDataFetcher = environment -> { + GraphQLDirective directive = environment.getSource(); + Boolean includeDeprecated = environment.getArgument("includeDeprecated"); + return ImmutableKit.filter(directive.getArguments(), + arg -> includeDeprecated || !arg.isDeprecated()); + }; + register(__Directive, "name", nameDataFetcher); + register(__Directive, "description", descriptionDataFetcher); + register(__Directive, "isRepeatable", GraphQLDirective.class, GraphQLDirective::isRepeatable); + register(__Directive, "locations", locationsDataFetcher); + register(__Directive, "args", argsDataFetcher); + } + public static final GraphQLObjectType __Schema = newObject() .name("__Schema") .description("A GraphQL Introspection defines the capabilities" + " of a GraphQL server. It exposes all available types and directives on " + "the server, the entry points for query, mutation, and subscription operations.") + .field(newFieldDefinition() + .name("description") + .type(GraphQLString)) .field(newFieldDefinition() .name("types") .description("A list of all types supported by this server.") - .type(nonNull(list(nonNull(__Type)))) - .dataFetcher(environment -> { - GraphQLSchema schema = environment.getSource(); - return schema.getAllTypesAsList(); - })) + .type(nonNull(list(nonNull(__Type))))) .field(newFieldDefinition() .name("queryType") .description("The type that query operations will be rooted at.") - .type(nonNull(__Type)) - .dataFetcher(environment -> { - GraphQLSchema schema = environment.getSource(); - return schema.getQueryType(); - })) + .type(nonNull(__Type))) .field(newFieldDefinition() .name("mutationType") .description("If this server supports mutation, the type that mutation operations will be rooted at.") - .type(__Type) - .dataFetcher(environment -> { - GraphQLSchema schema = environment.getSource(); - return schema.getMutationType(); - })) + .type(__Type)) .field(newFieldDefinition() .name("directives") - .description("'A list of all directives supported by this server.") - .type(nonNull(list(nonNull(__Directive)))) - .dataFetcher(environment -> environment.getGraphQLSchema().getDirectives())) + .description("A list of all directives supported by this server.") + .type(nonNull(list(nonNull(__Directive))))) .field(newFieldDefinition() .name("subscriptionType") - .description("'If this server support subscription, the type that subscription operations will be rooted at.") - .type(__Type) - .dataFetcher(environment -> { - GraphQLSchema schema = environment.getSource(); - return schema.getSubscriptionType(); - })) + .description("If this server support subscription, the type that subscription operations will be rooted at.") + .type(__Type)) .build(); + static { + IntrospectionDataFetcher descriptionsDataFetcher = environment -> environment.getGraphQLSchema().getDescription(); + + register(__Schema, "description", descriptionsDataFetcher); + register(__Schema, "types", GraphQLSchema.class, GraphQLSchema::getAllTypesAsList); + register(__Schema, "queryType", GraphQLSchema.class, GraphQLSchema::getQueryType); + register(__Schema, "mutationType", GraphQLSchema.class, GraphQLSchema::getMutationType); + register(__Schema, "directives", GraphQLSchema.class, GraphQLSchema::getDirectives); + register(__Schema, "subscriptionType", GraphQLSchema.class, GraphQLSchema::getSubscriptionType); + } - public static final GraphQLFieldDefinition SchemaMetaFieldDef = newFieldDefinition() - .name("__schema") - .type(nonNull(__Schema)) - .description("Access the current type schema of this server.") - .dataFetcher(DataFetchingEnvironment::getGraphQLSchema).build(); - - public static final GraphQLFieldDefinition TypeMetaFieldDef = newFieldDefinition() - .name("__type") - .type(__Type) - .description("Request the type information of a single type.") - .argument(newArgument() - .name("name") - .type(nonNull(GraphQLString))) - .dataFetcher(environment -> { - String name = environment.getArgument("name"); - return environment.getGraphQLSchema().getType(name); - }).build(); - + public static final GraphQLFieldDefinition SchemaMetaFieldDef = buildSchemaField(__Schema); + public static final GraphQLFieldDefinition TypeMetaFieldDef = buildTypeField(__Schema); public static final GraphQLFieldDefinition TypeNameMetaFieldDef = newFieldDefinition() .name("__typename") .type(nonNull(GraphQLString)) .description("The name of the current Object type at runtime.") - .dataFetcher(environment -> environment.getParentType().getName()) .build(); + public static final Set INTROSPECTION_SYSTEM_FIELDS = ImmutableSet.of( + Introspection.SchemaMetaFieldDef.getName(), + Introspection.TypeMetaFieldDef.getName(), + Introspection.TypeNameMetaFieldDef.getName() + ); + + public static final IntrospectionDataFetcher SchemaMetaFieldDefDataFetcher = IntrospectionDataFetchingEnvironment::getGraphQLSchema; + + public static final IntrospectionDataFetcher TypeMetaFieldDefDataFetcher = environment -> { + String name = environment.getArgument("name"); + return environment.getGraphQLSchema().getType(name); + }; + + // __typename is always available + public static final IntrospectionDataFetcher TypeNameMetaFieldDefDataFetcher = environment -> simplePrint(environment.getParentType()); + + @Internal + public static GraphQLFieldDefinition buildSchemaField(GraphQLObjectType introspectionSchemaType) { + return newFieldDefinition() + .name("__schema") + .type(nonNull(introspectionSchemaType)) + .description("Access the current type schema of this server.") + .build(); + } + + @Internal + public static GraphQLFieldDefinition buildTypeField(GraphQLObjectType introspectionSchemaType) { + + GraphQLOutputType fieldType = introspectionSchemaType.getFieldDefinition("types").getType(); + GraphQLObjectType underscoreType = unwrapAllAs(fieldType); + return newFieldDefinition() + .name("__type") + .type(underscoreType) + .description("Request the type information of a single type.") + .argument(newArgument() + .name("name") + .type(nonNull(GraphQLString))) + .build(); + } + + private static final Set introspectionTypes = new HashSet<>(); static { - // make sure all TypeReferences are resolved - GraphQLSchema.newSchema() - .query(GraphQLObjectType.newObject() - .name("IntrospectionQuery") - .field(SchemaMetaFieldDef) - .field(TypeMetaFieldDef) - .field(TypeNameMetaFieldDef) - .build()) + GraphQLObjectType IntrospectionQuery = newObject() + .name("IntrospectionQuery") + .field(SchemaMetaFieldDef) + .field(TypeMetaFieldDef) + .field(TypeNameMetaFieldDef) .build(); + + introspectionTypes.add(__DirectiveLocation.getName()); + introspectionTypes.add(__TypeKind.getName()); + introspectionTypes.add(__Type.getName()); + introspectionTypes.add(__Schema.getName()); + introspectionTypes.add(__InputValue.getName()); + introspectionTypes.add(__Field.getName()); + introspectionTypes.add(__EnumValue.getName()); + introspectionTypes.add(__Directive.getName()); + + // make sure all TypeReferences are resolved. + // note: it is important to put this on the bottom of static code block. + GraphQLSchema.newSchema().query(IntrospectionQuery).build(); + } + + public static boolean isIntrospectionTypes(GraphQLNamedType type) { + return introspectionTypes.contains(type.getName()); + } + + public static boolean isIntrospectionTypes(String typeName) { + return introspectionTypes.contains(typeName); } /** * This will look up a field definition by name, and understand that fields like __typename and __schema are special - * and take precedence in field resolution + * and take precedence in field resolution. If the parent type is a union type, then the only field allowed + * is `__typename`. * * @param schema the schema to use * @param parentType the type of the parent object * @param fieldName the field to look up * - * @return a field definition otherwise throws an assertion exception if its null + * @return a field definition otherwise throws an assertion exception if it's null */ public static GraphQLFieldDefinition getFieldDef(GraphQLSchema schema, GraphQLCompositeType parentType, String fieldName) { - if (schema.getQueryType() == parentType) { - if (fieldName.equals(SchemaMetaFieldDef.getName())) { - return SchemaMetaFieldDef; - } - if (fieldName.equals(TypeMetaFieldDef.getName())) { - return TypeMetaFieldDef; - } - } - if (fieldName.equals(TypeNameMetaFieldDef.getName())) { - return TypeNameMetaFieldDef; + GraphQLFieldDefinition fieldDefinition = getSystemFieldDef(schema, parentType, fieldName); + if (fieldDefinition != null) { + return fieldDefinition; } assertTrue(parentType instanceof GraphQLFieldsContainer, "should not happen : parent type must be an object or interface %s", parentType); GraphQLFieldsContainer fieldsContainer = (GraphQLFieldsContainer) parentType; - GraphQLFieldDefinition fieldDefinition = schema.getFieldVisibility().getFieldDefinition(fieldsContainer, fieldName); - Assert.assertTrue(fieldDefinition != null, "Unknown field '%s'", fieldName); + fieldDefinition = schema.getCodeRegistry().getFieldVisibility().getFieldDefinition(fieldsContainer, fieldName); + assertTrue(fieldDefinition != null, "Unknown field '%s' for type %s", fieldName, fieldsContainer.getName()); + return fieldDefinition; + } + + /** + * This will look up a field definition by name, and understand that fields like __typename and __schema are special + * and take precedence in field resolution + * + * @param schema the schema to use + * @param parentType the type of the parent {@link GraphQLFieldsContainer} + * @param fieldName the field to look up + * + * @return a field definition otherwise throws an assertion exception if it's null + */ + public static GraphQLFieldDefinition getFieldDefinition(GraphQLSchema schema, GraphQLFieldsContainer parentType, String fieldName) { + // this method is optimized to look up the most common case first (type for field) and hence suits the hot path of the execution engine + // and as a small benefit does not allocate any assertions unless it completely failed + GraphQLFieldDefinition fieldDefinition = schema.getCodeRegistry().getFieldVisibility().getFieldDefinition(parentType, fieldName); + if (fieldDefinition == null) { + // we look up system fields second because they are less likely to be the field in question + fieldDefinition = getSystemFieldDef(schema, parentType, fieldName); + if (fieldDefinition == null) { + Assert.assertShouldNeverHappen(String.format("Unknown field '%s' for type %s", fieldName, parentType.getName())); + } + } return fieldDefinition; } + + private static GraphQLFieldDefinition getSystemFieldDef(GraphQLSchema schema, GraphQLCompositeType parentType, String fieldName) { + if (schema.getQueryType() == parentType) { + if (fieldName.equals(schema.getIntrospectionSchemaFieldDefinition().getName())) { + return schema.getIntrospectionSchemaFieldDefinition(); + } + if (fieldName.equals(schema.getIntrospectionTypeFieldDefinition().getName())) { + return schema.getIntrospectionTypeFieldDefinition(); + } + } + if (fieldName.equals(schema.getIntrospectionTypenameFieldDefinition().getName())) { + return schema.getIntrospectionTypenameFieldDefinition(); + } + return null; + } } diff --git a/src/main/java/graphql/introspection/IntrospectionDataFetcher.java b/src/main/java/graphql/introspection/IntrospectionDataFetcher.java new file mode 100644 index 0000000000..8eb96d7cf3 --- /dev/null +++ b/src/main/java/graphql/introspection/IntrospectionDataFetcher.java @@ -0,0 +1,11 @@ +package graphql.introspection; + +import graphql.Internal; +import graphql.TrivialDataFetcher; + +/** + * Special DataFetcher which is only used inside {@link Introspection} + */ +@Internal +public interface IntrospectionDataFetcher extends TrivialDataFetcher { +} diff --git a/src/main/java/graphql/introspection/IntrospectionDataFetchingEnvironment.java b/src/main/java/graphql/introspection/IntrospectionDataFetchingEnvironment.java new file mode 100644 index 0000000000..a5892670df --- /dev/null +++ b/src/main/java/graphql/introspection/IntrospectionDataFetchingEnvironment.java @@ -0,0 +1,25 @@ +package graphql.introspection; + +import graphql.Internal; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLType; + +import java.util.Map; + +/** + * Extracted from {@link graphql.schema.DataFetchingEnvironment} to only capture + * the data really needed for {@link Introspection} + */ +@Internal +public interface IntrospectionDataFetchingEnvironment { + + T getSource(); + + Map getArguments(); + + GraphQLSchema getGraphQLSchema(); + + T getArgument(String name); + + GraphQLType getParentType(); +} diff --git a/src/main/java/graphql/introspection/IntrospectionDisabledError.java b/src/main/java/graphql/introspection/IntrospectionDisabledError.java new file mode 100644 index 0000000000..26e75d1bd5 --- /dev/null +++ b/src/main/java/graphql/introspection/IntrospectionDisabledError.java @@ -0,0 +1,34 @@ +package graphql.introspection; + +import graphql.ErrorClassification; +import graphql.GraphQLError; +import graphql.Internal; +import graphql.language.SourceLocation; + +import java.util.Collections; +import java.util.List; + +@Internal +public class IntrospectionDisabledError implements GraphQLError { + + private final List locations; + + public IntrospectionDisabledError(SourceLocation sourceLocation) { + locations = sourceLocation == null ? Collections.emptyList() : Collections.singletonList(sourceLocation); + } + + @Override + public String getMessage() { + return "Introspection has been disabled for this request"; + } + + @Override + public List getLocations() { + return locations; + } + + @Override + public ErrorClassification getErrorType() { + return ErrorClassification.errorClassification("IntrospectionDisabled"); + } +} diff --git a/src/main/java/graphql/introspection/IntrospectionQuery.java b/src/main/java/graphql/introspection/IntrospectionQuery.java index f28d7c46c6..694ccaab42 100644 --- a/src/main/java/graphql/introspection/IntrospectionQuery.java +++ b/src/main/java/graphql/introspection/IntrospectionQuery.java @@ -1,81 +1,13 @@ package graphql.introspection; -public interface IntrospectionQuery { +import graphql.PublicApi; - String INTROSPECTION_QUERY = "\n" + - " query IntrospectionQuery {\n" + - " __schema {\n" + - " queryType { name }\n" + - " mutationType { name }\n" + - " subscriptionType { name }\n" + - " types {\n" + - " ...FullType\n" + - " }\n" + - " directives {\n" + - " name\n" + - " description\n" + - " locations\n" + - " args {\n" + - " ...InputValue\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - "\n" + - " fragment FullType on __Type {\n" + - " kind\n" + - " name\n" + - " description\n" + - " fields(includeDeprecated: true) {\n" + - " name\n" + - " description\n" + - " args {\n" + - " ...InputValue\n" + - " }\n" + - " type {\n" + - " ...TypeRef\n" + - " }\n" + - " isDeprecated\n" + - " deprecationReason\n" + - " }\n" + - " inputFields {\n" + - " ...InputValue\n" + - " }\n" + - " interfaces {\n" + - " ...TypeRef\n" + - " }\n" + - " enumValues(includeDeprecated: true) {\n" + - " name\n" + - " description\n" + - " isDeprecated\n" + - " deprecationReason\n" + - " }\n" + - " possibleTypes {\n" + - " ...TypeRef\n" + - " }\n" + - " }\n" + - "\n" + - " fragment InputValue on __InputValue {\n" + - " name\n" + - " description\n" + - " type { ...TypeRef }\n" + - " defaultValue\n" + - " }\n" + - "\n" + - " fragment TypeRef on __Type {\n" + - " kind\n" + - " name\n" + - " ofType {\n" + - " kind\n" + - " name\n" + - " ofType {\n" + - " kind\n" + - " name\n" + - " ofType {\n" + - " kind\n" + - " name\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n"; +@PublicApi +public interface IntrospectionQuery { + /** + * This is the default introspection query provided by graphql-java + * + * @see IntrospectionQueryBuilder for ways to customize the introspection query + */ + String INTROSPECTION_QUERY = IntrospectionQueryBuilder.build(); } diff --git a/src/main/java/graphql/introspection/IntrospectionQueryBuilder.java b/src/main/java/graphql/introspection/IntrospectionQueryBuilder.java new file mode 100644 index 0000000000..d4d37005b0 --- /dev/null +++ b/src/main/java/graphql/introspection/IntrospectionQueryBuilder.java @@ -0,0 +1,423 @@ +package graphql.introspection; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.language.AstPrinter; +import graphql.language.BooleanValue; +import graphql.language.Document; +import graphql.language.OperationDefinition; +import graphql.language.SelectionSet; + +import java.util.List; +import java.util.Objects; + +import static graphql.language.Argument.newArgument; +import static graphql.language.Document.newDocument; +import static graphql.language.Field.newField; +import static graphql.language.FragmentDefinition.newFragmentDefinition; +import static graphql.language.FragmentSpread.newFragmentSpread; +import static graphql.language.OperationDefinition.newOperationDefinition; +import static graphql.language.SelectionSet.newSelectionSet; +import static graphql.language.TypeName.newTypeName; + +/** + * {@link IntrospectionQueryBuilder} allows you to build introspection queries controlled + * by the options you specify + */ +@PublicApi +public class IntrospectionQueryBuilder { + public static class Options { + + private final boolean descriptions; + + private final boolean specifiedByUrl; + private final boolean isOneOf; + + private final boolean directiveIsRepeatable; + + private final boolean schemaDescription; + + private final boolean inputValueDeprecation; + + private final int typeRefFragmentDepth; + + private Options(boolean descriptions, + boolean specifiedByUrl, + boolean isOneOf, + boolean directiveIsRepeatable, + boolean schemaDescription, + boolean inputValueDeprecation, + int typeRefFragmentDepth) { + this.descriptions = descriptions; + this.specifiedByUrl = specifiedByUrl; + this.isOneOf = isOneOf; + this.directiveIsRepeatable = directiveIsRepeatable; + this.schemaDescription = schemaDescription; + this.inputValueDeprecation = inputValueDeprecation; + this.typeRefFragmentDepth = typeRefFragmentDepth; + } + + public boolean isDescriptions() { + return descriptions; + } + + public boolean isSpecifiedByUrl() { + return specifiedByUrl; + } + + public boolean isOneOf() { + return isOneOf; + } + + public boolean isDirectiveIsRepeatable() { + return directiveIsRepeatable; + } + + public boolean isSchemaDescription() { + return schemaDescription; + } + + public boolean isInputValueDeprecation() { + return inputValueDeprecation; + } + + public int getTypeRefFragmentDepth() { + return typeRefFragmentDepth; + } + + public static Options defaultOptions() { + return new Options( + true, + false, + true, + true, + false, + true, + 7 + ); + } + + /** + * This will allow you to include description fields in the introspection query + * + * @param flag whether to include them + * + * @return options + */ + public Options descriptions(boolean flag) { + return new Options(flag, + this.specifiedByUrl, + this.isOneOf, + this.directiveIsRepeatable, + this.schemaDescription, + this.inputValueDeprecation, + this.typeRefFragmentDepth); + } + + /** + * This will allow you to include the `specifiedByURL` field for scalar types in the introspection query. + * + * @param flag whether to include them + * + * @return options + */ + public Options specifiedByUrl(boolean flag) { + return new Options(this.descriptions, + flag, + this.isOneOf, + this.directiveIsRepeatable, + this.schemaDescription, + this.inputValueDeprecation, + this.typeRefFragmentDepth); + } + + /** + * This will allow you to include the `isOneOf` field for one of input types in the introspection query. + *

+ * This option is only needed while `@oneOf` input types are new and in time the reason for this + * option will go away. + * + * @param flag whether to include them + * + * @return options + */ + public Options isOneOf(boolean flag) { + return new Options(this.descriptions, + this.specifiedByUrl, + flag, + this.directiveIsRepeatable, + this.schemaDescription, + this.inputValueDeprecation, + this.typeRefFragmentDepth); + } + + /** + * This will allow you to include the `isRepeatable` field for directives in the introspection query. + * + * @param flag whether to include them + * + * @return options + */ + public Options directiveIsRepeatable(boolean flag) { + return new Options(this.descriptions, + this.specifiedByUrl, + this.isOneOf, + flag, + this.schemaDescription, + this.inputValueDeprecation, + this.typeRefFragmentDepth); + } + + /** + * This will allow you to include the `description` field for the schema type in the introspection query. + * + * @param flag whether to include them + * + * @return options + */ + public Options schemaDescription(boolean flag) { + return new Options(this.descriptions, + this.specifiedByUrl, + this.isOneOf, + this.directiveIsRepeatable, + flag, + this.inputValueDeprecation, + this.typeRefFragmentDepth); + } + + /** + * This will allow you to include deprecated input fields in the introspection query. + * + * @param flag whether to include them + * + * @return options + */ + public Options inputValueDeprecation(boolean flag) { + return new Options(this.descriptions, + this.specifiedByUrl, + this.isOneOf, + this.directiveIsRepeatable, + this.schemaDescription, + flag, + this.typeRefFragmentDepth); + } + + /** + * This will allow you to control the depth of the `TypeRef` fragment in the introspection query. + * + * @param typeRefFragmentDepth the depth of the `TypeRef` fragment. + * + * @return options + */ + public Options typeRefFragmentDepth(int typeRefFragmentDepth) { + return new Options(this.descriptions, + this.specifiedByUrl, + this.isOneOf, + this.directiveIsRepeatable, + this.schemaDescription, + this.inputValueDeprecation, + typeRefFragmentDepth); + } + } + + @SafeVarargs + private static List filter(T... args) { + return ImmutableKit.filterVarArgs(Objects::nonNull, args); + } + + /** + * This will build an introspection query in {@link Document} form + * + * @param options the options to use + * + * @return an introspection query in document form + */ + public static Document buildDocument(Options options) { + SelectionSet schemaSelectionSet = newSelectionSet().selections(filter( + options.schemaDescription ? newField("description").build() : null, + newField("queryType", newSelectionSet() + .selection(newField("name").build()) + .build() + ) + .build(), + newField("mutationType", newSelectionSet() + .selection(newField("name").build()) + .build() + ) + .build(), + newField("subscriptionType", newSelectionSet() + .selection(newField("name").build()) + .build() + ) + .build(), + newField("types", newSelectionSet() + .selection(newFragmentSpread("FullType").build()) + .build() + ) + .build(), + newField("directives", newSelectionSet().selections(filter( + newField("name").build(), + options.descriptions ? newField("description").build() : null, + newField("locations").build(), + newField("args") + .arguments(filter( + options.inputValueDeprecation ? newArgument("includeDeprecated", BooleanValue.of(true)).build() : null + )) + .selectionSet(newSelectionSet() + .selection(newFragmentSpread("InputValue").build()) + .build() + ) + .build(), + options.directiveIsRepeatable ? newField("isRepeatable").build() : null + )) + .build() + ) + .build() + ) + ).build(); + + SelectionSet fullTypeSelectionSet = newSelectionSet().selections(filter( + newField("kind").build(), + newField("name").build(), + options.descriptions ? newField("description").build() : null, + options.specifiedByUrl ? newField("specifiedByURL").build() : null, + options.isOneOf ? newField("isOneOf").build() : null, + newField("fields") + .arguments(ImmutableList.of( + newArgument("includeDeprecated", BooleanValue.of(true)).build() + )) + .selectionSet(newSelectionSet().selections(filter( + newField("name").build(), + options.descriptions ? newField("description").build() : null, + newField("args") + .arguments(filter( + options.inputValueDeprecation ? newArgument("includeDeprecated", BooleanValue.of(true)).build() : null + )) + .selectionSet(newSelectionSet() + .selection(newFragmentSpread("InputValue").build()) + .build() + ) + .build(), + newField("type", newSelectionSet() + .selection(newFragmentSpread("TypeRef").build()) + .build() + ) + .build(), + newField("isDeprecated").build(), + newField("deprecationReason").build() + )).build() + ) + .build(), + newField("inputFields") + .arguments(filter( + options.inputValueDeprecation ? newArgument("includeDeprecated", BooleanValue.of(true)).build() : null + )) + .selectionSet(newSelectionSet() + .selection(newFragmentSpread("InputValue").build()) + .build() + ) + .build(), + newField("interfaces", newSelectionSet() + .selection(newFragmentSpread("TypeRef").build()) + .build() + ) + .build(), + newField("enumValues") + .arguments(ImmutableList.of( + newArgument("includeDeprecated", BooleanValue.of(true)).build() + )) + .selectionSet(newSelectionSet().selections(filter( + newField("name").build(), + options.descriptions ? newField("description").build() : null, + newField("isDeprecated").build(), + newField("deprecationReason").build() + )) + .build() + ) + .build(), + newField("possibleTypes", newSelectionSet() + .selection(newFragmentSpread("TypeRef").build()) + .build() + ) + .build() + )).build(); + + SelectionSet inputValueSelectionSet = newSelectionSet().selections(filter( + newField("name").build(), + options.descriptions ? newField("description").build() : null, + newField("type", newSelectionSet() + .selection(newFragmentSpread("TypeRef").build()) + .build() + ) + .build(), + newField("defaultValue").build(), + options.inputValueDeprecation ? newField("isDeprecated").build() : null, + options.inputValueDeprecation ? newField("deprecationReason").build() : null + )).build(); + + SelectionSet typeRefSelectionSet = newSelectionSet().selections(filter( + newField("kind").build(), + newField("name").build() + )).build(); + + for (int i = options.typeRefFragmentDepth; i > 0; i -= 1) { + typeRefSelectionSet = newSelectionSet().selections(filter( + newField("kind").build(), + newField("name").build(), + newField("ofType", typeRefSelectionSet).build() + )).build(); + } + + return newDocument() + .definition(newOperationDefinition() + .operation(OperationDefinition.Operation.QUERY) + .name("IntrospectionQuery") + .selectionSet(newSelectionSet() + .selection(newField("__schema", schemaSelectionSet).build()) + .build() + ) + .build() + ) + .definition(newFragmentDefinition() + .name("FullType") + .typeCondition(newTypeName().name("__Type").build()) + .selectionSet(fullTypeSelectionSet) + .build() + ) + .definition(newFragmentDefinition() + .name("InputValue") + .typeCondition(newTypeName().name("__InputValue").build()) + .selectionSet(inputValueSelectionSet) + .build() + ) + .definition(newFragmentDefinition() + .name("TypeRef") + .typeCondition(newTypeName().name("__Type").build()) + .selectionSet(typeRefSelectionSet) + .build() + ) + .build(); + } + + /** + * This will build an introspection query in {@link String} form based on the options you provide + * + * @param options the options to use + * + * @return an introspection query in string form + */ + + public static String build(Options options) { + return AstPrinter.printAst(buildDocument(options)); + } + + /** + * This will build a default introspection query in {@link String} form + * + * @return an introspection query in string form + */ + public static String build() { + return build(Options.defaultOptions()); + } +} \ No newline at end of file diff --git a/src/main/java/graphql/introspection/IntrospectionResultToSchema.java b/src/main/java/graphql/introspection/IntrospectionResultToSchema.java index a0c39f8f5b..608c570909 100644 --- a/src/main/java/graphql/introspection/IntrospectionResultToSchema.java +++ b/src/main/java/graphql/introspection/IntrospectionResultToSchema.java @@ -3,9 +3,10 @@ import graphql.ExecutionResult; import graphql.PublicApi; import graphql.language.Argument; -import graphql.language.AstValueHelper; -import graphql.language.Comment; +import graphql.language.Description; import graphql.language.Directive; +import graphql.language.DirectiveDefinition; +import graphql.language.DirectiveLocation; import graphql.language.Document; import graphql.language.EnumTypeDefinition; import graphql.language.EnumValueDefinition; @@ -20,24 +21,27 @@ import graphql.language.OperationTypeDefinition; import graphql.language.ScalarTypeDefinition; import graphql.language.SchemaDefinition; -import graphql.language.SourceLocation; import graphql.language.StringValue; import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeName; import graphql.language.UnionTypeDefinition; import graphql.language.Value; +import graphql.parser.Parser; import graphql.schema.idl.ScalarInfo; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.Optional; +import static graphql.Assert.assertNotEmpty; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertTrue; +import static graphql.collect.ImmutableKit.map; +import static graphql.schema.idl.DirectiveInfo.isGraphqlSpecifiedDirective; @SuppressWarnings("unchecked") @PublicApi @@ -51,13 +55,17 @@ public class IntrospectionResultToSchema { * @return a IDL Document of the schema */ public Document createSchemaDefinition(ExecutionResult introspectionResult) { + if (!introspectionResult.isDataPresent()) { + return null; + } + Map introspectionResultMap = introspectionResult.getData(); return createSchemaDefinition(introspectionResultMap); } /** - * Returns a IDL Document that reprSesents the schema as defined by the introspection result map + * Returns a IDL Document that represents the schema as defined by the introspection result map * * @param introspectionResult the result of an introspection query on a schema * @@ -65,9 +73,8 @@ public Document createSchemaDefinition(ExecutionResult introspectionResult) { */ @SuppressWarnings("unchecked") public Document createSchemaDefinition(Map introspectionResult) { - assertTrue(introspectionResult.get("__schema") != null, "__schema expected"); Map schema = (Map) introspectionResult.get("__schema"); - + assertNotNull(schema, "__schema expected"); Map queryType = (Map) schema.get("queryType"); assertNotNull(queryType, "queryType expected"); @@ -75,14 +82,15 @@ public Document createSchemaDefinition(Map introspectionResult) boolean nonDefaultQueryName = !"Query".equals(query.getName()); SchemaDefinition.Builder schemaDefinition = SchemaDefinition.newSchemaDefinition(); - schemaDefinition.operationTypeDefinition(OperationTypeDefinition.newOperationTypeDefinition().name("query").type(query).build()); + schemaDefinition.description(toDescription(schema)); + schemaDefinition.operationTypeDefinition(OperationTypeDefinition.newOperationTypeDefinition().name("query").typeName(query).build()); Map mutationType = (Map) schema.get("mutationType"); boolean nonDefaultMutationName = false; if (mutationType != null) { TypeName mutation = TypeName.newTypeName().name((String) mutationType.get("name")).build(); nonDefaultMutationName = !"Mutation".equals(mutation.getName()); - schemaDefinition.operationTypeDefinition(OperationTypeDefinition.newOperationTypeDefinition().name("mutation").type(mutation).build()); + schemaDefinition.operationTypeDefinition(OperationTypeDefinition.newOperationTypeDefinition().name("mutation").typeName(mutation).build()); } Map subscriptionType = (Map) schema.get("subscriptionType"); @@ -90,7 +98,7 @@ public Document createSchemaDefinition(Map introspectionResult) if (subscriptionType != null) { TypeName subscription = TypeName.newTypeName().name(((String) subscriptionType.get("name"))).build(); nonDefaultSubscriptionName = !"Subscription".equals(subscription.getName()); - schemaDefinition.operationTypeDefinition(OperationTypeDefinition.newOperationTypeDefinition().name("subscription").type(subscription).build()); + schemaDefinition.operationTypeDefinition(OperationTypeDefinition.newOperationTypeDefinition().name("subscription").typeName(subscription).build()); } Document.Builder document = Document.newDocument(); @@ -101,17 +109,66 @@ public Document createSchemaDefinition(Map introspectionResult) List> types = (List>) schema.get("types"); for (Map type : types) { TypeDefinition typeDefinition = createTypeDefinition(type); - if (typeDefinition == null) continue; + if (typeDefinition == null) { + continue; + } document.definition(typeDefinition); } + List> directives = (List>) schema.get("directives"); + if (directives != null) { + for (Map directive : directives) { + DirectiveDefinition directiveDefinition = createDirective(directive); + if (directiveDefinition == null) { + continue; + } + document.definition(directiveDefinition); + } + } + return document.build(); } + private DirectiveDefinition createDirective(Map input) { + String directiveName = (String) input.get("name"); + if (isGraphqlSpecifiedDirective(directiveName)) { + return null; + } + + DirectiveDefinition.Builder directiveDefBuilder = DirectiveDefinition.newDirectiveDefinition(); + directiveDefBuilder + .name(directiveName) + .description(toDescription(input)); + + List locations = (List) input.get("locations"); + List directiveLocations = createDirectiveLocations(locations); + directiveDefBuilder.directiveLocations(directiveLocations); + + + List> args = (List>) input.get("args"); + List inputValueDefinitions = createInputValueDefinitions(args); + directiveDefBuilder.inputValueDefinitions(inputValueDefinitions); + Optional.ofNullable((Boolean) input.get("isRepeatable")).ifPresent(value -> directiveDefBuilder.repeatable(value)); + + return directiveDefBuilder.build(); + } + + private List createDirectiveLocations(List locations) { + assertNotEmpty(locations, "the locations of directive should not be empty."); + List result = new ArrayList<>(locations.size()); + for (Object location : locations) { + DirectiveLocation directiveLocation = DirectiveLocation.newDirectiveLocation().name(location.toString()).build(); + result.add(directiveLocation); + } + return result; + } + private TypeDefinition createTypeDefinition(Map type) { String kind = (String) type.get("kind"); String name = (String) type.get("name"); - if (name.startsWith("__")) return null; + if (name.startsWith("__")) { + return null; + } switch (kind) { case "INTERFACE": return createInterface(type); @@ -132,10 +189,13 @@ private TypeDefinition createTypeDefinition(Map type) { private TypeDefinition createScalar(Map input) { String name = (String) input.get("name"); - if (ScalarInfo.isStandardScalar(name)) { + if (ScalarInfo.isGraphqlSpecifiedScalar(name)) { return null; } - return ScalarTypeDefinition.newScalarTypeDefinition().name(name).build(); + return ScalarTypeDefinition.newScalarTypeDefinition() + .name(name) + .description(toDescription(input)) + .build(); } @@ -145,7 +205,7 @@ UnionTypeDefinition createUnion(Map input) { UnionTypeDefinition.Builder unionTypeDefinition = UnionTypeDefinition.newUnionTypeDefinition(); unionTypeDefinition.name((String) input.get("name")); - unionTypeDefinition.comments(toComment((String) input.get("description"))); + unionTypeDefinition.description(toDescription(input)); List> possibleTypes = (List>) input.get("possibleTypes"); @@ -162,14 +222,14 @@ EnumTypeDefinition createEnum(Map input) { assertTrue(input.get("kind").equals("ENUM"), "wrong input"); EnumTypeDefinition.Builder enumTypeDefinition = EnumTypeDefinition.newEnumTypeDefinition().name((String) input.get("name")); - enumTypeDefinition.comments(toComment((String) input.get("description"))); + enumTypeDefinition.description(toDescription(input)); List> enumValues = (List>) input.get("enumValues"); for (Map enumValue : enumValues) { EnumValueDefinition.Builder enumValueDefinition = EnumValueDefinition.newEnumValueDefinition().name((String) enumValue.get("name")); - enumValueDefinition.comments(toComment((String) enumValue.get("description"))); + enumValueDefinition.description(toDescription(enumValue)); createDeprecatedDirective(enumValue, enumValueDefinition); @@ -184,7 +244,15 @@ InterfaceTypeDefinition createInterface(Map input) { assertTrue(input.get("kind").equals("INTERFACE"), "wrong input"); InterfaceTypeDefinition.Builder interfaceTypeDefinition = InterfaceTypeDefinition.newInterfaceTypeDefinition().name((String) input.get("name")); - interfaceTypeDefinition.comments(toComment((String) input.get("description"))); + interfaceTypeDefinition.description(toDescription(input)); + if (input.containsKey("interfaces") && input.get("interfaces") != null) { + interfaceTypeDefinition.implementz( + map( + (List>) input.get("interfaces"), + this::createTypeIndirection + ) + ); + } List> fields = (List>) input.get("fields"); interfaceTypeDefinition.definitions(createFields(fields)); @@ -198,7 +266,7 @@ InputObjectTypeDefinition createInputObject(Map input) { InputObjectTypeDefinition.Builder inputObjectTypeDefinition = InputObjectTypeDefinition.newInputObjectDefinition() .name((String) input.get("name")) - .comments(toComment((String) input.get("description"))); + .description(toDescription(input)); List> fields = (List>) input.get("inputFields"); List inputValueDefinitions = createInputValueDefinitions(fields); @@ -212,12 +280,10 @@ ObjectTypeDefinition createObject(Map input) { assertTrue(input.get("kind").equals("OBJECT"), "wrong input"); ObjectTypeDefinition.Builder objectTypeDefinition = ObjectTypeDefinition.newObjectTypeDefinition().name((String) input.get("name")); - objectTypeDefinition.comments(toComment((String) input.get("description"))); + objectTypeDefinition.description(toDescription(input)); if (input.containsKey("interfaces")) { objectTypeDefinition.implementz( - ((List>) input.get("interfaces")).stream() - .map(this::createTypeIndirection) - .collect(Collectors.toList()) + map((List>) input.get("interfaces"), this::createTypeIndirection) ); } List> fields = (List>) input.get("fields"); @@ -228,10 +294,10 @@ ObjectTypeDefinition createObject(Map input) { } private List createFields(List> fields) { - List result = new ArrayList<>(); + List result = new ArrayList<>(fields.size()); for (Map field : fields) { FieldDefinition.Builder fieldDefinition = FieldDefinition.newFieldDefinition().name((String) field.get("name")); - fieldDefinition.comments(toComment((String) field.get("description"))); + fieldDefinition.description(toDescription(field)); fieldDefinition.type(createTypeIndirection((Map) field.get("type"))); createDeprecatedDirective(field, fieldDefinition); @@ -245,31 +311,29 @@ private List createFields(List> fields) { } private void createDeprecatedDirective(Map field, NodeDirectivesBuilder nodeDirectivesBuilder) { - List directives = new ArrayList<>(); - if ((Boolean) field.get("isDeprecated")) { + if (Boolean.TRUE.equals(field.get("isDeprecated"))) { String reason = (String) field.get("deprecationReason"); if (reason == null) { reason = "No longer supported"; // default according to spec } Argument reasonArg = Argument.newArgument().name("reason").value(StringValue.newStringValue().value(reason).build()).build(); Directive deprecated = Directive.newDirective().name("deprecated").arguments(Collections.singletonList(reasonArg)).build(); - directives.add(deprecated); + nodeDirectivesBuilder.directive(deprecated); } - nodeDirectivesBuilder.directives(directives); } @SuppressWarnings("unchecked") private List createInputValueDefinitions(List> args) { - List result = new ArrayList<>(); + List result = new ArrayList<>(args.size()); for (Map arg : args) { Type argType = createTypeIndirection((Map) arg.get("type")); InputValueDefinition.Builder inputValueDefinition = InputValueDefinition.newInputValueDefinition().name((String) arg.get("name")).type(argType); - inputValueDefinition.comments(toComment((String) arg.get("description"))); + inputValueDefinition.description(toDescription(arg)); String valueLiteral = (String) arg.get("defaultValue"); if (valueLiteral != null) { - Value defaultValue = AstValueHelper.valueFromAst(valueLiteral); - inputValueDefinition.defaultValue(defaultValue); + Value value = Parser.parseValue(valueLiteral); + inputValueDefinition.defaultValue(value); } result.add(inputValueDefinition.build()); } @@ -296,10 +360,19 @@ private Type createTypeIndirection(Map type) { } } - private List toComment(String description) { - if (description == null) return Collections.emptyList(); - Comment comment = new Comment(description, new SourceLocation(1, 1)); - return Collections.singletonList(comment); + private Description toDescription(Map input) { + String description = (String) input.get("description"); + if (description == null) { + return null; + } + + String[] lines = description.split("\n"); + if (lines.length > 1) { + return new Description(description, null, true); + } else { + return new Description(description, null, false); + } } + } diff --git a/src/main/java/graphql/introspection/IntrospectionWithDirectivesSupport.java b/src/main/java/graphql/introspection/IntrospectionWithDirectivesSupport.java new file mode 100644 index 0000000000..5d264e113c --- /dev/null +++ b/src/main/java/graphql/introspection/IntrospectionWithDirectivesSupport.java @@ -0,0 +1,320 @@ +package graphql.introspection; + +import com.google.common.collect.ImmutableSet; +import graphql.DirectivesUtil; +import graphql.PublicApi; +import graphql.PublicSpi; +import graphql.collect.ImmutableKit; +import graphql.execution.ValuesResolver; +import graphql.language.AstPrinter; +import graphql.language.Node; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.InputValueWithState; +import graphql.schema.SchemaTransformer; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import org.jspecify.annotations.NonNull; + +import java.util.List; +import java.util.Set; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Scalars.GraphQLString; +import static graphql.introspection.Introspection.__EnumValue; +import static graphql.introspection.Introspection.__Field; +import static graphql.introspection.Introspection.__InputValue; +import static graphql.introspection.Introspection.__Schema; +import static graphql.introspection.Introspection.__Type; +import static graphql.schema.FieldCoordinates.coordinates; +import static graphql.schema.GraphQLList.list; +import static graphql.schema.GraphQLNonNull.nonNull; +import static graphql.schema.GraphQLObjectType.newObject; +import static graphql.util.TraversalControl.CONTINUE; + +/** + * The graphql specification does not allow you to retrieve the directives and their argument values that + * are present on types, enums, fields and input fields, so this class allows you to change the schema + * and enhance the Introspection types to contain this information. + * + * This allows you to get a directive say like `@example(argName : "someValue")` that is on a field or type + * at introspection time and act on it. + * + * This class takes a predicate that allows you to filter the directives you want to expose to the world. + * + * An `appliedDirectives` field is added and this contains extra fields that hold the directives and their applied values. + * + * For example the `__Field` type becomes as follows: + * + *
+ *      type __Field {
+ *          name: String!
+ *          // other fields ...
+ *          appliedDirectives: [_AppliedDirective!]!   // NEW FIELD
+ *      }
+ *
+ *     type _AppliedDirective {                        // NEW INTROSPECTION TYPE
+ *          name: String!
+ *          args: [_DirectiveArgument!]!
+ *      }
+ *
+ *      type _DirectiveArgument {                      // NEW INTROSPECTION TYPE
+ *          name: String!
+ *          value: String!
+ *      }
+ *  
+ */ +@PublicApi +public class IntrospectionWithDirectivesSupport { + + private final DirectivePredicate directivePredicate; + private final String typePrefix; + + private final Set INTROSPECTION_ELEMENTS = ImmutableSet.of( + __Schema.getName(), __Type.getName(), __Field.getName(), __EnumValue.getName(), __InputValue.getName() + ); + + + /** + * This version lists all directives on a schema element + */ + public IntrospectionWithDirectivesSupport() { + this(env -> true); + } + + /** + * This version allows you to filter what directives are listed via the provided predicate + * + * @param directivePredicate the filtering predicate to decide what directives are shown + */ + public IntrospectionWithDirectivesSupport(DirectivePredicate directivePredicate) { + this(directivePredicate, "_"); + } + + /** + * This version allows you to filter what directives are listed via the provided predicate + * + * Some graphql systems (graphql-js in 2021) cannot cope with extra types starting with `__` + * so we use a `_` as a prefix by default. You can supply your own prefix via this constructor. + * + * See: https://github.com/graphql-java/graphql-java/pull/2221 for more details + * + * @param directivePredicate the filtering predicate to decide what directives are shown + * @param typePrefix the prefix to put on the new `AppliedDirectives` type + */ + public IntrospectionWithDirectivesSupport(DirectivePredicate directivePredicate, String typePrefix) { + this.directivePredicate = assertNotNull(directivePredicate); + this.typePrefix = assertNotNull(typePrefix); + } + + /** + * This will transform the schema to have the new extension shapes + * + * @param schema the original schema + * + * @return the transformed schema with new extension types and fields in it for Introspection + */ + public GraphQLSchema apply(GraphQLSchema schema) { + GraphQLObjectType directiveArgumentType = mkDirectiveArgumentType(typePrefix + "DirectiveArgument"); + GraphQLObjectType appliedDirectiveType = mkAppliedDirectiveType(typePrefix + "AppliedDirective", directiveArgumentType); + GraphQLTypeVisitorStub visitor = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) { + GraphQLCodeRegistry.Builder codeRegistry = context.getVarFromParents(GraphQLCodeRegistry.Builder.class); + // we need to change __XXX introspection types to have directive extensions + if (INTROSPECTION_ELEMENTS.contains(objectType.getName())) { + GraphQLObjectType newObjectType = addAppliedDirectives(objectType, codeRegistry, appliedDirectiveType, directiveArgumentType); + return changeNode(context, newObjectType); + } + return CONTINUE; + } + }; + GraphQLSchema newSchema = SchemaTransformer.transformSchema(schema, visitor); + return addDirectiveDefinitionFilter(newSchema); + } + + private GraphQLObjectType mkDirectiveArgumentType(String name) { + return newObject().name(name) + .description("Directive arguments can have names and values. The values are in graphql SDL syntax printed as a string." + + " This type is NOT specified by the graphql specification presently.") + .field(fld -> fld + .name("name") + .type(nonNull(GraphQLString))) + .field(fld -> fld + .name("value") + .type(nonNull(GraphQLString))) + .build(); + } + + private GraphQLObjectType mkAppliedDirectiveType(String name, GraphQLType directiveArgumentType) { + return newObject().name(name) + .description("An Applied Directive is an instances of a directive as applied to a schema element." + + " This type is NOT specified by the graphql specification presently.") + .field(fld -> fld + .name("name") + .type(nonNull(GraphQLString))) + .field(fld -> fld + .name("args") + .type(nonNull(list(nonNull(directiveArgumentType))))) + .build(); + } + + private GraphQLSchema addDirectiveDefinitionFilter(GraphQLSchema schema) { + DataFetcher df = env -> { + List definedDirectives = env.getGraphQLSchema().getDirectives(); + return filterDirectives(schema, true, null, definedDirectives); + }; + GraphQLCodeRegistry codeRegistry = schema.getCodeRegistry().transform(bld -> + bld.dataFetcher(coordinates(__Schema, "directives"), df)); + return schema.transform(bld -> bld.codeRegistry(codeRegistry)); + } + + private GraphQLObjectType addAppliedDirectives(GraphQLObjectType originalType, GraphQLCodeRegistry.Builder codeRegistry, GraphQLObjectType appliedDirectiveType, GraphQLObjectType directiveArgumentType) { + GraphQLObjectType objectType = originalType.transform(bld -> bld.field(fld -> fld.name("appliedDirectives").type(nonNull(list(nonNull(appliedDirectiveType)))))); + DataFetcher df = env -> { + Object source = env.getSource(); + GraphQLSchema schema = env.getGraphQLSchema(); + if (source instanceof GraphQLDirectiveContainer) { + GraphQLDirectiveContainer type = env.getSource(); + List appliedDirectives = DirectivesUtil.toAppliedDirectives(type); + return filterAppliedDirectives(schema, false, type, appliedDirectives); + } + if (source instanceof GraphQLSchema) { + List appliedDirectives = DirectivesUtil.toAppliedDirectives(schema.getSchemaAppliedDirectives(), schema.getSchemaDirectives()); + return filterAppliedDirectives(schema, true, null, appliedDirectives); + } + return assertShouldNeverHappen("What directive containing element have we not considered? - %s", originalType); + }; + DataFetcher argsDF = env -> { + final GraphQLAppliedDirective directive = env.getSource(); + // we only show directive arguments that have values set on them + return ImmutableKit.filter(directive.getArguments(), + arg -> arg.getArgumentValue().isSet()); + }; + DataFetcher argValueDF = env -> { + final GraphQLAppliedDirectiveArgument argument = env.getSource(); + InputValueWithState value = argument.getArgumentValue(); + Node literal = ValuesResolver.valueToLiteral(value, argument.getType(), env.getGraphQlContext(), env.getLocale()); + return AstPrinter.printAst(literal); + }; + DataFetcher nameDF = env -> { + if (env.getSource() instanceof GraphQLNamedSchemaElement) { + return ((GraphQLNamedSchemaElement) env.getSource()).getName(); + } + return null; + }; + + codeRegistry.dataFetcher(coordinates(objectType, "appliedDirectives"), df); + codeRegistry.dataFetcher(coordinates(appliedDirectiveType, "name"), nameDF); + codeRegistry.dataFetcher(coordinates(appliedDirectiveType, "args"), argsDF); + + codeRegistry.dataFetcher(coordinates(directiveArgumentType, "name"), nameDF); + codeRegistry.dataFetcher(coordinates(directiveArgumentType, "value"), argValueDF); + return objectType; + } + + private List filterDirectives(GraphQLSchema schema, boolean isDefinedDirective, GraphQLDirectiveContainer container, List directives) { + return ImmutableKit.filter(directives, + directive -> { + DirectivePredicateEnvironment env = buildDirectivePredicateEnv(schema, isDefinedDirective, container, directive.getName()); + return directivePredicate.isDirectiveIncluded(env); + }); + } + + private List filterAppliedDirectives(GraphQLSchema schema, boolean isDefinedDirective, GraphQLDirectiveContainer container, List directives) { + return ImmutableKit.filter(directives, + directive -> { + DirectivePredicateEnvironment env = buildDirectivePredicateEnv(schema, isDefinedDirective, container, directive.getName()); + return directivePredicate.isDirectiveIncluded(env); + }); + } + + @NonNull + private DirectivePredicateEnvironment buildDirectivePredicateEnv(GraphQLSchema schema, boolean isDefinedDirective, GraphQLDirectiveContainer container, String directiveName) { + return new DirectivePredicateEnvironment() { + @Override + public GraphQLDirectiveContainer getDirectiveContainer() { + return container; + } + + @Override + public boolean isDefinedDirective() { + return isDefinedDirective; + } + + @Override + public String getDirectiveName() { + return directiveName; + } + + @Override + public GraphQLSchema getSchema() { + return schema; + } + }; + } + + /** + * The parameter environment on a call to {@link DirectivePredicate} + */ + @PublicApi + public interface DirectivePredicateEnvironment { + + /** + * The schema element that contained this directive. If this is a {@link GraphQLSchema} + * then this will be null. This is the only case where this is true. + * + * @return the schema element that contained this directive. + */ + GraphQLDirectiveContainer getDirectiveContainer(); + + /** + * @return the directive to be included + */ + String getDirectiveName(); + + /** + * A schema has two list of directives. A list of directives that are defined + * in that schema and the list of directives that are applied to a schema element. + * + * This returns true if this filtering represents the defined directives. + * + * @return true if this is filtering defined directives + */ + boolean isDefinedDirective(); + + /** + * @return graphql schema in place + */ + GraphQLSchema getSchema(); + } + + + /** + * A callback which allows you to decide what directives may be included + * in introspection extensions + */ + @PublicSpi + @FunctionalInterface + public interface DirectivePredicate { + /** + * Return true if the directive should be included + * + * @param environment the callback parameters + * + * @return true if the directive should be included + */ + boolean isDirectiveIncluded(DirectivePredicateEnvironment environment); + } +} diff --git a/src/main/java/graphql/language/AbstractDescribedNode.java b/src/main/java/graphql/language/AbstractDescribedNode.java new file mode 100644 index 0000000000..af963e7ab5 --- /dev/null +++ b/src/main/java/graphql/language/AbstractDescribedNode.java @@ -0,0 +1,22 @@ +package graphql.language; + +import graphql.PublicApi; + +import java.util.List; +import java.util.Map; + +@PublicApi +public abstract class AbstractDescribedNode extends AbstractNode implements DescribedNode { + + protected Description description; + + public AbstractDescribedNode(SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData, Description description) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.description = description; + } + + @Override + public Description getDescription() { + return description; + } +} diff --git a/src/main/java/graphql/language/AbstractNode.java b/src/main/java/graphql/language/AbstractNode.java index 68c167bcd5..bd3d74426e 100644 --- a/src/main/java/graphql/language/AbstractNode.java +++ b/src/main/java/graphql/language/AbstractNode.java @@ -1,38 +1,65 @@ package graphql.language; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import graphql.Assert; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; + +import static graphql.collect.ImmutableKit.map; @PublicApi +@NullMarked public abstract class AbstractNode implements Node { - private final SourceLocation sourceLocation; - private final List comments; + private final @Nullable SourceLocation sourceLocation; + private final ImmutableList comments; + private final IgnoredChars ignoredChars; + private final ImmutableMap additionalData; - public AbstractNode(SourceLocation sourceLocation, List comments) { - this.sourceLocation = sourceLocation; + public AbstractNode(@Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars) { + this(sourceLocation, comments, ignoredChars, ImmutableKit.emptyMap()); + } + + public AbstractNode(@Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { Assert.assertNotNull(comments, "comments can't be null"); - this.comments = new ArrayList<>(comments); + Assert.assertNotNull(ignoredChars, "ignoredChars can't be null"); + Assert.assertNotNull(additionalData, "additionalData can't be null"); + + this.sourceLocation = sourceLocation; + this.additionalData = ImmutableMap.copyOf(additionalData); + this.comments = ImmutableList.copyOf(comments); + this.ignoredChars = ignoredChars; } @Override - public SourceLocation getSourceLocation() { + public @Nullable SourceLocation getSourceLocation() { return sourceLocation; } @Override public List getComments() { - return new ArrayList<>(comments); + return comments; + } + + @Override + public IgnoredChars getIgnoredChars() { + return ignoredChars; } + public Map getAdditionalData() { + return additionalData; + } + @SuppressWarnings("unchecked") - protected V deepCopy(V nullableObj) { + protected @Nullable V deepCopy(@Nullable V nullableObj) { if (nullableObj == null) { return null; } @@ -40,11 +67,10 @@ protected V deepCopy(V nullableObj) { } @SuppressWarnings("unchecked") - protected List deepCopy(List list) { + protected @Nullable List deepCopy(@Nullable List list) { if (list == null) { return null; } - return list.stream().map(Node::deepCopy).map(node -> (V) node).collect(Collectors.toList()); + return map(list, n -> (V) n.deepCopy()); } - } diff --git a/src/main/java/graphql/language/Argument.java b/src/main/java/graphql/language/Argument.java index 2d1ccd61fc..9125d25f1f 100644 --- a/src/main/java/graphql/language/Argument.java +++ b/src/main/java/graphql/language/Argument.java @@ -1,24 +1,33 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class Argument extends AbstractNode implements NamedNode { - private String name; - private Value value; + public static final String CHILD_VALUE = "value"; + private final String name; + private final Value value; @Internal - protected Argument(String name, Value value, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected Argument(String name, Value value, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; this.value = value; } @@ -26,11 +35,19 @@ protected Argument(String name, Value value, SourceLocation sourceLocation, List /** * alternative to using a Builder for convenience * - * @param name - * @param value + * @param name of the argument + * @param value of the argument */ public Argument(String name, Value value) { - this(name, value, null, new ArrayList<>()); + this(name, value, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); + } + + public static Builder newArgument() { + return new Builder(); + } + + public static Builder newArgument(String name, Value value) { + return new Builder().name(name).value(value); } @Override @@ -42,36 +59,43 @@ public Value getValue() { return value; } - public void setName(String name) { - this.name = name; + @Override + public List getChildren() { + return ImmutableList.of(value); } - public void setValue(Value value) { - this.value = value; + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_VALUE, value) + .build(); } @Override - public List getChildren() { - List result = new ArrayList<>(); - result.add(value); - return result; + public Argument withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .value(newChildren.getChildOrNull(CHILD_VALUE)) + ); } - @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Argument that = (Argument) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public Argument deepCopy() { - return new Argument(name, deepCopy(value), getSourceLocation(), getComments()); + return new Argument(name, deepCopy(value), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -87,14 +111,6 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitArgument(this, context); } - public static Builder newArgument() { - return new Builder(); - } - - public static Builder newArgument(String name, Value value) { - return new Builder().name(name).value(value); - } - public Argument transform(Consumer builderConsumer) { Builder builder = new Builder(this); builderConsumer.accept(builder); @@ -103,18 +119,22 @@ public Argument transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Value value; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(Argument existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.value = existing.getValue(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -133,13 +153,27 @@ public Builder value(Value value) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public Argument build() { - Argument argument = new Argument(name, value, sourceLocation, comments); - return argument; + return new Argument(name, value, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/ArrayValue.java b/src/main/java/graphql/language/ArrayValue.java index 9946841841..2d5ae6c100 100644 --- a/src/main/java/graphql/language/ArrayValue.java +++ b/src/main/java/graphql/language/ArrayValue.java @@ -1,34 +1,50 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi +@NullMarked public class ArrayValue extends AbstractNode implements Value { - private final List values = new ArrayList<>(); + public static final String CHILD_VALUES = "values"; + private final ImmutableList values; @Internal - protected ArrayValue(List values, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); - this.values.addAll(values); + protected ArrayValue(List values, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.values = ImmutableList.copyOf(values); } /** * alternative to using a Builder for convenience * - * @param values + * @param values of the array */ public ArrayValue(List values) { - super(null, new ArrayList<>()); - this.values.addAll(values); + this(values, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); + } + + public static Builder newArrayValue() { + return new Builder(); } public List getValues() { @@ -37,13 +53,31 @@ public List getValues() { @Override public List getChildren() { - return new ArrayList<>(values); + return ImmutableList.copyOf(values); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_VALUES, values) + .build(); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public ArrayValue withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .values(newChildren.getChildren(CHILD_VALUES)) + ); + } + + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; } @@ -57,7 +91,8 @@ public String toString() { @Override public ArrayValue deepCopy() { - return new ArrayValue(deepCopy(values), getSourceLocation(), getComments()); + List copiedValues = assertNotNull(deepCopy(values)); + return new ArrayValue(copiedValues, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -65,28 +100,29 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitArrayValue(this, context); } - public static Builder newArrayValue() { - return new Builder(); - } - public ArrayValue transform(Consumer builderConsumer) { Builder builder = new Builder(this); builderConsumer.accept(builder); return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List values = new ArrayList<>(); - private List comments = new ArrayList<>(); + private ImmutableList values = emptyList(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(ArrayValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); - this.values = existing.getValues(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.values = ImmutableList.copyOf(existing.getValues()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -95,23 +131,38 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder values(List values) { - this.values = values; + this.values = ImmutableList.copyOf(values); return this; } public Builder value(Value value) { - this.values.add(value); + this.values = ImmutableKit.addToList(this.values, value); return this; } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ArrayValue build() { - ArrayValue arrayValue = new ArrayValue(values, sourceLocation, comments); - return arrayValue; + return new ArrayValue(values, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/AstComparator.java b/src/main/java/graphql/language/AstComparator.java index bc58052bc8..08e1d5a310 100644 --- a/src/main/java/graphql/language/AstComparator.java +++ b/src/main/java/graphql/language/AstComparator.java @@ -9,25 +9,54 @@ @Internal public class AstComparator { + private AstComparator() { - public boolean isEqual(Node node1, Node node2) { - if (null == node1) return null == node2; - if (!node1.isEqualTo(node2)) return false; + } + + public static boolean sameValue(Value value1, Value value2) { + if (value1 == null && value2 == null) { + return true; + } + if (value1 == null) { + return false; + } + if (value2 == null) { + return false; + } + return isEqual(value1, value2); + } + + + public static boolean isEqual(Node node1, Node node2) { + if (null == node1) { + return null == node2; + } + if (!node1.isEqualTo(node2)) { + return false; + } List childs1 = node1.getChildren(); List childs2 = node2.getChildren(); - if (childs1.size() != childs2.size()) return false; + if (childs1.size() != childs2.size()) { + return false; + } for (int i = 0; i < childs1.size(); i++) { - if (!isEqual(childs1.get(i), childs2.get(i))) return false; + if (!isEqual(childs1.get(i), childs2.get(i))) { + return false; + } } return true; } - public boolean isEqual(List nodes1, List nodes2) { - if (nodes1.size() != nodes2.size()) return false; + public static boolean isEqual(List nodes1, List nodes2) { + if (nodes1.size() != nodes2.size()) { + return false; + } Iterator iter1 = nodes1.iterator(); Iterator iter2 = nodes2.iterator(); while (iter1.hasNext()) { - if (!isEqual(iter1.next(), iter2.next())) return false; + if (!isEqual(iter1.next(), iter2.next())) { + return false; + } } return true; } diff --git a/src/main/java/graphql/language/AstNodeAdapter.java b/src/main/java/graphql/language/AstNodeAdapter.java new file mode 100644 index 0000000000..304fdfb5e9 --- /dev/null +++ b/src/main/java/graphql/language/AstNodeAdapter.java @@ -0,0 +1,38 @@ +package graphql.language; + +import graphql.PublicApi; +import graphql.util.NodeAdapter; +import graphql.util.NodeLocation; + +import java.util.List; +import java.util.Map; + +/** + * Adapts an Ast node to the general node from the util package + */ +@PublicApi +public class AstNodeAdapter implements NodeAdapter { + + public static final AstNodeAdapter AST_NODE_ADAPTER = new AstNodeAdapter(); + + private AstNodeAdapter() { + + } + + @Override + public Map> getNamedChildren(Node node) { + return node.getNamedChildren().getChildren(); + } + + @Override + public Node withNewChildren(Node node, Map> newChildren) { + NodeChildrenContainer nodeChildrenContainer = NodeChildrenContainer.newNodeChildrenContainer(newChildren).build(); + return node.withNewChildren(nodeChildrenContainer); + } + + @Override + public Node removeChild(Node node, NodeLocation location) { + return NodeUtil.removeChild(node, location); + } + +} \ No newline at end of file diff --git a/src/main/java/graphql/language/AstPrinter.java b/src/main/java/graphql/language/AstPrinter.java index 0e124e10f2..a5e1535ea5 100644 --- a/src/main/java/graphql/language/AstPrinter.java +++ b/src/main/java/graphql/language/AstPrinter.java @@ -1,20 +1,19 @@ package graphql.language; -import graphql.AssertException; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.IOException; +import java.io.UncheckedIOException; import java.io.Writer; -import java.util.Arrays; -import java.util.Collections; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertTrue; -import static java.lang.String.valueOf; -import static java.util.stream.Collectors.joining; +import static graphql.util.EscapeUtil.escapeJsonStringTo; /** * This can take graphql language AST and print it out as a string @@ -23,9 +22,26 @@ @PublicApi public class AstPrinter { - private static final Map, NodePrinter> printers = new LinkedHashMap<>(); + /** + * @return an {@link AstPrinter} that is in full print mode + */ + static AstPrinter full() { + return new AstPrinter(false); + } + + /** + * @return an {@link AstPrinter} that is in compact print mode + */ + static AstPrinter compact() { + return new AstPrinter(true); + } + + private final Map, NodePrinter> printers = new LinkedHashMap<>(); - static { + private final boolean compactMode; + + AstPrinter(boolean compactMode) { + this.compactMode = compactMode; printers.put(Argument.class, argument()); printers.put(ArrayValue.class, value()); printers.put(BooleanValue.class, value()); @@ -61,6 +77,7 @@ public class AstPrinter { printers.put(ScalarTypeDefinition.class, scalarTypeDefinition()); printers.put(ScalarTypeExtensionDefinition.class, scalarTypeExtensionDefinition()); printers.put(SchemaDefinition.class, schemaDefinition()); + printers.put(SchemaExtensionDefinition.class, schemaExtensionDefinition()); printers.put(SelectionSet.class, selectionSet()); printers.put(StringValue.class, value()); printers.put(TypeName.class, type()); @@ -70,435 +87,627 @@ public class AstPrinter { printers.put(VariableReference.class, variableReference()); } - private static NodePrinter argument() { - return (out, node) -> out.printf("%s: %s", node.getName(), value(node.getValue())); + private NodePrinter argument() { + if (compactMode) { + return (out, node) -> { + out.append(node.getName()).append(':'); + value(out, node.getValue()); + }; + } + return (out, node) -> { + out.append(node.getName()).append(": "); + value(out, node.getValue()); + }; } - private static NodePrinter document() { - return (out, node) -> out.printf("%s\n", join(node.getDefinitions(), "\n\n")); + private NodePrinter document() { + if (compactMode) { + return (out, node) -> join(out, node.getDefinitions(), " "); + } + return (out, node) -> { + join(out, node.getDefinitions(), "\n\n"); + out.append('\n'); + }; } - private static NodePrinter directive() { + private NodePrinter directive() { + final String argSep = compactMode ? "," : ", "; return (out, node) -> { - String arguments = wrap("(", join(node.getArguments(), ", "), ")"); - out.printf("@%s%s", node.getName(), arguments); + out.append('@'); + out.append(node.getName()); + if (!isEmpty(node.getArguments())) { + out.append('('); + join(out, node.getArguments(), argSep); + out.append(')'); + } }; } - private static NodePrinter directiveDefinition() { + private NodePrinter directiveDefinition() { + final String argSep = compactMode ? "," : ", "; return (out, node) -> { - String arguments = wrap("(", join(node.getInputValueDefinitions(), ", "), ")"); - String locations = join(node.getDirectiveLocations(), " | "); - out.printf("directive @%s%s on %s", node.getName(), arguments, locations); + description(out, node); + out.append("directive @"); + out.append(node.getName()); + if (!isEmpty(node.getInputValueDefinitions())) { + out.append('('); + join(out, node.getInputValueDefinitions(), argSep); + out.append(')'); + } + out.append(" "); + if (node.isRepeatable()) { + out.append("repeatable "); + } + out.append("on "); + join(out, node.getDirectiveLocations(), " | "); }; } - private static NodePrinter directiveLocation() { - return (out, node) -> out.print(node.getName()); + private NodePrinter directiveLocation() { + return (out, node) -> out.append(node.getName()); } - private static NodePrinter enumTypeDefinition() { + private NodePrinter enumTypeDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", - spaced( - "enum", - node.getName(), - directives(node.getDirectives()), - block(node.getEnumValueDefinitions()) - )); + description(out, node); + out.append("enum "); + out.append(node.getName()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + out.append(' '); + block(out, node.getEnumValueDefinitions()); }; } - private static NodePrinter enumValue() { - return (out, node) -> out.printf("%s", node.getName()); + private NodePrinter enumValue() { + return (out, node) -> out.append(node.getName()); } - private static NodePrinter enumValueDefinition() { + private NodePrinter enumValueDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", - spaced( - node.getName(), - directives(node.getDirectives()) - )); + description(out, node); + out.append(node.getName()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } }; } - private static NodePrinter field() { + private NodePrinter field() { + final String argSep = compactMode ? "," : ", "; + final String aliasSuffix = compactMode ? ":" : ": "; return (out, node) -> { - String alias = wrap("", node.getAlias(), ": "); String name = node.getName(); - String arguments = wrap("(", join(node.getArguments(), ", "), ")"); - String directives = directives(node.getDirectives()); - String selectionSet = node(node.getSelectionSet()); - - out.printf("%s", spaced( - alias + name + arguments, - directives, - selectionSet - )); + if (!isEmpty(node.getAlias())) { + out.append(node.getAlias()); + out.append(aliasSuffix); + } + out.append(name); + if (!isEmpty(node.getArguments())) { + out.append('('); + join(out, node.getArguments(), argSep); + out.append(')'); + } + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + if (node.getSelectionSet() != null && !isEmpty(node.getSelectionSet().getSelections())) { + if (!compactMode) { + out.append(' '); + } + node(out, node.getSelectionSet()); + } }; } - - private static NodePrinter fieldDefinition() { + private NodePrinter fieldDefinition() { + final String argSep = compactMode ? "," : ", "; return (out, node) -> { - out.printf("%s", comments(node)); - String args; - if (hasComments(node.getInputValueDefinitions())) { - args = join(node.getInputValueDefinitions(), "\n"); - out.printf("%s", node.getName() + - wrap("(\n", args, "\n)") + - ": " + - spaced( - type(node.getType()), - directives(node.getDirectives()) - ) - ); + if (hasDescription(node) && !compactMode) { + description(out, node); + out.append(node.getName()); + if (!isEmpty(node.getInputValueDefinitions())) { + out.append("(\n"); + join(out, node.getInputValueDefinitions(), "\n"); + out.append(')'); + } + out.append(": "); + type(out, node.getType()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } } else { - args = join(node.getInputValueDefinitions(), ", "); - out.printf("%s", node.getName() + - wrap("(", args, ")") + - ": " + - spaced( - type(node.getType()), - directives(node.getDirectives()) - ) - ); + out.append(node.getName()); + if (!isEmpty(node.getInputValueDefinitions())) { + out.append('('); + join(out, node.getInputValueDefinitions(), argSep); + out.append(')'); + } + out.append(": "); + type(out, node.getType()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } } }; } - private static boolean hasComments(List nodes) { - return nodes.stream().anyMatch(it -> it.getComments().size() > 0); + private static boolean hasDescription(Node node) { + if (node instanceof AbstractDescribedNode) { + AbstractDescribedNode describedNode = (AbstractDescribedNode) node; + return describedNode.getDescription() != null; + } + return false; } - private static NodePrinter fragmentDefinition() { + private NodePrinter fragmentDefinition() { return (out, node) -> { - String name = node.getName(); - String typeCondition = type(node.getTypeCondition()); - String directives = directives(node.getDirectives()); - String selectionSet = node(node.getSelectionSet()); - - out.printf("fragment %s on %s ", name, typeCondition); - out.printf("%s", directives + selectionSet); + out.append("fragment "); + out.append(node.getName()); + out.append(" on "); + type(out, node.getTypeCondition()); + out.append(' '); + directives(out, node.getDirectives()); + node(out, node.getSelectionSet()); }; } - private static NodePrinter fragmentSpread() { + private NodePrinter fragmentSpread() { return (out, node) -> { - String name = node.getName(); - String directives = directives(node.getDirectives()); - - out.printf("...%s%s", name, directives); + out.append("..."); + out.append(node.getName()); + directives(out, node.getDirectives()); }; } - private static NodePrinter inlineFragment() { + private NodePrinter inlineFragment() { return (out, node) -> { - String typeCondition = wrap("on ", type(node.getTypeCondition()), ""); - String directives = directives(node.getDirectives()); - String selectionSet = node(node.getSelectionSet()); - - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "...", - typeCondition, - directives, - selectionSet - )); + out.append("..."); + if (compactMode) { + // believe it or not but "...on Foo" is valid syntax + if (node.getTypeCondition() != null) { + out.append("on "); + type(out, node.getTypeCondition()); + } + directives(out, node.getDirectives()); + node(out, node.getSelectionSet()); + } else { + if (node.getTypeCondition() != null) { + out.append(" on "); + type(out, node.getTypeCondition()); + } + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + out.append(' '); + node(out, node.getSelectionSet()); + } }; } - private static NodePrinter inputObjectTypeDefinition() { + private NodePrinter inputObjectTypeDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "input", - node.getName(), - directives(node.getDirectives()), - block(node.getInputValueDefinitions()) - ) - ); + description(out, node); + out.append("input "); + out.append(node.getName()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + if (!isEmpty(node.getInputValueDefinitions())) { + out.append(' '); + block(out, node.getInputValueDefinitions()); + } }; } - private static NodePrinter inputValueDefinition() { + private NodePrinter inputValueDefinition() { + String nameTypeSep = compactMode ? ":" : ": "; + String defaultValueEquals = compactMode ? "=" : "= "; return (out, node) -> { - Value defaultValue = node.getDefaultValue(); - out.printf("%s", comments(node)); - out.printf("%s", spaced( - node.getName() + ": " + type(node.getType()), - wrap("= ", defaultValue, ""), - directives(node.getDirectives()) - ) - ); + Value defaultValue = node.getDefaultValue(); + description(out, node); + out.append(node.getName()); + out.append(nameTypeSep); + type(out, node.getType()); + if (defaultValue != null) { + out.append(' '); + out.append(defaultValueEquals); + node(out, defaultValue); + } + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } }; } - private static NodePrinter interfaceTypeDefinition() { + private NodePrinter interfaceTypeDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "interface", - node.getName(), - directives(node.getDirectives()), - block(node.getFieldDefinitions()) - ) - ); + description(out, node); + out.append("interface "); + out.append(node.getName()); + if (!isEmpty(node.getImplements())) { + out.append(" implements "); + join(out, node.getImplements(), " & "); + } + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + if (!isEmpty(node.getFieldDefinitions())) { + out.append(' '); + block(out, node.getFieldDefinitions()); + } }; } - private static NodePrinter objectField() { - return (out, node) -> out.printf("%s : %s", node.getName(), value(node.getValue())); + private NodePrinter objectField() { + String nameValueSep = compactMode ? ":" : " : "; + return (out, node) -> { + out.append(node.getName()); + out.append(nameValueSep); + value(out, node.getValue()); + }; } - - private static NodePrinter operationDefinition() { + private NodePrinter operationDefinition() { + final String argSep = compactMode ? "," : ", "; return (out, node) -> { - String op = node.getOperation().toString().toLowerCase(); String name = node.getName(); - String varDefinitions = wrap("(", join(nvl(node.getVariableDefinitions()), ", "), ")"); - String directives = directives(node.getDirectives()); - String selectionSet = node(node.getSelectionSet()); - // Anonymous queries with no directives or variable definitions can use // the query short form. - if (isEmpty(name) && isEmpty(directives) && isEmpty(varDefinitions) && op.equals("QUERY")) { - out.printf("%s", selectionSet); + if (isEmpty(name) && isEmpty(node.getDirectives()) && isEmpty(node.getVariableDefinitions()) + && node.getOperation() == OperationDefinition.Operation.QUERY) { + node(out, node.getSelectionSet()); } else { - out.printf("%s", spaced(op, smooshed(name, varDefinitions), directives, selectionSet)); + out.append(node.getOperation().toString().toLowerCase()); + if (!isEmpty(name)) { + out.append(' '); + out.append(name); + } + if (!isEmpty(node.getVariableDefinitions())) { + if (isEmpty(name)) { + out.append(' '); + } + out.append('('); + join(out, node.getVariableDefinitions(), argSep); + out.append(')'); + } + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + if (!compactMode) { + out.append(' '); + } + node(out, node.getSelectionSet()); } }; } - private static NodePrinter operationTypeDefinition() { - return (out, node) -> out.printf("%s: %s", node.getName(), type(node.getType())); - } - - private static NodePrinter objectTypeDefinition() { + private NodePrinter operationTypeDefinition() { + String nameTypeSep = compactMode ? ":" : ": "; return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "type", - node.getName(), - wrap("implements ", join(node.getImplements(), " & "), ""), - directives(node.getDirectives()), - block(node.getFieldDefinitions()) - )); + out.append(node.getName()); + out.append(nameTypeSep); + type(out, node.getTypeName()); }; } - private static NodePrinter selectionSet() { + private NodePrinter objectTypeDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", block(node.getSelections())); + description(out, node); + out.append("type "); + out.append(node.getName()); + if (!isEmpty(node.getImplements())) { + out.append(" implements "); + join(out, node.getImplements(), " & "); + } + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + if (!isEmpty(node.getFieldDefinitions())) { + out.append(' '); + block(out, node.getFieldDefinitions()); + } }; } - private static NodePrinter scalarTypeDefinition() { + private NodePrinter selectionSet() { + return (out, node) -> block(out, node.getSelections()); + } + + private NodePrinter scalarTypeDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "scalar", - node.getName(), - directives(node.getDirectives()))); + description(out, node); + out.append("scalar "); + out.append(node.getName()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } }; } - private static NodePrinter schemaDefinition() { + private NodePrinter schemaDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "schema", - directives(node.getDirectives()), - block(node.getOperationTypeDefinitions()) - - )); + description(out, node); + out.append("schema "); + if (!isEmpty(node.getDirectives())) { + directives(out, node.getDirectives()); + out.append(' '); + } + block(out, node.getOperationTypeDefinitions()); }; } - private static NodePrinter type() { - return (out, node) -> out.print(type(node)); + private NodePrinter> type() { + return this::type; } - static private String type(Type type) { + private void type(StringBuilder out, Type type) { if (type instanceof NonNullType) { NonNullType inner = (NonNullType) type; - return wrap("", type(inner.getType()), "!"); + type(out, inner.getType()); + out.append('!'); } else if (type instanceof ListType) { ListType inner = (ListType) type; - return wrap("[", type(inner.getType()), "]"); + out.append('['); + type(out, inner.getType()); + out.append(']'); } else { TypeName inner = (TypeName) type; - return inner.getName(); + out.append(inner.getName()); } } - private static NodePrinter objectTypeExtensionDefinition() { - return (out, node) -> out.printf("extend %s", node(node, ObjectTypeDefinition.class)); + private NodePrinter objectTypeExtensionDefinition() { + return (out, node) -> { + out.append("extend "); + node(out, node, ObjectTypeDefinition.class); + }; } - private static NodePrinter enumTypeExtensionDefinition() { - return (out, node) -> out.printf("extend %s", node(node, EnumTypeDefinition.class)); + private NodePrinter enumTypeExtensionDefinition() { + return (out, node) -> { + out.append("extend "); + node(out, node, EnumTypeDefinition.class); + }; } - private static NodePrinter interfaceTypeExtensionDefinition() { - return (out, node) -> out.printf("extend %s", node(node, InterfaceTypeDefinition.class)); + private NodePrinter interfaceTypeExtensionDefinition() { + return (out, node) -> { + out.append("extend "); + node(out, node, InterfaceTypeDefinition.class); + }; } - private static NodePrinter unionTypeExtensionDefinition() { - return (out, node) -> out.printf("extend %s", node(node, UnionTypeDefinition.class)); + private NodePrinter unionTypeExtensionDefinition() { + return (out, node) -> { + out.append("extend "); + node(out, node, UnionTypeDefinition.class); + }; } - private static NodePrinter scalarTypeExtensionDefinition() { - return (out, node) -> out.printf("extend %s", node(node, ScalarTypeDefinition.class)); + private NodePrinter scalarTypeExtensionDefinition() { + return (out, node) -> { + out.append("extend "); + node(out, node, ScalarTypeDefinition.class); + }; } - private static NodePrinter inputObjectTypeExtensionDefinition() { - return (out, node) -> out.printf("extend %s", node(node, InputObjectTypeDefinition.class)); + private NodePrinter inputObjectTypeExtensionDefinition() { + return (out, node) -> { + out.append("extend "); + node(out, node, InputObjectTypeDefinition.class); + }; } - private static NodePrinter unionTypeDefinition() { + private NodePrinter schemaExtensionDefinition() { return (out, node) -> { - out.printf("%s", comments(node)); - out.printf("%s", spaced( - "union", - node.getName(), - directives(node.getDirectives()), - "= " + join(node.getMemberTypes(), " | ") - )); + out.append("extend "); + node(out, node, SchemaDefinition.class); }; } - private static NodePrinter variableDefinition() { - return (out, node) -> out.printf("$%s: %s%s", - node.getName(), - type(node.getType()), - wrap(" = ", node.getDefaultValue(), "") - ); + private NodePrinter unionTypeDefinition() { + String barSep = compactMode ? "|" : " | "; + String equals = compactMode ? "=" : "= "; + return (out, node) -> { + description(out, node); + out.append("union "); + out.append(node.getName()); + if (!isEmpty(node.getDirectives())) { + out.append(' '); + directives(out, node.getDirectives()); + } + out.append(' '); + out.append(equals); + join(out, node.getMemberTypes(), barSep); + }; } - private static NodePrinter variableReference() { - return (out, node) -> out.printf("$%s", node.getName()); + private NodePrinter variableDefinition() { + String nameTypeSep = compactMode ? ":" : ": "; + String defaultValueEquals = compactMode ? "=" : " = "; + return (out, node) -> { + out.append('$'); + out.append(node.getName()); + out.append(nameTypeSep); + type(out, node.getType()); + if (node.getDefaultValue() != null) { + out.append(defaultValueEquals); + node(out, node.getDefaultValue()); + } + directives(out, node.getDirectives()); + }; + } + + private NodePrinter variableReference() { + return (out, node) -> out.append('$').append(node.getName()); } - static private String node(Node node) { + private String node(Node node) { return node(node, null); } - static private String node(Node node, Class startClass) { + private void node(StringBuilder out, Node node) { + node(out, node, null); + } + + private String node(Node node, Class startClass) { + StringBuilder builder = new StringBuilder(); + node(builder, node, startClass); + return builder.toString(); + } + + private void node(StringBuilder out, Node node, Class startClass) { if (startClass != null) { assertTrue(startClass.isInstance(node), "The starting class must be in the inherit tree"); } - StringWriter sw = new StringWriter(); - PrintWriter out = new PrintWriter(sw); - NodePrinter printer = _findPrinter(node, startClass); + NodePrinter> printer = _findPrinter(node, startClass); printer.print(out, node); - return sw.toString(); } @SuppressWarnings("unchecked") - static private NodePrinter _findPrinter(Node node) { + NodePrinter _findPrinter(Node node) { return _findPrinter(node, null); } - static private NodePrinter _findPrinter(Node node, Class startClass) { + NodePrinter _findPrinter(Node node, Class startClass) { if (node == null) { return (out, type) -> { }; } - Class clazz = startClass != null ? startClass : node.getClass(); + Class clazz = startClass != null ? startClass : node.getClass(); while (clazz != Object.class) { NodePrinter nodePrinter = printers.get(clazz); if (nodePrinter != null) { + //noinspection unchecked return nodePrinter; } clazz = clazz.getSuperclass(); } - throw new AssertException(String.format("We have a missing printer implementation for %s : report a bug!", clazz)); + return assertShouldNeverHappen("We have a missing printer implementation for %s : report a bug!", clazz); } - static private boolean isEmpty(List list) { + private static boolean isEmpty(List list) { return list == null || list.isEmpty(); } - static private boolean isEmpty(String s) { - return s == null || s.trim().length() == 0; + private static boolean isEmpty(String s) { + return s == null || s.isBlank(); } - static private List nvl(List list) { - return list != null ? list : Collections.emptyList(); + private static List nvl(List list) { + return list != null ? list : ImmutableKit.emptyList(); } - private static NodePrinter value() { - return (out, node) -> out.print(value(node)); + private NodePrinter> value() { + return this::value; } - static private String value(Value value) { + private void value(StringBuilder out, Value value) { + String argSep = compactMode ? "," : ", "; if (value instanceof IntValue) { - return valueOf(((IntValue) value).getValue()); + out.append(((IntValue) value).getValue()); } else if (value instanceof FloatValue) { - return valueOf(((FloatValue) value).getValue()); + out.append(((FloatValue) value).getValue()); } else if (value instanceof StringValue) { - return wrap("\"", valueOf(((StringValue) value).getValue()), "\""); + out.append('"'); + escapeJsonStringTo(out, ((StringValue) value).getValue()); + out.append('"'); } else if (value instanceof EnumValue) { - return valueOf(((EnumValue) value).getName()); + out.append(((EnumValue) value).getName()); } else if (value instanceof BooleanValue) { - return valueOf(((BooleanValue) value).isValue()); + out.append(((BooleanValue) value).isValue()); } else if (value instanceof NullValue) { - return "null"; + out.append("null"); } else if (value instanceof ArrayValue) { - return "[" + join(((ArrayValue) value).getValues(), ", ") + "]"; + out.append('['); + join(out, ((ArrayValue) value).getValues(), argSep); + out.append(']'); } else if (value instanceof ObjectValue) { - return "{" + join(((ObjectValue) value).getObjectFields(), ", ") + "}"; + out.append('{'); + join(out, ((ObjectValue) value).getObjectFields(), argSep); + out.append('}'); } else if (value instanceof VariableReference) { - return "$" + ((VariableReference) value).getName(); + out.append('$'); + out.append(((VariableReference) value).getName()); } - return ""; } - static private String comments(Node node) { - List comments = nvl(node.getComments()); - if (isEmpty(comments)) { - return ""; + private void description(StringBuilder out, Node node) { + Description description = ((AbstractDescribedNode) node).getDescription(); + if (description == null || description.getContent() == null || compactMode) { + return; + } +; + if (description.isMultiLine()) { + out.append("\"\"\""); + if (description.getContent().isEmpty() || description.getContent().charAt(0) != '\n') { + out.append('\n'); + } + out.append(description.getContent()); + out.append("\n\"\"\"\n"); + } else { + out.append('"'); + escapeJsonStringTo(out, description.getContent()); + out.append("\"\n"); } - String s = comments.stream().map(c -> "#" + c.getContent()).collect(joining("\n", "", "\n")); - return s; } - - private static String directives(List directives) { - return join(nvl(directives), " "); + private void directives(StringBuilder out, List directives) { + join(out, nvl(directives), compactMode ? "" : " "); } - static private String join(List nodes, String delim) { - return join(nodes, delim, "", ""); + private > void join(StringBuilder out, List nodes, String delim) { + if (isEmpty(nodes)) { + return; + } + Iterator iterator = nodes.iterator(); + node(out, iterator.next()); + while (iterator.hasNext()) { + out.append(delim); + node(out, iterator.next()); + } } + /* + * Some joined nodes don't need delimiters between them and some do + * This encodes that knowledge of those that don't require delimiters + */ @SuppressWarnings("SameParameterValue") - static private String join(List nodes, String delim, String prefix, String suffix) { - String s = nvl(nodes).stream().map(AstPrinter::node).collect(joining(delim, prefix, suffix)); - return s; - } + private > void joinTight(StringBuilder output, List nodes, String delim, String prefix, String suffix) { + output.append(prefix); - static private String spaced(String... args) { - return join(" ", args); - } - - static private String smooshed(String... args) { - return join("", args); - } + boolean first = true; + for (T node : nodes) { + if (first) { + first = false; + } else { + if (output.charAt(output.length() - 1) != '}') { + output.append(delim); + } + } + node(output, node); + } - static private String join(String delim, String... args) { - String s = Arrays.stream(args).filter(arg -> !isEmpty(arg)).collect(joining(delim)); - return s; + output.append(suffix); } - static String wrap(String start, String maybeString, String end) { + String wrap(String start, String maybeString, String end) { if (isEmpty(maybeString)) { if (start.equals("\"") && end.equals("\"")) { return "\"\""; @@ -508,25 +717,35 @@ static String wrap(String start, String maybeString, String end) { return start + maybeString + (!isEmpty(end) ? end : ""); } - private static String block(List nodes) { + private > void block(StringBuilder out, List nodes) { if (isEmpty(nodes)) { - return "{}"; + return; + } + if (compactMode) { + out.append('{'); + joinTight(out, nodes, " ", "", ""); + out.append('}'); + } else { + int offset = out.length(); + out.append("{\n"); + join(out, nodes, "\n"); + indent(out, offset); + out.append("\n}"); } - return indent("{\n" - + join(nodes, "\n")) - + "\n}"; } - private static String indent(String maybeString) { - if (isEmpty(maybeString)) { - return ""; + private static void indent(StringBuilder maybeString, int offset) { + for (int i = offset; i < maybeString.length(); i++) { + char c = maybeString.charAt(i); + if (c == '\n') { + maybeString.replace(i, i + 1, "\n "); + i += 3; + } } - maybeString = maybeString.replaceAll("\\n", "\n "); - return maybeString; } @SuppressWarnings("SameParameterValue") - static String wrap(String start, Node maybeNode, String end) { + String wrap(String start, Node maybeNode, String end) { if (maybeNode == null) { return ""; } @@ -541,24 +760,32 @@ static String wrap(String start, Node maybeNode, String end) { * @return the printed node in graphql language format */ public static String printAst(Node node) { - StringWriter sw = new StringWriter(); - printAst(sw, node); - return sw.toString(); + StringBuilder builder = new StringBuilder(); + printAstTo(node, builder); + return builder.toString(); } /** - * This will print the Ast node in graphql language format. - * The format is derived from the pretty print version by replacing - * all newlines and indentations through single space. + * This will pretty print the AST node in graphql language format to the given Appendable * - * @param node the AST node to print + * @param node the AST node to print + * @param appendable the Appendable to write the output to * - * @return the printed node in graphql language format */ - public static String printAstCompact(Node node) { - StringWriter sw = new StringWriter(); - printAst(sw, node); - return sw.toString().replaceAll("\\s+", " ").trim(); + public static void printAstTo(Node node, Appendable appendable) { + if (appendable instanceof StringBuilder) { + printImpl((StringBuilder) appendable, node, false); + } else if (appendable instanceof Writer) { + printAst((Writer) appendable, node); + } else { + StringBuilder builder = new StringBuilder(); + printImpl(builder, node, false); + try { + appendable.append(builder); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } } /** @@ -568,8 +795,32 @@ public static String printAstCompact(Node node) { * @param node the AST node to print */ public static void printAst(Writer writer, Node node) { - NodePrinter printer = _findPrinter(node); - printer.print(new PrintWriter(writer), node); + String ast = printAst(node); + try { + writer.write(ast); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * This will print the Ast node in graphql language format in a compact manner, with no new lines + * and descriptions stripped out of the text. + * + * @param node the AST node to print + * + * @return the printed node in a compact graphql language format + */ + public static String printAstCompact(Node node) { + StringBuilder builder = new StringBuilder(); + printImpl(builder, node, true); + return builder.toString(); + } + + private static void printImpl(StringBuilder writer, Node node, boolean compactMode) { + AstPrinter astPrinter = compactMode ? compact() : full(); + NodePrinter printer = astPrinter._findPrinter(node); + printer.print(writer, node); } /** @@ -577,7 +828,17 @@ public static void printAst(Writer writer, Node node) { * * @param the type of node */ - private interface NodePrinter { - void print(PrintWriter out, T node); + interface NodePrinter { + void print(StringBuilder out, T node); + } + + /** + * Allow subclasses to replace a printer for a specific {@link Node} + * + * @param nodeClass the class of the {@link Node} + * @param nodePrinter the custom {@link NodePrinter} + */ + void replacePrinter(Class nodeClass, NodePrinter nodePrinter) { + this.printers.put(nodeClass, nodePrinter); } } diff --git a/src/main/java/graphql/language/AstSignature.java b/src/main/java/graphql/language/AstSignature.java new file mode 100644 index 0000000000..f6964305b2 --- /dev/null +++ b/src/main/java/graphql/language/AstSignature.java @@ -0,0 +1,184 @@ +package graphql.language; + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import static graphql.util.TreeTransformerUtil.changeNode; + +/** + * This will produce signature and privacy safe query documents that can be used for query categorisation and logging. + */ +@PublicApi +public class AstSignature { + + /** + * This can produce a "signature" canonical AST that conforms to the algorithm as outlined + * here + * which removes excess operations, removes any field aliases, hides literal values and sorts the result into a canonical + * query. + * + * A signature says two queries with the same signature can be thought of as the same query. For example + * a tracing system will want a canonical signature for queries to group them. + * + * @param document the document to make a signature query from + * @param operationName the name of the operation to do it for (since only one query can be run at a time) + * + * @return the signature query in document form + */ + public Document signatureQuery(Document document, String operationName) { + return sortAST( + removeAliases( + hideLiterals(true, + dropUnusedQueryDefinitions(document, operationName))) + ); + } + + /** + * This can produce a "privacy safe" AST that some what conforms to the algorithm as outlined + * here + * which removes excess operations, removes any field aliases, hides some literal values and sorts the result. + * + * This is not a signature. For example object literal structures are retained like `{ a : "", b : 0}` which means + * you can infer what was asked for but not what the values are. This differs from {@link AstSignature#signatureQuery(Document, String)} + * which collapses literals to create more canonical signatures. A privacy safe Query is useful for logging say to show + * what shapes was asked for without revealing what data was provided + * + * @param document the document to make a privacy safe query from + * @param operationName the name of the operation to do it for (since only one query can be run at a time) + * + * @return the privacy safe query in document form + */ + public Document privacySafeQuery(Document document, String operationName) { + return sortAST( + removeAliases( + hideLiterals(false, + dropUnusedQueryDefinitions(document, operationName))) + ); + } + + private Document hideLiterals(boolean signatureMode, Document document) { + final Map variableRemapping = new HashMap<>(); + final AtomicInteger variableCount = new AtomicInteger(); + + NodeVisitorStub visitor = new NodeVisitorStub() { + @Override + public TraversalControl visitIntValue(IntValue node, TraverserContext context) { + return changeNode(context, node.transform(builder -> builder.value(BigInteger.ZERO))); + } + + @Override + public TraversalControl visitFloatValue(FloatValue node, TraverserContext context) { + return changeNode(context, node.transform(builder -> builder.value(BigDecimal.ZERO))); + } + + @Override + public TraversalControl visitStringValue(StringValue node, TraverserContext context) { + return changeNode(context, node.transform(builder -> builder.value(""))); + } + + @Override + public TraversalControl visitBooleanValue(BooleanValue node, TraverserContext context) { + return changeNode(context, node.transform(builder -> builder.value(false))); + } + + @Override + public TraversalControl visitArrayValue(ArrayValue node, TraverserContext context) { + if (signatureMode) { + return changeNode(context, node.transform(builder -> builder.values(ImmutableKit.emptyList()))); + } + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitObjectValue(ObjectValue node, TraverserContext context) { + if (signatureMode) { + return changeNode(context, node.transform(builder -> builder.objectFields(ImmutableKit.emptyList()))); + } + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitVariableReference(VariableReference node, TraverserContext context) { + String varName = remapVariable(node.getName(), variableRemapping, variableCount); + return changeNode(context, node.transform(builder -> builder.name(varName))); + } + + @Override + public TraversalControl visitVariableDefinition(VariableDefinition node, TraverserContext context) { + String varName = remapVariable(node.getName(), variableRemapping, variableCount); + return changeNode(context, node.transform(builder -> builder.name(varName))); + } + }; + return transformDoc(document, visitor); + } + + private String remapVariable(String varName, Map variableRemapping, AtomicInteger variableCount) { + String mappedName = variableRemapping.get(varName); + if (mappedName == null) { + mappedName = "var" + variableCount.incrementAndGet(); + variableRemapping.put(varName, mappedName); + } + return mappedName; + } + + private Document removeAliases(Document document) { + NodeVisitorStub visitor = new NodeVisitorStub() { + @Override + public TraversalControl visitField(Field node, TraverserContext context) { + return changeNode(context, node.transform(builder -> builder.alias(null))); + } + }; + return transformDoc(document, visitor); + } + + private Document sortAST(Document document) { + return new AstSorter().sort(document); + } + + private Document dropUnusedQueryDefinitions(Document document, final String operationName) { + NodeVisitorStub visitor = new NodeVisitorStub() { + @Override + public TraversalControl visitDocument(Document node, TraverserContext context) { + List wantedDefinitions = ImmutableKit.filter(node.getDefinitions(), + d -> { + if (d instanceof OperationDefinition) { + OperationDefinition operationDefinition = (OperationDefinition) d; + return isThisOperation(operationDefinition, operationName); + } + return d instanceof FragmentDefinition; + // SDL in a query makes no sense - its gone should it be present + }); + + Document changedNode = node.transform(builder -> { + builder.definitions(wantedDefinitions); + }); + return changeNode(context, changedNode); + } + }; + return transformDoc(document, visitor); + } + + private boolean isThisOperation(OperationDefinition operationDefinition, String operationName) { + String name = operationDefinition.getName(); + if (operationName == null) { + return name == null; + } + return operationName.equals(name); + } + + private Document transformDoc(Document document, NodeVisitorStub visitor) { + AstTransformer astTransformer = new AstTransformer(); + Node newDoc = astTransformer.transform(document, visitor); + return (Document) newDoc; + } + +} diff --git a/src/main/java/graphql/language/AstSorter.java b/src/main/java/graphql/language/AstSorter.java new file mode 100644 index 0000000000..d24969ea94 --- /dev/null +++ b/src/main/java/graphql/language/AstSorter.java @@ -0,0 +1,350 @@ +package graphql.language; + +import graphql.PublicApi; +import graphql.schema.idl.TypeInfo; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Function; + +import static graphql.util.TreeTransformerUtil.changeNode; +import static java.util.Comparator.naturalOrder; +import static java.util.Comparator.nullsLast; + +/** + * A class that helps you sort AST nodes + */ +@PublicApi +public class AstSorter { + + /** + * This will sort nodes in specific orders and then alphabetically. + * + * The order is : + *
    + *
  • Query operation definitions
  • + *
  • Mutation operation definitions
  • + *
  • Subscriptions operation definitions
  • + *
  • Fragment definitions
  • + *
  • Directive definitions
  • + *
  • Schema definitions
  • + *
  • Object Type definitions
  • + *
  • Interface Type definitions
  • + *
  • Union Type definitions
  • + *
  • Enum Type definitions
  • + *
  • Scalar Type definitions
  • + *
  • Input Object Type definitions
  • + *
+ * + * After those groupings they will be sorted alphabetic. All arguments and directives on elements + * will be sorted alphabetically by name. + * + * @param nodeToBeSorted the node to be sorted + * @param of type {@link graphql.language.Node} + * + * @return a new sorted node (because {@link graphql.language.Node}s are immutable) + */ + public T sort(T nodeToBeSorted) { + + NodeVisitorStub visitor = new NodeVisitorStub() { + + @Override + public TraversalControl visitDocument(Document node, TraverserContext context) { + Document changedNode = node.transform(builder -> { + List definitions = sort(node.getDefinitions(), comparingDefinitions()); + builder.definitions(definitions); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitOperationDefinition(OperationDefinition node, TraverserContext context) { + OperationDefinition changedNode = node.transform(builder -> { + builder.variableDefinitions(sort(node.getVariableDefinitions(), comparing(VariableDefinition::getName))); + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.selectionSet(sortSelectionSet(node.getSelectionSet())); + }); + return changeNode(context, changedNode); + } + + + @Override + public TraversalControl visitField(Field node, TraverserContext context) { + Field changedNode = node.transform(builder -> { + builder.arguments(sort(node.getArguments(), comparing(Argument::getName))); + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.selectionSet(sortSelectionSet(node.getSelectionSet())); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitFragmentDefinition(FragmentDefinition node, TraverserContext context) { + FragmentDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.selectionSet(sortSelectionSet(node.getSelectionSet())); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitInlineFragment(InlineFragment node, TraverserContext context) { + InlineFragment changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.selectionSet(sortSelectionSet(node.getSelectionSet())); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitFragmentSpread(FragmentSpread node, TraverserContext context) { + FragmentSpread changedNode = node.transform(builder -> { + List directives = sort(node.getDirectives(), comparing(Directive::getName)); + builder.directives(directives); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitDirective(Directive node, TraverserContext context) { + Directive changedNode = node.transform(builder -> { + List arguments = sort(node.getArguments(), comparing(Argument::getName)); + builder.arguments(arguments); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitObjectValue(ObjectValue node, TraverserContext context) { + ObjectValue changedNode = node.transform(builder -> { + List objectFields = sort(node.getObjectFields(), comparing(ObjectField::getName)); + builder.objectFields(objectFields); + }); + return changeNode(context, changedNode); + } + + // SDL classes here + + @Override + public TraversalControl visitSchemaDefinition(SchemaDefinition node, TraverserContext context) { + SchemaDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.operationTypeDefinitions(sort(node.getOperationTypeDefinitions(), comparing(OperationTypeDefinition::getName))); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitEnumTypeDefinition(EnumTypeDefinition node, TraverserContext context) { + EnumTypeDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.enumValueDefinitions(sort(node.getEnumValueDefinitions(), comparing(EnumValueDefinition::getName))); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitScalarTypeDefinition(ScalarTypeDefinition node, TraverserContext context) { + ScalarTypeDefinition changedNode = node.transform(builder -> { + List directives = sort(node.getDirectives(), comparing(Directive::getName)); + builder.directives(directives); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitInputObjectTypeDefinition(InputObjectTypeDefinition node, TraverserContext context) { + InputObjectTypeDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.inputValueDefinitions(sort(node.getInputValueDefinitions(), comparing(InputValueDefinition::getName))); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitObjectTypeDefinition(ObjectTypeDefinition node, TraverserContext context) { + ObjectTypeDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.implementz(sort(node.getImplements(), comparingTypes())); + builder.fieldDefinitions(sort(node.getFieldDefinitions(), comparing(FieldDefinition::getName))); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitInterfaceTypeDefinition(InterfaceTypeDefinition node, TraverserContext context) { + InterfaceTypeDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.implementz(sort(node.getImplements(), comparingTypes())); + builder.definitions(sort(node.getFieldDefinitions(), comparing(FieldDefinition::getName))); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitUnionTypeDefinition(UnionTypeDefinition node, TraverserContext context) { + UnionTypeDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.memberTypes(sort(node.getMemberTypes(), comparingTypes())); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitFieldDefinition(FieldDefinition node, TraverserContext context) { + FieldDefinition changedNode = node.transform(builder -> { + builder.directives(sort(node.getDirectives(), comparing(Directive::getName))); + builder.inputValueDefinitions(sort(node.getInputValueDefinitions(), comparing(InputValueDefinition::getName))); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitInputValueDefinition(InputValueDefinition node, TraverserContext context) { + InputValueDefinition changedNode = node.transform(builder -> { + List directives = sort(node.getDirectives(), comparing(Directive::getName)); + builder.directives(directives); + }); + return changeNode(context, changedNode); + } + + @Override + public TraversalControl visitDirectiveDefinition(DirectiveDefinition node, TraverserContext context) { + DirectiveDefinition changedNode = node.transform(builder -> { + builder.inputValueDefinitions(sort(node.getInputValueDefinitions(), comparing(InputValueDefinition::getName))); + builder.directiveLocations(sort(node.getDirectiveLocations(), comparing(DirectiveLocation::getName))); + }); + return changeNode(context, changedNode); + } + }; + + AstTransformer astTransformer = new AstTransformer(); + Node newDoc = astTransformer.transform(nodeToBeSorted, visitor); + //noinspection unchecked + return (T) newDoc; + } + + + private Comparator comparingTypes() { + return comparing(type -> TypeInfo.typeInfo(type).getName()); + } + + private Comparator comparingSelections() { + Function byName = s -> { + if (s instanceof FragmentSpread) { + return ((FragmentSpread) s).getName(); + } + if (s instanceof Field) { + return ((Field) s).getName(); + } + if (s instanceof InlineFragment) { + TypeName typeCondition = ((InlineFragment) s).getTypeCondition(); + return typeCondition == null ? "" : typeCondition.getName(); + } + return ""; + }; + Function byType = s -> { + if (s instanceof Field) { + return 1; + } + if (s instanceof FragmentSpread) { + return 2; + } + if (s instanceof InlineFragment) { + return 3; + } + return 4; + }; + return comparing(byType).thenComparing(comparing(byName)); + } + + private Comparator comparingDefinitions() { + Function byName = d -> { + if (d instanceof OperationDefinition) { + String name = ((OperationDefinition) d).getName(); + return name == null ? "" : name; + } + if (d instanceof FragmentDefinition) { + return ((FragmentDefinition) d).getName(); + } + if (d instanceof DirectiveDefinition) { + return ((DirectiveDefinition) d).getName(); + } + if (d instanceof TypeDefinition) { + return ((TypeDefinition) d).getName(); + } + return ""; + }; + Function byType = d -> { + if (d instanceof OperationDefinition) { + OperationDefinition.Operation operation = ((OperationDefinition) d).getOperation(); + if (OperationDefinition.Operation.QUERY == operation || operation == null) { + return 101; + } + if (OperationDefinition.Operation.MUTATION == operation) { + return 102; + } + if (OperationDefinition.Operation.SUBSCRIPTION == operation) { + return 104; + } + return 100; + } + if (d instanceof FragmentDefinition) { + return 200; + } + // SDL + if (d instanceof DirectiveDefinition) { + return 300; + } + if (d instanceof SchemaDefinition) { + return 400; + } + if (d instanceof TypeDefinition) { + if (d instanceof ObjectTypeDefinition) { + return 501; + } + if (d instanceof InterfaceTypeDefinition) { + return 502; + } + if (d instanceof UnionTypeDefinition) { + return 503; + } + if (d instanceof EnumTypeDefinition) { + return 504; + } + if (d instanceof ScalarTypeDefinition) { + return 505; + } + if (d instanceof InputObjectTypeDefinition) { + return 506; + } + return 500; + } + return -1; + }; + return comparing(byType).thenComparing(byName); + } + + private SelectionSet sortSelectionSet(SelectionSet selectionSet) { + if (selectionSet == null) { + return null; + } + List selections = sort(selectionSet.getSelections(), comparingSelections()); + return selectionSet.transform(builder -> builder.selections(selections)); + } + + private List sort(List items, Comparator comparing) { + items = new ArrayList<>(items); + items.sort(comparing); + return items; + } + + private > Comparator comparing( + Function keyExtractor) { + return Comparator.comparing(keyExtractor, nullsLast(naturalOrder())); + } + +} diff --git a/src/main/java/graphql/language/AstTransformer.java b/src/main/java/graphql/language/AstTransformer.java new file mode 100644 index 0000000000..f4e218dffd --- /dev/null +++ b/src/main/java/graphql/language/AstTransformer.java @@ -0,0 +1,91 @@ +package graphql.language; + +import graphql.PublicApi; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.util.TraverserVisitor; +import graphql.util.TraverserVisitorStub; +import graphql.util.TreeParallelTransformer; +import graphql.util.TreeTransformer; + +import java.util.Map; +import java.util.concurrent.ForkJoinPool; + +import static graphql.Assert.assertNotNull; +import static graphql.language.AstNodeAdapter.AST_NODE_ADAPTER; + +/** + * Allows for an easy way to "manipulate" the immutable Ast by changing specific nodes and getting back a new Ast + * containing the changed nodes while everything else is the same. + */ +@PublicApi +public class AstTransformer { + + /** + * Transforms the input tree using the Visitor Pattern. + * @param root the root node of the input tree. + * @param nodeVisitor the visitor which will transform the input tree. + * @return the transformed tree. + */ + public Node transform(Node root, NodeVisitor nodeVisitor) { + assertNotNull(root); + assertNotNull(nodeVisitor); + + TraverserVisitor traverserVisitor = getNodeTraverserVisitor(nodeVisitor); + TreeTransformer treeTransformer = new TreeTransformer<>(AST_NODE_ADAPTER); + return treeTransformer.transform(root, traverserVisitor); + } + + /** + * Transforms the input tree using the Visitor Pattern. + * @param root the root node of the input tree. + * @param nodeVisitor the visitor which will transform the input tree. + * @param rootVars a context argument to pass information into the nodeVisitor. Pass a contextual + * object to your visitor by adding it to this map such that such that the key + * is the class of the object, and the value is the object itself. The object + * can be retrieved within the visitor by calling context.getVarFromParents(). + * @return the transformed tree. + */ + public Node transform(Node root, NodeVisitor nodeVisitor, Map, Object> rootVars) { + assertNotNull(root); + assertNotNull(nodeVisitor); + + TraverserVisitor traverserVisitor = getNodeTraverserVisitor(nodeVisitor); + TreeTransformer treeTransformer = new TreeTransformer<>(AST_NODE_ADAPTER); + return treeTransformer.transform(root, traverserVisitor, rootVars); + } + + public Node transformParallel(Node root, NodeVisitor nodeVisitor) { + return transformParallel(root, nodeVisitor, ForkJoinPool.commonPool()); + } + + public Node transformParallel(Node root, NodeVisitor nodeVisitor, ForkJoinPool forkJoinPool) { + assertNotNull(root); + assertNotNull(nodeVisitor); + + TraverserVisitor traverserVisitor = new TraverserVisitorStub() { + @Override + public TraversalControl enter(TraverserContext context) { + return context.thisNode().accept(context, nodeVisitor); + } + + }; + + TreeParallelTransformer treeParallelTransformer = TreeParallelTransformer.parallelTransformer(AST_NODE_ADAPTER, forkJoinPool); + return treeParallelTransformer.transform(root, traverserVisitor); + } + + private TraverserVisitor getNodeTraverserVisitor(NodeVisitor nodeVisitor) { + return new TraverserVisitor() { + @Override + public TraversalControl enter(TraverserContext context) { + return context.thisNode().accept(context, nodeVisitor); + } + + @Override + public TraversalControl leave(TraverserContext context) { + return TraversalControl.CONTINUE; + } + }; + } +} diff --git a/src/main/java/graphql/language/AstValueHelper.java b/src/main/java/graphql/language/AstValueHelper.java deleted file mode 100644 index 826efa338a..0000000000 --- a/src/main/java/graphql/language/AstValueHelper.java +++ /dev/null @@ -1,232 +0,0 @@ -package graphql.language; - -import graphql.Assert; -import graphql.AssertException; -import graphql.GraphQLException; -import graphql.Internal; -import graphql.Scalars; -import graphql.parser.Parser; -import graphql.schema.GraphQLEnumType; -import graphql.schema.GraphQLInputObjectField; -import graphql.schema.GraphQLInputObjectType; -import graphql.schema.GraphQLInputType; -import graphql.schema.GraphQLList; -import graphql.schema.GraphQLNonNull; -import graphql.schema.GraphQLScalarType; -import graphql.schema.GraphQLType; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static graphql.schema.GraphQLTypeUtil.isList; -import static graphql.schema.GraphQLTypeUtil.isNonNull; - -@Internal -public class AstValueHelper { - - /** - * Produces a GraphQL Value AST given a Java value. - * - * A GraphQL type must be provided, which will be used to interpret different - * Java values. - * - *
-     * |      Value    | GraphQL Value        |
-     * | ------------- | -------------------- |
-     * | Object        | Input Object         |
-     * | Array         | List                 |
-     * | Boolean       | Boolean              |
-     * | String        | String / Enum Value  |
-     * | Number        | Int / Float          |
-     * | Mixed         | Enum Value           |
-     * 
- * - * @param value - the java value to be converted into graphql ast - * @param type the graphql type of the object - * - * @return a grapql language ast {@link Value} - */ - public static Value astFromValue(Object value, GraphQLType type) { - if (value == null) { - return null; - } - - if (isNonNull(type)) { - return handleNonNull(value, (GraphQLNonNull) type); - } - - // Convert JavaScript array to GraphQL list. If the GraphQLType is a list, but - // the value is not an array, convert the value using the list's item type. - if (isList(type)) { - return handleList(value, (GraphQLList) type); - } - - // Populate the fields of the input object by creating ASTs from each value - // in the JavaScript object according to the fields in the input type. - if (type instanceof GraphQLInputObjectType) { - return handleInputObject(value, (GraphQLInputObjectType) type); - } - - if (!(type instanceof GraphQLScalarType || type instanceof GraphQLEnumType)) { - throw new AssertException("Must provide Input Type, cannot use: " + type.getClass()); - } - - // Since value is an internally represented value, it must be serialized - // to an externally represented value before converting into an AST. - final Object serialized = serialize(type, value); - if (isNullish(serialized)) { - return null; - } - - // Others serialize based on their corresponding JavaScript scalar types. - if (serialized instanceof Boolean) { - return BooleanValue.newBooleanValue().value((Boolean) serialized).build(); - } - - String stringValue = serialized.toString(); - // numbers can be Int or Float values. - if (serialized instanceof Number) { - return handleNumber(stringValue); - } - - if (serialized instanceof String) { - // Enum types use Enum literals. - if (type instanceof GraphQLEnumType) { - return EnumValue.newEnumValue().name(stringValue).build(); - } - - // ID types can use Int literals. - if (type == Scalars.GraphQLID && stringValue.matches("^[0-9]+$")) { - return IntValue.newIntValue().value(new BigInteger(stringValue)).build(); - } - - // String types are just strings but JSON'ised - return StringValue.newStringValue().value(jsonStringify(stringValue)).build(); - } - - throw new AssertException("'Cannot convert value to AST: " + serialized); - } - - private static Value handleInputObject(Object _value, GraphQLInputObjectType type) { - Map mapValue = objToMap(_value); - List fields = type.getFields(); - List fieldNodes = new ArrayList<>(); - fields.forEach(field -> { - GraphQLInputType fieldType = field.getType(); - Value nodeValue = astFromValue(mapValue.get(field.getName()), fieldType); - if (nodeValue != null) { - - fieldNodes.add(ObjectField.newObjectField().name(field.getName()).value(nodeValue).build()); - } - }); - return ObjectValue.newObjectValue().objectFields(fieldNodes).build(); - } - - private static Value handleNumber(String stringValue) { - if (stringValue.matches("^[0-9]+$")) { - return IntValue.newIntValue().value(new BigInteger(stringValue)).build(); - } else { - return FloatValue.newFloatValue().value(new BigDecimal(stringValue)).build(); - } - } - - private static Value handleList(Object _value, GraphQLList type) { - GraphQLType itemType = type.getWrappedType(); - if (_value instanceof Iterable) { - Iterable iterable = (Iterable) _value; - List valuesNodes = new ArrayList<>(); - for (Object item : iterable) { - Value itemNode = astFromValue(item, itemType); - if (itemNode != null) { - valuesNodes.add(itemNode); - } - } - return ArrayValue.newArrayValue().values(valuesNodes).build(); - } - return astFromValue(_value, itemType); - } - - private static Value handleNonNull(Object _value, GraphQLNonNull type) { - GraphQLType wrappedType = type.getWrappedType(); - return astFromValue(_value, wrappedType); - } - - private static String jsonStringify(String stringValue) { - stringValue = stringValue.replace("\\", "\\\\"); - stringValue = stringValue.replace("\"", "\\\""); - stringValue = stringValue.replace("\f", "\\f"); - stringValue = stringValue.replace("\n", "\\n"); - stringValue = stringValue.replace("\r", "\\r"); - stringValue = stringValue.replace("\t", "\\t"); - stringValue = stringValue.replace("\b", "\\b"); - return stringValue; - } - - private static Object serialize(GraphQLType type, Object value) { - if (type instanceof GraphQLScalarType) { - return ((GraphQLScalarType) type).getCoercing().serialize(value); - } else { - return ((GraphQLEnumType) type).getCoercing().serialize(value); - } - } - - private static boolean isNullish(Object serialized) { - if (serialized instanceof Number) { - return Double.isNaN(((Number) serialized).doubleValue()); - } - return serialized == null; - } - - private static Map objToMap(Object value) { - if (value instanceof Map) { - return (Map) value; - } - // java bean inspector - Map result = new HashMap<>(); - try { - BeanInfo info = Introspector.getBeanInfo(value.getClass()); - for (PropertyDescriptor pd : info.getPropertyDescriptors()) { - Method reader = pd.getReadMethod(); - if (reader != null) - result.put(pd.getName(), reader.invoke(value)); - } - } catch (IntrospectionException | InvocationTargetException | IllegalAccessException e) { - throw new GraphQLException(e); - } - return result; - } - - /** - * Parses an AST value literal into the correct {@link graphql.language.Value} which - * MUST be of the correct shape eg '"string"' or 'true' or '1' or '{ "object", "form" }' - * or '[ "array", "form" ]' otherwise an exception is thrown - * - * @param astLiteral the string to parse an AST literal - * - * @return a valid Value - * - * @throws graphql.AssertException if the input can be parsed - */ - public static Value valueFromAst(String astLiteral) { - // we use the parser to give us the AST elements as if we defined an inputType - String toParse = "input X { x : String = " + astLiteral + "}"; - try { - Document doc = new Parser().parseDocument(toParse); - InputObjectTypeDefinition inputType = (InputObjectTypeDefinition) doc.getDefinitions().get(0); - InputValueDefinition inputValueDefinition = inputType.getInputValueDefinitions().get(0); - return inputValueDefinition.getDefaultValue(); - } catch (Exception e) { - return Assert.assertShouldNeverHappen("valueFromAst of '%s' failed because of '%s'", astLiteral, e.getMessage()); - } - } -} diff --git a/src/main/java/graphql/language/BooleanValue.java b/src/main/java/graphql/language/BooleanValue.java index d1d87b8f3e..c1fd7e3450 100644 --- a/src/main/java/graphql/language/BooleanValue.java +++ b/src/main/java/graphql/language/BooleanValue.java @@ -1,34 +1,45 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi +@NullMarked public class BooleanValue extends AbstractNode implements ScalarValue { private final boolean value; @Internal - protected BooleanValue(boolean value, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected BooleanValue(boolean value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } /** * alternative to using a Builder for convenience * - * @param value + * @param value of the Boolean */ public BooleanValue(boolean value) { - super(null, new ArrayList<>()); - this.value = value; + this(value, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public boolean isValue() { @@ -37,13 +48,28 @@ public boolean isValue() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public BooleanValue withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; + } + + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } BooleanValue that = (BooleanValue) o; @@ -53,7 +79,7 @@ public boolean isEqualTo(Node o) { @Override public BooleanValue deepCopy() { - return new BooleanValue(value, getSourceLocation(), getComments()); + return new BooleanValue(value, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -68,6 +94,10 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitBooleanValue(this, context); } + public static BooleanValue of(boolean value) { + return BooleanValue.newBooleanValue(value).build(); + } + public static Builder newBooleanValue() { return new Builder(); } @@ -83,18 +113,23 @@ public BooleanValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; private boolean value; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(BooleanValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.value = existing.isValue(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -109,13 +144,28 @@ public Builder value(boolean value) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public BooleanValue build() { - BooleanValue booleanValue = new BooleanValue(value, sourceLocation, comments); - return booleanValue; + return new BooleanValue(value, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/Comment.java b/src/main/java/graphql/language/Comment.java index 6ab6163ac0..a7a546facf 100644 --- a/src/main/java/graphql/language/Comment.java +++ b/src/main/java/graphql/language/Comment.java @@ -4,6 +4,9 @@ import java.io.Serializable; +/** + * A single-line comment. These are comments that start with a {@code #} in source documents. + */ @PublicApi public class Comment implements Serializable { public final String content; diff --git a/src/main/java/graphql/language/DescribedNode.java b/src/main/java/graphql/language/DescribedNode.java new file mode 100644 index 0000000000..0d68dac601 --- /dev/null +++ b/src/main/java/graphql/language/DescribedNode.java @@ -0,0 +1,16 @@ +package graphql.language; + +import graphql.PublicApi; + +/** + * Represents a node that can contain a description. + */ +@PublicApi +public interface DescribedNode extends Node { + + /** + * @return the description of this node + */ + Description getDescription(); + +} diff --git a/src/main/java/graphql/language/Directive.java b/src/main/java/graphql/language/Directive.java index ac9b5a3902..999722bec7 100644 --- a/src/main/java/graphql/language/Directive.java +++ b/src/main/java/graphql/language/Directive.java @@ -1,56 +1,70 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; -import static graphql.language.NodeUtil.argumentsByName; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.nodeByName; @PublicApi public class Directive extends AbstractNode implements NamedNode { private final String name; - private final List arguments = new ArrayList<>(); + private final ImmutableList arguments; + + public static final String CHILD_ARGUMENTS = "arguments"; @Internal - protected Directive(String name, List arguments, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected Directive(String name, List arguments, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; - this.arguments.addAll(arguments); + this.arguments = ImmutableList.copyOf(arguments); } /** * alternative to using a Builder for convenience + * + * @param name of the directive + * @param arguments of the directive */ public Directive(String name, List arguments) { - this(name, arguments, null, new ArrayList<>()); + this(name, arguments, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the directive */ public Directive(String name) { - this(name, new ArrayList<>(), null, new ArrayList<>()); + this(name, emptyList(), null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public List getArguments() { - return new ArrayList<>(arguments); + return arguments; } public Map getArgumentsByName() { // the spec says that args MUST be unique within context - return argumentsByName(arguments); + return nodeByName(arguments); } public Argument getArgument(String argumentName) { - return getArgumentsByName().get(argumentName); + return NodeUtil.findNodeByName(arguments, argumentName); } @Override @@ -61,23 +75,41 @@ public String getName() { @Override public List getChildren() { - return new ArrayList<>(arguments); + return ImmutableList.copyOf(arguments); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_ARGUMENTS, arguments) + .build(); + } + + @Override + public Directive withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .arguments(newChildren.getChildren(CHILD_ARGUMENTS)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Directive that = (Directive) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public Directive deepCopy() { - return new Directive(name, deepCopy(arguments), getSourceLocation(), getComments()); + return new Directive(name, deepCopy(arguments), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -105,18 +137,22 @@ public Directive transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; - private List arguments = new ArrayList<>(); + private ImmutableList arguments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(Directive existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); - this.arguments = existing.getArguments(); + this.arguments = ImmutableList.copyOf(existing.getArguments()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -126,7 +162,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -136,13 +172,33 @@ public Builder name(String name) { } public Builder arguments(List arguments) { - this.arguments = arguments; + this.arguments = ImmutableList.copyOf(arguments); + return this; + } + + public Builder argument(Argument argument) { + this.arguments = ImmutableKit.addToList(arguments,argument); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public Directive build() { - Directive directive = new Directive(name, arguments, sourceLocation, comments); - return directive; + return new Directive(name, arguments, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/DirectiveDefinition.java b/src/main/java/graphql/language/DirectiveDefinition.java index 04ad75624c..8aed5bb9ff 100644 --- a/src/main/java/graphql/language/DirectiveDefinition.java +++ b/src/main/java/graphql/language/DirectiveDefinition.java @@ -1,40 +1,59 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.addToList; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class DirectiveDefinition extends AbstractNode implements SDLDefinition, NamedNode { +public class DirectiveDefinition extends AbstractDescribedNode implements SDLNamedDefinition, NamedNode { private final String name; - private Description description; - private final List inputValueDefinitions; - private final List directiveLocations; + private final boolean repeatable; + private final ImmutableList inputValueDefinitions; + private final ImmutableList directiveLocations; + + public static final String CHILD_INPUT_VALUE_DEFINITIONS = "inputValueDefinitions"; + public static final String CHILD_DIRECTIVE_LOCATION = "directiveLocation"; @Internal protected DirectiveDefinition(String name, - List inputValueDefinitions, - List directiveLocations, - SourceLocation sourceLocation, - List comments - ) { - super(sourceLocation, comments); + boolean repeatable, + Description description, + List inputValueDefinitions, + List directiveLocations, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.inputValueDefinitions = inputValueDefinitions; - this.directiveLocations = directiveLocations; + this.repeatable = repeatable; + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); + this.directiveLocations = ImmutableList.copyOf(directiveLocations); } /** * alternative to using a Builder for convenience + * + * @param name of the directive definition */ public DirectiveDefinition(String name) { - this(name, new ArrayList<>(), new ArrayList<>(), null, new ArrayList<>()); + this(name, false, null, emptyList(), emptyList(), null, emptyList(), IgnoredChars.EMPTY, ImmutableKit.emptyMap()); } @Override @@ -42,20 +61,22 @@ public String getName() { return name; } - public Description getDescription() { - return description; - } - - public void setDescription(Description description) { - this.description = description; + /** + * An AST node can have multiple directives associated with it IF the directive definition allows + * repeatable directives. + * + * @return true if this directive definition allows repeatable directives + */ + public boolean isRepeatable() { + return repeatable; } public List getInputValueDefinitions() { - return new ArrayList<>(inputValueDefinitions); + return inputValueDefinitions; } public List getDirectiveLocations() { - return new ArrayList<>(directiveLocations); + return directiveLocations; } @Override @@ -66,23 +87,47 @@ public List getChildren() { return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_INPUT_VALUE_DEFINITIONS, inputValueDefinitions) + .children(CHILD_DIRECTIVE_LOCATION, directiveLocations) + .build(); + } + + @Override + public DirectiveDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .inputValueDefinitions(newChildren.getChildren(CHILD_INPUT_VALUE_DEFINITIONS)) + .directiveLocations(newChildren.getChildren(CHILD_DIRECTIVE_LOCATION)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } DirectiveDefinition that = (DirectiveDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public DirectiveDefinition deepCopy() { return new DirectiveDefinition(name, + repeatable, + description, deepCopy(inputValueDefinitions), deepCopy(directiveLocations), getSourceLocation(), - getComments()); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -111,22 +156,28 @@ public DirectiveDefinition transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; + private boolean repeatable = false; private Description description; - private List inputValueDefinitions = new ArrayList<>(); - private List directiveLocations = new ArrayList<>(); + private ImmutableList inputValueDefinitions = emptyList(); + private ImmutableList directiveLocations = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(DirectiveDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); + this.repeatable = existing.isRepeatable(); this.description = existing.getDescription(); - this.inputValueDefinitions = existing.getInputValueDefinitions(); - this.directiveLocations = existing.getDirectiveLocations(); + this.inputValueDefinitions = ImmutableList.copyOf(existing.getInputValueDefinitions()); + this.directiveLocations = ImmutableList.copyOf(existing.getDirectiveLocations()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -135,7 +186,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -144,35 +195,55 @@ public Builder name(String name) { return this; } + public Builder repeatable(boolean repeatable) { + this.repeatable = repeatable; + return this; + } + public Builder description(Description description) { this.description = description; return this; } public Builder inputValueDefinitions(List inputValueDefinitions) { - this.inputValueDefinitions = inputValueDefinitions; + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); return this; } public Builder inputValueDefinition(InputValueDefinition inputValueDefinition) { - this.inputValueDefinitions.add(inputValueDefinition); + this.inputValueDefinitions = addToList(inputValueDefinitions, inputValueDefinition); return this; } + public Builder directiveLocations(List directiveLocations) { - this.directiveLocations = directiveLocations; + this.directiveLocations = ImmutableList.copyOf(directiveLocations); return this; } public Builder directiveLocation(DirectiveLocation directiveLocation) { - this.directiveLocations.add(directiveLocation); + this.directiveLocations = addToList(directiveLocations, directiveLocation); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public DirectiveDefinition build() { - DirectiveDefinition directiveDefinition = new DirectiveDefinition(name, inputValueDefinitions, directiveLocations, sourceLocation, comments); - directiveDefinition.setDescription(description); - return directiveDefinition; + return new DirectiveDefinition(name, repeatable, description, inputValueDefinitions, directiveLocations, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/DirectiveLocation.java b/src/main/java/graphql/language/DirectiveLocation.java index 7d61e1e429..f9e5d920d0 100644 --- a/src/main/java/graphql/language/DirectiveLocation.java +++ b/src/main/java/graphql/language/DirectiveLocation.java @@ -1,38 +1,41 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; -// This should probably be an enum... but the grammar -// doesn't enforce the names. These are the current names: -// QUERY -// MUTATION -// FIELD -// FRAGMENT_DEFINITION -// FRAGMENT_SPREAD -// INLINE_FRAGMENT +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi public class DirectiveLocation extends AbstractNode implements NamedNode { private final String name; @Internal - protected DirectiveLocation(String name, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected DirectiveLocation(String name, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; } /** * alternative to using a Builder for convenience + * + * @param name of the directive location */ public DirectiveLocation(String name) { - this(name, null, new ArrayList<>()); + this(name, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override @@ -42,22 +45,37 @@ public String getName() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); + } + + @Override + public DirectiveLocation withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } DirectiveLocation that = (DirectiveLocation) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public DirectiveLocation deepCopy() { - return new DirectiveLocation(name, getSourceLocation(), getComments()); + return new DirectiveLocation(name, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -84,16 +102,19 @@ public DirectiveLocation transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(DirectiveLocation existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -102,7 +123,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -111,9 +132,23 @@ public Builder name(String name) { return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + public DirectiveLocation build() { - DirectiveLocation directiveLocation = new DirectiveLocation(name, sourceLocation, comments); - return directiveLocation; + return new DirectiveLocation(name, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/DirectivesContainer.java b/src/main/java/graphql/language/DirectivesContainer.java index 0b7b791542..a300072486 100644 --- a/src/main/java/graphql/language/DirectivesContainer.java +++ b/src/main/java/graphql/language/DirectivesContainer.java @@ -6,34 +6,47 @@ import java.util.List; import java.util.Map; -import static graphql.language.NodeUtil.directivesByName; - /** - * Represents a language node that has a name + * Represents a language node that can contain Directives. Directives can be repeatable and (by default) non repeatable. + *

+ * There are access methods here that get the two different types. + * + * @see graphql.language.DirectiveDefinition + * @see DirectiveDefinition#isRepeatable() */ @PublicApi -public interface DirectivesContainer extends NamedNode { +public interface DirectivesContainer extends Node { /** - * @return a list of directives associated with the type or field + * This will return a list of all the directives that have been put on {@link graphql.language.Node} as a flat list, which may contain repeatable + * and non repeatable directives. + * + * @return a list of all the directives associated with this Node */ List getDirectives(); /** - * @return a a map of directives by directive name + * This will return a Map of the all directives that are associated with a {@link graphql.language.Node}, including both repeatable and non repeatable directives. + * + * @return a map of all directives by directive name + */ + Map> getDirectivesByName(); + + /** + * Returns all the directives with the provided name, including repeatable and non repeatable directives. + * + * @param directiveName the name of the directives to retrieve + * + * @return the directives or empty list if there is not one with that name */ - default Map getDirectivesByName() { - return directivesByName(getDirectives()); - } + List getDirectives(String directiveName); /** - * Returns a named directive + * This returns true if the AST node contains one or more directives by the specified name * - * @param directiveName the name of the directive to retrieve + * @param directiveName the name ot check * - * @return the directive or null if there is one one with that name + * @return true if the AST node contains one or more directives by the specified name */ - default Directive getDirective(String directiveName) { - return getDirectivesByName().get(directiveName); - } + boolean hasDirective(String directiveName); } diff --git a/src/main/java/graphql/language/Document.java b/src/main/java/graphql/language/Document.java index ea15b43c79..1f613686e4 100644 --- a/src/main/java/graphql/language/Document.java +++ b/src/main/java/graphql/language/Document.java @@ -1,55 +1,133 @@ package graphql.language; +import com.google.common.collect.ImmutableList; +import graphql.Assert; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class Document extends AbstractNode { - private final List definitions; + private final ImmutableList definitions; + + public static final String CHILD_DEFINITIONS = "definitions"; @Internal - protected Document(List definitions, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); - this.definitions = definitions; + protected Document(List definitions, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.definitions = ImmutableList.copyOf(definitions); } /** * alternative to using a Builder for convenience + * + * @param definitions the definitions that make up this document */ public Document(List definitions) { - this(definitions, null, new ArrayList<>()); + this(definitions, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public List getDefinitions() { return definitions; } + /** + * Returns a list of definitions of the specific type. It uses {@link java.lang.Class#isAssignableFrom(Class)} for the test + * + * @param definitionClass the definition class + * @param the type of definition + * + * @return a list of definitions of that class or empty list + */ + public List getDefinitionsOfType(Class definitionClass) { + return ImmutableKit.filterAndMap(definitions, + d -> definitionClass.isAssignableFrom(d.getClass()), + definitionClass::cast); + } + + /** + * Returns the first of the specific type. It uses {@link java.lang.Class#isAssignableFrom(Class)} for the test. + * + * This is useful when you have generated a document in code and KNOW there is only one definition in it + * + * @param definitionClass the definition class + * @param the type of definition + * + * @return an optional definition which will be empty of there are none + */ + public Optional getFirstDefinitionOfType(Class definitionClass) { + return definitions.stream() + .filter(d -> definitionClass.isAssignableFrom(d.getClass())) + .map(definitionClass::cast) + .findFirst(); + } + + /** + * This will allow you to find a {@link OperationDefinition} with the specified name + * in the document + * + * @param name the name of the operation to find + * + * @return an optional {@link OperationDefinition} + */ + public Optional getOperationDefinition(String name) { + Assert.assertNotNull(name); + return definitions.stream() + .filter(d -> OperationDefinition.class.isAssignableFrom(d.getClass())) + .map(OperationDefinition.class::cast) + .filter(opDef -> name.equals(opDef.getName())) + .findFirst(); + } @Override public List getChildren() { - return new ArrayList<>(definitions); + return ImmutableList.copyOf(definitions); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DEFINITIONS, definitions) + .build(); } + @Override + public Document withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .definitions(newChildren.getChildren(CHILD_DEFINITIONS)) + ); + } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; } @Override public Document deepCopy() { - return new Document(deepCopy(definitions), getSourceLocation(), getComments()); + return new Document(deepCopy(definitions), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -75,26 +153,30 @@ public Document transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private List definitions = new ArrayList<>(); + private ImmutableList definitions = emptyList(); private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(Document existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); - this.definitions = existing.getDefinitions(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.definitions = ImmutableList.copyOf(existing.getDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder definitions(List definitions) { - this.definitions = definitions; + this.definitions = ImmutableList.copyOf(definitions); return this; } public Builder definition(Definition definition) { - this.definitions.add(definition); + this.definitions = ImmutableKit.addToList(definitions, definition); return this; } @@ -104,13 +186,28 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public Document build() { - Document document = new Document(definitions, sourceLocation, comments); - return document; + return new Document(definitions, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/EnumTypeDefinition.java b/src/main/java/graphql/language/EnumTypeDefinition.java index 419a719530..51bad7b12a 100644 --- a/src/main/java/graphql/language/EnumTypeDefinition.java +++ b/src/main/java/graphql/language/EnumTypeDefinition.java @@ -1,85 +1,133 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class EnumTypeDefinition extends AbstractNode implements TypeDefinition, DirectivesContainer { +public class EnumTypeDefinition extends AbstractDescribedNode implements TypeDefinition, DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List enumValueDefinitions; - private final List directives; + private final ImmutableList enumValueDefinitions; + private final NodeUtil.DirectivesHolder directives; + + public static final String CHILD_ENUM_VALUE_DEFINITIONS = "enumValueDefinitions"; + public static final String CHILD_DIRECTIVES = "directives"; @Internal protected EnumTypeDefinition(String name, - List enumValueDefinitions, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List enumValueDefinitions, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.description = description; - this.directives = (null == directives) ? new ArrayList<>() : directives; - this.enumValueDefinitions = enumValueDefinitions; + this.directives = NodeUtil.DirectivesHolder.of(directives); + this.enumValueDefinitions = ImmutableKit.nonNullCopyOf(enumValueDefinitions); } /** * alternative to using a Builder for convenience + * + * @param name of the enum */ public EnumTypeDefinition(String name) { - this(name, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public List getEnumValueDefinitions() { - return new ArrayList<>(enumValueDefinitions); + return enumValueDefinitions; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } @Override - public String getName() { - return name; + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } - public Description getDescription() { - return description; + @Override + public String getName() { + return name; } @Override public List getChildren() { List result = new ArrayList<>(); result.addAll(enumValueDefinitions); - result.addAll(directives); + result.addAll(directives.getDirectives()); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_ENUM_VALUE_DEFINITIONS, enumValueDefinitions) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public EnumTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .enumValueDefinitions(newChildren.getChildren(CHILD_ENUM_VALUE_DEFINITIONS)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } EnumTypeDefinition that = (EnumTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public EnumTypeDefinition deepCopy() { return new EnumTypeDefinition(name, deepCopy(enumValueDefinitions), - deepCopy(directives), + deepCopy(directives.getDirectives()), description, - getSourceLocation(), getComments()); + getSourceLocation(), + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -106,24 +154,28 @@ public EnumTypeDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List enumValueDefinitions = new ArrayList<>(); - private List directives = new ArrayList<>(); + private ImmutableList enumValueDefinitions = emptyList(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(EnumTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.enumValueDefinitions = existing.getEnumValueDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.enumValueDefinitions = ImmutableList.copyOf(existing.getEnumValueDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -132,7 +184,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -147,28 +199,44 @@ public Builder description(Description description) { } public Builder enumValueDefinitions(List enumValueDefinitions) { - this.enumValueDefinitions = enumValueDefinitions; + this.enumValueDefinitions = ImmutableList.copyOf(enumValueDefinitions); return this; } public Builder enumValueDefinition(EnumValueDefinition enumValueDefinition) { - this.enumValueDefinitions.add(enumValueDefinition); + this.enumValueDefinitions = ImmutableKit.addToList(enumValueDefinitions, enumValueDefinition); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public EnumTypeDefinition build() { - EnumTypeDefinition enumTypeDefinition = new EnumTypeDefinition(name, enumValueDefinitions, directives, description, sourceLocation, comments); - return enumTypeDefinition; + return new EnumTypeDefinition(name, enumValueDefinitions, directives, description, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/EnumTypeExtensionDefinition.java b/src/main/java/graphql/language/EnumTypeExtensionDefinition.java index bd0a05aa89..82bb3eb634 100644 --- a/src/main/java/graphql/language/EnumTypeExtensionDefinition.java +++ b/src/main/java/graphql/language/EnumTypeExtensionDefinition.java @@ -1,24 +1,32 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + @PublicApi -public class EnumTypeExtensionDefinition extends EnumTypeDefinition { +public class EnumTypeExtensionDefinition extends EnumTypeDefinition implements SDLExtensionDefinition { @Internal protected EnumTypeExtensionDefinition(String name, - List enumValueDefinitions, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { + List enumValueDefinitions, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { super(name, enumValueDefinitions, directives, description, - sourceLocation, comments); + sourceLocation, comments, ignoredChars, additionalData); } @Override @@ -28,7 +36,8 @@ public EnumTypeExtensionDefinition deepCopy() { deepCopy(getDirectives()), getDescription(), getSourceLocation(), - getComments()); + getComments(), + getIgnoredChars(), getAdditionalData()); } @Override @@ -44,30 +53,42 @@ public static Builder newEnumTypeExtensionDefinition() { return new Builder(); } + @Override + public EnumTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder + .enumValueDefinitions(newChildren.getChildren(CHILD_ENUM_VALUE_DEFINITIONS)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + public EnumTypeExtensionDefinition transformExtension(Consumer builderConsumer) { Builder builder = new Builder(this); builderConsumer.accept(builder); return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List enumValueDefinitions; - private List directives; + private ImmutableList enumValueDefinitions = emptyList(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(EnumTypeExtensionDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.enumValueDefinitions = existing.getEnumValueDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.enumValueDefinitions = ImmutableList.copyOf(existing.getEnumValueDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -76,7 +97,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -91,23 +112,45 @@ public Builder description(Description description) { } public Builder enumValueDefinitions(List enumValueDefinitions) { - this.enumValueDefinitions = enumValueDefinitions; + this.enumValueDefinitions = ImmutableList.copyOf(enumValueDefinitions); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public EnumTypeExtensionDefinition build() { - EnumTypeExtensionDefinition enumTypeDefinition = new EnumTypeExtensionDefinition(name, + return new EnumTypeExtensionDefinition(name, enumValueDefinitions, directives, description, sourceLocation, - comments); - return enumTypeDefinition; + comments, + ignoredChars, additionalData); } } diff --git a/src/main/java/graphql/language/EnumValue.java b/src/main/java/graphql/language/EnumValue.java index 292e9610cb..4164b6c68b 100644 --- a/src/main/java/graphql/language/EnumValue.java +++ b/src/main/java/graphql/language/EnumValue.java @@ -1,23 +1,36 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi +@NullMarked public class EnumValue extends AbstractNode implements Value, NamedNode { private final String name; @Internal - protected EnumValue(String name, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected EnumValue(String name, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; } @@ -25,11 +38,14 @@ protected EnumValue(String name, SourceLocation sourceLocation, List co /** * alternative to using a Builder for convenience * - * @param name + * @param name of the enum value */ public EnumValue(String name) { - super(null, new ArrayList<>()); - this.name = name; + this(name, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); + } + + public static EnumValue of(String name) { + return newEnumValue().name(name).build(); } @Override @@ -40,22 +56,37 @@ public String getName() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); + } + + @Override + public EnumValue withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; + } + + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } EnumValue that = (EnumValue) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public EnumValue deepCopy() { - return new EnumValue(name, getSourceLocation(), getComments()); + return new EnumValue(name, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -84,18 +115,22 @@ public EnumValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; private String name; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(EnumValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -110,13 +145,28 @@ public Builder name(String name) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public EnumValue build() { - EnumValue enumValue = new EnumValue(name, sourceLocation, comments); - return enumValue; + return new EnumValue(name, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/EnumValueDefinition.java b/src/main/java/graphql/language/EnumValueDefinition.java index d5a06ed8c3..5e28ae87f9 100644 --- a/src/main/java/graphql/language/EnumValueDefinition.java +++ b/src/main/java/graphql/language/EnumValueDefinition.java @@ -1,46 +1,60 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class EnumValueDefinition extends AbstractNode implements DirectivesContainer { +public class EnumValueDefinition extends AbstractDescribedNode implements DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List directives; + private final NodeUtil.DirectivesHolder directives; + public static final String CHILD_DIRECTIVES = "directives"; @Internal protected EnumValueDefinition(String name, List directives, Description description, SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List comments, + IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.description = description; - this.directives = (null == directives) ? new ArrayList<>() : directives; + this.directives = NodeUtil.DirectivesHolder.of(directives); } /** * alternative to using a Builder for convenience + * + * @param name of the enum value */ public EnumValueDefinition(String name) { - this(name, new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the enum value + * @param directives the directives on the enum value */ public EnumValueDefinition(String name, List directives) { - this(name, directives, null, null, new ArrayList<>()); + this(name, directives, null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override @@ -48,36 +62,63 @@ public String getName() { return name; } - public Description getDescription() { - return description; + @Override + public List getDirectives() { + return directives.getDirectives(); } @Override - public List getDirectives() { - return new ArrayList<>(directives); + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } @Override public List getChildren() { - List result = new ArrayList<>(); - result.addAll(directives); - return result; + return ImmutableList.copyOf(directives.getDirectives()); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public EnumValueDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } EnumValueDefinition that = (EnumValueDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public EnumValueDefinition deepCopy() { - return new EnumValueDefinition(name, deepCopy(directives), description, getSourceLocation(), getComments()); + return new EnumValueDefinition(name, deepCopy(directives.getDirectives()), description, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -105,20 +146,24 @@ public EnumValueDefinition transform(Consumer builderConsumer) { public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives; + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(EnumValueDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -127,7 +172,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -141,14 +186,35 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public EnumValueDefinition build() { - EnumValueDefinition enumValueDefinition = new EnumValueDefinition(name, directives, description, sourceLocation, comments); - return enumValueDefinition; + return new EnumValueDefinition(name, directives, description, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/Field.java b/src/main/java/graphql/language/Field.java index 2c74862084..45f9103f3d 100644 --- a/src/main/java/graphql/language/Field.java +++ b/src/main/java/graphql/language/Field.java @@ -1,27 +1,44 @@ package graphql.language; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.Interning; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static com.google.common.collect.ImmutableMap.copyOf; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.addToMap; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; + /* * This is provided to a DataFetcher, therefore it is a public API. * This might change in the future. */ @PublicApi -public class Field extends AbstractNode implements Selection, SelectionSetContainer, DirectivesContainer { +public class Field extends AbstractNode implements Selection, SelectionSetContainer, DirectivesContainer, NamedNode { + + private final String name; + private final String alias; + private final ImmutableList arguments; + private final NodeUtil.DirectivesHolder directives; + private final SelectionSet selectionSet; + + public static final String CHILD_ARGUMENTS = "arguments"; + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_SELECTION_SET = "selectionSet"; - private String name; - private String alias; - private List arguments; - private List directives; - private SelectionSet selectionSet; @Internal protected Field(String name, @@ -30,55 +47,86 @@ protected Field(String name, List directives, SelectionSet selectionSet, SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); - this.name = name; + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.name = name == null ? null : Interning.intern(name); this.alias = alias; - this.arguments = arguments; - this.directives = directives; + this.arguments = ImmutableList.copyOf(arguments); + this.directives = NodeUtil.DirectivesHolder.of(directives); this.selectionSet = selectionSet; } /** * alternative to using a Builder for convenience + * + * @param name of the field */ public Field(String name) { - this(name, null, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, null, emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the field + * @param arguments to the field */ public Field(String name, List arguments) { - this(name, null, arguments, new ArrayList<>(), null, null, new ArrayList<>()); + this(name, null, arguments, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the field + * @param arguments to the field + * @param selectionSet of the field */ public Field(String name, List arguments, SelectionSet selectionSet) { - this(name, null, arguments, new ArrayList<>(), selectionSet, null, new ArrayList<>()); + this(name, null, arguments, emptyList(), selectionSet, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the field + * @param selectionSet of the field */ public Field(String name, SelectionSet selectionSet) { - this(name, null, new ArrayList<>(), new ArrayList<>(), selectionSet, null, new ArrayList<>()); + this(name, null, emptyList(), emptyList(), selectionSet, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override public List getChildren() { List result = new ArrayList<>(); result.addAll(arguments); - result.addAll(directives); + result.addAll(directives.getDirectives()); if (selectionSet != null) { result.add(selectionSet); } return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return NodeChildrenContainer.newNodeChildrenContainer() + .children(CHILD_ARGUMENTS, arguments) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .child(CHILD_SELECTION_SET, selectionSet) + .build(); + } + + @Override + public Field withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> + builder.arguments(newChildren.getChildren(CHILD_ARGUMENTS)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .selectionSet(newChildren.getChildOrNull(CHILD_SELECTION_SET)) + ); + } @Override public String getName() { @@ -89,40 +137,40 @@ public String getAlias() { return alias; } - public List getArguments() { - return arguments; - } - - public void setArguments(List arguments) { - this.arguments = arguments; + public String getResultKey() { + return alias != null ? alias : name; } - public void setDirectives(List directives) { - this.directives = directives; + public List getArguments() { + return arguments; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } @Override - public SelectionSet getSelectionSet() { - return selectionSet; + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); } - public void setName(String name) { - this.name = name; + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); } - public void setAlias(String alias) { - this.alias = alias; + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } - public void setSelectionSet(SelectionSet selectionSet) { - this.selectionSet = selectionSet; + @Override + public SelectionSet getSelectionSet() { + return selectionSet; } + @Override public boolean isEqualTo(Node o) { if (this == o) { @@ -134,7 +182,7 @@ public boolean isEqualTo(Node o) { Field that = (Field) o; - return NodeUtil.isEqualTo(this.name, that.name) && NodeUtil.isEqualTo(this.alias, that.alias); + return Objects.equals(this.name, that.name) && Objects.equals(this.alias, that.alias); } @Override @@ -142,10 +190,12 @@ public Field deepCopy() { return new Field(name, alias, deepCopy(arguments), - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(selectionSet), getSourceLocation(), - getComments() + getComments(), + getIgnoredChars(), + getAdditionalData() ); } @@ -183,26 +233,30 @@ public Field transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private String alias; - private List arguments = new ArrayList<>(); - private List directives = new ArrayList<>(); + private ImmutableList arguments = emptyList(); + private ImmutableList directives = emptyList(); private SelectionSet selectionSet; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private ImmutableMap additionalData = emptyMap(); private Builder() { } private Builder(Field existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.alias = existing.getAlias(); - this.arguments = existing.getArguments(); - this.directives = existing.getDirectives(); + this.arguments = ImmutableList.copyOf(existing.getArguments()); + this.directives = ImmutableList.copyOf(existing.getDirectives()); this.selectionSet = existing.getSelectionSet(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = copyOf(existing.getAdditionalData()); } @@ -212,7 +266,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -227,12 +281,18 @@ public Builder alias(String alias) { } public Builder arguments(List arguments) { - this.arguments = arguments; + this.arguments = ImmutableList.copyOf(arguments); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); return this; } @@ -241,9 +301,24 @@ public Builder selectionSet(SelectionSet selectionSet) { return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = ImmutableMap.copyOf(assertNotNull(additionalData)); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData = addToMap(this.additionalData, key, value); + return this; + } + + public Field build() { - Field field = new Field(name, alias, arguments, directives, selectionSet, sourceLocation, comments); - return field; + return new Field(name, alias, arguments, directives, selectionSet, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/FieldDefinition.java b/src/main/java/graphql/language/FieldDefinition.java index 2c66dfd726..5fc03257aa 100644 --- a/src/main/java/graphql/language/FieldDefinition.java +++ b/src/main/java/graphql/language/FieldDefinition.java @@ -1,42 +1,56 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class FieldDefinition extends AbstractNode implements DirectivesContainer { - private String name; - private Type type; - private final Description description; - private final List inputValueDefinitions; - private final List directives; +public class FieldDefinition extends AbstractDescribedNode implements DirectivesContainer, NamedNode { + private final String name; + private final Type type; + private final ImmutableList inputValueDefinitions; + private final NodeUtil.DirectivesHolder directives; + + public static final String CHILD_TYPE = "type"; + public static final String CHILD_INPUT_VALUE_DEFINITION = "inputValueDefinition"; + public static final String CHILD_DIRECTIVES = "directives"; @Internal protected FieldDefinition(String name, - Type type, - List inputValueDefinitions, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); - this.description = description; + Type type, + List inputValueDefinitions, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; this.type = type; - this.inputValueDefinitions = inputValueDefinitions; - this.directives = directives; + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); + this.directives = NodeUtil.DirectivesHolder.of(directives); } public FieldDefinition(String name, Type type) { - this(name, type, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, type, emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public Type getType() { @@ -48,17 +62,28 @@ public String getName() { return name; } - public Description getDescription() { - return description; - } - public List getInputValueDefinitions() { return inputValueDefinitions; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } @Override @@ -66,18 +91,40 @@ public List getChildren() { List result = new ArrayList<>(); result.add(type); result.addAll(inputValueDefinitions); - result.addAll(directives); + result.addAll(directives.getDirectives()); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE, type) + .children(CHILD_INPUT_VALUE_DEFINITION, inputValueDefinitions) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public FieldDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .type(newChildren.getChildOrNull(CHILD_TYPE)) + .inputValueDefinitions(newChildren.getChildren(CHILD_INPUT_VALUE_DEFINITION)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } FieldDefinition that = (FieldDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override @@ -85,19 +132,12 @@ public FieldDefinition deepCopy() { return new FieldDefinition(name, deepCopy(type), deepCopy(inputValueDefinitions), - deepCopy(directives), + deepCopy(directives.getDirectives()), description, getSourceLocation(), - getComments() - ); - } - - public void setName(String name) { - this.name = name; - } - - public void setType(Type type) { - this.type = type; + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -128,11 +168,13 @@ public FieldDefinition transform(Consumer builderConsumer) { public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; private String name; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private Type type; private Description description; - private List inputValueDefinitions = new ArrayList<>(); - private List directives = new ArrayList<>(); + private ImmutableList inputValueDefinitions = emptyList(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } @@ -140,11 +182,13 @@ private Builder() { private Builder(FieldDefinition existing) { this.sourceLocation = existing.getSourceLocation(); this.name = existing.getName(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.type = existing.getType(); this.description = existing.getDescription(); - this.inputValueDefinitions = existing.getInputValueDefinitions(); - this.directives = existing.getDirectives(); + this.inputValueDefinitions = ImmutableList.copyOf(existing.getInputValueDefinitions()); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -159,7 +203,7 @@ public Builder name(String name) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -174,28 +218,45 @@ public Builder description(Description description) { } public Builder inputValueDefinitions(List inputValueDefinitions) { - this.inputValueDefinitions = inputValueDefinitions; + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); return this; } - public Builder inputValueDefinition(InputValueDefinition inputValueDefinitions) { - this.inputValueDefinitions.add(inputValueDefinitions); + public Builder inputValueDefinition(InputValueDefinition inputValueDefinition) { + this.inputValueDefinitions = ImmutableKit.addToList(inputValueDefinitions, inputValueDefinition); return this; } + + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public FieldDefinition build() { - FieldDefinition fieldDefinition = new FieldDefinition(name, type, inputValueDefinitions, directives, description, sourceLocation, comments); - return fieldDefinition; + return new FieldDefinition(name, type, inputValueDefinitions, directives, description, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/FloatValue.java b/src/main/java/graphql/language/FloatValue.java index 09dbcba861..c27cbd444b 100644 --- a/src/main/java/graphql/language/FloatValue.java +++ b/src/main/java/graphql/language/FloatValue.java @@ -1,32 +1,47 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import java.math.BigDecimal; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi +@NullMarked public class FloatValue extends AbstractNode implements ScalarValue { private final BigDecimal value; @Internal - protected FloatValue(BigDecimal value, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected FloatValue(BigDecimal value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } /** * alternative to using a Builder for convenience + * + * @param value of the Float */ public FloatValue(BigDecimal value) { - this(value, null, new ArrayList<>()); + this(value, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public BigDecimal getValue() { @@ -35,7 +50,18 @@ public BigDecimal getValue() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); + } + + @Override + public FloatValue withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; } @Override @@ -46,19 +72,23 @@ public String toString() { } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } FloatValue that = (FloatValue) o; - return !(value != null ? !value.equals(that.value) : that.value != null); + return Objects.equals(value, that.value); } @Override public FloatValue deepCopy() { - return new FloatValue(value, getSourceLocation(), getComments()); + return new FloatValue(value, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } public FloatValue transform(Consumer builderConsumer) { @@ -72,6 +102,10 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitFloatValue(this, context); } + public static FloatValue of(double d) { + return newFloatValue().value(d).build(); + } + public static Builder newFloatValue() { return new Builder(); } @@ -80,18 +114,22 @@ public static Builder newFloatValue(BigDecimal value) { return new Builder().value(value); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; private BigDecimal value; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(FloatValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.value = existing.getValue(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -105,14 +143,39 @@ public Builder value(BigDecimal value) { return this; } + public Builder value(double value) { + this.value = BigDecimal.valueOf(value); + return this; + } + + public Builder value(long value) { + this.value = BigDecimal.valueOf(value); + return this; + } + public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public FloatValue build() { - FloatValue floatValue = new FloatValue(value, sourceLocation, comments); - return floatValue; + return new FloatValue(value, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/FragmentDefinition.java b/src/main/java/graphql/language/FragmentDefinition.java index e0c1fa45e3..3913959607 100644 --- a/src/main/java/graphql/language/FragmentDefinition.java +++ b/src/main/java/graphql/language/FragmentDefinition.java @@ -1,37 +1,52 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + /** * Provided to the DataFetcher, therefore public API */ @PublicApi -public class FragmentDefinition extends AbstractNode implements Definition, SelectionSetContainer, DirectivesContainer { +public class FragmentDefinition extends AbstractNode implements Definition, SelectionSetContainer, DirectivesContainer, NamedNode { private final String name; private final TypeName typeCondition; - private final List directives; + private final NodeUtil.DirectivesHolder directives; private final SelectionSet selectionSet; + public static final String CHILD_TYPE_CONDITION = "typeCondition"; + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_SELECTION_SET = "selectionSet"; + @Internal protected FragmentDefinition(String name, - TypeName typeCondition, - List directives, - SelectionSet selectionSet, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + TypeName typeCondition, + List directives, + SelectionSet selectionSet, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; this.typeCondition = typeCondition; - this.directives = directives; + this.directives = NodeUtil.DirectivesHolder.of(directives); this.selectionSet = selectionSet; } @@ -47,9 +62,23 @@ public TypeName getTypeCondition() { @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); + } @Override public SelectionSet getSelectionSet() { @@ -60,30 +89,53 @@ public SelectionSet getSelectionSet() { public List getChildren() { List result = new ArrayList<>(); result.add(typeCondition); - result.addAll(directives); + result.addAll(directives.getDirectives()); result.add(selectionSet); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE_CONDITION, typeCondition) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .child(CHILD_SELECTION_SET, selectionSet) + .build(); + } + + @Override + public FragmentDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .typeCondition(newChildren.getChildOrNull(CHILD_TYPE_CONDITION)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .selectionSet(newChildren.getChildOrNull(CHILD_SELECTION_SET)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } FragmentDefinition that = (FragmentDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public FragmentDefinition deepCopy() { return new FragmentDefinition(name, deepCopy(typeCondition), - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(selectionSet), getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -111,24 +163,29 @@ public FragmentDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private String name; private TypeName typeCondition; - private List directives = new ArrayList<>(); + private ImmutableList directives = emptyList(); private SelectionSet selectionSet; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(FragmentDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.typeCondition = existing.getTypeCondition(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); this.selectionSet = existing.getSelectionSet(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -138,7 +195,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -152,8 +209,14 @@ public Builder typeCondition(TypeName typeCondition) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); return this; } @@ -162,9 +225,24 @@ public Builder selectionSet(SelectionSet selectionSet) { return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public FragmentDefinition build() { - FragmentDefinition fragmentDefinition = new FragmentDefinition(name, typeCondition, directives, selectionSet, sourceLocation, comments); - return fragmentDefinition; + return new FragmentDefinition(name, typeCondition, directives, selectionSet, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/FragmentSpread.java b/src/main/java/graphql/language/FragmentSpread.java index 23df8a1404..36575b36ed 100644 --- a/src/main/java/graphql/language/FragmentSpread.java +++ b/src/main/java/graphql/language/FragmentSpread.java @@ -1,33 +1,46 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class FragmentSpread extends AbstractNode implements Selection, DirectivesContainer { +public class FragmentSpread extends AbstractNode implements Selection, DirectivesContainer, NamedNode { private final String name; - private final List directives; + private final NodeUtil.DirectivesHolder directives; + + public static final String CHILD_DIRECTIVES = "directives"; @Internal - protected FragmentSpread(String name, List directives, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected FragmentSpread(String name, List directives, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; - this.directives = new ArrayList<>(directives); + this.directives = NodeUtil.DirectivesHolder.of(directives); } /** * alternative to using a Builder for convenience + * + * @param name of the fragment */ public FragmentSpread(String name) { - this(name, new ArrayList<>(), null, new ArrayList<>()); + this(name, emptyList(), null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override @@ -37,30 +50,61 @@ public String getName() { @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } FragmentSpread that = (FragmentSpread) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public List getChildren() { - List result = new ArrayList<>(); - result.addAll(directives); - return result; + return ImmutableList.copyOf(directives.getDirectives()); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public FragmentSpread withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); } @Override public FragmentSpread deepCopy() { - return new FragmentSpread(name, deepCopy(directives), getSourceLocation(), getComments()); + return new FragmentSpread(name, deepCopy(directives.getDirectives()), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -91,20 +135,24 @@ public FragmentSpread transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; - private List directives = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(FragmentSpread existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -113,7 +161,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -122,14 +170,35 @@ public Builder name(String name) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public FragmentSpread build() { - FragmentSpread fragmentSpread = new FragmentSpread(name, directives, sourceLocation, comments); - return fragmentSpread; + return new FragmentSpread(name, directives, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/IgnoredChar.java b/src/main/java/graphql/language/IgnoredChar.java new file mode 100644 index 0000000000..eaa1689d0c --- /dev/null +++ b/src/main/java/graphql/language/IgnoredChar.java @@ -0,0 +1,75 @@ +package graphql.language; + +import graphql.PublicApi; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Graphql syntax has a series of characters, such as spaces, new lines and commas that are not considered relevant + * to the syntax. However they can be captured and associated with the AST elements they belong to. + * + * This costs more memory but for certain use cases (like editors) this maybe be useful + */ +@PublicApi +public class IgnoredChar implements Serializable { + + public enum IgnoredCharKind { + SPACE, COMMA, TAB, CR, LF, OTHER + } + + private final String value; + private final IgnoredCharKind kind; + private final SourceLocation sourceLocation; + + + public IgnoredChar(String value, IgnoredCharKind kind, SourceLocation sourceLocation) { + this.value = value; + this.kind = kind; + this.sourceLocation = sourceLocation; + } + + public String getValue() { + return value; + } + + public IgnoredCharKind getKind() { + return kind; + } + + public SourceLocation getSourceLocation() { + return sourceLocation; + } + + @Override + public String toString() { + return "IgnoredChar{" + + "value='" + value + '\'' + + ", kind=" + kind + + ", sourceLocation=" + sourceLocation + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + IgnoredChar that = (IgnoredChar) o; + return Objects.equals(value, that.value) && + kind == that.kind && + Objects.equals(sourceLocation, that.sourceLocation); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + Objects.hashCode(value); + result = 31 * result + Objects.hashCode(kind); + result = 31 * result + Objects.hashCode(sourceLocation); + return result; + } +} diff --git a/src/main/java/graphql/language/IgnoredChars.java b/src/main/java/graphql/language/IgnoredChars.java new file mode 100644 index 0000000000..ce3a1ad59c --- /dev/null +++ b/src/main/java/graphql/language/IgnoredChars.java @@ -0,0 +1,37 @@ +package graphql.language; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; + +import java.io.Serializable; +import java.util.List; + +/** + * Graphql syntax has a series of characters, such as spaces, new lines and commas that are not considered relevant + * to the syntax. However they can be captured and associated with the AST elements they belong to. + * + * This costs more memory but for certain use cases (like editors) this maybe be useful + */ +@PublicApi +public class IgnoredChars implements Serializable { + + private final ImmutableList left; + private final ImmutableList right; + + public static final IgnoredChars EMPTY = new IgnoredChars(ImmutableKit.emptyList(), ImmutableKit.emptyList()); + + public IgnoredChars(List left, List right) { + this.left = ImmutableList.copyOf(left); + this.right = ImmutableList.copyOf(right); + } + + + public List getLeft() { + return left; + } + + public List getRight() { + return right; + } +} diff --git a/src/main/java/graphql/language/ImplementingTypeDefinition.java b/src/main/java/graphql/language/ImplementingTypeDefinition.java new file mode 100644 index 0000000000..31effe0d11 --- /dev/null +++ b/src/main/java/graphql/language/ImplementingTypeDefinition.java @@ -0,0 +1,19 @@ +package graphql.language; + + +import graphql.PublicApi; + +import java.util.List; + +/** + * A {@link TypeDefinition} that might implement interfaces + * + * @param for two + */ +@PublicApi +public interface ImplementingTypeDefinition extends TypeDefinition { + + List getImplements(); + + List getFieldDefinitions(); +} diff --git a/src/main/java/graphql/language/InlineFragment.java b/src/main/java/graphql/language/InlineFragment.java index 01470ff0c9..b065a5b8df 100644 --- a/src/main/java/graphql/language/InlineFragment.java +++ b/src/main/java/graphql/language/InlineFragment.java @@ -1,67 +1,90 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; -import static graphql.language.NodeUtil.directivesByName; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; @PublicApi -public class InlineFragment extends AbstractNode implements Selection, SelectionSetContainer { +public class InlineFragment extends AbstractNode implements Selection, SelectionSetContainer, DirectivesContainer { private final TypeName typeCondition; - private final List directives; + private final NodeUtil.DirectivesHolder directives; private final SelectionSet selectionSet; + public static final String CHILD_TYPE_CONDITION = "typeCondition"; + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_SELECTION_SET = "selectionSet"; + @Internal protected InlineFragment(TypeName typeCondition, - List directives, - SelectionSet selectionSet, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List directives, + SelectionSet selectionSet, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.typeCondition = typeCondition; - this.directives = directives; + this.directives = NodeUtil.DirectivesHolder.of(directives); this.selectionSet = selectionSet; } /** * alternative to using a Builder for convenience + * + * @param typeCondition the type condition of the inline fragment */ public InlineFragment(TypeName typeCondition) { - this(typeCondition, new ArrayList<>(), null, null, new ArrayList<>()); + this(typeCondition, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param typeCondition the type condition of the inline fragment + * @param selectionSet of the inline fragment */ public InlineFragment(TypeName typeCondition, SelectionSet selectionSet) { - this(typeCondition, new ArrayList<>(), selectionSet, null, new ArrayList<>()); + this(typeCondition, emptyList(), selectionSet, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public TypeName getTypeCondition() { return typeCondition; } - + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } - public Map getDirectivesByName() { - return directivesByName(directives); + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); } - public Directive getDirective(String directiveName) { - return getDirectivesByName().get(directiveName); + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); } + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); + } @Override public SelectionSet getSelectionSet() { @@ -74,28 +97,47 @@ public List getChildren() { if (typeCondition != null) { result.add(typeCondition); } - result.addAll(directives); + result.addAll(directives.getDirectives()); result.add(selectionSet); return result; } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE_CONDITION, typeCondition) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .child(CHILD_SELECTION_SET, selectionSet) + .build(); + } + + @Override + public InlineFragment withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .typeCondition(newChildren.getChildOrNull(CHILD_TYPE_CONDITION)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .selectionSet(newChildren.getChildOrNull(CHILD_SELECTION_SET)) + ); + } - return true; + @Override + public boolean isEqualTo(Node o) { + if (this == o) { + return true; + } + return o != null && getClass() == o.getClass(); } @Override public InlineFragment deepCopy() { return new InlineFragment( deepCopy(typeCondition), - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(selectionSet), getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -122,12 +164,14 @@ public InlineFragment transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private TypeName typeCondition; - private List directives = new ArrayList<>(); + private ImmutableList directives = emptyList(); private SelectionSet selectionSet; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } @@ -135,10 +179,12 @@ private Builder() { private Builder(InlineFragment existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.typeCondition = existing.getTypeCondition(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); this.selectionSet = existing.getSelectionSet(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -148,7 +194,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -157,19 +203,41 @@ public Builder typeCondition(TypeName typeCondition) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); return this; } + public Builder selectionSet(SelectionSet selectionSet) { this.selectionSet = selectionSet; return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public InlineFragment build() { - InlineFragment inlineFragment = new InlineFragment(typeCondition, directives, selectionSet, sourceLocation, comments); - return inlineFragment; + return new InlineFragment(typeCondition, directives, selectionSet, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/InputObjectTypeDefinition.java b/src/main/java/graphql/language/InputObjectTypeDefinition.java index 126a65a4a3..d545814091 100644 --- a/src/main/java/graphql/language/InputObjectTypeDefinition.java +++ b/src/main/java/graphql/language/InputObjectTypeDefinition.java @@ -1,40 +1,66 @@ package graphql.language; - +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.FpKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class InputObjectTypeDefinition extends AbstractNode implements TypeDefinition, DirectivesContainer { +public class InputObjectTypeDefinition extends AbstractDescribedNode implements TypeDefinition, DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List directives; - private final List inputValueDefinitions; + private final NodeUtil.DirectivesHolder directives; + private final ImmutableList inputValueDefinitions; + + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_INPUT_VALUES_DEFINITIONS = "inputValueDefinitions"; @Internal protected InputObjectTypeDefinition(String name, - List directives, - List inputValueDefinitions, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List directives, + List inputValueDefinitions, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.description = description; - this.directives = directives; - this.inputValueDefinitions = inputValueDefinitions; + this.directives = NodeUtil.DirectivesHolder.of(directives); + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } public List getInputValueDefinitions() { @@ -46,36 +72,51 @@ public String getName() { return name; } - public Description getDescription() { - return description; + @Override + public List getChildren() { + return FpKit.concat(directives.getDirectives(), inputValueDefinitions); } @Override - public List getChildren() { - List result = new ArrayList<>(); - result.addAll(directives); - result.addAll(inputValueDefinitions); - return result; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .children(CHILD_INPUT_VALUES_DEFINITIONS, inputValueDefinitions) + .build(); + } + + @Override + public InputObjectTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .inputValueDefinitions(newChildren.getChildren(CHILD_INPUT_VALUES_DEFINITIONS)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } InputObjectTypeDefinition that = (InputObjectTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public InputObjectTypeDefinition deepCopy() { return new InputObjectTypeDefinition(name, - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(inputValueDefinitions), description, getSourceLocation(), - getComments()); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -103,24 +144,27 @@ public InputObjectTypeDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives = new ArrayList<>(); - private List inputValueDefinitions = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private ImmutableList inputValueDefinitions = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(InputObjectTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.inputValueDefinitions = existing.getInputValueDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.inputValueDefinitions = ImmutableList.copyOf(existing.getInputValueDefinitions()); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -130,7 +174,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -144,34 +188,52 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } public Builder inputValueDefinitions(List inputValueDefinitions) { - this.inputValueDefinitions = inputValueDefinitions; + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); return this; } public Builder inputValueDefinition(InputValueDefinition inputValueDefinition) { - this.inputValueDefinitions.add(inputValueDefinition); + this.inputValueDefinitions = ImmutableKit.addToList(inputValueDefinitions, inputValueDefinition); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public InputObjectTypeDefinition build() { - InputObjectTypeDefinition inputObjectTypeDefinition = new InputObjectTypeDefinition(name, + return new InputObjectTypeDefinition(name, directives, inputValueDefinitions, description, sourceLocation, - comments); - return inputObjectTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/InputObjectTypeExtensionDefinition.java b/src/main/java/graphql/language/InputObjectTypeExtensionDefinition.java index 3026aa18d8..0835c0eb44 100644 --- a/src/main/java/graphql/language/InputObjectTypeExtensionDefinition.java +++ b/src/main/java/graphql/language/InputObjectTypeExtensionDefinition.java @@ -1,23 +1,31 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + @PublicApi -public class InputObjectTypeExtensionDefinition extends InputObjectTypeDefinition { +public class InputObjectTypeExtensionDefinition extends InputObjectTypeDefinition implements SDLExtensionDefinition { @Internal protected InputObjectTypeExtensionDefinition(String name, - List directives, - List inputValueDefinitions, - Description description, - SourceLocation sourceLocation, - List comments) { - super(name, directives, inputValueDefinitions, description, sourceLocation, comments); + List directives, + List inputValueDefinitions, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(name, directives, inputValueDefinitions, description, sourceLocation, comments, ignoredChars, additionalData); } @Override @@ -27,7 +35,9 @@ public InputObjectTypeExtensionDefinition deepCopy() { deepCopy(getInputValueDefinitions()), getDescription(), getSourceLocation(), - getComments()); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -43,6 +53,13 @@ public static Builder newInputObjectTypeExtensionDefinition() { return new Builder(); } + @Override + public InputObjectTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .inputValueDefinitions(newChildren.getChildren(CHILD_INPUT_VALUES_DEFINITIONS)) + ); + } public InputObjectTypeExtensionDefinition transformExtension(Consumer builderConsumer) { Builder builder = new Builder(this); @@ -50,24 +67,28 @@ public InputObjectTypeExtensionDefinition transformExtension(Consumer b return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives = new ArrayList<>(); - private List inputValueDefinitions = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private ImmutableList inputValueDefinitions = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(InputObjectTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.inputValueDefinitions = existing.getInputValueDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.inputValueDefinitions = ImmutableList.copyOf(existing.getInputValueDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -77,7 +98,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -91,23 +112,52 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); return this; } + public Builder inputValueDefinitions(List inputValueDefinitions) { - this.inputValueDefinitions = inputValueDefinitions; + this.inputValueDefinitions = ImmutableList.copyOf(inputValueDefinitions); + return this; + } + + public Builder inputValueDefinition(InputValueDefinition inputValueDefinition) { + this.inputValueDefinitions = ImmutableKit.addToList(inputValueDefinitions, inputValueDefinition); return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public InputObjectTypeExtensionDefinition build() { InputObjectTypeExtensionDefinition inputObjectTypeDefinition = new InputObjectTypeExtensionDefinition(name, directives, inputValueDefinitions, description, sourceLocation, - comments); + comments, + ignoredChars, additionalData); return inputObjectTypeDefinition; } } diff --git a/src/main/java/graphql/language/InputValueDefinition.java b/src/main/java/graphql/language/InputValueDefinition.java index 4169866be7..c0db3318fa 100644 --- a/src/main/java/graphql/language/InputValueDefinition.java +++ b/src/main/java/graphql/language/InputValueDefinition.java @@ -1,58 +1,77 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class InputValueDefinition extends AbstractNode implements DirectivesContainer { +public class InputValueDefinition extends AbstractDescribedNode implements DirectivesContainer, NamedNode { private final String name; private final Type type; private final Value defaultValue; - private final Description description; - private final List directives; + private final NodeUtil.DirectivesHolder directives; + public static final String CHILD_TYPE = "type"; + public static final String CHILD_DEFAULT_VALUE = "defaultValue"; + public static final String CHILD_DIRECTIVES = "directives"; @Internal protected InputValueDefinition(String name, - Type type, - Value defaultValue, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + Type type, + Value defaultValue, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; this.type = type; this.defaultValue = defaultValue; - this.directives = directives; - this.description = description; - + this.directives = NodeUtil.DirectivesHolder.of(directives); } /** * alternative to using a Builder for convenience + * + * @param name of the input value + * @param type of the input value */ public InputValueDefinition(String name, Type type) { - this(name, type, null, new ArrayList<>(), null, null, new ArrayList<>()); + this(name, type, null, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the input value + * @param type of the input value + * @param defaultValue of the input value */ public InputValueDefinition(String name, Type type, Value defaultValue) { - this(name, type, defaultValue, new ArrayList<>(), null, null, new ArrayList<>()); + this(name, type, defaultValue, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @@ -65,35 +84,72 @@ public String getName() { return name; } - public Description getDescription() { - return description; - } - public Value getDefaultValue() { return defaultValue; } + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } @Override public List getChildren() { List result = new ArrayList<>(); result.add(type); - result.add(defaultValue); - result.addAll(directives); + if (defaultValue != null) { + result.add(defaultValue); + } + result.addAll(directives.getDirectives()); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE, type) + .child(CHILD_DEFAULT_VALUE, defaultValue) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public InputValueDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .type(newChildren.getChildOrNull(CHILD_TYPE)) + .defaultValue(newChildren.getChildOrNull(CHILD_DEFAULT_VALUE)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } InputValueDefinition that = (InputValueDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override @@ -101,10 +157,12 @@ public InputValueDefinition deepCopy() { return new InputValueDefinition(name, deepCopy(type), deepCopy(defaultValue), - deepCopy(directives), + deepCopy(directives.getDirectives()), description, getSourceLocation(), - getComments()); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -132,26 +190,29 @@ public InputValueDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Type type; private Value defaultValue; private Description description; - private List directives = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(InputValueDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.type = existing.getType(); this.defaultValue = existing.getDefaultValue(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -161,7 +222,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -185,25 +246,42 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public InputValueDefinition build() { - InputValueDefinition inputValueDefinition = new InputValueDefinition(name, + return new InputValueDefinition(name, type, defaultValue, directives, description, sourceLocation, - comments); - return inputValueDefinition; + comments, + ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/IntValue.java b/src/main/java/graphql/language/IntValue.java index bf168c2cc2..5a197646d9 100644 --- a/src/main/java/graphql/language/IntValue.java +++ b/src/main/java/graphql/language/IntValue.java @@ -1,35 +1,47 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import java.math.BigInteger; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi +@NullMarked public class IntValue extends AbstractNode implements ScalarValue { private final BigInteger value; @Internal - protected IntValue(BigInteger value, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected IntValue(BigInteger value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } /** * alternative to using a Builder for convenience * - * @param value + * @param value of the Int */ public IntValue(BigInteger value) { - super(null, new ArrayList<>()); - this.value = value; + this(value, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public BigInteger getValue() { @@ -38,23 +50,37 @@ public BigInteger getValue() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); + } - IntValue that = (IntValue) o; + @Override + public IntValue withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; + } - return !(value != null ? !value.equals(that.value) : that.value != null); + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + IntValue that = (IntValue) o; + return Objects.equals(value, that.value); } @Override public IntValue deepCopy() { - return new IntValue(value, getSourceLocation(), getComments()); + return new IntValue(value, getSourceLocation(), getComments(), IgnoredChars.EMPTY, getAdditionalData()); } @Override @@ -69,6 +95,10 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitIntValue(this, context); } + public static IntValue of(int i) { + return newIntValue().value(i).build(); + } + public static Builder newIntValue() { return new Builder(); } @@ -83,18 +113,22 @@ public IntValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; private BigInteger value; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(IntValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.value = existing.getValue(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -107,14 +141,33 @@ public Builder value(BigInteger value) { return this; } + public Builder value(int value) { + this.value = BigInteger.valueOf(value); + return this; + } + public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public IntValue build() { - IntValue intValue = new IntValue(value, sourceLocation, comments); - return intValue; + return new IntValue(value, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/InterfaceTypeDefinition.java b/src/main/java/graphql/language/InterfaceTypeDefinition.java index ac5c82b503..3fd1343f89 100644 --- a/src/main/java/graphql/language/InterfaceTypeDefinition.java +++ b/src/main/java/graphql/language/InterfaceTypeDefinition.java @@ -1,96 +1,157 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class InterfaceTypeDefinition extends AbstractNode implements TypeDefinition, DirectivesContainer { +public class InterfaceTypeDefinition extends AbstractDescribedNode implements ImplementingTypeDefinition, DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List definitions; - private final List directives; + private final ImmutableList implementz; + private final ImmutableList definitions; + private final NodeUtil.DirectivesHolder directives; + + public static final String CHILD_IMPLEMENTZ = "implementz"; + public static final String CHILD_DEFINITIONS = "definitions"; + public static final String CHILD_DIRECTIVES = "directives"; @Internal protected InterfaceTypeDefinition(String name, - List definitions, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List implementz, + List definitions, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.definitions = definitions; - this.directives = directives; - this.description = description; + this.implementz = ImmutableList.copyOf(implementz); + this.definitions = ImmutableList.copyOf(definitions); + this.directives = NodeUtil.DirectivesHolder.of(directives); } /** * alternative to using a Builder for convenience + * + * @param name of the interface */ public InterfaceTypeDefinition(String name) { - this(name, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); + } + + @Override + public List getImplements() { + return implementz; } + @Override public List getFieldDefinitions() { - return new ArrayList<>(definitions); + return definitions; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } @Override - public String getName() { - return name; + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); } - public Description getDescription() { - return description; + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } + @Override + public String getName() { + return name; + } @Override public List getChildren() { List result = new ArrayList<>(); + result.addAll(implementz); result.addAll(definitions); - result.addAll(directives); + result.addAll(directives.getDirectives()); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_IMPLEMENTZ, implementz) + .children(CHILD_DEFINITIONS, definitions) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public InterfaceTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .implementz(newChildren.getChildren(CHILD_IMPLEMENTZ)) + .definitions(newChildren.getChildren(CHILD_DEFINITIONS)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } InterfaceTypeDefinition that = (InterfaceTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public InterfaceTypeDefinition deepCopy() { return new InterfaceTypeDefinition(name, + deepCopy(implementz), deepCopy(definitions), - deepCopy(directives), + deepCopy(directives.getDirectives()), description, getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override public String toString() { return "InterfaceTypeDefinition{" + "name='" + name + '\'' + + ", implements=" + implementz + ", fieldDefinitions=" + definitions + ", directives=" + directives + '}'; @@ -112,13 +173,16 @@ public InterfaceTypeDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List definitions = new ArrayList<>(); - private List directives = new ArrayList<>(); + private ImmutableList implementz = emptyList(); + private ImmutableList definitions = emptyList(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } @@ -126,22 +190,24 @@ private Builder() { private Builder(InterfaceTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.definitions = existing.getFieldDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.definitions = ImmutableList.copyOf(existing.getFieldDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); + this.implementz = ImmutableList.copyOf(existing.getImplements()); } - public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -155,34 +221,64 @@ public Builder description(Description description) { return this; } + public Builder implementz(List implementz) { + this.implementz = ImmutableList.copyOf(implementz); + return this; + } + + public Builder implementz(Type implement) { + this.implementz = ImmutableKit.addToList(implementz, implement); + return this; + } + + public Builder definitions(List definitions) { - this.definitions = definitions; + this.definitions = ImmutableList.copyOf(definitions); return this; } public Builder definition(FieldDefinition definition) { - this.definitions.add(definition); + this.definitions = ImmutableKit.addToList(definitions, definition); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public InterfaceTypeDefinition build() { - InterfaceTypeDefinition interfaceTypeDefinition = new InterfaceTypeDefinition(name, + return new InterfaceTypeDefinition(name, + implementz, definitions, directives, description, sourceLocation, - comments); - return interfaceTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/InterfaceTypeExtensionDefinition.java b/src/main/java/graphql/language/InterfaceTypeExtensionDefinition.java index bc6c3af581..2de917065b 100644 --- a/src/main/java/graphql/language/InterfaceTypeExtensionDefinition.java +++ b/src/main/java/graphql/language/InterfaceTypeExtensionDefinition.java @@ -1,34 +1,45 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + @PublicApi -public class InterfaceTypeExtensionDefinition extends InterfaceTypeDefinition { +public class InterfaceTypeExtensionDefinition extends InterfaceTypeDefinition implements SDLExtensionDefinition { @Internal protected InterfaceTypeExtensionDefinition(String name, - List definitions, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { - super(name, definitions, directives, description, sourceLocation, comments); + List implementz, + List definitions, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(name, implementz, definitions, directives, description, sourceLocation, comments, ignoredChars, additionalData); } @Override public InterfaceTypeExtensionDefinition deepCopy() { return new InterfaceTypeExtensionDefinition(getName(), + getImplements(), deepCopy(getFieldDefinitions()), deepCopy(getDirectives()), getDescription(), getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -45,30 +56,44 @@ public static Builder newInterfaceTypeExtensionDefinition() { return new Builder(); } + @Override + public InterfaceTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder + .definitions(newChildren.getChildren(CHILD_DEFINITIONS)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + public InterfaceTypeExtensionDefinition transformExtension(Consumer builderConsumer) { Builder builder = new Builder(this); builderConsumer.accept(builder); return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List definitions = new ArrayList<>(); - private List directives = new ArrayList<>(); + private ImmutableList implementz = emptyList(); + private ImmutableList definitions = emptyList(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(InterfaceTypeExtensionDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.definitions = existing.getFieldDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.implementz = ImmutableList.copyOf(existing.getImplements()); + this.definitions = ImmutableList.copyOf(existing.getFieldDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -77,7 +102,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -91,24 +116,63 @@ public Builder description(Description description) { return this; } + public Builder implementz(List implementz) { + this.implementz = ImmutableList.copyOf(implementz); + return this; + } + + public Builder implementz(Type implementz) { + this.implementz = ImmutableKit.addToList(this.implementz, implementz); + return this; + } + public Builder definitions(List definitions) { - this.definitions = definitions; + this.definitions = ImmutableList.copyOf(definitions); + return this; + } + + public Builder definition(FieldDefinition definition) { + this.definitions = ImmutableKit.addToList(definitions, definition); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public InterfaceTypeExtensionDefinition build() { - InterfaceTypeExtensionDefinition interfaceTypeDefinition = new InterfaceTypeExtensionDefinition(name, + return new InterfaceTypeExtensionDefinition(name, + implementz, definitions, directives, description, sourceLocation, - comments); - return interfaceTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/ListType.java b/src/main/java/graphql/language/ListType.java index 70addc3566..f193179bb6 100644 --- a/src/main/java/graphql/language/ListType.java +++ b/src/main/java/graphql/language/ListType.java @@ -1,32 +1,42 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class ListType extends AbstractNode implements Type { private final Type type; + public static final String CHILD_TYPE = "type"; + @Internal - protected ListType(Type type, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected ListType(Type type, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.type = type; } /** * alternative to using a Builder for convenience + * + * @param type the wrapped type */ public ListType(Type type) { - super(null, new ArrayList<>()); - this.type = type; + this(type, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public Type getType() { @@ -35,22 +45,38 @@ public Type getType() { @Override public List getChildren() { - List result = new ArrayList<>(); - result.add(type); - return result; + return ImmutableList.of(type); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE, type) + .build(); + } + + @Override + public ListType withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .type(newChildren.getChildOrNull(CHILD_TYPE)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; } @Override public ListType deepCopy() { - return new ListType(deepCopy(type), getSourceLocation(), getComments()); + return new ListType(deepCopy(type), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -82,15 +108,19 @@ public ListType transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private Type type; private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(ListType existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.type = existing.getType(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -105,13 +135,27 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ListType build() { - ListType listType = new ListType(type, sourceLocation, comments); - return listType; + return new ListType(type, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/Node.java b/src/main/java/graphql/language/Node.java index bf5c3f6827..962934d76b 100644 --- a/src/main/java/graphql/language/Node.java +++ b/src/main/java/graphql/language/Node.java @@ -4,9 +4,11 @@ import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.Nullable; import java.io.Serializable; import java.util.List; +import java.util.Map; /** * The base interface for virtually all graphql language elements @@ -15,6 +17,8 @@ * are not aiming to provide long term compatibility and do not intend for you to place this serialised data into permanent storage, * with times frames that cross graphql-java versions. While we don't change things unnecessarily, we may inadvertently break * the serialised compatibility across versions. + * + * Every Node is immutable */ @PublicApi public interface Node extends Serializable { @@ -24,9 +28,27 @@ public interface Node extends Serializable { */ List getChildren(); + /** + * Alternative to {@link #getChildren()} where the children are not all in one list regardless of type + * but grouped by name/type of the child. + * + * @return a container of the child nodes + */ + NodeChildrenContainer getNamedChildren(); + + /** + * Replaces the specified children and returns a new Node. + * + * @param newChildren must be empty for Nodes without children + * + * @return a new node + */ + T withNewChildren(NodeChildrenContainer newChildren); + /** * @return the source location where this node occurs */ + @Nullable SourceLocation getSourceLocation(); /** @@ -36,6 +58,25 @@ public interface Node extends Serializable { */ List getComments(); + /** + * The chars which are ignored by the parser. (Before and after the current node) + * + * @return the ignored chars + */ + IgnoredChars getIgnoredChars(); + + /** + * A node can have a map of additional data associated with it. + * + *

+ * NOTE: The reason this is a map of strings is so the Node + * can stay an immutable object, which Map<String,Object> would not allow + * say. + * + * @return the map of additional data about this node + */ + Map getAdditionalData(); + /** * Compares just the content and not the children. * @@ -43,7 +84,7 @@ public interface Node extends Serializable { * * @return isEqualTo */ - boolean isEqualTo(Node node); + boolean isEqualTo(@Nullable Node node); /** * @return a deep copy of this node @@ -69,4 +110,6 @@ public interface Node extends Serializable { * Note! Visitor's operation might return special results to control traversal process. */ TraversalControl accept(TraverserContext context, NodeVisitor visitor); + + } diff --git a/src/main/java/graphql/language/NodeBuilder.java b/src/main/java/graphql/language/NodeBuilder.java index 18479e0b48..88aaf63c82 100644 --- a/src/main/java/graphql/language/NodeBuilder.java +++ b/src/main/java/graphql/language/NodeBuilder.java @@ -1,13 +1,23 @@ package graphql.language; import graphql.PublicApi; +import org.jspecify.annotations.NullUnmarked; import java.util.List; +import java.util.Map; @PublicApi +@NullUnmarked public interface NodeBuilder { NodeBuilder sourceLocation(SourceLocation sourceLocation); NodeBuilder comments(List comments); + + NodeBuilder ignoredChars(IgnoredChars ignoredChars); + + NodeBuilder additionalData(Map additionalData); + + NodeBuilder additionalData(String key, String value); + } diff --git a/src/main/java/graphql/language/NodeChildrenContainer.java b/src/main/java/graphql/language/NodeChildrenContainer.java new file mode 100644 index 0000000000..d2e1b06fea --- /dev/null +++ b/src/main/java/graphql/language/NodeChildrenContainer.java @@ -0,0 +1,113 @@ +package graphql.language; + +import graphql.PublicApi; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + +/** + * Container of children of a {@link Node}. + */ +@PublicApi +public class NodeChildrenContainer { + + private final Map> children = new LinkedHashMap<>(); + + private NodeChildrenContainer(Map> children) { + this.children.putAll(assertNotNull(children)); + } + + public List getChildren(String key) { + return (List) children.getOrDefault(key, emptyList()); + } + + public T getChildOrNull(String key) { + List result = children.getOrDefault(key, emptyList()); + if (result.size() > 1) { + throw new IllegalStateException("children " + key + " is not a single value"); + } + return result.size() > 0 ? (T) result.get(0) : null; + } + + public Map> getChildren() { + return new LinkedHashMap<>(children); + } + + public static Builder newNodeChildrenContainer() { + return new Builder(); + } + + public static Builder newNodeChildrenContainer(Map> childrenMap) { + return new Builder().children(childrenMap); + } + + public static Builder newNodeChildrenContainer(NodeChildrenContainer existing) { + return new Builder(existing); + } + + public NodeChildrenContainer transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public boolean isEmpty() { + return this.children.isEmpty(); + } + + public static class Builder { + private final Map> children = new LinkedHashMap<>(); + + private Builder() { + + } + + private Builder(NodeChildrenContainer other) { + this.children.putAll(other.children); + } + + public Builder child(String key, Node child) { + // we allow null here to make the actual nodes easier + if (child == null) { + return this; + } + children.computeIfAbsent(key, (k) -> new ArrayList<>()); + children.get(key).add(child); + return this; + } + + public Builder children(String key, List children) { + this.children.computeIfAbsent(key, (k) -> new ArrayList<>()); + this.children.get(key).addAll(children); + return this; + } + + public Builder children(Map> children) { + this.children.clear(); + this.children.putAll((Map>) children); + return this; + } + + public Builder replaceChild(String key, int index, Node newChild) { + assertNotNull(newChild); + this.children.get(key).set(index, newChild); + return this; + } + + public Builder removeChild(String key, int index) { + this.children.get(key).remove(index); + return this; + } + + public NodeChildrenContainer build() { + return new NodeChildrenContainer(this.children); + + } + } +} diff --git a/src/main/java/graphql/language/NodeDirectivesBuilder.java b/src/main/java/graphql/language/NodeDirectivesBuilder.java index ebbd5b8d08..3694165fab 100644 --- a/src/main/java/graphql/language/NodeDirectivesBuilder.java +++ b/src/main/java/graphql/language/NodeDirectivesBuilder.java @@ -9,4 +9,5 @@ public interface NodeDirectivesBuilder extends NodeBuilder { NodeDirectivesBuilder directives(List directives); + NodeDirectivesBuilder directive(Directive directive); } diff --git a/src/main/java/graphql/language/NodeParentTree.java b/src/main/java/graphql/language/NodeParentTree.java index 9e58294ac8..91907e6ef0 100644 --- a/src/main/java/graphql/language/NodeParentTree.java +++ b/src/main/java/graphql/language/NodeParentTree.java @@ -1,13 +1,15 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Deque; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertTrue; @@ -22,8 +24,8 @@ public class NodeParentTree { private final T node; - private final Optional> parent; - private final List path; + private final NodeParentTree parent; + private final ImmutableList path; @Internal public NodeParentTree(Deque nodeStack) { @@ -34,17 +36,16 @@ public NodeParentTree(Deque nodeStack) { path = mkPath(copy); node = copy.pop(); if (!copy.isEmpty()) { - parent = Optional.of(new NodeParentTree(copy)); + parent = new NodeParentTree<>(copy); } else { - parent = Optional.empty(); + parent = null; } } - private List mkPath(Deque copy) { - return copy.stream() - .filter(node1 -> node1 instanceof NamedNode) - .map(node1 -> ((NamedNode) node1).getName()) - .collect(Collectors.toList()); + private ImmutableList mkPath(Deque copy) { + return ImmutableKit.filterAndMap(copy, + node1 -> node1 instanceof NamedNode, + node1 -> ((NamedNode) node1).getName()); } @@ -61,7 +62,7 @@ public T getNode() { * @return a node MAY have an optional parent */ public Optional> getParentInfo() { - return parent; + return Optional.ofNullable(parent); } /** @@ -71,10 +72,22 @@ public List getPath() { return path; } + /** + * @return the tree as a list of T + */ + public List toList() { + List nodes = new ArrayList<>(); + nodes.add(node); + Optional> parentInfo = this.getParentInfo(); + while (parentInfo.isPresent()) { + nodes.add(parentInfo.get().getNode()); + parentInfo = parentInfo.get().getParentInfo(); + } + return nodes; + } + @Override public String toString() { - return String.valueOf(node) + - " - parent : " + - parent.isPresent(); + return node + " - parent : " + parent; } } \ No newline at end of file diff --git a/src/main/java/graphql/language/NodeTraverser.java b/src/main/java/graphql/language/NodeTraverser.java index 7c6b768c09..916c290f95 100644 --- a/src/main/java/graphql/language/NodeTraverser.java +++ b/src/main/java/graphql/language/NodeTraverser.java @@ -1,7 +1,8 @@ package graphql.language; import graphql.PublicApi; -import graphql.util.SimpleTraverserContext; +import graphql.collect.ImmutableKit; +import graphql.util.DefaultTraverserContext; import graphql.util.TraversalControl; import graphql.util.Traverser; import graphql.util.TraverserContext; @@ -20,14 +21,6 @@ public class NodeTraverser { - /** - * Used by depthFirst to indicate via {@link TraverserContext#getVar(Class)} if the visit happens inside the ENTER or LEAVE phase. - */ - public enum LeaveOrEnter { - LEAVE, - ENTER - } - private final Map, Object> rootVars; private final Function> getChildren; @@ -37,67 +30,71 @@ public NodeTraverser(Map, Object> rootVars, Function roots) { + public Object depthFirst(NodeVisitor nodeVisitor, Collection roots) { TraverserVisitor nodeTraverserVisitor = new TraverserVisitor() { @Override public TraversalControl enter(TraverserContext context) { - context.setVar(LeaveOrEnter.class, LeaveOrEnter.ENTER); return context.thisNode().accept(context, nodeVisitor); } @Override public TraversalControl leave(TraverserContext context) { - context.setVar(LeaveOrEnter.class, LeaveOrEnter.LEAVE); return context.thisNode().accept(context, nodeVisitor); } - }; - doTraverse(roots, nodeTraverserVisitor); + return doTraverse(roots, nodeTraverserVisitor); } /** * Version of {@link #preOrder(NodeVisitor, Collection)} with one root. * - * @param nodeVisitor - * @param root + * @param nodeVisitor the visitor of the nodes + * @param root the root node + * + * @return the accumulation result of this traversal */ - public void preOrder(NodeVisitor nodeVisitor, Node root) { - preOrder(nodeVisitor, Collections.singleton(root)); + public Object preOrder(NodeVisitor nodeVisitor, Node root) { + return preOrder(nodeVisitor, Collections.singleton(root)); } /** * Pre-Order traversal: This is a specialized version of depthFirst with only the enter phase. * - * @param nodeVisitor - * @param roots + * @param nodeVisitor the visitor of the nodes + * @param roots the root nodes + * + * @return the accumulation result of this traversal */ - public void preOrder(NodeVisitor nodeVisitor, Collection roots) { + public Object preOrder(NodeVisitor nodeVisitor, Collection roots) { TraverserVisitor nodeTraverserVisitor = new TraverserVisitor() { @Override public TraversalControl enter(TraverserContext context) { - context.setVar(LeaveOrEnter.class, LeaveOrEnter.ENTER); return context.thisNode().accept(context, nodeVisitor); } @@ -107,27 +104,30 @@ public TraversalControl leave(TraverserContext context) { } }; - doTraverse(roots, nodeTraverserVisitor); - + return doTraverse(roots, nodeTraverserVisitor); } /** * Version of {@link #postOrder(NodeVisitor, Collection)} with one root. * - * @param nodeVisitor - * @param root + * @param nodeVisitor the visitor of the nodes + * @param root the root node + * + * @return the accumulation result of this traversal */ - public void postOrder(NodeVisitor nodeVisitor, Node root) { - postOrder(nodeVisitor, Collections.singleton(root)); + public Object postOrder(NodeVisitor nodeVisitor, Node root) { + return postOrder(nodeVisitor, Collections.singleton(root)); } /** * Post-Order traversal: This is a specialized version of depthFirst with only the leave phase. * - * @param nodeVisitor - * @param roots + * @param nodeVisitor the visitor of the nodes + * @param roots the root nodes + * + * @return the accumulation result of this traversal */ - public void postOrder(NodeVisitor nodeVisitor, Collection roots) { + public Object postOrder(NodeVisitor nodeVisitor, Collection roots) { TraverserVisitor nodeTraverserVisitor = new TraverserVisitor() { @Override @@ -137,25 +137,24 @@ public TraversalControl enter(TraverserContext context) { @Override public TraversalControl leave(TraverserContext context) { - context.setVar(LeaveOrEnter.class, LeaveOrEnter.LEAVE); return context.thisNode().accept(context, nodeVisitor); } }; - doTraverse(roots, nodeTraverserVisitor); + return doTraverse(roots, nodeTraverserVisitor); } - private void doTraverse(Collection roots, TraverserVisitor traverserVisitor) { + private Object doTraverse(Collection roots, TraverserVisitor traverserVisitor) { Traverser nodeTraverser = Traverser.depthFirst(this.getChildren); nodeTraverser.rootVars(rootVars); - nodeTraverser.traverse(roots, traverserVisitor); + return nodeTraverser.traverse(roots, traverserVisitor).getAccumulatedResult(); } @SuppressWarnings("TypeParameterUnusedInFormals") public static T oneVisitWithResult(Node node, NodeVisitor nodeVisitor) { - SimpleTraverserContext context = new SimpleTraverserContext<>(node); + DefaultTraverserContext context = DefaultTraverserContext.simple(node); node.accept(context, nodeVisitor); - return (T) context.getResult(); + return (T) context.getNewAccumulate(); } } diff --git a/src/main/java/graphql/language/NodeUtil.java b/src/main/java/graphql/language/NodeUtil.java index ba85416180..71ccc46ca9 100644 --- a/src/main/java/graphql/language/NodeUtil.java +++ b/src/main/java/graphql/language/NodeUtil.java @@ -1,14 +1,20 @@ package graphql.language; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import graphql.Internal; import graphql.execution.UnknownOperationException; import graphql.util.FpKit; +import graphql.util.NodeLocation; +import java.io.Serializable; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import static graphql.util.FpKit.mergeFirst; +import static java.util.Objects.requireNonNull; /** * Helper class for working with {@link Node}s @@ -16,24 +22,21 @@ @Internal public class NodeUtil { - public static boolean isEqualTo(String thisStr, String thatStr) { - if (null == thisStr) { - if (null != thatStr) { - return false; + public static > T findNodeByName(List namedNodes, String name) { + for (T namedNode : namedNodes) { + if (Objects.equals(namedNode.getName(), name)) { + return namedNode; } - } else if (!thisStr.equals(thatStr)) { - return false; } - return true; + return null; } - - public static Map directivesByName(List directives) { - return FpKit.getByName(directives, Directive::getName, mergeFirst()); + public static Map> allDirectivesByName(List directives) { + return FpKit.groupingBy(directives, Directive::getName); } - public static Map argumentsByName(List arguments) { - return FpKit.getByName(arguments, Argument::getName, mergeFirst()); + public static > Map nodeByName(List nameNode) { + return FpKit.getByName(nameNode, NamedNode::getName, mergeFirst()); } @@ -88,4 +91,52 @@ public static GetOperationResult getOperation(Document document, String operatio result.operationDefinition = operation; return result; } + + public static void assertNewChildrenAreEmpty(NodeChildrenContainer newChildren) { + if (!newChildren.isEmpty()) { + throw new IllegalArgumentException("Cannot pass non-empty newChildren to Node that doesn't hold children"); + } + } + + public static Node removeChild(Node node, NodeLocation childLocationToRemove) { + NodeChildrenContainer namedChildren = node.getNamedChildren(); + NodeChildrenContainer newChildren = namedChildren.transform(builder -> builder.removeChild(childLocationToRemove.getName(), childLocationToRemove.getIndex())); + return node.withNewChildren(newChildren); + } + + + /** + * A simple directives holder that makes it easier for {@link DirectivesContainer} classes + * to have their methods AND be efficient via immutable structures + */ + @Internal + static class DirectivesHolder implements Serializable { + private final ImmutableList directives; + private final ImmutableMap> directivesByName; + + static DirectivesHolder of(List directives) { + return new DirectivesHolder(directives); + } + + DirectivesHolder(List directives) { + this.directives = ImmutableList.copyOf(directives); + directivesByName = ImmutableMap.copyOf(allDirectivesByName(directives)); + } + + ImmutableList getDirectives() { + return directives; + } + + ImmutableMap> getDirectivesByName() { + return directivesByName; + } + + ImmutableList getDirectives(String directiveName) { + return ImmutableList.copyOf(requireNonNull(directivesByName.getOrDefault(directiveName, ImmutableList.of()))); + } + + boolean hasDirective(String directiveName) { + return directivesByName.containsKey(directiveName); + } + } } diff --git a/src/main/java/graphql/language/NonNullType.java b/src/main/java/graphql/language/NonNullType.java index 2f1c9817dd..e86e39c244 100644 --- a/src/main/java/graphql/language/NonNullType.java +++ b/src/main/java/graphql/language/NonNullType.java @@ -1,36 +1,42 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class NonNullType extends AbstractNode implements Type { private final Type type; - @Internal - protected NonNullType(Type type, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + public static final String CHILD_TYPE = "type"; + @Internal + protected NonNullType(Type type, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.type = type; } /** * alternative to using a Builder for convenience * - * @param type + * @param type the wrapped type */ public NonNullType(Type type) { - super(null, new ArrayList<>()); - - this.type = type; + this(type, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public Type getType() { @@ -39,15 +45,31 @@ public Type getType() { @Override public List getChildren() { - List result = new ArrayList<>(); - result.add(type); - return result; + return ImmutableList.of(type); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE, type) + .build(); + } + + @Override + public NonNullType withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .type((Type) newChildren.getChildOrNull(CHILD_TYPE)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; @@ -55,7 +77,7 @@ public boolean isEqualTo(Node o) { @Override public NonNullType deepCopy() { - return new NonNullType(deepCopy(type), getSourceLocation(), getComments()); + return new NonNullType(deepCopy(type), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -87,15 +109,19 @@ public NonNullType transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; private Type type; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(NonNullType existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.type = existing.getType(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -123,13 +149,28 @@ public Builder type(Type type) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public NonNullType build() { - NonNullType nonNullType = new NonNullType(type, sourceLocation, comments); - return nonNullType; + return new NonNullType(type, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/NullValue.java b/src/main/java/graphql/language/NullValue.java index 12ecccf352..9e053acae2 100644 --- a/src/main/java/graphql/language/NullValue.java +++ b/src/main/java/graphql/language/NullValue.java @@ -1,34 +1,63 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; @PublicApi +@NullMarked public class NullValue extends AbstractNode implements Value { - public static final NullValue Null = new NullValue(null, Collections.emptyList()); - @Internal - protected NullValue(SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected NullValue(@Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + } + + public static NullValue of() { + return NullValue.newNullValue().build(); } @Override public List getChildren() { - return Collections.emptyList(); + return ImmutableKit.emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NullValue withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; + } + + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; @@ -55,9 +84,25 @@ public static Builder newNullValue() { } + public NullValue transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); + + private Builder(NullValue existing) { + this.sourceLocation = existing.getSourceLocation(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); + } private Builder() { } @@ -68,13 +113,28 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public NullValue build() { - NullValue nullValue = new NullValue(sourceLocation, comments); - return nullValue; + return new NullValue(sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/ObjectField.java b/src/main/java/graphql/language/ObjectField.java index a87d4e2eca..8c4532a41c 100644 --- a/src/main/java/graphql/language/ObjectField.java +++ b/src/main/java/graphql/language/ObjectField.java @@ -1,33 +1,46 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class ObjectField extends AbstractNode implements NamedNode { private final String name; private final Value value; + public static final String CHILD_VALUE = "value"; + @Internal - protected ObjectField(String name, Value value, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); - this.name = name; - this.value = value; + protected ObjectField(String name, Value value, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.name = assertNotNull(name); + this.value = assertNotNull(value); } /** * alternative to using a Builder for convenience + * + * @param name of the field + * @param value of the field */ public ObjectField(String name, Value value) { - this(name, value, null, new ArrayList<>()); + this(name, value, null, emptyList(), IgnoredChars.EMPTY, ImmutableKit.emptyMap()); } @Override @@ -41,25 +54,41 @@ public Value getValue() { @Override public List getChildren() { - List result = new ArrayList<>(); - result.add(value); - return result; + return ImmutableList.of(value); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_VALUE, value) + .build(); + } + + @Override + public ObjectField withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .value(newChildren.getChildOrNull(CHILD_VALUE)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } ObjectField that = (ObjectField) o; - return !(name != null ? !name.equals(that.name) : that.name != null); + return Objects.equals(name, that.name); } @Override public ObjectField deepCopy() { - return new ObjectField(name, deepCopy(this.value), getSourceLocation(), getComments()); + return new ObjectField(name, deepCopy(this.value), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -88,8 +117,10 @@ public ObjectField transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; private String name; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private Value value; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } @@ -97,9 +128,10 @@ private Builder() { private Builder(ObjectField existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.value = existing.getValue(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -114,7 +146,7 @@ public Builder name(String name) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -123,9 +155,24 @@ public Builder value(Value value) { return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public ObjectField build() { - ObjectField objectField = new ObjectField(name, value, sourceLocation, comments); - return objectField; + return new ObjectField(name, value, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/ObjectTypeDefinition.java b/src/main/java/graphql/language/ObjectTypeDefinition.java index bb12484dbd..fca017594e 100644 --- a/src/main/java/graphql/language/ObjectTypeDefinition.java +++ b/src/main/java/graphql/language/ObjectTypeDefinition.java @@ -1,55 +1,87 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class ObjectTypeDefinition extends AbstractNode implements TypeDefinition, DirectivesContainer { +public class ObjectTypeDefinition extends AbstractDescribedNode implements ImplementingTypeDefinition, DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List implementz; - private final List directives; - private final List fieldDefinitions; + private final ImmutableList implementz; + private final NodeUtil.DirectivesHolder directives; + private final ImmutableList fieldDefinitions; + + public static final String CHILD_IMPLEMENTZ = "implementz"; + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_FIELD_DEFINITIONS = "fieldDefinitions"; @Internal protected ObjectTypeDefinition(String name, - List implementz, - List directives, - List fieldDefinitions, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List implementz, + List directives, + List fieldDefinitions, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.implementz = implementz; - this.directives = directives; - this.fieldDefinitions = fieldDefinitions; - this.description = description; + this.implementz = ImmutableList.copyOf(implementz); + this.directives = NodeUtil.DirectivesHolder.of(directives); + this.fieldDefinitions = ImmutableList.copyOf(fieldDefinitions); } /** * alternative to using a Builder for convenience + * + * @param name of the object type */ public ObjectTypeDefinition(String name) { - this(name, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } + @Override public List getImplements() { - return new ArrayList<>(implementz); + return implementz; } - @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); + } + + @Override public List getFieldDefinitions() { return fieldDefinitions; } @@ -59,38 +91,56 @@ public String getName() { return name; } - public Description getDescription() { - return description; - } - @Override public List getChildren() { List result = new ArrayList<>(); result.addAll(implementz); - result.addAll(directives); + result.addAll(directives.getDirectives()); result.addAll(fieldDefinitions); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_IMPLEMENTZ, implementz) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .children(CHILD_FIELD_DEFINITIONS, fieldDefinitions) + .build(); + } + + @Override + public ObjectTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder.implementz(newChildren.getChildren(CHILD_IMPLEMENTZ)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .fieldDefinitions(newChildren.getChildren(CHILD_FIELD_DEFINITIONS))); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } ObjectTypeDefinition that = (ObjectTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + + return Objects.equals(this.name, that.name); } @Override public ObjectTypeDefinition deepCopy() { return new ObjectTypeDefinition(name, deepCopy(implementz), - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(fieldDefinitions), description, getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -118,26 +168,30 @@ public ObjectTypeDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List implementz = new ArrayList<>(); - private List directives = new ArrayList<>(); - private List fieldDefinitions = new ArrayList<>(); + private ImmutableList implementz = emptyList(); + private ImmutableList directives = emptyList(); + private ImmutableList fieldDefinitions = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(ObjectTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.implementz = existing.getImplements(); - this.fieldDefinitions = existing.getFieldDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.implementz = ImmutableList.copyOf(existing.getImplements()); + this.fieldDefinitions = ImmutableList.copyOf(existing.getFieldDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -146,7 +200,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -161,44 +215,61 @@ public Builder description(Description description) { } public Builder implementz(List implementz) { - this.implementz = implementz; + this.implementz = ImmutableList.copyOf(implementz); return this; } public Builder implementz(Type implement) { - this.implementz.add(implement); + this.implementz = ImmutableKit.addToList(implementz, implement); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } public Builder fieldDefinitions(List fieldDefinitions) { - this.fieldDefinitions = fieldDefinitions; + this.fieldDefinitions = ImmutableList.copyOf(fieldDefinitions); return this; } public Builder fieldDefinition(FieldDefinition fieldDefinition) { - this.fieldDefinitions.add(fieldDefinition); + this.fieldDefinitions = ImmutableKit.addToList(fieldDefinitions, fieldDefinition); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ObjectTypeDefinition build() { - ObjectTypeDefinition objectTypeDefinition = new ObjectTypeDefinition(name, + return new ObjectTypeDefinition(name, implementz, directives, fieldDefinitions, description, sourceLocation, - comments); - return objectTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/ObjectTypeExtensionDefinition.java b/src/main/java/graphql/language/ObjectTypeExtensionDefinition.java index 78a7026c94..575827564f 100644 --- a/src/main/java/graphql/language/ObjectTypeExtensionDefinition.java +++ b/src/main/java/graphql/language/ObjectTypeExtensionDefinition.java @@ -1,33 +1,44 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; + @PublicApi -public class ObjectTypeExtensionDefinition extends ObjectTypeDefinition { +public class ObjectTypeExtensionDefinition extends ObjectTypeDefinition implements SDLExtensionDefinition { @Internal protected ObjectTypeExtensionDefinition(String name, - List implementz, - List directives, - List fieldDefinitions, - Description description, - SourceLocation sourceLocation, - List comments) { + List implementz, + List directives, + List fieldDefinitions, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { super(name, implementz, directives, fieldDefinitions, - description, sourceLocation, comments); + description, sourceLocation, comments, ignoredChars, additionalData); } /** * alternative to using a Builder for convenience + * + * @param name of the object type extension */ public ObjectTypeExtensionDefinition(String name) { - this(name, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override @@ -38,10 +49,17 @@ public ObjectTypeExtensionDefinition deepCopy() { deepCopy(getFieldDefinitions()), getDescription(), getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } + @Override + public ObjectTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder.implementz(newChildren.getChildren(CHILD_IMPLEMENTZ)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .fieldDefinitions(newChildren.getChildren(CHILD_FIELD_DEFINITIONS))); + } @Override public String toString() { @@ -63,26 +81,30 @@ public ObjectTypeExtensionDefinition transformExtension(Consumer builde return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List implementz = new ArrayList<>(); - private List directives = new ArrayList<>(); - private List fieldDefinitions = new ArrayList<>(); + private ImmutableList implementz = emptyList(); + private ImmutableList directives = emptyList(); + private ImmutableList fieldDefinitions = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } - private Builder(ObjectTypeExtensionDefinition existing) { + private Builder(ObjectTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.implementz = existing.getImplements(); - this.fieldDefinitions = existing.getFieldDefinitions(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.implementz = ImmutableList.copyOf(existing.getImplements()); + this.fieldDefinitions = ImmutableList.copyOf(existing.getFieldDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -91,7 +113,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -106,44 +128,60 @@ public Builder description(Description description) { } public Builder implementz(List implementz) { - this.implementz = implementz; + this.implementz = ImmutableList.copyOf(implementz); return this; } - public Builder implementz(Type implementz) { - this.implementz.add(implementz); + public Builder implementz(Type implement) { + this.implementz = ImmutableKit.addToList(implementz, implement); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } public Builder fieldDefinitions(List fieldDefinitions) { - this.fieldDefinitions = fieldDefinitions; + this.fieldDefinitions = ImmutableList.copyOf(fieldDefinitions); return this; } public Builder fieldDefinition(FieldDefinition fieldDefinition) { - this.fieldDefinitions.add(fieldDefinition); + this.fieldDefinitions = ImmutableKit.addToList(fieldDefinitions, fieldDefinition); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ObjectTypeExtensionDefinition build() { - ObjectTypeExtensionDefinition objectTypeDefinition = new ObjectTypeExtensionDefinition(name, + return new ObjectTypeExtensionDefinition(name, implementz, directives, fieldDefinitions, description, sourceLocation, - comments); - return objectTypeDefinition; + comments, + ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/ObjectValue.java b/src/main/java/graphql/language/ObjectValue.java index 939ad98688..7a40d0a4c9 100644 --- a/src/main/java/graphql/language/ObjectValue.java +++ b/src/main/java/graphql/language/ObjectValue.java @@ -1,50 +1,79 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi +@NullMarked public class ObjectValue extends AbstractNode implements Value { - private final List objectFields = new ArrayList<>(); + private final ImmutableList objectFields; + + public static final String CHILD_OBJECT_FIELDS = "objectFields"; @Internal - protected ObjectValue(List objectFields, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); - this.objectFields.addAll(objectFields); + protected ObjectValue(List objectFields, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.objectFields = ImmutableList.copyOf(objectFields); } /** * alternative to using a Builder for convenience + * + * @param objectFields the list of field that make up this object value */ public ObjectValue(List objectFields) { - this(objectFields, null, new ArrayList<>()); + this(objectFields, null, emptyList(), IgnoredChars.EMPTY, ImmutableKit.emptyMap()); } public List getObjectFields() { - return new ArrayList<>(objectFields); + return objectFields; } @Override public List getChildren() { - List result = new ArrayList<>(); - result.addAll(objectFields); - return result; + return ImmutableList.copyOf(objectFields); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_OBJECT_FIELDS, objectFields) + .build(); + } - ObjectValue that = (ObjectValue) o; + @Override + public ObjectValue withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .objectFields(newChildren.getChildren(CHILD_OBJECT_FIELDS)) + ); + } + + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; @@ -52,7 +81,8 @@ public boolean isEqualTo(Node o) { @Override public ObjectValue deepCopy() { - return new ObjectValue(deepCopy(objectFields), getSourceLocation(), getComments()); + List copiedFields = assertNotNull(deepCopy(objectFields)); + return new ObjectValue(copiedFields, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @@ -79,18 +109,22 @@ public ObjectValue transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List objectFields = new ArrayList<>(); - private List comments = new ArrayList<>(); + private ImmutableList objectFields = emptyList(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(ObjectValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); - this.objectFields = existing.getObjectFields(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.objectFields = ImmutableList.copyOf(existing.getObjectFields()); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -99,23 +133,37 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder objectFields(List objectFields) { - this.objectFields = objectFields; + this.objectFields = ImmutableList.copyOf(objectFields); return this; } public Builder objectField(ObjectField objectField) { - this.objectFields.add(objectField); + this.objectFields = ImmutableKit.addToList(objectFields, objectField); return this; } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ObjectValue build() { - ObjectValue objectValue = new ObjectValue(objectFields, sourceLocation, comments); - return objectValue; + return new ObjectValue(objectFields, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/OperationDefinition.java b/src/main/java/graphql/language/OperationDefinition.java index 208bd7b243..824180bb49 100644 --- a/src/main/java/graphql/language/OperationDefinition.java +++ b/src/main/java/graphql/language/OperationDefinition.java @@ -1,17 +1,28 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.language.NodeUtil.DirectivesHolder; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class OperationDefinition extends AbstractNode implements Definition, SelectionSetContainer { +public class OperationDefinition extends AbstractNode implements Definition, SelectionSetContainer, DirectivesContainer, NamedNode { public enum Operation { QUERY, MUTATION, SUBSCRIPTION @@ -19,45 +30,69 @@ public enum Operation { private final String name; - private Operation operation; - private final List variableDefinitions; - private final List directives; - private SelectionSet selectionSet; + private final Operation operation; + private final ImmutableList variableDefinitions; + private final DirectivesHolder directives; + private final SelectionSet selectionSet; + + public static final String CHILD_VARIABLE_DEFINITIONS = "variableDefinitions"; + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_SELECTION_SET = "selectionSet"; @Internal protected OperationDefinition(String name, - Operation operation, - List variableDefinitions, - List directives, - SelectionSet selectionSet, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + Operation operation, + List variableDefinitions, + List directives, + SelectionSet selectionSet, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; this.operation = operation; - this.variableDefinitions = variableDefinitions; - this.directives = directives; + this.variableDefinitions = ImmutableList.copyOf(variableDefinitions); + this.directives = DirectivesHolder.of(directives); this.selectionSet = selectionSet; } public OperationDefinition(String name, Operation operation) { - this(name, operation, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, operation, emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public OperationDefinition(String name) { - this(name, null, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, null, emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override public List getChildren() { List result = new ArrayList<>(); result.addAll(variableDefinitions); - result.addAll(directives); + result.addAll(directives.getDirectives()); result.add(selectionSet); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_VARIABLE_DEFINITIONS, variableDefinitions) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .child(CHILD_SELECTION_SET, selectionSet) + .build(); + } + + @Override + public OperationDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .variableDefinitions(newChildren.getChildren(CHILD_VARIABLE_DEFINITIONS)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .selectionSet(newChildren.getChildOrNull(CHILD_SELECTION_SET)) + ); + } + public String getName() { return name; } @@ -71,15 +106,22 @@ public List getVariableDefinitions() { } public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } - public void setOperation(Operation operation) { - this.operation = operation; + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); } - public void setSelectionSet(SelectionSet selectionSet) { - this.selectionSet = selectionSet; + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } @Override @@ -89,12 +131,16 @@ public SelectionSet getSelectionSet() { @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } OperationDefinition that = (OperationDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name) && operation == that.operation; + return Objects.equals(this.name, that.name) && operation == that.operation; } @@ -103,11 +149,12 @@ public OperationDefinition deepCopy() { return new OperationDefinition(name, operation, deepCopy(variableDefinitions), - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(selectionSet), getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -136,26 +183,30 @@ public OperationDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Operation operation; - private List variableDefinitions = new ArrayList<>(); - private List directives = new ArrayList<>(); + private ImmutableList variableDefinitions = emptyList(); + private ImmutableList directives = emptyList(); private SelectionSet selectionSet; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(OperationDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.operation = existing.getOperation(); - this.variableDefinitions = existing.getVariableDefinitions(); - this.directives = existing.getDirectives(); + this.variableDefinitions = ImmutableList.copyOf(existing.getVariableDefinitions()); + this.directives = ImmutableList.copyOf(existing.getDirectives()); this.selectionSet = existing.getSelectionSet(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -165,7 +216,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -180,12 +231,23 @@ public Builder operation(Operation operation) { } public Builder variableDefinitions(List variableDefinitions) { - this.variableDefinitions = variableDefinitions; + this.variableDefinitions = ImmutableList.copyOf(variableDefinitions); + return this; + } + + public Builder variableDefinition(VariableDefinition variableDefinition) { + this.variableDefinitions = ImmutableKit.addToList(variableDefinitions, variableDefinition); return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); return this; } @@ -194,17 +256,32 @@ public Builder selectionSet(SelectionSet selectionSet) { return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + public OperationDefinition build() { - OperationDefinition operationDefinition = new OperationDefinition( + return new OperationDefinition( name, operation, variableDefinitions, directives, selectionSet, sourceLocation, - comments - ); - return operationDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/OperationTypeDefinition.java b/src/main/java/graphql/language/OperationTypeDefinition.java index 5dce6ca3b5..5041e692cf 100644 --- a/src/main/java/graphql/language/OperationTypeDefinition.java +++ b/src/main/java/graphql/language/OperationTypeDefinition.java @@ -1,37 +1,51 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class OperationTypeDefinition extends AbstractNode implements NamedNode { private final String name; - private final Type type; + private final TypeName typeName; + + public static final String CHILD_TYPE_NAME = "typeName"; @Internal - protected OperationTypeDefinition(String name, Type type, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected OperationTypeDefinition(String name, TypeName typeName, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; - this.type = type; + this.typeName = typeName; } /** * alternative to using a Builder for convenience + * + * @param name of the operation + * @param typeName the type in play */ - public OperationTypeDefinition(String name, Type type) { - this(name, type, null, new ArrayList<>()); + public OperationTypeDefinition(String name, TypeName typeName) { + this(name, typeName, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } - public Type getType() { - return type; + public TypeName getTypeName() { + return typeName; } @Override @@ -42,30 +56,48 @@ public String getName() { @Override public List getChildren() { List result = new ArrayList<>(); - result.add(type); + result.add(typeName); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE_NAME, typeName) + .build(); + } + + @Override + public OperationTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .typeName(newChildren.getChildOrNull(CHILD_TYPE_NAME)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } OperationTypeDefinition that = (OperationTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public OperationTypeDefinition deepCopy() { - return new OperationTypeDefinition(name, deepCopy(type), getSourceLocation(), getComments()); + return new OperationTypeDefinition(name, deepCopy(typeName), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override public String toString() { return "OperationTypeDefinition{" + "name='" + name + "'" + - ", type=" + type + + ", typeName=" + typeName + "}"; } @@ -86,9 +118,11 @@ public OperationTypeDefinition transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; - private Type type; + private TypeName typeName; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } @@ -96,9 +130,11 @@ private Builder() { private Builder(OperationTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); - this.type = existing.getType(); + this.typeName = existing.getTypeName(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -108,7 +144,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -117,14 +153,29 @@ public Builder name(String name) { return this; } - public Builder type(Type type) { - this.type = type; + public Builder typeName(TypeName type) { + this.typeName = type; return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public OperationTypeDefinition build() { - OperationTypeDefinition operationTypeDefinition = new OperationTypeDefinition(name, type, sourceLocation, comments); - return operationTypeDefinition; + return new OperationTypeDefinition(name, typeName, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/PrettyAstPrinter.java b/src/main/java/graphql/language/PrettyAstPrinter.java new file mode 100644 index 0000000000..a5fc4628b1 --- /dev/null +++ b/src/main/java/graphql/language/PrettyAstPrinter.java @@ -0,0 +1,451 @@ +package graphql.language; + +import graphql.ExperimentalApi; +import graphql.collect.ImmutableKit; +import graphql.parser.CommentParser; +import graphql.parser.NodeToRuleCapturingParser; +import graphql.parser.ParserEnvironment; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.StringJoiner; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static graphql.Assert.assertTrue; +import static graphql.parser.ParserEnvironment.newParserEnvironment; + +/** + * A printer that acts as a code formatter. + * + * This printer will preserve pretty much all elements from the source text, even those that are not part of the AST + * (and are thus discarded by the {@link AstPrinter}), like comments. + * + * @see AstPrinter + */ +@ExperimentalApi +public class PrettyAstPrinter extends AstPrinter { + private final CommentParser commentParser; + private final PrettyPrinterOptions options; + + public PrettyAstPrinter(NodeToRuleCapturingParser.ParserContext parserContext) { + this(parserContext, PrettyPrinterOptions.defaultOptions); + } + + public PrettyAstPrinter(NodeToRuleCapturingParser.ParserContext parserContext, PrettyPrinterOptions options) { + super(false); + this.commentParser = new CommentParser(parserContext); + this.options = options; + + this.replacePrinter(DirectiveDefinition.class, directiveDefinition()); + this.replacePrinter(Document.class, document()); + this.replacePrinter(EnumTypeDefinition.class, enumTypeDefinition("enum")); + this.replacePrinter(EnumTypeExtensionDefinition.class, enumTypeDefinition("extend enum")); + this.replacePrinter(EnumValueDefinition.class, enumValueDefinition()); + this.replacePrinter(FieldDefinition.class, fieldDefinition()); + this.replacePrinter(InputObjectTypeDefinition.class, inputObjectTypeDefinition("input")); + this.replacePrinter(InputObjectTypeExtensionDefinition.class, inputObjectTypeDefinition("extend input")); + this.replacePrinter(InputValueDefinition.class, inputValueDefinition()); + this.replacePrinter(InterfaceTypeDefinition.class, implementingTypeDefinition("interface")); + this.replacePrinter(InterfaceTypeExtensionDefinition.class, implementingTypeDefinition("extend interface")); + this.replacePrinter(ObjectTypeDefinition.class, implementingTypeDefinition("type")); + this.replacePrinter(ObjectTypeExtensionDefinition.class, implementingTypeDefinition("extend type")); + this.replacePrinter(ScalarTypeDefinition.class, scalarTypeDefinition("scalar")); + this.replacePrinter(ScalarTypeExtensionDefinition.class, scalarTypeDefinition("extend scalar")); + this.replacePrinter(UnionTypeDefinition.class, unionTypeDefinition("union")); + this.replacePrinter(UnionTypeExtensionDefinition.class, unionTypeDefinition("extend union")); + } + + public String print(Node node) { + StringBuilder builder = new StringBuilder(); + + NodePrinter nodePrinter = this._findPrinter(node); + nodePrinter.print(builder, node); + + return builder.toString(); + } + + public static String print(String schemaDefinition, PrettyPrinterOptions options) { + NodeToRuleCapturingParser parser = new NodeToRuleCapturingParser(); + ParserEnvironment parserEnvironment = newParserEnvironment().document(schemaDefinition).build(); + Document document = parser.parseDocument(parserEnvironment); + + return new PrettyAstPrinter(parser.getParserContext(), options).print(document); + } + + private NodePrinter document() { + return (out, node) -> { + String firstLineComment = commentParser.getCommentOnFirstLineOfDocument(node) + .map(this::comment) + .map(append("\n")) + .orElse(""); + + out.append(firstLineComment); + out.append(join(node.getDefinitions(), "\n\n")).append("\n"); + + String endComments = comments(commentParser.getCommentsAfterAllDefinitions(node), "\n"); + + out.append(endComments); + }; + } + + private NodePrinter directiveDefinition() { + return (out, node) -> { + out.append(outset(node)); + String locations = join(node.getDirectiveLocations(), " | "); + String repeatable = node.isRepeatable() ? "repeatable " : ""; + out.append("directive @") + .append(node.getName()) + .append(block(node.getInputValueDefinitions(), node, "(", ")", "\n", ", ", "")) + .append(" ") + .append(repeatable) + .append("on ") + .append(locations); + }; + } + + private NodePrinter enumTypeDefinition(String nodeName) { + return (out, node) -> { + out.append(outset(node)); + out.append(spaced( + nodeName, + node.getName(), + directives(node.getDirectives()), + block(node.getEnumValueDefinitions(), node, "{", "}", "\n", null, null) + )); + }; + } + + private NodePrinter enumValueDefinition() { + return (out, node) -> { + out.append(outset(node)); + out.append(spaced( + node.getName(), + directives(node.getDirectives()) + )); + }; + } + + private NodePrinter fieldDefinition() { + return (out, node) -> { + out.append(outset(node)); + out.append(node.getName()) + .append(block(node.getInputValueDefinitions(), node, "(", ")", "\n", ", ", "")) + .append(": ") + .append(spaced( + type(node.getType()), + directives(node.getDirectives()) + )); + }; + } + + private String type(Type type) { + if (type instanceof NonNullType) { + NonNullType inner = (NonNullType) type; + return wrap("", type(inner.getType()), "!"); + } else if (type instanceof ListType) { + ListType inner = (ListType) type; + return wrap("[", type(inner.getType()), "]"); + } else { + TypeName inner = (TypeName) type; + return inner.getName(); + } + } + + private NodePrinter inputObjectTypeDefinition(String nodeName) { + return (out, node) -> { + out.append(outset(node)); + out.append(spaced( + nodeName, + node.getName(), + directives(node.getDirectives()), + block(node.getInputValueDefinitions(), node, "{", "}", "\n", null, null) + )); + }; + } + + private NodePrinter inputValueDefinition() { + String nameTypeSep = ": "; + String defaultValueEquals = "= "; + return (out, node) -> { + Value defaultValue = node.getDefaultValue(); + out.append(outset(node)); + out.append(spaced( + node.getName() + nameTypeSep + type(node.getType()), + wrap(defaultValueEquals, defaultValue, ""), + directives(node.getDirectives()) + )); + }; + } + + + private > NodePrinter implementingTypeDefinition(String nodeName) { + return (out, node) -> { + out.append(outset(node)); + out.append(spaced( + nodeName, + node.getName(), + wrap("implements ", block(node.getImplements(), node, "", "", " &\n", " & ", ""), ""), + directives(node.getDirectives()), + block(node.getFieldDefinitions(), node, "{", "}", "\n", null, null) + )); + }; + } + + private NodePrinter scalarTypeDefinition(String nodeName) { + return (out, node) -> { + out.append(outset(node)); + out.append(spaced( + nodeName, + node.getName(), + directives(node.getDirectives()))); + }; + } + + private NodePrinter unionTypeDefinition(String nodeName) { + String barSep = " | "; + String equals = "= "; + return (out, node) -> { + out.append(outset(node)); + out.append(spaced( + nodeName, + node.getName(), + directives(node.getDirectives()), + equals + join(node.getMemberTypes(), barSep) + )); + }; + } + + private String node(Node node, Class startClass) { + if (startClass != null) { + assertTrue(startClass.isInstance(node), "The starting class must be in the inherit tree"); + } + StringBuilder builder = new StringBuilder(); + + String comments = comments(commentParser.getLeadingComments(node), "\n"); + builder.append(comments); + + NodePrinter printer = _findPrinter(node, startClass); + printer.print(builder, node); + + commentParser.getTrailingComment(node) + .map(this::comment) + .map(prepend(" ")) + .ifPresent(builder::append); + + return builder.toString(); + } + + private boolean isEmpty(List list) { + return list == null || list.isEmpty(); + } + + private boolean isEmpty(String s) { + return s == null || s.isBlank(); + } + + private List nvl(List list) { + return list != null ? list : ImmutableKit.emptyList(); + } + + // Description and comments positioned before the node + private String outset(Node node) { + String description = description(node); + String commentsAfter = comments(commentParser.getCommentsAfterDescription(node), "\n"); + + return description + commentsAfter; + } + + private String description(Node node) { + Description description = ((AbstractDescribedNode) node).getDescription(); + if (description == null || description.getContent() == null) { + return ""; + } + String s; + boolean startNewLine = description.getContent().length() > 0 && description.getContent().charAt(0) == '\n'; + if (description.isMultiLine()) { + s = "\"\"\"" + (startNewLine ? "" : "\n") + description.getContent() + "\n\"\"\"\n"; + } else { + s = "\"" + description.getContent() + "\"\n"; + } + return s; + } + + private String comment(Comment comment) { + return comments(Collections.singletonList(comment)); + } + + private String comments(List comments) { + return comments(comments, ""); + } + + private String comments(List comments, String suffix) { + return comments(comments, "", suffix); + } + + private String comments(List comments, String prefix, String suffix) { + if (comments.isEmpty()) { + return ""; + } + + return comments.stream() + .map(Comment::getContent) + .map(content -> "#" + content) + .collect(Collectors.joining("\n", prefix, suffix)); + } + + private String directives(List directives) { + return join(nvl(directives), " "); + } + + private String join(List nodes, String delim) { + return join(nodes, delim, "", ""); + } + + private String join(List nodes, String delim, String prefix, String suffix) { + StringJoiner joiner = new StringJoiner(delim, prefix, suffix); + + for (T node : nodes) { + joiner.add(node(node)); + } + + return joiner.toString(); + } + + private String node(Node node) { + return node(node, null); + } + + private String spaced(String... args) { + return join(" ", args); + } + + private Function prepend(String prefix) { + return text -> prefix + text; + } + + private Function append(String suffix) { + return text -> text + suffix; + } + + private String join(String delim, String... args) { + StringJoiner joiner = new StringJoiner(delim); + + for (final String arg : args) { + if (!isEmpty(arg)) { + joiner.add(arg); + } + } + + return joiner.toString(); + } + + private String block(List nodes, Node parentNode, String prefix, String suffix, String separatorMultiline, String separatorSingleLine, String whenEmpty) { + if (isEmpty(nodes)) { + return whenEmpty != null ? whenEmpty : prefix + suffix; + } + + boolean hasDescriptions = nodes.stream() + .filter(node -> node instanceof AbstractDescribedNode) + .map(node -> (AbstractDescribedNode) node) + .map(AbstractDescribedNode::getDescription) + .anyMatch(Objects::nonNull); + + boolean hasTrailingComments = nodes.stream() + .map(commentParser::getTrailingComment) + .anyMatch(Optional::isPresent); + + boolean hasLeadingComments = nodes.stream() + .mapToLong(node -> commentParser.getLeadingComments(node).size()) + .sum() > 0; + + boolean isMultiline = hasDescriptions || hasTrailingComments || hasLeadingComments || separatorSingleLine == null; + + String appliedSeparator = isMultiline ? separatorMultiline : separatorSingleLine; + + String blockStart = commentParser.getBeginningOfBlockComment(parentNode, prefix) + .map(this::comment) + .map(commentText -> prefix + " " + commentText + "\n") + .orElseGet(() -> prefix + (isMultiline ? "\n" : "")); + + String blockEndComments = comments(commentParser.getEndOfBlockComments(parentNode, suffix), "\n", ""); + String blockEnd = (isMultiline ? "\n" : "") + suffix; + + String content = nodes.stream().map(this::node).collect(Collectors.joining(appliedSeparator)); + String possiblyIndentedContent = isMultiline ? indent(content + blockEndComments) : content + blockEndComments; + + return blockStart + possiblyIndentedContent + blockEnd; + } + + private String indent(String text) { + return indent(new StringBuilder(text)).toString(); + } + + private StringBuilder indent(StringBuilder stringBuilder) { + final String indentText = options.indentText; + + for (int i = 0; i < stringBuilder.length(); i++) { + char c = stringBuilder.charAt(i); + if (i == 0) { + stringBuilder.replace(i, i, indentText); + i += 2; + } + if (c == '\n') { + stringBuilder.replace(i, i + 1, "\n" + indentText); + i += 3; + } + } + return stringBuilder; + } + + /** + * Contains options that modify how a document is printed. + */ + public static class PrettyPrinterOptions { + private final String indentText; + private static final PrettyPrinterOptions defaultOptions = new PrettyPrinterOptions(IndentType.SPACE, 2); + + private PrettyPrinterOptions(IndentType indentType, int indentWidth) { + this.indentText = String.join("", Collections.nCopies(indentWidth, indentType.character)); + } + + public static PrettyPrinterOptions defaultOptions() { + return defaultOptions; + } + + public static Builder builder() { + return new Builder(); + } + + public enum IndentType { + TAB("\t"), SPACE(" "); + + private final String character; + + IndentType(String character) { + this.character = character; + } + } + + public static class Builder { + private IndentType indentType; + private int indentWidth = 1; + + public Builder indentType(IndentType indentType) { + this.indentType = indentType; + return this; + } + + public Builder indentWith(int indentWidth) { + this.indentWidth = indentWidth; + return this; + } + + public PrettyPrinterOptions build() { + return new PrettyPrinterOptions(indentType, indentWidth); + } + } + } +} diff --git a/src/main/java/graphql/language/SDLDefinition.java b/src/main/java/graphql/language/SDLDefinition.java index 668dc93da2..7b07a24919 100644 --- a/src/main/java/graphql/language/SDLDefinition.java +++ b/src/main/java/graphql/language/SDLDefinition.java @@ -4,9 +4,9 @@ import graphql.PublicApi; /** - * All Schema Definition Language (SDL) Definitions. + * An interface for Schema Definition Language (SDL) definitions. * - * @param + * @param the actual Node type */ @PublicApi public interface SDLDefinition extends Definition { diff --git a/src/main/java/graphql/language/SDLExtensionDefinition.java b/src/main/java/graphql/language/SDLExtensionDefinition.java new file mode 100644 index 0000000000..2b71cd46ab --- /dev/null +++ b/src/main/java/graphql/language/SDLExtensionDefinition.java @@ -0,0 +1,12 @@ +package graphql.language; + + +import graphql.PublicApi; + +/** + * A marker interface for Schema Definition Language (SDL) extension definitions. + */ +@PublicApi +public interface SDLExtensionDefinition { + +} diff --git a/src/main/java/graphql/language/SDLNamedDefinition.java b/src/main/java/graphql/language/SDLNamedDefinition.java new file mode 100644 index 0000000000..44b4bf85a6 --- /dev/null +++ b/src/main/java/graphql/language/SDLNamedDefinition.java @@ -0,0 +1,18 @@ +package graphql.language; + + +import graphql.PublicApi; + +/** + * A interface for named Schema Definition Language (SDL) definition. + * + * @param the actual Node type + */ +@PublicApi +public interface SDLNamedDefinition extends SDLDefinition { + + /** + * @return The name of this SDL definition + */ + String getName(); +} diff --git a/src/main/java/graphql/language/ScalarTypeDefinition.java b/src/main/java/graphql/language/ScalarTypeDefinition.java index 5e14bd1771..3374b69dab 100644 --- a/src/main/java/graphql/language/ScalarTypeDefinition.java +++ b/src/main/java/graphql/language/ScalarTypeDefinition.java @@ -1,40 +1,72 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class ScalarTypeDefinition extends AbstractNode implements TypeDefinition, DirectivesContainer { +public class ScalarTypeDefinition extends AbstractDescribedNode implements TypeDefinition, DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List directives; + private final NodeUtil.DirectivesHolder directives; + + public static final String CHILD_DIRECTIVES = "directives"; @Internal - protected ScalarTypeDefinition(String name, List directives, Description description, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected ScalarTypeDefinition(String name, + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.directives = directives; - this.description = description; + this.directives = NodeUtil.DirectivesHolder.of(directives); } /** * alternative to using a Builder for convenience + * + * @param name of the scalar */ public ScalarTypeDefinition(String name) { - this(name, new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } @Override @@ -42,31 +74,42 @@ public String getName() { return name; } + @Override + public List getChildren() { + return ImmutableList.copyOf(directives.getDirectives()); + } - public Description getDescription() { - return description; + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); } @Override - public List getChildren() { - List result = new ArrayList<>(); - result.addAll(directives); - return result; + public ScalarTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } ScalarTypeDefinition that = (ScalarTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public ScalarTypeDefinition deepCopy() { - return new ScalarTypeDefinition(name, deepCopy(directives), description, getSourceLocation(), getComments()); + return new ScalarTypeDefinition(name, deepCopy(directives.getDirectives()), description, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -92,22 +135,26 @@ public ScalarTypeDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(ScalarTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -117,7 +164,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -131,23 +178,39 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ScalarTypeDefinition build() { - ScalarTypeDefinition scalarTypeDefinition = new ScalarTypeDefinition(name, + return new ScalarTypeDefinition(name, directives, description, sourceLocation, - comments); - return scalarTypeDefinition; + comments, + ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/ScalarTypeExtensionDefinition.java b/src/main/java/graphql/language/ScalarTypeExtensionDefinition.java index 3f376f8428..0feb48451b 100644 --- a/src/main/java/graphql/language/ScalarTypeExtensionDefinition.java +++ b/src/main/java/graphql/language/ScalarTypeExtensionDefinition.java @@ -1,27 +1,34 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + @PublicApi -public class ScalarTypeExtensionDefinition extends ScalarTypeDefinition { +public class ScalarTypeExtensionDefinition extends ScalarTypeDefinition implements SDLExtensionDefinition { @Internal protected ScalarTypeExtensionDefinition(String name, - List directives, - Description description, - SourceLocation sourceLocation, - List comments) { - super(name, directives, description, sourceLocation, comments); + List directives, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, Map additionalData) { + super(name, directives, description, sourceLocation, comments, ignoredChars, additionalData); } @Override public ScalarTypeExtensionDefinition deepCopy() { - return new ScalarTypeExtensionDefinition(getName(), deepCopy(getDirectives()), getDescription(), getSourceLocation(), getComments()); + return new ScalarTypeExtensionDefinition(getName(), deepCopy(getDirectives()), getDescription(), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -37,29 +44,39 @@ public static Builder newScalarTypeExtensionDefinition() { return new Builder(); } + @Override + public ScalarTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + public ScalarTypeExtensionDefinition transformExtension(Consumer builderConsumer) { Builder builder = new Builder(this); builderConsumer.accept(builder); return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } - - private Builder(ScalarTypeExtensionDefinition existing) { + private Builder(ScalarTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -69,7 +86,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -83,18 +100,40 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public ScalarTypeExtensionDefinition build() { - ScalarTypeExtensionDefinition scalarTypeDefinition = new ScalarTypeExtensionDefinition(name, + return new ScalarTypeExtensionDefinition(name, directives, description, sourceLocation, - comments); - return scalarTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/ScalarValue.java b/src/main/java/graphql/language/ScalarValue.java index 7ddacb168f..25166972aa 100644 --- a/src/main/java/graphql/language/ScalarValue.java +++ b/src/main/java/graphql/language/ScalarValue.java @@ -1,7 +1,9 @@ package graphql.language; import graphql.PublicApi; +import org.jspecify.annotations.NullMarked; @PublicApi +@NullMarked public interface ScalarValue extends Value { } diff --git a/src/main/java/graphql/language/SchemaDefinition.java b/src/main/java/graphql/language/SchemaDefinition.java index f4840c275d..931ef33c41 100644 --- a/src/main/java/graphql/language/SchemaDefinition.java +++ b/src/main/java/graphql/language/SchemaDefinition.java @@ -1,72 +1,110 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.FpKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; -import static graphql.language.NodeUtil.directivesByName; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; @PublicApi -public class SchemaDefinition extends AbstractNode implements SDLDefinition { +public class SchemaDefinition extends AbstractDescribedNode implements SDLDefinition, DirectivesContainer { + + private final NodeUtil.DirectivesHolder directives; + private final ImmutableList operationTypeDefinitions; + + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_OPERATION_TYPE_DEFINITIONS = "operationTypeDefinitions"; - private final List directives; - private final List operationTypeDefinitions; @Internal protected SchemaDefinition(List directives, - List operationTypeDefinitions, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); - this.directives = directives; - this.operationTypeDefinitions = operationTypeDefinitions; + List operationTypeDefinitions, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData, + Description description) { + super(sourceLocation, comments, ignoredChars, additionalData, description); + this.directives = NodeUtil.DirectivesHolder.of(directives); + this.operationTypeDefinitions = ImmutableList.copyOf(operationTypeDefinitions); } + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); } - public Map getDirectivesByName() { - return directivesByName(directives); + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); } - public Directive getDirective(String directiveName) { - return getDirectivesByName().get(directiveName); + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); } + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); + } public List getOperationTypeDefinitions() { return operationTypeDefinitions; } + public Description getDescription() { + return description; + } + @Override public List getChildren() { - List result = new ArrayList<>(); - result.addAll(directives); - result.addAll(operationTypeDefinitions); - return result; + return FpKit.concat(directives.getDirectives(), operationTypeDefinitions); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .children(CHILD_OPERATION_TYPE_DEFINITIONS, operationTypeDefinitions) + .build(); + } - SchemaDefinition that = (SchemaDefinition) o; + @Override + public SchemaDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .operationTypeDefinitions(newChildren.getChildren(CHILD_OPERATION_TYPE_DEFINITIONS)) + ); + } + @Override + public boolean isEqualTo(Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } return true; } @Override public SchemaDefinition deepCopy() { - return new SchemaDefinition(deepCopy(directives), deepCopy(operationTypeDefinitions), getSourceLocation(), getComments()); + return new SchemaDefinition(deepCopy(directives.getDirectives()), deepCopy(operationTypeDefinitions), getSourceLocation(), getComments(), + getIgnoredChars(), getAdditionalData(), description); } @Override @@ -94,20 +132,31 @@ public static Builder newSchemaDefinition() { public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); - private List directives = new ArrayList<>(); - private List operationTypeDefinitions = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private ImmutableList directives = emptyList(); + private ImmutableList operationTypeDefinitions = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); + private Description description; - private Builder() { + + protected Builder() { } - private Builder(SchemaDefinition existing) { + protected Builder(SchemaDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); - this.directives = existing.getDirectives(); - this.operationTypeDefinitions = existing.getOperationTypeDefinitions(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.operationTypeDefinitions = ImmutableList.copyOf(existing.getOperationTypeDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); + this.description = existing.getDescription(); } + public Builder description(Description description) { + this.description = description; + return this; + } public Builder sourceLocation(SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; @@ -115,36 +164,53 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } public Builder operationTypeDefinitions(List operationTypeDefinitions) { - this.operationTypeDefinitions = operationTypeDefinitions; + this.operationTypeDefinitions = ImmutableList.copyOf(operationTypeDefinitions); + return this; + } + + public Builder operationTypeDefinition(OperationTypeDefinition operationTypeDefinition) { + this.operationTypeDefinitions = ImmutableKit.addToList(operationTypeDefinitions, operationTypeDefinition); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); return this; } - public Builder operationTypeDefinition(OperationTypeDefinition operationTypeDefinitions) { - this.operationTypeDefinitions.add(operationTypeDefinitions); + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public SchemaDefinition build() { - SchemaDefinition schemaDefinition = new SchemaDefinition(directives, + return new SchemaDefinition(directives, operationTypeDefinitions, sourceLocation, - comments); - return schemaDefinition; + comments, + ignoredChars, + additionalData, + description); } } } diff --git a/src/main/java/graphql/language/SchemaExtensionDefinition.java b/src/main/java/graphql/language/SchemaExtensionDefinition.java new file mode 100644 index 0000000000..43927f5b92 --- /dev/null +++ b/src/main/java/graphql/language/SchemaExtensionDefinition.java @@ -0,0 +1,137 @@ +package graphql.language; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + +@PublicApi +public class SchemaExtensionDefinition extends SchemaDefinition implements SDLExtensionDefinition { + + protected SchemaExtensionDefinition(List directives, + List operationTypeDefinitions, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(directives, operationTypeDefinitions, sourceLocation, comments, ignoredChars, additionalData, null); + } + + @Override + public SchemaExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .operationTypeDefinitions(newChildren.getChildren(CHILD_OPERATION_TYPE_DEFINITIONS)) + ); + } + + @Override + public SchemaExtensionDefinition deepCopy() { + return new SchemaExtensionDefinition(deepCopy(getDirectives()), deepCopy(getOperationTypeDefinitions()), getSourceLocation(), getComments(), + getIgnoredChars(), getAdditionalData()); + } + + @Override + public String toString() { + return "SchemaExtensionDefinition{" + + "directives=" + getDirectives() + + ", operationTypeDefinitions=" + getOperationTypeDefinitions() + + "}"; + } + + public SchemaExtensionDefinition transformExtension(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newSchemaExtensionDefinition() { + return new Builder(); + } + + public static final class Builder implements NodeDirectivesBuilder { + private SourceLocation sourceLocation; + private ImmutableList comments = emptyList(); + private ImmutableList directives = emptyList(); + private ImmutableList operationTypeDefinitions = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); + + + protected Builder() { + } + + protected Builder(SchemaDefinition existing) { + this.sourceLocation = existing.getSourceLocation(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.operationTypeDefinitions = ImmutableList.copyOf(existing.getOperationTypeDefinitions()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); + } + + + public Builder sourceLocation(SourceLocation sourceLocation) { + this.sourceLocation = sourceLocation; + return this; + } + + public Builder comments(List comments) { + this.comments = ImmutableList.copyOf(comments); + return this; + } + + @Override + public Builder directives(List directives) { + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder operationTypeDefinitions(List operationTypeDefinitions) { + this.operationTypeDefinitions = ImmutableList.copyOf(operationTypeDefinitions); + return this; + } + + public Builder operationTypeDefinition(OperationTypeDefinition operationTypeDefinition) { + this.operationTypeDefinitions = ImmutableKit.addToList(operationTypeDefinitions, operationTypeDefinition); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public SchemaExtensionDefinition build() { + return new SchemaExtensionDefinition(directives, + operationTypeDefinitions, + sourceLocation, + comments, + ignoredChars, + additionalData); + } + } + +} diff --git a/src/main/java/graphql/language/Selection.java b/src/main/java/graphql/language/Selection.java index c88557806c..7160ccfafe 100644 --- a/src/main/java/graphql/language/Selection.java +++ b/src/main/java/graphql/language/Selection.java @@ -4,5 +4,5 @@ import graphql.PublicApi; @PublicApi -public interface Selection extends Node { +public interface Selection> extends Node { } diff --git a/src/main/java/graphql/language/SelectionSet.java b/src/main/java/graphql/language/SelectionSet.java index 8b176b606e..8e85bdcdef 100644 --- a/src/main/java/graphql/language/SelectionSet.java +++ b/src/main/java/graphql/language/SelectionSet.java @@ -1,59 +1,98 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi public class SelectionSet extends AbstractNode { - private final List selections = new ArrayList<>(); + private final ImmutableList selections; + + public static final String CHILD_SELECTIONS = "selections"; @Internal - protected SelectionSet(List selections, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); - this.selections.addAll(selections); + protected SelectionSet(Collection selections, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); + this.selections = ImmutableList.copyOf(selections); } /** * alternative to using a Builder for convenience + * + * @param selections the list of selection in this selection set */ - public SelectionSet(List selections) { - this(selections, null, new ArrayList<>()); + public SelectionSet(Collection selections) { + this(selections, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } public List getSelections() { return selections; } + /** + * Returns a list of selections of the specific type. It uses {@link java.lang.Class#isAssignableFrom(Class)} for the test + * + * @param selectionClass the selection class + * @param the type of selection + * + * @return a list of selections of that class or empty list + */ + public List getSelectionsOfType(Class selectionClass) { + return ImmutableKit.filterAndMap(selections, + d -> selectionClass.isAssignableFrom(d.getClass()), + selectionClass::cast); + } @Override public List getChildren() { - List result = new ArrayList<>(); - result.addAll(selections); - return result; + return ImmutableList.copyOf(selections); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_SELECTIONS, selections) + .build(); + } - SelectionSet that = (SelectionSet) o; + @Override + public SelectionSet withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .selections(newChildren.getChildren(CHILD_SELECTIONS)) + ); + } - return true; + @Override + public boolean isEqualTo(Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return true; } @Override public SelectionSet deepCopy() { - return new SelectionSet(deepCopy(selections), getSourceLocation(), getComments()); + return new SelectionSet(deepCopy(selections), getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -72,7 +111,7 @@ public static Builder newSelectionSet() { return new Builder(); } - public static Builder newSelectionSet(List selections) { + public static Builder newSelectionSet(Collection selections) { return new Builder().selections(selections); } @@ -84,21 +123,30 @@ public SelectionSet transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { - private List selections = new ArrayList<>(); + private ImmutableList selections = emptyList(); private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(SelectionSet existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); - this.selections = existing.getSelections(); + this.comments = ImmutableList.copyOf(existing.getComments()); + this.selections = ImmutableList.copyOf(existing.getSelections()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); + } + + public Builder selections(Collection selections) { + this.selections = ImmutableList.copyOf(selections); + return this; } - public Builder selections(List selections) { - this.selections = selections; + public Builder selection(Selection selection) { + this.selections = ImmutableKit.addToList(selections, selection); return this; } @@ -108,13 +156,27 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public SelectionSet build() { - SelectionSet selectionSet = new SelectionSet(selections, sourceLocation, comments); - return selectionSet; + return new SelectionSet(selections, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/SourceLocation.java b/src/main/java/graphql/language/SourceLocation.java index a8c09f46c0..a4ae90a039 100644 --- a/src/main/java/graphql/language/SourceLocation.java +++ b/src/main/java/graphql/language/SourceLocation.java @@ -2,12 +2,20 @@ import graphql.PublicApi; +import graphql.schema.GraphQLModifiedType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.idl.SchemaGenerator; import java.io.Serializable; +import java.util.Objects; @PublicApi public class SourceLocation implements Serializable { + public static final SourceLocation EMPTY = new SourceLocation(-1, -1); + private final int line; private final int column; private final String sourceName; @@ -36,21 +44,30 @@ public String getSourceName() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } SourceLocation that = (SourceLocation) o; - if (line != that.line) return false; - if (column != that.column) return false; - return sourceName != null ? sourceName.equals(that.sourceName) : that.sourceName == null; + if (line != that.line) { + return false; + } + if (column != that.column) { + return false; + } + return Objects.equals(sourceName, that.sourceName); } @Override public int hashCode() { - int result = line; - result = 31 * result + column; - result = 31 * result + (sourceName != null ? sourceName.hashCode() : 0); + int result = 1; + result = 31 * result + Integer.hashCode(line); + result = 31 * result + Integer.hashCode(column); + result = 31 * result + Objects.hashCode(sourceName); return result; } @@ -62,4 +79,27 @@ public String toString() { (sourceName != null ? ", sourceName=" + sourceName : "") + '}'; } + + + /** + * This method can return {@link SourceLocation} that help create the given schema element. If the + * schema is created from input files and {@link SchemaGenerator.Options#isCaptureAstDefinitions()} + * is set to true then schema elements contain a reference to the {@link SourceLocation} that helped + * create that runtime schema element. + * + * @param schemaElement the schema element + * + * @return the source location if available or null if it's not. + */ + public static SourceLocation getLocation(GraphQLSchemaElement schemaElement) { + if (schemaElement instanceof GraphQLModifiedType) { + schemaElement = GraphQLTypeUtil.unwrapAllAs((GraphQLModifiedType) schemaElement); + } + if (schemaElement instanceof GraphQLNamedSchemaElement) { + Node node = ((GraphQLNamedSchemaElement) schemaElement).getDefinition(); + return node != null ? node.getSourceLocation() : null; + } + return null; + } + } diff --git a/src/main/java/graphql/language/StringValue.java b/src/main/java/graphql/language/StringValue.java index c9fc9cbf2e..46740ecff7 100644 --- a/src/main/java/graphql/language/StringValue.java +++ b/src/main/java/graphql/language/StringValue.java @@ -1,44 +1,65 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi +@NullMarked public class StringValue extends AbstractNode implements ScalarValue { - private final String value; + private final @Nullable String value; @Internal - protected StringValue(String value, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected StringValue(@Nullable String value, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.value = value; } /** * alternative to using a Builder for convenience * - * @param value + * @param value of the String */ public StringValue(String value) { - super(null, new ArrayList<>()); - this.value = value; + this(value, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } - public String getValue() { + public @Nullable String getValue() { return value; } @Override public List getChildren() { - List result = new ArrayList<>(); - return result; + return emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); + } + + @Override + public StringValue withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; } @Override @@ -49,19 +70,23 @@ public String toString() { } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } StringValue that = (StringValue) o; - return !(value != null ? !value.equals(that.value) : that.value != null); + return Objects.equals(value, that.value); } @Override public StringValue deepCopy() { - return new StringValue(value, getSourceLocation(), getComments()); + return new StringValue(value, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -69,6 +94,10 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitStringValue(this, context); } + public static StringValue of(String value) { + return StringValue.newStringValue(value).build(); + } + public static Builder newStringValue() { return new Builder(); } @@ -84,38 +113,57 @@ public StringValue transform(Consumer builderConsumer) { } public static final class Builder implements NodeBuilder { - private SourceLocation sourceLocation; - private String value; - private List comments = new ArrayList<>(); + private @Nullable SourceLocation sourceLocation; + private @Nullable String value; + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(StringValue existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.value = existing.getValue(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } - public Builder sourceLocation(SourceLocation sourceLocation) { + public Builder sourceLocation(@Nullable SourceLocation sourceLocation) { this.sourceLocation = sourceLocation; return this; } - public Builder value(String value) { + public Builder value(@Nullable String value) { this.value = value; return this; } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public StringValue build() { - StringValue stringValue = new StringValue(value, sourceLocation, comments); - return stringValue; + return new StringValue(value, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/TypeDefinition.java b/src/main/java/graphql/language/TypeDefinition.java index 87559e97bc..f75c2c5147 100644 --- a/src/main/java/graphql/language/TypeDefinition.java +++ b/src/main/java/graphql/language/TypeDefinition.java @@ -3,17 +3,12 @@ import graphql.PublicApi; -import java.util.List; - +/** + * An interface for type definitions in a Schema Definition Language (SDL). + * + * @param the actual Node type + */ @PublicApi -public interface TypeDefinition extends SDLDefinition { - /** - * @return the name of the type being defined. - */ - String getName(); +public interface TypeDefinition extends SDLNamedDefinition, DirectivesContainer, NamedNode { - /** - * @return the directives of this type being defined - */ - List getDirectives(); } diff --git a/src/main/java/graphql/language/TypeName.java b/src/main/java/graphql/language/TypeName.java index 30fb95f985..add06add41 100644 --- a/src/main/java/graphql/language/TypeName.java +++ b/src/main/java/graphql/language/TypeName.java @@ -1,34 +1,42 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi -public class TypeName extends AbstractNode implements Type { +public class TypeName extends AbstractNode implements Type, NamedNode { private final String name; @Internal - protected TypeName(String name, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected TypeName(String name, SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; } /** * alternative to using a Builder for convenience * - * @param name + * @param name of the type */ public TypeName(String name) { - super(null, new ArrayList<>()); - this.name = name; + this(name, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @@ -38,22 +46,37 @@ public String getName() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); + } + + @Override + public TypeName withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } TypeName that = (TypeName) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public TypeName deepCopy() { - return new TypeName(name, getSourceLocation(), getComments()); + return new TypeName(name, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -86,15 +109,18 @@ public TypeName transform(Consumer builderConsumer) { public static final class Builder implements NodeBuilder { private String name; private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(TypeName existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } @@ -109,13 +135,27 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); return this; } public TypeName build() { - TypeName typeName = new TypeName(name, sourceLocation, comments); - return typeName; + return new TypeName(name, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/language/UnionTypeDefinition.java b/src/main/java/graphql/language/UnionTypeDefinition.java index bee1103b24..9af502db89 100644 --- a/src/main/java/graphql/language/UnionTypeDefinition.java +++ b/src/main/java/graphql/language/UnionTypeDefinition.java @@ -1,59 +1,91 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.FpKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class UnionTypeDefinition extends AbstractNode implements TypeDefinition, DirectivesContainer { +public class UnionTypeDefinition extends AbstractDescribedNode implements TypeDefinition, DirectivesContainer, NamedNode { private final String name; - private final Description description; - private final List directives; - private final List memberTypes; + private final NodeUtil.DirectivesHolder directives; + private final ImmutableList memberTypes; + + public static final String CHILD_DIRECTIVES = "directives"; + public static final String CHILD_MEMBER_TYPES = "memberTypes"; @Internal protected UnionTypeDefinition(String name, - List directives, - List memberTypes, - Description description, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + List directives, + List memberTypes, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData, description); this.name = name; - this.directives = directives; - this.memberTypes = memberTypes; - this.description = description; + this.directives = NodeUtil.DirectivesHolder.of(directives); + this.memberTypes = ImmutableList.copyOf(memberTypes); } /** * alternative to using a Builder for convenience + * + * @param name of the union + * @param directives on the union */ public UnionTypeDefinition(String name, List directives) { - this(name, directives, new ArrayList<>(), null, null, new ArrayList<>()); + this(name, directives, emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the union */ public UnionTypeDefinition(String name) { - this(name, new ArrayList<>(), new ArrayList<>(), null, null, new ArrayList<>()); + this(name, emptyList(), emptyList(), null, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); } public List getMemberTypes() { - return new ArrayList<>(memberTypes); + return memberTypes; } @Override @@ -61,37 +93,51 @@ public String getName() { return name; } - public Description getDescription() { - return description; + @Override + public List getChildren() { + return FpKit.concat(directives.getDirectives(), memberTypes); } @Override - public List getChildren() { - List result = new ArrayList<>(); - result.addAll(directives); - result.addAll(memberTypes); - return result; + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .children(CHILD_MEMBER_TYPES, memberTypes) + .build(); + } + + @Override + public UnionTypeDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .memberTypes(newChildren.getChildren(CHILD_MEMBER_TYPES)) + ); } @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } UnionTypeDefinition that = (UnionTypeDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public UnionTypeDefinition deepCopy() { return new UnionTypeDefinition(name, - deepCopy(directives), + deepCopy(directives.getDirectives()), deepCopy(memberTypes), description, getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -118,24 +164,27 @@ public UnionTypeDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives = new ArrayList<>(); - private List memberTypes = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private ImmutableList memberTypes = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(UnionTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.memberTypes = existing.getMemberTypes(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.memberTypes = ImmutableList.copyOf(existing.getMemberTypes()); + this.ignoredChars = existing.getIgnoredChars(); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -144,7 +193,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -158,34 +207,52 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); return this; } public Builder directive(Directive directive) { - this.directives.add(directive); + this.directives = ImmutableKit.addToList(directives, directive); return this; } public Builder memberTypes(List memberTypes) { - this.memberTypes = memberTypes; + this.memberTypes = ImmutableList.copyOf(memberTypes); return this; } public Builder memberType(Type memberType) { - this.memberTypes.add(memberType); + this.memberTypes = ImmutableKit.addToList(memberTypes, memberType); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; return this; } + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public UnionTypeDefinition build() { - UnionTypeDefinition unionTypeDefinition = new UnionTypeDefinition(name, + return new UnionTypeDefinition(name, directives, memberTypes, description, sourceLocation, - comments); - return unionTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/UnionTypeExtensionDefinition.java b/src/main/java/graphql/language/UnionTypeExtensionDefinition.java index f7f58983d4..81ea751792 100644 --- a/src/main/java/graphql/language/UnionTypeExtensionDefinition.java +++ b/src/main/java/graphql/language/UnionTypeExtensionDefinition.java @@ -1,28 +1,38 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + @PublicApi -public class UnionTypeExtensionDefinition extends UnionTypeDefinition { +public class UnionTypeExtensionDefinition extends UnionTypeDefinition implements SDLExtensionDefinition { @Internal protected UnionTypeExtensionDefinition(String name, - List directives, - List memberTypes, - Description description, - SourceLocation sourceLocation, - List comments) { + List directives, + List memberTypes, + Description description, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { super(name, directives, memberTypes, description, sourceLocation, - comments); + comments, + ignoredChars, + additionalData); } @Override @@ -32,7 +42,8 @@ public UnionTypeExtensionDefinition deepCopy() { deepCopy(getMemberTypes()), getDescription(), getSourceLocation(), - getComments()); + getComments(), + getIgnoredChars(), getAdditionalData()); } @Override @@ -48,31 +59,41 @@ public static Builder newUnionTypeExtensionDefinition() { return new Builder(); } + @Override + public UnionTypeExtensionDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transformExtension(builder -> builder + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + .memberTypes(newChildren.getChildren(CHILD_MEMBER_TYPES)) + ); + } + public UnionTypeExtensionDefinition transformExtension(Consumer builderConsumer) { Builder builder = new Builder(this); builderConsumer.accept(builder); return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; private Description description; - private List directives = new ArrayList<>(); - private List memberTypes = new ArrayList<>(); + private ImmutableList directives = emptyList(); + private ImmutableList memberTypes = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } - - private Builder(UnionTypeExtensionDefinition existing) { + private Builder(UnionTypeDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.description = existing.getDescription(); - this.directives = existing.getDirectives(); - this.memberTypes = existing.getMemberTypes(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.memberTypes = ImmutableList.copyOf(existing.getMemberTypes()); + this.ignoredChars = existing.getIgnoredChars(); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -81,7 +102,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -95,25 +116,52 @@ public Builder description(Description description) { return this; } + @Override public Builder directives(List directives) { - this.directives = directives; + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); return this; } public Builder memberTypes(List memberTypes) { - this.memberTypes = memberTypes; + this.memberTypes = ImmutableList.copyOf(memberTypes); + return this; + } + + public Builder memberType(Type memberType) { + this.memberTypes = ImmutableKit.addToList(memberTypes, memberType); return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public UnionTypeExtensionDefinition build() { - UnionTypeExtensionDefinition unionTypeDefinition = new UnionTypeExtensionDefinition(name, + return new UnionTypeExtensionDefinition(name, directives, memberTypes, description, sourceLocation, - comments - ); - return unionTypeDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/Value.java b/src/main/java/graphql/language/Value.java index 08cfecbe29..ccb477a913 100644 --- a/src/main/java/graphql/language/Value.java +++ b/src/main/java/graphql/language/Value.java @@ -2,8 +2,10 @@ import graphql.PublicApi; +import org.jspecify.annotations.NullMarked; @PublicApi +@NullMarked public interface Value extends Node { } diff --git a/src/main/java/graphql/language/VariableDefinition.java b/src/main/java/graphql/language/VariableDefinition.java index abb59435d3..c119222d47 100644 --- a/src/main/java/graphql/language/VariableDefinition.java +++ b/src/main/java/graphql/language/VariableDefinition.java @@ -1,52 +1,77 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.util.TraversalControl; import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; + @PublicApi -public class VariableDefinition extends AbstractNode implements NamedNode { +public class VariableDefinition extends AbstractNode implements DirectivesContainer, NamedNode { private final String name; private final Type type; private final Value defaultValue; + private final NodeUtil.DirectivesHolder directives; + + public static final String CHILD_TYPE = "type"; + public static final String CHILD_DEFAULT_VALUE = "defaultValue"; + public static final String CHILD_DIRECTIVES = "directives"; @Internal protected VariableDefinition(String name, - Type type, - Value defaultValue, - SourceLocation sourceLocation, - List comments) { - super(sourceLocation, comments); + Type type, + Value defaultValue, + List directives, + SourceLocation sourceLocation, + List comments, + IgnoredChars ignoredChars, + Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; this.type = type; this.defaultValue = defaultValue; + this.directives = NodeUtil.DirectivesHolder.of(directives); } /** * alternative to using a Builder for convenience + * + * @param name of the variable + * @param type of the variable + * @param defaultValue of the variable */ public VariableDefinition(String name, Type type, Value defaultValue) { - this(name, type, defaultValue, null, new ArrayList<>()); + this(name, type, defaultValue, emptyList(), null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } /** * alternative to using a Builder for convenience + * + * @param name of the variable + * @param type of the variable */ public VariableDefinition(String name, Type type) { - this(name, type, null, null, new ArrayList<>()); + this(name, type, null, emptyList(), null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } - public Value getDefaultValue() { return defaultValue; } @@ -59,22 +84,67 @@ public Type getType() { return type; } + @Override + public List getDirectives() { + return directives.getDirectives(); + } + + @Override + public Map> getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public List getDirectives(String directiveName) { + return directives.getDirectives(directiveName); + } + + @Override + public boolean hasDirective(String directiveName) { + return directives.hasDirective(directiveName); + } + @Override public List getChildren() { List result = new ArrayList<>(); result.add(type); - if (defaultValue != null) result.add(defaultValue); + if (defaultValue != null) { + result.add(defaultValue); + } + result.addAll(directives.getDirectives()); return result; } + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer() + .child(CHILD_TYPE, type) + .child(CHILD_DEFAULT_VALUE, defaultValue) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .build(); + } + + @Override + public VariableDefinition withNewChildren(NodeChildrenContainer newChildren) { + return transform(builder -> builder + .type(newChildren.getChildOrNull(CHILD_TYPE)) + .defaultValue(newChildren.getChildOrNull(CHILD_DEFAULT_VALUE)) + .directives(newChildren.getChildren(CHILD_DIRECTIVES)) + ); + } + @Override public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } VariableDefinition that = (VariableDefinition) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @@ -83,9 +153,11 @@ public VariableDefinition deepCopy() { return new VariableDefinition(name, deepCopy(type), deepCopy(defaultValue), + deepCopy(directives.getDirectives()), getSourceLocation(), - getComments() - ); + getComments(), + getIgnoredChars(), + getAdditionalData()); } @Override @@ -94,6 +166,7 @@ public String toString() { "name='" + name + '\'' + ", type=" + type + ", defaultValue=" + defaultValue + + ", directives=" + directives + '}'; } @@ -125,22 +198,28 @@ public VariableDefinition transform(Consumer builderConsumer) { return builder.build(); } - public static final class Builder implements NodeBuilder { + public static final class Builder implements NodeDirectivesBuilder { private SourceLocation sourceLocation; private String name; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private Type type; private Value defaultValue; + private ImmutableList directives = emptyList(); + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(VariableDefinition existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); this.type = existing.getType(); this.defaultValue = existing.getDefaultValue(); + this.directives = ImmutableList.copyOf(existing.getDirectives()); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -154,7 +233,7 @@ public Builder name(String name) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -168,15 +247,42 @@ public Builder defaultValue(Value defaultValue) { return this; } + @Override + public Builder directives(List directives) { + this.directives = ImmutableList.copyOf(directives); + return this; + } + + public Builder directive(Directive directive) { + this.directives = ImmutableKit.addToList(directives, directive); + return this; + } + + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + public VariableDefinition build() { - VariableDefinition variableDefinition = new VariableDefinition( + return new VariableDefinition( name, type, defaultValue, + directives, sourceLocation, - comments - ); - return variableDefinition; + comments, + ignoredChars, + additionalData); } } } diff --git a/src/main/java/graphql/language/VariableReference.java b/src/main/java/graphql/language/VariableReference.java index 20197616bf..69fd14acf6 100644 --- a/src/main/java/graphql/language/VariableReference.java +++ b/src/main/java/graphql/language/VariableReference.java @@ -1,32 +1,46 @@ package graphql.language; +import com.google.common.collect.ImmutableList; import graphql.Internal; import graphql.PublicApi; import graphql.util.TraversalControl; import graphql.util.TraverserContext; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; -import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Consumer; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.language.NodeChildrenContainer.newNodeChildrenContainer; +import static graphql.language.NodeUtil.assertNewChildrenAreEmpty; + @PublicApi +@NullMarked public class VariableReference extends AbstractNode implements Value, NamedNode { private final String name; @Internal - protected VariableReference(String name, SourceLocation sourceLocation, List comments) { - super(sourceLocation, comments); + protected VariableReference(String name, @Nullable SourceLocation sourceLocation, List comments, IgnoredChars ignoredChars, Map additionalData) { + super(sourceLocation, comments, ignoredChars, additionalData); this.name = name; } /** * alternative to using a Builder for convenience + * + * @param name of the variable */ public VariableReference(String name) { - super(null, new ArrayList<>()); - this.name = name; + this(name, null, emptyList(), IgnoredChars.EMPTY, emptyMap()); } @Override @@ -36,22 +50,37 @@ public String getName() { @Override public List getChildren() { - return new ArrayList<>(); + return emptyList(); + } + + @Override + public NodeChildrenContainer getNamedChildren() { + return newNodeChildrenContainer().build(); } @Override - public boolean isEqualTo(Node o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public VariableReference withNewChildren(NodeChildrenContainer newChildren) { + assertNewChildrenAreEmpty(newChildren); + return this; + } + + @Override + public boolean isEqualTo(@Nullable Node o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } VariableReference that = (VariableReference) o; - return NodeUtil.isEqualTo(this.name, that.name); + return Objects.equals(this.name, that.name); } @Override public VariableReference deepCopy() { - return new VariableReference(name, getSourceLocation(), getComments()); + return new VariableReference(name, getSourceLocation(), getComments(), getIgnoredChars(), getAdditionalData()); } @Override @@ -66,6 +95,10 @@ public TraversalControl accept(TraverserContext context, NodeVisitor visit return visitor.visitVariableReference(this, context); } + public static VariableReference of(String name) { + return newVariableReference().name(name).build(); + } + public static Builder newVariableReference() { return new Builder(); } @@ -76,18 +109,23 @@ public VariableReference transform(Consumer builderConsumer) { return builder.build(); } + @NullUnmarked public static final class Builder implements NodeBuilder { private SourceLocation sourceLocation; - private List comments = new ArrayList<>(); + private ImmutableList comments = emptyList(); private String name; + private IgnoredChars ignoredChars = IgnoredChars.EMPTY; + private Map additionalData = new LinkedHashMap<>(); private Builder() { } private Builder(VariableReference existing) { this.sourceLocation = existing.getSourceLocation(); - this.comments = existing.getComments(); + this.comments = ImmutableList.copyOf(existing.getComments()); this.name = existing.getName(); + this.ignoredChars = existing.getIgnoredChars(); + this.additionalData = new LinkedHashMap<>(existing.getAdditionalData()); } public Builder sourceLocation(SourceLocation sourceLocation) { @@ -96,7 +134,7 @@ public Builder sourceLocation(SourceLocation sourceLocation) { } public Builder comments(List comments) { - this.comments = comments; + this.comments = ImmutableList.copyOf(comments); return this; } @@ -105,9 +143,24 @@ public Builder name(String name) { return this; } + public Builder ignoredChars(IgnoredChars ignoredChars) { + this.ignoredChars = ignoredChars; + return this; + } + + public Builder additionalData(Map additionalData) { + this.additionalData = assertNotNull(additionalData); + return this; + } + + public Builder additionalData(String key, String value) { + this.additionalData.put(key, value); + return this; + } + + public VariableReference build() { - VariableReference variableReference = new VariableReference(name, sourceLocation, comments); - return variableReference; + return new VariableReference(name, sourceLocation, comments, ignoredChars, additionalData); } } } diff --git a/src/main/java/graphql/normalized/ArgumentMaker.java b/src/main/java/graphql/normalized/ArgumentMaker.java new file mode 100644 index 0000000000..c6ad4868ba --- /dev/null +++ b/src/main/java/graphql/normalized/ArgumentMaker.java @@ -0,0 +1,110 @@ +package graphql.normalized; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.Internal; +import graphql.execution.directives.QueryAppliedDirective; +import graphql.execution.directives.QueryAppliedDirectiveArgument; +import graphql.execution.directives.QueryDirectives; +import graphql.language.Argument; +import graphql.language.ArrayValue; +import graphql.language.NullValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.Value; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +import static graphql.collect.ImmutableKit.emptyMap; +import static graphql.collect.ImmutableKit.map; +import static graphql.language.Argument.newArgument; + +/** + * This class is a peer class and broken out of {@link ExecutableNormalizedOperationToAstCompiler} to deal with + * argument value making. + */ +@Internal +class ArgumentMaker { + + static List createArguments(ExecutableNormalizedField executableNormalizedField, + VariableAccumulator variableAccumulator) { + ImmutableList.Builder result = ImmutableList.builder(); + ImmutableMap normalizedArguments = executableNormalizedField.getNormalizedArguments(); + for (String argName : normalizedArguments.keySet()) { + NormalizedInputValue normalizedInputValue = normalizedArguments.get(argName); + Value value = argValue(executableNormalizedField, null, argName, normalizedInputValue, variableAccumulator); + Argument argument = newArgument() + .name(argName) + .value(value) + .build(); + result.add(argument); + } + return result.build(); + } + + static List createDirectiveArguments(ExecutableNormalizedField executableNormalizedField, + QueryDirectives queryDirectives, + QueryAppliedDirective queryAppliedDirective, + VariableAccumulator variableAccumulator) { + + Map argValueMap = queryDirectives.getNormalizedInputValueByImmediateAppliedDirectives().getOrDefault(queryAppliedDirective, emptyMap()); + + ImmutableList.Builder result = ImmutableList.builder(); + for (QueryAppliedDirectiveArgument directiveArgument : queryAppliedDirective.getArguments()) { + String argName = directiveArgument.getName(); + if (argValueMap != null && argValueMap.containsKey(argName)) { + NormalizedInputValue normalizedInputValue = argValueMap.get(argName); + Value value = argValue(executableNormalizedField, queryAppliedDirective, argName, normalizedInputValue, variableAccumulator); + Argument argument = newArgument() + .name(argName) + .value(value) + .build(); + result.add(argument); + } + } + return result.build(); + } + + @SuppressWarnings("unchecked") + private static Value argValue(ExecutableNormalizedField executableNormalizedField, + QueryAppliedDirective queryAppliedDirective, + String argName, + @Nullable Object value, + VariableAccumulator variableAccumulator) { + if (value instanceof List) { + ArrayValue.Builder arrayValue = ArrayValue.newArrayValue(); + arrayValue.values(map((List) value, val -> argValue(executableNormalizedField, queryAppliedDirective, argName, val, variableAccumulator))); + return arrayValue.build(); + } + if (value instanceof Map) { + ObjectValue.Builder objectValue = ObjectValue.newObjectValue(); + Map map = (Map) value; + for (String fieldName : map.keySet()) { + Value fieldValue = argValue(executableNormalizedField, queryAppliedDirective, argName, (NormalizedInputValue) map.get(fieldName), variableAccumulator); + objectValue.objectField(ObjectField.newObjectField().name(fieldName).value(fieldValue).build()); + } + return objectValue.build(); + } + if (value == null) { + return NullValue.newNullValue().build(); + } + return (Value) value; + } + + @NonNull + private static Value argValue(ExecutableNormalizedField executableNormalizedField, + QueryAppliedDirective queryAppliedDirective, + String argName, + NormalizedInputValue normalizedInputValue, + VariableAccumulator variableAccumulator) { + if (variableAccumulator.shouldMakeVariable(executableNormalizedField, queryAppliedDirective, argName, normalizedInputValue)) { + VariableValueWithDefinition variableWithDefinition = variableAccumulator.accumulateVariable(normalizedInputValue); + return variableWithDefinition.getVariableReference(); + } else { + return argValue(executableNormalizedField, queryAppliedDirective, argName, normalizedInputValue.getValue(), variableAccumulator); + } + } +} diff --git a/src/main/java/graphql/normalized/ENFMerger.java b/src/main/java/graphql/normalized/ENFMerger.java new file mode 100644 index 0000000000..5150eee5a4 --- /dev/null +++ b/src/main/java/graphql/normalized/ENFMerger.java @@ -0,0 +1,197 @@ +package graphql.normalized; + +import graphql.Internal; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.AstComparator; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +@Internal +public class ENFMerger { + + public static void merge( + ExecutableNormalizedField parent, + List childrenWithSameResultKey, + GraphQLSchema schema, + boolean deferSupport + ) { + // they have all the same result key + // we can only merge the fields if they have the same field name + arguments + all children are the same + List> possibleGroupsToMerge = new ArrayList<>(); + for (ExecutableNormalizedField field : childrenWithSameResultKey) { + boolean addToGroup = false; + overPossibleGroups: + for (Set group : possibleGroupsToMerge) { + for (ExecutableNormalizedField fieldInGroup : group) { + if (field.getFieldName().equals(Introspection.TypeNameMetaFieldDef.getName())) { + addToGroup = true; + group.add(field); + continue overPossibleGroups; + } + if (field.getFieldName().equals(fieldInGroup.getFieldName()) && + sameArguments(field.getAstArguments(), fieldInGroup.getAstArguments()) + && isFieldInSharedInterface(field, fieldInGroup, schema) + ) { + addToGroup = true; + group.add(field); + continue overPossibleGroups; + } + } + } + if (!addToGroup) { + LinkedHashSet group = new LinkedHashSet<>(); + group.add(field); + possibleGroupsToMerge.add(group); + } + } + for (Set groupOfFields : possibleGroupsToMerge) { + // for each group we check if it could be merged + List> listOfChildrenForGroup = new ArrayList<>(); + for (ExecutableNormalizedField fieldInGroup : groupOfFields) { + Set childrenSets = new LinkedHashSet<>(fieldInGroup.getChildren()); + listOfChildrenForGroup.add(childrenSets); + } + boolean mergeable = areFieldSetsTheSame(listOfChildrenForGroup); + if (mergeable) { + Set mergedObjects = new LinkedHashSet<>(); + groupOfFields.forEach(f -> mergedObjects.addAll(f.getObjectTypeNames())); + // patching the first one to contain more objects, remove all others + Iterator iterator = groupOfFields.iterator(); + ExecutableNormalizedField first = iterator.next(); + + while (iterator.hasNext()) { + ExecutableNormalizedField next = iterator.next(); + parent.getChildren().remove(next); + + if (deferSupport) { + // Move defer executions from removed field into the merged field's entry + first.addDeferredExecutions(next.getDeferredExecutions()); + } + } + first.setObjectTypeNames(mergedObjects); + } + } + } + + private static boolean isFieldInSharedInterface(ExecutableNormalizedField fieldOne, ExecutableNormalizedField fieldTwo, GraphQLSchema schema) { + + /* + * we can get away with only checking one of the object names, because all object names in one ENF are guaranteed to be the same field. + * This comes from how the ENFs are created in the factory before. + */ + String firstObject = fieldOne.getSingleObjectTypeName(); + String secondObject = fieldTwo.getSingleObjectTypeName(); + // we know that the field names are the same, therefore we can just take the first one + String fieldName = fieldOne.getFieldName(); + + GraphQLObjectType objectTypeOne = schema.getObjectType(firstObject); + GraphQLObjectType objectTypeTwo = schema.getObjectType(secondObject); + List interfacesOne = (List) objectTypeOne.getInterfaces(); + List interfacesTwo = (List) objectTypeTwo.getInterfaces(); + + Optional firstInterfaceFound = interfacesOne.stream().filter(singleInterface -> singleInterface.getFieldDefinition(fieldName) != null).findFirst(); + Optional secondInterfaceFound = interfacesTwo.stream().filter(singleInterface -> singleInterface.getFieldDefinition(fieldName) != null).findFirst(); + if (!firstInterfaceFound.isPresent() || !secondInterfaceFound.isPresent()) { + return false; + } + return firstInterfaceFound.get().getName().equals(secondInterfaceFound.get().getName()); + } + + + private static boolean areFieldSetsTheSame(List> listOfSets) { + if (listOfSets.size() == 0 || listOfSets.size() == 1) { + return true; + } + Set first = listOfSets.get(0); + Iterator> iterator = listOfSets.iterator(); + iterator.next(); + while (iterator.hasNext()) { + Set set = iterator.next(); + if (!compareTwoFieldSets(first, set)) { + return false; + } + } + List> nextLevel = new ArrayList<>(); + for (Set set : listOfSets) { + for (ExecutableNormalizedField fieldInSet : set) { + nextLevel.add(new LinkedHashSet<>(fieldInSet.getChildren())); + } + } + return areFieldSetsTheSame(nextLevel); + } + + private static boolean compareTwoFieldSets(Set setOne, Set setTwo) { + if (setOne.size() != setTwo.size()) { + return false; + } + for (ExecutableNormalizedField field : setOne) { + if (!isContained(field, setTwo)) { + return false; + } + } + return true; + } + + private static boolean isContained(ExecutableNormalizedField searchFor, Set set) { + for (ExecutableNormalizedField field : set) { + if (compareWithoutChildren(searchFor, field)) { + return true; + } + } + return false; + } + + private static boolean compareWithoutChildren(ExecutableNormalizedField one, ExecutableNormalizedField two) { + + if (!one.getObjectTypeNames().equals(two.getObjectTypeNames())) { + return false; + } + if (!Objects.equals(one.getAlias(), two.getAlias())) { + return false; + } + if (!Objects.equals(one.getFieldName(), two.getFieldName())) { + return false; + } + if (!sameArguments(one.getAstArguments(), two.getAstArguments())) { + return false; + } + return true; + } + + // copied from graphql.validation.rules.OverlappingFieldsCanBeMerged + private static boolean sameArguments(List arguments1, List arguments2) { + if (arguments1.size() != arguments2.size()) { + return false; + } + for (Argument argument : arguments1) { + Argument matchedArgument = findArgumentByName(argument.getName(), arguments2); + if (matchedArgument == null) { + return false; + } + if (!AstComparator.sameValue(argument.getValue(), matchedArgument.getValue())) { + return false; + } + } + return true; + } + + private static Argument findArgumentByName(String name, List arguments) { + for (Argument argument : arguments) { + if (argument.getName().equals(name)) { + return argument; + } + } + return null; + } + +} diff --git a/src/main/java/graphql/normalized/ExecutableNormalizedField.java b/src/main/java/graphql/normalized/ExecutableNormalizedField.java new file mode 100644 index 0000000000..aefa115206 --- /dev/null +++ b/src/main/java/graphql/normalized/ExecutableNormalizedField.java @@ -0,0 +1,695 @@ +package graphql.normalized; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.ExperimentalApi; +import graphql.Internal; +import graphql.Mutable; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.normalized.incremental.NormalizedDeferredExecution; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLUnionType; +import graphql.util.FpKit; +import graphql.util.MutableRef; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; + +/** + * An {@link ExecutableNormalizedField} represents a field in an executable graphql operation. Its models what + * could be executed during a given operation. + *

+ * This class is intentionally mutable for performance reasons since building immutable parent child + * objects is too expensive. + */ +@PublicApi +@Mutable +public class ExecutableNormalizedField { + private final String alias; + private final ImmutableMap normalizedArguments; + private final LinkedHashMap resolvedArguments; + private final ImmutableList astArguments; + + // Mutable List on purpose: it is modified after creation + private final LinkedHashSet objectTypeNames; + private final ArrayList children; + private ExecutableNormalizedField parent; + + private final String fieldName; + private final int level; + + // Mutable List on purpose: it is modified after creation + private final LinkedHashSet deferredExecutions; + + private ExecutableNormalizedField(Builder builder) { + this.alias = builder.alias; + this.resolvedArguments = builder.resolvedArguments; + this.normalizedArguments = builder.normalizedArguments; + this.astArguments = builder.astArguments; + this.objectTypeNames = builder.objectTypeNames; + this.fieldName = assertNotNull(builder.fieldName); + this.children = builder.children; + this.level = builder.level; + this.parent = builder.parent; + this.deferredExecutions = builder.deferredExecutions; + } + + /** + * Determines whether this {@link ExecutableNormalizedField} needs a fragment to select the field. However, it considers the parent + * output type when determining whether it needs a fragment. + *

+ * Consider the following schema + * + *

+     * interface Animal {
+     *     name: String
+     *     parent: Animal
+     * }
+     * type Cat implements Animal {
+     *     name: String
+     *     parent: Cat
+     * }
+     * type Dog implements Animal {
+     *     name: String
+     *     parent: Dog
+     *     isGoodBoy: Boolean
+     * }
+     * type Query {
+     *     animal: Animal
+     * }
+     * 
+ *

+ * and the following query + * + *

+     * {
+     *     animal {
+     *         parent {
+     *             name
+     *         }
+     *     }
+     * }
+     * 
+ *

+ * Then we would get the following {@link ExecutableNormalizedOperation} + * + *

+     * -Query.animal: Animal
+     * --[Cat, Dog].parent: Cat, Dog
+     * ---[Cat, Dog].name: String
+     * 
+ *

+ * If we simply checked the {@link #parent}'s {@link #getFieldDefinitions(GraphQLSchema)} that would + * point us to {@code Cat.parent} and {@code Dog.parent} whose output types would incorrectly answer + * our question whether this is conditional? + *

+ * We MUST consider that the output type of the {@code parent} field is {@code Animal} and + * NOT {@code Cat} or {@code Dog} as their respective implementations would say. + * + * @param schema - the graphql schema in play + * + * @return true if the field is conditional + */ + public boolean isConditional(@NonNull GraphQLSchema schema) { + if (parent == null) { + return false; + } + + for (GraphQLInterfaceType commonParentOutputInterface : parent.getInterfacesCommonToAllOutputTypes(schema)) { + List implementations = schema.getImplementations(commonParentOutputInterface); + // __typename + if (fieldName.equals(Introspection.TypeNameMetaFieldDef.getName()) && implementations.size() == objectTypeNames.size()) { + return false; + } + if (commonParentOutputInterface.getField(fieldName) == null) { + continue; + } + if (implementations.size() == objectTypeNames.size()) { + return false; + } + } + + // __typename is the only field in a union type that CAN be NOT conditional + GraphQLFieldDefinition parentFieldDef = parent.getOneFieldDefinition(schema); + if (unwrapAll(parentFieldDef.getType()) instanceof GraphQLUnionType) { + GraphQLUnionType parentOutputTypeAsUnion = (GraphQLUnionType) unwrapAll(parentFieldDef.getType()); + if (fieldName.equals(Introspection.TypeNameMetaFieldDef.getName()) && objectTypeNames.size() == parentOutputTypeAsUnion.getTypes().size()) { + return false; // Not conditional + } + } + + // This means there is no Union or Interface which could serve as unconditional parent + if (objectTypeNames.size() > 1) { + return true; // Conditional + } + if (parent.objectTypeNames.size() > 1) { + return true; + } + + GraphQLObjectType oneObjectType = (GraphQLObjectType) schema.getType(objectTypeNames.iterator().next()); + return unwrapAll(parentFieldDef.getType()) != oneObjectType; + } + + public boolean hasChildren() { + return children.size() > 0; + } + + public GraphQLOutputType getType(GraphQLSchema schema) { + List fieldDefinitions = getFieldDefinitions(schema); + Set fieldTypes = fieldDefinitions.stream().map(fd -> simplePrint(fd.getType())).collect(toSet()); + assertTrue(fieldTypes.size() == 1, "More than one type ... use getTypes"); + return fieldDefinitions.get(0).getType(); + } + + public List getTypes(GraphQLSchema schema) { + return ImmutableKit.map(getFieldDefinitions(schema), fd -> fd.getType()); + } + + public void forEachFieldDefinition(GraphQLSchema schema, Consumer consumer) { + var fieldDefinition = resolveIntrospectionField(schema, objectTypeNames, fieldName); + if (fieldDefinition != null) { + consumer.accept(fieldDefinition); + return; + } + + for (String objectTypeName : objectTypeNames) { + GraphQLObjectType type = (GraphQLObjectType) assertNotNull(schema.getType(objectTypeName)); + consumer.accept(assertNotNull(type.getField(fieldName), "No field %s found for type %s", fieldName, objectTypeName)); + } + } + + public List getFieldDefinitions(GraphQLSchema schema) { + ImmutableList.Builder builder = ImmutableList.builder(); + forEachFieldDefinition(schema, builder::add); + return builder.build(); + } + + /** + * This is NOT public as it is not recommended usage. + *

+ * Internally there are cases where we know it is safe to use this, so this exists. + */ + private GraphQLFieldDefinition getOneFieldDefinition(GraphQLSchema schema) { + var fieldDefinition = resolveIntrospectionField(schema, objectTypeNames, fieldName); + if (fieldDefinition != null) { + return fieldDefinition; + } + + String objectTypeName = objectTypeNames.iterator().next(); + GraphQLObjectType type = (GraphQLObjectType) assertNotNull(schema.getType(objectTypeName)); + return assertNotNull(type.getField(fieldName), "No field %s found for type %s", fieldName, objectTypeName); + } + + private static GraphQLFieldDefinition resolveIntrospectionField(GraphQLSchema schema, Set objectTypeNames, String fieldName) { + if (fieldName.equals(schema.getIntrospectionTypenameFieldDefinition().getName())) { + return schema.getIntrospectionTypenameFieldDefinition(); + } else if (objectTypeNames.size() == 1 && objectTypeNames.iterator().next().equals(schema.getQueryType().getName())) { + if (fieldName.equals(schema.getIntrospectionSchemaFieldDefinition().getName())) { + return schema.getIntrospectionSchemaFieldDefinition(); + } else if (fieldName.equals(schema.getIntrospectionTypeFieldDefinition().getName())) { + return schema.getIntrospectionTypeFieldDefinition(); + } + } + return null; + } + + @Internal + public void addObjectTypeNames(Collection objectTypeNames) { + this.objectTypeNames.addAll(objectTypeNames); + } + + @Internal + public void setObjectTypeNames(Collection objectTypeNames) { + this.objectTypeNames.clear(); + this.objectTypeNames.addAll(objectTypeNames); + } + + @Internal + public void addChild(ExecutableNormalizedField executableNormalizedField) { + this.children.add(executableNormalizedField); + } + + @Internal + public void clearChildren() { + this.children.clear(); + } + + @Internal + public void setDeferredExecutions(Collection deferredExecutions) { + this.deferredExecutions.clear(); + this.deferredExecutions.addAll(deferredExecutions); + } + + public void addDeferredExecutions(Collection deferredExecutions) { + this.deferredExecutions.addAll(deferredExecutions); + } + + /** + * All merged fields have the same name so this is the name of the {@link ExecutableNormalizedField}. + *

+ * WARNING: This is not always the key in the execution result, because of possible field aliases. + * + * @return the name of this {@link ExecutableNormalizedField} + * + * @see #getResultKey() + * @see #getAlias() + */ + public String getName() { + return getFieldName(); + } + + /** + * @return the same value as {@link #getName()} + * + * @see #getResultKey() + * @see #getAlias() + */ + public String getFieldName() { + return fieldName; + } + + /** + * Returns the result key of this {@link ExecutableNormalizedField} within the overall result. + * This is either a field alias or the value of {@link #getName()} + * + * @return the result key for this {@link ExecutableNormalizedField}. + * + * @see #getName() + */ + public String getResultKey() { + if (alias != null) { + return alias; + } + return getName(); + } + + /** + * @return the field alias used or null if there is none + * + * @see #getResultKey() + * @see #getName() + */ + public String getAlias() { + return alias; + } + + /** + * @return a list of the {@link Argument}s on the field + */ + public ImmutableList getAstArguments() { + return astArguments; + } + + /** + * Returns an argument value as a {@link NormalizedInputValue} which contains its type name and its current value + * + * @param name the name of the argument + * + * @return an argument value + */ + public NormalizedInputValue getNormalizedArgument(String name) { + return normalizedArguments.get(name); + } + + /** + * @return a map of all the arguments in {@link NormalizedInputValue} form + */ + public ImmutableMap getNormalizedArguments() { + return normalizedArguments; + } + + /** + * @return a map of the resolved argument values + */ + public LinkedHashMap getResolvedArguments() { + return resolvedArguments; + } + + + /** + * A {@link ExecutableNormalizedField} can sometimes (for non-concrete types like interfaces and unions) + * have more than one object type it could be when executed. There is no way to know what it will be until + * the field is executed over data and the type is resolved via a {@link graphql.schema.TypeResolver}. + *

+ * This method returns all the possible types a field can be which is one or more {@link GraphQLObjectType} + * names. + *

+ * Warning: This returns a Mutable Set. No defensive copy is made for performance reasons. + * + * @return a set of the possible type names this field could be. + */ + public Set getObjectTypeNames() { + return objectTypeNames; + } + + + /** + * This returns the first entry in {@link #getObjectTypeNames()}. Sometimes you know a field cant be more than one + * type and this method is a shortcut one to help you. + * + * @return the first entry from + */ + public String getSingleObjectTypeName() { + return objectTypeNames.iterator().next(); + } + + /** + * @return a helper method show field details + */ + public String printDetails() { + StringBuilder result = new StringBuilder(); + if (getAlias() != null) { + result.append(getAlias()).append(": "); + } + return result + objectTypeNamesToString() + "." + fieldName; + } + + /** + * @return a helper method to show the object types names as a string + */ + public String objectTypeNamesToString() { + if (objectTypeNames.size() == 1) { + return objectTypeNames.iterator().next(); + } else { + return objectTypeNames.toString(); + } + } + + /** + * This returns the list of the result keys (see {@link #getResultKey()} that lead from this field upwards to + * its parent field + * + * @return a list of the result keys from this {@link ExecutableNormalizedField} to the top of the operation via parent fields + */ + public List getListOfResultKeys() { + LinkedList list = new LinkedList<>(); + ExecutableNormalizedField current = this; + while (current != null) { + list.addFirst(current.getResultKey()); + current = current.parent; + } + return list; + } + + /** + * @return the children of the {@link ExecutableNormalizedField} + */ + public List getChildren() { + return children; + } + + /** + * Returns the list of child fields that would have the same result key + * + * @param resultKey the result key to check + * + * @return a list of all direct {@link ExecutableNormalizedField} children with the specified result key + */ + public List getChildrenWithSameResultKey(String resultKey) { + return FpKit.filterList(children, child -> child.getResultKey().equals(resultKey)); + } + + public List getChildren(int includingRelativeLevel) { + assertTrue(includingRelativeLevel >= 1, "relative level must be >= 1"); + List result = new ArrayList<>(); + + this.getChildren().forEach(child -> { + traverseImpl(child, result::add, 1, includingRelativeLevel); + }); + return result; + } + + /** + * This returns the child fields that can be used if the object is of the specified object type + * + * @param objectTypeName the object type + * + * @return a list of child fields that would apply to that object type + */ + public List getChildren(String objectTypeName) { + return children.stream() + .filter(cld -> cld.objectTypeNames.contains(objectTypeName)) + .collect(toList()); + } + + /** + * the level of the {@link ExecutableNormalizedField} in the operation hierarchy with top level fields + * starting at 1 + * + * @return the level of the {@link ExecutableNormalizedField} in the operation hierarchy + */ + public int getLevel() { + return level; + } + + /** + * @return the parent of this {@link ExecutableNormalizedField} or null if it's a top level field + */ + public ExecutableNormalizedField getParent() { + return parent; + } + + /** + * @return the {@link NormalizedDeferredExecution}s associated with this {@link ExecutableNormalizedField}. + * + * @see NormalizedDeferredExecution + */ + @ExperimentalApi + public LinkedHashSet getDeferredExecutions() { + return deferredExecutions; + } + + @Internal + public void replaceParent(ExecutableNormalizedField newParent) { + this.parent = newParent; + } + + + @Override + public String toString() { + return "NormalizedField{" + + objectTypeNamesToString() + "." + fieldName + + ", alias=" + alias + + ", level=" + level + + ", children=" + children.stream().map(ExecutableNormalizedField::toString).collect(joining("\n")) + + '}'; + } + + + /** + * Traverse from this {@link ExecutableNormalizedField} down into itself and all of its children + * + * @param consumer the callback for each {@link ExecutableNormalizedField} in the hierarchy. + */ + public void traverseSubTree(Consumer consumer) { + this.getChildren().forEach(child -> { + traverseImpl(child, consumer, 1, Integer.MAX_VALUE); + }); + } + + private void traverseImpl(ExecutableNormalizedField root, + Consumer consumer, + int curRelativeLevel, + int abortAfter) { + if (curRelativeLevel > abortAfter) { + return; + } + consumer.accept(root); + root.getChildren().forEach(child -> { + traverseImpl(child, consumer, curRelativeLevel + 1, abortAfter); + }); + } + + /** + * This tries to find interfaces common to all the field output types. + *

+ * i.e. goes through {@link #getFieldDefinitions(GraphQLSchema)} and finds interfaces that + * all the field's unwrapped output types are assignable to. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private Set getInterfacesCommonToAllOutputTypes(GraphQLSchema schema) { + // Shortcut for performance + if (objectTypeNames.size() == 1) { + var fieldDef = getOneFieldDefinition(schema); + var outputType = unwrapAll(fieldDef.getType()); + + if (outputType instanceof GraphQLObjectType) { + return new LinkedHashSet<>((List) ((GraphQLObjectType) outputType).getInterfaces()); + } else if (outputType instanceof GraphQLInterfaceType) { + var result = new LinkedHashSet<>((List) ((GraphQLInterfaceType) outputType).getInterfaces()); + result.add(outputType); + return result; + } else { + return Collections.emptySet(); + } + } + + MutableRef> commonInterfaces = new MutableRef<>(); + forEachFieldDefinition(schema, (fieldDef) -> { + var outputType = unwrapAll(fieldDef.getType()); + + List outputTypeInterfaces; + if (outputType instanceof GraphQLObjectType) { + outputTypeInterfaces = (List) ((GraphQLObjectType) outputType).getInterfaces(); + } else if (outputType instanceof GraphQLInterfaceType) { + // This interface and superinterfaces + List superInterfaces = ((GraphQLInterfaceType) outputType).getInterfaces(); + + outputTypeInterfaces = new ArrayList<>(superInterfaces.size() + 1); + outputTypeInterfaces.add((GraphQLInterfaceType) outputType); + + if (!superInterfaces.isEmpty()) { + outputTypeInterfaces.addAll((List) superInterfaces); + } + } else { + outputTypeInterfaces = Collections.emptyList(); + } + + if (commonInterfaces.value == null) { + commonInterfaces.value = new LinkedHashSet<>(outputTypeInterfaces); + } else { + commonInterfaces.value.retainAll(outputTypeInterfaces); + } + }); + + return commonInterfaces.value; + } + + /** + * @return a {@link Builder} of {@link ExecutableNormalizedField}s + */ + public static Builder newNormalizedField() { + return new Builder(); + } + + /** + * Allows this {@link ExecutableNormalizedField} to be transformed via a {@link Builder} consumer callback + * + * @param builderConsumer the consumer given a builder + * + * @return a new transformed {@link ExecutableNormalizedField} + */ + public ExecutableNormalizedField transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public static class Builder { + private LinkedHashSet objectTypeNames = new LinkedHashSet<>(); + private String fieldName; + private ArrayList children = new ArrayList<>(); + private int level; + private ExecutableNormalizedField parent; + private String alias; + private ImmutableMap normalizedArguments = ImmutableKit.emptyMap(); + private LinkedHashMap resolvedArguments = new LinkedHashMap<>(); + private ImmutableList astArguments = ImmutableKit.emptyList(); + + private LinkedHashSet deferredExecutions = new LinkedHashSet<>(); + + private Builder() { + } + + private Builder(ExecutableNormalizedField existing) { + this.alias = existing.alias; + this.normalizedArguments = existing.normalizedArguments; + this.astArguments = existing.astArguments; + this.resolvedArguments = existing.resolvedArguments; + this.objectTypeNames = new LinkedHashSet<>(existing.getObjectTypeNames()); + this.fieldName = existing.getFieldName(); + this.children = new ArrayList<>(existing.children); + this.level = existing.getLevel(); + this.parent = existing.getParent(); + this.deferredExecutions = existing.getDeferredExecutions(); + } + + public Builder clearObjectTypesNames() { + this.objectTypeNames.clear(); + return this; + } + + public Builder objectTypeNames(List objectTypeNames) { + this.objectTypeNames.addAll(objectTypeNames); + return this; + } + + public Builder alias(String alias) { + this.alias = alias; + return this; + } + + public Builder normalizedArguments(@Nullable Map arguments) { + this.normalizedArguments = arguments == null ? ImmutableKit.emptyMap() : ImmutableMap.copyOf(arguments); + return this; + } + + public Builder resolvedArguments(@Nullable Map arguments) { + this.resolvedArguments = arguments == null ? new LinkedHashMap<>() : new LinkedHashMap<>(arguments); + return this; + } + + public Builder astArguments(@NonNull List astArguments) { + this.astArguments = ImmutableList.copyOf(astArguments); + return this; + } + + + public Builder fieldName(String fieldName) { + this.fieldName = fieldName; + return this; + } + + + public Builder children(List children) { + this.children.clear(); + this.children.addAll(children); + return this; + } + + public Builder level(int level) { + this.level = level; + return this; + } + + public Builder parent(ExecutableNormalizedField parent) { + this.parent = parent; + return this; + } + + public Builder deferredExecutions(LinkedHashSet deferredExecutions) { + this.deferredExecutions = deferredExecutions; + return this; + } + + public ExecutableNormalizedField build() { + return new ExecutableNormalizedField(this); + } + } +} diff --git a/src/main/java/graphql/normalized/ExecutableNormalizedOperation.java b/src/main/java/graphql/normalized/ExecutableNormalizedOperation.java new file mode 100644 index 0000000000..cfcda2746d --- /dev/null +++ b/src/main/java/graphql/normalized/ExecutableNormalizedOperation.java @@ -0,0 +1,180 @@ +package graphql.normalized; + +import com.google.common.collect.ImmutableListMultimap; +import graphql.Assert; +import graphql.PublicApi; +import graphql.execution.MergedField; +import graphql.execution.ResultPath; +import graphql.execution.directives.QueryDirectives; +import graphql.language.Field; +import graphql.language.OperationDefinition; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLFieldsContainer; + +import java.util.List; +import java.util.Map; + +/** + * A {@link ExecutableNormalizedOperation} represent how the text of a graphql operation (sometimes known colloquially as a query) + * will be executed at runtime according to the graphql specification. It handles complex mechanisms like merging + * duplicate fields into one and also detecting when the types of a given field may actually be for more than one possible object + * type. + *

+ * An operation consists of a list of {@link ExecutableNormalizedField}s in a parent child hierarchy + */ +@PublicApi +public class ExecutableNormalizedOperation { + private final OperationDefinition.Operation operation; + private final String operationName; + private final List topLevelFields; + private final ImmutableListMultimap fieldToNormalizedField; + private final Map normalizedFieldToMergedField; + private final Map normalizedFieldToQueryDirectives; + private final ImmutableListMultimap coordinatesToNormalizedFields; + private final int operationFieldCount; + private final int operationDepth; + + public ExecutableNormalizedOperation( + OperationDefinition.Operation operation, + String operationName, + List topLevelFields, + ImmutableListMultimap fieldToNormalizedField, + Map normalizedFieldToMergedField, + Map normalizedFieldToQueryDirectives, + ImmutableListMultimap coordinatesToNormalizedFields, + int operationFieldCount, + int operationDepth) { + this.operation = operation; + this.operationName = operationName; + this.topLevelFields = topLevelFields; + this.fieldToNormalizedField = fieldToNormalizedField; + this.normalizedFieldToMergedField = normalizedFieldToMergedField; + this.normalizedFieldToQueryDirectives = normalizedFieldToQueryDirectives; + this.coordinatesToNormalizedFields = coordinatesToNormalizedFields; + this.operationFieldCount = operationFieldCount; + this.operationDepth = operationDepth; + } + + /** + * @return operation AST being executed + */ + public OperationDefinition.Operation getOperation() { + return operation; + } + + /** + * @return the operation name, which can be null + */ + public String getOperationName() { + return operationName; + } + + /** + * @return This returns how many {@link ExecutableNormalizedField}s are in the operation. + */ + public int getOperationFieldCount() { + return operationFieldCount; + } + + /** + * @return This returns the depth of the operation + */ + public int getOperationDepth() { + return operationDepth; + } + + /** + * This multimap shows how a given {@link ExecutableNormalizedField} maps to a one or more field coordinate in the schema + * + * @return a multimap of fields to schema field coordinates + */ + public ImmutableListMultimap getCoordinatesToNormalizedFields() { + return coordinatesToNormalizedFields; + } + + /** + * @return a list of the top level {@link ExecutableNormalizedField}s in this operation. + */ + public List getTopLevelFields() { + return topLevelFields; + } + + /** + * This is a multimap and the size of it reflects all the normalized fields in the operation + * + * @return an immutable list multimap of {@link Field} to {@link ExecutableNormalizedField} + */ + public ImmutableListMultimap getFieldToNormalizedField() { + return fieldToNormalizedField; + } + + /** + * Looks up one or more {@link ExecutableNormalizedField}s given a {@link Field} AST element in the operation + * + * @param field the field to look up + * + * @return zero, one or more possible {@link ExecutableNormalizedField}s that represent that field + */ + public List getNormalizedFields(Field field) { + return fieldToNormalizedField.get(field); + } + + /** + * @return a map of {@link ExecutableNormalizedField} to {@link MergedField}s + */ + public Map getNormalizedFieldToMergedField() { + return normalizedFieldToMergedField; + } + + /** + * Looks up the {@link MergedField} given a {@link ExecutableNormalizedField} + * + * @param executableNormalizedField the field to use the key + * + * @return a {@link MergedField} or null if its not present + */ + public MergedField getMergedField(ExecutableNormalizedField executableNormalizedField) { + return normalizedFieldToMergedField.get(executableNormalizedField); + } + + /** + * @return a map of {@link ExecutableNormalizedField} to its {@link QueryDirectives} + */ + public Map getNormalizedFieldToQueryDirectives() { + return normalizedFieldToQueryDirectives; + + } + + /** + * This looks up the {@link QueryDirectives} associated with the given {@link ExecutableNormalizedField} + * + * @param executableNormalizedField the executable normalised field in question + * + * @return the fields query directives or null + */ + public QueryDirectives getQueryDirectives(ExecutableNormalizedField executableNormalizedField) { + return normalizedFieldToQueryDirectives.get(executableNormalizedField); + } + + /** + * This will find a {@link ExecutableNormalizedField} given a merged field and a result path. If this does not find a field it will assert with an exception + * + * @param mergedField the merged field + * @param fieldsContainer the containing type of that field + * @param resultPath the result path in play + * + * @return the ExecutableNormalizedField + */ + public ExecutableNormalizedField getNormalizedField(MergedField mergedField, GraphQLFieldsContainer fieldsContainer, ResultPath resultPath) { + List executableNormalizedFields = fieldToNormalizedField.get(mergedField.getSingleField()); + List keysOnlyPath = resultPath.getKeysOnly(); + for (ExecutableNormalizedField executableNormalizedField : executableNormalizedFields) { + if (executableNormalizedField.getListOfResultKeys().equals(keysOnlyPath)) { + if (executableNormalizedField.getObjectTypeNames().contains(fieldsContainer.getName())) { + return executableNormalizedField; + } + } + } + return Assert.assertShouldNeverHappen("normalized field not found"); + } +} diff --git a/src/main/java/graphql/normalized/ExecutableNormalizedOperationFactory.java b/src/main/java/graphql/normalized/ExecutableNormalizedOperationFactory.java new file mode 100644 index 0000000000..8501989237 --- /dev/null +++ b/src/main/java/graphql/normalized/ExecutableNormalizedOperationFactory.java @@ -0,0 +1,948 @@ +package graphql.normalized; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import graphql.Assert; +import graphql.ExperimentalApi; +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.execution.AbortExecutionException; +import graphql.execution.CoercedVariables; +import graphql.execution.MergedField; +import graphql.execution.NormalizedVariables; +import graphql.execution.RawVariables; +import graphql.execution.ValuesResolver; +import graphql.execution.conditional.ConditionalNodes; +import graphql.execution.directives.QueryDirectives; +import graphql.execution.directives.QueryDirectivesImpl; +import graphql.execution.incremental.IncrementalUtils; +import graphql.introspection.Introspection; +import graphql.language.Directive; +import graphql.language.Document; +import graphql.language.Field; +import graphql.language.FragmentDefinition; +import graphql.language.FragmentSpread; +import graphql.language.InlineFragment; +import graphql.language.NodeUtil; +import graphql.language.OperationDefinition; +import graphql.language.Selection; +import graphql.language.SelectionSet; +import graphql.language.VariableDefinition; +import graphql.normalized.incremental.NormalizedDeferredExecution; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphQLUnmodifiedType; +import graphql.schema.impl.SchemaUtil; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.collect.ImmutableKit.map; +import static graphql.collect.ImmutableKit.mapToSet; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; +import static graphql.util.FpKit.filterSet; +import static graphql.util.FpKit.groupingBy; +import static graphql.util.FpKit.intersection; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.toCollection; +import static java.util.stream.Collectors.toSet; + +/** + * This factory can create a {@link ExecutableNormalizedOperation} which represents what would be executed + * during a given graphql operation. + */ +@PublicApi +public class ExecutableNormalizedOperationFactory { + + public static class Options { + + + private final GraphQLContext graphQLContext; + private final Locale locale; + private final int maxChildrenDepth; + private final int maxFieldsCount; + + private final boolean deferSupport; + + /** + * The default max fields count is 100,000. + * This is big enough for even very large queries, but + * can be changed via {#setDefaultOptions + */ + public static final int DEFAULT_MAX_FIELDS_COUNT = 100_000; + private static Options defaultOptions = new Options(GraphQLContext.getDefault(), + Locale.getDefault(), + Integer.MAX_VALUE, + DEFAULT_MAX_FIELDS_COUNT, + false); + + private Options(GraphQLContext graphQLContext, + Locale locale, + int maxChildrenDepth, + int maxFieldsCount, + boolean deferSupport) { + this.graphQLContext = graphQLContext; + this.locale = locale; + this.maxChildrenDepth = maxChildrenDepth; + this.deferSupport = deferSupport; + this.maxFieldsCount = maxFieldsCount; + } + + /** + * Sets new default Options used when creating instances of {@link ExecutableNormalizedOperation}. + * + * @param options new default options + */ + public static void setDefaultOptions(Options options) { + defaultOptions = Assert.assertNotNull(options); + } + + + /** + * Returns the default options used when creating instances of {@link ExecutableNormalizedOperation}. + * + * @return the default options + */ + public static Options defaultOptions() { + return defaultOptions; + } + + /** + * Locale to use when parsing the query. + *

+ * e.g. can be passed to {@link graphql.schema.Coercing} for parsing. + * + * @param locale the locale to use + * + * @return new options object to use + */ + public Options locale(Locale locale) { + return new Options(this.graphQLContext, locale, this.maxChildrenDepth, this.maxFieldsCount, this.deferSupport); + } + + /** + * Context object to use when parsing the operation. + *

+ * Can be used to intercept input values e.g. using {@link graphql.execution.values.InputInterceptor}. + * + * @param graphQLContext the context to use + * + * @return new options object to use + */ + public Options graphQLContext(GraphQLContext graphQLContext) { + return new Options(graphQLContext, this.locale, this.maxChildrenDepth, this.maxFieldsCount, this.deferSupport); + } + + /** + * Controls the maximum depth of the operation. Can be used to prevent + * against malicious operations. + * + * @param maxChildrenDepth the max depth + * + * @return new options object to use + */ + public Options maxChildrenDepth(int maxChildrenDepth) { + return new Options(this.graphQLContext, this.locale, maxChildrenDepth, this.maxFieldsCount, this.deferSupport); + } + + /** + * Controls the maximum number of ENFs created. Can be used to prevent + * against malicious operations. + * + * @param maxFieldsCount the max number of ENFs created + * + * @return new options object to use + */ + public Options maxFieldsCount(int maxFieldsCount) { + return new Options(this.graphQLContext, this.locale, this.maxChildrenDepth, maxFieldsCount, this.deferSupport); + } + + /** + * Controls whether defer execution is supported when creating instances of {@link ExecutableNormalizedOperation}. + * + * @param deferSupport true to enable support for defer + * + * @return new options object to use + */ + @ExperimentalApi + public Options deferSupport(boolean deferSupport) { + return new Options(this.graphQLContext, this.locale, this.maxChildrenDepth, this.maxFieldsCount, deferSupport); + } + + /** + * @return context to use during operation parsing + * + * @see #graphQLContext(GraphQLContext) + */ + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + /** + * @return locale to use during operation parsing + * + * @see #locale(Locale) + */ + public Locale getLocale() { + return locale; + } + + /** + * @return maximum children depth before aborting parsing + * + * @see #maxChildrenDepth(int) + */ + public int getMaxChildrenDepth() { + return maxChildrenDepth; + } + + public int getMaxFieldsCount() { + return maxFieldsCount; + } + + /** + * @return whether support for defer is enabled + * + * @see #deferSupport(boolean) + */ + @ExperimentalApi + public boolean getDeferSupport() { + return deferSupport; + } + } + + private static final ConditionalNodes conditionalNodes = new ConditionalNodes(); + + private ExecutableNormalizedOperationFactory() { + + } + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param document the {@link Document} holding the operation text + * @param operationName the operation name to use + * @param coercedVariableValues the coerced variables to use + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperation( + GraphQLSchema graphQLSchema, + Document document, + String operationName, + CoercedVariables coercedVariableValues + ) { + return createExecutableNormalizedOperation( + graphQLSchema, + document, + operationName, + coercedVariableValues, + Options.defaultOptions()); + } + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param document the {@link Document} holding the operation text + * @param operationName the operation name to use + * @param coercedVariableValues the coerced variables to use + * @param options the {@link Options} to use for parsing + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperation( + GraphQLSchema graphQLSchema, + Document document, + String operationName, + CoercedVariables coercedVariableValues, + Options options + ) { + NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, operationName); + + return new ExecutableNormalizedOperationFactoryImpl( + graphQLSchema, + getOperationResult.operationDefinition, + getOperationResult.fragmentsByName, + coercedVariableValues, + null, + options + ).createNormalizedQueryImpl(); + } + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param operationDefinition the operation to be executed + * @param fragments a set of fragments associated with the operation + * @param coercedVariableValues the coerced variables to use + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperation(GraphQLSchema graphQLSchema, + OperationDefinition operationDefinition, + Map fragments, + CoercedVariables coercedVariableValues) { + return createExecutableNormalizedOperation(graphQLSchema, + operationDefinition, + fragments, + coercedVariableValues, + Options.defaultOptions()); + } + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param operationDefinition the operation to be executed + * @param fragments a set of fragments associated with the operation + * @param coercedVariableValues the coerced variables to use + * @param options the options to use + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperation(GraphQLSchema graphQLSchema, + OperationDefinition operationDefinition, + Map fragments, + CoercedVariables coercedVariableValues, + Options options) { + return new ExecutableNormalizedOperationFactoryImpl( + graphQLSchema, + operationDefinition, + fragments, + coercedVariableValues, + null, + options + ).createNormalizedQueryImpl(); + } + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param document the {@link Document} holding the operation text + * @param operationName the operation name to use + * @param rawVariables the raw variables to be coerced + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperationWithRawVariables(GraphQLSchema graphQLSchema, + Document document, + String operationName, + RawVariables rawVariables) { + return createExecutableNormalizedOperationWithRawVariables(graphQLSchema, + document, + operationName, + rawVariables, + Options.defaultOptions()); + } + + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param document the {@link Document} holding the operation text + * @param operationName the operation name to use + * @param rawVariables the raw variables that have not yet been coerced + * @param locale the {@link Locale} to use during coercion + * @param graphQLContext the {@link GraphQLContext} to use during coercion + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperationWithRawVariables( + GraphQLSchema graphQLSchema, + Document document, + String operationName, + RawVariables rawVariables, + GraphQLContext graphQLContext, + Locale locale + ) { + return createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + operationName, + rawVariables, + Options.defaultOptions().graphQLContext(graphQLContext).locale(locale)); + } + + + /** + * This will create a runtime representation of the graphql operation that would be executed + * in a runtime sense. + * + * @param graphQLSchema the schema to be used + * @param document the {@link Document} holding the operation text + * @param operationName the operation name to use + * @param rawVariables the raw variables that have not yet been coerced + * @param options the {@link Options} to use for parsing + * + * @return a runtime representation of the graphql operation. + */ + public static ExecutableNormalizedOperation createExecutableNormalizedOperationWithRawVariables(GraphQLSchema graphQLSchema, + Document document, + String operationName, + RawVariables rawVariables, + Options options) { + NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, operationName); + OperationDefinition operationDefinition = getOperationResult.operationDefinition; + + List variableDefinitions = operationDefinition.getVariableDefinitions(); + CoercedVariables coercedVariableValues = ValuesResolver.coerceVariableValues(graphQLSchema, + variableDefinitions, + rawVariables, + options.getGraphQLContext(), + options.getLocale()); + NormalizedVariables normalizedVariableValues = ValuesResolver.getNormalizedVariableValues(graphQLSchema, + variableDefinitions, + rawVariables, + options.getGraphQLContext(), + options.getLocale()); + + return new ExecutableNormalizedOperationFactoryImpl( + graphQLSchema, + operationDefinition, + getOperationResult.fragmentsByName, + coercedVariableValues, + normalizedVariableValues, + options + ).createNormalizedQueryImpl(); + } + + + private static class ExecutableNormalizedOperationFactoryImpl { + private final GraphQLSchema graphQLSchema; + private final OperationDefinition operationDefinition; + private final Map fragments; + private final CoercedVariables coercedVariableValues; + private final @Nullable NormalizedVariables normalizedVariableValues; + private final Options options; + + private final List possibleMergerList = new ArrayList<>(); + + private final ImmutableListMultimap.Builder fieldToNormalizedField = ImmutableListMultimap.builder(); + private final ImmutableMap.Builder normalizedFieldToMergedField = ImmutableMap.builder(); + private final ImmutableMap.Builder normalizedFieldToQueryDirectives = ImmutableMap.builder(); + private final ImmutableListMultimap.Builder coordinatesToNormalizedFields = ImmutableListMultimap.builder(); + private int fieldCount = 0; + private int maxDepthSeen = 0; + + private final List rootEnfs = new ArrayList<>(); + + private ExecutableNormalizedOperationFactoryImpl( + GraphQLSchema graphQLSchema, + OperationDefinition operationDefinition, + Map fragments, + CoercedVariables coercedVariableValues, + @Nullable NormalizedVariables normalizedVariableValues, + Options options + ) { + this.graphQLSchema = graphQLSchema; + this.operationDefinition = operationDefinition; + this.fragments = fragments; + this.coercedVariableValues = coercedVariableValues; + this.normalizedVariableValues = normalizedVariableValues; + this.options = options; + } + + /** + * Creates a new ExecutableNormalizedOperation for the provided query + */ + private ExecutableNormalizedOperation createNormalizedQueryImpl() { + buildEnfsRecursively(null, null, 0); + + for (PossibleMerger possibleMerger : possibleMergerList) { + List childrenWithSameResultKey = possibleMerger.parent.getChildrenWithSameResultKey(possibleMerger.resultKey); + ENFMerger.merge(possibleMerger.parent, childrenWithSameResultKey, graphQLSchema, options.deferSupport); + } + return new ExecutableNormalizedOperation( + operationDefinition.getOperation(), + operationDefinition.getName(), + new ArrayList<>(rootEnfs), + fieldToNormalizedField.build(), + normalizedFieldToMergedField.build(), + normalizedFieldToQueryDirectives.build(), + coordinatesToNormalizedFields.build(), + fieldCount, + maxDepthSeen + ); + } + + private void captureMergedField(ExecutableNormalizedField enf, MergedField mergedFld) { + // QueryDirectivesImpl is a lazy object and only computes itself when asked for + QueryDirectives queryDirectives = new QueryDirectivesImpl(mergedFld, + graphQLSchema, + coercedVariableValues, + () -> normalizedVariableValues, + options.getGraphQLContext(), + options.getLocale()); + normalizedFieldToQueryDirectives.put(enf, queryDirectives); + normalizedFieldToMergedField.put(enf, mergedFld); + } + + private void buildEnfsRecursively(@Nullable ExecutableNormalizedField executableNormalizedField, + @Nullable ImmutableList fieldAndAstParents, + int curLevel) { + if (this.maxDepthSeen < curLevel) { + this.maxDepthSeen = curLevel; + checkMaxDepthExceeded(curLevel); + } + Set possibleObjects; + List collectedFields; + + // special handling for the root selection Set + if (executableNormalizedField == null) { + GraphQLObjectType rootType = SchemaUtil.getOperationRootType(graphQLSchema, operationDefinition); + possibleObjects = ImmutableSet.of(rootType); + collectedFields = new ArrayList<>(); + collectFromSelectionSet(operationDefinition.getSelectionSet(), collectedFields, rootType, possibleObjects, null); + } else { + List fieldDefs = executableNormalizedField.getFieldDefinitions(graphQLSchema); + possibleObjects = resolvePossibleObjects(fieldDefs); + if (possibleObjects.isEmpty()) { + return; + } + collectedFields = new ArrayList<>(); + for (CollectedField fieldAndAstParent : fieldAndAstParents) { + if (fieldAndAstParent.field.getSelectionSet() == null) { + continue; + } + // the AST parent comes from the previous collect from selection set call + // and is the type to which the field belongs (the container type of the field) and output type + // of the field needs to be determined based on the field name + GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(graphQLSchema, fieldAndAstParent.astTypeCondition, fieldAndAstParent.field.getName()); + // it must a composite type, because the field has a selection set + GraphQLCompositeType selectionSetType = (GraphQLCompositeType) unwrapAll(fieldDefinition.getType()); + this.collectFromSelectionSet(fieldAndAstParent.field.getSelectionSet(), + collectedFields, + selectionSetType, + possibleObjects, + null + ); + } + } + + Map> fieldsByName = fieldsByResultKey(collectedFields); + ImmutableList.Builder resultNFs = ImmutableList.builder(); + ImmutableListMultimap.Builder normalizedFieldToAstFields = ImmutableListMultimap.builder(); + createNFs(resultNFs, fieldsByName, normalizedFieldToAstFields, curLevel + 1, executableNormalizedField); + + ImmutableList nextLevelChildren = resultNFs.build(); + ImmutableListMultimap nextLevelNormalizedFieldToAstFields = normalizedFieldToAstFields.build(); + + for (ExecutableNormalizedField childENF : nextLevelChildren) { + if (executableNormalizedField == null) { + // all root ENFs don't have a parent, but are collected in the rootEnfs list + rootEnfs.add(childENF); + } else { + executableNormalizedField.addChild(childENF); + } + ImmutableList childFieldAndAstParents = nextLevelNormalizedFieldToAstFields.get(childENF); + + MergedField mergedField = newMergedField(childFieldAndAstParents); + captureMergedField(childENF, mergedField); + + updateFieldToNFMap(childENF, childFieldAndAstParents); + updateCoordinatedToNFMap(childENF); + + // recursive call + buildEnfsRecursively(childENF, + childFieldAndAstParents, + curLevel + 1); + } + } + + private void checkMaxDepthExceeded(int depthSeen) { + if (depthSeen > this.options.getMaxChildrenDepth()) { + throw new AbortExecutionException("Maximum query depth exceeded. " + depthSeen + " > " + this.options.getMaxChildrenDepth()); + } + } + + private static MergedField newMergedField(ImmutableList fieldAndAstParents) { + return MergedField.newMergedField(mapToSet(fieldAndAstParents, fieldAndAstParent -> fieldAndAstParent.field)).build(); + } + + private void updateFieldToNFMap(ExecutableNormalizedField executableNormalizedField, + ImmutableList mergedField) { + for (CollectedField astField : mergedField) { + fieldToNormalizedField.put(astField.field, executableNormalizedField); + } + } + + private void updateCoordinatedToNFMap(ExecutableNormalizedField topLevel) { + for (String objectType : topLevel.getObjectTypeNames()) { + FieldCoordinates coordinates = FieldCoordinates.coordinates(objectType, topLevel.getFieldName()); + coordinatesToNormalizedFields.put(coordinates, topLevel); + } + } + + + private Map> fieldsByResultKey(List collectedFields) { + Map> fieldsByName = new LinkedHashMap<>(); + for (CollectedField collectedField : collectedFields) { + fieldsByName.computeIfAbsent(collectedField.field.getResultKey(), ignored -> new ArrayList<>()).add(collectedField); + } + return fieldsByName; + } + + + private void createNFs(ImmutableList.Builder nfListBuilder, + Map> fieldsByName, + ImmutableListMultimap.Builder normalizedFieldToAstFields, + int level, + ExecutableNormalizedField parent) { + for (String resultKey : fieldsByName.keySet()) { + List fieldsWithSameResultKey = fieldsByName.get(resultKey); + List commonParentsGroups = groupByCommonParents(fieldsWithSameResultKey); + for (CollectedFieldGroup fieldGroup : commonParentsGroups) { + ExecutableNormalizedField nf = createNF(fieldGroup, level, parent); + if (nf == null) { + continue; + } + for (CollectedField collectedField : fieldGroup.fields) { + normalizedFieldToAstFields.put(nf, collectedField); + } + nfListBuilder.add(nf); + + if (this.options.deferSupport) { + nf.addDeferredExecutions(fieldGroup.deferredExecutions); + } + } + if (commonParentsGroups.size() > 1) { + possibleMergerList.add(new PossibleMerger(parent, resultKey)); + } + } + } + + // new single ENF + private ExecutableNormalizedField createNF(CollectedFieldGroup collectedFieldGroup, + int level, + ExecutableNormalizedField parent) { + + this.fieldCount++; + if (this.fieldCount > this.options.getMaxFieldsCount()) { + throw new AbortExecutionException("Maximum field count exceeded. " + this.fieldCount + " > " + this.options.getMaxFieldsCount()); + } + Field field; + Set objectTypes = collectedFieldGroup.objectTypes; + field = collectedFieldGroup.fields.iterator().next().field; + String fieldName = field.getName(); + GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDefinition(graphQLSchema, objectTypes.iterator().next(), fieldName); + + Map argumentValues = ValuesResolver.getArgumentValues(fieldDefinition.getArguments(), field.getArguments(), CoercedVariables.of(this.coercedVariableValues.toMap()), this.options.graphQLContext, this.options.locale); + Map normalizedArgumentValues = null; + if (this.normalizedVariableValues != null) { + normalizedArgumentValues = ValuesResolver.getNormalizedArgumentValues(fieldDefinition.getArguments(), field.getArguments(), this.normalizedVariableValues.toMap()); + } + ImmutableList objectTypeNames = map(objectTypes, GraphQLObjectType::getName); + return ExecutableNormalizedField.newNormalizedField() + .alias(field.getAlias()) + .resolvedArguments(argumentValues) + .normalizedArguments(normalizedArgumentValues) + .astArguments(field.getArguments()) + .objectTypeNames(objectTypeNames) + .fieldName(fieldName) + .level(level) + .parent(parent) + .build(); + } + + private List groupByCommonParents(Collection fields) { + if (this.options.deferSupport) { + return groupByCommonParentsWithDeferSupport(fields); + } else { + return groupByCommonParentsNoDeferSupport(fields); + } + } + + private List groupByCommonParentsNoDeferSupport(Collection fields) { + ImmutableSet.Builder objectTypes = ImmutableSet.builder(); + for (CollectedField collectedField : fields) { + objectTypes.addAll(collectedField.objectTypes); + } + Set allRelevantObjects = objectTypes.build(); + Map> groupByAstParent = groupingBy(fields, fieldAndType -> fieldAndType.astTypeCondition); + if (groupByAstParent.size() == 1) { + return singletonList(new CollectedFieldGroup(ImmutableSet.copyOf(fields), allRelevantObjects, null)); + } + ImmutableList.Builder result = ImmutableList.builder(); + for (GraphQLObjectType objectType : allRelevantObjects) { + Set relevantFields = filterSet(fields, field -> field.objectTypes.contains(objectType)); + result.add(new CollectedFieldGroup(relevantFields, singleton(objectType), null)); + } + return result.build(); + } + + private List groupByCommonParentsWithDeferSupport(Collection fields) { + ImmutableSet.Builder objectTypes = ImmutableSet.builder(); + ImmutableSet.Builder deferredExecutionsBuilder = ImmutableSet.builder(); + + for (CollectedField collectedField : fields) { + objectTypes.addAll(collectedField.objectTypes); + + NormalizedDeferredExecution collectedDeferredExecution = collectedField.deferredExecution; + + if (collectedDeferredExecution != null) { + deferredExecutionsBuilder.add(collectedDeferredExecution); + } + } + + Set allRelevantObjects = objectTypes.build(); + Set deferredExecutions = deferredExecutionsBuilder.build(); + + Set duplicatedLabels = listDuplicatedLabels(deferredExecutions); + + if (!duplicatedLabels.isEmpty()) { + // Query validation should pick this up + Assert.assertShouldNeverHappen("Duplicated @defer labels are not allowed: [%s]", String.join(",", duplicatedLabels)); + } + + Map> groupByAstParent = groupingBy(fields, fieldAndType -> fieldAndType.astTypeCondition); + if (groupByAstParent.size() == 1) { + return singletonList(new CollectedFieldGroup(ImmutableSet.copyOf(fields), allRelevantObjects, deferredExecutions)); + } + + ImmutableList.Builder result = ImmutableList.builder(); + for (GraphQLObjectType objectType : allRelevantObjects) { + Set relevantFields = filterSet(fields, field -> field.objectTypes.contains(objectType)); + + Set filteredDeferredExecutions = deferredExecutions.stream() + .filter(filterExecutionsFromType(objectType)) + .collect(toCollection(LinkedHashSet::new)); + + result.add(new CollectedFieldGroup(relevantFields, singleton(objectType), filteredDeferredExecutions)); + } + return result.build(); + } + + private static Predicate filterExecutionsFromType(GraphQLObjectType objectType) { + String objectTypeName = objectType.getName(); + return deferredExecution -> deferredExecution.getPossibleTypes() + .stream() + .map(GraphQLObjectType::getName) + .anyMatch(objectTypeName::equals); + } + + private Set listDuplicatedLabels(Collection deferredExecutions) { + return deferredExecutions.stream() + .map(NormalizedDeferredExecution::getLabel) + .filter(Objects::nonNull) + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) + .entrySet() + .stream() + .filter(entry -> entry.getValue() > 1) + .map(Map.Entry::getKey) + .collect(toSet()); + } + + private void collectFromSelectionSet(SelectionSet selectionSet, + List result, + GraphQLCompositeType astTypeCondition, + Set possibleObjects, + NormalizedDeferredExecution deferredExecution + ) { + for (Selection selection : selectionSet.getSelections()) { + if (selection instanceof Field) { + collectField(result, (Field) selection, possibleObjects, astTypeCondition, deferredExecution); + } else if (selection instanceof InlineFragment) { + collectInlineFragment(result, (InlineFragment) selection, possibleObjects, astTypeCondition); + } else if (selection instanceof FragmentSpread) { + collectFragmentSpread(result, (FragmentSpread) selection, possibleObjects); + } + } + } + + private void collectFragmentSpread(List result, + FragmentSpread fragmentSpread, + Set possibleObjects + ) { + if (!conditionalNodes.shouldInclude(fragmentSpread, + this.coercedVariableValues.toMap(), + this.graphQLSchema, + this.options.graphQLContext)) { + return; + } + FragmentDefinition fragmentDefinition = assertNotNull(this.fragments.get(fragmentSpread.getName())); + + if (!conditionalNodes.shouldInclude(fragmentDefinition, + this.coercedVariableValues.toMap(), + this.graphQLSchema, + this.options.graphQLContext)) { + return; + } + GraphQLCompositeType newAstTypeCondition = (GraphQLCompositeType) assertNotNull(this.graphQLSchema.getType(fragmentDefinition.getTypeCondition().getName())); + Set newPossibleObjects = narrowDownPossibleObjects(possibleObjects, newAstTypeCondition); + + NormalizedDeferredExecution newDeferredExecution = buildDeferredExecution( + fragmentSpread.getDirectives(), + newPossibleObjects); + + collectFromSelectionSet(fragmentDefinition.getSelectionSet(), result, newAstTypeCondition, newPossibleObjects, newDeferredExecution); + } + + private void collectInlineFragment(List result, + InlineFragment inlineFragment, + Set possibleObjects, + GraphQLCompositeType astTypeCondition + ) { + if (!conditionalNodes.shouldInclude(inlineFragment, this.coercedVariableValues.toMap(), this.graphQLSchema, this.options.graphQLContext)) { + return; + } + Set newPossibleObjects = possibleObjects; + GraphQLCompositeType newAstTypeCondition = astTypeCondition; + + if (inlineFragment.getTypeCondition() != null) { + newAstTypeCondition = (GraphQLCompositeType) this.graphQLSchema.getType(inlineFragment.getTypeCondition().getName()); + newPossibleObjects = narrowDownPossibleObjects(possibleObjects, newAstTypeCondition); + + } + + NormalizedDeferredExecution newDeferredExecution = buildDeferredExecution( + inlineFragment.getDirectives(), + newPossibleObjects + ); + + collectFromSelectionSet(inlineFragment.getSelectionSet(), result, newAstTypeCondition, newPossibleObjects, newDeferredExecution); + } + + private @Nullable NormalizedDeferredExecution buildDeferredExecution( + List directives, + Set newPossibleObjects) { + if (!options.deferSupport) { + return null; + } + + return IncrementalUtils.createDeferredExecution( + this.coercedVariableValues.toMap(), + directives, + (label) -> new NormalizedDeferredExecution(label, newPossibleObjects) + ); + } + + private void collectField(List result, + Field field, + Set possibleObjectTypes, + GraphQLCompositeType astTypeCondition, + NormalizedDeferredExecution deferredExecution + ) { + if (!conditionalNodes.shouldInclude(field, + this.coercedVariableValues.toMap(), + this.graphQLSchema, + this.options.graphQLContext)) { + return; + } + // this means there is actually no possible type for this field, and we are done + if (possibleObjectTypes.isEmpty()) { + return; + } + result.add(new CollectedField(field, possibleObjectTypes, astTypeCondition, deferredExecution)); + } + + private Set narrowDownPossibleObjects(Set currentOnes, + GraphQLCompositeType typeCondition) { + + ImmutableSet resolvedTypeCondition = resolvePossibleObjects(typeCondition); + if (currentOnes.isEmpty()) { + return resolvedTypeCondition; + } + + // Faster intersection, as either set often has a size of 1. + return intersection(currentOnes, resolvedTypeCondition); + } + + private ImmutableSet resolvePossibleObjects(List defs) { + ImmutableSet.Builder builder = ImmutableSet.builder(); + + for (GraphQLFieldDefinition def : defs) { + GraphQLUnmodifiedType outputType = unwrapAll(def.getType()); + if (outputType instanceof GraphQLCompositeType) { + builder.addAll(resolvePossibleObjects((GraphQLCompositeType) outputType)); + } + } + + return builder.build(); + } + + private ImmutableSet resolvePossibleObjects(GraphQLCompositeType type) { + if (type instanceof GraphQLObjectType) { + return ImmutableSet.of((GraphQLObjectType) type); + } else if (type instanceof GraphQLInterfaceType) { + return ImmutableSet.copyOf(graphQLSchema.getImplementations((GraphQLInterfaceType) type)); + } else if (type instanceof GraphQLUnionType) { + List unionTypes = ((GraphQLUnionType) type).getTypes(); + return ImmutableSet.copyOf(ImmutableKit.map(unionTypes, GraphQLObjectType.class::cast)); + } else { + return assertShouldNeverHappen(); + } + } + + private static class PossibleMerger { + ExecutableNormalizedField parent; + String resultKey; + + public PossibleMerger(ExecutableNormalizedField parent, String resultKey) { + this.parent = parent; + this.resultKey = resultKey; + } + } + + private static class CollectedField { + Field field; + Set objectTypes; + GraphQLCompositeType astTypeCondition; + NormalizedDeferredExecution deferredExecution; + + public CollectedField(Field field, Set objectTypes, GraphQLCompositeType astTypeCondition, NormalizedDeferredExecution deferredExecution) { + this.field = field; + this.objectTypes = objectTypes; + this.astTypeCondition = astTypeCondition; + this.deferredExecution = deferredExecution; + } + } + + private static class CollectedFieldGroup { + Set objectTypes; + Set fields; + Set deferredExecutions; + + public CollectedFieldGroup(Set fields, Set objectTypes, Set deferredExecutions) { + this.fields = fields; + this.objectTypes = objectTypes; + this.deferredExecutions = deferredExecutions; + } + } + } + +} diff --git a/src/main/java/graphql/normalized/ExecutableNormalizedOperationToAstCompiler.java b/src/main/java/graphql/normalized/ExecutableNormalizedOperationToAstCompiler.java new file mode 100644 index 0000000000..f71e1a30e8 --- /dev/null +++ b/src/main/java/graphql/normalized/ExecutableNormalizedOperationToAstCompiler.java @@ -0,0 +1,473 @@ +package graphql.normalized; + +import com.google.common.collect.ImmutableList; +import graphql.Assert; +import graphql.Directives; +import graphql.ExperimentalApi; +import graphql.PublicApi; +import graphql.execution.directives.QueryAppliedDirective; +import graphql.execution.directives.QueryDirectives; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.Document; +import graphql.language.Field; +import graphql.language.InlineFragment; +import graphql.language.OperationDefinition; +import graphql.language.Selection; +import graphql.language.SelectionSet; +import graphql.language.StringValue; +import graphql.language.TypeName; +import graphql.normalized.incremental.NormalizedDeferredExecution; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLUnmodifiedType; +import graphql.util.LinkedHashMapFactory; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.Argument.newArgument; +import static graphql.language.Field.newField; +import static graphql.language.InlineFragment.newInlineFragment; +import static graphql.language.SelectionSet.newSelectionSet; +import static graphql.language.TypeName.newTypeName; +import static graphql.normalized.ArgumentMaker.createArguments; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; + +/** + * This class can take a list of {@link ExecutableNormalizedField}s and compiling out a + * normalised operation {@link Document} that would represent how those fields + * may be executed. + *

+ * This is essentially the reverse of {@link ExecutableNormalizedOperationFactory} which takes + * operation text and makes {@link ExecutableNormalizedField}s from it, this takes {@link ExecutableNormalizedField}s + * and makes operation text from it. + *

+ * You could for example send that operation text onto to some other graphql server if it + * has the same schema as the one provided. + */ +@PublicApi +public class ExecutableNormalizedOperationToAstCompiler { + + /** + * The result is a {@link Document} and a map of variables + * that would go with that document. + */ + public static class CompilerResult { + private final Document document; + private final Map variables; + + public CompilerResult(Document document, Map variables) { + this.document = document; + this.variables = variables; + } + + public Document getDocument() { + return document; + } + + public Map getVariables() { + return variables; + } + } + + /** + * This will compile an operation text {@link Document} with possibly variables from the given {@link ExecutableNormalizedField}s + *

+ * The {@link VariablePredicate} is used called to decide if the given argument values should be made into a variable + * OR inlined into the operation text as a graphql literal. + * + * @param schema the graphql schema to use + * @param operationKind the kind of operation + * @param operationName the name of the operation to use + * @param topLevelFields the top level {@link ExecutableNormalizedField}s to start from + * @param variablePredicate the variable predicate that decides if arguments turn into variables or not during compilation + * + * @return a {@link CompilerResult} object + */ + public static CompilerResult compileToDocument(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind, + @Nullable String operationName, + @NonNull List topLevelFields, + @Nullable VariablePredicate variablePredicate) { + return compileToDocument(schema, operationKind, operationName, topLevelFields, LinkedHashMapFactory.of(), variablePredicate); + } + + /** + * This will compile an operation text {@link Document} with possibly variables from the given {@link ExecutableNormalizedField}s + *

+ * The {@link VariablePredicate} is used called to decide if the given argument values should be made into a variable + * OR inlined into the operation text as a graphql literal. + * + * @param schema the graphql schema to use + * @param operationKind the kind of operation + * @param operationName the name of the operation to use + * @param topLevelFields the top level {@link ExecutableNormalizedField}s to start from + * @param normalizedFieldToQueryDirectives the map of normalized field to query directives + * @param variablePredicate the variable predicate that decides if arguments turn into variables or not during compilation + * + * @return a {@link CompilerResult} object + */ + public static CompilerResult compileToDocument(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind, + @Nullable String operationName, + @NonNull List topLevelFields, + @NonNull Map normalizedFieldToQueryDirectives, + @Nullable VariablePredicate variablePredicate) { + return compileToDocument(schema, operationKind, operationName, topLevelFields, normalizedFieldToQueryDirectives, variablePredicate, false); + } + + + /** + * This will compile an operation text {@link Document} with possibly variables from the given {@link ExecutableNormalizedField}s, with support for the experimental @defer directive. + *

+ * The {@link VariablePredicate} is used called to decide if the given argument values should be made into a variable + * OR inlined into the operation text as a graphql literal. + * + * @param schema the graphql schema to use + * @param operationKind the kind of operation + * @param operationName the name of the operation to use + * @param topLevelFields the top level {@link ExecutableNormalizedField}s to start from + * @param variablePredicate the variable predicate that decides if arguments turn into variables or not during compilation + * + * @return a {@link CompilerResult} object + * + * @see ExecutableNormalizedOperationToAstCompiler#compileToDocument(GraphQLSchema, OperationDefinition.Operation, String, List, VariablePredicate) + */ + @ExperimentalApi + public static CompilerResult compileToDocumentWithDeferSupport(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind, + @Nullable String operationName, + @NonNull List topLevelFields, + @Nullable VariablePredicate variablePredicate + ) { + return compileToDocumentWithDeferSupport(schema, operationKind, operationName, topLevelFields, LinkedHashMapFactory.of(), variablePredicate); + } + + /** + * This will compile an operation text {@link Document} with possibly variables from the given {@link ExecutableNormalizedField}s, with support for the experimental @defer directive. + *

+ * The {@link VariablePredicate} is used called to decide if the given argument values should be made into a variable + * OR inlined into the operation text as a graphql literal. + * + * @param schema the graphql schema to use + * @param operationKind the kind of operation + * @param operationName the name of the operation to use + * @param topLevelFields the top level {@link ExecutableNormalizedField}s to start from + * @param normalizedFieldToQueryDirectives the map of normalized field to query directives + * @param variablePredicate the variable predicate that decides if arguments turn into variables or not during compilation + * + * @return a {@link CompilerResult} object + * + * @see ExecutableNormalizedOperationToAstCompiler#compileToDocument(GraphQLSchema, OperationDefinition.Operation, String, List, Map, VariablePredicate) + */ + @ExperimentalApi + public static CompilerResult compileToDocumentWithDeferSupport(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind, + @Nullable String operationName, + @NonNull List topLevelFields, + @NonNull Map normalizedFieldToQueryDirectives, + @Nullable VariablePredicate variablePredicate + ) { + return compileToDocument(schema, operationKind, operationName, topLevelFields, normalizedFieldToQueryDirectives, variablePredicate, true); + } + + private static CompilerResult compileToDocument(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind, + @Nullable String operationName, + @NonNull List topLevelFields, + @NonNull Map normalizedFieldToQueryDirectives, + @Nullable VariablePredicate variablePredicate, + boolean deferSupport) { + GraphQLObjectType operationType = getOperationType(schema, operationKind); + + VariableAccumulator variableAccumulator = new VariableAccumulator(variablePredicate); + List> selections = subselectionsForNormalizedField(schema, operationType.getName(), topLevelFields, normalizedFieldToQueryDirectives, variableAccumulator, deferSupport); + SelectionSet selectionSet = new SelectionSet(selections); + + OperationDefinition.Builder definitionBuilder = OperationDefinition.newOperationDefinition() + .name(operationName) + .operation(operationKind) + .selectionSet(selectionSet); + + definitionBuilder.variableDefinitions(variableAccumulator.getVariableDefinitions()); + + return new CompilerResult( + Document.newDocument() + .definition(definitionBuilder.build()) + .build(), + variableAccumulator.getVariablesMap() + ); + } + + private static List> subselectionsForNormalizedField(GraphQLSchema schema, + @NonNull String parentOutputType, + List executableNormalizedFields, + @NonNull Map normalizedFieldToQueryDirectives, + VariableAccumulator variableAccumulator, + boolean deferSupport) { + if (deferSupport) { + return subselectionsForNormalizedFieldWithDeferSupport(schema, parentOutputType, executableNormalizedFields, normalizedFieldToQueryDirectives, variableAccumulator); + } else { + return subselectionsForNormalizedFieldNoDeferSupport(schema, parentOutputType, executableNormalizedFields, normalizedFieldToQueryDirectives, variableAccumulator); + } + } + + private static List> subselectionsForNormalizedFieldNoDeferSupport(GraphQLSchema schema, + @NonNull String parentOutputType, + List executableNormalizedFields, + @NonNull Map normalizedFieldToQueryDirectives, + VariableAccumulator variableAccumulator) { + ImmutableList.Builder> selections = ImmutableList.builder(); + + // All conditional fields go here instead of directly to selections, so they can be grouped together + // in the same inline fragment in the output + Map> fieldsByTypeCondition = new LinkedHashMap<>(); + + for (ExecutableNormalizedField nf : executableNormalizedFields) { + if (nf.isConditional(schema)) { + selectionForNormalizedField(schema, nf, normalizedFieldToQueryDirectives, variableAccumulator, false) + .forEach((objectTypeName, field) -> + fieldsByTypeCondition + .computeIfAbsent(objectTypeName, ignored -> new ArrayList<>()) + .add(field)); + } else { + selections.add(selectionForNormalizedField(schema, parentOutputType, nf, normalizedFieldToQueryDirectives, variableAccumulator, false)); + } + } + + fieldsByTypeCondition.forEach((objectTypeName, fields) -> { + TypeName typeName = newTypeName(objectTypeName).build(); + InlineFragment inlineFragment = newInlineFragment() + .typeCondition(typeName) + .selectionSet(selectionSet(fields)) + .build(); + selections.add(inlineFragment); + }); + + return selections.build(); + } + + + private static List> subselectionsForNormalizedFieldWithDeferSupport(GraphQLSchema schema, + @NonNull String parentOutputType, + List executableNormalizedFields, + @NonNull Map normalizedFieldToQueryDirectives, + VariableAccumulator variableAccumulator) { + ImmutableList.Builder> selections = ImmutableList.builder(); + + // All conditional and deferred fields go here instead of directly to selections, so they can be grouped together + // in the same inline fragment in the output + // + Map> fieldsByFragmentDetails = new LinkedHashMap<>(); + + for (ExecutableNormalizedField nf : executableNormalizedFields) { + LinkedHashSet deferredExecutions = nf.getDeferredExecutions(); + + if (nf.isConditional(schema)) { + selectionForNormalizedField(schema, nf, normalizedFieldToQueryDirectives, variableAccumulator, true) + .forEach((objectTypeName, field) -> { + if (deferredExecutions == null || deferredExecutions.isEmpty()) { + fieldsByFragmentDetails + .computeIfAbsent(new ExecutionFragmentDetails(objectTypeName, null), ignored -> new ArrayList<>()) + .add(field); + } else { + deferredExecutions.forEach(deferredExecution -> { + fieldsByFragmentDetails + .computeIfAbsent(new ExecutionFragmentDetails(objectTypeName, deferredExecution), ignored -> new ArrayList<>()) + .add(field); + }); + } + }); + + } else if (deferredExecutions != null && !deferredExecutions.isEmpty()) { + Field field = selectionForNormalizedField(schema, parentOutputType, nf, normalizedFieldToQueryDirectives, variableAccumulator, true); + + deferredExecutions.forEach(deferredExecution -> { + fieldsByFragmentDetails + .computeIfAbsent(new ExecutionFragmentDetails(null, deferredExecution), ignored -> new ArrayList<>()) + .add(field); + }); + } else { + selections.add(selectionForNormalizedField(schema, parentOutputType, nf, normalizedFieldToQueryDirectives, variableAccumulator, true)); + } + } + + fieldsByFragmentDetails.forEach((typeAndDeferPair, fields) -> { + InlineFragment.Builder fragmentBuilder = newInlineFragment() + .selectionSet(selectionSet(fields)); + + if (typeAndDeferPair.typeName != null) { + TypeName typeName = newTypeName(typeAndDeferPair.typeName).build(); + fragmentBuilder.typeCondition(typeName); + } + + if (typeAndDeferPair.deferredExecution != null) { + Directive.Builder deferBuilder = Directive.newDirective().name(Directives.DeferDirective.getName()); + + if (typeAndDeferPair.deferredExecution.getLabel() != null) { + deferBuilder.argument(newArgument().name("label").value(StringValue.of(typeAndDeferPair.deferredExecution.getLabel())).build()); + } + + fragmentBuilder.directive(deferBuilder.build()); + } + + + selections.add(fragmentBuilder.build()); + }); + + return selections.build(); + } + + /** + * @return Map of object type names to list of fields + */ + private static Map selectionForNormalizedField(GraphQLSchema schema, + ExecutableNormalizedField executableNormalizedField, + @NonNull Map normalizedFieldToQueryDirectives, + VariableAccumulator variableAccumulator, + boolean deferSupport) { + Map groupedFields = new LinkedHashMap<>(); + + for (String objectTypeName : executableNormalizedField.getObjectTypeNames()) { + groupedFields.put(objectTypeName, selectionForNormalizedField(schema, objectTypeName, executableNormalizedField, normalizedFieldToQueryDirectives, variableAccumulator, deferSupport)); + } + + return groupedFields; + } + + /** + * @return Map of object type names to list of fields + */ + private static Field selectionForNormalizedField(GraphQLSchema schema, + String objectTypeName, + ExecutableNormalizedField executableNormalizedField, + @NonNull Map normalizedFieldToQueryDirectives, + VariableAccumulator variableAccumulator, + boolean deferSupport) { + final List> subSelections; + if (executableNormalizedField.getChildren().isEmpty()) { + subSelections = emptyList(); + } else { + GraphQLFieldDefinition fieldDef = getFieldDefinition(schema, objectTypeName, executableNormalizedField); + GraphQLUnmodifiedType fieldOutputType = unwrapAll(fieldDef.getType()); + + subSelections = subselectionsForNormalizedField( + schema, + fieldOutputType.getName(), + executableNormalizedField.getChildren(), + normalizedFieldToQueryDirectives, + variableAccumulator, + deferSupport + ); + } + + SelectionSet selectionSet = selectionSetOrNullIfEmpty(subSelections); + List arguments = createArguments(executableNormalizedField, variableAccumulator); + + QueryDirectives queryDirectives = normalizedFieldToQueryDirectives.get(executableNormalizedField); + + Field.Builder builder = newField() + .name(executableNormalizedField.getFieldName()) + .alias(executableNormalizedField.getAlias()) + .selectionSet(selectionSet) + .arguments(arguments); + + List directives = buildDirectives(executableNormalizedField, queryDirectives, variableAccumulator); + return builder + .directives(directives) + .build(); + } + + private static @NonNull List buildDirectives(ExecutableNormalizedField executableNormalizedField, QueryDirectives queryDirectives, VariableAccumulator variableAccumulator) { + if (queryDirectives == null || queryDirectives.getImmediateAppliedDirectivesByField().isEmpty()) { + return emptyList(); + } + return queryDirectives.getImmediateAppliedDirectivesByField().entrySet().stream() + .flatMap(entry -> entry.getValue().stream()) + .map(queryAppliedDirective -> buildDirective(executableNormalizedField, queryDirectives, queryAppliedDirective, variableAccumulator)) + .collect(Collectors.toList()); + } + + private static Directive buildDirective(ExecutableNormalizedField executableNormalizedField, QueryDirectives queryDirectives, QueryAppliedDirective queryAppliedDirective, VariableAccumulator variableAccumulator) { + + List arguments = ArgumentMaker.createDirectiveArguments(executableNormalizedField, queryDirectives, queryAppliedDirective, variableAccumulator); + return Directive.newDirective() + .name(queryAppliedDirective.getName()) + .arguments(arguments).build(); + } + + @Nullable + private static SelectionSet selectionSetOrNullIfEmpty(List> selections) { + return selections.isEmpty() ? null : newSelectionSet().selections(selections).build(); + } + + private static SelectionSet selectionSet(List fields) { + return newSelectionSet().selections(fields).build(); + } + + + @NonNull + private static GraphQLFieldDefinition getFieldDefinition(GraphQLSchema schema, + String parentType, + ExecutableNormalizedField nf) { + return Introspection.getFieldDef(schema, (GraphQLCompositeType) schema.getType(parentType), nf.getName()); + } + + + @Nullable + private static GraphQLObjectType getOperationType(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind) { + switch (operationKind) { + case QUERY: + return schema.getQueryType(); + case MUTATION: + return schema.getMutationType(); + case SUBSCRIPTION: + return schema.getSubscriptionType(); + } + + return Assert.assertShouldNeverHappen("Unknown operation kind " + operationKind); + } + + /** + * Represents important execution details that can be associated with a fragment. + */ + private static class ExecutionFragmentDetails { + private final String typeName; + private final NormalizedDeferredExecution deferredExecution; + + public ExecutionFragmentDetails(String typeName, NormalizedDeferredExecution deferredExecution) { + this.typeName = typeName; + this.deferredExecution = deferredExecution; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ExecutionFragmentDetails that = (ExecutionFragmentDetails) o; + return Objects.equals(typeName, that.typeName) && Objects.equals(deferredExecution, that.deferredExecution); + } + + @Override + public int hashCode() { + return Objects.hash(typeName, deferredExecution); + } + } +} diff --git a/src/main/java/graphql/normalized/NormalizedInputValue.java b/src/main/java/graphql/normalized/NormalizedInputValue.java new file mode 100644 index 0000000000..c6f881fac0 --- /dev/null +++ b/src/main/java/graphql/normalized/NormalizedInputValue.java @@ -0,0 +1,144 @@ +package graphql.normalized; + +import graphql.Assert; +import graphql.PublicApi; +import graphql.language.Value; + +import java.util.Objects; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.Assert.assertValidName; +import static graphql.language.AstPrinter.printAst; + +/** + * An argument value with type information. + */ +@PublicApi +public class NormalizedInputValue { + private final String typeName; + private final Object value; + + public NormalizedInputValue(String typeName, Object value) { + this.typeName = assertValidTypeName(typeName); + this.value = value; + } + + private String assertValidTypeName(String typeName) { + assertValidName(unwrapAll(typeName)); + return typeName; + } + + private String unwrapAll(String typeName) { + String result = unwrapOne(typeName); + while (isWrapped(result)) { + result = unwrapOne(result); + } + return result; + } + + /** + * This can be a wrapped type: e.g. [String!]! + * + * @return the type name + */ + public String getTypeName() { + return typeName; + } + + /** + * @return the type name unwrapped of all list and non-null type wrapping + */ + public String getUnwrappedTypeName() { + return unwrapAll(typeName); + } + + /** + * Depending on the type it returns: + * Scalar or Enum: the ast literal of the Scalar. + * InputObject: the value is a map of field-name to NormalizedInputValue + * List of Scalar literal or Enum literal or NormalizedInput (or even List of List ..) + * + * @return the value + */ + public Object getValue() { + return value; + } + + + /** + * @return true if the input value type is a list or a non-nullable list + */ + public boolean isListLike() { + return typeName.startsWith("["); + } + + /** + * @return true if the input value type is non-nullable + */ + public boolean isNonNullable() { + return typeName.endsWith("!"); + } + + /** + * @return true if the input value type is nullable + */ + public boolean isNullable() { + return !isNonNullable(); + } + + private boolean isWrapped(String typeName) { + return typeName.endsWith("!") || isListOnly(typeName); + } + + private boolean isListOnly(String typeName) { + if (typeName.endsWith("!")) { + return false; + } + return typeName.startsWith("[") || typeName.endsWith("]"); + } + + private String unwrapOne(String typeName) { + assertNotNull(typeName); + Assert.assertTrue(!typeName.trim().isEmpty(), "We have an empty type name unwrapped"); + if (typeName.endsWith("!")) { + return typeName.substring(0, typeName.length() - 1); + } + if (isListOnly(typeName)) { + // nominally this will never be true - but better to be safe than sorry + assertTrue(typeName.startsWith("["), "We have a unbalanced list type string '%s'", typeName); + assertTrue(typeName.endsWith("]"), "We have a unbalanced list type string '%s'", typeName); + + return typeName.substring(1, typeName.length() - 1); + } + return typeName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NormalizedInputValue that = (NormalizedInputValue) o; + if (value instanceof Value && that.value instanceof Value) { + return Objects.equals(typeName, that.typeName) && Objects.equals(printAst((Value) value), printAst((Value) that.value)); + } + return Objects.equals(typeName, that.typeName) && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(typeName, value); + } + + @Override + public String toString() { + return "NormalizedInputValue{" + + "typeName='" + typeName + '\'' + + ", value=" + value + + '}'; + } +} diff --git a/src/main/java/graphql/normalized/ValueToVariableValueCompiler.java b/src/main/java/graphql/normalized/ValueToVariableValueCompiler.java new file mode 100644 index 0000000000..87144dcc42 --- /dev/null +++ b/src/main/java/graphql/normalized/ValueToVariableValueCompiler.java @@ -0,0 +1,138 @@ +package graphql.normalized; + +import graphql.AssertException; +import graphql.Internal; +import graphql.language.ArrayValue; +import graphql.language.BooleanValue; +import graphql.language.EnumValue; +import graphql.language.FloatValue; +import graphql.language.IntValue; +import graphql.language.NullValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.language.VariableDefinition; +import graphql.language.VariableReference; +import graphql.parser.Parser; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static java.util.stream.Collectors.toList; + +@Internal +public class ValueToVariableValueCompiler { + + static VariableValueWithDefinition normalizedInputValueToVariable(NormalizedInputValue normalizedInputValue, int queryVariableCount) { + Object variableValue = normalisedValueToVariableValue(normalizedInputValue); + String varName = getVarName(queryVariableCount); + return new VariableValueWithDefinition( + variableValue, + VariableDefinition.newVariableDefinition() + .name(varName) + .type(Parser.parseType(normalizedInputValue.getTypeName())) + .build(), + VariableReference.newVariableReference().name(varName).build()); + } + + @SuppressWarnings("unchecked") + @Nullable + static Object normalisedValueToVariableValue(Object maybeValue) { + Object variableValue; + if (maybeValue instanceof NormalizedInputValue) { + NormalizedInputValue normalizedInputValue = (NormalizedInputValue) maybeValue; + Object inputValue = normalizedInputValue.getValue(); + if (inputValue instanceof Value) { + variableValue = toVariableValue((Value) inputValue); + } else if (inputValue instanceof List) { + variableValue = normalisedValueToVariableValues((List) inputValue); + } else if (inputValue instanceof Map) { + variableValue = normalisedValueToVariableValues((Map) inputValue); + } else if (inputValue == null) { + variableValue = null; + } else { + throw new AssertException("Should never happen. Did not expect NormalizedInputValue.getValue() of type: " + maybeClass(inputValue)); + } + } else if (maybeValue instanceof Value) { + Value value = (Value) maybeValue; + variableValue = toVariableValue(value); + } else if (maybeValue instanceof List) { + variableValue = normalisedValueToVariableValues((List) maybeValue); + } else if (maybeValue instanceof Map) { + variableValue = normalisedValueToVariableValues((Map) maybeValue); + } else { + throw new AssertException("Should never happen. Did not expect type: " + maybeClass(maybeValue)); + } + return variableValue; + } + + private static List normalisedValueToVariableValues(List arrayValues) { + return arrayValues.stream() + .map(ValueToVariableValueCompiler::normalisedValueToVariableValue) + .collect(toList()); + } + + @NonNull + private static Map normalisedValueToVariableValues(Map objectMap) { + Map output = new LinkedHashMap<>(); + objectMap.forEach((k, v) -> { + Object value = normalisedValueToVariableValue(v); + output.put(k, value); + }); + return output; + } + + private static Map toVariableValue(ObjectValue objectValue) { + Map map = new LinkedHashMap<>(); + List objectFields = objectValue.getObjectFields(); + for (ObjectField objectField : objectFields) { + String objectFieldName = objectField.getName(); + Value objectFieldValue = objectField.getValue(); + map.put(objectFieldName, toVariableValue(objectFieldValue)); + } + return map; + } + + @NonNull + private static List toVariableValues(List arrayValues) { + // some values can be null (NullValue) and hence we can use Immutable Lists + return arrayValues.stream() + .map(ValueToVariableValueCompiler::toVariableValue) + .collect(toList()); + } + + @Nullable + private static Object toVariableValue(Value value) { + if (value instanceof ObjectValue) { + return toVariableValue((ObjectValue) value); + } else if (value instanceof ArrayValue) { + return toVariableValues(((ArrayValue) value).getValues()); + } else if (value instanceof StringValue) { + return ((StringValue) value).getValue(); + } else if (value instanceof FloatValue) { + return ((FloatValue) value).getValue(); + } else if (value instanceof IntValue) { + return ((IntValue) value).getValue(); + } else if (value instanceof BooleanValue) { + return ((BooleanValue) value).isValue(); + } else if (value instanceof EnumValue) { + return ((EnumValue) value).getName(); + } else if (value instanceof NullValue) { + return null; + } + throw new AssertException("Should never happen. Cannot handle node of type: " + maybeClass(value)); + } + + private static Object maybeClass(Object maybe) { + return maybe == null ? "null" : maybe.getClass(); + } + + private static String getVarName(int variableOrdinal) { + return "v" + variableOrdinal; + } + +} diff --git a/src/main/java/graphql/normalized/VariableAccumulator.java b/src/main/java/graphql/normalized/VariableAccumulator.java new file mode 100644 index 0000000000..08b3db4eb4 --- /dev/null +++ b/src/main/java/graphql/normalized/VariableAccumulator.java @@ -0,0 +1,70 @@ +package graphql.normalized; + +import graphql.Internal; +import graphql.execution.directives.QueryAppliedDirective; +import graphql.language.VariableDefinition; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static graphql.normalized.ValueToVariableValueCompiler.normalizedInputValueToVariable; + +/** + * This accumulator class decides on whether to create a variable for a query argument and if so it tracks what variables were made. + * The {@link ExecutableNormalizedOperationToAstCompiler} then uses all the variables when it compiles the final document. + */ +@Internal +public class VariableAccumulator { + + private final List valueWithDefinitions; + @Nullable + private final VariablePredicate variablePredicate; + + public VariableAccumulator(@Nullable VariablePredicate variablePredicate) { + this.variablePredicate = variablePredicate; + valueWithDefinitions = new ArrayList<>(); + } + + public boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, QueryAppliedDirective queryAppliedDirective, String argName, NormalizedInputValue normalizedInputValue) { + // when a variable is used on the argument to a query directive then the queryAppliedDirective will be nonnull. + // otherwise it must be a field argument + if (queryAppliedDirective != null) { + return variablePredicate != null && variablePredicate.shouldMakeVariable(executableNormalizedField, queryAppliedDirective, argName, normalizedInputValue); + } else { + return variablePredicate != null && variablePredicate.shouldMakeVariable(executableNormalizedField, argName, normalizedInputValue); + } + } + + public VariableValueWithDefinition accumulateVariable(NormalizedInputValue normalizedInputValue) { + VariableValueWithDefinition variableWithDefinition = normalizedInputValueToVariable(normalizedInputValue, getAccumulatedSize()); + valueWithDefinitions.add(variableWithDefinition); + return variableWithDefinition; + } + + public int getAccumulatedSize() { + return valueWithDefinitions.size(); + } + + /** + * @return the variable definitions that would go on the operation declaration + */ + public List getVariableDefinitions() { + return valueWithDefinitions.stream().map(VariableValueWithDefinition::getDefinition).collect(Collectors.toList()); + } + + /** + * @return the map of variable names to variable values + */ + public Map getVariablesMap() { + Map map = new LinkedHashMap<>(); + valueWithDefinitions.forEach(variableWithDefinition -> { + String name = variableWithDefinition.getDefinition().getName(); + map.put(name, variableWithDefinition.getValue()); + }); + return map; + } +} diff --git a/src/main/java/graphql/normalized/VariablePredicate.java b/src/main/java/graphql/normalized/VariablePredicate.java new file mode 100644 index 0000000000..a516c308ec --- /dev/null +++ b/src/main/java/graphql/normalized/VariablePredicate.java @@ -0,0 +1,42 @@ +package graphql.normalized; + +import graphql.PublicSpi; +import graphql.execution.directives.QueryAppliedDirective; + +/** + * This predicate indicates whether a variable should be made for this field argument OR whether it will be compiled + * into a graphql AST literal. + */ +@PublicSpi +public interface VariablePredicate { + /** + * Return true if a variable should be made for this field argument + * + * @param executableNormalizedField the field in question + * @param argName the argument on the field + * @param normalizedInputValue the input value for that argument + * + * @return true if a variable should be made + */ + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, + String argName, + NormalizedInputValue normalizedInputValue); + + /** + * Return true if a variable should be made for this query directive argument + * on the specified field + * + * @param executableNormalizedField the field in question + * @param queryAppliedDirective the query directive in question + * @param argName the argument on the directive + * @param normalizedInputValue the input value for that argument + * + * @return true if a variable should be made + */ + default boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, + QueryAppliedDirective queryAppliedDirective, + String argName, + NormalizedInputValue normalizedInputValue) { + return false; + } +} diff --git a/src/main/java/graphql/normalized/VariableValueWithDefinition.java b/src/main/java/graphql/normalized/VariableValueWithDefinition.java new file mode 100644 index 0000000000..39950b8786 --- /dev/null +++ b/src/main/java/graphql/normalized/VariableValueWithDefinition.java @@ -0,0 +1,30 @@ +package graphql.normalized; + +import graphql.Internal; +import graphql.language.VariableDefinition; +import graphql.language.VariableReference; + +@Internal +public class VariableValueWithDefinition { + private final Object value; + private final VariableDefinition definition; + private final VariableReference variableReference; + + public VariableValueWithDefinition(Object value, VariableDefinition definition, VariableReference variableReference) { + this.value = value; + this.definition = definition; + this.variableReference = variableReference; + } + + public Object getValue() { + return value; + } + + public VariableDefinition getDefinition() { + return definition; + } + + public VariableReference getVariableReference() { + return variableReference; + } +} diff --git a/src/main/java/graphql/normalized/incremental/NormalizedDeferredExecution.java b/src/main/java/graphql/normalized/incremental/NormalizedDeferredExecution.java new file mode 100644 index 0000000000..2eab7b5044 --- /dev/null +++ b/src/main/java/graphql/normalized/incremental/NormalizedDeferredExecution.java @@ -0,0 +1,129 @@ +package graphql.normalized.incremental; + +import graphql.ExperimentalApi; +import graphql.schema.GraphQLObjectType; +import org.jspecify.annotations.Nullable; + +import java.util.Set; + +/** + * Represents details about the defer execution that can be associated with a {@link graphql.normalized.ExecutableNormalizedField}. + * + * Taking this schema as an example: + *
+ *     type Query { animal: Animal }
+ *     interface Animal { name: String, age: Int }
+ *     type Cat implements Animal { name: String, age: Int }
+ *     type Dog implements Animal { name: String, age: Int }
+ * 
+ * + * An ENF can be associated with multiple `NormalizedDeferredExecution`s + * + * For example, this query: + *
+ *     query MyQuery {
+ *         animal {
+ *             ... @defer {
+ *                 name
+ *             }
+ *             ... @defer {
+ *                 name
+ *             }
+ *         }
+ *     }
+ * 
+ * + * Would result in one ENF (name) associated with 2 `NormalizedDeferredExecution` instances. This is relevant for the execution + * since the field would have to be included in 2 incremental payloads. (I know, there's some duplication here, but + * this is the current state of the spec. There are some discussions happening around de-duplicating data in scenarios + * like this, so this behaviour might change in the future). + * + * A `NormalizedDeferredExecution` may be associated with a list of possible types + * + * For example, this query: + *
+ *     query MyQuery {
+ *         animal {
+ *             ... @defer {
+ *                 name
+ *             }
+ *         }
+ *     }
+ * 
+ * results in a `NormalizedDeferredExecution` with no label and possible types [Dog, Cat] + * + * A `NormalizedDeferredExecution` may be associated with specific types + * For example, this query: + *
+ *     query MyQuery {
+ *         animal {
+ *             ... on Cat @defer {
+ *                 name
+ *             }
+ *             ... on Dog {
+ *                 name
+ *             }
+ *         }
+ *     }
+ * 
+ * results in a single ENF (name) associated with a `NormalizedDeferredExecution` with only "Cat" as a possible type. This means + * that, at execution time, `name` should be deferred only if the return object is a "Cat" (but not a if it is a "Dog"). + * + * ENFs associated with the same instance of `NormalizedDeferredExecution` will be resolved in the same incremental response payload + * For example, take these queries: + * + *
+ *     query Query1 {
+ *         animal {
+ *             ... @defer {
+ *                 name
+ *             }
+ *             ... @defer {
+ *                 age
+ *             }
+ *         }
+ *     }
+ *
+ *     query Query2 {
+ *         animal {
+ *             ... @defer {
+ *                 name
+ *                 age
+ *             }
+ *         }
+ *     }
+ * 
+ * + * In `Query1`, the ENFs name and age are associated with different instances of `NormalizedDeferredExecution`. This means that, + * during execution, `name` and `age` can be delivered at different times (if name is resolved faster, it will be + * delivered first, and vice-versa). + * In `Query2` the fields will share the same instance of `NormalizedDeferredExecution`. This ensures that, at execution time, the + * fields are guaranteed to be delivered together. In other words, execution should wait until the slowest field resolves + * and deliver both fields at the same time. + * + */ +@ExperimentalApi +public class NormalizedDeferredExecution { + private final String label; + private final Set possibleTypes; + + public NormalizedDeferredExecution(@Nullable String label, Set possibleTypes) { + this.label = label; + this.possibleTypes = possibleTypes; + } + + /** + * @return the label associated with this defer declaration + */ + @Nullable + public String getLabel() { + return label; + } + + /** + * @return the concrete object types that are associated with this defer execution + */ + public Set getPossibleTypes() { + return possibleTypes; + } +} diff --git a/src/main/java/graphql/normalized/nf/NormalizedDocument.java b/src/main/java/graphql/normalized/nf/NormalizedDocument.java new file mode 100644 index 0000000000..6bb306fa50 --- /dev/null +++ b/src/main/java/graphql/normalized/nf/NormalizedDocument.java @@ -0,0 +1,47 @@ +package graphql.normalized.nf; + +import graphql.Assert; +import graphql.ExperimentalApi; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; + +@ExperimentalApi +public class NormalizedDocument { + + private final List normalizedOperations; + + public NormalizedDocument(List normalizedOperations) { + this.normalizedOperations = normalizedOperations; + } + + public List getNormalizedOperations() { + return normalizedOperations; + } + + public NormalizedOperation getSingleNormalizedOperation() { + Assert.assertTrue(normalizedOperations.size() == 1, "Expecting a single normalized operation"); + return normalizedOperations.get(0).getNormalizedOperation(); + } + + public static class NormalizedOperationWithAssumedSkipIncludeVariables { + + Map assumedSkipIncludeVariables; + NormalizedOperation normalizedOperation; + + public NormalizedOperationWithAssumedSkipIncludeVariables(@Nullable Map assumedSkipIncludeVariables, NormalizedOperation normalizedOperation) { + this.assumedSkipIncludeVariables = assumedSkipIncludeVariables; + this.normalizedOperation = normalizedOperation; + } + + public Map getAssumedSkipIncludeVariables() { + return assumedSkipIncludeVariables; + } + + public NormalizedOperation getNormalizedOperation() { + return normalizedOperation; + } + } +} + diff --git a/src/main/java/graphql/normalized/nf/NormalizedDocumentFactory.java b/src/main/java/graphql/normalized/nf/NormalizedDocumentFactory.java new file mode 100644 index 0000000000..0d5c5c77b1 --- /dev/null +++ b/src/main/java/graphql/normalized/nf/NormalizedDocumentFactory.java @@ -0,0 +1,683 @@ +package graphql.normalized.nf; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import graphql.Assert; +import graphql.ExperimentalApi; +import graphql.GraphQLContext; +import graphql.collect.ImmutableKit; +import graphql.execution.AbortExecutionException; +import graphql.execution.MergedField; +import graphql.execution.conditional.ConditionalNodes; +import graphql.execution.directives.QueryDirectives; +import graphql.introspection.Introspection; +import graphql.language.Directive; +import graphql.language.Document; +import graphql.language.Field; +import graphql.language.FragmentDefinition; +import graphql.language.FragmentSpread; +import graphql.language.InlineFragment; +import graphql.language.NodeUtil; +import graphql.language.OperationDefinition; +import graphql.language.Selection; +import graphql.language.SelectionSet; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphQLUnmodifiedType; +import graphql.schema.impl.SchemaUtil; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.collect.ImmutableKit.map; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; +import static graphql.util.FpKit.filterSet; +import static graphql.util.FpKit.groupingBy; +import static graphql.util.FpKit.intersection; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; + +@ExperimentalApi +public class NormalizedDocumentFactory { + + public static class Options { + + + private final GraphQLContext graphQLContext; + private final Locale locale; + private final int maxChildrenDepth; + private final int maxFieldsCount; + + private final boolean deferSupport; + + /** + * The default max fields count is 100,000. + * This is big enough for even very large queries, but + * can be changed via {#setDefaultOptions + */ + public static final int DEFAULT_MAX_FIELDS_COUNT = 100_000; + private static Options defaultOptions = new Options(GraphQLContext.getDefault(), + Locale.getDefault(), + Integer.MAX_VALUE, + DEFAULT_MAX_FIELDS_COUNT, + false); + + private Options(GraphQLContext graphQLContext, + Locale locale, + int maxChildrenDepth, + int maxFieldsCount, + boolean deferSupport) { + this.graphQLContext = graphQLContext; + this.locale = locale; + this.maxChildrenDepth = maxChildrenDepth; + this.deferSupport = deferSupport; + this.maxFieldsCount = maxFieldsCount; + } + + /** + * Sets new default Options used when creating instances of {@link NormalizedDocument}. + * + * @param options new default options + */ + public static void setDefaultOptions(Options options) { + defaultOptions = Assert.assertNotNull(options); + } + + + /** + * Returns the default options used when creating instances of {@link NormalizedDocument}. + * + * @return the default options + */ + public static Options defaultOptions() { + return defaultOptions; + } + + /** + * Locale to use when parsing the query. + *

+ * e.g. can be passed to {@link graphql.schema.Coercing} for parsing. + * + * @param locale the locale to use + * + * @return new options object to use + */ + public Options locale(Locale locale) { + return new Options(this.graphQLContext, locale, this.maxChildrenDepth, this.maxFieldsCount, this.deferSupport); + } + + /** + * Context object to use when parsing the operation. + *

+ * Can be used to intercept input values e.g. using {@link graphql.execution.values.InputInterceptor}. + * + * @param graphQLContext the context to use + * + * @return new options object to use + */ + public Options graphQLContext(GraphQLContext graphQLContext) { + return new Options(graphQLContext, this.locale, this.maxChildrenDepth, this.maxFieldsCount, this.deferSupport); + } + + /** + * Controls the maximum depth of the operation. Can be used to prevent + * against malicious operations. + * + * @param maxChildrenDepth the max depth + * + * @return new options object to use + */ + public Options maxChildrenDepth(int maxChildrenDepth) { + return new Options(this.graphQLContext, this.locale, maxChildrenDepth, this.maxFieldsCount, this.deferSupport); + } + + /** + * Controls the maximum number of ENFs created. Can be used to prevent + * against malicious operations. + * + * @param maxFieldsCount the max number of ENFs created + * + * @return new options object to use + */ + public Options maxFieldsCount(int maxFieldsCount) { + return new Options(this.graphQLContext, this.locale, this.maxChildrenDepth, maxFieldsCount, this.deferSupport); + } + + /** + * Controls whether defer execution is supported when creating instances of {@link NormalizedDocument}. + * + * @param deferSupport true to enable support for defer + * + * @return new options object to use + */ + @ExperimentalApi + public Options deferSupport(boolean deferSupport) { + return new Options(this.graphQLContext, this.locale, this.maxChildrenDepth, this.maxFieldsCount, deferSupport); + } + + /** + * @return context to use during operation parsing + * + * @see #graphQLContext(GraphQLContext) + */ + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + /** + * @return locale to use during operation parsing + * + * @see #locale(Locale) + */ + public Locale getLocale() { + return locale; + } + + /** + * @return maximum children depth before aborting parsing + * + * @see #maxChildrenDepth(int) + */ + public int getMaxChildrenDepth() { + return maxChildrenDepth; + } + + public int getMaxFieldsCount() { + return maxFieldsCount; + } + + } + + private static final ConditionalNodes conditionalNodes = new ConditionalNodes(); + + private NormalizedDocumentFactory() { + + } + + public static NormalizedDocument createNormalizedDocument( + GraphQLSchema graphQLSchema, + Document document) { + return createNormalizedDocument( + graphQLSchema, + document, + Options.defaultOptions()); + } + + + public static NormalizedDocument createNormalizedDocument(GraphQLSchema graphQLSchema, + Document document, + Options options) { + return new NormalizedDocumentFactoryImpl( + graphQLSchema, + document, + options + ).createNormalizedQueryImpl(); + } + + + private static class NormalizedDocumentFactoryImpl { + private final GraphQLSchema graphQLSchema; + private final Document document; + private final Options options; + private final Map fragments; + + private final List possibleMergerList = new ArrayList<>(); + + private ImmutableListMultimap.Builder fieldToNormalizedField = ImmutableListMultimap.builder(); + private ImmutableMap.Builder normalizedFieldToMergedField = ImmutableMap.builder(); + private ImmutableMap.Builder normalizedFieldToQueryDirectives = ImmutableMap.builder(); + private ImmutableListMultimap.Builder coordinatesToNormalizedFields = ImmutableListMultimap.builder(); + + private int fieldCount = 0; + private int maxDepthSeen = 0; + + private final List rootEnfs = new ArrayList<>(); + + private final Set skipIncludeVariableNames = new LinkedHashSet<>(); + + private Map assumedSkipIncludeVariableValues; + + private NormalizedDocumentFactoryImpl( + GraphQLSchema graphQLSchema, + Document document, + Options options + ) { + this.graphQLSchema = graphQLSchema; + this.document = document; + this.options = options; + this.fragments = NodeUtil.getFragmentsByName(document); + } + + /** + * Creates a new NormalizedDocument for the provided query + */ + private NormalizedDocument createNormalizedQueryImpl() { + List normalizedOperations = new ArrayList<>(); + for (OperationDefinition operationDefinition : document.getDefinitionsOfType(OperationDefinition.class)) { + + assumedSkipIncludeVariableValues = null; + skipIncludeVariableNames.clear(); + NormalizedOperation normalizedOperation = createNormalizedOperation(operationDefinition); + + if (skipIncludeVariableNames.size() == 0) { + normalizedOperations.add(new NormalizedDocument.NormalizedOperationWithAssumedSkipIncludeVariables(null, normalizedOperation)); + } else { + int combinations = (int) Math.pow(2, skipIncludeVariableNames.size()); + for (int i = 0; i < combinations; i++) { + assumedSkipIncludeVariableValues = new LinkedHashMap<>(); + int variableIndex = 0; + for (String variableName : skipIncludeVariableNames) { + assumedSkipIncludeVariableValues.put(variableName, (i & (1 << variableIndex++)) != 0); + } + NormalizedOperation operationWithAssumedVariables = createNormalizedOperation(operationDefinition); + normalizedOperations.add(new NormalizedDocument.NormalizedOperationWithAssumedSkipIncludeVariables(assumedSkipIncludeVariableValues, operationWithAssumedVariables)); + } + } + } + + return new NormalizedDocument( + normalizedOperations + ); + } + + private NormalizedOperation createNormalizedOperation(OperationDefinition operationDefinition) { + this.rootEnfs.clear(); + this.fieldCount = 0; + this.maxDepthSeen = 0; + this.possibleMergerList.clear(); + fieldToNormalizedField = ImmutableListMultimap.builder(); + normalizedFieldToMergedField = ImmutableMap.builder(); + normalizedFieldToQueryDirectives = ImmutableMap.builder(); + coordinatesToNormalizedFields = ImmutableListMultimap.builder(); + + buildNormalizedFieldsRecursively(null, operationDefinition, null, 0); + + for (PossibleMerger possibleMerger : possibleMergerList) { + List childrenWithSameResultKey = possibleMerger.parent.getChildrenWithSameResultKey(possibleMerger.resultKey); + NormalizedFieldsMerger.merge(possibleMerger.parent, childrenWithSameResultKey, graphQLSchema); + } + + NormalizedOperation normalizedOperation = new NormalizedOperation( + operationDefinition.getOperation(), + operationDefinition.getName(), + new ArrayList<>(rootEnfs), + fieldToNormalizedField.build(), + normalizedFieldToMergedField.build(), + normalizedFieldToQueryDirectives.build(), + coordinatesToNormalizedFields.build(), + fieldCount, + maxDepthSeen + ); + return normalizedOperation; + } + + + private void captureMergedField(NormalizedField enf, MergedField mergedFld) { +// // QueryDirectivesImpl is a lazy object and only computes itself when asked for +// QueryDirectives queryDirectives = new QueryDirectivesImpl(mergedFld, graphQLSchema, coercedVariableValues.toMap(), options.getGraphQLContext(), options.getLocale()); +// normalizedFieldToQueryDirectives.put(enf, queryDirectives); + normalizedFieldToMergedField.put(enf, mergedFld); + } + + private void buildNormalizedFieldsRecursively(@Nullable NormalizedField normalizedField, + @Nullable OperationDefinition operationDefinition, + @Nullable ImmutableList fieldAndAstParents, + int curLevel) { + if (this.maxDepthSeen < curLevel) { + this.maxDepthSeen = curLevel; + checkMaxDepthExceeded(curLevel); + } + Set possibleObjects; + List collectedFields; + + // special handling for the root selection Set + if (normalizedField == null) { + GraphQLObjectType rootType = SchemaUtil.getOperationRootType(graphQLSchema, operationDefinition); + possibleObjects = ImmutableSet.of(rootType); + collectedFields = new ArrayList<>(); + collectFromSelectionSet(operationDefinition.getSelectionSet(), collectedFields, rootType, possibleObjects); + } else { + List fieldDefs = normalizedField.getFieldDefinitions(graphQLSchema); + possibleObjects = resolvePossibleObjects(fieldDefs); + if (possibleObjects.isEmpty()) { + return; + } + collectedFields = new ArrayList<>(); + for (CollectedField fieldAndAstParent : fieldAndAstParents) { + if (fieldAndAstParent.field.getSelectionSet() == null) { + continue; + } + // the AST parent comes from the previous collect from selection set call + // and is the type to which the field belongs (the container type of the field) and output type + // of the field needs to be determined based on the field name + GraphQLFieldDefinition fieldDefinition = Introspection.getFieldDef(graphQLSchema, fieldAndAstParent.astTypeCondition, fieldAndAstParent.field.getName()); + // it must a composite type, because the field has a selection set + GraphQLCompositeType selectionSetType = (GraphQLCompositeType) unwrapAll(fieldDefinition.getType()); + this.collectFromSelectionSet(fieldAndAstParent.field.getSelectionSet(), + collectedFields, + selectionSetType, + possibleObjects + ); + } + } + + Map> fieldsByName = fieldsByResultKey(collectedFields); + ImmutableList.Builder resultNFs = ImmutableList.builder(); + ImmutableListMultimap.Builder normalizedFieldToAstFields = ImmutableListMultimap.builder(); + createNFs(resultNFs, fieldsByName, normalizedFieldToAstFields, curLevel + 1, normalizedField); + + ImmutableList nextLevelChildren = resultNFs.build(); + ImmutableListMultimap nextLevelNormalizedFieldToAstFields = normalizedFieldToAstFields.build(); + + for (NormalizedField childENF : nextLevelChildren) { + if (normalizedField == null) { + // all root ENFs don't have a parent, but are collected in the rootEnfs list + rootEnfs.add(childENF); + } else { + normalizedField.addChild(childENF); + } + ImmutableList childFieldAndAstParents = nextLevelNormalizedFieldToAstFields.get(childENF); + + MergedField mergedField = newMergedField(childFieldAndAstParents); + captureMergedField(childENF, mergedField); + + updateFieldToNFMap(childENF, childFieldAndAstParents); + updateCoordinatedToNFMap(childENF); + + // recursive call + buildNormalizedFieldsRecursively(childENF, + null, + childFieldAndAstParents, + curLevel + 1); + } + } + + private void checkMaxDepthExceeded(int depthSeen) { + if (depthSeen > this.options.getMaxChildrenDepth()) { + throw new AbortExecutionException("Maximum query depth exceeded. " + depthSeen + " > " + this.options.getMaxChildrenDepth()); + } + } + + private static MergedField newMergedField(ImmutableList fieldAndAstParents) { + return MergedField.newMergedField(map(fieldAndAstParents, fieldAndAstParent -> fieldAndAstParent.field)).build(); + } + + private void updateFieldToNFMap(NormalizedField NormalizedField, + ImmutableList mergedField) { + for (CollectedField astField : mergedField) { + fieldToNormalizedField.put(astField.field, NormalizedField); + } + } + + private void updateCoordinatedToNFMap(NormalizedField topLevel) { + for (String objectType : topLevel.getObjectTypeNames()) { + FieldCoordinates coordinates = FieldCoordinates.coordinates(objectType, topLevel.getFieldName()); + coordinatesToNormalizedFields.put(coordinates, topLevel); + } + } + + + private Map> fieldsByResultKey(List collectedFields) { + Map> fieldsByName = new LinkedHashMap<>(); + for (CollectedField collectedField : collectedFields) { + fieldsByName.computeIfAbsent(collectedField.field.getResultKey(), ignored -> new ArrayList<>()).add(collectedField); + } + return fieldsByName; + } + + + private void createNFs(ImmutableList.Builder nfListBuilder, + Map> fieldsByName, + ImmutableListMultimap.Builder normalizedFieldToAstFields, + int level, + NormalizedField parent) { + for (String resultKey : fieldsByName.keySet()) { + List fieldsWithSameResultKey = fieldsByName.get(resultKey); + List commonParentsGroups = groupByCommonParents(fieldsWithSameResultKey); + for (CollectedFieldGroup fieldGroup : commonParentsGroups) { + NormalizedField nf = createNF(fieldGroup, level, parent); + if (nf == null) { + continue; + } + for (CollectedField collectedField : fieldGroup.fields) { + normalizedFieldToAstFields.put(nf, collectedField); + } + nfListBuilder.add(nf); + + } + if (commonParentsGroups.size() > 1) { + possibleMergerList.add(new PossibleMerger(parent, resultKey)); + } + } + } + + // new single ENF + private NormalizedField createNF(CollectedFieldGroup collectedFieldGroup, + int level, + NormalizedField parent) { + + this.fieldCount++; + if (this.fieldCount > this.options.getMaxFieldsCount()) { + throw new AbortExecutionException("Maximum field count exceeded. " + this.fieldCount + " > " + this.options.getMaxFieldsCount()); + } + Field field; + Set objectTypes = collectedFieldGroup.objectTypes; + field = collectedFieldGroup.fields.iterator().next().field; + List directives = collectedFieldGroup.fields.stream().flatMap(f -> f.field.getDirectives().stream()).collect(Collectors.toList()); + String fieldName = field.getName(); + ImmutableList objectTypeNames = map(objectTypes, GraphQLObjectType::getName); + return NormalizedField.newNormalizedField() + .alias(field.getAlias()) + .astArguments(field.getArguments()) + .astDirectives(directives) + .objectTypeNames(objectTypeNames) + .fieldName(fieldName) + .level(level) + .parent(parent) + .build(); + } + + + private List groupByCommonParents(Collection fields) { + ImmutableSet.Builder objectTypes = ImmutableSet.builder(); + for (CollectedField collectedField : fields) { + objectTypes.addAll(collectedField.objectTypes); + } + Set allRelevantObjects = objectTypes.build(); + Map> groupByAstParent = groupingBy(fields, fieldAndType -> fieldAndType.astTypeCondition); + if (groupByAstParent.size() == 1) { + return singletonList(new CollectedFieldGroup(ImmutableSet.copyOf(fields), allRelevantObjects)); + } + ImmutableList.Builder result = ImmutableList.builder(); + for (GraphQLObjectType objectType : allRelevantObjects) { + Set relevantFields = filterSet(fields, field -> field.objectTypes.contains(objectType)); + result.add(new CollectedFieldGroup(relevantFields, singleton(objectType))); + } + return result.build(); + } + + + private void collectFromSelectionSet(SelectionSet selectionSet, + List result, + GraphQLCompositeType astTypeCondition, + Set possibleObjects + ) { + for (Selection selection : selectionSet.getSelections()) { + if (selection instanceof Field) { + collectField(result, (Field) selection, possibleObjects, astTypeCondition); + } else if (selection instanceof InlineFragment) { + collectInlineFragment(result, (InlineFragment) selection, possibleObjects, astTypeCondition); + } else if (selection instanceof FragmentSpread) { + collectFragmentSpread(result, (FragmentSpread) selection, possibleObjects); + } + } + } + + private void collectFragmentSpread(List result, + FragmentSpread fragmentSpread, + Set possibleObjects + ) { +// if (!conditionalNodes.shouldInclude(fragmentSpread, +// this.coercedVariableValues.toMap(), +// this.graphQLSchema, +// this.options.graphQLContext)) { +// return; +// } + FragmentDefinition fragmentDefinition = assertNotNull(this.fragments.get(fragmentSpread.getName())); + +// if (!conditionalNodes.shouldInclude(fragmentDefinition, +// this.coercedVariableValues.toMap(), +// this.graphQLSchema, +// this.options.graphQLContext)) { +// return; +// } + GraphQLCompositeType newAstTypeCondition = (GraphQLCompositeType) assertNotNull(this.graphQLSchema.getType(fragmentDefinition.getTypeCondition().getName())); + Set newPossibleObjects = narrowDownPossibleObjects(possibleObjects, newAstTypeCondition); + collectFromSelectionSet(fragmentDefinition.getSelectionSet(), result, newAstTypeCondition, newPossibleObjects); + } + + private void collectInlineFragment(List result, + InlineFragment inlineFragment, + Set possibleObjects, + GraphQLCompositeType astTypeCondition + ) { +// if (!conditionalNodes.shouldInclude(inlineFragment, this.coercedVariableValues.toMap(), this.graphQLSchema, this.options.graphQLContext)) { +// return; +// } + Set newPossibleObjects = possibleObjects; + GraphQLCompositeType newAstTypeCondition = astTypeCondition; + + if (inlineFragment.getTypeCondition() != null) { + newAstTypeCondition = (GraphQLCompositeType) this.graphQLSchema.getType(inlineFragment.getTypeCondition().getName()); + newPossibleObjects = narrowDownPossibleObjects(possibleObjects, newAstTypeCondition); + + } + + + collectFromSelectionSet(inlineFragment.getSelectionSet(), result, newAstTypeCondition, newPossibleObjects); + } + + private void collectField(List result, + Field field, + Set possibleObjectTypes, + GraphQLCompositeType astTypeCondition + ) { + Boolean shouldInclude; + if (assumedSkipIncludeVariableValues == null) { + if ((shouldInclude = conditionalNodes.shouldIncludeWithoutVariables(field)) == null) { + + String skipVariableName = conditionalNodes.getSkipVariableName(field); + String includeVariableName = conditionalNodes.getIncludeVariableName(field); + if (skipVariableName != null) { + skipIncludeVariableNames.add(skipVariableName); + } + if (includeVariableName != null) { + skipIncludeVariableNames.add(includeVariableName); + } + } + if (shouldInclude != null && !shouldInclude) { + return; + } + } else { + if (!conditionalNodes.shouldInclude(field, (Map) assumedSkipIncludeVariableValues, graphQLSchema, null)) { + return; + } + } + // this means there is actually no possible type for this field, and we are done + if (possibleObjectTypes.isEmpty()) { + return; + } + result.add(new CollectedField(field, possibleObjectTypes, astTypeCondition)); + } + + private Set narrowDownPossibleObjects(Set currentOnes, + GraphQLCompositeType typeCondition) { + + ImmutableSet resolvedTypeCondition = resolvePossibleObjects(typeCondition); + if (currentOnes.isEmpty()) { + return resolvedTypeCondition; + } + + // Faster intersection, as either set often has a size of 1. + return intersection(currentOnes, resolvedTypeCondition); + } + + private ImmutableSet resolvePossibleObjects(List defs) { + ImmutableSet.Builder builder = ImmutableSet.builder(); + + for (GraphQLFieldDefinition def : defs) { + GraphQLUnmodifiedType outputType = unwrapAll(def.getType()); + if (outputType instanceof GraphQLCompositeType) { + builder.addAll(resolvePossibleObjects((GraphQLCompositeType) outputType)); + } + } + + return builder.build(); + } + + private ImmutableSet resolvePossibleObjects(GraphQLCompositeType type) { + if (type instanceof GraphQLObjectType) { + return ImmutableSet.of((GraphQLObjectType) type); + } else if (type instanceof GraphQLInterfaceType) { + return ImmutableSet.copyOf(graphQLSchema.getImplementations((GraphQLInterfaceType) type)); + } else if (type instanceof GraphQLUnionType) { + List unionTypes = ((GraphQLUnionType) type).getTypes(); + return ImmutableSet.copyOf(ImmutableKit.map(unionTypes, GraphQLObjectType.class::cast)); + } else { + return assertShouldNeverHappen(); + } + } + + private static class PossibleMerger { + NormalizedField parent; + String resultKey; + + public PossibleMerger(NormalizedField parent, String resultKey) { + this.parent = parent; + this.resultKey = resultKey; + } + } + + private static class CollectedField { + Field field; + Set objectTypes; + GraphQLCompositeType astTypeCondition; + + public CollectedField(Field field, Set objectTypes, GraphQLCompositeType astTypeCondition) { + this.field = field; + this.objectTypes = objectTypes; + this.astTypeCondition = astTypeCondition; + } + } + + private static class CollectedFieldGroup { + Set objectTypes; + Set fields; + + public CollectedFieldGroup(Set fields, Set objectTypes) { + this.fields = fields; + this.objectTypes = objectTypes; + } + } + } + +} diff --git a/src/main/java/graphql/normalized/nf/NormalizedField.java b/src/main/java/graphql/normalized/nf/NormalizedField.java new file mode 100644 index 0000000000..78aead5d2b --- /dev/null +++ b/src/main/java/graphql/normalized/nf/NormalizedField.java @@ -0,0 +1,678 @@ +package graphql.normalized.nf; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.ExperimentalApi; +import graphql.Internal; +import graphql.Mutable; +import graphql.collect.ImmutableKit; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.normalized.ExecutableNormalizedOperation; +import graphql.normalized.NormalizedInputValue; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLUnionType; +import graphql.util.FpKit; +import graphql.util.MutableRef; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; + +/** + * An {@link NormalizedField} represents a field in an executable graphql operation. Its models what + * could be executed during a given operation. + *

+ * This class is intentionally mutable for performance reasons since building immutable parent child + * objects is too expensive. + */ +@ExperimentalApi +@Mutable +public class NormalizedField { + private final String alias; + private final ImmutableMap normalizedArguments; + private final LinkedHashMap resolvedArguments; + private final ImmutableList astArguments; + private List astDirectives; + + // Mutable List on purpose: it is modified after creation + private final LinkedHashSet objectTypeNames; + private final ArrayList children; + private NormalizedField parent; + + private final String fieldName; + private final int level; + + + private NormalizedField(Builder builder) { + this.alias = builder.alias; + this.resolvedArguments = builder.resolvedArguments; + this.normalizedArguments = builder.normalizedArguments; + this.astArguments = builder.astArguments; + this.objectTypeNames = builder.objectTypeNames; + this.fieldName = assertNotNull(builder.fieldName); + this.children = builder.children; + this.level = builder.level; + this.parent = builder.parent; + this.astDirectives = builder.astDirectives; + } + + /** + * Determines whether this {@link NormalizedField} needs a fragment to select the field. However, it considers the parent + * output type when determining whether it needs a fragment. + *

+ * Consider the following schema + * + *

+     * interface Animal {
+     *     name: String
+     *     parent: Animal
+     * }
+     * type Cat implements Animal {
+     *     name: String
+     *     parent: Cat
+     * }
+     * type Dog implements Animal {
+     *     name: String
+     *     parent: Dog
+     *     isGoodBoy: Boolean
+     * }
+     * type Query {
+     *     animal: Animal
+     * }
+     * 
+ *

+ * and the following query + * + *

+     * {
+     *     animal {
+     *         parent {
+     *             name
+     *         }
+     *     }
+     * }
+     * 
+ *

+ * Then we would get the following {@link ExecutableNormalizedOperation} + * + *

+     * -Query.animal: Animal
+     * --[Cat, Dog].parent: Cat, Dog
+     * ---[Cat, Dog].name: String
+     * 
+ *

+ * If we simply checked the {@link #parent}'s {@link #getFieldDefinitions(GraphQLSchema)} that would + * point us to {@code Cat.parent} and {@code Dog.parent} whose output types would incorrectly answer + * our question whether this is conditional? + *

+ * We MUST consider that the output type of the {@code parent} field is {@code Animal} and + * NOT {@code Cat} or {@code Dog} as their respective implementations would say. + * + * @param schema - the graphql schema in play + * @return true if the field is conditional + */ + public boolean isConditional(@NonNull GraphQLSchema schema) { + if (parent == null) { + return false; + } + + for (GraphQLInterfaceType commonParentOutputInterface : parent.getInterfacesCommonToAllOutputTypes(schema)) { + List implementations = schema.getImplementations(commonParentOutputInterface); + // __typename + if (fieldName.equals(Introspection.TypeNameMetaFieldDef.getName()) && implementations.size() == objectTypeNames.size()) { + return false; + } + if (commonParentOutputInterface.getField(fieldName) == null) { + continue; + } + if (implementations.size() == objectTypeNames.size()) { + return false; + } + } + + // __typename is the only field in a union type that CAN be NOT conditional + GraphQLFieldDefinition parentFieldDef = parent.getOneFieldDefinition(schema); + if (unwrapAll(parentFieldDef.getType()) instanceof GraphQLUnionType) { + GraphQLUnionType parentOutputTypeAsUnion = (GraphQLUnionType) unwrapAll(parentFieldDef.getType()); + if (fieldName.equals(Introspection.TypeNameMetaFieldDef.getName()) && objectTypeNames.size() == parentOutputTypeAsUnion.getTypes().size()) { + return false; // Not conditional + } + } + + // This means there is no Union or Interface which could serve as unconditional parent + if (objectTypeNames.size() > 1) { + return true; // Conditional + } + if (parent.objectTypeNames.size() > 1) { + return true; + } + + GraphQLObjectType oneObjectType = (GraphQLObjectType) schema.getType(objectTypeNames.iterator().next()); + return unwrapAll(parentFieldDef.getType()) != oneObjectType; + } + + public boolean hasChildren() { + return children.size() > 0; + } + + public GraphQLOutputType getType(GraphQLSchema schema) { + List fieldDefinitions = getFieldDefinitions(schema); + Set fieldTypes = fieldDefinitions.stream().map(fd -> simplePrint(fd.getType())).collect(toSet()); + assertTrue(fieldTypes.size() == 1, "More than one type ... use getTypes"); + return fieldDefinitions.get(0).getType(); + } + + public List getTypes(GraphQLSchema schema) { + return ImmutableKit.map(getFieldDefinitions(schema), fd -> fd.getType()); + } + + public void forEachFieldDefinition(GraphQLSchema schema, Consumer consumer) { + var fieldDefinition = resolveIntrospectionField(schema, objectTypeNames, fieldName); + if (fieldDefinition != null) { + consumer.accept(fieldDefinition); + return; + } + + for (String objectTypeName : objectTypeNames) { + GraphQLObjectType type = (GraphQLObjectType) assertNotNull(schema.getType(objectTypeName)); + consumer.accept(assertNotNull(type.getField(fieldName), "No field %s found for type %s", fieldName, objectTypeName)); + } + } + + public List getFieldDefinitions(GraphQLSchema schema) { + ImmutableList.Builder builder = ImmutableList.builder(); + forEachFieldDefinition(schema, builder::add); + return builder.build(); + } + + /** + * This is NOT public as it is not recommended usage. + *

+ * Internally there are cases where we know it is safe to use this, so this exists. + */ + private GraphQLFieldDefinition getOneFieldDefinition(GraphQLSchema schema) { + var fieldDefinition = resolveIntrospectionField(schema, objectTypeNames, fieldName); + if (fieldDefinition != null) { + return fieldDefinition; + } + + String objectTypeName = objectTypeNames.iterator().next(); + GraphQLObjectType type = (GraphQLObjectType) assertNotNull(schema.getType(objectTypeName)); + return assertNotNull(type.getField(fieldName), "No field %s found for type %s", fieldName, objectTypeName); + } + + private static GraphQLFieldDefinition resolveIntrospectionField(GraphQLSchema schema, Set objectTypeNames, String fieldName) { + if (fieldName.equals(schema.getIntrospectionTypenameFieldDefinition().getName())) { + return schema.getIntrospectionTypenameFieldDefinition(); + } else if (objectTypeNames.size() == 1 && objectTypeNames.iterator().next().equals(schema.getQueryType().getName())) { + if (fieldName.equals(schema.getIntrospectionSchemaFieldDefinition().getName())) { + return schema.getIntrospectionSchemaFieldDefinition(); + } else if (fieldName.equals(schema.getIntrospectionTypeFieldDefinition().getName())) { + return schema.getIntrospectionTypeFieldDefinition(); + } + } + return null; + } + + @Internal + public void addObjectTypeNames(Collection objectTypeNames) { + this.objectTypeNames.addAll(objectTypeNames); + } + + @Internal + public void setObjectTypeNames(Collection objectTypeNames) { + this.objectTypeNames.clear(); + this.objectTypeNames.addAll(objectTypeNames); + } + + @Internal + public void addChild(NormalizedField normalizedField) { + this.children.add(normalizedField); + } + + @Internal + public void clearChildren() { + this.children.clear(); + } + + + /** + * All merged fields have the same name so this is the name of the {@link NormalizedField}. + *

+ * WARNING: This is not always the key in the execution result, because of possible field aliases. + * + * @return the name of this {@link NormalizedField} + * @see #getResultKey() + * @see #getAlias() + */ + public String getName() { + return getFieldName(); + } + + /** + * @return the same value as {@link #getName()} + * @see #getResultKey() + * @see #getAlias() + */ + public String getFieldName() { + return fieldName; + } + + /** + * Returns the result key of this {@link NormalizedField} within the overall result. + * This is either a field alias or the value of {@link #getName()} + * + * @return the result key for this {@link NormalizedField}. + * @see #getName() + */ + public String getResultKey() { + if (alias != null) { + return alias; + } + return getName(); + } + + /** + * @return the field alias used or null if there is none + * @see #getResultKey() + * @see #getName() + */ + public String getAlias() { + return alias; + } + + /** + * @return a list of the {@link Argument}s on the field + */ + public ImmutableList getAstArguments() { + return astArguments; + } + + public List getAstDirectives() { + return astDirectives; + } + + public void setAstDirectives(List astDirectives) { + this.astDirectives = astDirectives; + } + + + /** + * Returns an argument value as a {@link NormalizedInputValue} which contains its type name and its current value + * + * @param name the name of the argument + * @return an argument value + */ + public NormalizedInputValue getNormalizedArgument(String name) { + return normalizedArguments.get(name); + } + + /** + * @return a map of all the arguments in {@link NormalizedInputValue} form + */ + public ImmutableMap getNormalizedArguments() { + return normalizedArguments; + } + + /** + * @return a map of the resolved argument values + */ + public LinkedHashMap getResolvedArguments() { + return resolvedArguments; + } + + + /** + * A {@link NormalizedField} can sometimes (for non-concrete types like interfaces and unions) + * have more than one object type it could be when executed. There is no way to know what it will be until + * the field is executed over data and the type is resolved via a {@link graphql.schema.TypeResolver}. + *

+ * This method returns all the possible types a field can be which is one or more {@link GraphQLObjectType} + * names. + *

+ * Warning: This returns a Mutable Set. No defensive copy is made for performance reasons. + * + * @return a set of the possible type names this field could be. + */ + public Set getObjectTypeNames() { + return objectTypeNames; + } + + + /** + * This returns the first entry in {@link #getObjectTypeNames()}. Sometimes you know a field cant be more than one + * type and this method is a shortcut one to help you. + * + * @return the first entry from + */ + public String getSingleObjectTypeName() { + return objectTypeNames.iterator().next(); + } + + /** + * @return a helper method show field details + */ + public String printDetails() { + StringBuilder result = new StringBuilder(); + if (getAlias() != null) { + result.append(getAlias()).append(": "); + } + return result + objectTypeNamesToString() + "." + fieldName; + } + + /** + * @return a helper method to show the object types names as a string + */ + public String objectTypeNamesToString() { + if (objectTypeNames.size() == 1) { + return objectTypeNames.iterator().next(); + } else { + return objectTypeNames.toString(); + } + } + + /** + * This returns the list of the result keys (see {@link #getResultKey()} that lead from this field upwards to + * its parent field + * + * @return a list of the result keys from this {@link NormalizedField} to the top of the operation via parent fields + */ + public List getListOfResultKeys() { + LinkedList list = new LinkedList<>(); + NormalizedField current = this; + while (current != null) { + list.addFirst(current.getResultKey()); + current = current.parent; + } + return list; + } + + /** + * @return the children of the {@link NormalizedField} + */ + public List getChildren() { + return children; + } + + /** + * Returns the list of child fields that would have the same result key + * + * @param resultKey the result key to check + * @return a list of all direct {@link NormalizedField} children with the specified result key + */ + public List getChildrenWithSameResultKey(String resultKey) { + return FpKit.filterList(children, child -> child.getResultKey().equals(resultKey)); + } + + public List getChildren(int includingRelativeLevel) { + assertTrue(includingRelativeLevel >= 1, "relative level must be >= 1"); + List result = new ArrayList<>(); + + this.getChildren().forEach(child -> { + traverseImpl(child, result::add, 1, includingRelativeLevel); + }); + return result; + } + + /** + * This returns the child fields that can be used if the object is of the specified object type + * + * @param objectTypeName the object type + * @return a list of child fields that would apply to that object type + */ + public List getChildren(String objectTypeName) { + return children.stream() + .filter(cld -> cld.objectTypeNames.contains(objectTypeName)) + .collect(toList()); + } + + /** + * the level of the {@link NormalizedField} in the operation hierarchy with top level fields + * starting at 1 + * + * @return the level of the {@link NormalizedField} in the operation hierarchy + */ + public int getLevel() { + return level; + } + + /** + * @return the parent of this {@link NormalizedField} or null if it's a top level field + */ + public NormalizedField getParent() { + return parent; + } + + + @Internal + public void replaceParent(NormalizedField newParent) { + this.parent = newParent; + } + + + @Override + public String toString() { + return "NormalizedField{" + + objectTypeNamesToString() + "." + fieldName + + ", alias=" + alias + + ", level=" + level + + ", children=" + children.stream().map(NormalizedField::toString).collect(joining("\n")) + + '}'; + } + + + /** + * Traverse from this {@link NormalizedField} down into itself and all of its children + * + * @param consumer the callback for each {@link NormalizedField} in the hierarchy. + */ + public void traverseSubTree(Consumer consumer) { + this.getChildren().forEach(child -> { + traverseImpl(child, consumer, 1, Integer.MAX_VALUE); + }); + } + + private void traverseImpl(NormalizedField root, + Consumer consumer, + int curRelativeLevel, + int abortAfter) { + if (curRelativeLevel > abortAfter) { + return; + } + consumer.accept(root); + root.getChildren().forEach(child -> { + traverseImpl(child, consumer, curRelativeLevel + 1, abortAfter); + }); + } + + /** + * This tries to find interfaces common to all the field output types. + *

+ * i.e. goes through {@link #getFieldDefinitions(GraphQLSchema)} and finds interfaces that + * all the field's unwrapped output types are assignable to. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private Set getInterfacesCommonToAllOutputTypes(GraphQLSchema schema) { + // Shortcut for performance + if (objectTypeNames.size() == 1) { + var fieldDef = getOneFieldDefinition(schema); + var outputType = unwrapAll(fieldDef.getType()); + + if (outputType instanceof GraphQLObjectType) { + return new LinkedHashSet<>((List) ((GraphQLObjectType) outputType).getInterfaces()); + } else if (outputType instanceof GraphQLInterfaceType) { + var result = new LinkedHashSet<>((List) ((GraphQLInterfaceType) outputType).getInterfaces()); + result.add(outputType); + return result; + } else { + return Collections.emptySet(); + } + } + + MutableRef> commonInterfaces = new MutableRef<>(); + forEachFieldDefinition(schema, (fieldDef) -> { + var outputType = unwrapAll(fieldDef.getType()); + + List outputTypeInterfaces; + if (outputType instanceof GraphQLObjectType) { + outputTypeInterfaces = (List) ((GraphQLObjectType) outputType).getInterfaces(); + } else if (outputType instanceof GraphQLInterfaceType) { + // This interface and superinterfaces + List superInterfaces = ((GraphQLInterfaceType) outputType).getInterfaces(); + + outputTypeInterfaces = new ArrayList<>(superInterfaces.size() + 1); + outputTypeInterfaces.add((GraphQLInterfaceType) outputType); + + if (!superInterfaces.isEmpty()) { + outputTypeInterfaces.addAll((List) superInterfaces); + } + } else { + outputTypeInterfaces = Collections.emptyList(); + } + + if (commonInterfaces.value == null) { + commonInterfaces.value = new LinkedHashSet<>(outputTypeInterfaces); + } else { + commonInterfaces.value.retainAll(outputTypeInterfaces); + } + }); + + return commonInterfaces.value; + } + + /** + * @return a {@link Builder} of {@link NormalizedField}s + */ + public static Builder newNormalizedField() { + return new Builder(); + } + + /** + * Allows this {@link NormalizedField} to be transformed via a {@link Builder} consumer callback + * + * @param builderConsumer the consumer given a builder + * @return a new transformed {@link NormalizedField} + */ + public NormalizedField transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + + public static class Builder { + private LinkedHashSet objectTypeNames = new LinkedHashSet<>(); + private String fieldName; + private ArrayList children = new ArrayList<>(); + private int level; + private NormalizedField parent; + private String alias; + private ImmutableMap normalizedArguments = ImmutableKit.emptyMap(); + private LinkedHashMap resolvedArguments = new LinkedHashMap<>(); + private ImmutableList astArguments = ImmutableKit.emptyList(); + private List astDirectives = Collections.emptyList(); + + + private Builder() { + } + + private Builder(NormalizedField existing) { + this.alias = existing.alias; + this.normalizedArguments = existing.normalizedArguments; + this.astArguments = existing.astArguments; + this.resolvedArguments = existing.resolvedArguments; + this.objectTypeNames = new LinkedHashSet<>(existing.getObjectTypeNames()); + this.fieldName = existing.getFieldName(); + this.children = new ArrayList<>(existing.children); + this.level = existing.getLevel(); + this.parent = existing.getParent(); + } + + public Builder clearObjectTypesNames() { + this.objectTypeNames.clear(); + return this; + } + + public Builder objectTypeNames(List objectTypeNames) { + this.objectTypeNames.addAll(objectTypeNames); + return this; + } + + public Builder alias(String alias) { + this.alias = alias; + return this; + } + + public Builder normalizedArguments(@Nullable Map arguments) { + this.normalizedArguments = arguments == null ? ImmutableKit.emptyMap() : ImmutableMap.copyOf(arguments); + return this; + } + + public Builder resolvedArguments(@Nullable Map arguments) { + this.resolvedArguments = arguments == null ? new LinkedHashMap<>() : new LinkedHashMap<>(arguments); + return this; + } + + public Builder astArguments(@NonNull List astArguments) { + this.astArguments = ImmutableList.copyOf(astArguments); + return this; + } + + public Builder astDirectives(@NonNull List astDirectives) { + this.astDirectives = astDirectives; + return this; + } + + + public Builder fieldName(String fieldName) { + this.fieldName = fieldName; + return this; + } + + + public Builder children(List children) { + this.children.clear(); + this.children.addAll(children); + return this; + } + + public Builder level(int level) { + this.level = level; + return this; + } + + public Builder parent(NormalizedField parent) { + this.parent = parent; + return this; + } + + + public NormalizedField build() { + return new NormalizedField(this); + } + } +} diff --git a/src/main/java/graphql/normalized/nf/NormalizedFieldsMerger.java b/src/main/java/graphql/normalized/nf/NormalizedFieldsMerger.java new file mode 100644 index 0000000000..4261aa5307 --- /dev/null +++ b/src/main/java/graphql/normalized/nf/NormalizedFieldsMerger.java @@ -0,0 +1,195 @@ +package graphql.normalized.nf; + +import graphql.Internal; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.AstComparator; +import graphql.language.Directive; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +@Internal +public class NormalizedFieldsMerger { + + public static void merge( + NormalizedField parent, + List childrenWithSameResultKey, + GraphQLSchema schema + ) { + // they have all the same result key + // we can only merge the fields if they have the same field name + arguments + all children are the same + List> possibleGroupsToMerge = new ArrayList<>(); + for (NormalizedField field : childrenWithSameResultKey) { + boolean addToGroup = false; + overPossibleGroups: + for (Set group : possibleGroupsToMerge) { + for (NormalizedField fieldInGroup : group) { + if (field.getFieldName().equals(Introspection.TypeNameMetaFieldDef.getName())) { + addToGroup = true; + group.add(field); + continue overPossibleGroups; + } + if (field.getFieldName().equals(fieldInGroup.getFieldName()) && + sameArguments(field.getAstArguments(), fieldInGroup.getAstArguments()) + && isFieldInSharedInterface(field, fieldInGroup, schema) + ) { + addToGroup = true; + group.add(field); + continue overPossibleGroups; + } + } + } + if (!addToGroup) { + LinkedHashSet group = new LinkedHashSet<>(); + group.add(field); + possibleGroupsToMerge.add(group); + } + } + for (Set groupOfFields : possibleGroupsToMerge) { + // for each group we check if it could be merged + List> listOfChildrenForGroup = new ArrayList<>(); + for (NormalizedField fieldInGroup : groupOfFields) { + Set childrenSets = new LinkedHashSet<>(fieldInGroup.getChildren()); + listOfChildrenForGroup.add(childrenSets); + } + boolean mergeable = areFieldSetsTheSame(listOfChildrenForGroup); + if (mergeable) { + Set mergedObjects = new LinkedHashSet<>(); + List mergedDirectives = new ArrayList<>(); + groupOfFields.forEach(f -> mergedObjects.addAll(f.getObjectTypeNames())); + groupOfFields.forEach(f -> mergedDirectives.addAll(f.getAstDirectives())); + // patching the first one to contain more objects, remove all others + Iterator iterator = groupOfFields.iterator(); + NormalizedField first = iterator.next(); + + while (iterator.hasNext()) { + NormalizedField next = iterator.next(); + parent.getChildren().remove(next); + } + first.setObjectTypeNames(mergedObjects); + first.setAstDirectives(mergedDirectives); + } + } + } + + private static boolean isFieldInSharedInterface(NormalizedField fieldOne, NormalizedField fieldTwo, GraphQLSchema schema) { + + /* + * we can get away with only checking one of the object names, because all object names in one ENF are guaranteed to be the same field. + * This comes from how the ENFs are created in the factory before. + */ + String firstObject = fieldOne.getSingleObjectTypeName(); + String secondObject = fieldTwo.getSingleObjectTypeName(); + // we know that the field names are the same, therefore we can just take the first one + String fieldName = fieldOne.getFieldName(); + + GraphQLObjectType objectTypeOne = schema.getObjectType(firstObject); + GraphQLObjectType objectTypeTwo = schema.getObjectType(secondObject); + List interfacesOne = (List) objectTypeOne.getInterfaces(); + List interfacesTwo = (List) objectTypeTwo.getInterfaces(); + + Optional firstInterfaceFound = interfacesOne.stream().filter(singleInterface -> singleInterface.getFieldDefinition(fieldName) != null).findFirst(); + Optional secondInterfaceFound = interfacesTwo.stream().filter(singleInterface -> singleInterface.getFieldDefinition(fieldName) != null).findFirst(); + if (!firstInterfaceFound.isPresent() || !secondInterfaceFound.isPresent()) { + return false; + } + return firstInterfaceFound.get().getName().equals(secondInterfaceFound.get().getName()); + } + + + private static boolean areFieldSetsTheSame(List> listOfSets) { + if (listOfSets.size() == 0 || listOfSets.size() == 1) { + return true; + } + Set first = listOfSets.get(0); + Iterator> iterator = listOfSets.iterator(); + iterator.next(); + while (iterator.hasNext()) { + Set set = iterator.next(); + if (!compareTwoFieldSets(first, set)) { + return false; + } + } + List> nextLevel = new ArrayList<>(); + for (Set set : listOfSets) { + for (NormalizedField fieldInSet : set) { + nextLevel.add(new LinkedHashSet<>(fieldInSet.getChildren())); + } + } + return areFieldSetsTheSame(nextLevel); + } + + private static boolean compareTwoFieldSets(Set setOne, Set setTwo) { + if (setOne.size() != setTwo.size()) { + return false; + } + for (NormalizedField field : setOne) { + if (!isContained(field, setTwo)) { + return false; + } + } + return true; + } + + private static boolean isContained(NormalizedField searchFor, Set set) { + for (NormalizedField field : set) { + if (compareWithoutChildren(searchFor, field)) { + return true; + } + } + return false; + } + + private static boolean compareWithoutChildren(NormalizedField one, NormalizedField two) { + + if (!one.getObjectTypeNames().equals(two.getObjectTypeNames())) { + return false; + } + if (!Objects.equals(one.getAlias(), two.getAlias())) { + return false; + } + if (!Objects.equals(one.getFieldName(), two.getFieldName())) { + return false; + } + if (!sameArguments(one.getAstArguments(), two.getAstArguments())) { + return false; + } + return true; + } + + // copied from graphql.validation.rules.OverlappingFieldsCanBeMerged + private static boolean sameArguments(List arguments1, List arguments2) { + if (arguments1.size() != arguments2.size()) { + return false; + } + for (Argument argument : arguments1) { + Argument matchedArgument = findArgumentByName(argument.getName(), arguments2); + if (matchedArgument == null) { + return false; + } + if (!AstComparator.sameValue(argument.getValue(), matchedArgument.getValue())) { + return false; + } + } + return true; + } + + private static Argument findArgumentByName(String name, List arguments) { + for (Argument argument : arguments) { + if (argument.getName().equals(name)) { + return argument; + } + } + return null; + } + +} diff --git a/src/main/java/graphql/normalized/nf/NormalizedOperation.java b/src/main/java/graphql/normalized/nf/NormalizedOperation.java new file mode 100644 index 0000000000..6d3c333d0b --- /dev/null +++ b/src/main/java/graphql/normalized/nf/NormalizedOperation.java @@ -0,0 +1,180 @@ +package graphql.normalized.nf; + +import com.google.common.collect.ImmutableListMultimap; +import graphql.Assert; +import graphql.ExperimentalApi; +import graphql.execution.MergedField; +import graphql.execution.ResultPath; +import graphql.execution.directives.QueryDirectives; +import graphql.language.Field; +import graphql.language.OperationDefinition; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLFieldsContainer; + +import java.util.List; +import java.util.Map; + +/** + * A {@link NormalizedOperation} represent how the text of a graphql operation (sometimes known colloquially as a query) + * will be executed at runtime according to the graphql specification. It handles complex mechanisms like merging + * duplicate fields into one and also detecting when the types of a given field may actually be for more than one possible object + * type. + *

+ * An operation consists of a list of {@link NormalizedField}s in a parent child hierarchy + */ +@ExperimentalApi +public class NormalizedOperation { + private final OperationDefinition.Operation operation; + private final String operationName; + private final List rootFields; + private final ImmutableListMultimap fieldToNormalizedField; + private final Map normalizedFieldToMergedField; + private final Map normalizedFieldToQueryDirectives; + private final ImmutableListMultimap coordinatesToNormalizedFields; + private final int operationFieldCount; + private final int operationDepth; + + public NormalizedOperation( + OperationDefinition.Operation operation, + String operationName, + List rootFields, + ImmutableListMultimap fieldToNormalizedField, + Map normalizedFieldToMergedField, + Map normalizedFieldToQueryDirectives, + ImmutableListMultimap coordinatesToNormalizedFields, + int operationFieldCount, + int operationDepth) { + this.operation = operation; + this.operationName = operationName; + this.rootFields = rootFields; + this.fieldToNormalizedField = fieldToNormalizedField; + this.normalizedFieldToMergedField = normalizedFieldToMergedField; + this.normalizedFieldToQueryDirectives = normalizedFieldToQueryDirectives; + this.coordinatesToNormalizedFields = coordinatesToNormalizedFields; + this.operationFieldCount = operationFieldCount; + this.operationDepth = operationDepth; + } + + /** + * @return operation AST being executed + */ + public OperationDefinition.Operation getOperation() { + return operation; + } + + /** + * @return the operation name, which can be null + */ + public String getOperationName() { + return operationName; + } + + /** + * @return This returns how many {@link NormalizedField}s are in the operation. + */ + public int getOperationFieldCount() { + return operationFieldCount; + } + + /** + * @return This returns the depth of the operation + */ + public int getOperationDepth() { + return operationDepth; + } + + /** + * This multimap shows how a given {@link NormalizedField} maps to a one or more field coordinate in the schema + * + * @return a multimap of fields to schema field coordinates + */ + public ImmutableListMultimap getCoordinatesToNormalizedFields() { + return coordinatesToNormalizedFields; + } + + /** + * @return a list of the top level {@link NormalizedField}s in this operation. + */ + public List getRootFields() { + return rootFields; + } + + /** + * This is a multimap and the size of it reflects all the normalized fields in the operation + * + * @return an immutable list multimap of {@link Field} to {@link NormalizedField} + */ + public ImmutableListMultimap getFieldToNormalizedField() { + return fieldToNormalizedField; + } + + /** + * Looks up one or more {@link NormalizedField}s given a {@link Field} AST element in the operation + * + * @param field the field to look up + * + * @return zero, one or more possible {@link NormalizedField}s that represent that field + */ + public List getNormalizedFields(Field field) { + return fieldToNormalizedField.get(field); + } + + /** + * @return a map of {@link NormalizedField} to {@link MergedField}s + */ + public Map getNormalizedFieldToMergedField() { + return normalizedFieldToMergedField; + } + + /** + * Looks up the {@link MergedField} given a {@link NormalizedField} + * + * @param NormalizedField the field to use the key + * + * @return a {@link MergedField} or null if its not present + */ + public MergedField getMergedField(NormalizedField NormalizedField) { + return normalizedFieldToMergedField.get(NormalizedField); + } + + /** + * @return a map of {@link NormalizedField} to its {@link QueryDirectives} + */ + public Map getNormalizedFieldToQueryDirectives() { + return normalizedFieldToQueryDirectives; + + } + + /** + * This looks up the {@link QueryDirectives} associated with the given {@link NormalizedField} + * + * @param NormalizedField the executable normalised field in question + * + * @return the fields query directives or null + */ + public QueryDirectives getQueryDirectives(NormalizedField NormalizedField) { + return normalizedFieldToQueryDirectives.get(NormalizedField); + } + + /** + * This will find a {@link NormalizedField} given a merged field and a result path. If this does not find a field it will assert with an exception + * + * @param mergedField the merged field + * @param fieldsContainer the containing type of that field + * @param resultPath the result path in play + * + * @return the NormalizedField + */ + public NormalizedField getNormalizedField(MergedField mergedField, GraphQLFieldsContainer fieldsContainer, ResultPath resultPath) { + List NormalizedFields = fieldToNormalizedField.get(mergedField.getSingleField()); + List keysOnlyPath = resultPath.getKeysOnly(); + for (NormalizedField NormalizedField : NormalizedFields) { + if (NormalizedField.getListOfResultKeys().equals(keysOnlyPath)) { + if (NormalizedField.getObjectTypeNames().contains(fieldsContainer.getName())) { + return NormalizedField; + } + } + } + return Assert.assertShouldNeverHappen("normalized field not found"); + } +} diff --git a/src/main/java/graphql/normalized/nf/NormalizedOperationToAstCompiler.java b/src/main/java/graphql/normalized/nf/NormalizedOperationToAstCompiler.java new file mode 100644 index 0000000000..71fa804173 --- /dev/null +++ b/src/main/java/graphql/normalized/nf/NormalizedOperationToAstCompiler.java @@ -0,0 +1,248 @@ +package graphql.normalized.nf; + +import com.google.common.collect.ImmutableList; +import graphql.Assert; +import graphql.ExperimentalApi; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.Document; +import graphql.language.Field; +import graphql.language.InlineFragment; +import graphql.language.OperationDefinition; +import graphql.language.Selection; +import graphql.language.SelectionSet; +import graphql.language.TypeName; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLUnmodifiedType; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.language.Field.newField; +import static graphql.language.InlineFragment.newInlineFragment; +import static graphql.language.SelectionSet.newSelectionSet; +import static graphql.language.TypeName.newTypeName; +import static graphql.schema.GraphQLTypeUtil.unwrapAll; + +/** + * This class can take a list of {@link NormalizedField}s and compiling out a + * normalised operation {@link Document} that would represent how those fields + * may be executed. + *

+ * This is essentially the reverse of {@link NormalizedDocumentFactory} which takes + * operation text and makes {@link NormalizedField}s from it, this takes {@link NormalizedField}s + * and makes operation text from it. + *

+ * You could for example send that operation text onto to some other graphql server if it + * has the same schema as the one provided. + */ +@ExperimentalApi +public class NormalizedOperationToAstCompiler { + + /** + * The result is a {@link Document} and a map of variables + * that would go with that document. + */ + public static class CompilerResult { + private final Document document; + private final Map variables; + + public CompilerResult(Document document, Map variables) { + this.document = document; + this.variables = variables; + } + + public Document getDocument() { + return document; + } + + public Map getVariables() { + return variables; + } + } + + public static CompilerResult compileToDocument(GraphQLSchema graphQLSchema, + GraphQLObjectType rootType, + List rootFields, + @Nullable String operationName, + OperationDefinition.Operation operationKind) { + + return compileToDocumentImpl(graphQLSchema, rootType, rootFields, operationName, operationKind); + } + + public static CompilerResult compileToDocument(GraphQLSchema graphQLSchema, + GraphQLObjectType rootType, + NormalizedField singleRootField, + @Nullable String operationName, + OperationDefinition.Operation operationKind) { + return compileToDocumentImpl(graphQLSchema, rootType, ImmutableList.of(singleRootField), operationName, operationKind); + + + } + + + public static CompilerResult compileToDocument(GraphQLSchema schema, + NormalizedOperation normalizedOperation) { + GraphQLObjectType operationType = getOperationType(schema, normalizedOperation.getOperation()); + + return compileToDocumentImpl( + schema, + operationType, + normalizedOperation.getRootFields(), + normalizedOperation.getOperationName(), + normalizedOperation.getOperation() + ); + } + + private static CompilerResult compileToDocumentImpl(GraphQLSchema schema, + GraphQLObjectType rootType, + List rootFields, + @Nullable String operationName, + OperationDefinition.Operation operationKind) { + + List> selections = subSelectionsForNormalizedFields(schema, rootType.getName(), rootFields); + SelectionSet selectionSet = new SelectionSet(selections); + + OperationDefinition.Builder definitionBuilder = OperationDefinition.newOperationDefinition() + .name(operationName) + .operation(operationKind) + .selectionSet(selectionSet); + +// definitionBuilder.variableDefinitions(variableAccumulator.getVariableDefinitions()); + + return new CompilerResult( + Document.newDocument() + .definition(definitionBuilder.build()) + .build(), + null + ); + } + + + private static List> subSelectionsForNormalizedFields(GraphQLSchema schema, + @NonNull String parentOutputType, + List normalizedFields + ) { + ImmutableList.Builder> selections = ImmutableList.builder(); + + // All conditional fields go here instead of directly to selections, so they can be grouped together + // in the same inline fragment in the output + Map> fieldsByTypeCondition = new LinkedHashMap<>(); + + for (NormalizedField nf : normalizedFields) { + if (nf.isConditional(schema)) { + selectionForNormalizedField(schema, nf) + .forEach((objectTypeName, field) -> + fieldsByTypeCondition + .computeIfAbsent(objectTypeName, ignored -> new ArrayList<>()) + .add(field)); + } else { + selections.add(selectionForNormalizedField(schema, parentOutputType, nf)); + } + } + + fieldsByTypeCondition.forEach((objectTypeName, fields) -> { + TypeName typeName = newTypeName(objectTypeName).build(); + InlineFragment inlineFragment = newInlineFragment() + .typeCondition(typeName) + .selectionSet(selectionSet(fields)) + .build(); + selections.add(inlineFragment); + }); + + return selections.build(); + } + + /** + * @return Map of object type names to list of fields + */ + private static Map selectionForNormalizedField(GraphQLSchema schema, + NormalizedField normalizedField + ) { + Map groupedFields = new LinkedHashMap<>(); + + for (String objectTypeName : normalizedField.getObjectTypeNames()) { + groupedFields.put(objectTypeName, selectionForNormalizedField(schema, objectTypeName, normalizedField)); + } + + return groupedFields; + } + + /** + * @return Map of object type names to list of fields + */ + private static Field selectionForNormalizedField(GraphQLSchema schema, + String objectTypeName, + NormalizedField normalizedField) { + + final List> subSelections; + if (normalizedField.getChildren().isEmpty()) { + subSelections = emptyList(); + } else { + GraphQLFieldDefinition fieldDef = getFieldDefinition(schema, objectTypeName, normalizedField); + GraphQLUnmodifiedType fieldOutputType = unwrapAll(fieldDef.getType()); + + subSelections = subSelectionsForNormalizedFields( + schema, + fieldOutputType.getName(), + normalizedField.getChildren() + ); + } + + SelectionSet selectionSet = selectionSetOrNullIfEmpty(subSelections); +// List arguments = createArguments(executableNormalizedField, variableAccumulator); + List arguments = normalizedField.getAstArguments(); + List directives = normalizedField.getAstDirectives(); + + + Field.Builder builder = newField() + .name(normalizedField.getFieldName()) + .alias(normalizedField.getAlias()) + .selectionSet(selectionSet) + .directives(directives) + .arguments(arguments); + return builder.build(); + } + + @Nullable + private static SelectionSet selectionSetOrNullIfEmpty(List> selections) { + return selections.isEmpty() ? null : newSelectionSet().selections(selections).build(); + } + + private static SelectionSet selectionSet(List fields) { + return newSelectionSet().selections(fields).build(); + } + + + @NonNull + private static GraphQLFieldDefinition getFieldDefinition(GraphQLSchema schema, + String parentType, + NormalizedField nf) { + return Introspection.getFieldDef(schema, (GraphQLCompositeType) schema.getType(parentType), nf.getName()); + } + + + private static GraphQLObjectType getOperationType(@NonNull GraphQLSchema schema, + OperationDefinition.@NonNull Operation operationKind) { + switch (operationKind) { + case QUERY: + return schema.getQueryType(); + case MUTATION: + return schema.getMutationType(); + case SUBSCRIPTION: + return schema.getSubscriptionType(); + } + + return Assert.assertShouldNeverHappen("Unknown operation kind " + operationKind); + } + +} diff --git a/src/main/java/graphql/parser/AntlrHelper.java b/src/main/java/graphql/parser/AntlrHelper.java new file mode 100644 index 0000000000..4eb52d87ba --- /dev/null +++ b/src/main/java/graphql/parser/AntlrHelper.java @@ -0,0 +1,52 @@ +package graphql.parser; + +import graphql.Internal; +import graphql.language.SourceLocation; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.TerminalNode; + +import java.util.List; + +@Internal +public class AntlrHelper { + + public static SourceLocation createSourceLocation(MultiSourceReader multiSourceReader, int antrlLine, int charPositionInLine) { + // multi source reader lines are 0 based while Antler lines are 1's based + // + // Antler columns ironically are 0 based - go figure! + // + int tokenLine = antrlLine - 1; + MultiSourceReader.SourceAndLine sourceAndLine = multiSourceReader.getSourceAndLineFromOverallLine(tokenLine); + // + // graphql spec says line numbers and columns start at 1 + int line = sourceAndLine.getLine() + 1; + int column = charPositionInLine + 1; + return new SourceLocation(line, column, sourceAndLine.getSourceName()); + + } + + public static SourceLocation createSourceLocation(MultiSourceReader multiSourceReader, Token token) { + return AntlrHelper.createSourceLocation(multiSourceReader, token.getLine(), token.getCharPositionInLine()); + } + + public static SourceLocation createSourceLocation(MultiSourceReader multiSourceReader, TerminalNode terminalNode) { + return AntlrHelper.createSourceLocation(multiSourceReader, terminalNode.getSymbol().getLine(), terminalNode.getSymbol().getCharPositionInLine()); + } + + /* grabs 3 lines before and after the syntax error */ + public static String createPreview(MultiSourceReader multiSourceReader, int antrlLine) { + int line = antrlLine - 1; + StringBuilder sb = new StringBuilder(); + int startLine = line - 3; + int endLine = line + 3; + List lines = multiSourceReader.getData(); + for (int i = 0; i < lines.size(); i++) { + if (i >= startLine && i <= endLine) { + sb.append(lines.get(i)).append('\n'); + } + } + return sb.toString(); + + } + +} diff --git a/src/main/java/graphql/parser/CommentParser.java b/src/main/java/graphql/parser/CommentParser.java new file mode 100644 index 0000000000..cb6e0f1a0d --- /dev/null +++ b/src/main/java/graphql/parser/CommentParser.java @@ -0,0 +1,247 @@ +package graphql.parser; + +import com.google.common.collect.ImmutableList; +import graphql.Internal; +import graphql.language.AbstractDescribedNode; +import graphql.language.Comment; +import graphql.language.Document; +import graphql.language.Node; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; + +/** + * Contains methods for extracting {@link Comment} in various positions within and around {@link Node}s + */ +@Internal +public class CommentParser { + private final Map, ParserRuleContext> nodeToRuleMap; + private CommonTokenStream tokens; + private static final int CHANNEL_COMMENTS = 2; + + public CommentParser(NodeToRuleCapturingParser.ParserContext parserContext) { + nodeToRuleMap = parserContext.getNodeToRuleMap(); + tokens = parserContext.getTokens(); + } + + /* + * type MyType { # beginning of type block + * field( # beginning of field args block + * arg1: String + * arg2: String + * ) + * } + */ + public Optional getBeginningOfBlockComment(Node node, String prefix) { + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + final Token start = ctx.start; + + if (start != null) { + return this.tokens.getTokens(start.getTokenIndex(), ctx.stop.getTokenIndex()).stream() + .filter(token -> token.getText().equals(prefix)) + .findFirst() + .map(token -> tokens.getHiddenTokensToRight(token.getTokenIndex(), CHANNEL_COMMENTS)) + .map(commentTokens -> getCommentOnChannel(commentTokens, isNotPrecededByLineBreak)) + .flatMap(comments -> comments.stream().findFirst()); + } + + return Optional.empty(); + } + + /* + * type MyType { + * a( + * arg1: A + * arg2: B + * # end of field args block comment + * ): A + * # end of type block comment #1 + * # end of type block comment #2 + * } + */ + public List getEndOfBlockComments(Node node, String blockSuffix) { + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + return searchTokenToLeft(ctx.stop, blockSuffix) + .map(suffixToken -> tokens.getHiddenTokensToLeft(suffixToken.getTokenIndex(), CHANNEL_COMMENTS)) + .map(commentTokens -> getCommentOnChannel(commentTokens, isPrecededByLineBreak)) + .orElse(Collections.emptyList()); + } + + /* + * type MyType { + * a: A # field trailing comment + * } # type trailing comment + */ + public Optional getTrailingComment(Node node) { + // Only nodes that can hold descriptions can have trailing comments + if (!(node instanceof AbstractDescribedNode)) { + return Optional.empty(); + } + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + List rightRefChannel = this.tokens.getHiddenTokensToRight(ctx.stop.getTokenIndex(), CHANNEL_COMMENTS); + + if (rightRefChannel != null) { + List comments = getCommentOnChannel(rightRefChannel, isNotPrecededByLineBreak); + + return comments.stream().findFirst(); + } + + return Optional.empty(); + } + + /* + * # type leading comment #1 + * # type leading comment #2 + * type MyType { + * # field leading comment #1 + * # field leading comment #2 + * a: A + * } + */ + public List getLeadingComments(Node node) { + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + final Token start = ctx.start; + if (start != null) { + int tokPos = start.getTokenIndex(); + List leftRefChannel = this.tokens.getHiddenTokensToLeft(tokPos, CHANNEL_COMMENTS); + if (leftRefChannel != null) { + return getCommentOnChannel(leftRefChannel, isPrecededByLineBreak); + } + } + + return Collections.emptyList(); + } + + /* + * """ Description """ + * # comment after description #1 + * # comment after description #2 + * type MyType { + * a: A + * } + */ + public List getCommentsAfterDescription(Node node) { + // Early return if node doesn't have a description + if (!(node instanceof AbstractDescribedNode) || + (node instanceof AbstractDescribedNode && ((AbstractDescribedNode) node).getDescription() == null) + ) { + return Collections.emptyList(); + } + + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + final Token start = ctx.start; + if (start != null) { + List commentTokens = tokens.getHiddenTokensToRight(start.getTokenIndex(), CHANNEL_COMMENTS); + + if (commentTokens != null) { + return getCommentOnChannel(commentTokens, isPrecededByLineBreak); + } + } + + return Collections.emptyList(); + } + + public Optional getCommentOnFirstLineOfDocument(Document node) { + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + final Token start = ctx.start; + if (start != null) { + int tokPos = start.getTokenIndex(); + List leftRefChannel = this.tokens.getHiddenTokensToLeft(tokPos, CHANNEL_COMMENTS); + if (leftRefChannel != null) { + List comments = getCommentOnChannel(leftRefChannel, isFirstToken.or(isPrecededOnlyBySpaces)); + + return comments.stream().findFirst(); + } + } + + return Optional.empty(); + } + + public List getCommentsAfterAllDefinitions(Document node) { + final ParserRuleContext ctx = nodeToRuleMap.get(node); + + final Token start = ctx.start; + if (start != null) { + List leftRefChannel = this.tokens.getHiddenTokensToRight(ctx.stop.getTokenIndex(), CHANNEL_COMMENTS); + if (leftRefChannel != null) { + return getCommentOnChannel(leftRefChannel, + refToken -> Optional.ofNullable(this.tokens.getHiddenTokensToLeft(refToken.getTokenIndex(), -1)) + .map(hiddenTokens -> hiddenTokens.stream().anyMatch(token -> token.getText().equals("\n"))) + .orElse(false) + ); + } + } + + return Collections.emptyList(); + } + + protected List getCommentOnChannel(List refChannel, Predicate shouldIncludePredicate) { + ImmutableList.Builder comments = ImmutableList.builder(); + for (Token refTok : refChannel) { + String text = refTok.getText(); + // we strip the leading hash # character but we don't trim because we don't + // know the "comment markup". Maybe it's space sensitive, maybe it's not. So + // consumers can decide that + if (text == null) { + continue; + } + + boolean shouldIncludeComment = shouldIncludePredicate.test(refTok); + + if (!shouldIncludeComment) { + continue; + } + + text = text.replaceFirst("^#", ""); + + comments.add(new Comment(text, null)); + } + return comments.build(); + } + + private Optional searchTokenToLeft(Token token, String text) { + int i = token.getTokenIndex(); + + while (i > 0) { + Token t = tokens.get(i); + if (t.getText().equals(text)) { + return Optional.of(t); + } + i--; + } + + return Optional.empty(); + } + + private final Predicate alwaysTrue = token -> true; + + private final Predicate isNotPrecededByLineBreak = refToken -> + Optional.ofNullable(tokens.getHiddenTokensToLeft(refToken.getTokenIndex(), -1)) + .map(hiddenTokens -> hiddenTokens.stream().noneMatch(token -> token.getText().equals("\n"))) + .orElse(false); + + private final Predicate isPrecededByLineBreak = refToken -> + Optional.ofNullable(this.tokens.getHiddenTokensToLeft(refToken.getTokenIndex(), -1)) + .map(hiddenTokens -> hiddenTokens.stream().anyMatch(token -> token.getText().equals("\n"))) + .orElse(false); + + private final Predicate isFirstToken = refToken -> refToken.getTokenIndex() == 0; + + private final Predicate isPrecededOnlyBySpaces = refToken -> + Optional.ofNullable(this.tokens.getTokens(0, refToken.getTokenIndex() - 1)) + .map(beforeTokens -> beforeTokens.stream().allMatch(token -> token.getText().equals(" "))) + .orElse(false); + +} diff --git a/src/main/java/graphql/parser/ExtendedBailStrategy.java b/src/main/java/graphql/parser/ExtendedBailStrategy.java new file mode 100644 index 0000000000..8a83904402 --- /dev/null +++ b/src/main/java/graphql/parser/ExtendedBailStrategy.java @@ -0,0 +1,84 @@ +package graphql.parser; + +import com.google.common.collect.ImmutableList; +import graphql.Internal; +import graphql.language.SourceLocation; +import graphql.parser.exceptions.MoreTokensSyntaxException; +import org.antlr.v4.runtime.BailErrorStrategy; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.misc.ParseCancellationException; + +import java.util.List; + +@Internal +public class ExtendedBailStrategy extends BailErrorStrategy { + private final MultiSourceReader multiSourceReader; + private final ParserEnvironment environment; + + public ExtendedBailStrategy(MultiSourceReader multiSourceReader, ParserEnvironment environment) { + this.multiSourceReader = multiSourceReader; + this.environment = environment; + } + + @Override + public void recover(Parser recognizer, RecognitionException e) { + try { + super.recover(recognizer, e); + } catch (ParseCancellationException parseException) { + throw mkException(recognizer, e); + } + } + + @Override + public Token recoverInline(Parser recognizer) throws RecognitionException { + try { + return super.recoverInline(recognizer); + } catch (ParseCancellationException parseException) { + throw mkException(recognizer, null); + } + } + + InvalidSyntaxException mkMoreTokensException(Token token) { + SourceLocation sourceLocation = AntlrHelper.createSourceLocation(multiSourceReader, token); + if (environment.getParserOptions().isRedactTokenParserErrorMessages()) { + return new MoreTokensSyntaxException(environment.getI18N(), sourceLocation); + } + + String sourcePreview = AntlrHelper.createPreview(multiSourceReader, token.getLine()); + return new MoreTokensSyntaxException(environment.getI18N(), sourceLocation, + token.getText(), sourcePreview); + } + + + private InvalidSyntaxException mkException(Parser recognizer, RecognitionException cause) { + String sourcePreview; + String offendingToken; + final SourceLocation sourceLocation; + Token currentToken = recognizer.getCurrentToken(); + if (currentToken != null) { + sourceLocation = AntlrHelper.createSourceLocation(multiSourceReader, currentToken); + offendingToken = currentToken.getText(); + sourcePreview = AntlrHelper.createPreview(multiSourceReader, currentToken.getLine()); + } else { + sourcePreview = null; + offendingToken = null; + sourceLocation = null; + } + + String msgKey; + List args; + SourceLocation location = sourceLocation == null ? SourceLocation.EMPTY : sourceLocation; + if (offendingToken == null || environment.getParserOptions().isRedactTokenParserErrorMessages()) { + msgKey = "InvalidSyntaxBail.noToken"; + args = ImmutableList.of(location.getLine(), location.getColumn()); + } else { + msgKey = "InvalidSyntaxBail.full"; + args = ImmutableList.of(offendingToken, sourceLocation.getLine(), sourceLocation.getColumn()); + } + String msg = environment.getI18N().msg(msgKey, args); + return new InvalidSyntaxException(msg, sourceLocation, offendingToken, sourcePreview, cause); + } + +} diff --git a/src/main/java/graphql/parser/GraphqlAntlrToLanguage.java b/src/main/java/graphql/parser/GraphqlAntlrToLanguage.java index d6aeccdd32..125e184d19 100644 --- a/src/main/java/graphql/parser/GraphqlAntlrToLanguage.java +++ b/src/main/java/graphql/parser/GraphqlAntlrToLanguage.java @@ -1,8 +1,10 @@ package graphql.parser; - +import com.google.common.collect.ImmutableList; import graphql.Assert; import graphql.Internal; +import graphql.collect.ImmutableKit; +import graphql.i18n.I18n; import graphql.language.Argument; import graphql.language.ArrayValue; import graphql.language.BooleanValue; @@ -22,6 +24,8 @@ import graphql.language.FloatValue; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; +import graphql.language.IgnoredChar; +import graphql.language.IgnoredChars; import graphql.language.InlineFragment; import graphql.language.InputObjectTypeDefinition; import graphql.language.InputObjectTypeExtensionDefinition; @@ -30,8 +34,10 @@ import graphql.language.InterfaceTypeDefinition; import graphql.language.InterfaceTypeExtensionDefinition; import graphql.language.ListType; +import graphql.language.Node; import graphql.language.NodeBuilder; import graphql.language.NonNullType; +import graphql.language.NullValue; import graphql.language.ObjectField; import graphql.language.ObjectTypeDefinition; import graphql.language.ObjectTypeExtensionDefinition; @@ -42,6 +48,7 @@ import graphql.language.ScalarTypeDefinition; import graphql.language.ScalarTypeExtensionDefinition; import graphql.language.SchemaDefinition; +import graphql.language.SchemaExtensionDefinition; import graphql.language.Selection; import graphql.language.SelectionSet; import graphql.language.SourceLocation; @@ -54,32 +61,50 @@ import graphql.language.Value; import graphql.language.VariableDefinition; import graphql.language.VariableReference; +import graphql.parser.antlr.GraphqlLexer; import graphql.parser.antlr.GraphqlParser; import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.IntStream; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.jspecify.annotations.Nullable; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; import static graphql.Assert.assertShouldNeverHappen; -import static graphql.language.NullValue.Null; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.map; +import static graphql.parser.Parser.CHANNEL_COMMENTS; +import static graphql.parser.Parser.CHANNEL_WHITESPACE; import static graphql.parser.StringValueParsing.parseSingleQuotedString; import static graphql.parser.StringValueParsing.parseTripleQuotedString; +import static java.util.Optional.ofNullable; @Internal public class GraphqlAntlrToLanguage { + private static final List NO_COMMENTS = ImmutableKit.emptyList(); private final CommonTokenStream tokens; + private final MultiSourceReader multiSourceReader; + private final ParserOptions parserOptions; + private final Map, ParserRuleContext> nodeToRuleMap; + private final I18n i18N; - - public GraphqlAntlrToLanguage(CommonTokenStream tokens) { + public GraphqlAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiSourceReader, ParserOptions parserOptions, I18n i18N, @Nullable Map, ParserRuleContext> nodeToRuleMap) { this.tokens = tokens; + this.multiSourceReader = multiSourceReader; + this.parserOptions = ofNullable(parserOptions).orElse(ParserOptions.getDefaultParserOptions()); + this.i18N = i18N; + this.nodeToRuleMap = nodeToRuleMap; + + } + + public ParserOptions getParserOptions() { + return parserOptions; } //MARKER START: Here GraphqlOperation.g4 specific methods begin @@ -88,9 +113,8 @@ public GraphqlAntlrToLanguage(CommonTokenStream tokens) { public Document createDocument(GraphqlParser.DocumentContext ctx) { Document.Builder document = Document.newDocument(); addCommonData(document, ctx); - document.definitions(ctx.definition().stream().map(definition -> createDefinition(definition)) - .collect(Collectors.toList())); - return document.build(); + document.definitions(map(ctx.definition(), this::createDefinition)); + return captureRuleContext(document.build(), ctx); } protected Definition createDefinition(GraphqlParser.DefinitionContext definitionContext) { @@ -100,10 +124,11 @@ protected Definition createDefinition(GraphqlParser.DefinitionContext definition return createFragmentDefinition(definitionContext.fragmentDefinition()); } else if (definitionContext.typeSystemDefinition() != null) { return createTypeSystemDefinition(definitionContext.typeSystemDefinition()); + } else if (definitionContext.typeSystemExtension() != null) { + return createTypeSystemExtension(definitionContext.typeSystemExtension()); } else { return assertShouldNeverHappen(); } - } protected OperationDefinition createOperationDefinition(GraphqlParser.OperationDefinitionContext ctx) { @@ -120,18 +145,19 @@ protected OperationDefinition createOperationDefinition(GraphqlParser.OperationD operationDefinition.variableDefinitions(createVariableDefinitions(ctx.variableDefinitions())); operationDefinition.selectionSet(createSelectionSet(ctx.selectionSet())); operationDefinition.directives(createDirectives(ctx.directives())); - return operationDefinition.build(); + return captureRuleContext(operationDefinition.build(), ctx); } protected OperationDefinition.Operation parseOperation(GraphqlParser.OperationTypeContext operationTypeContext) { - if (operationTypeContext.getText().equals("query")) { - return OperationDefinition.Operation.QUERY; - } else if (operationTypeContext.getText().equals("mutation")) { - return OperationDefinition.Operation.MUTATION; - } else if (operationTypeContext.getText().equals("subscription")) { - return OperationDefinition.Operation.SUBSCRIPTION; - } else { - return assertShouldNeverHappen("InternalError: unknown operationTypeContext=%s", operationTypeContext.getText()); + switch (operationTypeContext.getText()) { + case "query": + return OperationDefinition.Operation.QUERY; + case "mutation": + return OperationDefinition.Operation.MUTATION; + case "subscription": + return OperationDefinition.Operation.SUBSCRIPTION; + default: + return assertShouldNeverHappen("InternalError: unknown operationTypeContext=%s", operationTypeContext.getText()); } } @@ -139,12 +165,14 @@ protected FragmentSpread createFragmentSpread(GraphqlParser.FragmentSpreadContex FragmentSpread.Builder fragmentSpread = FragmentSpread.newFragmentSpread().name(ctx.fragmentName().getText()); addCommonData(fragmentSpread, ctx); fragmentSpread.directives(createDirectives(ctx.directives())); - return fragmentSpread.build(); + return captureRuleContext(fragmentSpread.build(), ctx); } protected List createVariableDefinitions(GraphqlParser.VariableDefinitionsContext ctx) { - if (ctx == null) return new ArrayList<>(); - return ctx.variableDefinition().stream().map(this::createVariableDefinition).collect(Collectors.toList()); + if (ctx == null) { + return emptyList(); + } + return map(ctx.variableDefinition(), this::createVariableDefinition); } protected VariableDefinition createVariableDefinition(GraphqlParser.VariableDefinitionContext ctx) { @@ -156,7 +184,8 @@ protected VariableDefinition createVariableDefinition(GraphqlParser.VariableDefi variableDefinition.defaultValue(value); } variableDefinition.type(createType(ctx.type())); - return variableDefinition.build(); + variableDefinition.directives(createDirectives(ctx.directives())); + return captureRuleContext(variableDefinition.build(), ctx); } @@ -167,15 +196,17 @@ protected FragmentDefinition createFragmentDefinition(GraphqlParser.FragmentDefi fragmentDefinition.typeCondition(TypeName.newTypeName().name(ctx.typeCondition().typeName().getText()).build()); fragmentDefinition.directives(createDirectives(ctx.directives())); fragmentDefinition.selectionSet(createSelectionSet(ctx.selectionSet())); - return fragmentDefinition.build(); + return captureRuleContext(fragmentDefinition.build(), ctx); } protected SelectionSet createSelectionSet(GraphqlParser.SelectionSetContext ctx) { - if (ctx == null) return null; + if (ctx == null) { + return null; + } SelectionSet.Builder builder = SelectionSet.newSelectionSet(); addCommonData(builder, ctx); - List selections = ctx.selection().stream().map(selectionContext -> { + List selections = map(ctx.selection(), selectionContext -> { if (selectionContext.field() != null) { return createField(selectionContext.field()); } @@ -185,11 +216,11 @@ protected SelectionSet createSelectionSet(GraphqlParser.SelectionSetContext ctx) if (selectionContext.inlineFragment() != null) { return createInlineFragment(selectionContext.inlineFragment()); } - return (Selection) Assert.assertShouldNeverHappen(); + return Assert.assertShouldNeverHappen(); - }).collect(Collectors.toList()); + }); builder.selections(selections); - return builder.build(); + return captureRuleContext(builder.build(), ctx); } @@ -204,7 +235,7 @@ protected Field createField(GraphqlParser.FieldContext ctx) { builder.directives(createDirectives(ctx.directives())); builder.arguments(createArguments(ctx.arguments())); builder.selectionSet(createSelectionSet(ctx.selectionSet())); - return builder.build(); + return captureRuleContext(builder.build(), ctx); } @@ -216,7 +247,7 @@ protected InlineFragment createInlineFragment(GraphqlParser.InlineFragmentContex } inlineFragment.directives(createDirectives(ctx.directives())); inlineFragment.selectionSet(createSelectionSet(ctx.selectionSet())); - return inlineFragment.build(); + return captureRuleContext(inlineFragment.build(), ctx); } //MARKER END: Here GraphqlOperation.g4 specific methods end @@ -228,8 +259,16 @@ protected SDLDefinition createTypeSystemDefinition(GraphqlParser.TypeSystemDefin return createDirectiveDefinition(ctx.directiveDefinition()); } else if (ctx.typeDefinition() != null) { return createTypeDefinition(ctx.typeDefinition()); - } else if (ctx.typeExtension() != null) { + } else { + return assertShouldNeverHappen(); + } + } + + protected SDLDefinition createTypeSystemExtension(GraphqlParser.TypeSystemExtensionContext ctx) { + if (ctx.typeExtension() != null) { return createTypeExtension(ctx.typeExtension()); + } else if (ctx.schemaExtension() != null) { + return creationSchemaExtension(ctx.schemaExtension()); } else { return assertShouldNeverHappen(); } @@ -299,7 +338,7 @@ protected TypeName createTypeName(GraphqlParser.TypeNameContext ctx) { TypeName.Builder builder = TypeName.newTypeName(); builder.name(ctx.name().getText()); addCommonData(builder, ctx); - return builder.build(); + return captureRuleContext(builder.build(), ctx); } protected NonNullType createNonNullType(GraphqlParser.NonNullTypeContext ctx) { @@ -312,14 +351,14 @@ protected NonNullType createNonNullType(GraphqlParser.NonNullTypeContext ctx) { } else { return assertShouldNeverHappen(); } - return builder.build(); + return captureRuleContext(builder.build(), ctx); } protected ListType createListType(GraphqlParser.ListTypeContext ctx) { ListType.Builder builder = ListType.newListType(); addCommonData(builder, ctx); builder.type(createType(ctx.type())); - return builder.build(); + return captureRuleContext(builder.build(), ctx); } protected Argument createArgument(GraphqlParser.ArgumentContext ctx) { @@ -327,18 +366,22 @@ protected Argument createArgument(GraphqlParser.ArgumentContext ctx) { addCommonData(builder, ctx); builder.name(ctx.name().getText()); builder.value(createValue(ctx.valueWithVariable())); - return builder.build(); + return captureRuleContext(builder.build(), ctx); } protected List createArguments(GraphqlParser.ArgumentsContext ctx) { - if (ctx == null) return new ArrayList<>(); - return ctx.argument().stream().map(this::createArgument).collect(Collectors.toList()); + if (ctx == null) { + return emptyList(); + } + return map(ctx.argument(), this::createArgument); } protected List createDirectives(GraphqlParser.DirectivesContext ctx) { - if (ctx == null) return new ArrayList<>(); - return ctx.directive().stream().map(this::createDirective).collect(Collectors.toList()); + if (ctx == null) { + return emptyList(); + } + return map(ctx.directive(), this::createDirective); } protected Directive createDirective(GraphqlParser.DirectiveContext ctx) { @@ -346,24 +389,41 @@ protected Directive createDirective(GraphqlParser.DirectiveContext ctx) { builder.name(ctx.name().getText()); addCommonData(builder, ctx); builder.arguments(createArguments(ctx.arguments())); - return builder.build(); + return captureRuleContext(builder.build(), ctx); } protected SchemaDefinition createSchemaDefinition(GraphqlParser.SchemaDefinitionContext ctx) { SchemaDefinition.Builder def = SchemaDefinition.newSchemaDefinition(); addCommonData(def, ctx); def.directives(createDirectives(ctx.directives())); - def.operationTypeDefinitions(ctx.operationTypeDefinition().stream() - .map(this::createOperationTypeDefinition).collect(Collectors.toList())); - return def.build(); + def.description(newDescription(ctx.description())); + def.operationTypeDefinitions(map(ctx.operationTypeDefinition(), this::createOperationTypeDefinition)); + return captureRuleContext(def.build(), ctx); } + private SDLDefinition creationSchemaExtension(GraphqlParser.SchemaExtensionContext ctx) { + SchemaExtensionDefinition.Builder def = SchemaExtensionDefinition.newSchemaExtensionDefinition(); + addCommonData(def, ctx); + + List directives = new ArrayList<>(); + + GraphqlParser.DirectivesContext directivesCtx = ctx.directives(); + directives.addAll(createDirectives(directivesCtx)); + + def.directives(directives); + + List operationTypeDefs = map(ctx.operationTypeDefinition(), this::createOperationTypeDefinition); + def.operationTypeDefinitions(operationTypeDefs); + return captureRuleContext(def.build(), ctx); + } + + protected OperationTypeDefinition createOperationTypeDefinition(GraphqlParser.OperationTypeDefinitionContext ctx) { OperationTypeDefinition.Builder def = OperationTypeDefinition.newOperationTypeDefinition(); def.name(ctx.operationType().getText()); - def.type(createTypeName(ctx.typeName())); + def.typeName(createTypeName(ctx.typeName())); addCommonData(def, ctx); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected ScalarTypeDefinition createScalarTypeDefinition(GraphqlParser.ScalarTypeDefinitionContext ctx) { @@ -372,7 +432,7 @@ protected ScalarTypeDefinition createScalarTypeDefinition(GraphqlParser.ScalarTy addCommonData(def, ctx); def.description(newDescription(ctx.description())); def.directives(createDirectives(ctx.directives())); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected ScalarTypeExtensionDefinition createScalarTypeExtensionDefinition(GraphqlParser.ScalarTypeExtensionDefinitionContext ctx) { @@ -380,7 +440,7 @@ protected ScalarTypeExtensionDefinition createScalarTypeExtensionDefinition(Grap def.name(ctx.name().getText()); addCommonData(def, ctx); def.directives(createDirectives(ctx.directives())); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected ObjectTypeDefinition createObjectTypeDefinition(GraphqlParser.ObjectTypeDefinitionContext ctx) { @@ -390,17 +450,12 @@ protected ObjectTypeDefinition createObjectTypeDefinition(GraphqlParser.ObjectTy def.description(newDescription(ctx.description())); def.directives(createDirectives(ctx.directives())); GraphqlParser.ImplementsInterfacesContext implementsInterfacesContext = ctx.implementsInterfaces(); - List implementz = new ArrayList<>(); - while (implementsInterfacesContext != null) { - List typeNames = implementsInterfacesContext.typeName().stream().map(this::createTypeName).collect(Collectors.toList()); - implementz.addAll(0, typeNames); - implementsInterfacesContext = implementsInterfacesContext.implementsInterfaces(); - } + List implementz = getImplementz(implementsInterfacesContext); def.implementz(implementz); if (ctx.fieldsDefinition() != null) { def.fieldDefinitions(createFieldDefinitions(ctx.fieldsDefinition())); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected ObjectTypeExtensionDefinition createObjectTypeExtensionDefinition(GraphqlParser.ObjectTypeExtensionDefinitionContext ctx) { @@ -409,24 +464,29 @@ protected ObjectTypeExtensionDefinition createObjectTypeExtensionDefinition(Grap addCommonData(def, ctx); def.directives(createDirectives(ctx.directives())); GraphqlParser.ImplementsInterfacesContext implementsInterfacesContext = ctx.implementsInterfaces(); - List implementz = new ArrayList<>(); - while (implementsInterfacesContext != null) { - List typeNames = implementsInterfacesContext.typeName().stream().map(this::createTypeName).collect(Collectors.toList()); - implementz.addAll(0, typeNames); - implementsInterfacesContext = implementsInterfacesContext.implementsInterfaces(); - } + List implementz = getImplementz(implementsInterfacesContext); def.implementz(implementz); - if (ctx.fieldsDefinition() != null) { - def.fieldDefinitions(createFieldDefinitions(ctx.fieldsDefinition())); + if (ctx.extensionFieldsDefinition() != null) { + def.fieldDefinitions(createFieldDefinitions(ctx.extensionFieldsDefinition())); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected List createFieldDefinitions(GraphqlParser.FieldsDefinitionContext ctx) { - if (ctx == null) return new ArrayList<>(); - return ctx.fieldDefinition().stream().map(this::createFieldDefinition).collect(Collectors.toList()); + if (ctx == null) { + return emptyList(); + } + return map(ctx.fieldDefinition(), this::createFieldDefinition); + } + + protected List createFieldDefinitions(GraphqlParser.ExtensionFieldsDefinitionContext ctx) { + if (ctx == null) { + return emptyList(); + } + return map(ctx.fieldDefinition(), this::createFieldDefinition); } + protected FieldDefinition createFieldDefinition(GraphqlParser.FieldDefinitionContext ctx) { FieldDefinition.Builder def = FieldDefinition.newFieldDefinition(); def.name(ctx.name().getText()); @@ -437,12 +497,11 @@ protected FieldDefinition createFieldDefinition(GraphqlParser.FieldDefinitionCon if (ctx.argumentsDefinition() != null) { def.inputValueDefinitions(createInputValueDefinitions(ctx.argumentsDefinition().inputValueDefinition())); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected List createInputValueDefinitions(List defs) { - return defs.stream().map(this::createInputValueDefinition).collect(Collectors.toList()); - + return map(defs, this::createInputValueDefinition); } protected InputValueDefinition createInputValueDefinition(GraphqlParser.InputValueDefinitionContext ctx) { @@ -455,7 +514,7 @@ protected InputValueDefinition createInputValueDefinition(GraphqlParser.InputVal def.defaultValue(createValue(ctx.defaultValue().value())); } def.directives(createDirectives(ctx.directives())); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected InterfaceTypeDefinition createInterfaceTypeDefinition(GraphqlParser.InterfaceTypeDefinitionContext ctx) { @@ -464,8 +523,11 @@ protected InterfaceTypeDefinition createInterfaceTypeDefinition(GraphqlParser.In addCommonData(def, ctx); def.description(newDescription(ctx.description())); def.directives(createDirectives(ctx.directives())); + GraphqlParser.ImplementsInterfacesContext implementsInterfacesContext = ctx.implementsInterfaces(); + List implementz = getImplementz(implementsInterfacesContext); + def.implementz(implementz); def.definitions(createFieldDefinitions(ctx.fieldsDefinition())); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected InterfaceTypeExtensionDefinition createInterfaceTypeExtensionDefinition(GraphqlParser.InterfaceTypeExtensionDefinitionContext ctx) { @@ -473,8 +535,11 @@ protected InterfaceTypeExtensionDefinition createInterfaceTypeExtensionDefinitio def.name(ctx.name().getText()); addCommonData(def, ctx); def.directives(createDirectives(ctx.directives())); - def.definitions(createFieldDefinitions(ctx.fieldsDefinition())); - return def.build(); + GraphqlParser.ImplementsInterfacesContext implementsInterfacesContext = ctx.implementsInterfaces(); + List implementz = getImplementz(implementsInterfacesContext); + def.implementz(implementz); + def.definitions(createFieldDefinitions(ctx.extensionFieldsDefinition())); + return captureRuleContext(def.build(), ctx); } protected UnionTypeDefinition createUnionTypeDefinition(GraphqlParser.UnionTypeDefinitionContext ctx) { @@ -484,13 +549,16 @@ protected UnionTypeDefinition createUnionTypeDefinition(GraphqlParser.UnionTypeD def.description(newDescription(ctx.description())); def.directives(createDirectives(ctx.directives())); List members = new ArrayList<>(); - GraphqlParser.UnionMembersContext unionMembersContext = ctx.unionMembership().unionMembers(); - while (unionMembersContext != null) { - members.add(0, createTypeName(unionMembersContext.typeName())); - unionMembersContext = unionMembersContext.unionMembers(); + GraphqlParser.UnionMembershipContext unionMembership = ctx.unionMembership(); + if (unionMembership != null) { + GraphqlParser.UnionMembersContext unionMembersContext = unionMembership.unionMembers(); + while (unionMembersContext != null) { + members.add(0, createTypeName(unionMembersContext.typeName())); + unionMembersContext = unionMembersContext.unionMembers(); + } } def.memberTypes(members); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected UnionTypeExtensionDefinition createUnionTypeExtensionDefinition(GraphqlParser.UnionTypeExtensionDefinitionContext ctx) { @@ -507,7 +575,7 @@ protected UnionTypeExtensionDefinition createUnionTypeExtensionDefinition(Graphq } def.memberTypes(members); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected EnumTypeDefinition createEnumTypeDefinition(GraphqlParser.EnumTypeDefinitionContext ctx) { @@ -518,9 +586,9 @@ protected EnumTypeDefinition createEnumTypeDefinition(GraphqlParser.EnumTypeDefi def.directives(createDirectives(ctx.directives())); if (ctx.enumValueDefinitions() != null) { def.enumValueDefinitions( - ctx.enumValueDefinitions().enumValueDefinition().stream().map(this::createEnumValueDefinition).collect(Collectors.toList())); + map(ctx.enumValueDefinitions().enumValueDefinition(), this::createEnumValueDefinition)); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected EnumTypeExtensionDefinition createEnumTypeExtensionDefinition(GraphqlParser.EnumTypeExtensionDefinitionContext ctx) { @@ -528,11 +596,11 @@ protected EnumTypeExtensionDefinition createEnumTypeExtensionDefinition(GraphqlP def.name(ctx.name().getText()); addCommonData(def, ctx); def.directives(createDirectives(ctx.directives())); - if (ctx.enumValueDefinitions() != null) { + if (ctx.extensionEnumValueDefinitions() != null) { def.enumValueDefinitions( - ctx.enumValueDefinitions().enumValueDefinition().stream().map(this::createEnumValueDefinition).collect(Collectors.toList())); + map(ctx.extensionEnumValueDefinitions().enumValueDefinition(), this::createEnumValueDefinition)); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected EnumValueDefinition createEnumValueDefinition(GraphqlParser.EnumValueDefinitionContext ctx) { @@ -541,7 +609,7 @@ protected EnumValueDefinition createEnumValueDefinition(GraphqlParser.EnumValueD addCommonData(def, ctx); def.description(newDescription(ctx.description())); def.directives(createDirectives(ctx.directives())); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected InputObjectTypeDefinition createInputObjectTypeDefinition(GraphqlParser.InputObjectTypeDefinitionContext ctx) { @@ -553,7 +621,7 @@ protected InputObjectTypeDefinition createInputObjectTypeDefinition(GraphqlParse if (ctx.inputObjectValueDefinitions() != null) { def.inputValueDefinitions(createInputValueDefinitions(ctx.inputObjectValueDefinitions().inputValueDefinition())); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected InputObjectTypeExtensionDefinition createInputObjectTypeExtensionDefinition(GraphqlParser.InputObjectTypeExtensionDefinitionContext ctx) { @@ -561,10 +629,10 @@ protected InputObjectTypeExtensionDefinition createInputObjectTypeExtensionDefin def.name(ctx.name().getText()); addCommonData(def, ctx); def.directives(createDirectives(ctx.directives())); - if (ctx.inputObjectValueDefinitions() != null) { - def.inputValueDefinitions(createInputValueDefinitions(ctx.inputObjectValueDefinitions().inputValueDefinition())); + if (ctx.extensionInputObjectValueDefinitions() != null) { + def.inputValueDefinitions(createInputValueDefinitions(ctx.extensionInputObjectValueDefinitions().inputValueDefinition())); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected DirectiveDefinition createDirectiveDefinition(GraphqlParser.DirectiveDefinitionContext ctx) { @@ -572,6 +640,9 @@ protected DirectiveDefinition createDirectiveDefinition(GraphqlParser.DirectiveD def.name(ctx.name().getText()); addCommonData(def, ctx); def.description(newDescription(ctx.description())); + + def.repeatable(ctx.REPEATABLE() != null); + GraphqlParser.DirectiveLocationsContext directiveLocationsContext = ctx.directiveLocations(); List directiveLocations = new ArrayList<>(); while (directiveLocationsContext != null) { @@ -582,39 +653,46 @@ protected DirectiveDefinition createDirectiveDefinition(GraphqlParser.DirectiveD if (ctx.argumentsDefinition() != null) { def.inputValueDefinitions(createInputValueDefinitions(ctx.argumentsDefinition().inputValueDefinition())); } - return def.build(); + return captureRuleContext(def.build(), ctx); } protected DirectiveLocation createDirectiveLocation(GraphqlParser.DirectiveLocationContext ctx) { DirectiveLocation.Builder def = DirectiveLocation.newDirectiveLocation(); def.name(ctx.name().getText()); addCommonData(def, ctx); - return def.build(); + return captureRuleContext(def.build(), ctx); } protected Value createValue(GraphqlParser.ValueWithVariableContext ctx) { if (ctx.IntValue() != null) { IntValue.Builder intValue = IntValue.newIntValue().value(new BigInteger(ctx.IntValue().getText())); addCommonData(intValue, ctx); - return intValue.build(); + return captureRuleContext(intValue.build(), ctx); } else if (ctx.FloatValue() != null) { - FloatValue.Builder floatValue = FloatValue.newFloatValue().value(new BigDecimal(ctx.FloatValue().getText())); + FloatValue.Builder floatValue; + try { + floatValue = FloatValue.newFloatValue().value(new BigDecimal(ctx.FloatValue().getText())); + } catch (NumberFormatException e) { + throw new InvalidSyntaxException("Invalid floating point value", null, ctx.FloatValue().getText(), null, e); + } addCommonData(floatValue, ctx); - return floatValue.build(); + return captureRuleContext(floatValue.build(), ctx); } else if (ctx.BooleanValue() != null) { BooleanValue.Builder booleanValue = BooleanValue.newBooleanValue().value(Boolean.parseBoolean(ctx.BooleanValue().getText())); addCommonData(booleanValue, ctx); - return booleanValue.build(); + return captureRuleContext(booleanValue.build(), ctx); } else if (ctx.NullValue() != null) { - return Null; - } else if (ctx.stringValue() != null) { - StringValue.Builder stringValue = StringValue.newStringValue().value(quotedString(ctx.stringValue())); + NullValue.Builder nullValue = NullValue.newNullValue(); + addCommonData(nullValue, ctx); + return captureRuleContext(nullValue.build(), ctx); + } else if (ctx.StringValue() != null) { + StringValue.Builder stringValue = StringValue.newStringValue().value(quotedString(ctx.StringValue())); addCommonData(stringValue, ctx); - return stringValue.build(); + return captureRuleContext(stringValue.build(), ctx); } else if (ctx.enumValue() != null) { EnumValue.Builder enumValue = EnumValue.newEnumValue().name(ctx.enumValue().getText()); addCommonData(enumValue, ctx); - return enumValue.build(); + return captureRuleContext(enumValue.build(), ctx); } else if (ctx.arrayValueWithVariable() != null) { ArrayValue.Builder arrayValue = ArrayValue.newArrayValue(); addCommonData(arrayValue, ctx); @@ -622,7 +700,7 @@ protected Value createValue(GraphqlParser.ValueWithVariableContext ctx) { for (GraphqlParser.ValueWithVariableContext valueWithVariableContext : ctx.arrayValueWithVariable().valueWithVariable()) { values.add(createValue(valueWithVariableContext)); } - return arrayValue.values(values).build(); + return captureRuleContext(arrayValue.values(values).build(), ctx); } else if (ctx.objectValueWithVariable() != null) { ObjectValue.Builder objectValue = ObjectValue.newObjectValue(); addCommonData(objectValue, ctx); @@ -636,11 +714,11 @@ protected Value createValue(GraphqlParser.ValueWithVariableContext ctx) { .build(); objectFields.add(objectField); } - return objectValue.objectFields(objectFields).build(); + return captureRuleContext(objectValue.objectFields(objectFields).build(), ctx); } else if (ctx.variable() != null) { VariableReference.Builder variableReference = VariableReference.newVariableReference().name(ctx.variable().name().getText()); addCommonData(variableReference, ctx); - return variableReference.build(); + return captureRuleContext(variableReference.build(), ctx); } return assertShouldNeverHappen(); } @@ -649,25 +727,27 @@ protected Value createValue(GraphqlParser.ValueContext ctx) { if (ctx.IntValue() != null) { IntValue.Builder intValue = IntValue.newIntValue().value(new BigInteger(ctx.IntValue().getText())); addCommonData(intValue, ctx); - return intValue.build(); + return captureRuleContext(intValue.build(), ctx); } else if (ctx.FloatValue() != null) { FloatValue.Builder floatValue = FloatValue.newFloatValue().value(new BigDecimal(ctx.FloatValue().getText())); addCommonData(floatValue, ctx); - return floatValue.build(); + return captureRuleContext(floatValue.build(), ctx); } else if (ctx.BooleanValue() != null) { BooleanValue.Builder booleanValue = BooleanValue.newBooleanValue().value(Boolean.parseBoolean(ctx.BooleanValue().getText())); addCommonData(booleanValue, ctx); - return booleanValue.build(); + return captureRuleContext(booleanValue.build(), ctx); } else if (ctx.NullValue() != null) { - return Null; - } else if (ctx.stringValue() != null) { - StringValue.Builder stringValue = StringValue.newStringValue().value(quotedString(ctx.stringValue())); + NullValue.Builder nullValue = NullValue.newNullValue(); + addCommonData(nullValue, ctx); + return captureRuleContext(nullValue.build(), ctx); + } else if (ctx.StringValue() != null) { + StringValue.Builder stringValue = StringValue.newStringValue().value(quotedString(ctx.StringValue())); addCommonData(stringValue, ctx); - return stringValue.build(); + return captureRuleContext(stringValue.build(), ctx); } else if (ctx.enumValue() != null) { EnumValue.Builder enumValue = EnumValue.newEnumValue().name(ctx.enumValue().getText()); addCommonData(enumValue, ctx); - return enumValue.build(); + return captureRuleContext(enumValue.build(), ctx); } else if (ctx.arrayValue() != null) { ArrayValue.Builder arrayValue = ArrayValue.newArrayValue(); addCommonData(arrayValue, ctx); @@ -675,7 +755,7 @@ protected Value createValue(GraphqlParser.ValueContext ctx) { for (GraphqlParser.ValueContext valueContext : ctx.arrayValue().value()) { values.add(createValue(valueContext)); } - return arrayValue.values(values).build(); + return captureRuleContext(arrayValue.values(values).build(), ctx); } else if (ctx.objectValue() != null) { ObjectValue.Builder objectValue = ObjectValue.newObjectValue(); addCommonData(objectValue, ctx); @@ -688,18 +768,19 @@ protected Value createValue(GraphqlParser.ValueContext ctx) { .build(); objectFields.add(objectField); } - return objectValue.objectFields(objectFields).build(); + return captureRuleContext(objectValue.objectFields(objectFields).build(), ctx); } return assertShouldNeverHappen(); } - static String quotedString(GraphqlParser.StringValueContext ctx) { - boolean multiLine = ctx.TripleQuotedStringValue() != null; - String strText = ctx.getText(); + protected String quotedString(TerminalNode terminalNode) { + boolean multiLine = terminalNode.getText().startsWith("\"\"\""); + String strText = terminalNode.getText(); + SourceLocation sourceLocation = AntlrHelper.createSourceLocation(multiSourceReader, terminalNode); if (multiLine) { return parseTripleQuotedString(strText); } else { - return parseSingleQuotedString(strText); + return parseSingleQuotedString(i18N, strText, sourceLocation); } } @@ -709,67 +790,147 @@ protected void addCommonData(NodeBuilder nodeBuilder, ParserRuleContext parserRu nodeBuilder.comments(comments); } nodeBuilder.sourceLocation(getSourceLocation(parserRuleContext)); + addIgnoredChars(parserRuleContext, nodeBuilder); + } + + private void addIgnoredChars(ParserRuleContext ctx, NodeBuilder nodeBuilder) { + if (!parserOptions.isCaptureIgnoredChars()) { + return; + } + Token start = ctx.getStart(); + int tokenStartIndex = start.getTokenIndex(); + List leftChannel = tokens.getHiddenTokensToLeft(tokenStartIndex, CHANNEL_WHITESPACE); + List ignoredCharsLeft = mapTokenToIgnoredChar(leftChannel); + + Token stop = ctx.getStop(); + int tokenStopIndex = stop.getTokenIndex(); + List rightChannel = tokens.getHiddenTokensToRight(tokenStopIndex, CHANNEL_WHITESPACE); + List ignoredCharsRight = mapTokenToIgnoredChar(rightChannel); + + nodeBuilder.ignoredChars(new IgnoredChars(ignoredCharsLeft, ignoredCharsRight)); + } + + private List mapTokenToIgnoredChar(List tokens) { + if (tokens == null) { + return emptyList(); + } + return map(tokens, this::createIgnoredChar); + + } + + private IgnoredChar createIgnoredChar(Token token) { + String symbolicName = GraphqlLexer.VOCABULARY.getSymbolicName(token.getType()); + IgnoredChar.IgnoredCharKind kind; + switch (symbolicName) { + case "CR": + kind = IgnoredChar.IgnoredCharKind.CR; + break; + case "LF": + kind = IgnoredChar.IgnoredCharKind.LF; + break; + case "Tab": + kind = IgnoredChar.IgnoredCharKind.TAB; + break; + case "Comma": + kind = IgnoredChar.IgnoredCharKind.COMMA; + break; + case "Space": + kind = IgnoredChar.IgnoredCharKind.SPACE; + break; + default: + kind = IgnoredChar.IgnoredCharKind.OTHER; + } + return new IgnoredChar(token.getText(), kind, getSourceLocation(token)); } protected Description newDescription(GraphqlParser.DescriptionContext descriptionCtx) { if (descriptionCtx == null) { return null; } - GraphqlParser.StringValueContext stringValueCtx = descriptionCtx.stringValue(); - if (stringValueCtx == null) { + TerminalNode terminalNode = descriptionCtx.StringValue(); + if (terminalNode == null) { return null; } - boolean multiLine = stringValueCtx.TripleQuotedStringValue() != null; - String content = stringValueCtx.getText(); + String content = terminalNode.getText(); + boolean multiLine = content.startsWith("\"\"\""); + SourceLocation sourceLocation = getSourceLocation(descriptionCtx); if (multiLine) { content = parseTripleQuotedString(content); } else { - content = parseSingleQuotedString(content); + content = parseSingleQuotedString(i18N, content, sourceLocation); } - SourceLocation sourceLocation = getSourceLocation(descriptionCtx); return new Description(content, sourceLocation, multiLine); } - protected SourceLocation getSourceLocation(ParserRuleContext parserRuleContext) { - Token startToken = parserRuleContext.getStart(); - String sourceName = startToken.getTokenSource().getSourceName(); - if (IntStream.UNKNOWN_SOURCE_NAME.equals(sourceName)) { - // UNKNOWN_SOURCE_NAME is Antrl's way of indicating that no source name was given during parsing -- - // which is the case when queries and other operations are parsed. We don't want this hardcoded - // '' sourceName to leak to clients when the response is serialized as JSON, so we null it. - sourceName = null; + return getSourceLocation(parserRuleContext.getStart()); + } + + protected SourceLocation getSourceLocation(Token token) { + if (parserOptions.isCaptureSourceLocation()) { + return AntlrHelper.createSourceLocation(multiSourceReader, token); + } else { + return SourceLocation.EMPTY; } - return new SourceLocation(startToken.getLine(), startToken.getCharPositionInLine() + 1, sourceName); } protected List getComments(ParserRuleContext ctx) { + if (!parserOptions.isCaptureLineComments()) { + return NO_COMMENTS; + } + Token start = ctx.getStart(); if (start != null) { int tokPos = start.getTokenIndex(); - List refChannel = tokens.getHiddenTokensToLeft(tokPos, 2); + List refChannel = tokens.getHiddenTokensToLeft(tokPos, CHANNEL_COMMENTS); if (refChannel != null) { return getCommentOnChannel(refChannel); } } - return Collections.emptyList(); + return NO_COMMENTS; } protected List getCommentOnChannel(List refChannel) { - List comments = new ArrayList<>(); + ImmutableList.Builder comments = ImmutableList.builder(); for (Token refTok : refChannel) { String text = refTok.getText(); // we strip the leading hash # character but we don't trim because we don't - // know the "comment markup". Maybe its space sensitive, maybe its not. So + // know the "comment markup". Maybe it's space sensitive, maybe it's not. So // consumers can decide that if (text == null) { continue; } text = text.replaceFirst("^#", ""); - comments.add(new Comment(text, new SourceLocation(refTok.getLine(), refTok.getCharPositionInLine()))); + MultiSourceReader.SourceAndLine sourceAndLine = multiSourceReader.getSourceAndLineFromOverallLine(refTok.getLine()); + int column = refTok.getCharPositionInLine(); + // graphql spec says line numbers start at 1 + int line = sourceAndLine.getLine() + 1; + + SourceLocation sourceLocation = SourceLocation.EMPTY; + if (parserOptions.isCaptureSourceLocation()) { + sourceLocation = new SourceLocation(line, column, sourceAndLine.getSourceName()); + } + comments.add(new Comment(text, sourceLocation)); } - return comments; + return comments.build(); } + + private List getImplementz(GraphqlParser.ImplementsInterfacesContext implementsInterfacesContext) { + List implementz = new ArrayList<>(); + while (implementsInterfacesContext != null) { + GraphqlParser.TypeNameContext typeName = implementsInterfacesContext.typeName(); + implementz.add(0, createTypeName(typeName)); + implementsInterfacesContext = implementsInterfacesContext.implementsInterfaces(); + } + return implementz; + } + + private > T captureRuleContext(T node, ParserRuleContext ctx) { + if (nodeToRuleMap != null) { + nodeToRuleMap.put(node, ctx); + } + return node; + } } diff --git a/src/main/java/graphql/parser/InvalidSyntaxException.java b/src/main/java/graphql/parser/InvalidSyntaxException.java new file mode 100644 index 0000000000..939dfd2e2d --- /dev/null +++ b/src/main/java/graphql/parser/InvalidSyntaxException.java @@ -0,0 +1,56 @@ +package graphql.parser; + + +import graphql.GraphQLException; +import graphql.Internal; +import graphql.InvalidSyntaxError; +import graphql.PublicApi; +import graphql.language.SourceLocation; + +import java.util.Collections; +import java.util.List; + +/** + * This exception is thrown by the {@link Parser} if the graphql syntax is not valid + */ +@PublicApi +public class InvalidSyntaxException extends GraphQLException { + + private final String message; + private final String sourcePreview; + private final String offendingToken; + private final SourceLocation location; + + @Internal + protected InvalidSyntaxException(String msg, SourceLocation location, String offendingToken, String sourcePreview, Exception cause) { + super(cause); + this.message = msg; + this.sourcePreview = sourcePreview; + this.offendingToken = offendingToken; + this.location = location; + } + + public InvalidSyntaxError toInvalidSyntaxError() { + List sourceLocations = location == null ? null : Collections.singletonList(location); + return new InvalidSyntaxError(sourceLocations, message, sourcePreview, offendingToken); + } + + @Override + public String getMessage() { + return message; + } + + public SourceLocation getLocation() { + return location; + } + + public String getSourcePreview() { + return sourcePreview; + } + + public String getOffendingToken() { + return offendingToken; + } + +} + diff --git a/src/main/java/graphql/parser/MultiSourceReader.java b/src/main/java/graphql/parser/MultiSourceReader.java new file mode 100644 index 0000000000..fad54b2fa0 --- /dev/null +++ b/src/main/java/graphql/parser/MultiSourceReader.java @@ -0,0 +1,309 @@ +package graphql.parser; + +import graphql.Assert; +import graphql.PublicApi; +import graphql.util.LockKit; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.List; + +/** + * This reader allows you to read N number readers and combine them as one logical reader + * however you can then map back to the underlying readers in terms of their source name + * and the relative lines numbers. + * + * It can also track all data in memory if you want to have all of the previous read data in + * place at some point in time. + */ +@PublicApi +public class MultiSourceReader extends Reader { + + // In Java version 16+, LineNumberReader.read considers end-of-stream to be a line terminator + // and will increment the line number, whereas in previous versions it doesn't. + private static final boolean LINE_NUMBER_READER_EOS_IS_TERMINATOR; + + private final List sourceParts; + private final StringBuilder data = new StringBuilder(); + private int currentIndex = 0; + private int overallLineNumber = 0; + private final boolean trackData; + private final LockKit.ReentrantLock readerLock = new LockKit.ReentrantLock(); + + static { + LINE_NUMBER_READER_EOS_IS_TERMINATOR = lineNumberReaderEOSIsTerminator(); + } + + private static boolean lineNumberReaderEOSIsTerminator() { + LineNumberReader reader = new LineNumberReader(new StringReader("a")); + try { + reader.read(); + reader.read(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return reader.getLineNumber() > 0; + } + + + private MultiSourceReader(Builder builder) { + this.sourceParts = builder.sourceParts; + this.trackData = builder.trackData; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + while (true) { + readerLock.lock(); + try { + if (currentIndex >= sourceParts.size()) { + return -1; + } + SourcePart sourcePart = sourceParts.get(currentIndex); + int read = sourcePart.lineReader.read(cbuf, off, len); + if (read == -1) { + currentIndex++; + sourcePart.reachedEndOfStream = true; + } else if (read > 0) { + sourcePart.lastRead = cbuf[off + read - 1]; + } + // note: calcLineNumber() must be called after updating sourcePart.reachedEndOfStream + // and sourcePart.lastRead + overallLineNumber = calcLineNumber(); + if (read != -1) { + trackData(cbuf, off, read); + return read; + } + } finally { + readerLock.unlock(); + } + } + } + + private void trackData(char[] cbuf, int off, int len) { + if (trackData) { + data.append(cbuf, off, len); + } + } + + private int calcLineNumber() { + int linenumber = 0; + for (SourcePart sourcePart : sourceParts) { + linenumber += sourcePart.getLineNumber(); + } + return linenumber; + } + + public static class SourceAndLine { + private String sourceName = null; + private int line = 0; + + public String getSourceName() { + return sourceName; + } + + public int getLine() { + return line; + } + + @Override + public String toString() { + return "SourceAndLine{" + + "sourceName='" + sourceName + '\'' + + ", line=" + line + + '}'; + } + } + + /** + * This returns the source name and line number given an overall line number + * + * This is zeroes based like {@link java.io.LineNumberReader#getLineNumber()} + * + * @param overallLineNumber the over all line number + * + * @return the source name and relative line number to that source + */ + public SourceAndLine getSourceAndLineFromOverallLine(int overallLineNumber) { + SourceAndLine sourceAndLine = new SourceAndLine(); + if (sourceParts.isEmpty()) { + return sourceAndLine; + } + if (overallLineNumber == 0) { + sourceAndLine.sourceName = sourceParts.get(0).sourceName; + sourceAndLine.line = 0; + return sourceAndLine; + } + SourcePart currentPart; + if (currentIndex >= sourceParts.size()) { + currentPart = sourceParts.get(sourceParts.size() - 1); + } else { + currentPart = sourceParts.get(currentIndex); + } + int page = 0; + int previousPage; + for (SourcePart sourcePart : sourceParts) { + sourceAndLine.sourceName = sourcePart.sourceName; + if (sourcePart == currentPart) { + // we cant go any further + int partLineNumber = currentPart.getLineNumber(); + previousPage = page; + page += partLineNumber; + if (page > overallLineNumber) { + sourceAndLine.line = overallLineNumber - previousPage; + } else { + sourceAndLine.line = page; + } + return sourceAndLine; + } else { + previousPage = page; + int partLineNumber = sourcePart.getLineNumber(); + page += partLineNumber; + if (page > overallLineNumber) { + sourceAndLine.line = overallLineNumber - previousPage; + return sourceAndLine; + } + } + } + sourceAndLine.line = overallLineNumber - page; + return sourceAndLine; + } + + /** + * @return the line number of the current source. This is zeroes based like {@link java.io.LineNumberReader#getLineNumber()} + */ + public int getLineNumber() { + return readerLock.callLocked(() -> { + if (sourceParts.isEmpty()) { + return 0; + } + if (currentIndex >= sourceParts.size()) { + return sourceParts.get(sourceParts.size() - 1).getLineNumber(); + } + return sourceParts.get(currentIndex).getLineNumber(); + }); + } + + /** + * @return The name of the current source + */ + public String getSourceName() { + return readerLock.callLocked(() -> { + if (sourceParts.isEmpty()) { + return null; + } + if (currentIndex >= sourceParts.size()) { + return sourceParts.get(sourceParts.size() - 1).sourceName; + } + return sourceParts.get(currentIndex).sourceName; + }); + } + + /** + * @return the overall line number of the all the sources. This is zeroes based like {@link java.io.LineNumberReader#getLineNumber()} + */ + public int getOverallLineNumber() { + return overallLineNumber; + } + + public List getData() { + LineNumberReader reader = new LineNumberReader(new StringReader(data.toString())); + List lines = new ArrayList<>(); + while (true) { + try { + String line = reader.readLine(); + if (line == null) { + return lines; + } + lines.add(line); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + } + + @Override + public void close() throws IOException { + readerLock.lock(); + try { + for (SourcePart sourcePart : sourceParts) { + if (!sourcePart.closed) { + sourcePart.lineReader.close(); + sourcePart.closed = true; + } + } + } finally { + readerLock.unlock(); + } + } + + private static class SourcePart { + String sourceName; + LineNumberReader lineReader; + boolean closed; + char lastRead; + boolean reachedEndOfStream = false; + + /** + * This handles the discrepancy between LineNumberReader.getLineNumber() for Java versions + * 16+ vs below. Use this instead of lineReader.getLineNumber() directly. + * @return The current line number. EOS is not considered a line terminator. + */ + int getLineNumber() { + int lineNumber = lineReader.getLineNumber(); + if (reachedEndOfStream + && LINE_NUMBER_READER_EOS_IS_TERMINATOR + && lastRead != '\r' + && lastRead != '\n') { + return Math.max(lineNumber - 1, 0); + } + return lineNumber; + } + } + + + public static Builder newMultiSourceReader() { + return new Builder(); + } + + public static class Builder { + List sourceParts = new ArrayList<>(); + boolean trackData = true; + + private Builder() { + } + + public Builder reader(Reader reader, String sourceName) { + SourcePart sourcePart = new SourcePart(); + sourcePart.lineReader = new LineNumberReader(Assert.assertNotNull(reader)); + sourcePart.sourceName = sourceName; + sourcePart.closed = false; + sourceParts.add(sourcePart); + return this; + } + + public Builder string(String input, String sourceName) { + SourcePart sourcePart = new SourcePart(); + sourcePart.lineReader = new LineNumberReader(new StringReader(input)); + sourcePart.sourceName = sourceName; + sourcePart.closed = false; + sourceParts.add(sourcePart); + return this; + } + + public Builder trackData(boolean trackData) { + this.trackData = trackData; + return this; + + } + + public MultiSourceReader build() { + return new MultiSourceReader(this); + } + } + +} diff --git a/src/main/java/graphql/parser/NodeToRuleCapturingParser.java b/src/main/java/graphql/parser/NodeToRuleCapturingParser.java new file mode 100644 index 0000000000..f63fe58166 --- /dev/null +++ b/src/main/java/graphql/parser/NodeToRuleCapturingParser.java @@ -0,0 +1,49 @@ +package graphql.parser; + +import graphql.Internal; +import graphql.language.Node; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; + +import java.util.HashMap; +import java.util.Map; + +/** + * A parser that will capture parsing context data which can be later used for accessing tokens that are discarded + * during the conventional parsing process (like comments). + */ +@Internal +public class NodeToRuleCapturingParser extends Parser { + private final ParserContext parserContext; + + public NodeToRuleCapturingParser() { + parserContext = new ParserContext(); + } + + @Override + protected GraphqlAntlrToLanguage getAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiSourceReader, ParserEnvironment environment) { + parserContext.tokens = tokens; + return new GraphqlAntlrToLanguage(tokens, multiSourceReader, environment.getParserOptions(), environment.getI18N(), parserContext.nodeToRuleMap); + } + + public ParserContext getParserContext() { + return parserContext; + } + + static public class ParserContext { + private final Map, ParserRuleContext> nodeToRuleMap; + private CommonTokenStream tokens; + + public ParserContext() { + this.nodeToRuleMap = new HashMap<>(); + } + + protected CommonTokenStream getTokens() { + return tokens; + } + + protected Map, ParserRuleContext> getNodeToRuleMap() { + return nodeToRuleMap; + } + } +} diff --git a/src/main/java/graphql/parser/Parser.java b/src/main/java/graphql/parser/Parser.java index 9240a44128..c2015f274f 100644 --- a/src/main/java/graphql/parser/Parser.java +++ b/src/main/java/graphql/parser/Parser.java @@ -1,63 +1,455 @@ package graphql.parser; +import com.google.common.collect.ImmutableList; import graphql.Internal; +import graphql.PublicApi; import graphql.language.Document; +import graphql.language.FieldDefinition; +import graphql.language.Node; +import graphql.language.SourceLocation; +import graphql.language.Type; +import graphql.language.Value; +import graphql.parser.antlr.GraphqlBaseListener; import graphql.parser.antlr.GraphqlLexer; import graphql.parser.antlr.GraphqlParser; -import org.antlr.v4.runtime.BailErrorStrategy; -import org.antlr.v4.runtime.CharStream; +import graphql.parser.exceptions.ParseCancelledException; +import graphql.parser.exceptions.ParseCancelledTooDeepException; +import graphql.parser.exceptions.ParseCancelledTooManyCharsException; +import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CodePointCharStream; import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.jspecify.annotations.NonNull; +import java.io.IOException; +import java.io.Reader; +import java.io.UncheckedIOException; import java.util.List; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; -@Internal +/** + * This can parse graphql syntax, both Query syntax and Schema Definition Language (SDL) syntax, into an + * Abstract Syntax Tree (AST) represented by a {@link Document} + *

+ * You should not generally need to call this class as the {@link graphql.GraphQL} code sets this up for you + * but if you are doing specific graphql utilities this class is essential. + *

+ * Graphql syntax has a series of characters, such as spaces, new lines and commas that are not considered relevant + * to the syntax. However they can be captured and associated with the AST elements they belong to. + *

+ * This costs more memory but for certain use cases (like editors) this maybe be useful. We have chosen to no capture + * ignored characters by default but you can turn this on, either per parse or statically for the whole JVM + * via {@link ParserOptions#setDefaultParserOptions(ParserOptions)} ()}} + * + * @see graphql.language.IgnoredChar + */ +@PublicApi public class Parser { - public Document parseDocument(String input) { - return parseDocument(input, null); + @Internal + public static final int CHANNEL_COMMENTS = 2; + @Internal + public static final int CHANNEL_WHITESPACE = 3; + + /** + * Parses a string input into a graphql AST {@link Document} + * + * @param environment the parser environment to use + * + * @return an AST {@link Document} + * + * @throws InvalidSyntaxException if the document is not valid graphql syntax + */ + public static Document parse(ParserEnvironment environment) throws InvalidSyntaxException { + return new Parser().parseDocument(environment); } - public Document parseDocument(String input, String sourceName) { + /** + * Parses a string input into a graphql AST {@link Document} + * + * @param input the input to parse + * + * @return an AST {@link Document} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public static Document parse(String input) throws InvalidSyntaxException { + return new Parser().parseDocument(input); + } - CharStream charStream; - if(sourceName == null) { - charStream = CharStreams.fromString(input); - } else{ - charStream = CharStreams.fromString(input, sourceName); - } - GraphqlLexer lexer = new GraphqlLexer(charStream); + /** + * Parses a string input into a graphql AST {@link Value} + * + * @param input the input to parse + * + * @return an AST {@link Value} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public static Value parseValue(String input) throws InvalidSyntaxException { + return new Parser().parseValueImpl(input); + } + + /** + * Parses a string input into a graphql AST {@link FieldDefinition} + * + * @param input the input to parse + * + * @return an AST {@link FieldDefinition} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public static FieldDefinition parseFieldDefinition(String input) throws InvalidSyntaxException { + return new Parser().parseFieldDefinitionImpl(input); + } + + /** + * Parses a string input into a graphql AST Type + * + * @param input the input to parse + * + * @return an AST {@link Type} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public static Type parseType(String input) throws InvalidSyntaxException { + return new Parser().parseTypeImpl(input); + } - CommonTokenStream tokens = new CommonTokenStream(lexer); + /** + * Parses document text into a graphql AST {@link Document} + * + * @param environment the parser environment to sue + * + * @return an AST {@link Document} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public Document parseDocument(ParserEnvironment environment) throws InvalidSyntaxException { + return parseDocumentImpl(environment); + } + + /** + * Parses a string input into a graphql AST {@link Document} + * + * @param input the input to parse + * + * @return an AST {@link Document} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public Document parseDocument(String input) throws InvalidSyntaxException { + MultiSourceReader multiSourceReader = MultiSourceReader.newMultiSourceReader() + .string(input, null) + .trackData(true) + .build(); + + ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment() + .document(multiSourceReader) + .build(); + return parseDocumentImpl(parserEnvironment); + } + + /** + * Parses reader input into a graphql AST {@link Document} + * + * @param reader the reader input to parse + * + * @return an AST {@link Document} + * + * @throws InvalidSyntaxException if the input is not valid graphql syntax + */ + public Document parseDocument(Reader reader) throws InvalidSyntaxException { + ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment() + .document(reader) + .build(); + return parseDocumentImpl(parserEnvironment); + } + + private Document parseDocumentImpl(ParserEnvironment environment) throws InvalidSyntaxException { + BiFunction nodeFunction = (parser, toLanguage) -> { + GraphqlParser.DocumentContext documentContext = parser.document(); + Document doc = toLanguage.createDocument(documentContext); + return new Object[]{documentContext, doc}; + }; + return (Document) parseImpl(environment, nodeFunction); + } + + private Value parseValueImpl(String input) throws InvalidSyntaxException { + BiFunction nodeFunction = (parser, toLanguage) -> { + GraphqlParser.ValueContext documentContext = parser.value(); + Value value = toLanguage.createValue(documentContext); + return new Object[]{documentContext, value}; + }; + MultiSourceReader multiSourceReader = MultiSourceReader.newMultiSourceReader() + .string(input, null) + .trackData(true) + .build(); + ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment().document(multiSourceReader).build(); + return (Value) parseImpl(parserEnvironment, nodeFunction); + } + + private Type parseTypeImpl(String input) throws InvalidSyntaxException { + BiFunction nodeFunction = (parser, toLanguage) -> { + final GraphqlParser.TypeContext documentContext = parser.type(); + Type value = toLanguage.createType(documentContext); + return new Object[]{documentContext, value}; + }; + MultiSourceReader multiSourceReader = MultiSourceReader.newMultiSourceReader() + .string(input, null) + .trackData(true) + .build(); + + ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment().document(multiSourceReader).build(); + return (Type) parseImpl(parserEnvironment, nodeFunction); + } + + private FieldDefinition parseFieldDefinitionImpl(String input) throws InvalidSyntaxException { + BiFunction nodeFunction = (parser, toLanguage) -> { + final GraphqlParser.FieldDefinitionContext documentContext = parser.fieldDefinition(); + FieldDefinition value = toLanguage.createFieldDefinition(documentContext); + return new Object[]{documentContext, value}; + }; + MultiSourceReader multiSourceReader = MultiSourceReader.newMultiSourceReader() + .string(input, null) + .trackData(true) + .build(); + + ParserEnvironment parserEnvironment = ParserEnvironment.newParserEnvironment().document(multiSourceReader).build(); + return (FieldDefinition) parseImpl(parserEnvironment, nodeFunction); + } + + private Node parseImpl(ParserEnvironment environment, BiFunction nodeFunction) throws InvalidSyntaxException { + // default in the parser options if they are not set + ParserOptions parserOptions = environment.getParserOptions(); + parserOptions = Optional.ofNullable(parserOptions).orElse(ParserOptions.getDefaultParserOptions()); + + MultiSourceReader multiSourceReader = setupMultiSourceReader(environment, parserOptions); + + SafeTokenReader safeTokenReader = setupSafeTokenReader(environment, parserOptions, multiSourceReader); + + CodePointCharStream charStream = setupCharStream(safeTokenReader); + + GraphqlLexer lexer = setupGraphqlLexer(environment, multiSourceReader, charStream); + + // this lexer wrapper allows us to stop lexing when too many tokens are in place. This prevents DOS attacks. + SafeTokenSource safeTokenSource = getSafeTokenSource(environment, parserOptions, multiSourceReader, lexer); + + CommonTokenStream tokens = new CommonTokenStream(safeTokenSource); GraphqlParser parser = new GraphqlParser(tokens); parser.removeErrorListeners(); parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - parser.setErrorHandler(new BailErrorStrategy()); - GraphqlParser.DocumentContext documentContext = parser.document(); + + ExtendedBailStrategy bailStrategy = new ExtendedBailStrategy(multiSourceReader, environment); + parser.setErrorHandler(bailStrategy); + + // preserve old protected call semantics - remove at some point + GraphqlAntlrToLanguage toLanguage = getAntlrToLanguage(tokens, multiSourceReader, environment); + + setupParserListener(environment, multiSourceReader, parser, toLanguage); - GraphqlAntlrToLanguage antlrToLanguage = new GraphqlAntlrToLanguage(tokens); - Document doc = antlrToLanguage.createDocument(documentContext); + // + // parsing starts ...... now! + // + Object[] contextAndNode = nodeFunction.apply(parser, toLanguage); + ParserRuleContext parserRuleContext = (ParserRuleContext) contextAndNode[0]; + Node node = (Node) contextAndNode[1]; - Token stop = documentContext.getStop(); + Token stop = parserRuleContext.getStop(); List allTokens = tokens.getTokens(); if (stop != null && allTokens != null && !allTokens.isEmpty()) { Token last = allTokens.get(allTokens.size() - 1); // // do we have more tokens in the stream than we consumed in the parse? - // if yes then its invalid. We make sure its the same channel + // if yes then it's invalid. We make sure it's the same channel boolean notEOF = last.getType() != Token.EOF; boolean lastGreaterThanDocument = last.getTokenIndex() > stop.getTokenIndex(); boolean sameChannel = last.getChannel() == stop.getChannel(); if (notEOF && lastGreaterThanDocument && sameChannel) { - throw new ParseCancellationException("There are more tokens in the query that have not been consumed"); + throw bailStrategy.mkMoreTokensException(last); } } - return doc; + return node; + } + + private static MultiSourceReader setupMultiSourceReader(ParserEnvironment environment, ParserOptions parserOptions) { + MultiSourceReader multiSourceReader; + Reader reader = environment.getDocument(); + if (reader instanceof MultiSourceReader) { + multiSourceReader = (MultiSourceReader) reader; + } else { + multiSourceReader = MultiSourceReader.newMultiSourceReader() + .reader(reader, null) + .trackData(parserOptions.isReaderTrackData()) + .build(); + } + return multiSourceReader; + } + + @NonNull + private static SafeTokenReader setupSafeTokenReader(ParserEnvironment environment, ParserOptions parserOptions, MultiSourceReader multiSourceReader) { + int maxCharacters = parserOptions.getMaxCharacters(); + Consumer onTooManyCharacters = it -> { + throw new ParseCancelledTooManyCharsException(environment.getI18N(), maxCharacters); + }; + return new SafeTokenReader(multiSourceReader, maxCharacters, onTooManyCharacters); + } + + @NonNull + private static CodePointCharStream setupCharStream(SafeTokenReader safeTokenReader) { + CodePointCharStream charStream; + try { + charStream = CharStreams.fromReader(safeTokenReader); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return charStream; + } + + @NonNull + private static GraphqlLexer setupGraphqlLexer(ParserEnvironment environment, MultiSourceReader multiSourceReader, CodePointCharStream charStream) { + GraphqlLexer lexer = new GraphqlLexer(charStream); + lexer.removeErrorListeners(); + lexer.addErrorListener(new BaseErrorListener() { + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String antlerMsg, RecognitionException e) { + SourceLocation sourceLocation = AntlrHelper.createSourceLocation(multiSourceReader, line, charPositionInLine); + String preview = AntlrHelper.createPreview(multiSourceReader, line); + String msgKey; + List args; + if (antlerMsg == null || environment.getParserOptions().isRedactTokenParserErrorMessages()) { + msgKey = "InvalidSyntax.noMessage"; + args = ImmutableList.of(sourceLocation.getLine(), sourceLocation.getColumn()); + } else { + msgKey = "InvalidSyntax.full"; + args = ImmutableList.of(antlerMsg, sourceLocation.getLine(), sourceLocation.getColumn()); + } + String msg = environment.getI18N().msg(msgKey, args); + throw new InvalidSyntaxException(msg, sourceLocation, null, preview, null); + } + }); + return lexer; + } + + @NonNull + private SafeTokenSource getSafeTokenSource(ParserEnvironment environment, ParserOptions parserOptions, MultiSourceReader multiSourceReader, GraphqlLexer lexer) { + int maxTokens = parserOptions.getMaxTokens(); + int maxWhitespaceTokens = parserOptions.getMaxWhitespaceTokens(); + BiConsumer onTooManyTokens = (maxTokenCount, token) -> throwIfTokenProblems( + environment, + token, + maxTokenCount, + multiSourceReader, + ParseCancelledException.class); + return new SafeTokenSource(lexer, maxTokens, maxWhitespaceTokens, onTooManyTokens); + } + + private void setupParserListener(ParserEnvironment environment, MultiSourceReader multiSourceReader, GraphqlParser parser, GraphqlAntlrToLanguage toLanguage) { + ParserOptions parserOptions = toLanguage.getParserOptions(); + ParsingListener parsingListener = parserOptions.getParsingListener(); + int maxTokens = parserOptions.getMaxTokens(); + int maxRuleDepth = parserOptions.getMaxRuleDepth(); + // prevent a billion laugh attacks by restricting how many tokens we allow + ParseTreeListener listener = new GraphqlBaseListener() { + int count = 0; + int depth = 0; + + + @Override + public void enterEveryRule(ParserRuleContext ctx) { + depth++; + if (depth > maxRuleDepth) { + throwIfTokenProblems( + environment, + ctx.getStart(), + maxRuleDepth, + multiSourceReader, + ParseCancelledTooDeepException.class + ); + } + } + + @Override + public void exitEveryRule(ParserRuleContext ctx) { + depth--; + } + + @Override + public void visitTerminal(TerminalNode node) { + + final Token token = node.getSymbol(); + parsingListener.onToken(new ParsingListener.Token() { + @Override + public String getText() { + return token == null ? null : token.getText(); + } + + @Override + public int getLine() { + return token == null ? -1 : token.getLine(); + } + + @Override + public int getCharPositionInLine() { + return token == null ? -1 : token.getCharPositionInLine(); + } + }); + + count++; + if (count > maxTokens) { + throwIfTokenProblems( + environment, + token, + maxTokens, + multiSourceReader, + ParseCancelledException.class + ); + } + } + }; + parser.addParseListener(listener); + } + + private void throwIfTokenProblems(ParserEnvironment environment, Token token, int maxLimit, MultiSourceReader multiSourceReader, Class targetException) throws ParseCancelledException { + String tokenType = "grammar"; + SourceLocation sourceLocation = null; + String offendingToken = null; + if (token != null) { + int channel = token.getChannel(); + tokenType = channel == CHANNEL_WHITESPACE ? "whitespace" : (channel == CHANNEL_COMMENTS ? "comments" : "grammar"); + + offendingToken = token.getText(); + sourceLocation = AntlrHelper.createSourceLocation(multiSourceReader, token.getLine(), token.getCharPositionInLine()); + } + if (targetException.equals(ParseCancelledTooDeepException.class)) { + throw new ParseCancelledTooDeepException(environment.getI18N(), sourceLocation, offendingToken, maxLimit, tokenType); + } + throw new ParseCancelledException(environment.getI18N(), sourceLocation, offendingToken, maxLimit, tokenType); + } + + /** + * Allows you to override the ANTLR to AST code. + * + * @param tokens the token stream + * @param multiSourceReader the source of the query document + * @param environment the parser environment + * + * @return a new GraphqlAntlrToLanguage instance + */ + protected GraphqlAntlrToLanguage getAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiSourceReader, ParserEnvironment environment) { + return new GraphqlAntlrToLanguage(tokens, multiSourceReader, environment.getParserOptions(), environment.getI18N(), null); } } diff --git a/src/main/java/graphql/parser/ParserEnvironment.java b/src/main/java/graphql/parser/ParserEnvironment.java new file mode 100644 index 0000000000..7f0ac696ba --- /dev/null +++ b/src/main/java/graphql/parser/ParserEnvironment.java @@ -0,0 +1,97 @@ +package graphql.parser; + +import graphql.PublicApi; +import graphql.i18n.I18n; + +import java.io.Reader; +import java.io.StringReader; +import java.util.Locale; + +import static graphql.Assert.assertNotNull; + +/** + * This is the arguments that can be passed to a {@link Parser} + */ +@PublicApi +public interface ParserEnvironment { + + /** + * @return the document to be parsed + */ + Reader getDocument(); + + /** + * @return the parsing options + */ + ParserOptions getParserOptions(); + + /** + * @return the locale to produce parsing error messages in + */ + Locale getLocale(); + + /** + * @return the {@link I18n} to produce parsing error messages with + */ + I18n getI18N(); + + /** + * @return a builder of new parsing options + */ + static Builder newParserEnvironment() { + return new Builder(); + } + + class Builder { + Reader reader; + ParserOptions parserOptions = ParserOptions.getDefaultParserOptions(); + Locale locale = Locale.getDefault(); + + public Builder() { + } + + public Builder document(Reader documentText) { + this.reader = assertNotNull(documentText); + return this; + } + + public Builder document(String documentText) { + return document(new StringReader(documentText)); + } + + public Builder parserOptions(ParserOptions parserOptions) { + this.parserOptions = parserOptions; + return this; + } + + public Builder locale(Locale locale) { + this.locale = assertNotNull(locale); + return this; + } + + public ParserEnvironment build() { + I18n i18n = I18n.i18n(I18n.BundleType.Parsing, locale); + return new ParserEnvironment() { + @Override + public Reader getDocument() { + return reader; + } + + @Override + public ParserOptions getParserOptions() { + return parserOptions; + } + + @Override + public Locale getLocale() { + return locale; + } + + @Override + public I18n getI18N() { + return i18n; + } + }; + } + } +} diff --git a/src/main/java/graphql/parser/ParserOptions.java b/src/main/java/graphql/parser/ParserOptions.java new file mode 100644 index 0000000000..2e04294427 --- /dev/null +++ b/src/main/java/graphql/parser/ParserOptions.java @@ -0,0 +1,410 @@ +package graphql.parser; + +import graphql.PublicApi; + +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; + +/** + * Options that control how the {@link Parser} behaves. + */ +@PublicApi +public class ParserOptions { + /** + * A graphql hacking vector is to send nonsensical queries with large tokens that contain a repeated characters + * that burn lots of parsing CPU time and burn memory representing a document that won't ever execute. + * To prevent this for most users, graphql-java sets this value to 1MB. + * ANTLR parsing time is linear to the number of characters presented. The more you + * allow the longer it takes. + *

+ * If you want to allow more, then {@link #setDefaultParserOptions(ParserOptions)} allows you to change this + * JVM wide. + */ + public static final int MAX_QUERY_CHARACTERS = 1024 * 1024; // 1 MB + + /** + * A graphql hacking vector is to send nonsensical queries with lots of tokens that burn lots of parsing CPU time and burn + * memory representing a document that won't ever execute. To prevent this for most users, graphql-java + * sets this value to 15000. ANTLR parsing time is linear to the number of tokens presented. The more you + * allow the longer it takes. + *

+ * If you want to allow more, then {@link #setDefaultParserOptions(ParserOptions)} allows you to change this + * JVM wide. + */ + public static final int MAX_QUERY_TOKENS = 15_000; + /** + * Another graphql hacking vector is to send large amounts of whitespace in operations that burn lots of parsing CPU time and burn + * memory representing a document. Whitespace token processing in ANTLR is 2 orders of magnitude faster than grammar token processing + * however it still takes some time to happen. + *

+ * If you want to allow more, then {@link #setDefaultParserOptions(ParserOptions)} allows you to change this + * JVM wide. + */ + public static final int MAX_WHITESPACE_TOKENS = 200_000; + + /** + * A graphql hacking vector is to send nonsensical queries that have lots of grammar rule depth to them which + * can cause stack overflow exceptions during the query parsing. To prevent this for most users, graphql-java + * sets this value to 500 grammar rules deep. + *

+ * If you want to allow more, then {@link #setDefaultParserOptions(ParserOptions)} allows you to change this + * JVM wide. + */ + public static final int MAX_RULE_DEPTH = 500; + + private static ParserOptions defaultJvmParserOptions = newParserOptions() + .captureIgnoredChars(false) + .captureSourceLocation(true) + .captureLineComments(true) + .readerTrackData(true) + .maxCharacters(MAX_QUERY_CHARACTERS) + .maxTokens(MAX_QUERY_TOKENS) // to prevent a billion laughs style attacks, we set a default for graphql-java + .maxWhitespaceTokens(MAX_WHITESPACE_TOKENS) + .maxRuleDepth(MAX_RULE_DEPTH) + .redactTokenParserErrorMessages(false) + .build(); + + private static ParserOptions defaultJvmOperationParserOptions = newParserOptions() + .captureIgnoredChars(false) + .captureSourceLocation(true) + .captureLineComments(false) // #comments are not useful in query parsing + .readerTrackData(true) + .maxCharacters(MAX_QUERY_CHARACTERS) + .maxTokens(MAX_QUERY_TOKENS) // to prevent a billion laughs style attacks, we set a default for graphql-java + .maxWhitespaceTokens(MAX_WHITESPACE_TOKENS) + .maxRuleDepth(MAX_RULE_DEPTH) + .redactTokenParserErrorMessages(false) + .build(); + + private static ParserOptions defaultJvmSdlParserOptions = newParserOptions() + .captureIgnoredChars(false) + .captureSourceLocation(true) + .captureLineComments(true) // #comments are useful in SDL parsing + .readerTrackData(true) + .maxCharacters(Integer.MAX_VALUE) + .maxTokens(Integer.MAX_VALUE) // we are less worried about a billion laughs with SDL parsing since the call path is not facing attackers + .maxWhitespaceTokens(Integer.MAX_VALUE) + .maxRuleDepth(Integer.MAX_VALUE) + .redactTokenParserErrorMessages(false) + .build(); + + /** + * By default, the Parser will not capture ignored characters. A static holds this default + * value in a JVM wide basis options object. + * + * Significant memory savings can be made if we do NOT capture ignored characters, + * especially in SDL parsing. + * + * @return the static default JVM value + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public static ParserOptions getDefaultParserOptions() { + return defaultJvmParserOptions; + } + + /** + * By default, the Parser will not capture ignored characters. A static holds this default + * value in a JVM wide basis options object. + * + * Significant memory savings can be made if we do NOT capture ignored characters, + * especially in SDL parsing. So we have set this to false by default. + * + * This static can be set to true to allow the behavior of version 16.x or before. + * + * @param options - the new default JVM parser options + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public static void setDefaultParserOptions(ParserOptions options) { + defaultJvmParserOptions = assertNotNull(options); + } + + + /** + * By default, for operation parsing, the Parser will not capture ignored characters, and it will not capture line comments into AST + * elements . A static holds this default value for operation parsing in a JVM wide basis options object. + * + * @return the static default JVM value for operation parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public static ParserOptions getDefaultOperationParserOptions() { + return defaultJvmOperationParserOptions; + } + + /** + * By default, the Parser will not capture ignored characters or line comments. A static holds this default + * value in a JVM wide basis options object for operation parsing. + * + * This static can be set to true to allow the behavior of version 16.x or before. + * + * @param options - the new default JVM parser options for operation parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public static void setDefaultOperationParserOptions(ParserOptions options) { + defaultJvmOperationParserOptions = assertNotNull(options); + } + + /** + * By default, for SDL parsing, the Parser will not capture ignored characters, but it will capture line comments into AST + * elements. The SDL default options allow unlimited tokens and whitespace, since a DOS attack vector is + * not commonly available via schema SDL parsing. + * + * A static holds this default value for SDL parsing in a JVM wide basis options object. + * + * @return the static default JVM value for SDL parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + * @see graphql.schema.idl.SchemaParser + */ + public static ParserOptions getDefaultSdlParserOptions() { + return defaultJvmSdlParserOptions; + } + + /** + * By default, for SDL parsing, the Parser will not capture ignored characters, but it will capture line comments into AST + * elements . A static holds this default value for operation parsing in a JVM wide basis options object. + * + * This static can be set to true to allow the behavior of version 16.x or before. + * + * @param options - the new default JVM parser options for SDL parsing + * + * @see graphql.language.IgnoredChar + * @see graphql.language.SourceLocation + */ + public static void setDefaultSdlParserOptions(ParserOptions options) { + defaultJvmSdlParserOptions = assertNotNull(options); + } + + private final boolean captureIgnoredChars; + private final boolean captureSourceLocation; + private final boolean captureLineComments; + private final boolean readerTrackData; + private final int maxCharacters; + private final int maxTokens; + private final int maxWhitespaceTokens; + private final int maxRuleDepth; + private final boolean redactTokenParserErrorMessages; + private final ParsingListener parsingListener; + + private ParserOptions(Builder builder) { + this.captureIgnoredChars = builder.captureIgnoredChars; + this.captureSourceLocation = builder.captureSourceLocation; + this.captureLineComments = builder.captureLineComments; + this.readerTrackData = builder.readerTrackData; + this.maxCharacters = builder.maxCharacters; + this.maxTokens = builder.maxTokens; + this.maxWhitespaceTokens = builder.maxWhitespaceTokens; + this.maxRuleDepth = builder.maxRuleDepth; + this.redactTokenParserErrorMessages = builder.redactTokenParserErrorMessages; + this.parsingListener = builder.parsingListener; + } + + /** + * Significant memory savings can be made if we do NOT capture ignored characters, + * especially in SDL parsing. So we have set this to false by default. + * + * @return true if ignored chars should be captured as AST nodes + */ + public boolean isCaptureIgnoredChars() { + return captureIgnoredChars; + } + + + /** + * Memory savings can be made if we do NOT set {@link graphql.language.SourceLocation}s + * on AST nodes, especially in SDL parsing. + * + * @return true if {@link graphql.language.SourceLocation}s should be captured as AST nodes + * + * @see graphql.language.SourceLocation + */ + public boolean isCaptureSourceLocation() { + return captureSourceLocation; + } + + /** + * Single-line {@link graphql.language.Comment}s do not have any semantic meaning in + * GraphQL source documents, as such you may wish to ignore them. + *

+ * This option does not ignore documentation {@link graphql.language.Description}s. + * + * @return true if {@link graphql.language.Comment}s should be captured as AST nodes + * + * @see graphql.language.SourceLocation + */ + public boolean isCaptureLineComments() { + return captureLineComments; + } + + /** + * Controls whether the underlying {@link MultiSourceReader} should track previously read data or not. + * + * @return true if {@link MultiSourceReader} should track data in memory. + */ + public boolean isReaderTrackData() { + return readerTrackData; + } + + /** + * A graphql hacking vector is to send nonsensical queries that contain a repeated characters that burn lots of parsing CPU time and burn + * memory representing a document that won't ever execute. To prevent this for most users, graphql-java + * sets this value to 1MB. + * + * @return the maximum number of characters the parser will accept, after which an exception will be thrown. + */ + public int getMaxCharacters() { + return maxCharacters; + } + + + /** + * A graphql hacking vector is to send nonsensical queries that burn lots of parsing CPU time and burns + * memory representing a document that won't ever execute. To prevent this you can set a maximum number of parse + * tokens that will be accepted before an exception is thrown and the parsing is stopped. + * + * @return the maximum number of raw tokens the parser will accept, after which an exception will be thrown. + */ + public int getMaxTokens() { + return maxTokens; + } + + /** + * A graphql hacking vector is to send larges amounts of whitespace that burn lots of parsing CPU time and burn + * memory representing a document. To prevent this you can set a maximum number of whitespace parse + * tokens that will be accepted before an exception is thrown and the parsing is stopped. + * + * @return the maximum number of raw whitespace tokens the parser will accept, after which an exception will be thrown. + */ + public int getMaxWhitespaceTokens() { + return maxWhitespaceTokens; + } + + /** + * A graphql hacking vector is to send nonsensical queries that have lots of rule depth to them which + * can cause stack overflow exceptions during the query parsing. To prevent this you can set a value + * that is the maximum depth allowed before an exception is thrown and the parsing is stopped. + * + * @return the maximum token depth the parser will accept, after which an exception will be thrown. + */ + public int getMaxRuleDepth() { + return maxRuleDepth; + } + + /** + * Option to redact offending tokens in parser error messages. + * By default, the parser will include the offending token in the error message, if possible. + * + * @return true if the token parser messages should be redacted + */ + public boolean isRedactTokenParserErrorMessages() { + return redactTokenParserErrorMessages; + } + + public ParsingListener getParsingListener() { + return parsingListener; + } + + public ParserOptions transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newParserOptions() { + return new Builder(); + } + + public static class Builder { + + private boolean captureIgnoredChars = false; + private boolean captureSourceLocation = true; + private boolean captureLineComments = true; + private boolean readerTrackData = true; + private ParsingListener parsingListener = ParsingListener.NOOP; + private int maxCharacters = MAX_QUERY_CHARACTERS; + private int maxTokens = MAX_QUERY_TOKENS; + private int maxWhitespaceTokens = MAX_WHITESPACE_TOKENS; + private int maxRuleDepth = MAX_RULE_DEPTH; + private boolean redactTokenParserErrorMessages = false; + + Builder() { + } + + Builder(ParserOptions parserOptions) { + this.captureIgnoredChars = parserOptions.captureIgnoredChars; + this.captureSourceLocation = parserOptions.captureSourceLocation; + this.captureLineComments = parserOptions.captureLineComments; + this.maxCharacters = parserOptions.maxCharacters; + this.maxTokens = parserOptions.maxTokens; + this.maxWhitespaceTokens = parserOptions.maxWhitespaceTokens; + this.maxRuleDepth = parserOptions.maxRuleDepth; + this.redactTokenParserErrorMessages = parserOptions.redactTokenParserErrorMessages; + this.parsingListener = parserOptions.parsingListener; + } + + public Builder captureIgnoredChars(boolean captureIgnoredChars) { + this.captureIgnoredChars = captureIgnoredChars; + return this; + } + + public Builder captureSourceLocation(boolean captureSourceLocation) { + this.captureSourceLocation = captureSourceLocation; + return this; + } + + public Builder captureLineComments(boolean captureLineComments) { + this.captureLineComments = captureLineComments; + return this; + } + + public Builder readerTrackData(boolean readerTrackData) { + this.readerTrackData = readerTrackData; + return this; + } + + public Builder maxCharacters(int maxCharacters) { + this.maxCharacters = maxCharacters; + return this; + } + + public Builder maxTokens(int maxTokens) { + this.maxTokens = maxTokens; + return this; + } + + public Builder maxWhitespaceTokens(int maxWhitespaceTokens) { + this.maxWhitespaceTokens = maxWhitespaceTokens; + return this; + } + + public Builder maxRuleDepth(int maxRuleDepth) { + this.maxRuleDepth = maxRuleDepth; + return this; + } + + public Builder redactTokenParserErrorMessages(boolean redactTokenParserErrorMessages) { + this.redactTokenParserErrorMessages = redactTokenParserErrorMessages; + return this; + } + + public Builder parsingListener(ParsingListener parsingListener) { + this.parsingListener = assertNotNull(parsingListener); + return this; + } + + public ParserOptions build() { + return new ParserOptions(this); + } + + } + +} diff --git a/src/main/java/graphql/parser/ParsingListener.java b/src/main/java/graphql/parser/ParsingListener.java new file mode 100644 index 0000000000..b6344f0df1 --- /dev/null +++ b/src/main/java/graphql/parser/ParsingListener.java @@ -0,0 +1,44 @@ +package graphql.parser; + +import graphql.PublicSpi; + +/** + * This listener interface is invoked for each token parsed by the graphql parser code. + */ +@PublicSpi +public interface ParsingListener { + + /** + * A NoOp implementation of {@link ParsingListener} + */ + ParsingListener NOOP = t -> { + }; + + + /** + * This represents a token that has been parsed + */ + interface Token { + /** + * @return the text of the parsed token + */ + String getText(); + + /** + * @return the line the token occurred on + */ + int getLine(); + + /** + * @return the position within the line the token occurred on + */ + int getCharPositionInLine(); + } + + /** + * This is called for each token found during parsing + * + * @param token the token found + */ + void onToken(Token token); +} diff --git a/src/main/java/graphql/parser/SafeTokenReader.java b/src/main/java/graphql/parser/SafeTokenReader.java new file mode 100644 index 0000000000..8c655d9426 --- /dev/null +++ b/src/main/java/graphql/parser/SafeTokenReader.java @@ -0,0 +1,95 @@ +package graphql.parser; + +import graphql.Internal; +import org.jspecify.annotations.NonNull; + +import java.io.IOException; +import java.io.Reader; +import java.nio.CharBuffer; +import java.util.function.Consumer; + +/** + * This reader will only emit a maximum number of characters from it. This is used to protect us from evil input. + *

+ * If a graphql system does not have some max HTTP input limit, then this will help protect the system. This is a limit + * of last resort. Ideally the http input should be limited, but if its not, we have this. + */ +@Internal +public class SafeTokenReader extends Reader { + + private final Reader delegate; + private final int maxCharacters; + private final Consumer whenMaxCharactersExceeded; + private int count; + + public SafeTokenReader(Reader delegate, int maxCharacters, Consumer whenMaxCharactersExceeded) { + this.delegate = delegate; + this.maxCharacters = maxCharacters; + this.whenMaxCharactersExceeded = whenMaxCharactersExceeded; + count = 0; + } + + private int checkHowMany(int read, int howMany) { + if (read != -1) { + count += howMany; + if (count > maxCharacters) { + whenMaxCharactersExceeded.accept(maxCharacters); + } + } + return read; + } + + @Override + public int read(char @NonNull [] buff, int off, int len) throws IOException { + int howMany = delegate.read(buff, off, len); + return checkHowMany(howMany, howMany); + } + + @Override + public int read() throws IOException { + int ch = delegate.read(); + return checkHowMany(ch, 1); + } + + @Override + public int read(@NonNull CharBuffer target) throws IOException { + int howMany = delegate.read(target); + return checkHowMany(howMany, howMany); + } + + @Override + public int read(char @NonNull [] buff) throws IOException { + int howMany = delegate.read(buff); + return checkHowMany(howMany, howMany); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + + @Override + public long skip(long n) throws IOException { + return delegate.skip(n); + } + + @Override + public boolean ready() throws IOException { + return delegate.ready(); + } + + @Override + public boolean markSupported() { + return delegate.markSupported(); + } + + @Override + public void mark(int readAheadLimit) throws IOException { + delegate.mark(readAheadLimit); + } + + @Override + public void reset() throws IOException { + delegate.reset(); + } +} diff --git a/src/main/java/graphql/parser/SafeTokenSource.java b/src/main/java/graphql/parser/SafeTokenSource.java new file mode 100644 index 0000000000..c92c76d916 --- /dev/null +++ b/src/main/java/graphql/parser/SafeTokenSource.java @@ -0,0 +1,94 @@ +package graphql.parser; + +import graphql.Internal; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenFactory; +import org.antlr.v4.runtime.TokenSource; + +import java.util.function.BiConsumer; + +/** + * This token source can wrap a lexer and if it asks for more than a maximum number of tokens + * the user can take some action, typically throw an exception to stop lexing. + * + * It tracks the maximum number per token channel, so we have 3 at the moment, and they will all be tracked. + * + * This is used to protect us from evil input. The lexer will eagerly try to find all tokens + * at times and certain inputs (directives butted together for example) will cause the lexer + * to keep doing work even though before the tokens are presented back to the parser + * and hence before it has a chance to stop work once too much as been done. + */ +@Internal +public class SafeTokenSource implements TokenSource { + + private final TokenSource lexer; + private final int maxTokens; + private final int maxWhitespaceTokens; + private final BiConsumer whenMaxTokensExceeded; + private final int channelCounts[]; + + public SafeTokenSource(TokenSource lexer, int maxTokens, int maxWhitespaceTokens, BiConsumer whenMaxTokensExceeded) { + this.lexer = lexer; + this.maxTokens = maxTokens; + this.maxWhitespaceTokens = maxWhitespaceTokens; + this.whenMaxTokensExceeded = whenMaxTokensExceeded; + // this could be a Map however we want it to be faster as possible. + // we only have 3 channels - but they are 0,2 and 3 so use 5 for safety - still faster than a map get/put + // if we ever add another channel beyond 5 it will IOBEx during tests so future changes will be handled before release! + this.channelCounts = new int[]{0, 0, 0, 0, 0}; + } + + + @Override + public Token nextToken() { + Token token = lexer.nextToken(); + if (token != null) { + int channel = token.getChannel(); + int currentCount = ++channelCounts[channel]; + if (channel == Parser.CHANNEL_WHITESPACE) { + // whitespace gets its own max count + callbackIfMaxExceeded(maxWhitespaceTokens, currentCount, token); + } else { + callbackIfMaxExceeded(maxTokens, currentCount, token); + } + } + return token; + } + + private void callbackIfMaxExceeded(int maxCount, int currentCount, Token token) { + if (currentCount > maxCount) { + whenMaxTokensExceeded.accept(maxCount, token); + } + } + + @Override + public int getLine() { + return lexer.getLine(); + } + + @Override + public int getCharPositionInLine() { + return lexer.getCharPositionInLine(); + } + + @Override + public CharStream getInputStream() { + return lexer.getInputStream(); + } + + @Override + public String getSourceName() { + return lexer.getSourceName(); + } + + @Override + public void setTokenFactory(TokenFactory factory) { + lexer.setTokenFactory(factory); + } + + @Override + public TokenFactory getTokenFactory() { + return lexer.getTokenFactory(); + } +} diff --git a/src/main/java/graphql/parser/StringValueParsing.java b/src/main/java/graphql/parser/StringValueParsing.java index 4156cf813c..56b1f1ec88 100644 --- a/src/main/java/graphql/parser/StringValueParsing.java +++ b/src/main/java/graphql/parser/StringValueParsing.java @@ -2,6 +2,8 @@ import graphql.Assert; import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.SourceLocation; import java.io.StringWriter; import java.util.ArrayList; @@ -28,30 +30,36 @@ public static String parseTripleQuotedString(String strText) { */ public static String removeIndentation(String rawValue) { String[] lines = rawValue.split("\\n"); - int minIndent = Integer.MAX_VALUE; + Integer commonIndent = null; for (int i = 0; i < lines.length; i++) { - if (i == 0) continue; + if (i == 0) { + continue; + } String line = lines[i]; int length = line.length(); int indent = leadingWhitespace(line); - if (indent < length && indent < minIndent) { - minIndent = indent; + if (indent < length) { + if (commonIndent == null || indent < commonIndent) { + commonIndent = indent; + } } } List lineList = new ArrayList<>(Arrays.asList(lines)); - if (minIndent != Integer.MAX_VALUE) { + if (commonIndent != null) { for (int i = 0; i < lineList.size(); i++) { String line = lineList.get(i); - if (i == 0) continue; - if (line.length() > minIndent) { - line = line.substring(minIndent); + if (i == 0) { + continue; + } + if (line.length() > commonIndent) { + line = line.substring(commonIndent); lineList.set(i, line); } } } while (!lineList.isEmpty()) { String line = lineList.get(0); - if (line.isEmpty()) { + if (containsOnlyWhiteSpace(line)) { lineList.remove(0); } else { break; @@ -60,7 +68,7 @@ public static String removeIndentation(String rawValue) { while (!lineList.isEmpty()) { int endIndex = lineList.size() - 1; String line = lineList.get(endIndex); - if (line.isEmpty()) { + if (containsOnlyWhiteSpace(line)) { lineList.remove(endIndex); } else { break; @@ -79,10 +87,10 @@ public static String removeIndentation(String rawValue) { return formatted.toString(); } - private static int leadingWhitespace(String line) { + private static int leadingWhitespace(String str) { int count = 0; - for (int i = 1; i < line.length(); i++) { - char ch = line.charAt(i); + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); if (ch != ' ' && ch != '\t') { break; } @@ -91,7 +99,12 @@ private static int leadingWhitespace(String line) { return count; } - public static String parseSingleQuotedString(String string) { + private static boolean containsOnlyWhiteSpace(String str) { + // according to graphql spec and graphql-js - this is the definition + return leadingWhitespace(str) == str.length(); + } + + public static String parseSingleQuotedString(I18n i18n, String string, SourceLocation sourceLocation) { StringWriter writer = new StringWriter(string.length() - 2); int end = string.length() - 1; for (int i = 1; i < end; i++) { @@ -128,10 +141,7 @@ public static String parseSingleQuotedString(String string) { writer.write('\t'); continue; case 'u': - String hexStr = string.substring(i + 1, i + 5); - int codepoint = Integer.parseInt(hexStr, 16); - i += 4; - writer.write(codepoint); + i = UnicodeUtil.parseAndWriteUnicode(i18n, writer, string, i, sourceLocation); continue; default: Assert.assertShouldNeverHappen(); diff --git a/src/main/java/graphql/parser/UnicodeUtil.java b/src/main/java/graphql/parser/UnicodeUtil.java new file mode 100644 index 0000000000..d8fbff6308 --- /dev/null +++ b/src/main/java/graphql/parser/UnicodeUtil.java @@ -0,0 +1,123 @@ +package graphql.parser; + +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.SourceLocation; +import graphql.parser.exceptions.InvalidUnicodeSyntaxException; + +import java.io.IOException; +import java.io.StringWriter; + +import static graphql.Assert.assertShouldNeverHappen; + +/** + * Contains Unicode helpers for parsing StringValue types in the grammar + */ +@Internal +public class UnicodeUtil { + public static final int MAX_UNICODE_CODE_POINT = 0x10FFFF; + public static final int LEADING_SURROGATE_LOWER_BOUND = 0xD800; + public static final int LEADING_SURROGATE_UPPER_BOUND = 0xDBFF; + public static final int TRAILING_SURROGATE_LOWER_BOUND = 0xDC00; + public static final int TRAILING_SURROGATE_UPPER_BOUND = 0xDFFF; + + public static int parseAndWriteUnicode(I18n i18n, StringWriter writer, String string, int i, SourceLocation sourceLocation) { + // Unicode code points can either be: + // 1. Unbraced: four hex characters in the form \\u597D, or + // 2. Braced: any number of hex characters surrounded by braces in the form \\u{1F37A} + + // Extract the code point hex digits. Index i points to 'u' + int startIndex = isBracedEscape(string, i) ? i + 2 : i + 1; + int endIndexExclusive = getEndIndexExclusive(i18n, string, i, sourceLocation); + // Index for parser to continue at, the last character of the escaped unicode character. Either } or hex digit + int continueIndex = isBracedEscape(string, i) ? endIndexExclusive : endIndexExclusive - 1; + + int codePoint; + try { + codePoint = Integer.parseInt(string, startIndex, endIndexExclusive, 16); + } catch (NumberFormatException e) { + throw new InvalidUnicodeSyntaxException(i18n, "InvalidUnicode.invalidHexString", sourceLocation, offendingToken(string, i, continueIndex)); + } + + if (isTrailingSurrogateValue(codePoint)) { + throw new InvalidUnicodeSyntaxException(i18n, "InvalidUnicode.trailingLeadingSurrogate", sourceLocation, offendingToken(string, i, continueIndex)); + } else if (isLeadingSurrogateValue(codePoint)) { + if (!isEscapedUnicode(string, continueIndex + 1)) { + throw new InvalidUnicodeSyntaxException(i18n, "InvalidUnicode.leadingTrailingSurrogate", sourceLocation, offendingToken(string, i, continueIndex)); + } + + // Shift parser ahead to 'u' in second escaped Unicode character + i = continueIndex + 2; + int trailingStartIndex = isBracedEscape(string, i) ? i + 2 : i + 1; + int trailingEndIndexExclusive = getEndIndexExclusive(i18n, string, i, sourceLocation); + int trailingCodePoint = Integer.parseInt(string, trailingStartIndex, trailingEndIndexExclusive, 16); + continueIndex = isBracedEscape(string, i) ? trailingEndIndexExclusive : trailingEndIndexExclusive - 1; + + if (isTrailingSurrogateValue(trailingCodePoint)) { + writeCodePoint(writer, codePoint); + writeCodePoint(writer, trailingCodePoint); + return continueIndex; + } + + throw new InvalidUnicodeSyntaxException(i18n, "InvalidUnicode.leadingTrailingSurrogate", sourceLocation, offendingToken(string, i, continueIndex)); + } else if (isValidUnicodeCodePoint(codePoint)) { + writeCodePoint(writer, codePoint); + return continueIndex; + } + + throw new InvalidUnicodeSyntaxException(i18n, "InvalidUnicode.invalidCodePoint", sourceLocation, offendingToken(string, i, continueIndex)); + } + + private static String offendingToken(String string, int i, int continueIndex) { + return string.substring(i - 1, continueIndex + 1); + } + + private static int getEndIndexExclusive(I18n i18n, String string, int i, SourceLocation sourceLocation) { + // Unbraced case, with exactly 4 hex digits + if (string.length() > i + 5 && !isBracedEscape(string, i)) { + return i + 5; + } + + // Braced case, with any number of hex digits + int endIndexExclusive = i + 2; + do { + if (endIndexExclusive + 1 >= string.length()) { + throw new InvalidUnicodeSyntaxException(i18n, "InvalidUnicode.incorrectEscape", sourceLocation, string.substring(i - 1, endIndexExclusive)); + } + } while (string.charAt(++endIndexExclusive) != '}'); + + return endIndexExclusive; + } + + private static boolean isValidUnicodeCodePoint(int value) { + return value <= MAX_UNICODE_CODE_POINT; + } + + private static boolean isEscapedUnicode(String string, int index) { + if (index + 1 >= string.length()) { + return false; + } + return string.charAt(index) == '\\' && string.charAt(index + 1) == 'u'; + } + + private static boolean isLeadingSurrogateValue(int value) { + return LEADING_SURROGATE_LOWER_BOUND <= value && value <= LEADING_SURROGATE_UPPER_BOUND; + } + + private static boolean isTrailingSurrogateValue(int value) { + return TRAILING_SURROGATE_LOWER_BOUND <= value && value <= TRAILING_SURROGATE_UPPER_BOUND; + } + + private static void writeCodePoint(StringWriter writer, int codepoint) { + char[] chars = Character.toChars(codepoint); + try { + writer.write(chars); + } catch (IOException e) { + assertShouldNeverHappen(); + } + } + + private static boolean isBracedEscape(String string, int i) { + return string.charAt(i + 1) == '{'; + } +} diff --git a/src/main/java/graphql/parser/exceptions/InvalidUnicodeSyntaxException.java b/src/main/java/graphql/parser/exceptions/InvalidUnicodeSyntaxException.java new file mode 100644 index 0000000000..46b7ad37b3 --- /dev/null +++ b/src/main/java/graphql/parser/exceptions/InvalidUnicodeSyntaxException.java @@ -0,0 +1,16 @@ +package graphql.parser.exceptions; + +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.SourceLocation; +import graphql.parser.InvalidSyntaxException; +import org.jspecify.annotations.NonNull; + +@Internal +public class InvalidUnicodeSyntaxException extends InvalidSyntaxException { + + public InvalidUnicodeSyntaxException(@NonNull I18n i18N, @NonNull String msgKey, @NonNull SourceLocation sourceLocation, @NonNull String offendingToken) { + super(i18N.msg(msgKey, offendingToken, sourceLocation.getLine(), sourceLocation.getColumn()), + sourceLocation, offendingToken, null, null); + } +} diff --git a/src/main/java/graphql/parser/exceptions/MoreTokensSyntaxException.java b/src/main/java/graphql/parser/exceptions/MoreTokensSyntaxException.java new file mode 100644 index 0000000000..2956f3f95a --- /dev/null +++ b/src/main/java/graphql/parser/exceptions/MoreTokensSyntaxException.java @@ -0,0 +1,24 @@ +package graphql.parser.exceptions; + +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.SourceLocation; +import graphql.parser.InvalidSyntaxException; +import org.jspecify.annotations.NonNull; + +@Internal +public class MoreTokensSyntaxException extends InvalidSyntaxException { + + @Internal + public MoreTokensSyntaxException(@NonNull I18n i18N, @NonNull SourceLocation sourceLocation, @NonNull String offendingToken, @NonNull String sourcePreview) { + super(i18N.msg("InvalidSyntaxMoreTokens.full", offendingToken, sourceLocation.getLine(), sourceLocation.getColumn()), + sourceLocation, offendingToken, sourcePreview, null); + } + + @Internal + public MoreTokensSyntaxException(@NonNull I18n i18N, @NonNull SourceLocation sourceLocation) { + super(i18N.msg("InvalidSyntaxMoreTokens.noMessage", sourceLocation.getLine(), sourceLocation.getColumn()), + sourceLocation, null, null, null); + } + +} diff --git a/src/main/java/graphql/parser/exceptions/ParseCancelledException.java b/src/main/java/graphql/parser/exceptions/ParseCancelledException.java new file mode 100644 index 0000000000..4fe9541522 --- /dev/null +++ b/src/main/java/graphql/parser/exceptions/ParseCancelledException.java @@ -0,0 +1,18 @@ +package graphql.parser.exceptions; + +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.SourceLocation; +import graphql.parser.InvalidSyntaxException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +@Internal +public class ParseCancelledException extends InvalidSyntaxException { + + @Internal + public ParseCancelledException(@NonNull I18n i18N, @Nullable SourceLocation sourceLocation, @Nullable String offendingToken, int maxTokens, @NonNull String tokenType) { + super(i18N.msg("ParseCancelled.full", maxTokens, tokenType), + sourceLocation, offendingToken, null, null); + } +} diff --git a/src/main/java/graphql/parser/exceptions/ParseCancelledTooDeepException.java b/src/main/java/graphql/parser/exceptions/ParseCancelledTooDeepException.java new file mode 100644 index 0000000000..fe8717bedf --- /dev/null +++ b/src/main/java/graphql/parser/exceptions/ParseCancelledTooDeepException.java @@ -0,0 +1,18 @@ +package graphql.parser.exceptions; + +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.language.SourceLocation; +import graphql.parser.InvalidSyntaxException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +@Internal +public class ParseCancelledTooDeepException extends InvalidSyntaxException { + + @Internal + public ParseCancelledTooDeepException(@NonNull I18n i18N, @Nullable SourceLocation sourceLocation, @Nullable String offendingToken, int maxTokens, @NonNull String tokenType) { + super(i18N.msg("ParseCancelled.tooDeep", maxTokens, tokenType), + sourceLocation, offendingToken, null, null); + } +} diff --git a/src/main/java/graphql/parser/exceptions/ParseCancelledTooManyCharsException.java b/src/main/java/graphql/parser/exceptions/ParseCancelledTooManyCharsException.java new file mode 100644 index 0000000000..b861c78cfe --- /dev/null +++ b/src/main/java/graphql/parser/exceptions/ParseCancelledTooManyCharsException.java @@ -0,0 +1,16 @@ +package graphql.parser.exceptions; + +import graphql.Internal; +import graphql.i18n.I18n; +import graphql.parser.InvalidSyntaxException; +import org.jspecify.annotations.NonNull; + +@Internal +public class ParseCancelledTooManyCharsException extends InvalidSyntaxException { + + @Internal + public ParseCancelledTooManyCharsException(@NonNull I18n i18N, int maxCharacters) { + super(i18N.msg("ParseCancelled.tooManyChars", maxCharacters), + null, null, null, null); + } +} diff --git a/src/main/java/graphql/relay/Connection.java b/src/main/java/graphql/relay/Connection.java index ee8e165c9c..aec2158f70 100644 --- a/src/main/java/graphql/relay/Connection.java +++ b/src/main/java/graphql/relay/Connection.java @@ -19,7 +19,7 @@ public interface Connection { List> getEdges(); /** - * @return {@link graphql.relay.PageInfo} pagination data about about that list of edges + * @return {@link graphql.relay.PageInfo} pagination data about that list of edges */ PageInfo getPageInfo(); diff --git a/src/main/java/graphql/relay/DefaultConnection.java b/src/main/java/graphql/relay/DefaultConnection.java index 3986b76d30..9373de104f 100644 --- a/src/main/java/graphql/relay/DefaultConnection.java +++ b/src/main/java/graphql/relay/DefaultConnection.java @@ -1,12 +1,13 @@ package graphql.relay; +import com.google.common.collect.ImmutableList; import graphql.PublicApi; import java.util.Collections; import java.util.List; +import java.util.Objects; import static graphql.Assert.assertNotNull; -import static java.util.Collections.unmodifiableList; /** * A default implementation of {@link graphql.relay.Connection} @@ -14,7 +15,7 @@ @PublicApi public class DefaultConnection implements Connection { - private final List> edges; + private final ImmutableList> edges; private final PageInfo pageInfo; /** @@ -26,7 +27,7 @@ public class DefaultConnection implements Connection { * @throws IllegalArgumentException if edges or page info is null. use {@link Collections#emptyList()} for empty edges. */ public DefaultConnection(List> edges, PageInfo pageInfo) { - this.edges = unmodifiableList(assertNotNull(edges, "edges cannot be null")); + this.edges = ImmutableList.copyOf(assertNotNull(edges, "edges cannot be null")); this.pageInfo = assertNotNull(pageInfo, "page info cannot be null"); } @@ -40,6 +41,23 @@ public PageInfo getPageInfo() { return pageInfo; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DefaultConnection that = (DefaultConnection) o; + return Objects.equals(edges, that.edges) && Objects.equals(pageInfo, that.pageInfo); + } + + @Override + public int hashCode() { + return Objects.hash(edges, pageInfo); + } + @Override public String toString() { return "DefaultConnection{" + diff --git a/src/main/java/graphql/relay/DefaultConnectionCursor.java b/src/main/java/graphql/relay/DefaultConnectionCursor.java index 03f8375862..aaa695a956 100644 --- a/src/main/java/graphql/relay/DefaultConnectionCursor.java +++ b/src/main/java/graphql/relay/DefaultConnectionCursor.java @@ -3,6 +3,8 @@ import graphql.Assert; import graphql.PublicApi; +import java.util.Objects; + @PublicApi public class DefaultConnectionCursor implements ConnectionCursor { @@ -27,12 +29,12 @@ public boolean equals(Object o) { return false; } DefaultConnectionCursor that = (DefaultConnectionCursor) o; - return value != null ? value.equals(that.value) : that.value == null; + return Objects.equals(value, that.value); } @Override public int hashCode() { - return value != null ? value.hashCode() : 0; + return Objects.hashCode(value); } @Override diff --git a/src/main/java/graphql/relay/DefaultEdge.java b/src/main/java/graphql/relay/DefaultEdge.java index 0ea216f795..31b29ad414 100644 --- a/src/main/java/graphql/relay/DefaultEdge.java +++ b/src/main/java/graphql/relay/DefaultEdge.java @@ -2,6 +2,8 @@ import graphql.PublicApi; +import java.util.Objects; + import static graphql.Assert.assertNotNull; @PublicApi @@ -26,6 +28,23 @@ public ConnectionCursor getCursor() { return cursor; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DefaultEdge that = (DefaultEdge) o; + return Objects.equals(node, that.node) && Objects.equals(cursor, that.cursor); + } + + @Override + public int hashCode() { + return Objects.hash(node, cursor); + } + @Override public String toString() { return "DefaultEdge{" + diff --git a/src/main/java/graphql/relay/DefaultPageInfo.java b/src/main/java/graphql/relay/DefaultPageInfo.java index 6e20d073c2..d76ef04fb1 100644 --- a/src/main/java/graphql/relay/DefaultPageInfo.java +++ b/src/main/java/graphql/relay/DefaultPageInfo.java @@ -3,6 +3,8 @@ import graphql.PublicApi; +import java.util.Objects; + @PublicApi public class DefaultPageInfo implements PageInfo { @@ -39,6 +41,26 @@ public boolean isHasNextPage() { return hasNextPage; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DefaultPageInfo that = (DefaultPageInfo) o; + return Objects.equals(startCursor, that.startCursor) && + Objects.equals(endCursor, that.endCursor) && + Objects.equals(hasPreviousPage, that.hasPreviousPage) && + Objects.equals(hasNextPage, that.hasNextPage); + } + + @Override + public int hashCode() { + return Objects.hash(startCursor, endCursor, hasPreviousPage, hasNextPage); + } + @Override public String toString() { return "DefaultPageInfo{" + diff --git a/src/main/java/graphql/relay/InvalidCursorException.java b/src/main/java/graphql/relay/InvalidCursorException.java index 4839a71939..1268b779c5 100644 --- a/src/main/java/graphql/relay/InvalidCursorException.java +++ b/src/main/java/graphql/relay/InvalidCursorException.java @@ -3,12 +3,14 @@ import graphql.ErrorType; import graphql.GraphQLError; import graphql.GraphqlErrorHelper; +import graphql.Internal; import graphql.language.SourceLocation; import java.util.List; import static graphql.ErrorType.DataFetchingException; +@Internal public class InvalidCursorException extends RuntimeException implements GraphQLError { InvalidCursorException(String message) { diff --git a/src/main/java/graphql/relay/InvalidPageSizeException.java b/src/main/java/graphql/relay/InvalidPageSizeException.java index df349741f5..a11954ed28 100644 --- a/src/main/java/graphql/relay/InvalidPageSizeException.java +++ b/src/main/java/graphql/relay/InvalidPageSizeException.java @@ -3,12 +3,14 @@ import graphql.ErrorType; import graphql.GraphQLError; import graphql.GraphqlErrorHelper; +import graphql.Internal; import graphql.language.SourceLocation; import java.util.List; import static graphql.ErrorType.DataFetchingException; +@Internal public class InvalidPageSizeException extends RuntimeException implements GraphQLError { InvalidPageSizeException(String message) { diff --git a/src/main/java/graphql/relay/Relay.java b/src/main/java/graphql/relay/Relay.java index d98285f724..b2ffe26fb9 100644 --- a/src/main/java/graphql/relay/Relay.java +++ b/src/main/java/graphql/relay/Relay.java @@ -27,6 +27,7 @@ import static graphql.schema.GraphQLList.list; import static graphql.schema.GraphQLNonNull.nonNull; import static graphql.schema.GraphQLObjectType.newObject; +import static graphql.schema.GraphQLTypeReference.typeRef; /** * This can be used to compose graphql runtime types that implement @@ -39,7 +40,7 @@ public class Relay { public static final String NODE = "Node"; - private final GraphQLObjectType pageInfoType = newObject() + public static final GraphQLObjectType pageInfoType = newObject() .name("PageInfo") .description("Information about pagination in a connection.") .field(newFieldDefinition() @@ -167,7 +168,7 @@ public GraphQLObjectType connectionType(String name, GraphQLObjectType edgeType, .field(newFieldDefinition() .name("pageInfo") .description("details about this specific page") - .type(nonNull(pageInfoType))) + .type(nonNull(typeRef("PageInfo")))) .fields(connectionFields) .build(); } diff --git a/src/main/java/graphql/relay/SimpleListConnection.java b/src/main/java/graphql/relay/SimpleListConnection.java index f45a31f755..0c30337d0b 100644 --- a/src/main/java/graphql/relay/SimpleListConnection.java +++ b/src/main/java/graphql/relay/SimpleListConnection.java @@ -1,6 +1,8 @@ package graphql.relay; import graphql.PublicApi; +import graphql.TrivialDataFetcher; +import graphql.collect.ImmutableKit; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; @@ -16,7 +18,7 @@ import static java.util.Base64.getEncoder; @PublicApi -public class SimpleListConnection implements DataFetcher> { +public class SimpleListConnection implements DataFetcher>, TrivialDataFetcher> { static final String DUMMY_CURSOR_PREFIX = "simple-cursor"; private final String prefix; @@ -33,7 +35,10 @@ public SimpleListConnection(List data) { } private List> buildEdges() { - List> edges = new ArrayList<>(); + if (data.isEmpty()) { + return Collections.emptyList(); + } + List> edges = new ArrayList<>(data.size()); int ix = 0; for (T object : data) { edges.add(new DefaultEdge<>(object, new DefaultConnectionCursor(createCursor(ix++)))); @@ -46,6 +51,10 @@ public Connection get(DataFetchingEnvironment environment) { List> edges = buildEdges(); + if (edges.isEmpty()) { + return emptyConnection(); + } + ConnectionCursor firstPresliceCursor = edges.get(0).getCursor(); ConnectionCursor lastPresliceCursor = edges.get(edges.size() - 1).getCursor(); @@ -54,10 +63,12 @@ public Connection get(DataFetchingEnvironment environment) { int beforeOffset = getOffsetFromCursor(environment.getArgument("before"), edges.size()); int end = Math.min(beforeOffset, edges.size()); - if (begin > end) begin = end; + if (begin > end) { + begin = end; + } edges = edges.subList(begin, end); - if (edges.size() == 0) { + if (edges.isEmpty()) { return emptyConnection(); } @@ -99,7 +110,7 @@ public Connection get(DataFetchingEnvironment environment) { private Connection emptyConnection() { PageInfo pageInfo = new DefaultPageInfo(null, null, false, false); - return new DefaultConnection<>(Collections.emptyList(), pageInfo); + return new DefaultConnection<>(ImmutableKit.emptyList(), pageInfo); } /** diff --git a/src/main/java/graphql/scalar/CoercingUtil.java b/src/main/java/graphql/scalar/CoercingUtil.java new file mode 100644 index 0000000000..c3ac535522 --- /dev/null +++ b/src/main/java/graphql/scalar/CoercingUtil.java @@ -0,0 +1,25 @@ +package graphql.scalar; + +import graphql.Internal; +import graphql.i18n.I18n; + +import java.util.Locale; + +@Internal +public class CoercingUtil { + public static boolean isNumberIsh(Object input) { + return input instanceof Number || input instanceof String; + } + + public static String typeName(Object input) { + if (input == null) { + return "null"; + } + + return input.getClass().getSimpleName(); + } + + public static String i18nMsg(Locale locale, String msgKey, Object... args) { + return I18n.i18n(I18n.BundleType.Scalars, locale).msg(msgKey, args); + } +} diff --git a/src/main/java/graphql/scalar/GraphqlBooleanCoercing.java b/src/main/java/graphql/scalar/GraphqlBooleanCoercing.java new file mode 100644 index 0000000000..cea304a65b --- /dev/null +++ b/src/main/java/graphql/scalar/GraphqlBooleanCoercing.java @@ -0,0 +1,139 @@ +package graphql.scalar; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.language.BooleanValue; +import graphql.language.Value; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.math.BigDecimal; +import java.util.Locale; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.scalar.CoercingUtil.i18nMsg; +import static graphql.scalar.CoercingUtil.isNumberIsh; +import static graphql.scalar.CoercingUtil.typeName; + +/** + * The deprecated methods still have implementations in case code outside graphql-java is calling them + * but internally the call paths have been replaced. + */ +@Internal +public class GraphqlBooleanCoercing implements Coercing { + + private Boolean convertImpl(Object input) { + if (input instanceof Boolean) { + return (Boolean) input; + } else if (input instanceof String) { + String lStr = ((String) input).toLowerCase(); + if (lStr.equals("true")) { + return true; + } + if (lStr.equals("false")) { + return false; + } + return null; + } else if (isNumberIsh(input)) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + // this should never happen because String is handled above + return assertShouldNeverHappen(); + } + return value.compareTo(BigDecimal.ZERO) != 0; + } else { + return null; + } + + } + + @NonNull + private Boolean serializeImpl(@NonNull Object input, @NonNull Locale locale) { + Boolean result = convertImpl(input); + if (result == null) { + throw new CoercingSerializeException( + i18nMsg(locale, "Boolean.notBoolean", typeName(input)) + ); + } + return result; + } + + @NonNull + private Boolean parseValueImpl(@NonNull Object input, @NonNull Locale locale) { + if (!(input instanceof Boolean)) { + throw new CoercingParseValueException( + i18nMsg(locale, "Boolean.unexpectedRawValueType", typeName(input)) + ); + } + return (Boolean) input; + } + + private static boolean parseLiteralImpl(@NonNull Object input, @NonNull Locale locale) { + if (!(input instanceof BooleanValue)) { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Boolean.unexpectedAstType", typeName(input)) + ); + } + return ((BooleanValue) input).isValue(); + } + + @NonNull + private BooleanValue valueToLiteralImpl(@NonNull Object input, @NonNull Locale locale) { + Boolean result = convertImpl(input); + if (result == null) { + assertShouldNeverHappen(i18nMsg(locale, "Boolean.notBoolean", typeName(input))); + } + return BooleanValue.newBooleanValue(result).build(); + } + + @Override + @Deprecated + public Boolean serialize(@NonNull Object dataFetcherResult) { + return serializeImpl(dataFetcherResult, Locale.getDefault()); + } + + @Override + public @Nullable Boolean serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + return serializeImpl(dataFetcherResult, locale); + } + + @Override + @Deprecated + public Boolean parseValue(@NonNull Object input) { + return parseValueImpl(input, Locale.getDefault()); + } + + @Override + public Boolean parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + return parseValueImpl(input, locale); + } + + @Override + @Deprecated + public Boolean parseLiteral(@NonNull Object input) { + return parseLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @Nullable Boolean parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + return parseLiteralImpl(input, locale); + } + + @Override + @Deprecated + public @NonNull Value valueToLiteral(@NonNull Object input) { + return valueToLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @NonNull Value valueToLiteral(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) { + return valueToLiteralImpl(input, locale); + } +} diff --git a/src/main/java/graphql/scalar/GraphqlFloatCoercing.java b/src/main/java/graphql/scalar/GraphqlFloatCoercing.java new file mode 100644 index 0000000000..d1863ed450 --- /dev/null +++ b/src/main/java/graphql/scalar/GraphqlFloatCoercing.java @@ -0,0 +1,149 @@ +package graphql.scalar; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.language.FloatValue; +import graphql.language.IntValue; +import graphql.language.Value; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.math.BigDecimal; +import java.util.Locale; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.scalar.CoercingUtil.i18nMsg; +import static graphql.scalar.CoercingUtil.isNumberIsh; +import static graphql.scalar.CoercingUtil.typeName; + +/** + * The deprecated methods still have implementations in case code outside graphql-java is calling them + * but internally the call paths have been replaced. + */ +@Internal +public class GraphqlFloatCoercing implements Coercing { + + private Double convertImpl(Object input) { + // From the GraphQL Float spec, non-finite floating-point internal values (NaN and Infinity) + // must raise a field error on both result and input coercion + Double doubleInput; + if (input instanceof Double) { + doubleInput = (Double) input; + } else if (isNumberIsh(input)) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + return null; + } + doubleInput = value.doubleValue(); + } else { + return null; + } + + if (Double.isNaN(doubleInput) || Double.isInfinite(doubleInput)) { + return null; + } + return doubleInput; + } + + @NonNull + private Double serialiseImpl(Object input, @NonNull Locale locale) { + Double result = convertImpl(input); + if (result == null) { + throw new CoercingSerializeException( + i18nMsg(locale, "Float.notFloat", typeName(input)) + ); + } + return result; + } + + @NonNull + private Double parseValueImpl(@NonNull Object input, @NonNull Locale locale) { + if (!(input instanceof Number)) { + throw new CoercingParseValueException( + i18nMsg(locale, "Float.unexpectedRawValueType", typeName(input)) + ); + } + + Double result = convertImpl(input); + if (result == null) { + throw new CoercingParseValueException( + i18nMsg(locale, "Float.notFloat", typeName(input)) + ); + } + + return result; + } + + private static double parseLiteralImpl(@NonNull Object input, @NonNull Locale locale) { + if (input instanceof IntValue) { + return ((IntValue) input).getValue().doubleValue(); + } else if (input instanceof FloatValue) { + return ((FloatValue) input).getValue().doubleValue(); + } else { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Float.unexpectedAstType", typeName(input)) + ); + } + } + + @NonNull + private FloatValue valueToLiteralImpl(Object input, @NonNull Locale locale) { + Double result = convertImpl(input); + if (result == null) { + assertShouldNeverHappen(i18nMsg(locale, "Float.notFloat", typeName(input))); + } + return FloatValue.newFloatValue(BigDecimal.valueOf(result)).build(); + } + + @Override + @Deprecated + public Double serialize(@NonNull Object dataFetcherResult) { + return serialiseImpl(dataFetcherResult, Locale.getDefault()); + } + + @Override + public @Nullable Double serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + return serialiseImpl(dataFetcherResult, locale); + } + + @Override + @Deprecated + public @NonNull Double parseValue(@NonNull Object input) { + return parseValueImpl(input, Locale.getDefault()); + } + + @Override + public Double parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + return parseValueImpl(input, locale); + } + + @Override + @Deprecated + public Double parseLiteral(@NonNull Object input) { + return parseLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @Nullable Double parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + return parseLiteralImpl(input, locale); + } + + @Override + @Deprecated + public Value valueToLiteral(@NonNull Object input) { + return valueToLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @NonNull Value valueToLiteral(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) { + return valueToLiteralImpl(input, locale); + } +} + diff --git a/src/main/java/graphql/scalar/GraphqlIDCoercing.java b/src/main/java/graphql/scalar/GraphqlIDCoercing.java new file mode 100644 index 0000000000..7c8c6336cf --- /dev/null +++ b/src/main/java/graphql/scalar/GraphqlIDCoercing.java @@ -0,0 +1,137 @@ +package graphql.scalar; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.language.IntValue; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.math.BigInteger; +import java.util.Locale; +import java.util.UUID; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.scalar.CoercingUtil.i18nMsg; +import static graphql.scalar.CoercingUtil.typeName; + +/** + * The deprecated methods still have implementations in case code outside graphql-java is calling them + * but internally the call paths have been replaced. + */ +@Internal +public class GraphqlIDCoercing implements Coercing { + + private String convertImpl(Object input) { + if (input instanceof String) { + return (String) input; + } + if (input instanceof Integer) { + return String.valueOf(input); + } + if (input instanceof Long) { + return String.valueOf(input); + } + if (input instanceof UUID) { + return String.valueOf(input); + } + if (input instanceof BigInteger) { + return String.valueOf(input); + } + return String.valueOf(input); + + } + + @NonNull + private String serializeImpl(Object input, @NonNull Locale locale) { + String result = String.valueOf(input); + if (result == null) { + throw new CoercingSerializeException( + "Expected type 'ID' but was '" + typeName(input) + "'." + ); + } + return result; + } + + @NonNull + private String parseValueImpl(Object input, @NonNull Locale locale) { + String result = convertImpl(input); + if (result == null) { + throw new CoercingParseValueException( + i18nMsg(locale, "ID.notId", typeName(input)) + ); + } + return result; + } + + private String parseLiteralImpl(Object input, @NonNull Locale locale) { + if (input instanceof StringValue) { + return ((StringValue) input).getValue(); + } + if (input instanceof IntValue) { + return ((IntValue) input).getValue().toString(); + } + throw new CoercingParseLiteralException( + i18nMsg(locale, "ID.unexpectedAstType", typeName(input)) + ); + } + + @NonNull + private StringValue valueToLiteralImpl(Object input, @NonNull Locale locale) { + String result = convertImpl(input); + if (result == null) { + assertShouldNeverHappen(i18nMsg(locale, "ID.notId", typeName(input))); + } + return StringValue.newStringValue(result).build(); + } + + @Override + @Deprecated + public String serialize(@NonNull Object dataFetcherResult) { + return serializeImpl(dataFetcherResult, Locale.getDefault()); + } + + @Override + public @Nullable Object serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + return serializeImpl(dataFetcherResult, locale); + } + + @Override + @Deprecated + public String parseValue(@NonNull Object input) { + return parseValueImpl(input, Locale.getDefault()); + } + + @Override + public Object parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + return parseValueImpl(input, locale); + } + + @Override + @Deprecated + public String parseLiteral(@NonNull Object input) { + return parseLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @Nullable Object parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + return parseLiteralImpl(input, locale); + } + + @Override + @Deprecated + public Value valueToLiteral(@NonNull Object input) { + return valueToLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @NonNull Value valueToLiteral(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) { + return valueToLiteralImpl(input, locale); + } +} diff --git a/src/main/java/graphql/scalar/GraphqlIntCoercing.java b/src/main/java/graphql/scalar/GraphqlIntCoercing.java new file mode 100644 index 0000000000..bac8822f13 --- /dev/null +++ b/src/main/java/graphql/scalar/GraphqlIntCoercing.java @@ -0,0 +1,174 @@ +package graphql.scalar; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.language.IntValue; +import graphql.language.Value; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Locale; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.scalar.CoercingUtil.i18nMsg; +import static graphql.scalar.CoercingUtil.isNumberIsh; +import static graphql.scalar.CoercingUtil.typeName; + +/** + * The deprecated methods still have implementations in case code outside graphql-java is calling them + * but internally the call paths have been replaced. + */ +@Internal +public class GraphqlIntCoercing implements Coercing { + + private static final BigInteger INT_MAX = BigInteger.valueOf(Integer.MAX_VALUE); + private static final BigInteger INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE); + + private Integer convertImpl(Object input) { + if (input instanceof Integer) { + return (Integer) input; + } else if (isNumberIsh(input)) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + return null; + } + try { + return value.intValueExact(); + } catch (ArithmeticException e) { + return null; + } + } else { + return null; + } + } + + @NonNull + private Integer serialiseImpl(Object input, @NonNull Locale locale) { + Integer result = convertImpl(input); + if (result == null) { + throw new CoercingSerializeException( + i18nMsg(locale, "Int.notInt", typeName(input)) + ); + } + return result; + } + + @NonNull + private Integer parseValueImpl(@NonNull Object input, @NonNull Locale locale) { + if (!(input instanceof Number)) { + throw new CoercingParseValueException( + i18nMsg(locale, "Int.notInt", typeName(input)) + ); + } + + if (input instanceof Integer) { + return (Integer) input; + } + + BigInteger result = convertParseValueImpl(input); + if (result == null) { + throw new CoercingParseValueException( + i18nMsg(locale, "Int.notInt", typeName(input)) + ); + } + if (result.compareTo(INT_MIN) < 0 || result.compareTo(INT_MAX) > 0) { + throw new CoercingParseValueException( + i18nMsg(locale, "Int.outsideRange", result.toString()) + ); + } + return result.intValueExact(); + } + + private BigInteger convertParseValueImpl(Object input) { + BigDecimal value; + try { + value = new BigDecimal(input.toString()); + } catch (NumberFormatException e) { + return null; + } + + try { + return value.toBigIntegerExact(); + } catch (ArithmeticException e) { + // Exception if number has non-zero fractional part + return null; + } + } + + private static int parseLiteralImpl(Object input, @NonNull Locale locale) { + if (!(input instanceof IntValue)) { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Scalar.unexpectedAstType", "IntValue", typeName(input)) + ); + } + BigInteger value = ((IntValue) input).getValue(); + if (value.compareTo(INT_MIN) < 0 || value.compareTo(INT_MAX) > 0) { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Int.outsideRange", value.toString()) + ); + } + return value.intValue(); + } + + private IntValue valueToLiteralImpl(Object input, @NonNull Locale locale) { + Integer result = convertImpl(input); + if (result == null) { + assertShouldNeverHappen(i18nMsg(locale, "Int.notInt", typeName(input))); + } + return IntValue.newIntValue(BigInteger.valueOf(result)).build(); + } + + + @Override + @Deprecated + public Integer serialize(@NonNull Object dataFetcherResult) { + return serialiseImpl(dataFetcherResult, Locale.getDefault()); + } + + @Override + public @Nullable Integer serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + return serialiseImpl(dataFetcherResult, locale); + } + + @Override + @Deprecated + public Integer parseValue(@NonNull Object input) { + return parseValueImpl(input, Locale.getDefault()); + } + + @Override + public Integer parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + return parseValueImpl(input, locale); + } + + @Override + @Deprecated + public Integer parseLiteral(@NonNull Object input) { + return parseLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @Nullable Integer parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + return parseLiteralImpl(input, locale); + } + + @Override + @Deprecated + public @NonNull Value valueToLiteral(@NonNull Object input) { + return valueToLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @NonNull Value valueToLiteral(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) { + return valueToLiteralImpl(input, locale); + } +} diff --git a/src/main/java/graphql/scalar/GraphqlStringCoercing.java b/src/main/java/graphql/scalar/GraphqlStringCoercing.java new file mode 100644 index 0000000000..64ab93a911 --- /dev/null +++ b/src/main/java/graphql/scalar/GraphqlStringCoercing.java @@ -0,0 +1,96 @@ +package graphql.scalar; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Locale; + +import static graphql.scalar.CoercingUtil.i18nMsg; +import static graphql.scalar.CoercingUtil.typeName; + +/** + * The deprecated methods still have implementations in case code outside graphql-java is calling them + * but internally the call paths have been replaced. + */ +@Internal +public class GraphqlStringCoercing implements Coercing { + + private String toStringImpl(Object input) { + return String.valueOf(input); + } + + private String parseValueImpl(@NonNull Object input, @NonNull Locale locale) { + if (!(input instanceof String)) { + throw new CoercingParseValueException( + i18nMsg(locale, "String.unexpectedRawValueType", typeName(input)) + ); + } + return (String) input; + } + + private String parseLiteralImpl(@NonNull Object input, Locale locale) { + if (!(input instanceof StringValue)) { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Scalar.unexpectedAstType", "StringValue", typeName(input)) + ); + } + return ((StringValue) input).getValue(); + } + + private StringValue valueToLiteralImpl(@NonNull Object input) { + return StringValue.newStringValue(input.toString()).build(); + } + + @Override + @Deprecated + public String serialize(@NonNull Object dataFetcherResult) { + return toStringImpl(dataFetcherResult); + } + + @Override + public @Nullable String serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + return toStringImpl(dataFetcherResult); + } + + @Override + @Deprecated + public String parseValue(@NonNull Object input) { + return parseValueImpl(input, Locale.getDefault()); + } + + @Override + public String parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + return parseValueImpl(input, locale); + } + + @Override + @Deprecated + public String parseLiteral(@NonNull Object input) { + return parseLiteralImpl(input, Locale.getDefault()); + } + + @Override + public @Nullable String parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + return parseLiteralImpl(input, locale); + } + + @Override + @Deprecated + public @NonNull Value valueToLiteral(@NonNull Object input) { + return valueToLiteralImpl(input); + } + + @Override + public @NonNull Value valueToLiteral(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) { + return valueToLiteralImpl(input); + } +} diff --git a/src/main/java/graphql/schema/AsyncDataFetcher.java b/src/main/java/graphql/schema/AsyncDataFetcher.java index 162f9c2ad6..a003bc4c7e 100644 --- a/src/main/java/graphql/schema/AsyncDataFetcher.java +++ b/src/main/java/graphql/schema/AsyncDataFetcher.java @@ -21,7 +21,7 @@ public class AsyncDataFetcher implements DataFetcher> { * {@code .dataFetcher(async(fooDataFetcher))} *

* By default this will run in the {@link ForkJoinPool#commonPool()}. You can set - * your own {@link Executor} with {@link #async(DataFetcher)} (DataFetcher, Executor)} + * your own {@link Executor} with {@link #async(DataFetcher, Executor)} * * @param wrappedDataFetcher the data fetcher to run asynchronously * @param the type of data @@ -53,6 +53,15 @@ public static AsyncDataFetcher async(DataFetcher wrappedDataFetcher, E private final DataFetcher wrappedDataFetcher; private final Executor executor; + + public DataFetcher getWrappedDataFetcher() { + return wrappedDataFetcher; + } + + public Executor getExecutor() { + return executor; + } + public AsyncDataFetcher(DataFetcher wrappedDataFetcher) { this(wrappedDataFetcher, ForkJoinPool.commonPool()); } @@ -64,7 +73,17 @@ public AsyncDataFetcher(DataFetcher wrappedDataFetcher, Executor executor) { @Override public CompletableFuture get(DataFetchingEnvironment environment) { - return CompletableFuture.supplyAsync(() -> wrappedDataFetcher.get(environment), executor); + return CompletableFuture.supplyAsync(() -> { + try { + return wrappedDataFetcher.get(environment); + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException(e); + } + } + }, executor); } } diff --git a/src/main/java/graphql/schema/CodeRegistryVisitor.java b/src/main/java/graphql/schema/CodeRegistryVisitor.java new file mode 100644 index 0000000000..166ed6239c --- /dev/null +++ b/src/main/java/graphql/schema/CodeRegistryVisitor.java @@ -0,0 +1,57 @@ +package graphql.schema; + +import graphql.Internal; +import graphql.introspection.Introspection; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import static graphql.Assert.assertTrue; +import static graphql.schema.FieldCoordinates.coordinates; +import static graphql.util.TraversalControl.CONTINUE; + +/** + * This ensure that all fields have data fetchers and that unions and interfaces have type resolvers + */ +@Internal +public class CodeRegistryVisitor extends GraphQLTypeVisitorStub { + private final GraphQLCodeRegistry.Builder codeRegistry; + + public CodeRegistryVisitor(GraphQLCodeRegistry.Builder codeRegistry) { + this.codeRegistry = codeRegistry; + Introspection.addCodeForIntrospectionTypes(codeRegistry); + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + GraphQLFieldsContainer parentContainerType = (GraphQLFieldsContainer) context.getParentContext().thisNode(); + DataFetcher dataFetcher = node.getDataFetcher(); + if (dataFetcher != null) { + FieldCoordinates coordinates = coordinates(parentContainerType, node); + codeRegistry.dataFetcherIfAbsent(coordinates, dataFetcher); + } + + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + TypeResolver typeResolver = node.getTypeResolver(); + if (typeResolver != null) { + codeRegistry.typeResolverIfAbsent(node, typeResolver); + } + assertTrue(codeRegistry.getTypeResolver(node) != null, + "You MUST provide a type resolver for the interface type '%s'", node.getName()); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + TypeResolver typeResolver = node.getTypeResolver(); + if (typeResolver != null) { + codeRegistry.typeResolverIfAbsent(node, typeResolver); + } + assertTrue(codeRegistry.getTypeResolver(node) != null, + "You MUST provide a type resolver for the union type '%s'", node.getName()); + return CONTINUE; + } +} diff --git a/src/main/java/graphql/schema/Coercing.java b/src/main/java/graphql/schema/Coercing.java index f03e5f972a..3f580776aa 100644 --- a/src/main/java/graphql/schema/Coercing.java +++ b/src/main/java/graphql/schema/Coercing.java @@ -1,10 +1,20 @@ package graphql.schema; +import graphql.GraphQLContext; import graphql.PublicSpi; +import graphql.execution.CoercedVariables; +import graphql.language.Value; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Locale; +import java.util.Map; + +import static graphql.Assert.assertNotNull; /** - * The Coercing interface is used by {@link graphql.schema.GraphQLScalarType}s to parse and serialise object values. + * The Coercing interface is used by {@link graphql.schema.GraphQLScalarType}s to parse and serialize object values. *

* There are two major responsibilities, result coercion and input coercion. *

@@ -12,55 +22,221 @@ * For example imagine a DateTime scalar, the result coercion would need to take an object and turn it into a * ISO date or throw an exception if it cant. *

- * Input coercion is taking a value that came in from requests variables or hard coded query literals and coercing them into a - * Java object value that is acceptable to the scalar type. Again using the DateTime example, the input coercion would try to - * parse an ISO date time object or throw an exception if it cant. - * - * See http://facebook.github.io/graphql/#sec-Scalars + * Input coercion is made out of three different methods {@link #parseLiteral(Object)} which converts an literal Ast + * into an internal input value, {@link #parseValue(Object)} which converts an external input value into an internal one + * and {@link #valueToLiteral(Object)} which is a translation between an external input value into a literal. + *
+ * The relationship between these three methods is as follows: + * It is required that every valid external input values for {@link #parseValue(Object)} is also valid for + * {@link #valueToLiteral(Object)} + * and vice versa. + * Furthermore the literals returned by {@link #valueToLiteral(Object)} are required to be valid for + * {@link #parseLiteral(Object)}. */ @PublicSpi public interface Coercing { /** + * This is deprecated and you should implement {@link #serialize(Object, GraphQLContext, Locale)} instead + *

* Called to convert a Java object result of a DataFetcher to a valid runtime value for the scalar type. - * + *

+ * Note : Throw {@link graphql.schema.CoercingSerializeException} if there is fundamental + * problem during serialization, don't return null to indicate failure. + *

* Note : You should not allow {@link java.lang.RuntimeException}s to come out of your serialize method, but rather * catch them and fire them as {@link graphql.schema.CoercingSerializeException} instead as per the method contract. * * @param dataFetcherResult is never null * - * @return a serialized value which is never null + * @return a serialized value which may be null. * * @throws graphql.schema.CoercingSerializeException if value input can't be serialized */ - O serialize(Object dataFetcherResult) throws CoercingSerializeException; + @Deprecated(since = "2022-08-22") + default @Nullable O serialize(@NonNull Object dataFetcherResult) throws CoercingSerializeException { + throw new UnsupportedOperationException("The non deprecated version of serialize has not been implemented by this scalar : " + this.getClass()); + } /** - * Called to resolve a input from a query variable into a Java object acceptable for the scalar type. + * Called to convert a Java object result of a DataFetcher to a valid runtime value for the scalar type. + *

+ * Note : Throw {@link graphql.schema.CoercingSerializeException} if there is fundamental + * problem during serialization, don't return null to indicate failure. + *

+ * Note : You should not allow {@link java.lang.RuntimeException}s to come out of your serialize method, but rather + * catch them and fire them as {@link graphql.schema.CoercingSerializeException} instead as per the method contract. + * + * @param dataFetcherResult is never null + * @param graphQLContext the graphql context in place + * @param locale the locale to use * + * @return a serialized value which may be null. + * + * @throws graphql.schema.CoercingSerializeException if value input can't be serialized + */ + default @Nullable O serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + assertNotNull(dataFetcherResult); + assertNotNull(graphQLContext); + return serialize(dataFetcherResult); + } + + /** + * This is deprecated and you should implement {@link #parseValue(Object, GraphQLContext, Locale)} instead + *

+ * Called to resolve an input from a query variable into a Java object acceptable for the scalar type. + *

* Note : You should not allow {@link java.lang.RuntimeException}s to come out of your parseValue method, but rather - * catch them and fire them as {@link graphql.schema.CoercingSerializeException} instead as per the method contract. + * catch them and fire them as {@link graphql.schema.CoercingParseValueException} instead as per the method contract. + *

+ * Note : if input is explicit/raw value null, input coercion will return null before this method is called * * @param input is never null * - * @return a parsed value which is never null + * @return a parsed value which may be null * * @throws graphql.schema.CoercingParseValueException if value input can't be parsed */ - I parseValue(Object input) throws CoercingParseValueException; + @Deprecated(since = "2022-08-22") + default @Nullable I parseValue(@NonNull Object input) throws CoercingParseValueException { + throw new UnsupportedOperationException("The non deprecated version of parseValue has not been implemented by this scalar : " + this.getClass()); + } /** - * Called to convert an query input AST node into a Java object acceptable for the scalar type. The input - * object will be an instance of {@link graphql.language.Value}. + * Called to resolve an input from a query variable into a Java object acceptable for the scalar type. + *

+ * Note : You should not allow {@link java.lang.RuntimeException}s to come out of your parseValue method, but rather + * catch them and fire them as {@link graphql.schema.CoercingParseValueException} instead as per the method contract. + * + * Note : if input is explicit/raw value null, input coercion will return null before this method is called + * + * @param input is never null + * @param graphQLContext the graphql context in place + * @param locale the locale to use + * + * @return a parsed value which may be null * + * @throws graphql.schema.CoercingParseValueException if value input can't be parsed + */ + @Nullable + default I parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + assertNotNull(input); + assertNotNull(graphQLContext); + assertNotNull(locale); + return parseValue(input); + } + + /** + * This is deprecated and you should implement {@link #parseLiteral(Value, CoercedVariables, GraphQLContext, Locale)} instead + *

+ * Called during query validation to convert a query input AST node into a Java object acceptable for the scalar type. The input + * object will be an instance of {@link graphql.language.Value}. + *

* Note : You should not allow {@link java.lang.RuntimeException}s to come out of your parseLiteral method, but rather * catch them and fire them as {@link graphql.schema.CoercingParseLiteralException} instead as per the method contract. + *

+ * Note : if input is literal {@link graphql.language.NullValue}, input coercion will return null before this method is called * * @param input is never null * - * @return a parsed value which is never null + * @return a parsed value which may be null * * @throws graphql.schema.CoercingParseLiteralException if input literal can't be parsed */ - I parseLiteral(Object input) throws CoercingParseLiteralException; + @Deprecated(since = "2022-08-22") + default @Nullable I parseLiteral(@NonNull Object input) throws CoercingParseLiteralException { + throw new UnsupportedOperationException("The non deprecated version of parseLiteral has not been implemented by this scalar : " + this.getClass()); + } + + /** + * This is deprecated and you should implement {@link #parseLiteral(Value, CoercedVariables, GraphQLContext, Locale)} instead + *

+ * Called during query execution to convert a query input AST node into a Java object acceptable for the scalar type. The input + * object will be an instance of {@link graphql.language.Value}. + *

+ * Note : You should not allow {@link java.lang.RuntimeException}s to come out of your parseLiteral method, but rather + * catch them and fire them as {@link graphql.schema.CoercingParseLiteralException} instead as per the method contract. + *

+ * Many scalar types don't need to implement this method because they don't take AST {@link graphql.language.VariableReference} + * objects and convert them into actual values. But for those scalar types that want to do this, then this + * method should be implemented. + * + * Note : if input is literal {@link graphql.language.NullValue}, input coercion will return null before this method is called + * + * @param input is never null + * @param variables the resolved variables passed to the query + * + * @return a parsed value which may be null + * + * @throws graphql.schema.CoercingParseLiteralException if input literal can't be parsed + */ + @SuppressWarnings("unused") + @Deprecated(since = "2022-08-22") + default @Nullable I parseLiteral(Object input, Map variables) throws CoercingParseLiteralException { + return parseLiteral(input); + } + + /** + * Called during query execution to convert a query input AST node into a Java object acceptable for the scalar type. The input + * object will be an instance of {@link graphql.language.Value}. + *

+ * Note : You should not allow {@link java.lang.RuntimeException}s to come out of your parseLiteral method, but rather + * catch them and fire them as {@link graphql.schema.CoercingParseLiteralException} instead as per the method contract. + *

+ * Many scalar types don't need to implement this method because they don't take AST {@link graphql.language.VariableReference} + * objects and convert them into actual values. But for those scalar types that want to do this, then this + * method should be implemented. + * + * Note : if input is literal {@link graphql.language.NullValue}, input coercion will return null before this method is called + * + * @param input is never null + * @param variables the resolved variables passed to the query + * @param graphQLContext the graphql context in place + * @param locale the locale to use + * + * @return a parsed value which may be null + * + * @throws graphql.schema.CoercingParseLiteralException if input literal can't be parsed + */ + default @Nullable I parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + assertNotNull(input); + assertNotNull(graphQLContext); + assertNotNull(locale); + return parseLiteral(input, variables.toMap()); + } + + + /** + * This is deprecated and you should implement {@link #valueToLiteral(Object, GraphQLContext, Locale)} instead + *

+ * Converts an external input value to a literal (Ast Value). + *

+ * IMPORTANT: the argument is validated before by calling {@link #parseValue(Object)}. + * + * @param input an external input value + * + * @return The literal matching the external input value. + */ + @Deprecated(since = "2022-08-22") + default @NonNull Value valueToLiteral(@NonNull Object input) { + throw new UnsupportedOperationException("The non deprecated version of valueToLiteral has not been implemented by this scalar : " + this.getClass()); + } + + /** + * Converts an external input value to a literal (Ast Value). + *

+ * IMPORTANT: the argument is validated before by calling {@link #parseValue(Object)}. + * + * @param input an external input value + * @param graphQLContext the graphql context in place + * @param locale the locale to use + * + * @return The literal matching the external input value. + */ + default @NonNull Value valueToLiteral(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) { + assertNotNull(input); + assertNotNull(graphQLContext); + assertNotNull(locale); + return valueToLiteral(input); + } } diff --git a/src/main/java/graphql/schema/CoercingParseLiteralException.java b/src/main/java/graphql/schema/CoercingParseLiteralException.java index 1df766780e..73f562a62a 100644 --- a/src/main/java/graphql/schema/CoercingParseLiteralException.java +++ b/src/main/java/graphql/schema/CoercingParseLiteralException.java @@ -1,45 +1,49 @@ package graphql.schema; -import java.util.Collections; -import java.util.List; - import graphql.ErrorType; -import graphql.GraphQLError; -import graphql.GraphQLException; +import graphql.GraphqlErrorException; import graphql.PublicApi; import graphql.language.SourceLocation; @PublicApi -public class CoercingParseLiteralException extends GraphQLException implements GraphQLError { - private List sourceLocations; +public class CoercingParseLiteralException extends GraphqlErrorException { public CoercingParseLiteralException() { + this(newCoercingParseLiteralException()); } public CoercingParseLiteralException(String message) { - super(message); + this(newCoercingParseLiteralException().message(message)); } public CoercingParseLiteralException(String message, Throwable cause) { - super(message, cause); + this(newCoercingParseLiteralException().message(message).cause(cause)); } public CoercingParseLiteralException(String message, Throwable cause, SourceLocation sourceLocation) { - super(message, cause); - this.sourceLocations = Collections.singletonList(sourceLocation); + this(newCoercingParseLiteralException().message(message).cause(cause).sourceLocation(sourceLocation)); } public CoercingParseLiteralException(Throwable cause) { - super(cause); + this(newCoercingParseLiteralException().cause(cause)); } - @Override - public List getLocations() { - return sourceLocations; + private CoercingParseLiteralException(Builder builder) { + super(builder); } @Override public ErrorType getErrorType() { return ErrorType.ValidationError; } + + public static Builder newCoercingParseLiteralException() { + return new Builder(); + } + + public static class Builder extends BuilderBase { + public CoercingParseLiteralException build() { + return new CoercingParseLiteralException(this); + } + } } diff --git a/src/main/java/graphql/schema/CoercingParseValueException.java b/src/main/java/graphql/schema/CoercingParseValueException.java index 0234fd70fe..3bc93518d3 100644 --- a/src/main/java/graphql/schema/CoercingParseValueException.java +++ b/src/main/java/graphql/schema/CoercingParseValueException.java @@ -1,45 +1,49 @@ package graphql.schema; -import java.util.Collections; -import java.util.List; - import graphql.ErrorType; -import graphql.GraphQLError; -import graphql.GraphQLException; +import graphql.GraphqlErrorException; import graphql.PublicApi; import graphql.language.SourceLocation; @PublicApi -public class CoercingParseValueException extends GraphQLException implements GraphQLError { - private List sourceLocations; +public class CoercingParseValueException extends GraphqlErrorException { public CoercingParseValueException() { + this(newCoercingParseValueException()); } public CoercingParseValueException(String message) { - super(message); + this(newCoercingParseValueException().message(message)); } public CoercingParseValueException(String message, Throwable cause) { - super(message, cause); + this(newCoercingParseValueException().message(message).cause(cause)); } - public CoercingParseValueException(String message, Throwable cause, SourceLocation sourceLocation) { - super(message, cause); - this.sourceLocations = Collections.singletonList(sourceLocation); + public CoercingParseValueException(Throwable cause) { + this(newCoercingParseValueException().cause(cause)); } - public CoercingParseValueException(Throwable cause) { - super(cause); + public CoercingParseValueException(String message, Throwable cause, SourceLocation sourceLocation) { + this(newCoercingParseValueException().message(message).cause(cause).sourceLocation(sourceLocation)); } - @Override - public List getLocations() { - return sourceLocations; + private CoercingParseValueException(Builder builder) { + super(builder); } @Override public ErrorType getErrorType() { return ErrorType.ValidationError; } + + public static Builder newCoercingParseValueException() { + return new Builder(); + } + + public static class Builder extends BuilderBase { + public CoercingParseValueException build() { + return new CoercingParseValueException(this); + } + } } diff --git a/src/main/java/graphql/schema/CoercingSerializeException.java b/src/main/java/graphql/schema/CoercingSerializeException.java index 8656f55474..8de575af17 100644 --- a/src/main/java/graphql/schema/CoercingSerializeException.java +++ b/src/main/java/graphql/schema/CoercingSerializeException.java @@ -1,23 +1,45 @@ package graphql.schema; -import graphql.GraphQLException; +import graphql.ErrorClassification; +import graphql.ErrorType; +import graphql.GraphqlErrorException; import graphql.PublicApi; @PublicApi -public class CoercingSerializeException extends GraphQLException { +public class CoercingSerializeException extends GraphqlErrorException { public CoercingSerializeException() { + this(newCoercingSerializeException()); } public CoercingSerializeException(String message) { - super(message); + this(newCoercingSerializeException().message(message)); } public CoercingSerializeException(String message, Throwable cause) { - super(message, cause); + this(newCoercingSerializeException().message(message).cause(cause)); } public CoercingSerializeException(Throwable cause) { - super(cause); + this(newCoercingSerializeException().cause(cause)); + } + + private CoercingSerializeException(Builder builder) { + super(builder); + } + + @Override + public ErrorClassification getErrorType() { + return ErrorType.DataFetchingException; + } + + public static Builder newCoercingSerializeException() { + return new Builder(); + } + + public static class Builder extends BuilderBase { + public CoercingSerializeException build() { + return new CoercingSerializeException(this); + } } } diff --git a/src/main/java/graphql/schema/DataFetcher.java b/src/main/java/graphql/schema/DataFetcher.java index 5eac8467ab..ab5aad5009 100644 --- a/src/main/java/graphql/schema/DataFetcher.java +++ b/src/main/java/graphql/schema/DataFetcher.java @@ -11,18 +11,24 @@ * In other implementations, these are sometimes called "Resolvers" or "Field Resolvers", because that is there function, * they resolve a logical graphql field into an actual data value. * - * @param the type of object returned + * @param the type of object returned. May also be wrapped in a {@link graphql.execution.DataFetcherResult} */ @PublicSpi public interface DataFetcher { /** * This is called by the graphql engine to fetch the value. The {@link graphql.schema.DataFetchingEnvironment} is a composite - * context object that tells you all you need to know about who to fetch a data value in graphql type terms. + * context object that tells you all you need to know about how to fetch a data value in graphql type terms. * * @param environment this is the data fetching environment which contains all the context you need to fetch a value * - * @return a value of type T + * @return a value of type T. May be wrapped in a {@link graphql.execution.DataFetcherResult} + * + * @throws Exception to relieve the implementations from having to wrap checked exceptions. Any exception thrown + * from a {@code DataFetcher} will eventually be handled by the registered {@link graphql.execution.DataFetcherExceptionHandler} + * and the related field will have a value of {@code null} in the result. */ - T get(DataFetchingEnvironment environment); + T get(DataFetchingEnvironment environment) throws Exception; + + } diff --git a/src/main/java/graphql/schema/DataFetcherFactories.java b/src/main/java/graphql/schema/DataFetcherFactories.java index e9f6a88bb5..2345535d56 100644 --- a/src/main/java/graphql/schema/DataFetcherFactories.java +++ b/src/main/java/graphql/schema/DataFetcherFactories.java @@ -20,7 +20,18 @@ public class DataFetcherFactories { * @return a data fetcher factory that always returns the provided data fetcher */ public static DataFetcherFactory useDataFetcher(DataFetcher dataFetcher) { - return fieldDefinition -> dataFetcher; + //noinspection deprecation + return new DataFetcherFactory<>() { + @Override + public DataFetcher get(DataFetcherFactoryEnvironment environment) { + return dataFetcher; + } + + @Override + public DataFetcher get(GraphQLFieldDefinition fieldDefinition) { + return dataFetcher; + } + }; } /** @@ -32,7 +43,7 @@ public static DataFetcherFactory useDataFetcher(DataFetcher dataFetche * * @return a new data fetcher that wraps the provided data fetcher */ - public static DataFetcher wrapDataFetcher(DataFetcher delegateDataFetcher, BiFunction mapFunction) { + public static DataFetcher wrapDataFetcher(DataFetcher delegateDataFetcher, BiFunction mapFunction) { return environment -> { Object value = delegateDataFetcher.get(environment); if (value instanceof CompletionStage) { diff --git a/src/main/java/graphql/schema/DataFetcherFactory.java b/src/main/java/graphql/schema/DataFetcherFactory.java index ece0dcb6ea..9e7eafa872 100644 --- a/src/main/java/graphql/schema/DataFetcherFactory.java +++ b/src/main/java/graphql/schema/DataFetcherFactory.java @@ -19,7 +19,23 @@ public interface DataFetcherFactory { * @param environment the environment that needs the data fetcher * * @return a data fetcher + * + * @deprecated This method will go away at some point and {@link DataFetcherFactory#get(GraphQLFieldDefinition)} will be used */ + @Deprecated(since = "2024-11-26") DataFetcher get(DataFetcherFactoryEnvironment environment); + /** + * Returns a {@link graphql.schema.DataFetcher} given the field definition + * which is cheaper in object allocation terms. + * + * @param fieldDefinition the field that needs the data fetcher + * + * @return a data fetcher + */ + + default DataFetcher get(GraphQLFieldDefinition fieldDefinition) { + return null; + } + } diff --git a/src/main/java/graphql/schema/DataFetcherFactoryEnvironment.java b/src/main/java/graphql/schema/DataFetcherFactoryEnvironment.java index 991756d96b..7ff5aefb9a 100644 --- a/src/main/java/graphql/schema/DataFetcherFactoryEnvironment.java +++ b/src/main/java/graphql/schema/DataFetcherFactoryEnvironment.java @@ -5,8 +5,12 @@ /** * This is passed to a {@link graphql.schema.DataFetcherFactory} when it is invoked to * get a {@link graphql.schema.DataFetcher} + * + * @deprecated This class will go away at some point in the future since its pointless wrapper + * of a {@link GraphQLFieldDefinition} */ @PublicApi +@Deprecated(since = "2024-11-26") public class DataFetcherFactoryEnvironment { private final GraphQLFieldDefinition fieldDefinition; @@ -25,7 +29,7 @@ public static Builder newDataFetchingFactoryEnvironment() { return new Builder(); } - static class Builder { + public static class Builder { GraphQLFieldDefinition fieldDefinition; public Builder fieldDefinition(GraphQLFieldDefinition fieldDefinition) { diff --git a/src/main/java/graphql/schema/DataFetchingEnvironment.java b/src/main/java/graphql/schema/DataFetchingEnvironment.java index 7ef1de9a03..b08356f3e4 100644 --- a/src/main/java/graphql/schema/DataFetchingEnvironment.java +++ b/src/main/java/graphql/schema/DataFetchingEnvironment.java @@ -1,13 +1,24 @@ package graphql.schema; +import graphql.GraphQLContext; +import graphql.Internal; import graphql.PublicApi; -import graphql.execution.ExecutionContext; import graphql.execution.ExecutionId; -import graphql.execution.ExecutionTypeInfo; +import graphql.execution.ExecutionStepInfo; +import graphql.execution.MergedField; +import graphql.execution.directives.QueryDirectives; +import graphql.introspection.IntrospectionDataFetchingEnvironment; +import graphql.language.Document; import graphql.language.Field; import graphql.language.FragmentDefinition; +import graphql.language.OperationDefinition; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.List; +import java.util.Locale; import java.util.Map; @@ -17,7 +28,8 @@ */ @SuppressWarnings("TypeParameterUnusedInFormals") @PublicApi -public interface DataFetchingEnvironment { +@NullMarked +public interface DataFetchingEnvironment extends IntrospectionDataFetchingEnvironment { /** * This is the value of the current object to be queried. @@ -29,6 +41,7 @@ public interface DataFetchingEnvironment { * * @return can be null for the root query, otherwise it is never null */ + @Nullable T getSource(); /** @@ -51,22 +64,66 @@ public interface DataFetchingEnvironment { * @param name the name of the argument * @param you decide what type it is * - * @return the named argument or null if its not [present + * @return the named argument or null if it's not present */ + @Nullable T getArgument(String name); /** - * Returns a context argument that is set up when the {@link graphql.GraphQL#execute} method + * Returns the named argument or the default value + * + * @param name the name of the argument + * @param defaultValue the default value if the argument is not present + * @param you decide what type it is + * + * @return the named argument or the default if it's not present + */ + T getArgumentOrDefault(String name, T defaultValue); + + /** + * Returns a legacy context argument that is set up when the {@link graphql.GraphQL#execute(graphql.ExecutionInput)} method * is invoked. *

- * This is a info object which is provided to all DataFetcher, but never used by graphql-java itself. + * This is an info object which is provided to all DataFetchers, but never used by graphql-java itself. * * @param you decide what type it is * * @return can be null + * + * @deprecated - use {@link #getGraphQlContext()} instead */ + @Deprecated(since = "2021-07-05") + @Nullable T getContext(); + /** + * Returns a shared context argument that is set up when the {@link graphql.GraphQL#execute(graphql.ExecutionInput)} )} method + * is invoked. + *

+ * This is an info object which is provided to all DataFetchers. + * + * @return can NOT be null + */ + GraphQLContext getGraphQlContext(); + + /** + * This returns a context object that parent fields may have returned + * via {@link graphql.execution.DataFetcherResult#getLocalContext()} which can be used to pass down extra information to + * fields beyond the normal {@link #getSource()} + *

+ * This differs from {@link #getGraphQlContext()} in that it's field specific and passed from parent field to child field, + * whilst {@link #getGraphQlContext()} is global for the whole query. + *

+ * If the field is a top level field then 'localContext' equals null since it's never be set until those + * fields execute. + * + * @param you decide what type it is + * + * @return can be null if no field context objects are passed back by previous parent fields + */ + @Nullable + T getLocalContext(); + /** * This is the source object for the root query. * @@ -74,6 +131,7 @@ public interface DataFetchingEnvironment { * * @return can be null */ + @Nullable T getRoot(); /** @@ -83,31 +141,43 @@ public interface DataFetchingEnvironment { /** - * It can happen that a query has overlapping fields which are + * @return the list of fields + * + * @deprecated Use {@link #getMergedField()}. + */ + @Deprecated(since = "2018-12-20") + List getFields(); + + /** + * It can happen that a query has overlapping fields which * are querying the same data. If this is the case they get merged * together and fetched only once, but this method returns all of the Fields * from the query. - * + *

* Most of the time you probably want to use {@link #getField()}. - * + *

* Example query with more than one Field returned: * - * query Foo { - * bar - * ...BarFragment - * } + *

+     * {@code
      *
-     *  fragment BarFragment on Query {
-     *      bar
-     *  }
+     *      query Foo {
+     *          bar
+     *          ...BarFragment
+     *      }
      *
+     *      fragment BarFragment on Query {
+     *          bar
+     *      }
+     * }
+     * 
* * @return the list of fields currently queried */ - List getFields(); + MergedField getMergedField(); /** - * @return returns the field which is currently queried. See also {@link #getFields()} + * @return returns the field which is currently queried. See also {@link #getMergedField()}. */ Field getField(); @@ -118,9 +188,9 @@ public interface DataFetchingEnvironment { /** - * @return the field {@link ExecutionTypeInfo} for the current data fetch operation + * @return the field {@link ExecutionStepInfo} for the current data fetch operation */ - ExecutionTypeInfo getFieldTypeInfo(); + ExecutionStepInfo getExecutionStepInfo(); /** * @return the type of the parent of the current field @@ -148,7 +218,73 @@ public interface DataFetchingEnvironment { DataFetchingFieldSelectionSet getSelectionSet(); /** - * @return the current {@link ExecutionContext}. It gives access to the overall schema and other things related to the overall execution of the current request. + * This gives you access to the directives related to this field + * + * @return the {@link graphql.execution.directives.QueryDirectives} for the currently executing field + * + * @see graphql.execution.directives.QueryDirectives for more information */ - ExecutionContext getExecutionContext(); + QueryDirectives getQueryDirectives(); + + /** + * This allows you to retrieve a named dataloader from the underlying {@link org.dataloader.DataLoaderRegistry} + * + * @param dataLoaderName the name of the data loader to fetch + * @param the key type + * @param the value type + * + * @return the named data loader or null + * + * @see org.dataloader.DataLoaderRegistry#getDataLoader(String) + */ + @Nullable + DataLoader getDataLoader(String dataLoaderName); + + + /** + * @return the {@link org.dataloader.DataLoaderRegistry} in play + */ + DataLoaderRegistry getDataLoaderRegistry(); + + /** + * @return the current {@link java.util.Locale} instance used for this request + */ + Locale getLocale(); + + /** + * @return the current operation that is being executed + */ + OperationDefinition getOperationDefinition(); + + /** + * @return the current query Document that is being executed + */ + Document getDocument(); + + /** + * This returns the variables that have been passed into the query. Note that this is the query variables themselves and not the + * arguments to the field, which is accessed via {@link #getArguments()} + *

+ * The field arguments are created by interpolating any referenced variables and AST literals and resolving them into the arguments. + *

+ * Also note that the raw query variables are "coerced" into a map where the leaf scalar and enum types are called to create + * input coerced values. So the values you get here are not exactly as passed via {@link graphql.ExecutionInput#getVariables()} + * but have been processed. + * + * @return the coerced variables that have been passed to the query that is being executed + */ + Map getVariables(); + + + /** + * A method that should only be used by the GraphQL Java library itself. + * It is not intended for public use. + * + * @return an internal representation of the DataFetchingEnvironment + */ + @Internal + default Object toInternal() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/main/java/graphql/schema/DataFetchingEnvironmentBuilder.java b/src/main/java/graphql/schema/DataFetchingEnvironmentBuilder.java deleted file mode 100644 index f27562098a..0000000000 --- a/src/main/java/graphql/schema/DataFetchingEnvironmentBuilder.java +++ /dev/null @@ -1,149 +0,0 @@ -package graphql.schema; - -import graphql.PublicApi; -import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionId; -import graphql.execution.ExecutionTypeInfo; -import graphql.language.Field; -import graphql.language.FragmentDefinition; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * A builder of {@link DataFetchingEnvironment}s - */ -@PublicApi -public class DataFetchingEnvironmentBuilder { - - - /** - * @return a new {@link DataFetchingEnvironmentBuilder} - */ - public static DataFetchingEnvironmentBuilder newDataFetchingEnvironment() { - return new DataFetchingEnvironmentBuilder(); - } - - public static DataFetchingEnvironmentBuilder newDataFetchingEnvironment(DataFetchingEnvironment environment) { - return new DataFetchingEnvironmentBuilder() - .source(environment.getSource()) - .arguments(environment.getArguments()) - .context(environment.getContext()) - .root(environment.getRoot()) - .fields(environment.getFields()) - .fieldType(environment.getFieldType()) - .fieldTypeInfo(environment.getFieldTypeInfo()) - .parentType(environment.getParentType()) - .graphQLSchema(environment.getGraphQLSchema()) - .fragmentsByName(environment.getFragmentsByName()) - .executionId(environment.getExecutionId()) - .selectionSet(environment.getSelectionSet()) - .executionContext(environment.getExecutionContext()) - ; - } - - public static DataFetchingEnvironmentBuilder newDataFetchingEnvironment(ExecutionContext executionContext) { - return new DataFetchingEnvironmentBuilder() - .context(executionContext.getContext()) - .root(executionContext.getRoot()) - .graphQLSchema(executionContext.getGraphQLSchema()) - .fragmentsByName(executionContext.getFragmentsByName()) - .executionId(executionContext.getExecutionId()) - .executionContext(executionContext); - - } - - - private Object source; - private Map arguments = Collections.emptyMap(); - private Object context; - private Object root; - private GraphQLFieldDefinition fieldDefinition; - private List fields = Collections.emptyList(); - private GraphQLOutputType fieldType; - private GraphQLType parentType; - private GraphQLSchema graphQLSchema; - private Map fragmentsByName = Collections.emptyMap(); - private ExecutionId executionId; - private DataFetchingFieldSelectionSet selectionSet; - private ExecutionTypeInfo typeInfo; - private ExecutionContext executionContext; - - public DataFetchingEnvironmentBuilder source(Object source) { - this.source = source; - return this; - } - - public DataFetchingEnvironmentBuilder arguments(Map arguments) { - this.arguments = arguments; - return this; - } - - public DataFetchingEnvironmentBuilder context(Object context) { - this.context = context; - return this; - } - - public DataFetchingEnvironmentBuilder root(Object root) { - this.root = root; - return this; - } - - public DataFetchingEnvironmentBuilder fieldDefinition(GraphQLFieldDefinition fieldDefinition) { - this.fieldDefinition = fieldDefinition; - return this; - } - - public DataFetchingEnvironmentBuilder fields(List fields) { - this.fields = fields; - return this; - } - - public DataFetchingEnvironmentBuilder fieldType(GraphQLOutputType fieldType) { - this.fieldType = fieldType; - return this; - } - - public DataFetchingEnvironmentBuilder parentType(GraphQLType parentType) { - this.parentType = parentType; - return this; - } - - public DataFetchingEnvironmentBuilder graphQLSchema(GraphQLSchema graphQLSchema) { - this.graphQLSchema = graphQLSchema; - return this; - } - - public DataFetchingEnvironmentBuilder fragmentsByName(Map fragmentsByName) { - this.fragmentsByName = fragmentsByName; - return this; - } - - public DataFetchingEnvironmentBuilder executionId(ExecutionId executionId) { - this.executionId = executionId; - return this; - } - - public DataFetchingEnvironmentBuilder selectionSet(DataFetchingFieldSelectionSet selectionSet) { - this.selectionSet = selectionSet; - return this; - } - - public DataFetchingEnvironmentBuilder fieldTypeInfo(ExecutionTypeInfo typeInfo) { - this.typeInfo = typeInfo; - return this; - } - - public DataFetchingEnvironmentBuilder executionContext(ExecutionContext executionContext) { - this.executionContext = executionContext; - return this; - } - - public DataFetchingEnvironment build() { - return new DataFetchingEnvironmentImpl(source, arguments, context, root, - fieldDefinition, fields, fieldType, parentType, graphQLSchema, fragmentsByName, executionId, selectionSet, - typeInfo, - executionContext); - } -} diff --git a/src/main/java/graphql/schema/DataFetchingEnvironmentImpl.java b/src/main/java/graphql/schema/DataFetchingEnvironmentImpl.java index 3f9d88be94..b9cfce9485 100644 --- a/src/main/java/graphql/schema/DataFetchingEnvironmentImpl.java +++ b/src/main/java/graphql/schema/DataFetchingEnvironmentImpl.java @@ -1,93 +1,170 @@ package graphql.schema; +import com.google.common.collect.ImmutableMap; +import graphql.Assert; +import graphql.GraphQLContext; import graphql.Internal; +import graphql.Profiler; +import graphql.collect.ImmutableKit; +import graphql.collect.ImmutableMapWithNullValues; +import graphql.execution.DataLoaderDispatchStrategy; import graphql.execution.ExecutionContext; import graphql.execution.ExecutionId; -import graphql.execution.ExecutionTypeInfo; +import graphql.execution.ExecutionStepInfo; +import graphql.execution.MergedField; +import graphql.execution.directives.QueryDirectives; +import graphql.execution.incremental.AlternativeCallContext; +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys; +import graphql.language.Document; import graphql.language.Field; import graphql.language.FragmentDefinition; +import graphql.language.OperationDefinition; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.function.Supplier; -import static graphql.Assert.assertNotNull; - -@SuppressWarnings({"unchecked","TypeParameterUnusedInFormals"}) +@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) @Internal +@NullMarked public class DataFetchingEnvironmentImpl implements DataFetchingEnvironment { + @Nullable private final Object source; - private final Map arguments; + private final Supplier> arguments; + @Nullable private final Object context; + private final GraphQLContext graphQLContext; + @Nullable + private final Object localContext; + @Nullable private final Object root; private final GraphQLFieldDefinition fieldDefinition; - private final List fields; + private final MergedField mergedField; private final GraphQLOutputType fieldType; private final GraphQLType parentType; private final GraphQLSchema graphQLSchema; - private final Map fragmentsByName; + private final ImmutableMap fragmentsByName; private final ExecutionId executionId; private final DataFetchingFieldSelectionSet selectionSet; - private final ExecutionTypeInfo fieldTypeInfo; - private ExecutionContext executionContext; - - public DataFetchingEnvironmentImpl(Object source, - Map arguments, - Object context, - Object root, - GraphQLFieldDefinition fieldDefinition, - List fields, - GraphQLOutputType fieldType, - GraphQLType parentType, - GraphQLSchema graphQLSchema, - Map fragmentsByName, - ExecutionId executionId, - DataFetchingFieldSelectionSet selectionSet, - ExecutionTypeInfo fieldTypeInfo, - ExecutionContext executionContext) { - this.source = source; - this.arguments = arguments; - this.context = context; - this.root = root; - this.fieldDefinition = fieldDefinition; - this.fields = fields; - this.fieldType = fieldType; - this.parentType = parentType; - this.graphQLSchema = graphQLSchema; - this.fragmentsByName = fragmentsByName; - this.executionId = executionId; - this.selectionSet = selectionSet; - this.fieldTypeInfo = fieldTypeInfo; - this.executionContext = assertNotNull(executionContext); + private final Supplier executionStepInfo; + private final DataLoaderRegistry dataLoaderRegistry; + private final Locale locale; + private final OperationDefinition operationDefinition; + private final Document document; + private final ImmutableMapWithNullValues variables; + private final QueryDirectives queryDirectives; + private final int level; + + // used for internal() method + private final DFEInternalState dfeInternalState; + + private DataFetchingEnvironmentImpl(Builder builder) { + this.source = builder.source; + this.arguments = builder.arguments == null ? ImmutableKit::emptyMap : builder.arguments; + this.context = builder.context; + this.graphQLContext = Assert.assertNotNull(builder.graphQLContext); + this.localContext = builder.localContext; + this.root = builder.root; + this.fieldDefinition = builder.fieldDefinition; + this.mergedField = builder.mergedField; + this.fieldType = builder.fieldType; + this.parentType = builder.parentType; + this.graphQLSchema = builder.graphQLSchema; + this.fragmentsByName = builder.fragmentsByName == null ? ImmutableKit.emptyMap() : builder.fragmentsByName; + this.executionId = builder.executionId; + this.selectionSet = builder.selectionSet; + this.executionStepInfo = builder.executionStepInfo; + this.dataLoaderRegistry = builder.dataLoaderRegistry; + this.locale = builder.locale; + this.operationDefinition = builder.operationDefinition; + this.document = builder.document; + this.variables = builder.variables == null ? ImmutableMapWithNullValues.emptyMap() : builder.variables; + this.queryDirectives = builder.queryDirectives; + this.level = builder.level; + + // internal state + this.dfeInternalState = new DFEInternalState(builder.dataLoaderDispatchStrategy, builder.alternativeCallContext, builder.profiler); + } + + /** + * @return a new {@link graphql.schema.DataFetchingEnvironmentImpl.Builder} + */ + public static Builder newDataFetchingEnvironment() { + return new Builder(); + } + + public static Builder newDataFetchingEnvironment(DataFetchingEnvironment environment) { + return new Builder((DataFetchingEnvironmentImpl) environment); + } + + public static Builder newDataFetchingEnvironment(ExecutionContext executionContext) { + return new Builder() + .context(executionContext.getContext()) + .graphQLContext(executionContext.getGraphQLContext()) + .root(executionContext.getRoot()) + .graphQLSchema(executionContext.getGraphQLSchema()) + .fragmentsByName(executionContext.getFragmentsByName()) + .dataLoaderRegistry(executionContext.getDataLoaderRegistry()) + .locale(executionContext.getLocale()) + .document(executionContext.getDocument()) + .operationDefinition(executionContext.getOperationDefinition()) + .variables(executionContext.getCoercedVariables().toMap()) + .executionId(executionContext.getExecutionId()) + .dataLoaderDispatchStrategy(executionContext.getDataLoaderDispatcherStrategy()) + .profiler(executionContext.getProfiler()); + } @Override + @Nullable public T getSource() { return (T) source; } @Override public Map getArguments() { - return arguments; + return ImmutableMapWithNullValues.copyOf(arguments.get()); } @Override public boolean containsArgument(String name) { - return arguments.containsKey(name); + return arguments.get().containsKey(name); } @Override - public T getArgument(String name) { - return (T) arguments.get(name); + public @Nullable T getArgument(String name) { + return (T) arguments.get().get(name); } @Override - public T getContext() { + public T getArgumentOrDefault(String name, T defaultValue) { + return (T) arguments.get().getOrDefault(name, defaultValue); + } + + @Override + public @Nullable T getContext() { return (T) context; } @Override - public T getRoot() { + public GraphQLContext getGraphQlContext() { + return graphQLContext; + } + + @Override + public @Nullable T getLocalContext() { + return (T) localContext; + } + + @Override + public @Nullable T getRoot() { return (T) root; } @@ -98,12 +175,17 @@ public GraphQLFieldDefinition getFieldDefinition() { @Override public List getFields() { - return fields; + return mergedField.getFields(); } @Override public Field getField() { - return fields.get(0); + return mergedField.getSingleField(); + } + + @Override + public MergedField getMergedField() { + return mergedField; } @Override @@ -137,19 +219,292 @@ public DataFetchingFieldSelectionSet getSelectionSet() { } @Override - public ExecutionTypeInfo getFieldTypeInfo() { - return fieldTypeInfo; + public QueryDirectives getQueryDirectives() { + return queryDirectives; + } + + @Override + public ExecutionStepInfo getExecutionStepInfo() { + return executionStepInfo.get(); + } + + + @Override + public @Nullable DataLoader getDataLoader(String dataLoaderName) { + DataLoader dataLoader = dataLoaderRegistry.getDataLoader(dataLoaderName); + if (dataLoader == null) { + return null; + } + if (!graphQLContext.getBoolean(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, false) + && !graphQLContext.getBoolean(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, false)) { + return dataLoader; + } + return new DataLoaderWithContext<>(this, dataLoaderName, dataLoader); + } + + @Override + public DataLoaderRegistry getDataLoaderRegistry() { + return dataLoaderRegistry; } @Override - public ExecutionContext getExecutionContext() { - return executionContext; + public Locale getLocale() { + return locale; + } + + @Override + public OperationDefinition getOperationDefinition() { + return operationDefinition; + } + + @Override + public Document getDocument() { + return document; + } + + @Override + public Map getVariables() { + return variables; + } + + + @Override + public Object toInternal() { + return this.dfeInternalState; } @Override public String toString() { return "DataFetchingEnvironmentImpl{" + - "fieldTypeInfo=" + fieldTypeInfo + - '}'; + "executionStepInfo=" + executionStepInfo + + '}'; + } + + public int getLevel() { + return level; + } + + @NullUnmarked + public static class Builder { + + private Object source; + private Object context; + private GraphQLContext graphQLContext = GraphQLContext.newContext().build(); + private Object localContext; + private Object root; + private GraphQLFieldDefinition fieldDefinition; + private MergedField mergedField; + private GraphQLOutputType fieldType; + private GraphQLType parentType; + private GraphQLSchema graphQLSchema; + private ExecutionId executionId; + private DataFetchingFieldSelectionSet selectionSet; + private Supplier executionStepInfo; + private DataLoaderRegistry dataLoaderRegistry; + private Locale locale; + private OperationDefinition operationDefinition; + private Document document; + private Supplier> arguments; + private ImmutableMap fragmentsByName; + private ImmutableMapWithNullValues variables; + private QueryDirectives queryDirectives; + private DataLoaderDispatchStrategy dataLoaderDispatchStrategy; + private Profiler profiler; + private AlternativeCallContext alternativeCallContext; + private int level; + + public Builder(DataFetchingEnvironmentImpl env) { + this.source = env.source; + this.arguments = env.arguments; + this.context = env.context; + this.graphQLContext = env.graphQLContext; + this.localContext = env.localContext; + this.root = env.root; + this.fieldDefinition = env.fieldDefinition; + this.mergedField = env.mergedField; + this.fieldType = env.fieldType; + this.parentType = env.parentType; + this.graphQLSchema = env.graphQLSchema; + this.fragmentsByName = env.fragmentsByName; + this.executionId = env.executionId; + this.selectionSet = env.selectionSet; + this.executionStepInfo = env.executionStepInfo; + this.dataLoaderRegistry = env.dataLoaderRegistry; + this.locale = env.locale; + this.operationDefinition = env.operationDefinition; + this.document = env.document; + this.variables = env.variables; + this.queryDirectives = env.queryDirectives; + this.dataLoaderDispatchStrategy = env.dfeInternalState.dataLoaderDispatchStrategy; + this.profiler = env.dfeInternalState.profiler; + this.alternativeCallContext = env.dfeInternalState.alternativeCallContext; + this.level = env.level; + } + + public Builder() { + } + + public Builder source(Object source) { + this.source = source; + return this; + } + + public Builder arguments(Map arguments) { + return arguments(() -> arguments); + } + + public Builder arguments(Supplier> arguments) { + this.arguments = arguments; + return this; + } + + @Deprecated(since = "2021-07-05") + public Builder context(@Nullable Object context) { + this.context = context; + return this; + } + + public Builder graphQLContext(GraphQLContext context) { + this.graphQLContext = Assert.assertNotNull(context, "GraphQLContext cannot be null"); + return this; + } + + public Builder localContext(Object localContext) { + this.localContext = localContext; + return this; + } + + public Builder root(Object root) { + this.root = root; + return this; + } + + public Builder fieldDefinition(GraphQLFieldDefinition fieldDefinition) { + this.fieldDefinition = fieldDefinition; + return this; + } + + public Builder mergedField(MergedField mergedField) { + this.mergedField = mergedField; + return this; + } + + public Builder fieldType(GraphQLOutputType fieldType) { + this.fieldType = fieldType; + return this; + } + + public Builder parentType(GraphQLType parentType) { + this.parentType = parentType; + return this; + } + + public Builder graphQLSchema(GraphQLSchema graphQLSchema) { + this.graphQLSchema = graphQLSchema; + return this; + } + + public Builder fragmentsByName(Map fragmentsByName) { + this.fragmentsByName = ImmutableMap.copyOf(fragmentsByName); + return this; + } + + public Builder executionId(ExecutionId executionId) { + this.executionId = executionId; + return this; + } + + public Builder selectionSet(DataFetchingFieldSelectionSet selectionSet) { + this.selectionSet = selectionSet; + return this; + } + + public Builder executionStepInfo(ExecutionStepInfo executionStepInfo) { + return executionStepInfo(() -> executionStepInfo); + } + + public Builder executionStepInfo(Supplier executionStepInfo) { + this.executionStepInfo = executionStepInfo; + return this; + } + + public Builder dataLoaderRegistry(DataLoaderRegistry dataLoaderRegistry) { + this.dataLoaderRegistry = dataLoaderRegistry; + return this; + } + + public Builder locale(Locale locale) { + this.locale = locale; + return this; + } + + public Builder operationDefinition(OperationDefinition operationDefinition) { + this.operationDefinition = operationDefinition; + return this; + } + + public Builder document(Document document) { + this.document = document; + return this; + } + + public Builder variables(Map variables) { + this.variables = ImmutableMapWithNullValues.copyOf(variables); + return this; + } + + public Builder queryDirectives(QueryDirectives queryDirectives) { + this.queryDirectives = queryDirectives; + return this; + } + + public Builder deferredCallContext(AlternativeCallContext alternativeCallContext) { + this.alternativeCallContext = alternativeCallContext; + return this; + } + + public DataFetchingEnvironment build() { + return new DataFetchingEnvironmentImpl(this); + } + + public Builder dataLoaderDispatchStrategy(DataLoaderDispatchStrategy dataLoaderDispatcherStrategy) { + this.dataLoaderDispatchStrategy = dataLoaderDispatcherStrategy; + return this; + } + + public Builder profiler(Profiler profiler) { + this.profiler = profiler; + return this; + } + + public Builder level(int level) { + this.level = level; + return this; + } + } + + @Internal + public static class DFEInternalState { + final DataLoaderDispatchStrategy dataLoaderDispatchStrategy; + final Profiler profiler; + final AlternativeCallContext alternativeCallContext; + + public DFEInternalState(DataLoaderDispatchStrategy dataLoaderDispatchStrategy, AlternativeCallContext alternativeCallContext, Profiler profiler) { + this.dataLoaderDispatchStrategy = dataLoaderDispatchStrategy; + this.alternativeCallContext = alternativeCallContext; + this.profiler = profiler; + } + + public DataLoaderDispatchStrategy getDataLoaderDispatchStrategy() { + return dataLoaderDispatchStrategy; + } + + public AlternativeCallContext getDeferredCallContext() { + return alternativeCallContext; + } + + public Profiler getProfiler() { + return profiler; + } } } diff --git a/src/main/java/graphql/schema/DataFetchingFieldSelectionSet.java b/src/main/java/graphql/schema/DataFetchingFieldSelectionSet.java index 3b30ae0f47..62e7ad8333 100644 --- a/src/main/java/graphql/schema/DataFetchingFieldSelectionSet.java +++ b/src/main/java/graphql/schema/DataFetchingFieldSelectionSet.java @@ -1,15 +1,14 @@ package graphql.schema; -import graphql.language.Field; +import graphql.PublicApi; import java.util.List; import java.util.Map; -import java.util.function.Supplier; /** - * This allows you to retrieve the selection set of fields that have been asked for when the + * This class allows you to retrieve the selection set of fields that have been asked for when the * {@link DataFetcher} was invoked. - * + *

* For example imagine we are fetching the field 'user' in the following query * *

@@ -27,43 +26,190 @@
  *  }
  * }
  * 
- * + *

* The selection set in the case above consists of the fields "name, age, weight, friends and friends/name". - * + *

* You can use this selection set perhaps to "peek" ahead and decide that field values you might need * from the underlying data system. Imagine a SQL system where this might represent the SQL 'projection' * of columns say. + *

+ * However composite types such as Interfaces and Unions add some complexity. You cant know + * ahead of time the exact field and object types involved. There in fact be multiple possible `conditional` fields. + *

+ * This class represents this by returning a list of fields and having two addressing mechanisms, + * a simple `x/y` one and the more specific `Foo.x/Bar.y` mechanism. + *

+ * For example imagine a `Pet` interface type that has `Cat` and `Dog` object type implementations. The query might + * be: + * + *

+ * {@code
+ *  {
+ *      pet {
+ *          name
+ *      }
+ *  }
+ * }
+ * 
+ *

+ * In the example above you have a `Cat.name`and `Dog.name` as possible sub selections of the `pet` field. They are can be addressed by + * either `name` or `Dog.name` or `Cat.name` + * + *

+ * {@code
+ *  selectionSet.contains("name") == true
+ *  selectionSet.contains("Dog.name", "Cat.name") == true
+ *
+ *  List petNames = selectionSet.getFields("name")
+ *  petNames.size() == 2
+ *
+ *  List dogNames = selectionSet.getFields("Dog.name")
+ *  dogNames.size() == 1
+ * }
+ * 
+ *

+ * The simple naming is easier to work with but the type prefixed naming is more precise. + *

+ * Another complication is any field aliasing that a client can specify. + * + *

+ * {@code
+ *  {
+ *      pet {
+ *          name(arg : "foo")
+ *          ... on Dog {
+ *             aliasedName : name(arg : "bar")
+ *          }
+ *     }
+ *  }
+ * }
+ * 
+ *

+ * In the example above the `selectionSet.getFields("name")` actually returns three {@link graphql.schema.SelectedField}s, + * one for `Dog.name`, one for `Cat.name` and one for `Dog.name` with an alias of `aliasedName`. The arguments can + * differ on {@link graphql.schema.SelectedField}s that have different {@link SelectedField#getResultKey()}s, hence the multiple + * selected fields returned. + *

+ * To help you there is the {@link #getFieldsGroupedByResultKey()} that returns a {@code Map>} keyed + * by result key, that is by the field alias or by the field name. */ -public interface DataFetchingFieldSelectionSet extends Supplier>> { +@PublicApi +public interface DataFetchingFieldSelectionSet { + + /** + * This will return true if the field selection set matches a specified "glob" pattern matching ie + * the glob pattern matching supported by {@link java.nio.file.FileSystem#getPathMatcher}. + *

+ * This will allow you to use '*', '**' and '?' as special matching characters such that "invoice/customer*" would + * match an invoice field with child fields that start with 'customer'. + * + * @param fieldGlobPattern the glob pattern to match fields against + * + * @return true if the selection set contains these fields + * + * @see java.nio.file.FileSystem#getPathMatcher(String) + */ + boolean contains(String fieldGlobPattern); /** - * @return a map of the fields that represent the selection set + * This will return true if the field selection set matches any of the specified "glob" pattern matches ie + * the glob pattern matching supported by {@link java.nio.file.FileSystem#getPathMatcher}. + *

+ * This will allow you to use '*', '**' and '?' as special matching characters such that "invoice/customer*" would + * match an invoice field with child fields that start with 'customer'. + * + * @param fieldGlobPattern the glob pattern to match fields against + * @param fieldGlobPatterns optionally more glob pattern to match fields against + * + * @return true if the selection set contains any of these these fields + * + * @see java.nio.file.FileSystem#getPathMatcher(String) */ - @Override - Map> get(); + boolean containsAnyOf(String fieldGlobPattern, String... fieldGlobPatterns); /** - * @return a map of the arguments for each field in the selection set + * This will return true if the field selection set matches all of the specified "glob" pattern matches ie + * the glob pattern matching supported by {@link java.nio.file.FileSystem#getPathMatcher}. + *

+ * This will allow you to use '*', '**' and '?' as special matching characters such that "invoice/customer*" would + * match an invoice field with child fields that start with 'customer'. + * + * @param fieldGlobPattern the glob pattern to match fields against + * @param fieldGlobPatterns optionally more glob pattern to match fields against + * + * @return true if the selection set contains all of these these fields + * + * @see java.nio.file.FileSystem#getPathMatcher(String) */ - Map> getArguments(); + boolean containsAllOf(String fieldGlobPattern, String... fieldGlobPatterns); /** - * @return a map of the {@link graphql.schema.GraphQLFieldDefinition}s for each field in the selection set + * This will return all selected fields. + *

+ * The fields are guaranteed to be in pre-order as they appear in the query. + *

+ * A selected field may have an alias - and hence is a unique field in the returned list. It may + * have the same field names as others in the list but when you also consider the alias then it is indeed unique + * because it would be another entry in the graphql result. + * + * @return a list of all selected fields or empty list if none match */ - Map getDefinitions(); + List getFields(); /** - * This will return true if the field selection set matches a specified "glob" pattern matching ie - * the glob pattern matching supported by {@link java.nio.file.FileSystem#getPathMatcher}. + * This will return all selected fields that are immediate child fields + * of the field being fetched. + *

+ * The fields are guaranteed to be in pre-order as they appear in the query. + *

+ * A selected field may have an alias - and hence is a unique field in the returned list. It may + * have the same field names as others in the list but when you also consider the alias then it is indeed unique + * because it would be another entry in the graphql result. * + * @return a list of all selected immediate child fields or empty list if none match + */ + List getImmediateFields(); + + /** + * This will return a list of selected fields that match a specified "glob" pattern matching ie + * the glob pattern matching supported by {@link java.nio.file.FileSystem#getPathMatcher}. + *

* This will allow you to use '*', '**' and '?' as special matching characters such that "invoice/customer*" would * match an invoice field with child fields that start with 'customer'. + *

+ * The fields are guaranteed to be in pre-order as they appear in the query. + *

+ * A selected field may have an alias - and hence is a unique field in the returned list. It may + * have the same field names as others in the list but when you also consider the alias then it is indeed unique + * because it would be another entry in the graphql result. * - * @param fieldGlobPattern the glob pattern to match fields against - * @return true if the selection set contains these fields + * @param fieldGlobPattern the glob pattern to match fields against + * @param fieldGlobPatterns optionally more glob pattern to match fields against * - * @see java.nio.file.FileSystem#getPathMatcher(String) + * @return a list of selected fields or empty list if none match */ - boolean contains(String fieldGlobPattern); + List getFields(String fieldGlobPattern, String... fieldGlobPatterns); + + /** + * The result key of a selected field represents what the graphql return value will be. The same {@link graphql.schema.GraphQLFieldDefinition} + * may lead to a field being asked for multiple times (with differing arguments) if field aliases are used. This method + * helps you get all possible field invocations grouped by their result key. The arguments are guaranteed to be the same if + * the result key is the same, otherwise the query would not have validated correctly. + * + * @return a map of selected fields grouped by result key or an empty map if none match + */ + Map> getFieldsGroupedByResultKey(); + /** + * The result key of a selected field represents what the graphql return value will be. The same {@link graphql.schema.GraphQLFieldDefinition} + * may lead to a field being asked for multiple times (with differing arguments) if field aliases are used. This method + * helps you get all possible field invocations grouped by their result key. The arguments are guaranteed to be the same if + * the result key is the same, otherwise the query would not have validated correctly. + * + * @param fieldGlobPattern the glob pattern to match fields against + * @param fieldGlobPatterns optionally more glob pattern to match fields against + * + * @return a map of selected fields grouped by result key or an empty map if none match + */ + Map> getFieldsGroupedByResultKey(String fieldGlobPattern, String... fieldGlobPatterns); } diff --git a/src/main/java/graphql/schema/DataFetchingFieldSelectionSetImpl.java b/src/main/java/graphql/schema/DataFetchingFieldSelectionSetImpl.java index d352ad90ed..4800a0dfcf 100644 --- a/src/main/java/graphql/schema/DataFetchingFieldSelectionSetImpl.java +++ b/src/main/java/graphql/schema/DataFetchingFieldSelectionSetImpl.java @@ -1,172 +1,429 @@ package graphql.schema; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import graphql.Internal; -import graphql.execution.ExecutionContext; -import graphql.execution.ExecutionTypeInfo; -import graphql.execution.FieldCollector; -import graphql.execution.FieldCollectorParameters; -import graphql.execution.ValuesResolver; -import graphql.introspection.Introspection; -import graphql.language.Field; -import graphql.language.FragmentDefinition; +import graphql.collect.ImmutableKit; +import graphql.normalized.ExecutableNormalizedField; +import graphql.util.LockKit; +import java.io.File; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; -import static java.util.Collections.emptyMap; +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.util.FpKit.newList; @Internal public class DataFetchingFieldSelectionSetImpl implements DataFetchingFieldSelectionSet { + private final static String SEP = "/"; + private final static boolean UNIXY = SEP.equals(File.separator); + private final static DataFetchingFieldSelectionSet NOOP = new DataFetchingFieldSelectionSet() { + @Override - public Map> get() { - return emptyMap(); + public boolean contains(String fieldGlobPattern) { + return false; } @Override - public Map> getArguments() { - return emptyMap(); + public boolean containsAnyOf(String fieldGlobPattern, String... fieldGlobPatterns) { + return false; } @Override - public Map getDefinitions() { - return emptyMap(); + public boolean containsAllOf(String fieldGlobPattern, String... fieldGlobPatterns) { + return false; } + @Override - public boolean contains(String fieldGlobPattern) { - return false; + public List getFields() { + return emptyList(); + } + + @Override + public List getImmediateFields() { + return emptyList(); + } + + @Override + public List getFields(String fieldGlobPattern, String... fieldGlobPatterns) { + return ImmutableKit.emptyList(); + } + + @Override + public Map> getFieldsGroupedByResultKey() { + return ImmutableKit.emptyMap(); + } + + @Override + public Map> getFieldsGroupedByResultKey(String fieldGlobPattern, String... fieldGlobPatterns) { + return ImmutableKit.emptyMap(); } }; - public static DataFetchingFieldSelectionSet newCollector(ExecutionContext executionContext, GraphQLType fieldType, List fields) { - GraphQLType unwrappedType = ExecutionTypeInfo.unwrapBaseType(fieldType); - if (unwrappedType instanceof GraphQLFieldsContainer) { - return new DataFetchingFieldSelectionSetImpl(executionContext, (GraphQLFieldsContainer) unwrappedType, fields); + public static DataFetchingFieldSelectionSet newCollector(GraphQLSchema schema, GraphQLOutputType fieldType, Supplier normalizedFieldSupplier) { + if (!GraphQLTypeUtil.isLeaf(fieldType)) { + return new DataFetchingFieldSelectionSetImpl(normalizedFieldSupplier, schema); } else { - // we can only collect fields on object types and interfaces. Scalars, Unions etc... cant be done. + // we can only collect fields on object types and interfaces and unions. return NOOP; } } - private static GraphQLObjectType asObjectTypeOrNull(GraphQLType unwrappedType) { - return unwrappedType instanceof GraphQLObjectType ? (GraphQLObjectType) unwrappedType : null; - } + private final Supplier normalizedFieldSupplier; - private final List parentFields; - private final GraphQLSchema graphQLSchema; - private final GraphQLFieldsContainer parentFieldType; - private final Map variables; - private final Map fragmentsByName; + private final LockKit.ReentrantLock lock = new LockKit.ReentrantLock(); + private volatile boolean computedValues; + private volatile boolean computedImmediateValues; - private Map> selectionSetFields; - private Map selectionSetFieldDefinitions; - private Map> selectionSetFieldArgs; - private Set flattenedFields; + // we have multiple entries in this map so that we can do glob matching in multiple ways + // however it needs to be normalised back to a set of unique fields when give back out to + // the caller. + private Map> normalisedSelectionSetFields; + private List immediateFields; + private Set flattenedFieldsForGlobSearching; + private final GraphQLSchema schema; - private DataFetchingFieldSelectionSetImpl(ExecutionContext executionContext, GraphQLFieldsContainer parentFieldType, List parentFields) { - this.parentFields = parentFields; - this.graphQLSchema = executionContext.getGraphQLSchema(); - this.parentFieldType = parentFieldType; - this.variables = executionContext.getVariables(); - this.fragmentsByName = executionContext.getFragmentsByName(); + private DataFetchingFieldSelectionSetImpl(Supplier normalizedFieldSupplier, GraphQLSchema schema) { + this.schema = schema; + this.normalizedFieldSupplier = normalizedFieldSupplier; } - @Override - public Map> get() { - // by having a .get() method we get lazy evaluation. - computeValuesLazily(); - return selectionSetFields; + public boolean contains(String fieldGlobPattern) { + if (fieldGlobPattern == null || fieldGlobPattern.isEmpty()) { + return false; + } + computeValuesLazily(false); + fieldGlobPattern = removeLeadingSlash(fieldGlobPattern); + PathMatcher globMatcher = globMatcher(fieldGlobPattern); + for (String flattenedField : flattenedFieldsForGlobSearching) { + flattenedField = osAppropriate(flattenedField); + Path path = Paths.get(flattenedField); + if (globMatcher.matches(path)) { + return true; + } + } + return false; + } + + private String osAppropriate(String flattenedField) { + if (UNIXY) { + return flattenedField; + } else { + return flattenedField.replace(SEP, "\\"); + } } @Override - public Map> getArguments() { - computeValuesLazily(); - return selectionSetFieldArgs; + public boolean containsAnyOf(String fieldGlobPattern, String... fieldGlobPatterns) { + assertNotNull(fieldGlobPattern); + assertNotNull(fieldGlobPatterns); + for (String globPattern : mkIterable(fieldGlobPattern, fieldGlobPatterns)) { + if (contains(globPattern)) { + return true; + } + } + return false; } @Override - public Map getDefinitions() { - computeValuesLazily(); - return selectionSetFieldDefinitions; + public boolean containsAllOf(String fieldGlobPattern, String... fieldGlobPatterns) { + assertNotNull(fieldGlobPattern); + assertNotNull(fieldGlobPatterns); + for (String globPattern : mkIterable(fieldGlobPattern, fieldGlobPatterns)) { + if (!contains(globPattern)) { + return false; + } + } + return true; } @Override - public boolean contains(String fieldGlobPattern) { + public List getFields(String fieldGlobPattern, String... fieldGlobPatterns) { if (fieldGlobPattern == null || fieldGlobPattern.isEmpty()) { - return false; + return emptyList(); } - computeValuesLazily(); - PathMatcher globMatcher = FileSystems.getDefault().getPathMatcher("glob:" + fieldGlobPattern); - for (String flattenedField : flattenedFields) { - Path path = Paths.get(flattenedField); - if (globMatcher.matches(path)) { - return true; + computeValuesLazily(false); + + List targetNames = new ArrayList<>(); + for (String flattenedField : flattenedFieldsForGlobSearching) { + for (String globPattern : mkIterable(fieldGlobPattern, fieldGlobPatterns)) { + PathMatcher globMatcher = globMatcher(globPattern); + Path path = Paths.get(flattenedField); + if (globMatcher.matches(path)) { + targetNames.add(flattenedField); + } } } - return false; + + return toSetSemanticsList(targetNames.stream() + .flatMap(name -> normalisedSelectionSetFields.getOrDefault(name, emptyList()).stream())); + } + + @Override + public List getFields() { + computeValuesLazily(false); + return toSetSemanticsList(normalisedSelectionSetFields.values().stream() + .flatMap(Collection::stream)); + } + + private List toSetSemanticsList(Stream stream) { + return ImmutableList.copyOf(stream + .collect(ImmutableSet.toImmutableSet())); + } + + @Override + public List getImmediateFields() { + computeValuesLazily(true); + return immediateFields; + } + + @Override + public Map> getFieldsGroupedByResultKey() { + return getFields().stream().collect(Collectors.groupingBy(SelectedField::getResultKey)); } - private void computeValuesLazily() { - synchronized (this) { - if (selectionSetFields != null) { + @Override + public Map> getFieldsGroupedByResultKey(String fieldGlobPattern, String... fieldGlobPatterns) { + return getFields(fieldGlobPattern, fieldGlobPatterns).stream().collect(Collectors.groupingBy(SelectedField::getResultKey)); + } + + private void computeValuesLazily(boolean immediate) { + if (computedValues) { + return; + } + + // Avoid recomputing the immediate fields if they have already been computed. + if (immediate && computedImmediateValues) { + return; + } + + // this supplier is a once only thread synced call - so do it outside this lock + // if only to have only 1 lock in action at a time + ExecutableNormalizedField currentNormalisedField = normalizedFieldSupplier.get(); + + lock.runLocked(() -> { + if (computedValues) { return; } - selectionSetFields = new LinkedHashMap<>(); - selectionSetFieldDefinitions = new LinkedHashMap<>(); - selectionSetFieldArgs = new LinkedHashMap<>(); - flattenedFields = new LinkedHashSet<>(); + if (computedImmediateValues && immediate) { + return; + } + + flattenedFieldsForGlobSearching = new LinkedHashSet<>(); + normalisedSelectionSetFields = new LinkedHashMap<>(); + ImmutableList.Builder immediateFieldsBuilder = ImmutableList.builder(); + traverseSubSelectedFields(currentNormalisedField, immediateFieldsBuilder, "", "", true, immediate); + immediateFields = immediateFieldsBuilder.build(); + computedImmediateValues = true; + computedValues = !immediate; + }); + } + + private void traverseSubSelectedFields(ExecutableNormalizedField currentNormalisedField, ImmutableList.Builder immediateFieldsBuilder, String qualifiedFieldPrefix, String simpleFieldPrefix, boolean firstLevel, boolean immediate) { + List children = currentNormalisedField.getChildren(); + for (ExecutableNormalizedField normalizedSubSelectedField : children) { + String typeQualifiedName = mkTypeQualifiedName(normalizedSubSelectedField); + String simpleName = normalizedSubSelectedField.getName(); + + String globQualifiedName = mkFieldGlobName(qualifiedFieldPrefix, typeQualifiedName); + String globSimpleName = mkFieldGlobName(simpleFieldPrefix, simpleName); - traverseFields(parentFields, parentFieldType, ""); + flattenedFieldsForGlobSearching.add(globQualifiedName); + // put in entries for the simple names - eg `Invoice.payments/Payment.amount` becomes `payments/amount` + flattenedFieldsForGlobSearching.add(globSimpleName); + + SelectedFieldImpl selectedField = new SelectedFieldImpl(globSimpleName, globQualifiedName, normalizedSubSelectedField, schema); + if (firstLevel) { + immediateFieldsBuilder.add(selectedField); + } + normalisedSelectionSetFields.computeIfAbsent(globQualifiedName, newList()).add(selectedField); + normalisedSelectionSetFields.computeIfAbsent(globSimpleName, newList()).add(selectedField); + + if (normalizedSubSelectedField.hasChildren() && !immediate) { + traverseSubSelectedFields(normalizedSubSelectedField, immediateFieldsBuilder, globQualifiedName, globSimpleName, false, false); + } } } - private final static String SEP = "/"; + private String removeLeadingSlash(String fieldGlobPattern) { + if (fieldGlobPattern.startsWith(SEP)) { + fieldGlobPattern = fieldGlobPattern.substring(1); + } + return fieldGlobPattern; + } - private void traverseFields(List fieldList, GraphQLFieldsContainer parentFieldType, String fieldPrefix) { - FieldCollector fieldCollector = new FieldCollector(); - ValuesResolver valuesResolver = new ValuesResolver(); + private static String mkTypeQualifiedName(ExecutableNormalizedField executableNormalizedField) { + return executableNormalizedField.objectTypeNamesToString() + "." + executableNormalizedField.getName(); + } + + private static String mkFieldGlobName(String fieldPrefix, String fieldName) { + return (!fieldPrefix.isEmpty() ? fieldPrefix + SEP : "") + fieldName; + } + + private static PathMatcher globMatcher(String fieldGlobPattern) { + return FileSystems.getDefault().getPathMatcher("glob:" + fieldGlobPattern); + } + + private List mkIterable(String fieldGlobPattern, String[] fieldGlobPatterns) { + List l = new ArrayList<>(); + l.add(fieldGlobPattern); + Collections.addAll(l, fieldGlobPatterns); + return l; + } + + @Override + public String toString() { + if (!computedValues) { + return "notComputed"; + } + return String.join("\n", flattenedFieldsForGlobSearching); + } - FieldCollectorParameters parameters = FieldCollectorParameters.newParameters() - .schema(graphQLSchema) - .objectType(asObjectTypeOrNull(parentFieldType)) - .fragments(fragmentsByName) - .variables(variables) - .build(); + private static class SelectedFieldImpl implements SelectedField { - Map> collectedFields = fieldCollector.collectFields(parameters, fieldList); - for (Map.Entry> entry : collectedFields.entrySet()) { - String fieldName = mkFieldName(fieldPrefix, entry.getKey()); - List collectedFieldList = entry.getValue(); - selectionSetFields.put(fieldName, collectedFieldList); + private final String qualifiedName; + private final String fullyQualifiedName; + private final DataFetchingFieldSelectionSet selectionSet; + private final ExecutableNormalizedField executableNormalizedField; + private final GraphQLSchema schema; - Field field = collectedFieldList.get(0); - GraphQLFieldDefinition fieldDef = Introspection.getFieldDef(graphQLSchema, (GraphQLCompositeType) parentFieldType, field.getName()); - GraphQLType unwrappedType = ExecutionTypeInfo.unwrapBaseType(fieldDef.getType()); - Map argumentValues = valuesResolver.getArgumentValues(fieldDef.getArguments(), field.getArguments(), variables); + private SelectedFieldImpl(String simpleQualifiedName, String fullyQualifiedName, ExecutableNormalizedField executableNormalizedField, GraphQLSchema schema) { + this.schema = schema; + this.qualifiedName = simpleQualifiedName; + this.fullyQualifiedName = fullyQualifiedName; + this.executableNormalizedField = executableNormalizedField; + this.selectionSet = new DataFetchingFieldSelectionSetImpl(() -> executableNormalizedField, schema); + } - selectionSetFieldArgs.put(fieldName, argumentValues); - selectionSetFieldDefinitions.put(fieldName, fieldDef); - flattenedFields.add(fieldName); + private SelectedField mkParent(ExecutableNormalizedField executableNormalizedField) { + String parentSimpleQualifiedName = beforeLastSlash(qualifiedName); + String parentFullyQualifiedName = beforeLastSlash(fullyQualifiedName); + return executableNormalizedField.getParent() == null ? null : + new SelectedFieldImpl(parentSimpleQualifiedName, parentFullyQualifiedName, executableNormalizedField.getParent(), schema); + } - if (unwrappedType instanceof GraphQLFieldsContainer) { - traverseFields(collectedFieldList, (GraphQLFieldsContainer) unwrappedType, fieldName); + private String beforeLastSlash(String name) { + int index = name.lastIndexOf("/"); + if (index > 0) { + return name.substring(0, index); } + return ""; } - } - private String mkFieldName(String fieldPrefix, String fieldName) { - return (!fieldPrefix.isEmpty() ? fieldPrefix + SEP : "") + fieldName; + @Override + public String getName() { + return executableNormalizedField.getName(); + } + + @Override + public String getQualifiedName() { + return qualifiedName; + } + + @Override + public String getFullyQualifiedName() { + return fullyQualifiedName; + } + + @Override + public List getFieldDefinitions() { + return executableNormalizedField.getFieldDefinitions(schema); + } + + @Override + public GraphQLOutputType getType() { + return executableNormalizedField.getType(schema); + } + + @Override + public List getObjectTypes() { + return this.schema.getTypes(executableNormalizedField.getObjectTypeNames()); + } + + @Override + public List getObjectTypeNames() { + return ImmutableList.copyOf(executableNormalizedField.getObjectTypeNames()); + } + + @Override + public Map getArguments() { + return executableNormalizedField.getResolvedArguments(); + } + + @Override + public int getLevel() { + return executableNormalizedField.getLevel(); + } + + @Override + public boolean isConditional() { + return executableNormalizedField.isConditional(this.schema); + } + + @Override + public String getAlias() { + return executableNormalizedField.getAlias(); + } + + @Override + public String getResultKey() { + return executableNormalizedField.getResultKey(); + } + + @Override + public SelectedField getParentField() { + // lazy + return mkParent(executableNormalizedField); + } + + @Override + public DataFetchingFieldSelectionSet getSelectionSet() { + return selectionSet; + } + + // a selected field is the same as another selected field if it's the same ExecutableNF + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SelectedFieldImpl that = (SelectedFieldImpl) o; + return executableNormalizedField.equals(that.executableNormalizedField); + } + + @Override + public int hashCode() { + return Objects.hash(executableNormalizedField); + } + + @Override + public String toString() { + return getFullyQualifiedName(); + } } } diff --git a/src/main/java/graphql/schema/DataLoaderWithContext.java b/src/main/java/graphql/schema/DataLoaderWithContext.java new file mode 100644 index 0000000000..3d4224b364 --- /dev/null +++ b/src/main/java/graphql/schema/DataLoaderWithContext.java @@ -0,0 +1,81 @@ +package graphql.schema; + +import graphql.Internal; +import graphql.execution.incremental.AlternativeCallContext; +import graphql.execution.instrumentation.dataloader.ExhaustedDataLoaderDispatchStrategy; +import graphql.execution.instrumentation.dataloader.PerLevelDataLoaderDispatchStrategy; +import org.dataloader.DataLoader; +import org.dataloader.DelegatingDataLoader; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +@Internal +@NullMarked +public class DataLoaderWithContext extends DelegatingDataLoader { + final DataFetchingEnvironment dfe; + final String dataLoaderName; + + public DataLoaderWithContext(DataFetchingEnvironment dfe, String dataLoaderName, DataLoader delegate) { + super(delegate); + this.dataLoaderName = dataLoaderName; + this.dfe = dfe; + } + + // general note: calling super.load() is important, because otherwise the data loader will sometimes called + // later than the dispatch, which results in a hanging DL + + @Override + public CompletableFuture load(K key) { + CompletableFuture result = super.load(key); + newDataLoaderInvocation(); + return result; + } + + @Override + public CompletableFuture load(@NonNull K key, @Nullable Object keyContext) { + CompletableFuture result = super.load(key, keyContext); + newDataLoaderInvocation(); + return result; + } + + @Override + public CompletableFuture> loadMany(List keys) { + CompletableFuture> result = super.loadMany(keys); + newDataLoaderInvocation(); + return result; + } + + @Override + public CompletableFuture> loadMany(List keys, List keyContexts) { + CompletableFuture> result = super.loadMany(keys, keyContexts); + newDataLoaderInvocation(); + return result; + } + + @Override + public CompletableFuture> loadMany(Map keysAndContexts) { + CompletableFuture> result = super.loadMany(keysAndContexts); + newDataLoaderInvocation(); + return result; + } + + private void newDataLoaderInvocation() { + DataFetchingEnvironmentImpl dfeImpl = (DataFetchingEnvironmentImpl) dfe; + DataFetchingEnvironmentImpl.DFEInternalState dfeInternalState = (DataFetchingEnvironmentImpl.DFEInternalState) dfeImpl.toInternal(); + if (dfeInternalState.getDataLoaderDispatchStrategy() instanceof PerLevelDataLoaderDispatchStrategy) { + AlternativeCallContext alternativeCallContext = dfeInternalState.getDeferredCallContext(); + int level = dfeImpl.getLevel(); + ((PerLevelDataLoaderDispatchStrategy) dfeInternalState.dataLoaderDispatchStrategy).newDataLoaderInvocation(level, delegate, alternativeCallContext); + } else if (dfeInternalState.getDataLoaderDispatchStrategy() instanceof ExhaustedDataLoaderDispatchStrategy) { + AlternativeCallContext alternativeCallContext = dfeInternalState.getDeferredCallContext(); + ((ExhaustedDataLoaderDispatchStrategy) dfeInternalState.dataLoaderDispatchStrategy).newDataLoaderInvocation(alternativeCallContext); + } + } + + +} diff --git a/src/main/java/graphql/schema/DefaultGraphqlTypeComparatorRegistry.java b/src/main/java/graphql/schema/DefaultGraphqlTypeComparatorRegistry.java new file mode 100644 index 0000000000..29e7243c8f --- /dev/null +++ b/src/main/java/graphql/schema/DefaultGraphqlTypeComparatorRegistry.java @@ -0,0 +1,163 @@ +package graphql.schema; + +import com.google.common.collect.ImmutableMap; +import graphql.PublicApi; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.UnaryOperator; + +import static graphql.Assert.assertNotNull; +import static graphql.schema.GraphQLTypeUtil.unwrapAllAs; +import static graphql.schema.GraphqlTypeComparatorEnvironment.newEnvironment; + +/** + * Associates a {@code Comparator} with a {@code GraphqlTypeComparatorEnvironment} to control the scope in which the {@code Comparator} can be applied. + */ +@PublicApi +public class DefaultGraphqlTypeComparatorRegistry implements GraphqlTypeComparatorRegistry { + + // This sensible order was taken from the original SchemaPrinter code. It ordered the types in this manner + private static final ImmutableMap, Integer> SENSIBLE_ORDER = + ImmutableMap., Integer>builder() + .put(GraphQLDirective.class, 1) + .put(GraphQLInterfaceType.class, 2) + .put(GraphQLUnionType.class, 3) + .put(GraphQLObjectType.class, 4) + .put(GraphQLEnumType.class, 5) + .put(GraphQLScalarType.class, 6) + .put(GraphQLInputObjectType.class, 7) + .build(); + + /** + * This orders the schema into a sensible grouped order + * + * @return a comparator that allows for sensible grouped order + */ + public static Comparator sensibleGroupedOrder() { + return (o1, o2) -> { + o1 = unwrapElement(o1); + o2 = unwrapElement(o2); + int i1 = SENSIBLE_ORDER.getOrDefault(o1.getClass(), 0); + int i2 = SENSIBLE_ORDER.getOrDefault(o2.getClass(), 0); + int rc = i1 - i2; + if (rc == 0) { + rc = compareByName(o1, o2); + } + return rc; + }; + } + + private static GraphQLSchemaElement unwrapElement(GraphQLSchemaElement element) { + if (element instanceof GraphQLType) { + GraphQLType castElement = (GraphQLType) element; + // We need to unwrap as GraphQLType to support GraphQLTypeReferences which is not an GraphQLUnmodifiedType + // as returned by unwrapAll. + castElement = unwrapAllAs(castElement); + element = castElement; + } + return element; + } + + private static int compareByName(GraphQLSchemaElement o1, GraphQLSchemaElement o2) { + return Comparator.comparing(element -> { + if (element instanceof GraphQLType) { + element = unwrapElement((GraphQLType) element); + } + if (element instanceof GraphQLNamedSchemaElement) { + return ((GraphQLNamedSchemaElement) element).getName(); + } else { + return Objects.toString(element); + } + }).compare(o1, o2); + } + + public static final Comparator DEFAULT_COMPARATOR = sensibleGroupedOrder(); + + private Map> registry = new HashMap<>(); + + private DefaultGraphqlTypeComparatorRegistry() { + } + + private DefaultGraphqlTypeComparatorRegistry(Map> registry) { + this.registry = registry; + } + + /** + * Search for the most to least specific registered {@code Comparator} otherwise a default is returned. + */ + @Override + public Comparator getComparator(GraphqlTypeComparatorEnvironment environment) { + Comparator comparator = registry.get(environment); + if (comparator != null) { + //noinspection unchecked + return (Comparator) comparator; + } + comparator = registry.get(environment.transform(builder -> builder.parentType(null))); + if (comparator != null) { + //noinspection unchecked + return (Comparator) comparator; + } + return DEFAULT_COMPARATOR; + } + + /** + * @return A registry where all {@code GraphQLType}s receive a default {@code Comparator} by comparing {@code GraphQLType::getName}. + */ + public static GraphqlTypeComparatorRegistry defaultComparators() { + return new DefaultGraphqlTypeComparatorRegistry(); + } + + public static Builder newComparators() { + return new Builder(); + } + + public static class Builder { + + private final Map> registry = new HashMap<>(); + + /** + * Registers a {@code Comparator} with an environment to control its permitted scope of operation. + * + * @param environment Defines the scope to control where the {@code Comparator} can be applied. + * @param comparatorClass The {@code Comparator} class for added type safety. It should match {@code environment.elementType}. + * @param comparator The {@code Comparator} of type {@code comparatorClass}. + * @param The specific {@code GraphQLType} the {@code Comparator} should operate on. + * + * @return The {@code Builder} instance to allow chaining. + */ + public Builder addComparator(GraphqlTypeComparatorEnvironment environment, Class comparatorClass, Comparator comparator) { + assertNotNull(environment, "environment can't be null"); + assertNotNull(comparatorClass, "comparatorClass can't be null"); + assertNotNull(comparator, "comparator can't be null"); + registry.put(environment, comparator); + return this; + } + + /** + * Convenience method which supplies an environment builder function. + * + * @param builderFunction the function which is given a builder + * @param comparatorClass The {@code Comparator} class for added type safety. It should match {@code environment.elementType}. + * @param comparator The {@code Comparator} of type {@code comparatorClass}. + * @param the graphql type + * + * @return this builder + * + * @see #addComparator + */ + public Builder addComparator(UnaryOperator builderFunction, + Class comparatorClass, Comparator comparator) { + assertNotNull(builderFunction, "builderFunction can't be null"); + + GraphqlTypeComparatorEnvironment environment = builderFunction.apply(newEnvironment()).build(); + return addComparator(environment, comparatorClass, comparator); + } + + public DefaultGraphqlTypeComparatorRegistry build() { + return new DefaultGraphqlTypeComparatorRegistry(registry); + } + } +} diff --git a/src/main/java/graphql/schema/DelegatingDataFetchingEnvironment.java b/src/main/java/graphql/schema/DelegatingDataFetchingEnvironment.java new file mode 100644 index 0000000000..91bc2fe351 --- /dev/null +++ b/src/main/java/graphql/schema/DelegatingDataFetchingEnvironment.java @@ -0,0 +1,184 @@ +package graphql.schema; + +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.execution.ExecutionId; +import graphql.execution.ExecutionStepInfo; +import graphql.execution.MergedField; +import graphql.execution.directives.QueryDirectives; +import graphql.language.Document; +import graphql.language.Field; +import graphql.language.FragmentDefinition; +import graphql.language.OperationDefinition; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderRegistry; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.Locale; +import java.util.Map; + + +/** + * DelegatingDataFetchingEnvironment implements {@link graphql.schema.DataFetchingEnvironment} by delegating + * to an underlying instance. You can use this class to wrap the environment and perhaps change + * values and behavior more easily. + */ +@SuppressWarnings("TypeParameterUnusedInFormals") +@PublicApi +public class DelegatingDataFetchingEnvironment implements DataFetchingEnvironment { + + protected final DataFetchingEnvironment delegateEnvironment; + + /** + * Called to wrap an existing {@link graphql.schema.DataFetchingEnvironment}. + * + * @param delegateEnvironment the environment to wrap and delegate all method called to + */ + public DelegatingDataFetchingEnvironment(DataFetchingEnvironment delegateEnvironment) { + this.delegateEnvironment = delegateEnvironment; + } + + @Override + public T getSource() { + return delegateEnvironment.getSource(); + } + + @Override + public Map getArguments() { + return delegateEnvironment.getArguments(); + } + + @Override + public boolean containsArgument(String name) { + return delegateEnvironment.containsArgument(name); + } + + @Override + public T getArgument(String name) { + return delegateEnvironment.getArgument(name); + } + + @Override + public T getArgumentOrDefault(String name, T defaultValue) { + return delegateEnvironment.getArgumentOrDefault(name, defaultValue); + } + + @Deprecated(since = "2022-04-17") + @Override + public T getContext() { + return delegateEnvironment.getContext(); + } + + @Override + public @NonNull GraphQLContext getGraphQlContext() { + return delegateEnvironment.getGraphQlContext(); + } + + @Override + public @Nullable T getLocalContext() { + return delegateEnvironment.getLocalContext(); + } + + @Override + public T getRoot() { + return delegateEnvironment.getRoot(); + } + + @Override + public GraphQLFieldDefinition getFieldDefinition() { + return delegateEnvironment.getFieldDefinition(); + } + + @Deprecated(since = "2019-10-07") + @Override + public List getFields() { + return delegateEnvironment.getFields(); + } + + @Override + public MergedField getMergedField() { + return delegateEnvironment.getMergedField(); + } + + @Override + public Field getField() { + return delegateEnvironment.getField(); + } + + @Override + public GraphQLOutputType getFieldType() { + return delegateEnvironment.getFieldType(); + } + + @Override + public ExecutionStepInfo getExecutionStepInfo() { + return delegateEnvironment.getExecutionStepInfo(); + } + + @Override + public GraphQLType getParentType() { + return delegateEnvironment.getParentType(); + } + + @Override + public GraphQLSchema getGraphQLSchema() { + return delegateEnvironment.getGraphQLSchema(); + } + + @Override + public Map getFragmentsByName() { + return delegateEnvironment.getFragmentsByName(); + } + + @Override + public ExecutionId getExecutionId() { + return delegateEnvironment.getExecutionId(); + } + + @Override + public DataFetchingFieldSelectionSet getSelectionSet() { + return delegateEnvironment.getSelectionSet(); + } + + @Override + public QueryDirectives getQueryDirectives() { + return delegateEnvironment.getQueryDirectives(); + } + + @Override + public @Nullable DataLoader getDataLoader(String dataLoaderName) { + return delegateEnvironment.getDataLoader(dataLoaderName); + } + + @Override + public DataLoaderRegistry getDataLoaderRegistry() { + return delegateEnvironment.getDataLoaderRegistry(); + } + + @Override + public Locale getLocale() { + return delegateEnvironment.getLocale(); + } + + @Override + public OperationDefinition getOperationDefinition() { + return delegateEnvironment.getOperationDefinition(); + } + + @Override + public Document getDocument() { + return delegateEnvironment.getDocument(); + } + + @Override + public Map getVariables() { + return delegateEnvironment.getVariables(); + } + + @Override + public Object toInternal() { + return delegateEnvironment.toInternal(); + } +} diff --git a/src/main/java/graphql/schema/FieldCoordinates.java b/src/main/java/graphql/schema/FieldCoordinates.java new file mode 100644 index 0000000000..a8a048a72f --- /dev/null +++ b/src/main/java/graphql/schema/FieldCoordinates.java @@ -0,0 +1,131 @@ +package graphql.schema; + +import graphql.AssertException; +import graphql.PublicApi; + +import java.util.Objects; + +import static graphql.Assert.assertTrue; +import static graphql.Assert.assertValidName; + +/** + * A field in graphql is uniquely located within a parent type and hence code elements + * like {@link graphql.schema.DataFetcher} need to be specified using those coordinates. + */ +@PublicApi +public class FieldCoordinates { + + private final boolean systemCoordinates; + private final String typeName; + private final String fieldName; + + private FieldCoordinates(String typeName, String fieldName, boolean systemCoordinates) { + this.typeName = typeName; + this.fieldName = fieldName; + this.systemCoordinates = systemCoordinates; + } + + public String getTypeName() { + return typeName; + } + + public String getFieldName() { + return fieldName; + } + + public boolean isSystemCoordinates() { + return systemCoordinates; + } + + /** + * Checks the validity of the field coordinate names. The validity checks vary by coordinate type. Standard + * coordinates validate both the {@code typeName} and {@code fieldName}, while system coordinates do not have + * a parent so they only validate the {@code fieldName}. + * + * @throws AssertException if the coordinates are NOT valid; otherwise, returns normally. + */ + public void assertValidNames() throws AssertException { + if (systemCoordinates) { + assertTrue((null != fieldName) && + fieldName.startsWith("__"), () -> "Only __ system fields can be addressed without a parent type"); + assertValidName(fieldName); + } else { + assertValidName(typeName); + assertValidName(fieldName); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FieldCoordinates that = (FieldCoordinates) o; + return Objects.equals(typeName, that.typeName) && + Objects.equals(fieldName, that.fieldName); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + Objects.hashCode(typeName); + result = 31 * result + Objects.hashCode(fieldName); + return result; + } + + @Override + public String toString() { + return typeName + '.' + fieldName; + } + + /** + * Creates new field coordinates + * + * @param parentType the container of the field + * @param fieldDefinition the field definition + * + * @return new field coordinates represented by the two parameters + */ + public static FieldCoordinates coordinates(GraphQLFieldsContainer parentType, GraphQLFieldDefinition fieldDefinition) { + return new FieldCoordinates(parentType.getName(), fieldDefinition.getName(), false); + } + + /** + * Creates new field coordinates + * + * @param parentType the container of the field + * @param fieldName the field name + * + * @return new field coordinates represented by the two parameters + */ + public static FieldCoordinates coordinates(String parentType, String fieldName) { + return new FieldCoordinates(parentType, fieldName, false); + } + + /** + * Creates new field coordinates + * + * @param parentType the container of the field + * @param fieldName the field name + * + * @return new field coordinates represented by the two parameters + */ + public static FieldCoordinates coordinates(GraphQLFieldsContainer parentType, String fieldName) { + return coordinates(parentType.getName(), fieldName); + } + + /** + * The exception to the general rule is the system __xxxx Introspection fields which have no parent type and + * are able to be specified on any type + * + * @param fieldName the name of the system field which MUST start with __ + * + * @return the coordinates + */ + public static FieldCoordinates systemCoordinates(String fieldName) { + return new FieldCoordinates(null, fieldName, true); + } +} diff --git a/src/main/java/graphql/schema/GraphQLAppliedDirective.java b/src/main/java/graphql/schema/GraphQLAppliedDirective.java new file mode 100644 index 0000000000..ca270fa0fd --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLAppliedDirective.java @@ -0,0 +1,235 @@ +package graphql.schema; + + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.language.Directive; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertValidName; +import static graphql.util.FpKit.getByName; + +/** + * An applied directive represents the instance of a directive that is applied to a schema element, + * as opposed to it definition + *

+ * A directive has a definition, that is what arguments it takes, and it can also be applied + * to other schema elements. Originally graphql-java re-used the {@link GraphQLDirective} and {@link GraphQLArgument} + * classes to do both purposes. This was a modelling mistake. New {@link GraphQLAppliedDirective} and {@link GraphQLAppliedDirectiveArgument} + * classes have been introduced to better model when a directive is applied to a schema element, + * as opposed to its schema definition itself. + *

+ * See https://graphql.org/learn/queries/#directives for more details on the concept. + */ +@PublicApi +public class GraphQLAppliedDirective implements GraphQLNamedSchemaElement { + + private final String name; + private final ImmutableList arguments; + private final Directive definition; + + public static final String CHILD_ARGUMENTS = "arguments"; + + private GraphQLAppliedDirective(String name, Directive definition, List arguments) { + assertValidName(name); + assertNotNull(arguments, "arguments can't be null"); + this.name = name; + this.arguments = ImmutableList.copyOf(arguments); + this.definition = definition; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return null; + } + + public List getArguments() { + return arguments; + } + + public GraphQLAppliedDirectiveArgument getArgument(String name) { + for (GraphQLAppliedDirectiveArgument argument : arguments) { + if (argument.getName().equals(name)) { + return argument; + } + } + return null; + } + + public Directive getDefinition() { + return definition; + } + + @Override + public String toString() { + return new StringJoiner(", ", GraphQLAppliedDirective.class.getSimpleName() + "[", "]") + .add("name='" + name + "'") + .add("arguments=" + arguments) + .add("definition=" + definition) + .toString(); + } + + /** + * This helps you transform the current GraphQLDirective into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new field based on calling build on that builder + */ + public GraphQLAppliedDirective transform(Consumer builderConsumer) { + Builder builder = newDirective(this); + builderConsumer.accept(builder); + return builder.build(); + } + + @Override + public GraphQLSchemaElement copy() { + return newDirective(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLAppliedDirective(this, context); + } + + @Override + public List getChildren() { + return ImmutableList.copyOf(arguments); + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_ARGUMENTS, arguments) + .build(); + } + + @Override + public GraphQLAppliedDirective withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceArguments(newChildren.getChildren(CHILD_ARGUMENTS)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + + public static Builder newDirective() { + return new Builder(); + } + + public static Builder newDirective(GraphQLAppliedDirective existing) { + return new Builder(existing); + } + + public static class Builder extends GraphqlTypeBuilder { + + private final Map arguments = new LinkedHashMap<>(); + private Directive definition; + + public Builder() { + } + + public Builder(GraphQLAppliedDirective existing) { + this.name = existing.getName(); + this.description = existing.getDescription(); + this.arguments.putAll(getByName(existing.getArguments(), GraphQLAppliedDirectiveArgument::getName)); + } + + public Builder argument(GraphQLAppliedDirectiveArgument argument) { + assertNotNull(argument, "argument must not be null"); + arguments.put(argument.getName(), argument); + return this; + } + + public Builder replaceArguments(List arguments) { + assertNotNull(arguments, "arguments must not be null"); + this.arguments.clear(); + for (GraphQLAppliedDirectiveArgument argument : arguments) { + this.arguments.put(argument.getName(), argument); + } + return this; + } + + /** + * Take an argument builder in a function definition and apply. Can be used in a jdk8 lambda + * e.g.: + *

+         *     {@code
+         *      argument(a -> a.name("argumentName"))
+         *     }
+         * 
+ * + * @param builderFunction a supplier for the builder impl + * + * @return this + */ + public Builder argument(UnaryOperator builderFunction) { + GraphQLAppliedDirectiveArgument.Builder builder = GraphQLAppliedDirectiveArgument.newArgument(); + builder = builderFunction.apply(builder); + return argument(builder); + } + + /** + * Same effect as the argument(GraphQLAppliedDirectiveArgument). Builder.build() is called + * from within + * + * @param builder an un-built/incomplete GraphQLAppliedDirectiveArgument + * + * @return this + */ + public Builder argument(GraphQLAppliedDirectiveArgument.Builder builder) { + return argument(builder.build()); + } + + /** + * This is used to clear all the arguments in the builder so far. + * + * @return the builder + */ + public Builder clearArguments() { + arguments.clear(); + return this; + } + + + public Builder definition(Directive definition) { + this.definition = definition; + return this; + } + + public GraphQLAppliedDirective build() { + return new GraphQLAppliedDirective(name, this.definition, sort(arguments, GraphQLAppliedDirective.class, GraphQLAppliedDirectiveArgument.class)); + } + } +} diff --git a/src/main/java/graphql/schema/GraphQLAppliedDirectiveArgument.java b/src/main/java/graphql/schema/GraphQLAppliedDirectiveArgument.java new file mode 100644 index 0000000000..4446894ec9 --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLAppliedDirectiveArgument.java @@ -0,0 +1,262 @@ +package graphql.schema; + + +import graphql.Assert; +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.language.Argument; +import graphql.language.Value; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertValidName; +import static graphql.execution.ValuesResolver.getInputValueImpl; + +/** + * This represents the argument values that can be placed on an {@link GraphQLAppliedDirective}. + *

+ * You can think of them as 'instances' of {@link GraphQLArgument}, when applied to a directive on a schema element + */ +@PublicApi +public class GraphQLAppliedDirectiveArgument implements GraphQLNamedSchemaElement, GraphQLInputSchemaElement { + + private final String name; + private final InputValueWithState value; + private final GraphQLInputType originalType; + private GraphQLInputType replacedType; + + private final Argument definition; + + + public static final String CHILD_TYPE = "type"; + + private GraphQLAppliedDirectiveArgument(String name, + InputValueWithState value, + GraphQLInputType type, + Argument definition + ) { + assertValidName(name); + this.name = name; + this.value = assertNotNull(value); + this.originalType = assertNotNull(type); + this.definition = definition; + } + + @Override + public String getName() { + return name; + } + + public GraphQLInputType getType() { + return replacedType != null ? replacedType : originalType; + } + + void replaceType(GraphQLInputType type) { + this.replacedType = type; + } + + public boolean hasSetValue() { + return value.isSet(); + } + + /** + * @return an input value with state for an applied directive argument + */ + public @NonNull InputValueWithState getArgumentValue() { + return value; + } + + /** + * This will give out an internal java value based on the semantics captured + * in the {@link InputValueWithState} from {@link GraphQLAppliedDirectiveArgument#getArgumentValue()} + * + * Note : You MUST only call this on a {@link GraphQLAppliedDirectiveArgument} that is part of a fully formed schema. We need + * all the types to be resolved in order for this work correctly. + * + * Note: This method will return null if the value is not set or explicitly set to null. If you want to know the difference + * when "not set" and "set to null" then you can't use this method. Rather you should use {@link GraphQLAppliedDirectiveArgument#getArgumentValue()} + * and use the {@link InputValueWithState#isNotSet()} methods to decide how to handle those values. + * + * @param the type you want it cast as + * + * @return a value of type T which is the java value of the argument + */ + public T getValue() { + return getInputValueImpl(getType(), value, GraphQLContext.getDefault(), Locale.getDefault()); + } + + /** + * This will always be null. Applied arguments have no description + * + * @return always null + */ + public @Nullable String getDescription() { + return null; + } + + public Argument getDefinition() { + return definition; + } + + @Override + public List getChildren() { + List children = new ArrayList<>(); + children.add(getType()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .child(CHILD_TYPE, originalType) + .build(); + } + + @Override + public GraphQLAppliedDirectiveArgument withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.type(newChildren.getChildOrNull(CHILD_TYPE)) + ); + } + + @Override + public GraphQLSchemaElement copy() { + return newArgument(this).build(); + } + + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + + /** + * This helps you transform the current GraphQLArgument into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new field based on calling build on that builder + */ + public GraphQLAppliedDirectiveArgument transform(Consumer builderConsumer) { + Builder builder = newArgument(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public static Builder newArgument() { + return new Builder(); + } + + public static Builder newArgument(GraphQLAppliedDirectiveArgument existing) { + return new Builder(existing); + } + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLAppliedDirectiveArgument(this, context); + } + + @Override + public String toString() { + return "GraphQLAppliedDirectiveArgument{" + + "name='" + name + '\'' + + ", type=" + getType() + + ", value=" + value + + '}'; + } + + public static class Builder extends GraphqlTypeBuilder { + + private InputValueWithState value = InputValueWithState.NOT_SET; + private Argument definition; + private GraphQLInputType type; + + public Builder() { + } + + public Builder(GraphQLAppliedDirectiveArgument existing) { + this.name = existing.getName(); + this.value = existing.getArgumentValue(); + this.type = existing.getType(); + } + + public Builder type(GraphQLInputType type) { + this.type = assertNotNull(type); + return this; + } + + public Builder definition(Argument definition) { + this.definition = definition; + return this; + } + + /** + * Sets a literal AST value as the arguments value + * + * @param value can't be null as a `null` is represented a @{@link graphql.language.NullValue} Literal + * + * @return this builder + */ + public Builder valueLiteral(@NonNull Value value) { + this.value = InputValueWithState.newLiteralValue(value); + return this; + } + + /** + * @param value values can be null to represent null value + * + * @return this builder + */ + public Builder valueProgrammatic(@Nullable Object value) { + this.value = InputValueWithState.newExternalValue(value); + return this; + } + + public Builder inputValueWithState(@NonNull InputValueWithState value) { + this.value = Assert.assertNotNull(value); + return this; + } + + /** + * Removes the value to represent a missing value (which is different from null) + * + * @return this builder + */ + public Builder clearValue() { + this.value = InputValueWithState.NOT_SET; + return this; + } + + + public GraphQLAppliedDirectiveArgument build() { + + return new GraphQLAppliedDirectiveArgument( + name, + value, + type, + definition + ); + } + } +} diff --git a/src/main/java/graphql/schema/GraphQLArgument.java b/src/main/java/graphql/schema/GraphQLArgument.java index 95495fb8d7..924cdf1198 100644 --- a/src/main/java/graphql/schema/GraphQLArgument.java +++ b/src/main/java/graphql/schema/GraphQLArgument.java @@ -1,78 +1,93 @@ package graphql.schema; +import graphql.DirectivesUtil; +import graphql.GraphQLContext; import graphql.PublicApi; import graphql.language.InputValueDefinition; -import graphql.util.FpKit; +import graphql.language.Value; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; -import static graphql.util.FpKit.valuesToList; +import static graphql.execution.ValuesResolver.getInputValueImpl; /** - * This defines an argument that can be supplied to a graphql field (via {@link graphql.schema.GraphQLFieldDefinition}. - * + * This defines an argument that can be supplied to a graphql field (via {@link GraphQLFieldDefinition}. + *

* Fields can be thought of as "functions" that take arguments and return a value. - * - * See http://graphql.org/learn/queries/#arguments for more details on the concept. - * - * {@link graphql.schema.GraphQLArgument} is used in two contexts, one context is graphql queries where it represents the arguments that can be + *

+ * See https://graphql.org/learn/queries/#arguments for more details on the concept. + *

+ * {@link GraphQLArgument} is used in two contexts, one context is graphql queries where it represents the arguments that can be * set on a field and the other is in Schema Definition Language (SDL) where it can be used to represent the argument value instances - * that have been supplied on a {@link graphql.schema.GraphQLDirective}. - * + * that have been supplied on a {@link GraphQLDirective}. + *

* The difference is the 'value' and 'defaultValue' properties. In a query argument, the 'value' is never in the GraphQLArgument * object but rather in the AST direct or in the query variables map and the 'defaultValue' represents a value to use if both of these are * not present. You can think of them like a descriptor of what shape an argument might have. - * - * However with directives on SDL elements, the value is specified in AST only and transferred into the GraphQLArgument object and the + *

+ * However, with directives on SDL elements, the value is specified in AST only and transferred into the GraphQLArgument object and the * 'defaultValue' comes instead from the directive definition elsewhere in the SDL. You can think of them as 'instances' of arguments, their shape and their * specific value on that directive. + *

+ * Originally graphql-java re-used the {@link GraphQLDirective} and {@link GraphQLArgument} + * classes to do both purposes. This was a modelling mistake. New {@link GraphQLAppliedDirective} and {@link GraphQLAppliedDirectiveArgument} + * classes have been introduced to better model when a directive is applied to a schema element, + * as opposed to its schema definition itself. */ @PublicApi -public class GraphQLArgument implements GraphQLDirectiveContainer { +public class GraphQLArgument implements GraphQLNamedSchemaElement, GraphQLInputValueDefinition { private final String name; private final String description; - private GraphQLInputType type; - private final Object value; - private final Object defaultValue; + private final String deprecationReason; + private final GraphQLInputType originalType; + private GraphQLInputType replacedType; + + private final InputValueWithState defaultValue; + private final InputValueWithState value; + private final InputValueDefinition definition; - private final List directives; + private final DirectivesUtil.DirectivesHolder directivesHolder; - public GraphQLArgument(String name, String description, GraphQLInputType type, Object defaultValue) { - this(name, description, type, defaultValue, null); - } - public GraphQLArgument(String name, GraphQLInputType type) { - this(name, null, type, null, null); - } + public static final String CHILD_TYPE = "type"; - public GraphQLArgument(String name, String description, GraphQLInputType type, Object defaultValue, InputValueDefinition definition) { - this(name, description, type, defaultValue, null, definition, Collections.emptyList()); - } - private GraphQLArgument(String name, String description, GraphQLInputType type, Object defaultValue, Object value, InputValueDefinition definition, List directives) { + private GraphQLArgument(String name, + String description, + GraphQLInputType type, + InputValueWithState defaultValue, + InputValueWithState value, + InputValueDefinition definition, + List directives, + List appliedDirectives, + String deprecationReason) { assertValidName(name); assertNotNull(type, "type can't be null"); this.name = name; this.description = description; - this.type = type; + this.originalType = type; this.defaultValue = defaultValue; this.value = value; this.definition = definition; - this.directives = directives; + this.deprecationReason = deprecationReason; + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); } - void replaceTypeReferences(Map typeMap) { - type = (GraphQLInputType) new SchemaUtil().resolveTypeReference(type, typeMap); + void replaceType(GraphQLInputType type) { + this.replacedType = type; } @Override @@ -81,43 +96,184 @@ public String getName() { } public GraphQLInputType getType() { - return type; + return replacedType != null ? replacedType : originalType; } /** - * An argument has a default value when it represents the logical argument structure that a {@link graphql.schema.GraphQLFieldDefinition} - * can have and it can also have a default value when used in a schema definition language (SDL) where the - * default value comes via the directive definition. + * The default value of this argument. * - * @return the default value of an argument + * @return a {@link InputValueWithState} that represents the arguments default value */ - public Object getDefaultValue() { + public @NonNull InputValueWithState getArgumentDefaultValue() { return defaultValue; } + public boolean hasSetDefaultValue() { + return defaultValue.isSet(); + } + + public boolean hasSetValue() { + return value.isSet(); + } + + /** - * An argument ONLY has a value when its used in a schema definition language (SDL) context as the arguments to SDL directives. The method - * should not be called in a query context, but rather the AST / variables map should be used to obtain an arguments value. + * This is only used for applied directives, that is when this argument is on a {@link GraphQLDirective} applied to a schema or query element * - * @return the argument value + * @return an input value with state for an applied directive + * + * @deprecated use {@link GraphQLAppliedDirectiveArgument} instead */ - public Object getValue() { + @Deprecated(since = "2022-02-24") + public @NonNull InputValueWithState getArgumentValue() { return value; } + /** + * This static helper method will give out a java value based on the semantics captured + * in the {@link InputValueWithState} from {@link GraphQLArgument#getArgumentValue()} + * + * Note : You MUST only call this on a {@link GraphQLArgument} that is part of a fully formed schema. We need + * all of the types to be resolved in order for this work correctly. + * + * Note: This method will return null if the value is not set or explicitly set to null. If you you to know the difference + * when "not set" and "set to null" then you cant use this method. Rather you should use {@link GraphQLArgument#getArgumentValue()} + * and use the {@link InputValueWithState#isNotSet()} methods to decide how to handle those values. + * + * @param argument the fully formed {@link GraphQLArgument} + * @param the type you want it cast as + * + * @return a value of type T which is the java value of the argument + * + * @deprecated use {@link GraphQLAppliedDirectiveArgument} instead + */ + @Deprecated(since = "2022-02-24") + public static T getArgumentValue(GraphQLArgument argument) { + return getInputValueImpl(argument.getType(), argument.getArgumentValue(), GraphQLContext.getDefault(), Locale.getDefault()); + } + + /** + * This static helper method will give out a java value based on the semantics captured + * in the {@link InputValueWithState} from {@link GraphQLArgument#getArgumentDefaultValue()} + * + * Note : You MUST only call this on a {@link GraphQLArgument} that is part of a fully formed schema. We need + * all of the types to be resolved in order for this work correctly. + * + * Note: This method will return null if the value is not set or explicitly set to null. If you you to know the difference + * when "not set" and "set to null" then you cant use this method. Rather you should use {@link GraphQLArgument#getArgumentDefaultValue()} + * and use the {@link InputValueWithState#isNotSet()} methods to decide how to handle those values. + * + * @param argument the fully formed {@link GraphQLArgument} + * @param the type you want it cast as + * + * @return a value of type T which is the java value of the argument default + */ + public static T getArgumentDefaultValue(GraphQLArgument argument) { + return getInputValueImpl(argument.getType(), argument.getArgumentDefaultValue(), GraphQLContext.getDefault(), Locale.getDefault()); + } + public String getDescription() { return description; } + public String getDeprecationReason() { + return deprecationReason; + } + + public boolean isDeprecated() { + return deprecationReason != null; + } + public InputValueDefinition getDefinition() { return definition; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); } + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(); + children.add(getType()); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .child(CHILD_TYPE, originalType) + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLArgument withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.type(newChildren.getChildOrNull(CHILD_TYPE)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + @Override + public GraphQLSchemaElement copy() { + return newArgument(this).build(); + } + + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + /** * This helps you transform the current GraphQLArgument into another one by starting a builder with all * the current values and allows you to transform it how you want. @@ -140,91 +296,223 @@ public static Builder newArgument(GraphQLArgument existing) { return new Builder(existing); } - public static class Builder { + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLArgument(this, context); + } + + @Override + public String toString() { + return "GraphQLArgument{" + + "name='" + name + '\'' + + ", value=" + value + + ", defaultValue=" + defaultValue + + ", type=" + getType() + + '}'; + } + + /** + * This method can be used to turn an argument that was being use as an applied argument into one. + * + * @return an {@link GraphQLAppliedDirectiveArgument} + */ + public GraphQLAppliedDirectiveArgument toAppliedArgument() { + return GraphQLAppliedDirectiveArgument.newArgument() + .name(name) + .type(getType()) + .inputValueWithState(value) + .build(); + } + + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { - private String name; private GraphQLInputType type; - private Object defaultValue; - private Object value; - private String description; + private InputValueWithState defaultValue = InputValueWithState.NOT_SET; + private InputValueWithState value = InputValueWithState.NOT_SET; + private String deprecationReason; private InputValueDefinition definition; - private final Map directives = new LinkedHashMap<>(); + public Builder() { } public Builder(GraphQLArgument existing) { this.name = existing.getName(); - this.type = existing.getType(); - this.value = existing.getValue(); - this.defaultValue = existing.getDefaultValue(); + this.type = existing.originalType; + this.value = existing.getArgumentValue(); + this.defaultValue = existing.defaultValue; this.description = existing.getDescription(); this.definition = existing.getDefinition(); - this.directives.putAll(FpKit.getByName(existing.getDirectives(), GraphQLDirective::getName)); + this.deprecationReason = existing.deprecationReason; + copyExistingDirectives(existing); } - public Builder name(String name) { - this.name = name; + public Builder definition(InputValueDefinition definition) { + this.definition = definition; return this; } - public Builder description(String description) { - this.description = description; + public Builder deprecate(String deprecationReason) { + this.deprecationReason = deprecationReason; return this; } - public Builder definition(InputValueDefinition definition) { - this.definition = definition; + public Builder type(GraphQLInputType type) { + this.type = type; return this; } + /** + * A legacy method that sets a default value into the argument + * + * @param defaultValue a default value + * + * @return this builder + * + * @deprecated use {@link #defaultValueLiteral(Value)} or {@link #defaultValueProgrammatic(Object)} + */ + @Deprecated(since = "2021-05-10") + public Builder defaultValue(Object defaultValue) { + this.defaultValue = InputValueWithState.newInternalValue(defaultValue); + return this; + } - public Builder type(GraphQLInputType type) { - this.type = type; + /** + * @param defaultValue can't be null as a `null` is represented a @{@link graphql.language.NullValue} Literal + * + * @return this builder + */ + public Builder defaultValueLiteral(@NonNull Value defaultValue) { + this.defaultValue = InputValueWithState.newLiteralValue(defaultValue); return this; } - public Builder defaultValue(Object defaultValue) { - this.defaultValue = defaultValue; + /** + * @param defaultValue Can be null to represent null value + * + * @return this builder + */ + public Builder defaultValueProgrammatic(@Nullable Object defaultValue) { + this.defaultValue = InputValueWithState.newExternalValue(defaultValue); return this; } - public Builder value(Object value) { - this.value = value; + /** + * Removes the defaultValue to represent a missing default value (which is different from null) + * + * @return this builder + */ + public Builder clearDefaultValue() { + this.defaultValue = InputValueWithState.NOT_SET; return this; } - public Builder withDirectives(GraphQLDirective... directives) { - assertNotNull(directives, "directives can't be null"); - for (GraphQLDirective directive : directives) { - withDirective(directive); - } + /** + * A legacy method for setting an arguments value + * + * @param value the argument value + * + * @return this builder + * + * @deprecated use {@link #valueLiteral(Value)} or {@link #valueProgrammatic(Object)} + */ + @Deprecated(since = "2021-05-10") + public Builder value(@Nullable Object value) { + this.value = InputValueWithState.newInternalValue(value); return this; } - public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); + /** + * Sets a literal AST value as the arguments value + * + * @param value can't be null as a `null` is represented a @{@link graphql.language.NullValue} Literal + * + * @return this builder + * + * @deprecated use {@link GraphQLAppliedDirectiveArgument} methods instead + */ + @Deprecated(since = "2022-02-24") + public Builder valueLiteral(@NonNull Value value) { + this.value = InputValueWithState.newLiteralValue(value); return this; } - public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + /** + * @param value values can be null to represent null value + * + * @return this builder + * + * @deprecated use {@link GraphQLAppliedDirectiveArgument} methods instead + */ + @Deprecated(since = "2022-02-24") + public Builder valueProgrammatic(@Nullable Object value) { + this.value = InputValueWithState.newExternalValue(value); + return this; } /** - * This is used to clear all the directives in the builder so far. + * Removes the value to represent a missing value (which is different from null) * - * @return the builder + * @return this builder + * + * @deprecated use {@link GraphQLAppliedDirectiveArgument} methods instead */ - public Builder clearDirectives() { - directives.clear(); + @Deprecated(since = "2022-02-24") + public Builder clearValue() { + this.value = InputValueWithState.NOT_SET; return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override + public Builder withDirectives(GraphQLDirective... directives) { + return super.withDirectives(directives); + } + + @Override + public Builder withDirective(GraphQLDirective directive) { + return super.withDirective(directive); + } + + @Override + public Builder withDirective(GraphQLDirective.Builder builder) { + return super.withDirective(builder); + } + + @Override + public Builder clearDirectives() { + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); + } public GraphQLArgument build() { - return new GraphQLArgument(name, description, type, defaultValue, value, definition, valuesToList(directives)); + assertNotNull(type, "type can't be null"); + + return new GraphQLArgument( + name, + description, + type, + defaultValue, + value, + definition, + sort(directives, GraphQLArgument.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + deprecationReason + ); } } } diff --git a/src/main/java/graphql/schema/GraphQLCodeRegistry.java b/src/main/java/graphql/schema/GraphQLCodeRegistry.java new file mode 100644 index 0000000000..26574b819c --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLCodeRegistry.java @@ -0,0 +1,489 @@ +package graphql.schema; + +import graphql.Assert; +import graphql.Internal; +import graphql.PublicApi; +import graphql.schema.visibility.GraphqlFieldVisibility; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertValidName; +import static graphql.schema.DataFetcherFactoryEnvironment.newDataFetchingFactoryEnvironment; +import static graphql.schema.FieldCoordinates.coordinates; +import static graphql.schema.visibility.DefaultGraphqlFieldVisibility.DEFAULT_FIELD_VISIBILITY; + + +/** + * The {@link graphql.schema.GraphQLCodeRegistry} holds that execution code that is associated with graphql types, namely + * the {@link graphql.schema.DataFetcher}s associated with fields, the {@link graphql.schema.TypeResolver}s associated with + * abstract types and the {@link graphql.schema.visibility.GraphqlFieldVisibility} + *

+ * For legacy reasons these code functions can still exist on the original type objects but this will be removed in a future version. Once + * removed the type system objects will be able have proper hashCode/equals methods and be checked for proper equality. + */ +@PublicApi +public class GraphQLCodeRegistry { + + private final Map> dataFetcherMap; + private final Map> systemDataFetcherMap; + private final Map typeResolverMap; + private final GraphqlFieldVisibility fieldVisibility; + private final DataFetcherFactory defaultDataFetcherFactory; + + private GraphQLCodeRegistry(Builder builder) { + this.dataFetcherMap = builder.dataFetcherMap; + this.systemDataFetcherMap = builder.systemDataFetcherMap; + this.typeResolverMap = builder.typeResolverMap; + this.fieldVisibility = builder.fieldVisibility; + this.defaultDataFetcherFactory = builder.defaultDataFetcherFactory; + } + + /** + * @return the {@link graphql.schema.visibility.GraphqlFieldVisibility} + */ + public GraphqlFieldVisibility getFieldVisibility() { + return fieldVisibility; + } + + /** + * Returns a data fetcher associated with a field within an object type + * + * @param parentType the container type + * @param fieldDefinition the field definition + * + * @return the DataFetcher associated with this field. All fields have data fetchers + */ + public DataFetcher getDataFetcher(GraphQLObjectType parentType, GraphQLFieldDefinition fieldDefinition) { + return getDataFetcherImpl(FieldCoordinates.coordinates(parentType, fieldDefinition), fieldDefinition, dataFetcherMap, systemDataFetcherMap, defaultDataFetcherFactory); + } + + /** + * Returns a data fetcher associated with a field located at specified coordinates. + * + * @param coordinates the field coordinates + * @param fieldDefinition the field definition + * + * @return the DataFetcher associated with this field. All fields have data fetchers + */ + public DataFetcher getDataFetcher(FieldCoordinates coordinates, GraphQLFieldDefinition fieldDefinition) { + return getDataFetcherImpl(coordinates, fieldDefinition, dataFetcherMap, systemDataFetcherMap, defaultDataFetcherFactory); + } + + /** + * Returns true if the code registry contained a data fetcher at the specified co-ordinates + * + * @param coordinates the field coordinates + * + * @return the true if there is a data fetcher at those co-ordinates + */ + public boolean hasDataFetcher(FieldCoordinates coordinates) { + return hasDataFetcherImpl(coordinates, dataFetcherMap, systemDataFetcherMap); + } + + @SuppressWarnings("deprecation") + private static DataFetcher getDataFetcherImpl(FieldCoordinates coordinates, GraphQLFieldDefinition fieldDefinition, Map> dataFetcherMap, Map> systemDataFetcherMap, DataFetcherFactory defaultDataFetcherFactory) { + assertNotNull(coordinates); + assertNotNull(fieldDefinition); + + DataFetcherFactory dataFetcherFactory = systemDataFetcherMap.get(fieldDefinition.getName()); + if (dataFetcherFactory == null) { + dataFetcherFactory = dataFetcherMap.get(coordinates); + if (dataFetcherFactory == null) { + dataFetcherFactory = defaultDataFetcherFactory; + } + } + // call direct from the field - cheaper to not make a new environment object + DataFetcher dataFetcher = dataFetcherFactory.get(fieldDefinition); + if (dataFetcher == null) { + DataFetcherFactoryEnvironment factoryEnvironment = newDataFetchingFactoryEnvironment() + .fieldDefinition(fieldDefinition) + .build(); + dataFetcher = dataFetcherFactory.get(factoryEnvironment); + } + return dataFetcher; + } + + private static boolean hasDataFetcherImpl(FieldCoordinates coords, Map> dataFetcherMap, Map> systemDataFetcherMap) { + assertNotNull(coords); + + DataFetcherFactory dataFetcherFactory = systemDataFetcherMap.get(coords.getFieldName()); + if (dataFetcherFactory == null) { + dataFetcherFactory = dataFetcherMap.get(coords); + } + return dataFetcherFactory != null; + } + + + /** + * Returns the type resolver associated with this interface type + * + * @param interfaceType the interface type + * + * @return a non null {@link graphql.schema.TypeResolver} + */ + public TypeResolver getTypeResolver(GraphQLInterfaceType interfaceType) { + return getTypeResolverForInterface(interfaceType, typeResolverMap); + } + + /** + * Returns the type resolver associated with this union type + * + * @param unionType the union type + * + * @return a non null {@link graphql.schema.TypeResolver} + */ + + public TypeResolver getTypeResolver(GraphQLUnionType unionType) { + return getTypeResolverForUnion(unionType, typeResolverMap); + } + + private static TypeResolver getTypeResolverForInterface(GraphQLInterfaceType parentType, Map typeResolverMap) { + assertNotNull(parentType); + TypeResolver typeResolver = typeResolverMap.get(parentType.getName()); + if (typeResolver == null) { + typeResolver = parentType.getTypeResolver(); + } + return assertNotNull(typeResolver, "There must be a type resolver for interface %s", parentType.getName()); + } + + private static TypeResolver getTypeResolverForUnion(GraphQLUnionType parentType, Map typeResolverMap) { + assertNotNull(parentType); + TypeResolver typeResolver = typeResolverMap.get(parentType.getName()); + if (typeResolver == null) { + typeResolver = parentType.getTypeResolver(); + } + return assertNotNull(typeResolver, "There must be a type resolver for union %s", parentType.getName()); + } + + /** + * This helps you transform the current {@link graphql.schema.GraphQLCodeRegistry} object into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new GraphQLCodeRegistry object based on calling build on that builder + */ + public GraphQLCodeRegistry transform(Consumer builderConsumer) { + Builder builder = newCodeRegistry(this); + builderConsumer.accept(builder); + return builder.build(); + } + + /** + * @return a new builder of {@link graphql.schema.GraphQLCodeRegistry} objects + */ + public static Builder newCodeRegistry() { + return new Builder(); + } + + /** + * Returns a new builder of {@link graphql.schema.GraphQLCodeRegistry} objects based on the existing one + * + * @param existingCodeRegistry the existing code registry to use + * + * @return a new builder of {@link graphql.schema.GraphQLCodeRegistry} objects + */ + public static Builder newCodeRegistry(GraphQLCodeRegistry existingCodeRegistry) { + return new Builder(existingCodeRegistry); + } + + public static class Builder { + private final Map> dataFetcherMap = new LinkedHashMap<>(); + private final Map> systemDataFetcherMap = new LinkedHashMap<>(); + private final Map typeResolverMap = new HashMap<>(); + private GraphqlFieldVisibility fieldVisibility = DEFAULT_FIELD_VISIBILITY; + private DataFetcherFactory defaultDataFetcherFactory = SingletonPropertyDataFetcher.singletonFactory(); + private boolean changed = false; + + private Builder() { + } + + private Builder(GraphQLCodeRegistry codeRegistry) { + this.systemDataFetcherMap.putAll(codeRegistry.systemDataFetcherMap); + this.dataFetcherMap.putAll(codeRegistry.dataFetcherMap); + this.typeResolverMap.putAll(codeRegistry.typeResolverMap); + this.fieldVisibility = codeRegistry.fieldVisibility; + this.defaultDataFetcherFactory = codeRegistry.defaultDataFetcherFactory; + } + + /** + * A helper method to track if the builder changes from the point + * at which this method was called. + * + * @return this builder for fluent code + */ + @Internal + public Builder trackChanges() { + changed = false; + return this; + } + + /** + * @return true if the builder has changed since {@link #trackChanges()} was called + */ + @Internal + public boolean hasChanged() { + return changed; + } + + private Builder markChanged() { + changed = true; + return this; + } + + private Builder markChanged(boolean condition) { + if (condition) { + changed = true; + } + return this; + } + + /** + * Returns a data fetcher associated with a field within an object type + * + * @param parentType the container type + * @param fieldDefinition the field definition + * + * @return the DataFetcher associated with this field. All fields have data fetchers + */ + public DataFetcher getDataFetcher(GraphQLObjectType parentType, GraphQLFieldDefinition fieldDefinition) { + return getDataFetcherImpl(FieldCoordinates.coordinates(parentType, fieldDefinition), fieldDefinition, dataFetcherMap, systemDataFetcherMap, defaultDataFetcherFactory); + } + + /** + * Returns a data fetcher associated with a field located at specified coordinates. + * + * @param coordinates the field coordinates + * @param fieldDefinition the field definition + * + * @return the DataFetcher associated with this field. All fields have data fetchers + */ + public DataFetcher getDataFetcher(FieldCoordinates coordinates, GraphQLFieldDefinition fieldDefinition) { + return getDataFetcherImpl(coordinates, fieldDefinition, dataFetcherMap, systemDataFetcherMap, defaultDataFetcherFactory); + } + + /** + * @return the default data fetcher factory associated with this code registry + */ + public DataFetcherFactory getDefaultDataFetcherFactory() { + return defaultDataFetcherFactory; + } + + /** + * Returns true if the code registry contained a data fetcher at the specified co-ordinates + * + * @param coordinates the field coordinates + * + * @return the true if there is a data fetcher at those co-ordinates + */ + public boolean hasDataFetcher(FieldCoordinates coordinates) { + return hasDataFetcherImpl(coordinates, dataFetcherMap, systemDataFetcherMap); + } + + /** + * Returns the type resolver associated with this interface type + * + * @param interfaceType the interface type + * + * @return a non null {@link graphql.schema.TypeResolver} + */ + public TypeResolver getTypeResolver(GraphQLInterfaceType interfaceType) { + return getTypeResolverForInterface(interfaceType, typeResolverMap); + } + + /** + * Returns true of a type resolver has been registered for this type name + * + * @param typeName the name to check + * + * @return true if there is already a type resolver + */ + public boolean hasTypeResolver(String typeName) { + return typeResolverMap.containsKey(typeName); + } + + /** + * Returns the type resolver associated with this union type + * + * @param unionType the union type + * + * @return a non null {@link graphql.schema.TypeResolver} + */ + public TypeResolver getTypeResolver(GraphQLUnionType unionType) { + return getTypeResolverForUnion(unionType, typeResolverMap); + } + + /** + * Sets the data fetcher for a specific field inside a container type + * + * @param coordinates the field coordinates + * @param dataFetcher the data fetcher code for that field + * + * @return this builder + */ + public Builder dataFetcher(FieldCoordinates coordinates, DataFetcher dataFetcher) { + assertNotNull(dataFetcher); + return dataFetcher(assertNotNull(coordinates), DataFetcherFactories.useDataFetcher(dataFetcher)); + } + + /** + * Sets the data fetcher for a specific field inside an object type + * + * @param parentType the object type + * @param fieldDefinition the field definition + * @param dataFetcher the data fetcher code for that field + * + * @return this builder + */ + public Builder dataFetcher(GraphQLObjectType parentType, GraphQLFieldDefinition fieldDefinition, DataFetcher dataFetcher) { + return dataFetcher(FieldCoordinates.coordinates(parentType.getName(), fieldDefinition.getName()), dataFetcher); + } + + /** + * Called to place system data fetchers (eg Introspection fields) into the mix + * + * @param coordinates the field coordinates + * @param dataFetcher the data fetcher code for that field + * + * @return this builder + */ + public Builder systemDataFetcher(FieldCoordinates coordinates, DataFetcher dataFetcher) { + assertNotNull(dataFetcher); + assertNotNull(coordinates); + coordinates.assertValidNames(); + systemDataFetcherMap.put(coordinates.getFieldName(), DataFetcherFactories.useDataFetcher(dataFetcher)); + return markChanged(); + } + + /** + * Sets the data fetcher factory for a specific field inside a container type + * + * @param coordinates the field coordinates + * @param dataFetcherFactory the data fetcher factory code for that field + * + * @return this builder + */ + public Builder dataFetcher(FieldCoordinates coordinates, DataFetcherFactory dataFetcherFactory) { + assertNotNull(dataFetcherFactory); + assertNotNull(coordinates); + coordinates.assertValidNames(); + if (coordinates.isSystemCoordinates()) { + systemDataFetcherMap.put(coordinates.getFieldName(), dataFetcherFactory); + } else { + dataFetcherMap.put(coordinates, dataFetcherFactory); + } + return markChanged(); + } + + /** + * Sets the data fetcher factory for a specific field inside a container type ONLY if not mapping has already been made + * + * @param coordinates the field coordinates + * @param dataFetcher the data fetcher code for that field + * + * @return this builder + */ + public Builder dataFetcherIfAbsent(FieldCoordinates coordinates, DataFetcher dataFetcher) { + if (!hasDataFetcher(coordinates)) { + if (coordinates.isSystemCoordinates()) { + systemDataFetcher(coordinates, dataFetcher); + } else { + dataFetcher(coordinates, dataFetcher); + } + return markChanged(); + } + return this; + } + + /** + * This allows you you to build all the data fetchers for the fields of a container type. + * + * @param parentTypeName the parent container type + * @param fieldDataFetchers the map of field names to data fetchers + * + * @return this builder + */ + public Builder dataFetchers(String parentTypeName, Map> fieldDataFetchers) { + assertNotNull(fieldDataFetchers); + fieldDataFetchers.forEach((fieldName, dataFetcher) -> dataFetcher(coordinates(parentTypeName, fieldName), dataFetcher)); + return markChanged(!fieldDataFetchers.isEmpty()); + } + + /** + * This is the default data fetcher factory that will be used for fields that do not have specific data fetchers attached. By default + * {@link graphql.schema.PropertyDataFetcher} is used but you can have your own default via this method. + * + * @param defaultDataFetcherFactory the default data fetcher factory used + * + * @return this builder + */ + public Builder defaultDataFetcher(DataFetcherFactory defaultDataFetcherFactory) { + this.defaultDataFetcherFactory = Assert.assertNotNull(defaultDataFetcherFactory); + return markChanged(); + } + + public Builder dataFetchers(GraphQLCodeRegistry codeRegistry) { + this.dataFetcherMap.putAll(codeRegistry.dataFetcherMap); + return markChanged(!codeRegistry.dataFetcherMap.isEmpty()); + } + + public Builder typeResolver(GraphQLInterfaceType interfaceType, TypeResolver typeResolver) { + typeResolverMap.put(interfaceType.getName(), typeResolver); + return markChanged(); + } + + public Builder typeResolverIfAbsent(GraphQLInterfaceType interfaceType, TypeResolver typeResolver) { + if (!typeResolverMap.containsKey(interfaceType.getName())) { + typeResolverMap.put(interfaceType.getName(), typeResolver); + return markChanged(); + } + return this; + } + + public Builder typeResolver(GraphQLUnionType unionType, TypeResolver typeResolver) { + typeResolverMap.put(unionType.getName(), typeResolver); + return markChanged(); + } + + public Builder typeResolverIfAbsent(GraphQLUnionType unionType, TypeResolver typeResolver) { + if (!typeResolverMap.containsKey(unionType.getName())) { + typeResolverMap.put(unionType.getName(), typeResolver); + return markChanged(); + } + return markChanged(); + } + + public Builder typeResolver(String typeName, TypeResolver typeResolver) { + typeResolverMap.put(assertValidName(typeName), typeResolver); + return markChanged(); + } + + public Builder typeResolvers(GraphQLCodeRegistry codeRegistry) { + this.typeResolverMap.putAll(codeRegistry.typeResolverMap); + return markChanged(!codeRegistry.typeResolverMap.isEmpty()); + } + + public Builder fieldVisibility(GraphqlFieldVisibility fieldVisibility) { + this.fieldVisibility = assertNotNull(fieldVisibility); + return markChanged(); + } + + public Builder clearDataFetchers() { + dataFetcherMap.clear(); + return markChanged(); + } + + public Builder clearTypeResolvers() { + typeResolverMap.clear(); + return markChanged(); + } + + public GraphQLCodeRegistry build() { + return new GraphQLCodeRegistry(this); + } + } +} diff --git a/src/main/java/graphql/schema/GraphQLCompositeType.java b/src/main/java/graphql/schema/GraphQLCompositeType.java index bf1774410a..a8cf3c4ed6 100644 --- a/src/main/java/graphql/schema/GraphQLCompositeType.java +++ b/src/main/java/graphql/schema/GraphQLCompositeType.java @@ -4,5 +4,5 @@ import graphql.PublicApi; @PublicApi -public interface GraphQLCompositeType extends GraphQLOutputType { +public interface GraphQLCompositeType extends GraphQLNamedOutputType { } diff --git a/src/main/java/graphql/schema/GraphQLDirective.java b/src/main/java/graphql/schema/GraphQLDirective.java index 91b1037198..402902303e 100644 --- a/src/main/java/graphql/schema/GraphQLDirective.java +++ b/src/main/java/graphql/schema/GraphQLDirective.java @@ -1,10 +1,12 @@ package graphql.schema; -import graphql.Assert; +import com.google.common.collect.ImmutableList; import graphql.PublicApi; +import graphql.language.DirectiveDefinition; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; -import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.LinkedHashMap; @@ -13,99 +15,96 @@ import java.util.function.Consumer; import java.util.function.UnaryOperator; +import static graphql.Assert.assertNotEmpty; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; import static graphql.introspection.Introspection.DirectiveLocation; import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; /** * A directive can be used to modify the behavior of a graphql field or type. - * - * See http://graphql.org/learn/queries/#directives for more details on the concept. + *

+ * See https://graphql.org/learn/queries/#directives for more details on the concept. + *

+ * A directive has a definition, that is what arguments it takes, and it can also be applied + * to other schema elements. Originally graphql-java re-used the {@link GraphQLDirective} and {@link GraphQLArgument} + * classes to do both purposes. This was a modelling mistake. New {@link GraphQLAppliedDirective} and {@link GraphQLAppliedDirectiveArgument} + * classes have been introduced to better model when a directive is applied to a schema element, + * as opposed to its schema definition itself. */ -@SuppressWarnings("DeprecatedIsStillUsed") // because the graphql spec still has some of these deprecated fields @PublicApi -public class GraphQLDirective { +public class GraphQLDirective implements GraphQLNamedSchemaElement { private final String name; + private final boolean repeatable; private final String description; private final EnumSet locations; - private final List arguments = new ArrayList<>(); - private final boolean onOperation; - private final boolean onFragment; - private final boolean onField; + private final ImmutableList arguments; + private final DirectiveDefinition definition; - public GraphQLDirective(String name, String description, EnumSet locations, - List arguments, boolean onOperation, boolean onFragment, boolean onField) { + + public static final String CHILD_ARGUMENTS = "arguments"; + + private GraphQLDirective(String name, + String description, + boolean repeatable, + EnumSet locations, + List arguments, + DirectiveDefinition definition) { assertValidName(name); assertNotNull(arguments, "arguments can't be null"); + assertNotEmpty(locations, "locations can't be empty"); this.name = name; this.description = description; + this.repeatable = repeatable; this.locations = locations; - this.arguments.addAll(arguments); - this.onOperation = onOperation; - this.onFragment = onFragment; - this.onField = onField; + this.arguments = ImmutableList.copyOf(arguments); + this.definition = definition; } + @Override public String getName() { return name; } + public boolean isRepeatable() { + return repeatable; + } + + public boolean isNonRepeatable() { + return !repeatable; + } + public List getArguments() { - return new ArrayList<>(arguments); + return arguments; } public GraphQLArgument getArgument(String name) { for (GraphQLArgument argument : arguments) { - if (argument.getName().equals(name)) return argument; + if (argument.getName().equals(name)) { + return argument; + } } return null; } public EnumSet validLocations() { - return locations; - } - - /** - * @return onOperation - * - * @deprecated Use {@link #validLocations()} - */ - @Deprecated - public boolean isOnOperation() { - return onOperation; - } - - /** - * @return onFragment - * - * @deprecated Use {@link #validLocations()} - */ - @Deprecated - public boolean isOnFragment() { - return onFragment; - } - - /** - * @return onField - * - * @deprecated Use {@link #validLocations()} - */ - @Deprecated - public boolean isOnField() { - return onField; + return EnumSet.copyOf(locations); } public String getDescription() { return description; } + public DirectiveDefinition getDefinition() { + return definition; + } + @Override public String toString() { return "GraphQLDirective{" + "name='" + name + '\'' + + ", repeatable='" + repeatable + '\'' + ", arguments=" + arguments + ", locations=" + locations + '}'; @@ -125,6 +124,65 @@ public GraphQLDirective transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newDirective(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLDirective(this, context); + } + + @Override + public List getChildren() { + return ImmutableList.copyOf(arguments); + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_ARGUMENTS, arguments) + .build(); + } + + @Override + public GraphQLDirective withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceArguments(newChildren.getChildren(CHILD_ARGUMENTS)) + ); + } + + /** + * This method can be used to turn a directive that was being use as an applied directive into one. + * @return an {@link GraphQLAppliedDirective} + */ + public GraphQLAppliedDirective toAppliedDirective() { + GraphQLAppliedDirective.Builder builder = GraphQLAppliedDirective.newDirective(); + builder.name(this.name); + for (GraphQLArgument argument : arguments) { + builder.argument(argument.toAppliedArgument()); + } + return builder.build(); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + public static Builder newDirective() { return new Builder(); @@ -134,37 +192,26 @@ public static Builder newDirective(GraphQLDirective existing) { return new Builder(existing); } - public static class Builder { + public static class Builder extends GraphqlTypeBuilder { - private String name; - private String description; - private boolean onOperation; - private boolean onFragment; - private boolean onField; private EnumSet locations = EnumSet.noneOf(DirectiveLocation.class); private final Map arguments = new LinkedHashMap<>(); + private DirectiveDefinition definition; + private boolean repeatable = false; public Builder() { } - @SuppressWarnings("deprecation") public Builder(GraphQLDirective existing) { this.name = existing.getName(); this.description = existing.getDescription(); - this.onOperation = existing.isOnOperation(); - this.onFragment = existing.isOnFragment(); - this.onField = existing.isOnField(); + this.repeatable = existing.isRepeatable(); this.locations = existing.validLocations(); this.arguments.putAll(getByName(existing.getArguments(), GraphQLArgument::getName)); } - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder description(String description) { - this.description = description; + public Builder repeatable(boolean repeatable) { + this.repeatable = repeatable; return this; } @@ -184,11 +231,20 @@ public Builder clearValidLocations() { } public Builder argument(GraphQLArgument argument) { - Assert.assertNotNull(argument, "argument must not be null"); + assertNotNull(argument, "argument must not be null"); arguments.put(argument.getName(), argument); return this; } + public Builder replaceArguments(List arguments) { + assertNotNull(arguments, "arguments must not be null"); + this.arguments.clear(); + for (GraphQLArgument argument : arguments) { + this.arguments.put(argument.getName(), argument); + } + return this; + } + /** * Take an argument builder in a function definition and apply. Can be used in a jdk8 lambda * e.g.: @@ -231,47 +287,31 @@ public Builder clearArguments() { } - /** - * @param onOperation onOperation - * - * @return this builder - * - * @deprecated Use {@code graphql.schema.GraphQLDirective.Builder#validLocations(DirectiveLocation...)} - */ - @Deprecated - public Builder onOperation(boolean onOperation) { - this.onOperation = onOperation; + public Builder definition(DirectiveDefinition definition) { + this.definition = definition; return this; } - /** - * @param onFragment onFragment - * - * @return this builder - * - * @deprecated Use {@code graphql.schema.GraphQLDirective.Builder#validLocations(DirectiveLocation...)} - */ - @Deprecated - public Builder onFragment(boolean onFragment) { - this.onFragment = onFragment; - return this; + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder name(String name) { + return super.name(name); } - /** - * @param onField onField - * - * @return this builder - * - * @deprecated Use {@code graphql.schema.GraphQLDirective.Builder#validLocations(DirectiveLocation...)} - */ - @Deprecated - public Builder onField(boolean onField) { - this.onField = onField; - return this; + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLDirective build() { - return new GraphQLDirective(name, description, locations, valuesToList(arguments), onOperation, onFragment, onField); + return new GraphQLDirective( + name, + description, + repeatable, + locations, + sort(arguments, GraphQLDirective.class, GraphQLArgument.class), + definition); } diff --git a/src/main/java/graphql/schema/GraphQLDirectiveContainer.java b/src/main/java/graphql/schema/GraphQLDirectiveContainer.java index f296e20782..4bee55aa36 100644 --- a/src/main/java/graphql/schema/GraphQLDirectiveContainer.java +++ b/src/main/java/graphql/schema/GraphQLDirectiveContainer.java @@ -1,37 +1,153 @@ package graphql.schema; +import graphql.PublicApi; import java.util.List; import java.util.Map; -import static graphql.DirectivesUtil.directivesByName; +import static graphql.collect.ImmutableKit.emptyList; /** - * Represents a graphql object that can have {@link graphql.schema.GraphQLDirective}s + * Represents a graphql runtime type that can have {@link graphql.schema.GraphQLAppliedDirective}s. + *

+ * Directives can be repeatable and (by default) non-repeatable. + *

+ * There are access methods here that get the two different types. + *

+ * The use of {@link GraphQLDirective} to represent a directive applied to an element is deprecated in favour of + * {@link GraphQLAppliedDirective}. A {@link GraphQLDirective} really should represent the definition of a directive in a schema, not its use + * on schema elements. However, it has been left in place for legacy reasons and will be removed in a + * future version. + * + * @see graphql.language.DirectiveDefinition + * @see graphql.language.DirectiveDefinition#isRepeatable() */ -public interface GraphQLDirectiveContainer extends GraphQLType { +@PublicApi +public interface GraphQLDirectiveContainer extends GraphQLNamedSchemaElement { + + String CHILD_DIRECTIVES = "directives"; + String CHILD_APPLIED_DIRECTIVES = "appliedDirectives"; + /** - * @return a list of directives associated with the type or field + * This will return a list of all the directives that have been put on {@link graphql.schema.GraphQLNamedSchemaElement} as a flat list, which may contain repeatable + * and non-repeatable directives. + * + * @return a list of all the directives associated with this named schema element */ - List getDirectives(); + List getAppliedDirectives(); /** - * @return a a map of directives by directive name + * This will return a Map of the all directives that are associated with a {@link graphql.schema.GraphQLNamedSchemaElement}, including both + * repeatable and non-repeatable directives. + * + * @return a map of all directives by directive name */ - default Map getDirectivesByName() { - return directivesByName(getDirectives()); - } + Map> getAllAppliedDirectivesByName(); /** - * Returns a named directive + * Returns a non-repeatable directive with the provided name. * * @param directiveName the name of the directive to retrieve * - * @return the directive or null if there is one one with that name + * @return the directive or null if there is not one with that name + */ + GraphQLAppliedDirective getAppliedDirective(String directiveName); + + + /** + * Returns all of the directives with the provided name, including repeatable and non repeatable directives. + * + * @param directiveName the name of the directives to retrieve + * + * @return the directives or empty list if there is not one with that name */ - default GraphQLDirective getDirective(String directiveName) { - return getDirectivesByName().get(directiveName); + default List getAppliedDirectives(String directiveName) { + return getAllAppliedDirectivesByName().getOrDefault(directiveName, emptyList()); } + /** + * This will return true if the element has a directive (repeatable or non repeatable) with the specified name + * + * @param directiveName the name of the directive + * + * @return true if there is a directive on this element with that name + * + * @deprecated use {@link #hasAppliedDirective(String)} instead + */ + @Deprecated(since = "2022-02-24") + default boolean hasDirective(String directiveName) { + return getAllDirectivesByName().containsKey(directiveName); + } + + /** + * This will return true if the element has a directive (repeatable or non repeatable) with the specified name + * + * @param directiveName the name of the directive + * + * @return true if there is a directive on this element with that name + */ + default boolean hasAppliedDirective(String directiveName) { + return getAllAppliedDirectivesByName().containsKey(directiveName); + } + + /** + * This will return a list of all the directives that have been put on {@link graphql.schema.GraphQLNamedSchemaElement} as a flat list, which may contain repeatable + * and non-repeatable directives. + * + * @return a list of all the directives associated with this named schema element + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + List getDirectives(); + + /** + * This will return a Map of the non repeatable directives that are associated with a {@link graphql.schema.GraphQLNamedSchemaElement}. Any repeatable directives + * will be filtered out of this map. + * + * @return a map of non repeatable directives by directive name. + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + Map getDirectivesByName(); + + /** + * This will return a Map of the all directives that are associated with a {@link graphql.schema.GraphQLNamedSchemaElement}, including both + * repeatable and non repeatable directives. + * + * @return a map of all directives by directive name + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + Map> getAllDirectivesByName(); + + /** + * Returns a non-repeatable directive with the provided name. This will throw a {@link graphql.AssertException} if + * the directive is a repeatable directive that has more then one instance. + * + * @param directiveName the name of the directive to retrieve + * + * @return the directive or null if there is not one with that name + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + GraphQLDirective getDirective(String directiveName); + + /** + * Returns all of the directives with the provided name, including repeatable and non repeatable directives. + * + * @param directiveName the name of the directives to retrieve + * + * @return the directives or empty list if there is not one with that name + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + default List getDirectives(String directiveName) { + return getAllDirectivesByName().getOrDefault(directiveName, emptyList()); + } } diff --git a/src/main/java/graphql/schema/GraphQLEnumType.java b/src/main/java/graphql/schema/GraphQLEnumType.java index 8277740fef..b768fdde01 100644 --- a/src/main/java/graphql/schema/GraphQLEnumType.java +++ b/src/main/java/graphql/schema/GraphQLEnumType.java @@ -1,119 +1,164 @@ package graphql.schema; - -import graphql.AssertException; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.DirectivesUtil; +import graphql.GraphQLContext; import graphql.Internal; import graphql.PublicApi; import graphql.language.EnumTypeDefinition; +import graphql.language.EnumTypeExtensionDefinition; import graphql.language.EnumValue; +import graphql.language.Value; +import graphql.util.FpKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import org.jspecify.annotations.NonNull; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Consumer; import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertValidName; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.scalar.CoercingUtil.i18nMsg; +import static graphql.scalar.CoercingUtil.typeName; +import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition; import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; -import static java.util.Collections.emptyList; /** * A graphql enumeration type has a limited set of values. - * + *

* This allows you to validate that any arguments of this type are one of the allowed values * and communicate through the type system that a field will always be one of a finite set of values. - * - * See http://graphql.org/learn/schema/#enumeration-types for more details + *

+ * See https://graphql.org/learn/schema/#enumeration-types for more details */ @PublicApi -public class GraphQLEnumType implements GraphQLType, GraphQLInputType, GraphQLOutputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { +public class GraphQLEnumType implements GraphQLNamedInputType, GraphQLNamedOutputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { private final String name; private final String description; - private final Map valueDefinitionMap = new LinkedHashMap<>(); + private final ImmutableMap valueDefinitionMap; private final EnumTypeDefinition definition; - private final List directives; + private final ImmutableList extensionDefinitions; + private final DirectivesUtil.DirectivesHolder directivesHolder; - private final Coercing coercing = new Coercing() { - @Override - public Object serialize(Object input) { - return getNameByValue(input); - } + public static final String CHILD_VALUES = "values"; - @Override - public Object parseValue(Object input) { - return getValueByName(input); - } + @Internal + private GraphQLEnumType(String name, + String description, + List values, + List directives, + List appliedDirectives, + EnumTypeDefinition definition, + List extensionDefinitions) { + assertValidName(name); + assertNotNull(directives, "directives cannot be null"); - private String typeName(Object input) { - if (input == null) { - return "null"; - } - return input.getClass().getSimpleName(); - } + this.name = name; + this.description = description; + this.definition = definition; + this.extensionDefinitions = ImmutableList.copyOf(extensionDefinitions); + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); + this.valueDefinitionMap = buildMap(values); + } - @Override - public Object parseLiteral(Object input) { - if (!(input instanceof EnumValue)) { - throw new CoercingParseLiteralException( - "Expected AST type 'EnumValue' but was '" + typeName(input) + "'." - ); - } - EnumValue enumValue = (EnumValue) input; - GraphQLEnumValueDefinition enumValueDefinition = valueDefinitionMap.get(enumValue.getName()); - if (enumValueDefinition == null) { - throw new CoercingParseLiteralException( - "Expected enum literal value not in allowable values - '" + String.valueOf(input) + "'." - ); - } - return enumValueDefinition.getValue(); + @Internal + @Deprecated + public Object serialize(Object input) { + return serialize(input, GraphQLContext.getDefault(), Locale.getDefault()); + } + + @Internal + public Object serialize(Object input, GraphQLContext graphQLContext, Locale locale) { + return getNameByValue(input, graphQLContext, locale); + } + + @Internal + @Deprecated + public Object parseValue(Object input) { + return getValueByName(input, GraphQLContext.getDefault(), Locale.getDefault()); + } + + @Internal + public Object parseValue(Object input, GraphQLContext graphQLContext, Locale locale) { + return getValueByName(input, graphQLContext, locale); + } + + + @Internal + @Deprecated + public Object parseLiteral(Object input) { + return parseLiteralImpl(input, GraphQLContext.getDefault(), Locale.getDefault()); + } + + @Internal + public Object parseLiteral(Value input, GraphQLContext graphQLContext, Locale locale) { + return parseLiteralImpl(input, graphQLContext, locale); + } + + private Object parseLiteralImpl(Object input, GraphQLContext graphQLContext, Locale locale) { + if (!(input instanceof EnumValue)) { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Scalar.unexpectedAstType", "EnumValue", typeName(input)) + ); + } + EnumValue enumValue = (EnumValue) input; + GraphQLEnumValueDefinition enumValueDefinition = valueDefinitionMap.get(enumValue.getName()); + if (enumValueDefinition == null) { + throw new CoercingParseLiteralException( + i18nMsg(locale, "Enum.unallowableValue", getName(), input) + ); } - }; + return enumValueDefinition.getValue(); + } @Internal - public GraphQLEnumType(String name, String description, List values) { - this(name, description, values, emptyList(), null); + @Deprecated + public Value valueToLiteral(Object input) { + return valueToLiteral(input, GraphQLContext.getDefault(), Locale.getDefault()); } @Internal - public GraphQLEnumType(String name, String description, List values, List directives, EnumTypeDefinition definition) { - assertValidName(name); - assertNotNull(directives, "directives cannot be null"); + public Value valueToLiteral(Object input, GraphQLContext graphQLContext, Locale locale) { + GraphQLEnumValueDefinition enumValueDefinition = valueDefinitionMap.get(input.toString()); + if (enumValueDefinition == null) { + assertShouldNeverHappen(i18nMsg(locale, "Enum.badName", name, input.toString())); + }; + return EnumValue.newEnumValue(enumValueDefinition.getName()).build(); - this.name = name; - this.description = description; - this.definition = definition; - this.directives = directives; - buildMap(values); } public List getValues() { - return new ArrayList<>(valueDefinitionMap.values()); + return ImmutableList.copyOf(valueDefinitionMap.values()); } public GraphQLEnumValueDefinition getValue(String name) { return valueDefinitionMap.get(name); } - private void buildMap(List values) { - for (GraphQLEnumValueDefinition valueDefinition : values) { - String name = valueDefinition.getName(); - if (valueDefinitionMap.containsKey(name)) - throw new AssertException("value " + name + " redefined"); - valueDefinitionMap.put(name, valueDefinition); - } + private ImmutableMap buildMap(List values) { + return ImmutableMap.copyOf(FpKit.getByName(values, GraphQLEnumValueDefinition::getName, + (fld1, fld2) -> assertShouldNeverHappen("Duplicated definition for field '%s' in type '%s'", fld1.getName(), this.name))); } - private Object getValueByName(Object value) { + private Object getValueByName(@NonNull Object value, GraphQLContext graphQLContext, Locale locale) { GraphQLEnumValueDefinition enumValueDefinition = valueDefinitionMap.get(value.toString()); - if (enumValueDefinition != null) return enumValueDefinition.getValue(); - throw new CoercingParseValueException("Invalid input for Enum '" + name + "'. No value found for name '" + value.toString() + "'"); + if (enumValueDefinition != null) { + return enumValueDefinition.getValue(); + } + throw new CoercingParseValueException(i18nMsg(locale, "Enum.badName", name, value.toString())); } - private Object getNameByValue(Object value) { + private Object getNameByValue(Object value, GraphQLContext graphQLContext, Locale locale) { for (GraphQLEnumValueDefinition valueDefinition : valueDefinitionMap.values()) { Object definitionValue = valueDefinition.getValue(); if (value.equals(definitionValue)) { @@ -126,7 +171,7 @@ private Object getNameByValue(Object value) { } } } - // ok we didn't match on pure object.equals(). Lets try the Java enum strategy + // ok we didn't match on pure object.equals(). Let's try the Java enum strategy if (value instanceof Enum) { String enumNameValue = ((Enum) value).name(); for (GraphQLEnumValueDefinition valueDefinition : valueDefinitionMap.values()) { @@ -136,7 +181,7 @@ private Object getNameByValue(Object value) { } } } - throw new CoercingSerializeException("Invalid input for Enum '" + name + "'. Unknown value '" + value + "'"); + throw new CoercingSerializeException(i18nMsg(locale, "Enum.badInput", name, value)); } @Override @@ -148,17 +193,47 @@ public String getDescription() { return description; } - public Coercing getCoercing() { - return coercing; - } - public EnumTypeDefinition getDefinition() { return definition; } + public List getExtensionDefinitions() { + return extensionDefinitions; + } + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } /** @@ -175,6 +250,72 @@ public GraphQLEnumType transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newEnum(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLEnumType(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(valueDefinitionMap.values()); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_VALUES, valueDefinitionMap.values()) + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLEnumType withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceValues(newChildren.getChildren(CHILD_VALUES)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + + @Override + public String toString() { + return "GraphQLEnumType{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", valueDefinitionMap=" + valueDefinitionMap + + ", definition=" + definition + + ", extensionDefinitions=" + extensionDefinitions + + ", directives=" + directivesHolder + + '}'; + } + public static Builder newEnum() { return new Builder(); } @@ -183,13 +324,11 @@ public static Builder newEnum(GraphQLEnumType existing) { return new Builder(existing); } - public static class Builder { + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { - private String name; - private String description; private EnumTypeDefinition definition; + private List extensionDefinitions = emptyList(); private final Map values = new LinkedHashMap<>(); - private final Map directives = new LinkedHashMap<>(); public Builder() { } @@ -198,42 +337,54 @@ public Builder(GraphQLEnumType existing) { this.name = existing.getName(); this.description = existing.getDescription(); this.definition = existing.getDefinition(); + this.extensionDefinitions = existing.getExtensionDefinitions(); this.values.putAll(getByName(existing.getValues(), GraphQLEnumValueDefinition::getName)); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); - } - - public Builder name(String name) { - this.name = name; - return this; + copyExistingDirectives(existing); } - public Builder description(String description) { - this.description = description; + public Builder definition(EnumTypeDefinition definition) { + this.definition = definition; return this; } - public Builder definition(EnumTypeDefinition definition) { - this.definition = definition; + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; return this; } public Builder value(String name, Object value, String description, String deprecationReason) { - value(new GraphQLEnumValueDefinition(name, description, value, deprecationReason)); - return this; + return value(newEnumValueDefinition().name(name) + .description(description).value(value) + .deprecationReason(deprecationReason).build()); } public Builder value(String name, Object value, String description) { - return value(new GraphQLEnumValueDefinition(name, description, value)); + return value(newEnumValueDefinition().name(name) + .description(description).value(value).build()); } public Builder value(String name, Object value) { assertNotNull(value, "value can't be null"); - return value(new GraphQLEnumValueDefinition(name, null, value)); + return value(newEnumValueDefinition().name(name) + .value(value).build()); } + public Builder value(String name) { - return value(new GraphQLEnumValueDefinition(name, null, name)); + return value(newEnumValueDefinition().name(name) + .value(name).build()); + } + + public Builder values(List valueDefinitions) { + valueDefinitions.forEach(this::value); + return this; + } + + public Builder replaceValues(List valueDefinitions) { + this.values.clear(); + valueDefinitions.forEach(this::value); + return this; } public Builder value(GraphQLEnumValueDefinition enumValueDefinition) { @@ -256,36 +407,52 @@ public Builder clearValues() { return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override public Builder withDirectives(GraphQLDirective... directives) { - assertNotNull(directives, "directives can't be null"); - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLEnumType build() { - return new GraphQLEnumType(name, description, valuesToList(values), valuesToList(directives), definition); + return new GraphQLEnumType( + name, + description, + sort(values, GraphQLEnumType.class, GraphQLEnumValueDefinition.class), + sort(directives, GraphQLEnumType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + definition, + extensionDefinitions); } } } diff --git a/src/main/java/graphql/schema/GraphQLEnumValueDefinition.java b/src/main/java/graphql/schema/GraphQLEnumValueDefinition.java index 322d3af809..b06aed763c 100644 --- a/src/main/java/graphql/schema/GraphQLEnumValueDefinition.java +++ b/src/main/java/graphql/schema/GraphQLEnumValueDefinition.java @@ -4,47 +4,44 @@ import graphql.DirectivesUtil; import graphql.Internal; import graphql.PublicApi; +import graphql.language.EnumValueDefinition; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; -import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; -import static java.util.Collections.emptyList; /** * A graphql enumeration type has a limited set of values and this defines one of those unique values - * - * See http://graphql.org/learn/schema/#enumeration-types for more details + *

+ * See https://graphql.org/learn/schema/#enumeration-types for more details * * @see graphql.schema.GraphQLEnumType */ @PublicApi -public class GraphQLEnumValueDefinition implements GraphQLDirectiveContainer { +public class GraphQLEnumValueDefinition implements GraphQLNamedSchemaElement, GraphQLDirectiveContainer { private final String name; private final String description; private final Object value; private final String deprecationReason; - private final List directives; + private final DirectivesUtil.DirectivesHolder directivesHolder; + private final EnumValueDefinition definition; @Internal - public GraphQLEnumValueDefinition(String name, String description, Object value) { - this(name, description, value, null, emptyList()); - } - - @Internal - public GraphQLEnumValueDefinition(String name, String description, Object value, String deprecationReason) { - this(name, description, value, deprecationReason, emptyList()); - } - - @Internal - public GraphQLEnumValueDefinition(String name, String description, Object value, String deprecationReason, List directives) { + private GraphQLEnumValueDefinition(String name, + String description, + Object value, + String deprecationReason, + List directives, + List appliedDirectives, + EnumValueDefinition definition) { assertValidName(name); assertNotNull(directives, "directives cannot be null"); @@ -52,7 +49,8 @@ public GraphQLEnumValueDefinition(String name, String description, Object value, this.description = description; this.value = value; this.deprecationReason = deprecationReason; - this.directives = directives; + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); + this.definition = definition; } @Override @@ -78,17 +76,41 @@ public String getDeprecationReason() { @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); } @Override public Map getDirectivesByName() { - return DirectivesUtil.directivesByName(directives); + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); } @Override public GraphQLDirective getDirective(String directiveName) { - return getDirectivesByName().get(directiveName); + return directivesHolder.getDirective(directiveName); + } + + public EnumValueDefinition getDefinition() { + return definition; + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } /** @@ -105,6 +127,64 @@ public GraphQLEnumValueDefinition transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newEnumValueDefinition(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLEnumValueDefinition(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLEnumValueDefinition withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> builder + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + @Override + public String toString() { + return "GraphQLEnumValueDefinition{" + + "name='" + name + '\'' + + '}'; + } + public static Builder newEnumValueDefinition() { return new Builder(); } @@ -114,12 +194,11 @@ public static Builder newEnumValueDefinition(GraphQLEnumValueDefinition existing } @PublicApi - public static class Builder { - private String name; - private String description; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { private Object value; private String deprecationReason; - private final Map directives = new LinkedHashMap<>(); + private EnumValueDefinition definition; public Builder() { } @@ -129,59 +208,69 @@ public Builder(GraphQLEnumValueDefinition existing) { this.description = existing.getDescription(); this.value = existing.getValue(); this.deprecationReason = existing.getDeprecationReason(); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); + copyExistingDirectives(existing); } - public Builder name(String name) { - this.name = name; + public Builder value(Object value) { + this.value = value; return this; } - public Builder description(String description) { - this.description = description; + public Builder deprecationReason(String deprecationReason) { + this.deprecationReason = deprecationReason; return this; } - public Builder value(Object value) { - this.value = value; + public Builder definition(EnumValueDefinition definition) { + this.definition = definition; return this; } - public Builder deprecationReason(String deprecationReason) { - this.deprecationReason = deprecationReason; - return this; + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); } + @Override public Builder withDirectives(GraphQLDirective... directives) { - assertNotNull(directives, "directives can't be null"); - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLEnumValueDefinition build() { - return new GraphQLEnumValueDefinition(name, description, value, deprecationReason, valuesToList(directives)); + return new GraphQLEnumValueDefinition(name, + description, + value, + deprecationReason, + sort(directives, GraphQLScalarType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + definition); } } } diff --git a/src/main/java/graphql/schema/GraphQLFieldDefinition.java b/src/main/java/graphql/schema/GraphQLFieldDefinition.java index d01eafca67..779421c2c1 100644 --- a/src/main/java/graphql/schema/GraphQLFieldDefinition.java +++ b/src/main/java/graphql/schema/GraphQLFieldDefinition.java @@ -1,72 +1,80 @@ package graphql.schema; +import com.google.common.collect.ImmutableList; +import graphql.DirectivesUtil; import graphql.Internal; import graphql.PublicApi; import graphql.language.FieldDefinition; +import graphql.util.Interning; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import java.util.function.UnaryOperator; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; import static graphql.schema.DataFetcherFactoryEnvironment.newDataFetchingFactoryEnvironment; import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; /** * Fields are the ways you get data values in graphql and a field definition represents a field, its type, the arguments it takes - * and the {@link graphql.schema.DataFetcher} used to get data values for that field. - * + * and the {@link DataFetcher} used to get data values for that field. + *

* Fields can be thought of as functions in graphql, they have a name, take defined arguments and return a value. - * + *

* Fields can also be deprecated, which indicates the consumers that a field wont be supported in the future. - * - * See http://graphql.org/learn/queries/#fields for more details on the concept. + *

+ * See https://graphql.org/learn/queries/#fields for more details on the concept. */ @PublicApi -public class GraphQLFieldDefinition implements GraphQLDirectiveContainer { +public class GraphQLFieldDefinition implements GraphQLNamedSchemaElement, GraphQLDirectiveContainer { private final String name; private final String description; - private GraphQLOutputType type; + private final GraphQLOutputType originalType; private final DataFetcherFactory dataFetcherFactory; private final String deprecationReason; - private final List arguments; - private final List directives; + private final ImmutableList arguments; + private final DirectivesUtil.DirectivesHolder directivesHolder; private final FieldDefinition definition; + private GraphQLOutputType replacedType; - @Deprecated - @Internal - public GraphQLFieldDefinition(String name, String description, GraphQLOutputType type, DataFetcher dataFetcher, List arguments, String deprecationReason) { - this(name, description, type, DataFetcherFactories.useDataFetcher(dataFetcher), arguments, deprecationReason, Collections.emptyList(), null); - } + public static final String CHILD_ARGUMENTS = "arguments"; + public static final String CHILD_TYPE = "type"; @Internal - public GraphQLFieldDefinition(String name, String description, GraphQLOutputType type, DataFetcherFactory dataFetcherFactory, List arguments, String deprecationReason, List directives, FieldDefinition definition) { - this.directives = directives; + private GraphQLFieldDefinition(String name, + String description, + GraphQLOutputType type, + DataFetcherFactory dataFetcherFactory, + List arguments, + String deprecationReason, + List directives, + List appliedDirectives, + FieldDefinition definition) { assertValidName(name); - assertNotNull(dataFetcherFactory, "you have to provide a DataFetcher (or DataFetcherFactory)"); assertNotNull(type, "type can't be null"); assertNotNull(arguments, "arguments can't be null"); - this.name = name; + this.name = Interning.intern(name); this.description = description; - this.type = type; + this.originalType = type; this.dataFetcherFactory = dataFetcherFactory; - this.arguments = Collections.unmodifiableList(new ArrayList<>(arguments)); + this.arguments = ImmutableList.copyOf(arguments); + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); this.deprecationReason = deprecationReason; this.definition = definition; } - - void replaceTypeReferences(Map typeMap) { - this.type = (GraphQLOutputType) new SchemaUtil().resolveTypeReference(this.type, typeMap); + void replaceType(GraphQLOutputType type) { + this.replacedType = type; } @Override @@ -76,10 +84,16 @@ public String getName() { public GraphQLOutputType getType() { - return type; + return replacedType != null ? replacedType : originalType; } - public DataFetcher getDataFetcher() { + // to be removed in a future version when all code is in the code registry + @Internal + @Deprecated(since = "2018-12-03") + DataFetcher getDataFetcher() { + if (dataFetcherFactory == null) { + return null; + } return dataFetcherFactory.get(newDataFetchingFactoryEnvironment() .fieldDefinition(this) .build()); @@ -87,14 +101,46 @@ public DataFetcher getDataFetcher() { public GraphQLArgument getArgument(String name) { for (GraphQLArgument argument : arguments) { - if (argument.getName().equals(name)) return argument; + if (argument.getName().equals(name)) { + return argument; + } } return null; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } public List getArguments() { @@ -121,7 +167,7 @@ public boolean isDeprecated() { public String toString() { return "GraphQLFieldDefinition{" + "name='" + name + '\'' + - ", type=" + type + + ", type=" + getType() + ", arguments=" + arguments + ", dataFetcherFactory=" + dataFetcherFactory + ", description='" + description + '\'' + @@ -144,6 +190,64 @@ public GraphQLFieldDefinition transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newFieldDefinition(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLFieldDefinition(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(); + children.add(getType()); + children.addAll(arguments); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .child(CHILD_TYPE, originalType) + .children(CHILD_ARGUMENTS, arguments) + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .build(); + } + + // Spock mocking fails with the real return type GraphQLFieldDefinition + @Override + public GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceArguments(newChildren.getChildren(CHILD_ARGUMENTS)) + .type((GraphQLOutputType) newChildren.getChildOrNull(CHILD_TYPE)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + public static Builder newFieldDefinition(GraphQLFieldDefinition existing) { return new Builder(existing); } @@ -153,36 +257,27 @@ public static Builder newFieldDefinition() { } @PublicApi - public static class Builder { + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { - private String name; - private String description; private GraphQLOutputType type; private DataFetcherFactory dataFetcherFactory; private String deprecationReason; private FieldDefinition definition; private final Map arguments = new LinkedHashMap<>(); - private final Map directives = new LinkedHashMap<>(); public Builder() { } - @SuppressWarnings("unchecked") public Builder(GraphQLFieldDefinition existing) { this.name = existing.getName(); this.description = existing.getDescription(); - this.type = existing.getType(); + this.type = existing.originalType; this.dataFetcherFactory = DataFetcherFactories.useDataFetcher(existing.getDataFetcher()); this.deprecationReason = existing.getDeprecationReason(); this.definition = existing.getDefinition(); this.arguments.putAll(getByName(existing.getArguments(), GraphQLArgument::getName)); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); - } - - - public Builder name(String name) { - this.name = name; - return this; + copyExistingDirectives(existing); } public Builder definition(FieldDefinition definition) { @@ -190,11 +285,6 @@ public Builder definition(FieldDefinition definition) { return this; } - public Builder description(String description) { - this.description = description; - return this; - } - public Builder type(GraphQLObjectType.Builder builder) { return type(builder.build()); } @@ -218,7 +308,10 @@ public Builder type(GraphQLOutputType type) { * @param dataFetcher the data fetcher to use * * @return this builder + * + * @deprecated use {@link graphql.schema.GraphQLCodeRegistry} instead */ + @Deprecated(since = "2018-12-03") public Builder dataFetcher(DataFetcher dataFetcher) { assertNotNull(dataFetcher, "dataFetcher must be not null"); this.dataFetcherFactory = DataFetcherFactories.useDataFetcher(dataFetcher); @@ -228,11 +321,14 @@ public Builder dataFetcher(DataFetcher dataFetcher) { /** * Sets the {@link graphql.schema.DataFetcherFactory} to use with this field. * - * @param dataFetcherFactory the factory to use + * @param dataFetcherFactory the data fetcher factory * * @return this builder + * + * @deprecated use {@link graphql.schema.GraphQLCodeRegistry} instead */ - public Builder dataFetcherFactory(DataFetcherFactory dataFetcherFactory) { + @Deprecated(since = "2018-12-03") + public Builder dataFetcherFactory(DataFetcherFactory dataFetcherFactory) { assertNotNull(dataFetcherFactory, "dataFetcherFactory must be not null"); this.dataFetcherFactory = dataFetcherFactory; return this; @@ -244,7 +340,10 @@ public Builder dataFetcherFactory(DataFetcherFactory dataFetcherFactory) { * @param value the value to always return * * @return this builder + * + * @deprecated use {@link graphql.schema.GraphQLCodeRegistry} instead */ + @Deprecated(since = "2018-12-03") public Builder staticValue(final Object value) { this.dataFetcherFactory = DataFetcherFactories.useDataFetcher(environment -> value); return this; @@ -288,7 +387,28 @@ public Builder argument(GraphQLArgument.Builder builder) { return this; } + /** + * This adds the list of arguments to the field. + * + * @param arguments the arguments to add + * + * @return this + * + * @deprecated This is a badly named method and is replaced by {@link #arguments(java.util.List)} + */ + @Deprecated(since = "2019-02-06") public Builder argument(List arguments) { + return arguments(arguments); + } + + /** + * This adds the list of arguments to the field. + * + * @param arguments the arguments to add + * + * @return this + */ + public Builder arguments(List arguments) { assertNotNull(arguments, "arguments can't be null"); for (GraphQLArgument argument : arguments) { argument(argument); @@ -296,6 +416,15 @@ public Builder argument(List arguments) { return this; } + public Builder replaceArguments(List arguments) { + assertNotNull(arguments, "arguments can't be null"); + this.arguments.clear(); + for (GraphQLArgument argument : arguments) { + argument(argument); + } + return this; + } + /** * This is used to clear all the arguments in the builder so far. * @@ -312,40 +441,54 @@ public Builder deprecate(String deprecationReason) { return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override public Builder withDirectives(GraphQLDirective... directives) { - assertNotNull(directives, "directives can't be null"); - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLFieldDefinition build() { - if (dataFetcherFactory == null) { - dataFetcherFactory = DataFetcherFactories.useDataFetcher(new PropertyDataFetcher<>(name)); - } - return new GraphQLFieldDefinition(name, description, type, dataFetcherFactory, - valuesToList(arguments), deprecationReason, valuesToList(directives), definition); + return new GraphQLFieldDefinition( + name, + description, + type, + dataFetcherFactory, + sort(arguments, GraphQLFieldDefinition.class, GraphQLArgument.class), + deprecationReason, + sort(directives, GraphQLFieldDefinition.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + definition); } } } diff --git a/src/main/java/graphql/schema/GraphQLFieldsContainer.java b/src/main/java/graphql/schema/GraphQLFieldsContainer.java index e7a779c80f..449fb78f22 100644 --- a/src/main/java/graphql/schema/GraphQLFieldsContainer.java +++ b/src/main/java/graphql/schema/GraphQLFieldsContainer.java @@ -17,4 +17,12 @@ public interface GraphQLFieldsContainer extends GraphQLCompositeType { GraphQLFieldDefinition getFieldDefinition(String name); List getFieldDefinitions(); + + default GraphQLFieldDefinition getField(String name) { + return getFieldDefinition(name); + } + + default List getFields() { + return getFieldDefinitions(); + } } diff --git a/src/main/java/graphql/schema/GraphQLImplementingType.java b/src/main/java/graphql/schema/GraphQLImplementingType.java new file mode 100644 index 0000000000..f8d394567f --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLImplementingType.java @@ -0,0 +1,18 @@ +package graphql.schema; + +import graphql.PublicApi; + +import java.util.List; + +/** + * A GraphQLType which can implement interfaces + */ +@PublicApi +public interface GraphQLImplementingType extends GraphQLFieldsContainer { + /** + * @return This returns GraphQLInterface or GraphQLTypeReference instances, if the type + * references are not resolved yet. After they are resolved it contains only GraphQLInterface. + * Reference resolving happens when a full schema is built. + */ + List getInterfaces(); +} diff --git a/src/main/java/graphql/schema/GraphQLInputFieldsContainer.java b/src/main/java/graphql/schema/GraphQLInputFieldsContainer.java index 73264c8205..bac018bdf9 100644 --- a/src/main/java/graphql/schema/GraphQLInputFieldsContainer.java +++ b/src/main/java/graphql/schema/GraphQLInputFieldsContainer.java @@ -10,7 +10,7 @@ * @see graphql.schema.GraphQLInputType */ @PublicApi -public interface GraphQLInputFieldsContainer extends GraphQLType { +public interface GraphQLInputFieldsContainer extends GraphQLNamedType { GraphQLInputObjectField getFieldDefinition(String name); diff --git a/src/main/java/graphql/schema/GraphQLInputObjectField.java b/src/main/java/graphql/schema/GraphQLInputObjectField.java index a25c7b1de8..23323393b8 100644 --- a/src/main/java/graphql/schema/GraphQLInputObjectField.java +++ b/src/main/java/graphql/schema/GraphQLInputObjectField.java @@ -1,66 +1,75 @@ package graphql.schema; -import graphql.Internal; +import graphql.DirectivesUtil; +import graphql.GraphQLContext; import graphql.PublicApi; import graphql.language.InputValueDefinition; +import graphql.language.Value; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import org.jspecify.annotations.NonNull; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; -import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; -import static java.util.Collections.emptyList; +import static graphql.execution.ValuesResolver.getInputValueImpl; /** - * Input objects defined via {@link graphql.schema.GraphQLInputObjectType} contains these input fields. + * Input objects defined via {@link GraphQLInputObjectType} contains these input fields. * - * There are similar to {@link graphql.schema.GraphQLFieldDefinition} however they can ONLY be used on input objects, that + * There are similar to {@link GraphQLFieldDefinition} however they can ONLY be used on input objects, that * is to describe values that are fed into a graphql mutation. * - * See http://graphql.org/learn/schema/#input-types for more details on the concept. + * See https://graphql.org/learn/schema/#input-types for more details on the concept. */ @PublicApi -public class GraphQLInputObjectField implements GraphQLDirectiveContainer { +public class GraphQLInputObjectField implements GraphQLNamedSchemaElement, GraphQLInputValueDefinition { private final String name; private final String description; - private GraphQLInputType type; - private final Object defaultValue; + private final GraphQLInputType originalType; + private final InputValueWithState defaultValue; + + private final String deprecationReason; private final InputValueDefinition definition; - private final List directives; + private final DirectivesUtil.DirectivesHolder directivesHolder; - @Internal - public GraphQLInputObjectField(String name, GraphQLInputType type) { - this(name, null, type, null, emptyList(), null); - } + private GraphQLInputType replacedType; + + public static final String CHILD_TYPE = "type"; - @Internal - public GraphQLInputObjectField(String name, String description, GraphQLInputType type, Object defaultValue) { - this(name, description, type, defaultValue, emptyList(), null); - } - @Internal - public GraphQLInputObjectField(String name, String description, GraphQLInputType type, Object defaultValue, List directives, InputValueDefinition definition) { + private GraphQLInputObjectField( + String name, + String description, + GraphQLInputType type, + InputValueWithState defaultValue, + List directives, + List appliedDirectives, + InputValueDefinition definition, + String deprecationReason) { assertValidName(name); assertNotNull(type, "type can't be null"); assertNotNull(directives, "directives cannot be null"); this.name = name; - this.type = type; + this.originalType = type; this.defaultValue = defaultValue; this.description = description; - this.directives = directives; + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); this.definition = definition; + this.deprecationReason = deprecationReason; } - void replaceTypeReferences(Map typeMap) { - type = (GraphQLInputType) new SchemaUtil().resolveTypeReference(type, typeMap); + void replaceType(GraphQLInputType type) { + this.replacedType = type; } @Override @@ -69,24 +78,94 @@ public String getName() { } public GraphQLInputType getType() { - return type; + return replacedType != null ? replacedType : originalType; } - public Object getDefaultValue() { + /** + * The default value of this input field. + * + * The semantics of the returned Object depend on how the {@link InputValueWithState} was created. + * + * @return a input value with captured state + */ + public @NonNull InputValueWithState getInputFieldDefaultValue() { return defaultValue; } + /** + * This static helper method will give out a java value based on the semantics captured + * in the {@link InputValueWithState} from {@link GraphQLInputObjectField#getInputFieldDefaultValue()} + * + * Note : You MUST only call this on a {@link GraphQLInputObjectField} that is part of a fully formed schema. We need + * all of the types to be resolved in order for this work correctly. + * + * Note: This method will return null if the value is not set or explicitly set to null. If you you to know the difference + * when "not set" and "set to null" then you cant use this method. Rather you should use {@link GraphQLInputObjectField#getInputFieldDefaultValue()} + * and use the {@link InputValueWithState#isNotSet()} methods to decide how to handle those values. + * + * @param inputObjectField the fully formed {@link GraphQLInputObjectField} + * @param the type you want it cast as + * + * @return a value of type T which is the java value of the input field default + */ + public static T getInputFieldDefaultValue(GraphQLInputObjectField inputObjectField) { + return getInputValueImpl(inputObjectField.getType(), inputObjectField.getInputFieldDefaultValue(), GraphQLContext.getDefault(), Locale.getDefault()); + } + + + public boolean hasSetDefaultValue() { + return defaultValue.isSet(); + } + public String getDescription() { return description; } + public String getDeprecationReason() { + return deprecationReason; + } + + public boolean isDeprecated() { + return deprecationReason != null; + } + public InputValueDefinition getDefinition() { return definition; } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } /** @@ -103,6 +182,81 @@ public GraphQLInputObjectField transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newInputObjectField(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLInputObjectField(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(); + children.add(getType()); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .child(CHILD_TYPE, originalType) + .build(); + } + + @Override + public GraphQLInputObjectField withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.type((GraphQLInputType) newChildren.getChildOrNull(CHILD_TYPE)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + + @Override + public String toString() { + return "GraphQLInputObjectField{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", originalType=" + inputTypeToStringAvoidingCircularReference(originalType) + + ", defaultValue=" + defaultValue + + ", definition=" + definition + + ", directives=" + directivesHolder + + ", replacedType=" + inputTypeToStringAvoidingCircularReference(replacedType) + + '}'; + } + + private static Object inputTypeToStringAvoidingCircularReference(GraphQLInputType graphQLInputType) { + return (graphQLInputType instanceof GraphQLInputObjectType) + ? String.format("[%s]", GraphQLInputObjectType.class.getSimpleName()) + : graphQLInputType; + } + public static Builder newInputObjectField(GraphQLInputObjectField existing) { return new Builder(existing); } @@ -113,13 +267,13 @@ public static Builder newInputObjectField() { } @PublicApi - public static class Builder { - private String name; - private String description; - private Object defaultValue; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { + private InputValueWithState defaultValue = InputValueWithState.NOT_SET; private GraphQLInputType type; private InputValueDefinition definition; - private final Map directives = new LinkedHashMap<>(); + private String deprecationReason; + public Builder() { } @@ -127,24 +281,20 @@ public Builder() { public Builder(GraphQLInputObjectField existing) { this.name = existing.getName(); this.description = existing.getDescription(); - this.defaultValue = existing.getDefaultValue(); - this.type = existing.getType(); + this.defaultValue = existing.getInputFieldDefaultValue(); + this.type = existing.originalType; this.definition = existing.getDefinition(); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); - } - - public Builder name(String name) { - this.name = name; - return this; + this.deprecationReason = existing.deprecationReason; + copyExistingDirectives(existing); } - public Builder description(String description) { - this.description = description; + public Builder definition(InputValueDefinition definition) { + this.definition = definition; return this; } - public Builder definition(InputValueDefinition definition) { - this.definition = definition; + public Builder deprecate(String deprecationReason) { + this.deprecationReason = deprecationReason; return this; } @@ -157,41 +307,84 @@ public Builder type(GraphQLInputType type) { return this; } + /** + * A legacy method for setting a default value + * + * @param defaultValue the value to set + * + * @return this builder + * + * @deprecated use {@link #defaultValueLiteral(Value)} + */ + @Deprecated(since = "2021-05-10") public Builder defaultValue(Object defaultValue) { - this.defaultValue = defaultValue; + this.defaultValue = InputValueWithState.newInternalValue(defaultValue); return this; } - public Builder withDirectives(GraphQLDirective... directives) { - assertNotNull(directives, "directives can't be null"); - for (GraphQLDirective directive : directives) { - withDirective(directive); - } + public Builder defaultValueLiteral(Value defaultValue) { + this.defaultValue = InputValueWithState.newLiteralValue(defaultValue); return this; } - public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); + public Builder defaultValueProgrammatic(Object defaultValue) { + this.defaultValue = InputValueWithState.newExternalValue(defaultValue); + return this; + } + + public Builder clearDefaultValue() { + this.defaultValue = InputValueWithState.NOT_SET; return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override + public Builder withDirectives(GraphQLDirective... directives) { + return super.withDirectives(directives); + } + + @Override + public Builder withDirective(GraphQLDirective directive) { + return super.withDirective(directive); + } + + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLInputObjectField build() { - return new GraphQLInputObjectField(name, description, type, defaultValue, valuesToList(directives), definition); + assertNotNull(type, "type can't be null"); + return new GraphQLInputObjectField( + name, + description, + type, + defaultValue, + sort(directives, GraphQLInputObjectField.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + definition, + deprecationReason); } } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/schema/GraphQLInputObjectType.java b/src/main/java/graphql/schema/GraphQLInputObjectType.java index e5abbaf340..95ac38adef 100644 --- a/src/main/java/graphql/schema/GraphQLInputObjectType.java +++ b/src/main/java/graphql/schema/GraphQLInputObjectType.java @@ -1,45 +1,60 @@ package graphql.schema; -import graphql.AssertException; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.Directives; +import graphql.DirectivesUtil; +import graphql.ExperimentalApi; import graphql.Internal; import graphql.PublicApi; import graphql.language.InputObjectTypeDefinition; +import graphql.language.InputObjectTypeExtensionDefinition; +import graphql.util.FpKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import java.util.function.UnaryOperator; import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertValidName; +import static graphql.collect.ImmutableKit.emptyList; import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; -import static java.util.Collections.emptyList; /** * graphql clearly delineates between the types of objects that represent the output of a query and input objects that * can be fed into a graphql mutation. You can define objects as input to graphql via this class - * - * See http://graphql.org/learn/schema/#input-types for more details on the concept + *

+ * See https://graphql.org/learn/schema/#input-types for more details on the concept */ @PublicApi -public class GraphQLInputObjectType implements GraphQLType, GraphQLInputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLInputFieldsContainer, GraphQLDirectiveContainer { +public class GraphQLInputObjectType implements GraphQLNamedInputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLInputFieldsContainer, GraphQLDirectiveContainer { private final String name; + private final boolean isOneOf; private final String description; - private final Map fieldMap = new LinkedHashMap<>(); + private final ImmutableMap fieldMap; private final InputObjectTypeDefinition definition; - private final List directives; + private final ImmutableList extensionDefinitions; + private final DirectivesUtil.DirectivesHolder directives; - @Internal - public GraphQLInputObjectType(String name, String description, List fields) { - this(name, description, fields, emptyList(), null); - } + public static final String CHILD_FIELD_DEFINITIONS = "fieldDefinitions"; @Internal - public GraphQLInputObjectType(String name, String description, List fields, List directives, InputObjectTypeDefinition definition) { + private GraphQLInputObjectType(String name, + String description, + List fields, + List directives, + List appliedDirectives, + InputObjectTypeDefinition definition, + List extensionDefinitions) { assertValidName(name); assertNotNull(fields, "fields can't be null"); assertNotNull(directives, "directives cannot be null"); @@ -47,17 +62,23 @@ public GraphQLInputObjectType(String name, String description, List buildDefinitionMap(List fieldDefinitions) { + return ImmutableMap.copyOf(FpKit.getByName(fieldDefinitions, GraphQLInputObjectField::getName, + (fld1, fld2) -> assertShouldNeverHappen("Duplicated definition for field '%s' in type '%s'", fld1.getName(), this.name))); } - private void buildMap(List fields) { - for (GraphQLInputObjectField field : fields) { - String name = field.getName(); - if (fieldMap.containsKey(name)) - throw new AssertException("field " + name + " redefined"); - fieldMap.put(name, field); + private boolean hasOneOf(List directives, List appliedDirectives) { + if (appliedDirectives.stream().anyMatch(d -> Directives.OneOfDirective.getName().equals(d.getName()))) { + return true; } + // eventually GraphQLDirective as applied directive goes away + return directives.stream().anyMatch(d -> Directives.OneOfDirective.getName().equals(d.getName())); } @Override @@ -65,12 +86,26 @@ public String getName() { return name; } + + /** + * An Input Object is considered a OneOf Input Object if it has the `@oneOf` directive applied to it. + *

+ * This API is currently considered experimental since the graphql specification has not yet ratified + * this approach. + * + * @return true if it's a OneOf Input Object + */ + @ExperimentalApi + public boolean isOneOf() { + return isOneOf; + } + public String getDescription() { return description; } public List getFields() { - return new ArrayList<>(fieldMap.values()); + return getFieldDefinitions(); } public GraphQLInputObjectField getField(String name) { @@ -79,7 +114,37 @@ public GraphQLInputObjectField getField(String name) { @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directives.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directives.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directives.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directives.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directives.getAppliedDirective(directiveName); } @Override @@ -89,13 +154,18 @@ public GraphQLInputObjectField getFieldDefinition(String name) { @Override public List getFieldDefinitions() { - return new ArrayList<>(fieldMap.values()); + ImmutableCollection values = fieldMap.values(); + return values instanceof ImmutableList ? (ImmutableList) values : ImmutableList.copyOf(values); } public InputObjectTypeDefinition getDefinition() { return definition; } + public List getExtensionDefinitions() { + return extensionDefinitions; + } + /** * This helps you transform the current GraphQLInputObjectType into another one by starting a builder with all * the current values and allows you to transform it how you want. @@ -110,6 +180,71 @@ public GraphQLInputObjectType transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newInputObject(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLInputObjectType(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(fieldMap.values()); + children.addAll(directives.getDirectives()); + children.addAll(directives.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_FIELD_DEFINITIONS, fieldMap.values()) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directives.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLInputObjectType withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceFields(newChildren.getChildren(CHILD_FIELD_DEFINITIONS)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + + @Override + public String toString() { + return "GraphQLInputObjectType{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", fieldMap=" + fieldMap + + ", definition=" + definition + + ", directives=" + directives + + '}'; + } + public static Builder newInputObject(GraphQLInputObjectType existing) { return new Builder(existing); } @@ -119,12 +254,11 @@ public static Builder newInputObject() { } @PublicApi - public static class Builder { - private String name; - private String description; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { private InputObjectTypeDefinition definition; + private List extensionDefinitions = emptyList(); private final Map fields = new LinkedHashMap<>(); - private final Map directives = new LinkedHashMap<>(); public Builder() { } @@ -133,22 +267,18 @@ public Builder(GraphQLInputObjectType existing) { this.name = existing.getName(); this.description = existing.getDescription(); this.definition = existing.getDefinition(); + this.extensionDefinitions = existing.getExtensionDefinitions(); this.fields.putAll(getByName(existing.getFields(), GraphQLInputObjectField::getName)); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); + copyExistingDirectives(existing); } - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder description(String description) { - this.description = description; + public Builder definition(InputObjectTypeDefinition definition) { + this.definition = definition; return this; } - public Builder definition(InputObjectTypeDefinition definition) { - this.definition = definition; + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; return this; } @@ -195,6 +325,12 @@ public Builder fields(List fields) { return this; } + public Builder replaceFields(List fields) { + this.fields.clear(); + fields.forEach(this::field); + return this; + } + public boolean hasField(String fieldName) { return fields.containsKey(fieldName); } @@ -209,35 +345,52 @@ public Builder clearFields() { return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override public Builder withDirectives(GraphQLDirective... directives) { - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLInputObjectType build() { - return new GraphQLInputObjectType(name, description, valuesToList(fields), valuesToList(directives), definition); + return new GraphQLInputObjectType( + name, + description, + sort(fields, GraphQLInputObjectType.class, GraphQLInputObjectField.class), + sort(directives, GraphQLInputObjectType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLInputObjectType.class, GraphQLAppliedDirective.class), + definition, + extensionDefinitions); } } } diff --git a/src/main/java/graphql/schema/GraphQLInputSchemaElement.java b/src/main/java/graphql/schema/GraphQLInputSchemaElement.java new file mode 100644 index 0000000000..86b5b620f1 --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLInputSchemaElement.java @@ -0,0 +1,10 @@ +package graphql.schema; + +import graphql.PublicApi; + +/** + * A schema element that is concerned with input. + */ +@PublicApi +public interface GraphQLInputSchemaElement extends GraphQLSchemaElement { +} diff --git a/src/main/java/graphql/schema/GraphQLInputType.java b/src/main/java/graphql/schema/GraphQLInputType.java index 4999cbe4fe..46fcf91301 100644 --- a/src/main/java/graphql/schema/GraphQLInputType.java +++ b/src/main/java/graphql/schema/GraphQLInputType.java @@ -8,5 +8,5 @@ * to {@link graphql.schema.GraphQLOutputType}s which can only be used as graphql response output. */ @PublicApi -public interface GraphQLInputType extends GraphQLType { +public interface GraphQLInputType extends GraphQLType, GraphQLInputSchemaElement { } diff --git a/src/main/java/graphql/schema/GraphQLInputValueDefinition.java b/src/main/java/graphql/schema/GraphQLInputValueDefinition.java new file mode 100644 index 0000000000..bce4e31fa5 --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLInputValueDefinition.java @@ -0,0 +1,17 @@ +package graphql.schema; + +import graphql.PublicApi; + +/** + * Named schema elements that contain input type information. + * + * + * @see graphql.schema.GraphQLInputType + * @see graphql.schema.GraphQLInputObjectField + * @see graphql.schema.GraphQLArgument + */ +@PublicApi +public interface GraphQLInputValueDefinition extends GraphQLDirectiveContainer, GraphQLInputSchemaElement { + + T getType(); +} diff --git a/src/main/java/graphql/schema/GraphQLInterfaceType.java b/src/main/java/graphql/schema/GraphQLInterfaceType.java index b800ce15d2..eba21cc9aa 100644 --- a/src/main/java/graphql/schema/GraphQLInterfaceType.java +++ b/src/main/java/graphql/schema/GraphQLInterfaceType.java @@ -1,71 +1,89 @@ package graphql.schema; -import graphql.AssertException; +import com.google.common.collect.ImmutableList; +import graphql.Assert; +import graphql.DirectivesUtil; import graphql.Internal; import graphql.PublicApi; import graphql.language.InterfaceTypeDefinition; +import graphql.language.InterfaceTypeExtensionDefinition; +import graphql.util.FpKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; -import java.util.Collections; +import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import java.util.function.UnaryOperator; import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertValidName; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.schema.GraphqlTypeComparators.sortTypes; import static graphql.util.FpKit.getByName; import static graphql.util.FpKit.valuesToList; -import static java.lang.String.format; /** * In graphql, an interface is an abstract type that defines the set of fields that a type must include to * implement that interface. - * - * At runtime a {@link graphql.schema.TypeResolver} is used to take an interface object value and decide what {@link graphql.schema.GraphQLObjectType} + *

+ * At runtime a {@link TypeResolver} is used to take an interface object value and decide what {@link GraphQLObjectType} * represents this interface type. - * - * - * See http://graphql.org/learn/schema/#interfaces for more details on the concept. + *

+ * See https://graphql.org/learn/schema/#interfaces for more details on the concept. */ @PublicApi -public class GraphQLInterfaceType implements GraphQLType, GraphQLOutputType, GraphQLFieldsContainer, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { +public class GraphQLInterfaceType implements GraphQLNamedType, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer, GraphQLImplementingType { private final String name; private final String description; - private final Map fieldDefinitionsByName = new LinkedHashMap<>(); + private final Map fieldDefinitionsByName; private final TypeResolver typeResolver; private final InterfaceTypeDefinition definition; - private final List directives; + private final ImmutableList extensionDefinitions; + private final DirectivesUtil.DirectivesHolder directivesHolder; - @Internal - public GraphQLInterfaceType(String name, String description, List fieldDefinitions, TypeResolver typeResolver) { - this(name, description, fieldDefinitions, typeResolver, Collections.emptyList(), null); - } + private final ImmutableList originalInterfaces; + private final Comparator interfaceComparator; + private ImmutableList replacedInterfaces; + + public static final String CHILD_FIELD_DEFINITIONS = "fieldDefinitions"; + public static final String CHILD_INTERFACES = "interfaces"; @Internal - public GraphQLInterfaceType(String name, String description, List fieldDefinitions, TypeResolver typeResolver, List directives, InterfaceTypeDefinition definition) { + private GraphQLInterfaceType(String name, + String description, + List fieldDefinitions, + TypeResolver typeResolver, + List directives, + List appliedDirectives, + InterfaceTypeDefinition definition, + List extensionDefinitions, + List interfaces, + Comparator interfaceComparator) { assertValidName(name); - assertNotNull(typeResolver, "typeResolver can't null"); assertNotNull(fieldDefinitions, "fieldDefinitions can't null"); assertNotNull(directives, "directives cannot be null"); this.name = name; this.description = description; - buildDefinitionMap(fieldDefinitions); this.typeResolver = typeResolver; this.definition = definition; - this.directives = directives; + this.interfaceComparator = interfaceComparator; + this.originalInterfaces = ImmutableList.copyOf(sortTypes(interfaceComparator, interfaces)); + this.extensionDefinitions = ImmutableList.copyOf(extensionDefinitions); + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); + this.fieldDefinitionsByName = buildDefinitionMap(fieldDefinitions); } - private void buildDefinitionMap(List fieldDefinitions) { - for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { - String name = fieldDefinition.getName(); - if (fieldDefinitionsByName.containsKey(name)) - throw new AssertException(format("Duplicated definition for field '%s' in interface '%s'", name, this.name)); - fieldDefinitionsByName.put(name, fieldDefinition); - } + private Map buildDefinitionMap(List fieldDefinitions) { + return FpKit.getByName(fieldDefinitions, GraphQLFieldDefinition::getName, + (fld1, fld2) -> assertShouldNeverHappen("Duplicated definition for field '%s' in interface '%s'", fld1.getName(), this.name)); } @Override @@ -73,10 +91,9 @@ public GraphQLFieldDefinition getFieldDefinition(String name) { return fieldDefinitionsByName.get(name); } - @Override public List getFieldDefinitions() { - return new ArrayList<>(fieldDefinitionsByName.values()); + return ImmutableList.copyOf(fieldDefinitionsByName.values()); } @Override @@ -88,7 +105,10 @@ public String getDescription() { return description; } - public TypeResolver getTypeResolver() { + // to be removed in a future version when all code is in the code registry + @Internal + @Deprecated(since = "2018-12-03") + TypeResolver getTypeResolver() { return typeResolver; } @@ -96,9 +116,43 @@ public InterfaceTypeDefinition getDefinition() { return definition; } + public List getExtensionDefinitions() { + return extensionDefinitions; + } + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } @Override @@ -125,6 +179,76 @@ public GraphQLInterfaceType transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newInterface(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLInterfaceType(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(fieldDefinitionsByName.values()); + children.addAll(getInterfaces()); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_FIELD_DEFINITIONS, fieldDefinitionsByName.values()) + .children(CHILD_INTERFACES, originalInterfaces) + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLInterfaceType withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceFields(newChildren.getChildren(CHILD_FIELD_DEFINITIONS)) + .replaceInterfacesOrReferences(newChildren.getChildren(CHILD_INTERFACES)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + @Override + public List getInterfaces() { + if (replacedInterfaces != null) { + return replacedInterfaces; + } + return originalInterfaces; + } + + void replaceInterfaces(List interfaces) { + this.replacedInterfaces = ImmutableList.copyOf(sortTypes(interfaceComparator, interfaces)); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + public static Builder newInterface() { return new Builder(); } @@ -135,13 +259,13 @@ public static Builder newInterface(GraphQLInterfaceType existing) { @PublicApi - public static class Builder { - private String name; - private String description; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { private TypeResolver typeResolver; private InterfaceTypeDefinition definition; + private List extensionDefinitions = emptyList(); private final Map fields = new LinkedHashMap<>(); - private final Map directives = new LinkedHashMap<>(); + private final Map interfaces = new LinkedHashMap<>(); public Builder() { } @@ -151,22 +275,19 @@ public Builder(GraphQLInterfaceType existing) { this.description = existing.getDescription(); this.typeResolver = existing.getTypeResolver(); this.definition = existing.getDefinition(); + this.extensionDefinitions = existing.getExtensionDefinitions(); this.fields.putAll(getByName(existing.getFieldDefinitions(), GraphQLFieldDefinition::getName)); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); - } - - public Builder name(String name) { - this.name = name; - return this; + this.interfaces.putAll(getByName(existing.originalInterfaces, GraphQLNamedType::getName)); + copyExistingDirectives(existing); } - public Builder description(String description) { - this.description = description; + public Builder definition(InterfaceTypeDefinition definition) { + this.definition = definition; return this; } - public Builder definition(InterfaceTypeDefinition definition) { - this.definition = definition; + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; return this; } @@ -214,6 +335,13 @@ public Builder fields(List fieldDefinitions) { return this; } + public Builder replaceFields(List fieldDefinitions) { + assertNotNull(fieldDefinitions, "fieldDefinitions can't be null"); + this.fields.clear(); + fieldDefinitions.forEach(this::field); + return this; + } + public boolean hasField(String fieldName) { return fields.containsKey(fieldName); } @@ -228,41 +356,113 @@ public Builder clearFields() { return this; } - + /** + * @param typeResolver the type resolver + * + * @return this builder + * + * @deprecated use {@link graphql.schema.GraphQLCodeRegistry.Builder#typeResolver(GraphQLInterfaceType, TypeResolver)} instead + */ + @Deprecated(since = "2018-12-03") public Builder typeResolver(TypeResolver typeResolver) { this.typeResolver = typeResolver; return this; } - public Builder withDirectives(GraphQLDirective... directives) { - for (GraphQLDirective directive : directives) { - withDirective(directive); + public Builder replaceInterfaces(List interfaces) { + return replaceInterfacesOrReferences(interfaces); + } + + public Builder replaceInterfacesOrReferences(List interfacesOrReferences) { + assertNotNull(interfacesOrReferences, "interfaces can't be null"); + this.interfaces.clear(); + for (GraphQLNamedOutputType schemaElement : interfacesOrReferences) { + if (schemaElement instanceof GraphQLInterfaceType || schemaElement instanceof GraphQLTypeReference) { + this.interfaces.put(schemaElement.getName(), schemaElement); + } else { + Assert.assertShouldNeverHappen("Unexpected type " + (schemaElement != null ? schemaElement.getClass() : "null")); + } } return this; } - public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); + public Builder withInterface(GraphQLInterfaceType interfaceType) { + assertNotNull(interfaceType, "interfaceType can't be null"); + this.interfaces.put(interfaceType.getName(), interfaceType); return this; } + public Builder withInterface(GraphQLTypeReference reference) { + assertNotNull(reference, "reference can't be null"); + this.interfaces.put(reference.getName(), reference); + return this; + } + + public Builder withInterfaces(GraphQLInterfaceType... interfaceType) { + for (GraphQLInterfaceType type : interfaceType) { + withInterface(type); + } + return this; + } + + public Builder withInterfaces(GraphQLTypeReference... references) { + for (GraphQLTypeReference reference : references) { + withInterface(reference); + } + return this; + } + + // -- the following are repeated to avoid a binary incompatibility problem -- + + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override + public Builder withDirectives(GraphQLDirective... directives) { + return super.withDirectives(directives); + } + + @Override + public Builder withDirective(GraphQLDirective directive) { + return super.withDirective(directive); + } + + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLInterfaceType build() { - return new GraphQLInterfaceType(name, description, valuesToList(fields), typeResolver, valuesToList(directives), definition); + return new GraphQLInterfaceType( + name, + description, + sort(fields, GraphQLInterfaceType.class, GraphQLFieldDefinition.class), + typeResolver, + sort(directives, GraphQLInterfaceType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + definition, + extensionDefinitions, + valuesToList(interfaces), + getComparator(GraphQLInterfaceType.class, GraphQLInterfaceType.class) + ); } } } diff --git a/src/main/java/graphql/schema/GraphQLList.java b/src/main/java/graphql/schema/GraphQLList.java index 12dd5de2cc..053ffbd9de 100644 --- a/src/main/java/graphql/schema/GraphQLList.java +++ b/src/main/java/graphql/schema/GraphQLList.java @@ -2,19 +2,30 @@ import graphql.PublicApi; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; -import java.util.Map; +import java.util.Collections; +import java.util.List; +import java.util.Objects; import static graphql.Assert.assertNotNull; /** * A modified type that indicates there is a list of the underlying wrapped type, eg a list of strings or a list of booleans. - * - * See http://graphql.org/learn/schema/#lists-and-non-null for more details on the concept + *

+ * See https://graphql.org/learn/schema/#lists-and-non-null for more details on the concept */ @PublicApi public class GraphQLList implements GraphQLType, GraphQLInputType, GraphQLOutputType, GraphQLModifiedType, GraphQLNullableType { + + private final GraphQLType originalWrappedType; + private GraphQLType replacedWrappedType; + + public static final String CHILD_WRAPPED_TYPE = "wrappedType"; + + /** * A factory method for creating list types so that when used with static imports allows * more readable code such as @@ -28,41 +39,89 @@ public static GraphQLList list(GraphQLType wrappedType) { return new GraphQLList(wrappedType); } - private GraphQLType wrappedType; public GraphQLList(GraphQLType wrappedType) { assertNotNull(wrappedType, "wrappedType can't be null"); - this.wrappedType = wrappedType; + this.originalWrappedType = wrappedType; } @Override public GraphQLType getWrappedType() { - return wrappedType; + return replacedWrappedType != null ? replacedWrappedType : originalWrappedType; } - void replaceTypeReferences(Map typeMap) { - wrappedType = new SchemaUtil().resolveTypeReference(wrappedType, typeMap); + public GraphQLType getOriginalWrappedType() { + return originalWrappedType; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + void replaceType(GraphQLType type) { + this.replacedWrappedType = type; + } + + public boolean isEqualTo(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GraphQLList that = (GraphQLList) o; + GraphQLType wrappedType = getWrappedType(); + if (wrappedType instanceof GraphQLNonNull) { + return ((GraphQLNonNull) wrappedType).isEqualTo(that.getWrappedType()); + } + return Objects.equals(wrappedType, that.getWrappedType()); + } - return !(wrappedType != null ? !wrappedType.equals(that.wrappedType) : that.wrappedType != null); + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLList(this, context); + } + @Override + public List getChildren() { + return Collections.singletonList(getWrappedType()); } @Override - public int hashCode() { - return wrappedType != null ? wrappedType.hashCode() : 0; + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .child(CHILD_WRAPPED_TYPE, originalWrappedType) + .build(); } @Override - public String getName() { - return null; + public GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) { + return list(newChildren.getChildOrNull(CHILD_WRAPPED_TYPE)); } + + @Override + public GraphQLSchemaElement copy() { + return new GraphQLList(originalWrappedType); + } + + + @Override + public String toString() { + return GraphQLTypeUtil.simplePrint(this); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + } diff --git a/src/main/java/graphql/schema/GraphQLModifiedType.java b/src/main/java/graphql/schema/GraphQLModifiedType.java index 5bda290ee8..27e2ecc047 100644 --- a/src/main/java/graphql/schema/GraphQLModifiedType.java +++ b/src/main/java/graphql/schema/GraphQLModifiedType.java @@ -1,12 +1,15 @@ package graphql.schema; +import graphql.PublicApi; + /** * A modified type wraps another graphql type and modifies it behavior * * @see graphql.schema.GraphQLNonNull * @see graphql.schema.GraphQLList */ +@PublicApi public interface GraphQLModifiedType extends GraphQLType { GraphQLType getWrappedType(); diff --git a/src/main/java/graphql/schema/GraphQLNamedInputType.java b/src/main/java/graphql/schema/GraphQLNamedInputType.java new file mode 100644 index 0000000000..d44aeb7bab --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLNamedInputType.java @@ -0,0 +1,12 @@ +package graphql.schema; + + +import graphql.PublicApi; + +/** + * Input types represent those set of types that are allowed to be accepted as graphql mutation input, as opposed + * to {@link GraphQLOutputType}s which can only be used as graphql response output. + */ +@PublicApi +public interface GraphQLNamedInputType extends GraphQLInputType, GraphQLNamedType { +} diff --git a/src/main/java/graphql/schema/GraphQLNamedOutputType.java b/src/main/java/graphql/schema/GraphQLNamedOutputType.java new file mode 100644 index 0000000000..f93aafe84e --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLNamedOutputType.java @@ -0,0 +1,12 @@ +package graphql.schema; + + +import graphql.PublicApi; + +/** + * Output types represent those set of types that are allowed to be sent back as a graphql response, as opposed + * to {@link GraphQLInputType}s which can only be used as graphql mutation input. + */ +@PublicApi +public interface GraphQLNamedOutputType extends GraphQLOutputType, GraphQLNamedType { +} diff --git a/src/main/java/graphql/schema/GraphQLNamedSchemaElement.java b/src/main/java/graphql/schema/GraphQLNamedSchemaElement.java new file mode 100644 index 0000000000..704bc99623 --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLNamedSchemaElement.java @@ -0,0 +1,35 @@ +package graphql.schema; + +import graphql.PublicApi; +import graphql.language.Node; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +/** + * A Schema element which has a name and also a description and AST Node which it is based on. + */ +@PublicApi +public interface GraphQLNamedSchemaElement extends GraphQLSchemaElement { + + /** + * @return the name of this element. This cant be null + */ + @NonNull + String getName(); + + /** + * @return the description of this element. This can be null + */ + @Nullable + String getDescription(); + + /** + * The AST {@link Node} this schema element is based on. Is null if the GraphQLSchema + * is not based on a SDL document. + * Some elements also have additional extension Nodes. See for example {@link GraphQLObjectType#getExtensionDefinitions()} + * + * @return Node which this element is based on. Can be null. + */ + @Nullable + Node getDefinition(); +} diff --git a/src/main/java/graphql/schema/GraphQLNamedType.java b/src/main/java/graphql/schema/GraphQLNamedType.java new file mode 100644 index 0000000000..b58448d89d --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLNamedType.java @@ -0,0 +1,12 @@ +package graphql.schema; + +import graphql.PublicApi; + +/** + * A GraphQLType which is also a named element, which means it has a getName() method. + */ +@PublicApi +public interface GraphQLNamedType extends GraphQLType, GraphQLNamedSchemaElement { + + +} diff --git a/src/main/java/graphql/schema/GraphQLNonNull.java b/src/main/java/graphql/schema/GraphQLNonNull.java index 1a7d0193a7..914b38429f 100644 --- a/src/main/java/graphql/schema/GraphQLNonNull.java +++ b/src/main/java/graphql/schema/GraphQLNonNull.java @@ -2,18 +2,22 @@ import graphql.PublicApi; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; -import java.util.Map; +import java.util.Collections; +import java.util.List; +import java.util.Objects; import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; /** * A modified type that indicates there the underlying wrapped type will not be null. - * - * See http://graphql.org/learn/schema/#lists-and-non-null for more details on the concept + *

+ * See https://graphql.org/learn/schema/#lists-and-non-null for more details on the concept */ @PublicApi - public class GraphQLNonNull implements GraphQLType, GraphQLInputType, GraphQLOutputType, GraphQLModifiedType { /** @@ -29,47 +33,100 @@ public static GraphQLNonNull nonNull(GraphQLType wrappedType) { return new GraphQLNonNull(wrappedType); } - private GraphQLType wrappedType; + private final GraphQLType originalWrappedType; + private GraphQLType replacedWrappedType; + + public static final String CHILD_WRAPPED_TYPE = "wrappedType"; + public GraphQLNonNull(GraphQLType wrappedType) { assertNotNull(wrappedType, "wrappedType can't be null"); - this.wrappedType = wrappedType; + assertNonNullWrapping(wrappedType); + this.originalWrappedType = wrappedType; + } + + private void assertNonNullWrapping(GraphQLType wrappedType) { + assertTrue(!GraphQLTypeUtil.isNonNull(wrappedType), () -> + "A non null type cannot wrap an existing non null type"); } @Override public GraphQLType getWrappedType() { - return wrappedType; + return replacedWrappedType != null ? replacedWrappedType : originalWrappedType; } - void replaceTypeReferences(Map typeMap) { - wrappedType = new SchemaUtil().resolveTypeReference(wrappedType, typeMap); + public GraphQLType getOriginalWrappedType() { + return originalWrappedType; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + void replaceType(GraphQLType type) { + assertNonNullWrapping(type); + this.replacedWrappedType = type; + } + public boolean isEqualTo(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } GraphQLNonNull that = (GraphQLNonNull) o; + GraphQLType wrappedType = getWrappedType(); + if (wrappedType instanceof GraphQLList) { + return ((GraphQLList) wrappedType).isEqualTo(that.getWrappedType()); + } + return Objects.equals(wrappedType, that.getWrappedType()); + } - return !(wrappedType != null ? !wrappedType.equals(that.wrappedType) : that.wrappedType != null); + @Override + public String toString() { + return GraphQLTypeUtil.simplePrint(this); } @Override - public int hashCode() { - return wrappedType != null ? wrappedType.hashCode() : 0; + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLNonNull(this, context); } @Override - public String toString() { - return "GraphQLNonNull{" + - "wrappedType=" + wrappedType + - '}'; + public List getChildren() { + return Collections.singletonList(getWrappedType()); } @Override - public String getName() { - return null; + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .child(CHILD_WRAPPED_TYPE, originalWrappedType) + .build(); } + + @Override + public GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) { + return nonNull(newChildren.getChildOrNull(CHILD_WRAPPED_TYPE)); + } + + @Override + public GraphQLSchemaElement copy() { + return new GraphQLNonNull(originalWrappedType); + } + + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + } diff --git a/src/main/java/graphql/schema/GraphQLNullableType.java b/src/main/java/graphql/schema/GraphQLNullableType.java index 0c978823dd..584f9e0288 100644 --- a/src/main/java/graphql/schema/GraphQLNullableType.java +++ b/src/main/java/graphql/schema/GraphQLNullableType.java @@ -1,5 +1,8 @@ package graphql.schema; +import graphql.PublicApi; + +@PublicApi public interface GraphQLNullableType extends GraphQLType { } diff --git a/src/main/java/graphql/schema/GraphQLObjectType.java b/src/main/java/graphql/schema/GraphQLObjectType.java index 62f9ff9453..199c9cc009 100644 --- a/src/main/java/graphql/schema/GraphQLObjectType.java +++ b/src/main/java/graphql/schema/GraphQLObjectType.java @@ -1,83 +1,124 @@ package graphql.schema; -import graphql.AssertException; +import com.google.common.collect.ImmutableList; +import graphql.Assert; +import graphql.DirectivesUtil; import graphql.Internal; import graphql.PublicApi; import graphql.language.ObjectTypeDefinition; +import graphql.language.ObjectTypeExtensionDefinition; +import graphql.util.FpKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; +import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertValidName; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.schema.GraphqlTypeComparators.sortTypes; import static graphql.util.FpKit.getByName; import static graphql.util.FpKit.valuesToList; -import static java.lang.String.format; -import static java.util.Collections.emptyList; /** * This is the work horse type and represents an object with one or more field values that can be retrieved * by the graphql system. - * + *

* Those fields can themselves by object types and so on until you reach the leaf nodes of the type tree represented - * by {@link graphql.schema.GraphQLScalarType}s. - * - * See http://graphql.org/learn/schema/#object-types-and-fields for more details on the concept. + * by {@link GraphQLScalarType}s. + *

+ * See https://graphql.org/learn/schema/#object-types-and-fields for more details on the concept. */ @PublicApi -public class GraphQLObjectType implements GraphQLType, GraphQLOutputType, GraphQLFieldsContainer, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { - +public class GraphQLObjectType implements GraphQLNamedOutputType, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer, GraphQLImplementingType { private final String name; private final String description; - private final Map fieldDefinitionsByName = new LinkedHashMap<>(); - private List interfaces = new ArrayList<>(); - private final List directives; + private final Comparator interfaceComparator; + private final Map fieldDefinitionsByName; + private final ImmutableList originalInterfaces; + private final DirectivesUtil.DirectivesHolder directivesHolder; private final ObjectTypeDefinition definition; + private final ImmutableList extensionDefinitions; - @Internal - public GraphQLObjectType(String name, String description, List fieldDefinitions, - List interfaces) { - this(name, description, fieldDefinitions, interfaces, emptyList(), null); - } + private ImmutableList replacedInterfaces; + + public static final String CHILD_INTERFACES = "interfaces"; + public static final String CHILD_FIELD_DEFINITIONS = "fieldDefinitions"; @Internal - public GraphQLObjectType(String name, String description, List fieldDefinitions, - List interfaces, List directives, ObjectTypeDefinition definition) { + private GraphQLObjectType(String name, + String description, + List fieldDefinitions, + List interfaces, + List directives, + List appliedDirectives, + ObjectTypeDefinition definition, + List extensionDefinitions, + Comparator interfaceComparator) { assertValidName(name); assertNotNull(fieldDefinitions, "fieldDefinitions can't be null"); assertNotNull(interfaces, "interfaces can't be null"); this.name = name; this.description = description; - this.interfaces = interfaces; + this.interfaceComparator = interfaceComparator; + this.originalInterfaces = ImmutableList.copyOf(sortTypes(interfaceComparator, interfaces)); this.definition = definition; - this.directives = assertNotNull(directives); - buildDefinitionMap(fieldDefinitions); + this.extensionDefinitions = ImmutableList.copyOf(extensionDefinitions); + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); + this.fieldDefinitionsByName = buildDefinitionMap(fieldDefinitions); } - void replaceTypeReferences(Map typeMap) { - this.interfaces = this.interfaces.stream() - .map(type -> (GraphQLOutputType) new SchemaUtil().resolveTypeReference(type, typeMap)) - .collect(Collectors.toList()); + void replaceInterfaces(List interfaces) { + this.replacedInterfaces = ImmutableList.copyOf(sortTypes(interfaceComparator, interfaces)); } - private void buildDefinitionMap(List fieldDefinitions) { - for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { - String name = fieldDefinition.getName(); - if (fieldDefinitionsByName.containsKey(name)) - throw new AssertException(format("Duplicated definition for field '%s' in type '%s'", name, this.name)); - fieldDefinitionsByName.put(name, fieldDefinition); - } + private Map buildDefinitionMap(List fieldDefinitions) { + return FpKit.getByName(fieldDefinitions, GraphQLFieldDefinition::getName, + (fld1, fld2) -> assertShouldNeverHappen("Duplicated definition for field '%s' in type '%s'", fld1.getName(), this.name)); } @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } @Override @@ -87,17 +128,15 @@ public GraphQLFieldDefinition getFieldDefinition(String name) { @Override public List getFieldDefinitions() { - return new ArrayList<>(fieldDefinitionsByName.values()); + return ImmutableList.copyOf(fieldDefinitionsByName.values()); } - - /** - * @return This returns GraphQLInterface or GraphQLTypeReference instances, if the type - * references are not resolved yet. After they are resolved it contains only GraphQLInterface. - * Reference resolving happens when a full schema is built. - */ - public List getInterfaces() { - return new ArrayList<>(interfaces); + @Override + public List getInterfaces() { + if (replacedInterfaces != null) { + return replacedInterfaces; + } + return originalInterfaces; } public String getDescription() { @@ -114,13 +153,17 @@ public ObjectTypeDefinition getDefinition() { return definition; } + public List getExtensionDefinitions() { + return extensionDefinitions; + } + @Override public String toString() { return "GraphQLObjectType{" + "name='" + name + '\'' + ", description='" + description + '\'' + ", fieldDefinitionsByName=" + fieldDefinitionsByName.keySet() + - ", interfaces=" + interfaces + + ", interfaces=" + getInterfaces() + '}'; } @@ -138,6 +181,64 @@ public GraphQLObjectType transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newObject(this).build(); + } + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLObjectType(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(fieldDefinitionsByName.values()); + children.addAll(getInterfaces()); + children.addAll(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return SchemaElementChildrenContainer.newSchemaElementChildrenContainer() + .children(CHILD_FIELD_DEFINITIONS, fieldDefinitionsByName.values()) + .children(CHILD_INTERFACES, originalInterfaces) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .build(); + } + + // Spock mocking fails with the real return type GraphQLObjectType + @Override + public GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder + .replaceFields(newChildren.getChildren(CHILD_FIELD_DEFINITIONS)) + .replaceInterfaces(newChildren.getChildren(CHILD_INTERFACES)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + public static Builder newObject() { return new Builder(); } @@ -147,13 +248,12 @@ public static Builder newObject(GraphQLObjectType existing) { } @PublicApi - public static class Builder { - private String name; - private String description; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { private ObjectTypeDefinition definition; + private List extensionDefinitions = emptyList(); private final Map fields = new LinkedHashMap<>(); - private final Map interfaces = new LinkedHashMap<>(); - private final Map directives = new LinkedHashMap<>(); + private final Map interfaces = new LinkedHashMap<>(); public Builder() { } @@ -162,23 +262,19 @@ public Builder(GraphQLObjectType existing) { name = existing.getName(); description = existing.getDescription(); definition = existing.getDefinition(); + extensionDefinitions = existing.getExtensionDefinitions(); fields.putAll(getByName(existing.getFieldDefinitions(), GraphQLFieldDefinition::getName)); - interfaces.putAll(getByName(existing.getInterfaces(), GraphQLType::getName)); - directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); + interfaces.putAll(getByName(existing.originalInterfaces, GraphQLNamedType::getName)); + copyExistingDirectives(existing); } - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder description(String description) { - this.description = description; + public Builder definition(ObjectTypeDefinition definition) { + this.definition = definition; return this; } - public Builder definition(ObjectTypeDefinition definition) { - this.definition = definition; + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; return this; } @@ -226,6 +322,13 @@ public Builder fields(List fieldDefinitions) { return this; } + public Builder replaceFields(List fieldDefinitions) { + assertNotNull(fieldDefinitions, "fieldDefinitions can't be null"); + this.fields.clear(); + fieldDefinitions.forEach(this::field); + return this; + } + /** * This is used to clear all the fields in the builder so far. * @@ -247,6 +350,19 @@ public Builder withInterface(GraphQLInterfaceType interfaceType) { return this; } + public Builder replaceInterfaces(List interfaces) { + assertNotNull(interfaces, "interfaces can't be null"); + this.interfaces.clear(); + for (GraphQLNamedOutputType schemaElement : interfaces) { + if (schemaElement instanceof GraphQLInterfaceType || schemaElement instanceof GraphQLTypeReference) { + this.interfaces.put(schemaElement.getName(), schemaElement); + } else { + Assert.assertShouldNeverHappen("Unexpected type " + (schemaElement != null ? schemaElement.getClass() : "null")); + } + } + return this; + } + public Builder withInterface(GraphQLTypeReference reference) { assertNotNull(reference, "reference can't be null"); this.interfaces.put(reference.getName(), reference); @@ -277,40 +393,55 @@ public Builder clearInterfaces() { return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + @Override public Builder withDirectives(GraphQLDirective... directives) { - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); } - public GraphQLObjectType build() { - return new GraphQLObjectType(name, description, - valuesToList(fields), valuesToList(interfaces), valuesToList(directives), - definition); + @Override + public Builder name(String name) { + return super.name(name); } - } + @Override + public Builder description(String description) { + return super.description(description); + } + public GraphQLObjectType build() { + return new GraphQLObjectType( + name, + description, + sort(fields, GraphQLObjectType.class, GraphQLFieldDefinition.class), + valuesToList(interfaces), + sort(directives, GraphQLObjectType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLObjectType.class, GraphQLAppliedDirective.class), + definition, + extensionDefinitions, + getComparator(GraphQLObjectType.class, GraphQLInterfaceType.class) + ); + } + } } diff --git a/src/main/java/graphql/schema/GraphQLScalarType.java b/src/main/java/graphql/schema/GraphQLScalarType.java index ee1a160806..dbddab7510 100644 --- a/src/main/java/graphql/schema/GraphQLScalarType.java +++ b/src/main/java/graphql/schema/GraphQLScalarType.java @@ -1,21 +1,25 @@ package graphql.schema; +import com.google.common.collect.ImmutableList; +import graphql.DirectivesUtil; import graphql.Internal; import graphql.PublicApi; import graphql.language.ScalarTypeDefinition; +import graphql.language.ScalarTypeExtensionDefinition; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import org.jspecify.annotations.NullUnmarked; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; -import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; -import static java.util.Collections.emptyList; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer; /** * A scalar type is a leaf node in the graphql tree of types. This class allows you to define new scalar types. @@ -24,29 +28,35 @@ * GraphQL provides a number of built‐in scalars, but type systems can add additional scalars with semantic meaning, * for example, a GraphQL system could define a scalar called Time which, while serialized as a string, promises to * conform to ISO‐8601. When querying a field of type Time, you can then rely on the ability to parse the result with an ISO‐8601 parser and use a client‐specific primitive for time. - * - * From the spec : http://facebook.github.io/graphql/#sec-Scalars + *

+ * From the spec : https://spec.graphql.org/October2021/#sec-Scalars * - * + *

* graphql-java ships with a set of predefined scalar types via {@link graphql.Scalars} * * @see graphql.Scalars */ -public class GraphQLScalarType implements GraphQLType, GraphQLInputType, GraphQLOutputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { +@PublicApi +public class +GraphQLScalarType implements GraphQLNamedInputType, GraphQLNamedOutputType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { private final String name; private final String description; - private final Coercing coercing; + private final Coercing coercing; private final ScalarTypeDefinition definition; - private final List directives; - - @Internal - public GraphQLScalarType(String name, String description, Coercing coercing) { - this(name, description, coercing, emptyList(), null); - } + private final ImmutableList extensionDefinitions; + private final DirectivesUtil.DirectivesHolder directivesHolder; + private final String specifiedByUrl; @Internal - public GraphQLScalarType(String name, String description, Coercing coercing, List directives, ScalarTypeDefinition definition) { + private GraphQLScalarType(String name, + String description, + Coercing coercing, + List directives, + List appliedDirectives, + ScalarTypeDefinition definition, + List extensionDefinitions, + String specifiedByUrl) { assertValidName(name); assertNotNull(coercing, "coercing can't be null"); assertNotNull(directives, "directives can't be null"); @@ -55,7 +65,9 @@ public GraphQLScalarType(String name, String description, Coercing coercing, Lis this.description = description; this.coercing = coercing; this.definition = definition; - this.directives = directives; + this.directivesHolder = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); + this.extensionDefinitions = ImmutableList.copyOf(extensionDefinitions); + this.specifiedByUrl = specifiedByUrl; } @Override @@ -68,8 +80,11 @@ public String getDescription() { return description; } + public String getSpecifiedByUrl() { + return specifiedByUrl; + } - public Coercing getCoercing() { + public Coercing getCoercing() { return coercing; } @@ -77,9 +92,43 @@ public ScalarTypeDefinition getDefinition() { return definition; } + public List getExtensionDefinitions() { + return extensionDefinitions; + } + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directivesHolder.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directivesHolder.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directivesHolder.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directivesHolder.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directivesHolder.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directivesHolder.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directivesHolder.getAppliedDirective(directiveName); } @Override @@ -105,6 +154,57 @@ public GraphQLScalarType transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newScalar(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLScalarType(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(directivesHolder.getDirectives()); + children.addAll(directivesHolder.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return newSchemaElementChildrenContainer() + .children(CHILD_DIRECTIVES, directivesHolder.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directivesHolder.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLScalarType withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + public static Builder newScalar() { return new Builder(); } @@ -115,12 +215,12 @@ public static Builder newScalar(GraphQLScalarType existing) { @PublicApi - public static class Builder { - private String name; - private String description; - private Coercing coercing; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { + private Coercing coercing; private ScalarTypeDefinition definition; - private final Map directives = new LinkedHashMap<>(); + private List extensionDefinitions = emptyList(); + private String specifiedByUrl; public Builder() { } @@ -130,58 +230,77 @@ public Builder(GraphQLScalarType existing) { description = existing.getDescription(); coercing = existing.getCoercing(); definition = existing.getDefinition(); - directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); + extensionDefinitions = existing.getExtensionDefinitions(); + specifiedByUrl = existing.getSpecifiedByUrl(); + copyExistingDirectives(existing); } - public Builder name(String name) { - this.name = name; + public Builder specifiedByUrl(String specifiedByUrl) { + this.specifiedByUrl = specifiedByUrl; return this; } - public Builder description(String description) { - this.description = description; + public Builder definition(ScalarTypeDefinition definition) { + this.definition = definition; return this; } - public Builder definition(ScalarTypeDefinition definition) { - this.definition = definition; + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; return this; } - public Builder coercing(Coercing coercing) { + public Builder coercing(Coercing coercing) { this.coercing = coercing; return this; } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override public Builder withDirectives(GraphQLDirective... directives) { - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLScalarType build() { - return new GraphQLScalarType(name, description, coercing, valuesToList(directives), definition); + return new GraphQLScalarType(name, + description, + coercing, + sort(directives, GraphQLScalarType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLScalarType.class, GraphQLAppliedDirective.class), + definition, + extensionDefinitions, + specifiedByUrl); } } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/schema/GraphQLSchema.java b/src/main/java/graphql/schema/GraphQLSchema.java index 6f0ad3577d..ec272c3131 100644 --- a/src/main/java/graphql/schema/GraphQLSchema.java +++ b/src/main/java/graphql/schema/GraphQLSchema.java @@ -1,17 +1,28 @@ package graphql.schema; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import graphql.Assert; import graphql.Directives; +import graphql.DirectivesUtil; +import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.introspection.Introspection; +import graphql.language.SchemaDefinition; +import graphql.language.SchemaExtensionDefinition; +import graphql.schema.impl.GraphQLTypeCollectingVisitor; +import graphql.schema.impl.SchemaUtil; import graphql.schema.validation.InvalidSchemaException; import graphql.schema.validation.SchemaValidationError; import graphql.schema.validation.SchemaValidator; -import graphql.schema.visibility.GraphqlFieldVisibility; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -21,71 +32,252 @@ import static graphql.Assert.assertNotNull; import static graphql.Assert.assertShouldNeverHappen; import static graphql.Assert.assertTrue; -import static graphql.schema.visibility.DefaultGraphqlFieldVisibility.DEFAULT_FIELD_VISIBILITY; -import static java.lang.String.format; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.map; +import static graphql.collect.ImmutableKit.nonNullCopyOf; +import static graphql.schema.GraphqlTypeComparators.byNameAsc; +import static graphql.schema.GraphqlTypeComparators.sortTypes; import static java.util.Arrays.asList; /** * The schema represents the combined type system of the graphql engine. This is how the engine knows * what graphql queries represent what data. - * - * See http://graphql.org/learn/schema/#type-language for more details + *

+ * See https://graphql.org/learn/schema/#type-language for more details */ @PublicApi public class GraphQLSchema { - private final GraphQLObjectType queryType; private final GraphQLObjectType mutationType; private final GraphQLObjectType subscriptionType; - private final Map typeMap; - private final Set additionalTypes; - private final Set directives; - private final GraphqlFieldVisibility fieldVisibility; - private final Map> byInterface; + private final GraphQLObjectType introspectionSchemaType; + private final ImmutableSet additionalTypes; + private final GraphQLFieldDefinition introspectionSchemaField; + private final GraphQLFieldDefinition introspectionTypeField; + // we don't allow modification of "__typename" - it's a scalar + private final GraphQLFieldDefinition __typename = Introspection.TypeNameMetaFieldDef; + private final DirectivesUtil.DirectivesHolder directiveDefinitionsHolder; + private final DirectivesUtil.DirectivesHolder schemaAppliedDirectivesHolder; + + private final SchemaDefinition definition; + private final ImmutableList extensionDefinitions; + private final String description; + private final GraphQLCodeRegistry codeRegistry; + + private final ImmutableMap typeMap; + private final ImmutableMap> interfaceNameToObjectTypes; + private final ImmutableMap> interfaceNameToObjectTypeNames; + + /* + * This constructs partial GraphQL schema object which has the schema (query / mutation / subscription) trees + * in it but it does not have the collected types, code registry nor the type references replaced + * + * But it can be traversed to discover all that and filled out later via another constructor. + * + */ + @Internal + private GraphQLSchema(Builder builder) { + assertNotNull(builder.additionalTypes, "additionalTypes can't be null"); + assertNotNull(builder.queryType, "queryType can't be null"); + assertNotNull(builder.additionalDirectives, "directives can't be null"); + assertNotNull(builder.codeRegistry, "codeRegistry can't be null"); + + this.queryType = builder.queryType; + this.mutationType = builder.mutationType; + this.subscriptionType = builder.subscriptionType; + this.additionalTypes = ImmutableSet.copyOf(builder.additionalTypes); + this.introspectionSchemaType = builder.introspectionSchemaType; + this.introspectionSchemaField = Introspection.buildSchemaField(builder.introspectionSchemaType); + this.introspectionTypeField = Introspection.buildTypeField(builder.introspectionSchemaType); + this.directiveDefinitionsHolder = new DirectivesUtil.DirectivesHolder(builder.additionalDirectives, emptyList()); + this.schemaAppliedDirectivesHolder = new DirectivesUtil.DirectivesHolder(builder.schemaDirectives, builder.schemaAppliedDirectives); + this.definition = builder.definition; + this.extensionDefinitions = nonNullCopyOf(builder.extensionDefinitions); + this.description = builder.description; + + this.codeRegistry = null; + this.typeMap = ImmutableKit.emptyMap(); + this.interfaceNameToObjectTypes = ImmutableKit.emptyMap(); + this.interfaceNameToObjectTypeNames = ImmutableKit.emptyMap(); + } + /* + * This constructs a fully fledged graphql schema object that has not yet had its type references replaced + * but it's otherwise complete + */ + @Internal + public GraphQLSchema(GraphQLSchema existingSchema, + GraphQLCodeRegistry codeRegistry, + ImmutableMap typeMap, + ImmutableMap> interfaceNameToObjectTypes + ) { + assertNotNull(codeRegistry, "codeRegistry can't be null"); + + this.queryType = existingSchema.queryType; + this.mutationType = existingSchema.mutationType; + this.subscriptionType = existingSchema.subscriptionType; + this.additionalTypes = ImmutableSet.copyOf(existingSchema.additionalTypes); + this.introspectionSchemaType = existingSchema.introspectionSchemaType; + this.introspectionSchemaField = Introspection.buildSchemaField(existingSchema.introspectionSchemaType); + this.introspectionTypeField = Introspection.buildTypeField(existingSchema.introspectionSchemaType); + this.directiveDefinitionsHolder = existingSchema.directiveDefinitionsHolder; + this.schemaAppliedDirectivesHolder = existingSchema.schemaAppliedDirectivesHolder; + this.definition = existingSchema.definition; + this.extensionDefinitions = existingSchema.extensionDefinitions; + this.description = existingSchema.description; + this.codeRegistry = codeRegistry; + this.typeMap = typeMap; + this.interfaceNameToObjectTypes = interfaceNameToObjectTypes; + this.interfaceNameToObjectTypeNames = buildInterfacesToObjectName(interfaceNameToObjectTypes); + } - public GraphQLSchema(GraphQLObjectType queryType) { - this(queryType, null, Collections.emptySet()); + /* + * a constructor aimed at the simple builder - the type tree can be taken as is! + */ + @Internal + public GraphQLSchema(BuilderWithoutTypes builder) { + assertNotNull(builder.codeRegistry, "codeRegistry can't be null"); + + GraphQLSchema existingSchema = builder.existingSchema; + + this.queryType = existingSchema.queryType; + this.mutationType = existingSchema.mutationType; + this.subscriptionType = existingSchema.subscriptionType; + this.additionalTypes = existingSchema.additionalTypes; + this.introspectionSchemaType = existingSchema.introspectionSchemaType; + this.introspectionSchemaField = existingSchema.introspectionSchemaField; + this.introspectionTypeField = existingSchema.introspectionTypeField; + this.directiveDefinitionsHolder = existingSchema.directiveDefinitionsHolder; + this.schemaAppliedDirectivesHolder = existingSchema.schemaAppliedDirectivesHolder; + this.definition = existingSchema.definition; + this.extensionDefinitions = existingSchema.extensionDefinitions; + this.typeMap = existingSchema.typeMap; + this.interfaceNameToObjectTypes = existingSchema.interfaceNameToObjectTypes; + this.interfaceNameToObjectTypeNames = existingSchema.interfaceNameToObjectTypeNames; + + this.description = builder.description; + this.codeRegistry = builder.codeRegistry; } - public GraphQLSchema(GraphQLObjectType queryType, GraphQLObjectType mutationType, Set additionalTypes) { - this(queryType, mutationType, null, additionalTypes); + private static GraphQLDirective[] schemaDirectivesArray(GraphQLSchema existingSchema) { + return existingSchema.schemaAppliedDirectivesHolder.getDirectives().toArray(new GraphQLDirective[0]); } - public GraphQLSchema(GraphQLObjectType queryType, GraphQLObjectType mutationType, GraphQLObjectType subscriptionType, Set additionalTypes) { - this(queryType, mutationType, subscriptionType, additionalTypes, Collections.emptySet(), DEFAULT_FIELD_VISIBILITY); + private static GraphQLAppliedDirective[] schemaAppliedDirectivesArray(GraphQLSchema existingSchema) { + return existingSchema.schemaAppliedDirectivesHolder.getAppliedDirectives().toArray(new GraphQLAppliedDirective[0]); } - public GraphQLSchema(GraphQLObjectType queryType, GraphQLObjectType mutationType, GraphQLObjectType subscriptionType, Set additionalTypes, Set directives, GraphqlFieldVisibility fieldVisibility) { - assertNotNull(additionalTypes, "additionalTypes can't be null"); - assertNotNull(queryType, "queryType can't be null"); - assertNotNull(directives, "directives can't be null"); - assertNotNull(fieldVisibility, "fieldVisibility can't be null"); + private static List getAllTypesAsList(ImmutableMap typeMap) { + return sortTypes(byNameAsc(), typeMap.values()); + } - SchemaUtil schemaUtil = new SchemaUtil(); + private static ImmutableMap> buildInterfacesToObjectTypes(Map> groupImplementations) { + ImmutableMap.Builder> map = ImmutableMap.builder(); + for (Map.Entry> e : groupImplementations.entrySet()) { + ImmutableList sortedObjectTypes = ImmutableList.copyOf(sortTypes(byNameAsc(), e.getValue())); + map.put(e.getKey(), sortedObjectTypes); + } + return map.build(); + } - this.queryType = queryType; - this.mutationType = mutationType; - this.subscriptionType = subscriptionType; - this.fieldVisibility = fieldVisibility; - this.additionalTypes = additionalTypes; - this.directives = new LinkedHashSet<>( - asList(Directives.IncludeDirective, Directives.SkipDirective, Directives.DeferDirective) - ); - this.directives.addAll(directives); - this.typeMap = schemaUtil.allTypes(this, additionalTypes); - this.byInterface = schemaUtil.groupImplementations(this); + private static ImmutableMap> buildInterfacesToObjectName(ImmutableMap> byInterface) { + ImmutableMap.Builder> map = ImmutableMap.builder(); + for (Map.Entry> e : byInterface.entrySet()) { + ImmutableList objectTypeNames = map(e.getValue(), GraphQLObjectType::getName); + map.put(e.getKey(), objectTypeNames); + } + return map.build(); + } + + public GraphQLCodeRegistry getCodeRegistry() { + return codeRegistry; + } + + /** + * @return the special system field called "__schema" + */ + public GraphQLFieldDefinition getIntrospectionSchemaFieldDefinition() { + return introspectionSchemaField; + } + + /** + * @return the special system field called "__type" + */ + public GraphQLFieldDefinition getIntrospectionTypeFieldDefinition() { + return introspectionTypeField; + } + + /** + * @return the special system field called "__typename" + */ + public GraphQLFieldDefinition getIntrospectionTypenameFieldDefinition() { + return __typename; + } + + public GraphQLObjectType getIntrospectionSchemaType() { + return introspectionSchemaType; } public Set getAdditionalTypes() { return additionalTypes; } - public GraphQLType getType(String typeName) { + /** + * Gets the named type from the schema or null if it's not present + * + * @param typeName the name of the type to retrieve + * + * @return the type + */ + public @Nullable GraphQLType getType(@NonNull String typeName) { return typeMap.get(typeName); } + /** + * All types with the provided names. + * throws {@link graphql.AssertException} when a type name could not be resolved + * + * @param typeNames the type names to get + * @param for two + * + * @return The List of resolved types. + */ + @SuppressWarnings("unchecked") + public List getTypes(Collection typeNames) { + ImmutableList.Builder builder = ImmutableList.builder(); + for (String typeName : typeNames) { + builder.add((T) assertNotNull(typeMap.get(typeName), "No type found for name %s", typeName)); + } + return builder.build(); + } + + /** + * Gets the named type from the schema or null if it's not present. + *

+ * Warning - you are inviting class cast errors if the types are not what you expect. + * + * @param typeName the name of the type to retrieve + * @param for two + * + * @return the type cast to the target type. + */ + public T getTypeAs(String typeName) { + //noinspection unchecked + return (T) typeMap.get(typeName); + } + + /** + * Returns true if the schema contains a type with the specified name + * + * @param typeName the name of the type to check + * + * @return true if there is a type with the specified name + */ + public boolean containsType(String typeName) { + return typeMap.containsKey(typeName); + } + /** * Called to return a named {@link graphql.schema.GraphQLObjectType} from the schema * @@ -93,23 +285,76 @@ public GraphQLType getType(String typeName) { * * @return a graphql object type or null if there is one * - * @throws graphql.GraphQLException if the type is NOT a object type + * @throws graphql.GraphQLException if the type is NOT an object type */ public GraphQLObjectType getObjectType(String typeName) { GraphQLType graphQLType = typeMap.get(typeName); if (graphQLType != null) { assertTrue(graphQLType instanceof GraphQLObjectType, - format("You have asked for named object type '%s' but its not an object type but rather a '%s'", typeName, graphQLType.getClass().getName())); + "You have asked for named object type '%s' but it's not an object type but rather a '%s'", typeName, graphQLType.getClass().getName()); } return (GraphQLObjectType) graphQLType; } - public Map getTypeMap() { - return Collections.unmodifiableMap(typeMap); + /** + * Returns a {@link GraphQLFieldDefinition} as the specified co-ordinates or null + * if it does not exist + * + * @param fieldCoordinates the field co-ordinates + * + * @return the field or null if it does not exist + */ + public GraphQLFieldDefinition getFieldDefinition(FieldCoordinates fieldCoordinates) { + String fieldName = fieldCoordinates.getFieldName(); + if (fieldCoordinates.isSystemCoordinates()) { + if (fieldName.equals(this.getIntrospectionSchemaFieldDefinition().getName())) { + return this.getIntrospectionSchemaFieldDefinition(); + } + if (fieldName.equals(this.getIntrospectionTypeFieldDefinition().getName())) { + return this.getIntrospectionTypeFieldDefinition(); + } + if (fieldName.equals(this.getIntrospectionTypenameFieldDefinition().getName())) { + return this.getIntrospectionTypenameFieldDefinition(); + } + return Assert.assertShouldNeverHappen("The system field name %s is unknown", fieldName); + } + String typeName = fieldCoordinates.getTypeName(); + GraphQLType graphQLType = getType(typeName); + if (graphQLType != null) { + assertTrue(graphQLType instanceof GraphQLFieldsContainer, + "You have asked for named type '%s' but it's not GraphQLFieldsContainer but rather a '%s'", typeName, graphQLType.getClass().getName()); + return ((GraphQLFieldsContainer) graphQLType).getFieldDefinition(fieldName); + } + return null; } - public List getAllTypesAsList() { - return new ArrayList<>(typeMap.values()); + /** + * @return all the named types in the scheme as a map from name to named type + */ + public Map getTypeMap() { + return typeMap; + } + + /** + * This returns all the {@link GraphQLNamedType} named types in th schema + * + * @return all the {@link GraphQLNamedType} types in the schema + */ + public List getAllTypesAsList() { + return getAllTypesAsList(typeMap); + } + + /** + * This returns all the top level {@link GraphQLNamedSchemaElement} named types and directives + * in the schema + * + * @return all the top level {@link GraphQLNamedSchemaElement} types and directives in the schema + */ + public List getAllElementsAsList() { + List list = new ArrayList<>(); + list.addAll(getDirectives()); + list.addAll(getAllTypesAsList()); + return list; } /** @@ -121,61 +366,206 @@ public List getAllTypesAsList() { * @return list of types implementing provided interface */ public List getImplementations(GraphQLInterfaceType type) { - List implementations = byInterface.get(type.getName()); - return (implementations == null) - ? Collections.emptyList() - : Collections.unmodifiableList(implementations); + return interfaceNameToObjectTypes.getOrDefault(type.getName(), emptyList()); } /** * Returns true if a specified concrete type is a possible type of a provided abstract type. * If the provided abstract type is: - * - an interface, it checks whether the concrete type is one of its implementations. - * - a union, it checks whether the concrete type is one of its possible types. + * - an interface, it checks whether the concrete type is one of its implementations. + * - a union, it checks whether the concrete type is one of its possible types. * * @param abstractType abstract type either interface or union * @param concreteType concrete type + * * @return true if possible type, false otherwise. */ - public boolean isPossibleType(GraphQLType abstractType, GraphQLObjectType concreteType) { + public boolean isPossibleType(GraphQLNamedType abstractType, GraphQLObjectType concreteType) { if (abstractType instanceof GraphQLInterfaceType) { - return getImplementations((GraphQLInterfaceType) abstractType).stream() - .map(GraphQLType::getName) - .anyMatch(name -> concreteType.getName().equals(name)); + ImmutableList objectNames = this.interfaceNameToObjectTypeNames.getOrDefault(abstractType.getName(), emptyList()); + return objectNames.contains(concreteType.getName()); } else if (abstractType instanceof GraphQLUnionType) { - return ((GraphQLUnionType) abstractType).getTypes().stream() - .map(GraphQLType::getName) - .anyMatch(name -> concreteType.getName().equals(name)); + return ((GraphQLUnionType) abstractType).isPossibleType(concreteType); } - return assertShouldNeverHappen("Unsupported abstract type %s. Abstract types supported are Union and Interface.", abstractType.getName()); } + /** + * @return the Query type of the schema + */ public GraphQLObjectType getQueryType() { return queryType; } + /** + * @return the Mutation type of the schema of null if there is not one + */ public GraphQLObjectType getMutationType() { return mutationType; } + /** + * @return the Subscription type of the schema of null if there is not one + */ public GraphQLObjectType getSubscriptionType() { return subscriptionType; } - public GraphqlFieldVisibility getFieldVisibility() { - return fieldVisibility; + /** + * This returns the list of directives definitions that are associated with this schema object including + * built in ones. + * + * @return a list of directives + */ + public List getDirectives() { + return directiveDefinitionsHolder.getDirectives(); + } + + /** + * @return a map of non-repeatable directives by directive name + */ + public Map getDirectivesByName() { + return directiveDefinitionsHolder.getDirectivesByName(); } - public List getDirectives() { - return new ArrayList<>(directives); + /** + * Returns a named directive that (for legacy reasons) will be only in the set of non-repeatable directives + * + * @param directiveName the name of the directive to retrieve + * + * @return the directive or null if there is not one with that name + */ + public GraphQLDirective getDirective(String directiveName) { + return directiveDefinitionsHolder.getDirective(directiveName); } - public GraphQLDirective getDirective(String name) { - for (GraphQLDirective directive : getDirectives()) { - if (directive.getName().equals(name)) return directive; - } - return null; + + /** + * This returns the list of directives that have been explicitly applied to the + * schema object. Note that {@link #getDirectives()} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @return a list of directives + * + * @deprecated Use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public List getSchemaDirectives() { + return schemaAppliedDirectivesHolder.getDirectives(); + } + + /** + * This returns a map of non-repeatable directives that have been explicitly applied to the + * schema object. Note that {@link #getDirectives()} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @return a map of directives + * + * @deprecated Use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public Map getSchemaDirectiveByName() { + return schemaAppliedDirectivesHolder.getDirectivesByName(); + } + + /** + * This returns a map of non-repeatable and repeatable directives that have been explicitly applied to the + * schema object. Note that {@link #getDirectives()} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @return a map of directives + * + * @deprecated Use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public Map> getAllSchemaDirectivesByName() { + return schemaAppliedDirectivesHolder.getAllDirectivesByName(); + } + + /** + * This returns the named directive that have been explicitly applied to the + * schema object. Note that {@link graphql.schema.GraphQLDirectiveContainer#getDirective(String)} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @param directiveName the name of the directive + * + * @return a named directive + * + * @deprecated Use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public GraphQLDirective getSchemaDirective(String directiveName) { + return schemaAppliedDirectivesHolder.getDirective(directiveName); + } + + /** + * This returns the named directives that have been explicitly applied to the + * schema object. + * + * @param directiveName the name of the directive + * + * @return A list of repeated applied directives + * + * @deprecated Use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public List getSchemaDirectives(String directiveName) { + return schemaAppliedDirectivesHolder.getDirectives(directiveName); + } + + /** + * This returns the list of directives that have been explicitly applied to the + * schema object. Note that {@link #getDirectives()} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @return a list of directives + */ + public List getSchemaAppliedDirectives() { + return schemaAppliedDirectivesHolder.getAppliedDirectives(); + } + + /** + * This returns a map of non-repeatable and repeatable directives that have been explicitly applied to the + * schema object. Note that {@link #getDirectives()} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @return a map of all schema directives by directive name + */ + public Map> getAllSchemaAppliedDirectivesByName() { + return schemaAppliedDirectivesHolder.getAllAppliedDirectivesByName(); + } + + /** + * This returns the named directive that have been explicitly applied to the + * schema object. Note that {@link graphql.schema.GraphQLDirectiveContainer#getDirective(String)} will return + * directives for all schema elements, whereas this is just for the schema + * element itself + * + * @param directiveName the name of the directive + * + * @return a named directive + */ + public GraphQLAppliedDirective getSchemaAppliedDirective(String directiveName) { + return schemaAppliedDirectivesHolder.getAppliedDirective(directiveName); + } + + public List getSchemaAppliedDirectives(String directiveName) { + return schemaAppliedDirectivesHolder.getAppliedDirectives(directiveName); + } + + @Nullable + public SchemaDefinition getDefinition() { + return definition; + } + + public List getExtensionDefinitions() { + return extensionDefinitions; } public boolean isSupportingMutations() { @@ -186,13 +576,18 @@ public boolean isSupportingSubscriptions() { return subscriptionType != null; } + @Nullable + public String getDescription() { + return description; + } + /** * This helps you transform the current GraphQLSchema object into another one by starting a builder with all * the current values and allows you to transform it how you want. * * @param builderConsumer the consumer code that will be given a builder to transform * - * @return a new GraphQLSchema object based on calling build on that builder + * @return a new GraphQLSchema object based on calling built on that builder */ public GraphQLSchema transform(Consumer builderConsumer) { Builder builder = newSchema(this); @@ -200,6 +595,20 @@ public GraphQLSchema transform(Consumer builderConsumer) { return builder.build(); } + /** + * This helps you transform the current GraphQLSchema object into another one by using a builder that only allows you to change + * simple values and does not involve changing the complex schema type graph. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new GraphQLSchema object based on calling built on that builder + */ + public GraphQLSchema transformWithoutTypes(Consumer builderConsumer) { + BuilderWithoutTypes builder = new BuilderWithoutTypes(this); + builderConsumer.accept(builder); + return builder.build(); + } + /** * @return a new schema builder */ @@ -220,18 +629,66 @@ public static Builder newSchema(GraphQLSchema existingSchema) { .query(existingSchema.getQueryType()) .mutation(existingSchema.getMutationType()) .subscription(existingSchema.getSubscriptionType()) - .fieldVisibility(existingSchema.getFieldVisibility()) - .additionalDirectives(existingSchema.directives) - .additionalTypes(existingSchema.additionalTypes); + .extensionDefinitions(existingSchema.getExtensionDefinitions()) + .introspectionSchemaType(existingSchema.getIntrospectionSchemaType()) + .codeRegistry(existingSchema.getCodeRegistry()) + .clearAdditionalTypes() + .clearDirectives() + .additionalDirectives(new LinkedHashSet<>(existingSchema.getDirectives())) + .clearSchemaDirectives() + .withSchemaDirectives(schemaDirectivesArray(existingSchema)) + .withSchemaAppliedDirectives(schemaAppliedDirectivesArray(existingSchema)) + .additionalTypes(existingSchema.additionalTypes) + .description(existingSchema.getDescription()); + } + + public static class BuilderWithoutTypes { + private GraphQLCodeRegistry codeRegistry; + private String description; + private final GraphQLSchema existingSchema; + + private BuilderWithoutTypes(GraphQLSchema existingSchema) { + this.existingSchema = existingSchema; + this.codeRegistry = existingSchema.codeRegistry; + this.description = existingSchema.description; + } + + public BuilderWithoutTypes codeRegistry(GraphQLCodeRegistry codeRegistry) { + this.codeRegistry = Assert.assertNotNull(codeRegistry); + return this; + } + + public BuilderWithoutTypes codeRegistry(GraphQLCodeRegistry.Builder codeRegistryBuilder) { + return codeRegistry(codeRegistryBuilder.build()); + } + + public BuilderWithoutTypes description(String description) { + this.description = description; + return this; + } + + public GraphQLSchema build() { + return new GraphQLSchema(this); + } } public static class Builder { private GraphQLObjectType queryType; private GraphQLObjectType mutationType; + private GraphQLObjectType introspectionSchemaType = Introspection.__Schema; private GraphQLObjectType subscriptionType; - private GraphqlFieldVisibility fieldVisibility = DEFAULT_FIELD_VISIBILITY; - private Set additionalTypes = new HashSet<>(); - private Set additionalDirectives = new HashSet<>(); + private GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry().build(); + private SchemaDefinition definition; + private List extensionDefinitions; + private String description; + + // we default these in + private final Set additionalDirectives = new LinkedHashSet<>( + asList(Directives.IncludeDirective, Directives.SkipDirective) + ); + private final Set additionalTypes = new LinkedHashSet<>(); + private final List schemaDirectives = new ArrayList<>(); + private final List schemaAppliedDirectives = new ArrayList<>(); public Builder query(GraphQLObjectType.Builder builder) { return query(builder.build()); @@ -260,8 +717,8 @@ public Builder subscription(GraphQLObjectType subscriptionType) { return this; } - public Builder fieldVisibility(GraphqlFieldVisibility fieldVisibility) { - this.fieldVisibility = fieldVisibility; + public Builder codeRegistry(GraphQLCodeRegistry codeRegistry) { + this.codeRegistry = codeRegistry; return this; } @@ -275,6 +732,11 @@ public Builder additionalType(GraphQLType additionalType) { return this; } + public Builder clearAdditionalTypes() { + this.additionalTypes.clear(); + return this; + } + public Builder additionalDirectives(Set additionalDirectives) { this.additionalDirectives.addAll(additionalDirectives); return this; @@ -285,21 +747,142 @@ public Builder additionalDirective(GraphQLDirective additionalDirective) { return this; } - public GraphQLSchema build() { - return build(additionalTypes, additionalDirectives); + public Builder clearDirectives() { + this.additionalDirectives.clear(); + return this; + } + + + public Builder withSchemaDirectives(GraphQLDirective... directives) { + for (GraphQLDirective directive : directives) { + withSchemaDirective(directive); + } + return this; + } + + public Builder withSchemaDirectives(Collection directives) { + for (GraphQLDirective directive : directives) { + withSchemaDirective(directive); + } + return this; + } + + public Builder withSchemaDirective(GraphQLDirective directive) { + assertNotNull(directive, "directive can't be null"); + schemaDirectives.add(directive); + return this; + } + + public Builder withSchemaDirective(GraphQLDirective.Builder builder) { + return withSchemaDirective(builder.build()); + } + + public Builder withSchemaAppliedDirectives(GraphQLAppliedDirective... appliedDirectives) { + for (GraphQLAppliedDirective directive : appliedDirectives) { + withSchemaAppliedDirective(directive); + } + return this; + } + + public Builder withSchemaAppliedDirectives(Collection appliedDirectives) { + for (GraphQLAppliedDirective directive : appliedDirectives) { + withSchemaAppliedDirective(directive); + } + return this; + } + + public Builder withSchemaAppliedDirective(GraphQLAppliedDirective appliedDirective) { + assertNotNull(appliedDirective, "directive can't be null"); + schemaAppliedDirectives.add(appliedDirective); + return this; + } + + public Builder withSchemaAppliedDirective(GraphQLAppliedDirective.Builder builder) { + return withSchemaAppliedDirective(builder.build()); } - public GraphQLSchema build(Set additionalTypes) { - return build(additionalTypes, Collections.emptySet()); + /** + * This is used to clear all the directives in the builder so far. + * + * @return the builder + */ + public Builder clearSchemaDirectives() { + schemaDirectives.clear(); + schemaAppliedDirectives.clear(); + return this; } - public GraphQLSchema build(Set additionalTypes, Set additionalDirectives) { + public Builder definition(SchemaDefinition definition) { + this.definition = definition; + return this; + } + + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder introspectionSchemaType(GraphQLObjectType introspectionSchemaType) { + this.introspectionSchemaType = introspectionSchemaType; + return this; + } + + /** + * Builds the schema + * + * @return the built schema + */ + public GraphQLSchema build() { + return buildImpl(); + } + + private GraphQLSchema buildImpl() { assertNotNull(additionalTypes, "additionalTypes can't be null"); assertNotNull(additionalDirectives, "additionalDirectives can't be null"); - GraphQLSchema graphQLSchema = new GraphQLSchema(queryType, mutationType, subscriptionType, additionalTypes, additionalDirectives, fieldVisibility); - new SchemaUtil().replaceTypeReferences(graphQLSchema); + + // schemas built via the schema generator have the deprecated directive BUT we want it present for hand built + // schemas - it's inherently part of the spec! + addBuiltInDirective(Directives.DeprecatedDirective, additionalDirectives); + addBuiltInDirective(Directives.SpecifiedByDirective, additionalDirectives); + addBuiltInDirective(Directives.OneOfDirective, additionalDirectives); + addBuiltInDirective(Directives.DeferDirective, additionalDirectives); + addBuiltInDirective(Directives.ExperimentalDisableErrorPropagationDirective, additionalDirectives); + + // quick build - no traversing + final GraphQLSchema partiallyBuiltSchema = new GraphQLSchema(this); + + GraphQLCodeRegistry.Builder extractedDataFetchers = GraphQLCodeRegistry.newCodeRegistry(codeRegistry); + CodeRegistryVisitor codeRegistryVisitor = new CodeRegistryVisitor(extractedDataFetchers); + GraphQLTypeCollectingVisitor typeCollectingVisitor = new GraphQLTypeCollectingVisitor(); + SchemaUtil.visitPartiallySchema(partiallyBuiltSchema, codeRegistryVisitor, typeCollectingVisitor); + + codeRegistry = extractedDataFetchers.build(); + ImmutableMap allTypes = typeCollectingVisitor.getResult(); + List allTypesAsList = getAllTypesAsList(allTypes); + + ImmutableMap> groupedImplementations = SchemaUtil.groupInterfaceImplementationsByName(allTypesAsList); + ImmutableMap> interfaceNameToObjectTypes = buildInterfacesToObjectTypes(groupedImplementations); + + // this is now build however its contained types are still to be mutated by type reference replacement + final GraphQLSchema finalSchema = new GraphQLSchema(partiallyBuiltSchema, codeRegistry, allTypes, interfaceNameToObjectTypes); + SchemaUtil.replaceTypeReferences(finalSchema); + return validateSchema(finalSchema); + } + + private void addBuiltInDirective(GraphQLDirective qlDirective, Set additionalDirectives1) { + if (additionalDirectives1.stream().noneMatch(d -> d.getName().equals(qlDirective.getName()))) { + additionalDirectives1.add(qlDirective); + } + } + + private GraphQLSchema validateSchema(GraphQLSchema graphQLSchema) { Collection errors = new SchemaValidator().validateSchema(graphQLSchema); - if (errors.size() > 0) { + if (!errors.isEmpty()) { throw new InvalidSchemaException(errors); } return graphQLSchema; diff --git a/src/main/java/graphql/schema/GraphQLSchemaElement.java b/src/main/java/graphql/schema/GraphQLSchemaElement.java new file mode 100644 index 0000000000..df6a15cc0e --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLSchemaElement.java @@ -0,0 +1,60 @@ +package graphql.schema; + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.List; + +import static graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer; + +/** + * A GraphQLSchema can be viewed as a graph of GraphQLSchemaElement. Every node (vertex) of this graph implements + * this interface. + */ +@PublicApi +public interface GraphQLSchemaElement { + + default List getChildren() { + return ImmutableKit.emptyList(); + } + + default SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return newSchemaElementChildrenContainer().build(); + } + + default GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) { + return this; + } + + TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor); + + + /** + * No GraphQLSchemaElement implements `equals` because we need object identity + * to treat a GraphQLSchema as an abstract graph. + * + * @param obj the reference object with which to compare. + * + * @return {@code true} if this object is the same as the obj + * argument; {@code false} otherwise. + */ + boolean equals(Object obj); + + /** + * No GraphQLSchemaElement implements `equals/hashCode` because we need object identity + * to treat a GraphQLSchema as an abstract graph. + * + * @return a hash code value for this object. + */ + int hashCode(); + + /** + * Each GraphQLSchemaElement should make a copy of itself when this is called. The copy should + * be included its current contents as they currently exist into a new object. + * + * @return a copy of this element + */ + GraphQLSchemaElement copy(); +} diff --git a/src/main/java/graphql/schema/GraphQLSchemaElementAdapter.java b/src/main/java/graphql/schema/GraphQLSchemaElementAdapter.java new file mode 100644 index 0000000000..9bce889fde --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLSchemaElementAdapter.java @@ -0,0 +1,36 @@ +package graphql.schema; + +import graphql.Internal; +import graphql.util.NodeAdapter; +import graphql.util.NodeLocation; + +import java.util.List; +import java.util.Map; + +@Internal +public class GraphQLSchemaElementAdapter implements NodeAdapter { + + public static final GraphQLSchemaElementAdapter SCHEMA_ELEMENT_ADAPTER = new GraphQLSchemaElementAdapter(); + + private GraphQLSchemaElementAdapter() { + + } + + @Override + public Map> getNamedChildren(GraphQLSchemaElement node) { + return node.getChildrenWithTypeReferences().getChildren(); + } + + @Override + public GraphQLSchemaElement withNewChildren(GraphQLSchemaElement node, Map> newChildren) { + SchemaElementChildrenContainer childrenContainer = SchemaElementChildrenContainer.newSchemaElementChildrenContainer(newChildren).build(); + return node.withNewChildren(childrenContainer); + } + + @Override + public GraphQLSchemaElement removeChild(GraphQLSchemaElement node, NodeLocation location) { + SchemaElementChildrenContainer children = node.getChildrenWithTypeReferences(); + SchemaElementChildrenContainer newChildren = children.transform(builder -> builder.removeChild(location.getName(), location.getIndex())); + return node.withNewChildren(newChildren); + } +} diff --git a/src/main/java/graphql/schema/GraphQLType.java b/src/main/java/graphql/schema/GraphQLType.java index 0b3f3a67cd..e47ed46a2e 100644 --- a/src/main/java/graphql/schema/GraphQLType.java +++ b/src/main/java/graphql/schema/GraphQLType.java @@ -4,12 +4,10 @@ import graphql.PublicApi; /** - * All types in graphql have a name + * A type inside the GraphQLSchema. A type doesn't have to have name, e.g. {@link GraphQLList}. + * + * See {@link GraphQLNamedType} for types with a name. */ @PublicApi -public interface GraphQLType { - /** - * @return the name of the type which MUST fit within the regular expression {@code [_A-Za-z][_0-9A-Za-z]*} - */ - String getName(); +public interface GraphQLType extends GraphQLSchemaElement { } diff --git a/src/main/java/graphql/schema/GraphQLTypeReference.java b/src/main/java/graphql/schema/GraphQLTypeReference.java index c97a215ae2..08fb3df47a 100644 --- a/src/main/java/graphql/schema/GraphQLTypeReference.java +++ b/src/main/java/graphql/schema/GraphQLTypeReference.java @@ -2,6 +2,9 @@ import graphql.PublicApi; +import graphql.language.Node; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import static graphql.Assert.assertValidName; @@ -10,7 +13,7 @@ * object when the schema is built. */ @PublicApi -public class GraphQLTypeReference implements GraphQLType, GraphQLOutputType, GraphQLInputType { +public class GraphQLTypeReference implements GraphQLNamedOutputType, GraphQLNamedInputType { /** * A factory method for creating type references so that when used with static imports allows @@ -36,4 +39,33 @@ public GraphQLTypeReference(String name) { public String getName() { return name; } + + @Override + public String getDescription() { + return null; + } + + @Override + public Node getDefinition() { + return null; + } + + @Override + public String toString() { + return "GraphQLTypeReference{" + + "name='" + name + '\'' + + '}'; + } + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLTypeReference(this, context); + } + + @Override + public GraphQLSchemaElement copy() { + return typeRef(getName()); + } + + } diff --git a/src/main/java/graphql/schema/GraphQLTypeResolvingVisitor.java b/src/main/java/graphql/schema/GraphQLTypeResolvingVisitor.java new file mode 100644 index 0000000000..37a57f8933 --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLTypeResolvingVisitor.java @@ -0,0 +1,106 @@ +package graphql.schema; + +import graphql.Internal; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.Map; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.map; +import static graphql.util.TraversalControl.CONTINUE; + +@Internal +public class GraphQLTypeResolvingVisitor extends GraphQLTypeVisitorStub { + protected final Map typeMap; + + public GraphQLTypeResolvingVisitor(Map typeMap) { + this.typeMap = typeMap; + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + + node.replaceInterfaces(map(node.getInterfaces(), type -> (GraphQLNamedOutputType) typeMap.get(type.getName()))); + return super.visitGraphQLObjectType(node, context); + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + node.replaceInterfaces(map(node.getInterfaces(), type -> (GraphQLNamedOutputType) typeMap.get(type.getName()))); + return super.visitGraphQLInterfaceType(node, context); + } + + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + + node.replaceTypes(map(node.getTypes(), type -> (GraphQLNamedOutputType) typeMap.get(type.getName()))); + return super.visitGraphQLUnionType(node, context); + } + + @Override + public TraversalControl visitGraphQLTypeReference(GraphQLTypeReference node, TraverserContext context) { + return handleTypeReference(node, context); + } + + public TraversalControl handleTypeReference(GraphQLTypeReference node, TraverserContext context) { + final GraphQLType resolvedType = typeMap.get(node.getName()); + assertNotNull(resolvedType, "type %s not found in schema", node.getName()); + context.getParentContext().thisNode().accept(context, new TypeRefResolvingVisitor(resolvedType)); + return CONTINUE; + } + + @Override + public TraversalControl visitBackRef(TraverserContext context) { + GraphQLSchemaElement schemaElement = context.thisNode(); + if (schemaElement instanceof GraphQLTypeReference) { + return handleTypeReference((GraphQLTypeReference) schemaElement, context); + } + return CONTINUE; + } + + private static final class TypeRefResolvingVisitor extends GraphQLTypeVisitorStub { + private final GraphQLType resolvedType; + + TypeRefResolvingVisitor(GraphQLType resolvedType) { + this.resolvedType = resolvedType; + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + node.replaceType((GraphQLOutputType) resolvedType); + return super.visitGraphQLFieldDefinition(node, context); + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + node.replaceType((GraphQLInputType) resolvedType); + return super.visitGraphQLArgument(node, context); + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + node.replaceType((GraphQLInputType) resolvedType); + return super.visitGraphQLAppliedDirectiveArgument(node, context); + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + node.replaceType((GraphQLInputType) resolvedType); + return super.visitGraphQLInputObjectField(node, context); + } + + @Override + public TraversalControl visitGraphQLList(GraphQLList node, TraverserContext context) { + node.replaceType(resolvedType); + return super.visitGraphQLList(node, context); + } + + @Override + public TraversalControl visitGraphQLNonNull(GraphQLNonNull node, TraverserContext context) { + node.replaceType(resolvedType); + return super.visitGraphQLNonNull(node, context); + } + } +} diff --git a/src/main/java/graphql/schema/GraphQLTypeUtil.java b/src/main/java/graphql/schema/GraphQLTypeUtil.java index e512f08463..e3a6e58d89 100644 --- a/src/main/java/graphql/schema/GraphQLTypeUtil.java +++ b/src/main/java/graphql/schema/GraphQLTypeUtil.java @@ -1,31 +1,49 @@ package graphql.schema; -import graphql.Internal; +import graphql.Assert; +import graphql.PublicApi; +import graphql.introspection.Introspection; +import graphql.schema.idl.DirectiveInfo; +import graphql.schema.idl.ScalarInfo; -@Internal +import java.util.Stack; +import java.util.function.Predicate; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; + +/** + * A utility class that helps work with {@link graphql.schema.GraphQLType}s + */ +@PublicApi public class GraphQLTypeUtil { /** - * This will get the unwrapped type name that includes the non null and list wrappers - * so it might be '[typeName!]' + * This will return the type in graphql SDL format, eg [typeName!]! * * @param type the type in play * - * @return the unwrapped type name + * @return the type in graphql SDL format, eg [typeName!]! */ - public static String getUnwrappedTypeName(GraphQLType type) { - StringBuilder sb = new StringBuilder(); + public static String simplePrint(GraphQLType type) { + Assert.assertNotNull(type, "type can't be null"); if (isNonNull(type)) { - sb.append(getUnwrappedTypeName(unwrapOne(type))); - sb.append("!"); + return simplePrint(unwrapOne(type)) + "!"; } else if (isList(type)) { - sb.append("["); - sb.append(getUnwrappedTypeName(unwrapOne(type))); - sb.append("]"); - } else { - sb.append(type.getName()); + return "[" + simplePrint(unwrapOne(type)) + "]"; + } + return ((GraphQLNamedType) type).getName(); + } + + public static String simplePrint(GraphQLSchemaElement schemaElement) { + if (schemaElement instanceof GraphQLType) { + return simplePrint((GraphQLType) schemaElement); + } + if (schemaElement instanceof GraphQLNamedSchemaElement) { + return ((GraphQLNamedSchemaElement) schemaElement).getName(); } - return sb.toString(); + // a schema element is either a GraphQLType or a GraphQLNamedSchemaElement + return assertShouldNeverHappen("unexpected schema element: " + schemaElement); } /** @@ -135,11 +153,11 @@ public static boolean isInput(GraphQLType type) { } /** - * Unwraps one layer of the type or just returns the type again if its not a wrapped type + * Unwraps one layer of the type or just returns the type again if it's not a wrapped type * * @param type the type to unwrapOne * - * @return the unwrapped type or the same type again if its not wrapped + * @return the unwrapped type or the same type again if it's not wrapped */ public static GraphQLType unwrapOne(GraphQLType type) { if (isNonNull(type)) { @@ -151,19 +169,136 @@ public static GraphQLType unwrapOne(GraphQLType type) { } /** - * Unwraps all layers of the type or just returns the type again if its not a wrapped type + * Unwraps one layer of the type or just returns the type again if it's not a wrapped type + * and then cast to the target type. + * + * @param type the type to unwrapOne + * @param for two + * + * @return the unwrapped type or the same type again if it's not wrapped + */ + public static T unwrapOneAs(GraphQLType type) { + //noinspection unchecked + return (T) unwrapOne(type); + } + + /** + * Unwraps all layers of the type or just returns the type again if it's not a wrapped type + * NOTE: This method does not support GraphQLTypeReference as input and will lead to a ClassCastException * * @param type the type to unwrapOne * * @return the underlying type */ public static GraphQLUnmodifiedType unwrapAll(GraphQLType type) { + return unwrapAllAs(type); + } + + /** + * Unwraps all layers of the type or just returns the type again if it's not a wrapped type + * and then cast to the target type. + * + * @param type the type to unwrapOne + * @param for two + * + * @return the underlying type + */ + public static T unwrapAllAs(GraphQLType type) { + //noinspection unchecked + return (T) unwrapAllImpl(type); + } + + private static GraphQLType unwrapAllImpl(GraphQLType type) { + while (true) { + if (isNotWrapped(type)) { + return type; + } + type = unwrapOne(type); + } + } + + + /** + * Unwraps a single non-nullable layer of the type if its present. Note there can + * only ever be one non-nullable wrapping of a type and this is enforced by {@link GraphQLNonNull} + * + * @param type the type to unwrap + * + * @return the underlying type that is not {@link GraphQLNonNull} + */ + public static GraphQLType unwrapNonNull(GraphQLType type) { + // its illegal to have a type that is a non-null wrapping a non-null type + // and GraphQLNonNull has code that prevents it so we can just check once during the unwrapping + if (isNonNull(type)) { + // is cheaper doing this direct rather than calling #unwrapOne + type = ((GraphQLNonNull) type).getWrappedType(); + } + return type; + } + + /** + * Unwraps a single non-nullable layer of the type if its present and then cast to the target type. Note there can + * only ever be one non-nullable wrapping of a type and this is enforced by {@link GraphQLNonNull} + * + * @param type the type to unwrap + * @param for two + * + * @return the underlying type that is not {@link GraphQLNonNull} + */ + public static T unwrapNonNullAs(GraphQLType type) { + //noinspection unchecked + return (T) unwrapNonNull(type); + } + + /** + * graphql types can be wrapped in {@link GraphQLNonNull} and {@link GraphQLList} type wrappers + * so this method will unwrap the type down to the raw unwrapped type and return that wrapping + * as a stack, with the top of the stack being the raw underling type. + * + * @param type the type to unwrap + * + * @return a stack of the type wrapping which will be at least 1 later deep + */ + public static Stack unwrapType(GraphQLType type) { + assertNotNull(type); + Stack decoration = new Stack<>(); while (true) { + decoration.push(type); if (isNotWrapped(type)) { - return (GraphQLUnmodifiedType) type; + break; } type = unwrapOne(type); } + return decoration; + } + + public static boolean isInterfaceOrUnion(GraphQLType type) { + return type instanceof GraphQLInterfaceType || type instanceof GraphQLUnionType; + } + + public static boolean isObjectType(GraphQLType type) { + return type instanceof GraphQLObjectType; } + + /** + * This predicate returns true if the schema element is an inbuilt schema element + * such as the system scalars and directives or introspection types + * + * @return true if it's a system schema element + */ + public static Predicate isSystemElement() { + return schemaElement -> { + if (schemaElement instanceof GraphQLScalarType) { + return ScalarInfo.isGraphqlSpecifiedScalar((GraphQLScalarType) schemaElement); + } + if (schemaElement instanceof GraphQLDirective) { + return DirectiveInfo.isGraphqlSpecifiedDirective((GraphQLDirective) schemaElement); + } + if (schemaElement instanceof GraphQLNamedType) { + return Introspection.isIntrospectionTypes((GraphQLNamedType) schemaElement); + } + return false; + }; + } } diff --git a/src/main/java/graphql/schema/GraphQLTypeVisitor.java b/src/main/java/graphql/schema/GraphQLTypeVisitor.java new file mode 100644 index 0000000000..7853fa8dac --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLTypeVisitor.java @@ -0,0 +1,174 @@ +package graphql.schema; + +import graphql.PublicApi; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.util.TreeTransformerUtil; + +/** + * GraphQLTypeVisitor can be used to visit all the elements of a schema + * (types, fields, directives and so on) in a visitor pattern. + * + * @see GraphQLTypeVisitorStub + */ +@PublicApi +public interface GraphQLTypeVisitor { + /** + * This method will be called when a directive is applied to a schema element. + * + * The {@link TraverserContext#getParentNode()} will be the schema element that this is applied to. + * + * The graphql-java code base is trying to slowly move away from using {@link GraphQLDirective}s when they really should be {@link GraphQLAppliedDirective}s + * + * @param node the applied directive + * @param context the traversal context + * + * @return how to control the visitation processing + */ + default TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective node, TraverserContext context) { + return TraversalControl.CONTINUE; + } + + default TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + return TraversalControl.CONTINUE; + } + + TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context); + + /** + * This method will be called twice. Once for a directive definition in a schema and then do each time a directive is applied to a schema element + * + * When it's applied to a schema element then {@link TraverserContext#getParentNode()} will be the schema element that this is applied to. + * + * The graphql-java code base is trying to slowly move away from using {@link GraphQLDirective}s when they really should be {@link GraphQLAppliedDirective}s + * and this is another place that has been left in. In the future this behavior will change and this will only visit directive definitions of a schema, not where + * they are applied. + * + * @param node the directive + * @param context the traversal context + * + * @return how to control the visitation processing + */ + TraversalControl visitGraphQLDirective(GraphQLDirective node, TraverserContext context); + + TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context); + + TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition node, TraverserContext context); + + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context); + + TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context); + + TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context); + + TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context); + + TraversalControl visitGraphQLList(GraphQLList node, TraverserContext context); + + TraversalControl visitGraphQLNonNull(GraphQLNonNull node, TraverserContext context); + + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context); + + TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context); + + TraversalControl visitGraphQLTypeReference(GraphQLTypeReference node, TraverserContext context); + + TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context); + + /** + * Called when a node is visited more than once within a context. {@link graphql.util.TraverserContext#thisNode()} contains + * the node + * + * @param context the traversal context + * + * @return by default CONTINUE + */ + default TraversalControl visitBackRef(TraverserContext context) { + return TraversalControl.CONTINUE; + } + + // Marker interfaces + default TraversalControl visitGraphQLCompositeType(GraphQLCompositeType node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLDirectiveContainer(GraphQLDirectiveContainer node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLFieldsContainer(GraphQLFieldsContainer node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLInputFieldsContainer(GraphQLInputFieldsContainer node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLInputType(GraphQLInputType node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLModifiedType(GraphQLModifiedType node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLNullableType(GraphQLNullableType node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLOutputType(GraphQLOutputType node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + default TraversalControl visitGraphQLUnmodifiedType(GraphQLUnmodifiedType node, TraverserContext context) { + throw new UnsupportedOperationException(); + } + + /** + * This helper method can be used to "change" a node when returning control from this visitor + * + * @param context the current traversal context + * @param newChangedNode the new to be changed at this place + * + * @return this will always sent back TraversalControl.CONTINUE + */ + default TraversalControl changeNode(TraverserContext context, GraphQLSchemaElement newChangedNode) { + return TreeTransformerUtil.changeNode(context, newChangedNode); + } + + /** + * This helper method can be used to "delete" the current node when returning control from this visitor + * + * @param context the current traversal context which is pointing to the current node to be deleted + * + * @return this will always sent back TraversalControl.CONTINUE + */ + default TraversalControl deleteNode(TraverserContext context) { + return TreeTransformerUtil.deleteNode(context); + } + + /** + * This helper method can be used to "insert a new node" AFTER the current node when returning control from this visitor + * + * @param context the current traversal context + * @param toInsertAfter the new to be inserted AFTER this current code + * + * @return this will always sent back TraversalControl.CONTINUE + */ + default TraversalControl insertAfter(TraverserContext context, GraphQLSchemaElement toInsertAfter) { + return TreeTransformerUtil.insertAfter(context, toInsertAfter); + } + + /** + * This helper method can be used to "insert a new node" BEFORE the current node when returning control from this visitor + * + * @param context the current traversal context + * @param toInsertBefore the new to be inserted BEFORE this current code + * + * @return this will always sent back TraversalControl.CONTINUE + */ + default TraversalControl insertBefore(TraverserContext context, GraphQLSchemaElement toInsertBefore) { + return TreeTransformerUtil.insertBefore(context, toInsertBefore); + } + +} diff --git a/src/main/java/graphql/schema/GraphQLTypeVisitorStub.java b/src/main/java/graphql/schema/GraphQLTypeVisitorStub.java new file mode 100644 index 0000000000..79e9c0909c --- /dev/null +++ b/src/main/java/graphql/schema/GraphQLTypeVisitorStub.java @@ -0,0 +1,99 @@ +package graphql.schema; + +import graphql.PublicApi; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import static graphql.util.TraversalControl.CONTINUE; + +/** + * Base implementation of {@link GraphQLTypeVisitor} for convenience. + * Overwrite only required methods and/or {@link #visitGraphQLType(GraphQLSchemaElement, TraverserContext)} as default fallback. + */ +@PublicApi +public class GraphQLTypeVisitorStub implements GraphQLTypeVisitor { + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLList(GraphQLList node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLNonNull(GraphQLNonNull node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLTypeReference(GraphQLTypeReference node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + return visitGraphQLType(node, context); + } + + protected TraversalControl visitGraphQLType(GraphQLSchemaElement node, TraverserContext context) { + return CONTINUE; + } +} diff --git a/src/main/java/graphql/schema/GraphQLUnionType.java b/src/main/java/graphql/schema/GraphQLUnionType.java index a8a86cb10b..738c1dbcbf 100644 --- a/src/main/java/graphql/schema/GraphQLUnionType.java +++ b/src/main/java/graphql/schema/GraphQLUnionType.java @@ -1,70 +1,80 @@ package graphql.schema; +import com.google.common.collect.ImmutableList; +import graphql.Assert; +import graphql.DirectivesUtil; import graphql.Internal; import graphql.PublicApi; import graphql.language.UnionTypeDefinition; +import graphql.language.UnionTypeExtensionDefinition; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; -import java.util.stream.Collectors; +import org.jspecify.annotations.NullUnmarked; import static graphql.Assert.assertNotEmpty; import static graphql.Assert.assertNotNull; import static graphql.Assert.assertValidName; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer; import static graphql.util.FpKit.getByName; -import static graphql.util.FpKit.valuesToList; -import static java.util.Collections.emptyList; /** * A union type is a polymorphic type that dynamically represents one of more concrete object types. - * - * At runtime a {@link graphql.schema.TypeResolver} is used to take an union object value and decide what {@link graphql.schema.GraphQLObjectType} + *

+ * At runtime a {@link TypeResolver} is used to take an union object value and decide what {@link GraphQLObjectType} * represents this union of types. - * + *

* Note that members of a union type need to be concrete object types; you can't create a union type out of interfaces or other unions. - * - * See http://graphql.org/learn/schema/#union-types for more details on the concept. + *

+ * See https://graphql.org/learn/schema/#union-types for more details on the concept. */ @PublicApi -public class GraphQLUnionType implements GraphQLType, GraphQLOutputType, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { +public class GraphQLUnionType implements GraphQLNamedOutputType, GraphQLCompositeType, GraphQLUnmodifiedType, GraphQLNullableType, GraphQLDirectiveContainer { private final String name; private final String description; - private List types = new ArrayList<>(); + private final ImmutableList originalTypes; private final TypeResolver typeResolver; private final UnionTypeDefinition definition; - private final List directives; + private final ImmutableList extensionDefinitions; + private final DirectivesUtil.DirectivesHolder directives; + private ImmutableList replacedTypes; - @Internal - public GraphQLUnionType(String name, String description, List types, TypeResolver typeResolver) { - this(name, description, types, typeResolver, emptyList(), null); - } + public static final String CHILD_TYPES = "types"; @Internal - public GraphQLUnionType(String name, String description, List types, TypeResolver typeResolver, List directives, UnionTypeDefinition definition) { + private GraphQLUnionType(String name, + String description, + List types, + TypeResolver typeResolver, + List directives, + List appliedDirectives, + UnionTypeDefinition definition, + List extensionDefinitions) { assertValidName(name); assertNotNull(types, "types can't be null"); assertNotEmpty(types, "A Union type must define one or more member types."); - assertNotNull(typeResolver, "typeResolver can't be null"); assertNotNull(directives, "directives cannot be null"); this.name = name; this.description = description; - this.types = types; + this.originalTypes = ImmutableList.copyOf(types); this.typeResolver = typeResolver; this.definition = definition; - this.directives = directives; + this.extensionDefinitions = ImmutableList.copyOf(extensionDefinitions); + this.directives = DirectivesUtil.DirectivesHolder.create(directives, appliedDirectives); } - void replaceTypeReferences(Map typeMap) { - this.types = this.types.stream() - .map(type -> (GraphQLOutputType) new SchemaUtil().resolveTypeReference(type, typeMap)) - .collect(Collectors.toList()); + void replaceTypes(List types) { + this.replacedTypes = ImmutableList.copyOf(types); } /** @@ -72,11 +82,33 @@ void replaceTypeReferences(Map typeMap) { * references are not resolved yet. After they are resolved it contains only GraphQLObjectType. * Reference resolving happens when a full schema is built. */ - public List getTypes() { - return new ArrayList<>(types); + public List getTypes() { + if (replacedTypes != null) { + return replacedTypes; + } + return originalTypes; } - public TypeResolver getTypeResolver() { + /** + * Returns true of the object type is a member of this Union type. + * + * @param graphQLObjectType the type to check + * + * @return true if the object type is a member of this union type. + */ + public boolean isPossibleType(GraphQLObjectType graphQLObjectType) { + for (GraphQLNamedOutputType type : getTypes()) { + if (type.getName().equals(graphQLObjectType.getName())) { + return true; + } + } + return false; + } + + // to be removed in a future version when all code is in the code registry + @Internal + @Deprecated(since = "2018-12-03") + TypeResolver getTypeResolver() { return typeResolver; } @@ -93,9 +125,43 @@ public UnionTypeDefinition getDefinition() { return definition; } + public List getExtensionDefinitions() { + return extensionDefinitions; + } + @Override public List getDirectives() { - return new ArrayList<>(directives); + return directives.getDirectives(); + } + + @Override + public Map getDirectivesByName() { + return directives.getDirectivesByName(); + } + + @Override + public Map> getAllDirectivesByName() { + return directives.getAllDirectivesByName(); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directives.getDirective(directiveName); + } + + @Override + public List getAppliedDirectives() { + return directives.getAppliedDirectives(); + } + + @Override + public Map> getAllAppliedDirectivesByName() { + return directives.getAllAppliedDirectivesByName(); + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return directives.getAppliedDirective(directiveName); } /** @@ -112,6 +178,69 @@ public GraphQLUnionType transform(Consumer builderConsumer) { return builder.build(); } + @Override + public GraphQLSchemaElement copy() { + return newUnionType(this).build(); + } + + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return visitor.visitGraphQLUnionType(this, context); + } + + @Override + public List getChildren() { + List children = new ArrayList<>(getTypes()); + children.addAll(directives.getDirectives()); + children.addAll(directives.getAppliedDirectives()); + return children; + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + return newSchemaElementChildrenContainer() + .children(CHILD_TYPES, originalTypes) + .children(CHILD_DIRECTIVES, directives.getDirectives()) + .children(CHILD_APPLIED_DIRECTIVES, directives.getAppliedDirectives()) + .build(); + } + + @Override + public GraphQLUnionType withNewChildren(SchemaElementChildrenContainer newChildren) { + return transform(builder -> + builder.replacePossibleTypes(newChildren.getChildren(CHILD_TYPES)) + .replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES)) + .replaceAppliedDirectives(newChildren.getChildren(CHILD_APPLIED_DIRECTIVES)) + + ); + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean equals(Object o) { + return super.equals(o); + } + + /** + * {@inheritDoc} + */ + @Override + public final int hashCode() { + return super.hashCode(); + } + + @Override + public String toString() { + return "GraphQLUnionType{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", definition=" + definition + + '}'; + } + public static Builder newUnionType() { return new Builder(); } @@ -121,13 +250,12 @@ public static Builder newUnionType(GraphQLUnionType existing) { } @PublicApi - public static class Builder { - private String name; - private String description; + @NullUnmarked + public static class Builder extends GraphqlDirectivesContainerTypeBuilder { private TypeResolver typeResolver; private UnionTypeDefinition definition; - private final Map types = new LinkedHashMap<>(); - private final Map directives = new LinkedHashMap<>(); + private List extensionDefinitions = emptyList(); + private final Map types = new LinkedHashMap<>(); public Builder() { } @@ -137,18 +265,9 @@ public Builder(GraphQLUnionType existing) { this.description = existing.getDescription(); this.typeResolver = existing.getTypeResolver(); this.definition = existing.getDefinition(); - this.types.putAll(getByName(existing.getTypes(), GraphQLType::getName)); - this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); - } - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder description(String description) { - this.description = description; - return this; + this.extensionDefinitions = existing.getExtensionDefinitions(); + this.types.putAll(getByName(existing.originalTypes, GraphQLNamedType::getName)); + copyExistingDirectives(existing); } public Builder definition(UnionTypeDefinition definition) { @@ -156,13 +275,24 @@ public Builder definition(UnionTypeDefinition definition) { return this; } + public Builder extensionDefinitions(List extensionDefinitions) { + this.extensionDefinitions = extensionDefinitions; + return this; + } + /** + * @param typeResolver the type resolver + * + * @return this builder + * + * @deprecated use {@link graphql.schema.GraphQLCodeRegistry.Builder#typeResolver(GraphQLUnionType, TypeResolver)} instead + */ + @Deprecated(since = "2018-12-03") public Builder typeResolver(TypeResolver typeResolver) { this.typeResolver = typeResolver; return this; } - public Builder possibleType(GraphQLObjectType type) { assertNotNull(type, "possible type can't be null"); types.put(type.getName(), type); @@ -182,6 +312,20 @@ public Builder possibleTypes(GraphQLObjectType... type) { return this; } + public Builder replacePossibleTypes(List types) { + this.types.clear(); + for (GraphQLSchemaElement schemaElement : types) { + if (schemaElement instanceof GraphQLTypeReference) { + possibleType((GraphQLTypeReference) schemaElement); + } else if (schemaElement instanceof GraphQLObjectType) { + possibleType((GraphQLObjectType) schemaElement); + } else { + Assert.assertShouldNeverHappen("Unexpected type " + (schemaElement != null ? schemaElement.getClass() : "null")); + } + } + return this; + } + public Builder possibleTypes(GraphQLTypeReference... references) { for (GraphQLTypeReference reference : references) { possibleType(reference); @@ -203,35 +347,55 @@ public boolean containType(String name) { return types.containsKey(name); } + // -- the following are repeated to avoid a binary incompatibility problem -- + + @Override + public Builder replaceDirectives(List directives) { + return super.replaceDirectives(directives); + } + + @Override public Builder withDirectives(GraphQLDirective... directives) { - for (GraphQLDirective directive : directives) { - withDirective(directive); - } - return this; + return super.withDirectives(directives); } + @Override public Builder withDirective(GraphQLDirective directive) { - assertNotNull(directive, "directive can't be null"); - directives.put(directive.getName(), directive); - return this; + return super.withDirective(directive); } + @Override public Builder withDirective(GraphQLDirective.Builder builder) { - return withDirective(builder.build()); + return super.withDirective(builder); } - /** - * This is used to clear all the directives in the builder so far. - * - * @return the builder - */ + @Override public Builder clearDirectives() { - directives.clear(); - return this; + return super.clearDirectives(); + } + + @Override + public Builder name(String name) { + return super.name(name); + } + + @Override + public Builder description(String description) { + return super.description(description); } public GraphQLUnionType build() { - return new GraphQLUnionType(name, description, valuesToList(types), typeResolver, valuesToList(directives), definition); + return new GraphQLUnionType( + name, + description, + sort(types, GraphQLUnionType.class, GraphQLOutputType.class), + typeResolver, + sort(directives, GraphQLUnionType.class, GraphQLDirective.class), + sort(appliedDirectives, GraphQLUnionType.class, GraphQLAppliedDirective.class), + definition, + extensionDefinitions); } } + + } diff --git a/src/main/java/graphql/schema/GraphQLUnmodifiedType.java b/src/main/java/graphql/schema/GraphQLUnmodifiedType.java index ba84815182..8fc8c0a979 100644 --- a/src/main/java/graphql/schema/GraphQLUnmodifiedType.java +++ b/src/main/java/graphql/schema/GraphQLUnmodifiedType.java @@ -1,5 +1,8 @@ package graphql.schema; -public interface GraphQLUnmodifiedType extends GraphQLType { +import graphql.PublicApi; + +@PublicApi +public interface GraphQLUnmodifiedType extends GraphQLNamedType { } diff --git a/src/main/java/graphql/schema/GraphqlDirectivesContainerTypeBuilder.java b/src/main/java/graphql/schema/GraphqlDirectivesContainerTypeBuilder.java new file mode 100644 index 0000000000..759e2de9a5 --- /dev/null +++ b/src/main/java/graphql/schema/GraphqlDirectivesContainerTypeBuilder.java @@ -0,0 +1,129 @@ +package graphql.schema; + +import graphql.Internal; + +import java.util.ArrayList; +import java.util.List; + +import static graphql.Assert.assertNotNull; + +@Internal +public abstract class GraphqlDirectivesContainerTypeBuilder, BASE extends GraphqlTypeBuilder> extends GraphqlTypeBuilder { + + protected final List appliedDirectives = new ArrayList<>(); + protected final List directives = new ArrayList<>(); + + public B replaceAppliedDirectives(List directives) { + assertNotNull(directives, "directive can't be null"); + this.appliedDirectives.clear(); + this.appliedDirectives.addAll(directives); + return (B) this; + } + + /** + * @param directives the variable args of directives + * + * @return this builder + */ + public B withAppliedDirectives(GraphQLAppliedDirective... directives) { + assertNotNull(directives, "directives can't be null"); + for (GraphQLAppliedDirective directive : directives) { + withAppliedDirective(directive); + } + return (B) this; + } + + /** + * @param directive the directive to add + * + * @return this builder + */ + public B withAppliedDirective(GraphQLAppliedDirective directive) { + assertNotNull(directive, "directive can't be null"); + this.appliedDirectives.add(directive); + return (B) this; + } + + /** + * @param builder the directive builder + * + * @return this builder + */ + public B withAppliedDirective(GraphQLAppliedDirective.Builder builder) { + return withAppliedDirective(builder.build()); + } + + /** + * @param directives the list of directives + * + * @return this builder + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public B replaceDirectives(List directives) { + assertNotNull(directives, "directive can't be null"); + this.directives.clear(); + this.directives.addAll(directives); + return (B) this; + } + + /** + * @param directives the variable args of directives + * + * @return this builder + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public B withDirectives(GraphQLDirective... directives) { + assertNotNull(directives, "directives can't be null"); + for (GraphQLDirective directive : directives) { + withDirective(directive); + } + return (B) this; + } + + /** + * @param directive the directive to add + * + * @return this builder + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public B withDirective(GraphQLDirective directive) { + assertNotNull(directive, "directive can't be null"); + this.directives.add(directive); + return (B) this; + } + + /** + * @param builder the directive builder + * + * @return this builder + * + * @deprecated - use the {@link GraphQLAppliedDirective} methods instead + */ + @Deprecated(since = "2022-02-24") + public B withDirective(GraphQLDirective.Builder builder) { + return withDirective(builder.build()); + } + + /** + * This is used to clear all the directives in the builder so far. + * + * @return the builder + */ + public B clearDirectives() { + directives.clear(); + appliedDirectives.clear(); + return (B) this; + } + + protected void copyExistingDirectives(GraphQLDirectiveContainer directivesContainer) { + clearDirectives(); + directives.addAll(directivesContainer.getDirectives()); + appliedDirectives.addAll(directivesContainer.getAppliedDirectives()); + } +} diff --git a/src/main/java/graphql/schema/GraphqlElementParentTree.java b/src/main/java/graphql/schema/GraphqlElementParentTree.java new file mode 100644 index 0000000000..acf5080e0c --- /dev/null +++ b/src/main/java/graphql/schema/GraphqlElementParentTree.java @@ -0,0 +1,74 @@ +package graphql.schema; + +import graphql.Internal; +import graphql.PublicApi; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; +import java.util.Optional; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; + +/** + * This represents a hierarchy an graphql runtime element upwards to its + * associated parent elements. For example a GraphqlDirective can be on a GraphqlArgument + * which can be on a GraphqlFieldDefinition, which can be on a GraphqlObjectType. + */ +@PublicApi +public class GraphqlElementParentTree { + + private final GraphQLSchemaElement element; + private final GraphqlElementParentTree parent; + + @Internal + public GraphqlElementParentTree(Deque nodeStack) { + assertNotNull(nodeStack, "You MUST have a non null stack of elements"); + assertTrue(!nodeStack.isEmpty(), "You MUST have a non empty stack of element"); + + Deque copy = new ArrayDeque<>(nodeStack); + element = copy.pop(); + if (!copy.isEmpty()) { + parent = new GraphqlElementParentTree(copy); + } else { + parent = null; + } + } + + /** + * Returns the element represented by this info + * + * @return the element in play + */ + public GraphQLSchemaElement getElement() { + return element; + } + + /** + * @return an element MAY have an optional parent + */ + public Optional getParentInfo() { + return Optional.ofNullable(parent); + } + + /** + * @return the tree as a list of types + */ + public List toList() { + List types = new ArrayList<>(); + types.add(element); + Optional parentInfo = this.getParentInfo(); + while (parentInfo.isPresent()) { + types.add(parentInfo.get().getElement()); + parentInfo = parentInfo.get().getParentInfo(); + } + return types; + } + + @Override + public String toString() { + return element + " - parent : " + parent; + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/GraphqlTypeBuilder.java b/src/main/java/graphql/schema/GraphqlTypeBuilder.java new file mode 100644 index 0000000000..990532e4dc --- /dev/null +++ b/src/main/java/graphql/schema/GraphqlTypeBuilder.java @@ -0,0 +1,56 @@ +package graphql.schema; + +import com.google.common.collect.ImmutableList; +import graphql.Internal; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +import static graphql.util.FpKit.valuesToList; + +@SuppressWarnings("unchecked") +@Internal +public abstract class GraphqlTypeBuilder> { + + protected String name; + protected String description; + protected GraphqlTypeComparatorRegistry comparatorRegistry = GraphqlTypeComparatorRegistry.AS_IS_REGISTRY; + + public B name(String name) { + this.name = name; + return (B) this; + } + + public B description(String description) { + this.description = description; + return (B) this; + } + + public B comparatorRegistry(GraphqlTypeComparatorRegistry comparatorRegistry) { + this.comparatorRegistry = comparatorRegistry; + return (B) this; + } + + + List sort(Map types, Class parentType, Class elementType) { + return sort(valuesToList(types), parentType, elementType); + } + + List sort(List types, Class parentType, Class elementType) { + Comparator comparator = getComparatorImpl(comparatorRegistry, parentType, elementType); + return ImmutableList.copyOf(GraphqlTypeComparators.sortTypes(comparator, types)); + } + + Comparator getComparator(Class parentType, Class elementType) { + return getComparatorImpl(comparatorRegistry, parentType, elementType); + } + + private static Comparator getComparatorImpl(GraphqlTypeComparatorRegistry comparatorRegistry, Class parentType, Class elementType) { + GraphqlTypeComparatorEnvironment environment = GraphqlTypeComparatorEnvironment.newEnvironment() + .parentType(parentType) + .elementType(elementType) + .build(); + return comparatorRegistry.getComparator(environment); + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/GraphqlTypeComparatorEnvironment.java b/src/main/java/graphql/schema/GraphqlTypeComparatorEnvironment.java new file mode 100644 index 0000000000..de7ed388a9 --- /dev/null +++ b/src/main/java/graphql/schema/GraphqlTypeComparatorEnvironment.java @@ -0,0 +1,111 @@ +package graphql.schema; + +import graphql.PublicApi; + +import java.util.Objects; +import java.util.function.Consumer; + +/** + * Defines the scope to control where the registered {@code Comparator} can be applied. + *

+ * {@code elementType}s can be ordered within its {@code parentType} to restrict the {@code Comparator}s scope of operation. + * Otherwise, supplying only the {@code elementType} results in the {@code Comparator} being reused across all matching {@code GraphQLType}s regardless of parent. + */ +@PublicApi +public class GraphqlTypeComparatorEnvironment { + + private Class parentType; + + private Class elementType; + + private GraphqlTypeComparatorEnvironment(Class parentType, Class elementType) { + this.parentType = parentType; + this.elementType = elementType; + } + + /** + * @return The parent type or {@code null} if not supplied. + */ + public Class getParentType() { + return parentType; + } + + /** + * @return The valid element type or {@code null} if not supplied. + */ + public Class getElementType() { + return elementType; + } + + /** + * This helps you transform the current {@code GraphqlTypeComparatorEnvironment} into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform. + * + * @return a new object based on calling build on that builder. + */ + public GraphqlTypeComparatorEnvironment transform(Consumer builderConsumer) { + Builder builder = newEnvironment(this); + builderConsumer.accept(builder); + return builder.build(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GraphqlTypeComparatorEnvironment that = (GraphqlTypeComparatorEnvironment) o; + return Objects.equals(parentType, that.parentType) && elementType.equals(that.elementType); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + Objects.hashCode(parentType); + result = 31 * result + Objects.hashCode(elementType); + return result; + } + + public static Builder newEnvironment() { + return new Builder(); + } + + public static Builder newEnvironment(GraphqlTypeComparatorEnvironment existing) { + return new Builder(existing); + } + + public static class Builder { + + private Class parentType; + + private Class elementType; + + public Builder() { + } + + public Builder(GraphqlTypeComparatorEnvironment existing) { + this.parentType = existing.parentType; + this.elementType = existing.elementType; + } + + public Builder parentType(Class parentType) { + this.parentType = parentType; + return this; + } + + public Builder elementType(Class elementType) { + this.elementType = elementType; + return this; + } + + public GraphqlTypeComparatorEnvironment build() { + return new GraphqlTypeComparatorEnvironment(parentType, elementType); + } + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/GraphqlTypeComparatorRegistry.java b/src/main/java/graphql/schema/GraphqlTypeComparatorRegistry.java new file mode 100644 index 0000000000..af9f28914b --- /dev/null +++ b/src/main/java/graphql/schema/GraphqlTypeComparatorRegistry.java @@ -0,0 +1,39 @@ +package graphql.schema; + +import graphql.PublicApi; + +import java.util.Comparator; + +@PublicApi +public interface GraphqlTypeComparatorRegistry { + + /** + * A registry that leaves the elements as there currently are + */ + GraphqlTypeComparatorRegistry AS_IS_REGISTRY = new GraphqlTypeComparatorRegistry() { + @Override + public Comparator getComparator(GraphqlTypeComparatorEnvironment environment) { + return GraphqlTypeComparators.asIsOrder(); + } + }; + + + /** + * A registry that sorts the elements by their name ascending + */ + GraphqlTypeComparatorRegistry BY_NAME_REGISTRY = new GraphqlTypeComparatorRegistry() { + @Override + public Comparator getComparator(GraphqlTypeComparatorEnvironment environment) { + return GraphqlTypeComparators.byNameAsc(); + } + }; + + + /** + * @param environment Defines the scope to control where the {@code Comparator} can be applied. + * @param the type of the comparator + * + * @return The registered {@code Comparator} or {@code null} if not found. + */ + Comparator getComparator(GraphqlTypeComparatorEnvironment environment); +} diff --git a/src/main/java/graphql/schema/GraphqlTypeComparators.java b/src/main/java/graphql/schema/GraphqlTypeComparators.java new file mode 100644 index 0000000000..16eb006388 --- /dev/null +++ b/src/main/java/graphql/schema/GraphqlTypeComparators.java @@ -0,0 +1,49 @@ +package graphql.schema; + +import com.google.common.collect.ImmutableList; +import graphql.Internal; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +@Internal +public class GraphqlTypeComparators { + + private static final Comparator BY_NAME_ASCENDING = + Comparator.comparing(graphQLSchemaElement -> + ((GraphQLNamedSchemaElement) graphQLSchemaElement).getName()); + + /** + * This sorts the list of {@link graphql.schema.GraphQLType} objects (by name) and allocates a new sorted + * list back. + * + * @param the type of type + * @param comparator the comparator to use + * @param types the types to sort + * + * @return a new allocated list of sorted things + */ + public static List sortTypes(Comparator comparator, Collection types) { + return ImmutableList.sortedCopyOf(comparator, types); + } + + /** + * Returns a comparator that laves {@link graphql.schema.GraphQLType} objects as they are + * + * @return a comparator that laves {@link graphql.schema.GraphQLType} objects as they are + */ + public static Comparator asIsOrder() { + return (o1, o2) -> 0; + } + + /** + * Returns a comparator that compares {@link graphql.schema.GraphQLType} objects by ascending name + * + * @return a comparator that compares {@link graphql.schema.GraphQLType} objects by ascending name + */ + public static Comparator byNameAsc() { + return BY_NAME_ASCENDING; + } + +} diff --git a/src/main/java/graphql/schema/InputValueWithState.java b/src/main/java/graphql/schema/InputValueWithState.java new file mode 100644 index 0000000000..47a5236ec9 --- /dev/null +++ b/src/main/java/graphql/schema/InputValueWithState.java @@ -0,0 +1,91 @@ +package graphql.schema; + +import graphql.PublicApi; +import graphql.language.Value; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import static graphql.Assert.assertNotNull; + +/** + * Used by @{@link GraphQLArgument} and {@link GraphQLInputObjectField} to represent different value states. + */ +@PublicApi +public class InputValueWithState { + private enum State { + /** + * Value was never set aka not provided + */ + NOT_SET, + /** + * The value is an Ast literal + */ + LITERAL, + /** + * The value is an external value + */ + EXTERNAL_VALUE, + /** + * This is only used to preserve backward compatibility (for now): it is a value which is assumed to + * be already coerced. + * This will be removed at one point. + */ + INTERNAL_VALUE + + } + + private final State state; + private final Object value; + + private InputValueWithState(State state, Object value) { + this.state = state; + this.value = value; + } + + public static final InputValueWithState NOT_SET = new InputValueWithState(State.NOT_SET, null); + + public static InputValueWithState newLiteralValue(@NonNull Value value) { + assertNotNull(value, "value literal can't be null"); + return new InputValueWithState(State.LITERAL, value); + } + + public static InputValueWithState newExternalValue(@Nullable Object value) { + return new InputValueWithState(State.EXTERNAL_VALUE, value); + } + + public static InputValueWithState newInternalValue(@Nullable Object value) { + return new InputValueWithState(State.INTERNAL_VALUE, value); + } + + public @Nullable Object getValue() { + return value; + } + + public boolean isNotSet() { + return state == State.NOT_SET; + } + + public boolean isSet() { + return state != State.NOT_SET; + } + + public boolean isLiteral() { + return state == State.LITERAL; + } + + public boolean isExternal() { + return state == State.EXTERNAL_VALUE; + } + + public boolean isInternal() { + return state == State.INTERNAL_VALUE; + } + + @Override + public String toString() { + return "InputValueWithState{" + + "state=" + state + + ", value=" + value + + '}'; + } +} diff --git a/src/main/java/graphql/schema/LightDataFetcher.java b/src/main/java/graphql/schema/LightDataFetcher.java new file mode 100644 index 0000000000..0458457c02 --- /dev/null +++ b/src/main/java/graphql/schema/LightDataFetcher.java @@ -0,0 +1,36 @@ +package graphql.schema; + +import graphql.TrivialDataFetcher; + +import java.util.function.Supplier; + +/** + * A {@link LightDataFetcher} is a specialised version of {@link DataFetcher} that is passed more lightweight arguments + * when it is asked to fetch values. The most common example of this is the {@link PropertyDataFetcher} which does not need + * all the {@link DataFetchingEnvironment} values to perform its duties. + * + * @param for two + */ +public interface LightDataFetcher extends TrivialDataFetcher { + + /** + * This is called to by the engine to get a value from the source object in a lightweight fashion. Only the field + * and source object are passed in a materialised way. The more heavy weight {@link DataFetchingEnvironment} is wrapped + * in a supplier that is only created on demand. + *

+ * If you are a lightweight data fetcher (like {@link PropertyDataFetcher} is) then you can implement this method to have a more lightweight + * method invocation. However, if you need field arguments etc. during fetching (most custom fetchers will) then you should use implement + * {@link #get(DataFetchingEnvironment)}. + * + * @param fieldDefinition the graphql field definition + * @param sourceObject the source object to get a value from + * @param environmentSupplier a supplier of the {@link DataFetchingEnvironment} that creates it lazily + * + * @return a value of type T. May be wrapped in a {@link graphql.execution.DataFetcherResult} + * + * @throws Exception to relieve the implementations from having to wrap checked exceptions. Any exception thrown + * from a {@code DataFetcher} will eventually be handled by the registered {@link graphql.execution.DataFetcherExceptionHandler} + * and the related field will have a value of {@code null} in the result. + */ + T get(GraphQLFieldDefinition fieldDefinition, Object sourceObject, Supplier environmentSupplier) throws Exception; +} diff --git a/src/main/java/graphql/schema/PropertyDataFetcher.java b/src/main/java/graphql/schema/PropertyDataFetcher.java index aa9493fa7b..38382f4da9 100644 --- a/src/main/java/graphql/schema/PropertyDataFetcher.java +++ b/src/main/java/graphql/schema/PropertyDataFetcher.java @@ -2,49 +2,40 @@ import graphql.Assert; -import graphql.GraphQLException; import graphql.PublicApi; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.util.function.Function; - -import static graphql.Scalars.GraphQLBoolean; -import static graphql.schema.GraphQLTypeUtil.isNonNull; -import static graphql.schema.GraphQLTypeUtil.unwrapOne; +import java.util.function.Supplier; /** - * This is the default data fetcher used in graphql-java. It will examine - * maps and POJO java beans for values that match the desired name, typically the field name + * This is the default data fetcher used in graphql-java, and it will examine + * maps, records and POJO java beans for values that match the desired name, typically the field name, * or it will use a provided function to obtain values. - * maps and POJO java beans for values that match the desired name. - * + *

* It uses the following strategies *

    *
  • If the source is null, return null
  • *
  • If the source is a Map, return map.get(propertyName)
  • *
  • If a function is provided, it is used
  • - *
  • Find a public JavaBean getter method named `propertyName`
  • - *
  • Find any getter method named `propertyName` and call method.setAccessible(true)
  • + *
  • Find a public JavaBean getter method named `getPropertyName()` or `isPropertyName()` using {@link java.lang.invoke.LambdaMetafactory#metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
  • + *
  • Find a public Record like method named `propertyName()`
  • + *
  • Find a public JavaBean getter method named `getPropertyName()` or `isPropertyName()`
  • + *
  • Find any getter method named `getPropertyName()` or `isPropertyName()` and call method.setAccessible(true)
  • *
  • Find a public field named `propertyName`
  • *
  • Find any field named `propertyName` and call field.setAccessible(true)
  • *
  • If this cant find anything, then null is returned
  • *
- * + *

* You can write your own data fetchers to get data from some other backing system * if you need highly customised behaviour. * * @see graphql.schema.DataFetcher */ @PublicApi -public class PropertyDataFetcher implements DataFetcher { +public class PropertyDataFetcher implements LightDataFetcher { private final String propertyName; private final Function function; @@ -68,9 +59,9 @@ private PropertyDataFetcher(Function function) { /** * Returns a data fetcher that will use the property name to examine the {@link DataFetchingEnvironment#getSource()} object - * for a getter method or field with that name, or if its a map, it will look up a value using + * for a getter method or field with that name, or if it's a map, it will look up a value using * property name as a key. - * + *

* For example : *

      * {@code
@@ -93,7 +84,7 @@ public static  PropertyDataFetcher fetching(String propertyName) {
      * Returns a data fetcher that will present the {@link DataFetchingEnvironment#getSource()} object to the supplied
      * function to obtain a value, which allows you to use Java 8 method references say obtain values in a
      * more type safe way.
-     *
+     * 

* For example : *

      * {@code
@@ -120,10 +111,19 @@ public String getPropertyName() {
         return propertyName;
     }
 
-    @SuppressWarnings("unchecked")
+    @Override
+    public T get(GraphQLFieldDefinition fieldDefinition, Object source, Supplier environmentSupplier) throws Exception {
+        return getImpl(source, fieldDefinition.getType(), environmentSupplier);
+    }
+
     @Override
     public T get(DataFetchingEnvironment environment) {
         Object source = environment.getSource();
+        return getImpl(source, environment.getFieldType(), () -> environment);
+    }
+
+    @SuppressWarnings("unchecked")
+    private T getImpl(Object source, GraphQLOutputType fieldDefinition, Supplier environmentSupplier) {
         if (source == null) {
             return null;
         }
@@ -132,171 +132,42 @@ public T get(DataFetchingEnvironment environment) {
             return (T) function.apply(source);
         }
 
-        if (source instanceof Map) {
-            return (T) ((Map) source).get(propertyName);
-        }
-        return (T) getPropertyViaGetter(source, environment.getFieldType());
-    }
-
-    private Object getPropertyViaGetter(Object object, GraphQLOutputType outputType) {
-        try {
-            return getPropertyViaGetterMethod(object, outputType, this::findPubliclyAccessibleMethod);
-        } catch (NoSuchMethodException ignored) {
-            try {
-                return getPropertyViaGetterMethod(object, outputType, this::findViaSetAccessible);
-            } catch (NoSuchMethodException ignored2) {
-                return getPropertyViaFieldAccess(object);
-            }
-        }
+        return (T) PropertyDataFetcherHelper.getPropertyValue(propertyName, source, fieldDefinition, environmentSupplier);
     }
 
-    @FunctionalInterface
-    private interface MethodFinder {
-        Method apply(Class aClass, String s) throws NoSuchMethodException;
-    }
-
-    private Object getPropertyViaGetterMethod(Object object, GraphQLOutputType outputType, MethodFinder methodFinder) throws NoSuchMethodException {
-        if (isBooleanProperty(outputType)) {
-            try {
-                return getPropertyViaGetterUsingPrefix(object, "is", methodFinder);
-            } catch (NoSuchMethodException e) {
-                return getPropertyViaGetterUsingPrefix(object, "get", methodFinder);
-            }
-        } else {
-            return getPropertyViaGetterUsingPrefix(object, "get", methodFinder);
-        }
-    }
-
-    private Object getPropertyViaGetterUsingPrefix(Object object, String prefix, MethodFinder methodFinder) throws NoSuchMethodException {
-        String getterName = prefix + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
-        try {
-            Method method = methodFinder.apply(object.getClass(), getterName);
-            return method.invoke(object);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new GraphQLException(e);
-        }
-    }
-
-    @SuppressWarnings("SimplifiableIfStatement")
-    private boolean isBooleanProperty(GraphQLOutputType outputType) {
-        if (outputType == GraphQLBoolean) {
-            return true;
-        }
-        if (isNonNull(outputType)) {
-            return unwrapOne(outputType) == GraphQLBoolean;
-        }
-        return false;
-    }
-
-    private static final ConcurrentMap METHOD_CACHE = new ConcurrentHashMap<>();
-    private static final ConcurrentMap FIELD_CACHE = new ConcurrentHashMap<>();
-
     /**
-     * PropertyDataFetcher caches the methods and fields that map from a class to a property for runtime performance reasons.
-     *
+     * PropertyDataFetcher caches the methods and fields that map from a class to a property for runtime performance reasons
+     * as well as negative misses.
+     * 

* However during development you might be using an assistance tool like JRebel to allow you to tweak your code base and this * caching may interfere with this. So you can call this method to clear the cache. A JRebel plugin could * be developed to do just that. */ @SuppressWarnings("unused") public static void clearReflectionCache() { - METHOD_CACHE.clear(); - FIELD_CACHE.clear(); - } - - private String mkKey(Class clazz, String propertyName) { - return clazz.getName() + "__" + propertyName; - } - - // by not filling out the stack trace, we gain speed when using the exception as flow control - private static class FastNoSuchMethodException extends NoSuchMethodException { - public FastNoSuchMethodException(String methodName) { - super(methodName); - } - - @Override - public synchronized Throwable fillInStackTrace() { - return this; - } + PropertyDataFetcherHelper.clearReflectionCache(); } /** - * Invoking public methods on package-protected classes via reflection - * causes exceptions. This method searches a class's hierarchy for - * public visibility parent classes with the desired getter. This - * particular case is required to support AutoValue style data classes, - * which have abstract public interfaces implemented by package-protected - * (generated) subclasses. + * This can be used to control whether PropertyDataFetcher will use {@link java.lang.reflect.Method#setAccessible(boolean)} to gain access to property + * values. By default it PropertyDataFetcher WILL use setAccessible. + * + * @param flag whether to use setAccessible + * + * @return the previous value of the flag */ - @SuppressWarnings("unchecked") - private Method findPubliclyAccessibleMethod(Class root, String methodName) throws NoSuchMethodException { - Class currentClass = root; - while (currentClass != null) { - String key = mkKey(currentClass, propertyName); - Method method = METHOD_CACHE.get(key); - if (method != null) { - return method; - } - if (Modifier.isPublic(currentClass.getModifiers())) { - method = currentClass.getMethod(methodName); - if (Modifier.isPublic(method.getModifiers())) { - METHOD_CACHE.putIfAbsent(key, method); - return method; - } - } - currentClass = currentClass.getSuperclass(); - } - return root.getMethod(methodName); - } - - private Method findViaSetAccessible(Class aClass, String methodName) throws NoSuchMethodException { - String key = mkKey(aClass, propertyName); - Method method = METHOD_CACHE.get(key); - if (method != null) { - return method; - } - - Method[] declaredMethods = aClass.getDeclaredMethods(); - Optional m = Arrays.stream(declaredMethods) - .filter(mth -> methodName.equals(mth.getName())) - .findFirst(); - if (m.isPresent()) { - try { - // few JVMs actually enforce this but it might happen - method = m.get(); - method.setAccessible(true); - METHOD_CACHE.putIfAbsent(key, method); - return method; - } catch (SecurityException ignored) { - } - } - throw new FastNoSuchMethodException(methodName); + public static boolean setUseSetAccessible(boolean flag) { + return PropertyDataFetcherHelper.setUseSetAccessible(flag); } - private Object getPropertyViaFieldAccess(Object object) { - Class aClass = object.getClass(); - String key = mkKey(aClass, propertyName); - try { - Field field = FIELD_CACHE.get(key); - if (field == null) { - field = aClass.getField(propertyName); - FIELD_CACHE.putIfAbsent(key, field); - } - return field.get(object); - } catch (NoSuchFieldException e) { - // if not public fields then try via setAccessible - try { - Field field = aClass.getDeclaredField(propertyName); - field.setAccessible(true); - FIELD_CACHE.putIfAbsent(key, field); - return field.get(object); - } catch (SecurityException | NoSuchFieldException ignored2) { - return null; - } catch (IllegalAccessException e1) { - throw new GraphQLException(e); - } - } catch (IllegalAccessException e) { - throw new GraphQLException(e); - } + /** + * This can be used to control whether PropertyDataFetcher will cache negative lookups for a property for performance reasons. By default it PropertyDataFetcher WILL cache misses. + * + * @param flag whether to cache misses + * + * @return the previous value of the flag + */ + public static boolean setUseNegativeCache(boolean flag) { + return PropertyDataFetcherHelper.setUseNegativeCache(flag); } } diff --git a/src/main/java/graphql/schema/PropertyDataFetcherHelper.java b/src/main/java/graphql/schema/PropertyDataFetcherHelper.java new file mode 100644 index 0000000000..0877d93688 --- /dev/null +++ b/src/main/java/graphql/schema/PropertyDataFetcherHelper.java @@ -0,0 +1,42 @@ +package graphql.schema; + +import graphql.Internal; +import graphql.VisibleForTesting; + +import java.util.function.Supplier; + +/** + * This class is the guts of a property data fetcher and also used in AST code to turn + * in memory java objects into AST elements + */ +@Internal +public class PropertyDataFetcherHelper { + + private static final PropertyFetchingImpl impl = new PropertyFetchingImpl(DataFetchingEnvironment.class); + private static final Supplier ALWAYS_NULL = () -> null; + + public static Object getPropertyValue(String propertyName, Object object, GraphQLType graphQLType) { + return impl.getPropertyValue(propertyName, object, graphQLType, false, ALWAYS_NULL); + } + + public static Object getPropertyValue(String propertyName, Object object, GraphQLType graphQLType, Supplier environment) { + return impl.getPropertyValue(propertyName, object, graphQLType, true, environment); + } + + public static void clearReflectionCache() { + impl.clearReflectionCache(); + } + + public static boolean setUseSetAccessible(boolean flag) { + return impl.setUseSetAccessible(flag); + } + + @VisibleForTesting + public static boolean setUseLambdaFactory(boolean flag) { + return impl.setUseLambdaFactory(flag); + } + + public static boolean setUseNegativeCache(boolean flag) { + return impl.setUseNegativeCache(flag); + } +} diff --git a/src/main/java/graphql/schema/PropertyFetchingImpl.java b/src/main/java/graphql/schema/PropertyFetchingImpl.java new file mode 100644 index 0000000000..c17ba706b6 --- /dev/null +++ b/src/main/java/graphql/schema/PropertyFetchingImpl.java @@ -0,0 +1,465 @@ +package graphql.schema; + +import graphql.GraphQLException; +import graphql.Internal; +import graphql.schema.fetching.LambdaFetchingSupport; +import graphql.util.StringKit; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Scalars.GraphQLBoolean; +import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.schema.GraphQLTypeUtil.unwrapOne; + +/** + * A re-usable class that can fetch from POJOs + */ +@Internal +public class PropertyFetchingImpl { + private final AtomicBoolean USE_SET_ACCESSIBLE = new AtomicBoolean(true); + private final AtomicBoolean USE_LAMBDA_FACTORY = new AtomicBoolean(true); + private final AtomicBoolean USE_NEGATIVE_CACHE = new AtomicBoolean(true); + private final ConcurrentMap LAMBDA_CACHE = new ConcurrentHashMap<>(); + private final ConcurrentMap METHOD_CACHE = new ConcurrentHashMap<>(); + private final ConcurrentMap FIELD_CACHE = new ConcurrentHashMap<>(); + private final ConcurrentMap NEGATIVE_CACHE = new ConcurrentHashMap<>(); + private final Class singleArgumentType; + + public PropertyFetchingImpl(Class singleArgumentType) { + this.singleArgumentType = singleArgumentType; + } + + private final class CachedMethod { + private final Method method; + private final boolean takesSingleArgumentTypeAsOnlyArgument; + + CachedMethod(Method method) { + this.method = method; + this.takesSingleArgumentTypeAsOnlyArgument = takesSingleArgumentTypeAsOnlyArgument(method); + } + } + + private static final class CachedLambdaFunction { + private final Function getter; + + CachedLambdaFunction(Function getter) { + this.getter = getter; + } + } + + public Object getPropertyValue(String propertyName, Object object, GraphQLType graphQLType, boolean dfeInUse, Supplier singleArgumentValue) { + if (object instanceof Map) { + return ((Map) object).get(propertyName); + } + + CacheKey cacheKey = mkCacheKey(object, propertyName); + + // let's try positive cache mechanisms first. If we have seen the method or field before + // then we invoke it directly without burning any cycles doing reflection. + CachedLambdaFunction cachedFunction = LAMBDA_CACHE.get(cacheKey); + if (cachedFunction != null) { + return cachedFunction.getter.apply(object); + } + CachedMethod cachedMethod = METHOD_CACHE.get(cacheKey); + if (cachedMethod != null) { + try { + return invokeMethod(object, singleArgumentValue, cachedMethod.method, cachedMethod.takesSingleArgumentTypeAsOnlyArgument); + } catch (NoSuchMethodException ignored) { + assertShouldNeverHappen("A method cached as '%s' is no longer available??", cacheKey); + } + } + Field cachedField = FIELD_CACHE.get(cacheKey); + if (cachedField != null) { + return invokeField(object, cachedField); + } + + // + // if we have tried all strategies before, and they have all failed then we negatively cache + // the cacheKey and assume that it's never going to turn up. This shortcuts the property lookup + // in systems where there was a `foo` graphql property, but they never provided an POJO + // version of `foo`. + // + // we do this second because we believe in the positive cached version will mostly prevail + // but if we then look it up and negatively cache it then lest do that look up next + // + if (isNegativelyCached(cacheKey)) { + return null; + } + + // + // ok we haven't cached it, and we haven't negatively cached it, so we have to find the POJO method which is the most + // expensive operation here + // + + Optional> getterOpt = lambdaGetter(propertyName, object); + if (getterOpt.isPresent()) { + try { + Function getter = getterOpt.get(); + Object value = getter.apply(object); + cachedFunction = new CachedLambdaFunction(getter); + LAMBDA_CACHE.putIfAbsent(cacheKey, cachedFunction); + return value; + } catch (LinkageError | ClassCastException ignored) { + // + // if we get a linkage error then it maybe that class loader challenges + // are preventing the Meta Lambda from working. So let's continue with + // old skool reflection and if it's all broken there then it will eventually + // end up negatively cached + } + } + + // + // try by record like name - object.propertyName() + try { + MethodFinder methodFinder = (rootClass, methodName) -> findRecordMethod(cacheKey, rootClass, methodName); + return getPropertyViaRecordMethod(object, propertyName, methodFinder, singleArgumentValue); + } catch (NoSuchMethodException ignored) { + } + // + // try by public getters name - object.getPropertyName() + try { + MethodFinder methodFinder = (rootClass, methodName) -> findPubliclyAccessibleMethod(cacheKey, rootClass, methodName, dfeInUse, false); + return getPropertyViaGetterMethod(object, propertyName, graphQLType, methodFinder, singleArgumentValue); + } catch (NoSuchMethodException ignored) { + } + // + // try by public getters name - object.getPropertyName() where its static + try { + // we allow static getXXX() methods because we always have. It's strange in retrospect but + // in order to not break things we allow statics to be used. In theory this double code check is not needed + // because you CANT have a `static getFoo()` and a `getFoo()` in the same class hierarchy but to make the code read clearer + // I have repeated the lookup. Since we cache methods, this happens only once and does not slow us down + MethodFinder methodFinder = (rootClass, methodName) -> findPubliclyAccessibleMethod(cacheKey, rootClass, methodName, dfeInUse, true); + return getPropertyViaGetterMethod(object, propertyName, graphQLType, methodFinder, singleArgumentValue); + } catch (NoSuchMethodException ignored) { + } + // + // try by accessible getters name - object.getPropertyName() + try { + MethodFinder methodFinder = (aClass, methodName) -> findViaSetAccessible(cacheKey, aClass, methodName, dfeInUse); + return getPropertyViaGetterMethod(object, propertyName, graphQLType, methodFinder, singleArgumentValue); + } catch (NoSuchMethodException ignored) { + } + // + // try by field name - object.propertyName; + try { + return getPropertyViaFieldAccess(cacheKey, object, propertyName); + } catch (NoSuchMethodException ignored) { + } + // we have nothing to ask for, and we have exhausted our lookup strategies + putInNegativeCache(cacheKey); + return null; + } + + private Optional> lambdaGetter(String propertyName, Object object) { + if (USE_LAMBDA_FACTORY.get()) { + return LambdaFetchingSupport.createGetter(object.getClass(), propertyName); + } + return Optional.empty(); + } + + private boolean isNegativelyCached(CacheKey key) { + if (USE_NEGATIVE_CACHE.get()) { + return NEGATIVE_CACHE.containsKey(key); + } + return false; + } + + private void putInNegativeCache(CacheKey key) { + if (USE_NEGATIVE_CACHE.get()) { + NEGATIVE_CACHE.put(key, key); + } + } + + private interface MethodFinder { + Method apply(Class aClass, String s) throws NoSuchMethodException; + } + + private Object getPropertyViaRecordMethod(Object object, String propertyName, MethodFinder methodFinder, Supplier singleArgumentValue) throws NoSuchMethodException { + Method method = methodFinder.apply(object.getClass(), propertyName); + return invokeMethod(object, singleArgumentValue, method, takesSingleArgumentTypeAsOnlyArgument(method)); + } + + private Object getPropertyViaGetterMethod(Object object, String propertyName, GraphQLType graphQLType, MethodFinder methodFinder, Supplier singleArgumentValue) throws NoSuchMethodException { + if (isBooleanProperty(graphQLType)) { + try { + return getPropertyViaGetterUsingPrefix(object, propertyName, "is", methodFinder, singleArgumentValue); + } catch (NoSuchMethodException e) { + return getPropertyViaGetterUsingPrefix(object, propertyName, "get", methodFinder, singleArgumentValue); + } + } else { + return getPropertyViaGetterUsingPrefix(object, propertyName, "get", methodFinder, singleArgumentValue); + } + } + + private Object getPropertyViaGetterUsingPrefix(Object object, String propertyName, String prefix, MethodFinder methodFinder, Supplier singleArgumentValue) throws NoSuchMethodException { + String getterName = prefix + StringKit.capitalize(propertyName); + Method method = methodFinder.apply(object.getClass(), getterName); + return invokeMethod(object, singleArgumentValue, method, takesSingleArgumentTypeAsOnlyArgument(method)); + } + + /** + * Invoking public methods on package-protected classes via reflection + * causes exceptions. This method searches a class's hierarchy for + * public visibility parent classes with the desired getter. This + * particular case is required to support AutoValue style data classes, + * which have abstract public interfaces implemented by package-protected + * (generated) subclasses. + */ + private Method findPubliclyAccessibleMethod(CacheKey cacheKey, Class rootClass, String methodName, boolean dfeInUse, boolean allowStaticMethods) throws NoSuchMethodException { + Class currentClass = rootClass; + while (currentClass != null) { + if (Modifier.isPublic(currentClass.getModifiers())) { + if (dfeInUse) { + // + // try a getter that takes singleArgumentType first (if we have one) + try { + Method method = currentClass.getMethod(methodName, singleArgumentType); + if (isSuitablePublicMethod(method, allowStaticMethods)) { + METHOD_CACHE.putIfAbsent(cacheKey, new CachedMethod(method)); + return method; + } + } catch (NoSuchMethodException e) { + // ok try the next approach + } + } + Method method = currentClass.getMethod(methodName); + if (isSuitablePublicMethod(method, allowStaticMethods)) { + METHOD_CACHE.putIfAbsent(cacheKey, new CachedMethod(method)); + return method; + } + } + currentClass = currentClass.getSuperclass(); + } + assert rootClass != null; + return rootClass.getMethod(methodName); + } + + private boolean isSuitablePublicMethod(Method method, boolean allowStaticMethods) { + int methodModifiers = method.getModifiers(); + if (Modifier.isPublic(methodModifiers)) { + //noinspection RedundantIfStatement + if (Modifier.isStatic(methodModifiers) && !allowStaticMethods) { + return false; + } + return true; + } + return false; + } + + /* + https://docs.oracle.com/en/java/javase/15/language/records.html + + A record class declares a sequence of fields, and then the appropriate accessors, constructors, equals, hashCode, and toString methods are created automatically. + + Records cannot extend any class - so we need only check the root class for a publicly declared method with the propertyName + + However, we won't just restrict ourselves strictly to true records. We will find methods that are record like + and fetch them - e.g. `object.propertyName()` + + We won't allow static methods for record like methods however + */ + private Method findRecordMethod(CacheKey cacheKey, Class rootClass, String methodName) throws NoSuchMethodException { + return findPubliclyAccessibleMethod(cacheKey, rootClass, methodName, false, false); + } + + private Method findViaSetAccessible(CacheKey cacheKey, Class aClass, String methodName, boolean dfeInUse) throws NoSuchMethodException { + if (!USE_SET_ACCESSIBLE.get()) { + throw new FastNoSuchMethodException(methodName); + } + Class currentClass = aClass; + while (currentClass != null) { + Predicate whichMethods = mth -> { + if (dfeInUse) { + return hasZeroArgs(mth) || takesSingleArgumentTypeAsOnlyArgument(mth); + } + return hasZeroArgs(mth); + }; + Method[] declaredMethods = currentClass.getDeclaredMethods(); + Optional m = Arrays.stream(declaredMethods) + .filter(mth -> methodName.equals(mth.getName())) + .filter(whichMethods) + .min(mostMethodArgsFirst()); + if (m.isPresent()) { + try { + // few JVMs actually enforce this but it might happen + Method method = m.get(); + method.setAccessible(true); + METHOD_CACHE.putIfAbsent(cacheKey, new CachedMethod(method)); + return method; + } catch (SecurityException ignored) { + } + } + currentClass = currentClass.getSuperclass(); + } + throw new FastNoSuchMethodException(methodName); + } + + private Object getPropertyViaFieldAccess(CacheKey cacheKey, Object object, String propertyName) throws FastNoSuchMethodException { + Class aClass = object.getClass(); + try { + Field field = aClass.getField(propertyName); + FIELD_CACHE.putIfAbsent(cacheKey, field); + return field.get(object); + } catch (NoSuchFieldException e) { + if (!USE_SET_ACCESSIBLE.get()) { + throw new FastNoSuchMethodException(cacheKey.toString()); + } + // if not public fields then try via setAccessible + try { + Field field = aClass.getDeclaredField(propertyName); + field.setAccessible(true); + FIELD_CACHE.putIfAbsent(cacheKey, field); + return field.get(object); + } catch (SecurityException | NoSuchFieldException ignored2) { + throw new FastNoSuchMethodException(cacheKey.toString()); + } catch (IllegalAccessException e1) { + throw new GraphQLException(e); + } + } catch (IllegalAccessException e) { + throw new GraphQLException(e); + } + } + + private Object invokeMethod(Object object, Supplier singleArgumentValue, Method method, boolean takesSingleArgument) throws FastNoSuchMethodException { + try { + if (takesSingleArgument) { + Object argValue = singleArgumentValue.get(); + if (argValue == null) { + throw new FastNoSuchMethodException(method.getName()); + } + return method.invoke(object, argValue); + } else { + return method.invoke(object); + } + } catch (IllegalAccessException | InvocationTargetException e) { + throw new GraphQLException(e); + } + } + + private Object invokeField(Object object, Field field) { + try { + return field.get(object); + } catch (IllegalAccessException e) { + throw new GraphQLException(e); + } + } + + @SuppressWarnings("SimplifiableIfStatement") + private boolean isBooleanProperty(GraphQLType graphQLType) { + if (graphQLType == GraphQLBoolean) { + return true; + } + if (isNonNull(graphQLType)) { + return unwrapOne(graphQLType) == GraphQLBoolean; + } + return false; + } + + public void clearReflectionCache() { + LAMBDA_CACHE.clear(); + METHOD_CACHE.clear(); + FIELD_CACHE.clear(); + NEGATIVE_CACHE.clear(); + } + + public boolean setUseSetAccessible(boolean flag) { + return USE_SET_ACCESSIBLE.getAndSet(flag); + } + + public boolean setUseLambdaFactory(boolean flag) { + return USE_LAMBDA_FACTORY.getAndSet(flag); + } + + public boolean setUseNegativeCache(boolean flag) { + return USE_NEGATIVE_CACHE.getAndSet(flag); + } + + private CacheKey mkCacheKey(Object object, String propertyName) { + Class clazz = object.getClass(); + ClassLoader classLoader = clazz.getClassLoader(); + return new CacheKey(classLoader, clazz.getName(), propertyName); + } + + private static final class CacheKey { + private final ClassLoader classLoader; + private final String className; + private final String propertyName; + + private CacheKey(ClassLoader classLoader, String className, String propertyName) { + this.classLoader = classLoader; + this.className = className; + this.propertyName = propertyName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CacheKey)) { + return false; + } + CacheKey cacheKey = (CacheKey) o; + return Objects.equals(classLoader, cacheKey.classLoader) && Objects.equals(className, cacheKey.className) && Objects.equals(propertyName, cacheKey.propertyName); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + Objects.hashCode(classLoader); + result = 31 * result + Objects.hashCode(className); + result = 31 * result + Objects.hashCode(propertyName); + return result; + } + + @Override + public String toString() { + return "CacheKey{" + + "classLoader=" + classLoader + + ", className='" + className + '\'' + + ", propertyName='" + propertyName + '\'' + + '}'; + } + } + + // by not filling out the stack trace, we gain speed when using the exception as flow control + private boolean hasZeroArgs(Method mth) { + return mth.getParameterCount() == 0; + } + + private boolean takesSingleArgumentTypeAsOnlyArgument(Method mth) { + return mth.getParameterCount() == 1 && + mth.getParameterTypes()[0].equals(singleArgumentType); + } + + private static Comparator mostMethodArgsFirst() { + return Comparator.comparingInt(Method::getParameterCount).reversed(); + } + + private static class FastNoSuchMethodException extends NoSuchMethodException { + public FastNoSuchMethodException(String methodName) { + super(methodName); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + } +} diff --git a/src/main/java/graphql/schema/SchemaElementChildrenContainer.java b/src/main/java/graphql/schema/SchemaElementChildrenContainer.java new file mode 100644 index 0000000000..428913b012 --- /dev/null +++ b/src/main/java/graphql/schema/SchemaElementChildrenContainer.java @@ -0,0 +1,117 @@ +package graphql.schema; + +import graphql.PublicApi; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.emptyList; + +@PublicApi +public class SchemaElementChildrenContainer { + + private final Map> children = new LinkedHashMap<>(); + + private SchemaElementChildrenContainer(Map> children) { + this.children.putAll(assertNotNull(children)); + } + + public List getChildren(String key) { + return (List) children.getOrDefault(key, emptyList()); + } + + public T getChildOrNull(String key) { + List result = children.getOrDefault(key, new ArrayList<>()); + if (result.size() > 1) { + throw new IllegalStateException("children " + key + " is not a single value"); + } + return result.size() > 0 ? (T) result.get(0) : null; + } + + public Map> getChildren() { + return new LinkedHashMap<>(children); + } + + public List getChildrenAsList() { + List result = new ArrayList<>(); + children.values().forEach(result::addAll); + return result; + } + + public static Builder newSchemaElementChildrenContainer() { + return new Builder(); + } + + public static Builder newSchemaElementChildrenContainer(Map> childrenMap) { + return new Builder().children(childrenMap); + } + + public static Builder newSchemaElementChildrenContainer(SchemaElementChildrenContainer existing) { + return new Builder(existing); + } + + public SchemaElementChildrenContainer transform(Consumer builderConsumer) { + Builder builder = new Builder(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public boolean isEmpty() { + return this.children.isEmpty(); + } + + public static class Builder { + private final Map> children = new LinkedHashMap<>(); + + private Builder() { + + } + + private Builder(SchemaElementChildrenContainer other) { + this.children.putAll(other.children); + } + + public Builder child(String key, GraphQLSchemaElement child) { + // we allow null here to make the actual nodes easier + if (child == null) { + return this; + } + children.computeIfAbsent(key, (k) -> new ArrayList<>()); + children.get(key).add(child); + return this; + } + + public Builder children(String key, Collection children) { + this.children.computeIfAbsent(key, (k) -> new ArrayList<>()); + this.children.get(key).addAll(children); + return this; + } + + public Builder children(Map> children) { + this.children.clear(); + this.children.putAll((Map>) children); + return this; + } + + public Builder replaceChild(String key, int index, GraphQLSchemaElement newChild) { + assertNotNull(newChild); + this.children.get(key).set(index, newChild); + return this; + } + + public Builder removeChild(String key, int index) { + this.children.get(key).remove(index); + return this; + } + + public SchemaElementChildrenContainer build() { + return new SchemaElementChildrenContainer(this.children); + + } + } +} diff --git a/src/main/java/graphql/schema/SchemaTransformer.java b/src/main/java/graphql/schema/SchemaTransformer.java new file mode 100644 index 0000000000..41d669f4ed --- /dev/null +++ b/src/main/java/graphql/schema/SchemaTransformer.java @@ -0,0 +1,634 @@ +package graphql.schema; + +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.Breadcrumb; +import graphql.util.NodeAdapter; +import graphql.util.NodeLocation; +import graphql.util.NodeZipper; +import graphql.util.TraversalControl; +import graphql.util.Traverser; +import graphql.util.TraverserContext; +import graphql.util.TraverserVisitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotEmpty; +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER; +import static graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer; +import static graphql.schema.impl.StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted; +import static graphql.util.NodeZipper.ModificationType.DELETE; +import static graphql.util.NodeZipper.ModificationType.REPLACE; +import static graphql.util.TraversalControl.CONTINUE; + +/** + * Transforms a {@link GraphQLSchema} object by calling bac on a provided visitor. + *

+ * To change a {@link GraphQLSchemaElement} node in the schema you need + * to return {@link GraphQLTypeVisitor#changeNode(TraverserContext, GraphQLSchemaElement)} + * which instructs the schema transformer to change that element upon leaving that + * visitor method. + *

+ * {@code
+ *  public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) {
+ *      GraphQLObjectType newObjectType = mkSomeNewNode(objectType);
+ *      return changeNode(context, newObjectType);
+ *  }
+ *  }
+ * 
+ *

+ * To delete an element use {@link GraphQLTypeVisitor#deleteNode(TraverserContext)} + *

+ * {@code
+ *  public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) {
+ *      return deleteNode(context, objectType);
+ *  }
+ *  }
+ * 
+ *

+ * To insert elements use either {@link GraphQLTypeVisitor#insertAfter(TraverserContext, GraphQLSchemaElement)} or + * {@link GraphQLTypeVisitor#insertBefore(TraverserContext, GraphQLSchemaElement)} + * which will insert the new node before or after the current node being visited + *

+ * {@code
+ *  public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) {
+ *      GraphQLObjectType newObjectType = mkSomeNewNode();
+ *      return insertAfter(context, newObjectType);
+ *  }
+ *  }
+ * 
+ */ +@PublicApi +public class SchemaTransformer { + + /** + * Transforms a GraphQLSchema and returns a new GraphQLSchema object. + * + * @param schema the schema to transform + * @param visitor the visitor call back + * + * @return a new GraphQLSchema instance. + */ + public static GraphQLSchema transformSchema(GraphQLSchema schema, GraphQLTypeVisitor visitor) { + SchemaTransformer schemaTransformer = new SchemaTransformer(); + return schemaTransformer.transform(schema, visitor); + } + + /** + * Transforms a GraphQLSchema and returns a new GraphQLSchema object. + * + * @param schema the schema to transform + * @param visitor the visitor call back + * @param postTransformation a callback that can be as a final step to the schema + * + * @return a new GraphQLSchema instance. + */ + public static GraphQLSchema transformSchema(GraphQLSchema schema, GraphQLTypeVisitor visitor, Consumer postTransformation) { + SchemaTransformer schemaTransformer = new SchemaTransformer(); + return schemaTransformer.transform(schema, visitor, postTransformation); + } + + /** + * Transforms a {@link GraphQLSchemaElement} and returns a new element. + * + * @param schemaElement the schema element to transform + * @param visitor the visitor call back + * @param for two + * + * @return a new GraphQLSchemaElement instance. + */ + public static T transformSchema(final T schemaElement, GraphQLTypeVisitor visitor) { + SchemaTransformer schemaTransformer = new SchemaTransformer(); + return schemaTransformer.transform(schemaElement, visitor); + } + + public GraphQLSchema transform(final GraphQLSchema schema, GraphQLTypeVisitor visitor) { + return (GraphQLSchema) transformImpl(schema, null, visitor, null); + } + + public GraphQLSchema transform(final GraphQLSchema schema, GraphQLTypeVisitor visitor, Consumer postTransformation) { + return (GraphQLSchema) transformImpl(schema, null, visitor, postTransformation); + } + + public T transform(final T schemaElement, GraphQLTypeVisitor visitor) { + //noinspection unchecked + return (T) transformImpl(null, schemaElement, visitor, null); + } + + private Object transformImpl(final GraphQLSchema schema, GraphQLSchemaElement schemaElement, GraphQLTypeVisitor visitor, Consumer postTransformation) { + DummyRoot dummyRoot; + GraphQLCodeRegistry.Builder codeRegistry = null; + if (schema != null) { + dummyRoot = new DummyRoot(schema); + codeRegistry = GraphQLCodeRegistry.newCodeRegistry(schema.getCodeRegistry()); + } else { + dummyRoot = new DummyRoot(schemaElement); + } + + final Map changedTypes = new LinkedHashMap<>(); + final Map typeReferences = new LinkedHashMap<>(); + + // first pass - general transformation + boolean schemaChanged = traverseAndTransform(dummyRoot, changedTypes, typeReferences, visitor, codeRegistry, schema); + + // if we have changed any named elements AND we have type references referring to them then + // we need to make a second pass to replace these type references to the new names + if (!changedTypes.isEmpty()) { + boolean hasTypeRefsForChangedTypes = changedTypes.keySet().stream().anyMatch(typeReferences::containsKey); + if (hasTypeRefsForChangedTypes) { + replaceTypeReferences(dummyRoot, schema, codeRegistry, changedTypes); + } + } + + if (schema != null) { + + GraphQLSchema graphQLSchema = schema; + if (schemaChanged || codeRegistry.hasChanged()) { + graphQLSchema = dummyRoot.rebuildSchema(codeRegistry); + if (postTransformation != null) { + graphQLSchema = graphQLSchema.transform(postTransformation); + } + } + return graphQLSchema; + } else { + return dummyRoot.schemaElement; + } + } + + private void replaceTypeReferences(DummyRoot dummyRoot, GraphQLSchema schema, GraphQLCodeRegistry.Builder codeRegistry, Map changedTypes) { + GraphQLTypeVisitor typeRefVisitor = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLTypeReference(GraphQLTypeReference typeRef, TraverserContext context) { + GraphQLNamedType graphQLNamedType = changedTypes.get(typeRef.getName()); + if (graphQLNamedType != null) { + typeRef = GraphQLTypeReference.typeRef(graphQLNamedType.getName()); + return changeNode(context, typeRef); + } + return CONTINUE; + } + }; + traverseAndTransform(dummyRoot, new HashMap<>(), new HashMap<>(), typeRefVisitor, codeRegistry, schema); + } + + private boolean traverseAndTransform(DummyRoot dummyRoot, Map changedTypes, Map typeReferences, GraphQLTypeVisitor visitor, GraphQLCodeRegistry.Builder codeRegistry, GraphQLSchema schema) { + List> zippers = new LinkedList<>(); + Map> zipperByNodeAfterTraversing = new LinkedHashMap<>(); + Map> zipperByOriginalNode = new LinkedHashMap<>(); + + Map, List>>> breadcrumbsByZipper = new LinkedHashMap<>(); + + Map> reverseDependencies = new LinkedHashMap<>(); + Map> typeRefReverseDependencies = new LinkedHashMap<>(); + + TraverserVisitor nodeTraverserVisitor = new TraverserVisitor<>() { + @Override + public TraversalControl enter(TraverserContext context) { + GraphQLSchemaElement currentSchemaElement = context.thisNode(); + if (currentSchemaElement == dummyRoot) { + return TraversalControl.CONTINUE; + } + if (currentSchemaElement instanceof GraphQLTypeReference) { + GraphQLTypeReference typeRef = (GraphQLTypeReference) currentSchemaElement; + typeReferences.put(typeRef.getName(), typeRef); + } + NodeZipper nodeZipper = new NodeZipper<>(currentSchemaElement, context.getBreadcrumbs(), SCHEMA_ELEMENT_ADAPTER); + context.setVar(NodeZipper.class, nodeZipper); + context.setVar(NodeAdapter.class, SCHEMA_ELEMENT_ADAPTER); + + int zippersBefore = zippers.size(); + TraversalControl result = currentSchemaElement.accept(context, visitor); + + // detection if the node was changed + if (zippersBefore + 1 == zippers.size()) { + nodeZipper = zippers.get(zippers.size() - 1); + if (context.originalThisNode() instanceof GraphQLNamedType && context.isChanged()) { + GraphQLNamedType originalNamedType = (GraphQLNamedType) context.originalThisNode(); + GraphQLNamedType changedNamedType = (GraphQLNamedType) context.thisNode(); + if (!originalNamedType.getName().equals(changedNamedType.getName())) { + changedTypes.put(originalNamedType.getName(), changedNamedType); + } + } + } + zipperByOriginalNode.put(context.originalThisNode(), nodeZipper); + + if (context.isDeleted()) { + zipperByNodeAfterTraversing.put(context.originalThisNode(), nodeZipper); + } else { + zipperByNodeAfterTraversing.put(context.thisNode(), nodeZipper); + } + + breadcrumbsByZipper.put(nodeZipper, new ArrayList<>()); + breadcrumbsByZipper.get(nodeZipper).add(context.getBreadcrumbs()); + if (nodeZipper.getModificationType() != NodeZipper.ModificationType.DELETE) { + reverseDependencies.computeIfAbsent(context.thisNode(), ign -> new ArrayList<>()).add(context.getParentNode()); + + if (context.originalThisNode() instanceof GraphQLTypeReference) { + String typeName = ((GraphQLTypeReference) context.originalThisNode()).getName(); + typeRefReverseDependencies.computeIfAbsent(typeName, ign -> new ArrayList<>()).add(context.getParentNode()); + } + } + return result; + + } + + @Override + public TraversalControl leave(TraverserContext context) { + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl backRef(TraverserContext context) { + NodeZipper zipper = zipperByOriginalNode.get(context.thisNode()); + breadcrumbsByZipper.get(zipper).add(context.getBreadcrumbs()); + if (zipper.getModificationType() == DELETE) { + return CONTINUE; + } + visitor.visitBackRef(context); + List reverseDependenciesForCurNode = reverseDependencies.get(zipper.getCurNode()); + assertNotNull(reverseDependenciesForCurNode); + reverseDependenciesForCurNode.add(context.getParentNode()); + return TraversalControl.CONTINUE; + } + }; + + + Traverser traverser = Traverser.depthFirstWithNamedChildren(SCHEMA_ELEMENT_ADAPTER::getNamedChildren, zippers, null); + if (codeRegistry != null) { + traverser.rootVar(GraphQLCodeRegistry.Builder.class, codeRegistry); + } + if (schema != null) { + traverser.rootVar(GraphQLSchema.class, schema); + } + + traverser.traverse(dummyRoot, nodeTraverserVisitor); + + List> stronglyConnectedTopologicallySorted = getStronglyConnectedComponentsTopologicallySorted(reverseDependencies, typeRefReverseDependencies); + + return zipUpToDummyRoot(zippers, stronglyConnectedTopologicallySorted, breadcrumbsByZipper, zipperByNodeAfterTraversing); + } + + private static class RelevantZippersAndBreadcrumbs { + final Multimap> zipperByParent = LinkedHashMultimap.create(); + final Set> relevantZippers; + final Map, List>>> breadcrumbsByZipper; + + public RelevantZippersAndBreadcrumbs(List> relevantZippers, + Map, List>>> breadcrumbsByZipper) { + this.relevantZippers = new LinkedHashSet<>(relevantZippers); + this.breadcrumbsByZipper = breadcrumbsByZipper; + for (NodeZipper zipper : relevantZippers) { + for (List> breadcrumbs : breadcrumbsByZipper.get(zipper)) { + zipperByParent.put(breadcrumbs.get(0).getNode(), zipper); + } + } + } + + public boolean isRelevantZipper(NodeZipper zipper) { + return relevantZippers.contains(zipper); + } + + public Collection> zippersWithParent(GraphQLSchemaElement parent) { + return zipperByParent.get(parent); + } + + public void removeRelevantZipper(NodeZipper zipper) { + relevantZippers.remove(zipper); + } + + public List>> getBreadcrumbs(NodeZipper zipper) { + return breadcrumbsByZipper.get(zipper); + } + + public void updateZipper(NodeZipper currentZipper, + NodeZipper newZipper) { + // the current zipper is not always relevant, meaning this has no effect sometimes + relevantZippers.remove(currentZipper); + relevantZippers.add(newZipper); + + + List>> currentBreadcrumbs = breadcrumbsByZipper.get(currentZipper); + assertNotNull(currentBreadcrumbs, "No breadcrumbs found for zipper %s", currentZipper); + for (List> breadcrumbs : currentBreadcrumbs) { + GraphQLSchemaElement parent = breadcrumbs.get(0).getNode(); + zipperByParent.remove(parent, currentZipper); + zipperByParent.put(parent, newZipper); + } + breadcrumbsByZipper.remove(currentZipper); + breadcrumbsByZipper.put(newZipper, currentBreadcrumbs); + + } + + } + + + private boolean zipUpToDummyRoot(List> zippers, + List> stronglyConnectedTopologicallySorted, + Map, List>>> breadcrumbsByZipper, + Map> nodeToZipper) { + if (zippers.size() == 0) { + return false; + } + RelevantZippersAndBreadcrumbs relevantZippers = new RelevantZippersAndBreadcrumbs(zippers, breadcrumbsByZipper); + + for (int i = stronglyConnectedTopologicallySorted.size() - 1; i >= 0; i--) { + List scc = stronglyConnectedTopologicallySorted.get(i); + // performance relevant: we avoid calling zipperWithSameParent twice + // for SCC of size one. + if (scc.size() > 1) { + boolean sccChanged = false; + List unchangedSccElements = new ArrayList<>(); + for (GraphQLSchemaElement element : scc) { + // if the current element itself has a zipper it is changed + if (relevantZippers.isRelevantZipper(nodeToZipper.get(element))) { + sccChanged = true; + continue; + } + // if the current element is changed via "moveUp" it is changed + Map, Breadcrumb> zipperWithSameParent = zipperWithSameParent(element, relevantZippers, false); + if (zipperWithSameParent.size() > 0) { + sccChanged = true; + } else { + unchangedSccElements.add(element); + } + } + if (!sccChanged) { + continue; + } + // we need to change all elements inside the current SCC + for (GraphQLSchemaElement element : unchangedSccElements) { + NodeZipper currentZipper = nodeToZipper.get(element); + NodeZipper newZipper = currentZipper.withNewNode(element.copy()); + nodeToZipper.put(element, newZipper); + relevantZippers.updateZipper(currentZipper, newZipper); + } + } + for (int j = scc.size() - 1; j >= 0; j--) { + GraphQLSchemaElement element = scc.get(j); + Map, Breadcrumb> zipperWithSameParent = zipperWithSameParent(element, relevantZippers, true); + // this means we have a node which doesn't need to be changed + if (zipperWithSameParent.size() == 0) { + continue; + } + NodeZipper newZipper = moveUp(element, zipperWithSameParent); + + if (element instanceof DummyRoot) { + // this means we have updated the dummy root and we are done (dummy root is a special as it gets updated in place, see Implementation of DummyRoot) + break; + } + + NodeZipper curZipperForElement = nodeToZipper.get(element); + assertNotNull(curZipperForElement, "curZipperForElement is null for parentNode %s", element); + relevantZippers.updateZipper(curZipperForElement, newZipper); + + } + } + return true; + } + + private Map, Breadcrumb> zipperWithSameParent( + GraphQLSchemaElement parent, + RelevantZippersAndBreadcrumbs relevantZippers, + boolean cleanup) { + Map, Breadcrumb> result = new LinkedHashMap<>(); + Collection> zippersWithParent = relevantZippers.zippersWithParent(parent); + Iterator> zippersIter = zippersWithParent.iterator(); + outer: + while (zippersIter.hasNext()) { + NodeZipper zipper = zippersIter.next(); + List>> listOfBreadcrumbsList = assertNotNull(relevantZippers.getBreadcrumbs(zipper)); + for (int i = 0; i < listOfBreadcrumbsList.size(); i++) { + List> path = listOfBreadcrumbsList.get(i); + if (path.get(0).getNode() == parent) { + result.put(zipper, path.get(0)); + if (cleanup) { + // remove breadcrumb we just used + listOfBreadcrumbsList.remove(i); + if (listOfBreadcrumbsList.size() == 0) { + // if there are no breadcrumbs left for this zipper it is safe to remove + relevantZippers.removeRelevantZipper(zipper); + } + } + continue outer; + } + } + } + return result; + } + + private NodeZipper moveUp( + GraphQLSchemaElement parent, + Map, Breadcrumb> sameParentsZipper) { + Set> sameParent = sameParentsZipper.keySet(); + assertNotEmpty(sameParent, "expected at least one zipper"); + + Map> childrenMap = new HashMap<>(SCHEMA_ELEMENT_ADAPTER.getNamedChildren(parent)); + Map indexCorrection = new HashMap<>(); + + List zipperWithOneParents = new ArrayList<>(sameParent.size()); + for (NodeZipper zipper : sameParent) { + Breadcrumb breadcrumb = sameParentsZipper.get(zipper); + zipperWithOneParents.add(new ZipperWithOneParent(zipper, breadcrumb)); + } + + zipperWithOneParents.sort((zipperWithOneParent1, zipperWithOneParent2) -> { + NodeZipper zipper1 = zipperWithOneParent1.zipper; + NodeZipper zipper2 = zipperWithOneParent2.zipper; + Breadcrumb breadcrumb1 = zipperWithOneParent1.parent; + Breadcrumb breadcrumb2 = zipperWithOneParent2.parent; + int index1 = breadcrumb1.getLocation().getIndex(); + int index2 = breadcrumb2.getLocation().getIndex(); + if (index1 != index2) { + return Integer.compare(index1, index2); + } + NodeZipper.ModificationType modificationType1 = zipper1.getModificationType(); + NodeZipper.ModificationType modificationType2 = zipper2.getModificationType(); + + // same index can never be deleted and changed at the same time + + if (modificationType1 == modificationType2) { + return 0; + } + + // always first replacing the node + if (modificationType1 == REPLACE) { + return -1; + } + // and then INSERT_BEFORE before INSERT_AFTER + return modificationType1 == NodeZipper.ModificationType.INSERT_BEFORE ? -1 : 1; + + }); + + for (ZipperWithOneParent zipperWithOneParent : zipperWithOneParents) { + NodeZipper zipper = zipperWithOneParent.zipper; + Breadcrumb breadcrumb = zipperWithOneParent.parent; + NodeLocation location = breadcrumb.getLocation(); + Integer ixDiff = indexCorrection.getOrDefault(location.getName(), 0); + int ix = location.getIndex() + ixDiff; + String name = location.getName(); + List childList = new ArrayList<>(childrenMap.get(name)); + switch (zipper.getModificationType()) { + case REPLACE: + childList.set(ix, zipper.getCurNode()); + break; + case DELETE: + childList.remove(ix); + indexCorrection.put(name, ixDiff - 1); + break; + case INSERT_BEFORE: + childList.add(ix, zipper.getCurNode()); + indexCorrection.put(name, ixDiff + 1); + break; + case INSERT_AFTER: + childList.add(ix + 1, zipper.getCurNode()); + indexCorrection.put(name, ixDiff + 1); + break; + } + childrenMap.put(name, childList); + } + + GraphQLSchemaElement newNode = SCHEMA_ELEMENT_ADAPTER.withNewChildren(parent, childrenMap); + final List> oldBreadcrumbs = sameParent.iterator().next().getBreadcrumbs(); + List> newBreadcrumbs; + if (oldBreadcrumbs.size() > 1) { + newBreadcrumbs = oldBreadcrumbs.subList(1, oldBreadcrumbs.size()); + } else { + newBreadcrumbs = ImmutableKit.emptyList(); + } + return new NodeZipper<>(newNode, newBreadcrumbs, SCHEMA_ELEMENT_ADAPTER); + } + + private static class ZipperWithOneParent { + public NodeZipper zipper; + public Breadcrumb parent; + + public ZipperWithOneParent(NodeZipper zipper, Breadcrumb parent) { + this.zipper = zipper; + this.parent = parent; + } + } + + // artificial schema element which serves as root element for the transformation + private static class DummyRoot implements GraphQLSchemaElement { + + static final String QUERY = "query"; + static final String MUTATION = "mutation"; + static final String SUBSCRIPTION = "subscription"; + static final String ADD_TYPES = "addTypes"; + static final String DIRECTIVES = "directives"; + static final String SCHEMA_DIRECTIVES = "schemaDirectives"; + static final String SCHEMA_APPLIED_DIRECTIVES = "schemaAppliedDirectives"; + static final String INTROSPECTION = "introspection"; + static final String SCHEMA_ELEMENT = "schemaElement"; + + GraphQLSchema schema; + GraphQLObjectType query; + GraphQLObjectType mutation; + GraphQLObjectType subscription; + GraphQLObjectType introspectionSchemaType; + Set additionalTypes; + Set directives; + Set schemaDirectives; + Set schemaAppliedDirectives; + GraphQLSchemaElement schemaElement; + + DummyRoot(GraphQLSchema schema) { + this.schema = schema; + query = schema.getQueryType(); + mutation = schema.isSupportingMutations() ? schema.getMutationType() : null; + subscription = schema.isSupportingSubscriptions() ? schema.getSubscriptionType() : null; + additionalTypes = schema.getAdditionalTypes(); + schemaDirectives = new LinkedHashSet<>(schema.getSchemaDirectives()); + schemaAppliedDirectives = new LinkedHashSet<>(schema.getSchemaAppliedDirectives()); + directives = new LinkedHashSet<>(schema.getDirectives()); + introspectionSchemaType = schema.getIntrospectionSchemaType(); + } + + DummyRoot(GraphQLSchemaElement schemaElement) { + this.schemaElement = schemaElement; + } + + @Override + public GraphQLSchemaElement copy() { + return assertShouldNeverHappen(); + } + + @Override + public List getChildren() { + return assertShouldNeverHappen(); + } + + @Override + public SchemaElementChildrenContainer getChildrenWithTypeReferences() { + SchemaElementChildrenContainer.Builder builder = newSchemaElementChildrenContainer(); + if (schemaElement != null) { + builder.child(SCHEMA_ELEMENT, schemaElement); + } else { + builder.child(QUERY, query); + if (schema.isSupportingMutations()) { + builder.child(MUTATION, mutation); + } + if (schema.isSupportingSubscriptions()) { + builder.child(SUBSCRIPTION, subscription); + } + builder.children(ADD_TYPES, additionalTypes); + builder.children(DIRECTIVES, directives); + builder.children(SCHEMA_DIRECTIVES, schemaDirectives); + builder.children(SCHEMA_APPLIED_DIRECTIVES, schemaAppliedDirectives); + builder.child(INTROSPECTION, introspectionSchemaType); + } + return builder.build(); + } + + @Override + public GraphQLSchemaElement withNewChildren(SchemaElementChildrenContainer newChildren) { + if (this.schemaElement != null) { + this.schemaElement = newChildren.getChildOrNull(SCHEMA_ELEMENT); + return this; + } + // special hack: we don't create a new dummy root, but we simply update it + query = newChildren.getChildOrNull(QUERY); + mutation = newChildren.getChildOrNull(MUTATION); + subscription = newChildren.getChildOrNull(SUBSCRIPTION); + introspectionSchemaType = newChildren.getChildOrNull(INTROSPECTION); + additionalTypes = new LinkedHashSet<>(newChildren.getChildren(ADD_TYPES)); + directives = new LinkedHashSet<>(newChildren.getChildren(DIRECTIVES)); + schemaDirectives = new LinkedHashSet<>(newChildren.getChildren(SCHEMA_DIRECTIVES)); + schemaAppliedDirectives = new LinkedHashSet<>(newChildren.getChildren(SCHEMA_APPLIED_DIRECTIVES)); + return this; + } + + @Override + public TraversalControl accept(TraverserContext context, GraphQLTypeVisitor visitor) { + return assertShouldNeverHappen(); + } + + public GraphQLSchema rebuildSchema(GraphQLCodeRegistry.Builder codeRegistry) { + return GraphQLSchema.newSchema() + .query(this.query) + .mutation(this.mutation) + .subscription(this.subscription) + .additionalTypes(this.additionalTypes) + .additionalDirectives(this.directives) + .introspectionSchemaType(this.introspectionSchemaType) + .withSchemaDirectives(this.schemaDirectives) + .withSchemaAppliedDirectives(this.schemaAppliedDirectives) + .codeRegistry(codeRegistry.build()) + .description(schema.getDescription()) + .build(); + } + } +} diff --git a/src/main/java/graphql/schema/SchemaTraverser.java b/src/main/java/graphql/schema/SchemaTraverser.java new file mode 100644 index 0000000000..5322f4b407 --- /dev/null +++ b/src/main/java/graphql/schema/SchemaTraverser.java @@ -0,0 +1,158 @@ +package graphql.schema; + + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; +import graphql.util.TraversalControl; +import graphql.util.Traverser; +import graphql.util.TraverserContext; +import graphql.util.TraverserResult; +import graphql.util.TraverserVisitor; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import static graphql.util.TraversalControl.CONTINUE; + +@PublicApi +public class SchemaTraverser { + + + private final Function> getChildren; + + public SchemaTraverser(Function> getChildren) { + this.getChildren = getChildren; + } + + public SchemaTraverser() { + this(GraphQLSchemaElement::getChildren); + } + + /** + * This will visit all of the schema elements in the specified schema and invokes the visitor. + * + * @param typeVisitor a list of visitors to use + * @param schema the schema to visit + * + * @return a traversal result + */ + public TraverserResult depthFirstFullSchema(GraphQLTypeVisitor typeVisitor, GraphQLSchema schema) { + return depthFirstFullSchema(Collections.singletonList(typeVisitor), schema, ImmutableKit.emptyMap()); + } + + /** + * This will visit all of the schema elements in the specified schema, invoking each visitor in turn. + * + * @param typeVisitors a list of visitors to use + * @param schema the schema to visit + * @param rootVars this sets up variables to be made available to the {@link TraverserContext}. This can be empty but not null + * + * @return a traversal result + */ + public TraverserResult depthFirstFullSchema(List typeVisitors, GraphQLSchema schema, Map, Object> rootVars) { + Set roots = new LinkedHashSet<>(); + roots.add(schema.getQueryType()); + if (schema.isSupportingMutations()) { + roots.add(schema.getMutationType()); + } + if (schema.isSupportingSubscriptions()) { + roots.add(schema.getSubscriptionType()); + } + roots.addAll(schema.getAdditionalTypes()); + roots.addAll(schema.getDirectives()); + roots.addAll(schema.getSchemaDirectives()); + roots.addAll(schema.getSchemaAppliedDirectives()); + roots.add(schema.getIntrospectionSchemaType()); + TraverserDelegateListVisitor traverserDelegateListVisitor = new TraverserDelegateListVisitor(typeVisitors); + Traverser traverser = initTraverser().rootVars(rootVars).rootVar(GraphQLSchema.class, schema); + return traverser.traverse(roots, traverserDelegateListVisitor); + } + + public TraverserResult depthFirst(GraphQLTypeVisitor graphQLTypeVisitor, GraphQLSchemaElement root) { + return depthFirst(graphQLTypeVisitor, Collections.singletonList(root)); + } + + public TraverserResult depthFirst(final GraphQLTypeVisitor graphQLTypeVisitor, Collection roots) { + return depthFirst(initTraverser(), new TraverserDelegateVisitor(graphQLTypeVisitor), roots); + } + + + public TraverserResult depthFirst(final Traverser traverser, + final TraverserVisitor traverserVisitor, + Collection roots) { + return doTraverse(traverser, roots, traverserVisitor); + } + + private Traverser initTraverser() { + return Traverser.depthFirst(getChildren); + } + + private TraverserResult doTraverse(Traverser traverser, + Collection roots, + TraverserVisitor traverserVisitor) { + return traverser.traverse(roots, traverserVisitor); + } + + private static class TraverserDelegateVisitor implements TraverserVisitor { + private final GraphQLTypeVisitor delegate; + + TraverserDelegateVisitor(GraphQLTypeVisitor delegate) { + this.delegate = delegate; + + } + + @Override + public TraversalControl enter(TraverserContext context) { + return context.thisNode().accept(context, delegate); + } + + @Override + public TraversalControl leave(TraverserContext context) { + return CONTINUE; + } + + @Override + public TraversalControl backRef(TraverserContext context) { + return delegate.visitBackRef(context); + } + } + + private static class TraverserDelegateListVisitor implements TraverserVisitor { + private final List typeVisitors; + + TraverserDelegateListVisitor(List typeVisitors) { + this.typeVisitors = typeVisitors; + + } + + @Override + public TraversalControl enter(TraverserContext context) { + for (GraphQLTypeVisitor graphQLTypeVisitor : typeVisitors) { + TraversalControl control = context.thisNode().accept(context, graphQLTypeVisitor); + if (control != CONTINUE) { + return control; + } + } + return CONTINUE; + } + + @Override + public TraversalControl leave(TraverserContext context) { + return CONTINUE; + } + + @Override + public TraversalControl backRef(TraverserContext context) { + for (GraphQLTypeVisitor graphQLTypeVisitor : typeVisitors) { + graphQLTypeVisitor.visitBackRef(context); + } + return CONTINUE; + } + } + +} diff --git a/src/main/java/graphql/schema/SchemaUtil.java b/src/main/java/graphql/schema/SchemaUtil.java deleted file mode 100644 index 98faf2a7bc..0000000000 --- a/src/main/java/graphql/schema/SchemaUtil.java +++ /dev/null @@ -1,255 +0,0 @@ -package graphql.schema; - - -import graphql.Assert; -import graphql.AssertException; -import graphql.Internal; -import graphql.introspection.Introspection; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static graphql.schema.GraphQLTypeUtil.isList; -import static graphql.schema.GraphQLTypeUtil.isNonNull; -import static graphql.schema.GraphQLTypeUtil.unwrapOne; -import static java.lang.String.format; - -@Internal -public class SchemaUtil { - - @SuppressWarnings("StatementWithEmptyBody") - private void collectTypes(GraphQLType root, Map result) { - if (isNonNull(root)) { - collectTypes(unwrapOne(root), result); - } else if (isList(root)) { - collectTypes(unwrapOne(root), result); - } else if (root instanceof GraphQLEnumType) { - assertTypeUniqueness(root, result); - result.put(root.getName(), root); - } else if (root instanceof GraphQLScalarType) { - assertTypeUniqueness(root, result); - result.put(root.getName(), root); - } else if (root instanceof GraphQLObjectType) { - collectTypesForObjects((GraphQLObjectType) root, result); - } else if (root instanceof GraphQLInterfaceType) { - collectTypesForInterfaces((GraphQLInterfaceType) root, result); - } else if (root instanceof GraphQLUnionType) { - collectTypesForUnions((GraphQLUnionType) root, result); - } else if (root instanceof GraphQLInputObjectType) { - collectTypesForInputObjects((GraphQLInputObjectType) root, result); - } else if (root instanceof GraphQLTypeReference) { - // nothing to do - } else { - Assert.assertShouldNeverHappen("Unknown type %s", root); - } - } - - /* - From http://facebook.github.io/graphql/#sec-Type-System - - All types within a GraphQL schema must have unique names. No two provided types may have the same name. - No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types). - - Enforcing this helps avoid problems later down the track fo example https://github.com/graphql-java/graphql-java/issues/373 - */ - private void assertTypeUniqueness(GraphQLType type, Map result) { - GraphQLType existingType = result.get(type.getName()); - // do we have an existing definition - if (existingType != null) { - // type references are ok - if (!(existingType instanceof GraphQLTypeReference || type instanceof GraphQLTypeReference)) - // object comparison here is deliberate - if (existingType != type) { - throw new AssertException(format("All types within a GraphQL schema must have unique names. No two provided types may have the same name.\n" + - "No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).\n" + - "You have redefined the type '%s' from being a '%s' to a '%s'", - type.getName(), existingType.getClass().getSimpleName(), type.getClass().getSimpleName())); - } - } - } - - private void collectTypesForUnions(GraphQLUnionType unionType, Map result) { - assertTypeUniqueness(unionType, result); - - result.put(unionType.getName(), unionType); - for (GraphQLType type : unionType.getTypes()) { - collectTypes(type, result); - } - - } - - private void collectTypesForInterfaces(GraphQLInterfaceType interfaceType, Map result) { - if (result.containsKey(interfaceType.getName()) && !(result.get(interfaceType.getName()) instanceof GraphQLTypeReference)) { - assertTypeUniqueness(interfaceType, result); - return; - } - result.put(interfaceType.getName(), interfaceType); - - // this deliberately has open field visibility as its collecting on the whole schema - for (GraphQLFieldDefinition fieldDefinition : interfaceType.getFieldDefinitions()) { - collectTypes(fieldDefinition.getType(), result); - for (GraphQLArgument fieldArgument : fieldDefinition.getArguments()) { - collectTypes(fieldArgument.getType(), result); - } - } - } - - - private void collectTypesForObjects(GraphQLObjectType objectType, Map result) { - if (result.containsKey(objectType.getName()) && !(result.get(objectType.getName()) instanceof GraphQLTypeReference)) { - assertTypeUniqueness(objectType, result); - return; - } - result.put(objectType.getName(), objectType); - - // this deliberately has open field visibility as its collecting on the whole schema - for (GraphQLFieldDefinition fieldDefinition : objectType.getFieldDefinitions()) { - collectTypes(fieldDefinition.getType(), result); - for (GraphQLArgument fieldArgument : fieldDefinition.getArguments()) { - collectTypes(fieldArgument.getType(), result); - } - } - for (GraphQLOutputType interfaceType : objectType.getInterfaces()) { - collectTypes(interfaceType, result); - } - } - - private void collectTypesForInputObjects(GraphQLInputObjectType objectType, Map result) { - if (result.containsKey(objectType.getName()) && !(result.get(objectType.getName()) instanceof GraphQLTypeReference)) { - assertTypeUniqueness(objectType, result); - return; - } - result.put(objectType.getName(), objectType); - - for (GraphQLInputObjectField fieldDefinition : objectType.getFields()) { - collectTypes(fieldDefinition.getType(), result); - } - } - - - Map allTypes(GraphQLSchema schema, Set additionalTypes) { - Map typesByName = new LinkedHashMap<>(); - collectTypes(schema.getQueryType(), typesByName); - if (schema.isSupportingMutations()) { - collectTypes(schema.getMutationType(), typesByName); - } - if (schema.isSupportingSubscriptions()) { - collectTypes(schema.getSubscriptionType(), typesByName); - } - if (additionalTypes != null) { - for (GraphQLType type : additionalTypes) { - collectTypes(type, typesByName); - } - } - collectTypes(Introspection.__Schema, typesByName); - return typesByName; - } - - /* - * Indexes GraphQLObject types registered with the provided schema by implemented GraphQLInterface name - * - * This helps in accelerates/simplifies collecting types that implement a certain interface - * - * Provided to replace {@link #findImplementations(graphql.schema.GraphQLSchema, graphql.schema.GraphQLInterfaceType)} - * - */ - Map> groupImplementations(GraphQLSchema schema) { - Map> result = new HashMap<>(); - for (GraphQLType type : schema.getAllTypesAsList()) { - if (type instanceof GraphQLObjectType) { - for (GraphQLOutputType interfaceType : ((GraphQLObjectType) type).getInterfaces()) { - List myGroup = result.computeIfAbsent(interfaceType.getName(), k -> new ArrayList<>()); - myGroup.add((GraphQLObjectType) type); - } - } - } - - return result; - } - - /** - * This method is deprecated due to a performance concern. - * - * The Algorithm complexity: O(n^2), where n is number of registered GraphQLTypes - * - * That indexing operation is performed twice per input document: - * 1. during validation - * 2. during execution - * - * We now indexed all types at the schema creation, which has brought complexity down to O(1) - * - * @param schema GraphQL schema - * @param interfaceType an interface type to find implementations for - * - * @return List of object types implementing provided interface - * - * @deprecated use {@link graphql.schema.GraphQLSchema#getImplementations(GraphQLInterfaceType)} instead - */ - @Deprecated - public List findImplementations(GraphQLSchema schema, GraphQLInterfaceType interfaceType) { - List result = new ArrayList<>(); - for (GraphQLType type : schema.getAllTypesAsList()) { - if (!(type instanceof GraphQLObjectType)) { - continue; - } - GraphQLObjectType objectType = (GraphQLObjectType) type; - if ((objectType).getInterfaces().contains(interfaceType)) { - result.add(objectType); - } - } - return result; - } - - - void replaceTypeReferences(GraphQLSchema schema) { - Map typeMap = schema.getTypeMap(); - for (GraphQLType type : typeMap.values()) { - if (type instanceof GraphQLFieldsContainer) { - resolveTypeReferencesForFieldsContainer((GraphQLFieldsContainer) type, typeMap); - } - if (type instanceof GraphQLInputFieldsContainer) { - resolveTypeReferencesForInputFieldsContainer((GraphQLInputFieldsContainer) type, typeMap); - } - if (type instanceof GraphQLObjectType) { - ((GraphQLObjectType) type).replaceTypeReferences(typeMap); - } - if (type instanceof GraphQLUnionType) { - ((GraphQLUnionType) type).replaceTypeReferences(typeMap); - } - } - } - - private void resolveTypeReferencesForFieldsContainer(GraphQLFieldsContainer fieldsContainer, Map typeMap) { - for (GraphQLFieldDefinition fieldDefinition : fieldsContainer.getFieldDefinitions()) { - fieldDefinition.replaceTypeReferences(typeMap); - for (GraphQLArgument argument : fieldDefinition.getArguments()) { - argument.replaceTypeReferences(typeMap); - } - } - } - - private void resolveTypeReferencesForInputFieldsContainer(GraphQLInputFieldsContainer fieldsContainer, Map typeMap) { - for (GraphQLInputObjectField fieldDefinition : fieldsContainer.getFieldDefinitions()) { - fieldDefinition.replaceTypeReferences(typeMap); - } - } - - GraphQLType resolveTypeReference(GraphQLType type, Map typeMap) { - if (type instanceof GraphQLTypeReference || typeMap.containsKey(type.getName())) { - GraphQLType resolvedType = typeMap.get(type.getName()); - Assert.assertTrue(resolvedType != null, "type %s not found in schema", type.getName()); - return resolvedType; - } - if (isList(type)) { - ((GraphQLList) type).replaceTypeReferences(typeMap); - } - if (isNonNull(type)) { - ((GraphQLNonNull) type).replaceTypeReferences(typeMap); - } - return type; - } -} diff --git a/src/main/java/graphql/schema/SelectedField.java b/src/main/java/graphql/schema/SelectedField.java new file mode 100644 index 0000000000..e9b3dd89ce --- /dev/null +++ b/src/main/java/graphql/schema/SelectedField.java @@ -0,0 +1,95 @@ +package graphql.schema; + +import graphql.PublicApi; + +import java.util.List; +import java.util.Map; + +/** + * A {@link graphql.schema.SelectedField} represents a field that occurred in a query selection set during + * execution and they are returned from using the {@link graphql.schema.DataFetchingFieldSelectionSet} + * interface returned via {@link DataFetchingEnvironment#getSelectionSet()} + */ +@PublicApi +public interface SelectedField { + /** + * @return the simple name of the selected field + */ + String getName(); + + /** + * The selected field has a simple qualified name which is the path of field names to it. + * For example `payments/amount`. + * + * @return the simple qualified name of the selected field + */ + String getQualifiedName(); + + /** + * The selected field has a more complex type qualified name which is the path of field names to it + * as well as the object type of the parent. For example `[Invoice, Statement].payments/[Payment].amount` + * + * @return the fully qualified name of the selected field + */ + String getFullyQualifiedName(); + + /** + * @return the object types of this SelectedField + */ + List getObjectTypes(); + + /** + * @return The list of all object types + */ + List getObjectTypeNames(); + + /** + * @return the field runtime definition + */ + List getFieldDefinitions(); + + /** + * @return the type of this field + */ + GraphQLOutputType getType(); + + /** + * @return a map of the arguments to this selected field + */ + Map getArguments(); + + /** + * @return the level of the selected field within the query + */ + int getLevel(); + + /** + * @return whether the field is conditionally present. + */ + boolean isConditional(); + + /** + * @return the alias of the selected field or null if not alias was used + */ + String getAlias(); + + /** + * The result key is either the field query alias OR the field name in that preference order + * + * @return the result key of the selected field + */ + String getResultKey(); + + /** + * This will return the parent of the selected field OR null if there is no single parent, it that field + * was a top level field OR the parent was a non concrete field. + * + * @return the fields selected parent or null if there is not one + */ + SelectedField getParentField(); + + /** + * @return a sub selection set (if it has any) + */ + DataFetchingFieldSelectionSet getSelectionSet(); +} diff --git a/src/main/java/graphql/schema/SingletonPropertyDataFetcher.java b/src/main/java/graphql/schema/SingletonPropertyDataFetcher.java new file mode 100644 index 0000000000..8455963f0f --- /dev/null +++ b/src/main/java/graphql/schema/SingletonPropertyDataFetcher.java @@ -0,0 +1,71 @@ +package graphql.schema; + +import java.util.function.Supplier; + +/** + * The {@link SingletonPropertyDataFetcher} is much like the {@link PropertyDataFetcher} except + * that it is designed to only ever fetch properties via the name of the field passed in. + *

+ * This uses the same code as {@link PropertyDataFetcher} and hence is also controlled + * by static methods such as {@link PropertyDataFetcher#setUseNegativeCache(boolean)} + * + * @param for two + */ +public class SingletonPropertyDataFetcher implements LightDataFetcher { + + private static final SingletonPropertyDataFetcher SINGLETON_FETCHER = new SingletonPropertyDataFetcher<>(); + + private static final DataFetcherFactory SINGLETON_FETCHER_FACTORY = new DataFetcherFactory() { + @SuppressWarnings("deprecation") + @Override + public DataFetcher get(DataFetcherFactoryEnvironment environment) { + return SINGLETON_FETCHER; + } + + @Override + public DataFetcher get(GraphQLFieldDefinition fieldDefinition) { + return SINGLETON_FETCHER; + } + }; + + /** + * This returns the same singleton {@link LightDataFetcher} that fetches property values + * based on the name of the field that iis passed into it. + * + * @return a singleton property data fetcher + */ + public static LightDataFetcher singleton() { + return SINGLETON_FETCHER; + } + + /** + * This returns the same singleton {@link DataFetcherFactory} that returns the value of {@link #singleton()} + * + * @return a singleton data fetcher factory + */ + public static DataFetcherFactory singletonFactory() { + return SINGLETON_FETCHER_FACTORY; + } + + private SingletonPropertyDataFetcher() { + } + + @Override + public T get(GraphQLFieldDefinition fieldDefinition, Object sourceObject, Supplier environmentSupplier) throws Exception { + return fetchImpl(fieldDefinition, sourceObject, environmentSupplier); + } + + @Override + public T get(DataFetchingEnvironment environment) throws Exception { + return fetchImpl(environment.getFieldDefinition(), environment.getSource(), () -> environment); + } + + private T fetchImpl(GraphQLFieldDefinition fieldDefinition, Object source, Supplier environmentSupplier) { + if (source == null) { + return null; + } + // this is the same code that PropertyDataFetcher uses and hence unit tests for it include this one + //noinspection unchecked + return (T) PropertyDataFetcherHelper.getPropertyValue(fieldDefinition.getName(), source, fieldDefinition.getType(), environmentSupplier); + } +} diff --git a/src/main/java/graphql/schema/StaticDataFetcher.java b/src/main/java/graphql/schema/StaticDataFetcher.java index f7c7fa2948..b9b49d9d6d 100644 --- a/src/main/java/graphql/schema/StaticDataFetcher.java +++ b/src/main/java/graphql/schema/StaticDataFetcher.java @@ -2,12 +2,13 @@ import graphql.PublicApi; +import graphql.TrivialDataFetcher; /** * A {@link graphql.schema.DataFetcher} that always returns the same value */ @PublicApi -public class StaticDataFetcher implements DataFetcher { +public class StaticDataFetcher implements DataFetcher, TrivialDataFetcher { private final Object value; @@ -20,4 +21,5 @@ public StaticDataFetcher(Object value) { public Object get(DataFetchingEnvironment environment) { return value; } + } diff --git a/src/main/java/graphql/schema/diff/DiffCategory.java b/src/main/java/graphql/schema/diff/DiffCategory.java index a373d0f590..68592568cd 100644 --- a/src/main/java/graphql/schema/diff/DiffCategory.java +++ b/src/main/java/graphql/schema/diff/DiffCategory.java @@ -26,5 +26,13 @@ public enum DiffCategory { /** * The new API has changed something compared to the old API */ - DIFFERENT + DIFFERENT, + /** + * The new API has newly deprecated something + */ + DEPRECATION_ADDED, + /** + * The new API has removed something previously deprecated in the old API + */ + DEPRECATION_REMOVED, } diff --git a/src/main/java/graphql/schema/diff/DiffCtx.java b/src/main/java/graphql/schema/diff/DiffCtx.java index 048685d0c3..975189c174 100644 --- a/src/main/java/graphql/schema/diff/DiffCtx.java +++ b/src/main/java/graphql/schema/diff/DiffCtx.java @@ -11,7 +11,6 @@ import java.util.Deque; import java.util.List; import java.util.Optional; -import java.util.Stack; /* * A helper class that represents diff state (eg visited types) as well as helpers diff --git a/src/main/java/graphql/schema/diff/DiffEvent.java b/src/main/java/graphql/schema/diff/DiffEvent.java index e11088b4bf..1b58988eae 100644 --- a/src/main/java/graphql/schema/diff/DiffEvent.java +++ b/src/main/java/graphql/schema/diff/DiffEvent.java @@ -73,15 +73,6 @@ public String toString() { '}'; } - /** - * @return a Builder of Info level diff events - * @deprecated use {@link DiffEvent#apiInfo()} instead - */ - @Deprecated - public static Builder newInfo() { - return new Builder().level(DiffLevel.INFO); - } - public static Builder apiInfo() { return new Builder().level(DiffLevel.INFO); } diff --git a/src/main/java/graphql/schema/diff/DiffSet.java b/src/main/java/graphql/schema/diff/DiffSet.java index ee99273a2c..590d50bbb4 100644 --- a/src/main/java/graphql/schema/diff/DiffSet.java +++ b/src/main/java/graphql/schema/diff/DiffSet.java @@ -15,6 +15,7 @@ * {@link graphql.introspection.IntrospectionQuery}. */ @PublicApi +@Deprecated(since = "2023-10-04") public class DiffSet { private final Map introspectionOld; @@ -39,7 +40,6 @@ public Map getNew() { return introspectionNew; } - /** * Creates a diff set out of the result of 2 introspection queries. * @@ -69,7 +69,7 @@ public static DiffSet diffSet(GraphQLSchema schemaOld, GraphQLSchema schemaNew) private static Map introspect(GraphQLSchema schema) { GraphQL gql = GraphQL.newGraphQL(schema).build(); ExecutionResult result = gql.execute(IntrospectionQuery.INTROSPECTION_QUERY); - Assert.assertTrue(result.getErrors().size() == 0, "The schema has errors during Introspection"); + Assert.assertTrue(result.getErrors().isEmpty(), "The schema has errors during Introspection"); return result.getData(); } } diff --git a/src/main/java/graphql/schema/diff/SchemaDiff.java b/src/main/java/graphql/schema/diff/SchemaDiff.java index 6d21888c7c..e87fb126ae 100644 --- a/src/main/java/graphql/schema/diff/SchemaDiff.java +++ b/src/main/java/graphql/schema/diff/SchemaDiff.java @@ -1,8 +1,11 @@ package graphql.schema.diff; +import graphql.Assert; +import graphql.PublicSpi; import graphql.introspection.IntrospectionResultToSchema; import graphql.language.Argument; import graphql.language.Directive; +import graphql.language.DirectivesContainer; import graphql.language.Document; import graphql.language.EnumTypeDefinition; import graphql.language.EnumValueDefinition; @@ -23,8 +26,7 @@ import graphql.schema.diff.reporting.DifferenceReporter; import graphql.schema.idl.TypeInfo; -import java.util.Arrays; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -36,6 +38,7 @@ import static graphql.language.TypeKind.getTypeKind; import static graphql.schema.idl.TypeInfo.getAstDesc; import static graphql.schema.idl.TypeInfo.typeInfo; +import static graphql.util.StringKit.capitalize; /** * The SchemaDiff is called with a {@link DiffSet} and will report the @@ -43,6 +46,7 @@ * {@link graphql.schema.diff.reporting.DifferenceReporter} */ @SuppressWarnings("ConstantConditions") +@PublicSpi public class SchemaDiff { /** @@ -68,7 +72,7 @@ public static Options defaultOptions() { private static class CountingReporter implements DifferenceReporter { final DifferenceReporter delegate; - int breakingCount = 1; + int breakingCount = 0; private CountingReporter(DifferenceReporter delegate) { this.delegate = delegate; @@ -117,27 +121,42 @@ public SchemaDiff(Options options) { * * @return the number of API breaking changes */ + @Deprecated(since = "2023-10-04") @SuppressWarnings("unchecked") public int diffSchema(DiffSet diffSet, DifferenceReporter reporter) { - CountingReporter countingReporter = new CountingReporter(reporter); - diffSchemaImpl(diffSet, countingReporter); + Document oldDoc = new IntrospectionResultToSchema().createSchemaDefinition(diffSet.getOld()); + Document newDoc = new IntrospectionResultToSchema().createSchemaDefinition(diffSet.getNew()); + diffSchemaImpl(oldDoc, newDoc, countingReporter); return countingReporter.breakingCount; } - private void diffSchemaImpl(DiffSet diffSet, DifferenceReporter reporter) { - Map oldApi = diffSet.getOld(); - Map newApi = diffSet.getNew(); + /** + * This will perform a difference on the two schemas. The reporter callback + * interface will be called when differences are encountered. + * + * @param schemaDiffSet the two schemas to compare for difference + * @param reporter the place to report difference events to + * + * @return the number of API breaking changes + */ + @SuppressWarnings("unchecked") + public int diffSchema(SchemaDiffSet schemaDiffSet, DifferenceReporter reporter) { + if (options.enforceDirectives) { + Assert.assertTrue(schemaDiffSet.supportsEnforcingDirectives(), () -> + "The provided schema diff set implementation does not supporting enforcing directives during schema diff."); + } - Document oldDoc = new IntrospectionResultToSchema().createSchemaDefinition(oldApi); - Document newDoc = new IntrospectionResultToSchema().createSchemaDefinition(newApi); + CountingReporter countingReporter = new CountingReporter(reporter); + diffSchemaImpl(schemaDiffSet.getOldSchemaDefinitionDoc(), schemaDiffSet.getNewSchemaDefinitionDoc(), countingReporter); + return countingReporter.breakingCount; + } + private void diffSchemaImpl(Document oldDoc, Document newDoc, DifferenceReporter reporter) { DiffCtx ctx = new DiffCtx(reporter, oldDoc, newDoc); - Optional oldSchemaDef = getSchemaDef(oldDoc); Optional newSchemaDef = getSchemaDef(newDoc); - // check query operation checkOperation(ctx, "query", oldSchemaDef, newSchemaDef); checkOperation(ctx, "mutation", oldSchemaDef, newSchemaDef); @@ -184,14 +203,14 @@ private void checkOperation(DiffCtx ctx, String opName, Optional oldTD = ctx.getOldTypeDef(oldType, TypeDefinition.class); if (!oldTD.isPresent()) { return; } - checkType(ctx, oldType, newOpTypeDefinition.getType()); + checkType(ctx, oldType, newOpTypeDefinition.getTypeName()); } private void checkType(DiffCtx ctx, Type oldType, Type newType) { @@ -269,11 +288,15 @@ private void checkType(DiffCtx ctx, Type oldType, Type newType) { ctx.exitType(); } + private boolean isDeprecated(DirectivesContainer node) { + return node.hasDirective("deprecated"); + } + private boolean isReservedType(String typeName) { return typeName.startsWith("__"); } - private final static Set SYSTEM_SCALARS = new HashSet<>(); + private final static Set SYSTEM_SCALARS = new LinkedHashSet<>(); static { SYSTEM_SCALARS.add("ID"); @@ -318,6 +341,7 @@ private void checkUnionType(DiffCtx ctx, UnionTypeDefinition oldDef, UnionTypeDe Map oldMemberTypes = sortedMap(oldDef.getMemberTypes(), SchemaDiff::getTypeName); Map newMemberTypes = sortedMap(newDef.getMemberTypes(), SchemaDiff::getTypeName); + for (Map.Entry entry : oldMemberTypes.entrySet()) { String oldMemberTypeName = entry.getKey(); if (!newMemberTypes.containsKey(oldMemberTypeName)) { @@ -328,6 +352,9 @@ private void checkUnionType(DiffCtx ctx, UnionTypeDefinition oldDef, UnionTypeDe .components(oldMemberTypeName) .reasonMsg("The new API does not contain union member type '%s'", oldMemberTypeName) .build()); + } else { + // check type which is in the old and the new Union def + checkType(ctx, entry.getValue(), newMemberTypes.get(oldMemberTypeName)); } } for (Map.Entry entry : newMemberTypes.entrySet()) { @@ -370,15 +397,24 @@ private void checkInputFields(DiffCtx ctx, TypeDefinition old, List newEnum = Optional.ofNullable(newDefinitionMap.get(enumName)); if (!newEnum.isPresent()) { + DiffCategory category; + String message; + if (isDeprecated(oldEnum)) { + category = DiffCategory.DEPRECATION_REMOVED; + message = "The new API has removed a deprecated enum value '%s'"; + } else { + category = DiffCategory.MISSING; + message = "The new API is missing an enum value '%s'"; + } ctx.report(DiffEvent.apiBreakage() - .category(DiffCategory.MISSING) + .category(category) .typeName(oldDef.getName()) .typeKind(getTypeKind(oldDef)) .components(oldEnum.getName()) - .reasonMsg("The new API is missing an enum value '%s'", oldEnum.getName()) + .reasonMsg(message, oldEnum.getName()) .build()); } else { checkDirectives(ctx, oldDef, oldEnum.getDirectives(), newEnum.get().getDirectives()); @@ -444,6 +494,14 @@ private void checkEnumType(DiffCtx ctx, EnumTypeDefinition oldDef, EnumTypeDefin .components(enumName) .reasonMsg("The new API has added a new enum value '%s'", enumName) .build()); + } else if (isDeprecated(newDefinitionMap.get(enumName)) && !isDeprecated(oldEnum)) { + ctx.report(DiffEvent.apiDanger() + .category(DiffCategory.DEPRECATION_ADDED) + .typeName(oldDef.getName()) + .typeKind(getTypeKind(oldDef)) + .components(enumName) + .reasonMsg("The new API has deprecated an enum value '%s'", enumName) + .build()); } } checkDirectives(ctx, oldDef, newDef); @@ -458,18 +516,34 @@ private void checkImplements(DiffCtx ctx, ObjectTypeDefinition old, List o Map newImplementsMap = sortedMap(newImplements, t -> ((TypeName) t).getName()); for (Map.Entry entry : oldImplementsMap.entrySet()) { - InterfaceTypeDefinition oldInterface = ctx.getOldTypeDef(entry.getValue(), InterfaceTypeDefinition.class).get(); + Optional oldInterface = ctx.getOldTypeDef(entry.getValue(), InterfaceTypeDefinition.class); + if (!oldInterface.isPresent()) { + continue; + } Optional newInterface = ctx.getNewTypeDef(newImplementsMap.get(entry.getKey()), InterfaceTypeDefinition.class); if (!newInterface.isPresent()) { ctx.report(DiffEvent.apiBreakage() .category(DiffCategory.MISSING) .typeName(old.getName()) .typeKind(getTypeKind(old)) - .components(oldInterface.getName()) - .reasonMsg("The new API is missing the interface named '%s'", oldInterface.getName()) + .components(oldInterface.get().getName()) + .reasonMsg("The new API is missing the interface named '%s'", oldInterface.get().getName()) .build()); } else { - checkInterfaceType(ctx, oldInterface, newInterface.get()); + checkInterfaceType(ctx, oldInterface.get(), newInterface.get()); + } + } + + for (Map.Entry entry : newImplementsMap.entrySet()) { + Optional newInterface = ctx.getNewTypeDef(entry.getValue(), InterfaceTypeDefinition.class); + if (!oldImplementsMap.containsKey(entry.getKey())) { + ctx.report(DiffEvent.apiInfo() + .category(DiffCategory.ADDITION) + .typeName(old.getName()) + .typeKind(getTypeKind(old)) + .components(newInterface.get().getName()) + .reasonMsg("The new API has added the interface named '%s'", newInterface.get().getName()) + .build()); } } } @@ -504,12 +578,21 @@ private void checkFieldRemovals( FieldDefinition newField = newFields.get(fieldName); if (newField == null) { + DiffCategory category; + String message; + if (isDeprecated(entry.getValue())) { + category = DiffCategory.DEPRECATION_REMOVED; + message = "The new API has removed a deprecated field '%s'"; + } else { + category = DiffCategory.MISSING; + message = "The new API is missing the field '%s'"; + } ctx.report(DiffEvent.apiBreakage() - .category(DiffCategory.MISSING) + .category(category) .typeName(oldDef.getName()) .typeKind(getTypeKind(oldDef)) .fieldName(fieldName) - .reasonMsg("The new API is missing the field '%s'", mkDotName(oldDef.getName(), fieldName)) + .reasonMsg(message, mkDotName(oldDef.getName(), fieldName)) .build()); } else { checkField(ctx, oldDef, entry.getValue(), newField); @@ -542,6 +625,14 @@ private void checkFieldAdditions( .fieldName(fieldName) .reasonMsg("The new API adds the field '%s'", mkDotName(newDef.getName(), fieldName)) .build()); + } else if (!isDeprecated(oldField) && isDeprecated(entry.getValue())) { + ctx.report(DiffEvent.apiDanger() + .category(DiffCategory.DEPRECATION_ADDED) + .typeName(newDef.getName()) + .typeKind(getTypeKind(newDef)) + .fieldName(fieldName) + .reasonMsg("The new API deprecated a field '%s'", mkDotName(newDef.getName(), fieldName)) + .build()); } } } @@ -551,7 +642,7 @@ private void checkField(DiffCtx ctx, TypeDefinition old, FieldDefinition oldFiel Type oldFieldType = oldField.getType(); Type newFieldType = newField.getType(); - DiffCategory category = checkTypeWithNonNullAndList(oldFieldType, newFieldType); + DiffCategory category = checkTypeWithNonNullAndListOnObjectOrInterface(oldFieldType, newFieldType); if (category != null) { ctx.report(DiffEvent.apiBreakage() .category(category) @@ -640,7 +731,7 @@ private void checkFieldArg(DiffCtx ctx, TypeDefinition oldDef, FieldDefinition o Type oldArgType = oldArg.getType(); Type newArgType = newArg.getType(); - DiffCategory category = checkTypeWithNonNullAndList(oldArgType, newArgType); + DiffCategory category = checkTypeWithNonNullAndListOnInputOrArg(oldArgType, newArgType); if (category != null) { ctx.report(DiffEvent.apiBreakage() .category(category) @@ -770,7 +861,7 @@ void checkDirectives(DiffCtx ctx, TypeDefinition old, List oldDirecti } } - DiffCategory checkTypeWithNonNullAndList(Type oldType, Type newType) { + DiffCategory checkTypeWithNonNullAndListOnInputOrArg(Type oldType, Type newType) { TypeInfo oldTypeInfo = typeInfo(oldType); TypeInfo newTypeInfo = typeInfo(newType); @@ -779,31 +870,83 @@ DiffCategory checkTypeWithNonNullAndList(Type oldType, Type newType) { } while (true) { - // - // its allowed to get more less strict in the new but not more strict - if (oldTypeInfo.isNonNull() && newTypeInfo.isNonNull()) { - oldTypeInfo = oldTypeInfo.unwrapOne(); - newTypeInfo = newTypeInfo.unwrapOne(); - } else if (oldTypeInfo.isNonNull() && !newTypeInfo.isNonNull()) { - oldTypeInfo = oldTypeInfo.unwrapOne(); - } else if (!oldTypeInfo.isNonNull() && newTypeInfo.isNonNull()) { - return DiffCategory.STRICTER; - } - // lists - if (oldTypeInfo.isList() && !newTypeInfo.isList()) { - return DiffCategory.INVALID; + if (oldTypeInfo.isNonNull()) { + if (newTypeInfo.isNonNull()) { + // if they're both non-null, compare the unwrapped types + oldTypeInfo = oldTypeInfo.unwrapOne(); + newTypeInfo = newTypeInfo.unwrapOne(); + } else { + // non-null to nullable is valid, as long as the underlying types are also valid + oldTypeInfo = oldTypeInfo.unwrapOne(); + } + } else if (oldTypeInfo.isList()) { + if (newTypeInfo.isList()) { + // if they're both lists, compare the unwrapped types + oldTypeInfo = oldTypeInfo.unwrapOne(); + newTypeInfo = newTypeInfo.unwrapOne(); + } else if (newTypeInfo.isNonNull()) { + // nullable to non-null creates a stricter input requirement for clients to specify + return DiffCategory.STRICTER; + } else { + // list to non-list is not valid + return DiffCategory.INVALID; + } + } else { + if (newTypeInfo.isNonNull()) { + // nullable to non-null creates a stricter input requirement for clients to specify + return DiffCategory.STRICTER; + } else if (newTypeInfo.isList()) { + // non-list to list is not valid + return DiffCategory.INVALID; + } else { + return null; + } } - // plain - if (oldTypeInfo.isPlain()) { - if (!newTypeInfo.isPlain()) { + } + } + + DiffCategory checkTypeWithNonNullAndListOnObjectOrInterface(Type oldType, Type newType) { + TypeInfo oldTypeInfo = typeInfo(oldType); + TypeInfo newTypeInfo = typeInfo(newType); + + if (!oldTypeInfo.getName().equals(newTypeInfo.getName())) { + return DiffCategory.INVALID; + } + + while (true) { + if (oldTypeInfo.isNonNull()) { + if (newTypeInfo.isNonNull()) { + // if they're both non-null, compare the unwrapped types + oldTypeInfo = oldTypeInfo.unwrapOne(); + newTypeInfo = newTypeInfo.unwrapOne(); + } else { + // non-null to nullable requires a stricter check from clients since it removes the guarantee of presence + return DiffCategory.STRICTER; + } + } else if (oldTypeInfo.isList()) { + if (newTypeInfo.isList()) { + // if they're both lists, compare the unwrapped types + oldTypeInfo = oldTypeInfo.unwrapOne(); + newTypeInfo = newTypeInfo.unwrapOne(); + } else if (newTypeInfo.isNonNull()) { + // nullable to non-null is valid, as long as the underlying types are also valid + newTypeInfo = newTypeInfo.unwrapOne(); + } else { + // list to non-list is not valid + return DiffCategory.INVALID; + } + } else { + if (newTypeInfo.isNonNull()) { + // nullable to non-null is valid, as long as the underlying types are also valid + newTypeInfo = newTypeInfo.unwrapOne(); + } else if (newTypeInfo.isList()) { + // non-list to list is not valid return DiffCategory.INVALID; + } else { + return null; } - break; } - oldTypeInfo = oldTypeInfo.unwrapOne(); - newTypeInfo = newTypeInfo.unwrapOne(); } - return null; } @@ -832,10 +975,10 @@ private Optional getOpDef(String opName, SchemaDefiniti // looks for a type called `Query|Mutation|Subscription` and if it exist then assumes it as an operation def - private Optional synthOperationTypeDefinition(Function> typeReteriver, String opName) { + private Optional synthOperationTypeDefinition(Function> typeRetriever, String opName) { TypeName type = TypeName.newTypeName().name(capitalize(opName)).build(); - Optional typeDef = typeReteriver.apply(type); - return typeDef.map(objectTypeDefinition -> OperationTypeDefinition.newOperationTypeDefinition().name(opName).type(type).build()); + Optional typeDef = typeRetriever.apply(type); + return typeDef.map(objectTypeDefinition -> OperationTypeDefinition.newOperationTypeDefinition().name(opName).typeName(type).build()); } private Map sortedMap(List listOfNamedThings, Function nameFunc) { @@ -843,17 +986,8 @@ private Map sortedMap(List listOfNamedThings, Function(map); } - private static String capitalize(String name) { - if (name != null && name.length() != 0) { - char[] chars = name.toCharArray(); - chars[0] = Character.toUpperCase(chars[0]); - return new String(chars); - } else { - return name; - } - } private String mkDotName(String... objectNames) { - return Arrays.stream(objectNames).collect(Collectors.joining(".")); + return String.join(".", objectNames); } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/schema/diff/SchemaDiffSet.java b/src/main/java/graphql/schema/diff/SchemaDiffSet.java new file mode 100644 index 0000000000..dd28a65f4b --- /dev/null +++ b/src/main/java/graphql/schema/diff/SchemaDiffSet.java @@ -0,0 +1,134 @@ +package graphql.schema.diff; + +import graphql.Assert; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.PublicApi; +import graphql.introspection.IntrospectionQuery; +import graphql.introspection.IntrospectionResultToSchema; +import graphql.language.Document; +import graphql.parser.Parser; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.SchemaPrinter; + +import java.util.Map; + +/** + * Interface used to define 2 schemas that can be diffed by the {@link SchemaDiff} operation. + */ +@PublicApi +public class SchemaDiffSet { + + private final Document oldSchemaDoc; + private final Document newSchemaDoc; + private final boolean supportsEnforcingDirectives; + + private SchemaDiffSet(final Document oldSchemaDoc, + final Document newSchemaDoc, + final boolean supportsEnforcingDirectives) { + this.oldSchemaDoc = oldSchemaDoc; + this.newSchemaDoc = newSchemaDoc; + this.supportsEnforcingDirectives = supportsEnforcingDirectives; + } + + /** + * @return Returns a IDL document that represents the old schema as part of a SchemaDiff operation. + */ + public Document getOldSchemaDefinitionDoc() { + return this.oldSchemaDoc; + } + + /** + * @return Returns a IDL document that represents the new schema created from the introspection result. + */ + public Document getNewSchemaDefinitionDoc() { + return this.newSchemaDoc; + } + + /** + * @return Flag indicating whether this diffset implementation can be used to enforce directives when performing schema diff. + */ + public boolean supportsEnforcingDirectives() { + return this.supportsEnforcingDirectives; + } + + /** + * Creates an schema diff set out of the result of 2 introspection queries. + * + * @param introspectionOld the older introspection query + * @param introspectionNew the newer introspection query + * + * @return a diff set representing them which will not support enforcing directives. + */ + public static SchemaDiffSet diffSetFromIntrospection(final Map introspectionOld, + final Map introspectionNew) { + final Document oldDoc = getDocumentFromIntrospection(introspectionOld); + final Document newDoc = getDocumentFromIntrospection(introspectionNew); + return new SchemaDiffSet(oldDoc, newDoc, false); + } + + /** + * Creates an schema diff set out of the result of 2 introspection queries. + * + * @param oldSchema the older GraphQLSchema object to introspect. + * @param newSchema the new GraphQLSchema object to introspect. + * + * @return a diff set representing them which will not support enforcing directives. + */ + public static SchemaDiffSet diffSetFromIntrospection(final GraphQLSchema oldSchema, + final GraphQLSchema newSchema) { + final Map introspectionOld = introspect(oldSchema); + final Map introspectionNew = introspect(newSchema); + return diffSetFromIntrospection(introspectionOld, introspectionNew); + } + + /** + * Creates an schema diff set out of the two SDL definition Strings. + * + * @param oldSchemaSdl the older SDL definition String. + * @param newSchemaSdl the newer SDL definition String. + * + * @return a diff set representing them which will support enforcing directives. + */ + public static SchemaDiffSet diffSetFromSdl(final String oldSchemaSdl, + final String newSchemaSdl) { + final Document oldDoc = getDocumentFromSDLString(oldSchemaSdl); + final Document newDoc = getDocumentFromSDLString(newSchemaSdl); + return new SchemaDiffSet(oldDoc, newDoc, true); + } + + /** + * Creates an schema diff set out of the two SDL definition Strings. + * + * @param oldSchema the older SDL definition String. + * @param newSchema the newer SDL definition String. + * + * @return a diff set representing them which will support enforcing directives. + */ + public static SchemaDiffSet diffSetFromSdl(final GraphQLSchema oldSchema, + final GraphQLSchema newSchema) { + final String oldSchemaSdl = getSchemaSdl(oldSchema); + final String newSchemaSdl = getSchemaSdl(newSchema); + return diffSetFromSdl(oldSchemaSdl, newSchemaSdl); + } + + private static Document getDocumentFromIntrospection(final Map introspectionResult) { + return new IntrospectionResultToSchema().createSchemaDefinition(introspectionResult); + } + + private static Document getDocumentFromSDLString(final String sdlString) { + return Parser.parse(sdlString); + } + + private static String getSchemaSdl(GraphQLSchema schema) { + final SchemaPrinter schemaPrinter = new SchemaPrinter(); + return schemaPrinter.print(schema); + } + + private static Map introspect(GraphQLSchema schema) { + GraphQL gql = GraphQL.newGraphQL(schema).build(); + ExecutionResult result = gql.execute(IntrospectionQuery.INTROSPECTION_QUERY); + Assert.assertTrue(result.getErrors().isEmpty(), "The schema has errors during Introspection"); + return result.getData(); + } +} diff --git a/src/main/java/graphql/schema/diffing/DiffImpl.java b/src/main/java/graphql/schema/diffing/DiffImpl.java new file mode 100644 index 0000000000..f24eb934a6 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/DiffImpl.java @@ -0,0 +1,559 @@ +package graphql.schema.diffing; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import com.google.common.collect.Multisets; +import graphql.Internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.PriorityQueue; +import java.util.Set; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicInteger; + +import static graphql.Assert.assertFalse; +import static graphql.Assert.assertTrue; +import static graphql.schema.diffing.EditorialCostForMapping.baseEditorialCostForMapping; +import static graphql.schema.diffing.EditorialCostForMapping.editorialCostForMapping; + +/** + * This is an algorithm calculating the optimal edit to change the source graph into the target graph. + *

+ * It is based on the following two papers (both papers are from the same authors. The first one is newer, but the older one is more detailed in some aspects) + *

+ * Accelerating Graph Similarity Search via Efficient GED Computation (https://lijunchang.github.io/pdf/2022-ged-tkde.pdf) + *

+ * Efficient Graph Edit Distance Computation and Verification via Anchor-aware Lower Bound Estimation (https://arxiv.org/abs/1709.06810) + *

+ * The algorithm is a modified version of "AStar-BMao". + * It is adapted to directed graphs as a GraphQL schema is most naturally represented as directed graph (vs the undirected graphs used in the papers). + */ +@Internal +public class DiffImpl { + + private final PossibleMappingsCalculator possibleMappingsCalculator; + private final SchemaGraph completeSourceGraph; + private final SchemaGraph completeTargetGraph; + private final PossibleMappingsCalculator.PossibleMappings possibleMappings; + private final SchemaDiffingRunningCheck runningCheck; + + private static class MappingEntry { + public LinkedBlockingQueue mappingEntriesSiblings = new LinkedBlockingQueue<>(); + public int[] assignments; + + /** + * These are the available vertices, relative to the parent mapping. + * Meaning the last mapped element is NOT contained in it. + */ + public List availableTargetVertices; + + Mapping partialMapping; + int level; // = partialMapping.size + double lowerBoundCost; + + + public MappingEntry(Mapping partialMapping, int level, double lowerBoundCost) { + this.partialMapping = partialMapping; + this.level = level; + this.lowerBoundCost = lowerBoundCost; + } + + } + + /** + * An optimal edit from one graph to another. + * The mapping maps all vertices from source to target, but + * not all mappings represent an actual change. This is why there is a separate list + * of the actual changes. + */ + public static class OptimalEdit { + private final SchemaGraph completeSourceGraph; + private final SchemaGraph completeTargetGraph; + + public Mapping mapping; + public int ged = Integer.MAX_VALUE; + + public OptimalEdit( + SchemaGraph completeSourceGraph, + SchemaGraph completeTargetGraph) { + this.completeSourceGraph = completeSourceGraph; + this.completeTargetGraph = completeTargetGraph; + } + + public OptimalEdit( + SchemaGraph completeSourceGraph, + SchemaGraph completeTargetGraph, + Mapping mapping, + int ged) { + this.completeSourceGraph = completeSourceGraph; + this.completeTargetGraph = completeTargetGraph; + this.mapping = mapping; + this.ged = ged; + } + + public List getListOfEditOperations() { + ArrayList listOfEditOperations = new ArrayList<>(); + assertTrue(baseEditorialCostForMapping(mapping, completeSourceGraph, completeTargetGraph, listOfEditOperations) == ged); + return listOfEditOperations; + } + } + + public DiffImpl(PossibleMappingsCalculator possibleMappingsCalculator, SchemaGraph completeSourceGraph, SchemaGraph completeTargetGraph, PossibleMappingsCalculator.PossibleMappings possibleMappings, SchemaDiffingRunningCheck runningCheck) { + this.possibleMappingsCalculator = possibleMappingsCalculator; + this.completeSourceGraph = completeSourceGraph; + this.completeTargetGraph = completeTargetGraph; + this.possibleMappings = possibleMappings; + this.runningCheck = runningCheck; + } + + OptimalEdit diffImpl(Mapping startMapping, List allSources, List allTargets, AtomicInteger algoIterationCount) throws Exception { + int graphSize = allSources.size(); + + int fixedEditorialCost = baseEditorialCostForMapping(startMapping, completeSourceGraph, completeTargetGraph); + int level = startMapping.size(); + + List allNonFixedTargets = new ArrayList<>(allTargets); + startMapping.forEachTarget(allNonFixedTargets::remove); + + MappingEntry firstMappingEntry = new MappingEntry(startMapping, level, fixedEditorialCost); + firstMappingEntry.availableTargetVertices = allNonFixedTargets; + + OptimalEdit optimalEdit = new OptimalEdit(completeSourceGraph, completeTargetGraph); + PriorityQueue queue = new PriorityQueue<>((mappingEntry1, mappingEntry2) -> { + int compareResult = Double.compare(mappingEntry1.lowerBoundCost, mappingEntry2.lowerBoundCost); + // we prefer higher levels for equal lower bound costs + if (compareResult == 0) { + return Integer.compare(mappingEntry2.level, mappingEntry1.level); + } else { + return compareResult; + } + }); + queue.add(firstMappingEntry); + + + while (!queue.isEmpty()) { + MappingEntry mappingEntry = queue.poll(); + algoIterationCount.incrementAndGet(); + + if (mappingEntry.lowerBoundCost >= optimalEdit.ged) { + // once the lowest lowerBoundCost is not lower than the optimal edit, we are done + break; + } + + if (mappingEntry.level > 0 && !mappingEntry.mappingEntriesSiblings.isEmpty()) { + addSiblingToQueue( + fixedEditorialCost, + mappingEntry.level, + queue, + optimalEdit, + allSources, + allTargets, + mappingEntry); + } + if (mappingEntry.level < graphSize) { + addChildToQueue( + fixedEditorialCost, + mappingEntry, + queue, + optimalEdit, + allSources, + allTargets + ); + } + + runningCheck.check(); + } + + return optimalEdit; + } + + + // this calculates all children for the provided parentEntry, but only the first is directly added to the queue + private void addChildToQueue(int fixedEditorialCost, + MappingEntry parentEntry, + PriorityQueue queue, + OptimalEdit optimalEdit, + List allSources, + List allTargets + ) { + Mapping parentPartialMapping = parentEntry.partialMapping; + int parentLevel = parentEntry.level; + int level = parentLevel + 1; + + assertTrue(parentLevel == parentPartialMapping.size()); + + // the available target vertices are the parent queue entry ones plus + // minus the additional mapped element in parentPartialMapping + ArrayList availableTargetVertices = new ArrayList<>(parentEntry.availableTargetVertices); + availableTargetVertices.remove(parentPartialMapping.getTarget(parentLevel - 1)); + assertTrue(availableTargetVertices.size() + parentPartialMapping.size() == allTargets.size()); + Vertex v_i = allSources.get(parentLevel); + + + // the cost matrix is for the non mapped vertices + int costMatrixSize = allSources.size() - parentLevel; + + // costMatrix gets modified by the hungarian algorithm ... therefore we create two of them + double[][] costMatrixForHungarianAlgo = new double[costMatrixSize][costMatrixSize]; + double[][] costMatrix = new double[costMatrixSize][costMatrixSize]; + + Map isolatedVerticesCache = new LinkedHashMap<>(); + Map nonFixedParentRestrictions = possibleMappingsCalculator.getNonFixedParentRestrictions(completeSourceGraph, completeTargetGraph, parentPartialMapping); + + for (int i = parentLevel; i < allSources.size(); i++) { + Vertex v = allSources.get(i); + int j = 0; + for (Vertex u : availableTargetVertices) { + double cost = calcLowerBoundMappingCost(v, u, parentPartialMapping, isolatedVerticesCache, nonFixedParentRestrictions); + costMatrixForHungarianAlgo[i - parentLevel][j] = cost; + costMatrix[i - parentLevel][j] = cost; + j++; + } + runningCheck.check(); + } + + HungarianAlgorithm hungarianAlgorithm = new HungarianAlgorithm(costMatrixForHungarianAlgo); + int[] assignments = hungarianAlgorithm.execute(); + int editorialCostForMapping = editorialCostForMapping(fixedEditorialCost, parentPartialMapping, completeSourceGraph, completeTargetGraph); + double costMatrixSum = getCostMatrixSum(costMatrix, assignments); + double lowerBoundForPartialMapping = editorialCostForMapping + costMatrixSum; + + Mapping newMapping = parentPartialMapping.extendMapping(v_i, availableTargetVertices.get(assignments[0])); + + if (costMatrixSum >= Integer.MAX_VALUE && optimalEdit.mapping == null) { + throw new RuntimeException("bug: could not find any allowed mapping"); + } + + if (lowerBoundForPartialMapping >= optimalEdit.ged) { + return; + } + MappingEntry newMappingEntry = new MappingEntry(newMapping, level, lowerBoundForPartialMapping); + LinkedBlockingQueue siblings = new LinkedBlockingQueue<>(); + newMappingEntry.mappingEntriesSiblings = siblings; + newMappingEntry.assignments = assignments; + newMappingEntry.availableTargetVertices = availableTargetVertices; + + queue.add(newMappingEntry); + + expandMappingAndUpdateOptimalMapping(fixedEditorialCost, + level, + optimalEdit, + allSources, + parentPartialMapping.copy(), + assignments, + availableTargetVertices, + lowerBoundForPartialMapping); + + calculateRestOfChildren( + availableTargetVertices, + hungarianAlgorithm, + costMatrix, + editorialCostForMapping, + parentPartialMapping, + v_i, + optimalEdit.ged, + level, + siblings + ); + } + + private void updateOptimalEdit(OptimalEdit optimalEdit, int newGed, Mapping mapping) { + assertTrue(newGed < optimalEdit.ged); + optimalEdit.ged = newGed; + optimalEdit.mapping = mapping; + } + + // generate all children mappings and save in MappingEntry.sibling + private void calculateRestOfChildren(List availableTargetVertices, + HungarianAlgorithm hungarianAlgorithm, + double[][] costMatrixCopy, + double editorialCostForMapping, + Mapping partialMapping, + Vertex v_i, + int upperBound, + int level, + LinkedBlockingQueue siblings + ) { + // starting from 1 as we already generated the first one + for (int child = 1; child < availableTargetVertices.size(); child++) { + int[] assignments = hungarianAlgorithm.nextChild(); + if (hungarianAlgorithm.costMatrix[0][assignments[0]] == Integer.MAX_VALUE) { + break; + } + + double costMatrixSumSibling = getCostMatrixSum(costMatrixCopy, assignments); + double lowerBoundForPartialMappingSibling = editorialCostForMapping + costMatrixSumSibling; + Mapping newMappingSibling = partialMapping.extendMapping(v_i, availableTargetVertices.get(assignments[0])); + + + if (lowerBoundForPartialMappingSibling >= upperBound) { + break; + } + MappingEntry sibling = new MappingEntry(newMappingSibling, level, lowerBoundForPartialMappingSibling); + sibling.mappingEntriesSiblings = siblings; + sibling.assignments = assignments; + sibling.availableTargetVertices = availableTargetVertices; + + siblings.add(sibling); + + runningCheck.check(); + } + } + + // this retrieves the next sibling from MappingEntry.sibling and adds it to the queue if the lowerBound is less than the current upperBound + private void addSiblingToQueue( + int fixedEditorialCost, + int level, + PriorityQueue queue, + OptimalEdit optimalEdit, + List allSources, + List allTargets, + MappingEntry mappingEntry) throws InterruptedException { + + assertFalse(mappingEntry.mappingEntriesSiblings.isEmpty()); + + MappingEntry sibling = mappingEntry.mappingEntriesSiblings.take(); + if (sibling.lowerBoundCost < optimalEdit.ged) { + queue.add(sibling); + + // we need to start here from the parent mapping, this is why we remove the last element + Mapping toExpand = sibling.partialMapping.copyMappingWithLastElementRemoved(); + + expandMappingAndUpdateOptimalMapping(fixedEditorialCost, + level, + optimalEdit, + allSources, + toExpand, + sibling.assignments, + sibling.availableTargetVertices, + sibling.lowerBoundCost); + } + } + + /** + * Extend the partial mapping to a full mapping according to the optimal + * matching (hungarian algo result) and update the optimal edit if we + * found a better one. + */ + private void expandMappingAndUpdateOptimalMapping(int fixedEditorialCost, + int level, + OptimalEdit optimalEdit, + List allSources, + Mapping toExpand, + int[] assignments, + List availableTargetVertices, + double lowerBoundCost) { + for (int i = 0; i < assignments.length; i++) { + toExpand.add(allSources.get(level - 1 + i), availableTargetVertices.get(assignments[i])); + } + assertTrue(toExpand.size() == this.completeSourceGraph.size()); + int costForFullMapping = editorialCostForMapping(fixedEditorialCost, toExpand, completeSourceGraph, completeTargetGraph); + assertTrue(lowerBoundCost <= costForFullMapping); + if (costForFullMapping < optimalEdit.ged) { + updateOptimalEdit(optimalEdit, costForFullMapping, toExpand); + } + } + + + private double getCostMatrixSum(double[][] costMatrix, int[] assignments) { + double costMatrixSum = 0; + for (int i = 0; i < assignments.length; i++) { + costMatrixSum += costMatrix[i][assignments[i]]; + } + return costMatrixSum; + } + + /** + * a partial mapping introduces a sub graph. The editorial cost is only calculated with respect to this sub graph. + */ + + + /** + * lower bound mapping cost between for v -> u in respect to a partial mapping. + * It basically tells the minimal costs we can expect for all mappings that come from extending + * the partial mapping with v -> u. + *

+ * This is basically the formula (5) from page 6 of https://lijunchang.github.io/pdf/2022-ged-tkde.pdf. + *

+ * + * The main difference is that the formula works with undirected graphs, but we have a directed graph, + * hence there is no 1/2 factor and for comparing the labels of anchored vertices to v/u we need to + * take both directions into account. + *

+ * + * The other optimization is that a schema graph will have never a lot of adjacent edges compared to + * the overall vertices count, therefore the algorithm for the anchored vertices costs iterates + * over the adjacent edges of v/u instead of all the mapped vertices. + *

+ * + * Additionally, there is a shortcut for isolated vertices, representing deletion/insertion which is also cached. + *

+ * Some naming: an anchored vertex is a vertex that is mapped via the partial mapping. + * An inner edge is an edge between two vertices that are both not anchored (mapped). + * The vertices v and u are by definition not mapped. + */ + private double calcLowerBoundMappingCost(Vertex v, + Vertex u, + Mapping partialMapping, + Map isolatedVerticesCache, + Map nonFixedParentRestrictions) { + if (nonFixedParentRestrictions.containsKey(v) || partialMapping.hasParentRestriction(v)) { + if (!u.isIsolated()) { // Always allow mapping to isolated nodes + Vertex uParentRestriction = nonFixedParentRestrictions.get(v); + if (uParentRestriction == null) { + uParentRestriction = partialMapping.getParentRestriction(v); + } + + Collection parentEdges = completeTargetGraph.getAdjacentEdgesInverseNonCopy(u); + if (parentEdges.size() != 1) { + return Integer.MAX_VALUE; + } + + Vertex uParent = parentEdges.iterator().next().getFrom(); + if (uParent != uParentRestriction) { + return Integer.MAX_VALUE; + } + } + } + + if (!possibleMappings.mappingPossible(v, u)) { + return Integer.MAX_VALUE; + } + if (u.isOfType(SchemaGraph.ISOLATED)) { + if (isolatedVerticesCache.containsKey(v)) { + return isolatedVerticesCache.get(v); + } + double result = calcLowerBoundMappingCostForIsolated(v, partialMapping, true); + isolatedVerticesCache.put(v, result); + return result; + } + if (v.isOfType(SchemaGraph.ISOLATED)) { + if (isolatedVerticesCache.containsKey(u)) { + return isolatedVerticesCache.get(u); + } + double result = calcLowerBoundMappingCostForIsolated(u, partialMapping, false); + isolatedVerticesCache.put(u, result); + return result; + } + + boolean equalNodes = v.getType().equals(u.getType()) && v.getProperties().equals(u.getProperties()); + + int anchoredVerticesCost = 0; + Multiset multisetInnerEdgeLabelsV = HashMultiset.create(); + Multiset multisetInnerEdgeLabelsU = HashMultiset.create(); + + Collection adjacentEdgesV = completeSourceGraph.getAdjacentEdgesNonCopy(v); + Collection adjacentEdgesU = completeTargetGraph.getAdjacentEdgesNonCopy(u); + + Collection adjacentEdgesInverseV = completeSourceGraph.getAdjacentEdgesInverseNonCopy(v); + Collection adjacentEdgesInverseU = completeTargetGraph.getAdjacentEdgesInverseNonCopy(u); + + Set matchedTargetEdges = new LinkedHashSet<>(); + Set matchedTargetEdgesInverse = new LinkedHashSet<>(); + + for (Edge edgeV : adjacentEdgesV) { + + Vertex targetTo = partialMapping.getTarget(edgeV.getTo()); + if (targetTo == null) { + // meaning it is an inner edge(not part of the subgraph induced by the partial mapping) + multisetInnerEdgeLabelsV.add(edgeV.getLabel()); + continue; + } + /* question is if the edge from v is mapped onto an edge from u + (also edge are not mapped directly, but the vertices are) + and if the adjacent edge is mapped onto an adjacent edge, + we need to check the labels of the edges + */ + Edge matchedTargetEdge = completeTargetGraph.getEdge(u, targetTo); + if (matchedTargetEdge != null) { + matchedTargetEdges.add(matchedTargetEdge); + if (!Objects.equals(edgeV.getLabel(), matchedTargetEdge.getLabel())) { + anchoredVerticesCost++; + } + } else { +// // no matching adjacent edge from u found means there is no +// // edge from edgeV.getTo() to mapped(edgeV.getTo()) +// // and we need to increase the costs + anchoredVerticesCost++; + } + + } + + for (Edge edgeV : adjacentEdgesInverseV) { + + Vertex targetFrom = partialMapping.getTarget(edgeV.getFrom()); + // we are only interested in edges from anchored vertices + if (targetFrom == null) { + continue; + } + Edge matachedTargetEdge = completeTargetGraph.getEdge(targetFrom, u); + if (matachedTargetEdge != null) { + matchedTargetEdgesInverse.add(matachedTargetEdge); + if (!Objects.equals(edgeV.getLabel(), matachedTargetEdge.getLabel())) { + anchoredVerticesCost++; + } + } else { + anchoredVerticesCost++; + } + } + + for (Edge edgeU : adjacentEdgesU) { + // test if this is an inner edge (meaning it not part of the subgraph induced by the partial mapping) + // we know that u is not part of the mapped vertices, therefore we only need to test the "to" vertex + if (!partialMapping.containsTarget(edgeU.getTo())) { + multisetInnerEdgeLabelsU.add(edgeU.getLabel()); + continue; + } + if (matchedTargetEdges.contains(edgeU)) { + continue; + } + anchoredVerticesCost++; + + } + for (Edge edgeU : adjacentEdgesInverseU) { + // we are only interested in edges from anchored vertices + if (!partialMapping.containsTarget(edgeU.getFrom()) || matchedTargetEdgesInverse.contains(edgeU)) { + continue; + } + anchoredVerticesCost++; + } + + + Multiset intersectionInnerEdgeLabels = Multisets.intersection(multisetInnerEdgeLabelsV, multisetInnerEdgeLabelsU); + int multiSetEditDistanceForInnerEdges = Math.max(multisetInnerEdgeLabelsV.size(), multisetInnerEdgeLabelsU.size()) - intersectionInnerEdgeLabels.size(); + + int result = (equalNodes ? 0 : 1) + multiSetEditDistanceForInnerEdges + anchoredVerticesCost; + return result; + } + + + /** + * Simplified lower bound calc if the source/target vertex is isolated + */ + private double calcLowerBoundMappingCostForIsolated(Vertex vertex, + Mapping partialMapping, + boolean sourceOrTarget + ) { + SchemaGraph schemaGraph = sourceOrTarget ? completeSourceGraph : completeTargetGraph; + + // every adjacent edge is inserted/deleted for an isolated vertex + Collection adjacentEdges = schemaGraph.getAdjacentEdgesNonCopy(vertex); + + // for the inverse adjacent edges we only count the anchored ones + int anchoredInverseEdges = 0; + Collection adjacentEdgesInverse = schemaGraph.getAdjacentEdgesInverseNonCopy(vertex); + for (Edge edge : adjacentEdgesInverse) { + if (partialMapping.contains(edge.getFrom(), sourceOrTarget)) { + anchoredInverseEdges++; + } + } + return 1 + adjacentEdges.size() + anchoredInverseEdges; + } + +} diff --git a/src/main/java/graphql/schema/diffing/Edge.java b/src/main/java/graphql/schema/diffing/Edge.java new file mode 100644 index 0000000000..15a603ef62 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/Edge.java @@ -0,0 +1,62 @@ +package graphql.schema.diffing; + +import graphql.Internal; + +import java.util.Objects; + +@Internal +public class Edge { + private Vertex from; + private Vertex to; + + private String label = ""; + + public Edge(Vertex from, Vertex to) { + this.from = from; + this.to = to; + } + + public Edge(Vertex from, Vertex to, String label) { + this.from = from; + this.to = to; + this.label = label; + } + + public Vertex getFrom() { + return from; + } + + public void setFrom(Vertex from) { + this.from = from; + } + + public Vertex getTo() { + return to; + } + + public void setTo(Vertex to) { + this.to = to; + } + + + public void setLabel(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + @Override + public String toString() { + return "Edge{" + + "from=" + from + + ", to=" + to + + ", label='" + label + '\'' + + '}'; + } + + public boolean isEqualTo(Edge other) { + return Objects.equals(this.label, other.label); + } +} diff --git a/src/main/java/graphql/schema/diffing/EditOperation.java b/src/main/java/graphql/schema/diffing/EditOperation.java new file mode 100644 index 0000000000..ff24400367 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/EditOperation.java @@ -0,0 +1,115 @@ +package graphql.schema.diffing; + +import graphql.Internal; + +import java.util.Objects; + +/** + * An edit operation between two graphs can be one of six types: + * insert vertex, + * delete vertex, + * change vertex, + * insert edge, + * delete edge, + * change edge + */ +@Internal +public class EditOperation { + + private EditOperation(Operation operation, + String description, + Vertex sourceVertex, + Vertex targetVertex, + Edge sourceEdge, + Edge targetEdge) { + this.operation = operation; + this.description = description; + this.sourceVertex = sourceVertex; + this.targetVertex = targetVertex; + this.sourceEdge = sourceEdge; + this.targetEdge = targetEdge; + } + + public static EditOperation deleteVertex(String description, Vertex sourceVertex, Vertex targetVertex) { + return new EditOperation(Operation.DELETE_VERTEX, description, sourceVertex, targetVertex, null, null); + } + + public static EditOperation insertVertex(String description, Vertex sourceVertex, Vertex targetVertex) { + return new EditOperation(Operation.INSERT_VERTEX, description, sourceVertex, targetVertex, null, null); + } + + public static EditOperation changeVertex(String description, Vertex sourceVertex, Vertex targetVertex) { + return new EditOperation(Operation.CHANGE_VERTEX, description, sourceVertex, targetVertex, null, null); + } + + public static EditOperation deleteEdge(String description, Edge sourceEdge) { + return new EditOperation(Operation.DELETE_EDGE, description, null, null, sourceEdge, null); + } + + public static EditOperation insertEdge(String description, Edge targetEdge) { + return new EditOperation(Operation.INSERT_EDGE, description, null, null, null, targetEdge); + } + + public static EditOperation changeEdge(String description, Edge sourceEdge, Edge targetEdge) { + return new EditOperation(Operation.CHANGE_EDGE, description, null, null, sourceEdge, targetEdge); + } + + private Operation operation; + private String description; + private Vertex sourceVertex; + private Vertex targetVertex; + private Edge sourceEdge; + private Edge targetEdge; + + + public enum Operation { + CHANGE_VERTEX, DELETE_VERTEX, INSERT_VERTEX, CHANGE_EDGE, INSERT_EDGE, DELETE_EDGE + } + + public Operation getOperation() { + return operation; + } + + + public Vertex getSourceVertex() { + return sourceVertex; + } + + public Vertex getTargetVertex() { + return targetVertex; + } + + public Edge getSourceEdge() { + return sourceEdge; + } + + public Edge getTargetEdge() { + return targetEdge; + } + + @Override + public String toString() { + return "EditOperation{" + + "operation=" + operation + + ", description='" + description + '\'' + + '}'; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EditOperation that = (EditOperation) o; + return operation == that.operation && Objects.equals(description, that.description) && Objects.equals(sourceVertex, that.sourceVertex) && Objects.equals(targetVertex, that.targetVertex) && Objects.equals(sourceEdge, that.sourceEdge) && Objects.equals(targetEdge, that.targetEdge); + } + + @Override + public int hashCode() { + return Objects.hash(operation, description, sourceVertex, targetVertex, sourceEdge, targetEdge); + } +} diff --git a/src/main/java/graphql/schema/diffing/EditorialCostForMapping.java b/src/main/java/graphql/schema/diffing/EditorialCostForMapping.java new file mode 100644 index 0000000000..dbf38f2072 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/EditorialCostForMapping.java @@ -0,0 +1,187 @@ +package graphql.schema.diffing; + +import graphql.Internal; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; + +@Internal +public class EditorialCostForMapping { + /** + * @param mapping the mapping + * @param sourceGraph the source graph + * @param targetGraph the target graph + * + * @return the editorial cost + * + * @see #baseEditorialCostForMapping(Mapping, SchemaGraph, SchemaGraph, List) + */ + public static int baseEditorialCostForMapping(Mapping mapping, // can be a partial mapping + SchemaGraph sourceGraph, // the whole graph + SchemaGraph targetGraph // the whole graph + ) { + return baseEditorialCostForMapping(mapping, sourceGraph, targetGraph, new ArrayList<>()); + } + + /** + * Gets the "editorial cost for mapping" for the base mapping. + *

+ * Use this is as base cost when invoking + * {@link #editorialCostForMapping(int, Mapping, SchemaGraph, SchemaGraph)} + * as it heavily speeds up performance. + * + * @param mapping the mapping + * @param sourceGraph the source graph + * @param targetGraph the target graph + * @param editOperationsResult the list of edit operations + * + * @return the editorial cost + */ + public static int baseEditorialCostForMapping(Mapping mapping, // can be a partial mapping + SchemaGraph sourceGraph, // the whole graph + SchemaGraph targetGraph, // the whole graph + List editOperationsResult) { + int cost = 0; + + for (int i = 0; i < mapping.size(); i++) { + Vertex sourceVertex = mapping.getSource(i); + Vertex targetVertex = mapping.getTarget(i); + // Vertex changing (relabeling) + boolean equalNodes = sourceVertex.getType().equals(targetVertex.getType()) && sourceVertex.getProperties().equals(targetVertex.getProperties()); + if (!equalNodes) { + if (sourceVertex.isIsolated()) { + editOperationsResult.add(EditOperation.insertVertex("Insert" + targetVertex, sourceVertex, targetVertex)); + } else if (targetVertex.isIsolated()) { + editOperationsResult.add(EditOperation.deleteVertex("Delete " + sourceVertex, sourceVertex, targetVertex)); + } else { + editOperationsResult.add(EditOperation.changeVertex("Change " + sourceVertex + " to " + targetVertex, sourceVertex, targetVertex)); + } + cost++; + } + } + + // edge deletion or relabeling + for (Edge sourceEdge : sourceGraph.getEdges()) { + // only edges relevant to the subgraph + if (!mapping.containsSource(sourceEdge.getFrom()) || !mapping.containsSource(sourceEdge.getTo())) { + continue; + } + Vertex targetFrom = mapping.getTarget(sourceEdge.getFrom()); + Vertex targetTo = mapping.getTarget(sourceEdge.getTo()); + Edge targetEdge = targetGraph.getEdge(targetFrom, targetTo); + if (targetEdge == null) { + editOperationsResult.add(EditOperation.deleteEdge("Delete edge " + sourceEdge, sourceEdge)); + cost++; + } else if (!sourceEdge.getLabel().equals(targetEdge.getLabel())) { + editOperationsResult.add(EditOperation.changeEdge("Change " + sourceEdge + " to " + targetEdge, sourceEdge, targetEdge)); + cost++; + } + } + + for (Edge targetEdge : targetGraph.getEdges()) { + // only subgraph edges + if (!mapping.containsTarget(targetEdge.getFrom()) || !mapping.containsTarget(targetEdge.getTo())) { + continue; + } + Vertex sourceFrom = mapping.getSource(targetEdge.getFrom()); + Vertex sourceTo = mapping.getSource(targetEdge.getTo()); + if (sourceGraph.getEdge(sourceFrom, sourceTo) == null) { + editOperationsResult.add(EditOperation.insertEdge("Insert edge " + targetEdge, targetEdge)); + cost++; + } + } + + return cost; + } + + /** + * Calculates the "editorial cost for mapping" for the non-fixed targets in a {@link Mapping}. + *

+ * The {@code baseCost} argument should be the cost for the fixed mapping from + * {@link #baseEditorialCostForMapping(Mapping, SchemaGraph, SchemaGraph)}. + *

+ * The sum of the non-fixed costs and the fixed costs is total editorial cost for mapping. + * + * @param baseCost the starting base cost + * @param mapping the mapping + * @param sourceGraph the source graph + * @param targetGraph the target graph + * + * @return the editorial cost + */ + public static int editorialCostForMapping(int baseCost, + Mapping mapping, // can be a partial mapping + SchemaGraph sourceGraph, // the whole graph + SchemaGraph targetGraph // the whole graph + ) { + AtomicInteger cost = new AtomicInteger(baseCost); + + Set seenEdges = new LinkedHashSet<>(); + + // Tells us whether the edge should be visited. We need to avoid counting edges more than once + Predicate visitEdge = (data) -> { + if (seenEdges.contains(data)) { + return false; + } else { + seenEdges.add(data); + return true; + } + }; + + // Look through + mapping.forEachNonFixedSourceAndTarget((sourceVertex, targetVertex) -> { + // Vertex changing (relabeling) + boolean equalNodes = sourceVertex.getType().equals(targetVertex.getType()) && sourceVertex.getProperties().equals(targetVertex.getProperties()); + + if (!equalNodes) { + cost.getAndIncrement(); + } + + for (Edge sourceEdge : sourceGraph.getAdjacentEdgesAndInverseNonCopy(sourceVertex)) { + if (!visitEdge.test(sourceEdge)) { + continue; + } + + // only edges relevant to the subgraph + if (!mapping.containsSource(sourceEdge.getFrom()) || !mapping.containsSource(sourceEdge.getTo())) { + continue; + } + + Vertex targetFrom = mapping.getTarget(sourceEdge.getFrom()); + Vertex targetTo = mapping.getTarget(sourceEdge.getTo()); + Edge targetEdge = targetGraph.getEdge(targetFrom, targetTo); + + if (targetEdge == null) { + cost.getAndIncrement(); + } else if (!sourceEdge.getLabel().equals(targetEdge.getLabel())) { + cost.getAndIncrement(); + } + } + + for (Edge targetEdge : targetGraph.getAdjacentEdgesAndInverseNonCopy(targetVertex)) { + if (!visitEdge.test(targetEdge)) { + continue; + } + + // only edges relevant to the subgraph + if (!mapping.containsTarget(targetEdge.getFrom()) || !mapping.containsTarget(targetEdge.getTo())) { + continue; + } + + Vertex sourceFrom = mapping.getSource(targetEdge.getFrom()); + Vertex sourceTo = mapping.getSource(targetEdge.getTo()); + Edge sourceEdge = sourceGraph.getEdge(sourceFrom, sourceTo); + + if (sourceEdge == null) { + cost.getAndIncrement(); + } + } + }); + + return cost.get(); + } +} diff --git a/src/main/java/graphql/schema/diffing/HungarianAlgorithm.java b/src/main/java/graphql/schema/diffing/HungarianAlgorithm.java new file mode 100644 index 0000000000..b47d190f43 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/HungarianAlgorithm.java @@ -0,0 +1,378 @@ +package graphql.schema.diffing; + +import graphql.Internal; + +import java.util.Arrays; + +/* Copyright (c) 2012 Kevin L. Stern + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * An implementation of the Hungarian algorithm for solving the assignment + * problem. An instance of the assignment problem consists of a number of + * workers along with a number of jobs and a cost matrix which gives the cost of + * assigning the i'th worker to the j'th job at position (i, j). The goal is to + * find an assignment of workers to jobs so that no job is assigned more than + * one worker and so that no worker is assigned to more than one job in such a + * manner so as to minimize the total cost of completing the jobs. + *

+ * An assignment for a cost matrix that has more workers than jobs will + * necessarily include unassigned workers, indicated by an assignment value of + * -1; in no other circumstance will there be unassigned workers. Similarly, an + * assignment for a cost matrix that has more jobs than workers will necessarily + * include unassigned jobs; in no other circumstance will there be unassigned + * jobs. For completeness, an assignment for a square cost matrix will give + * exactly one unique worker to each job. + *

+ * This version of the Hungarian algorithm runs in time O(n^3), where n is the + * maximum among the number of workers and the number of jobs. + * + * @author Kevin L. Stern + */ +@Internal +public class HungarianAlgorithm { + // changed by reduce + public final double[][] costMatrix; + + // constant always + private final int rows; + private final int cols; + private final int dim; + + // the assigned workers,jobs for the result + public final int[] matchJobByWorker; + private final int[] matchWorkerByJob; + + // reset for each execute + private final int[] minSlackWorkerByJob; + private final double[] minSlackValueByJob; + private final int[] parentWorkerByCommittedJob; + // reset for worker + private final boolean[] committedWorkers; + + + // labels for both sides of the bipartite graph + private final double[] labelByWorker; + private final double[] labelByJob; + + + /** + * Construct an instance of the algorithm. + * + * @param costMatrix the cost matrix, where matrix[i][j] holds the cost of assigning + * worker i to job j, for all i, j. The cost matrix must not be + * irregular in the sense that all rows must be the same length; in + * addition, all entries must be non-infinite numbers. + */ + public HungarianAlgorithm(double[][] costMatrix) { + this.dim = Math.max(costMatrix.length, costMatrix[0].length); + this.rows = costMatrix.length; + this.cols = costMatrix[0].length; + this.costMatrix = costMatrix; +// for (int w = 0; w < this.dim; w++) { +// if (w < costMatrix.length) { +// if (costMatrix[w].length() != this.cols) { +// throw new IllegalArgumentException("Irregular cost matrix"); +// } +//// for (int j = 0; j < this.cols; j++) { +//// if (Double.isInfinite(costMatrix[w].get(j))) { +//// throw new IllegalArgumentException("Infinite cost"); +//// } +//// if (Double.isNaN(costMatrix[w].get(j))) { +//// throw new IllegalArgumentException("NaN cost"); +//// } +//// } +// this.costMatrix[w] = costMatrix(costMatrix[w], this.dim); +// } else { +// this.costMatrix[w] = new double[this.dim]; +// } +// } + labelByWorker = new double[this.dim]; + labelByJob = new double[this.dim]; + minSlackWorkerByJob = new int[this.dim]; + minSlackValueByJob = new double[this.dim]; + committedWorkers = new boolean[this.dim]; + parentWorkerByCommittedJob = new int[this.dim]; + matchJobByWorker = new int[this.dim]; + Arrays.fill(matchJobByWorker, -1); + matchWorkerByJob = new int[this.dim]; + Arrays.fill(matchWorkerByJob, -1); + } + + /** + * Compute an initial feasible solution by assigning zero labels to the + * workers and by assigning to each job a label equal to the minimum cost + * among its incident edges. + */ + protected void computeInitialFeasibleSolution() { + for (int j = 0; j < dim; j++) { + labelByJob[j] = Double.POSITIVE_INFINITY; + } + for (int w = 0; w < dim; w++) { + for (int j = 0; j < dim; j++) { + if (costMatrix[w][j] < labelByJob[j]) { + labelByJob[j] = costMatrix[w][j]; + } + } + } + } + + /** + * Execute the algorithm. + * + * @return the minimum cost matching of workers to jobs based upon the + * provided cost matrix. A matching value of -1 indicates that the + * corresponding worker is unassigned. + */ + public int[] execute() { + /* + * Heuristics to improve performance: Reduce rows and columns by their + * smallest element, compute an initial non-zero dual feasible solution and + * create a greedy matching from workers to jobs of the cost matrix. + */ + reduce(); + computeInitialFeasibleSolution(); + greedyMatch(); + + int w = fetchUnmatchedWorker(); + while (w < dim) { + initializePhase(w); + executePhase(); + w = fetchUnmatchedWorker(); + } + int[] result = Arrays.copyOf(matchJobByWorker, rows); + for (w = 0; w < result.length; w++) { + if (result[w] >= cols) { + result[w] = -1; + } + } + return result; + } + + /** + * Execute a single phase of the algorithm. A phase of the Hungarian algorithm + * consists of building a set of committed workers and a set of committed jobs + * from a root unmatched worker by following alternating unmatched/matched + * zero-slack edges. If an unmatched job is encountered, then an augmenting + * path has been found and the matching is grown. If the connected zero-slack + * edges have been exhausted, the labels of committed workers are increased by + * the minimum slack among committed workers and non-committed jobs to create + * more zero-slack edges (the labels of committed jobs are simultaneously + * decreased by the same amount in order to maintain a feasible labeling). + *

+ * The runtime of a single phase of the algorithm is O(n^2), where n is the + * dimension of the internal square cost matrix, since each edge is visited at + * most once and since increasing the labeling is accomplished in time O(n) by + * maintaining the minimum slack values among non-committed jobs. When a phase + * completes, the matching will have increased in size. + */ + protected void executePhase() { + while (true) { + // the last worker we found + int minSlackWorker = -1; + int minSlackJob = -1; + double minSlackValue = Double.POSITIVE_INFINITY; + for (int j = 0; j < dim; j++) { + if (parentWorkerByCommittedJob[j] == -1) { + if (minSlackValueByJob[j] < minSlackValue) { + minSlackValue = minSlackValueByJob[j]; + minSlackWorker = minSlackWorkerByJob[j]; + minSlackJob = j; + } + } + } + if (minSlackValue > 0) { + updateLabeling(minSlackValue); + } + // adding (minSlackWorker, minSlackJob) to the path + parentWorkerByCommittedJob[minSlackJob] = minSlackWorker; + // check if minSlackJob is not assigned yet + // the requirement of an augmenting path is that start and end is not matched (assigned) yet + if (matchWorkerByJob[minSlackJob] == -1) { + /* + * An augmenting path has been found. + * Iterating via parentWorkerByCommittedJob and matchJobByWorker through the + * path and add/update matching. + * Job -> Parent worker via parentWorkerByCommittedJob + * and Worker -> Job via matchJobByWorker + */ + int committedJob = minSlackJob; + int parentWorker = parentWorkerByCommittedJob[committedJob]; + while (true) { + int temp = matchJobByWorker[parentWorker]; + match(parentWorker, committedJob); + committedJob = temp; + if (committedJob == -1) { + break; + } + parentWorker = parentWorkerByCommittedJob[committedJob]; + } + return; + } else { + /* + * Update slack values since we increased the size of the committed + * workers set. + */ + // we checked above that minSlackJob is indeed assigned + int worker = matchWorkerByJob[minSlackJob]; + // committedWorkers is used when slack is updated + committedWorkers[worker] = true; + for (int j = 0; j < dim; j++) { + if (parentWorkerByCommittedJob[j] == -1) { + double slack = costMatrix[worker][j] - labelByWorker[worker] + - labelByJob[j]; + if (minSlackValueByJob[j] > slack) { + minSlackValueByJob[j] = slack; + minSlackWorkerByJob[j] = worker; + } + } + } + } + } + } + + /** + * @return the first unmatched worker or {@link #dim} if none. + */ + protected int fetchUnmatchedWorker() { + int w; + for (w = 0; w < dim; w++) { + if (matchJobByWorker[w] == -1) { + break; + } + } + return w; + } + + /** + * Find a valid matching by greedily selecting among zero-cost matchings. This + * is a heuristic to jump-start the augmentation algorithm. + */ + protected void greedyMatch() { + for (int w = 0; w < dim; w++) { + for (int j = 0; j < dim; j++) { + if (matchJobByWorker[w] == -1 && matchWorkerByJob[j] == -1 + && costMatrix[w][j] - labelByWorker[w] - labelByJob[j] == 0) { + match(w, j); + } + } + } + } + + /** + * Initialize the next phase of the algorithm by clearing the committed + * workers and jobs sets and by initializing the slack arrays to the values + * corresponding to the specified root worker. + * + * @param w the worker at which to root the next phase. + */ + protected void initializePhase(int w) { + Arrays.fill(committedWorkers, false); + Arrays.fill(parentWorkerByCommittedJob, -1); + committedWorkers[w] = true; + for (int j = 0; j < dim; j++) { + minSlackValueByJob[j] = costMatrix[w][j] - labelByWorker[w] - labelByJob[j]; + minSlackWorkerByJob[j] = w; + } + } + + /** + * Helper method to record a matching between worker w and job j. + * + * @param w the worker + * @param j the job + */ + protected void match(int w, int j) { + matchJobByWorker[w] = j; + matchWorkerByJob[j] = w; + } + + /** + * Reduce the cost matrix by subtracting the smallest element of each row from + * all elements of the row as well as the smallest element of each column from + * all elements of the column. Note that an optimal assignment for a reduced + * cost matrix is optimal for the original cost matrix. + */ + protected void reduce() { + for (int w = 0; w < dim; w++) { + double min = Double.POSITIVE_INFINITY; + for (int j = 0; j < dim; j++) { + if (costMatrix[w][j] < min) { + min = costMatrix[w][j]; + } + } + for (int j = 0; j < dim; j++) { + costMatrix[w][j] = costMatrix[w][j] - min; + } + } + double[] min = new double[dim]; + for (int j = 0; j < dim; j++) { + min[j] = Double.POSITIVE_INFINITY; + } + for (int w = 0; w < dim; w++) { + for (int j = 0; j < dim; j++) { + if (costMatrix[w][j] < min[j]) { + min[j] = costMatrix[w][j]; + } + } + } + for (int w = 0; w < dim; w++) { + for (int j = 0; j < dim; j++) { + costMatrix[w][j] = costMatrix[w][j] - min[j]; + } + } + } + + /** + * Update labels with the specified slack by adding the slack value for + * committed workers and by subtracting the slack value for committed jobs. In + * addition, update the minimum slack values appropriately. + * + * @param slack the specified slack + */ + protected void updateLabeling(double slack) { + for (int w = 0; w < dim; w++) { + if (committedWorkers[w]) { + labelByWorker[w] += slack; + } + } + for (int j = 0; j < dim; j++) { + if (parentWorkerByCommittedJob[j] != -1) { + labelByJob[j] -= slack; + } else { + minSlackValueByJob[j] -= slack; + } + } + } + + public int[] nextChild() { + int currentJobAssigned = matchJobByWorker[0]; + // we want to make currentJobAssigned not allowed,meaning we set the size to Infinity + costMatrix[0][currentJobAssigned] = Integer.MAX_VALUE; + matchWorkerByJob[currentJobAssigned] = -1; + matchJobByWorker[0] = -1; + minSlackValueByJob[currentJobAssigned] = Integer.MAX_VALUE; + initializePhase(0); + executePhase(); + int[] result = Arrays.copyOf(matchJobByWorker, rows); + return result; + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/diffing/Mapping.java b/src/main/java/graphql/schema/diffing/Mapping.java new file mode 100644 index 0000000000..68fbf22bd0 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/Mapping.java @@ -0,0 +1,194 @@ +package graphql.schema.diffing; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import graphql.Internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * A mapping (in the math sense) from a list of vertices to another list of + * vertices. + * A mapping can semantically mean a change, but doesn't have to: a vertex + * can be mapped to the same vertex (semantically the same, Java object wise they are different). + */ +@Internal +public class Mapping { + + + private final Map fixedParentRestrictions; + private final BiMap fixedMappings; + private final List fixedSourceList; + private final List fixedTargetList; + + private final BiMap map; + private final List sourceList; + private final List targetList; + + private Mapping(Map fixedParentRestrictions, + BiMap fixedMappings, + List fixedSourceList, + List fixedTargetList, + BiMap map, + List sourceList, + List targetList) { + this.fixedParentRestrictions = fixedParentRestrictions; + this.fixedMappings = fixedMappings; + this.fixedSourceList = fixedSourceList; + this.fixedTargetList = fixedTargetList; + this.map = map; + this.sourceList = sourceList; + this.targetList = targetList; + } + + public static Mapping newMapping(Map fixedParentRestrictions, + BiMap fixedMappings, + List fixedSourceList, + List fixedTargetList) { + return new Mapping( + fixedParentRestrictions, + fixedMappings, + fixedSourceList, + fixedTargetList, + HashBiMap.create(), + Collections.emptyList(), + Collections.emptyList()); + } + + public boolean hasParentRestriction(Vertex v) { + return fixedParentRestrictions.containsKey(v); + } + + public Vertex getParentRestriction(Vertex v) { + return fixedParentRestrictions.get(v); + } + + public Vertex getSource(Vertex target) { + if (fixedMappings.containsValue(target)) { + return fixedMappings.inverse().get(target); + } + return map.inverse().get(target); + } + + public Vertex getTarget(Vertex source) { + if (fixedMappings.containsKey(source)) { + return fixedMappings.get(source); + } + return map.get(source); + } + + public Vertex getSource(int i) { + if (i < fixedSourceList.size()) { + return fixedSourceList.get(i); + } + return sourceList.get(i - fixedSourceList.size()); + } + + public Vertex getTarget(int i) { + if (i < fixedTargetList.size()) { + return fixedTargetList.get(i); + } + return targetList.get(i - fixedTargetList.size()); + } + + public boolean containsSource(Vertex sourceVertex) { + if (fixedMappings.containsKey(sourceVertex)) { + return true; + } + return map.containsKey(sourceVertex); + } + + public boolean containsTarget(Vertex targetVertex) { + if (fixedMappings.containsValue(targetVertex)) { + return true; + } + return map.containsValue(targetVertex); + } + + + public boolean contains(Vertex vertex, boolean sourceOrTarget) { + return sourceOrTarget ? containsSource(vertex) : containsTarget(vertex); + } + + + public int size() { + return fixedMappings.size() + map.size(); + } + + public int fixedSize() { + return fixedMappings.size(); + } + + public int nonFixedSize() { + return map.size(); + } + + public void add(Vertex source, Vertex target) { + this.map.put(source, target); + this.sourceList.add(source); + this.targetList.add(target); + } + + public Mapping copyMappingWithLastElementRemoved() { + HashBiMap newMap = HashBiMap.create(map); + newMap.remove(this.sourceList.get(this.sourceList.size() - 1)); + List newSourceList = new ArrayList<>(this.sourceList.subList(0, this.sourceList.size() - 1)); + List newTargetList = new ArrayList<>(this.targetList.subList(0, this.targetList.size() - 1)); + return new Mapping(fixedParentRestrictions, fixedMappings, fixedSourceList, fixedTargetList, newMap, newSourceList, newTargetList); + } + + public Mapping copy() { + HashBiMap newMap = HashBiMap.create(map); + List newSourceList = new ArrayList<>(this.sourceList); + List newTargetList = new ArrayList<>(this.targetList); + return new Mapping(fixedParentRestrictions, fixedMappings, fixedSourceList, fixedTargetList, newMap, newSourceList, newTargetList); + } + + public Mapping extendMapping(Vertex source, Vertex target) { + HashBiMap newMap = HashBiMap.create(map); + newMap.put(source, target); + List newSourceList = new ArrayList<>(this.sourceList); + newSourceList.add(source); + List newTargetList = new ArrayList<>(this.targetList); + newTargetList.add(target); + return new Mapping(fixedParentRestrictions, fixedMappings, fixedSourceList, fixedTargetList, newMap, newSourceList, newTargetList); + } + + public void forEachTarget(Consumer action) { + for (Vertex t : fixedTargetList) { + action.accept(t); + } + for (Vertex t : targetList) { + action.accept(t); + } + } + + public void forEachNonFixedTarget(Consumer action) { + for (Vertex t : targetList) { + action.accept(t); + } + } + + public void forEachNonFixedSourceAndTarget(BiConsumer consumer) { + map.forEach(consumer); + } + + public Mapping invert() { + BiMap invertedFixedMappings = HashBiMap.create(); + for (Vertex s : fixedMappings.keySet()) { + Vertex t = fixedMappings.get(s); + invertedFixedMappings.put(t, s); + } + BiMap invertedMap = HashBiMap.create(); + for (Vertex s : map.keySet()) { + Vertex t = map.get(s); + invertedMap.put(t, s); + } + return new Mapping(fixedParentRestrictions, invertedFixedMappings, fixedTargetList, fixedSourceList, invertedMap, targetList, sourceList); + } +} diff --git a/src/main/java/graphql/schema/diffing/PossibleMappingsCalculator.java b/src/main/java/graphql/schema/diffing/PossibleMappingsCalculator.java new file mode 100644 index 0000000000..ac13a82dc8 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/PossibleMappingsCalculator.java @@ -0,0 +1,1142 @@ +package graphql.schema.diffing; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Multimap; +import com.google.common.collect.Table; +import graphql.Assert; +import graphql.Internal; +import graphql.util.FpKit; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static graphql.schema.diffing.SchemaGraph.APPLIED_ARGUMENT; +import static graphql.schema.diffing.SchemaGraph.APPLIED_DIRECTIVE; +import static graphql.schema.diffing.SchemaGraph.ARGUMENT; +import static graphql.schema.diffing.SchemaGraph.DIRECTIVE; +import static graphql.schema.diffing.SchemaGraph.ENUM; +import static graphql.schema.diffing.SchemaGraph.ENUM_VALUE; +import static graphql.schema.diffing.SchemaGraph.FIELD; +import static graphql.schema.diffing.SchemaGraph.INPUT_FIELD; +import static graphql.schema.diffing.SchemaGraph.INPUT_OBJECT; +import static graphql.schema.diffing.SchemaGraph.INTERFACE; +import static graphql.schema.diffing.SchemaGraph.OBJECT; +import static graphql.schema.diffing.SchemaGraph.SCALAR; +import static graphql.schema.diffing.SchemaGraph.SCHEMA; +import static graphql.schema.diffing.SchemaGraph.UNION; +import static graphql.util.FpKit.concat; +import static java.util.Collections.singletonList; + +/** + * We don't want to allow arbitrary schema changes. For example changing an Object type into a Scalar + * is not something we want to consider. + *

+ * We do this to make SchemaDiffings better understandable, but also to improve the overall runtime of + * the algorithm. By restricting the possible mappings the Schema diffing algo is actually able to + * finish in a reasonable time for real life inputs. + *

+ * + * We restrict the algo by calculating which mappings are possible for given vertex. This is later used in + * {@link DiffImpl#calcLowerBoundMappingCost}. + * While doing this we need to also ensure that there are the same amount of vertices in the same "context": + * for example if the source graph has 3 Objects, the target graph needs to have 3 Objects. We achieve this by + * adding "isolated vertices" as needed. + */ +@Internal +public class PossibleMappingsCalculator { + private final SchemaDiffingRunningCheck runningCheck; + + private final SchemaGraph sourceGraph; + private final SchemaGraph targetGraph; + private final PossibleMappings possibleMappings; + + private static final Map> typeContexts = new LinkedHashMap<>(); + + static { + typeContexts.put(SCHEMA, schemaContext()); + typeContexts.put(FIELD, fieldContext()); + typeContexts.put(ARGUMENT, argumentsContexts()); + typeContexts.put(INPUT_FIELD, inputFieldContexts()); + typeContexts.put(OBJECT, objectContext()); + typeContexts.put(INTERFACE, interfaceContext()); + typeContexts.put(UNION, unionContext()); + typeContexts.put(INPUT_OBJECT, inputObjectContext()); + typeContexts.put(SCALAR, scalarContext()); + typeContexts.put(ENUM, enumContext()); + typeContexts.put(ENUM_VALUE, enumValueContext()); + typeContexts.put(APPLIED_DIRECTIVE, appliedDirectiveContext()); + typeContexts.put(APPLIED_ARGUMENT, appliedArgumentContext()); + typeContexts.put(DIRECTIVE, directiveContext()); + } + + private static List inputFieldContexts() { + VertexContextSegment inputFieldType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return INPUT_FIELD.equals(vertex.getType()); + } + }; + VertexContextSegment inputObjectContext = new VertexContextSegment() { + @Override + public String idForVertex(Vertex inputField, SchemaGraph schemaGraph) { + Vertex inputObject = schemaGraph.getInputObjectForInputField(inputField); + return inputObject.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment inputFieldName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex inputField, SchemaGraph schemaGraph) { + return inputField.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(inputFieldType, inputObjectContext, inputFieldName); + return contexts; + } + + + private static List scalarContext() { + VertexContextSegment scalar = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return SCALAR.equals(vertex.getType()); + } + }; + VertexContextSegment scalarName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(scalar, scalarName); + return contexts; + } + + private static List inputObjectContext() { + VertexContextSegment inputObject = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return INPUT_OBJECT.equals(vertex.getType()); + } + }; + VertexContextSegment inputObjectName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex inputObject, SchemaGraph schemaGraph) { + return inputObject.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(inputObject, inputObjectName); + return contexts; + } + + private static List objectContext() { + VertexContextSegment objectType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return OBJECT.equals(vertex.getType()); + } + }; + + VertexContextSegment objectName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex object, SchemaGraph schemaGraph) { + return object.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(objectType, objectName); + return contexts; + } + + private static List enumContext() { + VertexContextSegment enumCtxType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return ENUM.equals(vertex.getType()); + } + }; + VertexContextSegment enumName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex enumVertex, SchemaGraph schemaGraph) { + return enumVertex.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(enumCtxType, enumName); + return contexts; + } + + private static List enumValueContext() { + VertexContextSegment enumValueType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return ENUM_VALUE.equals(vertex.getType()); + } + }; + VertexContextSegment enumName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex enumValue, SchemaGraph schemaGraph) { + return schemaGraph.getEnumForEnumValue(enumValue).getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment enumValueName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex enumValue, SchemaGraph schemaGraph) { + return enumValue.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(enumValueType, enumName, enumValueName); + return contexts; + } + + private static List interfaceContext() { + VertexContextSegment interfaceType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return INTERFACE.equals(vertex.getType()); + } + }; + VertexContextSegment interfaceName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex interfaceVertex, SchemaGraph schemaGraph) { + return interfaceVertex.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + List contexts = Arrays.asList(interfaceType, interfaceName); + return contexts; + } + + private static List unionContext() { + VertexContextSegment unionType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return UNION.equals(vertex.getType()); + } + }; + VertexContextSegment unionName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex union, SchemaGraph schemaGraph) { + return union.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + List contexts = Arrays.asList(unionType, unionName); + return contexts; + } + + private static List directiveContext() { + VertexContextSegment directiveType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return DIRECTIVE.equals(vertex.getType()); + } + }; + VertexContextSegment directiveName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex directive, SchemaGraph schemaGraph) { + return directive.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + List contexts = Arrays.asList(directiveType, directiveName); + return contexts; + } + + private static List appliedDirectiveContext() { + VertexContextSegment appliedDirectiveType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return APPLIED_DIRECTIVE.equals(vertex.getType()); + } + }; + VertexContextSegment appliedDirectiveIndex = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedDirective, SchemaGraph schemaGraph) { + int appliedDirectiveIndex = schemaGraph.getAppliedDirectiveIndex(appliedDirective); + return Integer.toString(appliedDirectiveIndex); + } + + }; + + VertexContextSegment appliedDirectiveName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedDirective, SchemaGraph schemaGraph) { + return appliedDirective.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + VertexContextSegment appliedDirectiveContainer = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedDirective, SchemaGraph schemaGraph) { + Vertex appliedDirectiveContainer = schemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + return appliedDirectiveContainer.getType() + "." + appliedDirectiveContainer.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment parentOfContainer = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedDirective, SchemaGraph schemaGraph) { + Vertex container = schemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + switch (container.getType()) { + case SCHEMA: + return SCHEMA; + case FIELD: + Vertex fieldsContainer = schemaGraph.getFieldsContainerForField(container); + return fieldsContainer.getType() + "." + fieldsContainer.getName(); + case OBJECT: + return OBJECT; + case INTERFACE: + return INTERFACE; + case INPUT_FIELD: + Vertex inputObject = schemaGraph.getInputObjectForInputField(container); + return inputObject.getType() + "." + inputObject.getName(); + case ARGUMENT: + Vertex fieldOrDirective = schemaGraph.getFieldOrDirectiveForArgument(container); + return fieldOrDirective.getType() + "." + fieldOrDirective.getName(); + case INPUT_OBJECT: + return INPUT_OBJECT; + case ENUM: + return ENUM; + case UNION: + return UNION; + case SCALAR: + return SCALAR; + case ENUM_VALUE: + Vertex enumVertex = schemaGraph.getEnumForEnumValue(container); + return enumVertex.getType() + "." + enumVertex.getName(); + default: + throw new IllegalStateException("Unexpected directive container type " + container.getType()); + } + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + VertexContextSegment parentOfParentOfContainer = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedDirective, SchemaGraph schemaGraph) { + Vertex container = schemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + switch (container.getType()) { + case SCHEMA: + case FIELD: + case OBJECT: + case INTERFACE: + case INPUT_FIELD: + case INPUT_OBJECT: + case ENUM: + case ENUM_VALUE: + case UNION: + case SCALAR: + return ""; + case ARGUMENT: + Vertex fieldOrDirective = schemaGraph.getFieldOrDirectiveForArgument(container); + switch (fieldOrDirective.getType()) { + case FIELD: + Vertex fieldsContainer = schemaGraph.getFieldsContainerForField(fieldOrDirective); + return fieldsContainer.getType() + "." + fieldsContainer.getName(); + case DIRECTIVE: + return ""; + default: + return Assert.assertShouldNeverHappen(); + } + default: + throw new IllegalStateException("Unexpected directive container type " + container.getType()); + } + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment vertexContextSegment = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return parentOfParentOfContainer.idForVertex(vertex, schemaGraph) + "." + + parentOfContainer.idForVertex(vertex, schemaGraph) + "." + + appliedDirectiveContainer.idForVertex(vertex, schemaGraph) + "." + + appliedDirectiveName.idForVertex(vertex, schemaGraph); + } + }; + List contexts = Arrays.asList(appliedDirectiveType, vertexContextSegment, appliedDirectiveIndex); + return contexts; + } + + + private static List appliedArgumentContext() { + VertexContextSegment appliedArgumentType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return APPLIED_ARGUMENT.equals(vertex.getType()); + } + }; + VertexContextSegment appliedDirective = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedArgument, SchemaGraph schemaGraph) { + Vertex appliedDirective = schemaGraph.getAppliedDirectiveForAppliedArgument(appliedArgument); + int appliedDirectiveIndex = schemaGraph.getAppliedDirectiveIndex(appliedDirective); + return appliedDirectiveIndex + ":" + appliedDirective.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + VertexContextSegment appliedDirectiveContainer = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedArgument, SchemaGraph schemaGraph) { + Vertex appliedDirective = schemaGraph.getAppliedDirectiveForAppliedArgument(appliedArgument); + Vertex appliedDirectiveContainer = schemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + return appliedDirectiveContainer.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment parentOfContainer = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedArgument, SchemaGraph schemaGraph) { + Vertex appliedDirective = schemaGraph.getAppliedDirectiveForAppliedArgument(appliedArgument); + Vertex container = schemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + switch (container.getType()) { + case SCHEMA: + return SCHEMA; + case FIELD: + Vertex fieldsContainer = schemaGraph.getFieldsContainerForField(container); + return fieldsContainer.getType() + "." + fieldsContainer.getName(); + case OBJECT: + return OBJECT; + case INTERFACE: + return INTERFACE; + case INPUT_FIELD: + Vertex inputObject = schemaGraph.getInputObjectForInputField(container); + return inputObject.getType() + "." + inputObject.getName(); + case ARGUMENT: + Vertex fieldOrDirective = schemaGraph.getFieldOrDirectiveForArgument(container); + return fieldOrDirective.getType() + "." + fieldOrDirective.getName(); + case INPUT_OBJECT: + return INPUT_OBJECT; + case ENUM: + return ENUM; + case UNION: + return UNION; + case SCALAR: + return SCALAR; + case ENUM_VALUE: + Vertex enumVertex = schemaGraph.getEnumForEnumValue(container); + return enumVertex.getType() + "." + enumVertex.getName(); + default: + throw new IllegalStateException("Unexpected directive container type " + container.getType()); + } + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + VertexContextSegment parentOfParentOfContainer = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedArgument, SchemaGraph schemaGraph) { + Vertex appliedDirective = schemaGraph.getAppliedDirectiveForAppliedArgument(appliedArgument); + Vertex container = schemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + switch (container.getType()) { + case SCHEMA: + case FIELD: + case OBJECT: + case INTERFACE: + case INPUT_FIELD: + case INPUT_OBJECT: + case ENUM: + case ENUM_VALUE: + case UNION: + case SCALAR: + return ""; + case ARGUMENT: + Vertex fieldOrDirective = schemaGraph.getFieldOrDirectiveForArgument(container); + switch (fieldOrDirective.getType()) { + case FIELD: + Vertex fieldsContainer = schemaGraph.getFieldsContainerForField(fieldOrDirective); + return fieldsContainer.getType() + "." + fieldsContainer.getName(); + case DIRECTIVE: + return ""; + default: + return Assert.assertShouldNeverHappen(); + } + default: + throw new IllegalStateException("Unexpected directive container type " + container.getType()); + } + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment appliedArgumentName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex appliedArgument, SchemaGraph schemaGraph) { + return appliedArgument.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment combined = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return parentOfContainer.idForVertex(vertex, schemaGraph) + "." + + parentOfContainer.idForVertex(vertex, schemaGraph) + "." + + appliedDirectiveContainer.idForVertex(vertex, schemaGraph) + "." + + appliedDirective.idForVertex(vertex, schemaGraph) + "." + + appliedArgumentName.idForVertex(vertex, schemaGraph); + } + }; + List contexts = Arrays.asList(appliedArgumentType, combined); + return contexts; + } + + private static List schemaContext() { + VertexContextSegment schema = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return SCHEMA.equals(vertex.getType()); + } + }; + return singletonList(schema); + } + + private static List fieldContext() { + VertexContextSegment field = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return FIELD.equals(vertex.getType()); + } + }; + VertexContextSegment container = new VertexContextSegment() { + @Override + public String idForVertex(Vertex field, SchemaGraph schemaGraph) { + Vertex fieldsContainer = schemaGraph.getFieldsContainerForField(field); + return fieldsContainer.getType() + "." + fieldsContainer.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + + VertexContextSegment fieldName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex field, SchemaGraph schemaGraph) { + return field.getName(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(field, container, fieldName); + return contexts; + } + + private static List argumentsContexts() { + + VertexContextSegment argumentType = new VertexContextSegment() { + @Override + public String idForVertex(Vertex vertex, SchemaGraph schemaGraph) { + return vertex.getType(); + } + + @Override + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return ARGUMENT.equals(vertex.getType()); + } + }; + + VertexContextSegment fieldOrDirective = new VertexContextSegment() { + @Override + public String idForVertex(Vertex argument, SchemaGraph schemaGraph) { + Vertex fieldOrDirective = schemaGraph.getFieldOrDirectiveForArgument(argument); + return fieldOrDirective.getType() + "." + fieldOrDirective.getName(); + } + + @Override + public boolean filter(Vertex argument, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment containerOrDirectiveHolder = new VertexContextSegment() { + @Override + public String idForVertex(Vertex argument, SchemaGraph schemaGraph) { + Vertex fieldOrDirective = schemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.getType().equals(FIELD)) { + Vertex fieldsContainer = schemaGraph.getFieldsContainerForField(fieldOrDirective); + // can be Interface or Object + return fieldsContainer.getType() + "." + fieldsContainer.getName(); + } else { + // a directive doesn't have further context + return ""; + } + } + + @Override + public boolean filter(Vertex argument, SchemaGraph schemaGraph) { + return true; + } + }; + VertexContextSegment argumentName = new VertexContextSegment() { + @Override + public String idForVertex(Vertex argument, SchemaGraph schemaGraph) { + return argument.getName(); + } + + @Override + public boolean filter(Vertex argument, SchemaGraph schemaGraph) { + return true; + } + }; + List contexts = Arrays.asList(argumentType, containerOrDirectiveHolder, fieldOrDirective, argumentName); + return contexts; + } + + + public PossibleMappingsCalculator(SchemaGraph sourceGraph, SchemaGraph targetGraph, SchemaDiffingRunningCheck runningCheck) { + this.runningCheck = runningCheck; + this.sourceGraph = sourceGraph; + this.targetGraph = targetGraph; + this.possibleMappings = new PossibleMappings(); + } + + public PossibleMappings calculate() { + calcPossibleMappings(typeContexts.get(SCHEMA), SCHEMA); + calcPossibleMappings(typeContexts.get(FIELD), FIELD); + calcPossibleMappings(typeContexts.get(ARGUMENT), ARGUMENT); + calcPossibleMappings(typeContexts.get(INPUT_FIELD), INPUT_FIELD); + calcPossibleMappings(typeContexts.get(OBJECT), OBJECT); + calcPossibleMappings(typeContexts.get(INTERFACE), INTERFACE); + calcPossibleMappings(typeContexts.get(UNION), UNION); + calcPossibleMappings(typeContexts.get(INPUT_OBJECT), INPUT_OBJECT); + calcPossibleMappings(typeContexts.get(SCALAR), SCALAR); + calcPossibleMappings(typeContexts.get(ENUM), ENUM); + calcPossibleMappings(typeContexts.get(ENUM_VALUE), ENUM_VALUE); + calcPossibleMappings(typeContexts.get(APPLIED_DIRECTIVE), APPLIED_DIRECTIVE); + calcPossibleMappings(typeContexts.get(APPLIED_ARGUMENT), APPLIED_ARGUMENT); + calcPossibleMappings(typeContexts.get(DIRECTIVE), DIRECTIVE); + + + sourceGraph.addVertices(possibleMappings.allIsolatedSource); + targetGraph.addVertices(possibleMappings.allIsolatedTarget); + + Assert.assertTrue(sourceGraph.size() == targetGraph.size()); + Set vertices = possibleMappings.possibleMappings.keySet(); + for (Vertex vertex : vertices) { + if (possibleMappings.possibleMappings.get(vertex).size() > 1) { +// System.out.println("vertex with possible mappings: " + possibleMappings.possibleMappings.get(vertex).size()); +// System.out.println("vertex " + vertex); +// System.out.println("-------------"); + } + } + + return possibleMappings; + } + + public abstract static class VertexContextSegment { + public VertexContextSegment() { + } + + public abstract String idForVertex(Vertex vertex, SchemaGraph schemaGraph); + + public boolean filter(Vertex vertex, SchemaGraph schemaGraph) { + return true; + } + } + + public class PossibleMappings { + + public Set allIsolatedSource = new LinkedHashSet<>(); + public Set allIsolatedTarget = new LinkedHashSet<>(); + + public Table, Set, Set> contexts = HashBasedTable.create(); + + public Multimap possibleMappings = HashMultimap.create(); + + public BiMap fixedOneToOneMappings = HashBiMap.create(); + public List fixedOneToOneSources = new ArrayList<>(); + public List fixedOneToOneTargets = new ArrayList<>(); + + public void putPossibleMappings(List contextId, + Collection sourceVertices, + Collection targetVertices, + String typeName) { + if (sourceVertices.isEmpty() && targetVertices.isEmpty()) { + return; + } + + if (sourceVertices.size() == 1 && targetVertices.size() == 1) { + Vertex sourceVertex = sourceVertices.iterator().next(); + Vertex targetVertex = targetVertices.iterator().next(); + fixedOneToOneMappings.put(sourceVertex, targetVertex); + fixedOneToOneSources.add(sourceVertex); + fixedOneToOneTargets.add(targetVertex); + return; + } + + if (APPLIED_DIRECTIVE.equals(typeName) || APPLIED_ARGUMENT.equals(typeName)) { + for (Vertex sourceVertex : sourceVertices) { + Vertex isolatedTarget = Vertex.newIsolatedNode("target-isolated-" + typeName); + allIsolatedTarget.add(isolatedTarget); + fixedOneToOneMappings.put(sourceVertex, isolatedTarget); + fixedOneToOneSources.add(sourceVertex); + fixedOneToOneTargets.add(isolatedTarget); + } + for (Vertex targetVertex : targetVertices) { + Vertex isolatedSource = Vertex.newIsolatedNode("source-isolated-" + typeName); + allIsolatedSource.add(isolatedSource); + fixedOneToOneMappings.put(isolatedSource, targetVertex); + fixedOneToOneSources.add(isolatedSource); + fixedOneToOneTargets.add(targetVertex); + } + return; + } + + Set newIsolatedSource = Collections.emptySet(); + Set newIsolatedTarget = Collections.emptySet(); + if (sourceVertices.size() > targetVertices.size()) { + newIsolatedTarget = Vertex.newIsolatedNodes(sourceVertices.size() - targetVertices.size(), "target-isolated-" + typeName + "-"); + } else if (targetVertices.size() > sourceVertices.size()) { + newIsolatedSource = Vertex.newIsolatedNodes(targetVertices.size() - sourceVertices.size(), "source-isolated-" + typeName + "-"); + } + this.allIsolatedSource.addAll(newIsolatedSource); + this.allIsolatedTarget.addAll(newIsolatedTarget); + + if (sourceVertices.size() == 0) { + Iterator iterator = newIsolatedSource.iterator(); + for (Vertex targetVertex : targetVertices) { + Vertex isolatedSourceVertex = iterator.next(); + fixedOneToOneMappings.put(isolatedSourceVertex, targetVertex); + fixedOneToOneSources.add(isolatedSourceVertex); + fixedOneToOneTargets.add(targetVertex); + } + return; + } + if (targetVertices.size() == 0) { + Iterator iterator = newIsolatedTarget.iterator(); + for (Vertex sourceVertex : sourceVertices) { + Vertex isolatedTargetVertex = iterator.next(); + fixedOneToOneMappings.put(sourceVertex, isolatedTargetVertex); + fixedOneToOneSources.add(sourceVertex); + fixedOneToOneTargets.add(isolatedTargetVertex); + } + return; + } + +// System.out.println("multiple mappings for context" + contextId + " overall size: " + (sourceVertices.size() + newIsolatedSource.size())); +// List vertexContextSegments = typeContexts.get(typeName); +// System.out.println("source ids: " + sourceVertices.size()); +// for (Vertex sourceVertex : sourceVertices) { +// List id = vertexContextSegments.stream().map(vertexContextSegment -> vertexContextSegment.idForVertex(sourceVertex, sourceGraph)) +// .collect(Collectors.toList()); +// System.out.println("id: " + id); +// } +// System.out.println("target ids ==================: " + targetVertices.size()); +// for (Vertex targetVertex : targetVertices) { +// List id = vertexContextSegments.stream().map(vertexContextSegment -> vertexContextSegment.idForVertex(targetVertex, targetGraph)) +// .collect(Collectors.toList()); +// System.out.println("id: " + id); +// } +// System.out.println("-------------------"); +// System.out.println("-------------------"); + + Assert.assertFalse(contexts.containsRow(contextId)); + + Set allSource = new LinkedHashSet<>(); + allSource.addAll(sourceVertices); + allSource.addAll(newIsolatedSource); + Set allTarget = new LinkedHashSet<>(); + allTarget.addAll(targetVertices); + allTarget.addAll(newIsolatedTarget); + contexts.put(contextId, allSource, allTarget); + for (Vertex sourceVertex : sourceVertices) { + possibleMappings.putAll(sourceVertex, targetVertices); + possibleMappings.putAll(sourceVertex, newIsolatedTarget); + } + for (Vertex sourceIsolatedVertex : newIsolatedSource) { + possibleMappings.putAll(sourceIsolatedVertex, targetVertices); + possibleMappings.putAll(sourceIsolatedVertex, newIsolatedTarget); + } + + + } + + // + public boolean mappingPossible(Vertex sourceVertex, Vertex targetVertex) { + return possibleMappings.containsEntry(sourceVertex, targetVertex); + } + } + + + public void calcPossibleMappings(List contexts, String typeNameForDebug) { + Collection currentSourceVertices = sourceGraph.getVertices(); + Collection currentTargetVertices = targetGraph.getVertices(); + calcPossibleMappingImpl(currentSourceVertices, + currentTargetVertices, + Collections.emptyList(), + 0, + contexts, + new LinkedHashSet<>(), + new LinkedHashSet<>(), + typeNameForDebug); + } + + /** + * calc for the provided context + */ + private void calcPossibleMappingImpl( + Collection currentSourceVertices, + Collection currentTargetVertices, + List contextId, + int contextIx, + List contexts, + Set usedSourceVertices, + Set usedTargetVertices, + String typeNameForDebug) { + runningCheck.check(); + + VertexContextSegment finalCurrentContext = contexts.get(contextIx); + Map> sourceGroups = FpKit.filterAndGroupingBy(currentSourceVertices, + v -> finalCurrentContext.filter(v, sourceGraph), + v -> finalCurrentContext.idForVertex(v, sourceGraph)); + Map> targetGroups = FpKit.filterAndGroupingBy(currentTargetVertices, + v -> finalCurrentContext.filter(v, targetGraph), + v -> finalCurrentContext.idForVertex(v, targetGraph)); + + + List deletedContexts = new ArrayList<>(); + List insertedContexts = new ArrayList<>(); + List sameContexts = new ArrayList<>(); + Util.diffNamedList(sourceGroups.keySet(), targetGroups.keySet(), deletedContexts, insertedContexts, sameContexts); + + // for each unchanged context we descend recursively into + for (String sameContext : sameContexts) { + ImmutableList sourceVerticesInContext = sourceGroups.get(sameContext); + ImmutableList targetVerticesInContext = targetGroups.get(sameContext); + + List currentContextId = concat(contextId, sameContext); + if (contexts.size() > contextIx + 1) { + calcPossibleMappingImpl(sourceVerticesInContext, targetVerticesInContext, currentContextId, contextIx + 1, contexts, usedSourceVertices, usedTargetVertices, typeNameForDebug); + } + /** + * Either there was no context segment left or not all vertices were relevant for + * Either way: fill up with isolated vertices and record as possible mapping + */ + Set notUsedSource = new LinkedHashSet<>(sourceVerticesInContext); + notUsedSource.removeAll(usedSourceVertices); + Set notUsedTarget = new LinkedHashSet<>(targetVerticesInContext); + notUsedTarget.removeAll(usedTargetVertices); + + possibleMappings.putPossibleMappings(currentContextId, notUsedSource, notUsedTarget, typeNameForDebug); + usedSourceVertices.addAll(notUsedSource); + usedTargetVertices.addAll(notUsedTarget); + } + + /** + * update the used vertices with the deleted and inserted contexts + */ + Set possibleSourceVertices = new LinkedHashSet<>(); + for (String deletedContext : deletedContexts) { + ImmutableList vertices = sourceGroups.get(deletedContext); + for (Vertex sourceVertex : vertices) { + if (!usedSourceVertices.contains(sourceVertex)) { + possibleSourceVertices.add(sourceVertex); + } + } + usedSourceVertices.addAll(vertices); + } + + Set possibleTargetVertices = new LinkedHashSet<>(); + for (String insertedContext : insertedContexts) { + ImmutableList vertices = targetGroups.get(insertedContext); + for (Vertex targetVertex : vertices) { + if (!usedTargetVertices.contains(targetVertex)) { + possibleTargetVertices.add(targetVertex); + } + } + usedTargetVertices.addAll(vertices); + } + if (contextId.size() == 0) { + contextId = singletonList(typeNameForDebug); + } + possibleMappings.putPossibleMappings(contextId, possibleSourceVertices, possibleTargetVertices, typeNameForDebug); + } + + public Map getFixedParentRestrictions() { + return getFixedParentRestrictions( + sourceGraph, + possibleMappings.fixedOneToOneSources, + possibleMappings.fixedOneToOneMappings + ); + } + + public Map getFixedParentRestrictionsInverse(Map fixedOneToOneMappingsInverted) { + return getFixedParentRestrictions( + targetGraph, + possibleMappings.fixedOneToOneTargets, + fixedOneToOneMappingsInverted + ); + } + + /** + * This computes the initial set of parent restrictions based on the fixed portion of the mapping. + *

+ * See {@link Mapping} for definition of fixed vs non-fixed. + *

+ * If a {@link Vertex} is present in the output {@link Map} then the value is the parent the + * vertex MUST map to. + *

+ * e.g. for an output {collar: Dog} then the collar vertex must be a child of Dog in the mapping. + * + * @return Map where key is any vertex, and the value is the parent that vertex must map to + */ + private Map getFixedParentRestrictions(SchemaGraph sourceGraph, + List fixedSourceVertices, + Map fixedOneToOneMappings) { + Assert.assertFalse(fixedOneToOneMappings.isEmpty()); + + List needsFixing = new ArrayList<>(sourceGraph.getVertices()); + needsFixing.removeAll(fixedSourceVertices); + + Map restrictions = new LinkedHashMap<>(); + + for (Vertex vertex : needsFixing) { + if (hasParentRestrictions(vertex)) { + Vertex sourceParent = sourceGraph.getSingleAdjacentInverseVertex(vertex); + Vertex fixedTargetParent = fixedOneToOneMappings.get(sourceParent); + + if (fixedTargetParent != null) { + for (Edge edge : sourceGraph.getAdjacentEdgesNonCopy(sourceParent)) { + Vertex sibling = edge.getTo(); + + if (hasParentRestrictions(sibling)) { + restrictions.put(sibling, fixedTargetParent); + } + } + } + } + } + + return restrictions; + } + + /** + * This computes the initial set of parent restrictions based on the given non-fixed mapping. + *

+ * i.e. this introduces restrictions as the {@link Mapping} is being built, as decisions + * can have knock on effects on other vertices' possible mappings. + *

+ * See {@link Mapping} for definition of fixed vs non-fixed. + *

+ * If a {@link Vertex} is present in the output {@link Map} then the value is the parent the + * vertex MUST map to. + *

+ * e.g. for an output {collar: Dog} then the collar vertex must be a child of Dog in the mapping. + * + * @param mapping the mapping to get non-fixed parent restrictions for + * @param sourceGraph the source graph + * @param targetGraph the target graph + * @return Map where key is any vertex, and the value is the parent that vertex must map to + */ + public Map getNonFixedParentRestrictions(SchemaGraph sourceGraph, + SchemaGraph targetGraph, + Mapping mapping) { + Map restrictions = new LinkedHashMap<>(); + + mapping.forEachNonFixedSourceAndTarget((source, target) -> { + if (hasChildrenRestrictions(source) && hasChildrenRestrictions(target)) { + for (Edge edge : sourceGraph.getAdjacentEdgesNonCopy(source)) { + Vertex child = edge.getTo(); + + if (hasParentRestrictions(child)) { + restrictions.put(child, target); + } + } + } else if (hasParentRestrictions(source) && hasParentRestrictions(target)) { + Vertex sourceParent = sourceGraph.getSingleAdjacentInverseVertex(source); + Vertex targetParent = targetGraph.getSingleAdjacentInverseVertex(target); + + for (Edge edge : sourceGraph.getAdjacentEdgesNonCopy(sourceParent)) { + Vertex sibling = edge.getTo(); + + if (hasParentRestrictions(sibling)) { + restrictions.put(sibling, targetParent); + } + } + } + }); + + return restrictions; + } + + public static boolean hasParentRestrictions(Vertex vertex) { + return vertex.isOfType(SchemaGraph.FIELD) + || vertex.isOfType(SchemaGraph.INPUT_FIELD) + || vertex.isOfType(SchemaGraph.ENUM_VALUE) + || vertex.isOfType(SchemaGraph.ARGUMENT); + } + + public static boolean hasChildrenRestrictions(Vertex vertex) { + return vertex.isOfType(SchemaGraph.INPUT_OBJECT) + || vertex.isOfType(SchemaGraph.OBJECT) + || vertex.isOfType(SchemaGraph.ENUM); + } +} diff --git a/src/main/java/graphql/schema/diffing/SchemaDiffing.java b/src/main/java/graphql/schema/diffing/SchemaDiffing.java new file mode 100644 index 0000000000..b12f8aec5a --- /dev/null +++ b/src/main/java/graphql/schema/diffing/SchemaDiffing.java @@ -0,0 +1,137 @@ +package graphql.schema.diffing; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimaps; +import graphql.Internal; +import graphql.schema.GraphQLSchema; +import graphql.schema.diffing.ana.EditOperationAnalysisResult; +import graphql.schema.diffing.ana.EditOperationAnalyzer; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static graphql.Assert.assertTrue; +import static graphql.schema.diffing.EditorialCostForMapping.baseEditorialCostForMapping; + +@Internal +public class SchemaDiffing { + private final SchemaDiffingRunningCheck runningCheck = new SchemaDiffingRunningCheck(); + + SchemaGraph sourceGraph; + SchemaGraph targetGraph; + + /** + * Tries to stop the algorithm from execution ASAP by throwing a + * {@link SchemaDiffingCancelledException}. + */ + public void stop() { + runningCheck.stop(); + } + + public List diffGraphQLSchema(GraphQLSchema graphQLSchema1, GraphQLSchema graphQLSchema2) throws Exception { + sourceGraph = new SchemaGraphFactory("source-").createGraph(graphQLSchema1); + targetGraph = new SchemaGraphFactory("target-").createGraph(graphQLSchema2); + return diffImpl(sourceGraph, targetGraph, new AtomicInteger()).getListOfEditOperations(); + } + + public EditOperationAnalysisResult diffAndAnalyze(GraphQLSchema graphQLSchema1, GraphQLSchema graphQLSchema2) throws Exception { + sourceGraph = new SchemaGraphFactory("source-").createGraph(graphQLSchema1); + targetGraph = new SchemaGraphFactory("target-").createGraph(graphQLSchema2); + DiffImpl.OptimalEdit optimalEdit = diffImpl(sourceGraph, targetGraph, new AtomicInteger()); + EditOperationAnalyzer editOperationAnalyzer = new EditOperationAnalyzer(graphQLSchema1, graphQLSchema1, sourceGraph, targetGraph); + return editOperationAnalyzer.analyzeEdits(optimalEdit.getListOfEditOperations(), optimalEdit.mapping); + } + + public DiffImpl.OptimalEdit diffGraphQLSchemaAllEdits(GraphQLSchema graphQLSchema1, GraphQLSchema graphQLSchema2, AtomicInteger algoIterationCount) throws Exception { + sourceGraph = new SchemaGraphFactory("source-").createGraph(graphQLSchema1); + targetGraph = new SchemaGraphFactory("target-").createGraph(graphQLSchema2); + return diffImpl(sourceGraph, targetGraph, algoIterationCount); + } + + + private DiffImpl.OptimalEdit diffImpl(SchemaGraph sourceGraph, SchemaGraph targetGraph, AtomicInteger algoIterationCount) throws Exception { + PossibleMappingsCalculator possibleMappingsCalculator = new PossibleMappingsCalculator(sourceGraph, targetGraph, runningCheck); + PossibleMappingsCalculator.PossibleMappings possibleMappings = possibleMappingsCalculator.calculate(); + + Mapping startMapping = Mapping.newMapping( + possibleMappingsCalculator.getFixedParentRestrictions(), + possibleMappings.fixedOneToOneMappings, + possibleMappings.fixedOneToOneSources, + possibleMappings.fixedOneToOneTargets); + + assertTrue(sourceGraph.size() == targetGraph.size()); + if (possibleMappings.fixedOneToOneMappings.size() == sourceGraph.size()) { + return new DiffImpl.OptimalEdit(sourceGraph, targetGraph, startMapping, baseEditorialCostForMapping(startMapping, sourceGraph, targetGraph)); + } + + List nonMappedSource = new ArrayList<>(sourceGraph.getVertices()); + nonMappedSource.removeAll(possibleMappings.fixedOneToOneSources); + + List nonMappedTarget = new ArrayList<>(targetGraph.getVertices()); + nonMappedTarget.removeAll(possibleMappings.fixedOneToOneTargets); + + runningCheck.check(); + + int isolatedSourceCount = (int) nonMappedSource.stream().filter(Vertex::isIsolated).count(); + int isolatedTargetCount = (int) nonMappedTarget.stream().filter(Vertex::isIsolated).count(); + if (isolatedTargetCount > isolatedSourceCount) { + // we flip source and target because the algo works much faster with + // this way for delete heavy graphs + BiMap fixedOneToOneInverted = HashBiMap.create(); + for (Vertex s : possibleMappings.fixedOneToOneMappings.keySet()) { + Vertex t = possibleMappings.fixedOneToOneMappings.get(s); + fixedOneToOneInverted.put(t, s); + } + Mapping startMappingInverted = Mapping.newMapping( + possibleMappingsCalculator.getFixedParentRestrictionsInverse(fixedOneToOneInverted), + fixedOneToOneInverted, + possibleMappings.fixedOneToOneTargets, + possibleMappings.fixedOneToOneSources + ); + HashMultimap invertedPossibleOnes = HashMultimap.create(); + Multimaps.invertFrom(possibleMappings.possibleMappings, invertedPossibleOnes); + possibleMappings.possibleMappings = invertedPossibleOnes; + + sortVertices(nonMappedTarget, targetGraph, possibleMappings); + + List sourceVertices = new ArrayList<>(); + sourceVertices.addAll(possibleMappings.fixedOneToOneSources); + sourceVertices.addAll(nonMappedSource); + + + List targetVertices = new ArrayList<>(); + targetVertices.addAll(possibleMappings.fixedOneToOneTargets); + targetVertices.addAll(nonMappedTarget); + + + DiffImpl diffImpl = new DiffImpl(possibleMappingsCalculator, targetGraph, sourceGraph, possibleMappings, runningCheck); + DiffImpl.OptimalEdit optimalEdit = diffImpl.diffImpl(startMappingInverted, targetVertices, sourceVertices, algoIterationCount); + DiffImpl.OptimalEdit invertedBackOptimalEdit = new DiffImpl.OptimalEdit(sourceGraph, targetGraph, optimalEdit.mapping.invert(), optimalEdit.ged); + return invertedBackOptimalEdit; + } else { + sortVertices(nonMappedSource, sourceGraph, possibleMappings); + + List sourceVertices = new ArrayList<>(); + sourceVertices.addAll(possibleMappings.fixedOneToOneSources); + sourceVertices.addAll(nonMappedSource); + + List targetVertices = new ArrayList<>(); + targetVertices.addAll(possibleMappings.fixedOneToOneTargets); + targetVertices.addAll(nonMappedTarget); + + DiffImpl diffImpl = new DiffImpl(possibleMappingsCalculator, sourceGraph, targetGraph, possibleMappings, runningCheck); + DiffImpl.OptimalEdit optimalEdit = diffImpl.diffImpl(startMapping, sourceVertices, targetVertices, algoIterationCount); + return optimalEdit; + } + } + + + private void sortVertices(List vertices, SchemaGraph schemaGraph, PossibleMappingsCalculator.PossibleMappings possibleMappings) { + Comparator vertexComparator = Comparator.comparing(schemaGraph::adjacentEdgesAndInverseCount).reversed(); + vertices.sort(vertexComparator); + } +} diff --git a/src/main/java/graphql/schema/diffing/SchemaDiffingCancelledException.java b/src/main/java/graphql/schema/diffing/SchemaDiffingCancelledException.java new file mode 100644 index 0000000000..1288644191 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/SchemaDiffingCancelledException.java @@ -0,0 +1,10 @@ +package graphql.schema.diffing; + +import graphql.Internal; + +@Internal +public class SchemaDiffingCancelledException extends RuntimeException { + SchemaDiffingCancelledException(boolean byInterrupt) { + super("Schema diffing job was cancelled by " + (byInterrupt ? "thread interrupt" : "stop call")); + } +} diff --git a/src/main/java/graphql/schema/diffing/SchemaDiffingRunningCheck.java b/src/main/java/graphql/schema/diffing/SchemaDiffingRunningCheck.java new file mode 100644 index 0000000000..8b0182eb38 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/SchemaDiffingRunningCheck.java @@ -0,0 +1,17 @@ +package graphql.schema.diffing; + +import java.util.concurrent.atomic.AtomicBoolean; + +class SchemaDiffingRunningCheck { + private final AtomicBoolean wasStopped = new AtomicBoolean(false); + + void check() { + if (wasStopped.get()) { + throw new SchemaDiffingCancelledException(false); + } + } + + void stop() { + wasStopped.set(true); + } +} diff --git a/src/main/java/graphql/schema/diffing/SchemaGraph.java b/src/main/java/graphql/schema/diffing/SchemaGraph.java new file mode 100644 index 0000000000..a89c35cdbe --- /dev/null +++ b/src/main/java/graphql/schema/diffing/SchemaGraph.java @@ -0,0 +1,303 @@ +package graphql.schema.diffing; + + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Iterables; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Table; +import graphql.ExperimentalApi; +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; + +import static graphql.Assert.assertTrue; + +@ExperimentalApi +public class SchemaGraph { + + public static final String SCHEMA = "Schema"; + public static final String OBJECT = "Object"; + public static final String INTERFACE = "Interface"; + public static final String UNION = "Union"; + public static final String FIELD = "Field"; + public static final String ARGUMENT = "Argument"; + public static final String SCALAR = "Scalar"; + public static final String ENUM = "Enum"; + public static final String ENUM_VALUE = "EnumValue"; + public static final String INPUT_OBJECT = "InputObject"; + public static final String INPUT_FIELD = "InputField"; + public static final String DIRECTIVE = "Directive"; + public static final String APPLIED_DIRECTIVE = "AppliedDirective"; + public static final String APPLIED_ARGUMENT = "AppliedArgument"; + public static final String ISOLATED = "__ISOLATED"; + + + private List vertices = new ArrayList<>(); + private List edges = new ArrayList<>(); + + private Map typesByName = new LinkedHashMap<>(); + private Map directivesByName = new LinkedHashMap<>(); + private Table edgesByDirection = HashBasedTable.create(); + private Table edgesByInverseDirection = HashBasedTable.create(); + private Multimap typeToVertices = LinkedHashMultimap.create(); + + public SchemaGraph() { + + } + + public SchemaGraph(List vertices, List edges, Table edgeByVertexPair) { + this.vertices = vertices; + this.edges = edges; + this.edgesByDirection = edgeByVertexPair; + } + + public void addVertex(Vertex vertex) { + vertices.add(vertex); + typeToVertices.put(vertex.getType(), vertex); + } + + public void addVertices(Collection vertices) { + for (Vertex vertex : vertices) { + this.vertices.add(vertex); + typeToVertices.put(vertex.getType(), vertex); + } + } + + public Collection getVerticesByType(String type) { + return typeToVertices.get(type); + } + + public Multimap getVerticesByType() { + return typeToVertices; + } + + public void addEdge(Edge edge) { + edges.add(edge); + edgesByDirection.put(edge.getFrom(), edge.getTo(), edge); + edgesByInverseDirection.put(edge.getTo(), edge.getFrom(), edge); + } + + // +// public List getAdjacentEdges(Vertex from) { +// return new ArrayList<>(edgesByDirection.row(from).values()); +// } + public Collection getAdjacentEdgesNonCopy(Vertex from) { + return edgesByDirection.row(from).values(); + } + + public Iterable getAdjacentEdgesAndInverseNonCopy(Vertex fromAndTo) { + Collection edges = edgesByInverseDirection.row(fromAndTo).values(); + Collection edgesInverse = edgesByDirection.row(fromAndTo).values(); + return Iterables.concat(edges, edgesInverse); + } + + public int adjacentEdgesAndInverseCount(Vertex fromAndTo) { + return edgesByInverseDirection.row(fromAndTo).size() + edgesByDirection.row(fromAndTo).size(); + } + + public List getAdjacentVertices(Vertex from) { + return getAdjacentVertices(from, x -> true); + } + + public List getAdjacentVertices(Vertex from, Predicate predicate) { + List result = new ArrayList<>(); + for (Edge edge : edgesByDirection.row(from).values()) { + Vertex v = edge.getTo(); + if (predicate.test(v)) { + result.add(v); + } + } + return result; + } + + public List getAdjacentVerticesInverse(Vertex to) { + return getAdjacentVerticesInverse(to, x -> true); + } + + public List getAdjacentVerticesInverse(Vertex to, Predicate predicate) { + List result = new ArrayList<>(); + for (Edge edge : edgesByInverseDirection.row(to).values()) { + Vertex v = edge.getFrom(); + if (predicate.test(v)) { + result.add(v); + } + } + return result; + } + + public List getAdjacentEdges(Vertex from) { + return getAdjacentEdges(from, x -> true); + } + public List getAdjacentEdges(Vertex from, Predicate predicate) { + List result = new ArrayList<>(); + for (Edge edge : edgesByDirection.row(from).values()) { + Vertex v = edge.getTo(); + if (predicate.test(v)) { + result.add(edge); + } + } + return result; + } + + public List getAdjacentEdgesInverseCopied(Vertex to) { + return new ArrayList<>(edgesByInverseDirection.row(to).values()); + } + + public Collection getAdjacentEdgesInverseNonCopy(Vertex to) { + return edgesByInverseDirection.row(to).values(); + } + + public List getAdjacentEdgesInverse(Vertex to, Predicate predicate) { + List result = new ArrayList<>(); + for (Edge edge : edgesByInverseDirection.row(to).values()) { + Vertex v = edge.getFrom(); + if (predicate.test(v)) { + result.add(edge); + } + } + return result; + } + + public Edge getSingleAdjacentEdge(Vertex from, Predicate predicate) { + for (Edge edge : edgesByDirection.row(from).values()) { + if (predicate.test(edge)) { + return edge; + } + } + return null; + } + + public List getEdges() { + return edges; + } + + // null if the edge doesn't exist + public @Nullable Edge getEdge(Vertex from, Vertex to) { + return edgesByDirection.get(from, to); + } + + public @Nullable Edge getEdgeOrInverse(Vertex from, Vertex to) { + Edge result = edgesByDirection.get(from, to); + return result != null ? result : edgesByInverseDirection.get(from, to); + } + + public List getVertices() { + return vertices; + } + + public void setVertices(List vertices) { + this.vertices = vertices; + } + + public void addType(String name, Vertex vertex) { + typesByName.put(name, vertex); + } + + public void addDirective(String name, Vertex vertex) { + directivesByName.put(name, vertex); + } + + public Vertex getType(String name) { + return typesByName.get(name); + } + + public Vertex getDirective(String name) { + return directivesByName.get(name); + } + + public Optional findTargetVertex(Vertex from, Predicate vertexPredicate) { + return edgesByDirection.row(from).values().stream().map(Edge::getTo).filter(vertexPredicate).findFirst(); + } + + public int size() { + return vertices.size(); + } + + public List addIsolatedVertices(int count, String debugPrefix) { + List result = new ArrayList<>(); + for (int i = 0; i < count; i++) { + Vertex isolatedVertex = Vertex.newIsolatedNode(debugPrefix + i); + vertices.add(isolatedVertex); + result.add(isolatedVertex); + } + return result; + } + + public Vertex getFieldOrDirectiveForArgument(Vertex argument) { + List adjacentVertices = getAdjacentVerticesInverse(argument); + assertTrue(adjacentVertices.size() == 1, "No field or directive found for %s", argument); + return adjacentVertices.get(0); + } + + public Vertex getFieldsContainerForField(Vertex field) { + List adjacentVertices = getAdjacentVerticesInverse(field); + assertTrue(adjacentVertices.size() == 1, "No fields container found for %s", field); + return adjacentVertices.get(0); + } + + public Vertex getInputObjectForInputField(Vertex inputField) { + List adjacentVertices = this.getAdjacentVerticesInverse(inputField); + assertTrue(adjacentVertices.size() == 1, "No input object found for %s", inputField); + return adjacentVertices.get(0); + } + + public Vertex getAppliedDirectiveForAppliedArgument(Vertex appliedArgument) { + List adjacentVertices = this.getAdjacentVerticesInverse(appliedArgument); + assertTrue(adjacentVertices.size() == 1, "No applied directive found for %s", appliedArgument); + return adjacentVertices.get(0); + } + + public Vertex getAppliedDirectiveContainerForAppliedDirective(Vertex appliedDirective) { + List adjacentVertices = this.getAdjacentVerticesInverse(appliedDirective); + assertTrue(adjacentVertices.size() == 1, "No applied directive container found for %s", appliedDirective); + return adjacentVertices.get(0); + } + + /** + * Gets the one inverse adjacent edge to the input and gets the other vertex. + * + * @param input the vertex input + * @return a vertex + */ + public Vertex getSingleAdjacentInverseVertex(Vertex input) { + Collection adjacentVertices = this.getAdjacentEdgesInverseNonCopy(input); + assertTrue(adjacentVertices.size() == 1, "No parent found for %s", input); + return adjacentVertices.iterator().next().getFrom(); + } + + public int getAppliedDirectiveIndex(Vertex appliedDirective) { + List adjacentEdges = this.getAdjacentEdgesInverseCopied(appliedDirective); + assertTrue(adjacentEdges.size() == 1, "No applied directive container found for %s", appliedDirective); + return Integer.parseInt(adjacentEdges.get(0).getLabel()); + } + + public Vertex getEnumForEnumValue(Vertex enumValue) { + List adjacentVertices = this.getAdjacentVerticesInverse(enumValue); + assertTrue(adjacentVertices.size() == 1, "No enum found for %s", enumValue); + return adjacentVertices.get(0); + } + + + public List getAllAdjacentEdges(List fromList, Vertex to) { + List result = new ArrayList<>(); + for (Vertex from : fromList) { + Edge edge = getEdge(from, to); + if (edge == null) { + continue; + } + result.add(edge); + } + return result; + } + + public boolean containsEdge(Vertex from, Vertex to) { + return this.edges.stream().anyMatch(edge -> edge.getFrom().equals(from) && edge.getTo().equals(to)); + } +} diff --git a/src/main/java/graphql/schema/diffing/SchemaGraphFactory.java b/src/main/java/graphql/schema/diffing/SchemaGraphFactory.java new file mode 100644 index 0000000000..37ac8d5e31 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/SchemaGraphFactory.java @@ -0,0 +1,420 @@ +package graphql.schema.diffing; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.ValuesResolver; +import graphql.introspection.Introspection; +import graphql.language.AstPrinter; +import graphql.schema.*; +import graphql.schema.idl.DirectiveInfo; +import graphql.schema.idl.ScalarInfo; +import graphql.util.TraversalControl; +import graphql.util.Traverser; +import graphql.util.TraverserContext; +import graphql.util.TraverserVisitor; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import static graphql.Assert.assertNotNull; + +@Internal +public class SchemaGraphFactory { + + private int counter = 1; + private final String debugPrefix; + + public SchemaGraphFactory(String debugPrefix) { + this.debugPrefix = debugPrefix; + } + + public SchemaGraphFactory() { + this.debugPrefix = ""; + } + + public SchemaGraph createGraph(GraphQLSchema schema) { + Set roots = new LinkedHashSet<>(); + roots.add(schema.getQueryType()); + if (schema.isSupportingMutations()) { + roots.add(schema.getMutationType()); + } + if (schema.isSupportingSubscriptions()) { + roots.add(schema.getSubscriptionType()); + } + roots.addAll(schema.getAdditionalTypes()); + roots.addAll(schema.getDirectives()); + roots.addAll(schema.getSchemaDirectives()); + roots.add(schema.getIntrospectionSchemaType()); + Traverser traverser = Traverser.depthFirst(GraphQLSchemaElement::getChildren); + SchemaGraph schemaGraph = new SchemaGraph(); + class IntrospectionNode { + + } + traverser.traverse(roots, new TraverserVisitor() { + @Override + public TraversalControl enter(TraverserContext context) { + boolean isIntrospectionNode = false; + if (context.thisNode() instanceof GraphQLNamedType) { + if (Introspection.isIntrospectionTypes((GraphQLNamedType) context.thisNode())) { + isIntrospectionNode = true; + context.setVar(IntrospectionNode.class, new IntrospectionNode()); + } + } else { + isIntrospectionNode = context.getVarFromParents(IntrospectionNode.class) != null; + } + if (context.thisNode() instanceof GraphQLObjectType) { + newObject((GraphQLObjectType) context.thisNode(), schemaGraph, isIntrospectionNode); + } + if (context.thisNode() instanceof GraphQLInterfaceType) { + newInterface((GraphQLInterfaceType) context.thisNode(), schemaGraph, isIntrospectionNode); + } + if (context.thisNode() instanceof GraphQLUnionType) { + newUnion((GraphQLUnionType) context.thisNode(), schemaGraph, isIntrospectionNode); + } + if (context.thisNode() instanceof GraphQLScalarType) { + newScalar((GraphQLScalarType) context.thisNode(), schemaGraph, isIntrospectionNode); + } + if (context.thisNode() instanceof GraphQLInputObjectType) { + newInputObject((GraphQLInputObjectType) context.thisNode(), schemaGraph, isIntrospectionNode); + } + if (context.thisNode() instanceof GraphQLEnumType) { + newEnum((GraphQLEnumType) context.thisNode(), schemaGraph, isIntrospectionNode); + } + if (context.thisNode() instanceof GraphQLDirective) { + // only continue if not applied directive + if (context.getParentNode() == null) { + newDirective((GraphQLDirective) context.thisNode(), schemaGraph); + } + } + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl leave(TraverserContext context) { + return TraversalControl.CONTINUE; + } + }); + addSchemaVertex(schemaGraph, schema); + + ArrayList copyOfVertices = new ArrayList<>(schemaGraph.getVertices()); + for (Vertex vertex : copyOfVertices) { + if (SchemaGraph.OBJECT.equals(vertex.getType())) { + handleObjectVertex(vertex, schemaGraph, schema); + } + if (SchemaGraph.INTERFACE.equals(vertex.getType())) { + handleInterfaceVertex(vertex, schemaGraph, schema); + } + if (SchemaGraph.UNION.equals(vertex.getType())) { + handleUnion(vertex, schemaGraph, schema); + } + if (SchemaGraph.INPUT_OBJECT.equals(vertex.getType())) { + handleInputObject(vertex, schemaGraph, schema); + } + if (SchemaGraph.DIRECTIVE.equals(vertex.getType())) { + handleDirective(vertex, schemaGraph, schema); + } + } + return schemaGraph; + } + + private void addSchemaVertex(SchemaGraph schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLObjectType queryType = graphQLSchema.getQueryType(); + GraphQLObjectType mutationType = graphQLSchema.getMutationType(); + GraphQLObjectType subscriptionType = graphQLSchema.getSubscriptionType(); + Vertex schemaVertex = new Vertex(SchemaGraph.SCHEMA, "schema"); + schemaVertex.add("name", SchemaGraph.SCHEMA); + schemaGraph.addVertex(schemaVertex); + + Vertex queryVertex = schemaGraph.getType(queryType.getName()); + schemaGraph.addEdge(new Edge(schemaVertex, queryVertex, "query")); + if (mutationType != null) { + Vertex mutationVertex = schemaGraph.getType(mutationType.getName()); + schemaGraph.addEdge(new Edge(schemaVertex, mutationVertex, "mutation")); + } + if (subscriptionType != null) { + Vertex subscriptionVertex = schemaGraph.getType(subscriptionType.getName()); + schemaGraph.addEdge(new Edge(schemaVertex, subscriptionVertex, "subscription")); + } + createAppliedDirectives(schemaVertex, graphQLSchema.getSchemaDirectives(), schemaGraph); + } + + private void handleInputObject(Vertex inputObject, SchemaGraph schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) graphQLSchema.getType(inputObject.get("name")); + List inputFields = inputObjectType.getFields(); + for (GraphQLInputObjectField inputField : inputFields) { + Vertex inputFieldVertex = schemaGraph.findTargetVertex(inputObject, vertex -> vertex.getType().equals("InputField") && + vertex.get("name").equals(inputField.getName())).get(); + handleInputField(inputFieldVertex, inputField, schemaGraph, graphQLSchema); + } + } + + private void handleInputField(Vertex inputFieldVertex, GraphQLInputObjectField inputField, SchemaGraph + schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLInputType type = inputField.getType(); + GraphQLUnmodifiedType graphQLUnmodifiedType = GraphQLTypeUtil.unwrapAll(type); + Vertex typeVertex = assertNotNull(schemaGraph.getType(graphQLUnmodifiedType.getName())); + Edge typeEdge = new Edge(inputFieldVertex, typeVertex); + String typeEdgeLabel = "type=" + GraphQLTypeUtil.simplePrint(type) + ";defaultValue="; + if (inputField.hasSetDefaultValue()) { + typeEdgeLabel += AstPrinter.printAst(ValuesResolver.valueToLiteral(inputField.getInputFieldDefaultValue(), inputField.getType(), GraphQLContext.getDefault(), Locale.getDefault())); + } + + typeEdge.setLabel(typeEdgeLabel); + schemaGraph.addEdge(typeEdge); + } + + private void handleUnion(Vertex unionVertex, SchemaGraph schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLUnionType unionType = (GraphQLUnionType) graphQLSchema.getType(unionVertex.get("name")); + List types = unionType.getTypes(); + for (GraphQLNamedOutputType unionMemberType : types) { + Vertex unionMemberVertex = assertNotNull(schemaGraph.getType(unionMemberType.getName())); + schemaGraph.addEdge(new Edge(unionVertex, unionMemberVertex)); + } + } + + private void handleInterfaceVertex(Vertex interfaceVertex, SchemaGraph schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLInterfaceType interfaceType = (GraphQLInterfaceType) graphQLSchema.getType(interfaceVertex.get("name")); + + for (GraphQLNamedOutputType implementsInterface : interfaceType.getInterfaces()) { + Vertex implementsInterfaceVertex = assertNotNull(schemaGraph.getType(implementsInterface.getName())); + schemaGraph.addEdge(new Edge(interfaceVertex, implementsInterfaceVertex, "implements " + implementsInterface.getName())); + } + + List fieldDefinitions = interfaceType.getFieldDefinitions(); + for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { + Vertex fieldVertex = schemaGraph.findTargetVertex(interfaceVertex, vertex -> vertex.getType().equals("Field") && + vertex.get("name").equals(fieldDefinition.getName())).get(); + handleField(fieldVertex, fieldDefinition, schemaGraph, graphQLSchema); + } + + } + + private void handleObjectVertex(Vertex objectVertex, SchemaGraph schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLObjectType objectType = graphQLSchema.getObjectType(objectVertex.get("name")); + + for (GraphQLNamedOutputType implementsInterface : objectType.getInterfaces()) { + Vertex implementsInterfaceVertex = assertNotNull(schemaGraph.getType(implementsInterface.getName())); + schemaGraph.addEdge(new Edge(objectVertex, implementsInterfaceVertex, "implements " + implementsInterface.getName())); + } + + List fieldDefinitions = objectType.getFieldDefinitions(); + for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { + Vertex fieldVertex = schemaGraph.findTargetVertex(objectVertex, vertex -> vertex.getType().equals("Field") && + vertex.get("name").equals(fieldDefinition.getName())).get(); + handleField(fieldVertex, fieldDefinition, schemaGraph, graphQLSchema); + } + } + + private void handleField(Vertex fieldVertex, GraphQLFieldDefinition fieldDefinition, SchemaGraph + schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLOutputType type = fieldDefinition.getType(); + GraphQLUnmodifiedType graphQLUnmodifiedType = GraphQLTypeUtil.unwrapAll(type); + Vertex typeVertex = assertNotNull(schemaGraph.getType(graphQLUnmodifiedType.getName())); + Edge typeEdge = new Edge(fieldVertex, typeVertex); + typeEdge.setLabel("type=" + GraphQLTypeUtil.simplePrint(type) + ";"); + schemaGraph.addEdge(typeEdge); + + for (GraphQLArgument graphQLArgument : fieldDefinition.getArguments()) { + Vertex argumentVertex = schemaGraph.findTargetVertex(fieldVertex, vertex -> vertex.getType().equals("Argument") && + vertex.get("name").equals(graphQLArgument.getName())).get(); + handleArgument(argumentVertex, graphQLArgument, schemaGraph); + } + } + + private void handleDirective(Vertex directive, SchemaGraph schemaGraph, GraphQLSchema graphQLSchema) { + GraphQLDirective graphQLDirective = graphQLSchema.getDirective(directive.getName()); + for (GraphQLArgument graphQLArgument : graphQLDirective.getArguments()) { + Vertex argumentVertex = schemaGraph.findTargetVertex(directive, vertex -> vertex.isOfType(SchemaGraph.ARGUMENT) && + vertex.getName().equals(graphQLArgument.getName())).get(); + handleArgument(argumentVertex, graphQLArgument, schemaGraph); + } + + } + + private void handleArgument(Vertex argumentVertex, GraphQLArgument graphQLArgument, SchemaGraph schemaGraph) { + GraphQLInputType type = graphQLArgument.getType(); + GraphQLUnmodifiedType graphQLUnmodifiedType = GraphQLTypeUtil.unwrapAll(type); + Vertex typeVertex = assertNotNull(schemaGraph.getType(graphQLUnmodifiedType.getName())); + Edge typeEdge = new Edge(argumentVertex, typeVertex); + String typeEdgeLabel = "type=" + GraphQLTypeUtil.simplePrint(type) + ";defaultValue="; + if (graphQLArgument.hasSetDefaultValue()) { + typeEdgeLabel += AstPrinter.printAst(ValuesResolver.valueToLiteral(graphQLArgument.getArgumentDefaultValue(), graphQLArgument.getType(), GraphQLContext.getDefault(), Locale.getDefault())); + } + typeEdge.setLabel(typeEdgeLabel); + schemaGraph.addEdge(typeEdge); + } + + private void newObject(GraphQLObjectType graphQLObjectType, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex objectVertex = new Vertex(SchemaGraph.OBJECT, debugPrefix + String.valueOf(counter++)); + objectVertex.setBuiltInType(isIntrospectionNode); + objectVertex.add("name", graphQLObjectType.getName()); + objectVertex.add("description", desc(graphQLObjectType.getDescription())); + for (GraphQLFieldDefinition fieldDefinition : graphQLObjectType.getFieldDefinitions()) { + Vertex newFieldVertex = newField(fieldDefinition, schemaGraph, isIntrospectionNode); + schemaGraph.addVertex(newFieldVertex); + schemaGraph.addEdge(new Edge(objectVertex, newFieldVertex)); + } + schemaGraph.addVertex(objectVertex); + schemaGraph.addType(graphQLObjectType.getName(), objectVertex); + createAppliedDirectives(objectVertex, graphQLObjectType.getDirectives(), schemaGraph); + } + + private Vertex newField(GraphQLFieldDefinition graphQLFieldDefinition, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex fieldVertex = new Vertex(SchemaGraph.FIELD, debugPrefix + String.valueOf(counter++)); + fieldVertex.setBuiltInType(isIntrospectionNode); + fieldVertex.add("name", graphQLFieldDefinition.getName()); + fieldVertex.add("description", desc(graphQLFieldDefinition.getDescription())); + for (GraphQLArgument argument : graphQLFieldDefinition.getArguments()) { + Vertex argumentVertex = newArgument(argument, schemaGraph, isIntrospectionNode); + schemaGraph.addVertex(argumentVertex); + schemaGraph.addEdge(new Edge(fieldVertex, argumentVertex)); + } + createAppliedDirectives(fieldVertex, graphQLFieldDefinition.getDirectives(), schemaGraph); + return fieldVertex; + } + + private Vertex newArgument(GraphQLArgument graphQLArgument, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex vertex = new Vertex(SchemaGraph.ARGUMENT, debugPrefix + String.valueOf(counter++)); + vertex.setBuiltInType(isIntrospectionNode); + vertex.add("name", graphQLArgument.getName()); + vertex.add("description", desc(graphQLArgument.getDescription())); + createAppliedDirectives(vertex, graphQLArgument.getDirectives(), schemaGraph); + return vertex; + } + + private void newScalar(GraphQLScalarType scalarType, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex scalarVertex = new Vertex(SchemaGraph.SCALAR, debugPrefix + String.valueOf(counter++)); + scalarVertex.setBuiltInType(isIntrospectionNode); + if (ScalarInfo.isGraphqlSpecifiedScalar(scalarType.getName())) { + scalarVertex.setBuiltInType(true); + } + scalarVertex.add("name", scalarType.getName()); + scalarVertex.add("description", desc(scalarType.getDescription())); + scalarVertex.add("specifiedByUrl", scalarType.getSpecifiedByUrl()); + schemaGraph.addVertex(scalarVertex); + schemaGraph.addType(scalarType.getName(), scalarVertex); + createAppliedDirectives(scalarVertex, scalarType.getDirectives(), schemaGraph); + } + + private void newInterface(GraphQLInterfaceType interfaceType, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex interfaceVertex = new Vertex(SchemaGraph.INTERFACE, debugPrefix + String.valueOf(counter++)); + interfaceVertex.setBuiltInType(isIntrospectionNode); + interfaceVertex.add("name", interfaceType.getName()); + interfaceVertex.add("description", desc(interfaceType.getDescription())); + for (GraphQLFieldDefinition fieldDefinition : interfaceType.getFieldDefinitions()) { + Vertex newFieldVertex = newField(fieldDefinition, schemaGraph, isIntrospectionNode); + schemaGraph.addVertex(newFieldVertex); + schemaGraph.addEdge(new Edge(interfaceVertex, newFieldVertex)); + } + schemaGraph.addVertex(interfaceVertex); + schemaGraph.addType(interfaceType.getName(), interfaceVertex); + createAppliedDirectives(interfaceVertex, interfaceType.getDirectives(), schemaGraph); + } + + private void newEnum(GraphQLEnumType enumType, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex enumVertex = new Vertex(SchemaGraph.ENUM, debugPrefix + String.valueOf(counter++)); + enumVertex.setBuiltInType(isIntrospectionNode); + enumVertex.add("name", enumType.getName()); + enumVertex.add("description", desc(enumType.getDescription())); + for (GraphQLEnumValueDefinition enumValue : enumType.getValues()) { + Vertex enumValueVertex = new Vertex(SchemaGraph.ENUM_VALUE, debugPrefix + String.valueOf(counter++)); + enumValueVertex.setBuiltInType(isIntrospectionNode); + enumValueVertex.add("name", enumValue.getName()); + schemaGraph.addVertex(enumValueVertex); + schemaGraph.addEdge(new Edge(enumVertex, enumValueVertex)); + createAppliedDirectives(enumValueVertex, enumValue.getDirectives(), schemaGraph); + } + schemaGraph.addVertex(enumVertex); + schemaGraph.addType(enumType.getName(), enumVertex); + createAppliedDirectives(enumVertex, enumType.getDirectives(), schemaGraph); + } + + private void newUnion(GraphQLUnionType unionType, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex unionVertex = new Vertex(SchemaGraph.UNION, debugPrefix + String.valueOf(counter++)); + unionVertex.setBuiltInType(isIntrospectionNode); + unionVertex.add("name", unionType.getName()); + unionVertex.add("description", desc(unionType.getDescription())); + schemaGraph.addVertex(unionVertex); + schemaGraph.addType(unionType.getName(), unionVertex); + createAppliedDirectives(unionVertex, unionType.getDirectives(), schemaGraph); + } + + private void newInputObject(GraphQLInputObjectType inputObject, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex inputObjectVertex = new Vertex(SchemaGraph.INPUT_OBJECT, debugPrefix + String.valueOf(counter++)); + inputObjectVertex.setBuiltInType(isIntrospectionNode); + inputObjectVertex.add("name", inputObject.getName()); + inputObjectVertex.add("description", desc(inputObject.getDescription())); + for (GraphQLInputObjectField inputObjectField : inputObject.getFieldDefinitions()) { + Vertex newInputField = newInputField(inputObjectField, schemaGraph, isIntrospectionNode); + Edge newEdge = new Edge(inputObjectVertex, newInputField); + schemaGraph.addEdge(newEdge); + } + schemaGraph.addVertex(inputObjectVertex); + schemaGraph.addType(inputObject.getName(), inputObjectVertex); + createAppliedDirectives(inputObjectVertex, inputObject.getDirectives(), schemaGraph); + } + + private void createAppliedDirectives(Vertex from, + List appliedDirectives, + SchemaGraph schemaGraph) { + Map countByName = new LinkedHashMap<>(); + for (GraphQLDirective appliedDirective : appliedDirectives) { + Vertex appliedDirectiveVertex = new Vertex(SchemaGraph.APPLIED_DIRECTIVE, debugPrefix + String.valueOf(counter++)); + appliedDirectiveVertex.add("name", appliedDirective.getName()); + for (GraphQLArgument appliedArgument : appliedDirective.getArguments()) { + if (appliedArgument.hasSetValue()) { + Vertex appliedArgumentVertex = new Vertex(SchemaGraph.APPLIED_ARGUMENT, debugPrefix + String.valueOf(counter++)); + appliedArgumentVertex.add("name", appliedArgument.getName()); + appliedArgumentVertex.add("value", AstPrinter.printAst(ValuesResolver.valueToLiteral(appliedArgument.getArgumentValue(), appliedArgument.getType(), GraphQLContext.getDefault(), Locale.getDefault()))); + schemaGraph.addVertex(appliedArgumentVertex); + schemaGraph.addEdge(new Edge(appliedDirectiveVertex, appliedArgumentVertex)); + } + } + schemaGraph.addVertex(appliedDirectiveVertex); + + // repeatable directives means we can have multiple directives with the same name + // the edge label indicates the applied directive index + Integer count = countByName.getOrDefault(appliedDirective.getName(), 0); + schemaGraph.addEdge(new Edge(from, appliedDirectiveVertex, String.valueOf(count))); + countByName.put(appliedDirective.getName(), count + 1); + } + } + + private void newDirective(GraphQLDirective directive, SchemaGraph schemaGraph) { + Vertex directiveVertex = new Vertex(SchemaGraph.DIRECTIVE, debugPrefix + String.valueOf(counter++)); + directiveVertex.add("name", directive.getName()); + directiveVertex.add("repeatable", directive.isRepeatable()); + directiveVertex.add("locations", directive.validLocations()); + boolean graphqlSpecified = DirectiveInfo.isGraphqlSpecifiedDirective(directive.getName()); + directiveVertex.setBuiltInType(graphqlSpecified); + directiveVertex.add("description", desc(directive.getDescription())); + for (GraphQLArgument argument : directive.getArguments()) { + Vertex argumentVertex = newArgument(argument, schemaGraph, graphqlSpecified); + schemaGraph.addVertex(argumentVertex); + schemaGraph.addEdge(new Edge(directiveVertex, argumentVertex)); + } + schemaGraph.addDirective(directive.getName(), directiveVertex); + schemaGraph.addVertex(directiveVertex); + } + + private Vertex newInputField(GraphQLInputObjectField inputField, SchemaGraph schemaGraph, boolean isIntrospectionNode) { + Vertex vertex = new Vertex(SchemaGraph.INPUT_FIELD, debugPrefix + String.valueOf(counter++)); + schemaGraph.addVertex(vertex); + vertex.setBuiltInType(isIntrospectionNode); + vertex.add("name", inputField.getName()); + vertex.add("description", desc(inputField.getDescription())); + createAppliedDirectives(vertex, inputField.getDirectives(), schemaGraph); + return vertex; + } + + private String desc(String desc) { + return desc; +// return desc != null ? desc.replace("\n", "\\n") : null; + } + +} diff --git a/src/main/java/graphql/schema/diffing/SortSourceGraph.java b/src/main/java/graphql/schema/diffing/SortSourceGraph.java new file mode 100644 index 0000000000..6b96ccfae3 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/SortSourceGraph.java @@ -0,0 +1,141 @@ +//package graphql.schema.diffing; +// +//import graphql.Internal; +// +//import java.util.ArrayList; +//import java.util.Comparator; +//import java.util.LinkedHashMap; +//import java.util.List; +//import java.util.Map; +//import java.util.concurrent.atomic.AtomicInteger; +// +//@Internal +//public class SortSourceGraph { +// +// public static void sortSourceGraph(SchemaGraph sourceGraph, SchemaGraph targetGraph, PossibleMappingsCalculator.PossibleMappings possibleMappings) { +//// // we sort descending by number of possible target vertices +//// Collections.sort(sourceGraph.getVertices(), (v1, v2) -> +//// +//// { +//// +//// int v2Count = v2.isBuiltInType() ? -1 : (v2.isIsolated() ? 0 : isolatedVertices.possibleMappings.get(v2).size()); +//// int v1Count = v1.isBuiltInType() ? -1 : (v1.isIsolated() ? 0 : isolatedVertices.possibleMappings.get(v1).size()); +//// return Integer.compare(v2Count, v1Count); +//// }); +//// +//// for (Vertex vertex : sourceGraph.getVertices()) { +//// System.out.println("c: " + isolatedVertices.possibleMappings.get(vertex).size() + " v: " + vertex); +//// } +// +//// +//// +//// // how often does each source edge (based on the label) appear in target graph +// Map targetLabelCount = new LinkedHashMap<>(); +// for (Edge targetEdge : targetGraph.getEdges()) { +// targetLabelCount.computeIfAbsent(targetEdge.getLabel(), __ -> new AtomicInteger()).incrementAndGet(); +// } +// // how often does each source vertex (based on the data) appear in the target graph +// Map targetVertexDataCount = new LinkedHashMap<>(); +// for (Vertex targetVertex : targetGraph.getVertices()) { +// targetVertexDataCount.computeIfAbsent(targetVertex.toData(), __ -> new AtomicInteger()).incrementAndGet(); +// } +// +// // an infrequency weight is 1 - count in target. Meaning the higher the +// // value, the smaller the count, the less frequent it. +// // Higher Infrequency => more unique is the vertex/label +// Map vertexInfrequencyWeights = new LinkedHashMap<>(); +// Map edgesInfrequencyWeights = new LinkedHashMap<>(); +// for (Vertex vertex : sourceGraph.getVertices()) { +// vertexInfrequencyWeights.put(vertex, 1 - targetVertexDataCount.getOrDefault(vertex.toData(), new AtomicInteger()).get()); +// } +// for (Edge edge : sourceGraph.getEdges()) { +// edgesInfrequencyWeights.put(edge, 1 - targetLabelCount.getOrDefault(edge.getLabel(), new AtomicInteger()).get()); +// } +// +// /** +// * vertices are sorted by increasing frequency/decreasing infrequency/decreasing uniqueness +// * we start with the most unique/least frequent/most infrequent and add incrementally the next most infrequent. +// */ +// +// //TODO: improve this: this is doing to much: we just want the max infrequent vertex, not all sorted +// ArrayList nextCandidates = new ArrayList<>(sourceGraph.getVertices()); +// nextCandidates.sort(Comparator.comparingInt(o -> totalInfrequencyWeightWithAdjacentEdges(sourceGraph, o, vertexInfrequencyWeights, edgesInfrequencyWeights))); +// +// Vertex curVertex = nextCandidates.get(nextCandidates.size() - 1); +// nextCandidates.remove(nextCandidates.size() - 1); +// +// List result = new ArrayList<>(); +// result.add(curVertex); +// while (nextCandidates.size() > 0) { Vertex nextOne = null; +// int curMaxWeight = Integer.MIN_VALUE; +// int index = 0; +// int nextOneIndex = -1; +// +// // which ones of the candidates has the highest infrequency weight relatively to the current result set of vertices +// for (Vertex candidate : nextCandidates) { +// List allAdjacentEdges = sourceGraph.getAllAdjacentEdges(result, candidate); +// int totalWeight = totalInfrequencyWeightWithSomeEdges(candidate, allAdjacentEdges, vertexInfrequencyWeights, edgesInfrequencyWeights); +// if (totalWeight > curMaxWeight) { +// nextOne = candidate; +// nextOneIndex = index; +// curMaxWeight = totalWeight; +// } +// index++; +// } +// result.add(nextOne); +// nextCandidates.remove(nextOneIndex); +// } +// sourceGraph.setVertices(result); +// } +// +// +// private static int totalInfrequencyWeightWithSomeEdges(Vertex vertex, +// List edges, +// Map vertexInfrequencyWeights, +// Map edgesInfrequencyWeights) { +// if (vertex.isBuiltInType()) { +// return Integer.MIN_VALUE + 1; +// } +// if (vertex.isIsolated()) { +// return Integer.MIN_VALUE + 2; +// } +// return vertexInfrequencyWeights.get(vertex) + edges.stream().mapToInt(edgesInfrequencyWeights::get).sum(); +// } +// +// private static int totalInfrequencyWeightWithAdjacentEdges(SchemaGraph sourceGraph, +// Vertex vertex, +// Map vertexInfrequencyWeights, +// Map edgesInfrequencyWeights) { +// if (vertex.isBuiltInType()) { +// return Integer.MIN_VALUE + 1; +// } +// if (vertex.isIsolated()) { +// return Integer.MIN_VALUE + 2; +// } +// List adjacentEdges = sourceGraph.getAdjacentEdges(vertex); +// return vertexInfrequencyWeights.get(vertex) + adjacentEdges.stream().mapToInt(edgesInfrequencyWeights::get).sum(); +// } +// +// private int infrequencyWeightForVertex(Vertex sourceVertex, SchemaGraph targetGraph) { +// int count = 0; +// for (Vertex targetVertex : targetGraph.getVertices()) { +// if (sourceVertex.isEqualTo(targetVertex)) { +// count++; +// } +// } +// return 1 - count; +// } +// +// private int infrequencyWeightForEdge(Edge sourceEdge, SchemaGraph targetGraph) { +// int count = 0; +// for (Edge targetEdge : targetGraph.getEdges()) { +// if (sourceEdge.isEqualTo(targetEdge)) { +// count++; +// } +// } +// return 1 - count; +// } +// +// +// +//} diff --git a/src/main/java/graphql/schema/diffing/Util.java b/src/main/java/graphql/schema/diffing/Util.java new file mode 100644 index 0000000000..38bd0878c1 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/Util.java @@ -0,0 +1,30 @@ +package graphql.schema.diffing; + +import graphql.Internal; + +import java.util.List; +import java.util.Set; + +@Internal +public class Util { + public static void diffNamedList(Set sourceNames, + Set targetNames, + List deleted, + List inserted, + List same) { + for (String sourceName : sourceNames) { + if (targetNames.contains(sourceName)) { + same.add(sourceName); + } else { + deleted.add(sourceName); + } + } + + for (String targetName : targetNames) { + if (!sourceNames.contains(targetName)) { + inserted.add(targetName); + } + } + } + +} diff --git a/src/main/java/graphql/schema/diffing/Vertex.java b/src/main/java/graphql/schema/diffing/Vertex.java new file mode 100644 index 0000000000..4b408a37c1 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/Vertex.java @@ -0,0 +1,135 @@ +package graphql.schema.diffing; + +import graphql.Assert; +import graphql.Internal; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +@Internal +public class Vertex { + + private String type; + private Map properties = new LinkedHashMap<>(); + private String debugName; + private boolean isolated; + + + private boolean builtInType; + + public static Vertex newIsolatedNode(String debugName) { + Vertex vertex = new Vertex(SchemaGraph.ISOLATED, debugName); + vertex.isolated = true; + return vertex; + } + + public static Set newIsolatedNodes(int count, String debugName) { + Set result = new LinkedHashSet<>(); + for (int i = 1; i <= count; i++) { + Vertex vertex = new Vertex(SchemaGraph.ISOLATED, debugName + i); + vertex.isolated = true; + result.add(vertex); + } + return result; + } + + public Vertex(String type, String debugName) { + this.type = type; + this.debugName = debugName; + } + + public boolean isIsolated() { + return isolated; + } + + public void add(String propName, Object propValue) { + properties.put(propName, propValue); + } + + public String getType() { + return type; + } + + public T get(String propName) { + return (T) properties.get(propName); + } + + public T getProperty(String name) { + return (T) properties.get(name); + } + + public String getName() { + return (String) Assert.assertNotNull(properties.get("name"), "should not call getName on %s", this); + } + + public Map getProperties() { + return properties; + } + + public String getDebugName() { + return debugName; + } + + public boolean isOfType(String type) { + return this.type.equals(type); + } + + public boolean isEqualTo(Vertex other) { + return other != null && + Objects.equals(this.type, other.type) && + Objects.equals(this.properties, other.properties); + } + + public boolean isBuiltInType() { + return builtInType; + } + + public void setBuiltInType(boolean builtInType) { + this.builtInType = builtInType; + } + + @Override + public String toString() { + return "Vertex{" + + "type='" + type + '\'' + + ", properties=" + properties.toString().replace("\n", "") + + ", debugName='" + debugName + '\'' + + ", builtInType='" + builtInType + '\'' + + '}'; + } + + public VertexData toData() { + return new VertexData(this.type, this.properties); + } + + public static class VertexData { + private final String type; + private final Map properties; + + public VertexData(String type, Map properties) { + this.type = type; + this.properties = properties; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + VertexData that = (VertexData) o; + return Objects.equals(type, that.type) && Objects.equals(properties, that.properties); + } + + @Override + public int hashCode() { + return Objects.hash(type, properties); + } + } + +} diff --git a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalysisResult.java b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalysisResult.java new file mode 100644 index 0000000000..d2eca0f7a4 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalysisResult.java @@ -0,0 +1,61 @@ +package graphql.schema.diffing.ana; + +import graphql.Internal; + +import java.util.Map; + +@Internal +public class EditOperationAnalysisResult { + private final Map objectDifferences; + private final Map interfaceDifferences; + private final Map unionDifferences; + private final Map enumDifferences; + private final Map inputObjectDifferences; + private final Map scalarDifferences; + + private final Map directiveDifferences; + + public EditOperationAnalysisResult(Map objectChanges, + Map interfaceDifferences, + Map unionDifferences, + Map enumDifferences, + Map inputObjectDifferences, + Map scalarDifferences, + Map directiveDifferences) { + this.objectDifferences = objectChanges; + this.interfaceDifferences = interfaceDifferences; + this.unionDifferences = unionDifferences; + this.enumDifferences = enumDifferences; + this.inputObjectDifferences = inputObjectDifferences; + this.scalarDifferences = scalarDifferences; + this.directiveDifferences = directiveDifferences; + } + + public Map getObjectDifferences() { + return objectDifferences; + } + + public Map getInterfaceDifferences() { + return interfaceDifferences; + } + + public Map getUnionDifferences() { + return unionDifferences; + } + + public Map getEnumDifferences() { + return enumDifferences; + } + + public Map getInputObjectDifferences() { + return inputObjectDifferences; + } + + public Map getScalarDifferences() { + return scalarDifferences; + } + + public Map getDirectiveDifferences() { + return directiveDifferences; + } +} diff --git a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java new file mode 100644 index 0000000000..d1da9830d1 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java @@ -0,0 +1,2716 @@ +package graphql.schema.diffing.ana; + +import graphql.Assert; +import graphql.Internal; +import graphql.VisibleForTesting; +import graphql.schema.GraphQLSchema; +import graphql.schema.diffing.Edge; +import graphql.schema.diffing.EditOperation; +import graphql.schema.diffing.Mapping; +import graphql.schema.diffing.SchemaGraph; +import graphql.schema.diffing.Vertex; +import graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentAddition; +import graphql.schema.idl.ScalarInfo; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.Assert.assertTrue; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveAddition; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentRename; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentValueModification; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDirectiveArgumentLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveEnumLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveEnumValueLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInputObjectFieldLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInputObjectLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceFieldArgumentLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceFieldLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldArgumentLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveScalarLocation; +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveUnionLocation; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveAddition; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentAddition; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentDefaultValueModification; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentRename; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentTypeModification; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveDifference; +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveModification; +import static graphql.schema.diffing.ana.SchemaDifference.EnumAddition; +import static graphql.schema.diffing.ana.SchemaDifference.EnumDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.EnumDifference; +import static graphql.schema.diffing.ana.SchemaDifference.EnumModification; +import static graphql.schema.diffing.ana.SchemaDifference.EnumValueAddition; +import static graphql.schema.diffing.ana.SchemaDifference.EnumValueDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.EnumValueRenamed; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectAddition; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectDifference; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldAddition; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldDefaultValueModification; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldRename; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldTypeModification; +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectModification; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceAddition; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceDifference; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldAddition; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentAddition; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentDefaultValueModification; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentRename; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentTypeModification; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldRename; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldTypeModification; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceInterfaceImplementationAddition; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceInterfaceImplementationDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceModification; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectAddition; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectDifference; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldAddition; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentAddition; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentDefaultValueModification; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentRename; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentTypeModification; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldRename; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldTypeModification; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectInterfaceImplementationAddition; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectInterfaceImplementationDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.ObjectModification; +import static graphql.schema.diffing.ana.SchemaDifference.ScalarAddition; +import static graphql.schema.diffing.ana.SchemaDifference.ScalarDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.ScalarDifference; +import static graphql.schema.diffing.ana.SchemaDifference.ScalarModification; +import static graphql.schema.diffing.ana.SchemaDifference.UnionAddition; +import static graphql.schema.diffing.ana.SchemaDifference.UnionDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.UnionDifference; +import static graphql.schema.diffing.ana.SchemaDifference.UnionMemberAddition; +import static graphql.schema.diffing.ana.SchemaDifference.UnionMemberDeletion; +import static graphql.schema.diffing.ana.SchemaDifference.UnionModification; + +/** + * Higher level GraphQL semantic assigned to + */ +@Internal +public class EditOperationAnalyzer { + + private final GraphQLSchema oldSchema; + private final GraphQLSchema newSchema; + private final SchemaGraph oldSchemaGraph; + private final SchemaGraph newSchemaGraph; + + private final Map objectDifferences = new LinkedHashMap<>(); + private final Map interfaceDifferences = new LinkedHashMap<>(); + private final Map unionDifferences = new LinkedHashMap<>(); + private final Map enumDifferences = new LinkedHashMap<>(); + private final Map inputObjectDifferences = new LinkedHashMap<>(); + private final Map scalarDifferences = new LinkedHashMap<>(); + + private final Map directiveDifferences = new LinkedHashMap<>(); + + public EditOperationAnalyzer(GraphQLSchema oldSchema, + GraphQLSchema newSchema, + SchemaGraph oldSchemaGraph, + SchemaGraph newSchemaGraph + ) { + this.oldSchema = oldSchema; + this.newSchema = newSchema; + this.oldSchemaGraph = oldSchemaGraph; + this.newSchemaGraph = newSchemaGraph; + } + + public EditOperationAnalysisResult analyzeEdits(List editOperations, Mapping mapping) { + editOperations = getTraversalOrder(editOperations); + + handleTypeVertexChanges(editOperations); + + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case CHANGE_VERTEX: + if (editOperation.getTargetVertex().isOfType(SchemaGraph.FIELD)) { + fieldChanged(editOperation); + } else if (editOperation.getTargetVertex().isOfType(SchemaGraph.ARGUMENT)) { + handleArgumentChange(editOperation, mapping); + } else if (editOperation.getTargetVertex().isOfType(SchemaGraph.INPUT_FIELD)) { + handleInputFieldChange(editOperation); + } + break; + case INSERT_VERTEX: + if (editOperation.getTargetVertex().isOfType(SchemaGraph.FIELD)) { + fieldAdded(editOperation); + } else if (editOperation.getTargetVertex().isOfType(SchemaGraph.ARGUMENT)) { + argumentAdded(editOperation); + } else if (editOperation.getTargetVertex().isOfType(SchemaGraph.INPUT_FIELD)) { + inputFieldAdded(editOperation); + } + break; + case DELETE_VERTEX: + if (editOperation.getSourceVertex().isOfType(SchemaGraph.ARGUMENT)) { + argumentDeleted(editOperation); + } else if (editOperation.getSourceVertex().isOfType(SchemaGraph.FIELD)) { + fieldDeleted(editOperation); + } else if (editOperation.getSourceVertex().isOfType(SchemaGraph.INPUT_FIELD)) { + inputFieldDeleted(editOperation); + } + } + } + + handleTypeChanges(editOperations, mapping); + handleImplementsChanges(editOperations, mapping); + handleUnionMemberChanges(editOperations, mapping); + handleEnumValuesChanges(editOperations, mapping); + handleAppliedDirectives(editOperations, mapping); + handleArgumentChanges(editOperations, mapping); + + return new EditOperationAnalysisResult( + objectDifferences, + interfaceDifferences, + unionDifferences, + enumDifferences, + inputObjectDifferences, + scalarDifferences, + directiveDifferences); + } + + private void handleArgumentChanges(List editOperations, Mapping mapping) { + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_EDGE: + if (editOperation.getTargetEdge().getTo().isOfType(SchemaGraph.ARGUMENT)) { + argumentAdded(editOperation); + } + break; + case DELETE_EDGE: + if (editOperation.getSourceEdge().getTo().isOfType(SchemaGraph.ARGUMENT)) { + argumentDeleted(editOperation); + } + break; + } + } + } + + + private void handleAppliedDirectives(List editOperations, Mapping mapping) { + + // first the applied directives itself and then all the applied arguments changes + // for the applied directives, so that we check for example if the applied directive is + // deleted before we check for the applied directive argument changes + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_VERTEX: + if (editOperation.getTargetVertex().isOfType(SchemaGraph.APPLIED_DIRECTIVE)) { + appliedDirectiveAdded(editOperation); + } + break; + case CHANGE_VERTEX: + // TODO: handle applied directive changes + break; + case DELETE_VERTEX: + if (editOperation.getSourceVertex().isOfType(SchemaGraph.APPLIED_DIRECTIVE)) { + appliedDirectiveDeleted(editOperation); + } + break; + + } + } + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_VERTEX: + if (editOperation.getTargetVertex().isOfType(SchemaGraph.APPLIED_ARGUMENT)) { + appliedDirectiveArgumentAdded(editOperation); + } + break; + case CHANGE_VERTEX: + if (editOperation.getTargetVertex().isOfType(SchemaGraph.APPLIED_ARGUMENT)) { + appliedDirectiveArgumentChanged(editOperation); + } + break; + case DELETE_VERTEX: + if (editOperation.getSourceVertex().isOfType(SchemaGraph.APPLIED_ARGUMENT)) { + appliedDirectiveArgumentDeleted(editOperation); + } + break; + + } + } + + } + + private void appliedDirectiveDeleted(EditOperation editOperation) { + Vertex appliedDirective = editOperation.getSourceVertex(); + Vertex container = oldSchemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + if (container.isOfType(SchemaGraph.FIELD)) { + appliedDirectiveDeletedFromField(appliedDirective, container); + } else if (container.isOfType(SchemaGraph.ARGUMENT)) { + appliedDirectiveDeletedFromArgument(appliedDirective, container); + } else if (container.isOfType(SchemaGraph.OBJECT)) { + Vertex object = container; + if (isObjectDeleted(object.getName())) { + return; + } + AppliedDirectiveObjectLocation location = new AppliedDirectiveObjectLocation(object.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = container; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + AppliedDirectiveInterfaceLocation location = new AppliedDirectiveInterfaceLocation(interfaze.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.SCALAR)) { + Vertex scalar = container; + if (isScalarDeleted(scalar.getName())) { + return; + } + AppliedDirectiveScalarLocation location = new AppliedDirectiveScalarLocation(scalar.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getScalarModification(scalar.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.ENUM)) { + Vertex enumVertex = container; + if (isEnumDeleted(enumVertex.getName())) { + return; + } + AppliedDirectiveEnumLocation location = new AppliedDirectiveEnumLocation(enumVertex.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.ENUM_VALUE)) { + Vertex enumValue = container; + Vertex enumVertex = oldSchemaGraph.getEnumForEnumValue(enumValue); + if (isEnumDeleted(enumVertex.getName())) { + return; + } + if (isEnumValueDeletedFromExistingEnum(enumVertex.getName(), enumValue.getName())) { + return; + } + AppliedDirectiveEnumValueLocation location = new AppliedDirectiveEnumValueLocation(enumVertex.getName(), enumValue.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.INPUT_OBJECT)) { + Vertex inputObject = container; + if (isInputObjectDeleted(inputObject.getName())) { + return; + } + AppliedDirectiveInputObjectLocation location = new AppliedDirectiveInputObjectLocation(inputObject.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.INPUT_FIELD)) { + Vertex inputField = container; + Vertex inputObject = oldSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectDeleted(inputObject.getName())) { + return; + } + if (isInputFieldDeletedFromExistingInputObject(inputObject.getName(), inputField.getName())) { + return; + } + AppliedDirectiveInputObjectFieldLocation location = new AppliedDirectiveInputObjectFieldLocation(inputObject.getName(), inputField.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(appliedDirectiveDeletion); + } else if (container.isOfType(SchemaGraph.UNION)) { + Vertex union = container; + if (isUnionDeleted(union.getName())) { + return; + } + AppliedDirectiveUnionLocation location = new AppliedDirectiveUnionLocation(union.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getUnionModification(union.getName()).getDetails().add(appliedDirectiveDeletion); + } + } + + private void appliedDirectiveArgumentDeleted(EditOperation editOperation) { + Vertex deletedArgument = editOperation.getSourceVertex(); + Vertex appliedDirective = oldSchemaGraph.getAppliedDirectiveForAppliedArgument(deletedArgument); + Vertex container = oldSchemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + + if (container.isOfType(SchemaGraph.ARGUMENT)) { + Vertex argument = container; + Vertex fieldOrDirective = oldSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex fieldsContainer = oldSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainer.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainer; + if (isObjectDeleted(object.getName())) { + return; + } + if (isFieldDeletedFromExistingObject(object.getName(), field.getName())) { + return; + } + if (isArgumentDeletedFromExistingObjectField(object.getName(), field.getName(), argument.getName())) { + return; + } + if (isAppliedDirectiveDeleted(object, appliedDirective.getName())) { + return; + } + AppliedDirectiveObjectFieldArgumentLocation location = new AppliedDirectiveObjectFieldArgumentLocation(object.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (fieldsContainer.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = fieldsContainer; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isArgumentDeletedFromExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) { + return; + } + if (isAppliedDirectiveDeleted(interfaze, appliedDirective.getName())) { + return; + } + AppliedDirectiveInterfaceFieldArgumentLocation location = new AppliedDirectiveInterfaceFieldArgumentLocation(interfaze.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } + } else if (fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)) { + Vertex directive = fieldOrDirective; + if (isDirectiveDeleted(directive.getName())) { + return; + } + if (isArgumentDeletedFromExistingDirective(directive.getName(), argument.getName())) { + return; + } + if (isAppliedDirectiveDeleted(fieldOrDirective, appliedDirective.getName())) { + return; + } + AppliedDirectiveDirectiveArgumentLocation location = new AppliedDirectiveDirectiveArgumentLocation(directive.getName(), argument.getName(), appliedDirective.getName()); + getDirectiveModification(directive.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } + } else if (container.isOfType(SchemaGraph.FIELD)) { + Vertex field = container; + Vertex interfaceOrObjective = oldSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + if (isObjectDeleted(object.getName())) { + return; + } + if (isFieldDeletedFromExistingObject(object.getName(), field.getName())) { + return; + } + if (isAppliedDirectiveDeleted(object, appliedDirective.getName())) { + return; + } + + AppliedDirectiveObjectFieldLocation location = new AppliedDirectiveObjectFieldLocation(object.getName(), field.getName(), appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else { + assertTrue(interfaceOrObjective.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = interfaceOrObjective; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + if (isFieldDeletedFromExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isAppliedDirectiveDeleted(interfaze, appliedDirective.getName())) { + return; + } + + AppliedDirectiveInterfaceFieldLocation location = new AppliedDirectiveInterfaceFieldLocation(interfaze.getName(), field.getName(), appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } + } else if (container.isOfType(SchemaGraph.SCALAR)) { + Vertex scalar = container; + if (isScalarDeleted(scalar.getName())) { + return; + } + if (isAppliedDirectiveDeleted(scalar, appliedDirective.getName())) { + return; + } + + AppliedDirectiveScalarLocation location = new AppliedDirectiveScalarLocation(scalar.getName(), appliedDirective.getName()); + getScalarModification(scalar.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.ENUM)) { + Vertex enumVertex = container; + if (isEnumDeleted(enumVertex.getName())) { + return; + } + if (isAppliedDirectiveDeleted(enumVertex, appliedDirective.getName())) { + return; + } + AppliedDirectiveEnumLocation location = new AppliedDirectiveEnumLocation(enumVertex.getName(), appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.ENUM_VALUE)) { + Vertex enumValue = container; + Vertex enumVertex = oldSchemaGraph.getEnumForEnumValue(enumValue); + if (isEnumDeleted(enumVertex.getName())) { + return; + } + if (isNewEnumValueForExistingEnum(enumVertex.getName(), enumValue.getName())) { + return; + } + AppliedDirectiveEnumValueLocation location = new AppliedDirectiveEnumValueLocation(enumVertex.getName(), enumValue.getName(), appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.UNION)) { + Vertex union = container; + if (isUnionDeleted(union.getName())) { + return; + } + if (isAppliedDirectiveDeleted(union, appliedDirective.getName())) { + return; + } + + AppliedDirectiveUnionLocation location = new AppliedDirectiveUnionLocation(union.getName(), appliedDirective.getName()); + getUnionModification(union.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.OBJECT)) { + Vertex object = container; + if (isObjectDeleted(object.getName())) { + return; + } + if (isAppliedDirectiveDeleted(object, appliedDirective.getName())) { + return; + } + + AppliedDirectiveObjectLocation location = new AppliedDirectiveObjectLocation(object.getName(), appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = container; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + if (isAppliedDirectiveDeleted(interfaze, appliedDirective.getName())) { + return; + } + + AppliedDirectiveInterfaceLocation location = new AppliedDirectiveInterfaceLocation(interfaze.getName(), appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.INPUT_OBJECT)) { + Vertex inputObject = container; + if (isInputObjectDeleted(inputObject.getName())) { + return; + } + if (isAppliedDirectiveDeleted(inputObject, appliedDirective.getName())) { + return; + } + AppliedDirectiveInputObjectLocation location = new AppliedDirectiveInputObjectLocation(inputObject.getName(), appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else if (container.isOfType(SchemaGraph.INPUT_FIELD)) { + Vertex inputField = container; + Vertex inputObject = oldSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectDeleted(inputObject.getName())) { + return; + } + if (isNewInputFieldExistingInputObject(inputObject.getName(), inputField.getName())) { + return; + } + if (isAppliedDirectiveDeleted(inputField, appliedDirective.getName())) { + return; + } + AppliedDirectiveInputObjectFieldLocation location = new AppliedDirectiveInputObjectFieldLocation(inputObject.getName(), inputField.getName(), appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(new AppliedDirectiveArgumentDeletion(location, deletedArgument.getName())); + } else { + assertShouldNeverHappen("Unexpected container " + container); + } + } + + private void appliedDirectiveArgumentAdded(EditOperation editOperation) { + Vertex addedArgument = editOperation.getTargetVertex(); + Vertex appliedDirective = newSchemaGraph.getAppliedDirectiveForAppliedArgument(addedArgument); + Vertex container = newSchemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + + if (container.isOfType(SchemaGraph.ARGUMENT)) { + Vertex argument = container; + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex fieldsContainer = newSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainer.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainer; + if (isObjectAdded(object.getName())) { + return; + } + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + if (isArgumentNewForExistingObjectField(object.getName(), field.getName(), argument.getName())) { + return; + } + if (isAppliedDirectiveAdded(object, appliedDirective.getName())) { + return; + } + AppliedDirectiveObjectFieldArgumentLocation location = new AppliedDirectiveObjectFieldArgumentLocation(object.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (fieldsContainer.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = fieldsContainer; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isArgumentNewForExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) { + return; + } + + if (isAppliedDirectiveAdded(interfaze, appliedDirective.getName())) { + return; + } + AppliedDirectiveInterfaceFieldArgumentLocation location = new AppliedDirectiveInterfaceFieldArgumentLocation(interfaze.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } + } else if (fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)) { + Vertex directive = fieldOrDirective; + if (isAppliedDirectiveAdded(directive, appliedDirective.getName())) { + return; + } + AppliedDirectiveDirectiveArgumentLocation location = new AppliedDirectiveDirectiveArgumentLocation(directive.getName(), argument.getName(), appliedDirective.getName()); + getDirectiveModification(directive.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } + } else if (container.isOfType(SchemaGraph.FIELD)) { + Vertex field = container; + Vertex interfaceOrObjective = newSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + if (isObjectAdded(object.getName())) { + return; + } + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + + AppliedDirectiveObjectFieldLocation location = new AppliedDirectiveObjectFieldLocation(object.getName(), field.getName(), appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (interfaceOrObjective.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = interfaceOrObjective; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + + AppliedDirectiveInterfaceFieldLocation location = new AppliedDirectiveInterfaceFieldLocation(interfaze.getName(), field.getName(), appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else { + assertShouldNeverHappen("Unexpected field container " + interfaceOrObjective); + } + } else if (container.isOfType(SchemaGraph.SCALAR)) { + Vertex scalar = container; + if (isScalarAdded(scalar.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveScalarLocation location = new AppliedDirectiveScalarLocation(scalar.getName(), appliedDirective.getName()); + getScalarModification(scalar.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.ENUM)) { + Vertex enumVertex = container; + if (isEnumAdded(enumVertex.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveEnumLocation location = new AppliedDirectiveEnumLocation(enumVertex.getName(), appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.ENUM_VALUE)) { + Vertex enumValue = container; + Vertex enumVertex = newSchemaGraph.getEnumForEnumValue(enumValue); + if (isEnumAdded(enumVertex.getName())) { + return; + } + if (isNewEnumValueForExistingEnum(enumVertex.getName(), enumValue.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveEnumValueLocation location = new AppliedDirectiveEnumValueLocation(enumVertex.getName(), enumValue.getName(), appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.UNION)) { + Vertex union = container; + if (isUnionAdded(union.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveUnionLocation location = new AppliedDirectiveUnionLocation(union.getName(), appliedDirective.getName()); + getUnionModification(union.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = container; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveInterfaceLocation location = new AppliedDirectiveInterfaceLocation(interfaze.getName(), appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.OBJECT)) { + Vertex interfaze = container; + if (isObjectAdded(interfaze.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveObjectLocation location = new AppliedDirectiveObjectLocation(interfaze.getName(), appliedDirective.getName()); + getObjectModification(interfaze.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.INPUT_OBJECT)) { + Vertex inputObject = container; + if (isInputObjectAdded(inputObject.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveInputObjectLocation location = new AppliedDirectiveInputObjectLocation(inputObject.getName(), appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else if (container.isOfType(SchemaGraph.INPUT_FIELD)) { + Vertex inputField = container; + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectAdded(inputObject.getName())) { + return; + } + if (isNewInputFieldExistingInputObject(inputObject.getName(), inputField.getName())) { + return; + } + if (isAppliedDirectiveAdded(container, appliedDirective.getName())) { + return; + } + AppliedDirectiveInputObjectFieldLocation location = new AppliedDirectiveInputObjectFieldLocation(inputObject.getName(), inputField.getName(), appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(new AppliedDirectiveArgumentAddition(location, addedArgument.getName())); + } else { + assertShouldNeverHappen("Unexpected applied argument container " + container); + } + } + + + private void appliedDirectiveArgumentChanged(EditOperation editOperation) { + Vertex appliedArgument = editOperation.getTargetVertex(); + String oldArgumentName = editOperation.getSourceVertex().getName(); + String newArgumentName = editOperation.getTargetVertex().getName(); + boolean nameChanged = !oldArgumentName.equals(newArgumentName); + + String oldValue = editOperation.getSourceVertex().get("value"); + String newValue = editOperation.getTargetVertex().get("value"); + boolean valueChanged = !oldValue.equals(newValue); + + + Vertex appliedDirective = newSchemaGraph.getAppliedDirectiveForAppliedArgument(appliedArgument); + Vertex container = newSchemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + if (container.isOfType(SchemaGraph.FIELD)) { + Vertex field = container; + Vertex interfaceOrObjective = newSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + AppliedDirectiveObjectFieldLocation location = new AppliedDirectiveObjectFieldLocation(object.getName(), field.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getObjectModification(object.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + AppliedDirectiveArgumentRename argumentRename = new AppliedDirectiveArgumentRename(location, oldArgumentName, newArgumentName); + getObjectModification(object.getName()).getDetails().add(argumentRename); + } + } else if (interfaceOrObjective.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = interfaceOrObjective; + AppliedDirectiveInterfaceFieldLocation location = new AppliedDirectiveInterfaceFieldLocation(interfaze.getName(), field.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getInterfaceModification(interfaze.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + } + } else if (container.isOfType(SchemaGraph.ARGUMENT)) { + Vertex argument = container; + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex fieldsContainer = newSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainer.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainer; + AppliedDirectiveObjectFieldArgumentLocation location = new AppliedDirectiveObjectFieldArgumentLocation(object.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getObjectModification(object.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + } else if (fieldsContainer.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = fieldsContainer; + AppliedDirectiveInterfaceFieldArgumentLocation location = new AppliedDirectiveInterfaceFieldArgumentLocation(interfaze.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getInterfaceModification(interfaze.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + } + } else if (fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)) { + Vertex directive = fieldOrDirective; + AppliedDirectiveDirectiveArgumentLocation location = new AppliedDirectiveDirectiveArgumentLocation(directive.getName(), argument.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getDirectiveModification(directive.getName()).getDetails().add(argumentValueModification); + } + + } + } else if (container.isOfType(SchemaGraph.INPUT_FIELD)) { + Vertex inputField = container; + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + AppliedDirectiveInputObjectFieldLocation location = new AppliedDirectiveInputObjectFieldLocation(inputObject.getName(), inputField.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getInputObjectModification(inputObject.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { +// AppliedDirectiveArgumentRename argumentRename = new AppliedDirectiveArgumentRename(location, oldArgumentName, newArgumentName); +// getInputObjectModification(inputObject.getName()).getDetails().add(argumentRename); + } + } else if (container.isOfType(SchemaGraph.OBJECT)) { + Vertex object = container; + AppliedDirectiveObjectLocation location = new AppliedDirectiveObjectLocation(object.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getObjectModification(object.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + } + } else if (container.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = container; + AppliedDirectiveInterfaceLocation location = new AppliedDirectiveInterfaceLocation(interfaze.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getInterfaceModification(interfaze.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + + } else if (container.isOfType(SchemaGraph.INPUT_OBJECT)) { + Vertex inputObject = container; + AppliedDirectiveInputObjectLocation location = new AppliedDirectiveInputObjectLocation(inputObject.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getInputObjectModification(inputObject.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + + } else if (container.isOfType(SchemaGraph.ENUM)) { + Vertex enumVertex = container; + AppliedDirectiveEnumLocation location = new AppliedDirectiveEnumLocation(enumVertex.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getEnumModification(enumVertex.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + } else if (container.isOfType(SchemaGraph.ENUM_VALUE)) { + Vertex enumValue = container; + Vertex enumVertex = newSchemaGraph.getEnumForEnumValue(enumValue); + AppliedDirectiveEnumValueLocation location = new AppliedDirectiveEnumValueLocation(enumVertex.getName(), enumValue.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getEnumModification(enumVertex.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + + } else if (container.isOfType(SchemaGraph.UNION)) { + Vertex union = container; + AppliedDirectiveUnionLocation location = new AppliedDirectiveUnionLocation(union.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getUnionModification(union.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + } else if (container.isOfType(SchemaGraph.SCALAR)) { + Vertex scalar = container; + AppliedDirectiveScalarLocation location = new AppliedDirectiveScalarLocation(scalar.getName(), appliedDirective.getName()); + if (valueChanged) { + AppliedDirectiveArgumentValueModification argumentValueModification = new AppliedDirectiveArgumentValueModification(location, newArgumentName, oldValue, newValue); + getScalarModification(scalar.getName()).getDetails().add(argumentValueModification); + } + if (nameChanged) { + + } + } else { + assertShouldNeverHappen("Unexpected applied argument container " + container); + } + } + + private void appliedDirectiveAdded(EditOperation editOperation) { + Vertex appliedDirective = editOperation.getTargetVertex(); + Vertex container = newSchemaGraph.getAppliedDirectiveContainerForAppliedDirective(appliedDirective); + if (container.isOfType(SchemaGraph.FIELD)) { + appliedDirectiveAddedToField(appliedDirective, container); + } else if (container.isOfType(SchemaGraph.ARGUMENT)) { + appliedDirectiveAddedToArgument(appliedDirective, container); + + } else if (container.isOfType(SchemaGraph.OBJECT)) { + Vertex object = container; + if (isObjectAdded(object.getName())) { + return; + } + AppliedDirectiveObjectLocation location = new AppliedDirectiveObjectLocation(object.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.INTERFACE)) { + Vertex interfaze = container; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + AppliedDirectiveInterfaceLocation location = new AppliedDirectiveInterfaceLocation(interfaze.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.SCALAR)) { + Vertex scalar = container; + if (isScalarAdded(scalar.getName())) { + return; + } + AppliedDirectiveScalarLocation location = new AppliedDirectiveScalarLocation(scalar.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getScalarModification(scalar.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.ENUM)) { + Vertex enumVertex = container; + if (isEnumAdded(enumVertex.getName())) { + return; + } + AppliedDirectiveEnumLocation location = new AppliedDirectiveEnumLocation(enumVertex.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.ENUM_VALUE)) { + Vertex enumValue = container; + Vertex enumVertex = newSchemaGraph.getEnumForEnumValue(enumValue); + if (isEnumAdded(enumVertex.getName())) { + return; + } + if (isNewEnumValueForExistingEnum(enumVertex.getName(), enumValue.getName())) { + return; + } + AppliedDirectiveEnumValueLocation location = new AppliedDirectiveEnumValueLocation(enumVertex.getName(), enumValue.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getEnumModification(enumVertex.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.INPUT_OBJECT)) { + Vertex inputObject = container; + if (isInputObjectAdded(inputObject.getName())) { + return; + } + AppliedDirectiveInputObjectLocation location = new AppliedDirectiveInputObjectLocation(inputObject.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.INPUT_FIELD)) { + Vertex inputField = container; + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectAdded(inputObject.getName())) { + return; + } + if (isNewInputFieldExistingInputObject(inputObject.getName(), inputField.getName())) { + return; + } + AppliedDirectiveInputObjectFieldLocation location = new AppliedDirectiveInputObjectFieldLocation(inputObject.getName(), inputField.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getInputObjectModification(inputObject.getName()).getDetails().add(appliedDirectiveAddition); + } else if (container.isOfType(SchemaGraph.UNION)) { + Vertex union = container; + if (isUnionAdded(union.getName())) { + return; + } + AppliedDirectiveUnionLocation location = new AppliedDirectiveUnionLocation(union.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getUnionModification(union.getName()).getDetails().add(appliedDirectiveAddition); + } + } + + private void appliedDirectiveDeletedFromField(Vertex appliedDirective, Vertex container) { + Vertex field = container; + Vertex interfaceOrObjective = oldSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + + if (isObjectDeleted(object.getName())) { + return; + } + if (isFieldDeletedFromExistingObject(object.getName(), field.getName())) { + return; + } + AppliedDirectiveObjectFieldLocation location = new AppliedDirectiveObjectFieldLocation(object.getName(), field.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(appliedDirectiveDeletion); + } + } + + private void appliedDirectiveAddedToField(Vertex appliedDirective, Vertex container) { + Vertex field = container; + Vertex interfaceOrObjective = newSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + + if (isObjectAdded(object.getName())) { + return; + } + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + AppliedDirectiveObjectFieldLocation location = new AppliedDirectiveObjectFieldLocation(object.getName(), field.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(appliedDirectiveAddition); + } + } + + private void appliedDirectiveDeletedFromArgument(Vertex appliedDirective, Vertex container) { + Vertex argument = container; + Vertex fieldOrDirective = oldSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex interfaceOrObjective = oldSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + if (isObjectDeleted(object.getName())) { + return; + } + if (isFieldDeletedFromExistingObject(object.getName(), field.getName())) { + return; + } + if (isArgumentDeletedFromExistingObjectField(object.getName(), field.getName(), argument.getName())) { + return; + } + AppliedDirectiveObjectFieldArgumentLocation location = new AppliedDirectiveObjectFieldArgumentLocation(object.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(appliedDirectiveDeletion); + } else { + assertTrue(interfaceOrObjective.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = interfaceOrObjective; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + if (isFieldDeletedFromExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isArgumentDeletedFromExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) { + return; + } + AppliedDirectiveInterfaceFieldArgumentLocation location = new AppliedDirectiveInterfaceFieldArgumentLocation(interfaze.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(appliedDirectiveDeletion); + } + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)); + Vertex directive = fieldOrDirective; + if (isDirectiveDeleted(directive.getName())) { + return; + } + if (isArgumentDeletedFromExistingDirective(directive.getName(), argument.getName())) { + return; + } + AppliedDirectiveDirectiveArgumentLocation location = new AppliedDirectiveDirectiveArgumentLocation(directive.getName(), argument.getName(), appliedDirective.getName()); + AppliedDirectiveDeletion appliedDirectiveDeletion = new AppliedDirectiveDeletion(location, appliedDirective.getName()); + getDirectiveModification(directive.getName()).getDetails().add(appliedDirectiveDeletion); + } + } + + private void appliedDirectiveAddedToArgument(Vertex appliedDirective, Vertex container) { + Vertex argument = container; + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex interfaceOrObjective = newSchemaGraph.getFieldsContainerForField(field); + if (interfaceOrObjective.isOfType(SchemaGraph.OBJECT)) { + Vertex object = interfaceOrObjective; + if (isObjectAdded(object.getName())) { + return; + } + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + if (isArgumentNewForExistingObjectField(object.getName(), field.getName(), argument.getName())) { + return; + } + AppliedDirectiveObjectFieldArgumentLocation location = new AppliedDirectiveObjectFieldArgumentLocation(object.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getObjectModification(object.getName()).getDetails().add(appliedDirectiveAddition); + } else { + assertTrue(interfaceOrObjective.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = interfaceOrObjective; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isArgumentNewForExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) { + return; + } + AppliedDirectiveInterfaceFieldArgumentLocation location = new AppliedDirectiveInterfaceFieldArgumentLocation(interfaze.getName(), field.getName(), argument.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getInterfaceModification(interfaze.getName()).getDetails().add(appliedDirectiveAddition); + } + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)); + Vertex directive = fieldOrDirective; + if (isDirectiveAdded(directive.getName())) { + return; + } + if (isArgumentNewForExistingDirective(directive.getName(), argument.getName())) { + return; + } + AppliedDirectiveDirectiveArgumentLocation location = new AppliedDirectiveDirectiveArgumentLocation(directive.getName(), argument.getName(), appliedDirective.getName()); + AppliedDirectiveAddition appliedDirectiveAddition = new AppliedDirectiveAddition(location, appliedDirective.getName()); + getDirectiveModification(directive.getName()).getDetails().add(appliedDirectiveAddition); + } + } + + private void handleTypeChanges(List editOperations, Mapping mapping) { + for (EditOperation editOperation : editOperations) { + Edge newEdge = editOperation.getTargetEdge(); + switch (editOperation.getOperation()) { + case INSERT_EDGE: + if (newEdge.getLabel().startsWith("type=")) { + typeEdgeInserted(editOperation, editOperations, mapping); + } + break; + case CHANGE_EDGE: + if (newEdge.getLabel().startsWith("type=")) { + typeEdgeChanged(editOperation, mapping); + } + break; + } + } + } + + private void handleUnionMemberChanges(List editOperations, Mapping mapping) { + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_EDGE: + Edge newEdge = editOperation.getTargetEdge(); + if (newEdge.getFrom().isOfType(SchemaGraph.UNION)) { + handleUnionMemberAdded(editOperation); + } + break; + case DELETE_EDGE: + Edge oldEdge = editOperation.getSourceEdge(); + if (oldEdge.getFrom().isOfType(SchemaGraph.UNION) && !oldEdge.getTo().isOfType(SchemaGraph.APPLIED_DIRECTIVE)) { + handleUnionMemberDeleted(editOperation); + } + break; + } + } + } + + private void handleEnumValuesChanges(List editOperations, Mapping mapping) { + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_EDGE: + Edge newEdge = editOperation.getTargetEdge(); + if (newEdge.getFrom().isOfType(SchemaGraph.ENUM) && newEdge.getTo().isOfType(SchemaGraph.ENUM_VALUE)) { + handleEnumValueAdded(editOperation); + } + break; + case DELETE_EDGE: + Edge oldEdge = editOperation.getSourceEdge(); + if (oldEdge.getFrom().isOfType(SchemaGraph.ENUM) && oldEdge.getTo().isOfType(SchemaGraph.ENUM_VALUE)) { + handleEnumValueDeleted(editOperation); + } + break; + case CHANGE_VERTEX: + if (editOperation.getSourceVertex().isOfType(SchemaGraph.ENUM_VALUE) && editOperation.getTargetVertex().isOfType(SchemaGraph.ENUM_VALUE)) { + handleEnumValueChanged(editOperation); + } + break; + } + } + } + + private void handleInputFieldChange(EditOperation editOperation) { + Vertex inputField = editOperation.getTargetVertex(); + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + + String oldName = editOperation.getSourceVertex().getName(); + String newName = inputField.getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + if (isInputObjectAdded(inputObject.getName())) { + return; + } + + getInputObjectModification(inputObject.getName()).getDetails().add(new InputObjectFieldRename(oldName, newName)); + } + + private void handleArgumentChange(EditOperation editOperation, Mapping mapping) { + Vertex oldArgument = editOperation.getSourceVertex(); + Vertex argument = editOperation.getTargetVertex(); + + String oldName = oldArgument.getName(); + String newName = argument.getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + if (!doesArgumentChangeMakeSense(oldArgument, argument, mapping)) { + return; + } + + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)) { + Vertex directive = fieldOrDirective; + DirectiveModification directiveModification = getDirectiveModification(directive.getName()); + directiveModification.getDetails().add(new DirectiveArgumentRename(oldName, newName)); + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.FIELD)); + Vertex field = fieldOrDirective; + String fieldName = field.getName(); + Vertex fieldsContainerForField = newSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainerForField.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainerForField; + ObjectModification objectModification = getObjectModification(object.getName()); + objectModification.getDetails().add(new ObjectFieldArgumentRename(fieldName, oldName, newName)); + } else { + assertTrue(fieldsContainerForField.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = fieldsContainerForField; + InterfaceModification interfaceModification = getInterfaceModification(interfaze.getName()); + interfaceModification.getDetails().add(new InterfaceFieldArgumentRename(fieldName, oldName, newName)); + } + } + } + + private void handleImplementsChanges(List editOperations, Mapping mapping) { + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_EDGE: + Edge newEdge = editOperation.getTargetEdge(); + if (newEdge.getLabel().startsWith("implements ")) { + newInterfaceAddedToInterfaceOrObject(newEdge); + } + break; + case DELETE_EDGE: + Edge oldEdge = editOperation.getSourceEdge(); + if (oldEdge.getLabel().startsWith("implements ")) { + interfaceImplementationDeleted(oldEdge); + } + break; + } + } + } + + private void handleUnionMemberAdded(EditOperation editOperation) { + Edge newEdge = editOperation.getTargetEdge(); + Vertex union = newEdge.getFrom(); + if (isUnionAdded(union.getName())) { + return; + } + Vertex newMemberObject = newEdge.getTo(); + UnionModification unionModification = getUnionModification(union.getName()); + unionModification.getDetails().add(new UnionMemberAddition(newMemberObject.getName())); + } + + private void handleUnionMemberDeleted(EditOperation editOperation) { + Edge deletedEdge = editOperation.getSourceEdge(); + Vertex union = deletedEdge.getFrom(); + if (isUnionDeleted(union.getName())) { + return; + } + Vertex memberObject = deletedEdge.getTo(); + UnionModification unionModification = getUnionModification(union.getName()); + unionModification.getDetails().add(new UnionMemberDeletion(memberObject.getName())); + } + + private void handleEnumValueAdded(EditOperation editOperation) { + Edge newEdge = editOperation.getTargetEdge(); + Vertex enumVertex = newEdge.getFrom(); + if (isEnumAdded(enumVertex.getName())) { + return; + } + Vertex newValue = newEdge.getTo(); + EnumModification enumModification = getEnumModification(enumVertex.getName()); + enumModification.getDetails().add(new EnumValueAddition(newValue.getName())); + } + + private void handleEnumValueDeleted(EditOperation editOperation) { + Edge deletedEdge = editOperation.getSourceEdge(); + Vertex enumVertex = deletedEdge.getFrom(); + if (isEnumDeleted(enumVertex.getName())) { + return; + } + Vertex value = deletedEdge.getTo(); + EnumModification enumModification = getEnumModification(enumVertex.getName()); + enumModification.getDetails().add(new EnumValueDeletion(value.getName())); + } + + private void handleEnumValueChanged(EditOperation editOperation) { + Vertex enumVertex = newSchemaGraph.getEnumForEnumValue(editOperation.getTargetVertex()); + EnumModification enumModification = getEnumModification(enumVertex.getName()); + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + enumModification.getDetails().add(new EnumValueRenamed(oldName, newName)); + } + + private void fieldChanged(EditOperation editOperation) { + Vertex field = editOperation.getTargetVertex(); + Vertex fieldsContainerForField = newSchemaGraph.getFieldsContainerForField(field); + + String oldName = editOperation.getSourceVertex().getName(); + String newName = field.getName(); + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + if (fieldsContainerForField.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainerForField; + + if (isObjectAdded(object.getName())) { + return; + } + + ObjectModification objectModification = getObjectModification(object.getName()); + objectModification.getDetails().add(new ObjectFieldRename(oldName, newName)); + } else { + assertTrue(fieldsContainerForField.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = fieldsContainerForField; + + if (isInterfaceAdded(interfaze.getName())) { + return; + } + + InterfaceModification interfaceModification = getInterfaceModification(interfaze.getName()); + interfaceModification.getDetails().add(new InterfaceFieldRename(oldName, newName)); + } + } + + private void inputFieldAdded(EditOperation editOperation) { + Vertex inputField = editOperation.getTargetVertex(); + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectAdded(inputObject.getName())) { + return; + } + InputObjectModification modification = getInputObjectModification(inputObject.getName()); + modification.getDetails().add(new InputObjectFieldAddition(inputField.getName())); + } + + private void fieldAdded(EditOperation editOperation) { + Vertex field = editOperation.getTargetVertex(); + Vertex fieldsContainerForField = newSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainerForField.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainerForField; + if (isObjectAdded(object.getName())) { + return; + } + ObjectModification objectModification = getObjectModification(object.getName()); + String name = field.getName(); + objectModification.getDetails().add(new ObjectFieldAddition(name)); + } else { + assertTrue(fieldsContainerForField.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = fieldsContainerForField; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + InterfaceModification interfaceModification = getInterfaceModification(interfaze.getName()); + String name = field.getName(); + interfaceModification.getDetails().add(new InterfaceFieldAddition(name)); + } + } + + private void inputFieldDeleted(EditOperation editOperation) { + Vertex inputField = editOperation.getSourceVertex(); + Vertex inputObject = oldSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectDeleted(inputObject.getName())) { + return; + } + getInputObjectModification(inputObject.getName()).getDetails().add(new InputObjectFieldDeletion(inputField.getName())); + } + + private void fieldDeleted(EditOperation editOperation) { + Vertex deletedField = editOperation.getSourceVertex(); + Vertex fieldsContainerForField = oldSchemaGraph.getFieldsContainerForField(deletedField); + if (fieldsContainerForField.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainerForField; + if (isObjectDeleted(object.getName())) { + return; + } + ObjectModification objectModification = getObjectModification(object.getName()); + String name = deletedField.getName(); + objectModification.getDetails().add(new ObjectFieldDeletion(name)); + } else { + assertTrue(fieldsContainerForField.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = fieldsContainerForField; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + InterfaceModification interfaceModification = getInterfaceModification(interfaze.getName()); + String name = deletedField.getName(); + interfaceModification.getDetails().add(new InterfaceFieldDeletion(name)); + } + } + + + private void handleTypeVertexChanges(List editOperations) { + for (EditOperation editOperation : editOperations) { + switch (editOperation.getOperation()) { + case INSERT_VERTEX: + insertedTypeVertex(editOperation); + break; + case DELETE_VERTEX: + deletedTypeVertex(editOperation); + break; + case CHANGE_VERTEX: + changedTypeVertex(editOperation); + break; + } + } + } + + private void insertedTypeVertex(EditOperation editOperation) { + switch (editOperation.getTargetVertex().getType()) { + case SchemaGraph.OBJECT: + addedObject(editOperation); + break; + case SchemaGraph.INTERFACE: + addedInterface(editOperation); + break; + case SchemaGraph.UNION: + addedUnion(editOperation); + break; + case SchemaGraph.INPUT_OBJECT: + addedInputObject(editOperation); + break; + case SchemaGraph.ENUM: + addedEnum(editOperation); + break; + case SchemaGraph.SCALAR: + addedScalar(editOperation); + break; + case SchemaGraph.DIRECTIVE: + addedDirective(editOperation); + break; + } + + } + + private void deletedTypeVertex(EditOperation editOperation) { + switch (editOperation.getSourceVertex().getType()) { + case SchemaGraph.OBJECT: + removedObject(editOperation); + break; + case SchemaGraph.INTERFACE: + removedInterface(editOperation); + break; + case SchemaGraph.UNION: + removedUnion(editOperation); + break; + case SchemaGraph.INPUT_OBJECT: + removedInputObject(editOperation); + break; + case SchemaGraph.ENUM: + removedEnum(editOperation); + break; + case SchemaGraph.SCALAR: + deletedScalar(editOperation); + break; + case SchemaGraph.DIRECTIVE: + deletedDirective(editOperation); + break; + } + } + + private void changedTypeVertex(EditOperation editOperation) { + switch (editOperation.getTargetVertex().getType()) { + case SchemaGraph.OBJECT: + changedObject(editOperation); + break; + case SchemaGraph.INTERFACE: + changedInterface(editOperation); + break; + case SchemaGraph.UNION: + changedUnion(editOperation); + break; + case SchemaGraph.INPUT_OBJECT: + changedInputObject(editOperation); + break; + case SchemaGraph.ENUM: + changedEnum(editOperation); + break; + case SchemaGraph.SCALAR: + changedScalar(editOperation); + break; + case SchemaGraph.DIRECTIVE: + changedDirective(editOperation); + break; + } + } + + + private void typeEdgeInserted(EditOperation editOperation, List editOperations, Mapping + mapping) { + Edge newEdge = editOperation.getTargetEdge(); + Vertex from = newEdge.getFrom(); + if (from.isOfType(SchemaGraph.FIELD)) { + typeEdgeInsertedForField(editOperation, editOperations, mapping); + } else if (from.isOfType(SchemaGraph.ARGUMENT)) { + typeEdgeInsertedForArgument(editOperation, editOperations, mapping); + } else if (from.isOfType(SchemaGraph.INPUT_FIELD)) { + typeEdgeInsertedForInputField(editOperation, editOperations, mapping); + } + + } + + private void typeEdgeInsertedForInputField(EditOperation editOperation, + List editOperations, + Mapping mapping) { + Vertex inputField = editOperation.getTargetEdge().getFrom(); + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + if (isInputObjectAdded(inputObject.getName())) { + return; + } + if (isNewInputFieldExistingInputObject(inputObject.getName(), inputField.getName())) { + return; + } + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(inputField, editOperations, mapping, this::isTypeEdge); + String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + InputObjectFieldTypeModification inputObjectFieldTypeModification = new InputObjectFieldTypeModification(inputField.getName(), oldType, newType); + getInputObjectModification(inputObject.getName()).getDetails().add(inputObjectFieldTypeModification); + } + + private void typeEdgeInsertedForArgument(EditOperation editOperation, + List editOperations, + Mapping mapping) { + Vertex argument = editOperation.getTargetEdge().getFrom(); + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex objectOrInterface = newSchemaGraph.getFieldsContainerForField(field); + + if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) { + Vertex object = objectOrInterface; + + // if the whole object is new we are done + if (isObjectAdded(object.getName())) { + return; + } + // if the field is new, we are done too + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + // if the argument is new, we are done too + if (isArgumentNewForExistingObjectField(object.getName(), field.getName(), argument.getName())) { + return; + } + + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + // this means we have an existing object changed its type + // and there must be a deleted edge with the old type information + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge); + String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + ObjectFieldArgumentTypeModification objectFieldArgumentTypeModification = new ObjectFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); + getObjectModification(object.getName()).getDetails().add(objectFieldArgumentTypeModification); + + String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldDefaultValue.equals(newDefaultValue)) { + getObjectModification(object.getName()).getDetails().add(new ObjectFieldArgumentDefaultValueModification(field.getName(), argument.getName(), oldDefaultValue, newDefaultValue)); + } + } else { + assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = objectOrInterface; + + // if the whole object is new we are done + if (isInterfaceAdded(interfaze.getName())) { + return; + } + // if the field is new, we are done too + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + // if the argument is new, we are done too + if (isArgumentNewForExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) { + return; + } + + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + // this means we have an existing object changed its type + // and there must be a deleted edge with the old type information + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge); + String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + InterfaceFieldArgumentTypeModification interfaceFieldArgumentTypeModification = new InterfaceFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); + getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldArgumentTypeModification); + + String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldDefaultValue.equals(newDefaultValue)) { + getInterfaceModification(interfaze.getName()).getDetails().add(new InterfaceFieldArgumentDefaultValueModification(field.getName(), argument.getName(), oldDefaultValue, newDefaultValue)); + } + } + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)); + Vertex directive = fieldOrDirective; + + if (isDirectiveAdded(directive.getName())) { + return; + } + if (isArgumentNewForExistingDirective(directive.getName(), argument.getName())) { + return; + } + + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge); + String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + DirectiveArgumentTypeModification directiveArgumentTypeModification = new DirectiveArgumentTypeModification(argument.getName(), oldType, newType); + getDirectiveModification(directive.getName()).getDetails().add(directiveArgumentTypeModification); + + String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldDefaultValue.equals(newDefaultValue)) { + getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentDefaultValueModification(argument.getName(), oldDefaultValue, newDefaultValue)); + } + } + } + + private void typeEdgeInsertedForField(EditOperation editOperation, + List editOperations, + Mapping mapping) { + Vertex field = editOperation.getTargetEdge().getFrom(); + Vertex objectOrInterface = newSchemaGraph.getFieldsContainerForField(field); + if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) { + Vertex object = objectOrInterface; + // if the whole object is new we are done + if (isObjectAdded(object.getName())) { + return; + } + // if the field is new, we are done too + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + // this means we have an existing object changed its type + // and there must be a deleted edge with the old type information + EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, this::isTypeEdge); + String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + ObjectFieldTypeModification objectFieldTypeModification = new ObjectFieldTypeModification(field.getName(), oldType, newType); + getObjectModification(object.getName()).getDetails().add(objectFieldTypeModification); + } else { + assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = objectOrInterface; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + // this means we have an existing object changed its type + // and there must be a deleted edge with the old type information + EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, this::isTypeEdge); + String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); + InterfaceFieldTypeModification interfaceFieldTypeModification = new InterfaceFieldTypeModification(field.getName(), oldType, newType); + getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldTypeModification); + } + } + + + private EditOperation findDeletedEdge(Vertex targetVertexFrom, + List editOperations, + Mapping mapping, + Predicate edgePredicate) { + Vertex sourceVertexFrom = mapping.getSource(targetVertexFrom); + for (EditOperation editOperation : editOperations) { + if (editOperation.getOperation() == EditOperation.Operation.DELETE_EDGE) { + Edge deletedEdge = editOperation.getSourceEdge(); + if (deletedEdge.getFrom() == sourceVertexFrom && edgePredicate.test(deletedEdge)) { + return editOperation; + } + } + } + return Assert.assertShouldNeverHappen(); + } + + + private void typeEdgeChanged(EditOperation editOperation, Mapping mapping) { + Edge targetEdge = editOperation.getTargetEdge(); + Vertex from = targetEdge.getFrom(); + if (from.isOfType(SchemaGraph.FIELD)) { + outputFieldTypeChanged(editOperation); + } else if (from.isOfType(SchemaGraph.ARGUMENT)) { + argumentTypeOrDefaultValueChanged(editOperation, mapping); + } else if (from.isOfType(SchemaGraph.INPUT_FIELD)) { + inputFieldTypeOrDefaultValueChanged(editOperation); + } + } + + private void inputFieldTypeOrDefaultValueChanged(EditOperation editOperation) { + Edge targetEdge = editOperation.getTargetEdge(); + Vertex inputField = targetEdge.getFrom(); + Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField); + + if (isInputObjectAdded(inputObject.getName())) { + return; + } + + String oldDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getSourceEdge()); + String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldDefaultValue.equals(newDefaultValue)) { + InputObjectFieldDefaultValueModification modification = new InputObjectFieldDefaultValueModification(inputField.getName(), oldDefaultValue, newDefaultValue); + getInputObjectModification(inputObject.getName()).getDetails().add(modification); + } + String oldType = getTypeFromEdgeLabel(editOperation.getSourceEdge()); + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldType.equals(newType)) { + InputObjectFieldTypeModification inputObjectFieldTypeModification = new InputObjectFieldTypeModification(inputField.getName(), oldType, newType); + getInputObjectModification(inputObject.getName()).getDetails().add(inputObjectFieldTypeModification); + } + } + + private void argumentTypeOrDefaultValueChanged(EditOperation editOperation, Mapping mapping) { + Vertex oldArgument = editOperation.getSourceEdge().getFrom(); + Vertex argument = editOperation.getTargetEdge().getFrom(); + + if (!doesArgumentChangeMakeSense(oldArgument, argument, mapping)) { + return; + } + + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex objectOrInterface = newSchemaGraph.getFieldsContainerForField(field); + + String oldDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getSourceEdge()); + String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldDefaultValue.equals(newDefaultValue)) { + if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) { + ObjectFieldArgumentDefaultValueModification defaultValueModification = new ObjectFieldArgumentDefaultValueModification( + field.getName(), + argument.getName(), + oldDefaultValue, + newDefaultValue); + getObjectModification(objectOrInterface.getName()).getDetails().add(defaultValueModification); + } else { + assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE)); + InterfaceFieldArgumentDefaultValueModification defaultValueModification = new InterfaceFieldArgumentDefaultValueModification( + field.getName(), + argument.getName(), + oldDefaultValue, + newDefaultValue); + getInterfaceModification(objectOrInterface.getName()).getDetails().add(defaultValueModification); + } + } + + String oldType = getTypeFromEdgeLabel(editOperation.getSourceEdge()); + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldType.equals(newType)) { + if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) { + ObjectFieldArgumentTypeModification objectFieldArgumentTypeModification = new ObjectFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); + getObjectModification(objectOrInterface.getName()).getDetails().add(objectFieldArgumentTypeModification); + } else { + assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE)); + InterfaceFieldArgumentTypeModification interfaceFieldArgumentTypeModification = new InterfaceFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); + getInterfaceModification(objectOrInterface.getName()).getDetails().add(interfaceFieldArgumentTypeModification); + } + } + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)); + Vertex directive = fieldOrDirective; + + String oldDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getSourceEdge()); + String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge()); + if (!oldDefaultValue.equals(newDefaultValue)) { + getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentDefaultValueModification(argument.getName(), oldDefaultValue, newDefaultValue)); + } + String oldType = getTypeFromEdgeLabel(editOperation.getSourceEdge()); + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + + if (!oldType.equals(newType)) { + getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentTypeModification(argument.getName(), oldType, newType)); + } + } + } + + /** + * Sometimes the diffing algorithm will give us an argument change when the argument container + * changed i.e. the argument was "moved" around because the deleted and newly added arguments + * look similar. + *

+ * We only want to report argument type changes if it makes sense i.e. if the argument container was the same. + */ + private boolean doesArgumentChangeMakeSense(Vertex oldArgument, Vertex newArgument, Mapping mapping) { + // Container for an argument in this case should be a field or directive + Vertex oldContainer = oldSchemaGraph.getFieldOrDirectiveForArgument(oldArgument); + Vertex newContainer = newSchemaGraph.getFieldOrDirectiveForArgument(newArgument); + + // Make sure the container is the same + return mapping.getTarget(oldContainer) == newContainer; + } + + private void outputFieldTypeChanged(EditOperation editOperation) { + Edge targetEdge = editOperation.getTargetEdge(); + Vertex field = targetEdge.getFrom(); + Vertex container = newSchemaGraph.getFieldsContainerForField(field); + if (container.isOfType(SchemaGraph.OBJECT)) { + Vertex object = container; + ObjectModification objectModification = getObjectModification(object.getName()); + String fieldName = field.getName(); + String oldType = getTypeFromEdgeLabel(editOperation.getSourceEdge()); + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + objectModification.getDetails().add(new ObjectFieldTypeModification(fieldName, oldType, newType)); + } else { + assertTrue(container.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = container; + InterfaceModification interfaceModification = getInterfaceModification(interfaze.getName()); + String fieldName = field.getName(); + String oldType = getTypeFromEdgeLabel(editOperation.getSourceEdge()); + String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); + interfaceModification.getDetails().add(new InterfaceFieldTypeModification(fieldName, oldType, newType)); + } + } + + // TODO: this is not great, we should avoid parsing the label like that + private String getTypeFromEdgeLabel(Edge edge) { + String label = edge.getLabel(); + assertTrue(label.startsWith("type=")); + String type = label.substring("type=".length(), label.indexOf(";")); + return type; + } + + private String getDefaultValueFromEdgeLabel(Edge edge) { + String label = edge.getLabel(); + assertTrue(label.startsWith("type=")); + String defaultValue = label.substring(label.indexOf(";defaultValue=") + ";defaultValue=".length()); + return defaultValue; + } + + private boolean isTypeEdge(Edge edge) { + String label = edge.getLabel(); + return label.startsWith("type="); + } + + private void interfaceImplementationDeleted(Edge deletedEdge) { + Vertex from = deletedEdge.getFrom(); + if (from.isOfType(SchemaGraph.OBJECT)) { + if (isObjectDeleted(from.getName())) { + return; + } + Vertex objectVertex = deletedEdge.getFrom(); + Vertex interfaceVertex = deletedEdge.getTo(); + ObjectInterfaceImplementationDeletion deletion = new ObjectInterfaceImplementationDeletion(interfaceVertex.getName()); + getObjectModification(objectVertex.getName()).getDetails().add(deletion); + + } else { + assertTrue(from.isOfType(SchemaGraph.INTERFACE)); + if (isInterfaceDeleted(from.getName())) { + return; + } + Vertex interfaceFromVertex = deletedEdge.getFrom(); + Vertex interfaceVertex = deletedEdge.getTo(); + InterfaceInterfaceImplementationDeletion deletion = new InterfaceInterfaceImplementationDeletion(interfaceVertex.getName()); + getInterfaceModification(interfaceFromVertex.getName()).getDetails().add(deletion); + } + + } + + private void newInterfaceAddedToInterfaceOrObject(Edge newEdge) { + Vertex from = newEdge.getFrom(); + if (from.isOfType(SchemaGraph.OBJECT)) { + if (isObjectAdded(from.getName())) { + return; + } + Vertex objectVertex = newEdge.getFrom(); + Vertex interfaceVertex = newEdge.getTo(); + ObjectInterfaceImplementationAddition objectInterfaceImplementationAddition = new ObjectInterfaceImplementationAddition(interfaceVertex.getName()); + getObjectModification(objectVertex.getName()).getDetails().add(objectInterfaceImplementationAddition); + + } else { + assertTrue(from.isOfType(SchemaGraph.INTERFACE)); + if (isInterfaceAdded(from.getName())) { + return; + } + Vertex interfaceFromVertex = newEdge.getFrom(); + Vertex interfaceVertex = newEdge.getTo(); + InterfaceInterfaceImplementationAddition addition = new InterfaceInterfaceImplementationAddition(interfaceVertex.getName()); + getInterfaceModification(interfaceFromVertex.getName()).getDetails().add(addition); + } + + } + + private boolean isDirectiveAdded(String name) { + return directiveDifferences.containsKey(name) && directiveDifferences.get(name) instanceof DirectiveAddition; + } + + private boolean isDirectiveDeleted(String name) { + return directiveDifferences.containsKey(name) && directiveDifferences.get(name) instanceof DirectiveDeletion; + } + + private boolean isObjectAdded(String name) { + return objectDifferences.containsKey(name) && objectDifferences.get(name) instanceof ObjectAddition; + } + + private boolean isUnionAdded(String name) { + return unionDifferences.containsKey(name) && unionDifferences.get(name) instanceof UnionAddition; + } + + private boolean isUnionDeleted(String name) { + return unionDifferences.containsKey(name) && unionDifferences.get(name) instanceof UnionDeletion; + } + + private boolean isEnumDeleted(String name) { + return enumDifferences.containsKey(name) && enumDifferences.get(name) instanceof EnumDeletion; + } + + private boolean isEnumAdded(String name) { + return enumDifferences.containsKey(name) && enumDifferences.get(name) instanceof EnumAddition; + } + + private boolean isInputObjectAdded(String name) { + return inputObjectDifferences.containsKey(name) && inputObjectDifferences.get(name) instanceof InputObjectAddition; + } + + private boolean isInputObjectDeleted(String name) { + return inputObjectDifferences.containsKey(name) && inputObjectDifferences.get(name) instanceof InputObjectDeletion; + } + + private boolean isInputFieldAdded(String name) { + return inputObjectDifferences.containsKey(name) && inputObjectDifferences.get(name) instanceof InputObjectAddition; + } + + private boolean isAppliedDirectiveAdded(Vertex container, String appliedDirectiveName) { + if (container.isOfType(SchemaGraph.SCALAR)) { + if (scalarDifferences.containsKey(container.getName())) { + ScalarDifference scalarDifference = scalarDifferences.get(container.getName()); + if (scalarDifference instanceof ScalarModification) { + ScalarModification scalarModification = (ScalarModification) scalarDifference; + List appliedDirectiveAdditions = scalarModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } else if (container.isOfType(SchemaGraph.ENUM)) { + if (enumDifferences.containsKey(container.getName())) { + EnumDifference enumDifference = enumDifferences.get(container.getName()); + if (enumDifference instanceof EnumModification) { + EnumModification enumModification = (EnumModification) enumDifference; + List appliedDirectiveAdditions = enumModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } else if (container.isOfType(SchemaGraph.OBJECT)) { + if (objectDifferences.containsKey(container.getName())) { + ObjectDifference objectDifference = objectDifferences.get(container.getName()); + if (objectDifference instanceof ObjectModification) { + ObjectModification objectModification = (ObjectModification) objectDifference; + List appliedDirectiveAdditions = objectModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } else if (container.isOfType(SchemaGraph.INTERFACE)) { + if (interfaceDifferences.containsKey(container.getName())) { + InterfaceDifference interfaceDifference = interfaceDifferences.get(container.getName()); + if (interfaceDifference instanceof InterfaceModification) { + InterfaceModification interfaceModification = (InterfaceModification) interfaceDifference; + List appliedDirectiveAdditions = interfaceModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } else if (container.isOfType(SchemaGraph.INPUT_OBJECT)) { + if (inputObjectDifferences.containsKey(container.getName())) { + InputObjectDifference inputObjectDifference = inputObjectDifferences.get(container.getName()); + if (inputObjectDifference instanceof InputObjectModification) { + InputObjectModification inputObjectModification = (InputObjectModification) inputObjectDifference; + List appliedDirectiveAdditions = inputObjectModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } else if (container.isOfType(SchemaGraph.UNION)) { + if (unionDifferences.containsKey(container.getName())) { + UnionDifference unionDifference = unionDifferences.get(container.getName()); + if (unionDifference instanceof UnionModification) { + UnionModification unionModification = (UnionModification) unionDifference; + List appliedDirectiveAdditions = unionModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } else if (container.isOfType(SchemaGraph.DIRECTIVE)) { + if (directiveDifferences.containsKey(container.getName())) { + DirectiveDifference directiveDifference = directiveDifferences.get(container.getName()); + if (directiveDifference instanceof DirectiveModification) { + DirectiveModification directiveModification = (DirectiveModification) directiveDifference; + List appliedDirectiveAdditions = directiveModification.getDetails(AppliedDirectiveAddition.class); + return appliedDirectiveAdditions.stream().anyMatch(addition -> addition.getName().equals(appliedDirectiveName)); + } + } + } + return false; + } + + + private boolean isAppliedDirectiveDeleted(Vertex rootContainer, String appliedDirectiveName) { +// if (rootContainer.isOfType(SchemaGraph.ARGUMENT)) { +// Vertex argument = rootContainer; +// Vertex fieldOrDirective = oldSchemaGraph.getFieldOrDirectiveForArgument(argument); +// if (fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)) { +// return isArgumentDeletedFromExistingDirective(fieldOrDirective.getName(), argument.getName()); +// } +// } + if (rootContainer.isOfType(SchemaGraph.SCALAR)) { + if (scalarDifferences.containsKey(rootContainer.getName())) { + ScalarDifference scalarDifference = scalarDifferences.get(rootContainer.getName()); + if (scalarDifference instanceof ScalarModification) { + ScalarModification scalarModification = (ScalarModification) scalarDifference; + List appliedDirectiveDeletions = scalarModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } else if (rootContainer.isOfType(SchemaGraph.ENUM)) { + if (enumDifferences.containsKey(rootContainer.getName())) { + EnumDifference enumDifference = enumDifferences.get(rootContainer.getName()); + if (enumDifference instanceof EnumModification) { + EnumModification enumModification = (EnumModification) enumDifference; + List appliedDirectiveDeletions = enumModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } else if (rootContainer.isOfType(SchemaGraph.OBJECT)) { + if (objectDifferences.containsKey(rootContainer.getName())) { + ObjectDifference objectDifference = objectDifferences.get(rootContainer.getName()); + if (objectDifference instanceof ObjectModification) { + ObjectModification objectModification = (ObjectModification) objectDifference; + List appliedDirectiveDeletions = objectModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } else if (rootContainer.isOfType(SchemaGraph.INTERFACE)) { + if (interfaceDifferences.containsKey(rootContainer.getName())) { + InterfaceDifference interfaceDifference = interfaceDifferences.get(rootContainer.getName()); + if (interfaceDifference instanceof InterfaceModification) { + InterfaceModification interfaceModification = (InterfaceModification) interfaceDifference; + List appliedDirectiveDeletions = interfaceModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } else if (rootContainer.isOfType(SchemaGraph.INPUT_OBJECT)) { + if (inputObjectDifferences.containsKey(rootContainer.getName())) { + InputObjectDifference inputObjectDifference = inputObjectDifferences.get(rootContainer.getName()); + if (inputObjectDifference instanceof InputObjectModification) { + InputObjectModification inputObjectModification = (InputObjectModification) inputObjectDifference; + List appliedDirectiveDeletions = inputObjectModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } else if (rootContainer.isOfType(SchemaGraph.UNION)) { + if (unionDifferences.containsKey(rootContainer.getName())) { + UnionDifference unionDifference = unionDifferences.get(rootContainer.getName()); + if (unionDifference instanceof UnionModification) { + UnionModification unionModification = (UnionModification) unionDifference; + List appliedDirectiveDeletions = unionModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } else if (rootContainer.isOfType(SchemaGraph.DIRECTIVE)) { + if (directiveDifferences.containsKey(rootContainer.getName())) { + DirectiveDifference directiveDifference = directiveDifferences.get(rootContainer.getName()); + if (directiveDifference instanceof DirectiveModification) { + DirectiveModification directiveModification = (DirectiveModification) directiveDifference; + List appliedDirectiveDeletions = directiveModification.getDetails(AppliedDirectiveDeletion.class); + return appliedDirectiveDeletions.stream().anyMatch(deletion -> deletion.getName().equals(appliedDirectiveName)); + } + } + } + return false; + } + + private boolean isNewInputFieldExistingInputObject(String inputObjectName, String fieldName) { + if (!inputObjectDifferences.containsKey(inputObjectName)) { + return false; + } + if (!(inputObjectDifferences.get(inputObjectName) instanceof InputObjectModification)) { + return false; + } + InputObjectModification modification = (InputObjectModification) inputObjectDifferences.get(inputObjectName); + List newFields = modification.getDetails(InputObjectFieldAddition.class); + return newFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + } + + private boolean isInputFieldDeletedFromExistingInputObject(String inputObjectName, String fieldName) { + if (!inputObjectDifferences.containsKey(inputObjectName)) { + return false; + } + if (!(inputObjectDifferences.get(inputObjectName) instanceof InputObjectModification)) { + return false; + } + InputObjectModification modification = (InputObjectModification) inputObjectDifferences.get(inputObjectName); + List deletedFields = modification.getDetails(InputObjectFieldDeletion.class); + return deletedFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + } + + private boolean isArgumentNewForExistingDirective(String directiveName, String argumentName) { + if (!directiveDifferences.containsKey(directiveName)) { + return false; + } + if (!(directiveDifferences.get(directiveName) instanceof DirectiveModification)) { + return false; + } + DirectiveModification directiveModification = (DirectiveModification) directiveDifferences.get(directiveName); + List newArgs = directiveModification.getDetails(DirectiveArgumentAddition.class); + return newArgs.stream().anyMatch(detail -> detail.getName().equals(argumentName)); + } + + private boolean isArgumentDeletedFromExistingDirective(String directiveName, String argumentName) { + if (!directiveDifferences.containsKey(directiveName)) { + return false; + } + if (!(directiveDifferences.get(directiveName) instanceof DirectiveModification)) { + return false; + } + DirectiveModification directiveModification = (DirectiveModification) directiveDifferences.get(directiveName); + List deletedArgs = directiveModification.getDetails(DirectiveArgumentDeletion.class); + return deletedArgs.stream().anyMatch(detail -> detail.getName().equals(argumentName)); + } + + private boolean isArgumentNewForExistingObjectField(String objectName, String fieldName, String argumentName) { + if (!objectDifferences.containsKey(objectName)) { + return false; + } + if (!(objectDifferences.get(objectName) instanceof ObjectModification)) { + return false; + } + // finding out if the field was just added + ObjectModification objectModification = (ObjectModification) objectDifferences.get(objectName); + List newFields = objectModification.getDetails(ObjectFieldAddition.class); + boolean newField = newFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + if (newField) { + return false; + } + // now finding out if the argument is new + List newArgs = objectModification.getDetails(ObjectFieldArgumentAddition.class); + return newArgs.stream().anyMatch(detail -> detail.getFieldName().equals(fieldName) && detail.getName().equals(argumentName)); + } + + private boolean isArgumentDeletedFromExistingObjectField(String objectName, String fieldName, String + argumentName) { + if (!objectDifferences.containsKey(objectName)) { + return false; + } + if (!(objectDifferences.get(objectName) instanceof ObjectModification)) { + return false; + } + // finding out if the field was just added + ObjectModification objectModification = (ObjectModification) objectDifferences.get(objectName); + List deletedFields = objectModification.getDetails(ObjectFieldDeletion.class); + boolean deletedField = deletedFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + if (deletedField) { + return false; + } + // now finding out if the argument is deleted + List deletedArgs = objectModification.getDetails(ObjectFieldArgumentDeletion.class); + return deletedArgs.stream().anyMatch(detail -> detail.getFieldName().equals(fieldName) && detail.getName().equals(argumentName)); + } + + private boolean isArgumentDeletedFromExistingInterfaceField(String interfaceName, String fieldName, String + argumentName) { + if (!interfaceDifferences.containsKey(interfaceName)) { + return false; + } + if (!(interfaceDifferences.get(interfaceName) instanceof InterfaceModification)) { + return false; + } + // finding out if the field was just added + InterfaceModification interfaceModification = (InterfaceModification) interfaceDifferences.get(interfaceName); + List deletedFields = interfaceModification.getDetails(InterfaceFieldDeletion.class); + boolean deletedField = deletedFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + if (deletedField) { + return false; + } + // now finding out if the argument is deleted + List deletedArgs = interfaceModification.getDetails(InterfaceFieldArgumentDeletion.class); + return deletedArgs.stream().anyMatch(detail -> detail.getFieldName().equals(fieldName) && detail.getName().equals(argumentName)); + } + + private boolean isArgumentNewForExistingInterfaceField(String objectName, String fieldName, String argumentName) { + if (!interfaceDifferences.containsKey(objectName)) { + return false; + } + if (!(interfaceDifferences.get(objectName) instanceof InterfaceModification)) { + return false; + } + // finding out if the field was just added + InterfaceModification interfaceModification = (InterfaceModification) interfaceDifferences.get(objectName); + List newFields = interfaceModification.getDetails(InterfaceFieldAddition.class); + boolean newField = newFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + if (newField) { + return false; + } + // now finding out if the argument is new + List newArgs = interfaceModification.getDetails(InterfaceFieldArgumentAddition.class); + return newArgs.stream().anyMatch(detail -> detail.getFieldName().equals(fieldName) && detail.getName().equals(argumentName)); + } + + private boolean isFieldNewForExistingObject(String objectName, String fieldName) { + if (!objectDifferences.containsKey(objectName)) { + return false; + } + if (!(objectDifferences.get(objectName) instanceof ObjectModification)) { + return false; + } + ObjectModification objectModification = (ObjectModification) objectDifferences.get(objectName); + List newFields = objectModification.getDetails(ObjectFieldAddition.class); + return newFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + } + + private boolean isFieldDeletedFromExistingInterface(String interfaceName, String fieldName) { + if (!interfaceDifferences.containsKey(interfaceName)) { + return false; + } + if (!(interfaceDifferences.get(interfaceName) instanceof InterfaceModification)) { + return false; + } + InterfaceModification interfaceModification = (InterfaceModification) interfaceDifferences.get(interfaceName); + List deletedFields = interfaceModification.getDetails(InterfaceFieldDeletion.class); + return deletedFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + } + + private boolean isFieldDeletedFromExistingObject(String objectName, String fieldName) { + if (!objectDifferences.containsKey(objectName)) { + return false; + } + if (!(objectDifferences.get(objectName) instanceof ObjectModification)) { + return false; + } + ObjectModification objectModification = (ObjectModification) objectDifferences.get(objectName); + List deletedFields = objectModification.getDetails(ObjectFieldDeletion.class); + return deletedFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + } + + private boolean isNewEnumValueForExistingEnum(String enumName, String valueName) { + if (!enumDifferences.containsKey(enumName)) { + return false; + } + if (!(enumDifferences.get(enumName) instanceof EnumModification)) { + return false; + } + EnumModification enumModification = (EnumModification) enumDifferences.get(enumName); + List newValues = enumModification.getDetails(EnumValueAddition.class); + return newValues.stream().anyMatch(detail -> detail.getName().equals(valueName)); + } + + private boolean isEnumValueDeletedFromExistingEnum(String enumName, String valueName) { + if (!enumDifferences.containsKey(enumName)) { + return false; + } + if (!(enumDifferences.get(enumName) instanceof EnumModification)) { + return false; + } + EnumModification enumModification = (EnumModification) enumDifferences.get(enumName); + List deletedValues = enumModification.getDetails(EnumValueDeletion.class); + return deletedValues.stream().anyMatch(detail -> detail.getName().equals(valueName)); + } + + private boolean isFieldNewForExistingInterface(String interfaceName, String fieldName) { + if (!interfaceDifferences.containsKey(interfaceName)) { + return false; + } + if (!(interfaceDifferences.get(interfaceName) instanceof InterfaceModification)) { + return false; + } + InterfaceModification interfaceModification = (InterfaceModification) interfaceDifferences.get(interfaceName); + List newFields = interfaceModification.getDetails(InterfaceFieldAddition.class); + return newFields.stream().anyMatch(detail -> detail.getName().equals(fieldName)); + } + + private boolean isObjectDeleted(String name) { + return objectDifferences.containsKey(name) && objectDifferences.get(name) instanceof ObjectDeletion; + } + + private boolean isInterfaceDeleted(String name) { + return interfaceDifferences.containsKey(name) && interfaceDifferences.get(name) instanceof InterfaceDeletion; + } + + private boolean isInterfaceAdded(String name) { + return interfaceDifferences.containsKey(name) && interfaceDifferences.get(name) instanceof InterfaceAddition; + } + + private boolean isScalarAdded(String name) { + return scalarDifferences.containsKey(name) && scalarDifferences.get(name) instanceof ScalarAddition; + } + + private boolean isScalarDeleted(String name) { + return scalarDifferences.containsKey(name) && scalarDifferences.get(name) instanceof ScalarDeletion; + } + + private ObjectModification getObjectModification(String newName) { + if (!objectDifferences.containsKey(newName)) { + objectDifferences.put(newName, new ObjectModification(newName)); + } + assertTrue(objectDifferences.get(newName) instanceof ObjectModification); + return (ObjectModification) objectDifferences.get(newName); + } + + private UnionModification getUnionModification(String newName) { + if (!unionDifferences.containsKey(newName)) { + unionDifferences.put(newName, new UnionModification(newName)); + } + assertTrue(unionDifferences.get(newName) instanceof UnionModification); + return (UnionModification) unionDifferences.get(newName); + } + + private EnumModification getEnumModification(String newName) { + if (!enumDifferences.containsKey(newName)) { + enumDifferences.put(newName, new EnumModification(newName)); + } + assertTrue(enumDifferences.get(newName) instanceof EnumModification); + return (EnumModification) enumDifferences.get(newName); + } + + private InputObjectModification getInputObjectModification(String newName) { + if (!inputObjectDifferences.containsKey(newName)) { + inputObjectDifferences.put(newName, new InputObjectModification(newName)); + } + assertTrue(inputObjectDifferences.get(newName) instanceof InputObjectModification); + return (InputObjectModification) inputObjectDifferences.get(newName); + } + + private DirectiveModification getDirectiveModification(String newName) { + if (!directiveDifferences.containsKey(newName)) { + directiveDifferences.put(newName, new DirectiveModification(newName)); + } + assertTrue(directiveDifferences.get(newName) instanceof DirectiveModification); + return (DirectiveModification) directiveDifferences.get(newName); + } + + private InterfaceModification getInterfaceModification(String newName) { + if (!interfaceDifferences.containsKey(newName)) { + interfaceDifferences.put(newName, new InterfaceModification(newName)); + } + assertTrue(interfaceDifferences.get(newName) instanceof InterfaceModification); + return (InterfaceModification) interfaceDifferences.get(newName); + } + + private ScalarModification getScalarModification(String newName) { + if (!scalarDifferences.containsKey(newName)) { + scalarDifferences.put(newName, new ScalarModification(newName)); + } + assertTrue(scalarDifferences.get(newName) instanceof ScalarModification); + return (ScalarModification) scalarDifferences.get(newName); + } + + + private void addedObject(EditOperation editOperation) { + String objectName = editOperation.getTargetVertex().getName(); + ObjectAddition objectAddition = new ObjectAddition(objectName); + objectDifferences.put(objectName, objectAddition); + } + + private void addedInterface(EditOperation editOperation) { + String objectName = editOperation.getTargetVertex().getName(); + + InterfaceAddition interfaceAddition = new InterfaceAddition(objectName); + interfaceDifferences.put(objectName, interfaceAddition); + } + + private void addedUnion(EditOperation editOperation) { + String unionName = editOperation.getTargetVertex().getName(); + + UnionAddition addition = new UnionAddition(unionName); + unionDifferences.put(unionName, addition); + } + + private void addedInputObject(EditOperation editOperation) { + String inputObjectName = editOperation.getTargetVertex().getName(); + + InputObjectAddition addition = new InputObjectAddition(inputObjectName); + inputObjectDifferences.put(inputObjectName, addition); + } + + private void addedEnum(EditOperation editOperation) { + String enumName = editOperation.getTargetVertex().getName(); + + EnumAddition enumAddition = new EnumAddition(enumName); + enumDifferences.put(enumName, enumAddition); + } + + private void addedScalar(EditOperation editOperation) { + String scalarName = editOperation.getTargetVertex().getName(); + // build in scalars can appear as added when not used in the old schema, but + // we don't want to register them as new Scalars + if (ScalarInfo.isGraphqlSpecifiedScalar(scalarName)) { + return; + } + + ScalarAddition addition = new ScalarAddition(scalarName); + scalarDifferences.put(scalarName, addition); + } + + private void addedDirective(EditOperation editOperation) { + String directiveName = editOperation.getTargetVertex().getName(); + + DirectiveAddition addition = new DirectiveAddition(directiveName); + directiveDifferences.put(directiveName, addition); + } + + + private void removedObject(EditOperation editOperation) { + String objectName = editOperation.getSourceVertex().getName(); + + ObjectDeletion change = new ObjectDeletion(objectName); + objectDifferences.put(objectName, change); + } + + private void removedInterface(EditOperation editOperation) { + String interfaceName = editOperation.getSourceVertex().getName(); + + InterfaceDeletion change = new InterfaceDeletion(interfaceName); + interfaceDifferences.put(interfaceName, change); + } + + private void removedUnion(EditOperation editOperation) { + String unionName = editOperation.getSourceVertex().getName(); + + UnionDeletion change = new UnionDeletion(unionName); + unionDifferences.put(unionName, change); + } + + private void removedInputObject(EditOperation editOperation) { + String name = editOperation.getSourceVertex().getName(); + + InputObjectDeletion change = new InputObjectDeletion(name); + inputObjectDifferences.put(name, change); + } + + private void removedEnum(EditOperation editOperation) { + String enumName = editOperation.getSourceVertex().getName(); + + EnumDeletion deletion = new EnumDeletion(enumName); + enumDifferences.put(enumName, deletion); + } + + private void deletedScalar(EditOperation editOperation) { + String scalarName = editOperation.getSourceVertex().getName(); + + ScalarDeletion change = new ScalarDeletion(scalarName); + scalarDifferences.put(scalarName, change); + } + + private void deletedDirective(EditOperation editOperation) { + String directiveName = editOperation.getSourceVertex().getName(); + + DirectiveDeletion change = new DirectiveDeletion(directiveName); + directiveDifferences.put(directiveName, change); + } + + private void argumentDeleted(EditOperation editOperation) { + // Note: sometimes the edit operation is the argument vertex itself being deleted + // Other times, it is the edge to the argument type being deleted + Vertex deletedArgument = editOperation.getSourceVertex(); + if (deletedArgument == null) { + deletedArgument = editOperation.getSourceEdge().getTo(); + } + + Vertex fieldOrDirective = oldSchemaGraph.getFieldOrDirectiveForArgument(deletedArgument); + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex fieldsContainerForField = oldSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainerForField.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainerForField; + if (isObjectDeleted(object.getName())) { + return; + } + if (isFieldDeletedFromExistingObject(object.getName(), field.getName())) { + return; + } + if (isArgumentDeletedFromExistingObjectField(object.getName(), field.getName(), deletedArgument.getName())) { + return; + } + getObjectModification(object.getName()).getDetails().add(new ObjectFieldArgumentDeletion(field.getName(), deletedArgument.getName())); + } else { + assertTrue(fieldsContainerForField.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = fieldsContainerForField; + if (isInterfaceDeleted(interfaze.getName())) { + return; + } + if (isFieldDeletedFromExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isArgumentDeletedFromExistingInterfaceField(interfaze.getName(), field.getName(), deletedArgument.getName())) { + return; + } + getInterfaceModification(interfaze.getName()).getDetails().add(new InterfaceFieldArgumentDeletion(field.getName(), deletedArgument.getName())); + } + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)); + Vertex directive = fieldOrDirective; + if (isDirectiveDeleted(directive.getName())) { + return; + } + if (isArgumentDeletedFromExistingDirective(directive.getName(), deletedArgument.getName())) { + return; + } + getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentDeletion(deletedArgument.getName())); + } + } + + private void argumentAdded(EditOperation editOperation) { + Vertex addedArgument = editOperation.getTargetVertex(); + if (addedArgument == null) { + addedArgument = editOperation.getTargetEdge().getTo(); + } + + Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(addedArgument); + + if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) { + Vertex field = fieldOrDirective; + Vertex fieldsContainerForField = newSchemaGraph.getFieldsContainerForField(field); + if (fieldsContainerForField.isOfType(SchemaGraph.OBJECT)) { + Vertex object = fieldsContainerForField; + if (isObjectAdded(object.getName())) { + return; + } + if (isFieldNewForExistingObject(object.getName(), field.getName())) { + return; + } + if (isArgumentNewForExistingObjectField(object.getName(), field.getName(), addedArgument.getName())) { + return; + } + getObjectModification(object.getName()).getDetails().add(new ObjectFieldArgumentAddition(field.getName(), addedArgument.getName())); + } else { + assertTrue(fieldsContainerForField.isOfType(SchemaGraph.INTERFACE)); + Vertex interfaze = fieldsContainerForField; + if (isInterfaceAdded(interfaze.getName())) { + return; + } + if (isFieldNewForExistingInterface(interfaze.getName(), field.getName())) { + return; + } + if (isArgumentNewForExistingInterfaceField(interfaze.getName(), field.getName(), addedArgument.getName())) { + return; + } + getInterfaceModification(interfaze.getName()).getDetails().add(new InterfaceFieldArgumentAddition(field.getName(), addedArgument.getName())); + } + } else { + assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE)); + Vertex directive = fieldOrDirective; + if (isDirectiveAdded(directive.getName())) { + return; + } + if (isArgumentNewForExistingDirective(directive.getName(), addedArgument.getName())) { + return; + } + getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentAddition(addedArgument.getName())); + } + } + + private void changedEnum(EditOperation editOperation) { + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + EnumModification modification = new EnumModification(oldName, newName); + enumDifferences.put(oldName, modification); + enumDifferences.put(newName, modification); + } + + private void changedScalar(EditOperation editOperation) { + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + ScalarModification modification = new ScalarModification(oldName, newName); + scalarDifferences.put(oldName, modification); + scalarDifferences.put(newName, modification); + } + + private void changedInputObject(EditOperation editOperation) { + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + InputObjectModification modification = new InputObjectModification(oldName, newName); + inputObjectDifferences.put(oldName, modification); + inputObjectDifferences.put(newName, modification); + } + + private void changedDirective(EditOperation editOperation) { + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + DirectiveModification modification = new DirectiveModification(oldName, newName); + directiveDifferences.put(oldName, modification); + directiveDifferences.put(newName, modification); + } + + private void changedObject(EditOperation editOperation) { + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + ObjectModification objectModification = new ObjectModification(oldName, newName); + objectDifferences.put(oldName, objectModification); + objectDifferences.put(newName, objectModification); + } + + private void changedInterface(EditOperation editOperation) { + String oldName = editOperation.getSourceVertex().getName(); + String newName = editOperation.getTargetVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + InterfaceModification interfaceModification = new InterfaceModification(oldName, newName); + interfaceDifferences.put(oldName, interfaceModification); + interfaceDifferences.put(newName, interfaceModification); + } + + private void changedUnion(EditOperation editOperation) { + String newName = editOperation.getTargetVertex().getName(); + String oldName = editOperation.getSourceVertex().getName(); + + if (oldName.equals(newName)) { + // Something else like description could have changed + return; + } + + UnionModification objectModification = new UnionModification(oldName, newName); + unionDifferences.put(oldName, objectModification); + unionDifferences.put(newName, objectModification); + } + + /** + * The order to traverse edit operations according to the operation. + * + * @see #getTraversalOrder(List) + */ + private static final List OPERATION_TRAVERSAL_ORDER = List.of( + EditOperation.Operation.CHANGE_VERTEX, + EditOperation.Operation.INSERT_VERTEX, + EditOperation.Operation.DELETE_VERTEX, + EditOperation.Operation.CHANGE_EDGE, + EditOperation.Operation.INSERT_EDGE, + EditOperation.Operation.DELETE_EDGE + ); + + /** + * The order to traverse edit operations according to the vertex types involved. + * + * @see #getTraversalOrder(List) + */ + private static final List TYPE_TRAVERSAL_ORDER = List.of( + // These are all top level declarations + SchemaGraph.SCHEMA, + SchemaGraph.OBJECT, + SchemaGraph.INTERFACE, + SchemaGraph.UNION, + SchemaGraph.SCALAR, + SchemaGraph.ENUM, + SchemaGraph.INPUT_OBJECT, + SchemaGraph.DIRECTIVE, + // These are all direct descendants of top level declarations + SchemaGraph.FIELD, + SchemaGraph.INPUT_FIELD, + SchemaGraph.ENUM_VALUE, + // Everything else + SchemaGraph.ARGUMENT, + SchemaGraph.APPLIED_DIRECTIVE, + SchemaGraph.APPLIED_ARGUMENT, + SchemaGraph.ISOLATED + ); + + /** + * The input list of {@link EditOperation}s does not conform to any order. + *

+ * We need to sort it as we sometimes rely on the parents being processed first. + *

+ * e.g. we ignore a new argument if the parent of the argument is new. + * However, if the argument addition is processed before the + */ + @VisibleForTesting + static List getTraversalOrder(List editOperations) { + ArrayList sorted = new ArrayList<>(editOperations); + + sorted.sort( + Comparator + .comparingInt((editOperation) -> { + int i = OPERATION_TRAVERSAL_ORDER.indexOf(editOperation.getOperation()); + if (i < 0) { + return Assert.assertShouldNeverHappen("Unknown operation: " + editOperation.getOperation()); + } + return i; + }) + .thenComparing((editOperation) -> { + // Converts this editOperation into an index from the order + // The lower the index, the earlier it appears in the sorted list + for (int i = 0; i < TYPE_TRAVERSAL_ORDER.size(); i++) { + String type = TYPE_TRAVERSAL_ORDER.get(i); + + if (isAnyVertexOfType(editOperation, type)) { + return i; + } + } + + return Assert.assertShouldNeverHappen("Unable to determine edit operation subject for: " + editOperation); + }) + ); + + return sorted; + } + + private static boolean isAnyVertexOfType(EditOperation edit, String type) { + return (edit.getSourceVertex() != null && edit.getSourceVertex().isOfType(type)) + || (edit.getTargetVertex() != null && edit.getTargetVertex().isOfType(type)) + || (edit.getSourceEdge() != null && isAnyVertexOfType(edit.getSourceEdge(), type)) + || (edit.getTargetEdge() != null && isAnyVertexOfType(edit.getTargetEdge(), type)); + } + + private static boolean isAnyVertexOfType(Edge edge, String type) { + return edge.getFrom().isOfType(type) || edge.getTo().isOfType(type); + } +} diff --git a/src/main/java/graphql/schema/diffing/ana/SchemaDifference.java b/src/main/java/graphql/schema/diffing/ana/SchemaDifference.java new file mode 100644 index 0000000000..d6a2c8e494 --- /dev/null +++ b/src/main/java/graphql/schema/diffing/ana/SchemaDifference.java @@ -0,0 +1,1722 @@ +package graphql.schema.diffing.ana; + +import graphql.Internal; +import graphql.util.FpKit; + +import java.util.ArrayList; +import java.util.List; + +/** + * Any kind of difference between two schemas is a SchemaDifference. + *

+ * Below that we have three different possible kind of differences: + * - Addition + * - Deletion + * - Modification + */ +@Internal +public interface SchemaDifference { + + interface SchemaAddition extends SchemaDifference { + + } + + interface SchemaDeletion extends SchemaDifference { + + } + + interface SchemaModification extends SchemaDifference { + + } + + interface SchemaModificationDetail extends SchemaDifference { + + } + + //------------ Object + public + interface ObjectDifference extends SchemaDifference { + + } + + class ObjectAddition implements SchemaAddition, ObjectDifference { + private final String name; + + public ObjectAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ObjectDeletion implements SchemaDeletion, ObjectDifference { + private final String name; + + public ObjectDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ObjectModification implements SchemaModification, ObjectDifference { + private final String oldName; + private final String newName; + private final boolean isNameChanged; + private final List details = new ArrayList<>(); + + public ObjectModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public ObjectModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + public List getDetails() { + return details; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + + public String getOldName() { + return oldName; + } + + public String getNewName() { + return newName; + } + + public boolean isNameChanged() { + return isNameChanged; + } + } + + interface ObjectModificationDetail { + + } + + class ObjectInterfaceImplementationAddition implements ObjectModificationDetail { + private final String name; + + public ObjectInterfaceImplementationAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ObjectInterfaceImplementationDeletion implements ObjectModificationDetail { + private final String name; + + public ObjectInterfaceImplementationDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ObjectFieldAddition implements ObjectModificationDetail { + private final String name; + + public ObjectFieldAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ObjectFieldDeletion implements ObjectModificationDetail { + private final String name; + + public ObjectFieldDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ObjectFieldRename implements ObjectModificationDetail { + private final String oldName; + private final String newName; + + public ObjectFieldRename(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + } + + class ObjectFieldArgumentRename implements ObjectModificationDetail { + private final String fieldName; + private final String oldName; + private final String newName; + + public ObjectFieldArgumentRename(String fieldName, String oldName, String newName) { + this.fieldName = fieldName; + this.oldName = oldName; + this.newName = newName; + } + + public String getFieldName() { + return fieldName; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + } + + class ObjectFieldTypeModification implements ObjectModificationDetail { + private final String fieldName; + private final String oldType; + private final String newType; + + public ObjectFieldTypeModification(String fieldName, String oldType, String newType) { + this.fieldName = fieldName; + this.oldType = oldType; + this.newType = newType; + } + + public String getFieldName() { + return fieldName; + } + + public String getNewType() { + return newType; + } + + public String getOldType() { + return oldType; + } + } + + class ObjectFieldArgumentDeletion implements ObjectModificationDetail { + private final String fieldName; + private final String name; + + public ObjectFieldArgumentDeletion(String fieldName, String name) { + this.fieldName = fieldName; + this.name = name; + } + + public String getName() { + return name; + } + + public String getFieldName() { + return fieldName; + } + } + + class ObjectFieldArgumentAddition implements ObjectModificationDetail { + private final String fieldName; + private final String name; + + + public ObjectFieldArgumentAddition(String fieldName, String name) { + this.fieldName = fieldName; + this.name = name; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return name; + } + } + + class ObjectFieldArgumentTypeModification implements ObjectModificationDetail { + private final String fieldName; + private final String argumentName; + private final String oldType; + private final String newType; + + public ObjectFieldArgumentTypeModification(String fieldName, String argumentName, String oldType, String newType) { + this.fieldName = fieldName; + this.argumentName = argumentName; + this.oldType = oldType; + this.newType = newType; + } + + public String getNewType() { + return newType; + } + + public String getOldType() { + return oldType; + } + + public String getFieldName() { + return fieldName; + } + + public String getArgumentName() { + return argumentName; + } + } + + class ObjectFieldArgumentDefaultValueModification implements ObjectModificationDetail { + private final String fieldName; + private final String argumentName; + private final String oldValue; + private final String newValue; + + public ObjectFieldArgumentDefaultValueModification(String fieldName, String argumentName, String oldValue, String newValue) { + this.fieldName = fieldName; + this.argumentName = argumentName; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public String getOldValue() { + return oldValue; + } + + public String getNewValue() { + return newValue; + } + + public String getFieldName() { + return fieldName; + } + + public String getArgumentName() { + return argumentName; + } + } + + //------------ Interface + interface InterfaceDifference extends SchemaDifference { + + } + + class InterfaceAddition implements SchemaAddition, InterfaceDifference { + private final String name; + + public InterfaceAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InterfaceDeletion implements SchemaDeletion, InterfaceDifference { + private final String name; + + public InterfaceDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InterfaceModification implements SchemaModification, InterfaceDifference { + private final String oldName; + private final String newName; + private final boolean isNameChanged; + private final List details = new ArrayList<>(); + + public InterfaceModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public InterfaceModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + public List getDetails() { + return details; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + + public boolean isNameChanged() { + return isNameChanged; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + } + + interface InterfaceModificationDetail { + + } + + class InterfaceInterfaceImplementationAddition implements InterfaceModificationDetail { + private final String name; + + public InterfaceInterfaceImplementationAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InterfaceInterfaceImplementationDeletion implements InterfaceModificationDetail { + private final String name; + + public InterfaceInterfaceImplementationDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InterfaceFieldAddition implements InterfaceModificationDetail { + private final String name; + + public InterfaceFieldAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InterfaceFieldDeletion implements InterfaceModificationDetail { + private final String name; + + public InterfaceFieldDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InterfaceFieldRename implements InterfaceModificationDetail { + private final String oldName; + private final String newName; + + public InterfaceFieldRename(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + } + + + class InterfaceFieldTypeModification implements InterfaceModificationDetail { + private final String fieldName; + private final String oldType; + private final String newType; + + public InterfaceFieldTypeModification(String fieldName, String oldType, String newType) { + this.fieldName = fieldName; + this.oldType = oldType; + this.newType = newType; + } + + public String getFieldName() { + return fieldName; + } + + public String getNewType() { + return newType; + } + + public String getOldType() { + return oldType; + } + } + + class InterfaceFieldArgumentDeletion implements InterfaceModificationDetail { + private final String fieldName; + private final String name; + + + public InterfaceFieldArgumentDeletion(String fieldName, String name) { + this.fieldName = fieldName; + this.name = name; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return name; + } + } + + class InterfaceFieldArgumentAddition implements InterfaceModificationDetail { + private final String fieldName; + private final String name; + + public InterfaceFieldArgumentAddition(String fieldName, String name) { + this.fieldName = fieldName; + this.name = name; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return name; + } + } + + class InterfaceFieldArgumentTypeModification implements InterfaceModificationDetail { + + private final String fieldName; + private final String argumentName; + private final String oldType; + private final String newType; + + public InterfaceFieldArgumentTypeModification(String fieldName, String argumentName, String oldType, String newType) { + this.fieldName = fieldName; + this.argumentName = argumentName; + this.oldType = oldType; + this.newType = newType; + } + + public String getFieldName() { + return fieldName; + } + + public String getNewType() { + return newType; + } + + public String getOldType() { + return oldType; + } + + public String getArgumentName() { + return argumentName; + } + + } + + class InterfaceFieldArgumentDefaultValueModification implements InterfaceModificationDetail { + private final String fieldName; + private final String argumentName; + private final String oldValue; + private final String newValue; + + + public InterfaceFieldArgumentDefaultValueModification(String fieldName, String argumentName, String oldValue, String newValue) { + this.fieldName = fieldName; + this.argumentName = argumentName; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public String getOldValue() { + return oldValue; + } + + public String getNewValue() { + return newValue; + } + + public String getFieldName() { + return fieldName; + } + + public String getArgumentName() { + return argumentName; + } + } + + class InterfaceFieldArgumentRename implements InterfaceModificationDetail { + private final String fieldName; + private final String oldName; + private final String newName; + + public InterfaceFieldArgumentRename(String fieldName, String oldName, String newName) { + this.fieldName = fieldName; + this.oldName = oldName; + this.newName = newName; + } + + public String getFieldName() { + return fieldName; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + } + + + // -----Union----------- + interface UnionDifference extends SchemaDifference { + + } + + class UnionAddition implements SchemaAddition, UnionDifference { + private final String name; + + public UnionAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class UnionDeletion implements SchemaDeletion, UnionDifference { + private final String name; + + public UnionDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class UnionModification implements SchemaModification, UnionDifference { + private final String oldName; + private final String newName; + private final boolean isNameChanged; + + private final List details = new ArrayList<>(); + + public UnionModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public UnionModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + + public List getDetails() { + return details; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + + public boolean isNameChanged() { + return isNameChanged; + } + } + + interface UnionModificationDetail { + + } + + class UnionMemberAddition implements UnionModificationDetail { + private final String name; + + public UnionMemberAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class UnionMemberDeletion implements UnionModificationDetail { + private final String name; + + public UnionMemberDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + //--------InputObject + + interface InputObjectDifference extends SchemaDifference { + + } + + class InputObjectAddition implements SchemaAddition, InputObjectDifference { + private final String name; + + public InputObjectAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InputObjectDeletion implements SchemaDeletion, InputObjectDifference { + private final String name; + + public InputObjectDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + interface InputObjectModificationDetail { + + } + + class InputObjectFieldDeletion implements InputObjectModificationDetail { + private final String name; + + public InputObjectFieldDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InputObjectFieldRename implements InputObjectModificationDetail { + private final String oldName; + private final String newName; + + public InputObjectFieldRename(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + } + + public String getOldName() { + return oldName; + } + + public String getNewName() { + return newName; + } + } + + class InputObjectFieldDefaultValueModification implements InputObjectModificationDetail { + private final String fieldName; + private final String oldDefaultValue; + private final String newDefaultValue; + + public InputObjectFieldDefaultValueModification(String fieldName, String oldDefaultValue, String newDefaultValue) { + this.fieldName = fieldName; + this.oldDefaultValue = oldDefaultValue; + this.newDefaultValue = newDefaultValue; + } + + public String getFieldName() { + return fieldName; + } + + public String getOldDefaultValue() { + return oldDefaultValue; + } + + public String getNewDefaultValue() { + return newDefaultValue; + } + } + + class InputObjectFieldTypeModification implements InputObjectModificationDetail { + private final String fieldName; + private final String oldType; + private final String newType; + + public InputObjectFieldTypeModification(String fieldName, String oldType, String newType) { + this.fieldName = fieldName; + this.oldType = oldType; + this.newType = newType; + } + + public String getFieldName() { + return fieldName; + } + + public String getOldType() { + return oldType; + } + + public String getNewType() { + return newType; + } + } + + class InputObjectFieldAddition implements InputObjectModificationDetail { + private final String name; + + public InputObjectFieldAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class InputObjectModification implements SchemaModification, InputObjectDifference { + private final String oldName; + private final String newName; + private final boolean isNameChanged; + + private final List details = new ArrayList<>(); + + + public InputObjectModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public InputObjectModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + public boolean isNameChanged() { + return isNameChanged; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + + public List getDetails() { + return details; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + + } + + //-------Enum + interface EnumDifference extends SchemaDifference { + + } + + class EnumAddition implements SchemaAddition, EnumDifference { + private final String name; + + public EnumAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class EnumDeletion implements SchemaDeletion, EnumDifference { + private final String name; + + public EnumDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class EnumModification implements SchemaModification, EnumDifference { + private final String oldName; + private final String newName; + + private final boolean isNameChanged; + private final List details = new ArrayList<>(); + + public EnumModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public EnumModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + public boolean isNameChanged() { + return isNameChanged; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + + public List getDetails() { + return details; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + + } + + interface EnumModificationDetail { + + } + + class EnumValueDeletion implements EnumModificationDetail { + private final String name; + + public EnumValueDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class EnumValueRenamed implements EnumModificationDetail { + private final String oldName; + private final String newName; + + public EnumValueRenamed(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + } + + public String getOldName() { + return oldName; + } + + public String getNewName() { + return newName; + } + } + + class EnumValueAddition implements EnumModificationDetail { + private final String name; + + public EnumValueAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + //--------Scalar + interface ScalarDifference extends SchemaDifference { + + } + + class ScalarAddition implements SchemaAddition, ScalarDifference { + private final String name; + + public ScalarAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ScalarDeletion implements SchemaDeletion, ScalarDifference { + private final String name; + + public ScalarDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + interface ScalarModificationDetail { + + } + + class ScalarModification implements SchemaModification, ScalarDifference { + private final String oldName; + private final String newName; + private final boolean isNameChanged; + private List details = new ArrayList<>(); + + + public ScalarModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public ScalarModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + + public boolean isNameChanged() { + return isNameChanged; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + + public List getDetails() { + return details; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + + } + + //------Directive + interface DirectiveDifference extends SchemaDifference { + + } + + class DirectiveAddition implements SchemaAddition, DirectiveDifference { + private final String name; + + public DirectiveAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class DirectiveDeletion implements SchemaDeletion, DirectiveDifference { + private final String name; + + public DirectiveDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class DirectiveModification implements SchemaModification, DirectiveDifference { + private final String oldName; + private final String newName; + private final boolean isNameChanged; + + private final List details = new ArrayList<>(); + + public DirectiveModification(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + this.isNameChanged = !oldName.equals(newName); + } + + public DirectiveModification(String newName) { + this.oldName = newName; + this.newName = newName; + this.isNameChanged = false; + } + + public boolean isNameChanged() { + return isNameChanged; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + + public List getDetails() { + return details; + } + + public List getDetails(Class clazz) { + return (List) FpKit.filterList(details, clazz::isInstance); + } + } + + interface DirectiveModificationDetail { + + } + + class DirectiveArgumentDeletion implements DirectiveModificationDetail { + private final String name; + + public DirectiveArgumentDeletion(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + + class DirectiveArgumentAddition implements DirectiveModificationDetail { + private final String name; + + public DirectiveArgumentAddition(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class DirectiveArgumentTypeModification implements DirectiveModificationDetail { + private final String argumentName; + private final String oldType; + private final String newType; + + + public DirectiveArgumentTypeModification(String argumentName, String oldType, String newType) { + this.argumentName = argumentName; + this.oldType = oldType; + this.newType = newType; + } + + public String getArgumentName() { + return argumentName; + } + + public String getNewType() { + return newType; + } + + public String getOldType() { + return oldType; + } + } + + class DirectiveArgumentDefaultValueModification implements DirectiveModificationDetail { + private final String argumentName; + private final String oldValue; + private final String newValue; + + public DirectiveArgumentDefaultValueModification(String argumentName, String oldValue, String newValue) { + this.argumentName = argumentName; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public String getOldValue() { + return oldValue; + } + + public String getNewValue() { + return newValue; + } + + public String getArgumentName() { + return argumentName; + } + } + + class DirectiveArgumentRename implements DirectiveModificationDetail { + private final String oldName; + private final String newName; + + public DirectiveArgumentRename(String oldName, String newName) { + this.oldName = oldName; + this.newName = newName; + } + + public String getNewName() { + return newName; + } + + public String getOldName() { + return oldName; + } + } + + //------Applied Directives + interface AppliedDirectiveDifference { + + } + + /** + * SCHEMA, + * SCALAR, + * OBJECT, + * FIELD_DEFINITION, + * ARGUMENT_DEFINITION, + * INTERFACE, + * UNION, + * ENUM, + * ENUM_VALUE, + * INPUT_OBJECT, + * INPUT_FIELD_DEFINITION + */ + + interface AppliedDirectiveLocationDetail { + + } + + class AppliedDirectiveObjectFieldLocation implements AppliedDirectiveLocationDetail { + private final String objectName; + private final String fieldName; + private final String directiveName; + + public AppliedDirectiveObjectFieldLocation(String objectName, String fieldName, String directiveName) { + this.objectName = objectName; + this.fieldName = fieldName; + this.directiveName = directiveName; + } + + public String getFieldName() { + return fieldName; + } + + public String getObjectName() { + return objectName; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveInterfaceFieldLocation implements AppliedDirectiveLocationDetail { + private final String interfaceName; + private final String fieldName; + + private final String directiveName; + + + public AppliedDirectiveInterfaceFieldLocation(String interfaceName, String fieldName, String directiveName) { + this.interfaceName = interfaceName; + this.fieldName = fieldName; + this.directiveName = directiveName; + } + + public String getFieldName() { + return fieldName; + } + + public String getInterfaceName() { + return interfaceName; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveScalarLocation implements AppliedDirectiveLocationDetail { + private final String name; + + private final String directiveName; + + public AppliedDirectiveScalarLocation(String name, String directiveName) { + this.name = name; + this.directiveName = directiveName; + } + + public String getName() { + return name; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveSchemaLocation implements AppliedDirectiveLocationDetail { + + } + + class AppliedDirectiveObjectLocation implements AppliedDirectiveLocationDetail { + private final String name; + private final String directiveName; + + + public AppliedDirectiveObjectLocation(String name, String directiveName) { + this.name = name; + this.directiveName = directiveName; + } + + public String getName() { + return name; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveInterfaceLocation implements AppliedDirectiveLocationDetail { + private final String name; + private final String directiveName; + + public AppliedDirectiveInterfaceLocation(String name, String directiveName) { + this.name = name; + this.directiveName = directiveName; + } + + public String getName() { + return name; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveObjectFieldArgumentLocation implements AppliedDirectiveLocationDetail { + private final String objectName; + private final String fieldName; + private final String argumentName; + private final String directiveName; + + + public AppliedDirectiveObjectFieldArgumentLocation(String objectName, String fieldName, String argumentName, String directiveName) { + this.objectName = objectName; + this.fieldName = fieldName; + this.argumentName = argumentName; + this.directiveName = directiveName; + } + + public String getObjectName() { + return objectName; + } + + public String getFieldName() { + return fieldName; + } + + public String getArgumentName() { + return argumentName; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveDirectiveArgumentLocation implements AppliedDirectiveLocationDetail { + // this is the applied directive name + private final String directiveName; + private final String directiveDefinitionName; + private final String argumentName; + + public AppliedDirectiveDirectiveArgumentLocation(String directiveDefinitionName, String argumentName, String directiveName) { + this.directiveDefinitionName = directiveDefinitionName; + this.argumentName = argumentName; + this.directiveName = directiveName; + } + + public String getDirectiveName() { + return directiveName; + } + + public String getArgumentName() { + return argumentName; + } + + public String getDirectiveDefinitionName() { + return directiveDefinitionName; + } + } + + class AppliedDirectiveInterfaceFieldArgumentLocation implements AppliedDirectiveLocationDetail { + private final String interfaceName; + private final String fieldName; + private final String argumentName; + private final String directiveName; + + + public AppliedDirectiveInterfaceFieldArgumentLocation(String interfaceName, String fieldName, String argumentName, String directiveName) { + this.interfaceName = interfaceName; + this.fieldName = fieldName; + this.argumentName = argumentName; + this.directiveName = directiveName; + } + + public String getInterfaceName() { + return interfaceName; + } + + public String getFieldName() { + return fieldName; + } + + public String getArgumentName() { + return argumentName; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveUnionLocation implements AppliedDirectiveLocationDetail { + private final String name; + private final String directiveName; + + + public AppliedDirectiveUnionLocation(String name, String directiveName) { + this.name = name; + this.directiveName = directiveName; + } + + public String getName() { + return name; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveEnumLocation implements AppliedDirectiveLocationDetail { + private final String name; + private final String directiveName; + + + public AppliedDirectiveEnumLocation(String name, String directiveName) { + this.name = name; + this.directiveName = directiveName; + } + + public String getName() { + return name; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveEnumValueLocation implements AppliedDirectiveLocationDetail { + private final String enumName; + private final String valueName; + private final String directiveName; + + + public AppliedDirectiveEnumValueLocation(String enumName, String valueName, String directiveName) { + this.enumName = enumName; + this.valueName = valueName; + this.directiveName = directiveName; + } + + public String getEnumName() { + return enumName; + } + + public String getValueName() { + return valueName; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveInputObjectLocation implements AppliedDirectiveLocationDetail { + private final String name; + private final String directiveName; + + + public AppliedDirectiveInputObjectLocation(String name, String directiveName) { + this.name = name; + this.directiveName = directiveName; + } + + public String getName() { + return name; + } + + public String getDirectiveName() { + return directiveName; + } + } + + + class AppliedDirectiveInputObjectFieldLocation implements AppliedDirectiveLocationDetail { + private final String inputObjectName; + private final String fieldName; + private final String directiveName; + + + public AppliedDirectiveInputObjectFieldLocation(String inputObjectName, String fieldName, String directiveName) { + this.inputObjectName = inputObjectName; + this.fieldName = fieldName; + this.directiveName = directiveName; + } + + public String getInputObjectName() { + return inputObjectName; + } + + public String getFieldName() { + return fieldName; + } + + public String getDirectiveName() { + return directiveName; + } + } + + class AppliedDirectiveAddition implements + ObjectModificationDetail, + InterfaceModificationDetail, + ScalarModificationDetail, + EnumModificationDetail, + InputObjectModificationDetail, + UnionModificationDetail, + DirectiveModificationDetail { + private final AppliedDirectiveLocationDetail locationDetail; + private final String name; + + public AppliedDirectiveAddition(AppliedDirectiveLocationDetail locationDetail, String name) { + this.locationDetail = locationDetail; + this.name = name; + } + + public String getName() { + return name; + } + + public AppliedDirectiveLocationDetail getLocationDetail() { + return locationDetail; + } + } + + class AppliedDirectiveDeletion implements + ObjectModificationDetail, + InterfaceModificationDetail, + ScalarModificationDetail, + EnumModificationDetail, + InputObjectModificationDetail, + UnionModificationDetail, + DirectiveModificationDetail { + + private final AppliedDirectiveLocationDetail locationDetail; + private final String name; + + public AppliedDirectiveDeletion(AppliedDirectiveLocationDetail locationDetail, String name) { + this.locationDetail = locationDetail; + this.name = name; + } + + public String getName() { + return name; + } + + public AppliedDirectiveLocationDetail getLocationDetail() { + return locationDetail; + } + + + } + + class AppliedDirectiveRenamed { + + } + + class AppliedDirectiveArgumentAddition implements ObjectModificationDetail, + InterfaceModificationDetail, + ScalarModificationDetail, + EnumModificationDetail, + UnionModificationDetail, + InputObjectModificationDetail, + DirectiveModificationDetail { + private final AppliedDirectiveLocationDetail locationDetail; + private final String argumentName; + + public AppliedDirectiveArgumentAddition(AppliedDirectiveLocationDetail locationDetail, String argumentName) { + this.locationDetail = locationDetail; + this.argumentName = argumentName; + } + + public AppliedDirectiveLocationDetail getLocationDetail() { + return locationDetail; + } + + public String getArgumentName() { + return argumentName; + } + } + + class AppliedDirectiveArgumentDeletion implements ObjectModificationDetail, + InterfaceModificationDetail, + ScalarModificationDetail, + EnumModificationDetail, + UnionModificationDetail, + InputObjectModificationDetail, + DirectiveModificationDetail { + private final AppliedDirectiveLocationDetail locationDetail; + private final String argumentName; + + public AppliedDirectiveArgumentDeletion(AppliedDirectiveLocationDetail locationDetail, String argumentName) { + this.locationDetail = locationDetail; + this.argumentName = argumentName; + } + + public AppliedDirectiveLocationDetail getLocationDetail() { + return locationDetail; + } + + public String getArgumentName() { + return argumentName; + } + } + + + class AppliedDirectiveArgumentValueModification implements ObjectModificationDetail, + InterfaceModificationDetail, + InputObjectModificationDetail, + EnumModificationDetail, + UnionModificationDetail, + ScalarModificationDetail, + DirectiveModificationDetail { + private final AppliedDirectiveLocationDetail locationDetail; + private final String argumentName; + private final String oldValue; + private final String newValue; + + public AppliedDirectiveArgumentValueModification(AppliedDirectiveLocationDetail locationDetail, String argumentName, String oldValue, String newValue) { + this.locationDetail = locationDetail; + this.argumentName = argumentName; + this.oldValue = oldValue; + this.newValue = newValue; + } + + public AppliedDirectiveLocationDetail getLocationDetail() { + return locationDetail; + } + + public String getArgumentName() { + return argumentName; + } + + public String getOldValue() { + return oldValue; + } + + public String getNewValue() { + return newValue; + } + } + + class AppliedDirectiveArgumentRename implements ObjectModificationDetail, InterfaceModificationDetail { + private final AppliedDirectiveLocationDetail locationDetail; + private final String oldName; + private final String newName; + + public AppliedDirectiveArgumentRename(AppliedDirectiveLocationDetail locationDetail, String oldName, String newName) { + this.locationDetail = locationDetail; + this.oldName = oldName; + this.newName = newName; + } + + public AppliedDirectiveLocationDetail getLocationDetail() { + return locationDetail; + } + + public String getOldName() { + return oldName; + } + + public String getNewName() { + return newName; + } + } + + +} diff --git a/src/main/java/graphql/schema/fetching/LambdaFetchingSupport.java b/src/main/java/graphql/schema/fetching/LambdaFetchingSupport.java new file mode 100644 index 0000000000..5ff38f5756 --- /dev/null +++ b/src/main/java/graphql/schema/fetching/LambdaFetchingSupport.java @@ -0,0 +1,227 @@ +package graphql.schema.fetching; + +import graphql.Internal; +import graphql.VisibleForTesting; +import graphql.util.FpKit; + +import java.lang.invoke.CallSite; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; + +@Internal +public class LambdaFetchingSupport { + + + /** + * This support class will use {@link LambdaMetafactory} and {@link MethodHandles} to create a dynamic function that allows access to a public + * getter method on the nominated class. {@link MethodHandles} is a caller senstive lookup mechanism. If the graphql-java cant lookup a class, then + * it won't be able to make dynamic lambda function to it. + *

+ * If one cant be made, because it doesn't exist or the calling class does not have access to the method, then it will return + * an empty result indicating that this strategy cant be used. + * + * @param sourceClass the class that has the property getter method + * @param propertyName the name of the property to get + * + * @return a function that can be used to pass in an instance of source class and returns its getter method value + */ + public static Optional> createGetter(Class sourceClass, String propertyName) { + Method candidateMethod = getCandidateMethod(sourceClass, propertyName); + if (candidateMethod != null) { + try { + Function getterFunction = mkCallFunction(sourceClass, candidateMethod.getName(), candidateMethod.getReturnType()); + return Optional.of(getterFunction); + } catch (Throwable ignore) { + // + // if we cant make a dynamic lambda here, then we give up and let the old property fetching code do its thing + // this can happen on runtimes such as GraalVM native where LambdaMetafactory is not supported + // and will throw something like : + // + // com.oracle.svm.core.jdk.UnsupportedFeatureError: Defining hidden classes at runtime is not supported. + // at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89) + } + } + return Optional.empty(); + } + + + private static Method getCandidateMethod(Class sourceClass, String propertyName) { + // property() methods first + Predicate recordLikePredicate = method -> isRecordLike(method) && propertyName.equals(decapitalize(method.getName())); + List recordLikeMethods = findMethodsForProperty(sourceClass, + recordLikePredicate); + if (!recordLikeMethods.isEmpty()) { + return recordLikeMethods.get(0); + } + + // getProperty() POJO methods next + Predicate getterPredicate = method -> isGetterNamed(method) && propertyName.equals(mkPropertyNameGetter(method)); + List allGetterMethods = findMethodsForProperty(sourceClass, + getterPredicate); + List pojoGetterMethods = FpKit.arrayListSizedTo(allGetterMethods); + for (Method allGetterMethod : allGetterMethods) { + if (isPossiblePojoMethod(allGetterMethod)) { + pojoGetterMethods.add(allGetterMethod); + } + } + if (!pojoGetterMethods.isEmpty()) { + Method method = pojoGetterMethods.get(0); + if (isBooleanGetter(method)) { + method = findBestBooleanGetter(pojoGetterMethods); + } + return checkForSingleParameterPeer(method, allGetterMethods); + } + return null; + } + + private static Method checkForSingleParameterPeer(Method candidateMethod, List allMethods) { + // getFoo(DataFetchingEnv ev) is allowed, but we don't want to handle it in this class + // so this find those edge cases + for (Method allMethod : allMethods) { + if (allMethod.getParameterCount() > 0) { + // we have some method with the property name that takes more than 1 argument + // we don't want to handle this here, so we are saying there is one + return null; + } + } + return candidateMethod; + } + + private static Method findBestBooleanGetter(List methods) { + // we prefer isX() over getX() if both happen to be present + Optional isMethod = Optional.empty(); + for (Method method : methods) { + if (method.getName().startsWith("is")) { + isMethod = Optional.of(method); + break; + } + } + return isMethod.orElse(methods.get(0)); + } + + /** + * Finds all methods in a class hierarchy that match the property name - they might not be suitable but they + * + * @param sourceClass the class we are looking to work on + * + * @return a list of getter methods for that property + */ + private static List findMethodsForProperty(Class sourceClass, Predicate predicate) { + List methods = new ArrayList<>(); + Class currentClass = sourceClass; + while (currentClass != null) { + Method[] declaredMethods = currentClass.getDeclaredMethods(); + for (Method declaredMethod : declaredMethods) { + if (predicate.test(declaredMethod)) { + methods.add(declaredMethod); + } + } + currentClass = currentClass.getSuperclass(); + } + + List list = new ArrayList<>(methods); + list.sort(Comparator.comparing(Method::getName)); + return list; + } + + private static boolean isPossiblePojoMethod(Method method) { + return !isObjectMethod(method) && + returnsSomething(method) && + isGetterNamed(method) && + hasNoParameters(method) && + isPublic(method); + } + + private static boolean isRecordLike(Method method) { + return !isObjectMethod(method) && + returnsSomething(method) && + hasNoParameters(method) && + isPublic(method); + } + + private static boolean isBooleanGetter(Method method) { + Class returnType = method.getReturnType(); + return isGetterNamed(method) && (returnType.equals(Boolean.class) || returnType.equals(Boolean.TYPE)); + } + + private static boolean hasNoParameters(Method method) { + return method.getParameterCount() == 0; + } + + private static boolean isGetterNamed(Method method) { + String name = method.getName(); + return ((name.startsWith("get") && name.length() > 4) || (name.startsWith("is") && name.length() > 3)); + } + + private static boolean returnsSomething(Method method) { + return !method.getReturnType().equals(Void.class); + } + + private static boolean isPublic(Method method) { + return Modifier.isPublic(method.getModifiers()); + } + + private static boolean isObjectMethod(Method method) { + return method.getDeclaringClass().equals(Object.class); + } + + private static String mkPropertyNameGetter(Method method) { + // + // getFooName becomes fooName + // isFoo becomes foo + // + String name = method.getName(); + if (name.startsWith("get")) { + name = name.substring(3); + } else if (name.startsWith("is")) { + name = name.substring(2); + } + return decapitalize(name); + } + + private static String decapitalize(String name) { + if (name.length() == 0) { + return name; + } + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + + + @VisibleForTesting + static Function mkCallFunction(Class targetClass, String targetMethod, Class targetMethodReturnType) throws Throwable { + MethodHandles.Lookup lookup = getLookup(targetClass); + MethodHandle virtualMethodHandle = lookup.findVirtual(targetClass, targetMethod, MethodType.methodType(targetMethodReturnType)); + CallSite site = LambdaMetafactory.metafactory(lookup, + "apply", + MethodType.methodType(Function.class), + MethodType.methodType(Object.class, Object.class), + virtualMethodHandle, + MethodType.methodType(targetMethodReturnType, targetClass)); + @SuppressWarnings("unchecked") + Function getterFunction = (Function) site.getTarget().invokeExact(); + return getterFunction; + } + + private static MethodHandles.Lookup getLookup(Class targetClass) { + MethodHandles.Lookup lookupMe = MethodHandles.lookup(); + // + // This is a Java 9+ approach to method look up allowing private access + // + try { + return MethodHandles.privateLookupIn(targetClass, lookupMe); + } catch (IllegalAccessException e) { + return lookupMe; + } + } + +} diff --git a/src/main/java/graphql/schema/idl/ArgValueOfAllowedTypeChecker.java b/src/main/java/graphql/schema/idl/ArgValueOfAllowedTypeChecker.java index 4503d82d63..1711b635c0 100644 --- a/src/main/java/graphql/schema/idl/ArgValueOfAllowedTypeChecker.java +++ b/src/main/java/graphql/schema/idl/ArgValueOfAllowedTypeChecker.java @@ -1,15 +1,19 @@ package graphql.schema.idl; import graphql.AssertException; +import graphql.GraphQLContext; import graphql.GraphQLError; import graphql.Internal; +import graphql.execution.CoercedVariables; import graphql.language.Argument; import graphql.language.ArrayValue; import graphql.language.Directive; import graphql.language.EnumTypeDefinition; +import graphql.language.EnumTypeExtensionDefinition; import graphql.language.EnumValue; import graphql.language.EnumValueDefinition; import graphql.language.InputObjectTypeDefinition; +import graphql.language.InputObjectTypeExtensionDefinition; import graphql.language.InputValueDefinition; import graphql.language.ListType; import graphql.language.Node; @@ -18,6 +22,7 @@ import graphql.language.ObjectField; import graphql.language.ObjectValue; import graphql.language.ScalarTypeDefinition; +import graphql.language.ScalarTypeExtensionDefinition; import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeName; @@ -25,45 +30,47 @@ import graphql.schema.CoercingParseLiteralException; import graphql.schema.GraphQLScalarType; import graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.stream.Stream; import static graphql.Assert.assertShouldNeverHappen; +import static graphql.collect.ImmutableKit.emptyList; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.DUPLICATED_KEYS_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_ENUM_MESSAGE; -import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_LIST_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_NON_NULL_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_OBJECT_MESSAGE; -import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_SCALAR_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.MISSING_REQUIRED_FIELD_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.MUST_BE_VALID_ENUM_VALUE_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.NOT_A_VALID_SCALAR_LITERAL_MESSAGE; import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.UNKNOWN_FIELDS_MESSAGE; +import static java.lang.String.format; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; /** * Class to check whether a given directive argument value * matches a given directive definition. - * */ @Internal class ArgValueOfAllowedTypeChecker { - private static final Logger log = LoggerFactory.getLogger(ArgValueOfAllowedTypeChecker.class); - private final Directive directive; - private final Node element; + private final Node element; private final String elementName; private final Argument argument; private final TypeDefinitionRegistry typeRegistry; private final RuntimeWiring runtimeWiring; ArgValueOfAllowedTypeChecker(final Directive directive, - final Node element, + final Node element, final String elementName, final Argument argument, final TypeDefinitionRegistry typeRegistry, @@ -79,20 +86,21 @@ class ArgValueOfAllowedTypeChecker { /** * Recursively inspects an argument value given an allowed type. * Given the (invalid) SDL below: - * - * directive @myDirective(arg: [[String]] ) on FIELD_DEFINITION - * - * query { - * f: String @myDirective(arg: ["A String"]) - * } - * + *

+ * directive @myDirective(arg: [[String]] ) on FIELD_DEFINITION + *

+ * query { + * f: String @myDirective(arg: ["A String"]) + * } + *

* it will first check that the `myDirective.arg` type is an array * and fail when finding "A String" as it expected a nested array ([[String]]). - * @param errors validation error collector - * @param instanceValue directive argument value + * + * @param errors validation error collector + * @param instanceValue directive argument value * @param allowedArgType directive definition argument allowed type */ - void checkArgValueMatchesAllowedType(List errors, Value instanceValue, Type allowedArgType) { + void checkArgValueMatchesAllowedType(List errors, Value instanceValue, Type allowedArgType) { if (allowedArgType instanceof TypeName) { checkArgValueMatchesAllowedTypeName(errors, instanceValue, allowedArgType); } else if (allowedArgType instanceof ListType) { @@ -105,20 +113,22 @@ void checkArgValueMatchesAllowedType(List errors, Value instanceVa } private void addValidationError(List errors, String message, Object... args) { - errors.add(new DirectiveIllegalArgumentTypeError(element, elementName, directive.getName(), argument.getName(), String.format(message, args))); + errors.add(new DirectiveIllegalArgumentTypeError(element, elementName, directive.getName(), argument.getName(), format(message, args))); } - private void checkArgValueMatchesAllowedTypeName(List errors, Value instanceValue, Type allowedArgType) { + private void checkArgValueMatchesAllowedTypeName(List errors, Value instanceValue, Type allowedArgType) { if (instanceValue instanceof NullValue) { return; } String allowedTypeName = ((TypeName) allowedArgType).getName(); - TypeDefinition allowedTypeDefinition = typeRegistry.getType(allowedTypeName) - .orElseThrow(() -> new AssertException("Directive unknown argument type '%s'. This should have been validated before.")); + TypeDefinition allowedTypeDefinition = typeRegistry.getTypeOrNull(allowedTypeName); + if (allowedTypeDefinition == null) { + throw new AssertException(format("Directive unknown argument type '%s'. This should have been validated before.", allowedTypeName)); + } if (allowedTypeDefinition instanceof ScalarTypeDefinition) { - checkArgValueMatchesAllowedScalar(errors, instanceValue, allowedTypeName); + checkArgValueMatchesAllowedScalar(errors, instanceValue, (ScalarTypeDefinition) allowedTypeDefinition); } else if (allowedTypeDefinition instanceof EnumTypeDefinition) { checkArgValueMatchesAllowedEnum(errors, instanceValue, (EnumTypeDefinition) allowedTypeDefinition); } else if (allowedTypeDefinition instanceof InputObjectTypeDefinition) { @@ -128,7 +138,7 @@ private void checkArgValueMatchesAllowedTypeName(List errors, Valu } } - private void checkArgValueMatchesAllowedInputType(List errors, Value instanceValue, InputObjectTypeDefinition allowedTypeDefinition) { + private void checkArgValueMatchesAllowedInputType(List errors, Value instanceValue, InputObjectTypeDefinition allowedTypeDefinition) { if (!(instanceValue instanceof ObjectValue)) { addValidationError(errors, EXPECTED_OBJECT_MESSAGE, instanceValue.getClass().getSimpleName()); return; @@ -139,40 +149,42 @@ private void checkArgValueMatchesAllowedInputType(List errors, Val // then it must be the same type as the definition List fields = objectValue.getObjectFields(); - List inputValueDefinitions = allowedTypeDefinition.getInputValueDefinitions(); + List inputObjExt = typeRegistry.inputObjectTypeExtensions().getOrDefault(allowedTypeDefinition.getName(), emptyList()); + Stream inputObjExtValues = inputObjExt.stream().flatMap(inputObj -> inputObj.getInputValueDefinitions().stream()); + List inputValueDefinitions = Stream.concat(allowedTypeDefinition.getInputValueDefinitions().stream(), inputObjExtValues).collect(toList()); // check for duplicated fields Map fieldsToOccurrenceMap = fields.stream().map(ObjectField::getName) - .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); + .collect(groupingBy(Function.identity(), counting())); if (fieldsToOccurrenceMap.values().stream().anyMatch(count -> count > 1)) { addValidationError(errors, DUPLICATED_KEYS_MESSAGE, fieldsToOccurrenceMap.entrySet().stream() .filter(entry -> entry.getValue() > 1) .map(Map.Entry::getKey) - .collect(Collectors.joining(","))); + .collect(joining(","))); return; } // check for unknown fields Map nameToInputValueDefMap = inputValueDefinitions.stream() - .collect(Collectors.toMap(InputValueDefinition::getName, inputValueDef -> inputValueDef)); + .collect(toMap(InputValueDefinition::getName, inputValueDef -> inputValueDef)); List unknownFields = fields.stream() .filter(field -> !nameToInputValueDefMap.containsKey(field.getName())) - .collect(Collectors.toList()); + .collect(toList()); if (!unknownFields.isEmpty()) { addValidationError(errors, UNKNOWN_FIELDS_MESSAGE, unknownFields.stream() .map(ObjectField::getName) - .collect(Collectors.joining(",")), + .collect(joining(",")), allowedTypeDefinition.getName()); return; } // fields to map for easy access Map nameToFieldsMap = fields.stream() - .collect(Collectors.toMap(ObjectField::getName, objectField -> objectField)); + .collect(toMap(ObjectField::getName, objectField -> objectField)); // check each single field with its definition inputValueDefinitions.forEach(allowedValueDef -> { ObjectField objectField = nameToFieldsMap.get(allowedValueDef.getName()); @@ -180,7 +192,7 @@ private void checkArgValueMatchesAllowedInputType(List errors, Val }); } - private void checkArgValueMatchesAllowedEnum(List errors, Value instanceValue, EnumTypeDefinition allowedTypeDefinition) { + private void checkArgValueMatchesAllowedEnum(List errors, Value instanceValue, EnumTypeDefinition allowedTypeDefinition) { if (!(instanceValue instanceof EnumValue)) { addValidationError(errors, EXPECTED_ENUM_MESSAGE, instanceValue.getClass().getSimpleName()); return; @@ -188,29 +200,36 @@ private void checkArgValueMatchesAllowedEnum(List errors, Value in EnumValue enumValue = ((EnumValue) instanceValue); - boolean noneMatchAllowedEnumValue = allowedTypeDefinition.getEnumValueDefinitions().stream() + List enumExtensions = typeRegistry.enumTypeExtensions().getOrDefault(allowedTypeDefinition.getName(), emptyList()); + Stream enumExtStream = enumExtensions.stream().flatMap(enumExt -> enumExt.getEnumValueDefinitions().stream()); + List enumValueDefinitions = Stream.concat(allowedTypeDefinition.getEnumValueDefinitions().stream(), enumExtStream).collect(toList()); + + boolean noneMatchAllowedEnumValue = enumValueDefinitions.stream() .noneMatch(enumAllowedValue -> enumAllowedValue.getName().equals(enumValue.getName())); if (noneMatchAllowedEnumValue) { - addValidationError(errors, MUST_BE_VALID_ENUM_VALUE_MESSAGE, enumValue.getName(), allowedTypeDefinition.getEnumValueDefinitions().stream() - .map(EnumValueDefinition::getName) - .collect(Collectors.joining(","))); + addValidationError(errors, MUST_BE_VALID_ENUM_VALUE_MESSAGE, enumValue.getName(), enumValueDefinitions.stream() + .map(EnumValueDefinition::getName) + .collect(joining(","))); } } - private void checkArgValueMatchesAllowedScalar(List errors, Value instanceValue, String allowedTypeName) { - if (instanceValue instanceof ArrayValue - || instanceValue instanceof EnumValue - || instanceValue instanceof ObjectValue) { - addValidationError(errors, EXPECTED_SCALAR_MESSAGE, instanceValue.getClass().getSimpleName()); - return; - } + private void checkArgValueMatchesAllowedScalar(List errors, Value instanceValue, ScalarTypeDefinition allowedTypeDefinition) { + // scalars are allowed to accept ANY literal value - its up to their coercion to decide if its valid or not + List extensions = typeRegistry.scalarTypeExtensions().getOrDefault(allowedTypeDefinition.getName(), emptyList()); + ScalarWiringEnvironment environment = new ScalarWiringEnvironment(typeRegistry, allowedTypeDefinition, extensions); + WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); - GraphQLScalarType scalarType = runtimeWiring.getScalars().get(allowedTypeName); + GraphQLScalarType scalarType; + if (wiringFactory.providesScalar(environment)) { + scalarType = wiringFactory.getScalar(environment); + } else { + scalarType = runtimeWiring.getScalars().get(allowedTypeDefinition.getName()); + } // scalarType will always be present as // scalar implementation validation has been performed earlier if (!isArgumentValueScalarLiteral(scalarType, instanceValue)) { - addValidationError(errors, NOT_A_VALID_SCALAR_LITERAL_MESSAGE, allowedTypeName); + addValidationError(errors, NOT_A_VALID_SCALAR_LITERAL_MESSAGE, allowedTypeDefinition.getName()); } } @@ -231,39 +250,44 @@ private void checkArgInputObjectValueFieldMatchesAllowedDefinition(List errors, Value instanceValue, NonNullType allowedArgType) { + private void checkArgValueMatchesAllowedNonNullType(List errors, Value instanceValue, NonNullType allowedArgType) { if (instanceValue instanceof NullValue) { addValidationError(errors, EXPECTED_NON_NULL_MESSAGE); return; } - Type unwrappedAllowedType = allowedArgType.getType(); + Type unwrappedAllowedType = allowedArgType.getType(); checkArgValueMatchesAllowedType(errors, instanceValue, unwrappedAllowedType); } - private void checkArgValueMatchesAllowedListType(List errors, Value instanceValue, ListType allowedArgType) { - if (instanceValue instanceof NullValue) { - return; + private void checkArgValueMatchesAllowedListType(List errors, Value instanceValue, ListType allowedArgType) { + // From the spec, on input coercion: + // If the value passed as an input to a list type is not a list and not the null value, + // then the result of input coercion is a list of size one where the single item value + // is the result of input coercion for the list’s item type on the provided value + // (note this may apply recursively for nested lists). + + Value coercedInstanceValue = instanceValue; + if (!(instanceValue instanceof ArrayValue) && !(instanceValue instanceof NullValue)) { + coercedInstanceValue = new ArrayValue(Collections.singletonList(instanceValue)); } - if (!(instanceValue instanceof ArrayValue)) { - addValidationError(errors, EXPECTED_LIST_MESSAGE, instanceValue.getClass().getSimpleName()); + if (coercedInstanceValue instanceof NullValue) { return; } - ArrayValue arrayValue = ((ArrayValue) instanceValue); - Type unwrappedAllowedType = allowedArgType.getType(); - - // validate each instance value in the list, all instances must match for the list to match - arrayValue.getValues().forEach(value -> checkArgValueMatchesAllowedType(errors, value, unwrappedAllowedType)); + Type unwrappedAllowedType = allowedArgType.getType(); + ArrayValue arrayValue = ((ArrayValue) coercedInstanceValue); + arrayValue.getValues().forEach(value -> { + checkArgValueMatchesAllowedType(errors, value, unwrappedAllowedType); + }); } - private boolean isArgumentValueScalarLiteral(GraphQLScalarType scalarType, Value instanceValue) { + private boolean isArgumentValueScalarLiteral(GraphQLScalarType scalarType, Value instanceValue) { try { - scalarType.getCoercing().parseLiteral(instanceValue); + scalarType.getCoercing().parseLiteral(instanceValue, CoercedVariables.emptyVariables(), GraphQLContext.getDefault(), Locale.getDefault()); return true; } catch (CoercingParseLiteralException ex) { - log.debug("Attempted parsing literal into '{}' but got the following error: ", scalarType.getName(), ex); return false; } } diff --git a/src/main/java/graphql/schema/idl/CombinedWiringFactory.java b/src/main/java/graphql/schema/idl/CombinedWiringFactory.java index 643f3cd4ac..1ff2eb4845 100644 --- a/src/main/java/graphql/schema/idl/CombinedWiringFactory.java +++ b/src/main/java/graphql/schema/idl/CombinedWiringFactory.java @@ -1,7 +1,9 @@ package graphql.schema.idl; +import graphql.PublicApi; import graphql.schema.DataFetcher; import graphql.schema.DataFetcherFactory; +import graphql.schema.GraphQLScalarType; import graphql.schema.TypeResolver; import java.util.ArrayList; @@ -14,6 +16,7 @@ * This combines a number of {@link WiringFactory}s together to act as one. It asks each one * whether it handles a type and delegates to the first one to answer yes. */ +@PublicApi public class CombinedWiringFactory implements WiringFactory { private final List factories; @@ -101,4 +104,55 @@ public DataFetcher getDataFetcher(FieldWiringEnvironment environment) { } return assertShouldNeverHappen(); } + + @Override + public boolean providesScalar(ScalarWiringEnvironment environment) { + for (WiringFactory factory : factories) { + if (factory.providesScalar(environment)) { + return true; + } + } + return false; + } + + @Override + public GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { + for (WiringFactory factory : factories) { + if (factory.providesScalar(environment)) { + return factory.getScalar(environment); + } + } + return assertShouldNeverHappen(); + } + + @Override + public boolean providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + for (WiringFactory factory : factories) { + if (factory.providesSchemaDirectiveWiring(environment)) { + return true; + } + } + return false; + } + + @Override + public SchemaDirectiveWiring getSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + for (WiringFactory factory : factories) { + if (factory.providesSchemaDirectiveWiring(environment)) { + return factory.getSchemaDirectiveWiring(environment); + } + } + return assertShouldNeverHappen(); + } + + @Override + public DataFetcher getDefaultDataFetcher(FieldWiringEnvironment environment) { + for (WiringFactory factory : factories) { + if (factory.getDefaultDataFetcher(environment) != null) { + return factory.getDefaultDataFetcher(environment); + } + } + return null; + } + } diff --git a/src/main/java/graphql/schema/idl/DirectiveInfo.java b/src/main/java/graphql/schema/idl/DirectiveInfo.java new file mode 100644 index 0000000000..9b8317f97e --- /dev/null +++ b/src/main/java/graphql/schema/idl/DirectiveInfo.java @@ -0,0 +1,61 @@ +package graphql.schema.idl; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import graphql.Directives; +import graphql.PublicApi; +import graphql.schema.GraphQLDirective; + +import java.util.Map; +import java.util.Set; + +/** + * Info on all the directives provided by graphql specification + */ +@PublicApi +public class DirectiveInfo { + + + /** + * A map from directive name to directive which provided by specification + */ + public static final Map GRAPHQL_SPECIFICATION_DIRECTIVE_MAP = ImmutableMap.of( + Directives.IncludeDirective.getName(), Directives.IncludeDirective, + Directives.SkipDirective.getName(), Directives.SkipDirective, + Directives.DeprecatedDirective.getName(), Directives.DeprecatedDirective, + Directives.SpecifiedByDirective.getName(), Directives.SpecifiedByDirective, + Directives.OneOfDirective.getName(), Directives.OneOfDirective, + // technically this is NOT yet in spec - but it is added by default by graphql-java so we include it + // we should also do @defer at some future time soon + Directives.DeferDirective.getName(), Directives.DeferDirective, + Directives.ExperimentalDisableErrorPropagationDirective.getName(), Directives.ExperimentalDisableErrorPropagationDirective + ); + /** + * A set of directives which provided by graphql specification + */ + public static final Set GRAPHQL_SPECIFICATION_DIRECTIVES =ImmutableSet.copyOf(GRAPHQL_SPECIFICATION_DIRECTIVE_MAP.values()); + + /** + * Returns true if a directive with provided directiveName has been defined in graphql specification + * + * @param directiveName the name of directive in question + * + * @return true if the directive provided by graphql specification, and false otherwise + */ + public static boolean isGraphqlSpecifiedDirective(String directiveName) { + return GRAPHQL_SPECIFICATION_DIRECTIVE_MAP.containsKey(directiveName); + } + + /** + * Returns true if the provided directive has been defined in graphql specification + * + * @param graphQLDirective the directive in question + * + * @return true if the directive provided by graphql specification, and false otherwise + */ + public static boolean isGraphqlSpecifiedDirective(GraphQLDirective graphQLDirective) { + return isGraphqlSpecifiedDirective(graphQLDirective.getName()); + } + + +} diff --git a/src/main/java/graphql/schema/idl/EchoingWiringFactory.java b/src/main/java/graphql/schema/idl/EchoingWiringFactory.java index 5f8988d916..e7be922da8 100644 --- a/src/main/java/graphql/schema/idl/EchoingWiringFactory.java +++ b/src/main/java/graphql/schema/idl/EchoingWiringFactory.java @@ -10,8 +10,6 @@ import graphql.schema.PropertyDataFetcher; import graphql.schema.TypeResolver; -import java.math.BigDecimal; -import java.math.BigInteger; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Consumer; @@ -98,21 +96,13 @@ private static Object fakeScalarValue(String fieldName, GraphQLScalarType scalar return 1.0; } else if (scalarType.equals(Scalars.GraphQLID)) { return "id_" + fieldName; - } else if (scalarType.equals(Scalars.GraphQLBigDecimal)) { - return new BigDecimal(1.0); - } else if (scalarType.equals(Scalars.GraphQLBigInteger)) { - return new BigInteger("1"); - } else if (scalarType.equals(Scalars.GraphQLByte)) { - return Byte.valueOf("1"); - } else if (scalarType.equals(Scalars.GraphQLShort)) { - return Short.valueOf("1"); } else { return null; } } public static GraphQLScalarType fakeScalar(String name) { - return new GraphQLScalarType(name, name, new Coercing() { + return GraphQLScalarType.newScalar().name(name).coercing(new Coercing() { @Override public Object serialize(Object dataFetcherResult) { return dataFetcherResult; @@ -127,7 +117,8 @@ public Object parseValue(Object input) { public Object parseLiteral(Object input) { return input; } - }); + }) + .build(); } } diff --git a/src/main/java/graphql/schema/idl/FetchSchemaDirectiveWiring.java b/src/main/java/graphql/schema/idl/FetchSchemaDirectiveWiring.java deleted file mode 100644 index ee71d40c59..0000000000 --- a/src/main/java/graphql/schema/idl/FetchSchemaDirectiveWiring.java +++ /dev/null @@ -1,39 +0,0 @@ -package graphql.schema.idl; - -import graphql.Internal; -import graphql.schema.DataFetcher; -import graphql.schema.GraphQLArgument; -import graphql.schema.GraphQLDirective; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.PropertyDataFetcher; - -import java.util.List; -import java.util.Optional; - -import static graphql.DirectivesUtil.directiveWithArg; - -/** - * This adds ' @fetch(from : "otherName") ' support so you can rename what property is read for a given field - */ -@Internal -public class FetchSchemaDirectiveWiring implements SchemaDirectiveWiring { - - public static final String FETCH = "fetch"; - - @Override - public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment environment) { - GraphQLFieldDefinition field = environment.getElement(); - String fetchName = atFetchFromSupport(field.getName(), field.getDirectives()); - DataFetcher dataFetcher = new PropertyDataFetcher(fetchName); - - return field.transform(builder -> builder.dataFetcher(dataFetcher)); - } - - - private String atFetchFromSupport(String fieldName, List directives) { - // @fetch(from : "name") - Optional from = directiveWithArg(directives, FETCH, "from"); - return from.map(arg -> String.valueOf(arg.getValue())).orElse(fieldName); - } - -} diff --git a/src/main/java/graphql/schema/idl/FieldWiringEnvironment.java b/src/main/java/graphql/schema/idl/FieldWiringEnvironment.java index 06cee69b9c..8dffb025ed 100644 --- a/src/main/java/graphql/schema/idl/FieldWiringEnvironment.java +++ b/src/main/java/graphql/schema/idl/FieldWiringEnvironment.java @@ -3,25 +3,30 @@ import graphql.PublicApi; import graphql.language.FieldDefinition; import graphql.language.TypeDefinition; +import graphql.schema.GraphQLAppliedDirective; import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLOutputType; +import org.jspecify.annotations.NullMarked; import java.util.List; @PublicApi +@NullMarked public class FieldWiringEnvironment extends WiringEnvironment { private final FieldDefinition fieldDefinition; private final TypeDefinition parentType; private final GraphQLOutputType fieldType; private final List directives; + private final List appliedDirectives; - FieldWiringEnvironment(TypeDefinitionRegistry registry, TypeDefinition parentType, FieldDefinition fieldDefinition, GraphQLOutputType fieldType, List directives) { + FieldWiringEnvironment(TypeDefinitionRegistry registry, TypeDefinition parentType, FieldDefinition fieldDefinition, GraphQLOutputType fieldType, List directives, List appliedDirectives) { super(registry); this.fieldDefinition = fieldDefinition; this.parentType = parentType; this.fieldType = fieldType; this.directives = directives; + this.appliedDirectives = appliedDirectives; } public FieldDefinition getFieldDefinition() { @@ -39,4 +44,8 @@ public GraphQLOutputType getFieldType() { public List getDirectives() { return directives; } -} \ No newline at end of file + + public List getAppliedDirectives() { + return appliedDirectives; + } +} diff --git a/src/main/java/graphql/schema/idl/ImmutableTypeDefinitionRegistry.java b/src/main/java/graphql/schema/idl/ImmutableTypeDefinitionRegistry.java new file mode 100644 index 0000000000..e1dff06e57 --- /dev/null +++ b/src/main/java/graphql/schema/idl/ImmutableTypeDefinitionRegistry.java @@ -0,0 +1,134 @@ +package graphql.schema.idl; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.GraphQLError; +import graphql.PublicApi; +import graphql.language.DirectiveDefinition; +import graphql.language.EnumTypeExtensionDefinition; +import graphql.language.InputObjectTypeExtensionDefinition; +import graphql.language.InterfaceTypeExtensionDefinition; +import graphql.language.ObjectTypeExtensionDefinition; +import graphql.language.SDLDefinition; +import graphql.language.ScalarTypeDefinition; +import graphql.language.ScalarTypeExtensionDefinition; +import graphql.language.SchemaExtensionDefinition; +import graphql.language.TypeDefinition; +import graphql.language.UnionTypeExtensionDefinition; +import graphql.schema.idl.errors.SchemaProblem; +import org.jspecify.annotations.NullMarked; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static com.google.common.collect.ImmutableMap.copyOf; + +/** + * A {@link ImmutableTypeDefinitionRegistry} contains an immutable set of type definitions that come from compiling + * a graphql schema definition file via {@link SchemaParser#parse(String)} and is more performant because it + * uses {@link ImmutableMap} structures. + */ +@SuppressWarnings("rawtypes") +@PublicApi +@NullMarked +public class ImmutableTypeDefinitionRegistry extends TypeDefinitionRegistry { + + ImmutableTypeDefinitionRegistry(TypeDefinitionRegistry registry) { + super( + copyOf(registry.objectTypeExtensions), + copyOf(registry.interfaceTypeExtensions), + copyOf(registry.unionTypeExtensions), + copyOf(registry.enumTypeExtensions), + copyOf(registry.scalarTypeExtensions), + copyOf(registry.inputObjectTypeExtensions), + copyOf(registry.types), + copyOf(registry.scalars()), // has an extra side effect + copyOf(registry.directiveDefinitions), + ImmutableList.copyOf(registry.schemaExtensionDefinitions), + registry.schema, + registry.schemaParseOrder + ); + } + + + private UnsupportedOperationException unsupportedOperationException() { + return new UnsupportedOperationException("The TypeDefinitionRegistry is in read only mode"); + } + + @Override + public TypeDefinitionRegistry merge(TypeDefinitionRegistry typeRegistry) throws SchemaProblem { + throw unsupportedOperationException(); + } + + @Override + public Optional addAll(Collection definitions) { + throw unsupportedOperationException(); + } + + @Override + public Optional add(SDLDefinition definition) { + throw unsupportedOperationException(); + } + + @Override + public void remove(SDLDefinition definition) { + throw unsupportedOperationException(); + } + + @Override + public void remove(String key, SDLDefinition definition) { + throw unsupportedOperationException(); + } + + @Override + public Map types() { + return types; + } + + @Override + public Map scalars() { + return scalarTypes; + } + + @Override + public Map> objectTypeExtensions() { + return objectTypeExtensions; + } + + @Override + public Map> interfaceTypeExtensions() { + return interfaceTypeExtensions; + } + + @Override + public Map> unionTypeExtensions() { + return unionTypeExtensions; + } + + @Override + public Map> enumTypeExtensions() { + return enumTypeExtensions; + } + + @Override + public Map> scalarTypeExtensions() { + return scalarTypeExtensions; + } + + @Override + public Map> inputObjectTypeExtensions() { + return inputObjectTypeExtensions; + } + + @Override + public List getSchemaExtensionDefinitions() { + return schemaExtensionDefinitions; + } + + @Override + public Map getDirectiveDefinitions() { + return directiveDefinitions; + } +} diff --git a/src/main/java/graphql/schema/idl/ImplementingTypesChecker.java b/src/main/java/graphql/schema/idl/ImplementingTypesChecker.java new file mode 100644 index 0000000000..0294e290a1 --- /dev/null +++ b/src/main/java/graphql/schema/idl/ImplementingTypesChecker.java @@ -0,0 +1,271 @@ +package graphql.schema.idl; + +import graphql.GraphQLError; +import graphql.Internal; +import graphql.language.AstPrinter; +import graphql.language.FieldDefinition; +import graphql.language.ImplementingTypeDefinition; +import graphql.language.InputValueDefinition; +import graphql.language.InterfaceTypeDefinition; +import graphql.language.InterfaceTypeExtensionDefinition; +import graphql.language.NonNullType; +import graphql.language.ObjectTypeDefinition; +import graphql.language.ObjectTypeExtensionDefinition; +import graphql.language.Type; +import graphql.language.TypeName; +import graphql.schema.idl.errors.InterfaceFieldArgumentNotOptionalError; +import graphql.schema.idl.errors.InterfaceFieldArgumentRedefinitionError; +import graphql.schema.idl.errors.InterfaceFieldRedefinitionError; +import graphql.schema.idl.errors.InterfaceImplementedMoreThanOnceError; +import graphql.schema.idl.errors.InterfaceImplementingItselfError; +import graphql.schema.idl.errors.InterfaceWithCircularImplementationHierarchyError; +import graphql.schema.idl.errors.MissingInterfaceFieldArgumentsError; +import graphql.schema.idl.errors.MissingInterfaceFieldError; +import graphql.schema.idl.errors.MissingTransitiveInterfaceError; +import graphql.util.FpKit; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Stream; + +import static graphql.collect.ImmutableKit.emptyList; +import static java.util.stream.Collectors.toMap; +import static java.util.stream.Collectors.toSet; + +/** + * A support class to help break up the large SchemaTypeChecker class. This handles + * the checking of {@link graphql.language.ImplementingTypeDefinition}s. + */ +@Internal +class ImplementingTypesChecker { + private static final Map, String> TYPE_OF_MAP = new HashMap<>(); + + static { + TYPE_OF_MAP.put(ObjectTypeDefinition.class, "object"); + TYPE_OF_MAP.put(ObjectTypeExtensionDefinition.class, "object extension"); + TYPE_OF_MAP.put(InterfaceTypeDefinition.class, "interface"); + TYPE_OF_MAP.put(InterfaceTypeExtensionDefinition.class, "interface extension"); + } + + /* + * "Implementing types" (i.e.: types that might implement interfaces) have the potential to be invalid if incorrectly defined. + * + * The same interface might not be implemented more than once by a type and its extensions + * The implementing type must implement all the transitive interfaces + * An interface implementation must not result in a circular reference (i.e.: an interface implementing itself) + * All fields declared by an interface have to be correctly declared by its implementing type, including the proper field arguments + */ + void checkImplementingTypes(List errors, TypeDefinitionRegistry typeRegistry) { + List interfaces = typeRegistry.getTypes(InterfaceTypeDefinition.class); + List objects = typeRegistry.getTypes(ObjectTypeDefinition.class); + + Stream.>concat(interfaces.stream(), objects.stream()) + .forEach(type -> checkImplementingType(errors, typeRegistry, type)); + } + + private void checkImplementingType( + List errors, + TypeDefinitionRegistry typeRegistry, + ImplementingTypeDefinition type) { + + Map implementedInterfaces = + checkInterfacesNotImplementedMoreThanOnce(errors, type, typeRegistry); + + checkInterfaceIsImplemented(errors, typeRegistry, type, implementedInterfaces); + + checkAncestorImplementation(errors, typeRegistry, type, implementedInterfaces); + } + + private Map checkInterfacesNotImplementedMoreThanOnce( + List errors, + ImplementingTypeDefinition type, + TypeDefinitionRegistry typeRegistry + ) { + Map> implementedInterfaces = + getLogicallyImplementedInterfaces(type, typeRegistry); + + Map interfacesImplementedOnce = implementedInterfaces.entrySet() + .stream() + .filter(entry -> entry.getValue().size() == 1) + .collect(toMap( + Map.Entry::getKey, + entry -> entry.getValue().get(0) + )); + + implementedInterfaces.entrySet().stream() + .filter(entry -> !interfacesImplementedOnce.containsKey(entry.getKey())) + .forEach(entry -> { + entry.getValue().forEach(offendingType -> { + errors.add(new InterfaceImplementedMoreThanOnceError(TYPE_OF_MAP.get(offendingType.getClass()), offendingType, entry.getKey())); + }); + }); + + return interfacesImplementedOnce; + } + + private void checkAncestorImplementation( + List errors, + TypeDefinitionRegistry typeRegistry, + ImplementingTypeDefinition type, + Map implementedInterfaces) { + + if (implementedInterfaces.containsKey(type)) { + errors.add(new InterfaceImplementingItselfError(TYPE_OF_MAP.get(type.getClass()), type)); + return; + } + + implementedInterfaces.forEach((implementedInterface, implementingType) -> { + Set transitiveInterfaces = getLogicallyImplementedInterfaces(implementedInterface, typeRegistry).keySet(); + + transitiveInterfaces.forEach(transitiveInterface -> { + if (transitiveInterface.equals(type)) { + errors.add(new InterfaceWithCircularImplementationHierarchyError(TYPE_OF_MAP.get(type.getClass()), type, implementedInterface)); + } else if (!implementedInterfaces.containsKey(transitiveInterface)) { + errors.add(new MissingTransitiveInterfaceError(TYPE_OF_MAP.get(implementingType.getClass()), implementingType, implementedInterface, transitiveInterface)); + } + }); + }); + } + + private void checkInterfaceIsImplemented( + List errors, + TypeDefinitionRegistry typeRegistry, + ImplementingTypeDefinition type, + Map implementedInterfaces + ) { + Set fieldDefinitions = getLogicallyDeclaredFields(type, typeRegistry); + + Map typeFields = fieldDefinitions.stream() + .collect(toMap(FieldDefinition::getName, Function.identity(), mergeFirstValue())); + + implementedInterfaces.forEach((implementedInterface, implementingType) -> { + implementedInterface.getFieldDefinitions().forEach(interfaceFieldDef -> { + FieldDefinition typeFieldDef = typeFields.get(interfaceFieldDef.getName()); + if (typeFieldDef == null) { + errors.add(new MissingInterfaceFieldError(TYPE_OF_MAP.get(implementingType.getClass()), implementingType, implementedInterface, interfaceFieldDef)); + } else { + if (!typeRegistry.isSubTypeOf(typeFieldDef.getType(), interfaceFieldDef.getType())) { + String interfaceFieldType = AstPrinter.printAst(interfaceFieldDef.getType()); + String objectFieldType = AstPrinter.printAst(typeFieldDef.getType()); + errors.add(new InterfaceFieldRedefinitionError(TYPE_OF_MAP.get(implementingType.getClass()), implementingType, implementedInterface, typeFieldDef, objectFieldType, interfaceFieldType)); + } + + // look at arguments + List objectArgs = typeFieldDef.getInputValueDefinitions(); + List interfaceArgs = interfaceFieldDef.getInputValueDefinitions(); + if (objectArgs.size() < interfaceArgs.size()) { + errors.add(new MissingInterfaceFieldArgumentsError(TYPE_OF_MAP.get(implementingType.getClass()), implementingType, implementedInterface, typeFieldDef)); + } else { + checkArgumentConsistency(TYPE_OF_MAP.get(implementingType.getClass()), implementingType, implementedInterface, typeFieldDef, interfaceFieldDef, errors); + } + } + }); + }); + } + + private void checkArgumentConsistency( + String typeOfType, + ImplementingTypeDefinition objectTypeDef, + InterfaceTypeDefinition interfaceTypeDef, + FieldDefinition objectFieldDef, + FieldDefinition interfaceFieldDef, + List errors + ) { + Map objectArgs = FpKit.getByName(objectFieldDef.getInputValueDefinitions(), InputValueDefinition::getName); + Map interfaceArgs = FpKit.getByName(interfaceFieldDef.getInputValueDefinitions(), InputValueDefinition::getName); + for (Map.Entry interfaceEntries : interfaceArgs.entrySet()) { + InputValueDefinition interfaceArg = interfaceEntries.getValue(); + InputValueDefinition objectArg = objectArgs.get(interfaceEntries.getKey()); + if (objectArg == null) { + errors.add(new MissingInterfaceFieldArgumentsError(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef)); + } else { + // we need to remove the not relevant applied directives on the argument definitions to compare + String interfaceArgStr = AstPrinter.printAstCompact(interfaceArg.transform(builder -> builder.directives(emptyList()))); + String objectArgStr = AstPrinter.printAstCompact(objectArg.transform(builder -> builder.directives(emptyList()))); + if (!interfaceArgStr.equals(objectArgStr)) { + errors.add(new InterfaceFieldArgumentRedefinitionError(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef, objectArgStr, interfaceArgStr)); + } + } + } + + if (objectArgs.size() > interfaceArgs.size()) { + for (Map.Entry objetEntries : objectArgs.entrySet()) { + InputValueDefinition objectArg = objetEntries.getValue(); + InputValueDefinition interfaceArg = interfaceArgs.get(objetEntries.getKey()); + if (interfaceArg == null) { + // there is no interface counterpart previously checked above + if (objectArg.getType() instanceof NonNullType) { + String objectArgStr = AstPrinter.printAst(objectArg); + errors.add(new InterfaceFieldArgumentNotOptionalError(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef, objectArgStr)); + } + } + } + } + } + + private Map> getLogicallyImplementedInterfaces( + ImplementingTypeDefinition type, + TypeDefinitionRegistry typeRegistry + ) { + + Stream extensions = Stream.concat( + typeRegistry.interfaceTypeExtensions().getOrDefault(type.getName(), emptyList()).stream(), + typeRegistry.objectTypeExtensions().getOrDefault(type.getName(), emptyList()).stream() + ); + + return Stream.concat(Stream.of(type), extensions) + .collect(HashMap::new, (map, implementingType) -> { + List implementedInterfaces = implementingType.getImplements(); + + toInterfaceTypeDefinitions(typeRegistry, implementedInterfaces).forEach(implemented -> { + List implementingTypes = map.getOrDefault(implemented, new ArrayList<>()); + implementingTypes.add(implementingType); + map.put(implemented, implementingTypes); + }); + }, HashMap::putAll); + + } + + private Set getLogicallyDeclaredFields( + ImplementingTypeDefinition type, + TypeDefinitionRegistry typeRegistry + ) { + + Stream extensions = Stream.concat( + typeRegistry.interfaceTypeExtensions().getOrDefault(type.getName(), emptyList()).stream(), + typeRegistry.objectTypeExtensions().getOrDefault(type.getName(), emptyList()).stream() + ); + + return Stream.concat(Stream.of(type), extensions) + .flatMap(implementingType -> { + List fieldDefinitions = implementingType.getFieldDefinitions(); + return fieldDefinitions.stream(); + }) + .collect(toSet()); + } + + private BinaryOperator mergeFirstValue() { + return (v1, v2) -> v1; + } + + private InterfaceTypeDefinition toInterfaceTypeDefinition(Type type, TypeDefinitionRegistry typeRegistry) { + TypeInfo typeInfo = TypeInfo.typeInfo(type); + TypeName unwrapped = typeInfo.getTypeName(); + + return typeRegistry.getTypeOrNull(unwrapped, InterfaceTypeDefinition.class); + } + + private Set toInterfaceTypeDefinitions(TypeDefinitionRegistry typeRegistry, Collection implementsTypes) { + return implementsTypes.stream() + .map(t -> toInterfaceTypeDefinition(t, typeRegistry)) + .filter(Objects::nonNull) + .collect(toSet()); + } +} diff --git a/src/main/java/graphql/schema/idl/InterfaceWiringEnvironment.java b/src/main/java/graphql/schema/idl/InterfaceWiringEnvironment.java index 6c635883db..a336b371d7 100644 --- a/src/main/java/graphql/schema/idl/InterfaceWiringEnvironment.java +++ b/src/main/java/graphql/schema/idl/InterfaceWiringEnvironment.java @@ -2,8 +2,10 @@ import graphql.PublicApi; import graphql.language.InterfaceTypeDefinition; +import org.jspecify.annotations.NullMarked; @PublicApi +@NullMarked public class InterfaceWiringEnvironment extends WiringEnvironment { private final InterfaceTypeDefinition interfaceTypeDefinition; @@ -16,4 +18,4 @@ public class InterfaceWiringEnvironment extends WiringEnvironment { public InterfaceTypeDefinition getInterfaceTypeDefinition() { return interfaceTypeDefinition; } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/schema/idl/MockedWiringFactory.java b/src/main/java/graphql/schema/idl/MockedWiringFactory.java new file mode 100644 index 0000000000..3d5f14f7a4 --- /dev/null +++ b/src/main/java/graphql/schema/idl/MockedWiringFactory.java @@ -0,0 +1,153 @@ +package graphql.schema.idl; + +import graphql.Assert; +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.execution.CoercedVariables; +import graphql.language.ArrayValue; +import graphql.language.BooleanValue; +import graphql.language.EnumValue; +import graphql.language.FloatValue; +import graphql.language.IntValue; +import graphql.language.NullValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.language.VariableReference; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLScalarType; +import graphql.schema.SingletonPropertyDataFetcher; +import graphql.schema.TypeResolver; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This is a {@link WiringFactory} which provides mocked types resolver + * and scalars. It is useful for testing only, for example for creating schemas + * that can be inspected but not executed on. + *

+ * See {@link RuntimeWiring#MOCKED_WIRING} for example usage + */ +@PublicApi +@NullMarked +@SuppressWarnings("rawtypes") +public class MockedWiringFactory implements WiringFactory { + + @Override + public boolean providesTypeResolver(InterfaceWiringEnvironment environment) { + return true; + } + + @Override + public TypeResolver getTypeResolver(InterfaceWiringEnvironment environment) { + return env -> { + throw new UnsupportedOperationException("Not implemented...this is only a mocked wiring"); + }; + } + + @Override + public boolean providesTypeResolver(UnionWiringEnvironment environment) { + return true; + } + + @Override + public TypeResolver getTypeResolver(UnionWiringEnvironment environment) { + return env -> { + throw new UnsupportedOperationException("Not implemented...this is only a mocked wiring"); + }; + } + + @Override + public boolean providesDataFetcher(FieldWiringEnvironment environment) { + return true; + } + + @Override + public DataFetcher getDataFetcher(FieldWiringEnvironment environment) { + return SingletonPropertyDataFetcher.singleton(); + } + + @Override + public boolean providesScalar(ScalarWiringEnvironment environment) { + return !ScalarInfo.isGraphqlSpecifiedScalar(environment.getScalarTypeDefinition().getName()); + } + + public GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { + return GraphQLScalarType.newScalar().name(environment.getScalarTypeDefinition().getName()).coercing(new Coercing<>() { + @Nullable + @Override + public Object serialize(@NonNull Object dataFetcherResult, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingSerializeException { + throw new UnsupportedOperationException("Not implemented...this is only a mocked wiring"); + } + + @Nullable + @Override + public Object parseValue(@NonNull Object input, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseValueException { + throw new UnsupportedOperationException("Not implemented...this is only a mocked wiring"); + } + + @Nullable + @Override + public Object parseLiteral(@NonNull Value input, @NonNull CoercedVariables variables, @NonNull GraphQLContext graphQLContext, @NonNull Locale locale) throws CoercingParseLiteralException { + return parseLiteralImpl(input, variables, graphQLContext, locale); + } + + @Nullable + private Object parseLiteralImpl(Value input, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) { + if (input instanceof NullValue) { + return null; + } + if (input instanceof FloatValue) { + return ((FloatValue) input).getValue(); + } + if (input instanceof StringValue) { + return ((StringValue) input).getValue(); + } + if (input instanceof IntValue) { + return ((IntValue) input).getValue(); + } + if (input instanceof BooleanValue) { + return ((BooleanValue) input).isValue(); + } + if (input instanceof EnumValue) { + return ((EnumValue) input).getName(); + } + if (input instanceof VariableReference) { + String varName = ((VariableReference) input).getName(); + return variables.get(varName); + } + if (input instanceof ArrayValue) { + List values = ((ArrayValue) input).getValues(); + return values.stream() + .map(v -> parseLiteral(v, variables, graphQLContext, locale)) + .collect(Collectors.toList()); + } + if (input instanceof ObjectValue) { + List values = ((ObjectValue) input).getObjectFields(); + Map parsedValues = new LinkedHashMap<>(); + values.forEach(fld -> { + Object parsedValue = parseLiteral(fld.getValue(), variables, graphQLContext, locale); + if (parsedValue != null) { + parsedValues.put(fld.getName(), parsedValue); + } + }); + return parsedValues; + } + return Assert.assertShouldNeverHappen("We have covered all Value types"); + } + + }).build(); + } +} diff --git a/src/main/java/graphql/schema/idl/NoopWiringFactory.java b/src/main/java/graphql/schema/idl/NoopWiringFactory.java index eaccea2085..93517eb26b 100644 --- a/src/main/java/graphql/schema/idl/NoopWiringFactory.java +++ b/src/main/java/graphql/schema/idl/NoopWiringFactory.java @@ -1,12 +1,13 @@ package graphql.schema.idl; +import graphql.Internal; import graphql.schema.DataFetcher; import graphql.schema.GraphQLScalarType; -import graphql.schema.PropertyDataFetcher; import graphql.schema.TypeResolver; import static graphql.Assert.assertShouldNeverHappen; +@Internal public class NoopWiringFactory implements WiringFactory { @Override diff --git a/src/main/java/graphql/schema/idl/RuntimeWiring.java b/src/main/java/graphql/schema/idl/RuntimeWiring.java index 2d5fa995a2..b985d648f5 100644 --- a/src/main/java/graphql/schema/idl/RuntimeWiring.java +++ b/src/main/java/graphql/schema/idl/RuntimeWiring.java @@ -2,20 +2,28 @@ import graphql.PublicApi; import graphql.schema.DataFetcher; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; +import graphql.schema.GraphqlTypeComparatorRegistry; import graphql.schema.TypeResolver; +import graphql.schema.idl.errors.StrictModeWiringException; import graphql.schema.visibility.GraphqlFieldVisibility; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.function.Consumer; import java.util.function.UnaryOperator; +import org.jspecify.annotations.NullUnmarked; import static graphql.Assert.assertNotNull; import static graphql.schema.visibility.DefaultGraphqlFieldVisibility.DEFAULT_FIELD_VISIBILITY; +import static java.lang.String.format; /** - * A runtime wiring is a specification of data fetchers, type resolves and custom scalars that are needed + * A runtime wiring is a specification of data fetchers, type resolvers and custom scalars that are needed * to wire together a functional {@link GraphQLSchema} */ @PublicApi @@ -25,20 +33,35 @@ public class RuntimeWiring { private final Map defaultDataFetchers; private final Map scalars; private final Map typeResolvers; - private final Map directiveWiring; + private final Map registeredDirectiveWiring; + private final List directiveWiring; private final WiringFactory wiringFactory; private final Map enumValuesProviders; private final GraphqlFieldVisibility fieldVisibility; + private final GraphQLCodeRegistry codeRegistry; + private final GraphqlTypeComparatorRegistry comparatorRegistry; - private RuntimeWiring(Map> dataFetchers, Map defaultDataFetchers, Map scalars, Map typeResolvers, Map directiveWiring, Map enumValuesProviders, WiringFactory wiringFactory, GraphqlFieldVisibility fieldVisibility) { - this.dataFetchers = dataFetchers; - this.defaultDataFetchers = defaultDataFetchers; - this.scalars = scalars; - this.typeResolvers = typeResolvers; - this.directiveWiring = directiveWiring; - this.wiringFactory = wiringFactory; - this.enumValuesProviders = enumValuesProviders; - this.fieldVisibility = fieldVisibility; + /** + * This is a Runtime wiring which provides mocked types resolver + * and scalars. It is useful for testing only, for example for creating schemas + * that can be inspected but not executed on. + */ + public static final RuntimeWiring MOCKED_WIRING = RuntimeWiring + .newRuntimeWiring() + .wiringFactory(new MockedWiringFactory()).build(); + + private RuntimeWiring(Builder builder) { + this.dataFetchers = builder.dataFetchers; + this.defaultDataFetchers = builder.defaultDataFetchers; + this.scalars = builder.scalars; + this.typeResolvers = builder.typeResolvers; + this.registeredDirectiveWiring = builder.registeredDirectiveWiring; + this.directiveWiring = builder.directiveWiring; + this.wiringFactory = builder.wiringFactory; + this.enumValuesProviders = builder.enumValuesProviders; + this.fieldVisibility = builder.fieldVisibility; + this.codeRegistry = builder.codeRegistry; + this.comparatorRegistry = builder.comparatorRegistry; } /** @@ -48,6 +71,45 @@ public static Builder newRuntimeWiring() { return new Builder(); } + /** + * @param originalRuntimeWiring the runtime wiring to start from + * + * @return a builder of Runtime Wiring based on the provided one + */ + public static Builder newRuntimeWiring(RuntimeWiring originalRuntimeWiring) { + Builder builder = new Builder(); + builder.dataFetchers.putAll(originalRuntimeWiring.dataFetchers); + builder.defaultDataFetchers.putAll(originalRuntimeWiring.defaultDataFetchers); + builder.scalars.putAll(originalRuntimeWiring.scalars); + builder.typeResolvers.putAll(originalRuntimeWiring.typeResolvers); + builder.registeredDirectiveWiring.putAll(originalRuntimeWiring.registeredDirectiveWiring); + builder.directiveWiring.addAll(originalRuntimeWiring.directiveWiring); + builder.wiringFactory = originalRuntimeWiring.wiringFactory; + builder.enumValuesProviders.putAll(originalRuntimeWiring.enumValuesProviders); + builder.fieldVisibility = originalRuntimeWiring.fieldVisibility; + builder.codeRegistry = originalRuntimeWiring.codeRegistry; + builder.comparatorRegistry = originalRuntimeWiring.comparatorRegistry; + return builder; + } + + /** + * This helps you transform the current RuntimeWiring object into another one by starting a builder with all + * the current values and allows you to transform it how you want. + * + * @param builderConsumer the consumer code that will be given a builder to transform + * + * @return a new RuntimeWiring object based on calling build on that builder + */ + public RuntimeWiring transform(Consumer builderConsumer) { + Builder builder = newRuntimeWiring(this); + builderConsumer.accept(builder); + return builder.build(); + } + + public GraphQLCodeRegistry getCodeRegistry() { + return codeRegistry; + } + public Map getScalars() { return new LinkedHashMap<>(scalars); } @@ -56,10 +118,31 @@ public Map> getDataFetchers() { return dataFetchers; } + /** + * This is deprecated because the name has the wrong plural case. + * + * @param typeName the type for fetch a map of per field data fetchers for + * + * @return a map of field data fetchers for a type + * + * @deprecated See {@link #getDataFetchersForType(String)} + */ + @Deprecated(since = "2024-04-28") public Map getDataFetcherForType(String typeName) { return dataFetchers.computeIfAbsent(typeName, k -> new LinkedHashMap<>()); } + /** + * This returns a map of the data fetchers per field on that named type. + * + * @param typeName the type for fetch a map of per field data fetchers for + * + * @return a map of field data fetchers for a type + */ + public Map getDataFetchersForType(String typeName) { + return dataFetchers.computeIfAbsent(typeName, k -> new LinkedHashMap<>()); + } + public DataFetcher getDefaultDataFetcherForType(String typeName) { return defaultDataFetchers.get(typeName); } @@ -80,25 +163,59 @@ public GraphqlFieldVisibility getFieldVisibility() { return fieldVisibility; } - public Map getDirectiveWiring() { + public Map getRegisteredDirectiveWiring() { + return registeredDirectiveWiring; + } + + public List getDirectiveWiring() { return directiveWiring; } + public GraphqlTypeComparatorRegistry getComparatorRegistry() { + return comparatorRegistry; + } + @PublicApi + @NullUnmarked public static class Builder { private final Map> dataFetchers = new LinkedHashMap<>(); private final Map defaultDataFetchers = new LinkedHashMap<>(); private final Map scalars = new LinkedHashMap<>(); private final Map typeResolvers = new LinkedHashMap<>(); private final Map enumValuesProviders = new LinkedHashMap<>(); - private final Map directiveWiring = new LinkedHashMap<>(); + private final Map registeredDirectiveWiring = new LinkedHashMap<>(); + private final List directiveWiring = new ArrayList<>(); private WiringFactory wiringFactory = new NoopWiringFactory(); + private boolean strictMode = true; private GraphqlFieldVisibility fieldVisibility = DEFAULT_FIELD_VISIBILITY; + private GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry().build(); + private GraphqlTypeComparatorRegistry comparatorRegistry = GraphqlTypeComparatorRegistry.AS_IS_REGISTRY; private Builder() { - ScalarInfo.STANDARD_SCALARS.forEach(this::scalar); - // we give this out by default - directiveWiring.put(FetchSchemaDirectiveWiring.FETCH, new FetchSchemaDirectiveWiring()); + ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS.forEach(this::scalar); + } + + /** + * This sets strict mode as true or false. If strictMode is true, if things get defined twice, for example, it will throw a {@link StrictModeWiringException}. + * + * @return this builder + */ + public Builder strictMode(boolean strictMode) { + this.strictMode = strictMode; + return this; + } + + /** + * This puts the builder into strict mode, so if things get defined twice, for example, it will throw a {@link StrictModeWiringException}. + * + * @return this builder + * + * @deprecated strictMode default value changed to true, use {@link #strictMode(boolean)} instead + */ + @Deprecated(since = "2025-03-22", forRemoval = true) + public Builder strictMode() { + this.strictMode = true; + return this; } /** @@ -114,6 +231,30 @@ public Builder wiringFactory(WiringFactory wiringFactory) { return this; } + /** + * This allows you to seed in your own {@link graphql.schema.GraphQLCodeRegistry} instance + * + * @param codeRegistry the code registry to use + * + * @return this outer builder + */ + public Builder codeRegistry(GraphQLCodeRegistry codeRegistry) { + this.codeRegistry = assertNotNull(codeRegistry); + return this; + } + + /** + * This allows you to seed in your own {@link graphql.schema.GraphQLCodeRegistry} instance + * + * @param codeRegistry the code registry to use + * + * @return this outer builder + */ + public Builder codeRegistry(GraphQLCodeRegistry.Builder codeRegistry) { + this.codeRegistry = assertNotNull(codeRegistry).build(); + return this; + } + /** * This allows you to add in new custom Scalar implementations beyond the standard set. * @@ -122,6 +263,9 @@ public Builder wiringFactory(WiringFactory wiringFactory) { * @return the runtime wiring builder */ public Builder scalar(GraphQLScalarType scalarType) { + if (strictMode && scalars.containsKey(scalarType.getName())) { + throw new StrictModeWiringException(format("The scalar %s is already defined", scalarType.getName())); + } scalars.put(scalarType.getName(), scalarType); return this; } @@ -172,17 +316,39 @@ public Builder type(String typeName, UnaryOperator bu public Builder type(TypeRuntimeWiring typeRuntimeWiring) { String typeName = typeRuntimeWiring.getTypeName(); Map typeDataFetchers = dataFetchers.computeIfAbsent(typeName, k -> new LinkedHashMap<>()); - typeRuntimeWiring.getFieldDataFetchers().forEach(typeDataFetchers::put); - defaultDataFetchers.put(typeName, typeRuntimeWiring.getDefaultDataFetcher()); + Map additionalFieldDataFetchers = typeRuntimeWiring.getFieldDataFetchers(); + if (strictMode && !typeDataFetchers.isEmpty()) { + // Check if the existing type wiring contains overlapping DataFetcher definitions + for (String fieldName : additionalFieldDataFetchers.keySet()) { + if (typeDataFetchers.containsKey(fieldName)) { + throw new StrictModeWiringException(format("The field %s on type %s has already been defined", fieldName, typeName)); + } + } + } + typeDataFetchers.putAll(additionalFieldDataFetchers); + + DataFetcher defaultDataFetcher = typeRuntimeWiring.getDefaultDataFetcher(); + if (defaultDataFetcher != null) { + if (strictMode && defaultDataFetchers.containsKey(typeName)) { + throw new StrictModeWiringException(format("The type %s already has a default data fetcher defined", typeName)); + } + defaultDataFetchers.put(typeName, defaultDataFetcher); + } TypeResolver typeResolver = typeRuntimeWiring.getTypeResolver(); if (typeResolver != null) { + if (strictMode && this.typeResolvers.containsKey(typeName)) { + throw new StrictModeWiringException(format("The type %s already has a type resolver defined", typeName)); + } this.typeResolvers.put(typeName, typeResolver); } EnumValuesProvider enumValuesProvider = typeRuntimeWiring.getEnumValuesProvider(); if (enumValuesProvider != null) { + if (strictMode && this.enumValuesProviders.containsKey(typeName)) { + throw new StrictModeWiringException(format("The type %s already has a enum provider defined", typeName)); + } this.enumValuesProviders.put(typeName, enumValuesProvider); } return this; @@ -190,28 +356,70 @@ public Builder type(TypeRuntimeWiring typeRuntimeWiring) { /** * This provides the wiring code for a named directive. + *

+ * Note: The provided directive wiring will ONLY be called back if an element has a directive + * with the specified name. + *

+ * To be called back for every directive the use {@link #directiveWiring(SchemaDirectiveWiring)} or + * use {@link graphql.schema.idl.WiringFactory#providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment)} + * instead. * * @param directiveName the name of the directive to wire * @param schemaDirectiveWiring the runtime behaviour of this wiring * * @return the runtime wiring builder * + * @see #directiveWiring(SchemaDirectiveWiring) * @see graphql.schema.idl.SchemaDirectiveWiring + * @see graphql.schema.idl.WiringFactory#providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment) */ public Builder directive(String directiveName, SchemaDirectiveWiring schemaDirectiveWiring) { - directiveWiring.put(directiveName, schemaDirectiveWiring); + registeredDirectiveWiring.put(directiveName, schemaDirectiveWiring); + return this; + } + + /** + * This adds a directive wiring that will be called for all directives. + *

+ * Note : Unlike {@link #directive(String, SchemaDirectiveWiring)} which is only called back if a named + * directives is present, this directive wiring will be called back for every element + * in the schema even if it has zero directives. + * + * @param schemaDirectiveWiring the runtime behaviour of this wiring + * + * @return the runtime wiring builder + * + * @see #directive(String, SchemaDirectiveWiring) + * @see graphql.schema.idl.SchemaDirectiveWiring + * @see graphql.schema.idl.WiringFactory#providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment) + */ + public Builder directiveWiring(SchemaDirectiveWiring schemaDirectiveWiring) { + directiveWiring.add(schemaDirectiveWiring); return this; } + /** + * You can specify your own sort order of graphql types via {@link graphql.schema.GraphqlTypeComparatorRegistry} + * which will tell you what type of objects you are to sort when + * it asks for a comparator. + * + * @param comparatorRegistry your own comparator registry + * + * @return the runtime wiring builder + */ + public Builder comparatorRegistry(GraphqlTypeComparatorRegistry comparatorRegistry) { + this.comparatorRegistry = comparatorRegistry; + return this; + } + + /** * @return the built runtime wiring */ public RuntimeWiring build() { - return new RuntimeWiring(dataFetchers, defaultDataFetchers, scalars, typeResolvers, directiveWiring, enumValuesProviders, wiringFactory, fieldVisibility); + return new RuntimeWiring(this); } } - - } diff --git a/src/main/java/graphql/schema/idl/ScalarInfo.java b/src/main/java/graphql/schema/idl/ScalarInfo.java index 258872ba72..fca5ee7509 100644 --- a/src/main/java/graphql/schema/idl/ScalarInfo.java +++ b/src/main/java/graphql/schema/idl/ScalarInfo.java @@ -1,99 +1,49 @@ package graphql.schema.idl; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import graphql.PublicApi; import graphql.Scalars; import graphql.language.ScalarTypeDefinition; import graphql.schema.GraphQLScalarType; +import org.jspecify.annotations.NullMarked; -import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Info on all the standard scalar objects provided by graphql-java */ +@PublicApi +@NullMarked public class ScalarInfo { - /** - * A list of the scalar types provided by graphql-java - */ - public static final List STANDARD_SCALARS = new ArrayList<>(); /** * A list of the built-in scalar types as defined by the graphql specification */ - public static final List GRAPHQL_SPECIFICATION_SCALARS = new ArrayList<>(); + public static final List GRAPHQL_SPECIFICATION_SCALARS = ImmutableList.of( + Scalars.GraphQLInt, + Scalars.GraphQLFloat, + Scalars.GraphQLString, + Scalars.GraphQLBoolean, + Scalars.GraphQLID); /** * A map of scalar type definitions provided by graphql-java */ - public static final Map STANDARD_SCALAR_DEFINITIONS = new LinkedHashMap<>(); - - static { - GRAPHQL_SPECIFICATION_SCALARS.add(Scalars.GraphQLInt); - GRAPHQL_SPECIFICATION_SCALARS.add(Scalars.GraphQLFloat); - GRAPHQL_SPECIFICATION_SCALARS.add(Scalars.GraphQLString); - GRAPHQL_SPECIFICATION_SCALARS.add(Scalars.GraphQLBoolean); - GRAPHQL_SPECIFICATION_SCALARS.add(Scalars.GraphQLID); - - STANDARD_SCALARS.add(Scalars.GraphQLInt); - STANDARD_SCALARS.add(Scalars.GraphQLFloat); - STANDARD_SCALARS.add(Scalars.GraphQLString); - STANDARD_SCALARS.add(Scalars.GraphQLBoolean); - STANDARD_SCALARS.add(Scalars.GraphQLID); - - STANDARD_SCALARS.add(Scalars.GraphQLBigDecimal); - STANDARD_SCALARS.add(Scalars.GraphQLBigInteger); - STANDARD_SCALARS.add(Scalars.GraphQLByte); - STANDARD_SCALARS.add(Scalars.GraphQLChar); - STANDARD_SCALARS.add(Scalars.GraphQLShort); - STANDARD_SCALARS.add(Scalars.GraphQLLong); - } - - static { - // graphql standard scalars - STANDARD_SCALAR_DEFINITIONS.put("Int", ScalarTypeDefinition.newScalarTypeDefinition().name("Int").build()); - STANDARD_SCALAR_DEFINITIONS.put("Float", ScalarTypeDefinition.newScalarTypeDefinition().name("Float").build()); - STANDARD_SCALAR_DEFINITIONS.put("String", ScalarTypeDefinition.newScalarTypeDefinition().name("String").build()); - STANDARD_SCALAR_DEFINITIONS.put("Boolean", ScalarTypeDefinition.newScalarTypeDefinition().name("Boolean").build()); - STANDARD_SCALAR_DEFINITIONS.put("ID", ScalarTypeDefinition.newScalarTypeDefinition().name("ID").build()); - - // graphql-java library extensions - STANDARD_SCALAR_DEFINITIONS.put("Long", ScalarTypeDefinition.newScalarTypeDefinition().name("Long").build()); - STANDARD_SCALAR_DEFINITIONS.put("BigInteger", ScalarTypeDefinition.newScalarTypeDefinition().name("BigInteger").build()); - STANDARD_SCALAR_DEFINITIONS.put("BigDecimal", ScalarTypeDefinition.newScalarTypeDefinition().name("BigDecimal").build()); - STANDARD_SCALAR_DEFINITIONS.put("Short", ScalarTypeDefinition.newScalarTypeDefinition().name("Short").build()); - STANDARD_SCALAR_DEFINITIONS.put("Char", ScalarTypeDefinition.newScalarTypeDefinition().name("Char").build()); - - } - - /** - * Returns true if the scalar type is a standard one provided by graphql-java - * - * @param scalarType the type in question - * - * @return true if the scalar type is a graphql-java provided scalar - */ - public static boolean isStandardScalar(GraphQLScalarType scalarType) { - return inList(STANDARD_SCALARS, scalarType.getName()); - } - - /** - * Returns true if the scalar type is a standard one provided by graphql-java - * - * @param scalarTypeName the name of the scalar type in question - * - * @return true if the scalar type is a graphql-java provided scalar - */ - public static boolean isStandardScalar(String scalarTypeName) { - return inList(STANDARD_SCALARS, scalarTypeName); - } + public static final Map GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS = ImmutableMap.of( + "Int", ScalarTypeDefinition.newScalarTypeDefinition().name("Int").build(), + "Float", ScalarTypeDefinition.newScalarTypeDefinition().name("Float").build(), + "String", ScalarTypeDefinition.newScalarTypeDefinition().name("String").build(), + "Boolean", ScalarTypeDefinition.newScalarTypeDefinition().name("Boolean").build(), + "ID", ScalarTypeDefinition.newScalarTypeDefinition().name("ID").build()); /** * Returns true if the scalar type is a scalar that is specified by the graphql specification * * @param scalarTypeName the name of the scalar type in question * - * @return true if the scalar type is is specified by the graphql specification + * @return true if the scalar type is specified by the graphql specification */ public static boolean isGraphqlSpecifiedScalar(String scalarTypeName) { return inList(GRAPHQL_SPECIFICATION_SCALARS, scalarTypeName); @@ -104,7 +54,7 @@ public static boolean isGraphqlSpecifiedScalar(String scalarTypeName) { * * @param scalarType the type in question * - * @return true if the scalar type is is specified by the graphql specification + * @return true if the scalar type is specified by the graphql specification */ public static boolean isGraphqlSpecifiedScalar(GraphQLScalarType scalarType) { return inList(GRAPHQL_SPECIFICATION_SCALARS, scalarType.getName()); diff --git a/src/main/java/graphql/schema/idl/ScalarWiringEnvironment.java b/src/main/java/graphql/schema/idl/ScalarWiringEnvironment.java index df8dad7935..ec39199a48 100644 --- a/src/main/java/graphql/schema/idl/ScalarWiringEnvironment.java +++ b/src/main/java/graphql/schema/idl/ScalarWiringEnvironment.java @@ -3,10 +3,12 @@ import graphql.PublicApi; import graphql.language.ScalarTypeDefinition; import graphql.language.ScalarTypeExtensionDefinition; +import org.jspecify.annotations.NullMarked; import java.util.List; @PublicApi +@NullMarked public class ScalarWiringEnvironment extends WiringEnvironment { private final ScalarTypeDefinition scalarTypeDefinition; diff --git a/src/main/java/graphql/schema/idl/SchemaDirectiveWiring.java b/src/main/java/graphql/schema/idl/SchemaDirectiveWiring.java index 19606a6f93..1b136ae9db 100644 --- a/src/main/java/graphql/schema/idl/SchemaDirectiveWiring.java +++ b/src/main/java/graphql/schema/idl/SchemaDirectiveWiring.java @@ -15,16 +15,26 @@ /** * A SchemaDirectiveWiring is responsible for enhancing a runtime element based on directives placed on that * element in the Schema Definition Language (SDL). - * + *

* It can enhance the graphql runtime element and add new behaviour for example by changing * the fields {@link graphql.schema.DataFetcher} + *

+ * The SchemaDirectiveWiring objects are called in a specific order based on registration: + *

    + *
  1. {@link graphql.schema.idl.RuntimeWiring.Builder#directive(String, SchemaDirectiveWiring)} which work against a specific named directive are called first
  2. + *
  3. {@link graphql.schema.idl.RuntimeWiring.Builder#directiveWiring(SchemaDirectiveWiring)} which work against all directives are called next
  4. + *
  5. {@link graphql.schema.idl.WiringFactory#providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment)} which work against all directives are called last
  6. + *
*/ @PublicApi public interface SchemaDirectiveWiring { /** * This is called when an object is encountered, which gives the schema directive a chance to modify the shape and behaviour - * of that DSL element + * of that DSL element + *

+ * The {@link #onArgument(SchemaDirectiveWiringEnvironment)} and {@link #onField(SchemaDirectiveWiringEnvironment)} callbacks will have been + * invoked for this element beforehand * * @param environment the wiring element * @@ -36,7 +46,10 @@ default GraphQLObjectType onObject(SchemaDirectiveWiringEnvironment + * The {@link #onArgument(SchemaDirectiveWiringEnvironment)} callbacks will have been + * invoked for this element beforehand * * @param environment the wiring element * @@ -48,7 +61,7 @@ default GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment + * The {@link #onArgument(SchemaDirectiveWiringEnvironment)} and {@link #onField(SchemaDirectiveWiringEnvironment)} callbacks will have been + * invoked for this element beforehand * * @param environment the wiring element * @@ -72,7 +88,7 @@ default GraphQLInterfaceType onInterface(SchemaDirectiveWiringEnvironment + * The {@link #onEnumValue(SchemaDirectiveWiringEnvironment)} callbacks will have been invoked for this element beforehand * * @param environment the wiring element * @@ -96,7 +114,7 @@ default GraphQLEnumType onEnum(SchemaDirectiveWiringEnvironment /** * This is called when an enum value is encountered, which gives the schema directive a chance to modify the shape and behaviour - * of that DSL element + * of that DSL element * * @param environment the wiring element * @@ -121,6 +139,8 @@ default GraphQLScalarType onScalar(SchemaDirectiveWiringEnvironment + * The {@link #onInputObjectField(SchemaDirectiveWiringEnvironment)}callbacks will have been invoked for this element beforehand * * @param environment the wiring element * diff --git a/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironment.java b/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironment.java index f42ba8d1b0..538582ed32 100644 --- a/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironment.java +++ b/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironment.java @@ -3,8 +3,14 @@ import graphql.PublicApi; import graphql.language.NamedNode; import graphql.language.NodeParentTree; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphqlElementParentTree; import java.util.Map; @@ -23,10 +29,79 @@ public interface SchemaDirectiveWiringEnvironment + * If this method of registration is not used (say because + * {@link graphql.schema.idl.WiringFactory#providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment)} or + * {@link graphql.schema.idl.RuntimeWiring.Builder#directiveWiring(SchemaDirectiveWiring)} was used) + * then this will return null. + * + * @return the directive that was registered under specific directive name or null if it was not + * registered this way + * + * @deprecated use {@link #getAppliedDirective()} */ + @Deprecated(since = "2022-06-21") GraphQLDirective getDirective(); + /** + * This returns the applied directive that the {@link graphql.schema.idl.SchemaDirectiveWiring} was registered + * against during calls to {@link graphql.schema.idl.RuntimeWiring.Builder#directive(String, SchemaDirectiveWiring)} + *

+ * If this method of registration is not used (say because + * {@link graphql.schema.idl.WiringFactory#providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment)} or + * {@link graphql.schema.idl.RuntimeWiring.Builder#directiveWiring(SchemaDirectiveWiring)} was used) + * then this will return null. + * + * @return the applied directive that was registered under specific directive name or null if it was not + * registered this way + */ + GraphQLAppliedDirective getAppliedDirective(); + + /** + * @return all of the directives that are on the runtime element + * + * @deprecated use {@link #getAppliedDirectives()} instead + */ + @Deprecated(since = "2022-06-21") + Map getDirectives(); + + /** + * Returns a named directive or null + * + * @param directiveName the name of the directive + * + * @return a named directive or null + * + * @deprecated use {@link #getAppliedDirective(String)} instead + */ + @Deprecated(since = "2022-06-21") + GraphQLDirective getDirective(String directiveName); + + /** + * @return all of the directives that are on the runtime element + */ + Map getAppliedDirectives(); + + /** + * Returns a named applied directive or null + * + * @param directiveName the name of the directive + * + * @return a named directive or null + */ + GraphQLAppliedDirective getAppliedDirective(String directiveName); + + /** + * Returns true if the named directive is present + * + * @param directiveName the name of the directive + * + * @return true if the named directive is present + */ + boolean containsDirective(String directiveName); + /** * The node hierarchy depends on the element in question. For example {@link graphql.language.ObjectTypeDefinition} nodes * have no parent, however a {@link graphql.language.Argument} might be on a {@link graphql.language.FieldDefinition} @@ -34,7 +109,16 @@ public interface SchemaDirectiveWiringEnvironment getNodeParentTree(); + NodeParentTree> getNodeParentTree(); + + /** + * The type hierarchy depends on the element in question. For example {@link graphql.schema.GraphQLObjectType} elements + * have no parent, however a {@link graphql.schema.GraphQLArgument} might be on a {@link graphql.schema.GraphQLFieldDefinition} + * which in turn might be on a {@link graphql.schema.GraphQLObjectType} say + * + * @return hierarchical graphql type information + */ + GraphqlElementParentTree getElementParentTree(); /** * @return the type registry @@ -42,8 +126,47 @@ public interface SchemaDirectiveWiringEnvironment getBuildContext(); + + /** + * @return a builder of the current code registry builder + */ + GraphQLCodeRegistry.Builder getCodeRegistry(); + + /** + * @return a {@link graphql.schema.GraphQLFieldsContainer} when the element is contained with a fields container + */ + GraphQLFieldsContainer getFieldsContainer(); + + /** + * @return a {@link GraphQLFieldDefinition} when the element is as field or is contained within one + */ + GraphQLFieldDefinition getFieldDefinition(); + + /** + * This is useful as a shortcut to get the current fields existing data fetcher + * + * @return a {@link graphql.schema.DataFetcher} when the element is as field or is contained within one + * + * @throws graphql.AssertException if there is not field in context at the time of the directive wiring callback + */ + DataFetcher getFieldDataFetcher(); + + /** + * This is a shortcut method to set a new data fetcher in the underlying {@link graphql.schema.GraphQLCodeRegistry} + * against the current field. + *

+ * Often schema directive wiring modify behaviour by wrapping or replacing data fetchers on + * fields. This method is a helper to make this easier in code. + * + * @param newDataFetcher the new data fetcher to use for this field + * + * @return the environments {@link #getFieldDefinition()} to allow for a more fluent code style + * + * @throws graphql.AssertException if there is not field in context at the time of the directive wiring callback */ - Map getBuildContext(); + GraphQLFieldDefinition setFieldDataFetcher(DataFetcher newDataFetcher); } diff --git a/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironmentImpl.java b/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironmentImpl.java index 344ef8913b..da1eadf3cb 100644 --- a/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironmentImpl.java +++ b/src/main/java/graphql/schema/idl/SchemaDirectiveWiringEnvironmentImpl.java @@ -3,26 +3,52 @@ import graphql.Internal; import graphql.language.NamedNode; import graphql.language.NodeParentTree; +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphqlElementParentTree; +import graphql.util.FpKit; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import static graphql.Assert.assertNotNull; + @Internal public class SchemaDirectiveWiringEnvironmentImpl implements SchemaDirectiveWiringEnvironment { private final T element; - private final GraphQLDirective directive; - private final NodeParentTree nodeParentTree; + private final Map directives; + private final Map appliedDirectives; + private final NodeParentTree> nodeParentTree; private final TypeDefinitionRegistry typeDefinitionRegistry; private final Map context; + private final GraphQLCodeRegistry.Builder codeRegistry; + private final GraphqlElementParentTree elementParentTree; + private final GraphQLFieldsContainer fieldsContainer; + private final GraphQLFieldDefinition fieldDefinition; + private final GraphQLDirective registeredDirective; + private final GraphQLAppliedDirective registeredAppliedDirective; - public SchemaDirectiveWiringEnvironmentImpl(T element, GraphQLDirective directive, NodeParentTree nodeParentTree, TypeDefinitionRegistry typeDefinitionRegistry, Map context) { + public SchemaDirectiveWiringEnvironmentImpl(T element, List directives, List appliedDirectives, GraphQLAppliedDirective registeredAppliedDirective, GraphQLDirective registeredDirective, SchemaGeneratorDirectiveHelper.Parameters parameters) { this.element = element; - this.nodeParentTree = nodeParentTree; - this.typeDefinitionRegistry = typeDefinitionRegistry; - this.directive = directive; - this.context = context; + this.registeredAppliedDirective = registeredAppliedDirective; + this.registeredDirective = registeredDirective; + this.typeDefinitionRegistry = parameters.getTypeRegistry(); + this.directives = FpKit.getByName(directives, GraphQLDirective::getName); + this.appliedDirectives = FpKit.getByName(appliedDirectives, GraphQLAppliedDirective::getName); + this.context = parameters.getContext(); + this.codeRegistry = parameters.getCodeRegistry(); + this.nodeParentTree = parameters.getNodeParentTree(); + this.elementParentTree = parameters.getElementParentTree(); + this.fieldsContainer = parameters.getFieldsContainer(); + this.fieldDefinition = parameters.getFieldsDefinition(); } @Override @@ -32,11 +58,41 @@ public T getElement() { @Override public GraphQLDirective getDirective() { - return directive; + return registeredDirective; + } + + @Override + public GraphQLAppliedDirective getAppliedDirective() { + return registeredAppliedDirective; + } + + @Override + public Map getDirectives() { + return new LinkedHashMap<>(directives); + } + + @Override + public GraphQLDirective getDirective(String directiveName) { + return directives.get(directiveName); + } + + @Override + public Map getAppliedDirectives() { + return appliedDirectives; + } + + @Override + public GraphQLAppliedDirective getAppliedDirective(String directiveName) { + return appliedDirectives.get(directiveName); + } + + @Override + public boolean containsDirective(String directiveName) { + return directives.containsKey(directiveName); } @Override - public NodeParentTree getNodeParentTree() { + public NodeParentTree> getNodeParentTree() { return nodeParentTree; } @@ -49,4 +105,41 @@ public TypeDefinitionRegistry getRegistry() { public Map getBuildContext() { return context; } + + @Override + public GraphQLCodeRegistry.Builder getCodeRegistry() { + return codeRegistry; + } + + @Override + public GraphQLFieldsContainer getFieldsContainer() { + return fieldsContainer; + } + + @Override + public GraphqlElementParentTree getElementParentTree() { + return elementParentTree; + } + + @Override + public GraphQLFieldDefinition getFieldDefinition() { + return fieldDefinition; + } + + @Override + public DataFetcher getFieldDataFetcher() { + assertNotNull(fieldDefinition, "An output field must be in context to call this method"); + assertNotNull(fieldsContainer, "An output field container must be in context to call this method"); + return codeRegistry.getDataFetcher(FieldCoordinates.coordinates(fieldsContainer, fieldDefinition), fieldDefinition); + } + + @Override + public GraphQLFieldDefinition setFieldDataFetcher(DataFetcher newDataFetcher) { + assertNotNull(fieldDefinition, "An output field must be in context to call this method"); + assertNotNull(fieldsContainer, "An output field container must be in context to call this method"); + + FieldCoordinates coordinates = FieldCoordinates.coordinates(fieldsContainer, fieldDefinition); + codeRegistry.dataFetcher(coordinates, newDataFetcher); + return fieldDefinition; + } } diff --git a/src/main/java/graphql/schema/idl/SchemaDirectiveWiringSchemaGeneratorPostProcessing.java b/src/main/java/graphql/schema/idl/SchemaDirectiveWiringSchemaGeneratorPostProcessing.java new file mode 100644 index 0000000000..52f8badbb4 --- /dev/null +++ b/src/main/java/graphql/schema/idl/SchemaDirectiveWiringSchemaGeneratorPostProcessing.java @@ -0,0 +1,144 @@ +package graphql.schema.idl; + +import graphql.Internal; +import graphql.language.NamedNode; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.schema.SchemaTransformer; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.util.TreeTransformerUtil; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import static graphql.util.TraversalControl.CONTINUE; + +@Internal +class SchemaDirectiveWiringSchemaGeneratorPostProcessing { + + private final SchemaGeneratorDirectiveHelper generatorDirectiveHelper = new SchemaGeneratorDirectiveHelper(); + private final TypeDefinitionRegistry typeRegistry; + private final RuntimeWiring runtimeWiring; + private final GraphQLCodeRegistry.Builder codeRegistryBuilder; + private final Map directiveBehaviourContext = new HashMap<>(); + + + public SchemaDirectiveWiringSchemaGeneratorPostProcessing(TypeDefinitionRegistry typeRegistry, RuntimeWiring runtimeWiring, GraphQLCodeRegistry.Builder codeRegistryBuilder) { + this.typeRegistry = typeRegistry; + this.runtimeWiring = runtimeWiring; + this.codeRegistryBuilder = codeRegistryBuilder; + } + + + public GraphQLSchema process(GraphQLSchema originalSchema) { + codeRegistryBuilder.trackChanges(); + Visitor visitor = new Visitor(); + GraphQLSchema newSchema = SchemaTransformer.transformSchema(originalSchema, visitor); + if (visitor.schemaChanged() || codeRegistryBuilder.hasChanged()) { + return newSchema.transform(builder -> { + // they could have changed the code registry so rebuild it + GraphQLCodeRegistry codeRegistry = this.codeRegistryBuilder.build(); + builder.codeRegistry(codeRegistry); + }); + } + return newSchema; + } + + public class Visitor extends GraphQLTypeVisitorStub { + + private boolean schemaChanged = false; + + public boolean schemaChanged() { + return schemaChanged; + } + + private SchemaGeneratorDirectiveHelper.Parameters mkBehaviourParams() { + return new SchemaGeneratorDirectiveHelper.Parameters(typeRegistry, runtimeWiring, directiveBehaviourContext, codeRegistryBuilder); + } + + private TraversalControl changOrContinue(GraphQLSchemaElement node, GraphQLSchemaElement newNode, TraverserContext context) { + if (node != newNode) { + TreeTransformerUtil.changeNode(context, newNode); + schemaChanged = true; + } + return CONTINUE; + } + + private boolean isIntrospectionType(GraphQLNamedType type) { + return type.getName().startsWith("__"); + } + + private boolean notSuitable(T node, Function> suitableFunc) { + if (isIntrospectionType(node)) { + return true; + } + NamedNode definition = suitableFunc.apply(node); + return definition == null; + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (notSuitable(node, GraphQLObjectType::getDefinition)) { + return CONTINUE; + } + GraphQLSchemaElement newNode = generatorDirectiveHelper.onObject(node, mkBehaviourParams()); + return changOrContinue(node, newNode, context); + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + if (notSuitable(node, GraphQLInterfaceType::getDefinition)) { + return CONTINUE; + } + GraphQLSchemaElement newNode = generatorDirectiveHelper.onInterface(node, mkBehaviourParams()); + return changOrContinue(node, newNode, context); + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context) { + if (notSuitable(node, GraphQLEnumType::getDefinition)) { + return CONTINUE; + } + GraphQLSchemaElement newNode = generatorDirectiveHelper.onEnum(node, mkBehaviourParams()); + return changOrContinue(node, newNode, context); + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + if (notSuitable(node, GraphQLInputObjectType::getDefinition)) { + return CONTINUE; + } + GraphQLSchemaElement newNode = generatorDirectiveHelper.onInputObjectType(node, mkBehaviourParams()); + return changOrContinue(node, newNode, context); + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + if (notSuitable(node, GraphQLScalarType::getDefinition)) { + return CONTINUE; + } + GraphQLSchemaElement newNode = generatorDirectiveHelper.onScalar(node, mkBehaviourParams()); + return changOrContinue(node, newNode, context); + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + if (notSuitable(node, GraphQLUnionType::getDefinition)) { + return CONTINUE; + } + GraphQLSchemaElement newNode = generatorDirectiveHelper.onUnion(node, mkBehaviourParams()); + return changOrContinue(node, newNode, context); + } + } +} diff --git a/src/main/java/graphql/schema/idl/SchemaExtensionsChecker.java b/src/main/java/graphql/schema/idl/SchemaExtensionsChecker.java new file mode 100644 index 0000000000..085af8b1b3 --- /dev/null +++ b/src/main/java/graphql/schema/idl/SchemaExtensionsChecker.java @@ -0,0 +1,130 @@ +package graphql.schema.idl; + +import graphql.Assert; +import graphql.GraphQLError; +import graphql.Internal; +import graphql.language.Directive; +import graphql.language.ObjectTypeDefinition; +import graphql.language.OperationTypeDefinition; +import graphql.language.SchemaDefinition; +import graphql.language.SchemaExtensionDefinition; +import graphql.language.Type; +import graphql.language.TypeDefinition; +import graphql.language.TypeName; +import graphql.schema.idl.errors.MissingTypeError; +import graphql.schema.idl.errors.OperationRedefinitionError; +import graphql.schema.idl.errors.OperationTypesMustBeObjects; +import graphql.schema.idl.errors.QueryOperationMissingError; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +@Internal +public class SchemaExtensionsChecker { + + static Map gatherOperationDefs(TypeDefinitionRegistry typeRegistry) { + List noErrors = new ArrayList<>(); + Map operationTypeDefinitionMap = gatherOperationDefs(noErrors, typeRegistry.schemaDefinition().orElse(null), typeRegistry.getSchemaExtensionDefinitions()); + Assert.assertTrue(noErrors.isEmpty(), "If you call this method it MUST have previously been error checked"); + return operationTypeDefinitionMap; + } + + static Map gatherOperationDefs(List errors, SchemaDefinition schema, List schemaExtensionDefinitions) { + Map operationDefs = new LinkedHashMap<>(); + if (schema != null) { + defineOperationDefs(errors, schema.getOperationTypeDefinitions(), operationDefs); + } + for (SchemaExtensionDefinition schemaExtensionDefinition : schemaExtensionDefinitions) { + defineOperationDefs(errors, schemaExtensionDefinition.getOperationTypeDefinitions(), operationDefs); + } + return operationDefs; + } + + static void defineOperationDefs(List errors, Collection newOperationDefs, Map existingOperationDefs) { + for (OperationTypeDefinition operationTypeDefinition : newOperationDefs) { + OperationTypeDefinition oldEntry = existingOperationDefs.get(operationTypeDefinition.getName()); + if (oldEntry != null) { + errors.add(new OperationRedefinitionError(oldEntry, operationTypeDefinition)); + } else { + existingOperationDefs.put(operationTypeDefinition.getName(), operationTypeDefinition); + } + } + } + + static List checkSchemaInvariants(List errors, TypeDefinitionRegistry typeRegistry) { + /* + https://github.com/facebook/graphql/pull/90/files#diff-fe406b08746616e2f5f00909488cce66R1000 + + GraphQL type system definitions can omit the schema definition when the query + and mutation root types are named `Query` and `Mutation`, respectively. + */ + // schema + SchemaDefinition schemaDef = typeRegistry.schemaDefinition().orElse(null); + Map operationTypeMap = SchemaExtensionsChecker.gatherOperationDefs(errors, schemaDef, typeRegistry.getSchemaExtensionDefinitions()); + List operationTypeDefinitions = new ArrayList<>(operationTypeMap.values()); + + operationTypeDefinitions + .forEach(checkOperationTypesExist(typeRegistry, errors)); + + operationTypeDefinitions + .forEach(checkOperationTypesAreObjects(typeRegistry, errors)); + + // ensure we have a "query" one + Optional query = operationTypeDefinitions.stream().filter(op -> "query".equals(op.getName())).findFirst(); + if (query.isEmpty()) { + // its ok if they have a type named Query + TypeDefinition queryType = typeRegistry.getTypeOrNull("Query"); + if (queryType == null) { + errors.add(new QueryOperationMissingError()); + } + } + return operationTypeDefinitions; + } + + static List gatherSchemaDirectives(TypeDefinitionRegistry typeRegistry) { + List noErrors = new ArrayList<>(); + List directiveList = gatherSchemaDirectives(typeRegistry, noErrors); + Assert.assertTrue(noErrors.isEmpty(), "If you call this method it MUST have previously been error checked"); + return directiveList; + } + + static List gatherSchemaDirectives(TypeDefinitionRegistry typeRegistry, List errors) { + List directiveList = new ArrayList<>(); + SchemaDefinition schemaDefinition = typeRegistry.schemaDefinition().orElse(null); + if (schemaDefinition != null) { + directiveList.addAll(schemaDefinition.getDirectives()); + } + for (SchemaExtensionDefinition schemaExtensionDefinition : typeRegistry.getSchemaExtensionDefinitions()) { + directiveList.addAll(schemaExtensionDefinition.getDirectives()); + } + return directiveList; + } + + private static Consumer checkOperationTypesExist(TypeDefinitionRegistry typeRegistry, List errors) { + return op -> { + TypeName unwrapped = TypeInfo.typeInfo(op.getTypeName()).getTypeName(); + if (!typeRegistry.hasType(unwrapped)) { + errors.add(new MissingTypeError("operation", op, op.getName(), unwrapped)); + } + }; + } + + private static Consumer checkOperationTypesAreObjects(TypeDefinitionRegistry typeRegistry, List errors) { + return op -> { + // make sure it is defined as a ObjectTypeDef + Type queryType = op.getTypeName(); + TypeDefinition type = typeRegistry.getTypeOrNull(queryType); + if (type != null) { + if (!(type instanceof ObjectTypeDefinition)) { + errors.add(new OperationTypesMustBeObjects(op)); + } + } + }; + } + +} diff --git a/src/main/java/graphql/schema/idl/SchemaGenerator.java b/src/main/java/graphql/schema/idl/SchemaGenerator.java index 8b14172e7d..c53ef08b8f 100644 --- a/src/main/java/graphql/schema/idl/SchemaGenerator.java +++ b/src/main/java/graphql/schema/idl/SchemaGenerator.java @@ -2,234 +2,72 @@ import graphql.GraphQLError; import graphql.PublicApi; -import graphql.introspection.Introspection.DirectiveLocation; -import graphql.language.Directive; -import graphql.language.EnumTypeDefinition; -import graphql.language.EnumTypeExtensionDefinition; -import graphql.language.EnumValueDefinition; -import graphql.language.FieldDefinition; -import graphql.language.InputObjectTypeDefinition; -import graphql.language.InputObjectTypeExtensionDefinition; -import graphql.language.InputValueDefinition; -import graphql.language.InterfaceTypeDefinition; -import graphql.language.InterfaceTypeExtensionDefinition; -import graphql.language.NamedNode; -import graphql.language.Node; -import graphql.language.NodeParentTree; -import graphql.language.ObjectTypeDefinition; -import graphql.language.ObjectTypeExtensionDefinition; import graphql.language.OperationTypeDefinition; -import graphql.language.ScalarTypeDefinition; -import graphql.language.ScalarTypeExtensionDefinition; -import graphql.language.SchemaDefinition; -import graphql.language.Type; -import graphql.language.TypeDefinition; -import graphql.language.TypeName; -import graphql.language.UnionTypeDefinition; -import graphql.language.UnionTypeExtensionDefinition; -import graphql.language.Value; -import graphql.schema.DataFetcher; -import graphql.schema.DataFetcherFactories; -import graphql.schema.DataFetcherFactory; -import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLDirective; -import graphql.schema.GraphQLEnumType; -import graphql.schema.GraphQLEnumValueDefinition; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLInputObjectField; -import graphql.schema.GraphQLInputObjectType; -import graphql.schema.GraphQLInputType; -import graphql.schema.GraphQLInterfaceType; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLOutputType; -import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; import graphql.schema.GraphQLType; -import graphql.schema.GraphQLTypeReference; -import graphql.schema.GraphQLUnionType; -import graphql.schema.PropertyDataFetcher; -import graphql.schema.TypeResolver; -import graphql.schema.TypeResolverProxy; -import graphql.schema.idl.errors.NotAnInputTypeError; -import graphql.schema.idl.errors.NotAnOutputTypeError; import graphql.schema.idl.errors.SchemaProblem; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static graphql.Assert.assertNotNull; -import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION; -import static graphql.introspection.Introspection.DirectiveLocation.ENUM; -import static graphql.introspection.Introspection.DirectiveLocation.ENUM_VALUE; -import static graphql.introspection.Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION; -import static graphql.introspection.Introspection.DirectiveLocation.INPUT_OBJECT; -import static graphql.introspection.Introspection.DirectiveLocation.OBJECT; -import static graphql.introspection.Introspection.DirectiveLocation.SCALAR; -import static graphql.introspection.Introspection.DirectiveLocation.UNION; -import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition; -import static graphql.schema.GraphQLTypeReference.typeRef; -import static java.util.Collections.emptyList; + +import static graphql.schema.idl.SchemaGeneratorHelper.buildDescription; + /** * This can generate a working runtime schema from a type registry and runtime wiring + *

+ * The generator uses the {@link RuntimeWiring} to insert code that runs behind the schema + * elements such as {@link graphql.schema.DataFetcher}s, {@link graphql.schema.TypeResolver}s + * and scalar {@link graphql.schema.Coercing}. + *

+ * The order of {@link graphql.schema.DataFetcher} resolution is as follows: + *

    + *
  1. If the {@link WiringFactory} provides the {@link graphql.schema.DataFetcherFactory} for a field in its parent type then that is used
  2. + *
  3. If the {@link WiringFactory} provides the {@link graphql.schema.DataFetcher} for a field in its parent type then that is used
  4. + *
  5. If the {@link RuntimeWiring} provides the {@link graphql.schema.DataFetcher} for a field in its parent type, then that is used
  6. + *
  7. If the {@link RuntimeWiring} provides a default {@link graphql.schema.DataFetcher} for a fields parent type, then that is used
  8. + *
  9. If the {@link WiringFactory} provides a default {@link graphql.schema.DataFetcherFactory} for any element then that is used
  10. + *
  11. If the {@link GraphQLCodeRegistry.Builder#getDefaultDataFetcherFactory()} provides a {@link graphql.schema.DataFetcherFactory} for a value then that is used
  12. + *
  13. Finally a {@link graphql.schema.PropertyDataFetcher} is used as a last resort for the field
  14. + *
+ *

+ * The order of {@link graphql.schema.TypeResolver} resolution is as follows: + *

    + *
  1. If the {@link WiringFactory} provides a {@link graphql.schema.TypeResolver} then that is used
  2. + *
  3. If the {@link TypeRuntimeWiring} provides a {@link graphql.schema.TypeResolver} then that is used
  4. + *
+ *

+ * The order of {@link graphql.schema.GraphQLScalarType} resolution is as follows: + *

    + *
  1. If the {@link WiringFactory} provides a {@link graphql.schema.GraphQLScalarType} then that is used
  2. + *
  3. Otherwise {@link RuntimeWiring#getScalars()} is used
  4. + *
*/ @PublicApi public class SchemaGenerator { - /** - * These options control how the schema generation works - */ - public static class Options { - private final boolean enforceSchemaDirectives; - - Options(boolean enforceSchemaDirectives) { - this.enforceSchemaDirectives = enforceSchemaDirectives; - } - - /** - * This controls whether schema directives MUST be declared using - * directive definition syntax before use. - * - * @return true if directives must be fully declared; the default is true - */ - public boolean isEnforceSchemaDirectives() { - return enforceSchemaDirectives; - } - - public static Options defaultOptions() { - return new Options(true); - } - - /** - * This controls whether schema directives MUST be declared using - * directive definition syntax before use. - * - * @param flag the value to use - * - * @return the new options - */ - public Options enforceSchemaDirectives(boolean flag) { - return new Options(flag); - } + private final SchemaTypeChecker typeChecker = new SchemaTypeChecker(); + private final SchemaGeneratorHelper schemaGeneratorHelper = new SchemaGeneratorHelper(); + public SchemaGenerator() { } - /** - * We pass this around so we know what we have defined in a stack like manner plus - * it gives us helper functions + * Created a schema from the SDL that is has a mocked runtime. + * + * @param sdl the SDL to be mocked + * + * @return a schema with a mocked runtime + * + * @see RuntimeWiring#MOCKED_WIRING */ - class BuildContext { - private final TypeDefinitionRegistry typeRegistry; - private final RuntimeWiring wiring; - private final Deque typeStack = new ArrayDeque<>(); - private final Deque nodeStack = new ArrayDeque<>(); - - private final Map outputGTypes = new HashMap<>(); - private final Map inputGTypes = new HashMap<>(); - private final Map directiveBehaviourContext = new HashMap<>(); - private final Set directiveDefinitions = new HashSet<>(); - - BuildContext(TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) { - this.typeRegistry = typeRegistry; - this.wiring = wiring; - } - - public TypeDefinitionRegistry getTypeRegistry() { - return typeRegistry; - } - - @SuppressWarnings({"OptionalGetWithoutIsPresent", "ConstantConditions"}) - TypeDefinition getTypeDefinition(Type type) { - return typeRegistry.getType(type).get(); - } - - boolean stackContains(TypeInfo typeInfo) { - return typeStack.contains(typeInfo.getName()); - } - - void push(TypeInfo typeInfo) { - typeStack.push(typeInfo.getName()); - } - - void pop() { - typeStack.pop(); - } - - void enterNode(Node node) { - nodeStack.push(node); - } - - T exitNode(T t) { - nodeStack.pop(); - return t; - } - - SchemaGeneratorDirectiveHelper.Parameters mkBehaviourParams() { - List list = nodeStack.stream() - .filter(NamedNode.class::isInstance) - .map(NamedNode.class::cast) - .collect(Collectors.toList()); - Deque deque = new ArrayDeque<>(list); - return new SchemaGeneratorDirectiveHelper.Parameters(typeRegistry, wiring, new NodeParentTree<>(deque), directiveBehaviourContext); - } - - GraphQLOutputType hasOutputType(TypeDefinition typeDefinition) { - return outputGTypes.get(typeDefinition.getName()); - } - - GraphQLInputType hasInputType(TypeDefinition typeDefinition) { - return inputGTypes.get(typeDefinition.getName()); - } - - void putOutputType(GraphQLOutputType outputType) { - outputGTypes.put(outputType.getName(), outputType); - // certain types can be both input and output types, for example enums - if (outputType instanceof GraphQLInputType) { - inputGTypes.put(outputType.getName(), (GraphQLInputType) outputType); - } - } - - void putInputType(GraphQLInputType inputType) { - inputGTypes.put(inputType.getName(), inputType); - // certain types can be both input and output types, for example enums - if (inputType instanceof GraphQLOutputType) { - outputGTypes.put(inputType.getName(), (GraphQLOutputType) inputType); - } - } - - RuntimeWiring getWiring() { - return wiring; - } - - public void setDirectiveDefinitions(Set directiveDefinitions) { - this.directiveDefinitions.addAll(directiveDefinitions); - } - - public Set getDirectiveDefinitions() { - return directiveDefinitions; - } - } - - private final SchemaTypeChecker typeChecker = new SchemaTypeChecker(); - private final SchemaGeneratorHelper schemaGeneratorHelper = new SchemaGeneratorHelper(); - private final SchemaGeneratorDirectiveHelper directiveBehaviour = new SchemaGeneratorDirectiveHelper(); - - public SchemaGenerator() { + public static GraphQLSchema createdMockedSchema(String sdl) { + TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(sdl); + GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, RuntimeWiring.MOCKED_WIRING); + return graphQLSchema; } /** @@ -263,681 +101,130 @@ public GraphQLSchema makeExecutableSchema(Options options, TypeDefinitionRegistr TypeDefinitionRegistry typeRegistryCopy = new TypeDefinitionRegistry(); typeRegistryCopy.merge(typeRegistry); - schemaGeneratorHelper.addDeprecatedDirectiveDefinition(typeRegistryCopy); + schemaGeneratorHelper.addDirectivesIncludedByDefault(typeRegistryCopy); - List errors = typeChecker.checkTypeRegistry(typeRegistryCopy, wiring, options.enforceSchemaDirectives); + // by making it read only all the traversal and checks run faster + ImmutableTypeDefinitionRegistry fasterImmutableRegistry = typeRegistryCopy.readOnly(); + List errors = typeChecker.checkTypeRegistry(fasterImmutableRegistry, wiring); if (!errors.isEmpty()) { throw new SchemaProblem(errors); } - BuildContext buildCtx = new BuildContext(typeRegistryCopy, wiring); - return makeExecutableSchemaImpl(buildCtx); + Map operationTypeDefinitions = SchemaExtensionsChecker.gatherOperationDefs(fasterImmutableRegistry); + + return makeExecutableSchemaImpl(fasterImmutableRegistry, wiring, operationTypeDefinitions, options); } - private GraphQLSchema makeExecutableSchemaImpl(BuildContext buildCtx) { - GraphQLObjectType query; - GraphQLObjectType mutation; - GraphQLObjectType subscription; + private GraphQLSchema makeExecutableSchemaImpl(ImmutableTypeDefinitionRegistry typeRegistry, + RuntimeWiring wiring, + Map operationTypeDefinitions, + Options options) { + SchemaGeneratorHelper.BuildContext buildCtx = new SchemaGeneratorHelper.BuildContext(typeRegistry, wiring, operationTypeDefinitions, options); GraphQLSchema.Builder schemaBuilder = GraphQLSchema.newSchema(); - Set additionalDirectives = buildAdditionalDirectives(buildCtx); + Set additionalDirectives = schemaGeneratorHelper.buildAdditionalDirectiveDefinitions(buildCtx); schemaBuilder.additionalDirectives(additionalDirectives); - buildCtx.setDirectiveDefinitions(additionalDirectives); - - // - // Schema can be missing if the type is called 'Query'. Pre flight checks have checked that! - // - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - if (!typeRegistry.schemaDefinition().isPresent()) { - @SuppressWarnings({"OptionalGetWithoutIsPresent", "ConstantConditions"}) - TypeDefinition queryTypeDef = typeRegistry.getType("Query").get(); - - query = buildOutputType(buildCtx, TypeName.newTypeName().name(queryTypeDef.getName()).build()); - schemaBuilder.query(query); - - Optional mutationTypeDef = typeRegistry.getType("Mutation"); - if (mutationTypeDef.isPresent()) { - mutation = buildOutputType(buildCtx, TypeName.newTypeName().name((mutationTypeDef.get().getName())).build()); - schemaBuilder.mutation(mutation); - } - Optional subscriptionTypeDef = typeRegistry.getType("Subscription"); - if (subscriptionTypeDef.isPresent()) { - subscription = buildOutputType(buildCtx, TypeName.newTypeName().name(subscriptionTypeDef.get().getName()).build()); - schemaBuilder.subscription(subscription); - } - } else { - SchemaDefinition schemaDefinition = typeRegistry.schemaDefinition().get(); - List operationTypes = schemaDefinition.getOperationTypeDefinitions(); - - // pre-flight checked via checker - @SuppressWarnings({"OptionalGetWithoutIsPresent", "ConstantConditions"}) - OperationTypeDefinition queryOp = operationTypes.stream().filter(op -> "query".equals(op.getName())).findFirst().get(); - Optional mutationOp = operationTypes.stream().filter(op -> "mutation".equals(op.getName())).findFirst(); - Optional subscriptionOp = operationTypes.stream().filter(op -> "subscription".equals(op.getName())).findFirst(); - - query = buildOperation(buildCtx, queryOp); - schemaBuilder.query(query); - - if (mutationOp.isPresent()) { - mutation = buildOperation(buildCtx, mutationOp.get()); - schemaBuilder.mutation(mutation); - } - if (subscriptionOp.isPresent()) { - subscription = buildOperation(buildCtx, subscriptionOp.get()); - schemaBuilder.subscription(subscription); - } - } - - Set additionalTypes = buildAdditionalTypes(buildCtx); - schemaBuilder.additionalTypes(additionalTypes); - - schemaBuilder.fieldVisibility(buildCtx.getWiring().getFieldVisibility()); - - return schemaBuilder.build(); - } - - private GraphQLObjectType buildOperation(BuildContext buildCtx, OperationTypeDefinition operation) { - Type type = operation.getType(); - - return buildOutputType(buildCtx, type); - } - - /** - * We build the query / mutation / subscription path as a tree of referenced types - * but then we build the rest of the types specified and put them in as additional types - * - * @param buildCtx the context we need to work out what we are doing - * - * @return the additional types not referenced from the top level operations - */ - private Set buildAdditionalTypes(BuildContext buildCtx) { - Set additionalTypes = new HashSet<>(); - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - typeRegistry.types().values().forEach(typeDefinition -> { - TypeName typeName = TypeName.newTypeName().name(typeDefinition.getName()).build(); - if (typeDefinition instanceof InputObjectTypeDefinition) { - if (buildCtx.hasInputType(typeDefinition) == null) { - additionalTypes.add(buildInputType(buildCtx, typeName)); - } - } else { - if (buildCtx.hasOutputType(typeDefinition) == null) { - additionalTypes.add(buildOutputType(buildCtx, typeName)); - } - } - }); - return additionalTypes; - } - - private Set buildAdditionalDirectives(BuildContext buildCtx) { - Set additionalDirectives = new HashSet<>(); - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - typeRegistry.getDirectiveDefinitions().values().forEach(directiveDefinition -> { - Function inputTypeFactory = inputType -> buildInputType(buildCtx, inputType); - GraphQLDirective directive = schemaGeneratorHelper.buildDirectiveFromDefinition(directiveDefinition, inputTypeFactory); - additionalDirectives.add(directive); - }); - return additionalDirectives; - } - - /** - * This is the main recursive spot that builds out the various forms of Output types - * - * @param buildCtx the context we need to work out what we are doing - * @param rawType the type to be built - * - * @return an output type - */ - @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) - private T buildOutputType(BuildContext buildCtx, Type rawType) { - - TypeDefinition typeDefinition = buildCtx.getTypeDefinition(rawType); - TypeInfo typeInfo = TypeInfo.typeInfo(rawType); - - GraphQLOutputType outputType = buildCtx.hasOutputType(typeDefinition); - if (outputType != null) { - return typeInfo.decorate(outputType); - } - - if (buildCtx.stackContains(typeInfo)) { - // we have circled around so put in a type reference and fix it up later - // otherwise we will go into an infinite loop - return typeInfo.decorate(typeRef(typeInfo.getName())); - } - - buildCtx.push(typeInfo); - - if (typeDefinition instanceof ObjectTypeDefinition) { - outputType = buildObjectType(buildCtx, (ObjectTypeDefinition) typeDefinition); - } else if (typeDefinition instanceof InterfaceTypeDefinition) { - outputType = buildInterfaceType(buildCtx, (InterfaceTypeDefinition) typeDefinition); - } else if (typeDefinition instanceof UnionTypeDefinition) { - outputType = buildUnionType(buildCtx, (UnionTypeDefinition) typeDefinition); - } else if (typeDefinition instanceof EnumTypeDefinition) { - outputType = buildEnumType(buildCtx, (EnumTypeDefinition) typeDefinition); - } else if (typeDefinition instanceof ScalarTypeDefinition) { - outputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition); - } else { - // typeDefinition is not a valid output type - throw new NotAnOutputTypeError(rawType, typeDefinition); - } - - buildCtx.putOutputType(outputType); - buildCtx.pop(); - return (T) typeInfo.decorate(outputType); - } - - private GraphQLInputType buildInputType(BuildContext buildCtx, Type rawType) { - - TypeDefinition typeDefinition = buildCtx.getTypeDefinition(rawType); - TypeInfo typeInfo = TypeInfo.typeInfo(rawType); - - GraphQLInputType inputType = buildCtx.hasInputType(typeDefinition); - if (inputType != null) { - return typeInfo.decorate(inputType); - } - - if (buildCtx.stackContains(typeInfo)) { - // we have circled around so put in a type reference and fix it later - return typeInfo.decorate(typeRef(typeInfo.getName())); - } - - buildCtx.push(typeInfo); - - if (typeDefinition instanceof InputObjectTypeDefinition) { - inputType = buildInputObjectType(buildCtx, (InputObjectTypeDefinition) typeDefinition); - } else if (typeDefinition instanceof EnumTypeDefinition) { - inputType = buildEnumType(buildCtx, (EnumTypeDefinition) typeDefinition); - } else if (typeDefinition instanceof ScalarTypeDefinition) { - inputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition); - } else { - // typeDefinition is not a valid InputType - throw new NotAnInputTypeError(rawType, typeDefinition); - } - buildCtx.putInputType(inputType); - buildCtx.pop(); - return typeInfo.decorate(inputType); - } - - private GraphQLObjectType buildObjectType(BuildContext buildCtx, ObjectTypeDefinition typeDefinition) { - buildCtx.enterNode(typeDefinition); - - GraphQLObjectType.Builder builder = GraphQLObjectType.newObject(); - builder.definition(typeDefinition); - builder.name(typeDefinition.getName()); - builder.description(schemaGeneratorHelper.buildDescription(typeDefinition, typeDefinition.getDescription())); - - List extensions = objectTypeExtensions(typeDefinition, buildCtx); - builder.withDirectives( - buildDirectives(typeDefinition.getDirectives(), - directivesOf(extensions), OBJECT, buildCtx.getDirectiveDefinitions()) - ); - - typeDefinition.getFieldDefinitions().forEach(fieldDef -> { - GraphQLFieldDefinition newFieldDefinition = buildField(buildCtx, typeDefinition, fieldDef); - builder.field(newFieldDefinition); - }); - - extensions.forEach(extension -> extension.getFieldDefinitions().forEach(fieldDef -> { - GraphQLFieldDefinition newFieldDefinition = buildField(buildCtx, typeDefinition, fieldDef); - if (!builder.hasField(newFieldDefinition.getName())) { - builder.field(newFieldDefinition); - } - })); - - buildObjectTypeInterfaces(buildCtx, typeDefinition, builder, extensions); - - GraphQLObjectType objectType = builder.build(); - objectType = directiveBehaviour.onObject(objectType, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(objectType); - } - - private void buildObjectTypeInterfaces(BuildContext buildCtx, ObjectTypeDefinition typeDefinition, GraphQLObjectType.Builder builder, List extensions) { - Map interfaces = new LinkedHashMap<>(); - typeDefinition.getImplements().forEach(type -> { - GraphQLOutputType newInterfaceType = buildOutputType(buildCtx, type); - interfaces.put(newInterfaceType.getName(), newInterfaceType); - }); - - extensions.forEach(extension -> extension.getImplements().forEach(type -> { - GraphQLInterfaceType interfaceType = buildOutputType(buildCtx, type); - if (!interfaces.containsKey(interfaceType.getName())) { - interfaces.put(interfaceType.getName(), interfaceType); - } - })); - - interfaces.values().forEach(interfaze -> { - if (interfaze instanceof GraphQLInterfaceType) { - builder.withInterface((GraphQLInterfaceType) interfaze); - return; - } - if (interfaze instanceof GraphQLTypeReference) { - builder.withInterface((GraphQLTypeReference) interfaze); - return; - } - }); - } - - - private GraphQLInterfaceType buildInterfaceType(BuildContext buildCtx, InterfaceTypeDefinition typeDefinition) { - buildCtx.enterNode(typeDefinition); - - GraphQLInterfaceType.Builder builder = GraphQLInterfaceType.newInterface(); - builder.definition(typeDefinition); - builder.name(typeDefinition.getName()); - builder.description(schemaGeneratorHelper.buildDescription(typeDefinition, typeDefinition.getDescription())); - - builder.typeResolver(getTypeResolverForInterface(buildCtx, typeDefinition)); - - List extensions = interfaceTypeExtensions(typeDefinition, buildCtx); - builder.withDirectives( - buildDirectives(typeDefinition.getDirectives(), - directivesOf(extensions), OBJECT, buildCtx.getDirectiveDefinitions()) - ); - - typeDefinition.getFieldDefinitions().forEach(fieldDef -> - builder.field(buildField(buildCtx, typeDefinition, fieldDef))); - - extensions.forEach(extension -> extension.getFieldDefinitions().forEach(fieldDef -> { - GraphQLFieldDefinition field = buildField(buildCtx, typeDefinition, fieldDef); - if (!builder.hasField(field.getName())) { - builder.field(field); - } - })); - - GraphQLInterfaceType interfaceType = builder.build(); - interfaceType = directiveBehaviour.onInterface(interfaceType, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(interfaceType); - } - - private GraphQLUnionType buildUnionType(BuildContext buildCtx, UnionTypeDefinition typeDefinition) { - buildCtx.enterNode(typeDefinition); - - GraphQLUnionType.Builder builder = GraphQLUnionType.newUnionType(); - builder.definition(typeDefinition); - builder.name(typeDefinition.getName()); - builder.description(schemaGeneratorHelper.buildDescription(typeDefinition, typeDefinition.getDescription())); - builder.typeResolver(getTypeResolverForUnion(buildCtx, typeDefinition)); - - List extensions = unionTypeExtensions(typeDefinition, buildCtx); + schemaGeneratorHelper.buildSchemaDirectivesAndExtensions(buildCtx, schemaBuilder); - typeDefinition.getMemberTypes().forEach(mt -> { - GraphQLOutputType outputType = buildOutputType(buildCtx, mt); - if (outputType instanceof GraphQLTypeReference) { - builder.possibleType((GraphQLTypeReference) outputType); - } else { - builder.possibleType((GraphQLObjectType) outputType); - } - }); - - builder.withDirectives( - buildDirectives(typeDefinition.getDirectives(), - directivesOf(extensions), UNION, buildCtx.getDirectiveDefinitions()) - ); - - extensions.forEach(extension -> extension.getMemberTypes().forEach(mt -> { - GraphQLOutputType outputType = buildOutputType(buildCtx, mt); - if (!builder.containType(outputType.getName())) { - if (outputType instanceof GraphQLTypeReference) { - builder.possibleType((GraphQLTypeReference) outputType); - } else { - builder.possibleType((GraphQLObjectType) outputType); - } - } - } - )); - - GraphQLUnionType unionType = builder.build(); - unionType = directiveBehaviour.onUnion(unionType, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(unionType); - } + schemaGeneratorHelper.buildOperations(buildCtx, schemaBuilder); - private GraphQLEnumType buildEnumType(BuildContext buildCtx, EnumTypeDefinition typeDefinition) { - buildCtx.enterNode(typeDefinition); + Set additionalTypes = schemaGeneratorHelper.buildAdditionalTypes(buildCtx); + schemaBuilder.additionalTypes(additionalTypes); - GraphQLEnumType.Builder builder = GraphQLEnumType.newEnum(); - builder.definition(typeDefinition); - builder.name(typeDefinition.getName()); - builder.description(schemaGeneratorHelper.buildDescription(typeDefinition, typeDefinition.getDescription())); + buildCtx.getCodeRegistry().fieldVisibility(buildCtx.getWiring().getFieldVisibility()); - List extensions = enumTypeExtensions(typeDefinition, buildCtx); + GraphQLCodeRegistry codeRegistry = buildCtx.getCodeRegistry().build(); + schemaBuilder.codeRegistry(codeRegistry); - EnumValuesProvider enumValuesProvider = buildCtx.getWiring().getEnumValuesProviders().get(typeDefinition.getName()); - typeDefinition.getEnumValueDefinitions().forEach(evd -> { - GraphQLEnumValueDefinition enumValueDefinition = buildEnumValue(buildCtx, typeDefinition, enumValuesProvider, evd); - builder.value(enumValueDefinition); + buildCtx.getTypeRegistry().schemaDefinition().ifPresent(schemaDefinition -> { + String description = buildDescription(buildCtx, schemaDefinition, schemaDefinition.getDescription()); + schemaBuilder.description(description); }); + GraphQLSchema graphQLSchema = schemaBuilder.build(); - extensions.forEach(extension -> extension.getEnumValueDefinitions().forEach(evd -> { - GraphQLEnumValueDefinition enumValueDefinition = buildEnumValue(buildCtx, typeDefinition, enumValuesProvider, evd); - if (!builder.hasValue(enumValueDefinition.getName())) { - builder.value(enumValueDefinition); - } - })); - - builder.withDirectives( - buildDirectives(typeDefinition.getDirectives(), - directivesOf(extensions), ENUM, buildCtx.getDirectiveDefinitions()) - ); - - GraphQLEnumType enumType = builder.build(); - enumType = directiveBehaviour.onEnum(enumType, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(enumType); - } - - private GraphQLEnumValueDefinition buildEnumValue(BuildContext buildCtx, EnumTypeDefinition typeDefinition, EnumValuesProvider enumValuesProvider, EnumValueDefinition evd) { - buildCtx.enterNode(evd); - - String description = schemaGeneratorHelper.buildDescription(evd, evd.getDescription()); - String deprecation = schemaGeneratorHelper.buildDeprecationReason(evd.getDirectives()); - Object value; - if (enumValuesProvider != null) { - value = enumValuesProvider.getValue(evd.getName()); - assertNotNull(value, "EnumValuesProvider for %s returned null for %s", typeDefinition.getName(), evd.getName()); - } else { - value = evd.getName(); + // we check if there are any SchemaDirectiveWiring's in play and if there are + // we add this to enable them. By not adding it always, we save unnecessary + // schema build traversals + if (buildCtx.isDirectiveWiringRequired()) { + // handle directive wiring AFTER the schema has been built and hence type references are resolved at callback time + SchemaDirectiveWiringSchemaGeneratorPostProcessing directiveWiringProcessing = new SchemaDirectiveWiringSchemaGeneratorPostProcessing( + buildCtx.getTypeRegistry(), + buildCtx.getWiring(), + buildCtx.getCodeRegistry()); + graphQLSchema = directiveWiringProcessing.process(graphQLSchema); } - GraphQLEnumValueDefinition valueDefinition = newEnumValueDefinition() - .name(evd.getName()) - .value(value) - .description(description) - .deprecationReason(deprecation) - .withDirectives( - buildDirectives(evd.getDirectives(), - emptyList(), ENUM_VALUE, buildCtx.getDirectiveDefinitions()) - ) - .build(); - valueDefinition = directiveBehaviour.onEnumValue(valueDefinition, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(valueDefinition); + return graphQLSchema; } - private GraphQLScalarType buildScalar(BuildContext buildCtx, ScalarTypeDefinition typeDefinition) { - buildCtx.enterNode(typeDefinition); - - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - RuntimeWiring runtimeWiring = buildCtx.getWiring(); - WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); - List extensions = scalarTypeExtensions(typeDefinition, buildCtx); - - ScalarWiringEnvironment environment = new ScalarWiringEnvironment(typeRegistry, typeDefinition, extensions); + /** + * These options control how the schema generation works + */ + public static class Options { + private final boolean useCommentsAsDescription; + private final boolean captureAstDefinitions; + private final boolean useAppliedDirectivesOnly; - GraphQLScalarType scalar; - if (wiringFactory.providesScalar(environment)) { - scalar = wiringFactory.getScalar(environment); - } else { - scalar = buildCtx.getWiring().getScalars().get(typeDefinition.getName()); + Options(boolean useCommentsAsDescription, boolean captureAstDefinitions, boolean useAppliedDirectivesOnly) { + this.useCommentsAsDescription = useCommentsAsDescription; + this.captureAstDefinitions = captureAstDefinitions; + this.useAppliedDirectivesOnly = useAppliedDirectivesOnly; } - if (!ScalarInfo.isStandardScalar(scalar) && !ScalarInfo.isGraphqlSpecifiedScalar(scalar)) { - scalar = scalar.transform(builder -> builder.withDirectives( - buildDirectives(typeDefinition.getDirectives(), - directivesOf(extensions), SCALAR, buildCtx.getDirectiveDefinitions()) - )); - // - // only allow modification of custom scalars - scalar = directiveBehaviour.onScalar(scalar, buildCtx.mkBehaviourParams()); + public boolean isUseCommentsAsDescription() { + return useCommentsAsDescription; } - return buildCtx.exitNode(scalar); - } - - private GraphQLFieldDefinition buildField(BuildContext buildCtx, TypeDefinition parentType, FieldDefinition fieldDef) { - buildCtx.enterNode(fieldDef); - - GraphQLFieldDefinition.Builder builder = GraphQLFieldDefinition.newFieldDefinition(); - builder.definition(fieldDef); - builder.name(fieldDef.getName()); - builder.description(schemaGeneratorHelper.buildDescription(fieldDef, fieldDef.getDescription())); - builder.deprecate(schemaGeneratorHelper.buildDeprecationReason(fieldDef.getDirectives())); - - GraphQLDirective[] directives = buildDirectives(fieldDef.getDirectives(), - Collections.emptyList(), DirectiveLocation.FIELD_DEFINITION, buildCtx.getDirectiveDefinitions()); - builder.withDirectives( - directives - ); - - fieldDef.getInputValueDefinitions().forEach(inputValueDefinition -> - builder.argument(buildArgument(buildCtx, inputValueDefinition))); - - GraphQLOutputType fieldType = buildOutputType(buildCtx, fieldDef.getType()); - builder.type(fieldType); - - builder.dataFetcherFactory(buildDataFetcherFactory(buildCtx, parentType, fieldDef, fieldType, Arrays.asList(directives))); - - GraphQLFieldDefinition fieldDefinition = builder.build(); - fieldDefinition = directiveBehaviour.onField(fieldDefinition, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(fieldDefinition); - } - - private DataFetcherFactory buildDataFetcherFactory(BuildContext buildCtx, TypeDefinition parentType, FieldDefinition fieldDef, GraphQLOutputType fieldType, List directives) { - String fieldName = fieldDef.getName(); - String parentTypeName = parentType.getName(); - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - RuntimeWiring runtimeWiring = buildCtx.getWiring(); - WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); - - FieldWiringEnvironment wiringEnvironment = new FieldWiringEnvironment(typeRegistry, parentType, fieldDef, fieldType, directives); - - DataFetcherFactory dataFetcherFactory; - if (wiringFactory.providesDataFetcherFactory(wiringEnvironment)) { - dataFetcherFactory = wiringFactory.getDataFetcherFactory(wiringEnvironment); - assertNotNull(dataFetcherFactory, "The WiringFactory indicated it provides a data fetcher factory but then returned null"); - } else { - // - // ok they provide a data fetcher directly - DataFetcher dataFetcher; - if (wiringFactory.providesDataFetcher(wiringEnvironment)) { - dataFetcher = wiringFactory.getDataFetcher(wiringEnvironment); - assertNotNull(dataFetcher, "The WiringFactory indicated it provides a data fetcher but then returned null"); - } else { - dataFetcher = runtimeWiring.getDataFetcherForType(parentTypeName).get(fieldName); - if (dataFetcher == null) { - dataFetcher = runtimeWiring.getDefaultDataFetcherForType(parentTypeName); - if (dataFetcher == null) { - dataFetcher = wiringFactory.getDefaultDataFetcher(wiringEnvironment); - if (dataFetcher == null) { - dataFetcher = dataFetcherOfLastResort(wiringEnvironment); - } - } - } - } - dataFetcherFactory = DataFetcherFactories.useDataFetcher(dataFetcher); + public boolean isCaptureAstDefinitions() { + return captureAstDefinitions; } - return dataFetcherFactory; - } - - private DataFetcher dataFetcherOfLastResort(FieldWiringEnvironment environment) { - String fieldName = environment.getFieldDefinition().getName(); - return new PropertyDataFetcher(fieldName); - } - - private GraphQLInputObjectType buildInputObjectType(BuildContext buildCtx, InputObjectTypeDefinition typeDefinition) { - buildCtx.enterNode(typeDefinition); - GraphQLInputObjectType.Builder builder = GraphQLInputObjectType.newInputObject(); - builder.definition(typeDefinition); - builder.name(typeDefinition.getName()); - builder.description(schemaGeneratorHelper.buildDescription(typeDefinition, typeDefinition.getDescription())); - - List extensions = inputObjectTypeExtensions(typeDefinition, buildCtx); - - builder.withDirectives( - buildDirectives(typeDefinition.getDirectives(), - directivesOf(extensions), INPUT_OBJECT, buildCtx.getDirectiveDefinitions()) - ); - - typeDefinition.getInputValueDefinitions().forEach(inputValue -> - builder.field(buildInputField(buildCtx, inputValue))); - - extensions.forEach(extension -> extension.getInputValueDefinitions().forEach(inputValueDefinition -> { - GraphQLInputObjectField inputField = buildInputField(buildCtx, inputValueDefinition); - if (!builder.hasField(inputField.getName())) { - builder.field(inputField); - } - })); - - GraphQLInputObjectType inputObjectType = builder.build(); - inputObjectType = directiveBehaviour.onInputObjectType(inputObjectType, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(inputObjectType); - } - - private GraphQLInputObjectField buildInputField(BuildContext buildCtx, InputValueDefinition fieldDef) { - buildCtx.enterNode(fieldDef); - - GraphQLInputObjectField.Builder fieldBuilder = GraphQLInputObjectField.newInputObjectField(); - fieldBuilder.definition(fieldDef); - fieldBuilder.name(fieldDef.getName()); - fieldBuilder.description(schemaGeneratorHelper.buildDescription(fieldDef, fieldDef.getDescription())); - - // currently the spec doesnt allow deprecations on InputValueDefinitions but it should! - //fieldBuilder.deprecate(buildDeprecationReason(fieldDef.getDirectives())); - GraphQLInputType inputType = buildInputType(buildCtx, fieldDef.getType()); - fieldBuilder.type(inputType); - Value defaultValue = fieldDef.getDefaultValue(); - if (defaultValue != null) { - fieldBuilder.defaultValue(schemaGeneratorHelper.buildValue(defaultValue, inputType)); + public boolean isUseAppliedDirectivesOnly() { + return useAppliedDirectivesOnly; } - fieldBuilder.withDirectives( - buildDirectives(fieldDef.getDirectives(), - emptyList(), INPUT_FIELD_DEFINITION, buildCtx.getDirectiveDefinitions()) - ); - - GraphQLInputObjectField inputObjectField = fieldBuilder.build(); - inputObjectField = directiveBehaviour.onInputObjectField(inputObjectField, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(inputObjectField); - } - - private GraphQLArgument buildArgument(BuildContext buildCtx, InputValueDefinition valueDefinition) { - buildCtx.enterNode(valueDefinition); - - GraphQLArgument.Builder builder = GraphQLArgument.newArgument(); - builder.definition(valueDefinition); - builder.name(valueDefinition.getName()); - builder.description(schemaGeneratorHelper.buildDescription(valueDefinition, valueDefinition.getDescription())); - GraphQLInputType inputType = buildInputType(buildCtx, valueDefinition.getType()); - builder.type(inputType); - Value defaultValue = valueDefinition.getDefaultValue(); - if (defaultValue != null) { - builder.defaultValue(schemaGeneratorHelper.buildValue(defaultValue, inputType)); + public static Options defaultOptions() { + return new Options(true, true, false); } - builder.withDirectives( - buildDirectives(valueDefinition.getDirectives(), - emptyList(), ARGUMENT_DEFINITION, buildCtx.getDirectiveDefinitions()) - ); - - GraphQLArgument argument = builder.build(); - argument = directiveBehaviour.onArgument(argument, buildCtx.mkBehaviourParams()); - return buildCtx.exitNode(argument); - } - - @SuppressWarnings("Duplicates") - private TypeResolver getTypeResolverForUnion(BuildContext buildCtx, UnionTypeDefinition unionType) { - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - RuntimeWiring wiring = buildCtx.getWiring(); - WiringFactory wiringFactory = wiring.getWiringFactory(); - - TypeResolver typeResolver; - UnionWiringEnvironment environment = new UnionWiringEnvironment(typeRegistry, unionType); - - if (wiringFactory.providesTypeResolver(environment)) { - typeResolver = wiringFactory.getTypeResolver(environment); - assertNotNull(typeResolver, "The WiringFactory indicated it union provides a type resolver but then returned null"); - - } else { - typeResolver = wiring.getTypeResolvers().get(unionType.getName()); - if (typeResolver == null) { - // this really should be checked earlier via a pre-flight check - typeResolver = new TypeResolverProxy(); - } + /** + * This controls whether # comments can be used as descriptions in the built schema. For specification legacy reasons + * # comments used to be used as schema element descriptions. The specification has since clarified this and "" quoted string + * descriptions are the sanctioned way to make scheme element descriptions. + * + * @param useCommentsAsDescription the flag to control whether comments can be used as schema element descriptions + * + * @return a new Options object + */ + public Options useCommentsAsDescriptions(boolean useCommentsAsDescription) { + return new Options(useCommentsAsDescription, captureAstDefinitions, useAppliedDirectivesOnly); } - return typeResolver; - } - - @SuppressWarnings("Duplicates") - private TypeResolver getTypeResolverForInterface(BuildContext buildCtx, InterfaceTypeDefinition interfaceType) { - TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); - RuntimeWiring wiring = buildCtx.getWiring(); - WiringFactory wiringFactory = wiring.getWiringFactory(); - - TypeResolver typeResolver; - - InterfaceWiringEnvironment environment = new InterfaceWiringEnvironment(typeRegistry, interfaceType); - - if (wiringFactory.providesTypeResolver(environment)) { - typeResolver = wiringFactory.getTypeResolver(environment); - assertNotNull(typeResolver, "The WiringFactory indicated it provides a interface type resolver but then returned null"); - - } else { - typeResolver = wiring.getTypeResolvers().get(interfaceType.getName()); - if (typeResolver == null) { - // this really should be checked earlier via a pre-flight check - typeResolver = new TypeResolverProxy(); - } + /** + * Memory can be saved if the original AST definitions are not associated with the built runtime types. However + * some tooling may require them. + * + * @param captureAstDefinitions the flag on whether to capture AST definitions + * + * @return a new Options object + */ + public Options captureAstDefinitions(boolean captureAstDefinitions) { + return new Options(useCommentsAsDescription, captureAstDefinitions, useAppliedDirectivesOnly); } - return typeResolver; - } - - - private GraphQLDirective[] buildDirectives(List directives, List extensionDirectives, DirectiveLocation directiveLocation, Set directiveDefinitions) { - directives = directives == null ? emptyList() : directives; - extensionDirectives = extensionDirectives == null ? emptyList() : extensionDirectives; - Set names = new HashSet<>(); - List output = new ArrayList<>(); - for (Directive directive : directives) { - if (!names.contains(directive.getName())) { - names.add(directive.getName()); - output.add(schemaGeneratorHelper.buildDirective(directive, directiveDefinitions, directiveLocation)); - } - } - for (Directive directive : extensionDirectives) { - if (!names.contains(directive.getName())) { - names.add(directive.getName()); - output.add(schemaGeneratorHelper.buildDirective(directive, directiveDefinitions, directiveLocation)); - } + /** + * The class {@link GraphQLDirective} should really represent the definition of a directive, and not its use on schema elements. + * The new {@link graphql.schema.GraphQLAppliedDirective} has been created to fix this however for legacy reasons both classes will be put on schema + * elements. This flag allows you to only use {@link graphql.schema.GraphQLAppliedDirective} on schema elements. + * + * @param useAppliedDirectivesOnly the flag on whether to use {@link graphql.schema.GraphQLAppliedDirective}s only on schema elements + * + * @return a new Options object + */ + public Options useAppliedDirectivesOnly(boolean useAppliedDirectivesOnly) { + return new Options(useCommentsAsDescription, captureAstDefinitions, useAppliedDirectivesOnly); } - return output.toArray(new GraphQLDirective[0]); - } - - - private List objectTypeExtensions(ObjectTypeDefinition typeDefinition, BuildContext buildCtx) { - return nvl(buildCtx.typeRegistry.objectTypeExtensions().get(typeDefinition.getName())); - } - - private List interfaceTypeExtensions(InterfaceTypeDefinition typeDefinition, BuildContext buildCtx) { - return nvl(buildCtx.typeRegistry.interfaceTypeExtensions().get(typeDefinition.getName())); } - - private List unionTypeExtensions(UnionTypeDefinition typeDefinition, BuildContext buildCtx) { - return nvl(buildCtx.typeRegistry.unionTypeExtensions().get(typeDefinition.getName())); - } - - private List enumTypeExtensions(EnumTypeDefinition typeDefinition, BuildContext buildCtx) { - return nvl(buildCtx.typeRegistry.enumTypeExtensions().get(typeDefinition.getName())); - } - - private List scalarTypeExtensions(ScalarTypeDefinition typeDefinition, BuildContext buildCtx) { - return nvl(buildCtx.typeRegistry.scalarTypeExtensions().get(typeDefinition.getName())); - } - - private List inputObjectTypeExtensions(InputObjectTypeDefinition typeDefinition, BuildContext buildCtx) { - return nvl(buildCtx.typeRegistry.inputObjectTypeExtensions().get(typeDefinition.getName())); - } - - private List nvl(List list) { - return list == null ? emptyList() : list; - } - - private List directivesOf(List typeDefinition) { - Stream directiveStream = typeDefinition.stream() - .map(TypeDefinition::getDirectives).filter(Objects::nonNull) - .flatMap(List::stream); - return directiveStream.collect(Collectors.toList()); - } - -} +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/idl/SchemaGeneratorAppliedDirectiveHelper.java b/src/main/java/graphql/schema/idl/SchemaGeneratorAppliedDirectiveHelper.java new file mode 100644 index 0000000000..e7d94dffdf --- /dev/null +++ b/src/main/java/graphql/schema/idl/SchemaGeneratorAppliedDirectiveHelper.java @@ -0,0 +1,297 @@ +package graphql.schema.idl; + +import graphql.Internal; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.DirectiveDefinition; +import graphql.language.InputValueDefinition; +import graphql.language.StringValue; +import graphql.language.Type; +import graphql.language.Value; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphqlDirectivesContainerTypeBuilder; +import graphql.schema.GraphqlTypeComparatorRegistry; +import graphql.util.FpKit; +import graphql.util.Pair; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; + +import static graphql.Directives.NO_LONGER_SUPPORTED; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.collect.ImmutableKit.map; +import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION; +import static graphql.schema.idl.SchemaGeneratorHelper.buildDescription; +import static graphql.util.Pair.pair; +import static java.util.stream.Collectors.toMap; + +/** + * This contains helper code to build out applied directives on schema element + */ +@Internal +class SchemaGeneratorAppliedDirectiveHelper { + + static void buildAppliedDirectives(SchemaGeneratorHelper.BuildContext buildCtx, GraphqlDirectivesContainerTypeBuilder builder, Pair, List> appliedDirectives) { + builder.clearDirectives(); + + // for legacy reasons we can use the old directives construct. This is false by default + if (!buildCtx.options.isUseAppliedDirectivesOnly()) { + for (GraphQLDirective directive : appliedDirectives.first) { + builder.withDirective(directive); + } + } + for (GraphQLAppliedDirective appliedDirective : appliedDirectives.second) { + builder.withAppliedDirective(appliedDirective); + } + } + + static Pair, List> buildAppliedDirectives( + SchemaGeneratorHelper.BuildContext buildCtx, + Function, GraphQLInputType> inputTypeFactory, + List directives, + List extensionDirectives, + Introspection.DirectiveLocation directiveLocation, + Set runtimeDirectives, + GraphqlTypeComparatorRegistry comparatorRegistry) { + directives = Optional.ofNullable(directives).orElse(emptyList()); + extensionDirectives = Optional.ofNullable(extensionDirectives).orElse(emptyList()); + + List output = new ArrayList<>(); + List outputApplied = new ArrayList<>(); + for (Directive directive : directives) { + Pair pair = buildAppliedDirective(buildCtx, + inputTypeFactory, + directive, + runtimeDirectives, + directiveLocation, + comparatorRegistry); + output.add(pair.first); + outputApplied.add(pair.second); + } + for (Directive directive : extensionDirectives) { + Pair pair = buildAppliedDirective(buildCtx, + inputTypeFactory, + directive, + runtimeDirectives, + directiveLocation, + comparatorRegistry); + output.add(pair.first); + outputApplied.add(pair.second); + } + return pair(output, outputApplied); + } + + // builds directives from a type and its extensions + private static Pair buildAppliedDirective(SchemaGeneratorHelper.BuildContext buildCtx, + Function, GraphQLInputType> inputTypeFactory, + Directive directive, + Set directiveDefinitions, + Introspection.DirectiveLocation directiveLocation, + GraphqlTypeComparatorRegistry comparatorRegistry) { + GraphQLDirective.Builder builder = GraphQLDirective.newDirective() + .name(directive.getName()) + .description(buildDescription(buildCtx, directive, null)) + .comparatorRegistry(comparatorRegistry) + .validLocations(directiveLocation); + + GraphQLAppliedDirective.Builder builderAppliedDirective = GraphQLAppliedDirective.newDirective() + .name(directive.getName()) + .description(buildDescription(buildCtx, directive, null)) + .comparatorRegistry(comparatorRegistry); + + Optional directiveDefOpt = FpKit.findOne(directiveDefinitions, dd -> dd.getName().equals(directive.getName())); + + GraphQLDirective graphQLDirective = directiveDefOpt.orElseGet(() -> { + return buildDirectiveDefinitionFromAst(buildCtx, buildCtx.getTypeRegistry().getDirectiveDefinition(directive.getName()).get(), inputTypeFactory); + }); + builder.repeatable(graphQLDirective.isRepeatable()); + + builder.definition(buildCtx.isCaptureAstDefinitions() ? graphQLDirective.getDefinition() : null); + builderAppliedDirective.definition(buildCtx.isCaptureAstDefinitions() ? directive : null); + + List directiveArguments = new ArrayList<>(); + List appliedArguments = new ArrayList<>(); + + for (Argument arg : directive.getArguments()) { + directiveArguments.add(buildDirectiveArg(buildCtx, arg, graphQLDirective)); + appliedArguments.add(buildAppliedArg(buildCtx, arg, graphQLDirective)); + } + + directiveArguments = transferMissingArguments(buildCtx, directiveArguments, graphQLDirective); + directiveArguments.forEach(builder::argument); + + appliedArguments = transferMissingAppliedArguments(appliedArguments, graphQLDirective); + appliedArguments.forEach(builderAppliedDirective::argument); + + return pair(builder.build(), builderAppliedDirective.build()); + } + + private static GraphQLArgument buildDirectiveArg(SchemaGeneratorHelper.BuildContext buildCtx, Argument arg, GraphQLDirective directiveDefinition) { + GraphQLArgument directiveDefArgument = directiveDefinition.getArgument(arg.getName()); + GraphQLArgument.Builder builder = GraphQLArgument.newArgument(); + GraphQLInputType inputType = directiveDefArgument.getType(); + builder.name(arg.getName()) + .type(inputType) + .definition(buildCtx.isCaptureAstDefinitions() ? directiveDefArgument.getDefinition() : null); + + // we know it is a literal because it was created by SchemaGenerator + if (directiveDefArgument.getArgumentDefaultValue().isSet()) { + builder.defaultValueLiteral((Value) directiveDefArgument.getArgumentDefaultValue().getValue()); + } + + // Object value = buildCtx, arg.getValue(), inputType); + // we put the default value in if the specified is null + if (arg.getValue() != null) { + //TODO: maybe validation of it + builder.valueLiteral(arg.getValue()); + } + + return builder.build(); + } + + private static GraphQLAppliedDirectiveArgument buildAppliedArg(SchemaGeneratorHelper.BuildContext buildCtx, Argument arg, GraphQLDirective directiveDefinition) { + GraphQLArgument directiveDefArgument = directiveDefinition.getArgument(arg.getName()); + GraphQLAppliedDirectiveArgument.Builder builder = GraphQLAppliedDirectiveArgument.newArgument(); + builder.name(arg.getName()) + .type(directiveDefArgument.getType()) + .definition(buildCtx.isCaptureAstDefinitions() ? arg : null); + + // Object value = buildCtx, arg.getValue(), inputType); + // we put the default value in if the specified is null + if (arg.getValue() != null) { + builder.valueLiteral(arg.getValue()); + } else { + // we know it is a literal because it was created by SchemaGenerator + if (directiveDefArgument.getArgumentDefaultValue().isSet()) { + builder.valueLiteral((Value) directiveDefArgument.getArgumentDefaultValue().getValue()); + } + } + return builder.build(); + } + + private static List transferMissingArguments(SchemaGeneratorHelper.BuildContext buildCtx, List arguments, GraphQLDirective directiveDefinition) { + Map declaredArgs = FpKit.getByName(arguments, GraphQLArgument::getName, FpKit.mergeFirst()); + List argumentsOut = new ArrayList<>(arguments); + + for (GraphQLArgument directiveDefArg : directiveDefinition.getArguments()) { + if (!declaredArgs.containsKey(directiveDefArg.getName())) { + GraphQLArgument.Builder missingArg = GraphQLArgument.newArgument() + .name(directiveDefArg.getName()) + .description(directiveDefArg.getDescription()) + .definition(buildCtx.isCaptureAstDefinitions() ? directiveDefArg.getDefinition() : null) + .type(directiveDefArg.getType()); + + if (directiveDefArg.hasSetDefaultValue()) { + missingArg.defaultValueLiteral((Value) directiveDefArg.getArgumentDefaultValue().getValue()); + } + if (directiveDefArg.hasSetValue()) { + missingArg.valueLiteral((Value) directiveDefArg.getArgumentValue().getValue()); + } + argumentsOut.add(missingArg.build()); + } + } + return argumentsOut; + } + + private static List transferMissingAppliedArguments(List arguments, GraphQLDirective directiveDefinition) { + Map declaredArgs = FpKit.getByName(arguments, GraphQLAppliedDirectiveArgument::getName, FpKit.mergeFirst()); + List argumentsOut = new ArrayList<>(arguments); + + for (GraphQLArgument directiveDefArg : directiveDefinition.getArguments()) { + if (!declaredArgs.containsKey(directiveDefArg.getName())) { + GraphQLAppliedDirectiveArgument.Builder missingArg = GraphQLAppliedDirectiveArgument.newArgument() + .name(directiveDefArg.getName()) + .type(directiveDefArg.getType()) + .description(directiveDefArg.getDescription()); + + if (directiveDefArg.hasSetDefaultValue()) { + missingArg.valueLiteral((Value) directiveDefArg.getArgumentDefaultValue().getValue()); + } + if (directiveDefArg.hasSetValue()) { + missingArg.valueLiteral((Value) directiveDefArg.getArgumentValue().getValue()); + } + argumentsOut.add(missingArg.build()); + } + } + return argumentsOut; + } + + static GraphQLDirective buildDirectiveDefinitionFromAst(SchemaGeneratorHelper.BuildContext buildCtx, DirectiveDefinition directiveDefinition, Function, GraphQLInputType> inputTypeFactory) { + + GraphQLDirective.Builder builder = GraphQLDirective.newDirective() + .name(directiveDefinition.getName()) + .definition(buildCtx.isCaptureAstDefinitions() ? directiveDefinition : null) + .repeatable(directiveDefinition.isRepeatable()) + .description(buildDescription(buildCtx, directiveDefinition, directiveDefinition.getDescription())); + + + List locations = buildLocations(directiveDefinition); + locations.forEach(builder::validLocations); + + List arguments = map(directiveDefinition.getInputValueDefinitions(), + arg -> buildDirectiveArgumentDefinitionFromAst(buildCtx, arg, inputTypeFactory)); + arguments.forEach(builder::argument); + return builder.build(); + } + + private static List buildLocations(DirectiveDefinition directiveDefinition) { + return map(directiveDefinition.getDirectiveLocations(), + dl -> Introspection.DirectiveLocation.valueOf(dl.getName().toUpperCase())); + } + + static GraphQLArgument buildDirectiveArgumentDefinitionFromAst(SchemaGeneratorHelper.BuildContext buildCtx, InputValueDefinition valueDefinition, Function, GraphQLInputType> inputTypeFactory) { + GraphQLArgument.Builder builder = GraphQLArgument.newArgument(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? valueDefinition : null); + builder.name(valueDefinition.getName()); + builder.description(buildDescription(buildCtx, valueDefinition, valueDefinition.getDescription())); + builder.deprecate(buildDeprecationReason(valueDefinition.getDirectives())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + GraphQLInputType inputType = inputTypeFactory.apply(valueDefinition.getType()); + builder.type(inputType); + if (valueDefinition.getDefaultValue() != null) { + builder.valueLiteral(valueDefinition.getDefaultValue()); + builder.defaultValueLiteral(valueDefinition.getDefaultValue()); + } + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory, + valueDefinition.getDirectives(), + emptyList(), + ARGUMENT_DEFINITION, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + return builder.build(); + } + + + static String buildDeprecationReason(List directives) { + directives = Optional.ofNullable(directives).orElse(emptyList()); + Optional directive = directives.stream().filter(d -> "deprecated".equals(d.getName())).findFirst(); + if (directive.isPresent()) { + Map args = directive.get().getArguments().stream().collect(toMap( + Argument::getName, arg -> ((StringValue) arg.getValue()).getValue() + )); + if (args.isEmpty()) { + return NO_LONGER_SUPPORTED; // default value from spec + } else { + // pre flight checks have ensured its valid + return args.get("reason"); + } + } + return null; + } + +} diff --git a/src/main/java/graphql/schema/idl/SchemaGeneratorDirectiveHelper.java b/src/main/java/graphql/schema/idl/SchemaGeneratorDirectiveHelper.java index e118782390..431f12f7cb 100644 --- a/src/main/java/graphql/schema/idl/SchemaGeneratorDirectiveHelper.java +++ b/src/main/java/graphql/schema/idl/SchemaGeneratorDirectiveHelper.java @@ -1,39 +1,100 @@ package graphql.schema.idl; +import graphql.Internal; import graphql.language.NamedNode; import graphql.language.NodeParentTree; +import graphql.schema.GraphQLAppliedDirective; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLDirectiveContainer; import graphql.schema.GraphQLEnumType; import graphql.schema.GraphQLEnumValueDefinition; import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchemaElement; import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphqlElementParentTree; +import graphql.util.FpKit; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import static graphql.Assert.assertNotNull; +import static graphql.collect.ImmutableKit.map; -class SchemaGeneratorDirectiveHelper { +/** + * This contains the helper code that allows {@link graphql.schema.idl.SchemaDirectiveWiring} implementations + * to be invoked during schema generation. + */ +@SuppressWarnings("DuplicatedCode") +@Internal +public class SchemaGeneratorDirectiveHelper { + + /** + * This will return true if something in the RuntimeWiring requires a {@link SchemaDirectiveWiring}. This is to allow + * a shortcut to decide that we don't need ANY SchemaDirectiveWiring post processing + * + * @param directiveContainer the element that has directives + * @param typeRegistry the type registry + * @param runtimeWiring the runtime wiring + * @param for two + * + * @return true if something in the RuntimeWiring requires a {@link SchemaDirectiveWiring} + */ + public static boolean schemaDirectiveWiringIsRequired(T directiveContainer, TypeDefinitionRegistry typeRegistry, RuntimeWiring runtimeWiring) { + + WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); + + Map registeredWiring = runtimeWiring.getRegisteredDirectiveWiring(); + List otherWiring = runtimeWiring.getDirectiveWiring(); + boolean thereAreSome = !registeredWiring.isEmpty() || !otherWiring.isEmpty(); + if (thereAreSome) { + return true; + } + + Parameters params = new Parameters(typeRegistry, runtimeWiring, new HashMap<>(), null); + SchemaDirectiveWiringEnvironment env = new SchemaDirectiveWiringEnvironmentImpl<>(directiveContainer, + directiveContainer.getDirectives(), + directiveContainer.getAppliedDirectives(), + null, + null, + params); + // do they dynamically provide a wiring for this element? + return wiringFactory.providesSchemaDirectiveWiring(env); + } static class Parameters { private final TypeDefinitionRegistry typeRegistry; private final RuntimeWiring runtimeWiring; - private final NodeParentTree nodeParentTree; + private final NodeParentTree> nodeParentTree; private final Map context; + private final GraphQLCodeRegistry.Builder codeRegistry; + private final GraphqlElementParentTree elementParentTree; + private final GraphQLFieldsContainer fieldsContainer; + private final GraphQLFieldDefinition fieldDefinition; + + Parameters(TypeDefinitionRegistry typeRegistry, RuntimeWiring runtimeWiring, Map context, GraphQLCodeRegistry.Builder codeRegistry) { + this(typeRegistry, runtimeWiring, context, codeRegistry, null, null, null, null); + } - Parameters(TypeDefinitionRegistry typeRegistry, RuntimeWiring runtimeWiring, NodeParentTree nodeParentTree, Map context) { + Parameters(TypeDefinitionRegistry typeRegistry, RuntimeWiring runtimeWiring, Map context, GraphQLCodeRegistry.Builder codeRegistry, NodeParentTree> nodeParentTree, GraphqlElementParentTree elementParentTree, GraphQLFieldsContainer fieldsContainer, GraphQLFieldDefinition fieldDefinition) { this.typeRegistry = typeRegistry; this.runtimeWiring = runtimeWiring; this.nodeParentTree = nodeParentTree; this.context = context; + this.codeRegistry = codeRegistry; + this.elementParentTree = elementParentTree; + this.fieldsContainer = fieldsContainer; + this.fieldDefinition = fieldDefinition; } public TypeDefinitionRegistry getTypeRegistry() { @@ -44,63 +105,303 @@ public RuntimeWiring getRuntimeWiring() { return runtimeWiring; } - public NodeParentTree getNodeParentTree() { + public NodeParentTree> getNodeParentTree() { return nodeParentTree; } + public GraphqlElementParentTree getElementParentTree() { + return elementParentTree; + } + + public GraphQLFieldsContainer getFieldsContainer() { + return fieldsContainer; + } + public Map getContext() { return context; } + + public GraphQLCodeRegistry.Builder getCodeRegistry() { + return codeRegistry; + } + + public GraphQLFieldDefinition getFieldsDefinition() { + return fieldDefinition; + } + + public Parameters newParams(GraphQLFieldsContainer fieldsContainer, NodeParentTree> nodeParentTree, GraphqlElementParentTree elementParentTree) { + return new Parameters(this.typeRegistry, this.runtimeWiring, this.context, this.codeRegistry, nodeParentTree, elementParentTree, fieldsContainer, fieldDefinition); + } + + public Parameters newParams(GraphQLFieldDefinition fieldDefinition, GraphQLFieldsContainer fieldsContainer, NodeParentTree> nodeParentTree, GraphqlElementParentTree elementParentTree) { + return new Parameters(this.typeRegistry, this.runtimeWiring, this.context, this.codeRegistry, nodeParentTree, elementParentTree, fieldsContainer, fieldDefinition); + } + + public Parameters newParams(NodeParentTree> nodeParentTree, GraphqlElementParentTree elementParentTree) { + return new Parameters(this.typeRegistry, this.runtimeWiring, this.context, this.codeRegistry, nodeParentTree, elementParentTree, this.fieldsContainer, fieldDefinition); + } } - public GraphQLObjectType onObject(GraphQLObjectType element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onObject); + private NodeParentTree> buildAstTree(NamedNode... nodes) { + Deque> nodeStack = new ArrayDeque<>(); + for (NamedNode node : nodes) { + nodeStack.push(node); + } + return new NodeParentTree<>(nodeStack); } - public GraphQLFieldDefinition onField(GraphQLFieldDefinition element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onField); + private GraphqlElementParentTree buildRuntimeTree(GraphQLSchemaElement... elements) { + Deque nodeStack = new ArrayDeque<>(); + for (GraphQLSchemaElement element : elements) { + nodeStack.push(element); + } + return new GraphqlElementParentTree(nodeStack); } - public GraphQLInterfaceType onInterface(GraphQLInterfaceType element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onInterface); + private List wireArguments(GraphQLFieldDefinition fieldDefinition, GraphQLFieldsContainer fieldsContainer, NamedNode fieldsContainerNode, Parameters params, GraphQLFieldDefinition field) { + return map(field.getArguments(), argument -> { + + NodeParentTree> nodeParentTree = buildAstTree(fieldsContainerNode, field.getDefinition(), argument.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(fieldsContainer, field, argument); + + Parameters argParams = params.newParams(fieldDefinition, fieldsContainer, nodeParentTree, elementParentTree); + + return onArgument(argument, argParams); + }); } + private List wireFields(GraphQLFieldsContainer fieldsContainer, NamedNode fieldsContainerNode, Parameters params) { + return map(fieldsContainer.getFieldDefinitions(), fieldDefinition -> { + + // and for each argument in the fieldDefinition run the wiring for them - and note that they can change + List startingArgs = fieldDefinition.getArguments(); + List newArgs = wireArguments(fieldDefinition, fieldsContainer, fieldsContainerNode, params, fieldDefinition); + + if (isNotTheSameObjects(startingArgs, newArgs)) { + // they may have changed the arguments to the fieldDefinition so reflect that + fieldDefinition = fieldDefinition.transform(builder -> builder.clearArguments().arguments(newArgs)); + } + + NodeParentTree> nodeParentTree = buildAstTree(fieldsContainerNode, fieldDefinition.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(fieldsContainer, fieldDefinition); + Parameters fieldParams = params.newParams(fieldDefinition, fieldsContainer, nodeParentTree, elementParentTree); + + // now for each fieldDefinition run the new wiring and capture the results + return onField(fieldDefinition, fieldParams); + }); + } + + + public GraphQLObjectType onObject(GraphQLObjectType objectType, Parameters params) { + List startingFields = objectType.getFieldDefinitions(); + List newFields = wireFields(objectType, objectType.getDefinition(), params); + + GraphQLObjectType newObjectType = objectType; + if (isNotTheSameObjects(startingFields, newFields)) { + newObjectType = objectType.transform(builder -> builder.clearFields().fields(newFields)); + } + NodeParentTree> nodeParentTree = buildAstTree(newObjectType.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(newObjectType); + Parameters newParams = params.newParams(newObjectType, nodeParentTree, elementParentTree); + + return wireDirectives(params, + newObjectType, + newObjectType.getDirectives(), + newObjectType.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + newParams), + SchemaDirectiveWiring::onObject); + } + + public GraphQLInterfaceType onInterface(GraphQLInterfaceType interfaceType, Parameters params) { + List startingFields = interfaceType.getFieldDefinitions(); + List newFields = wireFields(interfaceType, interfaceType.getDefinition(), params); + + GraphQLInterfaceType newInterfaceType = interfaceType; + if (isNotTheSameObjects(startingFields, newFields)) { + newInterfaceType = interfaceType.transform(builder -> builder.clearFields().fields(newFields)); + } + + NodeParentTree> nodeParentTree = buildAstTree(newInterfaceType.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(newInterfaceType); + Parameters newParams = params.newParams(newInterfaceType, nodeParentTree, elementParentTree); + + return wireDirectives(params, + newInterfaceType, + newInterfaceType.getDirectives(), + newInterfaceType.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + newParams), + SchemaDirectiveWiring::onInterface); + } + + public GraphQLEnumType onEnum(final GraphQLEnumType enumType, Parameters params) { + + List startingEnumValues = enumType.getValues(); + List newEnumValues = map(startingEnumValues, enumValueDefinition -> { + + NodeParentTree> nodeParentTree = buildAstTree(enumType.getDefinition(), enumValueDefinition.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(enumType, enumValueDefinition); + Parameters fieldParams = params.newParams(nodeParentTree, elementParentTree); + + // now for each field run the new wiring and capture the results + return onEnumValue(enumValueDefinition, fieldParams); + }); + + GraphQLEnumType newEnumType = enumType; + if (isNotTheSameObjects(startingEnumValues, newEnumValues)) { + newEnumType = enumType.transform(builder -> builder.clearValues().values(newEnumValues)); + } + + NodeParentTree> nodeParentTree = buildAstTree(newEnumType.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(newEnumType); + Parameters newParams = params.newParams(nodeParentTree, elementParentTree); + + return wireDirectives(params, + newEnumType, + newEnumType.getDirectives(), + newEnumType.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + newParams), + SchemaDirectiveWiring::onEnum); + } + + public GraphQLInputObjectType onInputObjectType(GraphQLInputObjectType inputObjectType, Parameters params) { + List startingFields = inputObjectType.getFieldDefinitions(); + List newFields = map(startingFields, inputField -> { + + NodeParentTree> nodeParentTree = buildAstTree(inputObjectType.getDefinition(), inputField.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(inputObjectType, inputField); + Parameters fieldParams = params.newParams(nodeParentTree, elementParentTree); + + // now for each field run the new wiring and capture the results + return onInputObjectField(inputField, fieldParams); + }); + GraphQLInputObjectType newInputObjectType = inputObjectType; + if (isNotTheSameObjects(startingFields, newFields)) { + newInputObjectType = inputObjectType.transform(builder -> builder.clearFields().fields(newFields)); + } + + NodeParentTree> nodeParentTree = buildAstTree(newInputObjectType.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(newInputObjectType); + Parameters newParams = params.newParams(nodeParentTree, elementParentTree); + + return wireDirectives(params, + newInputObjectType, + newInputObjectType.getDirectives(), + newInputObjectType.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + newParams), + SchemaDirectiveWiring::onInputObjectType); + } + + public GraphQLUnionType onUnion(GraphQLUnionType element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onUnion); + NodeParentTree> nodeParentTree = buildAstTree(element.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(element); + Parameters newParams = params.newParams(nodeParentTree, elementParentTree); + + return wireDirectives(params, + element, + element.getDirectives(), + element.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + newParams), + SchemaDirectiveWiring::onUnion); } public GraphQLScalarType onScalar(GraphQLScalarType element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onScalar); - } + NodeParentTree> nodeParentTree = buildAstTree(element.getDefinition()); + GraphqlElementParentTree elementParentTree = buildRuntimeTree(element); + Parameters newParams = params.newParams(nodeParentTree, elementParentTree); - public GraphQLEnumType onEnum(GraphQLEnumType element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onEnum); + return wireDirectives(params, + element, + element.getDirectives(), + element.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + newParams), + SchemaDirectiveWiring::onScalar); } - public GraphQLEnumValueDefinition onEnumValue(GraphQLEnumValueDefinition element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onEnumValue); + private GraphQLFieldDefinition onField(GraphQLFieldDefinition fieldDefinition, Parameters params) { + return wireDirectives(params, + fieldDefinition, + fieldDefinition.getDirectives(), + fieldDefinition.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + params), + SchemaDirectiveWiring::onField); } - public GraphQLArgument onArgument(GraphQLArgument element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onArgument); + private GraphQLInputObjectField onInputObjectField(GraphQLInputObjectField element, Parameters params) { + return wireDirectives(params, + element, + element.getDirectives(), + element.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + params), + SchemaDirectiveWiring::onInputObjectField); } - public GraphQLInputObjectType onInputObjectType(GraphQLInputObjectType element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onInputObjectType); + private GraphQLEnumValueDefinition onEnumValue(GraphQLEnumValueDefinition enumValueDefinition, Parameters params) { + return wireDirectives(params, + enumValueDefinition, + enumValueDefinition.getDirectives(), + enumValueDefinition.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + params), + SchemaDirectiveWiring::onEnumValue); } - public GraphQLInputObjectField onInputObjectField(GraphQLInputObjectField element, Parameters params) { - return wireForEachDirective(params, element, element.getDirectives(), - (outputElement, directive) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, directive, params.getNodeParentTree(), params.getTypeRegistry(), params.getContext()), SchemaDirectiveWiring::onInputObjectField); + private GraphQLArgument onArgument(GraphQLArgument argument, Parameters params) { + return wireDirectives(params, + argument, + argument.getDirectives(), + argument.getAppliedDirectives(), + (outputElement, directives, appliedDirectives, registeredAppliedDirective, registeredDirective) -> new SchemaDirectiveWiringEnvironmentImpl<>(outputElement, + directives, + appliedDirectives, + registeredAppliedDirective, + registeredDirective, + params), + SchemaDirectiveWiring::onArgument); } @@ -108,7 +409,7 @@ public GraphQLInputObjectField onInputObjectField(GraphQLInputObjectField elemen // builds a type safe SchemaDirectiveWiringEnvironment // interface EnvBuilder { - SchemaDirectiveWiringEnvironment apply(T outputElement, GraphQLDirective directive); + SchemaDirectiveWiringEnvironment apply(T outputElement, List allDirectives, List allAppliedDirectives, GraphQLAppliedDirective registeredAppliedDirective, GraphQLDirective registeredDirective); } // @@ -118,32 +419,70 @@ interface EnvInvoker { T apply(SchemaDirectiveWiring schemaDirectiveWiring, SchemaDirectiveWiringEnvironment env); } - private T wireForEachDirective( - Parameters parameters, T element, List directives, - EnvBuilder envBuilder, EnvInvoker invoker) { + private T wireDirectives( + Parameters parameters, T element, + List allDirectives, + List allAppliedDirectives, + EnvBuilder envBuilder, + EnvInvoker invoker) { + + RuntimeWiring runtimeWiring = parameters.getRuntimeWiring(); + WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); + SchemaDirectiveWiring schemaDirectiveWiring; + + SchemaDirectiveWiringEnvironment env; T outputObject = element; - for (GraphQLDirective directive : directives) { - SchemaDirectiveWiringEnvironment env = envBuilder.apply(outputObject,directive); - Optional directiveWiring = discoverWiringProvider(parameters, directive.getName(), env); - if (directiveWiring.isPresent()) { - SchemaDirectiveWiring schemaDirectiveWiring = directiveWiring.get(); - T newElement = invoker.apply(schemaDirectiveWiring, env); - assertNotNull(newElement, "The SchemaDirectiveWiring MUST return a non null return value for element '" + element.getName() + "'"); - outputObject = newElement; + + Map allDirectivesByName = FpKit.getByName(allDirectives, GraphQLDirective::getName); + // + // first the specific named directives + Map mapOfWiring = runtimeWiring.getRegisteredDirectiveWiring(); + for (GraphQLAppliedDirective appliedDirective : allAppliedDirectives) { + schemaDirectiveWiring = mapOfWiring.get(appliedDirective.getName()); + if (schemaDirectiveWiring != null) { + GraphQLDirective directive = allDirectivesByName.get(appliedDirective.getName()); + env = envBuilder.apply(outputObject, allDirectives, allAppliedDirectives, appliedDirective, directive); + outputObject = invokeWiring(outputObject, invoker, schemaDirectiveWiring, env); } } + // + // now call any statically added to the runtime + for (SchemaDirectiveWiring directiveWiring : runtimeWiring.getDirectiveWiring()) { + env = envBuilder.apply(outputObject, allDirectives, allAppliedDirectives, null, null); + outputObject = invokeWiring(outputObject, invoker, directiveWiring, env); + } + // + // wiring factory is last (if present) + env = envBuilder.apply(outputObject, allDirectives, allAppliedDirectives, null, null); + if (wiringFactory.providesSchemaDirectiveWiring(env)) { + schemaDirectiveWiring = assertNotNull(wiringFactory.getSchemaDirectiveWiring(env), "Your WiringFactory MUST provide a non null SchemaDirectiveWiring"); + outputObject = invokeWiring(outputObject, invoker, schemaDirectiveWiring, env); + } + return outputObject; } - private Optional discoverWiringProvider(Parameters parameters, String directiveName, SchemaDirectiveWiringEnvironment env) { - SchemaDirectiveWiring directiveWiring; - RuntimeWiring runtimeWiring = parameters.getRuntimeWiring(); - WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); - if (wiringFactory.providesSchemaDirectiveWiring(env)) { - directiveWiring = assertNotNull(wiringFactory.getSchemaDirectiveWiring(env), "You MUST provide a non null SchemaDirectiveWiring"); - } else { - directiveWiring = runtimeWiring.getDirectiveWiring().get(directiveName); + private T invokeWiring(T element, EnvInvoker invoker, SchemaDirectiveWiring schemaDirectiveWiring, SchemaDirectiveWiringEnvironment env) { + T newElement = invoker.apply(schemaDirectiveWiring, env); + assertNotNull(newElement, "The SchemaDirectiveWiring MUST return a non null return value for element '%s'",element.getName()); + return newElement; + } + + private boolean isNotTheSameObjects(List starting, List ending) { + if (starting == ending) { + return false; + } + if (ending.size() != starting.size()) { + return true; + } + for (int i = 0; i < starting.size(); i++) { + T startObj = starting.get(i); + T endObj = ending.get(i); + // object equality + if (!(startObj == endObj)) { + return true; + } } - return Optional.ofNullable(directiveWiring); + return false; } } diff --git a/src/main/java/graphql/schema/idl/SchemaGeneratorHelper.java b/src/main/java/graphql/schema/idl/SchemaGeneratorHelper.java index c395af79f0..c6368da666 100644 --- a/src/main/java/graphql/schema/idl/SchemaGeneratorHelper.java +++ b/src/main/java/graphql/schema/idl/SchemaGeneratorHelper.java @@ -1,121 +1,226 @@ package graphql.schema.idl; +import graphql.AssertException; import graphql.Internal; -import graphql.Scalars; import graphql.introspection.Introspection.DirectiveLocation; import graphql.language.Argument; -import graphql.language.ArrayValue; -import graphql.language.BooleanValue; import graphql.language.Comment; import graphql.language.Description; import graphql.language.Directive; import graphql.language.DirectiveDefinition; -import graphql.language.EnumValue; -import graphql.language.FloatValue; +import graphql.language.EnumTypeDefinition; +import graphql.language.EnumTypeExtensionDefinition; +import graphql.language.EnumValueDefinition; +import graphql.language.FieldDefinition; +import graphql.language.InputObjectTypeDefinition; +import graphql.language.InputObjectTypeExtensionDefinition; import graphql.language.InputValueDefinition; -import graphql.language.IntValue; +import graphql.language.InterfaceTypeDefinition; +import graphql.language.InterfaceTypeExtensionDefinition; import graphql.language.Node; -import graphql.language.NullValue; -import graphql.language.ObjectValue; +import graphql.language.ObjectTypeDefinition; +import graphql.language.ObjectTypeExtensionDefinition; +import graphql.language.OperationTypeDefinition; +import graphql.language.ScalarTypeDefinition; +import graphql.language.ScalarTypeExtensionDefinition; import graphql.language.StringValue; import graphql.language.Type; +import graphql.language.TypeDefinition; import graphql.language.TypeName; +import graphql.language.UnionTypeDefinition; +import graphql.language.UnionTypeExtensionDefinition; import graphql.language.Value; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetcherFactories; +import graphql.schema.DataFetcherFactory; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLAppliedDirective; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedInputType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchema; import graphql.schema.GraphQLType; -import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeReference; +import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphqlTypeComparatorRegistry; +import graphql.schema.SingletonPropertyDataFetcher; +import graphql.schema.TypeResolver; +import graphql.schema.TypeResolverProxy; +import graphql.schema.idl.errors.NotAnInputTypeError; +import graphql.schema.idl.errors.NotAnOutputTypeError; import graphql.util.FpKit; +import graphql.util.Pair; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; +import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import static graphql.Assert.assertShouldNeverHappen; -import static graphql.Assert.assertTrue; -import static graphql.schema.GraphQLList.list; -import static graphql.schema.GraphQLTypeUtil.isList; -import static graphql.schema.GraphQLTypeUtil.unwrapOne; -import static java.util.Collections.emptyList; -import static java.util.stream.Collectors.joining; +import static graphql.Assert.assertNotNull; +import static graphql.Directives.DEPRECATED_DIRECTIVE_DEFINITION; +import static graphql.Directives.IncludeDirective; +import static graphql.Directives.NO_LONGER_SUPPORTED; +import static graphql.Directives.ONE_OF_DIRECTIVE_DEFINITION; +import static graphql.Directives.SPECIFIED_BY_DIRECTIVE_DEFINITION; +import static graphql.Directives.SkipDirective; +import static graphql.Directives.SpecifiedByDirective; +import static graphql.collect.ImmutableKit.emptyList; +import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION; +import static graphql.introspection.Introspection.DirectiveLocation.ENUM; +import static graphql.introspection.Introspection.DirectiveLocation.ENUM_VALUE; +import static graphql.introspection.Introspection.DirectiveLocation.FIELD_DEFINITION; +import static graphql.introspection.Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION; +import static graphql.introspection.Introspection.DirectiveLocation.INPUT_OBJECT; +import static graphql.introspection.Introspection.DirectiveLocation.OBJECT; +import static graphql.introspection.Introspection.DirectiveLocation.SCALAR; +import static graphql.introspection.Introspection.DirectiveLocation.UNION; +import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition; +import static graphql.schema.GraphQLTypeReference.typeRef; +import static graphql.schema.idl.SchemaGeneratorAppliedDirectiveHelper.buildAppliedDirectives; +import static graphql.schema.idl.SchemaGeneratorAppliedDirectiveHelper.buildDirectiveDefinitionFromAst; +import static java.lang.String.format; import static java.util.stream.Collectors.toMap; -/** - * Simple helper methods with no BuildContext argument - */ @Internal public class SchemaGeneratorHelper { - static final String NO_LONGER_SUPPORTED = "No longer supported"; - static final DirectiveDefinition DEPRECATED_DIRECTIVE_DEFINITION; + /** + * We pass this around so we know what we have defined in a stack like manner plus + * it gives us helper functions + */ + static class BuildContext { + private final ImmutableTypeDefinitionRegistry typeRegistry; + private final RuntimeWiring wiring; + private final Deque typeStack = new ArrayDeque<>(); - static { - DirectiveDefinition.Builder builder = DirectiveDefinition.newDirectiveDefinition().name("deprecated"); - builder.directiveLocation(graphql.language.DirectiveLocation.newDirectiveLocation().name(DirectiveLocation.FIELD_DEFINITION.name()).build()); - builder.directiveLocation(graphql.language.DirectiveLocation.newDirectiveLocation().name((DirectiveLocation.ENUM_VALUE.name())).build()); - builder.inputValueDefinition( - InputValueDefinition.newInputValueDefinition() - .name("reason") - .type(TypeName.newTypeName().name("String").build()) - .defaultValue(StringValue.newStringValue().value(NO_LONGER_SUPPORTED).build()) - .build()); - DEPRECATED_DIRECTIVE_DEFINITION = builder.build(); - } + private final Map outputGTypes = new LinkedHashMap<>(); + private final Map inputGTypes = new LinkedHashMap<>(); + private final Set directives = new LinkedHashSet<>(); + private final GraphQLCodeRegistry.Builder codeRegistry; + public final Map operationTypeDefs; + public final SchemaGenerator.Options options; + public boolean directiveWiringRequired; - public Object buildValue(Value value, GraphQLType requiredType) { - Object result = null; - if (GraphQLTypeUtil.isNonNull(requiredType)) { - requiredType = unwrapOne(requiredType); + BuildContext(ImmutableTypeDefinitionRegistry typeRegistry, RuntimeWiring wiring, Map operationTypeDefinitions, SchemaGenerator.Options options) { + this.typeRegistry = typeRegistry; + this.wiring = wiring; + this.codeRegistry = GraphQLCodeRegistry.newCodeRegistry(wiring.getCodeRegistry()); + this.operationTypeDefs = operationTypeDefinitions; + this.options = options; + directiveWiringRequired = false; } - if (value == null) { - return null; + + public boolean isDirectiveWiringRequired() { + return directiveWiringRequired; } - if (requiredType instanceof GraphQLScalarType) { - result = parseLiteral(value, (GraphQLScalarType) requiredType); - } else if (value instanceof EnumValue && requiredType instanceof GraphQLEnumType) { - result = ((EnumValue) value).getName(); - } else if (value instanceof ArrayValue && isList(requiredType)) { - ArrayValue arrayValue = (ArrayValue) value; - GraphQLType wrappedType = unwrapOne(requiredType); - result = arrayValue.getValues().stream() - .map(item -> this.buildValue(item, wrappedType)).collect(Collectors.toList()); - } else if (value instanceof ObjectValue && requiredType instanceof GraphQLInputObjectType) { - result = buildObjectValue((ObjectValue) value, (GraphQLInputObjectType) requiredType); - } else if (!(value instanceof NullValue)) { - assertShouldNeverHappen( - "cannot build value of %s from %s", requiredType.getName(), String.valueOf(value)); - } - return result; - } - - private Object parseLiteral(Value value, GraphQLScalarType requiredType) { - if (value instanceof NullValue) { - return null; + + public TypeDefinitionRegistry getTypeRegistry() { + return typeRegistry; + } + + TypeDefinition getTypeDefinition(Type type) { + TypeDefinition typeDefinition = typeRegistry.getTypeOrNull(type); + if (typeDefinition != null) { + return typeDefinition; + } else { + throw new AssertException(format(" type definition for type '%s' not found", type)); + } + } + + boolean stackContains(TypeInfo typeInfo) { + return typeStack.contains(typeInfo.getName()); + } + + void push(TypeInfo typeInfo) { + typeStack.push(typeInfo.getName()); + } + + void pop() { + typeStack.pop(); + } + + GraphQLOutputType hasOutputType(TypeDefinition typeDefinition) { + return outputGTypes.get(typeDefinition.getName()); + } + + GraphQLInputType hasInputType(TypeDefinition typeDefinition) { + return inputGTypes.get(typeDefinition.getName()); + } + + void putOutputType(GraphQLNamedOutputType outputType) { + outputGTypes.put(outputType.getName(), outputType); + // certain types can be both input and output types, for example enums and scalars + if (outputType instanceof GraphQLInputType) { + inputGTypes.put(outputType.getName(), (GraphQLInputType) outputType); + } + } + + void putInputType(GraphQLNamedInputType inputType) { + inputGTypes.put(inputType.getName(), inputType); + // certain types can be both input and output types, for example enums and scalars + if (inputType instanceof GraphQLOutputType) { + outputGTypes.put(inputType.getName(), (GraphQLOutputType) inputType); + } + } + + RuntimeWiring getWiring() { + return wiring; + } + + GraphqlTypeComparatorRegistry getComparatorRegistry() { + return wiring.getComparatorRegistry(); + } + + public GraphQLCodeRegistry.Builder getCodeRegistry() { + return codeRegistry; + } + + public void addDirectiveDefinition(GraphQLDirective directive) { + this.directives.add(directive); + } + + public void addDirectives(Set directives) { + this.directives.addAll(directives); } - return requiredType.getCoercing().parseLiteral(value); - } + public Set getDirectives() { + return directives; + } - public Object buildObjectValue(ObjectValue defaultValue, GraphQLInputObjectType objectType) { - Map map = new LinkedHashMap<>(); - defaultValue.getObjectFields().forEach(of -> map.put(of.getName(), - buildValue(of.getValue(), objectType.getField(of.getName()).getType()))); - return map; + public boolean isCaptureAstDefinitions() { + return options.isCaptureAstDefinitions(); + } } - public String buildDescription(Node node, Description description) { + static String buildDescription(BuildContext buildContext, Node node, Description description) { if (description != null) { return description.getContent(); } + if (!buildContext.options.isUseCommentsAsDescription()) { + return null; + } List comments = node.getComments(); List lines = new ArrayList<>(); for (Comment comment : comments) { @@ -126,12 +231,14 @@ public String buildDescription(Node node, Description description) { lines.add(commentLine); } } - if (lines.size() == 0) return null; - return lines.stream().collect(joining("\n")); + if (lines.size() == 0) { + return null; + } + return String.join("\n", lines); } - public String buildDeprecationReason(List directives) { - directives = directives == null ? emptyList() : directives; + String buildDeprecationReason(List directives) { + directives = Optional.ofNullable(directives).orElse(emptyList()); Optional directive = directives.stream().filter(d -> "deprecated".equals(d.getName())).findFirst(); if (directive.isPresent()) { Map args = directive.get().getArguments().stream().collect(toMap( @@ -140,179 +247,869 @@ public String buildDeprecationReason(List directives) { if (args.isEmpty()) { return NO_LONGER_SUPPORTED; // default value from spec } else { - // pre flight checks have ensured its valid + // pre flight checks have ensured it's valid return args.get("reason"); } } return null; } - public void addDeprecatedDirectiveDefinition(TypeDefinitionRegistry typeRegistry) { - // we synthesize this into the type registry - no need for them to add it - typeRegistry.add(DEPRECATED_DIRECTIVE_DEFINITION); + public Function, GraphQLInputType> inputTypeFactory(BuildContext buildCtx) { + return rawType -> buildInputType(buildCtx, rawType); } - /** - * We support the basic types as directive types - * - * @param value the value to use - * - * @return a graphql input type - */ - public GraphQLInputType buildDirectiveInputType(Value value) { - if (value instanceof NullValue) { - return Scalars.GraphQLString; + GraphQLInputType buildInputType(BuildContext buildCtx, Type rawType) { + + TypeDefinition typeDefinition = buildCtx.getTypeDefinition(rawType); + TypeInfo typeInfo = TypeInfo.typeInfo(rawType); + + GraphQLInputType inputType = buildCtx.hasInputType(typeDefinition); + if (inputType != null) { + return typeInfo.decorate(inputType); + } + + if (buildCtx.stackContains(typeInfo)) { + // we have circled around so put in a type reference and fix it later + return typeInfo.decorate(typeRef(typeInfo.getName())); + } + + buildCtx.push(typeInfo); + + if (typeDefinition instanceof InputObjectTypeDefinition) { + inputType = buildInputObjectType(buildCtx, (InputObjectTypeDefinition) typeDefinition); + } else if (typeDefinition instanceof EnumTypeDefinition) { + inputType = buildEnumType(buildCtx, (EnumTypeDefinition) typeDefinition); + } else if (typeDefinition instanceof ScalarTypeDefinition) { + inputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition); + } else { + // typeDefinition is not a valid InputType + throw new NotAnInputTypeError(rawType, typeDefinition); + } + + buildCtx.putInputType((GraphQLNamedInputType) inputType); + buildCtx.pop(); + return typeInfo.decorate(inputType); + } + + GraphQLInputObjectType buildInputObjectType(BuildContext buildCtx, InputObjectTypeDefinition typeDefinition) { + GraphQLInputObjectType.Builder builder = GraphQLInputObjectType.newInputObject(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? typeDefinition : null); + builder.name(typeDefinition.getName()); + builder.description(buildDescription(buildCtx, typeDefinition, typeDefinition.getDescription())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + List extensions = inputObjectTypeExtensions(typeDefinition, buildCtx); + builder.extensionDefinitions(buildCtx.isCaptureAstDefinitions() ? extensions : emptyList()); + + + Pair, List> appliedDirectives = buildAppliedDirectives(buildCtx, + inputTypeFactory(buildCtx), + typeDefinition.getDirectives(), + directivesOf(extensions), + INPUT_OBJECT, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + typeDefinition.getInputValueDefinitions().forEach(inputValue -> + builder.field(buildInputField(buildCtx, inputValue))); + + extensions.forEach(extension -> extension.getInputValueDefinitions().forEach(inputValueDefinition -> { + GraphQLInputObjectField inputField = buildInputField(buildCtx, inputValueDefinition); + if (!builder.hasField(inputField.getName())) { + builder.field(inputField); + } + })); + + return directivesObserve(buildCtx, builder.build()); + } + + private GraphQLInputObjectField buildInputField(BuildContext buildCtx, InputValueDefinition fieldDef) { + GraphQLInputObjectField.Builder fieldBuilder = GraphQLInputObjectField.newInputObjectField(); + fieldBuilder.definition(buildCtx.isCaptureAstDefinitions() ? fieldDef : null); + fieldBuilder.name(fieldDef.getName()); + fieldBuilder.description(buildDescription(buildCtx, fieldDef, fieldDef.getDescription())); + fieldBuilder.deprecate(buildDeprecationReason(fieldDef.getDirectives())); + fieldBuilder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + GraphQLInputType inputType = buildInputType(buildCtx, fieldDef.getType()); + fieldBuilder.type(inputType); + Value defaultValue = fieldDef.getDefaultValue(); + if (defaultValue != null) { + fieldBuilder.defaultValueLiteral(defaultValue); } - if (value instanceof FloatValue) { - return Scalars.GraphQLFloat; + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + fieldDef.getDirectives(), + emptyList(), + INPUT_FIELD_DEFINITION, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + + buildAppliedDirectives(buildCtx, fieldBuilder, appliedDirectives); + + return directivesObserve(buildCtx, fieldBuilder.build()); + } + + GraphQLEnumType buildEnumType(BuildContext buildCtx, EnumTypeDefinition typeDefinition) { + GraphQLEnumType.Builder builder = GraphQLEnumType.newEnum(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? typeDefinition : null); + builder.name(typeDefinition.getName()); + builder.description(buildDescription(buildCtx, typeDefinition, typeDefinition.getDescription())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + List extensions = enumTypeExtensions(typeDefinition, buildCtx); + builder.extensionDefinitions(buildCtx.isCaptureAstDefinitions() ? extensions : emptyList()); + + EnumValuesProvider enumValuesProvider = buildCtx.getWiring().getEnumValuesProviders().get(typeDefinition.getName()); + typeDefinition.getEnumValueDefinitions().forEach(evd -> { + GraphQLEnumValueDefinition enumValueDefinition = buildEnumValue(buildCtx, typeDefinition, enumValuesProvider, evd); + builder.value(enumValueDefinition); + }); + + extensions.forEach(extension -> extension.getEnumValueDefinitions().forEach(evd -> { + GraphQLEnumValueDefinition enumValueDefinition = buildEnumValue(buildCtx, typeDefinition, enumValuesProvider, evd); + if (!builder.hasValue(enumValueDefinition.getName())) { + builder.value(enumValueDefinition); + } + })); + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + typeDefinition.getDirectives(), + directivesOf(extensions), + ENUM, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + return directivesObserve(buildCtx, builder.build()); + } + + private GraphQLEnumValueDefinition buildEnumValue(BuildContext buildCtx, + EnumTypeDefinition typeDefinition, + EnumValuesProvider enumValuesProvider, + EnumValueDefinition evd) { + String description = buildDescription(buildCtx, evd, evd.getDescription()); + String deprecation = buildDeprecationReason(evd.getDirectives()); + + Object value; + if (enumValuesProvider != null) { + value = enumValuesProvider.getValue(evd.getName()); + assertNotNull(value, + "EnumValuesProvider for %s returned null for %s", typeDefinition.getName(), evd.getName()); + } else { + value = evd.getName(); } - if (value instanceof StringValue) { - return Scalars.GraphQLString; + GraphQLEnumValueDefinition.Builder builder = newEnumValueDefinition() + .name(evd.getName()) + .value(value) + .description(description) + .deprecationReason(deprecation) + .definition(buildCtx.isCaptureAstDefinitions() ? evd : null) + .comparatorRegistry(buildCtx.getComparatorRegistry()); + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + evd.getDirectives(), + emptyList(), + ENUM_VALUE, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + GraphQLEnumValueDefinition enumValueDefinition = builder.build(); + return directivesObserve(buildCtx, enumValueDefinition); + } + + GraphQLScalarType buildScalar(BuildContext buildCtx, ScalarTypeDefinition typeDefinition) { + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + RuntimeWiring runtimeWiring = buildCtx.getWiring(); + WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); + List extensions = scalarTypeExtensions(typeDefinition, buildCtx); + + ScalarWiringEnvironment environment = new ScalarWiringEnvironment(typeRegistry, typeDefinition, extensions); + + GraphQLScalarType scalar; + if (wiringFactory.providesScalar(environment)) { + scalar = wiringFactory.getScalar(environment); + } else { + scalar = buildCtx.getWiring().getScalars().get(typeDefinition.getName()); } - if (value instanceof IntValue) { - return Scalars.GraphQLInt; + + if (!ScalarInfo.isGraphqlSpecifiedScalar(scalar)) { + String description = getScalarDesc(scalar, typeDefinition); + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + typeDefinition.getDirectives(), + directivesOf(extensions), + SCALAR, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + + scalar = scalar.transform(builder -> { + builder + .description(description) + .definition(buildCtx.isCaptureAstDefinitions() ? typeDefinition : null) + .comparatorRegistry(buildCtx.getComparatorRegistry()) + .specifiedByUrl(getSpecifiedByUrl(typeDefinition, extensions)); + + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + }); } - if (value instanceof BooleanValue) { - return Scalars.GraphQLBoolean; + return directivesObserve(buildCtx, scalar); + } + + private String getScalarDesc(GraphQLScalarType scalar, ScalarTypeDefinition typeDefinition) { + if (scalar.getDescription() != null) { + if (!scalar.getDescription().trim().isEmpty()) { + return scalar.getDescription(); + } } - if (value instanceof ArrayValue) { - ArrayValue arrayValue = (ArrayValue) value; - return list(buildDirectiveInputType(getArrayValueWrappedType(arrayValue))); + if (typeDefinition.getDescription() != null) { + return typeDefinition.getDescription().getContent(); } - return assertShouldNeverHappen("Directive values of type '%s' are not supported yet", value.getClass().getSimpleName()); + return ""; } - private Value getArrayValueWrappedType(ArrayValue value) { - // empty array [] is equivalent to [null] - if (value.getValues().isEmpty()) { - return NullValue.Null; + String getSpecifiedByUrl(ScalarTypeDefinition scalarTypeDefinition, List extensions) { + List allDirectives = new ArrayList<>(scalarTypeDefinition.getDirectives()); + extensions.forEach(extension -> allDirectives.addAll(extension.getDirectives())); + Optional specifiedByDirective = FpKit.findOne(allDirectives, + directiveDefinition -> directiveDefinition.getName().equals(SpecifiedByDirective.getName())); + if (!specifiedByDirective.isPresent()) { + return null; } + Argument urlArgument = specifiedByDirective.get().getArgument("url"); + StringValue url = (StringValue) urlArgument.getValue(); + return url.getValue(); + } + + private TypeResolver getTypeResolverForInterface(BuildContext buildCtx, InterfaceTypeDefinition interfaceType) { + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + RuntimeWiring wiring = buildCtx.getWiring(); + WiringFactory wiringFactory = wiring.getWiringFactory(); + + TypeResolver typeResolver; + + InterfaceWiringEnvironment environment = new InterfaceWiringEnvironment(typeRegistry, interfaceType); - // get rid of null values - List nonNullValueList = value.getValues().stream() - .filter(v -> !(v instanceof NullValue)) - .collect(Collectors.toList()); + if (wiringFactory.providesTypeResolver(environment)) { + typeResolver = wiringFactory.getTypeResolver(environment); + assertNotNull(typeResolver, "The WiringFactory indicated it provides a interface type resolver but then returned null"); - // [null, null, ...] unwrapped is null - if (nonNullValueList.isEmpty()) { - return NullValue.Null; + } else { + typeResolver = wiring.getTypeResolvers().get(interfaceType.getName()); + if (typeResolver == null) { + // this really should be checked earlier via a pre-flight check + typeResolver = new TypeResolverProxy(); + } } + return typeResolver; + } + + private TypeResolver getTypeResolverForUnion(BuildContext buildCtx, UnionTypeDefinition unionType) { + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + RuntimeWiring wiring = buildCtx.getWiring(); + WiringFactory wiringFactory = wiring.getWiringFactory(); - // make sure the array isn't polymorphic - Set> distinctTypes = nonNullValueList.stream() - .map(Value::getClass) - .distinct() - .collect(Collectors.toSet()); + TypeResolver typeResolver; + UnionWiringEnvironment environment = new UnionWiringEnvironment(typeRegistry, unionType); - assertTrue(distinctTypes.size() == 1, - "Arrays containing multiple types of values are not supported yet. Detected the following types [%s]", - nonNullValueList.stream() - .map(Value::getClass) - .map(Class::getSimpleName) - .distinct() - .sorted() - .collect(Collectors.joining(","))); + if (wiringFactory.providesTypeResolver(environment)) { + typeResolver = wiringFactory.getTypeResolver(environment); + assertNotNull(typeResolver, "The WiringFactory indicated it union provides a type resolver but then returned null"); + + } else { + typeResolver = wiring.getTypeResolvers().get(unionType.getName()); + if (typeResolver == null) { + // this really should be checked earlier via a pre-flight check + typeResolver = new TypeResolverProxy(); + } + } - // peek at first value, value exists and is assured to be non-null - return nonNullValueList.get(0); + return typeResolver; } - // builds directives from a type and its extensions - public GraphQLDirective buildDirective(Directive directive, Set directiveDefinitions, DirectiveLocation directiveLocation) { - Optional directiveDefinition = directiveDefinitions.stream().filter(dd -> dd.getName().equals(directive.getName())).findFirst(); - GraphQLDirective.Builder builder = GraphQLDirective.newDirective() - .name(directive.getName()) - .description(buildDescription(directive, null)) - .validLocations(directiveLocation); + private void buildInterfaceTypeInterfaces(BuildContext buildCtx, + InterfaceTypeDefinition typeDefinition, + GraphQLInterfaceType.Builder builder, + List extensions) { + Map interfaces = new LinkedHashMap<>(); + typeDefinition.getImplements().forEach(type -> { + GraphQLNamedOutputType newInterfaceType = buildOutputType(buildCtx, type); + interfaces.put(newInterfaceType.getName(), newInterfaceType); + }); - List arguments = directive.getArguments().stream() - .map(arg -> buildDirectiveArgument(arg, directiveDefinition)) - .collect(Collectors.toList()); + extensions.forEach(extension -> extension.getImplements().forEach(type -> { + GraphQLNamedOutputType interfaceType = buildOutputType(buildCtx, type); + if (!interfaces.containsKey(interfaceType.getName())) { + interfaces.put(interfaceType.getName(), interfaceType); + } + })); + + interfaces.values().forEach(interfaze -> { + if (interfaze instanceof GraphQLInterfaceType) { + builder.withInterface((GraphQLInterfaceType) interfaze); + return; + } + if (interfaze instanceof GraphQLTypeReference) { + builder.withInterface((GraphQLTypeReference) interfaze); + } + }); + } + + private GraphQLObjectType buildOperation(BuildContext buildCtx, OperationTypeDefinition operation) { + return buildOutputType(buildCtx, operation.getTypeName()); + } - if (directiveDefinition.isPresent()) { - arguments = transferMissingArguments(arguments, directiveDefinition.get()); + GraphQLInterfaceType buildInterfaceType(BuildContext buildCtx, InterfaceTypeDefinition typeDefinition) { + GraphQLInterfaceType.Builder builder = GraphQLInterfaceType.newInterface(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? typeDefinition : null); + builder.name(typeDefinition.getName()); + builder.description(buildDescription(buildCtx, typeDefinition, typeDefinition.getDescription())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + List extensions = interfaceTypeExtensions(typeDefinition, buildCtx); + builder.extensionDefinitions(buildCtx.isCaptureAstDefinitions() ? extensions : emptyList()); + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + typeDefinition.getDirectives(), + directivesOf(extensions), + OBJECT, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + typeDefinition.getFieldDefinitions().forEach(fieldDef -> { + GraphQLFieldDefinition fieldDefinition = buildField(buildCtx, typeDefinition, fieldDef); + builder.field(fieldDefinition); + }); + + extensions.forEach(extension -> extension.getFieldDefinitions().forEach(fieldDef -> { + GraphQLFieldDefinition fieldDefinition = buildField(buildCtx, typeDefinition, fieldDef); + if (!builder.hasField(fieldDefinition.getName())) { + builder.field(fieldDefinition); + } + })); + + buildInterfaceTypeInterfaces(buildCtx, typeDefinition, builder, extensions); + + GraphQLInterfaceType interfaceType = builder.build(); + if (!buildCtx.getCodeRegistry().hasTypeResolver(interfaceType.getName())) { + TypeResolver typeResolver = getTypeResolverForInterface(buildCtx, typeDefinition); + buildCtx.getCodeRegistry().typeResolver(interfaceType, typeResolver); } - arguments.forEach(builder::argument); + return directivesObserve(buildCtx, interfaceType); + } - return builder.build(); + GraphQLObjectType buildObjectType(BuildContext buildCtx, ObjectTypeDefinition typeDefinition) { + GraphQLObjectType.Builder builder = GraphQLObjectType.newObject(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? typeDefinition : null); + builder.name(typeDefinition.getName()); + builder.description(buildDescription(buildCtx, typeDefinition, typeDefinition.getDescription())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + List extensions = objectTypeExtensions(typeDefinition, buildCtx); + builder.extensionDefinitions(buildCtx.isCaptureAstDefinitions() ? extensions : emptyList()); + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + typeDefinition.getDirectives(), + directivesOf(extensions), + OBJECT, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + typeDefinition.getFieldDefinitions().forEach(fieldDef -> { + GraphQLFieldDefinition fieldDefinition = buildField(buildCtx, typeDefinition, fieldDef); + builder.field(fieldDefinition); + }); + + extensions.forEach(extension -> extension.getFieldDefinitions().forEach(fieldDef -> { + GraphQLFieldDefinition fieldDefinition = buildField(buildCtx, typeDefinition, fieldDef); + if (!builder.hasField(fieldDefinition.getName())) { + builder.field(fieldDefinition); + } + })); + + buildObjectTypeInterfaces(buildCtx, typeDefinition, builder, extensions); + + return directivesObserve(buildCtx, builder.build()); } - private GraphQLArgument buildDirectiveArgument(Argument arg, Optional directiveDefinition) { - Optional directiveDefArgument = directiveDefinition.map(dd -> dd.getArgument(arg.getName())); - GraphQLArgument.Builder builder = GraphQLArgument.newArgument(); - builder.name(arg.getName()); - GraphQLInputType inputType; - Object defaultValue = null; - if (directiveDefArgument.isPresent()) { - inputType = directiveDefArgument.get().getType(); - defaultValue = directiveDefArgument.get().getDefaultValue(); + private void buildObjectTypeInterfaces(BuildContext buildCtx, + ObjectTypeDefinition typeDefinition, + GraphQLObjectType.Builder builder, + List extensions) { + Map interfaces = new LinkedHashMap<>(); + typeDefinition.getImplements().forEach(type -> { + GraphQLNamedOutputType newInterfaceType = buildOutputType(buildCtx, type); + interfaces.put(newInterfaceType.getName(), newInterfaceType); + }); + + extensions.forEach(extension -> extension.getImplements().forEach(type -> { + GraphQLNamedOutputType interfaceType = buildOutputType(buildCtx, type); + if (!interfaces.containsKey(interfaceType.getName())) { + interfaces.put(interfaceType.getName(), interfaceType); + } + })); + + interfaces.values().forEach(interfaze -> { + if (interfaze instanceof GraphQLInterfaceType) { + builder.withInterface((GraphQLInterfaceType) interfaze); + return; + } + if (interfaze instanceof GraphQLTypeReference) { + builder.withInterface((GraphQLTypeReference) interfaze); + } + }); + } + + GraphQLUnionType buildUnionType(BuildContext buildCtx, UnionTypeDefinition typeDefinition) { + GraphQLUnionType.Builder builder = GraphQLUnionType.newUnionType(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? typeDefinition : null); + builder.name(typeDefinition.getName()); + builder.description(buildDescription(buildCtx, typeDefinition, typeDefinition.getDescription())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + List extensions = unionTypeExtensions(typeDefinition, buildCtx); + builder.extensionDefinitions(buildCtx.isCaptureAstDefinitions() ? extensions : emptyList()); + + typeDefinition.getMemberTypes().forEach(mt -> { + GraphQLOutputType outputType = buildOutputType(buildCtx, mt); + if (outputType instanceof GraphQLTypeReference) { + builder.possibleType((GraphQLTypeReference) outputType); + } else { + builder.possibleType((GraphQLObjectType) outputType); + } + }); + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + typeDefinition.getDirectives(), + directivesOf(extensions), + UNION, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + extensions.forEach(extension -> extension.getMemberTypes().forEach(mt -> { + GraphQLNamedOutputType outputType = buildOutputType(buildCtx, mt); + if (!builder.containType(outputType.getName())) { + if (outputType instanceof GraphQLTypeReference) { + builder.possibleType((GraphQLTypeReference) outputType); + } else { + builder.possibleType((GraphQLObjectType) outputType); + } + } + } + )); + + GraphQLUnionType unionType = builder.build(); + if (!buildCtx.getCodeRegistry().hasTypeResolver(unionType.getName())) { + TypeResolver typeResolver = getTypeResolverForUnion(buildCtx, typeDefinition); + buildCtx.getCodeRegistry().typeResolver(unionType, typeResolver); + } + return directivesObserve(buildCtx, unionType); + } + + /** + * This is the main recursive spot that builds out the various forms of Output types + * + * @param buildCtx the context we need to work out what we are doing + * @param rawType the type to be built + * + * @return an output type + */ + @SuppressWarnings({"TypeParameterUnusedInFormals"}) + private T buildOutputType(BuildContext buildCtx, Type rawType) { + + TypeDefinition typeDefinition = buildCtx.getTypeDefinition(rawType); + TypeInfo typeInfo = TypeInfo.typeInfo(rawType); + + GraphQLOutputType outputType = buildCtx.hasOutputType(typeDefinition); + if (outputType != null) { + return typeInfo.decorate(outputType); + } + + if (buildCtx.stackContains(typeInfo)) { + // we have circled around so put in a type reference and fix it up later + // otherwise we will go into an infinite loop + return typeInfo.decorate(typeRef(typeInfo.getName())); + } + + buildCtx.push(typeInfo); + + if (typeDefinition instanceof ObjectTypeDefinition) { + outputType = buildObjectType(buildCtx, (ObjectTypeDefinition) typeDefinition); + } else if (typeDefinition instanceof InterfaceTypeDefinition) { + outputType = buildInterfaceType(buildCtx, (InterfaceTypeDefinition) typeDefinition); + } else if (typeDefinition instanceof UnionTypeDefinition) { + outputType = buildUnionType(buildCtx, (UnionTypeDefinition) typeDefinition); + } else if (typeDefinition instanceof EnumTypeDefinition) { + outputType = buildEnumType(buildCtx, (EnumTypeDefinition) typeDefinition); + } else if (typeDefinition instanceof ScalarTypeDefinition) { + outputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition); } else { - inputType = buildDirectiveInputType(arg.getValue()); + // typeDefinition is not a valid output type + throw new NotAnOutputTypeError(rawType, typeDefinition); } + + buildCtx.putOutputType((GraphQLNamedOutputType) outputType); + buildCtx.pop(); + return typeInfo.decorate(outputType); + } + + GraphQLFieldDefinition buildField(BuildContext buildCtx, TypeDefinition parentType, FieldDefinition fieldDef) { + GraphQLFieldDefinition.Builder builder = GraphQLFieldDefinition.newFieldDefinition(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? fieldDef : null); + builder.name(fieldDef.getName()); + builder.description(buildDescription(buildCtx, fieldDef, fieldDef.getDescription())); + builder.deprecate(buildDeprecationReason(fieldDef.getDirectives())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + fieldDef.getDirectives(), + emptyList(), FIELD_DEFINITION, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + fieldDef.getInputValueDefinitions().forEach(inputValueDefinition -> + builder.argument(buildArgument(buildCtx, inputValueDefinition))); + + GraphQLOutputType fieldType = buildOutputType(buildCtx, fieldDef.getType()); + builder.type(fieldType); + + GraphQLFieldDefinition fieldDefinition = builder.build(); + // if they have already wired in a fetcher - then leave it alone + FieldCoordinates coordinates = FieldCoordinates.coordinates(parentType.getName(), fieldDefinition.getName()); + if (!buildCtx.getCodeRegistry().hasDataFetcher(coordinates)) { + Optional> dataFetcherFactory = buildDataFetcherFactory(buildCtx, + parentType, + fieldDef, + fieldType, + appliedDirectives.first, + appliedDirectives.second); + + // if the dataFetcherFactory is empty, then it must have been the code registry default one + // and hence we don't need to make a "map entry" in the code registry since it will be defaulted + // anyway + dataFetcherFactory.ifPresent(fetcherFactory -> buildCtx.getCodeRegistry().dataFetcher(coordinates, fetcherFactory)); + } + return directivesObserve(buildCtx, fieldDefinition); + } + + private Optional> buildDataFetcherFactory(BuildContext buildCtx, + TypeDefinition parentType, + FieldDefinition fieldDef, + GraphQLOutputType fieldType, + List directives, + List appliedDirectives) { + String fieldName = fieldDef.getName(); + String parentTypeName = parentType.getName(); + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + RuntimeWiring runtimeWiring = buildCtx.getWiring(); + WiringFactory wiringFactory = runtimeWiring.getWiringFactory(); + GraphQLCodeRegistry.Builder codeRegistry = buildCtx.getCodeRegistry(); + + FieldWiringEnvironment wiringEnvironment = new FieldWiringEnvironment(typeRegistry, parentType, fieldDef, fieldType, directives, appliedDirectives); + + DataFetcherFactory dataFetcherFactory; + if (wiringFactory.providesDataFetcherFactory(wiringEnvironment)) { + dataFetcherFactory = wiringFactory.getDataFetcherFactory(wiringEnvironment); + assertNotNull(dataFetcherFactory, "The WiringFactory indicated it provides a data fetcher factory but then returned null"); + } else { + // + // ok they provide a data fetcher directly + DataFetcher dataFetcher; + if (wiringFactory.providesDataFetcher(wiringEnvironment)) { + dataFetcher = wiringFactory.getDataFetcher(wiringEnvironment); + assertNotNull(dataFetcher, "The WiringFactory indicated it provides a data fetcher but then returned null"); + } else { + dataFetcher = runtimeWiring.getDataFetchersForType(parentTypeName).get(fieldName); + if (dataFetcher == null) { + dataFetcher = runtimeWiring.getDefaultDataFetcherForType(parentTypeName); + if (dataFetcher == null) { + dataFetcher = wiringFactory.getDefaultDataFetcher(wiringEnvironment); + if (dataFetcher == null) { + DataFetcherFactory codeRegistryDFF = codeRegistry.getDefaultDataFetcherFactory(); + if (codeRegistryDFF != null) { + // this will use the default of the code registry when its + // asked for at runtime + return Optional.empty(); + } + dataFetcher = dataFetcherOfLastResort(); + } + } + } + } + dataFetcherFactory = DataFetcherFactories.useDataFetcher(dataFetcher); + } + return Optional.of(dataFetcherFactory); + } + + GraphQLArgument buildArgument(BuildContext buildCtx, InputValueDefinition valueDefinition) { + GraphQLArgument.Builder builder = GraphQLArgument.newArgument(); + builder.definition(buildCtx.isCaptureAstDefinitions() ? valueDefinition : null); + builder.name(valueDefinition.getName()); + builder.description(buildDescription(buildCtx, valueDefinition, valueDefinition.getDescription())); + builder.deprecate(buildDeprecationReason(valueDefinition.getDirectives())); + builder.comparatorRegistry(buildCtx.getComparatorRegistry()); + + GraphQLInputType inputType = buildInputType(buildCtx, valueDefinition.getType()); builder.type(inputType); - builder.defaultValue(defaultValue); + Value defaultValue = valueDefinition.getDefaultValue(); + if (defaultValue != null) { + builder.defaultValueLiteral(defaultValue); + } - Object value = buildValue(arg.getValue(), inputType); + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + valueDefinition.getDirectives(), + emptyList(), + ARGUMENT_DEFINITION, + buildCtx.getDirectives(), + buildCtx.getComparatorRegistry()); + buildAppliedDirectives(buildCtx, builder, appliedDirectives); + + return directivesObserve(buildCtx, builder.build()); + } + + void buildOperations(BuildContext buildCtx, GraphQLSchema.Builder schemaBuilder) { + // + // Schema can be missing if the type is called 'Query'. Pre flight checks have checked that! // - // we put the default value in if the specified is null - builder.value(value == null ? defaultValue : value); - - return builder.build(); - } - - private List transferMissingArguments(List arguments, GraphQLDirective directiveDefinition) { - Map declaredArgs = FpKit.getByName(arguments, GraphQLArgument::getName, FpKit.mergeFirst()); - List argumentsOut = new ArrayList<>(arguments); - - for (GraphQLArgument directiveDefArg : directiveDefinition.getArguments()) { - if (!declaredArgs.containsKey(directiveDefArg.getName())) { - GraphQLArgument missingArg = GraphQLArgument.newArgument() - .name(directiveDefArg.getName()) - .description(directiveDefArg.getDescription()) - .definition(directiveDefArg.getDefinition()) - .type(directiveDefArg.getType()) - .defaultValue(directiveDefArg.getDefaultValue()) - .value(directiveDefArg.getDefaultValue()) - .build(); - argumentsOut.add(missingArg); + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + Map operationTypeDefs = buildCtx.operationTypeDefs; + + GraphQLObjectType query; + GraphQLObjectType mutation; + GraphQLObjectType subscription; + + Optional queryOperation = getOperationNamed("query", operationTypeDefs); + if (queryOperation.isEmpty()) { + TypeDefinition queryTypeDef = Objects.requireNonNull(typeRegistry.getTypeOrNull("Query")); + query = buildOutputType(buildCtx, TypeName.newTypeName().name(queryTypeDef.getName()).build()); + } else { + query = buildOperation(buildCtx, queryOperation.get()); + } + schemaBuilder.query(query); + + Optional mutationOperation = getOperationNamed("mutation", operationTypeDefs); + if (mutationOperation.isEmpty()) { + if (typeRegistry.schemaDefinition().isEmpty()) { + // If no schema definition, then there is no schema keyword. Default to using type called Mutation + TypeDefinition mutationTypeDef = typeRegistry.getTypeOrNull("Mutation"); + if (mutationTypeDef != null) { + mutation = buildOutputType(buildCtx, TypeName.newTypeName().name(mutationTypeDef.getName()).build()); + schemaBuilder.mutation(mutation); + } } + } else { + mutation = buildOperation(buildCtx, mutationOperation.get()); + schemaBuilder.mutation(mutation); + } + + Optional subscriptionOperation = getOperationNamed("subscription", operationTypeDefs); + if (subscriptionOperation.isEmpty()) { + if (typeRegistry.schemaDefinition().isEmpty()) { + // If no schema definition, then there is no schema keyword. Default to using type called Subscription + TypeDefinition subscriptionTypeDef = typeRegistry.getTypeOrNull("Subscription"); + if (subscriptionTypeDef != null) { + subscription = buildOutputType(buildCtx, TypeName.newTypeName().name(subscriptionTypeDef.getName()).build()); + schemaBuilder.subscription(subscription); + } + } + } else { + subscription = buildOperation(buildCtx, subscriptionOperation.get()); + schemaBuilder.subscription(subscription); } - return argumentsOut; } - public GraphQLDirective buildDirectiveFromDefinition(DirectiveDefinition directiveDefinition, Function inputTypeFactory) { + void buildSchemaDirectivesAndExtensions(BuildContext buildCtx, GraphQLSchema.Builder schemaBuilder) { + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + List schemaDirectiveList = SchemaExtensionsChecker.gatherSchemaDirectives(typeRegistry); + Set runtimeDirectives = buildCtx.getDirectives(); + Pair, List> appliedDirectives = buildAppliedDirectives( + buildCtx, + inputTypeFactory(buildCtx), + schemaDirectiveList, + emptyList(), + DirectiveLocation.SCHEMA, + runtimeDirectives, + buildCtx.getComparatorRegistry()); + schemaBuilder.withSchemaDirectives(appliedDirectives.first); + schemaBuilder.withSchemaAppliedDirectives(appliedDirectives.second); - GraphQLDirective.Builder builder = GraphQLDirective.newDirective() - .name(directiveDefinition.getName()) - .description(buildDescription(directiveDefinition, directiveDefinition.getDescription())); + schemaBuilder.definition(buildCtx.isCaptureAstDefinitions() ? typeRegistry.schemaDefinition().orElse(null) : null); + schemaBuilder.extensionDefinitions(buildCtx.isCaptureAstDefinitions() ? typeRegistry.getSchemaExtensionDefinitions() : emptyList()); + } + List inputObjectTypeExtensions(InputObjectTypeDefinition typeDefinition, BuildContext buildCtx) { + return buildCtx.getTypeRegistry().inputObjectTypeExtensions().getOrDefault(typeDefinition.getName(), emptyList()); + } - List locations = buildLocations(directiveDefinition); - locations.forEach(builder::validLocations); + List enumTypeExtensions(EnumTypeDefinition typeDefinition, BuildContext buildCtx) { + return buildCtx.getTypeRegistry().enumTypeExtensions().getOrDefault(typeDefinition.getName(), emptyList()); + } - List arguments = directiveDefinition.getInputValueDefinitions().stream() - .map(arg -> buildDirectiveArgumentFromDefinition(arg, inputTypeFactory)) - .collect(Collectors.toList()); - arguments.forEach(builder::argument); - return builder.build(); + List scalarTypeExtensions(ScalarTypeDefinition typeDefinition, BuildContext buildCtx) { + return buildCtx.getTypeRegistry().scalarTypeExtensions().getOrDefault(typeDefinition.getName(), emptyList()); } - private GraphQLArgument buildDirectiveArgumentFromDefinition(InputValueDefinition arg, Function inputTypeFactory) { - GraphQLArgument.Builder builder = GraphQLArgument.newArgument() - .name(arg.getName()) - .definition(arg); + List interfaceTypeExtensions(InterfaceTypeDefinition typeDefinition, BuildContext buildCtx) { + return buildCtx.getTypeRegistry().interfaceTypeExtensions().getOrDefault(typeDefinition.getName(), emptyList()); + } - GraphQLInputType inputType = inputTypeFactory.apply(arg.getType()); - builder.type(inputType); - builder.value(buildValue(arg.getDefaultValue(), inputType)); - builder.defaultValue(buildValue(arg.getDefaultValue(), inputType)); - return builder.build(); + List objectTypeExtensions(ObjectTypeDefinition typeDefinition, BuildContext buildCtx) { + return buildCtx.getTypeRegistry().objectTypeExtensions().getOrDefault(typeDefinition.getName(), emptyList()); } - private List buildLocations(DirectiveDefinition directiveDefinition) { - return directiveDefinition.getDirectiveLocations().stream() - .map(dl -> DirectiveLocation.valueOf(dl.getName().toUpperCase())) - .collect(Collectors.toList()); + List unionTypeExtensions(UnionTypeDefinition typeDefinition, BuildContext buildCtx) { + return buildCtx.getTypeRegistry().unionTypeExtensions().getOrDefault(typeDefinition.getName(), emptyList()); + } + + /** + * We build the query / mutation / subscription path as a tree of referenced types + * but then we build the rest of the types specified and put them in as additional types + * + * @param buildCtx the context we need to work out what we are doing + * + * @return the additional types not referenced from the top level operations + */ + Set buildAdditionalTypes(BuildContext buildCtx) { + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + + Set detachedTypeNames = getDetachedTypeNames(buildCtx); + + Set additionalTypes = new LinkedHashSet<>(); + // recursively record detached types on the ctx and add them to the additionalTypes set + typeRegistry.types().values().stream() + .filter(typeDefinition -> detachedTypeNames.contains(typeDefinition.getName())) + .forEach(typeDefinition -> { + TypeName typeName = TypeName.newTypeName().name(typeDefinition.getName()).build(); + + if (typeDefinition instanceof InputObjectTypeDefinition) { + if (buildCtx.hasInputType(typeDefinition) == null) { + buildCtx.putInputType((GraphQLNamedInputType) buildInputType(buildCtx, typeName)); + } + additionalTypes.add(buildCtx.inputGTypes.get(typeDefinition.getName())); + } else { + if (buildCtx.hasOutputType(typeDefinition) == null) { + buildCtx.putOutputType(buildOutputType(buildCtx, typeName)); + } + additionalTypes.add(buildCtx.outputGTypes.get(typeDefinition.getName())); + } + }); + + typeRegistry.scalars().values().stream() + .filter(typeDefinition -> detachedTypeNames.contains(typeDefinition.getName())) + .forEach(scalarTypeDefinition -> { + if (ScalarInfo.isGraphqlSpecifiedScalar(scalarTypeDefinition.getName())) { + return; + } + + if (buildCtx.hasInputType(scalarTypeDefinition) == null && buildCtx.hasOutputType(scalarTypeDefinition) == null) { + buildCtx.putOutputType(buildScalar(buildCtx, scalarTypeDefinition)); + } + if (buildCtx.hasInputType(scalarTypeDefinition) != null) { + additionalTypes.add(buildCtx.inputGTypes.get(scalarTypeDefinition.getName())); + } else if (buildCtx.hasOutputType(scalarTypeDefinition) != null) { + additionalTypes.add(buildCtx.outputGTypes.get(scalarTypeDefinition.getName())); + } + }); + + return additionalTypes; + } + + /** + * Detached types (or additional types) are all types that + * are not connected to the root operations types. + * + * @param buildCtx buildCtx + * + * @return detached type names + */ + private Set getDetachedTypeNames(BuildContext buildCtx) { + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + // connected types are all types that have a path that connects them back to the root operation types. + Set connectedTypes = new HashSet<>(buildCtx.inputGTypes.keySet()); + connectedTypes.addAll(buildCtx.outputGTypes.keySet()); + + Set allTypeNames = new HashSet<>(typeRegistry.types().keySet()); + Set scalars = new HashSet<>(typeRegistry.scalars().keySet()); + allTypeNames.addAll(scalars); + + // detached types are all types minus the connected types. + Set detachedTypeNames = new HashSet<>(allTypeNames); + detachedTypeNames.removeAll(connectedTypes); + return detachedTypeNames; + } + + Set buildAdditionalDirectiveDefinitions(BuildContext buildCtx) { + Set additionalDirectives = new LinkedHashSet<>(); + TypeDefinitionRegistry typeRegistry = buildCtx.getTypeRegistry(); + + for (DirectiveDefinition directiveDefinition : typeRegistry.getDirectiveDefinitions().values()) { + if (IncludeDirective.getName().equals(directiveDefinition.getName()) + || SkipDirective.getName().equals(directiveDefinition.getName())) { + // skip and include directives are added by default to the GraphQLSchema via the GraphQLSchema builder. + continue; + } + GraphQLDirective directive = buildDirectiveDefinitionFromAst(buildCtx, directiveDefinition, inputTypeFactory(buildCtx)); + buildCtx.addDirectiveDefinition(directive); + additionalDirectives.add(directive); + } + return additionalDirectives; + } + + void addDirectivesIncludedByDefault(TypeDefinitionRegistry typeRegistry) { + // we synthesize this into the type registry - no need for them to add it + typeRegistry.add(DEPRECATED_DIRECTIVE_DEFINITION); + typeRegistry.add(SPECIFIED_BY_DIRECTIVE_DEFINITION); + typeRegistry.add(ONE_OF_DIRECTIVE_DEFINITION); + } + + private Optional getOperationNamed(String name, Map operationTypeDefs) { + return Optional.ofNullable(operationTypeDefs.get(name)); + } + + private DataFetcher dataFetcherOfLastResort() { + return SingletonPropertyDataFetcher.singleton(); + } + + private List directivesOf(List> typeDefinitions) { + return typeDefinitions.stream() + .map(TypeDefinition::getDirectives) + .filter(Objects::nonNull) + .flatMap(List::stream).collect(Collectors.toList()); + } + + private T directivesObserve(BuildContext buildCtx, T directiveContainer) { + if (!buildCtx.directiveWiringRequired) { + boolean requiresWiring = SchemaGeneratorDirectiveHelper.schemaDirectiveWiringIsRequired(directiveContainer, buildCtx.getTypeRegistry(), buildCtx.getWiring()); + buildCtx.directiveWiringRequired = buildCtx.directiveWiringRequired || requiresWiring; + } + return directiveContainer; } } diff --git a/src/main/java/graphql/schema/idl/SchemaParseOrder.java b/src/main/java/graphql/schema/idl/SchemaParseOrder.java new file mode 100644 index 0000000000..4853b9e92d --- /dev/null +++ b/src/main/java/graphql/schema/idl/SchemaParseOrder.java @@ -0,0 +1,157 @@ +package graphql.schema.idl; + +import com.google.common.collect.ImmutableMap; +import graphql.collect.ImmutableKit; +import graphql.language.SDLDefinition; +import graphql.language.SDLNamedDefinition; +import graphql.language.SourceLocation; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLSchemaElement; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; + +import static java.util.Optional.ofNullable; + +/** + * This class will track what order {@link SDLDefinition} were parsed in + * via {@link SchemaParser} and {@link TypeDefinitionRegistry} + */ +public class SchemaParseOrder implements Serializable { + + private final Map>> definitionOrder = new LinkedHashMap<>(); + + + /** + * This map is the order in which {@link SDLDefinition}s were parsed per unique {@link SourceLocation#getSourceName()}. If there + * is no source then the empty string "" is used. + * + * @return a map of source names to definitions in parsed order + */ + public Map>> getInOrder() { + return ImmutableMap.copyOf(definitionOrder); + } + + /** + * This map is the order in which {@link SDLDefinition}s were parsed per unique {@link SourceLocation#getSourceName()} and it + * only contains {@link SDLNamedDefinition}s. If there is no source then the empty string "" is used. + * + * @return a map of source names to definitions in parsed order + */ + public Map>> getInNameOrder() { + Map>> named = new LinkedHashMap<>(); + definitionOrder.forEach((location, def) -> { + List> namedDefs = ImmutableKit.filterAndMap(def, + d -> d instanceof SDLNamedDefinition, + d -> (SDLNamedDefinition) d); + named.put(location, namedDefs); + }); + return named; + } + + /** + * This comparator will sort according to the original parsed order + * + * @param is a {@link GraphQLSchemaElement} + * + * @return a comparator that sorts schema elements in parsed order + */ + public Comparator getElementComparator() { + // relies in the fact that names in graphql schema are unique across ALL elements + Map namedSortValues = buildNameIndex(getInNameOrder()); + return (e1, e2) -> { + if (isAssignable(e1, GraphQLFieldDefinition.class, GraphQLInputObjectField.class, GraphQLEnumValueDefinition.class) || + isAssignable(e2, GraphQLFieldDefinition.class, GraphQLInputObjectField.class, GraphQLEnumValueDefinition.class) + ) { + return 0; // as is - they are not parsed tracked + } + if (isAssignable(e1, GraphQLDirective.class, GraphQLNamedType.class) && isAssignable(e2, GraphQLDirective.class, GraphQLNamedType.class)) { + int sortVal1 = sortValue((GraphQLNamedSchemaElement) e1, namedSortValues); + int sortVal2 = sortValue((GraphQLNamedSchemaElement) e2, namedSortValues); + return Integer.compare(sortVal1, sortVal2); + } + return -1; // sort to the top + }; + } + + private boolean isAssignable(T e1, Class... classes) { + return Arrays.stream(classes).anyMatch(aClass -> aClass.isAssignableFrom(e1.getClass())); + } + + private Integer sortValue(GraphQLNamedSchemaElement e1, Map namedSortValues) { + return namedSortValues.getOrDefault(e1.getName(), -1); + } + + private Map buildNameIndex(Map>> inNameOrder) { + Map nameIndex = new HashMap<>(); + int sourceIndex = 0; + for (Map.Entry>> entry : inNameOrder.entrySet()) { + List> namedDefs = entry.getValue(); + for (int i = 0; i < namedDefs.size(); i++) { + SDLNamedDefinition namedDefinition = namedDefs.get(i); + // we will put it in parsed order AND with first sources first + int index = i + (sourceIndex * 100_000_000); + nameIndex.put(namedDefinition.getName(), index); + } + sourceIndex++; + } + return nameIndex; + } + + /** + * This adds a new {@link SDLDefinition} to the order + * + * @param sdlDefinition the SDL definition to add + * @param for two + * + * @return this {@link SchemaParseOrder} for fluent building + */ + public > SchemaParseOrder addDefinition(T sdlDefinition) { + if (sdlDefinition != null) { + definitionList(sdlDefinition).add(sdlDefinition); + } + return this; + } + + /** + * This removes a {@link SDLDefinition} from the order + * + * @param sdlDefinition the SDL definition to remove + * @param for two + * + * @return this {@link SchemaParseOrder} for fluent building + */ + public > SchemaParseOrder removeDefinition(T sdlDefinition) { + definitionList(sdlDefinition).remove(sdlDefinition); + return this; + } + + private > List> definitionList(T sdlDefinition) { + String location = ofNullable(sdlDefinition.getSourceLocation()) + .map(SourceLocation::getSourceName).orElse(""); + return computeIfAbsent(location); + } + + private List> computeIfAbsent(String location) { + return definitionOrder.computeIfAbsent(location, k -> new ArrayList<>()); + } + + @Override + public String toString() { + return new StringJoiner(", ", SchemaParseOrder.class.getSimpleName() + "[", "]") + .add("definitionOrder=" + definitionOrder) + .toString(); + } +} diff --git a/src/main/java/graphql/schema/idl/SchemaParser.java b/src/main/java/graphql/schema/idl/SchemaParser.java index af64272295..0d6c071282 100644 --- a/src/main/java/graphql/schema/idl/SchemaParser.java +++ b/src/main/java/graphql/schema/idl/SchemaParser.java @@ -6,19 +6,27 @@ import graphql.language.Definition; import graphql.language.Document; import graphql.language.SDLDefinition; +import graphql.parser.InvalidSyntaxException; import graphql.parser.Parser; +import graphql.parser.ParserEnvironment; +import graphql.parser.ParserOptions; +import graphql.schema.idl.errors.NonSDLDefinitionError; import graphql.schema.idl.errors.SchemaProblem; -import org.antlr.v4.runtime.misc.ParseCancellationException; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.Reader; -import java.io.StringWriter; +import java.io.StringReader; import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static graphql.parser.ParserEnvironment.newParserEnvironment; import static java.nio.charset.Charset.defaultCharset; /** @@ -26,6 +34,7 @@ * definitions ready to be placed into {@link SchemaGenerator} say */ @PublicApi +@NullMarked public class SchemaParser { /** @@ -45,6 +54,19 @@ public TypeDefinitionRegistry parse(File file) throws SchemaProblem { } } + /** + * Parse a inputStream of schema definitions and create a {@link TypeDefinitionRegistry} + * + * @param inputStream the inputStream to parse + * + * @return registry of type definitions + * + * @throws SchemaProblem if there are problems compiling the schema definitions + */ + public TypeDefinitionRegistry parse(InputStream inputStream) throws SchemaProblem { + return parse(new InputStreamReader(inputStream)); + } + /** * Parse a reader of schema definitions and create a {@link TypeDefinitionRegistry} * @@ -55,8 +77,22 @@ public TypeDefinitionRegistry parse(File file) throws SchemaProblem { * @throws SchemaProblem if there are problems compiling the schema definitions */ public TypeDefinitionRegistry parse(Reader reader) throws SchemaProblem { + return parse(reader, null); + } + + /** + * Parse a reader of schema definitions and create a {@link TypeDefinitionRegistry} + * + * @param reader the reader to parse + * @param parserOptions the parse options to use while parsing + * + * @return registry of type definitions + * + * @throws SchemaProblem if there are problems compiling the schema definitions + */ + public TypeDefinitionRegistry parse(Reader reader, @Nullable ParserOptions parserOptions) throws SchemaProblem { try (Reader input = reader) { - return parse(read(input)); + return parseImpl(input, parserOptions); } catch (IOException e) { throw new RuntimeException(e); } @@ -72,18 +108,29 @@ public TypeDefinitionRegistry parse(Reader reader) throws SchemaProblem { * @throws SchemaProblem if there are problems compiling the schema definitions */ public TypeDefinitionRegistry parse(String schemaInput) throws SchemaProblem { + return parseImpl(new StringReader(schemaInput)); + } + + public TypeDefinitionRegistry parseImpl(Reader schemaInput) { + // why it this public - (head shake) + return parseImpl(schemaInput, null); + } + + private TypeDefinitionRegistry parseImpl(Reader schemaInput, @Nullable ParserOptions parseOptions) { try { - Parser parser = new Parser(); - Document document = parser.parseDocument(schemaInput); + if (parseOptions == null) { + parseOptions = ParserOptions.getDefaultSdlParserOptions(); + } + ParserEnvironment parserEnvironment = newParserEnvironment().document(schemaInput).parserOptions(parseOptions).build(); + Document document = Parser.parse(parserEnvironment); return buildRegistry(document); - } catch (ParseCancellationException e) { - throw handleParseException(e); + } catch (InvalidSyntaxException e) { + throw handleParseException(e.toInvalidSyntaxError()); } } - private SchemaProblem handleParseException(ParseCancellationException e) throws RuntimeException { - InvalidSyntaxError invalidSyntaxError = InvalidSyntaxError.toInvalidSyntaxError(e); + private SchemaProblem handleParseException(InvalidSyntaxError invalidSyntaxError) throws RuntimeException { return new SchemaProblem(Collections.singletonList(invalidSyntaxError)); } @@ -104,6 +151,8 @@ public TypeDefinitionRegistry buildRegistry(Document document) { for (Definition definition : definitions) { if (definition instanceof SDLDefinition) { typeRegistry.add((SDLDefinition) definition).ifPresent(errors::add); + } else { + errors.add(new NonSDLDefinitionError(definition)); } } if (errors.size() > 0) { @@ -112,14 +161,4 @@ public TypeDefinitionRegistry buildRegistry(Document document) { return typeRegistry; } } - - private String read(Reader reader) throws IOException { - char[] buffer = new char[1024 * 4]; - StringWriter sw = new StringWriter(); - int n; - while (-1 != (n = reader.read(buffer))) { - sw.write(buffer, 0, n); - } - return sw.toString(); - } } diff --git a/src/main/java/graphql/schema/idl/SchemaPrinter.java b/src/main/java/graphql/schema/idl/SchemaPrinter.java index 7788321416..cafa142e0c 100644 --- a/src/main/java/graphql/schema/idl/SchemaPrinter.java +++ b/src/main/java/graphql/schema/idl/SchemaPrinter.java @@ -1,15 +1,33 @@ package graphql.schema.idl; import graphql.Assert; +import graphql.DirectivesUtil; +import graphql.GraphQLContext; import graphql.PublicApi; +import graphql.execution.ValuesResolver; import graphql.language.AstPrinter; -import graphql.language.AstValueHelper; import graphql.language.Comment; import graphql.language.Description; +import graphql.language.DirectiveDefinition; import graphql.language.Document; -import graphql.language.Node; +import graphql.language.EnumTypeDefinition; +import graphql.language.EnumValueDefinition; +import graphql.language.FieldDefinition; +import graphql.language.InputObjectTypeDefinition; +import graphql.language.InputValueDefinition; +import graphql.language.InterfaceTypeDefinition; +import graphql.language.ObjectTypeDefinition; +import graphql.language.ScalarTypeDefinition; +import graphql.language.SchemaDefinition; +import graphql.language.SchemaExtensionDefinition; +import graphql.language.TypeDefinition; +import graphql.language.UnionTypeDefinition; +import graphql.schema.DefaultGraphqlTypeComparatorRegistry; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; import graphql.schema.GraphQLArgument; import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; import graphql.schema.GraphQLEnumType; import graphql.schema.GraphQLEnumValueDefinition; import graphql.schema.GraphQLFieldDefinition; @@ -17,54 +35,102 @@ import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInputType; import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; import graphql.schema.GraphQLType; import graphql.schema.GraphQLTypeUtil; import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphqlTypeComparatorEnvironment; +import graphql.schema.GraphqlTypeComparatorRegistry; +import graphql.schema.InputValueWithState; import graphql.schema.visibility.GraphqlFieldVisibility; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; -import java.util.function.Supplier; +import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; +import static graphql.Directives.DeprecatedDirective; +import static graphql.Scalars.GraphQLString; import static graphql.schema.visibility.DefaultGraphqlFieldVisibility.DEFAULT_FIELD_VISIBILITY; +import static graphql.util.EscapeUtil.escapeJsonString; +import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; - /** * This can print an in memory GraphQL schema back to a logical schema definition */ @PublicApi public class SchemaPrinter { + /** + * This predicate excludes all directives which are specified by the GraphQL Specification. + * Printing these directives is optional. + */ + public static final Predicate ExcludeGraphQLSpecifiedDirectivesPredicate = d -> !DirectiveInfo.isGraphqlSpecifiedDirective(d); /** * Options to use when printing a schema */ public static class Options { + private final boolean includeIntrospectionTypes; private final boolean includeScalars; - private final boolean includeExtendedScalars; + + private final boolean useAstDefinitions; + private final boolean includeSchemaDefinition; + private final boolean includeDirectiveDefinitions; + + private final boolean descriptionsAsHashComments; + + private final Predicate includeDirectiveDefinition; + + private final Predicate includeDirective; + + private final Predicate includeSchemaElement; + + private final GraphqlTypeComparatorRegistry comparatorRegistry; + + private final boolean includeAstDefinitionComments; + private Options(boolean includeIntrospectionTypes, boolean includeScalars, - boolean includeExtendedScalars, - boolean includeSchemaDefinition) { + boolean includeSchemaDefinition, + boolean includeDirectiveDefinitions, + Predicate includeDirectiveDefinition, + boolean useAstDefinitions, + boolean descriptionsAsHashComments, + Predicate includeDirective, + Predicate includeSchemaElement, + GraphqlTypeComparatorRegistry comparatorRegistry, + boolean includeAstDefinitionComments) { this.includeIntrospectionTypes = includeIntrospectionTypes; this.includeScalars = includeScalars; - this.includeExtendedScalars = includeExtendedScalars; this.includeSchemaDefinition = includeSchemaDefinition; + this.includeDirectiveDefinitions = includeDirectiveDefinitions; + this.includeDirectiveDefinition = includeDirectiveDefinition; + this.includeDirective = includeDirective; + this.useAstDefinitions = useAstDefinitions; + this.descriptionsAsHashComments = descriptionsAsHashComments; + this.comparatorRegistry = comparatorRegistry; + this.includeSchemaElement = includeSchemaElement; + this.includeAstDefinitionComments = includeAstDefinitionComments; } public boolean isIncludeIntrospectionTypes() { @@ -75,16 +141,53 @@ public boolean isIncludeScalars() { return includeScalars; } - public boolean isIncludeExtendedScalars() { - return includeExtendedScalars; - } - public boolean isIncludeSchemaDefinition() { return includeSchemaDefinition; } + public boolean isIncludeDirectiveDefinitions() { + return includeDirectiveDefinitions; + } + + public Predicate getIncludeDirectiveDefinition() { + return includeDirectiveDefinition; + } + + public Predicate getIncludeDirective() { + return includeDirective; + } + + public Predicate getIncludeSchemaElement() { + return includeSchemaElement; + } + + public boolean isDescriptionsAsHashComments() { + return descriptionsAsHashComments; + } + + public GraphqlTypeComparatorRegistry getComparatorRegistry() { + return comparatorRegistry; + } + + public boolean isUseAstDefinitions() { + return useAstDefinitions; + } + + public boolean isIncludeAstDefinitionComments() { + return includeAstDefinitionComments; + } + public static Options defaultOptions() { - return new Options(false, false, false, false); + return new Options(false, + true, + false, + true, + directive -> true, false, + false, + directive -> true, + element -> true, + DefaultGraphqlTypeComparatorRegistry.defaultComparators(), + false); } /** @@ -95,7 +198,16 @@ public static Options defaultOptions() { * @return options */ public Options includeIntrospectionTypes(boolean flag) { - return new Options(flag, this.includeScalars, includeExtendedScalars, this.includeSchemaDefinition); + return new Options(flag, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); } /** @@ -106,37 +218,251 @@ public Options includeIntrospectionTypes(boolean flag) { * @return options */ public Options includeScalarTypes(boolean flag) { - return new Options(this.includeIntrospectionTypes, flag, includeExtendedScalars, this.includeSchemaDefinition); + return new Options(this.includeIntrospectionTypes, + flag, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); } /** - * This will allow you to include the graphql 'extended' scalar types that come with graphql-java such as - * GraphQLBigDecimal or GraphQLBigInteger + * This will force the printing of the graphql schema definition even if the query, mutation, and/or subscription + * types use the default names. Some graphql parsers require this information even if the schema uses the + * default type names. The schema definition will always be printed if any of the query, mutation, or subscription + * types do not use the default names. * - * @param flag whether to include them + * @param flag whether to force include the schema definition * * @return options */ - public Options includeExtendedScalarTypes(boolean flag) { - return new Options(this.includeIntrospectionTypes, this.includeScalars, flag, this.includeSchemaDefinition); + public Options includeSchemaDefinition(boolean flag) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + flag, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); } /** - * This will force the printing of the graphql schema definition even if the query, mutation, and/or subscription - * types use the default names. Some graphql parsers require this information even if the schema uses the - * default type names. The schema definition will always be printed if any of the query, mutation, or subscription - * types do not use the default names. + * This flag controls whether schema printer will include directive definitions at the top of the schema, but does not remove them from the field or type usage. + *

+ * In some schema definitions, like Apollo Federation, the schema should be printed without the directive definitions. + * This simplified schema is returned by a GraphQL query to other services, in a format that is different that the introspection query. + *

+ * On by default. * - * @param flag whether to force include the schema definition + * @param flag whether to print directive definitions + * + * @return new instance of options + */ + public Options includeDirectiveDefinitions(boolean flag) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + flag, + directive -> flag, + this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + + /** + * This is a Predicate that decides whether a directive definition is printed. + * + * @param includeDirectiveDefinition the predicate to decide of a directive definition is printed + * + * @return new instance of options + */ + public Options includeDirectiveDefinition(Predicate includeDirectiveDefinition) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + /** + * Allow to print directives. In some situations, auto-generated schemas contain a lot of directives that + * make the printout noisy and having this flag would allow cleaner printout. On by default. + * + * @param flag whether to print directives + * + * @return new instance of options + */ + public Options includeDirectives(boolean flag) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + directive -> flag, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + /** + * This is a Predicate that decides whether a directive element is printed. + * + * @param includeDirective the predicate to decide of a directive is printed + * + * @return new instance of options + */ + public Options includeDirectives(Predicate includeDirective) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + + /** + * This is a general purpose Predicate that decides whether a schema element is printed ever. + * + * @param includeSchemaElement the predicate to decide of a schema is printed + * + * @return new instance of options + */ + public Options includeSchemaElement(Predicate includeSchemaElement) { + Assert.assertNotNull(includeSchemaElement); + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + /** + * This flag controls whether schema printer will use the {@link graphql.schema.GraphQLType}'s original Ast {@link graphql.language.TypeDefinition}s when printing the type. This + * allows access to any `extend type` declarations that might have been originally made. + * + * @param flag whether to print via AST type definitions + * + * @return new instance of options + */ + public Options useAstDefinitions(boolean flag) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + flag, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + /** + * Descriptions are defined as preceding string literals, however an older legacy + * versions of SDL supported preceding '#' comments as + * descriptions. Set this to true to enable this deprecated behavior. + * This option is provided to ease adoption and may be removed in future versions. + * + * @param flag whether to print description as # comments + * + * @return new instance of options + */ + public Options descriptionsAsHashComments(boolean flag) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + flag, + this.includeDirective, + this.includeSchemaElement, + this.comparatorRegistry, + this.includeAstDefinitionComments); + } + + /** + * The comparator registry controls the printing order for registered {@code GraphQLType}s. + *

+ * The default is to sort elements by name but you can put in your own code to decide on the field order + * + * @param comparatorRegistry The registry containing the {@code Comparator} and environment scoping rules. * * @return options */ - public Options includeSchemaDefintion(boolean flag) { - return new Options(this.includeIntrospectionTypes, this.includeScalars, this.includeExtendedScalars, flag); + public Options setComparators(GraphqlTypeComparatorRegistry comparatorRegistry) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + comparatorRegistry, + this.includeAstDefinitionComments); + } + + /** + * Sometimes it is useful to allow printing schema comments. This can be achieved by providing comments in the AST definitions. + *

+ * The default is to ignore these for backward compatibility and due to this being relatively uncommon need. + * + * @param flag whether to include AST definition comments. + * + * @return new instance of Options + */ + public Options includeAstDefinitionComments(boolean flag) { + return new Options(this.includeIntrospectionTypes, + this.includeScalars, + this.includeSchemaDefinition, + this.includeDirectiveDefinitions, + this.includeDirectiveDefinition, + this.useAstDefinitions, + this.descriptionsAsHashComments, + this.includeDirective, + this.includeSchemaElement, + comparatorRegistry, + flag); } } - private final Map> printers = new LinkedHashMap<>(); + private final Map, SchemaElementPrinter> printers = new LinkedHashMap<>(); + private final Options options; public SchemaPrinter() { @@ -146,6 +472,7 @@ public SchemaPrinter() { public SchemaPrinter(Options options) { this.options = options; printers.put(GraphQLSchema.class, schemaPrinter()); + printers.put(GraphQLDirective.class, directivePrinter()); printers.put(GraphQLObjectType.class, objectPrinter()); printers.put(GraphQLEnumType.class, enumPrinter()); printers.put(GraphQLScalarType.class, scalarPrinter()); @@ -156,8 +483,7 @@ public SchemaPrinter(Options options) { /** * This can print an in memory GraphQL IDL document back to a logical schema definition. - * - * If you want to turn a Introspection query result into a Document (and then into a printed + * If you want to turn an Introspection query result into a Document (and then into a printed * schema) then use {@link graphql.introspection.IntrospectionResultToSchema#createSchemaDefinition(java.util.Map)} * first to get the {@link graphql.language.Document} and then print that. * @@ -181,195 +507,335 @@ public String print(GraphQLSchema schema) { StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter(sw); - GraphqlFieldVisibility visibility = schema.getFieldVisibility(); + GraphqlFieldVisibility visibility = schema.getCodeRegistry().getFieldVisibility(); printer(schema.getClass()).print(out, schema, visibility); + Comparator comparator = getComparator(GraphQLSchemaElement.class, null); - List typesAsList = schema.getAllTypesAsList() - .stream() - .sorted(Comparator.comparing(GraphQLType::getName)) - .collect(toList()); + Stream directivesAndTypes = Stream.concat( + schema.getAllTypesAsList().stream(), + getSchemaDirectives(schema).stream()); - printType(out, typesAsList, GraphQLInterfaceType.class, visibility); - printType(out, typesAsList, GraphQLUnionType.class, visibility); - printType(out, typesAsList, GraphQLObjectType.class, visibility); - printType(out, typesAsList, GraphQLEnumType.class, visibility); - printType(out, typesAsList, GraphQLScalarType.class, visibility); - printType(out, typesAsList, GraphQLInputObjectType.class, visibility); + List elements = directivesAndTypes + .map(e -> (GraphQLSchemaElement) e) + .filter(options.getIncludeSchemaElement()) + .sorted(comparator) + .collect(toList()); - String result = sw.toString(); - if (result.endsWith("\n\n")) { - result = result.substring(0, result.length() - 1); + for (GraphQLSchemaElement element : elements) { + printSchemaElement(out, element, visibility); } - return result; + + return trimNewLineChars(sw.toString()); } - private interface TypePrinter { + private interface SchemaElementPrinter { - void print(PrintWriter out, T type, GraphqlFieldVisibility visibility); + void print(PrintWriter out, T schemaElement, GraphqlFieldVisibility visibility); } - private boolean isIntrospectionType(GraphQLType type) { + private boolean isIntrospectionType(GraphQLNamedType type) { return !options.isIncludeIntrospectionTypes() && type.getName().startsWith("__"); } - private TypePrinter scalarPrinter() { + private SchemaElementPrinter scalarPrinter() { return (out, type, visibility) -> { if (!options.isIncludeScalars()) { return; } boolean printScalar; - if (ScalarInfo.isStandardScalar(type)) { + if (ScalarInfo.isGraphqlSpecifiedScalar(type)) { printScalar = false; //noinspection RedundantIfStatement - if (options.isIncludeExtendedScalars() && !ScalarInfo.isGraphqlSpecifiedScalar(type)) { + if (!ScalarInfo.isGraphqlSpecifiedScalar(type)) { printScalar = true; } } else { printScalar = true; } if (printScalar) { - printComments(out, type, ""); - out.format("scalar %s%s\n\n", type.getName(), directivesString(type.getDirectives())); + if (shouldPrintAsAst(type.getDefinition())) { + printAsAst(out, type.getDefinition(), type.getExtensionDefinitions()); + } else { + printComments(out, type, ""); + out.format("scalar %s%s\n\n", type.getName(), directivesString(GraphQLScalarType.class, type)); + } } }; } - private TypePrinter enumPrinter() { + + private SchemaElementPrinter enumPrinter() { return (out, type, visibility) -> { if (isIntrospectionType(type)) { return; } - printComments(out, type, ""); - out.format("enum %s%s {\n", type.getName(), directivesString(type.getDirectives())); - List values = type.getValues() - .stream() - .sorted(Comparator.comparing(GraphQLEnumValueDefinition::getName)) - .collect(toList()); - for (GraphQLEnumValueDefinition enumValueDefinition : values) { - printComments(out, enumValueDefinition, " "); - out.format(" %s%s\n", enumValueDefinition.getName(), directivesString(enumValueDefinition.getDirectives())); + + Comparator comparator = getComparator(GraphQLEnumType.class, GraphQLEnumValueDefinition.class); + + if (shouldPrintAsAst(type.getDefinition())) { + printAsAst(out, type.getDefinition(), type.getExtensionDefinitions()); + } else { + printComments(out, type, ""); + out.format("enum %s%s", type.getName(), directivesString(GraphQLEnumType.class, type)); + List values = type.getValues() + .stream() + .sorted(comparator) + .collect(toList()); + if (values.size() > 0) { + out.format(" {\n"); + for (GraphQLEnumValueDefinition enumValueDefinition : values) { + printComments(out, enumValueDefinition, " "); + out.format(" %s%s\n", enumValueDefinition.getName(), directivesString(GraphQLEnumValueDefinition.class, enumValueDefinition.isDeprecated(), enumValueDefinition)); + } + out.format("}"); + } + out.format("\n\n"); } - out.format("}\n\n"); }; } - private TypePrinter interfacePrinter() { + private void printFieldDefinitions(PrintWriter out, Comparator comparator, List fieldDefinitions) { + if (fieldDefinitions.size() == 0) { + return; + } + + out.format(" {\n"); + fieldDefinitions + .stream() + .filter(options.getIncludeSchemaElement()) + .sorted(comparator) + .forEach(fd -> { + printComments(out, fd, " "); + + out.format(" %s%s: %s%s\n", + fd.getName(), argsString(GraphQLFieldDefinition.class, fd.getArguments()), typeString(fd.getType()), + directivesString(GraphQLFieldDefinition.class, fd.isDeprecated(), fd)); + }); + out.format("}"); + } + + private SchemaElementPrinter interfacePrinter() { return (out, type, visibility) -> { if (isIntrospectionType(type)) { return; } - printComments(out, type, ""); - out.format("interface %s%s {\n", type.getName(), directivesString(type.getDirectives())); - visibility.getFieldDefinitions(type) - .stream() - .sorted(Comparator.comparing(GraphQLFieldDefinition::getName)) - .forEach(fd -> { - printComments(out, fd, " "); - out.format(" %s%s: %s%s\n", - fd.getName(), argsString(fd.getArguments()), typeString(fd.getType()), directivesString(fd.getDirectives())); - }); - out.format("}\n\n"); + + if (shouldPrintAsAst(type.getDefinition())) { + printAsAst(out, type.getDefinition(), type.getExtensionDefinitions()); + } else { + printComments(out, type, ""); + if (type.getInterfaces().isEmpty()) { + out.format("interface %s%s", type.getName(), directivesString(GraphQLInterfaceType.class, type)); + } else { + + Comparator implementsComparator = getComparator(GraphQLInterfaceType.class, GraphQLOutputType.class); + + Stream interfaceNames = type.getInterfaces() + .stream() + .sorted(implementsComparator) + .map(GraphQLNamedType::getName); + out.format("interface %s implements %s%s", + type.getName(), + interfaceNames.collect(joining(" & ")), + directivesString(GraphQLInterfaceType.class, type)); + } + + Comparator comparator = getComparator(GraphQLInterfaceType.class, GraphQLFieldDefinition.class); + + printFieldDefinitions(out, comparator, visibility.getFieldDefinitions(type)); + out.format("\n\n"); + } }; } - private TypePrinter unionPrinter() { + private SchemaElementPrinter unionPrinter() { return (out, type, visibility) -> { if (isIntrospectionType(type)) { return; } - printComments(out, type, ""); - out.format("union %s%s = ", type.getName(), directivesString(type.getDirectives())); - List types = type.getTypes() - .stream() - .sorted(Comparator.comparing(GraphQLOutputType::getName)) - .collect(toList()); - for (int i = 0; i < types.size(); i++) { - GraphQLOutputType objectType = types.get(i); - if (i > 0) { - out.format(" | "); + + Comparator comparator = getComparator(GraphQLUnionType.class, GraphQLOutputType.class); + + if (shouldPrintAsAst(type.getDefinition())) { + printAsAst(out, type.getDefinition(), type.getExtensionDefinitions()); + } else { + printComments(out, type, ""); + out.format("union %s%s = ", type.getName(), directivesString(GraphQLUnionType.class, type)); + List types = type.getTypes() + .stream() + .sorted(comparator) + .collect(toList()); + for (int i = 0; i < types.size(); i++) { + GraphQLNamedOutputType objectType = types.get(i); + if (i > 0) { + out.format(" | "); + } + out.format("%s", objectType.getName()); } - out.format("%s", objectType.getName()); + out.format("\n\n"); } - out.format("\n\n"); }; } + private SchemaElementPrinter directivePrinter() { + return (out, directive, visibility) -> { + boolean isOnEver = options.isIncludeDirectiveDefinitions(); + boolean specificTest = options.getIncludeDirectiveDefinition().test(directive.getName()); + if (isOnEver && specificTest) { + String s = directiveDefinition(directive); + out.format("%s", s); + out.print("\n\n"); + } + }; + } - private TypePrinter objectPrinter() { + private SchemaElementPrinter objectPrinter() { return (out, type, visibility) -> { if (isIntrospectionType(type)) { return; } - printComments(out, type, ""); - if (type.getInterfaces().isEmpty()) { - out.format("type %s%s {\n", type.getName(), directivesString(type.getDirectives())); + if (shouldPrintAsAst(type.getDefinition())) { + printAsAst(out, type.getDefinition(), type.getExtensionDefinitions()); } else { - Stream interfaceNames = type.getInterfaces() - .stream() - .map(GraphQLType::getName) - .sorted(Comparator.naturalOrder()); - out.format("type %s implements %s%s {\n", - type.getName(), - interfaceNames.collect(joining(" & ")), - directivesString(type.getDirectives())); - } + printComments(out, type, ""); + if (type.getInterfaces().isEmpty()) { + out.format("type %s%s", type.getName(), directivesString(GraphQLObjectType.class, type)); + } else { + + Comparator implementsComparator = getComparator(GraphQLObjectType.class, GraphQLOutputType.class); + + Stream interfaceNames = type.getInterfaces() + .stream() + .sorted(implementsComparator) + .map(GraphQLNamedType::getName); + out.format("type %s implements %s%s", + type.getName(), + interfaceNames.collect(joining(" & ")), + directivesString(GraphQLObjectType.class, type)); + } + + Comparator comparator = getComparator(GraphQLObjectType.class, GraphQLFieldDefinition.class); - visibility.getFieldDefinitions(type) - .stream() - .sorted(Comparator.comparing(GraphQLFieldDefinition::getName)) - .forEach(fd -> { - printComments(out, fd, " "); - out.format(" %s%s: %s%s\n", - fd.getName(), argsString(fd.getArguments()), typeString(fd.getType()), directivesString(fd.getDirectives())); - }); - out.format("}\n\n"); + printFieldDefinitions(out, comparator, visibility.getFieldDefinitions(type)); + out.format("\n\n"); + } }; } - - private TypePrinter inputObjectPrinter() { + private SchemaElementPrinter inputObjectPrinter() { return (out, type, visibility) -> { if (isIntrospectionType(type)) { return; } - printComments(out, type, ""); - out.format("input %s%s {\n", type.getName(), directivesString(type.getDirectives())); - visibility.getFieldDefinitions(type) - .stream() - .sorted(Comparator.comparing(GraphQLInputObjectField::getName)) - .forEach(fd -> { - printComments(out, fd, " "); - out.format(" %s: %s", - fd.getName(), typeString(fd.getType())); - Object defaultValue = fd.getDefaultValue(); - if (defaultValue != null) { - String astValue = printAst(defaultValue, fd.getType()); - out.format(" = %s", astValue); - } - out.format(directivesString(fd.getDirectives())); - out.format("\n"); - }); - out.format("}\n\n"); + if (shouldPrintAsAst(type.getDefinition())) { + printAsAst(out, type.getDefinition(), type.getExtensionDefinitions()); + } else { + printComments(out, type, ""); + + Comparator comparator = getComparator(GraphQLInputObjectType.class, GraphQLInputObjectField.class); + + out.format("input %s%s", type.getName(), directivesString(GraphQLInputObjectType.class, type)); + List inputObjectFields = visibility.getFieldDefinitions(type); + if (inputObjectFields.size() > 0) { + out.format(" {\n"); + inputObjectFields + .stream() + .filter(options.getIncludeSchemaElement()) + .sorted(comparator) + .forEach(fd -> { + printComments(out, fd, " "); + out.format(" %s: %s", + fd.getName(), typeString(fd.getType())); + if (fd.hasSetDefaultValue()) { + InputValueWithState defaultValue = fd.getInputFieldDefaultValue(); + String astValue = printAst(defaultValue, fd.getType()); + out.format(" = %s", astValue); + } + out.print(directivesString(GraphQLInputObjectField.class, fd.isDeprecated(), fd)); + out.format("\n"); + }); + out.format("}"); + } + out.format("\n\n"); + } }; } - private static String printAst(Object value, GraphQLInputType type) { - return AstPrinter.printAst(AstValueHelper.astFromValue(value, type)); + /** + * This will return true if the options say to use the AST and we have an AST element + * + * @param definition the AST type definition + * + * @return true if we should print using AST nodes + */ + private boolean shouldPrintAsAst(TypeDefinition definition) { + return options.isUseAstDefinitions() && definition != null; } + /** + * This will return true if the options say to use the AST and we have an AST element + * + * @param definition the AST schema definition + * + * @return true if we should print using AST nodes + */ + private boolean shouldPrintAsAst(SchemaDefinition definition) { + return options.isUseAstDefinitions() && definition != null; + } + + /** + * This will print out a runtime graphql schema element using its contained AST type definition. This + * must be guarded by a called to {@link #shouldPrintAsAst(TypeDefinition)} + * + * @param out the output writer + * @param definition the AST type definition + * @param extensions a list of type definition extensions + */ + private void printAsAst(PrintWriter out, TypeDefinition definition, List> extensions) { + out.printf("%s\n", AstPrinter.printAst(definition)); + if (extensions != null) { + for (TypeDefinition extension : extensions) { + out.printf("\n%s\n", AstPrinter.printAst(extension)); + } + } + out.print('\n'); + } + + /** + * This will print out a runtime graphql schema block using its AST definition. This + * must be guarded by a called to {@link #shouldPrintAsAst(SchemaDefinition)} + * + * @param out the output writer + * @param definition the AST schema definition + * @param extensions a list of schema definition extensions + */ + private void printAsAst(PrintWriter out, SchemaDefinition definition, List extensions) { + out.printf("%s\n", AstPrinter.printAst(definition)); + if (extensions != null) { + for (SchemaExtensionDefinition extension : extensions) { + out.printf("\n%s\n", AstPrinter.printAst(extension)); + } + } + out.print('\n'); + } - private TypePrinter schemaPrinter() { - return (out, type, visibility) -> { - GraphQLObjectType queryType = type.getQueryType(); - GraphQLObjectType mutationType = type.getMutationType(); - GraphQLObjectType subscriptionType = type.getSubscriptionType(); + private static String printAst(InputValueWithState value, GraphQLInputType type) { + return AstPrinter.printAst(ValuesResolver.valueToLiteral(value, type, GraphQLContext.getDefault(), Locale.getDefault())); + } + + private SchemaElementPrinter schemaPrinter() { + return (out, schema, visibility) -> { + GraphQLObjectType queryType = schema.getQueryType(); + GraphQLObjectType mutationType = schema.getMutationType(); + GraphQLObjectType subscriptionType = schema.getSubscriptionType(); // when serializing a GraphQL schema using the type system language, a - // schema definition should be omitted if only uses the default root type names. - boolean needsSchemaPrinted = options.includeSchemaDefinition; + // schema definition should be omitted only if it uses the default root type names. + boolean needsSchemaPrinted = options.isIncludeSchemaDefinition(); if (!needsSchemaPrinted) { if (queryType != null && !queryType.getName().equals("Query")) { @@ -384,76 +850,131 @@ private TypePrinter schemaPrinter() { } if (needsSchemaPrinted) { - out.format("schema {\n"); - if (queryType != null) { - out.format(" query: %s\n", queryType.getName()); - } - if (mutationType != null) { - out.format(" mutation: %s\n", mutationType.getName()); + if (shouldPrintAsAst(schema.getDefinition())) { + printAsAst(out, schema.getDefinition(), schema.getExtensionDefinitions()); + } else { + if (hasAstDefinitionComments(schema) || hasDescription(schema)) { + out.print(printComments(schema, "")); + } + List directives = DirectivesUtil.toAppliedDirectives(schema.getSchemaAppliedDirectives(), schema.getSchemaDirectives()); + out.format("schema %s{\n", directivesString(GraphQLSchemaElement.class, directives)); + if (queryType != null) { + out.format(" query: %s\n", queryType.getName()); + } + if (mutationType != null) { + out.format(" mutation: %s\n", mutationType.getName()); + } + if (subscriptionType != null) { + out.format(" subscription: %s\n", subscriptionType.getName()); + } + out.format("}\n\n"); } - if (subscriptionType != null) { - out.format(" subscription: %s\n", subscriptionType.getName()); - } - out.format("}\n\n"); } }; } + private List getSchemaDirectives(GraphQLSchema schema) { + Predicate includePredicate = d -> options.getIncludeDirective().test(d.getName()); + return schema.getDirectives().stream() + .filter(includePredicate) + .filter(options.getIncludeSchemaElement()) + .collect(toList()); + } + String typeString(GraphQLType rawType) { - return GraphQLTypeUtil.getUnwrappedTypeName(rawType); + return GraphQLTypeUtil.simplePrint(rawType); } String argsString(List arguments) { - boolean hasDescriptions = arguments.stream().anyMatch(arg -> !isNullOrEmpty(arg.getDescription())); - String prefix = hasDescriptions ? " " : ""; + return argsString(null, arguments); + } + + String argsString(Class parent, List arguments) { + boolean hasAstDefinitionComments = arguments.stream().anyMatch(this::hasAstDefinitionComments); + boolean hasDescriptions = arguments.stream().anyMatch(this::hasDescription); + String halfPrefix = hasAstDefinitionComments || hasDescriptions ? " " : ""; + String prefix = hasAstDefinitionComments || hasDescriptions ? " " : ""; int count = 0; StringBuilder sb = new StringBuilder(); + + Comparator comparator = getComparator(parent, GraphQLArgument.class); + arguments = arguments .stream() - .sorted(Comparator.comparing(GraphQLArgument::getName)) + .sorted(comparator) + .filter(options.getIncludeSchemaElement()) .collect(toList()); for (GraphQLArgument argument : arguments) { if (count == 0) { sb.append("("); } else { - sb.append(", "); + sb.append(","); + if (!hasAstDefinitionComments && !hasDescriptions) { + sb.append(" "); + } } - if (hasDescriptions) { + if (hasAstDefinitionComments || hasDescriptions) { sb.append("\n"); } - String description = argument.getDescription(); - if (!isNullOrEmpty(description)) { - Stream stream = Arrays.stream(description.split("\n")); - stream.map(s -> " #" + s + "\n").forEach(sb::append); - } + sb.append(printComments(argument, prefix)); + sb.append(prefix).append(argument.getName()).append(": ").append(typeString(argument.getType())); - Object defaultValue = argument.getDefaultValue(); - if (defaultValue != null) { + if (argument.hasSetDefaultValue()) { + InputValueWithState defaultValue = argument.getArgumentDefaultValue(); sb.append(" = "); sb.append(printAst(defaultValue, argument.getType())); } + + sb.append(directivesString(GraphQLArgument.class, argument.isDeprecated(), argument)); + count++; } if (count > 0) { - if (hasDescriptions) { + if (hasAstDefinitionComments || hasDescriptions) { sb.append("\n"); } - sb.append(prefix).append(")"); + sb.append(halfPrefix).append(")"); } return sb.toString(); } - private String directivesString(List directives) { + public String directivesString(Class parentType, GraphQLDirectiveContainer directiveContainer) { + return directivesString(parentType, false, directiveContainer); + } + + String directivesString(Class parentType, boolean isDeprecated, GraphQLDirectiveContainer directiveContainer) { + List directives; + if (isDeprecated) { + directives = addOrUpdateDeprecatedDirectiveIfNeeded(directiveContainer); + } else { + directives = DirectivesUtil.toAppliedDirectives(directiveContainer); + } + return directivesString(parentType, directives); + } + + private String directivesString(Class parentType, List directives) { + directives = directives.stream() + // @deprecated is special - we always print it if something is deprecated + .filter(directive -> options.getIncludeDirective().test(directive.getName())) + .filter(options.getIncludeSchemaElement()) + .collect(toList()); + + if (directives.isEmpty()) { + return ""; + } StringBuilder sb = new StringBuilder(); - if (!directives.isEmpty()) { + if (parentType != GraphQLSchemaElement.class) { sb.append(" "); } + + Comparator comparator = getComparator(parentType, GraphQLAppliedDirective.class); + directives = directives .stream() - .sorted(Comparator.comparing(GraphQLDirective::getName)) + .sorted(comparator) .collect(toList()); for (int i = 0; i < directives.size(); i++) { - GraphQLDirective directive = directives.get(i); + GraphQLAppliedDirective directive = directives.get(i); sb.append(directiveString(directive)); if (i < directives.size() - 1) { sb.append(" "); @@ -462,29 +983,40 @@ private String directivesString(List directives) { return sb.toString(); } - private String directiveString(GraphQLDirective directive) { + private String directiveString(GraphQLAppliedDirective directive) { + if (!options.getIncludeSchemaElement().test(directive)) { + return ""; + } + if (!options.getIncludeDirective().test(directive.getName())) { + return ""; + } + StringBuilder sb = new StringBuilder(); sb.append("@").append(directive.getName()); - List args = directive.getArguments(); + + Comparator comparator = getComparator(GraphQLAppliedDirective.class, GraphQLAppliedDirectiveArgument.class); + + List args = directive.getArguments(); args = args .stream() - .sorted(Comparator.comparing(GraphQLArgument::getName)) + .filter(arg -> arg.getArgumentValue().isSet()) + .sorted(comparator) .collect(toList()); if (!args.isEmpty()) { sb.append("("); for (int i = 0; i < args.size(); i++) { - GraphQLArgument arg = args.get(i); - sb.append(arg.getName()); - if (arg.getValue() != null) { - sb.append(" : "); - sb.append(printAst(arg.getValue(), arg.getType())); + GraphQLAppliedDirectiveArgument arg = args.get(i); + String argValue = null; + if (arg.hasSetValue()) { + argValue = printAst(arg.getArgumentValue(), arg.getType()); } - if (arg.getDefaultValue() != null) { - sb.append(" = "); - sb.append(printAst(arg.getDefaultValue(), arg.getType())); - } - if (i < args.size() - 1) { - sb.append(", "); + if (!isNullOrEmpty(argValue)) { + sb.append(arg.getName()); + sb.append(" : "); + sb.append(argValue); + if (i < args.size() - 1) { + sb.append(", "); + } } } sb.append(")"); @@ -492,139 +1024,350 @@ private String directiveString(GraphQLDirective directive) { return sb.toString(); } + private boolean isDeprecatedDirectiveAllowed() { + // we ask if the special deprecated directive, + // which can be programmatically on a type without an applied directive, + // should be printed or not + return options.getIncludeDirective().test(DeprecatedDirective.getName()); + } + + private boolean isDeprecatedDirective(GraphQLAppliedDirective directive) { + return directive.getName().equals(DeprecatedDirective.getName()); + } + + private boolean hasDeprecatedDirective(List directives) { + return directives.stream() + .filter(this::isDeprecatedDirective) + .count() == 1; + } + + private List addOrUpdateDeprecatedDirectiveIfNeeded(GraphQLDirectiveContainer directiveContainer) { + List directives = DirectivesUtil.toAppliedDirectives(directiveContainer); + String reason = getDeprecationReason(directiveContainer); + + if (!hasDeprecatedDirective(directives) && isDeprecatedDirectiveAllowed()) { + directives = new ArrayList<>(directives); + directives.add(createDeprecatedDirective(reason)); + } else if (hasDeprecatedDirective(directives) && isDeprecatedDirectiveAllowed()) { + // Update deprecated reason in case modified by schema transform + directives = updateDeprecatedDirective(directives, reason); + } + return directives; + } + + private GraphQLAppliedDirective createDeprecatedDirective(String reason) { + GraphQLAppliedDirectiveArgument arg = GraphQLAppliedDirectiveArgument.newArgument() + .name("reason") + .valueProgrammatic(reason) + .type(GraphQLString) + .build(); + return GraphQLAppliedDirective.newDirective() + .name("deprecated") + .argument(arg) + .build(); + } + + private List updateDeprecatedDirective(List directives, String reason) { + GraphQLAppliedDirectiveArgument newArg = GraphQLAppliedDirectiveArgument.newArgument() + .name("reason") + .valueProgrammatic(reason) + .type(GraphQLString) + .build(); + + return directives.stream().map(d -> { + if (isDeprecatedDirective(d)) { + // Don't include reason is deliberately replaced with NOT_SET, for example in Anonymizer + if (d.getArgument("reason").getArgumentValue() != InputValueWithState.NOT_SET) { + return d.transform(builder -> builder.argument(newArg)); + } + } + return d; + }).collect(toList()); + } + + private String getDeprecationReason(GraphQLDirectiveContainer directiveContainer) { + if (directiveContainer instanceof GraphQLFieldDefinition) { + GraphQLFieldDefinition type = (GraphQLFieldDefinition) directiveContainer; + return type.getDeprecationReason(); + } else if (directiveContainer instanceof GraphQLEnumValueDefinition) { + GraphQLEnumValueDefinition type = (GraphQLEnumValueDefinition) directiveContainer; + return type.getDeprecationReason(); + } else if (directiveContainer instanceof GraphQLInputObjectField) { + GraphQLInputObjectField type = (GraphQLInputObjectField) directiveContainer; + return type.getDeprecationReason(); + } else if (directiveContainer instanceof GraphQLArgument) { + GraphQLArgument type = (GraphQLArgument) directiveContainer; + return type.getDeprecationReason(); + } else { + return Assert.assertShouldNeverHappen(); + } + } + + private String directiveDefinition(GraphQLDirective directive) { + StringBuilder sb = new StringBuilder(); + + StringWriter sw = new StringWriter(); + printComments(new PrintWriter(sw), directive, ""); + + sb.append(sw); + + sb.append("directive @").append(directive.getName()); + + Comparator comparator = getComparator(GraphQLDirective.class, GraphQLArgument.class); + + List args = directive.getArguments(); + args = args + .stream() + .filter(options.getIncludeSchemaElement()) + .sorted(comparator) + .collect(toList()); + + sb.append(argsString(GraphQLDirective.class, args)); + + if (directive.isRepeatable()) { + sb.append(" repeatable"); + } + + sb.append(" on "); + + String locations = directive.validLocations().stream().map(Enum::name).collect(Collectors.joining(" | ")); + sb.append(locations); + + return sb.toString(); + } + + @SuppressWarnings("unchecked") - private TypePrinter printer(Class clazz) { - TypePrinter typePrinter = printers.computeIfAbsent(clazz, k -> { + private SchemaElementPrinter printer(Class clazz) { + SchemaElementPrinter schemaElementPrinter = printers.get(clazz); + if (schemaElementPrinter == null) { Class superClazz = clazz.getSuperclass(); - TypePrinter result; - if (superClazz != Object.class) - result = printer(superClazz); - else - result = (out, type, visibility) -> out.println("Type not implemented : " + type); - return result; - }); - return (TypePrinter) typePrinter; + if (superClazz != Object.class) { + schemaElementPrinter = printer(superClazz); + } else { + schemaElementPrinter = (out, type, visibility) -> out.print("Type not implemented : " + type + "\n"); + } + printers.put(clazz, schemaElementPrinter); + } + return (SchemaElementPrinter) schemaElementPrinter; } + public String print(GraphQLType type) { StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter(sw); - printType(out, type, DEFAULT_FIELD_VISIBILITY); + printSchemaElement(out, type, DEFAULT_FIELD_VISIBILITY); - return sw.toString(); + return trimNewLineChars(sw.toString()); } - @SuppressWarnings("unchecked") - private void printType(PrintWriter out, List typesAsList, Class typeClazz, GraphqlFieldVisibility visibility) { - typesAsList.stream() - .filter(type -> typeClazz.isAssignableFrom(type.getClass())) - .forEach(type -> printType(out, type, visibility)); + public String print(List elements) { + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + + for (GraphQLSchemaElement element : elements) { + if (element instanceof GraphQLDirective) { + out.print(print(((GraphQLDirective) element))); + } else if (element instanceof GraphQLType) { + printSchemaElement(out, element, DEFAULT_FIELD_VISIBILITY); + } else { + Assert.assertShouldNeverHappen("How did we miss a %s", element.getClass()); + } + } + return trimNewLineChars(sw.toString()); } - private void printType(PrintWriter out, GraphQLType type, GraphqlFieldVisibility visibility) { - TypePrinter printer = printer(type.getClass()); - printer.print(out, type, visibility); + public String print(GraphQLDirective graphQLDirective) { + return directiveDefinition(graphQLDirective); } + private void printSchemaElement(PrintWriter out, GraphQLSchemaElement schemaElement, GraphqlFieldVisibility visibility) { + SchemaElementPrinter printer = printer(schemaElement.getClass()); + printer.print(out, schemaElement, visibility); + } - private void printComments(PrintWriter out, Object graphQLType, String prefix) { + private String printComments(Object graphQLType, String prefix) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + printComments(pw, graphQLType, prefix); + return sw.toString(); + } - AstDescriptionAndComments descriptionAndComments = getDescriptionAndComments(graphQLType); - if (descriptionAndComments == null) { - return; + private void printComments(PrintWriter out, Object graphQLType, String prefix) { + String descriptionText = getDescription(graphQLType); + if (!isNullOrEmpty(descriptionText)) { + List lines = Arrays.asList(descriptionText.split("\n")); + if (options.isDescriptionsAsHashComments()) { + printMultiLineHashDescription(out, prefix, lines); + } else if (!lines.isEmpty()) { + if (lines.size() > 1) { + printMultiLineDescription(out, prefix, lines); + } else { + printSingleLineDescription(out, prefix, lines.get(0)); + } + } } - Description astDescription = descriptionAndComments.descriptionAst; - if (astDescription != null) { - String quoteStr = "\""; - if (astDescription.isMultiLine()) { - quoteStr = "\"\"\""; + if (options.isIncludeAstDefinitionComments()) { + String commentsText = getAstDefinitionComments(graphQLType); + if (!isNullOrEmpty(commentsText)) { + List lines = Arrays.asList(commentsText.split("\n")); + if (!lines.isEmpty()) { + printMultiLineHashDescription(out, prefix, lines); + } } - out.write(prefix); - out.write(quoteStr); - out.write(astDescription.getContent()); - out.write(quoteStr); - out.write("\n"); - - return; } + } + + private void printMultiLineHashDescription(PrintWriter out, String prefix, List lines) { + lines.forEach(l -> out.printf("%s#%s\n", prefix, l)); + } - if (descriptionAndComments.comments != null) { - descriptionAndComments.comments.forEach(cmt -> { - out.write(prefix); - out.write("#"); - out.write(cmt.getContent()); - out.write("\n"); - }); + private void printMultiLineDescription(PrintWriter out, String prefix, List lines) { + out.printf("%s\"\"\"\n", prefix); + lines.forEach(l -> { + String escapedTripleQuotes = l.replaceAll("\"\"\"", "\\\\\"\"\""); + out.printf("%s%s\n", prefix, escapedTripleQuotes); + }); + out.printf("%s\"\"\"\n", prefix); + } + + private void printSingleLineDescription(PrintWriter out, String prefix, String s) { + // See: https://github.com/graphql/graphql-spec/issues/148 + String desc = escapeJsonString(s); + out.printf("%s\"%s\"\n", prefix, desc); + } + + private boolean hasAstDefinitionComments(Object commentHolder) { + String comments = getAstDefinitionComments(commentHolder); + return !isNullOrEmpty(comments); + } + + private String getAstDefinitionComments(Object commentHolder) { + if (commentHolder instanceof GraphQLObjectType) { + GraphQLObjectType type = (GraphQLObjectType) commentHolder; + return comments(ofNullable(type.getDefinition()).map(ObjectTypeDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLEnumType) { + GraphQLEnumType type = (GraphQLEnumType) commentHolder; + return comments(ofNullable(type.getDefinition()).map(EnumTypeDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLFieldDefinition) { + GraphQLFieldDefinition type = (GraphQLFieldDefinition) commentHolder; + return comments(ofNullable(type.getDefinition()).map(FieldDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLEnumValueDefinition) { + GraphQLEnumValueDefinition type = (GraphQLEnumValueDefinition) commentHolder; + return comments(ofNullable(type.getDefinition()).map(EnumValueDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLUnionType) { + GraphQLUnionType type = (GraphQLUnionType) commentHolder; + return comments(ofNullable(type.getDefinition()).map(UnionTypeDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLInputObjectType) { + GraphQLInputObjectType type = (GraphQLInputObjectType) commentHolder; + return comments(ofNullable(type.getDefinition()).map(InputObjectTypeDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLInputObjectField) { + GraphQLInputObjectField type = (GraphQLInputObjectField) commentHolder; + return comments(ofNullable(type.getDefinition()).map(InputValueDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLInterfaceType) { + GraphQLInterfaceType type = (GraphQLInterfaceType) commentHolder; + return comments(ofNullable(type.getDefinition()).map(InterfaceTypeDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLScalarType) { + GraphQLScalarType type = (GraphQLScalarType) commentHolder; + return comments(ofNullable(type.getDefinition()).map(ScalarTypeDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLArgument) { + GraphQLArgument type = (GraphQLArgument) commentHolder; + return comments(ofNullable(type.getDefinition()).map(InputValueDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLDirective) { + GraphQLDirective type = (GraphQLDirective) commentHolder; + return comments(ofNullable(type.getDefinition()).map(DirectiveDefinition::getComments).orElse(null)); + } else if (commentHolder instanceof GraphQLSchema) { + GraphQLSchema type = (GraphQLSchema) commentHolder; + return comments(ofNullable(type.getDefinition()).map(SchemaDefinition::getComments).orElse(null)); } else { - String runtimeDescription = descriptionAndComments.runtimeDescription; - if (!isNullOrEmpty(runtimeDescription)) { - Stream stream = Arrays.stream(runtimeDescription.split("\n")); - stream.map(s -> prefix + "#" + s + "\n").forEach(out::write); - } + return Assert.assertShouldNeverHappen(); } } - static class AstDescriptionAndComments { - String runtimeDescription; - Description descriptionAst; - List comments; - - public AstDescriptionAndComments(String runtimeDescription, Description descriptionAst, List comments) { - this.runtimeDescription = runtimeDescription; - this.descriptionAst = descriptionAst; - this.comments = comments; + private String comments(List comments) { + if (comments == null || comments.isEmpty()) { + return null; } + String s = comments.stream().map(c -> c.getContent()).collect(joining("\n", "", "\n")); + return s; + } + + private boolean hasDescription(Object descriptionHolder) { + String description = getDescription(descriptionHolder); + return !isNullOrEmpty(description); } - private AstDescriptionAndComments getDescriptionAndComments(Object descriptionHolder) { + private String getDescription(Object descriptionHolder) { if (descriptionHolder instanceof GraphQLObjectType) { GraphQLObjectType type = (GraphQLObjectType) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(ObjectTypeDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLEnumType) { GraphQLEnumType type = (GraphQLEnumType) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(EnumTypeDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLFieldDefinition) { GraphQLFieldDefinition type = (GraphQLFieldDefinition) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(FieldDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLEnumValueDefinition) { GraphQLEnumValueDefinition type = (GraphQLEnumValueDefinition) descriptionHolder; - return descriptionAndComments(type::getDescription, () -> null, () -> null); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(EnumValueDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLUnionType) { GraphQLUnionType type = (GraphQLUnionType) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(UnionTypeDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLInputObjectType) { GraphQLInputObjectType type = (GraphQLInputObjectType) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(InputObjectTypeDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLInputObjectField) { GraphQLInputObjectField type = (GraphQLInputObjectField) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(InputValueDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLInterfaceType) { GraphQLInterfaceType type = (GraphQLInterfaceType) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(InterfaceTypeDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLScalarType) { GraphQLScalarType type = (GraphQLScalarType) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(ScalarTypeDefinition::getDescription).orElse(null)); } else if (descriptionHolder instanceof GraphQLArgument) { GraphQLArgument type = (GraphQLArgument) descriptionHolder; - return descriptionAndComments(type::getDescription, type::getDefinition, () -> type.getDefinition().getDescription()); + return description(type.getDescription(), ofNullable(type.getDefinition()).map(InputValueDefinition::getDescription).orElse(null)); + } else if (descriptionHolder instanceof GraphQLDirective) { + GraphQLDirective type = (GraphQLDirective) descriptionHolder; + return description(type.getDescription(), null); + } else if (descriptionHolder instanceof GraphQLSchema) { + GraphQLSchema type = (GraphQLSchema) descriptionHolder; + return description(type.getDescription(), ofNullable(type.getDefinition()).map(SchemaDefinition::getDescription).orElse(null)); } else { return Assert.assertShouldNeverHappen(); } } - AstDescriptionAndComments descriptionAndComments(Supplier stringSupplier, Supplier nodeSupplier, Supplier descriptionSupplier) { - String runtimeDesc = stringSupplier.get(); - Node node = nodeSupplier.get(); - Description description = null; - List comments = null; - if (node != null) { - comments = node.getComments(); - description = descriptionSupplier.get(); + String description(String runtimeDescription, Description descriptionAst) { + // + // 95% of the time if the schema was built from SchemaGenerator then the runtime description is the only description + // So the other code here is a really defensive way to get the description + // + String descriptionText = runtimeDescription; + if (isNullOrEmpty(descriptionText)) { + if (descriptionAst != null) { + descriptionText = descriptionAst.getContent(); + } } - return new AstDescriptionAndComments(runtimeDesc, description, comments); + return descriptionText; + } + + private Comparator getComparator(Class parentType, Class elementType) { + GraphqlTypeComparatorEnvironment environment = GraphqlTypeComparatorEnvironment.newEnvironment() + .parentType(parentType) + .elementType(elementType) + .build(); + return options.comparatorRegistry.getComparator(environment); + } + private static String trimNewLineChars(String s) { + if (s.endsWith("\n\n")) { + s = s.substring(0, s.length() - 1); + } + return s; } private static boolean isNullOrEmpty(String s) { diff --git a/src/main/java/graphql/schema/idl/SchemaTypeChecker.java b/src/main/java/graphql/schema/idl/SchemaTypeChecker.java index 0f42d94231..3827f463f5 100644 --- a/src/main/java/graphql/schema/idl/SchemaTypeChecker.java +++ b/src/main/java/graphql/schema/idl/SchemaTypeChecker.java @@ -2,9 +2,9 @@ import graphql.GraphQLError; import graphql.Internal; +import graphql.collect.ImmutableKit; import graphql.introspection.Introspection; import graphql.language.Argument; -import graphql.language.AstPrinter; import graphql.language.Directive; import graphql.language.DirectiveDefinition; import graphql.language.EnumTypeDefinition; @@ -16,46 +16,32 @@ import graphql.language.Node; import graphql.language.ObjectTypeDefinition; import graphql.language.ObjectTypeExtensionDefinition; -import graphql.language.OperationTypeDefinition; -import graphql.language.SchemaDefinition; -import graphql.language.StringValue; import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeName; import graphql.language.UnionTypeDefinition; import graphql.schema.idl.errors.DirectiveIllegalLocationError; -import graphql.schema.idl.errors.InterfaceFieldArgumentRedefinitionError; -import graphql.schema.idl.errors.InterfaceFieldRedefinitionError; -import graphql.schema.idl.errors.InvalidDeprecationDirectiveError; -import graphql.schema.idl.errors.MissingInterfaceFieldArgumentsError; -import graphql.schema.idl.errors.MissingInterfaceFieldError; import graphql.schema.idl.errors.MissingInterfaceTypeError; import graphql.schema.idl.errors.MissingScalarImplementationError; import graphql.schema.idl.errors.MissingTypeError; import graphql.schema.idl.errors.MissingTypeResolverError; import graphql.schema.idl.errors.NonUniqueArgumentError; -import graphql.schema.idl.errors.NonUniqueDirectiveError; import graphql.schema.idl.errors.NonUniqueNameError; -import graphql.schema.idl.errors.OperationTypesMustBeObjects; -import graphql.schema.idl.errors.QueryOperationMissingError; -import graphql.schema.idl.errors.SchemaMissingError; import graphql.schema.idl.errors.SchemaProblem; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.function.BiFunction; -import java.util.function.BinaryOperator; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; + +import static graphql.introspection.Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION; +import static java.util.stream.Collectors.toList; /** * This helps pre check the state of the type system to ensure it can be made into an executable schema. @@ -65,7 +51,7 @@ @Internal public class SchemaTypeChecker { - public List checkTypeRegistry(TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring, boolean enforceSchemaDirectives) throws SchemaProblem { + public List checkTypeRegistry(ImmutableTypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) throws SchemaProblem { List errors = new ArrayList<>(); checkForMissingTypes(errors, typeRegistry); @@ -73,9 +59,13 @@ public List checkTypeRegistry(TypeDefinitionRegistry typeRegistry, typeExtensionsChecker.checkTypeExtensions(errors, typeRegistry); - checkInterfacesAreImplemented(errors, typeRegistry); + ImplementingTypesChecker implementingTypesChecker = new ImplementingTypesChecker(); + implementingTypesChecker.checkImplementingTypes(errors, typeRegistry); + + UnionTypesChecker unionTypesChecker = new UnionTypesChecker(); + unionTypesChecker.checkUnionType(errors, typeRegistry); - checkSchemaInvariants(errors, typeRegistry); + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry); checkScalarImplementationsArePresent(errors, typeRegistry, wiring); checkTypeResolversArePresent(errors, typeRegistry, wiring); @@ -85,49 +75,15 @@ public List checkTypeRegistry(TypeDefinitionRegistry typeRegistry, //check directive definitions before checking directive usages checkDirectiveDefinitions(typeRegistry, errors); - if (enforceSchemaDirectives) { - SchemaTypeDirectivesChecker directivesChecker = new SchemaTypeDirectivesChecker(typeRegistry, wiring); - directivesChecker.checkTypeDirectives(errors); - } + SchemaTypeDirectivesChecker directivesChecker = new SchemaTypeDirectivesChecker(typeRegistry, wiring); + directivesChecker.checkTypeDirectives(errors); return errors; } - private void checkSchemaInvariants(List errors, TypeDefinitionRegistry typeRegistry) { - /* - https://github.com/facebook/graphql/pull/90/files#diff-fe406b08746616e2f5f00909488cce66R1000 - - GraphQL type system definitions can omit the schema definition when the query - and mutation root types are named `Query` and `Mutation`, respectively. - */ - // schema - if (!typeRegistry.schemaDefinition().isPresent()) { - if (!typeRegistry.getType("Query").isPresent()) { - errors.add(new SchemaMissingError()); - } - } else { - SchemaDefinition schemaDefinition = typeRegistry.schemaDefinition().get(); - List operationTypeDefinitions = schemaDefinition.getOperationTypeDefinitions(); - - operationTypeDefinitions - .forEach(checkOperationTypesExist(typeRegistry, errors)); - - operationTypeDefinitions - .forEach(checkOperationTypesAreObjects(typeRegistry, errors)); - - // ensure we have a "query" one - Optional query = operationTypeDefinitions.stream().filter(op -> "query".equals(op.getName())).findFirst(); - if (!query.isPresent()) { - errors.add(new QueryOperationMissingError()); - } - - } - } - - private void checkForMissingTypes(List errors, TypeDefinitionRegistry typeRegistry) { // type extensions - List typeExtensions = typeRegistry.objectTypeExtensions().values().stream().flatMap(Collection::stream).collect(Collectors.toList()); + List typeExtensions = typeRegistry.objectTypeExtensions().values().stream().flatMap(Collection::stream).collect(toList()); typeExtensions.forEach(typeExtension -> { List implementsTypes = typeExtension.getImplements(); @@ -173,12 +129,8 @@ private void checkForMissingTypes(List errors, TypeDefinitionRegis List inputTypes = filterTo(typesMap, InputObjectTypeDefinition.class); inputTypes.forEach(inputType -> { List inputValueDefinitions = inputType.getInputValueDefinitions(); - List inputValueTypes = inputValueDefinitions.stream() - .map(InputValueDefinition::getType) - .collect(Collectors.toList()); - + List inputValueTypes = ImmutableKit.map(inputValueDefinitions, InputValueDefinition::getType); inputValueTypes.forEach(checkTypeExists("input value", typeRegistry, errors, inputType)); - }); } @@ -192,10 +144,7 @@ private void checkDirectiveDefinitions(TypeDefinitionRegistry typeRegistry, List checkNamedUniqueness(errors, arguments, InputValueDefinition::getName, (name, arg) -> new NonUniqueNameError(directiveDefinition, arg)); - List inputValueTypes = arguments.stream() - .map(InputValueDefinition::getType) - .collect(Collectors.toList()); - + List inputValueTypes = ImmutableKit.map(arguments, InputValueDefinition::getType); inputValueTypes.forEach( checkTypeExists(typeRegistry, errors, "directive definition", directiveDefinition, directiveDefinition.getName()) ); @@ -208,13 +157,13 @@ private void checkDirectiveDefinitions(TypeDefinitionRegistry typeRegistry, List errors.add(new DirectiveIllegalLocationError(directiveDefinition, locationName)); } }); - }); + }); } private void checkScalarImplementationsArePresent(List errors, TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) { typeRegistry.scalars().forEach((scalarName, scalarTypeDefinition) -> { WiringFactory wiringFactory = wiring.getWiringFactory(); - ScalarWiringEnvironment environment = new ScalarWiringEnvironment(typeRegistry, scalarTypeDefinition, Collections.emptyList()); + ScalarWiringEnvironment environment = new ScalarWiringEnvironment(typeRegistry, scalarTypeDefinition, ImmutableKit.emptyList()); if (!wiringFactory.providesScalar(environment) && !wiring.getScalars().containsKey(scalarName)) { errors.add(new MissingScalarImplementationError(scalarName)); } @@ -224,25 +173,26 @@ private void checkScalarImplementationsArePresent(List errors, Typ private void checkFieldsAreSensible(List errors, TypeDefinitionRegistry typeRegistry) { Map typesMap = typeRegistry.types(); + Map directiveDefinitionMap = typeRegistry.getDirectiveDefinitions(); + // objects List objectTypes = filterTo(typesMap, ObjectTypeDefinition.class); - objectTypes.forEach(objectType -> checkObjTypeFields(errors, objectType, objectType.getFieldDefinitions())); + objectTypes.forEach(objectType -> checkObjTypeFields(errors, objectType, objectType.getFieldDefinitions(), directiveDefinitionMap)); // interfaces List interfaceTypes = filterTo(typesMap, InterfaceTypeDefinition.class); - interfaceTypes.forEach(interfaceType -> checkInterfaceFields(errors, interfaceType, interfaceType.getFieldDefinitions())); + interfaceTypes.forEach(interfaceType -> checkInterfaceFields(errors, interfaceType, interfaceType.getFieldDefinitions(), directiveDefinitionMap)); // enum types List enumTypes = filterTo(typesMap, EnumTypeDefinition.class); - enumTypes.forEach(enumType -> checkEnumValues(errors, enumType, enumType.getEnumValueDefinitions())); + enumTypes.forEach(enumType -> checkEnumValues(errors, enumType, enumType.getEnumValueDefinitions(), directiveDefinitionMap)); // input types List inputTypes = filterTo(typesMap, InputObjectTypeDefinition.class); - inputTypes.forEach(inputType -> checkInputValues(errors, inputType, inputType.getInputValueDefinitions())); + inputTypes.forEach(inputType -> checkInputValues(errors, inputType, inputType.getInputValueDefinitions(), INPUT_FIELD_DEFINITION, directiveDefinitionMap)); } - - private void checkObjTypeFields(List errors, ObjectTypeDefinition typeDefinition, List fieldDefinitions) { + private void checkObjTypeFields(List errors, ObjectTypeDefinition typeDefinition, List fieldDefinitions, Map directiveDefinitionMap) { // field unique ness checkNamedUniqueness(errors, fieldDefinitions, FieldDefinition::getName, (name, fieldDef) -> new NonUniqueNameError(typeDefinition, fieldDef)); @@ -252,12 +202,7 @@ private void checkObjTypeFields(List errors, ObjectTypeDefinition (name, inputValueDefinition) -> new NonUniqueArgumentError(typeDefinition, fld, name))); // directive checks - fieldDefinitions.forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, - (directiveName, directive) -> new NonUniqueDirectiveError(typeDefinition, fld, directiveName))); - fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(typeDefinition, fld)); checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, (argumentName, argument) -> new NonUniqueArgumentError(typeDefinition, fld, argumentName)); @@ -265,7 +210,7 @@ private void checkObjTypeFields(List errors, ObjectTypeDefinition })); } - private void checkInterfaceFields(List errors, InterfaceTypeDefinition interfaceType, List fieldDefinitions) { + private void checkInterfaceFields(List errors, InterfaceTypeDefinition interfaceType, List fieldDefinitions, Map directiveDefinitionMap) { // field unique ness checkNamedUniqueness(errors, fieldDefinitions, FieldDefinition::getName, (name, fieldDef) -> new NonUniqueNameError(interfaceType, fieldDef)); @@ -275,20 +220,15 @@ private void checkInterfaceFields(List errors, InterfaceTypeDefini (name, inputValueDefinition) -> new NonUniqueArgumentError(interfaceType, fld, name))); // directive checks - fieldDefinitions.forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, - (directiveName, directive) -> new NonUniqueDirectiveError(interfaceType, fld, directiveName))); + fieldDefinitions.forEach(fieldDefinition -> { + List directives = fieldDefinition.getDirectives(); - fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(interfaceType, fld)); - - checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, - (argumentName, argument) -> new NonUniqueArgumentError(interfaceType, fld, argumentName)); - - })); + directives.forEach(directive -> checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, + (argumentName, argument) -> new NonUniqueArgumentError(interfaceType, fieldDefinition, argumentName))); + }); } - private void checkEnumValues(List errors, EnumTypeDefinition enumType, List enumValueDefinitions) { + private void checkEnumValues(List errors, EnumTypeDefinition enumType, List enumValueDefinitions, Map directiveDefinitionMap) { // enum unique ness checkNamedUniqueness(errors, enumValueDefinitions, EnumValueDefinition::getName, @@ -296,14 +236,7 @@ private void checkEnumValues(List errors, EnumTypeDefinition enumT // directive checks - enumValueDefinitions.forEach(enumValue -> { - BiFunction errorFunction = (directiveName, directive) -> new NonUniqueDirectiveError(enumType, enumValue, directiveName); - checkNamedUniqueness(errors, enumValue.getDirectives(), Directive::getName, errorFunction); - }); - enumValueDefinitions.forEach(enumValue -> enumValue.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(enumType, enumValue)); BiFunction errorFunction = (argumentName, argument) -> new NonUniqueArgumentError(enumType, enumValue, argumentName); checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, errorFunction); @@ -311,7 +244,7 @@ private void checkEnumValues(List errors, EnumTypeDefinition enumT })); } - private void checkInputValues(List errors, InputObjectTypeDefinition inputType, List inputValueDefinitions) { + private void checkInputValues(List errors, InputObjectTypeDefinition inputType, List inputValueDefinitions, Introspection.DirectiveLocation directiveLocation, Map directiveDefinitionMap) { // field unique ness checkNamedUniqueness(errors, inputValueDefinitions, InputValueDefinition::getName, @@ -324,43 +257,9 @@ private void checkInputValues(List errors, InputObjectTypeDefiniti // directive checks - inputValueDefinitions.forEach(inputValueDef -> checkNamedUniqueness(errors, inputValueDef.getDirectives(), Directive::getName, - (directiveName, directive) -> new NonUniqueDirectiveError(inputType, inputValueDef, directiveName))); - - inputValueDefinitions.forEach(inputValueDef -> inputValueDef.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(inputType, inputValueDef)); - - checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, - (argumentName, argument) -> new NonUniqueArgumentError(inputType, inputValueDef, argumentName)); - })); - } - - - /** - * A special check for the magic @deprecated directive - * - * @param errors the list of errors - * @param directive the directive to check - * @param errorSupplier the error supplier function - */ - static void checkDeprecatedDirective(List errors, Directive directive, Supplier errorSupplier) { - if ("deprecated".equals(directive.getName())) { - // it can have zero args - List arguments = directive.getArguments(); - if (arguments.size() == 0) { - return; - } - // but if has more than it must have 1 called "reason" of type StringValue - if (arguments.size() == 1) { - Argument arg = arguments.get(0); - if ("reason".equals(arg.getName()) && arg.getValue() instanceof StringValue) { - return; - } - } - // not valid - errors.add(errorSupplier.get()); - } + inputValueDefinitions.forEach(inputValueDef -> inputValueDef.getDirectives().forEach(directive -> + checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, + (argumentName, argument) -> new NonUniqueArgumentError(inputType, inputValueDef, argumentName)))); } /** @@ -373,7 +272,7 @@ static void checkDeprecatedDirective(List errors, Directive direct * @param errorFunction the function producing an error */ static void checkNamedUniqueness(List errors, List listOfNamedThings, Function namer, BiFunction errorFunction) { - Set names = new HashSet<>(); + Set names = new LinkedHashSet<>(); listOfNamedThings.forEach(thing -> { String name = namer.apply(thing); if (names.contains(name)) { @@ -386,7 +285,7 @@ static void checkNamedUniqueness(List private void checkTypeResolversArePresent(List errors, TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) { - Predicate noDynamicResolverForInterface = interaceTypeDef -> !wiring.getWiringFactory().providesTypeResolver(new InterfaceWiringEnvironment(typeRegistry, interaceTypeDef)); + Predicate noDynamicResolverForInterface = interfaceTypeDef -> !wiring.getWiringFactory().providesTypeResolver(new InterfaceWiringEnvironment(typeRegistry, interfaceTypeDef)); Predicate noDynamicResolverForUnion = unionTypeDef -> !wiring.getWiringFactory().providesTypeResolver(new UnionWiringEnvironment(typeRegistry, unionTypeDef)); Predicate noTypeResolver = typeDefinition -> !wiring.getTypeResolvers().containsKey(typeDefinition.getName()); @@ -409,16 +308,16 @@ private void checkTypeResolversArePresent(List errors, TypeDefinit } private void checkFieldTypesPresent(TypeDefinitionRegistry typeRegistry, List errors, TypeDefinition typeDefinition, List fields) { - List fieldTypes = fields.stream().map(FieldDefinition::getType).collect(Collectors.toList()); + List fieldTypes = ImmutableKit.map(fields, FieldDefinition::getType); fieldTypes.forEach(checkTypeExists("field", typeRegistry, errors, typeDefinition)); List fieldInputValues = fields.stream() .map(f -> f.getInputValueDefinitions() .stream() .map(InputValueDefinition::getType) - .collect(Collectors.toList())) + .collect(toList())) .flatMap(Collection::stream) - .collect(Collectors.toList()); + .collect(toList()); fieldInputValues.forEach(checkTypeExists("field input", typeRegistry, errors, typeDefinition)); } @@ -426,8 +325,9 @@ private void checkFieldTypesPresent(TypeDefinitionRegistry typeRegistry, List checkTypeExists(String typeOfType, TypeDefinitionRegistry typeRegistry, List errors, TypeDefinition typeDefinition) { return t -> { - TypeName unwrapped = TypeInfo.typeInfo(t).getTypeName(); - if (!typeRegistry.hasType(unwrapped)) { + String name = TypeInfo.typeName(t); + if (!typeRegistry.hasType(name)) { + TypeName unwrapped = TypeInfo.typeInfo(t).getTypeName(); errors.add(new MissingTypeError(typeOfType, typeDefinition, unwrapped)); } }; @@ -435,8 +335,9 @@ private Consumer checkTypeExists(String typeOfType, TypeDefinitionRegistry private Consumer checkTypeExists(TypeDefinitionRegistry typeRegistry, List errors, String typeOfType, Node element, String elementName) { return ivType -> { - TypeName unwrapped = TypeInfo.typeInfo(ivType).getTypeName(); - if (!typeRegistry.hasType(unwrapped)) { + String name = TypeInfo.typeName(ivType); + if (!typeRegistry.hasType(name)) { + TypeName unwrapped = TypeInfo.typeInfo(ivType).getTypeName(); errors.add(new MissingTypeError(typeOfType, element, elementName, unwrapped)); } }; @@ -446,116 +347,17 @@ private Consumer checkInterfaceTypeExists(TypeDefinitionRegistry t return t -> { TypeInfo typeInfo = TypeInfo.typeInfo(t); TypeName unwrapped = typeInfo.getTypeName(); - Optional type = typeRegistry.getType(unwrapped); - if (!type.isPresent()) { + TypeDefinition type = typeRegistry.getTypeOrNull(unwrapped); + if (type == null) { errors.add(new MissingInterfaceTypeError("interface", typeDefinition, unwrapped)); - } else if (!(type.get() instanceof InterfaceTypeDefinition)) { + } else if (!(type instanceof InterfaceTypeDefinition)) { errors.add(new MissingInterfaceTypeError("interface", typeDefinition, unwrapped)); } }; } - private void checkInterfacesAreImplemented(List errors, TypeDefinitionRegistry typeRegistry) { - Map typesMap = typeRegistry.types(); - - // objects - List objectTypes = filterTo(typesMap, ObjectTypeDefinition.class); - objectTypes.forEach(objectType -> { - List implementsTypes = objectType.getImplements(); - implementsTypes.forEach(checkInterfaceIsImplemented("object", typeRegistry, errors, objectType)); - }); - - Map> typeExtensions = typeRegistry.objectTypeExtensions(); - typeExtensions.values().forEach(extList -> extList.forEach(typeExtension -> { - List implementsTypes = typeExtension.getImplements(); - implementsTypes.forEach(checkInterfaceIsImplemented("extension", typeRegistry, errors, typeExtension)); - })); - } - - private Consumer checkInterfaceIsImplemented(String typeOfType, TypeDefinitionRegistry typeRegistry, List errors, ObjectTypeDefinition objectTypeDef) { - return t -> { - TypeInfo typeInfo = TypeInfo.typeInfo(t); - TypeName unwrapped = typeInfo.getTypeName(); - Optional type = typeRegistry.getType(unwrapped); - // previous checks handle the missing case and wrong type case - if (type.isPresent() && type.get() instanceof InterfaceTypeDefinition) { - InterfaceTypeDefinition interfaceTypeDef = (InterfaceTypeDefinition) type.get(); - - Map objectFields = objectTypeDef.getFieldDefinitions().stream() - .collect(Collectors.toMap( - FieldDefinition::getName, Function.identity(), mergeFirstValue() - )); - - interfaceTypeDef.getFieldDefinitions().forEach(interfaceFieldDef -> { - FieldDefinition objectFieldDef = objectFields.get(interfaceFieldDef.getName()); - if (objectFieldDef == null) { - errors.add(new MissingInterfaceFieldError(typeOfType, objectTypeDef, interfaceTypeDef, interfaceFieldDef)); - } else { - if (!typeRegistry.isSubTypeOf(objectFieldDef.getType(), interfaceFieldDef.getType())) { - String interfaceFieldType = AstPrinter.printAst(interfaceFieldDef.getType()); - String objectFieldType = AstPrinter.printAst(objectFieldDef.getType()); - errors.add(new InterfaceFieldRedefinitionError(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef, objectFieldType, interfaceFieldType)); - } - - // look at arguments - List objectArgs = objectFieldDef.getInputValueDefinitions(); - List interfaceArgs = interfaceFieldDef.getInputValueDefinitions(); - if (objectArgs.size() != interfaceArgs.size()) { - errors.add(new MissingInterfaceFieldArgumentsError(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef)); - } else { - checkArgumentConsistency(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef, interfaceFieldDef, errors); - } - } - }); - } - }; - } - - - private void checkArgumentConsistency(String typeOfType, ObjectTypeDefinition objectTypeDef, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef, FieldDefinition interfaceFieldDef, List errors) { - List objectArgs = objectFieldDef.getInputValueDefinitions(); - List interfaceArgs = interfaceFieldDef.getInputValueDefinitions(); - for (int i = 0; i < interfaceArgs.size(); i++) { - InputValueDefinition interfaceArg = interfaceArgs.get(i); - InputValueDefinition objectArg = objectArgs.get(i); - String interfaceArgStr = AstPrinter.printAst(interfaceArg); - String objectArgStr = AstPrinter.printAst(objectArg); - if (!interfaceArgStr.equals(objectArgStr)) { - errors.add(new InterfaceFieldArgumentRedefinitionError(typeOfType, objectTypeDef, interfaceTypeDef, objectFieldDef, objectArgStr, interfaceArgStr)); - } - } - } - - private Consumer checkOperationTypesExist(TypeDefinitionRegistry typeRegistry, List errors) { - return op -> { - TypeName unwrapped = TypeInfo.typeInfo(op.getType()).getTypeName(); - if (!typeRegistry.hasType(unwrapped)) { - errors.add(new MissingTypeError("operation", op, op.getName(), unwrapped)); - } - }; - } - - private Consumer checkOperationTypesAreObjects(TypeDefinitionRegistry typeRegistry, List errors) { - return op -> { - // make sure it is defined as a ObjectTypeDef - Type queryType = op.getType(); - Optional type = typeRegistry.getType(queryType); - type.ifPresent(typeDef -> { - if (!(typeDef instanceof ObjectTypeDefinition)) { - errors.add(new OperationTypesMustBeObjects(op)); - } - }); - }; - } - private List filterTo(Map types, Class clazz) { - return types.values().stream() - .filter(t -> clazz.equals(t.getClass())) - .map(clazz::cast) - .collect(Collectors.toList()); - } - - private BinaryOperator mergeFirstValue() { - return (v1, v2) -> v1; + return ImmutableKit.filterAndMap(types.values(), t -> clazz.equals(t.getClass()), + clazz::cast); } } diff --git a/src/main/java/graphql/schema/idl/SchemaTypeDirectivesChecker.java b/src/main/java/graphql/schema/idl/SchemaTypeDirectivesChecker.java index 550af4586d..4c3e373e37 100644 --- a/src/main/java/graphql/schema/idl/SchemaTypeDirectivesChecker.java +++ b/src/main/java/graphql/schema/idl/SchemaTypeDirectivesChecker.java @@ -12,20 +12,28 @@ import graphql.language.InputObjectTypeDefinition; import graphql.language.InputValueDefinition; import graphql.language.InterfaceTypeDefinition; +import graphql.language.NamedNode; import graphql.language.Node; import graphql.language.NonNullType; import graphql.language.ObjectTypeDefinition; +import graphql.language.ScalarTypeDefinition; +import graphql.language.SchemaDefinition; import graphql.language.TypeDefinition; +import graphql.language.TypeName; import graphql.language.UnionTypeDefinition; import graphql.schema.idl.errors.DirectiveIllegalLocationError; +import graphql.schema.idl.errors.DirectiveIllegalReferenceError; import graphql.schema.idl.errors.DirectiveMissingNonNullArgumentError; import graphql.schema.idl.errors.DirectiveUndeclaredError; import graphql.schema.idl.errors.DirectiveUnknownArgumentError; +import graphql.schema.idl.errors.IllegalNameError; +import graphql.schema.idl.errors.MissingTypeError; +import graphql.schema.idl.errors.NotAnInputTypeError; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION; import static graphql.introspection.Introspection.DirectiveLocation.ENUM; @@ -85,6 +93,13 @@ void checkTypeDirectives(List errors) { typeRegistry.scalars().values() .forEach(typeDef -> checkDirectives(SCALAR, errors, typeDef)); + List schemaDirectives = SchemaExtensionsChecker.gatherSchemaDirectives(typeRegistry, errors); + // we need to have a Node for error reporting so we make one in case there is not one + SchemaDefinition schemaDefinition = typeRegistry.schemaDefinition().orElse(SchemaDefinition.newSchemaDefinition().build()); + checkDirectives(DirectiveLocation.SCHEMA, errors, typeRegistry, schemaDefinition, "schema", schemaDirectives); + + Collection directiveDefinitions = typeRegistry.getDirectiveDefinitions().values(); + commonCheck(directiveDefinitions, errors); } @@ -121,7 +136,7 @@ private void checkFieldsDirectives(List errors, TypeDefinitionRegi private void checkDirectives(DirectiveLocation expectedLocation, List errors, TypeDefinitionRegistry typeRegistry, Node element, String elementName, List directives) { directives.forEach(directive -> { Optional directiveDefinition = typeRegistry.getDirectiveDefinition(directive.getName()); - if (!directiveDefinition.isPresent()) { + if (directiveDefinition.isEmpty()) { errors.add(new DirectiveUndeclaredError(element, elementName, directive.getName())); } else { if (!inRightLocation(expectedLocation, directiveDefinition.get())) { @@ -132,16 +147,16 @@ private void checkDirectives(DirectiveLocation expectedLocation, List names = directiveDefinition.getDirectiveLocations() - .stream().map(graphql.language.DirectiveLocation::getName) - .map(String::toUpperCase) - .collect(Collectors.toList()); - - return names.contains(expectedLocation.name().toUpperCase()); + private static boolean inRightLocation(DirectiveLocation expectedLocation, DirectiveDefinition directiveDefinition) { + for (graphql.language.DirectiveLocation location : directiveDefinition.getDirectiveLocations()) { + if (location.getName().equalsIgnoreCase(expectedLocation.name())) { + return true; + } + } + return false; } - private void checkDirectiveArguments(List errors, TypeDefinitionRegistry typeRegistry, Node element, String elementName, Directive directive, DirectiveDefinition directiveDefinition) { + private void checkDirectiveArguments(List errors, TypeDefinitionRegistry typeRegistry, Node element, String elementName, Directive directive, DirectiveDefinition directiveDefinition) { Map allowedArgs = getByName(directiveDefinition.getInputValueDefinitions(), (InputValueDefinition::getName), mergeFirst()); Map providedArgs = getByName(directive.getArguments(), (Argument::getName), mergeFirst()); directive.getArguments().forEach(argument -> { @@ -162,7 +177,51 @@ private void checkDirectiveArguments(List errors, TypeDefinitionRe }); } - private boolean isNoNullArgWithoutDefaultValue(InputValueDefinition definitionArgument) { + private static boolean isNoNullArgWithoutDefaultValue(InputValueDefinition definitionArgument) { return definitionArgument.getType() instanceof NonNullType && definitionArgument.getDefaultValue() == null; } -} + + private void commonCheck(Collection directiveDefinitions, List errors) { + directiveDefinitions.forEach(directiveDefinition -> { + assertTypeName(directiveDefinition, errors); + directiveDefinition.getInputValueDefinitions().forEach(inputValueDefinition -> { + assertTypeName(inputValueDefinition, errors); + assertExistAndIsInputType(inputValueDefinition, errors); + if (inputValueDefinition.hasDirective(directiveDefinition.getName())) { + errors.add(new DirectiveIllegalReferenceError(directiveDefinition, inputValueDefinition)); + } + }); + }); + } + + private static void assertTypeName(NamedNode node, List errors) { + if (node.getName().length() >= 2 && node.getName().startsWith("__")) { + errors.add((new IllegalNameError(node))); + } + } + + public void assertExistAndIsInputType(InputValueDefinition definition, List errors) { + TypeName namedType = TypeUtil.unwrapAll(definition.getType()); + + TypeDefinition unwrappedType = findTypeDefFromRegistry(namedType.getName(), typeRegistry); + + if (unwrappedType == null) { + errors.add(new MissingTypeError(namedType.getName(), definition, definition.getName())); + return; + } + + if (!(unwrappedType instanceof InputObjectTypeDefinition) + && !(unwrappedType instanceof EnumTypeDefinition) + && !(unwrappedType instanceof ScalarTypeDefinition)) { + errors.add(new NotAnInputTypeError(namedType, unwrappedType)); + } + } + + private static TypeDefinition findTypeDefFromRegistry(String typeName, TypeDefinitionRegistry typeRegistry) { + TypeDefinition typeDefinition = typeRegistry.getTypeOrNull(typeName); + if (typeDefinition != null) { + return typeDefinition; + } + return typeRegistry.scalars().get(typeName); + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/idl/SchemaTypeExtensionsChecker.java b/src/main/java/graphql/schema/idl/SchemaTypeExtensionsChecker.java index af0a80e2c4..c80bdcce01 100644 --- a/src/main/java/graphql/schema/idl/SchemaTypeExtensionsChecker.java +++ b/src/main/java/graphql/schema/idl/SchemaTypeExtensionsChecker.java @@ -3,8 +3,7 @@ import graphql.GraphQLError; import graphql.Internal; import graphql.language.Argument; -import graphql.language.AstPrinter; -import graphql.language.Directive; +import graphql.language.DirectiveDefinition; import graphql.language.EnumTypeDefinition; import graphql.language.EnumValueDefinition; import graphql.language.FieldDefinition; @@ -14,28 +13,24 @@ import graphql.language.InterfaceTypeDefinition; import graphql.language.ObjectTypeDefinition; import graphql.language.ScalarTypeDefinition; -import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeName; import graphql.language.UnionTypeDefinition; -import graphql.schema.idl.errors.InvalidDeprecationDirectiveError; import graphql.schema.idl.errors.MissingTypeError; import graphql.schema.idl.errors.NonUniqueArgumentError; -import graphql.schema.idl.errors.NonUniqueDirectiveError; import graphql.schema.idl.errors.NonUniqueNameError; -import graphql.schema.idl.errors.TypeExtensionDirectiveRedefinitionError; import graphql.schema.idl.errors.TypeExtensionEnumValueRedefinitionError; import graphql.schema.idl.errors.TypeExtensionFieldRedefinitionError; import graphql.schema.idl.errors.TypeExtensionMissingBaseTypeError; import graphql.util.FpKit; +import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; +import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; -import static graphql.schema.idl.SchemaTypeChecker.checkDeprecatedDirective; import static graphql.schema.idl.SchemaTypeChecker.checkNamedUniqueness; import static graphql.util.FpKit.mergeFirst; @@ -47,12 +42,13 @@ class SchemaTypeExtensionsChecker { void checkTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { - checkObjectTypeExtensions(errors, typeRegistry); - checkInterfaceTypeExtensions(errors, typeRegistry); - checkUnionTypeExtensions(errors, typeRegistry); - checkEnumTypeExtensions(errors, typeRegistry); - checkScalarTypeExtensions(errors, typeRegistry); - checkInputObjectTypeExtensions(errors, typeRegistry); + Map directiveDefinitionMap = typeRegistry.getDirectiveDefinitions(); + checkObjectTypeExtensions(errors, typeRegistry, directiveDefinitionMap); + checkInterfaceTypeExtensions(errors, typeRegistry, directiveDefinitionMap); + checkUnionTypeExtensions(errors, typeRegistry, directiveDefinitionMap); + checkEnumTypeExtensions(errors, typeRegistry, directiveDefinitionMap); + checkScalarTypeExtensions(errors, typeRegistry, directiveDefinitionMap); + checkInputObjectTypeExtensions(errors, typeRegistry, directiveDefinitionMap); } @@ -66,11 +62,10 @@ void checkTypeExtensions(List errors, TypeDefinitionRegistry typeR * Any interfaces provided must not be already implemented by the original Object type. * The resulting extended object type must be a super-set of all interfaces it implements. */ - private void checkObjectTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { + private void checkObjectTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry, Map directiveDefinitionMap) { typeRegistry.objectTypeExtensions() .forEach((name, extensions) -> { checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, ObjectTypeDefinition.class); - checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, ObjectTypeDefinition.class); extensions.forEach(extension -> { List fieldDefinitions = extension.getFieldDefinitions(); @@ -83,34 +78,28 @@ private void checkObjectTypeExtensions(List errors, TypeDefinition (namedField, inputValueDefinition) -> new NonUniqueArgumentError(extension, fld, name))); // directive checks - extension.getFieldDefinitions().forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, - (directiveName, directive) -> new NonUniqueDirectiveError(extension, fld, directiveName))); + fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> + checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, + (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName)))); - fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(extension, fld)); - - checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, - (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName)); - - })); - - // - // fields must be unique within a type extension - forEachBut(extension, extensions, - otherTypeExt -> checkForFieldRedefinition(errors, otherTypeExt, otherTypeExt.getFieldDefinitions(), fieldDefinitions)); - - // // then check for field re-defs from the base type - Optional baseTypeOpt = typeRegistry.getType(extension.getName(), ObjectTypeDefinition.class); - baseTypeOpt.ifPresent(baseTypeDef -> checkForFieldRedefinition(errors, extension, fieldDefinitions, baseTypeDef.getFieldDefinitions())); - + ObjectTypeDefinition baseTypeDef = typeRegistry.getTypeOrNull(extension.getName(), ObjectTypeDefinition.class); + if (baseTypeDef != null) { + checkForFieldRedefinition(errors, extension, fieldDefinitions, baseTypeDef.getFieldDefinitions()); + } }); + + // fields must be unique within a type extension + checkForTypeExtensionFieldUniqueness( + errors, + extensions, + ObjectTypeDefinition::getFieldDefinitions + ); + } ); } - /* * Interface type extensions have the potential to be invalid if incorrectly defined. * @@ -120,11 +109,10 @@ private void checkObjectTypeExtensions(List errors, TypeDefinition * Any Object type which implemented the original Interface type must also be a super-set of the fields of the Interface type extension (which may be due to Object type extension). * Any directives provided must not already apply to the original Interface type. */ - private void checkInterfaceTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { + private void checkInterfaceTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry, Map directiveDefinitionMap) { typeRegistry.interfaceTypeExtensions() .forEach((name, extensions) -> { checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, InterfaceTypeDefinition.class); - checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, InterfaceTypeDefinition.class); extensions.forEach(extension -> { List fieldDefinitions = extension.getFieldDefinitions(); @@ -137,28 +125,23 @@ private void checkInterfaceTypeExtensions(List errors, TypeDefinit (namedField, inputValueDefinition) -> new NonUniqueArgumentError(extension, fld, name))); // directive checks - extension.getFieldDefinitions().forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, - (directiveName, directive) -> new NonUniqueDirectiveError(extension, fld, directiveName))); - - fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(extension, fld)); - - checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, - (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName)); - - })); - - // - // fields must be unique within a type extension - forEachBut(extension, extensions, - otherTypeExt -> checkForFieldRedefinition(errors, otherTypeExt, otherTypeExt.getFieldDefinitions(), fieldDefinitions)); + fieldDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> + checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, + (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName)))); // // then check for field re-defs from the base type - Optional baseTypeOpt = typeRegistry.getType(extension.getName(), InterfaceTypeDefinition.class); - baseTypeOpt.ifPresent(baseTypeDef -> checkForFieldRedefinition(errors, extension, fieldDefinitions, baseTypeDef.getFieldDefinitions())); + InterfaceTypeDefinition baseTypeDef = typeRegistry.getTypeOrNull(extension.getName(), InterfaceTypeDefinition.class); + if (baseTypeDef != null) { + checkForFieldRedefinition(errors, extension, fieldDefinitions, baseTypeDef.getFieldDefinitions()); + } }); + // fields must be unique within a type extension + checkForTypeExtensionFieldUniqueness( + errors, + extensions, + InterfaceTypeDefinition::getFieldDefinitions + ); }); } @@ -171,11 +154,10 @@ private void checkInterfaceTypeExtensions(List errors, TypeDefinit * All member types of a Union type extension must not already be a member of the original Union type. * Any directives provided must not already apply to the original Union type. */ - private void checkUnionTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { + private void checkUnionTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry, Map directiveDefinitionMap) { typeRegistry.unionTypeExtensions() .forEach((name, extensions) -> { checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, UnionTypeDefinition.class); - checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, UnionTypeDefinition.class); extensions.forEach(extension -> { List memberTypes = extension.getMemberTypes().stream() @@ -186,8 +168,8 @@ private void checkUnionTypeExtensions(List errors, TypeDefinitionR memberTypes.forEach( memberType -> { - Optional unionTypeDefinition = typeRegistry.getType(memberType, ObjectTypeDefinition.class); - if (!unionTypeDefinition.isPresent()) { + ObjectTypeDefinition unionTypeDefinition = typeRegistry.getTypeOrNull(memberType, ObjectTypeDefinition.class); + if (unionTypeDefinition == null) { errors.add(new MissingTypeError("union member", extension, memberType)); } } @@ -204,11 +186,10 @@ private void checkUnionTypeExtensions(List errors, TypeDefinitionR * All values of an Enum type extension must not already be a value of the original Enum. * Any directives provided must not already apply to the original Enum type. */ - private void checkEnumTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { + private void checkEnumTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry, Map directiveDefinitionMap) { typeRegistry.enumTypeExtensions() .forEach((name, extensions) -> { checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, EnumTypeDefinition.class); - checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, EnumTypeDefinition.class); extensions.forEach(extension -> { // field unique ness @@ -216,19 +197,16 @@ private void checkEnumTypeExtensions(List errors, TypeDefinitionRe checkNamedUniqueness(errors, enumValueDefinitions, EnumValueDefinition::getName, (namedField, enumValue) -> new NonUniqueNameError(extension, enumValue)); - // - // enum values must be unique within a type extension - forEachBut(extension, extensions, - otherTypeExt -> checkForEnumValueRedefinition(errors, otherTypeExt, otherTypeExt.getEnumValueDefinitions(), enumValueDefinitions)); - // // then check for field re-defs from the base type - Optional baseTypeOpt = typeRegistry.getType(extension.getName(), EnumTypeDefinition.class); - baseTypeOpt.ifPresent(baseTypeDef -> checkForEnumValueRedefinition(errors, extension, enumValueDefinitions, baseTypeDef.getEnumValueDefinitions())); + EnumTypeDefinition baseTypeDef = typeRegistry.getTypeOrNull(extension.getName(), EnumTypeDefinition.class); + if (baseTypeDef != null) { + checkForEnumValueRedefinition(errors, extension, enumValueDefinitions, baseTypeDef.getEnumValueDefinitions()); + } }); - + checkForTypeExtensionEnumFieldUniqueness(errors, extensions, EnumTypeDefinition::getEnumValueDefinitions); }); } @@ -239,11 +217,10 @@ private void checkEnumTypeExtensions(List errors, TypeDefinitionRe * Any directives provided must not already apply to the original Scalar type. */ - private void checkScalarTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { + private void checkScalarTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry, Map directiveDefinitionMap) { typeRegistry.scalarTypeExtensions() .forEach((name, extensions) -> { checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, ScalarTypeDefinition.class); - checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, ScalarTypeDefinition.class); }); } @@ -256,11 +233,10 @@ private void checkScalarTypeExtensions(List errors, TypeDefinition * All fields of an Input Object type extension must not already be a field of the original Input Object. * Any directives provided must not already apply to the original Input Object type. */ - private void checkInputObjectTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry) { + private void checkInputObjectTypeExtensions(List errors, TypeDefinitionRegistry typeRegistry, Map directiveDefinitionMap) { typeRegistry.inputObjectTypeExtensions() .forEach((name, extensions) -> { checkTypeExtensionHasCorrespondingType(errors, typeRegistry, name, extensions, InputObjectTypeDefinition.class); - checkTypeExtensionDirectiveRedefinition(errors, typeRegistry, name, extensions, InputObjectTypeDefinition.class); // field redefinitions extensions.forEach(extension -> { List inputValueDefinitions = extension.getInputValueDefinitions(); @@ -269,69 +245,43 @@ private void checkInputObjectTypeExtensions(List errors, TypeDefin (namedField, fieldDef) -> new NonUniqueNameError(extension, fieldDef)); // directive checks - inputValueDefinitions.forEach(fld -> checkNamedUniqueness(errors, fld.getDirectives(), Directive::getName, - (directiveName, directive) -> new NonUniqueDirectiveError(extension, fld, directiveName))); - - inputValueDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> { - checkDeprecatedDirective(errors, directive, - () -> new InvalidDeprecationDirectiveError(extension, fld)); - - checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, - (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName)); - - })); - // - // fields must be unique within a type extension - forEachBut(extension, extensions, - otherTypeExt -> checkForInputValueRedefinition(errors, otherTypeExt, otherTypeExt.getInputValueDefinitions(), inputValueDefinitions)); - + inputValueDefinitions.forEach(fld -> fld.getDirectives().forEach(directive -> + checkNamedUniqueness(errors, directive.getArguments(), Argument::getName, + (argumentName, argument) -> new NonUniqueArgumentError(extension, fld, argumentName)))); // // then check for field re-defs from the base type - Optional baseTypeOpt = typeRegistry.getType(extension.getName(), InputObjectTypeDefinition.class); - baseTypeOpt.ifPresent(baseTypeDef -> checkForInputValueRedefinition(errors, extension, inputValueDefinitions, baseTypeDef.getInputValueDefinitions())); + InputObjectTypeDefinition baseTypeDef = typeRegistry.getTypeOrNull(extension.getName(), InputObjectTypeDefinition.class); + if (baseTypeDef != null) { + checkForInputValueRedefinition(errors, extension, inputValueDefinitions, baseTypeDef.getInputValueDefinitions()); + } }); + // + // fields must be unique within a type extension + checkForTypeExtensionInputFieldUniqueness( + errors, + extensions, + InputObjectTypeDefinition::getInputValueDefinitions + ); }); } - private void checkTypeExtensionHasCorrespondingType(List errors, TypeDefinitionRegistry typeRegistry, String name, List extTypeList, Class targetClass) { - TypeDefinition extensionDefinition = extTypeList.get(0); - Optional typeDefinition = typeRegistry.getType(TypeName.newTypeName().name(name).build(), targetClass); - if (!typeDefinition.isPresent()) { + private void checkTypeExtensionHasCorrespondingType(List errors, TypeDefinitionRegistry typeRegistry, String name, List> extTypeList, Class> targetClass) { + TypeDefinition extensionDefinition = extTypeList.get(0); + TypeDefinition typeDefinition = typeRegistry.getTypeOrNull(TypeName.newTypeName().name(name).build(), targetClass); + if (typeDefinition == null) { errors.add(new TypeExtensionMissingBaseTypeError(extensionDefinition)); } } - @SuppressWarnings("unchecked") - private void checkTypeExtensionDirectiveRedefinition(List errors, TypeDefinitionRegistry typeRegistry, String name, List extensions, Class targetClass) { - Optional typeDefinition = typeRegistry.getType(TypeName.newTypeName().name(name).build(), targetClass); - if (typeDefinition.isPresent() && typeDefinition.get().getClass().equals(targetClass)) { - List directives = typeDefinition.get().getDirectives(); - Map directiveMap = FpKit.getByName(directives, Directive::getName, mergeFirst()); - extensions.forEach(typeExt -> { - List extDirectives = typeExt.getDirectives(); - extDirectives.forEach(directive -> { - if (directiveMap.containsKey(directive.getName())) { - errors.add(new TypeExtensionDirectiveRedefinitionError(typeDefinition.get(), directive)); - } - }); - } - ); - } - } - - private void checkForFieldRedefinition(List errors, TypeDefinition typeDefinition, List fieldDefinitions, List referenceFieldDefinitions) { + private void checkForFieldRedefinition(List errors, TypeDefinition typeDefinition, List fieldDefinitions, List referenceFieldDefinitions) { Map referenceMap = FpKit.getByName(referenceFieldDefinitions, FieldDefinition::getName, mergeFirst()); fieldDefinitions.forEach(fld -> { - FieldDefinition reference = referenceMap.get(fld.getName()); if (referenceMap.containsKey(fld.getName())) { - // ok they have the same field but is it the same type - if (!isSameType(fld.getType(), reference.getType())) { - errors.add(new TypeExtensionFieldRedefinitionError(typeDefinition, fld)); - } + errors.add(new TypeExtensionFieldRedefinitionError(typeDefinition, fld)); } }); } @@ -340,17 +290,13 @@ private void checkForInputValueRedefinition(List errors, InputObje Map referenceMap = FpKit.getByName(referenceInputValues, InputValueDefinition::getName, mergeFirst()); inputValueDefinitions.forEach(fld -> { - InputValueDefinition reference = referenceMap.get(fld.getName()); if (referenceMap.containsKey(fld.getName())) { - // ok they have the same field but is it the same type - if (!isSameType(fld.getType(), reference.getType())) { - errors.add(new TypeExtensionFieldRedefinitionError(typeDefinition, fld)); - } + errors.add(new TypeExtensionFieldRedefinitionError(typeDefinition, fld)); } }); } - private void checkForEnumValueRedefinition(List errors, TypeDefinition typeDefinition, List enumValueDefinitions, List referenceEnumValueDefinitions) { + private void checkForEnumValueRedefinition(List errors, TypeDefinition typeDefinition, List enumValueDefinitions, List referenceEnumValueDefinitions) { Map referenceMap = FpKit.getByName(referenceEnumValueDefinitions, EnumValueDefinition::getName, mergeFirst()); @@ -361,20 +307,57 @@ private void checkForEnumValueRedefinition(List errors, TypeDefini }); } - private void forEachBut(T butThisOne, List list, Consumer consumer) { - for (T t : list) { - if (t == butThisOne) { - continue; + private > void checkForTypeExtensionFieldUniqueness( + List errors, + List extensions, + Function> getFieldDefinitionsFunc + ) { + Set seenFields = new HashSet<>(); + + for (T extension : extensions) { + for (FieldDefinition field : getFieldDefinitionsFunc.apply(extension)) { + if (seenFields.contains(field.getName())) { + errors.add(new TypeExtensionFieldRedefinitionError(extension, field)); + } else { + seenFields.add(field.getName()); + } } - consumer.accept(t); } } - - private boolean isSameType(Type type1, Type type2) { - String s1 = AstPrinter.printAst(type1); - String s2 = AstPrinter.printAst(type2); - return s1.equals(s2); + private > void checkForTypeExtensionInputFieldUniqueness( + List errors, + List extensions, + Function> getFieldDefinitionsFunc + ) { + Set seenFields = new HashSet<>(); + + for (T extension : extensions) { + for (InputValueDefinition field : getFieldDefinitionsFunc.apply(extension)) { + if (seenFields.contains(field.getName())) { + errors.add(new TypeExtensionFieldRedefinitionError(extension, field)); + } else { + seenFields.add(field.getName()); + } + } + } } + private > void checkForTypeExtensionEnumFieldUniqueness( + List errors, + List extensions, + Function> getFieldDefinitionsFunc + ) { + Set seenFields = new HashSet<>(); + + for (T extension : extensions) { + for (EnumValueDefinition field : getFieldDefinitionsFunc.apply(extension)) { + if (seenFields.contains(field.getName())) { + errors.add(new TypeExtensionEnumValueRedefinitionError(extension, field)); + } else { + seenFields.add(field.getName()); + } + } + } + } } diff --git a/src/main/java/graphql/schema/idl/TypeDefinitionRegistry.java b/src/main/java/graphql/schema/idl/TypeDefinitionRegistry.java index 402b9fe224..37bd404e4e 100644 --- a/src/main/java/graphql/schema/idl/TypeDefinitionRegistry.java +++ b/src/main/java/graphql/schema/idl/TypeDefinitionRegistry.java @@ -3,17 +3,21 @@ import graphql.Assert; import graphql.GraphQLError; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.language.DirectiveDefinition; import graphql.language.EnumTypeExtensionDefinition; +import graphql.language.ImplementingTypeDefinition; import graphql.language.InputObjectTypeExtensionDefinition; import graphql.language.InterfaceTypeDefinition; import graphql.language.InterfaceTypeExtensionDefinition; import graphql.language.ObjectTypeDefinition; import graphql.language.ObjectTypeExtensionDefinition; +import graphql.language.OperationTypeDefinition; import graphql.language.SDLDefinition; import graphql.language.ScalarTypeDefinition; import graphql.language.ScalarTypeExtensionDefinition; import graphql.language.SchemaDefinition; +import graphql.language.SchemaExtensionDefinition; import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeName; @@ -24,36 +28,105 @@ import graphql.schema.idl.errors.SchemaRedefinitionError; import graphql.schema.idl.errors.TypeRedefinitionError; import graphql.util.FpKit; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.function.Function; -import java.util.stream.Collectors; import static graphql.Assert.assertNotNull; +import static graphql.schema.idl.SchemaExtensionsChecker.defineOperationDefs; +import static graphql.schema.idl.SchemaExtensionsChecker.gatherOperationDefs; +import static graphql.schema.idl.TypeInfo.typeName; import static java.util.Optional.ofNullable; /** * A {@link TypeDefinitionRegistry} contains the set of type definitions that come from compiling * a graphql schema definition file via {@link SchemaParser#parse(String)} */ +@SuppressWarnings("rawtypes") @PublicApi -public class TypeDefinitionRegistry { +@NullMarked +public class TypeDefinitionRegistry implements Serializable { + + protected final Map> objectTypeExtensions; + protected final Map> interfaceTypeExtensions; + protected final Map> unionTypeExtensions; + protected final Map> enumTypeExtensions; + protected final Map> scalarTypeExtensions; + protected final Map> inputObjectTypeExtensions; + + protected final Map types; + protected final Map scalarTypes; + protected final Map directiveDefinitions; + protected @Nullable SchemaDefinition schema; + protected final List schemaExtensionDefinitions; + protected final SchemaParseOrder schemaParseOrder; + + public TypeDefinitionRegistry() { + objectTypeExtensions = new LinkedHashMap<>(); + interfaceTypeExtensions = new LinkedHashMap<>(); + unionTypeExtensions = new LinkedHashMap<>(); + enumTypeExtensions = new LinkedHashMap<>(); + scalarTypeExtensions = new LinkedHashMap<>(); + inputObjectTypeExtensions = new LinkedHashMap<>(); + types = new LinkedHashMap<>(); + scalarTypes = new LinkedHashMap<>(); + directiveDefinitions = new LinkedHashMap<>(); + schemaExtensionDefinitions = new ArrayList<>(); + schemaParseOrder = new SchemaParseOrder(); + } + + protected TypeDefinitionRegistry(Map> objectTypeExtensions, + Map> interfaceTypeExtensions, + Map> unionTypeExtensions, + Map> enumTypeExtensions, + Map> scalarTypeExtensions, + Map> inputObjectTypeExtensions, + Map types, + Map scalarTypes, + Map directiveDefinitions, + List schemaExtensionDefinitions, + @Nullable SchemaDefinition schema, + SchemaParseOrder schemaParseOrder) { + this.objectTypeExtensions = objectTypeExtensions; + this.interfaceTypeExtensions = interfaceTypeExtensions; + this.unionTypeExtensions = unionTypeExtensions; + this.enumTypeExtensions = enumTypeExtensions; + this.scalarTypeExtensions = scalarTypeExtensions; + this.inputObjectTypeExtensions = inputObjectTypeExtensions; + this.types = types; + this.scalarTypes = scalarTypes; + this.directiveDefinitions = directiveDefinitions; + this.schemaExtensionDefinitions = schemaExtensionDefinitions; + this.schema = schema; + this.schemaParseOrder = schemaParseOrder; + } - private final Map> objectTypeExtensions = new LinkedHashMap<>(); - private final Map> interfaceTypeExtensions = new LinkedHashMap<>(); - private final Map> unionTypeExtensions = new LinkedHashMap<>(); - private final Map> enumTypeExtensions = new LinkedHashMap<>(); - private final Map> scalarTypeExtensions = new LinkedHashMap<>(); - private final Map> inputObjectTypeExtensions = new LinkedHashMap<>(); + /** + * @return an immutable view of this {@link TypeDefinitionRegistry} that is more performant + * when in read only mode. + */ + public ImmutableTypeDefinitionRegistry readOnly() { + if (this instanceof ImmutableTypeDefinitionRegistry) { + return (ImmutableTypeDefinitionRegistry) this; + } + return new ImmutableTypeDefinitionRegistry(this); + } - private final Map types = new LinkedHashMap<>(); - private final Map scalarTypes = new LinkedHashMap<>(); - private final Map directiveDefinitions = new LinkedHashMap<>(); - private SchemaDefinition schema; + /** + * @return the order in which {@link SDLDefinition}s were parsed + */ + public SchemaParseOrder getParseOrder() { + return schemaParseOrder; + } /** * This will merge these type registries together and return this one @@ -82,9 +155,7 @@ public TypeDefinitionRegistry merge(TypeDefinitionRegistry typeRegistry) throws Map tempScalarTypes = new LinkedHashMap<>(); typeRegistry.scalarTypes.values().forEach(newEntry -> define(this.scalarTypes, tempScalarTypes, newEntry).ifPresent(errors::add)); - if (typeRegistry.schema != null && this.schema != null) { - errors.add(new SchemaRedefinitionError(this.schema, typeRegistry.schema)); - } + checkMergeSchemaDefs(typeRegistry, errors); if (!errors.isEmpty()) { throw new SchemaProblem(errors); @@ -93,7 +164,10 @@ public TypeDefinitionRegistry merge(TypeDefinitionRegistry typeRegistry) throws if (this.schema == null) { // ensure schema is not overwritten by merge this.schema = typeRegistry.schema; + schemaParseOrder.addDefinition(typeRegistry.schema); } + this.schemaExtensionDefinitions.addAll(typeRegistry.schemaExtensionDefinitions); + typeRegistry.schemaExtensionDefinitions.forEach(schemaParseOrder::addDefinition); // ok commit to the merge this.types.putAll(tempTypes); @@ -135,6 +209,46 @@ public TypeDefinitionRegistry merge(TypeDefinitionRegistry typeRegistry) throws return this; } + private Map checkMergeSchemaDefs(TypeDefinitionRegistry toBeMergedTypeRegistry, List errors) { + if (toBeMergedTypeRegistry.schema != null && this.schema != null) { + errors.add(new SchemaRedefinitionError(this.schema, toBeMergedTypeRegistry.schema)); + } + + Map tempOperationDefs = gatherOperationDefs(errors, this.schema, this.schemaExtensionDefinitions); + Map mergedOperationDefs = gatherOperationDefs(errors, toBeMergedTypeRegistry.schema, toBeMergedTypeRegistry.schemaExtensionDefinitions); + + defineOperationDefs(errors, mergedOperationDefs.values(), tempOperationDefs); + return tempOperationDefs; + } + + + private Optional checkAddOperationDefs() { + List errors = new ArrayList<>(); + gatherOperationDefs(errors, this.schema, this.schemaExtensionDefinitions); + if (!errors.isEmpty()) { + return Optional.of(errors.get(0)); + } + return Optional.empty(); + } + + + /** + * Adds a a collections of definitions to the registry + * + * @param definitions the definitions to add + * + * @return an optional error for the first problem, typically type redefinition + */ + public Optional addAll(Collection definitions) { + for (SDLDefinition definition : definitions) { + Optional error = add(definition); + if (error.isPresent()) { + return error; + } + } + return Optional.empty(); + } + /** * Adds a definition to the registry * @@ -162,8 +276,13 @@ public Optional add(SDLDefinition definition) { } else if (definition instanceof InputObjectTypeExtensionDefinition) { InputObjectTypeExtensionDefinition newEntry = (InputObjectTypeExtensionDefinition) definition; return defineExt(inputObjectTypeExtensions, newEntry, InputObjectTypeExtensionDefinition::getName); - // - // normal + } else if (definition instanceof SchemaExtensionDefinition) { + schemaExtensionDefinitions.add((SchemaExtensionDefinition) definition); + schemaParseOrder.addDefinition(definition); + Optional error = checkAddOperationDefs(); + if (error.isPresent()) { + return error; + } } else if (definition instanceof ScalarTypeDefinition) { ScalarTypeDefinition newEntry = (ScalarTypeDefinition) definition; return define(scalarTypes, scalarTypes, newEntry); @@ -179,6 +298,11 @@ public Optional add(SDLDefinition definition) { return Optional.of(new SchemaRedefinitionError(this.schema, newSchema)); } else { schema = newSchema; + schemaParseOrder.addDefinition(newSchema); + } + Optional error = checkAddOperationDefs(); + if (error.isPresent()) { + return error; } } else { return Assert.assertShouldNeverHappen(); @@ -186,8 +310,14 @@ public Optional add(SDLDefinition definition) { return Optional.empty(); } + /** + * Removes a {@code SDLDefinition} from the definition list. + * + * @param definition the definition to remove + */ public void remove(SDLDefinition definition) { - assertNotNull("definition to remove can't be null"); + assertNotNull(definition, "definition to remove can't be null"); + schemaParseOrder.removeDefinition(definition); if (definition instanceof ObjectTypeExtensionDefinition) { removeFromList(objectTypeExtensions, (TypeDefinition) definition); } else if (definition instanceof InterfaceTypeExtensionDefinition) { @@ -206,6 +336,8 @@ public void remove(SDLDefinition definition) { types.remove(((TypeDefinition) definition).getName()); } else if (definition instanceof DirectiveDefinition) { directiveDefinitions.remove(((DirectiveDefinition) definition).getName()); + } else if (definition instanceof SchemaExtensionDefinition) { + schemaExtensionDefinitions.remove(definition); } else if (definition instanceof SchemaDefinition) { schema = null; } else { @@ -214,11 +346,59 @@ public void remove(SDLDefinition definition) { } private void removeFromList(Map source, TypeDefinition value) { + //noinspection unchecked List list = (List) source.get(value.getName()); if (list == null) { return; } list.remove(value); + if (list.isEmpty()) { + source.remove(value.getName()); + } + } + + /** + * Removes a {@code SDLDefinition} from a map. + * + * @param key the key to remove + * @param definition the definition to remove + */ + public void remove(String key, SDLDefinition definition) { + assertNotNull(definition, "definition to remove can't be null"); + assertNotNull(key, "key to remove can't be null"); + schemaParseOrder.removeDefinition(definition); + if (definition instanceof ObjectTypeExtensionDefinition) { + removeFromMap(objectTypeExtensions, key); + } else if (definition instanceof InterfaceTypeExtensionDefinition) { + removeFromMap(interfaceTypeExtensions, key); + } else if (definition instanceof UnionTypeExtensionDefinition) { + removeFromMap(unionTypeExtensions, key); + } else if (definition instanceof EnumTypeExtensionDefinition) { + removeFromMap(enumTypeExtensions, key); + } else if (definition instanceof ScalarTypeExtensionDefinition) { + removeFromMap(scalarTypeExtensions, key); + } else if (definition instanceof InputObjectTypeExtensionDefinition) { + removeFromMap(inputObjectTypeExtensions, key); + } else if (definition instanceof ScalarTypeDefinition) { + removeFromMap(scalarTypes, key); + } else if (definition instanceof TypeDefinition) { + removeFromMap(types, key); + } else if (definition instanceof DirectiveDefinition) { + removeFromMap(directiveDefinitions, key); + } else if (definition instanceof SchemaExtensionDefinition) { + schemaExtensionDefinitions.remove(definition); + } else if (definition instanceof SchemaDefinition) { + schema = null; + } else { + Assert.assertShouldNeverHappen(); + } + } + + private void removeFromMap(Map source, String key) { + if (source == null) { + return; + } + source.remove(key); } @@ -230,6 +410,7 @@ private Optional define(Map return Optional.of(handleReDefinition(olderEntry, newEntry)); } else { target.put(name, newEntry); + schemaParseOrder.addDefinition(newEntry); } return Optional.empty(); } @@ -242,13 +423,15 @@ private Optional define(Map Optional defineExt(Map> typeExtensions, T newEntry, Function namerFunc) { + private Optional defineExt(Map> typeExtensions, T newEntry, Function namerFunc) { List currentList = typeExtensions.computeIfAbsent(namerFunc.apply(newEntry), k -> new ArrayList<>()); currentList.add(newEntry); + schemaParseOrder.addDefinition(newEntry); return Optional.empty(); } @@ -257,7 +440,7 @@ public Map types() { } public Map scalars() { - LinkedHashMap scalars = new LinkedHashMap<>(ScalarInfo.STANDARD_SCALAR_DEFINITIONS); + LinkedHashMap scalars = new LinkedHashMap<>(ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS); scalars.putAll(scalarTypes); return scalars; } @@ -290,6 +473,10 @@ public Optional schemaDefinition() { return ofNullable(schema); } + public List getSchemaExtensionDefinitions() { + return new ArrayList<>(schemaExtensionDefinitions); + } + private GraphQLError handleReDefinition(TypeDefinition oldEntry, TypeDefinition newEntry) { return new TypeRedefinitionError(newEntry, oldEntry); } @@ -306,43 +493,149 @@ public Map getDirectiveDefinitions() { return new LinkedHashMap<>(directiveDefinitions); } + /** + * Returns true if the registry has a type of the specified {@link TypeName} + * + * @param typeName the type name to check + * + * @return true if the registry has a type by that type name + */ public boolean hasType(TypeName typeName) { String name = typeName.getName(); - return types.containsKey(name) || ScalarInfo.STANDARD_SCALAR_DEFINITIONS.containsKey(name) || scalarTypes.containsKey(name) || objectTypeExtensions.containsKey(name); + return hasType(name); } + /** + * Returns true if the registry has a type of the specified name + * + * @param name the name to check + * + * @return true if the registry has a type by that name + */ + public boolean hasType(String name) { + return types.containsKey(name) || ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS.containsKey(name) || scalarTypes.containsKey(name) || objectTypeExtensions.containsKey(name); + } + + /** + * Returns an optional {@link TypeDefinition} of the specified type or {@link Optional#empty()} + * + * @param type the type to check + * + * @return an optional {@link TypeDefinition} or empty if it's not found + * + * @deprecated use the {@link #getTypeOrNull(Type)} variants instead since they avoid the allocation of an + * optional object + */ + @Deprecated(since = "2025-07-7") public Optional getType(Type type) { - String typeName = TypeInfo.typeInfo(type).getName(); - return getType(typeName); + return Optional.ofNullable(getTypeOrNull(type)); } + /** + * Returns an optional {@link TypeDefinition} of the specified type with the specified class or {@link Optional#empty()} + * + * @param type the type to check + * @param ofType the class of {@link TypeDefinition} + * + * @return an optional {@link TypeDefinition} or empty if it's not found + * + * @deprecated use the {@link #getTypeOrNull(Type)} variants instead since they avoid the allocation of an + * optional object + */ + @Deprecated(since = "2025-07-7") public Optional getType(Type type, Class ofType) { - String typeName = TypeInfo.typeInfo(type).getName(); - return getType(typeName, ofType); + return Optional.ofNullable(getTypeOrNull(typeName(type), ofType)); } + /** + * Returns an optional {@link TypeDefinition} of the specified type name or {@link Optional#empty()} + * + * @param typeName the type to check + * + * @return an optional {@link TypeDefinition} or empty if it's not found + * + * @deprecated use the {@link #getTypeOrNull(Type)} variants instead since they avoid the allocation of an + * optional object + */ + @Deprecated(since = "2025-07-7") public Optional getType(String typeName) { + return Optional.ofNullable(getTypeOrNull(typeName)); + } + + /** + * Returns an optional {@link TypeDefinition} of the specified type name with the specified class or {@link Optional#empty()} + * + * @param typeName the type to check + * @param ofType the class of {@link TypeDefinition} + * + * @deprecated use the {@link #getTypeOrNull(Type)} variants instead since they avoid the allocation of an + * optional object + */ + @Deprecated(since = "2025-07-7") + public Optional getType(String typeName, Class ofType) { + return Optional.ofNullable(getTypeOrNull(typeName, ofType)); + } + + /** + * Returns a {@link TypeDefinition} of the specified type or null + * + * @param type the type to check + * + * @return a {@link TypeDefinition} or null if it's not found + */ + @Nullable + public TypeDefinition getTypeOrNull(Type type) { + return getTypeOrNull(typeName(type)); + } + + /** + * Returns a {@link TypeDefinition} of the specified type with the specified class or null + * + * @param type the type to check + * @param ofType the class of {@link TypeDefinition} + * + * @return a {@link TypeDefinition} or null if it's not found + */ + @Nullable + public T getTypeOrNull(Type type, Class ofType) { + return getTypeOrNull(typeName(type), ofType); + } + + /** + * Returns a {@link TypeDefinition} of the specified name or null + * + * @param typeName the type name to check + * + * @return a {@link TypeDefinition} or null if it's not found + */ + @Nullable + public TypeDefinition getTypeOrNull(String typeName) { TypeDefinition typeDefinition = types.get(typeName); if (typeDefinition != null) { - return Optional.of(typeDefinition); + return typeDefinition; } typeDefinition = scalars().get(typeName); - if (typeDefinition != null) { - return Optional.of(typeDefinition); - } - return Optional.empty(); + return typeDefinition; } - public Optional getType(String typeName, Class ofType) { - Optional type = getType(typeName); - if (type.isPresent()) { - TypeDefinition typeDefinition = type.get(); - if (typeDefinition.getClass().equals(ofType)) { + /** + * Returns a {@link TypeDefinition} of the specified name and class or null + * + * @param typeName the type name to check + * @param ofType the class of {@link TypeDefinition} + * + * @return a {@link TypeDefinition} or null if it's not found + */ + @Nullable + public T getTypeOrNull(String typeName, Class ofType) { + TypeDefinition type = getTypeOrNull(typeName); + if (type != null) { + if (type.getClass().equals(ofType)) { //noinspection unchecked - return Optional.of((T) typeDefinition); + return (T) type; } } - return Optional.empty(); + return null; } /** @@ -353,10 +646,24 @@ public Optional getType(String typeName, Class * @return true if its abstract */ public boolean isInterfaceOrUnion(Type type) { - Optional typeDefinition = getType(type); - if (typeDefinition.isPresent()) { - TypeDefinition definition = typeDefinition.get(); - return definition instanceof UnionTypeDefinition || definition instanceof InterfaceTypeDefinition; + TypeDefinition typeDefinition = getTypeOrNull(type); + if (typeDefinition != null) { + return typeDefinition instanceof UnionTypeDefinition || typeDefinition instanceof InterfaceTypeDefinition; + } + return false; + } + + /** + * Returns true if the specified type exists in the registry and is an object type or interface + * + * @param type the type to check + * + * @return true if its an object type or interface + */ + public boolean isObjectTypeOrInterface(Type type) { + TypeDefinition typeDefinition = getTypeOrNull(type); + if (typeDefinition != null) { + return typeDefinition instanceof ObjectTypeDefinition || typeDefinition instanceof InterfaceTypeDefinition; } return false; } @@ -369,7 +676,7 @@ public boolean isInterfaceOrUnion(Type type) { * @return true if its an object type */ public boolean isObjectType(Type type) { - return getType(type, ObjectTypeDefinition.class).isPresent(); + return getTypeOrNull(type, ObjectTypeDefinition.class) != null; } /** @@ -381,10 +688,10 @@ public boolean isObjectType(Type type) { * @return a list of types of the target class */ public List getTypes(Class targetClass) { - return types.values().stream() - .filter(targetClass::isInstance) - .map(targetClass::cast) - .collect(Collectors.toList()); + return ImmutableKit.filterAndMap(types.values(), + targetClass::isInstance, + targetClass::cast + ); } /** @@ -401,53 +708,71 @@ public Map getTypesMap(Class targetClas } /** - * Returns the list of object types that implement the given interface type + * Returns the list of object and interface types that implement the given interface type + * + * @param targetInterface the target to search for + * + * @return the list of object types that implement the given interface type + * + * @see TypeDefinitionRegistry#getImplementationsOf(InterfaceTypeDefinition) + */ + public List getAllImplementationsOf(InterfaceTypeDefinition targetInterface) { + return ImmutableKit.filter( + getTypes(ImplementingTypeDefinition.class), + implementingTypeDefinition -> { + List> implementsList = implementingTypeDefinition.getImplements(); + for (Type iFace : implementsList) { + InterfaceTypeDefinition interfaceTypeDef = getTypeOrNull(iFace, InterfaceTypeDefinition.class); + if (interfaceTypeDef != null) { + if (interfaceTypeDef.getName().equals(targetInterface.getName())) { + return true; + } + } + } + return false; + }); + } + + /** + * Returns the list of object interface types that implement the given interface type * * @param targetInterface the target to search for * * @return the list of object types that implement the given interface type + * + * @see TypeDefinitionRegistry#getAllImplementationsOf(InterfaceTypeDefinition) */ public List getImplementationsOf(InterfaceTypeDefinition targetInterface) { - List objectTypeDefinitions = getTypes(ObjectTypeDefinition.class); - return objectTypeDefinitions.stream().filter(objectTypeDefinition -> { - List implementsList = objectTypeDefinition.getImplements(); - for (Type iFace : implementsList) { - Optional interfaceTypeDef = getType(iFace, InterfaceTypeDefinition.class); - if (interfaceTypeDef.isPresent()) { - boolean equals = interfaceTypeDef.get().getName().equals(targetInterface.getName()); - if (equals) { - return true; - } - } - } - return false; - }).collect(Collectors.toList()); + return ImmutableKit.filterAndMap( + getAllImplementationsOf(targetInterface), + typeDefinition -> typeDefinition instanceof ObjectTypeDefinition, + typeDefinition -> (ObjectTypeDefinition) typeDefinition + ); } /** - * Returns true of the abstract type is in implemented by the object type + * Returns true of the abstract type is in implemented by the object type or interface * - * @param abstractType the abstract type to check (interface or union) - * @param possibleObjectType the object type to check + * @param abstractType the abstract type to check (interface or union) + * @param possibleType the object type or interface to check * - * @return true if the object type implements the abstract type + * @return true if the object type or interface implements the abstract type */ - @SuppressWarnings("ConstantConditions") - public boolean isPossibleType(Type abstractType, Type possibleObjectType) { + public boolean isPossibleType(Type abstractType, Type possibleType) { if (!isInterfaceOrUnion(abstractType)) { return false; } - if (!isObjectType(possibleObjectType)) { + if (!isObjectTypeOrInterface(possibleType)) { return false; } - ObjectTypeDefinition targetObjectTypeDef = getType(possibleObjectType, ObjectTypeDefinition.class).get(); - TypeDefinition abstractTypeDef = getType(abstractType).get(); + TypeDefinition targetObjectTypeDef = Objects.requireNonNull(getTypeOrNull(possibleType)); + TypeDefinition abstractTypeDef = Objects.requireNonNull(getTypeOrNull(abstractType)); if (abstractTypeDef instanceof UnionTypeDefinition) { List memberTypes = ((UnionTypeDefinition) abstractTypeDef).getMemberTypes(); for (Type memberType : memberTypes) { - Optional checkType = getType(memberType, ObjectTypeDefinition.class); - if (checkType.isPresent()) { - if (checkType.get().getName().equals(targetObjectTypeDef.getName())) { + ObjectTypeDefinition checkType = getTypeOrNull(memberType, ObjectTypeDefinition.class); + if (checkType != null) { + if (checkType.getName().equals(targetObjectTypeDef.getName())) { return true; } } @@ -455,9 +780,21 @@ public boolean isPossibleType(Type abstractType, Type possibleObjectType) { return false; } else { InterfaceTypeDefinition iFace = (InterfaceTypeDefinition) abstractTypeDef; - List objectTypeDefinitions = getImplementationsOf(iFace); - return objectTypeDefinitions.stream() - .anyMatch(od -> od.getName().equals(targetObjectTypeDef.getName())); + for (TypeDefinition t : types.values()) { + if (t instanceof ImplementingTypeDefinition) { + if (t.getName().equals(targetObjectTypeDef.getName())) { + ImplementingTypeDefinition itd = (ImplementingTypeDefinition) t; + + for (Type implementsType : itd.getImplements()) { + TypeDefinition matchingInterface = types.get(typeName(implementsType)); + if (matchingInterface != null && matchingInterface.getName().equals(iFace.getName())) { + return true; + } + } + } + } + } + return false; } } @@ -506,7 +843,7 @@ public boolean isSubTypeOf(Type maybeSubType, Type superType) { // If superType type is an abstract type, maybeSubType type may be a currently // possible object type. if (isInterfaceOrUnion(superType) && - isObjectType(maybeSubType) && + isObjectTypeOrInterface(maybeSubType) && isPossibleType(superType, maybeSubType)) { return true; } diff --git a/src/main/java/graphql/schema/idl/TypeInfo.java b/src/main/java/graphql/schema/idl/TypeInfo.java index 8cb8df18cf..65a6c0e5a1 100644 --- a/src/main/java/graphql/schema/idl/TypeInfo.java +++ b/src/main/java/graphql/schema/idl/TypeInfo.java @@ -8,8 +8,9 @@ import graphql.language.TypeName; import graphql.schema.GraphQLType; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.Objects; -import java.util.Stack; import static graphql.Assert.assertNotNull; import static graphql.schema.GraphQLList.list; @@ -27,7 +28,7 @@ public static TypeInfo typeInfo(Type type) { private final Type rawType; private final TypeName typeName; - private final Stack> decoration = new Stack<>(); + private final Deque> decoration = new ArrayDeque<>(); private TypeInfo(Type type) { this.rawType = assertNotNull(type, "type must not be null"); @@ -68,6 +69,30 @@ public boolean isPlain() { return !isList() && !isNonNull(); } + /** + * This will rename the type with the specified new name but will preserve the wrapping that was present + * + * @param newName the new name of the type + * + * @return a new type info rebuilt with the new name + */ + public TypeInfo renameAs(String newName) { + + Type out = TypeName.newTypeName(newName).build(); + + Deque> wrappingStack = new ArrayDeque<>(this.decoration); + while (!wrappingStack.isEmpty()) { + Class clazz = wrappingStack.pop(); + if (clazz.equals(NonNullType.class)) { + out = NonNullType.newNonNullType(out).build(); + } + if (clazz.equals(ListType.class)) { + out = ListType.newListType(out).build(); + } + } + return typeInfo(out); + } + /** * This will decorate a graphql type with the original hierarchy of non null and list'ness * it originally contained in its definition type @@ -81,8 +106,7 @@ public boolean isPlain() { public T decorate(GraphQLType objectType) { GraphQLType out = objectType; - Stack> wrappingStack = new Stack<>(); - wrappingStack.addAll(this.decoration); + Deque> wrappingStack = new ArrayDeque<>(this.decoration); while (!wrappingStack.isEmpty()) { Class clazz = wrappingStack.pop(); if (clazz.equals(NonNullType.class)) { @@ -115,6 +139,36 @@ public Type unwrapOneType() { return unwrapOne().getRawType(); } + /** + * Gets the {@link TypeName} type name of a [Type], unwrapping any lists or non-null decorations + * + * @param type the Type + * + * @return the inner {@link TypeName} for this type + */ + public static TypeName getTypeName(Type type) { + while (!(type instanceof TypeName)) { + if (type instanceof NonNullType) { + type = ((NonNullType) type).getType(); + } + if (type instanceof ListType) { + type = ((ListType) type).getType(); + } + } + return (TypeName) type; + } + + /** + * Gets the string type name of a [Type], unwrapping any lists or non-null decorations + * + * @param type the Type + * + * @return the inner string name for this type + */ + public static String typeName(Type type) { + return getTypeName(type).getName(); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -127,10 +181,13 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(typeName.getName(), isNonNull(), isList()); + int result = 1; + result = 31 * result + Objects.hashCode(typeName.getName()); + result = 31 * result + Boolean.hashCode(isNonNull()); + result = 31 * result + Boolean.hashCode(isList()); + return result; } - @Override public String toString() { return "TypeInfo{" + diff --git a/src/main/java/graphql/schema/idl/TypeRuntimeWiring.java b/src/main/java/graphql/schema/idl/TypeRuntimeWiring.java index 95892d7072..e4eb79799e 100644 --- a/src/main/java/graphql/schema/idl/TypeRuntimeWiring.java +++ b/src/main/java/graphql/schema/idl/TypeRuntimeWiring.java @@ -1,21 +1,47 @@ package graphql.schema.idl; +import graphql.PublicApi; import graphql.schema.DataFetcher; import graphql.schema.GraphQLSchema; import graphql.schema.TypeResolver; +import graphql.schema.idl.errors.StrictModeWiringException; import java.util.LinkedHashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.UnaryOperator; import static graphql.Assert.assertNotNull; +import static java.lang.String.format; /** * A type runtime wiring is a specification of the data fetchers and possible type resolver for a given type name. - * + *
* This is used by {@link RuntimeWiring} to wire together a functional {@link GraphQLSchema} */ +@PublicApi public class TypeRuntimeWiring { + + private final static AtomicBoolean DEFAULT_STRICT_MODE = new AtomicBoolean(true); + + /** + * By default {@link TypeRuntimeWiring} builders are in strict mode, but you can set a JVM wide value too + * + * @param strictMode the desired strict mode state + * + * @see Builder#strictMode(boolean) + */ + public static void setStrictModeJvmWide(boolean strictMode) { + DEFAULT_STRICT_MODE.set(strictMode); + } + + /** + * @return the current JVM wide state of strict mode + */ + public static boolean getStrictModeJvmWide() { + return DEFAULT_STRICT_MODE.get(); + } + private final String typeName; private final DataFetcher defaultDataFetcher; private final Map fieldDataFetchers; @@ -80,6 +106,7 @@ public static class Builder { private DataFetcher defaultDataFetcher; private TypeResolver typeResolver; private EnumValuesProvider enumValuesProvider; + private boolean strictMode = DEFAULT_STRICT_MODE.get(); /** * Sets the type name for this type wiring. You MUST set this. @@ -93,6 +120,31 @@ public Builder typeName(String typeName) { return this; } + /** + * This puts the builder into strict mode, so if things get defined twice, for example, it + * will throw a {@link StrictModeWiringException}. + * + * @return this builder + */ + public Builder strictMode(boolean strictMode) { + this.strictMode = strictMode; + return this; + } + + /** + * This puts the builder into strict mode, so if things get defined twice, for example, it + * will throw a {@link StrictModeWiringException}. + * + * @return this builder + * + * @deprecated use {@link #strictMode(boolean)} instead + */ + @Deprecated(since = "2025-03-22", forRemoval = true) + public Builder strictMode() { + this.strictMode = true; + return this; + } + /** * Adds a data fetcher for the current type to the specified field * @@ -104,6 +156,9 @@ public Builder typeName(String typeName) { public Builder dataFetcher(String fieldName, DataFetcher dataFetcher) { assertNotNull(dataFetcher, "you must provide a data fetcher"); assertNotNull(fieldName, "you must tell us what field"); + if (strictMode) { + assertFieldStrictly(fieldName); + } fieldDataFetchers.put(fieldName, dataFetcher); return this; } @@ -117,10 +172,21 @@ public Builder dataFetcher(String fieldName, DataFetcher dataFetcher) { */ public Builder dataFetchers(Map dataFetchersMap) { assertNotNull(dataFetchersMap, "you must provide a data fetchers map"); + if (strictMode) { + dataFetchersMap.forEach((fieldName, df) -> { + assertFieldStrictly(fieldName); + }); + } fieldDataFetchers.putAll(dataFetchersMap); return this; } + private void assertFieldStrictly(String fieldName) { + if (fieldDataFetchers.containsKey(fieldName)) { + throw new StrictModeWiringException(format("The field %s already has a data fetcher defined", fieldName)); + } + } + /** * All fields in a type need a data fetcher of some sort and this method is called to provide the default data fetcher * that will be used for this type if no specific one has been provided per field. @@ -131,6 +197,9 @@ public Builder dataFetchers(Map dataFetchersMap) { */ public Builder defaultDataFetcher(DataFetcher dataFetcher) { assertNotNull(dataFetcher); + if (strictMode && defaultDataFetcher != null) { + throw new StrictModeWiringException(format("The type %s has already has a default data fetcher defined", typeName)); + } defaultDataFetcher = dataFetcher; return this; } @@ -150,7 +219,7 @@ public Builder typeResolver(TypeResolver typeResolver) { } public Builder enumValues(EnumValuesProvider enumValuesProvider) { - assertNotNull(enumValuesProvider, "you must provide a type resolver"); + assertNotNull(enumValuesProvider, "you must provide an enum values provider"); this.enumValuesProvider = enumValuesProvider; return this; } diff --git a/src/main/java/graphql/schema/idl/TypeUtil.java b/src/main/java/graphql/schema/idl/TypeUtil.java new file mode 100644 index 0000000000..0189666bd4 --- /dev/null +++ b/src/main/java/graphql/schema/idl/TypeUtil.java @@ -0,0 +1,99 @@ +package graphql.schema.idl; + +import graphql.language.Type; +import graphql.language.TypeName; +import graphql.language.ListType; +import graphql.language.NonNullType; + +/** + * This class consists of {@code static} utility methods for operating on {@link graphql.language.Type}. + */ +public class TypeUtil { + + /** + * This will return the type in graphql SDL format, eg [typeName!]! + * + * @param type the type in play + * @return the type in graphql SDL format, eg [typeName!]! + */ + public static String simplePrint(Type type) { + if (isNonNull(type)) { + return simplePrint(unwrapOne(type)) + "!"; + } else if (isList(type)) { + return "[" + simplePrint(unwrapOne(type)) + "]"; + } + return ((TypeName) type).getName(); + } + + /** + * Unwraps all layers of the type or just returns the type again if it's not a wrapped type + * + * @param type the type to be unwrapped + * + * @return the unwrapped type or the same type again if it's not wrapped + */ + public static TypeName unwrapAll(Type type) { + if (isList(type)) { + return unwrapAll(((ListType) type).getType()); + } else if (type instanceof NonNullType) { + return unwrapAll(((NonNullType) type).getType()); + } + return (TypeName) type; + } + + /** + * Unwraps one layer of the type or just returns the type again if it's not a wrapped type + * + * @param type the type to be unwrapped + * + * @return the unwrapped type or the same type again if it's not wrapped + */ + public static Type unwrapOne(Type type) { + if (isNonNull(type)) { + return ((NonNullType) type).getType(); + } else if (isList(type)) { + return ((ListType) type).getType(); + } + return type; + } + + /** + * Returns {@code true} if the provided type is a non null type, + * otherwise returns {@code false}. + * + * @param type the type to check + * + * @return {@code true} if the provided type is a non null type + * otherwise {@code false} + */ + public static boolean isNonNull(Type type) { + return type instanceof NonNullType; + } + + /** + * Returns {@code true} if the provided type is a list type, + * otherwise returns {@code false}. + * + * @param type the type to check + * + * @return {@code true} if the provided type is a list typ, + * otherwise {@code false} + */ + public static boolean isList(Type type) { + return type instanceof ListType; + } + + /** + * Returns {@code true} if the given type is a non null or list type, + * that is a wrapped type, otherwise returns {@code false}. + * + * @param type the type to check + * + * @return {@code true} if the given type is a non null or list type, + * otherwise {@code false} + */ + public static boolean isWrapped(Type type) { + return isList(type) || isNonNull(type); + } + +} diff --git a/src/main/java/graphql/schema/idl/UnExecutableSchemaGenerator.java b/src/main/java/graphql/schema/idl/UnExecutableSchemaGenerator.java index cabc0ef32c..4da72b8ab7 100644 --- a/src/main/java/graphql/schema/idl/UnExecutableSchemaGenerator.java +++ b/src/main/java/graphql/schema/idl/UnExecutableSchemaGenerator.java @@ -19,7 +19,7 @@ public static GraphQLSchema makeUnExecutableSchema(TypeDefinitionRegistry regist RuntimeWiring runtimeWiring = EchoingWiringFactory.newEchoingWiring(wiring -> { Map scalars = registry.scalars(); scalars.forEach((name, v) -> { - if (!ScalarInfo.isStandardScalar(name)) { + if (!ScalarInfo.isGraphqlSpecifiedScalar(name)) { wiring.scalar(fakeScalar(name)); } }); diff --git a/src/main/java/graphql/schema/idl/UnionTypesChecker.java b/src/main/java/graphql/schema/idl/UnionTypesChecker.java new file mode 100644 index 0000000000..f2134b2d54 --- /dev/null +++ b/src/main/java/graphql/schema/idl/UnionTypesChecker.java @@ -0,0 +1,75 @@ +package graphql.schema.idl; + +import graphql.GraphQLError; +import graphql.Internal; +import graphql.language.ObjectTypeDefinition; +import graphql.language.Type; +import graphql.language.TypeDefinition; +import graphql.language.TypeName; +import graphql.language.UnionTypeDefinition; +import graphql.language.UnionTypeExtensionDefinition; +import graphql.schema.idl.errors.UnionTypeError; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + +import static java.lang.String.format; + +/** + * UnionType check, details in https://spec.graphql.org/June2018/#sec-Type-System. + *
+ *     
+ *         
  • Invalid name begin with "__" (two underscores);
  • + *
  • Union type must include one or more member types;
  • + *
  • The member types of a Union type must all be Object base types;
  • + *
  • The member types of a Union type must be unique.
  • + *
    + *
    + */ +@Internal +class UnionTypesChecker { + + void checkUnionType(List errors, TypeDefinitionRegistry typeRegistry) { + List unionTypes = typeRegistry.getTypes(UnionTypeDefinition.class); + List unionTypeExtensions = typeRegistry.getTypes(UnionTypeExtensionDefinition.class); + + Stream.concat(unionTypes.stream(), unionTypeExtensions.stream()) + .forEach(type -> checkUnionType(typeRegistry, type, errors)); + } + + private void checkUnionType(TypeDefinitionRegistry typeRegistry, UnionTypeDefinition unionTypeDefinition, List errors) { + assertTypeName(unionTypeDefinition, errors); + + //noinspection rawtypes + List memberTypes = unionTypeDefinition.getMemberTypes(); + if (memberTypes == null || memberTypes.isEmpty()) { + errors.add(new UnionTypeError(unionTypeDefinition, format("Union type '%s' must include one or more member types.", unionTypeDefinition.getName()))); + return; + } + + Set typeNames = new LinkedHashSet<>(); + for (Type memberType : memberTypes) { + String memberTypeName = ((TypeName) memberType).getName(); + TypeDefinition memberTypeDefinition = typeRegistry.getTypeOrNull(memberTypeName); + if (!(memberTypeDefinition instanceof ObjectTypeDefinition)) { + errors.add(new UnionTypeError(unionTypeDefinition, format("The member types of a Union type must all be Object base types. member type '%s' in Union '%s' is invalid.", ((TypeName) memberType).getName(), unionTypeDefinition.getName()))); + continue; + } + + if (typeNames.contains(memberTypeName)) { + errors.add(new UnionTypeError(unionTypeDefinition, format("member type '%s' in Union '%s' is not unique. The member types of a Union type must be unique.", ((TypeName) memberType).getName(), unionTypeDefinition.getName()))); + continue; + } + typeNames.add(memberTypeName); + } + } + + private void assertTypeName(UnionTypeDefinition unionTypeDefinition, List errors) { + if (unionTypeDefinition.getName().length() >= 2 && unionTypeDefinition.getName().startsWith("__")) { + errors.add((new UnionTypeError(unionTypeDefinition, String.format("'%s' must not begin with '__', which is reserved by GraphQL introspection.", unionTypeDefinition.getName())))); + } + } + +} diff --git a/src/main/java/graphql/schema/idl/UnionWiringEnvironment.java b/src/main/java/graphql/schema/idl/UnionWiringEnvironment.java index bde774b7f4..54eba63d1a 100644 --- a/src/main/java/graphql/schema/idl/UnionWiringEnvironment.java +++ b/src/main/java/graphql/schema/idl/UnionWiringEnvironment.java @@ -2,8 +2,10 @@ import graphql.PublicApi; import graphql.language.UnionTypeDefinition; +import org.jspecify.annotations.NullMarked; @PublicApi +@NullMarked public class UnionWiringEnvironment extends WiringEnvironment { private final UnionTypeDefinition unionTypeDefinition; @@ -16,4 +18,4 @@ public class UnionWiringEnvironment extends WiringEnvironment { public UnionTypeDefinition getUnionTypeDefinition() { return unionTypeDefinition; } -} \ No newline at end of file +} diff --git a/src/main/java/graphql/schema/idl/WiringEnvironment.java b/src/main/java/graphql/schema/idl/WiringEnvironment.java index 2af0f0061b..76f5e89db2 100644 --- a/src/main/java/graphql/schema/idl/WiringEnvironment.java +++ b/src/main/java/graphql/schema/idl/WiringEnvironment.java @@ -1,5 +1,11 @@ package graphql.schema.idl; + +import graphql.PublicApi; +import org.jspecify.annotations.NullMarked; + +@PublicApi +@NullMarked abstract class WiringEnvironment { private final TypeDefinitionRegistry registry; diff --git a/src/main/java/graphql/schema/idl/WiringFactory.java b/src/main/java/graphql/schema/idl/WiringFactory.java index 866ac65693..2ceb969c66 100644 --- a/src/main/java/graphql/schema/idl/WiringFactory.java +++ b/src/main/java/graphql/schema/idl/WiringFactory.java @@ -4,7 +4,6 @@ import graphql.schema.DataFetcher; import graphql.schema.DataFetcherFactory; import graphql.schema.GraphQLScalarType; -import graphql.schema.PropertyDataFetcher; import graphql.schema.TypeResolver; import static graphql.Assert.assertShouldNeverHappen; @@ -106,10 +105,27 @@ default DataFetcherFactory getDataFetcherFactory(FieldWiringEnvironment e return assertShouldNeverHappen(); } + /** + * This is called to ask if this factory can provide a schema directive wiring. + *

    + * {@link SchemaDirectiveWiringEnvironment#getDirectives()} contains all the directives + * available which may in fact be an empty list. + * + * @param environment the calling environment + * + * @return true if the factory can give out a schema directive wiring. + */ default boolean providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { return false; } + /** + * Returns a {@link graphql.schema.idl.SchemaDirectiveWiring} given the environment + * + * @param environment the calling environment + * + * @return a {@link graphql.schema.idl.SchemaDirectiveWiring} + */ default SchemaDirectiveWiring getSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { return assertShouldNeverHappen(); } diff --git a/src/main/java/graphql/schema/idl/errors/BaseError.java b/src/main/java/graphql/schema/idl/errors/BaseError.java index 902c930223..ec3058a056 100644 --- a/src/main/java/graphql/schema/idl/errors/BaseError.java +++ b/src/main/java/graphql/schema/idl/errors/BaseError.java @@ -4,12 +4,14 @@ import graphql.GraphQLError; import graphql.GraphQLException; import graphql.GraphqlErrorHelper; +import graphql.Internal; import graphql.language.Node; import graphql.language.SourceLocation; import java.util.Collections; import java.util.List; +@Internal class BaseError extends GraphQLException implements GraphQLError { protected static final SourceLocation NO_WHERE = new SourceLocation(-1, -1); diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveIllegalArgumentTypeError.java b/src/main/java/graphql/schema/idl/errors/DirectiveIllegalArgumentTypeError.java index e933d035a9..70ef1930e2 100644 --- a/src/main/java/graphql/schema/idl/errors/DirectiveIllegalArgumentTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/DirectiveIllegalArgumentTypeError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Node; import static java.lang.String.format; +@Internal public class DirectiveIllegalArgumentTypeError extends BaseError { public static final String DUPLICATED_KEYS_MESSAGE = "Argument value object keys [%s] appear more than once."; @@ -14,7 +16,6 @@ public class DirectiveIllegalArgumentTypeError extends BaseError { public static final String NOT_A_VALID_SCALAR_LITERAL_MESSAGE = "Argument value is not a valid value of scalar '%s'."; public static final String MISSING_REQUIRED_FIELD_MESSAGE = "Missing required field '%s'."; public static final String EXPECTED_NON_NULL_MESSAGE = "Argument value is 'null', expected a non-null value."; - public static final String EXPECTED_LIST_MESSAGE = "Argument value is '%s', expected a list value."; public static final String EXPECTED_OBJECT_MESSAGE = "Argument value is of type '%s', expected an Object value."; public DirectiveIllegalArgumentTypeError(Node element, String elementName, String directiveName, String argumentName, String detailedMessaged) { diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveIllegalLocationError.java b/src/main/java/graphql/schema/idl/errors/DirectiveIllegalLocationError.java index 2b576978a4..c3a3aa09f4 100644 --- a/src/main/java/graphql/schema/idl/errors/DirectiveIllegalLocationError.java +++ b/src/main/java/graphql/schema/idl/errors/DirectiveIllegalLocationError.java @@ -1,10 +1,12 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.DirectiveDefinition; import graphql.language.Node; import static java.lang.String.format; +@Internal public class DirectiveIllegalLocationError extends BaseError { public DirectiveIllegalLocationError(Node element, String elementName, String directiveName, String locationName) { diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveIllegalReferenceError.java b/src/main/java/graphql/schema/idl/errors/DirectiveIllegalReferenceError.java new file mode 100644 index 0000000000..44fb541e53 --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/DirectiveIllegalReferenceError.java @@ -0,0 +1,15 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.DirectiveDefinition; +import graphql.language.NamedNode; + +@Internal +public class DirectiveIllegalReferenceError extends BaseError { + public DirectiveIllegalReferenceError(DirectiveDefinition directive, NamedNode location) { + super(directive, + String.format("'%s' must not reference itself on '%s''%s'", + directive.getName(), location.getName(), lineCol(location) + )); + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveMissingNonNullArgumentError.java b/src/main/java/graphql/schema/idl/errors/DirectiveMissingNonNullArgumentError.java index e24397afef..01dd7c6e6b 100644 --- a/src/main/java/graphql/schema/idl/errors/DirectiveMissingNonNullArgumentError.java +++ b/src/main/java/graphql/schema/idl/errors/DirectiveMissingNonNullArgumentError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Node; import static java.lang.String.format; +@Internal public class DirectiveMissingNonNullArgumentError extends BaseError { public DirectiveMissingNonNullArgumentError(Node element, String elementName, String directiveName, String argumentName) { diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/DirectiveRedefinitionError.java index ff80a33d71..878a728f5b 100644 --- a/src/main/java/graphql/schema/idl/errors/DirectiveRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/DirectiveRedefinitionError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.DirectiveDefinition; import static java.lang.String.format; +@Internal public class DirectiveRedefinitionError extends BaseError { public DirectiveRedefinitionError(DirectiveDefinition newEntry, DirectiveDefinition oldEntry) { diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveUndeclaredError.java b/src/main/java/graphql/schema/idl/errors/DirectiveUndeclaredError.java index 7814fb9b45..776da6719b 100644 --- a/src/main/java/graphql/schema/idl/errors/DirectiveUndeclaredError.java +++ b/src/main/java/graphql/schema/idl/errors/DirectiveUndeclaredError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Node; import static java.lang.String.format; +@Internal public class DirectiveUndeclaredError extends BaseError { public DirectiveUndeclaredError(Node element, String elementName, String directiveName) { diff --git a/src/main/java/graphql/schema/idl/errors/DirectiveUnknownArgumentError.java b/src/main/java/graphql/schema/idl/errors/DirectiveUnknownArgumentError.java index 7befa92612..69e90904a3 100644 --- a/src/main/java/graphql/schema/idl/errors/DirectiveUnknownArgumentError.java +++ b/src/main/java/graphql/schema/idl/errors/DirectiveUnknownArgumentError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Node; import static java.lang.String.format; +@Internal public class DirectiveUnknownArgumentError extends BaseError { public DirectiveUnknownArgumentError(Node element, String elementName, String directiveName, String argumentName) { diff --git a/src/main/java/graphql/schema/idl/errors/IllegalNameError.java b/src/main/java/graphql/schema/idl/errors/IllegalNameError.java new file mode 100644 index 0000000000..2733519b22 --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/IllegalNameError.java @@ -0,0 +1,14 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.NamedNode; + +@Internal +public class IllegalNameError extends BaseError { + public IllegalNameError(NamedNode directiveDefinition) { + super(directiveDefinition, + String.format("'%s''%s' must not begin with '__', which is reserved by GraphQL introspection.", + directiveDefinition.getName(), lineCol(directiveDefinition) + )); + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentNotOptionalError.java b/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentNotOptionalError.java new file mode 100644 index 0000000000..1303b5ef2f --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentNotOptionalError.java @@ -0,0 +1,16 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.FieldDefinition; +import graphql.language.ImplementingTypeDefinition; +import graphql.language.InterfaceTypeDefinition; + +import static java.lang.String.format; + +@Internal +public class InterfaceFieldArgumentNotOptionalError extends BaseError { + public InterfaceFieldArgumentNotOptionalError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef, String objectArgStr) { + super(typeDefinition, format("The %s type '%s' %s field '%s' defines an additional non-optional argument '%s' which is not allowed because field is also defined in interface '%s' %s.", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), objectFieldDef.getName(), objectArgStr, interfaceTypeDef.getName(), lineCol(interfaceTypeDef))); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentRedefinitionError.java index 8549018fa4..5ba558a8fb 100644 --- a/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/InterfaceFieldArgumentRedefinitionError.java @@ -1,15 +1,17 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.FieldDefinition; +import graphql.language.ImplementingTypeDefinition; import graphql.language.InterfaceTypeDefinition; -import graphql.language.ObjectTypeDefinition; import static java.lang.String.format; +@Internal public class InterfaceFieldArgumentRedefinitionError extends BaseError { - public InterfaceFieldArgumentRedefinitionError(String typeOfType, ObjectTypeDefinition objectTypeDef, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef, String objectArgStr, String interfaceArgStr) { - super(objectTypeDef, format("The %s type '%s' %s has tried to redefine field '%s' arguments defined via interface '%s' %s from '%s' to '%s", - typeOfType, objectTypeDef.getName(), lineCol(objectTypeDef), objectFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef), interfaceArgStr, objectArgStr)); + public InterfaceFieldArgumentRedefinitionError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef, String objectArgStr, String interfaceArgStr) { + super(typeDefinition, format("The %s type '%s' %s has tried to redefine field '%s' arguments defined via interface '%s' %s from '%s' to '%s", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), objectFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef), interfaceArgStr, objectArgStr)); } } diff --git a/src/main/java/graphql/schema/idl/errors/InterfaceFieldRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/InterfaceFieldRedefinitionError.java index 53e579e849..b8a1e582ef 100644 --- a/src/main/java/graphql/schema/idl/errors/InterfaceFieldRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/InterfaceFieldRedefinitionError.java @@ -1,14 +1,16 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.FieldDefinition; +import graphql.language.ImplementingTypeDefinition; import graphql.language.InterfaceTypeDefinition; -import graphql.language.ObjectTypeDefinition; import static java.lang.String.format; +@Internal public class InterfaceFieldRedefinitionError extends BaseError { - public InterfaceFieldRedefinitionError(String typeOfType, ObjectTypeDefinition objectType, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef, String objectFieldType, String interfaceFieldType) { - super(objectType, format("The %s type '%s' %s has tried to redefine field '%s' defined via interface '%s' %s from '%s' to '%s'", - typeOfType, objectType.getName(), lineCol(objectType), objectFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef), interfaceFieldType, objectFieldType)); + public InterfaceFieldRedefinitionError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef, String objectFieldType, String interfaceFieldType) { + super(typeDefinition, format("The %s type '%s' %s has tried to redefine field '%s' defined via interface '%s' %s from '%s' to '%s'", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), objectFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef), interfaceFieldType, objectFieldType)); } } diff --git a/src/main/java/graphql/schema/idl/errors/InterfaceImplementedMoreThanOnceError.java b/src/main/java/graphql/schema/idl/errors/InterfaceImplementedMoreThanOnceError.java new file mode 100644 index 0000000000..97e64f983d --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/InterfaceImplementedMoreThanOnceError.java @@ -0,0 +1,15 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.ImplementingTypeDefinition; +import graphql.language.InterfaceTypeDefinition; + +import static java.lang.String.format; + +@Internal +public class InterfaceImplementedMoreThanOnceError extends BaseError { + public InterfaceImplementedMoreThanOnceError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition implementedInterface) { + super(typeDefinition, format("The %s type '%s' %s can only implement '%s' %s once.", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), implementedInterface.getName(), lineCol(implementedInterface))); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/InterfaceImplementingItselfError.java b/src/main/java/graphql/schema/idl/errors/InterfaceImplementingItselfError.java new file mode 100644 index 0000000000..63925366ef --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/InterfaceImplementingItselfError.java @@ -0,0 +1,14 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.ImplementingTypeDefinition; + +import static java.lang.String.format; + +@Internal +public class InterfaceImplementingItselfError extends BaseError { + public InterfaceImplementingItselfError(String typeOfType, ImplementingTypeDefinition typeDefinition) { + super(typeDefinition, format("The %s type '%s' %s cannot implement itself", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition))); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/InterfaceWithCircularImplementationHierarchyError.java b/src/main/java/graphql/schema/idl/errors/InterfaceWithCircularImplementationHierarchyError.java new file mode 100644 index 0000000000..ed7e12cbe5 --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/InterfaceWithCircularImplementationHierarchyError.java @@ -0,0 +1,17 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.ImplementingTypeDefinition; +import graphql.language.InterfaceTypeDefinition; + +import static java.lang.String.format; + +@Internal +public class InterfaceWithCircularImplementationHierarchyError extends BaseError { + public InterfaceWithCircularImplementationHierarchyError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition implementedInterface) { + super(typeDefinition, format("The %s type '%s' %s cannot implement '%s' %s as this would result in a circular reference", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), + implementedInterface.getName(), lineCol(implementedInterface) + )); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/InvalidDeprecationDirectiveError.java b/src/main/java/graphql/schema/idl/errors/InvalidDeprecationDirectiveError.java deleted file mode 100644 index 288654d0b8..0000000000 --- a/src/main/java/graphql/schema/idl/errors/InvalidDeprecationDirectiveError.java +++ /dev/null @@ -1,27 +0,0 @@ -package graphql.schema.idl.errors; - -import graphql.language.EnumValueDefinition; -import graphql.language.FieldDefinition; -import graphql.language.InputValueDefinition; -import graphql.language.TypeDefinition; - -import static java.lang.String.format; - -public class InvalidDeprecationDirectiveError extends BaseError { - - public InvalidDeprecationDirectiveError(TypeDefinition typeDefinition, FieldDefinition fieldDefinition) { - super(typeDefinition, format("The type '%s' with field '%s' %s has declared an invalid deprecation directive. Its must be @deprecated(reason : \"xyz\")", - typeDefinition.getName(), fieldDefinition.getName(), lineCol(typeDefinition))); - } - - public InvalidDeprecationDirectiveError(TypeDefinition typeDefinition, InputValueDefinition inputValueDefinition) { - super(typeDefinition, format("The type '%s' with input value '%s' %s has declared an invalid deprecation directive. Its must be @deprecated(reason : \"xyz\")", - typeDefinition.getName(), inputValueDefinition.getName(), lineCol(typeDefinition))); - } - - public InvalidDeprecationDirectiveError(TypeDefinition typeDefinition, EnumValueDefinition enumValueDefinition) { - super(typeDefinition, format("The %s type with enum value '%s' %s has declared an invalid deprecation directive. Its must be @deprecated(reason : \"xyz\")", - typeDefinition.getName(), enumValueDefinition.getName(), lineCol(typeDefinition))); - } - -} diff --git a/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldArgumentsError.java b/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldArgumentsError.java index 1ab6126609..5c33f6d513 100644 --- a/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldArgumentsError.java +++ b/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldArgumentsError.java @@ -1,14 +1,16 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.FieldDefinition; +import graphql.language.ImplementingTypeDefinition; import graphql.language.InterfaceTypeDefinition; -import graphql.language.ObjectTypeDefinition; import static java.lang.String.format; +@Internal public class MissingInterfaceFieldArgumentsError extends BaseError { - public MissingInterfaceFieldArgumentsError(String typeOfType, ObjectTypeDefinition objectTypeDef, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef) { - super(objectTypeDef, format("The %s type '%s' %s field '%s' does not have the same number of arguments as specified via interface '%s' %s", - typeOfType, objectTypeDef.getName(), lineCol(objectTypeDef), objectFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef))); + public MissingInterfaceFieldArgumentsError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition objectFieldDef) { + super(typeDefinition, format("The %s type '%s' %s field '%s' does not have the same number of arguments as specified via interface '%s' %s", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), objectFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef))); } } diff --git a/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldError.java b/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldError.java index 9f04a92630..e3761b4d56 100644 --- a/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldError.java +++ b/src/main/java/graphql/schema/idl/errors/MissingInterfaceFieldError.java @@ -1,13 +1,15 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.FieldDefinition; +import graphql.language.ImplementingTypeDefinition; import graphql.language.InterfaceTypeDefinition; -import graphql.language.ObjectTypeDefinition; import static java.lang.String.format; +@Internal public class MissingInterfaceFieldError extends BaseError { - public MissingInterfaceFieldError(String typeOfType, ObjectTypeDefinition objectType, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition interfaceFieldDef) { + public MissingInterfaceFieldError(String typeOfType, ImplementingTypeDefinition objectType, InterfaceTypeDefinition interfaceTypeDef, FieldDefinition interfaceFieldDef) { super(objectType, format("The %s type '%s' %s does not have a field '%s' required via interface '%s' %s", typeOfType, objectType.getName(), lineCol(objectType), interfaceFieldDef.getName(), interfaceTypeDef.getName(), lineCol(interfaceTypeDef))); } diff --git a/src/main/java/graphql/schema/idl/errors/MissingInterfaceTypeError.java b/src/main/java/graphql/schema/idl/errors/MissingInterfaceTypeError.java index 2c69566dd6..56870b5715 100644 --- a/src/main/java/graphql/schema/idl/errors/MissingInterfaceTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/MissingInterfaceTypeError.java @@ -1,10 +1,12 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.TypeDefinition; import graphql.language.TypeName; import static java.lang.String.format; +@Internal public class MissingInterfaceTypeError extends BaseError { public MissingInterfaceTypeError(String typeOfType, TypeDefinition typeDefinition, TypeName typeName) { diff --git a/src/main/java/graphql/schema/idl/errors/MissingScalarImplementationError.java b/src/main/java/graphql/schema/idl/errors/MissingScalarImplementationError.java index f154eb6939..b6b963fb2f 100644 --- a/src/main/java/graphql/schema/idl/errors/MissingScalarImplementationError.java +++ b/src/main/java/graphql/schema/idl/errors/MissingScalarImplementationError.java @@ -1,7 +1,10 @@ package graphql.schema.idl.errors; +import graphql.Internal; + import static java.lang.String.format; +@Internal public class MissingScalarImplementationError extends BaseError { public MissingScalarImplementationError(String scalarName) { diff --git a/src/main/java/graphql/schema/idl/errors/MissingTransitiveInterfaceError.java b/src/main/java/graphql/schema/idl/errors/MissingTransitiveInterfaceError.java new file mode 100644 index 0000000000..f2b7e9423f --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/MissingTransitiveInterfaceError.java @@ -0,0 +1,15 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.ImplementingTypeDefinition; +import graphql.language.InterfaceTypeDefinition; + +import static java.lang.String.format; + +@Internal +public class MissingTransitiveInterfaceError extends BaseError { + public MissingTransitiveInterfaceError(String typeOfType, ImplementingTypeDefinition typeDefinition, InterfaceTypeDefinition implementedInterface, InterfaceTypeDefinition missingInterface) { + super(typeDefinition, format("The %s type '%s' %s must implement '%s' %s because it is implemented by '%s' %s", + typeOfType, typeDefinition.getName(), lineCol(typeDefinition), missingInterface.getName(), lineCol(missingInterface), implementedInterface.getName(), lineCol(implementedInterface))); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/MissingTypeError.java b/src/main/java/graphql/schema/idl/errors/MissingTypeError.java index e1fe76ac47..d037e471c5 100644 --- a/src/main/java/graphql/schema/idl/errors/MissingTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/MissingTypeError.java @@ -1,11 +1,13 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Node; import graphql.language.TypeDefinition; import graphql.language.TypeName; import static java.lang.String.format; +@Internal public class MissingTypeError extends BaseError { public MissingTypeError(String typeOfType, TypeDefinition typeDefinition, TypeName typeName) { @@ -17,4 +19,9 @@ public MissingTypeError(String typeOfType, Node node, String name, TypeName type super(node, format("The %s type '%s' is not present when resolving type '%s' %s", typeOfType, typeName.getName(), name, lineCol(node))); } + + public MissingTypeError(String typeOfType, Node node,String name) { + super(node, format("The %s type is not present when resolving type '%s' %s", + typeOfType, name, lineCol(node))); + } } diff --git a/src/main/java/graphql/schema/idl/errors/MissingTypeResolverError.java b/src/main/java/graphql/schema/idl/errors/MissingTypeResolverError.java index 7def130980..dbf00b8f39 100644 --- a/src/main/java/graphql/schema/idl/errors/MissingTypeResolverError.java +++ b/src/main/java/graphql/schema/idl/errors/MissingTypeResolverError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class MissingTypeResolverError extends BaseError { public MissingTypeResolverError(TypeDefinition typeDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/NonSDLDefinitionError.java b/src/main/java/graphql/schema/idl/errors/NonSDLDefinitionError.java new file mode 100644 index 0000000000..fb41b7b7d3 --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/NonSDLDefinitionError.java @@ -0,0 +1,15 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.Definition; + +import static java.lang.String.format; + +@Internal +public class NonSDLDefinitionError extends BaseError { + + public NonSDLDefinitionError(Definition definition) { + super(definition, format("%s The schema definition text contains a non schema definition language (SDL) element '%s'", + lineCol(definition), definition.getClass().getSimpleName())); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/NonUniqueArgumentError.java b/src/main/java/graphql/schema/idl/errors/NonUniqueArgumentError.java index 3f122ef34b..990826ac58 100644 --- a/src/main/java/graphql/schema/idl/errors/NonUniqueArgumentError.java +++ b/src/main/java/graphql/schema/idl/errors/NonUniqueArgumentError.java @@ -1,5 +1,6 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.EnumValueDefinition; import graphql.language.FieldDefinition; import graphql.language.InputValueDefinition; @@ -7,6 +8,7 @@ import static java.lang.String.format; +@Internal public class NonUniqueArgumentError extends BaseError { public NonUniqueArgumentError(TypeDefinition typeDefinition, FieldDefinition fieldDefinition, String argumentName) { diff --git a/src/main/java/graphql/schema/idl/errors/NonUniqueDirectiveError.java b/src/main/java/graphql/schema/idl/errors/NonUniqueDirectiveError.java index aa9b859387..9845973047 100644 --- a/src/main/java/graphql/schema/idl/errors/NonUniqueDirectiveError.java +++ b/src/main/java/graphql/schema/idl/errors/NonUniqueDirectiveError.java @@ -1,5 +1,6 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.EnumValueDefinition; import graphql.language.FieldDefinition; import graphql.language.InputValueDefinition; @@ -7,6 +8,7 @@ import static java.lang.String.format; +@Internal public class NonUniqueDirectiveError extends BaseError { public NonUniqueDirectiveError(TypeDefinition typeDefinition, FieldDefinition fieldDefinition, String directiveName) { diff --git a/src/main/java/graphql/schema/idl/errors/NonUniqueNameError.java b/src/main/java/graphql/schema/idl/errors/NonUniqueNameError.java index 4dee4e8f19..ec7b57266c 100644 --- a/src/main/java/graphql/schema/idl/errors/NonUniqueNameError.java +++ b/src/main/java/graphql/schema/idl/errors/NonUniqueNameError.java @@ -1,5 +1,6 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.DirectiveDefinition; import graphql.language.EnumValueDefinition; import graphql.language.FieldDefinition; @@ -10,6 +11,7 @@ import static java.lang.String.format; +@Internal public class NonUniqueNameError extends BaseError { public NonUniqueNameError(TypeDefinition typeDefinition, FieldDefinition fieldDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java index 728bab3df1..f51198b472 100644 --- a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java @@ -1,10 +1,12 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Type; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class NotAnInputTypeError extends BaseError { public NotAnInputTypeError(Type rawType, TypeDefinition typeDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java index da7c1dbe6b..1869d2ed4d 100644 --- a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java @@ -1,10 +1,12 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Type; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class NotAnOutputTypeError extends BaseError { public NotAnOutputTypeError(Type rawType, TypeDefinition typeDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/OperationRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/OperationRedefinitionError.java new file mode 100644 index 0000000000..e9c27ee33a --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/OperationRedefinitionError.java @@ -0,0 +1,15 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.OperationTypeDefinition; + +import static java.lang.String.format; + +@Internal +public class OperationRedefinitionError extends BaseError { + + public OperationRedefinitionError(OperationTypeDefinition oldEntry, OperationTypeDefinition newEntry) { + super(oldEntry, format("There is already an operation '%s' defined %s. The offending new one is here %s", + oldEntry.getName(), lineCol(oldEntry), lineCol(newEntry))); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/OperationTypesMustBeObjects.java b/src/main/java/graphql/schema/idl/errors/OperationTypesMustBeObjects.java index 1e56e951a1..43ea40d239 100644 --- a/src/main/java/graphql/schema/idl/errors/OperationTypesMustBeObjects.java +++ b/src/main/java/graphql/schema/idl/errors/OperationTypesMustBeObjects.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.OperationTypeDefinition; import static java.lang.String.format; +@Internal public class OperationTypesMustBeObjects extends BaseError { public OperationTypesMustBeObjects(OperationTypeDefinition op) { diff --git a/src/main/java/graphql/schema/idl/errors/QueryOperationMissingError.java b/src/main/java/graphql/schema/idl/errors/QueryOperationMissingError.java index a873e3989a..7ce1066ed4 100644 --- a/src/main/java/graphql/schema/idl/errors/QueryOperationMissingError.java +++ b/src/main/java/graphql/schema/idl/errors/QueryOperationMissingError.java @@ -1,5 +1,8 @@ package graphql.schema.idl.errors; +import graphql.Internal; + +@Internal public class QueryOperationMissingError extends BaseError { public QueryOperationMissingError() { diff --git a/src/main/java/graphql/schema/idl/errors/SchemaMissingError.java b/src/main/java/graphql/schema/idl/errors/SchemaMissingError.java index 7f4d455c9a..1da631980b 100644 --- a/src/main/java/graphql/schema/idl/errors/SchemaMissingError.java +++ b/src/main/java/graphql/schema/idl/errors/SchemaMissingError.java @@ -1,5 +1,8 @@ package graphql.schema.idl.errors; +import graphql.Internal; + +@Internal public class SchemaMissingError extends BaseError { public SchemaMissingError() { diff --git a/src/main/java/graphql/schema/idl/errors/SchemaProblem.java b/src/main/java/graphql/schema/idl/errors/SchemaProblem.java index 77c0e0f59a..817a54d5b5 100644 --- a/src/main/java/graphql/schema/idl/errors/SchemaProblem.java +++ b/src/main/java/graphql/schema/idl/errors/SchemaProblem.java @@ -2,6 +2,7 @@ import graphql.GraphQLError; import graphql.GraphQLException; +import graphql.PublicApi; import graphql.schema.idl.SchemaParser; import java.util.ArrayList; @@ -12,6 +13,7 @@ * or {@link graphql.schema.idl.SchemaGenerator} classes and they are reported via this * exception as a list of {@link GraphQLError}s */ +@PublicApi public class SchemaProblem extends GraphQLException { private final List errors; diff --git a/src/main/java/graphql/schema/idl/errors/SchemaRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/SchemaRedefinitionError.java index f97aa1843b..fa9638ceb2 100644 --- a/src/main/java/graphql/schema/idl/errors/SchemaRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/SchemaRedefinitionError.java @@ -1,13 +1,15 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.SchemaDefinition; import static java.lang.String.format; +@Internal public class SchemaRedefinitionError extends BaseError { public SchemaRedefinitionError(SchemaDefinition oldEntry, SchemaDefinition newEntry) { - super(oldEntry, format("There is already a schema defined %s. The offending new new ones is here %s", + super(oldEntry, format("There is already a schema defined %s. The offending new one is here %s", lineCol(oldEntry), lineCol(newEntry))); } } diff --git a/src/main/java/graphql/schema/idl/errors/StrictModeWiringException.java b/src/main/java/graphql/schema/idl/errors/StrictModeWiringException.java new file mode 100644 index 0000000000..4c92bffd6d --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/StrictModeWiringException.java @@ -0,0 +1,17 @@ +package graphql.schema.idl.errors; + +import graphql.GraphQLException; +import graphql.PublicApi; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.TypeRuntimeWiring; + +/** + * An exception that is throw when {@link RuntimeWiring.Builder#strictMode(boolean)} or {@link TypeRuntimeWiring.Builder#strictMode(boolean)} is true and + * something gets redefined. + */ +@PublicApi +public class StrictModeWiringException extends GraphQLException { + public StrictModeWiringException(String msg) { + super(msg); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/TypeExtensionDirectiveRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/TypeExtensionDirectiveRedefinitionError.java index 3c63b4fac4..1a1058f934 100644 --- a/src/main/java/graphql/schema/idl/errors/TypeExtensionDirectiveRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/TypeExtensionDirectiveRedefinitionError.java @@ -1,10 +1,12 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.Directive; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class TypeExtensionDirectiveRedefinitionError extends BaseError { public TypeExtensionDirectiveRedefinitionError(TypeDefinition typeExtensionDefinition, Directive directive) { diff --git a/src/main/java/graphql/schema/idl/errors/TypeExtensionEnumValueRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/TypeExtensionEnumValueRedefinitionError.java index 929ab8a6f3..d783ab9ea9 100644 --- a/src/main/java/graphql/schema/idl/errors/TypeExtensionEnumValueRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/TypeExtensionEnumValueRedefinitionError.java @@ -1,10 +1,12 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.EnumValueDefinition; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class TypeExtensionEnumValueRedefinitionError extends BaseError { public TypeExtensionEnumValueRedefinitionError(TypeDefinition typeDefinition, EnumValueDefinition enumValueDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/TypeExtensionFieldRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/TypeExtensionFieldRedefinitionError.java index e3315810e0..aecd819557 100644 --- a/src/main/java/graphql/schema/idl/errors/TypeExtensionFieldRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/TypeExtensionFieldRedefinitionError.java @@ -1,5 +1,6 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.AbstractNode; import graphql.language.FieldDefinition; import graphql.language.InputValueDefinition; @@ -7,6 +8,7 @@ import static java.lang.String.format; +@Internal public class TypeExtensionFieldRedefinitionError extends BaseError { public TypeExtensionFieldRedefinitionError(TypeDefinition typeDefinition, FieldDefinition fieldDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/TypeExtensionMissingBaseTypeError.java b/src/main/java/graphql/schema/idl/errors/TypeExtensionMissingBaseTypeError.java index 6ca9f67aa6..f72db0c3cb 100644 --- a/src/main/java/graphql/schema/idl/errors/TypeExtensionMissingBaseTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/TypeExtensionMissingBaseTypeError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class TypeExtensionMissingBaseTypeError extends BaseError { public TypeExtensionMissingBaseTypeError(TypeDefinition typeExtensionDefinition) { diff --git a/src/main/java/graphql/schema/idl/errors/TypeRedefinitionError.java b/src/main/java/graphql/schema/idl/errors/TypeRedefinitionError.java index a2fd16a9b0..860bdae881 100644 --- a/src/main/java/graphql/schema/idl/errors/TypeRedefinitionError.java +++ b/src/main/java/graphql/schema/idl/errors/TypeRedefinitionError.java @@ -1,9 +1,11 @@ package graphql.schema.idl.errors; +import graphql.Internal; import graphql.language.TypeDefinition; import static java.lang.String.format; +@Internal public class TypeRedefinitionError extends BaseError { public TypeRedefinitionError(TypeDefinition newEntry, TypeDefinition oldEntry) { diff --git a/src/main/java/graphql/schema/idl/errors/UnionTypeError.java b/src/main/java/graphql/schema/idl/errors/UnionTypeError.java new file mode 100644 index 0000000000..86e8f6148c --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/UnionTypeError.java @@ -0,0 +1,11 @@ +package graphql.schema.idl.errors; + +import graphql.Internal; +import graphql.language.Node; + +@Internal +public class UnionTypeError extends BaseError { + public UnionTypeError(Node node, String msg) { + super(node, msg); + } +} diff --git a/src/main/java/graphql/schema/impl/GraphQLTypeCollectingVisitor.java b/src/main/java/graphql/schema/impl/GraphQLTypeCollectingVisitor.java new file mode 100644 index 0000000000..e6ceb76e3c --- /dev/null +++ b/src/main/java/graphql/schema/impl/GraphQLTypeCollectingVisitor.java @@ -0,0 +1,186 @@ +package graphql.schema.impl; + +import com.google.common.collect.ImmutableMap; +import graphql.AssertException; +import graphql.Internal; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeReference; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.function.Supplier; + +import static graphql.schema.GraphQLTypeUtil.unwrapAllAs; +import static graphql.util.TraversalControl.CONTINUE; +import static java.lang.String.format; + +@Internal +public class GraphQLTypeCollectingVisitor extends GraphQLTypeVisitorStub { + + private final Map result = new LinkedHashMap<>(); + private final Map indirectStrongReferences = new LinkedHashMap<>(); + + public GraphQLTypeCollectingVisitor() { + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context) { + assertTypeUniqueness(node, result); + save(node.getName(), node); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + assertTypeUniqueness(node, result); + save(node.getName(), node); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (isNotTypeReference(node.getName())) { + assertTypeUniqueness(node, result); + } else { + save(node.getName(), node); + } + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + if (isNotTypeReference(node.getName())) { + assertTypeUniqueness(node, result); + } else { + save(node.getName(), node); + } + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + if (isNotTypeReference(node.getName())) { + assertTypeUniqueness(node, result); + } else { + save(node.getName(), node); + } + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + assertTypeUniqueness(node, result); + save(node.getName(), node); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + saveIndirectStrongReference(node::getType); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + saveIndirectStrongReference(node::getType); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + saveIndirectStrongReference(node::getType); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + saveIndirectStrongReference(node::getType); + return CONTINUE; + } + + private void saveIndirectStrongReference(Supplier typeSupplier) { + GraphQLNamedType type = unwrapAllAs(typeSupplier.get()); + if (!(type instanceof GraphQLTypeReference)) { + indirectStrongReferences.put(type.getName(), type); + } + } + + + private boolean isNotTypeReference(String name) { + return result.containsKey(name) && !(result.get(name) instanceof GraphQLTypeReference); + } + + private void save(String name, GraphQLNamedType type) { + result.put(name, type); + } + + + /* + From https://spec.graphql.org/October2021/#sec-Type-System + + All types within a GraphQL schema must have unique names. No two provided types may have the same name. + No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types). + + Enforcing this helps avoid problems later down the track fo example https://github.com/graphql-java/graphql-java/issues/373 + */ + private void assertTypeUniqueness(GraphQLNamedType type, Map result) { + GraphQLType existingType = result.get(type.getName()); + // do we have an existing definition + if (existingType != null) { + // type references are ok + if (!(existingType instanceof GraphQLTypeReference || type instanceof GraphQLTypeReference)) { + assertUniqueTypeObjects(type, existingType); + } + } + } + + private void assertUniqueTypeObjects(GraphQLNamedType type, GraphQLType existingType) { + // object comparison here is deliberate + if (existingType != type) { + throw new AssertException(format("All types within a GraphQL schema must have unique names. No two provided types may have the same name.\n" + + "No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).\n" + + "You have redefined the type '%s' from being a '%s' to a '%s'", + type.getName(), existingType.getClass().getSimpleName(), type.getClass().getSimpleName())); + } + } + + public ImmutableMap getResult() { + Map types = new TreeMap<>(fixDanglingReplacedTypes(result)); + return ImmutableMap.copyOf(types); + } + + /** + * It's possible for certain schema edits to create a situation where a field / arg / input field had a type reference, then + * it got replaced with an actual strong reference and then the schema gets edited such that the only reference + * to that type is the replaced strong reference. This edge case means that the replaced reference can be + * missed if it's the only way to get to that type because this visitor asks for the children as original type, + * e.g. the type reference and not the replaced reference. + * + * @param visitedTypes the types collected by this visitor + * + * @return a fixed up map where the only + */ + private Map fixDanglingReplacedTypes(Map visitedTypes) { + for (GraphQLNamedType indirectStrongReference : indirectStrongReferences.values()) { + String typeName = indirectStrongReference.getName(); + visitedTypes.putIfAbsent(typeName, indirectStrongReference); + } + return visitedTypes; + } +} diff --git a/src/main/java/graphql/schema/impl/MultiReadOnlyGraphQLTypeVisitor.java b/src/main/java/graphql/schema/impl/MultiReadOnlyGraphQLTypeVisitor.java new file mode 100644 index 0000000000..d3ca059fc2 --- /dev/null +++ b/src/main/java/graphql/schema/impl/MultiReadOnlyGraphQLTypeVisitor.java @@ -0,0 +1,225 @@ +package graphql.schema.impl; + +import graphql.Assert; +import graphql.Internal; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInputFieldsContainer; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLModifiedType; +import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLNullableType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeReference; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphQLUnmodifiedType; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.List; + +/** + * A delegating type visitor that allows you to call N visitors in a list + * and always continues via {@link TraversalControl#CONTINUE} + */ +@Internal +public class MultiReadOnlyGraphQLTypeVisitor implements GraphQLTypeVisitor { + + private final List visitors; + + public MultiReadOnlyGraphQLTypeVisitor(List visitors) { + this.visitors = visitors; + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLAppliedDirective(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLAppliedDirectiveArgument(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLArgument(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLInterfaceType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLEnumType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLEnumValueDefinition(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLFieldDefinition(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLDirective(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLInputObjectField(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLInputObjectType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLList(GraphQLList node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLList(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLNonNull(GraphQLNonNull node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLNonNull(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLObjectType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLScalarType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLTypeReference(GraphQLTypeReference node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLTypeReference(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLUnionType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitBackRef(TraverserContext context) { + visitors.forEach(v -> v.visitBackRef(context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLModifiedType(GraphQLModifiedType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLModifiedType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLCompositeType(GraphQLCompositeType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLCompositeType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLDirectiveContainer(GraphQLDirectiveContainer node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLDirectiveContainer(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLFieldsContainer(GraphQLFieldsContainer node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLFieldsContainer(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputFieldsContainer(GraphQLInputFieldsContainer node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLInputFieldsContainer(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputType(GraphQLInputType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLInputType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLNullableType(GraphQLNullableType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLNullableType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLOutputType(GraphQLOutputType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLOutputType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLUnmodifiedType(GraphQLUnmodifiedType node, TraverserContext context) { + visitors.forEach(v -> v.visitGraphQLUnmodifiedType(node, context)); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl changeNode(TraverserContext context, GraphQLSchemaElement newChangedNode) { + return Assert.assertShouldNeverHappen("This must be a read only operation"); + } + + @Override + public TraversalControl deleteNode(TraverserContext context) { + return Assert.assertShouldNeverHappen("This must be a read only operation"); + } + + @Override + public TraversalControl insertAfter(TraverserContext context, GraphQLSchemaElement toInsertAfter) { + return Assert.assertShouldNeverHappen("This must be a read only operation"); + } + + @Override + public TraversalControl insertBefore(TraverserContext context, GraphQLSchemaElement toInsertBefore) { + return Assert.assertShouldNeverHappen("This must be a read only operation"); + } +} diff --git a/src/main/java/graphql/schema/impl/SchemaUtil.java b/src/main/java/graphql/schema/impl/SchemaUtil.java new file mode 100644 index 0000000000..66b06f2b83 --- /dev/null +++ b/src/main/java/graphql/schema/impl/SchemaUtil.java @@ -0,0 +1,132 @@ +package graphql.schema.impl; + + +import com.google.common.collect.ImmutableMap; +import graphql.Internal; +import graphql.execution.MissingRootTypeException; +import graphql.language.OperationDefinition; +import graphql.schema.GraphQLImplementingType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeResolvingVisitor; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.SchemaTraverser; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import static graphql.Assert.assertShouldNeverHappen; +import static graphql.language.OperationDefinition.Operation.MUTATION; +import static graphql.language.OperationDefinition.Operation.QUERY; +import static graphql.language.OperationDefinition.Operation.SUBSCRIPTION; + +@Internal +public class SchemaUtil { + + /** + * Called to visit a partially built schema (during {@link GraphQLSchema} build phases) with a set of visitors + * + * Each visitor is expected to hold its own side effects that might be last used to construct a full schema + * + * @param partiallyBuiltSchema the partially built schema + * @param visitors the visitors to call + */ + + public static void visitPartiallySchema(final GraphQLSchema partiallyBuiltSchema, GraphQLTypeVisitor... visitors) { + List roots = new ArrayList<>(); + roots.add(partiallyBuiltSchema.getQueryType()); + + if (partiallyBuiltSchema.isSupportingMutations()) { + roots.add(partiallyBuiltSchema.getMutationType()); + } + + if (partiallyBuiltSchema.isSupportingSubscriptions()) { + roots.add(partiallyBuiltSchema.getSubscriptionType()); + } + + if (partiallyBuiltSchema.getAdditionalTypes() != null) { + roots.addAll(partiallyBuiltSchema.getAdditionalTypes()); + } + + if (partiallyBuiltSchema.getDirectives() != null) { + roots.addAll(partiallyBuiltSchema.getDirectives()); + } + + roots.add(partiallyBuiltSchema.getIntrospectionSchemaType()); + + GraphQLTypeVisitor visitor = new MultiReadOnlyGraphQLTypeVisitor(Arrays.asList(visitors)); + SchemaTraverser traverser; + traverser = new SchemaTraverser(schemaElement -> schemaElement.getChildrenWithTypeReferences().getChildrenAsList()); + traverser.depthFirst(visitor, roots); + } + + public static ImmutableMap> groupInterfaceImplementationsByName(List allTypesAsList) { + Map> result = new LinkedHashMap<>(); + for (GraphQLType type : allTypesAsList) { + if (type instanceof GraphQLObjectType) { + List interfaces = ((GraphQLObjectType) type).getInterfaces(); + for (GraphQLNamedOutputType interfaceType : interfaces) { + List myGroup = result.computeIfAbsent(interfaceType.getName(), k -> new ArrayList<>()); + myGroup.add((GraphQLObjectType) type); + } + } + } + return ImmutableMap.copyOf(new TreeMap<>(result)); + } + + public Map> groupImplementationsForInterfacesAndObjects(GraphQLSchema schema) { + Map> result = new LinkedHashMap<>(); + for (GraphQLType type : schema.getAllTypesAsList()) { + if (type instanceof GraphQLImplementingType) { + List interfaces = ((GraphQLImplementingType) type).getInterfaces(); + for (GraphQLNamedOutputType interfaceType : interfaces) { + List myGroup = result.computeIfAbsent(interfaceType.getName(), k -> new ArrayList<>()); + myGroup.add((GraphQLImplementingType) type); + } + } + } + return ImmutableMap.copyOf(new TreeMap<>(result)); + } + + public static void replaceTypeReferences(GraphQLSchema schema) { + final Map typeMap = schema.getTypeMap(); + List roots = new ArrayList<>(typeMap.values()); + roots.addAll(schema.getDirectives()); + roots.addAll(schema.getSchemaAppliedDirectives()); + SchemaTraverser schemaTraverser = new SchemaTraverser(schemaElement -> schemaElement.getChildrenWithTypeReferences().getChildrenAsList()); + schemaTraverser.depthFirst(new GraphQLTypeResolvingVisitor(typeMap), roots); + } + + public static GraphQLObjectType getOperationRootType(GraphQLSchema graphQLSchema, OperationDefinition operationDefinition) { + OperationDefinition.Operation operation = operationDefinition.getOperation(); + if (operation == MUTATION) { + GraphQLObjectType mutationType = graphQLSchema.getMutationType(); + if (mutationType == null) { + throw new MissingRootTypeException("Schema is not configured for mutations.", operationDefinition.getSourceLocation()); + } + return mutationType; + } else if (operation == QUERY) { + GraphQLObjectType queryType = graphQLSchema.getQueryType(); + if (queryType == null) { + throw new MissingRootTypeException("Schema does not define the required query root type.", operationDefinition.getSourceLocation()); + } + return queryType; + } else if (operation == SUBSCRIPTION) { + GraphQLObjectType subscriptionType = graphQLSchema.getSubscriptionType(); + if (subscriptionType == null) { + throw new MissingRootTypeException("Schema is not configured for subscriptions.", operationDefinition.getSourceLocation()); + } + return subscriptionType; + } else { + return assertShouldNeverHappen("Unhandled case. An extra operation enum has been added without code support"); + } + } +} diff --git a/src/main/java/graphql/schema/impl/StronglyConnectedComponentsTopologicallySorted.java b/src/main/java/graphql/schema/impl/StronglyConnectedComponentsTopologicallySorted.java new file mode 100644 index 0000000000..3ff66789ff --- /dev/null +++ b/src/main/java/graphql/schema/impl/StronglyConnectedComponentsTopologicallySorted.java @@ -0,0 +1,172 @@ +package graphql.schema.impl; + +import graphql.Assert; +import graphql.Internal; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLSchemaElement; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * This class returns a list of strongly connected components (SCC) which are topologically sorted. + * The algorithm is from https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + * + * The elements inside a SCC are additionally sorted top. itself: normally this is not possible, + * but we are using for this "inner sort" only the "reverseDependencies" Map which is made out of + * dependencies based one the Java references between Schema elements, which can't form a cycle. + * + * The inner sort algorithm is from https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search + */ +@Internal +public class StronglyConnectedComponentsTopologicallySorted { + + private int index; + private final Map nodeToIndex = new LinkedHashMap<>(); + private final Map nodeToLowLink = new LinkedHashMap<>(); + private final Map nodeToOnStack = new LinkedHashMap<>(); + private final Deque stack = new ArrayDeque<>(); + private final List> result = new ArrayList<>(); + + private final Map> reverseDependencies; + // this includes type references which means it allows for cycles + private final Map> typeRefReverseDependencies; + + + private StronglyConnectedComponentsTopologicallySorted(Map> reverseDependencies, + Map> typeRefReverseDependencies) { + this.reverseDependencies = reverseDependencies; + this.typeRefReverseDependencies = typeRefReverseDependencies; + } + + public static List> getStronglyConnectedComponentsTopologicallySorted( + Map> reverseDependencies, + Map> typeRefReverseDependencies + ) { + StronglyConnectedComponentsTopologicallySorted sccTopSort = new StronglyConnectedComponentsTopologicallySorted(reverseDependencies, typeRefReverseDependencies); + sccTopSort.calculate(); + return sccTopSort.result; + } + + private void calculate() { + index = 0; + for (GraphQLSchemaElement v : reverseDependencies.keySet()) { + if (nodeToIndex.get(v) == null) { + stronglyConnect(v); + } + } + } + + private void stronglyConnect(GraphQLSchemaElement v) { + nodeToIndex.put(v, index); + nodeToLowLink.put(v, index); + index++; + stack.push(v); + nodeToOnStack.put(v, true); + + List dependencies = reverseDependencies.get(v); + if (dependencies == null) { + dependencies = new ArrayList<>(); + } + if (v instanceof GraphQLNamedType) { + String name = ((GraphQLNamedType) v).getName(); + if (typeRefReverseDependencies.containsKey(name)) { + dependencies = new ArrayList<>(dependencies); + dependencies.addAll(typeRefReverseDependencies.get(name)); + } + } + for (GraphQLSchemaElement w : dependencies) { + if (nodeToIndex.get(w) == null) { + stronglyConnect(w); + nodeToLowLink.put(v, Math.min(nodeToLowLink.get(v), nodeToLowLink.get(w))); + } else if (Boolean.TRUE.equals(nodeToOnStack.get(w))) { + nodeToLowLink.put(v, Math.min(nodeToLowLink.get(v), nodeToIndex.get(w))); + } + } + if (nodeToLowLink.get(v).equals(nodeToIndex.get(v))) { + Set newSCC = new LinkedHashSet<>(); + GraphQLSchemaElement w; + do { + w = stack.pop(); + nodeToOnStack.put(w, false); + newSCC.add(w); + } while (w != v); + result.add(topologicallySort(newSCC)); + } + } + + private List topologicallySort(Set allNodes) { + List result = new ArrayList<>(); + Set notPermMarked = new LinkedHashSet<>(allNodes); + Set tempMarked = new LinkedHashSet<>(); + Set permMarked = new LinkedHashSet<>(); + /* + * Taken from: https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search + * while exists nodes without a permanent mark do + * select an unmarked node n + * visit(n) + */ + while (true) { + Iterator iterator = notPermMarked.iterator(); + if (!iterator.hasNext()) { + break; + } + GraphQLSchemaElement n = iterator.next(); + iterator.remove(); + visit(n, tempMarked, permMarked, notPermMarked, result, allNodes); + } + return result; + } + + private void visit(GraphQLSchemaElement n, + Set tempMarked, + Set permMarked, + Set notPermMarked, + List result, + Set allNodes) { + /* + * Taken from: https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search + * if n has a permanent mark then + * return + * if n has a temporary mark then + * stop (not a DAG) + * + * mark n with a temporary mark + * + * for each node m with an edge from n to m do + * visit(m) + * + * remove temporary mark from n + * mark n with a permanent mark + * add n to head of L + */ + if (permMarked.contains(n)) { + return; + } + if (tempMarked.contains(n)) { + // https://en.wikipedia.org/wiki/Directed_acyclic_graph + Assert.assertShouldNeverHappen("This schema is not forming an Directed Acyclic Graph : %s has already has a temporary mark", n); + return; + } + tempMarked.add(n); + if (reverseDependencies.containsKey(n)) { + for (GraphQLSchemaElement m : reverseDependencies.get(n)) { + if (allNodes.contains(m)) { + visit(m, tempMarked, permMarked, notPermMarked, result, allNodes); + } + } + } + tempMarked.remove(n); + permMarked.add(n); + notPermMarked.remove(n); + result.add(n); + } + +} diff --git a/src/main/java/graphql/schema/transform/FieldVisibilitySchemaTransformation.java b/src/main/java/graphql/schema/transform/FieldVisibilitySchemaTransformation.java new file mode 100644 index 0000000000..325854129c --- /dev/null +++ b/src/main/java/graphql/schema/transform/FieldVisibilitySchemaTransformation.java @@ -0,0 +1,274 @@ +package graphql.schema.transform; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLImplementingType; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.schema.SchemaTraverser; +import graphql.schema.impl.SchemaUtil; +import graphql.schema.transform.VisibleFieldPredicateEnvironment.VisibleFieldPredicateEnvironmentImpl; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static graphql.schema.SchemaTransformer.transformSchema; + +/** + * Transforms a schema by applying a visibility predicate to every field. + */ +@PublicApi +public class FieldVisibilitySchemaTransformation { + + private final VisibleFieldPredicate visibleFieldPredicate; + private final Runnable beforeTransformationHook; + private final Runnable afterTransformationHook; + + public FieldVisibilitySchemaTransformation(VisibleFieldPredicate visibleFieldPredicate) { + this(visibleFieldPredicate, () -> {}, () -> {}); + } + + public FieldVisibilitySchemaTransformation(VisibleFieldPredicate visibleFieldPredicate, + Runnable beforeTransformationHook, + Runnable afterTransformationHook) { + this.visibleFieldPredicate = visibleFieldPredicate; + this.beforeTransformationHook = beforeTransformationHook; + this.afterTransformationHook = afterTransformationHook; + } + + public final GraphQLSchema apply(GraphQLSchema schema) { + Set observedBeforeTransform = new HashSet<>(); + Set observedAfterTransform = new HashSet<>(); + Set markedForRemovalTypes = new HashSet<>(); + + // query, mutation, and subscription types should not be removed + final Set protectedTypeNames = new HashSet<>(); + for (GraphQLObjectType graphQLObjectType : getOperationTypes(schema)) { + protectedTypeNames.add(graphQLObjectType.getName()); + } + + beforeTransformationHook.run(); + + new SchemaTraverser(getChildrenFn(schema)).depthFirst(new TypeObservingVisitor(observedBeforeTransform), getRootTypes(schema)); + + // remove fields + GraphQLSchema interimSchema = transformSchema(schema, + new FieldRemovalVisitor(visibleFieldPredicate, markedForRemovalTypes)); + + new SchemaTraverser(getChildrenFn(interimSchema)).depthFirst(new TypeObservingVisitor(observedAfterTransform), getRootTypes(interimSchema)); + + // remove types that are not used after removing fields - (connected schema only) + GraphQLSchema connectedSchema = transformSchema(interimSchema, + new TypeVisibilityVisitor(protectedTypeNames, observedBeforeTransform, observedAfterTransform)); + + // ensure markedForRemovalTypes are not referenced by other schema elements, and delete from the schema + // the ones that aren't. + GraphQLSchema finalSchema = removeUnreferencedTypes(markedForRemovalTypes, connectedSchema); + + afterTransformationHook.run(); + + return finalSchema; + } + + // Creates a getChildrenFn that includes interface + private Function> getChildrenFn(GraphQLSchema schema) { + Map> interfaceImplementations = new SchemaUtil().groupImplementationsForInterfacesAndObjects(schema); + + return graphQLSchemaElement -> { + if (!(graphQLSchemaElement instanceof GraphQLInterfaceType)) { + return graphQLSchemaElement.getChildren(); + } + ArrayList children = new ArrayList<>(graphQLSchemaElement.getChildren()); + List implementations = interfaceImplementations.get(((GraphQLInterfaceType) graphQLSchemaElement).getName()); + if (implementations != null) { + children.addAll(implementations); + } + return children; + }; + } + + private GraphQLSchema removeUnreferencedTypes(Set markedForRemovalTypes, GraphQLSchema connectedSchema) { + GraphQLSchema withoutAdditionalTypes = connectedSchema.transform(builder -> { + Set additionalTypes = new HashSet<>(connectedSchema.getAdditionalTypes()); + additionalTypes.removeAll(markedForRemovalTypes); + builder.clearAdditionalTypes(); + builder.additionalTypes(additionalTypes); + }); + + // remove from markedForRemovalTypes any type that might still be referenced by other schema elements + transformSchema(withoutAdditionalTypes, new AdditionalTypeVisibilityVisitor(markedForRemovalTypes)); + + // finally remove the types on the schema we are certain aren't referenced by any other node. + return transformSchema(connectedSchema, new GraphQLTypeVisitorStub() { + @Override + protected TraversalControl visitGraphQLType(GraphQLSchemaElement node, TraverserContext context) { + if (node instanceof GraphQLType && markedForRemovalTypes.contains(node)) { + return deleteNode(context); + } + return super.visitGraphQLType(node, context); + } + }); + } + + private static class TypeObservingVisitor extends GraphQLTypeVisitorStub { + + private final Set observedTypes; + + + private TypeObservingVisitor(Set observedTypes) { + this.observedTypes = observedTypes; + } + + @Override + protected TraversalControl visitGraphQLType(GraphQLSchemaElement node, + TraverserContext context) { + if (node instanceof GraphQLType) { + observedTypes.add((GraphQLType) node); + } + + return TraversalControl.CONTINUE; + } + } + + private static class FieldRemovalVisitor extends GraphQLTypeVisitorStub { + + private final VisibleFieldPredicate visibilityPredicate; + private final Set removedTypes; + + private FieldRemovalVisitor(VisibleFieldPredicate visibilityPredicate, + Set removedTypes) { + this.visibilityPredicate = visibilityPredicate; + this.removedTypes = removedTypes; + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition definition, + TraverserContext context) { + return visitField(definition, context); + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField definition, + TraverserContext context) { + return visitField(definition, context); + } + + private TraversalControl visitField(GraphQLNamedSchemaElement element, + TraverserContext context) { + + VisibleFieldPredicateEnvironment environment = new VisibleFieldPredicateEnvironmentImpl( + element, context.getParentNode()); + if (!visibilityPredicate.isVisible(environment)) { + deleteNode(context); + + if (element instanceof GraphQLFieldDefinition) { + removedTypes.add(((GraphQLFieldDefinition) element).getType()); + } else if (element instanceof GraphQLInputObjectField) { + removedTypes.add(((GraphQLInputObjectField) element).getType()); + } + } + + return TraversalControl.CONTINUE; + } + } + + private static class TypeVisibilityVisitor extends GraphQLTypeVisitorStub { + + private final Set protectedTypeNames; + private final Set observedBeforeTransform; + private final Set observedAfterTransform; + + private TypeVisibilityVisitor(Set protectedTypeNames, + Set observedTypes, + Set observedAfterTransform) { + this.protectedTypeNames = protectedTypeNames; + this.observedBeforeTransform = observedTypes; + this.observedAfterTransform = observedAfterTransform; + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, + TraverserContext context) { + return super.visitGraphQLInterfaceType(node, context); + } + + @Override + public TraversalControl visitGraphQLType(GraphQLSchemaElement node, + TraverserContext context) { + if (observedBeforeTransform.contains(node) && + !observedAfterTransform.contains(node) && + (node instanceof GraphQLObjectType || + node instanceof GraphQLEnumType || + node instanceof GraphQLInputObjectType || + node instanceof GraphQLInterfaceType || + node instanceof GraphQLUnionType)) { + + return deleteNode(context); + } + + return TraversalControl.CONTINUE; + } + } + + private static class AdditionalTypeVisibilityVisitor extends GraphQLTypeVisitorStub { + + private final Set markedForRemovalTypes; + + private AdditionalTypeVisibilityVisitor(Set markedForRemovalTypes) { + this.markedForRemovalTypes = markedForRemovalTypes; + } + + @Override + public TraversalControl visitGraphQLType(GraphQLSchemaElement node, + TraverserContext context) { + + if (node instanceof GraphQLNamedType) { + GraphQLNamedType namedType = (GraphQLNamedType) node; + // we encountered a node referencing one of the marked types, so it should not be removed. + if (markedForRemovalTypes.contains(node)) { + markedForRemovalTypes.remove(namedType); + } + } + + return TraversalControl.CONTINUE; + } + } + + private List getRootTypes(GraphQLSchema schema) { + return ImmutableList.builder() + .addAll(getOperationTypes(schema)) + // Include directive definitions as roots, since they won't be removed in the filtering process. + // Some types (enums, input types, etc.) might be reachable only by directive definitions (and + // not by other types or fields). + .addAll(schema.getDirectives()) + .build(); + } + + private List getOperationTypes(GraphQLSchema schema) { + return Stream.of( + schema.getQueryType(), + schema.getSubscriptionType(), + schema.getMutationType() + ).filter(Objects::nonNull).collect(Collectors.toList()); + } +} diff --git a/src/main/java/graphql/schema/transform/VisibleFieldPredicate.java b/src/main/java/graphql/schema/transform/VisibleFieldPredicate.java new file mode 100644 index 0000000000..4fceb6db4e --- /dev/null +++ b/src/main/java/graphql/schema/transform/VisibleFieldPredicate.java @@ -0,0 +1,21 @@ +package graphql.schema.transform; + + +import graphql.PublicSpi; + +/** + * Predicate used during a {@link FieldVisibilitySchemaTransformation} to test whether a field should be visible. + */ +@PublicSpi +@FunctionalInterface +public interface VisibleFieldPredicate { + + /** + * Test whether a field should be visible. Provided as a more descriptive "test" method that describes exactly + * what a positive result of "test" should mean. + * + * @param environment the context of the field + * @return true if visible + */ + boolean isVisible(VisibleFieldPredicateEnvironment environment); +} diff --git a/src/main/java/graphql/schema/transform/VisibleFieldPredicateEnvironment.java b/src/main/java/graphql/schema/transform/VisibleFieldPredicateEnvironment.java new file mode 100644 index 0000000000..54ee176019 --- /dev/null +++ b/src/main/java/graphql/schema/transform/VisibleFieldPredicateEnvironment.java @@ -0,0 +1,43 @@ +package graphql.schema.transform; + +import graphql.PublicApi; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLSchemaElement; + +/** + * Container to pass additional context about a schema element (ie., field) to {@link VisibleFieldPredicate}. + */ +@PublicApi +public interface VisibleFieldPredicateEnvironment { + + GraphQLNamedSchemaElement getSchemaElement(); + + /** + * Get the element's immediate parent node. + * + * @return parent node + */ + GraphQLSchemaElement getParentElement(); + + class VisibleFieldPredicateEnvironmentImpl implements VisibleFieldPredicateEnvironment { + + private final GraphQLNamedSchemaElement schemaElement; + private final GraphQLSchemaElement parentElement; + + public VisibleFieldPredicateEnvironmentImpl(GraphQLNamedSchemaElement schemaElement, + GraphQLSchemaElement parentElement) { + this.schemaElement = schemaElement; + this.parentElement = parentElement; + } + + @Override + public GraphQLNamedSchemaElement getSchemaElement() { + return schemaElement; + } + + @Override + public GraphQLSchemaElement getParentElement() { + return parentElement; + } + } +} diff --git a/src/main/java/graphql/schema/usage/SchemaUsage.java b/src/main/java/graphql/schema/usage/SchemaUsage.java new file mode 100644 index 0000000000..25ed7fb24c --- /dev/null +++ b/src/main/java/graphql/schema/usage/SchemaUsage.java @@ -0,0 +1,270 @@ +package graphql.schema.usage; + +import com.google.common.collect.ImmutableMap; +import graphql.Internal; +import graphql.PublicApi; +import graphql.introspection.Introspection; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.DirectiveInfo; +import graphql.schema.idl.ScalarInfo; + +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static java.util.Collections.emptySet; + +/** + * This class shows schema usage information. There are two aspects to this. To be strongly referenced, a schema element + * (directive or type) must some how be connected back to the root query, mutation or subscription type. It's possible to define + * types that reference other types but if they do not get used by a field / interface or union that itself leads back to the root + * types then it is not considered strongly references. + * + * Its reference counts however might be non-zero yet not be strongly referenced. For example given `type A { f : B } type B { f : A }` both types A and B + * will have non-zero counts but if no other type points to A or B that leads back to the root types then they are not strongly referenced types. + * + * Such types could be removed from the schema because there is no way to ever consume these types in a query. A common use case for this class + * is to find the types and directives in a schema that could in theory be removed because they are not useful. + */ +@PublicApi +public class SchemaUsage { + private final Map fieldReferenceCounts; + private final Map inputFieldReferenceCounts; + private final Map outputFieldReferenceCounts; + private final Map argReferenceCount; + private final Map interfaceReferenceCount; + private final Map unionReferenceCount; + private final Map directiveReferenceCount; + private final Map> interfaceImplementors; + private final Map> elementBackReferences; + + private final Map> unionReferences; + + private SchemaUsage(Builder builder) { + this.fieldReferenceCounts = ImmutableMap.copyOf(builder.fieldReferenceCounts); + this.inputFieldReferenceCounts = ImmutableMap.copyOf(builder.inputFieldReferenceCounts); + this.outputFieldReferenceCounts = ImmutableMap.copyOf(builder.outputFieldReferenceCounts); + this.argReferenceCount = ImmutableMap.copyOf(builder.argReferenceCount); + this.interfaceReferenceCount = ImmutableMap.copyOf(builder.interfaceReferenceCount); + this.unionReferenceCount = ImmutableMap.copyOf(builder.unionReferenceCount); + this.directiveReferenceCount = ImmutableMap.copyOf(builder.directiveReferenceCount); + this.interfaceImplementors = ImmutableMap.copyOf(builder.interfaceImplementors); + this.elementBackReferences = ImmutableMap.copyOf(builder.elementBackReferences); + this.unionReferences = ImmutableMap.copyOf(builder.unionReferences); + } + + /** + * This shows how many times a type is referenced by either an input or output field. + * + * @return a map of type name to field reference counts + */ + public Map getFieldReferenceCounts() { + return fieldReferenceCounts; + } + + /** + * This shows how many times a type is referenced by an output field. + * + * @return a map of type name to output field reference counts + */ + public Map getOutputFieldReferenceCounts() { + return outputFieldReferenceCounts; + } + + /** + * This shows how many times a type is referenced by an input field. + * + * @return a map of type name to input field reference counts + */ + public Map getInputFieldReferenceCounts() { + return inputFieldReferenceCounts; + } + + /** + * This shows how many times a type is referenced by an argument. + * + * @return a map of type name to argument reference counts + */ + public Map getArgumentReferenceCounts() { + return argReferenceCount; + } + + /** + * This shows how many times an interface type is referenced as a member in some other + * object or interface type. + * + * @return a map of interface type name to object or interface type reference counts + */ + public Map getInterfaceReferenceCounts() { + return interfaceReferenceCount; + } + + /** + * This shows how many times an object type is referenced as a member in some other + * union type. + * + * @return a map of object type name to union membership reference counts + */ + public Map getUnionReferenceCounts() { + return unionReferenceCount; + } + + /** + * This shows how many times a directive is applied on some other schema element. + * + * @return a map of directive name to applied directive counts + */ + public Map getDirectiveReferenceCounts() { + return directiveReferenceCount; + } + + /** + * Returns true if the named element is strongly reference somewhere in the schema back to the root types such as the schema + * query, mutation or subscription types. + * + * Graphql specified scalar types, introspection types and directives are always counted as referenced, even if + * not used explicitly. + * + * Directives that are defined but never applied on any schema elements will not report as referenced. + * + * @param schema the schema that contains the name type + * @param elementName the element name to check + * + * @return true if the element could be referenced + */ + public boolean isStronglyReferenced(GraphQLSchema schema, String elementName) { + return isReferencedImpl(schema, elementName, new HashSet<>()); + } + + /** + * This returns all the unreferenced named elements in a schema. + * + * @param schema the schema to check + * + * @return a set of the named schema elements where {@link #isStronglyReferenced(GraphQLSchema, String)} returns false + */ + public Set getUnReferencedElements(GraphQLSchema schema) { + Set elements = new LinkedHashSet<>(); + schema.getAllTypesAsList().forEach(type -> { + if (!isStronglyReferenced(schema, type.getName())) { + elements.add(type); + } + }); + schema.getDirectives().forEach(directive -> { + if (!isStronglyReferenced(schema, directive.getName())) { + elements.add(directive); + } + }); + return elements; + } + + private boolean isReferencedImpl(GraphQLSchema schema, String elementName, Set pathSoFar) { + if (pathSoFar.contains(elementName)) { + return false; // circular reference to that element + } + pathSoFar.add(elementName); + + if (ScalarInfo.isGraphqlSpecifiedScalar(elementName)) { + return true; + } + + GraphQLDirective directive = schema.getDirective(elementName); + if (directive != null) { + String directiveName = directive.getName(); + if (DirectiveInfo.isGraphqlSpecifiedDirective(directiveName)) { + return true; + } + if (isNamedElementReferenced(schema, directiveName, pathSoFar)) { + return true; + } + } + + GraphQLNamedType type = schema.getTypeAs(elementName); + if (type == null) { + return false; + } + if (Introspection.isIntrospectionTypes(type)) { + return true; + } + + if (type == schema.getQueryType()) { + return true; + } + if (type == schema.getMutationType()) { + return true; + } + if (type == schema.getSubscriptionType()) { + return true; + } + + if (isNamedElementReferenced(schema, elementName, pathSoFar)) { + return true; + } + + if (type instanceof GraphQLInterfaceType) { + Set implementors = interfaceImplementors.getOrDefault(type.getName(), emptySet()); + for (String implementor : implementors) { + if (isReferencedImpl(schema, implementor, pathSoFar)) { + return true; + } + } + } + if (type instanceof GraphQLObjectType) { + List interfaces = ((GraphQLObjectType) type).getInterfaces(); + for (GraphQLNamedOutputType memberInterface : interfaces) { + Set implementors = interfaceImplementors.getOrDefault(memberInterface.getName(), emptySet()); + for (String implementor : implementors) { + if (isReferencedImpl(schema, implementor, pathSoFar)) { + return true; + } + } + } + + Set unionContainers = unionReferences.getOrDefault(type.getName(), emptySet()); + for (String unionContainer : unionContainers) { + if (isReferencedImpl(schema, unionContainer, pathSoFar)) { + return true; + } + } + } + return false; + } + + private boolean isNamedElementReferenced(GraphQLSchema schema, String elementName, Set pathSoFar) { + Set references = elementBackReferences.getOrDefault(elementName, emptySet()); + for (String reference : references) { + if (isReferencedImpl(schema, reference, pathSoFar)) { + return true; + } + } + return false; + } + + @Internal + static class Builder { + Map fieldReferenceCounts = new LinkedHashMap<>(); + Map inputFieldReferenceCounts = new LinkedHashMap<>(); + Map outputFieldReferenceCounts = new LinkedHashMap<>(); + Map argReferenceCount = new LinkedHashMap<>(); + Map interfaceReferenceCount = new LinkedHashMap<>(); + Map unionReferenceCount = new LinkedHashMap<>(); + Map directiveReferenceCount = new LinkedHashMap<>(); + Map> interfaceImplementors = new LinkedHashMap<>(); + + Map> unionReferences = new LinkedHashMap<>(); + Map> elementBackReferences = new LinkedHashMap<>(); + + SchemaUsage build() { + return new SchemaUsage(this); + } + } +} diff --git a/src/main/java/graphql/schema/usage/SchemaUsageSupport.java b/src/main/java/graphql/schema/usage/SchemaUsageSupport.java new file mode 100644 index 0000000000..f51bb0429d --- /dev/null +++ b/src/main/java/graphql/schema/usage/SchemaUsageSupport.java @@ -0,0 +1,193 @@ +package graphql.schema.usage; + +import graphql.PublicApi; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.schema.SchemaTraverser; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.HashSet; +import java.util.List; +import java.util.function.BiFunction; + +import static graphql.Assert.assertNotNull; +import static graphql.util.TraversalControl.CONTINUE; + +@PublicApi +public class SchemaUsageSupport { + + /** + * This builds out {@link SchemaUsage} statistics about the usage of types and directives within a schema + * + * @param schema the schema to check + * + * @return usage stats + */ + public static SchemaUsage getSchemaUsage(GraphQLSchema schema) { + + assertNotNull(schema); + + SchemaUsage.Builder builder = new SchemaUsage.Builder(); + GraphQLTypeVisitor visitor = new GraphQLTypeVisitorStub() { + + private BiFunction incCount() { + return (k, v) -> v == null ? 1 : v + 1; + } + + private void recordBackReference(GraphQLNamedSchemaElement referencedElement, GraphQLSchemaElement referencingElement) { + String referencedElementName = referencedElement.getName(); + if (referencingElement instanceof GraphQLType) { + String typeName = (GraphQLTypeUtil.unwrapAll((GraphQLType) referencingElement)).getName(); + builder.elementBackReferences.computeIfAbsent(referencedElementName, k -> new HashSet<>()).add(typeName); + } + if (referencingElement instanceof GraphQLDirective) { + String typeName = ((GraphQLDirective) referencingElement).getName(); + builder.elementBackReferences.computeIfAbsent(referencedElementName, k -> new HashSet<>()).add(typeName); + } + if (referencingElement instanceof GraphQLAppliedDirective) { + String typeName = ((GraphQLAppliedDirective) referencingElement).getName(); + builder.elementBackReferences.computeIfAbsent(referencedElementName, k -> new HashSet<>()).add(typeName); + } + } + + private void memberInterfaces(GraphQLNamedType containingType, List members) { + for (GraphQLNamedOutputType member : members) { + builder.interfaceReferenceCount.compute(member.getName(), incCount()); + builder.interfaceImplementors.computeIfAbsent(member.getName(), k -> new HashSet<>()).add(containingType.getName()); + + recordBackReference(containingType, member); + } + } + + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + GraphQLNamedType inputType = GraphQLTypeUtil.unwrapAll(node.getType()); + builder.argReferenceCount.compute(inputType.getName(), incCount()); + + GraphQLSchemaElement parentElement = context.getParentNode(); + if (parentElement instanceof GraphQLFieldDefinition) { + parentElement = context.getParentContext().getParentNode(); + } + recordBackReference(inputType, parentElement); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + GraphQLNamedType inputType = GraphQLTypeUtil.unwrapAll(node.getType()); + builder.argReferenceCount.compute(inputType.getName(), incCount()); + + GraphQLSchemaElement parentElement = context.getParentNode(); + if (parentElement instanceof GraphQLAppliedDirective) { + parentElement = context.getParentContext().getParentNode(); + } + recordBackReference(inputType, parentElement); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + GraphQLNamedType fieldType = GraphQLTypeUtil.unwrapAll(node.getType()); + builder.fieldReferenceCounts.compute(fieldType.getName(), incCount()); + builder.outputFieldReferenceCounts.compute(fieldType.getName(), incCount()); + + recordBackReference(fieldType, context.getParentNode()); + + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + GraphQLNamedType fieldType = GraphQLTypeUtil.unwrapAll(node.getType()); + builder.fieldReferenceCounts.compute(fieldType.getName(), incCount()); + builder.inputFieldReferenceCounts.compute(fieldType.getName(), incCount()); + + recordBackReference(fieldType, context.getParentNode()); + + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective directive, TraverserContext context) { + GraphQLSchemaElement parentElement = visitDirectiveLike(context, directive.getName()); + recordBackReference(directive, parentElement); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective appliedDirective, TraverserContext context) { + GraphQLSchemaElement parentElement = visitDirectiveLike(context, appliedDirective.getName()); + recordBackReference(appliedDirective, parentElement); + return CONTINUE; + } + + private GraphQLSchemaElement visitDirectiveLike(TraverserContext context, String directiveName) { + GraphQLSchemaElement parentElement = context.getParentNode(); + if (parentElement != null) { + // a null parent is a directive definition + // we record a count if the directive is applied to something - not just defined + builder.directiveReferenceCount.compute(directiveName, incCount()); + } + if (parentElement instanceof GraphQLArgument) { + context = context.getParentContext(); + parentElement = context.getParentNode(); + } + if (parentElement instanceof GraphQLFieldDefinition) { + context = context.getParentContext(); + parentElement = context.getParentNode(); + } + if (parentElement instanceof GraphQLInputObjectField) { + context = context.getParentContext(); + parentElement = context.getParentNode(); + } + return parentElement; + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType unionType, TraverserContext context) { + List members = unionType.getTypes(); + for (GraphQLNamedOutputType member : members) { + builder.unionReferenceCount.compute(member.getName(), incCount()); + builder.unionReferences.computeIfAbsent(member.getName(), k -> new HashSet<>()).add(unionType.getName()); + + recordBackReference(unionType, member); + } + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType interfaceType, TraverserContext context) { + memberInterfaces(interfaceType, interfaceType.getInterfaces()); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) { + memberInterfaces(objectType, objectType.getInterfaces()); + return CONTINUE; + } + + }; + new SchemaTraverser().depthFirstFullSchema(visitor, schema); + return builder.build(); + } + +} diff --git a/src/main/java/graphql/schema/validation/AppliedDirectiveArgumentsAreValid.java b/src/main/java/graphql/schema/validation/AppliedDirectiveArgumentsAreValid.java new file mode 100644 index 0000000000..1eec8bff75 --- /dev/null +++ b/src/main/java/graphql/schema/validation/AppliedDirectiveArgumentsAreValid.java @@ -0,0 +1,100 @@ +package graphql.schema.validation; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.NonNullableValueCoercedAsNullException; +import graphql.execution.ValuesResolver; +import graphql.language.Value; +import graphql.schema.CoercingParseValueException; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.InputValueWithState; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.validation.ValidationUtil; + +import java.util.Locale; + +import static java.lang.String.format; + +@Internal +public class AppliedDirectiveArgumentsAreValid extends GraphQLTypeVisitorStub { + + private ValidationUtil validationUtil = new ValidationUtil(); + + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective directive, TraverserContext context) { + // if there is no parent it means it is just a directive definition and not an applied directive + if (context.getParentNode() != null) { + for (GraphQLArgument graphQLArgument : directive.getArguments()) { + checkArgument( + directive.getName(), + graphQLArgument.getName(), + graphQLArgument.getArgumentValue(), + graphQLArgument.getType(), + context + ); + } + } + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective directive, TraverserContext context) { + // if there is no parent it means it is just a directive definition and not an applied directive + if (context.getParentNode() != null) { + for (GraphQLAppliedDirectiveArgument graphQLArgument : directive.getArguments()) { + checkArgument( + directive.getName(), + graphQLArgument.getName(), + graphQLArgument.getArgumentValue(), + graphQLArgument.getType(), + context + ); + } + } + return TraversalControl.CONTINUE; + } + + private void checkArgument( + String directiveName, + String argumentName, + InputValueWithState argumentValue, + GraphQLInputType argumentType, + TraverserContext context + ) { + GraphQLSchema schema = context.getVarFromParents(GraphQLSchema.class); + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + boolean invalid = false; + if (argumentValue.isLiteral() && + !validationUtil.isValidLiteralValue((Value) argumentValue.getValue(), argumentType, schema, GraphQLContext.getDefault(), Locale.getDefault())) { + invalid = true; + } else if (argumentValue.isExternal() && + !isValidExternalValue(schema, argumentValue.getValue(), argumentType, GraphQLContext.getDefault(), Locale.getDefault())) { + invalid = true; + } else if (argumentValue.isNotSet() && GraphQLTypeUtil.isNonNull(argumentType)) { + invalid = true; + } + if (invalid) { + String message = format("Invalid argument '%s' for applied directive of name '%s'", argumentName, directiveName); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.InvalidAppliedDirectiveArgument, message)); + } + } + + private boolean isValidExternalValue(GraphQLSchema schema, Object externalValue, GraphQLInputType type, GraphQLContext graphQLContext, Locale locale) { + try { + ValuesResolver.externalValueToInternalValue(schema.getCodeRegistry().getFieldVisibility(), externalValue, type, graphQLContext, locale); + return true; + } catch (CoercingParseValueException | NonNullableValueCoercedAsNullException e) { + return false; + } + } +} diff --git a/src/main/java/graphql/schema/validation/AppliedDirectivesAreValid.java b/src/main/java/graphql/schema/validation/AppliedDirectivesAreValid.java new file mode 100644 index 0000000000..cf2b3da5d4 --- /dev/null +++ b/src/main/java/graphql/schema/validation/AppliedDirectivesAreValid.java @@ -0,0 +1,59 @@ +package graphql.schema.validation; + +import graphql.Internal; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.List; +import java.util.Map; + +import static graphql.schema.validation.SchemaValidationErrorType.InvalidAppliedDirective; +import static java.lang.String.format; + +@Internal +public class AppliedDirectivesAreValid extends GraphQLTypeVisitorStub { + + @Override + protected TraversalControl visitGraphQLType(GraphQLSchemaElement node, TraverserContext context) { + SchemaValidationErrorCollector collector = context.getVarFromParents(SchemaValidationErrorCollector.class); + GraphQLSchema schema = context.getVarFromParents(GraphQLSchema.class); + if (node instanceof GraphQLDirectiveContainer) { + GraphQLDirectiveContainer directiveContainer = (GraphQLDirectiveContainer) node; + for (Map.Entry> entry : directiveContainer.getAllDirectivesByName().entrySet()) { + String directiveName = entry.getKey(); + GraphQLDirective directiveDef = schema.getDirective(directiveName); + if (directiveDef != null) { + checkNonRepeatable(collector, directiveContainer, directiveDef, entry.getValue()); + } else { + addError(collector, format("A definition for directive '%s' could not be found", directiveName)); + } + } + } + + return TraversalControl.CONTINUE; + } + + private void checkNonRepeatable(SchemaValidationErrorCollector collector, GraphQLDirectiveContainer directiveContainer, GraphQLDirective directiveDef, List directives) { + if (directiveDef.isNonRepeatable() && directives.size() > 1) { + addNonRepeatableError(collector, directiveContainer, directiveDef.getName(), directives.size()); + } + } + + private void addNonRepeatableError(SchemaValidationErrorCollector collector, GraphQLDirectiveContainer directiveContainer, String name, int howMany) { + addError(collector, format("The directive '%s' on the '%s' called '%s' is a non repeatable directive but has been applied %d times", + name, + directiveContainer.getClass().getSimpleName(), + directiveContainer.getName(), + howMany)); + } + + private void addError(SchemaValidationErrorCollector collector, String message) { + collector.addError(new SchemaValidationError(InvalidAppliedDirective, message)); + } + +} diff --git a/src/main/java/graphql/schema/validation/DefaultValuesAreValid.java b/src/main/java/graphql/schema/validation/DefaultValuesAreValid.java new file mode 100644 index 0000000000..4527973461 --- /dev/null +++ b/src/main/java/graphql/schema/validation/DefaultValuesAreValid.java @@ -0,0 +1,91 @@ +package graphql.schema.validation; + +import graphql.GraphQLContext; +import graphql.execution.NonNullableValueCoercedAsNullException; +import graphql.execution.ValuesResolver; +import graphql.language.Value; +import graphql.schema.CoercingParseValueException; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.InputValueWithState; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.validation.ValidationUtil; + +import java.util.Locale; + +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static java.lang.String.format; + +public class DefaultValuesAreValid extends GraphQLTypeVisitorStub { + + private ValidationUtil validationUtil = new ValidationUtil(); + + private final GraphQLContext graphQLContext = GraphQLContext.getDefault(); + + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + return super.visitGraphQLInputObjectType(node, context); + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField inputObjectField, TraverserContext context) { + if (!inputObjectField.hasSetDefaultValue()) { + return TraversalControl.CONTINUE; + } + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + GraphQLSchema schema = context.getVarFromParents(GraphQLSchema.class); + InputValueWithState defaultValue = inputObjectField.getInputFieldDefaultValue(); + boolean invalid = false; + if (defaultValue.isLiteral() && + !validationUtil.isValidLiteralValue((Value) defaultValue.getValue(), inputObjectField.getType(), schema, graphQLContext, Locale.getDefault())) { + invalid = true; + } else if (defaultValue.isExternal() && + !isValidExternalValue(schema, defaultValue.getValue(), inputObjectField.getType(), graphQLContext)) { + invalid = true; + } + if (invalid) { + String message = format("Invalid default value %s for type %s", defaultValue.getValue(), simplePrint(inputObjectField.getType())); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.InvalidDefaultValue, message)); + } + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument argument, TraverserContext context) { + if (!argument.hasSetDefaultValue()) { + return TraversalControl.CONTINUE; + } + GraphQLSchema schema = context.getVarFromParents(GraphQLSchema.class); + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + InputValueWithState defaultValue = argument.getArgumentDefaultValue(); + boolean invalid = false; + if (defaultValue.isLiteral() && + !validationUtil.isValidLiteralValue((Value) defaultValue.getValue(), argument.getType(), schema, graphQLContext, Locale.getDefault())) { + invalid = true; + } else if (defaultValue.isExternal() && + !isValidExternalValue(schema, defaultValue.getValue(), argument.getType(), graphQLContext)) { + invalid = true; + } + if (invalid) { + String message = format("Invalid default value %s for type %s", defaultValue.getValue(), simplePrint(argument.getType())); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.InvalidDefaultValue, message)); + } + return TraversalControl.CONTINUE; + } + + private boolean isValidExternalValue(GraphQLSchema schema, Object externalValue, GraphQLInputType type, GraphQLContext graphQLContext) { + try { + ValuesResolver.externalValueToInternalValue(schema.getCodeRegistry().getFieldVisibility(), externalValue, type, graphQLContext, Locale.getDefault()); + return true; + } catch (CoercingParseValueException | NonNullableValueCoercedAsNullException e) { + return false; + } + } +} diff --git a/src/main/java/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValid.java b/src/main/java/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValid.java new file mode 100644 index 0000000000..ce619223cc --- /dev/null +++ b/src/main/java/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValid.java @@ -0,0 +1,64 @@ +package graphql.schema.validation; + +import graphql.Directives; +import graphql.Internal; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import static java.lang.String.format; + +/* + From the spec: + The @deprecated directive must not appear on required (non-null without a default) arguments + or input object field definitions. + */ +@Internal +public class DeprecatedInputObjectAndArgumentsAreValid extends GraphQLTypeVisitorStub { + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField inputObjectField, TraverserContext context) { + // There can only be at most one @deprecated, because it is not a repeatable directive + GraphQLAppliedDirective deprecatedDirective = inputObjectField.getAppliedDirective(Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName()); + + if (deprecatedDirective != null && GraphQLTypeUtil.isNonNull(inputObjectField.getType()) && !inputObjectField.hasSetDefaultValue()) { + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) context.getParentNode(); + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + String message = format("Required input field '%s.%s' cannot be deprecated.", inputObjectType.getName(), inputObjectField.getName()); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.RequiredInputFieldCannotBeDeprecated, message)); + } + return TraversalControl.CONTINUE; + } + + // An argument can appear as either a field argument or a directive argument. This visitor will visit both field arguments and directive arguments. + // An applied directive's argument cannot be deprecated. + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument argument, TraverserContext context) { + // There can only be at most one @deprecated, because it is not a repeatable directive + GraphQLAppliedDirective deprecatedDirective = argument.getAppliedDirective(Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName()); + + if (deprecatedDirective != null && GraphQLTypeUtil.isNonNull(argument.getType()) && !argument.hasSetDefaultValue()) { + if (context.getParentNode() instanceof GraphQLFieldDefinition) { + GraphQLFieldDefinition fieldDefinition = (GraphQLFieldDefinition) context.getParentNode(); + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + String message = format("Required argument '%s' on field '%s' cannot be deprecated.", argument.getName(), fieldDefinition.getName()); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.RequiredFieldArgumentCannotBeDeprecated, message)); + } else if (context.getParentNode() instanceof GraphQLDirective) { + GraphQLDirective directive = (GraphQLDirective) context.getParentNode(); + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + String message = format("Required argument '%s' on directive '%s' cannot be deprecated.", argument.getName(), directive.getName()); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.RequiredDirectiveArgumentCannotBeDeprecated, message)); + } + } + return TraversalControl.CONTINUE; + } + +} diff --git a/src/main/java/graphql/schema/validation/InputAndOutputTypesUsedAppropriately.java b/src/main/java/graphql/schema/validation/InputAndOutputTypesUsedAppropriately.java new file mode 100644 index 0000000000..6ee43aef18 --- /dev/null +++ b/src/main/java/graphql/schema/validation/InputAndOutputTypesUsedAppropriately.java @@ -0,0 +1,90 @@ +package graphql.schema.validation; + +import graphql.Internal; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLModifiedType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.function.BiFunction; +import java.util.function.Predicate; + +/** + * Schema validation rule ensuring no input type forms an unbroken non-nullable recursion, + * as such a type would be impossible to satisfy + */ +@Internal +public class InputAndOutputTypesUsedAppropriately extends GraphQLTypeVisitorStub { + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDef, TraverserContext context) { + String typeName = getTypeName((GraphQLType) context.getParentNode()); + String fieldName = typeName + "." + fieldDef.getName(); + SchemaValidationErrorCollector validationErrorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + for (GraphQLArgument argument : fieldDef.getArguments()) { + String argName = fieldName + "." + argument.getName(); + GraphQLInputType argumentType = argument.getType(); + checkIsAllInputTypes(argumentType, validationErrorCollector, argName); + } + checkIsAllOutputTypes(fieldDef.getType(), validationErrorCollector, fieldName); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField fieldDef, TraverserContext context) { + String typeName = getTypeName((GraphQLType) context.getParentNode()); + String fieldName = typeName + "." + fieldDef.getName(); + SchemaValidationErrorCollector validationErrorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + checkIsAllInputTypes(fieldDef.getType(), validationErrorCollector, fieldName); + return TraversalControl.CONTINUE; + } + + private void checkIsAllInputTypes(GraphQLInputType inputType, + SchemaValidationErrorCollector validationErrorCollector, + String argName) { + checkTypeContext(inputType, validationErrorCollector, argName, + typeToCheck -> typeToCheck instanceof GraphQLInputType, + (typeToCheck, path) -> new SchemaValidationError(SchemaValidationErrorType.OutputTypeUsedInInputTypeContext, + String.format("The output type '%s' has been used in an input type context : '%s'", typeToCheck, path))); + } + + private void checkIsAllOutputTypes(GraphQLOutputType outputType, + SchemaValidationErrorCollector validationErrorCollector, + String fieldName) { + checkTypeContext(outputType, validationErrorCollector, fieldName, + typeToCheck -> typeToCheck instanceof GraphQLOutputType, + (typeToCheck, path) -> new SchemaValidationError(SchemaValidationErrorType.InputTypeUsedInOutputTypeContext, + String.format("The input type '%s' has been used in a output type context : '%s'", typeToCheck, path))); + } + + private void checkTypeContext(GraphQLType type, + SchemaValidationErrorCollector validationErrorCollector, + String path, + Predicate typePredicate, + BiFunction errorMaker) { + while (true) { + String typeName = getTypeName(type); + boolean isOk = typePredicate.test(type); + if (!isOk) { + validationErrorCollector.addError(errorMaker.apply(typeName, path)); + } + if (type instanceof GraphQLModifiedType) { + type = ((GraphQLModifiedType) type).getWrappedType(); + } else { + return; + } + } + } + + private String getTypeName(GraphQLType type) { + return GraphQLTypeUtil.simplePrint(type); + } +} diff --git a/src/main/java/graphql/schema/validation/InvalidSchemaException.java b/src/main/java/graphql/schema/validation/InvalidSchemaException.java index a0c169af7c..0740159122 100644 --- a/src/main/java/graphql/schema/validation/InvalidSchemaException.java +++ b/src/main/java/graphql/schema/validation/InvalidSchemaException.java @@ -1,13 +1,24 @@ package graphql.schema.validation; import graphql.GraphQLException; +import graphql.Internal; +import graphql.VisibleForTesting; import java.util.Collection; +@Internal public class InvalidSchemaException extends GraphQLException { + private final Collection errors; + public InvalidSchemaException(Collection errors) { super(buildErrorMsg(errors)); + this.errors = errors; + } + + @VisibleForTesting + Collection getErrors() { + return errors; } private static String buildErrorMsg(Collection errors) { diff --git a/src/main/java/graphql/schema/validation/NoUnbrokenInputCycles.java b/src/main/java/graphql/schema/validation/NoUnbrokenInputCycles.java index ae20520134..22be3f7148 100644 --- a/src/main/java/graphql/schema/validation/NoUnbrokenInputCycles.java +++ b/src/main/java/graphql/schema/validation/NoUnbrokenInputCycles.java @@ -1,5 +1,6 @@ package graphql.schema.validation; +import graphql.Internal; import graphql.schema.GraphQLArgument; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLInputObjectField; @@ -7,11 +8,14 @@ import graphql.schema.GraphQLInputType; import graphql.schema.GraphQLList; import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLSchemaElement; import graphql.schema.GraphQLType; -import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; import java.util.ArrayList; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -23,22 +27,20 @@ * Schema validation rule ensuring no input type forms an unbroken non-nullable recursion, * as such a type would be impossible to satisfy */ -public class NoUnbrokenInputCycles implements SchemaValidationRule { +@Internal +public class NoUnbrokenInputCycles extends GraphQLTypeVisitorStub { @Override - public void check(GraphQLType type, SchemaValidationErrorCollector validationErrorCollector) { - } - - @Override - public void check(GraphQLFieldDefinition fieldDef, SchemaValidationErrorCollector validationErrorCollector) { + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDef, TraverserContext context) { + SchemaValidationErrorCollector validationErrorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); for (GraphQLArgument argument : fieldDef.getArguments()) { GraphQLInputType argumentType = argument.getType(); if (argumentType instanceof GraphQLInputObjectType) { List path = new ArrayList<>(); - path.add(argumentType.getName()); - check((GraphQLInputObjectType) argumentType, new HashSet<>(), path, validationErrorCollector); + check((GraphQLInputObjectType) argumentType, new LinkedHashSet<>(), path, validationErrorCollector); } } + return TraversalControl.CONTINUE; } private void check(GraphQLInputObjectType type, Set seen, List path, SchemaValidationErrorCollector validationErrorCollector) { @@ -54,7 +56,7 @@ private void check(GraphQLInputObjectType type, Set seen, List(path); path.add(field.getName() + "!"); - check((GraphQLInputObjectType) unwrapped, new HashSet<>(seen), path, validationErrorCollector); + check((GraphQLInputObjectType) unwrapped, new LinkedHashSet<>(seen), path, validationErrorCollector); } } } diff --git a/src/main/java/graphql/schema/validation/ObjectsImplementInterfaces.java b/src/main/java/graphql/schema/validation/ObjectsImplementInterfaces.java deleted file mode 100644 index ab4c927fe5..0000000000 --- a/src/main/java/graphql/schema/validation/ObjectsImplementInterfaces.java +++ /dev/null @@ -1,162 +0,0 @@ -package graphql.schema.validation; - -import graphql.schema.GraphQLArgument; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLInterfaceType; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLOutputType; -import graphql.schema.GraphQLType; -import graphql.schema.GraphQLUnionType; - -import java.util.List; -import java.util.Objects; - -import static graphql.schema.GraphQLTypeUtil.getUnwrappedTypeName; -import static graphql.schema.GraphQLTypeUtil.isList; -import static graphql.schema.GraphQLTypeUtil.isNonNull; -import static graphql.schema.GraphQLTypeUtil.unwrapOne; -import static graphql.schema.validation.SchemaValidationErrorType.ObjectDoesNotImplementItsInterfaces; -import static java.lang.String.format; - -/** - * Schema validation rule ensuring object types have all the fields that they need to implement the interfaces - * they say they implement - */ -public class ObjectsImplementInterfaces implements SchemaValidationRule { - - @Override - public void check(GraphQLFieldDefinition fieldDef, SchemaValidationErrorCollector validationErrorCollector) { - } - - @Override - public void check(GraphQLType type, SchemaValidationErrorCollector validationErrorCollector) { - if (type instanceof GraphQLObjectType) { - check((GraphQLObjectType) type, validationErrorCollector); - } - } - - private void check(GraphQLObjectType objectType, SchemaValidationErrorCollector validationErrorCollector) { - List interfaces = objectType.getInterfaces(); - interfaces.forEach(interfaceType -> { - // we have resolved the interfaces at this point and hence the cast is ok - checkObjectImplementsInterface(objectType, (GraphQLInterfaceType) interfaceType, validationErrorCollector); - }); - - } - - // this deliberately has open field visibility here since its validating the schema - // when completely open - private void checkObjectImplementsInterface(GraphQLObjectType objectType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector) { - List fieldDefinitions = interfaceType.getFieldDefinitions(); - for (GraphQLFieldDefinition interfaceFieldDef : fieldDefinitions) { - GraphQLFieldDefinition objectFieldDef = objectType.getFieldDefinition(interfaceFieldDef.getName()); - if (objectFieldDef == null) { - validationErrorCollector.addError( - error(format("object type '%s' does not implement interface '%s' because field '%s' is missing", - objectType.getName(), interfaceType.getName(), interfaceFieldDef.getName()))); - } else { - checkFieldTypeCompatibility(objectType, interfaceType, validationErrorCollector, interfaceFieldDef, objectFieldDef); - } - } - } - - private void checkFieldTypeCompatibility(GraphQLObjectType objectType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) { - String interfaceFieldDefStr = getUnwrappedTypeName(interfaceFieldDef.getType()); - String objectFieldDefStr = getUnwrappedTypeName(objectFieldDef.getType()); - - if (!isCompatible(interfaceFieldDef.getType(), objectFieldDef.getType())) { - validationErrorCollector.addError( - error(format("object type '%s' does not implement interface '%s' because field '%s' is defined as '%s' type and not as '%s' type", - objectType.getName(), interfaceType.getName(), interfaceFieldDef.getName(), objectFieldDefStr, interfaceFieldDefStr))); - } else { - checkFieldArgumentEquivalence(objectType, interfaceType, validationErrorCollector, interfaceFieldDef, objectFieldDef); - } - } - - private void checkFieldArgumentEquivalence(GraphQLObjectType objectTyoe, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) { - List interfaceArgs = interfaceFieldDef.getArguments(); - List objectArgs = objectFieldDef.getArguments(); - if (interfaceArgs.size() != objectArgs.size()) { - validationErrorCollector.addError( - error(format("object type '%s' does not implement interface '%s' because field '%s' has a different number of arguments", - objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName()))); - } else { - for (int i = 0; i < interfaceArgs.size(); i++) { - GraphQLArgument interfaceArg = interfaceArgs.get(i); - GraphQLArgument objectArg = objectArgs.get(i); - - String interfaceArgStr = makeArgStr(interfaceArg); - String objectArgStr = makeArgStr(objectArg); - - boolean same = true; - if (!interfaceArgStr.equals(objectArgStr)) { - same = false; - } - if (!Objects.equals(interfaceArg.getDefaultValue(), objectArg.getDefaultValue())) { - same = false; - } - if (!same) { - validationErrorCollector.addError( - error(format("object type '%s' does not implement interface '%s' because field '%s' argument '%s' is defined differently", - objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName(), interfaceArg.getName()))); - } - - } - } - } - - private String makeArgStr(GraphQLArgument argument) { - // we don't do default value checking because toString of getDefaultValue is not guaranteed to be stable - return argument.getName() + - ":" + - getUnwrappedTypeName(argument.getType()); - - } - - private SchemaValidationError error(String msg) { - return new SchemaValidationError(ObjectDoesNotImplementItsInterfaces, msg); - } - - /** - * @return {@code true} if the specified objectType satisfies the constraintType. - */ - boolean isCompatible(GraphQLOutputType constraintType, GraphQLOutputType objectType) { - if (isSameType(constraintType, objectType)) { - return true; - } else if (constraintType instanceof GraphQLUnionType) { - return objectIsMemberOfUnion((GraphQLUnionType) constraintType, objectType); - } else if (constraintType instanceof GraphQLInterfaceType && objectType instanceof GraphQLObjectType) { - return objectImplementsInterface((GraphQLInterfaceType) constraintType, (GraphQLObjectType) objectType); - } else if (isList(constraintType) && isList(objectType)) { - GraphQLOutputType wrappedConstraintType = (GraphQLOutputType) unwrapOne(constraintType); - GraphQLOutputType wrappedObjectType = (GraphQLOutputType) unwrapOne(objectType); - return isCompatible(wrappedConstraintType, wrappedObjectType); - } else if (isNonNull(objectType)) { - GraphQLOutputType nullableConstraint; - if (isNonNull(constraintType)) { - nullableConstraint = (GraphQLOutputType) unwrapOne(constraintType); - } else { - nullableConstraint = constraintType; - } - GraphQLOutputType nullableObjectType = (GraphQLOutputType) unwrapOne(objectType); - return isCompatible(nullableConstraint, nullableObjectType); - } else { - return false; - } - } - - boolean isSameType(GraphQLOutputType a, GraphQLOutputType b) { - String aDefString = getUnwrappedTypeName(a); - String bDefString = getUnwrappedTypeName(b); - return aDefString.equals(bDefString); - } - - boolean objectImplementsInterface(GraphQLInterfaceType interfaceType, GraphQLObjectType objectType) { - return objectType.getInterfaces().contains(interfaceType); - } - - boolean objectIsMemberOfUnion(GraphQLUnionType unionType, GraphQLOutputType objectType) { - return unionType.getTypes().contains(objectType); - } - -} diff --git a/src/main/java/graphql/schema/validation/OneOfInputObjectRules.java b/src/main/java/graphql/schema/validation/OneOfInputObjectRules.java new file mode 100644 index 0000000000..87e39fc321 --- /dev/null +++ b/src/main/java/graphql/schema/validation/OneOfInputObjectRules.java @@ -0,0 +1,41 @@ +package graphql.schema.validation; + +import graphql.ExperimentalApi; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import static java.lang.String.format; + +/* + * Spec: If the Input Object is a OneOf Input Object then: + * The type of the input field must be nullable. + * The input field must not have a default value. + */ +@ExperimentalApi +public class OneOfInputObjectRules extends GraphQLTypeVisitorStub { + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField inputObjectField, TraverserContext context) { + GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) context.getParentNode(); + if (!inputObjectType.isOneOf()) { + return TraversalControl.CONTINUE; + } + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + // error messages take from the reference implementation + if (inputObjectField.hasSetDefaultValue()) { + String message = format("OneOf input field %s.%s cannot have a default value.", inputObjectType.getName(), inputObjectField.getName()); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.OneOfDefaultValueOnField, message)); + } + + if (GraphQLTypeUtil.isNonNull(inputObjectField.getType())) { + String message = format("OneOf input field %s.%s must be nullable.", inputObjectType.getName(), inputObjectField.getName()); + errorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.OneOfNonNullableField, message)); + } + return TraversalControl.CONTINUE; + } +} diff --git a/src/main/java/graphql/schema/validation/SchemaValidationError.java b/src/main/java/graphql/schema/validation/SchemaValidationError.java index 3860ffe225..55a661e23c 100644 --- a/src/main/java/graphql/schema/validation/SchemaValidationError.java +++ b/src/main/java/graphql/schema/validation/SchemaValidationError.java @@ -1,30 +1,46 @@ package graphql.schema.validation; +import graphql.Internal; + +import java.util.StringJoiner; + import static graphql.Assert.assertNotNull; +@Internal public class SchemaValidationError { - private final SchemaValidationErrorType errorType; + private final SchemaValidationErrorClassification errorClassification; private final String description; - public SchemaValidationError(SchemaValidationErrorType errorType, String description) { - assertNotNull(errorType, "error type can not be null"); + public SchemaValidationError(SchemaValidationErrorType errorClassification, String description) { + assertNotNull(errorClassification, "error classification can not be null"); assertNotNull(description, "error description can not be null"); - this.errorType = errorType; + this.errorClassification = errorClassification; this.description = description; } - public SchemaValidationErrorType getErrorType() { - return errorType; + public SchemaValidationErrorClassification getClassification() { + return errorClassification; } public String getDescription() { return description; } + @Override + public String toString() { + return new StringJoiner(", ", SchemaValidationError.class.getSimpleName() + "[", "]") + .add("errorClassification=" + errorClassification) + .add("description='" + description + "'") + .toString(); + } + @Override public int hashCode() { - return errorType.hashCode() ^ description.hashCode(); + int result = 1; + result = 31 * result + errorClassification.hashCode(); + result = 31 * result + description.hashCode(); + return result; } @Override @@ -36,6 +52,6 @@ public boolean equals(Object other) { return false; } SchemaValidationError that = (SchemaValidationError) other; - return this.errorType.equals(that.errorType) && this.description.equals(that.description); + return this.errorClassification.equals(that.errorClassification) && this.description.equals(that.description); } } diff --git a/src/main/java/graphql/schema/validation/SchemaValidationErrorClassification.java b/src/main/java/graphql/schema/validation/SchemaValidationErrorClassification.java new file mode 100644 index 0000000000..e8a7e6b08a --- /dev/null +++ b/src/main/java/graphql/schema/validation/SchemaValidationErrorClassification.java @@ -0,0 +1,14 @@ +package graphql.schema.validation; + + +import graphql.PublicApi; + + +/** + * Error in graphql schema validation can have a classification, + * and all the error classifications implement this interface. + */ +@PublicApi +public interface SchemaValidationErrorClassification { + +} diff --git a/src/main/java/graphql/schema/validation/SchemaValidationErrorCollector.java b/src/main/java/graphql/schema/validation/SchemaValidationErrorCollector.java index e8ccb3742d..cde3ed416e 100644 --- a/src/main/java/graphql/schema/validation/SchemaValidationErrorCollector.java +++ b/src/main/java/graphql/schema/validation/SchemaValidationErrorCollector.java @@ -1,8 +1,11 @@ package graphql.schema.validation; +import graphql.Internal; + import java.util.LinkedHashSet; import java.util.Set; +@Internal public class SchemaValidationErrorCollector { private final LinkedHashSet errors = new LinkedHashSet<>(); @@ -17,7 +20,7 @@ public Set getErrors() { public boolean containsValidationError(SchemaValidationErrorType validationErrorType) { for (SchemaValidationError validationError : errors) { - if (validationError.getErrorType() == validationErrorType) return true; + if (validationError.getClassification() == validationErrorType) return true; } return false; } diff --git a/src/main/java/graphql/schema/validation/SchemaValidationErrorType.java b/src/main/java/graphql/schema/validation/SchemaValidationErrorType.java index 6d65284079..b8392b18d7 100644 --- a/src/main/java/graphql/schema/validation/SchemaValidationErrorType.java +++ b/src/main/java/graphql/schema/validation/SchemaValidationErrorType.java @@ -1,7 +1,28 @@ package graphql.schema.validation; -public enum SchemaValidationErrorType { +import graphql.Internal; + +@Internal +public enum SchemaValidationErrorType implements SchemaValidationErrorClassification{ UnbrokenInputCycle, - ObjectDoesNotImplementItsInterfaces + ObjectDoesNotImplementItsInterfaces, + ImplementingTypeLackOfFieldError, + InputObjectTypeLackOfFieldError, + EnumLackOfValueError, + UnionTypeLackOfTypeError, + InvalidUnionMemberTypeError, + InvalidCustomizedNameError, + NonNullWrapNonNullError, + RepetitiveElementError, + InvalidDefaultValue, + InvalidAppliedDirectiveArgument, + InvalidAppliedDirective, + OutputTypeUsedInInputTypeContext, + InputTypeUsedInOutputTypeContext, + OneOfDefaultValueOnField, + OneOfNonNullableField, + RequiredInputFieldCannotBeDeprecated, + RequiredFieldArgumentCannotBeDeprecated, + RequiredDirectiveArgumentCannotBeDeprecated } diff --git a/src/main/java/graphql/schema/validation/SchemaValidationRule.java b/src/main/java/graphql/schema/validation/SchemaValidationRule.java deleted file mode 100644 index cd53cbc09b..0000000000 --- a/src/main/java/graphql/schema/validation/SchemaValidationRule.java +++ /dev/null @@ -1,11 +0,0 @@ -package graphql.schema.validation; - -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLType; - -public interface SchemaValidationRule { - - void check(GraphQLFieldDefinition fieldDef, SchemaValidationErrorCollector validationErrorCollector); - - void check(GraphQLType type, SchemaValidationErrorCollector validationErrorCollector); -} diff --git a/src/main/java/graphql/schema/validation/SchemaValidator.java b/src/main/java/graphql/schema/validation/SchemaValidator.java index bfdb981abf..1f676fb77e 100644 --- a/src/main/java/graphql/schema/validation/SchemaValidator.java +++ b/src/main/java/graphql/schema/validation/SchemaValidator.java @@ -1,75 +1,45 @@ package graphql.schema.validation; import graphql.Internal; -import graphql.schema.GraphQLFieldDefinition; -import graphql.schema.GraphQLFieldsContainer; -import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLSchema; -import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.SchemaTraverser; import java.util.ArrayList; -import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; @Internal public class SchemaValidator { - private final Set processed = new HashSet<>(); - private List rules = new ArrayList<>(); + private final List rules = new ArrayList<>(); public SchemaValidator() { rules.add(new NoUnbrokenInputCycles()); - rules.add(new ObjectsImplementInterfaces()); + rules.add(new TypesImplementInterfaces()); + rules.add(new TypeAndFieldRule()); + rules.add(new DefaultValuesAreValid()); + rules.add(new AppliedDirectivesAreValid()); + rules.add(new AppliedDirectiveArgumentsAreValid()); + rules.add(new InputAndOutputTypesUsedAppropriately()); + rules.add(new OneOfInputObjectRules()); + rules.add(new DeprecatedInputObjectAndArgumentsAreValid()); } - SchemaValidator(List rules) { - this.rules = rules; - } - - public List getRules() { + public List getRules() { return rules; } public Set validateSchema(GraphQLSchema schema) { SchemaValidationErrorCollector validationErrorCollector = new SchemaValidationErrorCollector(); - - checkTypes(schema, validationErrorCollector); - - traverse(schema.getQueryType(), rules, validationErrorCollector); - if (schema.isSupportingMutations()) { - traverse(schema.getMutationType(), rules, validationErrorCollector); - } - if (schema.isSupportingSubscriptions()) { - traverse(schema.getSubscriptionType(), rules, validationErrorCollector); - } + Map, Object> rootVars = new LinkedHashMap<>(); + rootVars.put(GraphQLSchema.class, schema); + rootVars.put(SchemaValidationErrorCollector.class, validationErrorCollector); + new SchemaTraverser().depthFirstFullSchema(rules, schema, rootVars); return validationErrorCollector.getErrors(); } - private void checkTypes(GraphQLSchema schema, SchemaValidationErrorCollector validationErrorCollector) { - List types = schema.getAllTypesAsList(); - types.forEach(type -> { - for (SchemaValidationRule rule : rules) { - rule.check(type, validationErrorCollector); - } - }); - } - - private void traverse(GraphQLOutputType root, List rules, SchemaValidationErrorCollector validationErrorCollector) { - if (processed.contains(root)) { - return; - } - processed.add(root); - if (root instanceof GraphQLFieldsContainer) { - // this deliberately has open field visibility here since its validating the schema - // when completely open - for (GraphQLFieldDefinition fieldDefinition : ((GraphQLFieldsContainer) root).getFieldDefinitions()) { - for (SchemaValidationRule rule : rules) { - rule.check(fieldDefinition, validationErrorCollector); - } - traverse(fieldDefinition.getType(), rules, validationErrorCollector); - } - } - } } diff --git a/src/main/java/graphql/schema/validation/TypeAndFieldRule.java b/src/main/java/graphql/schema/validation/TypeAndFieldRule.java new file mode 100644 index 0000000000..84a768479d --- /dev/null +++ b/src/main/java/graphql/schema/validation/TypeAndFieldRule.java @@ -0,0 +1,233 @@ +package graphql.schema.validation; + +import graphql.collect.ImmutableKit; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.util.FpKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import static graphql.introspection.Introspection.INTROSPECTION_SYSTEM_FIELDS; +import static graphql.introspection.Introspection.isIntrospectionTypes; +import static graphql.schema.idl.ScalarInfo.isGraphqlSpecifiedScalar; + +/** + * The validation about GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType, GraphQLEnumType, GraphQLInputObjectType, GraphQLScalarType. + *

      + *
    • Types must define one or more fields;
    • + *
    • Enum type must define one or more enum values;
    • + *
    • Union type must include one or more unique member types;
    • + *
    • The member types of a Union type must all be Object base types;
    • + *
    • Non‐Null type must not wrap another Non‐Null type;
    • + *
    • Invalid name begin with "__" (two underscores).
    • + *
    + *

    + * details in https://spec.graphql.org/June2018/#sec-Type-System + */ +public class TypeAndFieldRule extends GraphQLTypeVisitorStub { + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType type, TraverserContext context) { + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + validateContainsField((GraphQLFieldsContainer) type, errorCollector); + return super.visitGraphQLInterfaceType(type, context); + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType type, TraverserContext context) { + if (isIntrospectionTypes(type)) { + return TraversalControl.CONTINUE; + } + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + validateContainsField((GraphQLFieldsContainer) type, errorCollector); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType type, TraverserContext context) { + if (isIntrospectionTypes(type)) { + return TraversalControl.CONTINUE; + } + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + validateUnion((GraphQLUnionType) type, errorCollector); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType type, TraverserContext context) { + if (isIntrospectionTypes(type)) { + return TraversalControl.CONTINUE; + } + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + validateEnum((GraphQLEnumType) type, errorCollector); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType type, TraverserContext context) { + if (isIntrospectionTypes(type)) { + return TraversalControl.CONTINUE; + } + SchemaValidationErrorCollector errorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + validateInputObject((GraphQLInputObjectType) type, errorCollector); + return TraversalControl.CONTINUE; + } + + + private void validateContainsField(GraphQLFieldsContainer type, SchemaValidationErrorCollector errorCollector) { + List fieldDefinitions = type.getFieldDefinitions(); + if (fieldDefinitions == null || fieldDefinitions.size() == 0) { + SchemaValidationError validationError = new SchemaValidationError(SchemaValidationErrorType.ImplementingTypeLackOfFieldError, String.format("\"%s\" must define one or more fields.", type.getName())); + errorCollector.addError(validationError); + return; + } + + for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { + validateFieldDefinition(type.getName(), fieldDefinition, errorCollector); + } + } + + private void validateInputObject(GraphQLInputObjectType type, SchemaValidationErrorCollector errorCollector) { + List inputObjectFields = type.getFields(); + if (inputObjectFields == null || inputObjectFields.size() == 0) { + SchemaValidationError validationError = new SchemaValidationError(SchemaValidationErrorType.InputObjectTypeLackOfFieldError, String.format("\"%s\" must define one or more fields.", type.getName())); + errorCollector.addError(validationError); + return; + } + + for (GraphQLInputObjectField inputObjectField : inputObjectFields) { + validateInputFieldDefinition(type.getName(), inputObjectField, errorCollector); + } + } + + private void validateUnion(GraphQLUnionType type, SchemaValidationErrorCollector errorCollector) { + List memberTypes = type.getTypes(); + if (memberTypes.size() == 0) { + SchemaValidationError validationError = + new SchemaValidationError(SchemaValidationErrorType.UnionTypeLackOfTypeError, String.format("Union type \"%s\" must include one or more unique member types.", type.getName())); + errorCollector.addError(validationError); + } + + Set typeNames = new HashSet<>(); + for (GraphQLNamedOutputType memberType : type.getTypes()) { + String typeName = memberType.getName(); +// GraphQLNamedType graphQLNamedType = schemaTypeHolder.get(typeName); + if (!(memberType instanceof GraphQLObjectType)) { + SchemaValidationError validationError = + new SchemaValidationError(SchemaValidationErrorType.InvalidUnionMemberTypeError, String.format("The member types of a Union type must all be Object base types. member type \"%s\" in Union \"%s\" is invalid.", memberType.getName(), type.getName())); + errorCollector.addError(validationError); + } + if (typeNames.contains(typeName)) { + SchemaValidationError validationError = + new SchemaValidationError(SchemaValidationErrorType.RepetitiveElementError, String.format("The member types of a Union type must be unique. member type \"%s\" in Union \"%s\" is not unique.", memberType.getName(), type.getName())); + errorCollector.addError(validationError); + } + typeNames.add(typeName); + } + } + + private void validateEnum(GraphQLEnumType type, SchemaValidationErrorCollector errorCollector) { + List enumValueDefinitions = type.getValues(); + if (enumValueDefinitions == null || enumValueDefinitions.size() == 0) { + SchemaValidationError validationError = new SchemaValidationError(SchemaValidationErrorType.EnumLackOfValueError, String.format("Enum type \"%s\" must define one or more enum values.", type.getName())); + errorCollector.addError(validationError); + } else { + for (GraphQLEnumValueDefinition enumValueDefinition : enumValueDefinitions) { + assertEnumValueDefinitionName(type.getName(), enumValueDefinition.getName(), errorCollector); + } + } + + } + + private void validateFieldDefinition(String typeName, GraphQLFieldDefinition fieldDefinition, SchemaValidationErrorCollector errorCollector) { + assertFieldName(typeName, fieldDefinition.getName(), errorCollector); + assertNonNullType(fieldDefinition.getType(), errorCollector); + + List fieldDefinitionArguments = fieldDefinition.getArguments(); + for (GraphQLArgument fieldDefinitionArgument : fieldDefinitionArguments) { + validateFieldDefinitionArgument(typeName, fieldDefinition.getName(), fieldDefinitionArgument, errorCollector); + } + } + + private void validateInputFieldDefinition(String typeName, GraphQLInputObjectField inputObjectField, SchemaValidationErrorCollector errorCollector) { + assertFieldName(typeName, inputObjectField.getName(), errorCollector); + assertNonNullType(inputObjectField.getType(), errorCollector); + } + + private void validateFieldDefinitionArgument(String typeName, String fieldName, GraphQLArgument argument, SchemaValidationErrorCollector errorCollector) { + assertArgumentName(typeName, fieldName, argument.getName(), errorCollector); + assertNonNullType(argument.getType(), errorCollector); + } + + private void assertArgumentName(String typeName, String fieldName, String argumentName, SchemaValidationErrorCollector errorCollector) { + if (argumentName.length() >= 2 && argumentName.startsWith("__")) { + SchemaValidationError schemaValidationError = new SchemaValidationError(SchemaValidationErrorType.InvalidCustomizedNameError, + String.format("Argument name \"%s\" in \"%s-%s\" must not begin with \"__\", which is reserved by GraphQL introspection.", argumentName, typeName, fieldName)); + errorCollector.addError(schemaValidationError); + } + } + + private void assertEnumValueDefinitionName(String typeName, String enumValueDefinitionName, SchemaValidationErrorCollector errorCollector) { + if (enumValueDefinitionName.length() >= 2 && enumValueDefinitionName.startsWith("__")) { + SchemaValidationError schemaValidationError = new SchemaValidationError(SchemaValidationErrorType.InvalidCustomizedNameError, + String.format("EnumValueDefinition \"%s\" in \"%s\" must not begin with \"__\", which is reserved by GraphQL introspection.", enumValueDefinitionName, typeName)); + errorCollector.addError(schemaValidationError); + } + } + + private void assertNonNullType(GraphQLType type, SchemaValidationErrorCollector errorCollector) { + if (type instanceof GraphQLNonNull && ((GraphQLNonNull) type).getWrappedType() instanceof GraphQLNonNull) { + SchemaValidationError schemaValidationError = new SchemaValidationError(SchemaValidationErrorType.NonNullWrapNonNullError, + String.format("Non‐Null type must not wrap another Non‐Null type: \"%s\" is invalid.", GraphQLTypeUtil.simplePrint(type))); + errorCollector.addError(schemaValidationError); + } + } + + private List filterBuiltInTypes(List graphQLNamedTypes) { + if (graphQLNamedTypes == null || graphQLNamedTypes.isEmpty()) { + return ImmutableKit.emptyList(); + } + + Predicate filterFunction = namedType -> { + if (isIntrospectionTypes(namedType)) { + return false; + } + return !(namedType instanceof GraphQLScalarType) || !isGraphqlSpecifiedScalar((GraphQLScalarType) namedType); + }; + + return FpKit.filterList(graphQLNamedTypes, filterFunction); + } + + + private void assertFieldName(String typeName, String fieldName, SchemaValidationErrorCollector errorCollector) { + if (INTROSPECTION_SYSTEM_FIELDS.contains(fieldName)) { + return; + } + if (fieldName.length() >= 2 && fieldName.startsWith("__")) { + SchemaValidationError schemaValidationError = new SchemaValidationError(SchemaValidationErrorType.InvalidCustomizedNameError, + String.format("\"%s\" in \"%s\" must not begin with \"__\", which is reserved by GraphQL introspection.", fieldName, typeName)); + errorCollector.addError(schemaValidationError); + } + } +} \ No newline at end of file diff --git a/src/main/java/graphql/schema/validation/TypesImplementInterfaces.java b/src/main/java/graphql/schema/validation/TypesImplementInterfaces.java new file mode 100644 index 0000000000..2717ed8e46 --- /dev/null +++ b/src/main/java/graphql/schema/validation/TypesImplementInterfaces.java @@ -0,0 +1,234 @@ +package graphql.schema.validation; + +import graphql.GraphQLContext; +import graphql.Internal; +import graphql.execution.ValuesResolver; +import graphql.language.Value; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLImplementingType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNonNull; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.util.FpKit; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static graphql.collect.ImmutableKit.map; +import static graphql.language.AstPrinter.printAst; +import static graphql.schema.GraphQLTypeUtil.isList; +import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.schema.GraphQLTypeUtil.unwrapOne; +import static graphql.schema.validation.SchemaValidationErrorType.ObjectDoesNotImplementItsInterfaces; +import static java.lang.String.format; + +/** + * Schema validation rule ensuring object and interface types have all the fields that they need to + * implement the interfaces they say they implement. + */ +@Internal +public class TypesImplementInterfaces extends GraphQLTypeVisitorStub { + private static final Map, String> TYPE_OF_MAP = new HashMap<>(); + + static { + TYPE_OF_MAP.put(GraphQLObjectType.class, "object"); + TYPE_OF_MAP.put(GraphQLInterfaceType.class, "interface"); + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType type, TraverserContext context) { + SchemaValidationErrorCollector validationErrorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + check((GraphQLImplementingType) type, validationErrorCollector); + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType type, TraverserContext context) { + SchemaValidationErrorCollector validationErrorCollector = context.getVarFromParents(SchemaValidationErrorCollector.class); + check((GraphQLImplementingType) type, validationErrorCollector); + return TraversalControl.CONTINUE; + } + + + private void check(GraphQLImplementingType implementingType, SchemaValidationErrorCollector validationErrorCollector) { + List interfaces = implementingType.getInterfaces(); + interfaces.forEach(interfaceType -> { + // we have resolved the interfaces at this point and hence the cast is ok + checkObjectImplementsInterface(implementingType, (GraphQLInterfaceType) interfaceType, validationErrorCollector); + }); + + } + + // this deliberately has open field visibility here since it's validating the schema + // when completely open + private void checkObjectImplementsInterface(GraphQLImplementingType implementingType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector) { + List fieldDefinitions = interfaceType.getFieldDefinitions(); + for (GraphQLFieldDefinition interfaceFieldDef : fieldDefinitions) { + GraphQLFieldDefinition objectFieldDef = implementingType.getFieldDefinition(interfaceFieldDef.getName()); + if (objectFieldDef == null) { + validationErrorCollector.addError( + error(format("%s type '%s' does not implement interface '%s' because field '%s' is missing", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName(), interfaceFieldDef.getName()))); + } else { + checkFieldTypeCompatibility(implementingType, interfaceType, validationErrorCollector, interfaceFieldDef, objectFieldDef); + } + } + + checkTransitiveImplementations(implementingType, interfaceType, validationErrorCollector); + } + + private void checkTransitiveImplementations(GraphQLImplementingType implementingType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector) { + List implementedInterfaces = implementingType.getInterfaces(); + interfaceType.getInterfaces().forEach(transitiveInterface -> { + if (transitiveInterface.equals(implementingType)) { + validationErrorCollector.addError( + error(format("%s type '%s' cannot implement '%s' because that would result on a circular reference", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName())) + ); + } else if (!implementedInterfaces.contains(transitiveInterface)) { + validationErrorCollector.addError( + error(format("%s type '%s' must implement '%s' because it is implemented by '%s'", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), transitiveInterface.getName(), interfaceType.getName()))); + } + }); + } + + private void checkFieldTypeCompatibility(GraphQLImplementingType implementingType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) { + String interfaceFieldDefStr = simplePrint(interfaceFieldDef.getType()); + String objectFieldDefStr = simplePrint(objectFieldDef.getType()); + + if (!isCompatible(interfaceFieldDef.getType(), objectFieldDef.getType())) { + validationErrorCollector.addError( + error(format("%s type '%s' does not implement interface '%s' because field '%s' is defined as '%s' type and not as '%s' type", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName(), interfaceFieldDef.getName(), objectFieldDefStr, interfaceFieldDefStr))); + } else { + checkFieldArgumentEquivalence(implementingType, interfaceType, validationErrorCollector, interfaceFieldDef, objectFieldDef); + } + } + + private void checkFieldArgumentEquivalence(GraphQLImplementingType implementingType, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) { + List interfaceArgs = interfaceFieldDef.getArguments(); + List objectArgs = objectFieldDef.getArguments(); + + Map interfaceArgsByName = FpKit.getByName(interfaceArgs, GraphQLArgument::getName); + List objectArgsNames = map(objectArgs, GraphQLArgument::getName); + + if (!objectArgsNames.containsAll(interfaceArgsByName.keySet())) { + final String missingArgsNames = interfaceArgsByName.keySet().stream() + .filter(name -> !objectArgsNames.contains(name)) + .collect(Collectors.joining(", ")); + + validationErrorCollector.addError( + error(format("%s type '%s' does not implement interface '%s' because field '%s' is missing argument(s): '%s'", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName(), interfaceFieldDef.getName(), missingArgsNames))); + } else { + objectArgs.forEach(objectArg -> { + GraphQLArgument interfaceArg = interfaceArgsByName.get(objectArg.getName()); + + if (interfaceArg == null) { + if (objectArg.getType() instanceof GraphQLNonNull) { + validationErrorCollector.addError( + error(format("%s type '%s' field '%s' defines an additional non-optional argument '%s' which is not allowed because field is also defined in interface '%s'", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), objectFieldDef.getName(), objectArg.getName(), interfaceType.getName()))); + } + } else { + String interfaceArgStr = makeArgStr(objectArg); + String objectArgStr = makeArgStr(interfaceArg); + + boolean same = true; + if (!interfaceArgStr.equals(objectArgStr)) { + same = false; + } + if (objectArg.hasSetDefaultValue() && interfaceArg.hasSetDefaultValue()) { + Value objectDefaultValue = ValuesResolver.valueToLiteral(objectArg.getArgumentDefaultValue(), objectArg.getType(), GraphQLContext.getDefault(), Locale.getDefault()); + Value interfaceDefaultValue = ValuesResolver.valueToLiteral(interfaceArg.getArgumentDefaultValue(), interfaceArg.getType(), GraphQLContext.getDefault(), Locale.getDefault()); + if (!Objects.equals(printAst(objectDefaultValue), printAst(interfaceDefaultValue))) { + same = false; + } + } else if (objectArg.hasSetDefaultValue() || interfaceArg.hasSetDefaultValue()) { + same = false; + } + if (!same) { + validationErrorCollector.addError( + error(format("%s type '%s' does not implement interface '%s' because field '%s' argument '%s' is defined differently", + TYPE_OF_MAP.get(implementingType.getClass()), implementingType.getName(), interfaceType.getName(), interfaceFieldDef.getName(), objectArg.getName()))); + } + } + }); + } + } + + private String makeArgStr(GraphQLArgument argument) { + // we don't do default value checking because toString of getDefaultValue is not guaranteed to be stable + return argument.getName() + + ":" + + simplePrint(argument.getType()); + + } + + private SchemaValidationError error(String msg) { + return new SchemaValidationError(ObjectDoesNotImplementItsInterfaces, msg); + } + + /** + * @return {@code true} if the specified implementingType satisfies the constraintType. + */ + boolean isCompatible(GraphQLOutputType constraintType, GraphQLOutputType objectType) { + if (isSameType(constraintType, objectType)) { + return true; + } else if (constraintType instanceof GraphQLUnionType) { + return objectIsMemberOfUnion((GraphQLUnionType) constraintType, objectType); + } else if (constraintType instanceof GraphQLInterfaceType && objectType instanceof GraphQLObjectType) { + return objectImplementsInterface((GraphQLInterfaceType) constraintType, (GraphQLObjectType) objectType); + } else if (constraintType instanceof GraphQLInterfaceType && objectType instanceof GraphQLInterfaceType) { + return interfaceImplementsInterface((GraphQLInterfaceType) constraintType, (GraphQLInterfaceType) objectType); + } else if (isList(constraintType) && isList(objectType)) { + GraphQLOutputType wrappedConstraintType = (GraphQLOutputType) unwrapOne(constraintType); + GraphQLOutputType wrappedObjectType = (GraphQLOutputType) unwrapOne(objectType); + return isCompatible(wrappedConstraintType, wrappedObjectType); + } else if (isNonNull(objectType)) { + GraphQLOutputType nullableConstraint; + if (isNonNull(constraintType)) { + nullableConstraint = (GraphQLOutputType) unwrapOne(constraintType); + } else { + nullableConstraint = constraintType; + } + GraphQLOutputType nullableObjectType = (GraphQLOutputType) unwrapOne(objectType); + return isCompatible(nullableConstraint, nullableObjectType); + } else { + return false; + } + } + + boolean isSameType(GraphQLOutputType a, GraphQLOutputType b) { + String aDefString = simplePrint(a); + String bDefString = simplePrint(b); + return aDefString.equals(bDefString); + } + + boolean objectImplementsInterface(GraphQLInterfaceType interfaceType, GraphQLObjectType objectType) { + return objectType.getInterfaces().contains(interfaceType); + } + + boolean interfaceImplementsInterface(GraphQLInterfaceType interfaceType, GraphQLInterfaceType implementingType) { + return implementingType.getInterfaces().contains(interfaceType); + } + + boolean objectIsMemberOfUnion(GraphQLUnionType unionType, GraphQLOutputType objectType) { + return unionType.getTypes().contains(objectType); + } + +} diff --git a/src/main/java/graphql/schema/visibility/BlockedFields.java b/src/main/java/graphql/schema/visibility/BlockedFields.java index 02967ab501..937d029d83 100644 --- a/src/main/java/graphql/schema/visibility/BlockedFields.java +++ b/src/main/java/graphql/schema/visibility/BlockedFields.java @@ -1,6 +1,8 @@ package graphql.schema.visibility; +import graphql.Internal; import graphql.PublicApi; +import graphql.collect.ImmutableKit; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; import graphql.schema.GraphQLInputFieldsContainer; @@ -10,7 +12,6 @@ import java.util.Collection; import java.util.List; import java.util.regex.Pattern; -import java.util.stream.Collectors; /** * This helper class will take a list of regular expressions and match them against the fully qualified name @@ -24,15 +25,18 @@ public class BlockedFields implements GraphqlFieldVisibility { private final List patterns; - public BlockedFields(List patterns) { + /** + * @param patterns the blocked field patterns + */ + @Internal + private BlockedFields(List patterns) { this.patterns = patterns; } @Override public List getFieldDefinitions(GraphQLFieldsContainer fieldsContainer) { - return fieldsContainer.getFieldDefinitions().stream() - .filter(fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName()))) - .collect(Collectors.toList()); + return ImmutableKit.filter(fieldsContainer.getFieldDefinitions(), + fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName()))); } @Override @@ -48,9 +52,8 @@ public GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsCo @Override public List getFieldDefinitions(GraphQLInputFieldsContainer fieldsContainer) { - return fieldsContainer.getFieldDefinitions().stream() - .filter(fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName()))) - .collect(Collectors.toList()); + return ImmutableKit.filter(fieldsContainer.getFieldDefinitions(), + fieldDefinition -> !block(mkFQN(fieldsContainer.getName(), fieldDefinition.getName()))); } @Override diff --git a/src/main/java/graphql/schema/visibility/DefaultGraphqlFieldVisibility.java b/src/main/java/graphql/schema/visibility/DefaultGraphqlFieldVisibility.java index c7ff878804..d918d818ff 100644 --- a/src/main/java/graphql/schema/visibility/DefaultGraphqlFieldVisibility.java +++ b/src/main/java/graphql/schema/visibility/DefaultGraphqlFieldVisibility.java @@ -1,5 +1,6 @@ package graphql.schema.visibility; +import graphql.PublicApi; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; import graphql.schema.GraphQLInputFieldsContainer; @@ -10,6 +11,7 @@ /** * The default field visibility of graphql-java is that everything is visible */ +@PublicApi public class DefaultGraphqlFieldVisibility implements GraphqlFieldVisibility { public static final DefaultGraphqlFieldVisibility DEFAULT_FIELD_VISIBILITY = new DefaultGraphqlFieldVisibility(); diff --git a/src/main/java/graphql/schema/visibility/GraphqlFieldVisibility.java b/src/main/java/graphql/schema/visibility/GraphqlFieldVisibility.java index a677f0b3d7..91a9323280 100644 --- a/src/main/java/graphql/schema/visibility/GraphqlFieldVisibility.java +++ b/src/main/java/graphql/schema/visibility/GraphqlFieldVisibility.java @@ -31,7 +31,7 @@ public interface GraphqlFieldVisibility { * @param fieldsContainer the type in play * @param fieldName the name of the desired field * - * @return a {@link graphql.schema.GraphQLFieldDefinition} or null if its not visible + * @return a {@link graphql.schema.GraphQLFieldDefinition} or null if it's not visible */ GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsContainer, String fieldName); @@ -53,7 +53,7 @@ default List getFieldDefinitions(GraphQLInputFieldsCont * @param fieldsContainer the type in play * @param fieldName the name of the desired field * - * @return a {@link graphql.schema.GraphQLInputObjectField} or null if its not visible + * @return a {@link graphql.schema.GraphQLInputObjectField} or null if it's not visible */ default GraphQLInputObjectField getFieldDefinition(GraphQLInputFieldsContainer fieldsContainer, String fieldName) { return fieldsContainer.getFieldDefinition(fieldName); diff --git a/src/main/java/graphql/schema/visibility/NoIntrospectionGraphqlFieldVisibility.java b/src/main/java/graphql/schema/visibility/NoIntrospectionGraphqlFieldVisibility.java index 56af59fa1d..62aa16bbe0 100644 --- a/src/main/java/graphql/schema/visibility/NoIntrospectionGraphqlFieldVisibility.java +++ b/src/main/java/graphql/schema/visibility/NoIntrospectionGraphqlFieldVisibility.java @@ -1,5 +1,6 @@ package graphql.schema.visibility; +import graphql.PublicApi; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; @@ -9,11 +10,17 @@ /** * This field visibility will prevent Introspection queries from being performed. Technically this puts your - * system in contravention of the specification - http://facebook.github.io/graphql/#sec-Introspection but some - * production systems want this lock down in place. + * system in contravention of the specification + * but some production systems want this lock down in place. + * + * @deprecated This is no longer the best way to prevent Introspection - {@link graphql.introspection.Introspection#enabledJvmWide(boolean)} + * can be used instead */ +@PublicApi +@Deprecated(since = "2024-03-16") public class NoIntrospectionGraphqlFieldVisibility implements GraphqlFieldVisibility { + @Deprecated(since = "2024-03-16") public static NoIntrospectionGraphqlFieldVisibility NO_INTROSPECTION_FIELD_VISIBILITY = new NoIntrospectionGraphqlFieldVisibility(); diff --git a/src/main/java/graphql/schema/visitor/GraphQLSchemaTraversalControl.java b/src/main/java/graphql/schema/visitor/GraphQLSchemaTraversalControl.java new file mode 100644 index 0000000000..7020f088cc --- /dev/null +++ b/src/main/java/graphql/schema/visitor/GraphQLSchemaTraversalControl.java @@ -0,0 +1,81 @@ +package graphql.schema.visitor; + +import graphql.PublicApi; +import graphql.schema.GraphQLSchemaElement; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; +import graphql.util.TreeTransformerUtil; + +/** + * This indicates what traversal control to apply during the visitation + * and can be created via calls to methods like {@link GraphQLSchemaVisitorEnvironment#ok()} + * or {@link GraphQLSchemaVisitorEnvironment#changeNode(GraphQLSchemaElement)} say + */ +@PublicApi +public class GraphQLSchemaTraversalControl { + private final GraphQLSchemaElement element; + private final Control control; + + enum Control { + CONTINUE(TraversalControl.CONTINUE), + QUIT(TraversalControl.QUIT), + CHANGE(TraversalControl.CONTINUE), + DELETE(TraversalControl.CONTINUE), + INSERT_BEFORE(TraversalControl.CONTINUE), + INSERT_AFTER(TraversalControl.CONTINUE); + + private final TraversalControl traversalControl; + + Control(TraversalControl traversalControl) { + this.traversalControl = traversalControl; + } + + public TraversalControl toTraversalControl() { + return traversalControl; + } + } + + static final GraphQLSchemaTraversalControl CONTINUE = new GraphQLSchemaTraversalControl(Control.CONTINUE, null); + static final GraphQLSchemaTraversalControl QUIT = new GraphQLSchemaTraversalControl(Control.QUIT, null); + static final GraphQLSchemaTraversalControl DELETE = new GraphQLSchemaTraversalControl(Control.DELETE, null); + + GraphQLSchemaTraversalControl(Control control, GraphQLSchemaElement element) { + this.element = element; + this.control = control; + } + + GraphQLSchemaElement getElement() { + return element; + } + + Control getControl() { + return control; + } + + boolean isAbortive() { + return control == Control.QUIT; + } + + boolean isMutative() { + return control == Control.DELETE || control == Control.CHANGE || control == Control.INSERT_AFTER || control == Control.INSERT_BEFORE; + } + + TraversalControl toTraversalControl(TraverserContext context) { + if (control == Control.CONTINUE || control == Control.QUIT) { + return control.toTraversalControl(); + } + if (control == Control.DELETE) { + TreeTransformerUtil.deleteNode(context); + } + if (control == Control.CHANGE) { + TreeTransformerUtil.changeNode(context, element); + } + if (control == Control.INSERT_AFTER) { + TreeTransformerUtil.insertAfter(context, element); + } + if (control == Control.INSERT_BEFORE) { + TreeTransformerUtil.insertAfter(context, element); + } + return TraversalControl.CONTINUE; + } +} diff --git a/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitor.java b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitor.java new file mode 100644 index 0000000000..380ce8da08 --- /dev/null +++ b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitor.java @@ -0,0 +1,326 @@ +package graphql.schema.visitor; + +import graphql.PublicSpi; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedInputType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.GraphQLUnionType; + +/** + * This visitor interface offers more "smarts" above {@link GraphQLTypeVisitor} and aims to be easier to use + * with more type safe helpers. + *

    + * You would use it places that need a {@link GraphQLTypeVisitor} by doing `new GraphQLSchemaVisitor() { ...}.toTypeVisitor()` + */ +@PublicSpi +public interface GraphQLSchemaVisitor { + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLAppliedDirective} + */ + interface AppliedDirectiveVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + GraphQLDirectiveContainer getContainer(); + } + + /** + * Called when visiting a GraphQLAppliedDirective in the schema + * + * @param appliedDirective the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitAppliedDirective(GraphQLAppliedDirective appliedDirective, AppliedDirectiveVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLAppliedDirectiveArgument} + */ + interface AppliedDirectiveArgumentVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + + GraphQLAppliedDirective getContainer(); + + /** + * @return this elements type that has been unwrapped of {@link graphql.schema.GraphQLNonNull} and {@link graphql.schema.GraphQLList} + */ + GraphQLNamedInputType getUnwrappedType(); + } + + /** + * Called when visiting a {@link GraphQLAppliedDirectiveArgument} in the schema + * + * @param appliedDirectiveArgument the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument appliedDirectiveArgument, AppliedDirectiveArgumentVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLArgument} + */ + interface ArgumentVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + /** + * @return either a {@link GraphQLFieldDefinition} or a {@link graphql.schema.GraphQLDirective} + */ + GraphQLNamedSchemaElement getContainer(); + + /** + * @return this elements type that has been unwrapped of {@link graphql.schema.GraphQLNonNull} and {@link graphql.schema.GraphQLList} + */ + GraphQLNamedInputType getUnwrappedType(); + } + + /** + * Called when visiting a {@link GraphQLArgument} in the schema + * + * @param argument the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitArgument(GraphQLArgument argument, ArgumentVisitorEnvironment environment) { + return environment.ok(); + } + + interface DirectiveVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLArgument} in the schema + * + * @param directive the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitDirective(GraphQLDirective directive, DirectiveVisitorEnvironment environment) { + return environment.ok(); + } + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLEnumType} + */ + interface EnumTypeVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLEnumType} in the schema + * + * @param enumType the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitEnumType(GraphQLEnumType enumType, EnumTypeVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLEnumValueDefinition} + */ + interface EnumValueDefinitionVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + GraphQLEnumType getContainer(); + } + + /** + * Called when visiting a {@link GraphQLEnumValueDefinition} in the schema + * + * @param enumValueDefinition the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, EnumValueDefinitionVisitorEnvironment environment) { + return environment.ok(); + } + + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLFieldDefinition} + */ + interface FieldDefinitionVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + GraphQLFieldsContainer getContainer(); + + /** + * @return this elements type that has been unwrapped of {@link graphql.schema.GraphQLNonNull} and {@link graphql.schema.GraphQLList} + */ + GraphQLNamedOutputType getUnwrappedType(); + } + + /** + * Called when visiting a {@link GraphQLFieldDefinition} in the schema + * + * @param fieldDefinition the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitFieldDefinition(GraphQLFieldDefinition fieldDefinition, FieldDefinitionVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLInputObjectField} + */ + interface InputObjectFieldVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + GraphQLInputObjectType getContainer(); + + /** + * @return this elements type that has been unwrapped of {@link graphql.schema.GraphQLNonNull} and {@link graphql.schema.GraphQLList} + */ + GraphQLNamedInputType getUnwrappedType(); + } + + /** + * Called when visiting a {@link GraphQLInputObjectField} in the schema + * + * @param inputObjectField the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitInputObjectField(GraphQLInputObjectField inputObjectField, InputObjectFieldVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLInputObjectType} + */ + interface InputObjectTypeVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLInputObjectType} in the schema + * + * @param inputObjectType the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitInputObjectType(GraphQLInputObjectType inputObjectType, InputObjectTypeVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLInterfaceType} + */ + interface InterfaceTypeVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLInterfaceType} in the schema + * + * @param interfaceType the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitInterfaceType(GraphQLInterfaceType interfaceType, InterfaceTypeVisitorEnvironment environment) { + return environment.ok(); + } + + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLObjectType} + */ + interface ObjectVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLObjectType} in the schema + * + * @param objectType the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitObjectType(GraphQLObjectType objectType, ObjectVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLScalarType} + */ + interface ScalarTypeVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLScalarType} in the schema + * + * @param scalarType the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitScalarType(GraphQLScalarType scalarType, ScalarTypeVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLUnionType} + */ + interface UnionTypeVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting a {@link GraphQLUnionType} in the schema + * + * @param unionType the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitUnionType(GraphQLUnionType unionType, UnionTypeVisitorEnvironment environment) { + return environment.ok(); + } + + + /** + * A {@link GraphQLSchemaVisitorEnvironment} environment specific to {@link GraphQLSchemaElement} + */ + interface SchemaElementVisitorEnvironment extends GraphQLSchemaVisitorEnvironment { + } + + /** + * Called when visiting any {@link GraphQLSchemaElement} in the schema. Since every element in the schema + * is a schema element, this visitor method will be called back for every element in the schema + * + * @param schemaElement the schema element being visited + * @param environment the visiting environment + * + * @return a control value which is typically {@link GraphQLSchemaVisitorEnvironment#ok()}} + */ + default GraphQLSchemaTraversalControl visitSchemaElement(GraphQLSchemaElement schemaElement, SchemaElementVisitorEnvironment environment) { + return environment.ok(); + } + + /** + * This allows you to turn this smarter visitor into the base {@link graphql.schema.GraphQLTypeVisitor} interface + * + * @return a type visitor + */ + default GraphQLTypeVisitor toTypeVisitor() { + return new GraphQLSchemaVisitorAdapter(this); + } + + +} diff --git a/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorAdapter.java b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorAdapter.java new file mode 100644 index 0000000000..7b42b4f01a --- /dev/null +++ b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorAdapter.java @@ -0,0 +1,265 @@ +package graphql.schema.visitor; + +import graphql.Internal; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLDirectiveContainer; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLNamedInputType; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import java.util.function.Supplier; + +import static graphql.schema.visitor.GraphQLSchemaVisitor.FieldDefinitionVisitorEnvironment; +import static graphql.schema.visitor.GraphQLSchemaVisitor.ObjectVisitorEnvironment; + +@Internal +class GraphQLSchemaVisitorAdapter extends GraphQLTypeVisitorStub { + + private final GraphQLSchemaVisitor schemaVisitor; + + GraphQLSchemaVisitorAdapter(GraphQLSchemaVisitor schemaVisitor) { + this.schemaVisitor = schemaVisitor; + } + + static class SchemaElementEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.SchemaElementVisitorEnvironment { + public SchemaElementEnv(TraverserContext context) { + super(context); + } + } + + private TraversalControl visitE(TraverserContext context, Supplier visitCall) { + + GraphQLSchemaTraversalControl generalCall = schemaVisitor.visitSchemaElement(context.thisNode(), new SchemaElementEnv(context)); + // if they have changed anything in the general schema element visitation then we don't call the specific visit method + if (generalCall.isAbortive() || generalCall.isMutative()) { + return generalCall.toTraversalControl(context); + } + GraphQLSchemaTraversalControl specificCall = visitCall.get(); + return specificCall.toTraversalControl(context); + } + + static class AppliedDirectiveArgumentEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.AppliedDirectiveArgumentVisitorEnvironment { + public AppliedDirectiveArgumentEnv(TraverserContext context) { + super(context); + } + + @Override + public GraphQLAppliedDirective getContainer() { + return (GraphQLAppliedDirective) context.getParentNode(); + } + + @Override + public GraphQLNamedInputType getUnwrappedType() { + return GraphQLTypeUtil.unwrapAllAs(getElement().getType()); + } + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitAppliedDirectiveArgument(node, new AppliedDirectiveArgumentEnv(context))); + } + + static class AppliedDirectiveEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.AppliedDirectiveVisitorEnvironment { + public AppliedDirectiveEnv(TraverserContext context) { + super(context); + } + + @Override + public GraphQLDirectiveContainer getContainer() { + return (GraphQLDirectiveContainer) context.getParentNode(); + } + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitAppliedDirective(node, new AppliedDirectiveEnv(context))); + } + + static class ArgumentEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.ArgumentVisitorEnvironment { + public ArgumentEnv(TraverserContext context) { + super(context); + } + + @Override + public GraphQLNamedSchemaElement getContainer() { + return (GraphQLNamedSchemaElement) context.getParentNode(); + } + + @Override + public GraphQLNamedInputType getUnwrappedType() { + return GraphQLTypeUtil.unwrapAllAs(getElement().getType()); + } + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitArgument(node, new ArgumentEnv(context))); + } + + + static class DirectiveEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.DirectiveVisitorEnvironment { + public DirectiveEnv(TraverserContext context) { + super(context); + } + } + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective node, TraverserContext context) { + // + // we only want to visit directive definitions at the schema level + // this is our chance to fix up the applied directive problem + // of one class used in two contexts. + // + if (context.getParentNode() == null) { + return visitE(context, () -> schemaVisitor.visitDirective(node, new DirectiveEnv(context))); + + } + return TraversalControl.CONTINUE; + } + + static class EnumTypeEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.EnumTypeVisitorEnvironment { + public EnumTypeEnv(TraverserContext context) { + super(context); + } + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitEnumType(node, new EnumTypeEnv(context))); + } + + static class EnumValueDefinitionEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.EnumValueDefinitionVisitorEnvironment { + public EnumValueDefinitionEnv(TraverserContext context) { + super(context); + } + + @Override + public GraphQLEnumType getContainer() { + return (GraphQLEnumType) context.getParentNode(); + } + } + + @Override + public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitEnumValueDefinition(node, new EnumValueDefinitionEnv(context))); + } + + static class FieldDefinitionEnv extends GraphQLSchemaVisitorEnvironmentImpl implements FieldDefinitionVisitorEnvironment { + + public FieldDefinitionEnv(TraverserContext context) { + super(context); + } + + @Override + public GraphQLFieldsContainer getContainer() { + return (GraphQLFieldsContainer) context.getParentNode(); + } + + @Override + public GraphQLNamedOutputType getUnwrappedType() { + return GraphQLTypeUtil.unwrapAllAs(getElement().getType()); + } + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitFieldDefinition(node, new FieldDefinitionEnv(context))); + } + + static class InputObjectFieldEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.InputObjectFieldVisitorEnvironment { + public InputObjectFieldEnv(TraverserContext context) { + super(context); + } + + @Override + public GraphQLInputObjectType getContainer() { + return (GraphQLInputObjectType) context.getParentNode(); + } + + @Override + public GraphQLNamedInputType getUnwrappedType() { + return GraphQLTypeUtil.unwrapAllAs(getElement().getType()); + } + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitInputObjectField(node, new InputObjectFieldEnv(context))); + } + + static class InputObjectTypeEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.InputObjectTypeVisitorEnvironment { + public InputObjectTypeEnv(TraverserContext context) { + super(context); + } + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitInputObjectType(node, new InputObjectTypeEnv(context))); + } + + + static class InterfaceTypeEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.InterfaceTypeVisitorEnvironment { + public InterfaceTypeEnv(TraverserContext context) { + super(context); + } + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitInterfaceType(node, new InterfaceTypeEnv(context))); + } + + static class ObjectEnv extends GraphQLSchemaVisitorEnvironmentImpl implements ObjectVisitorEnvironment { + public ObjectEnv(TraverserContext context) { + super(context); + } + + } + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitObjectType(node, new ObjectEnv(context))); + } + + + static class ScalarTypeEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.ScalarTypeVisitorEnvironment { + public ScalarTypeEnv(TraverserContext context) { + super(context); + } + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitScalarType(node, new ScalarTypeEnv(context))); + } + + static class UnionTypeEnv extends GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitor.UnionTypeVisitorEnvironment { + public UnionTypeEnv(TraverserContext context) { + super(context); + } + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + return visitE(context, () -> schemaVisitor.visitUnionType(node, new UnionTypeEnv(context))); + } +} diff --git a/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorEnvironment.java b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorEnvironment.java new file mode 100644 index 0000000000..99cc4988e8 --- /dev/null +++ b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorEnvironment.java @@ -0,0 +1,89 @@ +package graphql.schema.visitor; + +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; + +import java.util.List; + +public interface GraphQLSchemaVisitorEnvironment { + + /** + * @return the element that is being visited + */ + T getElement(); + + /** + * This returns the schema element that led to this element, eg a field is contained + * in a type which is pointed to be another field say. + * + * @return a list of schema elements leading to this current element + */ + List getLeadingElements(); + + /** + * This returns the schema element that led to this element but with {@link graphql.schema.GraphQLModifiedType} wrappers + * removed. + * + * @return a list of schema elements leading to this current element + */ + List getUnwrappedLeadingElements(); + + /** + * @return the schema that is being visited upon + */ + GraphQLSchema getSchema(); + + /** + * This will return a value if the visitation call was via {@link graphql.schema.SchemaTransformer} + * + * @return a code registry builder + */ + GraphQLCodeRegistry.Builder getCodeRegistry(); + + + /** + * @return When returned the traversal will continue as planned. + */ + GraphQLSchemaTraversalControl ok(); + + /** + * @return When returned from a {@link GraphQLSchemaVisitor}'s method, indicates exiting the traversal. + */ + GraphQLSchemaTraversalControl quit(); + + /** + * Called to change the current node to the specific node + * + * @param schemaElement the schema element to change + * + * @return a control that changes the current node to a the given node + */ + GraphQLSchemaTraversalControl changeNode(T schemaElement); + + /** + * Called to delete the current node + * + * @return a control that deletes the current node + */ + GraphQLSchemaTraversalControl deleteNode(); + + /** + * Called to insert the current schema element after the specified schema element + * + * @param toInsertAfter the schema element to after before + * + * @return a control that inserts the given node after the current node + */ + GraphQLSchemaTraversalControl insertAfter(T toInsertAfter); + + /** + * Called to insert the current schema element before the specified schema element + * + * @param toInsertBefore the schema element to insert before + * + * @return a control that inserts the given node before the current node + */ + GraphQLSchemaTraversalControl insertBefore(T toInsertBefore); + +} diff --git a/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorEnvironmentImpl.java b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorEnvironmentImpl.java new file mode 100644 index 0000000000..41bb7edffc --- /dev/null +++ b/src/main/java/graphql/schema/visitor/GraphQLSchemaVisitorEnvironmentImpl.java @@ -0,0 +1,102 @@ +package graphql.schema.visitor; + +import graphql.Internal; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLModifiedType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.util.TraverserContext; +import org.jspecify.annotations.NonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +import static graphql.schema.visitor.GraphQLSchemaTraversalControl.CONTINUE; +import static graphql.schema.visitor.GraphQLSchemaTraversalControl.Control; +import static graphql.schema.visitor.GraphQLSchemaTraversalControl.DELETE; +import static graphql.schema.visitor.GraphQLSchemaTraversalControl.QUIT; + +@Internal +class GraphQLSchemaVisitorEnvironmentImpl implements GraphQLSchemaVisitorEnvironment { + + protected final TraverserContext context; + + GraphQLSchemaVisitorEnvironmentImpl(TraverserContext context) { + this.context = context; + } + + @Override + public GraphQLSchema getSchema() { + return context.getVarFromParents(GraphQLSchema.class); + } + + @Override + public GraphQLCodeRegistry.Builder getCodeRegistry() { + return context.getVarFromParents(GraphQLCodeRegistry.Builder.class); + } + + @Override + public T getElement() { + //noinspection unchecked + return (T) context.thisNode(); + } + + + @Override + public List getLeadingElements() { + return buildParentsImpl(schemaElement -> true); + } + + @Override + public List getUnwrappedLeadingElements() { + return buildParentsImpl(schemaElement -> !(schemaElement instanceof GraphQLModifiedType)); + } + + @NonNull + private List buildParentsImpl(Predicate predicate) { + List list = new ArrayList<>(); + TraverserContext parentContext = context.getParentContext(); + while (parentContext != null) { + GraphQLSchemaElement parentNode = parentContext.thisNode(); + if (parentNode != null) { + if (predicate.test(parentNode)) { + list.add(parentNode); + } + } + parentContext = parentContext.getParentContext(); + } + return list; + } + + @Override + public GraphQLSchemaTraversalControl ok() { + return CONTINUE; + } + + @Override + public GraphQLSchemaTraversalControl quit() { + return QUIT; + } + + + @Override + public GraphQLSchemaTraversalControl changeNode(T schemaElement) { + return new GraphQLSchemaTraversalControl(Control.CHANGE, schemaElement); + } + + @Override + public GraphQLSchemaTraversalControl deleteNode() { + return DELETE; + } + + @Override + public GraphQLSchemaTraversalControl insertAfter(T toInsertAfter) { + return new GraphQLSchemaTraversalControl(Control.INSERT_AFTER, toInsertAfter); + } + + @Override + public GraphQLSchemaTraversalControl insertBefore(T toInsertBefore) { + return new GraphQLSchemaTraversalControl(Control.INSERT_BEFORE, toInsertBefore); + } +} diff --git a/src/main/java/graphql/util/Anonymizer.java b/src/main/java/graphql/util/Anonymizer.java new file mode 100644 index 0000000000..ed00c7fbd6 --- /dev/null +++ b/src/main/java/graphql/util/Anonymizer.java @@ -0,0 +1,948 @@ +package graphql.util; + +import graphql.AssertException; +import graphql.Directives; +import graphql.GraphQLContext; +import graphql.PublicApi; +import graphql.Scalars; +import graphql.analysis.QueryTraverser; +import graphql.analysis.QueryVisitor; +import graphql.analysis.QueryVisitorFieldArgumentEnvironment; +import graphql.analysis.QueryVisitorFieldArgumentInputValue; +import graphql.analysis.QueryVisitorFieldArgumentValueEnvironment; +import graphql.analysis.QueryVisitorFieldEnvironment; +import graphql.analysis.QueryVisitorFragmentSpreadEnvironment; +import graphql.analysis.QueryVisitorInlineFragmentEnvironment; +import graphql.collect.ImmutableKit; +import graphql.execution.ValuesResolver; +import graphql.introspection.Introspection; +import graphql.language.Argument; +import graphql.language.ArrayValue; +import graphql.language.AstPrinter; +import graphql.language.AstTransformer; +import graphql.language.Definition; +import graphql.language.Directive; +import graphql.language.Document; +import graphql.language.EnumValue; +import graphql.language.Field; +import graphql.language.FragmentDefinition; +import graphql.language.FragmentSpread; +import graphql.language.InlineFragment; +import graphql.language.IntValue; +import graphql.language.ListType; +import graphql.language.Node; +import graphql.language.NodeVisitorStub; +import graphql.language.NonNullType; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.OperationDefinition; +import graphql.language.StringValue; +import graphql.language.Type; +import graphql.language.TypeName; +import graphql.language.Value; +import graphql.language.VariableDefinition; +import graphql.language.VariableReference; +import graphql.parser.Parser; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; +import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLEnumValueDefinition; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLImplementingType; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLList; +import graphql.schema.GraphQLNamedOutputType; +import graphql.schema.GraphQLNamedSchemaElement; +import graphql.schema.GraphQLNamedType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeReference; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.GraphQLUnionType; +import graphql.schema.SchemaTransformer; +import graphql.schema.TypeResolver; +import graphql.schema.idl.DirectiveInfo; +import graphql.schema.idl.ScalarInfo; +import graphql.schema.idl.TypeUtil; +import graphql.schema.impl.SchemaUtil; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import static graphql.Assert.assertNotNull; +import static graphql.parser.ParserEnvironment.newParserEnvironment; +import static graphql.schema.GraphQLNonNull.nonNull; +import static graphql.schema.GraphQLTypeUtil.unwrapNonNull; +import static graphql.schema.GraphQLTypeUtil.unwrapNonNullAs; +import static graphql.schema.GraphQLTypeUtil.unwrapOneAs; +import static graphql.schema.idl.SchemaGenerator.createdMockedSchema; +import static graphql.util.TraversalControl.CONTINUE; +import static graphql.util.TreeTransformerUtil.changeNode; + +/** + * Util class which converts schemas and optionally queries + * into anonymized schemas and queries. + */ +@PublicApi +public class Anonymizer { + + public static class AnonymizeResult { + private GraphQLSchema schema; + private List queries; + + public AnonymizeResult(GraphQLSchema schema, List queries) { + this.schema = schema; + this.queries = queries; + } + + public GraphQLSchema getSchema() { + return schema; + } + + public List getQueries() { + return queries; + } + } + + public static GraphQLSchema anonymizeSchema(String sdl) { + return anonymizeSchemaAndQueries(createdMockedSchema(sdl), ImmutableKit.emptyList(), ImmutableKit.emptyMap()).schema; + } + + public static GraphQLSchema anonymizeSchema(GraphQLSchema schema) { + return anonymizeSchemaAndQueries(schema, ImmutableKit.emptyList(), ImmutableKit.emptyMap()).schema; + } + + public static AnonymizeResult anonymizeSchemaAndQueries(String sdl, List queries) { + return anonymizeSchemaAndQueries(createdMockedSchema(sdl), queries, ImmutableKit.emptyMap()); + } + + public static AnonymizeResult anonymizeSchemaAndQueries(GraphQLSchema schema, List queries) { + return anonymizeSchemaAndQueries(schema, queries, ImmutableKit.emptyMap()); + } + + public static AnonymizeResult anonymizeSchemaAndQueries(String sdl, List queries, Map variables) { + return anonymizeSchemaAndQueries(createdMockedSchema(sdl), queries, variables); + } + + public static AnonymizeResult anonymizeSchemaAndQueries(GraphQLSchema schema, List queries, Map variables) { + assertNotNull(queries, "queries can't be null"); + + AtomicInteger defaultStringValueCounter = new AtomicInteger(1); + AtomicInteger defaultIntValueCounter = new AtomicInteger(1); + + Map newNameMap = recordNewNamesForSchema(schema); + + // stores a reverse index of anonymized argument name to argument instance + // this is to handle cases where the fields on implementing types MUST have the same exact argument and default + // value definitions as the fields on the implemented interface. (argument default values must match exactly) + Map renamedArgumentsMap = new HashMap<>(); + + SchemaTransformer schemaTransformer = new SchemaTransformer(); + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + public TraversalControl visitGraphQLTypeReference(GraphQLTypeReference graphQLTypeReference, TraverserContext context) { + GraphQLNamedSchemaElement type = (GraphQLNamedSchemaElement) schema.getType(graphQLTypeReference.getName()); + String newName = newNameMap.get(type); + GraphQLTypeReference newReference = GraphQLTypeReference.typeRef(newName); + return changeNode(context, newReference); + } + + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument graphQLArgument, TraverserContext context) { + String newName = assertNotNull(newNameMap.get(graphQLArgument)); + + if (context.getParentNode() instanceof GraphQLFieldDefinition) { + // arguments on field definitions must be identical across implementing types and interfaces. + if (renamedArgumentsMap.containsKey(newName)) { + return changeNode(context, renamedArgumentsMap.get(newName).transform(b -> { + })); + } + } + + GraphQLArgument newElement = graphQLArgument.transform(builder -> { + builder.name(newName).description(null).definition(null); + if (graphQLArgument.hasSetDefaultValue()) { + Value defaultValueLiteral = ValuesResolver.valueToLiteral(graphQLArgument.getArgumentDefaultValue(), graphQLArgument.getType(), GraphQLContext.getDefault(), Locale.getDefault()); + builder.defaultValueLiteral(replaceValue(defaultValueLiteral, graphQLArgument.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter)); + } + + if (graphQLArgument.hasSetValue()) { + Value valueLiteral = ValuesResolver.valueToLiteral(graphQLArgument.getArgumentValue(), graphQLArgument.getType(), GraphQLContext.getDefault(), Locale.getDefault()); + builder.valueLiteral(replaceValue(valueLiteral, graphQLArgument.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter)); + } + }); + + renamedArgumentsMap.put(newName, newElement); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument graphQLArgument, TraverserContext context) { + String newName = assertNotNull(newNameMap.get(graphQLArgument)); + + GraphQLAppliedDirectiveArgument newElement = graphQLArgument.transform(builder -> { + builder.name(newName).description(null).definition(null); + if (graphQLArgument.hasSetValue()) { + Value valueLiteral = ValuesResolver.valueToLiteral(graphQLArgument.getArgumentValue(), graphQLArgument.getType(), GraphQLContext.getDefault(), Locale.getDefault()); + builder.valueLiteral(replaceValue(valueLiteral, graphQLArgument.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter)); + } + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLInterfaceType)) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLInterfaceType)); + GraphQLInterfaceType newElement = graphQLInterfaceType.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + GraphQLCodeRegistry.Builder codeRegistry = assertNotNull(context.getVarFromParents(GraphQLCodeRegistry.Builder.class)); + TypeResolver typeResolver = codeRegistry.getTypeResolver(graphQLInterfaceType); + codeRegistry.typeResolver(newName, typeResolver); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType graphQLEnumType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLEnumType)) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLEnumType)); + GraphQLEnumType newElement = graphQLEnumType.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, TraverserContext context) { + String newName = assertNotNull(newNameMap.get(enumValueDefinition)); + GraphQLEnumValueDefinition newElement = enumValueDefinition.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition graphQLFieldDefinition, TraverserContext context) { + String newName = assertNotNull(newNameMap.get(graphQLFieldDefinition)); + GraphQLFieldDefinition newElement = graphQLFieldDefinition.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective graphQLDirective, TraverserContext context) { + if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective.getName())) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLDirective)); + GraphQLDirective newElement = graphQLDirective.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective graphQLDirective, TraverserContext context) { + if (Directives.DEPRECATED_DIRECTIVE_DEFINITION.getName().equals(graphQLDirective.getName())) { + GraphQLAppliedDirectiveArgument reason = GraphQLAppliedDirectiveArgument.newArgument().name("reason") + .type(Scalars.GraphQLString) + .clearValue() + .build(); + GraphQLAppliedDirective newElement = graphQLDirective.transform(builder -> { + builder.description(null).argument(reason); + }); + changeNode(context, newElement); + return TraversalControl.ABORT; + } + if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective.getName())) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLDirective)); + GraphQLAppliedDirective newElement = graphQLDirective.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField graphQLInputObjectField, TraverserContext context) { + String newName = assertNotNull(newNameMap.get(graphQLInputObjectField)); + + Value defaultValue = null; + if (graphQLInputObjectField.hasSetDefaultValue()) { + defaultValue = ValuesResolver.valueToLiteral(graphQLInputObjectField.getInputFieldDefaultValue(), graphQLInputObjectField.getType(), GraphQLContext.getDefault(), Locale.getDefault()); + defaultValue = replaceValue(defaultValue, graphQLInputObjectField.getType(), newNameMap, defaultStringValueCounter, defaultIntValueCounter); + } + + Value finalDefaultValue = defaultValue; + GraphQLInputObjectField newElement = graphQLInputObjectField.transform(builder -> { + builder.name(newName); + if (finalDefaultValue != null) { + builder.defaultValueLiteral(finalDefaultValue); + } + builder.description(null); + builder.definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType graphQLInputObjectType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLInputObjectType)) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLInputObjectType)); + GraphQLInputObjectType newElement = graphQLInputObjectType.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType graphQLObjectType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLObjectType)) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLObjectType)); + GraphQLObjectType newElement = graphQLObjectType.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType graphQLScalarType, TraverserContext context) { + if (ScalarInfo.isGraphqlSpecifiedScalar(graphQLScalarType)) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLScalarType)); + GraphQLScalarType newElement = graphQLScalarType.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + return changeNode(context, newElement); + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType graphQLUnionType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLUnionType)) { + return TraversalControl.ABORT; + } + String newName = assertNotNull(newNameMap.get(graphQLUnionType)); + GraphQLUnionType newElement = graphQLUnionType.transform(builder -> { + builder.name(newName).description(null).definition(null); + }); + GraphQLCodeRegistry.Builder codeRegistry = assertNotNull(context.getVarFromParents(GraphQLCodeRegistry.Builder.class)); + TypeResolver typeResolver = codeRegistry.getTypeResolver(graphQLUnionType); + codeRegistry.typeResolver(newName, typeResolver); + return changeNode(context, newElement); + } + }); + + List newQueries = new ArrayList<>(); + for (String query : queries) { + String newQuery = rewriteQuery(query, schema, newNameMap, variables); + newQueries.add(newQuery); + } + AnonymizeResult result = new AnonymizeResult(newSchema, newQueries); + return result; + } + + private static Value replaceValue(Value valueLiteral, GraphQLInputType argType, Map newNameMap, AtomicInteger defaultStringValueCounter, AtomicInteger defaultIntValueCounter) { + if (valueLiteral instanceof ArrayValue) { + List values = ((ArrayValue) valueLiteral).getValues(); + ArrayValue.Builder newArrayValueBuilder = ArrayValue.newArrayValue(); + for (Value value : values) { + // [Type!]! -> Type! + GraphQLInputType unwrappedInputType = unwrapOneAs(unwrapNonNull(argType)); + newArrayValueBuilder.value(replaceValue(value, unwrappedInputType, newNameMap, defaultStringValueCounter, defaultIntValueCounter)); + } + return newArrayValueBuilder.build(); + } else if (valueLiteral instanceof StringValue) { + return StringValue.newStringValue("stringValue" + defaultStringValueCounter.getAndIncrement()).build(); + } else if (valueLiteral instanceof IntValue) { + return IntValue.newIntValue(BigInteger.valueOf(defaultIntValueCounter.getAndIncrement())).build(); + } else if (valueLiteral instanceof EnumValue) { + GraphQLEnumType enumType = unwrapNonNullAs(argType); + GraphQLEnumValueDefinition enumValueDefinition = enumType.getValue(((EnumValue) valueLiteral).getName()); + String newName = newNameMap.get(enumValueDefinition); + return new EnumValue(newName); + } else if (valueLiteral instanceof ObjectValue) { + GraphQLInputObjectType inputObjectType = unwrapNonNullAs(argType); + ObjectValue.Builder newObjectValueBuilder = ObjectValue.newObjectValue(); + List objectFields = ((ObjectValue) valueLiteral).getObjectFields(); + for (ObjectField objectField : objectFields) { + String objectFieldName = objectField.getName(); + Value objectFieldValue = objectField.getValue(); + GraphQLInputObjectField inputObjectTypeField = inputObjectType.getField(objectFieldName); + GraphQLInputType fieldType = unwrapNonNullAs(inputObjectTypeField.getType()); + ObjectField newObjectField = objectField.transform(builder -> { + builder.name(newNameMap.get(inputObjectTypeField)); + builder.value(replaceValue(objectFieldValue, fieldType, newNameMap, defaultStringValueCounter, defaultIntValueCounter)); + }); + newObjectValueBuilder.objectField(newObjectField); + } + return newObjectValueBuilder.build(); + } + return valueLiteral; + } + + public static Map recordNewNamesForSchema(GraphQLSchema schema) { + AtomicInteger objectCounter = new AtomicInteger(1); + AtomicInteger inputObjectCounter = new AtomicInteger(1); + AtomicInteger inputObjectFieldCounter = new AtomicInteger(1); + AtomicInteger fieldCounter = new AtomicInteger(1); + AtomicInteger scalarCounter = new AtomicInteger(1); + AtomicInteger directiveCounter = new AtomicInteger(1); + AtomicInteger argumentCounter = new AtomicInteger(1); + AtomicInteger interfaceCounter = new AtomicInteger(1); + AtomicInteger unionCounter = new AtomicInteger(1); + AtomicInteger enumCounter = new AtomicInteger(1); + AtomicInteger enumValueCounter = new AtomicInteger(1); + + Map newNameMap = new LinkedHashMap<>(); + + Map directivesOriginalToNewNameMap = new HashMap<>(); + // DirectiveName.argumentName -> newArgumentName + Map seenArgumentsOnDirectivesMap = new HashMap<>(); + + Map> interfaceToImplementations = + new SchemaUtil().groupImplementationsForInterfacesAndObjects(schema); + + Consumer recordDirectiveName = (graphQLDirective) -> { + String directiveName = graphQLDirective.getName(); + if (directivesOriginalToNewNameMap.containsKey(directiveName)) { + newNameMap.put(graphQLDirective, directivesOriginalToNewNameMap.get(directiveName)); + return; + } + + String newName = "Directive" + directiveCounter.getAndIncrement(); + newNameMap.put(graphQLDirective, newName); + directivesOriginalToNewNameMap.put(directiveName, newName); + }; + + BiConsumer recordDirectiveArgumentName = (graphQLArgument, directiveArgumentKey) -> { + if (seenArgumentsOnDirectivesMap.containsKey(directiveArgumentKey)) { + newNameMap.put(graphQLArgument, seenArgumentsOnDirectivesMap.get(directiveArgumentKey)); + return; + } + String newName = "argument" + argumentCounter.getAndIncrement(); + newNameMap.put(graphQLArgument, newName); + seenArgumentsOnDirectivesMap.put(directiveArgumentKey, newName); + }; + + GraphQLTypeVisitor visitor = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLArgument(GraphQLArgument graphQLArgument, TraverserContext context) { + String curName = graphQLArgument.getName(); + GraphQLSchemaElement parentNode = context.getParentNode(); + if (parentNode instanceof GraphQLDirective) { + // if we already went over the argument for this directive name, no need to add new names + String directiveArgumentKey = ((GraphQLDirective) parentNode).getName() + graphQLArgument.getName(); + recordDirectiveArgumentName.accept(graphQLArgument, directiveArgumentKey); + return CONTINUE; + } + + if (!(parentNode instanceof GraphQLFieldDefinition)) { + String newName = "argument" + argumentCounter.getAndIncrement(); + newNameMap.put(graphQLArgument, newName); + return CONTINUE; + } + GraphQLFieldDefinition fieldDefinition = (GraphQLFieldDefinition) parentNode; + String fieldName = fieldDefinition.getName(); + GraphQLImplementingType implementingType = (GraphQLImplementingType) context.getParentContext().getParentNode(); + Set matchingInterfaceFieldDefinitions = getSameFields(fieldName, implementingType.getName(), interfaceToImplementations, schema); + String newName; + if (matchingInterfaceFieldDefinitions.size() == 0) { + newName = "argument" + argumentCounter.getAndIncrement(); + } else { + List matchingArgumentDefinitions = getMatchingArgumentDefinitions(curName, matchingInterfaceFieldDefinitions); + if (matchingArgumentDefinitions.size() == 0) { + newName = "argument" + argumentCounter.getAndIncrement(); + } else { + if (newNameMap.containsKey(matchingArgumentDefinitions.get(0))) { + newName = newNameMap.get(matchingArgumentDefinitions.get(0)); + } else { + newName = "argument" + argumentCounter.getAndIncrement(); + for (GraphQLArgument argument : matchingArgumentDefinitions) { + newNameMap.put(argument, newName); + } + } + } + } + newNameMap.put(graphQLArgument, newName); + + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument graphQLArgument, TraverserContext context) { + GraphQLSchemaElement parentNode = context.getParentNode(); + if (parentNode instanceof GraphQLAppliedDirective) { + // if we already went over the argument for this directive name, no need to add new names + String directiveArgumentKey = ((GraphQLAppliedDirective) parentNode).getName() + graphQLArgument.getName(); + recordDirectiveArgumentName.accept(graphQLArgument, directiveArgumentKey); + } + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLDirective(GraphQLDirective graphQLDirective, TraverserContext context) { + if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective)) { + return TraversalControl.ABORT; + } + recordDirectiveName.accept(graphQLDirective); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective graphQLAppliedDirective, TraverserContext context) { + if (DirectiveInfo.isGraphqlSpecifiedDirective(graphQLAppliedDirective.getName())) { + return TraversalControl.ABORT; + } + recordDirectiveName.accept(graphQLAppliedDirective); + return CONTINUE; + } + + + @Override + public TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLInterfaceType)) { + return TraversalControl.ABORT; + } + String newName = "Interface" + interfaceCounter.getAndIncrement(); + newNameMap.put(graphQLInterfaceType, newName); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLEnumType(GraphQLEnumType graphQLEnumType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLEnumType)) { + return TraversalControl.ABORT; + } + String newName = "Enum" + enumCounter.getAndIncrement(); + newNameMap.put(graphQLEnumType, newName); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, TraverserContext context) { + String newName = "EnumValue" + enumValueCounter.getAndIncrement(); + newNameMap.put(enumValueDefinition, newName); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition graphQLFieldDefinition, TraverserContext context) { + String fieldName = graphQLFieldDefinition.getName(); + GraphQLImplementingType parentNode = (GraphQLImplementingType) context.getParentNode(); + Set sameFields = getSameFields(fieldName, parentNode.getName(), interfaceToImplementations, schema); + String newName; + if (sameFields.size() == 0) { + newName = "field" + fieldCounter.getAndIncrement(); + } else { + if (newNameMap.containsKey(sameFields.iterator().next())) { + newName = newNameMap.get(sameFields.iterator().next()); + } else { + newName = "field" + fieldCounter.getAndIncrement(); + for (GraphQLFieldDefinition fieldDefinition : sameFields) { + newNameMap.put(fieldDefinition, newName); + } + } + } + newNameMap.put(graphQLFieldDefinition, newName); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField graphQLInputObjectField, TraverserContext context) { + String newName = "inputField" + inputObjectFieldCounter.getAndIncrement(); + newNameMap.put(graphQLInputObjectField, newName); + return CONTINUE; + + } + + @Override + public TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType graphQLInputObjectType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLInputObjectType)) { + return TraversalControl.ABORT; + } + String newName = "InputObject" + inputObjectCounter.getAndIncrement(); + newNameMap.put(graphQLInputObjectType, newName); + return CONTINUE; + } + + + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType graphQLObjectType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLObjectType)) { + return TraversalControl.ABORT; + } + String newName = "Object" + objectCounter.getAndIncrement(); + newNameMap.put(graphQLObjectType, newName); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLScalarType(GraphQLScalarType graphQLScalarType, TraverserContext context) { + if (ScalarInfo.isGraphqlSpecifiedScalar(graphQLScalarType)) { + return TraversalControl.ABORT; + } + String newName = "Scalar" + scalarCounter.getAndIncrement(); + newNameMap.put(graphQLScalarType, newName); + return CONTINUE; + } + + @Override + public TraversalControl visitGraphQLUnionType(GraphQLUnionType graphQLUnionType, TraverserContext context) { + if (Introspection.isIntrospectionTypes(graphQLUnionType)) { + return TraversalControl.ABORT; + } + String newName = "Union" + unionCounter.getAndIncrement(); + newNameMap.put(graphQLUnionType, newName); + return CONTINUE; + } + }; + + SchemaTransformer.transformSchema(schema, visitor); + return newNameMap; + } + + private static Set getSameFields(String fieldName, + String objectOrInterfaceName, + Map> interfaceToImplementations, + GraphQLSchema schema + ) { + Set result = new LinkedHashSet<>(); + Set alreadyChecked = new LinkedHashSet<>(); + getSameFieldsImpl(fieldName, objectOrInterfaceName, interfaceToImplementations, schema, alreadyChecked, result); + return result; + } + + private static void getSameFieldsImpl(String fieldName, + String curObjectOrInterface, + Map> interfaceToImplementations, + GraphQLSchema schema, + Set alreadyChecked, + Set result) { + if (alreadyChecked.contains(curObjectOrInterface)) { + return; + } + alreadyChecked.add(curObjectOrInterface); + + // "up": get all Interfaces + GraphQLImplementingType type = (GraphQLImplementingType) schema.getType(curObjectOrInterface); + List interfaces = type.getInterfaces(); + getMatchingFieldDefinitions(fieldName, interfaces, result); + for (GraphQLNamedOutputType interfaze : interfaces) { + getSameFieldsImpl(fieldName, interfaze.getName(), interfaceToImplementations, schema, alreadyChecked, result); + } + + // "down": get all Object or Interfaces + List implementations = interfaceToImplementations.get(curObjectOrInterface); + if (implementations == null) { + return; + } + getMatchingFieldDefinitions(fieldName, implementations, result); + for (GraphQLImplementingType implementingType : implementations) { + getSameFieldsImpl(fieldName, implementingType.getName(), interfaceToImplementations, schema, alreadyChecked, result); + } + } + + private static void getMatchingFieldDefinitions( + String fieldName, + List interfaces, + Set result) { + for (GraphQLType iface : interfaces) { + GraphQLImplementingType implementingType = (GraphQLImplementingType) iface; + if (implementingType.getFieldDefinition(fieldName) != null) { + result.add(implementingType.getFieldDefinition(fieldName)); + } + } + } + + private static List getMatchingArgumentDefinitions( + String name, + Set fieldDefinitions) { + List result = new ArrayList<>(); + for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { + Optional.ofNullable(fieldDefinition.getArgument(name)).ifPresent(result::add); + } + return result; + } + + private static String rewriteQuery(String query, GraphQLSchema schema, Map newNames, Map variables) { + AtomicInteger fragmentCounter = new AtomicInteger(1); + AtomicInteger variableCounter = new AtomicInteger(1); + Map astNodeToNewName = new LinkedHashMap<>(); + Map variableNames = new LinkedHashMap<>(); + Map fieldToFieldDefinition = new LinkedHashMap<>(); + + Document document = Parser.parse(newParserEnvironment().document(query).build()); + assertUniqueOperation(document); + QueryTraverser queryTraverser = QueryTraverser.newQueryTraverser().document(document).schema(schema).variables(variables).build(); + queryTraverser.visitDepthFirst(new QueryVisitor() { + + @Override + public void visitField(QueryVisitorFieldEnvironment env) { + if (env.isTypeNameIntrospectionField()) { + return; + } + fieldToFieldDefinition.put(env.getField(), env.getFieldDefinition()); + String newName = assertNotNull(newNames.get(env.getFieldDefinition())); + Field field = env.getField(); + astNodeToNewName.put(field, newName); + + List directives = field.getDirectives(); + for (Directive directive : directives) { + // this is a directive definition + GraphQLDirective directiveDefinition = assertNotNull(schema.getDirective(directive.getName()), "%s directive definition not found ", directive.getName()); + String directiveName = directiveDefinition.getName(); + String newDirectiveName = assertNotNull(newNames.get(directiveDefinition), "No new name found for directive %s", directiveName); + astNodeToNewName.put(directive, newDirectiveName); + + for (Argument argument : directive.getArguments()) { + GraphQLArgument argumentDefinition = directiveDefinition.getArgument(argument.getName()); + String newArgumentName = assertNotNull(newNames.get(argumentDefinition), "No new name found for directive %s argument %s", directiveName, argument.getName()); + astNodeToNewName.put(argument, newArgumentName); + visitDirectiveArgumentValues(directive, argument.getValue()); + } + } + } + + private void visitDirectiveArgumentValues(Directive directive, Value value) { + if (value instanceof VariableReference) { + String name = ((VariableReference) value).getName(); + if (!variableNames.containsKey(name)) { + String newName = "var" + variableCounter.getAndIncrement(); + variableNames.put(name, newName); + } + } + } + + @Override + public void visitInlineFragment(QueryVisitorInlineFragmentEnvironment queryVisitorInlineFragmentEnvironment) { + } + + @Override + public TraversalControl visitArgumentValue(QueryVisitorFieldArgumentValueEnvironment environment) { + QueryVisitorFieldArgumentInputValue argumentInputValue = environment.getArgumentInputValue(); + if (argumentInputValue.getValue() instanceof VariableReference) { + String name = ((VariableReference) argumentInputValue.getValue()).getName(); + if (!variableNames.containsKey(name)) { + String newName = "var" + variableCounter.getAndIncrement(); + variableNames.put(name, newName); + } + } + return CONTINUE; + } + + @Override + public void visitFragmentSpread(QueryVisitorFragmentSpreadEnvironment queryVisitorFragmentSpreadEnvironment) { + FragmentDefinition fragmentDefinition = queryVisitorFragmentSpreadEnvironment.getFragmentDefinition(); + String newName; + if (!astNodeToNewName.containsKey(fragmentDefinition)) { + newName = "Fragment" + fragmentCounter.getAndIncrement(); + astNodeToNewName.put(fragmentDefinition, newName); + } else { + newName = astNodeToNewName.get(fragmentDefinition); + } + astNodeToNewName.put(queryVisitorFragmentSpreadEnvironment.getFragmentSpread(), newName); + } + + @Override + public TraversalControl visitArgument(QueryVisitorFieldArgumentEnvironment environment) { + String newName = assertNotNull(newNames.get(environment.getGraphQLArgument())); + astNodeToNewName.put(environment.getArgument(), newName); + return CONTINUE; + } + }); + + AstTransformer astTransformer = new AstTransformer(); + AtomicInteger aliasCounter = new AtomicInteger(1); + AtomicInteger defaultStringValueCounter = new AtomicInteger(1); + AtomicInteger defaultIntValueCounter = new AtomicInteger(1); + + Document newDocument = (Document) astTransformer.transform(document, new NodeVisitorStub() { + + @Override + public TraversalControl visitDirective(Directive directive, TraverserContext context) { + String newName = assertNotNull(astNodeToNewName.get(directive)); + GraphQLDirective directiveDefinition = schema.getDirective(directive.getName()); + context.setVar(GraphQLDirective.class, directiveDefinition); + return changeNode(context, directive.transform(builder -> builder.name(newName))); + } + + @Override + public TraversalControl visitOperationDefinition(OperationDefinition node, TraverserContext context) { + if (node.getName() != null) { + return changeNode(context, node.transform(builder -> builder.name("operation"))); + } else { + return CONTINUE; + } + } + + @Override + public TraversalControl visitField(Field field, TraverserContext context) { + String newAlias = null; + if (field.getAlias() != null) { + newAlias = "alias" + aliasCounter.getAndIncrement(); + } + String newName; + if (field.getName().equals(Introspection.TypeNameMetaFieldDef.getName())) { + newName = Introspection.TypeNameMetaFieldDef.getName(); + } else { + newName = assertNotNull(astNodeToNewName.get(field)); + context.setVar(GraphQLFieldDefinition.class, assertNotNull(fieldToFieldDefinition.get(field))); + } + String finalNewAlias = newAlias; + return changeNode(context, field.transform(builder -> builder.name(newName).alias(finalNewAlias))); + } + + @Override + public TraversalControl visitVariableDefinition(VariableDefinition node, TraverserContext context) { + String newName = assertNotNull(variableNames.get(node.getName())); + VariableDefinition newNode = node.transform(builder -> { + builder.name(newName).comments(ImmutableKit.emptyList()); + + // convert variable language type to renamed language type + TypeName typeName = TypeUtil.unwrapAll(node.getType()); + GraphQLNamedType originalType = schema.getTypeAs(typeName.getName()); + // has the type name changed? (standard scalars such as String don't change) + if (newNames.containsKey(originalType)) { + String newTypeName = newNames.get(originalType); + builder.type(replaceTypeName(node.getType(), newTypeName)); + } + + if (node.getDefaultValue() != null) { + Value defaultValueLiteral = node.getDefaultValue(); + GraphQLType graphQLType = fromTypeToGraphQLType(node.getType(), schema); + builder.defaultValue(replaceValue(defaultValueLiteral, (GraphQLInputType) graphQLType, newNames, defaultStringValueCounter, defaultIntValueCounter)); + } + }); + + return changeNode(context, newNode); + } + + @Override + public TraversalControl visitVariableReference(VariableReference node, TraverserContext context) { + String newName = assertNotNull(variableNames.get(node.getName()), "No new variable name found for %s", node.getName()); + return changeNode(context, node.transform(builder -> builder.name(newName))); + } + + @Override + public TraversalControl visitFragmentDefinition(FragmentDefinition node, TraverserContext context) { + String newName = assertNotNull(astNodeToNewName.get(node)); + GraphQLType currentCondition = assertNotNull(schema.getType(node.getTypeCondition().getName())); + String newCondition = newNames.get(currentCondition); + return changeNode(context, node.transform(builder -> builder.name(newName).typeCondition(new TypeName(newCondition)))); + } + + @Override + public TraversalControl visitInlineFragment(InlineFragment node, TraverserContext context) { + GraphQLType currentCondition = assertNotNull(schema.getType(node.getTypeCondition().getName())); + String newCondition = newNames.get(currentCondition); + return changeNode(context, node.transform(builder -> builder.typeCondition(new TypeName(newCondition)))); + } + + @Override + public TraversalControl visitFragmentSpread(FragmentSpread node, TraverserContext context) { + String newName = assertNotNull(astNodeToNewName.get(node)); + return changeNode(context, node.transform(builder -> builder.name(newName))); + } + + @Override + public TraversalControl visitArgument(Argument argument, TraverserContext context) { + GraphQLArgument graphQLArgumentDefinition; + // An argument is either from a applied query directive or from a field + if (context.getVarFromParents(GraphQLDirective.class) != null) { + GraphQLDirective directiveDefinition = context.getVarFromParents(GraphQLDirective.class); + graphQLArgumentDefinition = directiveDefinition.getArgument(argument.getName()); + } else { + GraphQLFieldDefinition graphQLFieldDefinition = assertNotNull(context.getVarFromParents(GraphQLFieldDefinition.class)); + graphQLArgumentDefinition = graphQLFieldDefinition.getArgument(argument.getName()); + } + GraphQLInputType argumentType = graphQLArgumentDefinition.getType(); + String newName = assertNotNull(astNodeToNewName.get(argument)); + Value newValue = replaceValue(argument.getValue(), argumentType, newNames, defaultStringValueCounter, defaultIntValueCounter); + return changeNode(context, argument.transform(builder -> builder.name(newName).value(newValue))); + } + }); + return AstPrinter.printAstCompact(newDocument); + } + + // converts language [Type!] to [GraphQLType!] using the exact same GraphQLType instance from + // the provided schema + private static GraphQLType fromTypeToGraphQLType(Type type, GraphQLSchema schema) { + if (type instanceof TypeName) { + String typeName = ((TypeName) type).getName(); + GraphQLType graphQLType = schema.getType(typeName); + graphql.Assert.assertNotNull(graphQLType, "Schema must contain type %s", typeName); + return graphQLType; + } else if (type instanceof NonNullType) { + return nonNull(fromTypeToGraphQLType(TypeUtil.unwrapOne(type), schema)); + } else if (type instanceof ListType) { + return GraphQLList.list(fromTypeToGraphQLType(TypeUtil.unwrapOne(type), schema)); + } else { + graphql.Assert.assertShouldNeverHappen(); + return null; + } + } + + // rename a language type. e.g: [[Character!]!] -> [[NewName!]!] + private static Type replaceTypeName(Type type, String newName) { + if (type instanceof TypeName) { + return TypeName.newTypeName(newName).build(); + } else if (type instanceof ListType) { + return ListType.newListType(replaceTypeName(((ListType) type).getType(), newName)).build(); + } else if (type instanceof NonNullType) { + return NonNullType.newNonNullType(replaceTypeName(((NonNullType) type).getType(), newName)).build(); + } else { + graphql.Assert.assertShouldNeverHappen(); + return null; + } + } + + private static void assertUniqueOperation(Document document) { + String operationName = null; + for (Definition definition : document.getDefinitions()) { + if (definition instanceof OperationDefinition) { + if (operationName != null) { + throw new AssertException("Query must have exactly one operation"); + } + OperationDefinition operationDefinition = (OperationDefinition) definition; + operationName = operationDefinition.getName(); + } + } + + } + +} \ No newline at end of file diff --git a/src/main/java/graphql/util/Breadcrumb.java b/src/main/java/graphql/util/Breadcrumb.java new file mode 100644 index 0000000000..ad1415a00a --- /dev/null +++ b/src/main/java/graphql/util/Breadcrumb.java @@ -0,0 +1,63 @@ +package graphql.util; + +import graphql.PublicApi; + +import java.util.Objects; +import java.util.StringJoiner; + +/** + * A specific {@link NodeLocation} inside a node. This means {@link #getNode()} returns a Node which has a child + * at {@link #getLocation()} + *

    + * A list of Breadcrumbs is used to identify the exact location of a specific node inside a tree. + * + * @param the generic type of object + */ +@PublicApi +public class Breadcrumb { + + private final T node; + private final NodeLocation location; + + public Breadcrumb(T node, NodeLocation location) { + this.node = node; + this.location = location; + } + + public T getNode() { + return node; + } + + public NodeLocation getLocation() { + return location; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Breadcrumb that = (Breadcrumb) o; + return Objects.equals(node, that.node) && + Objects.equals(location, that.location); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + Objects.hashCode(node); + result = 31 * result + Objects.hashCode(location); + return result; + } + + @Override + public String toString() { + return new StringJoiner(", ", "[", "]") + .add("" + location) + .add("" + node) + .toString(); + } +} diff --git a/src/main/java/graphql/util/CyclicSchemaAnalyzer.java b/src/main/java/graphql/util/CyclicSchemaAnalyzer.java new file mode 100644 index 0000000000..069dba0783 --- /dev/null +++ b/src/main/java/graphql/util/CyclicSchemaAnalyzer.java @@ -0,0 +1,372 @@ +package graphql.util; + +import graphql.Assert; +import graphql.ExperimentalApi; +import graphql.introspection.Introspection; +import graphql.schema.GraphQLSchema; +import graphql.schema.diffing.Edge; +import graphql.schema.diffing.SchemaGraph; +import graphql.schema.diffing.SchemaGraphFactory; +import graphql.schema.diffing.Vertex; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Finds all cycles in a GraphQL Schema. + * Cycles caused by built-in introspection types are filtered out. + */ +@ExperimentalApi +public class CyclicSchemaAnalyzer { + + public static class SchemaCycle { + private final List cycle; + + public SchemaCycle(List cycle) { + this.cycle = cycle; + } + + public int size() { + return cycle.size(); + } + + public List getCycle() { + return cycle; + } + + @Override + public String toString() { + return cycle.toString(); + } + } + + public static List findCycles(GraphQLSchema schema) { + return findCycles(schema, true); + } + + public static List findCycles(GraphQLSchema schema, boolean filterOutIntrospectionCycles) { + FindCyclesImpl findCyclesImpl = new FindCyclesImpl(schema); + findCyclesImpl.findAllSimpleCyclesImpl(); + List> vertexCycles = findCyclesImpl.foundCycles; + if (filterOutIntrospectionCycles) { + vertexCycles = vertexCycles.stream().filter(vertices -> { + for (Vertex vertex : vertices) { + if (Introspection.isIntrospectionTypes(vertex.getName())) { + return false; + } + } + return true; + }).collect(Collectors.toList()); + } + List result = new ArrayList<>(); + for (List vertexCycle : vertexCycles) { + List stringCycle = new ArrayList<>(); + for (Vertex vertex : vertexCycle) { + if (vertex.isOfType(SchemaGraph.OBJECT) || vertex.isOfType(SchemaGraph.INTERFACE) || vertex.isOfType(SchemaGraph.UNION)) { + stringCycle.add(vertex.getName()); + } else if (vertex.isOfType(SchemaGraph.FIELD)) { + String fieldsContainerName = findCyclesImpl.graph.getFieldsContainerForField(vertex).getName(); + stringCycle.add(fieldsContainerName + "." + vertex.getName()); + } else if (vertex.isOfType(SchemaGraph.INPUT_OBJECT)) { + stringCycle.add(vertex.getName()); + } else if (vertex.isOfType(SchemaGraph.INPUT_FIELD)) { + String inputFieldsContainerName = findCyclesImpl.graph.getFieldsContainerForField(vertex).getName(); + stringCycle.add(inputFieldsContainerName + "." + vertex.getName()); + } else { + Assert.assertShouldNeverHappen("unexpected vertex in cycle found: " + vertex); + } + } + result.add(new SchemaCycle(stringCycle)); + } + return result; + } + + private static class GraphAndIndex { + final SchemaGraph graph; + final int index; + + public GraphAndIndex(SchemaGraph graph, int index) { + this.graph = graph; + this.index = index; + } + } + + /** + * This code was originally taken from https://github.com/jgrapht/jgrapht/blob/master/jgrapht-core/src/main/java/org/jgrapht/alg/cycle/JohnsonSimpleCycles.java + * * (C) Copyright 2013-2023, by Nikolay Ognyanov and Contributors. + * * + * * JGraphT : a free Java graph-theory library + * * + * * See the CONTRIBUTORS.md file distributed with this work for additional + * * information regarding copyright ownership. + * * + * * This program and the accompanying materials are made available under the + * * terms of the Eclipse Public License 2.0 which is available at + * * http://www.eclipse.org/legal/epl-2.0, or the + * * GNU Lesser General Public License v2.1 or later + * * which is available at + * * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html. + * * + * * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later + */ + private static class FindCyclesImpl { + + private final GraphQLSchema schema; + private final SchemaGraph graph; + + // The main state of the algorithm. + private Vertex[] iToV = null; + private Map vToI = null; + private Set blocked = null; + private Map> bSets = null; + private ArrayDeque stack = null; + + // The state of the embedded Tarjan SCC algorithm. + private List> foundSCCs = null; + private int index = 0; + private Map vIndex = null; + private Map vLowlink = null; + private ArrayDeque path = null; + private Set pathSet = null; + + private List> foundCycles = new ArrayList<>(); + + public FindCyclesImpl(GraphQLSchema schema) { + this.schema = schema; + SchemaGraphFactory schemaGraphFactory = new SchemaGraphFactory(); + this.graph = schemaGraphFactory.createGraph(schema); + iToV = (Vertex[]) graph.getVertices().toArray(new Vertex[0]); + vToI = new LinkedHashMap<>(); + blocked = new LinkedHashSet<>(); + bSets = new LinkedHashMap<>(); + stack = new ArrayDeque<>(); + + for (int i = 0; i < iToV.length; i++) { + vToI.put(iToV[i], i); + } + } + + public List> findAllSimpleCyclesImpl() { + int startIndex = 0; + + int size = graph.getVertices().size(); + while (startIndex < size) { + GraphAndIndex minSCCGResult = findMinSCSG(startIndex); + if (minSCCGResult != null) { + startIndex = minSCCGResult.index; + SchemaGraph scg = minSCCGResult.graph; + Vertex startV = toV(startIndex); + for (Edge e : scg.getAdjacentEdges(startV)) { + Vertex v = e.getTo(); + blocked.remove(v); + getBSet(v).clear(); + } + findCyclesInSCG(startIndex, startIndex, scg); + startIndex++; + } else { + break; + } + } + return this.foundCycles; + } + + private GraphAndIndex findMinSCSG(int startIndex) { + /* + * Per Johnson : "adjacency structure of strong component $K$ with least vertex in subgraph + * of $G$ induced by $(s, s + 1, n)$". Or in contemporary terms: the strongly connected + * component of the subgraph induced by $(v_1, \dotso ,v_n)$ which contains the minimum + * (among those SCCs) vertex index. We return that index together with the graph. + */ + initMinSCGState(); + + List> foundSCCs = findSCCS(startIndex); + + // find the SCC with the minimum index + int minIndexFound = Integer.MAX_VALUE; + Set minSCC = null; + for (Set scc : foundSCCs) { + for (Vertex v : scc) { + int t = toI(v); + if (t < minIndexFound) { + minIndexFound = t; + minSCC = scc; + } + } + } + if (minSCC == null) { + return null; + } + + // build a graph for the SCC found + SchemaGraph resultGraph = new SchemaGraph(); + for (Vertex v : minSCC) { + resultGraph.addVertex(v); + } + for (Vertex v : minSCC) { + for (Vertex w : minSCC) { + Edge edge = graph.getEdge(v, w); + if (edge != null) { + resultGraph.addEdge(edge); + } + } + } + + GraphAndIndex graphAndIndex = new GraphAndIndex(resultGraph, minIndexFound); + clearMinSCCState(); + return graphAndIndex; + } + + private List> findSCCS(int startIndex) { + // Find SCCs in the subgraph induced + // by vertices startIndex and beyond. + // A call to StrongConnectivityAlgorithm + // would be too expensive because of the + // need to materialize the subgraph. + // So - do a local search by the Tarjan's + // algorithm and pretend that vertices + // with an index smaller than startIndex + // do not exist. + for (Vertex v : graph.getVertices()) { + int vI = toI(v); + if (vI < startIndex) { + continue; + } + if (!vIndex.containsKey(v)) { + getSCCs(startIndex, vI); + } + } + List> result = foundSCCs; + foundSCCs = null; + return result; + } + + private void getSCCs(int startIndex, int vertexIndex) { + Vertex vertex = toV(vertexIndex); + vIndex.put(vertex, index); + vLowlink.put(vertex, index); + index++; + path.push(vertex); + pathSet.add(vertex); + + List edges = graph.getAdjacentEdges(vertex); + for (Edge e : edges) { + Vertex successor = e.getTo(); + int successorIndex = toI(successor); + if (successorIndex < startIndex) { + continue; + } + if (!vIndex.containsKey(successor)) { + getSCCs(startIndex, successorIndex); + vLowlink.put(vertex, Math.min(vLowlink.get(vertex), vLowlink.get(successor))); + } else if (pathSet.contains(successor)) { + vLowlink.put(vertex, Math.min(vLowlink.get(vertex), vIndex.get(successor))); + } + } + if (vLowlink.get(vertex).equals(vIndex.get(vertex))) { + Set result = new LinkedHashSet<>(); + Vertex temp; + do { + temp = path.pop(); + pathSet.remove(temp); + result.add(temp); + } while (!vertex.equals(temp)); + if (result.size() == 1) { + Vertex v = result.iterator().next(); + if (graph.containsEdge(vertex, v)) { + foundSCCs.add(result); + } + } else { + foundSCCs.add(result); + } + } + } + + private boolean findCyclesInSCG(int startIndex, int vertexIndex, SchemaGraph scg) { + /* + * Find cycles in a strongly connected graph per Johnson. + */ + boolean foundCycle = false; + Vertex vertex = toV(vertexIndex); + stack.push(vertex); + blocked.add(vertex); + + for (Edge e : scg.getAdjacentEdges(vertex)) { + Vertex successor = e.getTo(); + int successorIndex = toI(successor); + if (successorIndex == startIndex) { + List cycle = new ArrayList<>(stack.size()); + stack.descendingIterator().forEachRemaining(cycle::add); + this.foundCycles.add(cycle); + foundCycle = true; + } else if (!blocked.contains(successor)) { + boolean gotCycle = findCyclesInSCG(startIndex, successorIndex, scg); + foundCycle = foundCycle || gotCycle; + } + } + if (foundCycle) { + unblock(vertex); + } else { + for (Edge ew : scg.getAdjacentEdges(vertex)) { + Vertex w = ew.getTo(); + Set bSet = getBSet(w); + bSet.add(vertex); + } + } + stack.pop(); + return foundCycle; + } + + private void unblock(Vertex vertex) { + blocked.remove(vertex); + Set bSet = getBSet(vertex); + while (bSet.size() > 0) { + Vertex w = bSet.iterator().next(); + bSet.remove(w); + if (blocked.contains(w)) { + unblock(w); + } + } + } + + + private void initMinSCGState() { + index = 0; + foundSCCs = new ArrayList<>(); + vIndex = new LinkedHashMap<>(); + vLowlink = new LinkedHashMap<>(); + path = new ArrayDeque<>(); + pathSet = new LinkedHashSet<>(); + } + + private void clearMinSCCState() { + index = 0; + foundSCCs = null; + vIndex = null; + vLowlink = null; + path = null; + pathSet = null; + } + + private Integer toI(Vertex vertex) { + return vToI.get(vertex); + } + + private Vertex toV(Integer i) { + return iToV[i]; + } + + private Set getBSet(Vertex v) { + // B sets typically not all needed, + // so instantiate lazily. + return bSets.computeIfAbsent(v, k -> new LinkedHashSet<>()); + } + + + } +} diff --git a/src/main/java/graphql/util/DefaultTraverserContext.java b/src/main/java/graphql/util/DefaultTraverserContext.java new file mode 100644 index 0000000000..11bd65c36c --- /dev/null +++ b/src/main/java/graphql/util/DefaultTraverserContext.java @@ -0,0 +1,253 @@ +package graphql.util; + +import com.google.common.collect.ImmutableList; +import graphql.Internal; +import graphql.collect.ImmutableKit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static graphql.Assert.assertFalse; +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertNull; +import static graphql.Assert.assertTrue; + +@Internal +public class DefaultTraverserContext implements TraverserContext { + + private final T curNode; + private T newNode; + private boolean nodeDeleted; + + private final TraverserContext parent; + private final Set visited; + private final Map, Object> vars; + private final Object sharedContextData; + + private Object newAccValue; + private boolean hasNewAccValue; + private Object curAccValue; + private final NodeLocation location; + private final boolean isRootContext; + private boolean parallel; + private Map>> children; + private Phase phase; + private final List> breadcrumbs; + + public DefaultTraverserContext(T curNode, + TraverserContext parent, + Set visited, + Map, Object> vars, + Object sharedContextData, + NodeLocation location, + boolean isRootContext, + boolean parallel) { + this.curNode = curNode; + this.parent = parent; + this.visited = visited; + this.vars = vars; + this.sharedContextData = sharedContextData; + this.location = location; + this.isRootContext = isRootContext; + this.parallel = parallel; + + if (parent == null || parent.isRootContext()) { + this.breadcrumbs = ImmutableKit.emptyList(); + } else { + this.breadcrumbs = ImmutableList.>builderWithExpectedSize(parent.getBreadcrumbs().size() + 1) + .add(new Breadcrumb<>(this.parent.thisNode(), this.location)) + .addAll(parent.getBreadcrumbs()) + .build(); + + } + } + + public static DefaultTraverserContext dummy() { + return new DefaultTraverserContext<>(null, null, null, null, null, null, true, false); + } + + public static DefaultTraverserContext simple(T node) { + return new DefaultTraverserContext<>(node, null, null, null, null, null, true, false); + } + + @Override + public T thisNode() { + assertFalse(this.nodeDeleted, "node is deleted"); + if (newNode != null) { + return newNode; + } + return curNode; + } + + @Override + public T originalThisNode() { + return curNode; + } + + @Override + public void changeNode(T newNode) { + assertNotNull(newNode); + assertFalse(this.nodeDeleted, "node is deleted"); + this.newNode = newNode; + } + + + @Override + public void deleteNode() { + assertNull(this.newNode, "node is already changed"); + assertFalse(this.nodeDeleted, "node is already deleted"); + this.nodeDeleted = true; + } + + @Override + public boolean isDeleted() { + return this.nodeDeleted; + } + + @Override + public boolean isChanged() { + return this.newNode != null; + } + + + @Override + public TraverserContext getParentContext() { + return parent; + } + + @Override + public List getParentNodes() { + List result = new ArrayList<>(); + TraverserContext curContext = parent; + while (!curContext.isRootContext()) { + result.add(curContext.thisNode()); + curContext = curContext.getParentContext(); + } + return result; + } + + @Override + public List> getBreadcrumbs() { + return breadcrumbs; + } + + @Override + public T getParentNode() { + if (parent == null) { + return null; + } + return parent.thisNode(); + } + + @Override + public Set visitedNodes() { + return visited; + } + + @Override + public boolean isVisited() { + return visited.contains(curNode); + } + + @Override + public S getVar(Class key) { + return (S) key.cast(vars.get(key)); + } + + @Override + public TraverserContext setVar(Class key, S value) { + vars.put(key, value); + return this; + } + + @Override + public void setAccumulate(Object accumulate) { + hasNewAccValue = true; + newAccValue = accumulate; + } + + @Override + public U getNewAccumulate() { + if (hasNewAccValue) { + return (U) newAccValue; + } else { + return (U) curAccValue; + } + } + + @Override + public U getCurrentAccumulate() { + return (U) curAccValue; + } + + + @Override + public Object getSharedContextData() { + return sharedContextData; + } + + /* + * PRIVATE: Used by {@link Traverser} + */ + void setCurAccValue(Object curAccValue) { + hasNewAccValue = false; + this.curAccValue = curAccValue; + } + + @Override + public NodeLocation getLocation() { + return location; + } + + @Override + public boolean isRootContext() { + return isRootContext; + } + + @Override + public S getVarFromParents(Class key) { + TraverserContext curContext = parent; + while (curContext != null) { + S var = curContext.getVar(key); + if (var != null) { + return var; + } + curContext = curContext.getParentContext(); + } + return null; + } + + /* + * PRIVATE: Used by {@link Traverser} + */ + void setChildrenContexts(Map>> children) { + assertTrue(this.children == null, "children already set"); + this.children = children; + } + + + @Override + public Map>> getChildrenContexts() { + assertNotNull(children, "children not available"); + return children; + } + + /* + * PRIVATE: Used by {@link Traverser} + */ + void setPhase(Phase phase) { + this.phase = phase; + } + + @Override + public Phase getPhase() { + return phase; + } + + @Override + public boolean isParallel() { + return parallel; + } +} diff --git a/src/main/java/graphql/util/EscapeUtil.java b/src/main/java/graphql/util/EscapeUtil.java new file mode 100644 index 0000000000..521ac35846 --- /dev/null +++ b/src/main/java/graphql/util/EscapeUtil.java @@ -0,0 +1,56 @@ +package graphql.util; + +import graphql.Internal; + +@Internal +public final class EscapeUtil { + + private EscapeUtil() { + } + + /** + * Encodes the value as a JSON string according to https://json.org/ rules + * + * @param stringValue the value to encode as a JSON string + * + * @return the encoded string + */ + public static String escapeJsonString(String stringValue) { + StringBuilder sb = new StringBuilder(stringValue.length()); + escapeJsonStringTo(sb, stringValue); + return sb.toString(); + } + + public static void escapeJsonStringTo(StringBuilder output, String stringValue) { + int len = stringValue.length(); + for (int i = 0; i < len; i++) { + char ch = stringValue.charAt(i); + switch (ch) { + case '"': + output.append("\\\""); + break; + case '\\': + output.append("\\\\"); + break; + case '\b': + output.append("\\b"); + break; + case '\f': + output.append("\\f"); + break; + case '\n': + output.append("\\n"); + break; + case '\r': + output.append("\\r"); + break; + case '\t': + output.append("\\t"); + break; + default: + output.append(ch); + } + } + } + +} diff --git a/src/main/java/graphql/util/FpKit.java b/src/main/java/graphql/util/FpKit.java index ada6f6686c..b4bf6ca60d 100644 --- a/src/main/java/graphql/util/FpKit.java +++ b/src/main/java/graphql/util/FpKit.java @@ -1,21 +1,31 @@ package graphql.util; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import graphql.Internal; +import org.jspecify.annotations.NonNull; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.Set; import java.util.function.BinaryOperator; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.IntStream; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; -import static java.util.Collections.singletonList; -import static java.util.function.Function.identity; @Internal public class FpKit { @@ -23,13 +33,79 @@ public class FpKit { // // From a list of named things, get a map of them by name, merging them according to the merge function public static Map getByName(List namedObjects, Function nameFn, BinaryOperator mergeFunc) { - return namedObjects.stream().collect(Collectors.toMap( - nameFn, - identity(), - mergeFunc) - ); + return toMap(namedObjects, nameFn, mergeFunc); } + // + // From a collection of keyed things, get a map of them by key, merging them according to the merge function + public static Map toMap(Collection collection, Function keyFunction, BinaryOperator mergeFunc) { + Map resultMap = Maps.newLinkedHashMapWithExpectedSize(collection.size()); + for (T obj : collection) { + NewKey key = keyFunction.apply(obj); + if (resultMap.containsKey(key)) { + T existingValue = resultMap.get(key); + T mergedValue = mergeFunc.apply(existingValue, obj); + resultMap.put(key, mergedValue); + } else { + resultMap.put(key, obj); + } + } + return resultMap; + } + + // normal groupingBy but with LinkedHashMap + public static Map> groupingBy(Collection list, Function function) { + return filterAndGroupingBy(list, ALWAYS_TRUE, function); + } + + @SuppressWarnings("unchecked") + public static Map> filterAndGroupingBy(Collection list, + Predicate predicate, + Function function) { + // + // The cleanest version of this code would have two maps, one of immutable list builders and one + // of the built immutable lists. BUt we are trying to be performant and memory efficient so + // we treat it as a map of objects and cast like its Java 4x + // + Map resutMap = new LinkedHashMap<>(); + for (T item : list) { + if (predicate.test(item)) { + NewKey key = function.apply(item); + // we have to use an immutable list builder as we built it out + ((ImmutableList.Builder) resutMap.computeIfAbsent(key, k -> ImmutableList.builder())) + .add(item); + } + } + if (resutMap.isEmpty()) { + return Collections.emptyMap(); + } + // Convert builders to ImmutableLists in place to avoid an extra allocation + // yes the code is yuck - but its more performant yuck! + resutMap.replaceAll((key, builder) -> + ((ImmutableList.Builder) builder).build()); + + // make it the right shape - like as if generics were never invented + return (Map>) (Map) resutMap; + } + + public static Map toMapByUniqueKey(Collection list, Function keyFunction) { + return toMap(list, keyFunction, throwingMerger()); + } + + + private static final Predicate ALWAYS_TRUE = o -> true; + + private static final BinaryOperator THROWING_MERGER_SINGLETON = (u, v) -> { + throw new IllegalStateException(String.format("Duplicate key %s", u)); + }; + + + private static BinaryOperator throwingMerger() { + //noinspection unchecked + return (BinaryOperator) THROWING_MERGER_SINGLETON; + } + + // // From a list of named things, get a map of them by name, merging them first one added public static Map getByName(List namedObjects, Function nameFn) { @@ -49,20 +125,14 @@ public static BinaryOperator mergeFirst() { * * @return an Iterable from that object * - * @throws java.lang.ClassCastException if its not an Iterable + * @throws java.lang.ClassCastException if it's not an Iterable */ @SuppressWarnings("unchecked") public static Collection toCollection(Object iterableResult) { - if (iterableResult.getClass().isArray()) { - List collect = IntStream.range(0, Array.getLength(iterableResult)) - .mapToObj(i -> Array.get(iterableResult, i)) - .collect(Collectors.toList()); - return (List) collect; - } if (iterableResult instanceof Collection) { return (Collection) iterableResult; } - Iterable iterable = (Iterable) iterableResult; + Iterable iterable = toIterable(iterableResult); Iterator iterator = iterable.iterator(); List list = new ArrayList<>(); while (iterator.hasNext()) { @@ -71,6 +141,105 @@ public static Collection toCollection(Object iterableResult) { return list; } + /** + * Creates an {@link ArrayList} sized appropriately to the collection, typically for copying + * + * @param collection the collection of a certain size + * @param to two + * + * @return a new {@link ArrayList} initially sized to the same as the collection + */ + public static @NonNull List arrayListSizedTo(@NonNull Collection collection) { + return new ArrayList<>(collection.size()); + } + + + /** + * Converts a value into a list if it's really a collection or array of things + * else it turns it into a singleton list containing that one value + * + * @param possibleIterable the possible + * @param for two + * + * @return an list one way or another + */ + @SuppressWarnings("unchecked") + public static List toListOrSingletonList(Object possibleIterable) { + if (possibleIterable instanceof List) { + return (List) possibleIterable; + } + if (isIterable(possibleIterable)) { + return ImmutableList.copyOf(toIterable(possibleIterable)); + } + return ImmutableList.of((T) possibleIterable); + } + + public static boolean isIterable(Object result) { + return result.getClass().isArray() || result instanceof Iterable || result instanceof Stream || result instanceof Iterator; + } + + + @SuppressWarnings("unchecked") + public static Iterable toIterable(Object iterableResult) { + if (iterableResult instanceof Iterable) { + return ((Iterable) iterableResult); + } + + if (iterableResult instanceof Stream) { + return ((Stream) iterableResult)::iterator; + } + + if (iterableResult instanceof Iterator) { + return () -> (Iterator) iterableResult; + } + + if (iterableResult.getClass().isArray()) { + return () -> new ArrayIterator<>(iterableResult); + } + + throw new ClassCastException("not Iterable: " + iterableResult.getClass()); + } + + private static class ArrayIterator implements Iterator { + + private final Object array; + private final int size; + private int i; + + private ArrayIterator(Object array) { + this.array = array; + this.size = Array.getLength(array); + this.i = 0; + } + + @Override + public boolean hasNext() { + return i < size; + } + + @SuppressWarnings("unchecked") + @Override + public T next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return (T) Array.get(array, i++); + } + + } + + public static OptionalInt toSize(Object iterableResult) { + if (iterableResult instanceof Collection) { + return OptionalInt.of(((Collection) iterableResult).size()); + } + + if (iterableResult.getClass().isArray()) { + return OptionalInt.of(Array.getLength(iterableResult)); + } + + return OptionalInt.empty(); + } + /** * Concatenates (appends) a single elements to an existing list * @@ -78,10 +247,13 @@ public static Collection toCollection(Object iterableResult) { * @param t the element to append * @param the type of elements of the list * - * @return a new list componsed of the first list elements and the new element + * @return a new list composed of the first list elements and the new element */ public static List concat(List l, T t) { - return concat(l, singletonList(t)); + List list = new ArrayList<>(l.size() + 1); + list.addAll(l); + list.add(t); + return list; } /** @@ -93,10 +265,10 @@ public static List concat(List l, T t) { * * @return a new list composed of the two concatenated lists elements */ - public static List concat(List l1, List l2) { - ArrayList l = new ArrayList<>(l1); + public static List concat(List l1, List l2) { + List l = new ArrayList<>(l1.size() + l2.size()); + l.addAll(l1); l.addAll(l2); - l.trimToSize(); return l; } @@ -106,4 +278,128 @@ public static List valuesToList(Map map) { return new ArrayList<>(map.values()); } + public static List> transposeMatrix(List> matrix) { + int rowCount = matrix.size(); + int colCount = matrix.get(0).size(); + List> result = new ArrayList<>(); + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < colCount; j++) { + T val = matrix.get(i).get(j); + if (result.size() <= j) { + result.add(j, new ArrayList<>()); + } + result.get(j).add(i, val); + } + } + return result; + } + + public static Optional findOne(Collection list, Predicate filter) { + for (T t : list) { + if (filter.test(t)) { + return Optional.of(t); + } + } + return Optional.empty(); + } + + public static T findOneOrNull(List list, Predicate filter) { + return findOne(list, filter).orElse(null); + } + + public static int findIndex(List list, Predicate filter) { + for (int i = 0; i < list.size(); i++) { + if (filter.test(list.get(i))) { + return i; + } + } + return -1; + } + + public static List filterList(Collection list, Predicate filter) { + List result = arrayListSizedTo(list); + for (T t : list) { + if (filter.test(t)) { + result.add(t); + } + } + return result; + } + + public static Set filterSet(Collection input, Predicate filter) { + ImmutableSet.Builder result = ImmutableSet.builder(); + for (T t : input) { + if (filter.test(t)) { + result.add(t); + } + } + return result.build(); + } + + /** + * Used in simple {@link Map#computeIfAbsent(Object, java.util.function.Function)} cases + * + * @param for Key + * @param for Value + * + * @return a function that allocates a list + */ + public static Function> newList() { + return k -> new ArrayList<>(); + } + + /** + * This will memoize the Supplier within the current thread's visibility, that is it does not + * use volatile reads but rather use a sentinel check and re-reads the delegate supplier + * value if the read has not stuck to this thread. This means that it's possible that your delegate + * supplier MAY be called more than once across threads, but only once on the same thread. + * + * @param delegate the supplier to delegate to + * @param for two + * + * @return a supplier that will memoize values in the context of the current thread + */ + public static Supplier intraThreadMemoize(Supplier delegate) { + return new IntraThreadMemoizedSupplier<>(delegate); + } + + /** + * This will memoize the Supplier across threads and make sure the Supplier is exactly called once. + *

    + * Use for potentially costly actions. Otherwise consider {@link #intraThreadMemoize(Supplier)} + * + * @param delegate the supplier to delegate to + * @param for two + * + * @return a supplier that will memoize values in the context of the all the threads + */ + public static Supplier interThreadMemoize(Supplier delegate) { + return new InterThreadMemoizedSupplier<>(delegate); + } + + /** + * Faster set intersection. + * + * @param for two + * @param set1 first set + * @param set2 second set + * + * @return intersection set + */ + public static Set intersection(Set set1, Set set2) { + // Set intersection calculation is expensive when either set is large. Often, either set has only one member. + // When either set contains only one member, it is equivalent and much cheaper to calculate intersection via contains. + if (set1.size() == 1 && set2.contains(set1.iterator().next())) { + return set1; + } else if (set2.size() == 1 && set1.contains(set2.iterator().next())) { + return set2; + } + + // Guava's Sets.intersection is faster when the smaller set is passed as the first argument. + if (set1.size() < set2.size()) { + return Sets.intersection(set1, set2); + } + return Sets.intersection(set2, set1); + } + } diff --git a/src/main/java/graphql/util/IdGenerator.java b/src/main/java/graphql/util/IdGenerator.java new file mode 100644 index 0000000000..f92784c4ac --- /dev/null +++ b/src/main/java/graphql/util/IdGenerator.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * This class was taken from Spring https://github.com/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/util/AlternativeJdkIdGenerator.java + * as a way to get a more performant UUID generator for use as request ids. SecureRandom can be expensive + * to run on each request as per https://github.com/graphql-java/graphql-java/issues/3435, so this uses SecureRandom + * at application start and then the cheaper Random class each call after that. + */ +package graphql.util; + +import graphql.Internal; + +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Random; +import java.util.UUID; + +/** + * An id generator that uses {@link SecureRandom} for the initial seed and + * {@link Random} thereafter. This provides a better balance between securely random ids and performance. + * + * @author Rossen Stoyanchev + * @author Rob Winch + */ +@Internal +public class IdGenerator { + + private static final IdGenerator idGenerator = new IdGenerator(); + + public static UUID uuid() { + return idGenerator.generateId(); + } + + private final Random random; + + + public IdGenerator() { + SecureRandom secureRandom = new SecureRandom(); + byte[] seed = new byte[8]; + secureRandom.nextBytes(seed); + this.random = new Random(new BigInteger(seed).longValue()); + } + + + public UUID generateId() { + byte[] randomBytes = new byte[16]; + this.random.nextBytes(randomBytes); + + long mostSigBits = 0; + for (int i = 0; i < 8; i++) { + mostSigBits = (mostSigBits << 8) | (randomBytes[i] & 0xff); + } + + long leastSigBits = 0; + for (int i = 8; i < 16; i++) { + leastSigBits = (leastSigBits << 8) | (randomBytes[i] & 0xff); + } + + return new UUID(mostSigBits, leastSigBits); + } + +} \ No newline at end of file diff --git a/src/main/java/graphql/util/InterThreadMemoizedSupplier.java b/src/main/java/graphql/util/InterThreadMemoizedSupplier.java new file mode 100644 index 0000000000..072d5635cd --- /dev/null +++ b/src/main/java/graphql/util/InterThreadMemoizedSupplier.java @@ -0,0 +1,42 @@ +package graphql.util; + +import graphql.Internal; + +import java.util.function.Supplier; + +/** + * This memoizing supplier DOES use locked double locking to set its value. + * + * @param for two + */ +@Internal +public class InterThreadMemoizedSupplier implements Supplier { + + private final Supplier delegate; + private volatile boolean initialized; + private final LockKit.ReentrantLock lock = new LockKit.ReentrantLock(); + private T value; + + public InterThreadMemoizedSupplier(Supplier delegate) { + this.delegate = delegate; + } + + + @Override + public T get() { + if (!initialized) { + lock.lock(); + try { + if (initialized) { + return value; + } + value = delegate.get(); + initialized = true; + return value; + } finally { + lock.unlock(); + } + } + return value; + } +} diff --git a/src/main/java/graphql/util/Interning.java b/src/main/java/graphql/util/Interning.java new file mode 100644 index 0000000000..acbb54fdaf --- /dev/null +++ b/src/main/java/graphql/util/Interning.java @@ -0,0 +1,25 @@ +package graphql.util; + +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import graphql.Internal; +import org.jspecify.annotations.NonNull; + +/** + * Interner allowing object-identity comparison of key entities like field names. This is useful on hotspot + * areas like the engine where we look up field names a lot inside maps, and those maps use object identity first + * inside the key lookup code. + */ +@Internal +public class Interning { + + private Interning() { + } + + private static final Interner INTERNER = Interners.newWeakInterner(); + + public static @NonNull String intern(@NonNull String name) { + return INTERNER.intern(name); + } + +} diff --git a/src/main/java/graphql/util/IntraThreadMemoizedSupplier.java b/src/main/java/graphql/util/IntraThreadMemoizedSupplier.java new file mode 100644 index 0000000000..faf0d87c8f --- /dev/null +++ b/src/main/java/graphql/util/IntraThreadMemoizedSupplier.java @@ -0,0 +1,37 @@ +package graphql.util; + +import graphql.Internal; + +import java.util.function.Supplier; + +import static graphql.Assert.assertNotNull; + +/** + * This memoizing supplier does NOT use synchronised double locking to set its value + * so on multiple threads it MAY call the delegate again to get a value. + * + * @param for two + */ +@Internal +class IntraThreadMemoizedSupplier implements Supplier { + private final static Object SENTINEL = new Object() { + }; + + @SuppressWarnings("unchecked") + private T value = (T) SENTINEL; + private final Supplier delegate; + + IntraThreadMemoizedSupplier(Supplier delegate) { + this.delegate = assertNotNull(delegate); + } + + @Override + public T get() { + T t = value; + if (t == SENTINEL) { + t = delegate.get(); + value = t; + } + return t; + } +} diff --git a/src/main/java/graphql/util/LinkedHashMapFactory.java b/src/main/java/graphql/util/LinkedHashMapFactory.java new file mode 100644 index 0000000000..b9cc20ef75 --- /dev/null +++ b/src/main/java/graphql/util/LinkedHashMapFactory.java @@ -0,0 +1,344 @@ +package graphql.util; + +import graphql.Internal; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Factory class for creating LinkedHashMap instances with insertion order preservation. + * Use this instead of Map.of() to ensure consistent serialization order. + *

    + * This class provides static factory methods similar to Map.of() but returns mutable LinkedHashMap + * instances that preserve insertion order, which is important for consistent serialization. + */ +@Internal +public final class LinkedHashMapFactory { + + private LinkedHashMapFactory() { + // utility class + } + + /** + * Returns an empty LinkedHashMap. + * + * @param the key type + * @param the value type + * @return an empty LinkedHashMap + */ + public static Map of() { + return new LinkedHashMap<>(); + } + + /** + * Returns a LinkedHashMap containing a single mapping. + * + * @param the key type + * @param the value type + * @param k1 the mapping's key + * @param v1 the mapping's value + * @return a LinkedHashMap containing the specified mapping + */ + public static Map of(K k1, V v1) { + Map map = new LinkedHashMap<>(1); + map.put(k1, v1); + return map; + } + + /** + * Returns a LinkedHashMap containing two mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2) { + Map map = new LinkedHashMap<>(2); + map.put(k1, v1); + map.put(k2, v2); + return map; + } + + /** + * Returns a LinkedHashMap containing three mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3) { + Map map = new LinkedHashMap<>(3); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + return map; + } + + /** + * Returns a LinkedHashMap containing four mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + Map map = new LinkedHashMap<>(4); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + return map; + } + + /** + * Returns a LinkedHashMap containing five mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @param k5 the fifth mapping's key + * @param v5 the fifth mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + Map map = new LinkedHashMap<>(5); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + return map; + } + + /** + * Returns a LinkedHashMap containing six mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @param k5 the fifth mapping's key + * @param v5 the fifth mapping's value + * @param k6 the sixth mapping's key + * @param v6 the sixth mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { + Map map = new LinkedHashMap<>(6); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + return map; + } + + /** + * Returns a LinkedHashMap containing seven mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @param k5 the fifth mapping's key + * @param v5 the fifth mapping's value + * @param k6 the sixth mapping's key + * @param v6 the sixth mapping's value + * @param k7 the seventh mapping's key + * @param v7 the seventh mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { + Map map = new LinkedHashMap<>(7); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + return map; + } + + /** + * Returns a LinkedHashMap containing eight mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @param k5 the fifth mapping's key + * @param v5 the fifth mapping's value + * @param k6 the sixth mapping's key + * @param v6 the sixth mapping's value + * @param k7 the seventh mapping's key + * @param v7 the seventh mapping's value + * @param k8 the eighth mapping's key + * @param v8 the eighth mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { + Map map = new LinkedHashMap<>(8); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + map.put(k8, v8); + return map; + } + + /** + * Returns a LinkedHashMap containing nine mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @param k5 the fifth mapping's key + * @param v5 the fifth mapping's value + * @param k6 the sixth mapping's key + * @param v6 the sixth mapping's value + * @param k7 the seventh mapping's key + * @param v7 the seventh mapping's value + * @param k8 the eighth mapping's key + * @param v8 the eighth mapping's value + * @param k9 the ninth mapping's key + * @param v9 the ninth mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) { + Map map = new LinkedHashMap<>(9); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + map.put(k8, v8); + map.put(k9, v9); + return map; + } + + /** + * Returns a LinkedHashMap containing ten mappings. + * + * @param the key type + * @param the value type + * @param k1 the first mapping's key + * @param v1 the first mapping's value + * @param k2 the second mapping's key + * @param v2 the second mapping's value + * @param k3 the third mapping's key + * @param v3 the third mapping's value + * @param k4 the fourth mapping's key + * @param v4 the fourth mapping's value + * @param k5 the fifth mapping's key + * @param v5 the fifth mapping's value + * @param k6 the sixth mapping's key + * @param v6 the sixth mapping's value + * @param k7 the seventh mapping's key + * @param v7 the seventh mapping's value + * @param k8 the eighth mapping's key + * @param v8 the eighth mapping's value + * @param k9 the ninth mapping's key + * @param v9 the ninth mapping's value + * @param k10 the tenth mapping's key + * @param v10 the tenth mapping's value + * @return a LinkedHashMap containing the specified mappings + */ + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) { + Map map = new LinkedHashMap<>(10); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + map.put(k8, v8); + map.put(k9, v9); + map.put(k10, v10); + return map; + } + + /** + * Returns a LinkedHashMap containing mappings derived from the given arguments. + *

    + * This method is provided for cases where more than 10 key-value pairs are needed. + * It accepts alternating keys and values. + * + * @param the key type + * @param the value type + * @param keyValues alternating keys and values + * @return a LinkedHashMap containing the specified mappings + * @throws IllegalArgumentException if an odd number of arguments is provided + */ + @SuppressWarnings("unchecked") + public static Map ofEntries(Object... keyValues) { + if (keyValues.length % 2 != 0) { + throw new IllegalArgumentException("keyValues must contain an even number of arguments (key-value pairs)"); + } + + Map map = new LinkedHashMap<>(keyValues.length / 2); + for (int i = 0; i < keyValues.length; i += 2) { + K key = (K) keyValues[i]; + V value = (V) keyValues[i + 1]; + map.put(key, value); + } + return map; + } +} \ No newline at end of file diff --git a/src/main/java/graphql/util/LockKit.java b/src/main/java/graphql/util/LockKit.java new file mode 100644 index 0000000000..f2513d8628 --- /dev/null +++ b/src/main/java/graphql/util/LockKit.java @@ -0,0 +1,87 @@ +package graphql.util; + +import graphql.Internal; + +import java.util.concurrent.locks.Lock; +import java.util.function.Supplier; + +/** + * This provides reentrant locking support for our code base. Future worlds like Loom virtual threads don't like + * synchronised calls since they pin the VT to the carrier thread. Word on the street is that locks are preferred + * to synchronised. + */ +@Internal +public class LockKit { + + /** + * A class to run code inside a reentrant lock + */ + public static class ReentrantLock { + private final Lock lock = new java.util.concurrent.locks.ReentrantLock(); + + /** + * Sometimes you need to directly lock things like for checked exceptions + *

    + * It's on you to unlock it! + */ + public void lock() { + lock.lock(); + } + + public void unlock() { + lock.unlock(); + } + + public void runLocked(Runnable codeToRun) { + lock.lock(); + try { + codeToRun.run(); + } finally { + lock.unlock(); + } + } + + public E callLocked(Supplier codeToRun) { + lock.lock(); + try { + return codeToRun.get(); + } finally { + lock.unlock(); + } + } + } + + + /** + * Will allow for lazy computation of some values just once + */ + public static class ComputedOnce { + + private volatile boolean beenComputed = false; + private final ReentrantLock lock = new ReentrantLock(); + + + public boolean hasBeenComputed() { + return beenComputed; + } + + public void runOnce(Runnable codeToRunOnce) { + if (beenComputed) { + return; + } + lock.runLocked(() -> { + // double lock check + if (beenComputed) { + return; + } + try { + codeToRunOnce.run(); + beenComputed = true; + } finally { + // even for exceptions we will say its computed + beenComputed = true; + } + }); + } + } +} diff --git a/src/main/java/graphql/util/MutableRef.java b/src/main/java/graphql/util/MutableRef.java new file mode 100644 index 0000000000..d538f5eb95 --- /dev/null +++ b/src/main/java/graphql/util/MutableRef.java @@ -0,0 +1,15 @@ +package graphql.util; + +import graphql.Internal; + +/** + * This class is useful for creating a mutable reference to a variable that can be changed when you are in an + * effectively final bit of code. Its more performant than an {@link java.util.concurrent.atomic.AtomicReference} + * to gain mutability. Use this very carefully - Its not expected to be commonly used. + * + * @param for two + */ +@Internal +public class MutableRef { + public T value; +} diff --git a/src/main/java/graphql/util/NodeAdapter.java b/src/main/java/graphql/util/NodeAdapter.java new file mode 100644 index 0000000000..b416d5c2cb --- /dev/null +++ b/src/main/java/graphql/util/NodeAdapter.java @@ -0,0 +1,23 @@ +package graphql.util; + +import graphql.PublicApi; + +import java.util.List; +import java.util.Map; + +/** + * Adapts an arbitrary class to behave as a node. + * We are using an Adapter because we don't want to require Nodes to implement a certain Interface. + * + * @param the generic type of object + */ +@PublicApi +public interface NodeAdapter { + + Map> getNamedChildren(T node); + + T withNewChildren(T node, Map> newChildren); + + T removeChild(T node, NodeLocation location); + +} diff --git a/src/main/java/graphql/util/NodeLocation.java b/src/main/java/graphql/util/NodeLocation.java new file mode 100644 index 0000000000..8a1f9f10bc --- /dev/null +++ b/src/main/java/graphql/util/NodeLocation.java @@ -0,0 +1,62 @@ +package graphql.util; + +import graphql.PublicApi; + +import java.util.Objects; + +/** + * General position of a Node inside a parent. + *

    + * Can be an index or a name with an index. + */ +@PublicApi +public class NodeLocation { + + private final String name; + private final int index; + + public NodeLocation(String name, int index) { + this.name = name; + this.index = index; + } + + /** + * @return the name or null if there is no name + */ + public String getName() { + return name; + } + + public int getIndex() { + return index; + } + + @Override + public String toString() { + return "{" + + "name='" + name + '\'' + + ", index=" + index + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NodeLocation that = (NodeLocation) o; + return index == that.index && + Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + Objects.hashCode(name); + result = 31 * result + Integer.hashCode(index); + return result; + } +} diff --git a/src/main/java/graphql/util/NodeMultiZipper.java b/src/main/java/graphql/util/NodeMultiZipper.java new file mode 100644 index 0000000000..72801a920d --- /dev/null +++ b/src/main/java/graphql/util/NodeMultiZipper.java @@ -0,0 +1,196 @@ +package graphql.util; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static graphql.Assert.assertNotEmpty; +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.util.NodeZipper.ModificationType.REPLACE; + +@PublicApi +public class NodeMultiZipper { + + private final T commonRoot; + private final ImmutableList> zippers; + private final NodeAdapter nodeAdapter; + + public NodeMultiZipper(T commonRoot, List> zippers, NodeAdapter nodeAdapter) { + this.commonRoot = assertNotNull(commonRoot); + this.zippers = ImmutableList.copyOf(zippers); + this.nodeAdapter = nodeAdapter; + } + + /* + * constructor without defensive copy of the zippers + */ + private NodeMultiZipper(T commonRoot, List> zippers, NodeAdapter nodeAdapter, Object dummy) { + this.commonRoot = assertNotNull(commonRoot); + this.zippers = ImmutableList.copyOf(zippers); + this.nodeAdapter = nodeAdapter; + } + + /* + * special factory method which doesn't copy the zippers list and trusts that the zippers list is not modified outside + */ + public static NodeMultiZipper newNodeMultiZipperTrusted(T commonRoot, List> zippers, NodeAdapter nodeAdapter) { + return new NodeMultiZipper<>(commonRoot, zippers, nodeAdapter, null); + } + + /** + * @return can be null if the root node is marked as deleted + */ + public T toRootNode() { + if (zippers.size() == 0) { + return commonRoot; + } + + // we want to preserve the order here + Set> curZippers = new LinkedHashSet<>(zippers); + while (curZippers.size() > 1) { + + List> deepestZippers = getDeepestZippers(curZippers); + Map>> sameParent = zipperWithSameParent(deepestZippers); + + List> newZippers = new ArrayList<>(); + Map> zipperByNode = FpKit.toMapByUniqueKey(curZippers, NodeZipper::getCurNode); + for (Map.Entry>> entry : sameParent.entrySet()) { + NodeZipper newZipper = moveUp(entry.getKey(), entry.getValue()); + Optional> zipperToBeReplaced = Optional.ofNullable(zipperByNode.get(entry.getKey())); + zipperToBeReplaced.ifPresent(curZippers::remove); + newZippers.add(newZipper); + } + curZippers.removeAll(deepestZippers); + curZippers.addAll(newZippers); + } + assertTrue(curZippers.size() == 1, "unexpected state: all zippers must share the same root node"); + return curZippers.iterator().next().toRoot(); + } + + public T getCommonRoot() { + return commonRoot; + } + + public List> getZippers() { + return zippers; + } + + public int size() { + return zippers.size(); + } + + public NodeZipper getZipperForNode(T node) { + return FpKit.findOneOrNull(zippers, zipper -> zipper.getCurNode() == node); + } + + public NodeMultiZipper withReplacedZippers(List> zippers) { + return new NodeMultiZipper<>(commonRoot, zippers, this.nodeAdapter); + } + + + public NodeMultiZipper withNewZipper(NodeZipper newZipper) { + List> newZippers = new ArrayList<>(zippers); + newZippers.add(newZipper); + return new NodeMultiZipper<>(commonRoot, newZippers, this.nodeAdapter); + } + + public NodeMultiZipper withReplacedZipper(NodeZipper oldZipper, NodeZipper newZipper) { + int index = zippers.indexOf(oldZipper); + assertTrue(index >= 0, "oldZipper not found"); + List> newZippers = new ArrayList<>(zippers); + newZippers.set(index, newZipper); + return new NodeMultiZipper<>(commonRoot, newZippers, this.nodeAdapter); + } + + public NodeMultiZipper withReplacedZipperForNode(T currentNode, T newNode) { + int index = FpKit.findIndex(zippers, zipper -> zipper.getCurNode() == currentNode); + assertTrue(index >= 0, "No current zipper found for provided node"); + NodeZipper newZipper = zippers.get(index).withNewNode(newNode); + List> newZippers = new ArrayList<>(zippers); + newZippers.set(index, newZipper); + return new NodeMultiZipper<>(commonRoot, newZippers, this.nodeAdapter); + } + + + private List> getDeepestZippers(Set> zippers) { + Map>> grouped = FpKit.groupingBy(zippers, astZipper -> astZipper.getBreadcrumbs().size()); + + Integer maxLevel = Collections.max(grouped.keySet()); + return grouped.get(maxLevel); + } + + private NodeZipper moveUp(T parent, List> sameParent) { + assertNotEmpty(sameParent, "expected at least one zipper"); + + Map> childrenMap = new HashMap<>(nodeAdapter.getNamedChildren(parent)); + Map indexCorrection = new HashMap<>(); + + sameParent = new ArrayList<>(sameParent); + sameParent.sort((zipper1, zipper2) -> { + int index1 = zipper1.getBreadcrumbs().get(0).getLocation().getIndex(); + int index2 = zipper2.getBreadcrumbs().get(0).getLocation().getIndex(); + if (index1 != index2) { + return Integer.compare(index1, index2); + } + NodeZipper.ModificationType modificationType1 = zipper1.getModificationType(); + NodeZipper.ModificationType modificationType2 = zipper2.getModificationType(); + + // same index can never be deleted and changed at the same time + + if (modificationType1 == modificationType2) { + return 0; + } + + // always first replacing the node + if (modificationType1 == REPLACE) { + return -1; + } + // and then INSERT_BEFORE before INSERT_AFTER + return modificationType1 == NodeZipper.ModificationType.INSERT_BEFORE ? -1 : 1; + + }); + + for (NodeZipper zipper : sameParent) { + NodeLocation location = zipper.getBreadcrumbs().get(0).getLocation(); + Integer ixDiff = indexCorrection.getOrDefault(location.getName(), 0); + int ix = location.getIndex() + ixDiff; + String name = location.getName(); + List childList = new ArrayList<>(childrenMap.get(name)); + switch (zipper.getModificationType()) { + case REPLACE: + childList.set(ix, zipper.getCurNode()); + break; + case DELETE: + childList.remove(ix); + indexCorrection.put(name, ixDiff - 1); + break; + case INSERT_BEFORE: + childList.add(ix, zipper.getCurNode()); + indexCorrection.put(name, ixDiff + 1); + break; + case INSERT_AFTER: + childList.add(ix + 1, zipper.getCurNode()); + indexCorrection.put(name, ixDiff + 1); + break; + } + childrenMap.put(name, childList); + } + + T newNode = nodeAdapter.withNewChildren(parent, childrenMap); + List> newBreadcrumbs = sameParent.get(0).getBreadcrumbs().subList(1, sameParent.get(0).getBreadcrumbs().size()); + return new NodeZipper<>(newNode, newBreadcrumbs, this.nodeAdapter); + } + + private Map>> zipperWithSameParent(List> zippers) { + return FpKit.groupingBy(zippers, NodeZipper::getParent); + } +} diff --git a/src/main/java/graphql/util/NodeZipper.java b/src/main/java/graphql/util/NodeZipper.java new file mode 100644 index 0000000000..0a5dfd46a7 --- /dev/null +++ b/src/main/java/graphql/util/NodeZipper.java @@ -0,0 +1,150 @@ +package graphql.util; + +import com.google.common.collect.ImmutableList; +import graphql.PublicApi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import static graphql.Assert.assertNotNull; + +@PublicApi +public class NodeZipper { + + + public enum ModificationType { + REPLACE, + DELETE, + INSERT_AFTER, + INSERT_BEFORE + } + + private final T curNode; + private final NodeAdapter nodeAdapter; + // reverse: the breadCrumbs start from curNode upwards + private final List> breadcrumbs; + + private final ModificationType modificationType; + + + public NodeZipper(T curNode, List> breadcrumbs, NodeAdapter nodeAdapter) { + this(curNode, breadcrumbs, nodeAdapter, ModificationType.REPLACE); + } + + public NodeZipper(T curNode, List> breadcrumbs, NodeAdapter nodeAdapter, ModificationType modificationType) { + this.curNode = assertNotNull(curNode); + this.breadcrumbs = ImmutableList.copyOf(assertNotNull(breadcrumbs)); + this.nodeAdapter = nodeAdapter; + this.modificationType = modificationType; + } + + public ModificationType getModificationType() { + return modificationType; + } + + public T getCurNode() { + return curNode; + } + + public List> getBreadcrumbs() { + return breadcrumbs; + } + + public T getParent() { + return breadcrumbs.get(0).getNode(); + } + + public static NodeZipper rootZipper(T rootNode, NodeAdapter nodeAdapter) { + return new NodeZipper(rootNode, new ArrayList<>(), nodeAdapter); + } + + public NodeZipper modifyNode(Function transform) { + return new NodeZipper(transform.apply(curNode), breadcrumbs, nodeAdapter, this.modificationType); + } + + public NodeZipper deleteNode() { + return new NodeZipper(this.curNode, breadcrumbs, nodeAdapter, ModificationType.DELETE); + } + + public NodeZipper insertAfter(T toInsertAfter) { + return new NodeZipper(toInsertAfter, breadcrumbs, nodeAdapter, ModificationType.INSERT_AFTER); + } + + public NodeZipper insertBefore(T toInsertBefore) { + return new NodeZipper(toInsertBefore, breadcrumbs, nodeAdapter, ModificationType.INSERT_BEFORE); + } + + public NodeZipper withNewNode(T newNode) { + return new NodeZipper(newNode, breadcrumbs, nodeAdapter, this.modificationType); + } + + public NodeZipper moveUp() { + T node = getParent(); + List> newBreadcrumbs = breadcrumbs.subList(1, breadcrumbs.size()); + return new NodeZipper<>(node, newBreadcrumbs, nodeAdapter, this.modificationType); + } + + + /** + * @return null if it is the root node and marked as deleted, otherwise never null + */ + public T toRoot() { + if (breadcrumbs.size() == 0 && modificationType != ModificationType.DELETE) { + return this.curNode; + } + if (breadcrumbs.size() == 0 && modificationType == ModificationType.DELETE) { + return null; + } + T curNode = this.curNode; + + Breadcrumb firstBreadcrumb = breadcrumbs.get(0); + Map> childrenForParent = new HashMap<>(nodeAdapter.getNamedChildren(firstBreadcrumb.getNode())); + NodeLocation locationInParent = firstBreadcrumb.getLocation(); + int ix = locationInParent.getIndex(); + String name = locationInParent.getName(); + List childList = new ArrayList<>(childrenForParent.get(name)); + switch (modificationType) { + case REPLACE: + childList.set(ix, curNode); + break; + case DELETE: + childList.remove(ix); + break; + case INSERT_BEFORE: + childList.add(ix, curNode); + break; + case INSERT_AFTER: + childList.add(ix + 1, curNode); + break; + } + childrenForParent.put(name, childList); + curNode = nodeAdapter.withNewChildren(firstBreadcrumb.getNode(), childrenForParent); + if (breadcrumbs.size() == 1) { + return curNode; + } + for (Breadcrumb breadcrumb : breadcrumbs.subList(1, breadcrumbs.size())) { + // just handle replace + Map> newChildren = new LinkedHashMap<>(nodeAdapter.getNamedChildren(breadcrumb.getNode())); + final T newChild = curNode; + NodeLocation location = breadcrumb.getLocation(); + List list = new ArrayList<>(newChildren.get(location.getName())); + list.set(location.getIndex(), newChild); + newChildren.put(location.getName(), list); + curNode = nodeAdapter.withNewChildren(breadcrumb.getNode(), newChildren); + } + return curNode; + } + + @Override + public String toString() { + return "NodeZipper{" + + "curNode=" + curNode + + ", breadcrumbs.size=" + breadcrumbs.size() + + ", modificationType=" + modificationType + + '}'; + } +} diff --git a/src/main/java/graphql/util/Pair.java b/src/main/java/graphql/util/Pair.java new file mode 100644 index 0000000000..ccbb6c5e35 --- /dev/null +++ b/src/main/java/graphql/util/Pair.java @@ -0,0 +1,24 @@ +package graphql.util; + +import graphql.Internal; + +@Internal +public final class Pair { + + public Pair(T first, U second) { + this.second = second; + this.first = first; + } + + public final T first; + public final U second; + + public static Pair pair(T first, U second) { + return new Pair<>(first, second); + } + + @Override + public String toString() { + return "(" + first + ", " + second + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/graphql/util/ReplaceNode.java b/src/main/java/graphql/util/ReplaceNode.java new file mode 100644 index 0000000000..4716ee439d --- /dev/null +++ b/src/main/java/graphql/util/ReplaceNode.java @@ -0,0 +1,21 @@ +package graphql.util; + +import graphql.Internal; + +/** + * Special class to be set as var in {@link TraverserContext#setVar(Class, Object)} to indicate that the current node should be replaced. + * This is used when the new Node actually has different children and you wanna iterator over the new State. + */ +@Internal +public class ReplaceNode { + + private final Object newNode; + + public ReplaceNode(Object newNode) { + this.newNode = newNode; + } + + public Object getNewNode() { + return newNode; + } +} diff --git a/src/main/java/graphql/util/SimpleTraverserContext.java b/src/main/java/graphql/util/SimpleTraverserContext.java deleted file mode 100644 index f68cfeab97..0000000000 --- a/src/main/java/graphql/util/SimpleTraverserContext.java +++ /dev/null @@ -1,70 +0,0 @@ -package graphql.util; - -import graphql.Internal; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -@Internal -public class SimpleTraverserContext implements TraverserContext { - - private final Map, Object> vars = new LinkedHashMap<>(); - private final T node; - private Object result; - - public SimpleTraverserContext(T node) { - this.node = node; - } - - @Override - public T thisNode() { - return node; - } - - - @Override - public TraverserContext getParentContext() { - return null; - } - - @Override - public Object getParentResult() { - return null; - } - - @Override - public boolean isVisited() { - return false; - } - - @Override - public Set visitedNodes() { - return null; - } - - @Override - public S getVar(Class key) { - return null; - } - - @Override - public TraverserContext setVar(Class key, S value) { - return null; - } - - @Override - public void setResult(Object result) { - this.result = result; - } - - @Override - public Object getResult() { - return this.result; - } - - @Override - public Object getInitialData() { - return null; - } -} diff --git a/src/main/java/graphql/util/StringKit.java b/src/main/java/graphql/util/StringKit.java new file mode 100644 index 0000000000..20fcea1b1f --- /dev/null +++ b/src/main/java/graphql/util/StringKit.java @@ -0,0 +1,20 @@ +package graphql.util; + +import java.util.Locale; + +public class StringKit { + + public static String capitalize(String s) { + if (s != null && !s.isEmpty()) { + StringBuilder sb = new StringBuilder(); + // see https://github.com/graphql-java/graphql-java/issues/3385 + sb.append(s.substring(0, 1).toUpperCase(Locale.ROOT)); + if (s.length() > 1) { + sb.append(s.substring(1)); + } + return sb.toString(); + } + return s; + } + +} diff --git a/src/main/java/graphql/util/Traverser.java b/src/main/java/graphql/util/Traverser.java index 06b321f4eb..4190dfb6c0 100644 --- a/src/main/java/graphql/util/Traverser.java +++ b/src/main/java/graphql/util/Traverser.java @@ -20,16 +20,23 @@ public class Traverser { private final TraverserState traverserState; - private final Function> getChildren; + private final Function>> getChildren; + private final Object initialAccumulate; private final Map, Object> rootVars = new ConcurrentHashMap<>(); - private final TraverserContext BARRIER = new SimpleTraverserContext<>(null); - private static final List CONTINUE_OR_QUIT = Arrays.asList(CONTINUE, QUIT); - private Traverser(TraverserState traverserState, Function> getChildren) { + private Traverser(TraverserState traverserState, Function>> getChildren, Object initialAccumulate) { this.traverserState = assertNotNull(traverserState); this.getChildren = assertNotNull(getChildren); + this.initialAccumulate = initialAccumulate; + } + + private static Function>> wrapListFunction(Function> listFn) { + return node -> { + List childs = listFn.apply(node); + return Collections.singletonMap(null, childs); + }; } public Traverser rootVars(Map, Object> rootVars) { @@ -43,22 +50,38 @@ public Traverser rootVar(Class key, Object value) { } public static Traverser depthFirst(Function> getChildren) { - return depthFirst(getChildren, null); + return depthFirst(getChildren, null, null); } - public static Traverser depthFirst(Function> getChildren, Object initialData) { - return new Traverser<>(TraverserState.newStackState(initialData), getChildren); + public static Traverser depthFirst(Function> getChildren, Object sharedContextData) { + return depthFirst(getChildren, sharedContextData, null); } + public static Traverser depthFirst(Function> getChildren, Object sharedContextData, Object initialAccumulate) { + Function>> mapFunction = wrapListFunction(getChildren); + return new Traverser<>(TraverserState.newStackState(sharedContextData), mapFunction, initialAccumulate); + } + + public static Traverser depthFirstWithNamedChildren(Function>> getNamedChildren, Object sharedContextData, Object initialAccumulate) { + return new Traverser<>(TraverserState.newStackState(sharedContextData), getNamedChildren, initialAccumulate); + } public static Traverser breadthFirst(Function> getChildren) { - return breadthFirst(getChildren, null); + return breadthFirst(getChildren, null, null); } - public static Traverser breadthFirst(Function> getChildren, Object initialData) { - return new Traverser<>(TraverserState.newQueueState(initialData), getChildren); + public static Traverser breadthFirst(Function> getChildren, Object sharedContextData) { + return breadthFirst(getChildren, sharedContextData, null); } + public static Traverser breadthFirst(Function> getChildren, Object sharedContextData, Object initialAccumulate) { + Function>> mapFunction = wrapListFunction(getChildren); + return new Traverser<>(TraverserState.newQueueState(sharedContextData), mapFunction, initialAccumulate); + } + + public static Traverser breadthFirstWithNamedChildren(Function>> getNamedChildren, Object sharedContextData, Object initialAccumulate) { + return new Traverser<>(TraverserState.newQueueState(sharedContextData), getNamedChildren, initialAccumulate); + } public TraverserResult traverse(T root, TraverserVisitor visitor) { return traverse(Collections.singleton(root), visitor); @@ -68,21 +91,30 @@ public TraverserResult traverse(Collection roots, TraverserVisitor< assertNotNull(roots); assertNotNull(visitor); - traverserState.addNewContexts(roots, traverserState.newContext(null, null, rootVars)); - TraverserContext currentContext = BARRIER; + // "artificial" parent context for all roots with rootVars + DefaultTraverserContext rootContext = traverserState.newRootContext(rootVars); + traverserState.addNewContexts(roots, rootContext); + + DefaultTraverserContext currentContext; + Object currentAccValue = initialAccumulate; traverseLoop: while (!traverserState.isEmpty()) { Object top = traverserState.pop(); - if (top == TraverserState.Marker.END_LIST) { + if (top instanceof TraverserState.EndList) { + Map>> childrenContextMap = ((TraverserState.EndList) top).childrenContextMap; // end-of-list marker, we are done recursing children, // mark the current node as fully visited - TraverserContext contextForLeave = (TraverserContext) traverserState.pop(); - currentContext = contextForLeave; - TraversalControl traversalControl = visitor.leave(contextForLeave); + currentContext = (DefaultTraverserContext) traverserState.pop(); + currentContext.setCurAccValue(currentAccValue); + currentContext.setChildrenContexts(childrenContextMap); + currentContext.setPhase(TraverserContext.Phase.LEAVE); + TraversalControl traversalControl = visitor.leave(currentContext); + currentAccValue = currentContext.getNewAccumulate(); assertNotNull(traversalControl, "result of leave must not be null"); assertTrue(CONTINUE_OR_QUIT.contains(traversalControl), "result can only return CONTINUE or QUIT"); + switch (traversalControl) { case QUIT: break traverseLoop; @@ -93,19 +125,26 @@ public TraverserResult traverse(Collection roots, TraverserVisitor< } } - currentContext = (TraverserContext) top; + currentContext = (DefaultTraverserContext) top; if (currentContext.isVisited()) { + currentContext.setCurAccValue(currentAccValue); + currentContext.setPhase(TraverserContext.Phase.BACKREF); TraversalControl traversalControl = visitor.backRef(currentContext); - assertNotNull(traversalControl, "result of backRef must not be null"); + currentAccValue = currentContext.getNewAccumulate(); + assertNotNull(traversalControl,"result of backRef must not be null"); assertTrue(CONTINUE_OR_QUIT.contains(traversalControl), "backRef can only return CONTINUE or QUIT"); if (traversalControl == QUIT) { break traverseLoop; } } else { + currentContext.setCurAccValue(currentAccValue); + Object nodeBeforeEnter = currentContext.thisNode(); + currentContext.setPhase(TraverserContext.Phase.ENTER); TraversalControl traversalControl = visitor.enter(currentContext); + currentAccValue = currentContext.getNewAccumulate(); assertNotNull(traversalControl, "result of enter must not be null"); - this.traverserState.addVisited((T) currentContext.thisNode()); + this.traverserState.addVisited((T) nodeBeforeEnter); switch (traversalControl) { case QUIT: break traverseLoop; @@ -119,7 +158,8 @@ public TraverserResult traverse(Collection roots, TraverserVisitor< } } } - TraverserResult traverserResult = new TraverserResult(currentContext.getResult()); + + TraverserResult traverserResult = new TraverserResult(currentAccValue); return traverserResult; } diff --git a/src/main/java/graphql/util/TraverserContext.java b/src/main/java/graphql/util/TraverserContext.java index e6ca0efd8c..0f38dc5c0c 100644 --- a/src/main/java/graphql/util/TraverserContext.java +++ b/src/main/java/graphql/util/TraverserContext.java @@ -2,22 +2,73 @@ import graphql.PublicApi; +import java.util.List; +import java.util.Map; import java.util.Set; /** - * Traversal context + * Traversal context. + * + * It is used as providing context for traversing, but also for returning an accumulate value. ({@link #setAccumulate(Object)} + * + * There is always a "fake" root context with null node, null parent, null position. See {@link #isRootContext()} * * @param type of tree node */ @PublicApi public interface TraverserContext { + + enum Phase { + LEAVE, + ENTER, + BACKREF + } + /** - * Returns current node being visited + * Returns current node being visited. + * Special cases: + * It is null for the root context and it is the changed node after {@link #changeNode(Object)} is called. + * Throws Exception if the node is deleted. + * + * @return current node traverser is visiting. * - * @return current node traverser is visiting + * @throws graphql.AssertException if the current node is deleted */ T thisNode(); + /** + * Returns the original, unchanged, not deleted Node. + * + * @return the original node + */ + T originalThisNode(); + + /** + * Change the current node to the provided node. Only applicable in enter. + * + * Useful when the tree should be changed while traversing. + * + * Also: changing a node makes only a difference when it has different children than the current one. + * + * @param newNode the new Node + */ + void changeNode(T newNode); + + /** + * Deletes the current node. + */ + void deleteNode(); + + /** + * @return true if the current node is deleted (by calling {@link #deleteNode()} + */ + boolean isDeleted(); + + /** + * @return true if the current node is changed (by calling {@link #changeNode(Object)} + */ + boolean isChanged(); + /** * Returns parent context. * Effectively organizes Context objects in a linked list so @@ -30,11 +81,33 @@ public interface TraverserContext { TraverserContext getParentContext(); /** - * The result of the {@link #getParentContext()}. + * The list of parent nodes starting from the current parent. + * + * @return list of parent nodes + */ + List getParentNodes(); + + /** + * The parent node. + * + * @return The parent node. + */ + T getParentNode(); + + + /** + * The exact location of this node inside the tree as a list of {@link Breadcrumb} * - * @return + * @return list of breadcrumbs. the first element is the location inside the parent. */ - Object getParentResult(); + List> getBreadcrumbs(); + + /** + * The location of the current node regarding to the parent node. + * + * @return the position or null if this node is a root node + */ + NodeLocation getLocation(); /** * Informs that the current node has been already "visited" @@ -47,7 +120,7 @@ public interface TraverserContext { * Obtains all visited nodes and values received by the {@link TraverserVisitor#enter(graphql.util.TraverserContext) } * method * - * @return a map containg all nodes visited and values passed when visiting nodes for the first time + * @return a map containing all nodes visited and values passed when visiting nodes for the first time */ Set visitedNodes(); @@ -57,14 +130,25 @@ public interface TraverserContext { * @param type of the variable * @param key key to lookup the variable value * - * @return a variable value of {@code null} + * @return a variable value or {@code null} */ S getVar(Class key); + /** + * Searches for a context variable starting from the parent + * up the hierarchy of contexts until the first variable is found. + * + * @param type of the variable + * @param key key to lookup the variable value + * + * @return a variable value or {@code null} + */ + S getVarFromParents(Class key); + /** * Stores a variable in the context * - * @param type of a varable + * @param type of a variable * @param key key to create bindings for the variable * @param value value of variable * @@ -74,24 +158,64 @@ public interface TraverserContext { /** - * Set the result for this TraverserContext. + * Sets the new accumulate value. * - * @param result + * Can be retrieved by {@link #getNewAccumulate()} + * + * @param accumulate to set */ - void setResult(Object result); + void setAccumulate(Object accumulate); /** - * The result of this TraverserContext.. + * The new accumulate value, previously set by {@link #setAccumulate(Object)} + * or {@link #getCurrentAccumulate()} if {@link #setAccumulate(Object)} not invoked. + * + * @param and me * - * @return + * @return the new accumulate value */ - Object getResult(); + U getNewAccumulate(); + + /** + * The current accumulate value used as "input" for the current step. + * + * @param and me + * + * @return the current accumulate value + */ + U getCurrentAccumulate(); /** * Used to share something across all TraverserContext. * - * @return + * @param and me + * + * @return contextData + */ + U getSharedContextData(); + + /** + * Returns true for the root context, which doesn't have a node or a position. + * + * @return true for the root context, otherwise false + */ + boolean isRootContext(); + + /** + * In case of leave returns the children contexts, which have already been visited. + * + * @return the children contexts. If the childs are a simple list the key is null. + */ + Map>> getChildrenContexts(); + + /** + * @return the phase in which the node visits currently happens (Enter,Leave or BackRef) + */ + Phase getPhase(); + + /** + * @return true if the traversing happens in parallel (multi threaded) or not. */ - Object getInitialData(); + boolean isParallel(); } diff --git a/src/main/java/graphql/util/TraverserResult.java b/src/main/java/graphql/util/TraverserResult.java index 1d880189bd..bd7cea420b 100644 --- a/src/main/java/graphql/util/TraverserResult.java +++ b/src/main/java/graphql/util/TraverserResult.java @@ -5,16 +5,14 @@ @Internal public class TraverserResult { - private final Object result; + private final Object accumulatedResult; - - public TraverserResult(Object result) { - this.result = result; + public TraverserResult(Object accumulatedResult) { + this.accumulatedResult = accumulatedResult; } - - public Object getResult() { - return result; + public Object getAccumulatedResult() { + return accumulatedResult; } } diff --git a/src/main/java/graphql/util/TraverserState.java b/src/main/java/graphql/util/TraverserState.java index ac59a20240..e478e05a0b 100644 --- a/src/main/java/graphql/util/TraverserState.java +++ b/src/main/java/graphql/util/TraverserState.java @@ -3,13 +3,12 @@ import graphql.Internal; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Collection; import java.util.Deque; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -19,67 +18,102 @@ @Internal public abstract class TraverserState { - private Object initialData; - + private Object sharedContextData; private final Deque state; private final Set visited = new LinkedHashSet<>(); + // used for depth first traversal private static class StackTraverserState extends TraverserState { - private StackTraverserState(Object initialData) { - super(initialData); + private StackTraverserState(Object sharedContextData) { + super(sharedContextData); } @Override - public void pushAll(TraverserContext o, Function> getChildren) { - super.state.push(o); - super.state.push(Marker.END_LIST); - new ReverseIterator<>(getChildren.apply(o.thisNode())).forEachRemaining((e) -> super.state.push(newContext(e, o))); + public void pushAll(TraverserContext traverserContext, Function>> getChildren) { + super.state.push(traverserContext); + + EndList endList = new EndList<>(); + super.state.push(endList); + Map>> childrenContextMap = new LinkedHashMap<>(); + + if (!traverserContext.isDeleted()) { + Map> childrenMap = getChildren.apply(traverserContext.thisNode()); + childrenMap.keySet().forEach(key -> { + List children = childrenMap.get(key); + for (int i = children.size() - 1; i >= 0; i--) { + U child = assertNotNull(children.get(i), "null child for key %s",key); + NodeLocation nodeLocation = new NodeLocation(key, i); + DefaultTraverserContext context = super.newContext(child, traverserContext, nodeLocation); + super.state.push(context); + childrenContextMap.computeIfAbsent(key, notUsed -> new ArrayList<>()); + childrenContextMap.get(key).add(0, context); + } + }); + } + endList.childrenContextMap = childrenContextMap; } } + // used for breadth first traversal private static class QueueTraverserState extends TraverserState { - private QueueTraverserState(Object initialData) { - super(initialData); + private QueueTraverserState(Object sharedContextData) { + super(sharedContextData); } @Override - public void pushAll(TraverserContext o, Function> getChildren) { - getChildren.apply(o.thisNode()).iterator().forEachRemaining((e) -> super.state.add(newContext(e, o))); - super.state.add(Marker.END_LIST); - super.state.add(o); + public void pushAll(TraverserContext traverserContext, Function>> getChildren) { + Map>> childrenContextMap = new LinkedHashMap<>(); + if (!traverserContext.isDeleted()) { + Map> childrenMap = getChildren.apply(traverserContext.thisNode()); + childrenMap.keySet().forEach(key -> { + List children = childrenMap.get(key); + for (int i = 0; i < children.size(); i++) { + U child = assertNotNull(children.get(i), "null child for key %s",key); + NodeLocation nodeLocation = new NodeLocation(key, i); + DefaultTraverserContext context = super.newContext(child, traverserContext, nodeLocation); + childrenContextMap.computeIfAbsent(key, notUsed -> new ArrayList<>()); + childrenContextMap.get(key).add(context); + super.state.add(context); + } + }); + } + EndList endList = new EndList<>(); + endList.childrenContextMap = childrenContextMap; + super.state.add(endList); + super.state.add(traverserContext); } } - public enum Marker { - END_LIST + public static class EndList { + public Map>> childrenContextMap; } - private TraverserState(Object initialData) { - this.initialData = initialData; + private TraverserState(Object sharedContextData) { + this.sharedContextData = sharedContextData; this.state = new ArrayDeque<>(32); } - public static TraverserState newQueueState(Object initialData) { - return new QueueTraverserState<>(initialData); + public static TraverserState newQueueState(Object sharedContextData) { + return new QueueTraverserState<>(sharedContextData); } - public static TraverserState newStackState(Object initialData) { - return new StackTraverserState<>(initialData); + public static TraverserState newStackState(Object sharedContextData) { + return new StackTraverserState<>(sharedContextData); } - public abstract void pushAll(TraverserContext o, Function> getChildren); + public abstract void pushAll(TraverserContext o, Function>> getChildren); public Object pop() { return this.state.pop(); } - public void addNewContexts(Collection children, TraverserContext root) { - assertNotNull(children).stream().map((x) -> newContext(x, root)).forEach(this.state::add); + public void addNewContexts(Collection children, TraverserContext parentContext) { + assertNotNull(children).stream().map((child) -> newContext(child, parentContext, null)).forEach(this.state::add); } public boolean isEmpty() { @@ -91,93 +125,21 @@ public void addVisited(T visited) { this.visited.add(visited); } - public TraverserContext newContext(T o, TraverserContext parent) { - return newContext(o, parent, new LinkedHashMap<>()); - } - - public TraverserContext newContext(T curNode, TraverserContext parent, Map, Object> vars) { - assertNotNull(vars); - - return new TraverserContext() { - Object result; - - @Override - public T thisNode() { - return curNode; - } - - @Override - public TraverserContext getParentContext() { - return parent; - } - - @Override - public Object getParentResult() { - return parent.getResult(); - } - - @Override - public Set visitedNodes() { - return visited; - } - - @Override - public boolean isVisited() { - return visited.contains(curNode); - } - - @Override - public S getVar(Class key) { - return (S) key.cast(vars.get(key)); - } - - @Override - public TraverserContext setVar(Class key, S value) { - vars.put(key, value); - return this; - } - @Override - public void setResult(Object result) { - this.result = result; - } - - @Override - public Object getResult() { - return this.result; - } - - @Override - public Object getInitialData() { - return initialData; - } - - - }; + public DefaultTraverserContext newRootContext(Map, Object> vars) { + return newContextImpl(null, null, vars, null, true); } - private static class ReverseIterator implements Iterator { - private final ListIterator delegate; - - private ReverseIterator(List list) { - assertNotNull(list); - - this.delegate = list.listIterator(list.size()); - } - - @Override - public boolean hasNext() { - return delegate.hasPrevious(); - } - - @Override - public T next() { - return delegate.previous(); - } + private DefaultTraverserContext newContext(T o, TraverserContext parent, NodeLocation position) { + return newContextImpl(o, parent, new LinkedHashMap<>(), position, false); + } - @Override - public void remove() { - delegate.remove(); - } + private DefaultTraverserContext newContextImpl(T curNode, + TraverserContext parent, + Map, Object> vars, + NodeLocation nodeLocation, + boolean isRootContext) { + assertNotNull(vars); + return new DefaultTraverserContext<>(curNode, parent, visited, vars, sharedContextData, nodeLocation, isRootContext, false); } } diff --git a/src/main/java/graphql/util/TraverserVisitor.java b/src/main/java/graphql/util/TraverserVisitor.java index f7f2bc7c90..fa8f5cccc0 100644 --- a/src/main/java/graphql/util/TraverserVisitor.java +++ b/src/main/java/graphql/util/TraverserVisitor.java @@ -20,6 +20,12 @@ public interface TraverserVisitor { TraversalControl leave(TraverserContext context); /** + * This method is called when a node was already visited before. + * + * This can happen for two reasons: + * 1. There is a cycle. + * 2. A node has more than one parent. This means the structure is not a tree but a graph. + * * @param context the context in place * * @return Only Continue or Quit allowed diff --git a/src/main/java/graphql/util/TraverserVisitorStub.java b/src/main/java/graphql/util/TraverserVisitorStub.java new file mode 100644 index 0000000000..5ca930937d --- /dev/null +++ b/src/main/java/graphql/util/TraverserVisitorStub.java @@ -0,0 +1,19 @@ +package graphql.util; + +import graphql.Internal; + +@Internal +public class TraverserVisitorStub implements TraverserVisitor { + + + @Override + public TraversalControl enter(TraverserContext context) { + return TraversalControl.CONTINUE; + } + + @Override + public TraversalControl leave(TraverserContext context) { + return TraversalControl.CONTINUE; + } + +} diff --git a/src/main/java/graphql/util/TreeParallelTransformer.java b/src/main/java/graphql/util/TreeParallelTransformer.java new file mode 100644 index 0000000000..5bbde1cd1b --- /dev/null +++ b/src/main/java/graphql/util/TreeParallelTransformer.java @@ -0,0 +1,252 @@ +package graphql.util; + +import graphql.Internal; +import graphql.collect.ImmutableKit; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountedCompleter; +import java.util.concurrent.ForkJoinPool; + +import static graphql.Assert.assertNotEmpty; +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.util.NodeZipper.ModificationType.REPLACE; +import static graphql.util.TraversalControl.ABORT; +import static graphql.util.TraversalControl.CONTINUE; +import static graphql.util.TraversalControl.QUIT; + +@Internal +public class TreeParallelTransformer { + + private final Map, Object> rootVars = new ConcurrentHashMap<>(); + + private final ForkJoinPool forkJoinPool; + private final NodeAdapter nodeAdapter; + + + private final Object sharedContextData; + + + private TreeParallelTransformer(Object sharedContextData, + ForkJoinPool forkJoinPool, + NodeAdapter nodeAdapter) { + this.sharedContextData = sharedContextData; + this.forkJoinPool = forkJoinPool; + this.nodeAdapter = nodeAdapter; + } + + public static TreeParallelTransformer parallelTransformer(NodeAdapter nodeAdapter) { + return parallelTransformer(nodeAdapter, ForkJoinPool.commonPool()); + } + + public static TreeParallelTransformer parallelTransformer(NodeAdapter nodeAdapter, ForkJoinPool forkJoinPool) { + return new TreeParallelTransformer<>(null, forkJoinPool, nodeAdapter); + + } + + + public TreeParallelTransformer rootVars(Map, Object> rootVars) { + this.rootVars.putAll(assertNotNull(rootVars)); + return this; + } + + public TreeParallelTransformer rootVar(Class key, Object value) { + rootVars.put(key, value); + return this; + } + + public T transform(T root, TraverserVisitor visitor) { + return transformImpl(root, visitor); + } + + + public DefaultTraverserContext newRootContext(Map, Object> vars) { + return newContextImpl(null, null, vars, null, true); + } + + + public T transformImpl(T root, TraverserVisitor visitor) { + assertNotNull(root); + assertNotNull(visitor); + + DefaultTraverserContext rootContext = newRootContext(rootVars); + DefaultTraverserContext context = newContext(root, rootContext, null); + EnterAction enterAction = new EnterAction(null, context, visitor); + T result = (T) forkJoinPool.invoke(enterAction); + return result; + } + + private class EnterAction extends CountedCompleter { + private DefaultTraverserContext currentContext; + private TraverserVisitor visitor; + private List children; + private List> myZippers = new LinkedList<>(); + private T result; + + private EnterAction(CountedCompleter parent, DefaultTraverserContext currentContext, TraverserVisitor visitor) { + super(parent); + this.currentContext = currentContext; + this.visitor = visitor; + } + + @Override + public void compute() { + currentContext.setPhase(TraverserContext.Phase.ENTER); + currentContext.setVar(List.class, myZippers); + TraversalControl traversalControl = visitor.enter(currentContext); + assertNotNull(traversalControl, "result of enter must not be null"); + assertTrue(QUIT != traversalControl, "can't return QUIT for parallel traversing"); + if (traversalControl == ABORT) { + this.children = ImmutableKit.emptyList(); + tryComplete(); + return; + } + assertTrue(traversalControl == CONTINUE); + + this.children = pushAll(currentContext); + if (children.size() == 0) { + tryComplete(); + return; + } + setPendingCount(children.size() - 1); + for (int i = 1; i < children.size(); i++) { + new EnterAction(this, children.get(i), visitor).fork(); + } + new EnterAction(this, children.get(0), visitor).compute(); + } + + @Override + public void onCompletion(CountedCompleter caller) { + if (currentContext.isDeleted()) { + this.result = null; + return; + } + List> childZippers = new LinkedList<>(); + for (DefaultTraverserContext childContext : this.children) { + childZippers.addAll((Collection>) childContext.getVar(List.class)); + } + if (childZippers.size() > 0) { + NodeZipper newNode = moveUp((T) currentContext.thisNode(), childZippers); + myZippers.add(newNode); + this.result = (T) newNode.getCurNode(); + } else if (currentContext.isChanged()) { + NodeZipper newNode = new NodeZipper(currentContext.thisNode(), currentContext.getBreadcrumbs(), nodeAdapter); + myZippers.add(newNode); + this.result = (T) currentContext.thisNode(); + } else { + this.result = (T) currentContext.thisNode(); + } + } + + @Override + public T getRawResult() { + return result; + } + + private NodeZipper moveUp(T parent, List> sameParent) { + assertNotEmpty(sameParent, "expected at least one zipper"); + + Map> childrenMap = new HashMap<>(nodeAdapter.getNamedChildren(parent)); + Map indexCorrection = new HashMap<>(); + + sameParent.sort((zipper1, zipper2) -> { + int index1 = zipper1.getBreadcrumbs().get(0).getLocation().getIndex(); + int index2 = zipper2.getBreadcrumbs().get(0).getLocation().getIndex(); + if (index1 != index2) { + return Integer.compare(index1, index2); + } + NodeZipper.ModificationType modificationType1 = zipper1.getModificationType(); + NodeZipper.ModificationType modificationType2 = zipper2.getModificationType(); + + // same index can never be deleted and changed at the same time + + if (modificationType1 == modificationType2) { + return 0; + } + + // always first replacing the node + if (modificationType1 == REPLACE) { + return -1; + } + // and then INSERT_BEFORE before INSERT_AFTER + return modificationType1 == NodeZipper.ModificationType.INSERT_BEFORE ? -1 : 1; + + }); + + for (NodeZipper zipper : sameParent) { + NodeLocation location = zipper.getBreadcrumbs().get(0).getLocation(); + Integer ixDiff = indexCorrection.getOrDefault(location.getName(), 0); + int ix = location.getIndex() + ixDiff; + String name = location.getName(); + List childList = new ArrayList<>(childrenMap.get(name)); + switch (zipper.getModificationType()) { + case REPLACE: + childList.set(ix, zipper.getCurNode()); + break; + case DELETE: + childList.remove(ix); + indexCorrection.put(name, ixDiff - 1); + break; + case INSERT_BEFORE: + childList.add(ix, zipper.getCurNode()); + indexCorrection.put(name, ixDiff + 1); + break; + case INSERT_AFTER: + childList.add(ix + 1, zipper.getCurNode()); + indexCorrection.put(name, ixDiff + 1); + break; + } + childrenMap.put(name, childList); + } + + T newNode = nodeAdapter.withNewChildren(parent, childrenMap); + List> newBreadcrumbs = sameParent.get(0).getBreadcrumbs().subList(1, sameParent.get(0).getBreadcrumbs().size()); + return new NodeZipper<>(newNode, newBreadcrumbs, nodeAdapter); + } + } + + private List pushAll(TraverserContext traverserContext) { + + Map>> childrenContextMap = new LinkedHashMap<>(); + + LinkedList contexts = new LinkedList<>(); + if (!traverserContext.isDeleted()) { + + Map> childrenMap = this.nodeAdapter.getNamedChildren(traverserContext.thisNode()); + childrenMap.keySet().forEach(key -> { + List children = childrenMap.get(key); + for (int i = children.size() - 1; i >= 0; i--) { + T child = assertNotNull(children.get(i), "null child for key %s", key); + NodeLocation nodeLocation = new NodeLocation(key, i); + DefaultTraverserContext context = newContext(child, traverserContext, nodeLocation); + contexts.push(context); + childrenContextMap.computeIfAbsent(key, notUsed -> new ArrayList<>()); + childrenContextMap.get(key).add(0, context); + } + }); + } + return contexts; + } + + private DefaultTraverserContext newContext(T o, TraverserContext parent, NodeLocation position) { + return newContextImpl(o, parent, new LinkedHashMap<>(), position, false); + } + + private DefaultTraverserContext newContextImpl(T curNode, + TraverserContext parent, + Map, Object> vars, + NodeLocation nodeLocation, + boolean isRootContext) { + assertNotNull(vars); + return new DefaultTraverserContext<>(curNode, parent, null, vars, sharedContextData, nodeLocation, isRootContext, true); + } +} + + diff --git a/src/main/java/graphql/util/TreeParallelTraverser.java b/src/main/java/graphql/util/TreeParallelTraverser.java new file mode 100644 index 0000000000..9101226519 --- /dev/null +++ b/src/main/java/graphql/util/TreeParallelTraverser.java @@ -0,0 +1,191 @@ +package graphql.util; + +import graphql.Internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountedCompleter; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Function; + +import static graphql.Assert.assertNotNull; +import static graphql.Assert.assertTrue; +import static graphql.util.TraversalControl.ABORT; +import static graphql.util.TraversalControl.CONTINUE; +import static graphql.util.TraversalControl.QUIT; + +@Internal +public class TreeParallelTraverser { + + private final Function>> getChildren; + private final Map, Object> rootVars = new ConcurrentHashMap<>(); + + private final ForkJoinPool forkJoinPool; + + private Object sharedContextData; + + + private TreeParallelTraverser(Function>> getChildren, + Object sharedContextData, + ForkJoinPool forkJoinPool) { + this.getChildren = assertNotNull(getChildren); + this.sharedContextData = sharedContextData; + this.forkJoinPool = forkJoinPool; + } + + public static TreeParallelTraverser parallelTraverser(Function> getChildren) { + return parallelTraverser(getChildren, null, ForkJoinPool.commonPool()); + } + + public static TreeParallelTraverser parallelTraverser(Function> getChildren, + Object sharedContextData) { + return new TreeParallelTraverser<>(wrapListFunction(getChildren), sharedContextData, ForkJoinPool.commonPool()); + } + + public static TreeParallelTraverser parallelTraverser(Function> getChildren, + Object sharedContextData, + ForkJoinPool forkJoinPool) { + return new TreeParallelTraverser<>(wrapListFunction(getChildren), sharedContextData, forkJoinPool); + } + + + public static TreeParallelTraverser parallelTraverserWithNamedChildren(Function>> getNamedChildren, + Object sharedContextData) { + return new TreeParallelTraverser<>(getNamedChildren, sharedContextData, ForkJoinPool.commonPool()); + } + + public static TreeParallelTraverser parallelTraverserWithNamedChildren(Function>> getNamedChildren, + Object sharedContextData, + ForkJoinPool forkJoinPool) { + return new TreeParallelTraverser<>(getNamedChildren, sharedContextData, forkJoinPool); + } + + + private static Function>> wrapListFunction(Function> listFn) { + return node -> { + List childs = listFn.apply(node); + return Collections.singletonMap(null, childs); + }; + } + + public TreeParallelTraverser rootVars(Map, Object> rootVars) { + this.rootVars.putAll(assertNotNull(rootVars)); + return this; + } + + public TreeParallelTraverser rootVar(Class key, Object value) { + rootVars.put(key, value); + return this; + } + + public void traverse(T root, TraverserVisitor visitor) { + traverse(Collections.singleton(root), visitor); + } + + public void traverse(Collection roots, TraverserVisitor visitor) { + traverseImpl(roots, visitor); + } + + public DefaultTraverserContext newRootContext(Map, Object> vars) { + return newContextImpl(null, null, vars, null, true); + } + + + public void traverseImpl(Collection roots, TraverserVisitor visitor) { + assertNotNull(roots); + assertNotNull(visitor); + + DefaultTraverserContext rootContext = newRootContext(rootVars); + forkJoinPool.invoke(new CountedCompleter() { + @Override + public void compute() { + setPendingCount(roots.size()); + for (T root : roots) { + DefaultTraverserContext context = newContext(root, rootContext, null); + EnterAction enterAction = new EnterAction(this, context, visitor); + enterAction.fork(); + } + tryComplete(); + } + + }); + } + + private class EnterAction extends CountedCompleter { + private DefaultTraverserContext currentContext; + private TraverserVisitor visitor; + + private EnterAction(CountedCompleter parent, DefaultTraverserContext currentContext, TraverserVisitor visitor) { + super(parent); + this.currentContext = currentContext; + this.visitor = visitor; + } + + @Override + public void compute() { + currentContext.setPhase(TraverserContext.Phase.ENTER); + TraversalControl traversalControl = visitor.enter(currentContext); + assertNotNull(traversalControl, "result of enter must not be null"); + assertTrue(QUIT != traversalControl, "can't return QUIT for parallel traversing"); + if (traversalControl == ABORT) { + tryComplete(); + return; + } + assertTrue(traversalControl == CONTINUE); + List children = pushAll(currentContext); + if (children.size() == 0) { + tryComplete(); + return; + } + setPendingCount(children.size() - 1); + for (int i = 1; i < children.size(); i++) { + new EnterAction(this, children.get(i), visitor).fork(); + } + new EnterAction(this, children.get(0), visitor).compute(); + } + } + + private List pushAll(TraverserContext traverserContext) { + + Map>> childrenContextMap = new LinkedHashMap<>(); + + LinkedList contexts = new LinkedList<>(); + if (!traverserContext.isDeleted()) { + + Map> childrenMap = getChildren.apply(traverserContext.thisNode()); + childrenMap.keySet().forEach(key -> { + List children = childrenMap.get(key); + for (int i = children.size() - 1; i >= 0; i--) { + T child = assertNotNull(children.get(i), "null child for key %s", key); + NodeLocation nodeLocation = new NodeLocation(key, i); + DefaultTraverserContext context = newContext(child, traverserContext, nodeLocation); + contexts.push(context); + childrenContextMap.computeIfAbsent(key, notUsed -> new ArrayList<>()); + childrenContextMap.get(key).add(0, context); + } + }); + } + return contexts; + } + + private DefaultTraverserContext newContext(T o, TraverserContext parent, NodeLocation position) { + return newContextImpl(o, parent, new LinkedHashMap<>(), position, false); + } + + private DefaultTraverserContext newContextImpl(T curNode, + TraverserContext parent, + Map, Object> vars, + NodeLocation nodeLocation, + boolean isRootContext) { + assertNotNull(vars); + return new DefaultTraverserContext<>(curNode, parent, null, vars, sharedContextData, nodeLocation, isRootContext, true); + } +} + + diff --git a/src/main/java/graphql/util/TreeTransformer.java b/src/main/java/graphql/util/TreeTransformer.java new file mode 100644 index 0000000000..970b0eac48 --- /dev/null +++ b/src/main/java/graphql/util/TreeTransformer.java @@ -0,0 +1,60 @@ +package graphql.util; + + +import graphql.PublicApi; +import graphql.collect.ImmutableKit; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static graphql.Assert.assertNotNull; + +@PublicApi +public class TreeTransformer { + + private final NodeAdapter nodeAdapter; + + public TreeTransformer(NodeAdapter nodeAdapter) { + this.nodeAdapter = nodeAdapter; + } + + public T transform(T root, TraverserVisitor traverserVisitor) { + return transform(root, traverserVisitor, ImmutableKit.emptyMap()); + } + + public T transform(T root, TraverserVisitor traverserVisitor, Map, Object> rootVars) { + assertNotNull(root); + + + TraverserVisitor nodeTraverserVisitor = new TraverserVisitor() { + + @Override + public TraversalControl enter(TraverserContext context) { + NodeZipper nodeZipper = new NodeZipper<>(context.thisNode(), context.getBreadcrumbs(), nodeAdapter); + context.setVar(NodeZipper.class, nodeZipper); + context.setVar(NodeAdapter.class, nodeAdapter); + return traverserVisitor.enter(context); + } + + @Override + public TraversalControl leave(TraverserContext context) { + return traverserVisitor.leave(context); + } + + @Override + public TraversalControl backRef(TraverserContext context) { + return traverserVisitor.backRef(context); + } + }; + + List> zippers = new LinkedList<>(); + Traverser traverser = Traverser.depthFirstWithNamedChildren(nodeAdapter::getNamedChildren, zippers, null); + traverser.rootVars(rootVars); + traverser.traverse(root, nodeTraverserVisitor); + + NodeMultiZipper multiZipper = NodeMultiZipper.newNodeMultiZipperTrusted(root, zippers, nodeAdapter); + return multiZipper.toRootNode(); + } + +} diff --git a/src/main/java/graphql/util/TreeTransformerUtil.java b/src/main/java/graphql/util/TreeTransformerUtil.java new file mode 100644 index 0000000000..0ee41a3b3a --- /dev/null +++ b/src/main/java/graphql/util/TreeTransformerUtil.java @@ -0,0 +1,106 @@ +package graphql.util; + +import graphql.PublicApi; + +import java.util.List; +import java.util.Queue; + +import static graphql.Assert.assertTrue; + +@PublicApi +public class TreeTransformerUtil { + + /** + * Can be called multiple times to change the current node of the context. The latest call wins + * + * @param context the context in play + * @param changedNode the changed node + * @param for two + * + * @return traversal control + */ + public static TraversalControl changeNode(TraverserContext context, T changedNode) { + boolean changed = context.isChanged(); + if (context.isParallel()) { + List> zippers = context.getVar(List.class); + NodeAdapter adapter = context.getVar(NodeAdapter.class); + if (changed) { + replaceZipperForNode(zippers, context.thisNode(), changedNode); + context.changeNode(changedNode); + } else { + NodeZipper nodeZipper = new NodeZipper<>(changedNode, context.getBreadcrumbs(), adapter); + zippers.add(nodeZipper); + context.changeNode(changedNode); + } + return TraversalControl.CONTINUE; + } else { + NodeZipper zipperWithChangedNode = context.getVar(NodeZipper.class).withNewNode(changedNode); + List> zippers = context.getSharedContextData(); + if (changed) { + // this is potentially expensive + replaceZipperForNode(zippers, context.thisNode(), changedNode); + context.changeNode(changedNode); + } else { + zippers.add(zipperWithChangedNode); + context.changeNode(changedNode); + } + return TraversalControl.CONTINUE; + } + } + + private static void replaceZipperForNode(List> zippers, T currentNode, T newNode) { + int index = FpKit.findIndex(zippers, zipper -> zipper.getCurNode() == currentNode); + assertTrue(index >= 0, "No current zipper found for provided node"); + NodeZipper newZipper = zippers.get(index).withNewNode(newNode); + zippers.set(index, newZipper); + } + + public static TraversalControl deleteNode(TraverserContext context) { + if (context.isParallel()) { + NodeAdapter adapter = context.getVar(NodeAdapter.class); + NodeZipper deleteNodeZipper = new NodeZipper<>(context.thisNode(), context.getBreadcrumbs(), adapter).deleteNode(); + List> zippers = context.getVar(List.class); + zippers.add(deleteNodeZipper); + context.deleteNode(); + return TraversalControl.CONTINUE; + } else { + NodeZipper deleteNodeZipper = context.getVar(NodeZipper.class).deleteNode(); + Queue> zippers = context.getSharedContextData(); + zippers.add(deleteNodeZipper); + context.deleteNode(); + return TraversalControl.CONTINUE; + } + } + + public static TraversalControl insertAfter(TraverserContext context, T toInsertAfter) { + if (context.isParallel()) { + NodeAdapter adapter = context.getVar(NodeAdapter.class); + NodeZipper insertNodeZipper = new NodeZipper<>(context.originalThisNode(), context.getBreadcrumbs(), adapter).insertAfter(toInsertAfter); + List> zippers = context.getVar(List.class); + zippers.add(insertNodeZipper); + return TraversalControl.CONTINUE; + } else { + NodeZipper insertNodeZipper = context.getVar(NodeZipper.class).insertAfter(toInsertAfter); + Queue> zippers = context.getSharedContextData(); + zippers.add(insertNodeZipper); + return TraversalControl.CONTINUE; + } + } + + public static TraversalControl insertBefore(TraverserContext context, T toInsertBefore) { + if (context.isParallel()) { + NodeAdapter adapter = context.getVar(NodeAdapter.class); + NodeZipper insertNodeZipper = new NodeZipper<>(context.originalThisNode(), context.getBreadcrumbs(), adapter).insertBefore(toInsertBefore); + List> zippers = context.getVar(List.class); + zippers.add(insertNodeZipper); + return TraversalControl.CONTINUE; + } else { + NodeZipper insertNodeZipper = context.getVar(NodeZipper.class).insertBefore(toInsertBefore); + Queue> zippers = context.getSharedContextData(); + zippers.add(insertNodeZipper); + return TraversalControl.CONTINUE; + } + } + + +} diff --git a/src/main/java/graphql/util/querygenerator/QueryGenerator.java b/src/main/java/graphql/util/querygenerator/QueryGenerator.java new file mode 100644 index 0000000000..a176164683 --- /dev/null +++ b/src/main/java/graphql/util/querygenerator/QueryGenerator.java @@ -0,0 +1,170 @@ +package graphql.util.querygenerator; + +import graphql.ExperimentalApi; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLOutputType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLUnionType; +import graphql.util.querygenerator.QueryGeneratorFieldSelection.FieldSelection; +import graphql.util.querygenerator.QueryGeneratorFieldSelection.FieldSelectionResult; +import org.jspecify.annotations.Nullable; + +import java.util.stream.Stream; + +/** + * Generates a GraphQL query string based on the provided operation field path, operation name, arguments, and type classifier. + *

    + * While this class is useful for testing purposes, such as ensuring that all fields from a certain type are being + * fetched correctly, it is important to note that generating GraphQL queries with all possible fields defeats one of + * the main purposes of a GraphQL API: allowing clients to be selective about the fields they want to fetch. + *

    + * Callers can pass options to customize the query generation process, such as filtering fields or + * limiting the maximum number of fields. + *

    + * + */ +@ExperimentalApi +public class QueryGenerator { + private final GraphQLSchema schema; + private final QueryGeneratorFieldSelection fieldSelectionGenerator; + private final QueryGeneratorPrinter printer; + + + /** + * Constructor for QueryGenerator using default options. + * + * @param schema the GraphQL schema + */ + public QueryGenerator(GraphQLSchema schema) { + this.schema = schema; + this.fieldSelectionGenerator = new QueryGeneratorFieldSelection(schema, QueryGeneratorOptions.newBuilder().build()); + this.printer = new QueryGeneratorPrinter(); + } + + /** + * Constructor for QueryGenerator. + * + * @param schema the GraphQL schema + * @param options the options for query generation + */ + public QueryGenerator(GraphQLSchema schema, QueryGeneratorOptions options) { + this.schema = schema; + this.fieldSelectionGenerator = new QueryGeneratorFieldSelection(schema, options); + this.printer = new QueryGeneratorPrinter(); + } + + /** + * Generates a GraphQL query string based on the provided operation field path, operation name, arguments, + * and type classifier. + * + *

    + * operationFieldPath is a string that represents the path to the field in the GraphQL schema. This method + * will generate a query that includes all fields from the specified type, including nested fields. + *

    + * operationName is optional. When passed, the generated query will contain that value in the operation name. + *

    + * arguments are optional. When passed, the generated query will contain that value in the arguments. + *

    + * typeName is optional. It should not be passed in when the field in the path is an object type, and it + * **should** be passed when the field in the path is an interface or union type. In the latter case, its value + * should be an object type that is part of the union or implements the interface. + * + * @param operationFieldPath the operation field path (e.g., "Query.user", "Mutation.createUser", "Subscription.userCreated") + * @param operationName optional: the operation name (e.g., "getUser") + * @param arguments optional: the arguments for the operation in a plain text form (e.g., "(id: 1)") + * @param typeName optional: the type name for when operationFieldPath points to a field of union or interface types (e.g., "FirstPartyUser") + * + * @return a QueryGeneratorResult containing the generated query string and additional information + */ + public QueryGeneratorResult generateQuery( + String operationFieldPath, + @Nullable String operationName, + @Nullable String arguments, + @Nullable String typeName + ) { + String[] fieldParts = operationFieldPath.split("\\."); + String operation = fieldParts[0]; + + if (fieldParts.length < 2) { + throw new IllegalArgumentException("Field path must contain at least an operation and a field"); + } + + if (!operation.equals("Query") && !operation.equals("Mutation") && !operation.equals("Subscription")) { + throw new IllegalArgumentException("Operation must be 'Query', 'Mutation' or 'Subscription'"); + } + + GraphQLFieldsContainer fieldContainer = schema.getObjectType(operation); + + for (int i = 1; i < fieldParts.length - 1; i++) { + String fieldName = fieldParts[i]; + GraphQLFieldDefinition fieldDefinition = fieldContainer.getFieldDefinition(fieldName); + if (fieldDefinition == null) { + throw new IllegalArgumentException("Field " + fieldName + " not found in type " + fieldContainer.getName()); + } + // intermediate fields in the path need to be a field container + if (!(fieldDefinition.getType() instanceof GraphQLFieldsContainer)) { + throw new IllegalArgumentException("Type " + fieldDefinition.getType() + " is not a field container"); + } + fieldContainer = (GraphQLFieldsContainer) fieldDefinition.getType(); + } + + String lastFieldName = fieldParts[fieldParts.length - 1]; + GraphQLFieldDefinition lastFieldDefinition = fieldContainer.getFieldDefinition(lastFieldName); + if (lastFieldDefinition == null) { + throw new IllegalArgumentException("Field " + lastFieldName + " not found in type " + fieldContainer.getName()); + } + + // last field may be an object, interface or union type + GraphQLOutputType lastType = GraphQLTypeUtil.unwrapAllAs(lastFieldDefinition.getType()); + + final GraphQLFieldsContainer lastFieldContainer; + + if (lastType instanceof GraphQLObjectType) { + if (typeName != null) { + throw new IllegalArgumentException("typeName should be used only with interface or union types"); + } + lastFieldContainer = (GraphQLObjectType) lastType; + } else if (lastType instanceof GraphQLUnionType) { + if (typeName == null) { + throw new IllegalArgumentException("typeName is required for union types"); + } + lastFieldContainer = ((GraphQLUnionType) lastType).getTypes().stream() + .filter(GraphQLFieldsContainer.class::isInstance) + .map(GraphQLFieldsContainer.class::cast) + .filter(type -> type.getName().equals(typeName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Type " + typeName + " not found in union " + ((GraphQLUnionType) lastType).getName())); + } else if (lastType instanceof GraphQLInterfaceType) { + if (typeName == null) { + throw new IllegalArgumentException("typeName is required for interface types"); + } + Stream fieldsContainerStream = Stream.concat( + Stream.of((GraphQLInterfaceType) lastType), + schema.getImplementations((GraphQLInterfaceType) lastType).stream() + ); + + lastFieldContainer = fieldsContainerStream + .filter(type -> type.getName().equals(typeName)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Type " + typeName + " not found in interface " + ((GraphQLInterfaceType) lastType).getName())); + } else { + throw new IllegalArgumentException("Type " + lastType + " is not a field container"); + } + + FieldSelectionResult fieldSelectionResult = fieldSelectionGenerator.buildFields(lastFieldContainer); + FieldSelection rootFieldSelection = fieldSelectionResult.rootFieldSelection; + + String query = printer.print(operationFieldPath, operationName, arguments, rootFieldSelection); + + return new QueryGeneratorResult( + query, + lastFieldContainer.getName(), + fieldSelectionResult.totalFieldCount, + fieldSelectionResult.reachedMaxFieldCount + ); + } +} diff --git a/src/main/java/graphql/util/querygenerator/QueryGeneratorFieldSelection.java b/src/main/java/graphql/util/querygenerator/QueryGeneratorFieldSelection.java new file mode 100644 index 0000000000..0662854c77 --- /dev/null +++ b/src/main/java/graphql/util/querygenerator/QueryGeneratorFieldSelection.java @@ -0,0 +1,197 @@ +package graphql.util.querygenerator; + +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInterfaceType; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.GraphQLUnionType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +class QueryGeneratorFieldSelection { + private final QueryGeneratorOptions options; + private final GraphQLSchema schema; + + private static final GraphQLObjectType EMPTY_OBJECT_TYPE = GraphQLObjectType.newObject() + .name("Empty") + .build(); + + QueryGeneratorFieldSelection(GraphQLSchema schema, QueryGeneratorOptions options) { + this.options = options; + this.schema = schema; + } + + FieldSelectionResult buildFields(GraphQLFieldsContainer fieldsContainer) { + Queue> containersQueue = new LinkedList<>(); + containersQueue.add(Collections.singletonList(fieldsContainer)); + + Queue fieldSelectionQueue = new LinkedList<>(); + FieldSelection root = new FieldSelection(fieldsContainer.getName(), new HashMap<>(), false); + fieldSelectionQueue.add(root); + + Set visited = new HashSet<>(); + AtomicInteger totalFieldCount = new AtomicInteger(0); + boolean reachedMaxFieldCount = false; + + while (!reachedMaxFieldCount &&!containersQueue.isEmpty()) { + processContainers(containersQueue, fieldSelectionQueue, visited, totalFieldCount); + + if (totalFieldCount.get() >= options.getMaxFieldCount()) { + reachedMaxFieldCount = true; + } + } + + return new FieldSelectionResult( + root, + totalFieldCount.get(), + reachedMaxFieldCount + ); + } + + private void processContainers(Queue> containersQueue, + Queue fieldSelectionQueue, + Set visited, + AtomicInteger totalFieldCount) { + List containers = containersQueue.poll(); + FieldSelection fieldSelection = fieldSelectionQueue.poll(); + + for (GraphQLFieldsContainer container : Objects.requireNonNull(containers)) { + if (!options.getFilterFieldContainerPredicate().test(container)) { + continue; + } + + for (GraphQLFieldDefinition fieldDef : container.getFieldDefinitions()) { + if (!options.getFilterFieldDefinitionPredicate().test(fieldDef)) { + continue; + } + + if (totalFieldCount.get() >= options.getMaxFieldCount()) { + break; + } + + if (hasRequiredArgs(fieldDef)) { + continue; + } + + FieldCoordinates fieldCoordinates = FieldCoordinates.coordinates(container, fieldDef.getName()); + + if (visited.contains(fieldCoordinates)) { + continue; + } + + processField( + container, + fieldDef, + Objects.requireNonNull(fieldSelection), + containersQueue, + fieldSelectionQueue, + fieldCoordinates, + visited, + totalFieldCount + ); + } + } + } + + private void processField(GraphQLFieldsContainer container, + GraphQLFieldDefinition fieldDef, + FieldSelection fieldSelection, + Queue> containersQueue, + Queue fieldSelectionQueue, + FieldCoordinates fieldCoordinates, + Set visited, + AtomicInteger totalFieldCount) { + + GraphQLType unwrappedType = GraphQLTypeUtil.unwrapAll(fieldDef.getType()); + FieldSelection newFieldSelection = getFieldSelection(fieldDef, unwrappedType); + + fieldSelection.fieldsByContainer.computeIfAbsent(container.getName(), key -> new ArrayList<>()).add(newFieldSelection); + + fieldSelectionQueue.add(newFieldSelection); + + if (unwrappedType instanceof GraphQLInterfaceType) { + visited.add(fieldCoordinates); + GraphQLInterfaceType interfaceType = (GraphQLInterfaceType) unwrappedType; + List possibleTypes = new ArrayList<>(schema.getImplementations(interfaceType)); + + containersQueue.add(possibleTypes); + } else if (unwrappedType instanceof GraphQLUnionType) { + visited.add(fieldCoordinates); + GraphQLUnionType unionType = (GraphQLUnionType) unwrappedType; + List possibleTypes = unionType.getTypes().stream() + .filter(possibleType -> possibleType instanceof GraphQLFieldsContainer) + .map(possibleType -> (GraphQLFieldsContainer) possibleType) + .collect(Collectors.toList()); + + containersQueue.add(possibleTypes); + } else if (unwrappedType instanceof GraphQLFieldsContainer) { + visited.add(fieldCoordinates); + containersQueue.add(Collections.singletonList((GraphQLFieldsContainer) unwrappedType)); + } else { + containersQueue.add(Collections.singletonList(EMPTY_OBJECT_TYPE)); + } + + totalFieldCount.incrementAndGet(); + } + + private static FieldSelection getFieldSelection(GraphQLFieldDefinition fieldDef, GraphQLType unwrappedType) { + boolean typeNeedsClassifier = unwrappedType instanceof GraphQLUnionType || unwrappedType instanceof GraphQLInterfaceType; + + // TODO: This statement is kinda awful + final FieldSelection newFieldSelection; + + if (typeNeedsClassifier) { + newFieldSelection = new FieldSelection(fieldDef.getName(), new HashMap<>(), true); + } else if (unwrappedType instanceof GraphQLFieldsContainer) { + newFieldSelection = new FieldSelection(fieldDef.getName(), new HashMap<>(), false); + } else { + newFieldSelection = new FieldSelection(fieldDef.getName(), null, false); + } + return newFieldSelection; + } + + private boolean hasRequiredArgs(GraphQLFieldDefinition fieldDefinition) { + // TODO: Maybe provide a hook to allow callers to resolve required arguments + return fieldDefinition.getArguments().stream() + .anyMatch(arg -> GraphQLTypeUtil.isNonNull(arg.getType()) && !arg.hasSetDefaultValue()); + } + + static class FieldSelection { + final String name; + final boolean needsTypeClassifier; + final Map> fieldsByContainer; + + public FieldSelection(String name, Map> fieldsByContainer, boolean needsTypeClassifier) { + this.name = name; + this.needsTypeClassifier = needsTypeClassifier; + this.fieldsByContainer = fieldsByContainer; + } + } + + static class FieldSelectionResult { + final FieldSelection rootFieldSelection; + final Integer totalFieldCount; + final Boolean reachedMaxFieldCount; + + FieldSelectionResult(FieldSelection rootFieldSelection, Integer totalFieldCount, Boolean reachedMaxFieldCount) { + this.rootFieldSelection = rootFieldSelection; + this.totalFieldCount = totalFieldCount; + this.reachedMaxFieldCount = reachedMaxFieldCount; + } + } +} diff --git a/src/main/java/graphql/util/querygenerator/QueryGeneratorOptions.java b/src/main/java/graphql/util/querygenerator/QueryGeneratorOptions.java new file mode 100644 index 0000000000..bc3fdeae65 --- /dev/null +++ b/src/main/java/graphql/util/querygenerator/QueryGeneratorOptions.java @@ -0,0 +1,142 @@ +package graphql.util.querygenerator; + +import graphql.ExperimentalApi; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLFieldsContainer; + +import java.util.function.Predicate; + +/** + * Options for the {@link QueryGenerator} class. + */ +@ExperimentalApi +public class QueryGeneratorOptions { + private final int maxFieldCount; + private final Predicate filterFieldContainerPredicate; + private final Predicate filterFieldDefinitionPredicate; + + private static final int MAX_FIELD_COUNT_LIMIT = 10_000; + + private QueryGeneratorOptions( + int maxFieldCount, + Predicate filterFieldContainerPredicate, + Predicate filterFieldDefinitionPredicate + ) { + this.maxFieldCount = maxFieldCount; + this.filterFieldContainerPredicate = filterFieldContainerPredicate; + this.filterFieldDefinitionPredicate = filterFieldDefinitionPredicate; + } + + /** + * Returns the maximum number of fields that can be included in the generated query. + * + * @return the maximum field count + */ + public int getMaxFieldCount() { + return maxFieldCount; + } + + /** + * Returns the predicate used to filter field containers. + *

    + * The field container will be filtered out if this predicate returns false. + * + * @return the predicate for filtering field containers + */ + public Predicate getFilterFieldContainerPredicate() { + return filterFieldContainerPredicate; + } + + /** + * Returns the predicate used to filter field definitions. + *

    + * The field definition will be filtered out if this predicate returns false. + * + * @return the predicate for filtering field definitions + */ + public Predicate getFilterFieldDefinitionPredicate() { + return filterFieldDefinitionPredicate; + } + + /** + * Builder for {@link QueryGeneratorOptions}. + */ + @ExperimentalApi + public static class QueryGeneratorOptionsBuilder { + private int maxFieldCount = MAX_FIELD_COUNT_LIMIT; + + private static final Predicate ALWAYS_TRUE = fieldsContainer -> true; + + @SuppressWarnings("unchecked") + private static Predicate alwaysTrue() { + return (Predicate) ALWAYS_TRUE; + } + + private Predicate filterFieldContainerPredicate = alwaysTrue(); + private Predicate filterFieldDefinitionPredicate = alwaysTrue(); + + private QueryGeneratorOptionsBuilder() {} + + /** + * Sets the maximum number of fields that can be included in the generated query. + *

    + * This value must be non-negative and cannot exceed {@link #MAX_FIELD_COUNT_LIMIT}. + * + * @param maxFieldCount the maximum field count + * @return this builder + */ + public QueryGeneratorOptionsBuilder maxFieldCount(int maxFieldCount) { + if (maxFieldCount < 0) { + throw new IllegalArgumentException("Max field count cannot be negative"); + } + if (maxFieldCount > MAX_FIELD_COUNT_LIMIT) { + throw new IllegalArgumentException("Max field count cannot exceed " + MAX_FIELD_COUNT_LIMIT); + } + this.maxFieldCount = maxFieldCount; + return this; + } + + /** + * Sets the predicate used to filter field containers. + *

    + * The field container will be filtered out if this predicate returns false. + * + * @param predicate the predicate for filtering field containers + * @return this builder + */ + public QueryGeneratorOptionsBuilder filterFieldContainerPredicate(Predicate predicate) { + this.filterFieldContainerPredicate = predicate; + return this; + } + + /** + * Sets the predicate used to filter field definitions. + *

    + * The field definition will be filtered out if this predicate returns false. + * + * @param predicate the predicate for filtering field definitions + * @return this builder + */ + public QueryGeneratorOptionsBuilder filterFieldDefinitionPredicate(Predicate predicate) { + this.filterFieldDefinitionPredicate = predicate; + return this; + } + + public QueryGeneratorOptions build() { + return new QueryGeneratorOptions( + maxFieldCount, + filterFieldContainerPredicate, + filterFieldDefinitionPredicate + ); + } + } + + /** + * Creates a new {@link QueryGeneratorOptionsBuilder} with default values. + * + * @return a new builder instance + */ + public static QueryGeneratorOptions.QueryGeneratorOptionsBuilder newBuilder() { + return new QueryGeneratorOptions.QueryGeneratorOptionsBuilder(); + } +} diff --git a/src/main/java/graphql/util/querygenerator/QueryGeneratorPrinter.java b/src/main/java/graphql/util/querygenerator/QueryGeneratorPrinter.java new file mode 100644 index 0000000000..94046943e2 --- /dev/null +++ b/src/main/java/graphql/util/querygenerator/QueryGeneratorPrinter.java @@ -0,0 +1,129 @@ +package graphql.util.querygenerator; + +import graphql.language.AstPrinter; +import graphql.parser.Parser; +import org.jspecify.annotations.Nullable; + +import java.util.List; +import java.util.stream.Collectors; + +class QueryGeneratorPrinter { + String print( + String operationFieldPath, + @Nullable String operationName, + @Nullable String arguments, + QueryGeneratorFieldSelection.FieldSelection rootFieldSelection + ) { + String[] fieldPathParts = operationFieldPath.split("\\."); + + String fields = printFieldsForTopLevelType(rootFieldSelection); + String start = printOperationStart(fieldPathParts, operationName, arguments); + String end = printOperationEnd(fieldPathParts); + String raw = start + fields + end; + + return AstPrinter.printAst(Parser.parse(raw)); + } + + private String printFieldsForTopLevelType(QueryGeneratorFieldSelection.FieldSelection rootFieldSelection) { + return rootFieldSelection.fieldsByContainer.values().iterator().next().stream() + .map(this::printFieldSelection) + .collect(Collectors.joining( + "", + "... on " + rootFieldSelection.name + " {\n", + "}\n" + )); + } + + private String printOperationStart( + String[] fieldPathParts, + @Nullable String operationName, + @Nullable String arguments + ) { + String operation = fieldPathParts[0].toLowerCase(); + StringBuilder sb = new StringBuilder(); + sb.append(operation); + + if (operationName != null) { + sb.append(" ").append(operationName).append(" "); + } + + sb.append(" {\n"); + + for (int i = 1; i < fieldPathParts.length; i++) { + sb.append(fieldPathParts[i]); + boolean isLastField = i == fieldPathParts.length - 1; + + if (isLastField) { + if (arguments != null) { + sb.append(arguments); + } + } + + sb.append(" {\n"); + + } + return sb.toString(); + } + + private String printOperationEnd(String[] fieldPathParts) { + return "}\n".repeat(fieldPathParts.length); + } + + private String printFieldSelectionForContainer( + String containerName, + List fieldSelections, + boolean needsTypeClassifier + ) { + String fieldStr = fieldSelections.stream() + .map(subField -> + printFieldSelection(subField, needsTypeClassifier ? containerName + "_" : null)) + .collect(Collectors.joining()); + + if (fieldStr.isEmpty()) { + return ""; + } + + StringBuilder fieldSelectionSb = new StringBuilder(); + if (needsTypeClassifier) { + fieldSelectionSb.append("... on ").append(containerName).append(" {\n"); + } + + fieldSelectionSb.append(fieldStr); + + if (needsTypeClassifier) { + fieldSelectionSb.append(" }\n"); + } + + return fieldSelectionSb.toString(); + } + + private String printFieldSelection(QueryGeneratorFieldSelection.FieldSelection fieldSelection, @Nullable String aliasPrefix) { + StringBuilder sb = new StringBuilder(); + if (fieldSelection.fieldsByContainer != null) { + String fieldSelectionString = fieldSelection.fieldsByContainer.entrySet().stream() + .map((entry) -> + printFieldSelectionForContainer(entry.getKey(), entry.getValue(), fieldSelection.needsTypeClassifier)) + .collect(Collectors.joining()); + // It is possible that some container fields ended up with empty fields (due to filtering etc). We shouldn't print those + if (!fieldSelectionString.isEmpty()) { + if (aliasPrefix != null) { + sb.append(aliasPrefix).append(fieldSelection.name).append(": "); + } + sb.append(fieldSelection.name) + .append(" {\n") + .append(fieldSelectionString) + .append("}\n"); + } + } else { + if (aliasPrefix != null) { + sb.append(aliasPrefix).append(fieldSelection.name).append(": "); + } + sb.append(fieldSelection.name).append("\n"); + } + return sb.toString(); + } + + private String printFieldSelection(QueryGeneratorFieldSelection.FieldSelection fieldSelection) { + return printFieldSelection(fieldSelection, null); + } +} diff --git a/src/main/java/graphql/util/querygenerator/QueryGeneratorResult.java b/src/main/java/graphql/util/querygenerator/QueryGeneratorResult.java new file mode 100644 index 0000000000..b7541f5d0a --- /dev/null +++ b/src/main/java/graphql/util/querygenerator/QueryGeneratorResult.java @@ -0,0 +1,62 @@ +package graphql.util.querygenerator; + +import graphql.ExperimentalApi; + +/** + * Represents the result of a query generation process. + */ +@ExperimentalApi +public class QueryGeneratorResult { + private final String query; + private final String usedType; + private final int totalFieldCount; + private final boolean reachedMaxFieldCount; + + public QueryGeneratorResult( + String query, + String usedType, + int totalFieldCount, + boolean reachedMaxFieldCount + ) { + this.query = query; + this.usedType = usedType; + this.totalFieldCount = totalFieldCount; + this.reachedMaxFieldCount = reachedMaxFieldCount; + } + + /** + * Returns the generated query string. + * + * @return the query string + */ + public String getQuery() { + return query; + } + + /** + * Returns the type that ultimately was used to generate the query. + * + * @return the used type + */ + public String getUsedType() { + return usedType; + } + + /** + * Returns the total number of fields that were considered during query generation. + * + * @return the total field count + */ + public int getTotalFieldCount() { + return totalFieldCount; + } + + /** + * Indicates whether the maximum field count was reached during query generation. + * + * @return true if the maximum field count was reached, false otherwise + */ + public boolean isReachedMaxFieldCount() { + return reachedMaxFieldCount; + } +} diff --git a/src/main/java/graphql/validation/AbstractRule.java b/src/main/java/graphql/validation/AbstractRule.java index 49e3e1eded..fc5cf07771 100644 --- a/src/main/java/graphql/validation/AbstractRule.java +++ b/src/main/java/graphql/validation/AbstractRule.java @@ -1,10 +1,8 @@ package graphql.validation; -import java.util.ArrayList; -import java.util.List; - import graphql.Internal; +import graphql.i18n.I18nMsg; import graphql.language.Argument; import graphql.language.Directive; import graphql.language.Document; @@ -13,6 +11,7 @@ import graphql.language.FragmentSpread; import graphql.language.InlineFragment; import graphql.language.Node; +import graphql.language.ObjectValue; import graphql.language.OperationDefinition; import graphql.language.SelectionSet; import graphql.language.SourceLocation; @@ -20,20 +19,25 @@ import graphql.language.VariableDefinition; import graphql.language.VariableReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static graphql.validation.ValidationError.newValidationError; +import static java.lang.System.arraycopy; + @Internal public class AbstractRule { private final ValidationContext validationContext; private final ValidationErrorCollector validationErrorCollector; - - + private final ValidationUtil validationUtil; private boolean visitFragmentSpreads; - private ValidationUtil validationUtil = new ValidationUtil(); - public AbstractRule(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { this.validationContext = validationContext; this.validationErrorCollector = validationErrorCollector; + this.validationUtil = new ValidationUtil(); } public boolean isVisitFragmentSpreads() { @@ -44,40 +48,98 @@ public void setVisitFragmentSpreads(boolean visitFragmentSpreads) { this.visitFragmentSpreads = visitFragmentSpreads; } - public ValidationUtil getValidationUtil() { return validationUtil; } - public void setValidationUtil(ValidationUtil validationUtil) { - this.validationUtil = validationUtil; - } - - public void addError(ValidationErrorType validationErrorType, List locations, String description) { + public void addError(ValidationErrorType validationErrorType, Collection> locations, String description) { List locationList = new ArrayList<>(); - for (Node node : locations) { + for (Node node : locations) { locationList.add(node.getSourceLocation()); } - validationErrorCollector.addError(new ValidationError(validationErrorType, locationList, description, getQueryPath())); + addError(newValidationError() + .validationErrorType(validationErrorType) + .sourceLocations(locationList) + .description(description)); } public void addError(ValidationErrorType validationErrorType, SourceLocation location, String description) { - validationErrorCollector.addError(new ValidationError(validationErrorType, location, description, getQueryPath())); + addError(newValidationError() + .validationErrorType(validationErrorType) + .sourceLocation(location) + .description(description)); + } + + public void addError(ValidationError.Builder validationError) { + validationErrorCollector.addError(validationError.queryPath(getQueryPath()).build()); } public List getErrors() { return validationErrorCollector.getErrors(); } - public ValidationContext getValidationContext() { return validationContext; } + public ValidationErrorCollector getValidationErrorCollector() { + return validationErrorCollector; + } + protected List getQueryPath() { return validationContext.getQueryPath(); } + /** + * Verifies if the experimental API key is enabled + * @param key to be checked + * @return if the experimental API key is enabled + */ + protected Boolean isExperimentalApiKeyEnabled(String key) { + return (getValidationContext() != null && + getValidationContext().getGraphQLContext() != null || + getValidationContext().getGraphQLContext().get(key) != null || + ((Boolean) getValidationContext().getGraphQLContext().get(key))); + } + /** + * Creates an I18n message using the {@link graphql.i18n.I18nMsg} + * + * @param validationErrorType the type of validation failure + * @param i18nMsg the i18n message object + * + * @return the formatted I18n message + */ + public String i18n(ValidationErrorType validationErrorType, I18nMsg i18nMsg) { + return i18n(validationErrorType, i18nMsg.getMsgKey(), i18nMsg.getMsgArguments()); + } + + /** + * Creates an I18N message using the key and arguments + * + * @param validationErrorType the type of validation failure + * @param msgKey the key in the underlying message bundle + * @param msgArgs the message arguments + * + * @return the formatted I18N message + */ + public String i18n(ValidationErrorType validationErrorType, String msgKey, Object... msgArgs) { + Object[] params = new Object[msgArgs.length + 1]; + params[0] = mkTypeAndPath(validationErrorType); + arraycopy(msgArgs, 0, params, 1, msgArgs.length); + + return validationContext.i18n(msgKey, params); + } + + private String mkTypeAndPath(ValidationErrorType validationErrorType) { + List queryPath = getQueryPath(); + StringBuilder sb = new StringBuilder(); + sb.append(validationErrorType); + if (queryPath != null) { + sb.append("@[").append(String.join("/", queryPath)).append("]"); + } + return sb.toString(); + } + public void checkDocument(Document document) { } @@ -138,6 +200,10 @@ public void documentFinished(Document document) { } + public void checkObjectValue(ObjectValue objectValue) { + + } + @Override public String toString() { return "Rule{" + validationContext + "}"; diff --git a/src/main/java/graphql/validation/ArgumentValidationUtil.java b/src/main/java/graphql/validation/ArgumentValidationUtil.java index 13232d6932..a378f40b63 100644 --- a/src/main/java/graphql/validation/ArgumentValidationUtil.java +++ b/src/main/java/graphql/validation/ArgumentValidationUtil.java @@ -1,5 +1,8 @@ package graphql.validation; +import graphql.GraphQLError; +import graphql.Internal; +import graphql.i18n.I18nMsg; import graphql.language.Argument; import graphql.language.ObjectField; import graphql.language.Value; @@ -10,14 +13,17 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; +@Internal public class ArgumentValidationUtil extends ValidationUtil { private final List argumentNames = new ArrayList<>(); - private Value argumentValue; - private String errorMessage; + private Value argumentValue; + private String errMsgKey; private final List arguments = new ArrayList<>(); + private Map errorExtensions; private final String argumentName; @@ -27,39 +33,50 @@ public ArgumentValidationUtil(Argument argument) { } @Override - protected void handleNullError(Value value, GraphQLType type) { - errorMessage = "must not be null"; + protected void handleNullError(Value value, GraphQLType type) { + errMsgKey = "ArgumentValidationUtil.handleNullError"; argumentValue = value; } @Override - protected void handleScalarError(Value value, GraphQLScalarType type) { - errorMessage = "is not a valid '%s'"; + protected void handleScalarError(Value value, GraphQLScalarType type, GraphQLError invalid) { + if (invalid.getMessage() == null) { + errMsgKey = "ArgumentValidationUtil.handleScalarError"; + } else { + errMsgKey = "ArgumentValidationUtil.handleScalarErrorCustomMessage"; + } arguments.add(type.getName()); + arguments.add(invalid.getMessage()); argumentValue = value; + errorExtensions = invalid.getExtensions(); } @Override - protected void handleEnumError(Value value, GraphQLEnumType type) { - errorMessage = "is not a valid '%s'"; + protected void handleEnumError(Value value, GraphQLEnumType type, GraphQLError invalid) { + if (invalid.getMessage() == null) { + errMsgKey = "ArgumentValidationUtil.handleEnumError"; + } else { + errMsgKey = "ArgumentValidationUtil.handleEnumErrorCustomMessage"; + } arguments.add(type.getName()); + arguments.add(invalid.getMessage()); argumentValue = value; } @Override - protected void handleNotObjectError(Value value, GraphQLInputObjectType type) { - errorMessage = "must be an object type"; + protected void handleNotObjectError(Value value, GraphQLInputObjectType type) { + errMsgKey = "ArgumentValidationUtil.handleNotObjectError"; } @Override - protected void handleMissingFieldsError(Value value, GraphQLInputObjectType type, Set missingFields) { - errorMessage = "is missing required fields '%s'"; + protected void handleMissingFieldsError(Value value, GraphQLInputObjectType type, Set missingFields) { + errMsgKey = "ArgumentValidationUtil.handleMissingFieldsError"; arguments.add(missingFields); } @Override - protected void handleExtraFieldError(Value value, GraphQLInputObjectType type, ObjectField objectField) { - errorMessage = "contains a field not in '%s': '%s'"; + protected void handleExtraFieldError(Value value, GraphQLInputObjectType type, ObjectField objectField) { + errMsgKey = "ArgumentValidationUtil.handleExtraFieldError"; arguments.add(type.getName()); arguments.add(objectField.getName()); } @@ -70,11 +87,17 @@ protected void handleFieldNotValidError(ObjectField objectField, GraphQLInputObj } @Override - protected void handleFieldNotValidError(Value value, GraphQLType type, int index) { + protected void handleFieldNotValidError(Value value, GraphQLType type, int index) { argumentNames.add(0, String.format("[%s]", index)); } - public String getMessage() { + @Override + protected void handleExtraOneOfFieldsError(GraphQLInputObjectType type, Value value) { + errMsgKey = "ArgumentValidationUtil.extraOneOfFieldsError"; + arguments.add(type.getName()); + } + + public I18nMsg getMsgAndArgs() { StringBuilder argument = new StringBuilder(argumentName); for (String name : argumentNames) { if (name.startsWith("[")) { @@ -86,8 +109,10 @@ public String getMessage() { arguments.add(0, argument.toString()); arguments.add(1, argumentValue); - String message = "argument '%s' with value '%s'" + " " + errorMessage; + return new I18nMsg(errMsgKey, arguments); + } - return String.format(message, arguments.toArray()); + public Map getErrorExtensions() { + return errorExtensions; } } diff --git a/src/main/java/graphql/validation/RulesVisitor.java b/src/main/java/graphql/validation/RulesVisitor.java index 0e9cdf0bac..df3131ce7c 100644 --- a/src/main/java/graphql/validation/RulesVisitor.java +++ b/src/main/java/graphql/validation/RulesVisitor.java @@ -1,13 +1,11 @@ package graphql.validation; - -import java.util.ArrayList; -import java.util.IdentityHashMap; -import java.util.LinkedHashSet; +import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; +import com.google.common.collect.ImmutableList; + import graphql.Internal; import graphql.language.Argument; import graphql.language.Directive; @@ -17,6 +15,7 @@ import graphql.language.FragmentSpread; import graphql.language.InlineFragment; import graphql.language.Node; +import graphql.language.ObjectValue; import graphql.language.OperationDefinition; import graphql.language.SelectionSet; import graphql.language.TypeName; @@ -24,166 +23,141 @@ import graphql.language.VariableReference; @Internal +@SuppressWarnings("rawtypes") public class RulesVisitor implements DocumentVisitor { - - private final List rules = new ArrayList<>(); private final ValidationContext validationContext; - private boolean subVisitor; - private final List rulesVisitingFragmentSpreads = new ArrayList<>(); - private final Map> rulesToSkipByUntilNode = new IdentityHashMap<>(); - private final Set rulesToSkip = new LinkedHashSet<>(); + private final List allRules; + private List currentRules; + private final Set visitedFragmentSpreads = new HashSet<>(); + private final List fragmentSpreadVisitRules; + private final List nonFragmentSpreadRules; + private boolean operationScope = false; + private int fragmentSpreadVisitDepth = 0; public RulesVisitor(ValidationContext validationContext, List rules) { - this(validationContext, rules, false); - } - - public RulesVisitor(ValidationContext validationContext, List rules, boolean subVisitor) { this.validationContext = validationContext; - this.subVisitor = subVisitor; - this.rules.addAll(rules); - this.subVisitor = subVisitor; - findRulesVisitingFragmentSpreads(); + this.allRules = rules; + this.currentRules = allRules; + this.nonFragmentSpreadRules = filterRulesVisitingFragmentSpreads(allRules, false); + this.fragmentSpreadVisitRules = filterRulesVisitingFragmentSpreads(allRules, true); } - private void findRulesVisitingFragmentSpreads() { + private List filterRulesVisitingFragmentSpreads(List rules, boolean isVisitFragmentSpreads) { + ImmutableList.Builder builder = ImmutableList.builder(); for (AbstractRule rule : rules) { - if (rule.isVisitFragmentSpreads()) { - rulesVisitingFragmentSpreads.add(rule); + if (rule.isVisitFragmentSpreads() == isVisitFragmentSpreads) { + builder.add(rule); } } + return builder.build(); } @Override public void enter(Node node, List ancestors) { validationContext.getTraversalContext().enter(node, ancestors); - Set tmpRulesSet = new LinkedHashSet<>(this.rules); - tmpRulesSet.removeAll(rulesToSkip); - List rulesToConsider = new ArrayList<>(tmpRulesSet); + if (node instanceof Document){ - checkDocument((Document) node, rulesToConsider); + checkDocument((Document) node); } else if (node instanceof Argument) { - checkArgument((Argument) node, rulesToConsider); + checkArgument((Argument) node); } else if (node instanceof TypeName) { - checkTypeName((TypeName) node, rulesToConsider); + checkTypeName((TypeName) node); } else if (node instanceof VariableDefinition) { - checkVariableDefinition((VariableDefinition) node, rulesToConsider); + checkVariableDefinition((VariableDefinition) node); } else if (node instanceof Field) { - checkField((Field) node, rulesToConsider); + checkField((Field) node); } else if (node instanceof InlineFragment) { - checkInlineFragment((InlineFragment) node, rulesToConsider); + checkInlineFragment((InlineFragment) node); } else if (node instanceof Directive) { - checkDirective((Directive) node, ancestors, rulesToConsider); + checkDirective((Directive) node, ancestors); } else if (node instanceof FragmentSpread) { - checkFragmentSpread((FragmentSpread) node, rulesToConsider, ancestors); + checkFragmentSpread((FragmentSpread) node, ancestors); } else if (node instanceof FragmentDefinition) { - checkFragmentDefinition((FragmentDefinition) node, rulesToConsider); + checkFragmentDefinition((FragmentDefinition) node); } else if (node instanceof OperationDefinition) { - checkOperationDefinition((OperationDefinition) node, rulesToConsider); + checkOperationDefinition((OperationDefinition) node); } else if (node instanceof VariableReference) { - checkVariable((VariableReference) node, rulesToConsider); + checkVariable((VariableReference) node); } else if (node instanceof SelectionSet) { - checkSelectionSet((SelectionSet) node, rulesToConsider); + checkSelectionSet((SelectionSet) node); + } else if (node instanceof ObjectValue) { + checkObjectValue((ObjectValue) node); } } - private void checkDocument(Document node, List rules) { - for (AbstractRule rule : rules) { - rule.checkDocument(node); - } + private void checkDocument(Document node) { + currentRules.forEach(r -> r.checkDocument(node)); } - - private void checkArgument(Argument node, List rules) { - for (AbstractRule rule : rules) { - rule.checkArgument(node); - } + private void checkArgument(Argument node) { + currentRules.forEach(r -> r.checkArgument(node)); } - private void checkTypeName(TypeName node, List rules) { - for (AbstractRule rule : rules) { - rule.checkTypeName(node); - } + private void checkTypeName(TypeName node) { + currentRules.forEach(r -> r.checkTypeName(node)); } - - private void checkVariableDefinition(VariableDefinition variableDefinition, List rules) { - for (AbstractRule rule : rules) { - rule.checkVariableDefinition(variableDefinition); - } + private void checkVariableDefinition(VariableDefinition node) { + currentRules.forEach(r -> r.checkVariableDefinition(node)); } - private void checkField(Field field, List rules) { - for (AbstractRule rule : rules) { - rule.checkField(field); - } + private void checkField(Field node) { + currentRules.forEach(r -> r.checkField(node)); } - private void checkInlineFragment(InlineFragment inlineFragment, List rules) { - for (AbstractRule rule : rules) { - rule.checkInlineFragment(inlineFragment); - } + private void checkInlineFragment(InlineFragment node) { + currentRules.forEach(r -> r.checkInlineFragment(node)); } - private void checkDirective(Directive directive, List ancestors, List rules) { - for (AbstractRule rule : rules) { - rule.checkDirective(directive, ancestors); - } + private void checkDirective(Directive node, List ancestors) { + currentRules.forEach(r -> r.checkDirective(node, ancestors)); } - private void checkFragmentSpread(FragmentSpread fragmentSpread, List rules, List ancestors) { - for (AbstractRule rule : rules) { - rule.checkFragmentSpread(fragmentSpread); - } - List rulesVisitingFragmentSpreads = getRulesVisitingFragmentSpreads(rules); - if (rulesVisitingFragmentSpreads.size() > 0) { - FragmentDefinition fragment = validationContext.getFragment(fragmentSpread.getName()); - if (fragment != null && !ancestors.contains(fragment)) { - new LanguageTraversal(ancestors).traverse(fragment, new RulesVisitor(validationContext, rulesVisitingFragmentSpreads, true)); - } - } - } + private void checkFragmentSpread(FragmentSpread node, List ancestors) { + currentRules.forEach(r -> r.checkFragmentSpread(node)); - private List getRulesVisitingFragmentSpreads(List rules) { - List result = new ArrayList<>(); - for (AbstractRule rule : rules) { - if (rule.isVisitFragmentSpreads()) result.add(rule); + if (operationScope) { + FragmentDefinition fragment = validationContext.getFragment(node.getName()); + if (fragment != null && !visitedFragmentSpreads.contains(node.getName())) { + // Manually traverse into the FragmentDefinition + visitedFragmentSpreads.add(node.getName()); + List prevRules = currentRules; + currentRules = fragmentSpreadVisitRules; + fragmentSpreadVisitDepth++; + new LanguageTraversal(ancestors).traverse(fragment, this); + fragmentSpreadVisitDepth--; + currentRules = prevRules; + } } - return result; } - - private void checkFragmentDefinition(FragmentDefinition fragmentDefinition, List rules) { - if (!subVisitor) { - rulesToSkipByUntilNode.put(fragmentDefinition, new ArrayList<>(rulesVisitingFragmentSpreads)); - rulesToSkip.addAll(rulesVisitingFragmentSpreads); - } - - - for (AbstractRule rule : rules) { - if (!subVisitor && (rule.isVisitFragmentSpreads())) continue; - rule.checkFragmentDefinition(fragmentDefinition); + private void checkFragmentDefinition(FragmentDefinition node) { + // If we've encountered a FragmentDefinition and we got here without coming through + // an OperationDefinition, then suspend all isVisitFragmentSpread rules for this subtree. + // Expect these rules to be checked when the FragmentSpread is traversed + if (fragmentSpreadVisitDepth == 0) { + currentRules = nonFragmentSpreadRules; } + currentRules.forEach(r -> r.checkFragmentDefinition(node)); } - private void checkOperationDefinition(OperationDefinition operationDefinition, List rules) { - for (AbstractRule rule : rules) { - rule.checkOperationDefinition(operationDefinition); - } + private void checkOperationDefinition(OperationDefinition node) { + operationScope = true; + currentRules.forEach(r -> r.checkOperationDefinition(node)); } - private void checkSelectionSet(SelectionSet selectionSet, List rules) { - for (AbstractRule rule : rules) { - rule.checkSelectionSet(selectionSet); - } + private void checkSelectionSet(SelectionSet node) { + currentRules.forEach(r -> r.checkSelectionSet(node)); } - private void checkVariable(VariableReference variableReference, List rules) { - for (AbstractRule rule : rules) { - rule.checkVariable(variableReference); - } + private void checkVariable(VariableReference node) { + currentRules.forEach(r -> r.checkVariable(node)); } + private void checkObjectValue(ObjectValue node) { + currentRules.forEach(r -> r.checkObjectValue(node)); + } @Override public void leave(Node node, List ancestors) { @@ -195,31 +169,29 @@ public void leave(Node node, List ancestors) { leaveOperationDefinition((OperationDefinition) node); } else if (node instanceof SelectionSet) { leaveSelectionSet((SelectionSet) node); + } else if (node instanceof FragmentDefinition) { + leaveFragmentDefinition((FragmentDefinition) node); } + } - if (rulesToSkipByUntilNode.containsKey(node)) { - rulesToSkip.removeAll(rulesToSkipByUntilNode.get(node)); - rulesToSkipByUntilNode.remove(node); - } - - + private void leaveSelectionSet(SelectionSet node) { + currentRules.forEach(r -> r.leaveSelectionSet(node)); } - private void leaveSelectionSet(SelectionSet selectionSet) { - for (AbstractRule rule : rules) { - rule.leaveSelectionSet(selectionSet); - } + private void leaveOperationDefinition(OperationDefinition node) { + // fragments should be revisited for each operation + visitedFragmentSpreads.clear(); + operationScope = false; + currentRules.forEach(r -> r.leaveOperationDefinition(node)); } - private void leaveOperationDefinition(OperationDefinition operationDefinition) { - for (AbstractRule rule : rules) { - rule.leaveOperationDefinition(operationDefinition); - } + private void documentFinished(Document node) { + currentRules.forEach(r -> r.documentFinished(node)); } - private void documentFinished(Document document) { - for (AbstractRule rule : rules) { - rule.documentFinished(document); + private void leaveFragmentDefinition(FragmentDefinition node) { + if (fragmentSpreadVisitDepth == 0) { + currentRules = allRules; } } } diff --git a/src/main/java/graphql/validation/TraversalContext.java b/src/main/java/graphql/validation/TraversalContext.java index 953d140954..d9d93af7f1 100644 --- a/src/main/java/graphql/validation/TraversalContext.java +++ b/src/main/java/graphql/validation/TraversalContext.java @@ -32,14 +32,11 @@ import graphql.schema.GraphQLType; import graphql.schema.GraphQLUnionType; import graphql.schema.GraphQLUnmodifiedType; -import graphql.schema.SchemaUtil; +import graphql.schema.InputValueWithState; import java.util.ArrayList; import java.util.List; -import static graphql.introspection.Introspection.SchemaMetaFieldDef; -import static graphql.introspection.Introspection.TypeMetaFieldDef; -import static graphql.introspection.Introspection.TypeNameMetaFieldDef; import static graphql.schema.GraphQLTypeUtil.isList; import static graphql.schema.GraphQLTypeUtil.isNonNull; import static graphql.schema.GraphQLTypeUtil.unwrapAll; @@ -47,16 +44,15 @@ @Internal public class TraversalContext implements DocumentVisitor { - final GraphQLSchema schema; - final List outputTypeStack = new ArrayList<>(); - final List parentTypeStack = new ArrayList<>(); - final List inputTypeStack = new ArrayList<>(); - final List fieldDefStack = new ArrayList<>(); - final List nameStack = new ArrayList<>(); - GraphQLDirective directive; - GraphQLArgument argument; - - final SchemaUtil schemaUtil = new SchemaUtil(); + private final GraphQLSchema schema; + private final List outputTypeStack = new ArrayList<>(); + private final List parentTypeStack = new ArrayList<>(); + private final List inputTypeStack = new ArrayList<>(); + private final List defaultValueStack = new ArrayList<>(); + private final List fieldDefStack = new ArrayList<>(); + private final List nameStack = new ArrayList<>(); + private GraphQLDirective directive; + private GraphQLArgument argument; public TraversalContext(GraphQLSchema graphQLSchema) { @@ -129,9 +125,14 @@ private void enterImpl(InlineFragment inlineFragment) { TypeName typeCondition = inlineFragment.getTypeCondition(); GraphQLOutputType type; if (typeCondition != null) { - type = (GraphQLOutputType) schema.getType(typeCondition.getName()); + GraphQLType typeConditionType = schema.getType(typeCondition.getName()); + if (typeConditionType instanceof GraphQLOutputType) { + type = (GraphQLOutputType) typeConditionType; + } else { + type = null; + } } else { - type = (GraphQLOutputType) getParentType(); + type = getParentType(); } addOutputType(type); } @@ -139,7 +140,7 @@ private void enterImpl(InlineFragment inlineFragment) { private void enterImpl(FragmentDefinition fragmentDefinition) { enterName(fragmentDefinition.getName()); GraphQLType type = schema.getType(fragmentDefinition.getTypeCondition().getName()); - addOutputType((GraphQLOutputType) type); + addOutputType(type instanceof GraphQLOutputType ? (GraphQLOutputType) type : null); } private void enterImpl(VariableDefinition variableDefinition) { @@ -156,6 +157,7 @@ private void enterImpl(Argument argument) { } addInputType(argumentType != null ? argumentType.getType() : null); + addDefaultValue(argumentType != null ? argumentType.getArgumentDefaultValue() : null); this.argument = argumentType; } @@ -166,23 +168,30 @@ private void enterImpl(ArrayValue arrayValue) { inputType = (GraphQLInputType) unwrapOne(nullableType); } addInputType(inputType); + // List positions never have a default value. See graphql-js impl for inspiration + addDefaultValue(null); } private void enterImpl(ObjectField objectField) { GraphQLUnmodifiedType objectType = unwrapAll(getInputType()); GraphQLInputType inputType = null; + GraphQLInputObjectField inputField = null; if (objectType instanceof GraphQLInputObjectType) { GraphQLInputObjectType inputObjectType = (GraphQLInputObjectType) objectType; - GraphQLInputObjectField inputField = schema.getFieldVisibility().getFieldDefinition(inputObjectType, objectField.getName()); - if (inputField != null) + inputField = schema.getCodeRegistry().getFieldVisibility().getFieldDefinition(inputObjectType, objectField.getName()); + if (inputField != null) { inputType = inputField.getType(); + } } addInputType(inputType); + addDefaultValue(inputField != null ? inputField.getInputFieldDefaultValue() : null); } private GraphQLArgument find(List arguments, String name) { for (GraphQLArgument argument : arguments) { - if (argument.getName().equals(name)) return argument; + if (argument.getName().equals(name)) { + return argument; + } } return null; } @@ -191,29 +200,32 @@ private GraphQLArgument find(List arguments, String name) { @Override public void leave(Node node, List ancestors) { if (node instanceof OperationDefinition) { - outputTypeStack.remove(outputTypeStack.size() - 1); + pop(outputTypeStack); } else if (node instanceof SelectionSet) { - parentTypeStack.remove(parentTypeStack.size() - 1); + pop(parentTypeStack); } else if (node instanceof Field) { leaveName(((Field) node).getName()); - fieldDefStack.remove(fieldDefStack.size() - 1); - outputTypeStack.remove(outputTypeStack.size() - 1); + pop(fieldDefStack); + pop(outputTypeStack); } else if (node instanceof Directive) { directive = null; } else if (node instanceof InlineFragment) { - outputTypeStack.remove(outputTypeStack.size() - 1); + pop(outputTypeStack); } else if (node instanceof FragmentDefinition) { leaveName(((FragmentDefinition) node).getName()); - outputTypeStack.remove(outputTypeStack.size() - 1); + pop(outputTypeStack); } else if (node instanceof VariableDefinition) { inputTypeStack.remove(inputTypeStack.size() - 1); } else if (node instanceof Argument) { argument = null; - inputTypeStack.remove(inputTypeStack.size() - 1); + pop(inputTypeStack); + pop(defaultValueStack); } else if (node instanceof ArrayValue) { - inputTypeStack.remove(inputTypeStack.size() - 1); + pop(inputTypeStack); + pop(defaultValueStack); } else if (node instanceof ObjectField) { - inputTypeStack.remove(inputTypeStack.size() - 1); + pop(inputTypeStack); + pop(defaultValueStack); } } @@ -249,12 +261,17 @@ private void addOutputType(GraphQLOutputType type) { outputTypeStack.add(type); } - private T lastElement(List list) { - if (list.size() == 0) return null; + if (list.isEmpty()) { + return null; + } return list.get(list.size() - 1); } + private T pop(List list) { + return list.remove(list.size() - 1); + } + /** * @return can be null if the parent is not a CompositeType */ @@ -269,11 +286,18 @@ private void addParentType(GraphQLCompositeType compositeType) { public GraphQLInputType getInputType() { return lastElement(inputTypeStack); } + public InputValueWithState getDefaultValue() { + return lastElement(defaultValueStack); + } private void addInputType(GraphQLInputType graphQLInputType) { inputTypeStack.add(graphQLInputType); } + private void addDefaultValue(InputValueWithState defaultValue) { + defaultValueStack.add(defaultValue); + } + public GraphQLFieldDefinition getFieldDef() { return lastElement(fieldDefStack); } @@ -297,24 +321,23 @@ public GraphQLArgument getArgument() { return argument; } - private GraphQLFieldDefinition getFieldDef(GraphQLSchema schema, GraphQLType parentType, Field field) { if (schema.getQueryType().equals(parentType)) { - if (field.getName().equals(SchemaMetaFieldDef.getName())) { - return SchemaMetaFieldDef; + if (field.getName().equals(schema.getIntrospectionSchemaFieldDefinition().getName())) { + return schema.getIntrospectionSchemaFieldDefinition(); } - if (field.getName().equals(TypeMetaFieldDef.getName())) { - return TypeMetaFieldDef; + if (field.getName().equals(schema.getIntrospectionTypeFieldDefinition().getName())) { + return schema.getIntrospectionTypeFieldDefinition(); } } - if (field.getName().equals(TypeNameMetaFieldDef.getName()) + if (field.getName().equals(schema.getIntrospectionTypenameFieldDefinition().getName()) && (parentType instanceof GraphQLObjectType || parentType instanceof GraphQLInterfaceType || parentType instanceof GraphQLUnionType)) { - return TypeNameMetaFieldDef; + return schema.getIntrospectionTypenameFieldDefinition(); } if (parentType instanceof GraphQLFieldsContainer) { - return schema.getFieldVisibility().getFieldDefinition((GraphQLFieldsContainer) parentType, field.getName()); + return schema.getCodeRegistry().getFieldVisibility().getFieldDefinition((GraphQLFieldsContainer) parentType, field.getName()); } return null; } diff --git a/src/main/java/graphql/validation/ValidationContext.java b/src/main/java/graphql/validation/ValidationContext.java index 6347f0a99b..18fe678177 100644 --- a/src/main/java/graphql/validation/ValidationContext.java +++ b/src/main/java/graphql/validation/ValidationContext.java @@ -1,7 +1,9 @@ package graphql.validation; +import graphql.GraphQLContext; import graphql.Internal; +import graphql.i18n.I18n; import graphql.language.Definition; import graphql.language.Document; import graphql.language.FragmentDefinition; @@ -12,9 +14,11 @@ import graphql.schema.GraphQLInputType; import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLSchema; +import graphql.schema.InputValueWithState; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; @Internal @@ -25,18 +29,23 @@ public class ValidationContext { private final TraversalContext traversalContext; private final Map fragmentDefinitionMap = new LinkedHashMap<>(); + private final I18n i18n; + private final GraphQLContext graphQLContext; - - public ValidationContext(GraphQLSchema schema, Document document) { + public ValidationContext(GraphQLSchema schema, Document document, I18n i18n) { this.schema = schema; this.document = document; this.traversalContext = new TraversalContext(schema); + this.i18n = i18n; + this.graphQLContext = GraphQLContext.newContext().of(Locale.class, i18n.getLocale()).build(); buildFragmentMap(); } private void buildFragmentMap() { - for (Definition definition : document.getDefinitions()) { - if (!(definition instanceof FragmentDefinition)) continue; + for (Definition definition : document.getDefinitions()) { + if (!(definition instanceof FragmentDefinition)) { + continue; + } FragmentDefinition fragmentDefinition = (FragmentDefinition) definition; fragmentDefinitionMap.put(fragmentDefinition.getName(), fragmentDefinition); } @@ -66,6 +75,10 @@ public GraphQLInputType getInputType() { return traversalContext.getInputType(); } + public InputValueWithState getDefaultValue() { + return traversalContext.getDefaultValue(); + } + public GraphQLFieldDefinition getFieldDef() { return traversalContext.getFieldDef(); } @@ -82,11 +95,30 @@ public GraphQLOutputType getOutputType() { return traversalContext.getOutputType(); } - public List getQueryPath() { return traversalContext.getQueryPath(); } + public I18n getI18n() { + return i18n; + } + + public GraphQLContext getGraphQLContext() { + return graphQLContext; + } + + /** + * Creates an I18N message using the key and arguments + * + * @param msgKey the key in the underlying message bundle + * @param msgArgs the message arguments + * + * @return the formatted I18N message + */ + public String i18n(String msgKey, Object... msgArgs) { + return i18n.msg(msgKey, msgArgs); + } + @Override public String toString() { return "ValidationContext{" + getQueryPath() + "}"; diff --git a/src/main/java/graphql/validation/ValidationError.java b/src/main/java/graphql/validation/ValidationError.java index 64f8805bb0..04c1f88936 100644 --- a/src/main/java/graphql/validation/ValidationError.java +++ b/src/main/java/graphql/validation/ValidationError.java @@ -1,71 +1,49 @@ package graphql.validation; +import com.google.common.collect.ImmutableMap; import graphql.ErrorType; import graphql.GraphQLError; import graphql.GraphqlErrorHelper; +import graphql.PublicApi; import graphql.language.SourceLocation; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +@PublicApi public class ValidationError implements GraphQLError { - private final String message; private final List locations = new ArrayList<>(); private final String description; - private final ValidationErrorType validationErrorType; - private final List queryPath; - - public ValidationError(ValidationErrorType validationErrorType) { - this(validationErrorType, (SourceLocation) null, null); - } - - public ValidationError(ValidationErrorType validationErrorType, SourceLocation sourceLocation, String description) { - this(validationErrorType, nullOrList(sourceLocation), description, null); - } - - public ValidationError(ValidationErrorType validationErrorType, SourceLocation sourceLocation, String description, List queryPath) { - this(validationErrorType, nullOrList(sourceLocation), description, queryPath); - } - - public ValidationError(ValidationErrorType validationErrorType, List sourceLocations, String description) { - this(validationErrorType, sourceLocations, description, null); - } - - public ValidationError(ValidationErrorType validationErrorType, List sourceLocations, String description, List queryPath) { - this.validationErrorType = validationErrorType; - if (sourceLocations != null) - this.locations.addAll(sourceLocations); - this.description = description; - this.message = mkMessage(validationErrorType, description, queryPath); - this.queryPath = queryPath; - } - - private static List nullOrList(SourceLocation sourceLocation) { - return sourceLocation == null ? null : Collections.singletonList(sourceLocation); - } - - private String mkMessage(ValidationErrorType validationErrorType, String description, List queryPath) { - return String.format("Validation error of type %s: %s%s", validationErrorType, description, toPath(queryPath)); - } + private final ValidationErrorClassification validationErrorType; + private final List queryPath = new ArrayList<>(); + private final ImmutableMap extensions; + + private ValidationError(Builder builder) { + this.validationErrorType = builder.validationErrorType; + this.description = builder.description; + if (builder.sourceLocations != null) { + this.locations.addAll(builder.sourceLocations); + } - private String toPath(List queryPath) { - if (queryPath == null) { - return ""; + if (builder.queryPath != null) { + this.queryPath.addAll(builder.queryPath); } - return String.format(" @ '%s'", queryPath.stream().collect(Collectors.joining("/"))); + + this.extensions = (builder.extensions != null) ? ImmutableMap.copyOf(builder.extensions) : ImmutableMap.of(); } - public ValidationErrorType getValidationErrorType() { + public ValidationErrorClassification getValidationErrorType() { return validationErrorType; } @Override public String getMessage() { - return message; + return description; } public String getDescription() { @@ -86,15 +64,30 @@ public List getQueryPath() { return queryPath; } + @Override + public Map getExtensions() { + return extensions; + } @Override public String toString() { + String extensionsString = ""; + + if (extensions.size() > 0) { + extensionsString = extensions + .keySet() + .stream() + .map(key -> key + "=" + extensions.get(key)) + .collect(Collectors.joining(", ")); + } + return "ValidationError{" + "validationErrorType=" + validationErrorType + ", queryPath=" + queryPath + - ", message=" + message + + ", message=" + description + ", locations=" + locations + ", description='" + description + '\'' + + ", extensions=[" + extensionsString + ']' + '}'; } @@ -109,4 +102,51 @@ public int hashCode() { return GraphqlErrorHelper.hashCode(this); } + + public static Builder newValidationError() { + return new Builder(); + } + + public static class Builder { + private List sourceLocations; + private Map extensions; + private String description; + private ValidationErrorClassification validationErrorType; + private List queryPath; + + + public Builder validationErrorType(ValidationErrorClassification validationErrorType) { + this.validationErrorType = validationErrorType; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder queryPath(List queryPath) { + this.queryPath = queryPath; + return this; + } + + public Builder sourceLocation(SourceLocation sourceLocation) { + this.sourceLocations = sourceLocation == null ? null : Collections.singletonList(sourceLocation); + return this; + } + + public Builder sourceLocations(List sourceLocations) { + this.sourceLocations = sourceLocations; + return this; + } + + public Builder extensions(Map extensions) { + this.extensions = extensions; + return this; + } + + public ValidationError build() { + return new ValidationError(this); + } + } } diff --git a/src/main/java/graphql/validation/ValidationErrorClassification.java b/src/main/java/graphql/validation/ValidationErrorClassification.java new file mode 100644 index 0000000000..2a9ad78722 --- /dev/null +++ b/src/main/java/graphql/validation/ValidationErrorClassification.java @@ -0,0 +1,8 @@ +package graphql.validation; + + +import graphql.PublicApi; + +@PublicApi +public interface ValidationErrorClassification { +} diff --git a/src/main/java/graphql/validation/ValidationErrorCollector.java b/src/main/java/graphql/validation/ValidationErrorCollector.java index 02b91453c5..cdb21aca05 100644 --- a/src/main/java/graphql/validation/ValidationErrorCollector.java +++ b/src/main/java/graphql/validation/ValidationErrorCollector.java @@ -6,13 +6,46 @@ import java.util.ArrayList; import java.util.List; +import static graphql.validation.ValidationErrorType.MaxValidationErrorsReached; + @Internal public class ValidationErrorCollector { private final List errors = new ArrayList<>(); + private final int maxErrors; + + public ValidationErrorCollector() { + this(Validator.MAX_VALIDATION_ERRORS); + } + + public ValidationErrorCollector(int maxErrors) { + this.maxErrors = maxErrors; + } + + private boolean atMaxErrors() { + return errors.size() >= maxErrors - 1; + } - public void addError(ValidationError validationError) { - this.errors.add(validationError); + /** + * This will throw {@link MaxValidationErrorsReached} if too many validation errors are added + * + * @param validationError the error to add + * + * @throws MaxValidationErrorsReached if too many errors have been generated + */ + public void addError(ValidationError validationError) throws MaxValidationErrorsReached { + if (!atMaxErrors()) { + this.errors.add(validationError); + } else { + this.errors.add(ValidationError.newValidationError() + .validationErrorType(MaxValidationErrorsReached) + .description( + String.format("The maximum number of validation errors has been reached. (%d)", maxErrors) + ) + .build()); + + throw new MaxValidationErrorsReached(); + } } public List getErrors() { @@ -26,7 +59,7 @@ public boolean containsValidationError(ValidationErrorType validationErrorType) public boolean containsValidationError(ValidationErrorType validationErrorType, String description) { for (ValidationError validationError : errors) { if (validationError.getValidationErrorType() == validationErrorType) { - return description == null || validationError.getDescription().equals(description); + return description == null || validationError.getDescription().contains(description); } } return false; @@ -38,4 +71,17 @@ public String toString() { "errors=" + errors + '}'; } + + /** + * Indicates that that maximum number of validation errors has been reached + */ + @Internal + static class MaxValidationErrorsReached extends RuntimeException { + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + } + } diff --git a/src/main/java/graphql/validation/ValidationErrorType.java b/src/main/java/graphql/validation/ValidationErrorType.java index 540107fc86..e701a5d778 100644 --- a/src/main/java/graphql/validation/ValidationErrorType.java +++ b/src/main/java/graphql/validation/ValidationErrorType.java @@ -1,13 +1,17 @@ package graphql.validation; -public enum ValidationErrorType { +import graphql.PublicApi; +@PublicApi +public enum ValidationErrorType implements ValidationErrorClassification { + + MaxValidationErrorsReached, DefaultForNonNullArgument, WrongType, UnknownType, - SubSelectionRequired, - SubSelectionNotAllowed, + SubselectionRequired, + SubselectionNotAllowed, InvalidSyntax, BadValueForDefaultArg, FieldUndefined, @@ -23,12 +27,22 @@ public enum ValidationErrorType { UnknownDirective, MisplacedDirective, UndefinedVariable, + VariableNotAllowed, UnusedVariable, FragmentCycle, FieldsConflict, InvalidFragmentType, LoneAnonymousOperationViolation, NonExecutableDefinition, - DuplicateOperationName - + DuplicateOperationName, + DuplicateFragmentName, + DuplicateDirectiveName, + DuplicateArgumentNames, + DuplicateIncrementalLabel, + DuplicateVariableName, + NullValueForNonNullArgument, + SubscriptionMultipleRootFields, + SubscriptionIntrospectionRootField, + UniqueObjectFieldName, + UnknownOperation } diff --git a/src/main/java/graphql/validation/ValidationUtil.java b/src/main/java/graphql/validation/ValidationUtil.java index 1a3d0a59e8..1bff274d92 100644 --- a/src/main/java/graphql/validation/ValidationUtil.java +++ b/src/main/java/graphql/validation/ValidationUtil.java @@ -1,7 +1,13 @@ package graphql.validation; +import com.google.common.collect.ImmutableSet; import graphql.Assert; +import graphql.Directives; +import graphql.GraphQLContext; +import graphql.GraphQLError; +import graphql.Internal; +import graphql.execution.CoercedVariables; import graphql.language.ArrayValue; import graphql.language.ListType; import graphql.language.NonNullType; @@ -25,18 +31,19 @@ import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; import static graphql.schema.GraphQLTypeUtil.isList; import static graphql.schema.GraphQLTypeUtil.isNonNull; import static graphql.schema.GraphQLTypeUtil.unwrapOne; +@Internal public class ValidationUtil { - public TypeName getUnmodifiedType(Type type) { + public TypeName getUnmodifiedType(Type type) { if (type instanceof ListType) { return getUnmodifiedType(((ListType) type).getType()); } else if (type instanceof NonNullType) { @@ -47,31 +54,34 @@ public TypeName getUnmodifiedType(Type type) { return Assert.assertShouldNeverHappen(); } - protected void handleNullError(Value value, GraphQLType type) { + protected void handleNullError(Value value, GraphQLType type) { } - protected void handleScalarError(Value value, GraphQLScalarType type) { + protected void handleScalarError(Value value, GraphQLScalarType type, GraphQLError invalid) { } - protected void handleEnumError(Value value, GraphQLEnumType type) { + protected void handleEnumError(Value value, GraphQLEnumType type, GraphQLError invalid) { } - protected void handleNotObjectError(Value value, GraphQLInputObjectType type) { + protected void handleNotObjectError(Value value, GraphQLInputObjectType type) { } - protected void handleMissingFieldsError(Value value, GraphQLInputObjectType type, Set missingFields) { + protected void handleMissingFieldsError(Value value, GraphQLInputObjectType type, Set missingFields) { } - protected void handleExtraFieldError(Value value, GraphQLInputObjectType type, ObjectField objectField) { + protected void handleExtraFieldError(Value value, GraphQLInputObjectType type, ObjectField objectField) { } protected void handleFieldNotValidError(ObjectField objectField, GraphQLInputObjectType type) { } - protected void handleFieldNotValidError(Value value, GraphQLType type, int index) { + protected void handleFieldNotValidError(Value value, GraphQLType type, int index) { } - public boolean isValidLiteralValue(Value value, GraphQLType type, GraphQLSchema schema) { + protected void handleExtraOneOfFieldsError(GraphQLInputObjectType type, Value value) { + } + + public boolean isValidLiteralValue(Value value, GraphQLType type, GraphQLSchema schema, GraphQLContext graphQLContext, Locale locale) { if (value == null || value instanceof NullValue) { boolean valid = !(isNonNull(type)); if (!valid) { @@ -83,45 +93,51 @@ public boolean isValidLiteralValue(Value value, GraphQLType type, GraphQLSchema return true; } if (isNonNull(type)) { - return isValidLiteralValue(value, unwrapOne(type), schema); + return isValidLiteralValue(value, unwrapOne(type), schema, graphQLContext, locale); } if (type instanceof GraphQLScalarType) { - boolean valid = parseLiteral(value, ((GraphQLScalarType) type).getCoercing()); - if (!valid) { - handleScalarError(value, (GraphQLScalarType) type); - } - return valid; + Optional invalid = parseLiteral(value, ((GraphQLScalarType) type).getCoercing(), graphQLContext, locale); + invalid.ifPresent(graphQLError -> handleScalarError(value, (GraphQLScalarType) type, graphQLError)); + return invalid.isEmpty(); } if (type instanceof GraphQLEnumType) { - boolean valid = parseLiteral(value, ((GraphQLEnumType) type).getCoercing()); - if (!valid) { - handleEnumError(value, (GraphQLEnumType) type); - } - return valid; + Optional invalid = parseLiteralEnum(value, (GraphQLEnumType) type, graphQLContext, locale); + invalid.ifPresent(graphQLError -> handleEnumError(value, (GraphQLEnumType) type, graphQLError)); + return invalid.isEmpty(); } if (isList(type)) { - return isValidLiteralValue(value, (GraphQLList) type, schema); + return isValidLiteralValue(value, (GraphQLList) type, schema, graphQLContext, locale); } - return type instanceof GraphQLInputObjectType && isValidLiteralValue(value, (GraphQLInputObjectType) type, schema); + return type instanceof GraphQLInputObjectType && isValidLiteralValueForInputObjectType(value, (GraphQLInputObjectType) type, schema, graphQLContext, locale); } - private boolean parseLiteral(Value value, Coercing coercing) { + private Optional parseLiteralEnum(Value value, GraphQLEnumType graphQLEnumType, GraphQLContext graphQLContext, Locale locale) { try { - return coercing.parseLiteral(value) != null; + graphQLEnumType.parseLiteral(value, graphQLContext, locale); + return Optional.empty(); } catch (CoercingParseLiteralException e) { - return false; + return Optional.of(e); } } - private boolean isValidLiteralValue(Value value, GraphQLInputObjectType type, GraphQLSchema schema) { + private Optional parseLiteral(Value value, Coercing coercing, GraphQLContext graphQLContext, Locale locale) { + try { + coercing.parseLiteral(value, CoercedVariables.emptyVariables(), graphQLContext, locale); + return Optional.empty(); + } catch (CoercingParseLiteralException e) { + return Optional.of(e); + } + } + + boolean isValidLiteralValueForInputObjectType(Value value, GraphQLInputObjectType type, GraphQLSchema schema, GraphQLContext graphQLContext, Locale locale) { if (!(value instanceof ObjectValue)) { handleNotObjectError(value, type); return false; } - GraphqlFieldVisibility fieldVisibility = schema.getFieldVisibility(); + GraphqlFieldVisibility fieldVisibility = schema.getCodeRegistry().getFieldVisibility(); ObjectValue objectValue = (ObjectValue) value; Map objectFieldMap = fieldMap(objectValue); @@ -138,21 +154,28 @@ private boolean isValidLiteralValue(Value value, GraphQLInputObjectType type, Gr handleExtraFieldError(value, type, objectField); return false; } - if (!isValidLiteralValue(objectField.getValue(), inputObjectField.getType(), schema)) { + if (!isValidLiteralValue(objectField.getValue(), inputObjectField.getType(), schema, graphQLContext, locale)) { handleFieldNotValidError(objectField, type); return false; } } + if (type.hasAppliedDirective(Directives.OneOfDirective.getName())) { + if (objectFieldMap.keySet().size() != 1) { + handleExtraOneOfFieldsError(type,value); + return false; + } + } return true; } + private Set getMissingFields(GraphQLInputObjectType type, Map objectFieldMap, GraphqlFieldVisibility fieldVisibility) { return fieldVisibility.getFieldDefinitions(type).stream() .filter(field -> isNonNull(field.getType())) + .filter(value -> (value.getInputFieldDefaultValue().isNotSet()) && !objectFieldMap.containsKey(value.getName())) .map(GraphQLInputObjectField::getName) - .filter(((Predicate) objectFieldMap::containsKey).negate()) - .collect(Collectors.toSet()); + .collect(ImmutableSet.toImmutableSet()); } private Map fieldMap(ObjectValue objectValue) { @@ -163,19 +186,19 @@ private Map fieldMap(ObjectValue objectValue) { return result; } - private boolean isValidLiteralValue(Value value, GraphQLList type, GraphQLSchema schema) { + private boolean isValidLiteralValue(Value value, GraphQLList type, GraphQLSchema schema, GraphQLContext graphQLContext, Locale locale) { GraphQLType wrappedType = type.getWrappedType(); if (value instanceof ArrayValue) { List values = ((ArrayValue) value).getValues(); for (int i = 0; i < values.size(); i++) { - if (!isValidLiteralValue(values.get(i), wrappedType, schema)) { + if (!isValidLiteralValue(values.get(i), wrappedType, schema, graphQLContext, locale)) { handleFieldNotValidError(values.get(i), wrappedType, i); return false; } } return true; } else { - return isValidLiteralValue(value, wrappedType, schema); + return isValidLiteralValue(value, wrappedType, schema, graphQLContext, locale); } } diff --git a/src/main/java/graphql/validation/Validator.java b/src/main/java/graphql/validation/Validator.java index 528584bf8d..52709109d6 100644 --- a/src/main/java/graphql/validation/Validator.java +++ b/src/main/java/graphql/validation/Validator.java @@ -2,9 +2,15 @@ import graphql.Internal; +import graphql.i18n.I18n; import graphql.language.Document; import graphql.schema.GraphQLSchema; import graphql.validation.rules.ArgumentsOfCorrectType; +import graphql.validation.rules.DeferDirectiveLabel; +import graphql.validation.rules.DeferDirectiveOnRootLevel; +import graphql.validation.rules.DeferDirectiveOnValidOperation; +import graphql.validation.rules.KnownOperationTypes; +import graphql.validation.rules.UniqueObjectFieldName; import graphql.validation.rules.ExecutableDefinitions; import graphql.validation.rules.FieldsOnCorrectType; import graphql.validation.rules.FragmentsOnCompositeType; @@ -20,31 +26,68 @@ import graphql.validation.rules.OverlappingFieldsCanBeMerged; import graphql.validation.rules.PossibleFragmentSpreads; import graphql.validation.rules.ProvidedNonNullArguments; -import graphql.validation.rules.ScalarLeafs; +import graphql.validation.rules.ScalarLeaves; +import graphql.validation.rules.SubscriptionUniqueRootField; +import graphql.validation.rules.UniqueArgumentNames; +import graphql.validation.rules.UniqueDirectiveNamesPerLocation; +import graphql.validation.rules.UniqueFragmentNames; import graphql.validation.rules.UniqueOperationNames; +import graphql.validation.rules.UniqueVariableNames; import graphql.validation.rules.VariableDefaultValuesOfCorrectType; -import graphql.validation.rules.VariableTypesMatchRule; +import graphql.validation.rules.VariableTypesMatch; import graphql.validation.rules.VariablesAreInputTypes; import java.util.ArrayList; import java.util.List; +import java.util.Locale; +import java.util.function.Predicate; +import java.util.stream.Collectors; @Internal public class Validator { - public List validateDocument(GraphQLSchema schema, Document document) { - ValidationContext validationContext = new ValidationContext(schema, document); + static int MAX_VALIDATION_ERRORS = 100; + + /** + * `graphql-java` will stop validation after a maximum number of validation messages has been reached. Attackers + * can send pathologically invalid queries to induce a Denial of Service attack and fill memory with 10000s of errors + * and burn CPU in process. + *

    + * By default, this is set to 100 errors. You can set a new JVM wide value as the maximum allowed validation errors. + * + * @param maxValidationErrors the maximum validation errors allow JVM wide + */ + public static void setMaxValidationErrors(int maxValidationErrors) { + MAX_VALIDATION_ERRORS = maxValidationErrors; + } + + public static int getMaxValidationErrors() { + return MAX_VALIDATION_ERRORS; + } + + public List validateDocument(GraphQLSchema schema, Document document, Locale locale) { + return validateDocument(schema, document, ruleClass -> true, locale); + } + public List validateDocument(GraphQLSchema schema, Document document, Predicate> applyRule, Locale locale) { + I18n i18n = I18n.i18n(I18n.BundleType.Validation, locale); + ValidationContext validationContext = new ValidationContext(schema, document, i18n); - ValidationErrorCollector validationErrorCollector = new ValidationErrorCollector(); + ValidationErrorCollector validationErrorCollector = new ValidationErrorCollector(MAX_VALIDATION_ERRORS); List rules = createRules(validationContext, validationErrorCollector); + // filter out any rules they don't want applied + rules = rules.stream().filter(r -> applyRule.test(r.getClass())).collect(Collectors.toList()); LanguageTraversal languageTraversal = new LanguageTraversal(); - languageTraversal.traverse(document, new RulesVisitor(validationContext, rules)); + try { + languageTraversal.traverse(document, new RulesVisitor(validationContext, rules)); + } catch (ValidationErrorCollector.MaxValidationErrorsReached ignored) { + // if we have generated enough errors, then we can shortcut out + } return validationErrorCollector.getErrors(); } - private List createRules(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + public List createRules(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { List rules = new ArrayList<>(); ExecutableDefinitions executableDefinitions = new ExecutableDefinitions(validationContext, validationErrorCollector); @@ -84,15 +127,15 @@ private List createRules(ValidationContext validationContext, Vali ProvidedNonNullArguments providedNonNullArguments = new ProvidedNonNullArguments(validationContext, validationErrorCollector); rules.add(providedNonNullArguments); - ScalarLeafs scalarLeafs = new ScalarLeafs(validationContext, validationErrorCollector); - rules.add(scalarLeafs); + ScalarLeaves scalarLeaves = new ScalarLeaves(validationContext, validationErrorCollector); + rules.add(scalarLeaves); VariableDefaultValuesOfCorrectType variableDefaultValuesOfCorrectType = new VariableDefaultValuesOfCorrectType(validationContext, validationErrorCollector); rules.add(variableDefaultValuesOfCorrectType); VariablesAreInputTypes variablesAreInputTypes = new VariablesAreInputTypes(validationContext, validationErrorCollector); rules.add(variablesAreInputTypes); - VariableTypesMatchRule variableTypesMatchRule = new VariableTypesMatchRule(validationContext, validationErrorCollector); - rules.add(variableTypesMatchRule); + VariableTypesMatch variableTypesMatch = new VariableTypesMatch(validationContext, validationErrorCollector); + rules.add(variableTypesMatch); LoneAnonymousOperation loneAnonymousOperation = new LoneAnonymousOperation(validationContext, validationErrorCollector); rules.add(loneAnonymousOperation); @@ -100,6 +143,36 @@ private List createRules(ValidationContext validationContext, Vali UniqueOperationNames uniqueOperationNames = new UniqueOperationNames(validationContext, validationErrorCollector); rules.add(uniqueOperationNames); + UniqueFragmentNames uniqueFragmentNames = new UniqueFragmentNames(validationContext, validationErrorCollector); + rules.add(uniqueFragmentNames); + + UniqueDirectiveNamesPerLocation uniqueDirectiveNamesPerLocation = new UniqueDirectiveNamesPerLocation(validationContext, validationErrorCollector); + rules.add(uniqueDirectiveNamesPerLocation); + + UniqueArgumentNames uniqueArgumentNamesRule = new UniqueArgumentNames(validationContext, validationErrorCollector); + rules.add(uniqueArgumentNamesRule); + + UniqueVariableNames uniqueVariableNamesRule = new UniqueVariableNames(validationContext, validationErrorCollector); + rules.add(uniqueVariableNamesRule); + + SubscriptionUniqueRootField uniqueSubscriptionRootField = new SubscriptionUniqueRootField(validationContext, validationErrorCollector); + rules.add(uniqueSubscriptionRootField); + + UniqueObjectFieldName uniqueObjectFieldName = new UniqueObjectFieldName(validationContext, validationErrorCollector); + rules.add(uniqueObjectFieldName); + + DeferDirectiveOnRootLevel deferDirectiveOnRootLevel = new DeferDirectiveOnRootLevel(validationContext, validationErrorCollector); + rules.add(deferDirectiveOnRootLevel); + + DeferDirectiveOnValidOperation deferDirectiveOnValidOperation = new DeferDirectiveOnValidOperation(validationContext, validationErrorCollector); + rules.add(deferDirectiveOnValidOperation); + + DeferDirectiveLabel deferDirectiveLabel = new DeferDirectiveLabel(validationContext, validationErrorCollector); + rules.add(deferDirectiveLabel); + + KnownOperationTypes knownOperationTypes = new KnownOperationTypes(validationContext, validationErrorCollector); + rules.add(knownOperationTypes); + return rules; } } diff --git a/src/main/java/graphql/validation/rules/ArgumentsOfCorrectType.java b/src/main/java/graphql/validation/rules/ArgumentsOfCorrectType.java index bafff5ec78..ab54c59d3a 100644 --- a/src/main/java/graphql/validation/rules/ArgumentsOfCorrectType.java +++ b/src/main/java/graphql/validation/rules/ArgumentsOfCorrectType.java @@ -1,14 +1,18 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Argument; import graphql.schema.GraphQLArgument; import graphql.validation.AbstractRule; import graphql.validation.ArgumentValidationUtil; import graphql.validation.ValidationContext; +import graphql.validation.ValidationError; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.WrongType; + +@Internal public class ArgumentsOfCorrectType extends AbstractRule { public ArgumentsOfCorrectType(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { @@ -18,10 +22,17 @@ public ArgumentsOfCorrectType(ValidationContext validationContext, ValidationErr @Override public void checkArgument(Argument argument) { GraphQLArgument fieldArgument = getValidationContext().getArgument(); - if (fieldArgument == null) return; + if (fieldArgument == null) { + return; + } ArgumentValidationUtil validationUtil = new ArgumentValidationUtil(argument); - if (!validationUtil.isValidLiteralValue(argument.getValue(), fieldArgument.getType(), getValidationContext().getSchema())) { - addError(ValidationErrorType.WrongType, argument.getSourceLocation(), validationUtil.getMessage()); + if (!validationUtil.isValidLiteralValue(argument.getValue(), fieldArgument.getType(), getValidationContext().getSchema(), getValidationContext().getGraphQLContext(), getValidationContext().getI18n().getLocale())) { + String message = i18n(WrongType, validationUtil.getMsgAndArgs()); + addError(ValidationError.newValidationError() + .validationErrorType(WrongType) + .sourceLocation(argument.getSourceLocation()) + .description(message) + .extensions(validationUtil.getErrorExtensions())); } } } diff --git a/src/main/java/graphql/validation/rules/DeferDirectiveLabel.java b/src/main/java/graphql/validation/rules/DeferDirectiveLabel.java new file mode 100644 index 0000000000..fdf85fda82 --- /dev/null +++ b/src/main/java/graphql/validation/rules/DeferDirectiveLabel.java @@ -0,0 +1,66 @@ +package graphql.validation.rules; + +import graphql.Directives; +import graphql.ExperimentalApi; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.Node; +import graphql.language.NullValue; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static graphql.validation.ValidationErrorType.DuplicateIncrementalLabel; +import static graphql.validation.ValidationErrorType.WrongType; + +/** + * Defer and stream directive labels are unique + * + * A GraphQL document is only valid if defer and stream directives' label argument is static and unique. + * + * See proposed spec:spec/Section 5 -- Validation.md ### ### Defer And Stream Directive Labels Are Unique + */ +@ExperimentalApi +public class DeferDirectiveLabel extends AbstractRule { + private Set checkedLabels = new LinkedHashSet<>(); + public DeferDirectiveLabel(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkDirective(Directive directive, List ancestors) { + // ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT must be true + if (!isExperimentalApiKeyEnabled(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT) || + !Directives.DeferDirective.getName().equals(directive.getName()) || + directive.getArguments().size() == 0) { + return; + } + + Argument labelArgument = directive.getArgument("label"); + if (labelArgument == null || labelArgument.getValue() instanceof NullValue){ + return; + } + Value labelArgumentValue = labelArgument.getValue(); + + if (!(labelArgumentValue instanceof StringValue)) { + String message = i18n(WrongType, "DeferDirective.labelMustBeStaticString"); + addError(WrongType, directive.getSourceLocation(), message); + } else { + if (checkedLabels.contains(((StringValue) labelArgumentValue).getValue())) { + String message = i18n(DuplicateIncrementalLabel, "IncrementalDirective.uniqueArgument", labelArgument.getName(), directive.getName()); + addError(DuplicateIncrementalLabel, directive.getSourceLocation(), message); + } else { + checkedLabels.add(((StringValue) labelArgumentValue).getValue()); + } + } + } + + + +} \ No newline at end of file diff --git a/src/main/java/graphql/validation/rules/DeferDirectiveOnRootLevel.java b/src/main/java/graphql/validation/rules/DeferDirectiveOnRootLevel.java new file mode 100644 index 0000000000..39586a265b --- /dev/null +++ b/src/main/java/graphql/validation/rules/DeferDirectiveOnRootLevel.java @@ -0,0 +1,58 @@ +package graphql.validation.rules; + +import graphql.Directives; +import graphql.ExperimentalApi; +import graphql.language.Directive; +import graphql.language.Node; +import graphql.language.OperationDefinition; +import graphql.schema.GraphQLCompositeType; +import graphql.schema.GraphQLObjectType; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static graphql.validation.ValidationErrorType.MisplacedDirective; + +/** + * Defer and stream directives are used on valid root field + * + * A GraphQL document is only valid if defer directives are not used on root mutation or subscription types. + * + * See proposed spec:spec/Section 5 -- Validation.md ### Defer And Stream Directives Are Used On Valid Root Field + */ +@ExperimentalApi +public class DeferDirectiveOnRootLevel extends AbstractRule { + private Set invalidOperations = new LinkedHashSet(Arrays.asList(OperationDefinition.Operation.MUTATION, OperationDefinition.Operation.SUBSCRIPTION)); + public DeferDirectiveOnRootLevel(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + this.setVisitFragmentSpreads(true); + } + + @Override + public void checkDirective(Directive directive, List ancestors) { + // ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT must be true + if (!isExperimentalApiKeyEnabled(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT)) { + return; + } + + if (!Directives.DeferDirective.getName().equals(directive.getName())) { + return; + } + GraphQLObjectType mutationType = getValidationContext().getSchema().getMutationType(); + GraphQLObjectType subscriptionType = getValidationContext().getSchema().getSubscriptionType(); + GraphQLCompositeType parentType = getValidationContext().getParentType(); + if (mutationType != null && parentType != null && parentType.getName().equals(mutationType.getName())){ + String message = i18n(MisplacedDirective, "DeferDirective.notAllowedOperationRootLevelMutation", parentType.getName()); + addError(MisplacedDirective, directive.getSourceLocation(), message); + } else if (subscriptionType != null && parentType != null && parentType.getName().equals(subscriptionType.getName())) { + String message = i18n(MisplacedDirective, "DeferDirective.notAllowedOperationRootLevelSubscription", parentType.getName()); + addError(MisplacedDirective, directive.getSourceLocation(), message); + } + } + +} diff --git a/src/main/java/graphql/validation/rules/DeferDirectiveOnValidOperation.java b/src/main/java/graphql/validation/rules/DeferDirectiveOnValidOperation.java new file mode 100644 index 0000000000..6baa9df948 --- /dev/null +++ b/src/main/java/graphql/validation/rules/DeferDirectiveOnValidOperation.java @@ -0,0 +1,84 @@ +package graphql.validation.rules; + +import graphql.Directives; +import graphql.ExperimentalApi; +import graphql.language.Argument; +import graphql.language.BooleanValue; +import graphql.language.Directive; +import graphql.language.Node; +import graphql.language.OperationDefinition; +import graphql.language.VariableReference; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.List; +import java.util.Optional; + +import static graphql.language.OperationDefinition.Operation.SUBSCRIPTION; +import static graphql.validation.ValidationErrorType.MisplacedDirective; + +/** + * Defer Directive is Used On Valid Operations + * + * A GraphQL document is only valid if defer directives are not used on subscription types. + * + * See proposed spec:spec/Section 5 -- Validation.md ### Defer And Stream Directives Are Used On Valid Operations + * + */ +@ExperimentalApi +public class DeferDirectiveOnValidOperation extends AbstractRule { + public DeferDirectiveOnValidOperation(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + this.setVisitFragmentSpreads(true); + } + + + @Override + public void checkDirective(Directive directive, List ancestors) { + // ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT must be true + if (!isExperimentalApiKeyEnabled(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT)) { + return; + } + + if (!Directives.DeferDirective.getName().equals(directive.getName())) { + return; + } + // check if the directive is on allowed operation + Optional operationDefinition = getOperationDefinition(ancestors); + if (operationDefinition.isPresent() && + SUBSCRIPTION.equals(operationDefinition.get().getOperation()) && + !ifArgumentMightBeFalse(directive) ){ + String message = i18n(MisplacedDirective, "IncrementalDirective.notAllowedSubscriptionOperation", directive.getName()); + addError(MisplacedDirective, directive.getSourceLocation(), message); + } + } + + /** + * Extract from ancestors the OperationDefinition using the document ancestor. + * @param ancestors list of ancestors + * @return Optional of OperationDefinition + */ + private Optional getOperationDefinition(List ancestors) { + return ancestors.stream() + .filter(doc -> doc instanceof OperationDefinition) + .map((def -> (OperationDefinition) def)) + .findFirst(); + } + + private Boolean ifArgumentMightBeFalse(Directive directive) { + Argument ifArgument = directive.getArgumentsByName().get("if"); + if (ifArgument == null) { + return false; + } + if(ifArgument.getValue() instanceof BooleanValue){ + return !((BooleanValue) ifArgument.getValue()).isValue(); + } + if(ifArgument.getValue() instanceof VariableReference){ + return true; + } + return false; + } + +} + diff --git a/src/main/java/graphql/validation/rules/ExecutableDefinitions.java b/src/main/java/graphql/validation/rules/ExecutableDefinitions.java index 3379fe27b3..9a81f9c4aa 100644 --- a/src/main/java/graphql/validation/rules/ExecutableDefinitions.java +++ b/src/main/java/graphql/validation/rules/ExecutableDefinitions.java @@ -1,6 +1,8 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Definition; +import graphql.language.DirectiveDefinition; import graphql.language.Document; import graphql.language.FragmentDefinition; import graphql.language.OperationDefinition; @@ -9,8 +11,10 @@ import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.NonExecutableDefinition; + +@Internal public class ExecutableDefinitions extends AbstractRule { public ExecutableDefinitions(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { @@ -30,26 +34,20 @@ public void checkDocument(Document document) { && !(definition instanceof FragmentDefinition)) { String message = nonExecutableDefinitionMessage(definition); - addError(ValidationErrorType.NonExecutableDefinition, definition.getSourceLocation(), message); + addError(NonExecutableDefinition, definition.getSourceLocation(), message); } }); } private String nonExecutableDefinitionMessage(Definition definition) { - - String definitionName; if (definition instanceof TypeDefinition) { - definitionName = ((TypeDefinition) definition).getName(); + return i18n(NonExecutableDefinition, "ExecutableDefinitions.notExecutableType", ((TypeDefinition) definition).getName()); } else if (definition instanceof SchemaDefinition) { - definitionName = "schema"; - } else { - definitionName = "provided"; + return i18n(NonExecutableDefinition, "ExecutableDefinitions.notExecutableSchema"); + } else if (definition instanceof DirectiveDefinition) { + return i18n(NonExecutableDefinition, "ExecutableDefinitions.notExecutableDirective", ((DirectiveDefinition) definition).getName()); } - return nonExecutableDefinitionMessage(definitionName); - } - - static String nonExecutableDefinitionMessage(String definitionName) { - return String.format("The %s definition is not executable.", definitionName); + return i18n(NonExecutableDefinition, "ExecutableDefinitions.notExecutableDefinition"); } } diff --git a/src/main/java/graphql/validation/rules/FieldsOnCorrectType.java b/src/main/java/graphql/validation/rules/FieldsOnCorrectType.java index a0dc46487a..df9a403e26 100644 --- a/src/main/java/graphql/validation/rules/FieldsOnCorrectType.java +++ b/src/main/java/graphql/validation/rules/FieldsOnCorrectType.java @@ -1,14 +1,17 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Field; import graphql.schema.GraphQLCompositeType; import graphql.schema.GraphQLFieldDefinition; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.FieldUndefined; + +@Internal public class FieldsOnCorrectType extends AbstractRule { @@ -24,8 +27,8 @@ public void checkField(Field field) { if (parentType == null) return; GraphQLFieldDefinition fieldDef = getValidationContext().getFieldDef(); if (fieldDef == null) { - String message = String.format("Field '%s' in type '%s' is undefined", field.getName(), parentType.getName()); - addError(ValidationErrorType.FieldUndefined, field.getSourceLocation(), message); + String message = i18n(FieldUndefined, "FieldsOnCorrectType.unknownField", field.getName(), parentType.getName()); + addError(FieldUndefined, field.getSourceLocation(), message); } } diff --git a/src/main/java/graphql/validation/rules/FragmentsOnCompositeType.java b/src/main/java/graphql/validation/rules/FragmentsOnCompositeType.java index 2114c5c669..fd7cd3c21f 100644 --- a/src/main/java/graphql/validation/rules/FragmentsOnCompositeType.java +++ b/src/main/java/graphql/validation/rules/FragmentsOnCompositeType.java @@ -1,6 +1,7 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.FragmentDefinition; import graphql.language.InlineFragment; import graphql.schema.GraphQLCompositeType; @@ -8,8 +9,11 @@ import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.FragmentTypeConditionInvalid; +import static graphql.validation.ValidationErrorType.InlineFragmentTypeConditionInvalid; + +@Internal public class FragmentsOnCompositeType extends AbstractRule { @@ -25,8 +29,8 @@ public void checkInlineFragment(InlineFragment inlineFragment) { GraphQLType type = getValidationContext().getSchema().getType(inlineFragment.getTypeCondition().getName()); if (type == null) return; if (!(type instanceof GraphQLCompositeType)) { - String message = "Inline fragment type condition is invalid, must be on Object/Interface/Union"; - addError(ValidationErrorType.InlineFragmentTypeConditionInvalid, inlineFragment.getSourceLocation(), message); + String message = i18n(InlineFragmentTypeConditionInvalid, "FragmentsOnCompositeType.invalidInlineTypeCondition"); + addError(InlineFragmentTypeConditionInvalid, inlineFragment.getSourceLocation(), message); } } @@ -35,8 +39,8 @@ public void checkFragmentDefinition(FragmentDefinition fragmentDefinition) { GraphQLType type = getValidationContext().getSchema().getType(fragmentDefinition.getTypeCondition().getName()); if (type == null) return; if (!(type instanceof GraphQLCompositeType)) { - String message = "Fragment type condition is invalid, must be on Object/Interface/Union"; - addError(ValidationErrorType.InlineFragmentTypeConditionInvalid, fragmentDefinition.getSourceLocation(), message); + String message = i18n(FragmentTypeConditionInvalid, "FragmentsOnCompositeType.invalidFragmentTypeCondition"); + addError(FragmentTypeConditionInvalid, fragmentDefinition.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/KnownArgumentNames.java b/src/main/java/graphql/validation/rules/KnownArgumentNames.java index 012f63676f..8f123f7412 100644 --- a/src/main/java/graphql/validation/rules/KnownArgumentNames.java +++ b/src/main/java/graphql/validation/rules/KnownArgumentNames.java @@ -1,5 +1,6 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Argument; import graphql.schema.GraphQLArgument; import graphql.schema.GraphQLDirective; @@ -7,9 +8,12 @@ import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.UnknownArgument; +import static graphql.validation.ValidationErrorType.UnknownDirective; + +@Internal public class KnownArgumentNames extends AbstractRule { public KnownArgumentNames(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { @@ -23,8 +27,8 @@ public void checkArgument(Argument argument) { if (directiveDef != null) { GraphQLArgument directiveArgument = directiveDef.getArgument(argument.getName()); if (directiveArgument == null) { - String message = String.format("Unknown directive argument %s", argument.getName()); - addError(ValidationErrorType.UnknownDirective, argument.getSourceLocation(), message); + String message = i18n(UnknownDirective, "KnownArgumentNames.unknownDirectiveArg", argument.getName()); + addError(UnknownDirective, argument.getSourceLocation(), message); } return; @@ -34,8 +38,8 @@ public void checkArgument(Argument argument) { if (fieldDef == null) return; GraphQLArgument fieldArgument = fieldDef.getArgument(argument.getName()); if (fieldArgument == null) { - String message = String.format("Unknown field argument %s", argument.getName()); - addError(ValidationErrorType.UnknownArgument, argument.getSourceLocation(), message); + String message = i18n(UnknownArgument, "KnownArgumentNames.unknownFieldArg", argument.getName()); + addError(UnknownArgument, argument.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/KnownDirectives.java b/src/main/java/graphql/validation/rules/KnownDirectives.java index 3f35d1ba9d..eb011fb682 100644 --- a/src/main/java/graphql/validation/rules/KnownDirectives.java +++ b/src/main/java/graphql/validation/rules/KnownDirectives.java @@ -1,6 +1,7 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.introspection.Introspection.DirectiveLocation; import graphql.language.Directive; import graphql.language.Field; @@ -10,14 +11,19 @@ import graphql.language.Node; import graphql.language.OperationDefinition; import graphql.language.OperationDefinition.Operation; +import graphql.language.VariableDefinition; import graphql.schema.GraphQLDirective; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import java.util.List; +import java.util.EnumSet; +import static graphql.validation.ValidationErrorType.MisplacedDirective; +import static graphql.validation.ValidationErrorType.UnknownDirective; + +@Internal public class KnownDirectives extends AbstractRule { @@ -29,33 +35,40 @@ public KnownDirectives(ValidationContext validationContext, ValidationErrorColle public void checkDirective(Directive directive, List ancestors) { GraphQLDirective graphQLDirective = getValidationContext().getSchema().getDirective(directive.getName()); if (graphQLDirective == null) { - String message = String.format("Unknown directive %s", directive.getName()); - addError(ValidationErrorType.UnknownDirective, directive.getSourceLocation(), message); + String message = i18n(UnknownDirective, "KnownDirectives.unknownDirective", directive.getName()); + addError(UnknownDirective, directive.getSourceLocation(), message); return; } Node ancestor = ancestors.get(ancestors.size() - 1); if (hasInvalidLocation(graphQLDirective, ancestor)) { - String message = String.format("Directive %s not allowed here", directive.getName()); - addError(ValidationErrorType.MisplacedDirective, directive.getSourceLocation(), message); + String message = i18n(MisplacedDirective, "KnownDirectives.directiveNotAllowed", directive.getName()); + addError(MisplacedDirective, directive.getSourceLocation(), message); } } - @SuppressWarnings("deprecation") // the suppression stands because its deprecated but still in graphql spec + @SuppressWarnings("deprecation") // the suppression stands because it's deprecated but still in graphql spec private boolean hasInvalidLocation(GraphQLDirective directive, Node ancestor) { + EnumSet validLocations = directive.validLocations(); if (ancestor instanceof OperationDefinition) { Operation operation = ((OperationDefinition) ancestor).getOperation(); - return Operation.QUERY.equals(operation) ? - !(directive.validLocations().contains(DirectiveLocation.QUERY) || directive.isOnOperation()) : - !(directive.validLocations().contains(DirectiveLocation.MUTATION) || directive.isOnOperation()); + if (Operation.QUERY.equals(operation)) { + return !validLocations.contains(DirectiveLocation.QUERY); + } else if (Operation.MUTATION.equals(operation)) { + return !validLocations.contains(DirectiveLocation.MUTATION); + } else if (Operation.SUBSCRIPTION.equals(operation)) { + return !validLocations.contains(DirectiveLocation.SUBSCRIPTION); + } } else if (ancestor instanceof Field) { - return !(directive.validLocations().contains(DirectiveLocation.FIELD) || directive.isOnField()); + return !(validLocations.contains(DirectiveLocation.FIELD)); } else if (ancestor instanceof FragmentSpread) { - return !(directive.validLocations().contains(DirectiveLocation.FRAGMENT_SPREAD) || directive.isOnFragment()); + return !(validLocations.contains(DirectiveLocation.FRAGMENT_SPREAD)); } else if (ancestor instanceof FragmentDefinition) { - return !(directive.validLocations().contains(DirectiveLocation.FRAGMENT_DEFINITION) || directive.isOnFragment()); + return !(validLocations.contains(DirectiveLocation.FRAGMENT_DEFINITION)); } else if (ancestor instanceof InlineFragment) { - return !(directive.validLocations().contains(DirectiveLocation.INLINE_FRAGMENT) || directive.isOnFragment()); + return !(validLocations.contains(DirectiveLocation.INLINE_FRAGMENT)); + } else if (ancestor instanceof VariableDefinition) { + return !(validLocations.contains(DirectiveLocation.VARIABLE_DEFINITION)); } return true; } diff --git a/src/main/java/graphql/validation/rules/KnownFragmentNames.java b/src/main/java/graphql/validation/rules/KnownFragmentNames.java index dd97a29e4b..0ec66508a0 100644 --- a/src/main/java/graphql/validation/rules/KnownFragmentNames.java +++ b/src/main/java/graphql/validation/rules/KnownFragmentNames.java @@ -1,13 +1,16 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.UndefinedFragment; + +@Internal public class KnownFragmentNames extends AbstractRule { public KnownFragmentNames(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { @@ -18,8 +21,8 @@ public KnownFragmentNames(ValidationContext validationContext, ValidationErrorCo public void checkFragmentSpread(FragmentSpread fragmentSpread) { FragmentDefinition fragmentDefinition = getValidationContext().getFragment(fragmentSpread.getName()); if (fragmentDefinition == null) { - String message = String.format("Undefined fragment %s", fragmentSpread.getName()); - addError(ValidationErrorType.UndefinedFragment, fragmentSpread.getSourceLocation(), message); + String message = i18n(UndefinedFragment, "KnownFragmentNames.undefinedFragment", fragmentSpread.getName()); + addError(UndefinedFragment, fragmentSpread.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/KnownOperationTypes.java b/src/main/java/graphql/validation/rules/KnownOperationTypes.java new file mode 100644 index 0000000000..2ef9af48fe --- /dev/null +++ b/src/main/java/graphql/validation/rules/KnownOperationTypes.java @@ -0,0 +1,48 @@ +package graphql.validation.rules; + +import graphql.Internal; +import graphql.language.OperationDefinition; +import graphql.schema.GraphQLSchema; +import graphql.util.StringKit; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import static graphql.validation.ValidationErrorType.UnknownOperation; + +/** + * Unique variable names + *

    + * A GraphQL operation is only valid if all its variables are uniquely named. + */ +@Internal +public class KnownOperationTypes extends AbstractRule { + + public KnownOperationTypes(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkOperationDefinition(OperationDefinition operationDefinition) { + OperationDefinition.Operation documentOperation = operationDefinition.getOperation(); + GraphQLSchema graphQLSchema = getValidationContext().getSchema(); + if (documentOperation == OperationDefinition.Operation.MUTATION + && graphQLSchema.getMutationType() == null) { + String message = i18n(UnknownOperation, "KnownOperationTypes.noOperation", formatOperation(documentOperation)); + addError(UnknownOperation, operationDefinition.getSourceLocation(), message); + } else if (documentOperation == OperationDefinition.Operation.SUBSCRIPTION + && graphQLSchema.getSubscriptionType() == null) { + String message = i18n(UnknownOperation, "KnownOperationTypes.noOperation", formatOperation(documentOperation)); + addError(UnknownOperation, operationDefinition.getSourceLocation(), message); + } else if (documentOperation == OperationDefinition.Operation.QUERY + && graphQLSchema.getQueryType() == null) { + // This is unlikely to happen, as a validated GraphQLSchema must have a Query type by definition + String message = i18n(UnknownOperation, "KnownOperationTypes.noOperation", formatOperation(documentOperation)); + addError(UnknownOperation, operationDefinition.getSourceLocation(), message); + } + } + + private String formatOperation(OperationDefinition.Operation operation) { + return StringKit.capitalize(operation.name().toLowerCase()); + } +} diff --git a/src/main/java/graphql/validation/rules/KnownTypeNames.java b/src/main/java/graphql/validation/rules/KnownTypeNames.java index 967cc3a991..d28db91925 100644 --- a/src/main/java/graphql/validation/rules/KnownTypeNames.java +++ b/src/main/java/graphql/validation/rules/KnownTypeNames.java @@ -1,12 +1,15 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.TypeName; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.UnknownType; + +@Internal public class KnownTypeNames extends AbstractRule { @@ -17,8 +20,8 @@ public KnownTypeNames(ValidationContext validationContext, ValidationErrorCollec @Override public void checkTypeName(TypeName typeName) { if ((getValidationContext().getSchema().getType(typeName.getName())) == null) { - String message = String.format("Unknown type %s", typeName.getName()); - addError(ValidationErrorType.UnknownType, typeName.getSourceLocation(), message); + String message = i18n(UnknownType, "KnownTypeNames.unknownType", typeName.getName()); + addError(UnknownType, typeName.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/LoneAnonymousOperation.java b/src/main/java/graphql/validation/rules/LoneAnonymousOperation.java index 13b7e469b5..e89bec68e9 100644 --- a/src/main/java/graphql/validation/rules/LoneAnonymousOperation.java +++ b/src/main/java/graphql/validation/rules/LoneAnonymousOperation.java @@ -1,5 +1,6 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Document; import graphql.language.OperationDefinition; import graphql.validation.AbstractRule; @@ -7,6 +8,9 @@ import graphql.validation.ValidationErrorCollector; import graphql.validation.ValidationErrorType; +import static graphql.validation.ValidationErrorType.LoneAnonymousOperationViolation; + +@Internal public class LoneAnonymousOperation extends AbstractRule { boolean hasAnonymousOp = false; @@ -20,22 +24,20 @@ public LoneAnonymousOperation(ValidationContext validationContext, ValidationErr public void checkOperationDefinition(OperationDefinition operationDefinition) { super.checkOperationDefinition(operationDefinition); String name = operationDefinition.getName(); - String message = null; if (name == null) { hasAnonymousOp = true; if (count > 0) { - message = "Anonymous operation with other operations."; + String message = i18n(LoneAnonymousOperationViolation, "LoneAnonymousOperation.withOthers"); + addError(ValidationErrorType.LoneAnonymousOperationViolation, operationDefinition.getSourceLocation(), message); } } else { if (hasAnonymousOp) { - message = "Operation " + name + " is following anonymous operation."; + String message = i18n(LoneAnonymousOperationViolation, "LoneAnonymousOperation.namedOperation", name); + addError(ValidationErrorType.LoneAnonymousOperationViolation, operationDefinition.getSourceLocation(), message); } } count++; - if (message != null) { - addError(ValidationErrorType.LoneAnonymousOperationViolation, operationDefinition.getSourceLocation(), message); - } } @Override diff --git a/src/main/java/graphql/validation/rules/NoFragmentCycles.java b/src/main/java/graphql/validation/rules/NoFragmentCycles.java index 9b092b1baf..32c0f751b5 100644 --- a/src/main/java/graphql/validation/rules/NoFragmentCycles.java +++ b/src/main/java/graphql/validation/rules/NoFragmentCycles.java @@ -1,6 +1,15 @@ package graphql.validation.rules; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import graphql.Internal; import graphql.language.Definition; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; @@ -12,15 +21,12 @@ import graphql.validation.ValidationErrorCollector; import graphql.validation.ValidationErrorType; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import static graphql.validation.ValidationErrorType.FragmentCycle; +@Internal public class NoFragmentCycles extends AbstractRule { - private final Map> fragmentSpreads = new LinkedHashMap<>(); - + private final Map> fragmentSpreads = new HashMap<>(); public NoFragmentCycles(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { super(validationContext, validationErrorCollector); @@ -37,14 +43,13 @@ private void prepareFragmentMap() { } } - - private List gatherSpreads(FragmentDefinition fragmentDefinition) { - final List fragmentSpreads = new ArrayList<>(); + private Set gatherSpreads(FragmentDefinition fragmentDefinition) { + final Set fragmentSpreads = new HashSet<>(); DocumentVisitor visitor = new DocumentVisitor() { @Override public void enter(Node node, List path) { if (node instanceof FragmentSpread) { - fragmentSpreads.add((FragmentSpread) node); + fragmentSpreads.add(((FragmentSpread) node).getName()); } } @@ -58,36 +63,56 @@ public void leave(Node node, List path) { return fragmentSpreads; } - @Override public void checkFragmentDefinition(FragmentDefinition fragmentDefinition) { - List spreadPath = new ArrayList<>(); - detectCycleRecursive(fragmentDefinition.getName(), fragmentDefinition.getName(), spreadPath); + LinkedList path = new LinkedList<>(); + path.add(0, fragmentDefinition.getName()); + Map> transitiveSpreads = buildTransitiveSpreads(path, new HashMap<>()); + + for (Map.Entry> entry : transitiveSpreads.entrySet()) { + if (entry.getValue().contains(entry.getKey())) { + String message = i18n(FragmentCycle, "NoFragmentCycles.cyclesNotAllowed"); + addError(ValidationErrorType.FragmentCycle, Collections.singletonList(fragmentDefinition), message); + } + } } - private void detectCycleRecursive(String fragmentName, String initialName, List spreadPath) { - List fragmentSpreads = this.fragmentSpreads.get(fragmentName); - if (fragmentSpreads == null) { - // KnownFragmentNames will have picked this up. Lets not NPE - return; + private Map> buildTransitiveSpreads(LinkedList path, Map> transitiveSpreads) { + String name = path.peekFirst(); + + if (transitiveSpreads.containsKey(name)) { + return transitiveSpreads; } - outer: - for (FragmentSpread fragmentSpread : fragmentSpreads) { + Set spreads = fragmentSpreads.get(name); - if (fragmentSpread.getName().equals(initialName)) { - String message = "Fragment cycles not allowed"; - addError(ValidationErrorType.FragmentCycle, spreadPath, message); - continue; + // spreads may be null when there is no corresponding FragmentDefinition for this spread. + // This will be handled by KnownFragmentNames + if (spreads == null || spreads.isEmpty()) { + return transitiveSpreads; + } + + // Add the current spreads to the transitive spreads of each ancestor in the traversal path + for (String ancestor : path) { + Set ancestorSpreads = transitiveSpreads.get(ancestor); + if (ancestorSpreads == null) { + ancestorSpreads = new HashSet<>(); } - for (FragmentSpread spread : spreadPath) { - if (spread.equals(fragmentSpread)) { - continue outer; - } + ancestorSpreads.addAll(spreads); + transitiveSpreads.put(ancestor, ancestorSpreads); + } + + for (String child : spreads) { + // don't recurse infinitely, expect the recursion check to happen in checkFragmentDefinition + if (path.contains(child) || transitiveSpreads.containsKey(child)) { + continue; } - spreadPath.add(fragmentSpread); - detectCycleRecursive(fragmentSpread.getName(), initialName, spreadPath); - spreadPath.remove(spreadPath.size() - 1); + + // descend into each spread in the current fragment + LinkedList childPath = new LinkedList<>(path); + childPath.add(0, child); + buildTransitiveSpreads(childPath, transitiveSpreads); } + return transitiveSpreads; } } diff --git a/src/main/java/graphql/validation/rules/NoUndefinedVariables.java b/src/main/java/graphql/validation/rules/NoUndefinedVariables.java index 6de3c69118..f0592bb7df 100644 --- a/src/main/java/graphql/validation/rules/NoUndefinedVariables.java +++ b/src/main/java/graphql/validation/rules/NoUndefinedVariables.java @@ -1,6 +1,7 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.FragmentDefinition; import graphql.language.OperationDefinition; import graphql.language.VariableDefinition; @@ -8,11 +9,13 @@ import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import java.util.LinkedHashSet; import java.util.Set; +import static graphql.validation.ValidationErrorType.UndefinedVariable; + +@Internal public class NoUndefinedVariables extends AbstractRule { private final Set variableNames = new LinkedHashSet<>(); @@ -35,8 +38,8 @@ public void checkFragmentDefinition(FragmentDefinition fragmentDefinition) { @Override public void checkVariable(VariableReference variableReference) { if (!variableNames.contains(variableReference.getName())) { - String message = String.format("Undefined variable %s", variableReference.getName()); - addError(ValidationErrorType.UndefinedVariable, variableReference.getSourceLocation(), message); + String message = i18n(UndefinedVariable, "NoUndefinedVariables.undefinedVariable", variableReference.getName()); + addError(UndefinedVariable, variableReference.getSourceLocation(), message); } } diff --git a/src/main/java/graphql/validation/rules/NoUnusedFragments.java b/src/main/java/graphql/validation/rules/NoUnusedFragments.java index 633f8442b0..c0a61a50a6 100644 --- a/src/main/java/graphql/validation/rules/NoUnusedFragments.java +++ b/src/main/java/graphql/validation/rules/NoUnusedFragments.java @@ -1,6 +1,7 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Document; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; @@ -8,13 +9,15 @@ import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static graphql.validation.ValidationErrorType.UnusedFragment; + +@Internal public class NoUnusedFragments extends AbstractRule { @@ -59,8 +62,8 @@ public void documentFinished(Document document) { for (FragmentDefinition fragmentDefinition : allDeclaredFragments) { if (!allUsedFragments.contains(fragmentDefinition.getName())) { - String message = String.format("Unused fragment %s", fragmentDefinition.getName()); - addError(ValidationErrorType.UnusedFragment, fragmentDefinition.getSourceLocation(), message); + String message = i18n(UnusedFragment, "NoUnusedFragments.unusedFragments", fragmentDefinition.getName()); + addError(UnusedFragment, fragmentDefinition.getSourceLocation(), message); } } diff --git a/src/main/java/graphql/validation/rules/NoUnusedVariables.java b/src/main/java/graphql/validation/rules/NoUnusedVariables.java index 374cb17bc9..80e3aa9429 100644 --- a/src/main/java/graphql/validation/rules/NoUnusedVariables.java +++ b/src/main/java/graphql/validation/rules/NoUnusedVariables.java @@ -1,20 +1,22 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.OperationDefinition; import graphql.language.VariableDefinition; import graphql.language.VariableReference; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; -import graphql.validation.ValidationError; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import static graphql.validation.ValidationErrorType.UnusedVariable; + +@Internal public class NoUnusedVariables extends AbstractRule { private final List variableDefinitions = new ArrayList<>(); @@ -29,8 +31,8 @@ public NoUnusedVariables(ValidationContext validationContext, ValidationErrorCol public void leaveOperationDefinition(OperationDefinition operationDefinition) { for (VariableDefinition variableDefinition : variableDefinitions) { if (!usedVariables.contains(variableDefinition.getName())) { - String message = String.format("Unused variable %s", variableDefinition.getName()); - addError(ValidationErrorType.UnusedVariable, variableDefinition.getSourceLocation(), message); + String message = i18n(UnusedVariable, "NoUnusedVariables.unusedVariable", variableDefinition.getName()); + addError(UnusedVariable, variableDefinition.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/OverlappingFieldsCanBeMerged.java b/src/main/java/graphql/validation/rules/OverlappingFieldsCanBeMerged.java index 50c77ec95e..aa877d8cfd 100644 --- a/src/main/java/graphql/validation/rules/OverlappingFieldsCanBeMerged.java +++ b/src/main/java/graphql/validation/rules/OverlappingFieldsCanBeMerged.java @@ -1,6 +1,8 @@ package graphql.validation.rules; +import com.google.common.collect.ImmutableList; +import graphql.Internal; import graphql.execution.TypeFromAST; import graphql.language.Argument; import graphql.language.AstComparator; @@ -8,251 +10,254 @@ import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; import graphql.language.InlineFragment; +import graphql.language.OperationDefinition; import graphql.language.Selection; import graphql.language.SelectionSet; -import graphql.language.Value; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; import graphql.schema.GraphQLType; +import graphql.schema.GraphQLUnionType; +import graphql.schema.GraphQLUnmodifiedType; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import static graphql.collect.ImmutableKit.addToList; +import static graphql.collect.ImmutableKit.emptyList; import static graphql.schema.GraphQLTypeUtil.isEnum; import static graphql.schema.GraphQLTypeUtil.isList; import static graphql.schema.GraphQLTypeUtil.isNonNull; import static graphql.schema.GraphQLTypeUtil.isNotWrapped; import static graphql.schema.GraphQLTypeUtil.isNullable; import static graphql.schema.GraphQLTypeUtil.isScalar; +import static graphql.schema.GraphQLTypeUtil.simplePrint; import static graphql.schema.GraphQLTypeUtil.unwrapAll; import static graphql.schema.GraphQLTypeUtil.unwrapOne; +import static graphql.util.FpKit.filterSet; +import static graphql.util.FpKit.groupingBy; import static graphql.validation.ValidationErrorType.FieldsConflict; -import static java.lang.String.format; -/** - * See http://facebook.github.io/graphql/June2018/#sec-Field-Selection-Merging - */ +@Internal public class OverlappingFieldsCanBeMerged extends AbstractRule { - private final List alreadyChecked = new ArrayList<>(); + private final Set> sameResponseShapeChecked = new LinkedHashSet<>(); + private final Set> sameForCommonParentsChecked = new LinkedHashSet<>(); + private final Set> conflictsReported = new LinkedHashSet<>(); public OverlappingFieldsCanBeMerged(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { super(validationContext, validationErrorCollector); } @Override - public void leaveSelectionSet(SelectionSet selectionSet) { - Map> fieldMap = new LinkedHashMap<>(); + public void checkOperationDefinition(OperationDefinition operationDefinition) { + super.checkOperationDefinition(operationDefinition); + impl(operationDefinition.getSelectionSet(), getValidationContext().getOutputType()); + } + + public void impl(SelectionSet selectionSet, GraphQLOutputType graphQLOutputType) { + Map> fieldMap = new LinkedHashMap<>(); Set visitedFragmentSpreads = new LinkedHashSet<>(); - collectFields(fieldMap, selectionSet, getValidationContext().getOutputType(), visitedFragmentSpreads); + collectFields(fieldMap, selectionSet, graphQLOutputType, visitedFragmentSpreads); List conflicts = findConflicts(fieldMap); for (Conflict conflict : conflicts) { + if (conflictsReported.contains(conflict.fields)) { + continue; + } + conflictsReported.add(conflict.fields); + // each error contains a reference to the current querypath via validationContext.getQueryPath() + // queryPath is null for the first selection set addError(FieldsConflict, conflict.fields, conflict.reason); } } - private List findConflicts(Map> fieldMap) { - List result = new ArrayList<>(); - for (String name : fieldMap.keySet()) { - List fieldAndTypes = fieldMap.get(name); - for (int i = 0; i < fieldAndTypes.size(); i++) { - for (int j = i + 1; j < fieldAndTypes.size(); j++) { - Conflict conflict = findConflict(name, fieldAndTypes.get(i), fieldAndTypes.get(j)); - if (conflict != null) { - result.add(conflict); - } - } - } - } - return result; - } + private void collectFields(Map> fieldMap, SelectionSet selectionSet, GraphQLType parentType, Set visitedFragmentSpreads) { - private boolean isAlreadyChecked(Field field1, Field field2) { - for (FieldPair fieldPair : alreadyChecked) { - if (fieldPair.field1 == field1 && fieldPair.field2 == field2) { - return true; - } - if (fieldPair.field1 == field2 && fieldPair.field2 == field1) { - return true; + for (Selection selection : selectionSet.getSelections()) { + if (selection instanceof Field) { + collectFieldsForField(fieldMap, parentType, (Field) selection); + + } else if (selection instanceof InlineFragment) { + collectFieldsForInlineFragment(fieldMap, visitedFragmentSpreads, parentType, (InlineFragment) selection); + + } else if (selection instanceof FragmentSpread) { + collectFieldsForFragmentSpread(fieldMap, visitedFragmentSpreads, (FragmentSpread) selection); } } - return false; } - @SuppressWarnings("ConstantConditions") - private Conflict findConflict(String responseName, FieldAndType fieldAndTypeA, FieldAndType fieldAndTypeB) { - - Field fieldA = fieldAndTypeA.field; - Field fieldB = fieldAndTypeB.field; - - if (isAlreadyChecked(fieldA, fieldB)) { - return null; + private void collectFieldsForFragmentSpread(Map> fieldMap, Set visitedFragmentSpreads, FragmentSpread fragmentSpread) { + FragmentDefinition fragment = getValidationContext().getFragment(fragmentSpread.getName()); + if (fragment == null) { + return; } - alreadyChecked.add(new FieldPair(fieldA, fieldB)); - - String fieldNameA = fieldA.getName(); - String fieldNameB = fieldB.getName(); - - GraphQLType typeA = fieldAndTypeA.graphQLType; - GraphQLType typeB = fieldAndTypeB.graphQLType; - - Conflict conflict = checkListAndNonNullConflict(responseName,fieldAndTypeA,fieldAndTypeB); - if (conflict != null) { - return conflict; + if (visitedFragmentSpreads.contains(fragment.getName())) { + return; } + visitedFragmentSpreads.add(fragment.getName()); + GraphQLType graphQLType = getGraphQLTypeForFragmentDefinition(fragment); + collectFields(fieldMap, fragment.getSelectionSet(), graphQLType, visitedFragmentSpreads); + } - typeA = unwrapAll(typeA); - typeB = unwrapAll(typeB); + private GraphQLType getGraphQLTypeForFragmentDefinition(FragmentDefinition fragment) { + return TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), + fragment.getTypeCondition()); + } - if (checkScalarAndEnumConflict(typeA, typeB)) { - return mkNotSameTypeError(responseName, fieldA, fieldB, typeA, typeB); - } + private void collectFieldsForInlineFragment(Map> fieldMap, Set visitedFragmentSpreads, GraphQLType parentType, InlineFragment inlineFragment) { + GraphQLType graphQLType = getGraphQLTypeForInlineFragment(parentType, inlineFragment); + collectFields(fieldMap, inlineFragment.getSelectionSet(), graphQLType, visitedFragmentSpreads); + } - // If the statically known parent types could not possibly apply at the same - // time, then it is safe to permit them to diverge as they will not present - // any ambiguity by differing. - // It is known that two parent types could never overlap if they are - // different Object types. Interface or Union types might overlap - if not - // in the current state of the schema, then perhaps in some future version, - // thus may not safely diverge. - if (!sameType(fieldAndTypeA.parentType, fieldAndTypeB.parentType) && - fieldAndTypeA.parentType instanceof GraphQLObjectType && - fieldAndTypeB.parentType instanceof GraphQLObjectType) { - return null; + private GraphQLType getGraphQLTypeForInlineFragment(GraphQLType parentType, InlineFragment inlineFragment) { + if (inlineFragment.getTypeCondition() == null) { + return parentType; } + return TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), inlineFragment.getTypeCondition()); + } - if (!fieldNameA.equals(fieldNameB)) { - String reason = format("%s: %s and %s are different fields", responseName, fieldNameA, fieldNameB); - return new Conflict(responseName, reason, fieldA, fieldB); + private void collectFieldsForField(Map> fieldMap, GraphQLType parentType, Field field) { + String responseName = field.getResultKey(); + if (!fieldMap.containsKey(responseName)) { + fieldMap.put(responseName, new LinkedHashSet<>()); } - - if (!sameType(typeA, typeB)) { - return mkNotSameTypeError(responseName, fieldA, fieldB, typeA, typeB); + GraphQLOutputType fieldType = null; + GraphQLUnmodifiedType unwrappedParent = unwrapAll(parentType); + if (unwrappedParent instanceof GraphQLFieldsContainer) { + GraphQLFieldsContainer fieldsContainer = (GraphQLFieldsContainer) unwrappedParent; + GraphQLFieldDefinition fieldDefinition = getVisibleFieldDefinition(fieldsContainer, field); + fieldType = fieldDefinition != null ? fieldDefinition.getType() : null; } + fieldMap.get(responseName).add(new FieldAndType(field, fieldType, unwrappedParent)); + } - - if (!sameArguments(fieldA.getArguments(), fieldB.getArguments())) { - String reason = format("%s: they have differing arguments", responseName); - return new Conflict(responseName, reason, fieldA, fieldB); - } - SelectionSet selectionSet1 = fieldA.getSelectionSet(); - SelectionSet selectionSet2 = fieldB.getSelectionSet(); - if (selectionSet1 != null && selectionSet2 != null) { - Set visitedFragmentSpreads = new LinkedHashSet<>(); - Map> subFieldMap = new LinkedHashMap<>(); - collectFields(subFieldMap, selectionSet1, typeA, visitedFragmentSpreads); - collectFields(subFieldMap, selectionSet2, typeB, visitedFragmentSpreads); - List subConflicts = findConflicts(subFieldMap); - if (subConflicts.size() > 0) { - String reason = format("%s: %s", responseName, joinReasons(subConflicts)); - List fields = new ArrayList<>(); - fields.add(fieldA); - fields.add(fieldB); - fields.addAll(collectFields(subConflicts)); - return new Conflict(responseName, reason, fields); - } - } - return null; + private GraphQLFieldDefinition getVisibleFieldDefinition(GraphQLFieldsContainer fieldsContainer, Field field) { + return getValidationContext().getSchema().getCodeRegistry().getFieldVisibility().getFieldDefinition(fieldsContainer, field.getName()); } - private Conflict checkListAndNonNullConflict(String responseName, FieldAndType fieldAndTypeA, FieldAndType fieldAndTypeB) { - GraphQLType typeA = fieldAndTypeA.graphQLType; - GraphQLType typeB = fieldAndTypeB.graphQLType; + private List findConflicts(Map> fieldMap) { + /* + * The algorithm implemented here is not the one from the Spec, but is based on + * https://tech.xing.com/graphql-overlapping-fields-can-be-merged-fast-ea6e92e0a01 + * . It is not the final version (Listing 11), but Listing 10 adopted to this code base. + */ + List result = new ArrayList<>(); + sameResponseShapeByName(fieldMap, emptyList(), result); + sameForCommonParentsByName(fieldMap, emptyList(), result); + return result; + } - while (true) { - if (isNonNull(typeA) || isNonNull(typeB)) { - if (isNullable(typeA) || isNullable(typeB)) { - String reason = format("%s: fields have different nullability shapes", responseName); - return new Conflict(responseName, reason, fieldAndTypeA.field, fieldAndTypeB.field); - } - } - if (isList(typeA) || isList(typeB)) { - if (!isList(typeA) || !isList(typeB)) { - String reason = format("%s: fields have different list shapes", responseName); - return new Conflict(responseName, reason, fieldAndTypeA.field, fieldAndTypeB.field); - } + private void sameResponseShapeByName(Map> fieldMap, ImmutableList currentPath, List conflictsResult) { + for (Map.Entry> entry : fieldMap.entrySet()) { + if (sameResponseShapeChecked.contains(entry.getValue())) { + continue; } - if (isNotWrapped(typeA) && isNotWrapped(typeB)) { - break; + ImmutableList newPath = addToList(currentPath, entry.getKey()); + sameResponseShapeChecked.add(entry.getValue()); + Conflict conflict = requireSameOutputTypeShape(newPath, entry.getValue()); + if (conflict != null) { + conflictsResult.add(conflict); + continue; } - typeA = unwrapOne(typeA); - typeB = unwrapOne(typeB); + Map> subSelections = mergeSubSelections(entry.getValue()); + sameResponseShapeByName(subSelections, newPath, conflictsResult); } - return null; } - private boolean checkScalarAndEnumConflict(GraphQLType typeA, GraphQLType typeB) { - if (isScalar(typeA) || isScalar(typeB)) { - if (!sameType(typeA, typeB)) { - return true; + private Map> mergeSubSelections(Set sameNameFields) { + Map> fieldMap = new LinkedHashMap<>(); + for (FieldAndType fieldAndType : sameNameFields) { + if (fieldAndType.field.getSelectionSet() != null) { + Set visitedFragmentSpreads = new LinkedHashSet<>(); + collectFields(fieldMap, fieldAndType.field.getSelectionSet(), fieldAndType.graphQLType, visitedFragmentSpreads); } } - if (isEnum(typeA) || isEnum(typeB)) { - if (!sameType(typeA, typeB)) { - return true; - } - } - return false; + return fieldMap; } - private Conflict mkNotSameTypeError(String responseName, Field fieldA, Field fieldB, GraphQLType typeA, GraphQLType typeB) { - String name1 = typeA != null ? typeA.getName() : "null"; - String name2 = typeB != null ? typeB.getName() : "null"; - String reason = format("%s: they return differing types %s and %s", responseName, name1, name2); - return new Conflict(responseName, reason, fieldA, fieldB); + private void sameForCommonParentsByName(Map> fieldMap, ImmutableList currentPath, List conflictsResult) { + for (Map.Entry> entry : fieldMap.entrySet()) { + List> groups = groupByCommonParents(entry.getValue()); + ImmutableList newPath = addToList(currentPath, entry.getKey()); + for (Set group : groups) { + if (sameForCommonParentsChecked.contains(group)) { + continue; + } + sameForCommonParentsChecked.add(group); + Conflict conflict = requireSameNameAndArguments(newPath, group); + if (conflict != null) { + conflictsResult.add(conflict); + continue; + } + Map> subSelections = mergeSubSelections(group); + sameForCommonParentsByName(subSelections, newPath, conflictsResult); + } + } } - private List collectFields(List conflicts) { - List result = new ArrayList<>(); - for (Conflict conflict : conflicts) { - result.addAll(conflict.fields); + private List> groupByCommonParents(Set fields) { + Set abstractTypes = filterSet(fields, fieldAndType -> isInterfaceOrUnion(fieldAndType.parentType)); + Set concreteTypes = filterSet(fields, fieldAndType -> fieldAndType.parentType instanceof GraphQLObjectType); + if (concreteTypes.isEmpty()) { + return Collections.singletonList(abstractTypes); + } + Map> groupsByConcreteParent = groupingBy(concreteTypes, fieldAndType -> fieldAndType.parentType); + List> result = new ArrayList<>(); + for (ImmutableList concreteGroup : groupsByConcreteParent.values()) { + Set oneResultGroup = new LinkedHashSet<>(concreteGroup); + oneResultGroup.addAll(abstractTypes); + result.add(oneResultGroup); } return result; } - private String joinReasons(List conflicts) { - StringBuilder result = new StringBuilder(); - result.append("("); - for (Conflict conflict : conflicts) { - result.append(conflict.reason); - result.append(", "); - } - result.delete(result.length() - 2, result.length()); - result.append(")"); - return result.toString(); + private boolean isInterfaceOrUnion(GraphQLType type) { + return type instanceof GraphQLInterfaceType || type instanceof GraphQLUnionType; } - @SuppressWarnings("SimplifiableIfStatement") - private boolean sameType(GraphQLType type1, GraphQLType type2) { - if (type1 == null || type2 == null) { - return true; + private Conflict requireSameNameAndArguments(ImmutableList path, Set fieldAndTypes) { + if (fieldAndTypes.size() <= 1) { + return null; } - return type1.equals(type2); - } + String name = null; + List arguments = null; + List fields = new ArrayList<>(); + for (FieldAndType fieldAndType : fieldAndTypes) { + Field field = fieldAndType.field; + fields.add(field); + if (name == null) { + name = field.getName(); + arguments = field.getArguments(); + continue; + } + if (!field.getName().equals(name)) { + String reason = i18n(FieldsConflict, "OverlappingFieldsCanBeMerged.differentFields", pathToString(path), name, field.getName()); + return new Conflict(reason, fields); + } + if (!sameArguments(field.getArguments(), arguments)) { + String reason = i18n(FieldsConflict, "OverlappingFieldsCanBeMerged.differentArgs", pathToString(path)); + return new Conflict(reason, fields); + } - @SuppressWarnings("SimplifiableIfStatement") - private boolean sameValue(Value value1, Value value2) { - if (value1 == null && value2 == null) { - return true; } - if (value1 == null) { - return false; - } - if (value2 == null) { - return false; - } - return new AstComparator().isEqual(value1, value2); + return null; + } + + private String pathToString(ImmutableList path) { + return String.join("/", path); } private boolean sameArguments(List arguments1, List arguments2) { @@ -264,7 +269,7 @@ private boolean sameArguments(List arguments1, List argument if (matchedArgument == null) { return false; } - if (!sameValue(argument.getValue(), matchedArgument.getValue())) { + if (!AstComparator.sameValue(argument.getValue(), matchedArgument.getValue())) { return false; } } @@ -280,100 +285,120 @@ private Argument findArgumentByName(String name, List arguments) { return null; } - private void collectFields(Map> fieldMap, SelectionSet selectionSet, GraphQLType parentType, Set visitedFragmentSpreads) { - - for (Selection selection : selectionSet.getSelections()) { - if (selection instanceof Field) { - collectFieldsForField(fieldMap, parentType, (Field) selection); - } else if (selection instanceof InlineFragment) { - collectFieldsForInlineFragment(fieldMap, visitedFragmentSpreads, parentType, (InlineFragment) selection); - - } else if (selection instanceof FragmentSpread) { - collectFieldsForFragmentSpread(fieldMap, visitedFragmentSpreads, (FragmentSpread) selection); + private Conflict requireSameOutputTypeShape(ImmutableList path, Set fieldAndTypes) { + if (fieldAndTypes.size() <= 1) { + return null; + } + List fields = new ArrayList<>(); + GraphQLType typeAOriginal = null; + for (FieldAndType fieldAndType : fieldAndTypes) { + fields.add(fieldAndType.field); + if (typeAOriginal == null) { + typeAOriginal = fieldAndType.graphQLType; + continue; + } + GraphQLType typeA = typeAOriginal; + GraphQLType typeB = fieldAndType.graphQLType; + while (true) { + if (isNonNull(typeA) || isNonNull(typeB)) { + if (isNullable(typeA) || isNullable(typeB)) { + String reason = i18n(FieldsConflict, "OverlappingFieldsCanBeMerged.differentNullability", pathToString(path)); + return new Conflict(reason, fields); + } + } + if (isList(typeA) || isList(typeB)) { + if (!isList(typeA) || !isList(typeB)) { + String reason = i18n(FieldsConflict, "OverlappingFieldsCanBeMerged.differentLists", pathToString(path)); + return new Conflict(reason, fields); + } + } + if (isNotWrapped(typeA) && isNotWrapped(typeB)) { + break; + } + typeA = unwrapOne(typeA); + typeB = unwrapOne(typeB); + } + if (isScalar(typeA) || isScalar(typeB)) { + if (!sameType(typeA, typeB)) { + return mkNotSameTypeError(path, fields, typeA, typeB); + } + } + if (isEnum(typeA) || isEnum(typeB)) { + if (!sameType(typeA, typeB)) { + return mkNotSameTypeError(path, fields, typeA, typeB); + } } } + return null; } - private void collectFieldsForFragmentSpread(Map> fieldMap, Set visitedFragmentSpreads, FragmentSpread fragmentSpread) { - FragmentDefinition fragment = getValidationContext().getFragment(fragmentSpread.getName()); - if (fragment == null) { - return; - } - if (visitedFragmentSpreads.contains(fragment.getName())) { - return; - } - visitedFragmentSpreads.add(fragment.getName()); - GraphQLOutputType graphQLType = (GraphQLOutputType) TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), - fragment.getTypeCondition()); - collectFields(fieldMap, fragment.getSelectionSet(), graphQLType, visitedFragmentSpreads); + private Conflict mkNotSameTypeError(ImmutableList path, List fields, GraphQLType typeA, GraphQLType typeB) { + String name1 = typeA != null ? simplePrint(typeA) : "null"; + String name2 = typeB != null ? simplePrint(typeB) : "null"; + String reason = i18n(FieldsConflict, "OverlappingFieldsCanBeMerged.differentReturnTypes", pathToString(path), name1, name2); + return new Conflict(reason, fields); } - private void collectFieldsForInlineFragment(Map> fieldMap, Set visitedFragmentSpreads, GraphQLType parentType, InlineFragment inlineFragment) { - GraphQLType graphQLType = inlineFragment.getTypeCondition() != null - ? (GraphQLOutputType) TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), inlineFragment.getTypeCondition()) - : parentType; - collectFields(fieldMap, inlineFragment.getSelectionSet(), graphQLType, visitedFragmentSpreads); + + private boolean sameType(GraphQLType type1, GraphQLType type2) { + if (type1 == null || type2 == null) { + return true; + } + return type1.equals(type2); } - private void collectFieldsForField(Map> fieldMap, GraphQLType parentType, Field field) { - String responseName = field.getAlias() != null ? field.getAlias() : field.getName(); - if (!fieldMap.containsKey(responseName)) { - fieldMap.put(responseName, new ArrayList<>()); + + private static class FieldAndType { + final Field field; + final GraphQLType graphQLType; + final GraphQLType parentType; + + public FieldAndType(Field field, GraphQLType graphQLType, GraphQLType parentType) { + this.field = field; + this.graphQLType = graphQLType; + this.parentType = parentType; } - GraphQLOutputType fieldType = null; - if (parentType instanceof GraphQLFieldsContainer) { - GraphQLFieldsContainer fieldsContainer = (GraphQLFieldsContainer) parentType; - GraphQLFieldDefinition fieldDefinition = getVisibleFieldDefinition(fieldsContainer, field); - fieldType = fieldDefinition != null ? fieldDefinition.getType() : null; + + @Override + public String toString() { + return "FieldAndType{" + + "field=" + field + + ", graphQLType=" + graphQLType + + ", parentType=" + parentType + + '}'; } - fieldMap.get(responseName).add(new FieldAndType(field, fieldType, parentType)); - } - private GraphQLFieldDefinition getVisibleFieldDefinition(GraphQLFieldsContainer fieldsContainer, Field field) { - return getValidationContext().getSchema().getFieldVisibility().getFieldDefinition(fieldsContainer, field.getName()); - } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } - private static class FieldPair { - final Field field1; - final Field field2; + FieldAndType that = (FieldAndType) o; - public FieldPair(Field field1, Field field2) { - this.field1 = field1; - this.field2 = field2; + return Objects.equals(field, that.field); + } + + @Override + public int hashCode() { + return Objects.hashCode(field); } } private static class Conflict { - final String responseName; final String reason; - final List fields = new ArrayList<>(); + final Set fields = new LinkedHashSet<>(); - public Conflict(String responseName, String reason, Field field1, Field field2) { - this.responseName = responseName; - this.reason = reason; - this.fields.add(field1); - this.fields.add(field2); - } - public Conflict(String responseName, String reason, List fields) { - this.responseName = responseName; + public Conflict(String reason, List fields) { this.reason = reason; this.fields.addAll(fields); } - } - private static class FieldAndType { - final Field field; - final GraphQLType graphQLType; - final GraphQLType parentType; - - public FieldAndType(Field field, GraphQLType graphQLType, GraphQLType parentType) { - this.field = field; - this.graphQLType = graphQLType; - this.parentType = parentType; - } - } } diff --git a/src/main/java/graphql/validation/rules/PossibleFragmentSpreads.java b/src/main/java/graphql/validation/rules/PossibleFragmentSpreads.java index 18f809a3e1..a14740e113 100644 --- a/src/main/java/graphql/validation/rules/PossibleFragmentSpreads.java +++ b/src/main/java/graphql/validation/rules/PossibleFragmentSpreads.java @@ -2,6 +2,7 @@ import graphql.Assert; +import graphql.Internal; import graphql.execution.TypeFromAST; import graphql.language.FragmentDefinition; import graphql.language.FragmentSpread; @@ -15,28 +16,29 @@ import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import java.util.Collections; import java.util.List; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.validation.ValidationErrorType.InvalidFragmentType; + +@Internal public class PossibleFragmentSpreads extends AbstractRule { public PossibleFragmentSpreads(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { super(validationContext, validationErrorCollector); } - @Override public void checkInlineFragment(InlineFragment inlineFragment) { GraphQLOutputType fragType = getValidationContext().getOutputType(); GraphQLCompositeType parentType = getValidationContext().getParentType(); if (fragType == null || parentType == null) return; - if (!doTypesOverlap(fragType, parentType)) { - String message = String.format("Fragment cannot be spread here as objects of " + - "type %s can never be of type %s", parentType.getName(), fragType.getName()); - addError(ValidationErrorType.InvalidFragmentType, inlineFragment.getSourceLocation(), message); + if (isValidTargetCompositeType(fragType) && isValidTargetCompositeType(parentType) && !doTypesOverlap(fragType, parentType)) { + String message = i18n(InvalidFragmentType, "PossibleFragmentSpreads.inlineIncompatibleTypes", parentType.getName(), simplePrint(fragType)); + addError(InvalidFragmentType, inlineFragment.getSourceLocation(), message); } } @@ -48,10 +50,9 @@ public void checkFragmentSpread(FragmentSpread fragmentSpread) { GraphQLCompositeType parentType = getValidationContext().getParentType(); if (typeCondition == null || parentType == null) return; - if (!doTypesOverlap(typeCondition, parentType)) { - String message = String.format("Fragment %s cannot be spread here as objects of " + - "type %s can never be of type %s", fragmentSpread.getName(), parentType.getName(), typeCondition.getName()); - addError(ValidationErrorType.InvalidFragmentType, fragmentSpread.getSourceLocation(), message); + if (isValidTargetCompositeType(typeCondition) && isValidTargetCompositeType(parentType) && !doTypesOverlap(typeCondition, parentType)) { + String message = i18n(InvalidFragmentType, "PossibleFragmentSpreads.fragmentIncompatibleTypes", fragmentSpread.getName(), parentType.getName(), simplePrint(typeCondition)); + addError(InvalidFragmentType, fragmentSpread.getSourceLocation(), message); } } @@ -80,4 +81,14 @@ private List getPossibleType(GraphQLType type) { } return possibleConditionTypes; } + + /** + * Per spec: The target type of fragment (type condition) + * must have kind UNION, INTERFACE, or OBJECT. + * @param type GraphQLType + * @return true if it is a union, interface, or object. + */ + private boolean isValidTargetCompositeType(GraphQLType type) { + return type instanceof GraphQLCompositeType; + } } diff --git a/src/main/java/graphql/validation/rules/ProvidedNonNullArguments.java b/src/main/java/graphql/validation/rules/ProvidedNonNullArguments.java index bc68c6adc8..765e4ac276 100644 --- a/src/main/java/graphql/validation/rules/ProvidedNonNullArguments.java +++ b/src/main/java/graphql/validation/rules/ProvidedNonNullArguments.java @@ -1,24 +1,30 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.Argument; import graphql.language.Directive; import graphql.language.Field; import graphql.language.Node; +import graphql.language.NullValue; +import graphql.language.Value; import graphql.schema.GraphQLArgument; import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLFieldDefinition; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.validation.ValidationErrorType.MissingDirectiveArgument; +import static graphql.validation.ValidationErrorType.MissingFieldArgument; +import static graphql.validation.ValidationErrorType.NullValueForNonNullArgument; +@Internal public class ProvidedNonNullArguments extends AbstractRule { public ProvidedNonNullArguments(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { @@ -28,42 +34,55 @@ public ProvidedNonNullArguments(ValidationContext validationContext, ValidationE @Override public void checkField(Field field) { GraphQLFieldDefinition fieldDef = getValidationContext().getFieldDef(); - if (fieldDef == null) return; + if (fieldDef == null) { + return; + } Map argumentMap = argumentMap(field.getArguments()); for (GraphQLArgument graphQLArgument : fieldDef.getArguments()) { Argument argument = argumentMap.get(graphQLArgument.getName()); - if (argument == null - && (isNonNull(graphQLArgument.getType())) - && (graphQLArgument.getDefaultValue() == null)) { - String message = String.format("Missing field argument %s", graphQLArgument.getName()); - addError(ValidationErrorType.MissingFieldArgument, field.getSourceLocation(), message); + boolean nonNullType = isNonNull(graphQLArgument.getType()); + boolean noDefaultValue = graphQLArgument.getArgumentDefaultValue().isNotSet(); + if (argument == null && nonNullType && noDefaultValue) { + String message = i18n(MissingFieldArgument, "ProvidedNonNullArguments.missingFieldArg", graphQLArgument.getName()); + addError(MissingFieldArgument, field.getSourceLocation(), message); } - } - } - private Map argumentMap(List arguments) { - Map result = new LinkedHashMap<>(); - for (Argument argument : arguments) { - result.put(argument.getName(), argument); + if (argument != null) { + Value value = argument.getValue(); + if ((value == null || value instanceof NullValue) && nonNullType && noDefaultValue) { + String message = i18n(NullValueForNonNullArgument, "ProvidedNonNullArguments.nullValue", graphQLArgument.getName()); + addError(NullValueForNonNullArgument, field.getSourceLocation(), message); + } + } } - return result; } @Override public void checkDirective(Directive directive, List ancestors) { GraphQLDirective graphQLDirective = getValidationContext().getDirective(); - if (graphQLDirective == null) return; + if (graphQLDirective == null) { + return; + } Map argumentMap = argumentMap(directive.getArguments()); for (GraphQLArgument graphQLArgument : graphQLDirective.getArguments()) { Argument argument = argumentMap.get(graphQLArgument.getName()); - if (argument == null - && (isNonNull(graphQLArgument.getType()))) { - String message = String.format("Missing directive argument %s", graphQLArgument.getName()); - addError(ValidationErrorType.MissingDirectiveArgument, directive.getSourceLocation(), message); + boolean nonNullType = isNonNull(graphQLArgument.getType()); + boolean noDefaultValue = graphQLArgument.getArgumentDefaultValue().isNotSet(); + if (argument == null && nonNullType && noDefaultValue) { + String message = i18n(MissingDirectiveArgument, "ProvidedNonNullArguments.missingDirectiveArg", graphQLArgument.getName()); + addError(MissingDirectiveArgument, directive.getSourceLocation(), message); } } } + + private Map argumentMap(List arguments) { + Map result = new LinkedHashMap<>(); + for (Argument argument : arguments) { + result.put(argument.getName(), argument); + } + return result; + } } diff --git a/src/main/java/graphql/validation/rules/ScalarLeafs.java b/src/main/java/graphql/validation/rules/ScalarLeafs.java deleted file mode 100644 index 10213a776f..0000000000 --- a/src/main/java/graphql/validation/rules/ScalarLeafs.java +++ /dev/null @@ -1,35 +0,0 @@ -package graphql.validation.rules; - - -import graphql.language.Field; -import graphql.schema.GraphQLOutputType; -import graphql.validation.AbstractRule; -import graphql.validation.ValidationContext; -import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; - -import static graphql.schema.GraphQLTypeUtil.isLeaf; - -public class ScalarLeafs extends AbstractRule { - - public ScalarLeafs(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { - super(validationContext, validationErrorCollector); - } - - @Override - public void checkField(Field field) { - GraphQLOutputType type = getValidationContext().getOutputType(); - if (type == null) return; - if (isLeaf(type)) { - if (field.getSelectionSet() != null) { - String message = String.format("Sub selection not allowed on leaf type %s of field %s", type.getName(), field.getName()); - addError(ValidationErrorType.SubSelectionNotAllowed, field.getSourceLocation(), message); - } - } else { - if (field.getSelectionSet() == null) { - String message = String.format("Sub selection required for type %s of field %s", type.getName(), field.getName()); - addError(ValidationErrorType.SubSelectionRequired, field.getSourceLocation(), message); - } - } - } -} diff --git a/src/main/java/graphql/validation/rules/ScalarLeaves.java b/src/main/java/graphql/validation/rules/ScalarLeaves.java new file mode 100644 index 0000000000..072ba15080 --- /dev/null +++ b/src/main/java/graphql/validation/rules/ScalarLeaves.java @@ -0,0 +1,39 @@ +package graphql.validation.rules; + + +import graphql.Internal; +import graphql.language.Field; +import graphql.schema.GraphQLOutputType; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import static graphql.schema.GraphQLTypeUtil.isLeaf; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.validation.ValidationErrorType.SubselectionNotAllowed; +import static graphql.validation.ValidationErrorType.SubselectionRequired; + +@Internal +public class ScalarLeaves extends AbstractRule { + + public ScalarLeaves(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkField(Field field) { + GraphQLOutputType type = getValidationContext().getOutputType(); + if (type == null) return; + if (isLeaf(type)) { + if (field.getSelectionSet() != null) { + String message = i18n(SubselectionNotAllowed, "ScalarLeaves.subselectionOnLeaf", simplePrint(type), field.getName()); + addError(SubselectionNotAllowed, field.getSourceLocation(), message); + } + } else { + if (field.getSelectionSet() == null) { + String message = i18n(SubselectionRequired, "ScalarLeaves.subselectionRequired", simplePrint(type), field.getName()); + addError(SubselectionRequired, field.getSourceLocation(), message); + } + } + } +} diff --git a/src/main/java/graphql/validation/rules/SubscriptionUniqueRootField.java b/src/main/java/graphql/validation/rules/SubscriptionUniqueRootField.java new file mode 100644 index 0000000000..0ded9ca632 --- /dev/null +++ b/src/main/java/graphql/validation/rules/SubscriptionUniqueRootField.java @@ -0,0 +1,72 @@ +package graphql.validation.rules; + +import graphql.Internal; +import graphql.execution.CoercedVariables; +import graphql.execution.FieldCollector; +import graphql.execution.FieldCollectorParameters; +import graphql.execution.MergedField; +import graphql.execution.MergedSelectionSet; +import graphql.language.NodeUtil; +import graphql.language.OperationDefinition; +import graphql.language.Selection; +import graphql.schema.GraphQLObjectType; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.List; + +import static graphql.language.OperationDefinition.Operation.SUBSCRIPTION; +import static graphql.validation.ValidationErrorType.SubscriptionIntrospectionRootField; +import static graphql.validation.ValidationErrorType.SubscriptionMultipleRootFields; + + +/** + * A subscription operation must only have one root field + * A subscription operation's single root field must not be an introspection field + * https://spec.graphql.org/draft/#sec-Single-root-field + */ +@Internal +public class SubscriptionUniqueRootField extends AbstractRule { + private final FieldCollector fieldCollector = new FieldCollector(); + public SubscriptionUniqueRootField(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkOperationDefinition(OperationDefinition operationDef) { + if (operationDef.getOperation() == SUBSCRIPTION) { + + GraphQLObjectType subscriptionType = getValidationContext().getSchema().getSubscriptionType(); + + FieldCollectorParameters collectorParameters = FieldCollectorParameters.newParameters() + .schema(getValidationContext().getSchema()) + .fragments(NodeUtil.getFragmentsByName(getValidationContext().getDocument())) + .variables(CoercedVariables.emptyVariables().toMap()) + .objectType(subscriptionType) + .graphQLContext(getValidationContext().getGraphQLContext()) + .build(); + + MergedSelectionSet fields = fieldCollector.collectFields(collectorParameters, operationDef.getSelectionSet()); + List subscriptionSelections = operationDef.getSelectionSet().getSelections(); + + if (fields.size() > 1) { + String message = i18n(SubscriptionMultipleRootFields, "SubscriptionUniqueRootField.multipleRootFields", operationDef.getName()); + addError(SubscriptionMultipleRootFields, operationDef.getSourceLocation(), message); + } else { // Only one item in selection set, size == 1 + + MergedField mergedField = fields.getSubFieldsList().get(0); + + + if (isIntrospectionField(mergedField)) { + String message = i18n(SubscriptionIntrospectionRootField, "SubscriptionIntrospectionRootField.introspectionRootField", operationDef.getName(), mergedField.getName()); + addError(SubscriptionIntrospectionRootField, mergedField.getSingleField().getSourceLocation(), message); + } + } + } + } + + private boolean isIntrospectionField(MergedField field) { + return field.getName().startsWith("__"); + } +} diff --git a/src/main/java/graphql/validation/rules/UniqueArgumentNames.java b/src/main/java/graphql/validation/rules/UniqueArgumentNames.java new file mode 100644 index 0000000000..8122446a13 --- /dev/null +++ b/src/main/java/graphql/validation/rules/UniqueArgumentNames.java @@ -0,0 +1,66 @@ +package graphql.validation.rules; + +import com.google.common.collect.Sets; +import graphql.Internal; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.Field; +import graphql.language.Node; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.List; +import java.util.Set; + +import static graphql.validation.ValidationErrorType.DuplicateArgumentNames; + + +/** + * Unique argument names + * + * A GraphQL field or directive is only valid if all supplied arguments are uniquely named. + */ +@Internal +public class UniqueArgumentNames extends AbstractRule { + public UniqueArgumentNames(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkField(Field field) { + if (field.getArguments() == null || field.getArguments().size() <= 1) { + return; + } + + Set arguments = Sets.newHashSetWithExpectedSize(field.getArguments().size()); + + for (Argument argument : field.getArguments()) { + if (arguments.contains(argument.getName())) { + String message = i18n(DuplicateArgumentNames, "UniqueArgumentNames.uniqueArgument", argument.getName()); + addError(DuplicateArgumentNames, field.getSourceLocation(), message); + } else { + arguments.add(argument.getName()); + } + } + } + + @Override + public void checkDirective(Directive directive, List ancestors) { + if (directive.getArguments() == null || directive.getArguments().size() <= 1) { + return; + } + + Set arguments = Sets.newHashSetWithExpectedSize(directive.getArguments().size()); + + for (Argument argument : directive.getArguments()) { + if (arguments.contains(argument.getName())) { + String message = i18n(DuplicateArgumentNames, "UniqueArgumentNames.uniqueArgument", argument.getName()); + addError(DuplicateArgumentNames, directive.getSourceLocation(), message); + } else { + arguments.add(argument.getName()); + } + } + + } +} diff --git a/src/main/java/graphql/validation/rules/UniqueDirectiveNamesPerLocation.java b/src/main/java/graphql/validation/rules/UniqueDirectiveNamesPerLocation.java new file mode 100644 index 0000000000..0aa5eb68ac --- /dev/null +++ b/src/main/java/graphql/validation/rules/UniqueDirectiveNamesPerLocation.java @@ -0,0 +1,79 @@ +package graphql.validation.rules; + +import graphql.Internal; +import graphql.language.Directive; +import graphql.language.Document; +import graphql.language.Field; +import graphql.language.FragmentDefinition; +import graphql.language.FragmentSpread; +import graphql.language.InlineFragment; +import graphql.language.Node; +import graphql.language.OperationDefinition; +import graphql.schema.GraphQLDirective; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static graphql.validation.ValidationErrorType.DuplicateDirectiveName; + + +/** + * https://facebook.github.io/graphql/June2018/#sec-Directives-Are-Unique-Per-Location + */ +@Internal +public class UniqueDirectiveNamesPerLocation extends AbstractRule { + + public UniqueDirectiveNamesPerLocation(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkDocument(Document document) { + super.checkDocument(document); + } + + @Override + public void checkInlineFragment(InlineFragment inlineFragment) { + checkDirectivesUniqueness(inlineFragment, inlineFragment.getDirectives()); + } + + @Override + public void checkFragmentDefinition(FragmentDefinition fragmentDefinition) { + checkDirectivesUniqueness(fragmentDefinition, fragmentDefinition.getDirectives()); + } + + @Override + public void checkFragmentSpread(FragmentSpread fragmentSpread) { + checkDirectivesUniqueness(fragmentSpread, fragmentSpread.getDirectives()); + } + + @Override + public void checkField(Field field) { + checkDirectivesUniqueness(field, field.getDirectives()); + } + + @Override + public void checkOperationDefinition(OperationDefinition operationDefinition) { + checkDirectivesUniqueness(operationDefinition, operationDefinition.getDirectives()); + } + + private void checkDirectivesUniqueness(Node directivesContainer, List directives) { + Set directiveNames = new LinkedHashSet<>(); + for (Directive directive : directives) { + String name = directive.getName(); + GraphQLDirective graphQLDirective = getValidationContext().getSchema().getDirective(name); + boolean nonRepeatable = graphQLDirective != null && graphQLDirective.isNonRepeatable(); + if (directiveNames.contains(name) && nonRepeatable) { + String message = i18n(DuplicateDirectiveName, "UniqueDirectiveNamesPerLocation.uniqueDirectives", name, directivesContainer.getClass().getSimpleName()); + addError(DuplicateDirectiveName, directive.getSourceLocation(), message); + } else { + directiveNames.add(name); + } + } + } + +} diff --git a/src/main/java/graphql/validation/rules/UniqueFragmentNames.java b/src/main/java/graphql/validation/rules/UniqueFragmentNames.java new file mode 100644 index 0000000000..34adb39854 --- /dev/null +++ b/src/main/java/graphql/validation/rules/UniqueFragmentNames.java @@ -0,0 +1,40 @@ +package graphql.validation.rules; + +import graphql.Internal; +import graphql.language.FragmentDefinition; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.LinkedHashSet; +import java.util.Set; + +import static graphql.validation.ValidationErrorType.DuplicateFragmentName; + + +@Internal +public class UniqueFragmentNames extends AbstractRule { + + + private Set fragmentNames = new LinkedHashSet<>(); + + + public UniqueFragmentNames(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkFragmentDefinition(FragmentDefinition fragmentDefinition) { + String name = fragmentDefinition.getName(); + if (name == null) { + return; + } + + if (fragmentNames.contains(name)) { + String message = i18n(DuplicateFragmentName, "UniqueFragmentNames.oneFragment", name); + addError(DuplicateFragmentName, fragmentDefinition.getSourceLocation(), message); + } else { + fragmentNames.add(name); + } + } +} diff --git a/src/main/java/graphql/validation/rules/UniqueObjectFieldName.java b/src/main/java/graphql/validation/rules/UniqueObjectFieldName.java new file mode 100644 index 0000000000..25c7c2410d --- /dev/null +++ b/src/main/java/graphql/validation/rules/UniqueObjectFieldName.java @@ -0,0 +1,34 @@ +package graphql.validation.rules; + +import static graphql.validation.ValidationErrorType.UniqueObjectFieldName; + +import com.google.common.collect.Sets; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.Set; + +public class UniqueObjectFieldName extends AbstractRule { + public UniqueObjectFieldName(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkObjectValue(ObjectValue objectValue) { + Set fieldNames = Sets.newHashSetWithExpectedSize(objectValue.getObjectFields().size()); + + for (ObjectField field : objectValue.getObjectFields()) { + String fieldName = field.getName(); + + if (fieldNames.contains(fieldName)) { + String message = i18n(UniqueObjectFieldName, "UniqueObjectFieldName.duplicateFieldName", fieldName); + addError(UniqueObjectFieldName, objectValue.getSourceLocation(), message); + } else { + fieldNames.add(fieldName); + } + } + } +} diff --git a/src/main/java/graphql/validation/rules/UniqueOperationNames.java b/src/main/java/graphql/validation/rules/UniqueOperationNames.java index 33d3db8ce0..f3eecf00d8 100644 --- a/src/main/java/graphql/validation/rules/UniqueOperationNames.java +++ b/src/main/java/graphql/validation/rules/UniqueOperationNames.java @@ -1,21 +1,24 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.OperationDefinition; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; +import static graphql.validation.ValidationErrorType.DuplicateOperationName; + /** * A GraphQL document is only valid if all defined operations have unique names. - * http://facebook.github.io/graphql/October2016/#sec-Operation-Name-Uniqueness + * https://spec.graphql.org/October2021/#sec-Operation-Name-Uniqueness */ +@Internal public class UniqueOperationNames extends AbstractRule { - private Set operationNames = new HashSet<>(); + private Set operationNames = new LinkedHashSet<>(); public UniqueOperationNames(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { super(validationContext, validationErrorCollector); @@ -32,13 +35,10 @@ public void checkOperationDefinition(OperationDefinition operationDefinition) { } if (operationNames.contains(name)) { - addError(ValidationErrorType.DuplicateOperationName, operationDefinition.getSourceLocation(), duplicateOperationNameMessage(name)); + String message = i18n(DuplicateOperationName, "UniqueOperationNames.oneOperation", operationDefinition.getName()); + addError(DuplicateOperationName, operationDefinition.getSourceLocation(), message); } else { operationNames.add(name); } } - - static String duplicateOperationNameMessage(String definitionName) { - return String.format("There can be only one operation named '%s'", definitionName); - } } diff --git a/src/main/java/graphql/validation/rules/UniqueVariableNames.java b/src/main/java/graphql/validation/rules/UniqueVariableNames.java new file mode 100644 index 0000000000..e8706dc1e2 --- /dev/null +++ b/src/main/java/graphql/validation/rules/UniqueVariableNames.java @@ -0,0 +1,48 @@ +package graphql.validation.rules; + +import com.google.common.collect.Sets; +import graphql.Internal; +import graphql.language.OperationDefinition; +import graphql.language.VariableDefinition; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import static graphql.validation.ValidationErrorType.DuplicateVariableName; + +/** + * Unique variable names + *

    + * A GraphQL operation is only valid if all its variables are uniquely named. + */ +@Internal +public class UniqueVariableNames extends AbstractRule { + + public UniqueVariableNames(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + super(validationContext, validationErrorCollector); + } + + @Override + public void checkOperationDefinition(OperationDefinition operationDefinition) { + List variableDefinitions = operationDefinition.getVariableDefinitions(); + if (variableDefinitions == null || variableDefinitions.size() <= 1) { + return; + } + + Set variableNameList = Sets.newLinkedHashSetWithExpectedSize(variableDefinitions.size()); + + + for (VariableDefinition variableDefinition : variableDefinitions) { + if (variableNameList.contains(variableDefinition.getName())) { + String message = i18n(DuplicateVariableName, "UniqueVariableNames.oneVariable", variableDefinition.getName()); + addError(DuplicateVariableName, variableDefinition.getSourceLocation(), message); + } else { + variableNameList.add(variableDefinition.getName()); + } + } + } +} diff --git a/src/main/java/graphql/validation/rules/VariableDefaultValuesOfCorrectType.java b/src/main/java/graphql/validation/rules/VariableDefaultValuesOfCorrectType.java index ab42cbad72..115b70e895 100644 --- a/src/main/java/graphql/validation/rules/VariableDefaultValuesOfCorrectType.java +++ b/src/main/java/graphql/validation/rules/VariableDefaultValuesOfCorrectType.java @@ -1,15 +1,16 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.VariableDefinition; import graphql.schema.GraphQLInputType; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; - -import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.schema.GraphQLTypeUtil.simplePrint; +import static graphql.validation.ValidationErrorType.BadValueForDefaultArg; +@Internal public class VariableDefaultValuesOfCorrectType extends AbstractRule { @@ -17,19 +18,16 @@ public VariableDefaultValuesOfCorrectType(ValidationContext validationContext, V super(validationContext, validationErrorCollector); } - @Override public void checkVariableDefinition(VariableDefinition variableDefinition) { GraphQLInputType inputType = getValidationContext().getInputType(); - if (inputType == null) return; - if (isNonNull(inputType) && variableDefinition.getDefaultValue() != null) { - String message = "Missing value for non null type"; - addError(ValidationErrorType.DefaultForNonNullArgument, variableDefinition.getSourceLocation(), message); + if (inputType == null) { + return; } if (variableDefinition.getDefaultValue() != null - && !getValidationUtil().isValidLiteralValue(variableDefinition.getDefaultValue(), inputType, getValidationContext().getSchema())) { - String message = String.format("Bad default value %s for type %s", variableDefinition.getDefaultValue(), inputType.getName()); - addError(ValidationErrorType.BadValueForDefaultArg, variableDefinition.getSourceLocation(), message); + && !getValidationUtil().isValidLiteralValue(variableDefinition.getDefaultValue(), inputType, getValidationContext().getSchema(), getValidationContext().getGraphQLContext(), getValidationContext().getI18n().getLocale())) { + String message = i18n(BadValueForDefaultArg, "VariableDefaultValuesOfCorrectType.badDefault", variableDefinition.getDefaultValue(), simplePrint(inputType)); + addError(BadValueForDefaultArg, variableDefinition.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/VariableTypesMatch.java b/src/main/java/graphql/validation/rules/VariableTypesMatch.java new file mode 100644 index 0000000000..ef7c4069f4 --- /dev/null +++ b/src/main/java/graphql/validation/rules/VariableTypesMatch.java @@ -0,0 +1,84 @@ +package graphql.validation.rules; + + +import graphql.Internal; +import graphql.execution.TypeFromAST; +import graphql.execution.ValuesResolver; +import graphql.language.OperationDefinition; +import graphql.language.Value; +import graphql.language.VariableDefinition; +import graphql.language.VariableReference; +import graphql.schema.GraphQLInputType; +import graphql.schema.GraphQLType; +import graphql.schema.GraphQLTypeUtil; +import graphql.schema.InputValueWithState; +import graphql.validation.AbstractRule; +import graphql.validation.ValidationContext; +import graphql.validation.ValidationErrorCollector; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; + +import static graphql.validation.ValidationErrorType.VariableTypeMismatch; + +@Internal +public class VariableTypesMatch extends AbstractRule { + + final VariablesTypesMatcher variablesTypesMatcher; + + private Map variableDefinitionMap; + + public VariableTypesMatch(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { + this(validationContext, validationErrorCollector, new VariablesTypesMatcher()); + } + + VariableTypesMatch(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector, VariablesTypesMatcher variablesTypesMatcher) { + super(validationContext, validationErrorCollector); + setVisitFragmentSpreads(true); + this.variablesTypesMatcher = variablesTypesMatcher; + } + + @Override + public void checkOperationDefinition(OperationDefinition operationDefinition) { + variableDefinitionMap = new LinkedHashMap<>(); + } + + @Override + public void checkVariableDefinition(VariableDefinition variableDefinition) { + variableDefinitionMap.put(variableDefinition.getName(), variableDefinition); + } + + @Override + public void checkVariable(VariableReference variableReference) { + VariableDefinition variableDefinition = variableDefinitionMap.get(variableReference.getName()); + if (variableDefinition == null) { + return; + } + GraphQLType variableType = TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), variableDefinition.getType()); + if (variableType == null) { + return; + } + GraphQLInputType locationType = getValidationContext().getInputType(); + Optional locationDefault = Optional.ofNullable(getValidationContext().getDefaultValue()); + if (locationType == null) { + // we must have an unknown variable say to not have a known type + return; + } + Value locationDefaultValue = null; + if (locationDefault.isPresent() && locationDefault.get().isLiteral()) { + locationDefaultValue = (Value) locationDefault.get().getValue(); + } else if (locationDefault.isPresent() && locationDefault.get().isSet()) { + locationDefaultValue = ValuesResolver.valueToLiteral(locationDefault.get(), locationType, getValidationContext().getGraphQLContext(), getValidationContext().getI18n().getLocale()); + } + boolean variableDefMatches = variablesTypesMatcher.doesVariableTypesMatch(variableType, variableDefinition.getDefaultValue(), locationType, locationDefaultValue); + if (!variableDefMatches) { + GraphQLType effectiveType = variablesTypesMatcher.effectiveType(variableType, variableDefinition.getDefaultValue()); + String message = i18n(VariableTypeMismatch, "VariableTypesMatchRule.unexpectedType", + variableDefinition.getName(), + GraphQLTypeUtil.simplePrint(effectiveType), + GraphQLTypeUtil.simplePrint(locationType)); + addError(VariableTypeMismatch, variableReference.getSourceLocation(), message); + } + } +} diff --git a/src/main/java/graphql/validation/rules/VariableTypesMatchRule.java b/src/main/java/graphql/validation/rules/VariableTypesMatchRule.java deleted file mode 100644 index fd8771f35f..0000000000 --- a/src/main/java/graphql/validation/rules/VariableTypesMatchRule.java +++ /dev/null @@ -1,70 +0,0 @@ -package graphql.validation.rules; - - -import graphql.execution.TypeFromAST; -import graphql.language.OperationDefinition; -import graphql.language.VariableDefinition; -import graphql.language.VariableReference; -import graphql.schema.GraphQLInputType; -import graphql.schema.GraphQLType; -import graphql.schema.GraphQLTypeUtil; -import graphql.validation.AbstractRule; -import graphql.validation.ValidationContext; -import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class VariableTypesMatchRule extends AbstractRule { - - final VariablesTypesMatcher variablesTypesMatcher; - - private Map variableDefinitionMap; - - public VariableTypesMatchRule(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { - this(validationContext, validationErrorCollector, new VariablesTypesMatcher()); - } - - VariableTypesMatchRule(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector, VariablesTypesMatcher variablesTypesMatcher) { - super(validationContext, validationErrorCollector); - setVisitFragmentSpreads(true); - this.variablesTypesMatcher = variablesTypesMatcher; - } - - @Override - public void checkOperationDefinition(OperationDefinition operationDefinition) { - variableDefinitionMap = new LinkedHashMap<>(); - } - - @Override - public void checkVariableDefinition(VariableDefinition variableDefinition) { - variableDefinitionMap.put(variableDefinition.getName(), variableDefinition); - } - - @Override - public void checkVariable(VariableReference variableReference) { - VariableDefinition variableDefinition = variableDefinitionMap.get(variableReference.getName()); - if (variableDefinition == null) { - return; - } - GraphQLType variableType = TypeFromAST.getTypeFromAST(getValidationContext().getSchema(), variableDefinition.getType()); - if (variableType == null) { - return; - } - GraphQLInputType expectedType = getValidationContext().getInputType(); - if (expectedType == null) { - // we must have a unknown variable say to not have a known type - return; - } - if (!variablesTypesMatcher.doesVariableTypesMatch(variableType, variableDefinition.getDefaultValue(), expectedType)) { - GraphQLType effectiveType = variablesTypesMatcher.effectiveType(variableType, variableDefinition.getDefaultValue()); - String message = String.format("Variable type '%s' doesn't match expected type '%s'", - GraphQLTypeUtil.getUnwrappedTypeName(effectiveType), - GraphQLTypeUtil.getUnwrappedTypeName(expectedType)); - addError(ValidationErrorType.VariableTypeMismatch, variableReference.getSourceLocation(), message); - } - } - - -} diff --git a/src/main/java/graphql/validation/rules/VariablesAreInputTypes.java b/src/main/java/graphql/validation/rules/VariablesAreInputTypes.java index b67008db3a..3962ffeef4 100644 --- a/src/main/java/graphql/validation/rules/VariablesAreInputTypes.java +++ b/src/main/java/graphql/validation/rules/VariablesAreInputTypes.java @@ -1,16 +1,18 @@ package graphql.validation.rules; +import graphql.Internal; import graphql.language.TypeName; import graphql.language.VariableDefinition; import graphql.schema.GraphQLType; import graphql.validation.AbstractRule; import graphql.validation.ValidationContext; import graphql.validation.ValidationErrorCollector; -import graphql.validation.ValidationErrorType; import static graphql.schema.GraphQLTypeUtil.isInput; +import static graphql.validation.ValidationErrorType.NonInputTypeOnVariable; +@Internal public class VariablesAreInputTypes extends AbstractRule { public VariablesAreInputTypes(ValidationContext validationContext, ValidationErrorCollector validationErrorCollector) { @@ -22,10 +24,12 @@ public void checkVariableDefinition(VariableDefinition variableDefinition) { TypeName unmodifiedAstType = getValidationUtil().getUnmodifiedType(variableDefinition.getType()); GraphQLType type = getValidationContext().getSchema().getType(unmodifiedAstType.getName()); - if (type == null) return; + if (type == null) { + return; + } if (!isInput(type)) { - String message = "Wrong type for a variable"; - addError(ValidationErrorType.NonInputTypeOnVariable, variableDefinition.getSourceLocation(), message); + String message = i18n(NonInputTypeOnVariable, "VariablesAreInputTypes.wrongType", variableDefinition.getName(), unmodifiedAstType.getName()); + addError(NonInputTypeOnVariable, variableDefinition.getSourceLocation(), message); } } } diff --git a/src/main/java/graphql/validation/rules/VariablesTypesMatcher.java b/src/main/java/graphql/validation/rules/VariablesTypesMatcher.java index 82500d69d7..0b47fcec78 100644 --- a/src/main/java/graphql/validation/rules/VariablesTypesMatcher.java +++ b/src/main/java/graphql/validation/rules/VariablesTypesMatcher.java @@ -2,23 +2,46 @@ import graphql.Internal; +import graphql.language.NullValue; import graphql.language.Value; import graphql.schema.GraphQLType; import static graphql.schema.GraphQLNonNull.nonNull; import static graphql.schema.GraphQLTypeUtil.isList; import static graphql.schema.GraphQLTypeUtil.isNonNull; +import static graphql.schema.GraphQLTypeUtil.unwrapNonNull; import static graphql.schema.GraphQLTypeUtil.unwrapOne; @Internal public class VariablesTypesMatcher { - public boolean doesVariableTypesMatch(GraphQLType variableType, Value variableDefaultValue, GraphQLType expectedType) { - return checkType(effectiveType(variableType, variableDefaultValue), expectedType); + /** + * This method and variable naming was inspired from the reference graphql-js implementation + * + * @param varType the variable type + * @param varDefaultValue the default value for the variable + * @param locationType the location type where the variable was encountered + * @param locationDefaultValue the default value for that location + * + * @return true if the variable matches ok + */ + public boolean doesVariableTypesMatch(GraphQLType varType, Value varDefaultValue, GraphQLType locationType, Value locationDefaultValue) { + if (isNonNull(locationType) && !isNonNull(varType)) { + boolean hasNonNullVariableDefaultValue = + varDefaultValue != null && !(varDefaultValue instanceof NullValue); + boolean hasLocationDefaultValue = locationDefaultValue != null; + if (!hasNonNullVariableDefaultValue && !hasLocationDefaultValue) { + return false; + } + GraphQLType nullableLocationType = unwrapNonNull(locationType); + return checkType(varType, nullableLocationType); + } + return checkType(varType, locationType); } - public GraphQLType effectiveType(GraphQLType variableType, Value defaultValue) { - if (defaultValue == null) { + + public GraphQLType effectiveType(GraphQLType variableType, Value defaultValue) { + if (defaultValue == null || defaultValue instanceof NullValue) { return variableType; } if (isNonNull(variableType)) { diff --git a/src/main/resources/i18n/Execution.properties b/src/main/resources/i18n/Execution.properties new file mode 100644 index 0000000000..396c87025f --- /dev/null +++ b/src/main/resources/i18n/Execution.properties @@ -0,0 +1,8 @@ +# +# This resource bundle is used for the query execution code to produce i18n messages +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +Execution.handleOneOfNotOneFieldError=Exactly one key must be specified for OneOf type ''{0}''. +Execution.handleOneOfValueIsNullError=OneOf type field ''{0}'' must be non-null. diff --git a/src/main/resources/i18n/Execution_de.properties b/src/main/resources/i18n/Execution_de.properties new file mode 100644 index 0000000000..dd194540c7 --- /dev/null +++ b/src/main/resources/i18n/Execution_de.properties @@ -0,0 +1,8 @@ +# +# This resource bundle is used for the query execution code to produce i18n messages +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +Execution.handleOneOfNotOneFieldError=Es muss genau ein Key angegeben werden für OneOf Typ ''{0}''. +Execution.handleOneOfValueIsNullError=OneOf type field ''{0}'' darf nicht null sein. diff --git a/src/main/resources/i18n/Execution_nl.properties b/src/main/resources/i18n/Execution_nl.properties new file mode 100644 index 0000000000..eee9f69ea0 --- /dev/null +++ b/src/main/resources/i18n/Execution_nl.properties @@ -0,0 +1,8 @@ +# +# This resource bundle is used for the query execution code to produce i18n messages +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +Execution.handleOneOfNotOneFieldError=Er moet exact één sleutel aangegeven worden voor OneOf type ''{0}''. +Execution.handleOneOfValueIsNullError=OneOf type field ''{0}'' mag niet null zijn. diff --git a/src/main/resources/i18n/General.properties b/src/main/resources/i18n/General.properties new file mode 100644 index 0000000000..c4022715c4 --- /dev/null +++ b/src/main/resources/i18n/General.properties @@ -0,0 +1,6 @@ +# +# This resource bundle is used for the general code to produce i18n messages +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# \ No newline at end of file diff --git a/src/main/resources/i18n/Parsing.properties b/src/main/resources/i18n/Parsing.properties new file mode 100644 index 0000000000..474fba1545 --- /dev/null +++ b/src/main/resources/i18n/Parsing.properties @@ -0,0 +1,29 @@ +# +# This resource bundle is used for the query parsing code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +InvalidSyntax.noMessage=Invalid syntax at line {0} column {1} +InvalidSyntax.full=Invalid syntax with ANTLR error ''{0}'' at line {1} column {2} + +InvalidSyntaxBail.noToken=Invalid syntax at line {0} column {1} +InvalidSyntaxBail.full=Invalid syntax with offending token ''{0}'' at line {1} column {2} +# +InvalidSyntaxMoreTokens.noMessage=Invalid syntax encountered. There are extra tokens in the text that have not been consumed. Offending token at line {0} column {1} +InvalidSyntaxMoreTokens.full=Invalid syntax encountered. There are extra tokens in the text that have not been consumed. Offending token ''{0}'' at line {1} column {2} +# +ParseCancelled.full=More than {0} ''{1}'' tokens have been presented. To prevent Denial Of Service attacks, parsing has been cancelled. +ParseCancelled.tooDeep=More than {0} deep ''{1}'' rules have been entered. To prevent Denial Of Service attacks, parsing has been cancelled. +ParseCancelled.tooManyChars=More than {0} characters have been presented. To prevent Denial Of Service attacks, parsing has been cancelled. +# +InvalidUnicode.trailingLeadingSurrogate=Invalid unicode encountered. Trailing surrogate must be preceded with a leading surrogate. Offending token ''{0}'' at line {1} column {2} +InvalidUnicode.leadingTrailingSurrogate=Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token ''{0}'' at line {1} column {2} +InvalidUnicode.invalidCodePoint=Invalid unicode encountered. Not a valid code point. Offending token ''{0}'' at line {1} column {2} +InvalidUnicode.incorrectEscape=Invalid unicode encountered. Incorrectly formatted escape sequence. Offending token ''{0}'' at line {1} column {2} diff --git a/src/main/resources/i18n/Parsing_de.properties b/src/main/resources/i18n/Parsing_de.properties new file mode 100644 index 0000000000..55127ff689 --- /dev/null +++ b/src/main/resources/i18n/Parsing_de.properties @@ -0,0 +1,29 @@ +# +# This resource bundle is used for the query parsing code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +InvalidSyntax.noMessage=Ungültige Syntax in Zeile {0} Spalte {1} +InvalidSyntax.full=Ungültige Syntax, ANTLR-Fehler ''{0}'' in Zeile {1} Spalte {2} + +InvalidSyntaxBail.noToken=Ungültige Syntax in Zeile {0} Spalte {1} +InvalidSyntaxBail.full=Ungültige Syntax wegen des ungültigen Tokens ''{0}'' in Zeile {1} Spalte {2} +# +InvalidSyntaxMoreTokens.noMessage=Es wurde eine ungültige Syntax festgestellt. Es gibt zusätzliche Token im Text, die nicht konsumiert wurden. Ungültiges Token in Zeile {0} Spalte {1} +InvalidSyntaxMoreTokens.full=Es wurde eine ungültige Syntax festgestellt. Es gibt zusätzliche Token im Text, die nicht konsumiert wurden. Ungültiges Token ''{0}'' in Zeile {1} Spalte {2} +# +ParseCancelled.full=Es wurden mehr als {0} ''{1}'' Token präsentiert. Um Denial-of-Service-Angriffe zu verhindern, wurde das Parsing abgebrochen. +ParseCancelled.tooDeep=Es wurden mehr als {0} tief ''{1}'' Regeln ausgeführt. Um Denial-of-Service-Angriffe zu verhindern, wurde das Parsing abgebrochen. +ParseCancelled.tooManyChars=Es wurden mehr als {0} Zeichen vorgelegt. Um Denial-of-Service-Angriffe zu verhindern, wurde das Parsing abgebrochen. +# +InvalidUnicode.trailingLeadingSurrogate=Ungültiger Unicode gefunden. Trailing surrogate muss ein leading surrogate vorangestellt werden. Ungültiges Token ''{0}'' in Zeile {1} Spalte {2} +InvalidUnicode.leadingTrailingSurrogate=Ungültiger Unicode gefunden. Auf ein leading surrogate muss ein trailing surrogate folgen. Ungültiges Token ''{0}'' in Zeile {1} Spalte {2} +InvalidUnicode.invalidCodePoint=Ungültiger Unicode gefunden. Kein gültiger code point. Ungültiges Token ''{0}'' in Zeile {1} Spalte {2} +InvalidUnicode.incorrectEscape=Ungültiger Unicode gefunden. Falsch formatierte Escape-Sequenz. Ungültiges Token ''{0}'' in Zeile {1} Spalte {2} diff --git a/src/main/resources/i18n/Parsing_nl.properties b/src/main/resources/i18n/Parsing_nl.properties new file mode 100644 index 0000000000..cfd8457825 --- /dev/null +++ b/src/main/resources/i18n/Parsing_nl.properties @@ -0,0 +1,28 @@ +# +# This resource bundle is used for the query parsing code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +InvalidSyntax.noMessage=Ongeldige syntaxis op lijn {0} kolom {1} +InvalidSyntax.full=Ongeldige syntaxis, ANTLR foutmelding ''{0}'' op lijn {1} kolom {2} +InvalidSyntaxBail.noToken=Ongeldige syntaxis op lijn {0} kolom {1} +InvalidSyntaxBail.full=Ongeldige syntaxis wegens ongeldige token ''{0}'' op lijn {1} kolom {2} +# +InvalidSyntaxMoreTokens.noMessage=Ongeldige syntaxis tegengekomen. Er zijn tokens in de tekst die niet zijn verwerkt. Ongeldige token op lijn {0} kolom {1} +InvalidSyntaxMoreTokens.full=Ongeldige syntaxis tegengekomen. Er zijn tokens in de tekst die niet zijn verwerkt. Ongeldige token ''{0}'' op lijn {1} kolom {2} +# +ParseCancelled.full=Meer dan {0} ''{1}'' tokens zijn gepresenteerd. Om een DDoS-aanval te voorkomen is het parsen gestopt. +ParseCancelled.tooDeep=Meer dan {0} diep, ''{1}'' regels zijn uitgevoerd. Om een DDoS-aanval te voorkomen is het parsen gestopt. +ParseCancelled.tooManyChars=Meer dan {0} tekens zijn voorgelegd. Om een DDoS-aanval te voorkomen is het parsen gestopt. +# +InvalidUnicode.trailingLeadingSurrogate=Ongeldige Unicode tegengekomen. Trailing surrogate moet vooropgaan aan een leading surrogate. Ongeldige token ''{0}'' op lijn {1} kolom {2} +InvalidUnicode.leadingTrailingSurrogate=Ongeldige Unicode tegengekomen. Leading surrogate moet voorafgaan aan een trailing surrogate. Ongeldige token ''{0}'' op lijn {1} kolom {2} +InvalidUnicode.invalidCodePoint=Ongeldige Unicode tegengekomen. Ongeldig codepunt. Ongeldige token ''{0}'' op lijn {1} kolom {2} +InvalidUnicode.incorrectEscape=Ongeldige Unicode tegengekomen. Ongeldige geformatteerde escape-sequentie. Ongeldige token ''{0}'' op lijn {1} kolom {2}} diff --git a/src/main/resources/i18n/Scalars.properties b/src/main/resources/i18n/Scalars.properties new file mode 100644 index 0000000000..39fc6b4105 --- /dev/null +++ b/src/main/resources/i18n/Scalars.properties @@ -0,0 +1,33 @@ +# +# This resource bundle is used for the scalar code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +Scalar.unexpectedAstType=Expected an AST type of ''{0}'' but it was a ''{1}'' +# +Enum.badInput=Invalid input for enum ''{0}''. Unknown value ''{1}'' +Enum.badName=Invalid input for enum ''{0}''. No value found for name ''{1}'' +Enum.unallowableValue=Literal value not in allowable values for enum ''{0}'' - ''{1}'' +# +Int.notInt=Expected a value that can be converted to type ''Int'' but it was a ''{0}'' +Int.outsideRange=Expected value to be in the integer range, but it was a ''{0}'' +# +ID.notId=Expected a value that can be converted to type ''ID'' but it was a ''{0}'' +ID.unexpectedAstType=Expected an AST type of ''IntValue'' or ''StringValue'' but it was a ''{0}'' +# +Float.notFloat=Expected a value that can be converted to type ''Float'' but it was a ''{0}'' +Float.unexpectedAstType=Expected an AST type of ''IntValue'' or ''FloatValue'' but it was a ''{0}'' +Float.unexpectedRawValueType=Expected a Number input, but it was a ''{0}'' +# +Boolean.notBoolean=Expected a value that can be converted to type ''Boolean'' but it was a ''{0}'' +Boolean.unexpectedAstType=Expected an AST type of ''BooleanValue'' but it was a ''{0}'' +Boolean.unexpectedRawValueType=Expected a Boolean input, but it was a ''{0}'' +# +String.unexpectedRawValueType=Expected a String input, but it was a ''{0}'' diff --git a/src/main/resources/i18n/Scalars_de.properties b/src/main/resources/i18n/Scalars_de.properties new file mode 100644 index 0000000000..242046369b --- /dev/null +++ b/src/main/resources/i18n/Scalars_de.properties @@ -0,0 +1,33 @@ +# +# This resource bundle is used for the scalar code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +Scalar.unexpectedAstType=Erwartet wurde ein AST type von ''{0}'', aber es war ein ''{1}'' +# +Enum.badInput=Ungültige Eingabe für enum ''{0}''. Unbekannter Wert ''{1}'' +Enum.badName=Ungültige Eingabe für enum ''{0}''. Kein Wert für den Namen ''{1}'' gefunden +Enum.unallowableValue=Literal nicht in den zulässigen Werten für enum ''{0}'' - ''{1}'' +# +Int.notInt=Erwartet wurde ein Wert, der in den Typ ''Int'' konvertiert werden kann, aber es war ein ''{0}'' +Int.outsideRange=Erwarteter Wert im Integer-Bereich, aber es war ein ''{0}'' +# +ID.notId=Erwartet wurde ein Wert, der in den Typ ''ID'' umgewandelt werden kann, aber es war ein ''{0}'' +ID.unexpectedAstType=Erwartet wurde ein AST type von ''IntValue'' oder ''StringValue'', aber es war ein ''{0}'' +# +Float.notFloat=Erwartet wurde ein Wert, der in den Typ ''Float'' konvertiert werden kann, aber es war ein ''{0}'' +Float.unexpectedAstType=Erwartet wurde ein AST type von ''IntValue'' oder ''FloatValue'', aber es war ein ''{0}'' +Float.unexpectedRawValueType=Erwartet wurde eine Number-Eingabe, aber es war ein ''{0}'' +# +Boolean.notBoolean=Erwartet wurde ein Wert, der in den Typ ''Boolean'' konvertiert werden kann, aber es war ein ''{0}'' +Boolean.unexpectedAstType=Erwartet wurde ein AST type ''BooleanValue'', aber es war ein ''{0}'' +Boolean.unexpectedRawValueType=Erwartet wurde eine Boolean-Eingabe, aber es war ein ''{0}'' +# +String.unexpectedRawValueType=Erwartet wurde eine String-Eingabe, aber es war ein ''{0}'' diff --git a/src/main/resources/i18n/Scalars_nl.properties b/src/main/resources/i18n/Scalars_nl.properties new file mode 100644 index 0000000000..9878c1716f --- /dev/null +++ b/src/main/resources/i18n/Scalars_nl.properties @@ -0,0 +1,36 @@ +# +# This resource bundle is used for the scalar code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +Scalar.unexpectedAstType=Verwacht werd een AST-type ''{0}'', maar het was een ''{1}'' +# +Enum.badInput=Ongeldige invoer voor enum ''{0}''. Onbekende waarde ''{1}'' +Enum.badName=Ongeldige invoer voor enum ''{0}''. Geen waarde gevonden voor naam ''{1}'' +Enum.unallowableValue=Literal is niet een toegestane waarde voor enum ''{0}'' - ''{1}'' +# +Int.notInt=Verwacht werd een waarde die in ''Int'' veranderd kon worden, maar het was een ''{0}'' +Int.outsideRange=Verwacht werd een waarde die binnen het integerbereik valt, maar het was een ''{0}'' +# +ID.notId=Verwacht werd een waarde die in ''ID'' veranderd kon worden, maar het was een ''{0}'' +ID.unexpectedAstType=Verwacht werd een AST-type ''IntValue'' of ''StringValue'', maar het was een ''{0}'' +# +Float.notFloat=Verwacht werd een waarde die in ''Float'' veranderd kon worden, maar het was een ''{0}'' +Float.unexpectedAstType=Verwacht werd een AST-type ''IntValue'' of ''FloatValue'', maar het was een ''{0}'' +# TODO: To be translated into Dutch +Float.unexpectedRawValueType=Expected a Number input, but it was a ''{0}'' +# +Boolean.notBoolean=Verwacht werd een waarde die in ''Boolean'' veranderd kon worden, maar het was een ''{0}'' +Boolean.unexpectedAstType=Verwacht werd een AST-type ''BooleanValue'', maar het was een ''{0}'' +# TODO: To be translated into Dutch +Boolean.unexpectedRawValueType=Expected a Boolean input, but it was a ''{0}'' +# +# TODO: To be translated into Dutch +String.unexpectedRawValueType=Expected a String input, but it was a ''{0}'' diff --git a/src/main/resources/i18n/Validation.properties b/src/main/resources/i18n/Validation.properties new file mode 100644 index 0000000000..a9403bea5b --- /dev/null +++ b/src/main/resources/i18n/Validation.properties @@ -0,0 +1,113 @@ +# +# This resource bundle is used for the query validation code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# + +DeferDirective.notAllowedOperationRootLevelMutation=Validation error ({0}) : Defer directive cannot be used on root mutation type ''{1}'' +DeferDirective.notAllowedOperationRootLevelSubscription=Validation error ({0}) : Defer directive cannot be used on root subscription type ''{1}'' +DeferDirective.labelMustBeStaticString= Validation error ({0}) : Defer directive?s label argument must be a static string +IncrementalDirective.notAllowedSubscriptionOperation=Validation error ({0}) : Directive ''{1}'' is not allowed to be used on operation subscription + +IncrementalDirective.uniqueArgument=Validation error ({0}) : There can be only one argument named ''{1}'' for directive defer/Stream +# +ExecutableDefinitions.notExecutableType=Validation error ({0}) : Type ''{1}'' definition is not executable +ExecutableDefinitions.notExecutableSchema=Validation error ({0}) : Schema definition is not executable +ExecutableDefinitions.notExecutableDirective=Validation error ({0}) : Directive ''{1}'' definition is not executable +ExecutableDefinitions.notExecutableDefinition=Validation error ({0}) : Provided definition is not executable +# +FieldsOnCorrectType.unknownField=Validation error ({0}) : Field ''{1}'' in type ''{2}'' is undefined +# +FragmentsOnCompositeType.invalidInlineTypeCondition=Validation error ({0}) : Inline fragment type condition is invalid, must be on Object/Interface/Union +FragmentsOnCompositeType.invalidFragmentTypeCondition=Validation error ({0}) : Fragment type condition is invalid, must be on Object/Interface/Union +# +KnownArgumentNames.unknownDirectiveArg=Validation error ({0}) : Unknown directive argument ''{1}'' +KnownArgumentNames.unknownFieldArg=Validation error ({0}) : Unknown field argument ''{1}'' +# +KnownDirectives.unknownDirective=Validation error ({0}) : Unknown directive ''{1}'' +KnownDirectives.directiveNotAllowed=Validation error ({0}) : Directive ''{1}'' not allowed here +# +KnownFragmentNames.undefinedFragment=Validation error ({0}) : Undefined fragment ''{1}'' +# +KnownTypeNames.unknownType=Validation error ({0}) : Unknown type ''{1}'' +# +KnownOperationTypes.noOperation=Validation error ({0}): The ''{1}'' operation is not supported by the schema +# +LoneAnonymousOperation.withOthers=Validation error ({0}) : Anonymous operation with other operations +LoneAnonymousOperation.namedOperation=Validation error ({0}) : Operation ''{1}'' is following anonymous operation +# +NoFragmentCycles.cyclesNotAllowed=Validation error ({0}) : Fragment cycles not allowed +# +NoUndefinedVariables.undefinedVariable=Validation error ({0}) : Undefined variable ''{1}'' +# +NoUnusedFragments.unusedFragments=Validation error ({0}) : Unused fragment ''{1}'' +# +NoUnusedVariables.unusedVariable=Validation error ({0}) : Unused variable ''{1}'' +# +OverlappingFieldsCanBeMerged.differentFields=Validation error ({0}) : ''{1}'' : ''{2}'' and ''{3}'' are different fields +OverlappingFieldsCanBeMerged.differentArgs=Validation error ({0}) : ''{1}'' : fields have different arguments +OverlappingFieldsCanBeMerged.differentNullability=Validation error ({0}) : ''{1}'' : fields have different nullability shapes +OverlappingFieldsCanBeMerged.differentLists=Validation error ({0}) : ''{1}'' : fields have different list shapes +OverlappingFieldsCanBeMerged.differentReturnTypes=Validation error ({0}) : ''{1}'' : returns different types ''{2}'' and ''{3}'' +# +PossibleFragmentSpreads.inlineIncompatibleTypes=Validation error ({0}) : Fragment cannot be spread here as objects of type ''{1}'' can never be of type ''{2}'' +PossibleFragmentSpreads.fragmentIncompatibleTypes=Validation error ({0}) : Fragment ''{1}'' cannot be spread here as objects of type ''{2}'' can never be of type ''{3}'' +# +ProvidedNonNullArguments.missingFieldArg=Validation error ({0}) : Missing field argument ''{1}'' +ProvidedNonNullArguments.missingDirectiveArg=Validation error ({0}) : Missing directive argument ''{1}'' +ProvidedNonNullArguments.nullValue=Validation error ({0}) : Null value for non-null field argument ''{1}'' +# +ScalarLeaves.subselectionOnLeaf=Validation error ({0}) : Subselection not allowed on leaf type ''{1}'' of field ''{2}'' +ScalarLeaves.subselectionRequired=Validation error ({0}) : Subselection required for type ''{1}'' of field ''{2}'' +# +SubscriptionUniqueRootField.multipleRootFields=Validation error ({0}) : Subscription operation ''{1}'' must have exactly one root field +SubscriptionUniqueRootField.multipleRootFieldsWithFragment=Validation error ({0}) : Subscription operation ''{1}'' must have exactly one root field with fragments +SubscriptionIntrospectionRootField.introspectionRootField=Validation error ({0}) : Subscription operation ''{1}'' root field ''{2}'' cannot be an introspection field +SubscriptionIntrospectionRootField.introspectionRootFieldWithFragment=Validation error ({0}) : Subscription operation ''{1}'' fragment root field ''{2}'' cannot be an introspection field +# +UniqueArgumentNames.uniqueArgument=Validation error ({0}) : There can be only one argument named ''{1}'' +# +UniqueDirectiveNamesPerLocation.uniqueDirectives=Validation error ({0}) : Non repeatable directives must be uniquely named within a location. The directive ''{1}'' used on a ''{2}'' is not unique +# +UniqueFragmentNames.oneFragment=Validation error ({0}) : There can be only one fragment named ''{1}'' +# +UniqueOperationNames.oneOperation=Validation error ({0}) : There can be only one operation named ''{1}'' +# +UniqueVariableNames.oneVariable=Validation error ({0}) : There can be only one variable named ''{1}'' +# +VariableDefaultValuesOfCorrectType.badDefault=Validation error ({0}) : Bad default value ''{1}'' for type ''{2}'' +# +VariablesAreInputTypes.wrongType=Validation error ({0}) : Input variable ''{1}'' type ''{2}'' is not an input type +# +VariableTypesMatchRule.unexpectedType=Validation error ({0}) : Variable ''{1}'' of type ''{2}'' used in position expecting type ''{3}'' +# +UniqueObjectFieldName.duplicateFieldName=Validation Error ({0}) : There can be only one field named ''{1}'' +# +# These are used but IDEA cant find them easily as being called +# +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleNullError=Validation error ({0}) : argument ''{1}'' with value ''{2}'' must not be null +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleScalarError=Validation error ({0}) : argument ''{1}'' with value ''{2}'' is not a valid ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleScalarErrorCustomMessage=Validation error ({0}) : argument ''{1}'' with value ''{2}'' is not a valid ''{3}'' - {4} +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleEnumError=Validation error ({0}) : argument ''{1}'' with value ''{2}'' is not a valid ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleEnumErrorCustomMessage=Validation error ({0}) : argument ''{1}'' with value ''{2}'' is not a valid ''{3}'' - {4} +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleNotObjectError=Validation error ({0}) : argument ''{1}'' with value ''{2}'' must be an object type +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleMissingFieldsError=Validation error ({0}) : argument ''{1}'' with value ''{2}'' is missing required fields ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleExtraFieldError=Validation error ({0}) : argument ''{1}'' with value ''{2}'' contains a field not in ''{3}'': ''{4}'' +# suppress inspection "UnusedProperty" +# suppress inspection "UnusedMessageFormatParameter" +ArgumentValidationUtil.extraOneOfFieldsError=Validation error ({0}) : Exactly one key must be specified for OneOf type ''{3}''. \ No newline at end of file diff --git a/src/main/resources/i18n/Validation_de.properties b/src/main/resources/i18n/Validation_de.properties new file mode 100644 index 0000000000..7823c9d511 --- /dev/null +++ b/src/main/resources/i18n/Validation_de.properties @@ -0,0 +1,102 @@ +# +# This resource bundle is used for the query validation code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +ExecutableDefinitions.notExecutableType=Validierungsfehler ({0}) : Type definition ''{1}'' ist nicht ausführbar +ExecutableDefinitions.notExecutableSchema=Validierungsfehler ({0}) : Schema definition ist nicht ausführbar +ExecutableDefinitions.notExecutableDirective=Validierungsfehler ({0}) : Directive definition ''{1}'' ist nicht ausführbar +ExecutableDefinitions.notExecutableDefinition=Validierungsfehler ({0}) : Die angegebene Definition ist nicht ausführbar +# +FieldsOnCorrectType.unknownField=Validierungsfehler ({0}) : Feld ''{1}'' vom Typ ''{2}'' ist nicht definiert +# +FragmentsOnCompositeType.invalidInlineTypeCondition=Validierungsfehler ({0}) : Inline fragment type condition ist ungültig, muss auf Object/Interface/Union stehen +FragmentsOnCompositeType.invalidFragmentTypeCondition=Validierungsfehler ({0}) : Fragment type condition ist ungültig, muss auf Object/Interface/Union stehen +# +KnownArgumentNames.unknownDirectiveArg=Validierungsfehler ({0}) : Unbekanntes directive argument ''{1}'' +KnownArgumentNames.unknownFieldArg=Validierungsfehler ({0}) : Unbekanntes field argument ''{1}'' +# +KnownDirectives.unknownDirective=Validierungsfehler ({0}) : Unbekannte directive ''{1}'' +KnownDirectives.directiveNotAllowed=Validierungsfehler ({0}) : Directive ''{1}'' ist hier nicht erlaubt +# +KnownFragmentNames.undefinedFragment=Validierungsfehler ({0}) : Undefiniertes Fragment ''{1}'' +# +KnownTypeNames.unknownType=Validierungsfehler ({0}) : Unbekannter Typ ''{1}'' +# +KnownOperationTypes.noOperation=Validierungsfehler ({0}): ''{1}'' Operation wird vom Schema nicht unterstützt +# +LoneAnonymousOperation.withOthers=Validierungsfehler ({0}) : Anonyme Operation mit anderen Operationen +LoneAnonymousOperation.namedOperation=Validierungsfehler ({0}) : Operation ''{1}'' folgt der anonymen Operation +# +NoFragmentCycles.cyclesNotAllowed=Validierungsfehler ({0}) : Fragment cycles nicht erlaubt +# +NoUndefinedVariables.undefinedVariable=Validierungsfehler ({0}) : Undefinierte Variable ''{1}'' +# +NoUnusedFragments.unusedFragments=Validierungsfehler ({0}) : Unbenutztes Fragment ''{1}'' +# +NoUnusedVariables.unusedVariable=Validierungsfehler ({0}) : Unbenutzte Variable ''{1}'' +# +OverlappingFieldsCanBeMerged.differentFields=Validierungsfehler ({0}) : ''{1}'' : ''{2}'' und ''{3}'' sind unterschiedliche Felder +OverlappingFieldsCanBeMerged.differentArgs=Validierungsfehler ({0}) : ''{1}'' : Felder haben unterschiedliche Argumente +OverlappingFieldsCanBeMerged.differentNullability=Validierungsfehler ({0}) : ''{1}'' : Felder haben unterschiedliche nullability shapes +OverlappingFieldsCanBeMerged.differentLists=Validierungsfehler ({0}) : ''{1}'' : Felder haben unterschiedliche list shapes +OverlappingFieldsCanBeMerged.differentReturnTypes=Validierungsfehler ({0}) : ''{1}'' : gibt verschiedene Typen ''{2}'' und ''{3}'' zurück +# +PossibleFragmentSpreads.inlineIncompatibleTypes=Validierungsfehler ({0}) : Fragment kann hier nicht verbreitet werden, da object vom Typ ''{1}'' niemals vom Typ ''{2}'' sein können +PossibleFragmentSpreads.fragmentIncompatibleTypes=Validierungsfehler ({0}) : Fragment ''{1}'' kann hier nicht verbreitet werden, da object vom Typ ''{2}'' niemals vom Typ ''{3}'' sein können +# +ProvidedNonNullArguments.missingFieldArg=Validierungsfehler ({0}) : Fehlendes field argument ''{1}'' +ProvidedNonNullArguments.missingDirectiveArg=Validierungsfehler ({0}) : Fehlendes directive argument ''{1}'' +ProvidedNonNullArguments.nullValue=Validierungsfehler ({0}) : Nullwert für non-null field argument ''{1}'' +# +ScalarLeaves.subselectionOnLeaf=Validierungsfehler ({0}) : Unterauswahl für Blatttyp ''{1}'' von Feld ''{2}'' nicht zulässig +ScalarLeaves.subselectionRequired=Validierungsfehler ({0}) : Unterauswahl erforderlich für Typ ''{1}'' des Feldes ''{2}'' +# +SubscriptionUniqueRootField.multipleRootFields=Validierungsfehler ({0}) : Subscription operation ''{1}'' muss genau ein root field haben +SubscriptionUniqueRootField.multipleRootFieldsWithFragment=Validierungsfehler ({0}) : Subscription operation ''{1}'' muss genau ein root field mit Fragmenten haben +SubscriptionIntrospectionRootField.introspectionRootField=Validierungsfehler ({0}) : Subscription operation ''{1}'' root field ''{2}'' kann kein introspection field sein +SubscriptionIntrospectionRootField.introspectionRootFieldWithFragment=Validierungsfehler ({0}) : Subscription operation ''{1}'' fragment root field ''{2}'' kann kein introspection field sein +# +UniqueArgumentNames.uniqueArgument=Validierungsfehler ({0}) : Es kann nur ein Argument namens ''{1}'' geben +# +UniqueDirectiveNamesPerLocation.uniqueDirectives=Validierungsfehler ({0}) : Nicht wiederholbare directive müssen innerhalb einer Lokation eindeutig benannt werden. Directive ''{1}'', die auf einem ''{2}'' verwendet wird, ist nicht eindeutig +# +UniqueFragmentNames.oneFragment=Validierungsfehler ({0}) : Es kann nur ein Fragment namens ''{1}'' geben +# +UniqueOperationNames.oneOperation=Validierungsfehler ({0}) : Es kann nur eine Operation namens ''{1}'' geben +# +UniqueVariableNames.oneVariable=Validierungsfehler ({0}) : Es kann nur eine Variable namens ''{1}'' geben +# +VariableDefaultValuesOfCorrectType.badDefault=Validierungsfehler ({0}) : Ungültiger Standardwert ''{1}'' für Typ ''{2}'' +# +VariablesAreInputTypes.wrongType=Validierungsfehler ({0}) : Eingabevariable ''{1}'' Typ ''{2}'' ist kein Eingabetyp +# +VariableTypesMatchRule.unexpectedType=Validierungsfehler ({0}) : Variable ''{1}'' vom Typ ''{2}'' verwendet in Position, die Typ ''{3}'' erwartet +UniqueObjectFieldName.duplicateFieldName=Validierungsfehler ({0}) : Es kann nur ein Feld mit Name ''{1}'' geben +# +# These are used but IDEA cant find them easily as being called +# +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleNullError=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' darf nicht null sein +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleScalarError=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' ist kein gültiges ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleScalarErrorCustomMessage=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' ist kein gültiges ''{3}'' - {4} +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleEnumError=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' ist kein gültiges ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleEnumErrorCustomMessage=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' ist kein gültiges ''{3}'' - {4} +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleNotObjectError=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' muss ein object type sein +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleMissingFieldsError=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' fehlen Pflichtfelder ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleExtraFieldError=Validierungsfehler ({0}) : Argument ''{1}'' mit Wert ''{2}'' enthält ein Feld nicht in ''{3}'': ''{4}'' +# diff --git a/src/main/resources/i18n/Validation_nl.properties b/src/main/resources/i18n/Validation_nl.properties new file mode 100644 index 0000000000..e30b342640 --- /dev/null +++ b/src/main/resources/i18n/Validation_nl.properties @@ -0,0 +1,100 @@ +# +# This resource bundle is used for the query validation code to produce i18n messages +# +# The keys have the format of rule class name and then message type within that. Most rules +# will only have 1 or 2 message keys +# +# Please try and keep this sorted within rule class and use # between sections so the IDEA Ctrl-Alt-L reformat does not bunch +# them too tightly. +# +# REMEMBER - a single quote ' in MessageFormat means things that are never replaced within them +# so use 2 '' characters to make it one ' on output. This will take for the form ''{0}'' +# +ExecutableDefinitions.notExecutableType=Validatiefout ({0}) : Type definitie ''{1}'' is niet uitvoerbaar +ExecutableDefinitions.notExecutableSchema=Validatiefout ({0}) : Schema definitie is niet uitvoerbaar +ExecutableDefinitions.notExecutableDirective=Validatiefout ({0}) : Directive definitie ''{1}'' is niet uitvoerbaar +ExecutableDefinitions.notExecutableDefinition=Validatiefout ({0}) : Aangeleverde definition is niet uitvoerbaar +# +FieldsOnCorrectType.unknownField=Validatiefout ({0}) : Veld ''{1}'' in type ''{2}'' is ongedefinieerd +# +FragmentsOnCompositeType.invalidInlineTypeCondition=Validatiefout ({0}) : Inline fragment type condition is ongeldig, moet op een Object/Interface/Union zitten +FragmentsOnCompositeType.invalidFragmentTypeCondition=Validatiefout ({0}) : Fragment type condition is ongeldig, moet op een Object/Interface/Union zitten +# +KnownArgumentNames.unknownDirectiveArg=Validatiefout ({0}) : Onbekende directive argument ''{1}'' +KnownArgumentNames.unknownFieldArg=Validatiefout ({0}) : Onbekende field argument ''{1}'' +# +KnownDirectives.unknownDirective=Validatiefout ({0}) : Onbekende directive ''{1}'' +KnownDirectives.directiveNotAllowed=Validatiefout ({0}) : Directive ''{1}'' is hier niet toegestaan +# +KnownFragmentNames.undefinedFragment=Validatiefout ({0}) : Ongedefinieerd fragment ''{1}'' +# +KnownTypeNames.unknownType=Validatiefout ({0}) : Ongeldig type ''{1}'' +# +LoneAnonymousOperation.withOthers=Validatiefout ({0}) : Anonieme operation met andere operations +LoneAnonymousOperation.namedOperation=Validatiefout ({0}) : Operation ''{1}'' volgt een anonieme operatie +# +NoFragmentCycles.cyclesNotAllowed=Validatiefout ({0}) : Fragment cycles niet toegestaan +# +NoUndefinedVariables.undefinedVariable=Validatiefout ({0}) : Ongedefinieerde variabele ''{1}'' +# +NoUnusedFragments.unusedFragments=Validatiefout ({0}) : Ongebruikt fragment ''{1}'' +# +NoUnusedVariables.unusedVariable=Validatiefout ({0}) : Ongebruikte variabele ''{1}'' +# +OverlappingFieldsCanBeMerged.differentFields=Validatiefout ({0}) : ''{1}'' : ''{2}'' en ''{3}'' zijn verschillende velden +OverlappingFieldsCanBeMerged.differentArgs=Validatiefout ({0}) : ''{1}'' : velden hebben verschillende argumenten +OverlappingFieldsCanBeMerged.differentNullability=Validatiefout ({0}) : ''{1}'' : velden hebben verschillende nullability shapes +OverlappingFieldsCanBeMerged.differentLists=Validatiefout ({0}) : ''{1}'' : velden hebben verschillende vormen +OverlappingFieldsCanBeMerged.differentReturnTypes=Validatiefout ({0}) : ''{1}'' : retourneert verschillende types ''{2}'' en ''{3}'' +# +PossibleFragmentSpreads.inlineIncompatibleTypes=Validatiefout ({0}) : Fragment kan hier niet uitgespreid worden omdat een object van type ''{1}'' nooit van het type ''{2}'' kan zijn +PossibleFragmentSpreads.fragmentIncompatibleTypes=Validatiefout ({0}) : Fragment ''{1}'' kan hier niet uitgespreid worden omdat een object van type ''{2}'' nooit van het type ''{3}'' kan zijn +# +ProvidedNonNullArguments.missingFieldArg=Validatiefout ({0}) : Missend field argument ''{1}'' +ProvidedNonNullArguments.missingDirectiveArg=Validatiefout ({0}) : Missend directive argument ''{1}'' +ProvidedNonNullArguments.nullValue=Validatiefout ({0}) : Null waarde voor non-null field argument ''{1}'' +# +ScalarLeaves.subselectionOnLeaf=Validatiefout ({0}) : Sub-selectie niet toegestaan op leaf/uiteinde type ''{1}'' van veld ''{2}'' +ScalarLeaves.subselectionRequired=Validatiefout ({0}) : Sub-selectie verplicht voor type ''{1}'' van veld ''{2}'' +# +SubscriptionUniqueRootField.multipleRootFields=Validatiefout ({0}) : Subscription operation ''{1}'' moet exact één root field hebben +SubscriptionUniqueRootField.multipleRootFieldsWithFragment=Validatiefout ({0}) : Subscription operation ''{1}'' moet exact één root field met fragmenten hebben +SubscriptionIntrospectionRootField.introspectionRootField=Validatiefout ({0}) : Subscription operation ''{1}'' root field ''{2}'' kan geen introspectieveld zijn +SubscriptionIntrospectionRootField.introspectionRootFieldWithFragment=Validatiefout ({0}) : Subscription operation ''{1}'' fragment root field ''{2}'' kan geen introspectieveld zijn +# +UniqueArgumentNames.uniqueArgument=Validatiefout ({0}) : Er mag maar één argument met naam ''{1}'' bestaan +# +UniqueDirectiveNamesPerLocation.uniqueDirectives=Validatiefout ({0}) : Onherhaalbare directives moeten een unieke naam hebben binnen een locatie. De directive ''{1}'' gebruikt op een ''{2}'' is niet uniek +# +UniqueFragmentNames.oneFragment=Validatiefout ({0}) : Er mag maar één fragment met naam ''{1}'' bestaan +# +UniqueOperationNames.oneOperation=Validatiefout ({0}) : Er mag maar één operatie met naam ''{1}'' bestaan +# +UniqueVariableNames.oneVariable=Validatiefout ({0}) : Er mag maar één variabele met naam ''{1}'' bestaan +# +VariableDefaultValuesOfCorrectType.badDefault=Validatiefout ({0}) : Ongeldige standaardwaarde ''{1}'' voor type ''{2}'' +# +VariablesAreInputTypes.wrongType=Validatiefout ({0}) : Invoervariabele ''{1}'' type ''{2}'' is geen invoertype +# +VariableTypesMatchRule.unexpectedType=Validatiefout ({0}) : Variabele type ''{1}'' komt niet overeen met het verwachte type ''{2}'' +UniqueObjectFieldName.duplicateFieldName=Validatiefout ({0}) : Er kan slechts één veld genaamd ''{1}'' zijn +# +# These are used but IDEA cant find them easily as being called +# +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleNullError=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' mag niet null zijn +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleScalarError=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' is geen geldige ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleScalarErrorCustomMessage=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' is geen geldige ''{3}'' - {4} +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleEnumError=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' is geen geldige ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleEnumErrorCustomMessage=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' is geen geldige ''{3}'' - {4} +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleNotObjectError=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' moet een object type zijn +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleMissingFieldsError=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' mist een verplicht veld ''{3}'' +# suppress inspection "UnusedProperty" +ArgumentValidationUtil.handleExtraFieldError=Validatiefout ({0}) : argument ''{1}'' met waarde ''{2}'' bevat een veld niet in ''{3}'': ''{4}'' +# diff --git a/src/test/groovy/example/http/ExecutionResultJSONTesting.java b/src/test/groovy/example/http/ExecutionResultJSONTesting.java index 5075eed985..019eb17616 100644 --- a/src/test/groovy/example/http/ExecutionResultJSONTesting.java +++ b/src/test/groovy/example/http/ExecutionResultJSONTesting.java @@ -1,30 +1,30 @@ package example.http; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.google.gson.GsonBuilder; - import graphql.ExceptionWhileDataFetching; import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.GraphQLError; import graphql.InvalidSyntaxError; import graphql.SerializationError; -import graphql.execution.ExecutionPath; -import graphql.execution.ExecutionTypeInfo; +import graphql.execution.ExecutionStepInfo; import graphql.execution.MissingRootTypeException; import graphql.execution.NonNullableFieldWasNullError; import graphql.execution.NonNullableFieldWasNullException; +import graphql.execution.ResultPath; import graphql.introspection.Introspection; import graphql.language.SourceLocation; import graphql.schema.CoercingSerializeException; import graphql.validation.ValidationError; import graphql.validation.ValidationErrorType; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + import static java.util.Arrays.stream; import static java.util.stream.Collectors.toList; @@ -70,10 +70,14 @@ private void testGson(HttpServletResponse response, Object er) throws IOExceptio private ExecutionResult createER() { List errors = new ArrayList<>(); - errors.add(new ValidationError(ValidationErrorType.UnknownType, mkLocations(), "Test ValidationError")); + errors.add(ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.UnknownType) + .sourceLocations(mkLocations()) + .description("Test ValidationError") + .build()); errors.add(new MissingRootTypeException("Mutations are not supported.", null)); errors.add(new InvalidSyntaxError(mkLocations(), "Not good syntax m'kay")); - errors.add(new NonNullableFieldWasNullError(new NonNullableFieldWasNullException(mkTypeInfo(), mkPath()))); + errors.add(new NonNullableFieldWasNullError(new NonNullableFieldWasNullException(mkExecutionInfo(), mkPath()))); errors.add(new SerializationError(mkPath(), new CoercingSerializeException("Bad coercing"))); errors.add(new ExceptionWhileDataFetching(mkPath(), new RuntimeException("Bang"), mkLocation(666, 999))); @@ -88,12 +92,12 @@ private SourceLocation mkLocation(int line, int column) { return new SourceLocation(line, column); } - private ExecutionPath mkPath() { - return ExecutionPath.rootPath().segment("heroes").segment(0).segment("abilities").segment("speed").segment(4); + private ResultPath mkPath() { + return ResultPath.rootPath().segment("heroes").segment(0).segment("abilities").segment("speed").segment(4); } - private ExecutionTypeInfo mkTypeInfo() { - return ExecutionTypeInfo.newTypeInfo() + private ExecutionStepInfo mkExecutionInfo() { + return ExecutionStepInfo.newExecutionStepInfo() .type(Introspection.__Schema) .path(mkPath()) .build(); diff --git a/src/test/groovy/example/http/HttpMain.java b/src/test/groovy/example/http/HttpMain.java index 0dad6b5cbd..b823b78060 100644 --- a/src/test/groovy/example/http/HttpMain.java +++ b/src/test/groovy/example/http/HttpMain.java @@ -4,9 +4,6 @@ import graphql.ExecutionResult; import graphql.GraphQL; import graphql.StarWarsData; -import graphql.execution.instrumentation.ChainedInstrumentation; -import graphql.execution.instrumentation.Instrumentation; -import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation; import graphql.execution.instrumentation.tracing.TracingInstrumentation; import graphql.schema.DataFetcher; import graphql.schema.GraphQLObjectType; @@ -16,8 +13,12 @@ import graphql.schema.idl.SchemaGenerator; import graphql.schema.idl.SchemaParser; import graphql.schema.idl.TypeDefinitionRegistry; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.dataloader.BatchLoader; import org.dataloader.DataLoader; +import org.dataloader.DataLoaderFactory; import org.dataloader.DataLoaderRegistry; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; @@ -26,9 +27,6 @@ import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.ResourceHandler; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -41,19 +39,17 @@ import java.util.concurrent.CompletableFuture; import static graphql.ExecutionInput.newExecutionInput; -import static graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationOptions.newOptions; import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; -import static java.util.Arrays.asList; /** - * An very simple example of serving a qraphql schema over http. + * A very simple example of serving a graphql schema over http. *

    - * More info can be found here : http://graphql.org/learn/serving-over-http/ + * More info can be found here : https://graphql.org/learn/serving-over-http/ */ @SuppressWarnings("unchecked") public class HttpMain extends AbstractHandler { - static final int PORT = 3000; + static final int PORT = 8080; static GraphQLSchema starWarsSchema = null; public static void main(String[] args) throws Exception { @@ -105,19 +101,20 @@ private void handleStarWars(HttpServletRequest httpRequest, HttpServletResponse return; } - ExecutionInput.Builder executionInput = newExecutionInput() - .query(parameters.getQuery()) - .operationName(parameters.getOperationName()) - .variables(parameters.getVariables()); - // // This example uses the DataLoader technique to ensure that the most efficient - // loading of data (in this case StarWars characters) happens. We pass that to data - // fetchers via the graphql context object. + // loading of data (in this case StarWars characters) happens. // DataLoaderRegistry dataLoaderRegistry = buildDataLoaderRegistry(); + ExecutionInput.Builder executionInput = newExecutionInput() + .query(parameters.getQuery()) + .operationName(parameters.getOperationName()) + .variables(parameters.getVariables()) + .dataLoaderRegistry(dataLoaderRegistry); + + // // the context object is something that means something to down stream code. It is instructions // from yourself to your other code such as DataFetchers. The engine passes this on unchanged and @@ -132,33 +129,28 @@ private void handleStarWars(HttpServletRequest httpRequest, HttpServletResponse Map context = new HashMap<>(); context.put("YouAppSecurityClearanceLevel", "CodeRed"); context.put("YouAppExecutingUser", "Dr Nefarious"); - context.put("dataloaderRegistry", dataLoaderRegistry); - executionInput.context(context); + executionInput.graphQLContext(context); // // you need a schema in order to execute queries GraphQLSchema schema = buildStarWarsSchema(); - DataLoaderDispatcherInstrumentation dlInstrumentation = - new DataLoaderDispatcherInstrumentation(dataLoaderRegistry, newOptions().includeStatistics(true)); - - Instrumentation instrumentation = new ChainedInstrumentation( - asList(new TracingInstrumentation(), dlInstrumentation) - ); - // finally you build a runtime graphql object and execute the query GraphQL graphQL = GraphQL .newGraphQL(schema) - // instrumentation is pluggable - .instrumentation(instrumentation) + .instrumentation(new TracingInstrumentation()) .build(); - ExecutionResult executionResult = graphQL.execute(executionInput.build()); + ExecutionResult executionResult = graphQL.execute(executionInput); returnAsJson(httpResponse, executionResult); } private void returnAsJson(HttpServletResponse response, ExecutionResult executionResult) throws IOException { + sendNormalResponse(response, executionResult); + } + + private void sendNormalResponse(HttpServletResponse response, ExecutionResult executionResult) throws IOException { response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); JsonKit.toJson(response, executionResult.toSpecification()); @@ -174,7 +166,7 @@ private DataLoaderRegistry buildDataLoaderRegistry() { CompletableFuture.supplyAsync(() -> loadCharactersViaHTTP(keys)); - DataLoader friendsDataLoader = new DataLoader<>(friendsBatchLoader); + DataLoader friendsDataLoader = DataLoaderFactory.newDataLoader(friendsBatchLoader); DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); // @@ -201,8 +193,7 @@ private GraphQLSchema buildStarWarsSchema() { // more efficient by batching and caching the calls to load Character friends // DataFetcher friendsFetcher = environment -> { - DataLoaderRegistry dataloaderRegistry = asMapGet(environment.getContext(), "dataloaderRegistry"); - DataLoader friendsDataLoader = dataloaderRegistry.getDataLoader("friends"); + DataLoader friendsDataLoader = environment.getDataLoader("friends"); List friendIds = asMapGet(environment.getSource(), "friends"); return friendsDataLoader.loadMany(friendIds); @@ -220,7 +211,7 @@ private GraphQLSchema buildStarWarsSchema() { // logical schema // TypeResolver characterTypeResolver = env -> { - Map obj = (Map) env.getObject(); + Map obj = env.getObject(); String id = (String) obj.get("id"); GraphQLSchema schema = env.getSchema(); if (StarWarsData.isHuman(id)) { @@ -272,7 +263,7 @@ private Reader loadSchemaFile(String name) { } // Lots of the data happens to be maps of objects and this allows us to get back into type safety land - // with less boiler plat and casts + // with less boilerplate and casts // @SuppressWarnings("TypeParameterUnusedInFormals") private T asMapGet(Object mapObj, Object mapKey) { diff --git a/src/test/groovy/example/http/JsonKit.java b/src/test/groovy/example/http/JsonKit.java index 7d30ac92d2..822aaa425d 100644 --- a/src/test/groovy/example/http/JsonKit.java +++ b/src/test/groovy/example/http/JsonKit.java @@ -3,8 +3,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; +import jakarta.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collections; import java.util.Map; diff --git a/src/test/groovy/example/http/QueryParameters.java b/src/test/groovy/example/http/QueryParameters.java index 1c9c309a70..7855e9d316 100644 --- a/src/test/groovy/example/http/QueryParameters.java +++ b/src/test/groovy/example/http/QueryParameters.java @@ -1,6 +1,6 @@ package example.http; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.util.Collections; @@ -10,15 +10,15 @@ /** * Graphql clients can send GET or POST HTTP requests. The spec does not make an explicit * distinction. So you may need to handle both. The following was tested using - * a graphiql client tool found here : https://github.com/skevy/graphiql-app - * + * a graphiql client tool found here : graphiql-app + *

    * You should consider bundling graphiql in your application - * - * https://github.com/graphql/graphiql - * + *

    + * https://github.com/graphql/graphiql + *

    * This outlines more information on how to handle parameters over http - * - * http://graphql.org/learn/serving-over-http/ + *

    + * https://graphql.org/learn/serving-over-http/ */ class QueryParameters { diff --git a/src/test/groovy/example/http/package-info.java b/src/test/groovy/example/http/package-info.java index ddd7321e52..bea88ed753 100644 --- a/src/test/groovy/example/http/package-info.java +++ b/src/test/groovy/example/http/package-info.java @@ -1,11 +1,11 @@ /** * The purpose of this code is to show an example of serving a graphql query over HTTP - * - * More info can be found here : http://graphql.org/learn/serving-over-http/ - * + *

    + * More info can be found here : https://graphql.org/learn/serving-over-http/ + *

    * There are more concerns in a fully fledged application such as your approach to permissions * and authentication and so on that are not shown here. - * + *

    * The backing data is the "star wars" example schema. And fairly complex example query is as follows : * *

    @@ -29,6 +29,6 @@
      * }
      *
      * }
    - * 
    { + * */ package example.http; \ No newline at end of file diff --git a/src/test/groovy/graphql/AlwaysFailsTest.groovy b/src/test/groovy/graphql/AlwaysFailsTest.groovy new file mode 100644 index 0000000000..8136ff4f77 --- /dev/null +++ b/src/test/groovy/graphql/AlwaysFailsTest.groovy @@ -0,0 +1,27 @@ +package graphql + +import spock.lang.Ignore +import spock.lang.Specification + +/** + * This is only really useful for testing the gradle builds etc... + * and in general would not be needed to test graphql-java + */ +@Ignore +class AlwaysFailsTest extends Specification{ + + def "this test fails"() { + when: + true + then: + assert false + } + + def "and this test always fails"() { + when: + true + then: + assert false + } + +} diff --git a/src/test/groovy/graphql/AssertTest.groovy b/src/test/groovy/graphql/AssertTest.groovy index 94e87bd9eb..fe6d818f1f 100644 --- a/src/test/groovy/graphql/AssertTest.groovy +++ b/src/test/groovy/graphql/AssertTest.groovy @@ -2,34 +2,45 @@ package graphql import spock.lang.Specification +import static graphql.Assert.* + class AssertTest extends Specification { - def "assertNull should not throw on none null value"() { + def "assertNotNull should not throw on none null value"() { when: - Assert.assertNotNull("some object") + assertNotNull("some object") then: noExceptionThrown() } - def "assertNull should throw on null value"() { + def "assertNotNull should throw on null value"() { when: - Assert.assertNotNull(null) + assertNotNull(null) then: thrown(AssertException) } - def "assertNull with error message should not throw on none null value"() { + def "assertNotNull constant message should throw on null value"() { + when: + assertNotNull(null, "constant message") + + then: + def error = thrown(AssertException) + error.message == "constant message" + } + + def "assertNotNull with error message should not throw on none null value"() { when: - Assert.assertNotNull("some object", "error message") + assertNotNull("some object", { -> "error message" }) then: noExceptionThrown() } - def "assertNull with error message should throw on null value with formatted message"() { + def "assertNotNull with error message should throw on null value with formatted message"() { when: - Assert.assertNotNull(value, format, arg) + assertNotNull(value, { -> String.format(format, arg) }) then: def error = thrown(AssertException) @@ -42,9 +53,38 @@ class AssertTest extends Specification { null | "code" | null || "code" } + def "assertNotNull with different number of error args throws assertions"() { + when: + toRun.run() + + then: + def error = thrown(AssertException) + error.message == expectedMessage + + where: + toRun | expectedMessage + runnable({ assertNotNull(null, "error %s", "arg1") }) | "error arg1" + runnable({ assertNotNull(null, "error %s %s", "arg1", "arg2") }) | "error arg1 arg2" + runnable({ assertNotNull(null, "error %s %s %s", "arg1", "arg2", "arg3") }) | "error arg1 arg2 arg3" + } + + def "assertNotNull with different number of error args with non null does not throw assertions"() { + when: + toRun.run() + + then: + noExceptionThrown() + + where: + toRun | expectedMessage + runnable({ assertNotNull("x", "error %s", "arg1") }) | "error arg1" + runnable({ assertNotNull("x", "error %s %s", "arg1", "arg2") }) | "error arg1 arg2" + runnable({ assertNotNull("x", "error %s %s %s", "arg1", "arg2", "arg3") }) | "error arg1 arg2 arg3" + } + def "assertNeverCalled should always throw"() { when: - Assert.assertNeverCalled() + assertNeverCalled() then: def e = thrown(AssertException) @@ -53,7 +93,7 @@ class AssertTest extends Specification { def "assertShouldNeverHappen should always throw"() { when: - Assert.assertShouldNeverHappen() + assertShouldNeverHappen() then: def e = thrown(AssertException) @@ -62,7 +102,7 @@ class AssertTest extends Specification { def "assertShouldNeverHappen should always throw with formatted message"() { when: - Assert.assertShouldNeverHappen(format, arg) + assertShouldNeverHappen(format, arg) then: def error = thrown(AssertException) @@ -77,7 +117,7 @@ class AssertTest extends Specification { def "assertNotEmpty collection should throw on null or empty"() { when: - Assert.assertNotEmpty(value, format, arg) + assertNotEmpty(value, { -> String.format(format, arg) }) then: def error = thrown(AssertException) @@ -91,7 +131,7 @@ class AssertTest extends Specification { def "assertNotEmpty should not throw on none empty collection"() { when: - Assert.assertNotEmpty(["some object"], "error message") + assertNotEmpty(["some object"], { -> "error message" }) then: noExceptionThrown() @@ -99,7 +139,7 @@ class AssertTest extends Specification { def "assertTrue should not throw on true value"() { when: - Assert.assertTrue(true, "error message") + assertTrue(true, { -> "error message" }) then: noExceptionThrown() @@ -107,7 +147,77 @@ class AssertTest extends Specification { def "assertTrue with error message should throw on false value with formatted message"() { when: - Assert.assertTrue(false, format, arg) + assertTrue(false, { -> String.format(format, arg) }) + + then: + def error = thrown(AssertException) + error.message == expectedMessage + + where: + format | arg || expectedMessage + "error %s" | "msg" || "error msg" + "code %d" | 1 || "code 1" + "code" | null || "code" + } + + def "assertTrue constant message should throw with message"() { + when: + assertTrue(false, "constant message") + + then: + def error = thrown(AssertException) + error.message == "constant message" + } + + def "assertTrue with different number of error args throws assertions"() { + when: + toRun.run() + + then: + def error = thrown(AssertException) + error.message == expectedMessage + + where: + toRun | expectedMessage + runnable({ assertTrue(false, "error %s", "arg1") }) | "error arg1" + runnable({ assertTrue(false, "error %s %s", "arg1", "arg2") }) | "error arg1 arg2" + runnable({ assertTrue(false, "error %s %s %s", "arg1", "arg2", "arg3") }) | "error arg1 arg2 arg3" + } + + def "assertTrue with different number of error args but false does not throw assertions"() { + when: + toRun.run() + + then: + noExceptionThrown() + + where: + toRun | expectedMessage + runnable({ assertTrue(true, "error %s", "arg1") }) | "error arg1" + runnable({ assertTrue(true, "error %s %s", "arg1", "arg2") }) | "error arg1 arg2" + runnable({ assertTrue(true, "error %s %s %s", "arg1", "arg2", "arg3") }) | "error arg1 arg2 arg3" + } + + def "assertFalse should throw"() { + when: + assertFalse(true) + + then: + thrown(AssertException) + } + + def "assertFalse constant message should throw with message"() { + when: + assertFalse(true, "constant message") + + then: + def error = thrown(AssertException) + error.message == "constant message" + } + + def "assertFalse with error message should throw on false value with formatted message"() { + when: + assertFalse(true, { -> String.format(format, arg) }) then: def error = thrown(AssertException) @@ -120,9 +230,38 @@ class AssertTest extends Specification { "code" | null || "code" } + def "assertFalse with different number of error args throws assertions"() { + when: + toRun.run() + + then: + def error = thrown(AssertException) + error.message == expectedMessage + + where: + toRun | expectedMessage + runnable({ assertFalse(true, "error %s", "arg1") }) | "error arg1" + runnable({ assertFalse(true, "error %s %s", "arg1", "arg2") }) | "error arg1 arg2" + runnable({ assertFalse(true, "error %s %s %s", "arg1", "arg2", "arg3") }) | "error arg1 arg2 arg3" + } + + def "assertFalse with different number of error args but false does not throw assertions"() { + when: + toRun.run() + + then: + noExceptionThrown() + + where: + toRun | expectedMessage + runnable({ assertFalse(false, "error %s", "arg1") }) | "error arg1" + runnable({ assertFalse(false, "error %s %s", "arg1", "arg2") }) | "error arg1 arg2" + runnable({ assertFalse(false, "error %s %s %s", "arg1", "arg2", "arg3") }) | "error arg1 arg2 arg3" + } + def "assertValidName should not throw on valid names"() { when: - Assert.assertValidName(name) + assertValidName(name) then: noExceptionThrown() @@ -138,7 +277,7 @@ class AssertTest extends Specification { def "assertValidName should throw on invalid names"() { when: - Assert.assertValidName(name) + assertValidName(name) then: def error = thrown(AssertException) @@ -147,7 +286,13 @@ class AssertTest extends Specification { where: name | _ "0abc" | _ - "" | _ + "���" | _ "_()" | _ } + + // Spock data tables cant cope with { x } syntax but it cna do this + Runnable runnable(Runnable r) { + return r + } + } diff --git a/src/test/groovy/graphql/ChainedDataLoaderTest.groovy b/src/test/groovy/graphql/ChainedDataLoaderTest.groovy new file mode 100644 index 0000000000..98986b32c2 --- /dev/null +++ b/src/test/groovy/graphql/ChainedDataLoaderTest.groovy @@ -0,0 +1,508 @@ +package graphql + +import graphql.schema.DataFetcher +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import spock.lang.RepeatUntilFailure +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.concurrent.ExecutionException +import java.util.concurrent.atomic.AtomicInteger + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.setEnableDataLoaderChaining +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.setEnableDataLoaderExhaustedDispatching +import static java.util.concurrent.CompletableFuture.supplyAsync + +class ChainedDataLoaderTest extends Specification { + + + @Unroll + def "chained data loaders"() { + given: + def sdl = ''' + + type Query { + dogName: String + catName: String + } + ''' + int batchLoadCalls = 0 + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls++ + Thread.sleep(250) + println "BatchLoader called with keys: $keys" + assert keys.size() == 2 + return ["Luna", "Tiger"] + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader); + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("name", nameDataLoader); + + def df1 = { env -> + return env.getDataLoader("name").load("Key1").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } as DataFetcher + + def df2 = { env -> + return env.getDataLoader("name").load("Key2").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } as DataFetcher + + + def fetchers = ["Query": ["dogName": df1, "catName": df2]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ dogName catName } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).build() + chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei.graphQLContext, true) : setEnableDataLoaderExhaustedDispatching(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + then: + er.data == [dogName: "Luna", catName: "Tiger"] + batchLoadCalls == 2 + + where: + chainedDataLoaderOrExhaustedDispatcher << [true, false] + } + + @Unroll + @RepeatUntilFailure(maxAttempts = 20, ignoreRest = false) + def "parallel different data loaders"() { + given: + def sdl = ''' + + type Query { + hello: String + helloDelayed: String + } + ''' + AtomicInteger batchLoadCalls = new AtomicInteger() + BatchLoader batchLoader1 = { keys -> + println "BatchLoader 1 called with keys: $keys ${Thread.currentThread().name}" + batchLoadCalls.incrementAndGet() + return supplyAsync { + Thread.sleep(250) + assert keys.size() == 1 + return ["Luna" + keys[0]] + } + } + + BatchLoader batchLoader2 = { keys -> + println "BatchLoader 2 called with keys: $keys ${Thread.currentThread().name}" + batchLoadCalls.incrementAndGet() + return supplyAsync { + Thread.sleep(250) + assert keys.size() == 1 + return ["Skipper" + keys[0]] + } + } + BatchLoader batchLoader3 = { keys -> + println "BatchLoader 3 called with keys: $keys ${Thread.currentThread().name}" + batchLoadCalls.incrementAndGet() + return supplyAsync { + Thread.sleep(250) + assert keys.size() == 1 + return ["friends" + keys[0]] + } + } + + + DataLoader dl1 = DataLoaderFactory.newDataLoader(batchLoader1); + DataLoader dl2 = DataLoaderFactory.newDataLoader(batchLoader2); + DataLoader dl3 = DataLoaderFactory.newDataLoader(batchLoader3); + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("dl1", dl1); + dataLoaderRegistry.register("dl2", dl2); + dataLoaderRegistry.register("dl3", dl3); + + def df = { env -> + def cf1 = env.getDataLoader("dl1").load("key1") + def cf2 = env.getDataLoader("dl2").load("key2") + return cf1.thenCombine(cf2, { result1, result2 -> + return result1 + result2 + }).thenCompose { + return env.getDataLoader("dl3").load(it) + } + } as DataFetcher + + def dfDelayed = { env -> + return supplyAsync { + Thread.sleep(2000) + }.thenCompose { + def cf1 = env.getDataLoader("dl1").load("key1-delayed") + def cf2 = env.getDataLoader("dl2").load("key2-delayed") + return cf1.thenCombine(cf2, { result1, result2 -> + return result1 + result2 + }).thenCompose { + return env.getDataLoader("dl3").load(it) + } + } + } as DataFetcher + + + def fetchers = [Query: [hello: df, helloDelayed: dfDelayed]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello helloDelayed} " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).build() + chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei.graphQLContext, true) : setEnableDataLoaderExhaustedDispatching(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + then: + er.data == [hello: "friendsLunakey1Skipperkey2", helloDelayed: "friendsLunakey1-delayedSkipperkey2-delayed"] + batchLoadCalls.get() == 6 + + where: + chainedDataLoaderOrExhaustedDispatcher << [true, false] + + + } + + + @Unroll + def "more complicated chained data loader for one DF"() { + given: + def sdl = ''' + + type Query { + foo: String + } + ''' + int batchLoadCalls1 = 0 + BatchLoader batchLoader1 = { keys -> + return supplyAsync { + batchLoadCalls1++ + Thread.sleep(250) + println "BatchLoader1 called with keys: $keys" + return keys.collect { String key -> + key + "-batchloader1" + } + } + } + int batchLoadCalls2 = 0 + BatchLoader batchLoader2 = { keys -> + return supplyAsync { + batchLoadCalls2++ + Thread.sleep(250) + println "BatchLoader2 called with keys: $keys" + return keys.collect { String key -> + key + "-batchloader2" + } + } + } + + + DataLoader dl1 = DataLoaderFactory.newDataLoader(batchLoader1); + DataLoader dl2 = DataLoaderFactory.newDataLoader(batchLoader2); + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("dl1", dl1); + dataLoaderRegistry.register("dl2", dl2); + + def df = { env -> + return env.getDataLoader("dl1").load("start").thenCompose { + firstDLResult -> + + def otherCF1 = supplyAsync { + Thread.sleep(1000) + return "otherCF1" + } + def otherCF2 = supplyAsync { + Thread.sleep(1000) + return "otherCF2" + } + + def secondDL = env.getDataLoader("dl2").load(firstDLResult).thenApply { + secondDLResult -> + return secondDLResult + "-apply" + } + return otherCF1.thenCompose { + otherCF1Result -> + otherCF2.thenCompose { + otherCF2Result -> + secondDL.thenApply { + secondDLResult -> + return firstDLResult + "-" + otherCF1Result + "-" + otherCF2Result + "-" + secondDLResult + } + } + } + + } + } as DataFetcher + + + def fetchers = ["Query": ["foo": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ foo } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).build() + chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei.graphQLContext, true) : setEnableDataLoaderExhaustedDispatching(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + then: + er.data == [foo: "start-batchloader1-otherCF1-otherCF2-start-batchloader1-batchloader2-apply"] + batchLoadCalls1 == 1 + batchLoadCalls2 == 1 + where: + chainedDataLoaderOrExhaustedDispatcher << [true, false] + + } + + + @Unroll + def "chained data loaders with an delayed data loader"() { + given: + def sdl = ''' + + type Query { + dogName: String + catName: String + } + ''' + int batchLoadCalls = 0 + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls++ + Thread.sleep(250) + println "BatchLoader called with keys: $keys" + return keys.collect { String key -> + key.substring(0, key.length() - 1) + (Integer.parseInt(key.substring(key.length() - 1, key.length())) + 1) + } + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader); + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("name", nameDataLoader); + + def df1 = { env -> + return env.getDataLoader("name").load("Luna0").thenCompose { + result -> + { + return supplyAsync { + Thread.sleep(1000) + return "foo" + }.thenCompose { + return env.getDataLoader("name").load(result) + } + } + } + } as DataFetcher + + def df2 = { env -> + return env.getDataLoader("name").load("Tiger0").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } as DataFetcher + + + def fetchers = ["Query": ["dogName": df1, "catName": df2]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ dogName catName } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).build() + chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei.graphQLContext, true) : setEnableDataLoaderExhaustedDispatching(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + then: + er.data == [dogName: "Luna2", catName: "Tiger2"] + batchLoadCalls == 3 + where: + chainedDataLoaderOrExhaustedDispatcher << [true, false] + + } + + @Unroll + def "chained data loaders with two delayed data loaders"() { + given: + def sdl = ''' + + type Query { + foo: String + bar: String + } + ''' + AtomicInteger batchLoadCalls = new AtomicInteger() + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls.incrementAndGet() + Thread.sleep(250) + println "BatchLoader called with keys: $keys" + return keys; + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader); + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("dl", nameDataLoader); + + def fooDF = { env -> + return supplyAsync { + Thread.sleep(1000) + return "fooFirstValue" + }.thenCompose { + return env.getDataLoader("dl").load(it) + } + } as DataFetcher + + def barDF = { env -> + return supplyAsync { + Thread.sleep(1000) + return "barFirstValue" + }.thenCompose { + return env.getDataLoader("dl").load(it) + } + } as DataFetcher + + + def fetchers = ["Query": ["foo": fooDF, "bar": barDF]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ foo bar } " + + def eiBuilder = ExecutionInput.newExecutionInput(query) + def ei = eiBuilder.dataLoaderRegistry(dataLoaderRegistry).build() + chainedDataLoaderOrExhaustedDispatcher ? setEnableDataLoaderChaining(ei.graphQLContext, true) : setEnableDataLoaderExhaustedDispatching(ei.graphQLContext, true) + + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + then: + er.data == [foo: "fooFirstValue", bar: "barFirstValue"] + batchLoadCalls.get() == 1 || batchLoadCalls.get() == 2 // depending on timing, it can be 1 or 2 calls + + where: + chainedDataLoaderOrExhaustedDispatcher << [true, false] + + } + + def "handling of chained DataLoaders is disabled by default"() { + given: + def sdl = ''' + + type Query { + dogName: String + catName: String + } + ''' + int batchLoadCalls = 0 + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls++ + println "BatchLoader called with keys: $keys" + assert keys.size() == 2 + return ["Luna", "Tiger"] + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader); + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("name", nameDataLoader); + + def df1 = { env -> + return env.getDataLoader("name").load("Key1").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } as DataFetcher + + def df2 = { env -> + return env.getDataLoader("name").load("Key2").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } as DataFetcher + + + def fetchers = ["Query": ["dogName": df1, "catName": df2]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ dogName catName } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).build() + + + when: + def er = graphQL.executeAsync(ei) + Thread.sleep(1000) + then: + batchLoadCalls == 1 + !er.isDone() + } + + + def "setting chained and exhausted at the same time caused error"() { + given: + def sdl = ''' + + type Query { + echo:String + } + ''' + def schema = TestUtil.schema(sdl, [:]) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{echo} " + def ei = newExecutionInput(query).dataLoaderRegistry(new DataLoaderRegistry()).build() + setEnableDataLoaderChaining(ei.graphQLContext, true) + setEnableDataLoaderExhaustedDispatching(ei.graphQLContext, true) + + + when: + def er = graphQL.executeAsync(ei) + er.get() + + then: + def e = thrown(ExecutionException) + e.getCause().getMessage() == "enabling data loader chaining and exhausted dispatching at the same time ambiguous" + } + + +} diff --git a/src/test/groovy/graphql/ContextPassingDataFetcher.groovy b/src/test/groovy/graphql/ContextPassingDataFetcher.groovy new file mode 100644 index 0000000000..4b667bf765 --- /dev/null +++ b/src/test/groovy/graphql/ContextPassingDataFetcher.groovy @@ -0,0 +1,40 @@ +package graphql + +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment + +import static graphql.execution.DataFetcherResult.newResult + +/** + * A data fetcher that expects a numeric local context and adds one to it. It demonstrates using local context + */ +class ContextPassingDataFetcher implements DataFetcher { + def skip + + ContextPassingDataFetcher() { + this.skip = false + } + + ContextPassingDataFetcher(boolean skip) { + this.skip = skip + } + + @Override + Object get(DataFetchingEnvironment env) throws Exception { + String data = env.getSource() + + Integer localCtx = env.getLocalContext() + if (localCtx == null) { + localCtx = env.getGraphQlContext().get("key") + } + + def newData = data + localCtx + "," + def newCtx = localCtx + 1 + if (skip) { + // when null is returned than the previous field context is passed + // onto the next data fetcher + newCtx = null + } + newResult().data(newData).localContext(newCtx).build() + } +} diff --git a/src/test/groovy/graphql/CustomMapImplementationTest.groovy b/src/test/groovy/graphql/CustomMapImplementationTest.groovy new file mode 100644 index 0000000000..7287b8c19c --- /dev/null +++ b/src/test/groovy/graphql/CustomMapImplementationTest.groovy @@ -0,0 +1,69 @@ +package graphql + +import graphql.execution.ResponseMapFactory +import graphql.schema.idl.RuntimeWiring +import groovy.transform.Immutable +import spock.lang.Specification + +class CustomMapImplementationTest extends Specification { + + @Immutable + static class Person { + String name + @SuppressWarnings('unused') // used by graphql-java + int age + } + + class CustomResponseMapFactory implements ResponseMapFactory { + + @Override + Map createInsertionOrdered(List keys, List values) { + return Collections.unmodifiableMap(DEFAULT.createInsertionOrdered(keys, values)) + } + } + + def graphql = TestUtil.graphQL(""" + type Query { + people: [Person!]! + } + + type Person { + name: String! + age: Int! + } + + """, + RuntimeWiring.newRuntimeWiring() + .type("Query", { + it.dataFetcher("people", { List.of(new Person("Mario", 18), new Person("Luigi", 21))}) + }) + .build()) + .build() + + def "customMapImplementation"() { + when: + def input = ExecutionInput.newExecutionInput() + .query(''' + query { + people { + name + age + } + } + ''') + .graphQLContext { it -> GraphQL.unusualConfiguration(it).responseMapFactory().setFactory(new CustomResponseMapFactory())} + .build() + + def executionResult = graphql.execute(input) + + then: + executionResult.errors.isEmpty() + executionResult.data == [ people: [ + [name: "Mario", age: 18], + [name: "Luigi", age: 21], + ]] + executionResult.data.getClass().getSimpleName() == 'UnmodifiableMap' + executionResult.data['people'].each { it -> it.getClass().getSimpleName() == 'UnmodifiableMap' } + } + +} diff --git a/src/test/groovy/graphql/DataFetcherTest.groovy b/src/test/groovy/graphql/DataFetcherTest.groovy index 787767224f..2f57c41efd 100644 --- a/src/test/groovy/graphql/DataFetcherTest.groovy +++ b/src/test/groovy/graphql/DataFetcherTest.groovy @@ -1,13 +1,15 @@ package graphql -import graphql.execution.ExecutionContext + +import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLOutputType import graphql.schema.PropertyDataFetcher +import graphql.schema.SingletonPropertyDataFetcher import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean import static graphql.Scalars.GraphQLString -import static graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment +import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment class DataFetcherTest extends Specification { @@ -55,43 +57,95 @@ class DataFetcherTest extends Specification { } - def env(GraphQLOutputType type) { - newDataFetchingEnvironment().source(dataHolder).executionContext(Mock(ExecutionContext)).fieldType(type).build() + def env(String propertyName, GraphQLOutputType type) { + GraphQLFieldDefinition fieldDefinition = mkField(propertyName, type) + newDataFetchingEnvironment().source(dataHolder).fieldType(type).fieldDefinition(fieldDefinition).build() + } + + def mkField(String propertyName, GraphQLOutputType type) { + GraphQLFieldDefinition.newFieldDefinition().name(propertyName).type(type).build() } def "get property value"() { given: - def environment = env(GraphQLString) + def environment = env("property", GraphQLString) + def field = mkField("property", GraphQLString) + when: + def result = fetcher.get(environment) + then: + result == "propertyValue" + when: - def result = new PropertyDataFetcher("property").get(environment) + result = fetcher.get(field, dataHolder, { environment }) then: result == "propertyValue" + + where: + fetcher | _ + new PropertyDataFetcher("property") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "get Boolean property value"() { given: - def environment = env(GraphQLBoolean) + def environment = env("booleanField", GraphQLBoolean) + def field = mkField("booleanField", GraphQLBoolean) + + when: + def result = fetcher.get(environment) + then: + result == true + when: - def result = new PropertyDataFetcher("booleanField").get(environment) + result = fetcher.get(field, dataHolder, { environment }) then: result == true + + where: + fetcher | _ + new PropertyDataFetcher("booleanField") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "get Boolean property value with get"() { given: - def environment = env(GraphQLBoolean) + def environment = env("booleanFieldWithGet", GraphQLBoolean) + def field = mkField("booleanFieldWithGet", GraphQLBoolean) + when: - def result = new PropertyDataFetcher("booleanFieldWithGet").get(environment) + def result = fetcher.get(environment) then: result == false + + when: + result = fetcher.get(field, dataHolder, { environment }) + then: + result == false + + where: + fetcher | _ + new PropertyDataFetcher("booleanFieldWithGet") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "get public field value as property"() { given: - def environment = env(GraphQLString) + def environment = env("publicField", GraphQLString) + def field = mkField("publicField", GraphQLString) + + when: + def result = fetcher.get(environment) + then: + result == "publicValue" + when: - def result = new PropertyDataFetcher("publicField").get(environment) + result = fetcher.get(field, dataHolder, { environment }) then: result == "publicValue" + + where: + fetcher | _ + new PropertyDataFetcher("publicField") | _ + SingletonPropertyDataFetcher.singleton() | _ } } diff --git a/src/test/groovy/graphql/DataFetcherWithErrorsAndDataTest.groovy b/src/test/groovy/graphql/DataFetcherWithErrorsAndDataTest.groovy index 96b173d58f..2d5e8efa02 100644 --- a/src/test/groovy/graphql/DataFetcherWithErrorsAndDataTest.groovy +++ b/src/test/groovy/graphql/DataFetcherWithErrorsAndDataTest.groovy @@ -2,24 +2,27 @@ package graphql import graphql.execution.AsyncExecutionStrategy import graphql.execution.AsyncSerialExecutionStrategy -import graphql.execution.DataFetcherResult -import graphql.execution.ExecutorServiceExecutionStrategy import graphql.language.SourceLocation +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLOutputType import graphql.schema.GraphQLSchema +import graphql.schema.idl.RuntimeWiring import spock.lang.Specification import spock.lang.Unroll -import java.util.concurrent.CompletableFuture - +import static graphql.ExecutionInput.newExecutionInput +import static graphql.GraphqlErrorBuilder.newError import static graphql.Scalars.GraphQLString +import static graphql.execution.DataFetcherResult.newResult import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLObjectType.newObject import static graphql.schema.GraphQLSchema.newSchema -import static java.util.concurrent.ForkJoinPool.commonPool /** - * A set of tests to show how a data fetcher can return errors and data + * A set of tests to show how a data fetcher can return errors and data and field context */ @SuppressWarnings("GroovyUnusedDeclaration") class DataFetcherWithErrorsAndDataTest extends Specification { @@ -33,49 +36,92 @@ class DataFetcherWithErrorsAndDataTest extends Specification { ChildObject child = new ChildObject() } - def executionInput(String query) { - ExecutionInput.newExecutionInput().query(query).build() + static def executionInput(String query) { + newExecutionInput().query(query).build() + } + + class ParentDataFetcher implements DataFetcher { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return newResult() + .data(new ParentObject()) + .errors([newError() + .message("badField is bad") + .path(["root", "parent", "child", "badField"]) + .location(environment.getField().getSourceLocation()) + .build()]) + .build() + } + } + + class ChildDataFetcher implements DataFetcher { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return newResult() + .data(["goodField": null, "badField": null]) + .errors([newError() + .message("goodField is bad") + .path(["root", "parent", "child", "goodField"]) + .location(environment.getField().getSourceLocation()) + .build(), + newError().message("badField is bad") + .path(["root", "parent", "child", "badField"]) + .location(environment.getField().getSourceLocation()) + .build()]) + .build() + } } @Unroll def "#820 - data fetcher can return data and errors (strategy: #strategyName)"() { - // see https://github.com/graphql-java/graphql-java/issues/820 given: - + def queryTypeName = "QueryType" + def rootFieldName = "root" + def rootTypeName = "rootType" + def parentFieldName = "parent" GraphQLOutputType childType = newObject() .name("childType") - .field(newFieldDefinition().name("goodField") - .type(GraphQLString)) - .field(newFieldDefinition().name("badField") - .type(GraphQLString)) + .field(newFieldDefinition() + .name("goodField") + .type(GraphQLString)) + .field(newFieldDefinition() + .name("badField") + .type(GraphQLString)) .build() GraphQLOutputType parentType = newObject() .name("parentType") - .field(newFieldDefinition().name("child") - .type(childType)) + .field(newFieldDefinition() + .name("child") + .type(childType)) .build() GraphQLOutputType rootType = newObject() - .name("rootType") - .field(newFieldDefinition().name("parent") - .type(parentType) - .dataFetcher({ env -> - new DataFetcherResult(new ParentObject(), - [new DataFetchingErrorGraphQLError("badField is bad", ["child", "badField"])]) - })) + .name(rootTypeName) + .field(newFieldDefinition() + .name(parentFieldName) + .type(parentType)) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field(newFieldDefinition() - .name("root") - .type(rootType) - .dataFetcher({ env -> [:] }) + def rootTypeCoordinates = FieldCoordinates.coordinates(queryTypeName, rootFieldName) + def parentTypeCoordinates = FieldCoordinates.coordinates(rootTypeName, parentFieldName) + DataFetcher rootTypeDataFetcher = { env -> [:] } + DataFetcher parentTypeDataFetcher = new ParentDataFetcher() - )) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(rootTypeCoordinates, rootTypeDataFetcher) + .dataFetcher(parentTypeCoordinates, parentTypeDataFetcher) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryTypeName) + .field(newFieldDefinition() + .name(rootFieldName) + .type(rootType) + )) .build() def query = """ @@ -102,7 +148,7 @@ class DataFetcherWithErrorsAndDataTest extends Specification { result.errors.size() == 1 result.errors[0].path == ["root", "parent", "child", "badField"] result.errors[0].message == "badField is bad" - result.errors[0].locations == [new SourceLocation(6, 27)] + result.errors[0].locations == [new SourceLocation(4, 17)] result.data["root"]["parent"]["child"]["goodField"] == "good" result.data["root"]["parent"]["child"]["badField"] == null @@ -110,53 +156,60 @@ class DataFetcherWithErrorsAndDataTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() } @Unroll def "#820 - data fetcher can return multiple errors (strategy: #strategyName)"() { - // see https://github.com/graphql-java/graphql-java/issues/820 given: - + def queryTypeName = "QueryType" + def rootFieldName = "root" + def parentTypeName = "parentType" + def childFieldName = "child" GraphQLOutputType childType = newObject() .name("childType") - .field(newFieldDefinition().name("goodField") - .type(GraphQLString)) - .field(newFieldDefinition().name("badField") - .type(GraphQLString)) + .field(newFieldDefinition() + .name("goodField") + .type(GraphQLString)) + .field(newFieldDefinition() + .name("badField") + .type(GraphQLString)) .build() GraphQLOutputType parentType = newObject() - .name("parentType") - .field(newFieldDefinition().name("child") - .type(childType) - .dataFetcher({ env -> - new DataFetcherResult( - ["goodField": null, "badField": null], [ - new DataFetchingErrorGraphQLError("goodField is bad", ["goodField"]), - new DataFetchingErrorGraphQLError("badField is bad", ["badField"]) - ]) - })) + .name(parentTypeName) + .field(newFieldDefinition() + .name(childFieldName) + .type(childType)) .build() GraphQLOutputType rootType = newObject() .name("rootType") - .field(newFieldDefinition().name("parent") - .type(parentType)) + .field(newFieldDefinition() + .name("parent") + .type(parentType)) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field(newFieldDefinition() - .name("root") - .type(rootType) - .dataFetcher({ env -> ["parent": [:]] }) + def rootTypeCoordinates = FieldCoordinates.coordinates(queryTypeName, rootFieldName) + def childTypeCoordinates = FieldCoordinates.coordinates(parentTypeName, childFieldName) + DataFetcher rootTypeDataFetcher = { env -> ["parent": [:]] } + DataFetcher childTypeDataFetcher = new ChildDataFetcher() - )) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(rootTypeCoordinates, rootTypeDataFetcher) + .dataFetcher(childTypeCoordinates, childTypeDataFetcher) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryTypeName) + .field(newFieldDefinition() + .name(rootFieldName) + .type(rootType) + )) .build() def query = """ @@ -183,10 +236,10 @@ class DataFetcherWithErrorsAndDataTest extends Specification { result.errors.size() == 2 result.errors[0].path == ["root", "parent", "child", "goodField"] result.errors[0].message == "goodField is bad" - result.errors[0].locations == [new SourceLocation(7, 31)] + result.errors[0].locations == [new SourceLocation(5, 21)] result.errors[1].path == ["root", "parent", "child", "badField"] result.errors[1].message == "badField is bad" - result.errors[1].locations == [new SourceLocation(7, 31)] + result.errors[1].locations == [new SourceLocation(5, 21)] result.data["root"]["parent"]["child"]["goodField"] == null result.data["root"]["parent"]["child"]["badField"] == null @@ -194,154 +247,89 @@ class DataFetcherWithErrorsAndDataTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() } @Unroll - def "#820 - data fetcher can return multiple errors on one field, but collapsed (strategy: #strategyName)"() { - - // see https://github.com/graphql-java/graphql-java/issues/820 - + def "data fetcher can return context down each level (strategy: #strategyName)"() { given: - - GraphQLOutputType childType = newObject() - .name("childType") - .field(newFieldDefinition().name("goodField") - .type(GraphQLString)) - .field(newFieldDefinition().name("badField") - .type(GraphQLString)) - .build() - GraphQLOutputType parentType = newObject() - .name("parentType") - .field(newFieldDefinition().name("child") - .type(childType) - .dataFetcher({ env -> - new DataFetcherResult( - null, [ - new DataFetchingErrorGraphQLError("error 1", []), - new DataFetchingErrorGraphQLError("error 2", []) - ]) - })) - .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field(newFieldDefinition() - .name("parent") - .type(parentType) - .dataFetcher({ env -> [:] }) - - )) - .build() - - def query = """ - query { - parent { - child { - goodField - badField - } + def spec = ''' + type Query { + first : Level1 } - } - """ - - def result = GraphQL - .newGraphQL(schema) - .queryExecutionStrategy(executionStrategy) - .build() - .execute(executionInput(query)) - - expect: - - result.errors.size() == 2 - result.errors[0].path == ["parent", "child"] - result.errors[0].message == "error 1" - result.errors[0].locations == [new SourceLocation(6, 27)] - - result.errors[1].path == ["parent", "child"] - result.errors[1].message == "error 2" - result.errors[1].locations == [new SourceLocation(6, 27)] - - result.data["parent"]["child"] == null - - where: - - strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) - 'async' | new AsyncExecutionStrategy() - 'asyncSerial' | new AsyncSerialExecutionStrategy() - } - - @Unroll - def "#820 - data fetcher can return data and errors as completable future (strategy: #strategyName)"() { - - // see https://github.com/graphql-java/graphql-java/issues/820 - - given: - - GraphQLOutputType childType = newObject() - .name("childType") - .field(newFieldDefinition().name("goodField") - .type(GraphQLString)) - .field(newFieldDefinition().name("badField") - .type(GraphQLString)) - .build() - GraphQLOutputType parentType = newObject() - .name("parentType") - .field(newFieldDefinition().name("child") - .type(childType) - .dataFetcher({ env -> - CompletableFuture.completedFuture(new DataFetcherResult( - new ChildObject(), [ - new DataFetchingErrorGraphQLError("badField is bad", ["badField"]) - ])) - })) - .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field(newFieldDefinition() - .name("parent") - .type(parentType) - .dataFetcher({ env -> [:] }) - - )) + + type Level1 { + second : Level2 + } + + type Level2 { + third : Level3 + } + + type Level3 { + skip : Level4 + } + + type Level4 { + fourth : String + } + ''' + + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type("Query", + { type -> + type.dataFetcher("first", new ContextPassingDataFetcher()) + }) + .type("Level1", + { type -> + type.dataFetcher("second", new ContextPassingDataFetcher()) + }) + .type("Level2", + { type -> + type.dataFetcher("third", new ContextPassingDataFetcher()) + }) + .type("Level3", + { type -> + type.dataFetcher("skip", new ContextPassingDataFetcher(true)) + }) + .type("Level4", + { type -> + type.dataFetcher("fourth", new ContextPassingDataFetcher()) + }) .build() - def query = """ - query { - parent { - child { - goodField - badField + def query = ''' + { + first { + second { + third { + skip { + fourth + } + } + } } } - } - """ + ''' - def result = GraphQL - .newGraphQL(schema) + def result = TestUtil.graphQL(spec, runtimeWiring) .queryExecutionStrategy(executionStrategy) .build() - .execute(executionInput(query)) + .execute(newExecutionInput().query(query).root("").graphQLContext(["key": 1])) expect: - result.errors.size() == 1 - result.errors[0].path == ["parent", "child", "badField"] - result.errors[0].message == "badField is bad" - result.errors[0].locations == [new SourceLocation(6, 27)] + result.errors.isEmpty() + result.data == [first: [second: [third: [skip: [fourth: "1,2,3,4,4,"]]]]] - result.data["parent"]["child"]["goodField"] == "good" - result.data["parent"]["child"]["badField"] == null where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() + } } \ No newline at end of file diff --git a/src/test/groovy/graphql/DataFetchingErrorGraphQLError.groovy b/src/test/groovy/graphql/DataFetchingErrorGraphQLError.groovy deleted file mode 100644 index 4bec241a8d..0000000000 --- a/src/test/groovy/graphql/DataFetchingErrorGraphQLError.groovy +++ /dev/null @@ -1,42 +0,0 @@ -package graphql - -import graphql.language.SourceLocation - -class DataFetchingErrorGraphQLError implements GraphQLError { - - List path - String message - List locations - - DataFetchingErrorGraphQLError(String message) { - this.message = message - this.path = null - this.locations = null - } - - DataFetchingErrorGraphQLError(String message, List path) { - this.message = message - this.path = path - this.locations = [new SourceLocation(2, 10)] - } - - @Override - String getMessage() { - return message - } - - @Override - List getLocations() { - return locations - } - - @Override - ErrorType getErrorType() { - return ErrorType.DataFetchingException - } - - @Override - List getPath() { - return path - } -} diff --git a/src/test/groovy/graphql/DefaultValuesTest.groovy b/src/test/groovy/graphql/DefaultValuesTest.groovy new file mode 100644 index 0000000000..ccb26fe979 --- /dev/null +++ b/src/test/groovy/graphql/DefaultValuesTest.groovy @@ -0,0 +1,116 @@ +package graphql + +import graphql.schema.DataFetcher +import spock.lang.Specification + +import static graphql.ExecutionInput.newExecutionInput + +class DefaultValuesTest extends Specification { + + def "provided values override defaults"() { + def sdl = """ + type Query { + myField(deleted: Boolean = true) : String + myField2(deleted: Boolean = true) : String + } + """ + + def df = { env -> + return "dataFetcherArg=" + env.getArgument("deleted") + } as DataFetcher + def graphQL = TestUtil.graphQL(sdl, [Query: [ + myField : df, + myField2: df]] + ).build() + + // + // The variable is present in the variables map and its explicitly null + // + // https://spec.graphql.org/draft/#sec-Coercing-Variable-Values + // + when: + def ei = newExecutionInput(''' + query myQuery($deleted: Boolean = false) { + myField(deleted : $deleted) + } + ''').variables(["deleted": null]).build() + def er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [myField: "dataFetcherArg=null"] + + // + // The variable is present in the variables map and its explicitly a value + // + // https://spec.graphql.org/draft/#sec-Coercing-Variable-Values + // + when: + ei = newExecutionInput(''' + query myQuery($deleted: Boolean = false) { + myField(deleted : $deleted) + } + ''').variables(["deleted": true]).build() + er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [myField: "dataFetcherArg=true"] + + // + // The variable is NOT present in the variables map it should use a default + // value from the variable declaration + // + // https://spec.graphql.org/draft/#sec-Coercing-Variable-Values + // + when: + ei = newExecutionInput(''' + query myQuery($deleted: Boolean = false) { + myField(deleted : $deleted) + } + ''').variables(["NotProvided": "valueNotProvided"]).build() + er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [myField: "dataFetcherArg=false"] + + // + // The variable is NOT present in the variables map and a variable is NOT used + // it should use a default value from the field declaration + // + // + when: + ei = newExecutionInput(''' + query myQuery($deleted: Boolean = false) { + myField + myField2(deleted : $deleted) + } + ''').variables(["NotProvided": "valueNotProvided"]).build() + er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [myField : "dataFetcherArg=true", + myField2: "dataFetcherArg=false"] + + // + // If there are no variables on the query operation + // it should use a default value from the field declaration + // or literals provided + // + when: + ei = newExecutionInput(''' + query myQuery { + myField(deleted :false) + myField2 + } + ''').variables(["NotProvided": "valueNotProvided"]).build() + er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [myField : "dataFetcherArg=false", + myField2: "dataFetcherArg=true"] + } +} diff --git a/src/test/groovy/graphql/EngineRunningTest.groovy b/src/test/groovy/graphql/EngineRunningTest.groovy new file mode 100644 index 0000000000..592f7d2a1d --- /dev/null +++ b/src/test/groovy/graphql/EngineRunningTest.groovy @@ -0,0 +1,500 @@ +package graphql + +import graphql.execution.DataFetcherExceptionHandler +import graphql.execution.DataFetcherExceptionHandlerResult +import graphql.execution.EngineRunningObserver +import graphql.execution.ExecutionId +import graphql.execution.instrumentation.Instrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters +import graphql.execution.preparsed.PreparsedDocumentEntry +import graphql.execution.preparsed.PreparsedDocumentProvider +import graphql.parser.Parser +import graphql.schema.DataFetcher +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.locks.ReentrantLock +import java.util.function.Function + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.execution.EngineRunningObserver.ENGINE_RUNNING_OBSERVER_KEY +import static graphql.execution.EngineRunningObserver.RunningState +import static graphql.execution.EngineRunningObserver.RunningState.NOT_RUNNING +import static graphql.execution.EngineRunningObserver.RunningState.NOT_RUNNING_FINISH +import static graphql.execution.EngineRunningObserver.RunningState.RUNNING +import static graphql.execution.EngineRunningObserver.RunningState.RUNNING_START + +class EngineRunningTest extends Specification { + + + private static List trackStates(ExecutionInput ei) { + List states = new CopyOnWriteArrayList<>(); + ei.getGraphQLContext().put(ENGINE_RUNNING_OBSERVER_KEY, { + ExecutionId executionId, GraphQLContext context, RunningState running -> + states.add(running) + } as EngineRunningObserver); + states + } + + def "preparsed async document provider"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> + return "world" + } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + + def query = "{ hello }" + def document = Parser.parse(query) + + CompletableFuture cf = new CompletableFuture() + PreparsedDocumentProvider preparsedDocumentProvider = new PreparsedDocumentProvider() { + @Override + CompletableFuture getDocumentAsync(ExecutionInput executionInput, Function parseAndValidateFunction) { + return cf + } + } + def graphQL = GraphQL.newGraphQL(schema).preparsedDocumentProvider(preparsedDocumentProvider).build() + + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear() + cf.complete(new PreparsedDocumentEntry(document)) + then: + states == [RUNNING, NOT_RUNNING_FINISH] + er.get().data == [hello: "world"] + + + } + + def "engine starts before instrumentation state and handles async state correctly"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> + return "world" + } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + + CompletableFuture cf = new CompletableFuture() + Instrumentation instrumentation = new Instrumentation() { + + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return cf + } + } + def graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear() + cf.complete(new InstrumentationState() {}) + then: + states == [RUNNING, NOT_RUNNING_FINISH] + er.get().data == [hello: "world"] + + + } + + def "async instrument execution result"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> + return "world" + } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + + CompletableFuture cf = new CompletableFuture() + Instrumentation instrumentation = new Instrumentation() { + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return cf + } + } + def graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear() + cf.complete(ExecutionResultImpl.newExecutionResult().data([hello: "world-modified"]).build()) + then: + er.get().data == [hello: "world-modified"] + states == [RUNNING, NOT_RUNNING_FINISH] + + + } + + + def "engine running state is observed"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> + return "world" + } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.execute(ei) + then: + er.data == [hello: "world"] + states == [RUNNING_START, NOT_RUNNING_FINISH] + } + + def "multiple async DF"() { + given: + def sdl = ''' + + type Query { + hello: String + hello2: String + foo: Foo + someStaticValue: Bar + } + type Foo { + name: String + } + type Bar { + staticValue: String + } + ''' + CompletableFuture cf1 = new CompletableFuture(); + CompletableFuture cf2 = new CompletableFuture(); + CompletableFuture cfFooName = new CompletableFuture(); + def df1 = { env -> + return cf1; + } as DataFetcher + + def df2 = { env -> + return cf2; + } as DataFetcher + + def dfFoo = { env -> + return "Foo"; + } as DataFetcher + + def dfFooName = { env -> + return cfFooName; + } as DataFetcher + + def dfStaticValue = { env -> + return [staticValue: "staticValue"] + } as DataFetcher + + + def fetchers = [Query: ["hello": df1, "hello2": df2, foo: dfFoo, someStaticValue: dfStaticValue], Foo: [name: dfFooName]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello hello2 foo { name } someStaticValue {staticValue} }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear(); + cf1.complete("world") + then: + states == [RUNNING, NOT_RUNNING] + + when: + states.clear(); + cfFooName.complete("FooName") + then: + states == [RUNNING, NOT_RUNNING] + + + when: + states.clear() + cf2.complete("world2") + then: + states == [RUNNING, NOT_RUNNING_FINISH] + er.get().data == [hello: "world", hello2: "world2", foo: [name: "FooName"], someStaticValue: [staticValue: "staticValue"]] + } + + + def "engine running state is observed with one async datafetcher"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + CompletableFuture cf = new CompletableFuture(); + def df = { env -> + return cf; + } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear(); + cf.complete("world") + + then: + states == [RUNNING, NOT_RUNNING_FINISH] + er.get().data == [hello: "world"] + } + + def "engine running state is observed with one dependent async datafetcher"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + CompletableFuture cf = new CompletableFuture(); + def df = { env -> + return cf.thenApply { it -> it } + } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear(); + cf.complete("world") + + then: + er.get().data == [hello: "world"] + states == [RUNNING, NOT_RUNNING_FINISH] + } + + + def "datafetcher failing with async exception handler"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> + throw new RuntimeException("boom") + } as DataFetcher + + ReentrantLock reentrantLock = new ReentrantLock() + reentrantLock.lock(); + + def exceptionHandler = { param -> + def async = CompletableFuture.supplyAsync { + reentrantLock.lock(); + return DataFetcherExceptionHandlerResult.newResult(GraphqlErrorBuilder + .newError(param.dataFetchingEnvironment).message("recovered").build()).build() + } + return async + } as DataFetcherExceptionHandler + + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).defaultDataFetcherExceptionHandler(exceptionHandler).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + states.clear() + reentrantLock.unlock() + def result = er.get() + + then: + result.errors.collect { it.message } == ["recovered"] + states == [RUNNING, NOT_RUNNING_FINISH] + } + + def "async datafetcher failing with async exception handler"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def cf = new CompletableFuture(); + def df = { env -> + return cf.thenApply { it -> throw new RuntimeException("boom") } + } as DataFetcher + + ReentrantLock reentrantLock = new ReentrantLock() + reentrantLock.lock(); + + def exceptionHandler = { param -> + def async = CompletableFuture.supplyAsync { + reentrantLock.lock(); + return DataFetcherExceptionHandlerResult.newResult(GraphqlErrorBuilder + .newError(param.dataFetchingEnvironment).message("recovered").build()).build() + } + return async + } as DataFetcherExceptionHandler + + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).defaultDataFetcherExceptionHandler(exceptionHandler).build() + + def query = "{ hello }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear() + cf.complete("foo") + + then: + states == [RUNNING, NOT_RUNNING] + + when: + states.clear() + reentrantLock.unlock() + def result = er.get() + + then: + result.errors.collect { it.message } == ["recovered"] + states == [RUNNING, NOT_RUNNING_FINISH] + } + + + def "engine running state is observed with two async datafetcher"() { + given: + def sdl = ''' + + type Query { + hello: String + hello2: String + } + ''' + CompletableFuture cf1 = new CompletableFuture(); + CompletableFuture cf2 = new CompletableFuture(); + def df = { env -> + return cf1; + } as DataFetcher + def df2 = { env -> + return cf2 + } as DataFetcher + + def fetchers = ["Query": ["hello": df, "hello2": df2]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello hello2 }" + def ei = newExecutionInput(query).build() + + List states = trackStates(ei) + + when: + def er = graphQL.executeAsync(ei) + then: + states == [RUNNING_START, NOT_RUNNING] + + when: + states.clear(); + cf1.complete("world") + + then: + states == [RUNNING, NOT_RUNNING] + + when: + states.clear(); + cf2.complete("world2") + + then: + states == [RUNNING, NOT_RUNNING_FINISH] + er.get().data == [hello: "world", hello2: "world2"] + } +} diff --git a/src/test/groovy/graphql/EnumValues.groovy b/src/test/groovy/graphql/EnumValues.groovy new file mode 100644 index 0000000000..1f37f62af9 --- /dev/null +++ b/src/test/groovy/graphql/EnumValues.groovy @@ -0,0 +1,152 @@ +package graphql + +import graphql.schema.idl.NaturalEnumValuesProvider +import spock.lang.Specification + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class EnumValues extends Specification { + + static enum SomeEnum { + TWO(2), + THREE(3) + public final int number + + SomeEnum(int number) { + this.number = number + } + } + + def spec = ''' + enum SomeEnum { + TWO + THREE + } + + input Input { + e: SomeEnum! + } + + type Query { + field(e: SomeEnum = TWO) : Int! + wrappedArgField(e: [SomeEnum!]! = [TWO, THREE]) : Int! + inputField(i: Input = {e: THREE}) : Int! + } + ''' + + def typeRuntimeWiring = newTypeWiring('SomeEnum').enumValues(new NaturalEnumValuesProvider(SomeEnum)).build() + def queryRuntimeWriting = newTypeWiring('Query') + .dataFetcher( + 'field', + { env -> + def arg = env.getArgument("e") + // Be careful! In groovy `arg as SomeEnum` will convert a string to an enum, and the point of this test + // is to show that this isn't needed. + assert arg instanceof SomeEnum + arg.number + }) + .dataFetcher( + 'wrappedArgField', + { env -> + def arg = env.getArgument("e") + // Be careful! In groovy `arg as SomeEnum` will convert a string to an enum, and the point of this test + // is to show that this isn't needed. + (arg as List).collect { e -> + // Be careful! In groovy `e as SomeEnum` will convert a string to an enum, and the point of this test + // is to show that this isn't needed. + assert e instanceof SomeEnum + e.number + }.sum() + }) + .dataFetcher( + 'inputField', + { env -> + Map arg = env.getArgument("i") + def e = arg.get("e") + // Be careful! In groovy `arg as SomeEnum` will convert a string to an enum, and the point of this test + // is to show that this isn't needed. + assert e instanceof SomeEnum + e.number + }) + def runtimeWiring = newRuntimeWiring().type(typeRuntimeWiring).type(queryRuntimeWriting).build() + def graphql = TestUtil.graphQL(spec, runtimeWiring).build() + + def "explicit enum values go through EnumValuesProvider"() { + when: + def result = graphql.execute(''' + { + field(e: THREE) + } + ''') + + then: + result.errors.isEmpty() + result.data == [field: 3] + } + + def "default enum values go through EnumValuesProvider"() { + when: + def result = graphql.execute(''' + { + field + } + ''') + + then: + result.errors.isEmpty() + result.data == [field: 2] + } + + def "wrapped explicit enum values go through EnumValuesProvider"() { + when: + def result = graphql.execute(''' + { + wrappedArgField(e: [TWO, TWO, THREE]) + } + ''') + + then: + result.errors.isEmpty() + result.data == [wrappedArgField: 7] + } + + def "wrapped default enum values go through EnumValuesProvider"() { + when: + def result = graphql.execute(''' + { + wrappedArgField + } + ''') + + then: + result.errors.isEmpty() + result.data == [wrappedArgField: 5] + } + + def "explicit enum values in input objects go through EnumValuesProvider"() { + when: + def result = graphql.execute(''' + { + inputField(i: {e: TWO}) + } + ''') + + then: + result.errors.isEmpty() + result.data == [inputField: 2] + } + + def "default enum values in input objects go through EnumValuesProvider"() { + when: + def result = graphql.execute(''' + { + inputField + } + ''') + + then: + result.errors.isEmpty() + result.data == [inputField: 3] + } +} diff --git a/src/test/groovy/graphql/ErrorsTest.groovy b/src/test/groovy/graphql/ErrorsTest.groovy index 46d15f2d8c..e346a26b47 100644 --- a/src/test/groovy/graphql/ErrorsTest.groovy +++ b/src/test/groovy/graphql/ErrorsTest.groovy @@ -1,6 +1,6 @@ package graphql -import graphql.execution.ExecutionPath +import graphql.execution.ResultPath import graphql.language.SourceLocation import graphql.validation.ValidationError import graphql.validation.ValidationErrorType @@ -43,9 +43,21 @@ class ErrorsTest extends Specification { def "ValidationError equals and hashcode works"() { expect: - def same1 = new ValidationError(ValidationErrorType.BadValueForDefaultArg, [src(15, 34), src(23, 567)], "bad ju ju") - def same2 = new ValidationError(ValidationErrorType.BadValueForDefaultArg, [src(15, 34), src(23, 567)], "bad ju ju") - def different1 = new ValidationError(ValidationErrorType.FieldsConflict, [src(15, 34), src(23, 567)], "bad ju ju") + def same1 = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.BadValueForDefaultArg) + .sourceLocations([src(15, 34), src(23, 567)]) + .description("bad ju ju") + .build() + def same2 = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.BadValueForDefaultArg) + .sourceLocations([src(15, 34), src(23, 567)]) + .description("bad ju ju") + .build() + def different1 = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.FieldsConflict) + .sourceLocations([src(15, 34), src(23, 567)]) + .description("bad ju ju") + .build() commonAssert(same1, same2, different1) } @@ -53,9 +65,9 @@ class ErrorsTest extends Specification { def "ExceptionWhileDataFetching equals and hashcode works"() { expect: - def same1 = new ExceptionWhileDataFetching(ExecutionPath.rootPath(), new RuntimeException("bad ju ju"), null) - def same2 = new ExceptionWhileDataFetching(ExecutionPath.rootPath(), new RuntimeException("bad ju ju"), null) - def different1 = new ExceptionWhileDataFetching(ExecutionPath.rootPath(), new RuntimeException("unexpected ju ju"), null) + def same1 = new ExceptionWhileDataFetching(ResultPath.rootPath(), new RuntimeException("bad ju ju"), null) + def same2 = new ExceptionWhileDataFetching(ResultPath.rootPath(), new RuntimeException("bad ju ju"), null) + def different1 = new ExceptionWhileDataFetching(ResultPath.rootPath(), new RuntimeException("unexpected ju ju"), null) commonAssert(same1, same2, different1) } diff --git a/src/test/groovy/graphql/ExecutionInputTest.groovy b/src/test/groovy/graphql/ExecutionInputTest.groovy new file mode 100644 index 0000000000..23c06ea9c7 --- /dev/null +++ b/src/test/groovy/graphql/ExecutionInputTest.groovy @@ -0,0 +1,465 @@ +package graphql + +import graphql.execution.ExecutionId +import graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext +import graphql.execution.instrumentation.Instrumentation +import graphql.execution.instrumentation.InstrumentationContext +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters +import graphql.execution.preparsed.persisted.PersistedQuerySupport +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import org.dataloader.DataLoaderRegistry +import spock.lang.Specification + +import java.time.Duration +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CountDownLatch + +import static org.awaitility.Awaitility.* + +class ExecutionInputTest extends Specification { + + def query = "query { hello }" + def registry = new DataLoaderRegistry() + def root = "root" + def variables = [key: "value"] + + def "build works"() { + when: + def executionInput = ExecutionInput.newExecutionInput().query(query) + .dataLoaderRegistry(registry) + .variables(variables) + .root(root) + .graphQLContext({ it.of(["a": "b"]) }) + .locale(Locale.GERMAN) + .extensions([some: "map"]) + .build() + then: + executionInput.graphQLContext.get("a") == "b" + executionInput.root == root + executionInput.variables == variables + executionInput.rawVariables.toMap() == variables + executionInput.dataLoaderRegistry == registry + executionInput.query == query + executionInput.locale == Locale.GERMAN + executionInput.extensions == [some: "map"] + executionInput.toString() != null + } + + def "build without locale"() { + when: + def executionInput = ExecutionInput.newExecutionInput().query(query) + .dataLoaderRegistry(registry) + .variables(variables) + .root(root) + .graphQLContext({ it.of(["a": "b"]) }) + .locale(null) + .extensions([some: "map"]) + .build() + then: + executionInput.locale == Locale.getDefault() + } + + def "map context build works"() { + when: + def executionInput = ExecutionInput.newExecutionInput().query(query) + .graphQLContext([a: "b"]) + .build() + then: + executionInput.graphQLContext.get("a") == "b" + } + + def "legacy context is defaulted"() { + // Retaining deprecated method tests for coverage + when: + def executionInput = ExecutionInput.newExecutionInput().query(query) + .build() + then: + executionInput.context instanceof GraphQLContext // Retain deprecated for test coverage + executionInput.getGraphQLContext() == executionInput.getContext() // Retain deprecated for test coverage + } + + def "graphql context is defaulted"() { + when: + def executionInput = ExecutionInput.newExecutionInput().query(query) + .build() + then: + executionInput.graphQLContext instanceof GraphQLContext + } + + def "locale defaults to JVM default"() { + when: + def executionInput = ExecutionInput.newExecutionInput().query(query) + .build() + then: + executionInput.getLocale() == Locale.getDefault() + } + + def "transform works and copies values"() { + when: + def executionInputOld = ExecutionInput.newExecutionInput().query(query) + .dataLoaderRegistry(registry) + .variables(variables) + .extensions([some: "map"]) + .root(root) + .graphQLContext({ it.of(["a": "b"]) }) + .locale(Locale.GERMAN) + .build() + def graphQLContext = executionInputOld.getGraphQLContext() + def executionInput = executionInputOld.transform({ bldg -> bldg.query("new query") }) + + then: + executionInput.graphQLContext == graphQLContext + executionInput.root == root + executionInput.variables == variables + executionInput.dataLoaderRegistry == registry + executionInput.locale == Locale.GERMAN + executionInput.extensions == [some: "map"] + executionInput.query == "new query" + } + + def "transform works and sets variables"() { + when: + def executionInputOld = ExecutionInput.newExecutionInput().query(query) + .dataLoaderRegistry(registry) + .extensions([some: "map"]) + .root(root) + .graphQLContext({ it.of(["a": "b"]) }) + .locale(Locale.GERMAN) + .build() + def graphQLContext = executionInputOld.getGraphQLContext() + def executionInput = executionInputOld.transform({ bldg -> + bldg + .query("new query") + .variables(variables) + }) + + then: + executionInput.graphQLContext == graphQLContext + executionInput.root == root + executionInput.rawVariables.toMap() == variables + executionInput.dataLoaderRegistry == registry + executionInput.locale == Locale.GERMAN + executionInput.extensions == [some: "map"] + executionInput.query == "new query" + } + + def "defaults query into builder as expected"() { + when: + def executionInput = ExecutionInput.newExecutionInput("{ q }") + .locale(Locale.ENGLISH) + .build() + then: + executionInput.query == "{ q }" + executionInput.locale == Locale.ENGLISH + executionInput.dataLoaderRegistry != null + executionInput.variables == [:] + } + + def "integration test so that values make it right into the data fetchers"() { + + def sdl = ''' + type Query { + fetch : String + } + ''' + DataFetcher df = { DataFetchingEnvironment env -> + return [ + "locale" : env.getLocale().getDisplayName(Locale.ENGLISH), + "executionId" : env.getExecutionId().toString(), + "graphqlContext": env.getGraphQlContext().get("a") + + ] + } + def schema = TestUtil.schema(sdl, ["Query": ["fetch": df]]) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query("{ fetch }") + .locale(Locale.GERMAN) + .executionId(ExecutionId.from("ID123")) + .build() + executionInput.getGraphQLContext().putAll([a: "b"]) + + def er = graphQL.execute(executionInput) + + then: + er.errors.isEmpty() + er.data["fetch"] == "{locale=German, executionId=ID123, graphqlContext=b}" + } + + def "can cancel the execution"() { + def sdl = ''' + type Query { + fetch1 : Inner + fetch2 : Inner + } + + type Inner { + f : String + } + + ''' + + CountDownLatch fieldLatch = new CountDownLatch(1) + + DataFetcher df1Sec = { DataFetchingEnvironment env -> + println("Entering DF1") + return CompletableFuture.supplyAsync { + println("DF1 async run") + fieldLatch.await() + Thread.sleep(1000) + return [f: "x"] + } + } + DataFetcher df10Sec = { DataFetchingEnvironment env -> + println("Entering DF10") + return CompletableFuture.supplyAsync { + println("DF10 async run") + fieldLatch.await() + Thread.sleep(10000) + return "x" + } + } + + def fetcherMap = ["Query": ["fetch1": df1Sec, "fetch2": df1Sec], + "Inner": ["f": df10Sec] + ] + def schema = TestUtil.schema(sdl, fetcherMap) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query("query q { fetch1 { f } fetch2 { f } }") + .build() + + def cf = graphQL.executeAsync(executionInput) + + Thread.sleep(250) // let it get into the field fetching say + + // lets cancel it + println("cancelling") + executionInput.cancel() + + // let the DFs run + println("make the fields run") + fieldLatch.countDown() + + println("and await for the overall CF to complete") + await().atMost(Duration.ofSeconds(60)).until({ -> cf.isDone() }) + + def er = cf.join() + + then: + !er.errors.isEmpty() + er.errors[0]["message"] == "Execution has been asked to be cancelled" + } + + def "can cancel request at random times (#testName)"() { + def sdl = ''' + type Query { + fetch1 : Inner + fetch2 : Inner + } + + type Inner { + inner : Inner + f : String + } + + ''' + + when: + + CountDownLatch fetcherLatch = new CountDownLatch(1) + + DataFetcher df = { DataFetchingEnvironment env -> + return CompletableFuture.supplyAsync { + fetcherLatch.countDown() + def delay = plusOrMinus(dfDelay) + println("DF ${env.getExecutionStepInfo().getPath()} sleeping for $delay") + Thread.sleep(delay) + return [inner: [f: "x"], f: "x"] + } + } + + def fetcherMap = ["Query": ["fetch1": df, "fetch2": df], + "Inner": ["inner": df] + ] + def schema = TestUtil.schema(sdl, fetcherMap) + def graphQL = GraphQL.newGraphQL(schema).build() + + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query("query q { fetch1 { inner { inner { inner { f }}}} fetch2 { inner { inner { inner { f }}}} }") + .build() + + def cf = graphQL.executeAsync(executionInput) + + // wait for at least one fetcher to run + fetcherLatch.await() + + // using a random number MAY make this test flaky - but so be it. We want ot make sure that + // if we cancel then we dont lock up. We have deterministic tests for that so lets hav + // some random ones + // + def randomCancel = plusOrMinus(dfDelay) + Thread.sleep(randomCancel) + + // now make it cancel + println("Cancelling after $randomCancel") + executionInput.cancel() + + await().atMost(Duration.ofSeconds(10)).until({ -> cf.isDone() }) + + def er = cf.join() + + then: + !er.errors.isEmpty() + er.errors[0]["message"] == "Execution has been asked to be cancelled" + + where: + testName | dfDelay + "50 ms" | plusOrMinus(50) + "100 ms" | plusOrMinus(100) + "200 ms" | plusOrMinus(200) + "500 ms" | plusOrMinus(500) + "1000 ms" | plusOrMinus(1000) + } + + def "uses persisted query marker when query is null"() { + when: + ExecutionInput.newExecutionInput().query(null).build() + then: + thrown(AssertException) + } + + def "uses persisted query marker when query is null and extensions contains persistedQuery"() { + when: + def executionInput = ExecutionInput.newExecutionInput() + .extensions([persistedQuery: "any"]) + .query(null) + .build() + then: + executionInput.query == PersistedQuerySupport.PERSISTED_QUERY_MARKER + } + + def "uses persisted query marker when query is empty and extensions contains persistedQuery"() { + when: + def executionInput = ExecutionInput.newExecutionInput() + .extensions([persistedQuery: "any"]) + .query("") + .build() + then: + executionInput.query == PersistedQuerySupport.PERSISTED_QUERY_MARKER + } + + def "can cancel at specific places"() { + def sdl = ''' + type Query { + fetch1 : Inner + fetch2 : Inner + } + + type Inner { + inner : Inner + f : String + } + + ''' + + when: + + DataFetcher df = { DataFetchingEnvironment env -> + return CompletableFuture.supplyAsync { + return [inner: [f: "x"], f: "x"] + } + } + + def fetcherMap = ["Query": ["fetch1": df, "fetch2": df], + "Inner": ["inner": df] + ] + + + def queryText = "query q { fetch1 { inner { inner { inner { f }}}} fetch2 { inner { inner { inner { f }}}} }" + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(queryText) + .build() + + Instrumentation instrumentation = new Instrumentation() { + @Override + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + executionInput.cancel() + return null + } + } + def schema = TestUtil.schema(sdl, fetcherMap) + def graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + + def er = awaitAsync(graphQL, executionInput) + + then: + !er.errors.isEmpty() + er.errors[0]["message"] == "Execution has been asked to be cancelled" + + when: + executionInput = ExecutionInput.newExecutionInput() + .query(queryText) + .build() + + instrumentation = new Instrumentation() { + @Override + InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + executionInput.cancel() + return null + } + } + schema = TestUtil.schema(sdl, fetcherMap) + graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + er = awaitAsync(graphQL, executionInput) + + then: + !er.errors.isEmpty() + er.errors[0]["message"] == "Execution has been asked to be cancelled" + + when: + executionInput = ExecutionInput.newExecutionInput() + .query(queryText) + .build() + + instrumentation = new Instrumentation() { + + @Override + InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + executionInput.cancel() + return null + } + } + schema = TestUtil.schema(sdl, fetcherMap) + graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + er = awaitAsync(graphQL, executionInput) + + then: + !er.errors.isEmpty() + er.errors[0]["message"] == "Execution has been asked to be cancelled" + + } + + private static ExecutionResult awaitAsync(GraphQL graphQL, ExecutionInput executionInput) { + def cf = graphQL.executeAsync(executionInput) + await().atMost(Duration.ofSeconds(10)).until({ -> cf.isDone() }) + return cf.join() + } + + private static int plusOrMinus(int integer) { + int half = (int) (integer / 2) + def intVal = TestUtil.rand((integer - half), (integer + half)) + return intVal + } +} diff --git a/src/test/groovy/graphql/ExecutionResultImplTest.groovy b/src/test/groovy/graphql/ExecutionResultImplTest.groovy index 4a9042b4f0..8b8894cca3 100644 --- a/src/test/groovy/graphql/ExecutionResultImplTest.groovy +++ b/src/test/groovy/graphql/ExecutionResultImplTest.groovy @@ -6,7 +6,7 @@ import spock.lang.Specification class ExecutionResultImplTest extends Specification { def KNOWN_ERRORS = [new InvalidSyntaxError(new SourceLocation(666, 664), "Yikes")] - def EXPECTED_SPEC_ERRORS = [['message': 'Invalid Syntax : Yikes', 'locations': [[line: 666, column: 664]]]] + def EXPECTED_SPEC_ERRORS = [['message': 'Yikes', 'locations': [[line: 666, column: 664]], extensions:[classification:"InvalidSyntax"]]] def "data with no errors"() { @@ -17,6 +17,7 @@ class ExecutionResultImplTest extends Specification { def errors = er.getErrors() def specMap = er.toSpecification() then: + er.isDataPresent() actual == "hello world" errors.size() == 0 @@ -33,6 +34,7 @@ class ExecutionResultImplTest extends Specification { def errors = er.getErrors() def specMap = er.toSpecification() then: + er.isDataPresent() actual == "hello world" errors.size() == 1 @@ -43,6 +45,9 @@ class ExecutionResultImplTest extends Specification { specMap["errors"] == EXPECTED_SPEC_ERRORS } + // According to https://graphql.github.io/graphql-spec/June2018/#sec-Data, + // there's a disctinction between `null` data, and no data at all. + // See test below def "errors and no data"() { given: def er = new ExecutionResultImpl(KNOWN_ERRORS) @@ -51,6 +56,7 @@ class ExecutionResultImplTest extends Specification { def errors = er.getErrors() def specMap = er.toSpecification() then: + !er.isDataPresent() actual == null errors.size() == 1 @@ -60,6 +66,28 @@ class ExecutionResultImplTest extends Specification { specMap["errors"] == EXPECTED_SPEC_ERRORS } + // According to https://graphql.github.io/graphql-spec/June2018/#sec-Data, + // there's a disctinction between `null` data, and no data at all. + // See test above + def "errors and (present) null data"() { + given: + def er = new ExecutionResultImpl(null, KNOWN_ERRORS) + when: + def actual = er.getData() + def errors = er.getErrors() + def specMap = er.toSpecification() + then: + er.isDataPresent() + actual == null + + errors.size() == 1 + errors == KNOWN_ERRORS + + specMap.size() == 2 + specMap["errors"] == EXPECTED_SPEC_ERRORS + specMap["data"] == null + } + def "can have extensions"() { given: @@ -124,8 +152,8 @@ class ExecutionResultImplTest extends Specification { specMap.size() == 1 specMap["errors"] == [ - ['message': 'Invalid Syntax : Yikes', 'locations': [[line: 666, column: 664]]], - ['message': 'Invalid Syntax : Yowza', 'locations': [[line: 966, column: 964]]] + ['message': 'Yikes', 'locations': [[line: 666, column: 664]], extensions:[classification:"InvalidSyntax"]], + ['message': 'Yowza', 'locations': [[line: 966, column: 964]], extensions:[classification:"InvalidSyntax"]] ] } @@ -148,29 +176,58 @@ class ExecutionResultImplTest extends Specification { def "test setting extensions"() { given: - def startEr = new ExecutionResultImpl("Some Data", KNOWN_ERRORS,null) + def startEr = new ExecutionResultImpl("Some Data", KNOWN_ERRORS, null) - def er = ExecutionResultImpl.newExecutionResult().from(startEr).extensions([ext1:"here"]).build() + def er = ExecutionResultImpl.newExecutionResult().from(startEr).extensions([ext1: "here"]).build() when: def extensions = er.getExtensions() then: - extensions == [ext1:"here"] + extensions == [ext1: "here"] } def "test adding extension"() { given: - def startEr = new ExecutionResultImpl("Some Data", KNOWN_ERRORS,[ext1:"here"]) + def startEr = new ExecutionResultImpl("Some Data", KNOWN_ERRORS, [ext1: "here"]) - def er = ExecutionResultImpl.newExecutionResult().from(startEr).addExtension("ext2","aswell").build() + def er = ExecutionResultImpl.newExecutionResult().from(startEr).addExtension("ext2", "aswell").build() when: def extensions = er.getExtensions() then: - extensions == [ext1:"here", ext2 : "aswell"] + extensions == [ext1: "here", ext2: "aswell"] } + def "can parse out a map of to an ER"() { + when: + def map = [data: [f: "v"]] + def er = ExecutionResult.fromSpecification(map) + then: + er.data == [f: "v"] + er.extensions == null + er.errors.isEmpty() + + when: + // GraphqlErrorHelperTest is more extensive tests for error parsing which we will not repeat here + map = [errors: [[message: "m0"], [message: "m1"]]] + er = ExecutionResult.fromSpecification(map) + then: + er.data == null + er.extensions == null + !er.errors.isEmpty() + er.errors[0].message == "m0" + er.errors[1].message == "m1" + + when: + map = [data: [f: "v"], extensions: [ext1: "here", ext2: "and here"]] + er = ExecutionResult.fromSpecification(map) + then: + er.data == [f: "v"] + er.extensions == [ext1: "here", ext2: "and here"] + er.errors.isEmpty() + + } } diff --git a/src/test/groovy/graphql/ExecutionResultTest.groovy b/src/test/groovy/graphql/ExecutionResultTest.groovy new file mode 100644 index 0000000000..67e411941c --- /dev/null +++ b/src/test/groovy/graphql/ExecutionResultTest.groovy @@ -0,0 +1,31 @@ +package graphql + +import graphql.language.SourceLocation +import spock.lang.Specification + +/** + * Most of the tests are actually in ExecutionResultImplTest since this is the actual impl + */ +class ExecutionResultTest extends Specification { + + def error1 = new InvalidSyntaxError(new SourceLocation(966, 964), "Yowza") + + def "can use builder to build it"() { + when: + ExecutionResult er = ExecutionResult.newExecutionResult().data([a: "b"]).addError(error1).addExtension("x", "y").build() + then: + er.data == [a: "b"] + er.errors == [error1] + er.extensions == [x: "y"] + } + + def "can transform"() { + when: + ExecutionResult er = ExecutionResult.newExecutionResult().data([a: "b"]).addError(error1).addExtension("x", "y").build() + er = er.transform({ bld -> bld.addExtension("foo", "bar") }) + then: + er.data == [a: "b"] + er.errors == [error1] + er.extensions == [x: "y", foo: "bar"] + } +} diff --git a/src/test/groovy/graphql/Fixtures.groovy b/src/test/groovy/graphql/Fixtures.groovy deleted file mode 100644 index b08618c393..0000000000 --- a/src/test/groovy/graphql/Fixtures.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package graphql - -import graphql.schema.GraphQLFieldDefinition -import graphql.schema.GraphQLObjectType -import graphql.schema.GraphQLSchema - -class Fixtures { - - - static GraphQLSchema simpsonsSchema() { - GraphQLFieldDefinition nameField = new GraphQLFieldDefinition("name", Scalars.GraphQLString) - - GraphQLObjectType simpsonCharacter = new GraphQLObjectType("simpsonCharacter", [nameField]) - GraphQLFieldDefinition simpsons = new GraphQLFieldDefinition("simpson", simpsonCharacter) - GraphQLObjectType queryType = new GraphQLObjectType("query", [simpsons]) - GraphQLSchema schema = new GraphQLSchema(queryType) - schema - } -} diff --git a/src/test/groovy/graphql/GarfieldSchema.java b/src/test/groovy/graphql/GarfieldSchema.java index 6c22d31ab4..1e82f7e091 100644 --- a/src/test/groovy/graphql/GarfieldSchema.java +++ b/src/test/groovy/graphql/GarfieldSchema.java @@ -1,6 +1,7 @@ package graphql; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; @@ -111,23 +112,24 @@ public List getFriends() { .field(newFieldDefinition() .name("name") .type(GraphQLString)) - .typeResolver(new TypeResolver() { - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment env) { - if (env.getObject() instanceof Dog) { - return DogType; - } - if (env.getObject() instanceof Person) { - return PersonType; - } - if (env.getObject() instanceof Cat) { - return CatType; - } - return null; - } - }) .build(); + public static TypeResolver namedTypeResolver = new TypeResolver() { + @Override + public GraphQLObjectType getType(TypeResolutionEnvironment env) { + if (env.getObject() instanceof Dog) { + return DogType; + } + if (env.getObject() instanceof Person) { + return PersonType; + } + if (env.getObject() instanceof Cat) { + return CatType; + } + return null; + } + }; + public static GraphQLObjectType DogType = newObject() .name("Dog") .field(newFieldDefinition() @@ -154,17 +156,18 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { .name("Pet") .possibleType(CatType) .possibleType(DogType) - .typeResolver(env -> { - if (env.getObject() instanceof Cat) { - return CatType; - } - if (env.getObject() instanceof Dog) { - return DogType; - } - return null; - }) .build(); + public static TypeResolver petTypeResolver = env -> { + if (env.getObject() instanceof Cat) { + return CatType; + } + if (env.getObject() instanceof Dog) { + return DogType; + } + return null; + }; + public static GraphQLObjectType PersonType = newObject() .name("Person") .field(newFieldDefinition() @@ -179,9 +182,14 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { .withInterface(NamedType) .build(); + public static GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver("Named", namedTypeResolver) + .typeResolver("Pet", petTypeResolver) + .build(); + public static GraphQLSchema GarfieldSchema = GraphQLSchema.newSchema() .query(PersonType) + .codeRegistry(codeRegistry) .build(); - } diff --git a/src/test/groovy/graphql/GraphQLContextTest.groovy b/src/test/groovy/graphql/GraphQLContextTest.groovy new file mode 100644 index 0000000000..d411143db6 --- /dev/null +++ b/src/test/groovy/graphql/GraphQLContextTest.groovy @@ -0,0 +1,295 @@ +package graphql + +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import spock.lang.Specification + +import java.util.function.Consumer +import java.util.stream.Collectors + +import static graphql.ExecutionInput.newExecutionInput + +class GraphQLContextTest extends Specification { + + def buildContext(Map map) { + def context = GraphQLContext.newContext() + map.forEach({ k, v -> context.of(k, v) }) + return context.build() + } + + int sizeOf(GraphQLContext graphQLContext) { + graphQLContext.stream().count() + } + + def "of builder"() { + def context + when: + context = GraphQLContext.newContext().of("k1", "v1").build() + then: + context.get("k1") == "v1" + sizeOf(context) == 1 + + when: + context = GraphQLContext.newContext().of( + "k1", "v1", + "k2", "v2" + ).build() + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + sizeOf(context) == 2 + + when: + context = GraphQLContext.newContext().of( + "k1", "v1", + "k2", "v2", + "k3", "v3", + ).build() + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + context.get("k3") == "v3" + sizeOf(context) == 3 + + when: + context = GraphQLContext.newContext().of( + "k1", "v1", + "k2", "v2", + "k3", "v3", + "k4", "v4", + ).build() + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + context.get("k3") == "v3" + context.get("k4") == "v4" + sizeOf(context) == 4 + + when: + context = GraphQLContext.newContext().of( + "k1", "v1", + "k2", "v2", + "k3", "v3", + "k4", "v4", + "k5", "v5", + ).build() + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + context.get("k3") == "v3" + context.get("k4") == "v4" + context.get("k5") == "v5" + sizeOf(context) == 5 + + when: + context = GraphQLContext.newContext() + .of("k1", "v1") + .of("k2", "v2") + .of(["k3": "v3"]).build() + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + context.get("k3") == "v3" + sizeOf(context) == 3 + + when: + context = GraphQLContext.of(["k1": "v1", "k2": "v2"]) + + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + sizeOf(context) == 2 + + when: + context = GraphQLContext.of({ it.of("k1", "v1") } as Consumer) + + then: + context.get("k1") == "v1" + sizeOf(context) == 1 + } + + def "put works"() { + def context + when: + context = buildContext([k1: "v1"]) + context.put("k1", "v1delta") + then: + context.get("k1") == "v1delta" + context.hasKey("k1") + sizeOf(context) == 1 + } + + def "putAll works"() { + when: + def context = buildContext([k1: "v1"]) + def context2 = buildContext([k2: "v2"]) + context.putAll(context2) + + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + sizeOf(context) == 2 + + when: + context = buildContext([k1: "v1"]) + context.putAll([k2: "v2"]) + + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + sizeOf(context) == 2 + + when: + context = buildContext([k1: "v1"]) + context.putAll(GraphQLContext.newContext().of("k2", "v2")) + + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + sizeOf(context) == 2 + + when: + context = buildContext([k1: "v1"]) + context.putAll({ it.of([k2: "v2"]) } as Consumer) + + then: + context.get("k1") == "v1" + context.get("k2") == "v2" + sizeOf(context) == 2 + } + + def "hasKey works"() { + def context + when: + context = buildContext([k1: "v1", k2: "k2"]) + then: + context.hasKey("k1") + context.hasKey("k2") + !context.hasKey("k3") + } + + def "compute works"() { + def context + when: + context = buildContext([k1: "foo"]) + then: + context.compute("k1", (k, v) -> v ? v + "bar" : "default") == "foobar" + context.get("k1") == "foobar" + context.compute("k2", (k, v) -> v ? "new" : "default") == "default" + context.get("k2") == "default" + !context.compute("k3", (k, v) -> null) + !context.hasKey("k3") + sizeOf(context) == 2 + } + + def "computeIfAbsent works"() { + def context + when: + context = buildContext([k1: "v1", k2: "v2"]) + then: + context.computeIfAbsent("k1", k -> "default") == "v1" + context.get("k1") == "v1" + context.computeIfAbsent("k2", k -> null) == "v2" + context.get("k2") == "v2" + context.computeIfAbsent("k3", k -> "default") == "default" + context.get("k3") == "default" + !context.computeIfAbsent("k4", k -> null) + !context.hasKey("k4") + sizeOf(context) == 3 + } + + def "computeIfPresent works"() { + def context + when: + context = buildContext([k1: "foo", k2: "v2"]) + then: + context.computeIfPresent("k1", (k, v) -> v + "bar") == "foobar" + context.get("k1") == "foobar" + !context.computeIfPresent("k2", (k, v) -> null) + !context.hasKey("k2") + !context.computeIfPresent("k3", (k, v) -> v + "bar") + !context.hasKey("k3") + !context.computeIfPresent("k4", (k, v) -> null) + !context.hasKey("k4") + sizeOf(context) == 1 + } + + def "getOrDefault works"() { + def context + when: + context = buildContext([k1: "v1", k2: "k2"]) + then: + context.getOrDefault("k3", "default") == "default" + } + + def "getOrEmpty works"() { + def context + when: + context = buildContext([k1: "v1", k2: "k2"]) + then: + context.getOrEmpty("k1").isPresent() + context.getOrEmpty("k2").isPresent() + !context.getOrEmpty("k3").isPresent() + } + + def "stream works"() { + def context + when: + context = buildContext([k1: "v1", k2: "k2"]) + def keys = context.stream().map({ entry -> entry.key }).collect(Collectors.joining()) + then: + keys == "k1k2" + } + + def "delete works"() { + def context + when: + context = buildContext([k1: "v1"]) + context.delete("k1") + then: + !context.hasKey("k1") + context.get("k1") == null + context.getOrDefault("k1", "default") == "default" + + sizeOf(context) == 0 + } + + def "graphql context integration test"() { + def spec = ''' + type Query { + field : String + } + ''' + + DataFetcher df = { DataFetchingEnvironment env -> + GraphQLContext context = env.graphQlContext + return context.get("ctx1") + } + def graphQL = TestUtil.graphQL(spec, ["Query": ["field": df]]).build() + + ExecutionInput input = newExecutionInput().query("{ field }").build() + input.getGraphQLContext().putAll([ctx1: "ctx1value"]) + + when: + def executionResult = graphQL.execute(input) + then: + executionResult.errors.isEmpty() + executionResult.data == [field: "ctx1value"] + } + + def "boolean getters work"() { + when: + def context = GraphQLContext.newContext().of( + "f", false, + "t", true, + "notABool", "true" + ).build() + + then: + !context.getBoolean("f") + context.getBoolean("t") + !context.getBoolean("notABool") + !context.getBoolean("missing") + context.getBoolean("missing", true) + } +} diff --git a/src/test/groovy/graphql/GraphQLErrorTest.groovy b/src/test/groovy/graphql/GraphQLErrorTest.groovy index 3a772fb39a..cf80eb845f 100644 --- a/src/test/groovy/graphql/GraphQLErrorTest.groovy +++ b/src/test/groovy/graphql/GraphQLErrorTest.groovy @@ -1,10 +1,10 @@ package graphql -import graphql.execution.ExecutionPath -import graphql.execution.ExecutionTypeInfo +import graphql.execution.ExecutionStepInfo import graphql.execution.MissingRootTypeException import graphql.execution.NonNullableFieldWasNullError import graphql.execution.NonNullableFieldWasNullException +import graphql.execution.ResultPath import graphql.introspection.Introspection import graphql.language.SourceLocation import graphql.schema.CoercingSerializeException @@ -25,43 +25,95 @@ class GraphQLErrorTest extends Specification { where: gError | expectedMap - new ValidationError(ValidationErrorType.UnknownType, mkLocations(), "Test ValidationError") | + ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.UnknownType) + .sourceLocations(mkLocations()) + .description("Test ValidationError") + .build() | [ - locations: [[line: 666, column: 999], [line: 333, column: 0]], - message : "Validation error of type UnknownType: Test ValidationError", + locations: [[line: 666, column: 999], [line: 333, column: 1]], + message : "Test ValidationError", + extensions:[classification:"ValidationError"], ] new MissingRootTypeException("Mutations are not supported on this schema", null) | [ message: "Mutations are not supported on this schema", + extensions:[classification:"OperationNotSupported"], ] new InvalidSyntaxError(mkLocations(), "Not good syntax m'kay") | [ - locations: [[line: 666, column: 999], [line: 333, column: 0]], - message : "Invalid Syntax : Not good syntax m'kay", + locations: [[line: 666, column: 999], [line: 333, column: 1]], + message : "Not good syntax m'kay", + extensions:[classification:"InvalidSyntax"], ] new NonNullableFieldWasNullError(new NonNullableFieldWasNullException(mkTypeInfo(), mkPath())) | [ - message: 'Cannot return null for non-nullable type: \'__Schema\' (/heroes[0]/abilities/speed[4])', + message: '''The field at path '/heroes[0]/abilities/speed[4]' was declared as a non null type, but the code involved in retrieving data has wrongly returned a null value. The graphql specification requires that the parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on. The non-nullable type is '__Schema\'''', path : ["heroes", 0, "abilities", "speed", 4], + extensions:[classification:"NullValueInNonNullableField"], ] new SerializationError(mkPath(), new CoercingSerializeException("Bad coercing")) | [ message: "Can't serialize value (/heroes[0]/abilities/speed[4]) : Bad coercing", path : ["heroes", 0, "abilities", "speed", 4], + extensions:[classification:"DataFetchingException"], ] new ExceptionWhileDataFetching(mkPath(), new RuntimeException("Bang"), mkLocation(666, 999)) | [locations: [[line: 666, column: 999]], message : "Exception while fetching data (/heroes[0]/abilities/speed[4]) : Bang", path : ["heroes", 0, "abilities", "speed", 4], + extensions:[classification:"DataFetchingException"], ] } + def "toSpecification filters out error locations with line and column not starting at 1, as required in spec"() { + // See specification wording: https://spec.graphql.org/draft/#sec-Errors.Error-Result-Format + + given: + def error = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.UnknownType) + .sourceLocations([mkLocation(-1, -1), mkLocation(333, 1)]) + .description("Test ValidationError") + .build() + + def expectedMap = [ + locations: [ + [line: 333, column: 1] + ], + message: "Test ValidationError", + extensions: [classification:"ValidationError"] + ] + + expect: + error.toSpecification() == expectedMap + } + + def "toSpecification filters out null error locations"() { + given: + def error = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.UnknownType) + .sourceLocations([null, mkLocation(333, 1)]) + .description("Test ValidationError") + .build() + + def expectedMap = [ + locations: [ + [line: 333, column: 1] + ], + message: "Test ValidationError", + extensions: [classification:"ValidationError"] + ] + + expect: + error.toSpecification() == expectedMap + } + class CustomException extends RuntimeException implements GraphQLError { private LinkedHashMap map @@ -100,15 +152,15 @@ class GraphQLErrorTest extends Specification { } List mkLocations() { - return [mkLocation(666, 999), mkLocation(333, 0)] + return [mkLocation(666, 999), mkLocation(333, 1)] } SourceLocation mkLocation(int line, int column) { return new SourceLocation(line, column) } - ExecutionPath mkPath() { - return ExecutionPath.rootPath() + ResultPath mkPath() { + return ResultPath.rootPath() .segment("heroes") .segment(0) .segment("abilities") @@ -116,8 +168,8 @@ class GraphQLErrorTest extends Specification { .segment(4) } - ExecutionTypeInfo mkTypeInfo() { - return ExecutionTypeInfo.newTypeInfo() + ExecutionStepInfo mkTypeInfo() { + return ExecutionStepInfo.newExecutionStepInfo() .type(Introspection.__Schema) .path(mkPath()) .build() diff --git a/src/test/groovy/graphql/GraphQLTest.groovy b/src/test/groovy/graphql/GraphQLTest.groovy index b4a8f97e96..7b9c48ad7d 100644 --- a/src/test/groovy/graphql/GraphQLTest.groovy +++ b/src/test/groovy/graphql/GraphQLTest.groovy @@ -3,37 +3,53 @@ package graphql import graphql.analysis.MaxQueryComplexityInstrumentation import graphql.analysis.MaxQueryDepthInstrumentation import graphql.execution.AsyncExecutionStrategy +import graphql.execution.AsyncSerialExecutionStrategy +import graphql.execution.DataFetcherExceptionHandler +import graphql.execution.DataFetcherExceptionHandlerParameters +import graphql.execution.DataFetcherExceptionHandlerResult +import graphql.execution.DataFetcherResult import graphql.execution.ExecutionContext import graphql.execution.ExecutionId import graphql.execution.ExecutionIdProvider import graphql.execution.ExecutionStrategyParameters -import graphql.execution.MissingRootTypeException -import graphql.execution.batched.BatchedExecutionStrategy +import graphql.execution.ResultNodesInfo +import graphql.execution.SubscriptionExecutionStrategy +import graphql.execution.ValueUnboxer import graphql.execution.instrumentation.Instrumentation -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters +import graphql.execution.preparsed.NoOpPreparsedDocumentProvider import graphql.language.SourceLocation import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLEnumType import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLInterfaceType -import graphql.schema.GraphQLList import graphql.schema.GraphQLNonNull import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLSchema +import graphql.schema.LightDataFetcher import graphql.schema.StaticDataFetcher +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.errors.SchemaProblem +import graphql.schema.validation.InvalidSchemaException import graphql.validation.ValidationError import graphql.validation.ValidationErrorType import spock.lang.Specification import spock.lang.Unroll import java.util.concurrent.CompletableFuture +import java.util.function.Supplier import java.util.function.UnaryOperator import static graphql.ExecutionInput.Builder import static graphql.ExecutionInput.newExecutionInput import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString +import static graphql.execution.ResultNodesInfo.MAX_RESULT_NODES import static graphql.schema.GraphQLArgument.newArgument import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLInputObjectField.newInputObjectField @@ -45,17 +61,23 @@ import static graphql.schema.GraphQLTypeReference.typeRef class GraphQLTest extends Specification { - GraphQLSchema simpleSchema() { + static GraphQLSchema simpleSchema() { GraphQLFieldDefinition.Builder fieldDefinition = newFieldDefinition() .name("hello") .type(GraphQLString) - .staticValue("world") - GraphQLSchema schema = newSchema().query( - newObject() + FieldCoordinates fieldCoordinates = FieldCoordinates.coordinates("RootQueryType", "hello") + DataFetcher dataFetcher = { env -> "world" } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fieldCoordinates, dataFetcher) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() .name("RootQueryType") .field(fieldDefinition) - .build() - ).build() + .build()) + .build() schema } @@ -68,7 +90,6 @@ class GraphQLTest extends Specification { then: result == [hello: 'world'] - } def "query with sub-fields"() { @@ -76,26 +97,32 @@ class GraphQLTest extends Specification { GraphQLObjectType heroType = newObject() .name("heroType") .field( - newFieldDefinition() - .name("id") - .type(GraphQLString)) + newFieldDefinition() + .name("id") + .type(GraphQLString)) .field( - newFieldDefinition() - .name("name") - .type(GraphQLString)) + newFieldDefinition() + .name("name") + .type(GraphQLString)) .build() GraphQLFieldDefinition.Builder simpsonField = newFieldDefinition() .name("simpson") .type(heroType) - .staticValue([id: '123', name: 'homer']) - GraphQLSchema graphQLSchema = newSchema().query( - newObject() + FieldCoordinates fieldCoordinates = FieldCoordinates.coordinates("RootQueryType", "simpson") + DataFetcher dataFetcher = { env -> [id: '123', name: 'homer'] } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fieldCoordinates, dataFetcher) + .build() + + GraphQLSchema graphQLSchema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() .name("RootQueryType") .field(simpsonField) - .build() - ).build() + .build()) + .build() when: def result = GraphQL.newGraphQL(graphQLSchema).build().execute('{ simpson { id, name } }').data @@ -110,13 +137,20 @@ class GraphQLTest extends Specification { .name("hello") .type(GraphQLString) .argument(newArgument().name("arg").type(GraphQLString)) - .staticValue("world") - GraphQLSchema schema = newSchema().query( - newObject() + + FieldCoordinates fieldCoordinates = FieldCoordinates.coordinates("RootQueryType", "hello") + DataFetcher dataFetcher = { env -> "hello" } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fieldCoordinates, dataFetcher) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() .name("RootQueryType") .field(fieldDefinition) - .build() - ).build() + .build()) + .build() when: def errors = GraphQL.newGraphQL(schema).build().execute('{ hello(arg:11) }').errors @@ -130,6 +164,12 @@ class GraphQLTest extends Specification { GraphQLSchema schema = newSchema().query( newObject() .name("RootQueryType") + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)))) .build() ).build() @@ -139,7 +179,7 @@ class GraphQLTest extends Specification { then: errors.size() == 1 errors[0].errorType == ErrorType.InvalidSyntax - errors[0].locations == [new SourceLocation(1, 8)] + errors[0].locations == [new SourceLocation(1, 9)] } def "query with invalid syntax 2"() { @@ -147,6 +187,12 @@ class GraphQLTest extends Specification { GraphQLSchema schema = newSchema().query( newObject() .name("RootQueryType") + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)))) .build() ).build() @@ -156,7 +202,32 @@ class GraphQLTest extends Specification { then: errors.size() == 1 errors[0].errorType == ErrorType.InvalidSyntax - errors[0].locations == [new SourceLocation(1, 7)] + errors[0].locations == [new SourceLocation(1, 8)] + } + + def "query with invalid Unicode surrogate in argument - no trailing value"() { + given: + GraphQLSchema schema = newSchema().query( + newObject() + .name("RootQueryType") + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)))) + .build() + ).build() + + when: + // Invalid Unicode character - leading surrogate value without trailing surrogate value + def errors = GraphQL.newGraphQL(schema).build().execute('{ hello(arg:"\\ud83c") }').errors + + then: + errors.size() == 1 + errors[0].errorType == ErrorType.InvalidSyntax + errors[0].message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\ud83c' at line 1 column 13" + errors[0].locations == [new SourceLocation(1, 13)] } def "non null argument is missing"() { @@ -165,11 +236,11 @@ class GraphQLTest extends Specification { newObject() .name("RootQueryType") .field(newFieldDefinition() - .name("field") - .type(GraphQLString) - .argument(newArgument() - .name("arg") - .type(GraphQLNonNull.nonNull(GraphQLString)))) + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)))) .build() ).build() @@ -189,14 +260,22 @@ class GraphQLTest extends Specification { set.add("One") set.add("Two") + def queryType = "QueryType" + def fieldName = "set" + def fieldCoordinates = FieldCoordinates.coordinates(queryType, fieldName) + DataFetcher dataFetcher = { set } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fieldCoordinates, dataFetcher) + .build() + def schema = newSchema() + .codeRegistry(codeRegistry) .query(newObject() - .name("QueryType") - .field(newFieldDefinition() - .name("set") - .type(list(GraphQLString)) - .dataFetcher({ set }))) - .build() + .name(queryType) + .field(newFieldDefinition() + .name(fieldName) + .type(list(GraphQLString))) + ).build() when: def data = GraphQL.newGraphQL(schema).build().execute("query { set }").data @@ -208,14 +287,30 @@ class GraphQLTest extends Specification { def "document with two operations executes specified operation"() { given: - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field(newFieldDefinition().name("field1").type(GraphQLString).dataFetcher(new StaticDataFetcher("value1"))) - .field(newFieldDefinition().name("field2").type(GraphQLString).dataFetcher(new StaticDataFetcher("value2"))) - ) + def queryType = "RootQueryType" + def field1Name = "field1" + def field2Name = "field2" + def field1Coordinates = FieldCoordinates.coordinates(queryType, field1Name) + def field2Coordinates = FieldCoordinates.coordinates(queryType, field2Name) + DataFetcher field1DataFetcher = new StaticDataFetcher("value1") + DataFetcher field2DataFetcher = new StaticDataFetcher("value2") + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(field1Coordinates, field1DataFetcher) + .dataFetcher(field2Coordinates, field2DataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(field1Name) + .type(GraphQLString)) + .field(newFieldDefinition() + .name(field2Name) + .type(GraphQLString)) + ).build() + def query = """ query Query1 { field1 } query Query2 { field2 } @@ -224,7 +319,7 @@ class GraphQLTest extends Specification { def expected = [field2: 'value2'] when: - def executionInput = newExecutionInput().query(query).operationName('Query2').context(null).variables([:]) + def executionInput = newExecutionInput().query(query).operationName('Query2').variables([:]) def result = GraphQL.newGraphQL(schema).build().execute(executionInput) then: @@ -232,7 +327,7 @@ class GraphQLTest extends Specification { result.errors.size() == 0 } - def "document with two operations but no specified operation throws"() { + def "document with two operations but no specified operation does not throw"() { given: GraphQLSchema schema = newSchema().query( @@ -248,27 +343,35 @@ class GraphQLTest extends Specification { """ when: - GraphQL.newGraphQL(schema).build().execute(query) + def er = GraphQL.newGraphQL(schema).build().execute(query) then: - thrown(GraphQLException) + noExceptionThrown() + !er.errors.isEmpty() + er.errors[0].message.contains("Must provide operation name if query contains multiple operations") } - def "null mutation type does not throw an npe re: #345 but returns and error"() { + def "null mutation type does not throw an npe but returns and error"() { given: GraphQLSchema schema = newSchema().query( newObject() + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)))) .name("Query") ) .build() when: - def result = new GraphQL(schema).execute("mutation { doesNotExist }") + def result = GraphQL.newGraphQL(schema).build().execute("mutation { doesNotExist }") then: result.errors.size() == 1 - result.errors[0].class == MissingRootTypeException + ((ValidationError) result.errors[0]).validationErrorType == ValidationErrorType.UnknownOperation } def "#875 a subscription query against a schema that doesn't support subscriptions should result in a GraphQL error"() { @@ -277,253 +380,304 @@ class GraphQLTest extends Specification { GraphQLSchema schema = newSchema().query( newObject() .name("Query") + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)))) ) .build() when: - def result = new GraphQL(schema).execute("subscription { doesNotExist }") + def result = GraphQL.newGraphQL(schema).build().execute("subscription { doesNotExist }") then: result.errors.size() == 1 - result.errors[0].class == MissingRootTypeException + ((ValidationError) result.errors[0]).validationErrorType == ValidationErrorType.UnknownOperation } def "query with int literal too large"() { given: - GraphQLSchema schema = newSchema().query( - newObject() + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + DataFetcher dataFetcher = { env -> env.getArgument("bar") } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() .name("QueryType") - .field( - newFieldDefinition() + .field(newFieldDefinition() .name("foo") .type(GraphQLInt) - .argument(newArgument().name("bar").type(GraphQLInt).build()) - .dataFetcher({ return it.getArgument("bar") }) - )) - .build() + .argument(newArgument().name("bar").type(GraphQLInt).build())) + ).build() def query = "{foo(bar: 12345678910)}" + when: def result = GraphQL.newGraphQL(schema).build().execute(query) then: result.errors.size() == 1 - result.errors[0].description == "argument 'bar' with value 'IntValue{value=12345678910}' is not a valid 'Int'" + result.errors[0].message == "Validation error (WrongType@[foo]) : argument 'bar' with value 'IntValue{value=12345678910}' is not a valid 'Int' - Expected value to be in the integer range, but it was a '12345678910'" } @SuppressWarnings("GroovyAssignabilityCheck") def "query with missing argument results in arguments map missing the key"() { given: - def dataFetcher = Mock(DataFetcher) - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(GraphQLInt).build()) - .dataFetcher(dataFetcher) - )) + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(GraphQLInt).build())) + ).build() def query = "{foo}" + when: GraphQL.newGraphQL(schema).build().execute(query) then: - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - assert !env.arguments.containsKey('bar') + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert !env.arguments.containsKey('bar') } } @SuppressWarnings("GroovyAssignabilityCheck") def "query with null argument results in arguments map with value null "() { given: - def dataFetcher = Mock(DataFetcher) - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(GraphQLInt).build()) - .dataFetcher(dataFetcher) - )) + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(GraphQLInt).build())) + ).build() def query = "{foo(bar: null)}" - DataFetchingEnvironment dataFetchingEnvironment + when: GraphQL.newGraphQL(schema).build().execute(query) then: - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - dataFetchingEnvironment = env - assert env.arguments.containsKey('bar') - assert env.arguments['bar'] == null + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert env.arguments.containsKey('bar') + assert env.arguments['bar'] == null } } @SuppressWarnings("GroovyAssignabilityCheck") def "query with missing key in an input object result in a map with missing key"() { given: - def dataFetcher = Mock(DataFetcher) def inputObject = newInputObject().name("bar") .field(newInputObjectField().name("someKey").type(GraphQLString).build()) .field(newInputObjectField().name("otherKey").type(GraphQLString).build()).build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(inputObject).build()) - .dataFetcher(dataFetcher) - )) + + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(inputObject).build())) + ).build() def query = "{foo(bar: {someKey: \"value\"})}" when: def result = GraphQL.newGraphQL(schema).build().execute(query) then: result.errors.size() == 0 - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - assert env.arguments.size() == 1 - assert env.arguments["bar"] instanceof Map - assert env.arguments['bar']['someKey'] == 'value' - assert !(env.arguments['bar'] as Map).containsKey('otherKey') + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert env.arguments.size() == 1 + assert env.arguments["bar"] instanceof Map + assert env.arguments['bar']['someKey'] == 'value' + assert !(env.arguments['bar'] as Map).containsKey('otherKey') } } @SuppressWarnings("GroovyAssignabilityCheck") def "query with null value in an input object result in a map with null as value"() { given: - def dataFetcher = Mock(DataFetcher) def inputObject = newInputObject().name("bar") .field(newInputObjectField().name("someKey").type(GraphQLString).build()) .field(newInputObjectField().name("otherKey").type(GraphQLString).build()).build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(inputObject).build()) - .dataFetcher(dataFetcher) - )) + + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(inputObject).build())) + ).build() def query = "{foo(bar: {someKey: \"value\", otherKey: null})}" + when: def result = GraphQL.newGraphQL(schema).build().execute(query) then: result.errors.size() == 0 - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - assert env.arguments.size() == 1 - assert env.arguments["bar"] instanceof Map - assert env.arguments['bar']['someKey'] == 'value' - assert (env.arguments['bar'] as Map).containsKey('otherKey') - assert env.arguments['bar']['otherKey'] == null + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert env.arguments.size() == 1 + assert env.arguments["bar"] instanceof Map + assert env.arguments['bar']['someKey'] == 'value' + assert (env.arguments['bar'] as Map).containsKey('otherKey') + assert env.arguments['bar']['otherKey'] == null } } def "query with missing List input field results in a map with a missing key"() { given: - def dataFetcher = Mock(DataFetcher) def inputObject = newInputObject().name("bar") .field(newInputObjectField().name("list").type(list(GraphQLString)).build()) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(inputObject).build()) - .dataFetcher(dataFetcher) - )) + + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(inputObject).build())) + ).build() def query = "{foo(bar: {})}" + when: def result = GraphQL.newGraphQL(schema).build().execute(query) then: result.errors.size() == 0 - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - assert env.arguments.size() == 1 - assert env.arguments["bar"] instanceof Map - assert !(env.arguments['bar'] as Map).containsKey('list') + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert env.arguments.size() == 1 + assert env.arguments["bar"] instanceof Map + assert !(env.arguments['bar'] as Map).containsKey('list') } } def "query with null List input field results in a map with null as key"() { given: - def dataFetcher = Mock(DataFetcher) def inputObject = newInputObject().name("bar") .field(newInputObjectField().name("list").type(list(GraphQLString)).build()) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(inputObject).build()) - .dataFetcher(dataFetcher) - )) + + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(inputObject).build())) + ).build() def query = "{foo(bar: {list: null})}" + when: def result = GraphQL.newGraphQL(schema).build().execute(query) then: result.errors.size() == 0 - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - assert env.arguments.size() == 1 - assert env.arguments["bar"] instanceof Map - assert (env.arguments['bar'] as Map).containsKey('list') - assert env.arguments['bar']['list'] == null + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert env.arguments.size() == 1 + assert env.arguments["bar"] instanceof Map + assert (env.arguments['bar'] as Map).containsKey('list') + assert env.arguments['bar']['list'] == null } } def "query with List containing null input field results in a map with a list containing null"() { given: - def dataFetcher = Mock(DataFetcher) def inputObject = newInputObject().name("bar") .field(newInputObjectField().name("list").type(list(GraphQLString)).build()) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("QueryType") - .field( - newFieldDefinition() - .name("foo") - .type(GraphQLInt) - .argument(newArgument().name("bar").type(inputObject).build()) - .dataFetcher(dataFetcher) - )) + + def queryType = "QueryType" + def fooName = "foo" + def fooCoordinates = FieldCoordinates.coordinates(queryType, fooName) + def dataFetcher = Mock(LightDataFetcher) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) + .field(newFieldDefinition() + .name(fooName) + .type(GraphQLInt) + .argument(newArgument().name("bar").type(inputObject).build())) + ).build() def query = "{foo(bar: {list: [null]})}" + when: def result = GraphQL.newGraphQL(schema).build().execute(query) then: result.errors.size() == 0 - 1 * dataFetcher.get(_) >> { - DataFetchingEnvironment env -> - assert env.arguments.size() == 1 - assert env.arguments["bar"] instanceof Map - assert (env.arguments['bar'] as Map).containsKey('list') - assert env.arguments['bar']['list'] == [null] + 1 * dataFetcher.get(_, _, _) >> { + def env = (it[2] as Supplier).get() + assert env.arguments.size() == 1 + assert env.arguments["bar"] instanceof Map + assert (env.arguments['bar'] as Map).containsKey('list') + assert env.arguments['bar']['list'] == [null] } } @@ -544,9 +698,9 @@ class GraphQLTest extends Specification { GraphQLObjectType queryType = newObject() .name("QueryType") .field(newFieldDefinition() - .name("query") - .argument(newArgument().name("fooParam").type(enumType)) - .type(GraphQLInt)) + .name("query") + .argument(newArgument().name("fooParam").type(enumType)) + .type(GraphQLInt)) .build() GraphQLSchema schema = newSchema() @@ -561,7 +715,6 @@ class GraphQLTest extends Specification { } - def "execution input passing builder"() { given: GraphQLSchema schema = simpleSchema() @@ -579,7 +732,6 @@ class GraphQLTest extends Specification { GraphQLSchema schema = simpleSchema() when: - def builderFunction = { it.query('{hello}') } as UnaryOperator def result = GraphQL.newGraphQL(schema).build().execute(builderFunction).data @@ -618,21 +770,21 @@ class GraphQLTest extends Specification { def foo = newObject() .name("Foo") .field(newFieldDefinition() - .name("field") - .type(typeRef('Foo')) - .build()) + .name("field") + .type(typeRef('Foo')) + .build()) .field(newFieldDefinition() - .name("scalar") - .type(GraphQLString) - .build()) + .name("scalar") + .type(GraphQLString) + .build()) .build() GraphQLSchema schema = newSchema().query( newObject() .name("RootQueryType") .field(newFieldDefinition() - .name("field") - .type(foo) - .build()).build()) + .name("field") + .type(foo) + .build()).build()) .build() MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(3) @@ -662,21 +814,21 @@ class GraphQLTest extends Specification { def foo = newObject() .name("Foo") .field(newFieldDefinition() - .name("field") - .type(typeRef('Foo')) - .build()) + .name("field") + .type(typeRef('Foo')) + .build()) .field(newFieldDefinition() - .name("scalar") - .type(GraphQLString) - .build()) + .name("scalar") + .type(GraphQLString) + .build()) .build() GraphQLSchema schema = newSchema().query( newObject() .name("RootQueryType") .field(newFieldDefinition() - .name("field") - .type(foo) - .build()).build()) + .name("field") + .type(foo) + .build()).build()) .build() MaxQueryComplexityInstrumentation maxQueryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(3) @@ -706,35 +858,39 @@ class GraphQLTest extends Specification { .name("Foo") .withInterface(typeRef("Node")) .field( - { field -> - field - .name("id") - .type(Scalars.GraphQLID) - } as UnaryOperator) + { field -> + field + .name("id") + .type(Scalars.GraphQLID) + } as UnaryOperator) .build() GraphQLInterfaceType node = GraphQLInterfaceType.newInterface() .name("Node") .field( - { field -> - field - .name("id") - .type(Scalars.GraphQLID) - } as UnaryOperator) - .typeResolver({ type -> foo }) + { field -> + field + .name("id") + .type(Scalars.GraphQLID) + } as UnaryOperator) .build() GraphQLObjectType query = newObject() .name("RootQuery") .field( - { field -> - field - .name("a") - .type(node) - } as UnaryOperator) + { field -> + field + .name("a") + .type(node) + } as UnaryOperator) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(node, { type -> foo }) .build() GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) .query(query) .build() @@ -751,7 +907,7 @@ class GraphQLTest extends Specification { then: result.errors.size() == 1 - result.errors[0].message.contains("Sub selection required") + result.errors[0].message.contains("Subselection required") where: instrumentationName | instrumentation @@ -759,79 +915,6 @@ class GraphQLTest extends Specification { 'max query complexity' | new MaxQueryComplexityInstrumentation(10) } - - def "batched execution with non batched DataFetcher returning CompletableFuture"() { - given: - GraphQLObjectType foo = newObject() - .name("Foo") - .withInterface(typeRef("Node")) - .field( - { field -> - field - .name("id") - .type(Scalars.GraphQLID) - } as UnaryOperator) - .build() - - GraphQLInterfaceType node = GraphQLInterfaceType.newInterface() - .name("Node") - .field( - { field -> - field - .name("id") - .type(Scalars.GraphQLID) - } as UnaryOperator) - .typeResolver( - { - env -> - if (env.getObject() instanceof CompletableFuture) { - throw new RuntimeException("This seems bad!") - } - - return foo - }) - .build() - - GraphQLObjectType query = newObject() - .name("RootQuery") - .field( - { field -> - field - .name("node") - .dataFetcher( - { env -> - CompletableFuture.supplyAsync({ -> - Map map = new HashMap<>() - map.put("id", "abc") - - return map - }) - }) - .type(node) - } as UnaryOperator) - .build() - - GraphQLSchema schema = newSchema() - .query(query) - .additionalType(foo) - .build() - - GraphQL graphQL = GraphQL.newGraphQL(schema) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .mutationExecutionStrategy(new BatchedExecutionStrategy()) - .build() - - ExecutionInput executionInput = newExecutionInput() - .query("{node {id}}") - .build() - when: - def result = graphQL - .execute(executionInput) - - then: - result.getData() == [node: [id: "abc"]] - } - class CaptureStrategy extends AsyncExecutionStrategy { ExecutionId executionId = null Instrumentation instrumentation = null @@ -846,7 +929,7 @@ class GraphQLTest extends Specification { def "graphql copying works as expected"() { - def instrumentation = new SimpleInstrumentation() + def instrumentation = new SimplePerformantInstrumentation() def hello = ExecutionId.from("hello") def executionIdProvider = new ExecutionIdProvider() { @Override @@ -870,12 +953,13 @@ class GraphQLTest extends Specification { then: result == [hello: 'world'] queryStrategy.executionId == hello + queryStrategy.instrumentation instanceof Instrumentation queryStrategy.instrumentation == instrumentation when: // now make some changes - def newInstrumentation = new SimpleInstrumentation() + def newInstrumentation = new SimplePerformantInstrumentation() def goodbye = ExecutionId.from("goodbye") def newExecutionIdProvider = new ExecutionIdProvider() { @Override @@ -892,23 +976,49 @@ class GraphQLTest extends Specification { then: result == [hello: 'world'] queryStrategy.executionId == goodbye - queryStrategy.instrumentation == newInstrumentation + queryStrategy.instrumentation instanceof SimplePerformantInstrumentation + newGraphQL.instrumentation == newInstrumentation + } + + def "provided instrumentation is unchanged"() { + given: + def queryStrategy = new CaptureStrategy() + def instrumentation = new SimplePerformantInstrumentation() + def builder = GraphQL.newGraphQL(simpleSchema()) + .queryExecutionStrategy(queryStrategy) + .instrumentation(instrumentation) + + when: + def graphql = builder + .build() + graphql.execute('{ hello }') + + then: + queryStrategy.instrumentation == instrumentation } def "query with triple quoted multi line strings"() { given: + def queryType = "Query" + def fieldName = "hello" + def fieldCoordinates = FieldCoordinates.coordinates(queryType, fieldName) + DataFetcher dataFetcher = { env -> env.getArgument("arg") } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fieldCoordinates, dataFetcher) + .build() + GraphQLFieldDefinition.Builder fieldDefinition = newFieldDefinition() - .name("hello") + .name(fieldName) .type(GraphQLString) .argument(newArgument().name("arg").type(GraphQLString)) - .dataFetcher({ env -> env.getArgument("arg") } - ) - GraphQLSchema schema = newSchema().query( - newObject() - .name("Query") + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryType) .field(fieldDefinition) - .build() - ).build() + .build()) + .build() when: def result = GraphQL.newGraphQL(schema).build().execute('''{ hello(arg:""" @@ -921,4 +1031,578 @@ many lines""") }''') over many lines'''] } + + def "executionId is set before being passed to instrumentation"() { + InstrumentationCreateStateParameters seenParams + + def instrumentation = new Instrumentation() { + + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters params) { + seenParams = params + null + } + } + + when: + GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(instrumentation) + .build() + .execute("{ __typename }") + + then: + seenParams.executionInput.executionId != null + } + + def "variables map can't be null via ExecutionInput"() { + given: + + when: + def input = newExecutionInput().query('query($var:String){ hello(arg: $var) }').variables(null).build() + + then: + def assEx = thrown(AssertException) + assEx.message.contains("variables map can't be null") + } + + def "query can't be null via ExecutionInput"() { + given: + + when: + def input = newExecutionInput().query(null).build() + + then: + def assEx = thrown(AssertException) + assEx.message.contains("query can't be null") + } + + def "query must be set via ExecutionInput"() { + given: + + when: + def input = newExecutionInput().query().build() + + then: + def assEx = thrown(AssertException) + assEx.message.contains("query can't be null") + + + } + + def "default argument values are respected when variable is not provided"() { + given: + def spec = """type Query { + sayHello(name: String = "amigo"): String + }""" + def df = { dfe -> + return dfe.getArgument("name") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def data = graphQL.execute('query($var:String){sayHello(name:$var)}').getData() + + then: + data == [sayHello: "amigo"] + + } + + def "default variable values are respected"() { + given: + def spec = """type Query { + sayHello(name: String): String + }""" + def df = { dfe -> + return dfe.getArgument("name") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def data = graphQL.execute('query($var:String = "amigo"){sayHello(name:$var)}').getData() + + then: + data == [sayHello: "amigo"] + + } + + def "default variable values are respected for non null arguments"() { + given: + def spec = """type Query { + sayHello(name: String!): String + }""" + def df = { dfe -> + return dfe.getArgument("name") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def data = graphQL.execute('query($var:String! = "amigo"){sayHello(name:$var)}').getData() + + then: + data == [sayHello: "amigo"] + + } + + def "null as default variable value is used"() { + given: + def spec = """type Query { + sayHello(name: String): String + }""" + def df = { dfe -> + boolean isNullValue = dfe.containsArgument("name") && dfe.getArgument("name") == null + return isNullValue ? "is null" : "error" + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def data = graphQL.execute('query($var:String = null){sayHello(name:$var)}').getData() + + then: + data == [sayHello: "is null"] + + } + + def "null as default argument value is used with no provided variable"() { + given: + def spec = """type Query { + sayHello(name: String = null): String + }""" + def df = { dfe -> + boolean isNullValue = dfe.containsArgument("name") && dfe.getArgument("name") == null + return isNullValue ? "is null" : "error" + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def data = graphQL.execute('query($var:String){sayHello(name:$var)}').getData() + + then: + data == [sayHello: "is null"] + + } + + def "not provided variable results in not provided argument"() { + given: + def spec = """type Query { + sayHello(name: String): String + }""" + def df = { dfe -> + return !dfe.containsArgument("name") ? "not provided" : "error" + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def data = graphQL.execute('query($var:String){sayHello(name:$var)}').getData() + + then: + data == [sayHello: "not provided"] + + } + + def "null variable default value produces error for non null argument"() { + given: + def spec = """type Query { + sayHello(name: String!): String + }""" + def df = { dfe -> + return dfe.getArgument("name") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def errors = graphQL.execute('query($var:String=null){sayHello(name:$var)}').getErrors() + + then: + errors.size() == 1 + + } + + def "default value defined in the schema is used when none provided in the query"() { + // Spec (https://spec.graphql.org/June2018/#sec-All-Variable-Usages-are-Allowed): A notable exception to typical variable type compatibility is allowing a variable definition with a nullable type to be provided to a non‐null location as long as either that variable or that location provides a default value. + given: + def spec = """type Query { + sayHello(name: String! = "amigo"): String + }""" + def df = { dfe -> + return dfe.getArgument("name") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def result = graphQL.execute('query($var:String){sayHello(name:$var)}') + + then: + result.errors.isEmpty() + result.getData() == [sayHello: "amigo"] + + } + + def "specified url can be defined and queried via introspection"() { + given: + GraphQLSchema schema = TestUtil.schema('type Query {foo: MyScalar} scalar MyScalar @specifiedBy(url:"myUrl")') + + when: + def result = GraphQL.newGraphQL(schema).build().execute('{__type(name: "MyScalar") {name specifiedByURL}}').getData() + + then: + result == [__type: [name: "MyScalar", specifiedByURL: "myUrl"]] + } + + def "test DFR and CF"() { + def sdl = 'type Query { f : String } ' + + DataFetcher df = { env -> + + def dfr = DataFetcherResult.newResult().data("hi").build() + return CompletableFuture.supplyAsync({ -> dfr }) + } + def schema = TestUtil.schema(sdl, [Query: [f: df]]) + def graphQL = GraphQL.newGraphQL(schema).build() + when: + def er = graphQL.execute("{f}") + then: + er.data["f"] == "hi" + } + + + def "can set default fetcher exception handler"() { + + + def sdl = 'type Query { f : String } ' + + DataFetcher df = { env -> + throw new RuntimeException("BANG!") + } + def capturedMsg = null + def exceptionHandler = new DataFetcherExceptionHandler() { + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters params) { + capturedMsg = params.exception.getMessage() + return CompletableFuture.completedFuture(DataFetcherExceptionHandlerResult.newResult().build()) + } + } + def schema = TestUtil.schema(sdl, [Query: [f: df]]) + def graphQL = GraphQL.newGraphQL(schema).defaultDataFetcherExceptionHandler(exceptionHandler).build() + when: + graphQL.execute("{f}") + then: + capturedMsg == "BANG!" + } + + def "invalid argument literal"() { + def sdl = ''' + type Query { + foo(arg: Input): String + } + input Input { + required: String! + } + ''' + + def schema = TestUtil.schema(sdl) + def graphQL = GraphQL.newGraphQL(schema).build() + when: + def executionResult = graphQL.execute("{foo(arg:{})}") + then: + executionResult.errors.size() == 1 + executionResult.errors[0].message.contains("is missing required fields") + } + + def "invalid default value for argument via SDL"() { + given: + def sdl = ''' + type Query { + foo(arg: Input = {}): String + } + input Input { + required: String! + } + ''' + when: + def schema = TestUtil.schema(sdl) + then: + def e = thrown(InvalidSchemaException) + e.message.contains("Invalid default value") + } + + def "invalid default value for argument programmatically"() { + given: + def arg = newArgument().name("arg").type(GraphQLInt).defaultValueProgrammatic(new LinkedHashMap()).build() + def field = newFieldDefinition() + .name("hello") + .type(GraphQLString) + .argument(arg) + .build() + when: + newSchema().query( + newObject() + .name("Query") + .field(field) + .build()) + .build() + then: + def e = thrown(InvalidSchemaException) + e.message.contains("Invalid default value") + } + + def "invalid default value for input objects via SDL"() { + given: + def sdl = ''' + type Query { + foo(arg: Input ={required: null}): String + } + input Input { + required: String! + } + ''' + when: + def schema = TestUtil.schema(sdl) + then: + def e = thrown(InvalidSchemaException) + e.message.contains("Invalid default value") + } + + def "invalid default value for input object programmatically"() { + given: + def defaultValue = [required: null] + def inputObject = newInputObject().name("Input").field( + newInputObjectField().name("required").type(GraphQLNonNull.nonNull(GraphQLString)).build()) + .build() + def arg = newArgument().name("arg") + .type(inputObject) + .defaultValueProgrammatic(defaultValue).build() + def field = newFieldDefinition() + .name("hello") + .type(GraphQLString) + .argument(arg) + .build() + when: + newSchema().query( + newObject() + .name("Query") + .field(field) + .build()) + .build() + then: + def e = thrown(InvalidSchemaException) + e.message.contains("Invalid default value") + } + + def "Applied schema directives arguments are validated for SDL"() { + given: + def sdl = ''' + directive @cached( + key: String + ) on FIELD_DEFINITION + + type Query { + hello: String @cached(key: {foo: "bar"}) + } + ''' + when: + SchemaGenerator.createdMockedSchema(sdl) + then: + def e = thrown(SchemaProblem) + e.message.contains("an illegal value for the argument ") + } + + def "getters work as expected"() { + Instrumentation instrumentation = new SimplePerformantInstrumentation() + when: + def graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).instrumentation(instrumentation).build() + then: + graphQL.getGraphQLSchema() == StarWarsSchema.starWarsSchema + graphQL.getIdProvider() == ExecutionIdProvider.DEFAULT_EXECUTION_ID_PROVIDER + graphQL.getValueUnboxer() == ValueUnboxer.DEFAULT + graphQL.getPreparsedDocumentProvider() == NoOpPreparsedDocumentProvider.INSTANCE + graphQL.getInstrumentation() instanceof Instrumentation + graphQL.getQueryStrategy() instanceof AsyncExecutionStrategy + graphQL.getMutationStrategy() instanceof AsyncSerialExecutionStrategy + graphQL.getSubscriptionStrategy() instanceof SubscriptionExecutionStrategy + } + + def "null locale on input is handled under the covers"() { + + def graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build() + def ei = newExecutionInput("query q { validationError } ").locale(null).build() + + when: + def er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + } + + def "max result nodes not breached"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> "world" } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello h1: hello h2: hello h3: hello } " + def ei = newExecutionInput(query).build() + ei.getGraphQLContext().put(MAX_RESULT_NODES, 4); + + when: + def er = graphQL.execute(ei) + def rni = ei.getGraphQLContext().get(ResultNodesInfo.RESULT_NODES_INFO) as ResultNodesInfo + then: + !rni.maxResultNodesExceeded + rni.resultNodesCount == 4 + er.data == [hello: "world", h1: "world", h2: "world", h3: "world"] + } + + def "max result nodes breached"() { + given: + def sdl = ''' + + type Query { + hello: String + } + ''' + def df = { env -> "world" } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello h1: hello h2: hello h3: hello } " + def ei = newExecutionInput(query).build() + ei.getGraphQLContext().put(MAX_RESULT_NODES, 3); + + when: + def er = graphQL.execute(ei) + def rni = ei.getGraphQLContext().get(ResultNodesInfo.RESULT_NODES_INFO) as ResultNodesInfo + then: + rni.maxResultNodesExceeded + rni.resultNodesCount == 4 + er.data == [hello: "world", h1: "world", h2: "world", h3: null] + } + + def "max result nodes breached with list"() { + given: + def sdl = ''' + + type Query { + hello: [String] + } + ''' + def df = { env -> ["w1", "w2", "w3"] } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello}" + def ei = newExecutionInput(query).build() + ei.getGraphQLContext().put(MAX_RESULT_NODES, 3); + + when: + def er = graphQL.execute(ei) + def rni = ei.getGraphQLContext().get(ResultNodesInfo.RESULT_NODES_INFO) as ResultNodesInfo + then: + rni.maxResultNodesExceeded + rni.resultNodesCount == 4 + er.data == [hello: null] + } + + def "max result nodes breached with list 2"() { + given: + def sdl = ''' + + type Query { + hello: [Foo] + } + type Foo { + name: String + } + ''' + def df = { env -> [[name: "w1"], [name: "w2"], [name: "w3"]] } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello {name}}" + def ei = newExecutionInput(query).build() + // we have 7 result nodes overall + ei.getGraphQLContext().put(MAX_RESULT_NODES, 6); + + when: + def er = graphQL.execute(ei) + def rni = ei.getGraphQLContext().get(ResultNodesInfo.RESULT_NODES_INFO) as ResultNodesInfo + then: + rni.resultNodesCount == 7 + rni.maxResultNodesExceeded + er.data == [hello: [[name: "w1"], [name: "w2"], [name: null]]] + } + + def "max result nodes not breached with list"() { + given: + def sdl = ''' + + type Query { + hello: [Foo] + } + type Foo { + name: String + } + ''' + def df = { env -> [[name: "w1"], [name: "w2"], [name: "w3"]] } as DataFetcher + def fetchers = ["Query": ["hello": df]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ hello {name}}" + def ei = newExecutionInput(query).build() + // we have 7 result nodes overall + ei.getGraphQLContext().put(MAX_RESULT_NODES, 7); + + when: + def er = graphQL.execute(ei) + def rni = ei.getGraphQLContext().get(ResultNodesInfo.RESULT_NODES_INFO) as ResultNodesInfo + then: + !rni.maxResultNodesExceeded + rni.resultNodesCount == 7 + er.data == [hello: [[name: "w1"], [name: "w2"], [name: "w3"]]] + } + + def "exceptions thrown are turned into graphql errors"() { + def sdl = """ + type Query { + f(arg : Boolean) : String + } + """ + + def graphQL = TestUtil.graphQL(sdl).build() + + when: + def ei = newExecutionInput("query badSyntax {").build() + def er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message.contains("Invalid syntax with offending token") + + + when: + + ei = newExecutionInput('query badInput($varX : Boolean) { f(arg : $varX) }') + .variables([varX: "bad"]).build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message.contains("Variable 'varX' has an invalid value") + + when: + + ei = newExecutionInput("query ok1 { f } query ok2 { f } ") + .operationName("X").build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message.contains("Unknown operation named 'X'") + } } diff --git a/src/test/groovy/graphql/GraphqlErrorBuilderTest.groovy b/src/test/groovy/graphql/GraphqlErrorBuilderTest.groovy new file mode 100644 index 0000000000..8713100d02 --- /dev/null +++ b/src/test/groovy/graphql/GraphqlErrorBuilderTest.groovy @@ -0,0 +1,217 @@ +package graphql + +import graphql.execution.ResultPath +import graphql.language.SourceLocation +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.DataFetchingEnvironmentImpl +import spock.lang.Specification + +import static graphql.Scalars.GraphQLString +import static graphql.execution.ExecutionStepInfo.newExecutionStepInfo +import static graphql.execution.MergedField.newMergedField +import static graphql.language.Field.newField + +class GraphqlErrorBuilderTest extends Specification { + def location = new SourceLocation(6, 9) + def field = newMergedField(newField("f").sourceLocation(location).build()).build() + def stepInfo = newExecutionStepInfo().path(ResultPath.fromList(["a", "b"])).type(GraphQLString).build() + + def "dfe is passed on"() { + DataFetchingEnvironment dfe = DataFetchingEnvironmentImpl.newDataFetchingEnvironment() + .mergedField(field) + .executionStepInfo(stepInfo) + .build() + when: + def graphQLError = GraphqlErrorBuilder.newError(dfe).message("Gunfight at the %s corral", "NotOK").build() + then: + graphQLError.getMessage() == "Gunfight at the NotOK corral" + graphQLError.getLocations() == [location] + graphQLError.getPath() == ["a", "b"] + graphQLError.getExtensions() == null + } + + def "basic building"() { + when: + def graphQLError = GraphqlErrorBuilder.newError().message("Gunfight at the %s corral", "NotOK").build() + then: + graphQLError.getMessage() == "Gunfight at the NotOK corral" + graphQLError.getErrorType() == ErrorType.DataFetchingException + } + + def "builder getters work"() { + when: + def errorBuilder = GraphqlErrorBuilder.newError() + .message("Gunfight at the %s corral", "NotOK") + .location(location) + .path(["a","b"]) + then: + errorBuilder.getMessage() == "Gunfight at the NotOK corral" + errorBuilder.getErrorType() == ErrorType.DataFetchingException + errorBuilder.getPath() == ["a","b"] + errorBuilder.getLocations() == [location] + } + + def "data fetcher result building works"() { + when: + def result = GraphqlErrorBuilder.newError().message("Gunfight at the %s corral", "NotOK").toResult() + then: + result.getErrors().size() == 1 + result.getData() == null + + def graphQLError = result.getErrors()[0] + + graphQLError.getMessage() == "Gunfight at the NotOK corral" + graphQLError.getErrorType() == ErrorType.DataFetchingException + } + + def "integration test of this"() { + def sdl = ''' + type Query { + field(arg : String) : String + } + ''' + DataFetcher df = { env -> + GraphqlErrorBuilder.newError(env).message("Things are having %s", env.getArgument("arg")).toResult() + } + def graphQL = TestUtil.graphQL(sdl, [Query: [field: df]]).build() + + when: + def er = graphQL.execute({ input -> input.query('{ field(arg : "problems") }') }) + then: + er.getData() == [field: null] + er.getErrors().size() == 1 + def graphQLError = er.getErrors()[0] + + graphQLError.getMessage() == "Things are having problems" + graphQLError.getExtensions() == null + graphQLError.getErrorType() == ErrorType.DataFetchingException + graphQLError.getPath() == ["field"] + graphQLError.getLocations() == [new SourceLocation(1, 3)] + } + + def "java string format is safe"() { + when: + def gqlErr = GraphqlErrorBuilder.newError().message("This has %s in it").build() + then: + gqlErr.getMessage() == "This has %s in it" + + when: + gqlErr = GraphqlErrorBuilder.newError().message("This has %s in it", null).build() + then: + gqlErr.getMessage() == "This has %s in it" + + when: + gqlErr = GraphqlErrorBuilder.newError().message("This has %s in it", new Object[0]).build() + then: + gqlErr.getMessage() == "This has %s in it" + + when: + gqlErr = GraphqlErrorBuilder.newError().message("This has %s in it", "data").build() + then: + gqlErr.getMessage() == "This has data in it" + } + + def "null message is not acceptable"() { + when: + GraphqlErrorBuilder.newError().message(null, "a", "b").build() + then: + thrown(AssertException) + + when: + GraphqlErrorBuilder.newError().message(null).build() + then: + thrown(AssertException) + } + + def "can have nullable attributes"() { + when: + def error = GraphqlErrorBuilder.newError().message("msg") + .locations(null) + .extensions(null) + .path(null) + .build() + then: + error.message == "msg" + error.locations == null + error.path == null + error.extensions == null + } + + def "can use a builder direct from graphql error"() { + when: + def error = GraphQLError.newError().message("msg") + .locations(null) + .extensions([x : "y"]) + .path(null) + .build() + then: + error.message == "msg" + error.locations == null + error.extensions == [x : "y"] + error.path == null + + } + + def "implements equals/hashCode correctly for matching errors"() { + when: + def firstError = toGraphQLError(first) + def secondError = toGraphQLError(second) + + then: + firstError == secondError + firstError.hashCode() == secondError.hashCode() + + where: + first | second + [message: "msg"] | [message: "msg"] + [message: "msg", locations: [new SourceLocation(1, 2)]] | [message: "msg", locations: [new SourceLocation(1, 2)]] + [message: "msg", errorType: ErrorType.InvalidSyntax] | [message: "msg", errorType: ErrorType.InvalidSyntax] + [message: "msg", path: ["items", 1, "item"]] | [message: "msg", path: ["items", 1, "item"]] + [message: "msg", extensions: [aBoolean: true, aString: "foo"]] | [message: "msg", extensions: [aBoolean: true, aString: "foo"]] + } + + def "implements equals/hashCode correctly for different errors"() { + when: + def firstError = toGraphQLError(first) + def secondError = toGraphQLError(second) + + then: + firstError != secondError + firstError.hashCode() != secondError.hashCode() + + where: + first | second + [message: "msg"] | [message: "different msg"] + [message: "msg", locations: [new SourceLocation(1, 2)]] | [message: "msg", locations: [new SourceLocation(3, 4)]] + [message: "msg", errorType: ErrorType.InvalidSyntax] | [message: "msg", errorType: ErrorType.DataFetchingException] + [message: "msg", path: ["items", "1", "item"]] | [message: "msg", path: ["items"]] + [message: "msg", extensions: [aBoolean: false]] | [message: "msg", extensions: [aString: "foo"]] + } + + private static GraphQLError toGraphQLError(Map errorFields) { + def errorBuilder = GraphQLError.newError(); + errorFields.forEach { key, value -> + if (value != null) { + switch (key) { + case "message": + errorBuilder.message(value as String); + break; + case "locations": + errorBuilder.locations(value as List); + break; + case "errorType": + errorBuilder.errorType(value as ErrorClassification); + break; + case "path": + errorBuilder.path(value as List); + break; + case "extensions": + errorBuilder.extensions(value as Map); + break; + } + } + } + return errorBuilder.build(); + } +} diff --git a/src/test/groovy/graphql/GraphqlErrorHelperTest.groovy b/src/test/groovy/graphql/GraphqlErrorHelperTest.groovy new file mode 100644 index 0000000000..a0c4c4e9e3 --- /dev/null +++ b/src/test/groovy/graphql/GraphqlErrorHelperTest.groovy @@ -0,0 +1,169 @@ +package graphql + +import graphql.language.SourceLocation +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import spock.lang.RepeatUntilFailure +import spock.lang.Specification + +class GraphqlErrorHelperTest extends Specification { + + class TestError implements GraphQLError { + @Override + String getMessage() { + return "test" + } + + @Override + List getLocations() { + return [new SourceLocation(6, 9)] + } + + @Override + ErrorClassification getErrorType() { + return new ErrorClassification() { + @Override + Object toSpecification(GraphQLError error) { + return [statusCode: 200, reason: "Bad juj ju"] + } + } + } + + @Override + Map getExtensions() { + return [extra: "extensionData"] + } + } + + class ExtensionAddingError implements GraphQLError { + + Map extensions + + ExtensionAddingError(Map extensions) { + this.extensions = extensions + } + + @Override + String getMessage() { + return "has extensions" + } + + @Override + List getLocations() { + return null + } + + @Override + ErrorClassification getErrorType() { + return null + } + + @Override + Map getExtensions() { + return extensions + } + } + + def "can turn error classifications into extensions"() { + + def validationErr = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.InvalidFragmentType) + .sourceLocation(new SourceLocation(6, 9)) + .description("Things are not valid") + .build() + + when: + def specMap = GraphqlErrorHelper.toSpecification(validationErr) + then: + specMap == [ + locations : [[line: 6, column: 9]], + message : "Things are not valid", + extensions: [classification: "ValidationError"], + + ] + } + + def "can handle custom extensions and custom error classification"() { + when: + def specMap = GraphqlErrorHelper.toSpecification(new TestError()) + then: + specMap == [extensions: [ + extra : "extensionData", + classification: [ + statusCode: 200, + reason : "Bad juj ju" + ]], + locations : [[line: 6, column: 9]], + message : "test" + ] + } + + def "can handle custom extensions with classification"() { + when: + def specMap = GraphqlErrorHelper.toSpecification(new ExtensionAddingError([classification: "help"])) + then: + specMap == [extensions: [ + classification: "help"], + message : "has extensions" + ] + } + + def "can parse out a map and make an error"() { + when: + def rawError = [message: "m"] + def graphQLError = GraphqlErrorHelper.fromSpecification(rawError) + then: + graphQLError.getMessage() == "m" + graphQLError.getErrorType() == ErrorType.DataFetchingException // default from error builder + graphQLError.getLocations() == [] + graphQLError.getPath() == null + graphQLError.getExtensions() == null + + when: + rawError = [message: "m"] + graphQLError = GraphQLError.fromSpecification(rawError) // just so we reference the public method + then: + graphQLError.getMessage() == "m" + graphQLError.getErrorType() == ErrorType.DataFetchingException // default from error builder + graphQLError.getLocations() == [] + graphQLError.getPath() == null + graphQLError.getExtensions() == null + + when: + def extensionsMap = [attr1: "a1", attr2: "a2", classification: "CLASSIFICATION-X"] + rawError = [message: "m", path: ["a", "b"], locations: [[line: 2, column: 3]], extensions: extensionsMap] + graphQLError = GraphqlErrorHelper.fromSpecification(rawError) + + then: + graphQLError.getMessage() == "m" + graphQLError.getErrorType().toString() == "CLASSIFICATION-X" + graphQLError.getLocations() == [new SourceLocation(2, 3)] + graphQLError.getPath() == ["a", "b"] + graphQLError.getExtensions() == extensionsMap + + + when: "can do a list of errors" + def rawErrors = [[message: "m0"], [message: "m1"]] + def errors = GraphqlErrorHelper.fromSpecification(rawErrors) + then: + errors.size() == 2 + errors.eachWithIndex { GraphQLError gErr, int i -> + assert gErr.getMessage() == "m" + i + assert gErr.getErrorType() == ErrorType.DataFetchingException // default from error builder + assert gErr.getLocations() == [] + assert gErr.getPath() == null + assert gErr.getExtensions() == null + } + } + + @RepeatUntilFailure(maxAttempts = 1_000, ignoreRest = false) + def "can deterministically serialize SourceLocation"() { + when: + def specMap = GraphqlErrorHelper.toSpecification(new TestError()) + + then: + def location = specMap["locations"][0] as Map + def keys = location.keySet().toList() + keys == ["line", "column"] + } +} diff --git a/src/test/groovy/graphql/GuavaLimitCheck.groovy b/src/test/groovy/graphql/GuavaLimitCheck.groovy new file mode 100644 index 0000000000..cc4fc7ff58 --- /dev/null +++ b/src/test/groovy/graphql/GuavaLimitCheck.groovy @@ -0,0 +1,89 @@ +package graphql + +import com.tngtech.archunit.core.domain.JavaClasses +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.core.importer.ImportOption +import spock.lang.Specification + +/* + * We selectively shade in a few classes of Guava, however we want to minimise dependencies so we want to keep this list small. + * This check ensures no new Guava classes are added + */ +class GuavaLimitCheck extends Specification { + + static final String GUAVA_PACKAGE_PREFIX = "com.google.common" + + static final Set ALLOWED_GUAVA_CLASSES = [ + "com.google.common.base.Strings", + "com.google.common.collect.BiMap", + "com.google.common.collect.HashBasedTable", + "com.google.common.collect.HashBiMap", + "com.google.common.collect.HashMultimap", + "com.google.common.collect.HashMultiset", + "com.google.common.collect.ImmutableBiMap", + "com.google.common.collect.ImmutableCollection", + "com.google.common.collect.ImmutableList", + "com.google.common.collect.ImmutableList\$Builder", + "com.google.common.collect.ImmutableListMultimap", + "com.google.common.collect.ImmutableListMultimap\$Builder", + "com.google.common.collect.ImmutableMap", + "com.google.common.collect.ImmutableMap\$Builder", + "com.google.common.collect.ImmutableSet", + "com.google.common.collect.ImmutableSet\$Builder", + "com.google.common.collect.Interner", + "com.google.common.collect.Interners", + "com.google.common.collect.Iterables", + "com.google.common.collect.LinkedHashMultimap", + "com.google.common.collect.Maps", + "com.google.common.collect.Multimap", + "com.google.common.collect.Multimaps", + "com.google.common.collect.Multiset", + "com.google.common.collect.Multisets", + "com.google.common.collect.Sets", + "com.google.common.collect.Sets\$SetView", + "com.google.common.collect.Table" + ] + + def "should identify which classes use prohibited Guava dependencies"() { + given: + JavaClasses importedClasses = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) + .importPackages("graphql") + + when: + Map> violationsByClass = [:] + + importedClasses.each { javaClass -> + def className = javaClass.name + def guavaUsages = javaClass.getAccessesFromSelf() + .collect { it.targetOwner } + .findAll { it.packageName.startsWith(GUAVA_PACKAGE_PREFIX) && !ALLOWED_GUAVA_CLASSES.contains(it.fullName) } + .toSet() + + if (!guavaUsages.isEmpty()) { + violationsByClass[className] = guavaUsages + } + } + + then: + violationsByClass.isEmpty() + + cleanup: "if the test fails, provide detailed information about which classes have violations" + if (!violationsByClass.isEmpty()) { + def errorMessage = new StringBuilder("Prohibited Guava class usage found:\n") + + violationsByClass.each { className, guavaClasses -> + errorMessage.append("\nClass: ${className} uses these prohibited Guava classes:\n") + guavaClasses.each { guavaClass -> + errorMessage.append(" - ${guavaClass}\n") + } + } + + errorMessage.append("\nEither:\n") + errorMessage.append("1. Preferred option: Replace them with alternatives that don't depend on Guava\n") + errorMessage.append("2. If absolutely necessary: Add these Guava classes to the shade configuration in the build.gradle file\n") + + println errorMessage.toString() + } + } +} diff --git a/src/test/groovy/graphql/HelloWorld.java b/src/test/groovy/graphql/HelloWorld.java index b381b4bbc0..5c8e13790f 100644 --- a/src/test/groovy/graphql/HelloWorld.java +++ b/src/test/groovy/graphql/HelloWorld.java @@ -3,14 +3,14 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.Map; import static graphql.Scalars.GraphQLString; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLObjectType.newObject; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class HelloWorld { diff --git a/src/test/groovy/graphql/InterfacesImplementingInterfacesTest.groovy b/src/test/groovy/graphql/InterfacesImplementingInterfacesTest.groovy new file mode 100644 index 0000000000..bb22d70461 --- /dev/null +++ b/src/test/groovy/graphql/InterfacesImplementingInterfacesTest.groovy @@ -0,0 +1,1403 @@ +package graphql + +import graphql.schema.GraphQLCodeRegistry +import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLTypeReference +import graphql.schema.TypeResolver +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import graphql.schema.idl.SchemaPrinter +import graphql.schema.idl.errors.SchemaProblem +import graphql.schema.validation.InvalidSchemaException +import spock.lang.Specification + +import static graphql.Scalars.GraphQLInt +import static graphql.Scalars.GraphQLString +import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInterfaceType.newInterface +import static graphql.schema.GraphQLObjectType.newObject + +class InterfacesImplementingInterfacesTest extends Specification { + def 'Simple interface implementing interface'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When implementing interface does not declare required field, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + url: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + assertErrorMessage(error, "The interface type 'Resource' [@n:n] does not have a field 'id' required via interface 'Node' [@n:n]") + } + + def 'Transitively implemented interfaces defined in implementing interface'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + interface Image implements Resource & Node { + id: ID! + url: String + thumbnail: String + } + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + + def 'Transitively implemented interfaces defined in implementing type'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + type Image implements Resource & Node { + id: ID! + url: String + thumbnail: String + } + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When not all transitively implemented interfaces are defined in implementing interface, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + interface Image implements Resource & Node { + id: ID! + url: String + thumbnail: String + } + + interface LargeImage implements Image & Resource { + id: ID! + url: String + thumbnail: String + large: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 2 + assertErrorMessage(error, "The interface type 'LargeImage' [@n:n] must implement 'Node' [@n:n] because it is implemented by 'Image' [@n:n]") + assertErrorMessage(error, "The interface type 'LargeImage' [@n:n] must implement 'Node' [@n:n] because it is implemented by 'Resource' [@n:n]") + } + + def 'When not all transitively implemented interfaces are defined in implementing type, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + type Image implements Resource { + id: ID! + url: String + thumbnail: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + assertErrorMessage(error, "The object type 'Image' [@n:n] must implement 'Node' [@n:n] because it is implemented by 'Resource' [@n:n]") + } + + def 'When interface implements itself, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node implements Named & Node { + id: ID! + name: String + } + + interface Named implements Node & Named { + id: ID! + name: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 2 + assertErrorMessage(error, "The interface type 'Node' [@n:n] cannot implement itself") + assertErrorMessage(error, "The interface type 'Named' [@n:n] cannot implement itself") + } + + def 'When interface extension implements interface and declares required field, then parsing is successful'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource { + url: String + } + + extend interface Resource implements Node { + id: ID! + } + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When interface extension implements interface but doesn\'t declare required field, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + extraField: String + } + + interface Resource { + url: String + } + + extend interface Resource implements Node { + id: ID! + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + assertErrorMessage(error, "The interface extension type 'Resource' [@n:n] does not have a field 'extraField' required via interface 'Node' [@n:n]") + } + + def 'When object extension implements all transitive interfaces, then parsing is successful'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + type Image { + thumbnail: String! + } + + extend type Image implements Node & Resource { + id: ID! + url: String + } + """ + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When object extension does not implement all transitive interfaces, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + type Image { + thumbnail: String! + } + + extend type Image implements Resource { + id: ID! + url: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + assertErrorMessage(error, "The object extension type 'Image' [@n:n] must implement 'Node' [@n:n] because it is implemented by 'Resource' [@n:n]") + } + + def 'When interface extension implements all transitive interfaces, then parsing is successful'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + interface Image { + thumbnail: String! + } + + extend interface Image implements Node & Resource { + id: ID! + url: String + } + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When interface extension does not implement all transitive interfaces, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + interface Image { + thumbnail: String! + } + + extend interface Image implements Resource { + id: ID! + url: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + assertErrorMessage(error, "The interface extension type 'Image' [@n:n] must implement 'Node' [@n:n] because it is implemented by 'Resource' [@n:n]") + } + + def 'When hierarchy results in circular reference, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Interface1 + } + + interface Interface1 implements Interface3 & Interface2 { + field1: String + field2: String + field3: String + } + + interface Interface2 implements Interface1 & Interface3 { + field1: String + field2: String + field3: String + } + + interface Interface3 implements Interface2 & Interface1 { + field1: String + field2: String + field3: String + } + + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + + error.errors.size() == 6 + + assertErrorMessage(error, "The interface type 'Interface1' [@n:n] cannot implement 'Interface2' [@n:n] as this would result in a circular reference") + assertErrorMessage(error, "The interface type 'Interface1' [@n:n] cannot implement 'Interface3' [@n:n] as this would result in a circular reference") + assertErrorMessage(error, "The interface type 'Interface2' [@n:n] cannot implement 'Interface3' [@n:n] as this would result in a circular reference") + assertErrorMessage(error, "The interface type 'Interface2' [@n:n] cannot implement 'Interface1' [@n:n] as this would result in a circular reference") + assertErrorMessage(error, "The interface type 'Interface3' [@n:n] cannot implement 'Interface1' [@n:n] as this would result in a circular reference") + assertErrorMessage(error, "The interface type 'Interface3' [@n:n] cannot implement 'Interface2' [@n:n] as this would result in a circular reference") + } + + def 'When interface doesn\'t implement transitive interface declared in extension, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Interface1 + } + + interface Interface1 implements Interface2 { + field1: String + field2: String + } + + interface Interface2 { + field2: String + } + + interface Interface3 { + field3: String + } + + extend interface Interface2 implements Interface3 { + field3: String + } + + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + + assertErrorMessage( + error, + "The interface type 'Interface1' [@n:n] must implement 'Interface3' [@n:n] because it is implemented by 'Interface2' [@n:n]" + ) + } + + def 'When interface implements transitive interface declared in extension, then parsing succeeds'() { + when: + def schema = """ + type Query { + find(id: String!): Interface1 + } + + interface Interface1 implements Interface2 { + field1: String + field2: String + } + + interface Interface2 { + field2: String + } + + interface Interface3 { + field3: String + } + + extend interface Interface2 implements Interface3 { + field3: String + } + + extend interface Interface1 implements Interface3 { + field3: String + } + + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When field required by new extension implementation is declared in original interface type, then parsing succeeds'() { + when: + def schema = """ + type Query { + find(id: String!): Interface1 + } + + interface Interface1 { + field1: String + field2: String + } + + interface Interface2 { + field2: String + } + + extend interface Interface1 implements Interface2 + + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When type declares interface and extension declares required field, then parsing succeeds'() { + when: + def schema = """ + type Query { + find(id: String!): Interface1 + } + + interface Interface1 implements Interface2 { + field1: String + } + + interface Interface2 { + field2: String + } + + extend interface Interface1 { + field2: String + } + + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When interface implements same interface more than once via extensions, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Type1 + } + + type Type1 { + field1: String + } + + interface Interface2 { + field20: String + field21: String + } + + extend type Type1 implements Interface2 { + field20: String + } + + extend type Type1 implements Interface2 { + field21: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 2 + + assertErrorMessage(error, "The object extension type 'Type1' [@n:n] can only implement 'Interface2' [@n:n] once.") + } + + def 'When interface implements same interface more than once, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Type1 + } + + type Type1 implements Interface2 { + field1: String + field20: String + } + + interface Interface2 { + field20: String + field21: String + } + + extend type Type1 implements Interface2 { + field21: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 2 + + assertErrorMessage(error, "The object extension type 'Type1' [@n:n] can only implement 'Interface2' [@n:n] once.") + assertErrorMessage(error, "The object type 'Type1' [@n:n] can only implement 'Interface2' [@n:n] once.") + } + + def 'When interface implements interface and redefines non-null field as nullable, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + url: String + id: ID + } + + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + + assertErrorMessage(error, "The interface type 'Resource' [@n:n] has tried to redefine field 'id' defined via interface 'Node' [@n:n] from 'ID!' to 'ID'") + } + + def 'When interface extension implements interface and redefines non-null field as nullable, then parsing fails'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID! + } + + interface Resource { + url: String + } + + extend interface Resource implements Node { + id: ID + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 1 + + assertErrorMessage(error, "The interface extension type 'Resource' [@n:n] has tried to redefine field 'id' defined via interface 'Node' [@n:n] from 'ID!' to 'ID'") + } + + def 'When interface implements interface and redefines nullable field as non-null, then parsing succeeds'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID + } + + interface Resource implements Node { + url: String + id: ID! + } + + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When interface extension implements interface and redefines nullable field as non-null, then parsing succeeds'() { + when: + def schema = """ + type Query { + find(id: String!): Node + } + + interface Node { + id: ID + } + + interface Resource { + url: String + } + + extend interface Resource implements Node { + id: ID! + } + """ + + parseSchema(schema) + + then: + noExceptionThrown() + } + + def 'When interface extension implements interface and misses field arguments, then parsing fails'() { + when: + def schema = """ + interface InterfaceType { + fieldA(arg1 : Int) : Int + fieldB(arg1 : String = "defaultVal", arg2 : String, arg3 : Int) : String + } + + interface BaseInterface { + fieldX : Int + } + + extend interface BaseInterface implements InterfaceType { + fieldA : Int + fieldB(arg1 : String = "defaultValX", arg2 : String!, arg3 : String) : String + } + + type Query { + mock: String + } + + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 4 + + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] field 'fieldA' does not have the same number of arguments as specified via interface 'InterfaceType' [@n:n]") + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg1:String =\"defaultVal\"' to 'arg1:String =\"defaultValX\"") + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg2:String' to 'arg2:String!") + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg3:Int' to 'arg3:String") + } + + def 'When interface implements interface and misses field arguments, then parsing fails'() { + when: + def schema = """ + interface InterfaceType { + fieldA(arg1 : Int) : Int + fieldB(arg1 : String = "defaultVal", arg2 : String, arg3 : Int) : String + } + + interface BaseInterface implements InterfaceType { + fieldX : Int + fieldA : Int + fieldB(arg1 : String = "defaultValX", arg2 : String!, arg3 : String) : String + } + + type Query { + mock: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 4 + + assertErrorMessage(error, "The interface type 'BaseInterface' [@n:n] field 'fieldA' does not have the same number of arguments as specified via interface 'InterfaceType' [@n:n]") + assertErrorMessage(error, "The interface type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg1:String =\"defaultVal\"' to 'arg1:String =\"defaultValX\"") + assertErrorMessage(error, "The interface type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg2:String' to 'arg2:String!") + assertErrorMessage(error, "The interface type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg3:Int' to 'arg3:String") + } + + def 'When interface implements interface via extension and misses field arguments, then parsing fails'() { + when: + def schema = """ + interface InterfaceType { + fieldA(arg1 : Int) : Int + fieldB(arg1 : String = "defaultVal", arg2 : String, arg3 : Int) : String + } + + interface BaseInterface { + fieldX : Int + fieldA : Int + fieldB(arg1 : String = "defaultValX", arg2 : String!, arg3 : String) : String + } + + extend interface BaseInterface implements InterfaceType + + type BaseType { + id: ID! + } + + type Query { + mock: String + } + """ + + parseSchema(schema) + + then: + def error = thrown(SchemaProblem) + error.errors.size() == 4 + + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] field 'fieldA' does not have the same number of arguments as specified via interface 'InterfaceType' [@n:n]") + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg1:String =\"defaultVal\"' to 'arg1:String =\"defaultValX\"") + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg2:String' to 'arg2:String!") + assertErrorMessage(error, "The interface extension type 'BaseInterface' [@n:n] has tried to redefine field 'fieldB' arguments defined via interface 'InterfaceType' [@n:n] from 'arg3:Int' to 'arg3:String") + } + + def 'Test query execution'() { + given: + def graphQLSchema = createComplexSchema() + + when: + def result = GraphQL.newGraphQL(graphQLSchema).build().execute(""" + { + find { + ... on Node { + id + ... on Resource { + __typename + url + ... on Image { + thumbnail + } + ... on File { + path + } + } + } + } + } + """) + + then: + !result.errors + result.data == [find: [ + [id: '1', url: 'https://image.com/1', thumbnail: 'TN', __typename: 'Image'], + [id: '2', url: 'https://file.com/1', path: '/file/1', __typename: 'File'] + ]] + } + + def 'Test introspection query'() { + given: + def graphQLSchema = createComplexSchema() + + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + + when: + String query = """ + { + nodeType: __type(name: "Node") { + possibleTypes { + kind + name + } + } + } + """ + def result = graphQL.execute(query) + + then: + !result.errors + result.data == [ + nodeType: [possibleTypes: [[kind: 'OBJECT', name: 'File'], [kind: 'OBJECT', name: 'Image']]], + ] + + when: + query = """ + { + resourceType: __type(name: "Resource") { + possibleTypes { + kind + name + } + interfaces { + kind + name + } + } + } + """ + result = graphQL.execute(query) + + then: + !result.errors + result.data == [ + resourceType: [possibleTypes: [[kind: 'OBJECT', name: 'File'], [kind: 'OBJECT', name: 'Image']], interfaces: [[kind: 'INTERFACE', name: 'Node']]] + ] + + when: + + query = """ + { + imageType: __type(name: "Image") { + interfaces { + kind + name + } + } + } + """ + result = graphQL.execute(query) + + then: + !result.errors + result.data == [ + imageType : [interfaces: [[kind: 'INTERFACE', name: 'Resource'], [kind: 'INTERFACE', name: 'Node']]], + ] + } + + def "interfaces introspection field is empty list for interfaces"() { + given: + def graphQLSchema = createComplexSchema() + + when: + def result = GraphQL.newGraphQL(graphQLSchema).build().execute(""" + { + nodeType: __type(name: "Node") { + interfaces { + kind + name + } + } + } + """) + + then: + !result.errors + result.data == [ + nodeType: [interfaces: []] + ] + + } + + def "interface type has a reference to implemented interfaces"() { + when: + def schema = createComplexSchema() + def resourceType = schema.getType("Resource") as GraphQLInterfaceType + + then: + resourceType.getInterfaces().size() == 1 + resourceType.getInterfaces().get(0) instanceof GraphQLInterfaceType + resourceType.getInterfaces().get(0).getName() == "Node" + + } + + def "GraphQLInterfaceType can can implement interfaces"() { + given: + def node1Type = newInterface() + .name("Node1") + .field(newFieldDefinition().name("id1").type(GraphQLString).build()) + .build() + + def node2Type = newInterface() + .name("Node2") + .field(newFieldDefinition().name("id2").type(GraphQLString).build()) + .build() + + // references two interfaces: directly and via type ref + def resource = newInterface() + .name("Resource") + .field(newFieldDefinition().name("id1").type(GraphQLString).build()) + .field(newFieldDefinition().name("id2").type(GraphQLString).build()) + .withInterface(GraphQLTypeReference.typeRef("Node1")) + .withInterface(node2Type) + .build() + def image = newObject() + .name("Image") + .field(newFieldDefinition().name("id1").type(GraphQLString).build()) + .field(newFieldDefinition().name("id2").type(GraphQLString).build()) + .withInterface(resource) + .withInterface(node1Type) + .withInterface(node2Type) + .build() + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("image").type(image).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(node1Type, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(node2Type, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(resource, { env -> Assert.assertShouldNeverHappen() }) + .build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .additionalType(node1Type) + .build() + + when: + def printedSchema = new SchemaPrinter().print(schema) + + then: + printedSchema.contains(""" +interface Node1 { + id1: String +} + +interface Node2 { + id2: String +} + +interface Resource implements Node1 & Node2 { + id1: String + id2: String +} + +type Image implements Node1 & Node2 & Resource { + id1: String + id2: String +} + +type Query { + image: Image +} +""") + } + + def "When programmatically created interface does not implement interface correctly, then creation fails"() { + given: + def interface1 = newInterface() + .name("Interface1") + .field( + newFieldDefinition().name("field1").type(GraphQLString) + .argument(newArgument().name("arg1").type(GraphQLString)) + ) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .field( + newFieldDefinition().name("field3").type(GraphQLString) + .argument(newArgument().name("arg3").type(GraphQLString)) + ) + .field(newFieldDefinition().name("field4").type(GraphQLString)) + .build() + + def interface2 = newInterface() + .name("Interface2") + .field( + newFieldDefinition().name("field1").type(GraphQLString) + .argument(newArgument().name("arg1").type(GraphQLInt)) + ) + .field(newFieldDefinition().name("field2").type(GraphQLInt)) + .field(newFieldDefinition().name("field3").type(GraphQLString)) + .withInterface(interface1) + .build() + + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("interface2").type(interface2).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(interface1, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(interface2, { env -> Assert.assertShouldNeverHappen() }) + .build() + + when: + GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .build() + + then: + def error = thrown(InvalidSchemaException) + + assertErrorMessage(error, + "interface type 'Interface2' does not implement interface 'Interface1' because field 'field1' argument 'arg1' is defined differently", + "interface type 'Interface2' does not implement interface 'Interface1' because field 'field2' is defined as 'Int' type and not as 'String' type", + "interface type 'Interface2' does not implement interface 'Interface1' because field 'field3' is missing argument(s): 'arg3'", + "interface type 'Interface2' does not implement interface 'Interface1' because field 'field4' is missing" + ) + } + + def "When programmatically created interface implement interface correctly, then creation succeeds"() { + given: + def interface1 = newInterface() + .name("Interface1") + .field( + newFieldDefinition().name("field1").type(GraphQLString) + .argument(newArgument().name("arg1").type(GraphQLString)) + ) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .field( + newFieldDefinition().name("field3").type(GraphQLString) + .argument(newArgument().name("arg3").type(GraphQLString)) + ) + .field(newFieldDefinition().name("field4").type(GraphQLString)) + .build() + + def interface2 = newInterface() + .name("Interface2") + .field( + newFieldDefinition().name("field1").type(GraphQLString) + .argument(newArgument().name("arg1").type(GraphQLString)) + ) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .field( + newFieldDefinition().name("field3").type(GraphQLString) + .argument(newArgument().name("arg3").type(GraphQLString)) + ) + .field(newFieldDefinition().name("field4").type(GraphQLString)) + .withInterface(interface1) + .build() + + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("interface2").type(interface2).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(interface1, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(interface2, { env -> Assert.assertShouldNeverHappen() }) + .build() + + when: + GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .build() + + then: + noExceptionThrown() + } + + def "When programmatically created type does not implement all transitive interfaces, then creation fails"() { + given: + def interface1 = newInterface() + .name("Interface1") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .build() + + def interface2 = newInterface() + .name("Interface2") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .withInterface(interface1) + .build() + + def type = newObject() + .name("Type") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .withInterface(interface2) + .build() + + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("find").type(type).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(interface1, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(interface2, { env -> Assert.assertShouldNeverHappen() }) + .build() + + when: + GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .build() + + then: + def error = thrown(InvalidSchemaException) + + assertErrorMessage(error, "object type 'Type' must implement 'Interface1' because it is implemented by 'Interface2'") + } + + def "When programmatically created type implement all transitive interfaces, then creation succeeds"() { + given: + def interface1 = newInterface() + .name("Interface1") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .build() + + def interface2 = newInterface() + .name("Interface2") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .withInterface(interface1) + .build() + + def type = newObject() + .name("Type") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .field(newFieldDefinition().name("field2").type(GraphQLString)) + .withInterface(interface1) + .withInterface(interface2) + .build() + + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("find").type(type).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(interface1, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(interface2, { env -> Assert.assertShouldNeverHappen() }) + .build() + + when: + GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .build() + + then: + noExceptionThrown() + } + + def "When interface implementation results in circular reference, then creation fails"() { + given: + def interface1 = newInterface() + .name("Interface1") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .withInterface(GraphQLTypeReference.typeRef("Interface3")) + .withInterface(GraphQLTypeReference.typeRef("Interface2")) + .build() + + def interface2 = newInterface() + .name("Interface2") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .withInterface(interface1) + .withInterface(GraphQLTypeReference.typeRef("Interface3")) + .build() + + def interface3 = newInterface() + .name("Interface3") + .field(newFieldDefinition().name("field1").type(GraphQLString)) + .withInterface(interface1) + .withInterface(interface2) + .build() + + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("find").type(interface3).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(interface1, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(interface2, { env -> Assert.assertShouldNeverHappen() }) + .typeResolver(interface3, { env -> Assert.assertShouldNeverHappen() }) + .build() + + when: + GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .build() + + then: + def error = thrown(InvalidSchemaException) + + assertErrorMessage(error, + "interface type 'Interface3' cannot implement 'Interface1' because that would result on a circular reference", + "interface type 'Interface3' cannot implement 'Interface2' because that would result on a circular reference", + "interface type 'Interface1' cannot implement 'Interface3' because that would result on a circular reference", + "interface type 'Interface1' cannot implement 'Interface2' because that would result on a circular reference", + "interface type 'Interface2' cannot implement 'Interface1' because that would result on a circular reference", + "interface type 'Interface2' cannot implement 'Interface3' because that would result on a circular reference", + ) + } + + def assertErrorMessage(SchemaProblem error, expectedMessage) { + def normalizedMessages = error.errors.collect { it.message.replaceAll($/\[@[0-9]+:[0-9]+]/$, '[@n:n]') } + + if (!normalizedMessages.contains(expectedMessage)) { + return false + } + + return true + } + + def assertErrorMessage(InvalidSchemaException exception, String... expectedErrors) { + def expectedMessage = "invalid schema:\n" + expectedErrors.join("\n") + + return exception.message == expectedMessage + } + + def parseSchema(schema) { + def reader = new StringReader(schema) + def registry = new SchemaParser().parse(reader) + + def options = SchemaGenerator.Options.defaultOptions() + + return new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) + } + + def createComplexSchema() { + def sdl = """ + type Query { + find: [Node] + } + + interface Node { + id: ID! + } + + interface Resource implements Node { + id: ID! + url: String + } + + type Image implements Resource & Node { + id: ID! + url: String + thumbnail: String + } + + type File implements Resource & Node { + id: ID! + url: String + path: String + } + """ + + def typeDefinitionRegistry = new SchemaParser().parse(sdl) + + TypeResolver typeResolver = { env -> + Map obj = env.getObject() + String id = (String) obj.get("id") + GraphQLSchema schema = env.getSchema() + + if (id == "1") { + return (GraphQLObjectType) schema.getType("Image") + } else { + return (GraphQLObjectType) schema.getType("File") + } + } + + def graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, RuntimeWiring.newRuntimeWiring() + .type("Query", { typeWiring -> + typeWiring.dataFetcher( + "find", + { e -> + [ + [id: '1', url: 'https://image.com/1', thumbnail: 'TN'], + [id: '2', url: 'https://file.com/1', path: '/file/1'], + ] + } + ) + }) + .type("Node", { typeWiring -> + typeWiring.typeResolver(typeResolver) + }) + .type("Resource", { typeWiring -> + typeWiring.typeResolver(typeResolver) + }) + .build() + ) + + return graphQLSchema + } +} diff --git a/src/test/groovy/graphql/Issue1559.groovy b/src/test/groovy/graphql/Issue1559.groovy new file mode 100644 index 0000000000..7f57183ac3 --- /dev/null +++ b/src/test/groovy/graphql/Issue1559.groovy @@ -0,0 +1,90 @@ +package graphql + +import graphql.execution.DataFetcherResult +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.TypeRuntimeWiring +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import spock.lang.Specification + +class Issue1559 extends Specification { + + def graphql = TestUtil.graphQL(""" + type Query { + contextAwareList: [ContextAwareEntity!]! + } + + type ContextAwareEntity { + name: String + contextInfo: String + } + + """, + RuntimeWiring.newRuntimeWiring() + .type("ContextAwareEntity", { + it.dataFetcher("contextInfo", { it.getLocalContext() }) + }) + .build()) + .build() + + def "#1559 test if a list of DataFetcherResults is processed properly"() { + + when: + def input = ExecutionInput.newExecutionInput() + .root([contextAwareList: [ + DataFetcherResult.newResult().localContext("the context 1").data([name: "the name 1"]).build(), + DataFetcherResult.newResult().localContext("the context 2").data([name: "the name 2"]).build(), + DataFetcherResult.newResult().localContext("the context 3").data([name: "the name 3"]).build(), + DataFetcherResult.newResult().localContext("the context 4").data([name: "the name 4"]).build(), + ]]) + .query(''' + query getTheList { + contextAwareList { + name + contextInfo + } + } + ''') + .build() + def executionResult = graphql.execute(input) + + then: + executionResult.errors.isEmpty() + executionResult.data == [ contextAwareList: [ + [name: "the name 1", contextInfo: "the context 1"], + [name: "the name 2", contextInfo: "the context 2"], + [name: "the name 3", contextInfo: "the context 3"], + [name: "the name 4", contextInfo: "the context 4"], + ]] + + } + def "#1559 test if null validations are processed properly on DataFetcherResult List"() { + + when: + def input = ExecutionInput.newExecutionInput() + .root([contextAwareList: [ + DataFetcherResult.newResult().localContext("the context 1").data([name: "the name 1"]).build(), + DataFetcherResult.newResult().localContext("the context 2").data(null).build(), + null, + DataFetcherResult.newResult().localContext("the context 4").data([name: "the name 4"]).build(), + ]]) + .query(''' + query getTheList { + contextAwareList { + name + contextInfo + } + } + ''') + .build() + def executionResult = graphql.execute(input) + + then: + executionResult.errors.size() == 2 + executionResult.errors[0].path == ['contextAwareList', 1] + executionResult.errors[1].path == ['contextAwareList', 2] + } + +} diff --git a/src/test/groovy/graphql/Issue1768.groovy b/src/test/groovy/graphql/Issue1768.groovy new file mode 100644 index 0000000000..5dbfde6bca --- /dev/null +++ b/src/test/groovy/graphql/Issue1768.groovy @@ -0,0 +1,69 @@ +package graphql + +import graphql.schema.DataFetcher +import spock.lang.Specification + +class Issue1768 extends Specification { + + static enum ThreadSort { + NEWEST_FIRST, + OLDEST_FIRST, + MOST_COMMENTS_FIRST + } + + def "#1768 check if the old behavior is not broken" () { + def spec = ''' + type Query { + dummy: String + } + ''' + GraphQL graphql = TestUtil.graphQL(spec, [Query: [dummy: (DataFetcher) { null }]]).build() + + when: + ExecutionResult result = graphql.execute { + it.query(" { dummy } ") + } + + then: + result.data.dummy == null + + } + def "#1768 test if local context is set for top level"() { + def spec = ''' + type Query { + dummy: String + } + ''' + GraphQL graphql = TestUtil.graphQL(spec, [Query: [dummy: (DataFetcher) { (String) it.localContext }]]).build() + + when: + ExecutionResult result = graphql.execute { + it.localContext("test").query(" { dummy } ") + } + + then: + result.data.dummy == "test" + } + def "#1768 test if the top local context gets transferred to the next level"() { + def spec = ''' + type Query { + dummy: DummyType + } + type DummyType { + dummy: String + } + ''' + GraphQL graphql = TestUtil.graphQL(spec, [ + Query: [dummy: (DataFetcher) { [ : ]}], + DummyType: [dummy: (DataFetcher) { (String) it.localContext }]]).build() + + when: + ExecutionResult result = graphql.execute { + it.localContext("test").query(" { dummy { dummy }} ") + } + + then: + result.data.dummy.dummy == "test" + } + +} diff --git a/src/test/groovy/graphql/Issue1847.groovy b/src/test/groovy/graphql/Issue1847.groovy new file mode 100644 index 0000000000..958bbfa446 --- /dev/null +++ b/src/test/groovy/graphql/Issue1847.groovy @@ -0,0 +1,42 @@ +package graphql + +import spock.lang.Specification + +class Issue1847 extends Specification { + def schema = TestUtil.schema(''' + type Query { + listWithCircularReference(filter : TypeWithCircularReference) : String + list(filter : Type) : String + } + input TypeWithCircularReference { + circularField : TypeWithCircularReference + } + input Type { + field: String + } + ''') + + def "#1847 when there is a circular reference between Input Type and Input Field - not StackOverflowError"() { + when: + def type = schema.getType("TypeWithCircularReference") + + def string = type.toString() + + println(string) + + then: + string.contains("[GraphQLInputObjectType]") + } + + def "#1847 when there is no circular reference between Input Type and Input Field - toString returns all data"() { + when: + def type = schema.getType("Type") + + def string = type.toString() + println(string) + + then: + !string.contains("[GraphQLInputObjectType]") + string.contains("GraphQLScalarType") + } +} diff --git a/src/test/groovy/graphql/Issue1914.groovy b/src/test/groovy/graphql/Issue1914.groovy new file mode 100644 index 0000000000..2e73cb5c9e --- /dev/null +++ b/src/test/groovy/graphql/Issue1914.groovy @@ -0,0 +1,133 @@ +package graphql + +import graphql.schema.DataFetcher +import spock.lang.Specification + +class Issue1914 extends Specification { + + def "default values in input objects are respected when variable is not provided"() { + given: + def spec = """type Query { + sayHello(arg: Arg! = {}): String + } + input Arg { + foo: String = "bar" + } + """ + DataFetcher df = { dfe -> + Map arg = dfe.getArgument("arg") + return arg.get("foo") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def result = graphQL.execute('{sayHello}') + + then: + result.errors.isEmpty() + result.data == [sayHello: "bar"] + + } + + def "default values in input objects are overridden when variable is provided"() { + given: + def spec = """type Query { + sayHello(arg: Arg! = {foo: "brewery"}): String + } + input Arg { + foo: String = "bar" + } + """ + DataFetcher df = { dfe -> + Map arg = dfe.getArgument("arg") + return arg.get("foo") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def result = graphQL.execute('{sayHello}') + + then: + result.errors.isEmpty() + result.data == [sayHello: "brewery"] + + } + + def "default values in input objects are overridden when null value is provided in input"() { + given: + def spec = """type Query { + sayHello(arg: Arg! = {foo: null}): String + } + input Arg { + foo: String = "bar" + } + """ + DataFetcher df = { dfe -> + Map arg = dfe.getArgument("arg") + return arg.get("foo") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def result = graphQL.execute('{sayHello}') + + then: + result.errors.isEmpty() + result.data == [sayHello: null] + + } + + def "default values in input objects are overridden when variable is provided and otherwise are respected"() { + given: + def spec = """type Query { + sayHello(arg: Arg! = {field1: "F1ValOverride"}): String + } + input Arg { + field1: String = "F1V" + field2: String = "F2V" + } + """ + DataFetcher df = { dfe -> + Map arg = dfe.getArgument("arg") + return arg.get("field1") + " & " + arg.get("field2") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def result = graphQL.execute('{sayHello}') + + then: + result.errors.isEmpty() + result.data == [sayHello: "F1ValOverride & F2V"] + + } + + def "default values (including null) in input objects are overridden when variable is provided and otherwise are respected"() { + given: + def spec = """type Query { + sayHello(arg: Arg! = {field1: "F1ValOverride", field5: "F5Val"}): String + } + input Arg { + field1: String = "F1V" + field2: String = "F2V" + field3: String = null + field4: String + field5: String + } + """ + DataFetcher df = { dfe -> + Map arg = dfe.getArgument("arg") + return arg.get("field1") + " & " + arg.get("field2") + " & " + arg.get("field3") + " & " + arg.get("field4") + " & " + arg.get("field5") + } as DataFetcher + def graphQL = TestUtil.graphQL(spec, ["Query": ["sayHello": df]]).build() + + when: + def result = graphQL.execute('{sayHello}') + + then: + result.errors.isEmpty() + result.data == [sayHello: "F1ValOverride & F2V & null & null & F5Val"] + + } +} + diff --git a/src/test/groovy/graphql/Issue2055.groovy b/src/test/groovy/graphql/Issue2055.groovy new file mode 100644 index 0000000000..49f413ec4b --- /dev/null +++ b/src/test/groovy/graphql/Issue2055.groovy @@ -0,0 +1,116 @@ +package graphql + +import graphql.introspection.Introspection +import graphql.schema.GraphQLEnumType +import graphql.schema.GraphQLNamedInputType +import graphql.schema.GraphQLScalarType +import spock.lang.Specification + + +class Issue2055 extends Specification { + + def "issues 2055 for directive on SCALAR"() { + given: + def dsl = ''' + directive @testDirective(aDate: Date) on OBJECT | SCALAR + + directive @DummyDirective on SCALAR + + scalar Date @DummyDirective + + type Query { + aQuery: String + } + ''' + + when: + def schema = TestUtil.schema(dsl) + + then: + schema.getType("Date") != null + schema.getType("Date") instanceof GraphQLScalarType + ((GraphQLScalarType) schema.getType("Date")).getDirective("DummyDirective") != null + + schema.getDirective("DummyDirective") != null + schema.getDirective("DummyDirective").validLocations().size() == 1 + schema.getDirective("DummyDirective").validLocations().asList() == [Introspection.DirectiveLocation.SCALAR] + + schema.getDirective("testDirective") != null + schema.getDirective("testDirective").validLocations().size() == 2 + schema.getDirective("testDirective").validLocations().asList() == [Introspection.DirectiveLocation.SCALAR, Introspection.DirectiveLocation.OBJECT] + ((GraphQLNamedInputType) schema.getDirective("testDirective").getArgument("aDate").getType()).getName() == "Date" + } + + + def "issues 2055 for directive on ENUM"() { + given: + def dsl = ''' + directive @testDirective(anEnum: Episode = JEDI) on OBJECT | ENUM + + directive @DummyDirective on ENUM + + enum Episode @DummyDirective{ + JEDI + NEWHOPE + } + + type Query { + aQuery: String + } + ''' + when: + def schema = TestUtil.schema(dsl) + + then: + schema.getType("Episode") != null + schema.getType("Episode") instanceof GraphQLEnumType + ((GraphQLEnumType) schema.getType("Episode")).getValues().size() == 2 + ((GraphQLEnumType) schema.getType("Episode")).getDirective("DummyDirective").getName() == "DummyDirective" + + schema.getDirective("DummyDirective") != null + schema.getDirective("DummyDirective").validLocations().size() == 1 + schema.getDirective("DummyDirective").validLocations().asList() == [Introspection.DirectiveLocation.ENUM] + + schema.getDirective("testDirective") != null + schema.getDirective("testDirective").validLocations().size() == 2 + schema.getDirective("testDirective").validLocations().asList() == [Introspection.DirectiveLocation.OBJECT, Introspection.DirectiveLocation.ENUM] + ((GraphQLNamedInputType) schema.getDirective("testDirective").getArgument("anEnum").getType()).getName() == "Episode" + } + + + def "issues 2055 for directive on ENUM_VALUE"() { + given: + def dsl = ''' + directive @testDirective(anEnum: Episode = JEDI) on OBJECT | ENUM_VALUE + + directive @DummyDirective on ENUM_VALUE + + enum Episode { + JEDI @DummyDirective + NEWHOPE + } + + type Query { + aQuery: String + } + ''' + when: + def schema = TestUtil.schema(dsl) + + then: + schema.getType("Episode") != null + schema.getType("Episode") instanceof GraphQLEnumType + ((GraphQLEnumType) schema.getType("Episode")).getValues().size() == 2 + ((GraphQLEnumType) schema.getType("Episode")).getValue("JEDI").getDirective("DummyDirective").getName() == "DummyDirective" + + schema.getDirective("DummyDirective") != null + schema.getDirective("DummyDirective").validLocations().size() == 1 + schema.getDirective("DummyDirective").validLocations().asList() == [Introspection.DirectiveLocation.ENUM_VALUE] + + schema.getDirective("testDirective") != null + schema.getDirective("testDirective").validLocations().size() == 2 + schema.getDirective("testDirective").validLocations().asList() == [Introspection.DirectiveLocation.OBJECT, Introspection.DirectiveLocation.ENUM_VALUE] + ((GraphQLNamedInputType) schema.getDirective("testDirective").getArgument("anEnum").getType()).getName() == "Episode" + } + +} \ No newline at end of file diff --git a/src/test/groovy/graphql/Issue2068.groovy b/src/test/groovy/graphql/Issue2068.groovy new file mode 100644 index 0000000000..9b15e28085 --- /dev/null +++ b/src/test/groovy/graphql/Issue2068.groovy @@ -0,0 +1,193 @@ +package graphql + + +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.StaticDataFetcher +import graphql.schema.idl.RuntimeWiring +import org.apache.commons.lang3.concurrent.BasicThreadFactory +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderOptions +import org.dataloader.DataLoaderRegistry +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.concurrent.SynchronousQueue +import java.util.concurrent.ThreadFactory +import java.util.concurrent.ThreadPoolExecutor +import java.util.concurrent.TimeUnit + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class Issue2068 extends Specification { + def "shouldn't hang on exception in resolveFieldWithInfo"() { + setup: + def sdl = """ + type Nation { + name: String + } + + type Toy { + name: String + } + + type Owner { + nation: Nation + } + + type Cat { + toys: [Toy] + } + + type Dog { + owner: Owner + } + + type Pets { + cats: [Cat] + dogs: [Dog] + } + + type Query { + pets: Pets + } + """ + + def cats = [['id': "cat-1"]] + def dogs = [['id': "dog-1"]] + + ThreadFactory threadFactory = new BasicThreadFactory.Builder() + .namingPattern("resolver-chain-thread-%d").build() + def executor = new ThreadPoolExecutor(15, 15, 0L, + TimeUnit.MILLISECONDS, new SynchronousQueue<>(), threadFactory, + new ThreadPoolExecutor.CallerRunsPolicy()) + + DataFetcher nationsDf = { env -> + return env.getDataLoader("owner.nation").load(env) + } + DataFetcher ownersDf = { DataFetchingEnvironment env -> + return env.getDataLoader("dog.owner").load(env) + } + + def wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("pets", new StaticDataFetcher(['cats': cats, 'dogs': dogs]))) + .type(newTypeWiring("Cat") + .dataFetcher("toys", new StaticDataFetcher(new AbstractList() { + @Override + Object get(int i) { +// return "toy" + throw new RuntimeException("Simulated failure"); + } + + @Override + int size() { + return 1 + } + }))) + .type(newTypeWiring("Dog") + .dataFetcher("owner", ownersDf)) + .type(newTypeWiring("Owner") + .dataFetcher("nation", nationsDf)) + .build() + + def schema = TestUtil.schema(sdl, wiring) + + when: + def graphql = GraphQL.newGraphQL(schema) + .build() + DataLoaderRegistry dataLoaderRegistry = mkNewDataLoaderRegistry(executor) + + graphql.execute(newExecutionInput() + .dataLoaderRegistry(dataLoaderRegistry) + .query(""" + query LoadPets { + pets { + cats { + toys { + name + } + } + dogs { + owner { + nation { + name + } + } + } + } + } + """) + .build()) + + then: "execution with single instrumentation shouldn't hang" + // wait for each future to complete and grab the results + def e = thrown(RuntimeException) + + when: + graphql = GraphQL.newGraphQL(schema) + .build() + + graphql.execute(newExecutionInput() + .dataLoaderRegistry(dataLoaderRegistry) + .query(""" + query LoadPets { + pets { + cats { + toys { + name + } + } + dogs { + owner { + nation { + name + } + } + } + } + } + """) + .build()) + + then: "execution with chained instrumentation shouldn't hang" + // wait for each future to complete and grab the results + thrown(RuntimeException) + } + + private static DataLoaderRegistry mkNewDataLoaderRegistry(executor) { + def dataLoaderNations = new DataLoader(new BatchLoader>() { + @Override + CompletionStage>> load(List keys) { + return CompletableFuture.supplyAsync({ + def nations = [] + for (int i = 1; i <= 1; i++) { + nations.add(['id': "nation-$i", 'name': "nation-$i"]) + } + return nations + }, executor) as CompletionStage>> + } + }, DataLoaderOptions.newOptions().setMaxBatchSize(5)) + + def dataLoaderOwners = new DataLoader(new BatchLoader>() { + @Override + CompletionStage>> load(List keys) { + return CompletableFuture.supplyAsync({ + def owners = [] + for (int i = 1; i <= 1; i++) { + owners.add(['id': "owner-$i"]) + } + return owners + }, executor) as CompletionStage>> + } + }, DataLoaderOptions.newOptions().setMaxBatchSize(5)) + + def dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("dog.owner", dataLoaderOwners) + dataLoaderRegistry.register("owner.nation", dataLoaderNations) + dataLoaderRegistry + } +} diff --git a/src/test/groovy/graphql/Issue2114.groovy b/src/test/groovy/graphql/Issue2114.groovy new file mode 100644 index 0000000000..e4ad7fbda4 --- /dev/null +++ b/src/test/groovy/graphql/Issue2114.groovy @@ -0,0 +1,28 @@ +package graphql + +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import spock.lang.Specification + +class Issue2114 extends Specification { + + def "allow use of repeatable directives on extensions"() { + given: + def spec = "type Query {}" + + "directive @IamRepeatable repeatable on FIELD_DEFINITION" + + " extend type Query { " + + " test: String" + + " @IamRepeatable" + + " @IamRepeatable" + + "}" + + when: + def registry = new SchemaParser().parse(spec) + def graphQLSchema = new SchemaGenerator().makeExecutableSchema(registry, RuntimeWiring.newRuntimeWiring().build()) + + then: + graphQLSchema != null + } +} + diff --git a/src/test/groovy/graphql/Issue2141.groovy b/src/test/groovy/graphql/Issue2141.groovy new file mode 100644 index 0000000000..c3b00df8d6 --- /dev/null +++ b/src/test/groovy/graphql/Issue2141.groovy @@ -0,0 +1,70 @@ +package graphql + +import graphql.schema.idl.SchemaParser +import graphql.schema.idl.SchemaPrinter +import graphql.schema.idl.UnExecutableSchemaGenerator; + +import spock.lang.Specification + + +class Issue2141 extends Specification { + + def " remove redundant parenthesis "() { + when: + def schemaDesc = """ + directive @auth(roles: [String!]) on FIELD_DEFINITION + + type Query { + hello: String! @auth + } + """ + def schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(new SchemaParser().parse(schemaDesc)) + def schemaStr = new SchemaPrinter().print(schema) + + then: + schemaStr == '''directive @auth(roles: [String!]) on FIELD_DEFINITION + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type Query { + hello: String! @auth +} +''' + } +} diff --git a/src/test/groovy/graphql/Issue2274.groovy b/src/test/groovy/graphql/Issue2274.groovy new file mode 100644 index 0000000000..962f5e54cf --- /dev/null +++ b/src/test/groovy/graphql/Issue2274.groovy @@ -0,0 +1,110 @@ +package graphql + +import graphql.language.AstComparator +import graphql.language.Node +import graphql.language.ObjectTypeExtensionDefinition +import graphql.language.TypeName +import graphql.parser.Parser +import spock.lang.Specification + +class Issue2274 extends Specification { + boolean isEqual(Node node1, Node node2) { + return new AstComparator().isEqual(node1, node2) + } + + // This test happened to work previously, as there were no tokens following 'implements Thing' + def "extend type without text following works - schema build"() { + given: + def spec = ''' + type Query { + blob : Blob + } + + type Blob { + id: ID! + name: String + } + + interface Thing { + name: String + } + + input Interval { + now : Int + then : Int + } + + # random input + input AwesomeInput { + interval: Interval! + amount: Int! + } + + extend type Blob implements Thing + ''' + + when: + def schema = TestUtil.schema(spec) + + then: + schema != null + } + + // Placing an input immediately after extend type without braces previously failed + // The schema could not be compiled : SchemaProblem{errors=[The interface type 'input' is not present when resolving type + // 'Blob' [@20:13], The interface type 'AwesomeInput' is not present when resolving type 'Blob' [@20:13]]}. Expression: false + def "extend type with text following works - schema build"() { + given: + def spec = ''' + type Query { + blob : Blob + } + + type Blob { + id: ID! + name: String + } + + interface Thing { + name: String + } + + input Interval { + now : Int + then : Int + } + + extend type Blob implements Thing + + # random input + input AwesomeInput { + interval: Interval! + amount: Int! + } + ''' + + when: + def schema = TestUtil.schema(spec) + + then: + schema != null + } + + def "extend type with text following works - parser check"() { + given: + def spec = "extend type Blob implements Thing1 & Thing2 & Thing3" + + and: "expected schema" + def objSchema = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("Blob") + objSchema.implementz(new TypeName("Thing1")) + objSchema.implementz(new TypeName("Thing2")) + objSchema.implementz(new TypeName("Thing3")) + + when: + def document = new Parser().parseDocument(spec) + + then: + document.definitions.size() == 1 + isEqual(document.definitions[0], objSchema.build()) + } +} diff --git a/src/test/groovy/graphql/Issue296.groovy b/src/test/groovy/graphql/Issue296.groovy deleted file mode 100644 index e0ccc13549..0000000000 --- a/src/test/groovy/graphql/Issue296.groovy +++ /dev/null @@ -1,84 +0,0 @@ -package graphql - -import spock.lang.Specification - -import static graphql.Scalars.GraphQLString -import static graphql.schema.GraphQLArgument.newArgument -import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition -import static graphql.schema.GraphQLInputObjectField.newInputObjectField -import static graphql.schema.GraphQLInputObjectType.newInputObject -import static graphql.schema.GraphQLObjectType.newObject -import static graphql.schema.GraphQLSchema.newSchema - -class Issue296 extends Specification { - - def "test introspection for #296 with map"() { - - def graphql = GraphQL.newGraphQL(newSchema() - .query(newObject() - .name("Query") - .field(newFieldDefinition() - .name("field") - .type(GraphQLString) - .argument(newArgument() - .name("argument") - .type(newInputObject() - .name("InputObjectType") - .field(newInputObjectField() - .name("inputField") - .type(GraphQLString)) - .build()) - .defaultValue([inputField: 'value1'])))) - .build()) - .build() - - def query = '{ __type(name: "Query") { fields { args { defaultValue } } } }' - - expect: - // converts the default object value to AST, then graphql pretty prints that as the value - graphql.execute(query).data == - [__type: [fields: [[args: [[defaultValue: '{inputField : "value1"}']]]]]] - } - - class FooBar { - final String inputField = "foo" - final String bar = "bar" - - String getInputField() { - return inputField - } - - String getBar() { - return bar - } - } - - def "test introspection for #296 with some object"() { - - def graphql = GraphQL.newGraphQL(newSchema() - .query(newObject() - .name("Query") - .field(newFieldDefinition() - .name("field") - .type(GraphQLString) - .argument(newArgument() - .name("argument") - .type(newInputObject() - .name("InputObjectType") - .field(newInputObjectField() - .name("inputField") - .type(GraphQLString)) - .build()) - .defaultValue(new FooBar())))) - .build()) - .build() - - def query = '{ __type(name: "Query") { fields { args { defaultValue } } } }' - - expect: - // converts the default object value to AST, then graphql pretty prints that as the value - graphql.execute(query).data == - [__type: [fields: [[args: [[defaultValue: '{inputField : "foo"}']]]]]] - } -} - diff --git a/src/test/groovy/graphql/Issue3434.groovy b/src/test/groovy/graphql/Issue3434.groovy new file mode 100644 index 0000000000..4671c57ff8 --- /dev/null +++ b/src/test/groovy/graphql/Issue3434.groovy @@ -0,0 +1,26 @@ +package graphql + +import static graphql.schema.GraphQLUnionType.newUnionType +import static graphql.schema.GraphQLTypeReference.typeRef +import graphql.schema.idl.SchemaPrinter + +import spock.lang.Specification + +class Issue3434 extends Specification { + + def "allow printing of union types"() { + given: + def schema = newUnionType().name("Shape") + .possibleType(typeRef("Circle")) + .possibleType(typeRef("Square")) + .build() + + when: + def printer = new SchemaPrinter() + def result = printer.print(schema) + + then: + result.trim() == "union Shape = Circle | Square" + } +} + diff --git a/src/test/groovy/graphql/Issue526.groovy b/src/test/groovy/graphql/Issue526.groovy index daa9345e3e..8705e5abcd 100644 --- a/src/test/groovy/graphql/Issue526.groovy +++ b/src/test/groovy/graphql/Issue526.groovy @@ -52,15 +52,14 @@ class Issue526 extends Specification { } """ - def schema = TestUtil.schema(spec, newRuntimeWiring() + def graphQL = TestUtil.graphQL(spec, newRuntimeWiring() .type(newTypeWiring("Query").dataFetcher("droid", new DataFetcher() { @Override Object get(DataFetchingEnvironment environment) { return new Droid() } - }))) + }))).build() - def graphQL = GraphQL.newGraphQL(schema).build() def query = """ { droid { diff --git a/src/test/groovy/graphql/Issue739.groovy b/src/test/groovy/graphql/Issue739.groovy index c98c297384..e3e579ab6b 100644 --- a/src/test/groovy/graphql/Issue739.groovy +++ b/src/test/groovy/graphql/Issue739.groovy @@ -9,17 +9,17 @@ import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring class Issue739 extends Specification { - def "#739 test"() { + def "Arguments passed via variables are not validated"() { when: RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() .type(newTypeWiring("Query") - .dataFetcher("foo", - { env -> - Map map = new HashMap<>() - map.put("id", "abc") - return map + .dataFetcher("foo", + { env -> + Map map = new HashMap<>() + map.put("id", "abc") + return map }) .dataFetcher("bar", @@ -34,7 +34,7 @@ class Issue739 extends Specification { .build() - def schema = TestUtil.schema(""" + def graphQL = TestUtil.graphQL(""" schema { query: Query } @@ -56,11 +56,8 @@ class Issue739 extends Specification { type Foo implements Node { id: String } - """, runtimeWiring) - + """, runtimeWiring).build() - GraphQL graphQL = GraphQL.newGraphQL(schema) - .build() ExecutionInput noVarInput = ExecutionInput.newExecutionInput() .query('{ bar(input: 123) { id } } ') @@ -80,18 +77,17 @@ class Issue739 extends Specification { ExecutionInput varInput = ExecutionInput.newExecutionInput() .query('query Bar($input: BarInput!) {bar(input: $input) {id}}') .variables(variables) - .build() + .build() ExecutionResult varResult = graphQL - .executeAsync(varInput) - .join() + .executeAsync(varInput) + .join() then: varResult.data == null varResult.errors.size() == 1 varResult.errors[0].errorType == ErrorType.ValidationError - varResult.errors[0].message == "Variable 'input' has an invalid value. Expected type 'Map' but was 'Integer'." + - " Variables for input objects must be an instance of type 'Map'."; + varResult.errors[0].message == "Variable 'input' has an invalid value: Expected type 'Map' but was 'Integer'. Variables for input objects must be an instance of type 'Map'." varResult.errors[0].locations == [new SourceLocation(1, 11)] when: @@ -110,7 +106,7 @@ class Issue739 extends Specification { varResult.data == null varResult.errors.size() == 1 varResult.errors[0].errorType == ErrorType.ValidationError - varResult.errors[0].message == "Variable 'boom' has an invalid value. Expected type 'Int' but was 'String'." + varResult.errors[0].message == "Variable 'input' has an invalid value: Expected a value that can be converted to type 'Int' but it was a 'String'" varResult.errors[0].locations == [new SourceLocation(1, 11)] } } diff --git a/src/test/groovy/graphql/Issue743.groovy b/src/test/groovy/graphql/Issue743.groovy index 57323f2217..b6466c65d3 100644 --- a/src/test/groovy/graphql/Issue743.groovy +++ b/src/test/groovy/graphql/Issue743.groovy @@ -6,13 +6,11 @@ class Issue743 extends Specification { def "#743 missing variables"() { when: - def schema = TestUtil.schema(""" + def graphQL = TestUtil.graphQL(""" type Query { version : Int } - """) - - def graphQL = GraphQL.newGraphQL(schema).build() + """).build() def executionInput = ExecutionInput.newExecutionInput() .query(''' @@ -30,6 +28,6 @@ class Issue743 extends Specification { executionResult.data == null executionResult.errors.size() == 1 executionResult.errors[0].errorType == ErrorType.ValidationError - executionResult.errors[0].message == "Variable 'isTrue' has coerced Null value for NonNull type 'Boolean!'" + executionResult.errors[0].message == "Variable 'isTrue' has an invalid value: Variable 'isTrue' has coerced Null value for NonNull type 'Boolean!'" } } diff --git a/src/test/groovy/graphql/Issue921.groovy b/src/test/groovy/graphql/Issue921.groovy index f93efe245f..15d899d508 100644 --- a/src/test/groovy/graphql/Issue921.groovy +++ b/src/test/groovy/graphql/Issue921.groovy @@ -35,8 +35,7 @@ class Issue921 extends Specification { def typeRuntimeWiring = newTypeWiring('ThreadSort').enumValues(new NaturalEnumValuesProvider(ThreadSort)).build() def runtimeWiring = newRuntimeWiring().type(typeRuntimeWiring).build() - def qLSchema = TestUtil.schema(spec, runtimeWiring) - def graphql = GraphQL.newGraphQL(qLSchema).build() + def graphql = TestUtil.graphQL(spec, runtimeWiring).build() when: def result = graphql.execute(''' diff --git a/src/test/groovy/graphql/Issue938.groovy b/src/test/groovy/graphql/Issue938.groovy index cdb8afb0fb..1b2befcae8 100644 --- a/src/test/groovy/graphql/Issue938.groovy +++ b/src/test/groovy/graphql/Issue938.groovy @@ -13,7 +13,7 @@ import spock.lang.Specification class Issue938 extends Specification { - public static GraphQLScalarType GraphQLTimestamp = new GraphQLScalarType("Timestamp", "Timestamp", new Coercing() { + public static GraphQLScalarType GraphQLTimestamp = GraphQLScalarType.newScalar().name("Timestamp").description("Timestamp").coercing(new Coercing() { @Override Object serialize(Object input) { return input @@ -38,6 +38,7 @@ class Issue938 extends Specification { return calendar } }) + .build() class UserImpl { int id @@ -74,8 +75,7 @@ class Issue938 extends Specification { .dataFetcher("User", userDataFetcher) .build()) .build() - def schema = TestUtil.schema(schemaSDL, runtimeWiring) - def graphql = GraphQL.newGraphQL(schema).build(); + def graphql = TestUtil.graphQL(schemaSDL, runtimeWiring).build() when: def input = ExecutionInput.newExecutionInput() diff --git a/src/test/groovy/graphql/IssueNonNullDefaultAttribute.groovy b/src/test/groovy/graphql/IssueNonNullDefaultAttribute.groovy index be7b7a83ec..b92435efe8 100644 --- a/src/test/groovy/graphql/IssueNonNullDefaultAttribute.groovy +++ b/src/test/groovy/graphql/IssueNonNullDefaultAttribute.groovy @@ -11,8 +11,16 @@ import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring // See https://github.com/facebook/graphql/pull/418 class IssueNonNullDefaultAttribute extends Specification { def spec = ''' + input Locale { + country: String! = "CA" + language: String! = "en" + } + type Query { - name(characterNumber: Int! = 2): String + name( + characterNumber: Int! = 2 + locale: Locale! = {country: "US" language: "en"} + ): String } ''' @@ -20,14 +28,17 @@ class IssueNonNullDefaultAttribute extends Specification { @Override Object get(DataFetchingEnvironment env) { def number = env.getArgument("characterNumber") - return "Character No. " + number + def locale = env.getArgument("locale") + + def country = locale["country"] + def language = locale["language"] + return sprintf("Character No. $number $country-$language", number, country, language) } } def typeRuntimeWiring = newTypeWiring('Query').dataFetcher("name", nameFetcher).build() def runtimeWiring = newRuntimeWiring().type(typeRuntimeWiring).build() - def qLSchema = TestUtil.schema(spec, runtimeWiring) - def graphql = GraphQL.newGraphQL(qLSchema).build() + def graphql = TestUtil.graphQL(spec, runtimeWiring).build() def "Can omit non-null attributes that have default values"() { when: @@ -39,7 +50,7 @@ class IssueNonNullDefaultAttribute extends Specification { then: result.errors.isEmpty() - result.data == [name: "Character No. 2"] + result.data == [name: "Character No. 2 US-en"] } // Already works, should continue to work @@ -54,7 +65,7 @@ class IssueNonNullDefaultAttribute extends Specification { then: result.errors.size() == 1 result.errors[0].errorType == ErrorType.ValidationError - result.errors[0].message == "Validation error of type WrongType: argument 'characterNumber' with value 'NullValue{}' must not be null @ 'name'" + result.errors[0].message == "Validation error (WrongType@[name]) : argument 'characterNumber' with value 'NullValue{}' must not be null" result.errors[0].locations == [new SourceLocation(3, 26)] result.data == null @@ -71,7 +82,33 @@ class IssueNonNullDefaultAttribute extends Specification { then: result.errors.isEmpty() - result.data == [name: "Character No. 3"] + result.data == [name: "Character No. 3 US-en"] + } + + def "Can omit non-null attributes in input objects that have default values"() { + when: + def result = graphql.execute(''' + { + name(locale: {}) + } + ''') + + then: + result.errors.isEmpty() + result.data == [name: "Character No. 2 CA-en"] + } + + def "Provided non-null attribute in input objects will override default value"() { + when: + def result = graphql.execute(''' + { + name(locale: {language: "fr"}) + } + ''') + + then: + result.errors.isEmpty() + result.data == [name: "Character No. 2 CA-fr"] } } diff --git a/src/test/groovy/graphql/JvmSpecificTest.groovy b/src/test/groovy/graphql/JvmSpecificTest.groovy new file mode 100644 index 0000000000..d7e4e248cb --- /dev/null +++ b/src/test/groovy/graphql/JvmSpecificTest.groovy @@ -0,0 +1,17 @@ +package graphql + +import spock.lang.Specification + +import java.lang.reflect.Method + +class JvmSpecificTest extends Specification { + + def "javac -parameters is in place"() { + when: + Method method = ExecutionInput.class.getDeclaredMethods().toList().find {it.name == "transform"} + def parameters = method.getParameters() + then: + parameters.length == 1 + parameters[0].name == "builderConsumer" // without -parameters this would be "arg0" + } +} diff --git a/src/test/groovy/graphql/LargeSchemaDataFetcherTest.groovy b/src/test/groovy/graphql/LargeSchemaDataFetcherTest.groovy new file mode 100644 index 0000000000..1aa971c6e7 --- /dev/null +++ b/src/test/groovy/graphql/LargeSchemaDataFetcherTest.groovy @@ -0,0 +1,43 @@ +package graphql + + +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.PropertyDataFetcher +import graphql.schema.SingletonPropertyDataFetcher +import spock.lang.Specification + +class LargeSchemaDataFetcherTest extends Specification { + + def howManyFields = 100_000 + + def "large schema with lots of fields has the same property data fetcher by default"() { + def sdl = """ + type Query { + ${mkFields()} + } + """ + + when: + def schema = TestUtil.schema(sdl) + def codeRegistry = schema.getCodeRegistry() + def singletonDF = SingletonPropertyDataFetcher.singleton() + + then: + + for (int i = 0; i < howManyFields; i++) { + def fieldName = "f$i" + def fieldDef = GraphQLFieldDefinition.newFieldDefinition().name(fieldName).type(Scalars.GraphQLString).build() + def df = codeRegistry.getDataFetcher(FieldCoordinates.coordinates("Query", fieldName), fieldDef) + assert df == singletonDF + } + } + + def mkFields() { + StringBuilder sb = new StringBuilder() + for (int i = 0; i < howManyFields; i++) { + sb.append("f$i : String\n") + } + return sb.toString() + } +} diff --git a/src/test/groovy/graphql/LocalContextTest.groovy b/src/test/groovy/graphql/LocalContextTest.groovy new file mode 100644 index 0000000000..41a8593faf --- /dev/null +++ b/src/test/groovy/graphql/LocalContextTest.groovy @@ -0,0 +1,157 @@ +package graphql + +import graphql.execution.DataFetcherResult +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.TypeRuntimeWiring +import spock.lang.Specification + +class LocalContextTest extends Specification { + + // Configuration for the datafetchers for this schema, this will build a local context which will be consumed all the way down to the user + // of the comments + def graphql = TestUtil.graphQL(""" + type Query { + blog(arg: String): Blog! + } + + type Blog { + name: String! + echoLocalContext: String + comments: [Comment!]! + } + + type Comment { + author: User! + title: String! + body: String! + + } + + type User { + username: String! + } + """, + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Query") + .dataFetcher("blog", { + def blog = new Blog() + blog.name = "some name" + if (it.getArgument("arg") != null) { + DataFetcherResult.newResult() + .data("foo") + .localContext(it.getArgument("arg")) // here is where we build the initial context + .build() + } else { + DataFetcherResult.newResult() + .data(blog) + .localContext("BLOG CONTEXT") // here is where we build the initial context + .build() + } + }) + ) + .type(TypeRuntimeWiring.newTypeWiring("Blog") + .dataFetcher("echoLocalContext", { + return it.getLocalContext() + }) + .dataFetcher("comments", { + def comment = new Comment() + comment.title = it.getLocalContext() + " (comments data fetcher)" + DataFetcherResult.newResult() + .data([comment]) + .build() + }) + ) + .type(TypeRuntimeWiring.newTypeWiring("Comment") + .dataFetcher("body", { it.getLocalContext() + " (comment data fetcher)" }) + .dataFetcher("author", { new User() }) + ) + .type(TypeRuntimeWiring.newTypeWiring("User") + .dataFetcher("username", { it.getLocalContext() + " (user data fetcher)" }) + ) + .build()) + .build() + + def "when a local context is provided, it can be consumed by the grandchildren node data fetchers"() { + given: + def input = ExecutionInput.newExecutionInput() + .query(''' + query { + blog { + name + comments { + title + body + author { + username + } + } + } + } + ''') + .build() + when: + def executionResult = graphql.execute(input) + + then: + executionResult.errors.isEmpty() + executionResult.data == [ + blog: [ + name : "some name", + comments: [ + [ + title : "BLOG CONTEXT (comments data fetcher)", + body : "BLOG CONTEXT (comment data fetcher)", + author: [ + username: "BLOG CONTEXT (user data fetcher)" + ] + ] + ] + ] + ] + } + + def "different alias produce different local contexts"() { + given: + def input = ExecutionInput.newExecutionInput() + .query(''' + query { + blog1: blog(arg: "blog1") { + echoLocalContext + } + blog2: blog(arg: "blog2") { + echoLocalContext + } + } + ''') + .build() + when: + def executionResult = graphql.execute(input) + + then: + executionResult.errors.isEmpty() + executionResult.data == [ + blog1: [ + echoLocalContext: "blog1" + ], + blog2: [ + echoLocalContext: "blog2" + ] + ] + } + + // Really simply beans, without getters and setters for simplicity + static class User { + public String username + } + + static class Comment { + String title + String body + User author + } + + static class Blog { + String name + List comments + } +} diff --git a/src/test/groovy/graphql/MutationSchema.java b/src/test/groovy/graphql/MutationSchema.java index 2683652331..5956d7c56d 100644 --- a/src/test/groovy/graphql/MutationSchema.java +++ b/src/test/groovy/graphql/MutationSchema.java @@ -1,6 +1,9 @@ package graphql; +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; @@ -31,8 +34,8 @@ public void setTheNumber(int theNumber) { } public static class SubscriptionRoot { - List result = new ArrayList(); - List subscribers = new ArrayList(); + List result = new ArrayList<>(); + List subscribers = new ArrayList<>(); NumberHolder numberHolder; public SubscriptionRoot(int initalNumber) { @@ -89,23 +92,13 @@ public List getResult() { .type(numberHolderType) .argument(newArgument() .name("newNumber") - .type(GraphQLInt)) - .dataFetcher(environment -> { - Integer newNumber = environment.getArgument("newNumber"); - SubscriptionRoot root = environment.getSource(); - return root.changeNumber(newNumber); - })) + .type(GraphQLInt))) .field(newFieldDefinition() .name("failToChangeTheNumber") .type(numberHolderType) .argument(newArgument() .name("newNumber") - .type(GraphQLInt)) - .dataFetcher(environment -> { - Integer newNumber = environment.getArgument("newNumber"); - SubscriptionRoot root = environment.getSource(); - return root.failToChangeTheNumber(newNumber); - })) + .type(GraphQLInt))) .build(); public static GraphQLObjectType subscriptionType = GraphQLObjectType.newObject() @@ -115,16 +108,37 @@ public List getResult() { .type(numberHolderType) .argument(newArgument() .name("clientId") - .type(GraphQLInt)) - .dataFetcher(environment -> { - Integer clientId = environment.getArgument("clientId"); - SubscriptionRoot subscriptionRoot = environment.getSource(); - subscriptionRoot.subscribeToNumberChanges(clientId); - return subscriptionRoot.getNumberHolder(); - })) + .type(GraphQLInt))) + .build(); + + static FieldCoordinates changeMutationCoordinates = FieldCoordinates.coordinates("mutationType", "changeTheNumber"); + static DataFetcher changeMutationDataFetcher = environment -> { + Integer newNumber = environment.getArgument("newNumber"); + SubscriptionRoot root = environment.getSource(); + return root.changeNumber(newNumber); + }; + static FieldCoordinates failToChangeMutationCoordinates = FieldCoordinates.coordinates("mutationType", "failToChangeTheNumber"); + static DataFetcher failToChangeMutationDataFetcher = environment -> { + Integer newNumber = environment.getArgument("newNumber"); + SubscriptionRoot root = environment.getSource(); + return root.failToChangeTheNumber(newNumber); + }; + static FieldCoordinates changeNumberSubscribeCoordinates = FieldCoordinates.coordinates("subscriptionType", "changeNumberSubscribe"); + static DataFetcher changeNumberSubscribeDataFetcher = environment -> { + Integer clientId = environment.getArgument("clientId"); + SubscriptionRoot subscriptionRoot = environment.getSource(); + subscriptionRoot.subscribeToNumberChanges(clientId); + return subscriptionRoot.getNumberHolder(); + }; + + static GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(changeMutationCoordinates, changeMutationDataFetcher) + .dataFetcher(failToChangeMutationCoordinates, failToChangeMutationDataFetcher) + .dataFetcher(changeNumberSubscribeCoordinates, changeNumberSubscribeDataFetcher) .build(); public static GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) .query(queryType) .mutation(mutationType) .subscription(subscriptionType) diff --git a/src/test/groovy/graphql/MutationTest.groovy b/src/test/groovy/graphql/MutationTest.groovy index 68da613740..aa5813fe5f 100644 --- a/src/test/groovy/graphql/MutationTest.groovy +++ b/src/test/groovy/graphql/MutationTest.groovy @@ -1,7 +1,19 @@ package graphql + +import graphql.schema.DataFetcher +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.BatchLoaderWithContext +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry import spock.lang.Specification +import spock.lang.Unroll + +import java.util.concurrent.CompletableFuture +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING class MutationTest extends Specification { @@ -47,8 +59,8 @@ class MutationTest extends Specification { ] when: - def executionResult = GraphQL.newGraphQL(MutationSchema.schema).build().execute(query, new MutationSchema.SubscriptionRoot(6)) - + def ei = ExecutionInput.newExecutionInput(query).root(new MutationSchema.SubscriptionRoot(6)).build() + def executionResult = GraphQL.newGraphQL(MutationSchema.schema).build().execute(ei) then: executionResult.data == expectedResult @@ -93,8 +105,8 @@ class MutationTest extends Specification { ] when: - def executionResult = GraphQL.newGraphQL(MutationSchema.schema).build().execute(query, new MutationSchema.SubscriptionRoot(6)) - + def ei = ExecutionInput.newExecutionInput(query).root(new MutationSchema.SubscriptionRoot(6)).build() + def executionResult = GraphQL.newGraphQL(MutationSchema.schema).build().execute(ei) then: executionResult.data == expectedResult @@ -102,4 +114,610 @@ class MutationTest extends Specification { executionResult.errors.every({ it instanceof ExceptionWhileDataFetching }) } + + def "simple async mutation"() { + def sdl = """ + type Query { + q : String + } + + type Mutation { + plus1(arg: Int) : Int + plus2(arg: Int) : Int + plus3(arg: Int) : Int + } + """ + + def mutationDF = { env -> + CompletableFuture.supplyAsync { + + def fieldName = env.getField().name + def factor = Integer.parseInt(fieldName.substring(fieldName.length() - 1)) + def value = env.getArgument("arg") + + return value + factor + } + } as DataFetcher + + def schema = TestUtil.schema(sdl, [Mutation: [ + plus1: mutationDF, + plus2: mutationDF, + plus3: mutationDF, + ]]) + + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def er = graphQL.execute(""" + mutation m { + plus1(arg:10) + plus2(arg:10) + plus3(arg:10) + } + """) + + then: + er.errors.isEmpty() + er.data == [ + plus1: 11, + plus2: 12, + plus3: 13, + ] + } + + @Unroll + def "simple async mutation with DataLoader"() { + def sdl = """ + type Query { + q : String + } + + type Mutation { + plus1(arg: Int) : Int + plus2(arg: Int) : Int + plus3(arg: Int) : Int + } + + """ + + BatchLoader batchLoader = { keys -> + CompletableFuture.supplyAsync { + return keys + } + + } as BatchLoader + + + DataLoaderRegistry dlReg = DataLoaderRegistry.newRegistry() + .register("dl", DataLoaderFactory.newDataLoader(batchLoader)) + .build() + + def mutationDF = { env -> + def fieldName = env.getField().name + def factor = Integer.parseInt(fieldName.substring(fieldName.length() - 1)) + def value = env.getArgument("arg") + + def key = value + factor + return env.getDataLoader("dl").load(key) + } as DataFetcher + + def schema = TestUtil.schema(sdl, [Mutation: [ + plus1: mutationDF, + plus2: mutationDF, + plus3: mutationDF, + ]]) + + + def graphQL = GraphQL.newGraphQL(schema) + .build() + + + def ei = ExecutionInput.newExecutionInput(""" + mutation m { + plus1(arg:10) + plus2(arg:10) + plus3(arg:10) + } + """).graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .dataLoaderRegistry(dlReg).build() + when: + def er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [ + plus1: 11, + plus2: 12, + plus3: 13, + ] + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + } + + /* + This test shows a dataloader being called at the mutation field level, in serial via AsyncSerialExecutionStrategy, and then + again at the sub field level, in parallel, via AsyncExecutionStrategy. + */ + + @Unroll + def "more complex async mutation with DataLoader"() { + def sdl = """ + type Query { + q : String + } + + type Mutation { + topLevelF1(arg: Int) : ComplexType + topLevelF2(arg: Int) : ComplexType + topLevelF3(arg: Int) : ComplexType + topLevelF4(arg: Int) : ComplexType + } + + type ComplexType { + f1 : ComplexType + f2 : ComplexType + f3 : ComplexType + f4 : ComplexType + end : String + } + """ + + def emptyComplexMap = [ + f1: null, + f2: null, + f3: null, + f4: null, + ] + + BatchLoaderWithContext fieldBatchLoader = { keys, context -> + assert keys.size() == 2, "since only f1 and f2 are DL based, we will only get 2 key values" + + def batchValue = [ + emptyComplexMap, + emptyComplexMap, + ] + CompletableFuture.supplyAsync { + return batchValue + } + + } as BatchLoaderWithContext + + BatchLoader mutationBatchLoader = { keys -> + CompletableFuture.supplyAsync { + return keys + } + + } as BatchLoader + + + DataLoaderRegistry dlReg = DataLoaderRegistry.newRegistry() + .register("topLevelDL", DataLoaderFactory.newDataLoader(mutationBatchLoader)) + .register("fieldDL", DataLoaderFactory.newDataLoader(fieldBatchLoader)) + .build() + + def mutationDF = { env -> + def fieldName = env.getField().name + def factor = Integer.parseInt(fieldName.substring(fieldName.length() - 1)) + def value = env.getArgument("arg") + + def key = value + factor + return env.getDataLoader("topLevelDL").load(key) + } as DataFetcher + + def fieldDataLoaderDF = { env -> + def fieldName = env.getField().name + def level = env.getExecutionStepInfo().getPath().getLevel() + return env.getDataLoader("fieldDL").load(fieldName, level) + } as DataFetcher + + def fieldDataLoaderNonDF = { env -> + return emptyComplexMap + } as DataFetcher + + def schema = TestUtil.schema(sdl, + [Mutation : [ + topLevelF1: mutationDF, + topLevelF2: mutationDF, + topLevelF3: mutationDF, + topLevelF4: mutationDF, + ], + // only f1 and f3 are using data loaders - f2 and f4 are plain old property based + // so some fields with batch loader and some without + ComplexType: [ + f1: fieldDataLoaderDF, + f2: fieldDataLoaderNonDF, + f3: fieldDataLoaderDF, + f4: fieldDataLoaderNonDF, + ] + ]) + + + def graphQL = GraphQL.newGraphQL(schema) + .build() + + + def ei = ExecutionInput.newExecutionInput(""" + mutation m { + topLevelF1(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + + topLevelF2(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + + topLevelF3(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + + topLevelF4(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + } + """).dataLoaderRegistry(dlReg).graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]).build() + when: + def cf = graphQL.executeAsync(ei) + + Awaitility.await().until { cf.isDone() } + def er = cf.join() + + then: + + er.errors.isEmpty() + + def expectedMap = [ + f1: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + f2: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + f3: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + f4: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + ] + + er.data == [ + topLevelF1: expectedMap, + topLevelF2: expectedMap, + topLevelF3: expectedMap, + topLevelF4: expectedMap, + ] + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + } + + + @Unroll + def "stress test mutation with dataloader"() { + when: + // concurrency bugs are hard to find, so run this test a lot of times + for (int i = 0; i < 150; i++) { + println "iteration $i" + runTest(contextKey) + } + then: + noExceptionThrown() + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + } + + def runTest(String contextKey) { + def sdl = """ + type Query { + q : String + } + + type Mutation { + topLevelF1(arg: Int) : ComplexType + topLevelF2(arg: Int) : ComplexType + topLevelF3(arg: Int) : ComplexType + topLevelF4(arg: Int) : ComplexType + } + + type ComplexType { + f1 : ComplexType + f2 : ComplexType + f3 : ComplexType + f4 : ComplexType + end : String + } + """ + + def emptyComplexMap = [ + f1: null, + f2: null, + f3: null, + f4: null, + ] + + BatchLoaderWithContext fieldBatchLoader = { keys, context -> + assert keys.size() == 2, "since only f1 and f2 are DL based, we will only get 2 key values" + + def batchValue = [ + emptyComplexMap, + emptyComplexMap, + ] + CompletableFuture.supplyAsync { + return batchValue + } + + } as BatchLoaderWithContext + + BatchLoader mutationBatchLoader = { keys -> + CompletableFuture.supplyAsync { + return keys + } + + } as BatchLoader + + + DataLoaderRegistry dlReg = DataLoaderRegistry.newRegistry() + .register("topLevelDL", DataLoaderFactory.newDataLoader(mutationBatchLoader)) + .register("fieldDL", DataLoaderFactory.newDataLoader(fieldBatchLoader)) + .build() + + def mutationDF = { env -> + def fieldName = env.getField().name + def factor = Integer.parseInt(fieldName.substring(fieldName.length() - 1)) + def value = env.getArgument("arg") + + def key = value + factor + return env.getDataLoader("topLevelDL").load(key) + } as DataFetcher + + def fieldDataLoaderDF = { env -> + def fieldName = env.getField().name + def level = env.getExecutionStepInfo().getPath().getLevel() + return env.getDataLoader("fieldDL").load(fieldName, level) + } as DataFetcher + + def fieldDataLoaderNonDF = { env -> + return emptyComplexMap + } as DataFetcher + + def schema = TestUtil.schema(sdl, + [Mutation : [ + topLevelF1: mutationDF, + topLevelF2: mutationDF, + topLevelF3: mutationDF, + topLevelF4: mutationDF, + ], + // only f1 and f3 are using data loaders - f2 and f4 are plain old property based + // so some fields with batch loader and some without + ComplexType: [ + f1: fieldDataLoaderDF, + f2: fieldDataLoaderNonDF, + f3: fieldDataLoaderDF, + f4: fieldDataLoaderNonDF, + ] + ]) + + + def graphQL = GraphQL.newGraphQL(schema) + .build() + + + def ei = ExecutionInput.newExecutionInput(""" + mutation m { + topLevelF1(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + + topLevelF2(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + + topLevelF3(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + + topLevelF4(arg:10) { + f1 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f2 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f3 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + f4 { + f1 { end } + f2 { end } + f3 { end } + f4 { end } + } + } + } + """).dataLoaderRegistry(dlReg).graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]).build() + def cf = graphQL.executeAsync(ei) + + Awaitility.await().until { cf.isDone() } + def er = cf.join() + + assert er.errors.isEmpty() + + def expectedMap = [ + f1: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + f2: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + f3: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + f4: [f1: [end: null], f2: [end: null], f3: [end: null], f4: [end: null]], + ] + + assert er.data == [ + topLevelF1: expectedMap, + topLevelF2: expectedMap, + topLevelF3: expectedMap, + topLevelF4: expectedMap, + ] + } + } diff --git a/src/test/groovy/graphql/NestedInputSchema.java b/src/test/groovy/graphql/NestedInputSchema.java index add9b44c4d..6e19825914 100644 --- a/src/test/groovy/graphql/NestedInputSchema.java +++ b/src/test/groovy/graphql/NestedInputSchema.java @@ -1,6 +1,9 @@ package graphql; +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLInputObjectField; import graphql.schema.GraphQLInputObjectType; @@ -14,51 +17,53 @@ public class NestedInputSchema { - public static GraphQLSchema createSchema() { + GraphQLObjectType root = rootType(); + FieldCoordinates valueCoordinates = FieldCoordinates.coordinates("Root", "value"); + DataFetcher valueDataFetcher = environment -> { + Integer initialValue = environment.getArgument("initialValue"); + Map filter = environment.getArgument("filter"); + if (filter != null) { + if (filter.containsKey("even")) { + Boolean even = (Boolean) filter.get("even"); + if (even && (initialValue % 2 != 0)) { + return 0; + } else if (!even && (initialValue % 2 == 0)) { + return 0; + } + } + if (filter.containsKey("range")) { + Map range = (Map) filter.get("range"); + if (initialValue < range.get("lowerBound") || + initialValue > range.get("upperBound")) { + return 0; + } + } + } + return initialValue; + }; - GraphQLObjectType root = rootType(); + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(valueCoordinates, valueDataFetcher) + .build(); return GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) .query(root) .build(); } - @SuppressWarnings("unchecked") public static GraphQLObjectType rootType() { return GraphQLObjectType.newObject() - .name("Root") .field(GraphQLFieldDefinition.newFieldDefinition() .name("value") .type(GraphQLInt) - .dataFetcher(environment -> { - Integer initialValue = environment.getArgument("initialValue"); - Map filter = environment.getArgument("filter"); - if (filter != null) { - if (filter.containsKey("even")) { - Boolean even = (Boolean) filter.get("even"); - if (even && (initialValue % 2 != 0)) { - return 0; - } else if (!even && (initialValue % 2 == 0)) { - return 0; - } - } - if (filter.containsKey("range")) { - Map range = (Map) filter.get("range"); - if (initialValue < range.get("lowerBound") || - initialValue > range.get("upperBound")) { - return 0; - } - } - } - return initialValue; - }) .argument(GraphQLArgument.newArgument() .name("intialValue") .type(GraphQLInt) - .defaultValue(5)) + .defaultValueProgrammatic(5)) .argument(GraphQLArgument.newArgument() .name("filter") .type(filterType()))) diff --git a/src/test/groovy/graphql/NonNullHandlingTest.groovy b/src/test/groovy/graphql/NonNullHandlingTest.groovy index 8fdb505da9..a6a352ef93 100644 --- a/src/test/groovy/graphql/NonNullHandlingTest.groovy +++ b/src/test/groovy/graphql/NonNullHandlingTest.groovy @@ -2,7 +2,10 @@ package graphql import graphql.execution.AsyncExecutionStrategy import graphql.execution.AsyncSerialExecutionStrategy -import graphql.execution.ExecutorServiceExecutionStrategy +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLOutputType import graphql.schema.GraphQLSchema import spock.lang.Specification @@ -14,7 +17,6 @@ import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull import static graphql.schema.GraphQLObjectType.newObject import static graphql.schema.GraphQLSchema.newSchema -import static java.util.concurrent.ForkJoinPool.commonPool /** * A set of tests to show how non null field handling correctly bubble up or not @@ -34,37 +36,48 @@ class NonNullHandlingTest extends Specification { SimpleObject nonNullParent = new SimpleObject() } - def executionInput(String query) { + static def executionInput(String query) { ExecutionInput.newExecutionInput().query(query).build() } @Unroll def "#268 - null child field values are allowed in nullable parent type (strategy: #strategyName)"() { - // see https://github.com/graphql-java/graphql-java/issues/268 given: - - + def rootTypeName = "RootQueryType" + def parentFieldName = "parent" GraphQLOutputType parentType = newObject() .name("currentType") - .field(newFieldDefinition().name("nullChild") - .type(nonNull(GraphQLString))) - .field(newFieldDefinition().name("nonNullChild") - .type(nonNull(GraphQLString))) + .field(newFieldDefinition() + .name("nullChild") + .type(nonNull(GraphQLString))) + .field(newFieldDefinition() + .name("nonNullChild") + .type(nonNull(GraphQLString))) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field(newFieldDefinition() - .name("parent") - .type(parentType) // nullable parent - .dataFetcher({ env -> new SimpleObject() }) - - )) + def parentCoordinates = FieldCoordinates.coordinates(rootTypeName, parentFieldName) + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return new SimpleObject() + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(parentCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(rootTypeName) + .field(newFieldDefinition() + .name(parentFieldName) + .type(parentType) // nullable parent + ) + ).build() + def query = """ query { parent { @@ -88,39 +101,48 @@ class NonNullHandlingTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() } @Unroll def "#268 - null child field values are NOT allowed in non nullable parent types (strategy: #strategyName)"() { - // see https://github.com/graphql-java/graphql-java/issues/268 given: - + def rootTypeName = "RootQueryType" + def parentFieldName = "parent" GraphQLOutputType parentType = newObject() .name("currentType") .field(newFieldDefinition().name("nullChild") - .type(nonNull(GraphQLString))) + .type(nonNull(GraphQLString))) .field(newFieldDefinition().name("nonNullChild") - .type(nonNull(GraphQLString))) + .type(nonNull(GraphQLString))) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field( - newFieldDefinition() - .name("parent") - .type(nonNull(parentType)) // non nullable parent - .dataFetcher({ env -> new SimpleObject() }) - - )) + def parentCoordinates = FieldCoordinates.coordinates(rootTypeName, parentFieldName) + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return new SimpleObject() + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(parentCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(rootTypeName) + .field( + newFieldDefinition() + .name(parentFieldName) + .type(nonNull(parentType)) // non nullable parent + ) + ).build() + def query = """ query { parent { @@ -151,37 +173,52 @@ class NonNullHandlingTest extends Specification { @Unroll def "#581 - null child field values are allowed in nullable grand parent type (strategy: #strategyName)"() { - given: + def rootTypeName = "RootQueryType" + def topFieldName = "top" GraphQLOutputType parentType = newObject() .name("parentType") - .field(newFieldDefinition().name("nullChild") - .type(nonNull(GraphQLString))) - .field(newFieldDefinition().name("nonNullChild") - .type(nonNull(GraphQLString))) + .field(newFieldDefinition() + .name("nullChild") + .type(nonNull(GraphQLString))) + .field(newFieldDefinition() + .name("nonNullChild") + .type(nonNull(GraphQLString))) .build() GraphQLOutputType topType = newObject() .name("topType") - .field(newFieldDefinition().name("nullParent") - .type(nonNull(parentType))) - .field(newFieldDefinition().name("nonNullParent") - .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nullParent") + .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nonNullParent") + .type(nonNull(parentType))) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field( - newFieldDefinition() - .name("top") + def topCoordinates = FieldCoordinates.coordinates(rootTypeName, topFieldName) + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return new ContainingObject() + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(topCoordinates, dataFetcher) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(rootTypeName) + .field(newFieldDefinition() + .name(topFieldName) .type(topType) // nullable grand parent - .dataFetcher({ env -> new ContainingObject() }) - )) - .build() + ) + ).build() def query = """ query { @@ -209,7 +246,6 @@ class NonNullHandlingTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() @@ -219,36 +255,50 @@ class NonNullHandlingTest extends Specification { def "#581 - null child field values are NOT allowed in non nullable grand parent types (strategy: #strategyName)"() { given: - + def rootTypeName = "RootQueryType" + def topFieldName = "top" GraphQLOutputType parentType = newObject() .name("parentType") - .field(newFieldDefinition().name("nullChild") - .type(nonNull(GraphQLString))) - .field(newFieldDefinition().name("nonNullChild") - .type(nonNull(GraphQLString))) + .field(newFieldDefinition() + .name("nullChild") + .type(nonNull(GraphQLString))) + .field(newFieldDefinition() + .name("nonNullChild") + .type(nonNull(GraphQLString))) .build() GraphQLOutputType topType = newObject() .name("topType") - .field(newFieldDefinition().name("nullParent") - .type(nonNull(parentType))) - .field(newFieldDefinition().name("nonNullParent") - .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nullParent") + .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nonNullParent") + .type(nonNull(parentType))) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field( - newFieldDefinition() - .name("top") - .type(nonNull(topType)) // non nullable grand parent - .dataFetcher({ env -> new ContainingObject() }) - - )) + def topCoordinates = FieldCoordinates.coordinates(rootTypeName, topFieldName) + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return new ContainingObject() + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(topCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(rootTypeName) + .field(newFieldDefinition() + .name(topFieldName) + .type(nonNull(topType)) // non nullable grand parent + ) + ).build() + def query = """ query { top { @@ -275,7 +325,6 @@ class NonNullHandlingTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() @@ -285,34 +334,47 @@ class NonNullHandlingTest extends Specification { def "#561 - null entry in non null list type with non null wrapper list (strategy: #strategyName)"() { given: - + def rootTypeName = "RootQueryType" + def topFieldName = "top" GraphQLOutputType parentType = newObject() .name("parentType") - .field(newFieldDefinition().name("nonNullListWithNull") - .type(nonNull(list(nonNull(GraphQLString))))) + .field(newFieldDefinition() + .name("nonNullListWithNull") + .type(nonNull(list(nonNull(GraphQLString))))) .build() GraphQLOutputType topType = newObject() .name("topType") - .field(newFieldDefinition().name("nullParent") - .type(nonNull(parentType))) - .field(newFieldDefinition().name("nonNullParent") - .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nullParent") + .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nonNullParent") + .type(nonNull(parentType))) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field( - newFieldDefinition() - .name("top") - .type(nonNull(topType)) // non nullable grand parent - .dataFetcher({ env -> new ContainingObject() }) - - )) + def topCoordinates = FieldCoordinates.coordinates(rootTypeName, topFieldName) + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return new ContainingObject() + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(topCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(rootTypeName) + .field(newFieldDefinition() + .name(topFieldName) + .type(nonNull(topType)) // non nullable grand parent + ) + ).build() + def query = """ query { top { @@ -338,8 +400,8 @@ class NonNullHandlingTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) - 'async' | new AsyncExecutionStrategy() +// 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) +// 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() } @@ -349,33 +411,47 @@ class NonNullHandlingTest extends Specification { given: + def rootTypeName = "RootQueryType" + def topFieldName = "top" GraphQLOutputType parentType = newObject() .name("parentType") - .field(newFieldDefinition().name("nullableListWithNull") - .type(list(nonNull(GraphQLString)))) + .field(newFieldDefinition() + .name("nullableListWithNull") + .type(list(nonNull(GraphQLString)))) .build() GraphQLOutputType topType = newObject() .name("topType") - .field(newFieldDefinition().name("nullParent") - .type(nonNull(parentType))) - .field(newFieldDefinition().name("nonNullParent") - .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nullParent") + .type(nonNull(parentType))) + .field(newFieldDefinition() + .name("nonNullParent") + .type(nonNull(parentType))) .build() - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field( - newFieldDefinition() - .name("top") - .type(nonNull(topType)) // non nullable grand parent - .dataFetcher({ env -> new ContainingObject() }) - - )) + def topCoordinates = FieldCoordinates.coordinates(rootTypeName, topFieldName) + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return new ContainingObject() + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(topCoordinates, dataFetcher) .build() + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(rootTypeName) + .field(newFieldDefinition() + .name(topFieldName) + .type(nonNull(topType)) // non nullable grand parent + ) + ).build() + def query = """ query { top { @@ -401,7 +477,6 @@ class NonNullHandlingTest extends Specification { where: strategyName | executionStrategy - 'executor' | new ExecutorServiceExecutionStrategy(commonPool()) 'async' | new AsyncExecutionStrategy() 'asyncSerial' | new AsyncSerialExecutionStrategy() } diff --git a/src/test/groovy/graphql/NullValueSupportTest.groovy b/src/test/groovy/graphql/NullValueSupportTest.groovy index 52b52715dd..0a854cb6c3 100644 --- a/src/test/groovy/graphql/NullValueSupportTest.groovy +++ b/src/test/groovy/graphql/NullValueSupportTest.groovy @@ -7,8 +7,10 @@ import graphql.validation.ValidationErrorType import spock.lang.Specification import spock.lang.Unroll +import static graphql.ExecutionInput.newExecutionInput + /* - * Taken from http://facebook.github.io/graphql/#sec-Input-Objects + * Taken from https://spec.graphql.org/October2021/#sec-Input-Objects * * @@ -63,11 +65,14 @@ class NullValueSupportTest extends Specification { "test graphql spec examples that output results : #testCase"() { def fetcher = new CapturingDataFetcher() - def schema = TestUtil.schema(graphqlSpecExamples, ["Mutation": ["mutate": fetcher]]) + def graphQL = TestUtil.graphQL(graphqlSpecExamples, ["Mutation": ["mutate": fetcher]]).build() when: - def result = GraphQL.newGraphQL(schema).build().execute(queryStr, "mutate", "ctx", variables) + def executionInput = newExecutionInput().query(queryStr) + .operationName("mutate").variables(variables) + .build() + def result = graphQL.execute(executionInput) then: assert result.errors.isEmpty(): "Validation Failure in case ${testCase} : $result.errors" @@ -162,13 +167,16 @@ class NullValueSupportTest extends Specification { "test graphql spec examples that output errors #testCase"() { def fetcher = new CapturingDataFetcher() - def schema = TestUtil.schema(graphqlSpecExamples, ["Mutation": ["mutate": fetcher]]) + def graphQL = TestUtil.graphQL(graphqlSpecExamples, ["Mutation": ["mutate": fetcher]]).build() when: ExecutionResult result = null try { - result = GraphQL.newGraphQL(schema).build().execute(queryStr, "mutate", "ctx", variables) + def executionInput = newExecutionInput().query(queryStr) + .operationName("mutate").variables(variables) + .build() + result = graphQL.execute(executionInput) } catch (GraphQLException e) { assert false: "Unexpected exception during ${testCase} : ${e.message}" } @@ -206,10 +214,13 @@ class NullValueSupportTest extends Specification { "test graphql spec examples that output errors via internally throwing exception : #testCase"() { def fetcher = new CapturingDataFetcher() - def schema = TestUtil.schema(graphqlSpecExamples, ["Mutation": ["mutate": fetcher]]) + def graphQL = TestUtil.graphQL(graphqlSpecExamples, ["Mutation": ["mutate": fetcher]]).build() when: - def executionResult = GraphQL.newGraphQL(schema).build().execute(queryStr, "mutate", "ctx", variables) + def executionInput = newExecutionInput().query(queryStr) + .operationName("mutate").variables(variables) + .build() + def executionResult = graphQL.execute(executionInput) then: executionResult.data == null @@ -274,7 +285,7 @@ class NullValueSupportTest extends Specification { def fetcher = new CapturingDataFetcher() - def schema = TestUtil.schema(""" + def graphQL = TestUtil.graphQL(""" schema { query : Query } type Query { @@ -293,10 +304,13 @@ class NullValueSupportTest extends Specification { "list" : fetcher, "scalar" : fetcher, "complex": fetcher, - ]]) + ]]).build() when: - def result = GraphQL.newGraphQL(schema).build().execute(queryStr, null, "ctx", [:]) + def executionInput = newExecutionInput().query(queryStr) + .operationName(null).variables([:]) + .build() + def result = graphQL.execute(executionInput) assert result.errors.isEmpty(): "Unexpected query errors : ${result.errors}" then: diff --git a/src/test/groovy/graphql/NullVariableCoercionTest.groovy b/src/test/groovy/graphql/NullVariableCoercionTest.groovy index c96b674f18..ffd42ac362 100644 --- a/src/test/groovy/graphql/NullVariableCoercionTest.groovy +++ b/src/test/groovy/graphql/NullVariableCoercionTest.groovy @@ -1,10 +1,12 @@ package graphql import graphql.language.SourceLocation +import graphql.schema.DataFetcher import graphql.schema.GraphQLObjectType import graphql.schema.idl.RuntimeWiring import spock.lang.Specification +import static graphql.ExecutionInput.newExecutionInput import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring class NullVariableCoercionTest extends Specification { @@ -14,20 +16,20 @@ class NullVariableCoercionTest extends Specification { when: RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() - .type(newTypeWiring("Query") - .dataFetcher("bar", - { env -> - Map map = new HashMap<>() - map.put("id", "def") - return map - }) - ) - .type(newTypeWiring("Node") - .typeResolver({ env -> (GraphQLObjectType) env.getSchema().getType("Foo") })) - .build() - - - def schema = TestUtil.schema(""" + .type(newTypeWiring("Query") + .dataFetcher("bar", + { env -> + Map map = new HashMap<>() + map.put("id", "def") + return map + }) + ) + .type(newTypeWiring("Node") + .typeResolver({ env -> (GraphQLObjectType) env.getSchema().getType("Foo") })) + .build() + + + def graphQL = TestUtil.graphQL(""" schema { query: Query } @@ -47,30 +49,76 @@ class NullVariableCoercionTest extends Specification { type Foo implements Node { id: String } - """, runtimeWiring) + """, runtimeWiring).build() - GraphQL graphQL = GraphQL.newGraphQL(schema) - .build() - def variables = ["input": ["baz": null]] - ExecutionInput varInput = ExecutionInput.newExecutionInput() - .query('query Bar($input: BarInput!) {bar(input: $input) {id}}') - .variables(variables) - .build() + ExecutionInput varInput = newExecutionInput() + .query('query Bar($input: BarInput!) {bar(input: $input) {id}}') + .variables(variables) + .build() ExecutionResult varResult = graphQL - .executeAsync(varInput) - .join() + .executeAsync(varInput) + .join() then: varResult.data == null varResult.errors.size() == 1 varResult.errors[0].errorType == ErrorType.ValidationError - varResult.errors[0].message == "Variable 'input' has coerced Null value for NonNull type 'String!'" + varResult.errors[0].message == "Variable 'input' has an invalid value: Field 'baz' has coerced Null value for NonNull type 'String!'" varResult.errors[0].locations == [new SourceLocation(1, 11)] } + + def "can handle defaulting on complex input objects"() { + def sdl = ''' + input Kitchen { + pantry : String + } + + input ListSnacksInput { + kitchen: [Kitchen!]! = [{pantry : "Cheezels"}] + snackType : String = "healthy" + startPageToken: String + } + + type Snacks { + name : String + } + + type Query { + listSnacks(input: ListSnacksInput!) : [Snacks!]! + } + ''' + + + DataFetcher df = { env -> + def val = env.getArgument("input") + assert val instanceof Map + def defaultedKitchenList = val["kitchen"] + assert defaultedKitchenList instanceof List + def snackVal = defaultedKitchenList[0]["pantry"] + def snack = [name: snackVal] + return [snack] + } + + def graphQL = TestUtil.graphQL(sdl, [Query: [listSnacks: df]]).build() + + def query = ''' + query ($input: ListSnacksInput!){ + listSnacks(input: $input) { + name + } + } + ''' + + when: + def er = graphQL.execute(newExecutionInput(query).variables([input: [startPageToken: "dummyToken"]])) + then: + er.errors.isEmpty() + er.data == [listSnacks: [[name: "Cheezels"]]] + } } diff --git a/src/test/groovy/graphql/ParseAndValidateTest.groovy b/src/test/groovy/graphql/ParseAndValidateTest.groovy new file mode 100644 index 0000000000..fa66c3cbed --- /dev/null +++ b/src/test/groovy/graphql/ParseAndValidateTest.groovy @@ -0,0 +1,238 @@ +package graphql + +import graphql.language.Document +import graphql.language.SourceLocation +import graphql.parser.InvalidSyntaxException +import graphql.parser.Parser +import graphql.schema.idl.SchemaParser +import graphql.schema.idl.UnExecutableSchemaGenerator +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import graphql.validation.rules.NoUnusedFragments +import spock.lang.Specification + +import java.util.function.Predicate + +/** + * We trust that other unit tests of the parser and validation catch ALL of the combinations. These tests + * just show the combination of parsing and validation. + */ +class ParseAndValidateTest extends Specification { + + def "can parse a basic document"() { + + def input = ExecutionInput.newExecutionInput("query { hi }").variables([var1: 1]).build() + + when: + def result = ParseAndValidate.parse(input) + then: + !result.isFailure() + result.errors.isEmpty() + result.document != null + result.variables == [var1: 1] + result.syntaxException == null + } + + def "will pick up invalid documents"() { + + def input = ExecutionInput.newExecutionInput("query { hi( ").variables([var1: 1]).build() + + when: + def result = ParseAndValidate.parse(input) + then: + result.isFailure() + !result.errors.isEmpty() + result.document == null + result.variables == [var1: 1] + result.syntaxException instanceof InvalidSyntaxException + } + + def "will validate documents with no problems"() { + + def input = ExecutionInput.newExecutionInput("query { hero { name }}").variables([var1: 1]).build() + def result = ParseAndValidate.parse(input) + + when: + def errors = ParseAndValidate.validate(StarWarsSchema.starWarsSchema, result.getDocument(), input.getLocale()) + + then: + errors.isEmpty() + } + + def "will validate documents with actual problems"() { + + def input = ExecutionInput.newExecutionInput("query { hero }").variables([var1: 1]).build() + def result = ParseAndValidate.parse(input) + + when: + def errors = ParseAndValidate.validate(StarWarsSchema.starWarsSchema, result.getDocument(), input.getLocale()) + + then: + !errors.isEmpty() + errors[0].validationErrorType == ValidationErrorType.SubselectionRequired + } + + def "can combine parse and validation on valid input"() { + def input = ExecutionInput.newExecutionInput("query { hero { name }}").variables([var1: 1]).build() + + when: + def result = ParseAndValidate.parseAndValidate(StarWarsSchema.starWarsSchema, input) + then: + !result.isFailure() + result.errors.isEmpty() + result.validationErrors.isEmpty() + result.document != null + result.variables == [var1: 1] + result.syntaxException == null + } + + def "can combine parse and validation on VALID syntax but INVALID semantics"() { + def input = ExecutionInput.newExecutionInput("query { hero }").variables([var1: 1]).build() + + when: + def result = ParseAndValidate.parseAndValidate(StarWarsSchema.starWarsSchema, input) + then: + result.isFailure() + !result.errors.isEmpty() + !result.validationErrors.isEmpty() + result.document != null + result.variables == [var1: 1] + result.syntaxException == null + + (result.errors[0] as ValidationError).validationErrorType == ValidationErrorType.SubselectionRequired + } + + def "can shortcut on parse and validation on INVALID syntax"() { + def input = ExecutionInput.newExecutionInput("query { hero(").variables([var1: 1]).build() + + when: + def result = ParseAndValidate.parseAndValidate(StarWarsSchema.starWarsSchema, input) + then: + result.isFailure() + !result.errors.isEmpty() + result.validationErrors.isEmpty() + result.document == null + result.variables == [var1: 1] + result.syntaxException != null + + (result.errors[0] as InvalidSyntaxError).message.contains("Invalid syntax") + } + + def "can use the graphql context to stop certain validation rules"() { + + def sdl = '''type Query { foo : ID } ''' + def graphQL = TestUtil.graphQL(sdl).build() + + Predicate> predicate = new Predicate>() { + @Override + boolean test(Class aClass) { + if (aClass == NoUnusedFragments.class) { + return false + } + return true + } + } + + def query = ''' + query { foo } + + fragment UnusedFrag on Query { + foo + } + ''' + + when: + def ei = ExecutionInput.newExecutionInput(query) + .graphQLContext(["graphql.ParseAndValidate.Predicate": predicate]) + .build() + def rs = graphQL.execute(ei) + + then: + rs.errors.isEmpty() // we skipped a rule + + when: + predicate = { it -> true } + ei = ExecutionInput.newExecutionInput(query) + .graphQLContext(["graphql.ParseAndValidate.Predicate": predicate]) + .build() + rs = graphQL.execute(ei) + + then: + !rs.errors.isEmpty() // all rules apply - we have errors + } + + def "validation error raised if mutation operation does not exist in schema"() { + def sdl = ''' + type Query { + myQuery : String! + } + ''' + + def registry = new SchemaParser().parse(sdl) + def schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry) + String request = "mutation MyMutation { myMutation }" + + when: + Document inputDocument = new Parser().parseDocument(request) + List errors = ParseAndValidate.validate(schema, inputDocument) + + then: + errors.size() == 1 + def error = errors.first() + error.validationErrorType == ValidationErrorType.UnknownOperation + error.message == "Validation error (UnknownOperation): The 'Mutation' operation is not supported by the schema" + error.locations == [new SourceLocation(1, 1)] + } + + def "validation error raised if subscription operation does not exist in schema"() { + def sdl = ''' + type Query { + myQuery : String! + } + ''' + + def registry = new SchemaParser().parse(sdl) + def schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry) + + String request = "subscription MySubscription { mySubscription }" + + when: + Document inputDocument = new Parser().parseDocument(request) + List errors = ParseAndValidate.validate(schema, inputDocument) + + then: + errors.size() == 1 + def error = errors.first() + error.validationErrorType == ValidationErrorType.UnknownOperation + error.message == "Validation error (UnknownOperation): The 'Subscription' operation is not supported by the schema" + error.locations == [new SourceLocation(1, 1)] + } + + def "known operation validation rule checks all operations in document"() { + def sdl = ''' + type Query { + myQuery : String! + } + ''' + + def registry = new SchemaParser().parse(sdl) + def schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry) + String request = "mutation MyMutation { myMutation } subscription MySubscription { mySubscription }" + + when: + Document inputDocument = new Parser().parseDocument(request) + List errors = ParseAndValidate.validate(schema, inputDocument) + + then: + errors.size() == 2 + def error1 = errors.get(0) + error1.validationErrorType == ValidationErrorType.UnknownOperation + error1.message == "Validation error (UnknownOperation): The 'Mutation' operation is not supported by the schema" + error1.locations == [new SourceLocation(1, 1)] + + def error2 = errors.get(1) + error2.validationErrorType == ValidationErrorType.UnknownOperation + error2.message == "Validation error (UnknownOperation): The 'Subscription' operation is not supported by the schema" + error2.locations == [new SourceLocation(1, 36)] + } +} diff --git a/src/test/groovy/graphql/ProfilerTest.groovy b/src/test/groovy/graphql/ProfilerTest.groovy new file mode 100644 index 0000000000..d047edcc7d --- /dev/null +++ b/src/test/groovy/graphql/ProfilerTest.groovy @@ -0,0 +1,618 @@ +package graphql + +import graphql.execution.ExecutionId +import graphql.execution.instrumentation.ChainedInstrumentation +import graphql.execution.instrumentation.Instrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters +import graphql.language.OperationDefinition +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import spock.lang.Ignore +import spock.lang.Specification + +import java.time.Duration +import java.util.concurrent.CompletableFuture +import java.util.concurrent.atomic.AtomicInteger + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.ProfilerResult.DataFetcherResultType.COMPLETABLE_FUTURE_COMPLETED +import static graphql.ProfilerResult.DataFetcherResultType.COMPLETABLE_FUTURE_NOT_COMPLETED +import static graphql.ProfilerResult.DataFetcherResultType.MATERIALIZED +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.setEnableDataLoaderChaining +import static java.util.concurrent.CompletableFuture.supplyAsync + +class ProfilerTest extends Specification { + + + def "one field"() { + given: + def sdl = ''' + type Query { + hello: String + } + ''' + def schema = TestUtil.schema(sdl, [Query: [ + hello: { DataFetchingEnvironment dfe -> return "world" } as DataFetcher + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionInput ei = newExecutionInput() + .query("{ hello }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [hello: "world"] + + then: + profilerResult.getFieldsFetched() == ["/hello"] as Set + + } + + def "introspection fields are ignored"() { + given: + def sdl = ''' + type Query { + hello: String + } + ''' + def schema = TestUtil.schema(sdl, [Query: [ + hello: { DataFetchingEnvironment dfe -> return "world" } as DataFetcher + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionInput ei = newExecutionInput() + .query("{ hello __typename alias:__typename __schema {types{name}} __type(name: \"Query\") {name} }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData()["hello"] == "world" + + then: + profilerResult.getFieldsFetched() == ["/hello",] as Set + profilerResult.getTotalDataFetcherInvocations() == 1 + + } + + def "pure introspection "() { + given: + def sdl = ''' + type Query { + hello: String + } + ''' + def schema = TestUtil.schema(sdl, [Query: [ + hello: { DataFetchingEnvironment dfe -> return "world" } as DataFetcher + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionInput ei = newExecutionInput() + .query("{ __schema {types{name}} __type(name: \"Query\") {name} }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData()["__schema"] != null + + then: + profilerResult.getFieldsFetched() == [] as Set + profilerResult.getTotalDataFetcherInvocations() == 0 + + } + + + def "instrumented data fetcher"() { + given: + def sdl = ''' + type Query { + dog: Dog + } + type Dog { + name: String + age: Int + } + ''' + + + def dogDf = { DataFetchingEnvironment dfe -> return [name: "Luna", age: 5] } as DataFetcher + + Instrumentation instrumentation = new Instrumentation() { + @Override + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + if (parameters.getField().getName() == "name") { + // wrapping a PropertyDataFetcher + return { DataFetchingEnvironment dfe -> + def result = dataFetcher.get(dfe) + return result + } as DataFetcher + } + return dataFetcher + } + + } + def dfs = [Query: [ + dog: dogDf + ]] + def schema = TestUtil.schema(sdl, dfs) + def graphql = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + ExecutionInput ei = newExecutionInput() + .query("{ dog {name age} }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [dog: [name: "Luna", age: 5]] + + then: + profilerResult.getTotalDataFetcherInvocations() == 3 + profilerResult.getTotalTrivialDataFetcherInvocations() == 1 + profilerResult.getTotalTrivialDataFetcherInvocations() == 1 + profilerResult.getTotalCustomDataFetcherInvocations() == 1 + profilerResult.getDataFetcherResultType() == ["/dog": MATERIALIZED] + } + + + @Ignore("not available for performance reasons at the moment") + def "manual dataloader dispatch"() { + given: + def sdl = ''' + + type Query { + dog: String + } + ''' + AtomicInteger batchLoadCalls = new AtomicInteger() + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls.incrementAndGet() + Thread.sleep(250) + println "BatchLoader called with keys: $keys" + return ["Luna"] + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader) + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("name", nameDataLoader) + + def df1 = { env -> + def loader = env.getDataLoader("name") + def result = loader.load("Key1") + loader.dispatch() + return result + } as DataFetcher + + def fetchers = ["Query": ["dog": df1]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ dog } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).profileExecution(true).build() + setEnableDataLoaderChaining(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + then: + er.data == [dog: "Luna"] + batchLoadCalls.get() == 1 + then: + profilerResult.getDispatchEvents()[0].type == ProfilerResult.DispatchEventType.MANUAL_DISPATCH + profilerResult.getDispatchEvents()[0].dataLoaderName == "name" + profilerResult.getDispatchEvents()[0].keyCount == 1 + profilerResult.getDispatchEvents()[0].level == 1 + + } + + @Ignore("not available for performance reasons at the moment") + def "cached dataloader values"() { + given: + def sdl = ''' + + type Query { + dog: Dog + } + type Dog { + name: String + } + ''' + AtomicInteger batchLoadCalls = new AtomicInteger() + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls.incrementAndGet() + Thread.sleep(250) + println "BatchLoader called with keys: $keys" + return ["Luna"] + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader) + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("name", nameDataLoader) + + def dogDF = { env -> + def loader = env.getDataLoader("name") + def result = loader.load("Key1").thenCompose { + return loader.load("Key1") // This should hit the cache + } + } as DataFetcher + + def nameDF = { env -> + def loader = env.getDataLoader("name") + def result = loader.load("Key1").thenCompose { + return loader.load("Key1") // This should hit the cache + } + } as DataFetcher + + + def fetchers = [Query: [dog: dogDF], Dog: [name: nameDF]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ dog {name } } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).profileExecution(true).build() + setEnableDataLoaderChaining(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + then: + er.data == [dog: [name: "Luna"]] + batchLoadCalls.get() == 1 + then: + profilerResult.getDataLoaderLoadInvocations().get("name") == 4 + profilerResult.getDispatchEvents()[0].type == ProfilerResult.DispatchEventType.LEVEL_STRATEGY_DISPATCH + profilerResult.getDispatchEvents()[0].dataLoaderName == "name" + profilerResult.getDispatchEvents()[0].keyCount == 1 + profilerResult.getDispatchEvents()[0].level == 1 + + } + + + def "collects instrumentation list"() { + given: + def sdl = ''' + type Query { + hello: String + } + ''' + def schema = TestUtil.schema(sdl, [Query: [ + hello: { DataFetchingEnvironment dfe -> return "world" } as DataFetcher + ]]) + Instrumentation fooInstrumentation = new Instrumentation() {} + Instrumentation barInstrumentation = new Instrumentation() {} + ChainedInstrumentation chainedInstrumentation = new ChainedInstrumentation( + new ChainedInstrumentation(new SimplePerformantInstrumentation()), + new ChainedInstrumentation(fooInstrumentation, barInstrumentation), + new SimplePerformantInstrumentation()) + + + def graphql = GraphQL.newGraphQL(schema).instrumentation(chainedInstrumentation).build() + + ExecutionInput ei = newExecutionInput() + .query("{ hello }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [hello: "world"] + + then: + profilerResult.getInstrumentationClasses() == ["graphql.execution.instrumentation.SimplePerformantInstrumentation", + "graphql.ProfilerTest\$2", + "graphql.ProfilerTest\$3", + "graphql.execution.instrumentation.SimplePerformantInstrumentation"] + + } + + + def "two DF with list"() { + given: + def sdl = ''' + type Query { + foo: [Foo] + } + type Foo { + id: String + bar: String + } + ''' + def schema = TestUtil.schema(sdl, [ + Query: [ + foo: { DataFetchingEnvironment dfe -> return [[id: "1"], [id: "2"], [id: "3"]] } as DataFetcher], + Foo : [ + bar: { DataFetchingEnvironment dfe -> dfe.source.id } as DataFetcher + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionInput ei = newExecutionInput() + .query("{ foo { id bar } }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [foo: [[id: "1", bar: "1"], [id: "2", bar: "2"], [id: "3", bar: "3"]]] + + then: + profilerResult.getFieldsFetched() == ["/foo", "/foo/bar", "/foo/id"] as Set + profilerResult.getTotalDataFetcherInvocations() == 7 + profilerResult.getTotalCustomDataFetcherInvocations() == 4 + profilerResult.getTotalTrivialDataFetcherInvocations() == 3 + } + + def "records timing"() { + given: + def sdl = ''' + type Query { + foo: Foo + } + type Foo { + id: String + } + ''' + def schema = TestUtil.schema(sdl, [ + Query: [ + foo: { DataFetchingEnvironment dfe -> + // blocking the engine for 1ms + // so that engineTotalRunningTime time is more than 1ms + Thread.sleep(1) + return supplyAsync { + Thread.sleep(500) + "1" + } + } as DataFetcher], + Foo : [ + id: { DataFetchingEnvironment dfe -> + return supplyAsync { + Thread.sleep(500) + dfe.source + } + } as DataFetcher + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionInput ei = newExecutionInput() + .query("{ foo { id } }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [foo: [id: "1"]] + // the total execution time must be more than 1 second, + // the engine should take less than 500ms + profilerResult.getTotalExecutionTime() > Duration.ofSeconds(1).toNanos() + profilerResult.getEngineTotalRunningTime() > Duration.ofMillis(1).toNanos() + profilerResult.getEngineTotalRunningTime() < Duration.ofMillis(500).toNanos() + + + } + + def "data fetcher result types"() { + given: + def sdl = ''' + type Query { + foo: [Foo] + } + type Foo { + id: String + name: String + text: String + } + ''' + def schema = TestUtil.schema(sdl, [ + Query: [ + foo: { DataFetchingEnvironment dfe -> + return CompletableFuture.supplyAsync { + Thread.sleep(100) + return [[id: "1", name: "foo1"], [id: "2", name: "foo2"]] + } + } as DataFetcher], + Foo : [ + name: { DataFetchingEnvironment dfe -> + return CompletableFuture.completedFuture(dfe.source.name) + } as DataFetcher, + text: { DataFetchingEnvironment dfe -> + return "text" + } as DataFetcher + + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionId id = ExecutionId.from("myExecutionId") + ExecutionInput ei = newExecutionInput() + .query("{ foo { id name text } foo2: foo { id name text} }") + .profileExecution(true) + .executionId(id) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [foo: [[id: "1", name: "foo1", text: "text"], [id: "2", name: "foo2", text: "text"]], foo2: [[id: "1", name: "foo1", text: "text"], [id: "2", name: "foo2", text: "text"]]] + then: + profilerResult.getTotalDataFetcherInvocations() == 14 + profilerResult.getTotalCustomDataFetcherInvocations() == 10 + profilerResult.getDataFetcherResultType() == ["/foo/name" : COMPLETABLE_FUTURE_COMPLETED, + "/foo/text" : MATERIALIZED, + "/foo2/name": COMPLETABLE_FUTURE_COMPLETED, + "/foo2/text": MATERIALIZED, + "/foo2" : COMPLETABLE_FUTURE_NOT_COMPLETED, + "/foo" : COMPLETABLE_FUTURE_NOT_COMPLETED] + profilerResult.shortSummaryMap().get("dataFetcherResultTypes") == ["COMPLETABLE_FUTURE_COMPLETED" : ["count":2, "invocations":4], + "COMPLETABLE_FUTURE_NOT_COMPLETED": ["count":2, "invocations":2], + "MATERIALIZED" : ["count":2, "invocations":4]] + profilerResult.shortSummaryMap().get("executionId") == "myExecutionId" + } + + def "operation details"() { + given: + def sdl = ''' + type Query { + hello: String + } + ''' + def schema = TestUtil.schema(sdl, [Query: [ + hello: { DataFetchingEnvironment dfe -> return "world" } as DataFetcher + ]]) + def graphql = GraphQL.newGraphQL(schema).build() + + ExecutionInput ei = newExecutionInput() + .query("query MyQuery { hello }") + .profileExecution(true) + .build() + + when: + def result = graphql.execute(ei) + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + + then: + result.getData() == [hello: "world"] + + then: + profilerResult.getOperationName() == "MyQuery" + profilerResult.getOperationType() == OperationDefinition.Operation.QUERY + + + } + + @Ignore("not available for performance reasons at the moment") + def "dataloader usage"() { + given: + def sdl = ''' + + type Query { + dogName: String + catName: String + } + ''' + int batchLoadCalls = 0 + BatchLoader batchLoader = { keys -> + return supplyAsync { + batchLoadCalls++ + Thread.sleep(250) + println "BatchLoader called with keys: $keys thread: ${Thread.currentThread().name}" + return keys.collect { key -> + if (key == "Key1") { + return "Luna" + } else if (key == "Key2") { + return "Tiger" + } else { + return key + } + } + } + } + + DataLoader nameDataLoader = DataLoaderFactory.newDataLoader(batchLoader) + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("name", nameDataLoader) + + def dogDF = { env -> + return env.getDataLoader("name").load("Key1").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } as DataFetcher + + def catDF = { env -> + return supplyAsync { + Thread.sleep(1500) + return "foo" + }.thenCompose { + return env.getDataLoader("name").load("Key2").thenCompose { + result -> + { + return env.getDataLoader("name").load(result) + } + } + } + } as DataFetcher + + def fetchers = ["Query": ["dogName": dogDF, "catName": catDF]] + def schema = TestUtil.schema(sdl, fetchers) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = "{ dogName catName } " + def ei = newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).profileExecution(true).build() + setEnableDataLoaderChaining(ei.graphQLContext, true) + + when: + def efCF = graphQL.executeAsync(ei) + Awaitility.await().until { efCF.isDone() } + def er = efCF.get() + def profilerResult = ei.getGraphQLContext().get(ProfilerResult.PROFILER_CONTEXT_KEY) as ProfilerResult + then: + er.data == [dogName: "Luna", catName: "Tiger"] + batchLoadCalls == 4 + profilerResult.isDataLoaderChainingEnabled() + profilerResult.getDataLoaderLoadInvocations() == [name: 4] + profilerResult.getDispatchEvents().size() == 4 + + profilerResult.getDispatchEvents()[0].type == ProfilerResult.DispatchEventType.LEVEL_STRATEGY_DISPATCH + profilerResult.getDispatchEvents()[0].dataLoaderName == "name" + profilerResult.getDispatchEvents()[0].level == 1 + profilerResult.getDispatchEvents()[0].keyCount == 1 + + profilerResult.getDispatchEvents()[2].type == ProfilerResult.DispatchEventType.DELAYED_DISPATCH + profilerResult.getDispatchEvents()[2].dataLoaderName == "name" + profilerResult.getDispatchEvents()[2].level == 1 + profilerResult.getDispatchEvents()[2].keyCount == 1 + + profilerResult.getDispatchEvents()[3].type == ProfilerResult.DispatchEventType.CHAINED_DELAYED_DISPATCH + profilerResult.getDispatchEvents()[3].dataLoaderName == "name" + profilerResult.getDispatchEvents()[3].level == 1 + profilerResult.getDispatchEvents()[3].keyCount == 1 + + + } + + +} diff --git a/src/test/groovy/graphql/RelaySchema.java b/src/test/groovy/graphql/RelaySchema.java index 06f819ff50..52b5526277 100644 --- a/src/test/groovy/graphql/RelaySchema.java +++ b/src/test/groovy/graphql/RelaySchema.java @@ -1,6 +1,9 @@ package graphql; import graphql.relay.Relay; +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; @@ -57,15 +60,19 @@ public class RelaySchema { .argument(newArgument() .name("id") .description("id of the thing") - .type(GraphQLNonNull.nonNull(GraphQLString))) - .dataFetcher(environment -> { - //TODO: implement - return null; - })) + .type(GraphQLNonNull.nonNull(GraphQLString)))) .build(); + public static FieldCoordinates thingCoordinates = FieldCoordinates.coordinates("RelayQuery", "thing"); + public static DataFetcher thingDataFetcher = environment -> null; + + public static GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(thingCoordinates, thingDataFetcher) + .build(); public static GraphQLSchema Schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) .query(RelayQueryType) + .additionalType(Relay.pageInfoType) .build(); } diff --git a/src/test/groovy/graphql/RelaySchemaTest.groovy b/src/test/groovy/graphql/RelaySchemaTest.groovy index 81a83f963b..6c95096938 100644 --- a/src/test/groovy/graphql/RelaySchemaTest.groovy +++ b/src/test/groovy/graphql/RelaySchemaTest.groovy @@ -90,7 +90,8 @@ class RelaySchemaTest extends Specification { then: def fields = result.data["__type"]["fields"] - fields == [[name: "node", type: [name: "Stuff", kind: "OBJECT", ofType: null]], [name: "cursor", type: [name: null, kind: "NON_NULL", ofType: [name: "String", kind: "SCALAR"]]]] + fields == [[name: "node", type: [name: "Stuff", kind: "OBJECT", ofType: null]], + [name: "cursor", type: [name: null, kind: "NON_NULL", ofType: [name: "String", kind: "SCALAR"]]]] } } diff --git a/src/test/groovy/graphql/ScalarsBigDecimalTest.groovy b/src/test/groovy/graphql/ScalarsBigDecimalTest.groovy deleted file mode 100644 index e7b86d2804..0000000000 --- a/src/test/groovy/graphql/ScalarsBigDecimalTest.groovy +++ /dev/null @@ -1,94 +0,0 @@ -package graphql - -import graphql.language.BooleanValue -import graphql.language.FloatValue -import graphql.language.IntValue -import graphql.language.StringValue -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.concurrent.atomic.AtomicInteger - -class ScalarsBigDecimalTest extends Specification { - - @Unroll - def "BigDecimal parse literal #literal.value as #result"() { - expect: - Scalars.GraphQLBigDecimal.getCoercing().parseLiteral(literal) == result - - where: - literal | result - new IntValue(12345678910 as BigInteger) | new BigDecimal("12345678910") - new StringValue("12345678911.12") | new BigDecimal("12345678911.12") - new FloatValue(new BigDecimal("42.42")) | new BigDecimal("42.42") - - } - - @Unroll - def "BigDecimal returns null for invalid #literal"() { - when: - Scalars.GraphQLBigDecimal.getCoercing().parseLiteral(literal) - then: - thrown(CoercingParseLiteralException) - - where: - literal | _ - new BooleanValue(true) | _ - new StringValue("not a number") | _ - } - - @Unroll - def "BigDecimal serialize #value into #result (#result.class)"() { - expect: - Scalars.GraphQLBigDecimal.getCoercing().serialize(value) == result - Scalars.GraphQLBigDecimal.getCoercing().parseValue(value) == result - - where: - value | result - "42" | new BigDecimal("42") - "42.123" | new BigDecimal("42.123") - 42.0000d | new BigDecimal("42.000") - new Integer(42) | new BigDecimal("42") - "-1" | new BigDecimal("-1") - new BigInteger(42) | new BigDecimal("42") - new BigDecimal("42") | new BigDecimal("42") - 42.3f | new BigDecimal("42.3") - 42.0d | new BigDecimal("42") - new Byte("42") | new BigDecimal("42") - new Short("42") | new BigDecimal("42") - 1234567l | new BigDecimal("1234567") - new AtomicInteger(42) | new BigDecimal("42") - } - - @Unroll - def "serialize throws exception for invalid input #value"() { - when: - Scalars.GraphQLBigDecimal.getCoercing().serialize(value) - then: - thrown(CoercingSerializeException) - - where: - value | _ - "" | _ - "not a number " | _ - new Object() | _ - } - - @Unroll - def "parseValue throws exception for invalid input #value"() { - when: - Scalars.GraphQLBigDecimal.getCoercing().parseValue(value) - then: - thrown(CoercingParseValueException) - - where: - value | _ - "" | _ - "not a number " | _ - new Object() | _ - } - -} diff --git a/src/test/groovy/graphql/ScalarsBigIntegerTest.groovy b/src/test/groovy/graphql/ScalarsBigIntegerTest.groovy deleted file mode 100644 index f3a39f697e..0000000000 --- a/src/test/groovy/graphql/ScalarsBigIntegerTest.groovy +++ /dev/null @@ -1,95 +0,0 @@ -package graphql - -import graphql.language.BooleanValue -import graphql.language.FloatValue -import graphql.language.IntValue -import graphql.language.StringValue -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.concurrent.atomic.AtomicInteger - -class ScalarsBigIntegerTest extends Specification { - - @Unroll - def "BigInteger parse literal #literal.value as #result"() { - expect: - Scalars.GraphQLBigInteger.getCoercing().parseLiteral(literal) == result - - where: - literal | result - new IntValue(12345678910 as BigInteger) | new BigInteger("12345678910") - new StringValue("12345678911") | new BigInteger("12345678911") - new FloatValue(new BigDecimal("42")) | new BigInteger("42") - } - - @Unroll - def "BigInteger returns null for invalid #literal"() { - when: - Scalars.GraphQLBigInteger.getCoercing().parseLiteral(literal) - then: - thrown(CoercingParseLiteralException) - - where: - literal | _ - new BooleanValue(true) | _ - new StringValue("42.3") | _ - new FloatValue(new BigDecimal("12.12")) | _ - new StringValue("not a number") | _ - } - - @Unroll - def "BigInteger serialize #value into #result (#result.class)"() { - expect: - Scalars.GraphQLBigInteger.getCoercing().serialize(value) == result - Scalars.GraphQLBigInteger.getCoercing().parseValue(value) == result - - where: - value | result - "42" | new BigInteger("42") - new Integer(42) | new BigInteger("42") - "-1" | new BigInteger("-1") - new BigInteger("42") | new BigInteger("42") - 42.0d | new BigInteger("42") - new Byte("42") | new BigInteger("42") - new Short("42") | new BigInteger("42") - 1234567l | new BigInteger("1234567") - new AtomicInteger(42) | new BigInteger("42") - } - - @Unroll - def "serialize throws exception for invalid input #value"() { - when: - Scalars.GraphQLBigInteger.getCoercing().serialize(value) - then: - thrown(CoercingSerializeException) - - where: - value | _ - "" | _ - "not a number " | _ - new BigDecimal("12.12") | _ - "12.12" | _ - new Object() | _ - } - - @Unroll - def "parseValue throws exception for invalid input #value"() { - when: - Scalars.GraphQLBigInteger.getCoercing().parseValue(value) - then: - thrown(CoercingParseValueException) - - where: - value | _ - "" | _ - "not a number " | _ - new BigDecimal("12.12") | _ - "12.12" | _ - new Object() | _ - } - -} diff --git a/src/test/groovy/graphql/ScalarsBooleanTest.groovy b/src/test/groovy/graphql/ScalarsBooleanTest.groovy index df0f4ddd4c..55351f7f2b 100644 --- a/src/test/groovy/graphql/ScalarsBooleanTest.groovy +++ b/src/test/groovy/graphql/ScalarsBooleanTest.groovy @@ -1,5 +1,6 @@ package graphql +import graphql.execution.CoercedVariables import graphql.language.BooleanValue import graphql.language.FloatValue import graphql.language.IntValue @@ -15,19 +16,29 @@ class ScalarsBooleanTest extends Specification { @Unroll def "Boolean parse literal #literal.value as #result"() { expect: - Scalars.GraphQLBoolean.getCoercing().parseLiteral(literal) == result + Scalars.GraphQLBoolean.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) == result where: literal | result new BooleanValue(true) | true new BooleanValue(false) | false + } + + @Unroll + def "Boolean parse literal #literal.value as #result with deprecated method"() { + expect: + Scalars.GraphQLBoolean.getCoercing().parseLiteral(literal) == result // Retain deprecated method for test coverage + where: + literal | result + new BooleanValue(true) | true + new BooleanValue(false) | false } @Unroll def "Boolean returns null for invalid #literal"() { when: - Scalars.GraphQLBoolean.getCoercing().parseLiteral(literal) + Scalars.GraphQLBoolean.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) then: thrown(CoercingParseLiteralException) @@ -41,49 +52,106 @@ class ScalarsBooleanTest extends Specification { @Unroll def "Boolean serialize #value into #result (#result.class)"() { expect: - Scalars.GraphQLBoolean.getCoercing().serialize(value) == result - Scalars.GraphQLBoolean.getCoercing().parseValue(value) == result + Scalars.GraphQLBoolean.getCoercing().serialize(value, GraphQLContext.default, Locale.default) == result + + where: + value | result + true | true + "false" | false + "true" | true + "True" | true + 0 | false + 1 | true + -1 | true + Long.valueOf(42345784398534785l) | true + Double.valueOf(42.3) | true + Float.valueOf(42.3) | true + Integer.MAX_VALUE + 1l | true + Integer.MIN_VALUE - 1l | true + } + + @Unroll + def "Boolean serialize #value into #result (#result.class) with deprecated methods"() { + expect: + Scalars.GraphQLBoolean.getCoercing().serialize(value) == result // Retain deprecated method for test coverage where: - value | result - true | true - "false" | false - "true" | true - "True" | true - "some value not true" | false - "" | false - 0 | false - 1 | true - -1 | true - new Long(42345784398534785l) | true - new Double(42.3) | true - new Float(42.3) | true - Integer.MAX_VALUE + 1l | true - Integer.MIN_VALUE - 1l | true + value | result + true | true + "false" | false + "true" | true + "True" | true + 0 | false + 1 | true + -1 | true + Long.valueOf(42345784398534785l) | true + Double.valueOf(42.3) | true + Float.valueOf(42.3) | true + Integer.MAX_VALUE + 1l | true + Integer.MIN_VALUE - 1l | true } @Unroll def "serialize throws exception for invalid input #value"() { when: - Scalars.GraphQLBoolean.getCoercing().serialize(value) + Scalars.GraphQLBoolean.getCoercing().serialize(value, GraphQLContext.default, Locale.default) then: thrown(CoercingSerializeException) where: - value | _ - new Object() | _ + value | _ + new Object() | _ + "some value not true" | _ + "" | _ + "T" | _ + "t" | _ + "F" | _ + "f" | _ + } + + @Unroll + def "Boolean parseValue #value into #result (#result.class)"() { + expect: + Scalars.GraphQLBoolean.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) == result + + where: + value | result + true | true + false | false + } + + @Unroll + def "Boolean parseValue #value into #result (#result.class) with deprecated methods"() { + expect: + Scalars.GraphQLBoolean.getCoercing().parseValue(value) == result // Retain deprecated method for test coverage + + where: + value | result + true | true + false | false } @Unroll def "parseValue throws exception for invalid input #value"() { when: - Scalars.GraphQLBoolean.getCoercing().parseValue(value) + Scalars.GraphQLBoolean.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) then: thrown(CoercingParseValueException) where: - value | _ - new Object() | _ + value | _ + new Object() | _ + "false" | _ + "true" | _ + "True" | _ + 0 | _ + 1 | _ + -1 | _ + Long.valueOf(42345784398534785l) | _ + Double.valueOf(42.3) | _ + Float.valueOf(42.3) | _ + Integer.MAX_VALUE + 1l | _ + Integer.MIN_VALUE - 1l | _ } } diff --git a/src/test/groovy/graphql/ScalarsByteTest.groovy b/src/test/groovy/graphql/ScalarsByteTest.groovy deleted file mode 100644 index 4e19f43fe3..0000000000 --- a/src/test/groovy/graphql/ScalarsByteTest.groovy +++ /dev/null @@ -1,115 +0,0 @@ -package graphql - -import graphql.language.FloatValue -import graphql.language.IntValue -import graphql.language.StringValue -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.concurrent.atomic.AtomicInteger - -class ScalarsByteTest extends Specification { - - @Unroll - def "Byte parse literal #literal.value as #result"() { - expect: - Scalars.GraphQLByte.getCoercing().parseLiteral(literal) == result - - where: - literal | result - new IntValue(42 as BigInteger) | 42 - new IntValue(Byte.MAX_VALUE as BigInteger) | Byte.MAX_VALUE - new IntValue(Byte.MIN_VALUE as BigInteger) | Byte.MIN_VALUE - - } - - @Unroll - def "Byte returns null for invalid #literal"() { - when: - Scalars.GraphQLByte.getCoercing().parseLiteral(literal) - then: - thrown(CoercingParseLiteralException) - - where: - literal | _ - new IntValue(12345678910 as BigInteger) | _ - new StringValue("-1") | _ - new FloatValue(42.3) | _ - new IntValue(Byte.MAX_VALUE + 1l as BigInteger) | _ - new IntValue(Byte.MIN_VALUE - 1l as BigInteger) | _ - new StringValue("-1") | _ - new FloatValue(42.3) | _ - - } - - @Unroll - def "Byte serialize #value into #result (#result.class)"() { - expect: - Scalars.GraphQLByte.getCoercing().serialize(value) == result - Scalars.GraphQLByte.getCoercing().parseValue(value) == result - - where: - value | result - "42" | 42 - "42.0000" | 42 - 42.0000d | 42 - new Integer(42) | 42 - "-1" | -1 - new BigInteger(42) | 42 - new BigDecimal("42") | 42 - 42.0f | 42 - 42.0d | 42 - new Byte("42") | 42 - new Short("42") | 42 - 123l | 123 - new AtomicInteger(42) | 42 - Byte.MAX_VALUE | Byte.MAX_VALUE - Byte.MIN_VALUE | Byte.MIN_VALUE - } - - @Unroll - def "serialize throws exception for invalid input #value"() { - when: - Scalars.GraphQLByte.getCoercing().serialize(value) - then: - thrown(CoercingSerializeException) - - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Long(42345784398534785l) | _ - new Double(42.3) | _ - new Float(42.3) | _ - Byte.MAX_VALUE + 1l | _ - Byte.MIN_VALUE - 1l | _ - new Object() | _ - - } - - @Unroll - def "parseValue throws exception for invalid input #value"() { - when: - Scalars.GraphQLByte.getCoercing().parseValue(value) - then: - thrown(CoercingParseValueException) - - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Long(42345784398534785l) | _ - new Double(42.3) | _ - new Float(42.3) | _ - Byte.MAX_VALUE + 1l | _ - Byte.MIN_VALUE - 1l | _ - new Object() | _ - - } - -} diff --git a/src/test/groovy/graphql/ScalarsCharTest.groovy b/src/test/groovy/graphql/ScalarsCharTest.groovy deleted file mode 100644 index 91109bb9be..0000000000 --- a/src/test/groovy/graphql/ScalarsCharTest.groovy +++ /dev/null @@ -1,80 +0,0 @@ -package graphql - -import graphql.language.IntValue -import graphql.language.StringValue -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException -import spock.lang.Specification -import spock.lang.Unroll - -class ScalarsCharTest extends Specification { - - @Unroll - def "Char parse literal #literal.value as #result"() { - expect: - Scalars.GraphQLChar.getCoercing().parseLiteral(literal) == result - - where: - literal | result - new StringValue("a") | 'a' - new StringValue("b") | 'b' - - } - - @Unroll - def "Short returns null for invalid #literal"() { - when: - Scalars.GraphQLChar.getCoercing().parseLiteral(literal) - then: - thrown(CoercingParseLiteralException) - - where: - literal | _ - new StringValue("aa") | _ - new IntValue(12 as BigInteger) | _ - } - - @Unroll - def "Short serialize #value into #result (#result.class)"() { - expect: - Scalars.GraphQLChar.getCoercing().serialize(value) == result - Scalars.GraphQLChar.getCoercing().parseValue(value) == result - - where: - value | result - "a" | 'a' - 'z' | 'z' - } - - @Unroll - def "serialize throws exception for invalid input #value"() { - when: - Scalars.GraphQLChar.getCoercing().serialize(value) - then: - thrown(CoercingSerializeException) - - where: - value | _ - "" | _ - "aa" | _ - new Object() | _ - - } - - @Unroll - def "parseValue throws exception for invalid input #value"() { - when: - Scalars.GraphQLChar.getCoercing().parseValue(value) - then: - thrown(CoercingParseValueException) - - where: - value | _ - "" | _ - "aa" | _ - new Object() | _ - - } - -} diff --git a/src/test/groovy/graphql/ScalarsFloatTest.groovy b/src/test/groovy/graphql/ScalarsFloatTest.groovy index f2a1ad664e..744fcbac03 100644 --- a/src/test/groovy/graphql/ScalarsFloatTest.groovy +++ b/src/test/groovy/graphql/ScalarsFloatTest.groovy @@ -1,5 +1,6 @@ package graphql +import graphql.execution.CoercedVariables import graphql.language.BooleanValue import graphql.language.FloatValue import graphql.language.IntValue @@ -17,7 +18,7 @@ class ScalarsFloatTest extends Specification { @Unroll def "Float parse literal #literal.value as #result"() { expect: - Scalars.GraphQLFloat.getCoercing().parseLiteral(literal) == result + Scalars.GraphQLFloat.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) == result where: literal | result @@ -25,13 +26,25 @@ class ScalarsFloatTest extends Specification { new FloatValue(Double.MAX_VALUE) | Double.MAX_VALUE new FloatValue(Double.MIN_VALUE) | Double.MIN_VALUE new IntValue(12345678910 as BigInteger) | 12345678910 + } + + @Unroll + def "Float parse literal #literal.value as #result with deprecated method"() { + expect: + Scalars.GraphQLFloat.getCoercing().parseLiteral(literal) == result // Retain deprecated for test coverage + where: + literal | result + new FloatValue(42.442 as BigDecimal) | 42.442 + new FloatValue(Double.MAX_VALUE) | Double.MAX_VALUE + new FloatValue(Double.MIN_VALUE) | Double.MIN_VALUE + new IntValue(12345678910 as BigInteger) | 12345678910 } @Unroll def "Float returns null for invalid #literal"() { when: - Scalars.GraphQLFloat.getCoercing().parseLiteral(literal) + Scalars.GraphQLFloat.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) then: thrown(CoercingParseLiteralException) @@ -44,22 +57,47 @@ class ScalarsFloatTest extends Specification { @Unroll def "Float serialize #value into #result (#result.class)"() { expect: - Scalars.GraphQLFloat.getCoercing().serialize(value) == result - Scalars.GraphQLFloat.getCoercing().parseValue(value) == result + Scalars.GraphQLFloat.getCoercing().serialize(value, GraphQLContext.default, Locale.default) == result + + where: + value | result + "42" | 42d + "42.123" | 42.123d + 42.0000d | 42 + Integer.valueOf(42) | 42 + "-1" | -1 + new BigInteger("42") | 42 + new BigDecimal("42") | 42 + new BigDecimal("4.2") | 4.2d + 42.3f | 42.3d + 42.0d | 42d + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 + 1234567l | 1234567d + new AtomicInteger(42) | 42 + Double.MAX_VALUE | Double.MAX_VALUE + Double.MIN_VALUE | Double.MIN_VALUE + } + + @Unroll + def "Float serialize #value into #result (#result.class) with deprecated methods"() { + expect: + Scalars.GraphQLFloat.getCoercing().serialize(value) == result // Retain deprecated method for coverage where: value | result "42" | 42d "42.123" | 42.123d 42.0000d | 42 - new Integer(42) | 42 + Integer.valueOf(42) | 42 "-1" | -1 - new BigInteger(42) | 42 + new BigInteger("42") | 42 new BigDecimal("42") | 42 + new BigDecimal("4.2") | 4.2d 42.3f | 42.3d 42.0d | 42d - new Byte("42") | 42 - new Short("42") | 42 + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 1234567l | 1234567d new AtomicInteger(42) | 42 Double.MAX_VALUE | Double.MAX_VALUE @@ -69,29 +107,99 @@ class ScalarsFloatTest extends Specification { @Unroll def "serialize throws exception for invalid input #value"() { when: - Scalars.GraphQLFloat.getCoercing().serialize(value) + Scalars.GraphQLFloat.getCoercing().serialize(value, GraphQLContext.default, Locale.default) then: thrown(CoercingSerializeException) where: - value | _ - "" | _ - "not a number " | _ - Double.NaN | _ + value | _ + "" | _ + "not a number " | _ + Double.NaN | _ + Double.NaN.toString() | _ + Double.POSITIVE_INFINITY | _ + Double.POSITIVE_INFINITY.toString() | _ + Double.NEGATIVE_INFINITY | _ + Double.NEGATIVE_INFINITY.toString() | _ + Float.NaN | _ + Float.NaN.toString() | _ + Float.POSITIVE_INFINITY | _ + Float.POSITIVE_INFINITY.toString() | _ + Float.NEGATIVE_INFINITY | _ + Float.NEGATIVE_INFINITY.toString() | _ } @Unroll - def "serialize/parseValue throws exception for invalid input #value"() { + def "Float parseValue #value into #result (#result.class)"() { + expect: + Scalars.GraphQLFloat.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) == result + + where: + value | result + 42.0000d | 42 + Integer.valueOf(42) | 42 + new BigInteger("42") | 42 + new BigDecimal("42") | 42 + new BigDecimal("4.2") | 4.2d + 42.3f | 42.3d + 42.0d | 42d + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 + 1234567l | 1234567d + new AtomicInteger(42) | 42 + Double.MAX_VALUE | Double.MAX_VALUE + Double.MIN_VALUE | Double.MIN_VALUE + } + + @Unroll + def "Float parseValue #value into #result (#result.class) with deprecated methods"() { + expect: + Scalars.GraphQLFloat.getCoercing().parseValue(value) == result // Retain deprecated method for coverage + + where: + value | result + 42.0000d | 42 + Integer.valueOf(42) | 42 + new BigInteger("42") | 42 + new BigDecimal("42") | 42 + new BigDecimal("4.2") | 4.2d + 42.3f | 42.3d + 42.0d | 42d + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 + 1234567l | 1234567d + new AtomicInteger(42) | 42 + Double.MAX_VALUE | Double.MAX_VALUE + Double.MIN_VALUE | Double.MIN_VALUE + } + + + @Unroll + def "parseValue throws exception for invalid input #value"() { when: - Scalars.GraphQLFloat.getCoercing().parseValue(value) + Scalars.GraphQLFloat.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) then: thrown(CoercingParseValueException) where: - value | _ - "" | _ - "not a number " | _ - Double.NaN | _ + value | _ + "" | _ + "not a number " | _ + Double.NaN | _ + Double.NaN.toString() | _ + Double.POSITIVE_INFINITY | _ + Double.POSITIVE_INFINITY.toString() | _ + Double.NEGATIVE_INFINITY | _ + Double.NEGATIVE_INFINITY.toString() | _ + Float.NaN | _ + Float.NaN.toString() | _ + Float.POSITIVE_INFINITY | _ + Float.POSITIVE_INFINITY.toString() | _ + Float.NEGATIVE_INFINITY | _ + Float.NEGATIVE_INFINITY.toString() | _ + "42" | _ + "42.123" | _ + "-1" | _ } } diff --git a/src/test/groovy/graphql/ScalarsIDTest.groovy b/src/test/groovy/graphql/ScalarsIDTest.groovy index d891bef99a..a304251796 100644 --- a/src/test/groovy/graphql/ScalarsIDTest.groovy +++ b/src/test/groovy/graphql/ScalarsIDTest.groovy @@ -1,11 +1,12 @@ package graphql +import graphql.execution.CoercedVariables import graphql.language.BooleanValue import graphql.language.IntValue import graphql.language.StringValue +import graphql.relay.DefaultConnectionCursor import graphql.schema.CoercingParseLiteralException import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException import spock.lang.Specification import spock.lang.Unroll @@ -14,19 +15,29 @@ class ScalarsIDTest extends Specification { @Unroll def "ID parse literal #literal.value as #result"() { expect: - Scalars.GraphQLID.getCoercing().parseLiteral(literal) == result + Scalars.GraphQLID.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) == result where: literal | result new StringValue("1234ab") | "1234ab" new IntValue(123 as BigInteger) | "123" + } + + @Unroll + def "ID parse literal #literal.value as #result with deprecated method"() { + expect: + Scalars.GraphQLID.getCoercing().parseLiteral(literal) == result // Retain deprecated method for test coverage + where: + literal | result + new StringValue("1234ab") | "1234ab" + new IntValue(123 as BigInteger) | "123" } @Unroll def "ID returns null for invalid #literal"() { when: - Scalars.GraphQLID.getCoercing().parseLiteral(literal) + Scalars.GraphQLID.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) then: thrown(CoercingParseLiteralException) @@ -36,25 +47,27 @@ class ScalarsIDTest extends Specification { } @Unroll - def "ID serialize #value into #result (#result.class)"() { + def "ID serialize #value into #result (#result.class) with deprecated methods"() { expect: - Scalars.GraphQLID.getCoercing().serialize(value) == result - Scalars.GraphQLID.getCoercing().parseValue(value) == result + Scalars.GraphQLID.getCoercing().serialize(value) == result // Retain deprecated method for test coverage + Scalars.GraphQLID.getCoercing().parseValue(value) == result // Retain deprecated method for test coverage where: - value | result - "123ab" | "123ab" - 123 | "123" - 123123123123123123L | "123123123123123123" + value | result + "123ab" | "123ab" + 123 | "123" + 123123123123123123L | "123123123123123123" + new BigInteger("123123123123123123") | "123123123123123123" UUID.fromString("037ebc7a-f9b8-4d76-89f6-31b34a40e10b") | "037ebc7a-f9b8-4d76-89f6-31b34a40e10b" + new DefaultConnectionCursor("cursor123") | "cursor123" } @Unroll - def "serialize throws exception for invalid input #value"() { + def "serialize allows any object via String.valueOf #value"() { when: Scalars.GraphQLID.getCoercing().serialize(value) then: - thrown(CoercingSerializeException) + noExceptionThrown() where: value | _ @@ -63,11 +76,11 @@ class ScalarsIDTest extends Specification { } @Unroll - def "parseValue throws exception for invalid input #value"() { + def "parseValue allows any object via String.valueOf #value"() { when: Scalars.GraphQLID.getCoercing().parseValue(value) then: - thrown(CoercingParseValueException) + noExceptionThrown() where: value | _ diff --git a/src/test/groovy/graphql/ScalarsIntTest.groovy b/src/test/groovy/graphql/ScalarsIntTest.groovy index 9a037451c5..42c7c6887f 100644 --- a/src/test/groovy/graphql/ScalarsIntTest.groovy +++ b/src/test/groovy/graphql/ScalarsIntTest.groovy @@ -1,5 +1,6 @@ package graphql +import graphql.execution.CoercedVariables import graphql.language.FloatValue import graphql.language.IntValue import graphql.language.StringValue @@ -16,20 +17,31 @@ class ScalarsIntTest extends Specification { @Unroll def "Int parse literal #literal.value as #result"() { expect: - Scalars.GraphQLInt.getCoercing().parseLiteral(literal) == result + Scalars.GraphQLInt.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) == result where: literal | result new IntValue(42 as BigInteger) | 42 new IntValue(Integer.MAX_VALUE as BigInteger) | Integer.MAX_VALUE new IntValue(Integer.MIN_VALUE as BigInteger) | Integer.MIN_VALUE + } + + @Unroll + def "Int parse literal #literal.value as #result with deprecated method"() { + expect: + Scalars.GraphQLInt.getCoercing().parseLiteral(literal) == result // Retain deprecated method for test coverage + where: + literal | result + new IntValue(42 as BigInteger) | 42 + new IntValue(Integer.MAX_VALUE as BigInteger) | Integer.MAX_VALUE + new IntValue(Integer.MIN_VALUE as BigInteger) | Integer.MIN_VALUE } @Unroll def "Int returns null for invalid #literal"() { when: - Scalars.GraphQLInt.getCoercing().parseLiteral(literal) + Scalars.GraphQLInt.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) then: thrown(CoercingParseLiteralException) @@ -42,28 +54,50 @@ class ScalarsIntTest extends Specification { new IntValue(Integer.MIN_VALUE - 1l as BigInteger) | _ new StringValue("-1") | _ new FloatValue(42.3) | _ - } @Unroll def "Int serialize #value into #result (#result.class)"() { expect: - Scalars.GraphQLInt.getCoercing().serialize(value) == result - Scalars.GraphQLInt.getCoercing().parseValue(value) == result + Scalars.GraphQLInt.getCoercing().serialize(value, GraphQLContext.default, Locale.default) == result + + where: + value | result + "42" | 42 + "42.0000" | 42 + 42.0000d | 42 + Integer.valueOf(42) | 42 + "-1" | -1 + new BigInteger("42") | 42 + new BigDecimal("42") | 42 + 42.0f | 42 + 42.0d | 42 + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 + 1234567l | 1234567 + new AtomicInteger(42) | 42 + Integer.MAX_VALUE | Integer.MAX_VALUE + Integer.MIN_VALUE | Integer.MIN_VALUE + } + + @Unroll + def "Int serialize #value into #result (#result.class) with deprecated methods"() { + expect: + Scalars.GraphQLInt.getCoercing().serialize(value) == result // Retain deprecated for test coverage where: value | result "42" | 42 "42.0000" | 42 42.0000d | 42 - new Integer(42) | 42 + Integer.valueOf(42) | 42 "-1" | -1 - new BigInteger(42) | 42 + new BigInteger("42") | 42 new BigDecimal("42") | 42 42.0f | 42 42.0d | 42 - new Byte("42") | 42 - new Short("42") | 42 + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 1234567l | 1234567 new AtomicInteger(42) | 42 Integer.MAX_VALUE | Integer.MAX_VALUE @@ -73,44 +107,86 @@ class ScalarsIntTest extends Specification { @Unroll def "serialize throws exception for invalid input #value"() { when: - Scalars.GraphQLInt.getCoercing().serialize(value) + Scalars.GraphQLInt.getCoercing().serialize(value, GraphQLContext.default, Locale.default) then: thrown(CoercingSerializeException) where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Long(42345784398534785l) | _ - new Double(42.3) | _ - new Float(42.3) | _ - Integer.MAX_VALUE + 1l | _ - Integer.MIN_VALUE - 1l | _ - new Object() | _ + value | _ + "" | _ + "not a number " | _ + "42.3" | _ + Long.valueOf(42345784398534785l) | _ + Double.valueOf(42.3) | _ + Float.valueOf(42.3) | _ + Integer.MAX_VALUE + 1l | _ + Integer.MIN_VALUE - 1l | _ + new Object() | _ + } + @Unroll + def "Int parseValue #value into #result (#result.class)"() { + expect: + Scalars.GraphQLInt.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) == result + + where: + value | result + Integer.valueOf(42) | 42 + new BigInteger("42") | 42 + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 + 1234567l | 1234567 + new AtomicInteger(42) | 42 + 42.0000d | 42 + new BigDecimal("42") | 42 + 42.0f | 42 + 42.0d | 42 + Integer.MAX_VALUE | Integer.MAX_VALUE + Integer.MIN_VALUE | Integer.MIN_VALUE } @Unroll - def "parsValue throws exception for invalid input #value"() { + def "Int parseValue #value into #result (#result.class) with deprecated methods"() { + expect: + Scalars.GraphQLInt.getCoercing().parseValue(value) == result // Retain deprecated for test coverage + + where: + value | result + Integer.valueOf(42) | 42 + new BigInteger("42") | 42 + Byte.valueOf("42") | 42 + Short.valueOf("42") | 42 + 1234567l | 1234567 + new AtomicInteger(42) | 42 + 42.0000d | 42 + new BigDecimal("42") | 42 + 42.0f | 42 + 42.0d | 42 + Integer.MAX_VALUE | Integer.MAX_VALUE + Integer.MIN_VALUE | Integer.MIN_VALUE + } + + @Unroll + def "parseValue throws exception for invalid input #value"() { when: - Scalars.GraphQLInt.getCoercing().parseValue(value) + Scalars.GraphQLInt.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) then: thrown(CoercingParseValueException) - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Long(42345784398534785l) | _ - new Double(42.3) | _ - new Float(42.3) | _ - Integer.MAX_VALUE + 1l | _ - Integer.MIN_VALUE - 1l | _ - new Object() | _ - + value | _ + "" | _ + "not a number " | _ + "42.3" | _ + Long.valueOf(42345784398534785l) | _ + Double.valueOf(42.3) | _ + Float.valueOf(42.3) | _ + Integer.MAX_VALUE + 1l | _ + Integer.MIN_VALUE - 1l | _ + new Object() | _ + "42" | _ + "42.0000" | _ + "-1" | _ } } diff --git a/src/test/groovy/graphql/ScalarsLongTest.groovy b/src/test/groovy/graphql/ScalarsLongTest.groovy deleted file mode 100644 index 2b212aaa76..0000000000 --- a/src/test/groovy/graphql/ScalarsLongTest.groovy +++ /dev/null @@ -1,117 +0,0 @@ -package graphql - -import graphql.language.FloatValue -import graphql.language.IntValue -import graphql.language.StringValue -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException -import spock.lang.Shared -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.concurrent.atomic.AtomicInteger - -class ScalarsLongTest extends Specification { - - @Shared - def tooBig = new BigInteger(Long.toString(Long.MAX_VALUE)).add(new BigInteger("1")) - @Shared - def tooSmall = new BigInteger(Long.toString(Long.MIN_VALUE)).subtract(new BigInteger("1")) - - @Unroll - def "Long parse literal #literal.value as #result"() { - expect: - Scalars.GraphQLLong.getCoercing().parseLiteral(literal) == result - - where: - literal | result - new IntValue(42 as BigInteger) | 42 - new IntValue(Long.MAX_VALUE as BigInteger) | Long.MAX_VALUE - new IntValue(Long.MIN_VALUE as BigInteger) | Long.MIN_VALUE - new StringValue("12345678910") | 12345678910 - new StringValue("-1") | -1 - - } - - @Unroll - def "Long returns null for invalid #literal"() { - when: - Scalars.GraphQLLong.getCoercing().parseLiteral(literal) - then: - thrown(CoercingParseLiteralException) - - where: - literal | _ - new StringValue("not a number") | _ - new FloatValue(42.3) | _ - tooBig | null - tooSmall | null - new FloatValue(42.3) | null - } - - @Unroll - def "Long serialize #value into #result (#result.class)"() { - expect: - Scalars.GraphQLLong.getCoercing().serialize(value) == result - Scalars.GraphQLLong.getCoercing().parseValue(value) == result - - where: - value | result - "42" | 42 - "42.0000" | 42 - 42.0000d | 42 - new Integer(42) | 42 - "-1" | -1 - new BigInteger(42) | 42 - new BigDecimal("42") | 42 - 42.0f | 42 - 42.0d | 42 - new Byte("42") | 42 - new Short("42") | 42 - 12345678910l | 12345678910l - new AtomicInteger(42) | 42 - Long.MAX_VALUE | Long.MAX_VALUE - Long.MIN_VALUE | Long.MIN_VALUE - new Long(42345784398534785l) | 42345784398534785l - } - - @Unroll - def "serialize throws exception for invalid input #value"() { - when: - Scalars.GraphQLLong.getCoercing().serialize(value) - then: - thrown(CoercingSerializeException) - - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Double(42.3) | _ - new Float(42.3) | _ - tooBig | _ - tooSmall | _ - new Object() | _ - } - - @Unroll - def "parseValue throws exception for invalid input #value"() { - when: - Scalars.GraphQLLong.getCoercing().parseValue(value) - then: - thrown(CoercingParseValueException) - - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Double(42.3) | _ - new Float(42.3) | _ - tooBig | _ - tooSmall | _ - new Object() | _ - } - -} diff --git a/src/test/groovy/graphql/ScalarsQuerySchema.java b/src/test/groovy/graphql/ScalarsQuerySchema.java index 92276e1788..44718be9e3 100644 --- a/src/test/groovy/graphql/ScalarsQuerySchema.java +++ b/src/test/groovy/graphql/ScalarsQuerySchema.java @@ -2,123 +2,54 @@ import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLNonNull; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; -import java.math.BigDecimal; -import java.math.BigInteger; - import static graphql.schema.GraphQLArgument.newArgument; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLObjectType.newObject; public class ScalarsQuerySchema { - public static final DataFetcher inputDF = environment -> environment.getArgument("input"); + public static final DataFetcher inputDF = environment -> environment.getArgument("input"); public static final GraphQLObjectType queryType = newObject() .name("QueryType") - /** Static Scalars */ - .field(newFieldDefinition() - .name("bigInteger") - .type(Scalars.GraphQLBigInteger) - .staticValue(BigInteger.valueOf(9999))) - .field(newFieldDefinition() - .name("bigDecimal") - .type(Scalars.GraphQLBigDecimal) - .staticValue(BigDecimal.valueOf(1234.0))) - .field(newFieldDefinition() - .name("floatNaN") - .type(Scalars.GraphQLFloat) - .staticValue(Double.NaN)) - - - /** Scalars with input of same type, value echoed back */ - .field(newFieldDefinition() - .name("bigIntegerInput") - .type(Scalars.GraphQLBigInteger) - .argument(newArgument() - .name("input") - .type(GraphQLNonNull.nonNull(Scalars.GraphQLBigInteger))) - .dataFetcher(inputDF)) - .field(newFieldDefinition() - .name("bigDecimalInput") - .type(Scalars.GraphQLBigDecimal) - .argument(newArgument() - .name("input") - .type(GraphQLNonNull.nonNull(Scalars.GraphQLBigDecimal))) - .dataFetcher(inputDF)) - .field(newFieldDefinition() - .name("floatNaNInput") - .type(Scalars.GraphQLFloat) - .argument(newArgument() - .name("input") - .type(GraphQLNonNull.nonNull(Scalars.GraphQLFloat))) - .dataFetcher(inputDF)) .field(newFieldDefinition() .name("stringInput") .type(Scalars.GraphQLString) .argument(newArgument() .name("input") - .type(GraphQLNonNull.nonNull(Scalars.GraphQLString))) - .dataFetcher(inputDF)) - - - /** Scalars with input of String, cast to scalar */ - .field(newFieldDefinition() - .name("bigIntegerString") - .type(Scalars.GraphQLBigInteger) - .argument(newArgument() - .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) - .field(newFieldDefinition() - .name("bigDecimalString") - .type(Scalars.GraphQLBigDecimal) - .argument(newArgument() - .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) + .type(GraphQLNonNull.nonNull(Scalars.GraphQLString)))) + // Scalars with input of String, cast to scalar .field(newFieldDefinition() .name("floatString") .type(Scalars.GraphQLFloat) .argument(newArgument() .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) - .field(newFieldDefinition() - .name("longString") - .type(Scalars.GraphQLLong) - .argument(newArgument() - .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) + .type(Scalars.GraphQLString))) .field(newFieldDefinition() .name("intString") .type(Scalars.GraphQLInt) .argument(newArgument() .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) - .field(newFieldDefinition() - .name("shortString") - .type(Scalars.GraphQLShort) - .argument(newArgument() - .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) - .field(newFieldDefinition() - .name("byteString") - .type(Scalars.GraphQLByte) - .argument(newArgument() - .name("input") - .type(Scalars.GraphQLString)) - .dataFetcher(inputDF)) + .type(Scalars.GraphQLString))) .build(); + static FieldCoordinates stringInputCoordinates = FieldCoordinates.coordinates("QueryType", "stringInput"); + static FieldCoordinates floatStringCoordinates = FieldCoordinates.coordinates("QueryType", "floatString"); + static FieldCoordinates intStringCoordinates = FieldCoordinates.coordinates("QueryType", "intString"); + static GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(stringInputCoordinates, inputDF) + .dataFetcher(floatStringCoordinates, inputDF) + .dataFetcher(intStringCoordinates, inputDF) + .build(); public static final GraphQLSchema scalarsQuerySchema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) .query(queryType) .build(); } diff --git a/src/test/groovy/graphql/ScalarsQueryTest.groovy b/src/test/groovy/graphql/ScalarsQueryTest.groovy index 6f3196b10f..6a0376bfae 100644 --- a/src/test/groovy/graphql/ScalarsQueryTest.groovy +++ b/src/test/groovy/graphql/ScalarsQueryTest.groovy @@ -1,82 +1,11 @@ package graphql -import graphql.execution.batched.BatchedExecutionStrategy + import spock.lang.Specification import spock.lang.Unroll class ScalarsQueryTest extends Specification { - def 'Large BigIntegers'() { - given: - def query = """ - query BigInteger { - bigInteger - i1: bigIntegerInput(input: 1234567890123456789012345678901234567890) - i2: bigIntegerInput(input: "1234567890123456789012345678901234567890") - i3: bigIntegerString(input: "1234567890123456789012345678901234567890") - } - """ - def expected = [ - bigInteger: 9999, - i1 : 1234567890123456789012345678901234567890, - i2 : 1234567890123456789012345678901234567890, - i3 : 1234567890123456789012345678901234567890 - ] - - when: - def result = GraphQL.newGraphQL(ScalarsQuerySchema.scalarsQuerySchema).build().execute(query) - - then: - result.data == expected - result.errors.empty == true - } - - def 'Large BigDecimals'() { - given: - def query = """ - query BigDecimal { - bigDecimal - d1: bigDecimalInput(input: "1234567890123456789012345678901234567890.0") - d2: bigDecimalInput(input: 1234567890123456789012345678901234567890.0) - d3: bigDecimalString(input: "1234567890123456789012345678901234567890.0") - } - """ - def expected = [ - bigDecimal: 1234.0, - d1 : 1234567890123456789012345678901234567890.0, - d2 : 1234567890123456789012345678901234567890.0, - d3 : 1234567890123456789012345678901234567890.0, - ] - - when: - def result = GraphQL.newGraphQL(ScalarsQuerySchema.scalarsQuerySchema).build().execute(query) - - then: - result.data == expected - result.errors.empty == true - } - - def 'Float NaN Not a Number '() { - given: - def query = """ - query FloatNaN { - floatNaN - } - """ - def expected = [ - floatNaN: null - ] - - when: - def result = GraphQL.newGraphQL(ScalarsQuerySchema.scalarsQuerySchema) - .build().execute(query) - def resultBatched = GraphQL.newGraphQL(ScalarsQuerySchema.scalarsQuerySchema) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .build().execute(query) - - then: - thrown(GraphQLException) - } def 'Escaped characters are handled'() { given: @@ -94,7 +23,7 @@ class ScalarsQueryTest extends Specification { then: result.data == expected - result.errors.empty == true + result.errors.empty } @Unroll @@ -109,13 +38,8 @@ class ScalarsQueryTest extends Specification { result.errors[0] instanceof SerializationError where: - number | _ - "bigInteger" | _ - "bigDecimal" | _ - "float" | _ - "long" | _ - "int" | _ - "short" | _ - "byte" | _ + number | _ + "float" | _ + "int" | _ } } diff --git a/src/test/groovy/graphql/ScalarsShortTest.groovy b/src/test/groovy/graphql/ScalarsShortTest.groovy deleted file mode 100644 index 2dda325287..0000000000 --- a/src/test/groovy/graphql/ScalarsShortTest.groovy +++ /dev/null @@ -1,114 +0,0 @@ -package graphql - -import graphql.language.FloatValue -import graphql.language.IntValue -import graphql.language.StringValue -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.CoercingSerializeException -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.concurrent.atomic.AtomicInteger - -class ScalarsShortTest extends Specification { - - @Unroll - def "Short parse literal #literal.value as #result"() { - expect: - Scalars.GraphQLShort.getCoercing().parseLiteral(literal) == result - - where: - literal | result - new IntValue(42 as BigInteger) | 42 - new IntValue(Short.MAX_VALUE as BigInteger) | Short.MAX_VALUE - new IntValue(Short.MIN_VALUE as BigInteger) | Short.MIN_VALUE - - } - - @Unroll - def "Short returns null for invalid #literal"() { - when: - Scalars.GraphQLShort.getCoercing().parseLiteral(literal) - then: - thrown(CoercingParseLiteralException) - - where: - literal | _ - new IntValue(12345678910 as BigInteger) | _ - new StringValue("-1") | _ - new FloatValue(42.3) | _ - new IntValue(Short.MAX_VALUE + 1l as BigInteger) | null - new IntValue(Short.MIN_VALUE - 1l as BigInteger) | null - new StringValue("-1") | null - new FloatValue(42.3) | null - } - - @Unroll - def "Short serialize #value into #result (#result.class)"() { - expect: - Scalars.GraphQLShort.getCoercing().serialize(value) == result - Scalars.GraphQLShort.getCoercing().parseValue(value) == result - - where: - value | result - "42" | 42 - "42.0000" | 42 - 42.0000d | 42 - new Integer(42) | 42 - "-1" | -1 - new BigInteger(42) | 42 - new BigDecimal("42") | 42 - 42.0f | 42 - 42.0d | 42 - new Byte("42") | 42 - new Short("42") | 42 - 1234l | 1234 - new AtomicInteger(42) | 42 - Short.MAX_VALUE | Short.MAX_VALUE - Short.MIN_VALUE | Short.MIN_VALUE - } - - @Unroll - def "serialize throws exception for invalid input #value"() { - when: - Scalars.GraphQLShort.getCoercing().serialize(value) - then: - thrown(CoercingSerializeException) - - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Long(42345784398534785l) | _ - new Double(42.3) | _ - new Float(42.3) | _ - Short.MAX_VALUE + 1l | _ - Short.MIN_VALUE - 1l | _ - new Object() | _ - - } - - @Unroll - def "parseValue throws exception for invalid input #value"() { - when: - Scalars.GraphQLShort.getCoercing().parseValue(value) - then: - thrown(CoercingParseValueException) - - where: - value | _ - "" | _ - "not a number " | _ - "42.3" | _ - new Long(42345784398534785l) | _ - new Double(42.3) | _ - new Float(42.3) | _ - Short.MAX_VALUE + 1l | _ - Short.MIN_VALUE - 1l | _ - new Object() | _ - - } - -} diff --git a/src/test/groovy/graphql/ScalarsStringTest.groovy b/src/test/groovy/graphql/ScalarsStringTest.groovy index f25ead1c74..cbd00f97d9 100644 --- a/src/test/groovy/graphql/ScalarsStringTest.groovy +++ b/src/test/groovy/graphql/ScalarsStringTest.groovy @@ -1,5 +1,6 @@ package graphql +import graphql.execution.CoercedVariables import graphql.language.BooleanValue import graphql.language.StringValue import graphql.schema.CoercingParseLiteralException @@ -10,7 +11,6 @@ import spock.lang.Unroll class ScalarsStringTest extends Specification { - @Shared def customObject = new Object() { @Override @@ -22,18 +22,27 @@ class ScalarsStringTest extends Specification { @Unroll def "String parse literal #literal.value as #result"() { expect: - Scalars.GraphQLString.getCoercing().parseLiteral(literal) == result + Scalars.GraphQLString.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) == result where: literal | result new StringValue("1234ab") | "1234ab" + } + + @Unroll + def "String parse literal #literal.value as #result with deprecated method"() { + expect: + Scalars.GraphQLString.getCoercing().parseLiteral(literal) == result // Retain deprecated for test coverage + where: + literal | result + new StringValue("1234ab") | "1234ab" } @Unroll def "String returns null for invalid #literal"() { when: - Scalars.GraphQLString.getCoercing().parseLiteral(literal) + Scalars.GraphQLString.getCoercing().parseLiteral(literal, CoercedVariables.emptyVariables(), GraphQLContext.default, Locale.default) then: thrown(CoercingParseLiteralException) @@ -45,8 +54,7 @@ class ScalarsStringTest extends Specification { @Unroll def "String serialize #value into #result (#result.class)"() { expect: - Scalars.GraphQLString.getCoercing().serialize(value) == result - Scalars.GraphQLString.getCoercing().parseValue(value) == result + Scalars.GraphQLString.getCoercing().serialize(value, GraphQLContext.default, Locale.default) == result where: value | result @@ -55,5 +63,47 @@ class ScalarsStringTest extends Specification { customObject | "foo" } + @Unroll + def "String serialize #value into #result (#result.class) with deprecated method"() { + expect: + Scalars.GraphQLString.getCoercing().serialize(value) == result // Retain deprecated method for test coverage + + where: + value | result + "123ab" | "123ab" + 123 | "123" + customObject | "foo" + } + def "String parseValue value into result"() { + expect: + Scalars.GraphQLString.getCoercing().parseValue("123ab", GraphQLContext.default, Locale.default) == "123ab" + } + + def "String parseValue value into result with deprecated method"() { + expect: + Scalars.GraphQLString.getCoercing().parseValue("123ab") == "123ab" // Retain deprecated method for test coverage + } + + @Unroll + def "String parseValue throws exception for non-String values"() { + when: + Scalars.GraphQLString.getCoercing().parseValue(value, GraphQLContext.default, Locale.default) + then: + thrown(CoercingParseValueException) + + where: + value | _ + 123 | _ + true | _ + customObject | _ + } + + def "String parseValue English exception message"() { + when: + Scalars.GraphQLString.getCoercing().parseValue(9001, GraphQLContext.default, Locale.ENGLISH) + then: + def ex = thrown(CoercingParseValueException) + ex.message == "Expected a String input, but it was a 'Integer'" + } } diff --git a/src/test/groovy/graphql/SkipAndInclude.groovy b/src/test/groovy/graphql/SkipAndInclude.groovy index 85ecf756f0..d0008f63fd 100644 --- a/src/test/groovy/graphql/SkipAndInclude.groovy +++ b/src/test/groovy/graphql/SkipAndInclude.groovy @@ -4,11 +4,11 @@ import spock.lang.Specification class SkipAndInclude extends Specification { - private def graphQL = GraphQL.newGraphQL(TestUtil.schema(""" + private def graphQL = TestUtil.graphQL(""" type Query { field: Int } - """)).build() + """).build() def "@skip and @include"() { when: diff --git a/src/test/groovy/graphql/StarWarsData.groovy b/src/test/groovy/graphql/StarWarsData.groovy index 2bfd4accc9..d4a406d565 100644 --- a/src/test/groovy/graphql/StarWarsData.groovy +++ b/src/test/groovy/graphql/StarWarsData.groovy @@ -94,7 +94,6 @@ class StarWarsData { } } - static DataFetcher droidDataFetcher = new DataFetcher() { @Override Object get(DataFetchingEnvironment environment) { diff --git a/src/test/groovy/graphql/StarWarsIntrospectionTests.groovy b/src/test/groovy/graphql/StarWarsIntrospectionTests.groovy index 3550665626..75411f6af0 100644 --- a/src/test/groovy/graphql/StarWarsIntrospectionTests.groovy +++ b/src/test/groovy/graphql/StarWarsIntrospectionTests.groovy @@ -7,6 +7,30 @@ import spock.lang.Specification class StarWarsIntrospectionTests extends Specification { def "Allows querying the schema for types"() { + def expected = [ + __schema: [types: + [ + [name: 'Boolean'], + [name: 'Character'], + [name: 'Droid'], + [name: 'Episode'], + [name: 'Human'], + [name: 'HumanInput'], + [name: 'MutationType'], + [name: 'QueryType'], + [name: 'String'], + [name: '__Directive'], + [name: '__DirectiveLocation'], + [name: '__EnumValue'], + [name: '__Field'], + [name: '__InputValue'], + [name: '__Schema'], + [name: '__Type'], + [name: '__TypeKind'], + ] + ] + + ] given: def query = """ query IntrospectionTypeQuery { @@ -17,26 +41,6 @@ class StarWarsIntrospectionTests extends Specification { } } """ - def expected = [ - __schema: [types: - [[name: 'QueryType'], - [name: 'Character'], - [name: 'String'], - [name: 'Episode'], - [name: 'Human'], - [name: 'Droid'], - [name: '__Schema'], - [name: '__Type'], - [name: '__TypeKind'], - [name: '__Field'], - [name: '__InputValue'], - [name: 'Boolean'], - [name: '__EnumValue'], - [name: '__Directive'], - [name: '__DirectiveLocation']] - ] - - ] when: def result = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build().execute(query).data @@ -162,31 +166,31 @@ class StarWarsIntrospectionTests extends Specification { name : 'Droid', fields: [ [ - name: 'id', + name: 'appearsIn', type: [ name: null, - kind: 'NON_NULL' + kind: 'LIST' ] ], [ - name: 'name', + name: 'friends', type: [ - name: 'String', - kind: 'SCALAR' + name: null, + kind: 'LIST' ] ], [ - name: 'friends', + name: 'id', type: [ name: null, - kind: 'LIST' + kind: 'NON_NULL' ] ], [ - name: 'appearsIn', + name: 'name', type: [ - name: null, - kind: 'LIST' + name: 'String', + kind: 'SCALAR' ] ], [ @@ -231,24 +235,16 @@ class StarWarsIntrospectionTests extends Specification { name : 'Droid', fields: [ [ - name: 'id', + name: 'appearsIn', type: [ name : null, - kind : 'NON_NULL', + kind : 'LIST', ofType: [ - name: 'String', - kind: 'SCALAR' + name: 'Episode', + kind: 'ENUM' ] ] ], - [ - name: 'name', - type: [ - name : 'String', - kind : 'SCALAR', - ofType: null - ] - ], [ name: 'friends', type: [ @@ -261,16 +257,24 @@ class StarWarsIntrospectionTests extends Specification { ] ], [ - name: 'appearsIn', + name: 'id', type: [ name : null, - kind : 'LIST', + kind : 'NON_NULL', ofType: [ - name: 'Episode', - kind: 'ENUM' + name: 'String', + kind: 'SCALAR' ] ] ], + [ + name: 'name', + type: [ + name : 'String', + kind : 'SCALAR', + ofType: null + ] + ], [ name: 'primaryFunction', type: [ @@ -319,6 +323,24 @@ class StarWarsIntrospectionTests extends Specification { __schema: [ queryType: [ fields: [ + [ + name: 'droid', + args: [ + [ + name : 'id', + description : 'id of the droid', + type : [ + kind : 'NON_NULL', + name : null, + ofType: [ + kind: 'SCALAR', + name: 'String' + ] + ], + defaultValue: null + ] + ] + ], [ name: 'hero', args: [ @@ -356,24 +378,6 @@ class StarWarsIntrospectionTests extends Specification { ] ] ], - [ - name: 'droid', - args: [ - [ - name : 'id', - description : 'id of the droid', - type : [ - kind : 'NON_NULL', - name : null, - ofType: [ - kind: 'SCALAR', - name: 'String' - ] - ], - defaultValue: null - ] - ] - ] ] ] ] @@ -423,9 +427,9 @@ class StarWarsIntrospectionTests extends Specification { Map schemaParts = (Map) schema.get("__schema") schemaParts.size() == 5 schemaParts.get('queryType').size() == 1 - schemaParts.get('mutationType') == null + schemaParts.get('mutationType').size() == 1 schemaParts.get('subscriptionType') == null - schemaParts.get('types').size() == 15 - schemaParts.get('directives').size() == 3 + schemaParts.get('types').size() == 17 + schemaParts.get('directives').size() == 7 } } diff --git a/src/test/groovy/graphql/StarWarsQueryTest.groovy b/src/test/groovy/graphql/StarWarsQueryTest.groovy index f28cb3fe1b..0ed8b46bb2 100644 --- a/src/test/groovy/graphql/StarWarsQueryTest.groovy +++ b/src/test/groovy/graphql/StarWarsQueryTest.groovy @@ -190,7 +190,8 @@ class StarWarsQueryTest extends Specification { ] ] when: - def result = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build().execute(query, null, params).data + def ei = ExecutionInput.newExecutionInput(query).variables(params).build() + def result = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build().execute(ei).data then: result == expected @@ -212,7 +213,8 @@ class StarWarsQueryTest extends Specification { human: null ] when: - def result = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build().execute(query, null, params).data + def ei = ExecutionInput.newExecutionInput(query).variables(params).build() + def result = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build().execute(ei).data then: result == expected diff --git a/src/test/groovy/graphql/StarWarsSchema.java b/src/test/groovy/graphql/StarWarsSchema.java index c95c1f50b2..bf5b891c02 100644 --- a/src/test/groovy/graphql/StarWarsSchema.java +++ b/src/test/groovy/graphql/StarWarsSchema.java @@ -1,7 +1,11 @@ package graphql; +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; @@ -11,21 +15,24 @@ import static graphql.schema.GraphQLArgument.newArgument; import static graphql.schema.GraphQLEnumType.newEnum; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; +import static graphql.schema.GraphQLInputObjectField.newInputObjectField; +import static graphql.schema.GraphQLInputObjectType.newInputObject; import static graphql.schema.GraphQLInterfaceType.newInterface; import static graphql.schema.GraphQLList.list; import static graphql.schema.GraphQLNonNull.nonNull; import static graphql.schema.GraphQLObjectType.newObject; import static graphql.schema.GraphQLTypeReference.typeRef; +import static graphql.schema.GraphqlTypeComparatorRegistry.*; public class StarWarsSchema { - public static GraphQLEnumType episodeEnum = newEnum() .name("Episode") .description("One of the films in the Star Wars Trilogy") .value("NEWHOPE", 4, "Released in 1977.") .value("EMPIRE", 5, "Released in 1980.") .value("JEDI", 6, "Released in 1983.") + .comparatorRegistry(BY_NAME_REGISTRY) .build(); @@ -48,7 +55,7 @@ public class StarWarsSchema { .name("appearsIn") .description("Which movies they appear in.") .type(list(episodeEnum))) - .typeResolver(StarWarsData.getCharacterTypeResolver()) + .comparatorRegistry(BY_NAME_REGISTRY) .build(); public static GraphQLObjectType humanType = newObject() @@ -66,8 +73,7 @@ public class StarWarsSchema { .field(newFieldDefinition() .name("friends") .description("The friends of the human, or an empty list if they have none.") - .type(list(characterInterface)) - .dataFetcher(StarWarsData.getFriendsDataFetcher())) + .type(list(characterInterface))) .field(newFieldDefinition() .name("appearsIn") .description("Which movies they appear in.") @@ -76,6 +82,7 @@ public class StarWarsSchema { .name("homePlanet") .description("The home planet of the human, or null if unknown.") .type(GraphQLString)) + .comparatorRegistry(BY_NAME_REGISTRY) .build(); public static GraphQLObjectType droidType = newObject() @@ -93,8 +100,7 @@ public class StarWarsSchema { .field(newFieldDefinition() .name("friends") .description("The friends of the droid, or an empty list if they have none.") - .type(list(characterInterface)) - .dataFetcher(StarWarsData.getFriendsDataFetcher())) + .type(list(characterInterface))) .field(newFieldDefinition() .name("appearsIn") .description("Which movies they appear in.") @@ -103,8 +109,18 @@ public class StarWarsSchema { .name("primaryFunction") .description("The primary function of the droid.") .type(GraphQLString)) + .comparatorRegistry(BY_NAME_REGISTRY) .build(); + public static GraphQLInputObjectType inputHumanType = newInputObject() + .name("HumanInput") + .description("Input for A humanoid creature in the Star Wars universe.") + .field(newInputObjectField() + .name("id") + .description("The id of the human.") + .type(nonNull(GraphQLString))) + .comparatorRegistry(BY_NAME_REGISTRY) + .build(); public static GraphQLObjectType queryType = newObject() .name("QueryType") @@ -114,28 +130,61 @@ public class StarWarsSchema { .argument(newArgument() .name("episode") .description("If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.") - .type(episodeEnum)) - .dataFetcher(new StaticDataFetcher(StarWarsData.getArtoo()))) + .type(episodeEnum))) .field(newFieldDefinition() .name("human") .type(humanType) .argument(newArgument() .name("id") .description("id of the human") - .type(nonNull(GraphQLString))) - .dataFetcher(StarWarsData.getHumanDataFetcher())) + .type(nonNull(GraphQLString)))) .field(newFieldDefinition() .name("droid") .type(droidType) .argument(newArgument() .name("id") .description("id of the droid") - .type(nonNull(GraphQLString))) - .dataFetcher(StarWarsData.getDroidDataFetcher())) + .type(nonNull(GraphQLString)))) + .comparatorRegistry(BY_NAME_REGISTRY) + .build(); + + public static GraphQLObjectType mutationType = newObject() + .name("MutationType") + .field(newFieldDefinition() + .name("createHuman") + .type(characterInterface) + .argument(newArgument() + .name("input") + .type(inputHumanType))) + .comparatorRegistry(BY_NAME_REGISTRY) .build(); + public static FieldCoordinates humanFriendsCoordinates = FieldCoordinates.coordinates("Human", "friends"); + public static DataFetcher humanFriendsDataFetcher = StarWarsData.getFriendsDataFetcher(); + public static FieldCoordinates droidFriendsCoordinates = FieldCoordinates.coordinates("Droid", "friends"); + public static DataFetcher droidFriendsDataFetcher = StarWarsData.getFriendsDataFetcher(); + public static FieldCoordinates heroCoordinates = FieldCoordinates.coordinates("QueryType", "hero"); + public static DataFetcher heroDataFetcher = new StaticDataFetcher(StarWarsData.getArtoo()); + public static FieldCoordinates humanCoordinates = FieldCoordinates.coordinates("QueryType", "human"); + public static DataFetcher humanDataFetcher = StarWarsData.getHumanDataFetcher(); + public static FieldCoordinates droidCoordinates = FieldCoordinates.coordinates("QueryType", "droid"); + public static DataFetcher droidDataFetcher = StarWarsData.getDroidDataFetcher(); + public static FieldCoordinates createHumanCoordinates = FieldCoordinates.coordinates("MutationType", "createHuman"); + public static DataFetcher createHumanDataFetcher = new StaticDataFetcher(StarWarsData.getArtoo()); + + public static GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(humanFriendsCoordinates, humanFriendsDataFetcher) + .dataFetcher(droidFriendsCoordinates, droidFriendsDataFetcher) + .dataFetcher(heroCoordinates, heroDataFetcher) + .dataFetcher(humanCoordinates, humanDataFetcher) + .dataFetcher(droidCoordinates, droidDataFetcher) + .dataFetcher(createHumanCoordinates, createHumanDataFetcher) + .typeResolver("Character", StarWarsData.getCharacterTypeResolver()) + .build(); public static GraphQLSchema starWarsSchema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) .query(queryType) + .mutation(mutationType) .build(); } diff --git a/src/test/groovy/graphql/StarWarsValidationTest.groovy b/src/test/groovy/graphql/StarWarsValidationTest.groovy index 86bcf76cac..4343f0f580 100644 --- a/src/test/groovy/graphql/StarWarsValidationTest.groovy +++ b/src/test/groovy/graphql/StarWarsValidationTest.groovy @@ -7,10 +7,9 @@ import spock.lang.Specification class StarWarsValidationTest extends Specification { - - List validate(String query) { + static List validate(String query) { def document = new Parser().parseDocument(query) - return new Validator().validateDocument(StarWarsSchema.starWarsSchema, document) + return new Validator().validateDocument(StarWarsSchema.starWarsSchema, document, Locale.ENGLISH) } def 'Validates a complex but valid query'() { diff --git a/src/test/groovy/graphql/TestUtil.groovy b/src/test/groovy/graphql/TestUtil.groovy index d0048e339d..fce61c315c 100644 --- a/src/test/groovy/graphql/TestUtil.groovy +++ b/src/test/groovy/graphql/TestUtil.groovy @@ -1,49 +1,93 @@ package graphql +import graphql.execution.MergedField +import graphql.execution.MergedSelectionSet +import graphql.execution.pubsub.CapturingSubscriber +import graphql.incremental.DelayedIncrementalPartialResult +import graphql.incremental.IncrementalExecutionResult import graphql.introspection.Introspection.DirectiveLocation import graphql.language.Document +import graphql.language.Field +import graphql.language.NullValue +import graphql.language.ObjectTypeDefinition +import graphql.language.OperationDefinition import graphql.language.ScalarTypeDefinition +import graphql.language.Type import graphql.parser.Parser import graphql.schema.Coercing import graphql.schema.DataFetcher +import graphql.schema.GraphQLAppliedDirective +import graphql.schema.GraphQLAppliedDirectiveArgument import graphql.schema.GraphQLArgument import graphql.schema.GraphQLDirective -import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLInputType import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLType import graphql.schema.TypeResolver -import graphql.schema.idl.MockedWiringFactory import graphql.schema.idl.RuntimeWiring import graphql.schema.idl.SchemaGenerator import graphql.schema.idl.SchemaParser +import graphql.schema.idl.TestMockedWiringFactory import graphql.schema.idl.TypeRuntimeWiring import graphql.schema.idl.WiringFactory import graphql.schema.idl.errors.SchemaProblem +import groovy.json.JsonOutput +import org.awaitility.Awaitility +import org.reactivestreams.Publisher +import java.util.function.Supplier import java.util.stream.Collectors +import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLDirective.newDirective +import static graphql.schema.GraphQLFieldDefinition.Builder +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLScalarType.newScalar +import static graphql.schema.GraphQLSchema.newSchema class TestUtil { static GraphQLSchema schemaWithInputType(GraphQLInputType inputType) { GraphQLArgument.Builder fieldArgument = newArgument().name("arg").type(inputType) - GraphQLFieldDefinition.Builder name = GraphQLFieldDefinition.newFieldDefinition() + Builder name = newFieldDefinition() .name("name").type(GraphQLString).argument(fieldArgument) - GraphQLObjectType queryType = GraphQLObjectType.newObject().name("query").field(name).build() - new GraphQLSchema(queryType) + GraphQLObjectType queryType = newObject().name("query").field(name).build() + newSchema().query(queryType).build() } - static dummySchema = GraphQLSchema.newSchema() - .query(GraphQLObjectType.newObject() - .name("QueryType") - .build()) + static dummySchema = newSchema() + .query(newObject() + .name("QueryType") + .field(newFieldDefinition().name("field").type(GraphQLString)) + .build()) .build() + static GraphQLSchema schemaFile(String fileName) { + return schemaFile(fileName, mockRuntimeWiring) + } + + + static GraphQLSchema schemaFromResource(String resourceFileName, RuntimeWiring wiring) { + def stream = TestUtil.class.getClassLoader().getResourceAsStream(resourceFileName) + return schema(stream, wiring) + } + + + static GraphQLSchema schemaFile(String fileName, RuntimeWiring wiring) { + def stream = TestUtil.class.getClassLoader().getResourceAsStream(fileName) + + def typeRegistry = new SchemaParser().parse(new InputStreamReader(stream)) + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, typeRegistry, wiring) + schema + } + static GraphQLSchema schema(String spec, Map> dataFetchers) { def wiring = RuntimeWiring.newRuntimeWiring() dataFetchers.each { type, fieldFetchers -> @@ -65,39 +109,18 @@ class TestUtil { schema(specReader, mockRuntimeWiring) } - static GraphQLSchema schemaFile(String fileName) { - return schemaFile(fileName, mockRuntimeWiring) - } - - - static GraphQLSchema schemaFromResource(String resourceFileName, RuntimeWiring wiring) { - def stream = TestUtil.class.getClassLoader().getResourceAsStream(resourceFileName) - return schema(stream, wiring) - } - - - static GraphQLSchema schemaFile(String fileName, RuntimeWiring wiring) { - def stream = TestUtil.class.getClassLoader().getResourceAsStream(fileName) - - def typeRegistry = new SchemaParser().parse(new InputStreamReader(stream)) - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(false) - def schema = new SchemaGenerator().makeExecutableSchema(options, typeRegistry, wiring) - schema - } - - - static GraphQLSchema schema(String spec, RuntimeWiring runtimeWiring) { - schema(new StringReader(spec), runtimeWiring) + static GraphQLSchema schema(String spec, RuntimeWiring runtimeWiring, boolean commentsAsDescription = true) { + schema(new StringReader(spec), runtimeWiring, commentsAsDescription) } static GraphQLSchema schema(InputStream specStream, RuntimeWiring runtimeWiring) { schema(new InputStreamReader(specStream), runtimeWiring) } - static GraphQLSchema schema(Reader specReader, RuntimeWiring runtimeWiring) { + static GraphQLSchema schema(Reader specReader, RuntimeWiring runtimeWiring, boolean commentsAsDescription = true) { try { def registry = new SchemaParser().parse(specReader) - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(false) + def options = SchemaGenerator.Options.defaultOptions().useCommentsAsDescriptions(commentsAsDescription) return new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) } catch (SchemaProblem e) { assert false: "The schema could not be compiled : ${e}" @@ -115,15 +138,45 @@ class TestUtil { } } - static WiringFactory mockWiringFactory = new MockedWiringFactory() + static GraphQL.Builder graphQL(String spec) { + return graphQL(new StringReader(spec), mockRuntimeWiring) + } + + static GraphQL.Builder graphQL(String spec, RuntimeWiring runtimeWiring) { + return graphQL(new StringReader(spec), runtimeWiring) + } + + static GraphQL.Builder graphQL(String spec, RuntimeWiring.Builder runtimeWiring) { + return graphQL(new StringReader(spec), runtimeWiring.build()) + } + + static GraphQL.Builder graphQL(String spec, Map> dataFetchers) { + toGraphqlBuilder({ -> schema(spec, dataFetchers) }) + } + + static GraphQL.Builder graphQL(Reader specReader, RuntimeWiring runtimeWiring) { + return toGraphqlBuilder({ -> schema(specReader, runtimeWiring) }) + } + + private static GraphQL.Builder toGraphqlBuilder(Supplier supplier) { + try { + def schema = supplier.get() + return GraphQL.newGraphQL(schema) + } catch (SchemaProblem e) { + assert false: "The schema could not be compiled : ${e}" + return null + } + } + + static WiringFactory mockWiringFactory = new TestMockedWiringFactory() static RuntimeWiring mockRuntimeWiring = RuntimeWiring.newRuntimeWiring().wiringFactory(mockWiringFactory).build() static GraphQLScalarType mockScalar(String name) { - new GraphQLScalarType(name, name, mockCoercing()) + newScalar().name(name).description(name).coercing(mockCoercing()).build() } - private static Coercing mockCoercing() { + static Coercing mockCoercing() { new Coercing() { @Override Object serialize(Object dataFetcherResult) { @@ -137,22 +190,29 @@ class TestUtil { @Override Object parseLiteral(Object input) { - return null + return NullValue.newNullValue().build() } } } static GraphQLScalarType mockScalar(ScalarTypeDefinition definition) { - new GraphQLScalarType( - definition.getName(), - definition.getDescription() == null ? null : definition.getDescription().getContent(), - mockCoercing(), - definition.getDirectives().stream().map({ mockDirective(it.getName()) }).collect(Collectors.toList()), - definition) + newScalar() + .name(definition.getName()) + .description(definition.getDescription() == null ? null : definition.getDescription().getContent()) + .coercing(mockCoercing()) + .replaceDirectives( + definition.getDirectives() + .stream() + .map({ mkDirective(it.getName(), DirectiveLocation.SCALAR) }) + .collect(Collectors.toList())) + .definition(definition) + .build() } - static GraphQLDirective mockDirective(String name) { - new GraphQLDirective(name, name, EnumSet.noneOf(DirectiveLocation.class), Collections.emptyList(), false, false, false) + static GraphQLDirective mkDirective(String name, DirectiveLocation location, GraphQLArgument arg = null) { + def b = newDirective().name(name).description(name).validLocation(location) + if (arg != null) b.argument(arg) + b.build() } static TypeRuntimeWiring mockTypeRuntimeWiring(String typeName, boolean withResolver) { @@ -173,4 +233,190 @@ class TestUtil { new Parser().parseDocument(query) } + static Type parseType(String typeAst) { + String docStr = """ + type X { + field : $typeAst + } + """ + try { + def document = toDocument(docStr) + ObjectTypeDefinition objTypeDef = document.getDefinitionsOfType(ObjectTypeDefinition.class)[0] + return objTypeDef.fieldDefinitions[0].getType() + } catch (Exception ignored) { + assert false, "Invalid type AST string : $typeAst" + return null + } + } + + static Document toDocument(String query) { + parseQuery(query) + } + + static MergedField mergedField(List fields) { + return MergedField.newMergedField(fields).build() + } + + static MergedField mergedField(Field field) { + return MergedField.newMergedField(field).build() + } + + static MergedSelectionSet mergedSelectionSet(Map subFields) { + return MergedSelectionSet.newMergedSelectionSet().subFields(subFields).build() + } + + static Field parseField(String sdlField) { + String spec = """ query Foo { + $sdlField + } + """ + def document = parseQuery(spec) + def op = document.getDefinitionsOfType(OperationDefinition.class)[0] + return op.getSelectionSet().getSelectionsOfType(Field.class)[0] as Field + } + + static GraphQLAppliedDirective[] mockDirectivesWithArguments(String... names) { + return names.collect { directiveName -> + def builder = GraphQLAppliedDirective.newDirective().name(directiveName) + + names.each { argName -> + builder.argument(GraphQLAppliedDirectiveArgument.newArgument().name(argName).type(GraphQLInt).valueProgrammatic(BigInteger.valueOf(0)).build()) + } + return builder.build() + }.toArray() as GraphQLAppliedDirective[] + } + + static GraphQLAppliedDirective[] mockDirectivesWithNoValueArguments(String... names) { + return names.collect { directiveName -> + def builder = GraphQLAppliedDirective.newDirective().name(directiveName) + + names.each { argName -> + builder.argument(GraphQLAppliedDirectiveArgument.newArgument().name(argName).type(GraphQLInt).build()) + } + return builder.build() + }.toArray() as GraphQLAppliedDirective[] + } + + static List mockArguments(String... names) { + return names.collect { newArgument().name(it).type(GraphQLInt).build() } + } + + static List mockAppliedArguments(String... names) { + return names.collect { newArgument().name(it).type(GraphQLInt).build() } + } + + static Comparator byGreatestLength = Comparator.comparing({ it.name }, + Comparator.comparing({ it.length() }).reversed()) + + + /** + * Turns a object kinto JSON and prints it - Helpful for debugging + * @param obj some obj + * @return a string + */ + static String prettyPrint(Object obj) { + if (obj instanceof ExecutionResult) { + obj = ((ExecutionResult) obj).toSpecification() + } + return JsonOutput.prettyPrint(JsonOutput.toJson(obj)) + + } + + static Random rn = new Random() + + static int rand(int min, int max) { + return rn.nextInt(max - min + 1) + min + } + + + /** + * Helper to say that a sub list is contained inside rhe master list in order for its entire length + * + * @param source the source list to check + * @param target the target list + * @return true if the target lists are inside the source list in order + */ + static boolean listContainsInOrder(List source, List target, List... targets) { + def index = indexOfSubListFrom(0, source, target) + if (index == -1) { + return false + } + for (List list : targets) { + index = indexOfSubListFrom(index, source, list) + if (index == -1) { + return false + } + } + return true + } + + /** + * Finds the index of the target list inside the source list starting from the specified index + * + * @param startIndex the starting index + * @param source the source list + * @param target the target list + * @return the index of the target list or -1 + */ + static int indexOfSubListFrom(int startIndex, List source, List target) { + def subListSize = target.size() + def masterListSize = source.size() + if (masterListSize < subListSize) { + return -1 + } + if (target.isEmpty() || source.isEmpty()) { + return -1 + } + for (int i = startIndex; i < masterListSize; i++) { + // starting at each index look for the sub list + if (i + subListSize > masterListSize) { + return -1 + } + + boolean matches = true + for (int j = 0; j < subListSize; j++) { + T sub = target.get(j) + T m = source.get(i + j) + if (!eq(sub, m)) { + matches = false + break + } + } + if (matches) { + return i + } + } + return -1 + } + + private static boolean eq(T t1, T t2) { + if (t1 == null && t2 == null) { + return true + } + if (t1 != null && t2 != null) { + return t1 == t2 + } + return false + } + + + static T last(List list) { + return list.get(list.size()-1) + } + + static List> getIncrementalResults(IncrementalExecutionResult initialResult) { + Publisher deferredResultStream = initialResult.incrementalItemPublisher + + def subscriber = new CapturingSubscriber() + + deferredResultStream.subscribe(subscriber) + + Awaitility.await().untilTrue(subscriber.isDone()) + if (subscriber.throwable != null) { + throw new RuntimeException(subscriber.throwable) + } + return subscriber.getEvents() + .collect { it.toSpecification() } + } + } diff --git a/src/test/groovy/graphql/TestUtilTest.groovy b/src/test/groovy/graphql/TestUtilTest.groovy new file mode 100644 index 0000000000..faf63d66aa --- /dev/null +++ b/src/test/groovy/graphql/TestUtilTest.groovy @@ -0,0 +1,104 @@ +package graphql + +import spock.lang.Specification + +class TestUtilTest extends Specification { + + def "list contains in order"() { + given: + def masterList = ["a", "b", "c", "d", "e", "f", "g"] + + when: + def actual = TestUtil.listContainsInOrder(masterList, subList) + + then: + actual == expected + + where: + subList | expected + ["a"] | true + ["f"] | true + ["c", "d"] | true + ["f", "g"] | true + ["a", "b", "c", "d", "e", "f", "g"] | true + ["f", "g", "X"] | false + ["b", "c", "e"] | false + [] | false + ["a", "b", "c", "d", "e", "f", "g", "X"] | false + ["A", "B", "C"] | false + } + + def "list contains in order edge cases"() { + when: + def actual = TestUtil.listContainsInOrder([], []) + then: + !actual + + when: + actual = TestUtil.listContainsInOrder(["a"], []) + then: + !actual + + when: + actual = TestUtil.listContainsInOrder([], ["a"]) + then: + !actual + + when: + actual = TestUtil.listContainsInOrder([null, "a", null], [null, "a"]) + then: + actual + } + + def "list contains in order many lists"() { + def master = ["a", "b", "c", "d", "e", "f", "g"] + when: + def actual = TestUtil.listContainsInOrder(master, + ["b", "c"], ["e", "f"]) + then: + actual + + when: + actual = TestUtil.listContainsInOrder(master, + ["b", "c"], ["g"]) + then: + actual + + when: + actual = TestUtil.listContainsInOrder(master, + ["b", "c"], ["f", "g", "X"]) + then: + !actual + + when: + actual = TestUtil.listContainsInOrder(master, + ["a"], ["b"], ["c"], ["d"], ["e"], ["f"], ["g"]) + then: + actual + + when: + actual = TestUtil.listContainsInOrder(master, + ["a", "b"], ["c", "d"], ["e"], ["f"], ["g"]) + then: + actual + + when: + actual = TestUtil.listContainsInOrder(master, + ["a"], ["b"], ["c"], ["d"], ["e"], ["f"], ["g"], ["X"]) + then: + !actual + + when: "empty" + actual = TestUtil.listContainsInOrder(master, + ["a"], [], ["c"]) + then: + !actual + + when: + actual = TestUtil.listContainsInOrder(master, + ["a"], ["b"], ["c"], ["X"], ["e"], ["f"], ["g"]) + then: + !actual + + } +} diff --git a/src/test/groovy/graphql/TypeMismatchErrorTest.groovy b/src/test/groovy/graphql/TypeMismatchErrorTest.groovy index f1f363c695..ff226aab8b 100644 --- a/src/test/groovy/graphql/TypeMismatchErrorTest.groovy +++ b/src/test/groovy/graphql/TypeMismatchErrorTest.groovy @@ -1,18 +1,17 @@ package graphql import graphql.introspection.Introspection -import graphql.schema.GraphQLEnumType -import graphql.schema.GraphQLInputObjectType -import graphql.schema.GraphQLInterfaceType -import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLType -import graphql.schema.GraphQLUnionType -import graphql.schema.TypeResolverProxy import spock.lang.Specification import spock.lang.Unroll +import static graphql.schema.GraphQLEnumType.newEnum +import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLInterfaceType.newInterface import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLUnionType.newUnionType class TypeMismatchErrorTest extends Specification { @@ -22,14 +21,14 @@ class TypeMismatchErrorTest extends Specification { TypeMismatchError.GraphQLTypeToTypeKindMapping.getTypeKindFromGraphQLType(type) == typeKind where: - type || typeKind - list(Scalars.GraphQLInt) || Introspection.TypeKind.LIST - Scalars.GraphQLInt || Introspection.TypeKind.SCALAR - new GraphQLObjectType("myObject", "...", [], []) || Introspection.TypeKind.OBJECT - new GraphQLEnumType("myEnum", "...", []) || Introspection.TypeKind.ENUM - new GraphQLInputObjectType("myInputType", "...", []) || Introspection.TypeKind.INPUT_OBJECT - new GraphQLInterfaceType("myInterfaceType", "...", [], new TypeResolverProxy()) || Introspection.TypeKind.INTERFACE - nonNull(Scalars.GraphQLInt) || Introspection.TypeKind.NON_NULL - new GraphQLUnionType("myUnion", "...", [Scalars.GraphQLInt], new TypeResolverProxy()) || Introspection.TypeKind.UNION + type || typeKind + list(Scalars.GraphQLInt) || Introspection.TypeKind.LIST + Scalars.GraphQLInt || Introspection.TypeKind.SCALAR + newObject().name("myObject").fields([]).build() || Introspection.TypeKind.OBJECT + newEnum().name("myEnum").values([]).build() || Introspection.TypeKind.ENUM + newInputObject().name("myInputType").fields([]).build() || Introspection.TypeKind.INPUT_OBJECT + newInterface().name("myInterfaceType").fields([]).build() || Introspection.TypeKind.INTERFACE + nonNull(Scalars.GraphQLInt) || Introspection.TypeKind.NON_NULL + newUnionType().name("myUnion").possibleType(newObject().name("test").build()).build() || Introspection.TypeKind.UNION } } diff --git a/src/test/groovy/graphql/TypeReferenceSchema.java b/src/test/groovy/graphql/TypeReferenceSchema.java index 88e9677a27..1989a29d1d 100644 --- a/src/test/groovy/graphql/TypeReferenceSchema.java +++ b/src/test/groovy/graphql/TypeReferenceSchema.java @@ -1,9 +1,17 @@ package graphql; +import graphql.schema.Coercing; +import graphql.schema.GraphQLAppliedDirective; +import graphql.schema.GraphQLAppliedDirectiveArgument; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLEnumType; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLInputObjectType; +import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLScalarType; import graphql.schema.GraphQLSchema; import graphql.schema.GraphQLTypeReference; import graphql.schema.GraphQLUnionType; @@ -17,6 +25,11 @@ import static graphql.GarfieldSchema.NamedType; import static graphql.Scalars.GraphQLBoolean; import static graphql.Scalars.GraphQLString; +import static graphql.introspection.Introspection.DirectiveLocation; +import static graphql.schema.GraphQLArgument.newArgument; +import static graphql.schema.GraphQLDirective.newDirective; +import static graphql.schema.GraphQLEnumType.newEnum; +import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLInputObjectField.newInputObjectField; import static graphql.schema.GraphQLInputObjectType.newInputObject; @@ -25,53 +38,314 @@ public class TypeReferenceSchema { - public static GraphQLUnionType PetType = newUnionType() - .name("Pet") - .possibleType(GraphQLTypeReference.typeRef(CatType.getName())) - .possibleType(GraphQLTypeReference.typeRef(DogType.getName())) - .typeResolver(new TypeResolverProxy()) - .build(); - public static GraphQLInputObjectType PersonInputType = newInputObject() - .name("Person_Input") - .field(newInputObjectField() - .name("name") - .type(GraphQLString)) - .build(); + private static final GraphQLScalarType OnOff; - public static GraphQLObjectType PersonType = newObject() - .name("Person") - .field(newFieldDefinition() - .name("name") - .type(GraphQLString)) - .field(newFieldDefinition() - .name("pet") - .type(GraphQLTypeReference.typeRef(PetType.getName()))) - .withInterface(GraphQLTypeReference.typeRef(NamedType.getName())) - .build(); + private static GraphQLDirective serialisedToDirective; - public static GraphQLFieldDefinition exists = newFieldDefinition() - .name("exists") - .type(GraphQLBoolean) - .argument(GraphQLArgument.newArgument() - .name("person") - .type(GraphQLTypeReference.typeRef("Person_Input"))) - .build(); + static { + serialisedToDirective = newDirective() + .name("serializeTo") + .validLocation(DirectiveLocation.SCALAR) + .argument(newArgument() + .name("type") + .type(GraphQLTypeReference.typeRef(GraphQLBoolean.getName()))) + .build(); + + OnOff = GraphQLScalarType.newScalar() + .name("OnOff") + .coercing(new Coercing() { + + private static final String TEST_ONLY = "For testing only"; + + @Override + public Boolean serialize(Object input) { + throw new UnsupportedOperationException(TEST_ONLY); + } + + @Override + public Boolean parseValue(Object input) { + throw new UnsupportedOperationException(TEST_ONLY); + } + + @Override + public Boolean parseLiteral(Object input) { + throw new UnsupportedOperationException(TEST_ONLY); + } + }) + .withDirective(serialisedToDirective) + .build(); + } + + public static GraphQLScalarType UnionDirectiveInput = OnOff.transform(builder -> builder.name("Union_Directive_Input")); + public static GraphQLScalarType InputObjectDirectiveInput = OnOff.transform(builder -> builder.name("Input_Object_Directive_Input")); + public static GraphQLScalarType ObjectDirectiveInput = OnOff.transform(builder -> builder.name("Object_Directive_Input")); + public static GraphQLScalarType FieldDefDirectiveInput = OnOff.transform(builder -> builder.name("Field_Def_Directive_Input")); + public static GraphQLScalarType ArgumentDirectiveInput = OnOff.transform(builder -> builder.name("Argument_Directive_Input")); + public static GraphQLScalarType InputFieldDefDirectiveInput = OnOff.transform(builder -> builder.name("Input_Field_Def_Directive_Input")); + public static GraphQLScalarType InterfaceDirectiveInput = OnOff.transform(builder -> builder.name("Interface_Directive_Input")); + public static GraphQLScalarType EnumDirectiveInput = OnOff.transform(builder -> builder.name("Enum_Directive_Input")); + public static GraphQLScalarType EnumValueDirectiveInput = OnOff.transform(builder -> builder.name("Enum_Value_Directive_Input")); + public static GraphQLScalarType QueryDirectiveInput = OnOff.transform(builder -> builder.name("Query_Directive_Input")); + + private static GraphQLEnumType HairStyle; + private static GraphQLDirective enumDirective; + private static GraphQLDirective enumValueDirective; + + + static { + + enumDirective = newDirective() + .name("enumDirective") + .validLocation(DirectiveLocation.ENUM) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(EnumDirectiveInput)) + .build(); + + enumValueDirective = newDirective() + .name("enumValueDirective") + .validLocation(DirectiveLocation.ENUM_VALUE) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(EnumValueDirectiveInput)) + .build(); + + HairStyle = newEnum() + .name("HairStyle") + .withDirective(enumDirective) + .value(newEnumValueDefinition() + .name("Short") + .value("Short") + .withDirective(enumValueDirective) + .build()) + .value(newEnumValueDefinition() + .name("Long") + .value("Long") + .build()) + .build(); + } + + private static GraphQLUnionType PetType; + private static GraphQLDirective unionDirective; + + static { + unionDirective = newDirective() + .name("unionDirective") + .validLocation(DirectiveLocation.UNION) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(UnionDirectiveInput)) + .build(); + + PetType = newUnionType() + .name("Pet") + .possibleType(GraphQLTypeReference.typeRef(CatType.getName())) + .possibleType(GraphQLTypeReference.typeRef(DogType.getName())) + .withDirective(unionDirective) + .build(); + } + + private static GraphQLInterfaceType Addressable; + private static GraphQLDirective interfaceDirective; - public static GraphQLFieldDefinition find = newFieldDefinition() + static { + + interfaceDirective = newDirective() + .name("interfaceDirective") + .validLocation(DirectiveLocation.INTERFACE) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(InterfaceDirectiveInput)) + .build(); + + Addressable = GraphQLInterfaceType.newInterface() + .name("Addressable") + .field(GraphQLFieldDefinition.newFieldDefinition() + .name("address") + .type(GraphQLString)) + .withDirective(interfaceDirective) + .build(); + } + + private static GraphQLInputObjectType PersonInputType; + private static GraphQLDirective inputObjectDirective; + private static GraphQLDirective inputFieldDefDirective; + + static { + inputObjectDirective = newDirective() + .name("inputObjectDirective") + .validLocation(DirectiveLocation.INPUT_OBJECT) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(InputObjectDirectiveInput)) + .build(); + + inputFieldDefDirective = newDirective() + .name("inputFieldDefDirective") + .validLocation(DirectiveLocation.INPUT_FIELD_DEFINITION) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(InputFieldDefDirectiveInput)) + .build(); + + + PersonInputType = newInputObject() + .name("Person_Input") + .field(newInputObjectField() + .name("name") + .type(GraphQLString) + .withDirective(inputFieldDefDirective)) + .withDirective(inputObjectDirective) + .build(); + } + + private static GraphQLObjectType PersonType; + private static GraphQLDirective objectDirective; + + static { + objectDirective = newDirective() + .name("objectDirective") + .validLocation(DirectiveLocation.OBJECT) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(ObjectDirectiveInput)) + .build(); + + PersonType = newObject() + .name("Person") + .field(newFieldDefinition() + .name("name") + .type(GraphQLString)) + .field(newFieldDefinition() + .name("address") + .type(GraphQLString)) + .field(newFieldDefinition() + .name("pet") + .type(GraphQLTypeReference.typeRef(PetType.getName()))) + .field(newFieldDefinition() + .name("hairStyle") + .type(GraphQLTypeReference.typeRef(HairStyle.getName()))) + .withInterface(GraphQLTypeReference.typeRef(NamedType.getName())) + .withInterface(Addressable) + .withDirective(objectDirective) + .build(); + } + + private static GraphQLFieldDefinition exists; + private static GraphQLDirective fieldDefDirective; + private static GraphQLDirective argumentDirective; + + static { + fieldDefDirective = newDirective() + .name("fieldDefDirective") + .validLocation(DirectiveLocation.FIELD_DEFINITION) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(FieldDefDirectiveInput)) + .build(); + + argumentDirective = newDirective() + .name("argumentDirective") + .validLocation(DirectiveLocation.ARGUMENT_DEFINITION) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(newArgument() + .name("input") + .type(ArgumentDirectiveInput)) + .build(); + + + exists = newFieldDefinition() + .name("exists") + .type(GraphQLBoolean) + .argument(newArgument() + .name("person") + .type(GraphQLTypeReference.typeRef("Person_Input")) + .withDirective(argumentDirective)) + .withDirective(fieldDefDirective) + .build(); + } + + private static GraphQLFieldDefinition find = newFieldDefinition() .name("find") .type(GraphQLTypeReference.typeRef("Person")) - .argument(GraphQLArgument.newArgument() + .argument(newArgument() .name("name") .type(GraphQLString)) .build(); - public static GraphQLObjectType PersonService = newObject() + private static GraphQLObjectType PersonService = newObject() .name("PersonService") .field(exists) .field(find) .build(); - public static GraphQLSchema SchemaWithReferences = new GraphQLSchema(PersonService, null, - new HashSet<>(Arrays.asList(PersonType, PersonInputType, PetType, CatType, DogType, NamedType))); + public static GraphQLDirective Cache = newDirective() + .name("cache") + .validLocations(DirectiveLocation.QUERY) + .argument(newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName()))) + .argument(GraphQLArgument.newArgument() + .name("input") + .type(QueryDirectiveInput)) + .build(); + + public static GraphQLAppliedDirective cacheApplied = GraphQLAppliedDirective.newDirective() + .name("cache") + .argument(GraphQLAppliedDirectiveArgument.newArgument() + .name("enabled") + .type(GraphQLTypeReference.typeRef(OnOff.getName())) + .valueProgrammatic("On")) + .build(); + + public static GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver("Pet", new TypeResolverProxy()) + .typeResolver("Addressable", new TypeResolverProxy()) + .typeResolver("Named", GarfieldSchema.namedTypeResolver) + .build(); + + public static GraphQLSchema SchemaWithReferences = GraphQLSchema.newSchema() + .query(PersonService) + .additionalTypes(new HashSet<>(Arrays.asList(PersonType, PersonInputType, PetType, CatType, DogType, NamedType, HairStyle, OnOff))) + .additionalDirective(Cache) + .additionalDirective(fieldDefDirective) + .additionalDirective(argumentDirective) + .additionalDirective(inputObjectDirective) + .additionalDirective(inputFieldDefDirective) + .additionalDirective(serialisedToDirective) + .additionalDirective(objectDirective) + .additionalDirective(unionDirective) + .additionalDirective(enumDirective) + .additionalDirective(enumValueDirective) + .additionalDirective(interfaceDirective) + .codeRegistry(codeRegistry) + .withSchemaAppliedDirectives(cacheApplied) + .build(); } diff --git a/src/test/groovy/graphql/TypeResolutionEnvironmentTest.groovy b/src/test/groovy/graphql/TypeResolutionEnvironmentTest.groovy index 594fee50fe..55be8cc947 100644 --- a/src/test/groovy/graphql/TypeResolutionEnvironmentTest.groovy +++ b/src/test/groovy/graphql/TypeResolutionEnvironmentTest.groovy @@ -1,10 +1,14 @@ package graphql + +import graphql.execution.TypeResolutionParameters import graphql.language.Field import graphql.schema.GraphQLObjectType import graphql.schema.TypeResolver import spock.lang.Specification +import static graphql.TestUtil.mergedField + class TypeResolutionEnvironmentTest extends Specification { def idl = """ @@ -22,7 +26,7 @@ class TypeResolutionEnvironmentTest extends Specification { bar : String } - type FooBar implements Foo, Bar { + type FooBar implements Foo & Bar { foo : String bar : String } @@ -34,10 +38,23 @@ class TypeResolutionEnvironmentTest extends Specification { def schema = TestUtil.schema(idl) + def interfaceType = schema.getType("Foo") + + def graphqlContext = GraphQLContext.newContext().of("a", "b").build() + def "basic operations"() { given: - def environment = new TypeResolutionEnvironment("source", [:], new Field("field"), Scalars.GraphQLString, schema, "FooBar") + def environment = TypeResolutionParameters.newParameters() + .value("source") + .argumentValues(() -> [a: "b"]) + .field(mergedField(new Field("field"))) + .fieldType(interfaceType) + .schema(schema) + .context("FooBar") // Retain for test coverage + .graphQLContext(graphqlContext) + .localContext("LocalContext") + .build() when: @@ -46,6 +63,12 @@ class TypeResolutionEnvironmentTest extends Specification { GraphQLObjectType getType(TypeResolutionEnvironment env) { String source = env.getObject() assert source == "source" + assert env.getField().getName() == "field" + assert env.getFieldType() == interfaceType + assert env.getContext() == "FooBar" // Retain for test coverage + assert env.getLocalContext() == "LocalContext" + assert env.getGraphQLContext() == graphqlContext + assert env.getArguments() == [a: "b"] return schema.getObjectType("FooBar") } } @@ -80,10 +103,11 @@ class TypeResolutionEnvironmentTest extends Specification { GraphQLObjectType getType(TypeResolutionEnvironment env) { String source = env.getObject() assert source == "source" - if ("FooBar" == env.getContext()) { + assert env.getGraphQLContext().get("a") == "b" + if ("FooBar" == env.getContext()) { // Retain for test coverage return schema.getObjectType("FooBar") } - if ("Foo" == env.getContext()) { + if ("Foo" == env.getContext()) { // Retain for test coverage return schema.getObjectType("FooImpl") } return null @@ -91,14 +115,32 @@ class TypeResolutionEnvironmentTest extends Specification { } when: - def environmentFooBar = new TypeResolutionEnvironment("source", [:], new Field("field"), Scalars.GraphQLString, schema, "FooBar") + def environmentFooBar = TypeResolutionParameters.newParameters() + .value("source") + .argumentValues(() -> [:]) + .field(mergedField(new Field("field"))) + .fieldType(interfaceType) + .schema(schema) + .context("FooBar") // Retain for test coverage + .graphQLContext(graphqlContext) + .build() + def objTypeFooBar = resolverWithContext.getType(environmentFooBar) then: objTypeFooBar.name == "FooBar" when: - def environmentFooImpl = new TypeResolutionEnvironment("source", [:], new Field("field"), Scalars.GraphQLString, schema, "Foo") + def environmentFooImpl = TypeResolutionParameters.newParameters() + .value("source") + .argumentValues(() -> [:]) + .field(mergedField(new Field("field"))) + .fieldType(interfaceType) + .schema(schema) + .context("Foo") // Retain for test coverage + .graphQLContext(graphqlContext) + .build() + def objTypeFooImpl = resolverWithContext.getType(environmentFooImpl) then: diff --git a/src/test/groovy/graphql/TypeResolverExecutionTest.groovy b/src/test/groovy/graphql/TypeResolverExecutionTest.groovy index 51dee8c6dc..b19cf59a15 100644 --- a/src/test/groovy/graphql/TypeResolverExecutionTest.groovy +++ b/src/test/groovy/graphql/TypeResolverExecutionTest.groovy @@ -1,5 +1,6 @@ package graphql +import graphql.execution.DataFetcherResult import graphql.schema.DataFetcher import graphql.schema.GraphQLInterfaceType import graphql.schema.GraphQLObjectType @@ -13,7 +14,9 @@ import graphql.schema.idl.WiringFactory import spock.lang.Specification import static graphql.Assert.assertShouldNeverHappen -import static graphql.execution.ExecutionTypeInfo.unwrapBaseType +import static graphql.ExecutionInput.newExecutionInput +import static graphql.schema.GraphQLTypeUtil.unwrapAll +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring class TypeResolverExecutionTest extends Specification { @@ -77,8 +80,8 @@ class TypeResolverExecutionTest extends Specification { @Override boolean providesDataFetcher(FieldWiringEnvironment environment) { - if (unwrapBaseType(environment.fieldType) instanceof GraphQLInterfaceType || - unwrapBaseType(environment.fieldType) instanceof GraphQLUnionType) { + if (unwrapAll(environment.fieldType) instanceof GraphQLInterfaceType || + unwrapAll(environment.fieldType) instanceof GraphQLUnionType) { return true } return false @@ -86,9 +89,9 @@ class TypeResolverExecutionTest extends Specification { @Override DataFetcher getDataFetcher(FieldWiringEnvironment environment) { - if (unwrapBaseType(environment.fieldType) instanceof GraphQLInterfaceType) { + if (unwrapAll(environment.fieldType) instanceof GraphQLInterfaceType) { return { [id: 'confOne', topic: 'Front-End technologies'] } - } else if (unwrapBaseType(environment.fieldType) instanceof GraphQLUnionType) { + } else if (unwrapAll(environment.fieldType) instanceof GraphQLUnionType) { return { [id: 'getLucky', name: 'Daft Punk Anniversary'] } } assertShouldNeverHappen() @@ -118,8 +121,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(simpleTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -167,8 +169,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(aberrantTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -213,8 +214,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(aberrantTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -257,8 +257,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(nullTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -301,8 +300,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(nullTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -345,8 +343,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(aberrantTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -389,8 +386,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(aberrantTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -430,8 +426,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(nullTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -471,8 +466,7 @@ class TypeResolverExecutionTest extends Specification { def runTimeWiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(new SimpleTestWiringFactory(nullTypeResolver)) - def schema = TestUtil.schema(idl, runTimeWiring) - def graphql = new GraphQL(schema) + def graphql = TestUtil.graphQL(idl, runTimeWiring).build() when: def res = graphql.execute(''' @@ -489,4 +483,178 @@ class TypeResolverExecutionTest extends Specification { res.data == null res.errors[0] instanceof UnresolvedTypeError } + + def "can get access to field selection set during type resolution"() { + def sdl = ''' + + type Query { + foo : BarInterface + } + + interface BarInterface { + name : String + } + + type NewBar implements BarInterface { + name : String + newBarOnlyField : String + } + + type OldBar implements BarInterface { + name : String + oldBarOnlyField : String + } + ''' + + TypeResolver typeResolver = new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + boolean askedForOldBar = !env.getSelectionSet().getFields("oldBarOnlyField").isEmpty() + if (askedForOldBar) { + return env.getSchema().getObjectType("OldBar") + } + return env.getSchema().getObjectType("NewBar") + } + } + + + def wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("foo", { env -> [name: "NAME"] })) + .type(newTypeWiring("BarInterface") + .typeResolver(typeResolver)) + .build() + + + def graphQL = TestUtil.graphQL(sdl, wiring).build() + + when: + def query = ''' + query { + foo { + __typename + ...OldBarFragment + ...NewBarFragment + } + } + + fragment OldBarFragment on OldBar { + name + oldBarOnlyField + } + + fragment NewBarFragment on NewBar { + name + newBarOnlyField + } + ''' + + def er = graphQL.execute(query) + + then: + er.errors.isEmpty() + er.data == ["foo": [ + "__typename" : "OldBar", + "name" : "NAME", + "oldBarOnlyField": null, + ]] + + + when: + query = ''' + query { + foo { + __typename + ...NewBarFragment + } + } + + fragment NewBarFragment on NewBar { + name + } + ''' + + er = graphQL.execute(query) + + then: + er.errors.isEmpty() + er.data == ["foo": [ + "__typename": "NewBar", + "name" : "NAME", + ]] + } + + def "can get access to attributes in the type resolver"() { + def sdl = ''' + + type Query { + foo : BarInterface + } + + interface BarInterface { + name : String + } + + type NewBar implements BarInterface { + name : String + newBarOnlyField : String + } + + type OldBar implements BarInterface { + name : String + oldBarOnlyField : String + } + ''' + + + TypeResolver typeResolver = new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + assert env.getField().getName() == "foo" + assert env.getFieldType() == env.getSchema().getType("BarInterface") + assert env.getGraphQLContext().get("x") == "graphqlContext" + assert env.getLocalContext() == "LocalContext" + return env.getSchema().getObjectType("NewBar") + } + } + + def df = { env -> + DataFetcherResult.newResult().data([name: "NAME"]).localContext("LocalContext").build() + } + def wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("foo", df)) + .type(newTypeWiring("BarInterface") + .typeResolver(typeResolver)) + .build() + + + def graphQL = TestUtil.graphQL(sdl, wiring).build() + + def query = ''' + query { + foo { + __typename + ...NewBarFragment + } + } + + fragment NewBarFragment on NewBar { + name + } + ''' + + when: + def ei = newExecutionInput(query) + .graphQLContext(["x" : "graphqlContext"]) + .build() + def er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == ["foo": [ + "__typename": "NewBar", + "name" : "NAME", + ]] + } } diff --git a/src/test/groovy/graphql/UnionTest.groovy b/src/test/groovy/graphql/UnionTest.groovy index bf6b757047..8edd7b2600 100644 --- a/src/test/groovy/graphql/UnionTest.groovy +++ b/src/test/groovy/graphql/UnionTest.groovy @@ -4,8 +4,7 @@ import spock.lang.Specification class UnionTest extends Specification { - - def "can introspect on union and intersection types"() { + def "can introspect on union types"() { def query = """ { Named: __type(name: "Named") { @@ -16,15 +15,6 @@ class UnionTest extends Specification { possibleTypes { name } enumValues { name } inputFields { name } - } - Pet: __type(name: "Pet") { - kind - name - fields { name } - interfaces { name } - possibleTypes { name } - enumValues { name } - inputFields { name } } } """ @@ -35,16 +25,40 @@ class UnionTest extends Specification { fields : [ [name: 'name'] ], - interfaces : null, + interfaces : [], possibleTypes: [ - [name: 'Person'], [name: 'Cat'], - [name: 'Dog'] + [name: 'Dog'], + [name: 'Person'], ], enumValues : null, inputFields : null - ], - Pet : [ + ]] + when: + def executionResult = GraphQL.newGraphQL(GarfieldSchema.GarfieldSchema).build().execute(query) + + then: + executionResult.data == expectedResult + + + } + + def "can introspect on intersection types"() { + def query = """ + { + Pet: __type(name: "Pet") { + kind + name + fields { name } + interfaces { name } + possibleTypes { name } + enumValues { name } + inputFields { name } + } + } + """ + + def expectedResult = [Pet : [ kind : 'UNION', name : 'Pet', fields : null, @@ -96,7 +110,8 @@ class UnionTest extends Specification { ] when: - def executionResult = GraphQL.newGraphQL(GarfieldSchema.GarfieldSchema).build().execute(query, GarfieldSchema.john) + def ei = ExecutionInput.newExecutionInput(query).root(GarfieldSchema.john).build() + def executionResult = GraphQL.newGraphQL(GarfieldSchema.GarfieldSchema).build().execute(ei) then: executionResult.data == expectedResult @@ -148,7 +163,8 @@ class UnionTest extends Specification { ] ] when: - def executionResult = GraphQL.newGraphQL(GarfieldSchema.GarfieldSchema).build().execute(query, GarfieldSchema.john) + def ei = ExecutionInput.newExecutionInput(query).root(GarfieldSchema.john).build() + def executionResult = GraphQL.newGraphQL(GarfieldSchema.GarfieldSchema).build().execute(ei) then: executionResult.data == expectedResult diff --git a/src/test/groovy/graphql/analysis/MaxQueryComplexityInstrumentationTest.groovy b/src/test/groovy/graphql/analysis/MaxQueryComplexityInstrumentationTest.groovy index 49904abc2d..798b9e5512 100644 --- a/src/test/groovy/graphql/analysis/MaxQueryComplexityInstrumentationTest.groovy +++ b/src/test/groovy/graphql/analysis/MaxQueryComplexityInstrumentationTest.groovy @@ -3,14 +3,19 @@ package graphql.analysis import graphql.ExecutionInput import graphql.TestUtil import graphql.execution.AbortExecutionException -import graphql.execution.instrumentation.InstrumentationContext +import graphql.execution.ExecutionContext +import graphql.execution.ExecutionContextBuilder +import graphql.execution.ExecutionId +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters import graphql.language.Document import graphql.parser.Parser -import graphql.validation.ValidationError -import graphql.validation.ValidationErrorType +import graphql.schema.GraphQLSchema import spock.lang.Specification +import java.util.function.Function + class MaxQueryComplexityInstrumentationTest extends Specification { Document createQuery(String query) { @@ -18,63 +23,58 @@ class MaxQueryComplexityInstrumentationTest extends Specification { parser.parseDocument(query) } - def "doesn't do anything if validation errors occur"() { + + def "default complexity calculator"() { given: def schema = TestUtil.schema(""" type Query{ + foo: Foo bar: String } + type Foo { + scalar: String + foo: Foo + } """) def query = createQuery(""" - { bar { thisIsWrong } } + {f2: foo {scalar foo{scalar}} f1: foo { foo {foo {foo {foo{foo{scalar}}}}}} } """) - def queryTraversal = Mock(QueryTraversal) - MaxQueryComplexityInstrumentation maxQueryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(6) { - - @Override - QueryTraversal newQueryTraversal(InstrumentationValidationParameters parameters) { - return queryTraversal - } - } + MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(10) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = maxQueryComplexityInstrumentation.beginValidation(validationParameters) + def state = createInstrumentationState(queryComplexityInstrumentation) + InstrumentationExecuteOperationParameters executeOperationParameters = createExecuteOperationParameters(queryComplexityInstrumentation, executionInput, query, schema, state) when: - instrumentationContext.onCompleted([new ValidationError(ValidationErrorType.SubSelectionNotAllowed)], null) + queryComplexityInstrumentation.beginExecuteOperation(executeOperationParameters, state) then: - 0 * queryTraversal._(_) + def e = thrown(AbortExecutionException) + e.message == "maximum query complexity exceeded 11 > 10" } - def "doesn't do anything if exception was thrown"() { + + def "complexity calculator works with __typename field with score 0"() { given: def schema = TestUtil.schema(""" type Query{ - bar: String + foo: String } """) def query = createQuery(""" - { bar { thisIsWrong } } + { f1: foo f2: foo __typename } """) - def queryTraversal = Mock(QueryTraversal) - MaxQueryComplexityInstrumentation maxQueryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(6) { - - @Override - QueryTraversal newQueryTraversal(InstrumentationValidationParameters parameters) { - return queryTraversal - } - } + MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(1) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = maxQueryComplexityInstrumentation.beginValidation(validationParameters) + def state = createInstrumentationState(queryComplexityInstrumentation) + InstrumentationExecuteOperationParameters executeOperationParameters = createExecuteOperationParameters(queryComplexityInstrumentation, executionInput, query, schema, state) when: - instrumentationContext.onCompleted(null, new RuntimeException()) + queryComplexityInstrumentation.beginExecuteOperation(executeOperationParameters, state) then: - 0 * queryTraversal._(_) + def e = thrown(AbortExecutionException) + e.message == "maximum query complexity exceeded 2 > 1" } - def "default complexity calculator"() { + def "custom calculator"() { given: def schema = TestUtil.schema(""" type Query{ @@ -87,21 +87,25 @@ class MaxQueryComplexityInstrumentationTest extends Specification { } """) def query = createQuery(""" - {f2: foo {scalar foo{scalar}} f1: foo { foo {foo {foo {foo{foo{scalar}}}}}} } + {foo {scalar }} """) - MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(10) + def calculator = Mock(FieldComplexityCalculator) + MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(5, calculator) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = queryComplexityInstrumentation.beginValidation(validationParameters) + def state = createInstrumentationState(queryComplexityInstrumentation) + InstrumentationExecuteOperationParameters executeOperationParameters = createExecuteOperationParameters(queryComplexityInstrumentation, executionInput, query, schema, state) when: - instrumentationContext.onCompleted(null, null) + queryComplexityInstrumentation.beginExecuteOperation(executeOperationParameters, state) + then: + 1 * calculator.calculate({ FieldComplexityEnvironment env -> env.field.name == "scalar" }, 0) >> 10 + 1 * calculator.calculate({ FieldComplexityEnvironment env -> env.field.name == "foo" }, 10) >> 20 def e = thrown(AbortExecutionException) - e.message == "maximum query complexity exceeded 11 > 10" + e.message == "maximum query complexity exceeded 20 > 5" } - def "custom calculator"() { + def "custom max query complexity exceeded function"() { given: def schema = TestUtil.schema(""" type Query{ @@ -114,24 +118,72 @@ class MaxQueryComplexityInstrumentationTest extends Specification { } """) def query = createQuery(""" - {foo {scalar }} + {f2: foo {scalar foo{scalar}} f1: foo { foo {foo {foo {foo{foo{scalar}}}}}} } """) - def calculator = Mock(FieldComplexityCalculator) - MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(5, calculator) + Boolean customFunctionCalled = false + Function maxQueryComplexityExceededFunction = new Function() { + @Override + Boolean apply(final QueryComplexityInfo queryComplexityInfo) { + assert queryComplexityInfo.instrumentationExecuteOperationParameters != null + assert queryComplexityInfo.instrumentationValidationParameters != null + customFunctionCalled = true + return false + } + } + MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(10, maxQueryComplexityExceededFunction) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = queryComplexityInstrumentation.beginValidation(validationParameters) + def state = createInstrumentationState(queryComplexityInstrumentation) + InstrumentationExecuteOperationParameters executeOperationParameters = createExecuteOperationParameters(queryComplexityInstrumentation, executionInput, query, schema, state) when: - instrumentationContext.onCompleted(null, null) + queryComplexityInstrumentation.beginExecuteOperation(executeOperationParameters, state) + then: + customFunctionCalled + notThrown(Exception) + } + def "complexity with default query variables"() { + given: + def schema = TestUtil.schema(""" + type Query{ + hello(name: String): String + } + """) + def query = createQuery(""" + query Hello(\$name:String = "Someone") { + hello(name: \$name) + } + """) + + MaxQueryComplexityInstrumentation queryComplexityInstrumentation = new MaxQueryComplexityInstrumentation(0) + ExecutionInput executionInput = Mock(ExecutionInput) + def state = createInstrumentationState(queryComplexityInstrumentation) + InstrumentationExecuteOperationParameters executeOperationParameters = createExecuteOperationParameters(queryComplexityInstrumentation, executionInput, query, schema, state) + when: + queryComplexityInstrumentation.beginExecuteOperation(executeOperationParameters, state) then: - 1 * calculator.calculate({ FieldComplexityEnvironment env -> env.field.name == "scalar" }, 0) >> 10 - 1 * calculator.calculate({ FieldComplexityEnvironment env -> env.field.name == "foo" }, 10) >> 20 def e = thrown(AbortExecutionException) - e.message == "maximum query complexity exceeded 20 > 5" + e.message == "maximum query complexity exceeded 1 > 0" + } + private InstrumentationExecuteOperationParameters createExecuteOperationParameters(MaxQueryComplexityInstrumentation queryComplexityInstrumentation, ExecutionInput executionInput, Document query, GraphQLSchema schema, InstrumentationState state) { + // we need to run N steps to create instrumentation state + def validationParameters = new InstrumentationValidationParameters(executionInput, query, schema) + queryComplexityInstrumentation.beginValidation(validationParameters, state) + def executionContext = executionCtx(executionInput, query, schema) + def executeOperationParameters = new InstrumentationExecuteOperationParameters(executionContext) + executeOperationParameters } + def createInstrumentationState(MaxQueryComplexityInstrumentation queryComplexityInstrumentation) { + queryComplexityInstrumentation.createStateAsync(null).join() + } + + + private ExecutionContext executionCtx(ExecutionInput executionInput, Document query, GraphQLSchema schema) { + ExecutionContextBuilder.newExecutionContextBuilder() + .executionInput(executionInput).document(query).graphQLSchema(schema).executionId(ExecutionId.generate()) + .build() + } } diff --git a/src/test/groovy/graphql/analysis/MaxQueryDepthInstrumentationTest.groovy b/src/test/groovy/graphql/analysis/MaxQueryDepthInstrumentationTest.groovy index d019b2deba..acc1a08983 100644 --- a/src/test/groovy/graphql/analysis/MaxQueryDepthInstrumentationTest.groovy +++ b/src/test/groovy/graphql/analysis/MaxQueryDepthInstrumentationTest.groovy @@ -1,81 +1,80 @@ package graphql.analysis import graphql.ExecutionInput +import graphql.GraphQL import graphql.TestUtil import graphql.execution.AbortExecutionException -import graphql.execution.instrumentation.InstrumentationContext -import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters +import graphql.execution.ExecutionContext +import graphql.execution.ExecutionContextBuilder +import graphql.execution.ExecutionId +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters import graphql.language.Document import graphql.parser.Parser -import graphql.validation.ValidationError -import graphql.validation.ValidationErrorType +import graphql.schema.GraphQLSchema import spock.lang.Specification +import java.util.function.Function + class MaxQueryDepthInstrumentationTest extends Specification { - Document createQuery(String query) { + static Document createQuery(String query) { Parser parser = new Parser() parser.parseDocument(query) } - - def "doesn't do anything if validation errors occur"() { + def "throws exception if too deep"() { given: def schema = TestUtil.schema(""" type Query{ + foo: Foo bar: String } + type Foo { + scalar: String + foo: Foo + } """) def query = createQuery(""" - { bar { thisIsWrong } } + {f1: foo {foo {foo {scalar}}} f2: foo { foo {foo {foo {foo{foo{scalar}}}}}} } """) - def queryTraversal = Mock(QueryTraversal) - MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(6) { - - @Override - QueryTraversal newQueryTraversal(InstrumentationValidationParameters parameters) { - return queryTraversal - } - } + MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(6) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = maximumQueryDepthInstrumentation.beginValidation(validationParameters) + def executionContext = executionCtx(executionInput, query, schema) + def executeOperationParameters = new InstrumentationExecuteOperationParameters(executionContext) when: - instrumentationContext.onCompleted([new ValidationError(ValidationErrorType.SubSelectionNotAllowed)], null) + maximumQueryDepthInstrumentation.beginExecuteOperation(executeOperationParameters, null) then: - 0 * queryTraversal._(_) - + def e = thrown(AbortExecutionException) + e.message.contains("maximum query depth exceeded 7 > 6") } - def "doesn't do anything if exception was thrown"() { + def "doesn't throw exception if not deep enough"() { given: def schema = TestUtil.schema(""" type Query{ + foo: Foo bar: String } + type Foo { + scalar: String + foo: Foo + } """) def query = createQuery(""" - { bar { thisIsWrong } } + {f1: foo {foo {foo {scalar}}} f2: foo { foo {foo {foo {foo{foo{scalar}}}}}} } """) - def queryTraversal = Mock(QueryTraversal) - MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(6) { - - @Override - QueryTraversal newQueryTraversal(InstrumentationValidationParameters parameters) { - return queryTraversal - } - } + MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(7) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = maximumQueryDepthInstrumentation.beginValidation(validationParameters) + def executionContext = executionCtx(executionInput, query, schema) + def executeOperationParameters = new InstrumentationExecuteOperationParameters(executionContext) + def state = null // it has not state in implementation when: - instrumentationContext.onCompleted(null, new RuntimeException()) + maximumQueryDepthInstrumentation.beginExecuteOperation(executeOperationParameters, state) then: - 0 * queryTraversal._(_) - + notThrown(Exception) } - def "throws exception"() { + def "doesn't throw exception if not deep enough with deprecated beginExecuteOperation"() { given: def schema = TestUtil.schema(""" type Query{ @@ -90,18 +89,17 @@ class MaxQueryDepthInstrumentationTest extends Specification { def query = createQuery(""" {f1: foo {foo {foo {scalar}}} f2: foo { foo {foo {foo {foo{foo{scalar}}}}}} } """) - MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(6) + MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(7) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = maximumQueryDepthInstrumentation.beginValidation(validationParameters) + def executionContext = executionCtx(executionInput, query, schema) + def executeOperationParameters = new InstrumentationExecuteOperationParameters(executionContext) when: - instrumentationContext.onCompleted(null, null) + maximumQueryDepthInstrumentation.beginExecuteOperation(executeOperationParameters, null) // Retain for test coverage then: - def e = thrown(AbortExecutionException) - e.message.contains("maximum query depth exceeded 7 > 6") + notThrown(Exception) } - def "doesn't throw exception"() { + def "custom max query depth exceeded function"() { given: def schema = TestUtil.schema(""" type Query{ @@ -116,13 +114,52 @@ class MaxQueryDepthInstrumentationTest extends Specification { def query = createQuery(""" {f1: foo {foo {foo {scalar}}} f2: foo { foo {foo {foo {foo{foo{scalar}}}}}} } """) - MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(7) + Boolean calledFunction = false + Function maxQueryDepthExceededFunction = new Function() { + @Override + Boolean apply(final QueryDepthInfo queryDepthInfo) { + calledFunction = true + return false + } + } + MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(6, maxQueryDepthExceededFunction) ExecutionInput executionInput = Mock(ExecutionInput) - InstrumentationValidationParameters validationParameters = new InstrumentationValidationParameters(executionInput, query, schema, null) - InstrumentationContext instrumentationContext = maximumQueryDepthInstrumentation.beginValidation(validationParameters) + def executionContext = executionCtx(executionInput, query, schema) + def executeOperationParameters = new InstrumentationExecuteOperationParameters(executionContext) when: - instrumentationContext.onCompleted(null, null) + maximumQueryDepthInstrumentation.beginExecuteOperation(executeOperationParameters, null) then: + calledFunction notThrown(Exception) } + + def "coercing null variables that are marked as non nullable wont blow up early"() { + + given: + def schema = TestUtil.schema(""" + type Query { + field(arg : String!) : String + } + """) + + MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(6) + def graphQL = GraphQL.newGraphQL(schema).instrumentation(maximumQueryDepthInstrumentation).build() + + when: + def query = ''' + query x($var : String!) { + field(arg : $var) + } + ''' + def executionInput = ExecutionInput.newExecutionInput(query).variables(["var": null]).build() + def er = graphQL.execute(executionInput) + + then: + !er.errors.isEmpty() + } + + static private ExecutionContext executionCtx(ExecutionInput executionInput, Document query, GraphQLSchema schema) { + ExecutionContextBuilder.newExecutionContextBuilder() + .executionInput(executionInput).document(query).graphQLSchema(schema).executionId(ExecutionId.generate()).build() + } } diff --git a/src/test/groovy/graphql/analysis/QueryComplexityCalculatorTest.groovy b/src/test/groovy/graphql/analysis/QueryComplexityCalculatorTest.groovy new file mode 100644 index 0000000000..465c4de598 --- /dev/null +++ b/src/test/groovy/graphql/analysis/QueryComplexityCalculatorTest.groovy @@ -0,0 +1,52 @@ +package graphql.analysis + + +import graphql.TestUtil +import graphql.execution.CoercedVariables +import graphql.language.Document +import graphql.parser.Parser +import spock.lang.Specification + +class QueryComplexityCalculatorTest extends Specification { + + Document createQuery(String query) { + Parser parser = new Parser() + parser.parseDocument(query) + } + + def "can calculator complexity"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + scalar: String + foo: Foo + } + """) + def query = createQuery(""" + query q { + f2: foo {scalar foo{scalar}} + f1: foo { foo {foo {foo {foo{foo{scalar}}}}}} } + """) + + + when: + FieldComplexityCalculator fieldComplexityCalculator = new FieldComplexityCalculator() { + @Override + int calculate(FieldComplexityEnvironment environment, int childComplexity) { + return environment.getField().name.startsWith("foo") ? 10 : 1 + } + } + QueryComplexityCalculator calculator = QueryComplexityCalculator.newCalculator() + .fieldComplexityCalculator(fieldComplexityCalculator).schema(schema).document(query).variables(CoercedVariables.emptyVariables()) + .build() + def complexityScore = calculator.calculate() + then: + complexityScore == 20 + + + } +} diff --git a/src/test/groovy/graphql/analysis/QueryTransformerTest.groovy b/src/test/groovy/graphql/analysis/QueryTransformerTest.groovy new file mode 100644 index 0000000000..2ce312c7ce --- /dev/null +++ b/src/test/groovy/graphql/analysis/QueryTransformerTest.groovy @@ -0,0 +1,508 @@ +package graphql.analysis + +import graphql.TestUtil +import graphql.execution.CoercedVariables +import graphql.language.Document +import graphql.language.Field +import graphql.language.NodeUtil +import graphql.language.OperationDefinition +import graphql.language.TypeName +import graphql.parser.Parser +import graphql.schema.GraphQLFieldsContainer +import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLUnionType +import graphql.util.TraversalControl +import spock.lang.Specification + +import static graphql.language.AstPrinter.printAstCompact +import static graphql.language.Field.newField +import static graphql.util.TreeTransformerUtil.changeNode +import static graphql.util.TreeTransformerUtil.deleteNode +import static graphql.util.TreeTransformerUtil.insertAfter + +class QueryTransformerTest extends Specification { + Document createQuery(String query) { + Parser parser = new Parser() + parser.parseDocument(query) + } + + QueryTransformer createQueryTransformer(Document document, GraphQLSchema schema, Map variables = [:]) { + def fragments = NodeUtil.getFragmentsByName(document) + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(schema) + .fragmentsByName(fragments) + .root(document) + .variables(variables) + .rootParentType(schema.getQueryType()) + .build() + return queryTransformer + } + + def transfSchema = TestUtil.schema(""" + type Query { + root: Root + } + type Root { + fooA: Foo + fooB: Foo + } + type Foo { + midA: MidA + midB: MidB + } + + type MidA { + leafA: String + } + type MidB { + leafB: String + } + """) + + def "transform query rename query fields based on type information "() { + def query = TestUtil.parseQuery("{ root { fooA { midA { leafA } midB { leafB } } fooB { midA { leafA } midB { leafB } } } }") + + QueryTransformer queryTransformer = createQueryTransformer(query, transfSchema) + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.fieldDefinition.type.name == "MidA") { + String newName = env.field.name + "-modified" + + Field changedField = env.field.transform({ builder -> builder.name(newName) }) + changeNode(env.getTraverserContext(), changedField) + } + } + } + + when: + def newDocument = queryTransformer.transform(visitor) + + then: + printAstCompact(newDocument) == + "{root{fooA{midA-modified{leafA}midB{leafB}}fooB{midA-modified{leafA}midB{leafB}}}}" + } + + def "transform query delete midA nodes"() { + def query = TestUtil.parseQuery("{ root { fooA { midA { leafA } midB { leafB } } fooB { midA { leafA } midB { leafB } } } }") + + QueryTransformer queryTransformer = createQueryTransformer(query, transfSchema) + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.fieldDefinition.type.name == "MidA") { + deleteNode(env.getTraverserContext()) + } + } + } + + when: + def newDocument = queryTransformer.transform(visitor) + + then: + printAstCompact(newDocument) == + "{root{fooA{midB{leafB}}fooB{midB{leafB}}}}" + } + + def "transform query add midA sibling"() { + def query = TestUtil.parseQuery("{ root { fooA { midA { leafA } } } }") + + QueryTransformer queryTransformer = createQueryTransformer(query, transfSchema) + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.fieldDefinition.type.name == "MidA") { + insertAfter(env.getTraverserContext(), newField("addedField").build()) + } + } + } + + when: + def newDocument = queryTransformer.transform(visitor) + + then: + printAstCompact(newDocument) == + "{root{fooA{midA{leafA}addedField}}}" + } + + def "transform query delete fragment spread and inline fragment"() { + def query = TestUtil.parseQuery(''' + { + root { + fooA { + ...frag + midB { leafB } + } + + fooB { + ...{ + midA { leafA } + } + midB { leafB } + } + } + } + fragment frag on Foo { + midA {leafA} + } + ''') + + QueryTransformer queryTransformer = createQueryTransformer(query, transfSchema) + + def visitor = new QueryVisitorStub() { + @Override + void visitInlineFragment(QueryVisitorInlineFragmentEnvironment env) { + deleteNode(env.getTraverserContext()) + } + + @Override + void visitFragmentSpread(QueryVisitorFragmentSpreadEnvironment env) { + if (env.getFragmentDefinition().getName() == "frag") { + deleteNode(env.getTraverserContext()) + } + } + } + + when: + def newDocument = queryTransformer.transform(visitor) + then: + + printAstCompact(newDocument) == + "{root{fooA{midB{leafB}}fooB{midB{leafB}}}} fragment frag on Foo {midA{leafA}}" + } + + def "transform query does not traverse named fragments when started from query"() { + def query = TestUtil.parseQuery(''' + { + root { + ...frag + } + } + fragment frag on Root { + fooA{ midA {leafA}} + } + ''') + + def operationDefinition = NodeUtil.getOperation(query, null).operationDefinition + def fragments = NodeUtil.getFragmentsByName(query) + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(transfSchema) + .fragmentsByName(fragments) + .root(operationDefinition) + .variables([:]) + .rootParentType(transfSchema.getQueryType()) + .build() + + def visitor = Mock(QueryVisitor) + + + when: + queryTransformer.transform(visitor) + then: + 1 * visitor.visitFieldWithControl({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "root" && it.fieldDefinition.type.name == "Root" && it.parentType.name == "Query" }) >> TraversalControl.CONTINUE + 1 * visitor.visitFragmentSpread({ QueryVisitorFragmentSpreadEnvironment it -> it.fragmentSpread.name == "frag" }) + 0 * _ + } + + def "fragment definition is traversed if it is a root and can be transformed"() { + def query = TestUtil.parseQuery(''' + { + root { + ...frag + } + } + fragment frag on Root { + fooA{ midA {leafA}} + } + ''') + def fragments = NodeUtil.getFragmentsByName(query) + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(transfSchema) + .root(fragments["frag"]) + .rootParentType(transfSchema.getQueryType()) + .fragmentsByName(fragments) + .variables([:]) + .build() + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.field.name == "leafA") { + deleteNode(env.traverserContext) + } + if (env.fieldDefinition.type.name == "String") { + insertAfter(env.traverserContext, newField("newChild1").build()) + insertAfter(env.traverserContext, newField("newChild2").build()) + } + } + + @Override + void visitFragmentDefinition(QueryVisitorFragmentDefinitionEnvironment env) { + def changed = env.fragmentDefinition.transform({ builder -> + builder.typeCondition(TypeName.newTypeName("newTypeName").build()) + .name("newFragName") + }) + changeNode(env.traverserContext, changed) + } + } + + + when: + def newFragment = queryTransformer.transform(visitor) + then: + printAstCompact(newFragment) == + "fragment newFragName on newTypeName {fooA{midA{newChild1 newChild2}}}" + } + + def "transform starting in a interface field"() { + def schema = TestUtil.schema(""" + type Query { + root: SomeInterface + } + interface SomeInterface { + field1: String + field2: String + } + """) + def query = TestUtil.parseQuery(''' + { + root { + field1 + field2 + } + } + ''') + def rootField = (query.children[0] as OperationDefinition).selectionSet.selections[0] as Field + def field1 = rootField.selectionSet.selections[0] as Field + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(schema) + .root(field1) + .rootParentType(schema.getType("SomeInterface") as GraphQLFieldsContainer) + .fragmentsByName([:]) + .variables([:]) + .build() + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.field.name == "field1") { + changeNode(env.traverserContext, env.field.transform({ builder -> builder.name("field1X") })) + } + } + } + + + when: + def newNode = queryTransformer.transform(visitor) + then: + printAstCompact(newNode) == "field1X" + + } + + def "transform starting in a union field"() { + def schema = TestUtil.schema(""" + type Query { + root: SomeUnion + } + union SomeUnion = A | B + type A { + a: String + } + type B { + b: String + } + """) + def query = TestUtil.parseQuery(''' + { + root { + __typename + ... on A { + a + } + ... on B { + b + } + } + } + ''') + def rootField = (query.children[0] as OperationDefinition).selectionSet.selections[0] as Field + def typeNameField = rootField.selectionSet.selections[0] as Field + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(schema) + .root(typeNameField) + .rootParentType(schema.getType("SomeUnion") as GraphQLUnionType) + .fragmentsByName([:]) + .variables([:]) + .build() + + boolean visitedTypeNameField + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + visitedTypeNameField = env.isTypeNameIntrospectionField() + } + } + + + when: + queryTransformer.transform(visitor) + then: + visitedTypeNameField + + } + + def "transform starting in a selectionSet node belonging to an interface"() { + def schema = TestUtil.schema(""" + type Query { + root: SomeInterface + } + interface SomeInterface { + field1: String + field2: String + } + """) + def query = TestUtil.parseQuery(''' + { + root { + field1 + field2 + } + } + ''') + def rootField = (query.children[0] as OperationDefinition).selectionSet.selections[0] as Field + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(schema) + .root(rootField.getSelectionSet()) + .rootParentType(schema.getType("SomeInterface") as GraphQLFieldsContainer) + .fragmentsByName([:]) + .variables([:]) + .build() + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.field.name == "field1") { + changeNode(env.traverserContext, env.field.transform({ builder -> builder.name("field1X") })) + } + } + } + + + when: + def newNode = queryTransformer.transform(visitor) + then: + printAstCompact(newNode) == "{field1X field2}" + + } + + def "transform starting in a selectionSet node belonging to an union"() { + def schema = TestUtil.schema(""" + type Query { + root: SomeUnion + } + union SomeUnion = A | B + type A { + a: String + } + type B { + b: String + } + """) + def query = TestUtil.parseQuery(''' + { + root { + __typename + ... on A { + a + } + ... on B { + b + } + } + } + ''') + def rootField = (query.children[0] as OperationDefinition).selectionSet.selections[0] as Field + QueryTransformer queryTransformer = QueryTransformer.newQueryTransformer() + .schema(schema) + .root(rootField.getSelectionSet()) + .rootParentType(schema.getType("SomeUnion") as GraphQLFieldsContainer) + .fragmentsByName([:]) + .variables([:]) + .build() + + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment env) { + if (env.field.name == "a") { + changeNode(env.traverserContext, env.field.transform({ builder -> builder.name("aX") })) + } + } + } + + + when: + def newNode = queryTransformer.transform(visitor) + then: + printAstCompact(newNode) == "{__typename ...on A{aX}...on B{b}}" + + } + + def "can coerce field arguments or not"() { + def sdl = """ + input Test{ x: String!} + type Query{ testInput(input: Test!): String} + type Mutation{ testInput(input: Test!): String} + """ + + def schema = TestUtil.schema(sdl) + + def query = createQuery(''' + mutation a($test: Test!) { + testInput(input: $test) + }''') + + + def fieldArgMap = [:] + def queryVisitorStub = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment) { + super.visitField(queryVisitorFieldEnvironment) + fieldArgMap = queryVisitorFieldEnvironment.getArguments() + } + } + + when: + QueryTraverser.newQueryTraverser() + .schema(schema) + .document(query) + .coercedVariables(CoercedVariables.of([test: [x: "X"]])) + .build() + .visitPreOrder(queryVisitorStub) + + then: + + fieldArgMap == [input: [x:"X"]] + + when: + fieldArgMap = null + + + def options = QueryTraversalOptions.defaultOptions() + .coerceFieldArguments(false) + QueryTraverser.newQueryTraverser() + .schema(schema) + .document(query) + .coercedVariables(CoercedVariables.of([test: [x: "X"]])) + .options(options) + .build() + .visitPreOrder(queryVisitorStub) + + + then: + fieldArgMap == [:] // empty map + } + +} diff --git a/src/test/groovy/graphql/analysis/QueryTraversalOptionsTest.groovy b/src/test/groovy/graphql/analysis/QueryTraversalOptionsTest.groovy new file mode 100644 index 0000000000..379c58e820 --- /dev/null +++ b/src/test/groovy/graphql/analysis/QueryTraversalOptionsTest.groovy @@ -0,0 +1,20 @@ +package graphql.analysis + +import spock.lang.Specification + +class QueryTraversalOptionsTest extends Specification { + + def "defaulting works as expected"() { + when: + def options = QueryTraversalOptions.defaultOptions() + + then: + options.isCoerceFieldArguments() + + when: + options = QueryTraversalOptions.defaultOptions().coerceFieldArguments(false) + + then: + !options.isCoerceFieldArguments() + } +} diff --git a/src/test/groovy/graphql/analysis/QueryTraversalTest.groovy b/src/test/groovy/graphql/analysis/QueryTraverserTest.groovy similarity index 60% rename from src/test/groovy/graphql/analysis/QueryTraversalTest.groovy rename to src/test/groovy/graphql/analysis/QueryTraverserTest.groovy index d9cd42d0a4..dbe0b33384 100644 --- a/src/test/groovy/graphql/analysis/QueryTraversalTest.groovy +++ b/src/test/groovy/graphql/analysis/QueryTraverserTest.groovy @@ -1,23 +1,39 @@ package graphql.analysis +import graphql.AssertException import graphql.TestUtil +import graphql.execution.CoercedVariables +import graphql.language.ArrayValue import graphql.language.Document import graphql.language.Field import graphql.language.FragmentDefinition import graphql.language.FragmentSpread import graphql.language.InlineFragment +import graphql.language.IntValue +import graphql.language.NodeUtil +import graphql.language.ObjectValue +import graphql.language.OperationDefinition +import graphql.language.StringValue import graphql.parser.Parser +import graphql.schema.GraphQLArgument +import graphql.schema.GraphQLInputObjectField +import graphql.schema.GraphQLInterfaceType import graphql.schema.GraphQLNonNull import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLUnionType +import graphql.util.TraversalControl import spock.lang.Specification import spock.lang.Unroll import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.util.TraverserContext.Phase.ENTER +import static graphql.util.TraverserContext.Phase.LEAVE import static java.util.Collections.emptyMap -class QueryTraversalTest extends Specification { +class QueryTraverserTest extends Specification { Document createQuery(String query) { @@ -25,8 +41,8 @@ class QueryTraversalTest extends Specification { parser.parseDocument(query) } - QueryTraversal createQueryTraversal(Document document, GraphQLSchema schema, Map variables = [:]) { - QueryTraversal queryTraversal = QueryTraversal.newQueryTraversal() + QueryTraverser createQueryTraversal(Document document, GraphQLSchema schema, Map variables = [:]) { + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() .schema(schema) .document(document) .variables(variables) @@ -34,6 +50,22 @@ class QueryTraversalTest extends Specification { return queryTraversal } + QueryVisitor mockQueryVisitor() { + def mock = Mock(QueryVisitor) + + mock.visitFieldWithControl(_) >> { params -> + mock.visitField(params) + TraversalControl.CONTINUE + } + mock.visitArgument(_) >> { params -> + TraversalControl.CONTINUE + } + mock.visitArgumentValue(_) >> { params -> + TraversalControl.CONTINUE + } + return mock + } + def "test preOrder order for visitField"() { given: def schema = TestUtil.schema(""" @@ -45,11 +77,11 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {foo { subFoo} bar } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal.visitPreOrder(visitor) @@ -71,6 +103,7 @@ class QueryTraversalTest extends Specification { } + def "test postOrder order for visitField"() { given: def schema = TestUtil.schema(""" @@ -82,11 +115,11 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {foo { subFoo} bar } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal.visitPostOrder(visitor) @@ -103,6 +136,103 @@ class QueryTraversalTest extends Specification { } + def "test for visitArgs and visitArgsValue"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo (complexArg : Complex, simpleArg : String) : Foo + bar: String + } + type Foo { + subFoo: String + } + + input Complex { + name : String + moreComplex : [MoreComplex] + } + + input MoreComplex { + height : Int + weight : Int + } + """) + def visitor = mockQueryVisitor() + def query = createQuery('''{ + foo( complexArg : { name : "Ted", moreComplex : [{height : 100, weight : 200}] } , simpleArg : "Hi" ) { + subFoo + } + bar + }''') + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + when: + queryTraversal.visitPreOrder(visitor) + + then: + + 1 * visitor.visitArgument({ QueryVisitorFieldArgumentEnvironment env -> + env.argument.name == "complexArg" && env.graphQLArgument.type.name == "Complex" + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgument({ QueryVisitorFieldArgumentEnvironment env -> + env.argument.name == "simpleArg" && env.graphQLArgument.type.name == "String" + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgumentValue({ QueryVisitorFieldArgumentValueEnvironment env -> + env.graphQLArgument.name == "complexArg" && + env.argumentInputValue.name == "complexArg" && + env.argumentInputValue.value instanceof ObjectValue + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgumentValue({ QueryVisitorFieldArgumentValueEnvironment env -> + env.graphQLArgument.name == "complexArg" && + env.argumentInputValue.name == "name" && + env.argumentInputValue.value instanceof StringValue + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgumentValue({ QueryVisitorFieldArgumentValueEnvironment env -> + env.graphQLArgument.name == "complexArg" && + env.argumentInputValue.name == "moreComplex" && + env.argumentInputValue.value instanceof ArrayValue + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgumentValue({ QueryVisitorFieldArgumentValueEnvironment env -> + env.graphQLArgument.name == "complexArg" && + env.argumentInputValue.parent.name == "moreComplex" && + env.argumentInputValue.name == "weight" && + env.argumentInputValue.value instanceof IntValue + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgumentValue({ QueryVisitorFieldArgumentValueEnvironment env -> + env.graphQLArgument.name == "complexArg" && + env.argumentInputValue.parent.name == "moreComplex" && + env.argumentInputValue.name == "height" && + env.argumentInputValue.value instanceof IntValue && + env.argumentInputValue.inputValueDefinition instanceof GraphQLInputObjectField + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgumentValue({ QueryVisitorFieldArgumentValueEnvironment env -> + env.graphQLArgument.name == "simpleArg" && + env.argumentInputValue.name == "simpleArg" && + env.argumentInputValue.value instanceof StringValue && + env.argumentInputValue.inputValueDefinition instanceof GraphQLArgument + }) >> TraversalControl.CONTINUE + + + when: + queryTraversal.visitPostOrder(visitor) + + then: + + 1 * visitor.visitArgument({ QueryVisitorFieldArgumentEnvironment env -> + env.argument.name == "complexArg" && env.graphQLArgument.type.name == "Complex" + }) >> TraversalControl.CONTINUE + + 1 * visitor.visitArgument({ QueryVisitorFieldArgumentEnvironment env -> + env.argument.name == "simpleArg" && env.graphQLArgument.type.name == "String" + }) >> TraversalControl.CONTINUE + + } def "test preOrder order for inline fragments"() { given: @@ -115,7 +245,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { ... on Query { @@ -134,7 +264,7 @@ class QueryTraversalTest extends Specification { assert inlineFragmentLeft instanceof InlineFragment def inlineFragmentRight = inlineFragmentRoot.selectionSet.children[1] assert inlineFragmentRight instanceof InlineFragment - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal.visitPreOrder(visitor) @@ -159,7 +289,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { ... on Query @root { @@ -178,7 +308,7 @@ class QueryTraversalTest extends Specification { assert inlineFragmentLeft instanceof InlineFragment def inlineFragmentRight = inlineFragmentRoot.selectionSet.children[1] assert inlineFragmentRight instanceof InlineFragment - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal.visitPostOrder(visitor) @@ -202,7 +332,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { ...F1 @@ -232,7 +362,7 @@ class QueryTraversalTest extends Specification { assert fragmentSpreadLeft instanceof FragmentSpread def fragmentSpreadRight = fragmentF1.selectionSet.children[1] assert fragmentSpreadRight instanceof FragmentSpread - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal.visitPreOrder(visitor) @@ -256,7 +386,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { ...F1 @@ -286,7 +416,7 @@ class QueryTraversalTest extends Specification { assert fragmentSpreadLeft instanceof FragmentSpread def fragmentSpreadRight = fragmentF1.selectionSet.children[1] assert fragmentSpreadRight instanceof FragmentSpread - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal.visitPostOrder(visitor) @@ -299,6 +429,101 @@ class QueryTraversalTest extends Specification { } + + def "test preOrder and postOrder order for fragment definitions and raw variables"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + subFoo: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + { + ...F1 + } + + fragment F1 on Query { + foo { + subFoo + } + } + """) + + def fragments = NodeUtil.getFragmentsByName(query) + + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .root(fragments["F1"]) + .rootParentType(schema.getQueryType()) + .fragmentsByName(fragments) + .variables([:]) + .build() + + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitFragmentDefinition({ QueryVisitorFragmentDefinitionEnvironment env -> env.fragmentDefinition == fragments["F1"] }) + + when: + queryTraversal.visitPostOrder(visitor) + + then: + 1 * visitor.visitFragmentDefinition({ QueryVisitorFragmentDefinitionEnvironment env -> env.fragmentDefinition == fragments["F1"] }) + } + + def "test preOrder and postOrder order for fragment definitions and coerced variables"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + subFoo: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + { + ...F1 + } + + fragment F1 on Query { + foo { + subFoo + } + } + """) + + def fragments = NodeUtil.getFragmentsByName(query) + + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .root(fragments["F1"]) + .rootParentType(schema.getQueryType()) + .fragmentsByName(fragments) + .coercedVariables(CoercedVariables.emptyVariables()) + .build() + + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitFragmentDefinition({ QueryVisitorFragmentDefinitionEnvironment env -> env.fragmentDefinition == fragments["F1"] }) + + when: + queryTraversal.visitPostOrder(visitor) + + then: + 1 * visitor.visitFragmentDefinition({ QueryVisitorFragmentDefinitionEnvironment env -> env.fragmentDefinition == fragments["F1"] }) + } + def "works for mutations()"() { given: def schema = TestUtil.schema(""" @@ -314,11 +539,11 @@ class QueryTraversalTest extends Specification { } schema {mutation: Mutation, query: Query} """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" mutation M{bar foo { subFoo} } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -353,11 +578,11 @@ class QueryTraversalTest extends Specification { } schema {subscription: Subscription, query: Query} """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" subscription S{bar foo { subFoo} } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -385,11 +610,11 @@ class QueryTraversalTest extends Specification { foo(arg1: String, arg2: Boolean): String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" query myQuery(\$myVar: String){foo(arg1: \$myVar, arg2: true)} """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema, ['myVar': 'hello']) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, ['myVar': 'hello']) when: queryTraversal."$visitFn"(visitor) @@ -405,6 +630,62 @@ class QueryTraversalTest extends Specification { 'preOrder' | 'visitPreOrder' } + @Unroll + def "traverse a query when a default variable is a list: (#order)"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo(arg1: [String]): String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + query myQuery(\$myVar: [String] = ["hello default"]) {foo(arg1: \$myVar)} + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, ['myVar': 'hello']) + when: + queryTraversal."$visitFn"(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "foo" && + it.arguments == ['arg1': ['hello']] + }) + + where: + order | visitFn + 'postOrder' | 'visitPostOrder' + 'preOrder' | 'visitPreOrder' + } + + @Unroll + def "traverse a query when a default variable is a list and query does not specify variables: (#order)"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo(arg1: [String]): String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + query myQuery(\$myVar: [String] = ["hello default"]) {foo(arg1: \$myVar)} + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, [:]) + when: + queryTraversal."$visitFn"(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "foo" && + it.arguments == ['arg1': ['hello default']] + }) + + where: + order | visitFn + 'postOrder' | 'visitPostOrder' + 'preOrder' | 'visitPreOrder' + } + @Unroll def "simple query (#order)"() { given: @@ -417,11 +698,11 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {bar foo { subFoo} } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -454,11 +735,11 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {bar foo { subFoo} foo2 { subFoo} foo3 { subFoo}} """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -491,7 +772,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { bar @@ -502,7 +783,7 @@ class QueryTraversalTest extends Specification { } } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) def inlineFragment = query.children[0].children[0].children[1] assert inlineFragment instanceof InlineFragment when: @@ -536,7 +817,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { bar @@ -547,7 +828,7 @@ class QueryTraversalTest extends Specification { } } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -579,7 +860,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { bar @@ -592,7 +873,7 @@ class QueryTraversalTest extends Specification { } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) def fragmentDefinition = query.children[1] assert fragmentDefinition instanceof FragmentDefinition when: @@ -626,7 +907,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { bar @@ -639,7 +920,7 @@ class QueryTraversalTest extends Specification { } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -665,7 +946,7 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" query MyQuery(\$variableFoo: Boolean) { bar @@ -678,7 +959,7 @@ class QueryTraversalTest extends Specification { } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema, [variableFoo: true]) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, [variableFoo: true]) when: queryTraversal."$visitFn"(visitor) @@ -708,7 +989,7 @@ class QueryTraversalTest extends Specification { otherString: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" query MyQuery(\$variableFoo: Boolean) { bar @@ -731,7 +1012,7 @@ class QueryTraversalTest extends Specification { } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema, [variableFoo: true]) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, [variableFoo: true]) when: queryTraversal."$visitFn"(visitor) @@ -770,7 +1051,7 @@ class QueryTraversalTest extends Specification { otherString: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" query MyQuery(\$variableFoo: Boolean) { bar @@ -780,7 +1061,7 @@ class QueryTraversalTest extends Specification { bar } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema, [variableFoo: false]) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, [variableFoo: false]) when: queryTraversal."$visitFn"(visitor) @@ -811,7 +1092,7 @@ class QueryTraversalTest extends Specification { otherString: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" query MyQuery(\$variableFoo: Boolean) { bar @@ -820,7 +1101,7 @@ class QueryTraversalTest extends Specification { } } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema, [variableFoo: false]) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, [variableFoo: false]) when: queryTraversal."$visitFn"(visitor) @@ -851,14 +1132,14 @@ class QueryTraversalTest extends Specification { otherString: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" query MyQuery(\$variableFoo: Boolean) { bar foo @include(if: \$variableFoo) } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema, [variableFoo: false]) + QueryTraverser queryTraversal = createQueryTraversal(query, schema, [variableFoo: false]) when: queryTraversal."$visitFn"(visitor) @@ -888,7 +1169,7 @@ class QueryTraversalTest extends Specification { def query = createQuery(""" {foo { subFoo} bar } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) QueryReducer reducer = Mock(QueryReducer) when: def result = queryTraversal.reducePreOrder(reducer, 1) @@ -918,7 +1199,7 @@ class QueryTraversalTest extends Specification { def query = createQuery(""" {foo { subFoo} bar } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) QueryReducer reducer = Mock(QueryReducer) when: def result = queryTraversal.reducePostOrder(reducer, 1) @@ -951,11 +1232,11 @@ class QueryTraversalTest extends Specification { schema {query: Query} """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {a {id... on Person {name}}} """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -989,11 +1270,11 @@ class QueryTraversalTest extends Specification { schema {query: Query} """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {foo {... on Cat {catName} ... on Dog {dogName}} } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -1035,19 +1316,19 @@ class QueryTraversalTest extends Specification { """) def catOrDog = schema.getType("CatOrDog") def bar = schema.getType("Bar") - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {foo {... on Cat {catName} ... on Dog {dogName}} bar {id}} """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) then: - 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "foo" && it.fieldDefinition.type == list(nonNull(catOrDog)) && it.parentType.name == "Query" }) + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "foo" && list(nonNull(catOrDog)).isEqualTo(it.fieldDefinition.type) && it.parentType.name == "Query" }) 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "catName" && it.fieldDefinition.type.name == "String" && it.parentType.name == "Cat" && it.fieldsContainer.name == "Cat" }) 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "dogName" && it.fieldDefinition.type.name == "String" && it.parentType.name == "Dog" && it.fieldsContainer.name == "Dog" }) - 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "id" && it.fieldDefinition.type.name == "String" && it.parentType == nonNull(list(nonNull(bar))) && it.fieldsContainer.name == "Bar" }) + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "id" && it.fieldDefinition.type.name == "String" && nonNull(list(nonNull(bar))).isEqualTo(it.parentType) && it.fieldsContainer.name == "Bar" }) where: order | visitFn @@ -1066,14 +1347,14 @@ class QueryTraversalTest extends Specification { subFoo: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {foo {__typename subFoo} __schema{ types { name } } __type(name: "Foo") { name } } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -1111,7 +1392,7 @@ class QueryTraversalTest extends Specification { field2 : String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { someObject { @@ -1127,7 +1408,7 @@ class QueryTraversalTest extends Specification { } } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) when: queryTraversal."$visitFn"(visitor) @@ -1146,7 +1427,9 @@ class QueryTraversalTest extends Specification { } - def "can select an arbitrary root node"() { + def "can select an arbitrary root node with coerced variables as plain map"() { + // When using an arbitrary root node, there is no variable definition context available. + // Thus the variables must have already been coerced, but may appear as a plain map rather than CoercedVariables given: def schema = TestUtil.schema(""" type Query{ @@ -1159,7 +1442,7 @@ class QueryTraversalTest extends Specification { id: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" {foo { subFoo {id}} } """) @@ -1167,7 +1450,7 @@ class QueryTraversalTest extends Specification { assert subFooAsRoot instanceof Field ((Field) subFooAsRoot).name == "subFoo" def rootParentType = schema.getType("Foo") - QueryTraversal queryTraversal = QueryTraversal.newQueryTraversal() + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() .schema(schema) .root(subFooAsRoot) .rootParentType(rootParentType) @@ -1186,11 +1469,50 @@ class QueryTraversalTest extends Specification { } + def "can select an arbitrary root node with coerced variables"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + } + type Foo { + subFoo: SubFoo + } + type SubFoo { + id: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {foo { subFoo {id}} } + """) + def subFooAsRoot = query.children[0].children[0].children[0].children[0].children[0] + assert subFooAsRoot instanceof Field + ((Field) subFooAsRoot).name == "subFoo" + def rootParentType = schema.getType("Foo") + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .root(subFooAsRoot) + .rootParentType(rootParentType) + .coercedVariables(CoercedVariables.emptyVariables()) + .fragmentsByName(emptyMap()) + .build() + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "subFoo" && it.fieldDefinition.type.name == "SubFoo" + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> it.field.name == "id" && it.fieldDefinition.type.name == "String" && it.parentType.name == "SubFoo" }) + + } @Unroll - def "builder doesn't allow ambiguous arguments"() { + def "builder doesn't allow null arguments"() { when: - QueryTraversal.newQueryTraversal() + QueryTraverser.newQueryTraverser() .document(document) .operationName(operationName) .root(root) @@ -1199,7 +1521,7 @@ class QueryTraversalTest extends Specification { .build() then: - thrown(IllegalStateException) + thrown(AssertException) where: document | operationName | root | rootParentType | fragmentsByName @@ -1214,26 +1536,39 @@ class QueryTraversalTest extends Specification { null | "foo" | null | Mock(GraphQLObjectType) | emptyMap() null | "foo" | null | Mock(GraphQLObjectType) | null null | "foo" | null | null | emptyMap() + } + @Unroll + def "builder doesn't allow ambiguous arguments"() { + when: + QueryTraverser.newQueryTraverser() + .document(createQuery("{foo}")) + .operationName("foo") + .root(Field.newField().build()) + .rootParentType(Mock(GraphQLObjectType)) + .fragmentsByName(emptyMap()) + .build() + then: + thrown(IllegalStateException) } - def "typename special field doens't have a fields container and throws exception"() { + def "typename special field doesn't have a fields container and throws exception"() { given: def schema = TestUtil.schema(""" type Query{ bar: String } """) - def visitor = Mock(QueryVisitor) + def visitor = mockQueryVisitor() def query = createQuery(""" { __typename } """) - QueryTraversal queryTraversal = createQueryTraversal(query, schema) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) QueryVisitorFieldEnvironment env - 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> - env = it - }) + 1 * visitor.visitField(_) >> { args -> + env = args[0] + } when: queryTraversal.visitPreOrder(visitor) env.typeNameIntrospectionField @@ -1244,5 +1579,387 @@ class QueryTraversalTest extends Specification { } + def "traverserContext is passed along"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + subFoo: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {foo { subFoo} bar } + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + when: + queryTraversal.visitPreOrder(visitor) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "foo" && it.traverserContext.getParentNodes().size() == 2 + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "subFoo" && it.traverserContext.getParentNodes().size() == 4 + + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "bar" && it.traverserContext.getParentNodes().size() == 2 + }) + + + } + + def "traverserContext parent nodes for fragment definitions"() { + given: + def schema = TestUtil.schema(""" + type Query{ + bar: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + { ...F } fragment F on Query @myDirective {bar} + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "bar" && it.traverserContext.getParentNodes().size() == 5 && + it.traverserContext.getParentContext().getParentContext().thisNode() instanceof FragmentDefinition && + ((FragmentDefinition) it.traverserContext.getParentContext().getParentContext().thisNode()).hasDirective("myDirective") + }) + + + } + + def "test depthFirst"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + subFoo: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {foo { subFoo} bar } + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + when: + queryTraversal.visitDepthFirst(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "foo" && it.traverserContext.phase == ENTER + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "subFoo" && it.traverserContext.phase == ENTER + + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "subFoo" && it.traverserContext.phase == LEAVE + + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "foo" && it.traverserContext.phase == LEAVE + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "bar" && it.traverserContext.phase == ENTER + }) + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "bar" && it.traverserContext.phase == LEAVE + }) + + } + + def "test accumulate is returned"() { + given: + def schema = TestUtil.schema(""" + type Query{ + bar: String + } + """) + def query = createQuery(""" + {bar} + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + def visitor = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment) { + queryVisitorFieldEnvironment.traverserContext.setAccumulate("RESULT") + } + + } + when: + def result = queryTraversal.visitDepthFirst(visitor) + + then: + result == "RESULT" + + } + + def "can select an interface field as root node"() { + given: + def schema = TestUtil.schema(""" + type Query{ + root: SomeInterface + } + interface SomeInterface { + hello: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {root { hello } } + """) + def rootField = (query.children[0] as OperationDefinition).selectionSet.selections[0] as Field + def hello = rootField.selectionSet.selections[0] as Field + hello.name == "hello" + def rootParentType = schema.getType("SomeInterface") as GraphQLInterfaceType + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .root(hello) + .rootParentType(rootParentType) + .variables(emptyMap()) + .fragmentsByName(emptyMap()) + .build() + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.field.name == "hello" && it.parentType.name == "SomeInterface" + }) + + } + + def "can select __typename field as root node"() { + given: + def schema = TestUtil.schema(""" + type Query{ + root: SomeUnion + } + union SomeUnion = A | B + type A { + a: String + } + type B { + b: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {root { __typename } } + """) + def rootField = (query.children[0] as OperationDefinition).selectionSet.selections[0] as Field + def typeNameField = rootField.selectionSet.selections[0] as Field + def rootParentType = schema.getType("SomeUnion") as GraphQLUnionType + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .root(typeNameField) + .rootParentType(rootParentType) + .variables(emptyMap()) + .fragmentsByName(emptyMap()) + .build() + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.isTypeNameIntrospectionField() + }) + + } + + def "respects visitorWithControl result"() { + given: + def schema = TestUtil.schema(""" + type Query{ + field: Foo + } + type Foo { + a: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {field { a } } + """) + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .document(query) + .variables(emptyMap()) + .build() + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitFieldWithControl(_) >> { TraversalControl.ABORT } + + } + + def "can copy with Scalar ObjectField visits"() { + given: + def schema = TestUtil.schema(''' + scalar JSON + + type Query{ + field(arg : JSON): String + } + ''', newRuntimeWiring().scalar(TestUtil.mockScalar("JSON")).build()) + def visitor = mockQueryVisitor() + def query = createQuery(''' + {field(arg : {a : "x", b : "y"}) } + ''') + QueryTraverser queryTraversal = QueryTraverser.newQueryTraverser() + .schema(schema) + .document(query) + .variables(emptyMap()) + .build() + when: + queryTraversal.visitPreOrder(visitor) + + then: + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.fieldDefinition.name == "field" + }) + + } + + def "directive arguments are not visited"() { + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + subFoo: String + } + + directive @cache( + ttl: Int! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + """) + def visitor = mockQueryVisitor() + def query = createQuery(""" + {foo { subFoo @cache(ttl:100) } bar @cache(ttl:200) } + """) + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + when: + queryTraversal.visitPreOrder(visitor) + then: + 0 * visitor.visitArgument(_) + } + + def "conditional nodes via variables are defaulted correctly and visited correctly"() { + + given: + def schema = TestUtil.schema(""" + type Query{ + foo: Foo + bar: String + } + type Foo { + subFoo: String + } + """) + def visitor = mockQueryVisitor() + def query = createQuery(''' + query test($var : Boolean = true) { + bar @include(if:$var) + } + ''') + QueryTraverser queryTraversal = createQueryTraversal(query, schema) + + when: "we have an enabled variable conditional node" + queryTraversal.visitPreOrder(visitor) + + then: "it should be visited" + 1 * visitor.visitField({ QueryVisitorFieldEnvironmentImpl it -> + it.fieldDefinition.name == "bar" + }) + + when: "we have an enabled variable conditional node" + query = createQuery(''' + query test($var : Boolean = false) { + bar @include(if:$var) + } + ''') + queryTraversal = createQueryTraversal(query, schema) + queryTraversal.visitPreOrder(visitor) + then: "it should not be visited" + 0 * visitor.visitField(_) + } + + def "can coerce field arguments or not"() { + def sdl = """ + input Test{ x: String!} + type Query{ testInput(input: Test!): String} + type Mutation{ testInput(input: Test!): String} + """ + + def schema = TestUtil.schema(sdl) + + def query = createQuery(''' + mutation a($test: Test!) { + testInput(input: $test) + }''') + + + def fieldArgMap = [:] + def queryVisitorStub = new QueryVisitorStub() { + @Override + void visitField(QueryVisitorFieldEnvironment queryVisitorFieldEnvironment) { + super.visitField(queryVisitorFieldEnvironment) + fieldArgMap = queryVisitorFieldEnvironment.getArguments() + } + } + + when: + QueryTraverser.newQueryTraverser() + .schema(schema) + .document(query) + .coercedVariables(CoercedVariables.of([test: [x: "X"]])) + .build() + .visitPreOrder(queryVisitorStub) + + then: + + fieldArgMap == [input: [x:"X"]] + + when: + fieldArgMap = null + + + def options = QueryTraversalOptions.defaultOptions() + .coerceFieldArguments(false) + QueryTraverser.newQueryTraverser() + .schema(schema) + .document(query) + .coercedVariables(CoercedVariables.of([test: [x: "X"]])) + .options(options) + .build() + .visitPreOrder(queryVisitorStub) + + + then: + fieldArgMap == [:] // empty map + } } diff --git a/src/test/groovy/graphql/analysis/values/ValueTraverserTest.groovy b/src/test/groovy/graphql/analysis/values/ValueTraverserTest.groovy new file mode 100644 index 0000000000..1a60b35851 --- /dev/null +++ b/src/test/groovy/graphql/analysis/values/ValueTraverserTest.groovy @@ -0,0 +1,949 @@ +package graphql.analysis.values + +import graphql.AssertException +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.TestUtil +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.DataFetchingEnvironmentImpl +import graphql.schema.GraphQLAppliedDirectiveArgument +import graphql.schema.GraphQLArgument +import graphql.schema.GraphQLEnumType +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLFieldsContainer +import graphql.schema.GraphQLInputObjectField +import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphQLInputSchemaElement +import graphql.schema.GraphQLList +import graphql.schema.GraphQLNamedSchemaElement +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLScalarType +import graphql.schema.idl.SchemaDirectiveWiring +import graphql.schema.idl.SchemaDirectiveWiringEnvironment +import spock.lang.Specification + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class ValueTraverserTest extends Specification { + + def sdl = """ + type Query { + field(arg1 : ComplexInput, arg2 : ComplexInput, stringArg : String, enumArg : RGB) : String + } + + input ComplexInput { + complexListField : [[ComplexInput!]] + objectField : InnerInput + listField : [Int!] + stringField : String + enumField : RGB + } + + input InnerInput { + innerListField : [Int!] + innerStringField : String + innerEnumField : RGB + } + + + enum RGB { + RED,GREEN,BLUE + } + """ + + def schema = TestUtil.schema(sdl) + + class CountingVisitor implements ValueVisitor { + + Map visits = [:] + + private int bumpCount(String name) { + visits.compute(name, { k, v -> return v == null ? 0 : ++v }) + } + + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, InputElements inputElements) { + bumpCount("scalar") + return coercedValue + } + + @Override + Object visitEnumValue(Object coercedValue, GraphQLEnumType inputType, InputElements inputElements) { + bumpCount("enum") + return coercedValue + } + + @Override + Object visitInputObjectFieldValue(Object coercedValue, GraphQLInputObjectType inputObjectType, GraphQLInputObjectField inputObjectField, InputElements inputElements) { + bumpCount("objectField") + return coercedValue + } + + @Override + Map visitInputObjectValue(Map coercedValue, GraphQLInputObjectType inputObjectType, InputElements inputElements) { + bumpCount("object") + return coercedValue + } + + @Override + List visitListValue(List coercedValue, GraphQLList listInputType, InputElements inputElements) { + bumpCount("list") + return coercedValue + } + } + + def "can traverse and changes nothing at all"() { + + def fieldDef = this.schema.getObjectType("Query").getFieldDefinition("field") + + def innerInput = [ + innerListField : [6, 7, 8], + innerStringField: "Inner", + innerEnumField : "RED", + ] + def complexInput = [ + complexListField: [[[objectField: innerInput, complexListField: [[]], stringField: "There", enumField: "GREEN"]]], + objectField : [innerStringField: "World", innerEnumField: "BLUE"], + listField : [1, 2, 3, 4, 5], + stringField : "Hello", + enumField : "RED", + ] + Map originalValues = [ + arg1 : complexInput, + arg2 : null, + stringArg : "Hello", + enumArg : "RGB", + noFieldData: "wat", + ] + def visitor = new CountingVisitor() + when: + def newValues = ValueTraverser.visitPreOrder(originalValues, fieldDef, visitor) + then: + // nothing changed - its the same object + newValues === originalValues + visitor.visits == ["scalar": 12, "enum": 4, "list": 5, "object": 4, "objectField": 13] + + + when: + def originalDFE = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().fieldDefinition(fieldDef).graphQLSchema(this.schema).arguments(originalValues).build() + def newDFE = ValueTraverser.visitPreOrder(originalDFE, visitor) + + then: + newDFE === originalDFE + + when: + def graphQLArgument = fieldDef.getArgument("arg1") + def newValue = ValueTraverser.visitPreOrder(complexInput, graphQLArgument, visitor) + + then: + complexInput === newValue + } + + def "can change simple values"() { + def fieldDef = this.schema.getObjectType("Query").getFieldDefinition("field") + + def innerInput = [ + innerListField : [6, 7, 8], + innerStringField: "Inner", + innerEnumField : "RED", + ] + def complexInput = [ + complexListField: [[[objectField: innerInput, complexListField: [[]], stringField: "There", enumField: "GREEN"]]], + objectField : [innerStringField: "World", innerEnumField: "BLUE"], + listField : [1, 2, 3, 4, 5], + stringField : "Hello", + enumField : "RED", + ] + Map originalValues = [ + arg1 : complexInput, + arg2 : null, + stringArg : "Hello", + enumArg : "BLUE", + noFieldData: "wat", + ] + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + if (coercedValue instanceof String) { + def val = coercedValue as String + return val.toUpperCase().reverse() + } + if (coercedValue instanceof Number) { + return coercedValue * 1000 + } + return coercedValue; + } + + @Override + Object visitEnumValue(Object coercedValue, GraphQLEnumType inputType, ValueVisitor.InputElements inputElements) { + def val = coercedValue as String + return val.toLowerCase().reverse() + } + } + when: + def newValues = ValueTraverser.visitPreOrder(originalValues, fieldDef, visitor) + then: + // numbers are 1000 greater and strings are upper case reversed and enums are lower cased reversed + newValues == [ + arg1 : [complexListField: [[[ + objectField : [ + innerListField : [6000, 7000, 8000], + innerStringField: "RENNI", + innerEnumField : "der" + ], + complexListField: [[]], + stringField : "EREHT", + enumField : "neerg"]]], + objectField : [innerStringField: "DLROW", innerEnumField: "eulb"], + listField : [1000, 2000, 3000, 4000, 5000], + stringField : "OLLEH", + enumField : "der"], + arg2 : null, + stringArg : "OLLEH", + enumArg : "eulb", + noFieldData: "wat" + ] + } + + def "can change a list midway through "() { + def sdl = """ + type Query { + field(arg : [Int]!) : String + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: [1, 2, 3, 4]] + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + if (coercedValue == 3) { + return 33 + } + return coercedValue + } + } + when: + def newValues = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + then: + newValues == [arg: [1, 2, 33, 4]] + } + + def "can change an object midway through "() { + def sdl = """ + type Query { + field(arg : Input!) : String + } + + input Input { + name : String + age : Int + input : Input + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: + [name: "Tess", age: 42, input: + [name: "Tom", age: 33, input: + [name: "Ted", age: 42]] + ] + ] + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + if (coercedValue == 42) { + return 24 + } + return coercedValue + } + } + when: + def actual = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + + def expected = [arg: + [name: "Tess", age: 24, input: + [name: "Tom", age: 33, input: + [name: "Ted", age: 24] + ] + ] + ] + then: + actual == expected + + + // can change a DFE arguments + when: + def startingDFE = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().fieldDefinition(fieldDef).arguments(argValues).build() + def newDFE = ValueTraverser.visitPreOrder(startingDFE, visitor) + + then: + newDFE.getArguments() == expected + newDFE.getFieldDefinition() == fieldDef + + // can change a single arguments + when: + def newValues = ValueTraverser.visitPreOrder(argValues['arg'], fieldDef.getArgument("arg"), visitor) + + then: + newValues == [name: "Tess", age: 24, input: + [name: "Tom", age: 33, input: + [name: "Ted", age: 24] + ] + ] + } + + def "can visit arguments and change things"() { + def sdl = """ + type Query { + field(arg1 : Input!, arg2 : Input, removeArg : Input) : String + } + + input Input { + name : String + age : Int + input : Input + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [ + arg1 : + [name: "Tess", age: 42], + arg2 : + [name: "Tom", age: 24], + removeArg: + [name: "Gone-ski", age: 99], + ] + def visitor = new ValueVisitor() { + @Override + Object visitArgumentValue(Object coercedValue, GraphQLArgument graphQLArgument, ValueVisitor.InputElements inputElements) { + if (graphQLArgument.name == "arg2") { + return [name: "Harry Potter", age: 54] + } + if (graphQLArgument.name == "removeArg") { + return ABSENCE_SENTINEL + } + return coercedValue + } + } + when: + def actual = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + + def expected = [ + arg1: + [name: "Tess", age: 42], + arg2: + [name: "Harry Potter", age: 54] + ] + then: + actual == expected + + + // can change a DFE arguments + when: + def startingDFE = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().fieldDefinition(fieldDef).arguments(argValues).build() + def newDFE = ValueTraverser.visitPreOrder(startingDFE, visitor) + + then: + newDFE.getArguments() == expected + newDFE.getFieldDefinition() == fieldDef + + // can change a single arguments + when: + def newValues = ValueTraverser.visitPreOrder(argValues['arg2'], fieldDef.getArgument("arg2"), visitor) + + then: + newValues == [name: "Harry Potter", age: 54] + + // catches non sense states + when: + ValueTraverser.visitPreOrder([:], fieldDef.getArgument("removeArg"), visitor) + + then: + thrown(AssertException.class) + } + + def "can handle applied directive arguments"() { + def sdl = """ + directive @d( + arg1 : Input + arg2 : Input + removeArg : Input + ) on FIELD_DEFINITION + + type Query { + field : String @d( + arg1: + {name: "Tom Riddle", age: 42} + arg2: + {name: "Ron Weasley", age: 42} + removeArg: + {name: "Ron Weasley", age: 42} + ) + } + + input Input { + name : String + age : Int + input : Input + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def appliedDirective = fieldDef.getAppliedDirective("d") + def visitor = new ValueVisitor() { + + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + if (coercedValue == "Tom Riddle") { + return "Happy Potter" + } + return coercedValue + } + + @Override + Object visitAppliedDirectiveArgumentValue(Object coercedValue, GraphQLAppliedDirectiveArgument graphQLAppliedDirectiveArgument, ValueVisitor.InputElements inputElements) { + if (graphQLAppliedDirectiveArgument.name == "arg2") { + return [name: "Harry Potter", age: 54] + } + if (graphQLAppliedDirectiveArgument.name == "removeArg") { + return ABSENCE_SENTINEL + } + return coercedValue + } + } + + + def appliedDirectiveArgument = appliedDirective.getArgument("arg1") + when: + def actual = ValueTraverser.visitPreOrder(appliedDirectiveArgument.getValue(), appliedDirectiveArgument, visitor) + + then: + actual == [name: "Happy Potter", age: 42] + + when: + appliedDirectiveArgument = appliedDirective.getArgument("arg2") + actual = ValueTraverser.visitPreOrder(appliedDirectiveArgument.getValue(), appliedDirectiveArgument, visitor) + + then: + actual == [name: "Harry Potter", age: 54] + + + // catches non sense states + when: + appliedDirectiveArgument = appliedDirective.getArgument("removeArg") + ValueTraverser.visitPreOrder(appliedDirectiveArgument.getValue(), appliedDirectiveArgument, visitor) + + then: + thrown(AssertException.class) + } + + def "can handle a null changes"() { + def sdl = """ + type Query { + field(arg : Input!) : String + } + + input Input { + listField : [String!] + objectField : Input + stringField : String + leaveAloneField : String + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: + [ + listField : ["a", "b", "c"], + objectField : [listField: ["a", "b", "c"]], + stringField : "s", + leaveAloneField: "ok" + ] + ] + def visitor = new ValueVisitor() { + + @Override + Object visitInputObjectFieldValue(Object coercedValue, GraphQLInputObjectType inputObjectType, GraphQLInputObjectField inputObjectField, ValueVisitor.InputElements inputElements) { + if (inputObjectField.name == "leaveAloneField") { + return coercedValue + } + return null + } + + } + when: + def actual = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + + def expected = [arg: + [ + listField : null, + objectField : null, + stringField : null, + leaveAloneField: "ok", + ] + ] + then: + actual == expected + } + + def "can turn nulls into actual values"() { + def sdl = """ + type Query { + field(arg : Input) : String + } + + input Input { + listField : [String] + objectField : Input + stringField : String + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: + [ + listField : null, + objectField: null, + stringField: null, + ] + ] + def visitor = new ValueVisitor() { + + @Override + Object visitInputObjectFieldValue(Object coercedValue, GraphQLInputObjectType inputObjectType, GraphQLInputObjectField inputObjectField, ValueVisitor.InputElements inputElements) { + if (inputObjectField.name == "listField") { + return ["a", "b", "c"] + } + if (inputObjectField.name == "objectField") { + return [listField: ["x", "y", "z"], stringField: ["will be overwritten"]] + } + if (inputObjectField.name == "stringField") { + return "stringValue" + } + return coercedValue + } + + } + when: + def actual = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + + def expected = [arg: + [ + listField : ["a", "b", "c"], + objectField: [listField: ["a", "b", "c"], stringField: "stringValue"], + stringField: "stringValue", + ] + ] + then: + actual == expected + } + + + def "can use the sentinel to remove elements"() { + def sdl = """ + + type Query { + field(arg : Input!, arg2 : String) : String + } + + input Input { + name : String + age : Int + extraInput : ExtraInput + listInput : [Int] + } + + input ExtraInput { + name : String + gone : Boolean + age : Int + otherInput : ExtraInput + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg : + [name : "Tess", + age : 42, + extraInput: + [name : "Tom", + age : 33, + gone : true, + otherInput: [ + name: "Ted", + age : 42] + ], + listInput : [1, 2, 3, 4, 5, 6, 7, 8] + ], + arg2: "Gone-ski" + ] + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + def fieldName = inputElements.getLastInputValueDefinition().name + if (fieldName == "age") { + return ABSENCE_SENTINEL + } + if (coercedValue == "Gone-ski") { + return ABSENCE_SENTINEL + } + if (coercedValue == 4 || coercedValue == 7) { + return ABSENCE_SENTINEL + } + return coercedValue + } + + @Override + Object visitInputObjectFieldValue(Object coercedValue, GraphQLInputObjectType inputObjectType, GraphQLInputObjectField inputObjectField, ValueVisitor.InputElements inputElements) { + def fieldName = inputElements.getLastInputValueDefinition().name + if (fieldName == "otherInput") { + return ABSENCE_SENTINEL + } + if (fieldName == "gone") { + return ABSENCE_SENTINEL + } + return coercedValue + } + } + when: + def newValues = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + then: + newValues == [arg: + [name : "Tess", + extraInput: + [name: "Tom"], + listInput : [1, 2, 3, 5, 6, 8] + ] + ] + } + + def "can get give access to all elements and unwrapped elements"() { + def sdl = """ + + type Query { + field(arg : Input! ) : String + } + + input Input { + name : String + age : Int + objectField : [[Input!]]! + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: + [name : "Tess", + age : 42, + objectField: [[ + [ + name : "Tom", + age : 33, + objectField: [[ + [ + name: "Ted", + age : 42 + ] + ]] + ] + ]] + ] + ] + def captureAll = [] + def captureUnwrapped = [] + def last = "" + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + if (coercedValue == "Ted") { + captureAll = inputElements.inputElements.collect { testStr(it) } + captureUnwrapped = inputElements.unwrappedInputElements.collect { testStr(it) } + last = inputElements.lastInputValueDefinition.name + } + return coercedValue + } + + String testStr(GraphQLInputSchemaElement inputSchemaElement) { + if (inputSchemaElement instanceof GraphQLNamedSchemaElement) { + return inputSchemaElement.name + } + return inputSchemaElement.toString() + } + } + when: + def newValues = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + then: + newValues == argValues + last == "name" + captureAll == [ + "arg", + "Input!", + "Input", + "objectField", + "[[Input!]]!", + "[[Input!]]", + "[Input!]", + "Input!", + "Input", + "objectField", + "[[Input!]]!", + "[[Input!]]", + "[Input!]", + "Input!", + "Input", + "name", + "String", + ] + captureUnwrapped == [ + "arg", + "Input", + "objectField", + "Input", + "objectField", + "Input", + "name", + "String", + ] + } + + def "can get access to directives"() { + def sdl = """ + directive @d(name : String!) on ARGUMENT_DEFINITION | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + type Query { + field(arg : Input! @d(name : "argDirective") ) : String + } + + input Input { + name : String @d(name : "nameDirective") + age : Int @d(name : "ageDirective") + input : Input @d(name : "inputDirective") + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: + [name: "Tess", age: 42, input: + [name: "Tom", age: 33, input: + [name: "Ted", age: 42]] + ] + ] + def capture = [] + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + checkDirectives(inputElements) + return coercedValue + } + + + private void checkDirectives(ValueVisitor.InputElements inputElements) { + def lastElement = inputElements.getLastInputValueDefinition() + def directive = lastElement.getAppliedDirective("d") + if (directive != null) { + def elementNames = inputElements.getInputElements().collect( + { it -> + if (it instanceof GraphQLNamedSchemaElement) { + return it.name + } else { + it.toString() + } + }) + .join(":") + def value = directive.getArgument("name").value + capture.add(elementNames + "@" + value) + } + } + } + when: + def newValues = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + then: + newValues == argValues + capture == [ + "arg:Input!:Input:name:String@nameDirective", + "arg:Input!:Input:age:Int@ageDirective", + + "arg:Input!:Input:input:Input:name:String@nameDirective", + "arg:Input!:Input:input:Input:age:Int@ageDirective", + + "arg:Input!:Input:input:Input:input:Input:name:String@nameDirective", + "arg:Input!:Input:input:Input:input:Input:age:Int@ageDirective" + ] + } + + def "can follow directives and change input"() { + def sdl = """ + directive @stripHtml on ARGUMENT_DEFINITION | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + type Query { + field(arg : Input!) : String + } + + input Input { + name : String @stripHtml + age : Int + input : Input + } + """ + def schema = TestUtil.schema(sdl) + + def fieldDef = schema.getObjectType("Query").getFieldDefinition("field") + def argValues = [arg: + [name: "Tess", age: 42, input: + [name: "Tom", age: 33, input: + [name: "Ted", age: 42]] + ] + ] + + def visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + def lastElement = inputElements.getLastInputValueDefinition() + def directive = lastElement.getAppliedDirective("stripHtml") + if (directive != null) { + def v = String.valueOf(coercedValue) + return v.replaceAll(//, '').replaceAll(/<.*?>/, '') + } + return coercedValue + } + + } + when: + def newValues = ValueTraverser.visitPreOrder(argValues, fieldDef, visitor) + then: + newValues == [arg: + [name: "Tess", age: 42, input: + [name: "Tom", age: 33, input: + [name: "Ted", age: 42]] + ] + ] + } + + def "an integration test showing how to change values"() { + def sdl = """ +directive @stripHtml on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION + +type Query { + searchProfile(contains: String! @stripHtml, limit: Int): Profile! +} + +type Mutation { + signUp(input: SignUpInput!): Profile! +} + +input SignUpInput { + username: String! @stripHtml + password: String! + firstName: String! + lastName: String! +} + +type Profile { + username: String! + fullName: String! +} +""" + def schemaDirectiveWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + GraphQLFieldsContainer fieldsContainer = env.getFieldsContainer() + GraphQLFieldDefinition fieldDefinition = env.getFieldDefinition() + if (! fieldsContainer instanceof GraphQLObjectType) { + return fieldDefinition + } + GraphQLObjectType containingObjectType = env.getFieldsContainer() as GraphQLObjectType + + final DataFetcher originalDF = env.getCodeRegistry().getDataFetcher(containingObjectType, fieldDefinition) + final DataFetcher newDF = { DataFetchingEnvironment originalEnv -> + ValueVisitor visitor = new ValueVisitor() { + @Override + Object visitScalarValue(Object coercedValue, GraphQLScalarType inputType, ValueVisitor.InputElements inputElements) { + def container = inputElements.getLastInputValueDefinition() + if (container.hasAppliedDirective("stripHtml")) { + return stripHtml(coercedValue) + } + return coercedValue + } + + private String stripHtml(coercedValue) { + return String.valueOf(coercedValue) + .replaceAll(//, '') + .replaceAll(/<.*?>/, '') + } + } + DataFetchingEnvironment newEnv = ValueTraverser.visitPreOrder(originalEnv, visitor) + return originalDF.get(newEnv); + } + + env.getCodeRegistry().dataFetcher(containingObjectType, fieldDefinition, newDF) + + return fieldDefinition + } + } + + DataFetcher searchProfileDF = { env -> + def containsArg = env.getArgument("contains") as String + return [username: containsArg] + + } + DataFetcher signUpDF = { DataFetchingEnvironment env -> + def inputArg = env.getArgument("input") as Map + def inputUserName = inputArg["username"] + return [username: inputUserName] + } + def runtimeWiring = newRuntimeWiring().directiveWiring(schemaDirectiveWiring) + .type(newTypeWiring("Query").dataFetcher("searchProfile", searchProfileDF)) + .type(newTypeWiring("Mutation").dataFetcher("signUp", signUpDF)) + .build() + def schema = TestUtil.schema(sdl, runtimeWiring) + def graphQL = GraphQL.newGraphQL(schema).build() + + def query = """ + query q { + searchProfile(contains : "someHtml") { + username + } + } + + mutation m { + signUp(input : { + username: "bbakerman" + password: "hunter2" + firstName: "Brad" + lastName: "Baker" + } + ) { + username + } + } +""" + + when: + def executionInput = ExecutionInput.newExecutionInput(query).operationName("q").build() + def er = graphQL.execute(executionInput) + then: + er.errors.isEmpty() + er.data == [searchProfile: [username: "someHtml"]] + + // mutation + when: + executionInput = ExecutionInput.newExecutionInput(query).operationName("m").build() + er = graphQL.execute(executionInput) + then: + er.errors.isEmpty() + er.data == [signUp: [username: "bbakerman"]] + } +} diff --git a/src/test/groovy/graphql/archunit/JMHForkArchRuleTest.groovy b/src/test/groovy/graphql/archunit/JMHForkArchRuleTest.groovy new file mode 100644 index 0000000000..943da3f59d --- /dev/null +++ b/src/test/groovy/graphql/archunit/JMHForkArchRuleTest.groovy @@ -0,0 +1,51 @@ +package graphql.archunit + +import com.tngtech.archunit.core.domain.JavaClass +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.lang.ArchCondition +import com.tngtech.archunit.lang.ConditionEvents +import com.tngtech.archunit.lang.EvaluationResult +import com.tngtech.archunit.lang.SimpleConditionEvent +import org.openjdk.jmh.annotations.Fork +import spock.lang.Specification + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes + +class JMHForkArchRuleTest extends Specification { + + def "JMH benchmarks on classes should not have a fork value greater than 2"() { + given: + def importedClasses = new ClassFileImporter() + .importPackages("benchmark", "performance", "graphql.execution") + + + def rule = classes() + .that().areAnnotatedWith(Fork.class) + .and().areTopLevelClasses() + .should(haveForkValueNotGreaterThan(2)) + + when: + EvaluationResult result = rule.evaluate(importedClasses) + + then: + !result.hasViolation() + + cleanup: + if (result.hasViolation()) { + println result.getFailureReport().toString() + } + } + + private static ArchCondition haveForkValueNotGreaterThan(int maxFork) { + return new ArchCondition("have a @Fork value of at most $maxFork") { + @Override + void check(JavaClass javaClass, ConditionEvents events) { + def forkAnnotation = javaClass.getAnnotationOfType(Fork.class) + if (forkAnnotation.value() > maxFork) { + def message = "Class ${javaClass.name} has a @Fork value of ${forkAnnotation.value()} which is > $maxFork" + events.add(SimpleConditionEvent.violated(javaClass, message)) + } + } + } + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy b/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy new file mode 100644 index 0000000000..95dc0cc435 --- /dev/null +++ b/src/test/groovy/graphql/archunit/JSpecifyAnnotationsCheck.groovy @@ -0,0 +1,381 @@ +package graphql + +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.core.importer.ImportOption +import spock.lang.Specification + +/** + * This test ensures that all public API and experimental API classes + * are properly annotated with JSpecify annotations. + */ +class JSpecifyAnnotationsCheck extends Specification { + + private static final Set JSPECIFY_EXEMPTION_LIST = [ + "graphql.AssertException", + "graphql.Directives", + "graphql.ErrorClassification", + "graphql.ErrorType", + "graphql.ExceptionWhileDataFetching", + "graphql.ExecutionResult", + "graphql.GraphQLContext", + "graphql.GraphQLError", + "graphql.GraphqlErrorBuilder", + "graphql.GraphqlErrorException", + "graphql.ParseAndValidate", + "graphql.ParseAndValidateResult", + "graphql.Scalars", + "graphql.SerializationError", + "graphql.TypeMismatchError", + "graphql.TypeResolutionEnvironment", + "graphql.UnresolvedTypeError", + "graphql.agent.result.ExecutionTrackingResult", + "graphql.analysis.FieldComplexityCalculator", + "graphql.analysis.FieldComplexityEnvironment", + "graphql.analysis.MaxQueryComplexityInstrumentation", + "graphql.analysis.MaxQueryDepthInstrumentation", + "graphql.analysis.QueryComplexityCalculator", + "graphql.analysis.QueryComplexityInfo", + "graphql.analysis.QueryDepthInfo", + "graphql.analysis.QueryReducer", + "graphql.analysis.QueryTransformer", + "graphql.analysis.QueryTraversalOptions", + "graphql.analysis.QueryTraverser", + "graphql.analysis.QueryVisitor", + "graphql.analysis.QueryVisitorFieldArgumentEnvironment", + "graphql.analysis.QueryVisitorFieldArgumentInputValue", + "graphql.analysis.QueryVisitorFieldArgumentValueEnvironment", + "graphql.analysis.QueryVisitorFieldEnvironment", + "graphql.analysis.QueryVisitorFragmentDefinitionEnvironment", + "graphql.analysis.QueryVisitorFragmentSpreadEnvironment", + "graphql.analysis.QueryVisitorInlineFragmentEnvironment", + "graphql.analysis.QueryVisitorStub", + "graphql.analysis.values.ValueTraverser", + "graphql.execution.AbortExecutionException", + "graphql.execution.AsyncExecutionStrategy", + "graphql.execution.AsyncSerialExecutionStrategy", + "graphql.execution.CoercedVariables", + "graphql.execution.DataFetcherExceptionHandlerParameters", + "graphql.execution.DataFetcherExceptionHandlerResult", + "graphql.execution.DefaultValueUnboxer", + "graphql.execution.ExecutionContext", + "graphql.execution.ExecutionId", + "graphql.execution.ExecutionStepInfo", + "graphql.execution.ExecutionStrategyParameters", + "graphql.execution.FetchedValue", + "graphql.execution.FieldValueInfo", + "graphql.execution.InputMapDefinesTooManyFieldsException", + "graphql.execution.MergedSelectionSet", + "graphql.execution.MissingRootTypeException", + "graphql.execution.NonNullableValueCoercedAsNullException", + "graphql.execution.NormalizedVariables", + "graphql.execution.OneOfNullValueException", + "graphql.execution.OneOfTooManyKeysException", + "graphql.execution.ResultNodesInfo", + "graphql.execution.ResultPath", + "graphql.execution.SimpleDataFetcherExceptionHandler", + "graphql.execution.SubscriptionExecutionStrategy", + "graphql.execution.UnknownOperationException", + "graphql.execution.UnresolvedTypeException", + "graphql.execution.conditional.ConditionalNodeDecision", + "graphql.execution.directives.QueryAppliedDirective", + "graphql.execution.directives.QueryAppliedDirectiveArgument", + "graphql.execution.directives.QueryDirectives", + "graphql.execution.incremental.DeferredExecution", + "graphql.execution.instrumentation.ChainedInstrumentation", + "graphql.execution.instrumentation.DocumentAndVariables", + "graphql.execution.instrumentation.NoContextChainedInstrumentation", + "graphql.execution.ResponseMapFactory", + "graphql.execution.instrumentation.SimpleInstrumentation", + "graphql.execution.instrumentation.SimpleInstrumentationContext", + "graphql.execution.instrumentation.SimplePerformantInstrumentation", + "graphql.execution.instrumentation.fieldvalidation.FieldAndArguments", + "graphql.execution.instrumentation.fieldvalidation.FieldValidationEnvironment", + "graphql.execution.instrumentation.fieldvalidation.FieldValidationInstrumentation", + "graphql.execution.instrumentation.fieldvalidation.SimpleFieldValidation", + "graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters", + "graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters", + "graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters", + "graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters", + "graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters", + "graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters", + "graphql.execution.instrumentation.parameters.InstrumentationFieldParameters", + "graphql.execution.instrumentation.parameters.InstrumentationValidationParameters", + "graphql.execution.instrumentation.tracing.TracingInstrumentation", + "graphql.execution.instrumentation.tracing.TracingSupport", + "graphql.execution.preparsed.PreparsedDocumentEntry", + "graphql.execution.preparsed.persisted.ApolloPersistedQuerySupport", + "graphql.execution.preparsed.persisted.InMemoryPersistedQueryCache", + "graphql.execution.preparsed.persisted.PersistedQueryCacheMiss", + "graphql.execution.preparsed.persisted.PersistedQueryIdInvalid", + "graphql.execution.preparsed.persisted.PersistedQueryNotFound", + "graphql.execution.reactive.DelegatingSubscription", + "graphql.execution.reactive.SubscriptionPublisher", + "graphql.extensions.ExtensionsBuilder", + "graphql.incremental.DeferPayload", + "graphql.incremental.DelayedIncrementalPartialResult", + "graphql.incremental.DelayedIncrementalPartialResultImpl", + "graphql.incremental.IncrementalExecutionResult", + "graphql.incremental.IncrementalExecutionResultImpl", + "graphql.incremental.IncrementalPayload", + "graphql.incremental.StreamPayload", + "graphql.introspection.GoodFaithIntrospection", + "graphql.introspection.Introspection", + "graphql.introspection.IntrospectionQuery", + "graphql.introspection.IntrospectionQueryBuilder", + "graphql.introspection.IntrospectionResultToSchema", + "graphql.introspection.IntrospectionWithDirectivesSupport", + "graphql.introspection.IntrospectionWithDirectivesSupport\$DirectivePredicateEnvironment", + "graphql.language.AbstractDescribedNode", + "graphql.language.Argument", + "graphql.language.AstNodeAdapter", + "graphql.language.AstPrinter", + "graphql.language.AstSignature", + "graphql.language.AstSorter", + "graphql.language.AstTransformer", + "graphql.language.Comment", + "graphql.language.Definition", + "graphql.language.DescribedNode", + "graphql.language.Description", + "graphql.language.Directive", + "graphql.language.DirectiveDefinition", + "graphql.language.DirectiveLocation", + "graphql.language.DirectivesContainer", + "graphql.language.Document", + "graphql.language.EnumTypeDefinition", + "graphql.language.EnumTypeExtensionDefinition", + "graphql.language.EnumValueDefinition", + "graphql.language.Field", + "graphql.language.FieldDefinition", + "graphql.language.FragmentDefinition", + "graphql.language.FragmentSpread", + "graphql.language.IgnoredChar", + "graphql.language.IgnoredChars", + "graphql.language.ImplementingTypeDefinition", + "graphql.language.InlineFragment", + "graphql.language.InputObjectTypeDefinition", + "graphql.language.InputObjectTypeExtensionDefinition", + "graphql.language.InputValueDefinition", + "graphql.language.InterfaceTypeDefinition", + "graphql.language.InterfaceTypeExtensionDefinition", + "graphql.language.ListType", + "graphql.language.NamedNode", + "graphql.language.Node", + "graphql.language.NodeChildrenContainer", + "graphql.language.NodeDirectivesBuilder", + "graphql.language.NodeParentTree", + "graphql.language.NodeTraverser", + "graphql.language.NodeVisitor", + "graphql.language.NodeVisitorStub", + "graphql.language.NonNullType", + "graphql.language.ObjectField", + "graphql.language.ObjectTypeDefinition", + "graphql.language.ObjectTypeExtensionDefinition", + "graphql.language.OperationDefinition", + "graphql.language.OperationTypeDefinition", + "graphql.language.PrettyAstPrinter", + "graphql.language.SDLDefinition", + "graphql.language.SDLExtensionDefinition", + "graphql.language.SDLNamedDefinition", + "graphql.language.ScalarTypeDefinition", + "graphql.language.ScalarTypeExtensionDefinition", + "graphql.language.SchemaDefinition", + "graphql.language.SchemaExtensionDefinition", + "graphql.language.Selection", + "graphql.language.SelectionSet", + "graphql.language.SelectionSetContainer", + "graphql.language.SourceLocation", + "graphql.language.Type", + "graphql.language.TypeDefinition", + "graphql.language.TypeKind", + "graphql.language.TypeName", + "graphql.language.UnionTypeDefinition", + "graphql.language.UnionTypeExtensionDefinition", + "graphql.language.VariableDefinition", + "graphql.normalized.ExecutableNormalizedField", + "graphql.normalized.ExecutableNormalizedOperation", + "graphql.normalized.ExecutableNormalizedOperationFactory", + "graphql.normalized.ExecutableNormalizedOperationToAstCompiler", + "graphql.normalized.NormalizedInputValue", + "graphql.normalized.incremental.NormalizedDeferredExecution", + "graphql.normalized.nf.NormalizedDocument", + "graphql.normalized.nf.NormalizedDocumentFactory", + "graphql.normalized.nf.NormalizedField", + "graphql.normalized.nf.NormalizedOperation", + "graphql.normalized.nf.NormalizedOperationToAstCompiler", + "graphql.parser.InvalidSyntaxException", + "graphql.parser.MultiSourceReader", + "graphql.parser.Parser", + "graphql.parser.ParserEnvironment", + "graphql.parser.ParserOptions", + "graphql.relay.Connection", + "graphql.relay.ConnectionCursor", + "graphql.relay.DefaultConnection", + "graphql.relay.DefaultConnectionCursor", + "graphql.relay.DefaultEdge", + "graphql.relay.DefaultPageInfo", + "graphql.relay.Edge", + "graphql.relay.PageInfo", + "graphql.relay.Relay", + "graphql.relay.SimpleListConnection", + "graphql.schema.AsyncDataFetcher", + "graphql.schema.CoercingParseLiteralException", + "graphql.schema.CoercingParseValueException", + "graphql.schema.CoercingSerializeException", + "graphql.schema.DataFetcherFactories", + "graphql.schema.DataFetcherFactoryEnvironment", + "graphql.schema.DataFetchingFieldSelectionSet", + "graphql.schema.DefaultGraphqlTypeComparatorRegistry", + "graphql.schema.DelegatingDataFetchingEnvironment", + "graphql.schema.FieldCoordinates", + "graphql.schema.GraphQLAppliedDirective", + "graphql.schema.GraphQLAppliedDirectiveArgument", + "graphql.schema.GraphQLArgument", + "graphql.schema.GraphQLCodeRegistry", + "graphql.schema.GraphQLCompositeType", + "graphql.schema.GraphQLDirective", + "graphql.schema.GraphQLDirectiveContainer", + "graphql.schema.GraphQLEnumType", + "graphql.schema.GraphQLEnumValueDefinition", + "graphql.schema.GraphQLFieldDefinition", + "graphql.schema.GraphQLFieldsContainer", + "graphql.schema.GraphQLImplementingType", + "graphql.schema.GraphQLInputFieldsContainer", + "graphql.schema.GraphQLInputObjectField", + "graphql.schema.GraphQLInputObjectType", + "graphql.schema.GraphQLInputSchemaElement", + "graphql.schema.GraphQLInputType", + "graphql.schema.GraphQLInputValueDefinition", + "graphql.schema.GraphQLInterfaceType", + "graphql.schema.GraphQLList", + "graphql.schema.GraphQLModifiedType", + "graphql.schema.GraphQLNamedInputType", + "graphql.schema.GraphQLNamedOutputType", + "graphql.schema.GraphQLNamedSchemaElement", + "graphql.schema.GraphQLNamedType", + "graphql.schema.GraphQLNonNull", + "graphql.schema.GraphQLNullableType", + "graphql.schema.GraphQLObjectType", + "graphql.schema.GraphQLOutputType", + "graphql.schema.GraphQLScalarType", + "graphql.schema.GraphQLSchema", + "graphql.schema.GraphQLSchemaElement", + "graphql.schema.GraphQLType", + "graphql.schema.GraphQLTypeReference", + "graphql.schema.GraphQLTypeUtil", + "graphql.schema.GraphQLTypeVisitor", + "graphql.schema.GraphQLTypeVisitorStub", + "graphql.schema.GraphQLUnionType", + "graphql.schema.GraphQLUnmodifiedType", + "graphql.schema.GraphqlElementParentTree", + "graphql.schema.GraphqlTypeComparatorEnvironment", + "graphql.schema.GraphqlTypeComparatorRegistry", + "graphql.schema.InputValueWithState", + "graphql.schema.PropertyDataFetcher", + "graphql.schema.SchemaElementChildrenContainer", + "graphql.schema.SchemaTransformer", + "graphql.schema.SchemaTraverser", + "graphql.schema.SelectedField", + "graphql.schema.StaticDataFetcher", + "graphql.schema.diff.DiffCategory", + "graphql.schema.diff.DiffEvent", + "graphql.schema.diff.DiffLevel", + "graphql.schema.diff.DiffSet", + "graphql.schema.diff.SchemaDiffSet", + "graphql.schema.diff.reporting.CapturingReporter", + "graphql.schema.diff.reporting.ChainedReporter", + "graphql.schema.diff.reporting.PrintStreamReporter", + "graphql.schema.diffing.SchemaGraph", + "graphql.schema.idl.CombinedWiringFactory", + "graphql.schema.idl.DirectiveInfo", + "graphql.schema.idl.MapEnumValuesProvider", + "graphql.schema.idl.NaturalEnumValuesProvider", + "graphql.schema.idl.RuntimeWiring", + "graphql.schema.idl.SchemaDirectiveWiring", + "graphql.schema.idl.SchemaDirectiveWiringEnvironment", + "graphql.schema.idl.SchemaGenerator", + "graphql.schema.idl.SchemaPrinter", + "graphql.schema.idl.TypeRuntimeWiring", + "graphql.schema.idl.errors.SchemaProblem", + "graphql.schema.idl.errors.StrictModeWiringException", + "graphql.schema.transform.FieldVisibilitySchemaTransformation", + "graphql.schema.transform.VisibleFieldPredicateEnvironment", + "graphql.schema.usage.SchemaUsage", + "graphql.schema.usage.SchemaUsageSupport", + "graphql.schema.validation.OneOfInputObjectRules", + "graphql.schema.validation.SchemaValidationErrorClassification", + "graphql.schema.visibility.BlockedFields", + "graphql.schema.visibility.DefaultGraphqlFieldVisibility", + "graphql.schema.visibility.GraphqlFieldVisibility", + "graphql.schema.visibility.NoIntrospectionGraphqlFieldVisibility", + "graphql.schema.visitor.GraphQLSchemaTraversalControl", + "graphql.util.Anonymizer", + "graphql.util.Breadcrumb", + "graphql.util.CyclicSchemaAnalyzer", + "graphql.util.NodeAdapter", + "graphql.util.NodeLocation", + "graphql.util.NodeMultiZipper", + "graphql.util.NodeZipper", + "graphql.util.querygenerator.QueryGenerator", + "graphql.util.querygenerator.QueryGeneratorOptions", + "graphql.util.querygenerator.QueryGeneratorOptions\$QueryGeneratorOptionsBuilder", + "graphql.util.querygenerator.QueryGeneratorResult", + "graphql.util.TraversalControl", + "graphql.util.TraverserContext", + "graphql.util.TreeTransformer", + "graphql.util.TreeTransformerUtil", + "graphql.validation.ValidationError", + "graphql.validation.ValidationErrorClassification", + "graphql.validation.ValidationErrorType", + "graphql.validation.rules.DeferDirectiveLabel", + "graphql.validation.rules.DeferDirectiveOnRootLevel", + "graphql.validation.rules.DeferDirectiveOnValidOperation" + ] as Set + + def "ensure all public API and experimental API classes have @NullMarked annotation"() { + given: + def classes = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) + .importPackages("graphql") + .stream() + .filter { it.isAnnotatedWith("graphql.PublicApi") || it.isAnnotatedWith("graphql.ExperimentalApi") } + .collect() + + when: + def classesMissingAnnotation = classes + .stream() + .filter { !it.isAnnotatedWith("org.jspecify.annotations.NullMarked") && !it.isAnnotatedWith("org.jspecify.annotations.NullUnmarked") } + .map { it.name } + .filter { it -> !JSPECIFY_EXEMPTION_LIST.contains(it) } + .collect() + + then: + if (!classesMissingAnnotation.isEmpty()) { + throw new AssertionError("""The following public API and experimental API classes are missing a JSpecify annotation: +${classesMissingAnnotation.sort().join("\n")} + +Add @NullMarked or @NullUnmarked to these public API classes. See documentation at https://jspecify.dev/docs/user-guide/#nullmarked""") + } + } + + def "exempted classes should not be annotated with @NullMarked or @NullUnmarked"() { + given: + def classes = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) + .importPackages("graphql") + + when: + def annotatedButExempted = classes.stream() + .filter { JSPECIFY_EXEMPTION_LIST.contains(it.name) } + .filter { it.isAnnotatedWith("org.jspecify.annotations.NullMarked") || it.isAnnotatedWith("org.jspecify.annotations.NullUnmarked") } + .map { it.name } + .collect() + + then: + if (!annotatedButExempted.isEmpty()) { + throw new AssertionError("""The following classes are in the JSpecify exemption list but are annotated with @NullMarked or @NullUnmarked: +${annotatedButExempted.sort().join("\n")} + +Please remove them from the exemption list in ${JSpecifyAnnotationsCheck.class.simpleName}.groovy.""") + } + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/archunit/MapOfUsageTest.groovy b/src/test/groovy/graphql/archunit/MapOfUsageTest.groovy new file mode 100644 index 0000000000..9f6a4471c7 --- /dev/null +++ b/src/test/groovy/graphql/archunit/MapOfUsageTest.groovy @@ -0,0 +1,36 @@ +package graphql.archunit + +import com.tngtech.archunit.core.domain.JavaClasses +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.core.importer.ImportOption +import com.tngtech.archunit.lang.ArchRule +import com.tngtech.archunit.lang.EvaluationResult +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition +import spock.lang.Specification + +class MapOfUsageTest extends Specification { + + private static final JavaClasses importedClasses = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) + .importPackages("graphql") + + def "should not use Map.of()"() { + given: + ArchRule mapOfRule = ArchRuleDefinition.noClasses() + .should() + .callMethod(Map.class, "of") + .because("Map.of() does not guarantee insertion order. Use LinkedHashMapFactory.of() instead for consistent serialization order.") + + when: + EvaluationResult result = mapOfRule.evaluate(importedClasses) + + then: + if (result.hasViolation()) { + println "Map.of() usage detected. Please use LinkedHashMapFactory.of() instead for consistent serialization order:" + result.getFailureReport().getDetails().each { violation -> + println "- ${violation}" + } + } + !result.hasViolation() + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/archunit/NullabilityAnnotationUsageTest.groovy b/src/test/groovy/graphql/archunit/NullabilityAnnotationUsageTest.groovy new file mode 100644 index 0000000000..ed0b93197b --- /dev/null +++ b/src/test/groovy/graphql/archunit/NullabilityAnnotationUsageTest.groovy @@ -0,0 +1,40 @@ +package graphql.archunit + +import com.tngtech.archunit.core.domain.JavaClasses +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.core.importer.ImportOption +import com.tngtech.archunit.lang.ArchRule +import com.tngtech.archunit.lang.EvaluationResult +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition +import spock.lang.Specification + +class NullabilityAnnotationUsageTest extends Specification { + + private static final JavaClasses importedClasses = new ClassFileImporter() + .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) + .importPackages("graphql") + + def "should only use JSpecify nullability annotations"() { + given: + ArchRule dependencyRule = ArchRuleDefinition.noClasses() + .should() + .dependOnClassesThat() + .resideInAnyPackage( + "javax.annotation", + "org.jetbrains.annotations" + ) + .because("We are using JSpecify nullability annotations only. Please change to use JSpecify.") + + when: + EvaluationResult result = dependencyRule.evaluate(importedClasses) + + then: + if (result.hasViolation()) { + println "We are using JSpecify nullability annotations only. Please change the following to use JSpecify instead:" + result.getFailureReport().getDetails().each { violation -> + println "- ${violation}" + } + } + !result.hasViolation() + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/collect/ImmutableKitTest.groovy b/src/test/groovy/graphql/collect/ImmutableKitTest.groovy new file mode 100644 index 0000000000..c777211f53 --- /dev/null +++ b/src/test/groovy/graphql/collect/ImmutableKitTest.groovy @@ -0,0 +1,94 @@ +package graphql.collect + +import com.google.common.collect.ImmutableList +import spock.lang.Specification + +class ImmutableKitTest extends Specification { + + def "empty things are empty"() { + expect: + ImmutableKit.emptyMap().size() == 0 + ImmutableKit.emptyList().size() == 0 + ImmutableKit.emptyMap().size() == 0 + } + + def "can map a collections"() { + when: + def outputList = ImmutableKit.map(["quick", "brown", "fox"], { word -> word.reverse() }) + then: + outputList == ["kciuq", "nworb", "xof"] + outputList instanceof ImmutableList + } + + def "can map a collection with nulls"() { + when: + def outputList = ImmutableKit.mapAndDropNulls(["quick", "brown", "NULL", "fox"], { + word -> (word == "NULL") ? null : word.reverse() + }) + then: + outputList == ["kciuq", "nworb", "xof"] + outputList instanceof ImmutableList + } + + def "can add to lists"() { + def list = ["a"] + + when: + list = ImmutableKit.addToList(list, "b") + then: + list == ["a", "b"] + + when: + list = ImmutableKit.addToList(list, "c", "d", "e") + then: + list == ["a", "b", "c", "d", "e"] + } + + def "can add to sets"() { + def set = new HashSet(["a"]) + + when: + set = ImmutableKit.addToSet(set, "b") + then: + set == ["a", "b"] as Set + + when: + set = ImmutableKit.addToSet(set, "c", "d", "e") + then: + set == ["a", "b", "c", "d", "e"] as Set + + when: + set = ImmutableKit.addToSet(set, "c", "d", "e", "f") + then: + set == ["a", "b", "c", "d", "e", "f"] as Set + } + + def "flatMapList works"() { + def listOfLists = [ + ["A", "B"], + ["C"], + ["D", "E"], + ] + when: + def flatList = ImmutableKit.flatMapList(listOfLists) + then: + flatList == ["A", "B", "C", "D", "E",] + } + + def "can filter variable args"() { + when: + def list = ImmutableKit.filterVarArgs({ String s -> s.endsWith("x") }, "a", "b", "ax", "bx", "c") + then: + list == ["ax", "bx"] + + when: + list = ImmutableKit.filterVarArgs({ String s -> s.startsWith("Z") }, "a", "b", "ax", "bx", "c") + then: + list == [] + + when: + list = ImmutableKit.filterVarArgs({ String s -> s.startsWith("x") }) + then: + list == [] + } +} diff --git a/src/test/groovy/graphql/collect/ImmutableMapWithNullValuesTest.groovy b/src/test/groovy/graphql/collect/ImmutableMapWithNullValuesTest.groovy new file mode 100644 index 0000000000..8e32cb063d --- /dev/null +++ b/src/test/groovy/graphql/collect/ImmutableMapWithNullValuesTest.groovy @@ -0,0 +1,34 @@ +package graphql.collect + +import spock.lang.Specification + +class ImmutableMapWithNullValuesTest extends Specification { + + def "can have nulls as keys"() { + when: + def map = ImmutableMapWithNullValues.copyOf([a: null, b: "b"]) + then: + map.get("a") == null + map.get("b") == "b" + } + + def "can be empty"() { + when: + def map = ImmutableMapWithNullValues.copyOf([:]) + then: + map.isEmpty() + map == ImmutableMapWithNullValues.emptyMap() + + when: + map = ImmutableMapWithNullValues.copyOf(ImmutableKit.emptyMap()) + then: + map.isEmpty() + map == ImmutableMapWithNullValues.emptyMap() + + when: + map = ImmutableMapWithNullValues.copyOf(Collections.emptyMap()) + then: + map.isEmpty() + map == ImmutableMapWithNullValues.emptyMap() + } +} diff --git a/src/test/groovy/graphql/config/GraphQLUnusualConfigurationTest.groovy b/src/test/groovy/graphql/config/GraphQLUnusualConfigurationTest.groovy new file mode 100644 index 0000000000..6149e9bb75 --- /dev/null +++ b/src/test/groovy/graphql/config/GraphQLUnusualConfigurationTest.groovy @@ -0,0 +1,212 @@ +package graphql.config + +import graphql.ExecutionInput +import graphql.ExperimentalApi +import graphql.GraphQL +import graphql.GraphQLContext +import graphql.execution.ResponseMapFactory +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys +import graphql.introspection.GoodFaithIntrospection +import graphql.parser.ParserOptions +import graphql.schema.PropertyDataFetcherHelper +import spock.lang.Specification + +import static graphql.parser.ParserOptions.newParserOptions + +class GraphQLUnusualConfigurationTest extends Specification { + + def startingParserOptions = ParserOptions.getDefaultParserOptions() + def startingState = GoodFaithIntrospection.isEnabledJvmWide() + + void cleanup() { + // JVM wide so other tests can be affected + ParserOptions.setDefaultParserOptions(startingParserOptions) + PropertyDataFetcherHelper.setUseNegativeCache(true) + GoodFaithIntrospection.enabledJvmWide(startingState) + } + + def "can set parser configurations"() { + when: + def parserOptions = newParserOptions().maxRuleDepth(99).build() + GraphQL.unusualConfiguration().parsing().setDefaultParserOptions(parserOptions) + def defaultParserOptions = GraphQL.unusualConfiguration().parsing().getDefaultParserOptions() + + then: + defaultParserOptions.getMaxRuleDepth() == 99 + } + + def "can set property data fetcher config"() { + when: + def prevValue = GraphQL.unusualConfiguration().propertyDataFetching().setUseNegativeCache(false) + then: + prevValue + + when: + prevValue = GraphQL.unusualConfiguration().propertyDataFetching().setUseNegativeCache(false) + then: + !prevValue + + when: + prevValue = GraphQL.unusualConfiguration().propertyDataFetching().setUseNegativeCache(true) + then: + !prevValue + } + + def "can set good faith settings"() { + when: + GraphQL.unusualConfiguration().goodFaithIntrospection().enabledJvmWide(false) + + then: + !GraphQL.unusualConfiguration().goodFaithIntrospection().isEnabledJvmWide() + + when: + GraphQL.unusualConfiguration().goodFaithIntrospection().enabledJvmWide(true) + + then: + GraphQL.unusualConfiguration().goodFaithIntrospection().isEnabledJvmWide() + + // showing chaining + when: + GraphQL.unusualConfiguration().goodFaithIntrospection() + .enabledJvmWide(true) + .then().goodFaithIntrospection() + .enabledJvmWide(false) + + then: + !GraphQL.unusualConfiguration().goodFaithIntrospection().isEnabledJvmWide() + } + + def "can set defer configuration on graphql context objects"() { + when: + def graphqlContextBuilder = GraphQLContext.newContext() + GraphQL.unusualConfiguration(graphqlContextBuilder).incrementalSupport().enableIncrementalSupport(true) + + then: + graphqlContextBuilder.build().get(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT) == true + GraphQL.unusualConfiguration(graphqlContextBuilder).incrementalSupport().isIncrementalSupportEnabled() + + when: + graphqlContextBuilder = GraphQLContext.newContext() + GraphQL.unusualConfiguration(graphqlContextBuilder).incrementalSupport().enableIncrementalSupport(false) + + then: + graphqlContextBuilder.build().get(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT) == false + !GraphQL.unusualConfiguration(graphqlContextBuilder).incrementalSupport().isIncrementalSupportEnabled() + + when: + def graphqlContext = GraphQLContext.newContext().build() + GraphQL.unusualConfiguration(graphqlContext).incrementalSupport().enableIncrementalSupport(true) + + then: + graphqlContext.get(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT) == true + GraphQL.unusualConfiguration(graphqlContext).incrementalSupport().isIncrementalSupportEnabled() + + when: + graphqlContext = GraphQLContext.newContext().build() + GraphQL.unusualConfiguration(graphqlContext).incrementalSupport().enableIncrementalSupport(false) + + then: + graphqlContext.get(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT) == false + !GraphQL.unusualConfiguration(graphqlContext).incrementalSupport().isIncrementalSupportEnabled() + + when: + graphqlContext = GraphQLContext.newContext().build() + // just to show we we can navigate the DSL + GraphQL.unusualConfiguration(graphqlContext) + .incrementalSupport() + .enableIncrementalSupport(false) + .enableIncrementalSupport(true) + .then().incrementalSupport() + .enableIncrementalSupport(false) + + then: + graphqlContext.get(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT) == false + !GraphQL.unusualConfiguration(graphqlContext).incrementalSupport().isIncrementalSupportEnabled() + } + + def "can set data loader chaining config for enablement"() { + when: + def graphqlContextBuilder = GraphQLContext.newContext() + GraphQL.unusualConfiguration(graphqlContextBuilder).dataloaderConfig().enableDataLoaderChaining(true) + + then: + graphqlContextBuilder.build().get(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING) == true + GraphQL.unusualConfiguration(graphqlContextBuilder).dataloaderConfig().isDataLoaderChainingEnabled() + + + when: + def graphqlContext = GraphQLContext.newContext().build() + GraphQL.unusualConfiguration(graphqlContext).dataloaderConfig().enableDataLoaderChaining(true) + + then: + graphqlContext.get(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING) == true + GraphQL.unusualConfiguration(graphqlContext).dataloaderConfig().isDataLoaderChainingEnabled() + } + + def "we can access via the ExecutionInput"() { + when: + def eiBuilder = ExecutionInput.newExecutionInput("query q {f}") + + GraphQL.unusualConfiguration(eiBuilder) + .dataloaderConfig() + .enableDataLoaderChaining(true) + + def ei = eiBuilder.build() + + then: + ei.getGraphQLContext().get(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING) == true + + when: + ei = ExecutionInput.newExecutionInput("query q {f}").build() + + GraphQL.unusualConfiguration(ei) + .dataloaderConfig() + .enableDataLoaderChaining(true) + + then: + ei.getGraphQLContext().get(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING) == true + } + + def "can set response map factory"() { + def rfm1 = new ResponseMapFactory() { + @Override + Map createInsertionOrdered(List keys, List values) { + return null + } + } + + def rfm2 = new ResponseMapFactory() { + @Override + Map createInsertionOrdered(List keys, List values) { + return null + } + } + + when: + def graphqlContextBuilder = GraphQLContext.newContext() + GraphQL.unusualConfiguration(graphqlContextBuilder).responseMapFactory().setFactory(rfm1) + + then: + GraphQL.unusualConfiguration(graphqlContextBuilder).responseMapFactory().getOr(rfm2) == rfm1 + + when: + graphqlContextBuilder = GraphQLContext.newContext() + + then: "can default" + GraphQL.unusualConfiguration(graphqlContextBuilder).responseMapFactory().getOr(rfm2) == rfm2 + + when: + def graphqlContext = GraphQLContext.newContext().build() + GraphQL.unusualConfiguration(graphqlContext).responseMapFactory().setFactory(rfm1) + + then: + GraphQL.unusualConfiguration(graphqlContext).responseMapFactory().getOr(rfm2) == rfm1 + + when: + graphqlContext = GraphQLContext.newContext().build() + + then: "can default" + GraphQL.unusualConfiguration(graphqlContext).responseMapFactory().getOr(rfm2) == rfm2 + + } +} diff --git a/src/test/groovy/graphql/execution/AbortExecutionExceptionTest.groovy b/src/test/groovy/graphql/execution/AbortExecutionExceptionTest.groovy index 64a4cfcdbd..da2c9b8cc4 100644 --- a/src/test/groovy/graphql/execution/AbortExecutionExceptionTest.groovy +++ b/src/test/groovy/graphql/execution/AbortExecutionExceptionTest.groovy @@ -1,10 +1,24 @@ package graphql.execution import graphql.ErrorType +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.GraphQL import graphql.GraphQLError +import graphql.TestUtil +import graphql.execution.instrumentation.Instrumentation +import graphql.execution.instrumentation.InstrumentationContext +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters import graphql.language.SourceLocation +import graphql.validation.ValidationError import spock.lang.Specification +import java.util.concurrent.CompletableFuture + class AbortExecutionExceptionTest extends Specification { class BasicError implements GraphQLError { @@ -26,7 +40,7 @@ class AbortExecutionExceptionTest extends Specification { } } - def "to excution result handling"() { + def "to execution result handling"() { AbortExecutionException e when: e = new AbortExecutionException("No underlying errors") @@ -35,10 +49,73 @@ class AbortExecutionExceptionTest extends Specification { e.toExecutionResult().getErrors()[0].message == "No underlying errors" when: - e = new AbortExecutionException([new BasicError(message:"UnderlyingA"), new BasicError(message:"UnderlyingB")]) + e = new AbortExecutionException([new BasicError(message: "UnderlyingA"), new BasicError(message: "UnderlyingB")]) then: e.toExecutionResult().getErrors().size() == 2 e.toExecutionResult().getErrors()[0].message == "UnderlyingA" e.toExecutionResult().getErrors()[1].message == "UnderlyingB" } + + def "will call instrumentation.instrumentExecutionResult() at the end"() { + def sdl = """ + type Query { + q : Q + } + + type Q { + name : String + } + """ + + + def schema = TestUtil.schema(sdl) + + def throwOnEarlyPhase = true + Instrumentation instrumentation = new SimplePerformantInstrumentation() { + @Override + InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + if (throwOnEarlyPhase) { + throw new AbortExecutionException("early") + } + return super.beginValidation(parameters, state) + } + + @Override + InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + if (!throwOnEarlyPhase) { + throw new AbortExecutionException("later") + } + return super.beginExecuteOperation(parameters, state) + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + def newER = executionResult.transform { it.extensions([extra: "extensions"]) } + return CompletableFuture.completedFuture(newER) + } + } + def graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + + def executionInput = ExecutionInput.newExecutionInput("query q { q {name}}") + .root([q: [name: "nameV"]]) + .build() + + when: + def er = graphQL.execute(executionInput) + + then: + !er.errors.isEmpty() + er.errors[0].message == "early" + er.extensions == [extra: "extensions"] + + when: + throwOnEarlyPhase = false + er = graphQL.execute(executionInput) + + then: + !er.errors.isEmpty() + er.errors[0].message == "later" + er.extensions == [extra: "extensions"] + } } diff --git a/src/test/groovy/graphql/execution/AbsoluteGraphQLErrorTest.groovy b/src/test/groovy/graphql/execution/AbsoluteGraphQLErrorTest.groovy deleted file mode 100644 index 6d8ca3721d..0000000000 --- a/src/test/groovy/graphql/execution/AbsoluteGraphQLErrorTest.groovy +++ /dev/null @@ -1,181 +0,0 @@ -package graphql.execution - -import graphql.DataFetchingErrorGraphQLError -import graphql.language.Field -import graphql.language.SourceLocation -import spock.lang.Specification - -import static graphql.Scalars.GraphQLString -import static graphql.execution.ExecutionStrategyParameters.newParameters -import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition -import static graphql.schema.GraphQLObjectType.newObject - -class AbsoluteGraphQLErrorTest extends Specification { - - def fieldDefinition = newFieldDefinition() - .name("someField") - .type(GraphQLString) - .build() - def objectType = newObject() - .name("Test") - .field(fieldDefinition) - .build() - - def "constructor works as expected"() { - given: - - def field = Field.newField().name("test").sourceLocation(new SourceLocation(4, 5)).build() - - def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) - .source(new Object()) - .fields(["fld": [Field.newField().build()]]) - .field([field]) - .path(ExecutionPath.fromList(["foo", "bar"])) - .build() - - def relativeError = new DataFetchingErrorGraphQLError("blah", ["fld"]) { - @Override - Map getExtensions() { - return ["ext": true] - } - } - - when: - - def error = new AbsoluteGraphQLError(parameters, relativeError) - - then: - - error.getMessage() == "blah" - error.getPath() == ["foo", "bar", "fld"] - error.getLocations().size() == 1 - error.getLocations().get(0).getColumn() == 15 - error.getLocations().get(0).getLine() == 6 - error.getErrorType() == relativeError.getErrorType() - error.getExtensions() == ["ext": true] - } - - def "constructor handles missing path as null"() { - given: - - def field = Field.newField().name("test").sourceLocation(new SourceLocation(4, 5)).build() - - def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) - .source(new Object()) - .fields(["fld": [Field.newField().build()]]) - .field([field]) - .path(ExecutionPath.fromList(["foo", "bar"])) - .build() - - def relativeError = new DataFetchingErrorGraphQLError("blah") - - when: - - def error = new AbsoluteGraphQLError(parameters, relativeError) - - then: - - error.getPath() == null - } - - def "when constructor receives empty path it should return the base field path"() { - given: - - def field = Field.newField().name("test").sourceLocation(new SourceLocation(4, 5)).build() - - def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) - .source(new Object()) - .fields(["fld": [Field.newField().build()]]) - .field([field]) - .path(ExecutionPath.fromList(["foo", "bar"])) - .build() - - def relativeError = new DataFetchingErrorGraphQLError("blah") - relativeError.path = [] - - when: - - def error = new AbsoluteGraphQLError(parameters, relativeError) - - then: - - error.getPath() == ["foo", "bar"] - } - - def "constructor handles missing locations as null"() { - given: - - def field = Field.newField().name("test").build() - - def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) - .source(new Object()) - .fields(["fld": [Field.newField().build()]]) - .field([field]) - .path(ExecutionPath.fromList(["foo", "bar"])) - .build() - - def relativeError = new DataFetchingErrorGraphQLError("blah") - - when: - - def error = new AbsoluteGraphQLError(parameters, relativeError) - - then: - - error.getLocations() == null - } - - def "when constructor receives empty locations it should return the base field locations"() { - given: - - def expectedSourceLocation = new SourceLocation(1, 2) - def field = Field.newField().name("test").sourceLocation(expectedSourceLocation).build() - - def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) - .source(new Object()) - .fields(["fld": [Field.newField().build()]]) - .field([field]) - .path(ExecutionPath.fromList(["foo", "bar"])) - .build() - - def relativeError = new DataFetchingErrorGraphQLError("blah") - relativeError.locations = [] - - when: - def error = new AbsoluteGraphQLError(parameters, relativeError) - - then: - - error.getLocations() == [expectedSourceLocation] - } - - def "constructor transforms multiple source locations"() { - given: - - def field = Field.newField().name("test").sourceLocation(new SourceLocation(4, 5)).build() - - def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) - .source(new Object()) - .fields(["fld": [Field.newField().build()]]) - .field([field]) - .path(ExecutionPath.fromList(["foo", "bar"])) - .build() - - def relativeError = new DataFetchingErrorGraphQLError("blah", ["fld"]) - relativeError.locations = [new SourceLocation(1, 5), new SourceLocation(3, 6)] - - when: - - def error = new AbsoluteGraphQLError(parameters, relativeError) - - then: - - error.getLocations() == [new SourceLocation(5, 10), new SourceLocation(7, 11)] - } -} diff --git a/src/test/groovy/graphql/execution/AsyncExecutionStrategyTest.groovy b/src/test/groovy/graphql/execution/AsyncExecutionStrategyTest.groovy index 6aaeb86274..0c66a30e18 100644 --- a/src/test/groovy/graphql/execution/AsyncExecutionStrategyTest.groovy +++ b/src/test/groovy/graphql/execution/AsyncExecutionStrategyTest.groovy @@ -1,14 +1,21 @@ package graphql.execution +import graphql.EngineRunningState import graphql.ErrorType +import graphql.ExecutionInput import graphql.ExecutionResult +import graphql.GraphQLContext +import graphql.Profiler import graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters import graphql.language.Field import graphql.language.OperationDefinition import graphql.parser.Parser import graphql.schema.DataFetcher +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLSchema import spock.lang.Specification @@ -18,34 +25,56 @@ import java.util.concurrent.CompletionException import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.locks.ReentrantLock +import static graphql.ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mergedField +import static graphql.TestUtil.mergedSelectionSet import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLObjectType.newObject import static graphql.schema.GraphQLSchema.newSchema import static org.awaitility.Awaitility.await -class AsyncExecutionStrategyTest extends Specification { +abstract class AsyncExecutionStrategyTest extends Specification { + static boolean incrementalSupport + + def graphqlContextMock = Mock(GraphQLContext) GraphQLSchema schema(DataFetcher dataFetcher1, DataFetcher dataFetcher2) { - GraphQLFieldDefinition.Builder fieldDefinition = newFieldDefinition() - .name("hello") + def queryName = "RootQueryType" + def field1Name = "hello" + def field2Name = "hello2" + + GraphQLFieldDefinition.Builder fieldDefinition1 = newFieldDefinition() + .name(field1Name) .type(GraphQLString) - .dataFetcher(dataFetcher1) GraphQLFieldDefinition.Builder fieldDefinition2 = newFieldDefinition() - .name("hello2") + .name(field2Name) .type(GraphQLString) - .dataFetcher(dataFetcher2) - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field(fieldDefinition) + def field1Coordinates = FieldCoordinates.coordinates(queryName, field1Name) + def field2Coordinates = FieldCoordinates.coordinates(queryName, field2Name) + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(field1Coordinates, dataFetcher1) + .dataFetcher(field2Coordinates, dataFetcher2) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryName) + .field(fieldDefinition1) .field(fieldDefinition2) .build() - ).build() + ) + .build() + schema } + def setup() { + graphqlContextMock.get(ENABLE_INCREMENTAL_SUPPORT) >> incrementalSupport + } def "execution is serial if the dataFetchers are blocking"() { given: @@ -70,20 +99,28 @@ class AsyncExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(SimpleInstrumentation.INSTANCE) + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .valueUnboxer(ValueUnboxer.DEFAULT) + .graphQLContext(graphqlContextMock) + .executionInput(ei) + .locale(Locale.getDefault()) + .profiler(Profiler.NO_OP) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [Field.newField('hello').build()], 'hello2': [Field.newField('hello2').build()]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField([Field.newField('hello').build()]), 'hello2': mergedField([Field.newField('hello2').build()])])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncExecutionStrategy asyncExecutionStrategy = new AsyncExecutionStrategy() @@ -108,20 +145,28 @@ class AsyncExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(SimpleInstrumentation.INSTANCE) + .valueUnboxer(ValueUnboxer.DEFAULT) + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .locale(Locale.getDefault()) + .graphQLContext(graphqlContextMock) + .executionInput(ei) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) + .profiler(Profiler.NO_OP) .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [Field.newField('hello').build()], 'hello2': [Field.newField('hello2').build()]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField([Field.newField('hello').build()]), 'hello2': mergedField([Field.newField('hello2').build()])])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncExecutionStrategy asyncExecutionStrategy = new AsyncExecutionStrategy() @@ -148,20 +193,28 @@ class AsyncExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(SimpleInstrumentation.INSTANCE) + .valueUnboxer(ValueUnboxer.DEFAULT) + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .graphQLContext(graphqlContextMock) + .executionInput(ei) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) + .locale(Locale.getDefault()) + .profiler(Profiler.NO_OP) .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [Field.newField('hello').build()], 'hello2': [Field.newField('hello2').build()]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField([Field.newField('hello').build()]), 'hello2': mergedField([Field.newField('hello2').build()])])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncExecutionStrategy asyncExecutionStrategy = new AsyncExecutionStrategy() @@ -187,20 +240,28 @@ class AsyncExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(SimpleInstrumentation.INSTANCE) + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .valueUnboxer(ValueUnboxer.DEFAULT) + .locale(Locale.getDefault()) + .graphQLContext(graphqlContextMock) + .executionInput(ei) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) + .profiler(Profiler.NO_OP) .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [Field.newField('hello').build()], 'hello2': [Field.newField('hello2').build()]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField([Field.newField('hello').build()]), 'hello2': mergedField([Field.newField('hello2').build()])])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncExecutionStrategy asyncExecutionStrategy = new AsyncExecutionStrategy() @@ -225,17 +286,25 @@ class AsyncExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(new SimpleInstrumentation() { + .valueUnboxer(ValueUnboxer.DEFAULT) + .graphQLContext(graphqlContextMock) + .executionInput(ei) + .locale(Locale.getDefault()) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) + .profiler(Profiler.NO_OP) + .instrumentation(new SimplePerformantInstrumentation() { + @Override - ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { return new ExecutionStrategyInstrumentationContext() { @Override @@ -244,13 +313,11 @@ class AsyncExecutionStrategyTest extends Specification { } @Override - public void onDispatched(CompletableFuture result) { - + void onDispatched() { } @Override - public void onCompleted(ExecutionResult result, Throwable t) { - + void onCompleted(ExecutionResult result, Throwable t) { } } } @@ -258,8 +325,9 @@ class AsyncExecutionStrategyTest extends Specification { .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [new Field('hello')], 'hello2': [new Field('hello2')]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField([new Field('hello')]), 'hello2': mergedField([new Field('hello2')])])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncExecutionStrategy asyncExecutionStrategy = new AsyncExecutionStrategy() @@ -279,3 +347,15 @@ class AsyncExecutionStrategyTest extends Specification { } + +class AsyncExecutionStrategyTestWithIncrementalSupport extends AsyncExecutionStrategyTest { + static { + incrementalSupport = true + } +} + +class AsyncExecutionStrategyTestNoIncrementalSupport extends AsyncExecutionStrategyTest { + static { + incrementalSupport = false + } +} diff --git a/src/test/groovy/graphql/execution/AsyncSerialExecutionStrategyTest.groovy b/src/test/groovy/graphql/execution/AsyncSerialExecutionStrategyTest.groovy index dc6a323667..6089e75a88 100644 --- a/src/test/groovy/graphql/execution/AsyncSerialExecutionStrategyTest.groovy +++ b/src/test/groovy/graphql/execution/AsyncSerialExecutionStrategyTest.groovy @@ -1,12 +1,19 @@ package graphql.execution -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.EngineRunningState +import graphql.ExecutionInput +import graphql.GraphQLContext +import graphql.Profiler +import graphql.execution.instrumentation.SimplePerformantInstrumentation import graphql.language.Field import graphql.language.OperationDefinition import graphql.parser.Parser import graphql.schema.DataFetcher +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLSchema +import graphql.schema.LightDataFetcher import spock.lang.Specification import java.util.concurrent.CompletableFuture @@ -14,33 +21,50 @@ import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.locks.ReentrantLock import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mergedField +import static graphql.TestUtil.mergedSelectionSet import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLObjectType.newObject import static graphql.schema.GraphQLSchema.newSchema class AsyncSerialExecutionStrategyTest extends Specification { GraphQLSchema schema(DataFetcher dataFetcher1, DataFetcher dataFetcher2, DataFetcher dataFetcher3) { - GraphQLFieldDefinition.Builder fieldDefinition = newFieldDefinition() - .name("hello") + def queryName = "RootQueryType" + def field1Name = "hello" + def field2Name = "hello2" + def field3Name = "hello3" + + GraphQLFieldDefinition.Builder fieldDefinition1 = newFieldDefinition() + .name(field1Name) .type(GraphQLString) - .dataFetcher(dataFetcher1) GraphQLFieldDefinition.Builder fieldDefinition2 = newFieldDefinition() - .name("hello2") + .name(field2Name) .type(GraphQLString) - .dataFetcher(dataFetcher2) GraphQLFieldDefinition.Builder fieldDefinition3 = newFieldDefinition() - .name("hello3") + .name(field3Name) .type(GraphQLString) - .dataFetcher(dataFetcher3) - GraphQLSchema schema = newSchema().query( - newObject() - .name("RootQueryType") - .field(fieldDefinition) + def field1Coordinates = FieldCoordinates.coordinates(queryName, field1Name) + def field2Coordinates = FieldCoordinates.coordinates(queryName, field2Name) + def field3Coordinates = FieldCoordinates.coordinates(queryName, field3Name) + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(field1Coordinates, dataFetcher1) + .dataFetcher(field2Coordinates, dataFetcher2) + .dataFetcher(field3Coordinates, dataFetcher3) + .build() + + GraphQLSchema schema = newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name(queryName) + .field(fieldDefinition1) .field(fieldDefinition2) .field(fieldDefinition3) .build() - ).build() + ) + .build() + schema } @@ -73,20 +97,29 @@ class AsyncSerialExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(SimpleInstrumentation.INSTANCE) + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .valueUnboxer(ValueUnboxer.DEFAULT) + .locale(Locale.getDefault()) + .graphQLContext(GraphQLContext.getDefault()) + .executionInput(ExecutionInput.newExecutionInput("{}").build()) + .profiler(Profiler.NO_OP) + .executionInput(ei) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [new Field('hello')], 'hello2': [new Field('hello2')], 'hello3': [new Field('hello3')]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField(new Field('hello')), 'hello2': mergedField(new Field('hello2')), 'hello3': mergedField(new Field('hello3'))])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncSerialExecutionStrategy strategy = new AsyncSerialExecutionStrategy() @@ -102,13 +135,13 @@ class AsyncSerialExecutionStrategyTest extends Specification { @SuppressWarnings("GroovyAssignabilityCheck") def "async serial execution test"() { given: - def df1 = Mock(DataFetcher) + def df1 = Mock(LightDataFetcher) def cf1 = new CompletableFuture() - def df2 = Mock(DataFetcher) + def df2 = Mock(LightDataFetcher) def cf2 = new CompletableFuture() - def df3 = Mock(DataFetcher) + def df3 = Mock(LightDataFetcher) def cf3 = new CompletableFuture() GraphQLSchema schema = schema(df1, df2, df3) @@ -116,20 +149,29 @@ class AsyncSerialExecutionStrategyTest extends Specification { def document = new Parser().parseDocument(query) def operation = document.definitions[0] as OperationDefinition - def typeInfo = ExecutionTypeInfo.newTypeInfo() + def typeInfo = ExecutionStepInfo.newExecutionStepInfo() .type(schema.getQueryType()) .build() + def ei = ExecutionInput.newExecutionInput("{}").build() ExecutionContext executionContext = new ExecutionContextBuilder() .graphQLSchema(schema) .executionId(ExecutionId.generate()) .operationDefinition(operation) - .instrumentation(SimpleInstrumentation.INSTANCE) + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .valueUnboxer(ValueUnboxer.DEFAULT) + .locale(Locale.getDefault()) + .graphQLContext(GraphQLContext.getDefault()) + .executionInput(ei) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) + .executionInput(ExecutionInput.newExecutionInput("{}").build()) + .profiler(Profiler.NO_OP) .build() ExecutionStrategyParameters executionStrategyParameters = ExecutionStrategyParameters .newParameters() - .typeInfo(typeInfo) - .fields(['hello': [new Field('hello')], 'hello2': [new Field('hello2')], 'hello3': [new Field('hello3')]]) + .executionStepInfo(typeInfo) + .fields(mergedSelectionSet(['hello': mergedField(new Field('hello')), 'hello2': mergedField(new Field('hello2')), 'hello3': mergedField(new Field('hello3'))])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) .build() AsyncSerialExecutionStrategy strategy = new AsyncSerialExecutionStrategy() @@ -139,35 +181,35 @@ class AsyncSerialExecutionStrategyTest extends Specification { then: !result.isDone() - 1 * df1.get(_) >> cf1 - 0 * df2.get(_) >> cf2 - 0 * df3.get(_) >> cf3 + 1 * df1.get(_, _, _) >> cf1 + 0 * df2.get(_, _, _) >> cf2 + 0 * df3.get(_, _, _) >> cf3 when: cf1.complete("world1") then: !result.isDone() - 0 * df1.get(_) >> cf1 - 1 * df2.get(_) >> cf2 - 0 * df3.get(_) >> cf3 + 0 * df1.get(_, _, _) >> cf1 + 1 * df2.get(_, _, _) >> cf2 + 0 * df3.get(_, _, _) >> cf3 when: cf2.complete("world2") then: !result.isDone() - 0 * df1.get(_) >> cf1 - 0 * df2.get(_) >> cf2 - 1 * df3.get(_) >> cf3 + 0 * df1.get(_, _, _) >> cf1 + 0 * df2.get(_, _, _) >> cf2 + 1 * df3.get(_, _, _) >> cf3 when: cf3.complete("world3") then: - 0 * df1.get(_) >> cf1 - 0 * df2.get(_) >> cf2 - 0 * df3.get(_) >> cf3 + 0 * df1.get(_, _, _) >> cf1 + 0 * df2.get(_, _, _) >> cf2 + 0 * df3.get(_, _, _) >> cf3 result.isDone() result.get().data == ['hello': 'world1', 'hello2': 'world2', 'hello3': 'world3'] } diff --git a/src/test/groovy/graphql/execution/AsyncTest.groovy b/src/test/groovy/graphql/execution/AsyncTest.groovy index 1ac9650ef8..2661c4f5fd 100644 --- a/src/test/groovy/graphql/execution/AsyncTest.groovy +++ b/src/test/groovy/graphql/execution/AsyncTest.groovy @@ -1,3 +1,4 @@ +//file:noinspection GroovyVariableNotAssigned package graphql.execution import spock.lang.Specification @@ -5,6 +6,7 @@ import spock.lang.Specification import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionException import java.util.function.BiFunction +import java.util.function.Function import static java.util.concurrent.CompletableFuture.completedFuture @@ -13,7 +15,7 @@ class AsyncTest extends Specification { def "eachSequentially test"() { given: def input = ['a', 'b', 'c'] - def cfFactory = Mock(Async.CFFactory) + def cfFactory = Mock(BiFunction) def cf1 = new CompletableFuture() def cf2 = new CompletableFuture() def cf3 = new CompletableFuture() @@ -23,21 +25,21 @@ class AsyncTest extends Specification { then: !result.isDone() - 1 * cfFactory.apply('a', 0, []) >> cf1 + 1 * cfFactory.apply('a', []) >> cf1 when: cf1.complete('x') then: !result.isDone() - 1 * cfFactory.apply('b', 1, ['x']) >> cf2 + 1 * cfFactory.apply('b', ['x']) >> cf2 when: cf2.complete('y') then: !result.isDone() - 1 * cfFactory.apply('c', 2, ['x', 'y']) >> cf3 + 1 * cfFactory.apply('c', ['x', 'y']) >> cf3 when: cf3.complete('z') @@ -47,12 +49,49 @@ class AsyncTest extends Specification { result.get() == ['x', 'y', 'z'] } + def "eachSequentially polymorphic test"() { + given: + def input = ['a', 'b', 'c', 'd'] + def cfFactory = Mock(BiFunction) + def cf1 = new CompletableFuture() + def v2 = 'y' + def cf3 = new CompletableFuture() + + when: + def result = Async.eachSequentially(input, cfFactory) + + then: + !result.isDone() + 1 * cfFactory.apply('a', []) >> cf1 + + when: + cf1.complete('x') + + then: + !result.isDone() + 1 * cfFactory.apply('b', ['x']) >> v2 + + when: + + then: + !result.isDone() + 1 * cfFactory.apply('c', ['x', 'y']) >> cf3 + + when: + cf3.complete(null) // null valued CFS are allowed + + then: + 1 * cfFactory.apply('d', ['x', 'y', null]) >> null // nulls are allowed as values + result.isDone() + result.get() == ['x', 'y', null, null] + } + def "eachSequentially propagates exception"() { given: def input = ['a', 'b', 'c'] - def cfFactory = Mock(Async.CFFactory) - cfFactory.apply('a', 0, _) >> completedFuture("x") - cfFactory.apply('b', 1, _) >> { + def cfFactory = Mock(BiFunction) + cfFactory.apply('a', _) >> completedFuture("x") + cfFactory.apply('b', _) >> { def cf = new CompletableFuture<>() cf.completeExceptionally(new RuntimeException("some error")) cf @@ -74,9 +113,9 @@ class AsyncTest extends Specification { def "eachSequentially catches factory exception"() { given: def input = ['a', 'b', 'c'] - def cfFactory = Mock(Async.CFFactory) - cfFactory.apply('a', 0, _) >> completedFuture("x") - cfFactory.apply('b', 1, _) >> { throw new RuntimeException("some error") } + def cfFactory = Mock(BiFunction) + cfFactory.apply('a', _) >> completedFuture("x") + cfFactory.apply('b', _) >> { throw new RuntimeException("some error") } when: def result = Async.eachSequentially(input, cfFactory) @@ -94,10 +133,10 @@ class AsyncTest extends Specification { def "each works for mapping function"() { given: def input = ['a', 'b', 'c'] - def cfFactory = Mock(BiFunction) - cfFactory.apply('a', 0) >> completedFuture('x') - cfFactory.apply('b', 1) >> completedFuture('y') - cfFactory.apply('c', 2) >> completedFuture('z') + def cfFactory = Mock(Function) + cfFactory.apply('a') >> completedFuture('x') + cfFactory.apply('b') >> completedFuture('y') + cfFactory.apply('c') >> completedFuture('z') when: @@ -108,19 +147,70 @@ class AsyncTest extends Specification { result.get() == ['x', 'y', 'z'] } - def "each with mapping function propagates factory exception"() { + def "each works for mapping function with polymorphic values"() { given: def input = ['a', 'b', 'c'] - def cfFactory = Mock(BiFunction) + def cfFactory = Mock(Function) + cfFactory.apply('a') >> completedFuture('x') + cfFactory.apply('b') >> 'y' + cfFactory.apply('c') >> completedFuture('z') when: def result = Async.each(input, cfFactory) then: - 1 * cfFactory.apply('a', 0) >> completedFuture('x') - 1 * cfFactory.apply('b', 1) >> { throw new RuntimeException('some error') } - 1 * cfFactory.apply('c', 2) >> completedFuture('z') + result.isDone() + result.get() == ['x', 'y', 'z'] + } + + def "eachPolymorphic works for mapping function with polymorphic values"() { + given: + def input = ['a', 'b', 'c'] + def cfFactory = Mock(Function) + cfFactory.apply('a') >> completedFuture('x') + cfFactory.apply('b') >> 'y' + cfFactory.apply('c') >> completedFuture('z') + + + when: + def result = Async.eachPolymorphic(input, cfFactory) + + then: + result instanceof CompletableFuture + (result as CompletableFuture).isDone() + (result as CompletableFuture).get() == ['x', 'y', 'z'] + } + + def "eachPolymorphic works for mapping function with materialised values"() { + given: + def input = ['a', 'b', 'c'] + def cfFactory = Mock(Function) + cfFactory.apply('a') >> 'x' + cfFactory.apply('b') >> 'y' + cfFactory.apply('c') >> 'z' + + + when: + def result = Async.eachPolymorphic(input, cfFactory) + + then: + result instanceof List + result == ['x', 'y', 'z'] + } + + def "each with mapping function propagates factory exception"() { + given: + def input = ['a', 'b', 'c'] + def cfFactory = Mock(Function) + + when: + def result = Async.each(input, cfFactory) + + then: + 1 * cfFactory.apply('a') >> completedFuture('x') + 1 * cfFactory.apply('b') >> { throw new RuntimeException('some error') } + 1 * cfFactory.apply('c') >> completedFuture('z') result.isCompletedExceptionally() Throwable exception result.exceptionally({ e -> @@ -130,15 +220,205 @@ class AsyncTest extends Specification { exception.getCause().getMessage() == "some error" } - def "each works for list of futures "() { - given: - completedFuture('x') + + def "can wait on objects of cfs or both"() { + when: + def asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.add(completedFuture("0")) + asyncBuilder.add(completedFuture("1")) + asyncBuilder.addObject("2") + asyncBuilder.addObject("3") + asyncBuilder.add(completedFuture("4")) + + def list = asyncBuilder.await().join() + + then: + list == ["0", "1", "2", "3", "4"] when: - def result = Async.each([completedFuture('x'), completedFuture('y'), completedFuture('z')]) + asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.add(completedFuture("0")) + asyncBuilder.add(completedFuture("1")) + asyncBuilder.add(completedFuture("2")) + asyncBuilder.add(completedFuture("3")) + asyncBuilder.add(completedFuture("4")) + + list = asyncBuilder.await().join() then: - result.isDone() - result.get() == ['x', 'y', 'z'] + list == ["0", "1", "2", "3", "4"] + + when: + asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.addObject("0") + asyncBuilder.addObject("1") + asyncBuilder.addObject("2") + asyncBuilder.addObject("3") + asyncBuilder.addObject("4") + + list = asyncBuilder.await().join() + + then: + list == ["0", "1", "2", "3", "4"] + + when: "it has a mix of CFs and objects" + asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.addObject("0") + asyncBuilder.addObject("1") + asyncBuilder.add(completedFuture("2")) + asyncBuilder.addObject("3") + asyncBuilder.addObject(completedFuture("4")) + + list = asyncBuilder.await().join() + + then: + list == ["0", "1", "2", "3", "4"] + } + + def "can wait on objects of cfs or both with empty or single values"() { + when: + def asyncBuilder = Async.ofExpectedSize(0) + def list = asyncBuilder.await().join() + + then: + list == [] + + when: + asyncBuilder = Async.ofExpectedSize(1) + asyncBuilder.add(completedFuture("A")) + list = asyncBuilder.await().join() + + then: + list == ["A"] + + when: + asyncBuilder = Async.ofExpectedSize(1) + asyncBuilder.addObject(completedFuture("A")) + list = asyncBuilder.await().join() + + then: + list == ["A"] + + when: + asyncBuilder = Async.ofExpectedSize(1) + asyncBuilder.addObject("A") + list = asyncBuilder.await().join() + + then: + list == ["A"] + } + + def "await polymorphic works as expected"() { + + when: + def asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.add(completedFuture("0")) + asyncBuilder.add(completedFuture("1")) + asyncBuilder.addObject("2") + asyncBuilder.addObject("3") + asyncBuilder.add(completedFuture("4")) + + def awaited = asyncBuilder.awaitPolymorphic() + + then: + awaited instanceof CompletableFuture + joinOrMaterialized(awaited) == ["0", "1", "2", "3", "4"] + + when: + asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.addObject(completedFuture("0")) + asyncBuilder.addObject(completedFuture("1")) + asyncBuilder.addObject(completedFuture("2")) + asyncBuilder.addObject(completedFuture("3")) + asyncBuilder.addObject(completedFuture("4")) + + awaited = asyncBuilder.awaitPolymorphic() + + then: + awaited instanceof CompletableFuture + joinOrMaterialized(awaited) == ["0", "1", "2", "3", "4"] + + when: + asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.addObject("0") + asyncBuilder.addObject("1") + asyncBuilder.addObject("2") + asyncBuilder.addObject("3") + asyncBuilder.addObject("4") + + awaited = asyncBuilder.awaitPolymorphic() + + then: + !(awaited instanceof CompletableFuture) + joinOrMaterialized(awaited) == ["0", "1", "2", "3", "4"] + + when: + asyncBuilder = Async.ofExpectedSize(0) + + awaited = asyncBuilder.awaitPolymorphic() + + then: + !(awaited instanceof CompletableFuture) + joinOrMaterialized(awaited) == [] + + when: + asyncBuilder = Async.ofExpectedSize(1) + asyncBuilder.addObject("A") + + awaited = asyncBuilder.awaitPolymorphic() + + then: + !(awaited instanceof CompletableFuture) + joinOrMaterialized(awaited) == ["A"] + + when: + asyncBuilder = Async.ofExpectedSize(1) + asyncBuilder.addObject(completedFuture("A")) + + awaited = asyncBuilder.awaitPolymorphic() + + then: + awaited instanceof CompletableFuture + joinOrMaterialized(awaited) == ["A"] + } + + def "await polymorphic works as expected with nulls"() { + + when: + def asyncBuilder = Async.ofExpectedSize(5) + asyncBuilder.add(completedFuture("0")) + asyncBuilder.add(completedFuture(null)) + asyncBuilder.addObject("2") + asyncBuilder.addObject(null) + asyncBuilder.add(completedFuture("4")) + + def awaited = asyncBuilder.awaitPolymorphic() + + then: + awaited instanceof CompletableFuture + joinOrMaterialized(awaited) == ["0", null, "2", null, "4"] + } + + def "toCompletableFutureOrMaterializedObject tested"() { + def x = "x" + def cf = completedFuture(x) + + when: + def object = Async.toCompletableFutureOrMaterializedObject(x) + then: + object == x + + when: + object = Async.toCompletableFutureOrMaterializedObject(cf) + then: + object == cf + } + + Object joinOrMaterialized(Object awaited) { + if (awaited instanceof CompletableFuture) { + return ((CompletableFuture) awaited).join() + } else { + return awaited + } } } diff --git a/src/test/groovy/graphql/execution/BreadthFirstExecutionTestStrategy.java b/src/test/groovy/graphql/execution/BreadthFirstExecutionTestStrategy.java index d6c1cd1fd4..c110f04947 100644 --- a/src/test/groovy/graphql/execution/BreadthFirstExecutionTestStrategy.java +++ b/src/test/groovy/graphql/execution/BreadthFirstExecutionTestStrategy.java @@ -3,10 +3,8 @@ import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.Internal; -import graphql.language.Field; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -22,7 +20,7 @@ public BreadthFirstExecutionTestStrategy() { @Override public CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { - Map> fields = parameters.getFields(); + MergedSelectionSet fields = parameters.getFields(); Map fetchedValues = new LinkedHashMap<>(); @@ -35,10 +33,10 @@ public CompletableFuture execute(ExecutionContext executionCont // then for every fetched value, complete it Map results = new LinkedHashMap<>(); for (String fieldName : fetchedValues.keySet()) { - List currentField = fields.get(fieldName); + MergedField currentField = fields.getSubField(fieldName); Object fetchedValue = fetchedValues.get(fieldName); - ExecutionPath fieldPath = parameters.getPath().segment(fieldName); + ResultPath fieldPath = parameters.getPath().segment(fieldName); ExecutionStrategyParameters newParameters = parameters .transform(builder -> builder.field(currentField).path(fieldPath)); @@ -53,19 +51,19 @@ public CompletableFuture execute(ExecutionContext executionCont return CompletableFuture.completedFuture(new ExecutionResultImpl(results, executionContext.getErrors())); } - private Object fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Map> fields, String fieldName) { - List currentField = fields.get(fieldName); + private Object fetchField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, MergedSelectionSet fields, String fieldName) { + MergedField currentField = fields.getSubField(fieldName); - ExecutionPath fieldPath = parameters.getPath().segment(fieldName); + ResultPath fieldPath = parameters.getPath().segment(fieldName); ExecutionStrategyParameters newParameters = parameters .transform(builder -> builder.field(currentField).path(fieldPath)); - return fetchField(executionContext, newParameters).join(); + return Async.toCompletableFuture(fetchField(executionContext, newParameters)).join(); } private void completeValue(ExecutionContext executionContext, Map results, String fieldName, Object fetchedValue, ExecutionStrategyParameters newParameters) { - ExecutionResult resolvedResult = completeField(executionContext, newParameters, fetchedValue).getFieldValue().join(); - results.put(fieldName, resolvedResult != null ? resolvedResult.getData() : null); + Object resolvedResult = completeField(executionContext, newParameters, fetchedValue).getFieldValueFuture().join(); + results.put(fieldName, resolvedResult); } } diff --git a/src/test/groovy/graphql/execution/BreadthFirstTestStrategy.java b/src/test/groovy/graphql/execution/BreadthFirstTestStrategy.java index a4cb4c4e60..54b5e57898 100644 --- a/src/test/groovy/graphql/execution/BreadthFirstTestStrategy.java +++ b/src/test/groovy/graphql/execution/BreadthFirstTestStrategy.java @@ -3,7 +3,6 @@ import graphql.ExecutionResult; import graphql.ExecutionResultImpl; import graphql.Internal; -import graphql.language.Field; import java.util.Collection; import java.util.LinkedHashMap; @@ -34,7 +33,7 @@ public CompletableFuture execute(ExecutionContext executionCont } private Map fetchFields(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { - Map> fields = parameters.getFields(); + MergedSelectionSet fields = parameters.getFields(); Map> fetchFutures = new LinkedHashMap<>(); @@ -42,7 +41,7 @@ private Map fetchFields(ExecutionContext executionContext, Execu for (String fieldName : fields.keySet()) { ExecutionStrategyParameters newParameters = newParameters(parameters, fields, fieldName); - CompletableFuture fetchFuture = fetchField(executionContext, newParameters); + CompletableFuture fetchFuture = Async.toCompletableFuture(fetchField(executionContext, newParameters)); fetchFutures.put(fieldName, fetchFuture); } @@ -55,19 +54,17 @@ private Map fetchFields(ExecutionContext executionContext, Execu } private CompletableFuture completeFields(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Map fetchedValues) { - Map> fields = parameters.getFields(); + MergedSelectionSet fields = parameters.getFields(); // then for every fetched value, complete it, breath first Map results = new LinkedHashMap<>(); for (String fieldName : fetchedValues.keySet()) { - List fieldList = fields.get(fieldName); - ExecutionStrategyParameters newParameters = newParameters(parameters, fields, fieldName); Object fetchedValue = fetchedValues.get(fieldName); try { - ExecutionResult resolvedResult = completeField(executionContext, newParameters, fetchedValue).getFieldValue().join(); - results.put(fieldName, resolvedResult != null ? resolvedResult.getData() : null); + Object resolvedResult = completeField(executionContext, newParameters, fetchedValue).getFieldValueFuture().join(); + results.put(fieldName, resolvedResult); } catch (NonNullableFieldWasNullException e) { assertNonNullFieldPrecondition(e); results = null; @@ -77,16 +74,16 @@ private CompletableFuture completeFields(ExecutionContext execu return CompletableFuture.completedFuture(new ExecutionResultImpl(results, executionContext.getErrors())); } - private ExecutionStrategyParameters newParameters(ExecutionStrategyParameters parameters, Map> fields, String fieldName) { - List currentField = fields.get(fieldName); - ExecutionPath fieldPath = parameters.getPath().segment(fieldName); + private ExecutionStrategyParameters newParameters(ExecutionStrategyParameters parameters, MergedSelectionSet fields, String fieldName) { + MergedField currentField = fields.getSubField(fieldName); + ResultPath fieldPath = parameters.getPath().segment(fieldName); return parameters .transform(builder -> builder.field(currentField).path(fieldPath)); } public static CompletableFuture> allOf(final Collection> futures) { - CompletableFuture[] cfs = futures.toArray(new CompletableFuture[futures.size()]); + CompletableFuture[] cfs = futures.toArray(new CompletableFuture[0]); return CompletableFuture.allOf(cfs) .thenApply(vd -> futures.stream() diff --git a/src/test/groovy/graphql/execution/ConditionalNodesTest.groovy b/src/test/groovy/graphql/execution/ConditionalNodesTest.groovy new file mode 100644 index 0000000000..3b75b05b0b --- /dev/null +++ b/src/test/groovy/graphql/execution/ConditionalNodesTest.groovy @@ -0,0 +1,226 @@ +package graphql.execution + +import graphql.ExecutionInput +import graphql.GraphQLContext +import graphql.TestUtil +import graphql.execution.conditional.ConditionalNodeDecision +import graphql.execution.conditional.ConditionalNodeDecisionEnvironment +import graphql.execution.conditional.ConditionalNodes +import graphql.language.Argument +import graphql.language.BooleanValue +import graphql.language.Directive +import graphql.language.Field +import graphql.language.NodeUtil +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import spock.lang.Specification + +class ConditionalNodesTest extends Specification { + + def "should include false for skip = true"() { + given: + def variables = new LinkedHashMap() + ConditionalNodes conditionalNodes = new ConditionalNodes() + + def directives = directive("skip", ifArg(true)) + + expect: + !conditionalNodes.shouldInclude(mkField(directives), variables, null, GraphQLContext.getDefault()) + } + + def "should include true for skip = false"() { + given: + def variables = new LinkedHashMap() + ConditionalNodes conditionalNodes = new ConditionalNodes() + + def directives = directive("skip", ifArg(false)) + + expect: + conditionalNodes.shouldInclude(mkField(directives), variables, null, GraphQLContext.getDefault()) + } + + def "should include false for include = false"() { + given: + def variables = new LinkedHashMap() + ConditionalNodes conditionalNodes = new ConditionalNodes() + + def directives = directive("include", ifArg(false)) + + expect: + !conditionalNodes.shouldInclude(mkField(directives), variables, null, GraphQLContext.getDefault()) + } + + def "should include true for include = true"() { + given: + def variables = new LinkedHashMap() + ConditionalNodes conditionalNodes = new ConditionalNodes() + + def directives = directive("include", ifArg(true)) + + expect: + conditionalNodes.shouldInclude(mkField(directives), variables, null, GraphQLContext.getDefault()) + } + + def "no directives means include"() { + given: + def variables = new LinkedHashMap() + ConditionalNodes conditionalNodes = new ConditionalNodes() + + expect: + conditionalNodes.shouldInclude(mkField([]), variables, null, GraphQLContext.getDefault()) + } + + + def "allows a custom implementation to check conditional nodes"() { + given: + def variables = ["x": "y"] + def graphQLSchema = TestUtil.schema("type Query { f : String} ") + ConditionalNodes conditionalNodes = new ConditionalNodes() + + def graphQLContext = GraphQLContext.getDefault() + + def directives = directive("featureFlag", ifArg(true)) + def field = mkField(directives) + + def called = false + ConditionalNodeDecision conditionalDecision = new ConditionalNodeDecision() { + @Override + boolean shouldInclude(ConditionalNodeDecisionEnvironment env) { + called = true + assert env.variables.toMap() == variables + assert env.directivesContainer == field + assert env.graphQlSchema == graphQLSchema + assert env.graphQLContext.get("assert") != null + return false + } + } + graphQLContext.put(ConditionalNodeDecision.class, conditionalDecision) + graphQLContext.put("assert", true) + expect: + + !conditionalNodes.shouldInclude(field, variables, graphQLSchema, graphQLContext) + called == true + } + + def "integration test showing conditional nodes can be custom included"() { + + def sdl = """ + + directive @featureFlag(flagName: String!) repeatable on FIELD + + type Query { + in : String + out : String + pet : Pet + } + + type Pet { + name: String + favouriteSnack: String + } + """ + DataFetcher df = { DataFetchingEnvironment env -> env.getFieldDefinition().name } + def graphQL = TestUtil.graphQL(sdl, [ + Query: ["in": df, "out": df, "pet": (DataFetcher) { [ : ] } ], + Pet: ["name": df, "favouriteSnack": df]]).build() + ConditionalNodeDecision customDecision = new ConditionalNodeDecision() { + @Override + boolean shouldInclude(ConditionalNodeDecisionEnvironment env) { + + Directive foundDirective = NodeUtil.findNodeByName(env.getDirectives(), "featureFlag") + if (foundDirective != null) { + + def arguments = env.getGraphQlSchema().getDirective("featureFlag") + .getArguments() + Map argumentValues = ValuesResolver.getArgumentValues( + arguments, foundDirective.getArguments(), + env.variables, env.graphQLContext, Locale.getDefault()) + Object flagName = argumentValues.get("flagName") + return String.valueOf(flagName) == "ON" + } + return true + } + } + + def contextMap = [:] + contextMap.put(ConditionalNodeDecision.class, customDecision) + + when: + def ei = ExecutionInput.newExecutionInput() + .graphQLContext(contextMap) + .query(""" + query q { + in + out @featureFlag(flagName : "OFF") + } + """ + ).build() + def er = graphQL.execute(ei) + + then: + er["data"] == ["in": "in"] + + when: + ei = ExecutionInput.newExecutionInput() + .graphQLContext(contextMap) + .query(""" + query q { + in + out @featureFlag(flagName : "ON") + } + """ + ).build() + er = graphQL.execute(ei) + + then: + er["data"] == ["in": "in", "out": "out"] + + when: + ei = ExecutionInput.newExecutionInput() + .graphQLContext(contextMap) + .query(''' + query vars_should_work($v : String!) { + in + out @featureFlag(flagName : $v) + } + ''' + ) + .variables([v: "ON"]) + .build() + er = graphQL.execute(ei) + + then: + er["data"] == ["in": "in", "out": "out"] + + // A test for fields below the top level + when: + ei = ExecutionInput.newExecutionInput() + .graphQLContext(contextMap) + .query(""" + query q { + in + pet { + name + favouriteSnack @featureFlag(flagName : "OFF") + } + } + """ + ).build() + er = graphQL.execute(ei) + + then: + er["data"] == ["in": "in", "pet": ["name": "name"]] + } + + private ArrayList directive(String name, Argument argument) { + [Directive.newDirective().name(name).arguments([argument]).build()] + } + + private Argument ifArg(Boolean b) { + Argument.newArgument("if", new BooleanValue(b)).build() + } + + Field mkField(List directives) { + return Field.newField("name").directives(directives).build() + } +} diff --git a/src/test/groovy/graphql/execution/DataFetcherExceptionHandlerResultTest.groovy b/src/test/groovy/graphql/execution/DataFetcherExceptionHandlerResultTest.groovy new file mode 100644 index 0000000000..f902efe4ab --- /dev/null +++ b/src/test/groovy/graphql/execution/DataFetcherExceptionHandlerResultTest.groovy @@ -0,0 +1,43 @@ +package graphql.execution + +import graphql.ErrorType +import graphql.GraphQLError +import graphql.language.SourceLocation +import spock.lang.Specification + +class DataFetcherExceptionHandlerResultTest extends Specification { + + class CustomError implements GraphQLError { + def msg + + CustomError(msg) { + this.msg = msg + } + + @Override + String getMessage() { + return msg + } + + @Override + List getLocations() { + return null + } + + @Override + ErrorType getErrorType() { + return null + } + } + + def "builder works"() { + when: + def result = DataFetcherExceptionHandlerResult + .newResult(new CustomError("First")) + .error(new CustomError("Second")) + .errors([new CustomError("Third"), new CustomError("Fourth")]) + .build() + then: + result.errors.collect { err -> err.getMessage() } == ["First", "Second", "Third", "Fourth"] + } +} diff --git a/src/test/groovy/graphql/execution/DataFetcherExceptionHandlerTest.groovy b/src/test/groovy/graphql/execution/DataFetcherExceptionHandlerTest.groovy new file mode 100644 index 0000000000..0587dc4e8a --- /dev/null +++ b/src/test/groovy/graphql/execution/DataFetcherExceptionHandlerTest.groovy @@ -0,0 +1,152 @@ +package graphql.execution + +import graphql.ErrorType +import graphql.GraphQL +import graphql.GraphQLError +import graphql.TestUtil +import graphql.language.SourceLocation +import graphql.schema.DataFetcher +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture + +import static graphql.ExecutionInput.newExecutionInput + +class DataFetcherExceptionHandlerTest extends Specification { + + class CustomError implements GraphQLError { + String msg + SourceLocation sourceLocation + + CustomError(String msg, SourceLocation sourceLocation) { + this.msg = msg + this.sourceLocation = sourceLocation + } + + @Override + String getMessage() { + return msg + } + + @Override + List getLocations() { + return [sourceLocation] + } + + @Override + ErrorType getErrorType() { + return ErrorType.DataFetchingException + } + } + + private static GraphQL mkTestingGraphQL(DataFetcherExceptionHandler handler) { + def dataFetchers = [ + Query: [field: { env -> throw new RuntimeException("BANG") } as DataFetcher] + ] + + def graphQL = TestUtil.graphQL(''' + type Query { + field : String + } + ''', dataFetchers) + .queryExecutionStrategy(new AsyncExecutionStrategy(handler)) + .build() + graphQL + } + + def "integration test to prove custom error handle can be made"() { + DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { + def msg = "The thing went " + handlerParameters.getException().getMessage() + return CompletableFuture.completedFuture( + DataFetcherExceptionHandlerResult.newResult().error(new CustomError(msg, handlerParameters.getSourceLocation())).build() + ) + } + } + + GraphQL graphQL = mkTestingGraphQL(handler) + when: + def result = graphQL.execute(newExecutionInput().query(' { field }')) + then: + !result.errors.isEmpty() + result.errors[0].message == "The thing went BANG" + } + + + def "integration test to prove an async custom error handle can be made"() { + DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters params) { + def msg = "The thing went " + params.getException().getMessage() + def result = DataFetcherExceptionHandlerResult.newResult().error(new CustomError(msg, params.getSourceLocation())).build() + return CompletableFuture.supplyAsync({ -> result }) + } + } + + GraphQL graphQL = mkTestingGraphQL(handler) + + when: + def result = graphQL.execute(newExecutionInput().query(' { field }')) + then: + !result.errors.isEmpty() + result.errors[0].message == "The thing went BANG" + } + + def "if an exception handler itself throws an exception than that is handled"() { + DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { + throw new RuntimeException("The handler itself went BANG!") + } + } + + GraphQL graphQL = mkTestingGraphQL(handler) + + when: + def result = graphQL.execute(newExecutionInput().query(' { field }')) + then: + !result.errors.isEmpty() + result.errors[0].message.contains("The handler itself went BANG!") + } + + def "if an async exception handler itself throws an exception than that is handled"() { + DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { + throw new RuntimeException("The handler itself went BANG!") + } + } + + GraphQL graphQL = mkTestingGraphQL(handler) + + when: + def result = graphQL.execute(newExecutionInput().query(' { field }')) + then: + !result.errors.isEmpty() + result.errors[0].message.contains("The handler itself went BANG!") + } + + + def "multiple errors can be returned in a handler"() { + DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters params) { + def result = DataFetcherExceptionHandlerResult.newResult() + for (int i = 0; i < 5; i++) { + def msg = "$i The thing went " + params.getException().getMessage() + result.error(new CustomError(msg, params.getSourceLocation())) + } + return CompletableFuture.supplyAsync({ -> result.build() }) + } + } + + GraphQL graphQL = mkTestingGraphQL(handler) + + when: + def result = graphQL.execute(newExecutionInput().query(' { field }')) + + then: + result.errors.size() == 5 + } +} diff --git a/src/test/groovy/graphql/execution/DataFetcherResultTest.groovy b/src/test/groovy/graphql/execution/DataFetcherResultTest.groovy new file mode 100644 index 0000000000..07318afa75 --- /dev/null +++ b/src/test/groovy/graphql/execution/DataFetcherResultTest.groovy @@ -0,0 +1,184 @@ +package graphql.execution + +import graphql.GraphQLError +import graphql.InvalidSyntaxError +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import spock.lang.Specification + +class DataFetcherResultTest extends Specification { + + def error1 = ValidationError.newValidationError().validationErrorType(ValidationErrorType.DuplicateOperationName).build() + def error2 = new InvalidSyntaxError([], "Boo") + + def "basic building"() { + when: + def result = DataFetcherResult.newResult().data("hello") + .error(error1).errors([error2]).localContext("world").build() + then: + result.getData() == "hello" + result.getLocalContext() == "world" + result.getErrors() == [error1, error2] + } + + def "hasErrors can be called"() { + when: + def builder = DataFetcherResult.newResult() + then: + !builder.hasErrors() + + when: + builder.error(error1) + then: + builder.hasErrors() + + when: + def result = builder.build() + then: + result.hasErrors() + } + + def "clearErrors can be called in a builder"() { + when: + def builder = DataFetcherResult.newResult() + .errors([error1, error2]) + then: + builder.hasErrors() + + when: + builder.clearErrors() + then: + !builder.hasErrors() + + when: + def result = builder.build() + then: + !result.hasErrors() + } + + def "can set extensions"() { + + when: + def dfr = DataFetcherResult.newResult() + .extensions([x: "y"]).build() + + then: + dfr.getExtensions() == [x : "y"] + + when: + dfr = DataFetcherResult.newResult() + .data("x") + .build() + + then: + dfr.getExtensions() == null + + } + + def "mapping works"() { + when: + def original = DataFetcherResult.newResult().data("hello") + .errors([error1]).localContext("world") + .extensions([x: "y"]).build() + def result = original.map({ data -> data.length() }) + then: + result.getData() == 5 + result.getLocalContext() == "world" + result.getExtensions() == [x: "y"] + result.getErrors() == [error1] + } + + def "transforming works"() { + when: + def original = DataFetcherResult.newResult().data("hello") + .errors([error1]).localContext("world") + .extensions([x: "y"]).build() + def result = original.transform({ builder -> builder.error(error2) }) + then: + result.getData() == "hello" + result.getLocalContext() == "world" + result.getExtensions() == [x : "y"] + result.getErrors() == [error1, error2] + + when: + result = result.transform({ builder -> builder.extensions(a : "b") }) + then: + result.getData() == "hello" + result.getLocalContext() == "world" + result.getExtensions() == [a : "b"] + result.getErrors() == [error1, error2] + } + + def "implements equals/hashCode for matching results"() { + when: + def firstResult = toDataFetcherResult(first) + def secondResult = toDataFetcherResult(second) + + then: + firstResult == secondResult + firstResult.hashCode() == secondResult.hashCode() + + where: + first | second + [data: "A string"] | [data: "A string"] + [data: 5] | [data: 5] + [data: ["a", "b"]] | [data: ["a", "b"]] + [errors: [error("An error")]] | [errors: [error("An error")]] + [data: "A value", errors: [error("An error")]] | [data: "A value", errors: [error("An error")]] + [data: "A value", localContext: 5] | [data: "A value", localContext: 5] + [data: "A value", errors: [error("An error")], localContext: 5] | [data: "A value", errors: [error("An error")], localContext: 5] + [data: "A value", extensions: ["key": "value"]] | [data: "A value", extensions: ["key": "value"]] + [data: "A value", errors: [error("An error")], localContext: 5, extensions: ["key": "value"]] | [data: "A value", errors: [error("An error")], localContext: 5, extensions: ["key": "value"]] + } + + def "implements equals/hashCode for different results"() { + when: + def firstResult = toDataFetcherResult(first) + def secondResult = toDataFetcherResult(second) + + then: + firstResult != secondResult + firstResult.hashCode() != secondResult.hashCode() + + where: + first | second + [data: "A string"] | [data: "A different string"] + [data: 5] | [data: "not 5"] + [data: ["a", "b"]] | [data: ["a", "c"]] + [errors: [error("An error")]] | [errors: [error("A different error")]] + [data: "A value", errors: [error("An error")]] | [data: "A different value", errors: [error("An error")]] + [data: "A value", localContext: 5] | [data: "A value", localContext: 1] + [data: "A value", errors: [error("An error")], localContext: 5] | [data: "A value", errors: [error("A different error")], localContext: 5] + [data: "A value", extensions: ["key": "value"]] | [data: "A value", extensions: ["key", "different value"]] + [data: "A value", errors: [error("An error")], localContext: 5, extensions: ["key": "value"]] | [data: "A value", errors: [error("An error")], localContext: 5, extensions: ["key": "different value"]] + } + + private static DataFetcherResult toDataFetcherResult(Map resultFields) { + def resultBuilder = DataFetcherResult.newResult(); + resultFields.forEach { key, value -> + if (value != null) { + switch (key) { + case "data": + resultBuilder.data(value) + break; + case "errors": + resultBuilder.errors(value as List); + break; + case "localContext": + resultBuilder.localContext(value); + break; + case "extensions": + resultBuilder.extensions(value as Map); + break; + } + } + } + return resultBuilder.build(); + } + + private static GraphQLError error(String message) { + return GraphQLError.newError() + .message(message) + .build(); + } +} diff --git a/src/test/groovy/graphql/execution/DefaultResponseMapFactoryTest.groovy b/src/test/groovy/graphql/execution/DefaultResponseMapFactoryTest.groovy new file mode 100644 index 0000000000..f8ea921bad --- /dev/null +++ b/src/test/groovy/graphql/execution/DefaultResponseMapFactoryTest.groovy @@ -0,0 +1,42 @@ +package graphql.execution + +import spock.lang.Specification + +class DefaultResponseMapFactoryTest extends Specification { + + def "no keys"() { + given: + var sut = new DefaultResponseMapFactory() + + when: + var result = sut.createInsertionOrdered(List.of(), List.of()) + + then: + result.isEmpty() + result instanceof LinkedHashMap + } + + def "1 key"() { + given: + var sut = new DefaultResponseMapFactory() + + when: + var result = sut.createInsertionOrdered(List.of("name"), List.of("Mario")) + + then: + result == ["name": "Mario"] + result instanceof LinkedHashMap + } + + def "2 keys"() { + given: + var sut = new DefaultResponseMapFactory() + + when: + var result = sut.createInsertionOrdered(List.of("name", "age"), List.of("Mario", 18)) + + then: + result == ["name": "Mario", "age": 18] + result instanceof LinkedHashMap + } +} diff --git a/src/test/groovy/graphql/execution/ExceptionWhileDataFetchingTest.groovy b/src/test/groovy/graphql/execution/ExceptionWhileDataFetchingTest.groovy index a005f0d482..5abf30d7ed 100644 --- a/src/test/groovy/graphql/execution/ExceptionWhileDataFetchingTest.groovy +++ b/src/test/groovy/graphql/execution/ExceptionWhileDataFetchingTest.groovy @@ -3,7 +3,6 @@ package graphql.execution import graphql.ErrorType import graphql.ExceptionWhileDataFetching import graphql.ExecutionInput -import graphql.GraphQL import graphql.GraphQLError import graphql.TestUtil import graphql.language.SourceLocation @@ -80,8 +79,7 @@ class ExceptionWhileDataFetchingTest extends Specification { .dataFetcher("bangCF", bangDataFetcher)) .build() - def schema = TestUtil.schema(spec, runtimeWiring) - def graphQL = GraphQL.newGraphQL(schema).build() + def graphQL = TestUtil.graphQL(spec, runtimeWiring).build() def executionInput = ExecutionInput.newExecutionInput().query(''' { diff --git a/src/test/groovy/graphql/execution/ExecutionContextBuilderTest.groovy b/src/test/groovy/graphql/execution/ExecutionContextBuilderTest.groovy index abb58a41e8..2512cac1b8 100644 --- a/src/test/groovy/graphql/execution/ExecutionContextBuilderTest.groovy +++ b/src/test/groovy/graphql/execution/ExecutionContextBuilderTest.groovy @@ -1,58 +1,199 @@ package graphql.execution + +import graphql.GraphQLContext import graphql.execution.instrumentation.Instrumentation import graphql.language.Document import graphql.language.FragmentDefinition import graphql.language.OperationDefinition import graphql.parser.Parser import graphql.schema.GraphQLSchema +import org.dataloader.DataLoaderRegistry import spock.lang.Specification class ExecutionContextBuilderTest extends Specification { + Instrumentation instrumentation = Mock(Instrumentation) + ExecutionStrategy queryStrategy = Mock(ExecutionStrategy) + ExecutionStrategy mutationStrategy = Mock(ExecutionStrategy) + ExecutionStrategy subscriptionStrategy = Mock(ExecutionStrategy) + GraphQLSchema schema = Mock(GraphQLSchema) + def executionId = ExecutionId.generate() + def context = "context" + def graphQLContext = GraphQLContext.newContext().build() + def root = "root" + Document document = new Parser().parseDocument("query myQuery(\$var: String){...MyFragment} fragment MyFragment on Query{foo}") + def operation = document.definitions[0] as OperationDefinition + def fragment = document.definitions[1] as FragmentDefinition + def dataLoaderRegistry = new DataLoaderRegistry() + def mockDataLoaderDispatcherStrategy = Mock(DataLoaderDispatchStrategy) def "builds the correct ExecutionContext"() { - given: - ExecutionContextBuilder executionContextBuilder = new ExecutionContextBuilder() - - Instrumentation instrumentation = Mock(Instrumentation) - executionContextBuilder.instrumentation(instrumentation) + when: + def executionContext = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .context(context) // Retain deprecated builder for test coverage + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .fragmentsByName([MyFragment: fragment]) + .variables([var: 'value']) // Retain deprecated builder for test coverage + .dataLoaderRegistry(dataLoaderRegistry) + .dataLoaderDispatcherStrategy(mockDataLoaderDispatcherStrategy) + .build() - ExecutionStrategy queryStrategy = Mock(ExecutionStrategy) - executionContextBuilder.queryStrategy(queryStrategy) + then: + executionContext.executionId == executionId + executionContext.instrumentation == instrumentation + executionContext.graphQLSchema == schema + executionContext.queryStrategy == queryStrategy + executionContext.mutationStrategy == mutationStrategy + executionContext.subscriptionStrategy == subscriptionStrategy + executionContext.root == root + executionContext.context == context // Retain deprecated method for test coverage + executionContext.graphQLContext == graphQLContext + executionContext.getCoercedVariables().toMap() == [var: 'value'] + executionContext.getFragmentsByName() == [MyFragment: fragment] + executionContext.operationDefinition == operation + executionContext.dataLoaderRegistry == dataLoaderRegistry + executionContext.dataLoaderDispatcherStrategy == mockDataLoaderDispatcherStrategy + } - ExecutionStrategy mutationStrategy = Mock(ExecutionStrategy) - executionContextBuilder.mutationStrategy(mutationStrategy) + def "builds the correct ExecutionContext with coerced variables"() { + given: + def coercedVariables = CoercedVariables.of([var: 'value']) - ExecutionStrategy subscriptionStrategy = Mock(ExecutionStrategy) - executionContextBuilder.subscriptionStrategy(subscriptionStrategy) + when: + def executionContext = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .fragmentsByName([MyFragment: fragment]) + .coercedVariables(coercedVariables) + .dataLoaderRegistry(dataLoaderRegistry) + .build() - GraphQLSchema schema = Mock(GraphQLSchema) - executionContextBuilder.graphQLSchema(schema) + then: + executionContext.executionId == executionId + executionContext.instrumentation == instrumentation + executionContext.graphQLSchema == schema + executionContext.queryStrategy == queryStrategy + executionContext.mutationStrategy == mutationStrategy + executionContext.subscriptionStrategy == subscriptionStrategy + executionContext.root == root + executionContext.graphQLContext == graphQLContext + executionContext.coercedVariables == coercedVariables + executionContext.getFragmentsByName() == [MyFragment: fragment] + executionContext.operationDefinition == operation + executionContext.dataLoaderRegistry == dataLoaderRegistry + } - def executionId = ExecutionId.generate() - executionContextBuilder.executionId(executionId) + def "builds the correct ExecutionContext, if both variables and coercedVariables are set, latest value set takes precedence"() { + given: + def coercedVariables = CoercedVariables.of([var: 'value']) - def context = "context" - executionContextBuilder.context(context) + when: + def executionContext = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .fragmentsByName([MyFragment: fragment]) + .coercedVariables(coercedVariables) + .dataLoaderRegistry(dataLoaderRegistry) + .build() - def root = "root" - executionContextBuilder.root(root) + then: + executionContext.executionId == executionId + executionContext.instrumentation == instrumentation + executionContext.graphQLSchema == schema + executionContext.queryStrategy == queryStrategy + executionContext.mutationStrategy == mutationStrategy + executionContext.subscriptionStrategy == subscriptionStrategy + executionContext.root == root + executionContext.graphQLContext == graphQLContext + executionContext.coercedVariables == coercedVariables + executionContext.getFragmentsByName() == [MyFragment: fragment] + executionContext.operationDefinition == operation + executionContext.dataLoaderRegistry == dataLoaderRegistry + } - Document document = new Parser().parseDocument("query myQuery(\$var: String){...MyFragment} fragment MyFragment on Query{foo}") - def operation = document.definitions[0] as OperationDefinition - def fragment = document.definitions[1] as FragmentDefinition - executionContextBuilder.operationDefinition(operation) + def "transform works and copies values with coerced variables"() { + given: + def oldCoercedVariables = CoercedVariables.emptyVariables() + def executionContextOld = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .coercedVariables(oldCoercedVariables) + .fragmentsByName([MyFragment: fragment]) + .dataLoaderRegistry(dataLoaderRegistry) + .build() - executionContextBuilder.fragmentsByName([MyFragment: fragment]) + when: + def coercedVariables = CoercedVariables.of([var: 'value']) + def executionContext = executionContextOld.transform(builder -> builder + .coercedVariables(coercedVariables)) - def variables = Collections.emptyMap() - executionContextBuilder.variables(variables) + then: + executionContext.executionId == executionId + executionContext.instrumentation == instrumentation + executionContext.graphQLSchema == schema + executionContext.queryStrategy == queryStrategy + executionContext.mutationStrategy == mutationStrategy + executionContext.subscriptionStrategy == subscriptionStrategy + executionContext.root == root + executionContext.graphQLContext == graphQLContext + executionContext.coercedVariables == coercedVariables + executionContext.getFragmentsByName() == [MyFragment: fragment] + executionContext.operationDefinition == operation + executionContext.dataLoaderRegistry == dataLoaderRegistry + } - executionContextBuilder.variables([var: 'value']) + def "transform copies values, if both variables and coercedVariables set, latest value set takes precedence"() { + given: + def oldCoercedVariables = CoercedVariables.emptyVariables() + def executionContextOld = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .coercedVariables(oldCoercedVariables) + .fragmentsByName([MyFragment: fragment]) + .dataLoaderRegistry(dataLoaderRegistry) + .build() when: - def executionContext = executionContextBuilder.build() + def coercedVariables = CoercedVariables.of([var: 'value']) + def executionContext = executionContextOld.transform(builder -> builder + .coercedVariables(coercedVariables)) then: executionContext.executionId == executionId @@ -62,9 +203,68 @@ class ExecutionContextBuilderTest extends Specification { executionContext.mutationStrategy == mutationStrategy executionContext.subscriptionStrategy == subscriptionStrategy executionContext.root == root - executionContext.context == context - executionContext.variables == [var: 'value'] + executionContext.graphQLContext == graphQLContext + executionContext.coercedVariables == coercedVariables executionContext.getFragmentsByName() == [MyFragment: fragment] executionContext.operationDefinition == operation + executionContext.dataLoaderRegistry == dataLoaderRegistry } + + def "transform copies dispatcher"() { + given: + def oldCoercedVariables = CoercedVariables.emptyVariables() + def executionContextOld = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .coercedVariables(oldCoercedVariables) + .fragmentsByName([MyFragment: fragment]) + .dataLoaderRegistry(dataLoaderRegistry) + .dataLoaderDispatcherStrategy(DataLoaderDispatchStrategy.NO_OP) + .build() + + when: + def executionContext = executionContextOld + .transform(builder -> builder + .dataLoaderDispatcherStrategy(mockDataLoaderDispatcherStrategy)) + + then: + executionContext.getDataLoaderDispatcherStrategy() == mockDataLoaderDispatcherStrategy + } + + def "can detect operation type"() { + when: + def executionContext = new ExecutionContextBuilder() + .instrumentation(instrumentation) + .queryStrategy(queryStrategy) + .mutationStrategy(mutationStrategy) + .subscriptionStrategy(subscriptionStrategy) + .graphQLSchema(schema) + .executionId(executionId) + .graphQLContext(graphQLContext) + .root(root) + .operationDefinition(operation) + .fragmentsByName([MyFragment: fragment]) + .dataLoaderRegistry(dataLoaderRegistry) + .operationDefinition(OperationDefinition.newOperationDefinition().operation(opType).build()) + .build() + + then: + executionContext.isQueryOperation() == isQuery + executionContext.isMutationOperation() == isMutation + executionContext.isSubscriptionOperation() == isSubscription + + where: + opType | isQuery | isMutation | isSubscription + OperationDefinition.Operation.QUERY | true | false | false + OperationDefinition.Operation.MUTATION | false | true | false + OperationDefinition.Operation.SUBSCRIPTION | false | false | true + } + } diff --git a/src/test/groovy/graphql/execution/ExecutionStepInfoTest.groovy b/src/test/groovy/graphql/execution/ExecutionStepInfoTest.groovy new file mode 100644 index 0000000000..9fc34114a5 --- /dev/null +++ b/src/test/groovy/graphql/execution/ExecutionStepInfoTest.groovy @@ -0,0 +1,315 @@ +package graphql.execution + +import graphql.ExecutionInput +import graphql.Scalars +import graphql.TestUtil +import graphql.language.Field +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLList +import graphql.schema.GraphQLNonNull +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLType +import graphql.schema.GraphQLTypeUtil +import graphql.schema.TypeResolver +import spock.lang.Specification + +import java.util.function.Function + +import static ExecutionStepInfo.newExecutionStepInfo +import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mergedField +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLList.list +import static graphql.schema.GraphQLNonNull.nonNull +import static graphql.schema.GraphQLTypeUtil.simplePrint +import static graphql.schema.GraphQLTypeUtil.unwrapAll +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class ExecutionStepInfoTest extends Specification { + + def field = new Field("someAstField") + def mergedField = mergedField(field) + + def field1Def = newFieldDefinition().name("field1").type(GraphQLString).build() + + def interfaceType = GraphQLInterfaceType.newInterface().name("Interface") + .field(field1Def) + .build() + + def fieldType = GraphQLObjectType.newObject() + .name("FieldType") + .field(field1Def) + .build() + + def rootType = GraphQLObjectType.newObject() + .name("RootType") + .field(newFieldDefinition().name("rootField1").type(fieldType)) + .build() + + def "basic hierarchy"() { + given: + def rootTypeInfo = newExecutionStepInfo().type(rootType).build() + def fieldTypeInfo = newExecutionStepInfo().type(fieldType).fieldDefinition(field1Def).field(mergedField).parentInfo(rootTypeInfo).build() + def nonNullFieldTypeInfo = newExecutionStepInfo().type(nonNull(fieldType)).parentInfo(rootTypeInfo).build() + def listTypeInfo = newExecutionStepInfo().type(list(fieldType)).parentInfo(rootTypeInfo).build() + + expect: + rootTypeInfo.getUnwrappedNonNullType() == rootType + rootTypeInfo.field == null + rootTypeInfo.fieldDefinition == null + !rootTypeInfo.hasParent() + + fieldTypeInfo.getUnwrappedNonNullType() == fieldType + fieldTypeInfo.hasParent() + fieldTypeInfo.parent.type == rootType + !fieldTypeInfo.isNonNullType() + fieldTypeInfo.getFieldDefinition() == field1Def + fieldTypeInfo.getField() == mergedField + + nonNullFieldTypeInfo.getUnwrappedNonNullType() == fieldType + nonNullFieldTypeInfo.hasParent() + nonNullFieldTypeInfo.parent.type == rootType + nonNullFieldTypeInfo.isNonNullType() + + list(fieldType).isEqualTo(listTypeInfo.getUnwrappedNonNullType()) + listTypeInfo.hasParent() + listTypeInfo.parent.type == rootType + listTypeInfo.isListType() + } + + def "morphing type works"() { + given: + def rootTypeInfo = newExecutionStepInfo().type(rootType).build() + def interfaceTypeInfo = newExecutionStepInfo().type(interfaceType).parentInfo(rootTypeInfo).build() + def morphedTypeInfo = interfaceTypeInfo.changeTypeWithPreservedNonNull(fieldType) + + expect: + + interfaceTypeInfo.type == interfaceType + morphedTypeInfo.type == fieldType + } + + def "unwrapping stack works"() { + + given: + // [[String!]!] + GraphQLType wrappedType = list(nonNull(list(nonNull(GraphQLString)))) + def stack = GraphQLTypeUtil.unwrapType(wrappedType) + + expect: + stack.pop() == GraphQLString + stack.pop() instanceof GraphQLNonNull + stack.pop() instanceof GraphQLList + stack.pop() instanceof GraphQLNonNull + stack.pop() instanceof GraphQLList + stack.isEmpty() + } + + List executionTypeInfos = [] + + class ExecutionStepInfoCapturingDF implements DataFetcher { + Function function + + ExecutionStepInfoCapturingDF(function) { + this.function = function + } + + @Override + Object get(DataFetchingEnvironment environment) { + executionTypeInfos.add(environment.getExecutionStepInfo()) + def val = function.apply(environment) + return val + } + } + + class User { + def name + List friends + List mates + + User(name, List friends) { + this.name = name + this.friends = friends + this.mates = friends + } + } + + def "end to end type hierarchy is maintained during execution"() { + def spec = ''' + type Query { + hero(id:String) : User + } + + type User { + name : String + friends(closeFriends: Boolean) : [User] + mates : [User] + } + ''' + + def bilbo = new User("bilbo", []) + def gandalf = new User("gandalf", [bilbo]) + def frodo = new User("frodo", [bilbo, gandalf]) + def samwise = new User("samwise", [bilbo, gandalf, frodo]) + + DataFetcher samwiseDF = new ExecutionStepInfoCapturingDF({ env -> env.getSource() }) + DataFetcher friendsDF = new ExecutionStepInfoCapturingDF({ env -> (env.getSource() as User).friends }) + + def runtimeWiring = newRuntimeWiring() + .type(newTypeWiring("Query").dataFetcher("hero", samwiseDF)) + .type(newTypeWiring("User").dataFetcher("friends", friendsDF)) + .type(newTypeWiring("User").dataFetcher("mates", friendsDF)) + .build() + + def graphQL = TestUtil.graphQL(spec, runtimeWiring).build() + + def query = ''' + { + hero(id : "1234") { + name + friends(closeFriends : true) { + name + mates { + name + } + } + } + } + ''' + def executionInput = ExecutionInput.newExecutionInput().root(samwise).query(query).build() + when: + def er = graphQL.execute(executionInput) + then: + er.errors.isEmpty() + + executionTypeInfos.size() == 5 + + executionTypeInfos[0].path.toString() == "/hero" + (executionTypeInfos[0].type as GraphQLObjectType).name == "User" + executionTypeInfos[0].field.getName() == "hero" + executionTypeInfos[0].parent.path == ResultPath.rootPath() + (executionTypeInfos[0].parent.type as GraphQLObjectType).name == "Query" + executionTypeInfos[0].arguments == [id: "1234"] + executionTypeInfos[0].getArgument("id") == "1234" + + executionTypeInfos[1].path.toString() == "/hero/friends" + executionTypeInfos[1].field.name == "friends" + (unwrapAll(executionTypeInfos[1].type) as GraphQLObjectType).name == "User" + executionTypeInfos[1].parent.path.toString() == "/hero" + executionTypeInfos[1].parent.field.name == "hero" + (unwrapAll(executionTypeInfos[1].parent.type) as GraphQLObjectType).name == "User" + executionTypeInfos[1].arguments == [closeFriends: true] + executionTypeInfos[1].parent.arguments == [id: "1234"] + + // we have 3 list items here + for (int i = 2; i < 5; i++) { + assert executionTypeInfos[i].path.toString() == "/hero/friends[" + (i - 2) + "]/mates" + assert executionTypeInfos[i].field.name == "mates" + assert (unwrapAll(executionTypeInfos[i].type) as GraphQLObjectType).name == "User" + + assert executionTypeInfos[i].parent.path.toString() == "/hero/friends[" + (i - 2) + "]" + assert executionTypeInfos[i].parent.field.name == "friends" + assert (unwrapAll(executionTypeInfos[i].parent.type) as GraphQLObjectType).name == "User" + } + } + + + def "transform copies fieldContainer"() { + given: + ExecutionStepInfo executionStepInfo = newExecutionStepInfo() + .type(Scalars.GraphQLString) + .fieldContainer(GraphQLObjectType.newObject().name("foo").build()) + .build() + when: + def transformed = executionStepInfo.transform({ builder -> builder }) + + then: + transformed.getObjectType() == executionStepInfo.getObjectType() + } + + def "step info for list of lists of abstract type"() { + def spec = ''' + type Query { + pets: [[Pet]] + } + + interface Pet { + names : [String] + } + type Cat implements Pet { + names : [String] + } + type Dog implements Pet { + names : [String] + } + ''' + + def dog = [name: "Dog", __typename: "Dog"] + def cat = [name: "Cat", __typename: "Cat"] + def petTypeResolver = { it -> it.schema.getObjectType(it.object.__typename) } as TypeResolver + + + ExecutionStepInfo dogStepInfo + def dogDf = { it -> + dogStepInfo = it.getExecutionStepInfo() + return null + } as DataFetcher + + + ExecutionStepInfo catStepInfo + def catDf = { it -> + catStepInfo = it.getExecutionStepInfo() + return null + } as DataFetcher + + def pets = [[dog], [cat]] + def runtimeWiring = newRuntimeWiring() + .type(newTypeWiring("Query").dataFetcher("pets", { it -> pets })) + .type(newTypeWiring("Pet").typeResolver(petTypeResolver).build()) + .type(newTypeWiring("Cat").dataFetcher("names", catDf).build()) + .type(newTypeWiring("Dog").dataFetcher("names", dogDf).build()) + .build() + + def graphQL = TestUtil.graphQL(spec, runtimeWiring).build() + + def query = ''' + { + pets {names} + } + ''' + def executionInput = ExecutionInput.newExecutionInput().query(query).build() + when: + graphQL.execute(executionInput) + then: + // dog info + dogStepInfo.path.toString() == "/pets[0][0]/names" + simplePrint(dogStepInfo.type) == "[String]" + + dogStepInfo.parent.path.toString() == "/pets[0][0]" + simplePrint(dogStepInfo.parent.type) == "Dog" + + dogStepInfo.parent.parent.path.toString() == "/pets[0]" + simplePrint(dogStepInfo.parent.parent.type) == "[Pet]" + + dogStepInfo.parent.parent.parent.path.toString() == "/pets" + simplePrint(dogStepInfo.parent.parent.parent.type) == "[[Pet]]" + + // cat info + catStepInfo.path.toString() == "/pets[1][0]/names" + simplePrint(catStepInfo.type) == "[String]" + + catStepInfo.parent.path.toString() == "/pets[1][0]" + simplePrint(catStepInfo.parent.type) == "Cat" + + catStepInfo.parent.parent.path.toString() == "/pets[1]" + simplePrint(catStepInfo.parent.parent.type) == "[Pet]" + + catStepInfo.parent.parent.parent.path.toString() == "/pets" + simplePrint(catStepInfo.parent.parent.parent.type) == "[[Pet]]" + + + } +} diff --git a/src/test/groovy/graphql/execution/ExecutionStrategyEquivalenceTest.groovy b/src/test/groovy/graphql/execution/ExecutionStrategyEquivalenceTest.groovy index 8fbd75fd13..93e58e3aa6 100644 --- a/src/test/groovy/graphql/execution/ExecutionStrategyEquivalenceTest.groovy +++ b/src/test/groovy/graphql/execution/ExecutionStrategyEquivalenceTest.groovy @@ -6,8 +6,6 @@ import graphql.StarWarsSchema import spock.lang.Specification import spock.lang.Unroll -import java.util.concurrent.ForkJoinPool - /** * This allows the testing of different execution strategies that provide the same results given the same schema, * and queries and results @@ -27,8 +25,7 @@ class ExecutionStrategyEquivalenceTest extends Specification { name } } - """ - : [ + """: [ hero: [ name: 'R2-D2' ] @@ -46,8 +43,7 @@ class ExecutionStrategyEquivalenceTest extends Specification { } } } - """ - : [ + """: [ hero: [ id : '2001', name : 'R2-D2', @@ -73,8 +69,7 @@ class ExecutionStrategyEquivalenceTest extends Specification { name } } - """ - : [ + """: [ human: [ name: 'Luke Skywalker' ] @@ -93,8 +88,7 @@ class ExecutionStrategyEquivalenceTest extends Specification { name } } - """ - : [ + """: [ luke: [ name: 'Luke Skywalker' @@ -132,16 +126,12 @@ class ExecutionStrategyEquivalenceTest extends Specification { where: - strategyType | strategyUnderTest | expectedQueriesAndResults - "async" | new AsyncExecutionStrategy() | standardQueriesAndResults() - "asyncSerial" | new AsyncSerialExecutionStrategy() | standardQueriesAndResults() - "breadthFirst" | new BreadthFirstExecutionTestStrategy() | standardQueriesAndResults() - "executorService" | executorServiceStrategy() | standardQueriesAndResults() - "breadthFirst" | new BreadthFirstTestStrategy() | standardQueriesAndResults() + strategyType | strategyUnderTest | expectedQueriesAndResults + "async" | new AsyncExecutionStrategy() | standardQueriesAndResults() + "asyncSerial" | new AsyncSerialExecutionStrategy() | standardQueriesAndResults() + "breadthFirst" | new BreadthFirstExecutionTestStrategy() | standardQueriesAndResults() + "breadthFirst" | new BreadthFirstTestStrategy() | standardQueriesAndResults() } - def executorServiceStrategy() { - new ExecutorServiceExecutionStrategy(ForkJoinPool.commonPool()) - } } diff --git a/src/test/groovy/graphql/execution/ExecutionStrategyErrorsTest.groovy b/src/test/groovy/graphql/execution/ExecutionStrategyErrorsTest.groovy new file mode 100644 index 0000000000..55b6afb6cb --- /dev/null +++ b/src/test/groovy/graphql/execution/ExecutionStrategyErrorsTest.groovy @@ -0,0 +1,133 @@ +package graphql.execution + +import graphql.ExceptionWhileDataFetching +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.SerializationError +import graphql.TestUtil +import graphql.TypeMismatchError +import graphql.execution.instrumentation.Instrumentation +import graphql.execution.instrumentation.InstrumentationContext +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters +import graphql.schema.DataFetcher +import spock.lang.Specification + +/** + * A test of errors that can happen inside a ES + */ +class ExecutionStrategyErrorsTest extends Specification { + + def "can capture certain errors"() { + def sdl = ''' + type Query { + notAList : [String] + notAFloat : Float + notAnProperObject : ImproperObject + } + + + type ImproperObject { + name : String + diceyListCall : [DiceyCall!]! + diceyListCallAbort : [DiceyCall!]! + diceyCall : DiceyCall + } + + type DiceyCall { + bang : String + abort : String + nonNull : String! + } + ''' + + DataFetcher dfNotAList = { env -> "noAList" } + DataFetcher dfNotAFloat = { env -> "noAFloat" } + DataFetcher dfDiceyBang = { + env -> throw new RuntimeException("dicey call") + } + DataFetcher dfDiceyAbort = { + env -> throw new AbortExecutionException("abort abort") + } + DataFetcher dfDiceyListCall = { + env -> ["x", null] + } + DataFetcher dfReturnsNull = { + env -> null + } + + def schema = TestUtil.schema(sdl, [ + Query : + [notAList: dfNotAList, notAFloat: dfNotAFloat], + ImproperObject: + [diceyListCall: dfDiceyListCall], + DiceyCall : + [bang: dfDiceyBang, abort: dfDiceyAbort, nonNull: dfReturnsNull], + ] + ) + + Instrumentation instrumentation = new SimplePerformantInstrumentation() { + @Override + InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + if (parameters.field.name == "diceyListCallAbort") { + throw new AbortExecutionException("No lists for you") + } + return super.beginFieldListCompletion(parameters, state) + } + } + def graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build() + + + when: + def ei = ExecutionInput.newExecutionInput() + .query(""" + query q { + notAList + notAFloat + notAnProperObject { + name + diceyListCallAbort { + bang + } + diceyListCall { + bang + abort + nonNull + } + } + } + """) + .root([notAnProperObject: ["name" : "make it drive errors", + "diceyListCall" : [[:]], + "diceyListCallAbort": [[:]], + "diceyCall" : [:] + ]]) + .build() + def er = graphQL.execute(ei) + + then: + er.errors.size() == 7 + er.errors[0] instanceof TypeMismatchError + er.errors[0].path == ["notAList"] + + er.errors[1] instanceof SerializationError + er.errors[1].path == ["notAFloat"] + + er.errors[2] instanceof ExceptionWhileDataFetching + er.errors[2].path == ["notAnProperObject", "diceyListCall", 0, "bang"] + ((ExceptionWhileDataFetching) er.errors[2]).exception.message == "dicey call" + + er.errors[3] instanceof ExceptionWhileDataFetching + er.errors[3].path == ["notAnProperObject", "diceyListCall", 0, "abort"] + ((ExceptionWhileDataFetching) er.errors[3]).exception.message == "abort abort" + + er.errors[4] instanceof NonNullableFieldWasNullError + er.errors[4].path == ["notAnProperObject", "diceyListCall", 0, "nonNull"] + + er.errors[5] instanceof NonNullableFieldWasNullError + er.errors[5].path == ["notAnProperObject", "diceyListCall", 1] // the entry itself was null in a non null list entry + + er.errors[6] instanceof AbortExecutionException + } +} diff --git a/src/test/groovy/graphql/execution/ExecutionStrategyExceptionHandlingEquivalenceTest.groovy b/src/test/groovy/graphql/execution/ExecutionStrategyExceptionHandlingEquivalenceTest.groovy index 7a47cee7ad..2c8653491e 100644 --- a/src/test/groovy/graphql/execution/ExecutionStrategyExceptionHandlingEquivalenceTest.groovy +++ b/src/test/groovy/graphql/execution/ExecutionStrategyExceptionHandlingEquivalenceTest.groovy @@ -4,7 +4,8 @@ import graphql.ExecutionInput import graphql.GraphQL import graphql.StarWarsSchema import graphql.execution.instrumentation.InstrumentationContext -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters import graphql.validation.ValidationError import graphql.validation.ValidationErrorType @@ -13,11 +14,11 @@ import spock.lang.Unroll class ExecutionStrategyExceptionHandlingEquivalenceTest extends Specification { - class TestInstrumentation extends SimpleInstrumentation { + class TestInstrumentation extends SimplePerformantInstrumentation { @Override - InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - throw new AbortExecutionException([new ValidationError(ValidationErrorType.UnknownType)]) + InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + throw new AbortExecutionException([ValidationError.newValidationError().validationErrorType(ValidationErrorType.UnknownType).build()]) } } diff --git a/src/test/groovy/graphql/execution/ExecutionStrategyParametersTest.groovy b/src/test/groovy/graphql/execution/ExecutionStrategyParametersTest.groovy index d422f7e179..df09445497 100644 --- a/src/test/groovy/graphql/execution/ExecutionStrategyParametersTest.groovy +++ b/src/test/groovy/graphql/execution/ExecutionStrategyParametersTest.groovy @@ -1,30 +1,36 @@ package graphql.execution + import spock.lang.Specification -import static ExecutionTypeInfo.newTypeInfo +import static ExecutionStepInfo.newExecutionStepInfo import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mergedSelectionSet import static graphql.execution.ExecutionStrategyParameters.newParameters class ExecutionStrategyParametersTest extends Specification { def "ExecutionParameters can be transformed"() { given: + def executionContext = Mock(ExecutionContext) def parameters = newParameters() - .typeInfo(newTypeInfo().type(GraphQLString)) + .executionStepInfo(newExecutionStepInfo().type(GraphQLString)) .source(new Object()) - .fields("a": []) + .localContext("localContext") + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) + .fields(mergedSelectionSet("a": [])) .build() when: - def newParameters = parameters.transform { it -> it.source(123) } + def newParameters = parameters.transform { it -> it.source(123).localContext("newLocalContext") } then: - newParameters.getTypeInfo() == parameters.getTypeInfo() + newParameters.getExecutionStepInfo() == parameters.getExecutionStepInfo() newParameters.getFields() == parameters.getFields() newParameters.getSource() != parameters.getSource() newParameters.getSource() == 123 + newParameters.getLocalContext() == "newLocalContext" } } \ No newline at end of file diff --git a/src/test/groovy/graphql/execution/ExecutionStrategyTest.groovy b/src/test/groovy/graphql/execution/ExecutionStrategyTest.groovy index 27aeab5cb5..71eee4f284 100644 --- a/src/test/groovy/graphql/execution/ExecutionStrategyTest.groovy +++ b/src/test/groovy/graphql/execution/ExecutionStrategyTest.groovy @@ -1,13 +1,21 @@ package graphql.execution import graphql.Assert -import graphql.DataFetchingErrorGraphQLError +import graphql.EngineRunningState import graphql.ExceptionWhileDataFetching +import graphql.ExecutionInput import graphql.ExecutionResult +import graphql.GraphQLContext +import graphql.GraphqlErrorBuilder +import graphql.Profiler import graphql.Scalars import graphql.SerializationError +import graphql.StarWarsSchema import graphql.TypeMismatchError -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.execution.instrumentation.InstrumentationContext +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters import graphql.language.Argument import graphql.language.Field import graphql.language.OperationDefinition @@ -17,17 +25,26 @@ import graphql.parser.Parser import graphql.schema.Coercing import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLEnumType import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema +import graphql.schema.LightDataFetcher +import org.dataloader.DataLoaderRegistry import spock.lang.Specification import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionException +import java.util.function.Supplier +import java.util.stream.Stream import static ExecutionStrategyParameters.newParameters import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mergedField +import static graphql.TestUtil.mergedSelectionSet import static graphql.schema.GraphQLArgument.newArgument import static graphql.schema.GraphQLEnumType.newEnum import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition @@ -52,56 +69,87 @@ class ExecutionStrategyTest extends Specification { } } + def buildContext(GraphQLSchema schema = null) { ExecutionId executionId = ExecutionId.from("executionId123") + ExecutionInput ei = ExecutionInput.newExecutionInput("{}").build() def variables = [arg1: "value1"] - new ExecutionContext(SimpleInstrumentation.INSTANCE, executionId, schema, null, - executionStrategy, executionStrategy, executionStrategy, - null, null, null, - variables, "context", "root") + def builder = ExecutionContextBuilder.newExecutionContextBuilder() + .instrumentation(SimplePerformantInstrumentation.INSTANCE) + .executionId(executionId) + .graphQLSchema(schema ?: StarWarsSchema.starWarsSchema) + .queryStrategy(executionStrategy) + .mutationStrategy(executionStrategy) + .subscriptionStrategy(executionStrategy) + .coercedVariables(CoercedVariables.of(variables)) + .graphQLContext(GraphQLContext.newContext().of("key", "context").build()) + .executionInput(ei) + .root("root") + .dataLoaderRegistry(new DataLoaderRegistry()) + .locale(Locale.getDefault()) + .valueUnboxer(ValueUnboxer.DEFAULT) + .profiler(Profiler.NO_OP) + .engineRunningState(new EngineRunningState(ei, Profiler.NO_OP)) + + new ExecutionContext(builder) } @SuppressWarnings("GroovyAssignabilityCheck") def "complete values always calls query strategy to execute more"() { given: def dataFetcher = Mock(DataFetcher) + + def someFieldName = "someField" + def testTypeName = "Test" def fieldDefinition = newFieldDefinition() - .name("someField") + .name(someFieldName) .type(GraphQLString) - .dataFetcher(dataFetcher) .build() def objectType = newObject() - .name("Test") + .name(testTypeName) .field(fieldDefinition) .build() + def someFieldCoordinates = FieldCoordinates.coordinates(testTypeName, someFieldName) + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(someFieldCoordinates, dataFetcher) + .build() + def document = new Parser().parseDocument("{someField}") def operation = document.definitions[0] as OperationDefinition - GraphQLSchema schema = GraphQLSchema.newSchema().query(objectType).build() + GraphQLSchema schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(objectType) + .build() + def builder = new ExecutionContextBuilder() builder.queryStrategy(Mock(ExecutionStrategy)) builder.mutationStrategy(Mock(ExecutionStrategy)) builder.subscriptionStrategy(Mock(ExecutionStrategy)) builder.graphQLSchema(schema) + builder.valueUnboxer(ValueUnboxer.DEFAULT) builder.operationDefinition(operation) builder.executionId(ExecutionId.generate()) + builder.executionInput(ExecutionInput.newExecutionInput("{}").build()) def executionContext = builder.build() def result = new Object() def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(objectType)) + .executionStepInfo(ExecutionStepInfo.newExecutionStepInfo().type(objectType)) .source(result) - .fields(["fld": [Field.newField().build()]]) - .field([Field.newField().build()]) + .fields(mergedSelectionSet(["fld": [Field.newField().build()]])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) + .field(mergedField(Field.newField().build())) .build() when: executionStrategy.completeValue(executionContext, parameters) then: - 1 * executionContext.queryStrategy.execute(_, _) + 1 * executionContext.queryStrategy.executeObject(_, _) >> CompletableFuture.completedFuture(null) 0 * executionContext.mutationStrategy.execute(_, _) 0 * executionContext.subscriptionStrategy.execute(_, _) } @@ -111,24 +159,26 @@ class ExecutionStrategyTest extends Specification { given: ExecutionContext executionContext = buildContext() def fieldType = list(GraphQLString) + Field field = new Field("someField") def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).path(ResultPath.rootPath()).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def result = ["test", "1", "2", "3"] def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) + .field(mergedField(field)) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == result + executionResult == result } def "completes value for java.util.Optional"() { @@ -136,20 +186,20 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = GraphQLString def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .nonNullFieldValidator(nullableFieldValidator) .source(result) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == expected + executionResult == expected where: result || expected @@ -162,17 +212,17 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = nonNull(GraphQLString) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .nonNullFieldValidator(nullableFieldValidator) .source(Optional.ofNullable(null)) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: def e = thrown(CompletionException) @@ -184,24 +234,24 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = GraphQLString def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .nonNullFieldValidator(nullableFieldValidator) .source(result) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == expected + executionResult == expected where: - result || expected - OptionalInt.of(10) || "10" + result || expected + OptionalInt.of(10) || "10" OptionalInt.empty() || null } @@ -210,17 +260,17 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = nonNull(GraphQLString) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .nonNullFieldValidator(nullableFieldValidator) .source(OptionalInt.empty()) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: def e = thrown(CompletionException) @@ -232,24 +282,24 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = GraphQLString def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .nonNullFieldValidator(nullableFieldValidator) .source(result) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == expected + executionResult == expected where: - result || expected - OptionalDouble.of(10) || "10.0" + result || expected + OptionalDouble.of(10) || "10.0" OptionalDouble.empty() || null } @@ -258,17 +308,17 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = nonNull(GraphQLString) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .nonNullFieldValidator(nullableFieldValidator) .source(OptionalDouble.empty()) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: def e = thrown(CompletionException) @@ -280,24 +330,24 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = GraphQLString def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .nonNullFieldValidator(nullableFieldValidator) .source(result) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == expected + executionResult == expected where: - result || expected - OptionalLong.of(10) || "10" + result || expected + OptionalLong.of(10) || "10" OptionalLong.empty() || null } @@ -306,17 +356,17 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = nonNull(GraphQLString) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .nonNullFieldValidator(nullableFieldValidator) .source(OptionalLong.empty()) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) .build() when: - executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: def e = thrown(CompletionException) @@ -328,43 +378,44 @@ class ExecutionStrategyTest extends Specification { ExecutionContext executionContext = buildContext() def fieldType = list(GraphQLString) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).path(ResultPath.rootPath()).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def result = ["test", "1", "2", "3"] def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["fld": []]) + .fields(mergedSelectionSet(["fld": []])) + .field(mergedField(new Field("someField"))) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == result + executionResult == result } def "completing value with serializing throwing exception"() { given: ExecutionContext executionContext = buildContext() def fieldType = Scalars.GraphQLInt - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) String result = "not a number" def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["dummy": []]) + .fields(mergedSelectionSet(["dummy": []])) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == null + executionResult == null executionContext.errors.size() == 1 executionContext.errors[0] instanceof SerializationError @@ -374,22 +425,22 @@ class ExecutionStrategyTest extends Specification { given: ExecutionContext executionContext = buildContext() GraphQLEnumType enumType = newEnum().name("Enum").value("value").build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(enumType).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(enumType).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) String result = "not a enum number" def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["dummy": []]) + .fields(mergedSelectionSet(["dummy": []])) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == null + executionResult == null executionContext.errors.size() == 1 executionContext.errors[0] instanceof SerializationError @@ -397,7 +448,7 @@ class ExecutionStrategyTest extends Specification { def "completing a scalar null value for a non null type throws an exception"() { - GraphQLScalarType NullProducingScalar = new GraphQLScalarType("Custom", "It Can Produce Nulls", new Coercing() { + GraphQLScalarType NullProducingScalar = GraphQLScalarType.newScalar().name("Custom").description("It Can Produce Nulls").coercing(new Coercing() { @Override Double serialize(Object input) { if (input == 0xCAFED00Dd) { @@ -416,18 +467,19 @@ class ExecutionStrategyTest extends Specification { throw new UnsupportedOperationException("Not implemented") } }) + .build() ExecutionContext executionContext = buildContext() def fieldType = NullProducingScalar - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(nonNull(fieldType)).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(nonNull(fieldType)).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) when: def parameters = newParameters() - .typeInfo(ExecutionTypeInfo.newTypeInfo().type(fieldType)) + .executionStepInfo(ExecutionStepInfo.newExecutionStepInfo().type(fieldType)) .source(result) - .fields(["dummy": []]) + .fields(mergedSelectionSet(["dummy": []])) .nonNullFieldValidator(nullableFieldValidator) .build() @@ -457,52 +509,63 @@ class ExecutionStrategyTest extends Specification { @SuppressWarnings("GroovyVariableNotAssigned") def "resolveField creates correct DataFetchingEnvironment"() { - def dataFetcher = Mock(DataFetcher) + def dataFetcher = Mock(LightDataFetcher) + def someFieldName = "someField" + def testTypeName = "Type" def fieldDefinition = newFieldDefinition() - .name("someField") + .name(someFieldName) .type(GraphQLString) - .dataFetcher(dataFetcher) .argument(newArgument().name("arg1").type(GraphQLString)) .build() def objectType = newObject() - .name("Test") + .name(testTypeName) .field(fieldDefinition) .build() - GraphQLSchema schema = GraphQLSchema.newSchema().query(objectType).build() + def someFieldCoordinates = FieldCoordinates.coordinates(testTypeName, someFieldName) + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(someFieldCoordinates, dataFetcher) + .build() + + GraphQLSchema schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(objectType) + .build() ExecutionContext executionContext = buildContext(schema) - ExecutionTypeInfo typeInfo = ExecutionTypeInfo.newTypeInfo().type(objectType).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + ExecutionStepInfo typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(objectType).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) Argument argument = new Argument("arg1", new StringValue("argVal")) - Field field = new Field("someField", [argument]) - ExecutionPath executionPath = ExecutionPath.rootPath().segment("test") + Field field = new Field(someFieldName, [argument]) + MergedField mergedField = mergedField(field) + ResultPath resultPath = ResultPath.rootPath().segment("test") def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .source("source") - .fields(["someField": [field]]) - .field([field]) + .fields(mergedSelectionSet(["someField": [field]])) + .field(mergedField) .nonNullFieldValidator(nullableFieldValidator) - .path(executionPath) + .path(resultPath) .build() DataFetchingEnvironment environment when: - executionStrategy.resolveField(executionContext, parameters) + executionStrategy.resolveFieldWithInfo(executionContext, parameters) then: - 1 * dataFetcher.get({ it -> environment = it } as DataFetchingEnvironment) + 1 * dataFetcher.get(_, _, _) >> { environment = (it[2] as Supplier).get() } environment.fieldDefinition == fieldDefinition environment.graphQLSchema == schema - environment.context == "context" + environment.graphQlContext.get("key") == "context" environment.source == "source" - environment.fields == [field] + environment.mergedField == mergedField environment.root == "root" environment.parentType == objectType environment.arguments == ["arg1": "argVal"] - environment.fieldTypeInfo.type == GraphQLString - environment.fieldTypeInfo.path == executionPath - environment.fieldTypeInfo.parentTypeInfo.type == objectType + environment.executionStepInfo.getUnwrappedNonNullType() == GraphQLString + environment.executionStepInfo.path == resultPath + environment.executionStepInfo.parent.getUnwrappedNonNullType() == objectType environment.executionId == ExecutionId.from("executionId123") } @@ -513,52 +576,67 @@ class ExecutionStrategyTest extends Specification { throw expectedException } } - def fieldDefinition = newFieldDefinition().name("someField").type(GraphQLString).dataFetcher(dataFetcher).build() + + def someFieldName = "someField" + def testTypeName = "Test" + def fieldDefinition = newFieldDefinition() + .name(someFieldName) + .type(GraphQLString) + .build() def objectType = newObject() - .name("Test") + .name(testTypeName) .field(fieldDefinition) .build() - def schema = GraphQLSchema.newSchema().query(objectType).build() + + def someFieldCoordinates = FieldCoordinates.coordinates(testTypeName, someFieldName) + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(someFieldCoordinates, dataFetcher) + .build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(objectType) + .build() ExecutionContext executionContext = buildContext(schema) - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(objectType).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) - ExecutionPath expectedPath = ExecutionPath.rootPath().segment("someField") + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(objectType).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) + ResultPath expectedPath = ResultPath.rootPath().segment(someFieldName) SourceLocation sourceLocation = new SourceLocation(666, 999) - Field field = Field.newField("someField").sourceLocation(sourceLocation).build() + Field field = Field.newField(someFieldName).sourceLocation(sourceLocation).build() def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .source("source") - .fields(["someField": [field]]) - .field([field]) + .fields(mergedSelectionSet(["someField": [field]])) + .field(mergedField(field)) .path(expectedPath) .nonNullFieldValidator(nullableFieldValidator) .build() [executionContext, fieldDefinition, expectedPath, parameters, field, sourceLocation] } - def "test that the new data fetcher error handler interface is called"() { def expectedException = new UnsupportedOperationException("This is the exception you are looking for") //noinspection GroovyAssignabilityCheck,GroovyUnusedAssignment - def (ExecutionContext executionContext, GraphQLFieldDefinition fieldDefinition, ExecutionPath expectedPath, ExecutionStrategyParameters parameters, Field field, SourceLocation sourceLocation) = exceptionSetupFixture(expectedException) + def (ExecutionContext executionContext, GraphQLFieldDefinition fieldDefinition, ResultPath expectedPath, ExecutionStrategyParameters parameters, Field field, SourceLocation sourceLocation) = exceptionSetupFixture(expectedException) boolean handlerCalled = false ExecutionStrategy overridingStrategy = new AsyncExecutionStrategy(new SimpleDataFetcherExceptionHandler() { + + @Override - void accept(DataFetcherExceptionHandlerParameters handlerParameters) { + CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { handlerCalled = true assert handlerParameters.exception == expectedException - assert handlerParameters.executionContext == executionContext assert handlerParameters.fieldDefinition == fieldDefinition assert handlerParameters.field.name == 'someField' assert handlerParameters.path == expectedPath // by calling down we are testing the base class as well - super.accept(handlerParameters) + super.handleException(handlerParameters) } }) { @Override @@ -568,7 +646,7 @@ class ExecutionStrategyTest extends Specification { } when: - overridingStrategy.resolveField(executionContext, parameters) + overridingStrategy.resolveFieldWithInfo(executionContext, parameters) then: handlerCalled == true @@ -578,13 +656,28 @@ class ExecutionStrategyTest extends Specification { exceptionWhileDataFetching.getMessage().contains('This is the exception you are looking for') } - def "test that the old legacy method is still useful for those who derive new execution strategies"() { + def "#2519 data fetcher errors for a given field appear in FetchedResult within instrumentation"() { def expectedException = new UnsupportedOperationException("This is the exception you are looking for") //noinspection GroovyAssignabilityCheck,GroovyUnusedAssignment - def (ExecutionContext executionContext, GraphQLFieldDefinition fieldDefinition, ExecutionPath expectedPath, ExecutionStrategyParameters parameters, Field field, SourceLocation sourceLocation) = exceptionSetupFixture(expectedException) + def (ExecutionContext executionContext, GraphQLFieldDefinition fieldDefinition, ResultPath expectedPath, ExecutionStrategyParameters params, Field field, SourceLocation sourceLocation) = exceptionSetupFixture(expectedException) + + ExecutionContextBuilder executionContextBuilder = ExecutionContextBuilder.newExecutionContextBuilder(executionContext) + def instrumentation = new SimplePerformantInstrumentation() { + Map fetchedValues = [:] + @Override + @Override + InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + if (parameters.getFetchedObject() instanceof FetchedValue) { + FetchedValue value = (FetchedValue) parameters.getFetchedObject() + fetchedValues.put(parameters.field.name, value) + } + return super.beginFieldCompletion(parameters, state) + } + } + ExecutionContext instrumentedExecutionContext = executionContextBuilder.instrumentation(instrumentation).build() ExecutionStrategy overridingStrategy = new ExecutionStrategy() { @Override @@ -594,12 +687,16 @@ class ExecutionStrategyTest extends Specification { } when: - overridingStrategy.resolveField(executionContext, parameters) + overridingStrategy.resolveFieldWithInfo(instrumentedExecutionContext, params) then: - executionContext.errors.size() == 1 - def exceptionWhileDataFetching = executionContext.errors[0] as ExceptionWhileDataFetching + Object fetchedValue = instrumentation.fetchedValues.get("someField") + fetchedValue != null + fetchedValue.errors.size() == 1 + def exceptionWhileDataFetching = fetchedValue.errors[0] as ExceptionWhileDataFetching exceptionWhileDataFetching.getMessage().contains('This is the exception you are looking for') + instrumentedExecutionContext.errors.size() == 1 + instrumentedExecutionContext.errors[0] == fetchedValue.errors[0] } def "#522 - single error during execution - not two errors"() { @@ -612,34 +709,47 @@ class ExecutionStrategyTest extends Specification { throw new RuntimeException("bang") } } + + def someFieldName = "someField" + def testTypeName = "Test" + def fieldDefinition = newFieldDefinition() - .name("someField") + .name(someFieldName) .type(nonNull(GraphQLString)) - .dataFetcher(dataFetcher) .build() def objectType = newObject() - .name("Test") + .name(testTypeName) .field(fieldDefinition) .build() - GraphQLSchema schema = GraphQLSchema.newSchema().query(objectType).build() + def someFieldCoordinates = FieldCoordinates.coordinates(testTypeName, someFieldName) + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(someFieldCoordinates, dataFetcher) + .build() + + GraphQLSchema schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(objectType) + .build() ExecutionContext executionContext = buildContext(schema) - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(objectType).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) - Field field = new Field("someField") + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(objectType).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) + Field field = new Field(someFieldName) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .source(null) .nonNullFieldValidator(nullableFieldValidator) - .field([field]) - .fields(["someField": [field]]) - .path(ExecutionPath.rootPath().segment("abc")) + .field(mergedField(field)) + .fields(mergedSelectionSet(["someField": [mergedField(field)]])) + .path(ResultPath.rootPath().segment("abc")) .build() when: - executionStrategy.resolveField(executionContext, parameters).join() + FieldValueInfo fieldValueInfo = (executionStrategy.resolveFieldWithInfo(executionContext, parameters) as CompletableFuture).join() + (fieldValueInfo.fieldValueObject as CompletableFuture).join() then: thrown(CompletionException) @@ -650,77 +760,171 @@ class ExecutionStrategyTest extends Specification { def "#163 completes value for an primitive type array"() { given: ExecutionContext executionContext = buildContext() - long[] result = [1L, 2L, 3L] - def fieldType = list(Scalars.GraphQLLong) + long[] result = [1, 2, 3] + def fieldType = list(Scalars.GraphQLInt) + def fldDef = newFieldDefinition().name("test").type(fieldType).build() + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).path(ResultPath.rootPath()).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) + + def parameters = newParameters() + .executionStepInfo(executionStepInfo) + .source(result) + .nonNullFieldValidator(nullableFieldValidator) + .fields(mergedSelectionSet(["fld": [mergedField(Field.newField().build())]])) + .field(mergedField(Field.newField().build())) + .build() + + when: + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() + + then: + executionResult == [1, 2, 3] + } + + def "#842 completes value for java.util.Stream"() { + given: + ExecutionContext executionContext = buildContext() + Stream result = Stream.of(1L, 2L, 3L) + def fieldType = list(Scalars.GraphQLInt) + def fldDef = newFieldDefinition().name("test").type(fieldType).build() + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).path(ResultPath.rootPath()).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) + + def parameters = newParameters() + .executionStepInfo(executionStepInfo) + .source(result) + .nonNullFieldValidator(nullableFieldValidator) + .fields(mergedSelectionSet(["fld": [mergedField(Field.newField().build())]])) + .field(mergedField(Field.newField().build())) + .build() + + when: + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() + + then: + executionResult == [1, 2, 3] + } + + def "#842 completes value for java.util.Iterator"() { + given: + ExecutionContext executionContext = buildContext() + Iterator result = Arrays.asList(1L, 2L, 3L).iterator() + def fieldType = list(Scalars.GraphQLInt) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).path(ResultPath.rootPath()).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["fld": [Field.newField().build()]]) - .field([Field.newField().build()]) + .fields(mergedSelectionSet(["fld": [mergedField(Field.newField().build())]])) + .field(mergedField(Field.newField().build())) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.get().data == [1L, 2L, 3L] + executionResult == [1, 2, 3] } + def "#820 processes DataFetcherResult"() { given: ExecutionContext executionContext = buildContext() - def fieldType = list(Scalars.GraphQLLong) + def fieldType = list(Scalars.GraphQLInt) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() def field = Field.newField("parent").sourceLocation(new SourceLocation(5, 10)).build() def parameters = newParameters() - .path(ExecutionPath.fromList(["parent"])) - .field([field]) - .fields(["parent":[field]]) - .typeInfo(typeInfo) - .build() + .path(ResultPath.fromList(["parent"])) + .field(mergedField(field)) + .fields(mergedSelectionSet(["parent": [mergedField(field)]])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) + .executionStepInfo(executionStepInfo) + .build() def executionData = ["child": [:]] when: - def executionResult = executionStrategy.unboxPossibleDataFetcherResult(executionContext, parameters, - new DataFetcherResult(executionData, [new DataFetchingErrorGraphQLError("bad foo", ["child", "foo"])])) + def fetchedValue = executionStrategy.unboxPossibleDataFetcherResult(executionContext, parameters, + DataFetcherResult.newResult().data(executionData) + .error(GraphqlErrorBuilder.newError().message("bad foo").path(["child", "foo"]).build()) + .build() + ) then: - executionResult == executionData - executionContext.getErrors()[0].locations == [new SourceLocation(7, 20)] + fetchedValue.getFetchedValue() == executionData +// executionContext.getErrors()[0].locations == [new SourceLocation(7, 20)] executionContext.getErrors()[0].message == "bad foo" - executionContext.getErrors()[0].path == ["parent", "child", "foo"] + executionContext.getErrors()[0].path == ["child", "foo"] + } + + def "#1558 forward localContext on nonBoxed return from DataFetcher"() { + given: + def capturedLocalContext = "startingValue" + executionStrategy = new ExecutionStrategy(dataFetcherExceptionHandler) { + @Override + CompletableFuture execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { + return null + } + + @Override + protected FieldValueInfo completeValue(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException { + // shows we set the local context if the value is non boxed + capturedLocalContext = parameters.getLocalContext() + return super.completeValue(executionContext, parameters) + } + } + + ExecutionContext executionContext = buildContext() + def fieldType = StarWarsSchema.droidType + def fldDef = StarWarsSchema.droidType.getFieldDefinition("name") + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + def field = Field.newField("name").sourceLocation(new SourceLocation(5, 10)).build() + def localContext = "localContext" + def parameters = newParameters() + .path(ResultPath.fromList(["name"])) + .localContext(localContext) + .field(mergedField(field)) + .fields(mergedSelectionSet(["name": [mergedField(field)]])) + .executionStepInfo(executionStepInfo) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) + .build() + + when: + executionStrategy.completeField(executionContext, parameters, new Object()) + + then: + capturedLocalContext == localContext } def "#820 processes DataFetcherResult just message"() { given: ExecutionContext executionContext = buildContext() - def fieldType = list(Scalars.GraphQLLong) + def fieldType = list(Scalars.GraphQLInt) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() def field = Field.newField("parent").sourceLocation(new SourceLocation(5, 10)).build() def parameters = newParameters() - .path(ExecutionPath.fromList(["parent"])) - .field([field]) - .fields(["parent":[field]]) - .typeInfo(typeInfo) + .path(ResultPath.fromList(["parent"])) + .field(mergedField(field)) + .fields(mergedSelectionSet(["parent": [mergedField(field)]])) + .nonNullFieldValidator(new NonNullableFieldValidator(executionContext)) + .executionStepInfo(executionStepInfo) .build() def executionData = ["child": [:]] when: - def executionResult = executionStrategy.unboxPossibleDataFetcherResult(executionContext, parameters, - new DataFetcherResult(executionData, [new DataFetchingErrorGraphQLError("bad foo")])) - + def fetchedValue = executionStrategy.unboxPossibleDataFetcherResult(executionContext, parameters, + DataFetcherResult.newResult().data(executionData) + .error(GraphqlErrorBuilder.newError().message("bad foo").build()) + .build()) then: - executionResult == executionData - executionContext.getErrors()[0].locations == null + fetchedValue.getFetchedValue() == executionData + executionContext.getErrors()[0].locations == [] executionContext.getErrors()[0].message == "bad foo" executionContext.getErrors()[0].path == null } @@ -729,48 +933,48 @@ class ExecutionStrategyTest extends Specification { given: ExecutionContext executionContext = buildContext() List result = [1L, 2L, 3L] - def fieldType = list(Scalars.GraphQLLong) + def fieldType = list(Scalars.GraphQLInt) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def executionStepInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).path(ResultPath.rootPath()).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(executionStepInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["fld": [Field.newField().build()]]) - .field([Field.newField().build()]) + .fields(mergedSelectionSet(["fld": [mergedField(Field.newField().build())]])) + .field(mergedField(Field.newField().build())) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.get().data == [1L, 2L, 3L] + executionResult == [1L, 2L, 3L] } def "when completeValue expects GraphQLList and non iterable or non array is passed then it should yield a TypeMismatch error"() { given: ExecutionContext executionContext = buildContext() Map result = new HashMap<>() - def fieldType = list(Scalars.GraphQLLong) + def fieldType = list(Scalars.GraphQLInt) def fldDef = newFieldDefinition().name("test").type(fieldType).build() - def typeInfo = ExecutionTypeInfo.newTypeInfo().type(fieldType).fieldDefinition(fldDef).build() - NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext, typeInfo) + def typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(fieldType).fieldDefinition(fldDef).build() + NonNullableFieldValidator nullableFieldValidator = new NonNullableFieldValidator(executionContext) def parameters = newParameters() - .typeInfo(typeInfo) + .executionStepInfo(typeInfo) .source(result) .nonNullFieldValidator(nullableFieldValidator) - .fields(["fld": [Field.newField().build()]]) - .field([Field.newField().build()]) + .fields(mergedSelectionSet(["fld": [mergedField(Field.newField().build())]])) + .field(mergedField(Field.newField().build())) .build() when: - def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValue.join() + def executionResult = executionStrategy.completeValue(executionContext, parameters).fieldValueFuture.join() then: - executionResult.data == null + executionResult == null executionContext.errors.size() == 1 executionContext.errors[0] instanceof TypeMismatchError } diff --git a/src/test/groovy/graphql/execution/ExecutionTest.groovy b/src/test/groovy/graphql/execution/ExecutionTest.groovy index 02af8fa4bc..46ac3c7942 100644 --- a/src/test/groovy/graphql/execution/ExecutionTest.groovy +++ b/src/test/groovy/graphql/execution/ExecutionTest.groovy @@ -1,11 +1,14 @@ package graphql.execution +import graphql.EngineRunningState import graphql.ExecutionInput import graphql.ExecutionResult import graphql.ExecutionResultImpl import graphql.MutationSchema +import graphql.Profiler import graphql.execution.instrumentation.InstrumentationState -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters import graphql.parser.Parser import spock.lang.Specification @@ -34,17 +37,12 @@ class ExecutionTest extends Specification { def subscriptionStrategy = new CountingExecutionStrategy() def mutationStrategy = new CountingExecutionStrategy() def queryStrategy = new CountingExecutionStrategy() - def execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, SimpleInstrumentation.INSTANCE) - def emptyExecutionInput = ExecutionInput.newExecutionInput().build() + def execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, SimplePerformantInstrumentation.INSTANCE, ValueUnboxer.DEFAULT, false) + def emptyExecutionInput = ExecutionInput.newExecutionInput().query("query").build() def instrumentationState = new InstrumentationState() {} def "query strategy is used for query requests"() { given: - def mutationStrategy = new CountingExecutionStrategy() - - def queryStrategy = new CountingExecutionStrategy() - def execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, SimpleInstrumentation.INSTANCE) - def query = ''' query { numberHolder { @@ -55,7 +53,7 @@ class ExecutionTest extends Specification { def document = parser.parseDocument(query) when: - execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState) + execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState, new EngineRunningState(emptyExecutionInput, Profiler.NO_OP), Profiler.NO_OP) then: queryStrategy.execute == 1 @@ -75,7 +73,7 @@ class ExecutionTest extends Specification { def document = parser.parseDocument(query) when: - execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState) + execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState, new EngineRunningState(emptyExecutionInput, Profiler.NO_OP), Profiler.NO_OP) then: queryStrategy.execute == 0 @@ -87,7 +85,7 @@ class ExecutionTest extends Specification { given: def query = ''' subscription { - numberChanged(newNumber: 1) { + changeNumberSubscribe(clientId: 1) { theNumber } } @@ -95,11 +93,51 @@ class ExecutionTest extends Specification { def document = parser.parseDocument(query) when: - execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState) + execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState, new EngineRunningState(emptyExecutionInput, Profiler.NO_OP), Profiler.NO_OP) then: queryStrategy.execute == 0 mutationStrategy.execute == 0 subscriptionStrategy.execute == 1 } + + def "Update query strategy when instrumenting execution context"() { + given: + def query = ''' + query { + numberHolder { + theNumber + } + } + ''' + def document = parser.parseDocument(query) + def queryStrategyUpdatedToDuringExecutionContextInstrument = new CountingExecutionStrategy() + + def instrumentation = new SimplePerformantInstrumentation() { + + @Override + ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, + InstrumentationExecutionParameters parameters, + InstrumentationState state) { + + return ExecutionContextBuilder.newExecutionContextBuilder(executionContext) + .queryStrategy(queryStrategyUpdatedToDuringExecutionContextInstrument) + .build() + } + } + + def execution = new Execution(queryStrategy, mutationStrategy, subscriptionStrategy, instrumentation, ValueUnboxer.DEFAULT, false) + + + when: + execution.execute(document, MutationSchema.schema, ExecutionId.generate(), emptyExecutionInput, instrumentationState, new EngineRunningState(emptyExecutionInput, Profiler.NO_OP), Profiler.NO_OP) + + then: + queryStrategy.execute == 0 + mutationStrategy.execute == 0 + subscriptionStrategy.execute == 0 + queryStrategyUpdatedToDuringExecutionContextInstrument.execute == 1 + } + + } diff --git a/src/test/groovy/graphql/execution/ExecutionTypeInfoTest.groovy b/src/test/groovy/graphql/execution/ExecutionTypeInfoTest.groovy deleted file mode 100644 index 8179be8f60..0000000000 --- a/src/test/groovy/graphql/execution/ExecutionTypeInfoTest.groovy +++ /dev/null @@ -1,92 +0,0 @@ -package graphql.execution - -import graphql.schema.GraphQLInterfaceType -import graphql.schema.GraphQLList -import graphql.schema.GraphQLNonNull -import graphql.schema.GraphQLObjectType -import graphql.schema.GraphQLType -import spock.lang.Specification - -import static ExecutionTypeInfo.newTypeInfo -import static graphql.Scalars.GraphQLString -import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition -import static graphql.schema.GraphQLList.list -import static graphql.schema.GraphQLNonNull.nonNull - -class ExecutionTypeInfoTest extends Specification { - - def field1Def = newFieldDefinition().name("field1").type(GraphQLString).build() - - def interfaceType = GraphQLInterfaceType.newInterface().name("Interface") - .field(field1Def) - .typeResolver({ env -> null }) - .build() - - def fieldType = GraphQLObjectType.newObject() - .name("FieldType") - .field(field1Def) - .build() - - def rootType = GraphQLObjectType.newObject() - .name("RootType") - .field(newFieldDefinition().name("rootField1").type(fieldType)) - .build() - - - def "basic hierarchy"() { - given: - def rootTypeInfo = newTypeInfo().type(rootType).build() - def fieldTypeInfo = newTypeInfo().type(fieldType).fieldDefinition(field1Def).parentInfo(rootTypeInfo).build() - def nonNullFieldTypeInfo = newTypeInfo().type(nonNull(fieldType)).parentInfo(rootTypeInfo).build() - def listTypeInfo = newTypeInfo().type(list(fieldType)).parentInfo(rootTypeInfo).build() - - expect: - rootTypeInfo.type == rootType - !rootTypeInfo.hasParentType() - - fieldTypeInfo.type == fieldType - fieldTypeInfo.hasParentType() - fieldTypeInfo.parentTypeInfo.type == rootType - !fieldTypeInfo.isNonNullType() - fieldTypeInfo.getFieldDefinition() == field1Def - - nonNullFieldTypeInfo.type == fieldType - nonNullFieldTypeInfo.hasParentType() - nonNullFieldTypeInfo.parentTypeInfo.type == rootType - nonNullFieldTypeInfo.isNonNullType() - - listTypeInfo.type == list(fieldType) - listTypeInfo.hasParentType() - listTypeInfo.parentTypeInfo.type == rootType - listTypeInfo.isListType() - } - - def "morphing type works"() { - given: - def rootTypeInfo = newTypeInfo().type(rootType).build() - def interfaceTypeInfo = newTypeInfo().type(interfaceType).parentInfo(rootTypeInfo).build() - def morphedTypeInfo = interfaceTypeInfo.treatAs(fieldType) - - expect: - - interfaceTypeInfo.type == interfaceType - morphedTypeInfo.type == fieldType - } - - def "unwrapping stack works"() { - - given: - // [[String!]!] - GraphQLType wrappedType = list(nonNull(list(nonNull(GraphQLString)))) - def stack = ExecutionTypeInfo.unwrapType(wrappedType) - - expect: - stack.pop() == GraphQLString - stack.pop() instanceof GraphQLNonNull - stack.pop() instanceof GraphQLList - stack.pop() instanceof GraphQLNonNull - stack.pop() instanceof GraphQLList - stack.isEmpty() - - } -} diff --git a/src/test/groovy/graphql/execution/ExecutorServiceExecutionStrategyTest.groovy b/src/test/groovy/graphql/execution/ExecutorServiceExecutionStrategyTest.groovy deleted file mode 100644 index fc9ec00198..0000000000 --- a/src/test/groovy/graphql/execution/ExecutorServiceExecutionStrategyTest.groovy +++ /dev/null @@ -1,74 +0,0 @@ -package graphql.execution - -import graphql.GraphQL -import graphql.StarWarsSchema -import spock.lang.Specification - -import java.util.concurrent.BlockingQueue -import java.util.concurrent.LinkedBlockingQueue -import java.util.concurrent.ThreadPoolExecutor -import java.util.concurrent.TimeUnit - -class ExecutorServiceExecutionStrategyTest extends Specification { - - def 'Example usage of ExecutorServiceExecutionStrategy.'() { - given: - def query = """ - query HeroNameAndFriendsQuery { - hero { - id - friends { - name - } - } - } - """ - def expected = [ - hero: [ - id : '2001', - friends: [ - [ - name: 'Luke Skywalker', - ], - [ - name: 'Han Solo', - ], - [ - name: 'Leia Organa', - ], - ] - ] - ] - - when: - BlockingQueue queue = new LinkedBlockingQueue() { - @Override - boolean offer(Runnable e) { - /* queue that always rejects tasks */ - return false - } - } - - ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( - 2, /* core pool size 2 thread */ - 2, /* max pool size 2 thread */ - 30, TimeUnit.SECONDS, - /* - * Do not use the queue to prevent threads waiting on enqueued tasks. - */ - queue, - /* - * If all the threads are working, then the caller thread - * should execute the code in its own thread. (serially) - */ - new ThreadPoolExecutor.CallerRunsPolicy()) - - def graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) - .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(threadPoolExecutor)) - .build() - def result = graphQL.execute(query).data - - then: - result == expected - } -} diff --git a/src/test/groovy/graphql/execution/ExperimentalDisableErrorPropagationTest.groovy b/src/test/groovy/graphql/execution/ExperimentalDisableErrorPropagationTest.groovy new file mode 100644 index 0000000000..366c95426e --- /dev/null +++ b/src/test/groovy/graphql/execution/ExperimentalDisableErrorPropagationTest.groovy @@ -0,0 +1,114 @@ +package graphql.execution + +import graphql.Directives +import graphql.ExecutionInput +import graphql.TestUtil +import spock.lang.Specification + +class ExperimentalDisableErrorPropagationTest extends Specification { + + void setup() { + Directives.setExperimentalDisableErrorPropagationEnabled(true) + } + + def "with experimental_disableErrorPropagation, null is returned"() { + + def sdl = ''' + type Query { + foo : Int! + } + directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + ''' + + def graphql = TestUtil.graphQL(sdl).build() + + def query = ''' + query GetFoo @experimental_disableErrorPropagation { foo } + ''' + when: + + ExecutionInput ei = ExecutionInput.newExecutionInput(query).root( + [foo: null] + ).build() + + def er = graphql.execute(ei) + + then: + er.data != null + er.data.foo == null + er.errors[0].path.toList() == ["foo"] + } + + def "without experimental_disableErrorPropagation, error is propagated"() { + + def sdl = ''' + type Query { + foo : Int! + } + directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + ''' + + def graphql = TestUtil.graphQL(sdl).build() + + def query = ''' + query GetFoo { foo } + ''' + when: + + ExecutionInput ei = ExecutionInput.newExecutionInput(query).root( + [foo: null] + ).build() + + def er = graphql.execute(ei) + + then: + er.data == null + er.errors[0].message == "The field at path '/foo' was declared as a non null type, but the code involved in retrieving data has wrongly returned a null value. The graphql specification requires that the parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on. The non-nullable type is 'Int' within parent type 'Query'" + er.errors[0].path.toList() == ["foo"] + } + + def "With experimental_disableErrorPropagation JVM disabled, error is propagated"() { + def sdl = ''' + type Query { + foo : Int! + } + directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + ''' + + def graphql = TestUtil.graphQL(sdl).build() + + def query = ''' + query GetFoo @experimental_disableErrorPropagation { foo } + ''' + when: + + Directives.setExperimentalDisableErrorPropagationEnabled(false) // JVM wide + + ExecutionInput ei = ExecutionInput.newExecutionInput(query).root( + [foo: null] + ).build() + + def er = graphql.execute(ei) + + then: + er.data == null + er.errors[0].message == "The field at path '/foo' was declared as a non null type, but the code involved in retrieving data has wrongly returned a null value. The graphql specification requires that the parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on. The non-nullable type is 'Int' within parent type 'Query'" + er.errors[0].path.toList() == ["foo"] + } + + def "when @experimental_disableErrorPropagation is not added to the schema operation is gets added by schema code"() { + + def sdl = ''' + type Query { + foo : Int! + } + ''' + + when: + def graphql = TestUtil.graphQL(sdl).build() + + then: + graphql.getGraphQLSchema().getDirective(Directives.ExperimentalDisableErrorPropagationDirective.getName()) === Directives.ExperimentalDisableErrorPropagationDirective + } + +} diff --git a/src/test/groovy/graphql/execution/FieldCollectorTest.groovy b/src/test/groovy/graphql/execution/FieldCollectorTest.groovy index f5be40313a..6460512543 100644 --- a/src/test/groovy/graphql/execution/FieldCollectorTest.groovy +++ b/src/test/groovy/graphql/execution/FieldCollectorTest.groovy @@ -9,6 +9,7 @@ import graphql.parser.Parser import graphql.schema.GraphQLObjectType import spock.lang.Specification +import static graphql.TestUtil.mergedField import static graphql.execution.FieldCollectorParameters.newParameters class FieldCollectorTest extends Specification { @@ -20,7 +21,7 @@ class FieldCollectorTest extends Specification { type Query { bar1: String bar2: String - } + } """) def objectType = schema.getType("Query") as GraphQLObjectType FieldCollector fieldCollector = new FieldCollector() @@ -35,11 +36,11 @@ class FieldCollectorTest extends Specification { def bar2 = field.selectionSet.selections[1] when: - def result = fieldCollector.collectFields(fieldCollectorParameters, [field]) + def result = fieldCollector.collectFields(fieldCollectorParameters, mergedField(field)) then: - result['bar1'] == [bar1] - result['bar2'] == [bar2] + result.getSubField('bar1').getFields() == [bar1] + result.getSubField('bar2').getFields() == [bar2] } def "collect fields on inline fragments"() { @@ -47,12 +48,12 @@ class FieldCollectorTest extends Specification { type Query{ bar1: String bar2: Test - } + } interface Test { - fieldOnInterface: String - } + fieldOnInterface: String + } type TestImpl implements Test { - fieldOnInterface: String + fieldOnInterface: String } """) def object = schema.getType("TestImpl") as GraphQLObjectType @@ -68,10 +69,140 @@ class FieldCollectorTest extends Specification { def interfaceField = inlineFragment.selectionSet.selections[0] when: - def result = fieldCollector.collectFields(fieldCollectorParameters, [bar1Field]) + def result = fieldCollector.collectFields(fieldCollectorParameters, mergedField(bar1Field)) + + then: + result.getSubField('fieldOnInterface').getFields() == [interfaceField] + } + + def "collect fields that are merged together - one of the fields is on an inline fragment "() { + def schema = TestUtil.schema(""" + type Query { + echo: String + } +""") + + Document document = new Parser().parseDocument(""" + { + echo + ... on Query { + echo + } + } + +""") + + def object = schema.getType("TestImpl") as GraphQLObjectType + FieldCollector fieldCollector = new FieldCollector() + FieldCollectorParameters fieldCollectorParameters = newParameters() + .schema(schema) + .objectType(object) + .build() + + def selectionSet = ((OperationDefinition) document.children[0]).selectionSet + + when: + def result = fieldCollector.collectFields(fieldCollectorParameters, selectionSet) then: - result['fieldOnInterface'] == [interfaceField] + result.size() == 1 + result.getSubField('echo').fields.size() == 1 + } + + def "collect fields that are merged together - fields have different selection sets "() { + def schema = TestUtil.schema(""" + type Query { + me: Me + } + + type Me { + firstname: String + lastname: String + } +""") + + Document document = new Parser().parseDocument(""" + { + me { + firstname + } + me { + lastname + } + } + +""") + + def object = schema.getType("TestImpl") as GraphQLObjectType + FieldCollector fieldCollector = new FieldCollector() + FieldCollectorParameters fieldCollectorParameters = newParameters() + .schema(schema) + .objectType(object) + .build() + + def selectionSet = ((OperationDefinition) document.children[0]).selectionSet + + when: + def result = fieldCollector.collectFields(fieldCollectorParameters, selectionSet) + + then: + result.size() == 1 + + def meField = result.getSubField('me') + + meField.fields.size() == 2 + + meField.fields[0].selectionSet.selections.size() == 1 + meField.fields[0].selectionSet.selections[0].name == "firstname" + + meField.fields[1].selectionSet.selections.size() == 1 + meField.fields[1].selectionSet.selections[0].name == "lastname" + } + + def "collect fields that are merged together - fields have different directives"() { + def schema = TestUtil.schema(""" + directive @one on FIELD + directive @two on FIELD + + type Query { + echo: String + } +""") + + Document document = new Parser().parseDocument(""" + { + echo @one + echo @two + } + +""") + + def object = schema.getType("TestImpl") as GraphQLObjectType + FieldCollector fieldCollector = new FieldCollector() + FieldCollectorParameters fieldCollectorParameters = newParameters() + .schema(schema) + .objectType(object) + .build() + + def selectionSet = ((OperationDefinition) document.children[0]).selectionSet + + when: + def result = fieldCollector.collectFields(fieldCollectorParameters, selectionSet) + + then: + result.size() == 1 + + def echoField = result.getSubField('echo') + + echoField.fields.size() == 2 + + echoField.fields[0].name == "echo" + echoField.fields[0].directives.size() == 1 + echoField.fields[0].directives[0].name == "one" + + echoField.fields[1].name == "echo" + echoField.fields[1].directives.size() == 1 + echoField.fields[1].directives[0].name == "two" } } diff --git a/src/test/groovy/graphql/execution/FieldValueInfoTest.groovy b/src/test/groovy/graphql/execution/FieldValueInfoTest.groovy index 0fe4c30cec..5720d28444 100644 --- a/src/test/groovy/graphql/execution/FieldValueInfoTest.groovy +++ b/src/test/groovy/graphql/execution/FieldValueInfoTest.groovy @@ -3,26 +3,26 @@ package graphql.execution import graphql.AssertException import spock.lang.Specification +import java.util.concurrent.CompletableFuture -class FieldValueInfoTest extends Specification{ +import static graphql.execution.FieldValueInfo.CompleteValueType.SCALAR + + +class FieldValueInfoTest extends Specification { def "simple constructor test"() { when: - def fieldValueInfo = FieldValueInfo.newFieldValueInfo().build() + def fieldValueInfo = new FieldValueInfo(SCALAR, CompletableFuture.completedFuture("A")) then: "fieldValueInfos to be empty list" fieldValueInfo.fieldValueInfos == [] as List - - and: "other fields to be null " - fieldValueInfo.fieldValue == null - fieldValueInfo.completeValueType == null + fieldValueInfo.fieldValueFuture.join() == "A" + fieldValueInfo.completeValueType == SCALAR } def "negative constructor test"() { when: - FieldValueInfo.newFieldValueInfo() - .fieldValueInfos(null) - .build() + new FieldValueInfo(SCALAR, CompletableFuture.completedFuture("A"), null) then: def assEx = thrown(AssertException) assEx.message.contains("fieldValueInfos") diff --git a/src/test/groovy/graphql/execution/MaterialisedAndPromisedObjectsTest.groovy b/src/test/groovy/graphql/execution/MaterialisedAndPromisedObjectsTest.groovy new file mode 100644 index 0000000000..578e3b3ea9 --- /dev/null +++ b/src/test/groovy/graphql/execution/MaterialisedAndPromisedObjectsTest.groovy @@ -0,0 +1,97 @@ +package graphql.execution + + +import graphql.ExecutionResult +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.instrumentation.Instrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture + +import static graphql.ExecutionInput.newExecutionInput + +class MaterialisedAndPromisedObjectsTest extends Specification { + + def sdl = """ + type Query { + foo : Foo + } + + type Foo { + bar : Bar + name : String + } + + type Bar { + foo : Foo + name : String + } + """ + + def "make sure it can fetch both materialised and promised values"() { + + def cfPromisesOnFieldRegex = ~"neverMatchesAlwaysMaterialised" + Instrumentation fetchSwitcher = new SimplePerformantInstrumentation() { + @Override + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + return new DataFetcher() { + @Override + Object get(DataFetchingEnvironment env) throws Exception { + def fieldName = env.getField().name + def fetchValue = dataFetcher.get(env) + // if it matches the regex - we send back an async promise value + if (fieldName =~ cfPromisesOnFieldRegex) { + return CompletableFuture.supplyAsync { -> fetchValue } + } + // just the materialised value! + return fetchValue + } + } + } + } + + GraphQL graphQL = TestUtil.graphQL(sdl).instrumentation(fetchSwitcher).build() + + + def source = [foo: [bar: [foo: [name: "stop"]]]] + def expectedData = [foo: [bar: [foo: [name: "stop"]]]] + + def query = """ { foo { bar { foo { name }}}} """ + + + when: "always materialised - no promises" + + cfPromisesOnFieldRegex = ~"neverMatchesAlwaysMaterialised" + ExecutionResult er = graphQL.execute(newExecutionInput(query).root(source)) + + + then: + er.errors.isEmpty() + er.data == expectedData + + when: "everything is promises" + + cfPromisesOnFieldRegex = ~".*" + er = graphQL.execute(newExecutionInput(query).root(source)) + + then: + er.errors.isEmpty() + er.data == expectedData + + + when: "only foo fields are CF promises so a mix of materialised and promised values" + + cfPromisesOnFieldRegex = ~"foo" + er = graphQL.execute(newExecutionInput(query).root(source)) + + then: + er.errors.isEmpty() + er.data == expectedData + } +} diff --git a/src/test/groovy/graphql/execution/MergedFieldTest.groovy b/src/test/groovy/graphql/execution/MergedFieldTest.groovy new file mode 100644 index 0000000000..f327339891 --- /dev/null +++ b/src/test/groovy/graphql/execution/MergedFieldTest.groovy @@ -0,0 +1,179 @@ +package graphql.execution + +import graphql.execution.incremental.DeferredExecution +import graphql.language.Field +import graphql.language.SelectionSet +import spock.lang.Specification + +class MergedFieldTest extends Specification { + + def fa_1 = Field.newField("fa").build() + def fa_2 = Field.newField("fa").build() + def fa_3 = Field.newField("fa").build() + def alias1 = Field.newField("a1").alias("alias1").build() + def ss = SelectionSet.newSelectionSet([fa_1, fa_2]).build() + def sub1 = Field.newField("s1").selectionSet(ss).build() + def deferred1 = new DeferredExecution("defer1") + def deferred2 = new DeferredExecution("defer2") + + def "can construct from a single field"() { + when: + def mergedField = MergedField.newSingletonMergedField(fa_1, null) + then: + mergedField.getName() == "fa" + mergedField.getResultKey() == "fa" + mergedField.getSingleField() == fa_1 + mergedField.isSingleField() + !mergedField.hasSubSelection() + // lazily make the list + mergedField.getFields() == [fa_1] + + // these should still work + mergedField.getName() == "fa" + mergedField.getResultKey() == "fa" + mergedField.getSingleField() == fa_1 + mergedField.isSingleField() + !mergedField.hasSubSelection() + } + + def "can construct from multiple fields"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1).addField(fa_2).build() + + then: + mergedField.getName() == "fa" + mergedField.getResultKey() == "fa" + mergedField.getSingleField() == fa_1 + !mergedField.isSingleField() + !mergedField.hasSubSelection() + mergedField.getFields() == [fa_1, fa_2] + } + + def "can have aliases"() { + when: + def mergedField = MergedField.newSingletonMergedField(alias1, null) + then: + mergedField.getName() == "a1" + mergedField.getResultKey() == "alias1" + mergedField.getSingleField() == alias1 + mergedField.isSingleField() + !mergedField.hasSubSelection() + } + + def "can have selection set on single field"() { + when: + def mergedField = MergedField.newSingletonMergedField(sub1, null) + then: + mergedField.getName() == "s1" + mergedField.getResultKey() == "s1" + mergedField.getSingleField() == sub1 + mergedField.isSingleField() + mergedField.hasSubSelection() + } + + def "builder can build a singleton via addField()"() { + when: + def mergedField = MergedField.newMergedField().addField(sub1).build() + then: + mergedField.getName() == "s1" + mergedField.getResultKey() == "s1" + mergedField.getSingleField() == sub1 + mergedField.isSingleField() + mergedField.hasSubSelection() + } + + def "builder can build a multi via addField() / addField() combo"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1).addField(fa_2).build() + then: + mergedField.getName() == "fa" + mergedField.getResultKey() == "fa" + mergedField.getSingleField() == fa_1 + !mergedField.isSingleField() + mergedField.getFields() == [fa_1, fa_2] + } + + def "builder can build a multi via addField() / fields() combo"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1).fields([fa_2, fa_3]).build() + then: + mergedField.getName() == "fa" + mergedField.getResultKey() == "fa" + mergedField.getSingleField() == fa_1 + !mergedField.isSingleField() + mergedField.getFields() == [fa_1, fa_2, fa_3] + } + + def "builder can build a multi via fields()"() { + when: + def mergedField = MergedField.newMergedField().fields([fa_1, fa_2, fa_3]).build() + then: + mergedField.getName() == "fa" + mergedField.getResultKey() == "fa" + mergedField.getSingleField() == fa_1 + !mergedField.isSingleField() + mergedField.getFields() == [fa_1, fa_2, fa_3] + } + + def "can add to an existing field"() { + when: + def mergedField = MergedField.newSingletonMergedField(fa_1, null) + then: + mergedField.getName() == "fa" + mergedField.getDeferredExecutions().isEmpty() + mergedField.getSingleField() == fa_1 + mergedField.getFields() == [fa_1] + + when: + def mergedField2 = mergedField.newMergedFieldWith(fa_2, null) + then: + mergedField2.getName() == "fa" + mergedField2.getDeferredExecutions().isEmpty() + mergedField2.getSingleField() == fa_1 + mergedField2.getFields() == [fa_1, fa_2] + + // its a new instance + !(mergedField2 === mergedField) + } + + def "builder can handle no deferred executions"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1) + .addDeferredExecutions([]).build() + then: + mergedField.getName() == "fa" + mergedField.getSingleField() == fa_1 + mergedField.getDeferredExecutions().isEmpty() + } + + def "builder can handle list of deferred executions"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1) + .addDeferredExecutions([deferred1, deferred2]).build() + then: + mergedField.getName() == "fa" + mergedField.getSingleField() == fa_1 + mergedField.getDeferredExecutions() == [deferred1, deferred2] + + } + + def "builder can handle a single deferred executions"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1) + .addDeferredExecution(deferred1).build() + then: + mergedField.getName() == "fa" + mergedField.getSingleField() == fa_1 + mergedField.getDeferredExecutions() == [deferred1] + } + + def "builder can handle a single deferred execution at a time"() { + when: + def mergedField = MergedField.newMergedField().addField(fa_1) + .addDeferredExecution(deferred1).addDeferredExecution(deferred2).build() + then: + mergedField.getName() == "fa" + mergedField.getSingleField() == fa_1 + mergedField.getDeferredExecutions() == [deferred1,deferred2] + } +} diff --git a/src/test/groovy/graphql/execution/NonNullableFieldValidatorTest.groovy b/src/test/groovy/graphql/execution/NonNullableFieldValidatorTest.groovy index a723aed799..33977d515c 100644 --- a/src/test/groovy/graphql/execution/NonNullableFieldValidatorTest.groovy +++ b/src/test/groovy/graphql/execution/NonNullableFieldValidatorTest.groovy @@ -7,15 +7,22 @@ import static graphql.schema.GraphQLNonNull.nonNull class NonNullableFieldValidatorTest extends Specification { - ExecutionContext context = Mock(ExecutionContext) - def "non nullable field throws exception"() { - ExecutionTypeInfo typeInfo = ExecutionTypeInfo.newTypeInfo().type(nonNull(GraphQLString)).build() + ExecutionContext context = Mock(ExecutionContext) { + propagateErrorsOnNonNullContractFailure() >> true + } + + ExecutionStepInfo typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(nonNull(GraphQLString)).build() - NonNullableFieldValidator validator = new NonNullableFieldValidator(context, typeInfo) + def parameters = Mock(ExecutionStrategyParameters) { + getPath() >> ResultPath.rootPath() + getExecutionStepInfo() >> typeInfo + } + + NonNullableFieldValidator validator = new NonNullableFieldValidator(context) when: - validator.validate(ExecutionPath.rootPath(), null) + validator.validate(parameters, null) then: thrown(NonNullableFieldWasNullException) @@ -23,12 +30,42 @@ class NonNullableFieldValidatorTest extends Specification { } def "nullable field does not throw exception"() { - ExecutionTypeInfo typeInfo = ExecutionTypeInfo.newTypeInfo().type(GraphQLString).build() + ExecutionContext context = Mock(ExecutionContext) { + propagateErrorsOnNonNullContractFailure() >> true + } + + ExecutionStepInfo typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(GraphQLString).build() + + def parameters = Mock(ExecutionStrategyParameters) { + getPath() >> ResultPath.rootPath() + getExecutionStepInfo() >> typeInfo + } + + NonNullableFieldValidator validator = new NonNullableFieldValidator(context) + + when: + def result = validator.validate(parameters, null) + + then: + result == null + } + + def "non nullable field returns null if errors are not propagated"() { + ExecutionContext context = Mock(ExecutionContext) { + propagateErrorsOnNonNullContractFailure() >> false + } + + ExecutionStepInfo typeInfo = ExecutionStepInfo.newExecutionStepInfo().type(nonNull(GraphQLString)).build() + + def parameters = Mock(ExecutionStrategyParameters) { + getPath() >> ResultPath.rootPath() + getExecutionStepInfo() >> typeInfo + } - NonNullableFieldValidator validator = new NonNullableFieldValidator(context, typeInfo) + NonNullableFieldValidator validator = new NonNullableFieldValidator(context) when: - def result = validator.validate(ExecutionPath.rootPath(), null) + def result = validator.validate(parameters, null) then: result == null diff --git a/src/test/groovy/graphql/execution/NonNullableFieldWasNullExceptionTest.groovy b/src/test/groovy/graphql/execution/NonNullableFieldWasNullExceptionTest.groovy new file mode 100644 index 0000000000..7db3872664 --- /dev/null +++ b/src/test/groovy/graphql/execution/NonNullableFieldWasNullExceptionTest.groovy @@ -0,0 +1,120 @@ +package graphql.execution + +import graphql.ExecutionInput +import graphql.TestUtil +import spock.lang.Specification + +class NonNullableFieldWasNullExceptionTest extends Specification { + + def "lower level sets a null when it should not and it bubbles all the way up"() { + + def sdl = ''' + type Query { + topLevelField : Type1! + } + + type Type1 { + middleLevelField : Type2! + } + + type Type2 { + bottomLevelField : String! + } + ''' + + def graphql = TestUtil.graphQL(sdl).build() + + def query = ''' + { topLevelField { middleLevelField { bottomLevelField } } } + ''' + when: + + ExecutionInput ei = ExecutionInput.newExecutionInput(query).root( + [topLevelField: [middleLevelField: [bottomLevelField: null]]] + ).build() + + def er = graphql.execute(ei) + + then: + er.data == null + er.errors[0].path.toList() == ["topLevelField", "middleLevelField", "bottomLevelField"] + } + + def "lower level sets a null when it should not and it bubbles up one"() { + def sdl = ''' + type Query { + topLevelField : Type1! + } + + type Type1 { + middleLevelField : Type2 + } + + type Type2 { + bottomLevelField : String! + } + ''' + + def graphql = TestUtil.graphQL(sdl).build() + + def query = ''' + { topLevelField { middleLevelField { bottomLevelField } } } + ''' + when: + + ExecutionInput ei = ExecutionInput.newExecutionInput(query).root( + [topLevelField: [middleLevelField: [bottomLevelField: null]]] + ).build() + + def er = graphql.execute(ei) + + then: + er.data == [topLevelField : [middleLevelField : null ]] + er.errors[0].path.toList() == ["topLevelField", "middleLevelField", "bottomLevelField"] + } + + def "a top level sets a null when it should not and it bubbles up one"() { + def sdl = ''' + type Query { + topLevelField : Type1! + } + + type Type1 { + middleLevelField : Type2 + } + + type Type2 { + bottomLevelField : String! + } + ''' + + def graphql = TestUtil.graphQL(sdl).build() + + def query = ''' + { topLevelField { middleLevelField { bottomLevelField } } } + ''' + when: + + ExecutionInput ei = ExecutionInput.newExecutionInput(query).root( + [topLevelField: null] + ).build() + + def er = graphql.execute(ei) + + then: + er.data == null + er.errors[0].path.toList() == ["topLevelField"] + + when: + + ei = ExecutionInput.newExecutionInput(query).root( + null + ).build() + + er = graphql.execute(ei) + + then: + er.data == null + er.errors[0].path.toList() == ["topLevelField"] + } +} diff --git a/src/test/groovy/graphql/execution/ExecutionPathTest.groovy b/src/test/groovy/graphql/execution/ResultPathTest.groovy similarity index 50% rename from src/test/groovy/graphql/execution/ExecutionPathTest.groovy rename to src/test/groovy/graphql/execution/ResultPathTest.groovy index 55cebb194a..146970cd6e 100644 --- a/src/test/groovy/graphql/execution/ExecutionPathTest.groovy +++ b/src/test/groovy/graphql/execution/ResultPathTest.groovy @@ -3,7 +3,6 @@ package graphql.execution import graphql.AssertException import graphql.ExceptionWhileDataFetching import graphql.ExecutionInput -import graphql.GraphQL import graphql.GraphQLError import graphql.SerializationError import graphql.TestUtil @@ -11,7 +10,7 @@ import graphql.schema.DataFetcher import spock.lang.Specification import spock.lang.Unroll -class ExecutionPathTest extends Specification { +class ResultPathTest extends Specification { @Unroll "unit test toList works as expected : #actual"() { @@ -20,11 +19,11 @@ class ExecutionPathTest extends Specification { actual.toList() == expected where: - actual || expected - ExecutionPath.rootPath() || [] - ExecutionPath.rootPath().segment("A") || ["A"] - ExecutionPath.rootPath().segment("A").segment(1).segment("B") || ["A", 1, "B"] - ExecutionPath.rootPath().segment("A").segment("B").segment(1) || ["A", "B", 1] + actual || expected + ResultPath.rootPath() || [] + ResultPath.rootPath().segment("A") || ["A"] + ResultPath.rootPath().segment("A").segment(1).segment("B") || ["A", 1, "B"] + ResultPath.rootPath().segment("A").segment("B").segment(1) || ["A", "B", 1] } @Unroll @@ -33,11 +32,39 @@ class ExecutionPathTest extends Specification { actual.toString() == expected where: - actual || expected - ExecutionPath.rootPath() || "" - ExecutionPath.rootPath().segment("A") || "/A" - ExecutionPath.rootPath().segment("A").segment(1).segment("B") || "/A[1]/B" - ExecutionPath.rootPath().segment("A").segment("B").segment(1) || "/A/B[1]" + actual || expected + ResultPath.rootPath() || "" + ResultPath.rootPath().segment("A") || "/A" + ResultPath.rootPath().segment("A").segment(1).segment("B") || "/A[1]/B" + ResultPath.rootPath().segment("A").segment("B").segment(1) || "/A/B[1]" + } + + @Unroll + "unit test sibling works as expected : #actual"() { + + expect: + actual.toList() == expected + + where: + actual || expected + ResultPath.rootPath() || [] + ResultPath.rootPath().segment("A").sibling("B") || ["B"] + ResultPath.rootPath().segment("A").segment(1).segment("B").sibling("C") || ["A", 1, "C"] + } + + @Unroll + "unit test getLevel works as expected : #actual"() { + + expect: + actual.getLevel() == expected + + where: + actual || expected + ResultPath.rootPath() || 0 + ResultPath.rootPath().segment("A") || 1 + ResultPath.rootPath().segment("A").segment("B") || 2 + ResultPath.rootPath().segment("A").segment(1).segment("B") || 2 + ResultPath.rootPath().segment("A").segment("B").segment(1) || 2 } @@ -79,7 +106,7 @@ class ExecutionPathTest extends Specification { def f4Fetcher = { env -> "Some Value" } as DataFetcher def nonNullFieldFetcher = { env -> null } as DataFetcher - def schema = TestUtil.schema(spec, + def graphQL = TestUtil.graphQL(spec, ["Query" : [ "f1": f1Fetcher, @@ -96,11 +123,9 @@ class ExecutionPathTest extends Specification { [ "nonNullField": nonNullFieldFetcher ] - ]) + ]).build() - GraphQL graphQL = GraphQL.newGraphQL(schema).build() - ExecutionInput executionInput = ExecutionInput.newExecutionInput() .query(""" { @@ -109,7 +134,7 @@ class ExecutionPathTest extends Specification { sub1 sub2 } - f3 + aliasedF3 : f3 f4 { nonNullField } @@ -130,7 +155,7 @@ class ExecutionPathTest extends Specification { ["f2", 1, "sub2"] == error2.getPath() def error3 = errors.get(2) as SerializationError - ["f3"] == error3.getPath() + ["aliasedF3"] == error3.getPath() def error4 = errors.get(3) as NonNullableFieldWasNullError ["f4", "nonNullField"] == error4.getPath() @@ -140,7 +165,7 @@ class ExecutionPathTest extends Specification { expect: - ExecutionPath.parse(pathString).toList() == expectedList + ResultPath.parse(pathString).toList() == expectedList where: @@ -156,7 +181,7 @@ class ExecutionPathTest extends Specification { def "test worst case parsing"() { when: - ExecutionPath.parse(badPathString) + ResultPath.parse(badPathString) then: thrown(AssertException) @@ -173,11 +198,12 @@ class ExecutionPathTest extends Specification { "/" | _ } - def "test from test fromList"() { + @Unroll + def "test from test fromList #inputList and #expectedString"() { expect: - ExecutionPath.fromList(inputList).toString() == expectedString + ResultPath.fromList(inputList).toString() == expectedString where: @@ -188,4 +214,92 @@ class ExecutionPathTest extends Specification { "/a/b[0]/c[1]" | ["a", "b", 0, "c", 1] } + def "get path without list end"() { + when: + def path = ResultPath.fromList(["a", "b", 9]) + path = path.getPathWithoutListEnd() + then: + path.toList() == ["a", "b"] + + when: + path = path.getPathWithoutListEnd() + then: + path.toList() == ["a", "b"] + } + + def "pass any other object than string or int"(){ + when: + ResultPath.fromList(["a", "b", true]) + + then: + notThrown(ClassCastException) + } + + def "can append paths"() { + when: + def path = ResultPath.fromList(["a", "b", 0]) + def path2 = ResultPath.fromList(["x", "y", 9]) + + def newPath = path.append(path2) + + then: + newPath.toList() == ["a", "b", 0, "x", "y", 9] + + + when: + newPath = ResultPath.rootPath().append(path2) + + then: + newPath.toList() == ["x", "y", 9] + + when: + newPath = path2.append(ResultPath.rootPath()) + + then: + newPath.toList() == ["x", "y", 9] + + when: + newPath = ResultPath.rootPath().append(ResultPath.rootPath()) + + then: + newPath.toList() == [] + } + + def "replace support"() { + when: + def path = ResultPath.fromList(["a", "b", 0]) + def newPath = path.replaceSegment(1) + + then: + newPath.toList() == ["a", "b", 1] + + when: + newPath = path.replaceSegment("x") + + then: + newPath.toList() == ["a", "b", "x"] + + when: + newPath = path.replaceSegment(99) + + then: + newPath.toList() == ["a", "b", 99] + + when: + ResultPath.rootPath().replaceSegment(1) + + then: + thrown(AssertException) + + when: + ResultPath.rootPath().replaceSegment("x") + + then: + thrown(AssertException) + + when: + newPath = ResultPath.parse("/a/b[1]").replaceSegment("x") + then: + newPath.toList() == ["a", "b", "x"] + } } diff --git a/src/test/groovy/graphql/execution/SimpleDataFetcherExceptionHandlerTest.groovy b/src/test/groovy/graphql/execution/SimpleDataFetcherExceptionHandlerTest.groovy new file mode 100644 index 0000000000..2ec5f380e0 --- /dev/null +++ b/src/test/groovy/graphql/execution/SimpleDataFetcherExceptionHandlerTest.groovy @@ -0,0 +1,58 @@ +package graphql.execution + + +import graphql.ExceptionWhileDataFetching +import graphql.schema.DataFetchingEnvironment +import spock.lang.Specification + +import java.util.concurrent.CompletionException + +import static graphql.Scalars.GraphQLString +import static graphql.execution.DataFetcherExceptionHandlerParameters.newExceptionParameters +import static graphql.execution.ExecutionStepInfo.newExecutionStepInfo +import static graphql.execution.MergedField.newMergedField +import static graphql.language.Field.newField +import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment + +class SimpleDataFetcherExceptionHandlerTest extends Specification { + def handler = new SimpleDataFetcherExceptionHandler() + + + def "will wrap general exceptions"() { + when: + def handlerParameters = mkParams(new RuntimeException("RTE")) + def result = handler.handleException(handlerParameters) + + then: + result.join().errors[0] instanceof ExceptionWhileDataFetching + result.join().errors[0].getMessage().contains("RTE") + } + + def "can unwrap certain exceptions"() { + when: + def result = handler.handleException(mkParams(new CompletionException(new RuntimeException("RTE")))) + + then: + result.join().errors[0] instanceof ExceptionWhileDataFetching + result.join().errors[0].getMessage().contains("RTE") + } + + def "wont unwrap other exceptions"() { + when: + def result = handler.handleException(mkParams(new RuntimeException("RTE",new RuntimeException("BANG")))) + + then: + result.join().errors[0] instanceof ExceptionWhileDataFetching + ! result.join().errors[0].getMessage().contains("BANG") + } + + private static DataFetcherExceptionHandlerParameters mkParams(Exception exception) { + def mergedField = newMergedField(newField("f").build()).build() + def esi = newExecutionStepInfo() + .field(mergedField) + .type(GraphQLString).path(ResultPath.fromList(["hi"])).build() + DataFetchingEnvironment env = newDataFetchingEnvironment(). + mergedField(mergedField).executionStepInfo(esi).build() + newExceptionParameters().exception(exception).dataFetchingEnvironment(env).build() + } +} diff --git a/src/test/groovy/graphql/execution/SubscriptionExecutionStrategyTest.groovy b/src/test/groovy/graphql/execution/SubscriptionExecutionStrategyTest.groovy index 534fa272f8..af3dcaf5ce 100644 --- a/src/test/groovy/graphql/execution/SubscriptionExecutionStrategyTest.groovy +++ b/src/test/groovy/graphql/execution/SubscriptionExecutionStrategyTest.groovy @@ -1,22 +1,42 @@ package graphql.execution +import graphql.AssertException import graphql.ErrorType import graphql.ExecutionInput import graphql.ExecutionResult import graphql.GraphQL +import graphql.GraphQLError +import graphql.GraphqlErrorBuilder import graphql.TestUtil +import graphql.TypeMismatchError +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.LegacyTestingInstrumentation +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys +import graphql.execution.instrumentation.ModernTestingInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters import graphql.execution.pubsub.CapturingSubscriber +import graphql.execution.pubsub.FlowMessagePublisher import graphql.execution.pubsub.Message import graphql.execution.pubsub.ReactiveStreamsMessagePublisher +import graphql.execution.pubsub.ReactiveStreamsObjectPublisher import graphql.execution.pubsub.RxJavaMessagePublisher +import graphql.execution.reactive.SubscriptionPublisher import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.PropertyDataFetcher import graphql.schema.idl.RuntimeWiring import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry import org.reactivestreams.Publisher import spock.lang.Specification import spock.lang.Unroll +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.atomic.AtomicInteger + import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring class SubscriptionExecutionStrategyTest extends Specification { @@ -34,26 +54,100 @@ class SubscriptionExecutionStrategyTest extends Specification { type Subscription { newMessage(roomId:Int) : Message + newListOfMessages(roomId:Int): [Message] } """ GraphQL buildSubscriptionQL(DataFetcher newMessageDF) { - RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + buildSubscriptionQL(newMessageDF, PropertyDataFetcher.fetching("sender"), PropertyDataFetcher.fetching("text")) + } + + RuntimeWiring.Builder buildBaseSubscriptionWiring(DataFetcher senderDF, DataFetcher textDF) { + return RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Message") + .dataFetcher("sender", senderDF) + .dataFetcher("text", textDF) + .build()) + } + + GraphQL buildSubscriptionListQL(DataFetcher newListOfMessagesDF) { + return buildSubscriptionListQL(newListOfMessagesDF, PropertyDataFetcher.fetching("sender"), PropertyDataFetcher.fetching("text")) + } + + GraphQL buildSubscriptionListQL(DataFetcher newListOfMessagesDF, DataFetcher senderDF, DataFetcher textDF) { + RuntimeWiring runtimeWiring = buildBaseSubscriptionWiring(senderDF, textDF) + .type(newTypeWiring("Subscription").dataFetcher("newListOfMessages", newListOfMessagesDF).build()) + .build() + + return TestUtil.graphQL(idl, runtimeWiring).subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()).build() + } + + GraphQL buildSubscriptionQL(DataFetcher newMessageDF, DataFetcher senderDF, DataFetcher textDF) { + RuntimeWiring runtimeWiring = buildBaseSubscriptionWiring(senderDF, textDF) .type(newTypeWiring("Subscription").dataFetcher("newMessage", newMessageDF).build()) .build() - def schema = TestUtil.schema(idl, runtimeWiring) + return TestUtil.graphQL(idl, runtimeWiring).subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()).build() + } - def graphQL = GraphQL.newGraphQL(schema).subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()).build() - graphQL + static GraphQLError mkError(String message) { + GraphqlErrorBuilder.newError().message(message).build() } + @Unroll + def "#2609 when a GraphQLList is expected and a non iterable or non array is passed then it should yield a TypeMismatch error (spec October2021/6.2.3.2.ExecuteSubscriptionEvent(...).5)"() { + given: + DataFetcher newListOfMessagesDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + return new ReactiveStreamsMessagePublisher(5) { + @Override + protected Message examineMessage(Message message, Integer at) { + // Should actually be list of messages ([Message]) + return new Message("aSender_" + at, "someText" + at) + } + } + } + } + + GraphQL graphQL = buildSubscriptionListQL(newListOfMessagesDF) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewListOfMessages { + newListOfMessages(roomId: 123) { + sender + text + } + } + """).build() + + when: + def executionResult = graphQL.execute(executionInput) + + Publisher msgStream = executionResult.getData() + + def capturingSubscriber = new CapturingSubscriber() + msgStream.subscribe(capturingSubscriber) + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + def messages = capturingSubscriber.events + messages.size() == 5 + for (int i = 0; i < messages.size(); i++) { + def message = messages[i] + assert message.errors.size() == 1 + assert message.errors[0] instanceof TypeMismatchError + assert message.errors[0].message.contains("/newListOfMessages") + assert message.errors[0].message.contains("LIST") + } + } @Unroll def "subscription query sends out a stream of events using the '#why' implementation"() { given: - Publisher publisher = eventStreamPublisher + Object publisher = eventStreamPublisher DataFetcher newMessageDF = new DataFetcher() { @Override @@ -82,6 +176,7 @@ class SubscriptionExecutionStrategyTest extends Specification { msgStream.subscribe(capturingSubscriber) then: + msgStream instanceof SubscriptionPublisher Awaitility.await().untilTrue(capturingSubscriber.isDone()) def messages = capturingSubscriber.events @@ -95,6 +190,7 @@ class SubscriptionExecutionStrategyTest extends Specification { why | eventStreamPublisher 'reactive streams stream' | new ReactiveStreamsMessagePublisher(10) 'rxjava stream' | new RxJavaMessagePublisher(10) + 'flow stream' | new FlowMessagePublisher(10) } @@ -102,7 +198,7 @@ class SubscriptionExecutionStrategyTest extends Specification { def "subscription alias is correctly used in response messages using '#why' implementation"() { given: - Publisher publisher = eventStreamPublisher + Object publisher = eventStreamPublisher DataFetcher newMessageDF = new DataFetcher() { @Override @@ -141,6 +237,7 @@ class SubscriptionExecutionStrategyTest extends Specification { why | eventStreamPublisher 'reactive streams stream' | new ReactiveStreamsMessagePublisher(1) 'rxjava stream' | new RxJavaMessagePublisher(1) + 'flow stream' | new FlowMessagePublisher(1) } @@ -152,7 +249,7 @@ class SubscriptionExecutionStrategyTest extends Specification { // capability and it costs us little to support it, lets have a test for it. // given: - Publisher publisher = eventStreamPublisher + Object publisher = eventStreamPublisher DataFetcher newMessageDF = new DataFetcher() { @Override @@ -193,7 +290,7 @@ class SubscriptionExecutionStrategyTest extends Specification { why | eventStreamPublisher 'reactive streams stream' | new ReactiveStreamsMessagePublisher(10) 'rxjava stream' | new RxJavaMessagePublisher(10) - + 'flow stream' | new FlowMessagePublisher(10) } @@ -226,6 +323,33 @@ class SubscriptionExecutionStrategyTest extends Specification { executionResult.errors.size() == 1 } + def "if you dont return a Publisher we will assert"() { + + DataFetcher newMessageDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + return "Not a Publisher" + } + } + + GraphQL graphQL = buildSubscriptionQL(newMessageDF) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).build() + + when: + graphQL.execute(executionInput) + + then: + thrown(AssertException) + } + def "subscription query will surface event stream exceptions"() { DataFetcher newMessageDF = new DataFetcher() { @@ -328,14 +452,503 @@ class SubscriptionExecutionStrategyTest extends Specification { if (i == 5) { message.data == null assert message.errors.size() == 2 - assert message.errors[0].errorType == ErrorType.DataFetchingException - assert message.errors[0].message == "Cannot return null for non-nullable type: 'String' within parent 'Message' (/newMessage/sender)" + assert message.errors[0].errorType == ErrorType.NullValueInNonNullableField + assert message.errors[0].message.contains("/newMessage/sender") - assert message.errors[1].errorType == ErrorType.DataFetchingException - assert message.errors[1].message == "Cannot return null for non-nullable type: 'String' within parent 'Message' (/newMessage/text)" + assert message.errors[1].errorType == ErrorType.NullValueInNonNullableField + assert message.errors[1].message.contains("/newMessage/text") } else { assert message.data == ["newMessage": [sender: "sender" + i, text: "text" + i]] } } } + + def "subscriptions can return DataFetcher results with errors"() { + + // + // this tests that we can wrap the Publisher in a DataFetcherResult AND that the return types of the Publisher + // can themselves be DataFetcherResult objects - hence DataFetcherResult>> + // in this case + DataFetcher newMessageDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + def objectMaker = { int index -> + def message = new Message("sender" + index, "text" + index) + GraphQLError error = null + if (index == 1) { + error = mkError("1 is the loneliest number that you'll ever know") + } + // wrap inner result in DataFetcherResult + def resultBuilder = DataFetcherResult.newResult().data(message).localContext(index) + if (error != null) { + resultBuilder.error(error) + } + return resultBuilder.build() + } + def publisher = new ReactiveStreamsObjectPublisher(10, objectMaker) + // we also use DFR here to wrap the publisher to show it can work + return DataFetcherResult.newResult().data(publisher).error(mkError("The top level field publisher can have errors")).build() + } + + } + + DataFetcher senderDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + Message msg = environment.getSource() + if (msg.sender == "sender1") { + return DataFetcherResult.newResult().data(msg.sender).error(mkError("Sub level fields can have errors")).build() + } + return msg.sender + } + } + + GraphQL graphQL = buildSubscriptionQL(newMessageDF, senderDF, PropertyDataFetcher.fetching("text")) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).build() + + when: + + def executionResult = graphQL.execute(executionInput) + + Publisher msgStream = executionResult.getData() + + def capturingSubscriber = new CapturingSubscriber() + msgStream.subscribe(capturingSubscriber) + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + executionResult.errors.size() == 1 + executionResult.errors[0].message == "The top level field publisher can have errors" + + def messages = capturingSubscriber.events + messages.size() == 10 + for (int i = 0; i < messages.size(); i++) { + def message = messages[i] + // error handling on publisher events + if (i == 1) { + assert message.errors[0].message == "1 is the loneliest number that you'll ever know" + assert message.errors[1].message == "Sub level fields can have errors" + } else { + assert message.errors.isEmpty(), "There should be no errors present" + } + assert message.data == ["newMessage": [sender: "sender" + i, text: "text" + i]] + } + } + + def "subscriptions local context works as expected"() { + + // + // make sure local context is preserved down the subscription + DataFetcher newMessageDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + def objectMaker = { int index -> + def message = new Message("sender" + index, "text" + index) + return DataFetcherResult.newResult().data(message).localContext(index).build() + } + def publisher = new ReactiveStreamsObjectPublisher(10, objectMaker) + // we also use DFR here to wrap the publisher to show it can work + return DataFetcherResult.newResult().data(publisher).build() + } + + } + + DataFetcher senderDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + Message msg = environment.getSource() + return msg.sender + "-lc:" + environment.getLocalContext() + } + } + + GraphQL graphQL = buildSubscriptionQL(newMessageDF, senderDF, PropertyDataFetcher.fetching("text")) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).build() + + when: + + def executionResult = graphQL.execute(executionInput) + + Publisher msgStream = executionResult.getData() + + def capturingSubscriber = new CapturingSubscriber() + msgStream.subscribe(capturingSubscriber) + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + def messages = capturingSubscriber.events + messages.size() == 10 + for (int i = 0; i < messages.size(); i++) { + def message = messages[i] + def senderVal = "sender" + i + "-lc:" + i + assert message.data == ["newMessage": [sender: senderVal, text: "text" + i]] + } + } + + def "instrumentation gets called on subscriptions"() { + + // + // make sure local context is preserved down the subscription + DataFetcher newMessageDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + new ReactiveStreamsObjectPublisher(10, { int index -> + new Message("sender" + index, "text" + index) + }) + } + } + + def instrumentResultCalls = [] + LegacyTestingInstrumentation instrumentation = new LegacyTestingInstrumentation() { + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + instrumentResultCalls.add("instrumentExecutionResult") + return CompletableFuture.completedFuture(executionResult) + } + } + GraphQL graphQL = buildSubscriptionQL(newMessageDF) + graphQL = graphQL.transform({ builder -> builder.instrumentation(instrumentation) }) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).build() + + when: + + def executionResult = graphQL.execute(executionInput) + + Publisher msgStream = executionResult.getData() + + def capturingSubscriber = new CapturingSubscriber() + msgStream.subscribe(capturingSubscriber) + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + def messages = capturingSubscriber.events + messages.size() == 10 + + def subscribedFieldCalls = instrumentation.executionList.findAll { s -> s.contains(":subscribed-field-event") } + subscribedFieldCalls.size() == 20 // start and end calls + subscribedFieldCalls.findAll { s -> s.contains("newMessage") }.size() == 20 // all for our subscribed field + + // this works because our calls are serial - if we truly had async values then the order would not work + subscribedFieldCalls.withIndex().collect({ s, index -> + if (index % 2 == 0) { + assert s.startsWith("start:"), "expected start: on even indexes" + } else { + assert s.startsWith("end:"), "expected end: on odd indexes" + } + }) + + instrumentResultCalls.size() == 11 // one for the initial execution and then one for each stream event + } + + def "emits results in the order they complete"() { + List promises = [] + Publisher publisher = new RxJavaMessagePublisher(10) + + DataFetcher newMessageDF = { env -> return publisher } + DataFetcher senderDF = dfThatDoesNotComplete("sender", promises) + DataFetcher textDF = PropertyDataFetcher.fetching("text") + + GraphQL graphQL = buildSubscriptionQL(newMessageDF, senderDF, textDF) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).build() + + def executionResult = graphQL.execute(executionInput) + + when: + Publisher msgStream = executionResult.getData() + def capturingSubscriber = new CapturingSubscriber(100) + msgStream.subscribe(capturingSubscriber) + + // make them all complete but in reverse order + promises.reverse().forEach { it.run() } + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + // in order they completed - which was reversed + def messages = capturingSubscriber.events + messages.size() == 10 + for (int i = 0, j = messages.size() - 1; i < messages.size(); i++, j--) { + def message = messages[i].data + assert message == ["newMessage": [sender: "sender" + j, text: "text" + j]] + } + } + + def "emits results in the order they where emitted by source"() { + List promises = [] + Publisher publisher = new RxJavaMessagePublisher(10) + + DataFetcher newMessageDF = { env -> return publisher } + DataFetcher senderDF = dfThatDoesNotComplete("sender", promises) + DataFetcher textDF = PropertyDataFetcher.fetching("text") + + GraphQL graphQL = buildSubscriptionQL(newMessageDF, senderDF, textDF) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).graphQLContext([(SubscriptionExecutionStrategy.KEEP_SUBSCRIPTION_EVENTS_ORDERED): true]).build() + + def executionResult = graphQL.execute(executionInput) + + when: + Publisher msgStream = executionResult.getData() + def capturingSubscriber = new CapturingSubscriber(100) + msgStream.subscribe(capturingSubscriber) + + // make them all complete but in reverse order + promises.reverse().forEach { it.run() } + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + // in order they were emitted originally - they have been buffered + def messages = capturingSubscriber.events + messages.size() == 10 + for (int i = 0; i < messages.size(); i++) { + def message = messages[i].data + assert message == ["newMessage": [sender: "sender" + i, text: "text" + i]] + } + } + + def "we can cancel the operation and the upstream publisher is told"() { + List promises = new CopyOnWriteArrayList<>() + RxJavaMessagePublisher publisher = new RxJavaMessagePublisher(10) + + DataFetcher newMessageDF = { env -> return publisher } + DataFetcher senderDF = dfThatDoesNotComplete("sender", promises) + DataFetcher textDF = PropertyDataFetcher.fetching("text") + + GraphQL graphQL = buildSubscriptionQL(newMessageDF, senderDF, textDF) + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).graphQLContext([(SubscriptionExecutionStrategy.KEEP_SUBSCRIPTION_EVENTS_ORDERED): true]).build() + + def executionResult = graphQL.execute(executionInput) + + when: + Publisher msgStream = executionResult.getData() + def capturingSubscriber = new CapturingSubscriber(1) + msgStream.subscribe(capturingSubscriber) + + // now cancel the operation + executionInput.cancel() + + // make things over the subscription + promises.forEach { it.run() } + + + then: + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + def messages = capturingSubscriber.events + messages.size() == 1 + def error = messages[0].errors[0] + assert error.message.contains("Execution has been asked to be cancelled") + publisher.counter == 2 + } + + private static DataFetcher dfThatDoesNotComplete(String propertyName, List promises) { + { env -> + def df = PropertyDataFetcher.fetching(propertyName) + def value = df.get(env) + + def cf = new CompletableFuture() + promises.add({ cf.complete(value) }) + return cf + } + } + + + @Unroll + def "DataLoader works on each subscription event"() { + given: + def sdl = """ + type Query { + hello: String + } + + type Subscription { + newDogs: [Dog] + } + + type Dog { + name: String + } + """ + + AtomicInteger batchLoaderCalled = new AtomicInteger(0) + BatchLoader batchLoader = { keys -> + println "batchLoader called with keys: $keys" + batchLoaderCalled.incrementAndGet() + assert keys.size() == 2 + CompletableFuture.completedFuture(["Luna", "Skipper"]) + } + def dataLoader = DataLoaderFactory.newDataLoader("dogsNameLoader", batchLoader) + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("dogsNameLoader", dataLoader) + + DataFetcher dogsNameDF = { env -> + println "dogsNameDF called" + env.getDataLoader("dogsNameLoader").load(env.getSource()) + } + DataFetcher newDogsDF = { env -> + println "newDogsDF called" + def dogNames = ["Luna", "Skipper"] + return new ReactiveStreamsObjectPublisher(3, { int index -> + return dogNames.collect { it -> it + "$index" } + }) + } + + def query = '''subscription { + newDogs { + name + } + }''' + def schema = TestUtil.schema(sdl, [ + Subscription: [newDogs: newDogsDF], + Dog : [name: dogsNameDF] + ]) + ExecutionInput ei = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .build() + def graphQL = GraphQL.newGraphQL(schema) + .build() + + if (exhaustedStrategy) { + ei.getGraphQLContext().put(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, true) + } + + when: + def executionResult = graphQL.execute(ei) + Publisher msgStream = executionResult.getData() + def capturingSubscriber = new CapturingSubscriber(3) + msgStream.subscribe(capturingSubscriber) + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + then: + def events = capturingSubscriber.events + events.size() == 3 + batchLoaderCalled.get() == 3 // batchLoader should be called once for each event + + events[0].data == ["newDogs": [[name: "Luna"], [name: "Skipper"]]] + events[1].data == ["newDogs": [[name: "Luna"], [name: "Skipper"]]] + events[2].data == ["newDogs": [[name: "Luna"], [name: "Skipper"]]] + + where: + exhaustedStrategy << [false, true] + } + + + def "can instrument subscription reactive ending"() { + + given: + Object publisher = new ReactiveStreamsMessagePublisher(2) + + DataFetcher newMessageDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + return publisher + } + } + + def wiringBuilder = buildBaseSubscriptionWiring( + PropertyDataFetcher.fetching("sender"), PropertyDataFetcher.fetching("text") + ) + RuntimeWiring runtimeWiring = wiringBuilder + .type(newTypeWiring("Subscription").dataFetcher("newMessage", newMessageDF).build()) + .build() + + def instrumentation = new ModernTestingInstrumentation() + + def graphQL = TestUtil.graphQL(idl, runtimeWiring) + .instrumentation(instrumentation) + .subscriptionExecutionStrategy(new SubscriptionExecutionStrategy()).build() + + def executionInput = ExecutionInput.newExecutionInput().query(""" + subscription NewMessages { + newMessage(roomId: 123) { + sender + text + } + } + """).build() + + def executionResult = graphQL.execute(executionInput) + + when: + Publisher msgStream = executionResult.getData() + def capturingSubscriber = new CapturingSubscriber() + msgStream.subscribe(capturingSubscriber) + + then: + msgStream instanceof SubscriptionPublisher + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + TestUtil.listContainsInOrder(instrumentation.executionList, [ + "start:execution", + "start:parse", + "end:parse", + "start:validation", + "end:validation", + "start:execute-operation", + "start:execution-strategy", + "start:fetch-newMessage", + "end:fetch-newMessage", + "start:reactive-results-subscription", + "end:execution-strategy", + "end:execute-operation", + "end:execution", + ], [ + // followed by + "end:reactive-results-subscription" + ]) + + // last of all it finishes + TestUtil.last(instrumentation.executionList) == "end:reactive-results-subscription" + } } diff --git a/src/test/groovy/graphql/execution/ValuesResolverE2ETest.groovy b/src/test/groovy/graphql/execution/ValuesResolverE2ETest.groovy new file mode 100644 index 0000000000..590d84e277 --- /dev/null +++ b/src/test/groovy/graphql/execution/ValuesResolverE2ETest.groovy @@ -0,0 +1,136 @@ +package graphql.execution + +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.GraphQL +import graphql.Scalars +import graphql.TestUtil +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry +import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphQLList +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLSchema +import spock.lang.Specification + +class ValuesResolverE2ETest extends Specification { + + def "issue 3276 - reported bug on validation problems as SDL"() { + def sdl = ''' + type Query { + items(pagination: Pagination = {limit: 10, offset: 0}): [String] + } + + input Pagination { + limit: Int + offset: Int + } + ''' + DataFetcher df = { DataFetchingEnvironment env -> + def pagination = env.getArgument("pagination") as Map + def strings = pagination.entrySet().collect { entry -> entry.key + "=" + entry.value } + return strings + } + def schema = TestUtil.schema(sdl, [Query: [items: df]]) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def ei = ExecutionInput.newExecutionInput(''' + query Items($limit: Int, $offset: Int) { + items(pagination: {limit: $limit, offset: $offset}) + } + ''').variables([limit: 5, offset: 0]).build() + def er = graphQL.execute(ei) + then: + er.errors.isEmpty() + er.data == [items : ["limit=5", "offset=0"]] + } + + def "issue 3276 - reported bug on validation problems as reported code"() { + DataFetcher dataFetcher = { env -> + def pagination = env.getArgument("pagination") as Map + def strings = pagination.entrySet().collect { entry -> entry.key + "=" + entry.value } + return strings + } + GraphQLSchema schema = GraphQLSchema.newSchema() + .query(GraphQLObjectType.newObject() + .name("Query") + .field(items -> items + .name("items") + .type(GraphQLList.list(Scalars.GraphQLString)) + .argument(pagination -> pagination + .name("pagination") + //skipped adding the default limit/offset values as it doesn't change anything + .defaultValueProgrammatic(new HashMap<>()) + .type(GraphQLInputObjectType.newInputObject() + .name("Pagination") + .field(limit -> limit + .name("limit") + .type(Scalars.GraphQLInt)) + .field(offset -> offset + .name("offset") + .type(Scalars.GraphQLInt)) + .build()))) + .build()) + .codeRegistry(GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(FieldCoordinates.coordinates("Query", "items"), dataFetcher) + .build()) + .build() + + GraphQL gql = GraphQL.newGraphQL(schema).build() + + Map vars = new HashMap<>() + vars.put("limit", 5) + vars.put("offset", 0) + + ExecutionInput ei = ExecutionInput.newExecutionInput() + .query("query Items( \$limit: Int, \$offset: Int) {\n" + + " items(\n" + + " pagination: {limit: \$limit, offset: \$offset} \n" + + " )\n" + + "}") + .variables(vars) + .build() + + when: + ExecutionResult result = gql.execute( ei) + then: + result.errors.isEmpty() + result.data == [items : ["limit=5", "offset=0"]] + } + + def "issue 3276 - should end up in validation errors because location defaults are not present"() { + def sdl = ''' + type Query { + items(pagination: Pagination = {limit: 1, offset: 1}): [String] + } + input Pagination { + limit: Int! #non-null this time, no default value + offset: Int! #non-null this time, no default value + } + ''' + DataFetcher df = { DataFetchingEnvironment env -> + def pagination = env.getArgument("pagination") as Map + def strings = pagination.entrySet().collect { entry -> entry.key + "=" + entry.value } + return strings + } + def schema = TestUtil.schema(sdl, [Query: [items: df]]) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def ei = ExecutionInput.newExecutionInput(''' + query Items( $limit: Int, $offset: Int) { + items( + pagination: {limit: $limit, offset: $offset} + ) + } + ''').variables([limit: 5, offset: null]).build() + def er = graphQL.execute(ei) + then: + er.errors.size() == 2 + er.errors[0].message == "Validation error (VariableTypeMismatch@[items]) : Variable 'limit' of type 'Int' used in position expecting type 'Int!'" + er.errors[1].message == "Validation error (VariableTypeMismatch@[items]) : Variable 'offset' of type 'Int' used in position expecting type 'Int!'" + } +} diff --git a/src/test/groovy/graphql/execution/ValuesResolverTest.groovy b/src/test/groovy/graphql/execution/ValuesResolverTest.groovy index 74f6b086dd..b9256f1304 100644 --- a/src/test/groovy/graphql/execution/ValuesResolverTest.groovy +++ b/src/test/groovy/graphql/execution/ValuesResolverTest.groovy @@ -1,5 +1,8 @@ package graphql.execution +import graphql.Directives +import graphql.ErrorType +import graphql.GraphQLContext import graphql.GraphQLException import graphql.TestUtil import graphql.language.Argument @@ -9,22 +12,26 @@ import graphql.language.EnumValue import graphql.language.IntValue import graphql.language.ListType import graphql.language.NonNullType +import graphql.language.NullValue import graphql.language.ObjectField import graphql.language.ObjectValue +import graphql.language.SourceLocation import graphql.language.StringValue import graphql.language.TypeName import graphql.language.Value import graphql.language.VariableDefinition import graphql.language.VariableReference import graphql.schema.CoercingParseValueException -import graphql.schema.GraphQLArgument +import graphql.schema.DataFetcher import spock.lang.Specification import spock.lang.Unroll +import static graphql.ExecutionInput.newExecutionInput import static graphql.Scalars.GraphQLBoolean import static graphql.Scalars.GraphQLFloat import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString +import static graphql.schema.GraphQLArgument.newArgument import static graphql.schema.GraphQLEnumType.newEnum import static graphql.schema.GraphQLInputObjectField.newInputObjectField import static graphql.schema.GraphQLInputObjectType.newInputObject @@ -33,26 +40,26 @@ import static graphql.schema.GraphQLNonNull.nonNull class ValuesResolverTest extends Specification { - ValuesResolver resolver = new ValuesResolver() + def graphQLContext = GraphQLContext.getDefault() + def locale = Locale.getDefault() @Unroll def "getVariableValues: simple variable input #inputValue"() { given: def schema = TestUtil.schemaWithInputType(inputType) - VariableDefinition variableDefinition = new VariableDefinition("variable", variableType) + VariableDefinition variableDefinition = new VariableDefinition("variable", variableType, null) when: - def resolvedValues = resolver.coerceArgumentValues(schema, [variableDefinition], [variable: inputValue]) + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: inputValue]), graphQLContext, locale) then: - resolvedValues['variable'] == outputValue + resolvedValues.get('variable') == outputValue where: inputType | variableType | inputValue || outputValue GraphQLInt | new TypeName("Int") | 100 || 100 GraphQLString | new TypeName("String") | 'someString' || 'someString' - GraphQLBoolean | new TypeName("Boolean") | 'true' || true - GraphQLFloat | new TypeName("Float") | '42.43' || 42.43d - + GraphQLBoolean | new TypeName("Boolean") | true || true + GraphQLFloat | new TypeName("Float") | 42.43d || 42.43d } def "getVariableValues: map object as variable input"() { @@ -72,9 +79,9 @@ class ValuesResolverTest extends Specification { VariableDefinition variableDefinition = new VariableDefinition("variable", new TypeName("Person")) when: - def resolvedValues = resolver.coerceArgumentValues(schema, [variableDefinition], [variable: inputValue]) + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: inputValue]), graphQLContext, locale) then: - resolvedValues['variable'] == outputValue + resolvedValues.get('variable') == outputValue where: inputValue || outputValue [name: 'a', id: 123] || [name: 'a', id: 123] @@ -82,6 +89,72 @@ class ValuesResolverTest extends Specification { [name: 'x'] || [name: 'x'] } + def "getVariableValues: @oneOf map object as variable input"() { + given: + def aField = newInputObjectField() + .name("a") + .type(GraphQLString) + def bField = newInputObjectField() + .name("b") + .type(GraphQLString) + def inputType = newInputObject() + .name("Person") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(aField) + .field(bField) + .build() + def schema = TestUtil.schemaWithInputType(inputType) + VariableDefinition variableDefinition = new VariableDefinition("variable", new TypeName("Person")) + + when: + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: [a: 'x']]), graphQLContext, locale) + then: + resolvedValues.get('variable') == [a: 'x'] + + when: + resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: [b: 'y']]), graphQLContext, locale) + then: + resolvedValues.get('variable') == [b: 'y'] + + when: + ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: [a: 'x', b: 'y']]), graphQLContext, locale) + then: + thrown(OneOfTooManyKeysException.class) + } + + def "can validate inner input oneOf fields"() { + // + // a test from https://github.com/graphql-java/graphql-java/issues/3572 + // + def sdl = ''' + input OneOf @oneOf { a: Int, b: Int } + type Outer { inner(oneof: OneOf!): Boolean } + type Query { outer: Outer } + ''' + + DataFetcher outer = { env -> return null } + def graphQL = TestUtil.graphQL(sdl, [Query: [outer: outer]]).build() + + def query = ''' + query ($oneof: OneOf!) { + outer { + # these variables are never accessed by a data fetcher because + # Query.outer always returns null + inner(oneof: $oneof) + } + } + ''' + + when: + def er = graphQL.execute( + newExecutionInput(query).variables([oneof: [a: 2, b: 1]]) + ) + + then: + er.errors.size() == 1 + er.errors[0].message == "Exactly one key must be specified for OneOf type 'OneOf'." + } + class Person { def name = "" @@ -112,7 +185,7 @@ class ValuesResolverTest extends Specification { when: def obj = new Person('a', 123) - resolver.coerceArgumentValues(schema, [variableDefinition], [variable: obj]) + ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: obj]), graphQLContext, locale) then: thrown(CoercingParseValueException) } @@ -123,51 +196,91 @@ class ValuesResolverTest extends Specification { VariableDefinition variableDefinition = new VariableDefinition("variable", new ListType(new TypeName("String"))) String value = "world" when: - def resolvedValues = resolver.coerceArgumentValues(schema, [variableDefinition], [variable: value]) + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: value]), graphQLContext, locale) then: - resolvedValues['variable'] == ['world'] + resolvedValues.get('variable') == ['world'] + } + def "getVariableValues: list value gets resolved to a list when the type is a List"() { + given: + def schema = TestUtil.schemaWithInputType(list(GraphQLString)) + VariableDefinition variableDefinition = new VariableDefinition("variable", new ListType(new TypeName("String"))) + List value = ["hello", "world"] + when: + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: value]), graphQLContext, locale) + then: + resolvedValues.get('variable') == ['hello', 'world'] } + def "getVariableValues: array value gets resolved to a list when the type is a List"() { + given: + def schema = TestUtil.schemaWithInputType(list(GraphQLString)) + VariableDefinition variableDefinition = new VariableDefinition("variable", new ListType(new TypeName("String"))) + String[] value = ["hello", "world"] as String[] + when: + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: value]), graphQLContext, locale) + then: + resolvedValues.get('variable') == ['hello', 'world'] + } def "getArgumentValues: resolves argument with variable reference"() { given: - def variables = [var: 'hello'] - def fieldArgument = new GraphQLArgument("arg", GraphQLString) + def variables = CoercedVariables.of([var: 'hello']) + def fieldArgument = newArgument().name("arg").type(GraphQLString).build() def argument = new Argument("arg", new VariableReference("var")) when: - def values = resolver.getArgumentValues([fieldArgument], [argument], variables) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) then: values['arg'] == 'hello' } + def "getArgumentValues: uses default value with null variable reference value"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("inputObject") + .field(newInputObjectField() + .name("inputField") + .type(GraphQLString)) + .build() + + def fieldArgument = newArgument().name("arg").type(inputObjectType).defaultValueProgrammatic([inputField: "hello"]).build() + def argument = new Argument("arg", new VariableReference("var")) + + when: + def variables = CoercedVariables.emptyVariables() + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + values['arg'] == [inputField: 'hello'] + } + def "getArgumentValues: resolves object literal"() { given: "schema defining input object" def subObjectType = newInputObject() .name("SubType") .field(newInputObjectField() - .name("subKey") - .type(GraphQLBoolean)) + .name("subKey") + .type(GraphQLBoolean)) .build() def inputObjectType = newInputObject() .name("inputObject") .field(newInputObjectField() - .name("intKey") - .type(GraphQLInt)) + .name("intKey") + .type(GraphQLInt)) .field(newInputObjectField() - .name("stringKey") - .type(GraphQLString)) + .name("stringKey") + .type(GraphQLString)) .field(newInputObjectField() - .name("subObject") - .type(subObjectType)) + .name("subObject") + .type(subObjectType)) .build() - def fieldArgument = new GraphQLArgument("arg", inputObjectType) + def fieldArgument = newArgument().name("arg").type(inputObjectType).build() when: def argument = new Argument("arg", inputValue) - def values = resolver.getArgumentValues([fieldArgument], [argument], [:]) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], CoercedVariables.emptyVariables(), graphQLContext, locale) then: values['arg'] == outputValue @@ -201,21 +314,21 @@ class ValuesResolverTest extends Specification { def inputObjectType = newInputObject() .name("inputObject") .field(newInputObjectField() - .name("intKey") - .type(nonNull(GraphQLInt)) - .defaultValue(3) - .build()) + .name("intKey") + .type(nonNull(GraphQLInt)) + .defaultValueProgrammatic(3) + .build()) .field(newInputObjectField() - .name("stringKey") - .type(GraphQLString) - .defaultValue("defaultString") - .build()) + .name("stringKey") + .type(GraphQLString) + .defaultValueProgrammatic("defaultString") + .build()) .build() - def fieldArgument = new GraphQLArgument("arg", inputObjectType) + def fieldArgument = newArgument().name("arg").type(inputObjectType).build() when: def argument = new Argument("arg", inputValue) - def values = resolver.getArgumentValues([fieldArgument], [argument], [:]) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], CoercedVariables.emptyVariables(), graphQLContext, locale) then: values['arg'] == outputValue @@ -238,25 +351,6 @@ class ValuesResolverTest extends Specification { ] } - def "getArgumentValues: missing InputObject fields which are non-null cause error"() { - given: "schema defining input object" - def inputObjectType = newInputObject() - .name("inputObject") - .field(newInputObjectField() - .name("intKey") - .type(nonNull(GraphQLInt)) - .build()) - .build() - def fieldArgument = new GraphQLArgument("arg", inputObjectType) - - when: - def argument = new Argument("arg", ObjectValue.newObjectValue().build()) - resolver.getArgumentValues([fieldArgument], [argument], [:]) - - then: - thrown(GraphQLException) - } - ObjectValue buildObjectLiteral(Map contents) { def object = ObjectValue.newObjectValue() contents.each { key, value -> @@ -279,10 +373,10 @@ class ValuesResolverTest extends Specification { .value("PLUTO") .value("MARS", "mars") .build() - def fieldArgument1 = new GraphQLArgument("arg1", enumType) - def fieldArgument2 = new GraphQLArgument("arg2", enumType) + def fieldArgument1 = newArgument().name("arg1").type(enumType).build() + def fieldArgument2 = newArgument().name("arg2").type(enumType).build() when: - def values = resolver.getArgumentValues([fieldArgument1, fieldArgument2], [argument1, argument2], [:]) + def values = ValuesResolver.getArgumentValues([fieldArgument1, fieldArgument2], [argument1, argument2], CoercedVariables.emptyVariables(), graphQLContext, locale) then: values['arg1'] == 'PLUTO' @@ -296,14 +390,13 @@ class ValuesResolverTest extends Specification { arrayValue.value(new BooleanValue(false)) def argument = new Argument("arg", arrayValue.build()) - def fieldArgument = new GraphQLArgument("arg", list(GraphQLBoolean)) + def fieldArgument = newArgument().name("arg").type(list(GraphQLBoolean)).build() when: - def values = resolver.getArgumentValues([fieldArgument], [argument], [:]) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], CoercedVariables.emptyVariables(), graphQLContext, locale) then: values['arg'] == [true, false] - } def "getArgumentValues: resolves single value literal to a list when type is a list "() { @@ -311,13 +404,642 @@ class ValuesResolverTest extends Specification { StringValue stringValue = new StringValue("world") def argument = new Argument("arg", stringValue) - def fieldArgument = new GraphQLArgument("arg", list(GraphQLString)) + def fieldArgument = newArgument().name("arg").type(list(GraphQLString)).build() when: - def values = resolver.getArgumentValues([fieldArgument], [argument], [:]) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], CoercedVariables.emptyVariables(), graphQLContext, locale) then: values['arg'] == ['world'] + } + + def "getArgumentValues: invalid oneOf input because of duplicate keys - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + def argument = new Argument("arg", inputValue) + + when: + def fieldArgument = newArgument().name("arg").type(inputObjectType).build() + ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfTooManyKeysException) + e.message == "Exactly one key must be specified for OneOf type 'oneOfInputObject'." + + when: "input type is wrapped in non-null" + def nonNullInputObjectType = nonNull(inputObjectType) + def fieldArgumentNonNull = newArgument().name("arg").type(nonNullInputObjectType).build() + ValuesResolver.getArgumentValues([fieldArgumentNonNull], [argument], variables, graphQLContext, locale) + + then: + def eNonNull = thrown(OneOfTooManyKeysException) + eNonNull.message == "Exactly one key must be specified for OneOf type 'oneOfInputObject'." + + where: + // from https://github.com/graphql/graphql-spec/pull/825/files#diff-30a69c5a5eded8e1aea52e53dad1181e6ec8f549ca2c50570b035153e2de1c43R1692 + testCase | inputValue | variables + + '{ a: "abc", b: 123 } {}' | buildObjectLiteral([ + a: StringValue.of("abc"), + b: IntValue.of(123) + ]) | CoercedVariables.emptyVariables() + + '{ a: null, b: 123 } {}' | buildObjectLiteral([ + a: NullValue.of(), + b: IntValue.of(123) + ]) | CoercedVariables.emptyVariables() + + '{ a: $var, b: 123 } { var: null }' | buildObjectLiteral([ + a: VariableReference.of("var"), + b: IntValue.of(123) + ]) | CoercedVariables.of(["var": null]) + + '{ a: $var, b: 123 } {}' | buildObjectLiteral([ + a: VariableReference.of("var"), + b: IntValue.of(123) + ]) | CoercedVariables.emptyVariables() + + '{ a : "abc", b : null} {}' | buildObjectLiteral([ + a: StringValue.of("abc"), + b: NullValue.of() + ]) | CoercedVariables.emptyVariables() + + '{ a : null, b : null} {}' | buildObjectLiteral([ + a: NullValue.of(), + b: NullValue.of() + ]) | CoercedVariables.emptyVariables() + + '{ a : $a, b : $b} {a : "abc"}' | buildObjectLiteral([ + a: VariableReference.of("a"), + b: VariableReference.of("v") + ]) | CoercedVariables.of(["a": "abc"]) + + '$var {var : { a : "abc", b : 123}}' | VariableReference.of("var") + | CoercedVariables.of(["var": ["a": "abc", "b": 123]]) + + '$var {var : {}}' | VariableReference.of("var") + | CoercedVariables.of(["var": [:]]) + } + + def "getArgumentValues: invalid oneOf nested input because of duplicate keys - #testCase"() { + given: "schema defining input object" + def oneOfObjectType = newInputObject() + .name("OneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + def parentObjectType = newInputObject() + .name("ParentInputObject") + .field(newInputObjectField() + .name("oneOfField") + .type(oneOfObjectType) + .build()) + .build() + + def argument = new Argument("arg", inputValue) + + when: + def fieldArgument = newArgument().name("arg").type(parentObjectType).build() + ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfTooManyKeysException) + e.message == "Exactly one key must be specified for OneOf type 'OneOfInputObject'." + + where: + testCase | inputValue | variables + '{oneOfField: {a: "abc", b: 123} } {}' | buildObjectLiteral([ + oneOfField: [ + a: StringValue.of("abc"), + b: IntValue.of(123) + ] + ]) | CoercedVariables.emptyVariables() + '{oneOfField: {a: null, b: 123 }} {}' | buildObjectLiteral([ + oneOfField: [ + a: NullValue.of(), + b: IntValue.of(123) + ] + ]) | CoercedVariables.emptyVariables() + + '{oneOfField: {a: $var, b: 123 }} { var: null }' | buildObjectLiteral([ + oneOfField: [ + a: VariableReference.of("var"), + b: IntValue.of(123) + ] + ]) | CoercedVariables.of(["var": null]) + + '{oneOfField: {a: $var, b: 123 }} {}' | buildObjectLiteral([ + oneOfField: [ + a: VariableReference.of("var"), + b: IntValue.of(123) + ] + ]) | CoercedVariables.emptyVariables() + + '{oneOfField: {a : "abc", b : null}} {}' | buildObjectLiteral([ + oneOfField: [ + a: StringValue.of("abc"), + b: NullValue.of() + ] + ]) | CoercedVariables.emptyVariables() + + '{oneOfField: {a : null, b : null}} {}' | buildObjectLiteral([ + oneOfField: [ + a: NullValue.of(), + b: NullValue.of() + ] + ]) | CoercedVariables.emptyVariables() + + '{oneOfField: {a : $a, b : $b}} {a : "abc"}' | buildObjectLiteral([ + oneOfField: [ + a: VariableReference.of("a"), + b: VariableReference.of("v") + ] + ]) | CoercedVariables.of(["a": "abc"]) + '$var {var : {oneOfField: { a : "abc", b : 123}}}' | VariableReference.of("var") + | CoercedVariables.of(["var": ["oneOfField": ["a": "abc", "b": 123]]]) + + '$var {var : {oneOfField: {} }}' | VariableReference.of("var") + | CoercedVariables.of(["var": ["oneOfField": [:]]]) + + } + + def "getArgumentValues: invalid oneOf nested input because of null value - #testCase"() { + given: "schema defining input object" + def oneOfObjectType = newInputObject() + .name("OneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + def parentObjectType = newInputObject() + .name("ParentInputObject") + .field(newInputObjectField() + .name("oneOfField") + .type(oneOfObjectType) + .build()) + .build() + + + def fieldArgument = newArgument().name("arg").type(parentObjectType).build() + + when: + def argument = new Argument("arg", inputValue) + ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfNullValueException) + e.message == "OneOf type field 'OneOfInputObject.a' must be non-null." + + where: + // from https://github.com/graphql/graphql-spec/pull/825/files#diff-30a69c5a5eded8e1aea52e53dad1181e6ec8f549ca2c50570b035153e2de1c43R1692 + testCase | inputValue | variables + + '`{ oneOfField: { a: null }}` {}' | buildObjectLiteral([ + oneOfField: [a: NullValue.of()] + ]) | CoercedVariables.emptyVariables() + + '`{ oneOfField: { a: $var }}` { var : null}' | buildObjectLiteral([ + oneOfField: [a: VariableReference.of("var")] + ]) | CoercedVariables.of(["var": null]) + + } + + def "getArgumentValues: invalid oneOf input because of null value - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + def fieldArgument = newArgument().name("arg").type(inputObjectType).build() + + when: + def argument = new Argument("arg", inputValue) + ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfNullValueException) + e.message == "OneOf type field 'oneOfInputObject.a' must be non-null." + + where: + // from https://github.com/graphql/graphql-spec/pull/825/files#diff-30a69c5a5eded8e1aea52e53dad1181e6ec8f549ca2c50570b035153e2de1c43R1692 + testCase | inputValue | variables + + '`{ a: null }` {}' | buildObjectLiteral([ + a: NullValue.of() + ]) | CoercedVariables.emptyVariables() + + '`{ a: $var }` { var : null}' | buildObjectLiteral([ + a: VariableReference.of("var") + ]) | CoercedVariables.of(["var": null]) + + '`{ a: $var }` { }' | buildObjectLiteral([ + a: VariableReference.of("var") + ]) | CoercedVariables.emptyVariables() + } + + def "getArgumentValues: invalid oneOf list input because element contains duplicate key - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + when: + def argument = new Argument("arg", inputArray) + def fieldArgumentList = newArgument().name("arg").type(list(inputObjectType)).build() + ValuesResolver.getArgumentValues([fieldArgumentList], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfTooManyKeysException) + e.message == "Exactly one key must be specified for OneOf type 'oneOfInputObject'." + + where: + + testCase | inputArray | variables + + '[{ a: "abc", b: 123 }]' + | ArrayValue.newArrayValue() + .value(buildObjectLiteral([ + a: StringValue.of("abc"), + b: IntValue.of(123) + ])).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, { a: "xyz", b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + buildObjectLiteral([ + a: StringValue.of("xyz"), + b: IntValue.of(789) + ]), + ]).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, $var ] [{ a: "abc" }, { a: "xyz", b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + VariableReference.of("var") + ]).build() + | CoercedVariables.of("var": [a: "xyz", b: 789]) + + } + + def "getArgumentValues: invalid oneOf list input because element contains null value - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + when: + def argument = new Argument("arg", inputArray) + def fieldArgumentList = newArgument().name("arg").type(list(inputObjectType)).build() + ValuesResolver.getArgumentValues([fieldArgumentList], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfNullValueException) + e.message == "OneOf type field 'oneOfInputObject.a' must be non-null." + + where: + + testCase | inputArray | variables + + '[{ a: "abc" }, { a: null }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + buildObjectLiteral([ + a: NullValue.of() + ]), + ]).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, { a: $var }] [{ a: "abc" }, { a: null }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + buildObjectLiteral([ + a: VariableReference.of("var") + ]), + ]).build() + | CoercedVariables.of("var": null) + + } + + def "getArgumentValues: invalid oneOf non-null list input because element contains duplicate key - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + when: + def argument = new Argument("arg", inputArray) + def fieldArgumentList = newArgument().name("arg").type(nonNull(list(inputObjectType))).build() + ValuesResolver.getArgumentValues([fieldArgumentList], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfTooManyKeysException) + e.message == "Exactly one key must be specified for OneOf type 'oneOfInputObject'." + + where: + + testCase | inputArray | variables + + '[{ a: "abc", b: 123 }]' + | ArrayValue.newArrayValue() + .value(buildObjectLiteral([ + a: StringValue.of("abc"), + b: IntValue.of(123) + ])).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, { a: "xyz", b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + buildObjectLiteral([ + a: StringValue.of("xyz"), + b: IntValue.of(789) + ]), + ]).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, $var ] [{ a: "abc" }, { a: "xyz", b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + VariableReference.of("var") + ]).build() + | CoercedVariables.of("var": [a: "xyz", b: 789]) + + } + + def "getArgumentValues: invalid oneOf list input with non-nullable elements, because element contains duplicate key - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + when: + def argument = new Argument("arg", inputArray) + def fieldArgumentList = newArgument().name("arg").type(list(nonNull(inputObjectType))).build() + ValuesResolver.getArgumentValues([fieldArgumentList], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfTooManyKeysException) + e.message == "Exactly one key must be specified for OneOf type 'oneOfInputObject'." + + where: + + testCase | inputArray | variables + + '[{ a: "abc", b: 123 }]' + | ArrayValue.newArrayValue() + .value(buildObjectLiteral([ + a: StringValue.of("abc"), + b: IntValue.of(123) + ])).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, { a: "xyz", b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + buildObjectLiteral([ + a: StringValue.of("xyz"), + b: IntValue.of(789) + ]), + ]).build() + | CoercedVariables.emptyVariables() + + '[{ a: "abc" }, $var ] [{ a: "abc" }, { a: "xyz", b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + VariableReference.of("var") + ]).build() + | CoercedVariables.of("var": [a: "xyz", b: 789]) + + } + + def "getArgumentValues: valid oneOf input - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + def fieldArgument = newArgument().name("arg").type(inputObjectType).build() + + when: + def argument = new Argument("arg", inputValue) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + values == expectedValues + + where: + // from https://github.com/graphql/graphql-spec/pull/825/files#diff-30a69c5a5eded8e1aea52e53dad1181e6ec8f549ca2c50570b035153e2de1c43R1692 + testCase | inputValue | variables | expectedValues + + '{ b: 123 }` {}' | buildObjectLiteral([ + b: IntValue.of(123) + ]) | CoercedVariables.emptyVariables() | [arg: [b: 123]] + + '`$var` { var: { b: 123 } }' | VariableReference.of("var") + | CoercedVariables.of([var: [b: 123]]) | [arg: [b: 123]] + + '{ a: "abc" }` {}' | buildObjectLiteral([ + a: StringValue.of("abc") + ]) | CoercedVariables.emptyVariables() | [arg: [a: "abc"]] + + + '`$var` { var: { a: "abc" } }' | VariableReference.of("var") + | CoercedVariables.of([var: [a: "abc"]]) | [arg: [a: "abc"]] + + '{ a: $var }` { var : "abc"}' | buildObjectLiteral([ + a: VariableReference.of("var") + ]) | CoercedVariables.of([var: "abc"]) | [arg: [a: "abc"]] + + } + + def "getArgumentValues: valid oneOf list input - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + + when: + def argument = new Argument("arg", inputArray) + def fieldArgumentList = newArgument().name("arg").type(list(inputObjectType)).build() + def values = ValuesResolver.getArgumentValues([fieldArgumentList], [argument], variables, graphQLContext, locale) + + then: + values == expectedValues + + where: + + testCase | inputArray | variables | expectedValues + + '[{ a: "abc"}]' + | ArrayValue.newArrayValue() + .value(buildObjectLiteral([ + a: StringValue.of("abc"), + ])).build() + | CoercedVariables.emptyVariables() + | [arg: [[a: "abc"]]] + + '[{ a: "abc" }, $var ] [{ a: "abc" }, { b: 789 }]' + | ArrayValue.newArrayValue() + .values([ + buildObjectLiteral([ + a: StringValue.of("abc") + ]), + VariableReference.of("var") + ]).build() + | CoercedVariables.of("var": [b: 789]) + | [arg: [[a: "abc"], [b: 789]]] + + } + + def "getArgumentValues: invalid oneOf input no values where passed - #testCase"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("oneOfInputObject") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(newInputObjectField() + .name("a") + .type(GraphQLString) + .build()) + .field(newInputObjectField() + .name("b") + .type(GraphQLInt) + .build()) + .build() + def fieldArgument = newArgument().name("arg").type(inputObjectType).build() + + when: + def argument = new Argument("arg", inputValue) + ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + def e = thrown(OneOfNullValueException) + e.message == "OneOf type field 'oneOfInputObject.a' must be non-null." + + where: + // from https://github.com/graphql/graphql-spec/pull/825/files#diff-30a69c5a5eded8e1aea52e53dad1181e6ec8f549ca2c50570b035153e2de1c43R1692 + testCase | inputValue | variables + + '`{ a: null }` {}' | buildObjectLiteral([ + a: NullValue.of() + ]) | CoercedVariables.emptyVariables() + + '`{ a: $var }` { var : null}' | buildObjectLiteral([ + a: VariableReference.of("var") + ]) | CoercedVariables.of(["var": null]) } @@ -333,64 +1055,62 @@ class ValuesResolverTest extends Specification { VariableDefinition variableDefinition = new VariableDefinition("variable", new TypeName("Test")) when: - def resolvedValues = resolver.coerceArgumentValues(schema, [variableDefinition], [variable: inputValue]) + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: inputValue]), graphQLContext, locale) then: - resolvedValues['variable'] == outputValue + resolvedValues.get('variable') == outputValue where: inputValue || outputValue "A_TEST" || "A_TEST" "VALUE_TEST" || 1 - } - def "getVariableValues: input object with non-required fields and default values"() { + @Unroll + def "getVariableValues: input object with non-required fields and default values. #inputValue -> #outputValue"() { given: def inputObjectType = newInputObject() .name("InputObject") .field(newInputObjectField() - .name("intKey") - .type(GraphQLInt)) + .name("intKey") + .type(GraphQLInt)) .field(newInputObjectField() - .name("stringKey") - .type(GraphQLString) - .defaultValue("defaultString")) + .name("stringKey") + .type(GraphQLString) + .defaultValueProgrammatic("defaultString")) .build() def schema = TestUtil.schemaWithInputType(inputObjectType) VariableDefinition variableDefinition = new VariableDefinition("variable", new TypeName("InputObject")) when: - def resolvedValues = resolver.coerceArgumentValues(schema, [variableDefinition], [variable: inputValue]) + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: inputValue]), graphQLContext, locale) then: - resolvedValues['variable'] == outputValue + resolvedValues.get('variable') == outputValue where: inputValue || outputValue [intKey: 10] || [intKey: 10, stringKey: 'defaultString'] - [intKey: 10, stringKey: null] || [intKey: 10, stringKey: 'defaultString'] - + [intKey: 10, stringKey: null] || [intKey: 10, stringKey: null] } def "getVariableInput: Missing InputObject fields which are non-null cause error"() { - given: def inputObjectType = newInputObject() .name("InputObject") .field(newInputObjectField() - .name("intKey") - .type(GraphQLInt)) + .name("intKey") + .type(GraphQLInt)) .field(newInputObjectField() - .name("requiredField") - .type(nonNull(GraphQLString))) + .name("requiredField") + .type(nonNull(GraphQLString))) .build() def schema = TestUtil.schemaWithInputType(inputObjectType) VariableDefinition variableDefinition = new VariableDefinition("variable", new TypeName("InputObject")) when: - resolver.coerceArgumentValues(schema, [variableDefinition], [variable: inputValue]) + ValuesResolver.coerceVariableValues(schema, [variableDefinition], RawVariables.of([variable: inputValue]), graphQLContext, locale) then: thrown(GraphQLException) @@ -409,10 +1129,10 @@ class ValuesResolverTest extends Specification { VariableDefinition barVarDef = new VariableDefinition("bar", new TypeName("String")) when: - def resolvedValues = resolver.coerceArgumentValues(schema, [fooVarDef, barVarDef], InputValue) + def resolvedValues = ValuesResolver.coerceVariableValues(schema, [fooVarDef, barVarDef], RawVariables.of(InputValue), graphQLContext, locale) then: - resolvedValues == outputValue + resolvedValues.toMap() == outputValue where: InputValue || outputValue @@ -427,9 +1147,237 @@ class ValuesResolverTest extends Specification { VariableDefinition fooVarDef = new VariableDefinition("foo", new NonNullType(new TypeName("String"))) when: - resolver.coerceArgumentValues(schema, [fooVarDef], [:]) + ValuesResolver.coerceVariableValues(schema, [fooVarDef], RawVariables.emptyVariables(), graphQLContext, locale) then: thrown(GraphQLException) } + + def "coerceVariableValues: use null when variable defined in variableValuesMap is null"() { + given: + def schema = TestUtil.schemaWithInputType(nonNull(GraphQLString)) + + def defaultValueForFoo = new StringValue("defaultValueForFoo") + VariableDefinition fooVarDef = new VariableDefinition("foo", new TypeName("String"), defaultValueForFoo) + + def defaultValueForBar = new StringValue("defaultValueForBar") + VariableDefinition barVarDef = new VariableDefinition("bar", new TypeName("String"), defaultValueForBar) + + def variableValuesMap = RawVariables.of(["foo": null, "bar": "barValue"]) + + when: + def resolvedVars = ValuesResolver.coerceVariableValues(schema, [fooVarDef, barVarDef], variableValuesMap, graphQLContext, locale) + + then: + resolvedVars.get('foo') == null + resolvedVars.get('bar') == "barValue" + } + + def "coerceVariableValues: if variableType is a Non-Nullable type and value is null, throw a query error"() { + given: + def schema = TestUtil.schemaWithInputType(nonNull(GraphQLString)) + + def defaultValueForFoo = new StringValue("defaultValueForFoo") + VariableDefinition fooVarDef = new VariableDefinition("foo", new NonNullType(new TypeName("String")), defaultValueForFoo) + + def variableValuesMap = RawVariables.of(["foo": null]) + + when: + ValuesResolver.coerceVariableValues(schema, [fooVarDef], variableValuesMap, graphQLContext, locale) + + then: + def error = thrown(NonNullableValueCoercedAsNullException) + error.message == "Variable 'foo' has an invalid value: Variable 'foo' has coerced Null value for NonNull type 'String!'" + } + + def "coerceVariableValues: if variableType is a list of Non-Nullable type, and element value is null, throw a query error"() { + given: + def schema = TestUtil.schemaWithInputType(list(nonNull(GraphQLString))) + + def defaultValueForFoo = new ArrayValue([new StringValue("defaultValueForFoo")]) + def type = new ListType(new NonNullType(new TypeName("String"))) + VariableDefinition fooVarDef = new VariableDefinition("foo", type, defaultValueForFoo) + + def variableValuesMap = RawVariables.of(["foo": [null]]) + + when: + ValuesResolver.coerceVariableValues(schema, [fooVarDef], variableValuesMap, graphQLContext, locale) + + then: + def error = thrown(NonNullableValueCoercedAsNullException) + error.message == "Variable 'foo' has an invalid value: Coerced Null value for NonNull type 'String!'" + } + + // Note: use NullValue defined in Field when it exists, + // and ignore defaultValue defined in type system + def "getArgumentValues: use null value when argumentValue defined in Field is null"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("inputObject") + .build() + + def fieldArgument = newArgument().name("arg").type(inputObjectType).defaultValueProgrammatic("hello").build() + def argument = new Argument("arg", NullValue.newNullValue().build()) + + when: + def variables = CoercedVariables.emptyVariables() + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + values['arg'] == null + } + + def "getArgumentValues: use null when reference value in variables is null"() { + given: "schema defining input object" + def inputObjectType = newInputObject() + .name("inputObject") + .build() + + def fieldArgument = newArgument().name("arg").type(inputObjectType).defaultValueProgrammatic("hello").build() + def argument = new Argument("arg", new VariableReference("var")) + + when: + def variables = CoercedVariables.of(["var": null]) + def values = ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + values['arg'] == null + } + + def "argument of Non-Nullable type and with null coerced value throws error"() { + given: + def inputObjectType = newInputObject() + .name("inputObject") + .build() + + def fieldArgument = newArgument().name("arg").type(nonNull(inputObjectType)).build() + def argument = new Argument("arg", new VariableReference("var")) + + when: + def variables = CoercedVariables.of(["var": null]) + ValuesResolver.getArgumentValues([fieldArgument], [argument], variables, graphQLContext, locale) + + then: + def error = thrown(NonNullableValueCoercedAsNullException) + error.message == "Argument 'arg' has coerced Null value for NonNull type 'inputObject!'" + } + + def "invalid enum error message is not nested and contains source location - issue 2560"() { + when: + def graphQL = TestUtil.graphQL(''' + enum PositionType { + MANAGER + DEVELOPER + } + + input PersonInput { + name: String + position: PositionType + } + + type Query { + name: String + } + + type Mutation { + updatePerson(input: PersonInput!): Boolean + } + ''').build() + + def mutation = ''' + mutation UpdatePerson($input: PersonInput!) { + updatePerson(input: $input) + } + ''' + + def executionInput = newExecutionInput() + .query(mutation) + .variables([input: [name: 'Name', position: 'UNKNOWN_POSITION']]) + .build() + + def executionResult = graphQL.execute(executionInput) + + then: + executionResult.data == null + executionResult.errors.size() == 1 + executionResult.errors[0].errorType == ErrorType.ValidationError + executionResult.errors[0].message == "Variable 'input' has an invalid value: Invalid input for enum 'PositionType'. No value found for name 'UNKNOWN_POSITION'" + executionResult.errors[0].locations == [new SourceLocation(2, 35)] + } + + def "invalid boolean coercing parse value error message is not nested and contains source location - issue 2560"() { + when: + def graphQL = TestUtil.graphQL(''' + input PersonInput { + name: String + hilarious: Boolean + } + + type Query { + name: String + } + + type Mutation { + updatePerson(input: PersonInput!): Boolean + } + ''').build() + + def mutation = ''' + mutation UpdatePerson($input: PersonInput!) { + updatePerson(input: $input) + } + ''' + + def executionInput = newExecutionInput() + .query(mutation) + .variables([input: [name: 'Name', hilarious: 'sometimes']]) + .build() + + def executionResult = graphQL.execute(executionInput) + + then: + executionResult.data == null + executionResult.errors.size() == 1 + executionResult.errors[0].errorType == ErrorType.ValidationError + executionResult.errors[0].message == "Variable 'input' has an invalid value: Expected a Boolean input, but it was a 'String'" + executionResult.errors[0].locations == [new SourceLocation(2, 35)] + } + + def "invalid float coercing parse value error message is not nested and contains source location - issue 2560"() { + when: + def graphQL = TestUtil.graphQL(''' + input PersonInput { + name: String + laughsPerMinute: Float + } + + type Query { + name: String + } + + type Mutation { + updatePerson(input: PersonInput!): Boolean + } + ''').build() + + def mutation = ''' + mutation UpdatePerson($input: PersonInput!) { + updatePerson(input: $input) + } + ''' + + def executionInput = newExecutionInput() + .query(mutation) + .variables([input: [name: 'Name', laughsPerMinute: 'none']]) + .build() + + def executionResult = graphQL.execute(executionInput) + + then: + executionResult.data == null + executionResult.errors.size() == 1 + executionResult.errors[0].errorType == ErrorType.ValidationError + executionResult.errors[0].message == "Variable 'input' has an invalid value: Expected a Number input, but it was a 'String'" + executionResult.errors[0].locations == [new SourceLocation(2, 35)] + } } diff --git a/src/test/groovy/graphql/execution/ValuesResolverTestLegacy.groovy b/src/test/groovy/graphql/execution/ValuesResolverTestLegacy.groovy new file mode 100644 index 0000000000..0c944b7bb1 --- /dev/null +++ b/src/test/groovy/graphql/execution/ValuesResolverTestLegacy.groovy @@ -0,0 +1,214 @@ +package graphql.execution + +import graphql.GraphQLContext +import graphql.language.ArrayValue +import graphql.language.EnumValue +import graphql.language.FloatValue +import graphql.language.IntValue +import graphql.language.ObjectField +import graphql.language.ObjectValue +import graphql.language.StringValue +import graphql.schema.GraphQLEnumType +import graphql.schema.GraphQLInputObjectType +import spock.lang.Ignore +import spock.lang.Specification + +import static graphql.Scalars.GraphQLBoolean +import static graphql.Scalars.GraphQLFloat +import static graphql.Scalars.GraphQLID +import static graphql.Scalars.GraphQLInt +import static graphql.Scalars.GraphQLString +import static graphql.execution.ValuesResolverLegacy.valueToLiteralLegacy +import static graphql.language.BooleanValue.newBooleanValue +import static graphql.schema.GraphQLList.list +import static graphql.schema.GraphQLNonNull.nonNull + +class ValuesResolverTestLegacy extends Specification { + + def graphQLContext = GraphQLContext.getDefault() + def locale = Locale.getDefault() + + def 'converts boolean values to ASTs'() { + expect: + valueToLiteralLegacy(true, GraphQLBoolean, graphQLContext, locale).isEqualTo(newBooleanValue(true).build()) + + valueToLiteralLegacy(false, GraphQLBoolean, graphQLContext, locale).isEqualTo(newBooleanValue(false).build()) + + valueToLiteralLegacy(null, GraphQLBoolean, graphQLContext, locale) == null + + valueToLiteralLegacy(0, GraphQLBoolean, graphQLContext, locale).isEqualTo(newBooleanValue(false).build()) + + valueToLiteralLegacy(1, GraphQLBoolean, graphQLContext, locale).isEqualTo(newBooleanValue(true).build()) + + def NonNullBoolean = nonNull(GraphQLBoolean) + valueToLiteralLegacy(0, NonNullBoolean, graphQLContext, locale).isEqualTo(newBooleanValue(false).build()) + } + + BigInteger bigInt(int i) { + return new BigInteger(String.valueOf(i)) + } + + def 'converts Int values to Int ASTs'() { + expect: + valueToLiteralLegacy(123.0, GraphQLInt, graphQLContext, locale).isEqualTo(IntValue.newIntValue(bigInt(123)).build()) + + valueToLiteralLegacy(1e4, GraphQLInt, graphQLContext, locale).isEqualTo(IntValue.newIntValue(bigInt(10000)).build()) + } + + def 'converts Float values to Int/Float ASTs'() { + expect: + valueToLiteralLegacy(123.0, GraphQLFloat, graphQLContext, locale).isEqualTo(FloatValue.newFloatValue(123.0).build()) + + valueToLiteralLegacy(123.5, GraphQLFloat, graphQLContext, locale).isEqualTo(FloatValue.newFloatValue(123.5).build()) + + valueToLiteralLegacy(1e4, GraphQLFloat, graphQLContext, locale).isEqualTo(FloatValue.newFloatValue(10000.0).build()) + + valueToLiteralLegacy(1e40, GraphQLFloat, graphQLContext, locale).isEqualTo(FloatValue.newFloatValue(1.0e40).build()) + } + + + def 'converts String values to String ASTs'() { + expect: + valueToLiteralLegacy('hello', GraphQLString, graphQLContext, locale).isEqualTo(new StringValue('hello')) + + valueToLiteralLegacy('VALUE', GraphQLString, graphQLContext, locale).isEqualTo(new StringValue('VALUE')) + + valueToLiteralLegacy('VA\n\t\f\r\b\\LUE', GraphQLString, graphQLContext, locale).isEqualTo(new StringValue('VA\n\t\f\r\b\\LUE')) + + valueToLiteralLegacy('VA\\L\"UE', GraphQLString, graphQLContext, locale).isEqualTo(new StringValue('VA\\L\"UE')) + + valueToLiteralLegacy(123, GraphQLString, graphQLContext, locale).isEqualTo(new StringValue('123')) + + valueToLiteralLegacy(false, GraphQLString, graphQLContext, locale).isEqualTo(new StringValue('false')) + + valueToLiteralLegacy(null, GraphQLString, graphQLContext, locale) == null + } + + def 'converts ID values to Int/String ASTs'() { + expect: + valueToLiteralLegacy('hello', GraphQLID, graphQLContext, locale).isEqualTo(new StringValue('hello')) + + valueToLiteralLegacy('VALUE', GraphQLID, graphQLContext, locale).isEqualTo(new StringValue('VALUE')) + + // Note: EnumValues cannot contain non-identifier characters + valueToLiteralLegacy('VA\nLUE', GraphQLID, graphQLContext, locale).isEqualTo(new StringValue('VA\nLUE')) + + // Note: IntValues are used when possible. + valueToLiteralLegacy(123, GraphQLID, graphQLContext, locale).isEqualTo(new IntValue(bigInt(123))) + + valueToLiteralLegacy(null, GraphQLID, graphQLContext, locale) == null + } + + + def 'does not converts NonNull values to NullValue'() { + expect: + def NonNullBoolean = nonNull(GraphQLBoolean) + valueToLiteralLegacy(null, NonNullBoolean, graphQLContext, locale) == null + } + + def complexValue = { someArbitrary: 'complexValue' } + + + def myEnum = GraphQLEnumType.newEnum().name('MyEnum') + .value('HELLO') + .value('GOODBYE') + .value('COMPLEX', complexValue) + .build() + + def 'converts string values to Enum ASTs if possible'() { + expect: + valueToLiteralLegacy('HELLO', myEnum, graphQLContext, locale).isEqualTo(new EnumValue('HELLO')) + + valueToLiteralLegacy(complexValue, myEnum, graphQLContext, locale).isEqualTo(new EnumValue('COMPLEX')) + } + + def 'converts array values to List ASTs'() { + expect: + valueToLiteralLegacy(['FOO', 'BAR'], list(GraphQLString), graphQLContext, locale).isEqualTo( + new ArrayValue([new StringValue('FOO'), new StringValue('BAR')]) + ) + + + valueToLiteralLegacy(['HELLO', 'GOODBYE'], list(myEnum), graphQLContext, locale).isEqualTo( + new ArrayValue([new EnumValue('HELLO'), new EnumValue('GOODBYE')]) + ) + } + + def 'converts list singletons'() { + expect: + valueToLiteralLegacy('FOO', list(GraphQLString), graphQLContext, locale).isEqualTo( + new StringValue('FOO') + ) + } + + def 'converts list to lists'() { + expect: + valueToLiteralLegacy(['hello', 'world'], list(GraphQLString), graphQLContext, locale).isEqualTo( + new ArrayValue([new StringValue('hello'), new StringValue('world')]) + ) + } + + def 'converts arrays to lists'() { + String[] sArr = ['hello', 'world'] as String[] + expect: + valueToLiteralLegacy(sArr, list(GraphQLString), graphQLContext, locale).isEqualTo( + new ArrayValue([new StringValue('hello'), new StringValue('world')]) + ) + } + + class SomePojo { + def foo = 3 + def bar = "HELLO" + } + + class SomePojoWithFields { + public float foo = 3 + public String bar = "HELLO" + } + + def 'converts input objects'() { + given: + def inputObj = GraphQLInputObjectType.newInputObject() + .name('MyInputObj') + .field({ f -> f.name("foo").type(GraphQLFloat) }) + .field({ f -> f.name("bar").type(myEnum) }) + .build() + expect: + + valueToLiteralLegacy([foo: 3, bar: 'HELLO'], inputObj, graphQLContext, locale).isEqualTo( + new ObjectValue([new ObjectField("foo", new IntValue(bigInt(3))), + new ObjectField("bar", new EnumValue('HELLO')), + ]) + ) + + valueToLiteralLegacy(new SomePojo(), inputObj, graphQLContext, locale).isEqualTo( + new ObjectValue([new ObjectField("foo", new IntValue(bigInt(3))), + new ObjectField("bar", new EnumValue('HELLO')), + ]) + ) + + valueToLiteralLegacy(new SomePojoWithFields(), inputObj, graphQLContext, locale).isEqualTo( + new ObjectValue([new ObjectField("foo", new IntValue(bigInt(3))), + new ObjectField("bar", new EnumValue('HELLO')), + ]) + ) + + + } + + @Ignore("ObjectValue.isEqualTo is broken - this test currently makes no sense") + def 'converts input objects with explicit nulls'() { + expect: + def inputObj = GraphQLInputObjectType.newInputObject() + .name('MyInputObj') + .field({ f -> f.name("foo").type(GraphQLFloat) }) + .field({ f -> f.name("bar").type(myEnum) }) + .build() + + valueToLiteralLegacy([foo: null], inputObj, graphQLContext, locale).isEqualTo( + new ObjectValue([new ObjectField("foo", null)]) + ) + } + + +} diff --git a/src/test/groovy/graphql/execution/batched/BatchedExecutionStrategyTest.groovy b/src/test/groovy/graphql/execution/batched/BatchedExecutionStrategyTest.groovy deleted file mode 100644 index 55f82f2c04..0000000000 --- a/src/test/groovy/graphql/execution/batched/BatchedExecutionStrategyTest.groovy +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright 2016 Palantir Technologies, Inc. All rights reserved. - */ - -package graphql.execution.batched - -import graphql.ExceptionWhileDataFetching -import graphql.ExecutionResult -import graphql.GraphQL -import graphql.Scalars -import graphql.execution.AsyncExecutionStrategy -import graphql.execution.NonNullableFieldWasNullError -import graphql.execution.instrumentation.TestingInstrumentation -import graphql.schema.DataFetcher -import graphql.schema.GraphQLObjectType -import graphql.schema.GraphQLSchema -import spock.lang.Specification - -import java.util.concurrent.atomic.AtomicInteger - -import static graphql.schema.GraphQLArgument.newArgument -import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition -import static graphql.schema.GraphQLNonNull.nonNull -import static graphql.schema.GraphQLObjectType.newObject - -class BatchedExecutionStrategyTest extends Specification { - - private GraphQLSchema schema = new FunWithStringsSchemaFactory().createSchema() - - private GraphQL graphQLAsync = GraphQL.newGraphQL(schema) - .queryExecutionStrategy(new AsyncExecutionStrategy()) - .build() - - private GraphQL graphQLBatchedButUnbatched = GraphQL.newGraphQL(this.schema) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .build() - - private Map countMap = new HashMap<>() - private TestingInstrumentation testingInstrumentation = new TestingInstrumentation() - - private GraphQL graphQLBatchedValue = GraphQL.newGraphQL(FunWithStringsSchemaFactory.createBatched(countMap).createSchema()) - .instrumentation(testingInstrumentation) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .build() - - private void runTestExpectErrors(String query, Exception exception) { - runTestAsyncExpectErrors(query, exception) - runTestBatchingUnbatchedExpectErrors(query, exception) - runTestBatchingExpectErrors(query, exception) - } - - private void runTestBatchingUnbatchedExpectErrors(String query, Exception exception) { - def errors = this.graphQLBatchedButUnbatched.execute(query).getErrors() - assert errors.size() == 1 - assert exception.class == ((ExceptionWhileDataFetching) errors.get(0)).getException().class - assert exception.getMessage() == ((ExceptionWhileDataFetching) errors.get(0)).getException().getMessage() - } - - private void runTestBatchingExpectErrors(String query, Exception exception, boolean checkString = true) { - def errors = this.graphQLBatchedValue.execute(query).getErrors() - assert errors.size() == 1 - assert exception.class == ((ExceptionWhileDataFetching) errors.get(0)).getException().class - if (checkString) - assert exception.getMessage() == ((ExceptionWhileDataFetching) errors.get(0)).getException().getMessage() - } - - private void runTestAsyncExpectErrors(String query, Exception exception) { - def errors = this.graphQLAsync.execute(query).getErrors() - assert errors.size() == 1 - assert exception.class == ((ExceptionWhileDataFetching) errors.get(0)).getException().class - assert exception.getMessage() == ((ExceptionWhileDataFetching) errors.get(0)).getException().getMessage() - } - - // Split into sub-methods so the stack trace is more useful - private void runTest(String query, Map expected) { - runTestAsync(query, expected) - runTestBatchingUnbatched(query, expected) - runTestBatching(query, expected) - // check instrumentation recorded invocations - assert !testingInstrumentation.dfInvocations.isEmpty() - } - - private void runTestBatchingUnbatched(String query, Map expected) { - assert this.graphQLBatchedButUnbatched.execute(query).getData() == expected - } - - private void runTestBatching(String query, Map expected) { - assert this.graphQLBatchedValue.execute(query).getData() == expected - } - - private void runTestAsync(String query, Map expected) { - assert this.graphQLAsync.execute(query).getData() == expected - } - - // This method is agnostic to whether errors are returned or thrown, provided they contain the desired text - private void runTestExpectError(String query, String errorSubstring) { - - try { - ExecutionResult result = this.graphQLAsync.execute(query) - assert !result.getErrors().isEmpty(), "Simple should have errored but was: " + result.getData() - } catch (Exception e) { - assert e.getMessage().contains(errorSubstring), "Simple error must contain '" + errorSubstring + "'" - } - - try { - ExecutionResult result = this.graphQLBatchedButUnbatched.execute(query) - assert !result.getErrors().isEmpty(), "Batched should have errored, but was " + result.getData() - } catch (Exception e) { - assert e.getMessage().contains(errorSubstring), "Batched but unbatched error must contain '" + errorSubstring + "'" - } - } - - static Map mapOf(String firstKey, Object firstVal, Object... more) { - Map retVal = new HashMap<>() - retVal.put(firstKey, firstVal) - for (int i = 0; i < more.length; i += 2) { - retVal.put((String) more[i], more[i + 1]) - } - return retVal - } - - - def "Basic case works"() { - given: - String query = "{ string(value: \"Basic\"){value, nonNullValue, veryNonNullValue} }" - - def expected = [string: [veryNonNullValue: "Basic", nonNullValue: "Basic", value: "Basic"]] - println expected - - expect: - runTest(query, expected) - } - - def "Empty input"() { - given: - String query = "{ string(value: \"\"){value} }" - - def expected = [string: ["value": ""]] - - expect: - runTest(query, expected) - } - - def "Handles implicit null input"() { - given: - String query = "{ string{value} }" - - def expected = [string: null] - - expect: - runTest(query, expected) - } - - def "Handles explicit null input"() { - given: - String query = "{ string(value: \"null\"){value} }" - - def expected = [string: [value: null]] - - expect: - runTest(query, expected) - } - - def "Shatter works"() { - given: - String query = "{ string(value: \"Shatter\") {shatter{value}} }" - - def expected = ["string": ["shatter": [ - ["value": "S"], - ["value": "h"], - ["value": "a"], - ["value": "t"], - ["value": "t"], - ["value": "e"], - ["value": "r"] - ]]] - - - expect: - runTest(query, expected) - - } - - def "Shatter then append"() { - given: - String query = - "{ string(value: \"Sh\") { shatter { append(text: \"1\") { value } } } }" - - def expected = [string: [shatter: [[append: [value: "S1"]], [append: [value: "h1"]]]]] - - expect: - runTest(query, expected) - - } - - - def "Legal null entries in lists"() { - given: - String query = - "{ " + - "string(value: \"Sh\") {" + - "shatter { " + - "append(text: \"1\") {" + - "split(regex: \"h\") {" + - "value " + - "} " + - "} " + - "} " + - "} " + - "}" - - def expected = [string: [shatter: [[append: [split: [[value: "S1"]]]], [append: [split: [null, [value: "1"]]]]]]] - - expect: - runTest(query, expected) - - } - - def "Legal null values for entire lists"() { - - given: - String query = - "{ " + - "string(value: \"Sh\") {" + - "shatter { " + - "append(text: \"1\") {" + - "split {" + - "value " + - "} " + - "} " + - "} " + - "} " + - "}" - - def expected = [string: [shatter: [[append: [split: null]], [append: [split: null]]]]] - - expect: - runTest(query, expected) - - } - - - def "Legal null values for primitives"() { - - given: - String query = - "{ " + - "string(value: \"Shxnull\") {" + - "split(regex: \"x\") {" + - "value " + - "} " + - "} " + - "}" - - def expected = [string: [split: [[value: "Sh"], [value: null]]]] - - expect: - runTest(query, expected) - - } - - def "Legal null value for enum"() { - - given: - String query = - "{ nullEnum }" - - def expected = [nullEnum: null] - - expect: - runTest(query, expected) - - } - - def "Illegal null value for an object in a list"() { - given: - String query = - "{ " + - "string(value: \"Sh\") {" + - "shatter { " + - "append(text: \"1\") {" + - "splitNonNull(regex: \"h\") {" + - "value " + - "} " + - "} " + - "} " + - "} " + - "}" - - expect: - runTestExpectError(query, "non-null") - - } - - - def "Nested lists"() { - given: - String query = - "{ " + - "string(value: \"List of words\") {" + - "wordsAndLetters { " + - " value " + - "} " + - "} " + - "}" - - def expected = [string: [wordsAndLetters: [[[value: "L"], [value: "i"], [value: "s"], [value: "t"]], - [[value: "o"], [value: "f"]], - [[value: "w"], [value: "o"], [value: "r"], [value: "d"], [value: "s"]]]]] - - expect: - runTest(query, expected) - - } - - - def "Batching works"() { - given: - String query = """ - { string(value: "Batch") { - append(text: "x") { - value - } - shatter { - append(text: "1") { - split(regex: "h") { - value - } - } - } - } - }""" - - def expected = [string: - [append : [value: "Batchx"], - shatter: - [[append: [split: [[value: "B1"]]]], - [append: [split: [[value: "a1"]]]], - [append: [split: [[value: "t1"]]]], - [append: [split: [[value: "c1"]]]], - [append: [split: [null, [value: "1"]]]]] - ] - ] - expect: - runTest(query, expected) - - this.countMap.get(FunWithStringsSchemaFactory.CallType.VALUE).get() == 2 - this.countMap.get(FunWithStringsSchemaFactory.CallType.SHATTER).get() == 1 - this.countMap.get(FunWithStringsSchemaFactory.CallType.APPEND).get() == 2 - this.countMap.get(FunWithStringsSchemaFactory.CallType.SPLIT).get() == 1 - } - - - def "Return value ordering"() { - given: - String query = """ - { string(value: "TS") { - append(text:"1") { - v1:value - v2:nonNullValue - v3:veryNonNullValue - v4:value - v5:nonNullValue - v6:veryNonNullValue - v7:value - v8:nonNullValue - v9:veryNonNullValue - } - } - }""" - - expect: - Arrays.asList(this.graphQLAsync, this.graphQLBatchedButUnbatched, this.graphQLBatchedValue).each { GraphQL graphQL -> - Map response = graphQL.execute(query).getData() as Map - Map values = (response.get("string") as Map).get("append") as Map - assert ["v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9"] == values.keySet().toList() - } - } - - def "Handle exception inside DataFetcher"() { - given: - String query = "{ string(value: \"\"){ throwException} }" - Map expected = ["string": ["throwException": null]] - expect: - runTest(query, expected) - runTestExpectErrors(query, new RuntimeException("TestException")) - } - - def "Invalid batch size return does not crash whole query but generates error"() { - given: - String query = "{ string(value: \"\"){ returnBadList } }" - Map expected = ["string": ["returnBadList": null]] - expect: - runTestBatching(query, expected) - runTestBatchingExpectErrors(query, new BatchAssertionFailed(), false) - } - - def "#673 optional support"() { - given: - String query = "{ string(value: \"673-optional-support\"){emptyOptional, optional} }" - - def expected = [string: [emptyOptional: null, optional: "673-optional-support"]] - println expected - - expect: - runTest(query, expected) - } - - - def "Any Iterable is accepted as GraphQL list value"() { - given: - String query = "{ string(value: \"test\"){ anyIterable } }" - Map expected = ["string": ["anyIterable": ["test", "end"]]] - expect: - runTest(query, expected) - } - - def "#672-683 handles completable futures ok"() { - - given: - String query = "{ string(value: \"test\"){ completableFuture } }" - Map expected = ["string": ["completableFuture": "completableFuture"]] - expect: - runTest(query, expected) - } - - def "#672-683 handles completable futures ok in interfaces"() { - - given: - String query = "{ interface { value } }" - Map expected = ["interface": ["value": "interfacesHandled"]] - expect: - runTest(query, expected) - } - - def "#684 handles exceptions in DFs"() { - - given: - def UserType = newObject() - .name("User") - .field(newFieldDefinition() - .name("id") - .type(nonNull(Scalars.GraphQLInt)) - .dataFetcher( - { e -> throw new RuntimeException("Hello") } - )).build() - - DataFetcher userDataFetcher = { environment -> - if (environment.getArgument("nullArg") == true) { - return null - } - Map user = new HashMap<>() - user.put("id", 1) - return user - } - GraphQLObjectType queryObject = newObject().name("Query") - .field(newFieldDefinition() - .name("user") - .type(nonNull(UserType)) - .argument(newArgument().name("nullArg").type(Scalars.GraphQLBoolean)) - .dataFetcher(userDataFetcher) - ).build() - - GraphQLSchema schema = GraphQLSchema.newSchema() - .query(queryObject) - .build() - - GraphQL graphQL = GraphQL.newGraphQL(schema) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .build() - - //ExecutionResult result = graphQL.execute("query { user(nullArg:false) { id } }") - ExecutionResult result = graphQL.execute("query { user { id } }") - - expect: - result.getErrors().size() == 1 - result.getErrors()[0] instanceof ExceptionWhileDataFetching - } - -} diff --git a/src/test/groovy/graphql/execution/batched/FunWithStringsSchemaFactory.java b/src/test/groovy/graphql/execution/batched/FunWithStringsSchemaFactory.java deleted file mode 100644 index 7438332ef3..0000000000 --- a/src/test/groovy/graphql/execution/batched/FunWithStringsSchemaFactory.java +++ /dev/null @@ -1,442 +0,0 @@ -package graphql.execution.batched; - -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; -import graphql.schema.GraphQLArgument; -import graphql.schema.GraphQLEnumType; -import graphql.schema.GraphQLInterfaceType; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLSchema; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicInteger; - -import static graphql.Scalars.GraphQLString; -import static graphql.schema.GraphQLEnumType.newEnum; -import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import static graphql.schema.GraphQLInterfaceType.newInterface; -import static graphql.schema.GraphQLList.list; -import static graphql.schema.GraphQLNonNull.nonNull; -import static graphql.schema.GraphQLObjectType.newObject; -import static graphql.schema.GraphQLTypeReference.typeRef; - -public class FunWithStringsSchemaFactory { - - - private static void increment(Map callCounts, CallType type) { - if (!callCounts.containsKey(type)) { - callCounts.put(type, new AtomicInteger(0)); - } - callCounts.get(type).incrementAndGet(); - } - - public enum CallType { - VALUE, APPEND, WORDS_AND_LETTERS, SPLIT, SHATTER - } - - public static FunWithStringsSchemaFactory createBatched(final Map callCounts) { - FunWithStringsSchemaFactory factory = new FunWithStringsSchemaFactory(); - - - factory.setStringObjectValueFetcher(new DataFetcher() { - @Override - @Batched - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - increment(callCounts, CallType.VALUE); - List retVal = new ArrayList<>(); - for (String s : (List) environment.getSource()) { - retVal.add("null".equals(s) ? null : s); - } - return retVal; - } - }); - - factory.setThrowExceptionFetcher(new DataFetcher() { - @Override - @Batched - public Object get(DataFetchingEnvironment environment) { - throw new RuntimeException("TestException"); - } - }); - - factory.setReturnBadList(new DataFetcher() { - @Override - @Batched - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - List retVal = new ArrayList<>(); - for (String s : (List) environment.getSource()) { - retVal.add("null".equals(s) ? null : s); - } - retVal.add("badValue"); - return retVal; - } - }); - - factory.setAnyIterable(new DataFetcher() { - @Override - @Batched - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - List> retVal = new ArrayList<>(); - for (String s : (List) environment.getSource()) { - retVal.add(new LinkedHashSet<>(Arrays.asList(s, "end"))); - } - return retVal; - } - }); - - factory.setAppendFetcher(new DataFetcher() { - @Override - @Batched - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - increment(callCounts, CallType.APPEND); - List retVal = new ArrayList<>(); - for (String s : (List) environment.getSource()) { - retVal.add(s + environment.getArgument("text")); - } - // make it an Iterable thing not just List - return new ArrayDeque<>(retVal); - } - }); - - factory.setWordsAndLettersFetcher(new DataFetcher() { - @Batched - @Override - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - increment(callCounts, CallType.WORDS_AND_LETTERS); - List sources = environment.getSource(); - List>> retVal = new ArrayList<>(); - for (String source : sources) { - List> sentence = new ArrayList<>(); - splitSentence(source, sentence); - retVal.add(sentence); - } - return retVal.toArray(); - } - }); - - factory.setSplitFetcher(new DataFetcher() { - @Batched - @Override - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - increment(callCounts, CallType.SPLIT); - String regex = environment.getArgument("regex"); - List sources = environment.getSource(); - List> retVal = new ArrayList<>(); - if (regex == null) { - for (String ignored : sources) { - retVal.add(null); - } - return retVal; - } - for (String source : sources) { - List retItem = new ArrayList<>(); - for (String str : source.split(regex)) { - if (str.isEmpty()) { - retItem.add(null); - } else { - retItem.add(str); - } - } - retVal.add(retItem); - } - return retVal; - } - }); - - factory.setShatterFetcher(new DataFetcher() { - @Batched - @Override - @SuppressWarnings("unchecked") - public Object get(DataFetchingEnvironment environment) { - increment(callCounts, CallType.SHATTER); - List sources = environment.getSource(); - List> retVal = new ArrayList<>(); - for (String source : sources) { - List retItem = new ArrayList<>(); - for (char c : source.toCharArray()) { - retItem.add(Character.toString(c)); - } - retVal.add(retItem); - } - return retVal; - } - }); - - return factory; - - } - - private void setAnyIterable(DataFetcher fetcher) { - this.anyIterableFetcher = fetcher; - } - - private static void splitSentence(String source, List> sentence) { - for (String word : source.split(" ")) { - List letters = new ArrayList<>(); - for (char c : word.toCharArray()) { - letters.add(Character.toString(c)); - } - sentence.add(letters); - } - } - - - private DataFetcher stringObjectValueFetcher = e -> "null".equals(e.getSource()) ? null : e.getSource(); - - private DataFetcher throwExceptionFetcher = e -> { - throw new RuntimeException("TestException"); - }; - - private DataFetcher returnBadListFetcher = e -> { - throw new RuntimeException("This field should only be queried in batch."); - }; - - private DataFetcher shatterFetcher = e -> { - String source = e.getSource(); - if (source.isEmpty()) { - return null; // trigger error - } - List retVal = new ArrayList<>(); - for (char c : source.toCharArray()) { - retVal.add(Character.toString(c)); - } - return retVal; - }; - - private DataFetcher wordsAndLettersFetcher = e -> { - String source = e.getSource(); - List> retVal = new ArrayList<>(); - splitSentence(source, retVal); - return retVal; - }; - - private DataFetcher splitFetcher = e -> { - String regex = e.getArgument("regex"); - if (regex == null) { - return null; - } - String source = e.getSource(); - List retVal = new ArrayList<>(); - for (String str : source.split(regex)) { - if (str.isEmpty()) { - retVal.add(null); - } else { - retVal.add(str); - } - } - return retVal; - }; - - private DataFetcher appendFetcher = e -> ((String) e.getSource()) + e.getArgument("text"); - - private DataFetcher emptyOptionalFetcher = e -> Optional.empty(); - - private DataFetcher optionalFetcher = e -> Optional.of("673-optional-support"); - - private DataFetcher completableFutureFetcher = e -> CompletableFuture.completedFuture("completableFuture"); - - private DataFetcher anyIterableFetcher = e -> { - String source = e.getSource(); - return new LinkedHashSet<>(Arrays.asList(source, "end")); - }; - - private void setWordsAndLettersFetcher(DataFetcher fetcher) { - this.wordsAndLettersFetcher = fetcher; - } - - private void setShatterFetcher(DataFetcher fetcher) { - this.shatterFetcher = fetcher; - } - - private void setSplitFetcher(DataFetcher splitFetcher) { - this.splitFetcher = splitFetcher; - } - - private void setAppendFetcher(DataFetcher appendFetcher) { - this.appendFetcher = appendFetcher; - } - - private void setStringObjectValueFetcher(DataFetcher fetcher) { - this.stringObjectValueFetcher = fetcher; - } - - private void setThrowExceptionFetcher(DataFetcher fetcher) { - this.throwExceptionFetcher = fetcher; - } - - private void setReturnBadList(DataFetcher fetcher) { - this.returnBadListFetcher = fetcher; - } - - public static class SimpleObject { - public String getValue() { - return "interfacesHandled"; - } - } - - GraphQLSchema createSchema() { - - GraphQLObjectType stringObjectType = newObject() - .name("StringObject") - .field(newFieldDefinition() - .name("value") - .type(GraphQLString) - .dataFetcher(stringObjectValueFetcher)) - .field(newFieldDefinition() - .name("nonNullValue") - .type(nonNull(GraphQLString)) - .dataFetcher(stringObjectValueFetcher)) - .field(newFieldDefinition() - .name("veryNonNullValue") - .type(nonNull(nonNull(GraphQLString))) - .dataFetcher(stringObjectValueFetcher)) - .field(newFieldDefinition() - .name("throwException") - .type(GraphQLString) - .dataFetcher(throwExceptionFetcher)) - .field(newFieldDefinition() - .name("returnBadList") - .type(GraphQLString) - .dataFetcher(returnBadListFetcher)) - .field(newFieldDefinition() - .name("anyIterable") - .type(list(GraphQLString)) - .dataFetcher(anyIterableFetcher)) - .field(newFieldDefinition() - .name("shatter") - .type(nonNull(list(nonNull(typeRef("StringObject"))))) - .dataFetcher(shatterFetcher)) - - .field(newFieldDefinition() - .name("wordsAndLetters") - .type(nonNull(list(nonNull(list(nonNull(nonNull(typeRef("StringObject")))))))) - .dataFetcher(wordsAndLettersFetcher)) - - .field(newFieldDefinition() - .name("split") - .description("String#split(regex) but replace empty strings with nulls to help us test null behavior in lists") - .type(list(typeRef("StringObject"))) - .argument(GraphQLArgument.newArgument() - .name("regex") - .type(GraphQLString)) - .dataFetcher(splitFetcher)) - - .field(newFieldDefinition() - .name("splitNotNull") - .description("String#split(regex) but replace empty strings with nulls to help us test null behavior in lists") - .type(list(nonNull(typeRef("StringObject")))) - .argument(GraphQLArgument.newArgument() - .name("regex") - .type(GraphQLString)) - .dataFetcher(splitFetcher)) - - - .field(newFieldDefinition() - .name("append") - .type(typeRef("StringObject")) - .argument(GraphQLArgument.newArgument() - .name("text") - .type(GraphQLString)) - .dataFetcher(appendFetcher)) - - .field(newFieldDefinition() - .name("emptyOptional") - .type(GraphQLString) - .argument(GraphQLArgument.newArgument() - .name("text") - .type(GraphQLString)) - .dataFetcher(emptyOptionalFetcher)) - - .field(newFieldDefinition() - .name("optional") - .type(GraphQLString) - .argument(GraphQLArgument.newArgument() - .name("text") - .type(GraphQLString)) - .dataFetcher(optionalFetcher)) - - .field(newFieldDefinition() - .name("completableFuture") - .type(GraphQLString) - .argument(GraphQLArgument.newArgument() - .name("text") - .type(GraphQLString)) - .dataFetcher(completableFutureFetcher)) - - .build(); - - - GraphQLEnumType enumDayType = newEnum() - .name("Day") - .value("MONDAY") - .value("TUESDAY") - .description("Day of the week") - .build(); - - - GraphQLObjectType simpleObjectType = newObject() - .name("SimpleObject") - .withInterface(typeRef("InterfaceType")) - .field(newFieldDefinition() - .name("value") - .type(GraphQLString)) - .build(); - - - GraphQLInterfaceType interfaceType = newInterface() - .name("InterfaceType") - .field(newFieldDefinition() - .name("value") - .type(GraphQLString) - ) - .typeResolver(env -> { - // always this for testing - return simpleObjectType; - }) - .build(); - - GraphQLObjectType queryType = newObject() - .name("StringQuery") - .field(newFieldDefinition() - .name("string") - .type(stringObjectType) - .argument(GraphQLArgument.newArgument() - .name("value") - .type(GraphQLString)) - .dataFetcher(env -> env.getArgument("value")) - ) - .field(newFieldDefinition() - .name("interface") - .type(interfaceType) - .argument(GraphQLArgument.newArgument() - .name("value") - .type(GraphQLString)) - .dataFetcher(env -> CompletableFuture.completedFuture(new SimpleObject())) - ) - .field(newFieldDefinition() - .name("nullEnum") - .type(enumDayType) - .dataFetcher(env -> null) - ) - .build(); - - return GraphQLSchema.newSchema() - .query(queryType) - .additionalType(simpleObjectType) - .build(); - - } -} diff --git a/src/test/groovy/graphql/execution/defer/BasicSubscriber.groovy b/src/test/groovy/graphql/execution/defer/BasicSubscriber.groovy deleted file mode 100644 index 28cdad9135..0000000000 --- a/src/test/groovy/graphql/execution/defer/BasicSubscriber.groovy +++ /dev/null @@ -1,34 +0,0 @@ -package graphql.execution.defer - -import graphql.ExecutionResult -import org.reactivestreams.Subscriber -import org.reactivestreams.Subscription - -import java.util.concurrent.atomic.AtomicBoolean - -class BasicSubscriber implements Subscriber { - Subscription subscription - AtomicBoolean finished = new AtomicBoolean() - Throwable throwable - - @Override - void onSubscribe(Subscription s) { - assert s != null, "subscription must not be null" - this.subscription = s - s.request(1) - } - - @Override - void onNext(ExecutionResult executionResult) { - } - - @Override - void onError(Throwable t) { - finished.set(true) - } - - @Override - void onComplete() { - finished.set(true) - } -} diff --git a/src/test/groovy/graphql/execution/defer/CapturingSubscriber.groovy b/src/test/groovy/graphql/execution/defer/CapturingSubscriber.groovy deleted file mode 100644 index 3b66ac4ca2..0000000000 --- a/src/test/groovy/graphql/execution/defer/CapturingSubscriber.groovy +++ /dev/null @@ -1,45 +0,0 @@ -package graphql.execution.defer - -import graphql.ExecutionResult -import org.reactivestreams.Publisher -import org.reactivestreams.Subscriber -import org.reactivestreams.Subscription - -import java.util.concurrent.atomic.AtomicBoolean - -class CapturingSubscriber implements Subscriber { - Subscription subscription - AtomicBoolean finished = new AtomicBoolean() - Throwable throwable - List executionResults = [] - List executionResultData = [] - - AtomicBoolean subscribeTo(Publisher publisher) { - publisher.subscribe(this) - return finished - } - - @Override - void onSubscribe(Subscription s) { - assert s != null, "subscription must not be null" - this.subscription = s - s.request(1) - } - - @Override - void onNext(ExecutionResult executionResult) { - executionResults.add(executionResult) - executionResultData.add(executionResult.getData()) - subscription.request(1) - } - - @Override - void onError(Throwable t) { - finished.set(true) - } - - @Override - void onComplete() { - finished.set(true) - } -} diff --git a/src/test/groovy/graphql/execution/defer/DeferCallTest.groovy b/src/test/groovy/graphql/execution/defer/DeferCallTest.groovy deleted file mode 100644 index 87b7ac8b4c..0000000000 --- a/src/test/groovy/graphql/execution/defer/DeferCallTest.groovy +++ /dev/null @@ -1,45 +0,0 @@ -package graphql.execution.defer - -import graphql.ExecutionResultImpl -import graphql.validation.ValidationError -import graphql.validation.ValidationErrorType -import spock.lang.Specification - -import static java.util.concurrent.CompletableFuture.completedFuture - -class DeferCallTest extends Specification { - - def "test call capture gives a CF"() { - given: - DeferredCall call = new DeferredCall({ - completedFuture(new ExecutionResultImpl("some data", Collections.emptyList())) - }, new DeferredErrorSupport()) - - when: - def future = call.invoke() - then: - future.join().data == "some data" - } - - def "test error capture happens via CF"() { - given: - def errorSupport = new DeferredErrorSupport() - errorSupport.onError(new ValidationError(ValidationErrorType.MissingFieldArgument)) - errorSupport.onError(new ValidationError(ValidationErrorType.FieldsConflict)) - - DeferredCall call = new DeferredCall({ - completedFuture(new ExecutionResultImpl("some data", [new ValidationError(ValidationErrorType.FieldUndefined)])) - }, errorSupport) - - when: - def future = call.invoke() - def er = future.join() - - then: - er.errors.size() == 3 - er.errors[0].message.contains("Validation error of type FieldUndefined") - er.errors[1].message.contains("Validation error of type MissingFieldArgument") - er.errors[2].message.contains("Validation error of type FieldsConflict") - - } -} diff --git a/src/test/groovy/graphql/execution/defer/DeferSupportIntegrationTest.groovy b/src/test/groovy/graphql/execution/defer/DeferSupportIntegrationTest.groovy deleted file mode 100644 index 0aef52d3ec..0000000000 --- a/src/test/groovy/graphql/execution/defer/DeferSupportIntegrationTest.groovy +++ /dev/null @@ -1,274 +0,0 @@ -package graphql.execution.defer - -import graphql.ExecutionInput -import graphql.ExecutionResult -import graphql.GraphQL -import graphql.TestUtil -import graphql.schema.DataFetcher -import graphql.schema.DataFetchingEnvironment -import graphql.schema.idl.RuntimeWiring -import org.awaitility.Awaitility -import org.reactivestreams.Publisher -import spock.lang.Specification - -import java.time.Duration -import java.util.concurrent.CompletableFuture - -import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring - -class DeferSupportIntegrationTest extends Specification { - def then = 0 - - def sentAt() { - def seconds = Duration.ofMillis(System.currentTimeMillis() - then).toMillis() - "T+" + seconds - } - - def sleepSome(DataFetchingEnvironment env) { - Integer sleepTime = env.getArgument("sleepTime") - sleepTime = Optional.ofNullable(sleepTime).orElse(0) - Thread.sleep(sleepTime) - } - - def schemaSpec = ''' - type Query { - post : Post - } - - type Post { - postText : String - sentAt : String - echo(text : String = "echo") : String - comments(sleepTime : Int, prefix :String) : [Comment] - reviews(sleepTime : Int) : [Review] - } - - type Comment { - commentText : String - sentAt : String - comments(sleepTime : Int, prefix :String) : [Comment] - goes : Bang - } - - type Review { - reviewText : String - sentAt : String - comments(sleepTime : Int, prefix :String) : [Comment] - goes : Bang - } - - type Bang { - bang : String - } - ''' - - DataFetcher postFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - return CompletableFuture.supplyAsync({ - [postText: "post_data", sentAt: sentAt()] - }) - } - } - DataFetcher commentsFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment env) { - return CompletableFuture.supplyAsync({ - sleepSome(env) - - def prefix = env.getArgument("prefix") - prefix = prefix == null ? "" : prefix - - def result = [] - for (int i = 0; i < 3; i++) { - result.add([commentText: prefix + "comment" + i, sentAt: sentAt(), goes: "goes"]) - } - return result - }) - } - - } - DataFetcher reviewsFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment env) { - return CompletableFuture.supplyAsync({ - sleepSome(env) - def result = [] - for (int i = 0; i < 3; i++) { - result.add([reviewText: "review" + i, sentAt: sentAt(), goes: "goes"]) - } - return result - }) - } - } - - DataFetcher bangDataFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - throw new RuntimeException("Bang!") - } - } - DataFetcher echoDataFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - return environment.getArgument("text") - } - } - - GraphQL graphQL = null - - void setup() { - then = System.currentTimeMillis() - - def runtimeWiring = RuntimeWiring.newRuntimeWiring() - .type(newTypeWiring("Query").dataFetcher("post", postFetcher)) - .type(newTypeWiring("Post").dataFetcher("comments", commentsFetcher)) - .type(newTypeWiring("Post").dataFetcher("echo", echoDataFetcher)) - .type(newTypeWiring("Post").dataFetcher("reviews", reviewsFetcher)) - .type(newTypeWiring("Bang").dataFetcher("bang", bangDataFetcher)) - - .type(newTypeWiring("Comment").dataFetcher("comments", commentsFetcher)) - .type(newTypeWiring("Review").dataFetcher("comments", commentsFetcher)) - .build() - def schema = TestUtil.schema(schemaSpec, runtimeWiring) - - graphQL = GraphQL.newGraphQL(schema).build() - } - - def "test defer support end to end"() { - - def query = ''' - query { - post { - postText - - a :comments(sleepTime:200) @defer { - commentText - } - - b : reviews(sleepTime:100) @defer { - reviewText - comments(prefix : "b_") @defer { - commentText - } - } - - c: reviews @defer { - goes { - bang - } - } - } - } - ''' - - when: - def initialResult = graphQL.execute(ExecutionInput.newExecutionInput().query(query).build()) - - then: - initialResult.errors.isEmpty() - initialResult.data == ["post": ["postText": "post_data"]] - - when: - - Publisher deferredResultStream = initialResult.extensions[GraphQL.DEFERRED_RESULTS] as Publisher - - def subscriber = new CapturingSubscriber() - subscriber.subscribeTo(deferredResultStream); - Awaitility.await().untilTrue(subscriber.finished) - - List resultList = subscriber.executionResults - - then: - - assertDeferredData(resultList) - } - - def "test defer support keeps the fields named correctly when interspersed in the query"() { - - def query = ''' - query { - post { - interspersedA: echo(text:"before a:") - - a: comments(sleepTime:200) @defer { - commentText - } - - interspersedB: echo(text:"before b:") - - b : reviews(sleepTime:100) @defer { - reviewText - comments(prefix : "b_") @defer { - commentText - } - } - - interspersedC: echo(text:"before c:") - - c: reviews @defer { - goes { - bang - } - } - - interspersedD: echo(text:"after c:") - } - } - ''' - - when: - def initialResult = graphQL.execute(ExecutionInput.newExecutionInput().query(query).build()) - - then: - initialResult.errors.isEmpty() - initialResult.data == ["post": [ - "interspersedA": "before a:", - "interspersedB": "before b:", - "interspersedC": "before c:", - "interspersedD": "after c:", - ]] - - when: - - Publisher deferredResultStream = initialResult.extensions[GraphQL.DEFERRED_RESULTS] as Publisher - - def subscriber = new CapturingSubscriber() - subscriber.subscribeTo(deferredResultStream); - Awaitility.await().untilTrue(subscriber.finished) - - List resultList = subscriber.executionResults - - then: - - assertDeferredData(resultList) - } - - def assertDeferredData(ArrayList resultList) { - resultList.size() == 6 - - assert resultList[0].data == [[commentText: "comment0"], [commentText: "comment1"], [commentText: "comment2"]] - assert resultList[0].errors == [] - - assert resultList[1].data == [[reviewText: "review0"], [reviewText: "review1"], [reviewText: "review2"]] - assert resultList[1].errors == [] - - // exceptions in here - assert resultList[2].errors.size() == 3 - assert resultList[2].errors[0].getMessage() == "Exception while fetching data (/post/c[0]/goes/bang) : Bang!" - assert resultList[2].errors[1].getMessage() == "Exception while fetching data (/post/c[1]/goes/bang) : Bang!" - assert resultList[2].errors[2].getMessage() == "Exception while fetching data (/post/c[2]/goes/bang) : Bang!" - - // sub defers are sent in encountered order - assert resultList[3].data == [[commentText: "b_comment0"], [commentText: "b_comment1"], [commentText: "b_comment2"]] - assert resultList[3].errors == [] - - assert resultList[4].data == [[commentText: "b_comment0"], [commentText: "b_comment1"], [commentText: "b_comment2"]] - assert resultList[4].errors == [] - - assert resultList[5].data == [[commentText: "b_comment0"], [commentText: "b_comment1"], [commentText: "b_comment2"]] - assert resultList[5].errors == [] - - true - } -} diff --git a/src/test/groovy/graphql/execution/defer/DeferSupportTest.groovy b/src/test/groovy/graphql/execution/defer/DeferSupportTest.groovy deleted file mode 100644 index a2d9cdbb71..0000000000 --- a/src/test/groovy/graphql/execution/defer/DeferSupportTest.groovy +++ /dev/null @@ -1,222 +0,0 @@ -package graphql.execution.defer - -import graphql.ExecutionResult -import graphql.ExecutionResultImpl -import graphql.language.Directive -import graphql.language.Field -import org.awaitility.Awaitility -import spock.lang.Specification - -import java.util.concurrent.CompletableFuture - -class DeferSupportTest extends Specification { - - - def "emits N deferred calls with order preserved"() { - - given: - def deferSupport = new DeferSupport() - deferSupport.enqueue(offThread("A", 100)) // <-- will finish last - deferSupport.enqueue(offThread("B", 50)) // <-- will finish second - deferSupport.enqueue(offThread("C", 10)) // <-- will finish first - - when: - List results = [] - def subscriber = new BasicSubscriber() { - @Override - void onNext(ExecutionResult executionResult) { - results.add(executionResult) - subscription.request(1) - } - } - deferSupport.startDeferredCalls().subscribe(subscriber) - Awaitility.await().untilTrue(subscriber.finished) - then: - - results.size() == 3 - results[0].data == "A" - results[1].data == "B" - results[2].data == "C" - } - - def "calls within calls are enqueued correctly"() { - given: - def deferSupport = new DeferSupport() - deferSupport.enqueue(offThreadCallWithinCall(deferSupport, "A", "a", 100)) - deferSupport.enqueue(offThreadCallWithinCall(deferSupport, "B", "b", 50)) - deferSupport.enqueue(offThreadCallWithinCall(deferSupport, "C", "c", 10)) - - when: - List results = [] - BasicSubscriber subscriber = new BasicSubscriber() { - @Override - void onNext(ExecutionResult executionResult) { - results.add(executionResult) - subscription.request(1) - } - } - deferSupport.startDeferredCalls().subscribe(subscriber) - - Awaitility.await().untilTrue(subscriber.finished) - then: - - results.size() == 6 - results[0].data == "A" - results[1].data == "B" - results[2].data == "C" - results[3].data == "a" - results[4].data == "b" - results[5].data == "c" - } - - def "stops at first exception encountered"() { - given: - def deferSupport = new DeferSupport() - deferSupport.enqueue(offThread("A", 100)) - deferSupport.enqueue(offThread("Bang", 50)) // <-- will throw exception - deferSupport.enqueue(offThread("C", 10)) - - when: - List results = [] - Throwable thrown = null - def subscriber = new BasicSubscriber() { - @Override - void onNext(ExecutionResult executionResult) { - results.add(executionResult) - subscription.request(1) - } - - @Override - void onError(Throwable t) { - thrown = t - finished.set(true) - } - - @Override - void onComplete() { - assert false, "This should not be called!" - } - } - deferSupport.startDeferredCalls().subscribe(subscriber) - - Awaitility.await().untilTrue(subscriber.finished) - then: - - thrown.message == "java.lang.RuntimeException: Bang" - } - - def "you can cancel the subscription"() { - given: - def deferSupport = new DeferSupport() - deferSupport.enqueue(offThread("A", 100)) // <-- will finish last - deferSupport.enqueue(offThread("B", 50)) // <-- will finish second - deferSupport.enqueue(offThread("C", 10)) // <-- will finish first - - when: - List results = [] - def subscriber = new BasicSubscriber() { - @Override - void onNext(ExecutionResult executionResult) { - results.add(executionResult) - subscription.cancel() - finished.set(true) - } - } - deferSupport.startDeferredCalls().subscribe(subscriber) - - Awaitility.await().untilTrue(subscriber.finished) - then: - - results.size() == 1 - results[0].data == "A" - - } - - def "you cant subscribe twice"() { - given: - def deferSupport = new DeferSupport() - deferSupport.enqueue(offThread("A", 100)) - deferSupport.enqueue(offThread("Bang", 50)) // <-- will finish second - deferSupport.enqueue(offThread("C", 10)) // <-- will finish first - - when: - Throwable expectedThrowble - deferSupport.startDeferredCalls().subscribe(new BasicSubscriber()) - deferSupport.startDeferredCalls().subscribe(new BasicSubscriber() { - @Override - void onError(Throwable t) { - expectedThrowble = t - } - }) - then: - expectedThrowble != null - } - - def "indicates of there any defers present"() { - given: - def deferSupport = new DeferSupport() - - when: - def deferPresent1 = deferSupport.isDeferDetected() - - then: - !deferPresent1 - - when: - deferSupport.enqueue(offThread("A", 100)) - def deferPresent2 = deferSupport.isDeferDetected() - - then: - deferPresent2 - } - - def "detects @defer directive"() { - given: - def deferSupport = new DeferSupport() - - when: - def noDirectivePresent = deferSupport.checkForDeferDirective([ - new Field("a"), - new Field("b") - ]) - - then: - !noDirectivePresent - - when: - def directivePresent = deferSupport.checkForDeferDirective([ - Field.newField("a").directives([new Directive("defer")]).build(), - new Field("b") - ]) - - then: - directivePresent - - - } - - private static DeferredCall offThread(String data, int sleepTime) { - def callSupplier = { - CompletableFuture.supplyAsync({ - Thread.sleep(sleepTime) - if (data == "Bang") { - throw new RuntimeException(data) - } - new ExecutionResultImpl(data, []) - }) - } - return new DeferredCall(callSupplier, new DeferredErrorSupport()) - } - - private - static DeferredCall offThreadCallWithinCall(DeferSupport deferSupport, String dataParent, String dataChild, int sleepTime) { - def callSupplier = { - CompletableFuture.supplyAsync({ - Thread.sleep(sleepTime) - deferSupport.enqueue(offThread(dataChild, sleepTime)) - new ExecutionResultImpl(dataParent, []) - }) - } - return new DeferredCall(callSupplier, new DeferredErrorSupport()) - } -} diff --git a/src/test/groovy/graphql/execution/defer/DeferredErrorSupportTest.groovy b/src/test/groovy/graphql/execution/defer/DeferredErrorSupportTest.groovy deleted file mode 100644 index 59c3e993bf..0000000000 --- a/src/test/groovy/graphql/execution/defer/DeferredErrorSupportTest.groovy +++ /dev/null @@ -1,76 +0,0 @@ -package graphql.execution.defer - -import graphql.Directives -import graphql.ExecutionResult -import graphql.GraphQL -import graphql.schema.DataFetcher -import graphql.schema.DataFetchingEnvironment -import org.reactivestreams.Publisher -import spock.lang.Specification - -import static graphql.TestUtil.schema -import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring -import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring -import static org.awaitility.Awaitility.await - -class DeferredErrorSupportTest extends Specification { - - def "#1040 errors in stage one do not affect deferred stages"() { - - def spec = ''' - type Query { - stage1 : String - stage2 : String - } - ''' - - def bangDF = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - throw new RuntimeException("bang-" + environment.getField().getName()) - } - } - - def runtimeWiring = newRuntimeWiring().type( - newTypeWiring("Query") - .dataFetchers([ - stage1: bangDF, - stage2: bangDF, - ]) - ).build() - - def schema = schema(spec, runtimeWiring).transform({ b -> b.additionalDirective(Directives.DeferDirective) }) - def graphql = GraphQL.newGraphQL(schema).build() - - when: - def executionResult = graphql.execute(''' - { - stage1, - stage2 @defer - } - ''') - - then: - executionResult.errors.size() == 1 - executionResult.errors[0].getMessage().contains("bang-stage1") - - when: - def executionResultDeferred = null - def subscriber = new BasicSubscriber() { - @Override - void onNext(ExecutionResult executionResultStreamed) { - executionResultDeferred = executionResultStreamed - subscription.request(1) - } - } - Publisher deferredResultStream = executionResult.extensions[GraphQL.DEFERRED_RESULTS] as Publisher - deferredResultStream.subscribe(subscriber) - - await().untilTrue(subscriber.finished) - - then: - executionResultDeferred.errors.size() == 1 - executionResultDeferred.errors[0].getMessage().contains("bang-stage2") - - } -} diff --git a/src/test/groovy/graphql/execution/directives/QueryDirectivesImplTest.groovy b/src/test/groovy/graphql/execution/directives/QueryDirectivesImplTest.groovy new file mode 100644 index 0000000000..80b1bbbd5c --- /dev/null +++ b/src/test/groovy/graphql/execution/directives/QueryDirectivesImplTest.groovy @@ -0,0 +1,120 @@ +package graphql.execution.directives + +import graphql.GraphQLContext +import graphql.TestUtil +import graphql.execution.CoercedVariables +import graphql.execution.MergedField +import graphql.execution.NormalizedVariables +import graphql.language.IntValue +import graphql.normalized.NormalizedInputValue +import spock.lang.Specification + +import static graphql.language.AstPrinter.printAst + +class QueryDirectivesImplTest extends Specification { + + def sdl = ''' + directive @timeout(afterMillis : Int) on FIELD + + directive @cached(forMillis : Int = 99) on FIELD | QUERY + + directive @upper(place : String) on FIELD + + directive @rep(place : String) repeatable on FIELD + + type Query { + f : String + } + ''' + + def schema = TestUtil.schema(sdl) + + def "can get immediate directives"() { + def f1 = TestUtil.parseField("f1 @cached @upper") + def f2 = TestUtil.parseField("f2 @cached(forMillis : \$var) @timeout") + + def mergedField = MergedField.newMergedField([f1, f2]).build() + + def impl = new QueryDirectivesImpl(mergedField, schema, + CoercedVariables.of([var: 10]), + { -> NormalizedVariables.of([var: new NormalizedInputValue("type", IntValue.of(10))]) }, + GraphQLContext.getDefault(), Locale.getDefault()) + + when: + def directives = impl.getImmediateDirectivesByName() + then: + directives.keySet().sort() == ["cached", "timeout", "upper"] + impl.getImmediateAppliedDirectivesByName().keySet().sort() == ["cached", "timeout", "upper"] + + when: + def result = impl.getImmediateDirective("cached") + def appliedResult = impl.getImmediateAppliedDirective("cached") + + then: + result.size() == 2 + result[0].getName() == "cached" + result[1].getName() == "cached" + + result[0].getArgument("forMillis").getArgumentValue().value == 99 // defaults. Retain deprecated method to test getImmediateDirective + printAst(result[0].getArgument("forMillis").getArgumentDefaultValue().getValue()) == "99" + + result[1].getArgument("forMillis").getArgumentValue().value == 10 // Retain deprecated method to test getImmediateDirective + printAst(result[1].getArgument("forMillis").getArgumentDefaultValue().getValue()) == "99" + + // the prototypical other properties are copied ok + result[0].validLocations().collect({ it.name() }).sort() == ["FIELD", "QUERY"] + result[1].validLocations().collect({ it.name() }).sort() == ["FIELD", "QUERY"] + + appliedResult.size() == 2 + appliedResult[0].getName() == "cached" + appliedResult[1].getName() == "cached" + + appliedResult[0].getArgument("forMillis").getValue() == 99 + appliedResult[1].getArgument("forMillis").getValue() == 10 + } + + def "builder works as expected"() { + def f1 = TestUtil.parseField("f1 @cached @upper") + def f2 = TestUtil.parseField("f2 @cached(forMillis : \$var) @timeout") + + def mergedField = MergedField.newMergedField([f1, f2]).build() + + def queryDirectives = QueryDirectives.newQueryDirectives() + .mergedField(mergedField) + .schema(schema) + .coercedVariables(CoercedVariables.of([var: 10])) + .normalizedVariables({ NormalizedVariables.of([var: new NormalizedInputValue("type", IntValue.of(10))]) }) + .graphQLContext(GraphQLContext.getDefault()) + .locale(Locale.getDefault()) + .build() + + when: + def appliedDirectivesByName = queryDirectives.getImmediateAppliedDirectivesByName() + + then: + appliedDirectivesByName.keySet().sort() == ["cached", "timeout", "upper"] + } + + def "gets repeated definitions"() { + def f1 = TestUtil.parseField("f1 @rep(place: \$var) @rep(place: \"HELLO\")") + + def mergedField = MergedField.newMergedField([f1]).build() + + def queryDirectives = QueryDirectives.newQueryDirectives() + .mergedField(mergedField) + .schema(schema) + .coercedVariables(CoercedVariables.of([var: "ABC"])) + .graphQLContext(GraphQLContext.getDefault()) + .locale(Locale.getDefault()) + .build() + + when: + def appliedDirectivesByName = queryDirectives.getImmediateAppliedDirectivesByName() + + then: + appliedDirectivesByName.keySet() == ["rep"] as Set + appliedDirectivesByName["rep"].size() == 2 + // Groovy is a pathway to many abilities some consider to be unnatural + appliedDirectivesByName["rep"].arguments.value.flatten().sort() == ["ABC", "HELLO"] + } +} diff --git a/src/test/groovy/graphql/execution/directives/QueryDirectivesIntegrationTest.groovy b/src/test/groovy/graphql/execution/directives/QueryDirectivesIntegrationTest.groovy new file mode 100644 index 0000000000..60c82e3b62 --- /dev/null +++ b/src/test/groovy/graphql/execution/directives/QueryDirectivesIntegrationTest.groovy @@ -0,0 +1,304 @@ +package graphql.execution.directives + +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.RawVariables +import graphql.language.IntValue +import graphql.normalized.ExecutableNormalizedOperationFactory +import graphql.normalized.NormalizedInputValue +import graphql.schema.DataFetcher +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLDirective +import graphql.schema.GraphQLSchema +import spock.lang.Specification + +/** + * This test currently has way more directives than can be handled today but in the spirit of TDD + * I am going to leave the parent node directives there so we can expand the directives capabilities + * into the future + */ +class QueryDirectivesIntegrationTest extends Specification { + + def sdl = ''' + directive @timeout(afterMillis : Int) on FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | QUERY + + directive @cached(forMillis : Int) on FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | QUERY + + directive @importance(place : String) on FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | QUERY + + type Query { + books(searchString : String) : [Book] + } + + type Book { + id : ID + title : String + review : String + } + ''' + + def pathologicalQuery = ''' + fragment Details on Book @timeout(afterMillis: 25) @cached(forMillis : 25) @importance(place:"FragDef") { + title + review @timeout(afterMillis: 5) @cached(forMillis : 5) + ...InnerDetails @timeout(afterMillis: 26) + } + + fragment InnerDetails on Book @timeout(afterMillis: 27) { + review @timeout(afterMillis: 28) + } + + query Books @timeout(afterMillis: 30) @importance(place:"Operation") { + books(searchString: "monkey") { + id + ...Details @timeout(afterMillis: 20) + ...on Book @timeout(afterMillis: 15) { + review @timeout(afterMillis: 10) @cached(forMillis : 10) + } + } + } + ''' + + Map capturedDirectives + + DataFetcher reviewDF = { env -> + capturedDirectives.put(env.getMergedField().getName(), env.getQueryDirectives()) + "review" + } + + DataFetcher titleDF = { env -> + capturedDirectives.put(env.getMergedField().getName(), env.getQueryDirectives()) + "title" + } + + def schema = TestUtil.schema(sdl, [Book: [review: reviewDF, title: titleDF]]) + + def graphql = GraphQL.newGraphQL(schema).build() + + def execute(String query) { + def root = [books: [[review: "Text"]]] + graphql.execute({ input -> input.query(query).root(root) }) + } + + static def joinArgs(List timeoutDirectives) { + timeoutDirectives.collect({ + def s = it.getName() + "(" + it.arguments.forEach({ + s += it.getName() + ":" + it.getArgumentValue().value + }) + s += ")" + s + }).join(",") + } + + void setup() { + capturedDirectives = [:] + } + + def "can collect directives as expected"() { + when: + def er = execute(pathologicalQuery) + then: + er.errors.isEmpty() + + def immediateMap = capturedDirectives["review"].getImmediateAppliedDirectivesByName() + def entries = immediateMap.entrySet().collectEntries({ + [(it.getKey()): joinArgs(it.getValue())] + }) + entries == [cached : "cached(forMillis:5),cached(forMillis:10)", + timeout: "timeout(afterMillis:5),timeout(afterMillis:28),timeout(afterMillis:10)" + ] + + def immediate = capturedDirectives["review"].getImmediateAppliedDirective("cached") + joinArgs(immediate) == "cached(forMillis:5),cached(forMillis:10)" + } + + def "can collect merged field directives as expected"() { + when: + def query = """ + query Books { + books(searchString: "monkey") { + review @timeout(afterMillis: 10) @cached(forMillis : 10) + review @timeout(afterMillis: 100) @cached(forMillis : 100) + } + } + + """ + def er = execute(query) + then: + er.errors.isEmpty() + + def immediateMap = capturedDirectives["review"].getImmediateAppliedDirectivesByName() + def entries = immediateMap.entrySet().collectEntries({ + [(it.getKey()): joinArgs(it.getValue())] + }) + entries == [cached : "cached(forMillis:10),cached(forMillis:100)", + timeout: "timeout(afterMillis:10),timeout(afterMillis:100)" + ] + + def immediate = capturedDirectives["review"].getImmediateAppliedDirective("cached") + joinArgs(immediate) == "cached(forMillis:10),cached(forMillis:100)" + + def immediate2 = capturedDirectives["review"].getImmediateAppliedDirective("timeout") + joinArgs(immediate2) == "timeout(afterMillis:10),timeout(afterMillis:100)" + } + + def "wont create directives for peer fields accidentally"() { + def query = '''query Books { + books(searchString: "monkey") { + id + ...on Book { + review @timeout(afterMillis: 10) @cached(forMillis : 10) + title @timeout(afterMillis: 99) @cached(forMillis : 99) + } + } + } +''' + when: + def er = execute(query) + then: + er.errors.isEmpty() + + def immediateMap = capturedDirectives["title"].getImmediateAppliedDirectivesByName() + def entries = immediateMap.entrySet().collectEntries({ + [(it.getKey()): joinArgs(it.getValue())] + }) + entries == [cached : "cached(forMillis:99)", + timeout: "timeout(afterMillis:99)" + ] + + def immediate = capturedDirectives["review"].getImmediateAppliedDirective("cached") + joinArgs(immediate) == "cached(forMillis:10)" + } + + def "can capture directive argument values inside ENO path"() { + def query = TestUtil.parseQuery(pathologicalQuery) + when: + def eno = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + schema, query, "Books", RawVariables.emptyVariables()) + + + then: + def booksENF = eno.getTopLevelFields()[0] + booksENF != null + def bookQueryDirectives = eno.getQueryDirectives(booksENF) + bookQueryDirectives.immediateAppliedDirectivesByName.isEmpty() + + def reviewField = eno.getCoordinatesToNormalizedFields().get(FieldCoordinates.coordinates("Book", "review")) + def reviewQueryDirectives = eno.getQueryDirectives(reviewField[0]) + def reviewImmediateDirectivesMap = reviewQueryDirectives.immediateAppliedDirectivesByName + def argInputValues = simplifiedInputValuesWithState(reviewImmediateDirectivesMap) + argInputValues == [ + timeout: [ + [timeout: [[afterMillis: 5]]], [timeout: [[afterMillis: 28]]], [timeout: [[afterMillis: 10]]] + ], + cached : [ + [cached: [[forMillis: 5]]], [cached: [[forMillis: 10]]] + ] + ] + + // normalised values are AST values + def normalizedValues = simplifiedNormalizedValues(reviewQueryDirectives.getNormalizedInputValueByImmediateAppliedDirectives()) + normalizedValues == [ + timeout: [ + [afterMillis: 5], [afterMillis: 28], [afterMillis: 10]], + cached : [ + [forMillis: 5], [forMillis: 10]] + ] + + } + + def "fragments used multiple times and directives on it"() { + String schema = """ + type Query { + foo: String + } + """ + QueryDirectives queryDirectives + def fooDF = { env -> + queryDirectives = env.getQueryDirectives() + return "Foo" + } as DataFetcher + + GraphQLSchema graphQLSchema = TestUtil.schema(schema, [Query: [foo: fooDF]]) + + String query = "{...F1 ...F1 } fragment F1 on Query { foo @include(if: true) } " + + def graphql = GraphQL.newGraphQL(graphQLSchema).build() + when: + def er = graphql.execute(query) + then: + er.data == [foo: "Foo"] + def byName = queryDirectives.getImmediateDirectivesByName(); + byName.size() == 1 + byName["include"].size() == 1 + byName["include"][0] instanceof GraphQLDirective + + + } + + def "fragments used multiple times and directives on it deeper"() { + String schema = """ + type Query { + foo: Foo + } + type Foo { + hello: String + } + """ + QueryDirectives queryDirectives + def fooDF = { env -> + return "Foo" + } as DataFetcher + + def helloDF = { env -> + queryDirectives = env.getQueryDirectives() + return "world" + } as DataFetcher + + GraphQLSchema graphQLSchema = TestUtil.schema(schema, [Query: [foo: fooDF], Foo: [hello: helloDF]]) + + String query = "{foo{...F1 ...F1 } } fragment F1 on Foo { hello @include(if: true) hello @include(if:true) } " + + def graphql = GraphQL.newGraphQL(graphQLSchema).build() + when: + def er = graphql.execute(query) + then: + er.data == [foo: [hello: "world"]] + def byName = queryDirectives.getImmediateDirectivesByName(); + byName.size() == 1 + byName["include"].size() == 2 + byName["include"][0] instanceof GraphQLDirective + byName["include"][1] instanceof GraphQLDirective + byName["include"][0] != byName["include"][1] + } + + + def simplifiedInputValuesWithState(Map> mapOfDirectives) { + def simpleMap = [:] + mapOfDirectives.forEach { k, listOfDirectives -> + + def dirVals = listOfDirectives.collect { qd -> + def argVals = qd.getArguments().collect { arg -> + def argValue = arg.getArgumentValue() + return [(arg.name): argValue?.value] + } + return [(qd.name): argVals] + } + simpleMap[k] = dirVals + } + return simpleMap + } + + def simplifiedNormalizedValues(Map> mapOfDirectives) { + Map>> simpleMap = new LinkedHashMap<>() + mapOfDirectives.forEach { qd, argMap -> + def argVals = argMap.collect { entry -> + def argValueAst = entry.value?.value as IntValue // just assume INtValue for these tests + return [(entry.key): argValueAst?.value?.toInteger()] + } + simpleMap.computeIfAbsent(qd.name, { _ -> [] }).addAll(argVals) + } + return simpleMap + } +} diff --git a/src/test/groovy/graphql/execution/directives/RepeatableDirectivesTest.groovy b/src/test/groovy/graphql/execution/directives/RepeatableDirectivesTest.groovy new file mode 100644 index 0000000000..8d6338a885 --- /dev/null +++ b/src/test/groovy/graphql/execution/directives/RepeatableDirectivesTest.groovy @@ -0,0 +1,126 @@ +package graphql.execution.directives + +import graphql.TestUtil +import graphql.language.Directive +import graphql.language.Field +import graphql.language.OperationDefinition +import graphql.language.StringValue +import graphql.schema.idl.MockedWiringFactory +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import graphql.validation.Validator +import spock.lang.Specification + +class RepeatableDirectivesTest extends Specification { + + def sdl = ''' + directive @repeatableDirective(arg: String) repeatable on FIELD + + directive @nonRepeatableDirective on FIELD + type Query { + namedField: String + } + ''' + + def schema = TestUtil.schema(sdl) + + + def "repeatableDirectives"() { + def spec = ''' + query { + f1: namedField @repeatableDirective @repeatableDirective + f2: namedField @repeatableDirective + f3: namedField @nonRepeatableDirective + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 0 + } + + def "nonRepeatableDirective"() { + + def spec = ''' + query { + namedField @nonRepeatableDirective @nonRepeatableDirective + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 1 + validationErrors[0].message == "Validation error (DuplicateDirectiveName@[namedField]) : Non repeatable directives must be uniquely named within a location. The directive 'nonRepeatableDirective' used on a 'Field' is not unique" + } + + def "getRepeatableDirectivesInfo"() { + + def spec = ''' + query { + namedField @repeatableDirective(arg: "value1") @repeatableDirective(arg: "value2") + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + OperationDefinition operationDefinition = document.getDefinitions()[0] + Field field = operationDefinition.getSelectionSet().getSelections()[0] + List directives = field.getDirectives() + + then: + validationErrors.size() == 0 + directives.size() == 2 + ((StringValue) directives[0].getArgument("arg").getValue()).getValue() == "value1" + ((StringValue) directives[1].getArgument("arg").getValue()).getValue() == "value2" + } + + def " ensure repeatable directive on extend type run correctly "() { + given: + def spec = ''' + directive @key(dirArg:String!) repeatable on OBJECT + type Query{ + field: String! + pTypedField(fieldArg: String!): PType + } + + type PType @key(dirArg:"a") @key(dirArg:"b") { + name: String + } + + extend type PType @key(dirArg:"c") { + extendField: String + } + ''' + + when: + SchemaParser parser = new SchemaParser() + def typeDefinitionRegistry = parser.parse(spec) + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(new MockedWiringFactory()) + .build() + def schemaGenerator = new SchemaGenerator() + def schema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring) + def pType = schema.getObjectType("PType") + + then: + pType.getExtensionDefinitions().size() == 1 + def extensionType = pType.getExtensionDefinitions().get(0) + extensionType.getDirectives().size() == 1 + extensionType.getDirectives("key") != null + extensionType.getFieldDefinitions().size() == 1 + extensionType.getFieldDefinitions().get(0).getName() == "extendField" + } + +} \ No newline at end of file diff --git a/src/test/groovy/graphql/execution/directives/VariableDirectiveTest.groovy b/src/test/groovy/graphql/execution/directives/VariableDirectiveTest.groovy new file mode 100644 index 0000000000..4d230b7a64 --- /dev/null +++ b/src/test/groovy/graphql/execution/directives/VariableDirectiveTest.groovy @@ -0,0 +1,107 @@ +package graphql.execution.directives + +import graphql.TestUtil +import graphql.language.Directive +import graphql.language.OperationDefinition +import graphql.language.StringValue +import graphql.language.VariableDefinition +import graphql.validation.Validator +import spock.lang.Specification + +class VariableDirectiveTest extends Specification { + + def sdl = ''' + directive @variableDirective(dirArg : String) on VARIABLE_DEFINITION + + directive @argumentDirective(dirArg : String) on ARGUMENT_DEFINITION + + type Query { + f(fieldArg: String) : String + f2: String + } + ''' + + def schema = TestUtil.schema(sdl) + + + def "valid variable directive"() { + def spec = ''' + query Foo($arg: String @variableDirective(dirArg : "directive_arg_value")){ + f(fieldArg: $arg) + f2 + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 0 + } + + def "invalid variable directive position"() { + + def spec = ''' + query Foo($arg: String){ + f(fieldArg: $arg) @variableDirective(dirArg : "directive_arg_value") + f2 + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 1 + validationErrors[0].message == "Validation error (MisplacedDirective@[f]) : Directive 'variableDirective' not allowed here" + } + + def "invalid directive for variable"() { + + def spec = ''' + query Foo($arg: String @argumentDirective(dirArg : "directive_arg_value")){ + f(fieldArg: $arg) + f2 + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 1 + validationErrors[0].message == "Validation error (MisplacedDirective) : Directive 'argumentDirective' not allowed here" + } + + + def "get variable directive information from parsed Document"() { + + def spec = ''' + query Foo($arg: String @variableDirective(dirArg : "directive_arg_value")){ + f(fieldArg: $arg) + f2 + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + + OperationDefinition operationDefinition = document.getDefinitions()[0] + VariableDefinition variableDefinition = operationDefinition.getVariableDefinitions()[0] + + List directives = variableDefinition.getDirectives() + + then: + directives.size() == 1 + directives[0].getName() == "variableDirective" + directives[0].getArguments().size() == 1 + ((StringValue) directives[0].getArgument("dirArg").getValue()).getValue() == "directive_arg_value" + } + +} diff --git a/src/test/groovy/graphql/execution/incremental/DeferExecutionSupportIntegrationTest.groovy b/src/test/groovy/graphql/execution/incremental/DeferExecutionSupportIntegrationTest.groovy new file mode 100644 index 0000000000..487caee669 --- /dev/null +++ b/src/test/groovy/graphql/execution/incremental/DeferExecutionSupportIntegrationTest.groovy @@ -0,0 +1,1920 @@ +package graphql.execution.incremental + +import com.google.common.collect.Iterables +import graphql.Directives +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.ExperimentalApi +import graphql.GraphQL +import graphql.GraphqlErrorBuilder +import graphql.GraphQLContext +import graphql.TestUtil +import graphql.execution.DataFetcherResult +import graphql.execution.pubsub.CapturingSubscriber +import graphql.incremental.DelayedIncrementalPartialResult +import graphql.incremental.IncrementalExecutionResult +import graphql.incremental.IncrementalExecutionResultImpl +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.TypeResolver +import graphql.schema.idl.RuntimeWiring +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import org.reactivestreams.Publisher +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicInteger + +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class DeferExecutionSupportIntegrationTest extends Specification { + def schemaSpec = ''' + type Query { + post : Post + posts: [Post] + postById(id: ID!): Post + hello: String + item(type: String!): Item + } + + interface Item { + id: ID! + summary: String + text: String + } + + type Page implements Item { + id: ID! + summary: String + text: String + views: Int + } + + type Post implements Item { + id: ID! + summary : String + text : String + latestComment: Comment + comments: [Comment] + resolvesToNull: String + dataFetcherError: String + dataAndError: String + coercionError: Int + typeMismatchError: [String] + nonNullableError: String! + wordCount: Int + fieldWithDataLoader1: String + fieldWithDataLoader2: String + } + + type Comment { + title: String + content: String + author: Person + } + + type Person { + name: String + avatar: String + } + + type Mutation { + addPost: Post + } + ''' + + GraphQL graphQL = null + + private static DataFetcher resolve(Object value) { + return resolve(value, 0, false) + } + + private static DataFetcher resolve(Object value, Integer sleepMs) { + return resolve(value, sleepMs, false) + } + + private static DataFetcher fieldWithDataLoader(String key) { + return (dfe) -> { + def dataLoader = dfe.getDataLoader("someDataLoader") + return dataLoader.load(dfe.getSource().id + "-" + key) + }; + } + + private static DataFetcher resolve(Object value, Integer sleepMs, boolean allowMultipleCalls) { + return new DataFetcher() { + boolean executed = false + + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + if (executed && !allowMultipleCalls) { + throw new IllegalStateException("This data fetcher can run only once") + } + executed = true + return CompletableFuture.supplyAsync { + Thread.sleep(sleepMs) + return value + } + } + } + } + + private static DataFetcher resolveItem() { + return (env) -> { + def type = env.getArgument("type") + + return CompletableFuture.supplyAsync { [__typename: type, id: "1001"] } + } + } + + private static TypeResolver itemTypeResolver() { + return (env) -> { + env.getSchema().getObjectType(env.object["__typename"]) + } + } + + private static DataFetcher resolveWithException() { + return new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + throw new RuntimeException("Bang!!!") + } + } + } + + private static DataFetcher resolveWithDataAndError(Object data) { + return new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return DataFetcherResult.newResult() + .data(data) + .error( + GraphqlErrorBuilder.newError() + .message("Bang!") + .build() + ) + .build() + } + } + } + + void setup() { + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("post", resolve([id: "1001"])) + .dataFetcher("posts", resolve([ + [id: "1001"], + [id: "1002"], + [id: "1003"] + ])) + .dataFetcher("postById", (env) -> { + return [id: env.getArgument("id")] + }) + .dataFetcher("hello", resolve("world")) + .dataFetcher("item", resolveItem()) + ) + .type(newTypeWiring("Post").dataFetcher("summary", resolve("A summary", 10))) + .type(newTypeWiring("Post").dataFetcher("fieldWithDataLoader1", fieldWithDataLoader("fieldWithDataLoader1"))) + .type(newTypeWiring("Post").dataFetcher("fieldWithDataLoader2", fieldWithDataLoader("fieldWithDataLoader2"))) + .type(newTypeWiring("Post").dataFetcher("text", resolve("The full text", 100))) + .type(newTypeWiring("Post").dataFetcher("wordCount", resolve(45999, 10, true))) + .type(newTypeWiring("Post").dataFetcher("latestComment", resolve([title: "Comment title"], 10))) + .type(newTypeWiring("Post").dataFetcher("dataFetcherError", resolveWithException())) + .type(newTypeWiring("Post").dataFetcher("dataAndError", resolveWithDataAndError("data"))) + .type(newTypeWiring("Post").dataFetcher("coercionError", resolve("Not a number", 10))) + .type(newTypeWiring("Post").dataFetcher("typeMismatchError", resolve([a: "A Map instead of a List"], 10))) + .type(newTypeWiring("Post").dataFetcher("nonNullableError", resolve(null))) + .type(newTypeWiring("Page").dataFetcher("summary", resolve("A page summary", 10))) + .type(newTypeWiring("Page").dataFetcher("text", resolve("The page full text", 100))) + .type(newTypeWiring("Comment").dataFetcher("content", resolve("Full content", 100))) + .type(newTypeWiring("Comment").dataFetcher("author", resolve([name: "Author name"], 10))) + .type(newTypeWiring("Person").dataFetcher("avatar", resolve("Avatar image", 100))) + .type(newTypeWiring("Mutation") + .dataFetcher("addPost", resolve([id: "1001"])) + ) + .type(newTypeWiring("Item") + .typeResolver(itemTypeResolver())) + .build() + + def schema = TestUtil.schema(schemaSpec, runtimeWiring) + .transform({ builder -> builder.additionalDirective(Directives.DeferDirective) }) + this.graphQL = GraphQL.newGraphQL(schema).build() + } + + def "simple defer"() { + def query = ''' + query { + post { + id + ... @defer { + summary + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ] + ] + } + + def "defer with aliased fields"() { + def query = ''' + query { + postAlias: post { + idAlias: id + ... @defer { + summaryAlias: summary + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [postAlias: [idAlias: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["postAlias"], + data: [summaryAlias: "A summary"] + ] + ] + ] + ] + } + + def "aliased fields with different parameters"() { + def query = ''' + query { + postById(id: "1") { + id + } + ... @defer { + post2: postById(id: "2") { + id2: id + } + } + ... @defer(label: "defer-post3") { + post3: postById(id: "3") { + ... @defer(label: "defer-id3") { + id3: id + } + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [postById: [id: "1"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + // Ordering is non-deterministic, so we assert on the things we know are going to be true. + + incrementalResults.size() == 3 + // only the last payload has "hasNext=true" + incrementalResults[0].hasNext == true + incrementalResults[1].hasNext == true + incrementalResults[2].hasNext == false + + // every payload has only 1 incremental item + incrementalResults.every { it.incremental.size() == 1 } + + incrementalResults.any { + it.incremental[0] == [path: [], data: [post2: [id2: "2"]]] + } + + // id3 HAS TO be delivered after post3 + def indexOfPost3 = Iterables.indexOf(incrementalResults, { + it.incremental[0] == [path: [], label: "defer-post3", data: [post3: [:]]] + }) + + def indexOfId3 = Iterables.indexOf(incrementalResults, { + it.incremental[0] == [path: ["post3"], label: "defer-id3", data: [id3: "3"]] + }) + + // Assert that both post3 and id3 are present + indexOfPost3 >= 0 + indexOfId3 >= 0 + // Assert that id3 is delivered after post3 + indexOfId3 > indexOfPost3 + } + + def "defer on interface field"() { + def query = """ + query { + item(type: "$type") { + __typename + id + ... on Item @defer { + summary + } + + ... on Post { + text + } + + ... on Page @defer { + text + } + } + } + """ + + when: + def initialResult = executeQuery(query) + + then: + if (type == "Post") { + assert initialResult.toSpecification() == [ + data : [item: [__typename: "Post", id: "1001", text: "The full text"]], + hasNext: true + ] + } else { + assert initialResult.toSpecification() == [ + data : [item: [__typename: "Page", id: "1001"]], + hasNext: true + ] + } + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + if (type == "Post") { + assert incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["item"], + data: [summary: "A summary"] + ] + ] + ] + ] + } else { + assert incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path: ["item"], + data: [summary: "A page summary"] + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["item"], + data: [text: "The page full text"] + ] + ] + ] + ] + } + + where: + type << ["Page", "Post"] + } + + def "defer execution is ignored if support for incremental delivery is disabled"() { + def query = ''' + query { + post { + id + ... @defer { + summary + } + } + } + ''' + + when: + ExecutionResult initialResult = executeQuery(query, false, [:]) + + then: + !(initialResult instanceof IncrementalExecutionResult) + + initialResult.toSpecification() == [ + data: [post: [id: "1001", summary: "A summary"]], + ] + + } + + def "simple defer with label"() { + def query = ''' + query { + post { + id + ... @defer(label: "summary-defer") { + summary + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path : ["post"], + label: "summary-defer", + data : [summary: "A summary"] + ] + ] + ] + ] + } + + def "defer with null label should behave as if no label was provided"() { + def query = ''' + query { + post { + id + ... @defer(label: null) { + summary + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ] + ] + } + + def "deferred field results in 'null'"() { + def query = ''' + query { + post { + id + ... @defer { + resolvesToNull + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [resolvesToNull: null] + ] + ] + ] + ] + } + + def "simple defer with fragment definition"() { + def query = ''' + query { + post { + id + ... PostData @defer + } + } + + fragment PostData on Post { + summary + text + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary", text: "The full text"] + ] + ] + ] + ] + } + + @Unroll + def "defer with 'if: #ifValue' "() { + def query = """ + query { + post { + id + ... @defer(if: $ifValue) { + summary + } + } + } + """ + + when: + ExecutionResult executionResult = executeQuery(query) + + then: + if (ifValue) { + assert executionResult instanceof IncrementalExecutionResultImpl + + assert executionResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + def incrementalResults = getIncrementalResults(executionResult) + + assert incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ] + ] + } else { + assert !(executionResult instanceof IncrementalExecutionResult) + + assert executionResult.toSpecification() == [ + data: [post: [id: "1001", summary: "A summary"]], + ] + } + + where: + ifValue << [true, false] + } + + @Unroll + def "defer with 'if: #ifValue' passed as variable "() { + def query = """ + query(\$ifVar: Boolean!) { + post { + id + ... @defer(if: \$ifVar) { + summary + } + } + } + """ + + when: + ExecutionResult executionResult = executeQuery(query, [ifVar: ifValue]) + + then: + if (ifValue) { + assert executionResult instanceof IncrementalExecutionResultImpl + + assert executionResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + def incrementalResults = getIncrementalResults(executionResult) + + assert incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ] + ] + } else { + assert !(executionResult instanceof IncrementalExecutionResult) + + assert executionResult.toSpecification() == [ + data: [post: [id: "1001", summary: "A summary"]], + ] + } + + where: + ifValue << [true, false] + } + + def "2 fields deferred together"() { + def query = ''' + query { + post { + id + ... @defer { + summary + text + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary", text: "The full text"] + ] + ] + ] + ] + } + + def "2 fields deferred independently"() { + def query = ''' + query { + post { + id + ... @defer(label: "summary-defer") { + summary + } + ... @defer(label: "text-defer") { + text + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + label: "summary-defer", + path : ["post"], + data : [summary: "A summary"] + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + label: "text-defer", + path : ["post"], + data : [text: "The full text"] + ] + ] + ] + ] + } + + def "order of @defer definition in query doesn't affect order of incremental payloads in response"() { + def query = ''' + query { + post { + id + # "text" is defined before "summary" in the query, but it's slower, so it will be delivered after. + ... @defer { + text + } + ... @defer { + summary + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"] + ] + ] + ] + ] + } + + def "keeps the fields named correctly when interspersed in the query"() { + def query = ''' + query { + post { + firstId: id + ... @defer { + text + } + secondId: id + ... @defer { + summary + } + thirdId: id + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [firstId: "1001", secondId: "1001", thirdId: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"] + ] + ] + ] + ] + } + + def "defer result in initial result being empty object"() { + def query = ''' + query { + post { + ... @defer { + summary + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [:]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"] + ] + ] + ] + ] + } + + def "defer on top level field"() { + def query = ''' + query { + hello + ... @defer { + post { + id + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [hello: "world"], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: [], + data: [post: [id: "1001"]] + ] + ] + ] + ] + } + + def "nested defers"() { + def query = ''' + query { + ... @defer { + post { + id + ... @defer { + summary + latestComment { + title + ... @defer { + content + } + } + } + } + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [:], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path: [], + data: [post: [id: "1001"]] + ] + ] + ], + [ + hasNext : true, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary", latestComment: [title: "Comment title"]] + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post", "latestComment"], + data: [content: "Full content"] + ] + ] + ] + ] + } + + def "multiple defers on same field"() { + + def query = ''' + query { + post { + ... @defer { + summary + } + ... @defer(label: "defer-outer") { + summary + ... @defer(label: "defer-inner") { + summary + } + } + } + } + ''' + + when: + + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [:]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + // Ordering is non-deterministic, so we assert on the things we know are going to be true. + + incrementalResults.size() == 3 + // only the last payload has "hasNext=true" + incrementalResults[0].hasNext == true + incrementalResults[1].hasNext == true + incrementalResults[2].hasNext == false + + // every payload has only 1 incremental item, and the data is the same for all of them + incrementalResults.every { it.incremental.size() == 1 } + incrementalResults.every { it.incremental[0].data == [summary: "A summary"] } + + // "label" is different for every payload + incrementalResults.any { it.incremental[0].label == null } + incrementalResults.any { it.incremental[0].label == "defer-inner" } + incrementalResults.any { it.incremental[0].label == "defer-outer" } + } + + def "mutations can have defers"() { + def query = ''' + mutation { + addPost { + firstId: id + ... @defer { + text + } + secondId: id + ... @defer { + summary + } + thirdId: id + } + } + ''' + + when: + IncrementalExecutionResult initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [addPost: [firstId: "1001", secondId: "1001", thirdId: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path: ["addPost"], + data: [summary: "A summary"] + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["addPost"], + data: [text: "The full text"] + ] + ] + ] + ] + } + + def "can handle error raised by data fetcher"() { + def query = ''' + query { + post { + id + ... @defer { + dataFetcherError + } + ... @defer { + text + } + } + } + ''' + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path : ["post"], + data : [dataFetcherError: null], + errors: [[ + message : "Exception while fetching data (/post/dataFetcherError) : Bang!!!", + locations : [[line: 6, column: 25]], + path : ["post", "dataFetcherError"], + extensions: [classification: "DataFetchingException"] + ]], + ], + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"], + ] + ] + ] + ] + } + + def "can handle data fetcher that returns both data and error on nested field"() { + def query = ''' + query { + hello + ... @defer { + post { + dataAndError + } + } + } + ''' + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [hello: "world"], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path : [], + data : [post: [dataAndError: "data"]], + errors: [[ + message : "Bang!", + locations : [], + extensions: [classification: "DataFetchingException"] + ]], + ], + ] + ], + ] + } + + def "can handle data fetcher that returns both data and error"() { + def query = ''' + query { + post { + id + ... @defer { + dataAndError + } + ... @defer { + text + } + } + } + ''' + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path : ["post"], + data : [dataAndError: "data"], + errors: [[ + message : "Bang!", + locations : [], + extensions: [classification: "DataFetchingException"] + ]], + ], + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"], + ] + ] + ] + ] + } + + def "can handle UnresolvedTypeException"() { + def query = """ + query { + post { + id + ... @defer { + text + } + } + ... @defer { + item(type: "NonExistingType") { + id + summary + } + } + } + """ + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path : [], + data : [item: null], + errors: [ + [ + message : "Can't resolve '/item'. Abstract type 'Item' must resolve to an Object type at runtime for field 'Query.item'. Could not determine the exact type of 'Item'", + path : ["item"], + extensions: [ + classification: "DataFetchingException" + ] + ] + ], + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"], + ] + ] + ] + ] + } + + def "can handle coercion problem"() { + def query = """ + query { + post { + id + ... @defer { + text + } + ... @defer { + coercionError + } + } + } + """ + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path : ["post"], + data : [coercionError: null], + errors: [ + [ + message : "Can't serialize value (/post/coercionError) : Expected a value that can be converted to type 'Int' but it was a 'String'", + path : ["post", "coercionError"], + extensions: [ + classification: "DataFetchingException" + ] + ] + ], + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"], + ] + ] + ] + ] + } + + def "can handle type mismatch problem"() { + def query = """ + query { + post { + id + ... @defer { + text + } + ... @defer { + typeMismatchError + } + } + } + """ + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + path : ["post"], + data : [typeMismatchError: null], + errors: [ + [ + message : "Can't resolve value (/post/typeMismatchError) : type mismatch error, expected type LIST", + path : ["post", "typeMismatchError"], + extensions: [ + classification: "DataFetchingException" + ] + ] + ], + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"], + ] + ] + ] + ] + } + + def "can handle non nullable error in one of the defer calls"() { + def query = """ + query { + post { + id + ... @defer { + text + } + ... @defer { + summary + nonNullableError + } + } + } + """ + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : true, + incremental: [ + [ + data : null, + path : ["post"], + errors: [ + [ + message : "The field at path '/post/nonNullableError' was declared as a non null type, but the code involved in retrieving data has wrongly returned a null value. The graphql specification requires that the parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on. The non-nullable type is 'String' within parent type 'Post'", + path : ["post", "nonNullableError"], + extensions: [ + classification: "NullValueInNonNullableField" + ] + ] + ], + ] + ] + ], + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [text: "The full text"], + ] + ] + ] + ] + } + + def "can handle non nullable error in the initial result"() { + def query = """ + query { + post { + id + nonNullableError + ... @defer { + summary + } + } + } + """ + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: null], + errors : [ + [message : "The field at path '/post/nonNullableError' was declared as a non null type, but the code involved in retrieving data has wrongly returned a null value. The graphql specification requires that the parent field be set to null, or if that is non nullable that it bubble up null to its parent and so on. The non-nullable type is 'String' within parent type 'Post'", + path : ["post", "nonNullableError"], + extensions: [classification: "NullValueInNonNullableField"] + ] + ], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: ["post"], + data: [summary: "A summary"], + ] + ] + ] + ] + } + + def "defer on list items"() { + def query = ''' + query { + posts { + id + ... @defer { + wordCount + } + } + } + ''' + + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [posts: [[id: "1001"], [id: "1002"], [id: "1003"]]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + // Ordering is non-deterministic, so we assert on the things we know are going to be true. + + incrementalResults.size() == 3 + // only the last payload has "hasNext=true" + incrementalResults[0].hasNext == true + incrementalResults[1].hasNext == true + incrementalResults[2].hasNext == false + + // every payload has only 1 incremental item, and the data is the same for all of them + incrementalResults.every { it.incremental.size() == 1 } + incrementalResults.every { it.incremental[0].data == [wordCount: 45999] } + + // path is different for every payload + incrementalResults.any { it.incremental[0].path == ["posts", 0] } + incrementalResults.any { it.incremental[0].path == ["posts", 1] } + incrementalResults.any { it.incremental[0].path == ["posts", 2] } + } + + + def "two fragments one with defer and one without"() { + given: + def query = ''' + query { + post { + text + ...f1 @defer + ...f2 + } + } + + fragment f1 on Post { + summary + } + fragment f2 on Post { + summary + } + ''' + when: + def result = executeQuery(query) + + then: + result.toSpecification() == [ + data: [post: [summary: "A summary", text: "The full text"]] + ] + !(result instanceof IncrementalExecutionResult) + + + } + + def "two fragments one same type"() { + given: + def query = ''' + query { + post { + id + ...f1 + ...f2 @defer + } + } + + fragment f1 on Post { + text + } + fragment f2 on Post { + summary + } + ''' + when: + def initialResult = executeQuery(query) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001", text: "The full text"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + + incrementalResults.size() == 1 + incrementalResults[0] == [incremental: [[path: ["post"], data: [summary: "A summary"]]], + hasNext : false + ] + + } + + def "dataloader used inside defer"() { + given: + def query = ''' + query { + post { + id + ...@defer { + fieldWithDataLoader1 + fieldWithDataLoader2 + } + } + } + ''' + + def batchLoaderCallCount = new AtomicInteger(0) + when: + def initialResult = executeQuery(query, true, [:], batchLoaderCallCount) + + then: + initialResult.toSpecification() == [ + data : [post: [id: "1001"]], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + batchLoaderCallCount.get() == 1 + incrementalResults.size() == 1 + incrementalResults[0] == [incremental: [[path: ["post"], data: [fieldWithDataLoader1: "1001-fieldWithDataLoader1", fieldWithDataLoader2: "1001-fieldWithDataLoader2"]]], + hasNext : false + ] + + } + + def "eager defer starts before initial result completes when ENABLE_EAGER_DEFER_START"() { + given: + def deferStarted = new CountDownLatch(1) + def allowDeferredComplete = new CountDownLatch(1) + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("post", resolve([id: "1001"])) + ) + .type(newTypeWiring("Query").dataFetcher("hello", resolve("world", 4000))) + .type(newTypeWiring("Post").dataFetcher("summary", { env -> + deferStarted.countDown() + allowDeferredComplete.await(2, TimeUnit.SECONDS) + CompletableFuture.completedFuture("A summary") + } as DataFetcher)) + .type(newTypeWiring("Item").typeResolver(itemTypeResolver())) + .build() + + def schema = TestUtil.schema(schemaSpec, runtimeWiring) + .transform({ b -> b.additionalDirective(Directives.DeferDirective) }) + def testGraphQL = GraphQL.newGraphQL(schema).build() + + def ctx = GraphQLContext.newContext().build() + ctx.put(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT, true) + ctx.put(IncrementalExecutionContextKeys.ENABLE_EAGER_DEFER_START, true) + + def query = ''' + query { + hello + ... @defer { post { summary } } + } + ''' + + when: + def executionInput = ExecutionInput.newExecutionInput() + .graphQLContext([(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT): true, (IncrementalExecutionContextKeys.ENABLE_EAGER_DEFER_START): true]) + .query(query) + .build() + def execFuture = CompletableFuture.supplyAsync { + testGraphQL.execute(executionInput) + } + + then: + // Deferred fetcher starts while initial result is still computing + assert deferStarted.await(2000, TimeUnit.MILLISECONDS) + assert !execFuture.isDone() + + when: + allowDeferredComplete.countDown() + def initialResult = execFuture.join() as IncrementalExecutionResult + + then: + assert initialResult.toSpecification() == [ + data : [hello: "world"], + hasNext: true + ] + + when: + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: [], + data: [post: [summary: "A summary"]] + ] + ] + ] + ] + } + + + def "incremental starts only after initial result when eager start disabled"() { + given: + def deferStarted = new CountDownLatch(1) + def allowDeferredComplete = new CountDownLatch(1) + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("post", resolve([id: "1001"])) + ) + .type(newTypeWiring("Query").dataFetcher("hello", resolve("world", 300))) + .type(newTypeWiring("Post").dataFetcher("summary", { env -> + deferStarted.countDown() + allowDeferredComplete.await(2, TimeUnit.SECONDS) + CompletableFuture.completedFuture("A summary") + } as DataFetcher)) + .type(newTypeWiring("Item").typeResolver(itemTypeResolver())) + .build() + + def schema = TestUtil.schema(schemaSpec, runtimeWiring) + .transform({ b -> b.additionalDirective(Directives.DeferDirective) }) + def testGraphQL = GraphQL.newGraphQL(schema).build() + + def query = ''' + query { + hello + ... @defer { post { summary } } + } + ''' + + when: + def executionInput = ExecutionInput.newExecutionInput() + .graphQLContext([(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT): true]) // no eager flag + .query(query) + .build() + def execFuture = CompletableFuture.supplyAsync { + testGraphQL.execute(executionInput) + } + + then: + assert !deferStarted.await(100, TimeUnit.MILLISECONDS) + assert !execFuture.isDone() + + when: + def initialResult = execFuture.join() as IncrementalExecutionResult + + then: + assert initialResult.toSpecification() == [ + data : [hello: "world"], + hasNext: true + ] + assert deferStarted.count == 1 // still not started, no subscriber yet + + when: + allowDeferredComplete.countDown() + def incrementalResults = getIncrementalResults(initialResult) + + then: + incrementalResults == [ + [ + hasNext : false, + incremental: [ + [ + path: [], + data: [post: [summary: "A summary"]] + ] + ] + ] + ] + } + + + private ExecutionResult executeQuery(String query) { + return this.executeQuery(query, true, [:]) + } + + private ExecutionResult executeQuery(String query, Map variables) { + return this.executeQuery(query, true, variables) + } + + private ExecutionResult executeQuery(String query, boolean incrementalSupport, Map variables, AtomicInteger batchLoaderCallCount = null) { + BatchLoader batchLoader = { keys -> + if (batchLoaderCallCount != null) { + batchLoaderCallCount.incrementAndGet() + } + return CompletableFuture.completedFuture(keys) + } + DataLoader dl = DataLoaderFactory.newDataLoader(batchLoader) + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); + dataLoaderRegistry.register("someDataLoader", dl) + return graphQL.execute( + ExecutionInput.newExecutionInput() + .graphQLContext([(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .query(query) + .variables(variables) + .dataLoaderRegistry(dataLoaderRegistry) + .build() + ) + } + + private static List> getIncrementalResults(IncrementalExecutionResult initialResult) { + Publisher deferredResultStream = initialResult.incrementalItemPublisher + + def subscriber = new CapturingSubscriber() + + deferredResultStream.subscribe(subscriber) + + Awaitility.await().untilTrue(subscriber.isDone()) + if (subscriber.throwable != null) { + throw new RuntimeException(subscriber.throwable) + } + return subscriber.getEvents() + .collect { it.toSpecification() } + } +} diff --git a/src/test/groovy/graphql/execution/incremental/DeferredCallTest.groovy b/src/test/groovy/graphql/execution/incremental/DeferredCallTest.groovy new file mode 100644 index 0000000000..d8a011b8c4 --- /dev/null +++ b/src/test/groovy/graphql/execution/incremental/DeferredCallTest.groovy @@ -0,0 +1,119 @@ +package graphql.execution.incremental + +import graphql.ExecutionResultImpl +import graphql.GraphQLError +import graphql.execution.NonNullableFieldWasNullException +import graphql.execution.ResultPath +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture +import java.util.function.Supplier + +import static graphql.execution.ResultPath.parse +import static java.util.concurrent.CompletableFuture.completedFuture + +class DeferredCallTest extends Specification { + + def "test call capture gives a CF"() { + given: + DeferredFragmentCall call = new DeferredFragmentCall("my-label", parse("/path"), + [createResolvedFieldCall("field", "some data")], new AlternativeCallContext()) + + when: + def future = call.invoke() + then: + future.join().toSpecification() == [ + label: "my-label", + path : ["path"], + data : [field: "some data"] + ] + } + + def "multiple field calls are resolved together"() { + given: + DeferredFragmentCall call = new DeferredFragmentCall("my-label", parse("/path"), + [ + createResolvedFieldCall("field1", "some data 1"), + createResolvedFieldCall("field2", "some data 2"), + createResolvedFieldCall("field3", "some data 3") + ], + new AlternativeCallContext() + ) + + when: + def future = call.invoke() + then: + future.join().toSpecification() == [ + label: "my-label", + path : ["path"], + data : [field1: "some data 1", field2: "some data 2", field3: "some data 3"] + ] + } + + def "can handle non-nullable field error"() { + given: + def deferredCallContext = new AlternativeCallContext() + def mockedException = Mock(NonNullableFieldWasNullException) { + getMessage() >> "Field value can't be null" + getPath() >> ResultPath.parse("/path") + } + + DeferredFragmentCall call = new DeferredFragmentCall("my-label", parse("/path"), [ + createFieldCallThatThrowsException(mockedException), + createResolvedFieldCall("field1", "some data") + ], deferredCallContext) + + when: + def future = call.invoke() + def deferPayload = future.join() + + then: + deferPayload.toSpecification() == [ + data : null, + path : ["path"], + label : "my-label", + errors: [ + [ + message : "Field value can't be null", + path : ["path"], + extensions: [classification: "NullValueInNonNullableField"] + ] + ], + ] + } + + private static Supplier> createResolvedFieldCall( + String fieldName, + Object data + ) { + return createResolvedFieldCall(fieldName, data, Collections.emptyList()) + } + + private static Supplier> createResolvedFieldCall( + String fieldName, + Object data, + List errors + ) { + return new Supplier>() { + @Override + CompletableFuture get() { + return completedFuture( + new DeferredFragmentCall.FieldWithExecutionResult(fieldName, + new ExecutionResultImpl(data, errors) + ) + ) + } + } + } + + private static Supplier> createFieldCallThatThrowsException( + Throwable exception + ) { + return new Supplier>() { + @Override + CompletableFuture get() { + return CompletableFuture.failedFuture(exception) + } + } + } +} diff --git a/src/test/groovy/graphql/execution/incremental/IncrementalCallStateDeferTest.groovy b/src/test/groovy/graphql/execution/incremental/IncrementalCallStateDeferTest.groovy new file mode 100644 index 0000000000..db9085274f --- /dev/null +++ b/src/test/groovy/graphql/execution/incremental/IncrementalCallStateDeferTest.groovy @@ -0,0 +1,337 @@ +package graphql.execution.incremental + + +import graphql.ExecutionResultImpl +import graphql.execution.ResultPath +import graphql.execution.pubsub.CapturingSubscriber +import graphql.incremental.DelayedIncrementalPartialResult +import org.awaitility.Awaitility +import org.reactivestreams.Publisher +import spock.lang.Specification + +import java.util.concurrent.Callable +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executors +import java.util.concurrent.ThreadFactory +import java.util.function.Supplier + +class IncrementalCallStateDeferTest extends Specification { + + def "emits N deferred calls - ordering depends on call latency"() { + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread("A", 100, "/field/path")) // <-- will finish last + incrementalCallState.enqueue(offThread("B", 50, "/field/path")) // <-- will finish second + incrementalCallState.enqueue(offThread("C", 10, "/field/path")) // <-- will finish first + + when: + List results = startAndWaitCalls(incrementalCallState) + + then: + assertResultsSizeAndHasNextRule(3, results) + results[0].incremental[0].data["c"] == "C" + results[1].incremental[0].data["b"] == "B" + results[2].incremental[0].data["a"] == "A" + } + + def "calls within calls are enqueued correctly"() { + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThreadCallWithinCall(incrementalCallState, "A", "A_Child", 500, "/a")) + incrementalCallState.enqueue(offThreadCallWithinCall(incrementalCallState, "B", "B_Child", 300, "/b")) + incrementalCallState.enqueue(offThreadCallWithinCall(incrementalCallState, "C", "C_Child", 100, "/c")) + + when: + List results = startAndWaitCalls(incrementalCallState) + + then: + assertResultsSizeAndHasNextRule(6, results) + results[0].incremental[0].data["c"] == "C" + results[1].incremental[0].data["c_child"] == "C_Child" + results[2].incremental[0].data["b"] == "B" + results[3].incremental[0].data["a"] == "A" + results[4].incremental[0].data["b_child"] == "B_Child" + results[5].incremental[0].data["a_child"] == "A_Child" + } + + def "stops at first exception encountered"() { + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread("A", 100, "/field/path")) + incrementalCallState.enqueue(offThread("Bang", 50, "/field/path")) // <-- will throw exception + incrementalCallState.enqueue(offThread("C", 10, "/field/path")) + + when: + def subscriber = new CapturingSubscriber() { + @Override + void onComplete() { + assert false, "This should not be called!" + } + } + incrementalCallState.startDeferredCalls().subscribe(subscriber) + + Awaitility.await().untilTrue(subscriber.isDone()) + + def results = subscriber.getEvents() + def thrown = subscriber.getThrowable() + + then: + thrown.message == "java.lang.RuntimeException: Bang" + results[0].incremental[0].data["c"] == "C" + } + + def "you can cancel the subscription"() { + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread("A", 100, "/field/path")) // <-- will finish last + incrementalCallState.enqueue(offThread("B", 50, "/field/path")) // <-- will finish second + incrementalCallState.enqueue(offThread("C", 10, "/field/path")) // <-- will finish first + + when: + def subscriber = new CapturingSubscriber() { + @Override + void onNext(DelayedIncrementalPartialResult executionResult) { + this.getEvents().add(executionResult) + subscription.cancel() + this.isDone().set(true) + } + } + incrementalCallState.startDeferredCalls().subscribe(subscriber) + + Awaitility.await().untilTrue(subscriber.isDone()) + def results = subscriber.getEvents() + + then: + results.size() == 1 + results[0].incremental[0].data["c"] == "C" + // Cancelling the subscription will result in an invalid state. + // The last result item will have "hasNext=true" (but there will be no next) + results[0].hasNext + } + + def "you can't subscribe twice"() { + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread("A", 100, "/field/path")) + incrementalCallState.enqueue(offThread("Bang", 50, "/field/path")) // <-- will finish second + incrementalCallState.enqueue(offThread("C", 10, "/field/path")) // <-- will finish first + + when: + def subscriber1 = new CapturingSubscriber() + def subscriber2 = new CapturingSubscriber() + incrementalCallState.startDeferredCalls().subscribe(subscriber1) + incrementalCallState.startDeferredCalls().subscribe(subscriber2) + + then: + subscriber2.throwable != null + subscriber2.throwable.message == "This publisher only supports one subscriber" + } + + def "indicates if there are any defers present"() { + given: + def incrementalCallState = new IncrementalCallState() + + when: + def deferPresent1 = incrementalCallState.getIncrementalCallsDetected() + + then: + !deferPresent1 + + when: + incrementalCallState.enqueue(offThread("A", 100, "/field/path")) + def deferPresent2 = incrementalCallState.getIncrementalCallsDetected() + + then: + deferPresent2 + } + + def "multiple fields are part of the same call"() { + given: "a DeferredCall that contains resolution of multiple fields" + def call1 = new Supplier>() { + @Override + CompletableFuture get() { + return CompletableFuture.supplyAsync({ + Thread.sleep(10) + new DeferredFragmentCall.FieldWithExecutionResult("call1", new ExecutionResultImpl("Call 1", [])) + }) + } + } + + def call2 = new Supplier>() { + @Override + CompletableFuture get() { + return CompletableFuture.supplyAsync({ + Thread.sleep(100) + new DeferredFragmentCall.FieldWithExecutionResult("call2", new ExecutionResultImpl("Call 2", [])) + }) + } + } + + def deferredCall = new DeferredFragmentCall(null, ResultPath.parse("/field/path"), [call1, call2], new AlternativeCallContext()) + + when: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(deferredCall) + + def results = startAndWaitCalls(incrementalCallState) + + then: + assertResultsSizeAndHasNextRule(1, results) + results[0].incremental[0].data["call1"] == "Call 1" + results[0].incremental[0].data["call2"] == "Call 2" + } + + def "race conditions should not impact the calculation of the hasNext value"() { + given: "calls that have the same sleepTime" + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread("A", 10, "/field/path")) // <-- will finish last + incrementalCallState.enqueue(offThread("B", 10, "/field/path")) // <-- will finish second + incrementalCallState.enqueue(offThread("C", 10, "/field/path")) // <-- will finish first + + when: + List results = startAndWaitCalls(incrementalCallState) + + then: "hasNext placement should be deterministic - only the last event published should have 'hasNext=true'" + assertResultsSizeAndHasNextRule(3, results) + + then: "but the actual order or publish events is non-deterministic - they all have the same latency (sleepTime)." + results.any { it.incremental[0].data["a"] == "A" } + results.any { it.incremental[0].data["b"] == "B" } + results.any { it.incremental[0].data["c"] == "C" } + } + + def "nothing happens until the publisher is subscribed to"() { + + def startingValue = "*" + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread({ -> startingValue + "A" }, 100, "/field/path")) // <-- will finish last + incrementalCallState.enqueue(offThread({ -> startingValue + "B" }, 50, "/field/path")) // <-- will finish second + incrementalCallState.enqueue(offThread({ -> startingValue + "C" }, 10, "/field/path")) // <-- will finish first + + when: + + // get the publisher but not work has been done here + def publisher = incrementalCallState.startDeferredCalls() + // we are changing a side effect after the publisher is created + startingValue = "_" + + // subscription wll case the queue publisher to start draining the queue + List results = subscribeAndWaitCalls(publisher) + + then: + assertResultsSizeAndHasNextRule(3, results) + results[0].incremental[0].data["_c"] == "_C" + results[1].incremental[0].data["_b"] == "_B" + results[2].incremental[0].data["_a"] == "_A" + } + + def "can swap threads on subscribe"() { + + given: + def incrementalCallState = new IncrementalCallState() + incrementalCallState.enqueue(offThread({ -> "A" }, 100, "/field/path")) // <-- will finish last + incrementalCallState.enqueue(offThread({ -> "B" }, 50, "/field/path")) // <-- will finish second + incrementalCallState.enqueue(offThread({ -> "C" }, 10, "/field/path")) // <-- will finish first + + when: + + // get the publisher but not work has been done here + def publisher = incrementalCallState.startDeferredCalls() + + def threadFactory = new ThreadFactory() { + @Override + Thread newThread(Runnable r) { + return new Thread(r, "SubscriberThread") + } + } + def executor = Executors.newSingleThreadExecutor(threadFactory) + + def subscribeThreadName = "" + Callable callable = new Callable() { + @Override + Object call() throws Exception { + subscribeThreadName = Thread.currentThread().getName() + def listOfResults = subscribeAndWaitCalls(publisher) + return listOfResults + } + } + def future = executor.submit(callable) + + Awaitility.await().until { future.isDone() } + + then: + def results = future.get() + + // we subscribed on our other thread + subscribeThreadName == "SubscriberThread" + + assertResultsSizeAndHasNextRule(3, results) + results[0].incremental[0].data["c"] == "C" + results[1].incremental[0].data["b"] == "B" + results[2].incremental[0].data["a"] == "A" + } + + private static DeferredFragmentCall offThread(String data, int sleepTime, String path) { + offThread(() -> data, sleepTime, path) + } + + private static DeferredFragmentCall offThread(Supplier dataSupplier, int sleepTime, String path) { + def callSupplier = new Supplier>() { + @Override + CompletableFuture get() { + return CompletableFuture.supplyAsync({ + Thread.sleep(sleepTime) + String data = dataSupplier.get() + if (data == "Bang") { + throw new RuntimeException(data) + } + new DeferredFragmentCall.FieldWithExecutionResult(data.toLowerCase(), new ExecutionResultImpl(data, [])) + }) + } + } + + return new DeferredFragmentCall(null, ResultPath.parse(path), [callSupplier], new AlternativeCallContext()) + } + + private static DeferredFragmentCall offThreadCallWithinCall(IncrementalCallState incrementalCallState, String dataParent, String dataChild, int sleepTime, String path) { + def callSupplier = new Supplier>() { + @Override + CompletableFuture get() { + CompletableFuture.supplyAsync({ + Thread.sleep(sleepTime) + incrementalCallState.enqueue(offThread(dataChild, sleepTime, path)) + new DeferredFragmentCall.FieldWithExecutionResult(dataParent.toLowerCase(), new ExecutionResultImpl(dataParent, [])) + }) + } + } + return new DeferredFragmentCall(null, ResultPath.parse("/field/path"), [callSupplier], new AlternativeCallContext()) + } + + private static void assertResultsSizeAndHasNextRule(int expectedSize, List results) { + assert results.size() == expectedSize + + for (def i = 0; i < results.size(); i++) { + def isLastResult = i == results.size() - 1 + def hasNext = results[i].hasNext() + + assert (hasNext && !isLastResult) + || (!hasNext && isLastResult) + } + } + + private static List startAndWaitCalls(IncrementalCallState incrementalCallState) { + def publisher = incrementalCallState.startDeferredCalls() + return subscribeAndWaitCalls(publisher) + } + + private static List subscribeAndWaitCalls(Publisher publisher) { + def subscriber = new CapturingSubscriber() + publisher.subscribe(subscriber) + Awaitility.await().untilTrue(subscriber.isDone()) + if (subscriber.throwable != null) { + throw new RuntimeException(subscriber.throwable) + } + return subscriber.getEvents() + } +} diff --git a/src/test/groovy/graphql/execution/instrumentation/AllNullTestingInstrumentation.groovy b/src/test/groovy/graphql/execution/instrumentation/AllNullTestingInstrumentation.groovy new file mode 100644 index 0000000000..d702335c4d --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/AllNullTestingInstrumentation.groovy @@ -0,0 +1,155 @@ +package graphql.execution.instrumentation + +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.execution.ExecutionContext +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters +import graphql.language.Document +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLSchema +import graphql.validation.ValidationError + +import java.util.concurrent.CompletableFuture + +class AllNullTestingInstrumentation implements Instrumentation { + + InstrumentationState instrumentationState = new InstrumentationState() {} + List executionList = [] + List dfInvocations = [] + List dfClasses = [] + Map capturedData = [:] + + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.completedFuture(instrumentationState) + } + + @Override + InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:execution" + return null + } + + @Override + InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:parse" + return null + } + + @Override + InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:validation" + return null + } + + @Override + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:execution-strategy" + return null + } + + @Override + ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:execute-object" + return null + } + + @Override + InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:execute-operation" + return null + } + + @Override + InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:subscribed-field-event-$parameters.field.name" + return null + } + + @Override + InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:field-$parameters.field.name" + return null + } + + @Override + InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:fetch-$parameters.field.name" + return null + } + + @Override + InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:complete-$parameters.field.name" + return null + } + + @Override + InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + assert state == instrumentationState + executionList << "start:complete-list-$parameters.field.name" + return null + } + + @Override + ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return executionInput + } + + @Override + DocumentAndVariables instrumentDocumentAndVariables(DocumentAndVariables documentAndVariables, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return documentAndVariables + } + + @Override + GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return schema + } + + @Override + ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return executionContext + } + + @Override + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assert state == instrumentationState + dfClasses.add(dataFetcher.getClass()) + return new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + dfInvocations.add(environment) + dataFetcher.get(environment) + } + } + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return CompletableFuture.completedFuture(executionResult) + } +} + diff --git a/src/test/groovy/graphql/execution/instrumentation/ChainedInstrumentationStateTest.groovy b/src/test/groovy/graphql/execution/instrumentation/ChainedInstrumentationStateTest.groovy index 6904a69048..88d7c86538 100644 --- a/src/test/groovy/graphql/execution/instrumentation/ChainedInstrumentationStateTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/ChainedInstrumentationStateTest.groovy @@ -1,17 +1,13 @@ package graphql.execution.instrumentation +import graphql.ExecutionInput import graphql.ExecutionResult import graphql.GraphQL import graphql.StarWarsSchema import graphql.execution.AsyncExecutionStrategy -import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters -import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters -import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters -import graphql.language.Document -import graphql.schema.DataFetcher import graphql.validation.ValidationError import spock.lang.Specification @@ -19,89 +15,102 @@ import java.util.concurrent.CompletableFuture class ChainedInstrumentationStateTest extends Specification { - class NamedInstrumentationState implements InstrumentationState { - String name - } - // each implementation gives out a state object with its name - // and then asserts it gets it back with that name - class NamedInstrumentation extends TestingInstrumentation { - String name + def "basic chaining and state management"() { - NamedInstrumentation(String name) { - instrumentationState = new NamedInstrumentationState(name: name) - this.name = name - } + def a = new NamedInstrumentation("A") + def b = new NamedInstrumentation("B") + def c = new NamedInstrumentation("C") + def nullState = new SimplePerformantInstrumentation() - @Override - InstrumentationState createState() { - return instrumentationState - } + def chainedInstrumentation = new ChainedInstrumentation([ + a, + b, + nullState, + c, + ]) - def assertState(InstrumentationState instrumentationState) { - assert instrumentationState instanceof NamedInstrumentationState - assert (instrumentationState as NamedInstrumentationState).name == this.name + def query = """ + query HeroNameAndFriendsQuery { + hero { + id + } } + """ - @Override - InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginExecution(parameters) - } + def expected = [ + "start:execution", - @Override - InstrumentationContext beginParse(InstrumentationExecutionParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginParse(parameters) - } + "start:parse", + "end:parse", - @Override - InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginValidation(parameters) - } + "start:validation", + "end:validation", - @Override - ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginExecutionStrategy(parameters) - } + "start:execute-operation", - @Override - InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginExecuteOperation(parameters) - } + "start:execution-strategy", - @Override - InstrumentationContext beginField(InstrumentationFieldParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginField(parameters) - } + "start:field-hero", + "start:fetch-hero", + "end:fetch-hero", + "start:complete-hero", - @Override - InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.beginFieldFetch(parameters) - } + "start:execute-object", - @Override - DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.instrumentDataFetcher(dataFetcher, parameters) - } + "start:field-id", + "start:fetch-id", + "end:fetch-id", + "start:complete-id", + "end:complete-id", + "end:field-id", + + "end:execute-object", + + "end:complete-hero", + "end:field-hero", + + "end:execution-strategy", + + "end:execute-operation", + + "end:execution", + ] + + + when: + def strategy = new AsyncExecutionStrategy() + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .queryExecutionStrategy(strategy) + .instrumentation(chainedInstrumentation) + .build() + + graphQL.execute(query) + + then: + + chainedInstrumentation.getInstrumentations().size() == 4 + + a.executionList == expected + b.executionList == expected + c.executionList == expected + + assertCalls(a) + assertCalls(b) + assertCalls(c) - @Override - CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { - assertState(parameters.getInstrumentationState()) - return super.instrumentExecutionResult(executionResult, parameters) - } } - def "basic chaining and state management"() { + def "basic chaining and state management when null returned"() { def a = new NamedInstrumentation("A") - def b = new NamedInstrumentation("B") + def b = new NamedInstrumentation("B") { + @Override + InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + return null // just this method + } + } def c = new NamedInstrumentation("C") def chainedInstrumentation = new ChainedInstrumentation([ a, @@ -135,7 +144,7 @@ class ChainedInstrumentationStateTest extends Specification { "end:fetch-hero", "start:complete-hero", - "start:execution-strategy", + "start:execute-object", "start:field-id", "start:fetch-id", @@ -144,8 +153,48 @@ class ChainedInstrumentationStateTest extends Specification { "end:complete-id", "end:field-id", + "end:execute-object", + + "end:complete-hero", + "end:field-hero", + "end:execution-strategy", + "end:execute-operation", + + "end:execution", + ] + + def expectedWhenReturningNull = [ + "start:execution", + + "start:parse", + "end:parse", + + // overridden above + //"start:validation", + //"end:validation", + + "start:execute-operation", + + "start:execution-strategy", + + "start:field-hero", + "start:fetch-hero", + "end:fetch-hero", + "start:complete-hero", + + "start:execute-object", + + "start:field-id", + "start:fetch-id", + "end:fetch-id", + "start:complete-id", + "end:complete-id", + "end:field-id", + + "end:execute-object", + "end:complete-hero", "end:field-hero", @@ -170,13 +219,12 @@ class ChainedInstrumentationStateTest extends Specification { then: a.executionList == expected - b.executionList == expected + b.executionList == expectedWhenReturningNull c.executionList == expected assertCalls(a) assertCalls(b) assertCalls(c) - } def "empty chain"() { @@ -205,16 +253,111 @@ class ChainedInstrumentationStateTest extends Specification { } + def "single chain"() { + def a = new NamedInstrumentation("A") + def chainedInstrumentation = new ChainedInstrumentation([a]) + + def query = """ + query HeroNameAndFriendsQuery { + hero { + id + } + } + """ + + when: + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(chainedInstrumentation) + .build() + + graphQL.execute(query) + + then: + noExceptionThrown() + + assertCalls(a) + + } + + + class StringInstrumentationState implements InstrumentationState { + StringInstrumentationState(String value) { + this.value = value + } + + String value + } + + def "can have an multiple async createState() calls in play"() { + + + given: + + def query = '''query Q($var: String!) { + human(id: $var) { + id + name + } + } + ''' + + + def instrumentation1 = new SimplePerformantInstrumentation() { + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.supplyAsync { + return new StringInstrumentationState("I1") + } as CompletableFuture + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return CompletableFuture.completedFuture( + executionResult.transform { it.addExtension("i1", ((StringInstrumentationState) state).value) } + ) + } + } + def instrumentation2 = new SimplePerformantInstrumentation() { + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.supplyAsync { + return new StringInstrumentationState("I2") + } as CompletableFuture + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return CompletableFuture.completedFuture( + executionResult.transform { it.addExtension("i2", ((StringInstrumentationState) state).value) } + ) + } + + } + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(new ChainedInstrumentation([instrumentation1, instrumentation2])) + .build() + + when: + def variables = [var: "1001"] + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(query).variables(variables)) // Luke + + then: + er.extensions == [i1: "I1", i2: "I2"] + } + private void assertCalls(NamedInstrumentation instrumentation) { assert instrumentation.dfInvocations[0].getFieldDefinition().name == 'hero' - assert instrumentation.dfInvocations[0].getFieldTypeInfo().getPath().toList() == ['hero'] - assert instrumentation.dfInvocations[0].getFieldTypeInfo().getType().name == 'Character' - assert !instrumentation.dfInvocations[0].getFieldTypeInfo().isNonNullType() + assert instrumentation.dfInvocations[0].getExecutionStepInfo().getPath().toList() == ['hero'] + assert instrumentation.dfInvocations[0].getExecutionStepInfo().getUnwrappedNonNullType().name == 'Character' + assert !instrumentation.dfInvocations[0].getExecutionStepInfo().isNonNullType() assert instrumentation.dfInvocations[1].getFieldDefinition().name == 'id' - assert instrumentation.dfInvocations[1].getFieldTypeInfo().getPath().toList() == ['hero', 'id'] - assert instrumentation.dfInvocations[1].getFieldTypeInfo().getType().name == 'String' - assert instrumentation.dfInvocations[1].getFieldTypeInfo().isNonNullType() + assert instrumentation.dfInvocations[1].getExecutionStepInfo().getPath().toList() == ['hero', 'id'] + assert instrumentation.dfInvocations[1].getExecutionStepInfo().getUnwrappedNonNullType().name == 'String' + assert instrumentation.dfInvocations[1].getExecutionStepInfo().isNonNullType() } } diff --git a/src/test/groovy/graphql/execution/instrumentation/DataLoaderCacheCanBeAsyncTest.groovy b/src/test/groovy/graphql/execution/instrumentation/DataLoaderCacheCanBeAsyncTest.groovy new file mode 100644 index 0000000000..9aebce3640 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/DataLoaderCacheCanBeAsyncTest.groovy @@ -0,0 +1,133 @@ +package graphql.execution.instrumentation + +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.TestUtil +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderOptions +import org.dataloader.DataLoaderRegistry +import org.dataloader.ValueCache +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture + +class DataLoaderCacheCanBeAsyncTest extends Specification { + + def sdl = """ + type Query { + user(id : ID) : User + } + + type User { + id : ID + name : String + } + """ + + static class CustomValueCache implements ValueCache { + Map store = [:] + + int getRandomNumber(int min, int max) { + Random random = new Random() + return random.nextInt(max - min) + min + } + + @Override + CompletableFuture get(String key) { + return CompletableFuture.supplyAsync({ + Thread.sleep(getRandomNumber(100, 500)) + if (store.containsKey(key)) { + return store.get(key) + } + throw new RuntimeException("Key Missing") + }) + } + + @Override + CompletableFuture set(String key, Object value) { + return CompletableFuture.supplyAsync({ + Thread.sleep(getRandomNumber(100, 500)) + store.put(key, value) + return value + }) + } + + @Override + CompletableFuture delete(String key) { + return CompletableFuture.completedFuture(null) + } + + @Override + CompletableFuture clear() { + return CompletableFuture.completedFuture(null) + } + } + + DataLoaderRegistry registry + GraphQL graphQL + + void setup() { + + BatchLoader userBatchLoader = { List keys -> + return CompletableFuture.supplyAsync({ -> + Thread.sleep(100) + def users = [] + for (String k : keys) { + users.add([id: k, name: k + "Name"]) + } + users + }) + } + + + def valueCache = new CustomValueCache() + valueCache.store.put("a", [id: "cachedA", name: "cachedAName"]) + + DataLoaderOptions options = DataLoaderOptions.newOptions().setValueCache(valueCache).setCachingEnabled(true).build() + DataLoader userDataLoader = DataLoaderFactory.newDataLoader(userBatchLoader, options) + + registry = DataLoaderRegistry.newRegistry() + .register("users", userDataLoader) + .build() + + DataFetcher userDF = { DataFetchingEnvironment env -> + def id = env.getArgument("id") + def loader = env.getDataLoader("users") + return loader.load(id) + } + + def schema = TestUtil.schema(sdl, [Query: [user: userDF]]) + graphQL = GraphQL.newGraphQL(schema).build() + + } + + def "can execute data loader calls"() { + def query = ''' + query { + a: user(id : "a") { + id name + } + b: user(id : "b") { + id name + } + c: user(id : "c") { + id name + } + } + ''' + def executionInput = ExecutionInput.newExecutionInput(query).dataLoaderRegistry(registry).build() + + when: + def er = graphQL.execute(executionInput) + then: + er.errors.isEmpty() + er.data == [a: [id: "cachedA", name: "cachedAName"], + b: [id: "b", name: "bName"], + c: [id: "c", name: "cName"], + ] + } +} diff --git a/src/test/groovy/graphql/execution/instrumentation/InstrumentationTest.groovy b/src/test/groovy/graphql/execution/instrumentation/InstrumentationTest.groovy index e32b11c85d..43767d9348 100644 --- a/src/test/groovy/graphql/execution/instrumentation/InstrumentationTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/InstrumentationTest.groovy @@ -1,15 +1,21 @@ package graphql.execution.instrumentation +import graphql.ExecutionInput import graphql.ExecutionResult import graphql.GraphQL import graphql.StarWarsSchema +import graphql.TestUtil import graphql.execution.AsyncExecutionStrategy -import graphql.execution.batched.BatchedExecutionStrategy +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters +import graphql.incremental.IncrementalExecutionResult +import graphql.language.AstPrinter +import graphql.parser.Parser import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment -import graphql.schema.PropertyDataFetcher +import graphql.schema.SingletonPropertyDataFetcher import graphql.schema.StaticDataFetcher import org.awaitility.Awaitility import spock.lang.Specification @@ -20,7 +26,6 @@ import java.util.concurrent.atomic.AtomicBoolean class InstrumentationTest extends Specification { - def 'Instrumentation of simple serial execution'() { given: @@ -39,45 +44,46 @@ class InstrumentationTest extends Specification { def expected = [ "start:execution", - + "onDispatched:execution", "start:parse", + "onDispatched:parse", "end:parse", - "start:validation", + "onDispatched:validation", "end:validation", - "start:execute-operation", - "start:execution-strategy", - "start:field-hero", "start:fetch-hero", + "onDispatched:fetch-hero", "end:fetch-hero", - "start:complete-hero", - - "start:execution-strategy", - + "start:execute-object", "start:field-id", "start:fetch-id", + "onDispatched:fetch-id", "end:fetch-id", "start:complete-id", + "onDispatched:complete-id", "end:complete-id", + "onDispatched:field-id", "end:field-id", - - "end:execution-strategy", - + "onDispatched:execute-object", + "end:execute-object", + "onDispatched:complete-hero", "end:complete-hero", + "onDispatched:field-hero", "end:field-hero", - + "onDispatched:execution-strategy", "end:execution-strategy", - + "onDispatched:execute-operation", "end:execute-operation", "end:execution", ] when: - def instrumentation = new TestingInstrumentation() + def instrumentation = new LegacyTestingInstrumentation() + instrumentation.useOnDispatch = true def graphQL = GraphQL .newGraphQL(StarWarsSchema.starWarsSchema) @@ -93,70 +99,19 @@ class InstrumentationTest extends Specification { instrumentation.dfClasses.size() == 2 instrumentation.dfClasses[0] == StaticDataFetcher.class - instrumentation.dfClasses[1] == PropertyDataFetcher.class + instrumentation.dfClasses[1] == SingletonPropertyDataFetcher.class instrumentation.dfInvocations.size() == 2 instrumentation.dfInvocations[0].getFieldDefinition().name == 'hero' - instrumentation.dfInvocations[0].getFieldTypeInfo().getPath().toList() == ['hero'] - instrumentation.dfInvocations[0].getFieldTypeInfo().getType().name == 'Character' - !instrumentation.dfInvocations[0].getFieldTypeInfo().isNonNullType() + instrumentation.dfInvocations[0].getExecutionStepInfo().getPath().toList() == ['hero'] + instrumentation.dfInvocations[0].getExecutionStepInfo().getUnwrappedNonNullType().name == 'Character' + !instrumentation.dfInvocations[0].getExecutionStepInfo().isNonNullType() instrumentation.dfInvocations[1].getFieldDefinition().name == 'id' - instrumentation.dfInvocations[1].getFieldTypeInfo().getPath().toList() == ['hero', 'id'] - instrumentation.dfInvocations[1].getFieldTypeInfo().getType().name == 'String' - instrumentation.dfInvocations[1].getFieldTypeInfo().isNonNullType() - } - - def '#630 - Instrumentation of batched execution strategy is called'() { - given: - - def query = """ - { - hero { - id - } - } - """ - - def expected = [ - "start:execution", - "start:parse", - "end:parse", - "start:validation", - "end:validation", - "start:execute-operation", - "start:execution-strategy", - - "start:field-hero", - "start:fetch-hero", - "end:fetch-hero", - "end:field-hero", - - "start:field-id", - "start:fetch-id", - "end:fetch-id", - "end:field-id", - - "end:execution-strategy", - "end:execute-operation", - "end:execution", - ] - when: - - def instrumentation = new TestingInstrumentation() - - def graphQL = GraphQL - .newGraphQL(StarWarsSchema.starWarsSchema) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .instrumentation(instrumentation) - .build() - - graphQL.execute(query) - - then: - - instrumentation.executionList == expected + instrumentation.dfInvocations[1].getExecutionStepInfo().getPath().toList() == ['hero', 'id'] + instrumentation.dfInvocations[1].getExecutionStepInfo().getUnwrappedNonNullType().name == 'String' + instrumentation.dfInvocations[1].getExecutionStepInfo().isNonNullType() } def "exceptions at field fetch will instrument exceptions correctly"() { @@ -171,9 +126,10 @@ class InstrumentationTest extends Specification { } """ - def instrumentation = new TestingInstrumentation() { + def instrumentation = new LegacyTestingInstrumentation() { + @Override - DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { return new DataFetcher() { @Override Object get(DataFetchingEnvironment environment) { @@ -205,18 +161,18 @@ class InstrumentationTest extends Specification { * java-dataloader works. That is calls inside DataFetchers are "batched" * until a "dispatch" signal is made. */ - class WaitingInstrumentation extends SimpleInstrumentation { + class WaitingInstrumentation extends SimplePerformantInstrumentation { final AtomicBoolean goSignal = new AtomicBoolean() @Override - ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { System.out.println(String.format("t%s setting go signal off", Thread.currentThread().getId())) goSignal.set(false) return new ExecutionStrategyInstrumentationContext() { @Override - void onDispatched(CompletableFuture result) { + void onDispatched() { System.out.println(String.format("t%s setting go signal on", Thread.currentThread().getId())) goSignal.set(true) } @@ -228,8 +184,8 @@ class InstrumentationTest extends Specification { } @Override - DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - System.out.println(String.format("t%s instrument DF for %s", Thread.currentThread().getId(), parameters.environment.getFieldTypeInfo().getPath())) + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + System.out.println(String.format("t%s instrument DF for %s", Thread.currentThread().getId(), parameters.environment.getExecutionStepInfo().getPath())) return new DataFetcher() { @Override @@ -237,13 +193,12 @@ class InstrumentationTest extends Specification { // off thread call - that waits return CompletableFuture.supplyAsync({ def value = dataFetcher.get(environment) - System.out.println(String.format(" t%s awaiting %s", Thread.currentThread().getId(), environment.getFieldTypeInfo().getPath())) + System.out.println(String.format(" t%s awaiting %s", Thread.currentThread().getId(), environment.getExecutionStepInfo().getPath())) Awaitility.await().atMost(20, TimeUnit.SECONDS).untilTrue(goSignal) - System.out.println(String.format(" t%s returning value %s", Thread.currentThread().getId(), environment.getFieldTypeInfo().getPath())) + System.out.println(String.format(" t%s returning value %s", Thread.currentThread().getId(), environment.getExecutionStepInfo().getPath())) return value }) } - } } } @@ -279,4 +234,405 @@ class InstrumentationTest extends Specification { er.data == [artoo: [id: '2001'], r2d2: [name: 'R2-D2']] } + + def "document and variables can be intercepted by instrumentation and changed"() { + + given: + + def query = '''query Q($var: String!) { + human(id: $var) { + id + } +} +''' + def newQuery = '''query Q($var: String!) { + human(id: $var) { + id + name + } +} +''' + + def instrumentation = new ModernTestingInstrumentation() { + + @Override + DocumentAndVariables instrumentDocumentAndVariables(DocumentAndVariables documentAndVariables, InstrumentationExecutionParameters parameters, InstrumentationState state) { + this.capturedData["originalDoc"] = AstPrinter.printAst(documentAndVariables.getDocument()) + this.capturedData["originalVariables"] = documentAndVariables.getVariables() + def newDoc = new Parser().parseDocument(newQuery) + def newVars = [var: "1001"] + documentAndVariables.transform({ builder -> builder.document(newDoc).variables(newVars) }) + } + } + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(instrumentation) + .build() + + when: + def variables = [var: "1000"] + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(query).variables(variables)) // Luke + + then: + er.data == [human: [id: "1001", name: 'Darth Vader']] + instrumentation.capturedData["originalDoc"] == query + instrumentation.capturedData["originalVariables"] == variables + } + + def "an instrumentation can return null and graphql calling code can handle it when inside a chain"() { + given: + + def query = """ + { + hero { + id + } + } + """ + + // + // for testing purposes we must use AsyncExecutionStrategy under the covers to get such + // serial behaviour. The Instrumentation of a parallel strategy would be much different + // and certainly harder to test + + def expected = [ + "start:execution", + // because a null context was returned, there is no onDispatched and end + //"onDispatched:execution", + "start:parse", + "onDispatched:parse", + "end:parse", + "start:validation", + "onDispatched:validation", + "end:validation", + "start:execute-operation", + "start:execution-strategy", + "start:field-hero", + "start:fetch-hero", + "onDispatched:fetch-hero", + "end:fetch-hero", + "start:complete-hero", + "start:execute-object", + "start:field-id", + "start:fetch-id", + "onDispatched:fetch-id", + "end:fetch-id", + "start:complete-id", + "onDispatched:complete-id", + "end:complete-id", + "onDispatched:field-id", + "end:field-id", + "onDispatched:execute-object", + "end:execute-object", + "onDispatched:complete-hero", + "end:complete-hero", + "onDispatched:field-hero", + "end:field-hero", + "onDispatched:execution-strategy", + "end:execution-strategy", + "onDispatched:execute-operation", + "end:execute-operation", + //"end:execution", + ] + when: + + def instrumentation = new ModernTestingInstrumentation() { + @Override + InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + this.executionList.add("start:execution") + return null + } + } + instrumentation.useOnDispatch = true + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .queryExecutionStrategy(new AsyncExecutionStrategy()) + .instrumentation(instrumentation) + .build() + + graphQL.execute(query) + + then: + instrumentation.executionList == expected + } + + def "an instrumentation can return null and graphql calling code can handle it when not inside a chain"() { + + given: + + def query = '''query Q($var: String!) { + human(id: $var) { + id + name + } + } + ''' + + def instrumentation = new AllNullTestingInstrumentation() + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(instrumentation) + .build() + + when: + def variables = [var: "1001"] + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(query).variables(variables)) // Luke + + then: + er.data == [human: [id: "1001", name: 'Darth Vader']] + + def expected = [ + "start:execution", + "start:parse", + "start:validation", + "start:execute-operation", + "start:execution-strategy", + "start:field-human", + "start:fetch-human", + "start:complete-human", + "start:execute-object", + "start:field-id", + "start:fetch-id", + "start:complete-id", + "start:field-name", + "start:fetch-name", + "start:complete-name", + ] + + instrumentation.executionList == expected + } + + class StringInstrumentationState implements InstrumentationState { + StringInstrumentationState(String value) { + this.value = value + } + + String value + } + + def "can have an single async createState() in play"() { + + + given: + + def query = '''query Q($var: String!) { + human(id: $var) { + id + name + } + } + ''' + + + def instrumentation1 = new SimplePerformantInstrumentation() { + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.supplyAsync { + return new StringInstrumentationState("I1") + } as CompletableFuture + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return CompletableFuture.completedFuture( + executionResult.transform { it.addExtension("i1", ((StringInstrumentationState) state).value) } + ) + } + } + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(instrumentation1) + .build() + + when: + def variables = [var: "1001"] + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(query).variables(variables)) // Luke + + then: + er.extensions == [i1: "I1"] + } + + def "can have an backwards compatibility createState() in play"() { + + + given: + + def query = '''query Q($var: String!) { + human(id: $var) { + id + name + } + } + ''' + + + def instrumentation1 = new SimplePerformantInstrumentation() { + + @Override + InstrumentationState createState(InstrumentationCreateStateParameters parameters) { + return new StringInstrumentationState("I1") + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + return CompletableFuture.completedFuture( + executionResult.transform { it.addExtension("i1", ((StringInstrumentationState) state).value) } + ) + } + } + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .instrumentation(instrumentation1) + .build() + + when: + def variables = [var: "1001"] + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(query).variables(variables)) // Luke + + then: + er.extensions == [i1: "I1"] + } + + def "can instrumented deferred fields"() { + + given: + + def query = """ + { + hero { + id + ... @defer(label: "name") { + name + } + } + } + """ + + + when: + + def instrumentation = new ModernTestingInstrumentation() + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .queryExecutionStrategy(new AsyncExecutionStrategy()) + .instrumentation(instrumentation) + .build() + + def ei = ExecutionInput.newExecutionInput(query).graphQLContext { it -> + GraphQL.unusualConfiguration(it).incrementalSupport().enableIncrementalSupport(true) + }.build() + + IncrementalExecutionResult incrementalER = graphQL.execute(ei) as IncrementalExecutionResult + // + // cause the defer Publish to be finished + def results = TestUtil.getIncrementalResults(incrementalER) + + + then: + + instrumentation.executionList == ["start:execution", + "start:parse", + "end:parse", + "start:validation", + "end:validation", + "start:execute-operation", + "start:execution-strategy", + "start:field-hero", + "start:fetch-hero", + "end:fetch-hero", + "start:complete-hero", + "start:execute-object", + "start:field-id", + "start:fetch-id", + "end:fetch-id", + "start:complete-id", + "end:complete-id", + "end:field-id", + + "end:execute-object", + "end:complete-hero", + "end:field-hero", + "end:execution-strategy", + "end:execute-operation", + "start:reactive-results-defer", + "end:execution", + // + // the deferred field resolving now happens after the operation has come back + "start:deferred-field-name", + "start:field-name", + "start:fetch-name", + "end:fetch-name", + "start:complete-name", + "end:complete-name", + "end:field-name", + "end:deferred-field-name", + + "end:reactive-results-defer", + ] + } + + def "can instrument defer reactive ending"() { + + given: + + def query = """ + { + hero { + id + ... @defer(label: "name") { + name + } + } + } + """ + + + when: + + def instrumentation = new ModernTestingInstrumentation() + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .queryExecutionStrategy(new AsyncExecutionStrategy()) + .instrumentation(instrumentation) + .build() + + def ei = ExecutionInput.newExecutionInput(query).graphQLContext { it -> + GraphQL.unusualConfiguration(it).incrementalSupport().enableIncrementalSupport(true) + }.build() + + IncrementalExecutionResult incrementalER = graphQL.execute(ei) as IncrementalExecutionResult + // + // cause the defer Publish to be finished + def results = TestUtil.getIncrementalResults(incrementalER) + then: + + TestUtil.listContainsInOrder(instrumentation.executionList, [ + "start:execution", + "start:parse", + "end:parse", + "start:validation", + "end:validation", + "start:execute-operation", + ], [ + // then it ends initial operation + "end:execution-strategy", + "end:execute-operation", + "start:reactive-results-defer", + "end:execution", + ], [ + // followed by + "end:reactive-results-defer" + ]) + + // last of all it finishes + TestUtil.last(instrumentation.executionList) == "end:reactive-results-defer" + } + } diff --git a/src/test/groovy/graphql/execution/instrumentation/TestingInstrumentation.groovy b/src/test/groovy/graphql/execution/instrumentation/LegacyTestingInstrumentation.groovy similarity index 50% rename from src/test/groovy/graphql/execution/instrumentation/TestingInstrumentation.groovy rename to src/test/groovy/graphql/execution/instrumentation/LegacyTestingInstrumentation.groovy index edbac6ff2e..eb43263e72 100644 --- a/src/test/groovy/graphql/execution/instrumentation/TestingInstrumentation.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/LegacyTestingInstrumentation.groovy @@ -3,7 +3,7 @@ package graphql.execution.instrumentation import graphql.ExecutionInput import graphql.ExecutionResult import graphql.execution.ExecutionContext -import graphql.execution.instrumentation.parameters.InstrumentationDeferredFieldParameters +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters @@ -19,100 +19,111 @@ import graphql.validation.ValidationError import java.util.concurrent.CompletableFuture -class TestingInstrumentation implements Instrumentation { +/** + * This class overrides the old deprecated methods and shows that they still can be called + */ +class LegacyTestingInstrumentation implements Instrumentation { def instrumentationState = new InstrumentationState() {} - def executionList = [] + List executionList = [] List throwableList = [] List dfInvocations = [] List dfClasses = [] + def capturedData = [:] + + def useOnDispatch = false + + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.completedFuture(instrumentationState) + } @Override - InstrumentationState createState() { - return instrumentationState + InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + new TestingInstrumentContext("execution", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - new TestingInstrumentContext("execution", executionList, throwableList) + InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("parse", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext beginParse(InstrumentationExecutionParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("parse", executionList, throwableList) + InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("validation", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("validation", executionList, throwableList) + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingExecutionStrategyInstrumentationContext("execution-strategy", executionList, throwableList, useOnDispatch) } @Override - ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingExecutionStrategyInstrumentationContext("execution-strategy", executionList, throwableList) + ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + return new TestingExecuteObjectInstrumentationContext("execute-object", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("execute-operation", executionList, throwableList) + InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("execute-operation", executionList, throwableList, useOnDispatch) } @Override - DeferredFieldInstrumentationContext beginDeferredField(InstrumentationDeferredFieldParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("deferred-field-$parameters.field.name", executionList, throwableList) + InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("subscribed-field-event-$parameters.field.name", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext beginField(InstrumentationFieldParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("field-$parameters.field.name", executionList, throwableList) + InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("field-$parameters.field.name", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("fetch-$parameters.field.name", executionList, throwableList) + InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("fetch-$parameters.field.name", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext> beginFieldComplete(InstrumentationFieldCompleteParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("complete-$parameters.field.name", executionList, throwableList) + InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("complete-$parameters.field.name", executionList, throwableList, useOnDispatch) } @Override - InstrumentationContext> beginFieldListComplete(InstrumentationFieldCompleteParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState - return new TestingInstrumentContext("complete-list-$parameters.field.name", executionList, throwableList) + InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("complete-list-$parameters.field.name", executionList, throwableList, useOnDispatch) } @Override - GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState + GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState return schema } @Override - ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState + ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState return executionInput } @Override - ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState + ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState return executionContext } @Override - DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assert state == instrumentationState dfClasses.add(dataFetcher.getClass()) return new DataFetcher() { @Override @@ -124,8 +135,8 @@ class TestingInstrumentation implements Instrumentation { } @Override - CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { - assert parameters.getInstrumentationState() == instrumentationState + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState return CompletableFuture.completedFuture(executionResult) } } diff --git a/src/test/groovy/graphql/execution/instrumentation/ModernTestingInstrumentation.groovy b/src/test/groovy/graphql/execution/instrumentation/ModernTestingInstrumentation.groovy new file mode 100644 index 0000000000..1053ffd0d7 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/ModernTestingInstrumentation.groovy @@ -0,0 +1,163 @@ +package graphql.execution.instrumentation + +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.execution.ExecutionContext +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters +import graphql.execution.instrumentation.parameters.InstrumentationReactiveResultsParameters +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters +import graphql.language.Document +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLSchema +import graphql.validation.ValidationError + +import java.util.concurrent.CompletableFuture + +/** + * This class overrides the new methods that take state directly as a parameter + */ +class ModernTestingInstrumentation implements Instrumentation { + + InstrumentationState instrumentationState = new InstrumentationState() {} + List executionList = [] + List throwableList = [] + List dfInvocations = [] + List dfClasses = [] + Map capturedData = [:] + boolean useOnDispatch = false + + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.completedFuture(instrumentationState) + } + + @Override + InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + new TestingInstrumentContext("execution", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("parse", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("validation", executionList, throwableList, useOnDispatch) + } + + @Override + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingExecutionStrategyInstrumentationContext("execution-strategy", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginReactiveResults(InstrumentationReactiveResultsParameters parameters, InstrumentationState state) { + assert state == instrumentationState + def resultType = parameters.resultType.toString().toLowerCase() + return new TestingInstrumentContext("reactive-results-$resultType", executionList, throwableList, useOnDispatch) + } + + @Override + ExecuteObjectInstrumentationContext beginExecuteObject(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingExecuteObjectInstrumentationContext("execute-object", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("execute-operation", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("subscribed-field-event-$parameters.field.name", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("field-$parameters.field.name", executionList, throwableList, useOnDispatch) + } + + @Override + FieldFetchingInstrumentationContext beginFieldFetching(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingFieldFetchingInstrumentationContext("fetch-$parameters.field.name", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginFieldCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("complete-$parameters.field.name", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginFieldListCompletion(InstrumentationFieldCompleteParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("complete-list-$parameters.field.name", executionList, throwableList, useOnDispatch) + } + + @Override + InstrumentationContext beginDeferredField(InstrumentationFieldParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return new TestingInstrumentContext("deferred-field-$parameters.field.name", executionList, throwableList, useOnDispatch) + } + + @Override + ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return executionInput + } + + @Override + DocumentAndVariables instrumentDocumentAndVariables(DocumentAndVariables documentAndVariables, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return documentAndVariables + } + + @Override + GraphQLSchema instrumentSchema(GraphQLSchema schema, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return schema + } + + @Override + ExecutionContext instrumentExecutionContext(ExecutionContext executionContext, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return executionContext + } + + @Override + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assert state == instrumentationState + dfClasses.add(dataFetcher.getClass()) + return new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + dfInvocations.add(environment) + dataFetcher.get(environment) + } + } + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert state == instrumentationState + return CompletableFuture.completedFuture(executionResult) + } +} + diff --git a/src/test/groovy/graphql/execution/instrumentation/NamedInstrumentation.groovy b/src/test/groovy/graphql/execution/instrumentation/NamedInstrumentation.groovy new file mode 100644 index 0000000000..5e17e040ad --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/NamedInstrumentation.groovy @@ -0,0 +1,96 @@ +package graphql.execution.instrumentation + +import graphql.ExecutionResult +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters +import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters +import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters +import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters +import graphql.language.Document +import graphql.schema.DataFetcher +import graphql.validation.ValidationError + +import java.util.concurrent.CompletableFuture + +// each implementation gives out a state object with its name +// and then asserts it gets it back with that name + +class NamedInstrumentation extends ModernTestingInstrumentation { + String name + + + NamedInstrumentation(String name) { + instrumentationState = new NamedInstrumentationState(name: name) + this.name = name + } + + @Override + CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { + return CompletableFuture.completedFuture(instrumentationState) + } + + def assertState(InstrumentationState instrumentationState) { + assert instrumentationState instanceof NamedInstrumentationState + assert (instrumentationState as NamedInstrumentationState).name == this.name + } + + @Override + InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginExecution(parameters, state) + } + + @Override + InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginParse(parameters, state) + } + + @Override + InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginValidation(parameters, state) + } + + @Override + ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginExecutionStrategy(parameters, state) + } + + @Override + InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginExecuteOperation(parameters, state) + } + + @Override + InstrumentationContext beginFieldExecution(InstrumentationFieldParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginFieldExecution(parameters, state) + } + + @Override + InstrumentationContext beginFieldFetch(InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assertState(state) + return super.beginFieldFetch(parameters, state) + } + + @Override + DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { + assertState(state) + return super.instrumentDataFetcher(dataFetcher, parameters, state) + } + + @Override + CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assertState(state) + return super.instrumentExecutionResult(executionResult, parameters, state) + } +} + +class NamedInstrumentationState implements InstrumentationState { + String name +} diff --git a/src/test/groovy/graphql/execution/instrumentation/NoContextChainedInstrumentationTest.groovy b/src/test/groovy/graphql/execution/instrumentation/NoContextChainedInstrumentationTest.groovy new file mode 100644 index 0000000000..981f756633 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/NoContextChainedInstrumentationTest.groovy @@ -0,0 +1,87 @@ +package graphql.execution.instrumentation + +import graphql.GraphQL +import graphql.StarWarsSchema +import graphql.execution.AsyncExecutionStrategy +import spock.lang.Specification + +class NoContextChainedInstrumentationTest extends Specification { + + def "basic chaining and state management with no contexts"() { + + def a = new NamedInstrumentation("A") + def b = new NamedInstrumentation("B") + def c = new NamedInstrumentation("C") + def noContextChainedInstrumentation = new NoContextChainedInstrumentation([ + a, + b, + c, + ]) + + def query = """ + query HeroNameAndFriendsQuery { + hero { + id + } + } + """ + + // no end: statements becaue the context is never called + def expected = [ + "start:execution", + + "start:parse", + + "start:validation", + + "start:execute-operation", + + "start:execution-strategy", + + "start:field-hero", + "start:fetch-hero", + "start:complete-hero", + + "start:execute-object", + + "start:field-id", + "start:fetch-id", + "start:complete-id", + ] + + + when: + def strategy = new AsyncExecutionStrategy() + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .queryExecutionStrategy(strategy) + .instrumentation(noContextChainedInstrumentation) + .build() + + graphQL.execute(query) + + then: + + a.executionList == expected + b.executionList == expected + c.executionList == expected + + assertCalls(a) + assertCalls(b) + assertCalls(c) + } + + + private void assertCalls(NamedInstrumentation instrumentation) { + assert instrumentation.dfInvocations[0].getFieldDefinition().name == 'hero' + assert instrumentation.dfInvocations[0].getExecutionStepInfo().getPath().toList() == ['hero'] + assert instrumentation.dfInvocations[0].getExecutionStepInfo().getUnwrappedNonNullType().name == 'Character' + assert !instrumentation.dfInvocations[0].getExecutionStepInfo().isNonNullType() + + assert instrumentation.dfInvocations[1].getFieldDefinition().name == 'id' + assert instrumentation.dfInvocations[1].getExecutionStepInfo().getPath().toList() == ['hero', 'id'] + assert instrumentation.dfInvocations[1].getExecutionStepInfo().getUnwrappedNonNullType().name == 'String' + assert instrumentation.dfInvocations[1].getExecutionStepInfo().isNonNullType() + } + +} diff --git a/src/test/groovy/graphql/execution/instrumentation/TestingExecuteObjectInstrumentationContext.groovy b/src/test/groovy/graphql/execution/instrumentation/TestingExecuteObjectInstrumentationContext.groovy new file mode 100644 index 0000000000..a5b6cfd783 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/TestingExecuteObjectInstrumentationContext.groovy @@ -0,0 +1,9 @@ +package graphql.execution.instrumentation + +class TestingExecuteObjectInstrumentationContext extends TestingInstrumentContext> implements ExecuteObjectInstrumentationContext { + + TestingExecuteObjectInstrumentationContext(Object op, Object executionList, Object throwableList, Boolean useOnDispatch) { + super(op, executionList, throwableList, useOnDispatch) + } +} + diff --git a/src/test/groovy/graphql/execution/instrumentation/TestingExecutionStrategyInstrumentationContext.groovy b/src/test/groovy/graphql/execution/instrumentation/TestingExecutionStrategyInstrumentationContext.groovy index a5a77c36da..3f2f3efe29 100644 --- a/src/test/groovy/graphql/execution/instrumentation/TestingExecutionStrategyInstrumentationContext.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/TestingExecutionStrategyInstrumentationContext.groovy @@ -4,8 +4,8 @@ import graphql.ExecutionResult class TestingExecutionStrategyInstrumentationContext extends TestingInstrumentContext implements ExecutionStrategyInstrumentationContext { - TestingExecutionStrategyInstrumentationContext(Object op, Object executionList, Object throwableList) { - super(op, executionList, throwableList) + TestingExecutionStrategyInstrumentationContext(Object op, Object executionList, Object throwableList, Boolean useOnDispatch) { + super(op, executionList, throwableList,useOnDispatch) } } diff --git a/src/test/groovy/graphql/execution/instrumentation/TestingFieldFetchingInstrumentationContext.groovy b/src/test/groovy/graphql/execution/instrumentation/TestingFieldFetchingInstrumentationContext.groovy new file mode 100644 index 0000000000..50fcaccd2e --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/TestingFieldFetchingInstrumentationContext.groovy @@ -0,0 +1,9 @@ +package graphql.execution.instrumentation + +class TestingFieldFetchingInstrumentationContext extends TestingInstrumentContext implements FieldFetchingInstrumentationContext { + + TestingFieldFetchingInstrumentationContext(Object op, Object executionList, Object throwableList, Boolean useOnDispatch) { + super(op, executionList, throwableList, useOnDispatch) + } +} + diff --git a/src/test/groovy/graphql/execution/instrumentation/TestingInstrumentContext.groovy b/src/test/groovy/graphql/execution/instrumentation/TestingInstrumentContext.groovy index f2a90372b7..402fd2aee0 100644 --- a/src/test/groovy/graphql/execution/instrumentation/TestingInstrumentContext.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/TestingInstrumentContext.groovy @@ -7,11 +7,13 @@ class TestingInstrumentContext implements InstrumentationContext { def start = System.currentTimeMillis() def executionList = [] def throwableList = [] + def useOnDispatch - TestingInstrumentContext(op, executionList, throwableList) { + TestingInstrumentContext(op, executionList, throwableList, useOnDispatch) { this.op = op this.executionList = executionList this.throwableList = throwableList + this.useOnDispatch = useOnDispatch executionList << "start:$op" println("Started $op...") } @@ -23,7 +25,10 @@ class TestingInstrumentContext implements InstrumentationContext { } @Override - void onDispatched(CompletableFuture result) { + void onDispatched() { + if (useOnDispatch) { + this.executionList << "onDispatched:$op" + } } @Override diff --git a/src/test/groovy/graphql/execution/instrumentation/TracingInstrumentationTest.groovy b/src/test/groovy/graphql/execution/instrumentation/TracingInstrumentationTest.groovy index a43e009e82..db9f1932b5 100644 --- a/src/test/groovy/graphql/execution/instrumentation/TracingInstrumentationTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/TracingInstrumentationTest.groovy @@ -2,19 +2,19 @@ package graphql.execution.instrumentation import graphql.GraphQL import graphql.StarWarsSchema +import graphql.TestUtil import graphql.execution.AsyncExecutionStrategy import graphql.execution.AsyncSerialExecutionStrategy -import graphql.execution.batched.BatchedExecutionStrategy import graphql.execution.instrumentation.tracing.TracingInstrumentation +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment import spock.lang.Specification -class TracingInstrumentationTest extends Specification { - +import static graphql.execution.instrumentation.tracing.TracingInstrumentation.Options.newOptions - def 'tracing captures timings as expected'() { - given: +class TracingInstrumentationTest extends Specification { - def query = """ + def query = """ { hero { id @@ -23,6 +23,11 @@ class TracingInstrumentationTest extends Specification { } """ + + def 'tracing captures timings as expected'() { + given: + + when: def instrumentation = new TracingInstrumentation() @@ -93,6 +98,103 @@ class TracingInstrumentationTest extends Specification { testExecutionStrategy | _ new AsyncExecutionStrategy() | _ new AsyncSerialExecutionStrategy() | _ - new BatchedExecutionStrategy() | _ + } + + def "trivial data fetchers are ignored"() { + given: + + def spec = ''' + type Query { + hero : Hero + } + + type Hero { + id : ID + appearsIn : String + } + ''' + + DataFetcher df = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return [id: "id", appearsIn: "appearsIn"] + } + + //isTrivialDataFetcher defaults to false + } + + def instrumentation = new TracingInstrumentation( + newOptions().includeTrivialDataFetchers(false)) // defaults to true + + def graphQL = TestUtil.graphQL(spec, [Query: [hero: df]]) + .queryExecutionStrategy(testExecutionStrategy) + .instrumentation(instrumentation) + .build() + when: + def executionResult = graphQL.execute(query) + + def specExtensions = executionResult.toSpecification().get("extensions") + def tracing = specExtensions['tracing'] + + then: + + tracing["version"] == 1L + tracing["startTime"] != null + tracing["endTime"] != null + tracing["duration"] > 0L + + List resolvers = tracing['execution']['resolvers'] as List + resolvers.size() == 1 + resolvers[0]['fieldName'] == "hero" + resolvers[0]['path'] == ["hero"] + resolvers[0]['startOffset'] > 0L + resolvers[0]['duration'] > 0L + resolvers[0]['parentType'] == "Query" + resolvers[0]['returnType'] == "Hero" + + where: + + testExecutionStrategy | _ + new AsyncExecutionStrategy() | _ + new AsyncSerialExecutionStrategy() | _ + } + + def "default behavior is that trivial fields ARE recorded"() { + when: + def options = newOptions() + then: + options.isIncludeTrivialDataFetchers() + } + + def 'do not trace introspection information'() { + given: + def queryWithIntrospectionField = """ + { + __typename + } + """ + + when: + def instrumentation = new TracingInstrumentation(newOptions().includeTrivialDataFetchers(false)) + + def graphQL = GraphQL + .newGraphQL(StarWarsSchema.starWarsSchema) + .queryExecutionStrategy(testExecutionStrategy) + .instrumentation(instrumentation) + .build() + + def executionResult = graphQL.execute(queryWithIntrospectionField) + def extensions = executionResult.getExtensions() + + then: + extensions != null + def tracing = extensions['tracing'] + List resolvers = tracing['execution']['resolvers'] as List + resolvers.size() == 0 + + where: + testExecutionStrategy | _ + new AsyncExecutionStrategy() | _ + new AsyncSerialExecutionStrategy() | _ } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompare.java b/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompare.java index 93e5c0a89b..4882406716 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompare.java +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompare.java @@ -1,16 +1,11 @@ package graphql.execution.instrumentation.dataloader; -import graphql.ExecutionInput; -import graphql.ExecutionResult; -import graphql.GraphQL; -import graphql.execution.batched.BatchedExecutionStrategy; import graphql.schema.GraphQLSchema; import graphql.schema.idl.RuntimeWiring; import graphql.schema.idl.SchemaGenerator; import graphql.schema.idl.SchemaParser; import graphql.schema.idl.TypeDefinitionRegistry; import graphql.schema.idl.TypeRuntimeWiring; -import org.dataloader.DataLoaderRegistry; import java.io.InputStream; import java.io.InputStreamReader; @@ -19,79 +14,23 @@ import static java.nio.charset.Charset.defaultCharset; public class BatchCompare { - public static void main(String[] args) throws Exception { - BatchCompare batchCompare = new BatchCompare(); - batchCompare.batchedRun(); - System.out.println(); - batchCompare.dataLoaderRun(); - } - - void batchedRun() { - System.out.println("=== BatchedExecutionStrategy ==="); - GraphQLSchema schema = buildBatchedSchema(); - GraphQL graphQL = GraphQL - .newGraphQL(schema) - .queryExecutionStrategy(new BatchedExecutionStrategy()) - .build(); - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query("query { shops { id name departments { id name products { id name } } } }") - .build(); - ExecutionResult result = graphQL.execute(executionInput); - System.out.println("\nExecutionResult: " + result.toSpecification()); - } - - void dataLoaderRun() { - System.out.println("=== AsyncExecutionStrategy with DataLoader ==="); - GraphQLSchema schema = buildDataLoaderSchema(); - DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry(); - dataLoaderRegistry.register("departments", BatchCompareDataFetchers.departmentsForShopDataLoader); - dataLoaderRegistry.register("products", BatchCompareDataFetchers.productsForDepartmentDataLoader); - GraphQL graphQL = GraphQL - .newGraphQL(schema) - .instrumentation(new DataLoaderDispatcherInstrumentation(dataLoaderRegistry)) - .build(); - ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .query("query { shops { id name departments { id name products { id name } } } }") - .build(); - ExecutionResult result = graphQL.execute(executionInput); - System.out.println("\nExecutionResult: " + result.toSpecification()); - } - - GraphQLSchema buildBatchedSchema() { - InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("storesanddepartments.graphqls"); - Reader streamReader = new InputStreamReader(resourceAsStream, defaultCharset()); - TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(streamReader); - RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() - .type(TypeRuntimeWiring.newTypeWiring("Query") - .dataFetcher("shops", BatchCompareDataFetchers.shopsDataFetcher) - ) - .type(TypeRuntimeWiring.newTypeWiring("Shop") - .dataFetcher("departments", BatchCompareDataFetchers.departmentsForShopsBatchedDataFetcher) - ) - .type(TypeRuntimeWiring.newTypeWiring("Department") - .dataFetcher("products", BatchCompareDataFetchers.productsForDepartmentsBatchedDataFetcher) - ) - .build(); - - return new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); - } - GraphQLSchema buildDataLoaderSchema() { + GraphQLSchema buildDataLoaderSchema(BatchCompareDataFetchers batchCompareDataFetchers) { InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("storesanddepartments.graphqls"); Reader streamReader = new InputStreamReader(resourceAsStream, defaultCharset()); TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(streamReader); RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() .type(TypeRuntimeWiring.newTypeWiring("Query") - .dataFetcher("shops", BatchCompareDataFetchers.shopsDataFetcher) - .dataFetcher("expensiveShops", BatchCompareDataFetchers.expensiveShopsDataFetcher) + .dataFetcher("shops", batchCompareDataFetchers.shopsDataFetcher) + .dataFetcher("expensiveShops", batchCompareDataFetchers.expensiveShopsDataFetcher) ) .type(TypeRuntimeWiring.newTypeWiring("Shop") - .dataFetcher("departments", BatchCompareDataFetchers.departmentsForShopDataLoaderDataFetcher) - .dataFetcher("expensiveDepartments", BatchCompareDataFetchers.departmentsForShopDataLoaderDataFetcher) + .dataFetcher("departments", batchCompareDataFetchers.departmentsForShopDataLoaderDataFetcher) + .dataFetcher("expensiveDepartments", batchCompareDataFetchers.departmentsForShopDataLoaderDataFetcher) ) .type(TypeRuntimeWiring.newTypeWiring("Department") - .dataFetcher("products", BatchCompareDataFetchers.productsForDepartmentDataLoaderDataFetcher) - .dataFetcher("expensiveProducts", BatchCompareDataFetchers.productsForDepartmentDataLoaderDataFetcher) + .dataFetcher("products", batchCompareDataFetchers.productsForDepartmentDataLoaderDataFetcher) + .dataFetcher("expensiveProducts", batchCompareDataFetchers.productsForDepartmentDataLoaderDataFetcher) ) .build(); diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompareDataFetchers.java b/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompareDataFetchers.java index 62ed480318..08edd13248 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompareDataFetchers.java +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/BatchCompareDataFetchers.java @@ -1,13 +1,12 @@ package graphql.execution.instrumentation.dataloader; -import graphql.execution.batched.Batched; import graphql.execution.instrumentation.dataloader.models.Department; import graphql.execution.instrumentation.dataloader.models.Product; import graphql.execution.instrumentation.dataloader.models.Shop; import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; import org.dataloader.BatchLoader; import org.dataloader.DataLoader; +import org.dataloader.DataLoaderFactory; import java.util.ArrayList; import java.util.Arrays; @@ -27,25 +26,17 @@ public class BatchCompareDataFetchers { - static AtomicLong departmentsForShopsBatchLoaderCounter = new AtomicLong(); + AtomicLong departmentsForShopsBatchLoaderCounter = new AtomicLong(); - static AtomicLong productsForDepartmentsBatchLoaderCounter = new AtomicLong(); + AtomicLong productsForDepartmentsBatchLoaderCounter = new AtomicLong(); - static AtomicBoolean useAsyncBatchLoading = new AtomicBoolean(false); + AtomicBoolean useAsyncBatchLoading = new AtomicBoolean(false); - public static void useAsyncBatchLoading(boolean flag) { + public void useAsyncBatchLoading(boolean flag) { useAsyncBatchLoading.set(flag); } - static void resetState() { - departmentsForShopsBatchLoaderCounter.set(0); - productsForDepartmentsBatchLoaderCounter.set(0); - departmentsForShopDataLoader.clearAll(); - productsForDepartmentDataLoader.clearAll(); - useAsyncBatchLoading.set(false); - } - // Shops private static final Map shops = new LinkedHashMap<>(); private static final Map expensiveShops = new LinkedHashMap<>(); @@ -60,10 +51,10 @@ static void resetState() { } - public static DataFetcher>> shopsDataFetcher = + public DataFetcher>> shopsDataFetcher = environment -> supplyAsyncWithSleep(() -> new ArrayList<>(shops.values())); - public static DataFetcher>> expensiveShopsDataFetcher = environment -> + public DataFetcher>> expensiveShopsDataFetcher = environment -> supplyAsyncWithSleep(() -> new ArrayList<>(expensiveShops.values())); // Departments @@ -86,23 +77,12 @@ private static List getDepartmentsForShop(Shop shop) { } private static List> getDepartmentsForShops(List shops) { - System.out.println("getDepartmentsForShops batch: " + shops); List> departmentsResult = shops.stream().map(BatchCompareDataFetchers::getDepartmentsForShop).collect(Collectors.toList()); - System.out.println("result " + departmentsResult); return departmentsResult; } - public static DataFetcher>> departmentsForShopsBatchedDataFetcher = new DataFetcher>>() { - @Override - @Batched - public List> get(DataFetchingEnvironment environment) { - List shops = environment.getSource(); - return getDepartmentsForShops(shops); - } - }; - private static BatchLoader> departmentsForShopsBatchLoader = ids -> maybeAsyncWithSleep(() -> { - System.out.println("ids" + ids); + private BatchLoader> departmentsForShopsBatchLoader = ids -> maybeAsyncWithSleep(() -> { departmentsForShopsBatchLoaderCounter.incrementAndGet(); List shopList = new ArrayList<>(); for (String id : ids) { @@ -117,11 +97,11 @@ public List> get(DataFetchingEnvironment environment) { return completedFuture(getDepartmentsForShops(shopList)); }); - public static DataLoader> departmentsForShopDataLoader = new DataLoader<>(departmentsForShopsBatchLoader); + public DataLoader> departmentsForShopDataLoader = DataLoaderFactory.newDataLoader(departmentsForShopsBatchLoader); - public static DataFetcher>> departmentsForShopDataLoaderDataFetcher = environment -> { + public DataFetcher>> departmentsForShopDataLoaderDataFetcher = environment -> { Shop shop = environment.getSource(); - return departmentsForShopDataLoader.load(shop.getId()); + return (CompletableFuture) environment.getDataLoader("departments").load(shop.getId()); }; // Products @@ -144,33 +124,23 @@ private static List getProductsForDepartment(Department department) { } private static List> getProductsForDepartments(List departments) { - System.out.println("getProductsForDepartments batch: " + departments); return departments.stream().map(BatchCompareDataFetchers::getProductsForDepartment).collect(Collectors.toList()); } - public static DataFetcher>> productsForDepartmentsBatchedDataFetcher = new DataFetcher>>() { - @Override - @Batched - public List> get(DataFetchingEnvironment environment) { - List departments = environment.getSource(); - return getProductsForDepartments(departments); - } - }; - - private static BatchLoader> productsForDepartmentsBatchLoader = ids -> maybeAsyncWithSleep(() -> { + private BatchLoader> productsForDepartmentsBatchLoader = ids -> maybeAsyncWithSleep(() -> { productsForDepartmentsBatchLoaderCounter.incrementAndGet(); List d = ids.stream().map(departments::get).collect(Collectors.toList()); return completedFuture(getProductsForDepartments(d)); }); - public static DataLoader> productsForDepartmentDataLoader = new DataLoader<>(productsForDepartmentsBatchLoader); + public DataLoader> productsForDepartmentDataLoader = DataLoaderFactory.newDataLoader(productsForDepartmentsBatchLoader); - public static DataFetcher>> productsForDepartmentDataLoaderDataFetcher = environment -> { + public DataFetcher>> productsForDepartmentDataLoaderDataFetcher = environment -> { Department department = environment.getSource(); - return productsForDepartmentDataLoader.load(department.getId()); + return (CompletableFuture) environment.getDataLoader("products").load(department.getId()); }; - private static CompletableFuture maybeAsyncWithSleep(Supplier> supplier) { + private CompletableFuture maybeAsyncWithSleep(Supplier> supplier) { if (useAsyncBatchLoading.get()) { return supplyAsyncWithSleep(supplier) .thenCompose(cf -> cf); diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductBackend.java b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductBackend.java index 47ac93ef42..14d2f425c8 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductBackend.java +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductBackend.java @@ -1,10 +1,11 @@ package graphql.execution.instrumentation.dataloader; +import com.google.common.collect.ImmutableList; +import org.dataloader.BatchLoader; import org.dataloader.DataLoader; +import org.dataloader.DataLoaderFactory; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -26,12 +27,13 @@ public DataLoaderCompanyProductBackend(int companyCount, int projectCount) { mkCompany(projectCount); } - projectsLoader = new DataLoader<>(keys -> getProjectsForCompanies(keys).thenApply(projects -> keys + BatchLoader> uuidListBatchLoader = keys -> getProjectsForCompanies(keys).thenApply(projects -> keys .stream() .map(companyId -> projects.stream() .filter(project -> project.getCompanyId().equals(companyId)) .collect(Collectors.toList())) - .collect(Collectors.toList()))); + .collect(Collectors.toList())); + projectsLoader = DataLoaderFactory.newDataLoader(uuidListBatchLoader); } @@ -54,13 +56,13 @@ public CompletableFuture> getCompanies() { } private List companiesList() { - return Collections.unmodifiableList(new ArrayList<>(companies.values())); + return ImmutableList.copyOf(companies.values()); } public CompletableFuture> getProjectsForCompanies(List companyIds) { return CompletableFuture.supplyAsync(() -> projects.values().stream() .filter(project -> companyIds.contains(project.getCompanyId())) - .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList))); + .collect(Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf))); } public CompletableFuture addCompany() { diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductMutationTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductMutationTest.groovy index f9435fe11f..13c105039f 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductMutationTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderCompanyProductMutationTest.groovy @@ -2,7 +2,6 @@ package graphql.execution.instrumentation.dataloader import graphql.ExecutionInput import graphql.ExecutionResult -import graphql.GraphQL import graphql.TestUtil import graphql.execution.AsyncExecutionStrategy import graphql.execution.AsyncSerialExecutionStrategy @@ -49,30 +48,30 @@ class DataLoaderCompanyProductMutationTest extends Specification { newTypeWiring("Company").dataFetcher("projects", { environment -> DataLoaderCompanyProductBackend.Company source = environment.getSource() - return backend.getProjectsLoader().load(source.getId()) + return environment.getDataLoader("projects-dl").load(source.getId()) })) .type( - newTypeWiring("Query").dataFetcher("companies", { - environment -> backend.getCompanies() - })) + newTypeWiring("Query").dataFetcher("companies", { + environment -> backend.getCompanies() + })) .type( - newTypeWiring("Mutation").dataFetcher("addCompany", { - environment -> backend.addCompany() - })) + newTypeWiring("Mutation").dataFetcher("addCompany", { + environment -> backend.addCompany() + })) .build() - def schema = TestUtil.schema(spec, wiring) def registry = new DataLoaderRegistry() registry.register("projects-dl", backend.getProjectsLoader()) - def graphQL = GraphQL.newGraphQL(schema) + def graphQL = TestUtil.graphQL(spec, wiring) .queryExecutionStrategy(queryES) .mutationExecutionStrategy(mutationES) - .instrumentation(new DataLoaderDispatcherInstrumentation(registry)) .build() ExecutionInput executionInput = ExecutionInput.newExecutionInput() .query(query) + .dataLoaderRegistry(registry) + .graphQLContext([(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING): false]) .build() when: diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherTest.groovy new file mode 100644 index 0000000000..f62ae00222 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderDispatcherTest.groovy @@ -0,0 +1,393 @@ +package graphql.execution.instrumentation.dataloader + +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.AsyncSerialExecutionStrategy +import graphql.execution.instrumentation.ChainedInstrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.SimplePerformantInstrumentation +import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters +import graphql.execution.pubsub.CapturingSubscriber +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import org.reactivestreams.Publisher +import reactor.core.publisher.Mono +import spock.lang.Specification +import spock.lang.Unroll + +import java.time.Duration +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.StarWarsSchema.starWarsSchema +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class DataLoaderDispatcherTest extends Specification { + + + def query = """ + query { + hero { + name + friends { + name + friends { + name + } + } + } + } + """ + + def expectedQueryData = [hero: [name: 'R2-D2', friends: [ + [name: 'Luke Skywalker', friends: [ + [name: 'Han Solo'], [name: 'Leia Organa'], [name: 'C-3PO'], [name: 'R2-D2']]], + [name: 'Han Solo', friends: [ + [name: 'Luke Skywalker'], [name: 'Leia Organa'], [name: 'R2-D2']]], + [name: 'Leia Organa', friends: [ + [name: 'Luke Skywalker'], [name: 'Han Solo'], [name: 'C-3PO'], [name: 'R2-D2']]]]] + ] + + + @Unroll + def "basic dataloader dispatch test"() { + def dispatchedCalled = false + def dataLoaderRegistry = new DataLoaderRegistry() + def dataLoader = DataLoaderFactory.newDataLoader(new BatchLoader() { + @Override + CompletionStage load(List keys) { + return CompletableFuture.completedFuture(keys) + } + }) + dataLoaderRegistry.register("someDataLoader", dataLoader) + + def graphQL = GraphQL.newGraphQL(starWarsSchema).build() + def executionInput = newExecutionInput().dataLoaderRegistry(dataLoaderRegistry).query('{ hero { name } }').build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + + when: + def er = graphQL.executeAsync(executionInput) + Awaitility.await().until { er.isDone() } + then: + er.get().data == [hero: [name: 'R2-D2']] + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + def "enhanced execution input is respected"() { + + def starWarsWiring = new StarWarsDataLoaderWiring() + + + DataLoaderRegistry startingDataLoaderRegistry = new DataLoaderRegistry() + def enhancedDataLoaderRegistry = starWarsWiring.newDataLoaderRegistry() + + def enhancingInstrumentation = new SimplePerformantInstrumentation() { + + @Override + ExecutionInput instrumentExecutionInput(ExecutionInput executionInput, InstrumentationExecutionParameters parameters, InstrumentationState state) { + assert executionInput.getDataLoaderRegistry() == startingDataLoaderRegistry + return executionInput.transform({ builder -> builder.dataLoaderRegistry(enhancedDataLoaderRegistry) }) + } + } + + def chainedInstrumentation = new ChainedInstrumentation([enhancingInstrumentation]) + + def graphql = GraphQL.newGraphQL(starWarsWiring.schema) + .instrumentation(chainedInstrumentation).build() + + def executionInput = newExecutionInput() + .dataLoaderRegistry(startingDataLoaderRegistry) + .query(query).build() + + when: + def er = graphql.executeAsync(executionInput).join() + then: + er.data == expectedQueryData + } + + + @Unroll + def "ensure DataLoaderDispatcher works for async serial execution strategy"() { + + given: + def executionStrategy = new AsyncSerialExecutionStrategy() + def starWarsWiring = new StarWarsDataLoaderWiring() + def dlRegistry = starWarsWiring.newDataLoaderRegistry() + + + def graphql = GraphQL.newGraphQL(starWarsWiring.schema) + .queryExecutionStrategy(executionStrategy) + .build() + + when: + + def asyncResult = graphql.executeAsync(newExecutionInput().query(query) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .dataLoaderRegistry(dlRegistry)) + + + Awaitility.await().atMost(Duration.ofMillis(200)).until { -> asyncResult.isDone() } + def er = asyncResult.join() + + then: + er.data == expectedQueryData + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + def "basic batch loading is possible"() { + + given: + def starWarsWiring = new StarWarsDataLoaderWiring() + def dlRegistry = starWarsWiring.newDataLoaderRegistry() + + def graphql = GraphQL.newGraphQL(starWarsWiring.schema).build() + + when: + + def asyncResult = graphql.executeAsync(newExecutionInput().query(query) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .dataLoaderRegistry(dlRegistry)) + + def er = asyncResult.join() + + then: + er.data == [hero: [name: 'R2-D2', friends: [ + [name: 'Luke Skywalker', friends: [ + [name: 'Han Solo'], [name: 'Leia Organa'], [name: 'C-3PO'], [name: 'R2-D2']]], + [name: 'Han Solo', friends: [ + [name: 'Luke Skywalker'], [name: 'Leia Organa'], [name: 'R2-D2']]], + [name: 'Leia Organa', friends: [ + [name: 'Luke Skywalker'], [name: 'Han Solo'], [name: 'C-3PO'], [name: 'R2-D2']]]]] + ] + + // + // there are five characters in this query however we have asked for their details over and over + // and yet we only actually load the objects up five times + starWarsWiring.rawCharacterLoadCount == 5 + // + // our batch load API only gets called thrice, for R2D2, for his friends and for their friends + starWarsWiring.batchFunctionLoadCount == 3 + // + // if we didn't have batch loading it would have these many character load calls + starWarsWiring.naiveLoadCount == 15 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + + @Unroll + def "non list queries work as expected"() { + + given: + def starWarsWiring = new StarWarsDataLoaderWiring() + def dlRegistry = starWarsWiring.newDataLoaderRegistry() + + def graphql = GraphQL.newGraphQL(starWarsWiring.schema) + .build() + + when: + def query = """ + query { + arToo : hero { + name + friends { + name + } + } + + tinBox : hero { + name + friends { + name + } + } + } + """ + + def asyncResult = graphql.executeAsync(newExecutionInput().query(query) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .dataLoaderRegistry(dlRegistry)) + + def er = asyncResult.join() + + then: + er.data == [arToo : [name: "R2-D2", friends: [[name: "Luke Skywalker"], [name: "Han Solo"], [name: "Leia Organa"]]], + tinBox: [name: "R2-D2", friends: [[name: "Luke Skywalker"], [name: "Han Solo"], [name: "Leia Organa"]]] + ] + + starWarsWiring.rawCharacterLoadCount == 4 + starWarsWiring.batchFunctionLoadCount == 2 + starWarsWiring.naiveLoadCount == 8 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + def "can be efficient with lazily computed data loaders"() { + + def sdl = ''' + type Query { + field : String + } + ''' + + BatchLoader batchLoader = { keys -> CompletableFuture.completedFuture(keys) } + + def df = { env -> + def dataLoader = env.getDataLoader("key") + return dataLoader.load("working as expected") + } as DataFetcher + def runtimeWiring = newRuntimeWiring().type( + newTypeWiring("Query").dataFetcher("field", df).build() + ).build() + + def graphql = TestUtil.graphQL(sdl, runtimeWiring).build() + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + def loader = DataLoaderFactory.newDataLoader("key", batchLoader) + dataLoaderRegistry.register("key", loader) + + when: + def executionInput = newExecutionInput().dataLoaderRegistry(dataLoaderRegistry).query('{ field }').build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]); + def erCF = graphql.executeAsync(executionInput) + + then: + Awaitility.await().until { erCF.isDone() } + erCF.get().errors.isEmpty() + erCF.get().data["field"] == "working as expected" + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + } + + @Unroll + def "handles deep async queries when a data loader registry is present"() { + given: + def support = new DeepDataFetchers() + def dummyDataloaderRegistry = new DataLoaderRegistry() + def graphql = GraphQL.newGraphQL(support.schema()) + .build() + def depth = 50 + + when: + def asyncResult = graphql.executeAsync( + newExecutionInput() + .query(support.buildQuery(depth)) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .dataLoaderRegistry(dummyDataloaderRegistry) + ) + def er = asyncResult.join() + + then: + er.errors.isEmpty() + er.data == support.buildResponse(depth) + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + def "issue 3662 - dataloader dispatching can work with subscriptions"() { + + def sdl = ''' + type Query { + field : String + } + + type Subscription { + onSub : OnSub + } + + type OnSub { + x : String + y : String + } + ''' + + // the dispatching is ALWAYS so not really batching but it completes + BatchLoader batchLoader = { keys -> + CompletableFuture.supplyAsync { + Thread.sleep(50) // some delay + keys + } + } + + DataFetcher dlDF = { DataFetchingEnvironment env -> + def dataLoader = env.getDataLoader("dl") + return dataLoader.load("working as expected") + } + DataFetcher dlSub = { DataFetchingEnvironment env -> + return Mono.just([x: "X", y: "Y"]) + } + def runtimeWiring = newRuntimeWiring() + .type(newTypeWiring("OnSub") + .dataFetcher("x", dlDF) + .dataFetcher("y", dlDF) + .build() + ) + .type(newTypeWiring("Subscription") + .dataFetcher("onSub", dlSub) + .build() + ) + .build() + + def graphql = TestUtil.graphQL(sdl, runtimeWiring).build() + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("dl", DataLoaderFactory.newDataLoader(batchLoader)) + + when: + def query = """ + subscription s { + onSub { + x, y + } + } + """ + def executionInput = newExecutionInput() + .dataLoaderRegistry(dataLoaderRegistry) + .query(query) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .build() + def er = graphql.execute(executionInput) + + then: + er.errors.isEmpty() + def subscriber = new CapturingSubscriber() + Publisher pub = er.data + pub.subscribe(subscriber) + + Awaitility.await().untilTrue(subscriber.isDone()) + + subscriber.getEvents().size() == 1 + + def msgER = subscriber.getEvents()[0] as ExecutionResult + msgER.data == [onSub: [x: "working as expected", y: "working as expected"]] + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + } +} diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderHangingTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderHangingTest.groovy new file mode 100644 index 0000000000..f3b9087073 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderHangingTest.groovy @@ -0,0 +1,387 @@ +package graphql.execution.instrumentation.dataloader + +import com.github.javafaker.Faker +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.Async +import graphql.execution.AsyncExecutionStrategy +import graphql.execution.DataFetcherExceptionHandler +import graphql.execution.DataFetcherExceptionHandlerParameters +import graphql.execution.DataFetcherExceptionHandlerResult +import graphql.execution.instrumentation.dataloader.models.Company +import graphql.execution.instrumentation.dataloader.models.Person +import graphql.execution.instrumentation.dataloader.models.Product +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.idl.RuntimeWiring +import org.apache.commons.lang3.concurrent.BasicThreadFactory +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderOptions +import org.dataloader.DataLoaderRegistry +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.concurrent.SynchronousQueue +import java.util.concurrent.ThreadFactory +import java.util.concurrent.ThreadPoolExecutor +import java.util.concurrent.TimeUnit +import java.util.stream.Collectors + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class DataLoaderHangingTest extends Specification { + + public static final int NUM_OF_REPS = 50 + + @Unroll + def "deadlock attempt"() { + setup: + def sdl = """ + type Album { + id: ID! + title: String! + artist: Artist + songs( + limit: Int, + nextToken: String + ): ModelSongConnection + } + + type Artist { + id: ID! + name: String! + albums( + limit: Int, + nextToken: String + ): ModelAlbumConnection + songs( + limit: Int, + nextToken: String + ): ModelSongConnection + } + + type ModelAlbumConnection { + items: [Album] + nextToken: String + } + + type ModelArtistConnection { + items: [Artist] + nextToken: String + } + + type ModelSongConnection { + items: [Song] + nextToken: String + } + + type Query { + listArtists(limit: Int, nextToken: String): ModelArtistConnection + } + + type Song { + id: ID! + title: String! + artist: Artist + album: Album + } + """ + + ThreadFactory threadFactory = new BasicThreadFactory.Builder() + .namingPattern("resolver-chain-thread-%d").build() + def executor = new ThreadPoolExecutor(15, 15, 0L, + TimeUnit.MILLISECONDS, new SynchronousQueue<>(), threadFactory, + new ThreadPoolExecutor.CallerRunsPolicy()) + + DataFetcher albumsDf = { env -> + env.getDataLoader("artist.albums").load(env) + } + DataFetcher songsDf = { env -> + env.getDataLoader("album.songs").load(env) + } + + def dataFetcherArtists = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + def limit = environment.getArgument("limit") as Integer + def artists = [] + for (int i = 1; i <= limit; i++) { + artists.add(['id': "artist-$i", 'name': "artist-$i"]) + } + return ['nextToken': 'artist-next', 'items': artists] + } + } + + def wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("listArtists", dataFetcherArtists)) + .type(newTypeWiring("Artist") + .dataFetcher("albums", albumsDf)) + .type(newTypeWiring("Album") + .dataFetcher("songs", songsDf)) + .build() + + def schema = TestUtil.schema(sdl, wiring) + + when: + def graphql = GraphQL.newGraphQL(schema) + .build() + + then: "execution shouldn't hang" + def futures = Async.ofExpectedSize(NUM_OF_REPS) + for (int i = 0; i < NUM_OF_REPS; i++) { + DataLoaderRegistry dataLoaderRegistry = mkNewDataLoaderRegistry(executor) + def contextMap = contextKey == null ? Collections.emptyMap() : [(contextKey): true] + + def result = graphql.executeAsync(newExecutionInput() + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext(contextMap) + .query(""" + query getArtistsWithData { + listArtists(limit: 1) { + items { + name + albums(limit: 200) { + items { + title + # Uncommenting the following causes query to timeout + songs(limit: 5) { + nextToken + items { + title + } + } + } + } + } + } + } + """) + .build()) + result.whenComplete({ res, error -> + if (error) { + throw error + } + assert res.errors.empty + }) + // add all futures + futures.add(result) + } + // wait for each future to complete and grab the results + futures.await() + .whenComplete({ results, error -> + if (error) { + throw error + } + results.each { assert it.errors.empty } + }) + .join() + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + private DataLoaderRegistry mkNewDataLoaderRegistry(executor) { + def dataLoaderAlbums = DataLoaderFactory.newDataLoader(new BatchLoader>() { + @Override + CompletionStage>> load(List keys) { + return CompletableFuture.supplyAsync({ + def limit = keys.first().getArgument("limit") as Integer + return keys.collect({ k -> + def albums = [] + for (int i = 1; i <= limit; i++) { + albums.add(['id': "artist-$k.source.id-$i", 'title': "album-$i"]) + } + def albumsConnection = ['nextToken': 'album-next', 'items': albums] + return albumsConnection + }) + }, executor) + } + }, DataLoaderOptions.newOptions().setMaxBatchSize(5).build()) + + def dataLoaderSongs = DataLoaderFactory.newDataLoader(new BatchLoader>() { + @Override + CompletionStage>> load(List keys) { + return CompletableFuture.supplyAsync({ + def limit = keys.first().getArgument("limit") as Integer + return keys.collect({ k -> + def songs = [] + for (int i = 1; i <= limit; i++) { + songs.add(['id': "album-$k.source.id-$i", 'title': "song-$i"]) + } + def songsConnection = ['nextToken': 'song-next', 'items': songs] + return songsConnection + }) + }, executor) + } + }, DataLoaderOptions.newOptions().setMaxBatchSize(5).build()) + + def dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("artist.albums", dataLoaderAlbums) + dataLoaderRegistry.register("album.songs", dataLoaderSongs) + dataLoaderRegistry + } + + /* + Test code taken from https://github.com/graphql-java/graphql-java/issues/1973 + */ + Faker faker = new Faker() + String schema = """ + type Company { + id: Int! + } + type Person { + company: Company! + } + type Product { + suppliedBy: Person! + } + type QueryType { + products: [Product!]! + } + schema { + query: QueryType + } + """ + + DataFetcherExceptionHandler customExceptionHandlerThatThrows = new DataFetcherExceptionHandler() { + + @Override + CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { + // + // this is a weird test case - its not actually handling the exception - its a test + // case where the handler code itself throws an exception during the handling + // and that will not stop the DataLoader from being dispatched + throw handlerParameters.exception + } + } + + BatchLoader personBatchLoader = new BatchLoader() { + @Override + CompletionStage> load(List keys) { + return CompletableFuture.supplyAsync({ + List people = keys.stream() + .map({ id -> new Person(id, faker.name().fullName(), id + 200) }) + .collect(Collectors.toList()) + return people + }) + } + } + + BatchLoader companyBatchLoader = new BatchLoader() { + @Override + CompletionStage> load(List keys) { + return CompletableFuture.supplyAsync({ + def companies = keys.stream() + .map({ id -> new Company(id, faker.company().name()) }) + .collect(Collectors.toList()) + return companies + }) + } + } + + // Always returns exactly 2 products, one supplied by person with ID #0 and one supplied by person with ID #1. + DataFetcher productsDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + List products = new ArrayList<>() + for (int id = 0; id < 2; id++) { + products.add(new Product(faker.idNumber().toString(), faker.commerce().productName(), id, [])) + } + return products + } + } + + // Loads the person pointed to via Product.getSuppliedById. + // Then return it, unless the person has ID 0 in which case it fails. + DataFetcher suppliedByDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + Product source = environment.getSource() + DataLoaderRegistry dlRegistry = environment.getGraphQlContext().get("registry") + DataLoader personDL = dlRegistry.getDataLoader("person") + return personDL.load(source.getSuppliedById()).thenApply({ person -> + if (person.id == 0) { + throw new RuntimeException("Failure in suppliedByDF for person with ID == 0.") + } + return person + }) + } + } + + DataFetcher companyDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + Person source = environment.getSource() + DataLoaderRegistry dlRegistry = environment.getGraphQlContext().get("registry") + DataLoader companyDL = dlRegistry.getDataLoader("company") + return companyDL.load(source.getCompanyId()) + } + } + + RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type("QueryType", { builder -> builder.dataFetcher("products", productsDF) }) + .type("Product", { builder -> builder.dataFetcher("suppliedBy", suppliedByDF) }) + .type("Person", { builder -> builder.dataFetcher("company", companyDF) }) + .build() + + + def graphQLSchema = TestUtil.schema(schema, runtimeWiring) + + def query = """ + query Products { + products { + suppliedBy { + company { + id + } + } + } + } + """ + + private DataLoaderRegistry buildRegistry() { + DataLoader personDataLoader = DataLoaderFactory.newDataLoader(personBatchLoader) + DataLoader companyDataLoader = DataLoaderFactory.newDataLoader(companyBatchLoader) + + DataLoaderRegistry registry = new DataLoaderRegistry() + registry.register("person", personDataLoader) + registry.register("company", companyDataLoader) + return registry + } + + def "execution should never hang even if the datafetcher of one object in a list fails"() { + + DataLoaderRegistry registry = buildRegistry() + + GraphQL graphQL = GraphQL + .newGraphQL(graphQLSchema) + .queryExecutionStrategy(new AsyncExecutionStrategy(customExceptionHandlerThatThrows)) + .build() + + when: + + ExecutionInput executionInput = newExecutionInput() + .query(query) + .graphQLContext(["registry": registry]) + .graphQLContext([(ENABLE_DATA_LOADER_CHAINING): false]) + .dataLoaderRegistry(registry) + .build() + + def executionResult = graphQL.execute(executionInput) + + + then: + + (executionResult.errors.size() > 0) + } +} diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderNodeTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderNodeTest.groovy index a6c6100d49..46378c79a1 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderNodeTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderNodeTest.groovy @@ -1,12 +1,17 @@ package graphql.execution.instrumentation.dataloader +import graphql.ExecutionInput import graphql.ExecutionResult import graphql.GraphQL +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLSchema -import graphql.schema.GraphQLTypeReference import graphql.schema.StaticDataFetcher import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory import org.dataloader.DataLoaderRegistry import spock.lang.Specification @@ -64,11 +69,25 @@ class DataLoaderNodeTest extends Specification { } + class NodeDataFetcher implements DataFetcher { + String name + + NodeDataFetcher(String name) { + this.name = name + } + + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return environment.getDataLoader(name).load(environment.getSource()) + } + } + def "levels of loading"() { List> nodeLoads = [] - DataLoader> loader = new DataLoader<>({ keys -> + + def batchLoadFunction = { keys -> nodeLoads.add(keys) List> childNodes = new ArrayList<>() for (Node key : keys) { @@ -76,38 +95,53 @@ class DataLoaderNodeTest extends Specification { } System.out.println("BatchLoader called for " + keys + " -> got " + childNodes) return CompletableFuture.completedFuture(childNodes) - }) + } + DataLoader> loader = DataLoaderFactory.newDataLoader(batchLoadFunction) + + def nodeTypeName = "Node" + def childNodesFieldName = "childNodes" + def queryTypeName = "Query" + def rootFieldName = "root" - GraphQLObjectType nodeType = GraphQLObjectType.newObject() - .name("Node") + DataFetcher nodeDataFetcher = new NodeDataFetcher(childNodesFieldName) + DataLoaderRegistry registry = new DataLoaderRegistry().register(childNodesFieldName, loader) + + GraphQLObjectType nodeType = GraphQLObjectType + .newObject() + .name(nodeTypeName) .field(newFieldDefinition() - .name("id") - .type(GraphQLInt) - .build()) + .name("id") + .type(GraphQLInt) + .build()) .field(newFieldDefinition() - .name("childNodes") - .type(list(typeRef("Node"))) - .dataFetcher({ environment -> loader.load(environment.getSource()) }) - .build()) + .name(childNodesFieldName) + .type(list(typeRef(nodeTypeName))) + .build()) .build() + def childNodesCoordinates = FieldCoordinates.coordinates(nodeTypeName, childNodesFieldName) + def rootCoordinates = FieldCoordinates.coordinates(queryTypeName, rootFieldName) + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(childNodesCoordinates, nodeDataFetcher) + .dataFetcher(rootCoordinates, new StaticDataFetcher(root)) + .build() GraphQLSchema schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) .query(GraphQLObjectType.newObject() - .name("Query") - .field(newFieldDefinition() - .name("root") - .type(nodeType) - .dataFetcher(new StaticDataFetcher(root)) - .build()) - .build()) + .name(queryTypeName) + .field(newFieldDefinition() + .name(rootFieldName) + .type(nodeType) + .build()) + .build()) .build() - DataLoaderRegistry registry = new DataLoaderRegistry().register("childNodes", loader) - ExecutionResult result = GraphQL.newGraphQL(schema) - .instrumentation(new DataLoaderDispatcherInstrumentation(registry)) .build() - .execute(''' + .execute(ExecutionInput.newExecutionInput() + .graphQLContext([(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING): enableDataLoaderChaining]) + .dataLoaderRegistry(registry).query( + ''' query Q { root { id @@ -122,7 +156,7 @@ class DataLoaderNodeTest extends Specification { } } } - ''') + ''').build()) expect: result != null @@ -146,5 +180,9 @@ class DataLoaderNodeTest extends Specification { // but currently is this nodeLoads.size() == 3 // WOOT! + where: + enableDataLoaderChaining << [true, false] + + } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceData.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceData.groovy index cb1a5aae87..5e72e5f2ad 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceData.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceData.groovy @@ -1,23 +1,33 @@ package graphql.execution.instrumentation.dataloader +import com.fasterxml.jackson.databind.ObjectMapper import graphql.Directives import graphql.GraphQL import graphql.execution.instrumentation.Instrumentation +import graphql.execution.pubsub.CapturingSubscriber +import graphql.incremental.DelayedIncrementalPartialResult +import graphql.incremental.IncrementalExecutionResult import graphql.schema.GraphQLSchema +import org.awaitility.Awaitility import org.dataloader.DataLoaderRegistry - +import org.reactivestreams.Publisher class DataLoaderPerformanceData { - static DataLoaderRegistry setupDataLoaderRegistry() { + private final BatchCompareDataFetchers batchCompareDataFetchers; + + DataLoaderPerformanceData(BatchCompareDataFetchers batchCompareDataFetchers) { + this.batchCompareDataFetchers = batchCompareDataFetchers; + } + + DataLoaderRegistry setupDataLoaderRegistry() { DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() - dataLoaderRegistry.register("departments", BatchCompareDataFetchers.departmentsForShopDataLoader) - dataLoaderRegistry.register("products", BatchCompareDataFetchers.productsForDepartmentDataLoader) + dataLoaderRegistry.register("departments", batchCompareDataFetchers.departmentsForShopDataLoader) + dataLoaderRegistry.register("products", batchCompareDataFetchers.productsForDepartmentDataLoader) } - static GraphQL setupGraphQL(Instrumentation instrumentation) { - BatchCompareDataFetchers.resetState() - GraphQLSchema schema = new BatchCompare().buildDataLoaderSchema() + GraphQL setupGraphQL(Instrumentation instrumentation) { + GraphQLSchema schema = new BatchCompare().buildDataLoaderSchema(batchCompareDataFetchers) schema = schema.transform({ bldr -> bldr.additionalDirective(Directives.DeferDirective) }) GraphQL.newGraphQL(schema) @@ -25,6 +35,14 @@ class DataLoaderPerformanceData { .build() } + GraphQL setupGraphQL() { + GraphQLSchema schema = new BatchCompare().buildDataLoaderSchema(batchCompareDataFetchers) + schema = schema.transform({ bldr -> bldr.additionalDirective(Directives.DeferDirective) }) + + GraphQL.newGraphQL(schema) + .build() + } + static def expectedData = [ shops: [ [id : "shop-1", name: "Shop 1", @@ -43,20 +61,29 @@ class DataLoaderPerformanceData { [id: "department-9", name: "Department 9", products: [[id: "product-9", name: "Product 9"]]]] ]] ] + static String getQuery() { + return getQuery(false, false) + } - static def query = """ + static String getQuery(boolean deferDepartments, boolean deferProducts) { + return """ query { - shops { - id name - departments { - id name - products { - id name + shops { # 1 + id name # 2 + ... @defer(if: $deferDepartments) { + departments { # 2 + id name # 3 + ... @defer(if: $deferProducts) { + products { # 3 + id name # 4 + } + } } - } + } } } """ + } static def expectedExpensiveData = [ shops : [[name : "Shop 1", @@ -104,8 +131,49 @@ class DataLoaderPerformanceData { ] + static void assertIncrementalExpensiveData(List> incrementalResults) { + // Ordering is non-deterministic, so we assert on the things we know are going to be true. + + assert incrementalResults.size() == 25 + // only the last payload has "hasNext=true" + assert incrementalResults.subList(0, 24).every { it.hasNext == true } + assert incrementalResults[24].hasNext == false + + // every payload has only 1 incremental item, and the data is the same for all of them + assert incrementalResults.every { it.incremental.size() == 1 } - static def expensiveQuery = """ + def incrementalResultsItems = incrementalResults.collect { it.incremental[0] } + + // the order of the actual data is non-deterministic. So we assert via "any" that the data is there + assert incrementalResultsItems.any { it == [path: ["shops", 0], data: [departments: [[name: "Department 1"], [name: "Department 2"], [name: "Department 3"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0], data: [expensiveDepartments: [[name: "Department 1", products: [[name: "Product 1"]], expensiveProducts: [[name: "Product 1"]]], [name: "Department 2", products: [[name: "Product 2"]], expensiveProducts: [[name: "Product 2"]]], [name: "Department 3", products: [[name: "Product 3"]], expensiveProducts: [[name: "Product 3"]]]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1], data: [expensiveDepartments: [[name: "Department 4", products: [[name: "Product 4"]], expensiveProducts: [[name: "Product 4"]]], [name: "Department 5", products: [[name: "Product 5"]], expensiveProducts: [[name: "Product 5"]]], [name: "Department 6", products: [[name: "Product 6"]], expensiveProducts: [[name: "Product 6"]]]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1], data: [departments: [[name: "Department 4"], [name: "Department 5"], [name: "Department 6"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2], data: [departments: [[name: "Department 7"], [name: "Department 8"], [name: "Department 9"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2], data: [expensiveDepartments: [[name: "Department 7", products: [[name: "Product 7"]], expensiveProducts: [[name: "Product 7"]]], [name: "Department 8", products: [[name: "Product 8"]], expensiveProducts: [[name: "Product 8"]]], [name: "Department 9", products: [[name: "Product 9"]], expensiveProducts: [[name: "Product 9"]]]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0, "departments", 0], data: [products: [[name: "Product 1"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0, "departments", 0], data: [expensiveProducts: [[name: "Product 1"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0, "departments", 1], data: [products: [[name: "Product 2"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0, "departments", 1], data: [expensiveProducts: [[name: "Product 2"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0, "departments", 2], data: [products: [[name: "Product 3"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 0, "departments", 2], data: [expensiveProducts: [[name: "Product 3"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1, "departments", 0], data: [expensiveProducts: [[name: "Product 4"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1, "departments", 0], data: [products: [[name: "Product 4"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1, "departments", 1], data: [products: [[name: "Product 5"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1, "departments", 1], data: [expensiveProducts: [[name: "Product 5"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1, "departments", 2], data: [expensiveProducts: [[name: "Product 6"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 1, "departments", 2], data: [products: [[name: "Product 6"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2, "departments", 0], data: [products: [[name: "Product 7"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2, "departments", 0], data: [expensiveProducts: [[name: "Product 7"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2, "departments", 1], data: [products: [[name: "Product 8"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2, "departments", 1], data: [expensiveProducts: [[name: "Product 8"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2, "departments", 2], data: [products: [[name: "Product 9"]]]] } + assert incrementalResultsItems.any { it == [path: ["shops", 2, "departments", 2], data: [expensiveProducts: [[name: "Product 9"]]]] } + assert incrementalResultsItems.any { it == [path: [], data: [expensiveShops: [[id: "exshop-1", name: "ExShop 1"], [id: "exshop-2", name: "ExShop 2"], [id: "exshop-3", name: "ExShop 3"]]]] } + } + + static String getExpensiveQuery(boolean deferredEnabled) { + return """ query { shops { name @@ -114,19 +182,25 @@ class DataLoaderPerformanceData { products { name } - expensiveProducts { - name - } + ... @defer(if: $deferredEnabled) { + expensiveProducts { + name + } + } } - expensiveDepartments { - name - products { + ... @defer(if: $deferredEnabled) { + expensiveDepartments { name + products { + name + } + ... @defer(if: $deferredEnabled) { + expensiveProducts { + name + } + } } - expensiveProducts { - name - } - } + } } expensiveShops { name @@ -135,117 +209,95 @@ class DataLoaderPerformanceData { products { name } - expensiveProducts { - name - } + ... @defer(if: $deferredEnabled) { + expensiveProducts { + name + } + } } - expensiveDepartments { - name - products { + ... @defer(if: $deferredEnabled) { + expensiveDepartments { name + products { + name + } + ... @defer(if: $deferredEnabled) { + expensiveProducts { + name + } + } } - expensiveProducts { - name - } - } + } } } - """ +""" - static def expectedDeferredData = [ - shops: [ - [id: "shop-1", name: "Shop 1"], - [id: "shop-2", name: "Shop 2"], - [id: "shop-3", name: "Shop 3"], - ] - ] + } - static def expectedListOfDeferredData = [ - [[id: "department-1", name: "Department 1", products: [[id: "product-1", name: "Product 1"]]], - [id: "department-2", name: "Department 2", products: [[id: "product-2", name: "Product 2"]]], - [id: "department-3", name: "Department 3", products: [[id: "product-3", name: "Product 3"]]]] - , - - [[id: "department-4", name: "Department 4", products: [[id: "product-4", name: "Product 4"]]], - [id: "department-5", name: "Department 5", products: [[id: "product-5", name: "Product 5"]]], - [id: "department-6", name: "Department 6", products: [[id: "product-6", name: "Product 6"]]]] - , - [[id: "department-7", name: "Department 7", products: [[id: "product-7", name: "Product 7"]]], - [id: "department-8", name: "Department 8", products: [[id: "product-8", name: "Product 8"]]], - [id: "department-9", name: "Department 9", products: [[id: "product-9", name: "Product 9"]]]] - , + static List> getIncrementalResults(IncrementalExecutionResult initialResult) { + Publisher deferredResultStream = initialResult.incrementalItemPublisher - ] + def subscriber = new CapturingSubscriber() + deferredResultStream.subscribe(subscriber) + Awaitility.await().untilTrue(subscriber.isDone()) + if(subscriber.getThrowable() != null) { + throw subscriber.getThrowable() + } - static def deferredQuery = """ - query { - shops { - id name - departments @defer { - id name - products { - id name - } - } - } - } - """ + return subscriber.getEvents() + .collect { it.toSpecification() } + } - static def expensiveDeferredQuery = """ - query { - shops { - id name - departments @defer { - name - products @defer { - name - } - expensiveProducts @defer { - name - } - } - expensiveDepartments @defer { - name - products { - name - } - expensiveProducts { - name - } - } - } - expensiveShops @defer { - id name - } - } - """ + /** + * Combines the initial result with the incremental results into a single result that has the same shape as a + * "normal" execution result. + * + * @param initialResult the data from the initial execution + * @param incrementalResults the data from the incremental executions + * @return a single result that combines the initial and incremental results + */ + static Map combineExecutionResults(Map initialResult, List> incrementalResults) { + Map combinedResult = deepClone(initialResult, Map.class) - static def expectedExpensiveDeferredData = [ - [[id: "exshop-1", name: "ExShop 1"], [id: "exshop-2", name: "ExShop 2"], [id: "exshop-3", name: "ExShop 3"]], - [[name: "Department 1"], [name: "Department 2"], [name: "Department 3"]], - [[name: "Department 1", products: [[name: "Product 1"]], expensiveProducts: [[name: "Product 1"]]], [name: "Department 2", products: [[name: "Product 2"]], expensiveProducts: [[name: "Product 2"]]], [name: "Department 3", products: [[name: "Product 3"]], expensiveProducts: [[name: "Product 3"]]]], - [[name: "Department 4"], [name: "Department 5"], [name: "Department 6"]], - [[name: "Department 4", products: [[name: "Product 4"]], expensiveProducts: [[name: "Product 4"]]], [name: "Department 5", products: [[name: "Product 5"]], expensiveProducts: [[name: "Product 5"]]], [name: "Department 6", products: [[name: "Product 6"]], expensiveProducts: [[name: "Product 6"]]]], - [[name: "Department 7"], [name: "Department 8"], [name: "Department 9"]], - [[name: "Department 7", products: [[name: "Product 7"]], expensiveProducts: [[name: "Product 7"]]], [name: "Department 8", products: [[name: "Product 8"]], expensiveProducts: [[name: "Product 8"]]], [name: "Department 9", products: [[name: "Product 9"]], expensiveProducts: [[name: "Product 9"]]]], - [[name: "Product 1"]], - [[name: "Product 1"]], - [[name: "Product 2"]], - [[name: "Product 2"]], - [[name: "Product 3"]], - [[name: "Product 3"]], - [[name: "Product 4"]], - [[name: "Product 4"]], - [[name: "Product 5"]], - [[name: "Product 5"]], - [[name: "Product 6"]], - [[name: "Product 6"]], - [[name: "Product 7"]], - [[name: "Product 7"]], - [[name: "Product 8"]], - [[name: "Product 8"]], - [[name: "Product 9"]], - [[name: "Product 9"]], - ] + incrementalResults + // groovy's flatMap + .collectMany { (List) it.incremental } + .each { result -> + def parent = findByPath((Map) combinedResult.data, (List) result.path) + if (parent instanceof Map) { + parent.putAll((Map) result.data) + } else if (parent instanceof List) { + parent.addAll(result.data) + } else { + throw new RuntimeException("Unexpected parent type: ${parent.getClass()}") + } + + if(combinedResult.errors != null && !result.errors.isEmpty()) { + if(combinedResult.errors == null) { + combinedResult.errors = [] + } + + combinedResult.errors.addAll(result.errors) + } + } + + // Remove the "hasNext" to make the result look like a normal execution result + combinedResult.remove("hasNext") + + combinedResult + } + + private static ObjectMapper objectMapper = new ObjectMapper() + private static T deepClone(Object obj, Class clazz) { + return objectMapper.readValue(objectMapper.writeValueAsString(obj), clazz) + } + + private static Object findByPath(Map data, List path) { + def current = data + path.each { key -> + current = current[key] + } + current + } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceTest.groovy index 8c5d79718c..1ee790ded3 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceTest.groovy @@ -1,149 +1,151 @@ package graphql.execution.instrumentation.dataloader import graphql.ExecutionInput -import graphql.ExecutionResult import graphql.GraphQL -import graphql.execution.defer.CapturingSubscriber -import graphql.execution.instrumentation.Instrumentation -import org.awaitility.Awaitility import org.dataloader.DataLoaderRegistry -import org.reactivestreams.Publisher import spock.lang.Specification +import spock.lang.Unroll -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getDeferredQuery +import static graphql.ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.expectedExpensiveData import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedDeferredData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedExpensiveData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedExpensiveDeferredData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedListOfDeferredData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpensiveDeferredQuery import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpensiveQuery import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getQuery -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.setupDataLoaderRegistry -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.setupGraphQL class DataLoaderPerformanceTest extends Specification { GraphQL graphQL + DataLoaderRegistry dataLoaderRegistry + BatchCompareDataFetchers batchCompareDataFetchers void setup() { - DataLoaderRegistry dataLoaderRegistry = setupDataLoaderRegistry() - Instrumentation instrumentation = new DataLoaderDispatcherInstrumentation(dataLoaderRegistry) - graphQL = setupGraphQL(instrumentation) + batchCompareDataFetchers = new BatchCompareDataFetchers() + DataLoaderPerformanceData dataLoaderPerformanceData = new DataLoaderPerformanceData(batchCompareDataFetchers) + dataLoaderRegistry = dataLoaderPerformanceData.setupDataLoaderRegistry() + graphQL = dataLoaderPerformanceData.setupGraphQL() } + @Unroll def "760 ensure data loader is performant for lists"() { when: - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(query).build() + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getQuery()) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .build() def result = graphQL.execute(executionInput) then: result.data == expectedData // // eg 1 for shops-->departments and one for departments --> products - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + + where: + incrementalSupport | contextKey + false | ENABLE_DATA_LOADER_CHAINING + true | ENABLE_DATA_LOADER_CHAINING + false | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + true | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + false | null + true | null } + @Unroll def "970 ensure data loader is performant for multiple field with lists"() { when: - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(expensiveQuery).build() + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getExpensiveQuery(false)) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .build() def result = graphQL.execute(executionInput) then: result.data == expectedExpensiveData - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() <= 2 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() <= 2 + + where: + incrementalSupport | contextKey + false | ENABLE_DATA_LOADER_CHAINING + true | ENABLE_DATA_LOADER_CHAINING + false | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + true | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + false | null + true | null } + @Unroll def "ensure data loader is performant for lists using async batch loading"() { when: - BatchCompareDataFetchers.useAsyncBatchLoading(true) + batchCompareDataFetchers.useAsyncBatchLoading(true) + + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getQuery()) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .build() - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(query).build() def result = graphQL.execute(executionInput) then: result.data == expectedData // // eg 1 for shops-->departments and one for departments --> products - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 - + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + + where: + incrementalSupport | contextKey + false | ENABLE_DATA_LOADER_CHAINING + true | ENABLE_DATA_LOADER_CHAINING + false | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + true | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + false | null + true | null } + @Unroll def "970 ensure data loader is performant for multiple field with lists using async batch loading"() { when: - BatchCompareDataFetchers.useAsyncBatchLoading(true) - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(expensiveQuery).build() - def result = graphQL.execute(executionInput) - - then: - result.data == expectedExpensiveData - - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 - } + batchCompareDataFetchers.useAsyncBatchLoading(true) - def "data loader will work with deferred queries"() { + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getExpensiveQuery(false)) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .build() - when: - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(deferredQuery).build() def result = graphQL.execute(executionInput) - Map extensions = result.getExtensions() - Publisher deferredResultStream = (Publisher) extensions.get(GraphQL.DEFERRED_RESULTS) - - def subscriber = new CapturingSubscriber() - subscriber.subscribeTo(deferredResultStream) - Awaitility.await().untilTrue(subscriber.finished) - - then: + result.data == expectedExpensiveData - result.data == expectedDeferredData - - subscriber.executionResultData == expectedListOfDeferredData - - // - // with deferred results, we don't achieve the same efficiency - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 3 - } - - def "data loader will work with deferred queries on multiple levels deep"() { - - when: - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(expensiveDeferredQuery).build() - def result = graphQL.execute(executionInput) - - Map extensions = result.getExtensions() - Publisher deferredResultStream = (Publisher) extensions.get(GraphQL.DEFERRED_RESULTS) - - def subscriber = new CapturingSubscriber() - subscriber.subscribeTo(deferredResultStream) - Awaitility.await().untilTrue(subscriber.finished) - - - then: - - result.data == expectedDeferredData - - subscriber.executionResultData == expectedExpensiveDeferredData - - // - // with deferred results, we don't achieve the same efficiency - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 3 + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() <= 2 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() <= 2 + + where: + incrementalSupport | contextKey + false | ENABLE_DATA_LOADER_CHAINING + true | ENABLE_DATA_LOADER_CHAINING + false | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + true | ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING + false | null + true | null } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceWithChainedInstrumentationTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceWithChainedInstrumentationTest.groovy index 89bb73df9f..5467c87220 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceWithChainedInstrumentationTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderPerformanceWithChainedInstrumentationTest.groovy @@ -1,153 +1,122 @@ package graphql.execution.instrumentation.dataloader import graphql.ExecutionInput -import graphql.ExecutionResult import graphql.GraphQL -import graphql.execution.defer.CapturingSubscriber -import graphql.execution.instrumentation.ChainedInstrumentation -import graphql.execution.instrumentation.Instrumentation -import org.awaitility.Awaitility import org.dataloader.DataLoaderRegistry -import org.reactivestreams.Publisher +import spock.lang.Ignore import spock.lang.Specification -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getDeferredQuery +import static graphql.ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.expectedExpensiveData import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedDeferredData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedExpensiveData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedExpensiveDeferredData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpectedListOfDeferredData -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpensiveDeferredQuery import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpensiveQuery import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getQuery -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.setupDataLoaderRegistry -import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.setupGraphQL - class DataLoaderPerformanceWithChainedInstrumentationTest extends Specification { GraphQL graphQL + DataLoaderRegistry dataLoaderRegistry + BatchCompareDataFetchers batchCompareDataFetchers + void setup() { - DataLoaderRegistry dataLoaderRegistry = setupDataLoaderRegistry() - Instrumentation instrumentation = new ChainedInstrumentation( - Collections.singletonList(new DataLoaderDispatcherInstrumentation(dataLoaderRegistry))) - graphQL = setupGraphQL(instrumentation) + batchCompareDataFetchers = new BatchCompareDataFetchers() + DataLoaderPerformanceData dataLoaderPerformanceData = new DataLoaderPerformanceData(batchCompareDataFetchers) + + dataLoaderRegistry = dataLoaderPerformanceData.setupDataLoaderRegistry() + graphQL = dataLoaderPerformanceData.setupGraphQL() } def "chainedInstrumentation: 760 ensure data loader is performant for lists"() { when: - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(query).build() + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getQuery()) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .build() + def result = graphQL.execute(executionInput) then: result.data == expectedData // // eg 1 for shops-->departments and one for departments --> products - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + + where: + incrementalSupport << [true, false] } + @Ignore("This test flakes on Travis for some reason. Clearly this indicates some sort of problem to investigate. However it also stop releases.") def "chainedInstrumentation: 970 ensure data loader is performant for multiple field with lists"() { when: - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(expensiveQuery).build() + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getExpensiveQuery(false)) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .build() + def result = graphQL.execute(executionInput) then: result.data == expectedExpensiveData - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + + where: + incrementalSupport << [true, false] } def "chainedInstrumentation: ensure data loader is performant for lists using async batch loading"() { when: - BatchCompareDataFetchers.useAsyncBatchLoading(true) + batchCompareDataFetchers.useAsyncBatchLoading(true) - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(query).build() + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .build() def result = graphQL.execute(executionInput) then: result.data == expectedData // // eg 1 for shops-->departments and one for departments --> products - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + where: + incrementalSupport << [true, false] } def "chainedInstrumentation: 970 ensure data loader is performant for multiple field with lists using async batch loading"() { when: - BatchCompareDataFetchers.useAsyncBatchLoading(true) + batchCompareDataFetchers.useAsyncBatchLoading(true) - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(expensiveQuery).build() + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(getExpensiveQuery(false)) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): incrementalSupport]) + .build() def result = graphQL.execute(executionInput) then: result.data == expectedExpensiveData - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 - } - - def "chainedInstrumentation: data loader will work with deferred queries"() { - - when: - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(deferredQuery).build() - def result = graphQL.execute(executionInput) - - Map extensions = result.getExtensions() - Publisher deferredResultStream = (Publisher) extensions.get(GraphQL.DEFERRED_RESULTS) - - def subscriber = new CapturingSubscriber() - subscriber.subscribeTo(deferredResultStream) - Awaitility.await().untilTrue(subscriber.finished) - - - then: + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() <= 2 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() <= 2 - result.data == expectedDeferredData - - subscriber.executionResultData == expectedListOfDeferredData - - // - // with deferred results, we don't achieve the same efficiency - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 3 + where: + incrementalSupport << [true, false] } - def "chainedInstrumentation: data loader will work with deferred queries on multiple levels deep"() { - - when: - - ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(expensiveDeferredQuery).build() - def result = graphQL.execute(executionInput) - - Map extensions = result.getExtensions() - Publisher deferredResultStream = (Publisher) extensions.get(GraphQL.DEFERRED_RESULTS) - - def subscriber = new CapturingSubscriber() - subscriber.subscribeTo(deferredResultStream) - Awaitility.await().untilTrue(subscriber.finished) - - - then: - - result.data == expectedDeferredData - - subscriber.executionResultData == expectedExpensiveDeferredData - - // - // with deferred results, we don't achieve the same efficiency - BatchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 - BatchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 3 - } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderTypeMismatchTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderTypeMismatchTest.groovy index 16c3bca0e8..61e444b70c 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderTypeMismatchTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DataLoaderTypeMismatchTest.groovy @@ -1,5 +1,6 @@ package graphql.execution.instrumentation.dataloader +import graphql.ExecutionInput import graphql.GraphQL import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment @@ -8,6 +9,7 @@ import graphql.schema.idl.SchemaGenerator import graphql.schema.idl.SchemaParser import org.dataloader.BatchLoader import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory import org.dataloader.DataLoaderRegistry import spock.lang.Specification @@ -35,7 +37,7 @@ class DataLoaderTypeMismatchTest extends Specification { def typeDefinitionRegistry = new SchemaParser().parse(sdl) - def dataLoader = new DataLoader(new BatchLoader() { + def dataLoader = DataLoaderFactory.newDataLoader(new BatchLoader() { @Override CompletionStage> load(List keys) { return CompletableFuture.completedFuture([ @@ -49,26 +51,31 @@ class DataLoaderTypeMismatchTest extends Specification { def todosDef = new DataFetcher>() { @Override CompletableFuture get(DataFetchingEnvironment environment) { - return dataLoader.load(environment) + return environment.getDataLoader("getTodos").load(environment) } } def wiring = RuntimeWiring.newRuntimeWiring() .type(newTypeWiring("Query") - .dataFetcher("getTodos", todosDef)) + .dataFetcher("getTodos", todosDef)) .build() def schema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, wiring) def graphql = GraphQL.newGraphQL(schema) - .instrumentation(new DataLoaderDispatcherInstrumentation(dataLoaderRegistry)) .build() when: - def result = graphql.execute("query { getTodos { id } }") + def result = graphql.execute(ExecutionInput.newExecutionInput() + .graphQLContext([(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING): enableDataLoaderChaining]) + .dataLoaderRegistry(dataLoaderRegistry).query("query { getTodos { id } }").build()) then: "execution shouldn't hang" !result.errors.empty result.errors[0].message == "Can't resolve value (/getTodos) : type mismatch error, expected type LIST" + + where: + enableDataLoaderChaining << [true, false] + } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DeepDataFetchers.java b/src/test/groovy/graphql/execution/instrumentation/dataloader/DeepDataFetchers.java new file mode 100644 index 0000000000..874700f32a --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DeepDataFetchers.java @@ -0,0 +1,81 @@ +package graphql.execution.instrumentation.dataloader; + +import java.util.HashMap; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLTypeReference; + +public class DeepDataFetchers { + private static CompletableFuture supplyAsyncWithSleep(Supplier supplier) { + Supplier sleepSome = sleepSome(supplier); + return CompletableFuture.supplyAsync(sleepSome); + } + + private static Supplier sleepSome(Supplier supplier) { + return () -> { + try { + Thread.sleep(10L); + return supplier.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }; + } + + public GraphQLSchema schema() { + GraphQLFieldDefinition selfField = GraphQLFieldDefinition.newFieldDefinition() + .name("self") + .type(GraphQLTypeReference.typeRef("Query")) + .build(); + + GraphQLObjectType query = GraphQLObjectType.newObject() + .name("Query") + .field(selfField) + .build(); + + FieldCoordinates selfCoordinates = FieldCoordinates.coordinates("Query", "self"); + DataFetcher>> slowFetcher = environment -> + supplyAsyncWithSleep(HashMap::new); + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(selfCoordinates, slowFetcher) + .build(); + + return GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .build(); + } + + public String buildQuery(Integer depth) { + StringBuilder sb = new StringBuilder(); + sb.append("query {"); + for (Integer i = 0; i < depth; i++) { + sb.append("self {"); + } + sb.append("__typename"); + for (Integer i = 0; i < depth; i++) { + sb.append("}"); + } + sb.append("}"); + + return sb.toString(); + } + + public HashMap buildResponse(Integer depth) { + HashMap level = new HashMap<>(); + if (depth == 0) { + level.put("__typename", "Query"); + } else { + level.put("self", buildResponse(depth - 1)); + } + return level; + } +} diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/DeferWithDataLoaderTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/DeferWithDataLoaderTest.groovy new file mode 100644 index 0000000000..0fe86e3fba --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/DeferWithDataLoaderTest.groovy @@ -0,0 +1,526 @@ +package graphql.execution.instrumentation.dataloader + +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.ExperimentalApi +import graphql.GraphQL +import graphql.TestUtil +import graphql.incremental.IncrementalExecutionResult +import graphql.schema.DataFetcher +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import spock.lang.RepeatUntilFailure +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.concurrent.CompletableFuture + +import static graphql.ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.combineExecutionResults +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.expectedData +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.expectedExpensiveData +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getExpensiveQuery +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getIncrementalResults +import static graphql.execution.instrumentation.dataloader.DataLoaderPerformanceData.getQuery + +class DeferWithDataLoaderTest extends Specification { + + GraphQL graphQL + DataLoaderRegistry dataLoaderRegistry + BatchCompareDataFetchers batchCompareDataFetchers + + + void setup() { + batchCompareDataFetchers = new BatchCompareDataFetchers() + DataLoaderPerformanceData dataLoaderPerformanceData = new DataLoaderPerformanceData(batchCompareDataFetchers) + + dataLoaderRegistry = dataLoaderPerformanceData.setupDataLoaderRegistry() + graphQL = dataLoaderPerformanceData.setupGraphQL() + } + + /** + * @param results a list of the incremental results from the execution + * @param expectedPaths a list of the expected paths in the incremental results. The order of the elements in the list is not important. + */ + private static void assertIncrementalResults(List> results, List> expectedPaths, List expectedData = null) { + assert results.size() == expectedPaths.size(), "Expected ${expectedPaths.size()} results, got ${results.size()}" + + assert results.dropRight(1).every { it.hasNext == true }, "Expected all but the last result to have hasNext=true" + assert results.last().hasNext == false, "Expected last result to have hasNext=false" + + assert results.every { it.incremental.size() == 1 }, "Expected every result to have exactly one incremental item" + + expectedPaths.eachWithIndex { path, index -> + def result = results.find { it.incremental[0].path == path } + assert result != null, "Expected path $path not found in $results" + if (expectedData != null) { + assert result.incremental[0].data == expectedData[index], "Expected data $expectedData[index] for path $path, got ${result.incremental[0].data}" + } + } + } + + @Unroll + def "query with single deferred field"() { + given: + def query = getQuery(true, false) + + def expectedInitialData = [ + data : [ + shops: [ + [id: "shop-1", name: "Shop 1"], + [id: "shop-2", name: "Shop 2"], + [id: "shop-3", name: "Shop 3"], + ] + ], + hasNext: true + ] + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): true]) + .build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + + IncrementalExecutionResult result = graphQL.execute(executionInput) + + then: + result.toSpecification() == expectedInitialData + + when: + def incrementalResults = getIncrementalResults(result) + + then: + + assertIncrementalResults(incrementalResults, [["shops", 0], ["shops", 1], ["shops", 2]]) + + when: + def combined = combineExecutionResults(result.toSpecification(), incrementalResults) + then: + combined.errors == null + combined.data == expectedData + + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 3 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + } + + @Unroll + def "multiple fields on same defer block"() { + given: + def query = """ + query { + shops { + id + ... @defer { + name + departments { + name + } + } + } + } + + """ + + def expectedInitialData = [ + data : [ + shops: [ + [id: "shop-1"], + [id: "shop-2"], + [id: "shop-3"], + ] + ], + hasNext: true + ] + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): true]) + .build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + + IncrementalExecutionResult result = graphQL.execute(executionInput) + + then: + result.toSpecification() == expectedInitialData + + when: + def incrementalResults = getIncrementalResults(result) + + then: + + assertIncrementalResults(incrementalResults, [["shops", 0], ["shops", 1], ["shops", 2]]) + + when: + def combined = combineExecutionResults(result.toSpecification(), incrementalResults) + then: + combined.errors == null + combined.data == [ + shops: [ + [id : "shop-1", name: "Shop 1", + departments: [[name: "Department 1"], + [name: "Department 2"], + [name: "Department 3"] + ]], + [id : "shop-2", name: "Shop 2", + departments: [[name: "Department 4"], + [name: "Department 5"], + [name: "Department 6"] + ]], + [id : "shop-3", name: "Shop 3", + departments: [[name: "Department 7"], + [name: "Department 8"], + [name: "Department 9"]] + ]] + ] + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 0 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + def "query with nested deferred fields"() { + given: + def query = getQuery(true, true) + + def expectedInitialData = [ + data : [ + shops: [ + [id: "shop-1", name: "Shop 1"], + [id: "shop-2", name: "Shop 2"], + [id: "shop-3", name: "Shop 3"], + ] + ], + hasNext: true + ] + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): true]) + .build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + + + ExecutionResult result = graphQL.execute(executionInput) + + then: + result.toSpecification() == expectedInitialData + + when: + def incrementalResults = getIncrementalResults(result) + + then: + + assertIncrementalResults(incrementalResults, + [ + ["shops", 0], ["shops", 1], ["shops", 2], + ["shops", 0, "departments", 0], ["shops", 1, "departments", 0], ["shops", 2, "departments", 0], + ["shops", 0, "departments", 1], ["shops", 1, "departments", 1], ["shops", 2, "departments", 1], + ["shops", 0, "departments", 2], ["shops", 1, "departments", 2], ["shops", 2, "departments", 2], + ] + ) + + when: + def combined = combineExecutionResults(result.toSpecification(), incrementalResults) + then: + combined.errors == null + combined.data == expectedData + + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 3 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 9 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + def "query with top-level deferred field"() { + given: + def query = """ + query { + shops { + departments { + name + } + } + ... @defer { + expensiveShops { + name + } + } + } +""" + + def expectedInitialData = [ + data : [ + shops: [[departments: [[name: "Department 1"], [name: "Department 2"], [name: "Department 3"]]], + [departments: [[name: "Department 4"], [name: "Department 5"], [name: "Department 6"]]], + [departments: [[name: "Department 7"], [name: "Department 8"], [name: "Department 9"]]], + ] + ], + hasNext: true + ] + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): true]) + .build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + + + IncrementalExecutionResult result = graphQL.execute(executionInput) + + then: + result.toSpecification() == expectedInitialData + + when: + def incrementalResults = getIncrementalResults(result) + + then: + + assertIncrementalResults(incrementalResults, + [ + [] + ] + ) + + when: + def combined = combineExecutionResults(result.toSpecification(), incrementalResults) + then: + combined.errors == null + combined.data == [shops : [[departments: [[name: "Department 1"], [name: "Department 2"], [name: "Department 3"]]], + [departments: [[name: "Department 4"], [name: "Department 5"], [name: "Department 6"]]], + [departments: [[name: "Department 7"], [name: "Department 8"], [name: "Department 9"]]]], + expensiveShops: [[name: "ExShop 1"], [name: "ExShop 2"], [name: "ExShop 3"]]] + + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 0 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + @RepeatUntilFailure(maxAttempts = 5, ignoreRest = false) + def "query with multiple deferred fields"() { + given: + def query = getExpensiveQuery(true) + + def expectedInitialData = + [data : [shops : [[name : "Shop 1", + departments: [[name: "Department 1", products: [[name: "Product 1"]]], [name: "Department 2", products: [[name: "Product 2"]]], [name: "Department 3", products: [[name: "Product 3"]]]]], + [name : "Shop 2", + departments: [[name: "Department 4", products: [[name: "Product 4"]]], [name: "Department 5", products: [[name: "Product 5"]]], [name: "Department 6", products: [[name: "Product 6"]]]]], + [name : "Shop 3", + departments: [[name: "Department 7", products: [[name: "Product 7"]]], [name: "Department 8", products: [[name: "Product 8"]]], [name: "Department 9", products: [[name: "Product 9"]]]]]], + expensiveShops: [[name : "ExShop 1", + departments: [[name: "Department 1", products: [[name: "Product 1"]]], [name: "Department 2", products: [[name: "Product 2"]]], [name: "Department 3", products: [[name: "Product 3"]]]]], + [name : "ExShop 2", + departments: [[name: "Department 4", products: [[name: "Product 4"]]], [name: "Department 5", products: [[name: "Product 5"]]], [name: "Department 6", products: [[name: "Product 6"]]]]], + [name : "ExShop 3", + departments: [[name: "Department 7", products: [[name: "Product 7"]]], [name: "Department 8", products: [[name: "Product 8"]]], [name: "Department 9", products: [[name: "Product 9"]]]]]]], + hasNext: true] + + when: + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query(query) + .dataLoaderRegistry(dataLoaderRegistry) + .graphQLContext([(ENABLE_INCREMENTAL_SUPPORT): true]) + .build() + executionInput.getGraphQLContext().putAll(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + + IncrementalExecutionResult result = graphQL.execute(executionInput) + + then: + result.toSpecification() == expectedInitialData + + when: + def incrementalResults = getIncrementalResults(result) + + then: + + assertIncrementalResults(incrementalResults, + [ + ["expensiveShops", 0], ["expensiveShops", 1], ["expensiveShops", 2], + ["shops", 0], ["shops", 1], ["shops", 2], + ["shops", 0, "departments", 0], ["shops", 0, "departments", 1], ["shops", 0, "departments", 2], ["shops", 1, "departments", 0], ["shops", 1, "departments", 1], ["shops", 1, "departments", 2], ["shops", 2, "departments", 0], ["shops", 2, "departments", 1], ["shops", 2, "departments", 2], + ["shops", 0, "expensiveDepartments", 0], ["shops", 0, "expensiveDepartments", 1], ["shops", 0, "expensiveDepartments", 2], ["shops", 1, "expensiveDepartments", 0], ["shops", 1, "expensiveDepartments", 1], ["shops", 1, "expensiveDepartments", 2], ["shops", 2, "expensiveDepartments", 0], ["shops", 2, "expensiveDepartments", 1], ["shops", 2, "expensiveDepartments", 2], + ["expensiveShops", 0, "expensiveDepartments", 0], ["expensiveShops", 0, "expensiveDepartments", 1], ["expensiveShops", 0, "expensiveDepartments", 2], ["expensiveShops", 1, "expensiveDepartments", 0], ["expensiveShops", 1, "expensiveDepartments", 1], ["expensiveShops", 1, "expensiveDepartments", 2], ["expensiveShops", 2, "expensiveDepartments", 0], ["expensiveShops", 2, "expensiveDepartments", 1], ["expensiveShops", 2, "expensiveDepartments", 2], + ["expensiveShops", 0, "departments", 0], ["expensiveShops", 0, "departments", 1], ["expensiveShops", 0, "departments", 2], ["expensiveShops", 1, "departments", 0], ["expensiveShops", 1, "departments", 1], ["expensiveShops", 1, "departments", 2], ["expensiveShops", 2, "departments", 0], ["expensiveShops", 2, "departments", 1], ["expensiveShops", 2, "departments", 2]] + ) + + when: + def combined = combineExecutionResults(result.toSpecification(), incrementalResults) + then: + combined.errors == null + combined.data == expectedExpensiveData + + if (contextKey == ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING) { + // based on the timing of shops vs expensiveShops DF it could be one or two batch loader calls + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 || batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 2 + } else { + batchCompareDataFetchers.departmentsForShopsBatchLoaderCounter.get() == 1 + + } + batchCompareDataFetchers.productsForDepartmentsBatchLoaderCounter.get() == 1 + + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + @Unroll + @RepeatUntilFailure(maxAttempts = 20, ignoreRest = false) + def "dataloader in initial result and chained dataloader inside nested defer block"() { + given: + def sdl = ''' + type Query { + pets: [Pet] + } + + type Pet { + name: String + owner: Owner + } + type Owner { + name: String + address: String + } + + ''' + + def query = ''' + query { + pets { + name + ... @defer { + owner { + name + ... @defer { + address + } + } + } + } + } + ''' + + BatchLoader petNameBatchLoader = { List keys -> + println "petNameBatchLoader called with $keys" + assert keys.size() == 3 + return CompletableFuture.completedFuture(["Pet 1", "Pet 2", "Pet 3"]) + } + BatchLoader addressBatchLoader = { List keys -> + println "addressBatchLoader called with $keys" + return CompletableFuture.completedFuture(keys.collect { it -> + if (it == "owner-1") { + return "Address 1" + } else if (it == "owner-2") { + return "Address 2" + } else if (it == "owner-3") { + return "Address 3" + } + }) + } + + DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry() + def petNameDL = DataLoaderFactory.newDataLoader("petName", petNameBatchLoader) + def addressDL = DataLoaderFactory.newDataLoader("address", addressBatchLoader) + dataLoaderRegistry.register("petName", petNameDL) + dataLoaderRegistry.register("address", addressDL) + + DataFetcher petsDF = { env -> + return [ + [id: "pet-1"], + [id: "pet-2"], + [id: "pet-3"] + ] + } + DataFetcher petNameDF = { env -> + env.getDataLoader("petName").load(env.getSource().id) + } + + DataFetcher petOwnerDF = { env -> + String id = env.getSource().id + if (id == "pet-1") { + return [id: "owner-1", name: "Owner 1"] + } else if (id == "pet-2") { + return [id: "owner-2", name: "Owner 2"] + } else if (id == "pet-3") { + return [id: "owner-3", name: "Owner 3"] + } + } + DataFetcher ownerAddressDF = { env -> + return CompletableFuture.supplyAsync { + Thread.sleep(500) + return "foo" + }.thenCompose { + return env.getDataLoader("address").load(env.getSource().id) + } + .thenCompose { + return env.getDataLoader("address").load(env.getSource().id) + } + } + + def schema = TestUtil.schema(sdl, [Query: [pets: petsDF], + Pet : [name: petNameDF, owner: petOwnerDF], + Owner: [address: ownerAddressDF]]) + def graphQL = GraphQL.newGraphQL(schema).build() + def ei = ExecutionInput.newExecutionInput(query).dataLoaderRegistry(dataLoaderRegistry).build() + ei.getGraphQLContext().put(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT, true) + dataLoaderChainingOrExhaustedDispatching ? ei.getGraphQLContext().put(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, true) : ei.getGraphQLContext().put(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, true) + + when: + CompletableFuture erCF = graphQL.executeAsync(ei) + Awaitility.await().until { erCF.isDone() } + def er = erCF.get() + + then: + er.toSpecification() == [data : [pets: [[name: "Pet 1"], [name: "Pet 2"], [name: "Pet 3"]]], + hasNext: true] + + when: + def incrementalResults = getIncrementalResults(er) + println "incrementalResults: $incrementalResults" + + then: + assertIncrementalResults(incrementalResults, + [ + ["pets", 0], ["pets", 1], ["pets", 2], + ["pets", 0, "owner"], ["pets", 1, "owner"], ["pets", 2, "owner"], + ], + [ + [owner: [name: "Owner 1"]], + [owner: [name: "Owner 2"]], + [owner: [name: "Owner 3"]], + [address: "Address 1"], + [address: "Address 2"], + [address: "Address 3"] + ] + ) + + where: + dataLoaderChainingOrExhaustedDispatching << [true, false] + + } + +} diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/Issue1178DataLoaderDispatchTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/Issue1178DataLoaderDispatchTest.groovy new file mode 100644 index 0000000000..dc0e1c422a --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/Issue1178DataLoaderDispatchTest.groovy @@ -0,0 +1,145 @@ +package graphql.execution.instrumentation.dataloader + +import graphql.ExecutionInput +import graphql.TestUtil +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.StaticDataFetcher +import graphql.schema.idl.RuntimeWiring +import org.awaitility.Awaitility +import org.dataloader.BatchLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import spock.lang.RepeatUntilFailure +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.concurrent.Executors + +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING +import static graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class Issue1178DataLoaderDispatchTest extends Specification { + + + @Unroll + @RepeatUntilFailure(maxAttempts = 100, ignoreRest = false) + def "shouldn't dispatch twice in multithreaded env"() { + setup: + def sdl = """ + type Todo { + id: ID! + related: Todo + related2: Todo + } + + type Query { + getTodos: [Todo] + } + + schema { + query: Query + }""" + + def executor = Executors.newFixedThreadPool(5) + + def dataLoader = DataLoaderFactory.newDataLoader(new BatchLoader() { + @Override + CompletionStage> load(List keys) { + return CompletableFuture.supplyAsync({ + return keys.collect({ [id: 'r' + it] }) + }, executor) + } + }) + def dataLoader2 = DataLoaderFactory.newDataLoader(new BatchLoader() { + @Override + CompletionStage> load(List keys) { + return CompletableFuture.supplyAsync({ + return keys.collect({ [id: 'r' + it] }) + }, executor) + } + }) + + def dataLoaderRegistry = new DataLoaderRegistry() + dataLoaderRegistry.register("todo.related", dataLoader) + dataLoaderRegistry.register("todo.related2", dataLoader2) + + def relatedDf = new MyDataFetcher("todo.related") + def relatedDf2 = new MyDataFetcher("todo.related2") + + def wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("getTodos", new StaticDataFetcher([[id: '1'], [id: '2'], [id: '3'], [id: '4'], [id: '5']]))) + .type(newTypeWiring("Todo") + .dataFetcher("related", relatedDf) + .dataFetcher("related2", relatedDf2)) + .build() + + + when: + def graphql = TestUtil.graphQL(sdl, wiring) + .build() + + then: "execution shouldn't error" + def ei = ExecutionInput.newExecutionInput() + .graphQLContext(contextKey == null ? Collections.emptyMap() : [(contextKey): true]) + .dataLoaderRegistry(dataLoaderRegistry) + .query(""" + query { + getTodos { __typename id + related { id __typename + related { id __typename + related2 { id __typename + related2 { id __typename + related { id __typename } + } + } + } + } + related2 { id __typename + related2 { id __typename + related { id __typename + related { id __typename + related2 { id __typename + related2 { id __typename + related { id __typename } + related2 { id __typename + related2 { id __typename + related { id __typename } + } + } + } + related { id __typename } + } + } + } + } + } + } + }""").build() + def resultCF = graphql.executeAsync(ei) + Awaitility.await().until { resultCF.isDone() } + assert resultCF.get().errors.empty + where: + contextKey << [ENABLE_DATA_LOADER_CHAINING, ENABLE_DATA_LOADER_EXHAUSTED_DISPATCHING, null] + + } + + static class MyDataFetcher implements DataFetcher> { + + private final String name + + MyDataFetcher(String name) { + this.name = name + } + + @Override + CompletableFuture get(DataFetchingEnvironment environment) { + def todo = environment.source as Map + return environment.getDataLoader(name).load(todo['id']) + } + } +} diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/PeopleCompaniesAndProductsDataLoaderTest.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/PeopleCompaniesAndProductsDataLoaderTest.groovy index 343703eb1d..e38f6334b8 100644 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/PeopleCompaniesAndProductsDataLoaderTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/PeopleCompaniesAndProductsDataLoaderTest.groovy @@ -12,13 +12,13 @@ import graphql.schema.DataFetchingEnvironment import graphql.schema.idl.RuntimeWiring import org.dataloader.BatchLoader import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory import org.dataloader.DataLoaderRegistry import spock.lang.Specification import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionStage import java.util.stream.Collectors -import java.util.stream.IntStream import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring @@ -92,13 +92,12 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { DataFetcher productsDF = new DataFetcher() { @Override Object get(DataFetchingEnvironment environment) { - return IntStream.range(0, 5) - .mapToObj( - { id -> - List madeBy = [id * 10001, id * 10002, id * 10003, id * 10004, id * 10005] - new Product(id.toString(), faker.commerce().productName(), id + 200, madeBy) - }) - .collect(Collectors.toList()) + List products = new ArrayList<>(); + for (int id = 0; id < 5; id++) { + List madeBy = [id * 10001, id * 10002, id * 10003, id * 10004, id * 10005] + products.add(new Product(id.toString(), faker.commerce().productName(), id + 200, madeBy)) + } + return products } } @@ -106,9 +105,9 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { @Override Object get(DataFetchingEnvironment environment) { Product source = environment.getSource() - DataLoaderRegistry dlRegistry = environment.getContext() - DataLoader personDL = dlRegistry.getDataLoader("person") - return personDL.load(source.getSuppliedById()) +// DataLoaderRegistry dlRegistry = environment.getGraphQlContext().get("registry") +// DataLoader personDL = dlRegistry.getDataLoader("person") + return environment.getDataLoader("person").load(source.getSuppliedById()) } } @@ -116,10 +115,10 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { @Override Object get(DataFetchingEnvironment environment) { Product source = environment.getSource() - DataLoaderRegistry dlRegistry = environment.getContext() - DataLoader personDL = dlRegistry.getDataLoader("person") +// DataLoaderRegistry dlRegistry = environment.getGraphQlContext().get("registry") +// DataLoader personDL = dlRegistry.getDataLoader("person") - return personDL.loadMany(source.getMadeByIds()) + return environment.getDataLoader("person").loadMany(source.getMadeByIds()) } } @@ -127,9 +126,9 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { @Override Object get(DataFetchingEnvironment environment) { Person source = environment.getSource() - DataLoaderRegistry dlRegistry = environment.getContext() - DataLoader companyDL = dlRegistry.getDataLoader("company") - return companyDL.load(source.getCompanyId()) +// DataLoaderRegistry dlRegistry = environment.getGraphQlContext().get("registry") +// DataLoader companyDL = dlRegistry.getDataLoader("company") + return environment.getDataLoader("company").load(source.getCompanyId()) } } @@ -170,8 +169,8 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { private DataLoaderRegistry buildRegistry() { - DataLoader personDataLoader = new DataLoader<>(personBatchLoader) - DataLoader companyDataLoader = new DataLoader<>(companyBatchLoader) + DataLoader personDataLoader = DataLoaderFactory.newDataLoader(personBatchLoader) + DataLoader companyDataLoader = DataLoaderFactory.newDataLoader(companyBatchLoader) DataLoaderRegistry registry = new DataLoaderRegistry() registry.register("person", personDataLoader) @@ -185,14 +184,15 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { GraphQL graphQL = GraphQL .newGraphQL(graphQLSchema) - .instrumentation(new DataLoaderDispatcherInstrumentation(registry)) .build() when: ExecutionInput executionInput = ExecutionInput.newExecutionInput() .query(query) - .context(registry) + .graphQLContext(["registry": registry]) + .graphQLContext([(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING): enableDataLoaderChaining]) + .dataLoaderRegistry(registry) .build() def executionResult = graphQL.execute(executionInput) @@ -209,5 +209,8 @@ class PeopleCompaniesAndProductsDataLoaderTest extends Specification { companyBatchLoadInvocationCount == 1 + where: + enableDataLoaderChaining << [true, false] + } } diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/StarWarsDataLoaderWiring.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/StarWarsDataLoaderWiring.groovy new file mode 100644 index 0000000000..25189732b4 --- /dev/null +++ b/src/test/groovy/graphql/execution/instrumentation/dataloader/StarWarsDataLoaderWiring.groovy @@ -0,0 +1,160 @@ +package graphql.execution.instrumentation.dataloader + +import graphql.StarWarsData +import graphql.TypeResolutionEnvironment +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLObjectType +import graphql.schema.TypeResolver +import graphql.schema.idl.MapEnumValuesProvider +import graphql.schema.idl.RuntimeWiring +import org.dataloader.BatchLoader +import org.dataloader.DataLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.stream.Collectors + +import static graphql.TestUtil.schemaFile +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +/** + * A helper class that contains the complex wiring used in other tests + */ +class StarWarsDataLoaderWiring { + int rawCharacterLoadCount = 0 + int batchFunctionLoadCount = 0 + int naiveLoadCount = 0 + + Object getCharacterData(String id) { + rawCharacterLoadCount++ + if (StarWarsData.humanData[id] != null) return StarWarsData.humanData[id] + if (StarWarsData.droidData[id] != null) return StarWarsData.droidData[id] + return null + } + + List getCharacterDataViaBatchHTTPApi(List keys) { + keys.stream().map({ id -> getCharacterData(id) }).collect(Collectors.toList()) + } + + // a batch loader function that will be called with N or more keys for batch loading + BatchLoader characterBatchLoader = new BatchLoader() { + @Override + CompletionStage> load(List keys) { + println "loading characters via batch loader for keys: $keys" + batchFunctionLoadCount++ + + // + // direct return of values + //CompletableFuture.completedFuture(getCharacterDataViaBatchHTTPApi(keys)) + // + // or + // + // async supply of values + CompletableFuture.supplyAsync({ + def result = getCharacterDataViaBatchHTTPApi(keys) + println "result " + result + " for keys: $keys" + return result + }) + } + + } + + def newDataLoaderRegistry() { + // a data loader for characters that points to the character batch loader + def characterDataLoader = DataLoaderFactory.newDataLoader(characterBatchLoader) + new DataLoaderRegistry().register("character", characterDataLoader) + } + + // we define the normal StarWars data fetchers so we can point them at our data loader + DataFetcher humanDataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + String id = environment.arguments.id + naiveLoadCount += 1 + environment.getDataLoader("character").load(id) + } + } + + + DataFetcher droidDataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + String id = environment.arguments.id + naiveLoadCount += 1 + environment.getDataLoader("character").load(id) + } + } + + DataFetcher heroDataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + naiveLoadCount += 1 + environment.getDataLoader("character").load('2001') // R2D2 + } + } + + DataFetcher friendsDataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + List friendIds = environment.source.friends + naiveLoadCount += friendIds.size() + + def many = environment.getDataLoader("character").loadMany(friendIds) + many.whenComplete { result, error -> + if (error != null) { + println "Error loading friends: $error" + } else { + println "Loaded friends: $result" + } + } + return many + } + } + + TypeResolver characterTypeResolver = new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + String id = env.getObject().id + if (StarWarsData.humanData[id] != null) + return env.schema.getType("Human") as GraphQLObjectType + if (StarWarsData.droidData[id] != null) + return env.schema.getType("Droid") as GraphQLObjectType + return null + } + } + + + def starWarsWiring() { + def episodeValuesProvider = new MapEnumValuesProvider([NEWHOPE: 4, EMPIRE: 5, JEDI: 6]) + def episodeWiring = newTypeWiring("Episode").enumValues(episodeValuesProvider).build() + + RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("QueryType") + .dataFetchers( + [ + "hero" : heroDataFetcher, + "human": humanDataFetcher, + "droid": droidDataFetcher + ]) + ) + .type(newTypeWiring("Human") + .dataFetcher("friends", friendsDataFetcher) + ) + .type(newTypeWiring("Droid") + .dataFetcher("friends", friendsDataFetcher) + ) + + .type(newTypeWiring("Character") + .typeResolver(characterTypeResolver) + ) + .type(episodeWiring) + .build() + wiring + } + + def schema = schemaFile("starWarsSchema.graphqls", starWarsWiring()) + +} diff --git a/src/test/groovy/graphql/execution/instrumentation/dataloader/TestBatchLoadingSupported.groovy b/src/test/groovy/graphql/execution/instrumentation/dataloader/TestBatchLoadingSupported.groovy deleted file mode 100644 index e4e311b6fe..0000000000 --- a/src/test/groovy/graphql/execution/instrumentation/dataloader/TestBatchLoadingSupported.groovy +++ /dev/null @@ -1,287 +0,0 @@ -package graphql.execution.instrumentation.dataloader - -import graphql.ExecutionInput -import graphql.GraphQL -import graphql.StarWarsData -import graphql.TypeResolutionEnvironment -import graphql.execution.AsyncSerialExecutionStrategy -import graphql.execution.ExecutorServiceExecutionStrategy -import graphql.execution.batched.BatchedExecutionStrategy -import graphql.schema.DataFetcher -import graphql.schema.DataFetchingEnvironment -import graphql.schema.GraphQLObjectType -import graphql.schema.TypeResolver -import graphql.schema.idl.MapEnumValuesProvider -import graphql.schema.idl.RuntimeWiring -import org.dataloader.BatchLoader -import org.dataloader.DataLoader -import org.dataloader.DataLoaderRegistry -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.concurrent.CompletableFuture -import java.util.concurrent.CompletionStage -import java.util.concurrent.ForkJoinPool -import java.util.stream.Collectors - -import static graphql.TestUtil.schemaFile -import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring - -class TestBatchLoadingSupported extends Specification { - - int rawCharacterLoadCount = 0 - int batchFunctionLoadCount = 0 - int naiveLoadCount = 0 - - void setup() { - rawCharacterLoadCount = 0 - batchFunctionLoadCount = 0 - naiveLoadCount = 0 - } - - Object getCharacterData(String id) { - rawCharacterLoadCount++ - if (StarWarsData.humanData[id] != null) return StarWarsData.humanData[id] - if (StarWarsData.droidData[id] != null) return StarWarsData.droidData[id] - return null - } - - List getCharacterDataViaBatchHTTPApi(List keys) { - keys.stream().map({ id -> getCharacterData(id) }).collect(Collectors.toList()) - } - - // a batch loader function that will be called with N or more keys for batch loading - BatchLoader characterBatchLoader = new BatchLoader() { - @Override - CompletionStage> load(List keys) { - batchFunctionLoadCount++ - - // - // direct return of values - //CompletableFuture.completedFuture(getCharacterDataViaBatchHTTPApi(keys)) - // - // or - // - // async supply of values - CompletableFuture.supplyAsync({ - return getCharacterDataViaBatchHTTPApi(keys) - }) - } - - } - - // a data loader for characters that points to the character batch loader - def characterDataLoader = new DataLoader(characterBatchLoader) - - // we define the normal StarWars data fetchers so we can point them at our data loader - DataFetcher humanDataFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - String id = environment.arguments.id - naiveLoadCount += 1 - characterDataLoader.load(id) - } - } - - - DataFetcher droidDataFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - String id = environment.arguments.id - naiveLoadCount += 1 - characterDataLoader.load(id) - } - } - - DataFetcher heroDataFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - naiveLoadCount += 1 - characterDataLoader.load('2001') // R2D2 - } - } - - DataFetcher friendsDataFetcher = new DataFetcher() { - @Override - Object get(DataFetchingEnvironment environment) { - List friendIds = environment.source.friends - naiveLoadCount += friendIds.size() - return characterDataLoader.loadMany(friendIds) - } - } - - TypeResolver characterTypeResolver = new TypeResolver() { - @Override - GraphQLObjectType getType(TypeResolutionEnvironment env) { - String id = env.getObject().id - if (StarWarsData.humanData[id] != null) - return env.schema.getType("Human") as GraphQLObjectType - if (StarWarsData.droidData[id] != null) - return env.schema.getType("Droid") as GraphQLObjectType - return null - } - } - - - def starWarsWiring() { - def episodeValuesProvider = new MapEnumValuesProvider([NEWHOPE: 4, EMPIRE: 5, JEDI: 6]) - def episodeWiring = newTypeWiring("Episode").enumValues(episodeValuesProvider).build() - - RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() - .type(newTypeWiring("QueryType") - .dataFetchers( - [ - "hero" : heroDataFetcher, - "human": humanDataFetcher, - "droid": droidDataFetcher - ]) - ) - .type(newTypeWiring("Human") - .dataFetcher("friends", friendsDataFetcher) - ) - .type(newTypeWiring("Droid") - .dataFetcher("friends", friendsDataFetcher) - ) - - .type(newTypeWiring("Character") - .typeResolver(characterTypeResolver) - ) - .type(episodeWiring) - .build() - wiring - } - - def schema = schemaFile("starWarsSchema.graphqls", starWarsWiring()) - - - def query = """ - query { - hero { - name - friends { - name - friends { - name - } - } - } - } - """ - - def "basic batch loading is possible via instrumentation interception of Execution Strategies"() { - - given: - def dlRegistry = new DataLoaderRegistry().register("characters", characterDataLoader) - def batchingInstrumentation = new DataLoaderDispatcherInstrumentation(dlRegistry) - - def graphql = GraphQL.newGraphQL(schema).instrumentation(batchingInstrumentation).build() - - when: - - def asyncResult = graphql.executeAsync(ExecutionInput.newExecutionInput().query(query)) - - def er = asyncResult.join() - - then: - er.data == [hero: [name: 'R2-D2', friends: [ - [name: 'Luke Skywalker', friends: [ - [name: 'Han Solo'], [name: 'Leia Organa'], [name: 'C-3PO'], [name: 'R2-D2']]], - [name: 'Han Solo', friends: [ - [name: 'Luke Skywalker'], [name: 'Leia Organa'], [name: 'R2-D2']]], - [name: 'Leia Organa', friends: [ - [name: 'Luke Skywalker'], [name: 'Han Solo'], [name: 'C-3PO'], [name: 'R2-D2']]]]] - ] - - // - // there are five characters in this query however we have asked for their details over and over - // and yet we only actually load the objects up five times - rawCharacterLoadCount == 5 - // - // our batch load API only gets called thrice, for R2D2, for his friends and for their friends - batchFunctionLoadCount == 3 - // - // if we didn't have batch loading it would have these many character load calls - naiveLoadCount == 15 - } - - @Unroll - def "ensure DataLoaderDispatcherInstrumentation works for #name"() { - - given: - def dlRegistry = new DataLoaderRegistry().register("characters", characterDataLoader) - - def batchingInstrumentation = new DataLoaderDispatcherInstrumentation(dlRegistry) - - def graphql = GraphQL.newGraphQL(schema) - .queryExecutionStrategy(executionStrategy) - .instrumentation(batchingInstrumentation).build() - - when: - - def asyncResult = graphql.executeAsync(ExecutionInput.newExecutionInput().query(query)) - - def er = asyncResult.join() - - then: - er.data == [hero: [name: 'R2-D2', friends: [ - [name: 'Luke Skywalker', friends: [ - [name: 'Han Solo'], [name: 'Leia Organa'], [name: 'C-3PO'], [name: 'R2-D2']]], - [name: 'Han Solo', friends: [ - [name: 'Luke Skywalker'], [name: 'Leia Organa'], [name: 'R2-D2']]], - [name: 'Leia Organa', friends: [ - [name: 'Luke Skywalker'], [name: 'Han Solo'], [name: 'C-3PO'], [name: 'R2-D2']]]]] - ] - - where: - name | executionStrategy || _ - "AsyncExecutionStrategy" | new AsyncSerialExecutionStrategy() || _ - "AsyncSerialExecutionStrategy" | new AsyncSerialExecutionStrategy() || _ - "BatchedExecutionStrategy" | new BatchedExecutionStrategy() || _ - "ExecutorServiceExecutionStrategy" | new ExecutorServiceExecutionStrategy(ForkJoinPool.commonPool()) || _ - - } - - - def "non list queries work as expected"() { - - given: - def dlRegistry = new DataLoaderRegistry().register("characters", characterDataLoader) - def batchingInstrumentation = new DataLoaderDispatcherInstrumentation(dlRegistry) - - def graphql = GraphQL.newGraphQL(schema).instrumentation(batchingInstrumentation).build() - - when: - def query = """ - query { - arToo : hero { - name - friends { - name - } - } - - tinBox : hero { - name - friends { - name - } - } - } - """ - - def asyncResult = graphql.executeAsync(ExecutionInput.newExecutionInput().query(query)) - - def er = asyncResult.join() - - then: - er.data == [arToo : [name: "R2-D2", friends: [[name: "Luke Skywalker"], [name: "Han Solo"], [name: "Leia Organa"]]], - tinBox: [name: "R2-D2", friends: [[name: "Luke Skywalker"], [name: "Han Solo"], [name: "Leia Organa"]]] - ] - - rawCharacterLoadCount == 4 - batchFunctionLoadCount == 2 - naiveLoadCount == 8 - } - - -} diff --git a/src/test/groovy/graphql/execution/instrumentation/fieldvalidation/FieldValidationTest.groovy b/src/test/groovy/graphql/execution/instrumentation/fieldvalidation/FieldValidationTest.groovy index 759bb3fb62..fc0ae070e6 100644 --- a/src/test/groovy/graphql/execution/instrumentation/fieldvalidation/FieldValidationTest.groovy +++ b/src/test/groovy/graphql/execution/instrumentation/fieldvalidation/FieldValidationTest.groovy @@ -1,16 +1,19 @@ package graphql.execution.instrumentation.fieldvalidation +import graphql.EngineRunningState import graphql.ExecutionInput import graphql.ExecutionResult import graphql.GraphQL import graphql.GraphQLError +import graphql.Profiler import graphql.TestUtil import graphql.execution.AbortExecutionException import graphql.execution.AsyncExecutionStrategy import graphql.execution.Execution import graphql.execution.ExecutionId -import graphql.execution.ExecutionPath -import graphql.execution.instrumentation.SimpleInstrumentation +import graphql.execution.ResultPath +import graphql.execution.ValueUnboxer +import graphql.execution.instrumentation.ChainedInstrumentation import spock.lang.Specification import java.util.concurrent.CompletableFuture @@ -78,7 +81,7 @@ class FieldValidationTest extends Specification { def fieldArgumentsMap = validationEnvironment.getFieldsByPath() - FieldAndArguments field1Args = fieldArgumentsMap.get(ExecutionPath.parse("/field1"))[0] + FieldAndArguments field1Args = fieldArgumentsMap.get(ResultPath.parse("/field1"))[0] argValues = field1Args.getArgumentValuesByName() @@ -88,27 +91,27 @@ class FieldValidationTest extends Specification { assert !argValues.containsKey('intArg') - argValues = fieldArgumentsMap.get(ExecutionPath.parse("/field2"))[0] + argValues = fieldArgumentsMap.get(ResultPath.parse("/field2"))[0] .getArgumentValuesByName() assert argValues['stringArg'] == "stringValue" - argValues = fieldArgumentsMap.get(ExecutionPath.parse("/field3"))[0] + argValues = fieldArgumentsMap.get(ResultPath.parse("/field3"))[0] .getArgumentValuesByName() assert argValues['intArg'] == 666 - assert !fieldArgumentsMap.containsKey(ExecutionPath.parse("/noArgField")) + assert !fieldArgumentsMap.containsKey(ResultPath.parse("/noArgField")) argValues = fieldArgumentsMap.get( - ExecutionPath.parse("/field1/informationLink/informationString"))[0] + ResultPath.parse("/field1/informationLink/informationString"))[0] .getArgumentValuesByName() assert argValues['fmt1'] == "inlineFmt1" // inlined from query assert argValues['fmt2'] == "defaultFmt2" // defaulted from schema def linkLink = fieldArgumentsMap.get( - ExecutionPath.parse("/field1/informationLink/informationLink/informationString"))[0] + ResultPath.parse("/field1/informationLink/informationLink/informationString"))[0] argValues = linkLink .getArgumentValuesByName() @@ -152,12 +155,12 @@ class FieldValidationTest extends Specification { ] SimpleFieldValidation validation = new SimpleFieldValidation() - .addRule(ExecutionPath.parse("/field1"), - { fieldAndArguments, env -> err("Not happy Jan!", env, fieldAndArguments) }) - .addRule(ExecutionPath.parse("/field1/informationLink/informationLink/informationString"), - { fieldAndArguments, env -> err("Also not happy Jan!", env, fieldAndArguments) }) - .addRule(ExecutionPath.parse("/does/not/exist"), - { fieldAndArguments, env -> err("Wont happen", env, fieldAndArguments) }) + .addRule(ResultPath.parse("/field1"), + { fieldAndArguments, env -> err("Not happy Jan!", env, fieldAndArguments) }) + .addRule(ResultPath.parse("/field1/informationLink/informationLink/informationString"), + { fieldAndArguments, env -> err("Also not happy Jan!", env, fieldAndArguments) }) + .addRule(ResultPath.parse("/does/not/exist"), + { fieldAndArguments, env -> err("Wont happen", env, fieldAndArguments) }) when: @@ -201,16 +204,16 @@ class FieldValidationTest extends Specification { ''' SimpleFieldValidation validation = new SimpleFieldValidation() - .addRule(ExecutionPath.parse("/field1/informationString"), - { fieldAndArguments, env -> - def value = fieldAndArguments.getArgumentValue("fmt1") - if (value != "ok") { - return err("Nope : " + value, env, fieldAndArguments) - } else { - return Optional.empty() - } - } - ) + .addRule(ResultPath.parse("/field1/informationString"), + { fieldAndArguments, env -> + def value = fieldAndArguments.getArgumentValue("fmt1") + if (value != "ok") { + return err("Nope : " + value, env, fieldAndArguments) + } else { + return Optional.empty() + } + } + ) when: @@ -247,16 +250,16 @@ class FieldValidationTest extends Specification { ''' SimpleFieldValidation validation = new SimpleFieldValidation() - .addRule(ExecutionPath.parse("/field1/informationString"), - { fieldAndArguments, env -> - String value = fieldAndArguments.getArgumentValue("fmt1") - if (value.contains("alias")) { - return err("Nope : " + value, env, fieldAndArguments) - } else { - return Optional.empty() - } - } - ) + .addRule(ResultPath.parse("/field1/informationString"), + { fieldAndArguments, env -> + String value = fieldAndArguments.getArgumentValue("fmt1") + if (value.contains("alias")) { + return err("Nope : " + value, env, fieldAndArguments) + } else { + return Optional.empty() + } + } + ) when: @@ -304,10 +307,32 @@ class FieldValidationTest extends Specification { def document = TestUtil.parseQuery(query) def strategy = new AsyncExecutionStrategy() def instrumentation = new FieldValidationInstrumentation(validation) - def execution = new Execution(strategy, strategy, strategy, instrumentation) + def execution = new Execution(strategy, strategy, strategy, instrumentation, ValueUnboxer.DEFAULT, false) def executionInput = ExecutionInput.newExecutionInput().query(query).variables(variables).build() - execution.execute(document, schema, ExecutionId.generate(), executionInput, SimpleInstrumentation.INSTANCE.createState()) + execution.execute(document, schema, ExecutionId.generate(), executionInput, null, new EngineRunningState(executionInput, Profiler.NO_OP), Profiler.NO_OP) + } + + def "test graphql from end to end with chained instrumentation"() { + def fieldValidation = new FieldValidation() { + @Override + List validateFields(final FieldValidationEnvironment validationEnvironment) { + return new ArrayList(); + } + } + def instrumentations = [new FieldValidationInstrumentation + (fieldValidation)] + def chainedInstrumentation = new ChainedInstrumentation(instrumentations); + def graphql = GraphQL + .newGraphQL(schema) + .instrumentation(chainedInstrumentation) + .build(); + + when: + def result = graphql.execute("{ field2 }") + + then: + result.getErrors().size() == 0 } } diff --git a/src/test/groovy/graphql/execution/preparsed/NoOpPreparsedDocumentProviderTest.groovy b/src/test/groovy/graphql/execution/preparsed/NoOpPreparsedDocumentProviderTest.groovy index 3e59677dde..1926f0ff77 100644 --- a/src/test/groovy/graphql/execution/preparsed/NoOpPreparsedDocumentProviderTest.groovy +++ b/src/test/groovy/graphql/execution/preparsed/NoOpPreparsedDocumentProviderTest.groovy @@ -1,8 +1,10 @@ package graphql.execution.preparsed + import graphql.language.Document import spock.lang.Specification +import static graphql.ExecutionInput.newExecutionInput class NoOpPreparsedDocumentProviderTest extends Specification { def "NoOp always returns result of compute function"() { @@ -11,10 +13,10 @@ class NoOpPreparsedDocumentProviderTest extends Specification { def documentEntry = new PreparsedDocumentEntry(Document.newDocument().build()) when: - def actual = provider.get("{}", { return documentEntry }) + def actual = provider.getDocumentAsync(newExecutionInput("{}").build(), { return documentEntry }) then: - actual == documentEntry + actual.join() == documentEntry } } diff --git a/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentEntryTest.groovy b/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentEntryTest.groovy index d0484b83fe..4cfa7d0e15 100644 --- a/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentEntryTest.groovy +++ b/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentEntryTest.groovy @@ -33,7 +33,7 @@ class PreparsedDocumentEntryTest extends Specification { def "Ensure a non-null errors returns"() { given: def errors = [new InvalidSyntaxError(new SourceLocation(0, 0), "bang"), - new ValidationError(ValidationErrorType.InvalidSyntax)] + ValidationError.newValidationError().validationErrorType(ValidationErrorType.InvalidSyntax).build()] when: def docEntry = new PreparsedDocumentEntry(errors) @@ -43,6 +43,26 @@ class PreparsedDocumentEntryTest extends Specification { docEntry.errors == errors } + def "Ensure a non-null error returns"() { + given: + def error = new InvalidSyntaxError(new SourceLocation(0, 0), "bang") + + when: + def docEntry = new PreparsedDocumentEntry(error) + + then: + docEntry.document == null + docEntry.errors == Collections.singletonList(error) + } + + def "Ensure a null error throws Exception"() { + when: + new PreparsedDocumentEntry((GraphQLError) null) + + then: + thrown(AssertException) + } + def "Ensure a null errors throws Exception"() { when: new PreparsedDocumentEntry((List) null) @@ -51,13 +71,38 @@ class PreparsedDocumentEntryTest extends Specification { thrown(AssertException) } - def "Ensure a null error throws Exception"() { + def "Ensure a null error and valid document throws Exception"() { + given: + def document = Document.newDocument().build() + when: - new PreparsedDocumentEntry((GraphQLError) null) + new PreparsedDocumentEntry(document, (List) null) + + then: + thrown(AssertException) + } + + def "Ensure a non-null error and null document throws Exception"() { + given: + def error = new InvalidSyntaxError(new SourceLocation(0, 0), "bang") + + when: + new PreparsedDocumentEntry(null, [error]) then: thrown(AssertException) } + def "Ensure a non-null error and non-null document returns"() { + given: + def error = new InvalidSyntaxError(new SourceLocation(0, 0), "bang") + def document = Document.newDocument().build() + when: + def docEntry = new PreparsedDocumentEntry(document, [error]) + + then: + docEntry.document == document + docEntry.errors.get(0) == error + } } diff --git a/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentProviderTest.groovy b/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentProviderTest.groovy index 0dbed69617..fc1eb054f1 100644 --- a/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentProviderTest.groovy +++ b/src/test/groovy/graphql/execution/preparsed/PreparsedDocumentProviderTest.groovy @@ -6,14 +6,19 @@ import graphql.GraphQL import graphql.StarWarsSchema import graphql.execution.AsyncExecutionStrategy import graphql.execution.instrumentation.InstrumentationContext -import graphql.execution.instrumentation.SimpleInstrumentation -import graphql.execution.instrumentation.TestingInstrumentation +import graphql.execution.instrumentation.InstrumentationState +import graphql.execution.instrumentation.LegacyTestingInstrumentation +import graphql.execution.instrumentation.SimplePerformantInstrumentation import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters import graphql.language.Document import spock.lang.Specification +import java.util.concurrent.CompletableFuture import java.util.function.Function +import static graphql.ExecutionInput.newExecutionInput +import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp + class PreparsedDocumentProviderTest extends Specification { def 'Preparse of simple serial execution'() { @@ -34,7 +39,7 @@ class PreparsedDocumentProviderTest extends Specification { "end:fetch-hero", "start:complete-hero", - "start:execution-strategy", + "start:execute-object", "start:field-id", "start:fetch-id", @@ -43,7 +48,7 @@ class PreparsedDocumentProviderTest extends Specification { "end:complete-id", "end:field-id", - "end:execution-strategy", + "end:execute-object", "end:complete-hero", "end:field-hero", @@ -75,7 +80,7 @@ class PreparsedDocumentProviderTest extends Specification { "end:fetch-hero", "start:complete-hero", - "start:execution-strategy", + "start:execute-object", "start:field-id", "start:fetch-id", @@ -84,7 +89,7 @@ class PreparsedDocumentProviderTest extends Specification { "end:complete-id", "end:field-id", - "end:execution-strategy", + "end:execute-object", "end:complete-hero", "end:field-hero", @@ -97,8 +102,8 @@ class PreparsedDocumentProviderTest extends Specification { when: - def instrumentation = new TestingInstrumentation() - def instrumentationPreparsed = new TestingInstrumentation() + def instrumentation = new LegacyTestingInstrumentation() + def instrumentationPreparsed = new LegacyTestingInstrumentation() def preparsedCache = new TestingPreparsedDocumentProvider() def strategy = new AsyncExecutionStrategy() @@ -107,14 +112,14 @@ class PreparsedDocumentProviderTest extends Specification { .instrumentation(instrumentation) .preparsedDocumentProvider(preparsedCache) .build() - .execute(ExecutionInput.newExecutionInput().query(query).build()).data + .execute(newExecutionInput().query(query).build()).data def data2 = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) .queryExecutionStrategy(strategy) .instrumentation(instrumentationPreparsed) .preparsedDocumentProvider(preparsedCache) .build() - .execute(ExecutionInput.newExecutionInput().query(query).build()).data + .execute(newExecutionInput().query(query).build()).data then: @@ -142,12 +147,12 @@ class PreparsedDocumentProviderTest extends Specification { def result1 = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) .preparsedDocumentProvider(preparsedCache) .build() - .execute(ExecutionInput.newExecutionInput().query(query).build()) + .execute(newExecutionInput().query(query).build()) def result2 = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) .preparsedDocumentProvider(preparsedCache) .build() - .execute(ExecutionInput.newExecutionInput().query(query).build()) + .execute(newExecutionInput().query(query).build()) then: "Both the first and the second result should give the same validation error" result1.errors.size() == 1 @@ -158,13 +163,13 @@ class PreparsedDocumentProviderTest extends Specification { result1.errors[0].errorType == result2.errors[0].errorType } - class InputCapturingInstrumentation extends SimpleInstrumentation { + class InputCapturingInstrumentation extends SimplePerformantInstrumentation { ExecutionInput capturedInput @Override - InstrumentationContext beginParse(InstrumentationExecutionParameters parameters) { + InstrumentationContext beginParse(InstrumentationExecutionParameters parameters, InstrumentationState state) { capturedInput = parameters.getExecutionInput() - return super.beginParse(parameters) + return noOp() } } @@ -186,13 +191,15 @@ class PreparsedDocumentProviderTest extends Specification { """ def documentProvider = new PreparsedDocumentProvider() { + @Override - PreparsedDocumentEntry get(String query, Function computeFunction) { - if (query == "#A") { - return computeFunction.apply(queryA) + CompletableFuture getDocumentAsync(ExecutionInput executionInput, Function parseAndValidateFunction) { + if (executionInput.getQuery() == "#A") { + executionInput = executionInput.transform({ it.query(queryA) }) } else { - return computeFunction.apply(queryB) + executionInput = executionInput.transform({ it.query(queryB) }) } + return CompletableFuture.completedFuture(parseAndValidateFunction.apply(executionInput)) } } @@ -201,14 +208,14 @@ class PreparsedDocumentProviderTest extends Specification { .preparsedDocumentProvider(documentProvider) .instrumentation(instrumentationA) .build() - .execute(ExecutionInput.newExecutionInput().query("#A").build()) + .execute(newExecutionInput().query("#A").build()) def instrumentationB = new InputCapturingInstrumentation() def resultB = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) .preparsedDocumentProvider(documentProvider) .instrumentation(instrumentationB) .build() - .execute(ExecutionInput.newExecutionInput().query("#B").build()) + .execute(newExecutionInput().query("#B").build()) expect: diff --git a/src/test/groovy/graphql/execution/preparsed/TestingPreparsedDocumentProvider.groovy b/src/test/groovy/graphql/execution/preparsed/TestingPreparsedDocumentProvider.groovy index c45001cee1..30ae3d4f63 100644 --- a/src/test/groovy/graphql/execution/preparsed/TestingPreparsedDocumentProvider.groovy +++ b/src/test/groovy/graphql/execution/preparsed/TestingPreparsedDocumentProvider.groovy @@ -1,5 +1,8 @@ package graphql.execution.preparsed +import graphql.ExecutionInput + +import java.util.concurrent.CompletableFuture import java.util.function.Function @@ -7,8 +10,9 @@ class TestingPreparsedDocumentProvider implements PreparsedDocumentProvider { private Map cache = new HashMap<>() @Override - PreparsedDocumentEntry get(String query, Function compute) { - return cache.computeIfAbsent(query, compute) + CompletableFuture getDocumentAsync(ExecutionInput executionInput, Function parseAndValidateFunction) { + Function mapCompute = { key -> parseAndValidateFunction.apply(executionInput) } + return CompletableFuture.completedFuture(cache.computeIfAbsent(executionInput.query, mapCompute)) } } diff --git a/src/test/groovy/graphql/execution/preparsed/persisted/ApolloPersistedQuerySupportTest.groovy b/src/test/groovy/graphql/execution/preparsed/persisted/ApolloPersistedQuerySupportTest.groovy new file mode 100644 index 0000000000..7b4a4cc168 --- /dev/null +++ b/src/test/groovy/graphql/execution/preparsed/persisted/ApolloPersistedQuerySupportTest.groovy @@ -0,0 +1,173 @@ +package graphql.execution.preparsed.persisted + +import graphql.ExecutionInput +import graphql.execution.preparsed.PreparsedDocumentEntry +import graphql.parser.Parser +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture +import java.util.function.Function + +import static graphql.execution.preparsed.persisted.PersistedQuerySupport.PERSISTED_QUERY_MARKER +import static graphql.language.AstPrinter.printAstCompact + +class ApolloPersistedQuerySupportTest extends Specification { + + def hashOne = "761cd68b4afb3a824091884dd6cb759b5d068102c293af5a0bc2023bbf8fdb9f" + def hashTwo = "6e0a57aac0c8280588155e6d93436ad313e4c441b4e356703bdc297e32123d8f" + + def knownQueries = [ + (hashOne): "query { oneTwoThree }", + (hashTwo): "query { fourFiveSix }", + badHash : "query { fourFiveSix }" + ] + + // this cache will do a lookup, make the call back on miss and otherwise return cached values. And it + // tracks call counts for assertions + class CacheImplementation implements PersistedQueryCache { + def map = [:] + def keyCount = [:] + def parseCount = [:] + + @Override + CompletableFuture getPersistedQueryDocumentAsync(Object persistedQueryId, ExecutionInput executionInput, PersistedQueryCacheMiss onCacheMiss) throws PersistedQueryNotFound { + keyCount.compute(persistedQueryId, { k, v -> v == null ? 1 : v + 1 }) + PreparsedDocumentEntry entry = map.get(persistedQueryId) as PreparsedDocumentEntry + if (entry != null) { + return CompletableFuture.completedFuture(entry) + } + parseCount.compute(persistedQueryId, { k, v -> v == null ? 1 : v + 1 }) + + def queryText = knownQueries.get(persistedQueryId) + // if its outside our know bounds then throw because we dont have one + if (queryText == null) { + throw new PersistedQueryNotFound(persistedQueryId) + } + def newDocEntry = onCacheMiss.apply(queryText) + map.put(persistedQueryId, newDocEntry) + return CompletableFuture.completedFuture(newDocEntry) + } + } + + + Function engineParser = { + ExecutionInput ei -> + def doc = new Parser().parseDocument(ei.getQuery()) + return new PreparsedDocumentEntry(doc) + } + + + def mkEI(String hash, String query) { + ExecutionInput.newExecutionInput().query(query).extensions([persistedQuery: [sha256Hash: hash]]).build() + } + + def "will call the callback on cache miss and then not after initial caching"() { + CacheImplementation persistedQueryCache = new CacheImplementation() + def apolloSupport = new ApolloPersistedQuerySupport(persistedQueryCache) + + when: + def ei = mkEI(hashOne, PERSISTED_QUERY_MARKER) + def documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + def doc = documentEntry.getDocument() + then: + printAstCompact(doc) == "{oneTwoThree}" + persistedQueryCache.keyCount[hashOne] == 1 + persistedQueryCache.parseCount[hashOne] == 1 + + when: + ei = mkEI(hashOne, PERSISTED_QUERY_MARKER) + documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + doc = documentEntry.getDocument() + + then: + printAstCompact(doc) == "{oneTwoThree}" + persistedQueryCache.keyCount[hashOne] == 2 + persistedQueryCache.parseCount[hashOne] == 1 // only compiled once cause we had it + } + + def "will act as a normal query if there and no hash id present"() { + + CacheImplementation persistedQueryCache = new CacheImplementation() + def apolloSupport = new ApolloPersistedQuerySupport(persistedQueryCache) + + when: + def ei = ExecutionInput.newExecutionInput("query { normal }").build() + def documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + def doc = documentEntry.getDocument() + then: + printAstCompact(doc) == "{normal}" + persistedQueryCache.keyCount.size() == 0 + persistedQueryCache.parseCount.size() == 0 + } + + def "will use query hash in preference to query text"() { + CacheImplementation persistedQueryCache = new CacheImplementation() + def apolloSupport = new ApolloPersistedQuerySupport(persistedQueryCache) + + when: + def ei = mkEI(hashOne, "{normal}") + def documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + def doc = documentEntry.getDocument() + then: + printAstCompact(doc) == "{oneTwoThree}" + persistedQueryCache.keyCount[hashOne] == 1 + persistedQueryCache.parseCount[hashOne] == 1 + + } + + def "will have error if we dont return any query text on cache miss"() { + CacheImplementation persistedQueryCache = new CacheImplementation() + + def apolloSupport = new ApolloPersistedQuerySupport(persistedQueryCache) + + when: + def ei = mkEI("nonExistedHash", PERSISTED_QUERY_MARKER) + def documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + then: + documentEntry.getDocument() == null + def gqlError = documentEntry.getErrors()[0] + gqlError.getMessage() == "PersistedQueryNotFound" + gqlError.getErrorType().toString() == "PersistedQueryNotFound" + gqlError.getExtensions()["persistedQueryId"] == "nonExistedHash" + } + + def "InMemoryPersistedQueryCache implementation works as expected with this class"() { + + InMemoryPersistedQueryCache persistedQueryCache = new InMemoryPersistedQueryCache(knownQueries) + def apolloSupport = new ApolloPersistedQuerySupport(persistedQueryCache) + + when: + def ei = mkEI(hashOne, PERSISTED_QUERY_MARKER) + def documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + def doc = documentEntry.getDocument() + then: + printAstCompact(doc) == "{oneTwoThree}" + + when: + ei = mkEI(hashTwo, PERSISTED_QUERY_MARKER) + documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + doc = documentEntry.getDocument() + then: + printAstCompact(doc) == "{fourFiveSix}" + + when: + ei = mkEI("nonExistent", PERSISTED_QUERY_MARKER) + documentEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + then: + documentEntry.hasErrors() + } + + def "will have error if the calculated sha hash of the query does not match the persistedQueryId"() { + def cache = new CacheImplementation() + def apolloSupport = new ApolloPersistedQuerySupport(cache) + when: + def ei = mkEI("badHash", PERSISTED_QUERY_MARKER) + def docEntry = apolloSupport.getDocumentAsync(ei, engineParser).join() + then: + docEntry.getDocument() == null + def error = docEntry.getErrors()[0] + error.message == "PersistedQueryIdInvalid" + error.errorType.toString() == "PersistedQueryIdInvalid" + error.getExtensions()["persistedQueryId"] == "badHash" + } +} diff --git a/src/test/groovy/graphql/execution/preparsed/persisted/InMemoryPersistedQueryCacheTest.groovy b/src/test/groovy/graphql/execution/preparsed/persisted/InMemoryPersistedQueryCacheTest.groovy new file mode 100644 index 0000000000..bffc4e7d9c --- /dev/null +++ b/src/test/groovy/graphql/execution/preparsed/persisted/InMemoryPersistedQueryCacheTest.groovy @@ -0,0 +1,58 @@ +package graphql.execution.preparsed.persisted + +import graphql.ExecutionInput +import graphql.execution.preparsed.PreparsedDocumentEntry +import graphql.parser.Parser +import spock.lang.Specification + +import static graphql.language.AstPrinter.printAstCompact + +class InMemoryPersistedQueryCacheTest extends Specification { + + def mkEI(String hash, String query) { + ExecutionInput.newExecutionInput().query(query).extensions([persistedQuery: [sha256Hash: hash, version: 1]]).build() + } + + PersistedQueryCacheMiss onMiss = { + String query -> + def doc = new Parser().parseDocument(query) + return new PreparsedDocumentEntry(doc) + } + + def "can be build as expected"() { + def inMemoryPersistedQueryCache = InMemoryPersistedQueryCache.newInMemoryPersistedQueryCache() + .addQuery("hash123", "query { oneTwoThree }") + .addQuery("hash456", "query { fourFiveSix }") + .build() + + when: + def knownQueries = inMemoryPersistedQueryCache.getKnownQueries() + then: + knownQueries == [hash123: "query { oneTwoThree }", hash456: "query { fourFiveSix }"] + } + + def "Uses the query from the execution input if the query ID wasn't in the cache"() { + def inMemCache = InMemoryPersistedQueryCache.newInMemoryPersistedQueryCache().build() + def hash = "thisisahash" + def ei = mkEI(hash, "query { oneTwoThreeFour }") + + when: + def getDoc = inMemCache.getPersistedQueryDocumentAsync(hash, ei, onMiss).join() + def doc = getDoc.document + then: + printAstCompact(doc) == "{oneTwoThreeFour}" + } + + def "When there's a cache miss, uses the query from known queries if the execution input's query is the APQ Marker"() { + def hash = "somehash" + def inMemCache = InMemoryPersistedQueryCache.newInMemoryPersistedQueryCache() + .addQuery(hash, "{foo bar baz}") + .build() + def ei = mkEI(hash, PersistedQuerySupport.PERSISTED_QUERY_MARKER) + when: + def getDoc = inMemCache.getPersistedQueryDocumentAsync(hash, ei, onMiss).join() + def doc = getDoc.document + then: + printAstCompact(doc) == "{foo bar baz}" + } +} diff --git a/src/test/groovy/graphql/execution/pubsub/CapturingSubscriber.java b/src/test/groovy/graphql/execution/pubsub/CapturingSubscriber.java index 97e7d48315..790bac22be 100644 --- a/src/test/groovy/graphql/execution/pubsub/CapturingSubscriber.java +++ b/src/test/groovy/graphql/execution/pubsub/CapturingSubscriber.java @@ -3,9 +3,11 @@ import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; /** * A subscriber that captures each object for testing @@ -13,33 +15,53 @@ public class CapturingSubscriber implements Subscriber { private final List events = new ArrayList<>(); private final AtomicBoolean done = new AtomicBoolean(); + private final AtomicLong creationTime = new AtomicLong(System.nanoTime()); + private final int requestN; private Subscription subscription; private Throwable throwable; + public CapturingSubscriber() { + this(1); + } + + public CapturingSubscriber(int requestN) { + this.requestN = requestN; + } @Override public void onSubscribe(Subscription subscription) { + System.out.println("onSubscribe called at " + delta()); this.subscription = subscription; - subscription.request(1); + subscription.request(requestN); } @Override public void onNext(T t) { - events.add(t); - subscription.request(1); + System.out.println("\tonNext " + t + " called at " + delta()); + synchronized (this) { + events.add(t); + subscription.request(requestN); + } } @Override public void onError(Throwable t) { + System.out.println("onError called at " + delta()); this.throwable = t; done.set(true); } @Override public void onComplete() { + System.out.println("onComplete called at " + delta()); done.set(true); } + private String delta() { + Duration nanos = Duration.ofNanos(System.nanoTime() - creationTime.get()); + return "+" + nanos.toMillis() + "ms"; + } + public List getEvents() { return events; } @@ -51,4 +73,16 @@ public Throwable getThrowable() { public AtomicBoolean isDone() { return done; } + + public boolean isCompleted() { + return done.get() && throwable == null; + } + public boolean isCompletedExceptionally() { + return done.get() && throwable != null; + } + + public Subscription getSubscription() { + return subscription; + } + } diff --git a/src/test/groovy/graphql/execution/pubsub/CapturingSubscription.java b/src/test/groovy/graphql/execution/pubsub/CapturingSubscription.java new file mode 100644 index 0000000000..551a34a119 --- /dev/null +++ b/src/test/groovy/graphql/execution/pubsub/CapturingSubscription.java @@ -0,0 +1,26 @@ +package graphql.execution.pubsub; + +import org.reactivestreams.Subscription; + +public class CapturingSubscription implements Subscription { + private long count = 0; + private boolean cancelled = false; + + public long getCount() { + return count; + } + + public boolean isCancelled() { + return cancelled; + } + + @Override + public void request(long l) { + count += l; + } + + @Override + public void cancel() { + cancelled = true; + } +} diff --git a/src/test/groovy/graphql/execution/pubsub/CommonMessagePublisher.java b/src/test/groovy/graphql/execution/pubsub/CommonMessagePublisher.java new file mode 100644 index 0000000000..b83ff45f24 --- /dev/null +++ b/src/test/groovy/graphql/execution/pubsub/CommonMessagePublisher.java @@ -0,0 +1,44 @@ +package graphql.execution.pubsub; + +import org.reactivestreams.example.unicast.AsyncIterablePublisher; + +import java.util.Iterator; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Function; + +class CommonMessagePublisher { + + protected final AsyncIterablePublisher iterablePublisher; + + protected CommonMessagePublisher(final int count) { + Iterable iterable = mkIterable(count, at -> { + Message message = new Message("sender" + at, "text" + at); + return examineMessage(message, at); + }); + iterablePublisher = new AsyncIterablePublisher<>(iterable, ForkJoinPool.commonPool()); + } + + @SuppressWarnings("unused") + protected Message examineMessage(Message message, Integer at) { + return message; + } + + private static Iterable mkIterable(int count, Function msgMaker) { + return () -> new Iterator<>() { + private int at = 0; + + @Override + public boolean hasNext() { + return at < count; + } + + @Override + public Message next() { + Message message = msgMaker.apply(at); + at++; + return message; + } + }; + } + +} diff --git a/src/test/groovy/graphql/execution/pubsub/CountingFlux.groovy b/src/test/groovy/graphql/execution/pubsub/CountingFlux.groovy new file mode 100644 index 0000000000..64cf0eab5f --- /dev/null +++ b/src/test/groovy/graphql/execution/pubsub/CountingFlux.groovy @@ -0,0 +1,23 @@ +package graphql.execution.pubsub + +import reactor.core.publisher.Flux + +/** + * A flux that counts how many values it has given out + */ +class CountingFlux { + Flux flux + Integer count = 0 + + CountingFlux(List values) { + flux = Flux.generate({ -> 0 }, { Integer counter, sink -> + if (counter >= values.size()) { + sink.complete() + } else { + sink.next(values[counter]) + count++ + } + return counter + 1; + }) + } +} diff --git a/src/test/groovy/graphql/execution/pubsub/FlowMessagePublisher.java b/src/test/groovy/graphql/execution/pubsub/FlowMessagePublisher.java new file mode 100644 index 0000000000..1eb5649899 --- /dev/null +++ b/src/test/groovy/graphql/execution/pubsub/FlowMessagePublisher.java @@ -0,0 +1,22 @@ +package graphql.execution.pubsub; + +import org.reactivestreams.FlowAdapters; + +import java.util.concurrent.Flow; + +/** + * This example publisher will create count "messages" and then terminate. It + * uses the reactive streams TCK as its implementation but presents itself + * as a {@link Flow.Publisher} + */ +public class FlowMessagePublisher extends CommonMessagePublisher implements Flow.Publisher { + + public FlowMessagePublisher(int count) { + super(count); + } + + @Override + public void subscribe(Flow.Subscriber s) { + iterablePublisher.subscribe(FlowAdapters.toSubscriber(s)); + } +} diff --git a/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsMessagePublisher.java b/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsMessagePublisher.java index 796aa22076..81e661188c 100644 --- a/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsMessagePublisher.java +++ b/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsMessagePublisher.java @@ -2,54 +2,20 @@ import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; -import org.reactivestreams.example.unicast.AsyncIterablePublisher; - -import java.util.Iterator; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Function; /** - * This example publisher will create count "messages" and then terminate. Its + * This example publisher will create count "messages" and then terminate. It * uses the reactive streams TCK as its implementation */ -public class ReactiveStreamsMessagePublisher implements Publisher { - - private final AsyncIterablePublisher iterablePublisher; +public class ReactiveStreamsMessagePublisher extends CommonMessagePublisher implements Publisher { public ReactiveStreamsMessagePublisher(final int count) { - Iterable iterable = mkIterable(count, at -> { - Message message = new Message("sender" + at, "text" + at); - return examineMessage(message, at); - }); - iterablePublisher = new AsyncIterablePublisher<>(iterable, ForkJoinPool.commonPool()); + super(count); } @Override public void subscribe(Subscriber s) { iterablePublisher.subscribe(s); } - - @SuppressWarnings("unused") - protected Message examineMessage(Message message, Integer at) { - return message; - } - - private static Iterable mkIterable(int count, Function msgMaker) { - return () -> new Iterator() { - private int at = 0; - - @Override - public boolean hasNext() { - return at < count; - } - - @Override - public Message next() { - Message message = msgMaker.apply(at); - at++; - return message; - } - }; - } - } + diff --git a/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsObjectPublisher.java b/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsObjectPublisher.java new file mode 100644 index 0000000000..ebe1074201 --- /dev/null +++ b/src/test/groovy/graphql/execution/pubsub/ReactiveStreamsObjectPublisher.java @@ -0,0 +1,47 @@ +package graphql.execution.pubsub; + +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import org.reactivestreams.example.unicast.AsyncIterablePublisher; + +import java.util.Iterator; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Function; + +/** + * This example publisher will create count "objects" and then terminate. Its + * uses the reactive streams TCK as its implementation + */ +public class ReactiveStreamsObjectPublisher implements Publisher { + + private final AsyncIterablePublisher iterablePublisher; + + public ReactiveStreamsObjectPublisher(final int count, Function objectMaker) { + Iterable iterable = mkIterable(count, objectMaker); + iterablePublisher = new AsyncIterablePublisher<>(iterable, ForkJoinPool.commonPool()); + } + + @Override + public void subscribe(Subscriber s) { + iterablePublisher.subscribe(s); + } + + private static Iterable mkIterable(int count, Function objectMaker) { + return () -> new Iterator() { + private int at = 0; + + @Override + public boolean hasNext() { + return at < count; + } + + @Override + public Object next() { + Object message = objectMaker.apply(at); + at++; + return message; + } + }; + } + +} diff --git a/src/test/groovy/graphql/execution/pubsub/RxJavaMessagePublisher.java b/src/test/groovy/graphql/execution/pubsub/RxJavaMessagePublisher.java index 7d0be05cb4..0c19e90fa2 100644 --- a/src/test/groovy/graphql/execution/pubsub/RxJavaMessagePublisher.java +++ b/src/test/groovy/graphql/execution/pubsub/RxJavaMessagePublisher.java @@ -4,6 +4,8 @@ import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; +import java.util.concurrent.atomic.AtomicInteger; + /** * This example publisher will create count "messages" and then terminate. Its * uses tRxJava Flowable as a backing publisher @@ -11,10 +13,18 @@ public class RxJavaMessagePublisher implements Publisher { private final Flowable flowable; + private final AtomicInteger counter = new AtomicInteger(); public RxJavaMessagePublisher(final int count) { flowable = Flowable.range(0, count) - .map(at -> examineMessage(new Message("sender" + at, "text" + at), at)); + .map(at -> { + counter.incrementAndGet(); + return examineMessage(new Message("sender" + at, "text" + at), at); + }); + } + + public int getCounter() { + return counter.get(); } @Override diff --git a/src/test/groovy/graphql/execution/reactive/CompletionStageMappingPublisherTest.groovy b/src/test/groovy/graphql/execution/reactive/CompletionStageMappingPublisherTest.groovy index cd2771b605..bc069bcf1e 100644 --- a/src/test/groovy/graphql/execution/reactive/CompletionStageMappingPublisherTest.groovy +++ b/src/test/groovy/graphql/execution/reactive/CompletionStageMappingPublisherTest.groovy @@ -2,6 +2,7 @@ package graphql.execution.reactive import graphql.execution.pubsub.CapturingSubscriber import io.reactivex.Flowable +import org.awaitility.Awaitility import org.reactivestreams.Publisher import spock.lang.Specification @@ -9,9 +10,13 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionStage import java.util.function.Function +/** + * This contains tests for both CompletionStageMappingPublisher and CompletionStageMappingOrderedPublisher because + * they have so much common code + */ class CompletionStageMappingPublisherTest extends Specification { - def "basic mapping"() { + def "basic mapping of #why"() { when: Publisher rxIntegers = Flowable.range(0, 10) @@ -22,7 +27,7 @@ class CompletionStageMappingPublisherTest extends Specification { return CompletableFuture.completedFuture(String.valueOf(integer)) } } - Publisher rxStrings = new CompletionStageMappingPublisher(rxIntegers, mapper) + Publisher rxStrings = creator.call(rxIntegers,mapper) def capturingSubscriber = new CapturingSubscriber<>() rxStrings.subscribe(capturingSubscriber) @@ -30,11 +35,15 @@ class CompletionStageMappingPublisherTest extends Specification { then: capturingSubscriber.events.size() == 10 - capturingSubscriber.events[0] instanceof String - capturingSubscriber.events[0] == "0" + capturingSubscriber.events == ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",] + + where: + why | creator + "CompletionStageMappingPublisher" | { Publisher p, Function> m -> new CompletionStageMappingPublisher(p,m) } + "CompletionStageMappingOrderedPublisher" | { Publisher p, Function> m -> new CompletionStageMappingOrderedPublisher(p,m) } } - def "multiple subscribers get there messages"() { + def "multiple subscribers get there messages for #why"() { when: Publisher rxIntegers = Flowable.range(0, 10) @@ -45,7 +54,7 @@ class CompletionStageMappingPublisherTest extends Specification { return CompletableFuture.completedFuture(String.valueOf(integer)) } } - Publisher rxStrings = new CompletionStageMappingPublisher(rxIntegers, mapper) + Publisher rxStrings = creator.call(rxIntegers,mapper) def capturingSubscriber1 = new CapturingSubscriber<>() def capturingSubscriber2 = new CapturingSubscriber<>() @@ -55,10 +64,20 @@ class CompletionStageMappingPublisherTest extends Specification { then: capturingSubscriber1.events.size() == 10 + // order is kept + capturingSubscriber1.events == ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",] + capturingSubscriber2.events.size() == 10 + // order is kept + capturingSubscriber2.events == ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",] + + where: + why | creator + "CompletionStageMappingPublisher" | { Publisher p, Function> m -> new CompletionStageMappingPublisher(p,m) } + "CompletionStageMappingOrderedPublisher" | { Publisher p, Function> m -> new CompletionStageMappingOrderedPublisher(p,m) } } - def "error handling"() { + def "error handling for #why"() { when: Publisher rxIntegers = Flowable.range(0, 10) @@ -75,7 +94,7 @@ class CompletionStageMappingPublisherTest extends Specification { } } } - Publisher rxStrings = new CompletionStageMappingPublisher(rxIntegers, mapper) + Publisher rxStrings = creator.call(rxIntegers,mapper) def capturingSubscriber = new CapturingSubscriber<>() rxStrings.subscribe(capturingSubscriber) @@ -86,11 +105,16 @@ class CompletionStageMappingPublisherTest extends Specification { // // got this far and cancelled capturingSubscriber.events.size() == 5 + capturingSubscriber.events == ["0", "1", "2", "3", "4",] + where: + why | creator + "CompletionStageMappingPublisher" | { Publisher p, Function> m -> new CompletionStageMappingPublisher(p,m) } + "CompletionStageMappingOrderedPublisher" | { Publisher p, Function> m -> new CompletionStageMappingOrderedPublisher(p,m) } } - def "mapper exception causes onError"() { + def "mapper exception causes onError for #why"() { when: Publisher rxIntegers = Flowable.range(0, 10) @@ -105,7 +129,7 @@ class CompletionStageMappingPublisherTest extends Specification { } } } - Publisher rxStrings = new CompletionStageMappingPublisher(rxIntegers, mapper) + Publisher rxStrings = creator.call(rxIntegers, mapper) def capturingSubscriber = new CapturingSubscriber<>() rxStrings.subscribe(capturingSubscriber) @@ -116,7 +140,51 @@ class CompletionStageMappingPublisherTest extends Specification { // // got this far and cancelled capturingSubscriber.events.size() == 5 + capturingSubscriber.events == ["0", "1", "2", "3", "4",] + + where: + why | creator + "CompletionStageMappingPublisher" | { Publisher p, Function> m -> new CompletionStageMappingPublisher(p,m) } + "CompletionStageMappingOrderedPublisher" | { Publisher p, Function> m -> new CompletionStageMappingOrderedPublisher(p,m) } + + } + + def "asynchronous mapping works with completion"() { + + when: + Publisher rxIntegers = Flowable.range(0, 10) + + Function> mapper = mapperThatDelaysFor(10) + Publisher rxStrings = creator.call(rxIntegers,mapper) + + def capturingSubscriber = new CapturingSubscriber<>() + rxStrings.subscribe(capturingSubscriber) + + then: + + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + capturingSubscriber.events.size() == 10 + capturingSubscriber.events == ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",] + + where: + why | creator + "CompletionStageMappingPublisher" | { Publisher p, Function> m -> new CompletionStageMappingPublisher(p,m) } + "CompletionStageMappingOrderedPublisher" | { Publisher p, Function> m -> new CompletionStageMappingOrderedPublisher(p,m) } + } + + Function> mapperThatDelaysFor(int delay) { + def mapper = new Function>() { + @Override + CompletionStage apply(Integer integer) { + return CompletableFuture.supplyAsync({ + Thread.sleep(delay) + return String.valueOf(integer) + }) + } + } + mapper } } diff --git a/src/test/groovy/graphql/execution/reactive/CompletionStageOrderedSubscriberTest.groovy b/src/test/groovy/graphql/execution/reactive/CompletionStageOrderedSubscriberTest.groovy new file mode 100644 index 0000000000..3438a87d06 --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/CompletionStageOrderedSubscriberTest.groovy @@ -0,0 +1,22 @@ +package graphql.execution.reactive + +import graphql.execution.pubsub.CapturingSubscriber +import graphql.execution.pubsub.CapturingSubscription +import org.reactivestreams.Subscriber + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.function.Function + +class CompletionStageOrderedSubscriberTest extends CompletionStageSubscriberTest { + + @Override + protected Subscriber createSubscriber(Function> mapper, CapturingSubscriber capturingSubscriber) { + return new CompletionStageOrderedSubscriber(mapper, capturingSubscriber) + } + + @Override + protected ArrayList expectedOrderingOfAsyncCompletion() { + return ["0", "1", "2", "3"] + } +} diff --git a/src/test/groovy/graphql/execution/reactive/CompletionStageSubscriberTest.groovy b/src/test/groovy/graphql/execution/reactive/CompletionStageSubscriberTest.groovy new file mode 100644 index 0000000000..45d3d87830 --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/CompletionStageSubscriberTest.groovy @@ -0,0 +1,226 @@ +package graphql.execution.reactive + +import graphql.execution.pubsub.CapturingSubscriber +import graphql.execution.pubsub.CapturingSubscription +import org.reactivestreams.Subscriber +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionStage +import java.util.function.Function + +/** + * This can be used to test the CompletionStageSubscriber and CompletionStageOrderedSubscriber + * since they share so much common code. There are protected helpers to create the subscribers + * and set expectations + */ +class CompletionStageSubscriberTest extends Specification { + + protected Subscriber createSubscriber(Function> mapper, CapturingSubscriber capturingSubscriber) { + def completionStageSubscriber = new CompletionStageSubscriber(mapper, capturingSubscriber) + completionStageSubscriber + } + + protected ArrayList expectedOrderingOfAsyncCompletion() { + ["3", "2", "1", "0"] + } + + def "basic test of mapping"() { + def capturingSubscriber = new CapturingSubscriber<>() + def subscription = new CapturingSubscription() + def mapper = new Function>() { + @Override + CompletionStage apply(Integer integer) { + return CompletableFuture.completedFuture(String.valueOf(integer)) + } + } + Subscriber completionStageSubscriber = createSubscriber(mapper, capturingSubscriber) + + when: + completionStageSubscriber.onSubscribe(subscription) + completionStageSubscriber.onNext(0) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == ["0"] + + when: + completionStageSubscriber.onNext(1) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == ["0", "1"] + + when: + completionStageSubscriber.onComplete() + + then: + !subscription.isCancelled() + capturingSubscriber.isCompleted() + capturingSubscriber.events == ["0", "1"] + } + + def "can hold CFs that have not completed and does not emit them even when onComplete is called"() { + def capturingSubscriber = new CapturingSubscriber<>() + def subscription = new CapturingSubscription() + List promises = [] + Function> mapper = mapperThatDoesNotComplete(promises) + Subscriber completionStageSubscriber = createSubscriber(mapper, capturingSubscriber) + + when: + completionStageSubscriber.onSubscribe(subscription) + completionStageSubscriber.onNext(0) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == [] + + when: + completionStageSubscriber.onNext(1) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == [] + + when: + completionStageSubscriber.onComplete() + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == [] + + when: + promises.forEach { it.run() } + + then: + !subscription.isCancelled() + capturingSubscriber.isCompleted() + capturingSubscriber.events == ["0", "1"] + } + + def "can hold CFs that have not completed but finishes quickly when onError is called"() { + def capturingSubscriber = new CapturingSubscriber<>() + def subscription = new CapturingSubscription() + List promises = [] + Function> mapper = mapperThatDoesNotComplete(promises) + + Subscriber completionStageSubscriber = createSubscriber(mapper, capturingSubscriber) + + when: + completionStageSubscriber.onSubscribe(subscription) + completionStageSubscriber.onNext(0) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == [] + + when: + completionStageSubscriber.onNext(1) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == [] + + when: + completionStageSubscriber.onError(new RuntimeException("Bang")) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.isCompletedExceptionally() + // it immediately errored out + capturingSubscriber.getThrowable().getMessage() == "Bang" + capturingSubscriber.events == [] + + when: + // even if the promises later complete we are done + promises.forEach { it.run() } + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.isCompletedExceptionally() + capturingSubscriber.getThrowable().getMessage() == "Bang" + capturingSubscriber.events == [] + } + + def "if onError is called, then futures are cancelled"() { + def capturingSubscriber = new CapturingSubscriber<>() + def subscription = new CapturingSubscription() + List promises = [] + Function> mapper = mapperThatDoesNotComplete([], promises) + + Subscriber completionStageSubscriber = createSubscriber(mapper, capturingSubscriber) + + when: + completionStageSubscriber.onSubscribe(subscription) + completionStageSubscriber.onNext(0) + completionStageSubscriber.onNext(1) + completionStageSubscriber.onNext(2) + completionStageSubscriber.onNext(3) + completionStageSubscriber.onError(new RuntimeException("Bang")) + + then: + !capturingSubscriber.isCompleted() + capturingSubscriber.isCompletedExceptionally() + capturingSubscriber.events == [] + + promises.size() == 4 + for (CompletableFuture cf : promises) { + assert cf.isCancelled(), "The CF was not cancelled?" + } + } + + + def "ordering test - depends on implementation"() { + def capturingSubscriber = new CapturingSubscriber<>() + def subscription = new CapturingSubscription() + List promises = [] + Function> mapper = mapperThatDoesNotComplete(promises) + + Subscriber completionStageSubscriber = createSubscriber(mapper, capturingSubscriber) + + when: + completionStageSubscriber.onSubscribe(subscription) + completionStageSubscriber.onNext(0) + completionStageSubscriber.onNext(1) + completionStageSubscriber.onNext(2) + completionStageSubscriber.onNext(3) + + then: + !subscription.isCancelled() + !capturingSubscriber.isCompleted() + capturingSubscriber.events == [] + + when: + completionStageSubscriber.onComplete() + promises.reverse().forEach { it.run() } + + then: + !subscription.isCancelled() + capturingSubscriber.isCompleted() + capturingSubscriber.events == expectedOrderingOfAsyncCompletion() + } + + + static Function> mapperThatDoesNotComplete(List runToComplete, List promises = []) { + def mapper = new Function>() { + @Override + CompletionStage apply(Integer integer) { + def cf = new CompletableFuture() + runToComplete.add({ cf.complete(String.valueOf(integer)) }) + promises.add(cf) + return cf + } + } + mapper + } + +} diff --git a/src/test/groovy/graphql/execution/reactive/ReactiveSupportTest.groovy b/src/test/groovy/graphql/execution/reactive/ReactiveSupportTest.groovy new file mode 100644 index 0000000000..145c6d4efe --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/ReactiveSupportTest.groovy @@ -0,0 +1,280 @@ +package graphql.execution.reactive + +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.pubsub.CapturingSubscriber +import graphql.execution.pubsub.CountingFlux +import graphql.schema.DataFetcher +import org.awaitility.Awaitility +import reactor.adapter.JdkFlowAdapter +import reactor.core.publisher.Mono +import spock.lang.Specification + +import java.time.Duration +import java.util.concurrent.CancellationException +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CompletionException +import java.util.concurrent.Flow + +class ReactiveSupportTest extends Specification { + + private static Flow.Publisher toFlow(Mono stringMono) { + return JdkFlowAdapter.publisherToFlowPublisher(stringMono) + } + + private static Mono delayedMono(String X, Integer millis) { + Mono.just(X).delayElement(Duration.ofMillis(millis)) + } + + def "will pass through non reactive things and leave them as is"() { + + when: + def val = ReactiveSupport.fetchedObject("X") + then: + val === "X" + + when: + def cf = CompletableFuture.completedFuture("X") + val = ReactiveSupport.fetchedObject(cf) + then: + val === cf + } + + def "can get a reactive or flow publisher and make a CF from it"() { + + when: + CompletableFuture cf = ReactiveSupport.fetchedObject(reactiveObject) as CompletableFuture + + then: + !cf.isCancelled() + !cf.isCompletedExceptionally() + cf.isDone() + + cf.join() == "X" + + where: + reactiveObject || _ + Mono.just("X") || _ + toFlow(Mono.just("X")) || _ + } + + def "can get a reactive or flow publisher that takes some time and make a CF from it"() { + + when: + CompletableFuture cf = ReactiveSupport.fetchedObject(reactiveObject) as CompletableFuture + + then: + !cf.isCancelled() + !cf.isCompletedExceptionally() + !cf.isDone() + + cf.join() == "X" + + where: + reactiveObject || _ + delayedMono("X", 100) || _ + toFlow(delayedMono("X", 100)) || _ + } + + def "can get a reactive or flow publisher with an error and make a CF from it"() { + + when: + CompletableFuture cf = ReactiveSupport.fetchedObject(reactiveObject) as CompletableFuture + + then: + !cf.isCancelled() + cf.isCompletedExceptionally() + cf.isDone() + + when: + cf.join() + + then: + def e = thrown(CompletionException.class) + e.cause.message == "Bang!" + + where: + reactiveObject || _ + Mono.error(new RuntimeException("Bang!")) || _ + toFlow(Mono.error(new RuntimeException("Bang!"))) || _ + } + + def "can get a empty reactive or flow publisher and make a CF from it"() { + + when: + CompletableFuture cf = ReactiveSupport.fetchedObject(reactiveObject) as CompletableFuture + + then: + !cf.isCancelled() + !cf.isCompletedExceptionally() + cf.isDone() + + cf.join() == null + + where: + reactiveObject || _ + Mono.empty() || _ + toFlow(Mono.empty()) || _ + } + + + def "can get a reactive or flow publisher but cancel it before a value turns up"() { + + when: + CompletableFuture cf = ReactiveSupport.fetchedObject(reactiveObject) as CompletableFuture + + then: + !cf.isCancelled() + !cf.isCompletedExceptionally() + !cf.isDone() + + when: + def cfCancelled = cf.cancel(true) + + then: + cfCancelled + cf.isCancelled() + cf.isCompletedExceptionally() + cf.isDone() + + when: + cf.join() + + then: + thrown(CancellationException.class) + + where: + reactiveObject || _ + delayedMono("X", 1000) || _ + toFlow(delayedMono("X", 1000)) || _ + + } + + + def "can get a reactive Flux and only take one value and make a CF from it"() { + + def xyzStrings = ["X", "Y", "Z"] + when: + def countingFlux = new CountingFlux(xyzStrings) + CompletableFuture cf = ReactiveSupport.fetchedObject(countingFlux.flux) as CompletableFuture + + then: + !cf.isCancelled() + !cf.isCompletedExceptionally() + cf.isDone() + + cf.join() == "X" + countingFlux.count == 1 + + when: + def capturingSubscriber = new CapturingSubscriber<>() + countingFlux.flux.subscribe(capturingSubscriber) + + then: + // second subscriber + capturingSubscriber.events == ["X", "Y", "Z"] + countingFlux.count == 4 + } + + def "integration test showing reactive values in data fetchers as well as the ones we know and love"() { + def sdl = """ + type Query { + reactorField : String + flowField : String + cfField : String + materialisedField : String + } + """ + + // with some delay + def reactorDF = { env -> delayedMono("reactor", 100) } as DataFetcher + def flowDF = { env -> toFlow(delayedMono("flow", 50)) } as DataFetcher + + def cfDF = { env -> CompletableFuture.completedFuture("cf") } as DataFetcher + def materialisedDF = { env -> "materialised" } as DataFetcher + + def schema = TestUtil.schema(sdl, [Query: [ + reactorField : reactorDF, + flowField : flowDF, + cfField : cfDF, + materialisedField: materialisedDF, + ]]) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def er = graphQL.execute(""" + query q { + reactorField + flowField + cfField + materialisedField + } + """) + + then: + er.errors.isEmpty() + er.data == [ + reactorField : "reactor", + flowField : "flow", + cfField : "cf", + materialisedField: "materialised" + ] + } + + def "can be called back when there is a Publisher ends successfully or otherwise"() { + when: + def called = false + def throwable = null + + SingleSubscriberPublisher publisher = new SingleSubscriberPublisher<>() + def publisherFinishes = ReactiveSupport.whenPublisherFinishes(publisher, { t -> + throwable = t + called = true + }) + + + def capturingSubscriber = new CapturingSubscriber() + publisherFinishes.subscribe(capturingSubscriber) + + publisher.offer("a") + publisher.offer("b") + publisher.offer("c") + publisher.noMoreData() + + then: + + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + capturingSubscriber.events["a", "b", "c"] + + called + throwable == null + + when: "it has an error thrown" + + called = false + throwable = null + + publisher = new SingleSubscriberPublisher<>() + publisherFinishes = ReactiveSupport.whenPublisherFinishes(publisher, { t -> + throwable = t + called = true + }) + + + capturingSubscriber = new CapturingSubscriber() + publisherFinishes.subscribe(capturingSubscriber) + + publisher.offer("a") + publisher.offerError(new RuntimeException("BANG")) + + then: + + Awaitility.await().untilTrue(capturingSubscriber.isDone()) + + capturingSubscriber.events == ["a"] + + called + throwable.message == "BANG" + } +} diff --git a/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingOrderedPublisherRandomCompleteTckVerificationTest.java b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingOrderedPublisherRandomCompleteTckVerificationTest.java new file mode 100644 index 0000000000..19ebffc466 --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingOrderedPublisherRandomCompleteTckVerificationTest.java @@ -0,0 +1,70 @@ +package graphql.execution.reactive.tck; + +import graphql.execution.reactive.CompletionStageMappingOrderedPublisher; +import io.reactivex.Flowable; +import org.jspecify.annotations.NonNull; +import org.reactivestreams.Publisher; +import org.reactivestreams.tck.PublisherVerification; +import org.reactivestreams.tck.TestEnvironment; +import org.testng.annotations.Test; + +import java.time.Duration; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.function.Function; + +/** + * This uses the reactive streams TCK to test that our CompletionStageMappingPublisher meets spec + * when it's got CFs that complete at different times + */ +@Test +public class CompletionStageMappingOrderedPublisherRandomCompleteTckVerificationTest extends PublisherVerification { + + public CompletionStageMappingOrderedPublisherRandomCompleteTckVerificationTest() { + super(new TestEnvironment(Duration.ofMillis(100).toMillis())); + } + + @Override + public long maxElementsFromPublisher() { + return 10000; + } + + @Override + public Publisher createPublisher(long elements) { + Publisher publisher = Flowable.range(0, (int) elements); + Function> mapper = mapperFunc(); + return new CompletionStageMappingOrderedPublisher<>(publisher, mapper); + } + @Override + public Publisher createFailedPublisher() { + Publisher publisher = Flowable.error(() -> new RuntimeException("Bang")); + Function> mapper = mapperFunc(); + return new CompletionStageMappingOrderedPublisher<>(publisher, mapper); + } + + public boolean skipStochasticTests() { + return true; + } + + @NonNull + private static Function> mapperFunc() { + return i -> CompletableFuture.supplyAsync(() -> { + int ms = rand(0, 5); + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + return i + "!"; + }); + } + + static Random rn = new Random(); + + private static int rand(int min, int max) { + return rn.nextInt(max - min + 1) + min; + } + +} + diff --git a/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingOrderedPublisherTckVerificationTest.java b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingOrderedPublisherTckVerificationTest.java new file mode 100644 index 0000000000..b1b8689190 --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingOrderedPublisherTckVerificationTest.java @@ -0,0 +1,51 @@ +package graphql.execution.reactive.tck; + +import graphql.execution.reactive.CompletionStageMappingOrderedPublisher; +import io.reactivex.Flowable; +import org.reactivestreams.Publisher; +import org.reactivestreams.tck.PublisherVerification; +import org.reactivestreams.tck.TestEnvironment; +import org.testng.annotations.Test; + +import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executors; +import java.util.function.Function; + +/** + * This uses the reactive streams TCK to test that our CompletionStageMappingPublisher meets spec + * when it's got CFs that complete off thread + */ +@Test +public class CompletionStageMappingOrderedPublisherTckVerificationTest extends PublisherVerification { + + public CompletionStageMappingOrderedPublisherTckVerificationTest() { + super(new TestEnvironment(Duration.ofMillis(1000).toMillis())); + } + + @Override + public long maxElementsFromPublisher() { + return 10000; + } + + @Override + public Publisher createPublisher(long elements) { + Publisher publisher = Flowable.range(0, (int) elements); + Function> mapper = i -> CompletableFuture.supplyAsync(() -> i + "!", Executors.newSingleThreadExecutor()); + return new CompletionStageMappingOrderedPublisher<>(publisher, mapper); + } + + @Override + public Publisher createFailedPublisher() { + Publisher publisher = Flowable.error(() -> new RuntimeException("Bang")); + Function> mapper = i -> CompletableFuture.supplyAsync(() -> i + "!", Executors.newSingleThreadExecutor()); + return new CompletionStageMappingOrderedPublisher<>(publisher, mapper); + } + + @Override + public boolean skipStochasticTests() { + return true; + } +} + diff --git a/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingPublisherRandomCompleteTckVerificationTest.java b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingPublisherRandomCompleteTckVerificationTest.java new file mode 100644 index 0000000000..889b18eeeb --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingPublisherRandomCompleteTckVerificationTest.java @@ -0,0 +1,70 @@ +package graphql.execution.reactive.tck; + +import graphql.execution.reactive.CompletionStageMappingPublisher; +import io.reactivex.Flowable; +import org.jspecify.annotations.NonNull; +import org.reactivestreams.Publisher; +import org.reactivestreams.tck.PublisherVerification; +import org.reactivestreams.tck.TestEnvironment; +import org.testng.annotations.Test; + +import java.time.Duration; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.function.Function; + +/** + * This uses the reactive streams TCK to test that our CompletionStageMappingPublisher meets spec + * when it's got CFs that complete at different times + */ +@Test +public class CompletionStageMappingPublisherRandomCompleteTckVerificationTest extends PublisherVerification { + + public CompletionStageMappingPublisherRandomCompleteTckVerificationTest() { + super(new TestEnvironment(Duration.ofMillis(100).toMillis())); + } + + @Override + public long maxElementsFromPublisher() { + return 10000; + } + + @Override + public Publisher createPublisher(long elements) { + Publisher publisher = Flowable.range(0, (int) elements); + Function> mapper = mapperFunc(); + return new CompletionStageMappingPublisher<>(publisher, mapper); + } + @Override + public Publisher createFailedPublisher() { + Publisher publisher = Flowable.error(() -> new RuntimeException("Bang")); + Function> mapper = mapperFunc(); + return new CompletionStageMappingPublisher<>(publisher, mapper); + } + + public boolean skipStochasticTests() { + return true; + } + + @NonNull + private static Function> mapperFunc() { + return i -> CompletableFuture.supplyAsync(() -> { + int ms = rand(0, 5); + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + return i + "!"; + }); + } + + static Random rn = new Random(); + + private static int rand(int min, int max) { + return rn.nextInt(max - min + 1) + min; + } + +} + diff --git a/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingPublisherTckVerificationTest.java b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingPublisherTckVerificationTest.java new file mode 100644 index 0000000000..f68c7d3fab --- /dev/null +++ b/src/test/groovy/graphql/execution/reactive/tck/CompletionStageMappingPublisherTckVerificationTest.java @@ -0,0 +1,51 @@ +package graphql.execution.reactive.tck; + +import graphql.execution.reactive.CompletionStageMappingPublisher; +import io.reactivex.Flowable; +import org.reactivestreams.Publisher; +import org.reactivestreams.tck.PublisherVerification; +import org.reactivestreams.tck.TestEnvironment; +import org.testng.annotations.Test; + +import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executors; +import java.util.function.Function; + +/** + * This uses the reactive streams TCK to test that our CompletionStageMappingPublisher meets spec + * when it's got CFs that complete off thread + */ +@Test +public class CompletionStageMappingPublisherTckVerificationTest extends PublisherVerification { + + public CompletionStageMappingPublisherTckVerificationTest() { + super(new TestEnvironment(Duration.ofMillis(1000).toMillis())); + } + + @Override + public long maxElementsFromPublisher() { + return 10000; + } + + @Override + public Publisher createPublisher(long elements) { + Publisher publisher = Flowable.range(0, (int) elements); + Function> mapper = i -> CompletableFuture.supplyAsync(() -> i + "!", Executors.newSingleThreadExecutor()); + return new CompletionStageMappingPublisher<>(publisher, mapper); + } + + @Override + public Publisher createFailedPublisher() { + Publisher publisher = Flowable.error(() -> new RuntimeException("Bang")); + Function> mapper = i -> CompletableFuture.supplyAsync(() -> i + "!"); + return new CompletionStageMappingPublisher<>(publisher, mapper); + } + + @Override + public boolean skipStochasticTests() { + return true; + } +} + diff --git a/src/test/groovy/graphql/execution/reactive/SingleSubscriberPublisherTckVerificationTest.java b/src/test/groovy/graphql/execution/reactive/tck/SingleSubscriberPublisherTckVerificationTest.java similarity index 89% rename from src/test/groovy/graphql/execution/reactive/SingleSubscriberPublisherTckVerificationTest.java rename to src/test/groovy/graphql/execution/reactive/tck/SingleSubscriberPublisherTckVerificationTest.java index 73f1615df0..472cbaa357 100644 --- a/src/test/groovy/graphql/execution/reactive/SingleSubscriberPublisherTckVerificationTest.java +++ b/src/test/groovy/graphql/execution/reactive/tck/SingleSubscriberPublisherTckVerificationTest.java @@ -1,14 +1,17 @@ -package graphql.execution.reactive; +package graphql.execution.reactive.tck; +import graphql.execution.reactive.SingleSubscriberPublisher; import org.reactivestreams.Publisher; import org.reactivestreams.tck.PublisherVerification; import org.reactivestreams.tck.TestEnvironment; +import org.testng.annotations.Test; import java.time.Duration; /** * This uses the reactive streams TCK to test that our implementation meets spec */ +@Test public class SingleSubscriberPublisherTckVerificationTest extends PublisherVerification { public SingleSubscriberPublisherTckVerificationTest() { diff --git a/src/test/groovy/graphql/execution/values/InputInterceptorTest.groovy b/src/test/groovy/graphql/execution/values/InputInterceptorTest.groovy new file mode 100644 index 0000000000..f259714b82 --- /dev/null +++ b/src/test/groovy/graphql/execution/values/InputInterceptorTest.groovy @@ -0,0 +1,137 @@ +package graphql.execution.values + +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.GraphQLContext +import graphql.Scalars +import graphql.TestUtil +import graphql.execution.RawVariables +import graphql.execution.ValuesResolver +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLInputType +import spock.lang.Specification + +import static graphql.language.TypeName.newTypeName +import static graphql.language.VariableDefinition.newVariableDefinition + +class InputInterceptorTest extends Specification { + + def sdl = """ + type Query { + f(inputArg : InputArg, intArg : Int, stringArg : String,booleanArg : Boolean) : String + } + + input InputArg { + intArg : Int + stringArg : String + booleanArg : Boolean + } + """ + + def schema = TestUtil.schema(sdl) + + InputInterceptor interceptor = new InputInterceptor() { + @Override + Object intercept(Object value, GraphQLInputType graphQLType, GraphQLContext graphqlContext, Locale locale) { + if (graphQLType == Scalars.GraphQLBoolean) { + return "truthy" == value ? false : value + } + if (graphQLType == Scalars.GraphQLString) { + return String.valueOf(value).reverse() + } + return value + } + } + + + def "the input interceptor can be called"() { + def inputArgDef = newVariableDefinition("inputArg", + newTypeName("InputArg").build()).build() + def booleanArgDef = newVariableDefinition("booleanArg", + newTypeName("Boolean").build()).build() + def stringArgDef = newVariableDefinition("stringArg", + newTypeName("String").build()).build() + + def graphQLContext = GraphQLContext.newContext() + .put(InputInterceptor.class, interceptor).build() + + when: + def coercedVariables = ValuesResolver.coerceVariableValues( + this.schema, + [inputArgDef, booleanArgDef, stringArgDef], + RawVariables.of([ + "booleanArg": "truthy", + "stringArg" : "sdrawkcab", + "inputArg" : [ + "stringArg": "sdrawkcab osla" + ] + ]), + graphQLContext, + Locale.CANADA + ) + + then: + coercedVariables.toMap() == [ + "booleanArg": false, + "stringArg" : "backwards", + "inputArg" : [ + "stringArg": "also backwards" + ] + ] + } + + def "integration test of interceptor being called"() { + DataFetcher df = { DataFetchingEnvironment env -> + return env.getArguments().entrySet() + .collect({ String.valueOf(it.key) + ":" + String.valueOf(it.value) }) + .join(" ") + } + def schema = TestUtil.schema(sdl, ["Query": ["f": df]]) + def graphQL = GraphQL.newGraphQL(schema).build() + def ei = ExecutionInput.newExecutionInput().query(''' + query q($booleanArg : Boolean, $stringArg : String) { + f(booleanArg : $booleanArg, stringArg : $stringArg) + } + ''') + .graphQLContext({ it.put(InputInterceptor.class, interceptor) }) + .variables( + "booleanArg": false, + "stringArg": "sdrawkcab" + + ) + .build() + + when: + def er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + er.data == [f: "stringArg:backwards booleanArg:false"] + } + + + def "integration test showing the presence of an interceptor wont stop scalar coercing"() { + def schema = TestUtil.schema(sdl) + def graphQL = GraphQL.newGraphQL(schema).build() + def ei = ExecutionInput.newExecutionInput().query(''' + query q($booleanArg : Boolean, $stringArg : String) { + f(booleanArg : $booleanArg, stringArg : $stringArg) + } + ''') + .graphQLContext({ it.put(InputInterceptor.class, interceptor) }) + .variables( + "booleanArg": [not: "a boolean"], + "stringArg": "sdrawkcab" + + ) + .build() + + when: + def er = graphQL.execute(ei) + + then: + !er.errors.isEmpty() + er.errors[0].message == "Variable 'booleanArg' has an invalid value: Expected a Boolean input, but it was a 'LinkedHashMap'" + } +} diff --git a/src/test/groovy/graphql/execution/values/legacycoercing/LegacyCoercingInputInterceptorTest.groovy b/src/test/groovy/graphql/execution/values/legacycoercing/LegacyCoercingInputInterceptorTest.groovy new file mode 100644 index 0000000000..90a46bb1ed --- /dev/null +++ b/src/test/groovy/graphql/execution/values/legacycoercing/LegacyCoercingInputInterceptorTest.groovy @@ -0,0 +1,201 @@ +package graphql.execution.values.legacycoercing + +import graphql.GraphQLContext +import graphql.schema.GraphQLInputType +import spock.lang.Specification + +import java.util.function.BiConsumer + +import static graphql.Scalars.GraphQLBoolean +import static graphql.Scalars.GraphQLFloat +import static graphql.Scalars.GraphQLInt +import static graphql.Scalars.GraphQLString + +class LegacyCoercingInputInterceptorTest extends Specification { + + def "can detect legacy boolean values"() { + when: + def isLegacyValue = LegacyCoercingInputInterceptor.isLegacyValue(input, inputType) + then: + isLegacyValue == expected + + where: + input | inputType | expected + "true" | GraphQLBoolean | true + "false" | GraphQLBoolean | true + "TRUE" | GraphQLBoolean | true + "FALSE" | GraphQLBoolean | true + "junk" | GraphQLBoolean | true + // not acceptable to the old + true | GraphQLBoolean | false + false | GraphQLBoolean | false + ["rubbish"] | GraphQLBoolean | false + } + + def "can change legacy boolean values"() { + def interceptor = LegacyCoercingInputInterceptor.migratesValues() + when: + def value = interceptor.intercept(input, inputType, GraphQLContext.getDefault(), Locale.getDefault()) + then: + value == expected + + where: + input | inputType | expected + "true" | GraphQLBoolean | true + "false" | GraphQLBoolean | false + "TRUE" | GraphQLBoolean | true + "FALSE" | GraphQLBoolean | false + + // left alone + "junk" | GraphQLBoolean | "junk" + true | GraphQLBoolean | true + false | GraphQLBoolean | false + ["rubbish"] | GraphQLBoolean | ["rubbish"] + } + + def "can detect legacy float values"() { + when: + def isLegacyValue = LegacyCoercingInputInterceptor.isLegacyValue(input, inputType) + then: + isLegacyValue == expected + + where: + input | inputType | expected + "1.0" | GraphQLFloat | true + "1" | GraphQLFloat | true + "junk" | GraphQLFloat | true + // not acceptable to the old + 666.0F | GraphQLFloat | false + 666 | GraphQLFloat | false + ["rubbish"] | GraphQLFloat | false + } + + def "can change legacy float values"() { + def interceptor = LegacyCoercingInputInterceptor.migratesValues() + when: + def value = interceptor.intercept(input, inputType, GraphQLContext.getDefault(), Locale.getDefault()) + then: + value == expected + + where: + input | inputType | expected + "1.0" | GraphQLFloat | 1.0F + "1" | GraphQLFloat | 1.0F + + // left alone + "junk" | GraphQLFloat | "junk" + 666.0F | GraphQLFloat | 666.0F + 666 | GraphQLFloat | 666 + ["rubbish"] | GraphQLFloat | ["rubbish"] + } + + def "can detect legacy int values"() { + when: + def isLegacyValue = LegacyCoercingInputInterceptor.isLegacyValue(input, inputType) + then: + isLegacyValue == expected + + where: + input | inputType | expected + "1.0" | GraphQLInt | true + "1" | GraphQLInt | true + "junk" | GraphQLInt | true + // not acceptable to the old + 666.0F | GraphQLInt | false + 666 | GraphQLInt | false + ["rubbish"] | GraphQLInt | false + } + + def "can change legacy int values"() { + def interceptor = LegacyCoercingInputInterceptor.migratesValues() + when: + def value = interceptor.intercept(input, inputType, GraphQLContext.getDefault(), Locale.getDefault()) + then: + value == expected + + where: + input | inputType | expected + "1.0" | GraphQLInt | 1 + "1" | GraphQLInt | 1 + + // left alone + "junk" | GraphQLInt | "junk" + 666.0F | GraphQLInt | 666.0F + 666 | GraphQLInt | 666 + ["rubbish"] | GraphQLInt | ["rubbish"] + } + + def "can detect legacy String values"() { + when: + def isLegacyValue = LegacyCoercingInputInterceptor.isLegacyValue(input, inputType) + then: + isLegacyValue == expected + + where: + input | inputType | expected + 666.0F | GraphQLString | true + 666 | GraphQLString | true + ["rubbish"] | GraphQLString | true + + // strings that are strings dont need to change + "xyz" | GraphQLString | false + "abc" | GraphQLString | false + "junk" | GraphQLString | false + + } + + def "can change legacy String values"() { + def interceptor = LegacyCoercingInputInterceptor.migratesValues() + when: + def value = interceptor.intercept(input, inputType, GraphQLContext.getDefault(), Locale.getDefault()) + then: + value == expected + where: + // its just String.valueOf() + input | inputType | expected + "xyz" | GraphQLString | "xyz" + "abc" | GraphQLString | "abc" + "junk" | GraphQLString | "junk" + 666.0F | GraphQLString | "666.0" + 666 | GraphQLString | "666" + ["rubbish"] | GraphQLString | "[rubbish]" + } + + def "can observe values "() { + def lastValue = null + def lastType = null + + def callback = new BiConsumer() { + @Override + void accept(Object o, GraphQLInputType graphQLInputType) { + lastValue = o + lastType = graphQLInputType + } + } + def interceptor = LegacyCoercingInputInterceptor.observesValues(callback) + when: + lastValue = null + lastType = null + def value = interceptor.intercept(input, inputType, GraphQLContext.getDefault(), Locale.getDefault()) + + then: + // nothing changes - it observes only + value == input + lastValue == expectedLastValue + lastType == expectedLastType + + where: + input | inputType | expectedLastValue | expectedLastType + "true" | GraphQLBoolean | "true" | GraphQLBoolean + "1.0" | GraphQLFloat | "1.0" | GraphQLFloat + "1" | GraphQLInt | "1" | GraphQLInt + 1 | GraphQLString | 1 | GraphQLString + + // no observation if its not needed + true | GraphQLBoolean | null | null + 1.0F | GraphQLFloat | null | null + 1 | GraphQLInt | null | null + "x" | GraphQLString | null | null + + } +} diff --git a/src/test/groovy/graphql/extensions/DefaultExtensionsMergerTest.groovy b/src/test/groovy/graphql/extensions/DefaultExtensionsMergerTest.groovy new file mode 100644 index 0000000000..4714e4636a --- /dev/null +++ b/src/test/groovy/graphql/extensions/DefaultExtensionsMergerTest.groovy @@ -0,0 +1,79 @@ +package graphql.extensions + +import com.google.common.collect.ImmutableMap +import spock.lang.Specification + +class DefaultExtensionsMergerTest extends Specification { + + def merger = new DefaultExtensionsMerger() + + def "can merge maps"() { + + when: + def actual = merger.merge(leftMap, rightMap) + then: + actual == expected + where: + leftMap | rightMap | expected + [:] | [:] | ImmutableMap.of() + ImmutableMap.of() | ImmutableMap.of() | ImmutableMap.of() + // additive + [x: [firstName: "Brad"]] | [y: [lastName: "Baker"]] | [x: [firstName: "Brad"], y: [lastName: "Baker"]] + [x: "24", y: "25", z: "26"] | [a: "1", b: "2", c: "3"] | [x: "24", y: "25", z: "26", a: "1", b: "2", c: "3"] + // merge + [key1: [firstName: "Brad"]] | [key1: [lastName: "Baker"]] | [key1: [firstName: "Brad", lastName: "Baker"]] + + // merge with right extra key + [key1: [firstName: "Brad", middleName: "Leon"]] | [key1: [lastName: "Baker"], key2: [hobby: "graphql-java"]] | [key1: [firstName: "Brad", middleName: "Leon", lastName: "Baker"], key2: [hobby: "graphql-java"]] + + } + + def "can handle null entries"() { + + when: + def actual = merger.merge(leftMap, rightMap) + then: + actual == expected + where: + leftMap | rightMap | expected + // nulls + [x: [firstName: "Brad"]] | [y: [lastName: null]] | [x: [firstName: "Brad"], y: [lastName: null]] + } + + def "prefers the right on conflict"() { + + when: + def actual = merger.merge(leftMap, rightMap) + then: + actual == expected + where: + leftMap | rightMap | expected + [x: [firstName: "Brad"]] | [x: [firstName: "Donna"]] | [x: [firstName: "Donna"]] + [x: [firstName: "Brad"]] | [x: [firstName: "Donna", seenStarWars: true]] | [x: [firstName: "Donna", seenStarWars: true]] + [x: [firstName: "Brad", hates: "Python"]] | [x: [firstName: "Donna", seenStarWars: true]] | [x: [firstName: "Donna", hates: "Python", seenStarWars: true]] + + + // disparate types dont matter - it prefers the right + [x: [firstName: "Brad"]] | [x: [firstName: [salutation: "Queen", name: "Donna"]]] | [x: [firstName: [salutation: "Queen", name: "Donna"]]] + + } + + def "it appends to lists"() { + + when: + def actual = merger.merge(leftMap, rightMap) + then: + actual == expected + where: + leftMap | rightMap | expected + [x: [1, 2, 3, 4]] | [x: [5, 6, 7, 8]] | [x: [1, 2, 3, 4, 5, 6, 7, 8]] + // + // truly additive - no object equality + [x: [1, 2, 3]] | [x: [1, 2, 3]] | [x: [1, 2, 3, 1, 2, 3]] + [x: []] | [x: [1, 2, 3]] | [x: [1, 2, 3]] + [x: [null]] | [x: [1, 2, 3]] | [x: [null, 1, 2, 3]] + // + // prefers right if they are not both lists + [x: null] | [x: [1, 2, 3]] | [x: [1, 2, 3]] + } +} diff --git a/src/test/groovy/graphql/extensions/ExtensionsBuilderTest.groovy b/src/test/groovy/graphql/extensions/ExtensionsBuilderTest.groovy new file mode 100644 index 0000000000..e08a09b777 --- /dev/null +++ b/src/test/groovy/graphql/extensions/ExtensionsBuilderTest.groovy @@ -0,0 +1,281 @@ +package graphql.extensions + +import graphql.ExecutionResult +import graphql.TestUtil +import graphql.execution.DataFetcherResult +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLTypeUtil +import spock.lang.Specification + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.extensions.ExtensionsBuilder.newExtensionsBuilder +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class ExtensionsBuilderTest extends Specification { + + + def "can merge changes with default behavior"() { + when: + def extensions = newExtensionsBuilder().addValue("x", "24") + .addValues([y: "25", z: "26"]) + .addValues([x: "overwrite"]) + .buildExtensions() + then: + extensions == [x: "overwrite", y: "25", z: "26"] + + when: + extensions = newExtensionsBuilder().addValue("x", "24") + .addValues([y: "25", z: "26"]) + .addValues([x: "overwrite"]) + .addValues([x: "overwrite2"]) + .addValues([x: "overwrite2"]) + .addValue("x", "overwrite3") + .addValue("z", "overwriteZ") + .addValues([a: "1"]) + .buildExtensions() + then: + extensions == [x: "overwrite3", y: "25", z: "overwriteZ", a: "1"] + } + + def "wont add empty changes"() { + def builder = newExtensionsBuilder() + when: + builder.addValues([:]) + + then: + builder.getChangeCount() == 0 + + when: + builder.addValues([:]) + + then: + builder.getChangeCount() == 0 + + when: + def extensions = builder.buildExtensions() + then: + extensions.isEmpty() + + } + + def "can handle no changes"() { + when: + def extensions = newExtensionsBuilder() + .buildExtensions() + then: + extensions == [:] + } + + def "can handle one changes"() { + when: + def extensions = newExtensionsBuilder() + .addValues([x: "24", y: "25"]) + .buildExtensions() + then: + extensions == [x: "24", y: "25"] + } + + def "can set extensions into an ER"() { + + + when: + def er = ExecutionResult.newExecutionResult().data(["x": "data"]).build() + def newER = newExtensionsBuilder().addValue("x", "24") + .addValues([y: "25", z: "26"]) + .addValues([x: "overwrite"]) + .setExtensions(er) + then: + newER.data == ["x": "data"] + newER.extensions == [x: "overwrite", y: "25", z: "26"] + + when: + er = ExecutionResult.newExecutionResult().data(["x": "data"]).extensions([a: "1"]).build() + newER = newExtensionsBuilder().addValue("x", "24") + .addValues([y: "25", z: "26"]) + .addValues([x: "overwrite"]) + .setExtensions(er) + then: + newER.data == ["x": "data"] + newER.extensions == [x: "overwrite", y: "25", z: "26"] // it overwrites - its a set! + + } + + def "can use a custom merger"() { + ExtensionsMerger merger = new ExtensionsMerger() { + @Override + Map merge(Map leftMap, Map rightMap) { + return rightMap + } + } + when: + def extensions = newExtensionsBuilder(merger) + .addValue("x", "24") + .addValues([y: "25", z: "26"]) + .addValues([x: "overwrite"]) + .addValues([the: "end"]).buildExtensions() + then: + extensions == [the: "end"] + } + + DataFetcher extensionDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment env) throws Exception { + ExtensionsBuilder extensionsBuilder = env.getGraphQlContext().get(ExtensionsBuilder.class) + def fieldMap = [:] + fieldMap.put(env.getFieldDefinition().name, GraphQLTypeUtil.simplePrint(env.getFieldDefinition().type)) + extensionsBuilder.addValues([common: fieldMap]) + extensionsBuilder.addValues(fieldMap) + return "ignored" + } + } + + + def "integration test that shows it working when they put in a builder"() { + def sdl = """ + type Query { + name : String! + street : String + id : ID! + } + """ + + def extensionsBuilder = newExtensionsBuilder() + extensionsBuilder.addValue("added", "explicitly") + + def ei = newExecutionInput("query q { name street id }") + .graphQLContext({ ctx -> + ctx.put(ExtensionsBuilder.class, extensionsBuilder) + }) + .build() + + + def graphQL = TestUtil.graphQL(sdl, newRuntimeWiring() + .type(newTypeWiring("Query").dataFetchers([ + name : extensionDF, + street: extensionDF, + id : extensionDF, + ]))) + .build() + + when: + def er = graphQL.execute(ei) + then: + er.errors.isEmpty() + er.extensions == [ + "added": "explicitly", + common : [ + name : "String!", + street: "String", + id : "ID!", + ], + // we break them out so we have common and not common entries + name : "String!", + street : "String", + id : "ID!", + ] + } + + + def "integration test that shows it working when they use DataFetcherResult and defaulted values"() { + def sdl = """ + type Query { + name : String! + street : String + id : ID! + } + """ + + DataFetcher dfrDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment env) throws Exception { + def fieldMap = [:] + fieldMap.put(env.getFieldDefinition().name, GraphQLTypeUtil.simplePrint(env.getFieldDefinition().type)) + return DataFetcherResult.newResult().data("ignored").extensions(fieldMap).build() + } + } + + def graphQL = TestUtil.graphQL(sdl, newRuntimeWiring() + .type(newTypeWiring("Query").dataFetchers([ + name : dfrDF, + street: dfrDF, + id : dfrDF, + ]))) + .build() + + when: + def ei = newExecutionInput("query q { name street id }") + .build() + + def er = graphQL.execute(ei) + then: + er.errors.isEmpty() + er.extensions == [ + name : "String!", + street: "String", + id : "ID!", + ] + } + + def "integration test that shows it working when they DONT put in a builder"() { + def sdl = """ + type Query { + name : String! + street : String + id : ID! + } + """ + + def ei = newExecutionInput("query q { name street id }") + .build() + + + def graphQL = TestUtil.graphQL(sdl, newRuntimeWiring() + .type(newTypeWiring("Query").dataFetchers([ + name : extensionDF, + street: extensionDF, + id : extensionDF, + ]))) + .build() + + when: + def er = graphQL.execute(ei) + then: + er.errors.isEmpty() + er.extensions == [ + common: [ + name : "String!", + street: "String", + id : "ID!", + ], + // we break them out so we have common and not common entries + name : "String!", + street: "String", + id : "ID!", + ] + } + + def "integration test showing it leaves extensions null if they are empty"() { + def sdl = """ + type Query { + name : String! + street : String + id : ID! + } + """ + + def ei = newExecutionInput("query q { name street id }") + .root(["name": "Brad", "id": 1234]) + .build() + + + def graphQL = TestUtil.graphQL(sdl, newRuntimeWiring().build()).build() + + when: + def er = graphQL.execute(ei) + then: + er.errors.isEmpty() + er.extensions == null + } +} diff --git a/src/test/groovy/graphql/i18n/I18nTest.groovy b/src/test/groovy/graphql/i18n/I18nTest.groovy new file mode 100644 index 0000000000..84165264e7 --- /dev/null +++ b/src/test/groovy/graphql/i18n/I18nTest.groovy @@ -0,0 +1,167 @@ +package graphql.i18n + +import graphql.AssertException +import graphql.ExecutionInput +import graphql.TestUtil +import graphql.i18n.I18n.BundleType +import spock.lang.Specification + +class I18nTest extends Specification { + + def "missing resource keys cause an assert"() { + def i18n = I18n.i18n(BundleType.Validation, Locale.ENGLISH) + when: + i18n.msg("nonExistent") + then: + thrown(AssertException) + } + + def "missing resource bundles default to a base version"() { + // see https://saimana.com/list-of-country-locale-code/ + + def expected = "Validation error ({0}) : Type '{1}' definition is not executable" + + when: + def i18n = I18n.i18n(BundleType.Validation, Locale.ENGLISH) + def msg = i18n.msg("ExecutableDefinitions.notExecutableType") + + then: + msg == expected + + when: + i18n = I18n.i18n(BundleType.Validation, Locale.CHINESE) + msg = i18n.msg("ExecutableDefinitions.notExecutableType") + then: + msg == expected + + when: + i18n = I18n.i18n(BundleType.Validation, new Locale("en", "IN")) // India + msg = i18n.msg("ExecutableDefinitions.notExecutableType") + then: + msg == expected + + when: + i18n = I18n.i18n(BundleType.Validation, new Locale("en", "FJ")) // Fiji + msg = i18n.msg("ExecutableDefinitions.notExecutableType") + then: + msg == expected + + when: + i18n = I18n.i18n(BundleType.Validation, new Locale("")) // Nothing + msg = i18n.msg("ExecutableDefinitions.notExecutableType") + then: + msg == expected + } + + def "all enums have resources and decent shapes"() { + when: + def bundleTypes = BundleType.values() + then: + for (BundleType bundleType : (bundleTypes)) { + // Currently only testing the default English bundles + def i18n = I18n.i18n(bundleType, Locale.ENGLISH) + assert i18n.resourceBundle != null + assertBundleStaticShape(i18n.resourceBundle) + } + } + + def "A non-default bundle can be read"() { + def i18n = I18n.i18n(BundleType.Validation, Locale.GERMAN) + when: + def message = i18n.msg("ExecutableDefinitions.notExecutableType") + then: + message == "Validierungsfehler ({0}) : Type definition '{1}' ist nicht ausführbar" + } + + def "integration test of valid messages"() { + def sdl = """ + type Query { + field(arg : Int) : Subselection + } + + type Subselection { + name : String + } + """ + def graphQL = TestUtil.graphQL(sdl).build() + + + when: + def locale = new Locale("en", "IN") + def ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }") + .locale(locale) + .build() + def er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message == "Validation error (SubselectionRequired@[field]) : Subselection required for type 'Subselection' of field 'field'" + + when: + locale = Locale.GERMANY + ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }") + .locale(locale) + .build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message == "Validierungsfehler (SubselectionRequired@[field]) : Unterauswahl erforderlich für Typ 'Subselection' des Feldes 'field'" + + when: + locale = Locale.getDefault() + ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }") + .locale(locale) + .build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message == "Validation error (SubselectionRequired@[field]) : Subselection required for type 'Subselection' of field 'field'" + + when: + // no locale - it should default + ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }") + .build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message == "Validation error (SubselectionRequired@[field]) : Subselection required for type 'Subselection' of field 'field'" + } + + static def assertBundleStaticShape(ResourceBundle bundle) { + def enumeration = bundle.getKeys() + while (enumeration.hasMoreElements()) { + def msgKey = enumeration.nextElement() + def pattern = bundle.getString(msgKey) + quotesAreBalanced(msgKey, pattern, '\'') + quotesAreBalanced(msgKey, pattern, '"') + curlyBracesAreBalanced(msgKey, pattern) + noStringFormatPercentLeftOver(msgKey, pattern) + placeHoldersNotRepeated(msgKey, pattern) + } + } + + static quotesAreBalanced(String msgKey, String msg, String c) { + def quoteCount = msg.count(c) + assert quoteCount % 2 == 0, "The I18n message $msgKey quotes are unbalanced : $msg" + } + + static placeHoldersNotRepeated(String msgKey, String msg) { + for (int i = 0; i < 200; i++) { + def count = msg.count("{$i}") + assert count < 2, "The I18n message $msgKey has repeated positional placeholders : $msg" + } + } + + static noStringFormatPercentLeftOver(String msgKey, String msg) { + assert !msg.contains("%s"), "The I18n message $msgKey has a %s in it : $msg" + assert !msg.contains("%d"), "The I18n message $msgKey has a %d in it : $msg" + } + + static def curlyBracesAreBalanced(String msgKey, String msg) { + def leftCount = msg.count("{") + def rightCount = msg.count("}") + if (leftCount > 0 || rightCount > 0) { + assert leftCount == rightCount, "The I18n message $msgKey left curly quote are unbalanced : $msg" + } + } + +} \ No newline at end of file diff --git a/src/test/groovy/graphql/incremental/DeferPayloadTest.groovy b/src/test/groovy/graphql/incremental/DeferPayloadTest.groovy new file mode 100644 index 0000000000..693d3911db --- /dev/null +++ b/src/test/groovy/graphql/incremental/DeferPayloadTest.groovy @@ -0,0 +1,145 @@ +package graphql.incremental + +import graphql.GraphqlErrorBuilder +import graphql.execution.ResultPath +import spock.lang.Specification + +import static graphql.GraphQLError.newError + +class DeferPayloadTest extends Specification { + def "null data is included"() { + def payload = DeferPayload.newDeferredItem() + .data(null) + .build() + + when: + def spec = payload.toSpecification() + + then: + spec == [ + data: null, + path: null, + ] + } + + def "can construct an instance using builder"() { + def payload = DeferPayload.newDeferredItem() + .data("twow is that a bee") + .path(["hello"]) + .errors([]) + .addError(GraphqlErrorBuilder.newError() + .message("wow") + .build()) + .addErrors([ + GraphqlErrorBuilder.newError() + .message("yep") + .build(), + ]) + .extensions([echo: "Hello world"]) + .build() + + when: + def serialized = payload.toSpecification() + + then: + serialized == [ + data : "twow is that a bee", + path : ["hello"], + errors : [ + [ + message : "wow", + locations : [], + extensions: [classification: "DataFetchingException"], + ], + [ + message : "yep", + locations : [], + extensions: [classification: "DataFetchingException"], + ], + ], + extensions: [ + echo: "Hello world", + ], + ] + } + + def "errors replaces existing errors"() { + def payload = DeferPayload.newDeferredItem() + .data("twow is that a bee") + .path(ResultPath.fromList(["test", "echo"])) + .addError(GraphqlErrorBuilder.newError() + .message("wow") + .build()) + .addErrors([]) + .errors([ + GraphqlErrorBuilder.newError() + .message("yep") + .build(), + ]) + .extensions([echo: "Hello world"]) + .build() + + when: + def serialized = payload.toSpecification() + + then: + serialized == [ + data : "twow is that a bee", + errors : [ + [ + message : "yep", + locations : [], + extensions: [classification: "DataFetchingException"], + ], + ], + extensions: [ + echo: "Hello world", + ], + path : ["test", "echo"], + ] + } + + def "equals and hashcode methods work correctly"() { + when: + def payload = DeferPayload.newDeferredItem() + .data("data1") + .path(["path1"]) + .label("label1") + .errors([newError().message("message1").build()]) + .extensions([key: "value1"]) + .build() + + def equivalentPayload = DeferPayload.newDeferredItem() + .data("data1") + .path(["path1"]) + .label("label1") + .errors([newError().message("message1").build()]) + .extensions([key: "value1"]) + .build() + + def totallyDifferentPayload = DeferPayload.newDeferredItem() + .data("data2") + .path(["path2"]) + .label("label2") + .errors([newError().message("message2").build()]) + .extensions([key: "value2"]) + .build() + + def slightlyDifferentPayload = DeferPayload.newDeferredItem() + .data("data1") + .path(["path1"]) + .label("label1") + .errors([newError().message("message1").build()]) + .extensions([key: "value2"]) + .build() + + then: + payload == equivalentPayload + payload != totallyDifferentPayload + payload != slightlyDifferentPayload + + payload.hashCode() == equivalentPayload.hashCode() + payload.hashCode() != totallyDifferentPayload.hashCode() + payload.hashCode() != slightlyDifferentPayload.hashCode() + } +} diff --git a/src/test/groovy/graphql/incremental/IncrementalExecutionResultTest.groovy b/src/test/groovy/graphql/incremental/IncrementalExecutionResultTest.groovy new file mode 100644 index 0000000000..fd13de6d8e --- /dev/null +++ b/src/test/groovy/graphql/incremental/IncrementalExecutionResultTest.groovy @@ -0,0 +1,144 @@ +package graphql.incremental + +import graphql.execution.ResultPath +import io.reactivex.Flowable +import spock.lang.Specification + +import static graphql.incremental.DeferPayload.newDeferredItem +import static graphql.incremental.IncrementalExecutionResultImpl.newIncrementalExecutionResult +import static graphql.incremental.StreamPayload.newStreamedItem + +class IncrementalExecutionResultTest extends Specification { + + def "sanity test to check IncrementalExecutionResultImpl builder and item builders work"() { + when: + def defer1 = newDeferredItem() + .label("homeWorldDefer") + .path(ResultPath.parse("/person")) + .data([homeWorld: "Tatooine"]) + .build() + + def stream1 = newStreamedItem() + .label("filmsStream") + .path(ResultPath.parse("/person/films[1]")) + .items([[title: "The Empire Strikes Back"]]) + .build() + + def stream2 = newStreamedItem() + .label("filmsStream") + .path(ResultPath.parse("/person/films[2]")) + .items([[title: "Return of the Jedi"]]) + .build() + + def result = newIncrementalExecutionResult() + .data([ + person: [ + name : "Luke Skywalker", + films: [ + [title: "A New Hope"] + ] + ] + ]) + .hasNext(true) + .incremental([defer1, stream1, stream2]) + .extensions([some: "map"]) + .build() + + def toSpec = result.toSpecification() + + then: + toSpec == [ + data : [person: [name: "Luke Skywalker", films: [[title: "A New Hope"]]]], + extensions: [some: "map"], + hasNext : true, + incremental: [ + [path: ["person"], label: "homeWorldDefer", data: [homeWorld: "Tatooine"]], + [path: ["person", "films", 1], label: "filmsStream", items: [[title: "The Empire Strikes Back"]]], + [path: ["person", "films", 2], label: "filmsStream", items: [[title: "Return of the Jedi"]]], + ] + ] + + } + def "sanity test to check DelayedIncrementalPartialResult builder works"() { + when: + def deferredItem = newDeferredItem() + .label("homeWorld") + .path(ResultPath.parse("/person")) + .data([homeWorld: "Tatooine"]) + .build() + + def result = DelayedIncrementalPartialResultImpl.newIncrementalExecutionResult() + .incrementalItems([deferredItem]) + .hasNext(false) + .extensions([some: "map"]) + .build() + + def toSpec = result.toSpecification() + + then: + toSpec == [ + incremental: [[path: ["person"], label: "homeWorld", data: [homeWorld: "Tatooine"]]], + extensions: [some: "map"], + hasNext : false, + ] + } + + def "sanity test to check Builder.from works"() { + + when: + def defer1 = newDeferredItem() + .label("homeWorldDefer") + .path(ResultPath.parse("/person")) + .data([homeWorld: "Tatooine"]) + .build() + + + def incrementalExecutionResult = new IncrementalExecutionResultImpl.Builder() + .data([ + person: [ + name : "Luke Skywalker", + films: [ + [title: "A New Hope"] + ] + ] + ]) + .incrementalItemPublisher { Flowable.range(1,10)} + .hasNext(true) + .incremental([defer1]) + .extensions([some: "map"]) + .build() + + def newIncrementalExecutionResult = new IncrementalExecutionResultImpl.Builder().from(incrementalExecutionResult).build() + + then: + newIncrementalExecutionResult.incremental == incrementalExecutionResult.incremental + newIncrementalExecutionResult.extensions == incrementalExecutionResult.extensions + newIncrementalExecutionResult.errors == incrementalExecutionResult.errors + newIncrementalExecutionResult.incrementalItemPublisher == incrementalExecutionResult.incrementalItemPublisher + newIncrementalExecutionResult.hasNext() == incrementalExecutionResult.hasNext() + newIncrementalExecutionResult.toSpecification() == incrementalExecutionResult.toSpecification() + } + + def "transform returns IncrementalExecutionResult"() { + when: + def defer = newDeferredItem() + .label("homeWorldDefer") + .path(ResultPath.parse("/person")) + .data([homeWorld: "Tatooine"]) + .build() + def initial = newIncrementalExecutionResult() + .hasNext(true) + .incremental([defer]) + .build() + + then: + def transformed = initial.transform { b -> + b.addExtension("ext-key", "ext-value") + b.hasNext(false) + } + transformed instanceof IncrementalExecutionResult + transformed.extensions == ["ext-key": "ext-value"] + transformed.incremental == initial.incremental + transformed.hasNext == false + } +} diff --git a/src/test/groovy/graphql/incremental/StreamPayloadTest.groovy b/src/test/groovy/graphql/incremental/StreamPayloadTest.groovy new file mode 100644 index 0000000000..157dcc1f0d --- /dev/null +++ b/src/test/groovy/graphql/incremental/StreamPayloadTest.groovy @@ -0,0 +1,153 @@ +package graphql.incremental + +import graphql.execution.ResultPath +import spock.lang.Specification + +import static graphql.GraphqlErrorBuilder.newError + +class StreamPayloadTest extends Specification { + def "null data is included"() { + def payload = StreamPayload.newStreamedItem() + .items(null) + .build() + + when: + def spec = payload.toSpecification() + + then: + spec == [ + items: null, + path : null, + ] + } + + def "can construct an instance using builder"() { + def payload = StreamPayload.newStreamedItem() + .items(["twow is that a bee"]) + .path(["hello"]) + .errors([]) + .addError(newError() + .message("wow") + .build()) + .addErrors([ + newError() + .message("yep") + .build(), + ]) + .extensions([echo: "Hello world"]) + .build() + + when: + def serialized = payload.toSpecification() + + then: + serialized == [ + items : ["twow is that a bee"], + path : ["hello"], + errors : [ + [ + message : "wow", + locations : [], + extensions: [classification: "DataFetchingException"], + ], + [ + message : "yep", + locations : [], + extensions: [classification: "DataFetchingException"], + ], + ], + extensions: [ + echo: "Hello world", + ], + ] + } + + def "errors replaces existing errors"() { + def payload = StreamPayload.newStreamedItem() + .items(["twow is that a bee"]) + .path(ResultPath.fromList(["test", "echo"])) + .addError(newError() + .message("wow") + .build()) + .addErrors([]) + .errors([ + newError() + .message("yep") + .build(), + ]) + .extensions([echo: "Hello world"]) + .build() + + when: + def serialized = payload.toSpecification() + + then: + serialized == [ + items : ["twow is that a bee"], + errors : [ + [ + message : "yep", + locations : [], + extensions: [classification: "DataFetchingException"], + ], + ], + extensions: [ + echo: "Hello world", + ], + path : ["test", "echo"], + ] + } + + def "test equals and hashCode methods work"() { + given: + def items1 = ["test1"] + def items2 = ["test2", "test3"] + def path1 = ["test", "echo"] + def path2 = ["test", "echo", "foo"] + def errors1 = [newError().message("error1").build()] + def errors2 = [newError().message("error2").build()] + def extensions1 = [echo: "1"] + def extensions2 = [echo: "2"] + + def payload = new StreamPayload.Builder() + .items(items1) + .path(path1) + .label("label1") + .errors(errors1) + .extensions(extensions1) + .build() + + def equivalentPayload = new StreamPayload.Builder() + .items(items1) + .path(path1) + .label("label1") + .errors(errors1) + .extensions(extensions1) + .build() + + def totallyDifferentPayload = new StreamPayload.Builder() + .items(items2) + .path(path2) + .label("label2") + .errors(errors2) + .extensions(extensions2) + .build() + + def slightlyDifferentPayload = new StreamPayload.Builder() + .items(items2) + .path(path2) + .label("label1") + .errors(errors1) + .extensions(extensions2) + .build() + + expect: + payload == equivalentPayload + payload != totallyDifferentPayload + payload != slightlyDifferentPayload + + payload.hashCode() == equivalentPayload.hashCode() + payload.hashCode() != totallyDifferentPayload.hashCode() + payload.hashCode() != slightlyDifferentPayload.hashCode() + } +} diff --git a/src/test/groovy/graphql/introspection/GoodFaithIntrospectionTest.groovy b/src/test/groovy/graphql/introspection/GoodFaithIntrospectionTest.groovy new file mode 100644 index 0000000000..c2d9b2dc87 --- /dev/null +++ b/src/test/groovy/graphql/introspection/GoodFaithIntrospectionTest.groovy @@ -0,0 +1,231 @@ +package graphql.introspection + +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.TestUtil +import graphql.execution.CoercedVariables +import graphql.language.Document +import graphql.normalized.ExecutableNormalizedOperationFactory +import spock.lang.Specification + +class GoodFaithIntrospectionTest extends Specification { + + def graphql = TestUtil.graphQL("type Query { normalField : String }").build() + + def setup() { + GoodFaithIntrospection.enabledJvmWide(true) + } + + def cleanup() { + GoodFaithIntrospection.enabledJvmWide(true) + } + + def "standard introspection query is inside limits just in general"() { + + when: + Document document = TestUtil.toDocument(IntrospectionQuery.INTROSPECTION_QUERY) + def eno = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(graphql.getGraphQLSchema(), document, + "IntrospectionQuery", CoercedVariables.emptyVariables()) + + then: + eno.getOperationFieldCount() < GoodFaithIntrospection.GOOD_FAITH_MAX_FIELDS_COUNT // currently 189 + eno.getOperationDepth() < GoodFaithIntrospection.GOOD_FAITH_MAX_DEPTH_COUNT // currently 13 + } + + def "test asking for introspection in good faith"() { + + when: + ExecutionResult er = graphql.execute(IntrospectionQuery.INTROSPECTION_QUERY) + then: + er.errors.isEmpty() + } + + def "test asking for introspection in bad faith"() { + + when: + ExecutionResult er = graphql.execute(query) + then: + !er.errors.isEmpty() + er.errors[0] instanceof GoodFaithIntrospection.BadFaithIntrospectionError + + where: + query | _ + // long attack + """ + query badActor{__schema{types{fields{type{fields{type{fields{type{fields{type{name}}}}}}}}}}} + """ | _ + // a case for __Type interfaces + """ query badActor { + __schema { types { interfaces { fields { type { interfaces { name } } } } } } + } + """ | _ + // a case for __Type inputFields + """ query badActor { + __schema { types { inputFields { type { inputFields { name }}}}} + } + """ | _ + // a case for __Type possibleTypes + """ query badActor { + __schema { types { inputFields { type { inputFields { name }}}}} + } + """ | _ + // a case leading from __InputValue + """ query badActor { + __schema { types { fields { args { type { name fields { name }}}}}} + } + """ | _ + // a case leading from __Field + """ query badActor { + __schema { types { fields { type { name fields { name }}}}} + } + """ | _ + // a case for __type + """ query badActor { + __type(name : "t") { name } + alias1 : __type(name : "t1") { name } + } + """ | _ + // a case for __type with aliases + """ query badActor { + a1: __type(name : "t") { name } + a2 : __type(name : "t1") { name } + } + """ | _ + // a case for schema repeated - dont ask twice + """ query badActor { + __schema { types { name} } + alias1 : __schema { types { name} } + } + """ | _ + // a case for used aliases + """ query badActor { + a1: __schema { types { name} } + a2 : __schema { types { name} } + } + """ | _ + + } + + def "mixed general queries and introspections will be stopped anyway"() { + def query = """ + query goodAndBad { + normalField + __schema{types{fields{type{fields{type{fields{type{fields{type{name}}}}}}}}}} + } + """ + + when: + ExecutionResult er = graphql.execute(query) + then: + !er.errors.isEmpty() + er.errors[0] instanceof GoodFaithIntrospection.BadFaithIntrospectionError + er.data == null // it stopped hard - it did not continue to normal business + } + + def "can be disabled"() { + when: + def currentState = GoodFaithIntrospection.isEnabledJvmWide() + + then: + currentState + + when: + def prevState = GoodFaithIntrospection.enabledJvmWide(false) + + then: + prevState + + when: + ExecutionResult er = graphql.execute("query badActor{__schema{types{fields{type{fields{type{fields{type{fields{type{name}}}}}}}}}}}") + + then: + er.errors.isEmpty() + } + + def "can be disabled per request"() { + when: + def context = [(GoodFaithIntrospection.GOOD_FAITH_INTROSPECTION_DISABLED): true] + ExecutionInput executionInput = ExecutionInput.newExecutionInput("query badActor{__schema{types{fields{type{fields{type{fields{type{fields{type{name}}}}}}}}}}}") + .graphQLContext(context).build() + ExecutionResult er = graphql.execute(executionInput) + + then: + er.errors.isEmpty() + + when: + context = [(GoodFaithIntrospection.GOOD_FAITH_INTROSPECTION_DISABLED): false] + executionInput = ExecutionInput.newExecutionInput("query badActor{__schema{types{fields{type{fields{type{fields{type{fields{type{name}}}}}}}}}}}") + .graphQLContext(context).build() + er = graphql.execute(executionInput) + + then: + !er.errors.isEmpty() + er.errors[0] instanceof GoodFaithIntrospection.BadFaithIntrospectionError + } + + def "can stop deep queries"() { + + when: + def query = createDeepQuery(depth) + def then = System.currentTimeMillis() + ExecutionResult er = graphql.execute(query) + def ms = System.currentTimeMillis() - then + + then: + !er.errors.isEmpty() + er.errors[0].class == targetError + er.data == null // it stopped hard - it did not continue to normal business + println "Took " + ms + "ms" + + where: + depth | targetError + 2 | GoodFaithIntrospection.BadFaithIntrospectionError.class + 10 | GoodFaithIntrospection.BadFaithIntrospectionError.class + 15 | GoodFaithIntrospection.BadFaithIntrospectionError.class + 20 | GoodFaithIntrospection.BadFaithIntrospectionError.class + 25 | GoodFaithIntrospection.BadFaithIntrospectionError.class + 50 | GoodFaithIntrospection.BadFaithIntrospectionError.class + 100 | GoodFaithIntrospection.BadFaithIntrospectionError.class + } + + String createDeepQuery(int depth = 25) { + def result = """ +query test { + __schema { + types { + ...F1 + } + } +} +""" + for (int i = 1; i < depth; i++) { + result += """ + fragment F$i on __Type { + fields { + type { + ...F${i + 1} + } + } + + ofType { + ...F${i + 1} + } +} + + +""" + } + result += """ + fragment F$depth on __Type { + fields { + type { +name + } + } +} + + +""" + return result + } +} diff --git a/src/test/groovy/graphql/introspection/IntrospectionJsonBugTest.groovy b/src/test/groovy/graphql/introspection/IntrospectionJsonBugTest.groovy new file mode 100644 index 0000000000..316f687cf4 --- /dev/null +++ b/src/test/groovy/graphql/introspection/IntrospectionJsonBugTest.groovy @@ -0,0 +1,91 @@ +package graphql.introspection + +import graphql.Scalars +import graphql.language.Document +import graphql.schema.GraphQLScalarType +import graphql.schema.idl.MockedWiringFactory +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.ScalarWiringEnvironment +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import graphql.schema.idl.SchemaPrinter +import graphql.schema.idl.TypeDefinitionRegistry +import groovy.json.JsonSlurper +import spock.lang.Specification + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring + +class IntrospectionJsonBugTest extends Specification { + + Document createSchemaDoc(String fileName) { + // this json cam from a customer report + def schemaFile = getClass().getClassLoader().getResourceAsStream(fileName) + def json = new JsonSlurper().parse(schemaFile) + def schemaDoc = new IntrospectionResultToSchema().createSchemaDefinition(json["data"] as Map) + schemaDoc + } + + TypeDefinitionRegistry parseTypes(String printedSchema) { + def schemaProvider = new StringReader(printedSchema) + def parser = new SchemaParser() + def typeRegistry = parser.parse(schemaProvider) + typeRegistry + } + + // + // custom scalars that are present in the json schema + // + static RuntimeWiring runtimeWiring = newRuntimeWiring().wiringFactory(new MockedWiringFactory() { + @Override + boolean providesScalar(ScalarWiringEnvironment environment) { + def name = environment.scalarTypeDefinition.getName() + ["DateTime", "Date", "Blob", "BigInt", "HTML", "URI", + "GitObjectID", "GitTimestamp", "X509Certificate", "GitSSHRemote"].contains(name) + } + + @Override + GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { + Scalars.GraphQLString + } + }).build() + + def options = SchemaPrinter.Options.defaultOptions().includeScalarTypes(true) + def schemaPrinter = new SchemaPrinter(options) + + + def "1509 - can load data and generate schema from json first bug"() { + + when: + // this json cam from a customer report + def schema = createSchemaDoc("introspection/1509-first-bug-data.json") + + then: + def printedSchema = schemaPrinter.print(schema) + printedSchema != null + + when: + def typeRegistry = parseTypes(printedSchema) + def graphqlSchema = new SchemaGenerator().makeExecutableSchema(typeRegistry, runtimeWiring) + + then: + graphqlSchema != null + } + + def "1509 - can load data and generate schema from json second bug"() { + + when: + // this json cam from a customer report + def schema = createSchemaDoc("introspection/1509-second-bug-data.json") + + then: + def printedSchema = schemaPrinter.print(schema) + printedSchema != null + + when: + def typeRegistry = parseTypes(printedSchema) + def graphqlSchema = new SchemaGenerator().makeExecutableSchema(typeRegistry, runtimeWiring) + + then: + graphqlSchema != null + } +} diff --git a/src/test/groovy/graphql/introspection/IntrospectionResultToSchemaTest.groovy b/src/test/groovy/graphql/introspection/IntrospectionResultToSchemaTest.groovy index 730f12c550..f322d2700e 100644 --- a/src/test/groovy/graphql/introspection/IntrospectionResultToSchemaTest.groovy +++ b/src/test/groovy/graphql/introspection/IntrospectionResultToSchemaTest.groovy @@ -1,24 +1,38 @@ package graphql.introspection import com.fasterxml.jackson.databind.ObjectMapper +import graphql.Assert import graphql.ExecutionInput +import graphql.ExecutionResult import graphql.GraphQL import graphql.TestUtil -import graphql.language.AstPrinter import graphql.language.Document import graphql.language.EnumTypeDefinition import graphql.language.InputObjectTypeDefinition +import graphql.language.IntValue import graphql.language.InterfaceTypeDefinition +import graphql.language.ObjectField import graphql.language.ObjectTypeDefinition +import graphql.language.ObjectValue +import graphql.language.StringValue import graphql.language.UnionTypeDefinition +import graphql.language.Value +import graphql.schema.Coercing +import graphql.schema.CoercingParseLiteralException +import graphql.schema.CoercingParseValueException +import graphql.schema.CoercingSerializeException +import graphql.schema.GraphQLArgument import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema +import graphql.schema.idl.RuntimeWiring import graphql.schema.idl.SchemaPrinter import groovy.json.JsonSlurper import spock.lang.Specification import static graphql.Scalars.GraphQLString import static graphql.introspection.IntrospectionQuery.INTROSPECTION_QUERY +import static graphql.language.AstPrinter.printAst import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition class IntrospectionResultToSchemaTest extends Specification { @@ -44,7 +58,7 @@ class IntrospectionResultToSchemaTest extends Specification { "args": [ { "name": "episode", - "description": "comment about episode", + "description": "comment about episode\non two lines", "type": { "kind": "ENUM", "name": "Episode", @@ -86,16 +100,15 @@ class IntrospectionResultToSchemaTest extends Specification { when: ObjectTypeDefinition objectTypeDefinition = introspectionResultToSchema.createObject(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(objectTypeDefinition) + def result = printAst(objectTypeDefinition) then: result == """type QueryType implements Query { - hero( - #comment about episode - episode: Episode - foo: String = \"bar\" - ): Character @deprecated(reason: "killed off character") + hero(\"\"\" + comment about episode + on two lines + \"\"\" + episode: Episode, foo: String = \"bar\"): Character @deprecated(reason: "killed off character") }""" } @@ -192,19 +205,18 @@ class IntrospectionResultToSchemaTest extends Specification { when: InterfaceTypeDefinition interfaceTypeDefinition = introspectionResultToSchema.createInterface(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(interfaceTypeDefinition) + def result = printAst(interfaceTypeDefinition) then: - result == """#A character in the Star Wars Trilogy + result == """"A character in the Star Wars Trilogy" interface Character { - #The id of the character. + "The id of the character." id: String! - #The name of the character. + "The name of the character." name: String - #The friends of the character, or an empty list if they have none. + "The friends of the character, or an empty list if they have none." friends: [Character] - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] }""" @@ -245,17 +257,16 @@ interface Character { when: EnumTypeDefinition enumTypeDef = introspectionResultToSchema.createEnum(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(enumTypeDef) + def result = printAst(enumTypeDef) then: - result == """#One of the films in the Star Wars Trilogy + result == """"One of the films in the Star Wars Trilogy" enum Episode { - #Released in 1977. + "Released in 1977." NEWHOPE - #Released in 1980. + "Released in 1980." EMPIRE - #Released in 1983. + "Released in 1983." JEDI @deprecated(reason: "killed by clones") }""" @@ -288,11 +299,10 @@ enum Episode { when: UnionTypeDefinition unionTypeDefinition = introspectionResultToSchema.createUnion(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(unionTypeDefinition) + def result = printAst(unionTypeDefinition) then: - result == """#all the stuff + result == """"all the stuff" union Everything = Character | Episode""" } @@ -344,13 +354,12 @@ union Everything = Character | Episode""" when: InputObjectTypeDefinition inputObjectTypeDefinition = introspectionResultToSchema.createInputObject(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(inputObjectTypeDefinition) + def result = printAst(inputObjectTypeDefinition) then: - result == """#input for characters + result == """"input for characters" input CharacterInput { - #first name + "first name" firstName: String lastName: String family: Boolean @@ -368,13 +377,12 @@ input CharacterInput { "subscriptionType": {"name":"SubscriptionType"}, "types": [ ] - }""" + }}""" def parsed = slurp(input) when: Document document = introspectionResultToSchema.createSchemaDefinition(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(document) + def result = printAst(document) then: result == """schema { @@ -383,7 +391,6 @@ input CharacterInput { subscription: SubscriptionType } """ - } def "test starwars introspection result"() { @@ -394,8 +401,7 @@ input CharacterInput { when: Document document = introspectionResultToSchema.createSchemaDefinition(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(document) + def result = printAst(document) then: result == """schema { @@ -403,67 +409,61 @@ input CharacterInput { } type QueryType { - hero( - #If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode. - episode: Episode - ): Character - human( - #id of the human - id: String! - ): Human - droid( - #id of the droid - id: String! - ): Droid + hero("If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode." + episode: Episode): Character + human("id of the human" + id: String!): Human + droid("id of the droid" + id: String!): Droid } -#A character in the Star Wars Trilogy +"A character in the Star Wars Trilogy" interface Character { - #The id of the character. + "The id of the character." id: String! - #The name of the character. + "The name of the character." name: String - #The friends of the character, or an empty list if they have none. + "The friends of the character, or an empty list if they have none." friends: [Character] - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] } -#One of the films in the Star Wars Trilogy +"One of the films in the Star Wars Trilogy" enum Episode { - #Released in 1977. + "Released in 1977." NEWHOPE - #Released in 1980. + "Released in 1980." EMPIRE - #Released in 1983. + "Released in 1983." JEDI } -#A humanoid creature in the Star Wars universe. +"A humanoid creature in the Star Wars universe." type Human implements Character { - #The id of the human. + "The id of the human." id: String! - #The name of the human. + "The name of the human." name: String - #The friends of the human, or an empty list if they have none. + "The friends of the human, or an empty list if they have none." friends: [Character] - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The home planet of the human, or null if unknown. + "The home planet of the human, or null if unknown." homePlanet: String } -#A mechanical creature in the Star Wars universe. +"A mechanical creature in the Star Wars universe." type Droid implements Character { - #The id of the droid. + "The id of the droid." id: String! - #The name of the droid. + "The name of the droid." name: String - #The friends of the droid, or an empty list if they have none. + "The friends of the droid, or an empty list if they have none." friends: [Character] - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The primary function of the droid. + "The primary function of the droid." primaryFunction: String } """ @@ -477,8 +477,7 @@ type Droid implements Character { when: Document document = introspectionResultToSchema.createSchemaDefinition(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(document) + def result = printAst(document) then: result == """schema { @@ -510,19 +509,19 @@ type Episode { characters: [Character] } -# Simpson seasons +" Simpson seasons" enum Season { - # the beginning + " the beginning" Season1 Season2 Season3 Season4 - # Another one + " Another one" Season5 Season6 Season7 Season8 - # Not really the last one :-) + " Not really the last one :-)" Season9 } @@ -544,7 +543,6 @@ input CharacterInput { """ } - def "test complete round trip"() { given: def queryType = GraphQLObjectType.newObject().name("Query").field(newFieldDefinition().name("hello").type(GraphQLString).build()) @@ -552,14 +550,14 @@ input CharacterInput { when: - def printedSchema = new SchemaPrinter().print(graphQLSchema) + def options = SchemaPrinter.Options.defaultOptions().includeDirectives(false) + def printedSchema = new SchemaPrinter(options).print(graphQLSchema) - GraphQLSchema schema = TestUtil.schema(printedSchema) + def graphQL = TestUtil.graphQL(printedSchema).build() - def introspectionResult = GraphQL.newGraphQL(schema).build().execute(ExecutionInput.newExecutionInput().query(INTROSPECTION_QUERY).build()) + def introspectionResult = graphQL.execute(ExecutionInput.newExecutionInput().query(INTROSPECTION_QUERY).build()) Document schemaDefinitionDocument = introspectionResultToSchema.createSchemaDefinition(introspectionResult.data as Map) - AstPrinter astPrinter = new AstPrinter() - def astPrinterResult = astPrinter.printAst(schemaDefinitionDocument) + def astPrinterResult = printAst(schemaDefinitionDocument) then: printedSchema == astPrinterResult @@ -595,8 +593,9 @@ input CharacterInput { } ''' + def options = SchemaPrinter.Options.defaultOptions().includeDirectives(false) def schema = TestUtil.schema(schemaSpec) - def printedSchema = new SchemaPrinter().print(schema) + def printedSchema = new SchemaPrinter(options).print(schema) when: StringWriter sw = new StringWriter() @@ -613,11 +612,10 @@ input CharacterInput { Document schemaDefinitionDocument = introspectionResultToSchema.createSchemaDefinition(roundTripMap) - AstPrinter astPrinter = new AstPrinter() - def astPrinterResult = astPrinter.printAst(schemaDefinitionDocument) + def astPrinterResult = printAst(schemaDefinitionDocument) def actualSchema = TestUtil.schema(astPrinterResult) - def actualPrintedSchema = new SchemaPrinter().print(actualSchema) + def actualPrintedSchema = new SchemaPrinter(options).print(actualSchema) then: printedSchema == actualPrintedSchema @@ -627,7 +625,7 @@ input CharacterInput { } type Query { - outputField(inputArg: InputType = {age : 666, name : "nameViaArg"}, inputBoolean: Boolean = true, inputInt: Int = 1, inputString: String = "viaArgString"): OutputType + outputField(inputArg: InputType = {name : "nameViaArg", age : 666}, inputBoolean: Boolean = true, inputInt: Int = 1, inputString: String = "viaArgString"): OutputType } input ComplexType { @@ -638,7 +636,7 @@ input ComplexType { input InputType { age: Int = -1 - complex: ComplexType = {boolean : true, int : 666, string : "string"} + complex: ComplexType = {string : "string", boolean : true, int : 666} name: String = "defaultName" rocks: Boolean = true } @@ -684,8 +682,7 @@ input InputType { when: Document document = introspectionResultToSchema.createSchemaDefinition(parsed) - AstPrinter astPrinter = new AstPrinter() - def result = astPrinter.printAst(document) + def result = printAst(document) then: result == """type Query { @@ -701,5 +698,361 @@ input InputType { null | '{"name":"Subscription"}' } + def "create schema fail"() { + given: + def failResult = ExecutionResult.newExecutionResult().build() + + when: + Document document = introspectionResultToSchema.createSchemaDefinition(failResult) + + then: + document == null + } + + def "create scalars"() { + def input = ''' { + "kind": "SCALAR", + "name": "ScalarType", + "description": "description of ScalarType", + } + ''' + def parsed = slurp(input) + + when: + def scalarTypeDefinition = introspectionResultToSchema.createScalar(parsed) + def result = printAst(scalarTypeDefinition) + + then: + result == """"description of ScalarType"\nscalar ScalarType""" + } + + def " create directives "() { + def input = ''' + { + "name": "customizedDirective", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [] + } + ''' + def parsed = slurp(input) + + when: + def directiveDefinition = introspectionResultToSchema.createDirective(parsed) + def result = printAst(directiveDefinition) + + then: + result == """directive @customizedDirective on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT""" + } + + def "create directives with arguments and default value"() { + def input = '''{ + "name": "customizedDirective", + "description": "customized directive", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "directiveArg", + "description": "directive arg", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null, + "defaultValue": "\\"default Value\\"" + } + ] + } + ''' + def parsed = slurp(input) + + when: + def directiveDefinition = introspectionResultToSchema.createDirective(parsed) + def result = printAst(directiveDefinition) + + then: + result == """"customized directive" +directive @customizedDirective("directive arg" +directiveArg: String = "default Value") on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT""" + } + + def "create schema with directives"() { + def input = """{ + "__schema": { + "queryType": { + "name": "QueryType" + }, + "types": [], + "directives": [ + { + "name": "customizedDirective", + "description": "customized directive", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "directiveArg", + "description": "directive arg", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null, + "defaultValue": "\\"default Value\\"" + } + ] + }, + { + "name": "repeatableDirective", + "description": "repeatable directive", + "locations": [ + "FIELD_DEFINITION" + ], + "args": [], + "isRepeatable":true + } + ] + }}""" + def parsed = slurp(input) + + when: + Document document = introspectionResultToSchema.createSchemaDefinition(parsed) + def result = printAst(document) + + then: + result == """schema { + query: QueryType +} + +"customized directive" +directive @customizedDirective("directive arg" +directiveArg: String = "default Value") on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"repeatable directive" +directive @repeatableDirective repeatable on FIELD_DEFINITION +""" + } + + def "round trip of default values of complex custom Scalar via SDL"() { + given: + def employeeRefScalar = GraphQLScalarType.newScalar().name("EmployeeRef").coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + return null + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + return null + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + return null + } + + @Override + Value valueToLiteral(Object input) { + return null + } + }).build() + + def sdl = ''' + scalar EmployeeRef + type Query{ + foo(arg: EmployeeRef = {externalRef: "123", department: 5}): String + } + ''' + def options = SchemaPrinter.Options.defaultOptions().includeDirectives(false) + def rw = RuntimeWiring.newRuntimeWiring().scalar(employeeRefScalar).build() + def schema = TestUtil.schema(sdl, rw) + def printedSchema = new SchemaPrinter(options).print(schema) + + when: + StringWriter sw = new StringWriter() + def introspectionResult = GraphQL.newGraphQL(schema).build().execute(ExecutionInput.newExecutionInput().query(INTROSPECTION_QUERY).build()) + + // + // round trip the introspection into JSON and then again to ensure + // we see any encoding aspects + // + ObjectMapper objectMapper = new ObjectMapper() + objectMapper.writer().writeValue(sw, introspectionResult.data) + def json = sw.toString() + def roundTripMap = objectMapper.readValue(json, Map.class) + Document schemaDefinitionDocument = introspectionResultToSchema.createSchemaDefinition(roundTripMap) + + def astPrinterResult = printAst(schemaDefinitionDocument) + + def actualSchema = TestUtil.schema(astPrinterResult, rw) + def actualPrintedSchema = new SchemaPrinter(options).print(actualSchema) + + then: + printedSchema == actualPrintedSchema + + actualPrintedSchema == '''type Query { + foo(arg: EmployeeRef = {externalRef : "123", department : 5}): String } +scalar EmployeeRef +''' + } + + class ExternalEmployeeRef { + String externalRef; + String externalDepartment; + } + + def "round trip of default values of complex custom Scalar via programmatic schema"() { + given: + def employeeRefScalar = GraphQLScalarType.newScalar().name("EmployeeRef").coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + return null + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + return null + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + return null + } + + @Override + Value valueToLiteral(Object input) { + if (input instanceof ExternalEmployeeRef) { + def externalRef = StringValue.newStringValue(input.externalRef).build() + def refField = ObjectField.newObjectField().name("ref").value(externalRef).build() + def externalDepartment = IntValue.newIntValue(new BigInteger(input.externalDepartment)).build() + def departmentField = ObjectField.newObjectField().name("department").value(externalDepartment).build() + return ObjectValue.newObjectValue().objectField(refField).objectField(departmentField).build() + } + return Assert.assertShouldNeverHappen(); + } + }).build() + + + def ref = new ExternalEmployeeRef(externalRef: "123", externalDepartment: "5") + def argument = GraphQLArgument.newArgument().name("arg").type(employeeRefScalar).defaultValueProgrammatic(ref).build() + def field = newFieldDefinition().name("foo").type(GraphQLString).argument(argument).build() + def queryType = GraphQLObjectType.newObject().name("Query").field(field).build() + def schema = GraphQLSchema.newSchema().query(queryType).build() + + def options = SchemaPrinter.Options.defaultOptions().includeDirectives(false) + def printedSchema = new SchemaPrinter(options).print(schema) + + when: + StringWriter sw = new StringWriter() + def introspectionResult = GraphQL.newGraphQL(schema).build().execute(ExecutionInput.newExecutionInput().query(INTROSPECTION_QUERY).build()) + + // + // round trip the introspection into JSON and then again to ensure + // we see any encoding aspects + // + ObjectMapper objectMapper = new ObjectMapper() + objectMapper.writer().writeValue(sw, introspectionResult.data) + def json = sw.toString() + def roundTripMap = objectMapper.readValue(json, Map.class) + Document schemaDefinitionDocument = introspectionResultToSchema.createSchemaDefinition(roundTripMap) + + def astPrinterResult = printAst(schemaDefinitionDocument) + + def rw = RuntimeWiring.newRuntimeWiring().scalar(employeeRefScalar).build() + def actualSchema = TestUtil.schema(astPrinterResult, rw) + def actualPrintedSchema = new SchemaPrinter(options).print(actualSchema) + + then: + printedSchema == actualPrintedSchema + + actualPrintedSchema == '''type Query { + foo(arg: EmployeeRef = {ref : "123", department : 5}): String +} + +scalar EmployeeRef +''' + } + + def "copes when isDeprecated is not defined"() { + def input = ''' { + "kind": "OBJECT", + "name": "QueryType", + "description": null, + "fields": [ + { + "name": "hero", + "description": null, + "args": [ + { + "name": "episode", + "description": "comment about episode\non two lines", + "type": { + "kind": "ENUM", + "name": "Episode", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "foo", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": "\\"bar\\"" + } + ], + "type": { + "kind": "INTERFACE", + "name": "Character", + "ofType": null + }, + "isDeprecatedISNOTYDEFINED": false, + "deprecationReason": "killed off character" + } + ], + "inputFields": null, + "interfaces": [{ + "kind": "INTERFACE", + "name": "Query", + "ofType": null + }], + "enumValues": null, + "possibleTypes": null + } + ''' + def parsed = slurp(input) + + when: + ObjectTypeDefinition objectTypeDefinition = introspectionResultToSchema.createObject(parsed) + def result = printAst(objectTypeDefinition) + + then: + result == """type QueryType implements Query { + hero(\"\"\" + comment about episode + on two lines + \"\"\" + episode: Episode, foo: String = \"bar\"): Character +}""" + + } +} diff --git a/src/test/groovy/graphql/introspection/IntrospectionTest.groovy b/src/test/groovy/graphql/introspection/IntrospectionTest.groovy new file mode 100644 index 0000000000..8a70c68618 --- /dev/null +++ b/src/test/groovy/graphql/introspection/IntrospectionTest.groovy @@ -0,0 +1,807 @@ +package graphql.introspection + +import graphql.ExecutionInput +import graphql.TestUtil +import graphql.execution.AsyncSerialExecutionStrategy +import graphql.schema.DataFetcher +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry +import graphql.schema.GraphQLFieldsContainer +import graphql.schema.GraphQLNamedType +import spock.lang.Issue +import spock.lang.See +import spock.lang.Specification + +import static graphql.GraphQL.newGraphQL +import static graphql.Scalars.GraphQLString +import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInputObjectField.newInputObjectField +import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema + +class IntrospectionTest extends Specification { + + def setup() { + Introspection.enabledJvmWide(true) + } + + def cleanup() { + Introspection.enabledJvmWide(true) + } + + def "bug 1186 - introspection depth check"() { + def spec = ''' + type Query { + geo : GeoPolygon + } + + type GeoPolygon { + coordinates: [[[[[Float]]]]]! + } + ''' + + def graphQL = TestUtil.graphQL(spec).build() + when: + def executionResult = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + then: + executionResult.errors.isEmpty() + + def types = executionResult.data['__schema']['types'] as List + def geoPolygonType = types.find { it['name'] == 'GeoPolygon' } + def coordinatesField = (geoPolygonType['fields'] as List)[0] + def fieldType = coordinatesField['type'] + // should show up to 7 levels deep like GraphIQL does + fieldType == [ + kind : 'NON_NULL', + name : null, + ofType: [ + kind : 'LIST', + name : null, + ofType: [ + kind : 'LIST', + name : null, + ofType: [ + kind : 'LIST', + name : null, + ofType: [ + kind : 'LIST', + name : null, + ofType: [ + kind : 'LIST', + name : null, + ofType: [ + kind : 'SCALAR', + name : 'Float', + ofType: null] + ] + ] + ] + ] + ] + ] + } + + @Issue("https://github.com/graphql-java/graphql-java/issues/2702") + def "Introspection#__DirectiveLocation(GraphQLEnumType) `name` should match `value`'s DirectiveLocation#name() #2702"() { + given: + def directiveLocationValues = Introspection.__DirectiveLocation.values + + expect: + directiveLocationValues.each { + def value = it.value + assert value instanceof Introspection.DirectiveLocation + assert it.name == (value as Introspection.DirectiveLocation).name() + } + } + + @See("https://spec.graphql.org/October2021/#sec-Schema-Introspection.Schema-Introspection-Schema") + def "Introspection#__DirectiveLocation(GraphQLEnumType) should have 19 distinct values"() { + given: + def directiveLocationValues = Introspection.__DirectiveLocation.values + def numValues = 19 + + expect: + directiveLocationValues.size() == numValues + directiveLocationValues.unique(false).size() == numValues + } + + def "Introspection#__DirectiveLocation(GraphQLEnumType) should contain all Introspection.DirectiveLocation"() { + given: + def directiveLocationValues = new ArrayList<>(Introspection.__DirectiveLocation.values) + def possibleLocations = new ArrayList<>(Introspection.DirectiveLocation.values().toList()).iterator() + + expect: + while (possibleLocations.hasNext()) { + def nextPossibleLocation = possibleLocations.next() + assert directiveLocationValues.retainAll { (it.value != nextPossibleLocation) } + } + assert directiveLocationValues.isEmpty() + } + + def "schema description can be defined in SDL and queried via introspection"() { + given: + def sdl = ''' + """ + This is my schema + """ + schema { + query: Foo + } + + type Foo { + foo: String + } + + ''' + def graphql = TestUtil.graphQL(sdl).build() + when: + def data = graphql.execute("{__schema { description }}").getData() + + then: + data == [__schema: [description: "This is my schema"]] + + } + + def "introspection for repeatable directive info"() { + def spec = ''' + directive @repeatableDirective(arg: String) repeatable on FIELD + + type Query { + namedField: String + } + ''' + + when: + def graphQL = TestUtil.graphQL(spec).build() + def executionResult = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + executionResult.errors.isEmpty() + + def directives = executionResult.data["__schema"]["directives"] as List + def geoPolygonType = directives.find { it['name'] == 'repeatableDirective' } + geoPolygonType["isRepeatable"] == true + } + + def "introspection for deprecated support"() { + def spec = ''' + + directive @someDirective( + deprecatedArg : String @deprecated + notDeprecatedArg : String + ) on FIELD + + type Query { + namedField(arg : InputType @deprecated ) : Enum @deprecated + notDeprecated(arg : InputType) : Enum + } + enum Enum { + RED @deprecated + BLUE + } + input InputType { + inputField : String @deprecated + } + ''' + + when: + def graphQL = TestUtil.graphQL(spec).build() + def executionResult = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + executionResult.errors.isEmpty() + + def types = executionResult.data['__schema']['types'] as List + def queryType = types.find { it['name'] == 'Query' } + def namedField = (queryType['fields'] as List).find({ it["name"] == "namedField" }) + namedField["isDeprecated"] + + def notDeprecatedField = (queryType['fields'] as List).find({ it["name"] == "notDeprecated" }) + !notDeprecatedField["isDeprecated"] + notDeprecatedField["deprecationReason"] == null + + def enumType = types.find { it['name'] == 'Enum' } + def red = enumType["enumValues"].find({ it["name"] == "RED" }) + red["isDeprecated"] + red["deprecationReason"] == "No longer supported" + + def inputType = types.find { it['name'] == 'InputType' } + def inputField = inputType["inputFields"].find({ it["name"] == "inputField" }) + inputField["isDeprecated"] + inputField["deprecationReason"] == "No longer supported" + + def argument = (namedField["args"] as List).find({ it["name"] == "arg" }) + argument["isDeprecated"] + argument["deprecationReason"] == "No longer supported" + + def argument2 = (notDeprecatedField["args"] as List).find({ it["name"] == "arg" }) + !argument2["isDeprecated"] + argument2["deprecationReason"] == null + + + def directives = executionResult.data['__schema']['directives'] as List + def directive = directives.find { it['name'] == "someDirective" } + + def directiveArgs = directive["args"] as List + directiveArgs.collect({ it["name"] }).sort() == ["deprecatedArg", "notDeprecatedArg"] + + def dArgument = directiveArgs.find({ it["name"] == "deprecatedArg" }) + dArgument["isDeprecated"] + dArgument["deprecationReason"] == "No longer supported" + + } + + def "can filter out deprecated things in introspection"() { + + def spec = ''' + + directive @someDirective( + deprecatedArg : String @deprecated + notDeprecatedArg : String + ) on FIELD + + type Query { + namedField(arg : InputType @deprecated, notDeprecatedArg : InputType ) : Enum @deprecated + notDeprecated(arg : InputType @deprecated, notDeprecatedArg : InputType) : Enum + } + enum Enum { + RED @deprecated + BLUE + } + input InputType { + inputField : String @deprecated + notDeprecatedInputField : String + } + ''' + + def graphQL = TestUtil.graphQL(spec).build() + + when: "we dont include deprecated things" + def introspectionQueryWithoutDeprecated = IntrospectionQuery.INTROSPECTION_QUERY.replace("includeDeprecated: true", "includeDeprecated: false") + + def executionResult = graphQL.execute(introspectionQueryWithoutDeprecated) + + then: + executionResult.errors.isEmpty() + + def types = executionResult.data['__schema']['types'] as List + def queryType = types.find { it['name'] == 'Query' } + def fields = (queryType['fields'] as List) + fields.size() == 1 + + def notDeprecatedField = fields[0] + notDeprecatedField["name"] == "notDeprecated" + + def fieldArgs = notDeprecatedField["args"] as List + fieldArgs.size() == 1 + fieldArgs[0]["name"] == "notDeprecatedArg" + + def enumType = types.find { it['name'] == 'Enum' } + def enumValues = (enumType['enumValues'] as List) + enumValues.size() == 1 + enumValues[0]["name"] == "BLUE" + + def inputType = types.find { it['name'] == 'InputType' } + def inputFields = (inputType['inputFields'] as List) + inputFields.size() == 1 + inputFields[0]["name"] == "notDeprecatedInputField" + + when: "we DO include deprecated things" + executionResult = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + types = executionResult.data['__schema']['types'] as List + queryType = types.find { it['name'] == 'Query' } + fields = (queryType['fields'] as List) + + notDeprecatedField = fields.find { it["name"] == "notDeprecated" } + fieldArgs = notDeprecatedField["args"] as List + + enumType = types.find { it['name'] == 'Enum' } + enumValues = (enumType['enumValues'] as List) + + inputType = types.find { it['name'] == 'InputType' } + inputFields = (inputType['inputFields'] as List) + + then: + executionResult.errors.isEmpty() + + fields.size() == 2 + + fieldArgs.size() == 2 + + enumValues.size() == 2 + + inputFields.size() == 2 + } + + def "can change data fetchers for introspection types"() { + def sdl = ''' + type Query { + inA : Int + inB : Int + inC : Int + outA : Int + outB : Int + outC : Int + } + ''' + + def schema = TestUtil.schema(sdl) + def graphQL = newGraphQL(schema).build() + def query = ''' + { + __schema { + types { + name + fields { + name + } + } + } + } + ''' + + when: + def er = graphQL.execute(query) + then: + def queryTypeFields = er.data["__schema"]["types"].find({ it["name"] == "Query" })["fields"] + queryTypeFields == [[name: "inA"], [name: "inB"], [name: "inC"], [name: "outA"], [name: "outB"], [name: "outC"]] + + when: + DataFetcher introspectionFieldsOfTypeFetcher = { env -> + GraphQLNamedType type = env.getSource() + if (type instanceof GraphQLFieldsContainer) { + def fieldDefs = ((GraphQLFieldsContainer) type).getFieldDefinitions() + return fieldDefs.stream().filter({ fld -> fld.getName().startsWith("in") }).collect() + } + } + GraphQLCodeRegistry codeRegistry = schema.getCodeRegistry() + codeRegistry = codeRegistry.transform({ + bld -> bld.dataFetcher(FieldCoordinates.coordinates("__Type", "fields"), introspectionFieldsOfTypeFetcher) + } + ) + schema = schema.transform({ bld -> bld.codeRegistry(codeRegistry) }) + graphQL = newGraphQL(schema).build() + er = graphQL.execute(query) + queryTypeFields = er.data["__schema"]["types"].find({ it["name"] == "Query" })["fields"] + + then: + queryTypeFields == [[name: "inA"], [name: "inB"], [name: "inC"]] + } + + def "test introspection for #296 with map"() { + + def graphql = newGraphQL(newSchema() + .query(newObject() + .name("Query") + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("argument") + .type(newInputObject() + .name("InputObjectType") + .field(newInputObjectField() + .name("inputField") + .type(GraphQLString)) + .build()) + .defaultValueProgrammatic([inputField: 'value1']) + ) + ) + ) + .build() + ).build() + + def query = '{ __type(name: "Query") { fields { args { defaultValue } } } }' + + expect: + // converts the default object value to AST, then graphql pretty prints that as the value + graphql.execute(query).data == + [__type: [fields: [[args: [[defaultValue: '{inputField : "value1"}']]]]]] + } + + class FooBar { + final String inputField = "foo" + final String bar = "bar" + + String getInputField() { + return inputField + } + + String getBar() { + return bar + } + } + + def "test introspection for #296 with some object"() { + + def graphql = newGraphQL(newSchema() + .query(newObject() + .name("Query") + .field(newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(newArgument() + .name("argument") + .type(newInputObject() + .name("InputObjectType") + .field(newInputObjectField() + .name("inputField") + .type(GraphQLString)) + .build()) + .defaultValue(new FooBar()) // Retain for test coverage. There is no alternative method that sets an internal value. + ) + ) + ) + .build() + ).build() + + def query = '{ __type(name: "Query") { fields { args { defaultValue } } } }' + + expect: + // converts the default object value to AST, then graphql pretty prints that as the value + graphql.execute(query).data == + [__type: [fields: [[args: [[defaultValue: '{inputField : "foo"}']]]]]] + } + + def "test AST printed introspection query is equivalent to original string"() { + when: + def oldIntrospectionQuery = "\n" + + " query IntrospectionQuery {\n" + + " __schema {\n" + + " queryType { name }\n" + + " mutationType { name }\n" + + " subscriptionType { name }\n" + + " types {\n" + + " ...FullType\n" + + " }\n" + + " directives {\n" + + " name\n" + + " description\n" + + " locations\n" + + " args(includeDeprecated: true) {\n" + + " ...InputValue\n" + + " }\n" + + " isRepeatable\n" + + " }\n" + + " }\n" + + " }\n" + + "\n" + + " fragment FullType on __Type {\n" + + " kind\n" + + " name\n" + + " description\n" + + " isOneOf\n" + + " fields(includeDeprecated: true) {\n" + + " name\n" + + " description\n" + + " args(includeDeprecated: true) {\n" + + " ...InputValue\n" + + " }\n" + + " type {\n" + + " ...TypeRef\n" + + " }\n" + + " isDeprecated\n" + + " deprecationReason\n" + + " }\n" + + " inputFields(includeDeprecated: true) {\n" + + " ...InputValue\n" + + " }\n" + + " interfaces {\n" + + " ...TypeRef\n" + + " }\n" + + " enumValues(includeDeprecated: true) {\n" + + " name\n" + + " description\n" + + " isDeprecated\n" + + " deprecationReason\n" + + " }\n" + + " possibleTypes {\n" + + " ...TypeRef\n" + + " }\n" + + " }\n" + + "\n" + + " fragment InputValue on __InputValue {\n" + + " name\n" + + " description\n" + + " type { ...TypeRef }\n" + + " defaultValue\n" + + " isDeprecated\n" + + " deprecationReason\n" + + " }\n" + + "\n" + + // + // The depth of the types is actually an arbitrary decision. It could be any depth in fact. This depth + // was taken from GraphIQL https://github.com/graphql/graphiql/blob/master/src/utility/introspectionQueries.js + // which uses 7 levels and hence could represent a type like say [[[[[Float!]]]]] + // + "fragment TypeRef on __Type {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " ofType {\n" + + " kind\n" + + " name\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "\n" + + def newIntrospectionQuery = IntrospectionQuery.INTROSPECTION_QUERY + + + then: + def oldQuery = oldIntrospectionQuery.replaceAll("\\s+", "") + def newQuery = newIntrospectionQuery.replaceAll("\\s+", "") + oldQuery == newQuery + } + + def "test parameterized introspection queries"() { + def spec = ''' + scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") + + directive @repeatableDirective(arg: String) repeatable on FIELD + + """schema description""" + schema { + query: Query + } + + directive @someDirective( + deprecatedArg : String @deprecated + notDeprecatedArg : String + ) repeatable on FIELD + + type Query { + """notDeprecated root field description""" + notDeprecated(arg : InputType @deprecated, notDeprecatedArg : InputType) : Enum + tenDimensionalList : [[[[[[[[[[String]]]]]]]]]] + } + enum Enum { + RED @deprecated + BLUE + } + input InputType { + inputField : String @deprecated + } + ''' + + def graphQL = TestUtil.graphQL(spec).build() + + def parseExecutionResult = { + [ + it.data["__schema"]["types"].find { it["name"] == "Query" }["fields"].find { it["name"] == "notDeprecated" }["description"] != null, // descriptions is true + it.data["__schema"]["types"].find { it["name"] == "UUID" }["specifiedByURL"] != null, // specifiedByUrl is true + it.data["__schema"]["directives"].find { it["name"] == "repeatableDirective" }["isRepeatable"] != null, // directiveIsRepeatable is true + it.data["__schema"]["description"] != null, // schemaDescription is true + it.data["__schema"]["types"].find { it['name'] == 'InputType' }["inputFields"].find({ it["name"] == "inputField" }) != null // inputValueDeprecation is true + ] + } + + when: + def allFalseExecutionResult = graphQL.execute( + IntrospectionQueryBuilder.build( + IntrospectionQueryBuilder.Options.defaultOptions() + .descriptions(false) + .specifiedByUrl(false) + .directiveIsRepeatable(false) + .schemaDescription(false) + .inputValueDeprecation(false) + .typeRefFragmentDepth(5) + ) + ) + then: + !parseExecutionResult(allFalseExecutionResult).any() + allFalseExecutionResult.data["__schema"]["types"].find { it["name"] == "Query" }["fields"].find { it["name"] == "tenDimensionalList" }["type"]["ofType"]["ofType"]["ofType"]["ofType"]["ofType"]["ofType"] == null // typeRefFragmentDepth is 5 + + when: + def allTrueExecutionResult = graphQL.execute( + IntrospectionQueryBuilder.build( + IntrospectionQueryBuilder.Options.defaultOptions() + .descriptions(true) + .specifiedByUrl(true) + .directiveIsRepeatable(true) + .schemaDescription(true) + .inputValueDeprecation(true) + .typeRefFragmentDepth(7) + ) + ) + then: + parseExecutionResult(allTrueExecutionResult).every() + allTrueExecutionResult.data["__schema"]["types"].find { it["name"] == "Query" }["fields"].find { it["name"] == "tenDimensionalList" }["type"]["ofType"]["ofType"]["ofType"]["ofType"]["ofType"]["ofType"]["ofType"]["ofType"] == null // typeRefFragmentDepth is 7 + } + + def "issue 3285 - deprecated defaultValue on programmatic args prints AST literal as expected"() { + def queryObjType = newObject().name("Query") + .field(newFieldDefinition().name("f").type(GraphQLString) + .argument(newArgument().name("arg").type(GraphQLString).defaultValue(null))) + .build() + def schema = newSchema().query(queryObjType).build() + def graphQL = newGraphQL(schema).build() + + + when: + def executionResult = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + then: + executionResult.errors.isEmpty() + + def types = executionResult.data['__schema']['types'] as List + def queryType = types.find { it['name'] == 'Query' } + def fField = (queryType['fields'] as List)[0] + def arg = (fField['args'] as List)[0] + arg['name'] == "arg" + arg['defaultValue'] == "null" // printed AST + } + + + def "introspection for oneOf support"() { + def spec = ''' + + type Query { + oneOfNamedField(arg : OneOfInputType) : Enum + namedField(arg : InputType) : Enum + } + enum Enum { + RED + BLUE + } + input InputType { + inputField : String + } + input OneOfInputType @oneOf { + inputFieldA : String + inputFieldB : String + } + ''' + + when: + def graphQL = TestUtil.graphQL(spec).build() + def executionResult = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + executionResult.errors.isEmpty() + + def types = executionResult.data['__schema']['types'] as List + + def inputType = types.find { it['name'] == 'InputType' } + inputType["isOneOf"] == false + + def oneOfInputType = types.find { it['name'] == 'OneOfInputType' } + oneOfInputType["isOneOf"] == true + + def queryType = types.find { it['name'] == 'Query' } + queryType["isOneOf"] == null + } + + def "jvm wide enablement"() { + def graphQL = TestUtil.graphQL("type Query { f : String } ").build() + + when: + def er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + er.errors.isEmpty() + + when: + Introspection.enabledJvmWide(false) + er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + er.errors[0] instanceof IntrospectionDisabledError + er.errors[0].getErrorType().toString() == "IntrospectionDisabled" + + when: + Introspection.enabledJvmWide(true) + er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + er.errors.isEmpty() + } + + def "per request enablement"() { + def graphQL = TestUtil.graphQL("type Query { f : String } ").build() + + when: + // null context + def ei = ExecutionInput.newExecutionInput(IntrospectionQuery.INTROSPECTION_QUERY) + .build() + def er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + + when: + ei = ExecutionInput.newExecutionInput(IntrospectionQuery.INTROSPECTION_QUERY) + .graphQLContext(Map.of(Introspection.INTROSPECTION_DISABLED, false)).build() + er = graphQL.execute(ei) + + then: + er.errors.isEmpty() + + when: + ei = ExecutionInput.newExecutionInput(IntrospectionQuery.INTROSPECTION_QUERY) + .graphQLContext(Map.of(Introspection.INTROSPECTION_DISABLED, true)).build() + er = graphQL.execute(ei) + + then: + er.errors[0] instanceof IntrospectionDisabledError + er.errors[0].getErrorType().toString() == "IntrospectionDisabled" + } + + def "mixed schema and other fields stop early"() { + def graphQL = TestUtil.graphQL("type Query { normalField : String } ").build() + + def query = """ + query goodAndBad { + normalField + __schema{ types{ fields { name }}} + } + """ + + when: + def er = graphQL.execute(query) + + then: + er.errors.isEmpty() + + when: + Introspection.enabledJvmWide(false) + er = graphQL.execute(query) + + then: + er.errors[0] instanceof IntrospectionDisabledError + er.errors[0].getErrorType().toString() == "IntrospectionDisabled" + er.data == null // stops hard + } + + def "AsyncSerialExecutionStrategy with jvm wide enablement"() { + def graphQL = TestUtil.graphQL("type Query { f : String } ") + .queryExecutionStrategy(new AsyncSerialExecutionStrategy()).build() + + when: + def er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + er.errors.isEmpty() + + when: + Introspection.enabledJvmWide(false) + er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + er.errors[0] instanceof IntrospectionDisabledError + er.errors[0].getErrorType().toString() == "IntrospectionDisabled" + + when: + Introspection.enabledJvmWide(true) + er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + + then: + er.errors.isEmpty() + } + +} diff --git a/src/test/groovy/graphql/introspection/IntrospectionWithDirectivesSupportTest.groovy b/src/test/groovy/graphql/introspection/IntrospectionWithDirectivesSupportTest.groovy new file mode 100644 index 0000000000..591a44146e --- /dev/null +++ b/src/test/groovy/graphql/introspection/IntrospectionWithDirectivesSupportTest.groovy @@ -0,0 +1,239 @@ +package graphql.introspection + +import graphql.GraphQL +import graphql.TestUtil +import spock.lang.Specification + +class IntrospectionWithDirectivesSupportTest extends Specification { + + def "can find directives in introspection"() { + def sdl = ''' + directive @example( argName : String = "default") on OBJECT | FIELD_DEFINITION | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA + directive @secret( argName : String = "secret") on OBJECT + directive @noDefault( arg1 : String, arg2 : String) on OBJECT + + schema @example(argName : "onSchema") { + query : Query + } + + type Query @example(argName : "onQuery") @noDefault(arg1 : "set") { + hello : Hello @deprecated + } + + type Hello @example @noDefault { + world : String @deprecated + } + + input InputType { + inputField : String @example(argName : "onInputField") + } + ''' + + def schema = TestUtil.schema(sdl) + schema = new IntrospectionWithDirectivesSupport().apply(schema) + def graphql = GraphQL.newGraphQL(schema).build() + + def query = ''' + { + __schema { + directives { + name + } + appliedDirectives { + name + args { + name + value + } + } + types { + name + appliedDirectives { + name + args { + name + value + } + } + fields(includeDeprecated:true) { + name + appliedDirectives { + name + args { + name + value + } + } + } + inputFields { + name + appliedDirectives { + name + args { + name + value + } + } + } + } + } + } + ''' + + when: + + def er = graphql.execute(query) + then: + er.errors.isEmpty() + println TestUtil.prettyPrint(er) + + def schemaType = er.data["__schema"] + + schemaType["directives"] == [ + [name: "include"], [name: "skip"], [name: "example"], [name: "secret"], + [name: "noDefault"], [name: "deprecated"], [name: "specifiedBy"], [name: "oneOf"], + [name: "defer"], [name: "experimental_disableErrorPropagation"] + ] + + schemaType["appliedDirectives"] == [[name: "example", args: [[name: "argName", value: '"onSchema"']]]] + + def queryType = er.data["__schema"]["types"].find({ type -> (type["name"] == "Query") }) + queryType["appliedDirectives"] == [ + [name: "example", args: [[name: "argName", value: '"onQuery"']]], + [name: "noDefault", args: [[name: "arg1", value: '"set"']]] + ] + + def helloType = er.data["__schema"]["types"].find({ type -> (type["name"] == "Hello") }) + helloType["appliedDirectives"] == [ + [name: "example", args: [[name: "argName", value: '"default"']]], + [name: "noDefault", args: []] // always empty list + ] + + def worldField = helloType["fields"].find({ type -> (type["name"] == "world") }) + worldField["appliedDirectives"] == [[name: 'deprecated', args: [[name: 'reason', value: '"No longer supported"']]]] + + def inputType = er.data["__schema"]["types"].find({ type -> (type["name"] == "InputType") }) + def inputField = inputType["inputFields"].find({ type -> (type["name"] == "inputField") }) + inputField["appliedDirectives"] == [[name: 'example', args: [[name: 'argName', value: '"onInputField"']]]] + + } + + def "can filter the directives returned in introspection"() { + def sdl = ''' + directive @example( argName : String = "default") on OBJECT + directive @secret( argName : String = "secret") on OBJECT + + type Query { + hello : Hello + } + + type Hello @example @secret { + world : String + } + ''' + + def schema = TestUtil.schema(sdl) + def filter = new IntrospectionWithDirectivesSupport.DirectivePredicate() { + @Override + boolean isDirectiveIncluded(IntrospectionWithDirectivesSupport.DirectivePredicateEnvironment env) { + return !env.getDirectiveName().contains("secret") + } + } + schema = new IntrospectionWithDirectivesSupport(filter).apply(schema) + + def graphql = GraphQL.newGraphQL(schema).build() + + def query = ''' + { + __schema { + directives { + name + } + types { + name + appliedDirectives { + name + args { + name + value + } + } + } + } + } + ''' + + when: + + def er = graphql.execute(query) + then: + er.errors.isEmpty() + + def helloType = er.data["__schema"]["types"].find({ type -> (type["name"] == "Hello") }) + helloType["appliedDirectives"] == [[name: "example", args: [[name: "argName", value: '"default"']]]] + + def definedDirectives = er.data["__schema"]["directives"] + // secret is filter out + definedDirectives == [[name: "include"], [name: "skip"], [name: "example"], [name: "deprecated"], [name: "specifiedBy"], [name: "oneOf"], + [name: "defer"], [name: "experimental_disableErrorPropagation"] + ] + } + + def "can set prefixes onto the Applied types"() { + def sdl = ''' + type Query { + hello : __Hello + } + + type __Hello { + world : _Bar + } + + type _Bar { + bar : String + } + ''' + + def schema = TestUtil.schema(sdl) + def filter = new IntrospectionWithDirectivesSupport.DirectivePredicate() { + @Override + boolean isDirectiveIncluded(IntrospectionWithDirectivesSupport.DirectivePredicateEnvironment env) { + return !env.getDirective().getName().contains("secret") + } + } + def newSchema = new IntrospectionWithDirectivesSupport(filter, "__x__").apply(schema) + def graphql = GraphQL.newGraphQL(newSchema).build() + + def query = ''' + { + __schema { + types { + name + } + } + } + ''' + + when: + def er = graphql.execute(query) + then: + er.errors.isEmpty() + def types = er.data["__schema"]["types"] + + types.find({ type -> (type["name"] == "__x__AppliedDirective") }) != null + types.find({ type -> (type["name"] == "__x__DirectiveArgument") }) != null + + when: + + newSchema = new IntrospectionWithDirectivesSupport(filter, "__").apply(schema) + graphql = GraphQL.newGraphQL(newSchema).build() + er = graphql.execute(query) + + then: + er.errors.isEmpty() + def types2 = er.data["__schema"]["types"] + + types2.find({ type -> (type["name"] == "__AppliedDirective") }) != null + types2.find({ type -> (type["name"] == "__DirectiveArgument") }) != null + } +} diff --git a/src/test/groovy/graphql/language/AstMultiZipperTest.groovy b/src/test/groovy/graphql/language/AstMultiZipperTest.groovy new file mode 100644 index 0000000000..a878678d3e --- /dev/null +++ b/src/test/groovy/graphql/language/AstMultiZipperTest.groovy @@ -0,0 +1,96 @@ +package graphql.language + +import graphql.TestUtil +import graphql.util.Breadcrumb +import graphql.util.NodeLocation +import graphql.util.NodeMultiZipper +import graphql.util.NodeZipper +import spock.lang.Specification + +import static graphql.language.AstNodeAdapter.AST_NODE_ADAPTER + + +class AstMultiZipperTest extends Specification { + + + def "toRootNode with one zipper"() { + def rootNode = TestUtil.parseQuery("{root{midA{leafA leafB} midB{leafC leafD}}}") + def operationDefinition = rootNode.children[0] as OperationDefinition + + def rootField = operationDefinition.selectionSet.children[0] as Field + def midA = rootField.selectionSet.children[0] as Field + + def midB = rootField.selectionSet.children[1] as Field + + + def b1 = new Breadcrumb(rootNode, new NodeLocation(Document.CHILD_DEFINITIONS, 0)) + def b2 = new Breadcrumb(operationDefinition, new NodeLocation(OperationDefinition.CHILD_SELECTION_SET, 0)) + def b3 = new Breadcrumb(operationDefinition.selectionSet, new NodeLocation(SelectionSet.CHILD_SELECTIONS, 0)) + def b4 = new Breadcrumb(rootField, new NodeLocation(Field.CHILD_SELECTION_SET, 0)) + def b5 = new Breadcrumb(rootField.selectionSet, new NodeLocation(SelectionSet.CHILD_SELECTIONS, 0)) + + def breadCrumbsFromMidA = [b5, b4, b3, b2, b1] + + def midAZipper = new NodeZipper(midA, breadCrumbsFromMidA, AST_NODE_ADAPTER) + def midAZipperChanged = midAZipper.withNewNode(midA.transform({ builder -> builder.name("midA-changed") })) + def multiZipper = new NodeMultiZipper(rootNode, [midAZipperChanged], AST_NODE_ADAPTER) + + when: + def newRoot = multiZipper.toRootNode() + def newMidA = getMidA(newRoot) as Field + + then: + newMidA.name == "midA-changed" + } + + Node rootField(Document document) { + def operationDefinition = document.children[0] as OperationDefinition + operationDefinition.selectionSet.children[0] as Field + } + + Node getMidA(Document document) { + rootField(document).selectionSet.children[0] as Field + } + + Node getMidB(Document document) { + rootField(document).selectionSet.children[1] as Field + } + + def "toRootNode with two zippers"() { + def rootNode = TestUtil.parseQuery("{root{midA{leafA leafB} midB{leafC leafD}}}") + def operationDefinition = rootNode.children[0] as OperationDefinition + + def rootField = operationDefinition.selectionSet.children[0] as Field + def midA = rootField.selectionSet.children[0] as Field + + def midB = rootField.selectionSet.children[1] as Field + + + def b1 = new Breadcrumb(rootNode, new NodeLocation(Document.CHILD_DEFINITIONS, 0)) + def b2 = new Breadcrumb(operationDefinition, new NodeLocation(OperationDefinition.CHILD_SELECTION_SET, 0)) + def b3 = new Breadcrumb(operationDefinition.selectionSet, new NodeLocation(SelectionSet.CHILD_SELECTIONS, 0)) + def b4 = new Breadcrumb(rootField, new NodeLocation(Field.CHILD_SELECTION_SET, 0)) + def bMidA = new Breadcrumb(rootField.selectionSet, new NodeLocation(SelectionSet.CHILD_SELECTIONS, 0)) + def bMidB = new Breadcrumb(rootField.selectionSet, new NodeLocation(SelectionSet.CHILD_SELECTIONS, 1)) + + def breadCrumbsFromMidA = [bMidA, b4, b3, b2, b1] + def breadCrumbsFromMidB = [bMidB, b4, b3, b2, b1] + + def midAChanged = midA.transform({ builder -> builder.name("midA-changed") }) + def midBChanged = midB.transform({ builder -> builder.name("midB-changed") }) + + def midAZipperChanged = new NodeZipper(midAChanged, breadCrumbsFromMidA, AST_NODE_ADAPTER) + def midBZipperChanged = new NodeZipper(midBChanged, breadCrumbsFromMidB, AST_NODE_ADAPTER) + def multiZipper = new NodeMultiZipper(rootNode, [midAZipperChanged, midBZipperChanged], AST_NODE_ADAPTER) + + when: + def newRoot = multiZipper.toRootNode() + def newMidA = getMidA(newRoot) as Field + def newMidB = getMidB(newRoot) as Field + + then: + newMidA.name == "midA-changed" + newMidB.name == "midB-changed" + + } +} diff --git a/src/test/groovy/graphql/language/AstPrinterTest.groovy b/src/test/groovy/graphql/language/AstPrinterTest.groovy index a373b4d2bf..84c2de667a 100644 --- a/src/test/groovy/graphql/language/AstPrinterTest.groovy +++ b/src/test/groovy/graphql/language/AstPrinterTest.groovy @@ -3,6 +3,8 @@ package graphql.language import graphql.parser.Parser import spock.lang.Specification +import java.nio.CharBuffer + class AstPrinterTest extends Specification { Document parse(String input) { @@ -19,6 +21,16 @@ class AstPrinterTest extends Specification { AstPrinter.printAst(node) } + boolean isParseableAst(ast) { + try { + def document = parse(ast) + return document != null + } catch (Exception ignored) { + return false + } + } + + def starWarsSchema = """ # objects can have comments # over a number of lines @@ -95,15 +107,12 @@ scalar DateTime // // notice how it tightens everything up // - output == """# objects can have comments -# over a number of lines -schema { + output == """schema { query: QueryType mutation: Mutation } type QueryType { - # the hero of the film hero(episode: Episode): Character human(id: String): Human droid(id: ID!): Droid @@ -169,9 +178,7 @@ scalar DateTime String output = printAst(document.getDefinitions().get(0)) expect: - output == """# objects can have comments -# over a number of lines -schema { + output == """schema { query: QueryType mutation: Mutation }""" @@ -183,7 +190,6 @@ schema { expect: output == """type QueryType { - # the hero of the film hero(episode: Episode): Character human(id: String): Human droid(id: ID!): Droid @@ -205,7 +211,7 @@ schema { String output = printAst(document) expect: - output == """query { + output == """{ empireHero: hero(episode: EMPIRE) { name } @@ -241,7 +247,7 @@ fragment comparisonFields on Character { String output = printAst(document) expect: - output == """query { + output == """{ leftComparison: hero(episode: EMPIRE) { ...comparisonFields } @@ -286,7 +292,7 @@ query HeroNameAndFriends($episode: Episode) { def query = ''' query Hero($episode: Episode, $withFriends: Boolean!) { hero ( episode: $episode) { - name + name @repeatable @repeatable friends @include (if : $withFriends) { name } @@ -297,9 +303,10 @@ query Hero($episode: Episode, $withFriends: Boolean!) { String output = printAst(document) expect: + isParseableAst(output) output == '''query Hero($episode: Episode, $withFriends: Boolean!) { hero(episode: $episode) { - name + name @repeatable @repeatable friends @include(if: $withFriends) { name } @@ -338,8 +345,40 @@ query HeroForEpisode($ep: Episode!) { } } ''' + isParseableAst(output) } + def "ast printing of inline fragments in compactMode"() { + def query = ''' +query HeroForEpisode($ep: Episode!) { + hero(episode: $ep) { + name + ... on Droid { + primaryFunction + id + } + ... on Human { + height + id + } + age { + inMonths + inYears + } + } +}''' + when: + def document = parse(query) + String output = AstPrinter.printAstCompact(document) + + then: + + isParseableAst(output) + + output == 'query HeroForEpisode($ep:Episode!){hero(episode:$ep){name ...on Droid{primaryFunction id}...on Human{height id}age{inMonths inYears}}}' + } + + //------------------------------------------------- def "ast printing of default variables"() { def query = ''' @@ -408,6 +447,26 @@ query NullEpisodeQuery { ''' } + def "ast printing of blank string"() { + def query = ''' +query NullEpisodeQuery { + human(id: " ") { + name + } +} +''' + def document = parse(query) + String output = printAst(document) + + expect: + output == '''query NullEpisodeQuery { + human(id: " ") { + name + } +} +''' + } + //------------------------------------------------- def "ast printing of default variables with null"() { def query = ''' @@ -452,20 +511,52 @@ type Query { expect: output == '''type Query { + field(arg1: String, arg2: String, arg3: String): String +} +''' + + } + + def "print field descriptions"() { + def query = '''type Query { + "description" + field( + "description" + a: String): String +} +''' + def document = parse(query) + String output = printAst(document) + expect: + output == '''type Query { + "description" field( - #description1 - arg1: String - arg2: String - #description3 - arg3: String - ): String + "description" + a: String): String } ''' + } + + def "print empty description"() { + def query = ''' +"" +scalar Demo +''' + def document = parse(query) + String output = printAst(document) + expect: + output == '''"" +scalar Demo +''' } def "print type extensions"() { def query = ''' + extend schema { + query: Query + } + extend type Object @directive { objectField : String } @@ -491,7 +582,11 @@ type Query { String output = printAst(document) expect: - output == '''extend type Object @directive { + output == '''extend schema { + query: Query +} + +extend type Object @directive { objectField: String } @@ -516,12 +611,201 @@ extend input Input @directive { } def "compact ast printing"() { - def query = "{foo {hello} world}" + def query = ''' + { + #comments go away + aliasOfFoo : foo(arg1 : "val1", args2 : "val2") @isCached @orIsItNotCached { # and this comment as well + hello + } + world @neverCache @youSaidCache @okThenCache + } + + fragment FX on SomeType { + aliased : field(withArgs : "argVal", andMoreArgs : "andMoreVals") + } +''' def document = parse(query) String output = AstPrinter.printAstCompact(document) expect: - output == "query { foo { hello } world }" + isParseableAst(output) + output == '''{aliasOfFoo:foo(arg1:"val1",args2:"val2") @isCached@orIsItNotCached{hello}world @neverCache@youSaidCache@okThenCache} fragment FX on SomeType {aliased:field(withArgs:"argVal",andMoreArgs:"andMoreVals")}''' + } + + def "can tighten fields with no query prefix"() { + when: + def doc = parse("{root { fooA{ midB{ leafB}} fooB{ midB{ leafB }}}}") + def output = AstPrinter.printAstCompact(doc) + then: + isParseableAst(output) + output == "{root{fooA{midB{leafB}}fooB{midB{leafB}}}}" + } + + def "print ast with inline fragment without type condition"() { + def query = ''' + { + foo { + ... { + hello + } + } + } +''' + def document = parse(query) + String outputCompact = AstPrinter.printAstCompact(document) + String outputFull = AstPrinter.printAst(document) + + expect: + outputCompact == '''{foo{...{hello}}}''' + outputFull == '''{ + foo { + ... { + hello + } + } +} +''' + isParseableAst(outputCompact) + isParseableAst(outputFull) + } + + def 'StringValue is converted to valid Strings'() { + + when: + def result = AstPrinter.printAstCompact(new StringValue(strValue)) + + then: + result == expected + + where: + strValue | expected + 'VALUE' | '"VALUE"' + 'VA\n\t\f\n\b\\LUE' | '"VA\\n\\t\\f\\n\\b\\\\LUE"' + 'VA\\L"UE' | '"VA\\\\L\\"UE"' + } + + def 'Interfaces implementing interfaces'() { + given: + def interfaceType = InterfaceTypeDefinition + .newInterfaceTypeDefinition() + .name("Resource") + .implementz(new TypeName("Node")) + .implementz(new TypeName("Extra")) + .build() + + + when: + def result = AstPrinter.printAstCompact(interfaceType) + + then: + result == "interface Resource implements Node & Extra" + + } + + def 'Interfaces implementing interfaces in extension'() { + given: + def interfaceType = InterfaceTypeExtensionDefinition + .newInterfaceTypeExtensionDefinition() + .name("Resource") + .implementz(new TypeName("Node")) + .implementz(new TypeName("Extra")) + .build() + + when: + def result = AstPrinter.printAstCompact(interfaceType) + + then: + result == "extend interface Resource implements Node & Extra" + + } + + def "directive definitions can be printed"() { + + given: + def directiveDef1 = DirectiveDefinition.newDirectiveDefinition() + .name("d1") + .repeatable(true) + .directiveLocation(DirectiveLocation.newDirectiveLocation().name("FIELD").build()) + .directiveLocation(DirectiveLocation.newDirectiveLocation().name("OBJECT").build()) + .build() + + def directiveDef2 = DirectiveDefinition.newDirectiveDefinition() + .name("d2") + .repeatable(false) + .directiveLocation(DirectiveLocation.newDirectiveLocation().name("FIELD").build()) + .directiveLocation(DirectiveLocation.newDirectiveLocation().name("ENUM").build()) + .build() + + when: + def result = AstPrinter.printAstCompact(directiveDef1) + + then: + result == "directive @d1 repeatable on FIELD | OBJECT" + + when: + result = AstPrinter.printAstCompact(directiveDef2) + + then: + result == "directive @d2 on FIELD | ENUM" + + } + + def "empty type does not include braces"() { + def sdl = "type Query" + def document = parse(sdl) + + when: + String output = printAst(document) + then: + output == "type Query\n" + } + + def "empty selection set does not include braces"() { + // technically below is not valid graphql and will never be parsed as is + def field_with_empty_selection_set = Field.newField("foo") + .selectionSet(SelectionSet.newSelectionSet().build()) + .build() + + when: + String output = printAst(field_with_empty_selection_set) + then: + output == "foo" + } + + def "printAstTo writes to a StringBuilder instance"() { + def document = parse(starWarsSchema) + def output = new StringBuilder() + AstPrinter.printAstTo(document.getDefinitions().get(0), output) + + expect: + output.toString() == """schema { + query: QueryType + mutation: Mutation +}""" + } + + def "printAstTo writes to a Writer instance"() { + def document = parse(starWarsSchema) + def output = new StringWriter() + AstPrinter.printAstTo(document.getDefinitions().get(0), output) + + expect: + output.toString() == """schema { + query: QueryType + mutation: Mutation +}""" } + def "printAstTo writes to an Appendable instance"() { + def document = parse(starWarsSchema) + def output = CharBuffer.allocate(100) + AstPrinter.printAstTo(document.getDefinitions().get(0), output) + output.flip() + + expect: + output.toString() == """schema { + query: QueryType + mutation: Mutation +}""" + } } diff --git a/src/test/groovy/graphql/language/AstSignatureTest.groovy b/src/test/groovy/graphql/language/AstSignatureTest.groovy new file mode 100644 index 0000000000..0bf57022cf --- /dev/null +++ b/src/test/groovy/graphql/language/AstSignatureTest.groovy @@ -0,0 +1,129 @@ +package graphql.language + +import graphql.TestUtil +import spock.lang.Specification + +import static graphql.language.AstPrinter.printAst + +class AstSignatureTest extends Specification { + + def query = ''' + query Ouch($secretVariable : String, $otherVariable : Int) { + fieldZ + fieldX(password : "hunter2", accountBalance : 200000.23, + avatar : { name : "secretPicture", url : "http://someplace" } + favouriteThings : [ "brown", "paper", "packages", "tied", "up", "in", "string" ] + likesIceCream : true + argToAVariable : $secretVariable + anotherArg : $otherVariable + ) + fieldY { + innerFieldA + innerFieldC + innerFieldB + } + ... X + } + + query Ohh { + fieldZ + fieldX + fieldY { + innerFieldA + innerFieldC + innerFieldB + } + } + + { + unnamedQuery + withFields + } + + fragment X on SomeType { + fieldX(password : "hunter2", accountBalance : 200000.23, + avatar : { name : "secretPicture", url : "http://some place" } + favouriteThings : [ "brown", "paper", "packages", "tied", "up", "in", "string" ] + likesIceCream : true + ) + } + + type RogueSDLElement { + field : String + } +''' + def "can make a signature for a query"() { + + def expectedQuery = '''query Ouch($var1: String, $var2: Int) { + fieldX(accountBalance: 0, anotherArg: $var2, argToAVariable: $var1, avatar: {}, favouriteThings: [], likesIceCream: false, password: "") + fieldY { + innerFieldA + innerFieldB + innerFieldC + } + fieldZ + ...X +} + +fragment X on SomeType { + fieldX(accountBalance: 0, avatar: {}, favouriteThings: [], likesIceCream: false, password: "") +} +''' + def doc = TestUtil.parseQuery(query) + when: + def newDoc = new AstSignature().signatureQuery(doc, "Ouch") + then: + newDoc != null + printAst(newDoc) == expectedQuery + } + + def "can make a privacy safe document for a query"() { + + def expectedQuery = '''query Ouch($var1: String, $var2: Int) { + fieldX(accountBalance: 0, anotherArg: $var2, argToAVariable: $var1, avatar: {name : "", url : ""}, favouriteThings: ["", "", "", "", "", "", ""], likesIceCream: false, password: "") + fieldY { + innerFieldA + innerFieldB + innerFieldC + } + fieldZ + ...X +} + +fragment X on SomeType { + fieldX(accountBalance: 0, avatar: {name : "", url : ""}, favouriteThings: ["", "", "", "", "", "", ""], likesIceCream: false, password: "") +} +''' + def doc = TestUtil.parseQuery(query) + when: + def newDoc = new AstSignature().privacySafeQuery(doc, "Ouch") + then: + newDoc != null + printAst(newDoc) == expectedQuery + } + + def "can do signature on queries with no name"() { + def query = """ + { + allIssues(arg1 : "UGC", arg2 : 666) { + id + } + }""" + + def expectedQuery = """{ + allIssues(arg1: "", arg2: 0) { + id + } +} +""" + + def doc = TestUtil.parseQuery(query) + when: + def newDoc = new AstSignature().signatureQuery(doc, null) + then: + newDoc != null + printAst(newDoc) == expectedQuery + + + } +} diff --git a/src/test/groovy/graphql/language/AstSorterTest.groovy b/src/test/groovy/graphql/language/AstSorterTest.groovy new file mode 100644 index 0000000000..498598d715 --- /dev/null +++ b/src/test/groovy/graphql/language/AstSorterTest.groovy @@ -0,0 +1,356 @@ +package graphql.language + + +import spock.lang.Specification + +import static graphql.TestUtil.parseQuery +import static graphql.language.AstPrinter.printAst + +class AstSorterTest extends Specification { + + def "basic sorting of a query works"() { + def query = ''' + { + unamedQueryY + unamedQueryZ + unamedQueryX + } + + query QZ { + fieldZ(z: "valz", x : "valx", y:"valy") { + subfieldz + subfieldx + subfieldy + } + fieldX(z: "valz", x : "valx", y:"valy") { + subfieldz + subfieldx + subfieldy + } + } + + query QX { + ... inlineFragmentB + field(z: "valz", x : "valx", y:"valy") { + subfieldz + subfieldx(b : "valb", a : "vala", c : "valc") + subfieldy + } + ... on Z { + subfieldC + subfieldA + subfieldB + } + ... inlineFragmentA + ... on X { + subfieldC + subfieldA + subfieldB + } + ... inlineFragmentC + } + + query QY($varZ : Int = 3, $varX : Int = 1, $varY : Int = 2) @directiveC @directiveA @directiveB { + ... on SomeTypeB { + fieldC + fieldB + fieldA @directiveSWithArgs(argZ : "valZ", argX : "valX", argY : "valY") + } + ... on SomeTypeA { + fieldC + fieldB + fieldA @directiveSWithArgs(argZ : "valZ", argX : "valX", argY : "valY") + } + } + + fragment FZ on SomeType { + fieldY(z: "valz", x : "valx", y:"valy") { + subfieldb + subfielda + } + fieldX(z: "valz", x : "valx", y:"valy") { + subfieldb + subfielda + } + } + fragment FX on SomeType { + fieldY(z: "valz", x : "valx", y:"valy") { + subfieldb + subfielda + } + fieldX(z: "valz", x : "valx", y:"valy") { + subfieldb + subfielda + } + } + fragment FY on SomeType { + fieldY(z: "valz", x : "valx", y:"valy") { + subfieldb + subfielda + } + fieldX(z: "valz", x : "valx", y:"valy") { + subfieldb + subfielda + } + } + + +''' + + def expectedQuery = '''{ + unamedQueryX + unamedQueryY + unamedQueryZ +} + +query QX { + field(x: "valx", y: "valy", z: "valz") { + subfieldx(a: "vala", b: "valb", c: "valc") + subfieldy + subfieldz + } + ...inlineFragmentA + ...inlineFragmentB + ...inlineFragmentC + ... on X { + subfieldA + subfieldB + subfieldC + } + ... on Z { + subfieldA + subfieldB + subfieldC + } +} + +query QY($varX: Int = 1, $varY: Int = 2, $varZ: Int = 3) @directiveA @directiveB @directiveC { + ... on SomeTypeA { + fieldA @directiveSWithArgs(argX: "valX", argY: "valY", argZ: "valZ") + fieldB + fieldC + } + ... on SomeTypeB { + fieldA @directiveSWithArgs(argX: "valX", argY: "valY", argZ: "valZ") + fieldB + fieldC + } +} + +query QZ { + fieldX(x: "valx", y: "valy", z: "valz") { + subfieldx + subfieldy + subfieldz + } + fieldZ(x: "valx", y: "valy", z: "valz") { + subfieldx + subfieldy + subfieldz + } +} + +fragment FX on SomeType { + fieldX(x: "valx", y: "valy", z: "valz") { + subfielda + subfieldb + } + fieldY(x: "valx", y: "valy", z: "valz") { + subfielda + subfieldb + } +} + +fragment FY on SomeType { + fieldX(x: "valx", y: "valy", z: "valz") { + subfielda + subfieldb + } + fieldY(x: "valx", y: "valy", z: "valz") { + subfielda + subfieldb + } +} + +fragment FZ on SomeType { + fieldX(x: "valx", y: "valy", z: "valz") { + subfielda + subfieldb + } + fieldY(x: "valx", y: "valy", z: "valz") { + subfielda + subfieldb + } +} +''' + + def doc = parseQuery(query) + + when: + def newDoc = new AstSorter().sort(doc) + then: + printAst(newDoc) == expectedQuery + } + + def "sdl will sort as expected"() { + def sdl = ''' + + interface InterfaceZ { + fieldZ(argC : Int, argA : Int, argB : Int) : Int + fieldX(argC : Int, argA : Int, argB : Int) : Int + fieldY(argC : Int, argA : Int, argB : Int) : Int + } + + interface InterfaceX { + fieldZ(argC : Int, argA : Int, argB : Int) : Int + fieldX(argC : Int, argA : Int, argB : Int) : Int + fieldY(argC : Int, argA : Int, argB : Int) : Int + } + + union UnionZ = Foo | Bar + + union UnionX = Foo | Bar + + schema { + query : QueryType + mutation : MutationType + subscription : SubscriptionType + } + + type TypeZ { + fieldZ(argC : Int, argA : Int, argB : Int) : Int + fieldX(argC : Int, argA : Int, argB : Int) : Int + fieldY(argC : Int, argA : Int, argB : Int) : Int + } + + type TypeX { + fieldZ(argC : Int, argA : Int, argB : Int) : Int + fieldX(argC : Int, argA : Int, argB : Int) : Int + fieldY(argC : Int, argA : Int, argB : Int) : Int + } + + input InputZ { + fieldZ : String + fieldX : String + fieldY : String + } + + input InputX { + fieldZ : String + fieldX : String + fieldY : String + } + + + scalar ScalarZ + scalar ScalarX + + directive @directiveZ on FIELD_DEFINITION | ENUM_VALUE + + directive @directiveX on FIELD_DEFINITION | ENUM_VALUE + + enum EnumZ { + Z, Y , X + } + + enum EnumX { + Z, Y , X + } +''' + + def expectedSDL = '''directive @directiveX on ENUM_VALUE | FIELD_DEFINITION + +directive @directiveZ on ENUM_VALUE | FIELD_DEFINITION + +schema { + mutation: MutationType + query: QueryType + subscription: SubscriptionType +} + +type TypeX { + fieldX(argA: Int, argB: Int, argC: Int): Int + fieldY(argA: Int, argB: Int, argC: Int): Int + fieldZ(argA: Int, argB: Int, argC: Int): Int +} + +type TypeZ { + fieldX(argA: Int, argB: Int, argC: Int): Int + fieldY(argA: Int, argB: Int, argC: Int): Int + fieldZ(argA: Int, argB: Int, argC: Int): Int +} + +interface InterfaceX { + fieldX(argA: Int, argB: Int, argC: Int): Int + fieldY(argA: Int, argB: Int, argC: Int): Int + fieldZ(argA: Int, argB: Int, argC: Int): Int +} + +interface InterfaceZ { + fieldX(argA: Int, argB: Int, argC: Int): Int + fieldY(argA: Int, argB: Int, argC: Int): Int + fieldZ(argA: Int, argB: Int, argC: Int): Int +} + +union UnionX = Bar | Foo + +union UnionZ = Bar | Foo + +enum EnumX { + X + Y + Z +} + +enum EnumZ { + X + Y + Z +} + +scalar ScalarX + +scalar ScalarZ + +input InputX { + fieldX: String + fieldY: String + fieldZ: String +} + +input InputZ { + fieldX: String + fieldY: String + fieldZ: String +} +''' + + def doc = parseQuery(sdl) + + when: + def newDoc = new AstSorter().sort(doc) + then: + printAst(newDoc) == expectedSDL + } + + def "object literals gets sorted"() { + def query = ''' + { + field( arg : { z : "valz", x : { c : "valc" , a : "vala", b : "valb" }, y : "valy" } ) + } + ''' + + def expectedQuery = '''{ + field(arg: {x : {a : "vala", b : "valb", c : "valc"}, y : "valy", z : "valz"}) +} +''' + + def doc = parseQuery(query) + + when: + def newDoc = new AstSorter().sort(doc) + then: + printAst(newDoc) == expectedQuery + + } +} diff --git a/src/test/groovy/graphql/language/AstTransformerTest.groovy b/src/test/groovy/graphql/language/AstTransformerTest.groovy new file mode 100644 index 0000000000..f0eeaed400 --- /dev/null +++ b/src/test/groovy/graphql/language/AstTransformerTest.groovy @@ -0,0 +1,929 @@ +package graphql.language + +import graphql.TestUtil +import graphql.util.TraversalControl +import graphql.util.TraverserContext +import spock.lang.Specification + +import static graphql.language.AstPrinter.printAst +import static graphql.language.AstPrinter.printAstCompact +import static graphql.util.TreeTransformerUtil.changeNode +import static graphql.util.TreeTransformerUtil.deleteNode +import static graphql.util.TreeTransformerUtil.insertAfter +import static graphql.util.TreeTransformerUtil.insertBefore + +class AstTransformerTest extends Specification { + + def "modify multiple nodes"() { + def document = TestUtil.parseQuery("{ root { foo { midA { leafA } midB { leafB } } bar { midC { leafC } midD { leafD } } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + if (!node.name.startsWith("mid")) { + return TraversalControl.CONTINUE + } + String newName = node.name + "-modified" + + Field changedField = node.transform({ builder -> builder.name(newName) }) + return changeNode(context, changedField) + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == + "{root{foo{midA-modified{leafA}midB-modified{leafB}}bar{midC-modified{leafC}midD-modified{leafD}}}}" + } + + def "modify multiple nodes parallel"() { + def document = TestUtil.parseQuery("{ root { foo { midA { leafA } midB { leafB } } bar { midC { leafC } midD { leafD } } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + Thread.sleep(50); + if (!node.name.startsWith("mid")) { + return TraversalControl.CONTINUE + } + String newName = node.name + "-modified" + + Field changedField = node.transform({ builder -> builder.name(newName) }) + return changeNode(context, changedField) + } + } + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == + "{root{foo{midA-modified{leafA}midB-modified{leafB}}bar{midC-modified{leafC}midD-modified{leafD}}}}" + } + + def "no change at all"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + + when: + def newDocument = astTransformer.transform(document, new NodeVisitorStub()) + + then: + newDocument == document + + } + + def "no change at all parallel"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + + when: + def newDocument = astTransformer.transformParallel(document, new NodeVisitorStub()) + + then: + newDocument == document + + } + + def "one node changed"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + Field changedField = node.transform({ builder -> builder.name("foo2") }) + return changeNode(context, changedField) + } + } + + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2}" + + } + + def "one node changed parallel"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + Field changedField = node.transform({ builder -> builder.name("foo2") }) + return changeNode(context, changedField) + } + } + + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2}" + + } + + def "add new children"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + if (node.name != "foo") return TraversalControl.CONTINUE; + def newSelectionSet = SelectionSet.newSelectionSet([new Field("a"), new Field("b")]).build() + Field changedField = node.transform({ builder -> builder.name("foo2").selectionSet(newSelectionSet) }) + return changeNode(context, changedField) + } + } + + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2{a b}}" + + } + + def "add new children parallel"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + if (node.name != "foo") return TraversalControl.CONTINUE; + def newSelectionSet = SelectionSet.newSelectionSet([new Field("a"), new Field("b")]).build() + Field changedField = node.transform({ builder -> builder.name("foo2").selectionSet(newSelectionSet) }) + return changeNode(context, changedField) + } + } + + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2{a b}}" + + } + + + def "reorder children and sub children"() { + def document = TestUtil.parseQuery("{root { b(b_arg: 1) { y x } a(a_arg:2) { w v } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitSelectionSet(SelectionSet node, TraverserContext context) { + if (node.getChildren().isEmpty()) return TraversalControl.CONTINUE; + def selections = new ArrayList<>(node.getSelections()) + Collections.sort(selections, { o1, o2 -> (o1.name <=> o2.name) }) + Node changed = node.transform({ builder -> builder.selections(selections) }) + return changeNode(context, changed) + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(a_arg:2){v w}b(b_arg:1){x y}}}" + + } + + def "reorder children and sub children parallel"() { + def document = TestUtil.parseQuery("{root { b(b_arg: 1) { y x } a(a_arg:2) { w v } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitSelectionSet(SelectionSet node, TraverserContext context) { + if (node.getChildren().isEmpty()) return TraversalControl.CONTINUE; + def selections = new ArrayList<>(node.getSelections()) + Collections.sort(selections, { o1, o2 -> (o1.name <=> o2.name) }) + Node changed = node.transform({ builder -> builder.selections(selections) }) + return changeNode(context, changed) + } + } + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(a_arg:2){v w}b(b_arg:1){x y}}}" + + } + + + def "remove a subtree "() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitSelectionSet(SelectionSet node, TraverserContext context) { + if (context.getParentContext().thisNode().name == "root") { + def newNode = node.transform({ builder -> builder.selections([node.selections[0]]) }) + return changeNode(context, newNode) + } + return TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(arg:1){x y}}}" + + } + + def "remove a subtree parallel"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitSelectionSet(SelectionSet node, TraverserContext context) { + if (context.getParentContext().thisNode().name == "root") { + def newNode = node.transform({ builder -> builder.selections([node.selections[0]]) }) + return changeNode(context, newNode) + } + return TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(arg:1){x y}}}" + + } + + def "delete node"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + if (field.name == "toDelete") { + return deleteNode(context); + } else { + return TraversalControl.CONTINUE; + } + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(arg:1){x y}}}" + + } + + def "delete node through context"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + final Map, Object> rootVars = new LinkedHashMap<>(); + rootVars.put(String.class, "toDelete"); + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + final String fieldToDelete = context.getVarFromParents(String.class); + if (field.name == fieldToDelete) { + return deleteNode(context); + } else { + return TraversalControl.CONTINUE; + } + } + } + + when: + def newDocument = astTransformer.transform(document, visitor, rootVars) + + then: + printAstCompact(newDocument) == "{root{a(arg:1){x y}}}" + + } + + def "delete node parallel"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + if (field.name == "toDelete") { + Thread.sleep(250) + return deleteNode(context); + } else { + return TraversalControl.CONTINUE; + } + } + } + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(arg:1){x y}}}" + + } + + def "delete multiple nodes and change others"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x1 y1 } b { x2 y2 } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + if (field.name == "x1" || field.name == "x2") { + return deleteNode(context); + } else if (field.name == "a") { + return changeNode(context, field.transform({ builder -> builder.name("aChanged") })) + + } else if (field.name == "root") { + Field addField = new Field("new") + def newSelectionSet = field.getSelectionSet().transform({ builder -> builder.selection(addField) }) + changeNode(context, field.transform({ builder -> builder.selectionSet(newSelectionSet) })) + } else { + return TraversalControl.CONTINUE; + } + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + + printAstCompact(newDocument) == "{root{aChanged(arg:1){y1}b{y2}new}}" + printAstCompact(newDocumentParallel) == "{root{aChanged(arg:1){y1}b{y2}new}}" + + } + + def "add sibling after"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + return insertAfter(context, new Field("foo2")) + } + } + + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{foo foo2}" + printAstCompact(newDocumentParallel) == "{foo foo2}" + + } + + def "add sibling before"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + return insertBefore(context, new Field("foo2")) + } + } + + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2 foo}" + printAstCompact(newDocumentParallel) == "{foo2 foo}" + + } + + def "add sibling before and after"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + insertBefore(context, new Field("foo2")) + insertAfter(context, new Field("foo3")) + TraversalControl.CONTINUE + } + } + + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2 foo foo3}" + + } + + def "add sibling before and after parallel"() { + def document = TestUtil.parseQuery("{foo}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + insertBefore(context, new Field("foo2")) + insertAfter(context, new Field("foo3")) + TraversalControl.CONTINUE + } + } + + + when: + def newDocument = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2 foo foo3}" + + } + + def "delete node and add sibling"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + if (field.name == "toDelete") { + return deleteNode(context); + } else if (field.name == "a") { + return insertAfter(context, new Field("newOne")) + } else { + return TraversalControl.CONTINUE + } + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a(arg:1){x y}newOne}}" + printAstCompact(newDocumentParallel) == "{root{a(arg:1){x y}newOne}}" + + } + + def "delete node and change sibling"() { + def document = TestUtil.parseQuery("{root { a(arg: 1) { x y } toDelete { x y } } }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + if (field.name == "toDelete") { + return deleteNode(context); + } else if (field.name == "a") { + def newNode = field.transform({ builder -> builder.name("a-changed") }) + return changeNode(context, newNode) + } else { + return TraversalControl.CONTINUE + } + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{root{a-changed(arg:1){x y}}}" + printAstCompact(newDocumentParallel) == "{root{a-changed(arg:1){x y}}}" + + + } + + def "change root node"() { + def document = TestUtil.parseQuery("query A{ field } query B{ fieldB }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitDocument(Document node, TraverserContext context) { + def children = new ArrayList<>(node.getChildren()) + children.remove(0) + def newNode = node.transform({ builder -> builder.definitions(children) }) + changeNode(context, newNode) + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "query B{fieldB}" + printAstCompact(newDocumentParallel) == "query B{fieldB}" + + } + + def "change different kind of children"() { + def document = TestUtil.parseQuery("{ field(arg1:1, arg2:2) @directive1 @directive2}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitDirective(Directive node, TraverserContext context) { + if (node.name == "directive1") { + insertAfter(context, new Directive("after1Directive")) + } else { + deleteNode(context) + insertAfter(context, new Directive("newDirective2")) + } + TraversalControl.CONTINUE + } + + @Override + TraversalControl visitArgument(Argument node, TraverserContext context) { + if (node.name == "arg1") { + deleteNode(context) + insertAfter(context, new Argument("newArg1", new IntValue(BigInteger.TEN))) + } else { + insertAfter(context, new Argument("arg3", new IntValue(BigInteger.TEN))) + } + TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{field(newArg1:10,arg2:2,arg3:10) @directive1@after1Directive@newDirective2}" + printAstCompact(newDocumentParallel) == "{field(newArg1:10,arg2:2,arg3:10) @directive1@after1Directive@newDirective2}" + + } + + def "insertAfter and then insertBefore"() { + def document = TestUtil.parseQuery("{ field @directive1 @directive2}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitDirective(Directive node, TraverserContext context) { + if (node.name == "directive1") { + insertAfter(context, new Directive("after")) + insertBefore(context, new Directive("before")) + } + TraversalControl.CONTINUE + } + + @Override + TraversalControl visitArgument(Argument node, TraverserContext context) { + TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{field @before@directive1@after@directive2}" + printAstCompact(newDocumentParallel) == "{field @before@directive1@after@directive2}" + + } + + + def "mix of all modifications at once"() { + def document = TestUtil.parseQuery("{ field(arg1:1, arg2:2) @directive1 @directive2}") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitDirective(Directive node, TraverserContext context) { + + if (node.name == "directive1") { + insertAfter(context, new Directive("d4")) + insertBefore(context, new Directive("d5")) + } else { + insertBefore(context, new Directive("d1")) + insertBefore(context, new Directive("d2")) + deleteNode(context) + insertAfter(context, new Directive("d3")) + } + TraversalControl.CONTINUE + } + + @Override + TraversalControl visitArgument(Argument node, TraverserContext context) { + if (node.name == "arg1") { + insertAfter(context, new Argument("a1", new IntValue(BigInteger.TEN))) + } else { + deleteNode(context) + insertAfter(context, new Argument("a2", new IntValue(BigInteger.TEN))) + insertAfter(context, new Argument("a3", new IntValue(BigInteger.TEN))) + insertBefore(context, new Argument("a4", new IntValue(BigInteger.TEN))) + } + TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{field(arg1:1,a1:10,a4:10,a2:10,a3:10) @d5@directive1@d4@d1@d2@d3}" + printAstCompact(newDocumentParallel) == "{field(arg1:1,a1:10,a4:10,a2:10,a3:10) @d5@directive1@d4@d1@d2@d3}" + + } + + def "replace first , insert After twice, replace second"() { + def document = TestUtil.parseQuery("{ first second }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + if (field.name == "first") { + changeNode(context, new Field("first-changed")) + return TraversalControl.CONTINUE + } else { + insertAfter(context, new Field("after-second-1")) + insertAfter(context, new Field("after-second-2")) + changeNode(context, new Field("second-changed")) + return TraversalControl.CONTINUE + } + + } + + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{first-changed second-changed after-second-1 after-second-2}" + printAstCompact(newDocumentParallel) == "{first-changed second-changed after-second-1 after-second-2}" + + } + + def "replaced and inserted in random order"() { + def document = TestUtil.parseQuery("{ field }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field field, TraverserContext context) { + insertBefore(context, new Field("before-1")) + changeNode(context, new Field("changed")) + insertAfter(context, new Field("after-1")) + insertAfter(context, new Field("after-2")) + changeNode(context, new Field("changed")) + insertBefore(context, new Field("before-2")) + insertAfter(context, new Field("after-3")) + return TraversalControl.CONTINUE + + } + + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{before-1 before-2 changed after-1 after-2 after-3}" + + } + + def "changeNode can be called multiple times"() { + def document = TestUtil.parseQuery("{ field }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitField(Field node, TraverserContext context) { + changeNode(context, new Field("change1")) + changeNode(context, new Field("change2")) + changeNode(context, new Field("change3")) + TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + def newDocumentParallel = astTransformer.transformParallel(document, visitor) + + then: + printAstCompact(newDocument) == "{change3}" + printAstCompact(newDocumentParallel) == "{change3}" + + } + + + def "delete root node"() { + def document = TestUtil.parseQuery("{ field }") + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitDocument(Document node, TraverserContext context) { + deleteNode(context) + TraversalControl.CONTINUE + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + newDocument == null + + } + + def "regression: changing a property of an extension should not change the extension to a base definition"() { + def document = TestUtil.toDocument(""" + extend schema { query: Query } + extend type MyObjectType { login: String } + extend input MyInputObjectType { login: String } + extend interface MyInterface { login: String } + extend enum MyEnum { MONDAY } + extend scalar MyScalar @myDirective + extend union MyUnion = MyObjectType + """) + + AstTransformer astTransformer = new AstTransformer() + + def visitor = new NodeVisitorStub() { + + @Override + TraversalControl visitFieldDefinition(FieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "login") { + // change name + FieldDefinition signin = fieldDefinition.transform({ builder -> builder.name("signin") }) + return changeNode(context, signin) + } + return super.visitFieldDefinition(fieldDefinition, context) + } + + @Override + TraversalControl visitInputValueDefinition(InputValueDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "login") { + // change name + InputValueDefinition signin = fieldDefinition.transform({ builder -> builder.name("signin") }) + return changeNode(context, signin) + } + return super.visitInputValueDefinition(fieldDefinition, context) + } + + @Override + TraversalControl visitEnumValueDefinition(EnumValueDefinition node, TraverserContext context) { + if (node.name == "MONDAY") { + // change name + return changeNode(context, node.transform({ builder -> builder.name("TUESDAY") })) + } + return super.visitEnumValueDefinition(node, context) + } + + @Override + TraversalControl visitSchemaDefinition(SchemaDefinition node, TraverserContext context) { + if (node instanceof SchemaExtensionDefinition) { + return changeNode(context, node.transformExtension({ + it.operationTypeDefinitions([OperationTypeDefinition.newOperationTypeDefinition() + .name("myQuery") + .typeName(TypeName.newTypeName("MyQuery").build()) + .build()]) + })) + } + return super.visitSchemaDefinition(node, context) + } + } + + when: + def newDocument = astTransformer.transform(document, visitor) + + then: + newDocument instanceof Document + + and: + def transformedDoc = newDocument as Document + transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyObjectType"} instanceof ObjectTypeExtensionDefinition + transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyInputObjectType"} instanceof InputObjectTypeExtensionDefinition + transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyInterface"} instanceof InterfaceTypeExtensionDefinition + transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyEnum"} instanceof EnumTypeExtensionDefinition + transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyScalar"} instanceof ScalarTypeExtensionDefinition + transformedDoc.definitions.find {it instanceof NamedNode && it.name == "MyUnion"} instanceof UnionTypeExtensionDefinition + transformedDoc.definitions.find {it instanceof SchemaDefinition } instanceof SchemaExtensionDefinition + + and: + printAst(newDocument).trim() == """ + |extend schema { + | myQuery: MyQuery + |} + | + |extend type MyObjectType { + | signin: String + |} + | + |extend input MyInputObjectType { + | signin: String + |} + | + |extend interface MyInterface { + | signin: String + |} + | + |extend enum MyEnum { + | TUESDAY + |} + | + |extend scalar MyScalar @myDirective + | + |extend union MyUnion = MyObjectType + """.trim().stripMargin() + } +} diff --git a/src/test/groovy/graphql/language/AstValueHelperTest.groovy b/src/test/groovy/graphql/language/AstValueHelperTest.groovy deleted file mode 100644 index e6e46b9226..0000000000 --- a/src/test/groovy/graphql/language/AstValueHelperTest.groovy +++ /dev/null @@ -1,181 +0,0 @@ -package graphql.language - -import graphql.schema.GraphQLEnumType -import graphql.schema.GraphQLInputObjectType -import spock.lang.Specification - -import static AstValueHelper.astFromValue -import static graphql.Scalars.GraphQLBoolean -import static graphql.Scalars.GraphQLFloat -import static graphql.Scalars.GraphQLID -import static graphql.Scalars.GraphQLInt -import static graphql.Scalars.GraphQLString -import static graphql.language.BooleanValue.newBooleanValue -import static graphql.schema.GraphQLList.list -import static graphql.schema.GraphQLNonNull.nonNull - -class AstValueHelperTest extends Specification { - - def 'converts boolean values to ASTs'() { - expect: - astFromValue(true, GraphQLBoolean).isEqualTo(newBooleanValue(true).build()) - - astFromValue(false, GraphQLBoolean).isEqualTo(newBooleanValue(false).build()) - - astFromValue(null, GraphQLBoolean) == null - - astFromValue(0, GraphQLBoolean).isEqualTo(newBooleanValue(false).build()) - - astFromValue(1, GraphQLBoolean).isEqualTo(newBooleanValue(true).build()) - - def NonNullBoolean = nonNull(GraphQLBoolean) - astFromValue(0, NonNullBoolean).isEqualTo(newBooleanValue(false).build()) - } - - BigInteger bigInt(int i) { - return new BigInteger(String.valueOf(i)) - } - - def 'converts Int values to Int ASTs'() { - expect: - astFromValue(123.0, GraphQLInt).isEqualTo(IntValue.newIntValue(bigInt(123)).build()) - - astFromValue(1e4, GraphQLInt).isEqualTo(IntValue.newIntValue(bigInt(10000)).build()) - } - - def 'converts Float values to Int/Float ASTs'() { - expect: - astFromValue(123.0, GraphQLFloat).isEqualTo(FloatValue.newFloatValue(123.0).build()) - - astFromValue(123.5, GraphQLFloat).isEqualTo(FloatValue.newFloatValue(123.5).build()) - - astFromValue(1e4, GraphQLFloat).isEqualTo(FloatValue.newFloatValue(10000.0).build()) - - astFromValue(1e40, GraphQLFloat).isEqualTo(FloatValue.newFloatValue(1.0e40).build()) - } - - - def 'converts String values to String ASTs'() { - expect: - astFromValue('hello', GraphQLString).isEqualTo(new StringValue('hello')) - - astFromValue('VALUE', GraphQLString).isEqualTo(new StringValue('VALUE')) - - astFromValue('VA\n\t\f\r\b\\LUE', GraphQLString).isEqualTo(new StringValue('VA\\n\\t\\f\\r\\b\\\\LUE')) - - astFromValue('VA/LUE', GraphQLString).isEqualTo(new StringValue('VA/LUE')) - - astFromValue('VA\\L\"UE', GraphQLString).isEqualTo(new StringValue('VA\\\\L\\"UE')) - - astFromValue(123, GraphQLString).isEqualTo(new StringValue('123')) - - astFromValue(false, GraphQLString).isEqualTo(new StringValue('false')) - - astFromValue(null, GraphQLString) == null - } - - def 'converts ID values to Int/String ASTs'() { - expect: - astFromValue('hello', GraphQLID).isEqualTo(new StringValue('hello')) - - astFromValue('VALUE', GraphQLID).isEqualTo(new StringValue('VALUE')) - - // Note: EnumValues cannot contain non-identifier characters - astFromValue('VA\nLUE', GraphQLID).isEqualTo(new StringValue('VA\\nLUE')) - - // Note: IntValues are used when possible. - astFromValue(123, GraphQLID).isEqualTo(new IntValue(bigInt(123))) - - astFromValue(null, GraphQLID) == null - } - - - def 'does not converts NonNull values to NullValue'() { - expect: - def NonNullBoolean = nonNull(GraphQLBoolean) - astFromValue(null, NonNullBoolean) == null - } - - def complexValue = { someArbitrary: 'complexValue' } - - - def myEnum = GraphQLEnumType.newEnum().name('MyEnum') - .value('HELLO') - .value('GOODBYE') - .value('COMPLEX', complexValue) - .build() - - def 'converts string values to Enum ASTs if possible'() { - expect: - astFromValue('HELLO', myEnum).isEqualTo(new EnumValue('HELLO')) - - astFromValue(complexValue, myEnum).isEqualTo(new EnumValue('COMPLEX')) - -// // Note: case sensitive -// astFromValue('hello', myEnum) == null -// -// // Note: Not a valid enum value -// astFromValue('VALUE', myEnum) == null - } - - def 'converts array values to List ASTs'() { - expect: - astFromValue(['FOO', 'BAR'], list(GraphQLString)).isEqualTo( - new ArrayValue([new StringValue('FOO'), new StringValue('BAR')]) - ) - - - astFromValue(['HELLO', 'GOODBYE'], list(myEnum)).isEqualTo( - new ArrayValue([new EnumValue('HELLO'), new EnumValue('GOODBYE')]) - ) - } - - def 'converts list singletons'() { - expect: - astFromValue('FOO', list(GraphQLString)).isEqualTo( - new StringValue('FOO') - ) - } - - def 'converts input objects'() { - expect: - def inputObj = GraphQLInputObjectType.newInputObject() - .name('MyInputObj') - .field({ f -> f.name("foo").type(GraphQLFloat) }) - .field({ f -> f.name("bar").type(myEnum) }) - .build() - - astFromValue([foo: 3, bar: 'HELLO'], inputObj).isEqualTo( - new ObjectValue([new ObjectField("foo", new IntValue(bigInt(3))), - new ObjectField("bar", new EnumValue('HELLO')), - ]) - ) - } - - def 'converts input objects with explicit nulls'() { - expect: - def inputObj = GraphQLInputObjectType.newInputObject() - .name('MyInputObj') - .field({ f -> f.name("foo").type(GraphQLFloat) }) - .field({ f -> f.name("bar").type(myEnum) }) - .build() - - astFromValue([foo: null], inputObj).isEqualTo( - new ObjectValue([new ObjectField("foo", null)]) - ) - } - - def 'parse ast literals'() { - expect: - AstValueHelper.valueFromAst(valueLiteral) in expectedValue - - where: - valueLiteral | expectedValue - '"s"' | StringValue.class - 'true' | BooleanValue.class - '666' | IntValue.class - '666.6' | FloatValue.class - '["A", "B", "C"]' | ArrayValue.class - '{string : "s", integer : 1, boolean : true}' | ObjectValue.class - } -} diff --git a/src/test/groovy/graphql/language/AstZipperTest.groovy b/src/test/groovy/graphql/language/AstZipperTest.groovy new file mode 100644 index 0000000000..b7c81294de --- /dev/null +++ b/src/test/groovy/graphql/language/AstZipperTest.groovy @@ -0,0 +1,202 @@ +package graphql.language + +import graphql.util.Breadcrumb +import graphql.util.NodeLocation +import graphql.util.NodeZipper +import graphql.util.TraversalControl +import graphql.util.TraverserContext +import spock.lang.Specification + +import static graphql.language.AstNodeAdapter.AST_NODE_ADAPTER +import static java.util.Arrays.asList +import static java.util.Collections.emptyList + +class AstZipperTest extends Specification { + + /* + * Modify a node that is part of tree, resulting in a new tree being created with updated references. New nodes + * are created when necessary, instead of having their attributes modified. This test exemplifies the immutable + * characteristics of nodes. + * + * The node "child 1.2" will be renamed to "child 1.2x", this results in a new node being created with identical + * characteristics to the old node, except the name, and replacing the old node in the tree. + * + * This modification requires that the parent nodes are also updated so they have a reference to the newly created + * node. As a result, new instances are also created for "child 1" and "root". The rest of the tree remains + * untouched (including the children of "child 1.2"). + * + * + * Original Tree: + * + * + * root + * + + * | + * | + * +--------------+---------------+ + * | | + * v v + * child 1 child 2 + * + + + * | | + * | | + * +------+------+ +------+------+ + * | | | | + * v v v v + * child 1.1 child 1.2 child 2.1 child 2.2 + * + + * | + * v + * child 1.2.1 + * + * + * + * + * Modified Tree: + * + * + * root' + * + + * | + * | + * +--------------+---------------+ + * | | + * v v + * child 1' child 2 + * + + + * | | + * | | + * +------+------+ +------+------+ + * | | | | + * v v v v + * child 1.1 child 1.2x' child 2.1 child 2.2 + * + + * | + * v + * child 1.2.1 + * + * - A new node, named "child 1.2x" is created to replace the node named "child 1.2" + * - A new "child 1" is created and it references the newly created "child 1.2x" node + * - A new "root" is created and it references the newly created "child 1" node + * - The rest of the tree is not modified (same object references) + * + */ + + + def 'modify a child node'() { + def root = node("root", + node("child 1", + node("child 1.1"), + node("child 1.2", + node("child 1.2.1") + ) + ), + node("child 2", + node("child 2.1"), + node("child 2.2") + ) + ) + + Node child1 = root.selectChild(0) + Node child1_2 = child1.selectChild(1) + + List breadcrumbs = asList( + new Breadcrumb<>(child1, new NodeLocation("children", 1)), + new Breadcrumb<>(root, new NodeLocation("children", 0)) + ) + + NodeZipper zipper = new NodeZipper(child1_2, breadcrumbs, AST_NODE_ADAPTER) + + final MyNode rootModified = (MyNode) zipper.modifyNode( + { node -> + new MyNode("child 1.2x", node.getChildren()) + } + ).toRoot() + + expect: + + rootModified.selectChild(0, 1).getValue() == "child 1.2x" + + rootModified != root + + rootModified.selectChild(0) != root.selectChild(0) + rootModified.selectChild(0, 0) == root.selectChild(0, 0) + rootModified.selectChild(0, 1) != root.selectChild(0, 1) + rootModified.selectChild(0, 1, 0) == root.selectChild(0, 1, 0) + + rootModified.selectChild(1) == root.selectChild(1) + rootModified.selectChild(1, 0) == root.selectChild(1, 0) + rootModified.selectChild(1, 1) == root.selectChild(1, 1) + } + + static node(String value, Node... children) { + new MyNode(value, asList(children)) + } + + static class MyNode extends AbstractNode { + private final String value + private final List children + + private static final String CHILDREN = "children" + + MyNode(String value, List children) { + super(null, emptyList(), IgnoredChars.EMPTY, Collections.emptyMap()) + this.value = value + this.children = children + } + + String getValue() { + return value + } + + @Override + List getChildren() { + return children + } + + @Override + boolean isEqualTo(Node node) { + if (node instanceof MyNode) { + return ((MyNode) node).value.equals(this.value) + } + + return false + } + + @Override + MyNode deepCopy() { + return null + } + + @Override + TraversalControl accept(TraverserContext context, NodeVisitor visitor) { + return null + } + + @Override + NodeChildrenContainer getNamedChildren() { + return NodeChildrenContainer.newNodeChildrenContainer().children(CHILDREN, children).build() + } + + @Override + Node withNewChildren(NodeChildrenContainer newChildren) { + return new MyNode(this.getValue(), newChildren.getChildren(CHILDREN)) + } + + @Override + String toString() { + return value + } + + MyNode selectChild(Integer... indexes) { + def node = this + + for (int i = 0; i < indexes.length; i++) { + node = node.children.get(indexes[i]) + } + + (MyNode) node + } + } +} + diff --git a/src/test/groovy/graphql/language/DirectiveTest.groovy b/src/test/groovy/graphql/language/DirectiveTest.groovy index 8821c500cd..0b3d2e0506 100644 --- a/src/test/groovy/graphql/language/DirectiveTest.groovy +++ b/src/test/groovy/graphql/language/DirectiveTest.groovy @@ -36,17 +36,14 @@ class DirectiveTest extends Specification { new Directive("repeated", [new Argument("a1", new StringValue("v1"))]), new Directive("repeated", [new Argument("a1", new StringValue("v2"))]), ] - def directivesMap = NodeUtil.directivesByName(directives) - expect: - - // - // other parts of the system ensure that repeated directives are invalid, but if we manually create them - // we always return the first + when: + def directivesMap = NodeUtil.allDirectivesByName(directives) + then: directivesMap.size() == 3 - directivesMap.get("d1") == d1 + directivesMap.get("d1") == [d1] directivesMap.get("null") == null - directivesMap.get("repeated").getArgument("a1").getValue().isEqualTo(new StringValue("v1")) + directivesMap.get("repeated").collect({ d -> d.getName() }) == ["repeated", "repeated"] } } diff --git a/src/test/groovy/graphql/language/DocumentTest.groovy b/src/test/groovy/graphql/language/DocumentTest.groovy index 2c74b9c9d8..2aea51969f 100644 --- a/src/test/groovy/graphql/language/DocumentTest.groovy +++ b/src/test/groovy/graphql/language/DocumentTest.groovy @@ -43,4 +43,50 @@ class DocumentTest extends Specification { expected == actual } + + def "can give back one definition"() { + def doc = TestUtil.parseQuery(''' + query foo { + field + } + + query bar { + field + } + + type Query { + a : String + } + + ''') + + when: + def definition = doc.getFirstDefinitionOfType(OperationDefinition.class) + then: + definition.isPresent() + + when: + def operationDefinition = definition.get() + then: + operationDefinition instanceof OperationDefinition + operationDefinition.getName() == "foo" + + + when: + definition = doc.getOperationDefinition("bar") + then: + definition.isPresent() + + when: + operationDefinition = definition.get() + then: + operationDefinition instanceof OperationDefinition + operationDefinition.getName() == "bar" + + when: + definition = doc.getOperationDefinition("baz") + then: + !definition.isPresent() + + } } diff --git a/src/test/groovy/graphql/language/NodeTraverserTest.groovy b/src/test/groovy/graphql/language/NodeTraverserTest.groovy index decae45e89..9929f43ab5 100644 --- a/src/test/groovy/graphql/language/NodeTraverserTest.groovy +++ b/src/test/groovy/graphql/language/NodeTraverserTest.groovy @@ -4,8 +4,9 @@ import graphql.util.TraversalControl import graphql.util.TraverserContext import spock.lang.Specification -import static graphql.language.NodeTraverser.LeaveOrEnter.ENTER -import static graphql.language.NodeTraverser.LeaveOrEnter.LEAVE +import static graphql.util.TraverserContext.Phase.ENTER +import static graphql.util.TraverserContext.Phase.LEAVE + class NodeTraverserTest extends Specification { @@ -36,6 +37,27 @@ class NodeTraverserTest extends Specification { 0 * nodeVisitor._ } + def "traverse nodes returns accumulate"() { + given: + Field leaf = new Field("leaf") + SelectionSet rootSelectionSet = SelectionSet.newSelectionSet().selections(Arrays.asList(leaf)).build() + Field root = Field.newField().name("root").selectionSet(rootSelectionSet).build() + + NodeTraverser nodeTraverser = new NodeTraverser() + NodeVisitor nodeVisitor = new NodeVisitorStub() { + @Override + TraversalControl visitField(Field node, TraverserContext context) { + context.setAccumulate("RESULT") + return TraversalControl.CONTINUE + } + } + when: + def result = nodeTraverser.depthFirst(nodeVisitor, root) + + then: + result == "RESULT" + } + def "traverse nodes in pre-order"() { given: Field leaf = Field.newField().name("leaf").build() @@ -115,7 +137,7 @@ class NodeTraverserTest extends Specification { def visitor = new NodeVisitorStub() { @Override TraversalControl visitField(Field node, TraverserContext context) { - context.setResult(node) + context.setAccumulate(node) } } def field = Field.newField().build() @@ -127,10 +149,10 @@ class NodeTraverserTest extends Specification { boolean isEnter(TraverserContext context) { - return context.getVar(NodeTraverser.LeaveOrEnter.class) == ENTER + return context.phase == ENTER } boolean isLeave(TraverserContext context) { - return context.getVar(NodeTraverser.LeaveOrEnter.class) == LEAVE + return context.phase == LEAVE } } diff --git a/src/test/groovy/graphql/language/NodeUtilTest.groovy b/src/test/groovy/graphql/language/NodeUtilTest.groovy index d4ef91a8d1..b5265f276a 100644 --- a/src/test/groovy/graphql/language/NodeUtilTest.groovy +++ b/src/test/groovy/graphql/language/NodeUtilTest.groovy @@ -1,5 +1,6 @@ package graphql.language + import graphql.TestUtil import graphql.execution.UnknownOperationException import spock.lang.Specification @@ -35,4 +36,17 @@ class NodeUtilTest extends Specification { def ex = thrown(UnknownOperationException) ex.message == "Unknown operation named 'Unknown'." } + + def d1 = Directive.newDirective().name("d1").build() + def d2 = Directive.newDirective().name("d2").build() + def d3r = Directive.newDirective().name("d3").build() + + def "can create a map of all directives"() { + when: + def result = NodeUtil.allDirectivesByName([d1, d2, d3r, d3r]) + then: + result == [d1: [d1], d2: [d2], d3: [d3r, d3r],] + } + + } diff --git a/src/test/groovy/graphql/language/NodeVisitorStubTest.groovy b/src/test/groovy/graphql/language/NodeVisitorStubTest.groovy index a43d270ca8..8ca86ca936 100644 --- a/src/test/groovy/graphql/language/NodeVisitorStubTest.groovy +++ b/src/test/groovy/graphql/language/NodeVisitorStubTest.groovy @@ -48,7 +48,7 @@ class NodeVisitorStubTest extends Specification { ArrayValue.newArrayValue().build() | 'visitArrayValue' IntValue.newIntValue().build() | 'visitIntValue' new BooleanValue(true) | 'visitBooleanValue' - NullValue.Null | 'visitNullValue' + NullValue.newNullValue().build() | 'visitNullValue' ObjectValue.newObjectValue().build() | 'visitObjectValue' VariableReference.newVariableReference().build() | 'visitVariableReference' EnumValue.newEnumValue().build() | 'visitEnumValue' @@ -140,7 +140,7 @@ class NodeVisitorStubTest extends Specification { FieldDefinition.newFieldDefinition().build() | 'visitFieldDefinition' InputValueDefinition.newInputValueDefinition().build() | 'visitInputValueDefinition' InputValueDefinition.newInputValueDefinition().build() | 'visitInputValueDefinition' - new ObjectField("", null) | 'visitObjectField' + new ObjectField("a", IntValue.of(1)) | 'visitObjectField' OperationTypeDefinition.newOperationTypeDefinition().build() | 'visitOperationTypeDefinition' OperationTypeDefinition.newOperationTypeDefinition().build() | 'visitOperationTypeDefinition' SelectionSet.newSelectionSet().build() | 'visitSelectionSet' diff --git a/src/test/groovy/graphql/language/PrettyAstPrinterTest.groovy b/src/test/groovy/graphql/language/PrettyAstPrinterTest.groovy new file mode 100644 index 0000000000..0fab95cbf6 --- /dev/null +++ b/src/test/groovy/graphql/language/PrettyAstPrinterTest.groovy @@ -0,0 +1,521 @@ +package graphql.language + +import spock.lang.Specification + +class PrettyAstPrinterTest extends Specification { + + def "can print type with comments"() { + given: + def input = ''' +# before description +""" Description """ +# before def #1 +# before def #2 +type Query { # beginning of block +a: A b: B + # end of block inside #1 +# end of block inside #2 +} # end of block +''' + + def expected = '''# before description +""" + Description +""" +# before def #1 +# before def #2 +type Query { # beginning of block + a: A + b: B + # end of block inside #1 + # end of block inside #2 +} # end of block +''' + when: + def result = print(input) + + then: + result == expected + } + + + def "can print type with no comments"() { + given: + def input = ''' +""" Description """ +type Query { +a: A b: B} +''' + + def expected = '''""" + Description +""" +type Query { + a: A + b: B +} +''' + when: + def result = print(input) + then: + result == expected + } + + + def "can print interface with comments"() { + given: + def input = ''' +# before description +""" Description """ +# before def #1 +# before def #2 +interface MyInterface { # beginning of block +a: A b: B} # end of block +''' + + def expected = '''# before description +""" + Description +""" +# before def #1 +# before def #2 +interface MyInterface { # beginning of block + a: A + b: B +} # end of block +''' + when: + def result = print(input) + + then: + result == expected + } + + + def "can print interface with no comments"() { + given: + def input = ''' +""" Description """ +interface MyInterface { +a: A b: B} +''' + + def expected = '''""" + Description +""" +interface MyInterface { + a: A + b: B +} +''' + when: + def result = print(input) + then: + result == expected + } + + + def "can print fields with comments"() { + given: + def input = ''' +# before type +type MyType { # beginning of block + +# before field A #1 + +# before field A #2 +""" Description fieldA """ +# before field A #3 + a(arg1: String, arg2: String, arg3: String): A # after field A + # before field B #1 +b(arg1: String, arg2: String, arg3: String): B # after field B +} # end of block +''' + + def expected = '''# before type +type MyType { # beginning of block + # before field A #1 + # before field A #2 + """ + Description fieldA + """ + # before field A #3 + a(arg1: String, arg2: String, arg3: String): A # after field A + # before field B #1 + b(arg1: String, arg2: String, arg3: String): B # after field B +} # end of block +''' + when: + def result = print(input) + + then: + result == expected + } + + + def "can print field arguments with comments"() { + given: + def input = '''type MyType { +""" Description fieldA """ + a(arg1: String # arg1 #1 + # arg2 #1 + """ Description arg2 """ + # arg2 #2 + arg2: String, arg3: String # arg3 #1 + # after all args + ): A # after field A +} +''' + + def expected = '''type MyType { + """ + Description fieldA + """ + a( + arg1: String # arg1 #1 + # arg2 #1 + """ + Description arg2 + """ + # arg2 #2 + arg2: String + arg3: String # arg3 #1 + # after all args + ): A # after field A +} +''' + when: + def result = print(input) + + then: + result == expected + } + + + def "can print schema keeping document level comments"() { + given: + def input = ''' # start of document + +# before Query def + +type Query {a: A b: B} +type MyType {field(id: ID!): MyType! listField: [MyType!]!} +enum MyEnum {VALUE_1 VALUE_2} +# end of document #1 +# end of document #2 +''' + + def expected = """# start of document +# before Query def +type Query { + a: A + b: B +} + +type MyType { + field(id: ID!): MyType! + listField: [MyType!]! +} + +enum MyEnum { + VALUE_1 + VALUE_2 +} +# end of document #1 +# end of document #2 +""" + + when: + def result = print(input) + then: + + result == expected + } + + + def "can print comments between implements"() { + given: + def input = ''' +type MyType implements A & +# interface B #1 + # interface B #2 + B + & + # interface C + C {a: A} +''' + + def expected = '''type MyType implements + A & + # interface B #1 + # interface B #2 + B & + # interface C + C + { + a: A +} +''' + + when: + def result = print(input) + then: + + result == expected + } + + + def "can print type implementing interfaces with no comments"() { + given: + def input = ''' +type MyType implements A & + B & + C + & D + & E { # trailing comment + a: A} +''' + + def expected = '''type MyType implements A & B & C & D & E { # trailing comment + a: A +} +''' + + when: + def result = print(input) + then: + + result == expected + } + + + def "can print enums without comments"() { + given: + def input = ''' +enum MyEnum { + VALUE_1 +VALUE_2 VALUE_3 +} +''' + + def expected = '''enum MyEnum { + VALUE_1 + VALUE_2 + VALUE_3 +} +''' + + when: + def result = print(input) + then: + + result == expected + } + + + def "can print comments in enums"() { + given: + def input = ''' +# before def +enum MyEnum { # inside block #1 +# before VALUE_1 #1 + """ VALUE_1 description """ + # before VALUE_1 #2 + VALUE_1 # after VALUE_1 +VALUE_2 + #inside block #2 +} +''' + + def expected = '''# before def +enum MyEnum { # inside block #1 + # before VALUE_1 #1 + """ + VALUE_1 description + """ + # before VALUE_1 #2 + VALUE_1 # after VALUE_1 + VALUE_2 + #inside block #2 +} +''' + + when: + def result = print(input) + then: + + result == expected + } + + + def "can print comments in scalars"() { + given: + def input = ''' +# before def #1 +""" Description """ + # before def #2 +scalar +MyScalar # def trailing +# after def +''' + + def expected = '''# before def #1 +""" + Description +""" +# before def #2 +scalar MyScalar # def trailing +# after def +''' + + when: + def result = print(input) + then: + + result == expected + } + + + def "can print comments in directives"() { + given: + def input = ''' +# before def #1 +""" Description def """ + # before def #2 +directive +@myDirective( # inside block #1 + # arg1 #1 + """ Description arg1 """ + + # arg1 #2 + arg1: String! # arg1 trailing + # arg2 #1 + arg2: ID arg3: String! # arg3 trailing + # inside block #1 + ) on FIELD_DEFINITION # trailing def +# after def +''' + + def expected = '''# before def #1 +""" + Description def +""" +# before def #2 +directive @myDirective( # inside block #1 + # arg1 #1 + """ + Description arg1 + """ + # arg1 #2 + arg1: String! # arg1 trailing + # arg2 #1 + arg2: ID + arg3: String! # arg3 trailing + # inside block #1 +) on FIELD_DEFINITION # trailing def +# after def +''' + + when: + def result = print(input) + then: + + result == expected + } + + def "can print extended type with comments"() { + given: + def input = ''' +# before description +extend type Query { # beginning of block +a: A b: B + # end of block inside #1 +# end of block inside #2 +} # end of block +''' + + def expected = '''# before description +extend type Query { # beginning of block + a: A + b: B + # end of block inside #1 + # end of block inside #2 +} # end of block +''' + when: + def result = print(input) + + then: + result == expected + } + + + def "can print input type with comments"() { + given: + def input = ''' +# before description +""" Description """ +# before def #1 +# before def #2 +input MyInput { # beginning of block +a: A b: B + # end of block inside #1 +# end of block inside #2 +} # end of block +''' + + def expected = '''# before description +""" + Description +""" +# before def #1 +# before def #2 +input MyInput { # beginning of block + a: A + b: B + # end of block inside #1 + # end of block inside #2 +} # end of block +''' + when: + def result = print(input) + + then: + result == expected + } + + def "can use print with tab indent"() { + given: + def input = ''' +type Query { +field( +# comment +a: A, b: B): Type +} +''' + + def expected = '''type Query { +\tfield( +\t\t# comment +\t\ta: A +\t\tb: B +\t): Type +} +''' + when: + def options = PrettyAstPrinter.PrettyPrinterOptions + .builder() + .indentType(PrettyAstPrinter.PrettyPrinterOptions.IndentType.TAB) + .indentWith(1) + .build() + + def result = PrettyAstPrinter.print(input, options) + + then: + result == expected + } + + private static String print(String input) { + return PrettyAstPrinter.print(input, PrettyAstPrinter.PrettyPrinterOptions.defaultOptions()) + } +} diff --git a/src/test/groovy/graphql/language/SerialisationTest.groovy b/src/test/groovy/graphql/language/SerialisationTest.groovy index 4174834dc2..8bd4ae46af 100644 --- a/src/test/groovy/graphql/language/SerialisationTest.groovy +++ b/src/test/groovy/graphql/language/SerialisationTest.groovy @@ -112,7 +112,11 @@ class SerialisationTest extends Specification { when: GraphQLError syntaxError1 = new InvalidSyntaxError(srcLoc(1, 1), "Bad Syntax 1") - GraphQLError validationError2 = new ValidationError(ValidationErrorType.FieldUndefined, srcLoc(2, 2), "Bad Query 2") + GraphQLError validationError2 = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.FieldUndefined) + .sourceLocation(srcLoc(2, 2)) + .description("Bad Query 2") + .build() def originalEntry = new PreparsedDocumentEntry([syntaxError1, validationError2]) PreparsedDocumentEntry newEntry = serialisedDownAndBack(originalEntry) @@ -122,7 +126,47 @@ class SerialisationTest extends Specification { newEntry.getErrors().size() == 2 newEntry.getErrors().get(0).getMessage() == syntaxError1.getMessage() newEntry.getErrors().get(0).getLocations() == syntaxError1.getLocations() + newEntry.getErrors().get(1).getMessage() == validationError2.getMessage() + newEntry.getErrors().get(1).getLocations() == validationError2.getLocations() + } + + def "PreparsedDocumentEntry with error is serializable"() { + + when: + GraphQLError syntaxError1 = new InvalidSyntaxError(srcLoc(1, 1), "Bad Syntax 1") + def originalEntry = new PreparsedDocumentEntry(syntaxError1) + + PreparsedDocumentEntry newEntry = serialisedDownAndBack(originalEntry) + + then: + + newEntry.getErrors().size() == 1 + newEntry.getErrors().get(0).getMessage() == syntaxError1.getMessage() + newEntry.getErrors().get(0).getLocations() == syntaxError1.getLocations() + } + def "PreparsedDocumentEntry with errors and document is serializable"() { + when: + + Document originalDoc = TestUtil.parseQuery(query) + GraphQLError syntaxError1 = new InvalidSyntaxError(srcLoc(1, 1), "Bad Syntax 1") + GraphQLError validationError2 = ValidationError.newValidationError() + .validationErrorType(ValidationErrorType.FieldUndefined) + .sourceLocation(srcLoc(2, 2)) + .description("Bad Query 2") + .build() + def originalEntry = new PreparsedDocumentEntry(originalDoc, [syntaxError1, validationError2]) + def originalAst = AstPrinter.printAst(originalEntry.getDocument()) + PreparsedDocumentEntry newEntry = serialisedDownAndBack(originalEntry) + + def newAst = AstPrinter.printAst(newEntry.getDocument()) + + then: + + originalAst == newAst + newEntry.getErrors().size() == 2 + newEntry.getErrors().get(0).getMessage() == syntaxError1.getMessage() + newEntry.getErrors().get(0).getLocations() == syntaxError1.getLocations() newEntry.getErrors().get(1).getMessage() == validationError2.getMessage() newEntry.getErrors().get(1).getLocations() == validationError2.getLocations() } diff --git a/src/test/groovy/graphql/language/SourceLocationTest.groovy b/src/test/groovy/graphql/language/SourceLocationTest.groovy new file mode 100644 index 0000000000..f5e71e6f72 --- /dev/null +++ b/src/test/groovy/graphql/language/SourceLocationTest.groovy @@ -0,0 +1,71 @@ +package graphql.language + +import graphql.parser.MultiSourceReader +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import spock.lang.Specification + +import static graphql.schema.FieldCoordinates.coordinates + +class SourceLocationTest extends Specification { + + def "can get source location"() { + def sdl = """ + type Query { + a : A! + } + + type A { + b : B + } + + type B { + c : String + } + """ + + def sourceReader = MultiSourceReader.newMultiSourceReader().string(sdl, "sourceName").build() + + def definitionRegistry = new SchemaParser().parse(sourceReader) + when: + def schema = new SchemaGenerator().makeExecutableSchema(definitionRegistry, RuntimeWiring.MOCKED_WIRING) + def schemaElement = schema.getType("Query") + def location = SourceLocation.getLocation(schemaElement) + + then: + location.sourceName == "sourceName" + location.line == 2 + location.column == 13 + + when: + schemaElement = schema.getFieldDefinition(coordinates("Query", "a")) + location = SourceLocation.getLocation(schemaElement) + + then: + location.sourceName == "sourceName" + location.line == 3 + location.column == 17 + + when: + schemaElement = schema.getFieldDefinition(coordinates("Query", "a")).getType() + // unwrapped + location = SourceLocation.getLocation(schemaElement) + + then: + location.sourceName == "sourceName" + location.line == 6 + location.column == 13 + + when: + schemaElement = schema.getType("A") + location = SourceLocation.getLocation(schemaElement) + + then: + location.sourceName == "sourceName" + location.line == 6 + location.column == 13 + + + } +} diff --git a/src/test/groovy/graphql/normalized/ExecutableNormalizedFieldTest.groovy b/src/test/groovy/graphql/normalized/ExecutableNormalizedFieldTest.groovy new file mode 100644 index 0000000000..6debbb2ff2 --- /dev/null +++ b/src/test/groovy/graphql/normalized/ExecutableNormalizedFieldTest.groovy @@ -0,0 +1,62 @@ +package graphql.normalized + +import graphql.TestUtil +import graphql.execution.CoercedVariables +import graphql.language.Document +import graphql.schema.GraphQLSchema +import spock.lang.Specification + +class ExecutableNormalizedFieldTest extends Specification { + + def "can get children of object type"() { + + String schema = """ + type Query{ + pets: [Pet] + } + interface Pet { + id: ID + name : String! + } + type Cat implements Pet{ + id: ID + name : String! + meow : String + } + type Dog implements Pet{ + id: ID + name : String! + woof : String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pets { + id + name + ... on Dog { + woof + } + ... on Cat { + meow + } + } + } + + """ + Document document = TestUtil.parseQuery(query) + + def normalizedOperation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + + def pets = normalizedOperation.getTopLevelFields()[0] + def allChildren = pets.getChildren() + def dogFields = pets.getChildren("Dog") + + expect: + allChildren.collect { it.name } == ["id", "name", "woof", "meow"] + dogFields.collect { it.name } == ["id", "name", "woof"] + } + +} diff --git a/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationFactoryDeferTest.groovy b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationFactoryDeferTest.groovy new file mode 100644 index 0000000000..f861fcf222 --- /dev/null +++ b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationFactoryDeferTest.groovy @@ -0,0 +1,908 @@ +package graphql.normalized + +import graphql.AssertException +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.RawVariables +import graphql.language.Document +import graphql.schema.GraphQLSchema +import graphql.util.TraversalControl +import graphql.util.Traverser +import graphql.util.TraverserContext +import graphql.util.TraverserVisitorStub +import spock.lang.Specification + +class ExecutableNormalizedOperationFactoryDeferTest extends Specification { + String schema = """ + directive @defer(if: Boolean, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT + + type Query { + dog: Dog + animal: Animal + mammal: Mammal + } + + interface LivingThing { + age: Int + } + + interface Animal implements LivingThing { + name: String + age: Int + } + + type Dog implements Animal & LivingThing { + name: String + age: Int + breed: String + owner: Person + } + + type Cat implements Animal & LivingThing { + name: String + age: Int + breed: String + color: String + siblings: [Cat] + } + + type Fish implements Animal & LivingThing { + name: String + age: Int + } + + type Person { + firstname: String + lastname: String + bestFriend: Person + } + + union Mammal = Dog | Cat + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + def "defer on a single field via inline fragment without type"() { + given: + + String query = ''' + query q { + dog { + name + ... @defer(label: "breed-defer") { + breed + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name', + 'Dog.breed defer{[label=breed-defer;types=[Dog]]}', + ] + } + + def "fragment on interface field with no type"() { + given: + + String query = ''' + query q { + animal { + ... @defer { + name + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + "[Cat, Dog, Fish].name defer{[label=null;types=[Cat, Dog, Fish]]}", + ] + } + + def "fragments on non-conditional fields"() { + given: + + String query = ''' + query q { + animal { + ... on Cat @defer { + name + } + ... on Dog @defer { + name + } + ... on Animal @defer { + name + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + "[Cat, Dog, Fish].name defer{[label=null;types=[Cat]],[label=null;types=[Dog]],[label=null;types=[Cat, Dog, Fish]]}", + ] + } + + def "fragments on subset of non-conditional fields"() { + given: + + String query = ''' + query q { + animal { + ... on Cat @defer { + name + } + ... on Dog @defer { + name + } + ... on Fish { + name + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + "[Cat, Dog, Fish].name defer{[label=null;types=[Cat]],[label=null;types=[Dog]]}", + ] + } + + def "field on multiple defer declarations is associated with "() { + given: + String query = ''' + query q { + dog { + ... @defer { + name + age + } + ... @defer { + age + } + } + } + ''' + Map variables = [:] + + when: + def executableNormalizedOperation = createExecutableNormalizedOperations(query, variables); + + List printedTree = printTreeWithIncrementalExecutionDetails(executableNormalizedOperation) + + then: + + def nameField = findField(executableNormalizedOperation, "Dog", "name") + def ageField = findField(executableNormalizedOperation, "Dog", "age") + + nameField.deferredExecutions.size() == 1 + ageField.deferredExecutions.size() == 2 + + // age field is associated with 2 defer executions, one of then is shared with "name" the other isn't + ageField.deferredExecutions.any { + it == nameField.deferredExecutions[0] + } + + ageField.deferredExecutions.any { + it != nameField.deferredExecutions[0] + } + + printedTree == ['Query.dog', + "Dog.name defer{[label=null;types=[Dog]]}", + "Dog.age defer{[label=null;types=[Dog]],[label=null;types=[Dog]]}", + ] + } + + def "fragment on interface"() { + given: + + String query = ''' + query q { + animal { + ... on Animal @defer { + name + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + '[Cat, Dog, Fish].name defer{[label=null;types=[Cat, Dog, Fish]]}', + ] + } + + def "fragment on distant interface"() { + given: + + String query = ''' + query q { + animal { + ... on LivingThing @defer { + age + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + '[Cat, Dog, Fish].age defer{[label=null;types=[Cat, Dog, Fish]]}', + ] + } + + def "fragment on union"() { + given: + + String query = ''' + query q { + mammal { + ... on Dog @defer { + name + breed + } + ... on Cat @defer { + name + breed + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.mammal', + '[Dog, Cat].name defer{[label=null;types=[Cat]],[label=null;types=[Dog]]}', + 'Dog.breed defer{[label=null;types=[Dog]]}', + 'Cat.breed defer{[label=null;types=[Cat]]}', + ] + } + + def "fragments on interface"() { + given: + + String query = ''' + query q { + animal { + ... on Animal @defer { + name + } + ... on Animal @defer { + age + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + '[Cat, Dog, Fish].name defer{[label=null;types=[Cat, Dog, Fish]]}', + '[Cat, Dog, Fish].age defer{[label=null;types=[Cat, Dog, Fish]]}', + ] + } + + def "defer on a subselection of non-conditional fields"() { + given: + + String query = ''' + query q { + animal { + ... on Cat @defer { + name + } + ... on Dog { + name + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + '[Cat, Dog].name defer{[label=null;types=[Cat]]}', + ] + } + + def "fragments on conditional fields"() { + given: + + String query = ''' + query q { + animal { + ... on Cat @defer { + breed + } + ... on Dog @defer { + breed + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + 'Cat.breed defer{[label=null;types=[Cat]]}', + 'Dog.breed defer{[label=null;types=[Dog]]}' + ] + } + + def "defer on a single field via inline fragment with type"() { + given: + + String query = ''' + query q { + dog { + name + ... on Dog @defer(label: "breed-defer") { + breed + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name', + 'Dog.breed defer{[label=breed-defer;types=[Dog]]}', + ] + } + + def "1 defer on 2 fields"() { + given: + String query = ''' + query q { + animal { + ... @defer { + name + } + + ... on Dog @defer { + name + breed + } + + ... on Cat @defer { + name + breed + } + } + } + ''' + + Map variables = [:] + + when: + def executableNormalizedOperation = createExecutableNormalizedOperations(query, variables); + + List printedTree = printTreeWithIncrementalExecutionDetails(executableNormalizedOperation) + + then: "should result in the same instance of defer block" + def nameField = findField(executableNormalizedOperation,"[Cat, Dog, Fish]","name") + def dogBreedField = findField(executableNormalizedOperation, "Dog", "breed") + def catBreedField = findField(executableNormalizedOperation, "Cat", "breed") + + nameField.deferredExecutions.size() == 3 + dogBreedField.deferredExecutions.size() == 1 + catBreedField.deferredExecutions.size() == 1 + + // nameField should share a defer block with each of the other fields + nameField.deferredExecutions.any { + it == dogBreedField.deferredExecutions[0] + } + nameField.deferredExecutions.any { + it == catBreedField.deferredExecutions[0] + } + // also, nameField should have a defer block that is not shared with any other field + nameField.deferredExecutions.any { + it != dogBreedField.deferredExecutions[0] && + it != catBreedField.deferredExecutions[0] + } + + printedTree == ['Query.animal', + '[Cat, Dog, Fish].name defer{[label=null;types=[Cat]],[label=null;types=[Dog]],[label=null;types=[Cat, Dog, Fish]]}', + 'Dog.breed defer{[label=null;types=[Dog]]}', + 'Cat.breed defer{[label=null;types=[Cat]]}', + ] + } + + def "2 defers on 2 fields"() { + given: + + String query = ''' + query q { + dog { + ... @defer{ + name + } + ... @defer{ + breed + } + } + } + ''' + + Map variables = [:] + + when: + def executableNormalizedOperation = createExecutableNormalizedOperations(query, variables); + + List printedTree = printTreeWithIncrementalExecutionDetails(executableNormalizedOperation) + + then: "should result in 2 different instances of defer" + def nameField = findField(executableNormalizedOperation, "Dog", "name") + def breedField = findField(executableNormalizedOperation, "Dog", "breed") + + nameField.deferredExecutions.size() == 1 + breedField.deferredExecutions.size() == 1 + + // different label instances + nameField.deferredExecutions[0] != breedField.deferredExecutions[0] + + printedTree == ['Query.dog', + 'Dog.name defer{[label=null;types=[Dog]]}', + 'Dog.breed defer{[label=null;types=[Dog]]}', + ] + } + + def "defer on a fragment definition"() { + given: + + String query = ''' + query q { + dog { + ... DogFrag @defer(label: "breed-defer") + } + } + + fragment DogFrag on Dog { + name + breed + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=breed-defer;types=[Dog]]}', + 'Dog.breed defer{[label=breed-defer;types=[Dog]]}', + ] + } + + def "multiple defer on same field with different labels"() { + given: + + String query = ''' + query q { + dog { + ... @defer(label: "name-defer") { + name + } + + ... @defer(label: "another-name-defer") { + name + } + } + } + + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=another-name-defer;types=[Dog]],[label=name-defer;types=[Dog]]}' + ] + } + + def "multiple fields and a single defer"() { + given: + + String query = ''' + query q { + dog { + ... @defer(label: "name-defer") { + name + } + + ... { + name + } + } + } + + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=name-defer;types=[Dog]]}', + ] + } + + def "multiple fields and a single defer - no label"() { + given: + + String query = ''' + query q { + dog { + ... @defer { + name + } + + ... { + name + } + } + } + + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=null;types=[Dog]]}', + ] + } + + def "multiple fields and multiple defers - no label"() { + given: + + String query = ''' + query q { + dog { + ... @defer { + name + } + + ... @defer { + name + } + } + } + + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=null;types=[Dog]],[label=null;types=[Dog]]}', + ] + } + + def "nested defers - no label"() { + given: + + String query = ''' + query q { + dog { + ... @defer { + name + owner { + firstname + ... @defer { + lastname + } + } + } + } + } + + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=null;types=[Dog]]}', + 'Dog.owner defer{[label=null;types=[Dog]]}', + 'Person.firstname', + 'Person.lastname defer{[label=null;types=[Person]]}', + ] + } + + def "nested defers - with labels"() { + given: + + String query = ''' + query q { + dog { + ... @defer(label:"dog-defer") { + name + owner { + firstname + ... @defer(label: "lastname-defer") { + lastname + } + } + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=dog-defer;types=[Dog]]}', + 'Dog.owner defer{[label=dog-defer;types=[Dog]]}', + 'Person.firstname', + 'Person.lastname defer{[label=lastname-defer;types=[Person]]}', + ] + } + + def "nested defers - with named spreads"() { + given: + + String query = ''' + query q { + animal { + name + ... on Dog @defer(label:"dog-defer") { + owner { + firstname + ... @defer(label: "lastname-defer") { + lastname + } + } + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.animal', + '[Cat, Dog, Fish].name', + 'Dog.owner defer{[label=dog-defer;types=[Dog]]}', + 'Person.firstname', + 'Person.lastname defer{[label=lastname-defer;types=[Person]]}', + ] + } + + def "nesting defer blocks that would always result in no data are ignored"() { + given: + + String query = ''' + query q { + dog { + ... @defer(label: "one") { + ... @defer(label: "two") { + ... @defer(label: "three") { + name + } + } + } + } + } + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=three;types=[Dog]]}', + ] + } + + def "'if' argument is respected"() { + given: + + String query = ''' + query q { + dog { + ... @defer(if: false, label: "name-defer") { + name + } + + ... @defer(if: true, label: "another-name-defer") { + name + } + } + } + + ''' + + Map variables = [:] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=another-name-defer;types=[Dog]]}', + ] + } + + def "'if' argument is respected when value is passed through variable"() { + given: + + String query = ''' + query q($if1: Boolean, $if2: Boolean) { + dog { + ... @defer(if: $if1, label: "name-defer") { + name + } + + ... @defer(if: $if2, label: "another-name-defer") { + name + } + } + } + + ''' + + Map variables = [if1: false, if2: true] + + when: + List printedTree = executeQueryAndPrintTree(query, variables) + + then: + printedTree == ['Query.dog', + 'Dog.name defer{[label=another-name-defer;types=[Dog]]}', + ] + } + + private ExecutableNormalizedOperation createExecutableNormalizedOperations(String query, Map variables) { + assertValidQuery(graphQLSchema, query, variables) + Document document = TestUtil.parseQuery(query) + ExecutableNormalizedOperationFactory dependencyGraph = new ExecutableNormalizedOperationFactory() + + return dependencyGraph.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.of(variables), + ExecutableNormalizedOperationFactory.Options.defaultOptions().deferSupport(true), + ) + } + + private List executeQueryAndPrintTree(String query, Map variables) { + assertValidQuery(graphQLSchema, query, variables) + Document document = TestUtil.parseQuery(query) + ExecutableNormalizedOperationFactory dependencyGraph = new ExecutableNormalizedOperationFactory() + + def tree = dependencyGraph.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.of(variables), + ExecutableNormalizedOperationFactory.Options.defaultOptions().deferSupport(true), + ) + return printTreeWithIncrementalExecutionDetails(tree) + } + + private List printTreeWithIncrementalExecutionDetails(ExecutableNormalizedOperation queryExecutionTree) { + def result = [] + Traverser traverser = Traverser.depthFirst({ it.getChildren() }) + + traverser.traverse(queryExecutionTree.getTopLevelFields(), new TraverserVisitorStub() { + @Override + TraversalControl enter(TraverserContext context) { + ExecutableNormalizedField queryExecutionField = context.thisNode() + result << queryExecutionField.printDetails() + printDeferExecutionDetails(queryExecutionField) + return TraversalControl.CONTINUE + } + + String printDeferExecutionDetails(ExecutableNormalizedField field) { + def deferExecutions = field.deferredExecutions + if (deferExecutions == null || deferExecutions.isEmpty()) { + return "" + } + + def deferLabels = new ArrayList<>(deferExecutions) + .sort { it.label } + .sort { it.possibleTypes.collect {it.name} } + .collect { "[label=${it.label};types=${it.possibleTypes.collect{it.name}.sort()}]" } + .join(",") + + return " defer{${deferLabels}}" + } + }) + + result + } + + private static void assertValidQuery(GraphQLSchema graphQLSchema, String query, Map variables = [:]) { + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + def ei = ExecutionInput.newExecutionInput(query).variables(variables).build() + assert graphQL.execute(ei).errors.size() == 0 + } + + private static ExecutableNormalizedField findField(ExecutableNormalizedOperation operation, String objectTypeNames, String fieldName) { + return operation.normalizedFieldToMergedField + .collect { it.key } + .find { it.fieldName == fieldName + && it.objectTypeNamesToString() == objectTypeNames} + } +} diff --git a/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationFactoryTest.groovy b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationFactoryTest.groovy new file mode 100644 index 0000000000..a04c74f954 --- /dev/null +++ b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationFactoryTest.groovy @@ -0,0 +1,3297 @@ +package graphql.normalized + +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.AbortExecutionException +import graphql.execution.CoercedVariables +import graphql.execution.MergedField +import graphql.execution.RawVariables +import graphql.execution.directives.QueryAppliedDirective +import graphql.introspection.IntrospectionQuery +import graphql.language.Document +import graphql.language.Field +import graphql.language.FragmentDefinition +import graphql.language.OperationDefinition +import graphql.schema.GraphQLDirective +import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLTypeUtil +import graphql.util.TraversalControl +import graphql.util.Traverser +import graphql.util.TraverserContext +import graphql.util.TraverserVisitorStub +import spock.lang.Specification + +import java.util.stream.Collectors +import java.util.stream.IntStream + +import static graphql.TestUtil.schema +import static graphql.language.AstPrinter.printAst +import static graphql.parser.Parser.parseValue +import static graphql.schema.FieldCoordinates.coordinates + +class ExecutableNormalizedOperationFactoryTest extends Specification { + static boolean deferSupport + + + def "test"() { + String schema = """ +type Query{ + animal: Animal +} +interface Animal { + name: String + friends: [Friend] +} + +union Pet = Dog | Cat + +type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] +} + +type Bird implements Animal { + name: String + friends: [Friend] +} + +type Cat implements Animal{ + name: String + friends: [Friend] + breed: String +} + +type Dog implements Animal{ + name: String + breed: String + friends: [Friend] +} + + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + animal{ + name + otherName: name + ... on Animal { + name + } + ... on Cat { + name + friends { + ... on Friend { + isCatOwner + pets { + ... on Dog { + name + } + } + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Dog { + name + } + }} + + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.animal: Animal', + '--[Bird, Cat, Dog].name: String', + '--otherName: [Bird, Cat, Dog].name: String', + '--Cat.friends: [Friend]', + '---Friend.isCatOwner: Boolean', + '---Friend.pets: [Pet]', + '----Dog.name: String', + '--Bird.friends: [Friend]', + '---Friend.isBirdOwner: Boolean', + '---Friend.name: String', + '---Friend.pets: [Pet]', + '----Cat.breed: String' + ] + } + + def "test2"() { + String schema = """ + type Query{ + a: A + } + interface A { + b: B + } + type A1 implements A { + b: B + } + type A2 implements A{ + b: B + } + interface B { + leaf: String + } + type B1 implements B { + leaf: String + } + type B2 implements B { + leaf: String + } + + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + a { + ... on A { + myAlias: b { leaf } + } + ... on A1 { + b { + ... on B1 { + leaf + } + ... on B2 { + leaf + } + } + } + ... on A1 { + b { + ... on B1 { + leaf + } + } + } + ... on A2 { + b { + ... on B2 { + leaf + } + } + } + } + } + + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.a: A', + '--myAlias: [A1, A2].b: B', + '---[B1, B2].leaf: String', + '--A1.b: B', + '---[B1, B2].leaf: String', + '--A2.b: B', + '---B2.leaf: String' + ] + + + } + + def "test3"() { + String schema = """ + type Query{ + a: [A] + object: Object + } + type Object { + someValue: String + } + interface A { + b: B + } + type A1 implements A { + b: B + } + type A2 implements A{ + b: B + } + interface B { + leaf: String + } + type B1 implements B { + leaf: String + } + type B2 implements B { + leaf: String + } + + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + object{someValue} + a { + ... on A1 { + b { + ... on B { + leaf + } + ... on B1 { + leaf + } + ... on B2 { + ... on B { + leaf + } + leaf + leaf + ... on B2 { + leaf + } + } + } + } + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.object: Object', + '--Object.someValue: String', + '-Query.a: [A]', + '--A1.b: B', + '---[B1, B2].leaf: String' + ] + + } + + def "test impossible type condition"() { + + String schema = """ + type Query{ + pets: [Pet] + } + interface Pet { + name: String + } + type Cat implements Pet { + name: String + } + type Dog implements Pet{ + name: String + } + union CatOrDog = Cat | Dog + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pets { + ... on Dog { + ... on CatOrDog { + ... on Cat{ + name + } + } + } + } + } + + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.pets'] + + } + + def "query with unions and __typename"() { + + String schema = """ + type Query{ + pets: [CatOrDog] + } + type Cat { + catName: String + } + type Dog { + dogName: String + } + union CatOrDog = Cat | Dog + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pets { + __typename + ... on Cat { + catName + } + ... on Dog { + dogName + } + } + } + + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.pets', + '[Cat, Dog].__typename', + 'Cat.catName', + 'Dog.dogName'] + + } + + def "query with interface"() { + + String schema = """ + type Query{ + pets: [Pet] + } + interface Pet { + id: ID + } + type Cat implements Pet{ + id: ID + catName: String + } + type Dog implements Pet{ + id: ID + dogName: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pets { + id + ... on Cat { + catName + } + ... on Dog { + dogName + } + } + } + + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.pets', + '[Cat, Dog].id', + 'Cat.catName', + 'Dog.dogName'] + + } + + def "test5"() { + String schema = """ + type Query{ + a: [A] + } + interface A { + b: String + } + type A1 implements A { + b: String + } + type A2 implements A{ + b: String + otherField: A + } + type A3 implements A { + b: String + } + + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + + def query = """ + { + a { + b + ... on A1 { + b + } + ... on A2 { + b + otherField { + ... on A2 { + b + } + ... on A3 { + b + } + } + + } + } + } + + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.a: [A]', + '--[A1, A2, A3].b: String', + '--A2.otherField: A', + '---[A2, A3].b: String' + ] + + } + + def "test6"() { + String schema = """ + type Query { + issues: [Issue] + } + + type Issue { + id: ID + author: User + } + type User { + name: String + createdIssues: [Issue] + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + def query = """{ issues { + author { + name + ... on User { + createdIssues { + id + } + } + } + }} + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.issues', + 'Issue.author', + 'User.name', + 'User.createdIssues', + 'Issue.id'] + + } + + def "test7"() { + String schema = """ + type Query { + issues: [Issue] + } + + type Issue { + authors: [User] + } + type User { + name: String + friends: [User] + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + def query = """{ issues { + authors { + friends { + friends { + name + } + } + } + }} + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.issues', + 'Issue.authors', + 'User.friends', + 'User.friends', + 'User.name'] + + } + + def "parses operation name"() { + String schema = """ + type Query { + issues: [Issue] + } + + type Issue { + authors: [User] + } + type User { + name: String + friends: [User] + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + def query = """query X_28 { issues { + authors { + friends { + friends { + name + } + } + } + }} + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + tree.operation == OperationDefinition.Operation.QUERY + tree.operationName == "X_28" + printedTree == ['Query.issues', + 'Issue.authors', + 'User.friends', + 'User.friends', + 'User.name'] + + } + + def "query with fragment definition"() { + def graphQLSchema = TestUtil.schema(""" + type Query{ + foo: Foo + } + type Foo { + subFoo: String + moreFoos: Foo + } + """) + def query = """ + {foo { ...fooData moreFoos { ...fooData }}} fragment fooData on Foo { subFoo } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.foo', + 'Foo.subFoo', + 'Foo.moreFoos', + 'Foo.subFoo'] + } + + def "query with fragment and type condition"() { + def graphQLSchema = TestUtil.schema(""" + type Query { + pet(qualifier : String) : Pet + } + interface Pet { + name(nameArg : String) : String + } + + type Dog implements Pet { + name(nameArg : String) : String + } + + type Bird implements Pet { + name(nameArg : String) : String + } + + type Cat implements Pet { + name(nameArg : String) : String + } + """) + def query = """ + { + pet { + name + ... on Dog { + name + } + ... CatFrag + } + } + + fragment CatFrag on Cat { + name + } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.pet: Pet', + '--[Bird, Cat, Dog].name: String' + ] + } + + def "query with fragment and type condition merged together 2"() { + def graphQLSchema = TestUtil.schema(""" + type Query { + pet : Pet + } + interface Pet { + name : String + } + + type Dog implements Pet { + name : String + } + + type Bird implements Pet { + name : String + } + + type Cat implements Pet { + name : String + } + """) + def query = """ + { + pet { + name + ... on Dog { + name + } + ... CatFrag + } + } + + fragment CatFrag on Cat { + name + } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.pet: Pet', + '--[Bird, Cat, Dog].name: String' + ] + } + + + def "query with interface in between"() { + def graphQLSchema = schema(""" + type Query { + pets: [Pet] + } + interface Pet { + name: String + friends: [Human] + } + type Human { + name: String + } + type Cat implements Pet { + name: String + friends: [Human] + } + type Dog implements Pet { + name: String + friends: [Human] + } + """) + def query = """ + { pets { friends {name} } } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.pets', + '[Cat, Dog].friends', + 'Human.name'] + } + + def "test interface fields with different output types (covariance) on the implementations"() { + def graphQLSchema = schema(""" + interface Animal { + parent: Animal + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + def query = """ + { + animal { + parent { + name + } + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == [ + "-Query.animal: Animal", + "--[Cat, Dog].parent: Cat, Dog", + "---[Cat, Dog].name: String", + ] + } + + def "__typename in unions get merged"() { + def graphQLSchema = schema(""" + + type Cat { + name: String + } + type Dog { + name: String + } + union CatOrDog = Cat | Dog + type Query { + animal: CatOrDog + } + """) + + def query = """ + { + animal { + ... on Cat {__typename} + ... on Dog {__typename} + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == [ + "-Query.animal: CatOrDog", + "--[Cat, Dog].__typename: String!", + ] + } + + def "test union fields with different output types (covariance) on the implementations"() { + def graphQLSchema = schema(""" + + interface Animal { + parent: CatOrDog + name: String + } + type Cat implements Animal{ + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + union CatOrDog = Cat | Dog + type Query { + animal: Animal + } + """) + + def query = """ + { + animal { + parent { + ... on Cat {name __typename } + ... on Dog {name __typename } + } + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == [ + "-Query.animal: Animal", + "--[Cat, Dog].parent: Cat, Dog", + "---[Cat, Dog].name: String", + "---[Cat, Dog].__typename: String!" + ] + } + + List printTree(ExecutableNormalizedOperation queryExecutionTree) { + def result = [] + Traverser traverser = Traverser.depthFirst({ it.getChildren() }) + traverser.traverse(queryExecutionTree.getTopLevelFields(), new TraverserVisitorStub() { + @Override + TraversalControl enter(TraverserContext context) { + ExecutableNormalizedField queryExecutionField = context.thisNode() + result << queryExecutionField.printDetails() + return TraversalControl.CONTINUE + } + }) + result + } + + List printTreeAndDirectives(ExecutableNormalizedOperation queryExecutionTree) { + def result = [] + Traverser traverser = Traverser.depthFirst({ it.getChildren() }) + traverser.traverse(queryExecutionTree.getTopLevelFields(), new TraverserVisitorStub() { + @Override + TraversalControl enter(TraverserContext context) { + ExecutableNormalizedField queryExecutionField = context.thisNode() + def queryDirectives = queryExecutionTree.getQueryDirectives(queryExecutionField) + + def fieldDetails = queryExecutionField.printDetails() + if (queryDirectives != null) { + def appliedDirectivesByName = queryDirectives.getImmediateAppliedDirectivesByName() + if (!appliedDirectivesByName.isEmpty()) { + fieldDetails += " " + printDirectives(appliedDirectivesByName) + } + } + result << fieldDetails + return TraversalControl.CONTINUE + } + + String printDirectives(Map> stringListMap) { + String s = stringListMap.collect { entry -> + entry.value.collect { + " @" + it.name + "(" + it.getArguments().collect { + it.name + " : " + '"' + it.value + '"' + }.join(",") + ")" + }.join(' ') + }.join(" ") + return s + } + }) + result + } + + static List printTreeWithLevelInfo(ExecutableNormalizedOperation queryExecutionTree, GraphQLSchema schema) { + def result = [] + Traverser traverser = Traverser.depthFirst({ it.getChildren() }) + traverser.traverse(queryExecutionTree.getTopLevelFields(), new TraverserVisitorStub() { + @Override + TraversalControl enter(TraverserContext context) { + ExecutableNormalizedField queryExecutionField = context.thisNode() + String prefix = "" + for (int i = 1; i <= queryExecutionField.getLevel(); i++) { + prefix += "-" + } + + def possibleOutputTypes = new LinkedHashSet() + for (fieldDef in queryExecutionField.getFieldDefinitions(schema)) { + possibleOutputTypes.add(GraphQLTypeUtil.simplePrint(fieldDef.type)) + } + + result << (prefix + queryExecutionField.printDetails() + ": " + possibleOutputTypes.join(", ")) + return TraversalControl.CONTINUE + } + }) + result + } + + def "field to normalized field is build"() { + def graphQLSchema = TestUtil.schema(""" + type Query{ + foo: Foo + } + type Foo { + subFoo: String + moreFoos: Foo + } + """) + def query = """ + {foo { ...fooData moreFoos { ...fooData }}} fragment fooData on Foo { subFoo } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + def subFooField = (document.getDefinitions()[1] as FragmentDefinition).getSelectionSet().getSelections()[0] as Field + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def fieldToNormalizedField = tree.getFieldToNormalizedField() + + expect: + fieldToNormalizedField.keys().size() == 4 + fieldToNormalizedField.get(subFooField).size() == 2 + fieldToNormalizedField.get(subFooField)[0].level == 2 + fieldToNormalizedField.get(subFooField)[1].level == 3 + } + + def "normalized fields map with interfaces "() { + + String schema = """ + type Query{ + pets: [Pet] + } + interface Pet { + id: ID + } + type Cat implements Pet{ + id: ID + } + type Dog implements Pet{ + id: ID + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pets { + id + } + } + + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + def petsField = (document.getDefinitions()[0] as OperationDefinition).getSelectionSet().getSelections()[0] as Field + def idField = petsField.getSelectionSet().getSelections()[0] as Field + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def fieldToNormalizedField = tree.getFieldToNormalizedField() + + + expect: + fieldToNormalizedField.size() == 2 + fieldToNormalizedField.get(petsField).size() == 1 + fieldToNormalizedField.get(petsField)[0].printDetails() == "Query.pets" + fieldToNormalizedField.get(idField).size() == 1 + fieldToNormalizedField.get(idField)[0].printDetails() == "[Cat, Dog].id" + + + } + + def "query with introspection fields"() { + String schema = """ + type Query{ + foo: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + __typename + alias: __typename + __schema { queryType { name } } + __type(name: "Query") {name} + ...F + } + fragment F on Query { + __typename + alias: __typename + __schema { queryType { name } } + __type(name: "Query") {name} + } + + + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + def selections = (document.getDefinitions()[0] as OperationDefinition).getSelectionSet().getSelections() + def typeNameField = selections[0] as Field + def aliasedTypeName = selections[1] as Field + def schemaField = selections[2] as Field + def typeField = selections[3] as Field + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def fieldToNormalizedField = tree.getFieldToNormalizedField() + + expect: + fieldToNormalizedField.size() == 14 + fieldToNormalizedField.get(typeNameField)[0].objectTypeNamesToString() == "Query" + fieldToNormalizedField.get(typeNameField)[0].getFieldDefinitions(graphQLSchema) == [graphQLSchema.getIntrospectionTypenameFieldDefinition()] + fieldToNormalizedField.get(aliasedTypeName)[0].alias == "alias" + fieldToNormalizedField.get(aliasedTypeName)[0].getFieldDefinitions(graphQLSchema) == [graphQLSchema.getIntrospectionTypenameFieldDefinition()] + + fieldToNormalizedField.get(schemaField)[0].objectTypeNamesToString() == "Query" + fieldToNormalizedField.get(schemaField)[0].getFieldDefinitions(graphQLSchema) == [graphQLSchema.getIntrospectionSchemaFieldDefinition()] + + fieldToNormalizedField.get(typeField)[0].objectTypeNamesToString() == "Query" + fieldToNormalizedField.get(typeField)[0].getFieldDefinitions(graphQLSchema) == [graphQLSchema.getIntrospectionTypeFieldDefinition()] + + } + + def "fragment is used multiple times with different parents"() { + String schema = """ + type Query{ + pet: Pet + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pet { + ... on Dog { + ...F + } + ... on Cat { + ...F + } + } + } + fragment F on Pet { + name + } + + + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.pet: Pet', + '--[Dog, Cat].name: String'] + } + + def "same result key but different field"() { + String schema = """ + type Query{ + pet: Pet + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + otherField: String + } + type Cat implements Pet { + name: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + pet { + ... on Dog { + name: otherField + } + ... on Cat { + name + } + } + } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTree(tree) + + expect: + printedTree == ['Query.pet', + 'name: Dog.otherField', + 'Cat.name'] + } + + def "normalized field to MergedField is build"() { + given: + def graphQLSchema = TestUtil.schema(""" + type Query{ + foo: Foo + } + type Foo { + subFoo: String + moreFoos: Foo + } + """) + def query = """ + {foo { ...fooData moreFoos { ...fooData }}} fragment fooData on Foo { subFoo } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def normalizedFieldToMergedField = tree.getNormalizedFieldToMergedField() + Traverser traverser = Traverser.depthFirst({ it.getChildren() }) + List result = new ArrayList<>() + when: + traverser.traverse(tree.getTopLevelFields(), new TraverserVisitorStub() { + @Override + TraversalControl enter(TraverserContext context) { + ExecutableNormalizedField normalizedField = context.thisNode() + result.add(normalizedFieldToMergedField[normalizedField]) + return TraversalControl.CONTINUE + } + }) + + then: + result.size() == 4 + result.collect { it.getResultKey() } == ['foo', 'subFoo', 'moreFoos', 'subFoo'] + } + + def "coordinates to NormalizedField is build"() { + given: + def graphQLSchema = TestUtil.schema(""" + type Query{ + foo: Foo + } + type Foo { + subFoo: String + moreFoos: Foo + } + """) + def query = """ + {foo { ...fooData moreFoos { ...fooData }}} fragment fooData on Foo { subFoo } + """ + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + when: + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def coordinatesToNormalizedFields = tree.coordinatesToNormalizedFields + + then: + coordinatesToNormalizedFields.size() == 4 + coordinatesToNormalizedFields.get(coordinates("Query", "foo")).size() == 1 + coordinatesToNormalizedFields.get(coordinates("Foo", "moreFoos")).size() == 1 + coordinatesToNormalizedFields.get(coordinates("Foo", "subFoo")).size() == 2 + } + + def "handles mutations"() { + String schema = """ +type Query{ + animal: Animal +} + +type Mutation { + createAnimal: Query +} + +type Subscription { + subscribeToAnimal: Query +} + +interface Animal { + name: String + friends: [Friend] +} + +union Pet = Dog | Cat + +type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] +} + +type Bird implements Animal { + name: String + friends: [Friend] +} + +type Cat implements Animal{ + name: String + friends: [Friend] + breed: String +} + +type Dog implements Animal{ + name: String + breed: String + friends: [Friend] +} + +schema { + query: Query + mutation: Mutation + subscription: Subscription +} + + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String mutation = """ + mutation TestMutation{ + createAnimal { + animal { + name + otherName: name + ... on Cat { + name + friends { + ... on Friend { + isCatOwner + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + } + } + ... on Dog { + name + } + } + } + } + """ + + assertValidQuery(graphQLSchema, mutation) + + Document document = TestUtil.parseQuery(mutation) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Mutation.createAnimal: Query', + '--Query.animal: Animal', + '---[Bird, Cat, Dog].name: String', + '---otherName: [Bird, Cat, Dog].name: String', + '---Cat.friends: [Friend]', + '----Friend.isCatOwner: Boolean', + '---Bird.friends: [Friend]', + '----Friend.isBirdOwner: Boolean', + '----Friend.name: String'] + } + + private void assertValidQuery(GraphQLSchema graphQLSchema, String query, Map variables = [:]) { + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + def ei = ExecutionInput.newExecutionInput(query).variables(variables).build() + assert graphQL.execute(ei).errors.size() == 0 + } + + def "normalized arguments"() { + given: + String schema = """ + type Query{ + dog(id:ID): Dog + } + type Dog { + name: String + search(arg1: Input1, arg2: Input1, arg3: Input1): Boolean + } + input Input1 { + foo: String + input2: Input2 + } + input Input2 { + bar: Int + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + query(\$var1: Input2, \$var2: Input1){dog(id: "123"){ + search(arg1: {foo: "foo", input2: {bar: 123}}, arg2: {foo: "foo", input2: \$var1}, arg3: \$var2) + }} + """ + + assertValidQuery(graphQLSchema, query) + Document document = TestUtil.parseQuery(query) + + def variables = [ + var1: [bar: 123], + var2: [foo: "foo", input2: [bar: 123]] + ] + // the normalized arg value should be the same regardless of how the value was provided + def expectedNormalizedArgValue = [foo: new NormalizedInputValue("String", parseValue('"foo"')), input2: new NormalizedInputValue("Input2", [bar: new NormalizedInputValue("Int", parseValue("123"))])] + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.of(variables)) + def topLevelField = tree.getTopLevelFields().get(0) + def secondField = topLevelField.getChildren().get(0) + def arg1 = secondField.getNormalizedArgument("arg1") + def arg2 = secondField.getNormalizedArgument("arg2") + def arg3 = secondField.getNormalizedArgument("arg3") + + then: + topLevelField.getNormalizedArgument("id").getTypeName() == "ID" + printAst(topLevelField.getNormalizedArgument("id").getValue()) == '"123"' + + arg1.getTypeName() == "Input1" + arg1.getValue() == expectedNormalizedArgValue + arg2.getTypeName() == "Input1" + arg2.value == expectedNormalizedArgValue + arg3.getTypeName() == "Input1" + arg3.value == expectedNormalizedArgValue + } + + def "arguments with absent variable values inside input objects"() { + given: + def schema = """ + type Query { + hello(arg: Arg, otherArg: String = "otherValue"): String + } + input Arg { + ids: [ID] = ["defaultId"] + } + """ + def graphQLSchema = TestUtil.schema(schema) + + def query = """ + query myQuery(\$varIds: [ID], \$otherVar: String) { + hello(arg: {ids: \$varIds}, otherArg: \$otherVar) + } + """ + + assertValidQuery(graphQLSchema, query) + def document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.emptyVariables()) + + then: + def topLevelField = tree.getTopLevelFields().get(0) + + def arg = topLevelField.getNormalizedArgument("arg") + arg == new NormalizedInputValue("Arg", [:]) + !topLevelField.normalizedArguments.containsKey("otherArg") + + topLevelField.resolvedArguments.get("arg") == [ids: ["defaultId"]] + topLevelField.resolvedArguments.get("otherArg") == "otherValue" + } + + def "arguments with null variable values"() { + given: + def schema = """ + type Query { + hello(arg: Arg, otherArg: String = "otherValue"): String + } + input Arg { + ids: [ID] = ["defaultId"] + } + """ + def graphQLSchema = TestUtil.schema(schema) + + def query = """ + query nadel_2_MyService_myQuery(\$varIds: [ID], \$otherVar: String) { + hello(arg: {ids: \$varIds}, otherArg: \$otherVar) + } + """ + + assertValidQuery(graphQLSchema, query) + def document = TestUtil.parseQuery(query) + + def variables = [ + varIds : null, + otherVar: null, + ] + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.of(variables)) + + then: + def topLevelField = tree.getTopLevelFields().get(0) + def arg = topLevelField.getNormalizedArgument("arg") + def otherArg = topLevelField.getNormalizedArgument("otherArg") + + arg == new NormalizedInputValue( + "Arg", + [ + ids: new NormalizedInputValue( + "[ID]", + null, + ), + ] + ) + otherArg == new NormalizedInputValue("String", null) + + topLevelField.resolvedArguments.get("arg") == [ids: null] + topLevelField.resolvedArguments.get("otherArg") == null + } + + def "normalized arguments with lists"() { + given: + String schema = """ + type Query{ + search(arg1:[ID!], arg2:[[Input1]], arg3: [Input1]): Boolean + } + input Input1 { + foo: String + input2: Input2 + } + input Input2 { + bar: Int + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + query($var1: [Input1], $var2: ID!){ + search(arg1:["1",$var2], arg2: [[{foo: "foo1", input2: {bar: 123}},{foo: "foo2", input2: {bar: 456}}]], arg3: $var1) + } + ''' + + def variables = [ + var1: [[foo: "foo3", input2: [bar: 789]]], + var2: "2", + ] + assertValidQuery(graphQLSchema, query, variables) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.of(variables)) + def topLevelField = tree.getTopLevelFields().get(0) + def arg1 = topLevelField.getNormalizedArgument("arg1") + def arg2 = topLevelField.getNormalizedArgument("arg2") + def arg3 = topLevelField.getNormalizedArgument("arg3") + + then: + arg1.typeName == "[ID!]" + arg1.value.collect { printAst(it) } == ['"1"', '"2"'] + arg2.typeName == "[[Input1]]" + arg2.value == [[ + [foo: new NormalizedInputValue("String", parseValue('"foo1"')), input2: new NormalizedInputValue("Input2", [bar: new NormalizedInputValue("Int", parseValue("123"))])], + [foo: new NormalizedInputValue("String", parseValue('"foo2"')), input2: new NormalizedInputValue("Input2", [bar: new NormalizedInputValue("Int", parseValue("456"))])] + ]] + + arg3.getTypeName() == "[Input1]" + arg3.value == [ + [foo: new NormalizedInputValue("String", parseValue('"foo3"')), input2: new NormalizedInputValue("Input2", [bar: new NormalizedInputValue("Int", parseValue("789"))])], + ] + + + } + + def "normalized arguments with lists 2"() { + given: + String schema = """ + type Query{ + search(arg1:[[Input1]] ,arg2:[[ID!]!]): Boolean + } + input Input1 { + foo: String + input2: Input2 + } + input Input2 { + bar: Int + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + query($var1: [Input1], $var2: [ID!]!){ + search(arg1: [$var1],arg2:[["1"],$var2] ) + } + ''' + + def variables = [ + var1: [[foo: "foo1", input2: [bar: 123]]], + var2: "2" + ] + assertValidQuery(graphQLSchema, query, variables) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.of(variables)) + def topLevelField = tree.getTopLevelFields().get(0) + def arg1 = topLevelField.getNormalizedArgument("arg1") + def arg2 = topLevelField.getNormalizedArgument("arg2") + + then: + arg1.typeName == "[[Input1]]" + arg1.value == [[ + [foo: new NormalizedInputValue("String", parseValue('"foo1"')), input2: new NormalizedInputValue("Input2", [bar: new NormalizedInputValue("Int", parseValue("123"))])], + ]] + arg2.typeName == "[[ID!]!]" + arg2.value.collect { outer -> outer.collect { printAst(it) } } == [['"1"'], ['"2"']] + } + + + def "recursive schema with a lot of objects"() { + given: + String schema = """ + type Query{ + foo: Foo + } + interface Foo { + field: Foo + id: ID + } + type O1 implements Foo { + field: Foo + id: ID + } + type O2 implements Foo { + field: Foo + id: ID + } + type O3 implements Foo { + field: Foo + id: ID + } + type O4 implements Foo { + field: Foo + id: ID + } + type O5 implements Foo { + field: Foo + id: ID + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + {foo{field{id}}foo{field{id}}} + ''' + assertValidQuery(graphQLSchema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.emptyVariables()) + + then: + tree.normalizedFieldToMergedField.size() == 3 + tree.fieldToNormalizedField.size() == 6 + println String.join("\n", printTree(tree)) + /** + * NF{Query.foo} -> NF{"O1...O5".field,} -> NF{O1...O5.id}*/ + } + + def "diverged fields"() { + given: + String schema = """ + type Query { + pets: Pet + } + interface Pet { + name: String + } + type Cat implements Pet { + name: String + catValue: Int + catFriend(arg: String): CatFriend + } + type CatFriend { + catFriendName: String + } + type Dog implements Pet { + name: String + dogValue: Float + dogFriend: DogFriend + } + type DogFriend { + dogFriendName: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + {pets { + ... on Cat { + friend: catFriend(arg: "hello") { + catFriendName + }} + ... on Cat { + friend: catFriend(arg: "hello") { + catFriendName + }} + ... on Dog { + friend: dogFriend { + dogFriendName + }} + }} + ''' + assertValidQuery(graphQLSchema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + then: + // the two friend fields are not in on ENF + printedTree == ['-Query.pets: Pet', + '--friend: Cat.catFriend: CatFriend', + '---CatFriend.catFriendName: String', + '--friend: Dog.dogFriend: DogFriend', + '---DogFriend.dogFriendName: String'] + + tree.normalizedFieldToMergedField.size() == 5 + tree.fieldToNormalizedField.size() == 7 + } + + def "diverged fields 2"() { + given: + String schema = """ + type Query { + pets: Pet + } + interface Pet { + name(arg:String): String + } + type Cat implements Pet { + name(arg: String): String + } + + type Dog implements Pet { + name(arg: String): String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + {pets { + ... on Cat { + name(arg: "foo") + } + ... on Dog { + name(arg: "fooOther") + } + }} + ''' + assertValidQuery(graphQLSchema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + then: + /** + * the two name fields are not merged, because they are backed by different fields with different arguments + * If the arguments are the same, it would be one ENF. + */ + printedTree == ['-Query.pets: Pet', + '--Cat.name: String', + '--Dog.name: String' + ] + } + + + def "diverging fields with the same parent type on deeper level"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + name : String + friends: [Pet] + + } + ''') + /** + * Here F1 and F2 are allowed to diverge (backed by different field definitions) because the parent fields have + * different concrete parent: P1 has Dog, P2 has Cat. + */ + def query = ''' + { + pets { + ... on Dog { + friends { #P1 + name + ... on Dog { + breed: dogBreed #F1 + } + } + } + ... on Cat { + friends { #P2 + catFriendsName: name + ... on Dog { + breed #F2 + } + } + } + ... on Pet { + friends { + name + } + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--Dog.friends: [Pet]', + '---[Cat, Dog].name: String', + '---breed: Dog.dogBreed: String', + '--Cat.friends: [Pet]', + '---catFriendsName: [Cat, Dog].name: String', + '---Dog.breed: String', + '---[Cat, Dog].name: String' + ] + } + + def "subselection different with different concrete parents"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + name : String + friends: [Pet] + + } + ''') + def query = ''' + { + pets { + ... on Dog { + friends { #P1 + name + } + } + ... on Cat { + friends { + otherName: name + } + } + friends { + breed + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--Dog.friends: [Pet]', + '---[Cat, Dog].name: String', + '---[Cat, Dog].breed: String', + '--Cat.friends: [Pet]', + '---otherName: [Cat, Dog].name: String', + '---[Cat, Dog].breed: String', + ] + } + + + def "diverging non-composite fields"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + name : String + friends: [Pet] + + } + ''') + def query = ''' + { + pets { + ... on Dog { + breed: dogBreed + } + ... on Cat { + breed: catBreed + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--breed: Dog.dogBreed: String', + '--breed: Cat.catBreed: String' + ] + } + + def "different children for different Interfaces"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + + interface Mammal implements Pet { + name: String + breed: String + friends: [Pet] + } + type Turtle implements Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Mammal & Pet { + name: String + dogBreed: String + breed: String + friends: [Pet] + } + type Cat implements Mammal & Pet { + catBreed: String + breed: String + name : String + friends: [Pet] + } + ''') + def query = ''' + { + pets { + ... on Cat { + friends { + catFriendName: name + } + } + ... on Dog { + friends { + dogFriendName: name + } + } + ... on Mammal { + friends { + name + } + } + ... on Pet { + friends { + breed + } + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--Cat.friends: [Pet]', + '---catFriendName: [Cat, Dog, Turtle].name: String', + '---[Cat, Dog, Turtle].name: String', + '---[Cat, Dog, Turtle].breed: String', + '--Dog.friends: [Pet]', + '---dogFriendName: [Cat, Dog, Turtle].name: String', + '---[Cat, Dog, Turtle].name: String', + '---[Cat, Dog, Turtle].breed: String', + '--Turtle.friends: [Pet]', + '---[Cat, Dog, Turtle].breed: String' + ] + } + + def "diverging fields with Union as parent type"() { + given: + def schema = schema(''' + type Query { + pets: [DogOrCat] + } + type Dog { + name: String + dogBreed: String + breed: String + friends: [DogOrCat] + } + type Cat { + catBreed: String + breed: String + name : String + friends: [DogOrCat] + } + union DogOrCat = Dog | Cat + ''') + def query = ''' + { + pets { + ... on Dog { + friends { #P1 + ... on Dog { + breed: dogBreed #F1 + } + } + } + ... on Cat { + friends { #P2 + ... on Dog { + breed #F2 + } + } + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [DogOrCat]', + '--Dog.friends: [DogOrCat]', + '---breed: Dog.dogBreed: String', + '--Cat.friends: [DogOrCat]', + '---Dog.breed: String' + ] + } + + def "union fields are not merged"() { + given: + def schema = schema(''' + type Query { + pets: [DogOrCat] + } + type Dog { + name: String + } + type Cat { + name: String + } + union DogOrCat = Dog | Cat + ''') + def query = ''' + { + pets { + ... on Dog { + name + } + ... on Cat { + name + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [DogOrCat]', + '--Dog.name: String', + '--Cat.name: String' + ] + } + + def "union fields which are shared in an interface are merged"() { + given: + def schema = schema(''' + type Query { + pets: [DogOrCat] + } + interface Pet { + name: String + } + type Dog implements Pet{ + name: String + } + type Cat implements Pet{ + name: String + } + union DogOrCat = Dog | Cat + ''') + def query = ''' + { + pets { + ... on Dog { + name + } + ... on Cat { + name + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [DogOrCat]', + '--[Dog, Cat].name: String' + ] + } + + def "fields which don't come from a shared interface are not merged"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + } + type Dog implements Pet{ + name: String + breed: String + } + + type Cat implements Pet{ + name: String + breed: String + } + ''') + def query = ''' + { + pets { + ... on Dog { + breed + } + ... on Cat { + breed + } + }} + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--Dog.breed: String', + '--Cat.breed: String' + ] + } + + def "fields are merged together on multiple level"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + name : String + friends: [Pet] + + } + + ''') + def query = ''' + { + pets { + ... on Dog { + friends { + ... on Dog { + friends { + name + } + } + ... on Cat { + friends { + name + } + } + } + } + ... on Cat { + friends { + ... on Dog { + friends { + name + } + } + ... on Cat { + friends { + name + } + } + } + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--[Dog, Cat].friends: [Pet]', + '---[Dog, Cat].friends: [Pet]', + '----[Cat, Dog].name: String' + ] + } + + def "fields are not merged together because of different arguments on deeper level"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name(arg:String): String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name(arg:String): String + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + name(arg:String) : String + friends: [Pet] + + } + + ''') + def query = ''' + { + pets { + ... on Dog { + friends { + ... on Dog { + friends { + name + } + } + ... on Cat { + friends { + name + } + } + } + } + ... on Cat { + friends { + ... on Dog { + friends { + name + } + } + ... on Cat { + friends { + name(arg: "not-be-merged") + } + } + } + } + } + } + ''' + assertValidQuery(schema, query) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, schema) + + then: + printedTree == ['-Query.pets: [Pet]', + '--Dog.friends: [Pet]', + '---[Dog, Cat].friends: [Pet]', + '----[Cat, Dog].name: String', + '--Cat.friends: [Pet]', + '---Dog.friends: [Pet]', + '----[Cat, Dog].name: String', + '---Cat.friends: [Pet]', + '----[Cat, Dog].name: String' + ] + } + + + def "skip/include is respected"() { + given: + String schema = """ + type Query { + pets: Pet + } + interface Pet { + name: String + } + type Cat implements Pet { + name: String + } + type Dog implements Pet { + name: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + query($true: Boolean!,$false: Boolean!){pets { + ... on Cat { + cat_not: name @skip(if:true) + cat_not: name @skip(if:$true) + cat_yes_1: name @include(if:true) + cat_yes_2: name @skip(if:$false) + } + ... on Dog @include(if:$true) { + dog_no: name @include(if:false) + dog_no: name @include(if:$false) + dog_yes_1: name @include(if:$true) + dog_yes_2: name @skip(if:$false) + } + ... on Pet @skip(if:$true) { + not: name + } + ... on Pet @skip(if:$false) { + pet_name: name + } + }} + ''' + def variables = ["true": Boolean.TRUE, "false": Boolean.FALSE] + assertValidQuery(graphQLSchema, query, variables) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.of(variables)) + println String.join("\n", printTree(tree)) + def printedTree = printTree(tree) + + + then: + printedTree == ['Query.pets', + 'cat_yes_1: Cat.name', + 'cat_yes_2: Cat.name', + 'dog_yes_1: Dog.name', + 'dog_yes_2: Dog.name', + 'pet_name: [Cat, Dog].name', + ] + } + + + def "query directives are captured is respected"() { + given: + String schema = """ + directive @fieldDirective(target : String!) on FIELD + directive @fieldXDirective(target : String!) on FIELD + + type Query { + pets: Pet + } + interface Pet { + name: String + } + type Cat implements Pet { + name: String + } + type Dog implements Pet { + name: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + query q { + pets { + ... on Cat { + cName : name @fieldDirective(target : "Cat.name") + } + ... on Dog { + dName : name @fieldDirective(target : "Dog.name") @fieldXDirective(target : "Dog.name") + } + ... on Pet { + pName : name @fieldDirective(target : "Pet.name") + } + }} + ''' + + def variables = [:] + assertValidQuery(graphQLSchema, query, variables) + Document document = TestUtil.parseQuery(query) + + when: + def tree = localCreateExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.of(variables)) + def printedTree = printTreeAndDirectives(tree) + + then: + printedTree == ['Query.pets', + 'cName: Cat.name @fieldDirective(target : "Cat.name")', + 'dName: Dog.name @fieldDirective(target : "Dog.name") @fieldXDirective(target : "Dog.name")', + 'pName: [Cat, Dog].name @fieldDirective(target : "Pet.name")', + ] + } + + def "missing argument"() { + given: + String schema = """ + type Query { + hello(arg: String): String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = '''{hello} ''' + assertValidQuery(graphQLSchema, query) + Document document = TestUtil.parseQuery(query) + when: + def tree = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables(graphQLSchema, document, null, RawVariables.emptyVariables()) + println String.join("\n", printTree(tree)) + def printedTree = printTree(tree) + + + then: + printedTree == ['Query.hello'] + tree.getTopLevelFields().get(0).getNormalizedArguments().isEmpty() + } + + def "reused field via fragments"() { + String schema = """ + type Query { + pet: Pet + } + type Pet { + owner: Person + emergencyContact: Person + } + type Person { + name: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ +{ pet { + owner { ...personName } + emergencyContact { ...personName } +}} +fragment personName on Person { + name +} + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.pet: Pet', + '--Pet.owner: Person', + '---Person.name: String', + '--Pet.emergencyContact: Person', + '---Person.name: String' + ] + + } + + + def "test interface fields with three different output types (covariance) on the implementations"() { + def graphQLSchema = schema(""" + interface Animal { + parent: Animal + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Bird implements Animal { + name: String + parent: Bird + } + type Query { + animal: Animal + } + """) + + def query = """ + { + animal { + parent { + name + } + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == [ + "-Query.animal: Animal", + "--[Bird, Cat, Dog].parent: Bird, Cat, Dog", + "---[Bird, Cat, Dog].name: String", + ] + } + + def "covariants with union fields"() { + def graphQLSchema = schema(""" + type Query { + animal: Animal + } + interface Animal { + parent: DogOrCat + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + union DogOrCat = Dog | Cat + """) + + def query = """ + { + animal { + parent { + __typename + } + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + + def tree = localCreateExecutableNormalizedOperation(graphQLSchema, document, null, CoercedVariables.emptyVariables()) + def printedTree = printTreeWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == [ + "-Query.animal: Animal", + "--[Cat, Dog].parent: Cat, Dog", + "---[Cat, Dog].__typename: String!", + ] + } + + def "query cannot exceed max depth"() { + String schema = """ + type Query { + animal: Animal + } + interface Animal { + name: String + friends: [Animal] + } + type Bird implements Animal { + name: String + friends: [Animal] + } + type Cat implements Animal { + name: String + friends: [Animal] + breed: String + } + type Dog implements Animal { + name: String + breed: String + friends: [Animal] + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + // We generate two less fields than the given depth + // One is due to the top level field + // One is due to the leaf selection + def animalSubselection = IntStream.rangeClosed(1, queryDepth - 2) + .mapToObj { + "" + } + .reduce("CHILD") { acc, value -> + acc.replace("CHILD", "friends { CHILD }") + } + .replace("CHILD", "name") + + // Note: there is a total of 51 fields here + String query = """ + { + animal { + $animalSubselection + } + } + """ + + def limit = 50 + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + Exception exception + try { + ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables(), + ExecutableNormalizedOperationFactory.Options.defaultOptions().maxChildrenDepth(limit)) + } catch (Exception e) { + exception = e + } + + then: + if (queryDepth > limit) { + assert exception != null + assert exception.message.contains("depth exceeded") + assert exception.message.contains("> 50") + } else { + assert exception == null + } + + where: + _ | queryDepth + _ | 49 + _ | 50 + _ | 51 + } + + def "big query is fine as long as depth is under limit"() { + String schema = """ + type Query { + animal: Animal + } + interface Animal { + name: String + friends: [Friend] + } + union Pet = Dog | Cat + type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] + } + type Bird implements Animal { + name: String + friends: [Friend] + } + type Cat implements Animal { + name: String + friends: [Friend] + breed: String + } + type Dog implements Animal { + name: String + breed: String + friends: [Friend] + } + """ + + def garbageFields = IntStream.range(0, 1000) + .mapToObj { + """test_$it: friends { name }""" + } + .collect(Collectors.joining("\n")) + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + animal { + name + otherName: name + ... on Animal { + name + } + ... on Cat { + name + friends { + ... on Friend { + isCatOwner + pets { + ... on Dog { + name + } + } + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Dog { + name + } + $garbageFields + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables(), + ExecutableNormalizedOperationFactory.Options.defaultOptions().maxChildrenDepth(5)) + + then: + noExceptionThrown() + } + + def "big query exceeding fields count"() { + String schema = """ + type Query { + animal: Animal + } + interface Animal { + name: String + friends: [Friend] + } + union Pet = Dog | Cat + type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] + } + type Bird implements Animal { + name: String + friends: [Friend] + } + type Cat implements Animal { + name: String + friends: [Friend] + breed: String + } + type Dog implements Animal { + name: String + breed: String + friends: [Friend] + } + """ + + def garbageFields = IntStream.range(0, 1000) + .mapToObj { + """test_$it: friends { name }""" + } + .collect(Collectors.joining("\n")) + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + animal { + name + otherName: name + ... on Animal { + name + } + ... on Cat { + name + friends { + ... on Friend { + isCatOwner + pets { + ... on Dog { + name + } + } + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Dog { + name + } + $garbageFields + } + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables(), + ExecutableNormalizedOperationFactory.Options.defaultOptions().maxFieldsCount(2013)) + + then: + def e = thrown(AbortExecutionException) + e.message == "Maximum field count exceeded. 2014 > 2013" + } + + def "small query exceeding fields count"() { + String schema = """ + type Query { + hello: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ {hello a1: hello}""" + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables(), + ExecutableNormalizedOperationFactory.Options.defaultOptions().maxFieldsCount(1)) + + then: + def e = thrown(AbortExecutionException) + e.message == "Maximum field count exceeded. 2 > 1" + + + } + + def "query not exceeding fields count"() { + String schema = """ + type Query { + dogs: [Dog] + } + type Dog { + name: String + breed: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ {dogs{name breed }}""" + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables(), + ExecutableNormalizedOperationFactory.Options.defaultOptions().maxFieldsCount(3)) + + then: + notThrown(AbortExecutionException) + + + } + + def "query with meta fields exceeding fields count"() { + String schema = """ + type Query { + hello: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = IntrospectionQuery.INTROSPECTION_QUERY + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables(), + ExecutableNormalizedOperationFactory.Options.defaultOptions().maxFieldsCount(188)) + println result.normalizedFieldToMergedField.size() + + then: + def e = thrown(AbortExecutionException) + e.message == "Maximum field count exceeded. 189 > 188" + } + + def "can capture depth and field count"() { + String schema = """ + type Query { + foo: Foo + } + + type Foo { + stop : String + bar : Bar + } + + type Bar { + stop : String + foo : Foo + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = "{ foo { bar { foo { bar { foo { stop bar { stop }}}}}}}" + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables() + ) + + then: + result.getOperationDepth() == 7 + result.getOperationFieldCount() == 8 + } + + def "factory has a default max node count"() { + String schema = """ + type Query { + foo: Foo + } + type Foo { + foo: Foo + name: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = "{ foo { ...F1}} " + int fragmentCount = 12 + for (int i = 1; i < fragmentCount; i++) { + query += """ + fragment F$i on Foo { + foo { ...F${i + 1} } + a: foo{ ...F${i + 1} } + b: foo{ ...F${i + 1} } + } + """ + } + query += """ + fragment F$fragmentCount on Foo{ + name + } + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables() + ) + then: + def e = thrown(AbortExecutionException) + e.message == "Maximum field count exceeded. 100001 > 100000" + } + + def "default max fields can be changed "() { + String schema = """ + type Query { + foo: Foo + } + type Foo { + foo: Foo + name: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = "{foo{foo{name}}} " + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + ExecutableNormalizedOperationFactory.Options.setDefaultOptions(ExecutableNormalizedOperationFactory.Options.defaultOptions().maxFieldsCount(2)) + + when: + def result = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables() + ) + then: + def e = thrown(AbortExecutionException) + e.message == "Maximum field count exceeded. 3 > 2" + cleanup: + ExecutableNormalizedOperationFactory.Options.setDefaultOptions(ExecutableNormalizedOperationFactory.Options.defaultOptions().maxFieldsCount(ExecutableNormalizedOperationFactory.Options.DEFAULT_MAX_FIELDS_COUNT)) + } + + def "fragments used multiple times and directives on it"() { + String schema = """ + type Query { + foo: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = "{...F1 ...F1 } fragment F1 on Query { foo @include(if: true) } " + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + when: + def operation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables() + ) + def rootField = operation.topLevelFields[0] + def directives = operation.getQueryDirectives(rootField) + def byName = directives.getImmediateDirectivesByName(); + then: + byName.size() == 1 + byName["include"].size() == 1 + byName["include"][0] instanceof GraphQLDirective + } + + def "fragments used multiple times and directives on it deeper"() { + String schema = """ + type Query { + foo: Foo + } + type Foo { + hello: String + } + """ + + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = "{foo{...F1 ...F1 } } fragment F1 on Foo { hello @include(if: true) hello @include(if:true) } " + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + when: + def operation = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + null, + RawVariables.emptyVariables() + ) + def enf = operation.topLevelFields[0].children[0] + def directives = operation.getQueryDirectives(enf) + def byName = directives.getImmediateDirectivesByName(); + then: + byName.size() == 1 + byName["include"].size() == 2 + byName["include"][0] instanceof GraphQLDirective + byName["include"][1] instanceof GraphQLDirective + byName["include"][0] != byName["include"][1] + } + + + private static ExecutableNormalizedOperation localCreateExecutableNormalizedOperation( + GraphQLSchema graphQLSchema, + Document document, + String operationName, + CoercedVariables coercedVariableValues + ) { + + def options = ExecutableNormalizedOperationFactory.Options.defaultOptions().deferSupport(deferSupport) + + return ExecutableNormalizedOperationFactory.createExecutableNormalizedOperation(graphQLSchema, document, operationName, coercedVariableValues, options) + } + + private static ExecutableNormalizedOperation localCreateExecutableNormalizedOperationWithRawVariables( + GraphQLSchema graphQLSchema, + Document document, + String operationName, + RawVariables rawVariables + ) { + + def options = ExecutableNormalizedOperationFactory.Options.defaultOptions().deferSupport(deferSupport) + + return ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables( + graphQLSchema, + document, + operationName, + rawVariables, + options + ) + } +} + +class ExecutableNormalizedOperationFactoryTestWithDeferSupport extends ExecutableNormalizedOperationFactoryTest { + static { + deferSupport = true + } +} + +class ExecutableNormalizedOperationFactoryTestNoDeferSupport extends ExecutableNormalizedOperationFactoryTest { + static { + deferSupport = false + } +} diff --git a/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerDeferTest.groovy b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerDeferTest.groovy new file mode 100644 index 0000000000..13928fd991 --- /dev/null +++ b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerDeferTest.groovy @@ -0,0 +1,525 @@ +package graphql.normalized + + +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.RawVariables +import graphql.language.AstPrinter +import graphql.language.AstSorter +import graphql.language.Document +import graphql.schema.GraphQLSchema +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.TestLiveMockedWiringFactory +import graphql.schema.scalars.JsonScalar +import spock.lang.Specification + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.language.OperationDefinition.Operation.QUERY +import static graphql.normalized.ExecutableNormalizedOperationToAstCompiler.compileToDocumentWithDeferSupport + +class ExecutableNormalizedOperationToAstCompilerDeferTest extends Specification { + VariablePredicate noVariables = new VariablePredicate() { + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, String argName, NormalizedInputValue normalizedInputValue) { + return false + } + } + + String sdl = """ + directive @defer(if: Boolean, label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT + + type Query { + dog: Dog + animal: Animal + } + + interface Animal { + name: String + } + + type Dog implements Animal { + name: String + breed: String + owner: Person + } + + type Cat implements Animal { + name: String + breed: String + color: String + siblings: [Cat] + } + + type Fish implements Animal { + name: String + } + + type Person { + firstname: String + lastname: String + bestFriend: Person + } + """ + + def "simple defer"() { + String query = """ + query q { + dog { + name + ... @defer(label: "breed-defer") { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + dog { + name + ... @defer(label: "breed-defer") { + breed + } + } +} +''' + } + + def "simple defer with named spread"() { + String query = """ + query q { + dog { + name + ... on Dog @defer(label: "breed-defer") { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + dog { + name + ... @defer(label: "breed-defer") { + breed + } + } +} +''' + } + + def "multiple labels on the same field"() { + String query = """ + query q { + dog { + name + ... @defer(label: "breed-defer") { + breed + } + ... @defer(label: "breed-defer-2") { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + dog { + name + ... @defer(label: "breed-defer") { + breed + } + ... @defer(label: "breed-defer-2") { + breed + } + } +} +''' + } + + def "multiple defers without label on the same field"() { + String query = """ + query q { + dog { + name + ... @defer { + breed + } + ... @defer { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + dog { + name + ... @defer { + breed + } + ... @defer { + breed + } + } +} +''' + } + + def "field with and without defer"() { + String query = """ + query q { + dog { + ... @defer { + breed + } + ... { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + dog { + ... @defer { + breed + } + } +} +''' + } + + def "defer on type spread"() { + String query = """ + query q { + animal { + ... on Dog @defer { + breed + } + ... on Dog { + name + } + ... on Dog @defer(label: "owner-defer") { + owner { + firstname + } + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + ... on Dog @defer { + breed + } + ... on Dog { + name + } + ... on Dog @defer(label: "owner-defer") { + owner { + firstname + } + } + } +} +''' + } + + def "2 fragments on non-conditional fields"() { + String query = """ + query q { + animal { + ... on Cat @defer { + name + } + ... on Animal @defer { + name + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + ... @defer { + name + } + ... @defer { + name + } + } +} +''' + } + + def "2 fragments on conditional fields"() { + String query = """ + query q { + animal { + ... on Cat @defer { + breed + } + ... on Dog @defer { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + ... on Cat @defer { + breed + } + ... on Dog @defer { + breed + } + } +} +''' + } + + def "2 fragments on conditional fields with different labels"() { + String query = """ + query q { + animal { + ... on Cat @defer(label: "cat-defer") { + breed + } + ... on Dog @defer(label: "dog-defer") { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + ... on Cat @defer(label: "cat-defer") { + breed + } + ... on Dog @defer(label: "dog-defer") { + breed + } + } +} +''' + } + + def "fragments on conditional fields with different labels and repeating types"() { + String query = """ + query q { + animal { + ... on Cat @defer(label: "cat-defer-1") { + breed + } + ... on Cat @defer(label: "cat-defer-2") { + breed + } + ... on Dog @defer(label: "dog-defer") { + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + ... on Cat @defer(label: "cat-defer-1") { + breed + } + ... on Cat @defer(label: "cat-defer-2") { + breed + } + ... on Dog @defer(label: "dog-defer") { + breed + } + } +} +''' + } + + def "nested defer"() { + String query = """ + query q { + animal { + ... on Cat @defer { + name + } + ... on Animal @defer { + name + ... on Dog @defer { + owner { + firstname + ... @defer { + lastname + } + ... @defer { + bestFriend { + firstname + ... @defer { + lastname + } + } + } + } + } + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + ... @defer { + name + } + ... @defer { + name + } + ... on Dog @defer { + owner { + firstname + ... @defer { + lastname + } + ... @defer { + bestFriend { + firstname + ... @defer { + lastname + } + } + } + } + } + } +} +''' + } + + def "multiple defers at the same level are preserved"() { + String query = """ + query q { + dog { + ... @defer { + name + } + ... @defer { + breed + } + ... @defer { + owner { + firstname + } + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def tree = createNormalizedTree(schema, query) + when: + def result = compileToDocumentWithDeferSupport(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + dog { + ... @defer { + name + } + ... @defer { + breed + } + ... @defer { + owner { + firstname + } + } + } +} +''' + } + + private ExecutableNormalizedOperation createNormalizedTree(GraphQLSchema schema, String query, Map variables = [:]) { + assertValidQuery(schema, query, variables) + Document originalDocument = TestUtil.parseQuery(query) + + ExecutableNormalizedOperationFactory dependencyGraph = new ExecutableNormalizedOperationFactory() + def options = ExecutableNormalizedOperationFactory.Options.defaultOptions().deferSupport(true) + return dependencyGraph.createExecutableNormalizedOperationWithRawVariables( + schema, + originalDocument, + null, + RawVariables.of(variables), + options + ) + } + + private void assertValidQuery(GraphQLSchema graphQLSchema, String query, Map variables = [:]) { + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + assert graphQL.execute(newExecutionInput().query(query).variables(variables)).errors.isEmpty() + } + + GraphQLSchema mkSchema(String sdl) { + def wiringFactory = new TestLiveMockedWiringFactory([JsonScalar.JSON_SCALAR]) + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(wiringFactory).build() + TestUtil.schema(sdl, runtimeWiring) + } +} diff --git a/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerDirectivesTest.groovy b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerDirectivesTest.groovy new file mode 100644 index 0000000000..b7928b4aed --- /dev/null +++ b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerDirectivesTest.groovy @@ -0,0 +1,194 @@ +package graphql.normalized + +import graphql.schema.GraphQLSchema + +import static graphql.language.OperationDefinition.Operation.QUERY + +/** + * Test related to ENO and directives + */ +class ExecutableNormalizedOperationToAstCompilerDirectivesTest extends ENOToAstCompilerTestBase { + def bookSDL = ''' + directive @timeout(afterMillis : Int) on FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | QUERY + + directive @cached(forMillis : Int) on FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | QUERY + + directive @importance(place : String) on FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT | QUERY + + type Query { + books(searchString : String) : [Book] + } + + type Book { + id : ID + title : String + review : String + } + ''' + + def "can extract variables or inline values for directives on the query"() { + def sdl = ''' + type Query { + foo(fooArg : String) : Foo + } + + type Foo { + bar(barArg : String) : String + } + + directive @optIn(to : [String!]!) repeatable on FIELD + ''' + + def query = ''' + query named($fooArgVar : String, $barArgVar : String, $skipVar : Boolean!, $optVar : [String!]!) { + foo(fooArg : $fooArgVar) @skip(if : $skipVar) { + bar(barArg : $barArgVar) @optIn(to : ["optToX"]) @optIn(to : $optVar) + } + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def eno = createNormalizedTree(schema, query, + [fooArgVar: "fooArgVar", barArgVar: "barArgVar", skipVar: false, optVar: ["optToY"]]) + + when: + def result = localCompileToDocument(schema, QUERY, "named", + eno.getTopLevelFields(), eno.getNormalizedFieldToQueryDirectives(), + allVariables) + def document = result.document + def vars = result.variables + def ast = printDoc(document) + + then: + vars == [v0: "barArgVar", v1: ["optToX"], v2: ["optToY"], v3: "fooArgVar", v4: false] + // + // the below is what ir currently produces but its WRONG + // fix up when the other tests starts to work + // + ast == '''query named($v0: String, $v1: [String!]!, $v2: [String!]!, $v3: String, $v4: Boolean!) { + foo(fooArg: $v3) @skip(if: $v4) { + bar(barArg: $v0) @optIn(to: $v1) @optIn(to: $v2) + } +} +''' + + + when: "it has no variables" + + + result = localCompileToDocument(schema, QUERY, "named", + eno.getTopLevelFields(), eno.getNormalizedFieldToQueryDirectives(), + noVariables) + document = result.document + vars = result.variables + ast = printDoc(document) + + then: + vars == [:] + ast == '''query named { + foo(fooArg: "fooArgVar") @skip(if: false) { + bar(barArg: "barArgVar") @optIn(to: ["optToX"]) @optIn(to: ["optToY"]) + } +} +''' + + } + + def "can handle quite a pathological fragment query as expected"() { + + def pathologicalQuery = ''' + fragment Details on Book @timeout(afterMillis: 25) @cached(forMillis : 25) @importance(place:"FragDef") { + title + review @timeout(afterMillis: 5) @cached(forMillis : 5) + ...InnerDetails @timeout(afterMillis: 26) + } + + fragment InnerDetails on Book @timeout(afterMillis: 27) { + review @timeout(afterMillis: 28) + } + + query Books @timeout(afterMillis: 30) @importance(place:"Operation") { + books(searchString: "monkey") { + id + ...Details @timeout(afterMillis: 20) + ...on Book @timeout(afterMillis: 15) { + review @timeout(afterMillis: 10) @cached(forMillis : 10) + } + } + } + ''' + + GraphQLSchema schema = mkSchema(bookSDL) + def eno = createNormalizedTree(schema, pathologicalQuery, [:]) + + when: + def result = localCompileToDocument(schema, QUERY, "Books", + eno.getTopLevelFields(), eno.getNormalizedFieldToQueryDirectives(), + allVariables) + def document = result.document + def vars = result.variables + def ast = printDoc(document) + + then: + vars == [v0:5, v1:5, v2:28, v3:10, v4:10, v5:"monkey"] + ast == '''query Books($v0: Int, $v1: Int, $v2: Int, $v3: Int, $v4: Int, $v5: String) { + books(searchString: $v5) { + id + review @cached(forMillis: $v1) @cached(forMillis: $v4) @timeout(afterMillis: $v0) @timeout(afterMillis: $v2) @timeout(afterMillis: $v3) + title + } +} +''' + + + when: "it has no variables" + + + result = localCompileToDocument(schema, QUERY, "Books", + eno.getTopLevelFields(), eno.getNormalizedFieldToQueryDirectives(), + noVariables) + document = result.document + vars = result.variables + ast = printDoc(document) + + then: + vars == [:] + ast == '''query Books { + books(searchString: "monkey") { + id + review @cached(forMillis: 5) @cached(forMillis: 10) @timeout(afterMillis: 5) @timeout(afterMillis: 28) @timeout(afterMillis: 10) + title + } +} +''' + + } + + def "merged fields with the same field will capture all directives"() { + def query = ''' + query Books { + books(searchString: "monkey") { + review @timeout(afterMillis: 10) @cached(forMillis : 10) + review @timeout(afterMillis: 100) @cached(forMillis : 100) + } + } + ''' + + GraphQLSchema schema = mkSchema(bookSDL) + def eno = createNormalizedTree(schema, query, [:]) + + when: + def result = localCompileToDocument(schema, QUERY, "Books", + eno.getTopLevelFields(), eno.getNormalizedFieldToQueryDirectives(), + noVariables) + def document = result.document + def ast = printDoc(document) + + then: + ast == '''query Books { + books(searchString: "monkey") { + review @cached(forMillis: 10) @cached(forMillis: 100) @timeout(afterMillis: 10) @timeout(afterMillis: 100) + } +} +''' + } +} diff --git a/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerTest.groovy b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerTest.groovy new file mode 100644 index 0000000000..8f4a0851ac --- /dev/null +++ b/src/test/groovy/graphql/normalized/ExecutableNormalizedOperationToAstCompilerTest.groovy @@ -0,0 +1,2288 @@ +package graphql.normalized + +import graphql.GraphQL +import graphql.TestUtil +import graphql.execution.RawVariables +import graphql.execution.directives.QueryAppliedDirective +import graphql.execution.directives.QueryDirectives +import graphql.language.AstPrinter +import graphql.language.AstSorter +import graphql.language.Document +import graphql.language.Field +import graphql.language.IntValue +import graphql.language.OperationDefinition +import graphql.language.StringValue +import graphql.parser.Parser +import graphql.schema.GraphQLSchema +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.TestLiveMockedWiringFactory +import graphql.schema.scalars.JsonScalar +import spock.lang.Specification + +import static graphql.ExecutionInput.newExecutionInput +import static graphql.language.OperationDefinition.Operation.MUTATION +import static graphql.language.OperationDefinition.Operation.QUERY +import static graphql.language.OperationDefinition.Operation.SUBSCRIPTION +import static graphql.normalized.ExecutableNormalizedOperationToAstCompiler.compileToDocument +import static graphql.normalized.ExecutableNormalizedOperationToAstCompiler.compileToDocumentWithDeferSupport + +abstract class ENOToAstCompilerTestBase extends Specification { + static boolean deferSupport + + VariablePredicate noVariables = new VariablePredicate() { + + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, QueryAppliedDirective queryAppliedDirective, String argName, NormalizedInputValue normalizedInputValue) { + return false + } + + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, String argName, NormalizedInputValue normalizedInputValue) { + return false + } + } + + VariablePredicate jsonVariables = new VariablePredicate() { + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, String argName, NormalizedInputValue normalizedInputValue) { + "JSON" == normalizedInputValue.unwrappedTypeName && normalizedInputValue.value != null + } + + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, QueryAppliedDirective queryAppliedDirective, String argName, NormalizedInputValue normalizedInputValue) { + "JSON" == normalizedInputValue.unwrappedTypeName && normalizedInputValue.value != null + } + } + + VariablePredicate allVariables = new VariablePredicate() { + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, String argName, NormalizedInputValue normalizedInputValue) { + return true + } + + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, QueryAppliedDirective queryAppliedDirective, String argName, NormalizedInputValue normalizedInputValue) { + return true + } + } + + + static ExecutableNormalizedOperation createNormalizedTree(GraphQLSchema schema, String query, Map variables = [:]) { + assertValidQuery(schema, query, variables) + Document originalDocument = TestUtil.parseQuery(query) + + def options = ExecutableNormalizedOperationFactory.Options.defaultOptions().deferSupport(deferSupport) + return ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables(schema, originalDocument, null, RawVariables.of(variables), options) + } + + static List createNormalizedFields(GraphQLSchema schema, String query, Map variables = [:]) { + return createNormalizedTree(schema, query, variables).getTopLevelFields() + } + + static void assertValidQuery(GraphQLSchema graphQLSchema, String query, Map variables = [:]) { + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + assert graphQL.execute(newExecutionInput().query(query).variables(variables)).errors.isEmpty() + } + + static GraphQLSchema mkSchema(String sdl) { + def wiringFactory = new TestLiveMockedWiringFactory([JsonScalar.JSON_SCALAR]) + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(wiringFactory).build() + TestUtil.schema(sdl, runtimeWiring) + } + + static ExecutableNormalizedOperationToAstCompiler.CompilerResult localCompileToDocument( + GraphQLSchema schema, + OperationDefinition.Operation operationKind, + String operationName, + List topLevelFields, + VariablePredicate variablePredicate + ) { + return localCompileToDocument(schema, operationKind, operationName, topLevelFields, Map.of(), variablePredicate); + } + + static ExecutableNormalizedOperationToAstCompiler.CompilerResult localCompileToDocument( + GraphQLSchema schema, + OperationDefinition.Operation operationKind, + String operationName, + List topLevelFields, + Map normalizedFieldToQueryDirectives, + VariablePredicate variablePredicate + ) { + if (deferSupport) { + return compileToDocumentWithDeferSupport(schema, operationKind, operationName, topLevelFields, normalizedFieldToQueryDirectives, variablePredicate) + } + return compileToDocument(schema, operationKind, operationName, topLevelFields, normalizedFieldToQueryDirectives, variablePredicate) + } + + static Document sortDoc(Document doc) { + return new AstSorter().sort(doc) + } + + static printDoc(Document doc) { + return AstPrinter.printAst(sortDoc(doc)) + } +} + +/** + * Test code in here - helps in the base class + */ +abstract class ExecutableNormalizedOperationToAstCompilerTest extends ENOToAstCompilerTestBase { + + def "test pet interfaces"() { + String sdl = """ + type Query { + animal: Animal + } + interface Animal { + name: String + friends: [Friend] + } + + union Pet = Dog | Cat + + type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] + } + + type Bird implements Animal { + name: String + friends: [Friend] + } + + type Cat implements Animal { + name: String + friends: [Friend] + breed: String + mood: String + } + + type Dog implements Animal { + name: String + breed: String + friends: [Friend] + } + """ + + String query = """ + { + animal { + name + otherName: name + ... on Animal { + name + } + ... on Cat { + name + mood + friends { + ... on Friend { + isCatOwner + pets { + ... on Dog { + name + } + } + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Dog { + name + breed + } + } + } + """ + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def printed = printDoc(result.document) + then: + printed == '''{ + animal { + name + otherName: name + ... on Bird { + friends { + isBirdOwner + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Cat { + friends { + isCatOwner + pets { + ... on Dog { + name + } + } + } + mood + } + ... on Dog { + breed + } + } +} +''' + } + + def "test interface fields with different output types on the implementations"() { + def schema = TestUtil.schema(""" + interface Animal { + parent: Animal + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + parent { + name + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + parent { + name + } + } +} +""" + } + + def "test interface fields with different output types on the implementations 2"() { + def schema = TestUtil.schema(""" + interface Animal { + parent: Animal + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + parent { + name + ... on Dog { + isGoodBoy + } + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + parent { + name + ... on Dog { + isGoodBoy + } + } + } +} +""" + } + + def "test interface fields with different output types on the implementations 3"() { + // Tests we don't consider File as a possible option for parent on animals + def schema = TestUtil.schema(""" + interface Node { + parent: Node + } + type File implements Node { + name: ID + parent: File + } + interface Animal implements Node { + parent: Animal + name: String + } + type Cat implements Animal & Node { + name: String + parent: Cat + } + type Dog implements Animal & Node { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + file: File + } + """) + + String query = """ + { + animal { + parent { + name + ... on Dog { + isGoodBoy + } + ... on Node { + parent { + ... on Cat { + name + } + ... on Dog { + name + } + } + } + } + } + file { + name + ... on File { + parent { + name + } + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + parent { + name + parent { + name + } + ... on Dog { + isGoodBoy + } + } + } + file { + name + parent { + name + } + } +} +""" + } + + def "test interface fields with different output types on the implementations 4"() { + // Tests we don't consider File as a possible option for parent on animals + def schema = TestUtil.schema(""" + interface Node { + parent: Node + } + type File implements Node { + name: String + parent: File + } + interface Animal implements Node { + parent: Animal + name: String + } + type Cat implements Animal & Node { + name: String + parent: Cat + } + type Dog implements Animal & Node { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + file: File + } + """) + + String query = """ + { + animal { + parent { + name + ... on Dog { + isGoodBoy + } + ...F1 + } + } + file { + name + ... on File { + ...F1 + parent { + name + } + } + } + } + fragment F1 on Node { + parent { + ... on Cat { + name + } + ... on Dog { + name + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + parent { + name + parent { + name + } + ... on Dog { + isGoodBoy + } + } + } + file { + name + parent { + name + } + } +} +""" + } + + def "test named fragments on interface fields with different output types on implementations"() { + // Tests we don't consider File as a possible option for parent on animals + def schema = TestUtil.schema(""" + interface Node { + parent: Node + } + type File implements Node { + name: String + parent: File + } + interface Animal implements Node { + parent: Animal + name: String + } + type Cat implements Animal & Node { + name: String + parent: Cat + } + type Dog implements Animal & Node { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + file: File + } + """) + + String query = """ + { + animal { + parent { + name + ... on Dog { + isGoodBoy + } + ... on Node { + ...ParentName + } + } + } + file { + name + ... on File { + ...ParentName + } + } + } + + fragment ParentName on Node { + parent { + ... on Cat { + name + } + ... on Animal { + animal: name + } + ... on File { + name + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + parent { + name + parent { + animal: name + ... on Cat { + name + } + } + ... on Dog { + isGoodBoy + } + } + } + file { + name + parent { + name + } + } +} +""" + } + + def "test unions always insert fragments for its subselections"() { + def schema = TestUtil.schema(""" + union Animal = Cat | Dog + type Cat { + name: String + parent: Cat + } + type Dog { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + ... on Cat { + __typename + name + } + ... on Dog { + name + } + ... on Dog { + isGoodBoy + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + ... on Cat { + __typename + name + } + ... on Dog { + isGoodBoy + name + } + } +} +""" + } + + def "test typename in union when placed outside of fragments"() { + def schema = TestUtil.schema(""" + union Animal = Cat | Dog + type Cat { + name: String + parent: Cat + } + type Dog { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + __typename + ... on Cat { + name + } + ... on Dog { + name + } + ... on Dog { + isGoodBoy + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + printed == """{ + animal { + __typename + ... on Cat { + name + } + ... on Dog { + isGoodBoy + name + } + } +} +""" + } + + def "test typename in union when placed inside fragments but on all types conditions"() { + def schema = TestUtil.schema(""" + union Animal = Cat | Dog + type Cat { + name: String + parent: Cat + } + type Dog { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + ... on Cat { + __typename + name + } + ... on Dog { + __typename + name + } + ... on Dog { + isGoodBoy + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + // Perhaps the typename should be hoisted out of the fragments, but the impl currently generates + // -Query.animal: Animal + // --Cat.__typename: String! + // --Dog.__typename: String! + // --Cat.name: String + // --Dog.name: String + // --Dog.isGoodBoy: Boolean + printed == """{ + animal { + __typename + ... on Cat { + name + } + ... on Dog { + isGoodBoy + name + } + } +} +""" + } + + def "test print field for isGoodBoy when parent is changed to type Dog"() { + def schema = TestUtil.schema(""" + interface Animal { + parent: Animal + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + ... on Dog { + parent { + isGoodBoy + } + } + ... on Animal { + parent { + name + } + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + // Note: the name field is spread across both fragments + printed == """{ + animal { + ... on Cat { + parent { + name + } + } + ... on Dog { + parent { + isGoodBoy + name + } + } + } +} +""" + } + + def "test non conditional fields from interfaces are not surrounded by fragments"() { + def schema = TestUtil.schema(""" + interface Animal { + parent: Animal + name: String + age: Int + location: String + } + type Cat implements Animal { + name: String + parent: Cat + age: Int + location: String + } + type Possum implements Animal { + name: String + parent: Animal + age: Int + location: String + } + type Rodent implements Animal { + name: String + parent: Animal + age: Int + location: String + } + type Deer implements Animal { + name: String + parent: Animal + age: Int + location: String + } + type Dog implements Animal { + name: String + parent: Dog + age: Int + location: String + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """) + + String query = """ + { + animal { + __typename + name + age + location + parent { + name + location + ... on Dog { + __typename + age + isGoodBoy + } + grandparent: parent { + name + age + ... on Cat { + catAge: age + } + } + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + // Ensure that age location name etc are not surrounded by fragments unnecessarily + printed == """{ + animal { + __typename + age + location + name + parent { + location + name + grandparent: parent { + age + name + ... on Cat { + catAge: age + } + } + ... on Dog { + __typename + age + isGoodBoy + } + } + } +} +""" + } + + def "test non conditional fields from interfaces are not surrounded by fragments 2"() { + def schema = TestUtil.schema(""" + type Issue { + fields: IssueField + } + interface IssueField { + id: ID! + fieldId: Int + fieldName: String + label: String! + } + type DateIssueField implements IssueField { + id: ID! + fieldId: Int + fieldName: String + label: String! + date: String + } + type OptionsIssueField implements IssueField { + id: ID! + fieldId: Int + fieldName: String + label: String! + } + type SpecialIssueField implements IssueField { + id: ID! + fieldId: Int + fieldName: String + label: String! + specialType: String + } + type Query { + issue: Issue + } + """) + + // This query also includes unnecessary fragments for fields that are already defined without fragments + String query = """ + { + issue { + fields { + __typename + id + fieldId + fieldName + label + ... on IssueField { + fieldId + } + ... on DateIssueField { + date + } + ... on SpecialIssueField { + id + fieldId + specialType + } + } + } + } + """ + + def tree = createNormalizedTree(schema, query) + // printTreeWithLevelInfo(tree, schema).forEach { println it } + + when: + def result = localCompileToDocument(schema, QUERY, null, tree.topLevelFields, noVariables) + def printed = printDoc(result.document) + + then: + // Ensure that __typename id fieldId fieldName etc. are not surrounded by fragments unnecessarily + printed == """{ + issue { + fields { + __typename + fieldId + fieldName + id + label + ... on DateIssueField { + date + } + ... on SpecialIssueField { + specialType + } + } + } +} +""" + } + + def "test a combination of plain objects and interfaces"() { + def sdl = ''' + type Query { + foo(arg: I): Foo + } + type Foo { + bar(arg: I): Bar + } + type Bar { + baz : Baz + } + interface Baz { + boo : String + } + type ABaz implements Baz { + boo : String + a : String + } + type BBaz implements Baz { + boo : String + b : String + } + input I { + arg1: String + } + ''' + def query = '''query { + foo(arg: {arg1 : "fooArg"}) { + bar(arg: {arg1 : "barArg"}) { + baz { + ... on ABaz { + boo + a + } + } + } + } +} + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''{ + foo(arg: {arg1 : "fooArg"}) { + bar(arg: {arg1 : "barArg"}) { + baz { + ... on ABaz { + a + boo + } + } + } + } +} +''' + } + + def "test arguments"() { + def sdl = ''' + type Query { + foo1(arg: String): String + foo2(a: Int, b: Boolean, c: Float): String + } + ''' + def query = ''' { + foo1(arg: "hello") + foo2(a: 123, b: true, c: 123.45) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''{ + foo1(arg: "hello") + foo2(a: 123, b: true, c: 123.45) +} +''' + } + + def "sets operation name"() { + def sdl = ''' + type Query { + foo1(arg: String): String + foo2(a: Int,b: Boolean, c: Float): String + } + ''' + def query = ''' { + foo1(arg: "hello") + foo2(a: 123, b: true, c: 123.45) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, "My_Op23", fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''query My_Op23 { + foo1(arg: "hello") + foo2(a: 123, b: true, c: 123.45) +} +''' + } + + def "test input object arguments"() { + def sdl = ''' + type Query { + foo1(arg: I): String + } + input I { + arg1: String + arg2: Int + arg3: ID + arg4: Boolean + arg5: Float + nested: I + } + ''' + def query = '''{ + foo1(arg: { + arg1: "Hello" + arg2: 123 + arg3: "IDID" + arg4: false + arg5: 123.123 + nested: { + arg1: "Hello2" + arg2: 1234 + arg3: "IDID1" + arg4: null + arg5: null + } + }) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''{ + foo1(arg: {arg1 : "Hello", arg2 : 123, arg3 : "IDID", arg4 : false, arg5 : 123.123, nested : {arg1 : "Hello2", arg2 : 1234, arg3 : "IDID1", arg4 : null, arg5 : null}}) +} +''' + } + + + def "test input object arguments 2"() { + def sdl = ''' + type Query { + foo1(arg: Outer): String + } + input Outer { + a : Inner + } + input Inner { + b : InnerInner + } + input InnerInner { + c : Int + d : String + } + ''' + def query = '''query something($v : Int){ + foo1(arg: { a : { b : { c :$v, d :"ast" }}}) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query, ["v": 123]) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, allVariables) + def documentPrinted = printDoc(result.document) + + then: + fields[0].normalizedArguments["arg"].value["a"].value["b"].value["c"].value.isEqualTo(IntValue.of(123)) + fields[0].normalizedArguments["arg"].value["a"].value["b"].value["d"].value.isEqualTo(StringValue.of("ast")) + documentPrinted.trim() == '''query ($v0: Outer) { + foo1(arg: $v0) +}''' + } + + def "test mutations"() { + def sdl = ''' + type Query { + foo1(arg: I): String + } + type Mutation { + foo1(arg: I): String + } + input I { + arg1: String + } + ''' + def query = '''mutation { + foo1(arg: { + arg1: "Mutation" + }) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''mutation { + foo1(arg: {arg1 : "Mutation"}) +} +''' + } + + def "test subscriptions"() { + def sdl = ''' + type Query { + foo1(arg: I): String + } + type Subscription { + foo1(arg: I): String + } + input I { + arg1: String + } + ''' + def query = '''subscription { + foo1(arg: { + arg1: "Subscription" + }) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, SUBSCRIPTION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''subscription { + foo1(arg: {arg1 : "Subscription"}) +} +''' + } + + + def "test query directive"() { + def sdl = ''' + type Query { + foo1(arg: I): String + + } + type Subscription { + foo1(arg: I): DevOps + + } + input I { + arg1: String + } + + type DevOps{ + name: String + } + + directive @optIn(to : [String!]!) repeatable on FIELD + ''' + def query = '''subscription { + foo1 (arg: { + arg1: "Subscription" + }) @optIn(to: "foo") { + name @optIn(to: "devOps") + } + + + } + ''' + GraphQLSchema schema = mkSchema(sdl) + Document document = new Parser().parse(query) + ExecutableNormalizedOperation eno = ExecutableNormalizedOperationFactory.createExecutableNormalizedOperationWithRawVariables(schema, document, null, RawVariables.emptyVariables()) + + + when: + def result = localCompileToDocument(schema, SUBSCRIPTION, null, eno.topLevelFields, eno.normalizedFieldToQueryDirectives, noVariables) + OperationDefinition operationDefinition = result.document.getDefinitionsOfType(OperationDefinition.class)[0] + def fooField = (Field) operationDefinition.selectionSet.children[0] + def nameField = (Field) fooField.selectionSet.children[0] + def documentPrinted = printDoc(result.document) + + then: + + fooField.directives.size() == 1 + nameField.directives.size() == 1 + documentPrinted == '''subscription { + foo1(arg: {arg1 : "Subscription"}) @optIn(to: ["foo"]) { + name @optIn(to: ["devOps"]) + } +} +''' + } + + def "test redundant inline fragments specified in original query"() { + def sdl = ''' + type Query { + foo1(arg: I): Foo + } + type Mutation { + foo1(arg: I): Foo + } + type Foo { + test: String + } + input I { + arg1: String + } + ''' + def query = '''mutation { + ... on Mutation { + foo1(arg: { + arg1: "Mutation" + }) { + ... on Foo { + test + } + } + } + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + documentPrinted == '''mutation { + foo1(arg: {arg1 : "Mutation"}) { + test + } +} +''' + } + + def "inserts inline fragment on interface types"() { + def sdl = ''' + type Query { + foo1(arg: I): Foo + } + type Mutation { + foo1(arg: I): Foo + } + interface Foo { + test: String + } + type AFoo implements Foo { + test: String + } + input I { + arg1: String + } + ''' + def query = '''query { + ... on Query { + foo1(arg: { + arg1: "Query" + }) { + ... on Foo { + test + } + } + } + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + documentPrinted == '''{ + foo1(arg: {arg1 : "Query"}) { + test + } +} +''' + } + + def "introspection query can be printed __schema"() { + def sdl = ''' + type Query { + f: String + } + ''' + def query = ''' + query introspection_query { + __schema { + queryType { + fields(includeDeprecated: false) { + name + } + } + } + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + documentPrinted == '''{ + __schema { + queryType { + fields(includeDeprecated: false) { + name + } + } + } +} +''' + } + + def "introspection query can be printed __type"() { + def sdl = ''' + type Query { + f: String + } + ''' + def query = ''' + query introspection_query { + __type(name: "World") { + name + fields { + name + } + } + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + documentPrinted == '''{ + __type(name: "World") { + fields { + name + } + name + } +} +''' + } + + def "test is conditional when there is only one interface implementation"() { + def sdl = ''' + type Query { + foo1: Foo + } + interface Foo { + test: String + } + type AFoo implements Foo { + test: String + aFoo: String + } + ''' + def query = '''query { + ... on Query { + foo1 { + ... on Foo { + test + } + ... on AFoo { + aFoo + } + } + } + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + documentPrinted == '''{ + foo1 { + test + ... on AFoo { + aFoo + } + } +} +''' + } + + def "test is conditional when there is only one union implementation"() { + def sdl = ''' + type Query { + foo1: Foo + } + union Foo = AFoo + type AFoo { + test: String + aFoo: String + } + ''' + def query = '''{ + ... on Query { + foo1 { + ... on AFoo { + aFoo + } + } + } + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + documentPrinted == '''{ + foo1 { + ... on AFoo { + aFoo + } + } +} +''' + } + + def "handles concrete and abstract fields"() { + def sdl = ''' + type Query { + foo1(arg: I): Foo + } + type Mutation { + foo1(arg: I): Foo + } + interface Foo { + test: String + } + type AFoo implements Foo { + test: String + afoo: String + } + input I { + arg1: String + } + ''' + def query = '''query { + ... on Query { + foo1(arg: { + arg1: "Query" + }) { + test + ... on AFoo { + afoo + } + ... on AFoo { + __typename + } + } + } + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + // Note: the typename field moves out of a fragment because AFoo is the only impl + documentPrinted == '''{ + foo1(arg: {arg1 : "Query"}) { + __typename + test + ... on AFoo { + afoo + } + } +} +''' + } + + def "handles typename outside fragment and inside fragment"() { + def sdl = ''' + type Query { + foo1(arg: I): Foo + } + type Mutation { + foo1(arg: I): Foo + } + interface Foo { + test: String + } + type AFoo implements Foo { + test: String + } + input I { + arg1: String + } + ''' + def query = '''query { + ... on Query { + foo1(arg: { + arg1: "Query" + }) { + __typename + test + ... on AFoo { + __typename + } + } + } + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + // Note: the typename field moves out of a fragment because AFoo is the only impl + documentPrinted == '''{ + foo1(arg: {arg1 : "Query"}) { + __typename + test + } +} +''' + } + + def "handles typename inside fragment"() { + def sdl = ''' + type Query { + foo1(arg: I): Foo + } + type Mutation { + foo1(arg: I): Foo + } + interface Foo { + test: String + } + type AFoo implements Foo { + test: String + } + type BFoo implements Foo { + test: String + } + input I { + arg1: String + } + ''' + def query = '''{ + ... on Query { + foo1(arg: { + arg1: "Query" + }) { + test + ... on AFoo { + __typename + } + } + } + } + ''' + GraphQLSchema schema = TestUtil.schema(sdl) + def fields = createNormalizedFields(schema, query) + when: + def result = localCompileToDocument(schema, QUERY, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + then: + // Note: the typename field moves out of a fragment because AFoo is the only impl + documentPrinted == '''{ + foo1(arg: {arg1 : "Query"}) { + test + ... on AFoo { + __typename + } + } +} +''' + } + + def "test JSON when input is a variable"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: JSON!): String + } + + scalar JSON + ''' + def query = '''mutation hello($var: JSON!) { + foo1(arg: $var) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + + def vars = [var: ["48x48": "hello"]] + def fields = createNormalizedFields(schema, query, vars) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [v0: ["48x48": "hello"]] + documentPrinted == '''mutation ($v0: JSON!) { + foo1(arg: $v0) +} +''' + } + + def "test JSON when input is a string variable"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: JSON!): String + } + + scalar JSON + ''' + def query = '''mutation hello($var: JSON!) { + foo1(arg: $var) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + + def vars = [var: "hello there"] + def fields = createNormalizedFields(schema, query, vars) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [v0: "hello there"] + documentPrinted == '''mutation ($v0: JSON!) { + foo1(arg: $v0) +} +''' + } + + def "test JSON when input is an int variable"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: JSON!): String + } + + scalar JSON + ''' + def query = '''mutation hello($var: JSON!) { + foo1(arg: $var) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + + def vars = [var: 1] + def fields = createNormalizedFields(schema, query, vars) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [v0: 1] + documentPrinted == '''mutation ($v0: JSON!) { + foo1(arg: $v0) +} +''' + } + + def "test JSON scalar when JSON arg is null"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: JSON): String + } + + scalar JSON + ''' + def query = '''mutation { + foo1 + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [:] + documentPrinted == '''mutation { + foo1 +} +''' + } + + def "test JSON scalar when JSON arg is explicitly null"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: JSON): String + } + + scalar JSON + ''' + def query = '''mutation { + foo1(arg: null) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [:] + documentPrinted == '''mutation { + foo1(arg: null) +} +''' + } + + def "test JSON scalar when input is inlined"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: JSON!): String + } + + scalar JSON + ''' + def query = '''mutation { + foo1(arg: {one: "two", three: ["four", "five"]}) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [v0: [one: "two", three: ["four", "five"]]] + documentPrinted == '''mutation ($v0: JSON!) { + foo1(arg: $v0) +} +''' + } + + def "test JSON scalar when input is inlined, multiple JSON args"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg1: JSON!, arg2: [JSON!]): String + } + + scalar JSON + ''' + def query = '''mutation { + foo1(arg1: {one: "two", three: ["four", "five"]}, arg2: [{one: "two", three: ["four", "five"]}]) + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables.size() == 2 + result.variables['v0'] == [one: "two", three: ["four", "five"]] + result.variables['v1'] == [[one: "two", three: ["four", "five"]]] + documentPrinted == '''mutation ($v0: JSON!, $v1: [JSON!]) { + foo1(arg1: $v0, arg2: $v1) +} +''' + } + + def "test JSON scalar inside an input type"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: InputWithJson): String + } + + input InputWithJson { + id: ID + json: JSON + } + scalar JSON + ''' + def query = '''mutation { + foo1(arg: {id: "ID-00", json: {name: "Zlatan", lastName: "Ibrahimoviç", clubs: ["MU", "Barsa", "Inter", "Milan"]}}) + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + def vars = result.variables + + then: + vars.size() == 1 + vars['v0'] == [lastName: "Ibrahimoviç", name: "Zlatan", clubs: ["MU", "Barsa", "Inter", "Milan"]] + documentPrinted == '''mutation ($v0: JSON) { + foo1(arg: {id : "ID-00", json : $v0}) +} +''' + } + + def "test JSON scalar inside an input type, json value is explicitly null"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: InputWithJson): String + } + + input InputWithJson { + id: ID + json: JSON + } + scalar JSON + ''' + def query = '''mutation { + foo1(arg: {id: "ID-00", json: null}) + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [:] + documentPrinted == '''mutation { + foo1(arg: {id : "ID-00", json : null}) +} +''' + } + + def "test JSON scalar inside an input type, json value is null"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: InputWithJson): String + } + + input InputWithJson { + id: ID + json: JSON + } + scalar JSON + ''' + def query = '''mutation { + foo1(arg: {id: "ID-00"}) + } + ''' + + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, noVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables == [:] + documentPrinted == '''mutation { + foo1(arg: {id : "ID-00"}) +} +''' + } + + def "test JSON scalar inside an input type, json key is illegal graphql input name"() { + def sdl = ''' + type Query { + foo: String + } + type Mutation { + foo1(arg: InputWithJson): String + } + + input InputWithJson { + id: ID + json: [JSON!] + } + scalar JSON + ''' + def query = '''mutation test($var: InputWithJson) { + foo1(arg: $var) + } + ''' + def variables = [var: [ + id : "ID-00", + json: [[name : "Zlatan", + lastName: "Ibrahimoviç", + clubs : ["MU", "Barsa", "Inter", "Milan", null], + "48x48" : "Zlatan_48x48.jpg", + "96x96" : null + ]] + ]] + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query, variables) + + when: + def result = localCompileToDocument(schema, MUTATION, null, fields, jsonVariables) + def documentPrinted = printDoc(result.document) + + then: + result.variables.size() == 1 + result.variables['v0'] == [[name : "Zlatan", + lastName: "Ibrahimoviç", + clubs : ["MU", "Barsa", "Inter", "Milan", null], + "48x48" : "Zlatan_48x48.jpg", + "96x96" : null + ]] + documentPrinted == '''mutation ($v0: [JSON!]) { + foo1(arg: {id : "ID-00", json : $v0}) +} +''' + } + + + def "test a combination of plain objects and interfaces with all variables and no variables"() { + def sdl = ''' + type Query { + listField1(arg: [Int]): String + listField2(arg: [I]): String + foo(arg: I): Foo + fooNonNull(arg: [I!]!): String + } + type Foo { + bar(arg: I): Bar + } + type Bar { + baz : Baz + } + interface Baz { + boo(arg: I) : String + } + type ABaz implements Baz { + boo(arg: I) : String + a : String + } + type BBaz implements Baz { + boo(arg: I) : String + b : String + } + input I { + arg1: String + arg2: [I] + } + ''' + def query = ''' + query whatEv { + listField1( arg : [1,2,3] ) + listField2( arg : [ {arg1 : "v1", arg2 : [ {arg1 : "v1.1"}] }, + {arg1 : "v2"}, + {arg1 : "v3"}] ) + + fooNonNull(arg: [{arg1 : "fooNonNullArg1"}, {arg1 : "fooNonNullArg2"}]) + + foo(arg: {arg1 : "fooArg"}) { + bar(arg: {arg1 : "barArg"}) { + baz { + ... on ABaz { + boo(arg : {arg1 : "barFragArg"}) + a + } + } + } + } + } + ''' + GraphQLSchema schema = mkSchema(sdl) + def fields = createNormalizedFields(schema, query) + + when: + def result = localCompileToDocument(schema, QUERY, "named", fields, allVariables) + def document = result.document + def vars = result.variables + def ast = printDoc(document) + + then: + + ast == '''query named($v0: [Int], $v1: [I], $v2: [I!]!, $v3: I, $v4: I, $v5: I) { + foo(arg: $v5) { + bar(arg: $v4) { + baz { + ... on ABaz { + a + boo(arg: $v3) + } + } + } + } + fooNonNull(arg: $v2) + listField1(arg: $v0) + listField2(arg: $v1) +} +''' + + vars == [v0: [1, 2, 3], + v1: [[arg1: "v1", arg2: [[arg1: "v1.1"]]], [arg1: "v2"], [arg1: "v3"]], + v2: [[arg1: "fooNonNullArg1"], [arg1: "fooNonNullArg2"]], + v3: [arg1: "barFragArg"], + v4: [arg1: "barArg"], + v5: [arg1: "fooArg"]] + + // + // Test the opposite - when we use no variables predicate everything should be inlined + // + when: "it has no variables" + + fields = createNormalizedFields(schema, query, [v0: [1, 2, 3], + v1: [[arg1: "v1", arg2: [[arg1: "v1.1"]]], [arg1: "v2"], [arg1: "v3"]], + v2: [[arg1: "fooNonNullArg1"], [arg1: "fooNonNullArg2"]], + v3: [arg1: "barFragArg"], + v4: [arg1: "barArg"], + v5: [arg1: "fooArg"]]) + + result = localCompileToDocument(schema, QUERY, "named", fields, noVariables) + document = result.document + vars = result.variables + ast = printDoc(document) + + then: "they should be inlined as values" + + // no vars created + vars == [:] + + // everything inlined + ast == '''query named { + foo(arg: {arg1 : "fooArg"}) { + bar(arg: {arg1 : "barArg"}) { + baz { + ... on ABaz { + a + boo(arg: {arg1 : "barFragArg"}) + } + } + } + } + fooNonNull(arg: [{arg1 : "fooNonNullArg1"}, {arg1 : "fooNonNullArg2"}]) + listField1(arg: [1, 2, 3]) + listField2(arg: [{arg1 : "v1", arg2 : [{arg1 : "v1.1"}]}, {arg1 : "v2"}, {arg1 : "v3"}]) +} +''' + } +} + +class ExecutableNormalizedOperationToAstCompilerTestWithDeferSupport extends ExecutableNormalizedOperationToAstCompilerTest { + static { + deferSupport = true + } +} + +class ExecutableNormalizedOperationToAstCompilerTestNoDeferSupport extends ExecutableNormalizedOperationToAstCompilerTest { + static { + deferSupport = false + } +} diff --git a/src/test/groovy/graphql/normalized/NormalizedInputValueTest.groovy b/src/test/groovy/graphql/normalized/NormalizedInputValueTest.groovy new file mode 100644 index 0000000000..1eb092fa74 --- /dev/null +++ b/src/test/groovy/graphql/normalized/NormalizedInputValueTest.groovy @@ -0,0 +1,87 @@ +package graphql.normalized + +import graphql.AssertException +import spock.lang.Specification +import spock.lang.Unroll + +class NormalizedInputValueTest extends Specification { + + @Unroll + def "can get unwrapped type name - #typename"() { + expect: + + def value = new NormalizedInputValue(typename, 1) + value.getTypeName() == typename + value.getUnwrappedTypeName() == unwrappedTypeName + + where: + typename | unwrappedTypeName + "[TypeName!]!" | "TypeName" + "[TypeName!]" | "TypeName" + "[TypeName]" | "TypeName" + "TypeName!" | "TypeName" + "TypeName!" | "TypeName" + "TypeName" | "TypeName" + } + + @Unroll + def "is list like- #typename"() { + expect: + + def value = new NormalizedInputValue(typename, 1) + value.isListLike() == expected + + where: + typename | expected + "[TypeName!]!" | true + "[TypeName!]" | true + "[TypeName]" | true + "TypeName!" | false + "TypeName" | false + } + + @Unroll + def "is nullable - #typename"() { + expect: + + def value = new NormalizedInputValue(typename, 1) + value.isNonNullable() == expectedNonNullable + value.isNullable() == !expectedNonNullable + + where: + typename | expectedNonNullable + "[TypeName!]!" | true + "[TypeName!]" | false + "[TypeName]" | false + "TypeName!" | true + "TypeName" | false + } + + @Unroll + def "bad input will be rejected = #typename"() { + expect: + + try { + new NormalizedInputValue(typename, 1) + assert valid, "This should have thrown an assert" + } catch (AssertException ignored) { + assert !valid, "This should have been valid" + } + + where: + typename | valid + " !" | false + "" | false + " " | false + " Name" | false + "Name " | false + "[]!" | false + "!!" | false + "[Name" | false + "Name]" | false + null | false + "[Valid]" | true + "[Valid]!" | true + "[Valid!]!" | true + } +} diff --git a/src/test/groovy/graphql/normalized/ValueToVariableValueCompilerTest.groovy b/src/test/groovy/graphql/normalized/ValueToVariableValueCompilerTest.groovy new file mode 100644 index 0000000000..0a168121e7 --- /dev/null +++ b/src/test/groovy/graphql/normalized/ValueToVariableValueCompilerTest.groovy @@ -0,0 +1,134 @@ +package graphql.normalized + +import graphql.language.ArrayValue +import graphql.language.BooleanValue +import graphql.language.EnumValue +import graphql.language.FloatValue +import graphql.language.IntValue +import graphql.language.ListType +import graphql.language.NonNullType +import graphql.language.NullValue +import graphql.language.ObjectField +import graphql.language.ObjectValue +import graphql.language.StringValue +import graphql.language.TypeName +import graphql.schema.idl.TypeUtil +import spock.lang.Specification + +class ValueToVariableValueCompilerTest extends Specification { + + def "cam handle different ast Value objects"() { + + expect: + def actual = ValueToVariableValueCompiler.normalisedValueToVariableValue(value) + actual == expected + + where: + value | expected + NullValue.of() | null + IntValue.of(666) | 666 + StringValue.of("str") | "str" + BooleanValue.of(true) | true + FloatValue.of(999d) | 999d + EnumValue.of("enumValue") | "enumValue" + ObjectValue.newObjectValue() + .objectField(ObjectField.newObjectField().name("a").value(IntValue.of(64)).build()) + .objectField(ObjectField.newObjectField().name("b").value(StringValue.of("65")).build()) + .build() | [a: 64, b: "65"] + ArrayValue.newArrayValue() + .value(IntValue.of(9)) + .value(StringValue.of("10")) + .value(EnumValue.of("enum")) + .build() | [9, "10", "enum"] + + } + + def "can handle NormalizedInputValue values that are literals"() { + expect: + def niv = new NormalizedInputValue("TypeName", value) + def actual = ValueToVariableValueCompiler.normalisedValueToVariableValue(niv) + actual == expected + + where: + value | expected + NullValue.of() | null + IntValue.of(666) | 666 + StringValue.of("str") | "str" + BooleanValue.of(true) | true + FloatValue.of(999d) | 999d + EnumValue.of("enumValue") | "enumValue" + ObjectValue.newObjectValue() + .objectField(ObjectField.newObjectField().name("a").value(IntValue.of(64)).build()) + .objectField(ObjectField.newObjectField().name("b").value(StringValue.of("65")).build()) + .build() | [a: 64, b: "65"] + ArrayValue.newArrayValue() + .value(IntValue.of(9)) + .value(StringValue.of("10")) + .value(EnumValue.of("enum")) + .build() | [9, "10", "enum"] + + + } + + def "can handle NormalizedInputValue values that are not literals"() { + expect: + def niv = new NormalizedInputValue("TypeName", value) + def actual = ValueToVariableValueCompiler.normalisedValueToVariableValue(niv) + actual == expected + + where: + value | expected + null | null + [IntValue.of(666), IntValue.of(664)] | [666, 664] + [a: IntValue.of(666), b: IntValue.of(664)] | [a: 666, b: 664] + + // at present we dont handle straight up java objects like 123 because + // the ValueResolver never produces them during + // ValueResolver.getNormalizedVariableValues say - this is debatable behavior + // but for now this is what we do + } + + def "can handle NormalizedInputValue values that are NIV with null members"() { + expect: + def niv = new NormalizedInputValue("TypeName", value) + def actual = ValueToVariableValueCompiler.normalisedValueToVariableValue(niv) + actual == expected + + where: + value | expected + [a: new NormalizedInputValue("X", IntValue.of(666)), b: new NormalizedInputValue("X", null)] | [a: 666, b: null] + [new NormalizedInputValue("X", IntValue.of(666)), new NormalizedInputValue("X", null)] | [666, null] + } + + + def "can print variables as expected"() { + expect: + def niv = new NormalizedInputValue(typeName, value) + def actual = ValueToVariableValueCompiler.normalizedInputValueToVariable(niv, varCount) + actual.value == expectedValue + actual.variableReference.name == expectedVarName + actual.definition.name == expectedVarName + // compare actual type + def actualType = actual.definition.type + actualType.isEqualTo(expectedType) + if (actualType instanceof NonNullType || actualType instanceof ListType) { + actualType.type.isEqualTo(expectedType.type) + } + TypeUtil.simplePrint(actualType) == typeName + + where: + value | varCount | typeName | expectedValue | expectedVarName | expectedType + NullValue.newNullValue().build() | 1 | "ID" | null | "v1" | new TypeName("ID") + IntValue.of(666) | 2 | "Int!" | 666 | "v2" | new NonNullType(new TypeName("Int")) + StringValue.of("str") | 3 | "String" | "str" | "v3" | new TypeName("String") + BooleanValue.of(true) | 4 | "Boolean!" | true | "v4" | new NonNullType(new TypeName("Boolean")) + FloatValue.of(999d) | 5 | "Float" | 999d | "v5" | new TypeName("Float") + EnumValue.of("enumValue") | 6 | "Foo!" | "enumValue" | "v6" | new NonNullType(new TypeName("Foo")) + ["a": IntValue.of(64), + "b": IntValue.of(65)] | 7 | "ObjectType" | [a: 64, b: 65] | "v7" | new TypeName("ObjectType") + [StringValue.of("9"), + StringValue.of("10"), + StringValue.of("11")] | 8 | "[String]" | ["9", "10", "11"] | "v8" | new ListType((new TypeName("String"))) + + } +} diff --git a/src/test/groovy/graphql/normalized/VariableAccumulatorTest.groovy b/src/test/groovy/graphql/normalized/VariableAccumulatorTest.groovy new file mode 100644 index 0000000000..377907b771 --- /dev/null +++ b/src/test/groovy/graphql/normalized/VariableAccumulatorTest.groovy @@ -0,0 +1,46 @@ +package graphql.normalized + +import graphql.language.IntValue +import graphql.language.NullValue +import graphql.language.StringValue +import graphql.language.TypeName +import spock.lang.Specification + +class VariableAccumulatorTest extends Specification { + + def alwaysTruePredicate = new VariablePredicate() { + @Override + boolean shouldMakeVariable(ExecutableNormalizedField executableNormalizedField, String argName, NormalizedInputValue normalizedInputValue) { + return true + } + } + + def "can build itself handing null values"() { + when: + VariableAccumulator accumulator = new VariableAccumulator(alwaysTruePredicate) + accumulateData(accumulator) + + def variablesMap = accumulator.getVariablesMap() + then: + variablesMap == [v0: "hello", v1: 666, v2: null, v3: null] + } + + def "can build variable definitions"() { + when: + VariableAccumulator accumulator = new VariableAccumulator(alwaysTruePredicate) + accumulateData(accumulator) + def names = accumulator.getVariableDefinitions().collect { vd -> vd.name } + def typeNames = accumulator.getVariableDefinitions().collect { vd -> (vd.type as TypeName).name } + + then: + names == ["v0", "v1", "v2", "v3"] + typeNames == ["String", "Int", "Int", "String"] + } + + private void accumulateData(VariableAccumulator accumulator) { + accumulator.accumulateVariable(new NormalizedInputValue("String", StringValue.of("hello"))) + accumulator.accumulateVariable(new NormalizedInputValue("Int", IntValue.of(666))) + accumulator.accumulateVariable(new NormalizedInputValue("Int", NullValue.of())) + accumulator.accumulateVariable(new NormalizedInputValue("String", null)) + } +} diff --git a/src/test/groovy/graphql/normalized/nf/NormalizedDocumentFactoryTest.groovy b/src/test/groovy/graphql/normalized/nf/NormalizedDocumentFactoryTest.groovy new file mode 100644 index 0000000000..5ef79cd417 --- /dev/null +++ b/src/test/groovy/graphql/normalized/nf/NormalizedDocumentFactoryTest.groovy @@ -0,0 +1,251 @@ +package graphql.normalized.nf + +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.TestUtil +import graphql.language.Document +import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLTypeUtil +import graphql.util.TraversalControl +import graphql.util.Traverser +import graphql.util.TraverserContext +import graphql.util.TraverserVisitorStub +import spock.lang.Specification + +class NormalizedDocumentFactoryTest extends Specification { + + def "test"() { + String schema = """ +type Query{ + animal: Animal +} +interface Animal { + name: String + friends: [Friend] +} + +union Pet = Dog | Cat + +type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] +} + +type Bird implements Animal { + name: String + friends: [Friend] +} + +type Cat implements Animal{ + name: String + friends: [Friend] + breed: String +} + +type Dog implements Animal{ + name: String + breed: String + friends: [Friend] +} + + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = """ + { + animal{ + name + otherName: name + ... on Animal { + name + } + ... on Cat { + name + friends { + ... on Friend { + isCatOwner + pets { + ... on Dog { + name + } + } + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Dog { + name + } + }} + + """ + + assertValidQuery(graphQLSchema, query) + + Document document = TestUtil.parseQuery(query) + def tree = NormalizedDocumentFactory.createNormalizedDocument(graphQLSchema, document) + def printedTree = printDocumentWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree == ['-Query.animal: Animal', + '--[Bird, Cat, Dog].name: String', + '--otherName: [Bird, Cat, Dog].name: String', + '--Cat.friends: [Friend]', + '---Friend.isCatOwner: Boolean', + '---Friend.pets: [Pet]', + '----Dog.name: String', + '--Bird.friends: [Friend]', + '---Friend.isBirdOwner: Boolean', + '---Friend.name: String', + '---Friend.pets: [Pet]', + '----Cat.breed: String' + ] + } + + def "document with skip/include with variables"() { + String schema = """ + type Query{ + foo: Foo + } + type Foo { + bar: Bar + name: String + } + type Bar { + baz: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + query ($skip: Boolean!, $include: Boolean!) { + foo { + name + bar @skip(if: $skip) { + baz @include(if: $include) + } + } + } + ''' + + + assertValidQuery(graphQLSchema, query, [skip: false, include: true]) + + Document document = TestUtil.parseQuery(query) + def tree = NormalizedDocumentFactory.createNormalizedDocument(graphQLSchema, document) + def printedTree = printDocumentWithLevelInfo(tree, graphQLSchema) + + expect: + printedTree.join("\n") == '''variables: [skip:false, include:false] +-Query.foo: Foo +--Foo.name: String +--Foo.bar: Bar +variables: [skip:true, include:false] +-Query.foo: Foo +--Foo.name: String +variables: [skip:false, include:true] +-Query.foo: Foo +--Foo.name: String +--Foo.bar: Bar +---Bar.baz: String +variables: [skip:true, include:true] +-Query.foo: Foo +--Foo.name: String''' + } + + def "document with custom directives"() { + String schema = """ + directive @cache(time: Int!) on FIELD + type Query{ + foo: Foo + } + type Foo { + bar: Bar + name: String + } + type Bar { + baz: String + } + """ + GraphQLSchema graphQLSchema = TestUtil.schema(schema) + + String query = ''' + query { + foo { + name + bar @cache(time:100) { + baz + } + bar @cache(time:200) { + baz + } + + } + } + ''' + + + assertValidQuery(graphQLSchema, query, [skip: false, include: true]) + + Document document = TestUtil.parseQuery(query) + def normalizedDocument = NormalizedDocumentFactory.createNormalizedDocument(graphQLSchema, document) + def rootField = normalizedDocument.getSingleNormalizedOperation().getRootFields().get(0) + def bar = rootField.getChildren().get(1) + + expect: + bar.getAstDirectives().size() == 2 + } + + + private void assertValidQuery(GraphQLSchema graphQLSchema, String query, Map variables = [:]) { + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + def ei = ExecutionInput.newExecutionInput(query).variables(variables).build() + assert graphQL.execute(ei).errors.size() == 0 + } + + static List printDocumentWithLevelInfo(NormalizedDocument normalizedDocument, GraphQLSchema schema) { + def result = [] + for (NormalizedDocument.NormalizedOperationWithAssumedSkipIncludeVariables normalizedOperationWithAssumedSkipIncludeVariables : normalizedDocument.normalizedOperations) { + NormalizedOperation normalizedOperation = normalizedOperationWithAssumedSkipIncludeVariables.normalizedOperation; + if (normalizedOperationWithAssumedSkipIncludeVariables.assumedSkipIncludeVariables != null) { + result << "variables: " + normalizedOperationWithAssumedSkipIncludeVariables.assumedSkipIncludeVariables + } + Traverser traverser = Traverser.depthFirst({ it.getChildren() }) + traverser.traverse(normalizedOperation.getRootFields(), new TraverserVisitorStub() { + @Override + TraversalControl enter(TraverserContext context) { + NormalizedField normalizedField = context.thisNode() + String prefix = "" + for (int i = 1; i <= normalizedField.getLevel(); i++) { + prefix += "-" + } + + def possibleOutputTypes = new LinkedHashSet() + for (fieldDef in normalizedField.getFieldDefinitions(schema)) { + possibleOutputTypes.add(GraphQLTypeUtil.simplePrint(fieldDef.type)) + } + + result << (prefix + normalizedField.printDetails() + ": " + possibleOutputTypes.join(", ")) + return TraversalControl.CONTINUE + } + }) + } + result + } + + +} diff --git a/src/test/groovy/graphql/normalized/nf/NormalizedOperationToAstCompilerTest.groovy b/src/test/groovy/graphql/normalized/nf/NormalizedOperationToAstCompilerTest.groovy new file mode 100644 index 0000000000..c797392fe3 --- /dev/null +++ b/src/test/groovy/graphql/normalized/nf/NormalizedOperationToAstCompilerTest.groovy @@ -0,0 +1,257 @@ +package graphql.normalized.nf + +import graphql.GraphQL +import graphql.TestUtil +import graphql.language.AstPrinter +import graphql.language.AstSorter +import graphql.language.OperationDefinition +import graphql.parser.Parser +import graphql.schema.GraphQLSchema +import spock.lang.Specification + +import static graphql.ExecutionInput.newExecutionInput + +class NormalizedOperationToAstCompilerTest extends Specification { + + + def "test pet interfaces"() { + String sdl = """ + type Query { + animal: Animal + } + interface Animal { + name: String + friends: [Friend] + } + + union Pet = Dog | Cat + + type Friend { + name: String + isBirdOwner: Boolean + isCatOwner: Boolean + pets: [Pet] + } + + type Bird implements Animal { + name: String + friends: [Friend] + } + + type Cat implements Animal { + name: String + friends: [Friend] + breed: String + mood: String + } + + type Dog implements Animal { + name: String + breed: String + friends: [Friend] + } + """ + + String query = """ + { + animal { + name + otherName: name + ... on Animal { + name + } + ... on Cat { + name + mood + friends { + ... on Friend { + isCatOwner + pets { + ... on Dog { + name + } + } + } + } + } + ... on Bird { + friends { + isBirdOwner + } + friends { + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Dog { + name + breed + } + } + } + """ + GraphQLSchema schema = TestUtil.schema(sdl) + assertValidQuery(schema, query) + def normalizedDocument = NormalizedDocumentFactory.createNormalizedDocument(schema, Parser.parse(query)) + def normalizedOperation = normalizedDocument.getSingleNormalizedOperation() + when: + def result = NormalizedOperationToAstCompiler.compileToDocument(schema, normalizedOperation) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + animal { + name + otherName: name + ... on Bird { + friends { + isBirdOwner + name + pets { + ... on Cat { + breed + } + } + } + } + ... on Cat { + friends { + isCatOwner + pets { + ... on Dog { + name + } + } + } + mood + } + ... on Dog { + breed + } + } +} +''' + } + + def "print custom directives"() { + String sdl = """ + directive @cache(time: Int!) on FIELD + type Query{ + foo: Foo + } + type Foo { + bar: Bar + name: String + } + type Bar { + baz: String + } + """ + + String query = ''' + query { + foo { + name + bar @cache(time:100) { + baz + } + bar @cache(time:200) { + baz + } + + } + } + ''' + + GraphQLSchema schema = TestUtil.schema(sdl) + assertValidQuery(schema, query) + def normalizedDocument = NormalizedDocumentFactory.createNormalizedDocument(schema, Parser.parse(query)) + def normalizedOperation = normalizedDocument.getSingleNormalizedOperation() + when: + def result = NormalizedOperationToAstCompiler.compileToDocument(schema, normalizedOperation) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''{ + foo { + bar @cache(time: 100) @cache(time: 200) { + baz + } + name + } +} +''' + } + + + def "print one root field"() { + def sdl = """ + type Query { + foo: Foo + } + type Foo { + bar: String + } + """ + def query = ''' + { foo { bar } } + ''' + GraphQLSchema schema = TestUtil.schema(sdl) + assertValidQuery(schema, query) + def normalizedDocument = NormalizedDocumentFactory.createNormalizedDocument(schema, Parser.parse(query)) + def normalizedOperation = normalizedDocument.getSingleNormalizedOperation() + def rootField = normalizedOperation.getRootFields().get(0) + when: + def result = NormalizedOperationToAstCompiler.compileToDocument(schema, schema.getObjectType("Query"), rootField, "myOperation", OperationDefinition.Operation.QUERY) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''query myOperation { + foo { + bar + } +} +''' + } + + def "print list of root fields"() { + def sdl = """ + type Query { + foo: Foo + } + type Foo { + bar: String + } + """ + def query = ''' + { foo { bar } foo2: foo { bar } } + ''' + GraphQLSchema schema = TestUtil.schema(sdl) + assertValidQuery(schema, query) + def normalizedDocument = NormalizedDocumentFactory.createNormalizedDocument(schema, Parser.parse(query)) + def normalizedOperation = normalizedDocument.getSingleNormalizedOperation() + def rootFields = normalizedOperation.getRootFields() + when: + def result = NormalizedOperationToAstCompiler.compileToDocument(schema, schema.getObjectType("Query"), rootFields, "myOperation", OperationDefinition.Operation.QUERY) + def printed = AstPrinter.printAst(new AstSorter().sort(result.document)) + then: + printed == '''query myOperation { + foo { + bar + } + foo2: foo { + bar + } +} +''' + } + + + private void assertValidQuery(GraphQLSchema graphQLSchema, String query, Map variables = [:]) { + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build() + assert graphQL.execute(newExecutionInput().query(query).variables(variables)).errors.isEmpty() + } + + +} diff --git a/src/test/groovy/graphql/parser/BadParserSituations.java b/src/test/groovy/graphql/parser/BadParserSituations.java new file mode 100644 index 0000000000..9f603ccee9 --- /dev/null +++ b/src/test/groovy/graphql/parser/BadParserSituations.java @@ -0,0 +1,128 @@ +package graphql.parser; + +import com.google.common.base.Strings; +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.GraphQLError; +import graphql.schema.GraphQLSchema; +import graphql.schema.StaticDataFetcher; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import graphql.schema.idl.TypeDefinitionRegistry; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.time.Duration; +import java.util.List; +import java.util.function.Function; + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring; + +/** + * This is not a test - it's a program we can run to show the system reacts to certain bad inputs + * + * You can run this to discover scenarios and see what happens at what levels. + * + * I used this to help discover more on the behavior of ANTLR and its moving parts + */ +public class BadParserSituations { + static Integer STEP = 5000; + static Integer CHECKS_AMOUNT = 15; + + public static void main(String[] args) { + GraphQL graphQL = setupSchema(); + + System.setErr(toDevNull()); + + for (int runNumber = 1; runNumber <= 2; runNumber++) { + String runState = "Limited Tokens"; + // on the second run - have unlimited tokens + if (runNumber > 1) { + ParserOptions unlimitedTokens = ParserOptions.getDefaultOperationParserOptions().transform( + builder -> builder.maxTokens(Integer.MAX_VALUE).maxWhitespaceTokens(Integer.MAX_VALUE)); + ParserOptions.setDefaultOperationParserOptions(unlimitedTokens); + + runState = "Unlimited Tokens"; + } + runScenarios("Whitespace Bad Payloads", runState, graphQL, howMany -> { + String repeatedPayload = Strings.repeat(" ", howMany); + return "query {__typename " + repeatedPayload + " }"; + }); + runScenarios("Comment Bad Payloads", runState, graphQL, howMany -> { + String repeatedPayload = Strings.repeat("# some comment\n", howMany); + String query = repeatedPayload + "\nquery q {__typename }"; + return query; + }); + runScenarios("Grammar Directives Bad Payloads", runState, graphQL, howMany -> { + String repeatedPayload = Strings.repeat("@lol", howMany); + return "query {__typename " + repeatedPayload + " }"; + }); + runScenarios("Grammar Field Bad Payloads", runState, graphQL, howMany -> { + String repeatedPayload = Strings.repeat("f(id:null)", howMany); + return "query {__typename " + repeatedPayload + " }"; + }); + + } + + } + + private static void runScenarios(String scenarioName, String runState, GraphQL graphQL, Function queryGenerator) { + long maxRuntime = 0; + for (int i = 1; i < CHECKS_AMOUNT; i++) { + + int howManyBadPayloads = i * STEP; + String query = queryGenerator.apply(howManyBadPayloads); + + ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(query).build(); + long startTime = System.nanoTime(); + + ExecutionResult executionResult = graphQL.execute(executionInput); + + Duration duration = Duration.ofNanos(System.nanoTime() - startTime); + + System.out.printf("%s(%s)(%d of %d) - | query length %d | bad payloads %d | duration %dms \n", scenarioName, runState, i, CHECKS_AMOUNT, query.length(), howManyBadPayloads, duration.toMillis()); + printLastError(executionResult.getErrors()); + + if (duration.toMillis() > maxRuntime) { + maxRuntime = duration.toMillis(); + } + } + System.out.printf("%s(%s) - finished | max time was %s ms \n" + + "=======================\n\n", scenarioName, runState, maxRuntime); + } + + private static void printLastError(List errors) { + if (errors.size() > 0) { + GraphQLError lastError = errors.get(errors.size() - 1); + System.out.printf("\terror : %s \n", lastError.getMessage()); + } + + } + + private static PrintStream toDevNull() { + return new PrintStream(new OutputStream() { + public void write(int b) { + //DO NOTHING + } + }); + } + + private static GraphQL setupSchema() { + String schema = "type Query{hello: String}"; + + SchemaParser schemaParser = new SchemaParser(); + TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema); + + RuntimeWiring runtimeWiring = newRuntimeWiring() + .type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world"))) + .build(); + + SchemaGenerator schemaGenerator = new SchemaGenerator(); + GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring); + + GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build(); + return graphQL; + } +} diff --git a/src/test/groovy/graphql/parser/LineNumberingTest.groovy b/src/test/groovy/graphql/parser/LineNumberingTest.groovy new file mode 100644 index 0000000000..1a74c9cbeb --- /dev/null +++ b/src/test/groovy/graphql/parser/LineNumberingTest.groovy @@ -0,0 +1,136 @@ +package graphql.parser + +import graphql.language.Field +import graphql.language.FragmentDefinition +import graphql.language.OperationDefinition +import spock.lang.Specification +import spock.lang.Unroll + +/* + See https://github.com/graphql-java/graphql-java/issues/1512 + */ + +class LineNumberingTest extends Specification { + + def "basic line numbering works as expected with string input"() { + def query = '''query X { + field1 + field2 + field3 + field4 +} + +fragment X on Book { + frag1 +} + +''' + + when: + def document = new Parser().parseDocument(query) + def queryOp = document.getDefinitionsOfType(OperationDefinition.class)[0] + then: + queryOp.getSourceLocation().getLine() == 1 + + when: + def field1 = queryOp.getSelectionSet().getSelectionsOfType(Field.class)[0] + then: + field1.getSourceLocation().getLine() == 2 + + when: + def field2 = queryOp.getSelectionSet().getSelectionsOfType(Field.class)[1] + then: + field2.getSourceLocation().getLine() == 3 + + } + + def "multi source line numbering works as expected"() { + def queryBit1 = '''query X { + field1 + field2 # note the extra space here + field3 + field4 +}''' + def queryBit2 = '''fragment X on Book { + frag1 + frag2 # note the extra space here + frag2 +}''' + + MultiSourceReader msr = MultiSourceReader.newMultiSourceReader() + .string(queryBit1, "bit1") + .string(queryBit2, "bit2") + .build() + + when: + def document = new Parser().parseDocument(msr) + then: + document.getSourceLocation().getLine() == 1 + document.getSourceLocation().getColumn() == 1 + document.getSourceLocation().getSourceName() == "bit1" + + when: + def queryOp = document.getDefinitionsOfType(OperationDefinition.class)[0] + then: + queryOp.getSourceLocation().getLine() == 1 + queryOp.getSourceLocation().getColumn() == 1 + queryOp.getSourceLocation().getSourceName() == "bit1" + + when: + def field1 = queryOp.getSelectionSet().getSelectionsOfType(Field.class)[0] + then: + field1.getSourceLocation().getLine() == 2 + field1.getSourceLocation().getColumn() == 4 + field1.getSourceLocation().getSourceName() == "bit1" + + when: + def field2 = queryOp.getSelectionSet().getSelectionsOfType(Field.class)[1] + then: + field2.getSourceLocation().getLine() == 3 + field2.getSourceLocation().getColumn() == 5 + field2.getSourceLocation().getSourceName() == "bit1" + + when: + def fragment = document.getDefinitionsOfType(FragmentDefinition.class)[0] + then: + fragment.getSourceLocation().getLine() == 1 + fragment.getSourceLocation().getColumn() == 2 + fragment.getSourceLocation().getSourceName() == "bit2" + + when: + def fragField1 = fragment.getSelectionSet().getSelectionsOfType(Field.class)[0] + then: + fragField1.getSourceLocation().getLine() == 2 + fragField1.getSourceLocation().getColumn() == 4 + fragField1.getSourceLocation().getSourceName() == "bit2" + + when: + def fragField2 = fragment.getSelectionSet().getSelectionsOfType(Field.class)[1] + then: + fragField2.getSourceLocation().getLine() == 3 + fragField2.getSourceLocation().getColumn() == 5 + fragField2.getSourceLocation().getSourceName() == "bit2" + } + + @SuppressWarnings("GroovyVariableNotAssigned") + @Unroll + def "error is on the right line with string input"() { + expect: + def e + try { + new Parser().parseDocument(badQuery) + assert false, "Should have barfed" + } catch (InvalidSyntaxException ise) { + e = ise + } + e.getLocation().getLine() == line + e.getLocation().getColumn() == column + e.getLocation().getSourceName() == null + + where: + badQuery | line | column + '''query X { field() field2''' | 1 | 17 + '''query X { field()\nfield2''' | 1 | 17 + '''query X { field\nfield2()\nfield3''' | 2 | 8 + } +} diff --git a/src/test/groovy/graphql/parser/MultiSourceReaderTest.groovy b/src/test/groovy/graphql/parser/MultiSourceReaderTest.groovy new file mode 100644 index 0000000000..7e5a60ff0f --- /dev/null +++ b/src/test/groovy/graphql/parser/MultiSourceReaderTest.groovy @@ -0,0 +1,234 @@ +package graphql.parser + +import spock.lang.Specification + +class MultiSourceReaderTest extends Specification { + + MultiSourceReader multiSource + + void cleanup() { + multiSource.close() + } + + def "can combine files"() { + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .reader(readerOf("multisource/a.txt"), "PartA") + .reader(readerOf("multisource/b.txt"), "PartB") + .reader(readerOf("multisource/c.txt"), "PartC") + .build() + then: + multiSource.getLineNumber() == 0 + multiSource.getOverallLineNumber() == 0 + multiSource.getSourceName() == "PartA" + + when: + def line = readNLines(1) + then: + line == "A0*******X" + multiSource.getLineNumber() == 1 + multiSource.getOverallLineNumber() == 1 + multiSource.getSourceName() == "PartA" + + when: + line = readNLines(1) + then: + line == "A1*******X" + multiSource.getLineNumber() == 2 + multiSource.getOverallLineNumber() == 2 + multiSource.getSourceName() == "PartA" + + when: + line = readNLines(4) + then: + line == "A2*******XA3*******XA4*******XA5*******X" + multiSource.getLineNumber() == 6 + multiSource.getOverallLineNumber() == 6 + multiSource.getSourceName() == "PartA" + + // jumps into file B + when: + line = readNLines(1) + then: + line == "B0*******X" + multiSource.getLineNumber() == 1 + multiSource.getOverallLineNumber() == 7 + multiSource.getSourceName() == "PartB" + + // jumps into file C + when: + readNLines(6) + line = readNLines(1) + then: + line == "C1*******X" + multiSource.getLineNumber() == 2 + multiSource.getOverallLineNumber() == 14 + multiSource.getSourceName() == "PartC" + + // reads to the end and stays there + when: + line = readNLines(100) + then: + line == "C2*******XC3*******XC4*******XC5*******X" + multiSource.getLineNumber() == 6 + multiSource.getOverallLineNumber() == 18 + multiSource.getSourceName() == "PartC" + + when: + line = readNLines(100) + then: + line == "" + multiSource.getLineNumber() == 6 + multiSource.getOverallLineNumber() == 18 + multiSource.getSourceName() == "PartC" + } + + def "can read all the lines as one"() { + + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .reader(readerOf("multisource/a.graphql"), "SdlA") + .reader(readerOf("multisource/b.graphql"), "SdlB") + .reader(readerOf("multisource/c.graphql"), "SdlC") + .build() + + then: + + joinLines(multiSource.readLines()) == ''' +type A { + fieldC : String +} +type B { + fieldC : String +} +type C { + fieldC : String +} +''' + + } + + + def "does not track data if told too"() { + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .reader(readerOf("multisource/a.txt"), "PartA") + .reader(readerOf("multisource/b.txt"), "PartB") + .trackData(false) + .build() + then: + readNLines(100) + multiSource.getData() == [] + } + + def "can track data b y default"() { + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .reader(readerOf("multisource/a.txt"), "PartA") + .reader(readerOf("multisource/b.txt"), "PartB") + .build() + then: + readNLines(100) + joinLines(multiSource.getData()) == ''' +A0*******X +A1*******X +A2*******X +A3*******X +A4*******X +A5*******X +B0*******X +B1*******X +B2*******X +B3*******X +B4*******X +B5*******X +''' + } + + def "can handle zero elements"() { + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .build() + def lines = multiSource.readLines() + then: + lines.isEmpty() + multiSource.getSourceName() == null + multiSource.getLineNumber() == 0 + multiSource.getOverallLineNumber() == 0 + } + + def "can handle null source name"() { + def sr = new StringReader("Hello\nWorld") + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .reader(sr, null) + .build() + def lines = multiSource.readLines() + then: + lines == ["Hello", "World"] + multiSource.getSourceName() == null + multiSource.getLineNumber() == 1 + multiSource.getOverallLineNumber() == 1 + } + + def "can work out relative lines from overall lines"() { + when: + multiSource = MultiSourceReader.newMultiSourceReader() + .reader(readerOf("multisource/a.txt"), "PartA") + .reader(readerOf("multisource/b.txt"), "PartB") + .reader(readerOf("multisource/b.txt"), "PartC") + .trackData(true) + .build() + + readNLines(100) + + def sAndL = multiSource.getSourceAndLineFromOverallLine(7) + + then: + sAndL.line == 1 + sAndL.sourceName == "PartB" + + when: + sAndL = multiSource.getSourceAndLineFromOverallLine(3) + + then: + sAndL.line == 3 + sAndL.sourceName == "PartA" + + when: + sAndL = multiSource.getSourceAndLineFromOverallLine(13) + + then: + sAndL.line == 1 + sAndL.sourceName == "PartC" + + when: + // wont jump past the max lines + sAndL = multiSource.getSourceAndLineFromOverallLine(100) + + then: + sAndL.line == 18 + sAndL.sourceName == "PartC" + } + + String readNLines(int count) { + def line = "" + for (int i = 0; i < count; i++) { + def l = multiSource.readLine() + if (l == null) { + return line + } + line += l + } + line + } + + String joinLines(List lines) { + "\n" + lines.join("\n") + "\n" + } + + Reader readerOf(String s) { + def stream = this.class.classLoader.getResourceAsStream(s) + return new InputStreamReader(stream) + } +} diff --git a/src/test/groovy/graphql/parser/ParserExceptionTest.groovy b/src/test/groovy/graphql/parser/ParserExceptionTest.groovy new file mode 100644 index 0000000000..459ba957b6 --- /dev/null +++ b/src/test/groovy/graphql/parser/ParserExceptionTest.groovy @@ -0,0 +1,116 @@ +package graphql.parser + +import graphql.GraphQL +import graphql.InvalidSyntaxError +import graphql.StarWarsSchema +import spock.lang.Specification + +class ParserExceptionTest extends Specification { + def badQueryPart1 = ''' +query X { + field1 + field2 + field3 + field4 + field5 +}''' + + def badQueryPart2 = ''' + +fragment X on SomeType { + fragField1 + fragField2(syntaxErrorHere + fragField3 + fragField4 + fragField5 +} + ''' + + def badQuery = badQueryPart1 + badQueryPart2 + + def "builds specific exception with preview when in error"() { + when: + new Parser().parseDocument(badQuery) + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 13 + e.location.column == 5 + e.sourcePreview == '''fragment X on SomeType { + fragField1 + fragField2(syntaxErrorHere + fragField3 + fragField4 + fragField5 +} +''' + } + + def "can work with multi source input"() { + when: + def multiSource = MultiSourceReader.newMultiSourceReader() + .string(badQueryPart1, "part1") + .string(badQueryPart2, "part2") + .build() + + new Parser().parseDocument(multiSource) + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 6 + e.location.column == 5 + e.location.sourceName == "part2" + e.sourcePreview == '''fragment X on SomeType { + fragField1 + fragField2(syntaxErrorHere + fragField3 + fragField4 + fragField5 +} +''' + } + + def "more parsing error tests"() { + def sdl = ''' + scala Url # spillin misteak + + interface Foo { + is_foo : Boolean + } + ''' + when: + Reader reader = MultiSourceReader.newMultiSourceReader() + .string(sdl, "namedSource") + .build() + new Parser().parseDocument(reader) + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 2 + e.location.column == 13 + e.location.sourceName == "namedSource" + } + + def "short query failure is ok"() { + def query = '''query X { field1 field2(thisBreaksHere field3 }''' + when: + new Parser().parseDocument(query) + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 1 + e.location.column == 40 + e.location.sourceName == null + } + + def "integration test of parse exception handling "() { + def graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema).build() + when: + def er = graphQL.execute(badQuery) + then: + !er.errors.isEmpty() + er.errors[0] instanceof InvalidSyntaxError + + } + +} diff --git a/src/test/groovy/graphql/parser/ParserOptionsTest.groovy b/src/test/groovy/graphql/parser/ParserOptionsTest.groovy new file mode 100644 index 0000000000..9d43543f89 --- /dev/null +++ b/src/test/groovy/graphql/parser/ParserOptionsTest.groovy @@ -0,0 +1,111 @@ +package graphql.parser + +import spock.lang.Specification + +class ParserOptionsTest extends Specification { + static defaultOptions = ParserOptions.getDefaultParserOptions() + static defaultOperationOptions = ParserOptions.getDefaultOperationParserOptions() + static defaultSdlOptions = ParserOptions.getDefaultSdlParserOptions() + + static final int ONE_MB = 1024 * 1024 + + void setup() { + ParserOptions.setDefaultParserOptions(defaultOptions) + ParserOptions.setDefaultOperationParserOptions(defaultOperationOptions) + ParserOptions.setDefaultSdlParserOptions(defaultSdlOptions) + } + + void cleanup() { + ParserOptions.setDefaultParserOptions(defaultOptions) + ParserOptions.setDefaultOperationParserOptions(defaultOperationOptions) + ParserOptions.setDefaultSdlParserOptions(defaultSdlOptions) + } + + def "lock in default settings"() { + expect: + defaultOptions.getMaxCharacters() == ONE_MB + defaultOptions.getMaxTokens() == 15_000 + defaultOptions.getMaxWhitespaceTokens() == 200_000 + defaultOptions.isCaptureSourceLocation() + defaultOptions.isCaptureLineComments() + !defaultOptions.isCaptureIgnoredChars() + defaultOptions.isReaderTrackData() + !defaultOptions.isRedactTokenParserErrorMessages() + + defaultOperationOptions.getMaxTokens() == 15_000 + defaultOperationOptions.getMaxWhitespaceTokens() == 200_000 + defaultOperationOptions.isCaptureSourceLocation() + !defaultOperationOptions.isCaptureLineComments() + !defaultOperationOptions.isCaptureIgnoredChars() + defaultOperationOptions.isReaderTrackData() + !defaultOperationOptions.isRedactTokenParserErrorMessages() + + defaultSdlOptions.getMaxCharacters() == Integer.MAX_VALUE + defaultSdlOptions.getMaxTokens() == Integer.MAX_VALUE + defaultSdlOptions.getMaxWhitespaceTokens() == Integer.MAX_VALUE + defaultSdlOptions.isCaptureSourceLocation() + defaultSdlOptions.isCaptureLineComments() + !defaultSdlOptions.isCaptureIgnoredChars() + defaultSdlOptions.isReaderTrackData() + !defaultSdlOptions.isRedactTokenParserErrorMessages() + } + + def "can set in new option JVM wide"() { + def newDefaultOptions = defaultOptions.transform({ + it.captureIgnoredChars(true) + .readerTrackData(false) + .redactTokenParserErrorMessages(true) + }) + def newDefaultOperationOptions = defaultOperationOptions.transform( + { + it.captureIgnoredChars(true) + .captureLineComments(true) + .maxCharacters(1_000_000) + .maxWhitespaceTokens(300_000) + }) + def newDefaultSDlOptions = defaultSdlOptions.transform( + { + it.captureIgnoredChars(true) + .captureLineComments(true) + .maxWhitespaceTokens(300_000) + }) + + when: + ParserOptions.setDefaultParserOptions(newDefaultOptions) + ParserOptions.setDefaultOperationParserOptions(newDefaultOperationOptions) + ParserOptions.setDefaultSdlParserOptions(newDefaultSDlOptions) + + def currentDefaultOptions = ParserOptions.getDefaultParserOptions() + def currentDefaultOperationOptions = ParserOptions.getDefaultOperationParserOptions() + def currentDefaultSdlOptions = ParserOptions.getDefaultSdlParserOptions() + + then: + + currentDefaultOptions.getMaxCharacters() == ONE_MB + currentDefaultOptions.getMaxTokens() == 15_000 + currentDefaultOptions.getMaxWhitespaceTokens() == 200_000 + currentDefaultOptions.isCaptureSourceLocation() + currentDefaultOptions.isCaptureLineComments() + currentDefaultOptions.isCaptureIgnoredChars() + !currentDefaultOptions.isReaderTrackData() + currentDefaultOptions.isRedactTokenParserErrorMessages() + + currentDefaultOperationOptions.getMaxCharacters() == 1_000_000 + currentDefaultOperationOptions.getMaxTokens() == 15_000 + currentDefaultOperationOptions.getMaxWhitespaceTokens() == 300_000 + currentDefaultOperationOptions.isCaptureSourceLocation() + currentDefaultOperationOptions.isCaptureLineComments() + currentDefaultOperationOptions.isCaptureIgnoredChars() + currentDefaultOperationOptions.isReaderTrackData() + !currentDefaultOperationOptions.isRedactTokenParserErrorMessages() + + currentDefaultSdlOptions.getMaxCharacters() == Integer.MAX_VALUE + currentDefaultSdlOptions.getMaxTokens() == Integer.MAX_VALUE + currentDefaultSdlOptions.getMaxWhitespaceTokens() == 300_000 + currentDefaultSdlOptions.isCaptureSourceLocation() + currentDefaultSdlOptions.isCaptureLineComments() + currentDefaultSdlOptions.isCaptureIgnoredChars() + currentDefaultSdlOptions.isReaderTrackData() + !currentDefaultSdlOptions.isRedactTokenParserErrorMessages() + } +} diff --git a/src/test/groovy/graphql/parser/ParserStressTest.groovy b/src/test/groovy/graphql/parser/ParserStressTest.groovy new file mode 100644 index 0000000000..c058d56a2f --- /dev/null +++ b/src/test/groovy/graphql/parser/ParserStressTest.groovy @@ -0,0 +1,211 @@ +package graphql.parser + +import graphql.ExecutionInput +import graphql.TestUtil +import graphql.language.Document +import graphql.parser.exceptions.ParseCancelledException +import graphql.parser.exceptions.ParseCancelledTooDeepException +import graphql.parser.exceptions.ParseCancelledTooManyCharsException +import spock.lang.Specification + +import static graphql.parser.ParserEnvironment.newParserEnvironment + +/** + * Tests related to how the Parser can be stress tested + */ +class ParserStressTest extends Specification { + static defaultOptions = ParserOptions.getDefaultParserOptions() + static defaultOperationOptions = ParserOptions.getDefaultOperationParserOptions() + static defaultSdlOptions = ParserOptions.getDefaultSdlParserOptions() + + void setup() { + ParserOptions.setDefaultParserOptions(defaultOptions) + ParserOptions.setDefaultOperationParserOptions(defaultOperationOptions) + ParserOptions.setDefaultSdlParserOptions(defaultSdlOptions) + } + + void cleanup() { + ParserOptions.setDefaultParserOptions(defaultOptions) + ParserOptions.setDefaultOperationParserOptions(defaultOperationOptions) + ParserOptions.setDefaultSdlParserOptions(defaultSdlOptions) + } + + + def "a billion laughs attack will be prevented by default"() { + def lol = "@lol" * 10000 // two tokens = 20000+ tokens + def text = "query { f $lol }" + when: + Parser.parse(text) + + then: + def e = thrown(ParseCancelledException) + e.getMessage().contains("parsing has been cancelled") + + when: "integration test to prove it cancels by default" + + def sdl = """type Query { f : ID} """ + def graphQL = TestUtil.graphQL(sdl).build() + def er = graphQL.execute(text) + then: + er.errors.size() == 1 + er.errors[0].message.contains("parsing has been cancelled") + } + + def "a large whitespace laughs attack will be prevented by default"() { + def spaces = " " * 300_000 + def text = "query { f $spaces }" + when: + Parser.parse(text) + + then: + def e = thrown(ParseCancelledException) + e.getMessage().contains("parsing has been cancelled") + + when: "integration test to prove it cancels by default" + + def sdl = """type Query { f : ID} """ + def graphQL = TestUtil.graphQL(sdl).build() + def er = graphQL.execute(text) + then: + er.errors.size() == 1 + er.errors[0].message.contains("parsing has been cancelled") + } + + def "they can shoot themselves if they want to with large documents"() { + def lol = "@lol" * 10000 // two tokens = 20000+ tokens + def text = "query { f $lol }" + + def options = ParserOptions.newParserOptions().maxTokens(30000).build() + def parserEnvironment = newParserEnvironment().document(text).parserOptions(options).build() + + when: + def doc = new Parser().parseDocument(parserEnvironment) + + then: + doc != null + } + + def "they can shoot themselves if they want to with large documents with lots of whitespace"() { + def spaces = " " * 300_000 + def text = "query { f $spaces }" + + def options = ParserOptions.newParserOptions().maxWhitespaceTokens(Integer.MAX_VALUE).build() + def parserEnvironment = newParserEnvironment().document(text).parserOptions(options).build() + when: + def doc = new Parser().parseDocument(parserEnvironment) + + then: + doc != null + } + + def "they can set their own listener into action"() { + def queryText = "query { f(arg : 1) }" + + def count = 0 + def tokens = [] + ParsingListener listener = { count++; tokens.add(it.getText()) } + def parserOptions = ParserOptions.newParserOptions().parsingListener(listener).build() + def parserEnvironment = newParserEnvironment().document(queryText).parserOptions(parserOptions).build() + + when: + def doc = new Parser().parseDocument(parserEnvironment) + + then: + doc != null + count == 9 + tokens == ["query", "{", "f", "(", "arg", ":", "1", ")", "}"] + + when: "integration test to prove it be supplied via EI" + + def sdl = """type Query { f(arg : Int) : ID} """ + def graphQL = TestUtil.graphQL(sdl).build() + + + def context = [:] + context.put(ParserOptions.class, parserOptions) + def executionInput = ExecutionInput.newExecutionInput() + .query(queryText) + .graphQLContext(context).build() + + count = 0 + tokens = [] + def er = graphQL.execute(executionInput) + then: + er.errors.size() == 0 + count == 9 + tokens == ["query", "{", "f", "(", "arg", ":", "1", ")", "}"] + + } + + def "deep query stack overflows are prevented by limiting the depth of rules"() { + String text = mkDeepQuery(10000) + + when: + def parserEnvironment = newParserEnvironment().document(text).parserOptions(defaultOperationOptions).build() + Parser.parse(parserEnvironment) + + then: + thrown(ParseCancelledTooDeepException) + } + + def "wide queries are prevented by max token counts"() { + String text = mkWideQuery(10000) + + when: + + def parserEnvironment = newParserEnvironment().document(text).parserOptions(defaultOperationOptions).build() + Parser.parse(parserEnvironment) + + then: + thrown(ParseCancelledException) // too many tokens will catch this wide queries + } + + def "large single token attack parse can be prevented"() { + String text = "q" * 10_000_000 + text = "query " + text + " {f}" + + when: + def parserEnvironment = newParserEnvironment().document(text).parserOptions(defaultOperationOptions).build() + Parser.parse(parserEnvironment) + + then: + thrown(ParseCancelledTooManyCharsException) + } + + def "inside limits single token attack parse will be accepted"() { + String text = "q" * 900_000 + text = "query " + text + " {f}" + + when: + def parserEnvironment = newParserEnvironment().document(text).parserOptions(defaultOperationOptions).build() + def document = Parser.parse(parserEnvironment) + + then: + document != null // its parsed - its invalid of course but parsed + } + + String mkDeepQuery(int howMany) { + def field = 'f(a:"")' + StringBuilder sb = new StringBuilder("query q{") + for (int i = 0; i < howMany; i++) { + sb.append(field) + if (i < howMany - 1) { + sb.append("{") + } + } + for (int i = 0; i < howMany - 1; i++) { + sb.append("}") + } + sb.append("}") + return sb.toString() + } + + String mkWideQuery(int howMany) { + StringBuilder sb = new StringBuilder("query q{f(") + for (int i = 0; i < howMany; i++) { + sb.append('a:1,') + } + sb.append(")}") + return sb.toString() + } +} diff --git a/src/test/groovy/graphql/parser/ParserTest.groovy b/src/test/groovy/graphql/parser/ParserTest.groovy index b10228a116..94724742d4 100644 --- a/src/test/groovy/graphql/parser/ParserTest.groovy +++ b/src/test/groovy/graphql/parser/ParserTest.groovy @@ -3,6 +3,7 @@ package graphql.parser import graphql.language.Argument import graphql.language.ArrayValue import graphql.language.AstComparator +import graphql.language.AstPrinter import graphql.language.BooleanValue import graphql.language.Description import graphql.language.Directive @@ -13,12 +14,15 @@ import graphql.language.Field import graphql.language.FloatValue import graphql.language.FragmentDefinition import graphql.language.FragmentSpread +import graphql.language.IgnoredChar +import graphql.language.IgnoredChars import graphql.language.InlineFragment import graphql.language.InputObjectTypeDefinition import graphql.language.IntValue import graphql.language.InterfaceTypeDefinition import graphql.language.ListType import graphql.language.Node +import graphql.language.NodeBuilder import graphql.language.NonNullType import graphql.language.NullValue import graphql.language.ObjectField @@ -28,18 +32,21 @@ import graphql.language.OperationDefinition import graphql.language.ScalarTypeDefinition import graphql.language.Selection import graphql.language.SelectionSet +import graphql.language.SourceLocation import graphql.language.StringValue +import graphql.language.Type import graphql.language.TypeName import graphql.language.UnionTypeDefinition import graphql.language.VariableDefinition import graphql.language.VariableReference -import org.antlr.v4.runtime.misc.ParseCancellationException +import org.antlr.v4.runtime.CommonTokenStream +import org.antlr.v4.runtime.ParserRuleContext +import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll class ParserTest extends Specification { - def "parse anonymous simple query"() { given: def input = "{ me }" @@ -64,11 +71,7 @@ class ParserTest extends Specification { boolean isEqual(Node node1, Node node2) { - return new AstComparator().isEqual(node1, node2) - } - - boolean isEqual(List node1, List node2) { - return new AstComparator().isEqual(node1, node2) + return AstComparator.isEqual(node1, node2) } def "parse selectionSet for field"() { @@ -132,7 +135,7 @@ class ParserTest extends Specification { given: def input = '{ user(id: 10, name: "homer", admin:true, floatValue: 3.04) }' - def argument = new Argument("id", new IntValue(10)) + def argument = new Argument("id", new IntValue(BigInteger.valueOf(10))) def argument2 = new Argument("name", new StringValue("homer")) def argument3 = new Argument("admin", new BooleanValue(true)) def argument4 = new Argument("floatValue", new FloatValue(3.04)) @@ -168,20 +171,20 @@ class ParserTest extends Specification { and: "expected query" def fragmentSpreadFriends = new FragmentSpread("friendFields") def selectionSetFriends = new SelectionSet([fragmentSpreadFriends]) - def friendsField = new Field("friends", [new Argument("first", new IntValue(10))], selectionSetFriends) + def friendsField = new Field("friends", [new Argument("first", new IntValue(BigInteger.valueOf(10)))], selectionSetFriends) def fragmentSpreadMutalFriends = new FragmentSpread("friendFields") def selectionSetMutalFriends = new SelectionSet([fragmentSpreadMutalFriends]) - def mutalFriendsField = new Field("mutualFriends", [new Argument("first", new IntValue(10))], selectionSetMutalFriends) + def mutalFriendsField = new Field("mutualFriends", [new Argument("first", new IntValue(BigInteger.valueOf(10)))], selectionSetMutalFriends) - def userField = new Field("user", [new Argument("id", new IntValue(4))], new SelectionSet([friendsField, mutalFriendsField])) + def userField = new Field("user", [new Argument("id", new IntValue(BigInteger.valueOf(4)))], new SelectionSet([friendsField, mutalFriendsField])) def queryDefinition = OperationDefinition.newOperationDefinition().name("withFragments").operation(OperationDefinition.Operation.QUERY).selectionSet(new SelectionSet([userField])).build() and: "expected fragment definition" def idField = new Field("id") def nameField = new Field("name") - def profilePicField = new Field("profilePic", [new Argument("size", new IntValue(50))]) + def profilePicField = new Field("profilePic", [new Argument("size", new IntValue(BigInteger.valueOf(50)))]) def selectionSet = SelectionSet.newSelectionSet().selections([idField, nameField, profilePicField]).build() def fragmentDefinition = FragmentDefinition.newFragmentDefinition().name("friendFields").typeCondition(new TypeName("User")).selectionSet(selectionSet).build() @@ -277,7 +280,7 @@ class ParserTest extends Specification { def helloField = new Field("hello") - def variableDefinition = new VariableDefinition("someTest", getOutputType) + def variableDefinition = new VariableDefinition("someTest", getOutputType as Type) def queryDefinition = OperationDefinition.newOperationDefinition().name("myQuery").operation(OperationDefinition.Operation.QUERY) .variableDefinitions([variableDefinition]).selectionSet(new SelectionSet([helloField])).build() @@ -329,7 +332,7 @@ class ParserTest extends Specification { and: "expected query" def objectValue = ObjectValue.newObjectValue() - objectValue.objectField(new ObjectField("intKey", new IntValue(1))) + objectValue.objectField(new ObjectField("intKey", new IntValue(BigInteger.valueOf(1)))) objectValue.objectField(new ObjectField("floatKey", new FloatValue(4.1))) objectValue.objectField(new ObjectField("stringKey", new StringValue("world"))) def subObject = ObjectValue.newObjectValue() @@ -358,13 +361,36 @@ class ParserTest extends Specification { when: def document = new Parser().parseDocument(input) - Field helloField = document.definitions[0].selectionSet.selections[0] + Field helloField = (document.definitions[0] as OperationDefinition).selectionSet.selections[0] as Field then: isEqual(helloField, new Field("hello", [new Argument("arg", new StringValue("hello, world"))])) helloField.comments.collect { c -> c.content } == [" this is some comment, which should be captured"] } + @Issue("https://github.com/graphql-java/graphql-java/issues/2767") + def "parser does not transform comments to AST nodes when ParserOptions.captureLineComments(false)"() { + given: + def input = """ + { # this is some comment, which should be captured + hello(arg: "hello, world" ) # test + } + """ + def parserOptionsWithoutCaptureLineComments = ParserOptions.newParserOptions() + .captureLineComments(false) + .build() + + when: + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(input).parserOptions(parserOptionsWithoutCaptureLineComments).build() + def document = new Parser().parseDocument(parserEnvironment) + Field helloField = (document.definitions[0] as OperationDefinition).selectionSet.selections[0] as Field + + then: + isEqual(helloField, new Field("hello", [new Argument("arg", new StringValue("hello, world"))])) + assert helloField.comments.isEmpty() // No single-line comments on lone fields + assert document.comments.isEmpty() // No single-line comments in entire document + } + @Unroll def "parse floatValue #floatString"() { given: @@ -373,7 +399,7 @@ class ParserTest extends Specification { """ when: def document = new Parser().parseDocument(input) - Field helloField = document.definitions[0].selectionSet.selections[0] + Field helloField = (document.definitions[0] as OperationDefinition).selectionSet.selections[0] as Field then: isEqual(helloField, new Field("hello", [new Argument("arg", new FloatValue(floatValue))])) @@ -396,10 +422,10 @@ class ParserTest extends Specification { { hello(arg: 4.) } """ when: - def document = new Parser().parseDocument(input) + new Parser().parseDocument(input) then: - thrown(ParseCancellationException) + thrown(InvalidSyntaxException) } def "extraneous input is an exception"() { @@ -410,7 +436,7 @@ class ParserTest extends Specification { when: new Parser().parseDocument(input) then: - thrown(ParseCancellationException) + thrown(InvalidSyntaxException) } def "invalid syntax is an error"() { @@ -421,7 +447,7 @@ class ParserTest extends Specification { when: new Parser().parseDocument(input) then: - thrown(ParseCancellationException) + thrown(InvalidSyntaxException) } def "mutation without a name"() { @@ -486,7 +512,7 @@ class ParserTest extends Specification { new Parser().parseDocument(input) then: - def exception = thrown(ParseCancellationException) + def exception = thrown(InvalidSyntaxException) exception != null } @@ -498,7 +524,7 @@ class ParserTest extends Specification { new Parser().parseDocument(input) then: - def exception = thrown(ParseCancellationException) + def exception = thrown(InvalidSyntaxException) exception != null } @@ -514,9 +540,9 @@ class ParserTest extends Specification { } - def "parses null value"() { + def "parses null values"() { given: - def input = "{ foo(bar: null) }" + def input = "{ foo(bar: null, bell : null) }" when: def document = new Parser().parseDocument(input) @@ -524,7 +550,11 @@ class ParserTest extends Specification { def selection = operation.selectionSet.selections[0] as Field then: - selection.arguments[0].value == NullValue.Null + selection.arguments[0].value instanceof NullValue + selection.arguments[1].value instanceof NullValue + + selection.arguments[0].value.sourceLocation.toString() == "SourceLocation{line=1, column=12}" + selection.arguments[1].value.sourceLocation.toString() == "SourceLocation{line=1, column=25}" } @@ -545,6 +575,45 @@ class ParserTest extends Specification { selection.name == "foo" } + def "four quotation marks is an illegal string"() { + given: + def input = '''{foo(arg:[""""])}''' + + when: + Parser.parse(input) + + then: + def e = thrown(InvalidSyntaxException) + e.message.contains("Invalid syntax") + } + + def "three quotation marks is an illegal string"() { + given: + def input = '''{foo(arg: ["""])}''' + + when: + Parser.parse(input) + + then: + def e = thrown(InvalidSyntaxException) + e.message.contains("Invalid syntax") + } + + def "escaped triple quote inside block string"() { + given: + def input = '''{foo(arg: """\\"""""")}''' + + when: + Document document = Parser.parse(input) + OperationDefinition operationDefinition = document.definitions[0] as OperationDefinition + Selection selection = operationDefinition.getSelectionSet().getSelections()[0] + Field field = (Field) selection + + then: + field.getArguments().size() == 1 + argValue(field, 0) == '"""' + } + def "triple quoted strings"() { given: def input = '''{ field(triple : """triple @@ -555,7 +624,7 @@ string""", single : "single") }''' then: document.definitions.size() == 1 - OperationDefinition operationDefinition = document.definitions[0] + OperationDefinition operationDefinition = document.definitions[0] as OperationDefinition Selection selection = operationDefinition.getSelectionSet().getSelections()[0] Field field = (Field) selection assert field.getArguments().size() == 2 @@ -581,7 +650,7 @@ triple3 : """edge cases \\""" "" " \\"" \\" edge cases""" then: document.definitions.size() == 1 - OperationDefinition operationDefinition = document.definitions[0] + OperationDefinition operationDefinition = document.definitions[0] as OperationDefinition Selection selection = operationDefinition.getSelectionSet().getSelections()[0] Field field = (Field) selection assert field.getArguments().size() == 3 @@ -672,4 +741,530 @@ triple3 : """edge cases \\""" "" " \\"" \\" edge cases""" } true } + + + def "parse ignored chars"() { + given: + def input = "{,\r me\n\t} ,\n" + + when: + def captureIgnoredCharsTRUE = ParserOptions.newParserOptions().captureIgnoredChars(true).build() + + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(input).parserOptions(captureIgnoredCharsTRUE).build() + + Document document = new Parser().parseDocument(parserEnvironment) + def field = (document.definitions[0] as OperationDefinition).selectionSet.selections[0] + then: + field.getIgnoredChars().getLeft().size() == 3 + field.getIgnoredChars().getLeft()[0] == new IgnoredChar(",", IgnoredChar.IgnoredCharKind.COMMA, new SourceLocation(1, 2)) + field.getIgnoredChars().getLeft()[1] == new IgnoredChar("\r", IgnoredChar.IgnoredCharKind.CR, new SourceLocation(1, 3)) + field.getIgnoredChars().getLeft()[2] == new IgnoredChar(" ", IgnoredChar.IgnoredCharKind.SPACE, new SourceLocation(1, 4)) + + field.getIgnoredChars().getRight().size() == 2 + field.getIgnoredChars().getRight()[0] == new IgnoredChar("\n", IgnoredChar.IgnoredCharKind.LF, new SourceLocation(1, 7)) + field.getIgnoredChars().getRight()[1] == new IgnoredChar("\t", IgnoredChar.IgnoredCharKind.TAB, new SourceLocation(2, 1)) + + document.getIgnoredChars().getRight().size() == 3 + document.getIgnoredChars().getRight()[0] == new IgnoredChar(" ", IgnoredChar.IgnoredCharKind.SPACE, new SourceLocation(2, 3)) + document.getIgnoredChars().getRight()[1] == new IgnoredChar(",", IgnoredChar.IgnoredCharKind.COMMA, new SourceLocation(2, 4)) + document.getIgnoredChars().getRight()[2] == new IgnoredChar("\n", IgnoredChar.IgnoredCharKind.LF, new SourceLocation(2, 5)) + } + + def "parsed float with positive exponent"() { + given: + def input = """ + { + getEmployee (sal:1.7976931348155E+308){ + sal + } + } + """ + when: + Document document = new Parser().parseDocument(input) + Field getEmployee = (document.definitions[0] as OperationDefinition).selectionSet.selections[0] as Field + def argumentValue = getEmployee.getArguments().get(0).getValue() + + then: + argumentValue instanceof FloatValue + ((FloatValue) argumentValue).value.toString() == "1.7976931348155E+308" + } + + def "parse fragment definition"() { + given: + def input = """ + fragment Foo on Bar { + hello + } + """ + when: + Document document = Parser.parse(input) + FragmentDefinition fragmentDefinition = (document.definitions[0] as FragmentDefinition) + + then: + fragmentDefinition.name == "Foo" + + } + + def "parser should throw syntax errors"() { + given: + def input = """ + type Foo { + name / String + } + """ + when: + def document = Parser.parse(input) + println document + then: + def e = thrown(InvalidSyntaxException) + e.message.contains("Invalid syntax") + e.sourcePreview == input + "\n" + e.location.line == 3 + e.location.column == 20 + } + + def "allow emoji in comments"() { + def input = ''' + # Represents the 😕 emoji. + { + foo + } + ''' + when: + Document document = Parser.parse(input) + OperationDefinition operationDefinition = (document.definitions[0] as OperationDefinition) + + + then: + operationDefinition.getComments()[0].content == " Represents the 😕 emoji." + } + + + def "the parser can be invoked via parser environment"() { + def input = ''' + # Represents the 😕 emoji. + { + foo + } + ''' + when: + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(input).build() + + Document document = Parser.parse(parserEnvironment) + OperationDefinition operationDefinition = (document.definitions[0] as OperationDefinition) + + then: + operationDefinition.getComments()[0].content == " Represents the 😕 emoji." + } + + def "can override antlr to ast"() { + + def query = ''' + query { + field + } + ''' + when: + Parser parser = new Parser() { + @Override + protected GraphqlAntlrToLanguage getAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiSourceReader, ParserEnvironment environment) { + // this pattern is used in Nadel - its backdoor but needed + return new GraphqlAntlrToLanguage(tokens, multiSourceReader, environment.parserOptions, environment.i18N, null) { + @Override + protected void addCommonData(NodeBuilder nodeBuilder, ParserRuleContext parserRuleContext) { + super.addCommonData(nodeBuilder, parserRuleContext) + nodeBuilder.additionalData("key", "value") + } + } + } + } + + def document = parser.parseDocument(query) + + then: + document.getAdditionalData().get("key") == "value" + document.children[0].getAdditionalData().get("key") == "value" + + when: "The new override method is used" + parser = new Parser() { + + @Override + protected GraphqlAntlrToLanguage getAntlrToLanguage(CommonTokenStream tokens, MultiSourceReader multiSourceReader, ParserEnvironment environment) { + return new GraphqlAntlrToLanguage(tokens, multiSourceReader, environment.parserOptions, environment.i18N, null) { + @Override + protected void addCommonData(NodeBuilder nodeBuilder, ParserRuleContext parserRuleContext) { + super.addCommonData(nodeBuilder, parserRuleContext) + nodeBuilder.additionalData("key", "value") + } + } + } + } + + document = parser.parseDocument(query) + + then: + document.getAdditionalData().get("key") == "value" + document.children[0].getAdditionalData().get("key") == "value" + } + + def "parse integer"() { + given: + def input = '''{foo(arg: 11)}''' + + when: + Document document = Parser.parse(input) + OperationDefinition operationDefinition = document.definitions[0] as OperationDefinition + Selection selection = operationDefinition.getSelectionSet().getSelections()[0] + Field field = (Field) selection + + then: + field.getArguments().size() == 1 + (field.getArguments()[0].getValue() as IntValue).getValue().intValueExact() == 11 + } + + @Unroll + def "invalid int #value is an error"() { + given: + def input = "{foo(arg: [$value])}" + + when: + Parser.parse(input) + + then: + def e = thrown(InvalidSyntaxException) + e.message.contains("Invalid syntax") + where: + value | _ + '00' | _ + '01' | _ + '123.' | _ + '123e' | _ + '123E' | _ + } + + @Unroll + def "invalid float #value is an error"() { + given: + def input = "{foo(arg: [$value])}" + + when: + Parser.parse(input) + + then: + def e = thrown(InvalidSyntaxException) + e.message.contains("Invalid syntax") + where: + value | _ + '01.23' | _ + '1.2e3.4' | _ + '1.23.4' | _ + '1.2e3e' | _ + } + + @Unroll + def 'parse ast field definition #valueLiteral'() { + expect: + def fieldDefinition = Parser.parseFieldDefinition(valueLiteral) + AstPrinter.printAstCompact(fieldDefinition) == valueLiteral + + where: + valueLiteral | _ + 'foo: Foo' | _ + 'foo(a:String): Foo' | _ + 'foo(a:String!,b:Int!): Foo' | _ + 'foo(a:String! ="defaultValue",b:Int!): Foo' | _ + 'foo(a:String!,b:Int!): Foo @directive(someValue:String)' | _ + } + + + @Unroll + def 'parse ast literals #valueLiteral'() { + expect: + Parser.parseValue(valueLiteral) in expectedValue + + where: + valueLiteral | expectedValue + '"s"' | StringValue.class + 'true' | BooleanValue.class + '666' | IntValue.class + '666.6' | FloatValue.class + '["A", "B", "C"]' | ArrayValue.class + '{string : "s", integer : 1, boolean : true}' | ObjectValue.class + } + + @Unroll + def 'parse type literals #typeLiteral'() { + expect: + Parser.parseType(typeLiteral).isEqualTo(expectedType) + + where: + typeLiteral | expectedType + "Foo" | new TypeName("Foo") + "String" | new TypeName("String") + "[String]" | new ListType(new TypeName("String")) + "Boolean!" | new NonNullType(new TypeName("Boolean")) + "Boolean !" | new NonNullType(new TypeName("Boolean")) + "Boolean, !" | new NonNullType(new TypeName("Boolean")) + "[Int]!" | new NonNullType(new ListType(new TypeName("Int"))) + "[[String!]]" | new ListType(new ListType(new NonNullType(new TypeName("String")))) + } + + @Unroll + def 'parse invalid type literal #typeLiteral'() { + when: + Parser.parseType(typeLiteral) + + then: + thrown(InvalidSyntaxException) + + where: + typeLiteral | _ + "[String" | _ + "[[Int]" | _ + "![Foo]" | _ + "!Boolean" | _ + "[Int!" | _ + "[String]]" | _ + } + + def "ignored chars can be set on or off"() { + def s = ''' + + type X { + s : String + } + ''' + + def captureIgnoredCharsFALSE = ParserOptions.newParserOptions().captureIgnoredChars(false).build() + def captureIgnoredCharsTRUE = ParserOptions.newParserOptions().captureIgnoredChars(true).build() + + when: "explicitly off" + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(s).parserOptions(captureIgnoredCharsFALSE).build() + def doc = new Parser().parseDocument(parserEnvironment) + def type = doc.getDefinitionsOfType(ObjectTypeDefinition)[0] + then: + type.getIgnoredChars() == IgnoredChars.EMPTY + + when: "implicitly off it uses the system default" + doc = new Parser().parseDocument(s) + type = doc.getDefinitionsOfType(ObjectTypeDefinition)[0] + + then: + type.getIgnoredChars() == IgnoredChars.EMPTY + !ParserOptions.getDefaultParserOptions().isCaptureIgnoredChars() + + when: "explicitly on" + + parserEnvironment = ParserEnvironment.newParserEnvironment().document(s).parserOptions(captureIgnoredCharsTRUE).build() + doc = new Parser().parseDocument(parserEnvironment) + type = doc.getDefinitionsOfType(ObjectTypeDefinition)[0] + + then: + type.getIgnoredChars() != IgnoredChars.EMPTY + !type.getIgnoredChars().getLeft().isEmpty() + !type.getIgnoredChars().getRight().isEmpty() + + + when: "implicitly on if the static is set" + ParserOptions.setDefaultParserOptions(captureIgnoredCharsTRUE) + doc = new Parser().parseDocument(s) + type = doc.getDefinitionsOfType(ObjectTypeDefinition)[0] + + then: + type.getIgnoredChars() != IgnoredChars.EMPTY + !type.getIgnoredChars().getLeft().isEmpty() + !type.getIgnoredChars().getRight().isEmpty() + } + + def "allow braced escaped unicode"() { + given: + def input = ''' + { + foo(arg: "\\u{1F37A}") + } + ''' + + when: + Document document = Parser.parse(input) + OperationDefinition operationDefinition = (document.definitions[0] as OperationDefinition) + def field = operationDefinition.getSelectionSet().getSelections()[0] as Field + def argValue = field.arguments[0].value as StringValue + + then: + argValue.getValue() == "🍺" // contains the beer icon U+1F37A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + def "allow surrogate pairs escaped unicode"() { + given: + def input = ''' + { + foo(arg: "\\ud83c\\udf7a") + } + ''' + + when: + Document document = Parser.parse(input) + OperationDefinition operationDefinition = (document.definitions[0] as OperationDefinition) + def field = operationDefinition.getSelectionSet().getSelections()[0] as Field + def argValue = field.arguments[0].value as StringValue + + then: + argValue.getValue() == "🍺" // contains the beer icon U+1F37 A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + def "invalid surrogate pair - no trailing value"() { + given: + def input = ''' + { + foo(arg: "\\ud83c") + } + ''' + + when: + Parser.parse(input) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\ud83c' at line 3 column 24" + } + + def "invalid surrogate pair - no leading value"() { + given: + def input = ''' + { + foo(arg: "\\uDC00") + } + ''' + + when: + Parser.parse(input) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Trailing surrogate must be preceded with a leading surrogate. Offending token '\\uDC00' at line 3 column 24" + } + + def "source locations are on by default but can be turned off"() { + when: + def options = ParserOptions.getDefaultParserOptions() + + def document = new Parser().parseDocument("{ f }") + then: + options.isCaptureSourceLocation() + document.getSourceLocation() == new SourceLocation(1, 1) + document.getDefinitions()[0].getSourceLocation() == new SourceLocation(1, 1) + + when: + options = ParserOptions.newParserOptions().captureSourceLocation(false).build() + def parserEnvironment = ParserEnvironment.newParserEnvironment().document("{ f }").parserOptions(options).build() + document = new Parser().parseDocument(parserEnvironment) + + then: + !options.isCaptureSourceLocation() + document.getSourceLocation() == SourceLocation.EMPTY + document.getDefinitions()[0].getSourceLocation() == SourceLocation.EMPTY + } + + def "escape characters correctly printed when printing AST"() { + given: + def env = ParserEnvironment.newParserEnvironment() + .document(src) + .parserOptions( + ParserOptions.newParserOptions() + .captureIgnoredChars(true) + .build() + ) + .build() + + when: + // Parse the original Document + def doc = Parser.parse(env) + // Print the AST + def printed = AstPrinter.printAst(doc) + // Re-parse printed AST + def reparsed = Parser.parse(printed) + + then: + noExceptionThrown() // The printed AST was re-parsed without exception + + when: + def reparsedPrinted = AstPrinter.printAst(reparsed) + + then: + reparsedPrinted == printed // Re-parsing and re-printing produces the same result + + where: + src | _ + "\"\\\"\" scalar A" | _ + "\"\f\" scalar A" | _ + "\"\b\" scalar A" | _ + "\"\t\" scalar A" | _ + } + + def "can redact tokens in InvalidSyntax parser error message"() { + given: + def input = '''""" scalar ComputerSaysNo''' + + when: // Default options do not redact error messages + Parser.parse(input) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == '''Invalid syntax with ANTLR error 'token recognition error at: '""" scalar ComputerSaysNo'' at line 1 column 1''' + + when: // Enable redacted parser error messages + def redactParserErrorMessages = ParserOptions.newParserOptions().redactTokenParserErrorMessages(true).build() + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(input).parserOptions(redactParserErrorMessages).build() + new Parser().parseDocument(parserEnvironment) + + then: + InvalidSyntaxException redactedError = thrown(InvalidSyntaxException) + redactedError.message == "Invalid syntax at line 1 column 1" + } + + def "can redact tokens in InvalidSyntaxBail parser error message"() { + given: + def input = ''' + query { + computer says no!!!!!! + ''' + + when: // Default options do not redact error messages + Parser.parse(input) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid syntax with offending token '!' at line 3 column 31" + + when: // Enable redacted parser error messages + def redactParserErrorMessages = ParserOptions.newParserOptions().redactTokenParserErrorMessages(true).build() + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(input).parserOptions(redactParserErrorMessages).build() + new Parser().parseDocument(parserEnvironment) + + then: + InvalidSyntaxException redactedError = thrown(InvalidSyntaxException) + redactedError.message == "Invalid syntax at line 3 column 31" + } + + def "can redact tokens in InvalidSyntaxMoreTokens parser error message"() { + given: + def input = "{profile(id:117) {computer, says, no}}}" + + + when: // Default options do not redact error messages + Parser.parse(input) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid syntax encountered. There are extra tokens in the text that have not been consumed. Offending token '}' at line 1 column 39" + + when: // Enable redacted parser error messages + def redactParserErrorMessages = ParserOptions.newParserOptions().redactTokenParserErrorMessages(true).build() + def parserEnvironment = ParserEnvironment.newParserEnvironment().document(input).parserOptions(redactParserErrorMessages).build() + new Parser().parseDocument(parserEnvironment) + + then: + InvalidSyntaxException redactedError = thrown(InvalidSyntaxException) + redactedError.message == "Invalid syntax encountered. There are extra tokens in the text that have not been consumed. Offending token at line 1 column 39" + } } diff --git a/src/test/groovy/graphql/parser/IDLParserTest.groovy b/src/test/groovy/graphql/parser/SDLParserTest.groovy similarity index 77% rename from src/test/groovy/graphql/parser/IDLParserTest.groovy rename to src/test/groovy/graphql/parser/SDLParserTest.groovy index f01f691927..928619cf23 100644 --- a/src/test/groovy/graphql/parser/IDLParserTest.groovy +++ b/src/test/groovy/graphql/parser/SDLParserTest.groovy @@ -30,6 +30,7 @@ import graphql.language.OperationTypeDefinition import graphql.language.ScalarTypeDefinition import graphql.language.ScalarTypeExtensionDefinition import graphql.language.SchemaDefinition +import graphql.language.TypeDefinition import graphql.language.TypeName import graphql.language.UnionTypeDefinition import graphql.language.UnionTypeExtensionDefinition @@ -38,14 +39,14 @@ import spock.lang.Specification import java.util.stream.Collectors -class IDLParserTest extends Specification { +class SDLParserTest extends Specification { - boolean isEqual(Node node1, Node node2) { - return new AstComparator().isEqual(node1, node2) + static boolean isEqual(Node node1, Node node2) { + return AstComparator.isEqual(node1, node2) } - boolean isEqual(List node1, List node2) { - return new AstComparator().isEqual(node1, node2) + static boolean isEqual(List node1, List node2) { + return AstComparator.isEqual(node1, node2) } @@ -134,7 +135,7 @@ fieldName(arg1:SomeType={one:1} @argDirective(a1:\$v1)):[Elm] @fieldDirective(co field.directive(new Directive("fieldDirective", [new Argument("cool", new BooleanValue(true))])) def defaultValue = ObjectValue.newObjectValue() - defaultValue.objectField(new ObjectField("one", new IntValue(1))) + defaultValue.objectField(new ObjectField("one", new IntValue(BigInteger.valueOf(1)))) def arg1 = InputValueDefinition.newInputValueDefinition().name("arg1").type(new TypeName("SomeType")).defaultValue(defaultValue.build()) arg1.directive(new Directive("argDirective", [new Argument("a1", new VariableReference("v1"))])) @@ -176,7 +177,7 @@ TWO @second, def "object schema"() { given: def input = """ -type TypeName implements Impl1 Impl2 @typeDirective(a1:\$v1) { +type TypeName implements Impl1 & Impl2 @typeDirective(a1:\$v1) { one: Number two: Number @second cmd(arg1:[Number]=[1] arg2:String @secondArg(cool:true)): Function @@ -197,7 +198,7 @@ cmd(arg1:[Number]=[1] arg2:String @secondArg(cool:true)): Function def cmdField = FieldDefinition.newFieldDefinition().name("cmd").type(new TypeName("Function")) cmdField.inputValueDefinition(new InputValueDefinition("arg1", new ListType(new TypeName("Number")), - new ArrayValue([new IntValue(1)]))) + new ArrayValue([new IntValue(BigInteger.valueOf(1))]))) def arg2 = InputValueDefinition.newInputValueDefinition().name("arg2").type(new TypeName("String")) arg2.directive(new Directive("secondArg", [new Argument("cool", new BooleanValue(true))])) cmdField.inputValueDefinition(arg2.build()) @@ -240,18 +241,14 @@ union UnionName @d1 @d2 = Type1 | Type2 """ and: "expected schema" - def schema = UnionTypeDefinition.newUnionTypeDefinition().name("UnionName") - schema.directive(new Directive("d1")) - schema.directive(new Directive("d2")) - schema.memberType(new TypeName("Type1")) - schema.memberType(new TypeName("Type2")) + def unionTypeTestDefinition = unionDefinition() when: def document = new Parser().parseDocument(input) then: document.definitions.size() == 1 - isEqual(document.definitions[0], schema.build()) + isEqual(document.definitions[0], unionTypeTestDefinition) } def "input object schema"() { @@ -270,7 +267,7 @@ three: [Number] @three schema.directive(new Directive("d2")) schema.inputValueDefinition(new InputValueDefinition("one", new TypeName("Number"))) - def two = InputValueDefinition.newInputValueDefinition().name("two").type(new TypeName("Number")).defaultValue(new IntValue(1)) + def two = InputValueDefinition.newInputValueDefinition().name("two").type(new TypeName("Number")).defaultValue(new IntValue(BigInteger.valueOf(1))) two.directive(new Directive("two")) schema.inputValueDefinition(two.build()) @@ -335,7 +332,7 @@ withArgs(arg1:[Number]=[1] arg2:String @secondArg(cool:true)): Function def withArgs = FieldDefinition.newFieldDefinition().name("withArgs").type(new TypeName("Function")) withArgs.inputValueDefinition(new InputValueDefinition("arg1", new ListType(new TypeName("Number")), - new ArrayValue([new IntValue(1)]))) + new ArrayValue([new IntValue(BigInteger.valueOf(1))]))) def arg2 = InputValueDefinition.newInputValueDefinition().name("arg2").type(new TypeName("String")) arg2.directive(new Directive("secondArg", [new Argument("cool", new BooleanValue(true))])) @@ -350,7 +347,7 @@ withArgs(arg1:[Number]=[1] arg2:String @secondArg(cool:true)): Function isEqual(document.definitions[0], schema.build()) } - def "directive schema"() { + def "directive definition schema"() { given: def input = """ directive @DirectiveName(arg1:String arg2:Int=23) on FIELD | QUERY @@ -359,9 +356,10 @@ directive @DirectiveName(arg1:String arg2:Int=23) on FIELD | QUERY and: "expected schema" def schema = DirectiveDefinition.newDirectiveDefinition().name("DirectiveName") schema.inputValueDefinition(new InputValueDefinition("arg1", new TypeName("String"))) - schema.inputValueDefinition(new InputValueDefinition("arg2", new TypeName("Int"), new IntValue(23))) + schema.inputValueDefinition(new InputValueDefinition("arg2", new TypeName("Int"), new IntValue(BigInteger.valueOf(23)))) schema.directiveLocation(new DirectiveLocation("FIELD")) schema.directiveLocation(new DirectiveLocation("QUERY")) + schema.repeatable(false) when: def document = new Parser().parseDocument(input) @@ -371,14 +369,34 @@ directive @DirectiveName(arg1:String arg2:Int=23) on FIELD | QUERY isEqual(document.definitions[0], schema.build()) } + def "repeatable directive definition schema"() { + given: + def input = """ +directive @DirectiveName(arg1:String arg2:Int=23) repeatable on FIELD | QUERY +""" - List commentContent(List comments) { - comments.stream().map { c -> c.content }.collect(Collectors.toList()) + and: "expected schema" + def schema = DirectiveDefinition.newDirectiveDefinition().name("DirectiveName") + schema.inputValueDefinition(new InputValueDefinition("arg1", new TypeName("String"))) + schema.inputValueDefinition(new InputValueDefinition("arg2", new TypeName("Int"), new IntValue(BigInteger.valueOf(23)))) + schema.directiveLocation(new DirectiveLocation("FIELD")) + schema.directiveLocation(new DirectiveLocation("QUERY")) + schema.repeatable(true) + + when: + def document = new Parser().parseDocument(input) + + then: + document.definitions.size() == 1 + isEqual(document.definitions[0], schema.build()) } - def "comment support on definitions"() { + static List commentContent(List comments) { + comments.stream().map { c -> c.content }.collect(Collectors.toList()) + } + def "comment support on definitions"() { given: def input = """ @@ -555,12 +573,6 @@ input Gun { bar : String baz : String } - - type Foo2 implements Bar Baz { - bar : String - baz : String - } - """ when: def document = new Parser().parseDocument(input) @@ -571,13 +583,6 @@ input Gun { typeDef.getImplements().size() == 2 (typeDef.getImplements()[0] as TypeName).getName() == 'Bar' (typeDef.getImplements()[1] as TypeName).getName() == 'Baz' - - then: - ObjectTypeDefinition typeDef2 = document.definitions[3] as ObjectTypeDefinition - typeDef2.getName() == 'Foo2' - typeDef2.getImplements().size() == 2 - (typeDef2.getImplements()[0] as TypeName).getName() == 'Bar' - (typeDef2.getImplements()[1] as TypeName).getName() == 'Baz' } def "object type extensions"() { @@ -795,13 +800,15 @@ input Gun { when: def defaultDoc = new Parser().parseDocument(input) - def namedDocNull = new Parser().parseDocument(input, null) - def namedDoc = new Parser().parseDocument(input, sourceName) + Reader reader = MultiSourceReader.newMultiSourceReader() + .string(input, sourceName) + .build(); + + def namedDoc = new Parser().parseDocument(reader) then: defaultDoc.definitions[0].sourceLocation.sourceName == null - namedDocNull.definitions[0].sourceLocation.sourceName == null namedDoc.definitions[0].sourceLocation.sourceName == sourceName } @@ -811,5 +818,255 @@ input Gun { assert asClass == definition.getClass(), "Could not find expected definition of type " + asClass.getName() + " but was " + definition.getClass().getName() return asClass.cast(definition) } + + def "able to allow special names for field names"() { + given: + + def input = """ + type Query { + true: String + fragment: String + false: String + on: String + null: String + } + """ + when: + Document document = Parser.parse(input) + String name = (document.definitions[0] as TypeDefinition).name + + then: + name == "Query" + } + + + def "parse description with emoji characters"() { + def input = ''' + enum ReactionContent { + """ + Represents the 😕 emoji. + """ + someValue + } + ''' + when: + Document document = Parser.parse(input) + EnumTypeDefinition enumType = (document.definitions[0] as EnumTypeDefinition) + String description = enumType.enumValueDefinitions[0].description.content + + then: + description == "Represents the 😕 emoji." + } + + def unionDefinition() { + def schema = UnionTypeDefinition.newUnionTypeDefinition().name("UnionName") + schema.directive(new Directive("d1")) + schema.directive(new Directive("d2")) + schema.memberType(new TypeName("Type1")) + schema.memberType(new TypeName("Type2")) + return schema.build() + } + + def "union with two types and leading pipe"() { + given: + def input = """ +union UnionName @d1 @d2 = | Type1 | Type2 +""" + + when: + def document = new Parser().parseDocument(input) + + then: + document.definitions.size() == 1 + isEqual(document.definitions[0], unionDefinition()) + } + + def "union with leading pipe"() { + given: + def input = """ +union UnionName @d1 @d2 = | Type1 +""" + + and: "expected schema" + def schema = UnionTypeDefinition.newUnionTypeDefinition().name("UnionName") + schema.directive(new Directive("d1")) + schema.directive(new Directive("d2")) + schema.memberType(new TypeName("Type1")) + + when: + def document = new Parser().parseDocument(input) + + then: + document.definitions.size() == 1 + isEqual(document.definitions[0], schema.build()) + } + + def "union fails with double leading pipe"() { + given: + def input = """ +union UnionName @d1 @d2 = || Type1 | Type2 +""" + + when: + new Parser().parseDocument(input) + + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 2 + e.location.column == 28 + e.offendingToken == "|" + } + + def "union fails with double inner pipe"() { + given: + def input = """ +union UnionName @d1 @d2 = Type1 || Type2 +""" + + when: + new Parser().parseDocument(input) + + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 2 + e.location.column == 34 + e.offendingToken == "|" + } + + def "union fails with trailing pipe"() { + given: + def input = """ +union UnionName @d1 @d2 = Type1 | Type2 | +""" + + when: + new Parser().parseDocument(input) + + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 3 + e.location.column == 1 + e.offendingToken == "" + } + + def "directive with two locations and leading pipe"() { + given: + def input = """ +directive @myDirective on + | OBJECT + | INTERFACE +""" + + when: + def directive = new Parser().parseDocument(input) + + then: + directive.definitions.size() == 1 + def first = directive.definitions[0] + first instanceof DirectiveDefinition + def resultDirective = (DirectiveDefinition) first + resultDirective.name == "myDirective" + resultDirective.inputValueDefinitions.size() == 0 + resultDirective.directiveLocations.size() == 2 + resultDirective.directiveLocations[0].name == "OBJECT" + resultDirective.directiveLocations[1].name == "INTERFACE" + } + + def "directive with leading pipe"() { + given: + def input = """ +directive @myDirective on + | OBJECT +""" + + when: + def directive = new Parser().parseDocument(input) + + then: + directive.definitions.size() == 1 + def first = directive.definitions[0] + first instanceof DirectiveDefinition + def resultDirective = (DirectiveDefinition) first + resultDirective.name == "myDirective" + resultDirective.inputValueDefinitions.size() == 0 + resultDirective.directiveLocations.size() == 1 + resultDirective.directiveLocations[0].name == "OBJECT" + } + + def "directive with leading pipe INLINE"() { + given: + def input = """ +directive @myDirective on | OBJECT +""" + + when: + def directive = new Parser().parseDocument(input) + + then: + directive.definitions.size() == 1 + def first = directive.definitions[0] + first instanceof DirectiveDefinition + def resultDirective = (DirectiveDefinition) first + resultDirective.name == "myDirective" + resultDirective.inputValueDefinitions.size() == 0 + resultDirective.directiveLocations.size() == 1 + resultDirective.directiveLocations[0].name == "OBJECT" + } + + def "directive fails with double leading pipe"() { + given: + def input = """ +directive @myDirective on || OBJECT | INTERFACE +""" + + when: + new Parser().parseDocument(input) + + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 2 + e.location.column == 28 + e.offendingToken == "|" + } + + def "directive fails with double inner pipe between locations"() { + given: + def input = """ +directive @myDirective on OBJECT || INTERFACE +""" + + when: + new Parser().parseDocument(input) + + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 2 + e.location.column == 35 + e.offendingToken == "|" + } + + def "directive fails with trailing pipe"() { + given: + def input = """ +directive @myDirective on + OBJECT + | INTERFACE | +""" + + when: + new Parser().parseDocument(input) + + then: + def e = thrown(InvalidSyntaxException) + + e.location.line == 5 + e.location.column == 1 + e.offendingToken == "" + } } diff --git a/src/test/groovy/graphql/parser/SafeTokenReaderTest.groovy b/src/test/groovy/graphql/parser/SafeTokenReaderTest.groovy new file mode 100644 index 0000000000..e96fe93b9c --- /dev/null +++ b/src/test/groovy/graphql/parser/SafeTokenReaderTest.groovy @@ -0,0 +1,18 @@ +package graphql.parser + +import spock.lang.Specification + +class SafeTokenReaderTest extends Specification { + + def "will count how many its read and stop after max"() { + when: + StringReader sr = new StringReader("0123456789") + SafeTokenReader safeReader = new SafeTokenReader(sr, 5, + { Integer maxChars -> throw new RuntimeException("max " + maxChars) }) + safeReader.readLine() + + then: + def rte = thrown(RuntimeException) + rte.message == "max 5" + } +} diff --git a/src/test/groovy/graphql/parser/SafeTokenSourceTest.groovy b/src/test/groovy/graphql/parser/SafeTokenSourceTest.groovy new file mode 100644 index 0000000000..cf8b34658e --- /dev/null +++ b/src/test/groovy/graphql/parser/SafeTokenSourceTest.groovy @@ -0,0 +1,94 @@ +package graphql.parser + +import graphql.parser.antlr.GraphqlLexer +import org.antlr.v4.runtime.CharStreams +import org.antlr.v4.runtime.Token +import spock.lang.Specification + +import java.util.function.BiConsumer + +class SafeTokenSourceTest extends Specification { + + private void consumeAllTokens(SafeTokenSource tokenSource) { + def nextToken = tokenSource.nextToken() + while (nextToken != null && nextToken.getType() != Token.EOF) { + nextToken = tokenSource.nextToken() + } + } + + private GraphqlLexer lexer(doc) { + def charStream = CharStreams.fromString(doc) + def graphqlLexer = new GraphqlLexer(charStream) + graphqlLexer + } + + def "can call back to the consumer when max whitespace tokens are encountered"() { + + def offendingText = " " * 1000 + GraphqlLexer graphqlLexer = lexer(""" + query foo { _typename $offendingText @lol@lol@lol } + """) + when: + Token offendingToken = null + BiConsumer onTooManyTokens = { max, token -> + offendingToken = token + throw new IllegalStateException("stop at $max") + } + def tokenSource = new SafeTokenSource(graphqlLexer, 50, 1000, onTooManyTokens) + + consumeAllTokens(tokenSource) + assert false, "This is not meant to actually consume all tokens" + + then: + def e = thrown(IllegalStateException) + e.message == "stop at 1000" + offendingToken != null + offendingToken.getChannel() == 3 // whitespace + offendingToken.getText() == " " + } + + def "can call back to the consumer when max grammar tokens are encountered"() { + + def offendingText = "@lol" * 1000 + GraphqlLexer graphqlLexer = lexer(""" + query foo { _typename $offendingText } + """) + when: + Token offendingToken = null + BiConsumer onTooManyTokens = { max, token -> + offendingToken = token + throw new IllegalStateException("stop at $max") + } + def tokenSource = new SafeTokenSource(graphqlLexer, 1000, 200_000, onTooManyTokens) + + consumeAllTokens(tokenSource) + assert false, "This is not meant to actually consume all tokens" + + then: + def e = thrown(IllegalStateException) + e.message == "stop at 1000" + offendingToken != null + offendingToken.getChannel() == 0 // grammar + } + + def "can safely get to the end of text if its ok"() { + + GraphqlLexer graphqlLexer = lexer(""" + query foo { _typename @lol@lol@lol } + """) + when: + Token offendingToken = null + BiConsumer onTooManyTokens = { max, token -> + offendingToken = token + throw new IllegalStateException("stop at $max") + } + def tokenSource = new SafeTokenSource(graphqlLexer, 1000, 200_000, onTooManyTokens) + + consumeAllTokens(tokenSource) + + then: + noExceptionThrown() + offendingToken == null + } + +} diff --git a/src/test/groovy/graphql/parser/StringValueParsingTest.groovy b/src/test/groovy/graphql/parser/StringValueParsingTest.groovy index be23da614d..2142c84175 100644 --- a/src/test/groovy/graphql/parser/StringValueParsingTest.groovy +++ b/src/test/groovy/graphql/parser/StringValueParsingTest.groovy @@ -1,15 +1,23 @@ package graphql.parser +import graphql.i18n.I18n +import graphql.language.SourceLocation import spock.lang.Specification +import static java.util.Arrays.asList +import static java.util.stream.Collectors.joining + class StringValueParsingTest extends Specification { + def i18n = I18n.i18n(I18n.BundleType.Parsing, Locale.ENGLISH) + def sourceLocation = SourceLocation.EMPTY + def "parsing quoted string should work"() { given: def input = '''"simple quoted"''' when: - String parsed = StringValueParsing.parseSingleQuotedString(input) + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) then: parsed == "simple quoted" @@ -20,7 +28,7 @@ class StringValueParsingTest extends Specification { def input = '''"{\"name\": \"graphql\", \"year\": 2015}"''' when: - String parsed = StringValueParsing.parseSingleQuotedString(input) + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) then: parsed == '''{\"name\": \"graphql\", \"year\": 2015}''' @@ -31,36 +39,34 @@ class StringValueParsingTest extends Specification { def input = '''"""''' when: - String parsed = StringValueParsing.parseSingleQuotedString(input) + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) then: parsed == '''"''' } - def "parsing emoji should work"() { - // needs surrogate pairs for this emoji + def "parsing beer stein as surrogate pair should work"() { given: def input = '''"\\ud83c\\udf7a"''' when: - String parsed = StringValueParsing.parseSingleQuotedString(input) + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) then: parsed == '''🍺''' // contains the beer icon U+1F37A : http://www.charbase.com/1f37a-unicode-beer-mug } - def "parsing simple unicode should work"() { + def "parsing simple unicode should work - Basic Multilingual Plane (BMP)"() { given: - def input = '''"\\u56fe"''' + def input = '''"\\u5564\\u9152"''' when: - String parsed = StringValueParsing.parseSingleQuotedString(input) + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) then: - parsed == '''图''' + parsed == '''啤酒''' } - def "parsing triple quoted string should work"() { given: def input = '''"""triple quoted"""''' @@ -95,36 +101,129 @@ class StringValueParsingTest extends Specification { parsed == '''| inner quoted """ part but with all others left as they are \\n with slash escaped chars \\b\\ud83c\\udf7a\\r\\t\\n |''' } - def "remove common indentation works as per spec"() { + def joinLines(String... args) { + asList(args).stream().collect(joining('\n')) + } + + def "removes uniform indentation from a string"() { + given: + def input = joinLines( + '', + ' Hello,', + ' World!', + '', + ' Yours,', + ' GraphQL.', + ) + + when: + String parsed = StringValueParsing.removeIndentation(input) + + then: + def expected = joinLines('Hello,', ' World!', '', 'Yours,', ' GraphQL.') + parsed == expected + } + + def "removes empty leading and trailing lines"() { + given: + def input = joinLines( + '', + '', + ' Hello,', + ' World!', + '', + ' Yours,', + ' GraphQL.', + '', + '', + ) + + when: + String parsed = StringValueParsing.removeIndentation(input) + + then: + def expected = joinLines('Hello,', ' World!', '', 'Yours,', ' GraphQL.') + parsed == expected + } + + def "removes blank leading and trailing lines"() { given: - def input = ''' + def input = joinLines( + ' ', + ' ', + ' Hello,', + ' World!', + '', + ' Yours,', + ' GraphQL.', + ' ', + ' ', + ) + when: + String parsed = StringValueParsing.removeIndentation(input) - line A - line B - line C - line D - line E - line F - line G - line H + then: + def expected = joinLines('Hello,', ' World!', '', 'Yours,', ' GraphQL.') + parsed == expected + } + + def "retains indentation from first line"() { + given: + def input = joinLines( + ' Hello,', + ' World!', + '', + ' Yours,', + ' GraphQL.', + ) + + when: + String parsed = StringValueParsing.removeIndentation(input) + then: + def expected = joinLines(' Hello,', ' World!', '', 'Yours,', ' GraphQL.') + parsed == expected + } -''' // 2 empty lines at the start and end + def "does not alter trailing spaces"() { + given: + def input = joinLines( + ' ', + ' Hello, ', + ' World! ', + ' ', + ' Yours, ', + ' GraphQL. ', + ' ', + ) when: String parsed = StringValueParsing.removeIndentation(input) then: - def expected = ''' line A - line B - line C - line D - line E - line F - line G - line H''' + def expected = joinLines( + 'Hello, ', + ' World! ', + ' ', + 'Yours, ', + ' GraphQL. ', + ) parsed == expected + } + def "1438 - losing one character when followed by a space is fixed"() { + given: + def input = '''L1 +L 2 +L 3''' + when: + String parsed = StringValueParsing.removeIndentation(input) + + then: + def expected = '''L1 +L 2 +L 3''' + parsed == expected } } diff --git a/src/test/groovy/graphql/parser/StringValueParsingUnicodeTest.groovy b/src/test/groovy/graphql/parser/StringValueParsingUnicodeTest.groovy new file mode 100644 index 0000000000..192f3b0097 --- /dev/null +++ b/src/test/groovy/graphql/parser/StringValueParsingUnicodeTest.groovy @@ -0,0 +1,260 @@ +package graphql.parser + +import graphql.i18n.I18n +import graphql.language.SourceLocation +import spock.lang.Specification + +class StringValueParsingUnicodeTest extends Specification { + + def i18n = I18n.i18n(I18n.BundleType.Parsing, Locale.ENGLISH) + def sourceLocation = SourceLocation.EMPTY + + /** + * Implements RFC to support full Unicode https://github.com/graphql/graphql-spec/pull/849 + * + * Key changes + * + SourceCharacters now include all Unicode scalar values. Previously only included up to U+FFFF (Basic Multilingual Plane). + * + SourceCharacters now include control characters. Previously certain control characters were excluded. + * + Surrogate pair validation added. + * + * Note that "unescaped" Unicode characters such as 🍺 are handled by ANTLR grammar. + * "Escaped" Unicode characters such as \\u{1F37A} are handled by StringValueParsing. + */ + + // With this RFC, escaped code points outside the Basic Multilingual Plane (e.g. emojis) can be parsed. + def "parsing beer stein as escaped unicode"() { + given: + def input = '''"\\u{1F37A} hello"''' + + when: + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + parsed == '''🍺 hello''' // contains the beer icon U+1F37A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + def "parsing beer stein without escaping"() { + given: + def input = '''"🍺 hello"''' + + when: + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + parsed == '''🍺 hello''' // contains the beer icon U+1F37A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + /** + * From the RFC: + * For legacy reasons, a *supplementary character* may be escaped by two + * fixed-width unicode escape sequences forming a *surrogate pair*. For example + * the input `"\\uD83D\\uDCA9"` is a valid {StringValue} which represents the same + * Unicode text as `"\\u{1F4A9}"`. While this legacy form is allowed, it should be + * avoided as a variable-width unicode escape sequence is a clearer way to encode + * such code points. + * + * Valid surrogate pair combinations: + * + If {leadingValue} is >= 0xD800 and <= 0xDBFF (a *Leading Surrogate*): + * + Assert {trailingValue} is >= 0xDC00 and <= 0xDFFF (a *Trailing Surrogate*). + */ + def "invalid surrogate pair - no trailing value"() { + given: + def input = '''"\\uD83D hello"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\uD83D' at line -1 column -1" + } + + def "invalid surrogate pair - end of string"() { + given: + def input = '''"\\uD83D"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\uD83D' at line -1 column -1" + } + + def "invalid surrogate pair - invalid trailing value"() { + given: + def input = '''"\\uD83D\\uDBFF"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\uDBFF' at line -1 column -1" + } + + def "invalid surrogate pair - no leading value"() { + given: + def input = '''"\\uDC00"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Trailing surrogate must be preceded with a leading surrogate. Offending token '\\uDC00' at line -1 column -1" + } + + def "invalid surrogate pair - invalid leading value"() { + given: + def input = '''"\\uD700\\uDC00"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Trailing surrogate must be preceded with a leading surrogate. Offending token '\\uDC00' at line -1 column -1" + } + + def "valid surrogate pair - leading code with braces"() { + given: + def input = '''"hello \\u{d83c}\\udf7a"''' + + when: + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + parsed == '''hello 🍺''' // contains the beer icon U+1F37 A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + def "valid surrogate pair - trailing code with braces"() { + given: + def input = '''"hello \\ud83c\\u{df7a}"''' + + when: + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + parsed == '''hello 🍺''' // contains the beer icon U+1F37A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + def "valid surrogate pair - leading and trailing code with braces"() { + given: + def input = '''"hello \\u{d83c}\\u{df7a}"''' + + when: + String parsed = StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + parsed == '''hello 🍺''' // contains the beer icon U+1F37A : http://www.charbase.com/1f37a-unicode-beer-mug + } + + def "invalid surrogate pair - leading code with only \\ at end of string"() { + given: + def input = '''"hello \\u{d83c}\\"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\u{d83c}' at line -1 column -1" + } + + def "invalid surrogate pair - leading code with only \\u at end of string"() { + given: + def input = '''"hello \\u{d83c}\\u"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Incorrectly formatted escape sequence. Offending token '\\u\"' at line -1 column -1" + } + + def "invalid surrogate pair - trailing code without closing brace"() { + given: + def input = '''"hello \\u{d83c}\\u{df7a"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Incorrectly formatted escape sequence. Offending token '\\u{df7a' at line -1 column -1" + } + + def "invalid surrogate pair - invalid trailing code without unicode escape 1"() { + given: + def input = '''"hello \\u{d83c}{df7a}"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\u{d83c}' at line -1 column -1" + } + + def "invalid surrogate pair - invalid trailing code without unicode escape 2"() { + given: + def input = '''"hello \\u{d83c}df7a"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\u{d83c}' at line -1 column -1" + } + + def "invalid surrogate pair - invalid leading code"() { + given: + def input = '''"hello d83c\\u{df7a}"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Trailing surrogate must be preceded with a leading surrogate. Offending token '\\u{df7a}' at line -1 column -1" + } + + def "invalid surrogate pair - invalid leading value with braces"() { + given: + def input = '''"\\u{5B57}\\uDC00"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Trailing surrogate must be preceded with a leading surrogate. Offending token '\\uDC00' at line -1 column -1" + } + + def "invalid surrogate pair - invalid trailing value with braces"() { + given: + def input = '''"\\uD83D\\u{DBFF}"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Leading surrogate must be followed by a trailing surrogate. Offending token '\\u{DBFF}' at line -1 column -1" + } + + def "invalid unicode code point - value is too high"() { + given: + def input = '''"\\u{fffffff}"''' + + when: + StringValueParsing.parseSingleQuotedString(i18n, input,sourceLocation) + + then: + InvalidSyntaxException e = thrown(InvalidSyntaxException) + e.message == "Invalid unicode encountered. Not a valid code point. Offending token '\\u{fffffff}' at line -1 column -1" + } +} diff --git a/src/test/groovy/graphql/relay/DefaultConnectionTest.groovy b/src/test/groovy/graphql/relay/DefaultConnectionTest.groovy new file mode 100644 index 0000000000..592b18c968 --- /dev/null +++ b/src/test/groovy/graphql/relay/DefaultConnectionTest.groovy @@ -0,0 +1,27 @@ +package graphql.relay + +import com.google.common.collect.ImmutableList +import spock.lang.Specification + +class DefaultConnectionTest extends Specification { + + def "test equality and hashcode"() { + def edges1 = ImmutableList.of(new DefaultEdge("a", new DefaultConnectionCursor("a"))) + def edges2 = ImmutableList.of(new DefaultEdge("b", new DefaultConnectionCursor("b"))) + + def pageInfo1 = new DefaultPageInfo(new DefaultConnectionCursor("c"), new DefaultConnectionCursor("c"), true, false) + def pageInfo2 = new DefaultPageInfo(new DefaultConnectionCursor("d"), new DefaultConnectionCursor("d"), false, true) + + expect: + + assert new DefaultConnection(edges1, pageInfo1).equals(new DefaultConnection(edges1, pageInfo1)) + assert !new DefaultConnection(edges1, pageInfo2).equals(new DefaultConnection(edges1, pageInfo1)) + assert !new DefaultConnection(edges1, pageInfo1).equals(new DefaultConnection(edges2, pageInfo1)) + assert !new DefaultConnection(edges1, pageInfo1).equals(new DefaultConnection(edges1, pageInfo2)) + + assert new DefaultConnection(edges1, pageInfo1).hashCode() == new DefaultConnection(edges1, pageInfo1).hashCode() + assert new DefaultConnection(edges1, pageInfo2).hashCode() != new DefaultConnection(edges1, pageInfo1).hashCode() + assert new DefaultConnection(edges1, pageInfo1).hashCode() != new DefaultConnection(edges2, pageInfo1).hashCode() + assert new DefaultConnection(edges1, pageInfo1).hashCode() != new DefaultConnection(edges1, pageInfo2).hashCode() + } +} diff --git a/src/test/groovy/graphql/relay/DefaultEdgeTest.groovy b/src/test/groovy/graphql/relay/DefaultEdgeTest.groovy new file mode 100644 index 0000000000..3763a0c7ab --- /dev/null +++ b/src/test/groovy/graphql/relay/DefaultEdgeTest.groovy @@ -0,0 +1,25 @@ +package graphql.relay + +import spock.lang.Specification + +class DefaultEdgeTest extends Specification { + + def "test equality and hashcode"() { + expect: + + assert new DefaultEdge(leftNode, new DefaultConnectionCursor(leftConnectionCursor)).equals( + new DefaultEdge(rightNode, new DefaultConnectionCursor(rightConnectionCursor))) == isEqual + + assert (new DefaultEdge(leftNode, new DefaultConnectionCursor(leftConnectionCursor)).hashCode() == + new DefaultEdge(rightNode, new DefaultConnectionCursor(rightConnectionCursor)).hashCode()) == isEqual + + where: + + leftNode | leftConnectionCursor | rightNode | rightConnectionCursor || isEqual + "a" | "b" | "a" | "b" || true + "x" | "b" | "a" | "b" || false + "a" | "x" | "a" | "b" || false + "a" | "b" | "x" | "b" || false + "a" | "b" | "a" | "x" || false + } +} diff --git a/src/test/groovy/graphql/relay/DefaultPageInfoTest.groovy b/src/test/groovy/graphql/relay/DefaultPageInfoTest.groovy new file mode 100644 index 0000000000..2e370467cb --- /dev/null +++ b/src/test/groovy/graphql/relay/DefaultPageInfoTest.groovy @@ -0,0 +1,29 @@ +package graphql.relay + +import spock.lang.Specification + +class DefaultPageInfoTest extends Specification { + + def "test equality and hashcode"() { + expect: + + assert new DefaultPageInfo(new DefaultConnectionCursor(ls), new DefaultConnectionCursor(le), lp, ln).equals( + new DefaultPageInfo(new DefaultConnectionCursor(rs), new DefaultConnectionCursor(re), rp, rn)) == isEqual + + assert (new DefaultPageInfo(new DefaultConnectionCursor(ls), new DefaultConnectionCursor(le), lp, ln).hashCode() == + new DefaultPageInfo(new DefaultConnectionCursor(rs), new DefaultConnectionCursor(re), rp, rn).hashCode()) == isEqual + + where: + + ls | le | lp | ln | rs | re | rp | rn || isEqual + "a" | "b" | true | true | "a" | "b" | true | true || true + "x" | "b" | true | true | "a" | "b" | true | true || false + "a" | "x" | true | true | "a" | "b" | true | true || false + "a" | "b" | false | true | "a" | "b" | true | true || false + "a" | "b" | true | false | "a" | "b" | true | true || false + "a" | "b" | true | true | "x" | "b" | true | true || false + "a" | "b" | true | true | "a" | "x" | true | true || false + "a" | "b" | true | true | "a" | "b" | false | true || false + "a" | "b" | true | true | "a" | "b" | true | false || false + } +} diff --git a/src/test/groovy/graphql/relay/SimpleListConnectionTest.groovy b/src/test/groovy/graphql/relay/SimpleListConnectionTest.groovy index dcc0b57d3a..05e4cc607d 100644 --- a/src/test/groovy/graphql/relay/SimpleListConnectionTest.groovy +++ b/src/test/groovy/graphql/relay/SimpleListConnectionTest.groovy @@ -1,17 +1,17 @@ package graphql.relay -import graphql.execution.ExecutionContext + import graphql.schema.DataFetchingEnvironment import spock.lang.Specification import java.nio.charset.StandardCharsets -import static graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment +import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment class SimpleListConnectionTest extends Specification { DataFetchingEnvironment afterCursorEnv(String cursor) { - newDataFetchingEnvironment().executionContext(Mock(ExecutionContext)).arguments(["after": cursor]).build() + newDataFetchingEnvironment().arguments(["after": cursor]).build() } def createCursor(int offset) { @@ -72,7 +72,7 @@ class SimpleListConnectionTest extends Specification { def "can accept a list with nulls"() { given: def dataWithNull = ["a", null, "b"] - def env = newDataFetchingEnvironment().executionContext(Mock(ExecutionContext)).build() + def env = newDataFetchingEnvironment().build() when: def connection = new SimpleListConnection(dataWithNull).get(env) @@ -81,4 +81,16 @@ class SimpleListConnectionTest extends Specification { connection.getEdges().size() == 3 connection.getEdges().get(1).getNode() == null } + + def "can accept an empty list"() { + given: + def empty = [] + def env = newDataFetchingEnvironment().build() + + when: + def connection = new SimpleListConnection(empty).get(env) + + then: + connection.getEdges().size() == 0 + } } diff --git a/src/test/groovy/graphql/schema/CoercingTest.groovy b/src/test/groovy/graphql/schema/CoercingTest.groovy new file mode 100644 index 0000000000..9504243c4d --- /dev/null +++ b/src/test/groovy/graphql/schema/CoercingTest.groovy @@ -0,0 +1,300 @@ +package graphql.schema + +import graphql.ExecutionInput +import graphql.GraphQLContext +import graphql.TestUtil +import graphql.analysis.MaxQueryDepthInstrumentation +import graphql.language.ArrayValue +import graphql.language.BooleanValue +import graphql.language.FloatValue +import graphql.language.IntValue +import graphql.language.NullValue +import graphql.language.ObjectValue +import graphql.language.StringValue +import graphql.language.VariableReference +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.TypeRuntimeWiring +import spock.lang.Specification + +import java.time.ZonedDateTime + +import static graphql.schema.GraphQLScalarType.newScalar + +class CoercingTest extends Specification { + + GraphQLScalarType mapLikeScalar = newScalar().name("MapLike").description("MapLike").coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + return dataFetcherResult + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + return input + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + return parseLiteral(input, [:]) + } + + @Override + Object parseLiteral(Object input, Map variables) throws CoercingParseLiteralException { + if (input instanceof StringValue) { + return ((StringValue) input).getValue() + } + if (input instanceof IntValue) { + return ((IntValue) input).getValue() + } + if (input instanceof FloatValue) { + return ((FloatValue) input).getValue() + } + if (input instanceof BooleanValue) { + return ((BooleanValue) input).isValue() + } + if (input instanceof ObjectValue) { + Map obj = new LinkedHashMap<>() + ((ObjectValue) input).getObjectFields().forEach({ + fld -> + def value = parseLiteral(fld.getValue(), variables) + obj.put(fld.getName(), value) + }) + return obj + } + if (input instanceof VariableReference) { + def name = ((VariableReference) input).getName() + return variables.get(name) + } + if (input instanceof ArrayValue) { + return ((ArrayValue) input).getValues().collect({ v -> parseLiteral(v, variables) }) + } + if (input instanceof NullValue) { + return null + } + throw new CoercingParseLiteralException() + } + }) + .build() + + def "end to end test of coercing with variables references"() { + def spec = ''' + + scalar MapLike + + type Query { + field(argument : MapLike) : MapLike + } + ''' + DataFetcher df = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + def argument = environment.getArgument("argument") + return argument + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Query") + .dataFetcher("field", df)) + .scalar(mapLikeScalar) + .build() + + + def graphQL = TestUtil.graphQL(spec, runtimeWiring).build() + def executionInput = ExecutionInput.newExecutionInput() + .variables([ + strVar: "strVar", + intVar: 999 + ]) + .query(''' + query Q($strVar : String) { + field(argument : { s : $strVar, i : 666 }) + } + ''') + .build() + + when: + def er = graphQL.execute(executionInput) + then: + er.errors.isEmpty() + er.data == [field: [s: "strVar", i: 666]] + } + + GraphQLScalarType customScalar = newScalar().name("CustomScalar").description("CustomScalar").coercing(new Coercing() { + @Override + Object serialize(Object input) throws CoercingSerializeException { + if ("bang" == String.valueOf(input)) { + throw CoercingSerializeException.newCoercingSerializeException() + .message("serialize message").extensions([serialize: true]).build() + } + return input + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + if ("bang" == String.valueOf(input)) { + throw CoercingParseValueException.newCoercingParseValueException() + .message("parseValue message").extensions([parseValue: true]).build() + } + return input + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + StringValue sv = (StringValue) input + if ("bang" == String.valueOf(sv.getValue())) { + throw CoercingParseLiteralException.newCoercingParseLiteralException() + .message("parseLiteral message").extensions([parseLiteral: true]).build() + } + return new StringValue(String.valueOf("input")) + } + }) + .build() + + def customScalarSDL = ''' + scalar CustomScalar + + type Query { + field(arg1 : CustomScalar, arg2 : CustomScalar) : CustomScalar + } + ''' + DataFetcher customScalarDF = { env -> return "bang" } + + def customScalarRuntimeWiring = RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("field", customScalarDF)) + .scalar(customScalar) + .build() + + def customScalarSchema = TestUtil.graphQL(customScalarSDL, customScalarRuntimeWiring).build() + + def "custom coercing parseValue messages become graphql errors"() { + + when: + def ei = ExecutionInput.newExecutionInput().query(''' + query($v1 : CustomScalar) { + field(arg1:$v1, arg2:"ok") + } + ''') + .variables([v1: "bang"]) + .build() + def er = customScalarSchema.execute(ei) + then: + er.errors.size() == 1 + er.errors[0].message.contains("parseValue message") + er.errors[0].extensions == [parseValue: true] + } + + def "custom coercing parseLiteral messages become graphql errors"() { + + when: + def ei = ExecutionInput.newExecutionInput().query(''' + query($v1 : CustomScalar) { + field(arg1:$v1, arg2:"bang") + } + ''') + .variables([v1: "ok"]) + .build() + def er = customScalarSchema.execute(ei) + then: + er.errors.size() == 1 + er.errors[0].message == "Validation error (WrongType@[field]) : argument 'arg2' with value 'StringValue{value='bang'}' is not a valid 'CustomScalar' - parseLiteral message" + er.errors[0].extensions == [parseLiteral: true] + } + + def "custom coercing serialize messages become graphql errors"() { + + when: + def ei = ExecutionInput.newExecutionInput().query(''' + query { + field + } + ''') + .root([field: "bang"]) + .build() + def er = customScalarSchema.execute(ei) + then: + er.errors.size() == 1 + er.errors[0].message.contains("Can't serialize value (/field) : serialize message") + er.errors[0].extensions == [serialize: true] + } + + static def parseDateTimeValue(Object input) { + try { + if (input instanceof StringValue) { + return ZonedDateTime.parse(((StringValue) input).getValue()) + } else if (input instanceof String) { + return ZonedDateTime.parse((String) input) + } else throw new IllegalArgumentException("Unexpected input type: ${input.getClass()}") + } catch (Exception e) { + throw new CoercingParseValueException("Failed to parse input value $input as ZonedDateTime", e) + } + } + + GraphQLScalarType zonedDateTimeLikeScalar = newScalar().name("ZonedDateTimeLike").description("ZonedDateTimeLike").coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + return dataFetcherResult + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + return parseDateTimeValue(input) + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + return input + } + + @Override + StringValue valueToLiteral(Object input, GraphQLContext graphQLContext, Locale locale) { + return new StringValue(input.toString()) + } + }) + .build() + + def "custom scalars are only coerced once - end to end test with execution and instrumentation"() { + def spec = ''' + scalar ZonedDateTimeLike + + type Query { + field(argument : ZonedDateTimeLike) : ZonedDateTimeLike + } + ''' + DataFetcher df = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) { + def argument = environment.getArgument("argument") + return argument + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Query") + .dataFetcher("field", df)) + .scalar(zonedDateTimeLikeScalar) + .build() + + def executionInput = ExecutionInput.newExecutionInput() + .variables([zonedDateTime: "2022-05-16T19:52:37Z"]) + .query(''' + query myZonedDateTimeQuery($zonedDateTime : ZonedDateTimeLike) { + field(argument : $zonedDateTime) + }''') + .build() + + MaxQueryDepthInstrumentation maximumQueryDepthInstrumentation = new MaxQueryDepthInstrumentation(7) + + def graphQL = TestUtil.graphQL(spec, runtimeWiring).instrumentation(maximumQueryDepthInstrumentation).build() + + when: + def er = graphQL.execute(executionInput) + + then: + // If variables were coerced twice, would expect an IllegalArgumentException to be thrown, + // as the ZonedDateTime custom scalar parser can only parse strings, not instances of ZonedDateTime + notThrown(Exception) + er.errors.isEmpty() + er.data == [field: ZonedDateTime.parse("2022-05-16T19:52:37Z")] + } +} diff --git a/src/test/groovy/graphql/schema/DataFetcherFactoriesTest.groovy b/src/test/groovy/graphql/schema/DataFetcherFactoriesTest.groovy index 5050ba0ef1..3fb58ed1e7 100644 --- a/src/test/groovy/graphql/schema/DataFetcherFactoriesTest.groovy +++ b/src/test/groovy/graphql/schema/DataFetcherFactoriesTest.groovy @@ -32,7 +32,17 @@ class DataFetcherFactoriesTest extends Specification { def fetcherFactory = DataFetcherFactories.useDataFetcher(pojoDF) when: - def value = fetcherFactory.get(null).get(null) + def value = fetcherFactory.get((GraphQLFieldDefinition)null).get(null) + + then: + value == "goodbye" + } + + def "will use given df via field"() { + def fetcherFactory = DataFetcherFactories.useDataFetcher(pojoDF) + + when: + def value = fetcherFactory.get((GraphQLFieldDefinition) null).get(null) then: value == "goodbye" diff --git a/src/test/groovy/graphql/schema/DataFetcherSelectionTest.groovy b/src/test/groovy/graphql/schema/DataFetcherSelectionTest.groovy deleted file mode 100644 index 0c265a9e20..0000000000 --- a/src/test/groovy/graphql/schema/DataFetcherSelectionTest.groovy +++ /dev/null @@ -1,262 +0,0 @@ -package graphql.schema - -import graphql.ExecutionInput -import graphql.GraphQL -import graphql.StarWarsData -import graphql.TestUtil -import graphql.execution.FieldCollector -import graphql.language.AstPrinter -import graphql.language.Field -import graphql.schema.idl.MapEnumValuesProvider -import graphql.schema.idl.RuntimeWiring -import spock.lang.Specification - -import java.util.stream.Collectors - -import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring - -/** - * #377 - this test proves that a data fetcher has enough information to allow sub request - * proxying or fine grained control of the fields in an object that should be returned - */ -class DataFetcherSelectionTest extends Specification { - - class SelectionCapturingDataFetcher implements DataFetcher { - final DataFetcher delegate - final FieldCollector fieldCollector - final Map captureMap - - final List>> captureFieldArgs - - SelectionCapturingDataFetcher(DataFetcher delegate, Map captureMap, List>> captureFieldArgs) { - this.delegate = delegate - this.fieldCollector = new FieldCollector() - this.captureMap = captureMap - this.captureFieldArgs = captureFieldArgs; - } - - @Override - Object get(DataFetchingEnvironment environment) { - - // - // we capture the inner field selections of the current field that is being fetched - // this would allow proxying or really fine grained controlled object retrieval - // if one was so included - // - def selectionSet = environment.getSelectionSet().get() - def arguments = environment.getSelectionSet().getArguments() - captureFieldArgs.add(arguments) - - if (!selectionSet.isEmpty()) { - for (String fieldName : selectionSet.keySet()) { - String ast = captureFields(selectionSet.get(fieldName)) - captureMap.put(fieldName, ast) - } - } - - return delegate.get(environment) - } - - String captureFields(List fields) { - def collect = fields.stream().map({ f -> AstPrinter.printAst(f) }).collect(Collectors.joining(";")) - return collect - } - } - - // side effect captured here - Map captureMap = new HashMap<>() - List>> captureFieldArgs = [] - - SelectionCapturingDataFetcher captureSelection(DataFetcher delegate) { - return new SelectionCapturingDataFetcher(delegate, captureMap, captureFieldArgs) - } - - def episodeValuesProvider = new MapEnumValuesProvider([NEWHOPE: 4, EMPIRE: 5, JEDI: 6]) - def episodeWiring = newTypeWiring("Episode").enumValues(episodeValuesProvider).build() - - RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring() - .type(newTypeWiring("QueryType") - .dataFetchers( - [ - "hero" : captureSelection(new StaticDataFetcher(StarWarsData.getArtoo())), - "human": captureSelection(StarWarsData.getHumanDataFetcher()), - "droid": captureSelection(StarWarsData.getDroidDataFetcher()) - ]) - ) - .type(newTypeWiring("Human") - .dataFetcher("friends", captureSelection(StarWarsData.getFriendsDataFetcher())) - ) - .type(newTypeWiring("Droid") - .dataFetcher("friends", captureSelection(StarWarsData.getFriendsDataFetcher())) - ) - - .type(newTypeWiring("Character") - .typeResolver(StarWarsData.getCharacterTypeResolver()) - ) - .type(episodeWiring) - .build() - - def executableStarWarsSchema = TestUtil.schemaFile("starWarsSchemaWithArguments.graphqls", wiring) - - void setup() { - captureMap.clear() - captureFieldArgs.clear() - - } - - def "field selection can be captured via data environment"() { - - def query = """ - query CAPTURED_VIA_DF { - - luke: human(id: "1000") { - ...HumanFragment # this is a named fragment - homePlanet - } - - leia: human(id: "1003") { - ... on Character { # this is an inline fragment - id - friends { - name - } - } - appearsIn - } - } - fragment HumanFragment on Human { - name - ...FriendsAndFriendsFragment - - } - - fragment FriendsAndFriendsFragment on Character { - friends { - name - friends { - name - } - } - } - - """ - - - expect: - when: - GraphQL.newGraphQL(executableStarWarsSchema).build().execute(query).data - - then: - - // captures each stage as it descends - captureMap == [ - "appearsIn" : "appearsIn", - "friends/friends/name": "name", - "friends/friends" : "friends {\n" + - " name\n" + - "}", - "friends/name" : "name", - "friends" : "friends {\n" + - " name\n" + - "}", - "homePlanet" : "homePlanet", - "id" : "id", - "name" : "name" - - ] - } - - def "#595 - field selection works for List types"() { - - def query = """ - query CAPTURED_VIA_DF { - luke: human(id: "1000") { - name - friends { - name - } - homePlanet - } - } - """ - - - expect: - when: - GraphQL.newGraphQL(executableStarWarsSchema).build().execute(query).data - - then: - - captureMap == [ - "name" : "name", - "friends" : "friends {\n" + - " name\n" + - "}", - "friends/name": "name", - "homePlanet" : "homePlanet", - ] - } - - def "#832 - field selection captures field arguments"() { - - def query = ''' - query CAPTURED_VIA_DF($localeVar : String) { - luke: human(id: "1000") { - name - homePlanet(coordsFormat: "republic") - } - - leia: human(id: "1003") { - ... on Human { # this is an inline fragment - name - homePlanet(includeMoons : true, locale: $localeVar) - } - } - - vader: human(id: "1003") { - ...CharacterFragment # this is an named fragment - } - } - - fragment CharacterFragment on Character { - name - friends(separationCount : 4) { - id - } - } - - ''' - - - expect: - when: - ExecutionInput input = ExecutionInput.newExecutionInput().query(query).variables([localeVar: "AU"]).build() - def executionResult = GraphQL.newGraphQL(executableStarWarsSchema).build().execute(input) - - then: - - executionResult.errors.isEmpty() - - captureFieldArgs == [ - [ - name : [:], - homePlanet: [ - includeMoons: false, - coordsFormat: "republic" - ] - ], - - [ - name : [:], - homePlanet: [ - includeMoons: true, - locale : "AU" - ] - ], - [name: [:], friends: [separationCount: 4], "friends/id": [:]], - [id: [:]] - ] - - } - -} diff --git a/src/test/groovy/graphql/schema/DataFetchingEnvironmentImplTest.groovy b/src/test/groovy/graphql/schema/DataFetchingEnvironmentImplTest.groovy new file mode 100644 index 0000000000..561b881bd2 --- /dev/null +++ b/src/test/groovy/graphql/schema/DataFetchingEnvironmentImplTest.groovy @@ -0,0 +1,161 @@ +package graphql.schema + +import graphql.GraphQLContext +import graphql.execution.CoercedVariables +import graphql.execution.ExecutionId +import graphql.execution.ExecutionStepInfo +import graphql.execution.instrumentation.dataloader.DataLoaderDispatchingContextKeys +import graphql.language.Argument +import graphql.language.Field +import graphql.language.FragmentDefinition +import graphql.language.OperationDefinition +import graphql.language.StringValue +import graphql.language.TypeName +import org.dataloader.BatchLoader +import org.dataloader.DataLoaderFactory +import org.dataloader.DataLoaderRegistry +import spock.lang.Specification + +import java.util.concurrent.CompletableFuture + +import static graphql.StarWarsSchema.starWarsSchema +import static graphql.TestUtil.mergedField +import static graphql.TestUtil.toDocument +import static graphql.execution.ExecutionContextBuilder.newExecutionContextBuilder +import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment + +class DataFetchingEnvironmentImplTest extends Specification { + + def frag = FragmentDefinition.newFragmentDefinition().name("frag").typeCondition(new TypeName("t")).build() + + def dataLoader = DataLoaderFactory.newDataLoader({ keys -> CompletableFuture.completedFuture(keys) } as BatchLoader) + def operationDefinition = new OperationDefinition("q") + def document = toDocument("{ f }") + def executionId = ExecutionId.from("123") + def fragmentByName = [frag: frag] + def variables = [var: "able"] + def dataLoaderRegistry = new DataLoaderRegistry().register("dataLoader", dataLoader) + + def executionContext = newExecutionContextBuilder() + .root("root") + .graphQLContext(GraphQLContext.of(["key": "context"])) + .executionId(executionId) + .operationDefinition(operationDefinition) + .document(document) + .coercedVariables(CoercedVariables.of(variables)) + .graphQLSchema(starWarsSchema) + .fragmentsByName(fragmentByName) + .dataLoaderRegistry(dataLoaderRegistry) + .build() + + def "immutable arguments"() { + def dataFetchingEnvironment = newDataFetchingEnvironment(executionContext).arguments([arg: "argVal"]) + .build() + + when: + def value = dataFetchingEnvironment.getArguments().get("arg") + then: + value == "argVal" + when: + dataFetchingEnvironment.getArguments().put("arg", "some other value") + then: + thrown(UnsupportedOperationException) + } + + def "copying works as expected from execution context"() { + when: + def dfe = newDataFetchingEnvironment(executionContext) + .build() + dfe.getGraphQlContext().put(DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING, chainedDataLoaderEnabled) + then: + dfe.getRoot() == "root" + dfe.getGraphQlContext().get("key") == "context" + dfe.getGraphQLSchema() == starWarsSchema + dfe.getDocument() == document + dfe.getVariables() == variables + dfe.getOperationDefinition() == operationDefinition + dfe.getExecutionId() == executionId + dfe.getDataLoaderRegistry() == executionContext.getDataLoaderRegistry() + dfe.getDataLoader("dataLoader") == executionContext.getDataLoaderRegistry().getDataLoader("dataLoader") || + dfe.getDataLoader("dataLoader").delegate == executionContext.getDataLoaderRegistry().getDataLoader("dataLoader") + where: + chainedDataLoaderEnabled << [true, false] + } + + def "create environment from existing one will copy everything to new instance"() { + def dfe = newDataFetchingEnvironment() + .context("Test Context") // Retain deprecated builder for coverage + .graphQLContext(GraphQLContext.of(["key": "context", (DataLoaderDispatchingContextKeys.ENABLE_DATA_LOADER_CHAINING): chainedDataLoaderEnabled])) + .source("Test Source") + .root("Test Root") + .fieldDefinition(Mock(GraphQLFieldDefinition)) + .fieldType(Mock(GraphQLOutputType)) + .executionStepInfo(Mock(ExecutionStepInfo)) + .parentType(Mock(GraphQLType)) + .graphQLSchema(Mock(GraphQLSchema)) + .fragmentsByName(fragmentByName) + .executionId(Mock(ExecutionId)) + .selectionSet(Mock(DataFetchingFieldSelectionSet)) + .operationDefinition(operationDefinition) + .document(document) + .variables(variables) + .dataLoaderRegistry(dataLoaderRegistry) + .locale(Locale.CANADA) + .localContext("localContext") + .build() + + when: + def dfeCopy = newDataFetchingEnvironment(dfe).build() + + then: + dfe != dfeCopy + dfe.getContext() == dfeCopy.getContext() // Retain deprecated method for coverage + dfe.getGraphQlContext() == dfeCopy.getGraphQlContext() + dfe.getSource() == dfeCopy.getSource() + dfe.getRoot() == dfeCopy.getRoot() + dfe.getFieldDefinition() == dfeCopy.getFieldDefinition() + dfe.getFieldType() == dfeCopy.getFieldType() + dfe.getExecutionStepInfo() == dfeCopy.getExecutionStepInfo() + dfe.getParentType() == dfeCopy.getParentType() + dfe.getGraphQLSchema() == dfeCopy.getGraphQLSchema() + dfe.getFragmentsByName() == dfeCopy.getFragmentsByName() + dfe.getExecutionId() == dfeCopy.getExecutionId() + dfe.getSelectionSet() == dfeCopy.getSelectionSet() + dfe.getDocument() == dfeCopy.getDocument() + dfe.getOperationDefinition() == dfeCopy.getOperationDefinition() + dfe.getVariables() == dfeCopy.getVariables() + dfe.getDataLoader("dataLoader") == executionContext.getDataLoaderRegistry().getDataLoader("dataLoader") || + dfe.getDataLoader("dataLoader").delegate == dfeCopy.getDataLoader("dataLoader").delegate + dfe.getLocale() == dfeCopy.getLocale() + dfe.getLocalContext() == dfeCopy.getLocalContext() + where: + chainedDataLoaderEnabled << [true, false] + + } + + def "get or default support"() { + when: + def dfe = newDataFetchingEnvironment(executionContext) + .arguments([x: "y"]) + .build() + then: + dfe.getArgument("z") == null + dfe.getArgumentOrDefault("z", "default") == "default" + dfe.getArgument("x") == "y" + dfe.getArgumentOrDefault("x", "default") == "y" + } + + def "deprecated getFields() method works"() { + when: + Argument argument = new Argument("arg1", new StringValue("argVal")) + Field field = new Field("someField", [argument]) + + def environment = newDataFetchingEnvironment(executionContext) + .mergedField(mergedField(field)) + .build() + + then: + environment.fields == [field] // Retain deprecated method for test coverage + } + +} diff --git a/src/test/groovy/graphql/schema/DataFetchingFieldSelectionSetImplTest.groovy b/src/test/groovy/graphql/schema/DataFetchingFieldSelectionSetImplTest.groovy index e54f4833fa..ff80ad9b32 100644 --- a/src/test/groovy/graphql/schema/DataFetchingFieldSelectionSetImplTest.groovy +++ b/src/test/groovy/graphql/schema/DataFetchingFieldSelectionSetImplTest.groovy @@ -1,30 +1,26 @@ package graphql.schema -import graphql.Scalars +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.StarWarsData import graphql.TestUtil -import graphql.execution.ExecutionContextBuilder -import graphql.execution.ExecutionId -import graphql.language.Document -import graphql.language.Field -import graphql.language.FragmentDefinition -import graphql.language.NodeUtil -import graphql.language.OperationDefinition +import graphql.schema.idl.RuntimeWiring import spock.lang.Specification -class DataFetchingFieldSelectionSetImplTest extends Specification { - - def starWarsSchema = TestUtil.schemaFile("starWarsSchemaWithArguments.graphqls") +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring +class DataFetchingFieldSelectionSetImplTest extends Specification { - def query = ''' + def starWarsQuery = ''' { human { name appearsIn - friends(separationCount : 2) { + friends { name appearsIn - friends(separationCount : 5) { + friends { name appearsIn } @@ -43,30 +39,29 @@ class DataFetchingFieldSelectionSetImplTest extends Specification { } ''' - List firstFields(Document document) { - (document.definitions[0] as OperationDefinition).selectionSet.selections - .collect({ node -> (Field) node }) + DataFetchingFieldSelectionSet selectionSet = null + DataFetcher humanDF = { DataFetchingEnvironment env -> + selectionSet = env.getSelectionSet() + return StarWarsData.humanDataFetcher.get(env) } - Map getFragments(Document document) { - NodeUtil.GetOperationResult getOperationResult = NodeUtil.getOperation(document, null) - getOperationResult.fragmentsByName - } + RuntimeWiring starWarsRuntimeWiring = newRuntimeWiring() + .type(newTypeWiring("QueryType").dataFetcher("human", humanDF)) + .type(newTypeWiring("Character").typeResolver({ env -> env.getSchema().getType("Human") })) + .build() - def "glob pattern matching works"() { + def starWarsSchema = TestUtil.schemaFile("starWarsSchemaWithArguments.graphqls", starWarsRuntimeWiring) + def starWarsGraphql = GraphQL.newGraphQL(starWarsSchema).build() - def document = TestUtil.parseQuery(query) - List fields = firstFields(document) - - def executionContext = ExecutionContextBuilder.newExecutionContextBuilder() - .executionId(ExecutionId.generate()) - .fragmentsByName(getFragments(document)) - .graphQLSchema(starWarsSchema).build() + def "glob pattern matching works"() { - def selectionSet = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, starWarsSchema.getType('Human'), fields) + def ei = ExecutionInput.newExecutionInput(starWarsQuery).build() + def er = starWarsGraphql.execute(ei) expect: + er.errors.isEmpty() + !selectionSet.contains(null) !selectionSet.contains("") !selectionSet.contains("rubbish") @@ -107,75 +102,882 @@ class DataFetchingFieldSelectionSetImplTest extends Specification { !selectionSet.contains("?/name") !selectionSet.contains("friends/friends/rubbish") + + // + // allOf matching + selectionSet.containsAllOf("name") + selectionSet.containsAllOf("name", "appearsIn", "friends") + !selectionSet.containsAllOf("name", "appearsIn", "friends", "notPresent") + + // + // anyOf matching + selectionSet.containsAnyOf("name") + selectionSet.containsAnyOf("name", "appearsIn", "friends", "notPresent") + !selectionSet.containsAnyOf("notPresent") + !selectionSet.containsAnyOf("notPresent", "alsoNotPresent") } - def "test field selection set capture works"() { - def document = TestUtil.parseQuery(query) + def relayQuery = ''' + { + things(first: 10) { + nodes { + ... thingInfo @skip(if:false) + ... dateInfo @skip(if:true) + ...fix + } + edges { + cursor + node { + description + status { + ...status @skip(if:false) + } + } + } + totalCount + } + } + + fragment thingInfo on Thing { + key + summary + status { + ...status + } + } + + fragment fix on Thing { + stuff { + name + } + } + + fragment status on Status { + name + } + + fragment dateInfo on Thing { + createdDate + lastUpdatedDate + } + ''' - List fields = firstFields(document) + DataFetcher thingConnectionDF = { DataFetchingEnvironment env -> + selectionSet = env.getSelectionSet() + return [totalCount: 0] + } - def executionContext = ExecutionContextBuilder.newExecutionContextBuilder() - .executionId(ExecutionId.generate()) - .fragmentsByName(getFragments(document)) - .graphQLSchema(starWarsSchema).build() + RuntimeWiring relayRuntimeWiring = newRuntimeWiring() + .type(newTypeWiring("Query").dataFetcher("things", thingConnectionDF)) + .type(newTypeWiring("Node").typeResolver({ env -> env.getSchema().getType("Thing") })) + .build() - def selectionSet = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, starWarsSchema.getType('Human'), fields) + def relaySchema = TestUtil.schemaFile("thingRelaySchema.graphqls", relayRuntimeWiring) + def relayGraphql = GraphQL.newGraphQL(relaySchema).build() - def fieldMap = selectionSet.get() - expect: - fieldMap.keySet() == [ - "name", - "appearsIn", - "friends", - "friends/name", - "friends/appearsIn", - "friends/friends", - "friends/friends/name", - "friends/friends/appearsIn", - ] as Set + def "test getting sub selected fields by name"() { + + when: + def ei = ExecutionInput.newExecutionInput(relayQuery).build() + def er = relayGraphql.execute(ei) + + then: + er.getErrors().isEmpty() + + def selectedNodesField = selectionSet.getFields("nodes")[0] + selectedNodesField.getName() == "nodes" + GraphQLTypeUtil.simplePrint(selectedNodesField.type) == "[Thing]" + selectedNodesField.getSelectionSet().contains("key") + selectedNodesField.getSelectionSet().contains("summary") + selectedNodesField.getSelectionSet().contains("status") + selectedNodesField.getSelectionSet().contains("status/name") + selectedNodesField.getSelectionSet().contains("status*") + selectedNodesField.getSelectionSet().contains("status/*") + + // directives are respected + !selectedNodesField.getSelectionSet().contains("createdDate") + !selectedNodesField.getSelectionSet().contains("lastUpdatedDate") + + when: + def selectedKeyField = selectedNodesField.getSelectionSet().getFields("key")[0] + + then: + selectedKeyField.getName() == "key" + GraphQLTypeUtil.simplePrint(selectedKeyField.type) == "String" + + when: + def selectedStatusField = selectedNodesField.getSelectionSet().getFields("status")[0] + + then: + selectedStatusField.getName() == "status" + GraphQLTypeUtil.simplePrint(selectedStatusField.type) == "Status" + selectedStatusField.getSelectionSet().contains("name") + + // jump straight to compound fq name (which is 2 down from 'nodes') + when: + def selectedStatusNameField = selectedNodesField.getSelectionSet().getFields("status/name")[0] + + then: + selectedStatusNameField.getName() == "name" + GraphQLTypeUtil.simplePrint(selectedStatusNameField.type) == "String" } + def "test getting sub selected fields by glob"() { - def "test field argument capture works"() { + when: + def ei = ExecutionInput.newExecutionInput(relayQuery).build() + def er = relayGraphql.execute(ei) - def document = TestUtil.parseQuery(query) + then: + er.getErrors().isEmpty() + List selectedUnderNodesAster = selectionSet.getFields("nodes/*") - List fields = firstFields(document) + selectedUnderNodesAster.size() == 4 + def sortedSelectedUnderNodesAster = new ArrayList<>(selectedUnderNodesAster).sort({ sf -> sf.name }) - def executionContext = ExecutionContextBuilder.newExecutionContextBuilder() - .executionId(ExecutionId.generate()) - .fragmentsByName(getFragments(document)) - .graphQLSchema(starWarsSchema).build() + def fieldNames = sortedSelectedUnderNodesAster.collect({ sf -> sf.name }) + fieldNames == ["key", "status", "stuff", "summary"] - def selectionSet = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, starWarsSchema.getType('Human'), fields) + GraphQLTypeUtil.simplePrint(sortedSelectedUnderNodesAster[0].type) == "String" + GraphQLTypeUtil.simplePrint(sortedSelectedUnderNodesAster[1].type) == "Status" + GraphQLTypeUtil.simplePrint(sortedSelectedUnderNodesAster[2].type) == "Stuff" + GraphQLTypeUtil.simplePrint(sortedSelectedUnderNodesAster[3].type) == "String" - expect: + // descend one down from here Status.name which has not further sub selection + when: + def statusName = sortedSelectedUnderNodesAster[1].getSelectionSet().getFields("name")[0] + + then: + statusName.name == "name" + GraphQLTypeUtil.simplePrint(statusName.type) == "String" + statusName.getSelectionSet().getFields().isEmpty() + } - selectionSet.arguments['name'] == [:] - selectionSet.arguments['friends'] == [separationCount: 2] - selectionSet.arguments['friends/friends'] == [separationCount: 5] + def "test that aster aster is equal to get all"() { + when: + def ei = ExecutionInput.newExecutionInput(relayQuery).build() + def er = relayGraphql.execute(ei) + + then: + er.getErrors().isEmpty() + List allFieldsViaAsterAster = selectionSet.getFields("**") + List allFields = selectionSet.getFields() + + then: + + allFieldsViaAsterAster.size() == 14 + allFields.size() == 14 + def allFieldsViaAsterAsterSorted = new ArrayList<>(allFieldsViaAsterAster).sort({ sf -> sf.qualifiedName }) + def allFieldsSorted = new ArrayList<>(allFields).sort({ sf -> sf.qualifiedName }) + + def expectedFieldNames = [ + "edges", + "edges/cursor", + "edges/node", + "edges/node/description", + "edges/node/status", + "edges/node/status/name", + "nodes", + "nodes/key", + "nodes/status", + "nodes/status/name", + "nodes/stuff", + "nodes/stuff/name", + "nodes/summary", + "totalCount" + ] + allFieldsViaAsterAsterSorted.collect({ sf -> sf.qualifiedName }) == expectedFieldNames + allFieldsSorted.collect({ sf -> sf.qualifiedName }) == expectedFieldNames + + when: + def expectedFullyQualifiedFieldNames = [ + "ThingConnection.edges", + "ThingConnection.edges/ThingEdge.cursor", + "ThingConnection.edges/ThingEdge.node", + "ThingConnection.edges/ThingEdge.node/Thing.description", + "ThingConnection.edges/ThingEdge.node/Thing.status", + "ThingConnection.edges/ThingEdge.node/Thing.status/Status.name", + "ThingConnection.nodes", + "ThingConnection.nodes/Thing.key", + "ThingConnection.nodes/Thing.status", + "ThingConnection.nodes/Thing.status/Status.name", + "ThingConnection.nodes/Thing.stuff", + "ThingConnection.nodes/Thing.stuff/Stuff.name", + "ThingConnection.nodes/Thing.summary", + "ThingConnection.totalCount" + ] + then: + allFieldsViaAsterAsterSorted.collect({ sf -> sf.fullyQualifiedName }) == expectedFullyQualifiedFieldNames + allFieldsSorted.collect({ sf -> sf.fullyQualifiedName }) == expectedFullyQualifiedFieldNames } - def "test field type capture works"() { + def "fields are returned in pre order"() { + + when: + def ei = ExecutionInput.newExecutionInput(relayQuery).build() + def er = relayGraphql.execute(ei) + + then: + er.getErrors().isEmpty() + + List fieldsGlob = selectionSet.getFields("**") + List fields = selectionSet.getFields() + + def expectedFieldName = [ + "nodes", + "nodes/key", + "nodes/summary", + "nodes/status", + "nodes/status/name", + "nodes/stuff", + "nodes/stuff/name", + "edges", + "edges/cursor", + "edges/node", + "edges/node/description", + "edges/node/status", + "edges/node/status/name", + "totalCount" + ] + + then: + fieldsGlob.collect({ field -> field.qualifiedName }) == expectedFieldName + fields.collect({ field -> field.qualifiedName }) == expectedFieldName + } - def document = TestUtil.parseQuery(query) - List fields = firstFields(document) + def "immediate fields followed by fields are computed"() { + + when: + def ei = ExecutionInput.newExecutionInput(relayQuery).build() + def er = relayGraphql.execute(ei) + + then: + er.getErrors().isEmpty() + + then: + List immediateFields = selectionSet.getImmediateFields() + + then: + def expectedImmediateFieldName = [ + "nodes", + "edges", + "totalCount" + ] + + immediateFields.collect({ field -> field.qualifiedName }) == expectedImmediateFieldName + + then: + List fieldsGlob = selectionSet.getFields("**") + List fields = selectionSet.getFields() + + def expectedFieldName = [ + "nodes", + "nodes/key", + "nodes/summary", + "nodes/status", + "nodes/status/name", + "nodes/stuff", + "nodes/stuff/name", + "edges", + "edges/cursor", + "edges/node", + "edges/node/description", + "edges/node/status", + "edges/node/status/name", + "totalCount" + ] + + then: + fieldsGlob.collect({ field -> field.qualifiedName }) == expectedFieldName + fields.collect({ field -> field.qualifiedName }) == expectedFieldName + } - def executionContext = ExecutionContextBuilder.newExecutionContextBuilder() - .executionId(ExecutionId.generate()) - .fragmentsByName(getFragments(document)) - .graphQLSchema(starWarsSchema).build() + def petSDL = ''' + type Query { + petUnion : PetUnion + pet(qualifier : String) : Pet + leads : [Lead] + } + + interface Pet { + name(nameArg : String) : String + pet(qualifier : String) : Pet + petUnion : PetUnion + lead : Lead + } + + type Dog implements Pet { + name(nameArg : String) : String + pet(qualifier : String) : Pet + petUnion : PetUnion + lead : Lead + woof : String + } - def selectionSet = DataFetchingFieldSelectionSetImpl.newCollector(executionContext, starWarsSchema.getType('Human'), fields) + type Bird implements Pet { + name(nameArg : String) : String + pet(qualifier : String) : Pet + petUnion : PetUnion + lead : Lead + tweet : String + } + + type Cat implements Pet { + name(nameArg : String) : String + pet(qualifier : String) : Pet + petUnion : PetUnion + lead : Lead + meow : String + } + + type Lead { + material : String + } + + union PetUnion = Dog | Cat + + ''' - expect: + def lassie = [name: "lassie", lead: [material: "leather"]] + def grumpyCat = [name: "grumpCat", pet: lassie, petUnion: lassie, lead: [material: "leather"]] + def fido = [name: "fido", pet: grumpyCat, petUnion: grumpyCat, lead: [material: "leather"]] + + DataFetchingFieldSelectionSet petSelectionSet = null + DataFetcher petDF = { DataFetchingEnvironment env -> + petSelectionSet = env.getSelectionSet() + return fido + } + DataFetchingFieldSelectionSet petUnionSelectionSet = null + DataFetcher petUnionDF = { DataFetchingEnvironment env -> + petUnionSelectionSet = env.getSelectionSet() + return fido + } + + DataFetchingFieldSelectionSet leadsSelectionSet = null + DataFetcher leadsDF = { DataFetchingEnvironment env -> + leadsSelectionSet = env.getSelectionSet() + return [[material: "rope"]] + } + + DataFetchingFieldSelectionSet leadSelectionSet = null + DataFetcher leadDF = { DataFetchingEnvironment env -> + leadSelectionSet = env.getSelectionSet() + return [material: "plastic"] + } + + DataFetchingFieldSelectionSet simpleSelectionSet = null + DataFetcher simpleSF = { DataFetchingEnvironment env -> + simpleSelectionSet = env.getSelectionSet() + def pdf = PropertyDataFetcher.fetching(env.getFieldDefinition().getName()) + return pdf.get(env) + } + + def typeResolver = { e -> e.getSchema().getObjectType("Dog") } + RuntimeWiring runtimeWiring = newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("leads", leadsDF) + .dataFetcher("pet", petDF) + .dataFetcher("petUnion", petUnionDF) + ) + .type(newTypeWiring("Dog") + .dataFetcher("name", simpleSF) + .dataFetcher("lead", leadDF) + ) + .type(newTypeWiring("Pet") + .typeResolver(typeResolver) + ) + .type(newTypeWiring("PetUnion") + .typeResolver(typeResolver) + ) + .build() + + def petSchema = TestUtil.graphQL(petSDL, runtimeWiring).build() + + def "test normalised selection occurs on interfaces"() { + + when: + def query = ''' + { + pet(qualifier : "onPet") { + name(nameArg : "OnPet") + lead { material } + ... on Cat { + n1: name(nameArg : "OnCatN1") + n2: name(nameArg : "OnCatN2") + } + } + + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + petSelectionSet.contains("name") + petSelectionSet.contains("*Dog*.name") + petSelectionSet.contains("*Cat*.name") + petSelectionSet.contains("*Bird*.name") + petSelectionSet.contains("*Bird*.*") + petSelectionSet.contains("*name") + !petSelectionSet.contains("notPresent") + + petSelectionSet.containsAnyOf("name", "lead", "notPresent") + petSelectionSet.containsAllOf("name", "lead") + !petSelectionSet.containsAllOf("name", "lead", "notPresent") + + when: + def selectedFields = petSelectionSet.getFields("name") + + then: + selectedFields.size() == 3 + assertTheyAreExpected(selectedFields, ["[Bird, Cat, Dog].name", "n1:Cat.name", "n2:Cat.name"]) + + def byResultKey = petSelectionSet.getFieldsGroupedByResultKey("name") + byResultKey.size() == 3 + assertTheyAreExpected(byResultKey["name"], ["[Bird, Cat, Dog].name"]) + assertTheyAreExpected(byResultKey["n1"], ["n1:Cat.name"]) + assertTheyAreExpected(byResultKey["n2"], ["n2:Cat.name"]) + + petSelectionSet.contains("lead") + petSelectionSet.contains("lead/material") + + when: + selectedFields = petSelectionSet.getFields("*Dog*.name") + then: + selectedFields.size() == 1 + + when: + selectedFields = new ArrayList<>(petSelectionSet.getFields("*lead*")) + selectedFields.sort(byName()) + + then: + selectedFields.size() == 1 + assertTheyAreExpected(selectedFields, ["[Bird, Cat, Dog].lead"]) + // we can work our sub selection from them as well + selectedFields[0].getSelectionSet().contains("material") + !selectedFields[0].getSelectionSet().contains("rubbish") + + + when: + selectedFields = new ArrayList<>(petSelectionSet.getFields("lead/material")) + selectedFields.sort(byName()) + + then: + selectedFields.size() == 1 //one for the Cat and Dog and Bird entries + assertTheyAreExpected(selectedFields, ["Lead.material"]) + selectedFields[0].getParentField().getFullyQualifiedName() == "[Bird, Cat, Dog].lead" + + // parents can have computed selection sets + def birdLead = selectedFields[0].getParentField() + birdLead.getSelectionSet().contains("material") + !birdLead.getSelectionSet().contains("rubbish") + + when: + selectedFields = petSelectionSet.getFields("name", "lead**") + then: + selectedFields.size() == 5 + } + + def "aliasing returns values as selected fields"() { + when: + def query = ''' + { + pet { + name + ... on Dog { + aliasedName : name + } + } + + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + def selectedFields = petSelectionSet.getFields("name") + selectedFields.size() == 2 + assertTheyAreExpected(selectedFields, ["[Bird, Cat, Dog].name", "aliasedName:Dog.name"]) + + def getFields = petSelectionSet.getFields() + getFields.size() == 2 + assertTheyAreExpected(getFields, ["[Bird, Cat, Dog].name", "aliasedName:Dog.name"]) + + def byResultKey = petSelectionSet.getFieldsGroupedByResultKey() + byResultKey.size() == 2 + byResultKey.containsKey("name") + byResultKey.containsKey("aliasedName") + } + + def "test normalised selection occurs on unions"() { + + when: + def query = ''' + { + + petUnion { + ... on Cat { + name + meow + pet(qualifier : "cat") { + name + ... on Cat { + name + meow + } + } + } + ... on Dog { + name + woof + pet(qualifier : "dog") { + name + ... on Dog { + name + woof + lead { material } + } + } + } + } + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + petUnionSelectionSet.contains("name") + petUnionSelectionSet.contains("meow") + petUnionSelectionSet.contains("pet") + petUnionSelectionSet.contains("pet/name") + petUnionSelectionSet.contains("pet/woof") + petUnionSelectionSet.contains("pet/meow") + petUnionSelectionSet.contains("pet/lead") + petUnionSelectionSet.contains("pet/lead/material") + + when: + def selectedFields = petUnionSelectionSet.getFields("name") + then: + selectedFields.size() == 1 + assertTheyAreExpected(selectedFields, ["[Cat, Dog].name"]) + } + + def "test normalised selection occurs on objects"() { + + when: + def query = ''' + { + leads { + material + } + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + leadsSelectionSet.contains("material") + leadsSelectionSet.contains("material*") + leadsSelectionSet.contains("material**") + + when: + def selectedFields = leadsSelectionSet.getFields("material*") + then: + selectedFields.size() == 1 + assertTheyAreExpected(selectedFields, ["Lead.material"]) + + def byResultKey = leadsSelectionSet.getFieldsGroupedByResultKey("material") + byResultKey.size() == 1 + + } + + def "different arguments are available for different result keys"() { + when: + def query = ''' + { + pet { + name(nameArg : "OnPet") + ... on Cat { + n1: name(nameArg : "OnCatN1") + n2: name(nameArg : "OnCatN2") + } + } + + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + when: + def selectedFields = petSelectionSet.getFields("name") + + then: + selectedFields.size() == 3 + assertTheyAreExpected(selectedFields, ["[Bird, Cat, Dog].name", "n1:Cat.name", "n2:Cat.name"]) + + def byResultKey = petSelectionSet.getFieldsGroupedByResultKey("name") + byResultKey.size() == 3 + + byResultKey["name"][0].getArguments()["nameArg"] == "OnPet" + + byResultKey["n1"][0].getArguments()["nameArg"] == "OnCatN1" + byResultKey["n2"][0].getArguments()["nameArg"] == "OnCatN2" + } + + def "field definitions and object types are available"() { + when: + def query = ''' + { + pet { + name(nameArg : "OnPet") + } + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + when: + def selectedFields = new ArrayList<>(petSelectionSet.getFields("name")) + selectedFields.sort(byName()) + + then: + selectedFields[0].getObjectTypeNames() == ["Bird", "Cat", "Dog"] + selectedFields[0].getName() == "name" + + } + + def "fragments inline and defined work as expected"() { + // this is repeating a lot of the underlying NormalisedField tests - so this is not extensively tested here + when: + def query = ''' + { + pet { + name + ... on Dog { + name + } + ... CatFrag + } + } + + fragment CatFrag on Cat { + name + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + when: + def selectedFields = new ArrayList<>(petSelectionSet.getFields("name")) + selectedFields.sort(byName()) + + then: + selectedFields.size() == 1 + assertTheyAreExpected(selectedFields, ["[Bird, Cat, Dog].name"]) + + } + + def "immediate fields can be found at all levels"() { + when: + def query = ''' + { + pet { + name + ... on Dog { + woof + } + ... on Cat { + meow + } + lead { + material + } + } + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + when: + def selectedFields = petSelectionSet.getImmediateFields() + then: + assertTheyAreExpected(selectedFields, [ + "Cat.meow", "Dog.woof", "[Bird, Cat, Dog].lead", "[Bird, Cat, Dog].name"]) + + when: + selectedFields = petSelectionSet.getFields("lead") + selectedFields = selectedFields[0].getSelectionSet().getImmediateFields() + then: + assertTheyAreExpected(selectedFields, ["Lead.material"]) + } + + def "simple fields do not have selection sets"() { + when: + def query = ''' + { + pet { + name(nameArg : "OnPet") + } + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + simpleSelectionSet.getFields().isEmpty() + } + + def "selection supplier grabs the right type down the execution path"() { + when: + def query = ''' + { + pet { + lead { material } + ... on Dog { + lead { material } + } + } + } + ''' + def ei = ExecutionInput.newExecutionInput(query).build() + def er = petSchema.execute(ei) + then: + er.errors.isEmpty() + + when: + def selectedFields = leadSelectionSet.getFields() + + then: + selectedFields.size() == 1 + assertTheyAreExpected(selectedFields, ["Lead.material"]) + + when: + selectedFields = leadSelectionSet.getFields("material") + + then: + selectedFields.size() == 1 + assertTheyAreExpected(selectedFields, ["Lead.material"]) + + } + + def "issue 2381 - selected fields can work in mutations"() { + def sdl = ''' + type Query { + f :String + } + + type Mutation { + mutate : SomeType + } + + type SomeType { + selectedFieldNames : [String] + b : String + c : String + } + ''' + DataFetcher mutationDF = { DataFetchingEnvironment env -> + def selectedFields = env.getSelectionSet().getImmediateFields() + + def fieldNames = selectedFields.collect { it.getName() } + return ["selectedFieldNames": fieldNames] + } + def schema = TestUtil.schema(sdl, [Mutation: ["mutate": mutationDF]]) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def er = graphQL.execute('''mutation M { + mutate { + selectedFieldNames + b + c + } + }''') + then: + er.errors.isEmpty() + er.data["mutate"]["selectedFieldNames"] == ["selectedFieldNames", "b", "c"] + } + + def "issue 2736 - test interface fields with different output types on the implementations - covariance"() { + def sdl = """ + interface Animal { + parent: Animal + name: String + } + type Cat implements Animal { + name: String + parent: Cat + } + type Dog implements Animal { + name: String + parent: Dog + isGoodBoy: Boolean + } + type Query { + animal: Animal + } + """ + + def query = """ + { + animal { + parent { + name + } + } + } + """ + + + DataFetcher dataFetcher = { DataFetchingEnvironment env -> + selectionSet = env.getSelectionSet() + } + RuntimeWiring runtimeWiring = newRuntimeWiring() + .type(newTypeWiring("Query").dataFetcher("animal", dataFetcher)) + .type(newTypeWiring("Animal").typeResolver({ env -> env.schema.getObjectType("Dog") })) + .build() + def schema = TestUtil.schema(sdl, runtimeWiring) + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def er = graphQL.execute(query) + then: + er.errors.isEmpty() + + selectionSet.contains("parent") // short syntax + selectionSet.contains("parent/name") // short syntax + selectionSet.contains("*Cat*.parent/*Cat*.name") + selectionSet.contains("*Dog*.parent/*Dog*.name") + + } + + static Comparator byName() { + { o1, o2 -> (o1.getQualifiedName() <=> o2.getQualifiedName()) } + } + + static void assertTheyAreExpected(List selectedFields, List expected) { + def names = selectedFields.collect({ sf -> mkSpecialName(sf) }) + names.sort() + assert names == expected, "Not the right selected fields" + } - (selectionSet.definitions['name'].getType() as GraphQLNonNull).getWrappedType() == Scalars.GraphQLString - (selectionSet.definitions['friends'].getType() as GraphQLList).getWrappedType() == starWarsSchema.getType('Character') - (selectionSet.definitions['friends/friends'].getType() as GraphQLList).getWrappedType() == starWarsSchema.getType('Character') + static String mkSpecialName(SelectedField selectedField) { + def names = selectedField.getObjectTypeNames() + (selectedField.getAlias() == null ? "" : selectedField.getAlias() + ":") + (names.size() > 1 ? names.toString() : names.get(0)) + "." + selectedField.getName() } } diff --git a/src/test/groovy/graphql/schema/DelegatingDataFetchingEnvironmentTest.groovy b/src/test/groovy/graphql/schema/DelegatingDataFetchingEnvironmentTest.groovy new file mode 100644 index 0000000000..687a0f62ae --- /dev/null +++ b/src/test/groovy/graphql/schema/DelegatingDataFetchingEnvironmentTest.groovy @@ -0,0 +1,45 @@ +package graphql.schema + +import graphql.GraphQLContext +import spock.lang.Specification + +class DelegatingDataFetchingEnvironmentTest extends Specification { + + def "calls to underlying delegate"() { + + def root = "Root" + def source = "Source" + def args = [arg1: "val1"] + def variables = [var1: "varVal1"] + + def dfe = DataFetchingEnvironmentImpl.newDataFetchingEnvironment() + .source(source) + .arguments(args) + .root(root) + .graphQLContext(GraphQLContext.of(["key": "context"])) + .variables(variables) + .build() + + when: + def delegatingDFE = new DelegatingDataFetchingEnvironment(dfe) { + @Override + GraphQLContext getGraphQlContext() { + return GraphQLContext.of(["key": "overriddenContext"]) + } + + @Override + def getContext() { // Retain for test coverage + return "overriddenContext" + } + } + then: + delegatingDFE.getSource() == source + delegatingDFE.getRoot() == root + delegatingDFE.getContext() == "overriddenContext" + delegatingDFE.getGraphQlContext().get("key") == "overriddenContext" + delegatingDFE.getVariables() == variables + delegatingDFE.getArguments() == args + delegatingDFE.getArgumentOrDefault("arg1", "x") == "val1" + delegatingDFE.getArgumentOrDefault("arg2", "x") == "x" + } +} diff --git a/src/test/groovy/graphql/schema/FieldCoordinatesTest.groovy b/src/test/groovy/graphql/schema/FieldCoordinatesTest.groovy new file mode 100644 index 0000000000..e2e82da0a4 --- /dev/null +++ b/src/test/groovy/graphql/schema/FieldCoordinatesTest.groovy @@ -0,0 +1,307 @@ +package graphql.schema + +import graphql.AssertException +import spock.lang.Specification + +import static graphql.Scalars.GraphQLFloat +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLObjectType.newObject + +class FieldCoordinatesTest extends Specification { + def emptyParentName = "" + def validParentName = "Foo" + def invalidParentName = "InvalidParent;" + def validFieldName = "Bar" + def invalidFieldName = "InvalidField;" + def validSystemFieldName = "__Foo" + def invalidSystemFieldName = "Invalid" + + def validSystemFieldDef = newFieldDefinition().name(validSystemFieldName).type(GraphQLFloat).build() + def validFieldDef = newFieldDefinition().name(validFieldName).type(GraphQLFloat).build() + + GraphQLObjectType validParentType = newObject().name(validParentName).field(validFieldDef).build() + def emptyParentType = [ + getName: { -> "" }, + getFieldDefinition: { name -> validFieldDef } + ] as GraphQLFieldsContainer + def nullParentType = [ + getName: { -> null }, + getFieldDefinition: { name -> validFieldDef } + ] as GraphQLFieldsContainer + + + def "GetTypeName for standard coordinates"() { + def coordinatesFromStrings = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(validParentType, validFieldDef) + expect: + validParentName.equals(coordinatesFromStrings.getTypeName()) + validParentName.equals(coordinatesFromTypes.getTypeName()) + } + + def "GetFieldName for standard coordinates"() { + def coordinatesFromStrings = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(validParentType, validFieldDef) + expect: + validFieldName.equals(coordinatesFromStrings.getFieldName()) + validFieldName.equals(coordinatesFromTypes.getFieldName()) + } + + def "GetTypeName for system coordinates"() { + def coordinatesFromStrings = FieldCoordinates.systemCoordinates(validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(nullParentType, validFieldDef) + expect: + null == coordinatesFromStrings.getTypeName() + null == coordinatesFromTypes.getTypeName() + } + + def "GetFieldName for sytem coordinates"() { + def coordinatesFromStrings = FieldCoordinates.systemCoordinates(validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(nullParentType, validFieldDef) + expect: + validFieldName.equals(coordinatesFromStrings.getFieldName()) + validFieldName.equals(coordinatesFromTypes.getFieldName()) + } + + def "Equals true"() { + when: 'The same parent and field names are used to construct different coordinates' + def coordinatesFromStrings1 = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromStrings2 = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes1 = FieldCoordinates.coordinates(validParentType, validFieldDef) + def coordinatesFromTypes2 = FieldCoordinates.coordinates(validParentType, validFieldDef) + then: 'All coordinates should equal each other' + coordinatesFromStrings1.equals(coordinatesFromStrings2) + coordinatesFromTypes1.equals(coordinatesFromTypes2) + coordinatesFromStrings1.equals(coordinatesFromTypes1) + } + + def "Equals false"() { + when: 'The different parent and field names are used to construct different coordinates' + def coordinatesFromStrings = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(nullParentType, validFieldDef) + then: 'Coordinates should NOT equal each other' + !coordinatesFromStrings.equals(coordinatesFromTypes) + } + + def "HashCode equals"() { + when: 'The same parent and field names are used to construct different coordinates' + def coordinatesFromStrings1 = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromStrings2 = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes1 = FieldCoordinates.coordinates(validParentType, validFieldDef) + def coordinatesFromTypes2 = FieldCoordinates.coordinates(validParentType, validFieldDef) + then: 'All coordinate hash codes should equal each other' + coordinatesFromStrings1.hashCode().equals(coordinatesFromStrings2.hashCode()) + coordinatesFromTypes1.hashCode().equals(coordinatesFromTypes2.hashCode()) + coordinatesFromStrings1.hashCode().equals(coordinatesFromTypes1.hashCode()) + } + + def "HashCode NOT equals"() { + when: 'The different parent and field names are used to construct different coordinates' + def coordinatesFromStrings = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(nullParentType, validFieldDef) + then: 'Coordinate hash codes should NOT equal each other' + !coordinatesFromStrings.hashCode().equals(coordinatesFromTypes.hashCode()) + } + + def "ToString equals"() { + when: 'The same parent and field names are used to construct different coordinates' + def coordinatesFromStrings1 = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromStrings2 = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes1 = FieldCoordinates.coordinates(validParentType, validFieldDef) + then: 'All coordinate toStrings should equal each other' + coordinatesFromStrings1.toString().equals(coordinatesFromStrings2.toString()) + coordinatesFromStrings1.toString().equals(coordinatesFromTypes1.toString()) + } + + def "ToString NOT equals"() { + when: 'The different parent and field names are used to construct different coordinates' + def coordinatesFromStrings = FieldCoordinates.coordinates(validParentName, validFieldName) + def coordinatesFromTypes = FieldCoordinates.coordinates(nullParentType, validFieldDef) + then: 'Coordinate toStrings should NOT equal each other' + !coordinatesFromStrings.toString().equals(coordinatesFromTypes.toString()) + } + + def "FieldCoordinate.coordinates(GraphQLFieldsContainer, GraphQLFieldDefinition) creation failure on null parentType"() { + when: 'null parent type is given for coordinates and no validation' + FieldCoordinates.coordinates(null, validFieldDef) + then: 'throw NullPointerException' + thrown NullPointerException; + } + + def "FieldCoordinate.coordinates(GraphQLFieldsContainer, GraphQLFieldDefinition) creation failure on null fieldDefinition"() { + when: 'null field definition is given for coordinates and no validation' + FieldCoordinates.coordinates(validParentType, null as GraphQLFieldDefinition) + then: 'throw NullPointerException' + thrown NullPointerException; + } + + def "FieldCoordinate.coordinates(GraphQLFieldsContainer, GraphQLFieldDefinition) test validation"() { + when: 'parent type with null name is given for coordinates' + def coordinates = FieldCoordinates.coordinates(nullParentType, validFieldDef) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'parent type with empty name is given for coordinates' + coordinates = FieldCoordinates.coordinates(emptyParentType, validFieldDef) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'valid parent type with name and field definition are given for coordinates' + coordinates = FieldCoordinates.coordinates(validParentType, validFieldDef) + coordinates.assertValidNames() + then: 'succeed' + validParentName.equals(coordinates.getTypeName()) + validFieldName.equals(coordinates.getFieldName()) + } + + def "FieldCoordinate.coordinates(GraphQLFieldsContainer, GraphQLFieldDefinition) creation success with no validation"() { + when: 'parent type with null name is given for coordinates and no validation' + def coordinates = FieldCoordinates.coordinates(nullParentType, validFieldDef) + then: 'succeed' + null == coordinates.getTypeName() + validFieldName.equals(coordinates.getFieldName()) + + when: 'parent type with empty name is given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(emptyParentType, validFieldDef) + then: 'succeed' + emptyParentName.equals(coordinates.getTypeName()) + validFieldName.equals(coordinates.getFieldName()) + + when: 'valid parent type with name and field definition are given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(validParentType, validFieldDef) + then: 'succeed' + validParentName.equals(coordinates.getTypeName()) + validFieldName.equals(coordinates.getFieldName()) + } + + def "FieldCoordinate.coordinates(String, String) test validation"() { + when: 'null parent name is given for coordinates' + def coordinates = FieldCoordinates.coordinates(null as String, validFieldName) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'null field name is given for coordinates' + coordinates = FieldCoordinates.coordinates(validParentName, null) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'null parent name and null field name are given for coordinates' + coordinates = FieldCoordinates.coordinates((String) null, null) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'invalid parent name is given for coordinates' + coordinates = FieldCoordinates.coordinates(invalidParentName, validFieldName) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'invalid field name is given for coordinates' + coordinates = FieldCoordinates.coordinates(validParentName, invalidFieldName) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'invalid parent and field names are given for coordinates' + coordinates = FieldCoordinates.coordinates(invalidParentName, invalidFieldName) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'valid parent name and field name are given for coordinates' + coordinates = FieldCoordinates.coordinates(validParentName, validFieldName) + coordinates.assertValidNames() + then: 'succeed' + validParentName.equals(coordinates.getTypeName()) + validFieldName.equals(coordinates.getFieldName()) + } + + def "FieldCoordinate.coordinates(String, String) creation success with no validation"() { + when: 'null parent name is given for coordinates and no validation' + def coordinates = FieldCoordinates.coordinates(null as String, validFieldName) + then: 'succeed' + null == coordinates.getTypeName() + validFieldName.equals(coordinates.getFieldName()) + + when: 'null field name is given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(validParentName, null) + then: 'succeed' + validParentName.equals(coordinates.getTypeName()) + null == coordinates.getFieldName() + + when: 'null parent name and null field name are given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates((String) null, null) + then: 'succeed' + null == coordinates.getTypeName() + null == coordinates.getFieldName() + + when: 'invalid parent name is given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(invalidParentName, validFieldName) + then: 'succeed' + invalidParentName.equals(coordinates.getTypeName()) + validFieldName.equals(coordinates.getFieldName()) + + when: 'invalid field name is given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(validParentName, invalidFieldName) + then: 'succeed' + validParentName.equals(coordinates.getTypeName()) + invalidFieldName.equals(coordinates.getFieldName()) + + when: 'invalid parent and field names are given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(invalidParentName, invalidFieldName) + then: 'succeed' + invalidParentName.equals(coordinates.getTypeName()) + invalidFieldName.equals(coordinates.getFieldName()) + + when: 'valid parent name and field name are given for coordinates and no validation' + coordinates = FieldCoordinates.coordinates(validParentName, validFieldName) + then: 'succeed' + validParentName.equals(coordinates.getTypeName()) + validFieldName.equals(coordinates.getFieldName()) + } + + def "FieldCoordinate.systemCoordinates(String) test validation"() { + when: 'null field name is given for system coordinates' + def coordinates = FieldCoordinates.systemCoordinates(null) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'invalid field name is given for system coordinates' + coordinates = FieldCoordinates.systemCoordinates(invalidSystemFieldName) + coordinates.assertValidNames() + then: 'fail assert on validation' + thrown AssertException + + when: 'valid field name is given for system coordinates' + coordinates = FieldCoordinates.systemCoordinates(validSystemFieldName) + coordinates.assertValidNames() + then: 'succeed' + null == coordinates.getTypeName() + validSystemFieldName.equals(coordinates.getFieldName()) + } + + def "FieldCoordinate.systemCoordinates(String) creation success with no validation"() { + when: 'null field name is given for system coordinates and no validation' + def coordinates = FieldCoordinates.systemCoordinates(null) + then: 'succeed' + null == coordinates.getTypeName() + null == coordinates.getFieldName() + + when: 'invalid field name is given for system coordinates and no validation' + coordinates = FieldCoordinates.systemCoordinates(invalidSystemFieldName) + then: 'succeed' + null == coordinates.getTypeName() + invalidSystemFieldName.equals(coordinates.getFieldName()) + + when: 'valid field name is given for system coordinates and no validation' + coordinates = FieldCoordinates.systemCoordinates(validSystemFieldName) + then: 'succeed' + null == coordinates.getTypeName() + validSystemFieldName.equals(coordinates.getFieldName()) + } +} diff --git a/src/test/groovy/graphql/schema/GraphQLAppliedDirectiveArgumentTest.groovy b/src/test/groovy/graphql/schema/GraphQLAppliedDirectiveArgumentTest.groovy new file mode 100644 index 0000000000..35875c78d2 --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphQLAppliedDirectiveArgumentTest.groovy @@ -0,0 +1,64 @@ +package graphql.schema + +import graphql.GraphQLContext +import graphql.TestUtil +import graphql.execution.ValuesResolver +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import graphql.schema.idl.errors.SchemaProblem +import spock.lang.Specification + +class GraphQLAppliedDirectiveArgumentTest extends Specification { + def "test non-list value for a list argument of a directive - issue 2001"() { + def spec = ''' + directive @test(value: [String] = "default") on FIELD_DEFINITION + type Query { + testDefaultWorks : String @test + testItWorks : String @test(value: "test") + testItIsNotBroken : String @test(value: ["test"]) + } + ''' + + def closure = { + def argument = it.fieldDefinition.getAppliedDirective("test").getArgument("value") as GraphQLAppliedDirectiveArgument + return ValuesResolver.valueToInternalValue(argument.getArgumentValue(), argument.getType(), GraphQLContext.getDefault(), Locale.getDefault())[0] + } + def graphql = TestUtil.graphQL(spec, RuntimeWiring.newRuntimeWiring() + .type("Query", { + it.dataFetcher("testDefaultWorks", closure) + .dataFetcher("testItWorks", closure) + .dataFetcher("testItIsNotBroken", closure) + }).build()) + .build() + + when: + def result = graphql.execute(' { testDefaultWorks testItWorks testItIsNotBroken }') + + then: + result.errors.isEmpty() + result.data.testDefaultWorks == "default" + result.data.testItWorks == "test" + result.data.testItIsNotBroken == "test" + } + + def "test an incorrect non-list value for a list argument of a directive - issue 2001"() { + def spec = ''' + directive @test(value: [String]) on FIELD_DEFINITION + type Query { + test : String @test(value : 123) + } + ''' + + when: + def reader = new StringReader(spec) + def registry = new SchemaParser().parse(reader) + + def options = SchemaGenerator.Options.defaultOptions() + + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) + + then: + thrown(SchemaProblem.class) + } +} diff --git a/src/test/groovy/graphql/schema/GraphQLArgumentTest.groovy b/src/test/groovy/graphql/schema/GraphQLArgumentTest.groovy index 1442c5b1ac..a957b25425 100644 --- a/src/test/groovy/graphql/schema/GraphQLArgumentTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLArgumentTest.groovy @@ -1,10 +1,19 @@ package graphql.schema +import graphql.collect.ImmutableKit +import static graphql.introspection.Introspection.DirectiveLocation.ARGUMENT_DEFINITION +import graphql.language.FloatValue +import graphql.schema.validation.InvalidSchemaException import spock.lang.Specification +import static graphql.Scalars.GraphQLFloat import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString -import static graphql.schema.GraphQLDirective.newDirective +import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema +import static graphql.TestUtil.mkDirective class GraphQLArgumentTest extends Specification { @@ -13,7 +22,8 @@ class GraphQLArgumentTest extends Specification { def startingArgument = GraphQLArgument.newArgument().name("A1") .description("A1_description") .type(GraphQLInt) - .withDirective(newDirective().name("directive1")) + .deprecate("custom reason") + .withDirective(mkDirective("directive1", ARGUMENT_DEFINITION)) .build() when: def transformedArgument = startingArgument.transform({ @@ -21,38 +31,58 @@ class GraphQLArgumentTest extends Specification { .name("A2") .description("A2_description") .type(GraphQLString) - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive3")) - .value("VALUE") - .defaultValue("DEFAULT") + .withDirective(mkDirective("directive3", ARGUMENT_DEFINITION)) + .value("VALUE") // Retain deprecated for test coverage + .deprecate(null) + .defaultValue("DEFAULT") // Retain deprecated for test coverage }) then: startingArgument.name == "A1" startingArgument.description == "A1_description" startingArgument.type == GraphQLInt - startingArgument.defaultValue == null + startingArgument.argumentDefaultValue.value == null + startingArgument.deprecationReason == "custom reason" + startingArgument.isDeprecated() startingArgument.getDirectives().size() == 1 startingArgument.getDirective("directive1") != null transformedArgument.name == "A2" transformedArgument.description == "A2_description" transformedArgument.type == GraphQLString - transformedArgument.value == "VALUE" - transformedArgument.defaultValue == "DEFAULT" + transformedArgument.argumentValue.value == "VALUE" // Retain deprecated for test coverage + transformedArgument.argumentDefaultValue.value == "DEFAULT" + transformedArgument.deprecationReason == null + !transformedArgument.isDeprecated() transformedArgument.getDirectives().size() == 2 transformedArgument.getDirective("directive1") != null transformedArgument.getDirective("directive3") != null } + def "object can be transformed without setting the default value"() { + given: + def startingArgument = GraphQLArgument.newArgument().name("A1") + .type(GraphQLInt) + .build() + when: + def transformedArgument = startingArgument.transform({ + it.name("A2") + }) + + then: + + transformedArgument.name == "A2" + !transformedArgument.hasSetDefaultValue() + } + def "directive support on arguments via builder"() { def argument given: - def builder = GraphQLArgument.newArgument().name("A1") + def builder = newArgument().name("A1") .type(GraphQLInt) - .withDirective(newDirective().name("directive1")) + .withDirective(mkDirective("directive1", ARGUMENT_DEFINITION)) when: argument = builder.build() @@ -67,8 +97,8 @@ class GraphQLArgumentTest extends Specification { when: argument = builder .clearDirectives() - .withDirective(newDirective().name("directive2")) - .withDirective(newDirective().name("directive3")) + .withDirective(mkDirective("directive2", ARGUMENT_DEFINITION)) + .withDirective(mkDirective("directive3", ARGUMENT_DEFINITION)) .build() then: @@ -79,9 +109,10 @@ class GraphQLArgumentTest extends Specification { when: argument = builder - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive2")) // overwrite - .withDirective(newDirective().name("directive3")) // overwrite + .replaceDirectives([ + mkDirective("directive1", ARGUMENT_DEFINITION), + mkDirective("directive2", ARGUMENT_DEFINITION), + mkDirective("directive3", ARGUMENT_DEFINITION)]) // overwrite .build() then: @@ -90,4 +121,131 @@ class GraphQLArgumentTest extends Specification { argument.getDirective("directive2") != null argument.getDirective("directive3") != null } + + def "can get values statically"() { + // Retain deprecated API usages in this test for test coverage + when: + GraphQLArgument startingArg = GraphQLArgument.newArgument() + .name("F1") + .type(GraphQLFloat) + .description("F1_description") + .valueProgrammatic(4.56d) // Retain deprecated for test coverage + .defaultValueProgrammatic(1.23d) + .build() + def inputValue = startingArg.getArgumentValue() // Retain deprecated for test coverage + def resolvedValue = GraphQLArgument.getArgumentValue(startingArg) // Retain deprecated for test coverage + + def inputDefaultValue = startingArg.getArgumentDefaultValue() + def resolvedDefaultValue = GraphQLArgument.getArgumentDefaultValue(startingArg) + + then: + inputValue.isExternal() + inputValue.getValue() == 4.56d + resolvedValue == 4.56d + + inputDefaultValue.isExternal() + inputDefaultValue.getValue() == 1.23d + resolvedDefaultValue == 1.23d + + when: + startingArg = GraphQLArgument.newArgument() + .name("F1") + .type(GraphQLFloat) + .description("F1_description") + .valueLiteral(FloatValue.newFloatValue().value(4.56d).build()) // Retain deprecated for test coverage + .defaultValueLiteral(FloatValue.newFloatValue().value(1.23d).build()) + .build() + + inputValue = startingArg.getArgumentValue() // Retain deprecated for test coverage + resolvedValue = GraphQLArgument.getArgumentValue(startingArg) // Retain deprecated for test coverage + + inputDefaultValue = startingArg.getArgumentDefaultValue() + resolvedDefaultValue = GraphQLArgument.getArgumentDefaultValue(startingArg) + + then: + + inputValue.isLiteral() + (inputValue.getValue() as FloatValue).getValue().toDouble() == 4.56d + resolvedValue == 4.56d + + inputDefaultValue.isLiteral() + (inputDefaultValue.getValue() as FloatValue).getValue().toDouble() == 1.23d + resolvedDefaultValue == 1.23d + + when: + startingArg = GraphQLArgument.newArgument() + .name("F1") + .type(GraphQLFloat) + .description("F1_description") + .build() + + inputValue = startingArg.getArgumentValue() // Retain deprecated for test coverage + resolvedValue = GraphQLArgument.getArgumentValue(startingArg) // Retain deprecated for test coverage + + inputDefaultValue = startingArg.getArgumentDefaultValue() + resolvedDefaultValue = GraphQLArgument.getArgumentDefaultValue(startingArg) + + then: + + inputValue.isNotSet() + inputValue.getValue() == null + resolvedValue == null + + inputDefaultValue.isNotSet() + inputDefaultValue.getValue() == null + resolvedDefaultValue == null + } + + def "schema directive arguments are validated for programmatic schemas"() { + given: + def arg = newArgument().name("arg").type(GraphQLInt).valueProgrammatic(ImmutableKit.emptyMap()).build() // Retain for test coverage + def directive = mkDirective("cached", ARGUMENT_DEFINITION, arg) + def field = newFieldDefinition() + .name("hello") + .type(GraphQLString) + .argument(arg) + .withDirective(directive) + .build() + when: + newSchema() + .query( + newObject() + .name("Query") + .field(field) + .build() + ) + .additionalDirective(directive) + .build() + then: + def e = thrown(InvalidSchemaException) + e.message.contains("Invalid argument 'arg' for applied directive of name 'cached'") + } + + def "applied directive arguments are validated for programmatic schemas"() { + given: + def arg = newArgument() + .name("arg") + .type(GraphQLNonNull.nonNull(GraphQLInt)) + .build() + def directive = mkDirective("cached", ARGUMENT_DEFINITION, arg) + def field = newFieldDefinition() + .name("hello") + .type(GraphQLString) + .withAppliedDirective(directive.toAppliedDirective()) + .build() + when: + newSchema() + .query( + newObject() + .name("Query") + .field(field) + .build() + ) + .additionalDirective(directive) + .build() + then: + def e = thrown(InvalidSchemaException) + e.message.contains("Invalid argument 'arg' for applied directive of name 'cached'") + } + } diff --git a/src/test/groovy/graphql/schema/GraphQLCodeRegistryTest.groovy b/src/test/groovy/graphql/schema/GraphQLCodeRegistryTest.groovy new file mode 100644 index 0000000000..e528f5619f --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphQLCodeRegistryTest.groovy @@ -0,0 +1,399 @@ +package graphql.schema + +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.Scalars +import graphql.StarWarsSchema +import graphql.TestUtil +import graphql.TrivialDataFetcher +import graphql.TypeResolutionEnvironment +import graphql.schema.visibility.GraphqlFieldVisibility +import spock.lang.Specification + +import static graphql.Scalars.GraphQLInt +import static graphql.Scalars.GraphQLString +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class GraphQLCodeRegistryTest extends Specification { + + class NamedDF implements DataFetcher { + String name + + NamedDF(name) { + this.name = name + } + + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return name + } + } + + class NamedTypeResolver implements TypeResolver { + String name + + NamedTypeResolver(name) { + this.name = name + } + + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + return objectType(name) + } + } + + class NamedFieldVisibility implements GraphqlFieldVisibility { + String name + + NamedFieldVisibility(name) { + this.name = name + } + + @Override + List getFieldDefinitions(GraphQLFieldsContainer fieldsContainer) { + return fieldsContainer.fieldDefinitions + } + + @Override + GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsContainer, String fieldName) { + return fieldsContainer.getFieldDefinition(fieldName) + } + } + + static GraphQLFieldDefinition field(String name) { + return newFieldDefinition().name(name).type(Scalars.GraphQLString).build() + } + + static GraphQLObjectType objectType(String name) { + return newObject() + .field(newFieldDefinition() + .name("field") + .type(GraphQLString)) + .name(name) + .build() + } + + static GraphQLInterfaceType interfaceType(String name) { + return GraphQLInterfaceType.newInterface().name(name).build() + } + + static GraphQLUnionType unionType(String name) { + return GraphQLUnionType.newUnionType().name(name).possibleType(objectType("obj")).build() + } + + def "records data fetchers against parent objects and fields"() { + + when: + def codeRegistryBuilder = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(FieldCoordinates.coordinates("parentType1", "A"), new NamedDF("A")) + .dataFetcher(FieldCoordinates.coordinates("parentType2", "B"), new NamedDF("B")) + .dataFetchers("parentType3", [fieldD: new NamedDF("D"), fieldE: new NamedDF("E")]) + + // we can do a read on a half built code registry, namely for schema directive wiring use cases + then: + (codeRegistryBuilder.getDataFetcher(objectType("parentType1"), field("A")) as NamedDF).name == "A" + (codeRegistryBuilder.getDataFetcher(objectType("parentType2"), field("B")) as NamedDF).name == "B" + (codeRegistryBuilder.getDataFetcher(objectType("parentType3"), field("fieldD")) as NamedDF).name == "D" + (codeRegistryBuilder.getDataFetcher(objectType("parentType3"), field("fieldE")) as NamedDF).name == "E" + + codeRegistryBuilder.getDataFetcher(objectType("parentType2"), field("A")) instanceof SingletonPropertyDataFetcher // a default one + + when: + def codeRegistry = codeRegistryBuilder.build() + then: + (codeRegistry.getDataFetcher(objectType("parentType1"), field("A")) as NamedDF).name == "A" + (codeRegistry.getDataFetcher(objectType("parentType2"), field("B")) as NamedDF).name == "B" + (codeRegistry.getDataFetcher(objectType("parentType3"), field("fieldD")) as NamedDF).name == "D" + (codeRegistry.getDataFetcher(objectType("parentType3"), field("fieldE")) as NamedDF).name == "E" + + codeRegistry.getDataFetcher(objectType("parentType2"), field("A")) instanceof SingletonPropertyDataFetcher // a default one + } + + def "data fetchers can be retrieved using field coordinates"() { + when: + def codeRegistryBuilder = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(FieldCoordinates.coordinates("parentType1", "A"), new NamedDF("A")) + .dataFetcher(FieldCoordinates.coordinates("parentType2", "B"), new NamedDF("B")) + .dataFetchers("parentType3", [fieldD: new NamedDF("D"), fieldE: new NamedDF("E")]) + + // we can do a read on a half built code registry, namely for schema directive wiring use cases + then: + (codeRegistryBuilder.getDataFetcher(FieldCoordinates.coordinates("parentType1", "A"), field("A")) as NamedDF).name == "A" + (codeRegistryBuilder.getDataFetcher(FieldCoordinates.coordinates("parentType2", "B"), field("B")) as NamedDF).name == "B" + (codeRegistryBuilder.getDataFetcher(FieldCoordinates.coordinates("parentType3", "fieldD"), field("fieldD")) as NamedDF).name == "D" + (codeRegistryBuilder.getDataFetcher(FieldCoordinates.coordinates("parentType3", "fieldE"), field("fieldE")) as NamedDF).name == "E" + + codeRegistryBuilder.getDataFetcher(FieldCoordinates.coordinates("parentType2", "A"), field("A")) instanceof SingletonPropertyDataFetcher // a default one + + when: + def codeRegistry = codeRegistryBuilder.build() + then: + (codeRegistry.getDataFetcher(FieldCoordinates.coordinates("parentType1", "A"), field("A")) as NamedDF).name == "A" + (codeRegistry.getDataFetcher(FieldCoordinates.coordinates("parentType2", "B"), field("B")) as NamedDF).name == "B" + (codeRegistry.getDataFetcher(FieldCoordinates.coordinates("parentType3", "fieldD"), field("fieldD")) as NamedDF).name == "D" + (codeRegistry.getDataFetcher(FieldCoordinates.coordinates("parentType3", "fieldE"), field("fieldE")) as NamedDF).name == "E" + + codeRegistry.getDataFetcher(FieldCoordinates.coordinates("parentType2", "A"), field("A")) instanceof SingletonPropertyDataFetcher // a default one + } + + def "records type resolvers against unions and interfaces"() { + when: + def codeRegistryBuilder = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(interfaceType("interfaceType1"), new NamedTypeResolver("A")) + .typeResolver(interfaceType("interfaceType2"), new NamedTypeResolver("B")) + .typeResolver(unionType("unionType1"), new NamedTypeResolver("C")) + + then: + (codeRegistryBuilder.getTypeResolver(interfaceType("interfaceType1")) as NamedTypeResolver).name == "A" + (codeRegistryBuilder.getTypeResolver(interfaceType("interfaceType2")) as NamedTypeResolver).name == "B" + (codeRegistryBuilder.getTypeResolver(unionType("unionType1")) as NamedTypeResolver).name == "C" + + when: + def codeRegistry = codeRegistryBuilder.build() + then: + (codeRegistry.getTypeResolver(interfaceType("interfaceType1")) as NamedTypeResolver).name == "A" + (codeRegistry.getTypeResolver(interfaceType("interfaceType2")) as NamedTypeResolver).name == "B" + (codeRegistry.getTypeResolver(unionType("unionType1")) as NamedTypeResolver).name == "C" + } + + def "records field visibility"() { + + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry().fieldVisibility(new NamedFieldVisibility("A")).build() + then: + (codeRegistry.getFieldVisibility() as NamedFieldVisibility).name == "A" + } + + def "schema delegates field visibility to code registry"() { + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .fieldVisibility(new NamedFieldVisibility("B")) + .build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(objectType("query")) + .build() + then: + (schema.getCodeRegistry().getFieldVisibility() as NamedFieldVisibility).name == "B" + } + + def "SingletonPropertyDataFetcher is the default data fetcher used when no data fetcher is available"() { + + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry().build() + def dataFetcher = codeRegistry.getDataFetcher(StarWarsSchema.humanType, StarWarsSchema.humanType.getFieldDefinition("name")) + then: + dataFetcher instanceof SingletonPropertyDataFetcher + } + + def "custom DF can be the default data fetcher used when no data fetcher is available"() { + + when: + + DataFetcher customDF = { env -> "hi" } + DataFetcherFactory customDataFetcherFactory = { env -> customDF } + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry().defaultDataFetcher(customDataFetcherFactory).build() + def dataFetcher = codeRegistry.getDataFetcher(StarWarsSchema.humanType, StarWarsSchema.humanType.getFieldDefinition("name")) + then: + dataFetcher == customDF + dataFetcher.get(null) == "hi" + } + + def "default DF is used when no data fetcher is specified"() { + + def queryType = newObject().name("Query") + .field(newFieldDefinition().name("test").type(Scalars.GraphQLString)) + .build() + + DataFetcher customDF = { env -> "hi" } + DataFetcherFactory customDataFetcherFactory = { env -> customDF } + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry().defaultDataFetcher(customDataFetcherFactory).build() + + def schema = GraphQLSchema.newSchema().query(queryType).codeRegistry(codeRegistry).build() + def graphQL = GraphQL.newGraphQL(schema).build() + + when: + def er = graphQL.execute(ExecutionInput.newExecutionInput().query('''query { test }''').build()) + + then: + er.errors.isEmpty() + er.data == [test: "hi"] + } + + def "integration test that code registry gets asked for data fetchers"() { + + def queryType = newObject().name("Query") + .field(newFieldDefinition().name("codeRegistryField").type(Scalars.GraphQLString)) + .field(newFieldDefinition().name("nonCodeRegistryField").type(Scalars.GraphQLString) + // df comes from the field itself here + .dataFetcher(new NamedDF("nonCodeRegistryFieldValue"))) // Retain to test Field Definition DataFetcher + .field(newFieldDefinition().name("neitherSpecified").type(Scalars.GraphQLString)) + .build() + + // here we wire in a specific data fetcher via the code registry + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetchers("Query", [codeRegistryField: new NamedDF("codeRegistryFieldValue")]) + .build() + + def schema = GraphQLSchema.newSchema().query(queryType).codeRegistry(codeRegistry).build() + def graphQL = GraphQL.newGraphQL(schema).build() + when: + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(''' + query { + codeRegistryField, nonCodeRegistryField,neitherSpecified + } + ''').root([neitherSpecified: "neitherSpecifiedValue"]).build()) + then: + er.errors.isEmpty() + er.data == [codeRegistryField: "codeRegistryFieldValue", nonCodeRegistryField: "nonCodeRegistryFieldValue", neitherSpecified: "neitherSpecifiedValue"] + + // when nothing is specified then its a plain old SingletonPropertyDataFetcher + schema.getCodeRegistry().getDataFetcher(queryType, queryType.getFieldDefinition("neitherSpecified")) instanceof SingletonPropertyDataFetcher + + } + + def "integration test that code registry works with SDL and the code registry can be pre-specified"() { + + def spec = ''' + type Query { + codeRegistryField : String + nonCodeRegistryField : String + neitherSpecified : String + } + ''' + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetchers("Query", [codeRegistryField: new NamedDF("codeRegistryFieldValue")] + ) + def runtime = newRuntimeWiring().type(newTypeWiring("Query") + .dataFetcher("nonCodeRegistryField", new NamedDF("nonCodeRegistryFieldValue"))) + .codeRegistry(codeRegistry) + .build() + def schema = TestUtil.schema(spec, runtime) + def graphQL = GraphQL.newGraphQL(schema).build() + when: + def er = graphQL.execute(ExecutionInput.newExecutionInput().query(''' + query { + codeRegistryField, nonCodeRegistryField,neitherSpecified + } + ''').root([neitherSpecified: "neitherSpecifiedValue"]).build()) + then: + er.errors.isEmpty() + er.data == [codeRegistryField: "codeRegistryFieldValue", nonCodeRegistryField: "nonCodeRegistryFieldValue", neitherSpecified: "neitherSpecifiedValue"] + + // when nothing is specified then its a plain old PropertyDataFetcher + def queryType = schema.getObjectType("Query") + schema.getCodeRegistry().getDataFetcher(queryType, queryType.getFieldDefinition("neitherSpecified")) instanceof SingletonPropertyDataFetcher + } + + def "will detect system versus user data fetchers"() { + DataFetcher dfSystem = { env -> "system" } + DataFetcher dfUser = { env -> "user" } + def systemFieldDef = newFieldDefinition().name("__system").type(GraphQLInt).build() + def userFieldDef = newFieldDefinition().name("field").type(GraphQLInt).build() + def systemCoords = FieldCoordinates.systemCoordinates(systemFieldDef.name) + def userCoords = FieldCoordinates.coordinates("User", userFieldDef.name) + + + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(systemCoords, dfSystem) + .dataFetcher(userCoords, dfUser) + .build() + + then: + codeRegistry.hasDataFetcher(systemCoords) + codeRegistry.hasDataFetcher(userCoords) + + codeRegistry.getDataFetcher(systemCoords, systemFieldDef) == dfSystem + codeRegistry.getDataFetcher(userCoords, userFieldDef) == dfUser + } + + def "will put a data fetcher if absent"() { + DataFetcher dfSystem = { env -> "system" } + DataFetcher dfUser = { env -> "user" } + + DataFetcher dfSystem2 = { env -> "system2" } + DataFetcher dfUser2 = { env -> "user2" } + + def systemFieldDef = newFieldDefinition().name("__system").type(GraphQLInt).build() + def userFieldDef = newFieldDefinition().name("field").type(GraphQLInt).build() + def systemCoords = FieldCoordinates.systemCoordinates(systemFieldDef.name) + def userCoords = FieldCoordinates.coordinates("User", userFieldDef.name) + + + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcherIfAbsent(systemCoords, dfSystem) + .dataFetcherIfAbsent(userCoords, dfUser) + .build() + + then: + + codeRegistry.getDataFetcher(systemCoords, systemFieldDef) == dfSystem + codeRegistry.getDataFetcher(userCoords, userFieldDef) == dfUser + + when: + codeRegistry = GraphQLCodeRegistry.newCodeRegistry(codeRegistry) + .dataFetcherIfAbsent(systemCoords, dfSystem2) + .dataFetcherIfAbsent(userCoords, dfUser2) + .build() + + then: + + codeRegistry.getDataFetcher(systemCoords, systemFieldDef) == dfSystem + codeRegistry.getDataFetcher(userCoords, userFieldDef) == dfUser + + } + + def "builder can track changes - internal methods"() { + DataFetcher dfSystem = { env -> "system" } + DataFetcher dfUser = { env -> "user" } + def systemFieldDef = newFieldDefinition().name("__system").type(GraphQLInt).build() + def userFieldDef = newFieldDefinition().name("field").type(GraphQLInt).build() + def systemCoords = FieldCoordinates.systemCoordinates(systemFieldDef.name) + def userCoords = FieldCoordinates.coordinates("User", userFieldDef.name) + + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + then: + !codeRegistry.hasChanged() + + when: + codeRegistry.dataFetcher(systemCoords, dfSystem) + codeRegistry.dataFetcher(userCoords, dfUser) + then: + codeRegistry.hasChanged() + + when: + codeRegistry.trackChanges() + then: + !codeRegistry.hasChanged() + + when: + codeRegistry.clearDataFetchers() + then: + codeRegistry.hasChanged() + + when: + def newCodeRegistry = GraphQLCodeRegistry.newCodeRegistry(codeRegistry.build()) + then: + !newCodeRegistry.hasChanged() + + when: + newCodeRegistry = GraphQLCodeRegistry.newCodeRegistry(codeRegistry.build()) + then: + !newCodeRegistry.hasChanged() + + when: + newCodeRegistry.dataFetcher(systemCoords, dfSystem as DataFetcher) + newCodeRegistry.dataFetcher(userCoords, dfUser as DataFetcher) + then: + newCodeRegistry.hasChanged() + } +} diff --git a/src/test/groovy/graphql/schema/GraphQLDirectiveTest.groovy b/src/test/groovy/graphql/schema/GraphQLDirectiveTest.groovy index cf530ed65f..4c9b8bd486 100644 --- a/src/test/groovy/graphql/schema/GraphQLDirectiveTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLDirectiveTest.groovy @@ -1,5 +1,9 @@ package graphql.schema +import graphql.AssertException +import graphql.TestUtil +import graphql.introspection.Introspection +import graphql.language.Node import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean @@ -10,6 +14,7 @@ import static graphql.introspection.Introspection.DirectiveLocation.FIELD_DEFINI import static graphql.introspection.Introspection.DirectiveLocation.INTERFACE import static graphql.introspection.Introspection.DirectiveLocation.OBJECT import static graphql.introspection.Introspection.DirectiveLocation.UNION +import static graphql.language.AstPrinter.printAst class GraphQLDirectiveTest extends Specification { @@ -48,4 +53,174 @@ class GraphQLDirectiveTest extends Specification { transformedDirective.getArgument("argInt").type == GraphQLBoolean // swapped transformedDirective.getArgument("argIntAdded").type == GraphQLInt } + + def "integration test of directives on elements"() { + def sdl = """ + directive @d1(arg : String) on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | + ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + directive @dr(arg : String) repeatable on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | + ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + + schema @d1 @dr(arg : "a1") @dr(arg : "a2") { + query : Query + } + + type Query @d1 @dr(arg : "a1") @dr(arg : "a2") { + field(arg : String @d1 @dr(arg : "a1") @dr(arg : "a2") ) : String @d1 @dr(arg : "a1") @dr(arg : "a2") + } + + input Input @d1 @dr(arg : "a1") @dr(arg : "a2") { + inputField : String @d1 @dr(arg : "a1") @dr(arg : "a2") + } + + + interface InterfaceType @d1 @dr(arg : "a1") @dr(arg : "a2") { + interfaceField : String @d1 @dr(arg : "a1") @dr(arg : "a2") + } + + type A { a : String } + + type B { b : String } + + union UnionType @d1 @dr(arg : "a1") @dr(arg : "a2") = A | B + + scalar ScalarType @d1 @dr(arg : "a1") @dr(arg : "a2") + + enum EnumType @d1 @dr(arg : "a1") @dr(arg : "a2") { + EnumVal @d1 @dr(arg : "a1") @dr(arg : "a2") + } + """ + + when: + def schema = TestUtil.schema(sdl) + then: + schema.getSchemaAppliedDirective("d1").name == "d1" + schema.getAllSchemaAppliedDirectivesByName().keySet() == ["d1", "dr"] as Set + + schema.getAllSchemaAppliedDirectivesByName()["d1"].size() == 1 + schema.getAllSchemaAppliedDirectivesByName()["dr"].size() == 2 + schema.getAllSchemaAppliedDirectivesByName()["dr"].collect({ printAst(it.getArgument("arg").argumentValue.value) }) == ['"a1"', '"a2"'] + + when: + def queryType = schema.getObjectType("Query") + + then: + assertDirectiveContainer(queryType) + + when: + def fieldDef = queryType.getFieldDefinition("field") + + then: + assertDirectiveContainer(fieldDef) + + when: + def arg = fieldDef.getArgument("arg") + + then: + assertDirectiveContainer(arg) + + when: + def inputType = schema.getType("Input") as GraphQLInputObjectType + + then: + assertDirectiveContainer(inputType) + + when: + def inputField = inputType.getField("inputField") + + then: + assertDirectiveContainer(inputField) + + + when: + def enumType = schema.getType("EnumType") as GraphQLEnumType + + then: + assertDirectiveContainer(enumType) + + when: + def enumVal = enumType.getValue("EnumVal") + + then: + assertDirectiveContainer(enumVal) + + when: + def interfaceType = schema.getType("InterfaceType") as GraphQLInterfaceType + + then: + assertDirectiveContainer(interfaceType) + + when: + def interfaceField = interfaceType.getFieldDefinition("interfaceField") + + then: + assertDirectiveContainer(interfaceField) + + when: + def unionType = schema.getType("UnionType") as GraphQLUnionType + + then: + assertDirectiveContainer(unionType) + + + when: + def scalarType = schema.getType("ScalarType") as GraphQLScalarType + + then: + assertDirectiveContainer(scalarType) + } + + def "throws an error on missing required properties"() { + given: + def validDirective = GraphQLDirective.newDirective() + .name("dir") + .validLocation(Introspection.DirectiveLocation.SCALAR) + .build() + + when: + validDirective.transform { it.name(null) } + + then: + def e = thrown(AssertException) + e.message.contains("Name must be non-null, non-empty") + + when: + validDirective.transform { it.replaceArguments(null) } + + then: + def e2 = thrown(AssertException) + e2.message.contains("arguments must not be null") + + when: + validDirective.transform { it.clearValidLocations() } + + then: + def e3 = thrown(AssertException) + e3.message.contains("locations can't be empty") + } + + + static boolean assertDirectiveContainer(GraphQLDirectiveContainer container) { + assert container.hasDirective("d1") // Retain for test coverage + assert container.hasAppliedDirective("d1") + assert container.hasAppliedDirective("dr") + assert !container.hasAppliedDirective("non existent") + assert container.getDirectives().collect({ it.name }) == ["d1", "dr", "dr"] // Retain for test coverage + assert container.getAppliedDirectives().collect({ it.name }) == ["d1", "dr", "dr"] + assert container.getAppliedDirective("d1").name == "d1" + assert container.getDirectivesByName().keySet() == ["d1"] as Set // Retain for test coverage, there is no equivalent non-repeatable directive method + + assert container.getAllDirectivesByName().keySet() == ["d1", "dr"] as Set // Retain for test coverage + assert container.getAllAppliedDirectivesByName().keySet() == ["d1", "dr"] as Set + assert container.getAllAppliedDirectivesByName()["d1"].size() == 1 + assert container.getAllAppliedDirectivesByName()["dr"].size() == 2 + + assert container.getAppliedDirectives("d1").size() == 1 + assert container.getAppliedDirectives("dr").size() == 2 + assert container.getAppliedDirectives("dr").collect({ printAst(it.getArgument("arg").argumentValue.value as Node) }) == ['"a1"', '"a2"'] + + return true + } } diff --git a/src/test/groovy/graphql/schema/GraphQLEnumTypeTest.groovy b/src/test/groovy/graphql/schema/GraphQLEnumTypeTest.groovy index 4938339e5f..d717e607a7 100644 --- a/src/test/groovy/graphql/schema/GraphQLEnumTypeTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLEnumTypeTest.groovy @@ -1,6 +1,7 @@ package graphql.schema import graphql.AssertException +import graphql.GraphQLContext import graphql.language.EnumValue import graphql.language.StringValue import spock.lang.Specification @@ -19,51 +20,74 @@ class GraphQLEnumTypeTest extends Specification { def "parse throws exception for unknown value"() { when: - enumType.getCoercing().parseValue("UNKNOWN") + enumType.parseValue("UNKNOWN", GraphQLContext.default, Locale.default) then: thrown(CoercingParseValueException) } + def "parse throws exception for unknown value with deprecated method"() { + when: + enumType.parseValue("UNKNOWN") // Retain for test coverage + + then: + thrown(CoercingParseValueException) + } def "parse value return value for the name"() { expect: - enumType.getCoercing().parseValue("NAME") == 42 + enumType.parseValue("NAME", GraphQLContext.default, Locale.default) == 42 } def "serialize returns name for value"() { expect: - enumType.getCoercing().serialize(42) == "NAME" + enumType.serialize(42, GraphQLContext.default, Locale.default) == "NAME" + } + + def "serialize returns name for value with deprecated method"() { + expect: + enumType.serialize(42) == "NAME" } def "serialize throws exception for unknown value"() { when: - enumType.getCoercing().serialize(12) + enumType.serialize(12, GraphQLContext.default, Locale.default) then: thrown(CoercingSerializeException) } - def "parseLiteral return null for invalid input"() { when: - enumType.getCoercing().parseLiteral(StringValue.newStringValue("foo").build()) + enumType.parseLiteral(StringValue.newStringValue("foo").build(), + GraphQLContext.default, + Locale.default) + then: + thrown(CoercingParseLiteralException) + } + + def "parseLiteral return null for invalid input with deprecated method"() { + when: + enumType.parseLiteral(StringValue.newStringValue("foo").build()) then: thrown(CoercingParseLiteralException) } def "parseLiteral return null for invalid enum name"() { when: - enumType.getCoercing().parseLiteral(EnumValue.newEnumValue("NOT_NAME").build()) + enumType.parseLiteral(EnumValue.newEnumValue("NOT_NAME").build(), + GraphQLContext.default, + Locale.default) then: thrown(CoercingParseLiteralException) } def "parseLiteral returns value for 'NAME'"() { expect: - enumType.getCoercing().parseLiteral(EnumValue.newEnumValue("NAME").build()) == 42 + enumType.parseLiteral(EnumValue.newEnumValue("NAME").build(), + GraphQLContext.default, + Locale.default) == 42 } - def "null values are not allowed"() { when: newEnum().name("AnotherTestEnum") @@ -72,7 +96,6 @@ class GraphQLEnumTypeTest extends Specification { thrown(AssertException) } - def "duplicate value definition overwrites"() { when: def enumType = newEnum().name("AnotherTestEnum") @@ -96,7 +119,7 @@ class GraphQLEnumTypeTest extends Specification { .build() when: - def serialized = enumType.coercing.serialize(Episode.EMPIRE) + def serialized = enumType.serialize(Episode.EMPIRE, GraphQLContext.default, Locale.default) then: serialized == "EMPIRE" @@ -111,7 +134,7 @@ class GraphQLEnumTypeTest extends Specification { .build() when: - def serialized = enumType.coercing.serialize(Episode.NEWHOPE) + def serialized = enumType.serialize(Episode.NEWHOPE, GraphQLContext.default, Locale.default) then: serialized == "NEWHOPE" @@ -128,7 +151,7 @@ class GraphQLEnumTypeTest extends Specification { String stringInput = Episode.NEWHOPE.toString() when: - def serialized = enumType.coercing.serialize(stringInput) + def serialized = enumType.serialize(stringInput, GraphQLContext.default, Locale.default) then: serialized == "NEWHOPE" diff --git a/src/test/groovy/graphql/schema/GraphQLEnumValueDefinitionTest.groovy b/src/test/groovy/graphql/schema/GraphQLEnumValueDefinitionTest.groovy index 8f6a4145bc..0a755a9f3c 100644 --- a/src/test/groovy/graphql/schema/GraphQLEnumValueDefinitionTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLEnumValueDefinitionTest.groovy @@ -1,9 +1,10 @@ package graphql.schema +import static graphql.introspection.Introspection.DirectiveLocation import spock.lang.Specification -import static graphql.schema.GraphQLDirective.newDirective import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition +import static graphql.TestUtil.mkDirective class GraphQLEnumValueDefinitionTest extends Specification { def "object can be transformed"() { @@ -11,15 +12,14 @@ class GraphQLEnumValueDefinitionTest extends Specification { def startEnumValue = newEnumValueDefinition().name("EV1") .description("EV1_description") .value("A") - .withDirective(newDirective().name("directive1")) + .withDirective(mkDirective("directive1", DirectiveLocation.ENUM_VALUE)) .build() when: def transformedEnumValue = startEnumValue.transform({ it .name("EV2") .value("X") - .withDirective(newDirective().name("directive2")) - + .withDirective(mkDirective("directive2", DirectiveLocation.ENUM_VALUE)) }) then: diff --git a/src/test/groovy/graphql/schema/GraphQLFieldDefinitionTest.groovy b/src/test/groovy/graphql/schema/GraphQLFieldDefinitionTest.groovy index 5c5854eb48..46a5c3c1e5 100644 --- a/src/test/groovy/graphql/schema/GraphQLFieldDefinitionTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLFieldDefinitionTest.groovy @@ -1,21 +1,27 @@ package graphql.schema import graphql.AssertException +import graphql.TestUtil +import graphql.introspection.Introspection +import graphql.schema.idl.SchemaPrinter import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean import static graphql.Scalars.GraphQLFloat import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mockArguments +import static graphql.TestUtil.mkDirective +import static graphql.schema.DefaultGraphqlTypeComparatorRegistry.newComparators import static graphql.schema.GraphQLArgument.newArgument -import static graphql.schema.GraphQLDirective.newDirective import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.idl.SchemaPrinter.Options.defaultOptions class GraphQLFieldDefinitionTest extends Specification { def "dataFetcher can't be null"() { when: - newFieldDefinition().dataFetcher(null) + newFieldDefinition().dataFetcher(null) // Retain for test coverage then: def exception = thrown(AssertException) exception.getMessage().contains("dataFetcher") @@ -30,8 +36,8 @@ class GraphQLFieldDefinitionTest extends Specification { .deprecate("F1_deprecated") .argument(newArgument().name("argStr").type(GraphQLString)) .argument(newArgument().name("argInt").type(GraphQLInt)) - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive2")) + .withDirective(mkDirective("directive1", Introspection.DirectiveLocation.FIELD_DEFINITION)) + .withDirective(mkDirective("directive2", Introspection.DirectiveLocation.FIELD_DEFINITION)) .build() when: @@ -42,14 +48,10 @@ class GraphQLFieldDefinitionTest extends Specification { .argument(newArgument().name("argStr").type(GraphQLString)) .argument(newArgument().name("argInt").type(GraphQLBoolean)) .argument(newArgument().name("argIntAdded").type(GraphQLInt)) - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive3")) - + .withDirective(mkDirective("directive3", Introspection.DirectiveLocation.FIELD_DEFINITION)) }) - then: - startingField.name == "F1" startingField.type == GraphQLFloat startingField.description == "F1_description" @@ -78,4 +80,19 @@ class GraphQLFieldDefinitionTest extends Specification { transformedField.getDirective("directive2") != null transformedField.getDirective("directive3") != null } + + def "test deprecated argument builder for list"() { + given: + def field = newFieldDefinition().name("field").type(GraphQLInt).argument(mockArguments("a", "bb")).build() // Retain for test coverage + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def printer = new SchemaPrinter(options) + + then: + printer.argsString(GraphQLFieldDefinition.class, field.arguments) == '''(bb: Int, a: Int)''' + } } diff --git a/src/test/groovy/graphql/schema/GraphQLInputObjectFieldTest.groovy b/src/test/groovy/graphql/schema/GraphQLInputObjectFieldTest.groovy index 1e4eb3de8e..67e3611442 100644 --- a/src/test/groovy/graphql/schema/GraphQLInputObjectFieldTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLInputObjectFieldTest.groovy @@ -1,11 +1,13 @@ package graphql.schema +import graphql.introspection.Introspection +import graphql.language.FloatValue import spock.lang.Specification import static graphql.Scalars.GraphQLFloat import static graphql.Scalars.GraphQLInt -import static graphql.schema.GraphQLDirective.newDirective import static graphql.schema.GraphQLInputObjectField.newInputObjectField +import static graphql.TestUtil.mkDirective class GraphQLInputObjectFieldTest extends Specification { @@ -15,25 +17,25 @@ class GraphQLInputObjectFieldTest extends Specification { .name("F1") .type(GraphQLFloat) .description("F1_description") - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive2")) + .withDirective(mkDirective("directive1", Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION)) + .withDirective(mkDirective("directive2", Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION)) + .deprecate("No longer useful") .build() when: def transformedField = startingField.transform({ builder -> builder.name("F2") .type(GraphQLInt) - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive3")) - + .deprecate(null) + .withDirective(mkDirective("directive3", Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION)) }) - then: - startingField.name == "F1" startingField.type == GraphQLFloat startingField.description == "F1_description" + startingField.isDeprecated() + startingField.getDeprecationReason() == "No longer useful" startingField.getDirectives().size() == 2 startingField.getDirective("directive1") != null @@ -43,9 +45,58 @@ class GraphQLInputObjectFieldTest extends Specification { transformedField.type == GraphQLInt transformedField.description == "F1_description" // left alone + !transformedField.isDeprecated() + transformedField.getDeprecationReason() == null + transformedField.getDirectives().size() == 3 transformedField.getDirective("directive1") != null transformedField.getDirective("directive2") != null transformedField.getDirective("directive3") != null } + + def "can get default values statically"() { + when: + def startingField = newInputObjectField() + .name("F1") + .type(GraphQLFloat) + .description("F1_description") + .defaultValueProgrammatic(1.23d) + .build() + def inputValue = startingField.getInputFieldDefaultValue() + def resolvedValue = GraphQLInputObjectField.getInputFieldDefaultValue(startingField) + + then: + inputValue.isExternal() + inputValue.getValue() == 1.23d + resolvedValue == 1.23d + + when: + startingField = newInputObjectField() + .name("F1") + .type(GraphQLFloat) + .description("F1_description") + .defaultValueLiteral(FloatValue.newFloatValue().value(1.23d).build()) + .build() + inputValue = startingField.getInputFieldDefaultValue() + resolvedValue = GraphQLInputObjectField.getInputFieldDefaultValue(startingField) + + then: + inputValue.isLiteral() + (inputValue.getValue() as FloatValue).getValue().toDouble() == 1.23d + resolvedValue == 1.23d + + when: " we have no values " + startingField = newInputObjectField() + .name("F1") + .type(GraphQLFloat) + .description("F1_description") + .build() + inputValue = startingField.getInputFieldDefaultValue() + resolvedValue = GraphQLInputObjectField.getInputFieldDefaultValue(startingField) + + then: + inputValue.isNotSet() + inputValue.getValue() == null + resolvedValue == null + } } diff --git a/src/test/groovy/graphql/schema/GraphQLInputObjectTypeTest.groovy b/src/test/groovy/graphql/schema/GraphQLInputObjectTypeTest.groovy index f8f3358b12..9ad43412bf 100644 --- a/src/test/groovy/graphql/schema/GraphQLInputObjectTypeTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLInputObjectTypeTest.groovy @@ -1,6 +1,13 @@ package graphql.schema -import graphql.AssertException +import graphql.Directives +import graphql.ExecutionInput +import graphql.GraphQL +import graphql.GraphQLContext +import graphql.StarWarsSchema +import graphql.TestUtil +import graphql.language.ObjectValue +import graphql.validation.ValidationUtil import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean @@ -8,22 +15,10 @@ import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString import static graphql.schema.GraphQLInputObjectField.newInputObjectField import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLNonNull.nonNull class GraphQLInputObjectTypeTest extends Specification { - def "duplicate field definition fails"() { - when: - // preserve old constructor behavior test - new GraphQLInputObjectType("TestInputObjectType", "description", - [ - newInputObjectField().name("NAME").type(GraphQLString).build(), - newInputObjectField().name("NAME").type(GraphQLString).build() - ]) - then: - thrown(AssertException) - } - - def "duplicate field definition overwrites"() { when: def inputObjectType = newInputObject().name("TestInputObjectType") @@ -68,4 +63,122 @@ class GraphQLInputObjectTypeTest extends Specification { transformedInputType.getFieldDefinition("Str").getType() == GraphQLBoolean } + def "deprecated default value builder works"() { + given: + def graphQLContext = GraphQLContext.getDefault() + def schema = GraphQLSchema.newSchema() + .query(StarWarsSchema.queryType) + .codeRegistry(StarWarsSchema.codeRegistry) + .build() + def validationUtil = new ValidationUtil() + def inputObjectType = GraphQLInputObjectType.newInputObject() + .name("inputObjectType") + .field(GraphQLInputObjectField.newInputObjectField() + .name("hello") + .type(nonNull(GraphQLString)) + .defaultValue("default")) // Retain deprecated builder for test coverage + .build() + def objectValue = ObjectValue.newObjectValue() + + expect: + validationUtil.isValidLiteralValue(objectValue.build(), inputObjectType, schema, graphQLContext, Locale.ENGLISH) + } + + def "can detect one of support"() { + when: + def inputObjectType = newInputObject().name("TestInputObjectType") + .field(newInputObjectField().name("NAME").type(GraphQLInt)) + .build() + then: + !inputObjectType.isOneOf() + + when: + inputObjectType = newInputObject().name("TestInputObjectType") + .field(newInputObjectField().name("NAME").type(GraphQLInt)) + .withDirective(Directives.OneOfDirective) + .build() + then: + inputObjectType.isOneOf() + + when: + inputObjectType = newInputObject().name("TestInputObjectType") + .field(newInputObjectField().name("NAME").type(GraphQLInt)) + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .build() + then: + inputObjectType.isOneOf() + } + + def "e2e test of oneOf support"() { + def sdl = ''' + type Query { + f(arg : OneOf) : [KV] + } + + type KV { + key : String + value : String + } + + input OneOf @oneOf { + a : String + b : Int + } + ''' + + DataFetcher df = { DataFetchingEnvironment env -> + Map arg = env.getArgument("arg") + + def l = [] + for (Map.Entry entry : arg.entrySet()) { + l.add(["key": entry.getKey(), "value": String.valueOf(entry.getValue())]) + } + return l + } + + def graphQLSchema = TestUtil.schema(sdl, [Query: [f: df]]) + def graphQL = GraphQL.newGraphQL(graphQLSchema).build() + + when: + def er = graphQL.execute('query q { f( arg : {a : "abc"}) { key value }}') + def l = (er.data["f"] as List) + then: + er.errors.isEmpty() + l.size() == 1 + l[0]["key"] == "a" + l[0]["value"] == "abc" + + when: + er = graphQL.execute('query q { f( arg : {b : 123}) { key value }}') + l = (er.data["f"] as List) + + then: + er.errors.isEmpty() + l.size() == 1 + l[0]["key"] == "b" + l[0]["value"] == "123" + + when: + er = graphQL.execute('query q { f( arg : {a : "abc", b : 123}) { key value }}') + then: + !er.errors.isEmpty() + // caught during early validation + er.errors[0].message == "Validation error (WrongType@[f]) : Exactly one key must be specified for OneOf type 'OneOf'." + + when: + def ei = ExecutionInput.newExecutionInput('query q($var : OneOf) { f( arg : $var) { key value }}').variables([var: [a: "abc", b: 123]]).build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message == "Exactly one key must be specified for OneOf type 'OneOf'." + + when: + ei = ExecutionInput.newExecutionInput('query q($var : OneOf) { f( arg : $var) { key value }}').variables([var: [a: null]]).build() + er = graphQL.execute(ei) + then: + !er.errors.isEmpty() + er.errors[0].message == "OneOf type field 'OneOf.a' must be non-null." + + // lots more covered in unit tests + } } diff --git a/src/test/groovy/graphql/schema/GraphQLInterfaceTypeTest.groovy b/src/test/groovy/graphql/schema/GraphQLInterfaceTypeTest.groovy index 670a86188d..b6c4273ae3 100644 --- a/src/test/groovy/graphql/schema/GraphQLInterfaceTypeTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLInterfaceTypeTest.groovy @@ -1,26 +1,33 @@ package graphql.schema -import graphql.AssertException +import graphql.util.TraversalControl +import graphql.util.TraverserContext import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString +import static graphql.schema.GraphQLCodeRegistry.newCodeRegistry import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLInterfaceType.newInterface +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema +import static graphql.schema.GraphQLTypeReference.typeRef class GraphQLInterfaceTypeTest extends Specification { - def "duplicate field definition fails"() { + def "duplicate field definition overwrites existing value"() { when: - // preserve old constructor behavior test - new GraphQLInterfaceType("TestInputObjectType", "description", - [ + def interfaceType = newInterface().name("TestInterfaceType") + .description("description") + .fields([ newFieldDefinition().name("NAME").type(GraphQLString).build(), - newFieldDefinition().name("NAME").type(GraphQLString).build() - ], new TypeResolverProxy()) + newFieldDefinition().name("NAME").type(GraphQLInt).build() + ]) + .build() then: - thrown(AssertException) + interfaceType.getName() == "TestInterfaceType" + interfaceType.getFieldDefinition("NAME").getType() == GraphQLInt } def "builder can change existing object into a new one"() { @@ -29,7 +36,6 @@ class GraphQLInterfaceTypeTest extends Specification { .description("StartingDescription") .field(newFieldDefinition().name("Str").type(GraphQLString)) .field(newFieldDefinition().name("Int").type(GraphQLInt)) - .typeResolver(new TypeResolverProxy()) .build() when: @@ -57,4 +63,61 @@ class GraphQLInterfaceTypeTest extends Specification { objectType2.getFieldDefinition("Str").getType() == GraphQLBoolean } + def "schema transformer accepts interface with type reference"() { + given: + def iFace = newInterface().name("iFace") + .field(builder -> builder.type(GraphQLString).name("field")) + .withInterface(typeRef("iFace2")) + .build() + + def iFace2 = newInterface().name("iFace2") + .field(builder -> builder.type(GraphQLString).name("field")) + .build() + + def impl = newObject().name("impl") + .field(builder -> builder.type(GraphQLString).name("field")) + .withInterfaces(typeRef("iFace")) + .withInterfaces(typeRef("iFace2")) + .build() + + def codeRegBuilder = newCodeRegistry().typeResolver(iFace, env -> impl) + .typeResolver(iFace2, env -> impl) + + def schema = newSchema() + .codeRegistry(codeRegBuilder.build()) + .additionalType(iFace).additionalType(iFace2) + .query(newObject() + .name("test") + .field(builder -> builder.name("iFaceField").type(impl)) + ).build() + + when: + SchemaTransformer.transformSchema(schema, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + GraphQLFieldDefinition transform = node.transform( + builder -> builder.argument(builder1 -> builder1.name("arg").type(GraphQLString))) + changeNode(context, transform) + return super.visitGraphQLFieldDefinition(node, context) + } + }) + + then: + noExceptionThrown() + } + + def "deprecated typeResolver builder works"() { + when: + def interfaceType = newInterface().name("TestInterfaceType") + .description("description") + .fields([ + newFieldDefinition().name("NAME").type(GraphQLString).build(), + newFieldDefinition().name("NAME").type(GraphQLInt).build() + ]) + .typeResolver(new TypeResolverProxy()) // Retain for test coverage + .build() + then: + interfaceType.getName() == "TestInterfaceType" + interfaceType.getFieldDefinition("NAME").getType() == GraphQLInt + } } diff --git a/src/test/groovy/graphql/schema/GraphQLNonNullTest.groovy b/src/test/groovy/graphql/schema/GraphQLNonNullTest.groovy new file mode 100644 index 0000000000..a0722fd8ab --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphQLNonNullTest.groovy @@ -0,0 +1,26 @@ +package graphql.schema + +import graphql.AssertException +import spock.lang.Specification + +import static graphql.Scalars.GraphQLString + +class GraphQLNonNullTest extends Specification { + + def "non null wrapping"() { + when: + GraphQLNonNull.nonNull(GraphQLString) + then: + noExceptionThrown() + + when: + GraphQLNonNull.nonNull(GraphQLList.list(GraphQLString)) + then: + noExceptionThrown() + + when: + GraphQLNonNull.nonNull(GraphQLNonNull.nonNull(GraphQLList.list(GraphQLString))) + then: + thrown(AssertException) + } +} diff --git a/src/test/groovy/graphql/schema/GraphQLObjectTypeTest.groovy b/src/test/groovy/graphql/schema/GraphQLObjectTypeTest.groovy index 7a29451272..5a79fc97e7 100644 --- a/src/test/groovy/graphql/schema/GraphQLObjectTypeTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLObjectTypeTest.groovy @@ -1,6 +1,5 @@ package graphql.schema -import graphql.AssertException import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean @@ -11,18 +10,6 @@ import static graphql.schema.GraphQLObjectType.newObject class GraphQLObjectTypeTest extends Specification { - def "duplicate field definition fails"() { - when: - // preserve old constructor behavior test - new GraphQLObjectType("TestObjectType", "description", - [ - newFieldDefinition().name("NAME").type(GraphQLString).build(), - newFieldDefinition().name("NAME").type(GraphQLString).build() - ], []) - then: - thrown(AssertException) - } - def "duplicate field definition overwrites existing value"() { when: def objectType = newObject().name("TestObjectType") @@ -65,5 +52,10 @@ class GraphQLObjectTypeTest extends Specification { objectType2.getFieldDefinition("AddedInt").getType() == GraphQLInt objectType2.getFieldDefinition("Int").getType() == GraphQLInt objectType2.getFieldDefinition("Str").getType() == GraphQLBoolean + + // getFields shortcuts work + objectType.getField("Int").getType() == GraphQLInt + objectType.getField("Str").getType() == GraphQLString + objectType.getFields().size() == 2 } } diff --git a/src/test/groovy/graphql/schema/GraphQLScalarTypeTest.groovy b/src/test/groovy/graphql/schema/GraphQLScalarTypeTest.groovy index 5a4f0ad286..100269838d 100644 --- a/src/test/groovy/graphql/schema/GraphQLScalarTypeTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLScalarTypeTest.groovy @@ -1,8 +1,9 @@ package graphql.schema +import graphql.introspection.Introspection import spock.lang.Specification -import static graphql.schema.GraphQLDirective.newDirective +import static graphql.TestUtil.mkDirective class GraphQLScalarTypeTest extends Specification { Coercing coercing = new Coercing() { @@ -28,15 +29,14 @@ class GraphQLScalarTypeTest extends Specification { .name("S1") .description("S1_description") .coercing(coercing) - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive2")) + .withDirective(mkDirective("directive1", Introspection.DirectiveLocation.SCALAR)) + .withDirective(mkDirective("directive2", Introspection.DirectiveLocation.SCALAR)) .build() when: def transformedScalar = startingScalar.transform({ builder -> builder.name("S2") .description("S2_description") - .withDirective(newDirective().name("directive1")) - .withDirective(newDirective().name("directive3")) + .withDirective(mkDirective("directive3", Introspection.DirectiveLocation.SCALAR)) }) then: @@ -56,6 +56,5 @@ class GraphQLScalarTypeTest extends Specification { transformedScalar.getDirective("directive1") != null transformedScalar.getDirective("directive2") != null transformedScalar.getDirective("directive3") != null - } } diff --git a/src/test/groovy/graphql/schema/GraphQLSchemaTest.groovy b/src/test/groovy/graphql/schema/GraphQLSchemaTest.groovy index d77099d7de..73a04346f2 100644 --- a/src/test/groovy/graphql/schema/GraphQLSchemaTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLSchemaTest.groovy @@ -1,16 +1,33 @@ package graphql.schema import graphql.AssertException +import graphql.Directives import graphql.ExecutionInput import graphql.GraphQL import graphql.TestUtil +import graphql.language.Directive +import graphql.language.SchemaExtensionDefinition import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.TypeRuntimeWiring +import graphql.util.TraversalControl +import graphql.util.TraverserContext import spock.lang.Specification +import java.util.function.UnaryOperator + +import static graphql.Scalars.GraphQLString import static graphql.StarWarsSchema.characterInterface import static graphql.StarWarsSchema.droidType import static graphql.StarWarsSchema.humanType import static graphql.StarWarsSchema.starWarsSchema +import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInputObjectField.newInputObjectField +import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLNonNull.nonNull +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLTypeReference.typeRef +import static java.util.stream.Collectors.toList class GraphQLSchemaTest extends Specification { @@ -21,7 +38,7 @@ class GraphQLSchemaTest extends Specification { then: objectTypes.size() == 2 objectTypes == [ - humanType, droidType + droidType, humanType ] } @@ -56,15 +73,15 @@ class GraphQLSchemaTest extends Specification { RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() .type("Query", { wiring -> - wiring.dataFetcher("foo", { env -> - Map map = new HashMap<>() - map.put("id", "abc") - return map - }) - }) + wiring.dataFetcher("foo", { env -> + Map map = new HashMap<>() + map.put("id", "abc") + return map + }) + } as UnaryOperator) .type("Node", { wiring -> - wiring.typeResolver({ env -> (GraphQLObjectType) env.getSchema().getType("Foo") }) - }) + wiring.typeResolver({ env -> (GraphQLObjectType) env.getSchema().getType("Foo") }) + } as UnaryOperator) .build() def existingSchema = TestUtil.schema(idl, runtimeWiring) @@ -77,8 +94,7 @@ class GraphQLSchemaTest extends Specification { assert 0 == runQuery(schema).getErrors().size() } - - def runQuery(GraphQLSchema schema) { + static def runQuery(GraphQLSchema schema) { GraphQL graphQL = GraphQL.newGraphQL(schema) .build() @@ -90,4 +106,461 @@ class GraphQLSchemaTest extends Specification { .executeAsync(executionInput) .join() } + + static def basicSchemaBuilder() { + def queryTypeName = "QueryType" + def fooCoordinates = FieldCoordinates.coordinates(queryTypeName, "hero") + DataFetcher basicDataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return null + } + } + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, basicDataFetcher) + .build() + + GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(newObject() + .name("QueryType") + .field(newFieldDefinition() + .name("hero") + .type(GraphQLString) + )) + } + + def "schema builder copies extension definitions"() { + setup: + def schemaBuilder = basicSchemaBuilder() + def newDirective = Directive.newDirective().name("pizza").build() + def extension = SchemaExtensionDefinition.newSchemaExtensionDefinition().directive(newDirective).build() + def oldSchema = schemaBuilder.extensionDefinitions([extension]).build() + + when: + def newSchema = GraphQLSchema.newSchema(oldSchema).build() + + then: + oldSchema.extensionDefinitions.size() == 1 + newSchema.extensionDefinitions.size() == 1 + ((Directive) oldSchema.extensionDefinitions.first().getDirectives().first()).name == "pizza" + ((Directive) newSchema.extensionDefinitions.first().getDirectives().first()).name == "pizza" + } + + def "clear directives works as expected"() { + setup: + def schemaBuilder = basicSchemaBuilder() + + when: "no additional directives have been specified" + def schema = schemaBuilder.build() + then: + schema.directives.size() == 7 + + when: "clear directives is called" + schema = schemaBuilder.clearDirectives().build() + then: + schema.directives.size() == 5 // @deprecated and @specifiedBy and @oneOf et al is ALWAYS added if missing + + when: "clear directives is called with more directives" + schema = schemaBuilder.clearDirectives().additionalDirective(Directives.SkipDirective).build() + then: + schema.directives.size() == 6 + + when: "the schema is transformed, things are copied" + schema = schema.transform({ builder -> builder.additionalDirective(Directives.IncludeDirective) }) + then: + schema.directives.size() == 7 + } + + def "clear additional types works as expected"() { + setup: + def schemaBuilder = basicSchemaBuilder() + + when: "no additional types have been specified" + def schema = schemaBuilder.build() + then: + schema.additionalTypes.size() == 0 + + when: "clear types is called" + schema = schemaBuilder.clearAdditionalTypes().build() + then: + schema.additionalTypes.empty + + when: "clear types is called with additional types" + def additional1TypeName = "Additional1" + def additional2TypeName = "Additional2" + def fieldName = "field" + def additionalType1 = newObject() + .name(additional1TypeName) + .field(newFieldDefinition() + .name(fieldName) + .type(GraphQLString)) + .build() + def additionalType2 = newObject() + .name("Additional2") + .field(newFieldDefinition() + .name(fieldName) + .type(GraphQLString)) + .build() + + def additional1Coordinates = FieldCoordinates.coordinates(additionalType1, fieldName) + DataFetcher basicDataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return null + } + } + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(additional1Coordinates, basicDataFetcher) + .build() + + schema = schemaBuilder + .clearAdditionalTypes() + .additionalType(additionalType1) + .codeRegistry(codeRegistry) + .build() + + then: + schema.additionalTypes.size() == 1 + + when: "the schema is transformed, things are copied" + def additional2Coordinates = FieldCoordinates.coordinates(additional2TypeName, fieldName) + codeRegistry = codeRegistry.transform({ builder -> builder.dataFetcher(additional2Coordinates, basicDataFetcher) }) + schema = schema.transform({ builder -> builder.additionalType(additionalType2).codeRegistry(codeRegistry) }) + then: + schema.additionalTypes.size() == 2 + } + + def "getType works as expected"() { + def sdl = ''' + type Query { + field1 : Pet + field2 : UnionType + } + + interface Pet { + name : String + } + + type Dog implements Pet { + name : String + } + type Cat implements Pet { + name : String + } + + union UnionType = Cat | Dog + ''' + + when: + def schema = TestUtil.schema(sdl) + + then: + schema.containsType("Pet") + schema.containsType("Dog") + !schema.containsType("Elephant") + + schema.getType("Pet") != null + + GraphQLInterfaceType petType = schema.getTypeAs("Pet") + petType.getName() == "Pet" + + GraphQLObjectType dogType = schema.getTypeAs("Dog") + dogType.getName() == "Dog" + } + + def "issue with type references when original type is transformed away"() { + def sdl = ''' + type Query { + # The b fields leads to the addition of the B type (actual definition) + b: B + # When we filter out the `b` field, we can still access B through A + # however they are GraphQLTypeReferences and not an actual GraphQL Object + a: A + } + + type A { + b: B + } + + type B { + a: A + b: B + } + ''' + + when: + def schema = TestUtil.schema(sdl) + // When field `b` is filtered out + List fields = schema.queryType.fieldDefinitions.stream().filter({ + it.name == "a" + }).collect(toList()) + // And we transform the schema's query root, the schema building + // will throw because type B won't be in the type map anymore, since + // there are no more actual B object types in the schema tree. + def transformed = schema.transform({ + it.query(schema.queryType.transform({ + it.replaceFields(fields) + })) + }) + + then: + transformed.containsType("B") + + } + + def "can change types via SchemaTransformer and visitor"() { + def sdl = ''' + type Query { + b: B + a: A + } + + type A { + b: B + } + + type B { + a: A + b: B + } + ''' + + when: + def schema = TestUtil.schema(sdl) + + GraphQLTypeVisitorStub visitor = new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) { + if (objectType.getName() == "Query") { + def queryType = objectType + List fields = queryType.fieldDefinitions.stream().filter({ + it.name == "a" + }).collect(toList()) + + GraphQLObjectType newObjectType = queryType.transform({ + it.replaceFields(fields) + }) + + return changeNode(context, newObjectType) + } + return TraversalControl.CONTINUE + } + } + GraphQLSchema transformedSchema = SchemaTransformer.transformSchema(schema, visitor) + + then: + transformedSchema.containsType("B") + } + + def "fields edited from type references should still built valid schemas"() { + def typeB = newObject().name("B") + .field(newFieldDefinition().name("a").type(typeRef("A"))) + .field(newFieldDefinition().name("b").type(typeRef("B"))) + .build() + + + def typeAFieldB = newFieldDefinition().name("b").type(typeRef("B")).build() + // at the line above typeB is never strongly referenced + // and this simulates an edit situation that wont happen with direct java declaration + // but where the type reference is replaced to an actual but its the ONLY direct reference + // to that type`` + typeAFieldB.replaceType(typeB) + + def typeA = newObject().name("A") + .field(typeAFieldB) + .build() + + // + // the same pattern above applies ot other replaceable types like arguments and input fields + def inputTypeY = newInputObject().name("InputTypeY") + .field(newInputObjectField().name("in2").type(GraphQLString)) + .build() + + def inputFieldOfY = newInputObjectField().name("inY").type(typeRef("InputTypeY")).build() + // only reference to InputTypeY + inputFieldOfY.replaceType(inputTypeY) + + def inputTypeZ = newInputObject().name("InputTypeZ") + .field(inputFieldOfY) + .build() + + def inputTypeX = newInputObject().name("InputTypeX") + .field(newInputObjectField().name("inX").type(GraphQLString)) + .build() + + GraphQLArgument argOfX = newArgument().name("argOfX").type(typeRef("InputTypeX")).build() + // only reference to InputTypeX + argOfX.replaceType(inputTypeX) + + GraphQLArgument argOfZ = newArgument().name("argOfZ").type(inputTypeZ).build() + + def typeC = newObject().name("C") + .field(newFieldDefinition().name("f1").type(GraphQLString).argument(argOfX)) + .field(newFieldDefinition().name("f2").type(GraphQLString).argument(argOfZ)) + .build() + + def queryType = newObject().name("Query") + .field(newFieldDefinition().name("a").type(typeA)) + .field(newFieldDefinition().name("c").type(typeC)) + .build() + + when: + def schema = GraphQLSchema.newSchema().query(queryType).build() + then: + schema.getType("A") != null + schema.getType("B") != null + schema.getType("InputTypeX") != null + schema.getType("InputTypeY") != null + schema.getType("InputTypeZ") != null + } + + def "list and non nulls work when direct references are edited"() { + + def typeX = newObject().name("TypeX") + .field(newFieldDefinition().name("f1").type(GraphQLString)) + .build() + def queryType = newObject().name("Query") + .field(newFieldDefinition().name("direct").type(typeX)) + .field(newFieldDefinition().name("indirectNonNull").type(nonNull(typeRef("TypeX")))) + .field(newFieldDefinition().name("indirectList").type(GraphQLList.list(nonNull(typeRef("TypeX"))))) + .build() + + when: + def schema = GraphQLSchema.newSchema().query(queryType).build() + then: + schema.getType("TypeX") != null + + // now edit away the actual strong reference + when: + GraphQLTypeVisitor visitor = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + if (node.getName() == "direct") { + return deleteNode(context) + } + return TraversalControl.CONTINUE + } + } + + GraphQLSchema transformedSchema = SchemaTransformer.transformSchema(schema, visitor) + + then: + transformedSchema.getType("TypeX") != null + } + + def "cheap transform without types transformation works"() { + + def sdl = ''' + "a schema involving pets" + schema { + query : Query + } + type Query { + field1 : Dog + field2 : Cat + } + + type Dog { + name : String + } + + type Cat { + name : String + } + + ''' + + + when: + DataFetcher nameDF = { env -> "name" } + def originalSchema = TestUtil.schema(sdl, ["Dog": ["name": nameDF]]) + def originalCodeRegistry = originalSchema.getCodeRegistry() + + then: + originalSchema.getDescription() == "a schema involving pets" + originalSchema.containsType("Dog") + !originalSchema.containsType("Elephant") + + originalCodeRegistry.getDataFetcher(originalSchema.getObjectType("Dog"), originalSchema.getObjectType("Dog").getField("name")) === nameDF + + when: + def newRegistry = originalCodeRegistry.transform({ bld -> bld.clearDataFetchers() }) + def newSchema = originalSchema.transformWithoutTypes({ + it.description("A new home for pets").codeRegistry(newRegistry) + }) + + then: + + newSchema.getDescription() == "A new home for pets" + newSchema.containsType("Dog") + !newSchema.containsType("Elephant") + + def dogType = newSchema.getObjectType("Dog") + dogType === originalSchema.getObjectType("Dog") // schema type graph is the same + + newRegistry == newSchema.getCodeRegistry() + newRegistry != originalCodeRegistry + + + def newDF = newRegistry.getDataFetcher(dogType, dogType.getField("name")) + newDF !== nameDF + newDF instanceof LightDataFetcher // defaulted in + } + + def "can get by field co-ordinate"() { + when: + def fieldDef = starWarsSchema.getFieldDefinition(FieldCoordinates.coordinates("QueryType", "hero")) + + then: + fieldDef.name == "hero" + (fieldDef.type as GraphQLInterfaceType).getName() == "Character" + + when: + fieldDef = starWarsSchema.getFieldDefinition(FieldCoordinates.coordinates("X", "hero")) + + then: + fieldDef == null + + when: + fieldDef = starWarsSchema.getFieldDefinition(FieldCoordinates.coordinates("QueryType", "X")) + + then: + fieldDef == null + + when: + starWarsSchema.getFieldDefinition(FieldCoordinates.coordinates("Episode", "JEDI")) + + then: + thrown(AssertException) + + when: + fieldDef = starWarsSchema.getFieldDefinition(FieldCoordinates.systemCoordinates("__typename")) + + then: + fieldDef == starWarsSchema.getIntrospectionTypenameFieldDefinition() + + when: + fieldDef = starWarsSchema.getFieldDefinition(FieldCoordinates.systemCoordinates("__type")) + + then: + fieldDef == starWarsSchema.getIntrospectionTypeFieldDefinition() + + when: + fieldDef = starWarsSchema.getFieldDefinition(FieldCoordinates.systemCoordinates("__schema")) + + then: + fieldDef == starWarsSchema.getIntrospectionSchemaFieldDefinition() + + when: + starWarsSchema.getFieldDefinition(FieldCoordinates.systemCoordinates("__junk")) + + then: + thrown(AssertException) + + } + } diff --git a/src/test/groovy/graphql/schema/GraphQLTypeReferenceTest.groovy b/src/test/groovy/graphql/schema/GraphQLTypeReferenceTest.groovy new file mode 100644 index 0000000000..61647aee6f --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphQLTypeReferenceTest.groovy @@ -0,0 +1,49 @@ +package graphql.schema + +import graphql.Scalars +import spock.lang.Specification + +import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInputObjectField.newInputObjectField +import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema + +class GraphQLTypeReferenceTest extends Specification { + + def "the same reference can be used multiple times without throwing exception"() { + when: + GraphQLTypeReference ref = new GraphQLTypeReference("String") + def inputObject = newInputObject() + .name("ObjInput") + .field(newInputObjectField() + .name("value") + .type(ref)) //Will get replaced, as expected + .field(newInputObjectField() + .name("value2") + .type(ref)) //Will get replaced, as expected + .build() + + GraphQLSchema schema = newSchema() + .query( + newObject() + .name("Query") + .field(newFieldDefinition() + .name("test") + .type(Scalars.GraphQLString) + .argument(newArgument() + .name("in") + .type(inputObject)) + )).build() + + then: + // issue 1216 - reuse of type reference caused problems + schema != null + GraphQLInputObjectType objInput = ((GraphQLInputObjectType) schema.getType("ObjInput")) + objInput.getField("value").getType() != ref + objInput.getField("value").getType() instanceof GraphQLScalarType + objInput.getField("value2").getType() != ref + objInput.getField("value2").getType() instanceof GraphQLScalarType + } +} diff --git a/src/test/groovy/graphql/schema/GraphQLTypeUtilTest.groovy b/src/test/groovy/graphql/schema/GraphQLTypeUtilTest.groovy index c7d6af50c4..bc8a08aff1 100644 --- a/src/test/groovy/graphql/schema/GraphQLTypeUtilTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLTypeUtilTest.groovy @@ -6,6 +6,7 @@ import static graphql.Scalars.GraphQLString import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLTypeReference.typeRef class GraphQLTypeUtilTest extends Specification { @@ -22,10 +23,10 @@ class GraphQLTypeUtilTest extends Specification { def nonnull_list_nonnull_heroType = nonNull(list_nonnull_heroType) when: - def heroTypeStr = GraphQLTypeUtil.getUnwrappedTypeName(heroType) - def nonnull_heroType_str = GraphQLTypeUtil.getUnwrappedTypeName(nonnull_heroType) - def list_nonnull_heroType_str = GraphQLTypeUtil.getUnwrappedTypeName(list_nonnull_heroType) - def nonnull_list_nonnull_heroType_str = GraphQLTypeUtil.getUnwrappedTypeName(nonnull_list_nonnull_heroType) + def heroTypeStr = GraphQLTypeUtil.simplePrint(heroType) + def nonnull_heroType_str = GraphQLTypeUtil.simplePrint(nonnull_heroType) + def list_nonnull_heroType_str = GraphQLTypeUtil.simplePrint(list_nonnull_heroType) + def nonnull_list_nonnull_heroType_str = GraphQLTypeUtil.simplePrint(nonnull_list_nonnull_heroType) then: heroTypeStr == "Hero" @@ -85,7 +86,6 @@ class GraphQLTypeUtilTest extends Specification { then: GraphQLTypeUtil.isList(type) - when: type = GraphQLTypeUtil.unwrapOne(type) @@ -98,6 +98,12 @@ class GraphQLTypeUtilTest extends Specification { then: !GraphQLTypeUtil.isWrapped(type) type == GraphQLString + + when: + GraphQLScalarType scalar = GraphQLTypeUtil.unwrapOneAs(nonNull(GraphQLString)) + + then: + scalar == GraphQLString } def "unwrapAll tests"() { @@ -105,7 +111,7 @@ class GraphQLTypeUtilTest extends Specification { def type = list(nonNull(list(nonNull(GraphQLString)))) then: - GraphQLTypeUtil.getUnwrappedTypeName(type) == "[[String!]!]" + GraphQLTypeUtil.simplePrint(type) == "[[String!]!]" when: @@ -122,6 +128,38 @@ class GraphQLTypeUtilTest extends Specification { } + def "unwrapAllAs tests"() { + def type = list(nonNull(list(nonNull(GraphQLString)))) + def typeRef = list(nonNull(list(nonNull(typeRef("A"))))) + + when: + type = GraphQLTypeUtil.unwrapAllAs(type) + + then: + type == GraphQLString + + when: + type = GraphQLTypeUtil.unwrapAllAs(type) + + then: + type == GraphQLString + + when: + typeRef = GraphQLTypeUtil.unwrapAllAs(typeRef) + + then: + typeRef instanceof GraphQLTypeReference + (typeRef as GraphQLTypeReference).name == "A" + + when: + typeRef = GraphQLTypeUtil.unwrapAllAs(typeRef) + + then: + typeRef instanceof GraphQLTypeReference + (typeRef as GraphQLTypeReference).name == "A" + + } + def "isLeaf tests"() { when: def type = GraphQLString @@ -167,4 +205,32 @@ class GraphQLTypeUtilTest extends Specification { then: !GraphQLTypeUtil.isInput(type) } + + def "can unwrap non null-ness"() { + + when: + def type = GraphQLTypeUtil.unwrapNonNull(nonNull(GraphQLString)) + + then: + (type as GraphQLNamedType).getName() == "String" + + when: + type = GraphQLTypeUtil.unwrapNonNull(nonNull(list(GraphQLString))) + + then: + type instanceof GraphQLList + + when: + type = GraphQLTypeUtil.unwrapNonNull(list(GraphQLString)) + + then: + type instanceof GraphQLList + + when: + type = GraphQLTypeUtil.unwrapNonNull(GraphQLString) + + then: + (type as GraphQLNamedType).getName() == "String" + + } } diff --git a/src/test/groovy/graphql/schema/GraphQLTypeVisitorStubTest.groovy b/src/test/groovy/graphql/schema/GraphQLTypeVisitorStubTest.groovy new file mode 100644 index 0000000000..019d7e0f6f --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphQLTypeVisitorStubTest.groovy @@ -0,0 +1,38 @@ +package graphql.schema + +import graphql.util.TraversalControl +import graphql.util.TraverserContext +import spock.lang.Specification +import spock.lang.Unroll + +class GraphQLTypeVisitorStubTest extends Specification { + + @Unroll + def "#visitMethod scalar type"() { + given: + GraphQLTypeVisitorStub typeVisitorStub = Spy(GraphQLTypeVisitorStub, constructorArgs: []) + TraverserContext context = Mock(TraverserContext) + + when: + def control = typeVisitorStub."$visitMethod"(node, context) + then: + typeVisitorStub.visitGraphQLType(node, context) >> TraversalControl.CONTINUE + control == TraversalControl.CONTINUE + + where: + node | visitMethod + Mock(GraphQLScalarType) | 'visitGraphQLScalarType' + Mock(GraphQLArgument) | 'visitGraphQLArgument' + Mock(GraphQLInterfaceType) | 'visitGraphQLInterfaceType' + Mock(GraphQLEnumType) | 'visitGraphQLEnumType' + Mock(GraphQLEnumValueDefinition) | 'visitGraphQLEnumValueDefinition' + Mock(GraphQLFieldDefinition) | 'visitGraphQLFieldDefinition' + Mock(GraphQLInputObjectField) | 'visitGraphQLInputObjectField' + Mock(GraphQLInputObjectType) | 'visitGraphQLInputObjectType' + Mock(GraphQLList) | 'visitGraphQLList' + Mock(GraphQLNonNull) | 'visitGraphQLNonNull' + Mock(GraphQLObjectType) | 'visitGraphQLObjectType' + Mock(GraphQLTypeReference) | 'visitGraphQLTypeReference' + Mock(GraphQLUnionType) | 'visitGraphQLUnionType' + } +} diff --git a/src/test/groovy/graphql/schema/GraphQLUnionTypeTest.groovy b/src/test/groovy/graphql/schema/GraphQLUnionTypeTest.groovy index d30cc79ff7..6524d135da 100644 --- a/src/test/groovy/graphql/schema/GraphQLUnionTypeTest.groovy +++ b/src/test/groovy/graphql/schema/GraphQLUnionTypeTest.groovy @@ -14,7 +14,6 @@ class GraphQLUnionTypeTest extends Specification { when: newUnionType() .name("TestUnionType") - .typeResolver(new TypeResolverProxy()) .build() then: thrown(AssertException) @@ -38,7 +37,6 @@ class GraphQLUnionTypeTest extends Specification { .description("StartingDescription") .possibleType(objType1) .possibleType(objType2) - .typeResolver(new TypeResolverProxy()) .build() when: @@ -55,9 +53,23 @@ class GraphQLUnionTypeTest extends Specification { startingUnion.getDescription() == "StartingDescription" startingUnion.getTypes().size() == 2 + startingUnion.isPossibleType(objType2) + !startingUnion.isPossibleType(objType3) + transformedUnion.getName() == "NewName" transformedUnion.getDescription() == "NewDescription" transformedUnion.getTypes().size() == 1 + !transformedUnion.isPossibleType(objType2) + transformedUnion.isPossibleType(objType3) } + def "deprecated typeResolver builder works"() { + when: + newUnionType() + .name("TestUnionType") + .typeResolver(new TypeResolverProxy()) // Retain for test coverage + .build() + then: + thrown(AssertException) + } } diff --git a/src/test/groovy/graphql/schema/GraphqlTypeComparatorEnvironmentTest.groovy b/src/test/groovy/graphql/schema/GraphqlTypeComparatorEnvironmentTest.groovy new file mode 100644 index 0000000000..c997e42fc5 --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphqlTypeComparatorEnvironmentTest.groovy @@ -0,0 +1,119 @@ +package graphql.schema + +import graphql.AssertException +import spock.lang.Specification + +import static graphql.schema.GraphqlTypeComparatorEnvironment.newEnvironment + +class GraphqlTypeComparatorEnvironmentTest extends Specification { + + def "valid instance"() { + when: + environment.build() + + then: + notThrown() + + where: + + environment << [ + newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class), + newEnvironment() + .elementType(GraphQLFieldDefinition.class) + ] + } + + def "equals handles optional parentType"() { + given: + def fullEnvironmentA = newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class) + .build() + def fullEnvironmentB = newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class) + .build() + + def partialEnvironmentA = newEnvironment() + .elementType(GraphQLFieldDefinition.class) + .build() + def partialEnvironmentB = newEnvironment() + .elementType(GraphQLFieldDefinition.class) + .build() + expect: + fullEnvironmentA == fullEnvironmentB + partialEnvironmentA == partialEnvironmentB + fullEnvironmentA != partialEnvironmentA + fullEnvironmentB != partialEnvironmentB + } + + def "hashCode handles optional parentType"() { + given: + def fullEnvironmentA = newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class) + .build() + def fullEnvironmentB = newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class) + .build() + + def partialEnvironmentA = newEnvironment() + .elementType(GraphQLFieldDefinition.class) + .build() + def partialEnvironmentB = newEnvironment() + .elementType(GraphQLFieldDefinition.class) + .build() + expect: + fullEnvironmentA.hashCode() == fullEnvironmentB.hashCode() + partialEnvironmentA.hashCode() == partialEnvironmentB.hashCode() + fullEnvironmentA.hashCode() != partialEnvironmentA.hashCode() + fullEnvironmentB.hashCode() != partialEnvironmentB.hashCode() + } + + def "new environment can be created from an existing one"() { + given: + def startEnvironment = newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class) + .build() + + when: + def nextEnvironment = newEnvironment(startEnvironment) + + then: + startEnvironment.elementType == nextEnvironment.build().elementType + startEnvironment.parentType == nextEnvironment.build().parentType + } + + def "object can be transformed into a valid state"() { + given: + def startEnvironment = newEnvironment() + .parentType(GraphQLObjectType.class) + .elementType(GraphQLFieldDefinition.class) + .build() + when: + def transformedEnvironment = startEnvironment.transform({ + it.parentType(null) + }) + + then: + startEnvironment.parentType == GraphQLObjectType.class + startEnvironment.elementType == GraphQLFieldDefinition.class + + transformedEnvironment.parentType == null + transformedEnvironment.elementType == GraphQLFieldDefinition.class + + when: + transformedEnvironment = startEnvironment.transform({ + it.elementType(null) + }) + + then: + transformedEnvironment.parentType == GraphQLObjectType.class + transformedEnvironment.elementType == null + } + +} diff --git a/src/test/groovy/graphql/schema/GraphqlTypeComparatorsTest.groovy b/src/test/groovy/graphql/schema/GraphqlTypeComparatorsTest.groovy new file mode 100644 index 0000000000..ba93f1d2ec --- /dev/null +++ b/src/test/groovy/graphql/schema/GraphqlTypeComparatorsTest.groovy @@ -0,0 +1,207 @@ +package graphql.schema + +import graphql.TestUtil +import spock.lang.Specification + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring + +class GraphqlTypeComparatorsTest extends Specification { + + def spec = ''' + type Query { + zField(zArg : String, yArg : String, xArg : InputType) : ZType + yField : YInterface + xField : XUnion + } + + type ZType { + enumField : EnumType + } + + interface YInterface { + zField : String + yField : String + xField : String + } + + interface XInterface { + zField : String + yField : String + xField : String + } + + interface ZInterface { + zField : String + yField : String + xField : String + } + + union XUnion = Foo | Bar + + type Foo implements YInterface & XInterface & ZInterface { + zField : String + yField : String + xField : String + } + + type Bar implements YInterface { + zField : String + yField : String + xField : String + } + + enum EnumType { + z + y + x + } + + input InputType { + zInput : String + xInput : String + yInput : String + } + ''' + + def runtimeWiringByName = newRuntimeWiring() + .comparatorRegistry(GraphqlTypeComparatorRegistry.BY_NAME_REGISTRY) + .wiringFactory(TestUtil.mockWiringFactory) + def schemaByName = TestUtil.schema(spec, runtimeWiringByName) + + + def runtimeWiringAsIs = newRuntimeWiring() + .comparatorRegistry(GraphqlTypeComparatorRegistry.AS_IS_REGISTRY) + .wiringFactory(TestUtil.mockWiringFactory) + def schemaAsIs = TestUtil.schema(spec, runtimeWiringAsIs) + + def "test that types sorted from the schema"() { + def expectedNames = ["Bar", "Boolean", "EnumType", "Foo", "InputType", "Query", "String", "XInterface", "XUnion", "YInterface", "ZInterface", "ZType", + "__Directive", "__DirectiveLocation", "__EnumValue", "__Field", "__InputValue", "__Schema", "__Type", "__TypeKind"] + when: + def names = schemaByName.getAllTypesAsList().collect({ thing -> thing.getName() }) + + then: + names == expectedNames + + when: + names = schemaByName.getTypeMap().values().collect({ thing -> thing.getName() }) + + then: + names == expectedNames + + when: + names = schemaByName.getTypeMap().keySet().toList() + + then: + names == expectedNames + + } + + def "test that fields in a type are sorted"() { + when: + def names = schemaByName.getObjectType("Query").getFieldDefinitions().collect({ thing -> thing.getName() }) + + then: + names == ["xField", "yField", "zField"] + + when: + names = schemaAsIs.getObjectType("Query").getFieldDefinitions().collect({ thing -> thing.getName() }) + + then: + names == ["zField", "yField", "xField"] + + when: + def interfaceType = schemaByName.getType("YInterface") as GraphQLInterfaceType + names = interfaceType.getFieldDefinitions().collect({ thing -> thing.getName() }) + + then: + names == ["xField", "yField", "zField"] + + when: + interfaceType = schemaAsIs.getType("YInterface") as GraphQLInterfaceType + names = interfaceType.getFieldDefinitions().collect({ thing -> thing.getName() }) + + then: + names == ["zField", "yField", "xField"] + } + + def "test that members in a union are sorted"() { + when: + def unionType = schemaByName.getType("XUnion") as GraphQLUnionType + def names = unionType.getTypes().collect({ thing -> thing.getName() }) + + then: + names == ["Bar", "Foo"] + + when: + unionType = schemaAsIs.getType("XUnion") as GraphQLUnionType + names = unionType.getTypes().collect({ thing -> thing.getName() }) + + then: + names == ["Foo", "Bar"] + } + + def "test that implementations in a object type are sorted"() { + when: + def objectType = schemaByName.getObjectType("Foo") + def names = objectType.getInterfaces().collect({ thing -> thing.getName() }) + + then: + names == ["XInterface", "YInterface", "ZInterface"] + + when: + objectType = schemaAsIs.getObjectType("Foo") + names = objectType.getInterfaces().collect({ thing -> thing.getName() }) + + then: + names == ["YInterface", "XInterface", "ZInterface"] + } + + def "test that args in a field in a type are sorted"() { + when: + def names = schemaByName.getObjectType("Query").getFieldDefinition("zField").getArguments().collect({ thing -> thing.getName() }) + + then: + names == ["xArg", "yArg", "zArg"] + + when: + names = schemaAsIs.getObjectType("Query").getFieldDefinition("zField").getArguments().collect({ thing -> thing.getName() }) + + then: + names == ["zArg", "yArg", "xArg"] + + } + + def "test that enum values in a enum are sorted"() { + when: + def enumType = schemaByName.getType("EnumType") as GraphQLEnumType + def names = enumType.getValues().collect({ thing -> thing.getName() }) + + then: + names == ["x", "y", "z"] + + when: + enumType = schemaAsIs.getType("EnumType") as GraphQLEnumType + names = enumType.getValues().collect({ thing -> thing.getName() }) + + then: + names == ["z", "y", "x"] + + } + + def "test that input fields in a input type are sorted"() { + when: + def inputType = schemaByName.getType("InputType") as GraphQLInputObjectType + def names = inputType.getFieldDefinitions().collect({ thing -> thing.getName() }) + + then: + names == ["xInput", "yInput", "zInput"] + + when: + inputType = schemaAsIs.getType("InputType") as GraphQLInputObjectType + names = inputType.getFieldDefinitions().collect({ thing -> thing.getName() }) + + then: + names == ["zInput", "xInput", "yInput"] + } +} diff --git a/src/test/groovy/graphql/schema/PropertyDataFetcherClassLoadingTest.groovy b/src/test/groovy/graphql/schema/PropertyDataFetcherClassLoadingTest.groovy new file mode 100644 index 0000000000..62b814db0d --- /dev/null +++ b/src/test/groovy/graphql/schema/PropertyDataFetcherClassLoadingTest.groovy @@ -0,0 +1,62 @@ +package graphql.schema + +import graphql.GraphQLException +import graphql.Scalars +import spock.lang.Specification + +class PropertyDataFetcherClassLoadingTest extends Specification { + + GraphQLFieldDefinition fld(String fldName) { + return GraphQLFieldDefinition.newFieldDefinition().name(fldName).type(Scalars.GraphQLString).build() + } + + static class BrokenClass { + static { + // this should prevent it from existing + throw new RuntimeException("No soup for you!") + } + } + + + static class TargetClass { + + String getOkThings() { + return "ok" + } + + BrokenClass getBrokenThings() { + return new BrokenClass() + } + } + + def "can survive linkage errors during access to broken classes in Lambda support"() { + def okDF = PropertyDataFetcher.fetching("okThings") + def brokenDF = PropertyDataFetcher.fetching("brokenThings") + + def target = new TargetClass() + + when: + def value = okDF.get(fld("okThings"), target, { -> null }) + then: + value == "ok" + + when: + brokenDF.get(fld("brokenThings"), target, { -> null }) + then: + // This is because the reflection method finder cant get to it + // but it has made it past the Meta Lambda support + thrown(GraphQLException) + + // multiple times - same result + when: + value = okDF.get(fld("okThings"), target, { -> null }) + then: + value == "ok" + + when: + brokenDF.get(fld("brokenThings"), target, { -> null }) + then: + thrown(GraphQLException) + + } +} diff --git a/src/test/groovy/graphql/schema/PropertyDataFetcherTest.groovy b/src/test/groovy/graphql/schema/PropertyDataFetcherTest.groovy index 4a1fca654a..7903f14229 100644 --- a/src/test/groovy/graphql/schema/PropertyDataFetcherTest.groovy +++ b/src/test/groovy/graphql/schema/PropertyDataFetcherTest.groovy @@ -1,35 +1,68 @@ package graphql.schema -import graphql.execution.ExecutionContext +import graphql.ExecutionInput +import graphql.Scalars +import graphql.TestUtil +import graphql.schema.fetching.ConfusedPojo +import graphql.schema.somepackage.ClassWithDFEMethods +import graphql.schema.somepackage.ClassWithInterfaces +import graphql.schema.somepackage.ClassWithInteritanceAndInterfaces +import graphql.schema.somepackage.RecordLikeClass +import graphql.schema.somepackage.RecordLikeTwoClassesDown import graphql.schema.somepackage.TestClass import graphql.schema.somepackage.TwoClassesDown import spock.lang.Specification import java.util.function.Function -import static graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment - +import static graphql.schema.DataFetchingEnvironmentImpl.newDataFetchingEnvironment + +/** + * Note : That `new PropertyDataFetcher("someProperty")` and `SingletonPropertyDataFetcher.singleton()` + * should really be the equivalent since they both go via `PropertyDataFetcherHelper.getPropertyValue` + * under the covers. + * + * But where we can we have tried to use `where` blocks to test both + * + */ +@SuppressWarnings("GroovyUnusedDeclaration") class PropertyDataFetcherTest extends Specification { - def env(obj) { + void setup() { + PropertyDataFetcher.setUseSetAccessible(true) + PropertyDataFetcher.setUseNegativeCache(true) + PropertyDataFetcher.clearReflectionCache() + PropertyDataFetcherHelper.setUseLambdaFactory(true) + } + + def env(String propertyName, Object obj) { + def fieldDefinition = GraphQLFieldDefinition.newFieldDefinition().name(propertyName).type(Scalars.GraphQLString).build() newDataFetchingEnvironment() - .executionContext(Mock(ExecutionContext)) - .source(obj).build() + .source(obj) + .fieldDefinition(fieldDefinition) + .arguments([argument1: "value1", argument2: "value2"]) + .build() } - class SomeObject { + static class SomeObject { String value } def "null source is always null"() { - def environment = env(null) - def fetcher = new PropertyDataFetcher("someProperty") + given: + def environment = env("someProperty", null) + expect: fetcher.get(environment) == null + + where: + fetcher | _ + new PropertyDataFetcher("someProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "function based fetcher works with non null source"() { - def environment = env(new SomeObject(value: "aValue")) + def environment = env("notused", new SomeObject(value: "aValue")) Function f = { obj -> obj['value'] } def fetcher = PropertyDataFetcher.fetching(f) expect: @@ -37,7 +70,7 @@ class PropertyDataFetcherTest extends Specification { } def "function based fetcher works with null source"() { - def environment = env(null) + def environment = env("notused", null) Function f = { obj -> obj['value'] } def fetcher = PropertyDataFetcher.fetching(f) expect: @@ -45,79 +78,295 @@ class PropertyDataFetcherTest extends Specification { } def "fetch via map lookup"() { - def environment = env(["mapProperty": "aValue"]) - def fetcher = PropertyDataFetcher.fetching("mapProperty") + given: + def environment = env("mapProperty", ["mapProperty": "aValue"]) + expect: fetcher.get(environment) == "aValue" + + where: + fetcher | _ + PropertyDataFetcher.fetching("mapProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "fetch via public getter with private subclass"() { - def environment = env(TestClass.createPackageProtectedImpl("aValue")) - def fetcher = new PropertyDataFetcher("packageProtectedProperty") + given: + def environment = env("packageProtectedProperty", TestClass.createPackageProtectedImpl("aValue")) + expect: fetcher.get(environment) == "aValue" + + where: + fetcher | _ + new PropertyDataFetcher("packageProtectedProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "fetch via method that isn't present"() { - def environment = env(new TestClass()) - def fetcher = new PropertyDataFetcher("valueNotPresent") + given: + def environment = env("valueNotPresent", new TestClass()) + + when: def result = fetcher.get(environment) - expect: + + then: result == null + + where: + fetcher | _ + new PropertyDataFetcher("valueNotPresent") | _ + SingletonPropertyDataFetcher.singleton() | _ + } def "fetch via method that is private"() { - def environment = env(new TestClass()) - def fetcher = new PropertyDataFetcher("privateProperty") + given: + def environment = env("privateProperty", new TestClass()) + + when: def result = fetcher.get(environment) - expect: + + then: result == "privateValue" + + where: + fetcher | _ + new PropertyDataFetcher("privateProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ + + } + + def "fetch via method that is private with setAccessible OFF"() { + given: + PropertyDataFetcher.setUseSetAccessible(false) + def environment = env("privateProperty", new TestClass()) + + when: + def result = fetcher.get(environment) + + then: + result == null + + where: + fetcher | _ + new PropertyDataFetcher("privateProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ + + } + + def "fetch via record method"() { + given: + def environment = env("recordProperty", new RecordLikeClass()) + + when: + def fetcher = new PropertyDataFetcher("recordProperty") + def result = fetcher.get(environment) + then: + result == "recordProperty" + + // caching works + when: + fetcher = new PropertyDataFetcher("recordProperty") + result = fetcher.get(environment) + then: + result == "recordProperty" + + // recordArgumentMethod will not work because it takes a parameter + when: + fetcher = new PropertyDataFetcher("recordArgumentMethod") + result = fetcher.get(environment) + then: + result == null + + // equals will not work because it takes a parameter + when: + fetcher = new PropertyDataFetcher("equals") + result = fetcher.get(environment) + then: + result == null + + // we allow hashCode() and toString() because why not - they are valid property names + // they might not be that useful but they can be accessed + + when: + fetcher = new PropertyDataFetcher("hashCode") + result = fetcher.get(environment) + then: + result == 666 + + when: + fetcher = new PropertyDataFetcher("toString") + result = fetcher.get(environment) + then: + result == "toString" + } + + def "fetch via record method with singleton fetcher"() { + given: + def environment = env("recordProperty", new RecordLikeClass()) + + when: + def fetcher = SingletonPropertyDataFetcher.singleton() + def result = fetcher.get(environment) + then: + result == "recordProperty" + } + + def "can fetch record like methods that are public and on super classes"() { + given: + def environment = env("recordProperty", new RecordLikeTwoClassesDown()) + + when: + def result = fetcher.get(environment) + + then: + result == "recordProperty" + + where: + fetcher | _ + new PropertyDataFetcher("recordProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ + } + + def "fetch via record method without lambda support"() { + given: + PropertyDataFetcherHelper.setUseLambdaFactory(false) + PropertyDataFetcherHelper.clearReflectionCache() + + when: + def environment = env("recordProperty", new RecordLikeClass()) + def fetcher = new PropertyDataFetcher("recordProperty") + def result = fetcher.get(environment) + + then: + result == "recordProperty" + + when: + environment = env("recordProperty", new RecordLikeTwoClassesDown()) + fetcher = new PropertyDataFetcher("recordProperty") + result = fetcher.get(environment) + + then: + result == "recordProperty" + } + + def "fetch via record method without lambda support in preference to getter methods"() { + given: + PropertyDataFetcherHelper.setUseLambdaFactory(false) + PropertyDataFetcherHelper.clearReflectionCache() + + when: + def environment = env("recordLike", new ConfusedPojo()) + def result = fetcher.get(environment) + + then: + result == "recordLike" + + where: + fetcher | _ + new PropertyDataFetcher("recordLike") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "fetch via public method"() { - def environment = env(new TestClass()) - def fetcher = new PropertyDataFetcher("publicProperty") + given: + def environment = env("publicProperty", new TestClass()) + + when: def result = fetcher.get(environment) - expect: + + then: result == "publicValue" + + where: + fetcher | _ + new PropertyDataFetcher("publicProperty") | _ + SingletonPropertyDataFetcher.singleton() | _ + } def "fetch via public method declared two classes up"() { - def environment = env(new TwoClassesDown("aValue")) + given: + def environment = env("publicProperty", new TwoClassesDown("aValue")) def fetcher = new PropertyDataFetcher("publicProperty") + + when: def result = fetcher.get(environment) - expect: + then: result == "publicValue" + + when: + result = fetcher.get(environment) + then: + result == "publicValue" + } def "fetch via property only defined on package protected impl"() { - def environment = env(TestClass.createPackageProtectedImpl("aValue")) - def fetcher = new PropertyDataFetcher("propertyOnlyDefinedOnPackageProtectedImpl") + given: + def environment = env("propertyOnlyDefinedOnPackageProtectedImpl", TestClass.createPackageProtectedImpl("aValue")) + + when: def result = fetcher.get(environment) - expect: + + then: result == "valueOnlyDefinedOnPackageProtectedIpl" + + where: + fetcher | _ + new PropertyDataFetcher("propertyOnlyDefinedOnPackageProtectedImpl") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "fetch via public field"() { - def environment = env(new TestClass()) - def fetcher = new PropertyDataFetcher("publicField") + given: + + def environment = env("publicField", new TestClass()) def result = fetcher.get(environment) + expect: result == "publicFieldValue" + + where: + fetcher | _ + new PropertyDataFetcher("publicField") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "fetch via private field"() { - def environment = env(new TestClass()) - def fetcher = new PropertyDataFetcher("privateField") + given: + def environment = env("privateField", new TestClass()) def result = fetcher.get(environment) + expect: result == "privateFieldValue" + + where: + fetcher | _ + new PropertyDataFetcher("privateField") | _ + SingletonPropertyDataFetcher.singleton() | _ + } + + def "fetch via private field when setAccessible OFF"() { + given: + PropertyDataFetcher.setUseSetAccessible(false) + def environment = env("privateField", new TestClass()) + def result = fetcher.get(environment) + + expect: + result == null + + where: + fetcher | _ + new PropertyDataFetcher("privateField") | _ + SingletonPropertyDataFetcher.singleton() | _ } def "fetch when caching is in place has no bad effects"() { - def environment = env(new TestClass()) + def environment = env("publicProperty", new TestClass()) def fetcher = new PropertyDataFetcher("publicProperty") when: def result = fetcher.get(environment) @@ -190,4 +439,432 @@ class PropertyDataFetcherTest extends Specification { } + def "support for DFE on methods"() { + given: + def environment = env("methodWithDFE", new ClassWithDFEMethods()) + def fetcher = new PropertyDataFetcher("methodWithDFE") + + when: + def result = fetcher.get(environment) + then: + result == "methodWithDFE" + + when: + fetcher = new PropertyDataFetcher("methodWithoutDFE") + result = fetcher.get(environment) + then: + result == "methodWithoutDFE" + + when: + fetcher = new PropertyDataFetcher("defaultMethodWithDFE") + result = fetcher.get(environment) + then: + result == "defaultMethodWithDFE" + + when: + fetcher = new PropertyDataFetcher("defaultMethodWithoutDFE") + result = fetcher.get(environment) + then: + result == "defaultMethodWithoutDFE" + + when: + fetcher = new PropertyDataFetcher("methodWithTooManyArgs") + result = fetcher.get(environment) + then: + result == null + + when: + fetcher = new PropertyDataFetcher("defaultMethodWithTooManyArgs") + result = fetcher.get(environment) + then: + result == null + + when: + fetcher = new PropertyDataFetcher("methodWithOneArgButNotDataFetchingEnvironment") + result = fetcher.get(environment) + then: + result == null + + when: + fetcher = new PropertyDataFetcher("defaultMethodWithOneArgButNotDataFetchingEnvironment") + result = fetcher.get(environment) + then: + result == null + + } + + def "finds interface methods"() { + when: + def environment = env("methodYouMustImplement", new ClassWithInterfaces()) + def fetcher = new PropertyDataFetcher("methodYouMustImplement") + def result = fetcher.get(environment) + then: + result == "methodYouMustImplement" + + when: + fetcher = new PropertyDataFetcher("methodYouMustAlsoImplement") + result = fetcher.get(environment) + then: + result == "methodYouMustAlsoImplement" + + when: + fetcher = new PropertyDataFetcher("methodThatIsADefault") + result = fetcher.get(environment) + then: + result == "methodThatIsADefault" + + when: + fetcher = new PropertyDataFetcher("methodThatIsAlsoADefault") + result = fetcher.get(environment) + then: + result == "methodThatIsAlsoADefault" + + } + + def "finds interface methods with inheritance"() { + def environment = env("methodYouMustImplement", new ClassWithInteritanceAndInterfaces.StartingClass()) + + when: + def fetcher = new PropertyDataFetcher("methodYouMustImplement") + def result = fetcher.get(environment) + then: + result == "methodYouMustImplement" + + when: + fetcher = new PropertyDataFetcher("methodThatIsADefault") + result = fetcher.get(environment) + then: + result == "methodThatIsADefault" + + def environment2 = env("methodYouMustImplement", new ClassWithInteritanceAndInterfaces.InheritedClass()) + + when: + fetcher = new PropertyDataFetcher("methodYouMustImplement") + result = fetcher.get(environment2) + then: + result == "methodYouMustImplement" + + when: + fetcher = new PropertyDataFetcher("methodThatIsADefault") + result = fetcher.get(environment2) + then: + result == "methodThatIsADefault" + + when: + fetcher = new PropertyDataFetcher("methodYouMustAlsoImplement") + result = fetcher.get(environment2) + then: + result == "methodYouMustAlsoImplement" + + when: + fetcher = new PropertyDataFetcher("methodThatIsAlsoADefault") + result = fetcher.get(environment2) + then: + result == "methodThatIsAlsoADefault" + } + + def "ensure DFE is passed to method"() { + + def environment = env("methodUsesDataFetchingEnvironment", new ClassWithDFEMethods()) + def fetcher = new PropertyDataFetcher("methodUsesDataFetchingEnvironment") + when: + def result = fetcher.get(environment) + then: + result == "value1" + + when: + fetcher = new PropertyDataFetcher("defaultMethodUsesDataFetchingEnvironment") + result = fetcher.get(environment) + then: + result == "value2" + } + + def "negative caching works as expected"() { + def environment = env("doesNotExist", new ClassWithDFEMethods()) + def fetcher = new PropertyDataFetcher("doesNotExist") + when: + def result = fetcher.get(environment) + then: + result == null + + when: + result = fetcher.get(environment) + then: + result == null + + when: + PropertyDataFetcher.setUseNegativeCache(false) + PropertyDataFetcher.clearReflectionCache() + result = fetcher.get(environment) + then: + result == null + + when: + PropertyDataFetcher.setUseNegativeCache(true) + PropertyDataFetcher.clearReflectionCache() + result = fetcher.get(environment) + then: + result == null + + } + + static class ProductDTO { + String name + String model + } + + class ProductData { + def data = [new ProductDTO(name: "Prado", model: "GLX"), new ProductDTO(name: "Camry", model: "Momento")] + + List getProducts(DataFetchingEnvironment env) { + boolean reverse = env.getArgument("reverseNames") + if (reverse) { + return data.collect { product -> new ProductDTO(name: product.name.reverse(), model: product.model) } + } else { + return data + } + } + } + + def "end to end test of property fetcher working"() { + def spec = ''' + type Query { + products(reverseNames : Boolean = false) : [Product] + } + + type Product { + name : String + model : String + } + ''' + + def graphQL = TestUtil.graphQL(spec).build() + def executionInput = ExecutionInput.newExecutionInput().query(''' + { + products(reverseNames : true) { + name + model + } + } + ''').root(new ProductData()).build() + + when: + def er = graphQL.execute(executionInput) + then: + er.errors.isEmpty() + er.data == [products: [[name: "odarP", model: "GLX"], [name: "yrmaC", model: "Momento"]]] + } + + interface Foo { + String getSomething(); + } + + private static class Bar implements Foo { + @Override + String getSomething() { + return "bar" + } + } + + private static class Baz extends Bar implements Foo {} + + def "search for private getter in class hierarchy"() { + given: + Bar bar = new Baz() + def dfe = env("something", bar) + + when: + def result = fetcher.get(dfe) + + then: + result == "bar" + + // repeat - should be cached + when: + result = fetcher.get(dfe) + + then: + result == "bar" + + where: + fetcher | _ + new PropertyDataFetcher("something") | _ + SingletonPropertyDataFetcher.singleton() | _ + } + + def "issue 3247 - record like statics should not be used"() { + given: + def payload = new UpdateOrganizerSubscriptionPayload(true, new OrganizerSubscriptionError()) + def dfe = env("success", payload) + + when: + def result = fetcher.get(dfe) + + then: + result == true + + // repeat - should be cached + when: + result = fetcher.get(dfe) + + then: + result == true + + where: + fetcher | _ + new PropertyDataFetcher("success") | _ + SingletonPropertyDataFetcher.singleton() | _ + } + + def "issue 3247 - record like statics should not be found"() { + given: + def errorShape = new OrganizerSubscriptionError() + def dfe = env("message", errorShape) + + when: + def result = fetcher.get(dfe) + + then: + result == null // not found as its a static recordLike() method + + // repeat - should be cached + when: + result = fetcher.get(dfe) + + then: + result == null + + where: + fetcher | _ + new PropertyDataFetcher("message") | _ + SingletonPropertyDataFetcher.singleton() | _ + } + + def "issue 3247 - getter statics should be found"() { + given: + def objectInQuestion = new BarClassWithStaticProperties() + def dfe = env("foo", objectInQuestion) + PropertyDataFetcher propertyDataFetcher = new PropertyDataFetcher("foo") + + when: + def result = propertyDataFetcher.get(dfe) + + then: + result == "foo" + + // repeat - should be cached + when: + result = propertyDataFetcher.get(dfe) + + then: + result == "foo" + + when: + propertyDataFetcher = new PropertyDataFetcher("bar") + result = propertyDataFetcher.get(dfe) + + then: + result == "bar" + + // repeat - should be cached + when: + result = propertyDataFetcher.get(dfe) + + then: + result == "bar" + } + + class BaseObject { + private String id + + String getId() { + return id + } + + void setId(String value) { + id = value; + } + } + + class OtherObject extends BaseObject {} + + def "Can access private property from base class that starts with i in Turkish"() { + // see https://github.com/graphql-java/graphql-java/issues/3385 + given: + Locale oldLocale = Locale.getDefault() + Locale.setDefault(new Locale("tr", "TR")) + + def environment = env("id", new OtherObject(id: "aValue")) + + when: + def fetcher = PropertyDataFetcher.fetching("id") + String propValue = fetcher.get(environment) + + then: + propValue == 'aValue' + + when: + fetcher = SingletonPropertyDataFetcher.singleton() + propValue = fetcher.get(environment) + + then: + propValue == 'aValue' + + cleanup: + Locale.setDefault(oldLocale) + } + /** + * Classes from issue to ensure we reproduce as reported by customers + * + * In the UpdateOrganizerSubscriptionPayload class we will find the getSuccess() because static recordLike() methods are no longer allowed + */ + static class OrganizerSubscriptionError { + static String message() { return "error " } + } + + static class UpdateOrganizerSubscriptionPayload { + private final Boolean success + private final OrganizerSubscriptionError error + + UpdateOrganizerSubscriptionPayload(Boolean success, OrganizerSubscriptionError error) { + this.success = success + this.error = error + } + + static UpdateOrganizerSubscriptionPayload success() { + // 👈 note the static factory method for creating a success payload + return new UpdateOrganizerSubscriptionPayload(Boolean.TRUE, null) + } + + static UpdateOrganizerSubscriptionPayload error(OrganizerSubscriptionError error) { + // 👈 note the static factory method for creating a success payload + return new UpdateOrganizerSubscriptionPayload(null, error) + } + + Boolean getSuccess() { + return success + } + + OrganizerSubscriptionError getError() { + return error + } + + + @Override + String toString() { + return new StringJoiner( + ", ", UpdateOrganizerSubscriptionPayload.class.getSimpleName() + "[", "]") + .add("success=" + success) + .add("error=" + error) + .toString() + } + } + + static class FooClassWithStaticProperties { + static String getFoo() { return "foo" } + } + + static class BarClassWithStaticProperties extends FooClassWithStaticProperties { + static String getBar() { return "bar" } + } } diff --git a/src/test/groovy/graphql/schema/SchemaPrinterComparatorsTest.groovy b/src/test/groovy/graphql/schema/SchemaPrinterComparatorsTest.groovy new file mode 100644 index 0000000000..35ef8ab026 --- /dev/null +++ b/src/test/groovy/graphql/schema/SchemaPrinterComparatorsTest.groovy @@ -0,0 +1,794 @@ +package graphql.schema + +import graphql.TestUtil +import graphql.schema.idl.SchemaPrinter +import spock.lang.Specification + +import java.util.stream.Collectors + +import static graphql.Scalars.GraphQLInt +import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.* +import static graphql.schema.DefaultGraphqlTypeComparatorRegistry.DEFAULT_COMPARATOR +import static graphql.schema.DefaultGraphqlTypeComparatorRegistry.newComparators +import static graphql.schema.GraphQLEnumType.newEnum +import static graphql.schema.GraphQLEnumValueDefinition.newEnumValueDefinition +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInputObjectField.newInputObjectField +import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLInterfaceType.newInterface +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLScalarType.newScalar +import static graphql.schema.GraphQLUnionType.newUnionType +import static graphql.schema.GraphqlTypeComparatorEnvironment.newEnvironment +import static graphql.schema.idl.SchemaPrinter.Options.defaultOptions + +class SchemaPrinterComparatorsTest extends Specification { + + def "scalarPrinter default comparator"() { + given: + GraphQLScalarType scalarType = newScalar(mockScalar("TestScalar")) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .build() + + when: + def options = defaultOptions().includeScalarTypes(true) + def result = new SchemaPrinter(options).print(scalarType) + + then: + result == '''"TestScalar" +scalar TestScalar @a(a : 0, bb : 0) @bb(a : 0, bb : 0) +''' + } + + def "enumPrinter default comparator"() { + given: + GraphQLEnumType enumType = newEnum().name("TestEnum") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .value(newEnumValueDefinition().name("a").value(0).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .value(newEnumValueDefinition().name("bb").value(1).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + + when: + def options = defaultOptions() + def result = new SchemaPrinter(options).print(enumType) + + then: + result == '''enum TestEnum @a(a : 0, bb : 0) @bb(a : 0, bb : 0) { + a @a(a : 0, bb : 0) @bb(a : 0, bb : 0) + bb @a(a : 0, bb : 0) @bb(a : 0, bb : 0) +} +''' + } + + def "unionPrinter default comparator"() { + given: + GraphQLUnionType unionType = newUnionType().name("TestUnion") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .possibleType(newObject().name("a").build()) + .possibleType(newObject().name("bb").build()) + .build() + + when: + def options = defaultOptions() + def result = new SchemaPrinter(options).print(unionType) + + then: + result == '''union TestUnion @a(a : 0, bb : 0) @bb(a : 0, bb : 0) = a | bb +''' + } + + def "interfacePrinter default comparator"() { + given: + // @formatter:off + GraphQLInterfaceType interfaceType = newInterface().name("TypeA") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def options = defaultOptions() + def result = new SchemaPrinter(options).print(interfaceType) + + then: + result == '''interface TypeA @a(a : 0, bb : 0) @bb(a : 0, bb : 0) { + a(a: Int, bb: Int): String @a(a : 0, bb : 0) @bb(a : 0, bb : 0) + bb(a: Int, bb: Int): String @a(a : 0, bb : 0) @bb(a : 0, bb : 0) +} +''' + } + + def "objectPrinter default comparator"() { + given: + // @formatter:off + GraphQLObjectType objectType = newObject().name("TypeA") + .withInterfaces(newInterface().name("a").build(), newInterface().name("bb").build()) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def options = defaultOptions() + def result = new SchemaPrinter(options).print(objectType) + + then: + result == '''type TypeA implements a & bb @a(a : 0, bb : 0) @bb(a : 0, bb : 0) { + a(a: Int, bb: Int): String @a(a : 0, bb : 0) @bb(a : 0, bb : 0) + bb(a: Int, bb: Int): String @a(a : 0, bb : 0) @bb(a : 0, bb : 0) +} +''' + } + + def "inputObjectPrinter default comparator"() { + given: + // @formatter:off + GraphQLInputObjectType inputObjectType = newInputObject().name("TypeA") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newInputObjectField().name("a") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newInputObjectField().name("bb") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def options = defaultOptions() + def result = new SchemaPrinter(options).print(inputObjectType) + + then: + result == '''input TypeA @a(a : 0, bb : 0) @bb(a : 0, bb : 0) { + a: String @a(a : 0, bb : 0) @bb(a : 0, bb : 0) + bb: String @a(a : 0, bb : 0) @bb(a : 0, bb : 0) +} +''' + } + + def "argsString default comparator"() { + given: + def args = mockArguments("a", "bb") + + when: + def options = defaultOptions() + def printer = new SchemaPrinter(options) + + then: + printer.argsString(args) == '''(a: Int, bb: Int)''' + printer.argsString(null, args) == '''(a: Int, bb: Int)''' + } + + def "directivesString default comparator"() { + given: + def directives = mockDirectivesWithArguments("a", "bb").collect { it } + + when: + def options = defaultOptions() + def result = new SchemaPrinter(options).directivesString(null, directives) + + then: + result == ''' @a(a : 0, bb : 0) @bb(a : 0, bb : 0)''' + } + + def "scalarPrinter uses most specific registered comparators"() { + given: + GraphQLScalarType scalarType = newScalar(mockScalar("TestScalar")) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .build() + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLScalarType.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().includeScalarTypes(true).setComparators(registry) + def result = new SchemaPrinter(options).print(scalarType) + + then: + result == '''"TestScalar" +scalar TestScalar @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +''' + } + + def "scalarPrinter uses least specific registered comparators"() { + given: + GraphQLScalarType scalarType = newScalar(mockScalar("TestScalar")) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .build() + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().includeScalarTypes(true).setComparators(registry) + def result = new SchemaPrinter(options).print(scalarType) + + then: + result == '''"TestScalar" +scalar TestScalar @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +''' + } + + def "enumPrinter uses most specific registered comparators"() { + given: + GraphQLEnumType enumType = newEnum().name("TestEnum") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .value(newEnumValueDefinition().name("a").value(0).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .value(newEnumValueDefinition().name("bb").value(1).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLEnumType.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLEnumType.class).elementType(GraphQLEnumValueDefinition.class) }, GraphQLEnumValueDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLEnumValueDefinition.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(enumType) + + then: + result == '''enum TestEnum @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "enumPrinter uses least specific registered comparators"() { + given: + GraphQLEnumType enumType = newEnum().name("TestEnum") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .value(newEnumValueDefinition().name("a").value(0).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .value(newEnumValueDefinition().name("bb").value(1).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLEnumValueDefinition.class) }, GraphQLEnumValueDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(enumType) + + then: + result == '''enum TestEnum @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "unionPrinter uses most specific registered comparators"() { + given: + GraphQLUnionType unionType = newUnionType().name("TestUnion") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .possibleType(newObject().name("a").build()) + .possibleType(newObject().name("bb").build()) + .build() + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLUnionType.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLUnionType.class).elementType(GraphQLOutputType.class) }, GraphQLOutputType.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(unionType) + + then: + result == '''union TestUnion @bb(bb : 0, a : 0) @a(bb : 0, a : 0) = bb | a +''' + } + + def "unionPrinter uses least specific registered comparators"() { + given: + GraphQLUnionType unionType = newUnionType().name("TestUnion") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .possibleType(newObject().name("a").build()) + .possibleType(newObject().name("bb").build()) + .build() + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLOutputType.class) }, GraphQLOutputType.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(unionType) + + then: + result == '''union TestUnion @bb(bb : 0, a : 0) @a(bb : 0, a : 0) = bb | a +''' + } + + def "interfacePrinter uses most specific registered comparators"() { + given: + // @formatter:off + GraphQLInterfaceType interfaceType = newInterface().name("TypeA") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLInterfaceType.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLInterfaceType.class).elementType(GraphQLFieldDefinition.class) }, GraphQLFieldDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(interfaceType) + + then: + result == '''interface TypeA @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "interfacePrinter uses least specific registered comparators"() { + given: + // @formatter:off + GraphQLInterfaceType interfaceType = newInterface().name("TypeA") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLFieldDefinition.class) }, GraphQLFieldDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(interfaceType) + + then: + result == '''interface TypeA @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "objectPrinter uses most specific registered comparators"() { + given: + // @formatter:off + GraphQLObjectType objectType = newObject().name("TypeA") + .withInterfaces(newInterface().name("a") .build(), newInterface().name("bb").build()) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLObjectType.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLObjectType.class).elementType(GraphQLOutputType.class) }, GraphQLOutputType.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLObjectType.class).elementType(GraphQLFieldDefinition.class) }, GraphQLFieldDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLAppliedDirective.class) }, GraphQLDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(objectType) + + then: + result == '''type TypeA implements bb & a @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "objectPrinter uses least specific registered comparators"() { + given: + // @formatter:off + GraphQLObjectType objectType = newObject().name("TypeA") + .withInterfaces(newInterface().name("a") .build(), newInterface().name("bb").build()) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLOutputType.class) }, GraphQLOutputType.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLFieldDefinition.class) }, GraphQLFieldDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(objectType) + + then: + result == '''type TypeA implements bb & a @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "inputObjectPrinter uses most specific registered comparators"() { + given: + // @formatter:off + GraphQLInputObjectType inputObjectType = newInputObject().name("TypeA") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newInputObjectField().name("a") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newInputObjectField().name("bb") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLInputObjectType.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLInputObjectType.class).elementType(GraphQLInputObjectField.class) }, GraphQLInputObjectField.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLInputObjectField.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(inputObjectType) + + then: + result == '''input TypeA @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb: String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a: String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "inputObjectPrinter uses least specific registered comparators"() { + given: + // @formatter:off + GraphQLInputObjectType inputObjectType = newInputObject().name("TypeA") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newInputObjectField().name("a") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newInputObjectField().name("bb") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLInputObjectField.class) }, GraphQLInputObjectField.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).print(inputObjectType) + + then: + result == '''input TypeA @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb: String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a: String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "argsString uses most specific registered comparators"() { + given: + def field = newFieldDefinition().name("field").type(GraphQLInt).arguments(mockArguments("a", "bb")).build() + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def printer = new SchemaPrinter(options) + + then: + printer.argsString(GraphQLFieldDefinition.class, field.arguments) == '''(bb: Int, a: Int)''' + } + + def "argsString uses least specific registered comparators"() { + given: + def field = newFieldDefinition().name("field").type(GraphQLInt).arguments(mockArguments("a", "bb")).build() + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def printer = new SchemaPrinter(options) + + then: + printer.argsString(GraphQLFieldDefinition.class, field.arguments) == '''(bb: Int, a: Int)''' + printer.argsString(null, field.arguments) == '''(bb: Int, a: Int)''' + } + + + def "directivesString uses most specific registered comparators"() { + given: + def field = newFieldDefinition().name("field") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .build() + + when: + def registry = newComparators() + .addComparator({ it.parentType(GraphQLFieldDefinition.class).elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).directivesString(GraphQLFieldDefinition.class, field) + + then: + result == ''' @bb(bb : 0, a : 0) @a(bb : 0, a : 0)''' + } + + def "directivesString uses least specific registered comparators"() { + given: + def field = newFieldDefinition().name("field") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .build() + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.parentType(GraphQLAppliedDirective.class).elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().setComparators(registry) + def result = new SchemaPrinter(options).directivesString(GraphQLFieldDefinition.class, field) + + then: + result == ''' @bb(bb : 0, a : 0) @a(bb : 0, a : 0)''' + } + + + def "least specific comparator applied across different types"() { + given: + // @formatter:off + GraphQLScalarType scalarType = newScalar(mockScalar("TestScalar")) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .build() + + GraphQLUnionType unionType = newUnionType().name("TestUnion") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .possibleType(newObject().name("a").build()) + .possibleType(newObject().name("bb").build()) + .build() + + GraphQLEnumType enumType = newEnum().name("TestEnum") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .value(newEnumValueDefinition().name("a").value(0).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .value(newEnumValueDefinition().name("bb").value(0).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + + GraphQLObjectType objectType = newObject().name("TestObjectType") + .withInterfaces(newInterface().name("a") .build(), newInterface().name("bb").build()) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString).withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + + GraphQLInterfaceType interfaceType = newInterface().name("TestInterfaceType") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newFieldDefinition().name("a") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newFieldDefinition().name("bb") + .arguments(mockArguments("a", "bb")) + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + + GraphQLInputObjectType inputObjectType = newInputObject().name("TestInputObjectType") + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")) + .field(newInputObjectField().name("a") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .field(newInputObjectField().name("bb") + .type(GraphQLString) + .withAppliedDirectives(mockDirectivesWithArguments("a", "bb")).build()) + .build() + // @formatter:on + + when: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLFieldDefinition.class) }, GraphQLFieldDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLInputObjectField.class) }, GraphQLInputObjectField.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLEnumValueDefinition.class) }, GraphQLEnumValueDefinition.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLOutputType.class) }, GraphQLOutputType.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirective.class) }, GraphQLAppliedDirective.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLAppliedDirectiveArgument.class) }, GraphQLAppliedDirectiveArgument.class, TestUtil.byGreatestLength) + .addComparator({ it.elementType(GraphQLArgument.class) }, GraphQLArgument.class, TestUtil.byGreatestLength) + .build() + def options = defaultOptions().includeScalarTypes(true).setComparators(registry) + def printer = new SchemaPrinter(options) + + def scalarResult = printer.print(scalarType) + def enumResult = printer.print(enumType) + def unionResult = printer.print(unionType) + def objectTypeResult = printer.print(objectType) + def interfaceTypeResult = printer.print(interfaceType) + def inputObjectTypeResult = printer.print(inputObjectType) + + then: + + scalarResult == '''"TestScalar" +scalar TestScalar @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +''' + + enumResult == '''enum TestEnum @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + + unionResult == '''union TestUnion @bb(bb : 0, a : 0) @a(bb : 0, a : 0) = bb | a +''' + + interfaceTypeResult == '''interface TestInterfaceType @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + + objectTypeResult == '''type TestObjectType implements bb & a @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a(bb: Int, a: Int): String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + + inputObjectTypeResult == '''input TestInputObjectType @bb(bb : 0, a : 0) @a(bb : 0, a : 0) { + bb: String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) + a: String @bb(bb : 0, a : 0) @a(bb : 0, a : 0) +} +''' + } + + def "DefaultSchemaPrinterComparatorRegistry finds expected comparator"() { + given: + def registry = newComparators() + .addComparator({ it.elementType(GraphQLFieldDefinition.class) }, GraphQLFieldDefinition.class, TestUtil.byGreatestLength) + .build() + + when: + def result = registry.getComparator(newEnvironment().elementType(GraphQLFieldDefinition.class).build()) + + then: + result == byGreatestLength + } + + def "DefaultSchemaPrinterComparatorRegistry provides default comparator when environment is not found"() { + given: + def registry = newComparators().build() + + when: + def result = registry.getComparator(newEnvironment().elementType(GraphQLFieldDefinition.class).build()) + + then: + result == DEFAULT_COMPARATOR + } + + def "directive string when argument has no value"() { + given: + GraphQLScalarType scalarType = newScalar(mockScalar("TestScalar")) + .withAppliedDirectives(mockDirectivesWithNoValueArguments("a", "bb")) + .build() + + when: + def options = defaultOptions().includeScalarTypes(true) + def result = new SchemaPrinter(options).print(scalarType) + + then: + result == '''"TestScalar" +scalar TestScalar @a @bb +''' + } + + def " sort GraphQLSchemaElement by name or toString()"() { + given: + def coercing = new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + return null + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + return null + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + return null + } + } + + def a = newScalar() + .name("a") + .coercing(coercing) + .build() + def b = newScalar() + .name("b") + .coercing(coercing) + .build() + + def nonNullA = GraphQLNonNull.nonNull(a) + def nonNullB = GraphQLNonNull.nonNull(b) + def list = [nonNullB, nonNullA] + + when: + def sortedList = list.stream().sorted( + DEFAULT_COMPARATOR).collect(Collectors.toList() + ) + + then: + sortedList == [nonNullA, nonNullB] + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/schema/SchemaTransformerTest.groovy b/src/test/groovy/graphql/schema/SchemaTransformerTest.groovy new file mode 100644 index 0000000000..9513ed39fc --- /dev/null +++ b/src/test/groovy/graphql/schema/SchemaTransformerTest.groovy @@ -0,0 +1,1105 @@ +package graphql.schema + +import graphql.GraphQL +import graphql.Scalars +import graphql.TestUtil +import graphql.schema.idl.RuntimeWiring +import graphql.schema.idl.SchemaPrinter +import graphql.util.TraversalControl +import graphql.util.TraverserContext +import spock.lang.Specification + +import static graphql.schema.FieldCoordinates.coordinates +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema +import static graphql.schema.GraphQLTypeReference.typeRef +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring + +class SchemaTransformerTest extends Specification { + + def "can change field in schema"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + type Query { + hello: Foo + } + type Foo { + bar: String + } + """) + schema.getQueryType() + SchemaTransformer schemaTransformer = new SchemaTransformer() + when: + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "bar") { + def changedNode = fieldDefinition.transform({ builder -> builder.name("barChanged") }) + return changeNode(context, changedNode) + } + return TraversalControl.CONTINUE + } + }) + + then: + newSchema != schema + (newSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("barChanged") != null + } + + def "can remove field in schema"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + type Query { + hello: Foo + } + type Foo { + bar: String + baz: String + } + """) + schema.getQueryType() + SchemaTransformer schemaTransformer = new SchemaTransformer() + when: + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "baz") { + return deleteNode(context) + } + return TraversalControl.CONTINUE + } + }) + + then: + newSchema != schema + (newSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("baz") == null + } + + def "can change schema with logical cycles"() { + given: + GraphQLObjectType foo = newObject() + .name("Foo") + .field(newFieldDefinition() + .name("foo") + .type(typeRef("Foo")) + .build() + ).build() + GraphQLObjectType query = newObject() + .name("Query") + .field(newFieldDefinition() + .name("queryField") + .type(foo) + .build() + ).build() + GraphQLSchema schema = newSchema() + .query(query).build() + SchemaTransformer schemaTransformer = new SchemaTransformer() + when: + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "foo") { + def changedNode = fieldDefinition.transform({ builder -> builder.name("fooChanged") }) + return changeNode(context, changedNode) + } + return TraversalControl.CONTINUE + } + }) + + then: + newSchema != schema + newSchema.typeMap.size() == schema.typeMap.size() + (newSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("fooChanged") != null + (newSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("fooChanged").getType() == newSchema.getType("Foo") + } + + def "transform with interface"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + type Query { + hello: Foo + } + + interface Foo { + bar: String + } + + type FooImpl implements Foo { + bar: String + baz: String + } + """) + schema.getQueryType() + SchemaTransformer schemaTransformer = new SchemaTransformer() + when: + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "baz") { + return deleteNode(context) + } + return TraversalControl.CONTINUE + } + }) + + then: + newSchema != schema + (newSchema.getType("FooImpl") as GraphQLObjectType).getFieldDefinition("baz") == null + } + + def "elements having more than one parent"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + type Query { + parent: Parent + } + type Parent { + child1: Child + child2: Child + subChild: SubChild + otherParent: Parent + } + type Child { + hello: String + subChild: SubChild + } + type SubChild { + hello: String + } + """) + SchemaTransformer schemaTransformer = new SchemaTransformer() + when: + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "hello") { + def changedNode = fieldDefinition.transform({ builder -> builder.name("helloChanged") }) + return changeNode(context, changedNode) + } + return TraversalControl.CONTINUE + } + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (node.name == "Parent") { + def changedNode = node.transform({ builder -> builder.name("ParentChanged") }) + return changeNode(context, changedNode) + } + if (node.name == "SubChild") { + def changedNode = node.transform({ builder -> builder.name("SubChildChanged") }) + return changeNode(context, changedNode) + } + return super.visitGraphQLObjectType(node, context) + } + + @Override + TraversalControl visitGraphQLTypeReference(GraphQLTypeReference node, TraverserContext context) { + if (node.name == "Parent") { + return changeNode(context, typeRef("ParentChanged")) + } + return super.visitGraphQLTypeReference(node, context) + } + }) + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(false)) + then: + printer.print(newSchema) == """type Child { + helloChanged: String + subChild: SubChildChanged +} + +type ParentChanged { + child1: Child + child2: Child + otherParent: ParentChanged + subChild: SubChildChanged +} + +type Query { + parent: ParentChanged +} + +type SubChildChanged { + helloChanged: String +} +""" + newSchema != schema + (newSchema.getType("Child") as GraphQLObjectType).getFieldDefinition("helloChanged") != null + + + } + + def "traverses all types"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + type Query { + hello: Foo + } + + type Subscription { + fooHappened: FooEvent + } + + type Mutation { + updateFoo(foo: FooUpdate): Boolean + } + + type FooEvent { + foo: Foo + timestamp: Int + } + + type Foo { + bar: Bar + } + + input FooUpdate { + newBarBaz: String + } + + type Bar { + baz: String + } + + type Baz { + bing: String + } + + """) + SchemaTransformer schemaTransformer = new SchemaTransformer() + + when: + final Set visitedTypeNames = [] + schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + visitedTypeNames << node.name + + TraversalControl.CONTINUE + } + + @Override + TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + visitedTypeNames << node.name + + TraversalControl.CONTINUE + } + }) + + then: + visitedTypeNames.containsAll(['Foo', 'FooUpdate', 'FooEvent', 'Bar', 'Baz']) + } + + + def "transformed schema can be executed programmatically"() { + + given: + // build query and schema manually so we have a test that uses a programmatic approach rather than the SDL. + def queryObject = newObject() + .name("Query") + .field({ builder -> + builder.name("foo") + .type(Scalars.GraphQLString) + }).build() + + def fooCoordinates = FieldCoordinates.coordinates("Query", "foo") + DataFetcher dataFetcher = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment environment) throws Exception { + return "bar" + } + } + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(fooCoordinates, dataFetcher) + .build() + + def schemaObject = newSchema() + .codeRegistry(codeRegistry) + .query(queryObject) + .build() + + when: + def result = GraphQL.newGraphQL(schemaObject) + .build() + .execute(''' + { foo } + ''').getData() + + then: + (result as Map)['foo'] == 'bar' + + when: + def newSchema = SchemaTransformer.transformSchema(schemaObject, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + if (node.name == 'foo') { + def changedNode = node.transform({ builder -> builder.name('fooChanged') }) + return changeNode(context, changedNode) + } + + return TraversalControl.CONTINUE + } + }) + + def fooTransformedCoordinates = FieldCoordinates.coordinates("Query", "fooChanged") + codeRegistry = codeRegistry.transform({ it.dataFetcher(fooTransformedCoordinates, dataFetcher) }) + newSchema = newSchema.transform({ + builder -> builder.codeRegistry(codeRegistry) + }) + result = GraphQL.newGraphQL(newSchema) + .build() + .execute(''' + { fooChanged } + ''').getData() + + then: + (result as Map)['fooChanged'] == 'bar' + } + + def "transformed schema can be executed"() { + + given: + GraphQLSchema schema = TestUtil.schema(""" + type Query { + foo: String + } + """, RuntimeWiring.newRuntimeWiring() + .type(newTypeWiring("Query") + .dataFetcher("foo", + { env -> + return "bar" + }) + ).build() + ) + + when: + def result = GraphQL.newGraphQL(schema) + .build().execute(''' + { foo } + ''').getData() + + then: + (result as Map)['foo'] == 'bar' + + when: + def newSchema = SchemaTransformer.transformSchema(schema, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + GraphQLCodeRegistry.Builder registryBuilder = context.getVarFromParents(GraphQLCodeRegistry.Builder.class) + + if (node.name == 'foo') { + def changedNode = node.transform({ builder -> builder.name('fooChanged') }) + registryBuilder.dataFetcher(coordinates("Query", "fooChanged"), + schema.getCodeRegistry().getDataFetcher(coordinates("Query", "foo"), node)) + + return changeNode(context, changedNode) + } + + return TraversalControl.CONTINUE + } + }) + result = GraphQL.newGraphQL(newSchema) + .build().execute(''' + { fooChanged } + ''').getData() + + then: + (result as Map)['fooChanged'] == 'bar' + + } + + def "type references are replaced again after transformation"() { + given: + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("account").type(typeRef("Account")).build()) + .build() + + def account = newObject() + .name("Account") + .field(newFieldDefinition().name("name").type(Scalars.GraphQLString).build()) + .field(newFieldDefinition().name("billingStatus").type(typeRef("BillingStatus")).build()) + .build() + + def billingStatus = newObject() + .name("BillingStatus") + .field(newFieldDefinition().name("id").type(Scalars.GraphQLString).build()) + .build() + + def schema = newSchema() + .query(query) + .additionalType(billingStatus) + .additionalType(account) + .build() + when: + SchemaTransformer schemaTransformer = new SchemaTransformer() + GraphQLSchema newSchema = schemaTransformer.transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.name == "billingStatus") { + return deleteNode(context) + } + return TraversalControl.CONTINUE + } + }) + + then: + newSchema != schema + (newSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + newSchema.getType("Account") == (newSchema.getType("Query") as GraphQLObjectType).getFieldDefinition("account").getType() + + } + + def "test as reported in 1928 "() { + given: + + def internalNoteHider = new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLDirective(GraphQLDirective node, + TraverserContext context) { + if ("internalnote" == node.getName()) { + // this deletes the declaration and the two usages of it + deleteNode(context) + } + return TraversalControl.CONTINUE + } + } + + GraphQLSchema schema = TestUtil.schema(""" + directive @internalnote(doc: String!) on OBJECT | FIELD_DEFINITION | INTERFACE + + type Query { + fooBar: Foo + } + + interface Manchu @internalnote(doc:"...") { + id: ID! + } + + type Foo implements Manchu { + id: ID! + } + + type Bar @internalnote(doc:"...") { + id: ID! + hidden: String! + } + + union FooBar = Foo | Bar + """) + + when: + def newSchema = SchemaTransformer.transformSchema(schema, internalNoteHider) + + then: + newSchema.getType("FooBar") != null + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(false)) + then: + printer.print(newSchema) == """interface Manchu { + id: ID! +} + +union FooBar = Bar | Foo + +type Bar { + hidden: String! + id: ID! +} + +type Foo implements Manchu { + id: ID! +} + +type Query { + fooBar: Foo +} +""" + } + + def "test as reported in 1953 "() { + given: + + def fieldChanger = new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, + TraverserContext context) { + if (node.getName() == "f") { + changeNode(context, node.transform({ builder -> builder.type(Scalars.GraphQLInt) })) + } + return TraversalControl.CONTINUE + } + } + + GraphQLSchema schema = TestUtil.schema(""" + type Query { + manchu: Manchu + foo: Foo + } + + interface Manchu { + id: ID! + f: String + } + + type Foo implements Manchu { + id: ID! + f: String + } + """) + + when: + def newSchema = SchemaTransformer.transformSchema(schema, fieldChanger) + + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(false)) + then: + (newSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("f").getType() == Scalars.GraphQLInt + printer.print(newSchema) == """interface Manchu { + f: Int + id: ID! +} + +type Foo implements Manchu { + f: Int + id: ID! +} + +type Query { + foo: Foo + manchu: Manchu +} +""" + } + + def "can change a schema element only"() { + def sdl = ''' + type Query { + f : Foo + } + type Foo { + foo : Foo + bar : Bar + } + type Bar { + b : EnumType + } + enum EnumType { + E + } + ''' + def schema = TestUtil.schema(sdl) + def oldType = schema.getObjectType("Foo") + when: + GraphQLObjectType newType = new SchemaTransformer().transform(oldType, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + node = node.transform({ b -> b.name(node.getName().toUpperCase()) }) + return changeNode(context, node) + } + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + node = node.transform({ b -> b.name(node.getName().toUpperCase()) }) + return changeNode(context, node) + } + }) + then: + newType.getName() == "FOO" + newType.getFieldDefinition("FOO") != null + newType.getFieldDefinition("BAR") != null + } + + def "can handle self referencing type which require type references"() { + def sdl = ''' + type Query { + f : Foo + } + type Foo { + foo : Foo + bar : Bar + } + type Bar { + foo : Foo + enum : EnumType + } + enum EnumType { + e + } + ''' + def schema = TestUtil.schema(sdl) + + when: + GraphQLSchema newSchema = new SchemaTransformer().transform(schema, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + node = node.transform({ b -> b.name(node.getName().toUpperCase()) }) + return changeNode(context, node) + } + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (node.getName().startsWith("__")) return TraversalControl.ABORT + node = node.transform({ b -> b.name(node.getName().toUpperCase()) }) + return changeNode(context, node) + } + }) + then: + + // all our fields are upper case as are our object types + def queryType = newSchema.getObjectType("QUERY") + def fooType = newSchema.getObjectType("FOO") + def barType = newSchema.getObjectType("BAR") + def enumType = newSchema.getType("EnumType") as GraphQLEnumType + + queryType.getFieldDefinition("F").getType().is(fooType) // groovy object equality + fooType.getFieldDefinition("FOO").getType().is(fooType) + fooType.getFieldDefinition("BAR").getType().is(barType) + + barType.getFieldDefinition("FOO").getType().is(fooType) + barType.getFieldDefinition("ENUM").getType().is(enumType) + + enumType.getValue("e") != null // left alone + } + + def "cycle with type refs"() { + given: + def field = newFieldDefinition() + .name("foo") + .type(typeRef("Foo")) + .build() + + def query = newObject() + .name("Query") + .field(field) + .build() + def foo = newObject() + .name("Foo") + .field(newFieldDefinition().name("toChange").type(Scalars.GraphQLString)) + .field(newFieldDefinition().name("subFoo").type(typeRef("Foo"))) + .build() + + + GraphQLSchema schema = newSchema().query(query).additionalType(foo).build() + def fieldChanger = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, + TraverserContext context) { + if (node.getName() == "toChange") { + changeNode(context, node.transform({ builder -> builder.name("changed") })) + } + return TraversalControl.CONTINUE + } + } + + when: + def newSchema = SchemaTransformer.transformSchema(schema, fieldChanger) + + def newFoo = newSchema.getQueryType().getFieldDefinition("foo").getType() as GraphQLObjectType + then: + newFoo.getFieldDefinition("changed") != null + } + + def "delete type which is references twice"() { + def sdl = ''' + type Query { + u1: U1 + u2: U2 + } + union U1 = A | ToDel + union U2 = B | ToDel + type A { + a: String + } + type B { + a: String + } + type ToDel { + a: String + } + + ''' + def schema = TestUtil.schema(sdl) + + when: + GraphQLSchema newSchema = new SchemaTransformer().transform(schema, new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (node.getName() == 'ToDel') { + return deleteNode(context) + } + return TraversalControl.CONTINUE + } + }) + then: + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(false)) + printer.print(newSchema) == '''union U1 = A + +union U2 = B + +type A { + a: String +} + +type B { + a: String +} + +type Query { + u1: U1 + u2: U2 +} +''' + } + + def "if nothing changes in the schema transformer, we return the same object"() { + + def schema = TestUtil.schema("type Query { f : String }") + + def fieldChanger = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, + TraverserContext context) { + return TraversalControl.CONTINUE + } + } + + when: + def newSchema = SchemaTransformer.transformSchema(schema, fieldChanger) + then: + newSchema === schema + } + + def "__Field can be changed"() { + // this is a test when only + // one element inside a scc is changed + def schema = TestUtil.schema("type Query { f : String }") + + def fieldChanger = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (node.name == "__Field") { + return changeNode(context, node.transform({ it.name("__FieldChanged") })) + } + return TraversalControl.CONTINUE + } + } + + when: + def newSchema = SchemaTransformer.transformSchema(schema, fieldChanger) + then: + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(false)) + printer.print(newSchema) == '''type Query { + f: String +} +''' + newSchema.getObjectType("__FieldChanged") != null + newSchema.getObjectType("__Field") == null + + } + + + def "applied directive and applied args can be changed"() { + // this is a test when only + // one element inside a scc is changed + def schema = TestUtil.schema(""" + directive @foo(arg1 : String) on FIELD_DEFINITION + directive @bar(arg1 : String) on FIELD_DEFINITION + type Query { + field : String @foo(arg1 : "fooArg") + field2 : String @bar(arg1 : "barArg") + } +""") + + def visitor = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + if (context.getParentNode() instanceof GraphQLAppliedDirective) { + GraphQLAppliedDirective directive = context.getParentNode() + if (directive.name == "foo") { + if (node.name == "arg1") { + def newNode = node.transform({ + it.name("changedArg1") + }) + return changeNode(context, newNode) + } + } + } + return TraversalControl.CONTINUE + } + + @Override + TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective node, TraverserContext context) { + return super.visitGraphQLAppliedDirective(node, context) + } + + } + + when: + def newSchema = SchemaTransformer.transformSchema(schema, visitor) + then: + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(true)) + def newQueryType = newSchema.getObjectType("Query") + + printer.print(newQueryType) == '''type Query { + field: String @foo(changedArg1 : "fooArg") + field2: String @bar(arg1 : "barArg") +} +''' + } + + def "can rename scalars"() { + + def schema = TestUtil.schema(""" + scalar Foo + type Query { + field : Foo + } +""") + + def visitor = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + if (node.getName() == "Foo") { + GraphQLScalarType newNode = node.transform({ sc -> sc.name("Bar") }) + return changeNode(context, newNode) + } + return super.visitGraphQLScalarType(node, context) + } + } + + when: + def newSchema = SchemaTransformer.transformSchema(schema, visitor) + then: + newSchema.getType("Bar") instanceof GraphQLScalarType + newSchema.getType("Foo") == null + (newSchema.getObjectType("Query").getFieldDefinition("field").getType() as GraphQLScalarType).getName() == "Bar" + } + + def "rename scalars are changed in applied arguments"() { + + def schema = TestUtil.schema(""" + scalar Foo + directive @myDirective(fooArgOnDirective: Foo) on FIELD_DEFINITION + type Query { + foo(fooArgOnField: Foo) : Foo @myDirective + } +""") + + def visitor = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + if (node.getName() == "Foo") { + GraphQLScalarType newNode = node.transform({ sc -> sc.name("Bar") }) + return changeNode(context, newNode) + } + return super.visitGraphQLScalarType(node, context) + } + } + + when: + def newSchema = SchemaTransformer.transformSchema(schema, visitor) + then: + + def fieldDef = newSchema.getObjectType("Query").getFieldDefinition("foo") + def appliedDirective = fieldDef.getAppliedDirective("myDirective") + def oldSkoolDirective = fieldDef.getDirective("myDirective") + def argument = fieldDef.getArgument("fooArgOnField") + def directiveDecl = newSchema.getDirective("myDirective") + def directiveArgument = directiveDecl.getArgument("fooArgOnDirective") + + (fieldDef.getType() as GraphQLScalarType).getName() == "Bar" + (argument.getType() as GraphQLScalarType).getName() == "Bar" + (directiveArgument.getType() as GraphQLScalarType).getName() == "Bar" + + (oldSkoolDirective.getArgument("fooArgOnDirective").getType() as GraphQLScalarType).getName() == "Bar" + + newSchema.getType("Bar") instanceof GraphQLScalarType + + // not working at this stage + (appliedDirective.getArgument("fooArgOnDirective").getType() as GraphQLScalarType).getName() == "Bar" + newSchema.getType("Foo") == null + } + + def "has access to common variables"() { + def schema = TestUtil.schema(""" + type Query { + foo : String + } + """) + + def visitedSchema = null + def visitedCodeRegistry = null + def visitor = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + visitedSchema = context.getVarFromParents(GraphQLSchema.class) + visitedCodeRegistry = context.getVarFromParents(GraphQLCodeRegistry.Builder.class) + return super.visitGraphQLFieldDefinition(node, context) + } + + } + + when: + SchemaTransformer.transformSchema(schema, visitor) + + then: + visitedSchema == schema + visitedCodeRegistry instanceof GraphQLCodeRegistry.Builder + } + + def "deprecation transformation correctly overrides existing deprecated directive reasons"() { + def schema = TestUtil.schema(""" + schema { + query: QueryType + } + + type QueryType { + a: String + b: String @deprecated(reason: "Replace this doc") + } + + interface InterfaceType { + a: String + b: String @deprecated(reason: "Replace this doc") + } + + input InputType { + a: String + b: String @deprecated(reason: "Replace this doc") + } + """) + + when: + def typeVisitor = new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + def n = node.transform(b -> b.deprecate("NEW REASON")); + return changeNode(context, n); + } + + @Override + TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + def n = node.transform(b -> b.deprecate("NEW REASON")); + return changeNode(context, n); + } + } + def newSchema = SchemaTransformer.transformSchema(schema, typeVisitor) + + then: + def newQueryType = newSchema.getObjectType("QueryType") + def newQueryTypePrinted = new SchemaPrinter().print(newQueryType) + + newQueryTypePrinted == """type QueryType { + a: String @deprecated(reason : "NEW REASON") + b: String @deprecated(reason : "NEW REASON") +} +""" + def newInterfaceType = newSchema.getType("InterfaceType") + def newInterfaceTypePrinted = new SchemaPrinter().print(newInterfaceType) + newInterfaceTypePrinted == """interface InterfaceType { + a: String @deprecated(reason : "NEW REASON") + b: String @deprecated(reason : "NEW REASON") +} +""" + def newInputType = newSchema.getType("InputType") + def newInputTypePrinted = new SchemaPrinter().print(newInputType) + newInputTypePrinted == """input InputType { + a: String @deprecated(reason : "NEW REASON") + b: String @deprecated(reason : "NEW REASON") +} +""" + } + + def "issue 4133 reproduction"() { + def sdl = """ + directive @remove on FIELD_DEFINITION + + type Query { + rental: Rental @remove + customer: Customer + } + + type Store { + inventory: Inventory @remove + } + + type Inventory { + store: Store @remove + } + + type Customer { + rental: Rental + payment: Payment @remove + } + + type Payment { + inventory: Inventory @remove + } + + type Rental { + id: ID + customer: Customer @remove + } + """ + + def schema = TestUtil.schema(sdl) + schema = schema.transform { builder -> + for (def type : schema.getTypeMap().values()) { + if (type != schema.getQueryType() && type != schema.getMutationType() && type != schema.getSubscriptionType()) { + builder.additionalType(type) + } + } + } + + + def visitor = new GraphQLTypeVisitorStub() { + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + if (node.hasAppliedDirective("remove")) { + return deleteNode(context) + } + return TraversalControl.CONTINUE + } + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + if (node.getFields().stream().allMatch(field -> field.hasAppliedDirective("remove"))) { + return deleteNode(context) + } + + return TraversalControl.CONTINUE + } + } + when: + def newSchema = SchemaTransformer.transformSchema(schema, visitor) + def printer = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(false)) + def newSdl = printer.print(newSchema) + + then: + newSdl.trim() == """type Customer { + rental: Rental +} + +type Query { + customer: Customer +} + +type Rental { + id: ID +}""".trim() + } +} diff --git a/src/test/groovy/graphql/schema/SchemaTraverserTest.groovy b/src/test/groovy/graphql/schema/SchemaTraverserTest.groovy new file mode 100644 index 0000000000..f7a6fc8a9c --- /dev/null +++ b/src/test/groovy/graphql/schema/SchemaTraverserTest.groovy @@ -0,0 +1,529 @@ +package graphql.schema + +import graphql.Scalars +import graphql.TestUtil +import graphql.util.TraversalControl +import graphql.util.TraverserContext +import spock.lang.Specification + +import static graphql.introspection.Introspection.DirectiveLocation +import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLTypeReference.typeRef +import static graphql.schema.GraphqlTypeComparatorRegistry.BY_NAME_REGISTRY +import static graphql.TestUtil.mkDirective + +class SchemaTraverserTest extends Specification { + + def "reachable scalar type"() { + + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, Scalars.GraphQLString) + + then: + visitor.getStack() == ["scalar: String", "fallback: String"] + } + + def "reachable string argument type"() { + when: + def visitor = new GraphQLTestingVisitor() + + new SchemaTraverser().depthFirst(visitor, newArgument() + .name("Test") + .type(Scalars.GraphQLString) + .build()) + then: + visitor.getStack() == ["argument: Test", "fallback: Test", "scalar: String", "fallback: String"] + } + + def "reachable number argument type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, newArgument() + .name("Test") + .type(Scalars.GraphQLInt) + .build()) + then: + visitor.getStack() == ["argument: Test", "fallback: Test", "scalar: Int", "fallback: Int"] + } + + def "reachable enum type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLEnumType + .newEnum() + .name("foo") + .value("bar") + .value(GraphQLEnumValueDefinition.newEnumValueDefinition().name("abc").value(123).build()) + .comparatorRegistry(BY_NAME_REGISTRY) + .build()) + then: + visitor.getStack() == ["enum: foo", "fallback: foo", + "enum value: abc", "fallback: abc", + "enum value: bar", "fallback: bar"] + } + + def "reachable field definition type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLFieldDefinition.newFieldDefinition() + .name("foo") + .type(Scalars.GraphQLString) + .build()) + then: + visitor.getStack() == ["field: foo", "fallback: foo", "scalar: String", "fallback: String"] + } + + def "reachable input object field type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLInputObjectField.newInputObjectField() + .name("bar") + .type(Scalars.GraphQLString) + .build()) + then: + visitor.getStack() == ["input object field: bar", "fallback: bar", "scalar: String", "fallback: String"] + } + + def "reachable input object type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLInputObjectType.newInputObject() + .name("foo") + .field(GraphQLInputObjectField.newInputObjectField() + .name("bar") + .type(Scalars.GraphQLString) + .build()) + .build()) + then: + visitor.getStack() == ["input object: foo", "fallback: foo", + "input object field: bar", "fallback: bar", + "scalar: String", "fallback: String"] + } + + def "reachable interface type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLInterfaceType.newInterface() + .name("foo") + .field(GraphQLFieldDefinition.newFieldDefinition() + .name("bar") + .type(Scalars.GraphQLString) + .build()) + .build()) + then: + visitor.getStack() == ["interface: foo", "fallback: foo", + "field: bar", "fallback: bar", + "scalar: String", "fallback: String"] + } + + def "reachable list type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLList.list(Scalars.GraphQLString)) + then: + visitor.getStack() == ["list: String", "fallback: [String]", + "scalar: String", "fallback: String"] + } + + + def "reachable nonNull type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLNonNull.nonNull(Scalars.GraphQLString)) + then: + visitor.getStack() == ["nonNull: String", "fallback: String!", + "scalar: String", "fallback: String"] + } + + def "reachable object type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLObjectType.newObject() + .name("myObject") + .field(GraphQLFieldDefinition.newFieldDefinition() + .name("foo") + .type(Scalars.GraphQLString) + .build()) + .withInterface(GraphQLInterfaceType.newInterface() + .name("bar") + .build()) + .build()) + then: + visitor.getStack() == ["object: myObject", "fallback: myObject", + "field: foo", "fallback: foo", + "scalar: String", "fallback: String", + "interface: bar", "fallback: bar"] + } + + def "reachable reference type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, typeRef("something")) + then: + visitor.getStack() == ["reference: something", "fallback: something"] + } + + def "reachable union type"() { + when: + def visitor = new GraphQLTestingVisitor() + new SchemaTraverser().depthFirst(visitor, GraphQLUnionType.newUnionType() + .name("foo") + .possibleType(GraphQLObjectType.newObject().name("dummy").build()) + .possibleType(typeRef("dummyRef")) + .build()) + then: + visitor.getStack() == ["union: foo", "fallback: foo", + "object: dummy", "fallback: dummy", + "reference: dummyRef", "fallback: dummyRef"] + } + + def "reachable scalar directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def coercing = new Coercing() { + private static final String TEST_ONLY = "For testing only" + + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + throw new UnsupportedOperationException(TEST_ONLY) + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + throw new UnsupportedOperationException(TEST_ONLY) + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + throw new UnsupportedOperationException(TEST_ONLY) + } + } + def scalarType = GraphQLScalarType.newScalar() + .name("foo") + .coercing(coercing) + .withDirective(mkDirective("bar", DirectiveLocation.SCALAR)) + .withAppliedDirective(GraphQLAppliedDirective.newDirective() + .name("barApplied")) + .build() + new SchemaTraverser().depthFirst(visitor, scalarType) + then: + visitor.getStack() == [ + "scalar: foo", "fallback: foo", "directive: bar", "fallback: bar", "appliedDirective: barApplied", "fallback: barApplied" + ] + } + + def "reachable object directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def objectType = GraphQLObjectType.newObject() + .name("foo") + .withDirective(mkDirective("bar", DirectiveLocation.OBJECT)) + .withAppliedDirective(GraphQLAppliedDirective.newDirective() + .name("barApplied")) + .build() + new SchemaTraverser().depthFirst(visitor, objectType) + then: + visitor.getStack() == [ + "object: foo", "fallback: foo", "directive: bar", "fallback: bar", "appliedDirective: barApplied", "fallback: barApplied" + ] + } + + def "reachable field definition directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def fieldDefinition = GraphQLFieldDefinition.newFieldDefinition() + .name("foo") + .type(Scalars.GraphQLString) + .withDirective(mkDirective("bar", DirectiveLocation.FIELD_DEFINITION)) + .withAppliedDirective(GraphQLAppliedDirective.newDirective() + .name("barApplied")) + .build() + new SchemaTraverser().depthFirst(visitor, fieldDefinition) + then: + visitor.getStack() == [ + "field: foo", "fallback: foo", "scalar: String", "fallback: String", "directive: bar", "fallback: bar", "appliedDirective: barApplied", "fallback: barApplied" + ] + } + + def "reachable argument directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def argument = newArgument() + .name("foo") + .type(Scalars.GraphQLString) + .withDirective(mkDirective("bar", DirectiveLocation.ARGUMENT_DEFINITION)) + .withAppliedDirective(GraphQLAppliedDirective.newDirective() + .name("barApplied")) + .build() + new SchemaTraverser().depthFirst(visitor, argument) + then: + visitor.getStack() == [ + "argument: foo", "fallback: foo", "scalar: String", "fallback: String", "directive: bar", "fallback: bar", "appliedDirective: barApplied", "fallback: barApplied" + ] + } + + def "reachable interface directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def interfaceType = GraphQLInterfaceType.newInterface() + .name("foo") + .withDirective(mkDirective("bar", DirectiveLocation.INTERFACE)) + .withAppliedDirective(GraphQLAppliedDirective.newDirective() + .name("barApplied")) + .build() + new SchemaTraverser().depthFirst(visitor, interfaceType) + then: + visitor.getStack() == [ + "interface: foo", "fallback: foo", "directive: bar", "fallback: bar", "appliedDirective: barApplied", "fallback: barApplied" + ] + } + + def "reachable union directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def unionType = GraphQLUnionType.newUnionType() + .name("foo") + .possibleType(GraphQLObjectType.newObject().name("dummy").build()) + .withDirective(mkDirective("bar", DirectiveLocation.UNION)) + .build() + new SchemaTraverser().depthFirst(visitor, unionType) + then: + visitor.getStack() == ["union: foo", "fallback: foo", "object: dummy", "fallback: dummy", "directive: bar", "fallback: bar"] + } + + def "reachable enum directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def enumType = GraphQLEnumType.newEnum() + .name("foo") + .value("dummy") + .withDirective(mkDirective("bar", DirectiveLocation.ENUM)) + .build() + new SchemaTraverser().depthFirst(visitor, enumType) + then: + visitor.getStack() == ["enum: foo", "fallback: foo", "enum value: dummy", "fallback: dummy", "directive: bar", "fallback: bar"] + } + + def "reachable enum value directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def enumValue = GraphQLEnumValueDefinition.newEnumValueDefinition() + .name("foo") + .withDirective(mkDirective("bar", DirectiveLocation.ENUM_VALUE)) + .build() + new SchemaTraverser().depthFirst(visitor, enumValue) + then: + visitor.getStack() == ["enum value: foo", "fallback: foo", "directive: bar", "fallback: bar"] + } + + def "reachable input object directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def inputObjectType = GraphQLInputObjectType.newInputObject() + .name("foo") + .withDirective(mkDirective("bar", DirectiveLocation.INPUT_OBJECT)) + .build() + new SchemaTraverser().depthFirst(visitor, inputObjectType) + then: + visitor.getStack() == ["input object: foo", "fallback: foo", "directive: bar", "fallback: bar"] + } + + def "reachable input field definition directive"() { + when: + def visitor = new GraphQLTestingVisitor() + def inputField = GraphQLInputObjectField.newInputObjectField() + .name("foo") + .type(Scalars.GraphQLString) + .withDirective(mkDirective("bar", DirectiveLocation.INPUT_FIELD_DEFINITION)) + .build() + new SchemaTraverser().depthFirst(visitor, inputField) + then: + visitor.getStack() == ["input object field: foo", "fallback: foo", "scalar: String", "fallback: String", "directive: bar", "fallback: bar"] + } + + def "back references is are called when a type reference node is visited more than once"() { + when: + def visitor = new GraphQLTestingVisitor() + + def typeRef = typeRef("String") + + new SchemaTraverser().depthFirst(visitor, [ + newArgument() + .name("Test1") + .type(typeRef) + .build(), + newArgument() + .name("Test2") + .type(typeRef) + .build() + ]) + then: + visitor.getStack() == ["argument: Test1", "fallback: Test1", "reference: String", "fallback: String", + "argument: Test2", "fallback: Test2", "backRef: String" + ] + } + + def "can quit the schema traverser"() { + def sdl = """ + type Query { + f : ObjType + f2NeverVisited : String + } + + type ObjType { + fQuit : ObjType2 + } + + type ObjType2 { + neverVisited : String + } + """ + + def schema = TestUtil.schema(sdl) + + def visitor = new GraphQLTestingVisitor() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + super.visitGraphQLFieldDefinition(node, context) + if (node.name.contains("Quit")) { + return TraversalControl.QUIT + } + return TraversalControl.CONTINUE + } + } + + when: + new SchemaTraverser().depthFirstFullSchema(visitor, schema) + + then: + visitor.getStack() == ["object: Query", + "fallback: Query", + "field: f", + "fallback: f", + "object: ObjType", + "fallback: ObjType", + "field: fQuit", + "fallback: fQuit", + ] + } + + class GraphQLTestingVisitor extends GraphQLTypeVisitorStub { + + def stack = [] + + @Override + TraversalControl visitGraphQLAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument node, TraverserContext context) { + stack.add("appliedArgument: ${node.getName()}") + return super.visitGraphQLAppliedDirectiveArgument(node, context) + } + + @Override + TraversalControl visitGraphQLAppliedDirective(GraphQLAppliedDirective node, TraverserContext context) { + stack.add("appliedDirective: ${node.getName()}") + return super.visitGraphQLAppliedDirective(node, context) + } + + @Override + TraversalControl visitGraphQLArgument(GraphQLArgument node, TraverserContext context) { + stack.add("argument: ${node.getName()}") + return super.visitGraphQLArgument(node, context) + } + + @Override + TraversalControl visitGraphQLScalarType(GraphQLScalarType node, TraverserContext context) { + stack.add("scalar: ${node.getName()}") + return super.visitGraphQLScalarType(node, context) + } + + @Override + protected TraversalControl visitGraphQLType(GraphQLSchemaElement node, TraverserContext context) { + stack.add("fallback: ${GraphQLTypeUtil.simplePrint(node)}") + return super.visitGraphQLType(node, context) + } + + @Override + TraversalControl visitGraphQLEnumType(GraphQLEnumType node, TraverserContext context) { + stack.add("enum: ${node.getName()}") + return super.visitGraphQLEnumType(node, context) + } + + @Override + TraversalControl visitGraphQLEnumValueDefinition(GraphQLEnumValueDefinition node, TraverserContext context) { + stack.add("enum value: ${node.getName()}") + return super.visitGraphQLEnumValueDefinition(node, context) + } + + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext context) { + stack.add("field: ${node.getName()}") + return super.visitGraphQLFieldDefinition(node, context) + } + + @Override + TraversalControl visitGraphQLDirective(GraphQLDirective node, TraverserContext context) { + stack.add("directive: ${node.getName()}") + return super.visitGraphQLDirective(node, context) + } + + @Override + TraversalControl visitGraphQLInputObjectField(GraphQLInputObjectField node, TraverserContext context) { + stack.add("input object field: ${node.getName()}") + return super.visitGraphQLInputObjectField(node, context) + } + + @Override + TraversalControl visitGraphQLInputObjectType(GraphQLInputObjectType node, TraverserContext context) { + stack.add("input object: ${node.getName()}") + return super.visitGraphQLInputObjectType(node, context) + } + + @Override + TraversalControl visitGraphQLInterfaceType(GraphQLInterfaceType node, TraverserContext context) { + stack.add("interface: ${node.getName()}") + return super.visitGraphQLInterfaceType(node, context) + } + + @Override + TraversalControl visitGraphQLList(GraphQLList node, TraverserContext context) { + stack.add("list: ${node.getWrappedType().getName()}") + return super.visitGraphQLList(node, context) + } + + @Override + TraversalControl visitGraphQLNonNull(GraphQLNonNull node, TraverserContext context) { + stack.add("nonNull: ${node.getWrappedType().getName()}") + return super.visitGraphQLNonNull(node, context) + } + + @Override + TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext context) { + stack.add("object: ${node.getName()}") + return super.visitGraphQLObjectType(node, context) + } + + @Override + TraversalControl visitGraphQLTypeReference(GraphQLTypeReference node, TraverserContext context) { + stack.add("reference: ${node.getName()}") + return super.visitGraphQLTypeReference(node, context) + } + + @Override + TraversalControl visitGraphQLUnionType(GraphQLUnionType node, TraverserContext context) { + stack.add("union: ${node.getName()}") + return super.visitGraphQLUnionType(node, context) + } + + @Override + TraversalControl visitBackRef(TraverserContext context) { + stack.add("backRef: ${context.thisNode().getName()}") + return TraversalControl.CONTINUE + } + + def getStack() { + return stack + } + } + + +} diff --git a/src/test/groovy/graphql/schema/diff/SchemaDiffTest.groovy b/src/test/groovy/graphql/schema/diff/SchemaDiffTest.groovy index 42b393293a..fbefc15de2 100644 --- a/src/test/groovy/graphql/schema/diff/SchemaDiffTest.groovy +++ b/src/test/groovy/graphql/schema/diff/SchemaDiffTest.groovy @@ -1,5 +1,6 @@ package graphql.schema.diff +import graphql.AssertException import graphql.TestUtil import graphql.language.Argument import graphql.language.Directive @@ -15,6 +16,7 @@ import graphql.language.TypeName import graphql.schema.Coercing import graphql.schema.DataFetcher import graphql.schema.GraphQLScalarType +import graphql.schema.GraphQLSchema import graphql.schema.PropertyDataFetcher import graphql.schema.TypeResolver import graphql.schema.diff.reporting.CapturingReporter @@ -30,77 +32,121 @@ import spock.lang.Specification import java.util.stream.Collectors class SchemaDiffTest extends Specification { - private CapturingReporter reporter - private ChainedReporter chainedReporter + private CapturingReporter introspectionReporter + private CapturingReporter sdlReporter + private ChainedReporter introspectionChainedReporter + private ChainedReporter sdlChainedReporter private static final TypeResolver NULL_TYPE_RESOLVER = { env -> null } - static GraphQLScalarType CUSTOM_SCALAR = new GraphQLScalarType("CustomScalar", "CustomScalar", new Coercing() { - @Override - Object serialize(Object dataFetcherResult) { - throw new UnsupportedOperationException("Not implemented") - } - - @Override - Object parseValue(Object input) { - throw new UnsupportedOperationException("Not implemented") - } - - @Override - Object parseLiteral(Object input) { - throw new UnsupportedOperationException("Not implemented") - } - }) + static GraphQLScalarType CUSTOM_SCALAR = GraphQLScalarType + .newScalar() + .name("CustomScalar") + .description("CustomScalar") + .coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) { + throw new UnsupportedOperationException("Not implemented") + } + + @Override + Object parseValue(Object input) { + throw new UnsupportedOperationException("Not implemented") + } + + @Override + Object parseLiteral(Object input) { + throw new UnsupportedOperationException("Not implemented") + } + }) + .build() static RuntimeWiring wireWithNoFetching() { return RuntimeWiring.newRuntimeWiring() .wiringFactory(new WiringFactory() { - @Override - boolean providesTypeResolver(UnionWiringEnvironment environment) { - return true - } - - @Override - boolean providesTypeResolver(InterfaceWiringEnvironment environment) { - return true - } - - @Override - TypeResolver getTypeResolver(InterfaceWiringEnvironment environment) { - return NULL_TYPE_RESOLVER - } - - @Override - TypeResolver getTypeResolver(UnionWiringEnvironment environment) { - return NULL_TYPE_RESOLVER - } - - @Override - DataFetcher getDefaultDataFetcher(FieldWiringEnvironment environment) { - return new PropertyDataFetcher(environment.getFieldDefinition().getName()) - } - }) + @Override + boolean providesTypeResolver(UnionWiringEnvironment environment) { + return true + } + + @Override + boolean providesTypeResolver(InterfaceWiringEnvironment environment) { + return true + } + + @Override + TypeResolver getTypeResolver(InterfaceWiringEnvironment environment) { + return NULL_TYPE_RESOLVER + } + + @Override + TypeResolver getTypeResolver(UnionWiringEnvironment environment) { + return NULL_TYPE_RESOLVER + } + + @Override + DataFetcher getDefaultDataFetcher(FieldWiringEnvironment environment) { + return new PropertyDataFetcher(environment.getFieldDefinition().getName()) + } + }) .scalar(CUSTOM_SCALAR) .build() } void setup() { - reporter = new CapturingReporter() - chainedReporter = new ChainedReporter(reporter, new PrintStreamReporter()) + introspectionReporter = new CapturingReporter() + sdlReporter = new CapturingReporter() + introspectionChainedReporter = new ChainedReporter(introspectionReporter, new PrintStreamReporter()) + sdlChainedReporter = new ChainedReporter(sdlReporter, new PrintStreamReporter()) + } + + void compareDiff(String newFile) { + SchemaDiffSet introspectionSchemaDiffSet = introspectionSchemaDiffSet(newFile) + SchemaDiffSet sdlSchemaDiffSet = sdlSchemaDiffSet(newFile) + + def diff = new SchemaDiff() + diff.diffSchema(introspectionSchemaDiffSet, introspectionChainedReporter) + diff.diffSchema(sdlSchemaDiffSet, sdlChainedReporter) } - DiffSet diffSet(String newFile) { + void compareDiff(GraphQLSchema oldSchema, GraphQLSchema newSchema) { + SchemaDiffSet introspectionSchemaDiffSet = SchemaDiffSet.diffSetFromIntrospection(oldSchema, newSchema) + SchemaDiffSet sdlSchemaDiffSet = SchemaDiffSet.diffSetFromSdl(oldSchema, newSchema) + + def diff = new SchemaDiff() + diff.diffSchema(introspectionSchemaDiffSet, introspectionChainedReporter) + diff.diffSchema(sdlSchemaDiffSet, sdlChainedReporter) + } + + void validateReportersAreEqual() { + introspectionReporter.events == sdlReporter.events + introspectionReporter.infos == sdlReporter.infos + introspectionReporter.dangers == sdlReporter.dangers + introspectionReporter.breakages == sdlReporter.breakages + introspectionReporter.breakageCount == sdlReporter.breakageCount + introspectionReporter.infoCount == sdlReporter.infoCount + introspectionReporter.dangerCount == sdlReporter.dangerCount + } + + SchemaDiffSet introspectionSchemaDiffSet(String newFile) { def schemaOld = TestUtil.schemaFile("diff/" + "schema_ABaseLine.graphqls", wireWithNoFetching()) def schemaNew = TestUtil.schemaFile("diff/" + newFile, wireWithNoFetching()) - def diffSet = DiffSet.diffSet(schemaOld, schemaNew) + def diffSet = SchemaDiffSet.diffSetFromIntrospection(schemaOld, schemaNew) diffSet } + SchemaDiffSet sdlSchemaDiffSet(String newFile) { + def schemaOld = TestUtil.schemaFile("diff/" + "schema_ABaseLine.graphqls", wireWithNoFetching()) + def schemaNew = TestUtil.schemaFile("diff/" + newFile, wireWithNoFetching()) - def "change_in_null_ness"() { + def diffSet = SchemaDiffSet.diffSetFromSdl(schemaOld, schemaNew) + diffSet + } + + def "change_in_null_ness_input_or_arg"() { given: Type baseLine = new NonNullType(new ListType(new TypeName("foo"))) @@ -111,12 +157,12 @@ class SchemaDiffTest extends Specification { def diff = new SchemaDiff() - def sameType = diff.checkTypeWithNonNullAndList(baseLine, same) + def sameType = diff.checkTypeWithNonNullAndListOnInputOrArg(baseLine, same) - def lessStrict = diff.checkTypeWithNonNullAndList(baseLine, less) + def lessStrict = diff.checkTypeWithNonNullAndListOnInputOrArg(baseLine, less) // not allowed as old clients wont work - def moreStrict = diff.checkTypeWithNonNullAndList(less, baseLine) + def moreStrict = diff.checkTypeWithNonNullAndListOnInputOrArg(less, baseLine) expect: @@ -125,18 +171,60 @@ class SchemaDiffTest extends Specification { moreStrict == DiffCategory.STRICTER } - def "change_in_list_ness"() { + def "change_in_null_ness_object_or_interface"() { given: - Type baseLine = new NonNullType(new ListType(new TypeName("foo"))) + Type nonNull = new NonNullType(new ListType(new TypeName("foo"))) + Type nonNullDuplicate = new NonNullType(new ListType(new TypeName("foo"))) + + Type nullable = new ListType(new TypeName("foo")) + + + def diff = new SchemaDiff() + + def sameType = diff.checkTypeWithNonNullAndListOnObjectOrInterface(nonNull, nonNullDuplicate) + + def removeGuarantee = diff.checkTypeWithNonNullAndListOnObjectOrInterface(nonNull, nullable) + + def addGuarantee = diff.checkTypeWithNonNullAndListOnObjectOrInterface(nullable, nonNull) + + + expect: + sameType == null + removeGuarantee == DiffCategory.STRICTER + addGuarantee == null + } + + def "change_in_list_ness_input_or_arg"() { + + given: + Type list = new NonNullType(new ListType(new TypeName("foo"))) + Type notList = new NonNullType(new TypeName("foo")) + + def diff = new SchemaDiff() + + def noLongerList = diff.checkTypeWithNonNullAndListOnInputOrArg(list, notList) + def nowList = diff.checkTypeWithNonNullAndListOnInputOrArg(notList, list) + + expect: + noLongerList == DiffCategory.INVALID + nowList == DiffCategory.INVALID + } + + def "change_in_list_ness_object_or_interface"() { + + given: + Type list = new NonNullType(new ListType(new TypeName("foo"))) Type notList = new NonNullType(new TypeName("foo")) def diff = new SchemaDiff() - def noLongerList = diff.checkTypeWithNonNullAndList(baseLine, notList) + def noLongerList = diff.checkTypeWithNonNullAndListOnObjectOrInterface(list, notList) + def nowList = diff.checkTypeWithNonNullAndListOnObjectOrInterface(list, notList) expect: noLongerList == DiffCategory.INVALID + nowList == DiffCategory.INVALID } DiffEvent lastBreakage(CapturingReporter capturingReporter) { @@ -147,7 +235,7 @@ class SchemaDiffTest extends Specification { def "directives_controlled_via_options"() { given: - DiffCtx ctx = new DiffCtx(reporter, null, null) + DiffCtx ctx = new DiffCtx(introspectionReporter, null, null) TypeDefinition left = new ObjectTypeDefinition("fooType") @@ -156,11 +244,11 @@ class SchemaDiffTest extends Specification { def diff = new SchemaDiff() diff.checkDirectives(ctx, left, twoDirectives, oneDirective) - def notChecked = lastBreakage(reporter) + def notChecked = lastBreakage(introspectionReporter) diff = new SchemaDiff(SchemaDiff.Options.defaultOptions().enforceDirectives()) diff.checkDirectives(ctx, left, twoDirectives, oneDirective) - def missingDirective = lastBreakage(reporter) + def missingDirective = lastBreakage(introspectionReporter) expect: notChecked == null @@ -171,7 +259,7 @@ class SchemaDiffTest extends Specification { def "directives enforced to be the same"() { given: - DiffCtx ctx = new DiffCtx(reporter, null, null) + DiffCtx ctx = new DiffCtx(introspectionReporter, null, null) TypeDefinition left = new ObjectTypeDefinition("fooType") @@ -182,7 +270,7 @@ class SchemaDiffTest extends Specification { def diff = new SchemaDiff(SchemaDiff.Options.defaultOptions().enforceDirectives()) diff.checkDirectives(ctx, left, twoDirectives, oneDirective) - def missingDirective = lastBreakage(reporter) + def missingDirective = lastBreakage(introspectionReporter) def oldDirective = new Directive("foo", [ new Argument("arg1", new StringValue("p1")), @@ -195,7 +283,7 @@ class SchemaDiffTest extends Specification { ]) diff.checkDirectives(ctx, left, [oldDirective], [newDirective]) - def missingArgs = lastBreakage(reporter) + def missingArgs = lastBreakage(introspectionReporter) def newDirectiveDiffDefaultType = new Directive("foo", [ @@ -204,36 +292,32 @@ class SchemaDiffTest extends Specification { ]) diff.checkDirectives(ctx, left, [oldDirective], [newDirectiveDiffDefaultType]) - def changedType = lastBreakage(reporter) + def changedType = lastBreakage(introspectionReporter) expect: missingDirective.category == DiffCategory.MISSING missingArgs.category == DiffCategory.MISSING changedType.category == DiffCategory.INVALID - reporter.getBreakageCount() == 3 + introspectionReporter.getBreakageCount() == 3 } def "same schema diff"() { - DiffSet diffSet = diffSet("schema_ABaseLine.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_ABaseLine.graphqls") expect: - reporter.breakageCount == 0 + validateReportersAreEqual() + introspectionReporter.breakageCount == 0 } def "additional field"() { - DiffSet diffSet = diffSet("schema_with_additional_field.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_with_additional_field.graphqls") expect: - reporter.breakageCount == 0 + validateReportersAreEqual() + introspectionReporter.breakageCount == 0 - List newFieldEvents = reporter.infos.stream() - .filter{de -> de.typeName == "Ainur" && de.fieldName == "surname"} + List newFieldEvents = introspectionReporter.infos.stream() + .filter { de -> de.typeName == "Ainur" && de.fieldName == "surname" } .collect(Collectors.toList()) newFieldEvents.size() == 2 @@ -244,224 +328,483 @@ class SchemaDiffTest extends Specification { } def "missing fields on interface"() { - DiffSet diffSet = diffSet("schema_interface_fields_missing.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_interface_fields_missing.graphqls") expect: - reporter.breakageCount == 8 // 2 fields removed from interface, affecting 3 types - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.Interface + validateReportersAreEqual() + introspectionReporter.breakageCount == 8 // 2 fields removed from interface, affecting 3 types + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.Interface - reporter.breakages[1].category == DiffCategory.MISSING - reporter.breakages[1].typeKind == TypeKind.Interface + introspectionReporter.breakages[1].category == DiffCategory.MISSING + introspectionReporter.breakages[1].typeKind == TypeKind.Interface } def "missing members on union"() { - DiffSet diffSet = diffSet("schema_missing_union_members.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_missing_union_members.graphqls") expect: - reporter.breakageCount == 1 // 1 member removed - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.Union - + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 // 1 member removed + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.Union } def "missing fields on object"() { - DiffSet diffSet = diffSet("schema_missing_object_fields.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_missing_object_fields.graphqls") expect: - reporter.breakageCount == 2 // 2 fields removed - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.Object - reporter.breakages[0].fieldName == 'colour' + validateReportersAreEqual() + introspectionReporter.breakageCount == 2 // 2 fields removed + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.Object + introspectionReporter.breakages[0].fieldName == 'colour' - reporter.breakages[1].category == DiffCategory.MISSING - reporter.breakages[1].typeKind == TypeKind.Object - reporter.breakages[1].fieldName == 'temperament' + introspectionReporter.breakages[1].category == DiffCategory.MISSING + introspectionReporter.breakages[1].typeKind == TypeKind.Object + introspectionReporter.breakages[1].fieldName == 'temperament' } def "missing operation"() { - DiffSet diffSet = diffSet("schema_missing_operation.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_missing_operation.graphqls") expect: - reporter.breakageCount == 1 - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.Operation - reporter.breakages[0].typeName == 'Mutation' - + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.Operation + introspectionReporter.breakages[0].typeName == 'Mutation' } def "missing input object fields"() { - DiffSet diffSet = diffSet("schema_missing_input_object_fields.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_missing_input_object_fields.graphqls") expect: - reporter.breakageCount == 1 - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.InputObject - reporter.breakages[0].fieldName == 'queryTarget' + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.InputObject + introspectionReporter.breakages[0].fieldName == 'queryTarget' } - def "changed input object field types"() { - DiffSet diffSet = diffSet("schema_changed_input_object_fields.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + def "changed nested input object field types"() { + compareDiff("schema_changed_nested_input_object_fields.graphqls") expect: - reporter.breakageCount == 2 - reporter.breakages[0].category == DiffCategory.INVALID - reporter.breakages[0].typeName == 'Questor' - reporter.breakages[0].typeKind == TypeKind.InputObject - reporter.breakages[0].fieldName == 'queryTarget' + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages[0].category == DiffCategory.INVALID + introspectionReporter.breakages[0].typeName == 'NestedInput' + introspectionReporter.breakages[0].typeKind == TypeKind.InputObject + introspectionReporter.breakages[0].fieldName == 'nestedInput' + } + + def "changed input object field types"() { + compareDiff("schema_changed_input_object_fields.graphqls") - reporter.breakages[1].category == DiffCategory.STRICTER - reporter.breakages[1].typeName == 'Questor' - reporter.breakages[1].typeKind == TypeKind.InputObject - reporter.breakages[1].fieldName == 'newMandatoryField' + expect: + validateReportersAreEqual() + introspectionReporter.breakageCount == 4 + introspectionReporter.breakages[0].category == DiffCategory.STRICTER + introspectionReporter.breakages[0].typeName == 'Query' + introspectionReporter.breakages[0].typeKind == TypeKind.Object + introspectionReporter.breakages[0].fieldName == 'being' + + introspectionReporter.breakages[1].category == DiffCategory.STRICTER + introspectionReporter.breakages[1].typeName == 'Questor' + introspectionReporter.breakages[1].typeKind == TypeKind.InputObject + introspectionReporter.breakages[1].fieldName == 'nestedInput' + + introspectionReporter.breakages[2].category == DiffCategory.INVALID + introspectionReporter.breakages[2].typeName == 'Questor' + introspectionReporter.breakages[2].typeKind == TypeKind.InputObject + introspectionReporter.breakages[2].fieldName == 'queryTarget' + + introspectionReporter.breakages[3].category == DiffCategory.STRICTER + introspectionReporter.breakages[3].typeName == 'Questor' + introspectionReporter.breakages[3].typeKind == TypeKind.InputObject + introspectionReporter.breakages[3].fieldName == 'newMandatoryField' } def "changed type kind"() { - DiffSet diffSet = diffSet("schema_changed_type_kind.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_changed_type_kind.graphqls") expect: - reporter.breakageCount == 1 - reporter.breakages[0].category == DiffCategory.INVALID - reporter.breakages[0].typeName == 'Character' - reporter.breakages[0].typeKind == TypeKind.Union - + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages[0].category == DiffCategory.INVALID + introspectionReporter.breakages[0].typeName == 'Character' + introspectionReporter.breakages[0].typeKind == TypeKind.Union } def "missing object field args"() { - DiffSet diffSet = diffSet("schema_missing_field_arguments.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_missing_field_arguments.graphqls") expect: - reporter.breakageCount == 2 + validateReportersAreEqual() + introspectionReporter.breakageCount == 2 - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.Object - reporter.breakages[0].typeName == "Mutation" - reporter.breakages[0].fieldName == 'being' - reporter.breakages[0].components.contains("questor") + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.Object + introspectionReporter.breakages[0].typeName == "Mutation" + introspectionReporter.breakages[0].fieldName == 'being' + introspectionReporter.breakages[0].components.contains("questor") - reporter.breakages[1].category == DiffCategory.MISSING - reporter.breakages[1].typeKind == TypeKind.Object - reporter.breakages[0].typeName == "Mutation" - reporter.breakages[1].fieldName == 'sword' + introspectionReporter.breakages[1].category == DiffCategory.MISSING + introspectionReporter.breakages[1].typeKind == TypeKind.Object + introspectionReporter.breakages[0].typeName == "Mutation" + introspectionReporter.breakages[1].fieldName == 'sword' } def "missing enum value"() { - DiffSet diffSet = diffSet("schema_missing_enum_value.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_missing_enum_value.graphqls") expect: - reporter.breakageCount == 1 - reporter.breakages[0].category == DiffCategory.MISSING - reporter.breakages[0].typeKind == TypeKind.Enum - reporter.breakages[0].typeName == 'Temperament' - reporter.breakages[0].components.contains("Duplicitous") + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages[0].category == DiffCategory.MISSING + introspectionReporter.breakages[0].typeKind == TypeKind.Enum + introspectionReporter.breakages[0].typeName == 'Temperament' + introspectionReporter.breakages[0].components.contains("Duplicitous") } def "changed object field args"() { - DiffSet diffSet = diffSet("schema_changed_field_arguments.graphqls") - - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + compareDiff("schema_changed_field_arguments.graphqls") expect: - reporter.breakageCount == 2 - reporter.breakages[0].category == DiffCategory.INVALID - reporter.breakages[0].typeKind == TypeKind.Object - reporter.breakages[0].fieldName == 'sword' + validateReportersAreEqual() + introspectionReporter.breakageCount == 2 + introspectionReporter.breakages[0].category == DiffCategory.INVALID + introspectionReporter.breakages[0].typeKind == TypeKind.Object + introspectionReporter.breakages[0].fieldName == 'sword' - reporter.breakages[1].category == DiffCategory.INVALID - reporter.breakages[1].typeKind == TypeKind.Object - reporter.breakages[1].fieldName == 'sword' + introspectionReporter.breakages[1].category == DiffCategory.INVALID + introspectionReporter.breakages[1].typeKind == TypeKind.Object + introspectionReporter.breakages[1].fieldName == 'sword' } def "changed type on object"() { - DiffSet diffSet = diffSet("schema_changed_object_fields.graphqls") + compareDiff("schema_changed_object_fields.graphqls") - def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + expect: + validateReportersAreEqual() + introspectionReporter.breakageCount == 3 + introspectionReporter.breakages[0].category == DiffCategory.STRICTER + introspectionReporter.breakages[0].typeName == 'Istari' + introspectionReporter.breakages[0].typeKind == TypeKind.Object + introspectionReporter.breakages[0].fieldName == 'temperament' + + introspectionReporter.breakages[1].category == DiffCategory.INVALID + introspectionReporter.breakages[1].typeName == 'Query' + introspectionReporter.breakages[1].typeKind == TypeKind.Object + introspectionReporter.breakages[1].fieldName == 'beings' + + introspectionReporter.breakages[2].category == DiffCategory.INVALID + introspectionReporter.breakages[2].typeName == 'Query' + introspectionReporter.breakages[2].typeKind == TypeKind.Object + introspectionReporter.breakages[2].fieldName == 'customScalar' + } + + def "dangerous changes"() { + compareDiff("schema_dangerous_changes.graphqls") expect: - reporter.breakageCount == 4 - reporter.breakages[0].category == DiffCategory.STRICTER - reporter.breakages[0].typeName == 'Query' - reporter.breakages[0].typeKind == TypeKind.Object - reporter.breakages[0].fieldName == 'being' + validateReportersAreEqual() + introspectionReporter.breakageCount == 0 + introspectionReporter.dangerCount == 3 + + introspectionReporter.dangers[0].category == DiffCategory.ADDITION + introspectionReporter.dangers[0].typeName == "Temperament" + introspectionReporter.dangers[0].typeKind == TypeKind.Enum + introspectionReporter.dangers[0].components.contains("Nonplussed") + + introspectionReporter.dangers[1].category == DiffCategory.ADDITION + introspectionReporter.dangers[1].typeName == "Character" + introspectionReporter.dangers[1].typeKind == TypeKind.Union + introspectionReporter.dangers[1].components.contains("BenignFigure") + + introspectionReporter.dangers[2].category == DiffCategory.DIFFERENT + introspectionReporter.dangers[2].typeName == "Query" + introspectionReporter.dangers[2].typeKind == TypeKind.Object + introspectionReporter.dangers[2].fieldName == "being" + introspectionReporter.dangers[2].components.contains("type") + } - reporter.breakages[1].category == DiffCategory.INVALID - reporter.breakages[1].typeName == 'Query' - reporter.breakages[1].typeKind == TypeKind.Object - reporter.breakages[1].fieldName == 'beings' + def "deprecated fields are unchanged"() { + def schema = TestUtil.schemaFile("diff/" + "schema_deprecated_fields_new.graphqls", wireWithNoFetching()) + SchemaDiffSet introspectionSchemaDiffSet = SchemaDiffSet.diffSetFromIntrospection(schema, schema) + SchemaDiffSet sdlSchemaDiffSet = SchemaDiffSet.diffSetFromSdl(schema, schema) - reporter.breakages[2].category == DiffCategory.STRICTER - reporter.breakages[2].typeName == 'Query' - reporter.breakages[2].typeKind == TypeKind.Object - reporter.breakages[2].fieldName == 'customScalar' + def diff = new SchemaDiff() + diff.diffSchema(introspectionSchemaDiffSet, introspectionChainedReporter) + diff.diffSchema(sdlSchemaDiffSet, sdlChainedReporter) - reporter.breakages[3].category == DiffCategory.STRICTER - reporter.breakages[3].typeName == 'Query' - reporter.breakages[3].typeKind == TypeKind.Object - reporter.breakages[3].fieldName == 'wizards' + expect: + validateReportersAreEqual() + introspectionReporter.dangerCount == 0 + introspectionReporter.breakageCount == 0 + } + def "field was deprecated"() { + compareDiff("schema_deprecated_fields_new.graphqls") + + expect: + validateReportersAreEqual() + introspectionReporter.dangerCount == 14 + introspectionReporter.breakageCount == 0 + introspectionReporter.dangers.every { + it.getCategory() == DiffCategory.DEPRECATION_ADDED + } } - def "dangerous changes "() { - DiffSet diffSet = diffSet("schema_dangerous_changes.graphqls") + def "deprecated field was removed"() { + def schemaOld = TestUtil.schemaFile("diff/" + "schema_deprecated_fields_new.graphqls", wireWithNoFetching()) + def schemaNew = TestUtil.schemaFile("diff/" + "schema_deprecated_fields_removed.graphqls", wireWithNoFetching()) + + SchemaDiffSet introspectionSchemaDiffSet = SchemaDiffSet.diffSetFromIntrospection(schemaOld, schemaNew) + SchemaDiffSet sdlSchemaDiffSet = SchemaDiffSet.diffSetFromSdl(schemaOld, schemaNew) def diff = new SchemaDiff() - diff.diffSchema(diffSet, chainedReporter) + diff.diffSchema(introspectionSchemaDiffSet, introspectionChainedReporter) + diff.diffSchema(sdlSchemaDiffSet, sdlChainedReporter) expect: - reporter.breakageCount == 0 - reporter.dangerCount == 3 + validateReportersAreEqual() + introspectionReporter.dangerCount == 0 + introspectionReporter.breakageCount == 12 + introspectionReporter.breakages.every { + it.getCategory() == DiffCategory.DEPRECATION_REMOVED + } + } + + def "union members are checked"() { + def oldSchema = TestUtil.schema(''' + type Query { + foo: Foo + } + union Foo = A | B + type A { + a: String + toRemove: String + } + type B { + b: String + } + ''') + def newSchema = TestUtil.schema(''' + type Query { + foo: Foo + } + union Foo = A | B + type A { + a: String + } + type B { + b: String + } + ''') + + when: + compareDiff(oldSchema, newSchema) - reporter.dangers[0].category == DiffCategory.ADDITION - reporter.dangers[0].typeName == "Character" - reporter.dangers[0].typeKind == TypeKind.Union - reporter.dangers[0].components.contains("BenignFigure") + then: + validateReportersAreEqual() + introspectionReporter.dangerCount == 0 + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages.every { + it.getCategory() == DiffCategory.MISSING + } + + } + + def "field renamed"() { + def oldSchema = TestUtil.schema(''' + type Query { + hello: String + } + ''') + def newSchema = TestUtil.schema(''' + type Query { + hello2: String + } + ''') + when: + compareDiff(oldSchema, newSchema) + + then: + // the old hello field is missing + validateReportersAreEqual() + introspectionReporter.breakageCount == 1 + introspectionReporter.breakages.every { + it.getCategory() == DiffCategory.MISSING + } + } + def "interface renamed"() { + def oldSchema = TestUtil.schema(''' + type Query implements Hello{ + hello: String + world: World + } + type World implements Hello { + hello: String + } + interface Hello { + hello: String + } + ''') + def newSchema = TestUtil.schema(''' + type Query implements Hello2{ + hello: String + world: World + } + type World implements Hello2 { + hello: String + } + interface Hello2 { + hello: String + } + ''') + when: - reporter.dangers[1].category == DiffCategory.DIFFERENT - reporter.dangers[1].typeName == "Query" - reporter.dangers[1].typeKind == TypeKind.Object - reporter.dangers[1].fieldName == "being" - reporter.dangers[1].components.contains("type") + compareDiff(oldSchema, newSchema) - reporter.dangers[2].category == DiffCategory.ADDITION - reporter.dangers[2].typeName == "Temperament" - reporter.dangers[2].typeKind == TypeKind.Enum - reporter.dangers[2].components.contains("Nonplussed") + then: + // two breakages for World and Query not implementing Hello anymore + validateReportersAreEqual() + introspectionReporter.breakageCount == 2 } + def "SchemaDiff and CapturingReporter have the same diff counts"() { + def schema1 = TestUtil.schema("type Query { f : String }") + def schema2 = TestUtil.schema("type Query { f : Int }") + + when: + def capturingReporter = new CapturingReporter() + def schemaDiff = new SchemaDiff() + def breakingCount = schemaDiff.diffSchema(SchemaDiffSet.diffSetFromIntrospection(schema1, schema1), capturingReporter) + then: + breakingCount == capturingReporter.getBreakageCount() + breakingCount == 0 + + when: + capturingReporter = new CapturingReporter() + schemaDiff = new SchemaDiff() + breakingCount = schemaDiff.diffSchema(SchemaDiffSet.diffSetFromIntrospection(schema1, schema2), capturingReporter) + + then: + breakingCount == capturingReporter.getBreakageCount() + breakingCount == 1 + } + + def "directives are removed should be breaking when enforceDirectives is enabled"() { + def oldSchema = TestUtil.schema(''' + directive @someDirective on FIELD_DEFINITION + + type test { + version: String! @someDirective + } + + type Query { + getTests: [test]! + } + ''') + def newSchema = TestUtil.schema(''' + type test { + version: String! + } + + type Query { + getTests: [test]! + } + ''') + def reporter = new CapturingReporter() + SchemaDiffSet diffSet = SchemaDiffSet.diffSetFromSdl(oldSchema, newSchema) + def diff = new SchemaDiff(SchemaDiff.Options.defaultOptions().enforceDirectives()) + when: + diff.diffSchema(diffSet, reporter) + + then: + reporter.dangerCount == 0 + reporter.breakageCount == 1 + reporter.breakages.every { + it.getCategory() == DiffCategory.MISSING + } + } + + def "When enforceDirectives is enabled, IntrospectionSchemaDiffSet should assert"() { + def oldSchema = TestUtil.schema(''' + directive @someDirective on FIELD_DEFINITION + + type test { + version: String! @someDirective + } + + type Query { + getTests: [test]! + } + ''') + def newSchema = TestUtil.schema(''' + type test { + version: String! + } + + type Query { + getTests: [test]! + } + ''') + def reporter = new CapturingReporter() + SchemaDiffSet diffSet = SchemaDiffSet.diffSetFromIntrospection(oldSchema, newSchema) + def diff = new SchemaDiff(SchemaDiff.Options.defaultOptions().enforceDirectives()) + when: + diff.diffSchema(diffSet, reporter) + + then: + thrown(AssertException) + } + + def "checkImplements emits ADDITION events for new interfaces"() { + def oldSchema = TestUtil.schema(''' + type Query { + foo: Foo + } + type Foo { + a: String + } + interface Bar { + a: String + } + ''') + def newSchema = TestUtil.schema(''' + type Query { + foo: Foo + } + type Foo implements Bar { + a: String + } + interface Bar { + a: String + } + ''') + + when: + compareDiff(oldSchema, newSchema) + + then: + validateReportersAreEqual() + introspectionReporter.breakageCount == 0 + introspectionReporter.infos.any { + it.category == DiffCategory.ADDITION && + it.typeKind == TypeKind.Object && + it.typeName == "Foo" && + it.level == DiffLevel.INFO + } + + } } diff --git a/src/test/groovy/graphql/schema/diffing/SchemaDiffingTest.groovy b/src/test/groovy/graphql/schema/diffing/SchemaDiffingTest.groovy new file mode 100644 index 0000000000..46481fa7a5 --- /dev/null +++ b/src/test/groovy/graphql/schema/diffing/SchemaDiffingTest.groovy @@ -0,0 +1,1596 @@ +package graphql.schema.diffing + +import graphql.TestUtil +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLSchemaElement +import graphql.schema.GraphQLTypeVisitorStub +import graphql.schema.SchemaTransformer +import graphql.util.TraversalControl +import graphql.util.TraverserContext +import spock.lang.Specification + +import static graphql.TestUtil.schema + +class SchemaDiffingTest extends Specification { + + + def "test schema generation"() { + given: + def schema = schema(""" + type Query { + hello: String + } + """) + + when: + def schemaGraph = new SchemaGraphFactory().createGraph(schema) + + then: + schemaGraph.getVerticesByType().keySet().size() == 8 + schemaGraph.getVerticesByType(SchemaGraph.SCHEMA).size() == 1 + schemaGraph.getVerticesByType(SchemaGraph.OBJECT).size() == 7 + schemaGraph.getVerticesByType(SchemaGraph.ENUM).size() == 2 + schemaGraph.getVerticesByType(SchemaGraph.ENUM_VALUE).size() == 27 + schemaGraph.getVerticesByType(SchemaGraph.INTERFACE).size() == 0 + schemaGraph.getVerticesByType(SchemaGraph.UNION).size() == 0 + schemaGraph.getVerticesByType(SchemaGraph.SCALAR).size() == 2 + schemaGraph.getVerticesByType(SchemaGraph.FIELD).size() == 40 + schemaGraph.getVerticesByType(SchemaGraph.ARGUMENT).size() == 11 + schemaGraph.getVerticesByType(SchemaGraph.INPUT_FIELD).size() == 0 + schemaGraph.getVerticesByType(SchemaGraph.INPUT_OBJECT).size() == 0 + schemaGraph.getVerticesByType(SchemaGraph.DIRECTIVE).size() == 7 + schemaGraph.getVerticesByType(SchemaGraph.APPLIED_ARGUMENT).size() == 0 + schemaGraph.getVerticesByType(SchemaGraph.APPLIED_DIRECTIVE).size() == 0 + schemaGraph.size() == 97 + + } + + def "test rename field"() { + given: + def schema1 = schema(""" + type Query { + hello: String + } + """) + def schema2 = schema(""" + type Query { + hello2: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + then: + diff.size() == 1 + + } + + def "test rename field 2"() { + given: + def schema1 = schema(""" + type Query { + fixed: String + hello: String + f3(arg3: String): String + } + type O1 { + f1(arg1: String, x: String): String + } + + """) + def schema2 = schema(""" + type Query { + hello2: String + fixed: String + f3(arg4: String): String + } + type O2 { + f2(arg2: String, y: String): String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + then: + diff.size() == 6 + + } + + def "adding fields and rename and delete"() { + given: + def schema1 = schema(""" + type Query { + hello: String + toDelete:String + newField: String + newField2: String + } + type Mutation { + unchanged: Boolean + unchanged2: Other + } + type Other { + id: ID + } + """) + def schema2 = schema(""" + type Query { + helloRenamed: String + newField: String + newField2: String + } + type Mutation { + unchanged: Boolean + unchanged2: Other + } + type Other { + id: ID + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + then: + diff.size() == 4 + + } + + def "remove field and rename type"() { + given: + def schema1 = schema(""" + type Query { + foo: Foo + } + type Foo { + bar: Bar + toDelete:String + } + type Bar { + id: ID + name: String + } + """) + def schema2 = schema(""" + type Query { + foo: FooRenamed + } + type FooRenamed { + bar: Bar + } + type Bar { + id: ID + name: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + then: + diff.size() == 5 + + } + + def "renamed field and added field and type"() { + given: + def schema1 = schema(""" + type Query { + foo: Foo + } + type Foo { + foo:String + } + """) + def schema2 = schema(""" + type Query { + foo: Foo + } + type Foo { + fooRenamed:String + bar: Bar + } + type Bar { + id: String + name: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + then: + /** + * 1: Changed Field + * 2: New Object + * 3-8: Three new Fields + DummyTypes + * 9-17: Edges from Object to new Fields (3) + Edges from Field to Dummy Type (3) + Edges from DummyType to String + * */ + diff.size() == 11 + + } + + + def "test two field renames one type rename"() { + given: + def schema1 = schema(""" + type Query { + hello: Foo + } + type Foo { + foo: String + } + """) + def schema2 = schema(""" + type Query { + hello2: Foo2 + } + type Foo2 { + foo2: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 4 + + } + + def "test field type change"() { + given: + def schema1 = schema(""" + type Query { + hello: Boolean + } + """) + def schema2 = schema(""" + type Query { + hello: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + /** + * Deleting the edge from __DUMMY_TYPE_VERTICE to Boolean + * Insert the edge from __DUMMY_TYPE_VERTICE to String + */ + diff.size() == 2 + + } + + def "change object type name used once"() { + given: + def schema1 = schema(""" + type Query { + hello: Foo + } + type Foo { + foo: String + } + """) + def schema2 = schema(""" + type Query { + hello: Foo2 + } + type Foo2 { + foo: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 2 + + } + + def "remove Interface from Object"() { + given: + def schema1 = schema(""" + type Query { + hello: Foo + hello2: Foo2 + } + interface Node { + id: ID + } + type Foo implements Node{ + id: ID + } + type Foo2 implements Node{ + id: ID + } + """) + def schema2 = schema(""" + type Query { + hello: Foo + hello2: Foo2 + } + interface Node { + id: ID + } + type Foo implements Node{ + id: ID + } + type Foo2 { + id: ID + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 1 + + } + + def "inserting interface with same name as previous object"() { + given: + def schema1 = schema(""" + type Query { + luna: Pet + } + type Pet { + name: String + } + """) + def schema2 = schema(""" + type Query { + luna: Pet + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + for (EditOperation operation : diff) { + println operation + } + + then: + /** + * If we would allow to map Object to Interface this would have a result of 8 + */ + diff.size() == 8 + + } + + def "remove scalars and add Enums"() { + given: + def schema1 = schema(""" + scalar S1 + scalar S2 + scalar S3 + enum E1{ + E1 + } + type Query { + s1: S1 + s2: S2 + s3: S3 + e1: E1 + } + """) + def schema2 = schema(""" + enum E1{ + E1 + } + enum E2{ + E2 + } + type Query { + e1: E1 + e2: E2 + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + for (EditOperation operation : diff) { + println operation + } + + then: + diff.size() == 15 + + } + + def "change large schema a bit"() { + given: + def largeSchema = TestUtil.schemaFromResource("large-schema-2.graphqls", TestUtil.mockRuntimeWiring) + int counter = 0; + def changedOne = SchemaTransformer.transformSchema(largeSchema, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.getName() == "field50") { + counter++; + return changeNode(context, fieldDefinition.transform({ it.name("field50Changed") })) + } + return TraversalControl.CONTINUE + } + }) + println "changed fields: " + counter + when: + def diff = new SchemaDiffing().diffGraphQLSchema(largeSchema, changedOne) + then: + diff.size() == 171 + } + + def "change large schema a bit 2"() { + given: + def largeSchema = TestUtil.schemaFromResource("large-schema-2.graphqls", TestUtil.mockRuntimeWiring) + int counter = 0; + def changedOne = SchemaTransformer.transformSchema(largeSchema, new GraphQLTypeVisitorStub() { + @Override + TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition fieldDefinition, TraverserContext context) { + if (fieldDefinition.getName() == "field50") { + counter++; + return deleteNode(context); + } + return TraversalControl.CONTINUE + } + }) + println "deleted fields: " + counter + when: + def diff = new SchemaDiffing().diffGraphQLSchema(largeSchema, changedOne) + diff.each { println it } + then: + // deleting 171 fields + dummyTypes + 3 edges for each field,dummyType pair = 5*171 + diff.size() == 3 * 171 + } + + def "change object type name used twice"() { + given: + def schema1 = schema(""" + type Query { + hello: Foo + hello2: Foo + } + type Foo { + foo: String + } + """) + def schema2 = schema(""" + type Query { + hello: Foo2 + hello2: Foo2 + } + type Foo2 { + foo: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 3 + + } + + def "change directive not applied"() { + given: + def schema1 = schema(""" + directive @foo on FIELD_DEFINITION + type Query { + hello: String + } + """) + def schema2 = schema(""" + directive @foo2 on FIELD_DEFINITION + type Query { + hello: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 1 + + } + + def "change directive which is also applied"() { + given: + def schema1 = schema(""" + directive @foo on FIELD_DEFINITION + type Query { + hello: String @foo + } + """) + def schema2 = schema(""" + directive @foo2 on FIELD_DEFINITION + type Query { + hello: String @foo2 + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 2 + + } + + def "delete a field"() { + given: + def schema1 = schema(""" + type Query { + hello: String + toDelete: String + } + """) + def schema2 = schema(""" + type Query { + hello: String + } + """) + + def diffing = new SchemaDiffing() + when: + def diff = diffing.diffGraphQLSchema(schema1, schema2) + for (EditOperation editOperation : diff) { + println editOperation + } + + then: + diff.size() == 3 + } + + + def "added different types and fields"() { + given: + def schema1 = schema(""" + type Query { + pets: [Pet] + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + """) + def schema2 = schema(""" + type Query { + pets: [Animal] @deprecated + animals: [Animal] + } + interface Animal { + name: String + friend: Human + } + type Human { + name: String + } + interface Pet implements Animal { + name: String + friend: Human + } + type Dog implements Pet & Animal { + name: String + friend: Human + } + type Cat implements Pet & Animal { + name: String + friend: Human + } + type Fish implements Pet & Animal { + name: String + friend: Human + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + + then: + diff.size() == 41 + + } + + def "adding a few things "() { + given: + def schema1 = schema(""" + type Query { + pets: [Pet] + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + """) + def schema2 = schema(""" + type Query { + pets: [Pet] + animals: [Animal] + } + interface Animal { + name: String + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + type Fish implements Pet{ + name: String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 12 + } + + def "adding a few things plus introducing new interface"() { + given: + def schema1 = schema(""" + type Query { + pets: [Pet] + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + """) + def schema2 = schema(""" + type Query { + pets: [Pet] + animals: [Animal] + } + interface Animal { + name: String + } + interface Pet implements Animal { + name: String + } + type Dog implements Pet & Animal { + name: String + } + type Cat implements Pet & Animal { + name: String + } + type Fish implements Pet & Animal { + name: String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 16 + } + + def "adding a few things plus introducing new interface plus changing return type"() { + given: + def schema1 = schema(""" + type Query { + pets: [Pet] + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + """) + def schema2 = schema(""" + type Query { + pets: [Animal] + animals: [Animal] + } + interface Animal { + name: String + } + interface Pet implements Animal { + name: String + } + type Dog implements Pet & Animal { + name: String + } + type Cat implements Pet & Animal { + name: String + } + type Fish implements Pet & Animal { + name: String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 18 + } + + def "adding a few things plus introducing new interface plus changing return type plus adding field in Interface"() { + given: + def schema1 = schema(""" + type Query { + pets: [Pet] + } + interface Pet { + name: String + } + type Dog implements Pet { + name: String + } + type Cat implements Pet { + name: String + } + """) + def schema2 = schema(""" + type Query { + pets: [Pet] + } + interface Animal { + name: String + friend: String + } + interface Pet implements Animal { + name: String + friend: String + } + type Dog implements Pet & Animal { + name: String + friend: String + } + type Cat implements Pet & Animal { + name: String + friend: String + } + type Fish implements Pet & Animal { + name: String + friend: String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 28 + } + + def "add a field"() { + given: + def schema1 = schema(""" + type Query { + hello: String + } + """) + def schema2 = schema(""" + type Query { + hello: String + newField: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 3 + + } + + def "add a field and Type"() { + given: + def schema1 = schema(""" + type Query { + hello: String + } + """) + def schema2 = schema(""" + type Query { + hello: String + newField: Foo + } + type Foo { + foo: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + diff.each { println it } + + then: + diff.size() == 7 + + } + + def "add a field and Type and remove a field"() { + given: + def schema1 = schema(""" + type Query { + hello: String + } + """) + def schema2 = schema(""" + type Query { + newField: Foo + } + type Foo { + foo: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + diff.size() == 7 + + } + + + def "change a Union "() { + given: + def schema1 = schema(""" + type Query { + pet: Pet + } + union Pet = Dog | Cat + type Dog { + name: String + } + type Cat { + name: String + } + """) + def schema2 = schema(""" + type Query { + pet: Pet + } + union Pet = Dog | Bird | Fish + type Dog { + name: String + } + type Bird { + name: String + } + type Fish { + name: String + } + """) + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + /** + * 1. Change Cat to Bird + * 2,3: Insert Fish, Insert Fish.name + * 4. Insert Edge from Fish to Fish.name + * 5 Insert Edge from Fish.name -> String + * 6. Insert edge from Pet -> Fish + */ + diff.size() == 6 + + } + + def "adding an argument "() { + given: + def schema1 = schema(""" + type Query { + foo: String + } + """) + def schema2 = schema(""" + type Query { + foo(arg: Int): String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 4 + } + + def "changing an argument "() { + given: + def schema1 = schema(""" + type Query { + foo(arg: Int): String + } + """) + def schema2 = schema(""" + type Query { + foo(arg2: Boolean): String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 4 + } + + def "input fields"() { + given: + def schema1 = schema(""" + type Query { + foo(arg: I1, arg2: I2): String + } + input I1 { + f1: String + f2: String + } + input I2 { + g1: String + g2: String + } + """) + def schema2 = schema(""" + type Query { + foo(arg: I1,arg2: I2 ): String + } + input I1 { + f1: String + } + input I2 { + g2: String + g3: String + g4: String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + /** + * The test here is that f2 is deleted and one g is renamed and g3 is inserted. + * It would be less operations with f2 renamed to g3, but this would defy expectations. + * + */ + operations.size() == 7 + } + + def "arguments in fields"() { + given: + def schema1 = schema(""" + type Query { + a(f1: String, f2:String): String + b(g1: String, g2:String): O1 + } + type O1 { + c(h1: String, h2:String): String + d(i1: String, i2:String): O1 + } + """) + def schema2 = schema(""" + type Query { + a(f1: String): String + b(g2: String, g3:String, g4: String): String + } + type O1 { + c(h1: String, h2:String): String + renamed(i2: String, i3:String): O1 + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + /** + * Query.f2 deleted + * O1.b.g1 => O1.b.g4 + * O1.d.i1 -> O.renamed.i3 + * O1.d => O1.renamed + * Inserted O1.b.g3 + */ + operations.size() == 11 + } + + def "same arguments in different contexts"() { + given: + def schema1 = schema(""" + type Query { + foo(someArg:String): String + } + """) + def schema2 = schema(""" + type Query { + field1(arg1: String): String + field2(arg1: String): String + field3(arg1: String): String + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 14 + } + + def "adding enum value"() { + given: + def schema1 = schema(""" + type Query { + foo: Foo + } + enum Foo { + V1 + V2 + } + """) + def schema2 = schema(""" + type Query { + foo: Foo + } + enum Foo { + V1 + V2 + V3 + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 2 + } + + def "rename enum value"() { + given: + def schema1 = schema(""" + type Query { + foo: Foo + } + enum Foo { + V1 + V2 + } + """) + def schema2 = schema(""" + type Query { + foo: Foo + } + enum Foo { + V1 + V3 + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 1 + } + + def "arguments in directives changed"() { + given: + def schema1 = schema(''' + directive @d(a1: String, a2: String) on FIELD_DEFINITION + type Query { + foo: String @d + } + ''') + def schema2 = schema(""" + directive @d(a1: String, a3: String, a4: String) on FIELD_DEFINITION + type Query { + foo: String @d + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + /** + * change: a2 => a3 + * insert: a4 + * new edge from directive to a4 + * new edge from a4 to String + */ + operations.size() == 4 + } + + def "change applied argument"() { + given: + def schema1 = schema(''' + directive @d(a1: String, a2: String) on FIELD_DEFINITION + type Query { + foo: String @d(a1: "S1", a2: "S2") + } + ''') + def schema2 = schema(""" + directive @d(a1: String, a2: String) on FIELD_DEFINITION + type Query { + foo: String @d(a2: "S2Changed", a1: "S1Changed") + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 2 + } + + def "applied arguments in different contexts"() { + given: + def schema1 = schema(''' + directive @d(a1: String, a2: String, b1: String, b2: String, b3: String, b4: String) on FIELD_DEFINITION + type Query { + foo: String @d(a1: "a1", a2: "a2") + foo2: String @d(b1: "b1", b2: "b2") + } + ''') + def schema2 = schema(""" + directive @d(a1: String, a2: String, b1: String, b2: String, b3: String, b4: String) on FIELD_DEFINITION + type Query { + foo: String @d(a1: "a1") + foo2: String @d(b2: "b2", b3: "b3", b4: "b4") + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + /** + * The test here is that the context of the applied argument is considered and that a2 is deleted and one b is inserted and another one changed. + * Note: this is not longer true + */ + operations.size() == 8 + } + + def "with directives"() { + given: + def schema1 = schema(''' + directive @TopLevelType on OBJECT + directive @specialId(type: String) on ARGUMENT_DEFINITION + type Query { + foo: Foo + } + type Foo @TopLevelType { + user(location: ID! @specialId(type : "someId"), limit: Int = 25, start: Int, title: String): PaginatedList + } + type PaginatedList { + count: Int + } + ''') + def schema2 = schema(""" + directive @TopLevelType on OBJECT + directive @specialId(type: String) on ARGUMENT_DEFINITION + type Query { + foo: Foo + } + type Foo @TopLevelType { + user(location: ID! @specialId(type : "someId"), limit: Int = 25, start: Int, title: String): PaginatedList + other(after: String, favourite: Boolean, first: Int = 25, location: ID! @specialId(type : "someId"), label: [String], offset: Int, status: String, type: String): PaginatedList + } + type PaginatedList { + count: Int + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + + then: + operations.size() == 31 + } + + def "built in directives"() { + given: + def schema1 = schema(''' + directive @specialId(type: String) on FIELD_DEFINITION + + + type Query { + hello: String @specialId(type: "someId") + } + ''') + def schema2 = schema(""" + directive @specialId(type: String) on FIELD_DEFINITION + + type Query { + renamedHello: String @specialId(type: "otherId") + } + """) + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 2 + } + + def "unchanged scheme"() { + given: + def schema1 = schema(''' + directive @specialId(type: String) on FIELD_DEFINITION + directive @Magic(owner: String!, type: String!) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION + + + type Query { + hello: String @specialId(type: "someId") + foo(arg: Int, arg2: String = "hello"): [Foo]! + old: Boolean @deprecated + someOther(input1: MyInput, input2: OtherInput): E + } + type Foo { + id: ID + e1: E + union: MyUnion + } + union MyUnion = Foo | Bar + type Bar { + id: ID + } + enum E { + E1, E2, E3 + } + input MyInput { + id: ID + other: String! @Magic(owner: "Me", type: "SomeType") + } + input OtherInput { + inputField1: ID! @Magic(owner: "O1", type: "T1") + inputField2: ID! @Magic(owner: "O2", type: "T2") + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema1) + operations.each { println it } + + then: + operations.size() == 0 + } + + def "changed query operation type "() { + given: + def schema1 = schema(''' + type Query { + foo: String + } + type MyQuery { + foo: String + } + ''') + def schema2 = schema(''' + schema { + query: MyQuery + } + type Query { + foo: String + } + type MyQuery { + foo: String + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + // delete edge and insert new one + operations.size() == 2 + } + + def "applied schema directives"() { + given: + def schema1 = schema(''' + directive @foo(arg: String) on SCHEMA + + schema @foo(arg: "bar") { + query: MyQuery + } + type MyQuery { + foo: String + } + ''') + def schema2 = schema(''' + directive @foo(arg: String) on SCHEMA + + schema @foo(arg: "barChanged") { + query: MyQuery + } + type MyQuery { + foo: String + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + // applied argument changed + operations.size() == 1 + + } + + def "change description"() { + given: + def schema1 = schema(''' + "Hello World" + type Query { + "helloDesc" + hello: String + } + ''') + def schema2 = schema(''' + "Hello World now" + type Query { + "helloDescChanged" + hello: String + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 2 + + } + + def "change default value"() { + given: + def schema1 = schema(''' + input I { + someNumber: Int = 100 + } + type Query { + hello(arg: String = "defaultValue", i: I): String + } + ''') + def schema2 = schema(''' + input I { + someNumber: Int = 200 + } + type Query { + hello(arg: String = "defaultValueChanged",i: I): String + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 2 + + } + + def "change field type, but not the wrapped type "() { + given: + def schema1 = schema(''' + type Query { + hello: String + hello2: String + } + ''') + def schema2 = schema(''' + type Query { + hello: String! + hello2: [[String!]] + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 2 + operations.findAll({ it.operation == EditOperation.Operation.CHANGE_EDGE }).size() == 2 + + } + + def "Recursive input field with default "() { + given: + def schema1 = schema(''' + input I { + name: String + field: I = {name: "default name"} + } + type Query { + foo(arg: I): String + } + ''') + def schema2 = schema(''' + input I { + name: String + field: [I] = [{name: "default name"}] + } + type Query { + foo(arg: I): String + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + // changing the label of the edge to the type + operations.size() == 1 + operations.findAll({ it.operation == EditOperation.Operation.CHANGE_EDGE }).size() == 1 + + } + + def "directive argument default value changed"() { + given: + def schema1 = schema(''' + type Query { + foo: String + } + directive @d(foo:String = "A") on FIELD + ''') + def schema2 = schema(''' + type Query { + foo: String + } + directive @d(foo: String = "B") on FIELD + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + // changing the label of the edge to the type + operations.size() == 1 + operations.findAll({ it.operation == EditOperation.Operation.CHANGE_EDGE }).size() == 1 + + + } + + def "object applied directive argument change"() { + given: + def schema1 = schema(''' + directive @d(arg:String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "foo") + } + + ''') + def schema2 = schema(''' + directive @d(arg: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "bar") + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 1 + } + + def "object applied directive rename"() { + given: + def schema1 = schema(''' + directive @d1(arg:String) on FIELD_DEFINITION + directive @d2(arg:String) on FIELD_DEFINITION + + type Query { + foo: String @d1(arg: "foo") + } + + ''') + def schema2 = schema(''' + directive @d1(arg:String) on FIELD_DEFINITION + directive @d2(arg:String) on FIELD_DEFINITION + + type Query { + foo: String @d2(arg: "foo") + } + ''') + + when: + def operations = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + operations.each { println it } + + then: + operations.size() == 1 + } + + + /* + * The schema can't be mapped at the moment because + * the arguments mapping doesn't work. + * The PossibleMappingCalculator finds two context: "Object.Query" (with one argument vertex) which is deleted + * and "Object.Foo" (with two argument vertices) which is added. Therefore one isolated vertex is added in the source + * to align both context. + * + * But the parent restrictions dictate that the target parent of i1 must be Query.foo, because Query.echo is fixed mapped + * to Query.foo. But that would mean i1 is deleted, but there is no isolated argument vertex for the target because of + * the contexts. So there is no possible mapping and the exception is thrown. + */ + + def "bug produced well known exception"() { + given: + def schema1 = schema(''' + type Query { + echo(i1: String): String + } + ''') + def schema2 = schema(''' + type Query { + foo: Foo + } + type Foo { + a(i2: String): String + b(i3: String): String + } +''') + + when: + def diff = new SchemaDiffing().diffGraphQLSchema(schema1, schema2) + then: + def e = thrown(RuntimeException) + e.message.contains("bug: ") + } + +} + + diff --git a/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy new file mode 100644 index 0000000000..2fc9336bcc --- /dev/null +++ b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy @@ -0,0 +1,1947 @@ +package graphql.schema.diffing.ana + +import graphql.TestUtil +import graphql.schema.diffing.SchemaDiffing +import spock.lang.Specification + +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveAddition +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentAddition +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentDeletion +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentRename +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveArgumentValueModification +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDeletion +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDirectiveArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveEnumLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveEnumValueLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInputObjectFieldLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInputObjectLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceFieldArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceFieldLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveScalarLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveUnionLocation +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveModification +import static graphql.schema.diffing.ana.SchemaDifference.EnumModification +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectModification +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceModification +import static graphql.schema.diffing.ana.SchemaDifference.ObjectModification +import static graphql.schema.diffing.ana.SchemaDifference.ScalarModification +import static graphql.schema.diffing.ana.SchemaDifference.UnionModification + +class EditOperationAnalyzerAppliedDirectivesTest extends Specification { + + def "applied directive argument added interface field"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query implements I{ + foo: String + } + interface I { + foo: String @d + } + ''' + def newSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query implements I{ + foo: String + } + interface I { + foo: String @d(arg1: "foo") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def argumentAddition = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentAddition) + def location = argumentAddition[0].locationDetail as AppliedDirectiveInterfaceFieldLocation + location.interfaceName == "I" + location.fieldName == "foo" + argumentAddition[0].argumentName == "arg1" + } + + def "applied directive argument value changed object"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on OBJECT + + type Query @d(arg1:"foo") { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1: String) on OBJECT + + type Query @d(arg1: "bar") { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def detail = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveObjectLocation + location.name == "Query" + location.directiveName == "d" + detail[0].argumentName == "arg1" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed object field"() { + given: + def oldSdl = ''' + directive @d(arg:String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "foo") + } + ''' + def newSdl = ''' + directive @d(arg: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "bar") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def detail = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveObjectFieldLocation + location.objectName == "Query" + location.fieldName == "foo" + location.directiveName == "d" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed object field argument"() { + given: + def oldSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d(directiveArg: "foo")) : String + } + ''' + def newSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d(directiveArg: "bar")) : String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def detail = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentValueModification) + def locationDetail = detail[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation + locationDetail.objectName == "Query" + locationDetail.fieldName == "foo" + locationDetail.argumentName == "arg" + locationDetail.directiveName == "d" + detail[0].argumentName == "directiveArg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + + def "applied directive argument value changed interface"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I @d(arg1: "foo") { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I @d(arg1: "bar") { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def detail = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveInterfaceLocation + location.name == "I" + location.directiveName == "d" + detail[0].argumentName == "arg1" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + + def "applied directive argument value changed interface field"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query implements I{ + foo: String + } + interface I { + foo: String @d(arg1: "foo") + } + ''' + def newSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query implements I{ + foo: String + } + interface I { + foo: String @d(arg1: "bar") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def detail = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveInterfaceFieldLocation + location.interfaceName == "I" + location.fieldName == "foo" + location.directiveName == "d" + detail[0].argumentName == "arg1" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed interface field argument"() { + given: + def oldSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d(directiveArg: "foo") ): String + } + ''' + def newSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d(directiveArg: "bar") ): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def detail = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation + location.interfaceName == "I" + location.fieldName == "foo" + location.argumentName == "arg" + location.directiveName == "d" + detail[0].argumentName == "directiveArg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed input object"() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d(arg: "foo"){ + a: String + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d(arg: "bar") { + a: String + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def detail = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveInputObjectLocation + location.name == "I" + location.directiveName == "d" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + + } + + + def "applied directive argument value changed input object field "() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d(arg: "foo") + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d(arg: "bar") + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def detail = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveInputObjectFieldLocation + location.inputObjectName == "I" + location.fieldName == "a" + location.directiveName == "d" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed enum"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM + enum E @d(arg:"foo") { A, B } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM + enum E @d(arg: "bar") { A, B } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def detail = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveEnumLocation + location.name == "E" + location.directiveName == "d" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed enum value"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d(arg: "foo") } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d(arg: "bar") } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def detail = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveEnumValueLocation + location.enumName == "E" + location.valueName == "B" + location.directiveName == "d" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed union"() { + given: + def oldSdl = ''' + directive @d(arg: String) on UNION + type Query { + foo: U + } + union U @d(arg: "foo") = A | B + type A { a: String } + type B { b: String } + ''' + def newSdl = ''' + directive @d(arg: String) on UNION + type Query { + foo: U + } + union U @d(arg: "bar") = A | B + type A { a: String } + type B { b: String } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionModification + def detail = (changes.unionDifferences["U"] as UnionModification).getDetails(AppliedDirectiveArgumentValueModification) + (detail[0].locationDetail as AppliedDirectiveUnionLocation).name == "U" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed scalar"() { + given: + def oldSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d(arg: "foo") + type Query { + foo: DateTime + } + ''' + def newSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d(arg: "bar") + type Query { + foo: DateTime + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["DateTime"] instanceof ScalarModification + def detail = (changes.scalarDifferences["DateTime"] as ScalarModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveScalarLocation + location.name == "DateTime" + location.directiveName == "d" + detail[0].argumentName == "arg" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + def "applied directive argument value changed directive argument"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on ARGUMENT_DEFINITION + directive @d2(arg:String @d(arg1:"foo")) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1:String) on ARGUMENT_DEFINITION + directive @d2(arg:String @d(arg1:"bar")) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d2"] instanceof DirectiveModification + (changes.directiveDifferences["d2"] as DirectiveModification).details.size() == 1 + def detail = (changes.directiveDifferences["d2"] as DirectiveModification).getDetails(AppliedDirectiveArgumentValueModification) + def location = detail[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveDefinitionName == "d2" + location.directiveName == "d" + location.argumentName == "arg" + detail[0].argumentName == "arg1" + detail[0].oldValue == '"foo"' + detail[0].newValue == '"bar"' + } + + + def "applied directive argument added interface"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I @d { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I @d(arg1: "foo") { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def argumentAddition = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentAddition) + def location = argumentAddition[0].locationDetail as AppliedDirectiveInterfaceLocation + location.name == "I" + argumentAddition[0].argumentName == "arg1" + } + + def "applied directive argument deleted interface field "() { + given: + def oldSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query implements I{ + foo: String + } + interface I { + foo: String @d(arg1: "foo") + } + ''' + def newSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query implements I{ + foo: String + } + interface I { + foo: String @d + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def argumentDeletions = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = argumentDeletions[0].locationDetail as AppliedDirectiveInterfaceFieldLocation + location.interfaceName == "I" + location.fieldName == "foo" + argumentDeletions[0].argumentName == "arg1" + } + + def "applied directive argument deleted interface"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I @d(arg1: "foo") { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1:String) on INTERFACE + + type Query implements I { + foo: String + } + interface I @d{ + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def argumentDeletions = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = argumentDeletions[0].locationDetail as AppliedDirectiveInterfaceLocation + location.name == "I" + argumentDeletions[0].argumentName == "arg1" + } + + + def "applied directive added input object field "() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d(arg: "foo") + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def appliedDirective = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveInputObjectFieldLocation).inputObjectName == "I" + (appliedDirective[0].locationDetail as AppliedDirectiveInputObjectFieldLocation).fieldName == "a" + appliedDirective[0].name == "d" + } + + def "applied directive added object field"() { + given: + def oldSdl = ''' + directive @d(arg:String) on FIELD_DEFINITION + + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "foo") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirective = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldLocation).objectName == "Query" + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldLocation).fieldName == "foo" + appliedDirective[0].name == "d" + } + + def "applied directive argument value changed object field "() { + given: + def oldSdl = ''' + directive @d(arg:String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "foo1") + } + ''' + def newSdl = ''' + directive @d(arg: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "foo2") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def argumentValueModifications = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentValueModification) + (argumentValueModifications[0].locationDetail as AppliedDirectiveObjectFieldLocation).objectName == "Query" + (argumentValueModifications[0].locationDetail as AppliedDirectiveObjectFieldLocation).fieldName == "foo" + argumentValueModifications[0].argumentName == "arg" + argumentValueModifications[0].oldValue == '"foo1"' + argumentValueModifications[0].newValue == '"foo2"' + } + + def "applied directive argument name changed object field"() { + given: + def oldSdl = ''' + directive @d(arg1:String, arg2: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg1: "foo") + } + ''' + def newSdl = ''' + directive @d(arg1: String, arg2: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg2: "foo") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def argumentRenames = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentRename) + def location = argumentRenames[0].locationDetail as AppliedDirectiveObjectFieldLocation + location.objectName == "Query" + location.fieldName == "foo" + argumentRenames[0].oldName == "arg1" + argumentRenames[0].newName == "arg2" + } + + def "applied directive argument added object"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on OBJECT + + type Query @d { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1: String) on OBJECT + + type Query @d(arg1: "foo") { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def argumentAddition = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentAddition) + def location = argumentAddition[0].locationDetail as AppliedDirectiveObjectLocation + location.name == "Query" + argumentAddition[0].argumentName == "arg1" + } + + def "applied directive argument added object field"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query { + foo: String @d + } + ''' + def newSdl = ''' + directive @d(arg1: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg1: "foo") + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def argumentAddition = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentAddition) + def location = argumentAddition[0].locationDetail as AppliedDirectiveObjectFieldLocation + location.objectName == "Query" + location.fieldName == "foo" + argumentAddition[0].argumentName == "arg1" + } + + def "applied directive argument deleted object field"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg1: "foo") + } + ''' + def newSdl = ''' + directive @d(arg1: String) on FIELD_DEFINITION + + type Query { + foo: String @d + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def argumentDeletions = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = argumentDeletions[0].locationDetail as AppliedDirectiveObjectFieldLocation + location.objectName == "Query" + location.fieldName == "foo" + argumentDeletions[0].argumentName == "arg1" + } + + def "applied directive argument deleted object"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on OBJECT + + type Query @d(arg1: "foo"){ + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1: String) on OBJECT + + type Query @d { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def argumentDeletions = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = argumentDeletions[0].locationDetail as AppliedDirectiveObjectLocation + location.name == "Query" + argumentDeletions[0].argumentName == "arg1" + } + + def "applied directive added input object"() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I { + a: String + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d(arg: "foo") { + a: String + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def appliedDirective = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveInputObjectLocation).name == "I" + appliedDirective[0].name == "d" + } + + def "applied directive added object"() { + given: + def oldSdl = ''' + directive @d(arg:String) on OBJECT + + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg: String) on OBJECT + + type Query @d(arg: "foo") { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + (changes.objectDifferences["Query"] as ObjectModification).details.size() == 1 + def appliedDirective = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveObjectLocation).name == "Query" + appliedDirective[0].name == "d" + } + + def "applied directive added interface"() { + given: + def oldSdl = ''' + directive @d(arg:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg: String) on INTERFACE + + type Query implements I { + foo: String + } + interface I @d(arg: "foo") { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def appliedDirective = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceLocation).name == "I" + appliedDirective[0].name == "d" + } + + def "applied directive added union"() { + given: + def oldSdl = ''' + directive @d(arg: String) on UNION + type Query { + foo: U + } + union U = A | B + type A { a: String } + type B { b: String } + ''' + def newSdl = ''' + directive @d(arg: String) on UNION + type Query { + foo: U + } + union U @d(arg: "foo") = A | B + type A { a: String } + type B { b: String } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionModification + def appliedDirective = (changes.unionDifferences["U"] as UnionModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveUnionLocation).name == "U" + appliedDirective[0].name == "d" + } + + def "applied directive added scalar"() { + given: + def oldSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime + type Query { + foo: DateTime + } + ''' + def newSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d(arg: "foo") + type Query { + foo: DateTime + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["DateTime"] instanceof ScalarModification + def appliedDirective = (changes.scalarDifferences["DateTime"] as ScalarModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveScalarLocation).name == "DateTime" + appliedDirective[0].name == "d" + } + + def "applied directive added enum"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM + enum E { A, B } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM + enum E @d(arg: "foo") { A, B } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def appliedDirective = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveEnumLocation).name == "E" + appliedDirective[0].name == "d" + } + + def "applied directive added enum value"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d(arg: "foo") } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def appliedDirective = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveEnumValueLocation).enumName == "E" + (appliedDirective[0].locationDetail as AppliedDirectiveEnumValueLocation).valueName == "B" + appliedDirective[0].name == "d" + } + + def "applied directive argument added enum value"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d(arg: "foo") } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def argumentAdded = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveArgumentAddition) + def location = argumentAdded[0].locationDetail as AppliedDirectiveEnumValueLocation + location.enumName == "E" + location.valueName == "B" + location.directiveName == "d" + argumentAdded[0].argumentName == "arg" + } + + def "applied directive argument deleted enum value"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d(arg: "foo") } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def argumentDeletion = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = argumentDeletion[0].locationDetail as AppliedDirectiveEnumValueLocation + location.enumName == "E" + location.valueName == "B" + location.directiveName == "d" + argumentDeletion[0].argumentName == "arg" + } + + + def "applied directive added object field argument"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String) : String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d(arg: "foo")) : String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirective = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation).objectName == "Query" + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation).fieldName == "foo" + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation).argumentName == "arg" + appliedDirective[0].name == "d" + } + + def "applied directive argument added object field argument"() { + given: + def oldSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d) : String + } + ''' + def newSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d(directiveArg: "foo")) : String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirectiveArgumentAddition = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentAddition) + def locationDetail = appliedDirectiveArgumentAddition[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation + locationDetail.objectName == "Query" + locationDetail.fieldName == "foo" + locationDetail.argumentName == "arg" + appliedDirectiveArgumentAddition[0].argumentName == "directiveArg" + } + + def "applied directive argument deleted object field argument"() { + given: + def oldSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d(directiveArg: "foo")) : String + } + ''' + def newSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d) : String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirectiveArgumentDeletion = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveArgumentDeletion) + def locationDetail = appliedDirectiveArgumentDeletion[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation + locationDetail.objectName == "Query" + locationDetail.fieldName == "foo" + locationDetail.argumentName == "arg" + appliedDirectiveArgumentDeletion[0].argumentName == "directiveArg" + } + + def "applied directive added interface field argument"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def appliedDirective = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveAddition) + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation).interfaceName == "I" + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation).fieldName == "foo" + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation).argumentName == "arg" + appliedDirective[0].name == "d" + } + + def "applied directive argument added interface field argument"() { + given: + def oldSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d): String + } + ''' + def newSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d(directiveArg: "foo") ): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def appliedDirective = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentAddition) + def location = appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation + location.interfaceName == "I" + location.fieldName == "foo" + location.argumentName == "arg" + appliedDirective[0].argumentName == "directiveArg" + } + + def "applied directive argument deleted interface field argument"() { + given: + def oldSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d(directiveArg: "foo")): String + } + ''' + def newSdl = ''' + directive @d(directiveArg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def appliedDirective = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation + location.interfaceName == "I" + location.fieldName == "foo" + location.argumentName == "arg" + appliedDirective[0].argumentName == "directiveArg" + } + + def "applied directive added directive argument "() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + directive @d2(arg:String) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + directive @d2(arg:String @d) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d2"] instanceof DirectiveModification + def appliedDirective = (changes.directiveDifferences["d2"] as DirectiveModification).getDetails(AppliedDirectiveAddition) + def location = appliedDirective[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveDefinitionName == "d2" + location.argumentName == "arg" + location.directiveName == "d" + appliedDirective[0].name == "d" + } + + def "applied directive argument added directive argument "() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + directive @d2(arg2:String @d) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + directive @d2(arg2:String @d(arg:"foo") ) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d2"] instanceof DirectiveModification + (changes.directiveDifferences["d2"] as DirectiveModification).details.size() == 1 + def appliedDirectiveArgumentAddition = (changes.directiveDifferences["d2"] as DirectiveModification).getDetails(AppliedDirectiveArgumentAddition) + def location = appliedDirectiveArgumentAddition[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveName == "d" + location.argumentName == "arg2" + appliedDirectiveArgumentAddition[0].argumentName == "arg" + } + + def "applied directive argument deleted directive argument "() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + directive @d2(arg2:String @d(arg:"foo")) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + directive @d2(arg2:String @d ) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d2"] instanceof DirectiveModification + (changes.directiveDifferences["d2"] as DirectiveModification).details.size() == 1 + def appliedDirectiveArgumentDeletion = (changes.directiveDifferences["d2"] as DirectiveModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = appliedDirectiveArgumentDeletion[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveName == "d" + location.argumentName == "arg2" + appliedDirectiveArgumentDeletion[0].argumentName == "arg" + } + + + def "applied directive deleted object"() { + given: + def oldSdl = ''' + directive @d(arg: String) on OBJECT + + type Query @d(arg: "foo") { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg:String) on OBJECT + + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirective = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveObjectLocation).name == "Query" + appliedDirective[0].name == "d" + } + + def "applied directive deleted argument directive argument"() { + given: + def oldSdl = ''' + directive @d(arg1:String) on ARGUMENT_DEFINITION + directive @d2(arg:String @d(arg1:"foo")) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg1:String) on ARGUMENT_DEFINITION + directive @d2(arg:String) on ARGUMENT_DEFINITION + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d2"] instanceof DirectiveModification + // whole applied directive is deleted, so we don't count the applied argument deletion + (changes.directiveDifferences["d2"] as DirectiveModification).details.size() == 1 + def appliedDirective = (changes.directiveDifferences["d2"] as DirectiveModification).getDetails(AppliedDirectiveDeletion) + def location = appliedDirective[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveDefinitionName == "d2" + location.argumentName == "arg" + location.directiveName == "d" + appliedDirective[0].name == "d" + } + + def "applied directive deleted enum"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM + enum E @d(arg: "foo") { A, B } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM + enum E { A, B } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def diff = changes.enumDifferences["E"] as EnumModification + + diff.getDetails().size() == 1 + + def appliedDirective = diff.getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveEnumLocation).name == "E" + appliedDirective[0].name == "d" + } + + def "applied directive deleted argument enum"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM + enum E @d(arg: "foo") { A, B } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM + enum E @d { A, B } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def argumentDeleted = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveArgumentDeletion) + (argumentDeleted[0].locationDetail as AppliedDirectiveEnumLocation).name == "E" + argumentDeleted[0].argumentName == "arg" + } + + def "applied directive added argument enum"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM + enum E @d { A, B } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM + enum E @d(arg: "foo"){ A, B } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def argumentAdded = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveArgumentAddition) + (argumentAdded[0].locationDetail as AppliedDirectiveEnumLocation).name == "E" + argumentAdded[0].argumentName == "arg" + + } + + + def "applied directive deleted enum value"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B @d(arg: "foo") } + type Query { + foo: E + } + ''' + def newSdl = ''' + directive @d(arg:String) on ENUM_VALUE + enum E { A, B } + type Query { + foo: E + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def appliedDirective = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveEnumValueLocation).enumName == "E" + (appliedDirective[0].locationDetail as AppliedDirectiveEnumValueLocation).valueName == "B" + appliedDirective[0].name == "d" + } + + + def "applied directive deleted input object"() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d(arg: "foo") { + a: String + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I { + a: String + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def appliedDirective = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveInputObjectLocation).name == "I" + appliedDirective[0].name == "d" + } + + def "applied directive deleted input object field "() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d(arg: "foo") + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def appliedDirective = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveInputObjectFieldLocation).inputObjectName == "I" + (appliedDirective[0].locationDetail as AppliedDirectiveInputObjectFieldLocation).fieldName == "a" + appliedDirective[0].name == "d" + } + + + def "applied directive argument added input object field "() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d(arg: "foo") + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def argumentAdded = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveArgumentAddition) + def location = argumentAdded[0].locationDetail as AppliedDirectiveInputObjectFieldLocation + location.inputObjectName == "I" + location.fieldName == "a" + location.directiveName == "d" + argumentAdded[0].argumentName == "arg" + } + + def "applied directive argument deleted input object field "() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d(arg: "foo") + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_FIELD_DEFINITION + input I { + a: String @d + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def argumentDeletion = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveArgumentDeletion) + def location = argumentDeletion[0].locationDetail as AppliedDirectiveInputObjectFieldLocation + location.inputObjectName == "I" + location.fieldName == "a" + location.directiveName == "d" + argumentDeletion[0].argumentName == "arg" + } + + + def "applied directive deleted interface"() { + given: + def oldSdl = ''' + directive @d(arg: String) on INTERFACE + + type Query implements I { + foo: String + } + interface I @d(arg: "foo") { + foo: String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INTERFACE + + type Query implements I{ + foo: String + } + interface I { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def appliedDirective = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceLocation).name == "I" + appliedDirective[0].name == "d" + } + + + def "applied directive deleted interface field argument"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String @d): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query implements I { + foo(arg: String) : String + } + interface I { + foo(arg: String): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def appliedDirective = (changes.interfaceDifferences["I"] as InterfaceModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation).interfaceName == "I" + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation).fieldName == "foo" + (appliedDirective[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation).argumentName == "arg" + appliedDirective[0].name == "d" + } + + def "applied directive deleted object field"() { + given: + def oldSdl = ''' + directive @d(arg: String) on FIELD_DEFINITION + + type Query { + foo: String @d(arg: "foo") + } + ''' + def newSdl = ''' + directive @d(arg:String) on FIELD_DEFINITION + + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirective = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldLocation).objectName == "Query" + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldLocation).fieldName == "foo" + appliedDirective[0].name == "d" + } + + def "applied directive deleted object field argument"() { + given: + def oldSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String @d(arg: "foo")) : String + } + ''' + def newSdl = ''' + directive @d(arg:String) on ARGUMENT_DEFINITION + type Query { + foo(arg: String) : String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def appliedDirective = (changes.objectDifferences["Query"] as ObjectModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation).objectName == "Query" + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation).fieldName == "foo" + (appliedDirective[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation).argumentName == "arg" + appliedDirective[0].name == "d" + } + + + def "applied directive deleted scalar"() { + given: + def oldSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d(arg: "foo") + type Query { + foo: DateTime + } + ''' + def newSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime + type Query { + foo: DateTime + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["DateTime"] instanceof ScalarModification + def appliedDirective = (changes.scalarDifferences["DateTime"] as ScalarModification).getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveScalarLocation).name == "DateTime" + appliedDirective[0].name == "d" + } + + def "applied directive deleted union"() { + given: + def oldSdl = ''' + directive @d(arg: String) on UNION + type Query { + foo: U + } + union U @d(arg: "foo") = A | B + type A { a: String } + type B { b: String } + ''' + def newSdl = ''' + directive @d(arg: String) on UNION + type Query { + foo: U + } + union U = A | B + type A { a: String } + type B { b: String } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences.keySet() == ["U"] as Set + changes.unionDifferences["U"] instanceof UnionModification + def diff = changes.unionDifferences["U"] as UnionModification + diff.details.size() == 1 + + def appliedDirective = diff.getDetails(AppliedDirectiveDeletion) + (appliedDirective[0].locationDetail as AppliedDirectiveUnionLocation).name == "U" + appliedDirective[0].name == "d" + } + + def "applied directive argument added union"() { + given: + def oldSdl = ''' + directive @d(arg:String) on UNION + type Query { + foo: FooBar + } + union FooBar @d = A | B + type A { a: String } + type B { b: String } + ''' + def newSdl = ''' + directive @d(arg:String) on UNION + type Query { + foo: FooBar + } + union FooBar @d(arg:"arg") = A | B + type A { a: String } + type B { b: String } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["FooBar"] instanceof UnionModification + def argumentAdded = (changes.unionDifferences["FooBar"] as UnionModification).getDetails(AppliedDirectiveArgumentAddition) + (argumentAdded[0].locationDetail as AppliedDirectiveUnionLocation).name == "FooBar" + (argumentAdded[0].locationDetail as AppliedDirectiveUnionLocation).directiveName == "d" + argumentAdded[0].argumentName == "arg" + } + + def "applied directive argument deleted union"() { + given: + def oldSdl = ''' + directive @d(arg:String) on UNION + type Query { + foo: FooBar + } + union FooBar @d(arg:"arg") = A | B + type A { a: String } + type B { b: String } + ''' + def newSdl = ''' + directive @d(arg:String) on UNION + type Query { + foo: FooBar + } + union FooBar @d = A | B + type A { a: String } + type B { b: String } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["FooBar"] instanceof UnionModification + def argumentDeleted = (changes.unionDifferences["FooBar"] as UnionModification).getDetails(AppliedDirectiveArgumentDeletion) + (argumentDeleted[0].locationDetail as AppliedDirectiveUnionLocation).name == "FooBar" + (argumentDeleted[0].locationDetail as AppliedDirectiveUnionLocation).directiveName == "d" + argumentDeleted[0].argumentName == "arg" + } + + + def "applied directive argument added scalar"() { + given: + def oldSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d + type Query { + foo: DateTime + } + ''' + def newSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d(arg: "foo") + type Query { + foo: DateTime + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["DateTime"] instanceof ScalarModification + def argumentAdded = (changes.scalarDifferences["DateTime"] as ScalarModification).getDetails(AppliedDirectiveArgumentAddition) + (argumentAdded[0].locationDetail as AppliedDirectiveScalarLocation).name == "DateTime" + argumentAdded[0].argumentName == "arg" + } + + def "applied directive argument deleted scalar"() { + given: + def oldSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d(arg: "foo") + type Query { + foo: DateTime + } + ''' + def newSdl = ''' + directive @d(arg:String) on SCALAR + scalar DateTime @d + type Query { + foo: DateTime + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["DateTime"] instanceof ScalarModification + def argumentDeletion = (changes.scalarDifferences["DateTime"] as ScalarModification).getDetails(AppliedDirectiveArgumentDeletion) + (argumentDeletion[0].locationDetail as AppliedDirectiveScalarLocation).name == "DateTime" + argumentDeletion[0].argumentName == "arg" + } + + def "applied directive argument added input object"() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d { + a: String + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d(arg: "foo") { + a: String + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def argumentAdded = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveArgumentAddition) + (argumentAdded[0].locationDetail as AppliedDirectiveInputObjectLocation).name == "I" + argumentAdded[0].argumentName == "arg" + } + + def "applied directive argument deleted input object"() { + given: + def oldSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d(arg: "foo") { + a: String + } + type Query { + foo(arg: I): String + } + ''' + def newSdl = ''' + directive @d(arg:String) on INPUT_OBJECT + input I @d { + a: String + } + type Query { + foo(arg: I): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def argumentAdded = (changes.inputObjectDifferences["I"] as InputObjectModification).getDetails(AppliedDirectiveArgumentDeletion) + (argumentAdded[0].locationDetail as AppliedDirectiveInputObjectLocation).name == "I" + argumentAdded[0].argumentName == "arg" + } + + + EditOperationAnalysisResult calcDiff( + String oldSdl, + String newSdl + ) { + def oldSchema = TestUtil.schema(oldSdl) + def newSchema = TestUtil.schema(newSdl) + def changes = new SchemaDiffing().diffAndAnalyze(oldSchema, newSchema) + return changes + } + +} diff --git a/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy new file mode 100644 index 0000000000..8661293408 --- /dev/null +++ b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy @@ -0,0 +1,3162 @@ +package graphql.schema.diffing.ana + +import graphql.TestUtil +import graphql.schema.diffing.Edge +import graphql.schema.diffing.EditOperation +import graphql.schema.diffing.SchemaDiffing +import graphql.schema.diffing.SchemaGraph +import graphql.schema.diffing.Vertex +import spock.lang.Specification + +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDeletion +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDirectiveArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceFieldArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldLocation +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveAddition +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentAddition +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentDefaultValueModification +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentDeletion +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentRename +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentTypeModification +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveDeletion +import static graphql.schema.diffing.ana.SchemaDifference.DirectiveModification +import static graphql.schema.diffing.ana.SchemaDifference.EnumAddition +import static graphql.schema.diffing.ana.SchemaDifference.EnumDeletion +import static graphql.schema.diffing.ana.SchemaDifference.EnumModification +import static graphql.schema.diffing.ana.SchemaDifference.EnumValueAddition +import static graphql.schema.diffing.ana.SchemaDifference.EnumValueDeletion +import static graphql.schema.diffing.ana.SchemaDifference.EnumValueRenamed +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectAddition +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectDeletion +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldAddition +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldDefaultValueModification +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldDeletion +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldRename +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectFieldTypeModification +import static graphql.schema.diffing.ana.SchemaDifference.InputObjectModification +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceAddition +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceDeletion +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldAddition +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentAddition +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentDefaultValueModification +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentDeletion +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentRename +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldArgumentTypeModification +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldDeletion +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldRename +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceFieldTypeModification +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceInterfaceImplementationDeletion +import static graphql.schema.diffing.ana.SchemaDifference.InterfaceModification +import static graphql.schema.diffing.ana.SchemaDifference.ObjectAddition +import static graphql.schema.diffing.ana.SchemaDifference.ObjectDeletion +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldAddition +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentAddition +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentDefaultValueModification +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentDeletion +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentRename +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldArgumentTypeModification +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldDeletion +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldRename +import static graphql.schema.diffing.ana.SchemaDifference.ObjectFieldTypeModification +import static graphql.schema.diffing.ana.SchemaDifference.ObjectInterfaceImplementationAddition +import static graphql.schema.diffing.ana.SchemaDifference.ObjectInterfaceImplementationDeletion +import static graphql.schema.diffing.ana.SchemaDifference.ObjectModification +import static graphql.schema.diffing.ana.SchemaDifference.ScalarAddition +import static graphql.schema.diffing.ana.SchemaDifference.ScalarDeletion +import static graphql.schema.diffing.ana.SchemaDifference.ScalarModification +import static graphql.schema.diffing.ana.SchemaDifference.UnionAddition +import static graphql.schema.diffing.ana.SchemaDifference.UnionDeletion +import static graphql.schema.diffing.ana.SchemaDifference.UnionMemberAddition +import static graphql.schema.diffing.ana.SchemaDifference.UnionMemberDeletion +import static graphql.schema.diffing.ana.SchemaDifference.UnionModification + +class EditOperationAnalyzerTest extends Specification { + def "object renamed"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + ''' + def newSdl = ''' + schema { + query: MyQuery + } + type MyQuery { + foo: String + } + + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] === changes.objectDifferences["MyQuery"] + changes.objectDifferences["Query"] instanceof ObjectModification + (changes.objectDifferences["Query"] as ObjectModification).oldName == "Query" + (changes.objectDifferences["Query"] as ObjectModification).newName == "MyQuery" + (changes.objectDifferences["Query"] as ObjectModification).isNameChanged() + } + + def "interface renamed"() { + given: + def oldSdl = ''' + type Query implements I { + foo: String + } + interface I { + foo: String + } + ''' + def newSdl = ''' + type Query implements IRenamed { + foo: String + } + interface IRenamed { + foo: String + } + + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] === changes.interfaceDifferences["IRenamed"] + changes.interfaceDifferences["I"] instanceof InterfaceModification + (changes.interfaceDifferences["I"] as InterfaceModification).oldName == "I" + (changes.interfaceDifferences["I"] as InterfaceModification).newName == "IRenamed" + (changes.interfaceDifferences["I"] as InterfaceModification).isNameChanged() + } + + def "interface removed from object"() { + given: + def oldSdl = ''' + type Query implements I { + foo: String + } + interface I { + foo: String + } + ''' + def newSdl = ''' + type Query{ + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def implementationDeletions = (changes.objectDifferences["Query"] as ObjectModification).getDetails(ObjectInterfaceImplementationDeletion) + implementationDeletions[0].name == "I" + } + + def "interface removed from interface"() { + given: + def oldSdl = ''' + type Query { + foo: Foo + } + interface FooI { + foo: String + } + interface Foo implements FooI { + foo: String + } + type FooImpl implements Foo & FooI { + foo: String + } + ''' + def newSdl = ''' + type Query { + foo: Foo + } + interface Foo { + foo: String + } + type FooImpl implements Foo { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["Foo"] instanceof InterfaceModification + def implementationDeletions = (changes.interfaceDifferences["Foo"] as InterfaceModification).getDetails(InterfaceInterfaceImplementationDeletion) + implementationDeletions[0].name == "FooI" + } + + def "object and interface field renamed"() { + given: + def oldSdl = ''' + type Query implements I{ + hello: String + } + interface I { + hello: String + } + ''' + def newSdl = ''' + type Query implements I{ + hello2: String + } + interface I { + hello2: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def oFieldRenames = objectModification.getDetails(ObjectFieldRename.class) + oFieldRenames[0].oldName == "hello" + oFieldRenames[0].newName == "hello2" + and: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["I"] as InterfaceModification + def iFieldRenames = interfaceModification.getDetails(InterfaceFieldRename.class) + iFieldRenames[0].oldName == "hello" + iFieldRenames[0].newName == "hello2" + } + + def "object and interface field deleted"() { + given: + def oldSdl = ''' + type Query implements I{ + hello: String + toDelete: String + } + interface I { + hello: String + toDelete: String + } + ''' + def newSdl = ''' + type Query implements I{ + hello: String + } + interface I { + hello: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def oFieldDeletions = objectModification.getDetails(ObjectFieldDeletion.class) + oFieldDeletions[0].name == "toDelete" + and: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["I"] as InterfaceModification + def iFieldDeletions = interfaceModification.getDetails(InterfaceFieldDeletion.class) + iFieldDeletions[0].name == "toDelete" + + } + + def "union added"() { + given: + def oldSdl = ''' + type Query { + hello: String + } + ''' + def newSdl = ''' + type Query { + hello: String + u: U + } + union U = A | B + type A { + foo: String + } + type B { + foo: String + } + + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionAddition + (changes.unionDifferences["U"] as UnionAddition).name == "U" + } + + def "union deleted"() { + given: + def oldSdl = ''' + type Query { + hello: String + u: U + } + union U = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + def newSdl = ''' + type Query { + hello: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionDeletion + (changes.unionDifferences["U"] as UnionDeletion).name == "U" + } + + def "union renamed"() { + given: + def oldSdl = ''' + type Query { + u: U + } + union U = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + def newSdl = ''' + type Query { + u: X + } + union X = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["X"] === changes.unionDifferences["U"] + changes.unionDifferences["U"] instanceof UnionModification + (changes.unionDifferences["U"] as UnionModification).oldName == "U" + (changes.unionDifferences["U"] as UnionModification).newName == "X" + (changes.unionDifferences["U"] as UnionModification).isNameChanged() + } + + def "union renamed and member removed"() { + given: + def oldSdl = ''' + type Query { + u: U + } + union U = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + def newSdl = ''' + type Query { + u: X + } + union X = A + type A { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionModification + def unionDiff = changes.unionDifferences["U"] as UnionModification + unionDiff.oldName == "U" + unionDiff.newName == "X" + unionDiff.getDetails(UnionMemberDeletion)[0].name == "B" + unionDiff.isNameChanged() + } + + def "union renamed and member added"() { + given: + def oldSdl = ''' + type Query { + u: U + } + union U = A + type A { + foo: String + } + + ''' + def newSdl = ''' + type Query { + u: X + } + union X = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionModification + def unionDiff = changes.unionDifferences["U"] as UnionModification + unionDiff.oldName == "U" + unionDiff.newName == "X" + unionDiff.isNameChanged() + unionDiff.getDetails(UnionMemberAddition)[0].name == "B" + } + + def "union member added"() { + given: + def oldSdl = ''' + type Query { + hello: String + u: U + } + union U = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + def newSdl = ''' + type Query { + hello: String + u: U + } + union U = A | B | C + type A { + foo: String + } + type B { + foo: String + } + type C { + foo: String + } + + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionModification + def unionModification = changes.unionDifferences["U"] as UnionModification + unionModification.getDetails(UnionMemberAddition)[0].name == "C" + } + + def "union member deleted"() { + given: + def oldSdl = ''' + type Query { + hello: String + u: U + } + union U = A | B + type A { + foo: String + } + type B { + foo: String + } + ''' + def newSdl = ''' + type Query { + hello: String + u: U + } + union U = A + type A { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.unionDifferences["U"] instanceof UnionModification + def unionModification = changes.unionDifferences["U"] as UnionModification + unionModification.getDetails(UnionMemberDeletion)[0].name == "B" + } + + def "field type modified"() { + given: + def oldSdl = ''' + type Query { + hello: String + } + ''' + def newSdl = ''' + type Query { + hello: String! + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def typeModification = objectModification.getDetails(ObjectFieldTypeModification.class) + typeModification[0].oldType == "String" + typeModification[0].newType == "String!" + } + + def "object and interface field argument added"() { + given: + def oldSdl = ''' + type Query implements I{ + hello: String + } + interface I { + hello: String + } + ''' + def newSdl = ''' + type Query implements I{ + hello(arg: String): String + } + interface I { + hello(arg: String): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def objectArgumentAdded = objectModification.getDetails(ObjectFieldArgumentAddition.class); + objectArgumentAdded[0].name == "arg" + and: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["I"] as InterfaceModification + def interfaceArgumentAdded = interfaceModification.getDetails(InterfaceFieldArgumentAddition.class); + interfaceArgumentAdded[0].name == "arg" + + } + + def "object and interface field argument renamed"() { + given: + def oldSdl = ''' + type Query implements I{ + hello(arg: String): String + } + interface I { + hello(arg: String): String + } + ''' + def newSdl = ''' + type Query implements I{ + hello(argRename: String): String + } + interface I { + hello(argRename: String): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def objectArgumentRenamed = objectModification.getDetails(ObjectFieldArgumentRename.class); + objectArgumentRenamed[0].fieldName == "hello" + objectArgumentRenamed[0].oldName == "arg" + objectArgumentRenamed[0].newName == "argRename" + and: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["I"] as InterfaceModification + def interfaceArgumentRenamed = interfaceModification.getDetails(InterfaceFieldArgumentRename.class); + interfaceArgumentRenamed[0].fieldName == "hello" + interfaceArgumentRenamed[0].oldName == "arg" + interfaceArgumentRenamed[0].newName == "argRename" + } + + + def "object and interface field argument deleted"() { + given: + def oldSdl = ''' + type Query implements I{ + hello(arg: String): String + } + interface I{ + hello(arg: String): String + } + ''' + def newSdl = ''' + type Query implements I { + hello: String + } + interface I { + hello: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def oArgumentRemoved = objectModification.getDetails(ObjectFieldArgumentDeletion.class); + oArgumentRemoved[0].fieldName == "hello" + oArgumentRemoved[0].name == "arg" + and: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["I"] as InterfaceModification + def iArgumentRemoved = interfaceModification.getDetails(InterfaceFieldArgumentDeletion.class); + iArgumentRemoved[0].fieldName == "hello" + iArgumentRemoved[0].name == "arg" + + } + + def "argument default value modified for Object and Interface"() { + given: + def oldSdl = ''' + type Query implements Foo { + foo(arg: String = "bar"): String + } + interface Foo { + foo(arg: String = "bar"): String + } + + ''' + def newSdl = ''' + type Query implements Foo { + foo(arg: String = "barChanged"): String + } + interface Foo { + foo(arg: String = "barChanged"): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def objDefaultValueModified = objectModification.getDetails(ObjectFieldArgumentDefaultValueModification.class); + objDefaultValueModified[0].fieldName == "foo" + objDefaultValueModified[0].argumentName == "arg" + objDefaultValueModified[0].oldValue == '"bar"' + objDefaultValueModified[0].newValue == '"barChanged"' + and: + changes.interfaceDifferences["Foo"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["Foo"] as InterfaceModification + def intDefaultValueModified = interfaceModification.getDetails(InterfaceFieldArgumentDefaultValueModification.class); + intDefaultValueModified[0].fieldName == "foo" + intDefaultValueModified[0].argumentName == "arg" + intDefaultValueModified[0].oldValue == '"bar"' + intDefaultValueModified[0].newValue == '"barChanged"' + } + + def "object and interface argument type changed completely"() { + given: + def oldSdl = ''' + type Query implements Foo { + foo(arg: String ): String + } + interface Foo { + foo(arg: String): String + } + + ''' + def newSdl = ''' + type Query implements Foo { + foo(arg: Int!): String + } + interface Foo { + foo(arg: Int!): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def objDefaultValueModified = objectModification.getDetails(ObjectFieldArgumentTypeModification.class); + objDefaultValueModified[0].fieldName == "foo" + objDefaultValueModified[0].argumentName == "arg" + objDefaultValueModified[0].oldType == 'String' + objDefaultValueModified[0].newType == 'Int!' + and: + changes.interfaceDifferences["Foo"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["Foo"] as InterfaceModification + def intDefaultValueModified = interfaceModification.getDetails(InterfaceFieldArgumentTypeModification.class); + intDefaultValueModified[0].fieldName == "foo" + intDefaultValueModified[0].argumentName == "arg" + intDefaultValueModified[0].oldType == 'String' + intDefaultValueModified[0].newType == 'Int!' + } + + def "object and interface argument type changed wrapping type"() { + given: + def oldSdl = ''' + type Query implements Foo { + foo(arg: String ): String + } + interface Foo { + foo(arg: String): String + } + + ''' + def newSdl = ''' + type Query implements Foo { + foo(arg: String!): String + } + interface Foo { + foo(arg: String!): String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def objDefaultValueModified = objectModification.getDetails(ObjectFieldArgumentTypeModification.class); + objDefaultValueModified[0].fieldName == "foo" + objDefaultValueModified[0].argumentName == "arg" + objDefaultValueModified[0].oldType == 'String' + objDefaultValueModified[0].newType == 'String!' + and: + changes.interfaceDifferences["Foo"] instanceof InterfaceModification + def interfaceModification = changes.interfaceDifferences["Foo"] as InterfaceModification + def intDefaultValueModified = interfaceModification.getDetails(InterfaceFieldArgumentTypeModification.class); + intDefaultValueModified[0].fieldName == "foo" + intDefaultValueModified[0].argumentName == "arg" + intDefaultValueModified[0].oldType == 'String' + intDefaultValueModified[0].newType == 'String!' + } + + def "object and interface field added"() { + given: + def oldSdl = ''' + type Query implements I{ + hello: String + } + interface I { + hello: String + } + ''' + def newSdl = ''' + type Query implements I{ + hello: String + newOne: String + } + interface I { + hello: String + newOne: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Query"] as ObjectModification + def oFieldAdded = objectModification.getDetails(ObjectFieldAddition) + oFieldAdded[0].name == "newOne" + and: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def iInterfaces = changes.interfaceDifferences["I"] as InterfaceModification + def iFieldAdded = iInterfaces.getDetails(InterfaceFieldAddition) + iFieldAdded[0].name == "newOne" + + } + + def "object added"() { + given: + def oldSdl = ''' + type Query { + hello: String + } + ''' + def newSdl = ''' + type Query { + hello: String + foo: Foo + } + type Foo { + id: ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Foo"] instanceof ObjectAddition + } + + def "object removed and field type changed"() { + given: + def oldSdl = ''' + type Query { + foo: Foo + } + type Foo { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.objectDifferences["Foo"] instanceof ObjectDeletion + (changes.objectDifferences["Foo"] as ObjectDeletion).name == "Foo" + changes.objectDifferences["Query"] instanceof ObjectModification + def queryObjectModification = changes.objectDifferences["Query"] as ObjectModification + queryObjectModification.details.size() == 1 + queryObjectModification.details[0] instanceof ObjectFieldTypeModification + (queryObjectModification.details[0] as ObjectFieldTypeModification).oldType == "Foo" + (queryObjectModification.details[0] as ObjectFieldTypeModification).newType == "String" + + } + + def "Interface and Object field type changed completely"() { + given: + def oldSdl = ''' + type Query implements I{ + foo: String + } + interface I { + foo: String + } + ''' + def newSdl = ''' + type Query implements I{ + foo: ID + } + interface I { + foo: ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def iModification = changes.interfaceDifferences["I"] as InterfaceModification + def iFieldTypeModifications = iModification.getDetails(InterfaceFieldTypeModification) + iFieldTypeModifications[0].fieldName == "foo" + iFieldTypeModifications[0].oldType == "String" + iFieldTypeModifications[0].newType == "ID" + and: + changes.objectDifferences["Query"] instanceof ObjectModification + def oModification = changes.objectDifferences["Query"] as ObjectModification + def oFieldTypeModifications = oModification.getDetails(ObjectFieldTypeModification) + oFieldTypeModifications[0].fieldName == "foo" + oFieldTypeModifications[0].oldType == "String" + oFieldTypeModifications[0].newType == "ID" + } + + def "Interface and Object field type changed wrapping type"() { + given: + def oldSdl = ''' + type Query implements I{ + foo: String + } + interface I { + foo: String + } + ''' + def newSdl = ''' + type Query implements I{ + foo: [String!] + } + interface I { + foo: [String!] + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences["I"] instanceof InterfaceModification + def iModification = changes.interfaceDifferences["I"] as InterfaceModification + def iFieldTypeModifications = iModification.getDetails(InterfaceFieldTypeModification) + iFieldTypeModifications[0].fieldName == "foo" + iFieldTypeModifications[0].oldType == "String" + iFieldTypeModifications[0].newType == "[String!]" + and: + changes.objectDifferences["Query"] instanceof ObjectModification + def oModification = changes.objectDifferences["Query"] as ObjectModification + def oFieldTypeModifications = oModification.getDetails(ObjectFieldTypeModification) + oFieldTypeModifications[0].fieldName == "foo" + oFieldTypeModifications[0].oldType == "String" + oFieldTypeModifications[0].newType == "[String!]" + + + } + + def "new Interface introduced"() { + given: + def oldSdl = ''' + type Query { + foo: Foo + } + type Foo { + id: ID! + } + ''' + def newSdl = ''' + type Query { + foo: Foo + } + type Foo implements Node{ + id: ID! + } + interface Node { + id: ID! + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences.size() == 1 + changes.interfaceDifferences["Node"] instanceof InterfaceAddition + changes.objectDifferences.size() == 1 + changes.objectDifferences["Foo"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Foo"] as ObjectModification + def addedInterfaceDetails = objectModification.getDetails(ObjectInterfaceImplementationAddition.class) + addedInterfaceDetails.size() == 1 + addedInterfaceDetails[0].name == "Node" + } + + def "Object and Interface added"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + ''' + def newSdl = ''' + type Query { + foo: Foo + } + type Foo implements Node{ + id: ID! + } + interface Node { + id: ID! + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences.size() == 1 + changes.interfaceDifferences["Node"] instanceof InterfaceAddition + changes.objectDifferences.size() == 2 + changes.objectDifferences["Foo"] instanceof ObjectAddition + changes.objectDifferences["Query"] instanceof ObjectModification + (changes.objectDifferences["Query"] as ObjectModification).getDetails()[0] instanceof ObjectFieldTypeModification + } + + def "interfaced renamed"() { + given: + def oldSdl = ''' + type Query { + foo: Foo + } + type Foo implements Node{ + id: ID! + } + interface Node { + id: ID! + } + ''' + def newSdl = ''' + type Query { + foo: Foo + } + interface Node2 { + id: ID! + } + type Foo implements Node2{ + id: ID! + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences.size() == 2 + changes.interfaceDifferences["Node"] === changes.interfaceDifferences["Node2"] + changes.interfaceDifferences["Node2"] instanceof InterfaceModification + (changes.interfaceDifferences["Node2"] as InterfaceModification).isNameChanged() + } + + def "interfaced renamed and another interface added to it"() { + given: + def oldSdl = ''' + type Query { + foo: Foo + } + type Foo implements Node{ + id: ID! + } + interface Node { + id: ID! + } + ''' + def newSdl = ''' + type Query { + foo: Foo + } + interface NewI { + hello: String + } + interface Node2 { + id: ID! + } + type Foo implements Node2 & NewI { + id: ID! + hello: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.interfaceDifferences.size() == 3 + changes.interfaceDifferences["Node"] == changes.interfaceDifferences["Node2"] + changes.interfaceDifferences["Node2"] instanceof InterfaceModification + (changes.interfaceDifferences["Node2"] as InterfaceModification).isNameChanged() + changes.interfaceDifferences["NewI"] instanceof InterfaceAddition + changes.objectDifferences.size() == 1 + changes.objectDifferences["Foo"] instanceof ObjectModification + def objectModification = changes.objectDifferences["Foo"] as ObjectModification + def addedInterfaceDetails = objectModification.getDetails(ObjectInterfaceImplementationAddition) + addedInterfaceDetails.size() == 1 + addedInterfaceDetails[0].name == "NewI" + } + + def "enum renamed"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + enum E { + A, B + } + ''' + def newSdl = ''' + type Query { + foo: ERenamed + } + enum ERenamed { + A, B + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] === changes.enumDifferences["ERenamed"] + def modification = changes.enumDifferences["E"] as EnumModification + modification.oldName == "E" + modification.newName == "ERenamed" + modification.isNameChanged() + } + + def "enum added"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + ''' + def newSdl = ''' + type Query { + foo: E + } + enum E { + A, B + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumAddition + (changes.enumDifferences["E"] as EnumAddition).getName() == "E" + } + + def "enum deleted"() { + given: + def oldSdl = ''' + type Query { + foo: E + } + enum E { + A, B + } + ''' + def newSdl = ''' + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumDeletion + (changes.enumDifferences["E"] as EnumDeletion).getName() == "E" + } + + + def "enum value added"() { + given: + def oldSdl = ''' + type Query { + e: E + } + enum E { + A + } + ''' + def newSdl = ''' + type Query { + e: E + } + enum E { + A, B + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def enumModification = changes.enumDifferences["E"] as EnumModification + enumModification.getDetails(EnumValueAddition)[0].name == "B" + } + + def "enum value deleted"() { + given: + def oldSdl = ''' + type Query { + e: E + } + enum E { + A,B + } + ''' + def newSdl = ''' + type Query { + e: E + } + enum E { + A + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["E"] instanceof EnumModification + def enumModification = changes.enumDifferences["E"] as EnumModification + enumModification.getDetails(EnumValueDeletion)[0].name == "B" + } + + def "enum value added and removed"() { + given: + def oldSdl = ''' + type Query { + e: MyEnum + } + enum MyEnum { + A + B + } + ''' + def newSdl = ''' + type Query { + e: MyEnum + } + enum MyEnum { + A + C + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.enumDifferences["MyEnum"] instanceof EnumModification + + def enumModification = changes.enumDifferences["MyEnum"] as EnumModification + enumModification.getDetails().size() == 1 + + def rename = enumModification.getDetails(EnumValueRenamed)[0] + rename.oldName == "B" + rename.newName == "C" + } + + def "scalar added"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + ''' + def newSdl = ''' + type Query { + foo: E + } + scalar E + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["E"] instanceof ScalarAddition + (changes.scalarDifferences["E"] as ScalarAddition).getName() == "E" + } + + def "scalar deleted"() { + given: + def oldSdl = ''' + type Query { + foo: E + } + scalar E + ''' + def newSdl = ''' + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["E"] instanceof ScalarDeletion + (changes.scalarDifferences["E"] as ScalarDeletion).getName() == "E" + } + + def "scalar renamed"() { + given: + def oldSdl = ''' + type Query { + foo: Foo + } + scalar Foo + ''' + def newSdl = ''' + type Query { + foo: Bar + } + scalar Bar + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.scalarDifferences["Foo"] === changes.scalarDifferences["Bar"] + def modification = changes.scalarDifferences["Foo"] as ScalarModification + modification.oldName == "Foo" + modification.newName == "Bar" + modification.isNameChanged() + } + + def "input object added"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectAddition + (changes.inputObjectDifferences["I"] as InputObjectAddition).getName() == "I" + } + + def "input object field added"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + newField: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + def fieldAddition = modification.getDetails(InputObjectFieldAddition)[0] + fieldAddition.name == "newField" + } + + def "input object field deletion"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + toDelete: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + def fieldDeletion = modification.getDetails(InputObjectFieldDeletion)[0] + fieldDeletion.name == "toDelete" + } + + def "input object field renamed"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + barNew: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + def fieldDeletion = modification.getDetails(InputObjectFieldRename)[0] + fieldDeletion.oldName == "bar" + fieldDeletion.newName == "barNew" + } + + def "input object field wrapping type changed"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: [String] + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + def typeModification = modification.getDetails(InputObjectFieldTypeModification)[0] + typeModification.oldType == "String" + typeModification.newType == "[String]" + } + + def "input object field type changed"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + def typeModification = modification.getDetails(InputObjectFieldTypeModification)[0] + typeModification.oldType == "String" + typeModification.newType == "ID" + } + + def "input object field default value changed"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String = "A" + } + ''' + def newSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String = "B" + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectModification + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + def modificationDetail = modification.getDetails(InputObjectFieldDefaultValueModification)[0] + modificationDetail.oldDefaultValue == '"A"' + modificationDetail.newDefaultValue == '"B"' + } + + def "input object deleted"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] instanceof InputObjectDeletion + (changes.inputObjectDifferences["I"] as InputObjectDeletion).getName() == "I" + } + + def "input object renamed"() { + given: + def oldSdl = ''' + type Query { + foo(arg: I): String + } + input I { + bar: String + } + ''' + def newSdl = ''' + type Query { + foo(arg: IRenamed): String + } + input IRenamed { + bar: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["I"] === changes.inputObjectDifferences["IRenamed"] + def modification = changes.inputObjectDifferences["I"] as InputObjectModification + modification.oldName == "I" + modification.newName == "IRenamed" + modification.isNameChanged() + } + + + def "directive added"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveAddition + (changes.directiveDifferences["d"] as DirectiveAddition).getName() == "d" + } + + def "directive deleted"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveDeletion + (changes.directiveDifferences["d"] as DirectiveDeletion).getName() == "d" + } + + def "directive renamed"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @dRenamed on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] === changes.directiveDifferences["dRenamed"] + def modification = changes.directiveDifferences["d"] as DirectiveModification + modification.oldName == "d" + modification.newName == "dRenamed" + modification.isNameChanged() + } + + def "directive argument renamed"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d(foo: String) on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d(bar:String) on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveModification + def renames = (changes.directiveDifferences["d"] as DirectiveModification).getDetails(DirectiveArgumentRename) + renames[0].oldName == "foo" + renames[0].newName == "bar" + } + + def "directive argument added"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d(foo:String) on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveModification + def addition = (changes.directiveDifferences["d"] as DirectiveModification).getDetails(DirectiveArgumentAddition) + addition[0].name == "foo" + + + } + + def "directive argument deleted"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d(foo:String) on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveModification + def deletion = (changes.directiveDifferences["d"] as DirectiveModification).getDetails(DirectiveArgumentDeletion) + deletion[0].name == "foo" + + + } + + def "directive argument default value changed"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d(foo:String = "A") on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d(foo: String = "B") on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveModification + def defaultValueChange = (changes.directiveDifferences["d"] as DirectiveModification).getDetails(DirectiveArgumentDefaultValueModification) + defaultValueChange[0].argumentName == "foo" + defaultValueChange[0].oldValue == '"A"' + defaultValueChange[0].newValue == '"B"' + + + } + + def "directive argument type changed completely"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d(foo:String) on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d(foo: ID) on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveModification + def argTypeModification = (changes.directiveDifferences["d"] as DirectiveModification).getDetails(DirectiveArgumentTypeModification) + argTypeModification[0].argumentName == "foo" + argTypeModification[0].oldType == 'String' + argTypeModification[0].newType == 'ID' + } + + def "directive argument wrapping type changed"() { + given: + def oldSdl = ''' + type Query { + foo: String + } + directive @d(foo:String) on FIELD + ''' + def newSdl = ''' + type Query { + foo: String + } + directive @d(foo: [String]!) on FIELD + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.directiveDifferences["d"] instanceof DirectiveModification + def argTypeModification = (changes.directiveDifferences["d"] as DirectiveModification).getDetails(DirectiveArgumentTypeModification) + argTypeModification[0].argumentName == "foo" + argTypeModification[0].oldType == 'String' + argTypeModification[0].newType == '[String]!' + } + + def "field renamed and output type changed and argument deleted"() { + given: + def oldSdl = ''' + type Query { + ping(pong: String): ID + } + ''' + def newSdl = ''' + type Query { + echo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.objectDifferences["Query"] instanceof ObjectModification + def objectDiff = changes.objectDifferences["Query"] as ObjectModification + + def rename = objectDiff.getDetails(ObjectFieldRename) + rename.size() == 1 + rename[0].oldName == "ping" + rename[0].newName == "echo" + + def argumentDeletion = objectDiff.getDetails(ObjectFieldArgumentDeletion) + argumentDeletion.size() == 1 + argumentDeletion[0].fieldName == "ping" + argumentDeletion[0].name == "pong" + + def typeModification = objectDiff.getDetails(ObjectFieldTypeModification) + typeModification.size() == 1 + typeModification[0].fieldName == "echo" + typeModification[0].oldType == "ID" + typeModification[0].newType == "String" + } + + def "object field argument changed and applied directive deleted"() { + given: + def oldSdl = ''' + type Query { + ping(pong: String @d): ID + } + directive @d on ARGUMENT_DEFINITION + ''' + def newSdl = ''' + type Query { + ping(pong: Int): ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.objectDifferences["Query"] instanceof ObjectModification + def objectDiff = changes.objectDifferences["Query"] as ObjectModification + + def typeModification = objectDiff.getDetails(ObjectFieldArgumentTypeModification) + typeModification.size() == 1 + typeModification[0].oldType == "String" + typeModification[0].newType == "Int" + typeModification[0].fieldName == "ping" + typeModification[0].argumentName == "pong" + + def directiveDeletion = objectDiff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveObjectFieldArgumentLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation + location.objectName == "Query" + location.fieldName == "ping" + location.argumentName == "pong" + } + + def "interface field argument changed and applied directive deleted"() { + given: + def oldSdl = ''' + type Query { + echo: String + } + interface TableTennis { + ping(pong: String @d): ID + } + directive @d on ARGUMENT_DEFINITION + ''' + def newSdl = ''' + type Query { + echo: String + } + interface TableTennis { + ping(pong: Int): ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.interfaceDifferences["TableTennis"] instanceof InterfaceModification + def diff = changes.interfaceDifferences["TableTennis"] as InterfaceModification + + def typeModification = diff.getDetails(InterfaceFieldArgumentTypeModification) + typeModification.size() == 1 + typeModification[0].oldType == "String" + typeModification[0].newType == "Int" + typeModification[0].fieldName == "ping" + typeModification[0].argumentName == "pong" + + def directiveDeletion = diff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveInterfaceFieldArgumentLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation + location.interfaceName == "TableTennis" + location.fieldName == "ping" + location.argumentName == "pong" + } + + def "directive argument changed and applied directive deleted"() { + given: + def oldSdl = ''' + type Query { + ping(pong: String): ID @d + } + directive @a on ARGUMENT_DEFINITION + directive @d(message: ID @a) on FIELD_DEFINITION + ''' + def newSdl = ''' + type Query { + ping(pong: String): ID @d + } + directive @a on ARGUMENT_DEFINITION + directive @d(message: String) on FIELD_DEFINITION + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.directiveDifferences["d"] instanceof DirectiveModification + def diff = changes.directiveDifferences["d"] as DirectiveModification + + def typeModification = diff.getDetails(DirectiveArgumentTypeModification) + typeModification.size() == 1 + typeModification[0].oldType == "ID" + typeModification[0].newType == "String" + typeModification[0].argumentName == "message" + + def directiveDeletion = diff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "a" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveDirectiveArgumentLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveDefinitionName == "d" + location.argumentName == "message" + location.directiveName == "a" + } + + def "field output type changed and applied directive removed"() { + given: + def oldSdl = ''' + type Query { + echo: ID @d + } + directive @d on FIELD_DEFINITION + ''' + def newSdl = ''' + type Query { + echo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.objectDifferences["Query"] instanceof ObjectModification + def objectDiff = changes.objectDifferences["Query"] as ObjectModification + + def typeModification = objectDiff.getDetails(ObjectFieldTypeModification) + typeModification.size() == 1 + typeModification[0].fieldName == "echo" + typeModification[0].oldType == "ID" + typeModification[0].newType == "String" + + def directiveDeletion = objectDiff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveObjectFieldLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveObjectFieldLocation + location.objectName == "Query" + location.fieldName == "echo" + } + + def "input field renamed and type changed and applied directive removed"() { + given: + def oldSdl = ''' + type Query { + echo(input: Echo): String + } + input Echo { + message: String @d + } + directive @d on INPUT_FIELD_DEFINITION + ''' + def newSdl = ''' + type Query { + echo(input: Echo): String + } + input Echo { + age: Int + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + changes.inputObjectDifferences["Echo"] instanceof InputObjectModification + def diff = changes.inputObjectDifferences["Echo"] as InputObjectModification + + def rename = diff.getDetails(InputObjectFieldRename) + rename.size() == 1 + rename[0].oldName == "message" + rename[0].newName == "age" + + def typeModification = diff.getDetails(InputObjectFieldTypeModification) + typeModification.size() == 1 + typeModification[0].fieldName == "age" + typeModification[0].oldType == "String" + typeModification[0].newType == "Int" + + def directiveDeletion = diff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + } + + def "object field description changed"() { + given: + def oldSdl = ''' + type Query { + " Hello" + echo: String + } + ''' + def newSdl = ''' + type Query { + "Test " + echo: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + // no changes + changes.objectDifferences["Query"] == null + } + + def "interface field description changed"() { + given: + def oldSdl = ''' + type Query { + node: Node + } + interface Node { + " Hello" + echo: String + } + ''' + def newSdl = ''' + type Query { + node: Node + } + interface Node { + "World" + echo: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + // no changes + changes.interfaceDifferences["Node"] == null + } + + def "interface deleted with field argument"() { + given: + def oldSdl = ''' + type Query { + node: Node + } + interface Node { + echo(test: String): String + } + ''' + def newSdl = ''' + type Query { + node: ID + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["Node"] instanceof InterfaceDeletion + } + + def "object deleted with field argument"() { + given: + def oldSdl = ''' + type Query { + node: Node + } + type Node { + echo(test: String): String + } + ''' + def newSdl = ''' + type Query { + node: ID + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Node"] instanceof ObjectDeletion + } + + def "directive deleted with argument"() { + given: + def oldSdl = ''' + type Query { + node: String + } + directive @test(message: String) on FIELD + ''' + def newSdl = ''' + type Query { + node: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences["test"] instanceof DirectiveDeletion + } + + def "interface added with field argument"() { + given: + def oldSdl = ''' + type Query { + node: ID + } + ''' + def newSdl = ''' + type Query { + node: Node + } + interface Node { + echo(test: String): String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["Node"] instanceof InterfaceAddition + } + + def "object added with field argument"() { + given: + def oldSdl = ''' + type Query { + node: ID + } + ''' + def newSdl = ''' + type Query { + node: Node + } + type Node { + echo(test: String): String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Node"] instanceof ObjectAddition + } + + def "directive added with argument"() { + given: + def oldSdl = ''' + type Query { + node: String + } + ''' + def newSdl = ''' + type Query { + node: String + } + directive @test(message: String) on FIELD + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences["test"] instanceof DirectiveAddition + } + + def "delete object with applied directive on field"() { + given: + def oldSdl = ''' + type Query { + user(id: ID!): User + } + directive @id(type: String, owner: String) on FIELD_DEFINITION + type User { + id: ID! @id(type: "user", owner: "profiles") + } + ''' + def newSdl = ''' + type Query { + echo: String + } + directive @id(type: String, owner: String) on FIELD_DEFINITION + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["User"] instanceof ObjectDeletion + } + + def "delete interface with applied directive on field"() { + given: + def oldSdl = ''' + type Query { + user(id: ID!): User + } + directive @id(type: String, owner: String) on FIELD_DEFINITION + interface User { + id: ID! @id(type: "user", owner: "profiles") + } + ''' + def newSdl = ''' + type Query { + echo: String + } + directive @id(type: String, owner: String) on FIELD_DEFINITION + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["User"] instanceof InterfaceDeletion + } + + def "argument removed and similar argument added on separate object fields"() { + given: + def oldSdl = ''' + type Query { + issues: IssueQuery + } + type IssueQuery { + issue: Issue + issues(id: [ID!]!): [Issue] + } + type Issue { + id: ID! + } + ''' + def newSdl = ''' + type Query { + issues: IssueQuery + } + type IssueQuery { + issue(id: ID): Issue + issues: [Issue] + } + type Issue { + id: ID! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["IssueQuery"] instanceof ObjectModification + def issueQueryChanges = changes.objectDifferences["IssueQuery"] as ObjectModification + issueQueryChanges.details.size() == 2 + + def argumentAddition = issueQueryChanges.getDetails(ObjectFieldArgumentAddition) + argumentAddition.size() == 1 + argumentAddition[0].fieldName == "issue" + argumentAddition[0].name == "id" + + def argumentDeletion = issueQueryChanges.getDetails(ObjectFieldArgumentDeletion) + argumentDeletion.size() == 1 + argumentDeletion[0].fieldName == "issues" + argumentDeletion[0].name == "id" + } + + def "argument removed and similar argument added on separate interface fields"() { + given: + def oldSdl = ''' + type Query { + issues: IssueQuery + } + interface IssueQuery { + issue: Issue + issues(id: [ID!]!): [Issue] + } + type Issue { + id: ID! + } + ''' + def newSdl = ''' + type Query { + issues: IssueQuery + } + interface IssueQuery { + issue(id: ID): Issue + issues: [Issue] + } + type Issue { + id: ID! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["IssueQuery"] instanceof InterfaceModification + def issueQueryChanges = changes.interfaceDifferences["IssueQuery"] as InterfaceModification + issueQueryChanges.details.size() == 2 + + def argumentAddition = issueQueryChanges.getDetails(InterfaceFieldArgumentAddition) + argumentAddition.size() == 1 + argumentAddition[0].fieldName == "issue" + argumentAddition[0].name == "id" + + def argumentDeletion = issueQueryChanges.getDetails(InterfaceFieldArgumentDeletion) + argumentDeletion.size() == 1 + argumentDeletion[0].fieldName == "issues" + argumentDeletion[0].name == "id" + } + + def "argument removed and similar argument added on separate directives"() { + given: + def oldSdl = ''' + directive @dog(name: String) on FIELD_DEFINITION + directive @cat on FIELD_DEFINITION + type Query { + pet: String @dog + } + ''' + def newSdl = ''' + directive @dog on FIELD_DEFINITION + directive @cat(name: [String]) on FIELD_DEFINITION + type Query { + pet: String @dog + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences["cat"] instanceof DirectiveModification + def catChanges = changes.directiveDifferences["cat"] as DirectiveModification + catChanges.details.size() == 1 + def argumentAdditions = catChanges.getDetails(DirectiveArgumentAddition) + argumentAdditions.size() == 1 + argumentAdditions[0].name == "name" + + changes.directiveDifferences["dog"] instanceof DirectiveModification + def dogChanges = changes.directiveDifferences["dog"] as DirectiveModification + dogChanges.details.size() == 1 + def argumentDeletions = dogChanges.getDetails(DirectiveArgumentDeletion) + argumentDeletions.size() == 1 + argumentDeletions[0].name == "name" + } + + def "argument removed and added on renamed object field"() { + given: + def oldSdl = ''' + type Query { + issues: IssueQuery + } + type IssueQuery { + issues(id: [ID!]): [Issue] + } + type Issue { + id: ID! + } + ''' + def newSdl = ''' + type Query { + issues: IssueQuery + } + type IssueQuery { + issuesById(ids: [ID!]!): [Issue] + } + type Issue { + id: ID! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["IssueQuery"] instanceof ObjectModification + def issueQueryChanges = changes.objectDifferences["IssueQuery"] as ObjectModification + issueQueryChanges.details.size() == 3 + + def rename = issueQueryChanges.getDetails(ObjectFieldRename) + rename.size() == 1 + rename[0].oldName == "issues" + rename[0].newName == "issuesById" + + def argumentRename = issueQueryChanges.getDetails(ObjectFieldArgumentRename) + argumentRename.size() == 1 + argumentRename[0].fieldName == "issuesById" + argumentRename[0].oldName == "id" + argumentRename[0].newName == "ids" + + def argumentTypeModification = issueQueryChanges.getDetails(ObjectFieldArgumentTypeModification) + argumentTypeModification.size() == 1 + argumentTypeModification[0].fieldName == "issuesById" + argumentTypeModification[0].argumentName == "ids" + argumentTypeModification[0].oldType == "[ID!]" + argumentTypeModification[0].newType == "[ID!]!" + } + + def "argument removed and added on renamed interface field"() { + given: + def oldSdl = ''' + type Query { + issues: IssueQuery + } + interface IssueQuery { + issues(id: [ID!]): [Issue] + } + type Issue { + id: ID! + } + ''' + def newSdl = ''' + type Query { + issues: IssueQuery + } + interface IssueQuery { + issuesById(ids: [ID!]!): [Issue] + } + type Issue { + id: ID! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["IssueQuery"] instanceof InterfaceModification + def issueQueryChanges = changes.interfaceDifferences["IssueQuery"] as InterfaceModification + issueQueryChanges.details.size() == 3 + + def rename = issueQueryChanges.getDetails(InterfaceFieldRename) + rename.size() == 1 + rename[0].oldName == "issues" + rename[0].newName == "issuesById" + + def argumentRename = issueQueryChanges.getDetails(InterfaceFieldArgumentRename) + argumentRename.size() == 1 + argumentRename[0].fieldName == "issuesById" + argumentRename[0].oldName == "id" + argumentRename[0].newName == "ids" + + def argumentTypeModification = issueQueryChanges.getDetails(InterfaceFieldArgumentTypeModification) + argumentTypeModification.size() == 1 + argumentTypeModification[0].fieldName == "issuesById" + argumentTypeModification[0].argumentName == "ids" + argumentTypeModification[0].oldType == "[ID!]" + argumentTypeModification[0].newType == "[ID!]!" + } + + def "argument removed and added on renamed directive"() { + given: + def oldSdl = ''' + directive @dog(name: String) on FIELD_DEFINITION + type Query { + pet: String @dog + } + ''' + def newSdl = ''' + directive @cat(names: [String]) on FIELD_DEFINITION + type Query { + pet: String @cat + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences["cat"] instanceof DirectiveModification + def catChanges = changes.directiveDifferences["cat"] as DirectiveModification + catChanges.oldName == "dog" + catChanges.newName == "cat" + catChanges.isNameChanged() + catChanges.details.size() == 2 + + def argumentRename = catChanges.getDetails(DirectiveArgumentRename) + argumentRename.size() == 1 + argumentRename[0].oldName == "name" + argumentRename[0].newName == "names" + + def argumentTypeModification = catChanges.getDetails(DirectiveArgumentTypeModification) + argumentTypeModification.size() == 1 + argumentTypeModification[0].argumentName == "names" + argumentTypeModification[0].oldType == "String" + argumentTypeModification[0].newType == "[String]" + } + + + def "object field argument type and default value changed"() { + given: + def oldSdl = ''' + type Query { + echo(message: String! = "Hello World"): String + } + ''' + def newSdl = ''' + type Query { + echo(message: ID! = "1"): String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Query"] instanceof ObjectModification + def queryChanges = changes.objectDifferences["Query"] as ObjectModification + queryChanges.details.size() == 2 + + def argumentTypeModification = queryChanges.getDetails(ObjectFieldArgumentTypeModification) + argumentTypeModification.size() == 1 + argumentTypeModification[0].fieldName == "echo" + argumentTypeModification[0].argumentName == "message" + argumentTypeModification[0].oldType == "String!" + argumentTypeModification[0].newType == "ID!" + + def defaultValueModification = queryChanges.getDetails(ObjectFieldArgumentDefaultValueModification) + defaultValueModification.size() == 1 + defaultValueModification[0].fieldName == "echo" + defaultValueModification[0].argumentName == "message" + defaultValueModification[0].oldValue == '"Hello World"' + defaultValueModification[0].newValue == '"1"' + } + + def "interface field argument type and default value changed"() { + given: + def oldSdl = ''' + type Query { + echo: EchoProvider + } + interface EchoProvider { + send(message: String! = "Hello World"): String + } + ''' + def newSdl = ''' + type Query { + echo: EchoProvider + } + interface EchoProvider { + send(message: ID! = "1"): String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["EchoProvider"] instanceof InterfaceModification + def echoProviderChanges = changes.interfaceDifferences["EchoProvider"] as InterfaceModification + echoProviderChanges.details.size() == 2 + + def argumentTypeModification = echoProviderChanges.getDetails(InterfaceFieldArgumentTypeModification) + argumentTypeModification.size() == 1 + argumentTypeModification[0].fieldName == "send" + argumentTypeModification[0].argumentName == "message" + argumentTypeModification[0].oldType == "String!" + argumentTypeModification[0].newType == "ID!" + + def defaultValueModification = echoProviderChanges.getDetails(InterfaceFieldArgumentDefaultValueModification) + defaultValueModification.size() == 1 + defaultValueModification[0].fieldName == "send" + defaultValueModification[0].argumentName == "message" + defaultValueModification[0].oldValue == '"Hello World"' + defaultValueModification[0].newValue == '"1"' + } + + def "directive argument type and default value changed"() { + given: + def oldSdl = ''' + directive @deleteBy(date: String = "+1 week") on FIELD_DEFINITION + type Query { + echo: String @deleteBy + } + ''' + def newSdl = ''' + directive @deleteBy(date: Int = 1000) on FIELD_DEFINITION + type Query { + echo: String @deleteBy + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences["deleteBy"] instanceof DirectiveModification + def deleteByChanges = changes.directiveDifferences["deleteBy"] as DirectiveModification + deleteByChanges.details.size() == 2 + + def argumentTypeModification = deleteByChanges.getDetails(DirectiveArgumentTypeModification) + argumentTypeModification.size() == 1 + argumentTypeModification[0].argumentName == "date" + argumentTypeModification[0].oldType == "String" + argumentTypeModification[0].newType == "Int" + + def defaultValueModification = deleteByChanges.getDetails(DirectiveArgumentDefaultValueModification) + defaultValueModification.size() == 1 + defaultValueModification[0].argumentName == "date" + defaultValueModification[0].oldValue == '"+1 week"' + defaultValueModification[0].newValue == '1000' + } + + def "object field with argument removed and similarly named argument added"() { + given: + def oldSdl = """ + type Query { + issues: IssueQuery + } + type IssueQuery { + issues(id: [ID!]): [Issue] + issuesById: [Issue] + } + type Issue { + id: ID! + } + """ + def newSdl = ''' + type Query { + issues: IssueQuery + } + type IssueQuery { + issuesById(ids: [ID!]!): [Issue] + } + type Issue { + id: ID! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["IssueQuery"] instanceof ObjectModification + def issueQueryChanges = changes.objectDifferences["IssueQuery"] as ObjectModification + issueQueryChanges.details.size() == 2 + + def fieldDeletion = issueQueryChanges.getDetails(ObjectFieldDeletion) + fieldDeletion.size() == 1 + fieldDeletion[0].name == "issues" + + def fieldArgumentAddition = issueQueryChanges.getDetails(ObjectFieldArgumentAddition) + fieldArgumentAddition.size() == 1 + fieldArgumentAddition[0].fieldName == "issuesById" + fieldArgumentAddition[0].name == "ids" + } + + def "interface field with argument removed and similarly named argument added"() { + given: + def oldSdl = """ + type Query { + issues: IssueQuery + } + interface IssueQuery { + issues(id: [ID!]): [Issue] + issuesById: [Issue] + } + type Issue { + id: ID! + } + """ + def newSdl = ''' + type Query { + issues: IssueQuery + } + interface IssueQuery { + issuesById(ids: [ID!]!): [Issue] + } + type Issue { + id: ID! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences["IssueQuery"] instanceof InterfaceModification + def issueQueryChanges = changes.interfaceDifferences["IssueQuery"] as InterfaceModification + issueQueryChanges.details.size() == 2 + + def fieldDeletion = issueQueryChanges.getDetails(InterfaceFieldDeletion) + fieldDeletion.size() == 1 + fieldDeletion[0].name == "issues" + + def fieldArgumentAddition = issueQueryChanges.getDetails(InterfaceFieldArgumentAddition) + fieldArgumentAddition.size() == 1 + fieldArgumentAddition[0].fieldName == "issuesById" + fieldArgumentAddition[0].name == "ids" + } + + def "directive removed and similarly named argument added"() { + given: + def oldSdl = ''' + directive @dog(name: String) on FIELD_DEFINITION + directive @cat on FIELD_DEFINITION + type Query { + pet: String + } + ''' + def newSdl = ''' + directive @cat(names: String) on FIELD_DEFINITION + type Query { + pet: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences["dog"] instanceof DirectiveDeletion + def dogChanges = changes.directiveDifferences["dog"] as DirectiveDeletion + dogChanges.name == "dog" + + changes.directiveDifferences["cat"] instanceof DirectiveModification + def catChanges = changes.directiveDifferences["cat"] as DirectiveModification + !catChanges.isNameChanged() + catChanges.oldName == catChanges.newName + catChanges.newName == "cat" + catChanges.details.size() == 1 + + def argumentAddition = catChanges.getDetails(DirectiveArgumentAddition) + argumentAddition.size() == 1 + argumentAddition[0].name == "names" + } + + def "change object description"() { + given: + def oldSdl = ''' + "HELLO" + type Query { + pet: String + } + ''' + def newSdl = ''' + type Query { + pet: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences.isEmpty() + } + + def "change object field argument description"() { + given: + def oldSdl = ''' + type Query { + pet( + age: Int + ): String + } + ''' + def newSdl = ''' + type Query { + pet( + "The age of the pet" + age: Int + ): String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences.isEmpty() + } + + def "change interface description"() { + given: + def oldSdl = ''' + type Query { + pet: Pet + } + interface Pet { + name: String + } + ''' + def newSdl = ''' + type Query { + pet: Pet + } + "Hello World" + interface Pet { + name: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.interfaceDifferences.isEmpty() + } + + def "change union description"() { + given: + def oldSdl = ''' + type Query { + pet: Pet + } + union Pet = Dog | Cat + type Dog { + name: String + } + type Cat { + name: String + } + ''' + def newSdl = ''' + type Query { + pet: Pet + } + "----------------" + union Pet = Dog | Cat + type Dog { + name: String + } + type Cat { + name: String + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.unionDifferences.isEmpty() + } + + def "change input object and field description"() { + given: + def oldSdl = ''' + type Query { + pets(filter: PetFilter): [ID] + } + "Pet" + input PetFilter { + age: Int + } + ''' + def newSdl = ''' + type Query { + pets(filter: PetFilter): [ID] + } + "Only pets matching the filter will be returned" + input PetFilter { + "The age in years" + age: Int + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.inputObjectDifferences.isEmpty() + } + + def "change enum type and value description"() { + given: + def oldSdl = ''' + type Query { + pet(kind: PetKind): ID + } + enum PetKind { + "doggo" + DOG, + CAT, + } + ''' + def newSdl = ''' + type Query { + pet(kind: PetKind): ID + } + "The kind of pet" + enum PetKind { + DOG, + CAT, + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.enumDifferences.isEmpty() + } + + def "change scalar description"() { + given: + def oldSdl = ''' + scalar Age + type Query { + pet(age: Age): ID + } + ''' + def newSdl = ''' + "Represents age in years" + scalar Age + type Query { + pet(age: Age): ID + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.scalarDifferences.isEmpty() + } + + def "change directive description"() { + given: + def oldSdl = ''' + directive @cat on FIELD_DEFINITION + type Query { + pet: String @cat + } + ''' + def newSdl = ''' + "A cat or something" + directive @cat on FIELD_DEFINITION + type Query { + pet: String @cat + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.directiveDifferences.isEmpty() + } + + def "traversal order puts field changes before arguments"() { + def objectOld = new Vertex(SchemaGraph.OBJECT, "target-1") + objectOld.add("name", "Obey") + def objectNew = new Vertex(SchemaGraph.OBJECT, "target-1") + objectNew.add("name", "Ob") + def changeObjectVertex = EditOperation.changeVertex( + "Change object", + objectOld, + objectNew, + ) + + def newField = new Vertex(SchemaGraph.FIELD, "target-1") + newField.add("name", "fried") + def insertNewFieldVertex = EditOperation.insertVertex( + "Insert new field", + Vertex.newIsolatedNode("source-isolated-Field-1"), + newField, + ) + + def newArgument = new Vertex(SchemaGraph.ARGUMENT, "target-1") + newArgument.add("name", "alone") + def insertNewArgumentVertex = EditOperation.insertVertex( + "Insert argument", + Vertex.newIsolatedNode("source-isolated-Argument-1"), + newArgument, + ) + + def insertNewFieldEdge = EditOperation.insertEdge( + "Insert Object -> Field Edge", + new Edge(objectNew, newField), + ) + + def insertNewArgumentEdge = EditOperation.insertEdge( + "Insert Field -> Argument Edge", + new Edge(newField, newArgument), + ) + + when: + def result = EditOperationAnalyzer.getTraversalOrder([ + insertNewArgumentVertex, + insertNewFieldEdge, + insertNewArgumentEdge, + changeObjectVertex, + insertNewFieldVertex, + ]) + + then: + result == [ + changeObjectVertex, + insertNewFieldVertex, + insertNewArgumentVertex, + insertNewFieldEdge, + insertNewArgumentEdge, + ] + } + + def "less fields in the renamed object"() { + given: + def oldSdl = ''' + type Query { + user(id: ID!): User + } + type User { + id: String + name: String + account: String + email: Boolean + age: Int + } + ''' + def newSdl = ''' + type Query { + account(id: ID!): Account + } + type Account { + id: String + name: String + yearsOld: Int + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["User"] instanceof ObjectModification + def userModification = changes.objectDifferences["User"] as ObjectModification + userModification.isNameChanged() + userModification.oldName == "User" + userModification.newName == "Account" + + def deletions = userModification.getDetails(ObjectFieldDeletion) + deletions.size() == 2 + deletions.collect { it.name }.toSet() == ["account", "email"] as Set + + def rename = userModification.getDetails(ObjectFieldRename) + rename.size() == 1 + rename[0].oldName == "age" + rename[0].newName == "yearsOld" + } + + def "two possible mappings for object rename where one has less fields"() { + given: + def oldSdl = ''' + type Query { + user(id: ID!): User + } + type User { + id: String + name: String + account: String + email: String + age: Int + } + ''' + def newSdl = ''' + type Query { + account(id: ID!): Account + } + type Account { + yearsOld: Int + } + type Profile { + id: String + name: String + account: String + email: String + age: Int + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["Account"] instanceof ObjectAddition + + changes.objectDifferences["User"] instanceof ObjectModification + def userModification = changes.objectDifferences["User"] as ObjectModification + userModification.isNameChanged() + userModification.oldName == "User" + userModification.newName == "Profile" + + userModification.details.isEmpty() + } + + def "deleted field with fixed parent binding can map to isolated node"() { + given: + def oldSdl = ''' + type Query { + notifications: NotificationQuery + } + type NotificationQuery { + notificationFeed( + feedFilter: NotificationFeedFilter + first: Int = 25 + after: String + ): NotificationGroupedConnection! + unseenNotificationCount(workspaceId: String, product: String): Int! + } + input NotificationFeedFilter { + workspaceId: String + productFilter: String + groupId: String + } + type NotificationItem { + notificationId: ID! + workspaceId: String + } + type NotificationGroupedItem { + groupId: ID! + groupSize: Int! + headNotification: NotificationItem! + childItems(first: Int, after: String): [NotificationItem!] + } + type NotificationGroupedConnection { + nodes: [NotificationGroupedItem!]! + } + ''' + def newSdl = ''' + type Query { + notifications: NotificationQuery + } + type NotificationQuery { + notificationFeed( + filter: NotificationFilter + first: Int = 25 + after: String + ): NotificationFeedConnection! + notificationGroup( + groupId: String! + filter: NotificationFilter + first: Int = 25 + after: String + ): NotificationGroupConnection! + unseenNotificationCount(workspaceId: String, product: String): Int! + } + input NotificationFilter { + workspaceId: String + productFilter: String + } + type NotificationEntityModel{ + objectId: String! + containerId: String + workspaceId: String + cloudId: String + } + type NotificationItem { + notificationId: ID! + entityModel: NotificationEntityModel + workspaceId: String + } + type NotificationHeadItem { + groupId: ID! + groupSize: Int! + readStates: [String]! + additionalTypes: [String!]! + headNotification: NotificationItem! + endCursor: String + } + type NotificationFeedConnection { + nodes: [NotificationHeadItem!]! + } + type NotificationGroupConnection { + nodes: [NotificationItem!]! + } + ''' + + when: + def changes = calcDiff(oldSdl, newSdl) + + then: + changes.objectDifferences["NotificationGroupedItem"] === changes.objectDifferences["NotificationHeadItem"] + changes.objectDifferences["NotificationGroupedConnection"] === changes.objectDifferences["NotificationFeedConnection"] + changes.objectDifferences["NotificationGroupedItem"] instanceof ObjectModification + changes.objectDifferences["NotificationGroupedConnection"] instanceof ObjectModification + changes.objectDifferences["NotificationEntityModel"] instanceof ObjectAddition + changes.objectDifferences["NotificationGroupConnection"] instanceof ObjectAddition + changes.objectDifferences["NotificationItem"] instanceof ObjectModification + changes.objectDifferences["NotificationQuery"] instanceof ObjectModification + + changes.inputObjectDifferences["NotificationFeedFilter"] === changes.inputObjectDifferences["NotificationFilter"] + changes.inputObjectDifferences["NotificationFeedFilter"] instanceof InputObjectModification + + def notificationFeedFilterChange = changes.inputObjectDifferences["NotificationFeedFilter"] as InputObjectModification + notificationFeedFilterChange.details.size() == 1 + notificationFeedFilterChange.details[0] instanceof InputObjectFieldDeletion + def groupIdInputObjectFieldDeletion = notificationFeedFilterChange.details[0] as InputObjectFieldDeletion + groupIdInputObjectFieldDeletion.name == "groupId" + } + + EditOperationAnalysisResult calcDiff( + String oldSdl, + String newSdl + ) { + def oldSchema = TestUtil.schema(oldSdl) + def newSchema = TestUtil.schema(newSdl) + def changes = new SchemaDiffing().diffAndAnalyze(oldSchema, newSchema) + return changes + } +} diff --git a/src/test/groovy/graphql/schema/fetching/ConfusedPojo.java b/src/test/groovy/graphql/schema/fetching/ConfusedPojo.java new file mode 100644 index 0000000000..aa0bc174c6 --- /dev/null +++ b/src/test/groovy/graphql/schema/fetching/ConfusedPojo.java @@ -0,0 +1,28 @@ +package graphql.schema.fetching; + +public class ConfusedPojo { + + public String getRecordLike() { + return "getRecordLike"; + } + + public String recordLike() { + return "recordLike"; + } + + public String gettingConfused() { + return "gettingConfused"; + } + + public String getTingConfused() { + return "getTingConfused"; + } + + public boolean issues() { + return true; + } + + public boolean isSues() { + return false; + } +} diff --git a/src/test/groovy/graphql/schema/fetching/LambdaFetchingSupportTest.groovy b/src/test/groovy/graphql/schema/fetching/LambdaFetchingSupportTest.groovy new file mode 100644 index 0000000000..9ad4df39ef --- /dev/null +++ b/src/test/groovy/graphql/schema/fetching/LambdaFetchingSupportTest.groovy @@ -0,0 +1,199 @@ +package graphql.schema.fetching + +import graphql.Scalars +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.PropertyDataFetcher +import graphql.util.javac.DynamicJavacSupport +import spock.lang.IgnoreIf +import spock.lang.Specification + +class LambdaFetchingSupportTest extends Specification { + + def "can proxy Pojo methods"() { + + def pojo = new Pojo("Brad", 42) + when: + def getName = LambdaFetchingSupport.mkCallFunction(Pojo.class, "getName", String.class) + def getAge = LambdaFetchingSupport.mkCallFunction(Pojo.class, "getAge", Integer.TYPE) + + then: + getName.apply(pojo) == "Brad" + getAge.apply(pojo) == 42 + } + + def "get make getters based on property names"() { + def pojo = new Pojo("Brad", 42) + when: + def getter = LambdaFetchingSupport.createGetter(Pojo.class, "name") + then: + getter.isPresent() + getter.get().apply(pojo) == "Brad" + + when: + getter = LambdaFetchingSupport.createGetter(Pojo.class, "age") + then: + getter.isPresent() + getter.get().apply(pojo) == 42 + + } + + def "get make getters based on record like names"() { + def pojo = new Pojo("Brad", 42) + when: + def getter = LambdaFetchingSupport.createGetter(Pojo.class, "recordLike") + then: + getter.isPresent() + getter.get().apply(pojo) == "recordLike" + + // + // record like getters will be found first - this is new behavior but more sensible behavior + def confusedPojo = new ConfusedPojo() + when: + getter = LambdaFetchingSupport.createGetter(ConfusedPojo.class, "recordLike") + then: + getter.isPresent() + getter.get().apply(confusedPojo) == "recordLike" + + // weird arse getter methods like `issues` versus `isSues` + when: + getter = LambdaFetchingSupport.createGetter(ConfusedPojo.class, "gettingConfused") + then: + getter.isPresent() + getter.get().apply(confusedPojo) == "gettingConfused" + + when: + getter = LambdaFetchingSupport.createGetter(ConfusedPojo.class, "tingConfused") + then: + getter.isPresent() + getter.get().apply(confusedPojo) == "getTingConfused" + + // weird arse getter methods like `issues` versus `isSues` + when: + getter = LambdaFetchingSupport.createGetter(ConfusedPojo.class, "issues") + then: + getter.isPresent() + getter.get().apply(confusedPojo) == true + + when: + getter = LambdaFetchingSupport.createGetter(ConfusedPojo.class, "sues") + then: + getter.isPresent() + getter.get().apply(confusedPojo) == false + + } + + def "will handle missing ones"() { + + when: + def getter = LambdaFetchingSupport.createGetter(Pojo.class, "nameX") + then: + !getter.isPresent() + } + + def "will handle weird ones"() { + + def pojo = new Pojo("Brad", 42) + + when: + def getter = LambdaFetchingSupport.createGetter(Pojo.class, "get") + then: + getter.isPresent() + getter.get().apply(pojo) == "get" + + when: + getter = LambdaFetchingSupport.createGetter(Pojo.class, "is") + then: + getter.isPresent() + getter.get().apply(pojo) == "is" + } + + def "can handle boolean setters - is by preference"() { + + def pojo = new Pojo("Brad", 42) + when: + def getter = LambdaFetchingSupport.createGetter(Pojo.class, "interesting") + then: + getter.isPresent() + getter.get().apply(pojo) == true + + when: + getter = LambdaFetchingSupport.createGetter(Pojo.class, "alone") + then: + getter.isPresent() + getter.get().apply(pojo) == true + + when: + getter = LambdaFetchingSupport.createGetter(Pojo.class, "booleanAndNullish") + then: + getter.isPresent() + getter.get().apply(pojo) == null + } + + def "will ignore non public methods"() { + + when: + def getter = LambdaFetchingSupport.createGetter(Pojo.class, "protectedLevelMethod") + then: + !getter.isPresent() + + when: + getter = LambdaFetchingSupport.createGetter(Pojo.class, "privateLevelMethod") + then: + !getter.isPresent() + + when: + getter = LambdaFetchingSupport.createGetter(Pojo.class, "packageLevelMethod") + then: + !getter.isPresent() + } + + GraphQLFieldDefinition fld(String fldName) { + return GraphQLFieldDefinition.newFieldDefinition().name(fldName).type(Scalars.GraphQLString).build() + } + + @IgnoreIf({ System.getProperty("java.version").split('\\.')[0] as Integer > 11 }) + def "different class loaders induce certain behaviours"() { + String sourceCode = ''' + package com.dynamic; + public class TestClass { + public String hello() { + return "world"; + } + } + ''' + + def customClass = new DynamicJavacSupport(null).compile("com.dynamic.TestClass", sourceCode) + def targetObject = customClass.getDeclaredConstructor().newInstance() + + // show that the graphql-java classes cant access this custom loaded class + when: + LambdaFetchingSupport.class.getClassLoader().loadClass("com.dynamic.TestClass") + then: + thrown(ClassNotFoundException) + + // show that reflection works + when: + def helloMethod = targetObject.getClass().getMethod("hello") + def reflectedValue = helloMethod.invoke(targetObject) + then: + reflectedValue == "world" + + // without MethodHandles.privateLookupIn this will fail crossing class loaders in Java 8 + // if we change to privateLookupIn - then this will start working and this test will need to be changed + when: + def getter = LambdaFetchingSupport.createGetter(customClass, "hello") + then: + + // with Java 9+ we can get access to methods across class loaders + getter.isPresent() + def value = getter.get().apply(targetObject) + value == "world" + + // show that a DF can be used + when: + def ageDF = PropertyDataFetcher.fetching("hello") + value = ageDF.get(fld("hello"), targetObject, { -> null }) + then: + value == "world" + } +} diff --git a/src/test/groovy/graphql/schema/fetching/Pojo.java b/src/test/groovy/graphql/schema/fetching/Pojo.java new file mode 100644 index 0000000000..dac6ce914b --- /dev/null +++ b/src/test/groovy/graphql/schema/fetching/Pojo.java @@ -0,0 +1,72 @@ +package graphql.schema.fetching; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +public class Pojo { + final String name; + final int age; + + public Pojo(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Integer getHeight() { + return null; + } + + public List getOtherNames() { + return ImmutableList.of("A", "B"); + } + + protected String protectedLevelMethod() { + return "protectedLevelMethod"; + } + + private String privateLevelMethod() { + return "privateLevelMethod"; + } + + String packageLevelMethod() { + return "packageLevelMethod"; + } + + public boolean getInteresting() { + return false; + } + + public boolean isInteresting() { + return true; + } + + public Boolean getAlone() { + return true; + } + + public Boolean getBooleanAndNullish() { + return null; + } + + public String get() { + return "get"; + } + + public String is() { + return "is"; + } + + public String recordLike() { + return "recordLike"; + } + +} \ No newline at end of file diff --git a/src/test/groovy/graphql/schema/idl/EchoingWiringFactoryTest.groovy b/src/test/groovy/graphql/schema/idl/EchoingWiringFactoryTest.groovy index 09d61dd734..b1846f2b22 100644 --- a/src/test/groovy/graphql/schema/idl/EchoingWiringFactoryTest.groovy +++ b/src/test/groovy/graphql/schema/idl/EchoingWiringFactoryTest.groovy @@ -31,8 +31,7 @@ class EchoingWiringFactoryTest extends Specification { } """ - def schema = TestUtil.schema(idl, EchoingWiringFactory.newEchoingWiring()) - def graphQL = GraphQL.newGraphQL(schema).build() + def graphQL = TestUtil.graphQL(idl, EchoingWiringFactory.newEchoingWiring()).build() when: def result = graphQL.execute(""" diff --git a/src/test/groovy/graphql/schema/idl/ImmutableTypeDefinitionRegistryTest.groovy b/src/test/groovy/graphql/schema/idl/ImmutableTypeDefinitionRegistryTest.groovy new file mode 100644 index 0000000000..9bf440c572 --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/ImmutableTypeDefinitionRegistryTest.groovy @@ -0,0 +1,255 @@ +package graphql.schema.idl + +import graphql.language.InterfaceTypeDefinition +import graphql.language.TypeDefinition +import spock.lang.Specification + +class ImmutableTypeDefinitionRegistryTest extends Specification { + + def serializableSchema = ''' + "the schema" + schema { + query : Q + } + + "the query type" + type Q { + field( arg : String! = "default") : FieldType @deprecated(reason : "no good") + } + + interface FieldType { + f : UnionType + } + + type FieldTypeImpl implements FieldType { + f : UnionType + } + + union UnionType = Foo | Bar + + type Foo { + foo : String + } + + type Bar { + bar : String + } + + scalar MyScalar + + input InputType { + in : String + } + ''' + + def "immutable registry can be serialized and hence cacheable"() { + def registryOut = new SchemaParser().parse(serializableSchema).readOnly() + + when: + + TypeDefinitionRegistry registryIn = serialise(registryOut).readOnly() + + then: + + TypeDefinition typeIn = registryIn.getTypeOrNull(typeName) + TypeDefinition typeOut = registryOut.getTypeOrNull(typeName) + typeIn.isEqualTo(typeOut) + + where: + typeName | _ + "Q" | _ + "FieldType" | _ + "FieldTypeImpl" | _ + "UnionType" | _ + "Foo" | _ + "Bar" | _ + } + + def "immutable registry is a perfect copy of the starting registry"() { + when: + def mutableRegistry = new SchemaParser().parse(serializableSchema) + def immutableRegistry = mutableRegistry.readOnly() + + then: + + containsSameObjects(mutableRegistry.types(), immutableRegistry.types()) + + TypeDefinition typeIn = mutableRegistry.getTypeOrNull(typeName) + TypeDefinition typeOut = immutableRegistry.getTypeOrNull(typeName) + typeIn.isEqualTo(typeOut) + + where: + typeName | _ + "Q" | _ + "FieldType" | _ + "FieldTypeImpl" | _ + "UnionType" | _ + "Foo" | _ + "Bar" | _ + } + + def "extensions are also present in immutable copy"() { + def sdl = serializableSchema + """ + extend type FieldTypeImpl { + extra : String + } + + extend input InputType { + out : String + } + + extend scalar MyScalar @specifiedBy(url: "myUrl.example") + + extend union UnionType @deprecated + + extend interface FieldType @deprecated + + """ + + when: + def mutableRegistry = new SchemaParser().parse(sdl) + def immutableRegistry = mutableRegistry.readOnly() + + then: + + containsSameObjects(mutableRegistry.types(), immutableRegistry.types()) + containsSameObjects(mutableRegistry.objectTypeExtensions(), immutableRegistry.objectTypeExtensions()) + containsSameObjects(mutableRegistry.inputObjectTypeExtensions(), immutableRegistry.inputObjectTypeExtensions()) + containsSameObjects(mutableRegistry.interfaceTypeExtensions(), immutableRegistry.interfaceTypeExtensions()) + containsSameObjects(mutableRegistry.unionTypeExtensions(), immutableRegistry.unionTypeExtensions()) + containsSameObjects(mutableRegistry.scalarTypeExtensions(), immutableRegistry.scalarTypeExtensions()) + + } + + def "readonly is aware if itself"() { + when: + def mutableRegistry = new SchemaParser().parse(serializableSchema) + def immutableRegistry1 = mutableRegistry.readOnly() + + then: + mutableRegistry !== immutableRegistry1 + + when: + def immutableRegistry2 = immutableRegistry1.readOnly() + + then: + immutableRegistry2 === immutableRegistry1 + + + } + + def "is in read only mode"() { + when: + def mutableRegistry = new SchemaParser().parse(serializableSchema) + def immutableRegistry = mutableRegistry.readOnly() + + immutableRegistry.merge(mutableRegistry) + + then: + thrown(UnsupportedOperationException) + + when: + immutableRegistry.addAll([]) + then: + thrown(UnsupportedOperationException) + + + def someDef = mutableRegistry.getTypes(TypeDefinition.class)[0] + + when: + immutableRegistry.add(someDef) + then: + thrown(UnsupportedOperationException) + + when: + immutableRegistry.remove(someDef) + then: + thrown(UnsupportedOperationException) + + when: + immutableRegistry.remove("key", someDef) + then: + thrown(UnsupportedOperationException) + } + + def "get implementations of"() { + def sdl = serializableSchema + """ + interface IType { + i : String + } + + interface DerivedIType implements IType { + i : String + d : String + } + + """ + for (int i = 0; i < 10; i++) { + sdl += """ + type OT$i implements IType { + i : String + } + """ + + } + for (int i = 0; i < 5; i++) { + sdl += """ + type DT$i implements DerivedIType { + i : String + d : String + } + """ + + } + def immutableRegistry = new SchemaParser().parse(sdl).readOnly() + + Map interfaces = immutableRegistry.getTypesMap(InterfaceTypeDefinition.class) + + when: + def iFieldType = interfaces.get("IType") + def allImplementationsOf = immutableRegistry.getAllImplementationsOf(iFieldType) + def implementationsOf = immutableRegistry.getImplementationsOf(iFieldType) + + then: + allImplementationsOf.size() == 11 + allImplementationsOf.collect({ it.getName() }).every { it.startsWith("OT") || it == "DerivedIType" } + + implementationsOf.size() == 10 + implementationsOf.collect({ it.getName() }).every { it.startsWith("OT") } + + when: + def iDerivedType = interfaces.get("DerivedIType") + allImplementationsOf = immutableRegistry.getAllImplementationsOf(iDerivedType) + implementationsOf = immutableRegistry.getImplementationsOf(iDerivedType) + + then: + allImplementationsOf.size() == 5 + allImplementationsOf.collect({ it.getName() }).every { it.startsWith("DT") } + + implementationsOf.size() == 5 + implementationsOf.collect({ it.getName() }).every { it.startsWith("DT") } + + } + + void containsSameObjects(Map leftMap, Map rightMap) { + assert leftMap.size() > 0, "The map must have some entries" + assert leftMap.size() == rightMap.size(), "The maps are not the same size" + for (String leftKey : leftMap.keySet()) { + def leftVal = leftMap.get(leftKey) + def rightVal = rightMap.get(leftKey) + assert leftVal === rightVal, "$leftKey : $leftVal dont not strictly equal $rightVal" + } + } + + static TypeDefinitionRegistry serialise(TypeDefinitionRegistry registryOut) { + ByteArrayOutputStream baOS = new ByteArrayOutputStream() + ObjectOutputStream oos = new ObjectOutputStream(baOS) + + oos.writeObject(registryOut) + + ByteArrayInputStream baIS = new ByteArrayInputStream(baOS.toByteArray()) + ObjectInputStream ois = new ObjectInputStream(baIS) + + ois.readObject() as TypeDefinitionRegistry + } +} diff --git a/src/test/groovy/graphql/schema/idl/MockedWiringFactory.groovy b/src/test/groovy/graphql/schema/idl/MockedWiringFactory.groovy deleted file mode 100644 index 78c5705e36..0000000000 --- a/src/test/groovy/graphql/schema/idl/MockedWiringFactory.groovy +++ /dev/null @@ -1,50 +0,0 @@ -package graphql.schema.idl - -import graphql.TypeResolutionEnvironment -import graphql.schema.DataFetcher -import graphql.schema.GraphQLObjectType -import graphql.schema.PropertyDataFetcher -import graphql.schema.TypeResolver - -class MockedWiringFactory implements WiringFactory { - - @Override - boolean providesTypeResolver(InterfaceWiringEnvironment environment) { - return true - } - - @Override - TypeResolver getTypeResolver(InterfaceWiringEnvironment environment) { - new TypeResolver() { - @Override - GraphQLObjectType getType(TypeResolutionEnvironment env) { - throw new UnsupportedOperationException("Not implemented") - } - } - } - - @Override - boolean providesTypeResolver(UnionWiringEnvironment environment) { - return true - } - - @Override - TypeResolver getTypeResolver(UnionWiringEnvironment environment) { - new TypeResolver() { - @Override - GraphQLObjectType getType(TypeResolutionEnvironment env) { - throw new UnsupportedOperationException("Not implemented") - } - } - } - - @Override - boolean providesDataFetcher(FieldWiringEnvironment environment) { - return true - } - - @Override - DataFetcher getDataFetcher(FieldWiringEnvironment environment) { - return new PropertyDataFetcher(environment.getFieldDefinition().getName()) - } -} diff --git a/src/test/groovy/graphql/schema/idl/MockedWiringFactoryTest.groovy b/src/test/groovy/graphql/schema/idl/MockedWiringFactoryTest.groovy new file mode 100644 index 0000000000..18fa630a7b --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/MockedWiringFactoryTest.groovy @@ -0,0 +1,49 @@ +package graphql.schema.idl + + +import spock.lang.Specification + +class MockedWiringFactoryTest extends Specification { + + def "mock wiring factory can be used for any schema"() { + def sdl = """ + type Query { + foo : Foo + } + + scalar SomeScalar + scalar SomeOtherScalar + + type Foo { + bar( + arg1 : SomeScalar! = 666, + arg2 : Int! = 777, + arg3 : SomeOtherScalar = { x : [{ y : 1, z : "s"}] } ) : Bar + } + + interface Bar { + baz : String + } + + type BarBar implements Bar { + baz : String + } + + type BlackSheep implements Bar { + baz : String + } + """ + + when: + def registry = new SchemaParser().parse(sdl) + def schema = new SchemaGenerator().makeExecutableSchema(registry, RuntimeWiring.MOCKED_WIRING) + + then: + schema != null + schema.getType("Query") != null + schema.getType("Foo") != null + schema.getType("Bar") != null + schema.getType("BarBar") != null + schema.getType("BlackSheep") != null + } +} diff --git a/src/test/groovy/graphql/schema/idl/RuntimeWiringTest.groovy b/src/test/groovy/graphql/schema/idl/RuntimeWiringTest.groovy index 81b2554a34..beb518ae2f 100644 --- a/src/test/groovy/graphql/schema/idl/RuntimeWiringTest.groovy +++ b/src/test/groovy/graphql/schema/idl/RuntimeWiringTest.groovy @@ -1,12 +1,17 @@ package graphql.schema.idl +import graphql.Scalars import graphql.TypeResolutionEnvironment import graphql.schema.Coercing import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLFieldsContainer import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.TypeResolver +import graphql.schema.idl.errors.StrictModeWiringException +import graphql.schema.visibility.GraphqlFieldVisibility import spock.lang.Specification import java.util.function.UnaryOperator @@ -59,22 +64,22 @@ class RuntimeWiringTest extends Specification { def "basic call structure"() { def wiring = RuntimeWiring.newRuntimeWiring() .type("Query", { type -> - type - .dataFetcher("fieldX", new NamedDF("fieldX")) - .dataFetcher("fieldY", new NamedDF("fieldY")) - .dataFetcher("fieldZ", new NamedDF("fieldZ")) - .defaultDataFetcher(new NamedDF("defaultQueryDF")) - .typeResolver(new NamedTR("typeResolver4Query")) - } as UnaryOperator) + type + .dataFetcher("fieldX", new NamedDF("fieldX")) + .dataFetcher("fieldY", new NamedDF("fieldY")) + .dataFetcher("fieldZ", new NamedDF("fieldZ")) + .defaultDataFetcher(new NamedDF("defaultQueryDF")) + .typeResolver(new NamedTR("typeResolver4Query")) + } as UnaryOperator) .type("Mutation", { type -> - type - .dataFetcher("fieldX", new NamedDF("mfieldX")) - .dataFetcher("fieldY", new NamedDF("mfieldY")) - .dataFetcher("fieldZ", new NamedDF("mfieldZ")) - .defaultDataFetcher(new NamedDF("defaultMutationDF")) - .typeResolver(new NamedTR("typeResolver4Mutation")) - } as UnaryOperator) + type + .dataFetcher("fieldX", new NamedDF("mfieldX")) + .dataFetcher("fieldY", new NamedDF("mfieldY")) + .dataFetcher("fieldZ", new NamedDF("mfieldZ")) + .defaultDataFetcher(new NamedDF("defaultMutationDF")) + .typeResolver(new NamedTR("typeResolver4Mutation")) + } as UnaryOperator) .build() @@ -99,7 +104,7 @@ class RuntimeWiringTest extends Specification { } def "scalars are present"() { - def customScalar = new GraphQLScalarType("URL", "Custom", coercing) + def customScalar = GraphQLScalarType.newScalar().name("URL").description("Custom").coercing(coercing).build() def wiring = RuntimeWiring.newRuntimeWiring().scalar(customScalar).build() @@ -113,11 +118,272 @@ class RuntimeWiringTest extends Specification { wiring.getScalars().get("String").name == "String" wiring.getScalars().get("Boolean").name == "Boolean" wiring.getScalars().get("ID").name == "ID" - wiring.getScalars().get("BigDecimal").name == "BigDecimal" - wiring.getScalars().get("BigInteger").name == "BigInteger" - wiring.getScalars().get("Byte").name == "Byte" - wiring.getScalars().get("Char").name == "Char" - wiring.getScalars().get("Short").name == "Short" - wiring.getScalars().get("Long").name == "Long" + } + + def "newRuntimeWiring works and copies values"() { + when: + def customScalar1 = GraphQLScalarType.newScalar() + .name("Custom1").description("Custom 1").coercing(coercing).build() + + def oldWiring = RuntimeWiring.newRuntimeWiring() + .scalar(customScalar1) + .build() + + def customScalar2 = GraphQLScalarType.newScalar() + .name("Custom2").description("Custom 2").coercing(coercing).build() + + GraphqlFieldVisibility fieldVisibility = new GraphqlFieldVisibility() { + @Override + List getFieldDefinitions(GraphQLFieldsContainer fieldsContainer) { + return null + } + + @Override + GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsContainer, String fieldName) { + return null + } + } + + def newWiring = RuntimeWiring.newRuntimeWiring(oldWiring) + .scalar(customScalar2) + .fieldVisibility(fieldVisibility) + .build() + + then: + newWiring.scalars.entrySet().containsAll(oldWiring.scalars.entrySet()) + newWiring.scalars["Custom1"] == customScalar1 + newWiring.scalars["Custom2"] == customScalar2 + newWiring.fieldVisibility == fieldVisibility + } + + def "transform works and copies values"() { + when: + def customScalar1 = GraphQLScalarType.newScalar() + .name("Custom1").description("Custom 1").coercing(coercing).build() + + def oldWiring = RuntimeWiring.newRuntimeWiring() + .scalar(customScalar1) + .build() + + def customScalar2 = GraphQLScalarType.newScalar() + .name("Custom2").description("Custom 2").coercing(coercing).build() + + GraphqlFieldVisibility fieldVisibility = new GraphqlFieldVisibility() { + @Override + List getFieldDefinitions(GraphQLFieldsContainer fieldsContainer) { + return null + } + + @Override + GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsContainer, String fieldName) { + return null + } + } + + def newWiring = oldWiring.transform({ builder -> + builder + .scalar(customScalar2) + .fieldVisibility(fieldVisibility) + }) + + then: + newWiring.scalars.entrySet().containsAll(oldWiring.scalars.entrySet()) + newWiring.scalars["Custom1"] == customScalar1 + newWiring.scalars["Custom2"] == customScalar2 + newWiring.fieldVisibility == fieldVisibility + } + + def "strict mode, on by default, can stop certain redefinitions"() { + DataFetcher DF1 = env -> "x" + DataFetcher DF2 = env -> "x" + TypeResolver TR1 = env -> null + EnumValuesProvider EVP1 = name -> null + + when: + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("foo", DF1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("foo", DF1)) // Cannot redefine the same field's datafetcher + + then: + def e1 = thrown(StrictModeWiringException) + e1.message == "The field foo on type Foo has already been defined" + + when: + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").typeResolver(TR1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").typeResolver(TR1)) + + then: + def e2 = thrown(StrictModeWiringException) + e2.message == "The type Foo already has a type resolver defined" + + when: + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").enumValues(EVP1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").enumValues(EVP1)) + then: + def e3 = thrown(StrictModeWiringException) + e3.message == "The type Foo already has a enum provider defined" + + when: + RuntimeWiring.newRuntimeWiring() + .scalar(Scalars.GraphQLString) + then: + def e4 = thrown(StrictModeWiringException) + e4.message == "The scalar String is already defined" + + when: + TypeRuntimeWiring.newTypeWiring("Foo") + .defaultDataFetcher(DF1) + .defaultDataFetcher(DF2) + + then: + def e5 = thrown(StrictModeWiringException) + e5.message == "The type Foo has already has a default data fetcher defined" + } + + def "strict mode, on by default, permits a type to be defined more than once as long as elements are not overlapping"() { + DataFetcher DF1 = env -> "x" + DataFetcher DF2 = env -> "x" + TypeResolver TR1 = env -> null + EnumValuesProvider EVP1 = name -> null + + when: + // Permit type wiring to be defined more than once, if child DataFetchers are for distinct fields + def runtimeWiring1 = RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("foo", DF1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("bar", DF2)) + .build() + + then: + noExceptionThrown() + runtimeWiring1.getDataFetchers().get("Foo").get("foo") == DF1 + runtimeWiring1.getDataFetchers().get("Foo").get("bar") == DF2 + + when: + // Only one type wiring is allowed per type, do not allow redefinition + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").typeResolver(TR1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").typeResolver(TR1)) + + then: + def e2 = thrown(StrictModeWiringException) + e2.message == "The type Foo already has a type resolver defined" + + when: + // Only one enum values provider is allowed per type, do not allow redefinition + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").enumValues(EVP1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").enumValues(EVP1)) + + then: + def e3 = thrown(StrictModeWiringException) + e3.message == "The type Foo already has a enum provider defined" + + when: + // Only one scalar wiring is allowed per scalar + RuntimeWiring.newRuntimeWiring() + .scalar(Scalars.GraphQLString) + then: + def e4 = thrown(StrictModeWiringException) + e4.message == "The scalar String is already defined" + + when: + // Only one default data fetcher is allowed, do not allow redefinition + TypeRuntimeWiring.newTypeWiring("Foo") + .defaultDataFetcher(DF1) + .defaultDataFetcher(DF2) + + then: + def e5 = thrown(StrictModeWiringException) + e5.message == "The type Foo has already has a default data fetcher defined" + } + + def "strict mode, if set to off, won't stop certain redefinitions"() { + DataFetcher DF1 = env -> "x" + DataFetcher DF2 = env -> "x" + TypeResolver TR1 = env -> null + EnumValuesProvider EVP1 = name -> null + + when: + def runtimeWiring1 = RuntimeWiring.newRuntimeWiring() + .strictMode(false) + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("foo", DF1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("foo", DF2)) + .build() + + then: + noExceptionThrown() + runtimeWiring1.getDataFetchers().get("Foo").get("foo") == DF2 + + when: + def runtimeWiring2 = RuntimeWiring.newRuntimeWiring() + .strictMode(false) + .type(TypeRuntimeWiring.newTypeWiring("Foo").typeResolver(TR1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").typeResolver(TR1)) + .build() + + then: + noExceptionThrown() + runtimeWiring2.typeResolvers.get("Foo") == TR1 + + when: + def runtimeWiring3 = RuntimeWiring.newRuntimeWiring() + .strictMode(false) + .type(TypeRuntimeWiring.newTypeWiring("Foo").enumValues(EVP1)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").enumValues(EVP1)) + .build() + + then: + noExceptionThrown() + runtimeWiring3.getEnumValuesProviders().get("Foo") == EVP1 + + when: + def runtimeWiring4 = RuntimeWiring.newRuntimeWiring() + .strictMode(false) + .scalar(Scalars.GraphQLString) + .build() + + then: + noExceptionThrown() + runtimeWiring4.scalars.get("String") == Scalars.GraphQLString + + when: + def typeRuntimeWiring = TypeRuntimeWiring.newTypeWiring("Foo") + .strictMode(false) + .defaultDataFetcher(DF1) + .defaultDataFetcher(DF2) + .build() + + then: + noExceptionThrown() + typeRuntimeWiring.defaultDataFetcher == DF2 + } + + def "when strict mode on, do not allow default data fetcher redefinition"() { + DataFetcher DF1 = env -> "w" + DataFetcher DEFAULT_DF = env -> "x" + DataFetcher DEFAULT_DF2 = env -> "y" + + // Having a datafetcher and a default for the type is ok + when: + def runtimeWiring1 = RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").defaultDataFetcher(DEFAULT_DF)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").dataFetcher("foo", DF1)) + .build() + + then: + runtimeWiring1.getDefaultDataFetcherForType("Foo") == DEFAULT_DF + + // Do not permit redefinition of the default datafetcher + when: + RuntimeWiring.newRuntimeWiring() + .type(TypeRuntimeWiring.newTypeWiring("Foo").defaultDataFetcher(DEFAULT_DF)) + .type(TypeRuntimeWiring.newTypeWiring("Foo").defaultDataFetcher(DEFAULT_DF2)) + .build() + + then: + def error = thrown(StrictModeWiringException) + error.message == "The type Foo already has a default data fetcher defined" } } diff --git a/src/test/groovy/graphql/schema/idl/SchemaExtensionsCheckerTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaExtensionsCheckerTest.groovy new file mode 100644 index 0000000000..60c6386b7c --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/SchemaExtensionsCheckerTest.groovy @@ -0,0 +1,171 @@ +package graphql.schema.idl + +import graphql.schema.idl.errors.MissingTypeError +import graphql.schema.idl.errors.OperationRedefinitionError +import graphql.schema.idl.errors.OperationTypesMustBeObjects +import graphql.schema.idl.errors.QueryOperationMissingError +import graphql.schema.idl.errors.SchemaProblem +import spock.lang.Specification + +class SchemaExtensionsCheckerTest extends Specification { + + static TypeDefinitionRegistry typeRegistry(String sdl) { + def registry = new SchemaParser().parse(sdl) + registry + } + + def "schema def missing query operation and query type"() { + def sdl = ''' + type Foo { f : String } + ''' + + when: + def errors = [] + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry(sdl)) + + then: + !errors.isEmpty() + errors[0] instanceof QueryOperationMissingError + } + + def "schema def missing query operation and query type but has extensions but without query op"() { + def sdl = ''' + type Foo { f : String } + + extend schema { + mutation : Foo + } + ''' + + when: + def errors = [] + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry(sdl)) + + then: + !errors.isEmpty() + errors[0] instanceof QueryOperationMissingError + } + + def "schema def missing query operation and has query type"() { + def sdl = ''' + type Query { f : String } + ''' + + when: + def errors = [] + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry(sdl)) + + then: + errors.isEmpty() + } + + def "schema def missing query operation and query type but has extensions with query op"() { + def sdl = ''' + type Foo { f : String } + + extend schema { + query : Foo + } + ''' + + when: + def errors = [] + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry(sdl)) + + then: + errors.isEmpty() + } + + def "schema def present with query operation but extension redefines its"() { + def sdl = ''' + type Foo { f : String } + + schema { + query : Foo + } + + extend schema { + query : Foo + } + ''' + + when: + typeRegistry(sdl) + + then: + //parsing picks this up but via SchemaExtensionsChecker + def schemaProblem = thrown(SchemaProblem) + schemaProblem.errors[0] instanceof OperationRedefinitionError + } + + + def "operation is not a defined type"() { + def sdl = ''' + type Foo { f : String } + + schema { + query : Bar + } + ''' + + when: + def errors = [] + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry(sdl)) + + then: + !errors.isEmpty() + errors[0] instanceof MissingTypeError + } + + def "operation is not an object type"() { + def sdl = ''' + input Foo { f : String } + + schema { + query : Foo + } + ''' + + when: + def errors = [] + SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry(sdl)) + + then: + !errors.isEmpty() + errors[0] instanceof OperationTypesMustBeObjects + } + + def "can gather all the different types"() { + def sdl = ''' + type Foo { f : String } + + type Mutate { f : String } + + type Subscribe { f : String } + + schema { + query : Foo + } + + extend schema { + mutation : Mutate + } + + extend schema { + subscription : Subscribe + } + ''' + + when: + def errors = [] + def typeRegistry = typeRegistry(sdl) + def operationDefs = SchemaExtensionsChecker.checkSchemaInvariants(errors, typeRegistry) + + then: + errors.isEmpty() + operationDefs.size() == 3 + operationDefs.collect { opTypeDef -> opTypeDef.getName() }.contains("query") + operationDefs.collect { opTypeDef -> opTypeDef.getName() }.contains("mutation") + operationDefs.collect { opTypeDef -> opTypeDef.getName() }.contains("subscription") + } +} diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorAppliedDirectiveHelperTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorAppliedDirectiveHelperTest.groovy new file mode 100644 index 0000000000..f42cc49058 --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorAppliedDirectiveHelperTest.groovy @@ -0,0 +1,132 @@ +package graphql.schema.idl + + +import graphql.TestUtil +import graphql.schema.GraphQLInputType +import spock.lang.Specification + +class SchemaGeneratorAppliedDirectiveHelperTest extends Specification { + + def sdl = """ + directive @foo(arg1 : String! = "fooArg1Value", arg2 : String) on + SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | + INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + directive @bar(arg1 : String, arg2 : String) on + SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | + INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + directive @complex(complexArg1 : ComplexInput! = { name : "Boris", address : { number : 10 street : "Downing St", town : "London" }}) on + SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | + INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + + type Query { + field : Bar @foo(arg2 : "arg2Value") @bar(arg1 : "barArg1Value" arg2 : "arg2Value") + complexField : Bar @complex + } + + type Bar @foo(arg1 : "BarTypeValue" arg2 : "arg2Value") { + bar : String + } + + input ComplexInput { + name : String + address : Address + } + + input Address { + number : Int + street : String + town : String + } + + """ + + def "can capture applied directives and legacy directives"() { + + when: + def schema = TestUtil.schema(sdl) + def field = schema.getObjectType("Query").getField("field") + def complexField = schema.getObjectType("Query").getField("complexField") + def barType = schema.getObjectType("Bar") + + then: + + schema.getDirectives().collect {it.name}.sort() == [ + "bar", + "complex", + "defer", + "deprecated", + "experimental_disableErrorPropagation", + "foo", + "include", + "oneOf", + "skip", + "specifiedBy", + ] + + field.directives.collect { it.name }.sort() == ["bar", "foo"] + field.appliedDirectives.collect { it.name }.sort() == ["bar", "foo"] + + barType.directives.collect { it.name }.sort() == ["foo"] + barType.appliedDirectives.collect { it.name }.sort() == ["foo"] + + def fooAppliedDirective = field.getAppliedDirective("foo") + fooAppliedDirective.arguments.collect { it.name }.sort() == ["arg1", "arg2"] + fooAppliedDirective.arguments.collect { it.getValue() }.sort() == ["arg2Value", "fooArg1Value"] + + def fooAppliedDirectiveOnType = barType.getAppliedDirective("foo") + fooAppliedDirectiveOnType.arguments.collect { it.name }.sort() == ["arg1", "arg2"] + fooAppliedDirectiveOnType.arguments.collect { it.getValue() }.sort() == ["BarTypeValue", "arg2Value",] + + def complexAppliedDirective = complexField.getAppliedDirective("complex") + GraphQLInputType complexInputType = schema.getTypeAs("ComplexInput") + complexAppliedDirective.arguments.collect { it.name }.sort() == ["complexArg1"] + complexAppliedDirective.arguments.collect { it.getValue() }.sort() == [ + [name:"Boris", address:[number:10, street:"Downing St", town:"London"]] + ] + } + + def "can capture ONLY applied directives"() { + + when: + def options = SchemaGenerator.Options.defaultOptions() + then: + !options.isUseAppliedDirectivesOnly() // default is capture both + + + when: + options = SchemaGenerator.Options.defaultOptions().useAppliedDirectivesOnly(true) + + def schema = TestUtil.schema(options, sdl, RuntimeWiring.MOCKED_WIRING) + def field = schema.getObjectType("Query").getField("field") + def barType = schema.getObjectType("Bar") + + then: + + schema.getDirectives().collect {it.name}.sort() == [ + "bar", + "complex", + "defer", + "deprecated", + "experimental_disableErrorPropagation", + "foo", + "include", + "oneOf", + "skip", + "specifiedBy", + ] + + field.directives.collect { it.name }.sort() == [] + field.appliedDirectives.collect { it.name }.sort() == ["bar", "foo"] + + barType.directives.collect { it.name }.sort() == [] + barType.appliedDirectives.collect { it.name }.sort() == ["foo"] + + + def fooAppliedDirective = field.getAppliedDirective("foo") + fooAppliedDirective.arguments.collect { it.name }.sort() == ["arg1", "arg2"] + fooAppliedDirective.arguments.collect { it.value }.sort() == ["arg2Value", "fooArg1Value"] + } + +} diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorDirectiveHelperTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorDirectiveHelperTest.groovy index b60e35b19e..0570df2770 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorDirectiveHelperTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorDirectiveHelperTest.groovy @@ -2,20 +2,27 @@ package graphql.schema.idl import graphql.ExecutionInput import graphql.GraphQL -import graphql.language.ObjectTypeDefinition +import graphql.GraphQLContext +import graphql.execution.ValuesResolver import graphql.schema.Coercing import graphql.schema.CoercingParseLiteralException import graphql.schema.CoercingParseValueException import graphql.schema.CoercingSerializeException import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironment +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLAppliedDirective import graphql.schema.GraphQLArgument -import graphql.schema.GraphQLDirective +import graphql.schema.GraphQLCodeRegistry +import graphql.schema.GraphQLDirectiveContainer import graphql.schema.GraphQLEnumType import graphql.schema.GraphQLEnumValueDefinition import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLFieldsContainer import graphql.schema.GraphQLInputObjectField import graphql.schema.GraphQLInputObjectType import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLNamedType import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLUnionType @@ -23,13 +30,14 @@ import readme.DirectivesExamples import spock.lang.Specification import java.time.LocalDateTime +import java.time.format.DateTimeFormatter import static graphql.TestUtil.schema import static graphql.schema.DataFetcherFactories.wrapDataFetcher class SchemaGeneratorDirectiveHelperTest extends Specification { - def customScalarType = new GraphQLScalarType("ScalarType", "", new Coercing() { + def customScalarType = GraphQLScalarType.newScalar().name("ScalarType").coercing(new Coercing() { @Override Object serialize(Object input) throws CoercingSerializeException { return input @@ -45,11 +53,28 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { return input } }) + .build() + + static def assertCallHierarchy(elementHierarchy, astHierarchy, String name, List l) { + assert elementHierarchy[name] == l, "unexpected elementHierarchy" + assert astHierarchy[name] == l, "unexpected astHierarchy" + true + } def "will trace down into each directive callback"() { - def spec = ''' + def sdl = ''' + directive @fieldDirective(target: String) on FIELD_DEFINITION + directive @argumentDirective(target: String) on ARGUMENT_DEFINITION + directive @objectDirective(target: String) on OBJECT + directive @interfaceDirective(target: String) on INTERFACE + directive @unionDirective(target: String) on UNION + directive @enumDirective(target: String) on ENUM + directive @enumValueDirective(target: String) on ENUM_VALUE + directive @inputDirective(target: String) on INPUT_OBJECT + directive @inputFieldDirective(target: String) on INPUT_FIELD_DEFINITION + directive @scalarDirective(target: String) on SCALAR type Query { f : ObjectType s : ScalarType @@ -64,6 +89,7 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { interface InterfaceType @interfaceDirective(target : "InterfaceType") { interfaceField1 : String @fieldDirective(target : "interfaceField1") interfaceField2 : String @fieldDirective(target : "interfaceField2") + interfaceField3(iArgument1 : String @argumentDirective(target : "iArgument1") iArgument2 : String @argumentDirective(target : "iArgument2")) : Int } type Foo { @@ -79,87 +105,109 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { input InputType @inputDirective(target : "InputType") { inputField1 : String @inputFieldDirective(target : "inputField1") inputField2 : String @inputFieldDirective(target : "inputField2") + circularInputField : IndirectType @inputFieldDirective(target : "circularInputField") } + input IndirectType { + indirectInputField1 : InputType @inputFieldDirective(target : "indirectInputField1") + } + enum EnumType @enumDirective(target:"EnumType") { enumVal1 @enumValueDirective(target : "enumVal1") enumVal2 @enumValueDirective(target : "enumVal2") } scalar ScalarType @scalarDirective(target:"ScalarType") - ''' + //`this contains the name of the element that was asked to be directive wired def targetList = [] + // this contains the names of the elements that presented as the runtime type hierarchy + Map> elementHierarchy = [:] + // this contains the names of the elements that presented as the ast bide hierarchy + Map> astHierarchy = [:] + // contains the name of the fields container + Map fieldsContainers = [:] + // contains the name of the field + Map fieldDefinitions = [:] def schemaDirectiveWiring = new SchemaDirectiveWiring() { - def assertDirectiveTarget(SchemaDirectiveWiringEnvironment environment, String name) { + def assertDirectiveTarget(SchemaDirectiveWiringEnvironment environment, String name) { + def element = environment.getElement() + targetList.add(name) - GraphQLDirective directive = environment.getDirective() - String target = directive.getArgument("target").getValue() + elementHierarchy[name] = environment.elementParentTree.toList().collect { type -> type.getName() } + astHierarchy[name] = environment.nodeParentTree.toList().collect { namedNode -> namedNode.getName() } + fieldsContainers[name] = environment.getFieldsContainer()?.getName() + fieldDefinitions[name] = environment.getFieldDefinition()?.getName() + + GraphQLAppliedDirective appliedDirective = environment.getAppliedDirective() + def arg = appliedDirective.getArgument("target") + + String target = ValuesResolver.valueToInternalValue(arg.getArgumentValue(), arg.getType(), GraphQLContext.getDefault(), Locale.getDefault()) assert name == target, " The target $target is not equal to the object name $name" - return environment.getElement() + return element } @Override GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLFieldDefinition } @Override GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLArgument } @Override GraphQLObjectType onObject(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLObjectType } @Override GraphQLInterfaceType onInterface(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLInterfaceType } @Override GraphQLUnionType onUnion(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLUnionType } @Override GraphQLEnumType onEnum(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLEnumType } @Override GraphQLEnumValueDefinition onEnumValue(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLEnumValueDefinition } @Override GraphQLScalarType onScalar(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLScalarType } @Override GraphQLInputObjectType onInputObjectType(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLInputObjectType } @Override GraphQLInputObjectField onInputObjectField(SchemaDirectiveWiringEnvironment environment) { String name = environment.getElement().getName() - return assertDirectiveTarget(environment, name) + return assertDirectiveTarget(environment, name) as GraphQLInputObjectField } } RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() @@ -178,7 +226,7 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { .build() when: - def schema = schema(spec, runtimeWiring) + def schema = schema(sdl, runtimeWiring) then: schema != null @@ -195,16 +243,66 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { targetList.contains("InputType") targetList.contains("inputField1") targetList.contains("inputField2") + targetList.contains("circularInputField") + targetList.contains("indirectInputField1") targetList.contains("EnumType") targetList.contains("enumVal1") targetList.contains("enumVal2") targetList.contains("ScalarType") + + !targetList.contains("Query") // it has no directives + + // are the element tree as expected + + assertCallHierarchy(elementHierarchy, astHierarchy, "ObjectType", ["ObjectType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "field1", ["field1", "ObjectType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "field3", null) // it has no directives but its innards do + assertCallHierarchy(elementHierarchy, astHierarchy, "argument1", ["argument1", "field3", "ObjectType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "argument2", ["argument2", "field3", "ObjectType"]) + + assertCallHierarchy(elementHierarchy, astHierarchy, "InterfaceType", ["InterfaceType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "interfaceField1", ["interfaceField1", "InterfaceType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "interfaceField3", null) // it has no directives but its innards do + assertCallHierarchy(elementHierarchy, astHierarchy, "iArgument1", ["iArgument1", "interfaceField3", "InterfaceType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "iArgument2", ["iArgument2", "interfaceField3", "InterfaceType"]) + + assertCallHierarchy(elementHierarchy, astHierarchy, "EnumType", ["EnumType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "enumVal1", ["enumVal1", "EnumType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "enumVal2", ["enumVal2", "EnumType"]) + + assertCallHierarchy(elementHierarchy, astHierarchy, "InputType", ["InputType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "inputField1", ["inputField1", "InputType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "inputField2", ["inputField2", "InputType"]) + + assertCallHierarchy(elementHierarchy, astHierarchy, "UnionType", ["UnionType"]) + assertCallHierarchy(elementHierarchy, astHierarchy, "ScalarType", ["ScalarType"]) + + assertCallHierarchy(elementHierarchy, astHierarchy, "Query", null) // it has no directives + + // + fieldDefinitions["argument1"] == "field3" + fieldsContainers["argument1"] == "ObjectType" + + fieldDefinitions["argument2"] == "field3" + fieldsContainers["argument2"] == "ObjectType" + + fieldDefinitions["field2"] == "field2" + fieldsContainers["field2"] == "ObjectType" + + fieldDefinitions["ObjectType"] == null + fieldsContainers["ObjectType"] == "ObjectType" } + def "can modify the existing behaviour"() { - def spec = ''' + def sdl = ''' + directive @uppercase on FIELD_DEFINITION + directive @lowercase on FIELD_DEFINITION + directive @mixedcase on FIELD_DEFINITION + directive @echoFieldName on FIELD_DEFINITION + directive @reverse on FIELD_DEFINITION type Query { lowerCaseValue : String @uppercase upperCaseValue : String @lowercase @@ -227,8 +325,16 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { @Override GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment directiveEnv) { GraphQLFieldDefinition field = directiveEnv.getElement() - def newFetcher = wrapDataFetcher(field.getDataFetcher(), { dfEnv, value -> - def directiveName = directiveEnv.directive.name + def container = directiveEnv.fieldsContainer + if (!container instanceof GraphQLObjectType) { + return field + } + // + // we use the non shortcut path to the data fetcher here so prove it still works + + def fetcher = directiveEnv.getCodeRegistry().getDataFetcher(container as GraphQLObjectType, field) + def newFetcher = wrapDataFetcher(fetcher, { dfEnv, value -> + def directiveName = directiveEnv.appliedDirective.name if (directiveName == "uppercase") { return String.valueOf(value).toUpperCase() } else if (directiveName == "lowercase") { @@ -239,7 +345,8 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { return String.valueOf(value).reverse() } }) - field = field.transform({ builder -> builder.dataFetcher(newFetcher) }) + def coordinates = FieldCoordinates.coordinates(directiveEnv.getFieldsContainer(), field) + directiveEnv.getCodeRegistry().dataFetcher(coordinates, newFetcher) return field } @@ -259,9 +366,8 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { def fieldName = field.getName() DataFetcher echoDF = { dfEnv -> return fieldName - } - GraphQLFieldDefinition newField = field.transform({ builder -> builder.dataFetcher(echoDF) }) - return newField + } + return env.setFieldDataFetcher(echoDF) } } @@ -273,14 +379,14 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { .directive("echoFieldName", echoFieldNameWiring) .build() - def schema = schema(spec, runtimeWiring) + def schema = schema(sdl, runtimeWiring) def graphQL = GraphQL.newGraphQL(schema).build() def input = ExecutionInput.newExecutionInput() .root( - [ - lowerCaseValue: "lowercasevalue", - upperCaseValue: "UPPERCASEVALUE", - ]) + [ + lowerCaseValue: "lowercasevalue", + upperCaseValue: "UPPERCASEVALUE", + ]) .query(""" query { lowerCaseValue @@ -294,11 +400,11 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { .build() when: - def executionResult = graphQL.execute(input) + def er = graphQL.execute(input) then: - executionResult.errors.isEmpty() - executionResult.data == [ + er.errors.isEmpty() + er.data == [ lowerCaseValue: "LOWERCASEVALUE", upperCaseValue: "uppercasevalue", echoField1 : "echoField1", @@ -310,7 +416,8 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { def "ensure the readme examples work"() { - def spec = ''' + def sdl = ''' + directive @dateFormat on FIELD_DEFINITION type Query { dateField : String @dateFormat } @@ -320,10 +427,12 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { .directive("dateFormat", new DirectivesExamples.DateFormatting()) .build() - def schema = schema(spec, runtimeWiring) + def schema = schema(sdl, runtimeWiring) def graphQL = GraphQL.newGraphQL(schema).build() def day = LocalDateTime.of(1969, 10, 8, 0, 0) + // MMM is Locale sensitive + def localizedYearFirst = DateTimeFormatter.ofPattern("YYYY, MMM dd").format(day) when: def executionInput = ExecutionInput.newExecutionInput().root([dateField: day]) .query(''' @@ -335,17 +444,18 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { ''') .build() - def executionResult = graphQL.execute(executionInput) + def er = graphQL.execute(executionInput) then: - executionResult.errors.isEmpty() - executionResult.data['default'] == '08-10-1969' - executionResult.data['usa'] == '10-08-1969' - executionResult.data['yearFirst'] == '1969, Oct 08' + er.errors.isEmpty() + er.data['default'] == '08-10-1969' + er.data['usa'] == '10-08-1969' + er.data['yearFirst'] == localizedYearFirst } def "can state-fully track wrapped elements"() { - def spec = ''' + def sdl = ''' + directive @secret on FIELD_DEFINITION | OBJECT type Query { secret : Secret nonSecret : NonSecret @@ -371,7 +481,7 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { def definitions = objectType.getFieldDefinitions() def contextMap = environment.getBuildContext() - definitions = definitions.collect { fld -> wrapField(fld, objectType.getName(), contextMap) } + definitions = definitions.collect { fld -> wrapField(environment.getElement(), fld, contextMap, environment.getCodeRegistry()) } return objectType.transform({ builder -> builder.clearFields().fields(definitions) }) } @@ -379,17 +489,18 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { @Override GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment environment) { GraphQLFieldDefinition element = environment.getElement() - def tree = environment.getNodeParentTree() - ObjectTypeDefinition objectTypeDef = tree.parentInfo.get().node - def contextMap = environment.getBuildContext() - return wrapField(element, objectTypeDef.getName(), contextMap) + def container = environment.fieldsContainer + if (! container instanceof GraphQLObjectType) { + return element + } + return wrapField(container as GraphQLObjectType, element, environment.getBuildContext(), environment.getCodeRegistry()) } - private GraphQLFieldDefinition wrapField(GraphQLFieldDefinition field, String objectTypeName, Map contextMap) { - def originalFetcher = field.getDataFetcher() + private GraphQLFieldDefinition wrapField(GraphQLObjectType parentType, GraphQLFieldDefinition field, Map contextMap, GraphQLCodeRegistry.Builder codeRegistry) { + def originalFetcher = codeRegistry.getDataFetcher(parentType, field) - String key = mkFieldKey(objectTypeName, field.getName()) + String key = mkFieldKey(parentType.getName(), field.getName()) // are we already wrapped if (contextMap.containsKey(key)) { @@ -397,14 +508,16 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { } contextMap.put(key, true) - DataFetcher wrapper = { dfEnv -> - def flag = dfEnv.getContext()['protectSecrets'] + DataFetcher wrapper = { DataFetchingEnvironment dfEnv -> + def flag = dfEnv.getGraphQlContext().get('protectSecrets') if (flag == null || flag == false) { return originalFetcher.get(dfEnv) } return null } - return field.transform({ builder -> builder.dataFetcher(wrapper) }) + def coordinates = FieldCoordinates.coordinates(parentType, field) + codeRegistry.dataFetcher(coordinates, wrapper) + return field } String mkFieldKey(String objectName, String fieldName) { @@ -416,7 +529,7 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { .directive("secret", directiveWiring) .build() - def schema = schema(spec, runtimeWiring) + def schema = schema(sdl, runtimeWiring) def graphQL = GraphQL.newGraphQL(schema).build() String query = ''' @@ -437,33 +550,447 @@ class SchemaGeneratorDirectiveHelperTest extends Specification { def executionInput = ExecutionInput.newExecutionInput() .root(root) .query(query) - .context([protectSecrets: true]) + .graphQLContext([protectSecrets: true]) .build() - def executionResult = graphQL.execute(executionInput) + def er = graphQL.execute(executionInput) then: - executionResult.errors.isEmpty() - executionResult.data['secret']['identity'] == null - executionResult.data['secret']['age'] == null - executionResult.data['nonSecret']['identity'] == "BruceWayne" - executionResult.data['nonSecret']['age'] == 42 + er.errors.isEmpty() + er.data['secret']['identity'] == null + er.data['secret']['age'] == null + er.data['nonSecret']['identity'] == "BruceWayne" + er.data['nonSecret']['age'] == 42 when: executionInput = ExecutionInput.newExecutionInput() .root(root) .query(query) - .context([protectSecrets: false]) + .graphQLContext([protectSecrets: false]) + .build() + + er = graphQL.execute(executionInput) + + then: + er.errors.isEmpty() + er.data['secret']['identity'] == "BruceWayne" + er.data['secret']['age'] == 42 + er.data['nonSecret']['identity'] == "BruceWayne" + er.data['nonSecret']['age'] == 42 + } + + def "ordering of directive wiring is locked in place"() { + def sdl = ''' + directive @generalDirective on FIELD_DEFINITION + directive @factoryDirective on FIELD_DEFINITION + directive @namedDirective1 on FIELD_DEFINITION + directive @namedDirective2 on FIELD_DEFINITION + type Query { + field : String @generalDirective @factoryDirective @namedDirective1 @namedDirective2 + } + ''' + + SchemaDirectiveWiring generalWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + def existingFetcher = env.getFieldDataFetcher() + + DataFetcher newDF = { dfEnv -> + def val = existingFetcher.get(dfEnv) + return val + ",general" + } + return env.setFieldDataFetcher(newDF) + } + } + + def factoryWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + def existingFetcher = env.getFieldDataFetcher() + + DataFetcher newDF = { dfEnv -> + def val = existingFetcher.get(dfEnv) + return val + ",factory" + } + return env.setFieldDataFetcher(newDF) + } + } + + def wiringFactory = new WiringFactory() { + @Override + boolean providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + return true + } + + @Override + SchemaDirectiveWiring getSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + return factoryWiring + } + } + + def namedWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment environment) { + GraphQLAppliedDirective directive = environment.getAppliedDirective() + DataFetcher existingFetcher = environment.getFieldDataFetcher() + + DataFetcher newDF = new DataFetcher() { + @Override + Object get(DataFetchingEnvironment dfEnv) throws Exception { + Object val = existingFetcher.get(dfEnv) + return val + "," + directive.getName() + } + } + return environment.setFieldDataFetcher(newDF) + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(wiringFactory) + .directive("namedDirective1", namedWiring) + .directive("namedDirective2", namedWiring) + .directiveWiring(generalWiring) + .build() + + def schema = schema(sdl, runtimeWiring) + def graphQL = GraphQL.newGraphQL(schema).build() + + String query = ''' + query { + field + } + ''' + when: + def executionInput = ExecutionInput.newExecutionInput() + .root([field: "start"]) + .query(query) .build() - executionResult = graphQL.execute(executionInput) + def er = graphQL.execute(executionInput) then: - executionResult.errors.isEmpty() - executionResult.data['secret']['identity'] == "BruceWayne" - executionResult.data['secret']['age'] == 42 - executionResult.data['nonSecret']['identity'] == "BruceWayne" - executionResult.data['nonSecret']['age'] == 42 + er.errors.isEmpty() + // + // the ordering is named ones first, general ones next and finally the factory + // + er.data["field"] == "start,namedDirective1,namedDirective2,general,factory" } + def "all directives are available to all callbacks"() { + def sdl = ''' + directive @generalDirective on FIELD_DEFINITION + directive @factoryDirective on FIELD_DEFINITION + directive @namedDirective1 on FIELD_DEFINITION + directive @namedDirective2 on FIELD_DEFINITION + type Query { + field : String @generalDirective @factoryDirective @namedDirective1 @namedDirective2 + } + ''' + + def generalCount = 0 + def factoryCount = 0 + def namedCount = 0 + + SchemaDirectiveWiring generalWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + generalCount++ + def directiveNames = env.getAppliedDirectives().values().collect { d -> d.getName() }.sort() + assert directiveNames == ["factoryDirective", "generalDirective", "namedDirective1", "namedDirective2"] + return env.getFieldDefinition() + } + } + + def factoryWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + factoryCount++ + def directiveNames = env.getAppliedDirectives().values().collect { d -> d.getName() }.sort() + assert directiveNames == ["factoryDirective", "generalDirective", "namedDirective1", "namedDirective2"] + return env.getFieldDefinition() + } + } + + def wiringFactory = new WiringFactory() { + @Override + boolean providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + return true + } + + @Override + SchemaDirectiveWiring getSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + return factoryWiring + } + } + + def namedWiring = new SchemaDirectiveWiring() { + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + namedCount++ + def directiveNames = env.getAppliedDirectives().values().collect { d -> d.getName() }.sort() + assert directiveNames == ["factoryDirective", "generalDirective", "namedDirective1", "namedDirective2"] + + assert env.getAppliedDirective("factoryDirective") != null + assert env.containsDirective("factoryDirective") + return env.getFieldDefinition() + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(wiringFactory) + .directive("namedDirective1", namedWiring) + .directive("namedDirective2", namedWiring) + .directiveWiring(generalWiring) + .build() + + def schema = schema(sdl, runtimeWiring) + def graphQL = GraphQL.newGraphQL(schema).build() + + String query = ''' + query { + field + } + ''' + when: + def executionInput = ExecutionInput.newExecutionInput() + .root([field: "start"]) + .query(query) + .build() + + def er = graphQL.execute(executionInput) + + then: + er.errors.isEmpty() + namedCount == 2 + factoryCount == 1 + generalCount == 1 + } + + + def "parent and child element directives can be accessed"() { + def sdl = ''' + directive @argDirective1 on ARGUMENT_DEFINITION + directive @argDirective2 on ARGUMENT_DEFINITION + directive @argDirective3 on ARGUMENT_DEFINITION + directive @fieldDirective on FIELD_DEFINITION + type Query { + field(arg1 : String @argDirective1 @argDirective2, arg2 : String @argDirective3) : String @fieldDirective + } + ''' + + def fieldCount = 0 + def argCount = 0 + SchemaDirectiveWiring generalWiring = new SchemaDirectiveWiring() { + + @Override + GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment env) { + argCount++ + def arg = env.getElement() + if (arg.getName() == "arg1") { + assert env.getAppliedDirectives().keySet().sort() == ["argDirective1", "argDirective2"] + assert env.getAppliedDirectives().keySet().sort() == ["argDirective1", "argDirective2"] + } + if (arg.getName() == "arg2") { + assert env.getAppliedDirectives().keySet().sort() == ["argDirective3"] + assert env.getAppliedDirectives().keySet().sort() == ["argDirective3"] + } + def fieldDef = env.getFieldDefinition() + assert fieldDef != null + assert fieldDef.getDirectives().collect({ d -> d.getName() }) == ["fieldDirective"] + + return arg + } + + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + fieldCount++ + + assert env.getAppliedDirectives().keySet().sort() == ["fieldDirective"] + + def fieldDef = env.getFieldDefinition() + assert fieldDef.getDirectives().collect({ d -> d.getName() }) == ["fieldDirective"] + + def argDirectiveNames = fieldDef.getArguments() + .stream() + .map({ a -> a.getDirectives() }) + .flatMap({ dl -> dl.stream() }) + .collect { d -> d.getName() } + .sort() + + assert argDirectiveNames == ["argDirective1", "argDirective2", "argDirective3"] + + def argAppliedDirectiveNames = fieldDef.getArguments() + .stream() + .map({ a -> a.getAppliedDirectives() }) + .flatMap({ dl -> dl.stream() }) + .collect { d -> d.getName() } + .sort() + + assert argAppliedDirectiveNames == ["argDirective1", "argDirective2", "argDirective3"] + + return env.getElement() + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .directiveWiring(generalWiring) + .build() + + when: + def schema = schema(sdl, runtimeWiring) + + then: + schema != null + fieldCount == 1 + argCount == 2 + } + + def "data fetchers can be changed in argument and object callbacks"() { + def sdl = ''' + directive @argDirective1 on ARGUMENT_DEFINITION + directive @argDirective2 on ARGUMENT_DEFINITION + directive @argDirective3 on ARGUMENT_DEFINITION + directive @fieldDirective on FIELD_DEFINITION + type Query { + field1(arg1 : String @argDirective1 @argDirective2, arg2 : String @argDirective3) : String @fieldDirective + field2 : String + } + ''' + + SchemaDirectiveWiring generalWiring = new SchemaDirectiveWiring() { + + @Override + GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment env) { + def argument = env.getElement() + def oldDF = env.getFieldDataFetcher() + DataFetcher newDF = { dfEnv -> + def val = oldDF.get(dfEnv) + return val + "+" + argument.getName() + } + env.setFieldDataFetcher(newDF) + return argument + } + + @Override + GraphQLObjectType onObject(SchemaDirectiveWiringEnvironment env) { + + def codeRegistry = env.getCodeRegistry() + def objectType = env.getElement() + objectType.getFieldDefinitions().forEach({ fieldDef -> + def oldDF = codeRegistry.getDataFetcher(objectType, fieldDef) + DataFetcher newDF = { dfEnv -> + def val = oldDF.get(dfEnv) + return val + "+" + fieldDef.getName() + } + codeRegistry.dataFetcher(objectType, fieldDef, newDF) + + }) + return objectType + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .directiveWiring(generalWiring) + .build() + + def schema = schema(sdl, runtimeWiring) + def graphQL = GraphQL.newGraphQL(schema).build() + + String query = ''' + query { + field1 + field2 + } + ''' + when: + def executionInput = ExecutionInput.newExecutionInput() + .root([field1: "data", field2: "data"]) + .query(query) + .build() + + def er = graphQL.execute(executionInput) + + then: + er.errors.isEmpty() + // two args on field1 so wrapped twice plus one object callback for two fields + er.data["field1"] == "data+arg1+arg2+field1" + er.data["field2"] == "data+field2" + } + + def "can change elements and rebuild the schema"() { + + def sdl = ''' + type Query { + field(arg : Int) : String + } + + ''' + + SchemaDirectiveWiring generalWiring = new SchemaDirectiveWiring() { + + @Override + GraphQLArgument onArgument(SchemaDirectiveWiringEnvironment env) { + def argument = env.getElement() + return argument.transform({ builder -> builder.name(reverse(argument.getName())) }) + } + + @Override + GraphQLObjectType onObject(SchemaDirectiveWiringEnvironment env) { + def obj = env.getElement() + return obj.transform({ builder -> builder.name(reverse(obj.getName())) }) + } + + @Override + GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment env) { + def field = env.getElement() + return field.transform({ builder -> builder.name(reverse(field.getName())) }) + } + } + + def wiringFactory = new WiringFactory() { + @Override + boolean providesSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + true + } + + @Override + SchemaDirectiveWiring getSchemaDirectiveWiring(SchemaDirectiveWiringEnvironment environment) { + return generalWiring + } + } + + when: "Its via a hard coded wiring" + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .directiveWiring(generalWiring) + .build() + def graphqlSchema = schema(sdl, runtimeWiring) + + then: + assert directiveWiringAsserts(graphqlSchema) + + when: "It via a wiring factory" + runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(wiringFactory) + .build() + graphqlSchema = schema(sdl, runtimeWiring) + + then: + assert directiveWiringAsserts(graphqlSchema) + } + + static def directiveWiringAsserts(schema) { + def queryType = schema.getObjectType("yreuQ") + assert queryType != null + + def fld = queryType.getFieldDefinition("dleif") + assert fld != null + + def arg = fld.getArgument("gra") + assert arg != null + true + } + + static def reverse(String s) { + new StringBuilder(s).reverse().toString() + } } diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy index c9c407c5c9..9eeed6c018 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy @@ -1,9 +1,14 @@ package graphql.schema.idl -import graphql.AssertException import graphql.TestUtil import graphql.introspection.Introspection -import graphql.schema.GraphQLDirective +import graphql.language.Node +import graphql.schema.DataFetcher +import graphql.schema.DataFetcherFactory +import graphql.schema.DataFetcherFactoryEnvironment +import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLAppliedDirective +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLDirectiveContainer import graphql.schema.GraphQLEnumType import graphql.schema.GraphQLFieldDefinition @@ -11,17 +16,20 @@ import graphql.schema.GraphQLFieldsContainer import graphql.schema.GraphQLInputObjectType import graphql.schema.GraphQLInterfaceType import graphql.schema.GraphQLList +import graphql.schema.GraphQLNamedType import graphql.schema.GraphQLNonNull import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema import graphql.schema.GraphQLType +import graphql.schema.GraphQLTypeUtil import graphql.schema.GraphQLUnionType -import graphql.schema.PropertyDataFetcher +import graphql.schema.GraphqlTypeComparatorRegistry import graphql.schema.idl.errors.NotAnInputTypeError import graphql.schema.idl.errors.NotAnOutputTypeError +import graphql.schema.idl.errors.SchemaProblem import graphql.schema.visibility.GraphqlFieldVisibility import spock.lang.Specification -import spock.lang.Unroll import java.util.function.UnaryOperator @@ -29,21 +37,33 @@ import static graphql.Scalars.GraphQLBoolean import static graphql.Scalars.GraphQLFloat import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString -import static graphql.TestUtil.schema -import static graphql.schema.GraphQLList.list +import static graphql.language.AstPrinter.printAst +import static graphql.schema.GraphQLCodeRegistry.newCodeRegistry +import static graphql.schema.idl.SchemaGenerator.Options.defaultOptions +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring class SchemaGeneratorTest extends Specification { - GraphQLType unwrap1Layer(GraphQLType type) { - if (type instanceof GraphQLNonNull) { - type = (type as GraphQLNonNull).wrappedType - } else if (type instanceof GraphQLList) { - type = (type as GraphQLList).wrappedType - } - type + static def newRuntimeWiring() { + return RuntimeWiring.newRuntimeWiring() + .comparatorRegistry(GraphqlTypeComparatorRegistry.BY_NAME_REGISTRY) + } + + static GraphQLSchema schema(String sdl) { + def runtimeWiringAsIs = newRuntimeWiring() + .comparatorRegistry(GraphqlTypeComparatorRegistry.BY_NAME_REGISTRY) + .wiringFactory(TestUtil.mockWiringFactory) + .build() + return schema(sdl, runtimeWiringAsIs) + } + + static GraphQLSchema schema(String sdl, RuntimeWiring runtimeWiring) { + SchemaGenerator.Options options = defaultOptions().captureAstDefinitions(true) + return TestUtil.schema(options, sdl, runtimeWiring) } - GraphQLType unwrap(GraphQLType type) { + + static GraphQLType unwrap(GraphQLType type) { while (true) { if (type instanceof GraphQLNonNull) { type = (type as GraphQLNonNull).wrappedType @@ -56,7 +76,7 @@ class SchemaGeneratorTest extends Specification { type } - void commonSchemaAsserts(GraphQLSchema schema) { + static void commonSchemaAsserts(GraphQLSchema schema) { assert schema.getQueryType().name == "Query" assert schema.getMutationType().name == "Mutation" @@ -141,7 +161,6 @@ class SchemaGeneratorTest extends Specification { } - def "test simple schema generate"() { def schemaSpec = """ @@ -301,8 +320,8 @@ class SchemaGeneratorTest extends Specification { types.size() == 2 types[0] instanceof GraphQLObjectType types[1] instanceof GraphQLObjectType - types[0].name == "Foo" - types[1].name == "Bar" + types[0].name == "Bar" + types[1].name == "Foo" } @@ -338,8 +357,8 @@ class SchemaGeneratorTest extends Specification { types.size() == 2 types[0] instanceof GraphQLObjectType types[1] instanceof GraphQLObjectType - types[0].name == "Foo" - types[1].name == "Bar" + types[0].name == "Bar" + types[1].name == "Foo" } @@ -374,8 +393,8 @@ class SchemaGeneratorTest extends Specification { types.size() == 2 types[0] instanceof GraphQLObjectType types[1] instanceof GraphQLObjectType - types[0].name == "Foo" - types[1].name == "Bar" + types[0].name == "Bar" + types[1].name == "Foo" } @@ -413,8 +432,8 @@ class SchemaGeneratorTest extends Specification { types.size() == 2 types[0] instanceof GraphQLObjectType types[1] instanceof GraphQLObjectType - types[0].name == "Foo" - types[1].name == "Bar" + types[0].name == "Bar" + types[1].name == "Foo" } @@ -447,9 +466,9 @@ class SchemaGeneratorTest extends Specification { enumType.getName() == "RGB" enumType.getDefinition().getName() == "RGB" - enumType.values.get(0).getValue() == "RED" + enumType.values.get(0).getValue() == "BLUE" enumType.values.get(1).getValue() == "GREEN" - enumType.values.get(2).getValue() == "BLUE" + enumType.values.get(2).getValue() == "RED" } @@ -482,9 +501,9 @@ class SchemaGeneratorTest extends Specification { interfaceType.name == "Foo" interfaceType.getDefinition().getName() == "Foo" - schema.queryType.fieldDefinitions[0].name == "is_foo" + schema.queryType.fieldDefinitions[0].name == "is_bar" schema.queryType.fieldDefinitions[0].type.name == "Boolean" - schema.queryType.fieldDefinitions[1].name == "is_bar" + schema.queryType.fieldDefinitions[1].name == "is_foo" schema.queryType.fieldDefinitions[1].type.name == "Boolean" } @@ -511,11 +530,9 @@ class SchemaGeneratorTest extends Specification { extraField1 : String } extend type BaseType implements Interface2 { - extraField1 : String extraField2 : Int } extend type BaseType implements Interface3 { - extraField1 : String extraField3 : ID } extend type BaseType { @@ -524,13 +541,6 @@ class SchemaGeneratorTest extends Specification { extend type BaseType { extraField5 : Boolean! } - # - # if we repeat a definition, that's ok as long as its the same types as before - # they will be de-duped since the effect is the same - # - extend type BaseType implements Interface1 { - extraField1 : String - } schema { query: BaseType @@ -591,7 +601,6 @@ class SchemaGeneratorTest extends Specification { name: String! } extend type Human implements Character { - name: String! friends: [Character] } extend type Human { @@ -607,11 +616,11 @@ class SchemaGeneratorTest extends Specification { GraphQLObjectType type = schema.getQueryType() type.name == "Human" - type.fieldDefinitions[0].name == "id" - type.fieldDefinitions[1].name == "name" - type.fieldDefinitions[2].name == "friends" - type.fieldDefinitions[3].name == "appearsIn" - type.fieldDefinitions[4].name == "homePlanet" + type.fieldDefinitions[0].name == "appearsIn" + type.fieldDefinitions[1].name == "friends" + type.fieldDefinitions[2].name == "homePlanet" + type.fieldDefinitions[3].name == "id" + type.fieldDefinitions[4].name == "name" type.interfaces.size() == 1 type.interfaces[0].name == "Character" @@ -864,7 +873,7 @@ class SchemaGeneratorTest extends Specification { def enumValuesProvider = new NaturalEnumValuesProvider(ExampleEnum.class) when: - def wiring = RuntimeWiring.newRuntimeWiring() + def wiring = newRuntimeWiring() .type("Enum", { TypeRuntimeWiring.Builder it -> it.enumValues(enumValuesProvider) } as UnaryOperator) .build() def schema = schema(spec, wiring) @@ -876,6 +885,33 @@ class SchemaGeneratorTest extends Specification { enumType.getValue("C").value == ExampleEnum.C } + def " MapEnum values provider"() { + given: + def spec = ''' + enum Enum{ + A + B + C + } + + type Query{ + field: Enum + } + ''' + + when: + def mapEnumProvider = new MapEnumValuesProvider([A: 11, B: 12, C: 13]) + def enumTypeWiring = newTypeWiring("Enum").enumValues(mapEnumProvider).build() + def wiring = RuntimeWiring.newRuntimeWiring().type(enumTypeWiring).build() + def schema = TestUtil.schema(spec, wiring) + GraphQLEnumType graphQLEnumType = schema.getType("Enum") as GraphQLEnumType + + then: + graphQLEnumType.getValue("A").value == 11 + graphQLEnumType.getValue("B").value == 12 + graphQLEnumType.getValue("C").value == 13 + } + def "enum with no values provider: value is the name"() { given: def spec = """ @@ -903,61 +939,6 @@ class SchemaGeneratorTest extends Specification { } - @Unroll - def "when using implicit directive (w/o definition), #argumentName is supported"() { - setup: - def spec = """ - type Query @myDirective($argumentName: $argumentValue) { - foo: String - } - """ - when: - def wiring = RuntimeWiring.newRuntimeWiring() - .build() - - def schema = schema(spec, wiring) - def queryType = schema.queryType - - then: - def directive = queryType.getDirective("myDirective") - directive.getArgument(argumentName).type == expectedArgumentType - - where: - argumentName | argumentValue || expectedArgumentType - "stringArg" | '"a string"' || GraphQLString - "boolArg" | "true" || GraphQLBoolean - "floatArg" | "4.5" || GraphQLFloat - "intArg" | "5" || GraphQLInt - "nullArg" | "null" || GraphQLString - "emptyArrayArg" | "[]" || list(GraphQLString) - "arrayNullsArg" | "[null, null]" || list(GraphQLString) - "arrayArg" | "[3,4,6]" || list(GraphQLInt) - "arrayWithNullsArg" | "[null,3,null,6]" || list(GraphQLInt) - } - - @Unroll - def "when using implicit directive (w/o definition), #argumentName is NOT supported"() { - setup: - def spec = """ - type Query @myDirective($argumentName: $argumentValue) { - foo: String - } - """ - when: - def wiring = RuntimeWiring.newRuntimeWiring() - .build() - schema(spec, wiring) - - then: - def ex = thrown(AssertException) - ex.message == expectedErrorMessage - - where: - argumentName | argumentValue || expectedErrorMessage - "objArg" | '{ hi: "John"}' || "Internal error: should never happen: Directive values of type 'ObjectValue' are not supported yet" - "enumArg" | "MONDAY" || "Internal error: should never happen: Directive values of type 'EnumValue' are not supported yet" - "polymorphicArrayArg" | '["one", { hi: "John"}, 5]' || "Arrays containing multiple types of values are not supported yet. Detected the following types [IntValue,ObjectValue,StringValue]" - } def "deprecated directive is supported"() { given: @@ -977,10 +958,7 @@ class SchemaGeneratorTest extends Specification { } """ when: - def wiring = RuntimeWiring.newRuntimeWiring() - .build() - - def schema = schema(spec, wiring) + def schema = schema(spec) GraphQLEnumType enumType = schema.getType("Enum") as GraphQLEnumType GraphQLObjectType queryType = schema.getType("Query") as GraphQLObjectType @@ -994,6 +972,57 @@ class SchemaGeneratorTest extends Specification { !queryType.getFieldDefinition("baz").isDeprecated() } + def "specifiedBy directive is supported"() { + given: + def spec = """ + type Query { + foo: MyScalar + } + "My scalar has a specifiedBy url" + scalar MyScalar @specifiedBy(url: "myUrl.example") + """ + when: + def schema = schema(spec) + GraphQLScalarType scalar = schema.getType("MyScalar") as GraphQLScalarType + + then: + scalar.getSpecifiedByUrl() == "myUrl.example" + scalar.getDescription() == "My scalar has a specifiedBy url" + } + + def "specifiedBy requires an url "() { + given: + def spec = """ + type Query { + foo: MyScalar + } + scalar MyScalar @specifiedBy + """ + when: + def registry = new SchemaParser().parse(spec) + new SchemaGenerator().makeExecutableSchema(defaultOptions(), registry, TestUtil.mockRuntimeWiring) + + then: + def schemaProblem = thrown(SchemaProblem) + schemaProblem.message.contains("failed to provide a value for the non null argument 'url' on directive 'specifiedBy'") + } + + def "specifiedBy can be added via extension"() { + given: + def spec = """ + type Query { + foo: MyScalar + } + scalar MyScalar + extend scalar MyScalar @specifiedBy(url: "myUrl.example") + """ + when: + def schema = schema(spec) + GraphQLScalarType scalar = schema.getType("MyScalar") as GraphQLScalarType + + then: + scalar.getSpecifiedByUrl() == "myUrl.example" + } def "schema is optional if there is a type called Query"() { @@ -1099,6 +1128,103 @@ class SchemaGeneratorTest extends Specification { schema.getType("UnReferencedD") instanceof GraphQLUnionType } + def "nested additional types should be part of the additional types, not the schema types"() { + def spec = """ + type Query { + fieldA : ReferencedA + } + + type ReferencedA { + field : String + } + + type UnReferencedA { + field : UnReferencedNestedE + } + + input UnReferencedB { + field : UnReferencedNestedF + } + + type UnReferencedNestedE { + field: String + field2: UnReferencedScalarB + } + + input UnReferencedNestedF { + field: String + } + + interface UnReferencedC { + field : UnReferencedNestedE + } + + union UnReferencedD = ReferencedA + + scalar UnReferencedScalarA + + scalar UnReferencedScalarB + """ + + def schema = schema(spec) + + expect: "all types to be registered" + schema.getType("ReferencedA") instanceof GraphQLObjectType + schema.getType("UnReferencedA") instanceof GraphQLObjectType + schema.getType("UnReferencedB") instanceof GraphQLInputObjectType + schema.getType("UnReferencedC") instanceof GraphQLInterfaceType + schema.getType("UnReferencedD") instanceof GraphQLUnionType + schema.getType("UnReferencedNestedE") instanceof GraphQLObjectType + schema.getType("UnReferencedNestedF") instanceof GraphQLInputObjectType + + + and: "unreferenced types should all be additional types" + + def namedTypes = schema.getAdditionalTypes() as Set + namedTypes.name.toSet() == ["UnReferencedA", + "UnReferencedB", + "UnReferencedC", + "UnReferencedD", + "UnReferencedNestedE", + "UnReferencedNestedF", + "UnReferencedScalarA", + "UnReferencedScalarB"].toSet() + } + + + def "nested additional types recursive"() { + def spec = """ + type Query { + fieldA : ReferencedA + } + + type ReferencedA { + field : String + } + + type UnReferencedA { + field : UnReferencedNestedB + } + + type UnReferencedNestedB { + field: UnReferencedNestedB + } + """ + + def schema = schema(spec) + + expect: "all types to be registered" + schema.getType("ReferencedA") instanceof GraphQLObjectType + schema.getType("UnReferencedA") instanceof GraphQLObjectType + schema.getType("UnReferencedNestedB") instanceof GraphQLObjectType + + and: "unreferenced types should all be additional types" + + def namedTypes = schema.getAdditionalTypes() as Set + namedTypes.name.toSet() == ["UnReferencedA", "UnReferencedNestedB"].toSet() + } + + def "scalar default value is parsed"() { def spec = """ type Query { @@ -1109,13 +1235,12 @@ class SchemaGeneratorTest extends Specification { def schema = schema(spec) schema.getType("Query") instanceof GraphQLObjectType GraphQLObjectType query = schema.getType("Query") as GraphQLObjectType - Object arg1 = query.getFieldDefinition("field").getArgument("arg1").defaultValue - Object arg2 = query.getFieldDefinition("field").getArgument("arg2").defaultValue + Object arg1 = printAst(query.getFieldDefinition("field").getArgument("arg1").argumentDefaultValue.value as Node) + Object arg2 = printAst(query.getFieldDefinition("field").getArgument("arg2").argumentDefaultValue.value as Node) expect: - arg1 instanceof Integer - arg2 instanceof List - (arg2 as List).get(0) instanceof Integer + arg1 == "10" + arg2 == "[20]" } def "null default arguments are ok"() { @@ -1128,7 +1253,7 @@ class SchemaGeneratorTest extends Specification { def schema = schema(spec) schema.getType("Query") instanceof GraphQLObjectType GraphQLObjectType query = schema.getType("Query") as GraphQLObjectType - Object argNoDefault = query.getFieldDefinition("field").getArgument("argNoDefault").defaultValue + Object argNoDefault = query.getFieldDefinition("field").getArgument("argNoDefault").argumentDefaultValue.value expect: argNoDefault == null @@ -1136,6 +1261,13 @@ class SchemaGeneratorTest extends Specification { def "object type directives are gathered and turned into runtime objects with arguments"() { def spec = """ + directive @directive1 on OBJECT + directive @fieldDirective1 on FIELD_DEFINITION + directive @directive2 on OBJECT + directive @directive3 on OBJECT + directive @directiveWithArgs(strArg: String, intArg: Int, boolArg: Boolean, floatArg: Float,nullArg: String) on OBJECT + directive @fieldDirective2 on FIELD_DEFINITION + type Query @directive1 { field1 : String @fieldDirective1 } @@ -1144,8 +1276,6 @@ class SchemaGeneratorTest extends Specification { field2 : String @fieldDirective2 } - extend type Query @directive2 - extend type Query @directive3 extend type Query @directiveWithArgs(strArg : "String", intArg : 1, boolArg : true, floatArg : 1.1, nullArg : null) @@ -1159,8 +1289,11 @@ class SchemaGeneratorTest extends Specification { expect: type.getDirectives().size() == 4 type.getDirectives()[0].name == "directive1" + type.getDirectives()[0].getDefinition() != null type.getDirectives()[1].name == "directive2" + type.getDirectives()[1].getDefinition() != null type.getDirectives()[2].name == "directive3" + type.getDirectives()[2].getDefinition() != null // test that fields can have directives as well @@ -1174,22 +1307,22 @@ class SchemaGeneratorTest extends Specification { def fieldDirective2 = field2.getDirectives()[0] fieldDirective2.getName() == "fieldDirective2" - - def directive = type.getDirectives()[3] as GraphQLDirective + def directive = type.getAppliedDirectives()[3] as GraphQLAppliedDirective directive.name == "directiveWithArgs" directive.arguments.size() == 5 directive.arguments[argIndex].name == argName directive.arguments[argIndex].type == argType - directive.arguments[argIndex].value == argValue + printAst(directive.arguments[argIndex].argumentValue.value as Node) == argValue + // arguments are sorted where: argIndex | argName | argType | argValue - 0 | "strArg" | GraphQLString | "String" - 1 | "intArg" | GraphQLInt | 1 - 2 | "boolArg" | GraphQLBoolean | true - 3 | "floatArg" | GraphQLFloat | 1.1 - 4 | "nullArg" | GraphQLString | null + 0 | "boolArg" | GraphQLBoolean | "true" + 1 | "floatArg" | GraphQLFloat | "1.1" + 2 | "intArg" | GraphQLInt | "1" + 3 | "nullArg" | GraphQLString | "null" + 4 | "strArg" | GraphQLString | "\"String\"" } @@ -1204,18 +1337,21 @@ class SchemaGeneratorTest extends Specification { type B { fieldB : String } - + directive @IFaceDirective on INTERFACE interface IFace @IFaceDirective { field1 : String } - + directive @OnionDirective on UNION union Onion @OnionDirective = A | B + directive @EnumValueDirective on ENUM_VALUE + directive @NumbDirective on ENUM enum Numb @NumbDirective { X @EnumValueDirective, Y } - + directive @PuterDirective on INPUT_OBJECT + directive @InputFieldDirective on INPUT_FIELD_DEFINITION input Puter @PuterDirective { inputField : String @InputFieldDirective } @@ -1226,7 +1362,7 @@ class SchemaGeneratorTest extends Specification { expect: - container.getDirective(directiveName) != null + container.getAppliedDirective(directiveName) != null if (container instanceof GraphQLEnumType) { def evd = ((GraphQLEnumType) container).getValue("X").getDirective("EnumValueDirective") @@ -1259,11 +1395,10 @@ class SchemaGeneratorTest extends Specification { def schema = schema(spec) schema.getType("Query") instanceof GraphQLObjectType GraphQLObjectType query = schema.getType("Query") as GraphQLObjectType - Object arg = query.getFieldDefinition("field").getArgument("arg").defaultValue as Map + String arg = printAst(query.getFieldDefinition("field").getArgument("arg").argumentDefaultValue.value as Node) expect: - arg["str"] instanceof String - arg["num"] instanceof Integer + arg == '{str : "string", num : 100}' } def "field visibility is used"() { @@ -1289,7 +1424,7 @@ class SchemaGeneratorTest extends Specification { expect: - schema.getFieldVisibility() == fieldVisibility + schema.getCodeRegistry().getFieldVisibility() == fieldVisibility } @@ -1333,10 +1468,12 @@ class SchemaGeneratorTest extends Specification { } + directive @directive on INTERFACE interface IAgeAndHeight @directive { age : Int } + directive @directiveField on FIELD_DEFINITION extend interface IAgeAndHeight { height : Int @directiveField } @@ -1377,7 +1514,7 @@ class SchemaGeneratorTest extends Specification { union FooBar = Foo extend union FooBar = Bar | Baz - + directive @directive on UNION extend union FooBar @directive """ @@ -1407,7 +1544,7 @@ class SchemaGeneratorTest extends Specification { extend enum Numb { C } - + directive @directive on ENUM extend enum Numb @directive{ D } @@ -1444,6 +1581,7 @@ class SchemaGeneratorTest extends Specification { fieldC : String } + directive @directive on INPUT_OBJECT extend input Puter @directive { fieldD : String } @@ -1467,7 +1605,10 @@ class SchemaGeneratorTest extends Specification { type Query { obj : Object } - + directive @strDirective on ARGUMENT_DEFINITION + directive @secondDirective on ARGUMENT_DEFINITION + directive @intDirective(inception: Boolean) on ARGUMENT_DEFINITION + directive @thirdDirective on ARGUMENT_DEFINITION type Object { field(argStr : String @strDirective @secondDirective, argInt : Int @intDirective(inception : true) @thirdDirective ) : String } @@ -1489,13 +1630,14 @@ class SchemaGeneratorTest extends Specification { argInt.getDirective("thirdDirective") != null def intDirective = argInt.getDirective("intDirective") - intDirective.name == "intDirective" - intDirective.arguments.size() == 1 - def directiveArg = intDirective.getArgument("inception") + def intAppliedDirective = argInt.getAppliedDirective("intDirective") + intAppliedDirective.name == "intDirective" + intAppliedDirective.arguments.size() == 1 + def directiveArg = intAppliedDirective.getArgument("inception") directiveArg.name == "inception" directiveArg.type == GraphQLBoolean - directiveArg.value == true - directiveArg.defaultValue == null + printAst(directiveArg.argumentValue.value as Node) == "true" + intDirective.getArgument("inception").argumentDefaultValue.value == null } def "directives definitions can be made"() { @@ -1512,12 +1654,7 @@ class SchemaGeneratorTest extends Specification { """ when: - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(true) - - then: - options.isEnforceSchemaDirectives() - - when: + def options = defaultOptions() def registry = new SchemaParser().parse(spec) def schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) @@ -1538,7 +1675,7 @@ class SchemaGeneratorTest extends Specification { Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION, ) directive.getArgument("knownArg").type == GraphQLString - directive.getArgument("knownArg").defaultValue == "defaultValue" + printAst(directive.getArgument("knownArg").argumentDefaultValue.value as Node) == '"defaultValue"' } def "directive definitions don't have to provide default values"() { @@ -1554,21 +1691,23 @@ class SchemaGeneratorTest extends Specification { """ when: - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(true) + def options = defaultOptions() def registry = new SchemaParser().parse(spec) def schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) then: def directiveTest1 = schema.getDirective("test1") - directiveTest1.getArgument("include").type == GraphQLNonNull.nonNull(GraphQLBoolean) - directiveTest1.getArgument("include").value == null + GraphQLNonNull.nonNull(GraphQLBoolean).isEqualTo(directiveTest1.getArgument("include").type) + directiveTest1.getArgument("include").argumentDefaultValue.value == null + def appliedDirective1 = schema.getObjectType("Query").getFieldDefinition("f1").getAppliedDirective("test1") + printAst(appliedDirective1.getArgument("include").argumentValue.value as Node) == "false" def directiveTest2 = schema.getDirective("test2") - directiveTest2.getArgument("include").type == GraphQLNonNull.nonNull(GraphQLBoolean) - directiveTest2.getArgument("include").value == true - directiveTest2.getArgument("include").defaultValue == true - + GraphQLNonNull.nonNull(GraphQLBoolean).isEqualTo(directiveTest2.getArgument("include").type) + printAst(directiveTest2.getArgument("include").argumentDefaultValue.value as Node) == "true" + def appliedDirective2 = schema.getObjectType("Query").getFieldDefinition("f2").getAppliedDirective("test2") + printAst(appliedDirective2.getArgument("include").argumentValue.value as Node) == "true" } def "missing directive arguments are transferred as are default values"() { @@ -1586,28 +1725,24 @@ class SchemaGeneratorTest extends Specification { """ when: - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(true) - - then: - options.isEnforceSchemaDirectives() - - when: + def options = defaultOptions() def registry = new SchemaParser().parse(spec) def schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) then: def directive = schema.getObjectType("Query").getFieldDefinition("f").getDirective("testDirective") directive.getArgument("knownArg1").type == GraphQLString - directive.getArgument("knownArg1").value == "overrideVal1" - directive.getArgument("knownArg1").defaultValue == "defaultValue1" + printAst(directive.getArgument("knownArg1").argumentDefaultValue.value as Node) == '"defaultValue1"' + def appliedDirective = schema.getObjectType("Query").getFieldDefinition("f").getAppliedDirective("testDirective") + printAst(appliedDirective.getArgument("knownArg1").argumentValue.value as Node) == '"overrideVal1"' directive.getArgument("knownArg2").type == GraphQLInt - directive.getArgument("knownArg2").value == 666 - directive.getArgument("knownArg2").defaultValue == 666 + printAst(directive.getArgument("knownArg2").argumentDefaultValue.value as Node) == "666" + printAst(appliedDirective.getArgument("knownArg2").argumentValue.value as Node) == "666" directive.getArgument("knownArg3").type == GraphQLString - directive.getArgument("knownArg3").value == null - directive.getArgument("knownArg3").defaultValue == null + directive.getArgument("knownArg3").argumentDefaultValue.value == null + appliedDirective.getArgument("knownArg3").argumentValue.value == null } def "deprecated directive is implicit"() { @@ -1619,7 +1754,7 @@ class SchemaGeneratorTest extends Specification { } """ - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(true) + def options = defaultOptions() when: def registry = new SchemaParser().parse(spec) @@ -1630,62 +1765,33 @@ class SchemaGeneratorTest extends Specification { f1.getDeprecationReason() == "No longer supported" // spec default text def directive = f1.getDirective("deprecated") - directive.name == "deprecated" - directive.getArgument("reason").type == GraphQLString - directive.getArgument("reason").value == "No longer supported" - directive.getArgument("reason").defaultValue == "No longer supported" + printAst(directive.getArgument("reason").argumentDefaultValue.value as Node) == '"No longer supported"' directive.validLocations().collect { it.name() } == [Introspection.DirectiveLocation.FIELD_DEFINITION.name()] + def appliedDirective = f1.getAppliedDirective("deprecated") + appliedDirective.name == "deprecated" + appliedDirective.getArgument("reason").type instanceof GraphQLNonNull + (appliedDirective.getArgument("reason").type as GraphQLNonNull).wrappedType == GraphQLString + printAst(appliedDirective.getArgument("reason").argumentValue.value as Node) == '"No longer supported"' + when: def f2 = schema.getObjectType("Query").getFieldDefinition("f2") then: f2.getDeprecationReason() == "Just because" + def appliedDirective2 = f2.getAppliedDirective("deprecated") + appliedDirective2.name == "deprecated" + appliedDirective2.getArgument("reason").type instanceof GraphQLNonNull + (appliedDirective2.getArgument("reason").type as GraphQLNonNull).wrappedType == GraphQLString + printAst(appliedDirective2.getArgument("reason").argumentValue.value as Node) == '"Just because"' def directive2 = f2.getDirective("deprecated") - directive2.name == "deprecated" - directive2.getArgument("reason").type == GraphQLString - directive2.getArgument("reason").value == "Just because" - directive2.getArgument("reason").defaultValue == "No longer supported" + printAst(directive2.getArgument("reason").argumentDefaultValue.value as Node) == '"No longer supported"' directive2.validLocations().collect { it.name() } == [Introspection.DirectiveLocation.FIELD_DEFINITION.name()] - - } - - def "@fetch directive is respected"() { - def spec = """ - - directive @fetch(from : String!) on FIELD_DEFINITION - - type Query { - name : String, - homePlanet: String @fetch(from : "planetOfBirth") - } - """ - - def wiring = RuntimeWiring.newRuntimeWiring().build() - def schema = schema(spec, wiring) - - GraphQLObjectType type = schema.getType("Query") as GraphQLObjectType - - expect: - def fetcher = type.getFieldDefinition("homePlanet").getDataFetcher() - fetcher instanceof PropertyDataFetcher - - PropertyDataFetcher propertyDataFetcher = fetcher as PropertyDataFetcher - propertyDataFetcher.getPropertyName() == "planetOfBirth" - // - // no directive - plain name - // - def fetcher2 = type.getFieldDefinition("name").getDataFetcher() - fetcher2 instanceof PropertyDataFetcher - - PropertyDataFetcher propertyDataFetcher2 = fetcher2 as PropertyDataFetcher - propertyDataFetcher2.getPropertyName() == "name" } - def "does not break for circular references to interfaces"() { - def spec = """ + def spec = """ interface MyInterface { interfaceField: MyNonImplementingType } @@ -1702,15 +1808,737 @@ class SchemaGeneratorTest extends Specification { hello: String } """ - - def types = new SchemaParser().parse(spec) - def wiring = RuntimeWiring.newRuntimeWiring() - .type("Query", { typeWiring -> typeWiring.dataFetcher("hello", { env -> "Hello, world" }) }) - .type("MyInterface", { typeWiring -> typeWiring.typeResolver({ env -> null}) }) - .build(); - GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(types, wiring); - expect: - assert schema != null + + def types = new SchemaParser().parse(spec) + def wiring = RuntimeWiring.newRuntimeWiring() + .type("Query", { typeWiring -> typeWiring.dataFetcher("hello", { env -> "Hello, world" }) }) + .type("MyInterface", { typeWiring -> typeWiring.typeResolver({ env -> null }) }) + .build() + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(types, wiring) + expect: + assert schema != null + } + + def "enum object default values are handled"() { + def spec = ''' + enum EnumValue { + ONE, TWO, THREE + } + + input InputType { + value : EnumValue + } + + type Query { + fieldWithEnum(arg : InputType = { value : ONE } ) : String + } + ''' + def types = new SchemaParser().parse(spec) + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(types, TestUtil.mockRuntimeWiring) + expect: + assert schema != null + def queryType = schema.getObjectType("Query") + def fieldWithEnum = queryType.getFieldDefinition("fieldWithEnum") + def arg = fieldWithEnum.getArgument("arg") + printAst(arg.argumentDefaultValue.value as Node) == '{value : ONE}' } + def "extensions are captured into runtime objects"() { + def sdl = ''' + directive @directive1 on SCALAR + ######## Objects + + type Query { + foo : String + } + + extend type Query { + bar : String + } + + extend type Query { + baz : String + } + + ######## Enums + + enum Enum { + A + } + + extend enum Enum { + B + } + + ######## Interface + + interface Interface { + foo : String + } + + extend interface Interface { + bar : String + } + + extend interface Interface { + baz : String + } + + ######## Unions + + type Foo { + foo : String + } + + type Bar { + bar : Scalar + } + + union Union = Foo + + extend union Union = Bar + + ######## Input Objects + + input Input { + foo: String + } + + extend input Input { + bar: String + } + + extend input Input { + baz: String + } + + extend input Input { + faz: String + } + + ######## Scalar + + scalar Scalar + + extend scalar Scalar @directive1 + ''' + + + when: + def wiringFactory = new MockedWiringFactory() { + @Override + boolean providesScalar(ScalarWiringEnvironment env) { + return env.getScalarTypeDefinition().getName() == "Scalar" + } + + @Override + GraphQLScalarType getScalar(ScalarWiringEnvironment env) { + def definition = env.getScalarTypeDefinition() + return GraphQLScalarType.newScalar() + .name(definition.getName()) + .definition(definition) + .extensionDefinitions(env.getExtensions()) + .coercing(TestUtil.mockCoercing()) + .build() + } + } + + def runtimeWiring = RuntimeWiring.newRuntimeWiring() + .wiringFactory(wiringFactory) + .build() + + def options = defaultOptions() + + def types = new SchemaParser().parse(sdl) + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(options, types, runtimeWiring) + + then: + schema != null + + (schema.getType("Query") as GraphQLObjectType).getExtensionDefinitions().size() == 2 + + (schema.getType("Enum") as GraphQLEnumType).getExtensionDefinitions().size() == 1 + + (schema.getType("Interface") as GraphQLInterfaceType).getExtensionDefinitions().size() == 2 + + (schema.getType("Union") as GraphQLUnionType).getExtensionDefinitions().size() == 1 + + (schema.getType("Input") as GraphQLInputObjectType).getExtensionDefinitions().size() == 3 + + // scalars are special - they are created via a WiringFactory - but this tests they are given the extensions + (schema.getType("Scalar") as GraphQLScalarType).getExtensionDefinitions().size() == 1 + } + + def "schema extensions and directives can be generated"() { + def sdl = ''' + + directive @sd1 on SCHEMA + directive @sd2 on SCHEMA + directive @sd3 on SCHEMA + + schema @sd1 { + query : Query + } + + extend schema @sd2 { + mutation : Mutation + } + + extend schema @sd3 + + type Query { + f : String + } + + type Mutation { + f : String + } + ''' + + when: + def typeDefinitionRegistry = new SchemaParser().parse(sdl) + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, TestUtil.mockRuntimeWiring) + + then: + + schema.getQueryType().name == 'Query' + schema.getMutationType().name == 'Mutation' + + when: + def directives = schema.getSchemaDirectives() // Retain for test coverage + + then: + directives.size() == 3 + schema.getSchemaDirective("sd1") != null // Retain for test coverage + schema.getSchemaDirective("sd2") != null // Retain for test coverage + schema.getSchemaDirective("sd3") != null // Retain for test coverage + + when: + def directivesMap = schema.getSchemaDirectiveByName() // Retain for test coverage + then: + directives.size() == 3 + directivesMap["sd1"] != null + directivesMap["sd2"] != null + directivesMap["sd3"] != null + + when: + directives = schema.getDirectives() + + then: + directives.size() == 10 // built in ones : include / skip and deprecated + def directiveNames = directives.collect { it.name } + directiveNames.contains("include") + directiveNames.contains("skip") + directiveNames.contains("defer") + directiveNames.contains("deprecated") + directiveNames.contains("specifiedBy") + directiveNames.contains("oneOf") + directiveNames.contains("sd1") + directiveNames.contains("sd2") + directiveNames.contains("sd3") + + when: + directivesMap = schema.getDirectivesByName() + + then: + directivesMap.size() == 10 // built in ones + directivesMap.containsKey("include") + directivesMap.containsKey("skip") + directivesMap.containsKey("defer") + directivesMap.containsKey("deprecated") + directivesMap.containsKey("oneOf") + directivesMap.containsKey("sd1") + directivesMap.containsKey("sd2") + directivesMap.containsKey("sd3") + } + + def "directive arg descriptions are captured correctly"() { + given: + def spec = ''' + type Query { + foo: String + } + directive @MyDirective( + """ + DOC + """ + arg: String) on FIELD + ''' + when: + def schema = schema(spec) + + then: + schema.getDirective("MyDirective").getArgument("arg").description == "DOC" + } + + def "capture DirectiveDefinitions"() { + given: + def spec = ''' + type Query { + foo: String + } + directive @MyDirective on FIELD + ''' + when: + def schema = schema(spec) + def directiveDefinition = schema.getDirective("MyDirective").getDefinition() + then: + directiveDefinition != null + directiveDefinition.getName() == "MyDirective" + + + } + + def "directive with enum args"() { + given: + + def spec = """ + directive @myDirective ( + enumArguments: [SomeEnum!] = [] + ) on FIELD_DEFINITION + + enum SomeEnum { + VALUE_1 + VALUE_2 + } + type Query{ foo: String } + """ + when: + def schema = schema(spec) + def directive = schema.getDirective("myDirective") + then: + directive != null + GraphQLTypeUtil.simplePrint(directive.getArgument("enumArguments").getType()) == "[SomeEnum!]" + printAst(directive.getArgument("enumArguments").getArgumentDefaultValue().value as Node) == "[]" + } + + def "scalar used as output is not in additional types"() { + given: + + def spec = """ + scalar UsedScalar + type Query{ foo: UsedScalar } + """ + when: + def schema = schema(spec) + then: + schema.getType("UsedScalar") != null + schema.getAdditionalTypes().find { it.name == "UsedScalar" } == null + } + + def "scalar used as input is not in additional types"() { + given: + + def spec = """ + scalar UsedScalar + input Input { + foo: UsedScalar + } + type Query{ foo(arg: Input): String } + """ + when: + def schema = schema(spec) + then: + schema.getType("UsedScalar") != null + schema.getAdditionalTypes().find { it.name == "UsedScalar" } == null + } + + def "unused scalar is not ignored and provided as additional type"() { + given: + + def spec = """ + scalar UnusedScalar + type Query{ foo: String } + """ + when: + def schema = schema(spec) + then: + schema.getType("UnusedScalar") != null + schema.getAdditionalTypes().find { it.name == "UnusedScalar" } != null + } + + def "interface can be implemented with additional optional arguments"() { + given: + def spec = """ + interface Vehicle { + name: String! + } + + type Car implements Vehicle { + name(charLimit: Int = 10): String! + } + type Query { + car: Car + } + """ + when: + def schema = schema(spec) + then: + (schema.getType("Car") as GraphQLObjectType).getFieldDefinition("name").getArgument("charLimit") != null + (schema.getType("Car") as GraphQLObjectType).getInterfaces().size() == 1 + + (schema.getType("Vehicle") as GraphQLInterfaceType).getFieldDefinition("name").getArguments().size() == 0 + + } + + def "extended enums work as expected for arg values"() { + + given: + def spec = """ + enum AuthRoles { + USER + } + + extend enum AuthRoles { + AUTHENTICATED + } + + directive @auth(if: AuthRoles) on FIELD_DEFINITION + + type Query { + danger: String @auth(if: AUTHENTICATED) + } + """ + when: + def schema = schema(spec) + then: + def enumType = schema.getType("AuthRoles") as GraphQLEnumType + def listOfEnumValues = enumType.getValues().collect({ it.getValue() }) + listOfEnumValues.sort() == ["AUTHENTICATED", "USER"] + } + + def "extended input objects work as expected for arg values"() { + + given: + def spec = """ + input ArgInput { + fieldA : String + } + + extend input ArgInput { + fieldB : String + } + + directive @auth(if: ArgInput) on FIELD_DEFINITION + + type Query { + danger: String @auth(if: { fieldB : "B"} ) + } + """ + when: + def schema = schema(spec) + then: + def inputType = schema.getType("ArgInput") as GraphQLInputObjectType + def listOfEnumValues = inputType.getFieldDefinitions().collect({ it.getName() }) + listOfEnumValues.sort() == ["fieldA", "fieldB"] + } + + def "shows that issue 2238 and 2290 - recursive input types on directives - has been fixed"() { + def sdl1 = ''' + directive @test(arg: Recursive) on OBJECT + + input Recursive { + deeper: Recursive + name: String + } + type Test @test(arg: { deeper: {name: "test"}}){ + field: String + } + type Query { + test : Test + } + ''' + when: + GraphQLSchema schema = TestUtil.schema(sdl1) + then: + schema != null + + def sdl2 = ''' + input MyInput { + a: String + b: MyInput + } + directive @myDirective(x: MyInput) on FIELD_DEFINITION + type Query { + f: String @myDirective(x: {b: {a:"yada"}}) + } + ''' + + when: + schema = TestUtil.schema(sdl2) + then: + schema != null + } + + def "code registry default data fetcher is respected"() { + def sdl = ''' + type Query { + field : String + } + ''' + + DataFetcher df = { DataFetchingEnvironment env -> + env.getFieldDefinition().getName().reverse() + } + + DataFetcherFactory dff = new DataFetcherFactory() { + @Override + DataFetcher get(DataFetcherFactoryEnvironment environment) { + return df + } + + @Override + DataFetcher get(GraphQLFieldDefinition fieldDefinition) { + return df + } + } + + GraphQLCodeRegistry codeRegistry = newCodeRegistry() + .defaultDataFetcher(dff).build() + + def runtimeWiring = newRuntimeWiring().codeRegistry(codeRegistry).build() + + def graphQL = TestUtil.graphQL(sdl, runtimeWiring).build() + when: + def er = graphQL.execute('{ field }') + then: + er.errors.isEmpty() + er.data["field"] == "dleif" + + } + + def "custom scalars can be used in schema generation as directive args"() { + def sdl = ''' + directive @test(arg: MyType) on OBJECT + scalar MyType + type Test @test(arg: { some: "data" }){ + field: String + } + type Query { + field: Test + } + ''' + def runtimeWiring = RuntimeWiring.newRuntimeWiring().scalar(TestUtil.mockScalar("MyType")).build() + when: + def schema = TestUtil.schema(sdl, runtimeWiring) + then: + schema.getType("MyType") instanceof GraphQLScalarType + } + + def "1498 - order of arguments should not matter"() { + def sdl = ''' + input TimelineDimensionPredicate { + s : String + } + + input TimelineDimension { + d : String + } + + type TimelineEntriesGroup { + e : String + } + + interface Timeline { + id: ID! + entryGroups(groupBy: [TimelineDimension!]!, filter: TimelineDimensionPredicate): [TimelineEntriesGroup!]! + } + + type ActualSalesTimeline implements Timeline { + id: ID! + entryGroups(groupBy: [TimelineDimension!]!, filter: TimelineDimensionPredicate): [TimelineEntriesGroup!]! + } + + type Query { + salesTimeLine : Timeline + } + ''' + + when: + def schema = TestUtil.schema(sdl) + then: + assert1498Shape(schema) + + when: "The arg order has been rearranged" + sdl = ''' + input TimelineDimensionPredicate { + s : String + } + + input TimelineDimension { + d : String + } + + type TimelineEntriesGroup { + e : String + } + + interface Timeline { + id: ID! + entryGroups(filter: TimelineDimensionPredicate, groupBy: [TimelineDimension!]!): [TimelineEntriesGroup!]! + } + + type ActualSalesTimeline implements Timeline { + id: ID! + entryGroups(groupBy: [TimelineDimension!]!, filter: TimelineDimensionPredicate): [TimelineEntriesGroup!]! + } + + type Query { + salesTimeLine : Timeline + } + ''' + + schema = TestUtil.schema(sdl) + then: + assert1498Shape(schema) + + } + + static boolean assert1498Shape(GraphQLSchema schema) { + def actualSalesTL = schema.getObjectType("ActualSalesTimeline") + def entryGroupsField = actualSalesTL.getField("entryGroups") + def groupByArg = entryGroupsField.getArgument("groupBy") + def filterArg = entryGroupsField.getArgument("filter") + + GraphQLInputObjectType groupArgType = GraphQLTypeUtil.unwrapAllAs(groupByArg.getType()) + assert groupArgType.name == "TimelineDimension" + + GraphQLInputObjectType filterArgType = GraphQLTypeUtil.unwrapAllAs(filterArg.getType()) + assert filterArgType.name == "TimelineDimensionPredicate" + true + } + + + def "comments as descriptions disabled"() { + def sdl = ''' + type Query { + # Comment + test : String + "Description" + test2: String + } + ''' + when: + def registry = new SchemaParser().parse(sdl) + def options = defaultOptions().useCommentsAsDescriptions(false) + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) + + then: + schema.getQueryType().getFieldDefinition("test").getDescription() == null + schema.getQueryType().getFieldDefinition("test2").getDescription() == "Description" + } + + def "ast definition capture can be disabled"() { + def sdl = ''' + type Query { + test : String + } + + extend type Query { + test2 : Int + } + ''' + when: + def registry = new SchemaParser().parse(sdl) + def options = defaultOptions().captureAstDefinitions(false) + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) + + then: + schema.getQueryType().getDefinition() == null + schema.getQueryType().getExtensionDefinitions() == [] + schema.getQueryType().getFieldDefinition("test").getDefinition() == null + + when: + registry = new SchemaParser().parse(sdl) + options = defaultOptions() // default is to capture them + schema = new SchemaGenerator().makeExecutableSchema(options, registry, TestUtil.mockRuntimeWiring) + + then: + options.isCaptureAstDefinitions() + schema.getQueryType().getDefinition() != null + schema.getQueryType().getExtensionDefinitions().size() == 1 + schema.getQueryType().getFieldDefinition("test").getDefinition() != null + } + + + def "classCastException when interface extension is before base and has recursion"() { + given: + def spec = ''' + # order is important, moving extension below type Foo will fix the issue + extend type Foo implements HasFoo { + foo: Foo + } + + type Query { + test: ID + } + + interface HasFoo { + foo: Foo + } + + type Foo { + id: ID + } + ''' + + when: + TestUtil.schema(spec) + + then: + noExceptionThrown() + } + + def "skip and include should be added to the schema only if not already defined"() { + def sdl = ''' + "Directs the executor to skip this field or fragment when the `if`'argument is true." + directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + + "Directs the executor to include this field or fragment only when the `if` argument is true" + directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + + type Query { + hello: String + } + ''' + when: + def schema = TestUtil.schema(sdl) + then: + schema.getDirectives().findAll { it.name == "skip" }.size() == 1 + schema.getDirectives().findAll { it.name == "include" }.size() == 1 + + and: + def newSchema = GraphQLSchema.newSchema(schema).build() + then: + newSchema.getDirectives().findAll { it.name == "skip" }.size() == 1 + newSchema.getDirectives().findAll { it.name == "include" }.size() == 1 + } + + def "oneOf directive is available implicitly"() { + def sdl = ''' + type Query { + f(arg : OneOfInputType) : String + } + + input OneOfInputType @oneOf { + a : String + b : String + } + ''' + + when: + def schema = TestUtil.schema(sdl) + then: + schema.getDirectives().findAll { it.name == "oneOf" }.size() == 1 + + GraphQLInputObjectType inputObjectType = schema.getTypeAs("OneOfInputType") + inputObjectType.isOneOf() + inputObjectType.hasAppliedDirective("oneOf") + } } diff --git a/src/test/groovy/graphql/schema/idl/SchemaParserTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaParserTest.groovy index b319d56e72..762cce719f 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaParserTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaParserTest.groovy @@ -1,11 +1,16 @@ package graphql.schema.idl +import graphql.TestUtil import graphql.language.EnumTypeDefinition import graphql.language.InterfaceTypeDefinition import graphql.language.ObjectTypeDefinition import graphql.language.ScalarTypeDefinition +import graphql.parser.ParserOptions import graphql.schema.idl.errors.SchemaProblem import spock.lang.Specification +import spock.lang.Unroll + +import static graphql.schema.idl.SchemaPrinter.Options.defaultOptions /** * We don't want to retest the base GraphQL parser since it has its own testing @@ -28,7 +33,7 @@ class SchemaParserTest extends Specification { is_bar : Boolean } - type Baz implements Foo, Goo { + type Baz implements Foo & Goo { is_foo : Boolean is_goo : Boolean is_baz : Boolean @@ -113,7 +118,7 @@ class SchemaParserTest extends Specification { typeExtensions.size() == 1 typeExtensions.get("Query") != null - scalarTypes.size() == 11 // includes standard scalars + scalarTypes.size() == 6 // only contains the 5 graphql standard types and URL scalarTypes.get("Url") instanceof ScalarTypeDefinition @@ -164,9 +169,325 @@ class SchemaParserTest extends Specification { """ when: - TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(schema) + TypeDefinitionRegistry typeRegistry = read(schema) then: typeRegistry.types().size() == 4 } + def assertSchemaProblem(String s) { + try { + read(s) + assert false, "Expected a a schema problem for : " + s + } catch (SchemaProblem ignored) { + true + } + } + + def assertNoSchemaProblem(String s) { + try { + read(s) + true + } catch (SchemaProblem problem) { + assert false, "Did not expected a schema problem for : " + s + " of : " + problem + } + } + + + @Unroll + def "empty types (with and without parentheses) are allowed in '#schema'"() { + // + // empty parentheses are not quite allowed by the spec but in the name of backwards compatibility + // AND general usefulness we are going to allow them. So in the list below the last two of each section + // is not technically allowed by the latest spec + // + expect: + assertNoSchemaProblem(schema) + + where: + schema | _ + ''' type Foo ''' | _ + ''' type Foo @directive ''' | _ + ''' type Foo { } ''' | _ + ''' type Foo @directive { } ''' | _ + + ''' interface Foo ''' | _ + ''' interface Foo @directive ''' | _ + ''' interface Foo { } ''' | _ + ''' interface Foo @directive { } ''' | _ + + ''' input Foo ''' | _ + ''' input Foo @directive ''' | _ + ''' input Foo { } ''' | _ + ''' input Foo @directive { } ''' | _ + + ''' enum Foo ''' | _ + ''' enum Foo @directive ''' | _ + ''' enum Foo { } ''' | _ + ''' enum Foo @directive { } ''' | _ + + ''' union Foo ''' | _ + ''' union Foo @directive ''' | _ + + ''' scalar Foo ''' | _ // special case - has no innards + } + + + @Unroll + def "extensions are not allowed to be empty without directives in '#schema'"() { + + expect: + assertSchemaProblem(schema) + + where: + schema | _ + ''' extend type Foo''' | _ + ''' extend type Foo {}''' | _ + ''' extend interface Foo ''' | _ + ''' extend interface Foo {}''' | _ + ''' extend input Foo ''' | _ + ''' extend input Foo {}''' | _ + ''' extend enum Foo ''' | _ + ''' extend enum Foo {}''' | _ + ''' extend union Foo ''' | _ + ''' extend scalar Foo ''' | _ + } + + @Unroll + def "extensions are allowed to be empty with directives in '#schema'"() { + + expect: + assertNoSchemaProblem(schema) + + where: + schema | _ + ''' extend type Foo @d1 @d2 {}''' | _ + ''' extend interface Foo @d1 @d2 {}''' | _ + ''' extend input Foo @d1 @d2 {}''' | _ + ''' extend enum Foo @d1 @d2 {}''' | _ + ''' extend union Foo @d1 @d2 ''' | _ + ''' extend scalar Foo @d1 @d2 ''' | _ // special case - has no innards + } + + @Unroll + def "extensions must extend with fields or directives in '#schema'"() { + + expect: + assertNoSchemaProblem(schema) + + where: + schema | _ + ''' extend type Foo @directive''' | _ + ''' extend type Foo { f : Int }''' | _ + ''' extend type Foo @directive { f : Int }''' | _ + + ''' extend interface Foo @directive ''' | _ + ''' extend interface Foo { f : Int }''' | _ + ''' extend interface Foo { f : Int }''' | _ + + ''' extend input Foo @directive ''' | _ + ''' extend input Foo { f : Int }''' | _ + ''' extend input Foo { f : Int }''' | _ + + ''' extend enum Foo @directive ''' | _ + ''' extend enum Foo { a,b,c }''' | _ + ''' extend enum Foo @directive { a,b,c }''' | _ + + ''' extend union Foo @directive ''' | _ + ''' extend union Foo = | a | b | c''' | _ + ''' extend union Foo = a | b | c''' | _ + ''' extend union Foo @directive = | a | b | c''' | _ + ''' extend union Foo @directive = a | b | c''' | _ + + ''' extend scalar Foo @directive''' | _ // special case - has no innards + } + + def "1447 - non schema elements are detected"() { + def schema = ''' + + type Query { + allUsers: [User!]! + } + + type User { + name: String! + age: Int! + } + + { + allUsers { + ... addressDetails + } + } + + fragment addressDetails on User { + name + age + } + + mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { + createReview(episode: $ep, review: $review) { + stars + commentary + } + } + + ''' + when: + read(schema) + then: + def schemaProblem = thrown(SchemaProblem) + schemaProblem.getErrors().size() == 3 + schemaProblem.getErrors()[0].getMessage().contains("OperationDefinition") + schemaProblem.getErrors()[1].getMessage().contains("FragmentDefinition") + schemaProblem.getErrors()[2].getMessage().contains("OperationDefinition") + } + + def "large schema files can be parsed - there is no limit"() { + def sdl = "type Query {\n" + for (int i = 0; i < 30000; i++) { + sdl += " f" + i + " : ID\n" + sdl += " " * 10 // 10 whitespace as well + } + sdl += "}" + + when: + def typeDefinitionRegistry = new SchemaParser().parse(sdl) + then: + typeDefinitionRegistry != null + + + when: "options are used they will be respected" + def options = ParserOptions.defaultParserOptions.transform({ it.maxTokens(100) }) + new SchemaParser().parse(new StringReader(sdl), options) + then: + def e = thrown(SchemaProblem) + e.errors[0].message.contains("parsing has been cancelled") + + } + + def "correctly parses schema keyword block, include Query, does not include Mutation type"() { + // From RFC to clarify spec https://github.com/graphql/graphql-spec/pull/987 + when: + def schema = """schema { + query: Query +} + +type Mutation { + geneSequence: String! + name: String! +} + +type Query { + viruses: [Virus!] +} + +type Virus { + knownMutations: [Mutation!]! + name: String! +} +""" + def graphQL = TestUtil.graphQL(schema).build() + + then: + graphQL.graphQLSchema.definition.operationTypeDefinitions.size() == 1 + graphQL.graphQLSchema.definition.operationTypeDefinitions.first().name == "query" + graphQL.graphQLSchema.queryType != null + graphQL.graphQLSchema.mutationType == null + + when: + // Verify that the printed schema is the same as the original + def options = defaultOptions() + .includeIntrospectionTypes(false) + .includeScalarTypes(false) + .includeDirectiveDefinitions(false) + .includeSchemaDefinition(true) + + then: + def printedSchema = new SchemaPrinter(options).print(graphQL.graphQLSchema) + printedSchema == schema + } + + def "correctly parses schema keyword block, include Query, does not include Subscription type"() { + // From RFC to clarify spec https://github.com/graphql/graphql-spec/pull/987 + when: + def schema = """schema { + query: Query +} + +type Query { + viruses: [Virus!] +} + +type Subscription { + newspaper: String! +} + +type Virus { + name: String! +} +""" + def graphQL = TestUtil.graphQL(schema).build() + + then: + graphQL.graphQLSchema.definition.operationTypeDefinitions.size() == 1 + graphQL.graphQLSchema.definition.operationTypeDefinitions.first().name == "query" + graphQL.graphQLSchema.queryType != null + graphQL.graphQLSchema.subscriptionType == null + + when: + // Verify that the printed schema is the same as the original + def options = defaultOptions() + .includeIntrospectionTypes(false) + .includeScalarTypes(false) + .includeDirectiveDefinitions(false) + .includeSchemaDefinition(true) + + then: + def printedSchema = new SchemaPrinter(options).print(graphQL.graphQLSchema) + printedSchema == schema + } + + def "correctly parses schema that does not contain a schema definition block, includes Query and Mutation types"() { + when: + def schema = """type Mutation { + geneSequence: String! + name: String! +} + +type Query { + viruses: [Virus!] +} + +type Virus { + name: String! +} +""" + def graphQL = TestUtil.graphQL(schema).build() + + then: + graphQL.graphQLSchema.definition == null // No SchemaDefinition + graphQL.graphQLSchema.queryType != null + graphQL.graphQLSchema.mutationType != null + + when: + // Verify that the printed schema is the same as the original + def options = defaultOptions() + .includeIntrospectionTypes(false) + .includeScalarTypes(false) + .includeDirectiveDefinitions(false) + + then: + def printedSchema = new SchemaPrinter(options).print(graphQL.graphQLSchema) + printedSchema == schema + } + + def "testNumberFormatException"() { + when: + SchemaParser parser = new SchemaParser(); + parser.parse("{B(t:66E3333333320,t:#\n66666666660)},622»» »»»6666662}}6666660t:z6666") + + then: + thrown(SchemaProblem) + } + } diff --git a/src/test/groovy/graphql/schema/idl/SchemaPrinterTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaPrinterTest.groovy index ad3f8019e5..2870244328 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaPrinterTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaPrinterTest.groovy @@ -1,46 +1,75 @@ package graphql.schema.idl import graphql.GraphQL -import graphql.Scalars import graphql.TestUtil import graphql.TypeResolutionEnvironment +import graphql.introspection.Introspection import graphql.introspection.IntrospectionQuery import graphql.introspection.IntrospectionResultToSchema +import graphql.language.Comment +import graphql.language.DirectiveDefinition +import graphql.language.EnumValueDefinition +import graphql.language.FieldDefinition +import graphql.language.IntValue +import graphql.language.ScalarTypeDefinition +import graphql.language.SchemaDefinition +import graphql.language.StringValue import graphql.schema.Coercing -import graphql.schema.GraphQLArgument +import graphql.schema.GraphQLAppliedDirective +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLDirective import graphql.schema.GraphQLEnumType +import graphql.schema.GraphQLEnumValueDefinition import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLInputObjectType import graphql.schema.GraphQLInputType import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLNamedSchemaElement import graphql.schema.GraphQLObjectType -import graphql.schema.GraphQLOutputType import graphql.schema.GraphQLScalarType import graphql.schema.GraphQLSchema +import graphql.schema.GraphQLSchemaElement import graphql.schema.GraphQLType import graphql.schema.GraphQLUnionType +import graphql.schema.GraphqlTypeComparatorRegistry +import graphql.schema.GraphqlTypeComparators import graphql.schema.TypeResolver import spock.lang.Specification -import java.util.Collections +import java.util.function.Predicate import java.util.function.UnaryOperator +import java.util.stream.Collectors +import static graphql.Scalars.GraphQLID +import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString -import static graphql.TestUtil.mockDirective import static graphql.TestUtil.mockScalar import static graphql.TestUtil.mockTypeRuntimeWiring +import static graphql.language.EnumTypeDefinition.newEnumTypeDefinition +import static graphql.language.InputObjectTypeDefinition.newInputObjectDefinition +import static graphql.language.InputValueDefinition.newInputValueDefinition +import static graphql.language.InterfaceTypeDefinition.newInterfaceTypeDefinition +import static graphql.language.ObjectTypeDefinition.newObjectTypeDefinition +import static graphql.language.UnionTypeDefinition.newUnionTypeDefinition import static graphql.schema.GraphQLArgument.newArgument +import static graphql.schema.GraphQLEnumType.newEnum import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLInputObjectField.newInputObjectField import static graphql.schema.GraphQLInterfaceType.newInterface import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLScalarType.newScalar +import static graphql.schema.GraphQLTypeReference.typeRef +import static graphql.schema.GraphQLUnionType.newUnionType import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring +import static graphql.schema.idl.SchemaPrinter.ExcludeGraphQLSpecifiedDirectivesPredicate import static graphql.schema.idl.SchemaPrinter.Options.defaultOptions class SchemaPrinterTest extends Specification { + def noDirectivesOption = defaultOptions().includeDirectives(false) + GraphQLSchema starWarsSchema() { def wiring = newRuntimeWiring() .type("Character", { type -> type.typeResolver(resolver) } as UnaryOperator) @@ -52,7 +81,7 @@ class SchemaPrinterTest extends Specification { } - GraphQLScalarType ASTEROID = new GraphQLScalarType("Asteroid", "desc", new Coercing() { + GraphQLScalarType ASTEROID = newScalar().name("Asteroid").description("desc").coercing(new Coercing() { @Override Object serialize(Object input) { throw new UnsupportedOperationException("Not implemented") @@ -68,6 +97,7 @@ class SchemaPrinterTest extends Specification { throw new UnsupportedOperationException("Not implemented") } }) + .build() def resolver = new TypeResolver() { @@ -77,31 +107,31 @@ class SchemaPrinterTest extends Specification { } } - static class MyGraphQLObjectType extends GraphQLObjectType { - - MyGraphQLObjectType(String name, String description, List fieldDefinitions) { - super(name, description, fieldDefinitions, new ArrayList()) - } - } - def "typeString"() { - GraphQLType type1 = nonNull(list(nonNull(list(nonNull(Scalars.GraphQLInt))))) - GraphQLType type2 = nonNull(nonNull(list(nonNull(Scalars.GraphQLInt)))) + GraphQLType type1 = nonNull(list(nonNull(list(nonNull(GraphQLInt))))) def typeStr1 = new SchemaPrinter().typeString(type1) - def typeStr2 = new SchemaPrinter().typeString(type2) expect: typeStr1 == "[[Int!]!]!" - typeStr2 == "[Int!]!!" - } def "argsString"() { - def argument1 = new GraphQLArgument("arg1", null, list(nonNull(Scalars.GraphQLInt)), 10) - def argument2 = new GraphQLArgument("arg2", null, GraphQLString, null) - def argument3 = new GraphQLArgument("arg3", null, GraphQLString, "default") + def argument1 = newArgument() + .name("arg1") + .type(list(nonNull(GraphQLInt))) + .defaultValueLiteral(IntValue.newIntValue().value(10).build()) + .build() + def argument2 = newArgument() + .name("arg2") + .type(GraphQLString) + .build() + def argument3 = newArgument() + .name("arg3") + .type(GraphQLString) + .defaultValueLiteral(StringValue.newStringValue().value("default").build()) + .build() def argStr = new SchemaPrinter().argsString([argument1, argument2, argument3]) expect: @@ -110,9 +140,20 @@ class SchemaPrinterTest extends Specification { } def "argsString_sorts"() { - def argument1 = new GraphQLArgument("arg1", null, list(nonNull(Scalars.GraphQLInt)), 10) - def argument2 = new GraphQLArgument("arg2", null, GraphQLString, null) - def argument3 = new GraphQLArgument("arg3", null, GraphQLString, "default") + def argument1 = newArgument() + .name("arg1") + .type(list(nonNull(GraphQLInt))) + .defaultValueLiteral(IntValue.newIntValue().value(10).build()) + .build() + def argument2 = newArgument() + .name("arg2") + .type(GraphQLString) + .build() + def argument3 = newArgument() + .name("arg3") + .type(GraphQLString) + .defaultValueLiteral(StringValue.newStringValue().value("default").build()) + .build() def argStr = new SchemaPrinter().argsString([argument2, argument1, argument3]) expect: @@ -120,6 +161,34 @@ class SchemaPrinterTest extends Specification { argStr == "(arg1: [Int!] = 10, arg2: String, arg3: String = \"default\")" } + def "argsString_comments"() { + def argument1 = newArgument() + .name("arg1") + .description("A multiline\ncomment") + .type(list(nonNull(GraphQLInt))) + .defaultValueLiteral(IntValue.newIntValue().value(10).build()) + .build() + def argument2 = newArgument() + .name("arg2") + .description("A single line comment") + .type(list(nonNull(GraphQLInt))) + .defaultValueLiteral(IntValue.newIntValue().value(10).build()) + .build() + def argStr = new SchemaPrinter().argsString([argument1, argument2]) + + expect: + + argStr == '''( + """ + A multiline + comment + """ + arg1: [Int!] = 10, + "A single line comment" + arg2: [Int!] = 10 + )''' + } + def "print type direct"() { GraphQLSchema schema = starWarsSchema() @@ -133,7 +202,6 @@ class SchemaPrinterTest extends Specification { id: ID! name: String! } - """ } @@ -144,7 +212,6 @@ class SchemaPrinterTest extends Specification { expect: result != null - !result.contains("scalar") !result.contains("__TypeKind") } @@ -179,7 +246,7 @@ class SchemaPrinterTest extends Specification { """) - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) expect: result == """type Mutation { @@ -212,7 +279,8 @@ type Subscription { """) def options = defaultOptions() - .includeSchemaDefintion(true) + .includeDirectives(false) + .includeSchemaDefinition(true) def result = new SchemaPrinter(options).print(schema) @@ -261,7 +329,7 @@ type Subscription { """) - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) expect: result == """schema { @@ -288,46 +356,50 @@ type Subscription { given: GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").type(GraphQLString).build() - def queryType = GraphQLObjectType.newObject().name("Query").description("About Query\nSecond Line").field(fieldDefinition).build() + def queryType = newObject().name("Query").description("About Query\nSecond Line").field(fieldDefinition).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """#About Query -#Second Line + result == '''""" +About Query +Second Line +""" type Query { field: String } -""" +''' } def "prints field description as comment"() { given: GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").description("About field\nsecond").type(GraphQLString).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """type Query { - #About field - #second + result == '''type Query { + """ + About field + second + """ field: String } -""" +''' } def "does not print empty field description as comment"() { given: GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").description("").type(GraphQLString).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: result == """type Query { @@ -338,29 +410,29 @@ type Query { def "prints enum description as comment"() { given: - GraphQLEnumType graphQLEnumType = GraphQLEnumType.newEnum() + GraphQLEnumType graphQLEnumType = newEnum() .name("Enum") .description("About enum") .value("value", "value", "value desc") .build() GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").type(graphQLEnumType).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """type Query { + result == '''type Query { field: Enum } -#About enum +"About enum" enum Enum { - #value desc + "value desc" value } -""" +''' } @@ -368,22 +440,29 @@ enum Enum { given: GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").type(GraphQLString).build() - def possibleType = GraphQLObjectType.newObject().name("PossibleType").field(fieldDefinition).build() - GraphQLUnionType unionType = GraphQLUnionType.newUnionType() + def possibleType = newObject().name("PossibleType").field(fieldDefinition).build() + GraphQLUnionType unionType = newUnionType() .name("Union") .description("About union") .possibleType(possibleType) - .typeResolver({ it -> null }) .build() GraphQLFieldDefinition fieldDefinition2 = newFieldDefinition() .name("field").type(unionType).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition2).build() - def schema = GraphQLSchema.newSchema().query(queryType).build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(unionType, { it -> null }) + .build() + def queryType = newObject().name("Query").field(fieldDefinition2).build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(queryType) + .build() + when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """#About union + result == '''"About union" union Union = PossibleType type PossibleType { @@ -393,29 +472,36 @@ type PossibleType { type Query { field: Union } -""" +''' } def "prints union"() { - def possibleType1 = GraphQLObjectType.newObject().name("PossibleType1").field( + def possibleType1 = newObject().name("PossibleType1").field( newFieldDefinition().name("field").type(GraphQLString).build() ).build() - def possibleType2 = GraphQLObjectType.newObject().name("PossibleType2").field( + def possibleType2 = newObject().name("PossibleType2").field( newFieldDefinition().name("field").type(GraphQLString).build() ).build() - GraphQLUnionType unionType = GraphQLUnionType.newUnionType() + GraphQLUnionType unionType = newUnionType() .name("Union") .possibleType(possibleType1) .possibleType(possibleType2) - .typeResolver({ it -> null }) .build() GraphQLFieldDefinition fieldDefinition2 = newFieldDefinition() .name("field").type(unionType).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition2).build() - def schema = GraphQLSchema.newSchema().query(queryType).build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(unionType, { it -> null }) + .build() + def queryType = newObject().name("Query").field(fieldDefinition2).build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(queryType) + .build() + when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: result == """union Union = PossibleType1 | PossibleType2 @@ -446,22 +532,22 @@ type Query { .name("field") .argument(newArgument().name("arg").type(inputType).build()) .type(GraphQLString).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition2).build() + def queryType = newObject().name("Query").field(fieldDefinition2).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """type Query { + result == '''type Query { field(arg: Input): String } -#About input +"About input" input Input { - #about field + "about field" field: String } -""" +''' } @@ -471,31 +557,38 @@ input Input { .name("Interface") .description("about interface") .field(newFieldDefinition().name("field").description("about field").type(GraphQLString).build()) - .typeResolver({ it -> null }) .build() GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").type(graphQLInterfaceType).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition).build() - def schema = GraphQLSchema.newSchema().query(queryType).build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(graphQLInterfaceType, { it -> null }) + .build() + def queryType = newObject().name("Query").field(fieldDefinition).build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(queryType) + .build() + when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """#about interface + result == '''"about interface" interface Interface { - #about field + "about field" field: String } type Query { field: Interface } -""" +''' } def "prints scalar description as comment"() { given: - GraphQLScalarType myScalar = new GraphQLScalarType("Scalar", "about scalar", new Coercing() { + GraphQLScalarType myScalar = newScalar().name("Scalar").description("about scalar").coercing(new Coercing() { @Override Object serialize(Object input) { return null @@ -511,21 +604,22 @@ type Query { return null } }) + .build() GraphQLFieldDefinition fieldDefinition = newFieldDefinition() .name("field").type(myScalar).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter(defaultOptions().includeScalarTypes(true)).print(schema) + def result = new SchemaPrinter(defaultOptions().includeScalarTypes(true).includeDirectives(false)).print(schema) then: - result == """type Query { + result == '''type Query { field: Scalar } -#about scalar +"about scalar" scalar Scalar -""" +''' } def "special formatting for argument descriptions"() { @@ -535,79 +629,121 @@ scalar Scalar .argument(newArgument().name("arg2").type(GraphQLString).build()) .argument(newArgument().name("arg3").description("about 3\nsecond line").type(GraphQLString).build()) .type(GraphQLString).build() - def queryType = GraphQLObjectType.newObject().name("Query").field(fieldDefinition2).build() + def queryType = newObject().name("Query").field(fieldDefinition2).build() def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """type Query { + result == '''type Query { field( - #about arg1 - arg1: String, - arg2: String, - #about 3 - #second line - arg3: String + "about arg1" + arg1: String, + arg2: String, + """ + about 3 + second line + """ + arg3: String ): String } -""" +''' } - def "prints derived object type"() { + def "prints type"() { given: - GraphQLFieldDefinition fieldDefinition = newFieldDefinition().name("field").type(GraphQLString).build() - def queryType = new MyGraphQLObjectType("Query", "About Query\nSecond Line", Arrays.asList(fieldDefinition)) - def schema = GraphQLSchema.newSchema().query(queryType).build() + def inputObjectType = GraphQLInputObjectType.newInputObject() + .name("inputObjectType") + .field(newInputObjectField().name("field").type(GraphQLString).build()) + .build() + def objectType = newObject() + .name("objectType") + .field(newFieldDefinition().name("field").type(GraphQLString).build()) + .build() + def argument = newArgument().name("arg").type(inputObjectType).build() + GraphQLFieldDefinition field1 = newFieldDefinition().name("field1").type(objectType).argument(argument).build() + + def interfaceType = newInterface() + .name("interfaceType") + .field(newFieldDefinition().name("field").type(GraphQLString).build()) + .build() + def objectWithInterface = newObject() + .name("objectWithInterface") + .field(newFieldDefinition().name("field").type(GraphQLString).build()) + .withInterface(interfaceType) + .build() + GraphQLFieldDefinition field2 = newFieldDefinition() + .name("field2") + .type(objectWithInterface) + .build() + + def enumType = newEnum() + .name("enumType") + .value(GraphQLEnumValueDefinition.newEnumValueDefinition().name("GraphQLEnumValueDefinition").build()) + .build() + GraphQLFieldDefinition field3 = newFieldDefinition() + .name("field3") + .type(enumType) + .build() + def queryType = newObject().name("Query").field(field1).field(field2).field(field3).build() + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry().typeResolver(interfaceType, { env -> null }).build() + def schema = GraphQLSchema.newSchema().query(queryType).codeRegistry(codeRegistry).build() when: - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - result == """#About Query -#Second Line + result == '''interface interfaceType { + field: String +} + type Query { + field1(arg: inputObjectType): objectType + field2: objectWithInterface + field3: enumType +} + +type objectType { field: String } -""" + +type objectWithInterface implements interfaceType { + field: String +} + +enum enumType { + GraphQLEnumValueDefinition +} + +input inputObjectType { + field: String +} +''' } - def "prints extended types"() { + def "arrayIndexOutOfBoundsException should not occur if a field description of only a newline is passed"() { given: - def idl = ''' - type Query { - field : CustomScalar - bigDecimal : BigDecimal - } - - scalar CustomScalar - ''' - - def schema = TestUtil.schema(idl, newRuntimeWiring().scalar(mockScalar("CustomScalar"))) + GraphQLFieldDefinition fieldDefinition = newFieldDefinition() + .name("field") + .description("\n") + .type(GraphQLString) + .build() + def queryType = newObject().name("Query").description("test").field(fieldDefinition).build() + def schema = GraphQLSchema.newSchema().query(queryType).build() when: - def result = new SchemaPrinter(options).print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) then: - - if (expectedStrs.isEmpty()) { - assert !result.contains("scalar") - } else { - expectedStrs.forEach({ s -> assert result.contains(s) }) - } - - - where: - expectedStrs | options - [] | defaultOptions() - ["scalar CustomScalar"] | defaultOptions().includeScalarTypes(true).includeExtendedScalarTypes(false) - ["scalar BigDecimal", "scalar CustomScalar"] | defaultOptions().includeScalarTypes(true).includeExtendedScalarTypes(true) - ["scalar CustomScalar"] | defaultOptions().includeScalarTypes(true).includeExtendedScalarTypes(false) + result == '''"test" +type Query { + field: String +} +''' } - def "schema will be sorted"() { def schema = TestUtil.schema(""" type Query { @@ -632,7 +768,7 @@ type Query { """) - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) expect: result == """type Query { @@ -666,7 +802,7 @@ type TypeE { def schemaDefinition = new IntrospectionResultToSchema().createSchemaDefinition(executionResult) - def result = new SchemaPrinter().print(schemaDefinition) + def result = new SchemaPrinter(noDirectivesOption).print(schemaDefinition) expect: result == @@ -719,6 +855,9 @@ enum Episode { JEDI NEWHOPE } + +"desc" +scalar Asteroid """ } @@ -726,7 +865,9 @@ enum Episode { def "AST doc string entries are printed if present"() { def schema = TestUtil.schema(''' # comments up here - """docstring""" + """ + doc + string""" # and comments as well down here type Query { "field single desc" @@ -735,10 +876,13 @@ enum Episode { ''') - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(noDirectivesOption).print(schema) expect: - result == '''"""docstring""" + result == '''""" +doc + string +""" type Query { "field single desc" field: String @@ -746,10 +890,26 @@ type Query { ''' } - - def "directives will be printed"() { - given: - def idl = """ + def idlWithDirectives() { + return """ + directive @interfaceFieldDirective on FIELD_DEFINITION + directive @unionTypeDirective on UNION + directive @query1 repeatable on OBJECT + directive @query2(arg1: String) on OBJECT + directive @fieldDirective1 on FIELD_DEFINITION + directive @fieldDirective2(argStr: String, argInt: Int, argFloat: Float, argBool: Boolean) on FIELD_DEFINITION + directive @argDirective on ARGUMENT_DEFINITION + directive @interfaceImplementingTypeDirective on OBJECT + directive @enumTypeDirective on ENUM + directive @single on OBJECT + directive @singleField on FIELD_DEFINITION + directive @interfaceImplementingFieldDirective on FIELD_DEFINITION + directive @enumValueDirective on ENUM_VALUE + directive @inputTypeDirective on INPUT_OBJECT + directive @inputFieldDirective on INPUT_FIELD_DEFINITION + directive @interfaceTypeDirective on INTERFACE + directive @scalarDirective on SCALAR + directive @repeatableDirective repeatable on SCALAR interface SomeInterface @interfaceTypeDirective { fieldA : String @interfaceFieldDirective @@ -763,6 +923,7 @@ type Query { fieldC : SomeEnum fieldD : SomeInterface fieldE : SomeUnion + fieldF(argWithDirective: String @argDirective): String } type Single @single { @@ -777,19 +938,24 @@ type Query { SOME_ENUM_VALUE @enumValueDirective } - scalar SomeScalar @scalarDirective + scalar SomeScalar @scalarDirective @repeatableDirective @repeatableDirective input SomeInput @inputTypeDirective { fieldA : String @inputFieldDirective } """ - def registry = new SchemaParser().parse(idl) + } + + + def "directives will be printed with the includeDirectives flag set"() { + given: + def registry = new SchemaParser().parse(idlWithDirectives()) def runtimeWiring = newRuntimeWiring() - .scalar(mockScalar(registry.scalars().get("SomeScalar"))) - .type(mockTypeRuntimeWiring("SomeInterface", true)) - .type(mockTypeRuntimeWiring("SomeUnion", true)) - .build() - def options = SchemaGenerator.Options.defaultOptions().enforceSchemaDirectives(false) + .scalar(mockScalar(registry.scalars().get("SomeScalar"))) + .type(mockTypeRuntimeWiring("SomeInterface", true)) + .type(mockTypeRuntimeWiring("SomeUnion", true)) + .build() + def options = SchemaGenerator.Options.defaultOptions() def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) when: @@ -797,7 +963,81 @@ type Query { then: // args and directives are sorted like the rest of the schema printer - result == '''interface SomeInterface @interfaceTypeDirective { + result == '''directive @argDirective on ARGUMENT_DEFINITION + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +directive @enumTypeDirective on ENUM + +directive @enumValueDirective on ENUM_VALUE + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +directive @fieldDirective1 on FIELD_DEFINITION + +directive @fieldDirective2(argBool: Boolean, argFloat: Float, argInt: Int, argStr: String) on FIELD_DEFINITION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +directive @inputFieldDirective on INPUT_FIELD_DEFINITION + +directive @inputTypeDirective on INPUT_OBJECT + +directive @interfaceFieldDirective on FIELD_DEFINITION + +directive @interfaceImplementingFieldDirective on FIELD_DEFINITION + +directive @interfaceImplementingTypeDirective on OBJECT + +directive @interfaceTypeDirective on INTERFACE + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +directive @query1 repeatable on OBJECT + +directive @query2(arg1: String) on OBJECT + +directive @repeatableDirective repeatable on SCALAR + +directive @scalarDirective on SCALAR + +directive @single on OBJECT + +directive @singleField on FIELD_DEFINITION + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +directive @unionTypeDirective on UNION + +interface SomeInterface @interfaceTypeDirective { fieldA: String @interfaceFieldDirective } @@ -809,6 +1049,7 @@ type Query @query1 @query2(arg1 : "x") { fieldC: SomeEnum fieldD: SomeInterface fieldE: SomeUnion + fieldF(argWithDirective: String @argDirective): String } type Single @single { @@ -823,13 +1064,2037 @@ enum SomeEnum @enumTypeDirective { SOME_ENUM_VALUE @enumValueDirective } -scalar SomeScalar @scalarDirective +scalar SomeScalar @repeatableDirective @repeatableDirective @scalarDirective input SomeInput @inputTypeDirective { fieldA: String @inputFieldDirective } +''' + when: + def resultNoDirectives = new SchemaPrinter(defaultOptions() + .includeScalarTypes(true) + .includeDirectives(false)) + .print(schema) + + then: + // args and directives are sorted like the rest of the schema printer + resultNoDirectives == '''interface SomeInterface { + fieldA: String +} + +union SomeUnion = Single | SomeImplementingType + +type Query { + fieldA: String + fieldB(input: SomeInput): SomeScalar + fieldC: SomeEnum + fieldD: SomeInterface + fieldE: SomeUnion + fieldF(argWithDirective: String): String +} + +type Single { + fieldA: String +} + +type SomeImplementingType implements SomeInterface { + fieldA: String +} + +enum SomeEnum { + SOME_ENUM_VALUE +} + +scalar SomeScalar + +input SomeInput { + fieldA: String +} +''' + } + + + def "directives with default values are printed correctly"() { + given: + def idl = """ + + type Field { + active : Enum + deprecated : Enum @deprecated + deprecatedWithReason : Enum @deprecated(reason : "Custom reason 1") + deprecatedFieldArgument( arg1 : String, arg2 : Int @deprecated) : Enum + deprecatedFieldArgumentWithReason( arg1 : String, arg2 : Int @deprecated(reason : "Custom arg reason 1")) : Enum + } + + type Query { + field : Field + } + + enum Enum { + ACTIVE + DEPRECATED @deprecated + DEPRECATED_WITH_REASON @deprecated(reason : "Custom reason 2") + } + + input Input { + active : Enum + deprecated : Enum @deprecated + deprecatedWithReason : Enum @deprecated(reason : "Custom reason 3") + } + """ + def registry = new SchemaParser().parse(idl) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def result = new SchemaPrinter(defaultOptions().includeScalarTypes(true)).print(schema) + + then: + // args and directives are sorted like the rest of the schema printer + result == '''"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type Field { + active: Enum + deprecated: Enum @deprecated(reason : "No longer supported") + deprecatedFieldArgument(arg1: String, arg2: Int @deprecated(reason : "No longer supported")): Enum + deprecatedFieldArgumentWithReason(arg1: String, arg2: Int @deprecated(reason : "Custom arg reason 1")): Enum + deprecatedWithReason: Enum @deprecated(reason : "Custom reason 1") +} + +type Query { + field: Field +} + +enum Enum { + ACTIVE + DEPRECATED @deprecated(reason : "No longer supported") + DEPRECATED_WITH_REASON @deprecated(reason : "Custom reason 2") +} + +input Input { + active: Enum + deprecated: Enum @deprecated(reason : "No longer supported") + deprecatedWithReason: Enum @deprecated(reason : "Custom reason 3") +} +''' + } + + + def "directives are printed as top level types when the includeDirectives flag is set"() { + def simpleIdlWithDirective = ''' + directive @example on FIELD_DEFINITION + + directive @moreComplex(arg1 : String = "default", arg2 : Int) + on FIELD_DEFINITION | + INPUT_FIELD_DEFINITION + + type Query { + fieldA : String @example @moreComplex(arg2 : 666) + } + ''' + given: + def registry = new SchemaParser().parse(simpleIdlWithDirective) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def resultWithNoDirectives = new SchemaPrinter(defaultOptions().includeDirectives(false)).print(schema) + + then: + resultWithNoDirectives == '''type Query { + fieldA: String +} +''' + + when: + def resultWithSomeDirectives = new SchemaPrinter(defaultOptions().includeDirectives({ it == "example" })).print(schema) + + then: + resultWithSomeDirectives == '''directive @example on FIELD_DEFINITION + +type Query { + fieldA: String @example +} +''' + + when: + def resultWithDirectives = new SchemaPrinter(defaultOptions().includeDirectives(true)).print(schema) + + then: + resultWithDirectives == '''"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +directive @example on FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +directive @moreComplex(arg1: String = "default", arg2: Int) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type Query { + fieldA: String @example @moreComplex(arg1 : "default", arg2 : 666) +} ''' } + def "directive definitions are not printed when the includeDirectiveDefinitions flag is set to false"() { + def simpleIdlWithDirective = ''' + directive @example on FIELD_DEFINITION + + directive @moreComplex(arg1 : String = "default", arg2 : Int) + on FIELD_DEFINITION | + INPUT_FIELD_DEFINITION + + type Query { + fieldA : String @example @moreComplex(arg2 : 666) + } + ''' + given: + def registry = new SchemaParser().parse(simpleIdlWithDirective) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def resultWithNoDirectiveDefinitions = new SchemaPrinter(defaultOptions().includeDirectiveDefinitions(false)).print(schema) + + then: + resultWithNoDirectiveDefinitions == '''type Query { + fieldA: String @example @moreComplex(arg1 : "default", arg2 : 666) +} +''' + + when: + def resultWithDirectiveDefinitions = new SchemaPrinter(defaultOptions().includeDirectiveDefinitions(true)).print(schema) + + then: + resultWithDirectiveDefinitions == '''"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +directive @example on FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +directive @moreComplex(arg1: String = "default", arg2: Int) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type Query { + fieldA: String @example @moreComplex(arg1 : "default", arg2 : 666) +} +''' + } + + def "can print extend schema block when AST printing enabled"() { + def sdl = ''' + directive @schemaDirective on SCHEMA + + """ + My schema block description + """ + schema { + mutation: MyMutation + } + + extend schema @schemaDirective { + query: MyQuery + } + + extend schema { + subscription: MySubscription + } + + type MyQuery { + foo: String + } + + type MyMutation { + pizza: String + } + + type MySubscription { + chippies: String + } + ''' + + when: + def runtimeWiring = newRuntimeWiring().build() + + def options = SchemaGenerator.Options.defaultOptions() + def types = new SchemaParser().parse(sdl) + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(options, types, runtimeWiring) + + def printOptions = defaultOptions() + .useAstDefinitions(true) + .includeSchemaDefinition(true) + def result = new SchemaPrinter(printOptions).print(schema) + + then: + result == '''""" +My schema block description +""" +schema { + mutation: MyMutation +} + +extend schema @schemaDirective { + query: MyQuery +} + +extend schema { + subscription: MySubscription +} + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +directive @schemaDirective on SCHEMA + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type MyMutation { + pizza: String +} + +type MyQuery { + foo: String +} + +type MySubscription { + chippies: String +} +''' + } + + def "will not print extend schema block when AST printing not enabled"() { + def sdl = ''' + directive @schemaDirective on SCHEMA + + """ + My schema block description + """ + schema { + mutation: MyMutation + } + + extend schema @schemaDirective { + query: MyQuery + } + + type MyQuery { + foo: String + } + + type MyMutation { + pizza: String + } + ''' + + when: + def runtimeWiring = newRuntimeWiring().build() + + def options = SchemaGenerator.Options.defaultOptions() + def types = new SchemaParser().parse(sdl) + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(options, types, runtimeWiring) + + def printOptions = defaultOptions() + .useAstDefinitions(false) + .includeSchemaDefinition(true) + def result = new SchemaPrinter(printOptions).print(schema) + + then: + result == '''"My schema block description" +schema @schemaDirective{ + query: MyQuery + mutation: MyMutation +} + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +directive @schemaDirective on SCHEMA + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type MyMutation { + pizza: String +} + +type MyQuery { + foo: String +} +''' + } + + def "can print a schema as AST elements"() { + def sdl = ''' + directive @directive1 on SCALAR + + type Query { + foo : String + } + + extend type Query { + bar : String + } + + extend type Query { + baz : String + } + + enum Enum { + A + } + + extend enum Enum { + B + } + + interface Interface { + foo : String + } + + extend interface Interface { + bar : String + } + + extend interface Interface { + baz : String + } + + type Foo { + foo : String + } + + type Bar { + bar : Scalar + } + + union Union = Foo + + extend union Union = Bar + + input Input { + foo: String + } + + extend input Input { + bar: String + } + + extend input Input { + baz: String + } + + extend input Input { + faz: String + } + + scalar Scalar + + extend scalar Scalar @directive1 + ''' + + + when: + def wiringFactory = new MockedWiringFactory() { + @Override + boolean providesScalar(ScalarWiringEnvironment env) { + return env.getScalarTypeDefinition().getName() == "Scalar" + } + + @Override + GraphQLScalarType getScalar(ScalarWiringEnvironment env) { + def definition = env.getScalarTypeDefinition() + return newScalar() + .name(definition.getName()) + .definition(definition) + .extensionDefinitions(env.getExtensions()) + .coercing(TestUtil.mockCoercing()) + .build() + } + } + + def runtimeWiring = newRuntimeWiring() + .wiringFactory(wiringFactory) + .build() + + def options = SchemaGenerator.Options.defaultOptions() + def types = new SchemaParser().parse(sdl) + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(options, types, runtimeWiring) + + def printOptions = defaultOptions().includeScalarTypes(true).useAstDefinitions(true) + def result = new SchemaPrinter(printOptions).print(schema) + + then: + result == '''"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +directive @directive1 on SCALAR + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +interface Interface { + foo: String +} + +extend interface Interface { + bar: String +} + +extend interface Interface { + baz: String +} + +union Union = Foo + +extend union Union = Bar + +type Bar { + bar: Scalar +} + +type Foo { + foo: String +} + +type Query { + foo: String +} + +extend type Query { + bar: String +} + +extend type Query { + baz: String +} + +enum Enum { + A +} + +extend enum Enum { + B +} + +scalar Scalar + +extend scalar Scalar @directive1 + +input Input { + foo: String +} + +extend input Input { + bar: String +} + +extend input Input { + baz: String +} + +extend input Input { + faz: String +} +''' + + when: + // we can print by direct type using AST + def queryType = schema.getType("Query") + result = new SchemaPrinter(printOptions).print(queryType) + + then: + result == '''type Query { + foo: String +} + +extend type Query { + bar: String +} + +extend type Query { + baz: String +} +''' + } + + def "@deprecated directives are NOT always printed - they used to be"() { + given: + def idl = """ + + directive @example on FIELD_DEFINITION + + type Field { + deprecated : Enum @deprecated + } + + type Query { + field : Field + } + + enum Enum { + enumVal @deprecated + } + + input Input { + deprecated : String @deprecated(reason : "custom reason") + } + """ + def registry = new SchemaParser().parse(idl) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(false)).print(schema) + + then: + result == '''type Field { + deprecated: Enum +} + +type Query { + field: Field +} + +enum Enum { + enumVal +} + +input Input { + deprecated: String +} +''' + } + + def "descriptions can be printed as # comments"() { + given: + def idl = ''' + + """ + This is the docstring of + the Query type + """ + type Query { + """ + This is the docstring of + the fieldX field + """ + fieldX : String + } + + ''' + def registry = new SchemaParser().parse(idl) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def result = new SchemaPrinter(defaultOptions().descriptionsAsHashComments(true).includeDirectives(false)).print(schema) + + then: + result == '''#This is the docstring of +#the Query type +type Query { + #This is the docstring of + #the fieldX field + fieldX: String +} +''' + } + + def "@deprecated directive are NOT always printed regardless of options"() { + given: + def idl = ''' + + type Query { + fieldX : String @deprecated + } + + ''' + def registry = new SchemaParser().parse(idl) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def result = new SchemaPrinter(noDirectivesOption).print(schema) + + then: + result == '''type Query { + fieldX: String +} +''' + } + + def "@deprecated directive are printed respecting options"() { + given: + def idl = ''' + + type Query { + fieldX : String @deprecated + } + + ''' + def registry = new SchemaParser().parse(idl) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def printOptions = defaultOptions().includeDirectives({ dName -> (dName == "deprecated") }) + def result = new SchemaPrinter(printOptions).print(schema) + + then: + result == '''"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +type Query { + fieldX: String @deprecated(reason : "No longer supported") +} +''' + } + + def "omit unused built-in scalars by default - created by sdl string"() { + given: + def sdl = '''type Query {scalarcustom : RandomScalar} scalar RandomScalar''' + + def registry = new SchemaParser().parse(sdl) + def runtimeWiring = newRuntimeWiring().scalar(mockScalar("RandomScalar")).build() + def options = SchemaGenerator.Options.defaultOptions() + + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + def result = new SchemaPrinter(noDirectivesOption).print(schema) + + expect: + + ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS.forEach({ + scalarType -> assert !result.contains(scalarType.name) + }) + + result == '''type Query { + scalarcustom: RandomScalar +} + +"RandomScalar" +scalar RandomScalar +''' + } + + def "show unused custom scalars when unused - created by sdl string"() { + given: + def sdl = '''type Query {astring : String aInt : Int} "Some Scalar" scalar CustomScalar''' + + def registry = new SchemaParser().parse(sdl) + def runtimeWiring = newRuntimeWiring().scalar(mockScalar("CustomScalar")).build() + def options = SchemaGenerator.Options.defaultOptions() + + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + def result = new SchemaPrinter(noDirectivesOption).print(schema) + + expect: + assert !result.contains("ID") && !result.contains("Float") && !result.contains("Boolean") + result == + '''type Query { + aInt: Int + astring: String +} + +"CustomScalar" +scalar CustomScalar +''' + } + + def "omit unused built-in by default - created programmatically"() { + given: + GraphQLScalarType myScalar = newScalar().name("RandomScalar").description("about scalar").coercing(new Coercing() { + @Override + Object serialize(Object input) { + return null + } + + @Override + Object parseValue(Object input) { + return null + } + + @Override + Object parseLiteral(Object input) { + return null + } + }) + .build() + + GraphQLFieldDefinition fieldDefinition = newFieldDefinition() + .name("scalarType").type(myScalar).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() + + def schema = GraphQLSchema.newSchema().query(queryType).additionalType(myScalar).build() + + def result = new SchemaPrinter(defaultOptions().includeDirectives(false)).print(schema) + + expect: + ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS.forEach({ + scalarType -> assert !result.contains(scalarType.name) + }) + result == + '''type Query { + scalarType: RandomScalar +} + +"about scalar" +scalar RandomScalar +''' + } + + def "show unused custom scalars when unused - created programmatically"() { + given: + GraphQLScalarType myScalar = newScalar().name("Scalar").description("about scalar").coercing(new Coercing() { + @Override + Object serialize(Object input) { + return null + } + + @Override + Object parseValue(Object input) { + return null + } + + @Override + Object parseLiteral(Object input) { + return null + } + }) + .build() + + GraphQLFieldDefinition fieldDefinition = newFieldDefinition() + .name("someType").type(GraphQLInt).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() + + def schema = GraphQLSchema.newSchema().query(queryType).additionalType(myScalar).build() + + def result = new SchemaPrinter(defaultOptions().includeScalarTypes(true).includeDirectives(false)).print(schema) + + expect: + result == + '''type Query { + someType: Int +} + +"about scalar" +scalar Scalar +''' + } + + def "single line comments are properly escaped"() { + given: + def idl = """ + type Query { + "$comment" + fieldX : String + } + """ + def registry = new SchemaParser().parse(idl) + def runtimeWiring = newRuntimeWiring().build() + def options = SchemaGenerator.Options.defaultOptions() + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, runtimeWiring) + + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(false)).print(schema) + + then: + result == """type Query { + "$comment" + fieldX: String +} +""" + + where: + _ | comment + _ | 'quotation-\\"' + _ | 'reverse-solidus-\\\\' + _ | 'backspace-\\b' + _ | 'formfeed-\\f' + _ | 'carriage-return-\\r' + _ | 'horizontal-tab-\\t' + } + + def 'print interfaces implementing interfaces correctly'() { + given: + def sdl = """ + type Query { + foo: Resource + } + + interface Node { + id: ID! + } + interface Node2 { + id2: ID! + } + + interface Resource implements Node & Node2 { + id: ID! + id2: ID! + } + """ + def schema = TestUtil.schema(sdl) + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(false)).print(schema) + + then: + result == """interface Node { + id: ID! +} + +interface Node2 { + id2: ID! +} + +interface Resource implements Node & Node2 { + id: ID! + id2: ID! +} + +type Query { + foo: Resource +} +""" + } + + def "schema element filtering works"() { + def sdl = """ + schema { + query : PrintMeQuery + } + + directive @directivePrintMe on ARGUMENT_DEFINITION + directive @someOtherDirective on FIELD_DEFINITION + + type PrintMeQuery { + field : PrintMeType + fieldPrintMe : SomeType + fieldPrintMeWithArgs(arg1 : String, arg2PrintMe : String @directivePrintMe) : SomeType @someOtherDirective + } + + type PrintMeType { + fieldPrintMe : String + } + + type SomeType { + fieldPrintMe : String + } + + """ + def schema = TestUtil.schema(sdl) + + when: + Predicate predicate = { element -> + if (element instanceof GraphQLNamedSchemaElement) { + def printIt = ((GraphQLNamedSchemaElement) element).getName().contains("PrintMe") + return printIt + } + return false + } + def result = new SchemaPrinter(defaultOptions().includeDirectives(true).includeSchemaElement(predicate)).print(schema) + + then: + result == """schema { + query: PrintMeQuery +} + +directive @directivePrintMe on ARGUMENT_DEFINITION + +type PrintMeQuery { + fieldPrintMe: SomeType + fieldPrintMeWithArgs(arg2PrintMe: String @directivePrintMe): SomeType +} + +type PrintMeType { + fieldPrintMe: String +} +""" + + } + + def "schema with directive prints directive"() { + def sdl = """ + directive @foo on SCHEMA + type MyQuery { anything: String } + schema @foo { + query: MyQuery + } + """ + def schema = TestUtil.schema(sdl) + + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(true)).print(schema) + + then: + result == """schema @foo{ + query: MyQuery +} + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +directive @foo on SCHEMA + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type MyQuery { + anything: String +} +""" + } + + def "allow printing of just directives"() { + def sdl = """ + directive @foo on FIELD_DEFINITION + type Query { anything: String @foo } + """ + def schema = TestUtil.schema(sdl) + def directive = schema.getDirective("foo") + + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(true)).print(directive) + + then: + result == """directive @foo on FIELD_DEFINITION""" + } + + def "directive with leading pipe gets discarded"() { + def sdl = """ + directive @foo on | OBJECT | FIELD_DEFINITION + type Query { anything: String @foo } + """ + def schema = TestUtil.schema(sdl) + def directive = schema.getDirective("foo") + + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(true)).print(directive) + + then: + result == """directive @foo on OBJECT | FIELD_DEFINITION""" + } + + def "description printing escapes triple quotes"() { + def descriptionWithTripleQuote = 'Hello """ \n World """ """' + def field = newFieldDefinition().name("hello").type(GraphQLString).build() + def queryType = newObject().name("Query").field(field).description(descriptionWithTripleQuote).build() + def schema = GraphQLSchema.newSchema().query(queryType).build() + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(ExcludeGraphQLSpecifiedDirectivesPredicate)).print(schema) + + then: + result == '''""" +Hello \\""" + World \\""" \\""" +""" +type Query { + hello: String +} +''' + } + + def "directive with optional values"() { + def sdl = """ + directive @foo(note:String) on FIELD_DEFINITION + type Query { + anything: String @foo + anything2: String @foo(note: "foo") + } + """ + def schema = TestUtil.schema(sdl) + when: + def result = new SchemaPrinter(defaultOptions().includeDirectives(ExcludeGraphQLSpecifiedDirectivesPredicate)).print(schema) + + + then: + result == """directive @foo(note: String) on FIELD_DEFINITION + +type Query { + anything: String @foo + anything2: String @foo(note : "foo") +} +""" + } + + def "programmatic object value in an argument is printed"() { + + GraphQLInputObjectType compoundType = GraphQLInputObjectType.newInputObject().name("Compound") + .field({ it.name("a").type(GraphQLString) }) + .field({ it.name("b").type(GraphQLString) }) + .build() + + GraphQLObjectType objType = newObject().name("obj") + .field({ + it.name("f").type(GraphQLString) + .argument({ + it.name("arg").type(compoundType).defaultValueProgrammatic(["a": "A", "b": "B"]) + }) + }).build() + + when: + + def result = new SchemaPrinter().print(objType) + + + then: + result == '''type obj { + f(arg: Compound = {a : "A", b : "B"}): String +} +''' + + when: + def newAppliedDirective = GraphQLAppliedDirective.newDirective().name("foo") + .argument({ + it.name("arg").type(compoundType).valueProgrammatic(["a": "A", "b": "B"]) + }) + .build() + + objType = newObject().name("obj").field({ + it.name("f").type(GraphQLString).withAppliedDirective(newAppliedDirective) + }).build() + + result = new SchemaPrinter().print(objType) + + then: + + result == '''type obj { + f: String @foo(arg : {a : "A", b : "B"}) +} +''' + } + + def "directive containing formatting specifiers"() { + def constraintAppliedDirective = GraphQLAppliedDirective.newDirective().name("constraint") + .argument({ + it.name("regex").type(GraphQLString).valueProgrammatic("%") + }) + .build() + + GraphQLInputObjectType type = GraphQLInputObjectType.newInputObject().name("Person") + .field({ it.name("thisMustBeAPercentageSign").type(GraphQLString).withAppliedDirective(constraintAppliedDirective) }) + .build() + + when: + def result = new SchemaPrinter().print(type) + + + then: + result == '''input Person { + thisMustBeAPercentageSign: String @constraint(regex : "%") +} +''' + } + + def "can specify a new ordering for the schema printer"() { + + def sdl = """ + type Query { id( b:ID a:ID c:ID) : ID } + + type XQuery { id: ID } + type YQuery { id: ID } + type ZQuery { id: ID } + + interface XInterface { id: ID } + interface ZInterface { id: ID } + interface YInterface { id: ID } + + + input XInput { x : Int } + input ZInput { x : Int } + input YInput { x : Int } + + scalar XScalar + scalar ZScalar + scalar YScalar + + union XUnion = Query | XQuery + union ZUnion = Query | XQuery + union YUnion = Query | XQuery + """ + def schema = TestUtil.schema(sdl) + + // by name descending + GraphqlTypeComparatorRegistry comparatorRegistry = { env -> return GraphqlTypeComparators.byNameAsc().reversed() } + def options = defaultOptions().includeDirectives(true).setComparators(comparatorRegistry) + when: + def result = new SchemaPrinter(options).print(schema) + + then: + result == '''"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive allows results to be deferred during execution" +directive @defer( + "A unique label that represents the fragment being deferred" + label: String, + "Deferred behaviour is controlled by this argument" + if: Boolean! = true + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +union ZUnion = XQuery | Query + +scalar ZScalar + +type ZQuery { + id: ID +} + +interface ZInterface { + id: ID +} + +input ZInput { + x: Int +} + +union YUnion = XQuery | Query + +scalar YScalar + +type YQuery { + id: ID +} + +interface YInterface { + id: ID +} + +input YInput { + x: Int +} + +union XUnion = XQuery | Query + +scalar XScalar + +type XQuery { + id: ID +} + +interface XInterface { + id: ID +} + +input XInput { + x: Int +} + +type Query { + id(c: ID, b: ID, a: ID): ID +} +''' + + } + + def "prints schema description as comment"() { + given: + GraphQLFieldDefinition fieldDefinition = newFieldDefinition() + .name("field").type(GraphQLString).build() + def queryType = newObject().name("Query").field(fieldDefinition).build() + def schema = GraphQLSchema.newSchema().description("About Schema").query(queryType).build() + when: + def result = new SchemaPrinter(noDirectivesOption.includeSchemaDefinition(true)).print(schema) + println(result) + + then: + result == '''"About Schema" +schema { + query: Query +} + +type Query { + field: String +} +''' + } + + def "prints list of schema elements"() { + given: + def testObjectA = newObject() + .name("TestObjectA") + .field(newFieldDefinition().name("field").type(GraphQLString)) + .build() + def testObjectB = newObject() + .name("TestObjectB") + .field(newFieldDefinition().name("field").type(GraphQLString)) + .build() + + when: + def result = new SchemaPrinter().print([testObjectA, testObjectB]) + println(result) + + then: + result == '''type TestObjectA { + field: String +} + +type TestObjectB { + field: String +} +''' + } + + final def SDL_WITH_COMMENTS = '''#schema comment 1 +# schema comment 2 with leading spaces +schema { + query: Query + mutation: Mutation +} + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +" custom directive 'example' description 1" +# custom directive 'example' comment 1 +directive @example on ENUM_VALUE + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +# interface Character comment 1 +# interface Character comment 2 +interface Character implements Node { + appearsIn: [Episode] + friends: [Character] + id: ID! + name: String +} + +interface Node { + id: ID! +} + +# union type Humanoid comment 1 +union Humanoid = Droid | Human + +type Droid implements Character & Node { + appearsIn: [Episode]! + friends: [Character] + id: ID! + madeOn: Planet + name: String! + primaryFunction: String +} + +type Human implements Character & Node { + appearsIn: [Episode]! + friends: [Character] + homePlanet: String + id: ID! + name: String! +} + +type Mutation { + shoot( + # arg 'id\' + id: String!, + # arg 'with\' + with: Gun + ): Query +} + +type Planet { + hitBy: Asteroid + name: String +} + +# type query comment 1 +# type query comment 2 +type Query { + # query field 'hero' comment + hero(episode: Episode): Character + # query field 'humanoid' comment + humanoid(id: ID!): Humanoid +} + +# enum Episode comment 1 +# enum Episode comment 2 +enum Episode { + # enum value EMPIRE comment 1 + EMPIRE + JEDI + NEWHOPE @example +} + +"desc" +# scalar Asteroid comment 1 +scalar Asteroid + +# input type Gun comment 1 +input Gun { + # gun 'caliber' input value comment + caliber: Int + # gun 'name' input value comment + name: String +} +''' + + static List makeComments(String... strings) { + return strings.stream() + .map(s -> new Comment(s, null)) + .collect(Collectors.toList()) + } + + def "prints with AST comments"() { + given: + def exampleDirective = GraphQLDirective.newDirective().name("example").validLocation(Introspection.DirectiveLocation.ENUM_VALUE) + .description(" custom directive 'example' description 1") + .definition(DirectiveDefinition.newDirectiveDefinition().comments(makeComments(" custom directive 'example' comment 1")).build()).build() + def asteroidType = newScalar().name("Asteroid").description("desc") + .definition(ScalarTypeDefinition.newScalarTypeDefinition().comments(makeComments(" scalar Asteroid comment 1")).build()) + .coercing(TestUtil.mockCoercing()) + .build() + def nodeType = newInterface().name("Node") + .field(newFieldDefinition().name("id").type(nonNull(GraphQLID)).build()) + .build() + def planetType = newObject().name("Planet") + .field(newFieldDefinition().name("hitBy").type(asteroidType).build()) + .field(newFieldDefinition().name("name").type(GraphQLString).build()) + .build() + def episodeType = newEnum().name("Episode") + .definition(newEnumTypeDefinition().comments( + makeComments(" enum Episode comment 1", " enum Episode comment 2")).build()) + .values(List.of( + GraphQLEnumValueDefinition.newEnumValueDefinition().name("EMPIRE") + .definition(EnumValueDefinition.newEnumValueDefinition().comments(makeComments(" enum value EMPIRE comment 1")).build()).build(), + GraphQLEnumValueDefinition.newEnumValueDefinition().name("JEDI").build(), + GraphQLEnumValueDefinition.newEnumValueDefinition().name("NEWHOPE").withDirective(exampleDirective).build())) + .build() + def characterType = newInterface().name("Character").withInterface(nodeType) + .definition(newInterfaceTypeDefinition().comments( + makeComments(" interface Character comment 1", " interface Character comment 2")).build()) + .field(newFieldDefinition().name("appearsIn").type(list(episodeType)).build()) + .field(newFieldDefinition().name("friends").type(list(typeRef("Character"))).build()) + .field(newFieldDefinition().name("id").type(nonNull(GraphQLID)).build()) + .field(newFieldDefinition().name("name").type(GraphQLString).build()) + .build() + def droidType = newObject().name("Droid").withInterfaces(characterType, nodeType) + .field(newFieldDefinition().name("appearsIn").type(nonNull(list(episodeType))).build()) + .field(newFieldDefinition().name("friends").type(list(typeRef("Character"))).build()) + .field(newFieldDefinition().name("id").type(nonNull(GraphQLID)).build()) + .field(newFieldDefinition().name("madeOn").type(planetType).build()) + .field(newFieldDefinition().name("name").type(nonNull(GraphQLString)).build()) + .field(newFieldDefinition().name("primaryFunction").type(GraphQLString).build()) + .build() + def humanType = newObject().name("Human").withInterfaces(characterType, nodeType) + .field(newFieldDefinition().name("appearsIn").type(nonNull(list(episodeType))).build()) + .field(newFieldDefinition().name("friends").type(list(typeRef("Character"))).build()) + .field(newFieldDefinition().name("homePlanet").type(GraphQLString).build()) + .field(newFieldDefinition().name("id").type(nonNull(GraphQLID)).build()) + .field(newFieldDefinition().name("name").type(nonNull(GraphQLString)).build()) + .build() + def humanoidType = newUnionType().name("Humanoid") + .definition(newUnionTypeDefinition().comments(makeComments(" union type Humanoid comment 1")).build()) + .possibleTypes(humanType, droidType) + .build() + def queryType = newObject().name("Query") + .definition(newObjectTypeDefinition().comments(makeComments(" type query comment 1", " type query comment 2")).build()) + .field(newFieldDefinition().name("hero").type(characterType) + .definition(FieldDefinition.newFieldDefinition().comments(makeComments(" query field 'hero' comment")).build()) + .argument(newArgument().name("episode").type(episodeType).build()) + .build()) + .field(newFieldDefinition().name("humanoid").type(humanoidType) + .definition(FieldDefinition.newFieldDefinition().comments(makeComments(" query field 'humanoid' comment")).build()) + .argument(newArgument().name("id").type(nonNull(GraphQLID)).build()) + .build()) + .build() + def gunType = GraphQLInputObjectType.newInputObject().name("Gun") + .definition(newInputObjectDefinition().comments(makeComments(" input type Gun comment 1")).build()) + .field(newInputObjectField().name("name").type(GraphQLString) + .definition(newInputValueDefinition().comments(makeComments(" gun 'name' input value comment")).build()).build()) + .field(newInputObjectField().name("caliber").type(GraphQLInt) + .definition(newInputValueDefinition().comments(makeComments(" gun 'caliber' input value comment")).build()).build()) + .build() + def schema = GraphQLSchema.newSchema() + .additionalDirective(exampleDirective) + .codeRegistry(GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(characterType, resolver) + .typeResolver(humanoidType, resolver) + .typeResolver(nodeType, resolver) + .build()) + .definition(SchemaDefinition.newSchemaDefinition().comments( + makeComments("schema comment 1", " schema comment 2 with leading spaces")).build()) + .mutation(newObject().name("Mutation") + .field(newFieldDefinition().name("shoot").type(queryType).arguments(List.of( + newArgument().name("id").type(nonNull(GraphQLString)) + .definition(newInputValueDefinition().comments(makeComments(" arg 'id'")).build()).build(), + newArgument().name("with").type(gunType) + .definition(newInputValueDefinition().comments(makeComments(" arg 'with'")).build()).build())) + .build()) + .build()) + .query(queryType) + .build() + when: + def result = new SchemaPrinter(defaultOptions().includeSchemaDefinition(true).includeAstDefinitionComments(true)).print(schema) + println(result) + + then: + result == SDL_WITH_COMMENTS + } + + def "parses, generates and prints with AST comments"() { + given: + def registry = new SchemaParser().parse(SDL_WITH_COMMENTS) + def wiring = newRuntimeWiring() + .scalar(mockScalar(registry.scalars().get("Asteroid"))) + .type(mockTypeRuntimeWiring("Character", true)) + .type(mockTypeRuntimeWiring("Humanoid", true)) + .type(mockTypeRuntimeWiring("Node", true)) + .build() + def options = SchemaGenerator.Options.defaultOptions().useCommentsAsDescriptions(false) + def schema = new SchemaGenerator().makeExecutableSchema(options, registry, wiring) + when: + def result = new SchemaPrinter(defaultOptions().includeSchemaDefinition(true).includeAstDefinitionComments(true)).print(schema) + println(result) + + // @TODO: Schema Parser seems to be ignoring directive and scalar comments and needs to be fixed. + // The expected result below should be the same as the SDL_WITH_COMMENTS above BUT with the two comments temporarily removed. + then: + result == '''#schema comment 1 +# schema comment 2 with leading spaces +schema { + query: Query + mutation: Mutation +} + +"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +" custom directive 'example' description 1" +directive @example on ENUM_VALUE + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +# interface Character comment 1 +# interface Character comment 2 +interface Character implements Node { + appearsIn: [Episode] + friends: [Character] + id: ID! + name: String +} + +interface Node { + id: ID! +} + +# union type Humanoid comment 1 +union Humanoid = Droid | Human + +type Droid implements Character & Node { + appearsIn: [Episode]! + friends: [Character] + id: ID! + madeOn: Planet + name: String! + primaryFunction: String +} + +type Human implements Character & Node { + appearsIn: [Episode]! + friends: [Character] + homePlanet: String + id: ID! + name: String! +} + +type Mutation { + shoot( + # arg 'id\' + id: String!, + # arg 'with\' + with: Gun + ): Query +} + +type Planet { + hitBy: Asteroid + name: String +} + +# type query comment 1 +# type query comment 2 +type Query { + # query field 'hero' comment + hero(episode: Episode): Character + # query field 'humanoid' comment + humanoid(id: ID!): Humanoid +} + +# enum Episode comment 1 +# enum Episode comment 2 +enum Episode { + # enum value EMPIRE comment 1 + EMPIRE + JEDI + NEWHOPE @example +} + +"desc" +scalar Asteroid + +# input type Gun comment 1 +input Gun { + # gun 'caliber' input value comment + caliber: Int + # gun 'name' input value comment + name: String +} +''' + } + + def "issue 3285 - deprecated defaultValue on programmatic args prints as expected"() { + def queryObjType = newObject().name("Query") + .field(newFieldDefinition().name("f").type(GraphQLString) + .argument(newArgument().name("arg").type(GraphQLString).defaultValue(null))) + .build() + def schema = GraphQLSchema.newSchema().query(queryObjType).build() + + + when: + def options = defaultOptions().includeDirectiveDefinitions(false) + def sdl = new SchemaPrinter(options).print(schema) + then: + sdl == '''type Query { + f(arg: String = null): String +} +''' + } + + def "deprecated directive with custom reason"() { + given: + def enumType = newEnum().name("Enum") + .values(List.of( + GraphQLEnumValueDefinition.newEnumValueDefinition().name("DEPRECATED_WITH_REASON").deprecationReason("Custom enum value reason").build())) + .build() + def fieldType = newObject().name("Field") + .field(newFieldDefinition().name("deprecatedWithReason").type(enumType).deprecate("Custom field reason").build()) + .build() + def inputType = GraphQLInputObjectType.newInputObject().name("Input") + .field(newInputObjectField().name("deprecatedWithReason").type(enumType).deprecate("Custom input reason").build()) + .build() + def queryType = newObject().name("Query") + .field(newFieldDefinition().name("field").type(fieldType) + .argument(newArgument().name("deprecatedWithReason").type(inputType).deprecate("Custom argument reason").build()).build()) + .build() + def schema = GraphQLSchema.newSchema() + .query(queryType) + .build() + when: + + def printOptions = defaultOptions().includeDirectiveDefinitions(false).includeDirectives({ d -> true }) + + def result = "\n" + new SchemaPrinter(printOptions).print(schema) + println(result) + + then: + result == """ +type Field { + deprecatedWithReason: Enum @deprecated(reason : "Custom field reason") +} + +type Query { + field(deprecatedWithReason: Input @deprecated(reason : "Custom argument reason")): Field +} + +enum Enum { + DEPRECATED_WITH_REASON @deprecated(reason : "Custom enum value reason") +} + +input Input { + deprecatedWithReason: Enum @deprecated(reason : "Custom input reason") +} +""" + } + + def "can use predicate for directive definitions"() { + + def schema = TestUtil.schema(""" + type Query { + field: String @deprecated + } + """) + + + def options = defaultOptions() + .includeDirectiveDefinitions(true) + .includeDirectiveDefinition({ it != "skip" }) + def result = new SchemaPrinter(options).print(schema) + + expect: "has no skip definition" + + result == """"This directive allows results to be deferred during execution" +directive @defer( + "Deferred behaviour is controlled by this argument" + if: Boolean! = true, + "A unique label that represents the fragment being deferred" + label: String + ) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"This directive disables error propagation when a non nullable field returns null for the given operation." +directive @experimental_disableErrorPropagation on QUERY | MUTATION | SUBSCRIPTION + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! + ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Indicates an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! + ) on SCALAR + +type Query { + field: String @deprecated(reason : "No longer supported") +} +""" + } +} + -} \ No newline at end of file diff --git a/src/test/groovy/graphql/schema/idl/SchemaTypeCheckerTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaTypeCheckerTest.groovy index ee2aae53f6..a109e0583c 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaTypeCheckerTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaTypeCheckerTest.groovy @@ -1,29 +1,28 @@ package graphql.schema.idl import graphql.GraphQLError +import graphql.TestUtil import graphql.TypeResolutionEnvironment import graphql.language.StringValue import graphql.schema.Coercing import graphql.schema.CoercingParseLiteralException import graphql.schema.DataFetcher import graphql.schema.GraphQLObjectType -import graphql.schema.GraphQLScalarType import graphql.schema.TypeResolver import graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError import graphql.schema.idl.errors.DirectiveIllegalLocationError import graphql.schema.idl.errors.DirectiveUndeclaredError import graphql.schema.idl.errors.MissingTypeError import graphql.schema.idl.errors.NonUniqueNameError -import graphql.schema.idl.errors.SchemaMissingError +import graphql.schema.idl.errors.QueryOperationMissingError import spock.lang.Specification import spock.lang.Unroll +import static graphql.schema.GraphQLScalarType.newScalar import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.DUPLICATED_KEYS_MESSAGE import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_ENUM_MESSAGE -import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_LIST_MESSAGE import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_NON_NULL_MESSAGE import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_OBJECT_MESSAGE -import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.EXPECTED_SCALAR_MESSAGE import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.MISSING_REQUIRED_FIELD_MESSAGE import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.MUST_BE_VALID_ENUM_VALUE_MESSAGE import static graphql.schema.idl.errors.DirectiveIllegalArgumentTypeError.NOT_A_VALID_SCALAR_LITERAL_MESSAGE @@ -32,11 +31,8 @@ import static java.lang.String.format class SchemaTypeCheckerTest extends Specification { - def enforceSchemaDirectives = false - - - TypeDefinitionRegistry parse(String spec) { - new SchemaParser().parse(spec) + static TypeDefinitionRegistry parseSDL(String spec) { + new SchemaParser().parse(spec).readOnly() } def resolver = new TypeResolver() { @@ -89,12 +85,12 @@ class SchemaTypeCheckerTest extends Specification { } List check(String spec, List resolvingNames) { - def types = parse(spec) + def types = parseSDL(spec) NamedWiringFactory wiringFactory = new NamedWiringFactory("InterfaceType") - def scalesScalar = new GraphQLScalarType("Scales", "", new Coercing() { + def scalesScalar = newScalar().name("Scales").coercing(new Coercing() { @Override Object serialize(Object dataFetcherResult) { return null @@ -110,7 +106,9 @@ class SchemaTypeCheckerTest extends Specification { return null } }) - def aCustomDateScalar = new GraphQLScalarType("ACustomDate", "", new Coercing() { + .build() + + def aCustomDateScalar = newScalar().name("ACustomDate").coercing(new Coercing() { @Override Object serialize(Object dataFetcherResult) { return null @@ -128,7 +126,8 @@ class SchemaTypeCheckerTest extends Specification { } return null } - }) + }).build() + def runtimeBuilder = RuntimeWiring.newRuntimeWiring() .wiringFactory(wiringFactory) .scalar(scalesScalar) @@ -140,7 +139,7 @@ class SchemaTypeCheckerTest extends Specification { for (String name : resolvingNames) { runtimeBuilder.type(TypeRuntimeWiring.newTypeWiring(name).typeResolver(resolver)) } - return new SchemaTypeChecker().checkTypeRegistry(types, runtimeBuilder.build(), enforceSchemaDirectives) + return new SchemaTypeChecker().checkTypeRegistry(types.readOnly(), runtimeBuilder.build()) } def "test missing type in object"() { @@ -254,7 +253,7 @@ class SchemaTypeCheckerTest extends Specification { expect: - result.get(0) instanceof SchemaMissingError + result.get(0) instanceof QueryOperationMissingError } def "test missing schema operation types"() { @@ -306,7 +305,7 @@ class SchemaTypeCheckerTest extends Specification { expect: - result.get(0) instanceof SchemaMissingError + result.get(0) instanceof QueryOperationMissingError } def "test operation type is not an object"() { @@ -400,8 +399,8 @@ class SchemaTypeCheckerTest extends Specification { result.get(0).getMessage().contains("tried to redefine field 'fieldA'") } - def "test ext type can redefine fields in their base type of the same type"() { - + def "test ext type cannot redefine fields in their base type of the same type"() { + given: def spec = """ type BaseType { @@ -418,11 +417,12 @@ class SchemaTypeCheckerTest extends Specification { } """ + when: def result = check(spec) - expect: + then: - result.isEmpty() + errorContaining(result, "BaseType' extension type [@n:n] tried to redefine field 'fieldA' [@n:n]") } def "test ext type redefines fields in their peer types"() { @@ -454,7 +454,7 @@ class SchemaTypeCheckerTest extends Specification { } def "test ext type redefines fields in their peer types of the same type is ok"() { - + given: def spec = """ type BaseType { @@ -474,11 +474,11 @@ class SchemaTypeCheckerTest extends Specification { } """ + when: def result = check(spec) - expect: - - result.isEmpty() + then: + errorContaining(result, "BaseType' extension type [@n:n] tried to redefine field 'fieldB' [@n:n]") } def "test ext type is missing the base type"() { @@ -707,6 +707,119 @@ class SchemaTypeCheckerTest extends Specification { } + def "directives on arguments are not relevant"() { + def spec = """ + directive @d on ARGUMENT_DEFINITION + interface InterfaceType { + fieldB(arg1 : String = "defaultVal", arg2 : String @d, arg3 : Int @d) : String + } + + type BaseType { + fieldX : Int + } + + extend type BaseType implements InterfaceType { + fieldB(arg1 : String = "defaultVal" @d, arg2 : String, arg3 : Int) : String + } + + schema { + query : BaseType + } + """ + + def result = check(spec) + + expect: + result.isEmpty() + + } + + + + def "test field arguments on object can contain additional optional arguments"() { + def spec = """ + interface InterfaceType { + fieldA : Int + fieldB(arg1 : String = "defaultVal") : String + } + + type BaseType { + fieldX : Int + } + + extend type BaseType implements InterfaceType { + fieldA(arg1 : String) : Int + fieldB(arg1 : String = "defaultVal", arg2 : String) : String + } + + schema { + query : BaseType + } + """ + + def result = check(spec) + + expect: + + result.isEmpty() + } + + def "order of interface args does not matter"() { + def spec = """ + interface InterfaceType { + fieldA(arg1 : String, arg2 : Int) : String + } + + type BaseType { + fieldX : Int + } + + extend type BaseType implements InterfaceType { + fieldA(arg2 : Int, arg1 : String) : String + } + + schema { + query : BaseType + } + """ + + def result = check(spec) + + expect: + + result.isEmpty() + } + + + def "test field arguments on object cannot contain additional required arguments"() { + def spec = """ + interface InterfaceType { + fieldA : Int + fieldB(arg1 : String = "defaultVal") : String + } + + type BaseType { + fieldX : Int + } + + extend type BaseType implements InterfaceType { + fieldA(arg1 : String!) : Int + fieldB(arg1 : String = "defaultVal", arg2 : String!) : String + } + + schema { + query : BaseType + } + """ + + def result = check(spec) + + expect: + + result.get(0).getMessage().contains("field 'fieldA' defines an additional non-optional argument 'arg1: String!' which is not allowed because field is also defined in interface 'InterfaceType'") + result.get(1).getMessage().contains("field 'fieldB' defines an additional non-optional argument 'arg2: String!' which is not allowed because field is also defined in interface 'InterfaceType'") + } + def "test field arguments on objects must match the interface"() { def spec = """ interface InterfaceType { @@ -830,7 +943,7 @@ class SchemaTypeCheckerTest extends Specification { expect: !result.isEmpty() - result.size() == 4 + result.size() == 5 } def "test that field args are unique"() { @@ -887,53 +1000,13 @@ class SchemaTypeCheckerTest extends Specification { } enum EnumType { - enumA @deprecated(badName : "must be called reason"), enumB @deprecated(reason : "it must have", one : "argument value") } - - input InputType { - inputFieldA : String @deprecated(badName : "must be called reason") - inputFieldB : String @deprecated(reason : "it must have", one : "argument value") - } - """ - - def result = check(spec) - - expect: - - !result.isEmpty() - result.size() == 8 - } - - def "test that directives are valid"() { - - def spec = """ - interface InterfaceType1 { - fieldA : String @directiveA @directiveA - } - - type Query implements InterfaceType1 { - fieldA : String - fieldC : String @directiveA @directiveA - } - - extend type Query { - fieldB : Int - fieldD: Int @directiveA @directiveA - fieldE: Int @directiveA @directiveOK - } - - enum EnumType { - - enumA @directiveA @directiveA - enumB @directiveA @directiveOK - } - + # deprecation is no allowed on input field definitions and args atm, see: https://github.com/graphql-java/graphql-java/issues/1770 input InputType { - inputFieldA : String @directiveA @directiveA - inputFieldB : String @directiveA @directiveOK + inputField : String @deprecated } """ @@ -942,13 +1015,14 @@ class SchemaTypeCheckerTest extends Specification { expect: !result.isEmpty() - result.size() == 5 + result.size() == 7 } + def "test that directives args are valid"() { def spec = """ - + directive @directive(arg1: Int,argOK: Int) on FIELD_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION interface InterfaceType1 { fieldA : String @directive(arg1 : 1, arg1 : 2) } @@ -1031,7 +1105,6 @@ class SchemaTypeCheckerTest extends Specification { expect: - errorContaining(result, "The extension 'Query' type [@n:n] has redefined the directive called 'directive'") errorContaining(result, "'Query' extension type [@n:n] tried to redefine field 'fieldB' [@n:n]") errorContaining(result, "The type 'Query' [@n:n] has declared a field with a non unique name 'fieldC'") errorContaining(result, "The extension 'NonExistent' type [@n:n] is missing its base underlying type") @@ -1040,7 +1113,7 @@ class SchemaTypeCheckerTest extends Specification { def "interface type extensions invariants are enforced"() { def spec = """ - + directive @directive on INTERFACE type Query implements InterfaceType1 { fieldA : String fieldC : String @@ -1064,10 +1137,9 @@ class SchemaTypeCheckerTest extends Specification { expect: - result.size() == 3 + result.size() == 2 errorContaining(result, "The extension 'NonExistent' type [@n:n] is missing its base underlying type") errorContaining(result, "'InterfaceType1' extension type [@n:n] tried to redefine field 'fieldA' [@n:n]") - errorContaining(result, "The extension 'InterfaceType1' type [@n:n] has redefined the directive called 'directive'") } def "union type extensions invariants are enforced"() { @@ -1088,7 +1160,7 @@ class SchemaTypeCheckerTest extends Specification { type Baz { baz : String } - + directive @directive on UNION union FooBar @directive = Foo | Bar extend union FooBar @directive @@ -1107,9 +1179,8 @@ class SchemaTypeCheckerTest extends Specification { expect: - result.size() == 4 + result.size() == 3 errorContaining(result, "The extension 'NonExistent' type [@n:n] is missing its base underlying type") - errorContaining(result, "The extension 'FooBar' type [@n:n] has redefined the directive called 'directive'") errorContaining(result, "The union member type 'Buzz' is not present when resolving type 'FooBar' [@n:n]") errorContaining(result, "The type 'FooBar' [@n:n] has declared an union member with a non unique name 'Foo'") } @@ -1148,7 +1219,6 @@ class SchemaTypeCheckerTest extends Specification { expect: errorContaining(result, "'Numb' extension type [@n:n] tried to redefine enum value 'A' [@n:n]") - errorContaining(result, "The extension 'Numb' type [@n:n] has redefined the directive called 'directive'") errorContaining(result, "The type 'Numb' [@n:n] has declared an enum value with a non unique name 'D'") errorContaining(result, "The extension 'NonExistent' type [@n:n] is missing its base underlying type") } @@ -1166,9 +1236,7 @@ class SchemaTypeCheckerTest extends Specification { extend scalar Scales @directive - extend scalar NonExistent { - E - } + extend scalar NonExistent @directive """ @@ -1176,7 +1244,6 @@ class SchemaTypeCheckerTest extends Specification { expect: - errorContaining(result, "The extension 'Scales' type [@n:n] has redefined the directive called 'directive'") errorContaining(result, "The extension 'NonExistent' type [@n:n] is missing its base underlying type") } @@ -1224,7 +1291,6 @@ class SchemaTypeCheckerTest extends Specification { expect: - errorContaining(result, "The extension 'Puter' type [@n:n] has redefined the directive called 'directive'") errorContaining(result, "The type 'Puter' [@n:n] has declared an input field with a non unique name 'fieldD'") errorContaining(result, "'Puter' extension type [@n:n] tried to redefine field 'fieldE' [@n:n]") errorContaining(result, "The extension 'NonExistent' type [@n:n] is missing its base underlying type") @@ -1321,7 +1387,6 @@ class SchemaTypeCheckerTest extends Specification { } """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1338,7 +1403,6 @@ class SchemaTypeCheckerTest extends Specification { } """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1355,7 +1419,6 @@ class SchemaTypeCheckerTest extends Specification { } """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1376,7 +1439,6 @@ class SchemaTypeCheckerTest extends Specification { } """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1397,7 +1459,6 @@ class SchemaTypeCheckerTest extends Specification { } """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1438,7 +1499,6 @@ class SchemaTypeCheckerTest extends Specification { """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1450,22 +1510,16 @@ class SchemaTypeCheckerTest extends Specification { where: allowedArgType | argValue | detailedMessage - "String" | 'MONDAY' | format(EXPECTED_SCALAR_MESSAGE, "EnumValue") - "String" | '{ an: "object" }' | format(EXPECTED_SCALAR_MESSAGE, "ObjectValue") - "String" | '["str", "str2"]' | format(EXPECTED_SCALAR_MESSAGE, "ArrayValue") "ACustomDate" | '"AFailingDate"' | format(NOT_A_VALID_SCALAR_LITERAL_MESSAGE, "ACustomDate") - "[String]" | '"str"' | format(EXPECTED_LIST_MESSAGE, "StringValue") - "[String]!" | '"str"' | format(EXPECTED_LIST_MESSAGE, "StringValue") + "[String]" | 123 | format(NOT_A_VALID_SCALAR_LITERAL_MESSAGE, "String") "[String!]" | '["str", null]' | format(EXPECTED_NON_NULL_MESSAGE) "[[String!]!]" | '[["str"], ["str2", null]]' | format(EXPECTED_NON_NULL_MESSAGE) + "[[String!]!]" | '[["str"], ["str2", "str3"], null]' | format(EXPECTED_NON_NULL_MESSAGE) "WEEKDAY" | '"somestr"' | format(EXPECTED_ENUM_MESSAGE, "StringValue") "WEEKDAY" | 'SATURDAY' | format(MUST_BE_VALID_ENUM_VALUE_MESSAGE, "SATURDAY", "MONDAY,TUESDAY") "UserInput" | '{ fieldNonNull: "str", fieldNonNull: "dupeKey" }' | format(DUPLICATED_KEYS_MESSAGE, "fieldNonNull") "UserInput" | '{ fieldNonNull: "str", unknown: "field" }' | format(UNKNOWN_FIELDS_MESSAGE, "unknown", "UserInput") - "UserInput" | '{ fieldNonNull: "str", fieldArray: "strInsteadOfArray" }' | format(EXPECTED_LIST_MESSAGE, "StringValue") - "UserInput" | '{ fieldNonNull: "str", fieldArrayOfArray: ["ArrayInsteadOfArrayOfArray"] }' | format(EXPECTED_LIST_MESSAGE, "StringValue") "UserInput" | '{ fieldNonNull: "str", fieldNestedInput: "strInsteadOfObject" }' | format(EXPECTED_OBJECT_MESSAGE, "StringValue") - "UserInput" | '{ fieldNonNull: "str", fieldNestedInput: { street: { s: "objectInsteadOfString" }} }' | format(EXPECTED_SCALAR_MESSAGE, "ObjectValue") "UserInput" | '{ field: "missing the `fieldNonNull` entry"}' | format(MISSING_REQUIRED_FIELD_MESSAGE, "fieldNonNull") } @@ -1498,7 +1552,6 @@ class SchemaTypeCheckerTest extends Specification { } """ - enforceSchemaDirectives = true def result = check(spec) expect: @@ -1515,8 +1568,11 @@ class SchemaTypeCheckerTest extends Specification { "ACustomDate" | '2002' "[String]" | '["str", null]' "[String]" | 'null' + "[String]" | '"str"' // see #2001 "[String!]!" | '["str"]' "[[String!]!]" | '[["str"], ["str2", "str3"]]' + "[[String]]" | '[["str"], ["str2", null], null]' + "[[String!]]" | '[["str"], ["str2", "str3"], null]' "WEEKDAY" | 'MONDAY' "UserInput" | '{ fieldNonNull: "str" }' "UserInput" | '{ fieldNonNull: "str", fieldString: "Hey" }' @@ -1526,4 +1582,362 @@ class SchemaTypeCheckerTest extends Specification { "UserInput" | '{ fieldNonNull: "str", fieldNestedInput: { street: "nestedStr"} }' } + + def "different field descriptions on interface vs implementation should not cause an error "() { + given: + def sdl = """ + type Query { hello: String } + interface Customer { + "The display name of the customer" + displayName: String! + } + + type PersonCustomer implements Customer { + "The display name of the customer. For persons, this is the first and last name." + displayName: String! + } + + type CompanyCustomer implements Customer { + "The display name of the customer. For companies, this is the company name and its form." + displayName: String! + }""" + + when: + def schema = TestUtil.schema(sdl); + + then: + schema != null + + } + + def "different argument descriptions on interface vs implementation should not cause an error "() { + given: + def sdl = """ + type Query { hello: String } + + interface Customer { + displayName( + "interface arg" + arg: String + ): String! + } + + type PersonCustomer implements Customer { + displayName( + "impl arg 1" + arg: String + ): String! + } + + type CompanyCustomer implements Customer { + displayName( + arg: String + ): String! + }""" + + when: + def schema = TestUtil.schema(sdl); + + then: + schema != null + + } + + def "different argument comments on interface vs implementation should not cause an error "() { + given: + def sdl = """ + type Query { hello: String } + + interface Customer { + displayName( + # interface arg + arg: String + ): String! + } + + type PersonCustomer implements Customer { + displayName( + # impl arg 1 + arg: String + ): String! + } + + type CompanyCustomer implements Customer { + displayName( + arg: String + ): String! + }""" + + when: + def schema = TestUtil.schema(sdl); + + then: + schema != null + + } + + def "field in base interface type redefined in extension type should cause an error"() { + given: + def sdl = """ + type Query { hello: String } + + interface Human { + id: ID! + name: String! + } + extend interface Human { + name: String! + friends: [String] + } + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "'Human' extension type [@n:n] tried to redefine field 'name' [@n:n]") + + } + + def "field in interface extension type redefined in another extension type should cause an error"() { + given: + def sdl = """ + type Query { hello: String } + + interface Human { + id: ID! + } + + extend interface Human { + name: String! + } + + extend interface Human { + name: String! + friends: [String] + } + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "'Human' extension type [@n:n] tried to redefine field 'name' [@n:n]") + + } + + def "field in base input type redefined in extension type should cause an error"() { + given: + def sdl = """ + type Query { hello: String } + + input Human { + id: ID! + name: String! + } + extend input Human { + name: String! + friends: [String] + } + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "'Human' extension type [@n:n] tried to redefine field 'name' [@n:n]") + + } + + def "union type name must not begin with '__'"() { + given: + def sdl = """ + type Query { hello: String } + + type Bar { + id : ID! + } + + type Foo { + id : ID! + } + + union __FooBar = Bar | Foo + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "'__FooBar' must not begin with '__', which is reserved by GraphQL introspection.") + } + + def "union type must include one or more member types"() { + given: + def sdl = """ + type Query { hello: String } + + union UnionType + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "Union type 'UnionType' must include one or more member types.") + } + + def "The member types of a Union type must all be object base types"() { + given: + def sdl = """ + type Query { hello: String } + + type A { hello: String } + + interface B { hello: String } + + union UnionType = A | B + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "The member types of a Union type must all be Object base types. member type 'B' in Union 'UnionType' is invalid.") + } + + def "The member types of a Union type must be unique"() { + given: + def sdl = """ + type Query { hello: String } + + type Bar { + id : ID! + } + + union DuplicateBar = Bar | Bar + """ + + when: + def result = check(sdl) + + then: + errorContaining(result, "member type 'Bar' in Union 'DuplicateBar' is not unique. The member types of a Union type must be unique.") + } + + def "how many errors do we get on type extension field redefinition"() { + def sdl = """ + + type Query { + foo : Foo + } + + type Foo { + foo : String + } + + extend type Foo { + redefinedField : String + } + + extend type Foo { + otherField1 : String + } + + extend type Foo { + otherField2 : String + } + + extend type Foo { + redefinedField : String + } + + extend type Foo { + redefinedField : String + } + + interface InterfaceType { + foo : String + } + + extend interface InterfaceType { + redefinedInterfaceField : String + } + + extend interface InterfaceType { + otherField1 : String + } + + extend interface InterfaceType { + otherField2 : String + } + + extend interface InterfaceType { + redefinedInterfaceField : String + } + + extend interface InterfaceType { + redefinedInterfaceField : String + } + + input Bar { + bar : String + } + + extend input Bar { + redefinedInputField : String + } + + extend input Bar { + otherField1 : String + } + + extend input Bar { + otherField2 : String + } + + extend input Bar { + redefinedInputField : String + } + + extend input Bar { + redefinedInputField : String + } + + enum Baz { + baz + } + + extend enum Baz { + redefinedEnumValue + } + + extend enum Baz { + otherField1 + } + + extend enum Baz { + otherField2 + } + + extend enum Baz { + redefinedEnumValue + } + + extend enum Baz { + redefinedEnumValue + } + + """ + + when: + def result = check(sdl) + + then: + result.size() == 8 + errorContaining(result, "'Foo' extension type [@n:n] tried to redefine field 'redefinedField' [@n:n]") + errorContaining(result, "'InterfaceType' extension type [@n:n] tried to redefine field 'redefinedInterfaceField' [@n:n]") + errorContaining(result, "'Bar' extension type [@n:n] tried to redefine field 'redefinedInputField' [@n:n]") + errorContaining(result, "'Baz' extension type [@n:n] tried to redefine enum value 'redefinedEnumValue' [@n:n]") + } } diff --git a/src/test/groovy/graphql/schema/idl/SchemaTypeDirectivesCheckerTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaTypeDirectivesCheckerTest.groovy index a88bbc6822..887fe97f5c 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaTypeDirectivesCheckerTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaTypeDirectivesCheckerTest.groovy @@ -1,9 +1,14 @@ package graphql.schema.idl +import graphql.Scalars +import graphql.schema.GraphQLScalarType import graphql.schema.idl.errors.DirectiveIllegalLocationError +import graphql.schema.idl.errors.DirectiveIllegalReferenceError import graphql.schema.idl.errors.DirectiveMissingNonNullArgumentError import graphql.schema.idl.errors.DirectiveUndeclaredError import graphql.schema.idl.errors.DirectiveUnknownArgumentError +import graphql.schema.idl.errors.IllegalNameError +import graphql.schema.idl.errors.NotAnInputTypeError import spock.lang.Specification class SchemaTypeDirectivesCheckerTest extends Specification { @@ -22,6 +27,8 @@ class SchemaTypeDirectivesCheckerTest extends Specification { ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + directive @d(arg: String @testDirective) on FIELD + type ObjectType @testDirective(knownArg : "x") { field(arg1 : String @testDirective(knownArg : "x")) : String @testDirective(knownArg : "x") @@ -203,4 +210,131 @@ class SchemaTypeDirectivesCheckerTest extends Specification { errors.size() == 1 errors.each { assert it instanceof DirectiveMissingNonNullArgumentError } } + + def "directive must not reference itself"() { + given: + def spec = ''' + directive @invalidExample(arg: String @invalidExample) on ARGUMENT_DEFINITION + + type Query { + f1 : String + } + ''' + def registry = parse(spec) + def errors = [] + + when: + new SchemaTypeDirectivesChecker(registry, RuntimeWiring.newRuntimeWiring().build()).checkTypeDirectives(errors) + + then: + errors.size() == 1 + errors.get(0) instanceof DirectiveIllegalReferenceError + errors.get(0).getMessage() == "'invalidExample' must not reference itself on 'arg''[@2:39]'" + } + + def "directive must not begin with '__'"() { + given: + def spec = ''' + directive @__invalidExample on ARGUMENT_DEFINITION + + type Query { + f1 : String + } + ''' + def registry = parse(spec) + def errors = [] + + when: + new SchemaTypeDirectivesChecker(registry, RuntimeWiring.newRuntimeWiring().build()).checkTypeDirectives(errors) + + then: + errors.size() == 1 + errors.get(0) instanceof IllegalNameError + errors.get(0).getMessage() == "'__invalidExample''[@2:13]' must not begin with '__', which is reserved by GraphQL introspection." + } + + def "arguments of directive must not have a name which begins with the characters '__' "() { + given: + def spec = ''' + directive @directiveExample(__arg: String) on ARGUMENT_DEFINITION + + type Query { + f1 : String + } + ''' + def registry = parse(spec) + def errors = [] + + when: + new SchemaTypeDirectivesChecker(registry, RuntimeWiring.newRuntimeWiring().build()).checkTypeDirectives(errors) + + then: + errors.size() == 1 + errors.get(0) instanceof IllegalNameError + errors.get(0).getMessage() == "'__arg''[@2:41]' must not begin with '__', which is reserved by GraphQL introspection." + } + + def "arguments of directive is not an input type"() { + given: + def spec = ''' + type NotInputType{ + field: String + } + + directive @directiveExample(arg: NotInputType) on ARGUMENT_DEFINITION + + type Query { + f1 : String + } + ''' + def registry = parse(spec) + def errors = [] + + when: + new SchemaTypeDirectivesChecker(registry, RuntimeWiring.newRuntimeWiring().build()).checkTypeDirectives(errors) + + then: + errors.size() == 1 + errors.get(0) instanceof NotAnInputTypeError + errors.get(0).getMessage() == "The type 'NotInputType' [@2:13] is not an input type, but was used as an input type [@6:46]" + } + + def "uses runtime wiring factory for scalars"() { + given: + def spec = ''' + directive @testDirective(knownArg : ScalarType!) on OBJECT + + scalar ScalarType + + type ObjectType @testDirective(knownArg : "x") { + field : String + } + ''' + def registry = parse(spec) + def scalarType = GraphQLScalarType + .newScalar(Scalars.GraphQLString) + .name("ScalarType") + .build() + def runtimeWiring = RuntimeWiring + .newRuntimeWiring() + .wiringFactory(new WiringFactory() { + @Override + boolean providesScalar(ScalarWiringEnvironment environment) { + return environment.scalarTypeDefinition.name == scalarType.name + } + + @Override + GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { + return scalarType + } + }) + .build() + def errors = [] + + when: + new SchemaTypeDirectivesChecker(registry, runtimeWiring).checkTypeDirectives(errors) + + then: + errors.size() == 0 + } } diff --git a/src/test/groovy/graphql/schema/idl/TestLiveMockedWiringFactory.groovy b/src/test/groovy/graphql/schema/idl/TestLiveMockedWiringFactory.groovy new file mode 100644 index 0000000000..fe12c3a1b1 --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/TestLiveMockedWiringFactory.groovy @@ -0,0 +1,110 @@ +package graphql.schema.idl + +import graphql.TypeResolutionEnvironment +import graphql.schema.Coercing +import graphql.schema.CoercingParseLiteralException +import graphql.schema.CoercingParseValueException +import graphql.schema.CoercingSerializeException +import graphql.schema.DataFetcher +import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLScalarType +import graphql.schema.GraphQLTypeUtil +import graphql.schema.GraphQLUnionType +import graphql.schema.PropertyDataFetcher +import graphql.schema.SingletonPropertyDataFetcher +import graphql.schema.TypeResolver + +class TestLiveMockedWiringFactory implements WiringFactory { + + private final Map scalars + + TestLiveMockedWiringFactory() { + this.scalars = new HashMap<>() + } + + TestLiveMockedWiringFactory(List scalars) { + this.scalars = new HashMap<>() + scalars.forEach({ scalar -> this.scalars.put(scalar.getName(), scalar) }) + } + + @Override + boolean providesTypeResolver(InterfaceWiringEnvironment environment) { + return true + } + + @Override + TypeResolver getTypeResolver(InterfaceWiringEnvironment environment) { + new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + def fieldType = GraphQLTypeUtil.unwrapAll(env.getFieldType()) + env.getSchema().getImplementations((GraphQLInterfaceType) fieldType).get(0) + } + } + } + + @Override + boolean providesTypeResolver(UnionWiringEnvironment environment) { + return true + } + + @Override + TypeResolver getTypeResolver(UnionWiringEnvironment environment) { + new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + def fieldType = GraphQLTypeUtil.unwrapAll(env.getFieldType()) + GraphQLObjectType graphQLObjectType + def unionFirstType = ((GraphQLUnionType) fieldType).getTypes().get(0) + if (unionFirstType instanceof GraphQLInterfaceType) { + graphQLObjectType = env.getSchema().getImplementations((GraphQLInterfaceType) unionFirstType).get(0) + } else { + graphQLObjectType = unionFirstType as GraphQLObjectType + } + return graphQLObjectType + } + } + } + + + @Override + boolean providesDataFetcher(FieldWiringEnvironment environment) { + return true + } + + @Override + DataFetcher getDataFetcher(FieldWiringEnvironment environment) { + return SingletonPropertyDataFetcher.singleton() + } + + @Override + boolean providesScalar(ScalarWiringEnvironment environment) { + if (ScalarInfo.isGraphqlSpecifiedScalar(environment.getScalarTypeDefinition().getName())) { + return false + } + return true + } + + @Override + GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { + + String scalarName = environment.getScalarTypeDefinition().getName() + return scalars.computeIfAbsent(scalarName, name -> GraphQLScalarType.newScalar().name(name).coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + throw new UnsupportedOperationException("Not implemented...this is only a mocked scalar") + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + throw new UnsupportedOperationException("Not implemented...this is only a mocked scalar") + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + throw new UnsupportedOperationException("Not implemented...this is only a mocked scalar") + } + }).build()) + } +} diff --git a/src/test/groovy/graphql/schema/idl/TestMockedWiringFactory.groovy b/src/test/groovy/graphql/schema/idl/TestMockedWiringFactory.groovy new file mode 100644 index 0000000000..827fadafbb --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/TestMockedWiringFactory.groovy @@ -0,0 +1,82 @@ +package graphql.schema.idl + +import graphql.TypeResolutionEnvironment +import graphql.schema.Coercing +import graphql.schema.CoercingParseLiteralException +import graphql.schema.CoercingParseValueException +import graphql.schema.CoercingSerializeException +import graphql.schema.DataFetcher +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLScalarType +import graphql.schema.PropertyDataFetcher +import graphql.schema.TypeResolver + +/** + * There is a {@link MockedWiringFactory} in the main code base now but this one is retained + * for testing purposes. + */ +class TestMockedWiringFactory implements WiringFactory { + + @Override + boolean providesTypeResolver(InterfaceWiringEnvironment environment) { + return true + } + + @Override + TypeResolver getTypeResolver(InterfaceWiringEnvironment environment) { + new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + throw new UnsupportedOperationException("Not implemented") + } + } + } + + @Override + boolean providesTypeResolver(UnionWiringEnvironment environment) { + return true + } + + @Override + TypeResolver getTypeResolver(UnionWiringEnvironment environment) { + new TypeResolver() { + @Override + GraphQLObjectType getType(TypeResolutionEnvironment env) { + throw new UnsupportedOperationException("Not implemented") + } + } + } + + @Override + boolean providesDataFetcher(FieldWiringEnvironment environment) { + // rely on defaulting in code registry + return false + } + + @Override + boolean providesScalar(ScalarWiringEnvironment environment) { + if (ScalarInfo.isGraphqlSpecifiedScalar(environment.getScalarTypeDefinition().getName())) { + return false + } + return true + } + + GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { + return GraphQLScalarType.newScalar().name(environment.getScalarTypeDefinition().getName()).coercing(new Coercing() { + @Override + Object serialize(Object dataFetcherResult) throws CoercingSerializeException { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + Object parseValue(Object input) throws CoercingParseValueException { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + Object parseLiteral(Object input) throws CoercingParseLiteralException { + throw new UnsupportedOperationException("Not implemented"); + } + }).build() + } +} diff --git a/src/test/groovy/graphql/schema/idl/TestTripleQuotedCommentSupport.groovy b/src/test/groovy/graphql/schema/idl/TestTripleQuotedCommentSupport.groovy new file mode 100644 index 0000000000..b218ea4f23 --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/TestTripleQuotedCommentSupport.groovy @@ -0,0 +1,76 @@ +package graphql.schema.idl + + +import graphql.TestUtil +import graphql.introspection.IntrospectionQuery +import spock.lang.Specification + +class TestTripleQuotedCommentSupport extends Specification { + + def "1405 - triple quote support in Introspection"() { + def sdl = ''' +""" +A simple GraphQL schema which is well described. +And has multiple lines of description +""" +type Query { + """ + Translates a string from a given language into a different language. + """ + translate( + "The original language that `text` is provided in." + fromLanguage: Language + + "The translated language to be returned." + toLanguage: Language + + "The text to be translated." + text: String + ): String +} + +""" +The set of languages supported by `translate`. +""" +enum Language { + "English" + EN + + "French" + FR + + "Chinese" + CH +} +''' + + def graphQL = TestUtil.graphQL(sdl).build() + + when: + def er = graphQL.execute(IntrospectionQuery.INTROSPECTION_QUERY) + then: + er.errors.isEmpty() + def introspection = er.data + def types = introspection["__schema"]["types"] + + def queryType = typeKindNamed(types, "OBJECT", "Query") + queryType["description"] == """A simple GraphQL schema which is well described.\nAnd has multiple lines of description""" + + def translateField = named(queryType["fields"], "translate") + translateField["description"] == "Translates a string from a given language into a different language." + + def fromLanguage = named(translateField["args"], "fromLanguage") + fromLanguage["description"] == "The original language that `text` is provided in." + + def languageEnum = typeKindNamed(types, "ENUM", "Language") + languageEnum["description"] == "The set of languages supported by `translate`." + } + + def typeKindNamed(types, String kind, String named) { + types.find { it -> it["name"] == named && it["kind"] == kind.toUpperCase() } + } + + def named(list, String named) { + list.find { it -> it["name"] == named } + } +} diff --git a/src/test/groovy/graphql/schema/idl/TypeDefinitionRegistryTest.groovy b/src/test/groovy/graphql/schema/idl/TypeDefinitionRegistryTest.groovy index 7a2f7cb1d6..0ebd6dc882 100644 --- a/src/test/groovy/graphql/schema/idl/TypeDefinitionRegistryTest.groovy +++ b/src/test/groovy/graphql/schema/idl/TypeDefinitionRegistryTest.groovy @@ -15,20 +15,26 @@ import graphql.language.ScalarTypeDefinition import graphql.language.ScalarTypeExtensionDefinition import graphql.language.SchemaDefinition import graphql.language.Type +import graphql.language.TypeDefinition import graphql.language.TypeName import graphql.language.UnionTypeDefinition import graphql.language.UnionTypeExtensionDefinition +import graphql.parser.MultiSourceReader +import graphql.schema.GraphQLTypeUtil import graphql.schema.idl.errors.SchemaProblem import graphql.schema.idl.errors.SchemaRedefinitionError import spock.lang.Specification import spock.lang.Unroll +import java.util.stream.Collectors + class TypeDefinitionRegistryTest extends Specification { - TypeDefinitionRegistry parse(String spec) { + static TypeDefinitionRegistry parse(String spec) { new SchemaParser().parse(spec) } + def "test default scalars are locked in"() { def registry = new TypeDefinitionRegistry() @@ -43,13 +49,6 @@ class TypeDefinitionRegistryTest extends Specification { scalars.containsKey("Boolean") scalars.containsKey("ID") - // graphql-java library extensions - scalars.containsKey("Long") - scalars.containsKey("BigInteger") - scalars.containsKey("BigDecimal") - scalars.containsKey("Short") - scalars.containsKey("Char") - } def "adding 2 schemas is not allowed"() { @@ -331,6 +330,18 @@ class TypeDefinitionRegistryTest extends Specification { !registry.isInterfaceOrUnion(type("Scalar")) } + def "test object type or interface detection"() { + + when: + def registry = parse(commonSpec) + + then: + registry.isObjectTypeOrInterface(type("Type")) + registry.isObjectTypeOrInterface(type("Interface")) + !registry.isObjectTypeOrInterface(type("Union")) + !registry.isObjectTypeOrInterface(type("Scalar")) + } + def "test object type detection"() { when: @@ -364,7 +375,7 @@ class TypeDefinitionRegistryTest extends Specification { } - def "test can get implements of interface"() { + def "test can get implements of interface #typeOfReg"() { def spec = ''' interface Interface { name : String @@ -385,14 +396,30 @@ class TypeDefinitionRegistryTest extends Specification { type Type4 implements NotThatInterface { name : String } + + interface Type5 implements Interface { + name : String + } + + interface Type6 implements NotThatInterface { + name : String + } ''' when: def registry = parse(spec) - def interfaceDef = registry.getType("Interface", InterfaceTypeDefinition.class).get() - def objectTypeDefinitions = registry.getImplementationsOf(interfaceDef) - def names = objectTypeDefinitions.collect { it.getName() } + if (typeOfReg == "immutable") { + registry = registry.readOnly() + } + def interfaceDef = registry.getTypeOrNull("Interface", InterfaceTypeDefinition.class) + def implementingTypeDefinitions = registry.getAllImplementationsOf(interfaceDef) + def names = implementingTypeDefinitions.collect { it.getName() } then: - names == ["Type1", "Type2", "Type3"] + names == ["Type1", "Type2", "Type3", "Type5"] + + where: + typeOfReg | _ + "mutable" | _ + "immutable" | _ } def animalia = ''' @@ -403,38 +430,58 @@ class TypeDefinitionRegistryTest extends Specification { interface Mammal { id: String! + mother: Mammal! + offspring: [Mammal!]! } interface Reptile { id: String! } - type Dog implements Animal, Mammal { + interface Canine implements Animal & Mammal { id: String! + mother: Canine! + offspring: [Canine!]! } - type Duck implements Animal, Mammal { + type Dog implements Animal & Mammal & Canine { id: String! + mother: Dog! + offspring: [Dog!]! } - + + type Duck implements Animal { + id: String! + } + union Platypus = Duck | Turtle - type Cat implements Animal, Mammal { + type Cat implements Animal & Mammal { id: String! + mother: Cat! + offspring: [Cat!]! } - type Turtle implements Animal, Reptile { + type Turtle implements Animal & Reptile { id: String! } ''' - def "test possible type detection"() { + def "test possible type detection #typeOfReg"() { + given: + TypeDefinitionRegistry mutableReg = parse(animalia) + ImmutableTypeDefinitionRegistry immutableReg = mutableReg.readOnly() + when: - def registry = parse(animalia) + def registry = mutableReg + if (typeOfReg == "immutable") { + registry = immutableReg + } then: + registry.isPossibleType(type("Mammal"), type("Canine")) registry.isPossibleType(type("Mammal"), type("Dog")) registry.isPossibleType(type("Mammal"), type("Cat")) !registry.isPossibleType(type("Mammal"), type("Turtle")) @@ -443,6 +490,7 @@ class TypeDefinitionRegistryTest extends Specification { !registry.isPossibleType(type("Reptile"), type("Cat")) registry.isPossibleType(type("Reptile"), type("Turtle")) + registry.isPossibleType(type("Animal"), type("Canine")) registry.isPossibleType(type("Animal"), type("Dog")) registry.isPossibleType(type("Animal"), type("Cat")) registry.isPossibleType(type("Animal"), type("Turtle")) @@ -452,16 +500,28 @@ class TypeDefinitionRegistryTest extends Specification { !registry.isPossibleType(type("Platypus"), type("Dog")) !registry.isPossibleType(type("Platypus"), type("Cat")) + where: + typeOfReg | _ + "mutable" | _ + "immutable" | _ } - def "isSubTypeOf detection"() { + def "isSubTypeOf detection #typeOfReg"() { when: def registry = parse(animalia) + if (typeOfReg == "immutable") { + registry = registry.readOnly() + } then: registry.isSubTypeOf(type("Mammal"), type("Mammal")) + registry.isSubTypeOf(type("Canine"), type("Animal")) + registry.isSubTypeOf(type("Canine"), type("Mammal")) + registry.isSubTypeOf(type("Canine"), type("Canine")) + registry.isSubTypeOf(type("Dog"), type("Animal")) registry.isSubTypeOf(type("Dog"), type("Mammal")) + registry.isSubTypeOf(type("Dog"), type("Canine")) registry.isSubTypeOf(type("Turtle"), type("Animal")) !registry.isSubTypeOf(type("Turtle"), type("Mammal")) @@ -471,11 +531,19 @@ class TypeDefinitionRegistryTest extends Specification { registry.isSubTypeOf(listType("Mammal"), listType("Mammal")) !registry.isSubTypeOf(listType("Mammal"), type("Mammal")) // but not if they aren't both lists + registry.isSubTypeOf(listType("Canine"), listType("Mammal")) + registry.isSubTypeOf(listType("Canine"), listType("Animal")) // unwraps all the way down registry.isSubTypeOf(listType(nonNullType(listType(type("Dog")))), listType(nonNullType(listType(type("Mammal"))))) + registry.isSubTypeOf(listType(nonNullType(listType(type("Canine")))), listType(nonNullType(listType(type("Mammal"))))) !registry.isSubTypeOf(listType(nonNullType(listType(type("Turtle")))), listType(nonNullType(listType(type("Mammal"))))) + + where: + typeOfReg | _ + "mutable" | _ + "immutable" | _ } @Unroll @@ -486,7 +554,7 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(definition) then: - !registry.getType(definition.getName()).isPresent() + registry.getTypeOrNull(definition.getName()) == null where: definition | _ @@ -498,7 +566,7 @@ class TypeDefinitionRegistryTest extends Specification { InputObjectTypeDefinition.newInputObjectDefinition().name("foo").build() | _ } - def "remove directive definition"() { + def "remove single directive definition from list"() { given: DirectiveDefinition definition = DirectiveDefinition.newDirectiveDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -509,8 +577,47 @@ class TypeDefinitionRegistryTest extends Specification { !registry.getDirectiveDefinition(definition.getName()).isPresent() } + def "remove multiple directive definition from list"() { + given: + DirectiveDefinition definition1 = DirectiveDefinition.newDirectiveDefinition().name("foo").build() + DirectiveDefinition definition2 = DirectiveDefinition.newDirectiveDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(definition1) + registry.add(definition2) + when: + registry.remove(definition1) + then: + !registry.getDirectiveDefinition(definition1.getName()).isPresent() + registry.getDirectiveDefinition(definition2.getName()).isPresent() + } - def "remove object type extension"() { + def "remove single directive definition from map"() { + given: + DirectiveDefinition definition = DirectiveDefinition.newDirectiveDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(definition) + when: + registry.remove(definition.getName(), definition) + then: + !registry.getDirectiveDefinition(definition.getName()).isPresent() + } + + def "remove multiple directive definition from map"() { + given: + DirectiveDefinition definition1 = DirectiveDefinition.newDirectiveDefinition().name("foo").build() + DirectiveDefinition definition2 = DirectiveDefinition.newDirectiveDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(definition1) + registry.add(definition2) + when: + registry.remove(definition1.getName(), definition1) + then: + !registry.getDirectiveDefinition(definition1.getName()).isPresent() + registry.getDirectiveDefinition(definition2.getName()).isPresent() + } + + + def "remove single object type extension from list"() { given: def extension = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -518,10 +625,51 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(extension) then: - !registry.objectTypeExtensions().get(extension.getName()).contains(extension) + !registry.objectTypeExtensions().containsKey(extension.getName()) } - def "remove interface type extension"() { + def "remove multiple object type extension from list"() { + given: + def extension1 = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("foo").build() + def extension2 = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1) + then: + !registry.objectTypeExtensions().containsKey(extension1.getName()) + registry.objectTypeExtensions().containsKey(extension2.getName()) + registry.objectTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single object type extension from map"() { + given: + def extension = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension) + when: + registry.remove(extension.getName(), extension) + then: + !registry.objectTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple object type extension from map"() { + given: + def extension1 = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("foo").build() + def extension2 = ObjectTypeExtensionDefinition.newObjectTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1.getName(), extension1) + then: + !registry.objectTypeExtensions().containsKey(extension1.getName()) + registry.objectTypeExtensions().containsKey(extension2.getName()) + registry.objectTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single interface type extension from list"() { given: def extension = InterfaceTypeExtensionDefinition.newInterfaceTypeExtensionDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -529,10 +677,51 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(extension) then: - !registry.interfaceTypeExtensions().get(extension.getName()).contains(extension) + !registry.interfaceTypeExtensions().containsKey(extension.getName()) } - def "remove union type extension"() { + def "remove multiple interface type extension from list"() { + given: + def extension1 = InterfaceTypeExtensionDefinition.newInterfaceTypeExtensionDefinition().name("foo").build() + def extension2 = InterfaceTypeExtensionDefinition.newInterfaceTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1) + then: + !registry.interfaceTypeExtensions().containsKey(extension1.getName()) + registry.interfaceTypeExtensions().containsKey(extension2.getName()) + registry.interfaceTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single interface type extension from map"() { + given: + def extension = InterfaceTypeExtensionDefinition.newInterfaceTypeExtensionDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension) + when: + registry.remove(extension.getName(), extension) + then: + !registry.interfaceTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple interface type extension from map"() { + given: + def extension1 = InterfaceTypeExtensionDefinition.newInterfaceTypeExtensionDefinition().name("foo").build() + def extension2 = InterfaceTypeExtensionDefinition.newInterfaceTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1.getName(), extension1) + then: + !registry.interfaceTypeExtensions().containsKey(extension1.getName()) + registry.interfaceTypeExtensions().containsKey(extension2.getName()) + registry.interfaceTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single union type extension from list"() { given: def extension = UnionTypeExtensionDefinition.newUnionTypeExtensionDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -540,10 +729,51 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(extension) then: - !registry.unionTypeExtensions().get(extension.getName()).contains(extension) + !registry.unionTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple union type extension from list"() { + given: + def extension1 = UnionTypeExtensionDefinition.newUnionTypeExtensionDefinition().name("foo").build() + def extension2 = UnionTypeExtensionDefinition.newUnionTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1) + then: + !registry.unionTypeExtensions().containsKey(extension1.getName()) + registry.unionTypeExtensions().containsKey(extension2.getName()) + registry.unionTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single union type extension from map"() { + given: + def extension = UnionTypeExtensionDefinition.newUnionTypeExtensionDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension) + when: + registry.remove(extension.getName(), extension) + then: + !registry.unionTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple union type extension from map"() { + given: + def extension1 = UnionTypeExtensionDefinition.newUnionTypeExtensionDefinition().name("foo").build() + def extension2 = UnionTypeExtensionDefinition.newUnionTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1.getName(), extension1) + then: + !registry.unionTypeExtensions().containsKey(extension1.getName()) + registry.unionTypeExtensions().containsKey(extension2.getName()) + registry.unionTypeExtensions().get(extension2.getName()).contains(extension2) } - def "remove enum type extension"() { + def "remove single enum type extension from list"() { given: def extension = EnumTypeExtensionDefinition.newEnumTypeExtensionDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -551,10 +781,51 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(extension) then: - !registry.enumTypeExtensions().get(extension.getName()).contains(extension) + !registry.enumTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple enum type extension from list"() { + given: + def extension1 = EnumTypeExtensionDefinition.newEnumTypeExtensionDefinition().name("foo").build() + def extension2 = EnumTypeExtensionDefinition.newEnumTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1) + then: + !registry.enumTypeExtensions().containsKey(extension1.getName()) + registry.enumTypeExtensions().containsKey(extension2.getName()) + registry.enumTypeExtensions().get(extension2.getName()).contains(extension2) } - def "remove scalar type extension"() { + def "remove single enum type extension from map"() { + given: + def extension = EnumTypeExtensionDefinition.newEnumTypeExtensionDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension) + when: + registry.remove(extension.getName(), extension) + then: + !registry.enumTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple enum type extension from map"() { + given: + def extension1 = EnumTypeExtensionDefinition.newEnumTypeExtensionDefinition().name("foo").build() + def extension2 = EnumTypeExtensionDefinition.newEnumTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1.getName(), extension1) + then: + !registry.enumTypeExtensions().containsKey(extension1.getName()) + registry.enumTypeExtensions().containsKey(extension2.getName()) + registry.enumTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single scalar type extension from list"() { given: def extension = ScalarTypeExtensionDefinition.newScalarTypeExtensionDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -562,10 +833,51 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(extension) then: - !registry.scalarTypeExtensions().get(extension.getName()).contains(extension) + !registry.scalarTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple scalar type extension from list"() { + given: + def extension1 = ScalarTypeExtensionDefinition.newScalarTypeExtensionDefinition().name("foo").build() + def extension2 = ScalarTypeExtensionDefinition.newScalarTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1) + then: + !registry.scalarTypeExtensions().containsKey(extension1.getName()) + registry.scalarTypeExtensions().containsKey(extension2.getName()) + registry.scalarTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single scalar type extension from map"() { + given: + def extension = ScalarTypeExtensionDefinition.newScalarTypeExtensionDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension) + when: + registry.remove(extension.getName(), extension) + then: + !registry.scalarTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple scalar type extension from map"() { + given: + def extension1 = ScalarTypeExtensionDefinition.newScalarTypeExtensionDefinition().name("foo").build() + def extension2 = ScalarTypeExtensionDefinition.newScalarTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1.getName(), extension1) + then: + !registry.scalarTypeExtensions().containsKey(extension1.getName()) + registry.scalarTypeExtensions().containsKey(extension2.getName()) + registry.scalarTypeExtensions().get(extension2.getName()).contains(extension2) } - def "remove input object type extension"() { + def "remove single input object type extension from list"() { given: def extension = InputObjectTypeExtensionDefinition.newInputObjectTypeExtensionDefinition().name("foo").build() def registry = new TypeDefinitionRegistry() @@ -573,7 +885,48 @@ class TypeDefinitionRegistryTest extends Specification { when: registry.remove(extension) then: - !registry.inputObjectTypeExtensions().get(extension.getName()).contains(extension) + !registry.inputObjectTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple input object type extension from list"() { + given: + def extension1 = InputObjectTypeExtensionDefinition.newInputObjectTypeExtensionDefinition().name("foo").build() + def extension2 = InputObjectTypeExtensionDefinition.newInputObjectTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1) + then: + !registry.inputObjectTypeExtensions().containsKey(extension1.getName()) + registry.inputObjectTypeExtensions().containsKey(extension2.getName()) + registry.inputObjectTypeExtensions().get(extension2.getName()).contains(extension2) + } + + def "remove single input object type extension from map"() { + given: + def extension = InputObjectTypeExtensionDefinition.newInputObjectTypeExtensionDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension) + when: + registry.remove(extension.getName(), extension) + then: + !registry.inputObjectTypeExtensions().containsKey(extension.getName()) + } + + def "remove multiple input object type extension from map"() { + given: + def extension1 = InputObjectTypeExtensionDefinition.newInputObjectTypeExtensionDefinition().name("foo").build() + def extension2 = InputObjectTypeExtensionDefinition.newInputObjectTypeExtensionDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + registry.add(extension1) + registry.add(extension2) + when: + registry.remove(extension1.getName(), extension1) + then: + !registry.inputObjectTypeExtensions().containsKey(extension1.getName()) + registry.inputObjectTypeExtensions().containsKey(extension2.getName()) + registry.inputObjectTypeExtensions().get(extension2.getName()).contains(extension2) } def "remove schema definition"() { @@ -586,4 +939,300 @@ class TypeDefinitionRegistryTest extends Specification { then: !registry.schemaDefinition().isPresent() } + + def "addAll can add multiple things successfully"() { + def obj1 = ObjectTypeDefinition.newObjectTypeDefinition().name("foo").build() + def obj2 = ObjectTypeDefinition.newObjectTypeDefinition().name("bar").build() + def registry = new TypeDefinitionRegistry() + when: + registry.addAll(Arrays.asList(obj1, obj2)) + then: + registry.getTypeOrNull("foo") != null + registry.getTypeOrNull("bar") != null + } + + def "addAll will return an error on the first abd thing"() { + def obj1 = ObjectTypeDefinition.newObjectTypeDefinition().name("foo").build() + def obj2 = ObjectTypeDefinition.newObjectTypeDefinition().name("bar").build() + def obj3 = ObjectTypeDefinition.newObjectTypeDefinition().name("bar").build() + def obj4 = ObjectTypeDefinition.newObjectTypeDefinition().name("foo").build() + def registry = new TypeDefinitionRegistry() + when: + def error = registry.addAll(Arrays.asList(obj1, obj2, obj3, obj4)) + then: + error.isPresent() + error.get().getMessage().contains("tried to redefine existing 'bar' type") + } + + def "can be serialized and hence cacheable"() { + def sdl = ''' + "the schema" + schema { + query : Q + } + + "the query type" + type Q { + field( arg : String! = "default") : FieldType @deprecated(reason : "no good") + } + + interface FieldType { + f : UnionType + } + + type FieldTypeImpl implements FieldType { + f : UnionType + } + + union UnionType = Foo | Bar + + type Foo { + foo : String + } + + type Bar { + bar : String + } + ''' + def registryOut = new SchemaParser().parse(sdl) + + when: + + TypeDefinitionRegistry registryIn = serialise(registryOut) + + then: + TypeDefinition typeIn = registryIn.getTypeOrNull(typeName) + TypeDefinition typeOut = registryOut.getTypeOrNull(typeName) + typeIn.isEqualTo(typeOut) + + where: + typeName | _ + "Q" | _ + "FieldType" | _ + "FieldTypeImpl" | _ + "UnionType" | _ + "Foo" | _ + "Bar" | _ + } + + def "can maintain parsed order"() { + def sdl = ''' + "the schema" + schema { + query : Q + } + + "the query type" + type Q { + field( arg : String! = "default") : FieldType @deprecated(reason : "no good") + } + + interface FieldType { + f : UnionType + } + + type FieldTypeImpl implements FieldType { + f : UnionType + } + + union UnionType = Foo | Bar + + type Foo { + foo : String + } + + type Bar { + bar : String + } + + scalar FooScalar + + directive @FooDirective on FIELD_DEFINITION + ''' + + when: + def registry = new SchemaParser().parse(sdl) + def parseOrder = registry.getParseOrder() + def defListInOrder = parseOrder.getInOrder().get("") + def defListInNameOrder = parseOrder.getInNameOrder().get("") + def listOfNames = defListInNameOrder.collect({ d -> d.getName() }) + + then: + + defListInOrder.size() == 9 + + defListInOrder[0] instanceof SchemaDefinition + defListInOrder[1] instanceof ObjectTypeDefinition + defListInOrder[2] instanceof InterfaceTypeDefinition + + defListInOrder[8] instanceof DirectiveDefinition + + listOfNames == ["Q", "FieldType", "FieldTypeImpl", "UnionType", + "Foo", "Bar", "FooScalar", "FooDirective"] + + when: "We merge in a new type registry, they are added to the end" + def extraSDL = ''' + type Extra { + s : String + } + + interface ExtraInterface { + s : String + } + ''' + + def extraRegistry = new SchemaParser().parse(extraSDL) + registry.merge(extraRegistry) + + parseOrder = registry.getParseOrder() + defListInOrder = parseOrder.getInOrder().get("") + defListInNameOrder = parseOrder.getInNameOrder().get("") + listOfNames = defListInNameOrder.collect({ d -> d.getName() }) + + then: + + defListInOrder.size() == 11 + + defListInOrder[0] instanceof SchemaDefinition + defListInOrder[1] instanceof ObjectTypeDefinition + defListInOrder[2] instanceof InterfaceTypeDefinition + + defListInOrder[9] instanceof ObjectTypeDefinition + defListInOrder[10] instanceof InterfaceTypeDefinition + + listOfNames == ["Q", "FieldType", "FieldTypeImpl", "UnionType", + "Foo", "Bar", "FooScalar", "FooDirective", "Extra", "ExtraInterface"] + } + + def "multi source reader works"() { + + def sdl1 = ''' + type Query { + f : IType + } + + scalar FooScalar + ''' + + def sdl2 = ''' + interface IType { + q : FooScalar + } + + type QType { + q : FooScalar + } + ''' + + def sdl3 = ''' + directive @FooDirective on FIELD_DEFINITION + ''' + + def multiSourceReader = MultiSourceReader.newMultiSourceReader() + .string(sdl1, "source1") + .string(sdl2, "source2") + .string(sdl3, null) + .build() + + when: + def registry = new SchemaParser().parse(multiSourceReader) + def parseOrder = registry.getParseOrder() + def inNameOrderMap = parseOrder.getInNameOrder() + + then: + inNameOrderMap.size() == 3 + inNameOrderMap["source1"].collect({ it.getName() }) + == ["Query", "FooScalar"] + inNameOrderMap["source2"].collect({ it.getName() }) + == ["IType", "QType"] + inNameOrderMap[""].collect({ it.getName() }) + == ["FooDirective"] + + } + + def "can created a runtime type comparator"() { + def sdl1 = ''' + type Query { + f : QType @FooDirective + } + + input BInput { + b : String + } + + input AInput { + a : String + } + + scalar FooScalar + ''' + + def sdl2 = ''' + type QType { + c : String + b : ID + a : FooScalar + } + + type XType { + x : String + z : ID + y : FooScalar + } + + ''' + + def sdl3 = ''' + type AType { + y : FooScalar + x : String + z : ID + } + + directive @FooDirective on FIELD_DEFINITION + ''' + + def multiSourceReader = MultiSourceReader.newMultiSourceReader() + .string(sdl1, "source1") + .string(sdl2, "source2") + .string(sdl3, null) + .build() + + when: + def registry = new SchemaParser().parse(multiSourceReader) + def parseOrder = registry.getParseOrder() + def schema = new SchemaGenerator().makeExecutableSchema(registry, RuntimeWiring.MOCKED_WIRING) + + + def schemaElements = schema.getAllElementsAsList().stream() + .filter(GraphQLTypeUtil.isSystemElement().negate()) + .collect(Collectors.toList()) + + schemaElements.sort(parseOrder.getElementComparator()) + + then: + schemaElements.collect({ it.name }) == + ["Query", + "BInput", + "AInput", + "FooScalar", + "QType", + "XType", + "AType", + "FooDirective", + ] + + } + + static TypeDefinitionRegistry serialise(TypeDefinitionRegistry registryOut) { + ByteArrayOutputStream baOS = new ByteArrayOutputStream() + ObjectOutputStream oos = new ObjectOutputStream(baOS) + + oos.writeObject(registryOut) + + ByteArrayInputStream baIS = new ByteArrayInputStream(baOS.toByteArray()) + ObjectInputStream ois = new ObjectInputStream(baIS) + + ois.readObject() as TypeDefinitionRegistry + } } diff --git a/src/test/groovy/graphql/schema/idl/TypeInfoTest.groovy b/src/test/groovy/graphql/schema/idl/TypeInfoTest.groovy index 971fbfc399..556755e436 100644 --- a/src/test/groovy/graphql/schema/idl/TypeInfoTest.groovy +++ b/src/test/groovy/graphql/schema/idl/TypeInfoTest.groovy @@ -1,5 +1,7 @@ package graphql.schema.idl +import graphql.TestUtil +import graphql.language.AstPrinter import graphql.language.ListType import graphql.language.NonNullType import graphql.language.Type @@ -9,6 +11,7 @@ import graphql.schema.GraphQLNonNull import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLType import spock.lang.Specification +import spock.lang.Unroll class TypeInfoTest extends Specification { @@ -112,4 +115,43 @@ class TypeInfoTest extends Specification { assertNotEqualsAndHashCode(new NonNullType(new ListType(new TypeName("A"))), new ListType(new TypeName("A"))) assertNotEqualsAndHashCode(new NonNullType(new ListType(new TypeName("A"))), new NonNullType(new ListType(new TypeName("B")))) } + + + @Unroll + def "test rename works as expected"() { + + expect: + Type actualType = TestUtil.parseType(actual) + def typeInfo = TypeInfo.typeInfo(actualType) + TypeInfo newTypeInfo = typeInfo.renameAs("newName") + def printed = AstPrinter.printAst(newTypeInfo.getRawType()) + printed == expected + + where: + actual | expected + "named" | "newName" + "named!" | "newName!" + "[named]" | "[newName]" + "[named!]" | "[newName!]" + "[named!]!" | "[newName!]!" + "[[named!]!]" | "[[newName!]!]" + } + + @Unroll + def "test getTypeName gets to the inner type"() { + + expect: + Type actualType = TestUtil.parseType(actual) + def typeName = TypeInfo.getTypeName(actualType) + typeName.getName() == expected + + where: + actual | expected + "named" | "named" + "named!" | "named" + "[named]" | "named" + "[named!]" | "named" + "[named!]!" | "named" + "[[named!]!]" | "named" + } } diff --git a/src/test/groovy/graphql/schema/idl/TypeRuntimeWiringTest.groovy b/src/test/groovy/graphql/schema/idl/TypeRuntimeWiringTest.groovy new file mode 100644 index 0000000000..006258cdb3 --- /dev/null +++ b/src/test/groovy/graphql/schema/idl/TypeRuntimeWiringTest.groovy @@ -0,0 +1,85 @@ +package graphql.schema.idl + +import graphql.schema.DataFetcher +import graphql.schema.idl.errors.StrictModeWiringException +import spock.lang.Specification + +class TypeRuntimeWiringTest extends Specification { + + void setup() { + TypeRuntimeWiring.setStrictModeJvmWide(true) + } + + void cleanup() { + TypeRuntimeWiring.setStrictModeJvmWide(true) + } + + DataFetcher DF1 = env -> "x" + DataFetcher DF2 = env -> "y" + + def "strict mode is on by default"() { + when: + TypeRuntimeWiring.newTypeWiring("Foo") + .dataFetcher("foo", DF1) + .dataFetcher("foo", DF2) + .build() + then: + def e = thrown(StrictModeWiringException) + e.message == "The field foo already has a data fetcher defined" + } + + def "strict mode can be turned off"() { + when: + def typeRuntimeWiring = TypeRuntimeWiring.newTypeWiring("Foo") + .strictMode(false) + .dataFetcher("foo", DF1) + .dataFetcher("foo", DF2) + .build() + then: + typeRuntimeWiring.getFieldDataFetchers().get("foo") == DF2 + } + + def "strict mode, on by default, works for maps of fields"() { + when: + TypeRuntimeWiring.newTypeWiring("Foo") + .dataFetcher("foo", DF1) + .dataFetchers(["foo": DF2]) + .build() + then: + def e = thrown(StrictModeWiringException) + e.message == "The field foo already has a data fetcher defined" + } + + def "strict mode can be turned off and on JVM wide"() { + when: + def inStrictMode = TypeRuntimeWiring.getStrictModeJvmWide() + then: + inStrictMode + + when: + TypeRuntimeWiring.setStrictModeJvmWide(false) + inStrictMode = TypeRuntimeWiring.getStrictModeJvmWide() + + TypeRuntimeWiring.newTypeWiring("Foo") + .dataFetcher("foo", DF1) + .dataFetcher("foo", DF2) + .build() + then: + !inStrictMode + noExceptionThrown() + + when: + TypeRuntimeWiring.setStrictModeJvmWide(true) + inStrictMode = TypeRuntimeWiring.getStrictModeJvmWide() + + TypeRuntimeWiring.newTypeWiring("Foo") + .dataFetcher("foo", DF1) + .dataFetcher("foo", DF2) + .build() + + then: + inStrictMode + def e = thrown(StrictModeWiringException) + e.message == "The field foo already has a data fetcher defined" + } +} diff --git a/src/test/groovy/graphql/schema/idl/WiringFactoryTest.groovy b/src/test/groovy/graphql/schema/idl/WiringFactoryTest.groovy index 3f9e68d8e1..70c96fc7da 100644 --- a/src/test/groovy/graphql/schema/idl/WiringFactoryTest.groovy +++ b/src/test/groovy/graphql/schema/idl/WiringFactoryTest.groovy @@ -1,5 +1,6 @@ package graphql.schema.idl + import graphql.TestUtil import graphql.TypeResolutionEnvironment import graphql.schema.Coercing @@ -52,12 +53,12 @@ class WiringFactoryTest extends Specification { @Override boolean providesScalar(ScalarWiringEnvironment environment) { - return name == environment.getInterfaceTypeDefinition().getName() + return name == environment.getScalarTypeDefinition().getName() } @Override GraphQLScalarType getScalar(ScalarWiringEnvironment environment) { - return new GraphQLScalarType(name, "Custom scalar", new Coercing() { + return GraphQLScalarType.newScalar().name(name).description("Custom scalar").coercing(new Coercing() { @Override Object serialize(Object input) { throw new UnsupportedOperationException("Not implemented") @@ -73,6 +74,7 @@ class WiringFactoryTest extends Specification { throw new UnsupportedOperationException("Not implemented") } }) + .build() } @Override @@ -124,6 +126,30 @@ class WiringFactoryTest extends Specification { } } + class NamedDefaultDataFetcherWiringFactory implements WiringFactory { + def fields = [] + + @Override + boolean providesDataFetcher(FieldWiringEnvironment environment) { + if (environment.getFieldDefinition().getName() == "name") { + return true + } + return false + } + + @Override + DataFetcher getDataFetcher(FieldWiringEnvironment environment) { + new PropertyDataFetcher("name") + } + + @Override + DataFetcher getDefaultDataFetcher(FieldWiringEnvironment environment) { + def name = environment.getFieldDefinition().getName() + fields.add(name) + new PropertyDataFetcher(name) + } + } + def "ensure that wiring factory is called to resolve and create data fetchers"() { @@ -161,16 +187,23 @@ class WiringFactoryTest extends Specification { homePlanet: String cyborg: Cyborg } + + type Other implements Character { + name: String! + fetchedByDefaultDataFetcher: String! + } """ - + WiringFactory defaultDataFetcherWiringFactory = new NamedDefaultDataFetcherWiringFactory() def combinedWiringFactory = new CombinedWiringFactory([ new NamedWiringFactory("Character"), new NamedWiringFactory("Cyborg"), new NamedWiringFactory("Long"), new NamedDataFetcherFactoryWiringFactory("cyborg"), - new NamedWiringFactory("friends")]) + new NamedWiringFactory("friends"), + defaultDataFetcherWiringFactory + ]) def wiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(combinedWiringFactory) @@ -182,25 +215,28 @@ class WiringFactoryTest extends Specification { GraphQLInterfaceType characterType = schema.getType("Character") as GraphQLInterfaceType - def characterTypeResolver = characterType.getTypeResolver() as NamedTypeResolver + def characterTypeResolver = schema.getCodeRegistry().getTypeResolver(characterType) as NamedTypeResolver characterTypeResolver.name == "Character" GraphQLUnionType unionType = schema.getType("Cyborg") as GraphQLUnionType - def unionTypeResolver = unionType.getTypeResolver() as NamedTypeResolver + def unionTypeResolver = schema.getCodeRegistry().getTypeResolver(unionType) as NamedTypeResolver unionTypeResolver.name == "Cyborg" GraphQLObjectType humanType = schema.getType("Human") as GraphQLObjectType - def friendsDataFetcher = humanType.getFieldDefinition("friends").getDataFetcher() as NamedDataFetcher + def friendsDataFetcher = schema.getCodeRegistry().getDataFetcher(humanType, humanType.getFieldDefinition("friends")) as NamedDataFetcher friendsDataFetcher.name == "friends" - def cyborgDataFetcher = humanType.getFieldDefinition("cyborg").getDataFetcher() as NamedDataFetcher + def cyborgDataFetcher = schema.getCodeRegistry().getDataFetcher(humanType, humanType.getFieldDefinition("cyborg")) as NamedDataFetcher cyborgDataFetcher.name == "cyborg" GraphQLScalarType longScalar = schema.getType("Long") as GraphQLScalarType longScalar.name == "Long" + + defaultDataFetcherWiringFactory.fields.contains("fetchedByDefaultDataFetcher") + } def "ensure field wiring environment makes sense"() { @@ -223,7 +259,7 @@ class WiringFactoryTest extends Specification { boolean providesDataFetcher(FieldWiringEnvironment environment) { assert ["id", "name", "homePlanet"].contains(environment.fieldDefinition.name) assert environment.parentType.name == "Human" - assert environment.registry.getType("Human").isPresent() + assert environment.registry.getTypeOrNull("Human") != null return true } @@ -231,7 +267,7 @@ class WiringFactoryTest extends Specification { DataFetcher getDataFetcher(FieldWiringEnvironment environment) { assert ["id", "name", "homePlanet"].contains(environment.fieldDefinition.name) assert environment.parentType.name == "Human" - assert environment.registry.getType("Human").isPresent() + assert environment.registry.getTypeOrNull("Human") != null new PropertyDataFetcher(environment.fieldDefinition.name) } } @@ -257,30 +293,7 @@ class WiringFactoryTest extends Specification { } """ - - def fields = [] - - def wiringFactory = new WiringFactory() { - @Override - boolean providesDataFetcher(FieldWiringEnvironment environment) { - if (environment.getFieldDefinition().getName() == "name") { - return true - } - return false - } - - @Override - DataFetcher getDataFetcher(FieldWiringEnvironment environment) { - new PropertyDataFetcher("name") - } - - @Override - DataFetcher getDefaultDataFetcher(FieldWiringEnvironment environment) { - def name = environment.getFieldDefinition().getName() - fields.add(name) - new PropertyDataFetcher(name) - } - } + def wiringFactory = new NamedDefaultDataFetcherWiringFactory() def wiring = RuntimeWiring.newRuntimeWiring() .wiringFactory(wiringFactory) .build() @@ -289,44 +302,30 @@ class WiringFactoryTest extends Specification { expect: - fields == ["id", "homePlanet"] + wiringFactory.fields == ["id", "homePlanet"] } - def "@fetch directive is respected by default data fetcher wiring"() { - def spec = """ - - directive @fetch(from : String!) on FIELD_DEFINITION - - type Query { - name : String, - homePlanet: String @fetch(from : "planetOfBirth") + def "Name"() { + WiringFactory wf = new WiringFactory() { + @Override + boolean providesDataFetcherFactory(FieldWiringEnvironment environment) { + def fieldDef = environment.getFieldDefinition(); + if (fieldDef.getName() == "class") { + return true; + } + return false; } - """ - def wiringFactory = new WiringFactory() { + @Override + DataFetcher getDataFetcher(FieldWiringEnvironment environment) { + return new DataFetcher() { + @Override + Object get(DataFetchingEnvironment env) throws Exception { + def sourceObject = env.getSource() + return sourceObject.getClass().getSimpleName() + } + } + } } - def wiring = RuntimeWiring.newRuntimeWiring() - .wiringFactory(wiringFactory) - .build() - - def schema = TestUtil.schema(spec, wiring) - - GraphQLObjectType type = schema.getType("Query") as GraphQLObjectType - - expect: - def fetcher = type.getFieldDefinition("homePlanet").getDataFetcher() - fetcher instanceof PropertyDataFetcher - - PropertyDataFetcher propertyDataFetcher = fetcher as PropertyDataFetcher - propertyDataFetcher.getPropertyName() == "planetOfBirth" - // - // no directive - plain name - // - def fetcher2 = type.getFieldDefinition("name").getDataFetcher() - fetcher2 instanceof PropertyDataFetcher - - PropertyDataFetcher propertyDataFetcher2 = fetcher2 as PropertyDataFetcher - propertyDataFetcher2.getPropertyName() == "name" - } } diff --git a/src/test/groovy/graphql/schema/SchemaUtilTest.groovy b/src/test/groovy/graphql/schema/impl/SchemaUtilTest.groovy similarity index 63% rename from src/test/groovy/graphql/schema/SchemaUtilTest.groovy rename to src/test/groovy/graphql/schema/impl/SchemaUtilTest.groovy index 1bb3a78c96..a36dfaf924 100644 --- a/src/test/groovy/graphql/schema/SchemaUtilTest.groovy +++ b/src/test/groovy/graphql/schema/impl/SchemaUtilTest.groovy @@ -1,8 +1,17 @@ -package graphql.schema +package graphql.schema.impl import graphql.AssertException +import graphql.DirectivesUtil import graphql.NestedInputSchema import graphql.introspection.Introspection +import graphql.schema.GraphQLAppliedDirectiveArgument +import graphql.schema.GraphQLArgument +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLType +import graphql.schema.GraphQLTypeReference +import graphql.schema.GraphQLUnionType import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean @@ -12,28 +21,46 @@ import static graphql.StarWarsSchema.characterInterface import static graphql.StarWarsSchema.droidType import static graphql.StarWarsSchema.episodeEnum import static graphql.StarWarsSchema.humanType +import static graphql.StarWarsSchema.inputHumanType +import static graphql.StarWarsSchema.mutationType import static graphql.StarWarsSchema.queryType import static graphql.StarWarsSchema.starWarsSchema +import static graphql.TypeReferenceSchema.ArgumentDirectiveInput +import static graphql.TypeReferenceSchema.Cache +import static graphql.TypeReferenceSchema.EnumDirectiveInput +import static graphql.TypeReferenceSchema.EnumValueDirectiveInput +import static graphql.TypeReferenceSchema.FieldDefDirectiveInput +import static graphql.TypeReferenceSchema.InputFieldDefDirectiveInput +import static graphql.TypeReferenceSchema.InputObjectDirectiveInput +import static graphql.TypeReferenceSchema.InterfaceDirectiveInput +import static graphql.TypeReferenceSchema.ObjectDirectiveInput +import static graphql.TypeReferenceSchema.QueryDirectiveInput import static graphql.TypeReferenceSchema.SchemaWithReferences +import static graphql.TypeReferenceSchema.UnionDirectiveInput import static graphql.schema.GraphQLArgument.newArgument import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLInputObjectField.newInputObjectField import static graphql.schema.GraphQLInputObjectType.newInputObject import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema import static graphql.schema.GraphQLTypeReference.typeRef class SchemaUtilTest extends Specification { def "collectAllTypes"() { when: - Map types = new SchemaUtil().allTypes(starWarsSchema, Collections.emptySet()) + def collectingVisitor = new GraphQLTypeCollectingVisitor() + SchemaUtil.visitPartiallySchema(starWarsSchema, collectingVisitor) + Map types = collectingVisitor.getResult() then: - types.size() == 15 + types.size() == 17 types == [(droidType.name) : droidType, (humanType.name) : humanType, (queryType.name) : queryType, + (mutationType.name) : mutationType, (characterInterface.name) : characterInterface, + (inputHumanType.name) : inputHumanType, (episodeEnum.name) : episodeEnum, (GraphQLString.name) : GraphQLString, (Introspection.__Schema.name) : Introspection.__Schema, @@ -49,7 +76,9 @@ class SchemaUtilTest extends Specification { def "collectAllTypesNestedInput"() { when: - Map types = new SchemaUtil().allTypes(NestedInputSchema.createSchema(), Collections.emptySet()) + def collectingVisitor = new GraphQLTypeCollectingVisitor() + SchemaUtil.visitPartiallySchema(NestedInputSchema.createSchema(), collectingVisitor) + Map types = collectingVisitor.getResult() Map expected = [(NestedInputSchema.rootType().name) : NestedInputSchema.rootType(), @@ -70,15 +99,35 @@ class SchemaUtilTest extends Specification { types.keySet() == expected.keySet() } + def "collect all types defined in directives"() { + when: + def collectingVisitor = new GraphQLTypeCollectingVisitor() + SchemaUtil.visitPartiallySchema(SchemaWithReferences, collectingVisitor) + Map types = collectingVisitor.getResult() + + then: + types.size() == 30 + types.containsValue(UnionDirectiveInput) + types.containsValue(InputObjectDirectiveInput) + types.containsValue(ObjectDirectiveInput) + types.containsValue(FieldDefDirectiveInput) + types.containsValue(ArgumentDirectiveInput) + types.containsValue(InputFieldDefDirectiveInput) + types.containsValue(InterfaceDirectiveInput) + types.containsValue(EnumDirectiveInput) + types.containsValue(EnumValueDirectiveInput) + types.containsValue(QueryDirectiveInput) + } + def "group all types by implemented interface"() { when: - Map> byInterface = new SchemaUtil().groupImplementations(starWarsSchema) + Map> byInterface = SchemaUtil.groupInterfaceImplementationsByName(starWarsSchema.getAllTypesAsList()) then: byInterface.size() == 1 byInterface[characterInterface.getName()].size() == 2 byInterface == [ - (characterInterface.getName()): [humanType, droidType] + (characterInterface.getName()): [droidType, humanType] ] } @@ -87,39 +136,58 @@ class SchemaUtilTest extends Specification { GraphQLInputObjectType PersonInputType = newInputObject() .name("Person") .field(newInputObjectField() - .name("name") - .type(GraphQLString)) + .name("name") + .type(GraphQLString)) .build() GraphQLFieldDefinition field = newFieldDefinition() .name("find") .type(typeRef("Person")) .argument(newArgument() - .name("ssn") - .type(GraphQLString)) + .name("ssn") + .type(GraphQLString)) .build() GraphQLObjectType PersonService = newObject() .name("PersonService") .field(field) .build() - def schema = new GraphQLSchema(PersonService, null, Collections.singleton(PersonInputType)) + when: - new SchemaUtil().replaceTypeReferences(schema) + newSchema().query(PersonService).additionalType(PersonInputType).build() then: thrown(ClassCastException) } def "all references are replaced"() { - given: + when: GraphQLUnionType pet = ((GraphQLUnionType) SchemaWithReferences.getType("Pet")) GraphQLObjectType person = ((GraphQLObjectType) SchemaWithReferences.getType("Person")) + GraphQLArgument cacheEnabled = SchemaWithReferences.getDirectivesByName() + .get(Cache.getName()).getArgument("enabled") + GraphQLAppliedDirectiveArgument appliedCacheEnabled = SchemaWithReferences.getSchemaAppliedDirective(Cache.getName()) + .getArgument("enabled") + + then: + SchemaWithReferences.allTypesAsList.findIndexOf { it instanceof GraphQLTypeReference } == -1 + pet.types.findIndexOf { it instanceof GraphQLTypeReference } == -1 + person.interfaces.findIndexOf { it instanceof GraphQLTypeReference } == -1 + !(cacheEnabled.getType() instanceof GraphQLTypeReference) + !(appliedCacheEnabled.getType() instanceof GraphQLTypeReference) + } + + def "all references are replaced with deprecated directiveWithArg"() { when: - new SchemaUtil().replaceTypeReferences(SchemaWithReferences) + GraphQLUnionType pet = ((GraphQLUnionType) SchemaWithReferences.getType("Pet")) + GraphQLObjectType person = ((GraphQLObjectType) SchemaWithReferences.getType("Person")) + GraphQLArgument cacheEnabled = DirectivesUtil.directiveWithArg( // Retain for test coverage + SchemaWithReferences.getDirectives(), Cache.getName(), "enabled").get() + then: SchemaWithReferences.allTypesAsList.findIndexOf { it instanceof GraphQLTypeReference } == -1 pet.types.findIndexOf { it instanceof GraphQLTypeReference } == -1 person.interfaces.findIndexOf { it instanceof GraphQLTypeReference } == -1 + !(cacheEnabled.getType() instanceof GraphQLTypeReference) } def "redefined types are caught"() { @@ -161,7 +229,7 @@ class SchemaUtilTest extends Specification { final GraphQLObjectType mutation = newObject().name("mutation").field(systemWithArgsForMutation) .build() - GraphQLSchema.newSchema().query(queryType).mutation(mutation).build() + newSchema().query(queryType).mutation(mutation).build() then: diff --git a/src/test/groovy/graphql/schema/somepackage/ClassWithDFEMethods.java b/src/test/groovy/graphql/schema/somepackage/ClassWithDFEMethods.java new file mode 100644 index 0000000000..5c04cbf84d --- /dev/null +++ b/src/test/groovy/graphql/schema/somepackage/ClassWithDFEMethods.java @@ -0,0 +1,53 @@ +package graphql.schema.somepackage; + +import graphql.schema.DataFetchingEnvironment; + +@SuppressWarnings("unused") +public class ClassWithDFEMethods { + + public String getMethodWithDFE(DataFetchingEnvironment dataFetchingEnvironment) { + return "methodWithDFE"; + } + + public String getMethodWithDFE() { + return "methodWithDFEWontBeFoundAsItsSecondarilyPreferred"; + } + + public String getMethodWithoutDFE() { + return "methodWithoutDFE"; + } + + String getDefaultMethodWithDFE(DataFetchingEnvironment dataFetchingEnvironment) { + return "defaultMethodWithDFE"; + } + + String getDefaultMethodWithDFE() { + return "defaultMethodWithDFEWontBeFoundAsItsSecondarilyPreferred"; + } + + String getDefaultMethodWithoutDFE() { + return "defaultMethodWithoutDFE"; + } + + public String getMethodWithTooManyArgs(DataFetchingEnvironment dataFetchingEnvironment, String moreArgs) { + return "methodWithTooManyArgs"; + } + String getDefaultMethodWithTooManyArgs(DataFetchingEnvironment dataFetchingEnvironment, String moreArgs) { + return "defaultMethodWithTooManyArgs"; + } + + public String getMethodWithOneArgButNotDataFetchingEnvironment(String moreArgs) { + return "methodWithOneArgButNotDataFetchingEnvironment"; + } + String getDefaultMethodWithOneArgButNotDataFetchingEnvironment(String moreArgs) { + return "defaultMethodWithOneArgButNotDataFetchingEnvironment"; + } + + public String getMethodUsesDataFetchingEnvironment(DataFetchingEnvironment dataFetchingEnvironment) { + return dataFetchingEnvironment.getArgument("argument1"); + } + + String getDefaultMethodUsesDataFetchingEnvironment(DataFetchingEnvironment dataFetchingEnvironment) { + return dataFetchingEnvironment.getArgument("argument2"); + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/schema/somepackage/ClassWithInterfaces.java b/src/test/groovy/graphql/schema/somepackage/ClassWithInterfaces.java new file mode 100644 index 0000000000..137e5e721c --- /dev/null +++ b/src/test/groovy/graphql/schema/somepackage/ClassWithInterfaces.java @@ -0,0 +1,13 @@ +package graphql.schema.somepackage; + +public class ClassWithInterfaces implements InterfaceHolder.Trait1, InterfaceHolder.Trait2 { + @Override + public String getMethodYouMustImplement() { + return "methodYouMustImplement"; + } + + @Override + public String getMethodYouMustAlsoImplement() { + return "methodYouMustAlsoImplement"; + } +} diff --git a/src/test/groovy/graphql/schema/somepackage/ClassWithInteritanceAndInterfaces.java b/src/test/groovy/graphql/schema/somepackage/ClassWithInteritanceAndInterfaces.java new file mode 100644 index 0000000000..582e60d494 --- /dev/null +++ b/src/test/groovy/graphql/schema/somepackage/ClassWithInteritanceAndInterfaces.java @@ -0,0 +1,20 @@ +package graphql.schema.somepackage; + +public class ClassWithInteritanceAndInterfaces { + + public static class StartingClass implements InterfaceHolder.Trait1 { + @Override + public String getMethodYouMustImplement() { + return "methodYouMustImplement"; + } + } + + public static class InheritedClass extends StartingClass implements InterfaceHolder.Trait2 { + + @Override + public String getMethodYouMustAlsoImplement() { + return "methodYouMustAlsoImplement"; + } + } + +} diff --git a/src/test/groovy/graphql/schema/somepackage/InterfaceHolder.java b/src/test/groovy/graphql/schema/somepackage/InterfaceHolder.java new file mode 100644 index 0000000000..551ed4204f --- /dev/null +++ b/src/test/groovy/graphql/schema/somepackage/InterfaceHolder.java @@ -0,0 +1,20 @@ +package graphql.schema.somepackage; + +public class InterfaceHolder { + + public interface Trait1 { + String getMethodYouMustImplement(); + + default String getMethodThatIsADefault() { + return "methodThatIsADefault"; + } + } + + public interface Trait2 { + String getMethodYouMustAlsoImplement(); + + default String getMethodThatIsAlsoADefault() { + return "methodThatIsAlsoADefault"; + } + } +} diff --git a/src/test/groovy/graphql/schema/somepackage/RecordLikeClass.java b/src/test/groovy/graphql/schema/somepackage/RecordLikeClass.java new file mode 100644 index 0000000000..57cc04f2f1 --- /dev/null +++ b/src/test/groovy/graphql/schema/somepackage/RecordLikeClass.java @@ -0,0 +1,34 @@ +package graphql.schema.somepackage; + +import graphql.schema.DataFetchingEnvironment; + +/** + * This is obviously not an actual record class from Java 14 onwards, but it + * smells like one and that's enough really. Its public, not derived from another + * class and has a public method named after a property + */ +public class RecordLikeClass { + + public String recordProperty() { + return "recordProperty"; + } + + public String recordArgumentMethod(DataFetchingEnvironment environment) { + return "recordArgumentMethod"; + } + + @Override + public int hashCode() { + return 666; + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public String toString() { + return "toString"; + } +} diff --git a/src/test/groovy/graphql/schema/somepackage/RecordLikeTwoClassesDown.java b/src/test/groovy/graphql/schema/somepackage/RecordLikeTwoClassesDown.java new file mode 100644 index 0000000000..4e744f2872 --- /dev/null +++ b/src/test/groovy/graphql/schema/somepackage/RecordLikeTwoClassesDown.java @@ -0,0 +1,4 @@ +package graphql.schema.somepackage; + +public class RecordLikeTwoClassesDown extends RecordLikeClass { +} diff --git a/src/test/groovy/graphql/schema/transform/FieldVisibilitySchemaTransformationTest.groovy b/src/test/groovy/graphql/schema/transform/FieldVisibilitySchemaTransformationTest.groovy new file mode 100644 index 0000000000..00b7edd505 --- /dev/null +++ b/src/test/groovy/graphql/schema/transform/FieldVisibilitySchemaTransformationTest.groovy @@ -0,0 +1,1249 @@ +package graphql.schema.transform + +import graphql.Scalars +import graphql.TestUtil +import graphql.schema.GraphQLAppliedDirective +import graphql.schema.GraphQLCodeRegistry +import graphql.schema.GraphQLDirectiveContainer +import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLSchema +import graphql.schema.TypeResolver +import graphql.schema.idl.SchemaPrinter +import spock.lang.Specification + +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInterfaceType.newInterface +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLTypeReference.typeRef + +class FieldVisibilitySchemaTransformationTest extends Specification { + + def visibilitySchemaTransformation = new FieldVisibilitySchemaTransformation({ environment -> + def directives = (environment.schemaElement as GraphQLDirectiveContainer).appliedDirectives + return directives.find({ directive -> directive.name == "private" }) == null + }) + + def "can remove a private field"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus { + accountNumber: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + } + + def "can remove a type associated with a private field"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus { + accountNumber: String + secrets: SuperSecretCustomerData + otherBillingStatus: BillingStatus + } + + type SuperSecretCustomerData { + cardLast4: Int + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") == null + } + + def "removes concrete types referenced only by interface"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: SuperSecretCustomerData @private + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + secrets: SuperSecretCustomerData + otherBillingStatus: BillingStatus + cardLast4: Int + } + + interface SuperSecretCustomerData { + cardLast4: Int + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") == null + } + + def "interface and its implementations that have both private and public reference is retained"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: SuperSecretCustomerData @private + billingStatus2: SuperSecretCustomerData + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + secrets: SuperSecretCustomerData + otherBillingStatus: BillingStatus + cardLast4: Int + } + + interface SuperSecretCustomerData { + cardLast4: Int + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("SuperSecretCustomerData") != null + restrictedSchema.getType("BillingStatus") != null + } + + + def "types with both private and public references are retained"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + public: Foo + private: Bar @private + } + + type Foo { + x: X + } + + type Bar { + x: X + bar2: Bar2 + } + + type Bar2 { + id: Int + } + + type X { + x2: X2 + } + + type X2 { + id: Int + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("Bar") == null + restrictedSchema.getType("Bar2") == null + restrictedSchema.getType("X") != null + restrictedSchema.getType("Foo") != null + restrictedSchema.getType("X2") != null + } + + def "union types"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + privateFooOrBar: FooOrBar @private + privateBar: Bar @private + privateFoo: Foo @private + public: Foo + } + + union FooOrBar = Foo | Bar + + type Foo { + id: ID + } + + type Bar { + id: ID + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Query") as GraphQLObjectType).getFieldDefinition("privateFooOrBar") == null + (restrictedSchema.getType("Query") as GraphQLObjectType).getFieldDefinition("privateBar") == null + (restrictedSchema.getType("Query") as GraphQLObjectType).getFieldDefinition("privateFoo") == null + (restrictedSchema.getType("Query") as GraphQLObjectType).getFieldDefinition("public") != null + restrictedSchema.getType("FooOrBar") == null + restrictedSchema.getType("Bar") == null + restrictedSchema.getType("Foo") != null + } + + def "union type with reference by private interface removed"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + public: Bar + private: Baz @private + } + + type Bar { + id: ID + } + + interface Baz { + fooOrBar: FooOrBar + } + + type Bing implements Baz { + fooOrBar: FooOrBar + } + union FooOrBar = Foo | Bar + + type Foo { + id: ID + } + + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Query") as GraphQLObjectType).getFieldDefinition("private") == null + restrictedSchema.getType("Foo") == null + restrictedSchema.getType("Bar") != null + restrictedSchema.getType("Baz") == null + restrictedSchema.getType("Bing") == null + restrictedSchema.getType("FooOrBar") == null + } + + + def "leaves concrete types referenced only by interfaces"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: SuperSecretCustomerData + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + cardLast4: Int + } + + interface SuperSecretCustomerData { + cardLast4: Int + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("BillingStatus") != null + restrictedSchema.getType("SuperSecretCustomerData") != null + } + + def "leaves interface types referenced only by concrete types"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + cardLast4: Int + } + + interface SuperSecretCustomerData { + cardLast4: Int + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("BillingStatus") != null + restrictedSchema.getType("SuperSecretCustomerData") != null + } + + + def "removes interface types implemented by types used in a private field"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + cardLast4: Int + } + + interface SuperSecretCustomerData { + cardLast4: Int + } + + """) + + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") == null + } + + def "leaves interface type if has private and public reference"() { + + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + accountStatus: AccountStatus + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + cardLast4: Int + } + + type AccountStatus implements SuperSecretCustomerData { + accountNumber: String + inGoodStanding: Boolean + } + + interface SuperSecretCustomerData { + accountNumber: String + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") != null + } + + def "leaves concrete type if has public and private"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + publicBillingStatus: BillingStatus + } + + type BillingStatus implements SuperSecretCustomerData { + accountNumber: String + cardLast4: Int + } + + interface SuperSecretCustomerData { + accountNumber: String + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("publicBillingStatus") != null + restrictedSchema.getType("BillingStatus") != null + } + + def "removes interface type if only private reference with multiple interfaces"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account implements PublicView { + name: String + billingStatus: BillingStatus @private + country: String + } + + type BillingStatus implements SuperSecretCustomerData & Billable & PublicView { + accountNumber: String + cardLast4: Int + country: String + } + + interface SuperSecretCustomerData { + accountNumber: String + } + + interface Billable { + cardLast4: Int + } + + interface PublicView { + country: String + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") == null + restrictedSchema.getType("Billable") == null + restrictedSchema.getType("PublicView") != null + } + + def "primitive types are retained"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + # only String and Boolean types have other references (in the introspection query) + type Query { + bar: String @private + baz: Boolean @private + placeholderField: Int + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("String") != null + restrictedSchema.getType("Boolean") != null + } + + def "root types with different names are supported"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + schema { + query: FooQuery + } + + type FooQuery { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus { + accountNumber: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + } + + def "fields and types are removed from subscriptions and mutations"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + schema { + query: Query + mutation: Mutation + subscription: Subscription + } + + type Query { + something: String + } + + type Mutation { + setFoo(foo: String): Foo @private + placeholderField: Int + } + + type Subscription { + barAdded: Bar @private + placeholderField: Int + } + + type Foo { + foo: String + } + + type Bar { + bar: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("Foo") == null + restrictedSchema.getType("Bar") == null + } + + def "type with both private and public transitive references is retained"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + private: Foo # calls Baz privately + public: Bar # calls Baz publicly + } + + type Foo { + baz: Baz @private + placeholderField: Int + } + + type Bar { + baz: Baz + } + + type Baz { + bing: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("baz") == null + restrictedSchema.getType("Baz") != null + } + + def "type with multiple private parent references is removed"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + foo: Foo + bar: Bar + } + + type Foo { + baz: Baz @private + placeholderField: Int + } + + type Bar { + baz: Baz @private + placeholderField: Int + } + + type Baz { + bing: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("baz") == null + (restrictedSchema.getType("Bar") as GraphQLObjectType).getFieldDefinition("baz") == null + restrictedSchema.getType("Baz") == null + } + + def "type with multiple private grandparent references is removed"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + foo: Foo @private + bar: Bar @private + placeholderField: Int + } + + type Foo { + baz: Baz + } + + type Bar { + baz: Baz + } + + type Baz { + bing: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + restrictedSchema.getType("Foo") == null + restrictedSchema.getType("Bar") == null + restrictedSchema.getType("Baz") == null + } + + def "type with circular reference can be traversed"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + foo: Foo + } + + type Foo { + foo2: Foo @private + bar: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Foo") as GraphQLObjectType).getFieldDefinition("foo2") == null + restrictedSchema.getType("Foo") != null + } + + def "input types can have private fields"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + + type Query { + foo: Foo + } + + type Mutation { + setFoo(fooInput: FooInput): Foo + } + + type Foo { + id: ID + } + + input FooInput { + foo: BarInput @private + bar: String + } + + input BarInput { + id: ID + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("FooInput") as GraphQLInputObjectType).getFieldDefinition("foo") == null + restrictedSchema.getType("FooInput") != null + restrictedSchema.getType("BarInput") == null + } + + def "enum types can be removed"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + + type Query { + foo: Foo + } + + type Mutation { + setFoo(fooInput: FooInput): Foo + } + + type Foo { + id: ID + fooEnum: FooEnum @private + } + + input FooInput { + foo: BarEnum @private + bar: String + } + + enum BarEnum { + FOO + BAR + BAZ + } + + enum FooEnum { + BING + BOO + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("FooInput") as GraphQLInputObjectType).getFieldDefinition("foo") == null + restrictedSchema.getType("FooInput") != null + restrictedSchema.getType("BarEnum") == null + restrictedSchema.getType("FooEnum") == null + } + + def "unreferenced types can have fields removed, and the referenced types must be removed as well if they are not used"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + foo: Foo + } + + type Foo { + id: ID + } + + type Bar { + baz: String + bing: Bing @private + } + + type Bing { + id: ID + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: "Bar.bing field must have been removed" + (restrictedSchema.getType("Bar") as GraphQLObjectType).getFieldDefinition("bing") == null + + and: "since Bing is not used anywhere else, it should be removed" + restrictedSchema.getType("Bing") == null + } + + def "unreferenced types can have fields removed, and referenced type must not be removed if used elsewhere in the connected graph"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + foo: Foo + zinc: Bing + } + + type Foo { + id: ID + } + + type Bar { + baz: String + bing: Bing @private + } + + type Bing { + id: ID + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: "Bar.bing field must have been removed" + (restrictedSchema.getType("Bar") as GraphQLObjectType).getFieldDefinition("bing") == null + + and: "since Bing is used in the connected graph, it MUST not be removed" + restrictedSchema.getType("Bing") != null + } + + def "unreferenced types can have fields removed, and referenced type must not be removed if used elsewhere"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + foo: Foo + } + + type Foo { + id: ID + } + + type Bar { + baz: String + foo: Bing + bing: Bing @private + } + + type Bing { + id: ID + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: "Bar.bing field must have been removed" + (restrictedSchema.getType("Bar") as GraphQLObjectType).getFieldDefinition("bing") == null + + and: "since Bing is used elsewhere, it SHOULD not be removed" + restrictedSchema.getType("Bing") != null + } + + def "use type references - private field declared with interface type removes both concrete and interface"() { + given: + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("account").type(typeRef("Account")).build()) + .build() + + def privateDirective = GraphQLAppliedDirective.newDirective().name("private").build() + def account = newObject() + .name("Account") + .field(newFieldDefinition().name("name").type(Scalars.GraphQLString).build()) + .field(newFieldDefinition().name("billingStatus").type(typeRef("SuperSecretCustomerData")).withAppliedDirective(privateDirective).build()) + .build() + + def billingStatus = newObject() + .name("BillingStatus") + .field(newFieldDefinition().name("id").type(Scalars.GraphQLString).build()) + .withInterface(typeRef("SuperSecretCustomerData")) + .build() + + def secretData = newInterface() + .name("SuperSecretCustomerData") + .field(newFieldDefinition().name("id").type(Scalars.GraphQLString).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(secretData, Mock(TypeResolver)) + .build() + + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .additionalType(billingStatus) + .additionalType(account) + .additionalType(billingStatus) + .additionalType(secretData) + .build() + when: + + System.out.println((new SchemaPrinter()).print(schema)) + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") == null + } + + + def "use type references - private field declared with concrete type removes both concrete and interface"() { + given: + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("account").type(typeRef("Account")).build()) + .build() + + def privateDirective = GraphQLAppliedDirective.newDirective().name("private").build() + def account = newObject() + .name("Account") + .field(newFieldDefinition().name("name").type(Scalars.GraphQLString).build()) + .field(newFieldDefinition().name("billingStatus").type(typeRef("BillingStatus")).withAppliedDirective(privateDirective).build()) + .build() + + def billingStatus = newObject() + .name("BillingStatus") + .field(newFieldDefinition().name("id").type(Scalars.GraphQLString).build()) + .withInterface(typeRef("SuperSecretCustomerData")) + .build() + + def secretData = newInterface() + .name("SuperSecretCustomerData") + .field(newFieldDefinition().name("id").type(Scalars.GraphQLString).build()) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(secretData, Mock(TypeResolver)) + .build() + + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(query) + .additionalType(billingStatus) + .additionalType(account) + .additionalType(billingStatus) + .additionalType(secretData) + .build() + when: + + System.out.println((new SchemaPrinter()).print(schema)) + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + restrictedSchema.getType("SuperSecretCustomerData") == null + } + + def "use type references - unreferenced types are removed"() { + given: + def query = newObject() + .name("Query") + .field(newFieldDefinition().name("account").type(typeRef("Account")).build()) + .build() + + def privateDirective = GraphQLAppliedDirective.newDirective().name("private").build() + def account = newObject() + .name("Account") + .field(newFieldDefinition().name("name").type(Scalars.GraphQLString).build()) + .field(newFieldDefinition().name("billingStatus").type(typeRef("BillingStatus")).withAppliedDirective(privateDirective).build()) + .build() + + def billingStatus = newObject() + .name("BillingStatus") + .field(newFieldDefinition().name("id").type(Scalars.GraphQLString).build()) + .build() + + def schema = GraphQLSchema.newSchema() + .query(query) + .additionalType(billingStatus) + .additionalType(account) + .build() + when: + + System.out.println((new SchemaPrinter()).print(schema)) + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + } + + def "before and after transformation hooks are run"() { + + given: + def callbacks = [] + + def visibilitySchemaTransformation = new FieldVisibilitySchemaTransformation({ environment -> + def directives = (environment.schemaElement as GraphQLDirectiveContainer).appliedDirectives + return directives.find({ directive -> directive.name == "private" }) == null + }, { -> callbacks << "before" }, { -> callbacks << "after"} ) + + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus { + accountNumber: String + } + """) + + when: + visibilitySchemaTransformation.apply(schema) + + then: + callbacks.containsAll(["before", "after"]) + } + + def "handles types that become visible via types reachable by interface only"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + node: Node + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus { + accountNumber: String + } + + interface Node { + id: ID! + } + + type Billing implements Node { + id: ID! + status: BillingStatus + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") != null + } + + def "handles types that become visible via types reachable by interface that implements interface"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private on FIELD_DEFINITION + + type Query { + account: Account + node: Node + } + + type Account { + name: String + billingStatus: BillingStatus @private + } + + type BillingStatus { + accountNumber: String + } + + interface Node { + id: ID! + } + + interface NamedNode implements Node { + id: ID! + name: String + } + + type Billing implements Node & NamedNode { + id: ID! + name: String + status: BillingStatus + } + + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") != null + } + + def "can remove a field with a directive containing enum argument"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private(privateType: SecretType) on FIELD_DEFINITION + enum SecretType { + SUPER_SECRET + NOT_SO_SECRET + } + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private(privateType: NOT_SO_SECRET) + } + + type BillingStatus { + accountNumber: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + } + + def "can remove a field with a directive containing type argument"() { + given: + GraphQLSchema schema = TestUtil.schema(""" + + directive @private(privateType: SecretType) on FIELD_DEFINITION + input SecretType { + description: String + } + + type Query { + account: Account + } + + type Account { + name: String + billingStatus: BillingStatus @private(privateType: { description: "secret" }) + } + + type BillingStatus { + accountNumber: String + } + """) + + when: + GraphQLSchema restrictedSchema = visibilitySchemaTransformation.apply(schema) + + then: + (restrictedSchema.getType("Account") as GraphQLObjectType).getFieldDefinition("billingStatus") == null + restrictedSchema.getType("BillingStatus") == null + } +} diff --git a/src/test/groovy/graphql/schema/usage/SchemaUsageSupportTest.groovy b/src/test/groovy/graphql/schema/usage/SchemaUsageSupportTest.groovy new file mode 100644 index 0000000000..07c2db114c --- /dev/null +++ b/src/test/groovy/graphql/schema/usage/SchemaUsageSupportTest.groovy @@ -0,0 +1,280 @@ +package graphql.schema.usage + +import graphql.TestUtil +import graphql.schema.GraphQLAppliedDirective +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.SchemaTransformer +import graphql.schema.visitor.GraphQLSchemaTraversalControl +import graphql.schema.visitor.GraphQLSchemaVisitor +import spock.lang.Specification + +class SchemaUsageSupportTest extends Specification { + + def sdl = ''' + type Query { + f : Ref1 + } + + type Ref1 { + f1 : Ref2 + f2 : IRef1 + f3 : RefUnion1 + f4 : RefEnum1 + f5 : String + f6 : RefUnion2 + + f_arg1( arg : RefInput1) : String + f_arg2( arg : [RefInput2]) : String + f_arg3( arg : RefInput3!) : String + + f_directive1 : RefDirectiveObjectType + } + + type Ref2 { f : ID} + + interface IRef1 implements IRef2 { + f : ID + f2 : String + } + + interface IRef2 { + f: ID + } + + + type Floating1 implements IRef1 & IRef2 { + f : ID + f2 : String + } + + type Floating2 implements IRef2 { + f : ID + circular1 : Floating2 + circular2 : Floating3 + } + + type Floating3 { + circular1 : Floating2 @deprecated + } + + union RefUnion1 = Ref1 | Ref2 + + + type RefByUnionOnly1 { f : ID} + type RefByUnionOnly2 { f : ID} + + union RefUnion2 = RefByUnionOnly1 | RefByUnionOnly2 + + enum RefEnum1 { A, B } + + + input RefInput1 { + f : RefInput2 + } + + input RefInput2 { + f : RefInput1 + f1 : String + f3 : RefInput1 + f4 : RefInput1 + } + + input RefInput3 { + f1 : String + f2 : RefInput4 + } + + input RefInput4 { + f1 : String + } + + + interface UnIRef1 { f: ID } + + union UnRefUnion1 = Ref1 | Ref2 + + type UnRef1 { f : ID } + + enum UnRefEnum1 { A, B } + + input UnRefInput1 { + f : ID + } + + + directive @RefArgDirective on ARGUMENT_DEFINITION + directive @RefFieldDirective on FIELD_DEFINITION + directive @RefInputFieldDirective on INPUT_FIELD_DEFINITION + directive @RefInputTypeDirective on INPUT_OBJECT + directive @RefObjectTypeDirective(arg : RefDirectiveInputType) on OBJECT + + type RefDirectiveObjectType @RefObjectTypeDirective { + f(arg : ID @RefArgDirective) : ID @RefFieldDirective + } + + input RefDirectiveInputType @RefInputTypeDirective { + f : ID @RefInputFieldDirective + } + + + directive @UnRefFieldDirective(arg : UnRefDirectiveInputType) on FIELD_DEFINITION + directive @UnRefInputTypeDirective on INPUT_OBJECT + + input UnRefDirectiveInputType @UnRefInputTypeDirective { + f : ID + } + + ### hanging elements + + directive @UnRefHangingArgDirective(arg : UnRefHangingInputType3) on ARGUMENT_DEFINITION + + type UnRefHangingType { + f(arg : UnRefHangingInputType @UnRefHangingArgDirective) : UnRefHangingType2 + } + + type UnRefHangingType2 { + f : UnRefHangingType2 + } + + input UnRefHangingInputType { + f : UnRefHangingInputType2 + } + + input UnRefHangingInputType2 { + f : UnRefHangingInputType + } + + input UnRefHangingInputType3 { + f : ID + } + ''' + + def "can get references"() { + + def schema = TestUtil.schema(sdl) + + when: + def schemaUsage = SchemaUsageSupport.getSchemaUsage(schema) + then: + schemaUsage.isStronglyReferenced(schema, "Ref1") + schemaUsage.isStronglyReferenced(schema, "Ref2") + schemaUsage.isStronglyReferenced(schema, "IRef1") + schemaUsage.isStronglyReferenced(schema, "IRef2") + schemaUsage.isStronglyReferenced(schema, "Floating1") + schemaUsage.isStronglyReferenced(schema, "Floating2") + schemaUsage.isStronglyReferenced(schema, "Floating3") + + schemaUsage.isStronglyReferenced(schema, "RefUnion1") + + schemaUsage.isStronglyReferenced(schema, "RefUnion2") + schemaUsage.isStronglyReferenced(schema, "RefByUnionOnly1") + schemaUsage.isStronglyReferenced(schema, "RefByUnionOnly2") + + schemaUsage.isStronglyReferenced(schema, "RefInput1") + schemaUsage.isStronglyReferenced(schema, "RefInput2") + schemaUsage.isStronglyReferenced(schema, "RefInput3") + schemaUsage.isStronglyReferenced(schema, "RefInput4") + + schemaUsage.isStronglyReferenced(schema, "ID") + schemaUsage.isStronglyReferenced(schema, "String") + schemaUsage.isStronglyReferenced(schema, "Int") + schemaUsage.isStronglyReferenced(schema, "__Type") + schemaUsage.isStronglyReferenced(schema, "__Schema") + + schemaUsage.isStronglyReferenced(schema, "RefDirectiveObjectType") + schemaUsage.isStronglyReferenced(schema, "RefDirectiveInputType") + schemaUsage.isStronglyReferenced(schema, "RefInputTypeDirective") + schemaUsage.isStronglyReferenced(schema, "RefFieldDirective") + schemaUsage.isStronglyReferenced(schema, "RefArgDirective") + schemaUsage.isStronglyReferenced(schema, "RefInputFieldDirective") + + + !schemaUsage.isStronglyReferenced(schema, "UnRef1") + !schemaUsage.isStronglyReferenced(schema, "UnIRef1") + !schemaUsage.isStronglyReferenced(schema, "UnRefEnum1") + !schemaUsage.isStronglyReferenced(schema, "UnRefInput1") + + !schemaUsage.isStronglyReferenced(schema, "UnRefFieldDirective") + !schemaUsage.isStronglyReferenced(schema, "UnRefInputTypeDirective") + !schemaUsage.isStronglyReferenced(schema, "UnRefDirectiveInputType") + + schemaUsage.getUnReferencedElements(schema).collect { it.name }.sort() == + ["UnIRef1", "UnRef1", "UnRefDirectiveInputType", "UnRefEnum1", + "UnRefHangingInputType", "UnRefHangingInputType2", "UnRefHangingInputType3", + "UnRefHangingType", "UnRefHangingType2", "UnRefInput1", + "UnRefFieldDirective", "UnRefInputTypeDirective", "UnRefHangingArgDirective"].sort() + } + + def "can record counts"() { + def schema = TestUtil.schema(sdl) + + when: + def schemaUsage = SchemaUsageSupport.getSchemaUsage(schema) + + then: + schemaUsage.getOutputFieldReferenceCounts()["Ref1"] == 1 + schemaUsage.getFieldReferenceCounts()["Ref1"] == 1 + schemaUsage.getUnionReferenceCounts()["Ref1"] == 2 + + schemaUsage.getInputFieldReferenceCounts()["Ref1"] == null + schemaUsage.getInputFieldReferenceCounts()["RefInput1"] == 3 + + schemaUsage.getFieldReferenceCounts()["RefInput1"] == 3 + schemaUsage.getArgumentReferenceCounts()["RefInput1"] == 1 + + schemaUsage.getFieldReferenceCounts()["UnRef1"] == null + schemaUsage.getFieldReferenceCounts()["UnRefInput1"] == null + schemaUsage.getDirectiveReferenceCounts()["UnRefFieldDirective"] == null + + } + + def "can handle hanging elements"() { + // hanging elements are elements that reference other elements + // but ultimately dont lead to the root types + + def schema = TestUtil.schema(sdl) + + when: + def schemaUsage = SchemaUsageSupport.getSchemaUsage(schema) + + then: + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingType") + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingType2") + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingType3") + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingInputType") + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingInputType2") + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingInputType3") + !schemaUsage.isStronglyReferenced(schema, "UnRefHangingArgDirective") + + // 2 because of the dual nature of directives and applied directives + schemaUsage.getDirectiveReferenceCounts()["UnRefHangingArgDirective"] == 2 + schemaUsage.getArgumentReferenceCounts()["UnRefHangingInputType"] == 1 + schemaUsage.getFieldReferenceCounts()["UnRefHangingType2"] == 2 + schemaUsage.getArgumentReferenceCounts()["UnRefHangingInputType3"] == 3 + } + + def "can handle cleared directives"() { + // https://github.com/graphql-java/graphql-java/issues/3267 + + + def schema = TestUtil.schema(sdl) + schema = new SchemaTransformer().transform(schema, new GraphQLSchemaVisitor() { + + @Override + GraphQLSchemaTraversalControl visitFieldDefinition(GraphQLFieldDefinition fieldDef, GraphQLSchemaVisitor.FieldDefinitionVisitorEnvironment env) { + if (fieldDef.getAppliedDirective("RefFieldDirective") != null) { + List directives = fieldDef.getAppliedDirectives(); + fieldDef = fieldDef.transform( + f -> f.clearDirectives().replaceAppliedDirectives(directives) + ) + } + return env.changeNode(fieldDef) + } + }.toTypeVisitor()) + + when: + def schemaUsage = SchemaUsageSupport.getSchemaUsage(schema) + then: + schemaUsage.isStronglyReferenced(schema, "RefFieldDirective") + } +} diff --git a/src/test/groovy/graphql/schema/validation/AppliedDirectivesAreValidTest.groovy b/src/test/groovy/graphql/schema/validation/AppliedDirectivesAreValidTest.groovy new file mode 100644 index 0000000000..f5a2136bba --- /dev/null +++ b/src/test/groovy/graphql/schema/validation/AppliedDirectivesAreValidTest.groovy @@ -0,0 +1,127 @@ +package graphql.schema.validation + +import graphql.TestUtil +import graphql.schema.FieldCoordinates +import spock.lang.Specification + +import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.mkDirective +import static graphql.introspection.Introspection.DirectiveLocation.FIELD_DEFINITION +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLSchema.newSchema + +class AppliedDirectivesAreValidTest extends Specification { + + def "non repeatable directives cannot be repeated"() { + def sdl = ''' + + directive @directiveA on FIELD_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + directive @directiveOK on FIELD_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + + interface InterfaceType1 { + fieldA : String @directiveA @directiveA + } + + type Query implements InterfaceType1 { + fieldA : String + fieldC : String @directiveA @directiveA + } + + extend type Query { + fieldB : Int + fieldD: Int @directiveA @directiveA + fieldE: Int @directiveA @directiveOK + } + + enum EnumType { + + enumA @directiveA @directiveA + enumB @directiveA @directiveOK + } + + input InputType { + inputFieldA : String @directiveA @directiveA + inputFieldB : String @directiveA @directiveOK + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 5 + hasError(schemaProblem, "The directive 'directiveA' on the 'GraphQLFieldDefinition' called 'fieldC' is a non repeatable directive but has been applied 2 times") + hasError(schemaProblem, "The directive 'directiveA' on the 'GraphQLFieldDefinition' called 'fieldD' is a non repeatable directive but has been applied 2 times") + hasError(schemaProblem, "The directive 'directiveA' on the 'GraphQLFieldDefinition' called 'fieldA' is a non repeatable directive but has been applied 2 times") + hasError(schemaProblem, "The directive 'directiveA' on the 'GraphQLEnumValueDefinition' called 'enumA' is a non repeatable directive but has been applied 2 times") + hasError(schemaProblem, "The directive 'directiveA' on the 'GraphQLInputObjectField' called 'inputFieldA' is a non repeatable directive but has been applied 2 times") + } + + def "applied directive builders do not clear any existing applied directives"() { + given: + def directive1 = mkDirective("myDirectiveName1", FIELD_DEFINITION) + def directive2 = mkDirective("myDirectiveName2", FIELD_DEFINITION) + def field = newFieldDefinition() + .name("hello") + .type(GraphQLString) + .withAppliedDirectives(directive1.toAppliedDirective()) + .withAppliedDirectives(directive2.toAppliedDirective()) + .build() + + when: + def schema = newSchema() + .query( + newObject() + .name("Query") + .field(field) + .build() + ) + .additionalDirective(directive1) + .additionalDirective(directive2) + .build() + + then: + def fieldAppliedDirectives = schema.getFieldDefinition(FieldCoordinates.coordinates("Query", "hello")).getAppliedDirectives() + fieldAppliedDirectives.size() == 2 + fieldAppliedDirectives.any { it.name == "myDirectiveName1" } + fieldAppliedDirectives.any { it.name == "myDirectiveName2" } + } + + def "replace applied directive builder does clear and replace existing applied directives"() { + given: + def directive1 = mkDirective("myDirectiveName1", FIELD_DEFINITION) + def directive2 = mkDirective("myDirectiveName2", FIELD_DEFINITION) + def field = newFieldDefinition() + .name("hello") + .type(GraphQLString) + .withAppliedDirective(directive1.toAppliedDirective()) + .replaceAppliedDirectives(List.of(directive2.toAppliedDirective())) + .build() + + when: + def schema = newSchema() + .query( + newObject() + .name("Query") + .field(field) + .build() + ) + .additionalDirective(directive1) + .additionalDirective(directive2) + .build() + + then: + // As prior applied directives are cleared, there is only 1 applied directive left on the field (directive container) + def fieldAppliedDirectives = schema.getFieldDefinition(FieldCoordinates.coordinates("Query", "hello")).getAppliedDirectives() + fieldAppliedDirectives.size() == 1 + fieldAppliedDirectives.find { it.name == "myDirectiveName1" } == null + fieldAppliedDirectives.any { it.name == "myDirectiveName2" } + } + + static boolean hasError(InvalidSchemaException schemaException, String msg) { + def err = schemaException.getErrors().find { it.description == msg } + return err != null + } +} diff --git a/src/test/groovy/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValidTest.groovy b/src/test/groovy/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValidTest.groovy new file mode 100644 index 0000000000..056f134db4 --- /dev/null +++ b/src/test/groovy/graphql/schema/validation/DeprecatedInputObjectAndArgumentsAreValidTest.groovy @@ -0,0 +1,296 @@ +package graphql.schema.validation + +import graphql.TestUtil +import spock.lang.Specification + +class DeprecatedInputObjectAndArgumentsAreValidTest extends Specification { + + def "required input field cannot be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(pizzaInfo: PizzaInfo!): String + } + + input PizzaInfo { + name: String! + pineapples: Boolean! @deprecated(reason: "Don't need this input field") + spicy: Boolean @deprecated(reason: "Don't need this nullable input field") + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 1 + schemaProblem.getErrors().first().description == "Required input field 'PizzaInfo.pineapples' cannot be deprecated." + } + + def "multiple required input fields cannot be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(pizzaInfo: PizzaInfo!): String + } + + input PizzaInfo { + name: String! + pineapples: Boolean! @deprecated(reason: "Don't need this input field") + spicy: Boolean! @deprecated(reason: "Don't need this input field") + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 2 + schemaProblem.getErrors()[0].description == "Required input field 'PizzaInfo.pineapples' cannot be deprecated." + schemaProblem.getErrors()[1].description == "Required input field 'PizzaInfo.spicy' cannot be deprecated." + } + + def "required input field list cannot be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(pizzaInfos: [PizzaInfo]!): String + } + + input PizzaInfo { + name: String! + pineapples: Boolean! @deprecated(reason: "Don't need this input field") + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 1 + schemaProblem.getErrors().first().description == "Required input field 'PizzaInfo.pineapples' cannot be deprecated." + } + + def "nullable input field can be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(pizzaInfo: PizzaInfo!): String + } + + input PizzaInfo { + name: String! + pineapples: Boolean @deprecated(reason: "Don't need this input field") + } + ''' + + when: + TestUtil.schema(sdl) + + then: + noExceptionThrown() + } + + def "non-nullable input field with default value can be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(pizzaInfo: PizzaInfo!): String + } + + input PizzaInfo { + name: String! + pineapples: Boolean! = false @deprecated(reason: "Don't need this input field") + } + ''' + + when: + TestUtil.schema(sdl) + + then: + noExceptionThrown() + } + + def "required field argument cannot be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean! @deprecated(reason: "Don't need this field argument")): String + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 1 + schemaProblem.getErrors().first().description == "Required argument 'pineapples' on field 'updatePizza' cannot be deprecated." + } + + def "multiple required field arguments cannot be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(name: String! @deprecated(reason: "yeah nah"), pineapples: Boolean! @deprecated(reason: "Don't need this field argument")): String + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 2 + schemaProblem.getErrors()[0].description == "Required argument 'name' on field 'updatePizza' cannot be deprecated." + schemaProblem.getErrors()[1].description == "Required argument 'pineapples' on field 'updatePizza' cannot be deprecated." + } + + def "nullable field argument can be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean @deprecated(reason: "Don't need this field argument")): String + } + ''' + + when: + TestUtil.schema(sdl) + + then: + noExceptionThrown() + } + + def "non-nullable field argument with default value can be deprecated"() { + def sdl = ''' + type Query { + pizza(name: String!): String + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean! = false @deprecated(reason: "Don't need this field argument")): String + } + ''' + + when: + TestUtil.schema(sdl) + + then: + noExceptionThrown() + } + + def "required directive argument cannot be deprecated"() { + def sdl = ''' + directive @pizzaDirective(name: String!, likesPineapples: Boolean! @deprecated(reason: "Don't need this directive argument")) on FIELD_DEFINITION + + type Query { + pizza(name: String!): String @pizzaDirective(name: "Stefano", likesPineapples: false) + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean!): String + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 1 + schemaProblem.getErrors().first().description == "Required argument 'likesPineapples' on directive 'pizzaDirective' cannot be deprecated." + } + + def "multiple required directive arguments cannot be deprecated"() { + def sdl = ''' + directive @pizzaDirective(name: String! @deprecated, likesPineapples: Boolean! @deprecated(reason: "Don't need this directive argument")) on FIELD_DEFINITION + + type Query { + pizza(name: String!): String @pizzaDirective(name: "Stefano", likesPineapples: false) + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean!): String + } + ''' + + when: + TestUtil.schema(sdl) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.getErrors().size() == 2 + schemaProblem.getErrors()[0].description == "Required argument 'name' on directive 'pizzaDirective' cannot be deprecated." + schemaProblem.getErrors()[1].description == "Required argument 'likesPineapples' on directive 'pizzaDirective' cannot be deprecated." + } + + def "nullable directive argument can be deprecated"() { + def sdl = ''' + directive @pizzaDirective(name: String!, likesPineapples: Boolean @deprecated(reason: "Don't need this directive argument")) on FIELD_DEFINITION + + type Query { + pizza(name: String!): String @pizzaDirective(name: "Stefano", likesPineapples: false) + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean!): String + } + + ''' + + when: + TestUtil.schema(sdl) + + then: + noExceptionThrown() + } + + def "non-nullable directive argument with default value can be deprecated"() { + def sdl = ''' + directive @pizzaDirective(name: String!, likesPineapples: Boolean! = false @deprecated(reason: "Don't need this directive argument")) on FIELD_DEFINITION + + type Query { + pizza(name: String!): String @pizzaDirective(name: "Stefano", likesPineapples: false) + } + + type Mutation { + updatePizza(name: String!, pineapples: Boolean!): String + } + + ''' + + when: + TestUtil.schema(sdl) + + then: + noExceptionThrown() + } + +} diff --git a/src/test/groovy/graphql/schema/validation/InputAndOutputTypesUsedAppropriatelyTest.groovy b/src/test/groovy/graphql/schema/validation/InputAndOutputTypesUsedAppropriatelyTest.groovy new file mode 100644 index 0000000000..0c5a60208f --- /dev/null +++ b/src/test/groovy/graphql/schema/validation/InputAndOutputTypesUsedAppropriatelyTest.groovy @@ -0,0 +1,93 @@ +package graphql.schema.validation + +import graphql.schema.GraphQLArgument +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLSchema +import spock.lang.Specification + +import static graphql.Scalars.GraphQLBoolean +import static graphql.Scalars.GraphQLString +import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition +import static graphql.schema.GraphQLInputObjectField.newInputObjectField +import static graphql.schema.GraphQLInputObjectType.newInputObject +import static graphql.schema.GraphQLList.list +import static graphql.schema.GraphQLNonNull.nonNull +import static graphql.schema.GraphQLObjectType.newObject +import static graphql.schema.GraphQLTypeReference.typeRef + +class InputAndOutputTypesUsedAppropriatelyTest extends Specification { + + def "output type within input context is caught"() { + given: + + GraphQLObjectType OutputType = newObject() + .name("OutputType") + .field(newFieldDefinition().name("field").type(GraphQLString)) + .build() + + GraphQLInputObjectType PersonInputType = newInputObject() + .name("Person") + .field(newInputObjectField() + .name("friend") + .type(nonNull(list(nonNull(typeRef("OutputType"))))) + .build()) + .build() + + GraphQLFieldDefinition field = newFieldDefinition() + .name("exists") + .type(GraphQLBoolean) + .argument(GraphQLArgument.newArgument() + .name("person") + .type(PersonInputType)) + .build() + + GraphQLObjectType queryType = newObject() + .name("Query") + .field(field) + .build() + + when: + GraphQLSchema.newSchema() + .query(queryType) + .additionalTypes([OutputType] as Set) + .build() + then: + def schemaException = thrown(InvalidSchemaException) + def errors = schemaException.getErrors().collect { it.description } + errors.contains("The output type 'OutputType' has been used in an input type context : 'Person.friend'") + } + + def "input type within output context is caught"() { + given: + + GraphQLInputObjectType PersonInputType = newInputObject() + .name("Person") + .field(newInputObjectField() + .name("friend") + .type(GraphQLString) + .build()) + .build() + + GraphQLFieldDefinition field = newFieldDefinition() + .name("outputField") + .type(nonNull(list(nonNull(typeRef("Person"))))) + .build() + + GraphQLObjectType queryType = newObject() + .name("Query") + .field(field) + .build() + + when: + GraphQLSchema.newSchema() + .query(queryType) + .additionalTypes([PersonInputType] as Set) + .build() + then: + def schemaException = thrown(InvalidSchemaException) + def errors = schemaException.getErrors().collect { it.description } + errors.contains("The input type 'Person' has been used in a output type context : 'Query.outputField'") + } +} diff --git a/src/test/groovy/graphql/schema/validation/NoUnbrokenInputCyclesTest.groovy b/src/test/groovy/graphql/schema/validation/NoUnbrokenInputCyclesTest.groovy index 5f195545b0..2ead346116 100644 --- a/src/test/groovy/graphql/schema/validation/NoUnbrokenInputCyclesTest.groovy +++ b/src/test/groovy/graphql/schema/validation/NoUnbrokenInputCyclesTest.groovy @@ -4,7 +4,7 @@ import graphql.schema.GraphQLArgument import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLInputObjectField import graphql.schema.GraphQLInputObjectType -import graphql.schema.GraphQLTypeReference +import graphql.util.TraverserContext import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean @@ -31,13 +31,15 @@ class NoUnbrokenInputCyclesTest extends Specification { .name("exists") .type(GraphQLBoolean) .argument(GraphQLArgument.newArgument() - .name("person") - .type(PersonInputType)) + .name("person") + .type(PersonInputType)) .build() - PersonInputType.getFieldDefinition("friend").type = nonNull(PersonInputType) + PersonInputType.getFieldDefinition("friend").replacedType = nonNull(PersonInputType) + def context = Mock(TraverserContext) + context.getVarFromParents(SchemaValidationErrorCollector) >> errorCollector when: - new NoUnbrokenInputCycles().check(field, errorCollector) + new NoUnbrokenInputCycles().visitGraphQLFieldDefinition(field, context) then: errorCollector.containsValidationError(SchemaValidationErrorType.UnbrokenInputCycle) } diff --git a/src/test/groovy/graphql/schema/validation/OneOfInputObjectRulesTest.groovy b/src/test/groovy/graphql/schema/validation/OneOfInputObjectRulesTest.groovy new file mode 100644 index 0000000000..813e54672b --- /dev/null +++ b/src/test/groovy/graphql/schema/validation/OneOfInputObjectRulesTest.groovy @@ -0,0 +1,36 @@ +package graphql.schema.validation + +import graphql.TestUtil +import graphql.schema.idl.SchemaGenerator +import graphql.schema.idl.SchemaParser +import spock.lang.Specification + +class OneOfInputObjectRulesTest extends Specification { + + def "oneOf fields must be the right shape"() { + + def sdl = """ + type Query { + f(arg : OneOfInputType) : String + } + + input OneOfInputType @oneOf { + ok : String + badNonNull : String! + badDefaulted : String = "default" + } + """ + + when: + def registry = new SchemaParser().parse(sdl) + new SchemaGenerator().makeExecutableSchema(registry, TestUtil.getMockRuntimeWiring()) + + then: + def schemaProblem = thrown(InvalidSchemaException) + schemaProblem.errors.size() == 2 + schemaProblem.errors[0].description == "OneOf input field OneOfInputType.badNonNull must be nullable." + schemaProblem.errors[0].classification == SchemaValidationErrorType.OneOfNonNullableField + schemaProblem.errors[1].description == "OneOf input field OneOfInputType.badDefaulted cannot have a default value." + schemaProblem.errors[1].classification == SchemaValidationErrorType.OneOfDefaultValueOnField + } +} diff --git a/src/test/groovy/graphql/schema/validation/SchemaValidatorTest.groovy b/src/test/groovy/graphql/schema/validation/SchemaValidatorTest.groovy index aab7bfd153..706542df8d 100644 --- a/src/test/groovy/graphql/schema/validation/SchemaValidatorTest.groovy +++ b/src/test/groovy/graphql/schema/validation/SchemaValidatorTest.groovy @@ -1,9 +1,6 @@ package graphql.schema.validation -import graphql.Scalars -import graphql.schema.GraphQLFieldDefinition -import graphql.schema.GraphQLObjectType -import graphql.schema.GraphQLSchema + import spock.lang.Specification class SchemaValidatorTest extends Specification { @@ -14,96 +11,15 @@ class SchemaValidatorTest extends Specification { def validator = new SchemaValidator() def rules = validator.rules then: - rules.size() == 2 + rules.size() == 9 rules[0] instanceof NoUnbrokenInputCycles - rules[1] instanceof ObjectsImplementInterfaces - } - - def "rules are used"() { - def queryType = GraphQLObjectType.newObject() - .name("query") - .build() - def schema = GraphQLSchema.newSchema() - .query(queryType) - .build() - def dummyRule = Mock(SchemaValidationRule) - when: - def validator = new SchemaValidator([dummyRule]) - validator.validateSchema(schema) - - then: - 1 * dummyRule.check(queryType, _ as SchemaValidationErrorCollector) - } - - def "query fields are checked"() { - def field = GraphQLFieldDefinition.newFieldDefinition() - .name("field") - .type(Scalars.GraphQLString) - .build() - def queryType = GraphQLObjectType.newObject() - .name("query") - .field(field) - .build() - def schema = GraphQLSchema.newSchema() - .query(queryType) - .build() - def dummyRule = Mock(SchemaValidationRule) - when: - def validator = new SchemaValidator([dummyRule]) - validator.validateSchema(schema) - - then: - 1 * dummyRule.check(field, _ as SchemaValidationErrorCollector) + rules[1] instanceof TypesImplementInterfaces + rules[2] instanceof TypeAndFieldRule + rules[3] instanceof DefaultValuesAreValid + rules[4] instanceof AppliedDirectivesAreValid + rules[5] instanceof AppliedDirectiveArgumentsAreValid + rules[6] instanceof InputAndOutputTypesUsedAppropriately + rules[7] instanceof OneOfInputObjectRules + rules[8] instanceof DeprecatedInputObjectAndArgumentsAreValid } - - def "mutation fields are checked"() { - def dummyRule = Mock(SchemaValidationRule) - def field = GraphQLFieldDefinition.newFieldDefinition() - .name("field") - .type(Scalars.GraphQLString) - .build() - def mutation = GraphQLObjectType.newObject() - .name("mutation") - .field(field) - .build() - def queryType = GraphQLObjectType.newObject() - .name("query") - .build() - def schema = GraphQLSchema.newSchema() - .query(queryType) - .mutation(mutation) - .build() - when: - def validator = new SchemaValidator([dummyRule]) - validator.validateSchema(schema) - - then: - 1 * dummyRule.check(field, _ as SchemaValidationErrorCollector) - } - - def "subscription fields are checked"() { - def dummyRule = Mock(SchemaValidationRule) - def field = GraphQLFieldDefinition.newFieldDefinition() - .name("field") - .type(Scalars.GraphQLString) - .build() - def mutation = GraphQLObjectType.newObject() - .name("subscription") - .field(field) - .build() - def queryType = GraphQLObjectType.newObject() - .name("query") - .build() - def schema = GraphQLSchema.newSchema() - .query(queryType) - .subscription(mutation) - .build() - when: - def validator = new SchemaValidator([dummyRule]) - validator.validateSchema(schema) - - then: - 1 * dummyRule.check(field, _ as SchemaValidationErrorCollector) - } - } diff --git a/src/test/groovy/graphql/schema/validation/TypeAndFieldRuleTest.groovy b/src/test/groovy/graphql/schema/validation/TypeAndFieldRuleTest.groovy new file mode 100644 index 0000000000..8c3f4fc2a3 --- /dev/null +++ b/src/test/groovy/graphql/schema/validation/TypeAndFieldRuleTest.groovy @@ -0,0 +1,168 @@ +package graphql.schema.validation + +import graphql.TestUtil +import graphql.schema.GraphQLCodeRegistry +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLTypeReference +import graphql.schema.TypeResolverProxy +import spock.lang.Specification + +import static graphql.schema.GraphQLUnionType.newUnionType + +class TypeAndFieldRuleTest extends Specification { + + def "type must define one or more fields."() { + when: + def sdl = ''' + type Query {} + ''' + + TestUtil.schema(sdl) + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + e.message == "invalid schema:\n\"Query\" must define one or more fields." + } + + def "Enum type must define one or more enum values"() { + when: + def sdl = ''' + type Query { + enumValue: EnumType + } + enum EnumType {} + ''' + + TestUtil.schema(sdl) + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + e.message == "invalid schema:\nEnum type \"EnumType\" must define one or more enum values." + } + + def "input type must define one or more fields"() { + when: + def sdl = ''' + type Query { + field: String + } + input InputType {} + + ''' + + TestUtil.schema(sdl) + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + print(e.message) + e.message == "invalid schema:\n\"InputType\" must define one or more fields." + } + + def "field name must not begin with \"__\""() { + when: + def sdl = ''' + type Query { __namedField: Int } + ''' + + TestUtil.schema(sdl) + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + e.message == "invalid schema:\n\"__namedField\" in \"Query\" must not begin with \"__\", which is reserved by GraphQL introspection." + } + + def "argument name must not begin with \"__\""() { + when: + def sdl = ''' + type Query { namedField(__arg: Int): Int } + ''' + + TestUtil.schema(sdl) + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + e.message == "invalid schema:\nArgument name \"__arg\" in \"Query-namedField\" must not begin with \"__\", which is reserved by GraphQL introspection." + } + + def "interface must define one or more fields."() { + when: + def sdl = ''' + type Query { field: Int } + interface Interface {} + ''' + + TestUtil.schema(sdl) + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + e.message == "invalid schema:\n\"Interface\" must define one or more fields." + } + + def "union member types must be object types"() { + def sdl = ''' + type Query { dummy: String } + + type Object { + dummy: String + } + + interface Interface { + dummy: String + } + ''' + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver("Interface", { null }) + .build() + def graphQLSchema = TestUtil.schema(sdl).transform({it.codeRegistry(codeRegistry)}) + + // this is a little convoluted, since this rule is repeated in the schemaChecker + // we add the invalid union after schema creation so we can cover the validation from + // the TypeAndFieldRule. + def unionType = newUnionType().name("unionWithNonObjectTypes") + .possibleType(graphQLSchema.getObjectType("Object")) + .possibleType(GraphQLTypeReference.typeRef("Interface")) + .build() + codeRegistry = codeRegistry.transform({it.typeResolver(unionType, new TypeResolverProxy())}) + graphQLSchema.transform({ schema -> schema + .additionalType(unionType) + .codeRegistry(codeRegistry)}) + + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + !e.getErrors().isEmpty() + e.getErrors()[0].classification == SchemaValidationErrorType.InvalidUnionMemberTypeError + } + + def "union member types must be unique"() { + def sdl = ''' + type Query { dummy: String } + + type Object { + dummy: String + } + ''' + when: + def graphQLSchema = TestUtil.schema(sdl) + + // Since this rule is repeated in the schemaChecker + // there is no way to effectively cover it after the schema has + // been constructed. We use a Stub here to register the same object type at two + // different names. + def stubObjectType = Stub(GraphQLObjectType) { + getName() >>> ["Other","Object"] + } + + def unionType = newUnionType().name("unionWithNonObjectTypes") + .possibleType(graphQLSchema.getObjectType("Object")) + .possibleType(stubObjectType) + .build() + + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(unionType, new TypeResolverProxy()) + .build() + + graphQLSchema.transform({ schema -> schema + .additionalType(unionType) + .codeRegistry(codeRegistry) }) + + then: + InvalidSchemaException e = thrown(InvalidSchemaException) + !e.getErrors().isEmpty() + e.getErrors()[0].classification == SchemaValidationErrorType.RepetitiveElementError + } +} diff --git a/src/test/groovy/graphql/schema/validation/ObjectsImplementInterfacesTest.groovy b/src/test/groovy/graphql/schema/validation/TypesImplementInterfacesTest.groovy similarity index 62% rename from src/test/groovy/graphql/schema/validation/ObjectsImplementInterfacesTest.groovy rename to src/test/groovy/graphql/schema/validation/TypesImplementInterfacesTest.groovy index 4bb20649ba..c504393cf2 100644 --- a/src/test/groovy/graphql/schema/validation/ObjectsImplementInterfacesTest.groovy +++ b/src/test/groovy/graphql/schema/validation/TypesImplementInterfacesTest.groovy @@ -1,9 +1,7 @@ package graphql.schema.validation -import graphql.TypeResolutionEnvironment import graphql.schema.GraphQLInterfaceType import graphql.schema.GraphQLObjectType -import graphql.schema.TypeResolver import spock.lang.Specification import static SchemaValidationErrorType.ObjectDoesNotImplementItsInterfaces @@ -18,14 +16,7 @@ import static graphql.schema.GraphQLNonNull.nonNull import static graphql.schema.GraphQLObjectType.newObject import static graphql.schema.GraphQLUnionType.newUnionType -class ObjectsImplementInterfacesTest extends Specification { - - TypeResolver typeResolver = new TypeResolver() { - @Override - GraphQLObjectType getType(TypeResolutionEnvironment env) { - null - } - } +class TypesImplementInterfacesTest extends Specification { GraphQLInterfaceType InterfaceType = newInterface() .name("Interface") @@ -39,7 +30,7 @@ class ObjectsImplementInterfacesTest extends Specification { .argument(newArgument().name("arg1").type(GraphQLString)) .argument(newArgument().name("arg2").type(GraphQLInt)) .argument(newArgument().name("arg3").type(GraphQLBoolean)) - .argument(newArgument().name("arg4").type(GraphQLString).defaultValue("ABC")) + .argument(newArgument().name("arg4").type(GraphQLString).defaultValueProgrammatic("ABC")) ) .field(newFieldDefinition().name("argField2").type(GraphQLString) @@ -47,14 +38,13 @@ class ObjectsImplementInterfacesTest extends Specification { .argument(newArgument().name("arg2").type(GraphQLInt)) .argument(newArgument().name("arg3").type(GraphQLBoolean)) ) - .typeResolver(typeResolver) .build() def "objects implement interfaces"() { given: SchemaValidationErrorCollector errorCollector = new SchemaValidationErrorCollector() - GraphQLObjectType objType = GraphQLObjectType.newObject() + GraphQLObjectType objType = newObject() .name("obj") .withInterface(InterfaceType) .field(newFieldDefinition().name("name").type(GraphQLString)) @@ -66,7 +56,7 @@ class ObjectsImplementInterfacesTest extends Specification { .argument(newArgument().name("arg1").type(GraphQLInt)) .argument(newArgument().name("arg2").type(GraphQLInt)) .argument(newArgument().name("arg3").type(GraphQLInt)) - .argument(newArgument().name("arg4").type(GraphQLString).defaultValue("XYZ")) + .argument(newArgument().name("arg4").type(GraphQLString).defaultValueProgrammatic("XYZ")) ) .field(newFieldDefinition().name("argField2").type(GraphQLString) @@ -76,7 +66,7 @@ class ObjectsImplementInterfacesTest extends Specification { .build() when: - new ObjectsImplementInterfaces().check(objType, errorCollector) + new TypesImplementInterfaces().check(objType, errorCollector) then: @@ -94,7 +84,7 @@ class ObjectsImplementInterfacesTest extends Specification { errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces, "object type 'obj' does not implement interface 'Interface' because field 'argField1' argument 'arg4' is defined differently")) errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces, - "object type 'obj' does not implement interface 'Interface' because field 'argField2' has a different number of arguments")) + "object type 'obj' does not implement interface 'Interface' because field 'argField2' is missing argument(s): 'arg2, arg3'")) } def "field is object implementing interface"() { @@ -102,7 +92,6 @@ class ObjectsImplementInterfacesTest extends Specification { def person = newInterface() .name("Person") .field(newFieldDefinition().name("name").type(GraphQLString).build()) - .typeResolver({}) .build() def actor = newObject() @@ -119,7 +108,6 @@ class ObjectsImplementInterfacesTest extends Specification { GraphQLInterfaceType interfaceType = newInterface() .name("TestInterface") .field(newFieldDefinition().name("field").type(person).build()) - .typeResolver({}) .build() GraphQLObjectType goodImpl = newObject() @@ -138,8 +126,8 @@ class ObjectsImplementInterfacesTest extends Specification { SchemaValidationErrorCollector badErrorCollector = new SchemaValidationErrorCollector() when: - new ObjectsImplementInterfaces().check(goodImpl, goodErrorCollector) - new ObjectsImplementInterfaces().check(badImpl, badErrorCollector) + new TypesImplementInterfaces().check(goodImpl, goodErrorCollector) + new TypesImplementInterfaces().check(badImpl, badErrorCollector) then: goodErrorCollector.getErrors().isEmpty() @@ -151,7 +139,6 @@ class ObjectsImplementInterfacesTest extends Specification { def person = newInterface() .name("Person") .field(newFieldDefinition().name("name").type(GraphQLString).build()) - .typeResolver({}) .build() def actor = newObject() @@ -168,7 +155,6 @@ class ObjectsImplementInterfacesTest extends Specification { GraphQLInterfaceType interfaceType = newInterface() .name("TestInterface") .field(newFieldDefinition().name("field").type(list(person)).build()) - .typeResolver({}) .build() GraphQLObjectType goodImpl = newObject() @@ -187,8 +173,55 @@ class ObjectsImplementInterfacesTest extends Specification { SchemaValidationErrorCollector badErrorCollector = new SchemaValidationErrorCollector() when: - new ObjectsImplementInterfaces().check(goodImpl, goodErrorCollector) - new ObjectsImplementInterfaces().check(badImpl, badErrorCollector) + new TypesImplementInterfaces().check(goodImpl, goodErrorCollector) + new TypesImplementInterfaces().check(badImpl, badErrorCollector) + + then: + goodErrorCollector.getErrors().isEmpty() + !badErrorCollector.getErrors().isEmpty() + } + + def "field is list of interfaces implementing interface" () { + given: + def person = newInterface() + .name("Person") + .field(newFieldDefinition().name("name").type(GraphQLString).build()) + .build() + + def actor = newInterface() + .name("Actor") + .field(newFieldDefinition().name("name").type(GraphQLString).build()) + .withInterface(person) + .build() + + def prop = newObject() + .name("Prop") + .field(newFieldDefinition().name("name").type(GraphQLString).build()) + .build() + + GraphQLInterfaceType interfaceType = newInterface() + .name("TestInterface") + .field(newFieldDefinition().name("field").type(list(person)).build()) + .build() + + GraphQLObjectType goodImpl = newObject() + .name("GoodImpl") + .field(newFieldDefinition().name("field").type(list(actor)).build()) + .withInterface(interfaceType) + .build() + + GraphQLObjectType badImpl = newObject() + .name("BadImpl") + .field(newFieldDefinition().name("field").type(list(prop)).build()) + .withInterface(interfaceType) + .build() + + SchemaValidationErrorCollector goodErrorCollector = new SchemaValidationErrorCollector() + SchemaValidationErrorCollector badErrorCollector = new SchemaValidationErrorCollector() + + when: + new TypesImplementInterfaces().check(goodImpl, goodErrorCollector) + new TypesImplementInterfaces().check(badImpl, badErrorCollector) then: goodErrorCollector.getErrors().isEmpty() @@ -211,7 +244,6 @@ class ObjectsImplementInterfacesTest extends Specification { .name("Person") .possibleType(actor) .possibleType(director) - .typeResolver({}) .build() def prop = newObject() @@ -222,7 +254,6 @@ class ObjectsImplementInterfacesTest extends Specification { GraphQLInterfaceType interfaceType = newInterface() .name("TestInterface") .field(newFieldDefinition().name("field").type(person).build()) - .typeResolver({}) .build() GraphQLObjectType goodImpl = newObject() @@ -241,8 +272,8 @@ class ObjectsImplementInterfacesTest extends Specification { SchemaValidationErrorCollector badErrorCollector = new SchemaValidationErrorCollector() when: - new ObjectsImplementInterfaces().check(goodImpl, goodErrorCollector) - new ObjectsImplementInterfaces().check(badImpl, badErrorCollector) + new TypesImplementInterfaces().check(goodImpl, goodErrorCollector) + new TypesImplementInterfaces().check(badImpl, badErrorCollector) then: goodErrorCollector.getErrors().isEmpty() @@ -254,7 +285,6 @@ class ObjectsImplementInterfacesTest extends Specification { GraphQLInterfaceType interfaceType = newInterface() .name("TestInterface") .field(newFieldDefinition().name("field").type(GraphQLString).build()) - .typeResolver({}) .build() GraphQLObjectType goodImpl = newObject() @@ -273,8 +303,8 @@ class ObjectsImplementInterfacesTest extends Specification { SchemaValidationErrorCollector badErrorCollector = new SchemaValidationErrorCollector() when: - new ObjectsImplementInterfaces().check(goodImpl, goodErrorCollector) - new ObjectsImplementInterfaces().check(badImpl, badErrorCollector) + new TypesImplementInterfaces().check(goodImpl, goodErrorCollector) + new TypesImplementInterfaces().check(badImpl, badErrorCollector) then: goodErrorCollector.getErrors().isEmpty() @@ -287,7 +317,6 @@ class ObjectsImplementInterfacesTest extends Specification { GraphQLInterfaceType memberInterface = newInterface() .name("TestMemberInterface") .field(newFieldDefinition().name("field").type(GraphQLString).build()) - .typeResolver({}) .build() GraphQLObjectType memberInterfaceImpl = newObject() @@ -299,7 +328,6 @@ class ObjectsImplementInterfacesTest extends Specification { GraphQLInterfaceType testInterface = newInterface() .name("TestInterface") .field(newFieldDefinition().name("field").type(nonNull(memberInterface)).build()) - .typeResolver({}) .build() GraphQLObjectType testInterfaceImpl = newObject() @@ -311,10 +339,119 @@ class ObjectsImplementInterfacesTest extends Specification { SchemaValidationErrorCollector goodErrorCollector = new SchemaValidationErrorCollector() when: - new ObjectsImplementInterfaces().check(testInterfaceImpl, goodErrorCollector) + new TypesImplementInterfaces().check(testInterfaceImpl, goodErrorCollector) then: goodErrorCollector.getErrors().isEmpty() } + def "type can declare extra optional field arguments"() { + given: + + GraphQLInterfaceType InterfaceType = newInterface() + .name("Interface") + .field(newFieldDefinition().name("argField").type(GraphQLString)) + .build() + + SchemaValidationErrorCollector errorCollector = new SchemaValidationErrorCollector() + + GraphQLObjectType objType = newObject() + .name("Object") + .withInterface(InterfaceType) + .field(newFieldDefinition().name("argField").type(GraphQLString) + .argument(newArgument().name("arg1").type(GraphQLInt)) + ) + .build() + + when: + new TypesImplementInterfaces().check(objType, errorCollector) + + then: + def errors = errorCollector.getErrors() + errors.isEmpty() + } + + def "type should declare all arguments present in implemented interface"() { + given: + + GraphQLInterfaceType InterfaceType = newInterface() + .name("Interface") + .field(newFieldDefinition().name("argField").type(GraphQLString) + .argument(newArgument().name("arg1").type(GraphQLInt)) + .argument(newArgument().name("arg2").type(GraphQLInt)) + ) + .build() + + SchemaValidationErrorCollector errorCollector = new SchemaValidationErrorCollector() + + GraphQLObjectType objType = newObject() + .name("Object") + .withInterface(InterfaceType) + .field(newFieldDefinition().name("argField").type(GraphQLString) + .argument(newArgument().name("argX").type(GraphQLInt)) + .argument(newArgument().name("argZ").type(GraphQLInt)) + ) + .build() + + when: + new TypesImplementInterfaces().check(objType, errorCollector) + + then: + def errors = errorCollector.getErrors() + errors.size() == 1 + errors.iterator().next().description == "object type 'Object' does not implement interface 'Interface' because field 'argField' is missing argument(s): 'arg1, arg2'" + } + + def "type cannot declare extra non-null field arguments"() { + given: + + GraphQLInterfaceType InterfaceType = newInterface() + .name("Interface") + .field(newFieldDefinition().name("argField").type(GraphQLString)) + .build() + + SchemaValidationErrorCollector errorCollector = new SchemaValidationErrorCollector() + + GraphQLObjectType objType = newObject() + .name("Object") + .withInterface(InterfaceType) + .field(newFieldDefinition().name("argField").type(GraphQLString) + .argument(newArgument().name("arg1").type(nonNull(GraphQLInt))) + ) + .build() + + when: + new TypesImplementInterfaces().check(objType, errorCollector) + + then: + def errors = errorCollector.getErrors() + errors.size() == 1 + errors.iterator().next().description == "object type 'Object' field 'argField' defines an additional non-optional argument 'arg1' which is not allowed because field is also defined in interface 'Interface'" + } + + def "type can change order of field arguments"() { + given: + + GraphQLInterfaceType InterfaceType = newInterface() + .name("Interface") + .field(newFieldDefinition().name("argField1").type(GraphQLString)) + .field(newFieldDefinition().name("argField2").type(GraphQLString)) + .build() + + SchemaValidationErrorCollector errorCollector = new SchemaValidationErrorCollector() + + GraphQLObjectType objType = newObject() + .name("Object") + .withInterface(InterfaceType) + .field(newFieldDefinition().name("argField2").type(GraphQLString)) + .field(newFieldDefinition().name("argField1").type(GraphQLString)) + .build() + + when: + new TypesImplementInterfaces().check(objType, errorCollector) + + then: + def errors = errorCollector.getErrors() + errors.isEmpty() + } } diff --git a/src/test/groovy/graphql/schema/visibility/BlockedFieldsTest.groovy b/src/test/groovy/graphql/schema/visibility/BlockedFieldsTest.groovy index c5d053992c..9fdd63b9a3 100644 --- a/src/test/groovy/graphql/schema/visibility/BlockedFieldsTest.groovy +++ b/src/test/groovy/graphql/schema/visibility/BlockedFieldsTest.groovy @@ -2,6 +2,7 @@ package graphql.schema.visibility import graphql.StarWarsSchema import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphqlTypeComparatorRegistry import spock.lang.Specification import spock.lang.Unroll @@ -27,6 +28,7 @@ class BlockedFieldsTest extends Specification { .name("secretRoles") .type(list(GraphQLString)) ) + .comparatorRegistry(GraphqlTypeComparatorRegistry.BY_NAME_REGISTRY) .build() @Unroll @@ -43,12 +45,12 @@ class BlockedFieldsTest extends Specification { where: why | type | patterns | expectedFieldList - "partial field name match" | StarWarsSchema.characterInterface | [".*\\.name"] | ["id", "friends", "appearsIn"] - "no match" | StarWarsSchema.characterInterface | ["Character.mismatched"] | ["id", "name", "friends", "appearsIn"] + "partial field name match" | StarWarsSchema.characterInterface | [".*\\.name"] | ["appearsIn", "friends", "id"] + "no match" | StarWarsSchema.characterInterface | ["Character.mismatched"] | ["appearsIn", "friends", "id", "name",] "all blocked" | StarWarsSchema.characterInterface | [".*"] | [] - "needs FQN to match" | StarWarsSchema.characterInterface | ["name"] | ["id", "name", "friends", "appearsIn"] - "FQN" | StarWarsSchema.characterInterface | ["Character.name"] | ["id", "friends", "appearsIn"] - "multiple patterns" | StarWarsSchema.characterInterface | ["Character.name", ".*.id"] | ["friends", "appearsIn"] + "needs FQN to match" | StarWarsSchema.characterInterface | ["name"] | ["appearsIn", "friends", "id", "name",] + "FQN" | StarWarsSchema.characterInterface | ["Character.name"] | ["appearsIn", "friends", "id",] + "multiple patterns" | StarWarsSchema.characterInterface | ["Character.name", ".*.id"] | ["appearsIn", "friends",] "input partial field name match" | accessInputType | [".*\\.secretRoles"] | ["openRoles", "questionableRoles"] "input no match" | accessInputType | ["Access.mismatched"] | ["openRoles", "questionableRoles", "secretRoles"] diff --git a/src/test/groovy/graphql/schema/visibility/GraphqlFieldVisibilityTest.groovy b/src/test/groovy/graphql/schema/visibility/GraphqlFieldVisibilityTest.groovy index 1a5d631942..e292cffb9a 100644 --- a/src/test/groovy/graphql/schema/visibility/GraphqlFieldVisibilityTest.groovy +++ b/src/test/groovy/graphql/schema/visibility/GraphqlFieldVisibilityTest.groovy @@ -6,6 +6,9 @@ import graphql.StarWarsSchema import graphql.execution.AsyncExecutionStrategy import graphql.introspection.IntrospectionQuery import graphql.language.Field +import graphql.schema.DataFetcher +import graphql.schema.FieldCoordinates +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLSchema @@ -23,45 +26,14 @@ import static graphql.schema.visibility.NoIntrospectionGraphqlFieldVisibility.NO class GraphqlFieldVisibilityTest extends Specification { - def "visibility is enforced"() { - - GraphqlFieldVisibility banNameVisibility = newBlock().addPattern(".*\\.name").build() - def schema = GraphQLSchema.newSchema() - .query(StarWarsSchema.queryType) - .fieldVisibility(banNameVisibility) - .build() - - def graphQL = GraphQL.newGraphQL(schema).build() - - given: - def query = """ - { - hero { - id - name - friends { - aliasHandled: name - } - } - } - """ - - when: - def result = graphQL.execute(query) - - then: - result.errors[0].getMessage().contains("Field 'name' in type 'Character' is undefined") - result.errors[1].getMessage().contains("Field 'name' in type 'Character' is undefined") - } - def "introspection visibility is enforced"() { - - given: - + GraphQLCodeRegistry codeRegistry = StarWarsSchema.codeRegistry.transform(builder -> { + builder.fieldVisibility(fieldVisibility) + }) def schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(fieldVisibility) + .codeRegistry(codeRegistry) .build() def graphQL = GraphQL.newGraphQL(schema).build() @@ -92,10 +64,12 @@ class GraphqlFieldVisibilityTest extends Specification { def "introspection turned off via field visibility"() { given: - + GraphQLCodeRegistry codeRegistry = StarWarsSchema.codeRegistry.transform(builder -> { + builder.fieldVisibility(NO_INTROSPECTION_FIELD_VISIBILITY) + }) def schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(NO_INTROSPECTION_FIELD_VISIBILITY) + .codeRegistry(codeRegistry) .build() def graphQL = GraphQL.newGraphQL(schema).build() @@ -114,152 +88,158 @@ class GraphqlFieldVisibilityTest extends Specification { def "schema printing filters on visibility"() { when: + def codeRegistry = StarWarsSchema.codeRegistry.transform(builder -> { + builder.fieldVisibility(DEFAULT_FIELD_VISIBILITY) + }) def schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(DEFAULT_FIELD_VISIBILITY) + .codeRegistry(codeRegistry) .build() - def result = new SchemaPrinter().print(schema) + def options = SchemaPrinter.Options.defaultOptions().includeDirectives(false) + def result = new SchemaPrinter(options).print(schema) then: result == """schema { query: QueryType } -#A character in the Star Wars Trilogy +"A character in the Star Wars Trilogy" interface Character { - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The friends of the character, or an empty list if they have none. + "The friends of the character, or an empty list if they have none." friends: [Character] - #The id of the character. + "The id of the character." id: String! - #The name of the character. + "The name of the character." name: String } -#A mechanical creature in the Star Wars universe. +"A mechanical creature in the Star Wars universe." type Droid implements Character { - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The friends of the droid, or an empty list if they have none. + "The friends of the droid, or an empty list if they have none." friends: [Character] - #The id of the droid. + "The id of the droid." id: String! - #The name of the droid. + "The name of the droid." name: String - #The primary function of the droid. + "The primary function of the droid." primaryFunction: String } -#A humanoid creature in the Star Wars universe. +"A humanoid creature in the Star Wars universe." type Human implements Character { - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The friends of the human, or an empty list if they have none. + "The friends of the human, or an empty list if they have none." friends: [Character] - #The home planet of the human, or null if unknown. + "The home planet of the human, or null if unknown." homePlanet: String - #The id of the human. + "The id of the human." id: String! - #The name of the human. + "The name of the human." name: String } type QueryType { droid( - #id of the droid - id: String! + "id of the droid" + id: String! ): Droid hero( - #If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode. - episode: Episode + "If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode." + episode: Episode ): Character human( - #id of the human - id: String! + "id of the human" + id: String! ): Human } -#One of the films in the Star Wars Trilogy +"One of the films in the Star Wars Trilogy" enum Episode { - #Released in 1980. + "Released in 1980." EMPIRE - #Released in 1983. + "Released in 1983." JEDI - #Released in 1977. + "Released in 1977." NEWHOPE } """ // and with specific bans - when: + codeRegistry = StarWarsSchema.codeRegistry.transform(builder -> { + builder.fieldVisibility(ban(['Droid.id', 'Character.name', "QueryType.hero"])) + }) schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(ban(['Droid.id', 'Character.name', "QueryType.hero"])) + .codeRegistry(codeRegistry) .build() - result = new SchemaPrinter().print(schema) + result = new SchemaPrinter(options).print(schema) then: result == """schema { query: QueryType } -#A character in the Star Wars Trilogy +"A character in the Star Wars Trilogy" interface Character { - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The friends of the character, or an empty list if they have none. + "The friends of the character, or an empty list if they have none." friends: [Character] - #The id of the character. + "The id of the character." id: String! } -#A mechanical creature in the Star Wars universe. +"A mechanical creature in the Star Wars universe." type Droid implements Character { - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The friends of the droid, or an empty list if they have none. + "The friends of the droid, or an empty list if they have none." friends: [Character] - #The name of the droid. + "The name of the droid." name: String - #The primary function of the droid. + "The primary function of the droid." primaryFunction: String } -#A humanoid creature in the Star Wars universe. +"A humanoid creature in the Star Wars universe." type Human implements Character { - #Which movies they appear in. + "Which movies they appear in." appearsIn: [Episode] - #The friends of the human, or an empty list if they have none. + "The friends of the human, or an empty list if they have none." friends: [Character] - #The home planet of the human, or null if unknown. + "The home planet of the human, or null if unknown." homePlanet: String - #The id of the human. + "The id of the human." id: String! - #The name of the human. + "The name of the human." name: String } type QueryType { droid( - #id of the droid - id: String! + "id of the droid" + id: String! ): Droid human( - #id of the human - id: String! + "id of the human" + id: String! ): Human } -#One of the films in the Star Wars Trilogy +"One of the films in the Star Wars Trilogy" enum Episode { - #Released in 1980. + "Released in 1980." EMPIRE - #Released in 1983. + "Released in 1983." JEDI - #Released in 1977. + "Released in 1977." NEWHOPE } """ @@ -275,16 +255,15 @@ enum Episode { } def "ensure execution cant get to the field"() { - - when: + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .fieldVisibility(ban(['Droid.appearsIn'])) + .build() def schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(ban(['Droid.appearsIn'])) + .codeRegistry(codeRegistry) .build() - - def executionStrategy = new AsyncExecutionStrategy() { // gives us access to this unit tested method @@ -307,17 +286,28 @@ enum Episode { .field(newInputObjectField().name("closedField").type(GraphQLString)) .build() - def inputQueryType = GraphQLObjectType.newObject().name("InputQuery") - .field(newFieldDefinition().name("hello").type(GraphQLString) - .argument(newArgument().name("arg").type(inputType)) - .dataFetcher({ env -> return "world" }) - ) - .build() + DataFetcher inputDataFetcher = { env -> return "world" } + + def inputQueryType = GraphQLObjectType.newObject() + .name("InputQuery") + .field(newFieldDefinition() + .name("hello") + .type(GraphQLString) + .argument(newArgument() + .name("arg") + .type(inputType)) + ).build() def "ensure input field are blocked"() { when: + def inputTypeCoordinates = FieldCoordinates.coordinates("InputQuery", "hello") + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher(inputTypeCoordinates, inputDataFetcher) + .build() + def schema = GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) .query(inputQueryType) .build() @@ -337,9 +327,10 @@ enum Episode { er.getData() == ["hello": "world"] when: + codeRegistry = codeRegistry.transform({builder -> builder.fieldVisibility(ban(['InputType.closedField']))}) schema = GraphQLSchema.newSchema() .query(inputQueryType) - .fieldVisibility(ban(['InputType.closedField'])) + .codeRegistry(codeRegistry) .build() graphQL = GraphQL.newGraphQL(schema).build() @@ -363,9 +354,12 @@ enum Episode { given: + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .fieldVisibility(fieldVisibility) + .build() def schema = GraphQLSchema.newSchema() .query(inputQueryType) - .fieldVisibility(fieldVisibility) + .codeRegistry(codeRegistry) .build() def graphQL = GraphQL.newGraphQL(schema).build() @@ -389,12 +383,16 @@ enum Episode { } def "input schema print is blocked"() { + + def options = SchemaPrinter.Options.defaultOptions().includeDirectives(false) + when: + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry().fieldVisibility(DEFAULT_FIELD_VISIBILITY).build() def schema = GraphQLSchema.newSchema() .query(inputQueryType) - .fieldVisibility(DEFAULT_FIELD_VISIBILITY) + .codeRegistry(codeRegistry) .build() - def result = new SchemaPrinter().print(schema) + def result = new SchemaPrinter(options).print(schema) then: result == '''schema { @@ -412,11 +410,13 @@ input InputType { ''' when: + + codeRegistry = GraphQLCodeRegistry.newCodeRegistry().fieldVisibility(ban(["InputType.closedField"])).build() schema = GraphQLSchema.newSchema() .query(inputQueryType) - .fieldVisibility(ban(["InputType.closedField"])) + .codeRegistry(codeRegistry) .build() - result = new SchemaPrinter().print(schema) + result = new SchemaPrinter(options).print(schema) then: result == '''schema { diff --git a/src/test/groovy/graphql/schema/visitor/GraphQLSchemaVisitorTest.groovy b/src/test/groovy/graphql/schema/visitor/GraphQLSchemaVisitorTest.groovy new file mode 100644 index 0000000000..9629920db6 --- /dev/null +++ b/src/test/groovy/graphql/schema/visitor/GraphQLSchemaVisitorTest.groovy @@ -0,0 +1,372 @@ +package graphql.schema.visitor + +import graphql.Assert +import graphql.TestUtil +import graphql.schema.GraphQLAppliedDirective +import graphql.schema.GraphQLAppliedDirectiveArgument +import graphql.schema.GraphQLArgument +import graphql.schema.GraphQLDirective +import graphql.schema.GraphQLEnumType +import graphql.schema.GraphQLEnumValueDefinition +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLInputObjectField +import graphql.schema.GraphQLInputObjectType +import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLModifiedType +import graphql.schema.GraphQLNamedSchemaElement +import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLScalarType +import graphql.schema.GraphQLSchemaElement +import graphql.schema.GraphQLTypeUtil +import graphql.schema.GraphQLUnionType +import graphql.schema.SchemaTransformer +import graphql.schema.SchemaTraverser +import spock.lang.Specification + +import static graphql.schema.FieldCoordinates.coordinates + +class GraphQLSchemaVisitorTest extends Specification { + + + def toNames(GraphQLSchemaElement start, List elements) { + def l = elements.collect({ + return GraphQLTypeUtil.simplePrint(it) + }) + l.add(0, GraphQLTypeUtil.simplePrint((start))) + return l + } + + class CapturingSchemaVisitor implements GraphQLSchemaVisitor { + + Map> pathsToElement = [:] + def types = [:] + def leafs = [:] + def schema + + @Override + GraphQLSchemaTraversalControl visitSchemaElement(GraphQLSchemaElement schemaElement, SchemaElementVisitorEnvironment environment) { + this.schema = environment.getSchema() + def leadingElements = environment.getLeadingElements() + pathsToElement.put(schemaElement, leadingElements) + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitFieldDefinition(GraphQLFieldDefinition fieldDefinition, FieldDefinitionVisitorEnvironment environment) { + def key = environment.container.getName() + "." + fieldDefinition.getName() + ":" + environment.getUnwrappedType().getName() + leafs[key] = fieldDefinition + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitAppliedDirective(GraphQLAppliedDirective appliedDirective, AppliedDirectiveVisitorEnvironment environment) { + def key = "@" + environment.container.getName() + "." + appliedDirective.getName() + leafs[key] = appliedDirective + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitAppliedDirectiveArgument(GraphQLAppliedDirectiveArgument appliedDirectiveArgument, AppliedDirectiveArgumentVisitorEnvironment environment) { + def key = "@" + environment.container.getName() + "." + appliedDirectiveArgument.getName() + ":" + environment.getUnwrappedType().getName() + leafs[key] = appliedDirectiveArgument + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitArgument(GraphQLArgument argument, ArgumentVisitorEnvironment environment) { + def key = environment.container.getName() + "." + argument.getName() + ":" + environment.getUnwrappedType().getName() + leafs[key] = argument + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitDirective(GraphQLDirective directive, DirectiveVisitorEnvironment environment) { + leafs[directive.getName()] = directive + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitEnumType(GraphQLEnumType enumType, EnumTypeVisitorEnvironment environment) { + types[enumType.getName()] = enumType + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitEnumValueDefinition(GraphQLEnumValueDefinition enumValueDefinition, EnumValueDefinitionVisitorEnvironment environment) { + leafs[environment.container.getName() + "." + enumValueDefinition.getName()] = enumValueDefinition + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitInputObjectField(GraphQLInputObjectField inputObjectField, InputObjectFieldVisitorEnvironment environment) { + def key = environment.container.getName() + "." + inputObjectField.getName() + ":" + environment.getUnwrappedType().getName() + leafs[key] = inputObjectField + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitInputObjectType(GraphQLInputObjectType inputObjectType, InputObjectTypeVisitorEnvironment environment) { + types[inputObjectType.getName()] = inputObjectType + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitInterfaceType(GraphQLInterfaceType interfaceType, InterfaceTypeVisitorEnvironment environment) { + types[interfaceType.getName()] = interfaceType + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitScalarType(GraphQLScalarType scalarType, ScalarTypeVisitorEnvironment environment) { + types[scalarType.getName()] = scalarType + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitUnionType(GraphQLUnionType unionType, UnionTypeVisitorEnvironment environment) { + types[unionType.getName()] = unionType + return environment.ok() + } + + @Override + GraphQLSchemaTraversalControl visitObjectType(GraphQLObjectType objectType, ObjectVisitorEnvironment environment) { + types[objectType.getName()] = objectType + return environment.ok() + } + } + + def uberSDL = ''' + directive @directive(directiveArgument : String) on FIELD_DEFINITION + + type Query { + object(arg : InputObjectTypeA) : [ObjectTypeA!]! @directive(directiveArgument : "directiveArgument") + } + + input InputObjectTypeA { + fieldA : String! + } + + input InputObjectTypeB { + fieldB : String + } + + interface InterfaceTypeA { + fieldA : [String!]! + } + + type ObjectTypeA implements InterfaceTypeA { + fieldA : [String!]! + fieldAToX : [ObjectTypeX!]! + } + + type ObjectTypeB { + fieldB : String + } + + type ObjectTypeX { + fieldX(arg : InputObjectTypeA) : ObjectTypeX # self referential + } + + union UnionTypeA = ObjectTypeA | ObjectTypeB + + enum EnumTypeA { + enumDefA + enumDefB + } + ''' + + def schema = TestUtil.schema(uberSDL) + + + def "will visit things"() { + + def visitor = new CapturingSchemaVisitor() + + when: + new SchemaTraverser().depthFirstFullSchema(visitor.toTypeVisitor(), this.schema) + + then: + + visitor.schema == this.schema + visitor.types["Query"] instanceof GraphQLObjectType + + visitor.leafs["directive"] instanceof GraphQLDirective + visitor.leafs["directive.directiveArgument:String"] instanceof GraphQLArgument + + visitor.leafs["@object.directive"] instanceof GraphQLAppliedDirective + visitor.leafs["@directive.directiveArgument:String"] instanceof GraphQLAppliedDirectiveArgument + + visitor.types["EnumTypeA"] instanceof GraphQLEnumType + visitor.leafs["EnumTypeA.enumDefA"] instanceof GraphQLEnumValueDefinition + visitor.leafs["EnumTypeA.enumDefB"] instanceof GraphQLEnumValueDefinition + + visitor.types["InputObjectTypeA"] instanceof GraphQLInputObjectType + visitor.types["InputObjectTypeB"] instanceof GraphQLInputObjectType + visitor.leafs["InputObjectTypeA.fieldA:String"] instanceof GraphQLInputObjectField + + visitor.types["InterfaceTypeA"] instanceof GraphQLInterfaceType + visitor.leafs["InterfaceTypeA.fieldA:String"] instanceof GraphQLFieldDefinition + + visitor.types["ObjectTypeA"] instanceof GraphQLObjectType + visitor.types["ObjectTypeB"] instanceof GraphQLObjectType + visitor.leafs["ObjectTypeA.fieldA:String"] instanceof GraphQLFieldDefinition + + visitor.types["String"] instanceof GraphQLScalarType + + visitor.types["UnionTypeA"] instanceof GraphQLUnionType + + // schema paths + + + def fieldX = schema.getFieldDefinition(coordinates("ObjectTypeX", "fieldX")) + def fieldXArg = fieldX.getArgument("arg") + toNames(fieldXArg, visitor.pathsToElement[fieldXArg]) == [ + "arg", + "fieldX", "ObjectTypeX", "ObjectTypeX!", "[ObjectTypeX!]", "[ObjectTypeX!]!", + "fieldAToX", "ObjectTypeA", "ObjectTypeA!", "[ObjectTypeA!]", "[ObjectTypeA!]!", + "object", "Query"] + + def argInputType = fieldXArg.getType() as GraphQLInputObjectType + def inputFieldA = argInputType.getFieldDefinition("fieldA") + + toNames(inputFieldA, visitor.pathsToElement[inputFieldA]) == [ + "fieldA", "InputObjectTypeA", "arg", + "fieldX", "ObjectTypeX", "ObjectTypeX!", "[ObjectTypeX!]", "[ObjectTypeX!]!", + "fieldAToX", "ObjectTypeA", "ObjectTypeA!", "[ObjectTypeA!]", "[ObjectTypeA!]!", + "object", "Query"] + + } + + def "can transform schemas via this pattern"() { + def sdl = """ + type Query { + f : xfoo + } + + type xfoo { + bar : xbar + } + + type xbar { + baz : String + } + + """ + + def schema = TestUtil.schema(sdl) + + def schemaVisitor = new GraphQLSchemaVisitor() { + + @Override + GraphQLSchemaTraversalControl visitObjectType(GraphQLObjectType objectType, GraphQLSchemaVisitor.ObjectVisitorEnvironment environment) { + if (objectType.name.startsWith("x")) { + def newName = objectType.name.replaceFirst("x", "").capitalize() + def newType = objectType.transform { it.name(newName) } + return environment.changeNode(newType) + } + return environment.ok(); + } + } + + when: + def newSchema = new SchemaTransformer().transform(schema, schemaVisitor.toTypeVisitor()) + then: + newSchema.getType("Foo") instanceof GraphQLObjectType + newSchema.getType("Bar") instanceof GraphQLObjectType + } + + def "can change things at the schema element level and its does not continue"() { + def sdl = """ + type Query { + f : xfoo + } + + type xfoo { + bar : xbar + } + + type xbar { + baz : String + } + + """ + + def schema = TestUtil.schema(sdl) + + def schemaVisitor = new GraphQLSchemaVisitor() { + + @Override + GraphQLSchemaTraversalControl visitSchemaElement(GraphQLSchemaElement schemaElement, GraphQLSchemaVisitor.SchemaElementVisitorEnvironment environment) { + if (schemaElement instanceof GraphQLObjectType) { + GraphQLObjectType objectType = schemaElement + if (objectType.name.startsWith("x")) { + def newName = objectType.name.replaceFirst("x", "y").capitalize() + def newType = objectType.transform { it.name(newName) } + return environment.changeNode(newType) + } + } + return environment.ok(); + } + + @Override + GraphQLSchemaTraversalControl visitObjectType(GraphQLObjectType objectType, GraphQLSchemaVisitor.ObjectVisitorEnvironment environment) { + // this wont be called if we changed it + if (objectType.name.startsWith("x")) { + assert false, "This should not be called for X object types" + } + return environment.ok(); + } + } + + when: + def newSchema = new SchemaTransformer().transform(schema, schemaVisitor.toTypeVisitor()) + then: + newSchema.getType("Yfoo") instanceof GraphQLObjectType + newSchema.getType("Ybar") instanceof GraphQLObjectType + } + + def "can quit visitation"() { + + def visited = [] + def schemaVisitor = new GraphQLSchemaVisitor() { + + @Override + GraphQLSchemaTraversalControl visitSchemaElement(GraphQLSchemaElement schemaElement, GraphQLSchemaVisitor.SchemaElementVisitorEnvironment environment) { + def name = GraphQLTypeUtil.simplePrint(schemaElement) + if (name.toLowerCase().startsWith("x")) { + visited.add(name) + if (name.contains("Quit")) { + return environment.quit() + } + } + return environment.ok() + } + } + when: // test quit + + def sdl = """ + type Query { + xField(xQuit : XInputType) : XObjectType + } + + type XObjectType { + xObj(xArg : String) : XObjectType2 + } + + type XObjectType2 { + xObj2 : XObjectType2 + } + + input XInputType { + xinA : String + } + + """ + + def schema = TestUtil.schema(sdl) + new SchemaTransformer().transform(schema,schemaVisitor.toTypeVisitor()) + + then: + visited == ["xField", "xQuit",] + } +} diff --git a/src/test/groovy/graphql/util/AnonymizerTest.groovy b/src/test/groovy/graphql/util/AnonymizerTest.groovy new file mode 100644 index 0000000000..6865879f55 --- /dev/null +++ b/src/test/groovy/graphql/util/AnonymizerTest.groovy @@ -0,0 +1,876 @@ +package graphql.util + +import graphql.AssertException +import graphql.TestUtil +import graphql.schema.idl.DirectiveInfo +import graphql.schema.idl.SchemaPrinter +import spock.lang.Specification + +class AnonymizerTest extends Specification { + + def "simple schema and query"() { + given: + def schema = TestUtil.schema(""" + type Query { + foo: Foo + } + type Foo { + bar1: String + bar2: ID + } + """) + def query = "{foo{bar1 bar2}}" + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1: Object2 +} + +type Object2 { + field2: String + field3: ID +} +""" + newQuery == "{field1{field2 field3}}" + } + + def "query with fragments"() { + given: + def schema = TestUtil.schema(""" + type Query { + foo: Foo + } + type Foo { + bar1: String + bar2: ID + } + """) + def query = "{...MyFragment foo {... on Foo{bar1 bar2}}} fragment MyFragment on Query{foo {bar1 bar2 }}" + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1: Object2 +} + +type Object2 { + field2: String + field3: ID +} +""" + newQuery == "{...Fragment1 field1{...on Object2{field2 field3}}} fragment Fragment1 on Object1 {field1{field2 field3}}" + + } + + def "query with arguments"() { + given: + def schema = TestUtil.schema(""" + type Query { + foo(id: ID, otherArg: String): Foo + } + type Foo { + bar1(someArg: Boolean): String + bar2: ID + } + """) + def query = '{foo(id: "123", otherArg: "456") {bar1 bar2 }}' + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1(argument1: ID, argument2: String): Object2 +} + +type Object2 { + field2(argument3: Boolean): String + field3: ID +} +""" + newQuery == '{field1(argument1:"stringValue1",argument2:"stringValue2"){field2 field3}}' + + } + + def "query with operation and variable names"() { + given: + def schema = TestUtil.schema(""" + type Query { + foo(id: ID, otherArg: String): Foo + } + type Foo { + bar1(someArg: Boolean): String + bar2(otherId: ID): ID + } + """) + def query = 'query myOperation($myVar:ID) {foo(id: $myVar, otherArg: "456") {bar1 bar2(otherId: $myVar) }}' + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query], [myVar: "myVarValue"]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1(argument1: ID, argument2: String): Object2 +} + +type Object2 { + field2(argument3: Boolean): String + field3(argument4: ID): ID +} +""" + newQuery == 'query operation($var1:ID){field1(argument1:$var1,argument2:"stringValue1"){field2 field3(argument4:$var1)}}' + + + } + + def "rejects query with multiple operations"() { + given: + def schema = TestUtil.schema(""" + type Query { + foo: String + } + """) + def query = 'query myOperation{foo} query myOtherQuery{foo}' + + when: + Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + + then: + def assertException = thrown(AssertException) + assertException.getMessage().contains("Query must have exactly one operation") + + } + + def "replace values"() { + given: + def schema = TestUtil.schema(""" + + type Query { + foo(myInput: MyInput!): String + foo2(arg: String = "toBeReplaced"): String + foo3(arg: [[String!]!]! = [["defaultValueList"]]): String + foo4(arg: Weekend! = SATURDAY): String + foo5(arg: MyInput! = { foo2: "default", foo5: SUNDAY, foo6: { foo1: 10 } } ): String + foo6: Object + } + input MyInput { + foo1: Int + foo2: String = "myDefaultValue" + foo3: Int = 1234 + foo4: Int = 4567 + foo5: Weekend = SUNDAY + foo6: MyInput + } + + enum Weekend { + SATURDAY + SUNDAY + } + + type Object implements Iface { + id: String + # default value must match across hierarchy + bar(arg: MyInput = {foo2: "adefault", foo5: SATURDAY}): String + } + + interface Iface { + id: String + + bar(arg: MyInput = {foo2: "adefault", foo5: SATURDAY}): String + } + """) + def query = ''' + query myQuery($myVar: String = "someValue", + $varFoo3: [[String!]!]! = [["defaultValueList"]], + $varFoo4: Weekend! = SATURDAY, + $varFoo5: MyInput! = { foo2: "default", foo5: SUNDAY, foo6: { foo1: 10 } }){ + foo(myInput: {foo1: 8923, foo2: $myVar }) + foo3(arg: $varFoo3) + foo4(arg: $varFoo4) + foo5(arg: $varFoo5) + } + ''' + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """\ + schema { + query: Object1 + } + + interface Interface1 { + field7: String + field8(argument6: InputObject1 = {inputField2 : "stringValue5", inputField5 : EnumValue1}): String + } + + type Object1 { + field1(argument1: InputObject1!): String + field2(argument2: String = "stringValue2"): String + field3(argument3: [[String!]!]! = [["stringValue3"]]): String + field4(argument4: Enum1! = EnumValue1): String + field5(argument5: InputObject1! = {inputField2 : "stringValue4", inputField5 : EnumValue2, inputField6 : {inputField1 : 3}}): String + field6: Object2 + } + + type Object2 implements Interface1 { + field7: String + field8(argument6: InputObject1 = {inputField2 : "stringValue5", inputField5 : EnumValue1}): String + } + + enum Enum1 { + EnumValue1 + EnumValue2 + } + + input InputObject1 { + inputField1: Int + inputField2: String = "stringValue1" + inputField3: Int = 1 + inputField4: Int = 2 + inputField5: Enum1 = EnumValue2 + inputField6: InputObject1 + } + """.stripIndent() + newQuery == 'query operation($var1:String="stringValue1",$var2:[[String!]!]!=[["stringValue2"]],$var3:Enum1!=EnumValue1,$var4:InputObject1!={inputField2:"stringValue3",inputField5:EnumValue2,inputField6:{inputField1:2}}){field1(argument1:{inputField1:1,inputField2:$var1}) field3(argument3:$var2) field4(argument4:$var3) field5(argument5:$var4)}' + } + + def "query with aliases"() { + given: + def schema = TestUtil.schema(""" + type Query { + foo: Foo + } + type Foo { + bar1: String + bar2: ID + } + """) + def query = "{myAlias: foo { anotherOne: bar2}}" + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newQuery = result.queries[0] + + then: + newQuery == "{alias1:field1{alias2:field3}}" + } + + def "complex schema"() { + given: + def schema = TestUtil.schema(""" + type Query { + pets: Pet + allPets: AllPets + } + enum PetKind { + FRIENDLY + NOT_FRIENDLY + } + + interface Pet { + name: String + petKind: PetKind + } + type Dog implements Pet { + name: String + dogField: String + petKind: PetKind + } + type Cat implements Pet { + name: String + catField: String + petKind: PetKind + } + union AllPets = Dog | Cat + """) + + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object1 +} + +interface Interface1 { + field2: String + field3: Enum1 +} + +union Union1 = Object2 | Object3 + +type Object1 { + field1: Interface1 + field4: Union1 +} + +type Object2 implements Interface1 { + field2: String + field3: Enum1 + field5: String +} + +type Object3 implements Interface1 { + field2: String + field3: Enum1 + field6: String +} + +enum Enum1 { + EnumValue1 + EnumValue2 +} +""" + } + + def "interface hierarchies with arguments"() { + given: + def schema = TestUtil.schema(""" + type Query { + pets: Pet + } + + interface Pet { + name: String + } + interface GoodPet implements Pet { + name(nameArg1: String): String + goodScore: Int + } + type Cat implements GoodPet & Pet{ + name(nameArg1:String, nameArg2: ID): String + goodScore: Int + catField: ID + } + + interface ProblematicPet implements Pet { + name(nameArg3:String): String + problemField: Float + } + interface AnotherInterface implements ProblematicPet & Pet { + name(nameArg3: String, nameArg4: Float): String + problemField: Float + otherField: Boolean + } + type Dog implements AnotherInterface & ProblematicPet & Pet { + name(nameArg3: String, nameArg4: Float): String + problemField: Float + otherField: Boolean + dogField: Int + } + """) + + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object3 +} + +interface Interface1 implements Interface2 { + field1(argument1: String): String + field2: Int +} + +interface Interface2 { + field1: String +} + +interface Interface3 implements Interface2 { + field1(argument3: String): String + field4: Float +} + +interface Interface4 implements Interface2 & Interface3 { + field1(argument3: String, argument4: Float): String + field4: Float + field5: Boolean +} + +type Object1 implements Interface1 & Interface2 { + field1(argument1: String, argument2: ID): String + field2: Int + field3: ID +} + +type Object2 implements Interface2 & Interface3 & Interface4 { + field1(argument3: String, argument4: Float): String + field4: Float + field5: Boolean + field6: Int +} + +type Object3 { + field7: Interface2 +} +""" + } + + def "simple interface hierarchies with arguments"() { + given: + def schema = TestUtil.schema(""" + type Query { + pets: Pet + } + + interface Pet { + name(nameArg: String): String + } + type Dog implements Pet { + name(nameArg: String, otherOptionalArg: Float): String + } + """) + + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object2 +} + +interface Interface1 { + field1(argument1: String): String +} + +type Object1 implements Interface1 { + field1(argument1: String, argument2: Float): String +} + +type Object2 { + field2: Interface1 +} +""" + } + + def "query with introspection typename"() { + given: + def schema = TestUtil.schema(""" + type Query { + pets: Pet + } + interface Pet { + name:String + } + type Dog implements Pet { + name:String + } + """) + + def query = "{pets {__typename otherTypeName:__typename name}}" + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newQuery = result.queries[0] + + then: + newQuery == "{field2{__typename alias1:__typename field1}}" + } + + def "handles cyclic types"() { + def schema = TestUtil.schema(""" + type Query { + query: Foo + } + type Foo { + foo: [Bar] + } + + type Bar { + bar: [Foo] + } + """) + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1: Object2 +} + +type Object2 { + field2: [Object3] +} + +type Object3 { + field3: [Object2] +} +""" + } + + def "descriptions are removed"() { + def schema = TestUtil.schema(""" + "DOC" + type Query { + "DOC" + query( + "DOC" + arg: String): Foo + } + "DOC" + type Foo { + "DOC" + foo: String + } + + """) + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1(argument1: String): Object2 +} + +type Object2 { + field2: String +} +""" + } + + def "deprecated reasons are removed"() { + def schema = TestUtil.schema(""" + type Query { + foo: String @deprecated(reason: "secret") + } + """) + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object1 +} + +type Object1 { + field1: String @deprecated +} +""" + } + + def "same field across hierarchy"() { + def schema = TestUtil.schema(""" + type Query { + foo: Interface2 + } +interface Interface1 implements Interface2 & Interface3 { + id: ID! +} +interface Interface4 implements Interface1 & Interface2 & Interface3 { + id: ID! +} +interface Interface5 implements Interface1 & Interface2 & Interface3 & Interface6{ + id: ID! +} +interface Interface2 { + id: ID! +} + +interface Interface3 { + id: ID! +} +interface Interface6 { + id: ID! +} + +interface Interface7 implements Interface6 { + id: ID! +} + + + """) + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectiveDefinitions(false)).print(result) + + then: + newSchema == """schema { + query: Object1 +} + +interface Interface1 implements Interface2 & Interface3 { + field1: ID! +} + +interface Interface2 { + field1: ID! +} + +interface Interface3 { + field1: ID! +} + +interface Interface4 implements Interface1 & Interface2 & Interface3 { + field1: ID! +} + +interface Interface5 implements Interface1 & Interface2 & Interface3 & Interface6 { + field1: ID! +} + +interface Interface6 { + field1: ID! +} + +interface Interface7 implements Interface6 { + field1: ID! +} + +type Object1 { + field2: Interface2 +} +""" + } + + def "complex schema with directives"() { + given: + def schema = TestUtil.schema(""" + directive @key(fields: String! = "sensitive") repeatable on SCHEMA | SCALAR + | OBJECT + | FIELD_DEFINITION + | ARGUMENT_DEFINITION + | INTERFACE + | UNION + | ENUM + | ENUM_VALUE + | INPUT_OBJECT + | INPUT_FIELD_DEFINITION + + schema @key(fields: "hello") { + query: Query + } + + type Query @key(fields: "hello2") { + pets: Pet @key(fields: "hello3") + allPets: AllPets @deprecated(reason: "no money") + } + + enum PetKind @key(fields: "hello4") { + FRIENDLY @key(fields: "hello5") + NOT_FRIENDLY + } + + interface Pet @key(fields: "hello6") { + name: String + petKind: PetKind + } + type Dog implements Pet { + name: String + dogField(limit: LimitInput): String + petKind: PetKind + } + + input LimitInput @key(fields: "hello7") { + value: Int @key(fields: "hello8") + } + + union AllPets @key(fields: "hello9") = Dog + """) + + when: + def result = Anonymizer.anonymizeSchema(schema) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions() + .includeDirectives({!DirectiveInfo.isGraphqlSpecifiedDirective(it) || it == "deprecated"})) + .print(result) + + then: + newSchema == """schema @Directive1(argument1 : "stringValue1"){ + query: Object1 +} + +directive @Directive1(argument1: String! = "stringValue4") repeatable on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String! = "No longer supported" + ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +interface Interface1 @Directive1(argument1 : "stringValue12") { + field2: String + field3: Enum1 +} + +union Union1 @Directive1(argument1 : "stringValue21") = Object2 + +type Object1 @Directive1(argument1 : "stringValue8") { + field1: Interface1 @Directive1(argument1 : "stringValue9") + field4: Union1 @deprecated +} + +type Object2 implements Interface1 { + field2: String + field3: Enum1 + field5(argument2: InputObject1): String +} + +enum Enum1 @Directive1(argument1 : "stringValue15") { + EnumValue1 @Directive1(argument1 : "stringValue18") + EnumValue2 +} + +input InputObject1 @Directive1(argument1 : "stringValue24") { + inputField1: Int @Directive1(argument1 : "stringValue27") +} +""" + } + + def "query with directives"() { + given: + def schema = TestUtil.schema(""" + directive @whatever(myArg: String = "secret") on FIELD + type Query { + foo: Foo + } + type Foo { + bar: String + } + """) + def query = 'query{foo @whatever {bar @whatever }}' + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(SchemaPrinter.ExcludeGraphQLSpecifiedDirectivesPredicate)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +directive @Directive1(argument1: String = "stringValue1") on FIELD + +type Object1 { + field1: Object2 +} + +type Object2 { + field2: String +} +""" + newQuery == "{field1 @Directive1{field2 @Directive1}}" + + } + + def "query with directives with arguments"() { + given: + def schema = TestUtil.schema(""" + directive @whatever(myArg: String = "secret") on FIELD + type Query { + foo: Foo + } + type Foo { + bar: String + } + """) + def query = '{foo @whatever(myArg: "secret2") {bar @whatever(myArg: "secret3") }}' + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(SchemaPrinter.ExcludeGraphQLSpecifiedDirectivesPredicate)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +directive @Directive1(argument1: String = "stringValue1") on FIELD + +type Object1 { + field1: Object2 +} + +type Object2 { + field2: String +} +""" + newQuery == '{field1 @Directive1(argument1:"stringValue2"){field2 @Directive1(argument1:"stringValue1")}}' + + } + + def "query with directives with arguments and variables"() { + given: + def schema = TestUtil.schema(""" + directive @whatever(myArg: String = "secret") on FIELD + type Query { + foo: Foo + } + type Foo { + bar(barArg: String): String + } + """) + def query = 'query($myVar: String = "myDefaultValue"){foo @whatever(myArg: $myVar) {bar(barArg: "barArgValue") @whatever(myArg: "secret3") }}' + + when: + def result = Anonymizer.anonymizeSchemaAndQueries(schema, [query]) + def newSchema = new SchemaPrinter(SchemaPrinter.Options.defaultOptions().includeDirectives(SchemaPrinter.ExcludeGraphQLSpecifiedDirectivesPredicate)).print(result.schema) + def newQuery = result.queries[0] + + then: + newSchema == """schema { + query: Object1 +} + +directive @Directive1(argument1: String = "stringValue1") on FIELD + +type Object1 { + field1: Object2 +} + +type Object2 { + field2(argument2: String): String +} +""" + newQuery == 'query ($var1:String="stringValue3"){field1 @Directive1(argument1:$var1){field2(argument2:"stringValue2") @Directive1(argument1:"stringValue1")}}' + + } +} diff --git a/src/test/groovy/graphql/util/CyclicSchemaAnalyzerTest.groovy b/src/test/groovy/graphql/util/CyclicSchemaAnalyzerTest.groovy new file mode 100644 index 0000000000..d24c2289c6 --- /dev/null +++ b/src/test/groovy/graphql/util/CyclicSchemaAnalyzerTest.groovy @@ -0,0 +1,311 @@ +package graphql.util + + +import graphql.TestUtil +import spock.lang.Specification + +class CyclicSchemaAnalyzerTest extends Specification { + + def "simple cycle"() { + given: + def sdl = ''' + + type Query { + hello: [Foo] + } + type Foo { + foo: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 1 + cycles[0].toString() == "[Foo.foo, Foo]" + + } + + def "simple cycle with interfaces"() { + given: + def sdl = ''' + + type Query { + hello: [Foo] + } + interface Foo { + foo: Foo + } + type Impl implements Foo { + foo: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 1 + cycles[0].toString() == "[Foo.foo, Foo]" + + } + + def "input field cycle"() { + given: + def sdl = ''' + type Query { + hello(i: I): String + } + input I { + foo: I + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 1 + cycles[0].toString() == "[I.foo, I]" + + } + + def "multiple cycles"() { + given: + def sdl = ''' + + type Query { + hello: [Foo] + } + type Foo { + bar: Bar + foo: Foo + } + type Bar { + bar: [Bar]! + foo: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 3 + cycles[0].toString() == "[Foo.bar, Bar, Bar.foo, Foo]" + cycles[1].toString() == "[Foo.foo, Foo]" + cycles[2].toString() == "[Bar.bar, Bar]" + + } + + def "larger cycle"() { + given: + def sdl = ''' + + type Query { + hello: [Foo] + } + type Foo { + bar: Bar + } + type Bar { + subBar: SubBar + } + type SubBar { + foo: Foo + } + + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 1 + cycles[0].toString() == "[Foo.bar, Bar, Bar.subBar, SubBar, SubBar.foo, Foo]" + + } + + def "two parents and no cycle"() { + given: + def sdl = ''' + + type Query { + hello: Foo1 + hello2: Foo2 + } + type Foo1 { + bar: Bar + } + type Foo2 { + bar: Bar + } + type Bar { + id: ID + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 0 + + } + + def "cycle test"() { + given: + def sdl = ''' + type Query { + foo: Foo + } + type Foo { + f1: Foo + f2: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 2 + cycles[0].toString() == "[Foo.f1, Foo]" + cycles[1].toString() == "[Foo.f2, Foo]" + + + } + + def "cycle test 2"() { + given: + def sdl = ''' + type Query { + foo: Foo + } + type Foo { + f1: Foo + f2: Bar + } + type Bar { + foo: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 2 + cycles[0].toString() == "[Foo.f1, Foo]" + cycles[1].toString() == "[Foo.f2, Bar, Bar.foo, Foo]" + + } + + def "cycle test 3"() { + given: + def sdl = ''' + type Query { + foo: Foo + } + type Foo { + issues: [IssueConnection] + } + type IssueConnection { + edges: [Edge] + nodes: [Issue] + } + type Edge { + node: Issue + } + type Issue { + foo: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + //TODO: should be 2 + cycles.size() == 2 + cycles[0].toString() == "[Foo.issues, IssueConnection, IssueConnection.nodes, Issue, Issue.foo, Foo]" + cycles[1].toString() == "[Foo.issues, IssueConnection, IssueConnection.edges, Edge, Edge.node, Issue, Issue.foo, Foo]" + + } + + def "cycle test 4"() { + given: + def sdl = ''' + type Query { + foo: Foo + } + type Foo { + issues: [IssueConnection] + } + type IssueConnection { + edges: [Edge] + nodes: [Foo] + } + type Edge { + node: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 2 + cycles[0].toString() == "[Foo.issues, IssueConnection, IssueConnection.nodes, Foo]" + cycles[1].toString() == "[Foo.issues, IssueConnection, IssueConnection.edges, Edge, Edge.node, Foo]" + + } + + def "cycle with Union"() { + given: + def sdl = ''' + type Query { + foo: Foo + } + union Foo = Bar | Baz + type Bar { + bar: Foo + } + type Baz { + bar: Foo + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema) + + then: + cycles.size() == 2 + cycles[0].toString() == "[Foo, Baz, Baz.bar]" + cycles[1].toString() == "[Foo, Bar, Bar.bar]" + + } + + def "introspection cycles "() { + given: + def sdl = ''' + type Query { + hello: String + } + ''' + def schema = TestUtil.schema(sdl) + when: + def cycles = CyclicSchemaAnalyzer.findCycles(schema, false) + + then: + cycles.size() == 6 + cycles[0].toString() == "[__Type.fields, __Field, __Field.type, __Type]" + cycles[1].toString() == "[__Type.fields, __Field, __Field.args, __InputValue, __InputValue.type, __Type]" + cycles[2].toString() == "[__Type.interfaces, __Type]" + cycles[3].toString() == "[__Type.possibleTypes, __Type]" + cycles[4].toString() == "[__Type.inputFields, __InputValue, __InputValue.type, __Type]" + cycles[5].toString() == "[__Type.ofType, __Type]" + + } +} diff --git a/src/test/groovy/graphql/util/EscapeUtilTest.groovy b/src/test/groovy/graphql/util/EscapeUtilTest.groovy new file mode 100644 index 0000000000..be41f2e0ed --- /dev/null +++ b/src/test/groovy/graphql/util/EscapeUtilTest.groovy @@ -0,0 +1,51 @@ +package graphql.util + + +import spock.lang.Specification + +class EscapeUtilTest extends Specification { + + def "1105 - encoding of json strings"() { + when: + def json = EscapeUtil.escapeJsonString(strValue) + + then: + json == expected + + where: + strValue | expected + '' | '' + 'json' | 'json' + 'quotation-"' | 'quotation-\\"' + 'reverse-solidus-\\' | 'reverse-solidus-\\\\' + 'backspace-\b' | 'backspace-\\b' + 'formfeed-\f' | 'formfeed-\\f' + 'newline-\n' | 'newline-\\n' + 'carriage-return-\r' | 'carriage-return-\\r' + 'horizontal-tab-\t' | 'horizontal-tab-\\t' + + // this is some AST from issue 1105 + '''"{"operator":"eq", "operands": []}"''' | '''\\"{\\"operator\\":\\"eq\\", \\"operands\\": []}\\"''' + } + + def "escapeJsonStringTo produces correct escaped output"() { + given: + def strValue = new StringBuilder() + + when: + EscapeUtil.escapeJsonStringTo(strValue, input) + + then: + strValue.toString() == expected + + where: + input | expected + '' | '' + 'plain' | 'plain' + 'quote-"and\\' | 'quote-\\"and\\\\' + 'tab\tnewline\n' | 'tab\\tnewline\\n' + 'combo-"\\\b\f\n\r\t' | 'combo-\\"\\\\\\b\\f\\n\\r\\t' + } + + +} diff --git a/src/test/groovy/graphql/util/FpKitTest.groovy b/src/test/groovy/graphql/util/FpKitTest.groovy index ddfcc05451..21dad8ef1f 100644 --- a/src/test/groovy/graphql/util/FpKitTest.groovy +++ b/src/test/groovy/graphql/util/FpKitTest.groovy @@ -1,12 +1,19 @@ package graphql.util +import com.google.common.collect.ImmutableList import spock.lang.Specification +import java.util.function.Supplier + class FpKitTest extends Specification { class IterableThing implements Iterable { Iterable delegate + IterableThing(Iterable delegate) { + this.delegate = delegate + } + @Override Iterator iterator() { return delegate.iterator() @@ -36,9 +43,196 @@ class FpKitTest extends Specification { actual == expected when: - IterableThing iterableThing = new IterableThing(delegate: ["a", "b", "c"]) + IterableThing iterableThing = new IterableThing(["a", "b", "c"]) actual = FpKit.toCollection(iterableThing) then: actual == expected } + + void "memoized supplier"() { + + def count = 0 + Supplier supplier = { -> count++; return count } + + when: + def memoizeSupplier = FpKit.intraThreadMemoize(supplier) + def val1 = supplier.get() + def val2 = supplier.get() + def memoVal1 = memoizeSupplier.get() + def memoVal2 = memoizeSupplier.get() + + then: + val1 == 1 + val2 == 2 + + memoVal1 == 3 + memoVal2 == 3 + } + + def "toListOrSingletonList works"() { + def birdArr = ["Parrot", "Cockatiel", "Pigeon"] as String[] + + when: + def l = FpKit.toListOrSingletonList(birdArr) + then: + l == ["Parrot", "Cockatiel", "Pigeon"] + + when: + l = FpKit.toListOrSingletonList(["Parrot", "Cockatiel", "Pigeon"]) + then: + l == ["Parrot", "Cockatiel", "Pigeon"] + + when: + l = FpKit.toListOrSingletonList(["Parrot", "Cockatiel", "Pigeon"].stream()) + then: + l == ["Parrot", "Cockatiel", "Pigeon"] + + when: + l = FpKit.toListOrSingletonList(["Parrot", "Cockatiel", "Pigeon"].stream().iterator()) + then: + l == ["Parrot", "Cockatiel", "Pigeon"] + + when: + l = FpKit.toListOrSingletonList("Parrot") + then: + l == ["Parrot"] + } + + class Person { + String name + String city + + Person(String name) { + this.name = name + } + + Person(String name, String city) { + this.name = name + this.city = city + } + + String getName() { + return name + } + + String getCity() { + return city + } + } + + def a = new Person("a", "New York") + def b = new Person("b", "New York") + def c1 = new Person("c", "Sydney") + def c2 = new Person("c", "London") + + def "getByName tests"() { + + when: + def map = FpKit.getByName([a, b, c1, c2], { it -> it.getName() }) + then: + map == ["a": a, "b": b, c: c1] + + when: + map = FpKit.getByName([a, b, c1, c2], { it -> it.getName() }, { it1, it2 -> it2 }) + then: + map == ["a": a, "b": b, c: c2] + } + + def "groupingBy tests"() { + + when: + Map> map = FpKit.groupingBy([a, b, c1, c2], { it -> it.getCity() }) + then: + map == ["New York": [a, b], "Sydney": [c1], "London": [c2]] + + when: + map = FpKit.filterAndGroupingBy([a, b, c1, c2], { it -> it != c1 }, { it -> it.getCity() }) + then: + map == ["New York": [a, b], "London": [c2]] + + } + + def "toMapByUniqueKey works"() { + + when: + Map map = FpKit.toMapByUniqueKey([a, b, c1], { it -> it.getName() }) + then: + map == ["a": a, "b": b, "c": c1] + + when: + FpKit.toMapByUniqueKey([a, b, c1, c2], { it -> it.getName() }) + then: + def e = thrown(IllegalStateException.class) + e.message.contains("Duplicate key") + } + + def "findOne test"() { + when: + def opt = FpKit.findOne([a, b, c1, c2], { it -> it.getName() == "c" }) + then: + opt.isPresent() + opt.get() == c1 + + when: + opt = FpKit.findOne([a, b, c1, c2], { it -> it.getName() == "d" }) + then: + opt.isEmpty() + + when: + opt = FpKit.findOne([a, b, c1, c2], { it -> it.getName() == "a" }) + then: + opt.isPresent() + opt.get() == a + } + + def "filterList works"() { + when: + def list = FpKit.filterList([a, b, c1, c2], { it -> it.getName() == "c" }) + then: + list == [c1, c2] + } + + def "set intersection works"() { + def set1 = ["A", "B", "C"] as Set + def set2 = ["A", "C", "D"] as Set + def singleSetA = ["A"] as Set + def disjointSet = ["X", "Y"] as Set + + when: + def intersection = FpKit.intersection(set1, set2) + then: + intersection == ["A", "C"] as Set + + when: // reversed parameters + intersection = FpKit.intersection(set2, set1) + then: + intersection == ["A", "C"] as Set + + when: // singles + intersection = FpKit.intersection(set1, singleSetA) + then: + intersection == ["A"] as Set + + when: // singles reversed + intersection = FpKit.intersection(singleSetA, set1) + then: + intersection == ["A"] as Set + + when: // disjoint + intersection = FpKit.intersection(set1, disjointSet) + then: + intersection.isEmpty() + + when: // disjoint reversed + intersection = FpKit.intersection(disjointSet, set1) + then: + intersection.isEmpty() + } + + def "test sized allocation"() { + when: + def newArrayList = FpKit.arrayListSizedTo(["a", "b", "c"]) + then: + newArrayList instanceof ArrayList + } } diff --git a/src/test/groovy/graphql/util/IdGeneratorTest.groovy b/src/test/groovy/graphql/util/IdGeneratorTest.groovy new file mode 100644 index 0000000000..99a9344012 --- /dev/null +++ b/src/test/groovy/graphql/util/IdGeneratorTest.groovy @@ -0,0 +1,17 @@ +package graphql.util + +import spock.lang.Specification + +class IdGeneratorTest extends Specification { + def "can generate uuids"() { + when: + def set = new HashSet() + for (int i = 0; i < 1000; i++) { + set.add(IdGenerator.uuid().toString()); + } + + then: + // should this fail - the universe has ended and has retracted back into the singularity + set.size() == 1000 + } +} diff --git a/src/test/groovy/graphql/util/LockKitTest.groovy b/src/test/groovy/graphql/util/LockKitTest.groovy new file mode 100644 index 0000000000..e205ff0574 --- /dev/null +++ b/src/test/groovy/graphql/util/LockKitTest.groovy @@ -0,0 +1,70 @@ +package graphql.util + +import spock.lang.Specification + +class LockKitTest extends Specification { + + + def "can run code under a lock (simple test)"() { + def sideEffect = 0 + + when: + LockKit.ReentrantLock lockedCode = new LockKit.ReentrantLock() + lockedCode.runLocked { sideEffect++ } + + then: + sideEffect == 1 + } + + def "can call code under a lock (simple test)"() { + + when: + LockKit.ReentrantLock lockedCode = new LockKit.ReentrantLock() + def val = lockedCode.callLocked { return "x" } + + then: + val == "x" + } + + def "is reentrant"() { + + def sideEffect = 0 + + when: + LockKit.ReentrantLock lockedCode = new LockKit.ReentrantLock() + lockedCode.runLocked { + sideEffect++ + lockedCode.runLocked { + sideEffect++ + } + } + + then: + sideEffect == 2 + } + + def "can compute once"() { + def sideEffect = 0 + + when: + LockKit.ComputedOnce computedOnce = new LockKit.ComputedOnce() + + then: + !computedOnce.hasBeenComputed() + sideEffect == 0 + + when: + computedOnce.runOnce { sideEffect++ } + + then: + computedOnce.hasBeenComputed() + sideEffect == 1 + + when: + computedOnce.runOnce { sideEffect++ } + + then: + computedOnce.hasBeenComputed() + sideEffect == 1 + } +} diff --git a/src/test/groovy/graphql/util/PairTest.groovy b/src/test/groovy/graphql/util/PairTest.groovy new file mode 100644 index 0000000000..f64f9127a4 --- /dev/null +++ b/src/test/groovy/graphql/util/PairTest.groovy @@ -0,0 +1,31 @@ +package graphql.util + +import spock.lang.Specification + +class PairTest extends Specification { + def "constructor initializes fields correctly"() { + when: + def pair = new Pair<>("hello", 123) + + then: + pair.first == "hello" + pair.second == 123 + } + + def "static pair method creates Pair instance"() { + when: + def pair = Pair.pair("foo", "bar") + + then: + pair instanceof Pair + pair.first == "foo" + pair.second == "bar" + } + + def "toString returns formatted string"() { + expect: + new Pair<>(1, 2).toString() == "(1, 2)" + Pair.pair("a", "b").toString() == "(a, b)" + new Pair<>(null, null).toString() == "(null, null)" + } +} diff --git a/src/test/groovy/graphql/util/StringKitTest.groovy b/src/test/groovy/graphql/util/StringKitTest.groovy new file mode 100644 index 0000000000..a2a428bce6 --- /dev/null +++ b/src/test/groovy/graphql/util/StringKitTest.groovy @@ -0,0 +1,22 @@ +package graphql.util + +import spock.lang.Specification + +class StringKitTest extends Specification { + + + def "can capitalise"() { + expect: + + def actual = StringKit.capitalize(input) + actual == expected + + where: + input | expected + null | null + "" | "" + "a" | "A" + "abc" | "Abc" + + } +} diff --git a/src/test/groovy/graphql/util/TraverserTest.groovy b/src/test/groovy/graphql/util/TraverserTest.groovy index a1705d4d70..84abb4edb1 100644 --- a/src/test/groovy/graphql/util/TraverserTest.groovy +++ b/src/test/groovy/graphql/util/TraverserTest.groovy @@ -21,6 +21,7 @@ class TraverserTest extends Specification { ] ] + def "test depth-first traversal"() { given: def preOrderNodes = [] @@ -34,7 +35,7 @@ class TraverserTest extends Specification { leave: { TraverserContext context -> postOrderNodes << context.thisNode().number println "leave:$postOrderNodes" - context.setResult(context.thisNode()) + context.setAccumulate(context.thisNode()) TraversalControl.CONTINUE } ] as TraverserVisitor @@ -43,7 +44,7 @@ class TraverserTest extends Specification { then: - result.result.number == 0 + result.accumulatedResult.number == 0 preOrderNodes == [0, 1, 3, 2, 4, 5] postOrderNodes == [3, 1, 4, 5, 2, 0] } @@ -56,7 +57,7 @@ class TraverserTest extends Specification { def visitor = [ enter: { TraverserContext context -> enterData << context.thisNode().number - context.setResult(context.thisNode()) + context.setAccumulate(context.thisNode()) println "enter:$enterData" TraversalControl.CONTINUE }, @@ -70,7 +71,7 @@ class TraverserTest extends Specification { def result = Traverser.breadthFirst({ n -> n.children }).traverse(root, visitor) then: - result.result.number == 5 + result.accumulatedResult.number == 5 enterData == [0, 1, 2, 3, 4, 5] leaveData == [0, 1, 2, 3, 4, 5] } @@ -109,11 +110,11 @@ class TraverserTest extends Specification { def leaveCount = 0 def visitor = [ enter: { TraverserContext context -> - context.getInitialData().add(context.thisNode().number) + context.getSharedContextData().add(context.thisNode().number) TraversalControl.CONTINUE }, leave: { TraverserContext context -> - context.setResult(leaveResult) + context.setAccumulate(leaveResult) leaveCount++ TraversalControl.QUIT }, @@ -124,7 +125,7 @@ class TraverserTest extends Specification { def result = Traverser.depthFirst({ n -> n.children }, initialData).traverse(root, visitor) then: - result.result == leaveResult + result.accumulatedResult == leaveResult initialData == [0, 1, 3] leaveCount == 1 } @@ -135,7 +136,7 @@ class TraverserTest extends Specification { def visitor = [ enter: { TraverserContext context -> - context.getInitialData().add(context.thisNode().number) + context.getSharedContextData().add(context.thisNode().number) if ([1, 2].contains(context.thisNode().number)) return TraversalControl.ABORT TraversalControl.CONTINUE }, @@ -159,7 +160,7 @@ class TraverserTest extends Specification { def visitor = [ enter: { TraverserContext context -> - context.getInitialData().add(context.thisNode().number) + context.getSharedContextData().add(context.thisNode().number) if ([2].contains(context.thisNode().number)) return TraversalControl.ABORT TraversalControl.CONTINUE }, @@ -264,7 +265,29 @@ class TraverserTest extends Specification { } ] as TraverserVisitor when: - def result = Traverser.breadthFirst({ n -> n.children },) + def result = Traverser.breadthFirst({ n -> n.children }) + .rootVars([(Object.class): "var1", (String.class): "var2"]) + .traverse(root, visitor) + + + then: + true + } + + def "test context variables from parents"() { + given: + def visitor = [ + enter: { TraverserContext context -> + assert context.getVarFromParents(Object.class) == "var1" + assert context.getVarFromParents(String.class) == "var2" + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + Traverser.breadthFirst({ n -> n.children }) .rootVars([(Object.class): "var1", (String.class): "var2"]) .traverse(root, visitor) @@ -273,15 +296,15 @@ class TraverserTest extends Specification { true } - def "test parent result chain"() { + + def "test accumulator"() { given: def visitor = [ enter: { TraverserContext context -> - List visited = context.getParentResult() - visited = visited == null ? new ArrayList<>() : visited + List visited = context.getCurrentAccumulate() + visited = visited == null ? new ArrayList<>() : new ArrayList<>(visited) visited.add(context.thisNode().number) - context.setVar(List.class, visited) - context.setResult(visited) + context.setAccumulate(visited) TraversalControl.CONTINUE }, leave: { TraverserContext context -> @@ -289,22 +312,42 @@ class TraverserTest extends Specification { } ] as TraverserVisitor when: - def result = Traverser.breadthFirst({ n -> n.children },) + def result = Traverser.breadthFirst({ n -> n.children }) .traverse(root, visitor) then: - result.result == [0, 1, 2, 3, 4, 5] + result.accumulatedResult == [0, 1, 2, 3, 4, 5] } - def "test initial data"() { + def "test accumulate with initial value unchanged"() { + given: def visitor = [ enter: { TraverserContext context -> - assert context.getInitialData() == "foo" TraversalControl.CONTINUE }, leave: { TraverserContext context -> - assert context.getInitialData() == "foo" + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def result = Traverser.breadthFirst({ n -> n.children }, null, "acc-result") + .traverse(root, visitor) + + + then: + result.accumulatedResult == "acc-result" + + } + + def "test shared data"() { + def visitor = [ + enter: { TraverserContext context -> + assert context.getSharedContextData() == "foo" + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + assert context.getSharedContextData() == "foo" TraversalControl.QUIT }, @@ -327,10 +370,297 @@ class TraverserTest extends Specification { TraverserResult result = Traverser.depthFirst({ n -> n.children }).traverse(roots, visitor) then: - result.getResult() == null + result.getAccumulatedResult() == null } + def "test node position"() { + given: + def visitor = [ + enter: { TraverserContext context -> + def curAcc = context.getCurrentAccumulate() + if (context.getLocation() != null) { + curAcc.add(context.getLocation().index) + } + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def result = Traverser.depthFirst({ n -> n.children }, null, []) + .traverse(root, visitor) + + + then: + result.accumulatedResult == [0, 0, 1, 0, 1] + } + + def treeWithNamedChildren() { + def leaf1 = [number: 3, children: [:]] + def leaf2 = [number: 4, children: [:]] + def leaf3 = [number: 5, children: [:]] + def leaf4 = [number: 6, children: [:]] + + def node1 = [number: 1, children: [a: [leaf1], b: [leaf2]]] + def node2 = [number: 2, children: [c: [leaf3], d: [leaf4]]] + + [number: 0, children: [x: [node1], y: [node2]]] + } + + def "breadth first with named children"() { + def root = treeWithNamedChildren() + given: + def visitor = [ + enter: { TraverserContext context -> + def curAcc = context.getCurrentAccumulate() + if (context.getLocation() != null) { + curAcc.add(context.getLocation()) + } + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def result = Traverser.breadthFirstWithNamedChildren({ n -> n.children }, null, []) + .traverse(root, visitor) + + + then: + result.accumulatedResult == [new NodeLocation("x", 0), + new NodeLocation("y", 0), + new NodeLocation("a", 0), + new NodeLocation("b", 0), + new NodeLocation("c", 0), + new NodeLocation("d", 0), + ] + } + + def "depth first with named children"() { + def root = treeWithNamedChildren() + given: + def visitor = [ + enter: { TraverserContext context -> + def curAcc = context.getCurrentAccumulate() + if (context.getLocation() != null) { + curAcc.add(context.getLocation()) + } + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def result = Traverser.depthFirstWithNamedChildren({ n -> n.children }, null, []) + .traverse(root, visitor) + + + then: + result.accumulatedResult == [new NodeLocation("y", 0), + new NodeLocation("d", 0), + new NodeLocation("c", 0), + new NodeLocation("x", 0), + new NodeLocation("b", 0), + new NodeLocation("a", 0), + ] + } + + def "test parent nodes"() { + given: + def visitor = [ + enter: { TraverserContext context -> + context.getSharedContextData() << context.getParentNodes().collect { it.number } + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + TraversalControl.CONTINUE + } + ] as TraverserVisitor + def list = [] + when: + Traverser.depthFirst({ n -> n.children }, list).traverse(root, visitor) + + + then: + list == [[], [0], [1, 0], [0], [2, 0], [2, 0]] + + } + + + def "changing the node while traversing"() { + given: + def visitedNodes = [] + def visitedNodesLeave = [] + def root = [ + number: 0 + ] + def visitor = [ + enter: { TraverserContext context -> + visitedNodes << context.thisNode().number + if (context.thisNode().number > 0) return TraversalControl.CONTINUE + def newRoot = [ + number : 0, + children: [ + [number: 1, children: []], + [number: 2, children: []] + ] + ] + context.changeNode(newRoot) + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + visitedNodesLeave << context.thisNode().number + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + Traverser.depthFirst({ n -> n.children }).traverse(root, visitor) + + + then: + visitedNodes == [0, 1, 2] + visitedNodesLeave == [1, 2, 0] + + + } + + def "depth-first traversal children contexts are available"() { + given: + def childContextVars = [] + def visitor = [ + enter: { TraverserContext context -> + context.setVar(Object.class, context.thisNode().number) + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + def childNumbers = context.getChildrenContexts().get(null).collect { it.getVar(Object.class) } + childContextVars << childNumbers + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + Traverser.depthFirst({ n -> n.children }).traverse(root, visitor) + + + then: + childContextVars == [[], [3], [], [], [4, 5], [1, 2]] + } + + def "breadth-first traversal children contexts are available"() { + given: + def childContextVars = [] + def visitor = [ + enter: { TraverserContext context -> + context.setVar(Object.class, context.thisNode().number) + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + def childNumbers = context.getChildrenContexts().get(null).collect { it.getVar(Object.class) } + childContextVars << childNumbers + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + Traverser.breadthFirst({ n -> n.children }).traverse(root, visitor) + + + then: + childContextVars == [[1, 2], [3], [4, 5], [], [], []] + } + + def "delete node depth-first"() { + given: + def preOrderNodes = [] + def postOrderNodes = [] + def visitor = [ + enter: { TraverserContext context -> + preOrderNodes << context.thisNode().number + if (context.thisNode().number == 2) { + context.deleteNode() + } + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + postOrderNodes << context.originalThisNode().number + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def result = Traverser.depthFirst({ n -> n.children }).traverse(root, visitor) + + + then: + preOrderNodes == [0, 1, 3, 2] + postOrderNodes == [3, 1, 2, 0] + } + + def "delete nodes breadth-first"() { + given: + def enterData = [] + def leaveData = [] + def visitor = [ + enter: { TraverserContext context -> + enterData << context.thisNode().number + if (context.thisNode().number == 2) { + context.deleteNode() + } + TraversalControl.CONTINUE + }, + leave: { TraverserContext context -> + leaveData << context.originalThisNode().number + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def result = Traverser.breadthFirst({ n -> n.children }).traverse(root, visitor) + + then: + enterData == [0, 1, 2, 3] + leaveData == [0, 1, 2, 3] + } + + def "phase is provided for enter and leave"() { + given: + def visitor = [ + enter : { TraverserContext context -> + assert context.phase == TraverserContext.Phase.ENTER + TraversalControl.CONTINUE + }, + leave : { TraverserContext context -> + assert context.phase == TraverserContext.Phase.LEAVE + TraversalControl.CONTINUE + }, + backRef: { TraverserContext context -> + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + Traverser.depthFirst({ n -> n.children }).traverse(root, visitor) + + + then: + noExceptionThrown() + } + + def "phase is provided for backRef"() { + given: + def cycleRoot = new Node(number: 0) + cycleRoot.children.add(cycleRoot) + + + def visitor = Mock(TraverserVisitor) + when: + Traverser.depthFirst({ n -> n.children }).traverse(cycleRoot, visitor) + + then: + 1 * visitor.enter(_) >> TraversalControl.CONTINUE + 1 * visitor.leave(_) >> TraversalControl.CONTINUE + 1 * visitor.backRef({ TraverserContext context -> context.getPhase() == TraverserContext.Phase.BACKREF }) >> TraversalControl.CONTINUE + } } diff --git a/src/test/groovy/graphql/util/TreeParallelTransformerTest.groovy b/src/test/groovy/graphql/util/TreeParallelTransformerTest.groovy new file mode 100644 index 0000000000..d9f3eb5aa1 --- /dev/null +++ b/src/test/groovy/graphql/util/TreeParallelTransformerTest.groovy @@ -0,0 +1,63 @@ +package graphql.util + +import graphql.TestUtil +import graphql.language.Field +import graphql.language.Node +import spock.lang.Specification + +import static graphql.language.AstNodeAdapter.AST_NODE_ADAPTER +import static graphql.language.AstPrinter.printAstCompact +import static graphql.util.TreeTransformerUtil.changeNode + +class TreeParallelTransformerTest extends Specification { + + def "one node changed"() { + def document = TestUtil.parseQuery("{foo}") + + TreeParallelTransformer parallelTransformer = TreeParallelTransformer.parallelTransformer(AST_NODE_ADAPTER) + def visitor = new TraverserVisitorStub() { + + @Override + TraversalControl enter(TraverserContext context) { + Node node = context.thisNode() + if (!(node instanceof Field)) return TraversalControl.CONTINUE; + Field changedField = node.transform({ builder -> builder.name("foo2") }) + return changeNode(context, changedField) + } + } + + + when: + def newDocument = parallelTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2}" + + } + + def "abort traversing"() { + def document = TestUtil.parseQuery("{foo}") + + TreeParallelTransformer parallelTransformer = TreeParallelTransformer.parallelTransformer(AST_NODE_ADAPTER) + def visitor = new TraverserVisitorStub() { + + @Override + TraversalControl enter(TraverserContext context) { + Node node = context.thisNode() + if (!(node instanceof Field)) return TraversalControl.CONTINUE; + Field changedField = node.transform({ builder -> builder.name("foo2") }) + changeNode(context, changedField) + return TraversalControl.ABORT + } + } + + + when: + def newDocument = parallelTransformer.transform(document, visitor) + + then: + printAstCompact(newDocument) == "{foo2}" + + } +} + diff --git a/src/test/groovy/graphql/util/TreeParallelTraverserTest.groovy b/src/test/groovy/graphql/util/TreeParallelTraverserTest.groovy new file mode 100644 index 0000000000..d7621f20be --- /dev/null +++ b/src/test/groovy/graphql/util/TreeParallelTraverserTest.groovy @@ -0,0 +1,81 @@ +package graphql.util + +import spock.lang.Ignore +import spock.lang.Specification + +import java.util.concurrent.ConcurrentLinkedQueue +import java.util.concurrent.CountDownLatch +import java.util.concurrent.ForkJoinPool +import java.util.concurrent.TimeUnit + +class TreeParallelTraverserTest extends Specification { + /** + * 0 + * 1 2 + * 3 4 5 + */ + def root = [ + [number: 0, children: [ + [number: 1, children: [ + [number: 3, children: []] + ]], + [number: 2, children: [ + [number: 4, children: []], + [number: 5, children: []] + ]]] + ] + ] + + + // fails on travis ci because only one thread is used for an unknown reason + @Ignore + def "test parallel traversing"() { + given: + Queue nodes = new ConcurrentLinkedQueue() + CountDownLatch latch = new CountDownLatch(4) + def visitor = [ + enter: { TraverserContext context -> + def number = context.thisNode().number + println "number: $number in ${Thread.currentThread()}" + if (number == 1) { + println "wating in ${Thread.currentThread()}" + assert latch.await(30, TimeUnit.SECONDS) + } + nodes.add(number) + latch.countDown() + println "added new node: $nodes with size: ${nodes.size()} and latch: ${latch.getCount()} in ${Thread.currentThread()}" + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def pool = new ForkJoinPool(4) + println "parellism: ${pool.getParallelism()}" + println "processors: ${Runtime.getRuntime().availableProcessors()}" + TreeParallelTraverser.parallelTraverser({ n -> n.children }, pool).traverse(root, visitor) + + + then: + new ArrayList(nodes) == [0, 2, 4, 5, 1, 3] + true + } + + def "test traversing"() { + given: + Queue nodes = new ConcurrentLinkedQueue() + def visitor = [ + enter: { TraverserContext context -> + def number = context.thisNode().number + nodes.add(number) + TraversalControl.CONTINUE + } + ] as TraverserVisitor + when: + def pool = new ForkJoinPool(4) + TreeParallelTraverser.parallelTraverser({ n -> n.children }, pool).traverse(root, visitor) + + then: + new ArrayList(nodes).containsAll([0, 2, 4, 5, 1, 3]) + true + } + +} diff --git a/src/test/groovy/graphql/util/TreeTransformerUtilTest.groovy b/src/test/groovy/graphql/util/TreeTransformerUtilTest.groovy new file mode 100644 index 0000000000..c46cdf08b5 --- /dev/null +++ b/src/test/groovy/graphql/util/TreeTransformerUtilTest.groovy @@ -0,0 +1,72 @@ +package graphql.util + +import spock.lang.Specification + +class TreeTransformerUtilTest extends Specification { + + def "changeNode in parallel mode with already changed node"() { + given: + def context = Mock(TraverserContext) + def zippers = [] + def adapter = Mock(NodeAdapter) + def originalNode = "original" + def newNode = "changed" + + def mockZipper = Mock(NodeZipper) + mockZipper.getCurNode() >> originalNode + zippers << mockZipper + + context.isParallel() >> true + context.isChanged() >> true + context.thisNode() >> originalNode + context.getVar(List) >> zippers + context.getVar(NodeAdapter) >> adapter + + when: + def result = TreeTransformerUtil.changeNode(context, newNode) + + then: + 1 * context.changeNode(newNode) + result == TraversalControl.CONTINUE + } + + def "deleteNode in sequential mode adds delete zipper to shared context"() { + given: + def context = Mock(TraverserContext) + def nodeZipper = Mock(NodeZipper) + def zipperQueue = Mock(Queue) + + context.isParallel() >> false + context.getVar(NodeZipper) >> nodeZipper + context.getSharedContextData() >> zipperQueue + nodeZipper.deleteNode() >> nodeZipper + + when: + def result = TreeTransformerUtil.deleteNode(context) + + then: + 1 * context.deleteNode() + 1 * zipperQueue.add(nodeZipper) + result == TraversalControl.CONTINUE + } + + def "insertBefore in sequential mode adds zipper to queue"() { + given: + def context = Mock(TraverserContext) + def zipper = Mock(NodeZipper) + def zipperQueue = Mock(Queue) + def toInsert = "insert-me" + + context.isParallel() >> false + context.getVar(NodeZipper) >> zipper + zipper.insertBefore(toInsert) >> zipper + context.getSharedContextData() >> zipperQueue + + when: + def result = TreeTransformerUtil.insertBefore(context, toInsert) + + then: + 1 * zipperQueue.add(zipper) + result == TraversalControl.CONTINUE + } +} diff --git a/src/test/groovy/graphql/util/javac/DynamicJavacSupport.java b/src/test/groovy/graphql/util/javac/DynamicJavacSupport.java new file mode 100644 index 0000000000..6655bcd599 --- /dev/null +++ b/src/test/groovy/graphql/util/javac/DynamicJavacSupport.java @@ -0,0 +1,157 @@ +package graphql.util.javac; + +import javax.tools.DiagnosticCollector; +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static java.util.Objects.requireNonNull; + + +/** + * This utility allows is to dynamically create Java classes and place them into + * floating class loaders. This will allow us to test class loader challenges + *

    + * Proprs to https://www.baeldung.com/java-string-compile-execute-code where + * most of this code came from. + */ +public class DynamicJavacSupport { + + private final JavaCompiler compiler; + private final InMemoryFileManager manager; + + public DynamicJavacSupport(ClassLoader parentClassLoader) { + compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null); + manager = new InMemoryFileManager(parentClassLoader, standardFileManager); + } + + + public Class compile(String qualifiedClassName, String sourceCode) throws ClassNotFoundException { + + List sourceFiles = Collections.singletonList(new JavaSourceFromString(qualifiedClassName, sourceCode)); + + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + JavaCompiler.CompilationTask task = compiler.getTask(null, manager, diagnostics, null, null, sourceFiles); + + boolean result = task.call(); + + if (!result) { + diagnostics.getDiagnostics() + .forEach(d -> System.out.printf("dyna-javac : %s\n", d)); + throw new IllegalStateException("Could not compile " + qualifiedClassName + " as a class"); + } else { + ClassLoader classLoader = manager.getClassLoader(null); + Class clazz = classLoader.loadClass(qualifiedClassName); + return (Class) clazz; + } + } + + static class InMemoryFileManager extends ForwardingJavaFileManager { + private final InMemoryClassLoader loader; + private final Map compiledClasses; + + InMemoryFileManager(ClassLoader parentClassLoader, StandardJavaFileManager standardManager) { + super(standardManager); + this.compiledClasses = new ConcurrentHashMap<>(); + this.loader = new InMemoryClassLoader(parentClassLoader, this); + } + + @Override + public JavaFileObject getJavaFileForOutput(Location location, + String className, JavaFileObject.Kind kind, FileObject sibling) { + + JavaClassAsBytes classAsBytes = new JavaClassAsBytes(className, kind); + compiledClasses.put(className, classAsBytes); + + return classAsBytes; + } + + public Map getBytesMap() { + return compiledClasses; + } + + @Override + public ClassLoader getClassLoader(Location location) { + return loader; + } + } + + static class InMemoryClassLoader extends ClassLoader { + + private InMemoryFileManager manager; + + InMemoryClassLoader(ClassLoader parentClassLoader, InMemoryFileManager manager) { + super(parentClassLoader); + this.manager = requireNonNull(manager, "manager must not be null"); + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + + Map compiledClasses = manager.getBytesMap(); + + if (compiledClasses.containsKey(name)) { + byte[] bytes = compiledClasses.get(name).getBytes(); + return defineClass(name, bytes, 0, bytes.length); + } else { + throw new ClassNotFoundException(); + } + } + + } + + static class JavaSourceFromString extends SimpleJavaFileObject { + + + private String sourceCode; + + JavaSourceFromString(String name, String sourceCode) { + super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), + Kind.SOURCE); + this.sourceCode = requireNonNull(sourceCode, "sourceCode must not be null"); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return sourceCode; + } + + } + + static class JavaClassAsBytes extends SimpleJavaFileObject { + + + protected ByteArrayOutputStream bos = + new ByteArrayOutputStream(); + + JavaClassAsBytes(String name, Kind kind) { + super(URI.create("string:///" + name.replace('.', '/') + + kind.extension), kind); + } + + public byte[] getBytes() { + return bos.toByteArray(); + } + + @Override + public OutputStream openOutputStream() { + return bos; + } + + } + + +} diff --git a/src/test/groovy/graphql/util/javac/DynamicJavacSupportTest.groovy b/src/test/groovy/graphql/util/javac/DynamicJavacSupportTest.groovy new file mode 100644 index 0000000000..a07c4cbbd2 --- /dev/null +++ b/src/test/groovy/graphql/util/javac/DynamicJavacSupportTest.groovy @@ -0,0 +1,57 @@ +package graphql.util.javac + +import spock.lang.Specification + +class DynamicJavacSupportTest extends Specification { + + String sourceCode = ''' + package com.dynamic; + public class TestClass { + public String hello() { + return "world"; + } + } + ''' + + def "can compile things without a parent class loader"() { + + def javacSupport = new DynamicJavacSupport(null) + + when: + def compiledClass = javacSupport.compile("com.dynamic.TestClass", sourceCode) + def instance = compiledClass.getDeclaredConstructor().newInstance() + def runCodeMethod = compiledClass.getMethod("hello") + def value = runCodeMethod.invoke(instance) + + then: + value == "world" + + // with a null parent class loader, this class loader should not be able to see this code + when: + compiledClass.getClassLoader().loadClass(this.getClass().getCanonicalName()) + then: + thrown(ClassNotFoundException) + } + + + def "can compile things with a parent class loader"() { + + def javacSupport = new DynamicJavacSupport(this.getClass().getClassLoader()) + + when: + def compiledClass = javacSupport.compile("com.dynamic.TestClass", sourceCode) + def instance = compiledClass.getDeclaredConstructor().newInstance() + def runCodeMethod = compiledClass.getMethod("hello") + def value = runCodeMethod.invoke(instance) + + then: + noExceptionThrown() + value == "world" + + // with a parent class loader, this class loader should be able to see this code + when: + def backToUs = compiledClass.getClassLoader().loadClass(this.getClass().getCanonicalName()) + then: + backToUs === this.getClass() + } +} diff --git a/src/test/groovy/graphql/util/querygenerator/QueryGeneratorOptionsTest.groovy b/src/test/groovy/graphql/util/querygenerator/QueryGeneratorOptionsTest.groovy new file mode 100644 index 0000000000..78a0f4fe11 --- /dev/null +++ b/src/test/groovy/graphql/util/querygenerator/QueryGeneratorOptionsTest.groovy @@ -0,0 +1,80 @@ +package graphql.util.querygenerator + +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLFieldsContainer +import spock.lang.Specification + +import java.util.function.Predicate + +class QueryGeneratorOptionsTest extends Specification { + + def "default builder sets maxFieldCount to 10_000 and always-true predicates"() { + when: + def options = QueryGeneratorOptions.newBuilder().build() + + then: + options.maxFieldCount == 10_000 + options.filterFieldContainerPredicate.test(Mock(GraphQLFieldsContainer)) + options.filterFieldDefinitionPredicate.test(Mock(GraphQLFieldDefinition)) + } + + def "builder sets maxFieldCount to custom value within range"() { + when: + def options = QueryGeneratorOptions.newBuilder() + .maxFieldCount(500) + .build() + + then: + options.maxFieldCount == 500 + } + + def "builder throws exception if maxFieldCount is negative"() { + when: + QueryGeneratorOptions.newBuilder().maxFieldCount(-1) + + then: + def e = thrown(IllegalArgumentException) + e.message == "Max field count cannot be negative" + } + + def "builder throws exception if maxFieldCount exceeds MAX_FIELD_COUNT_LIMIT"() { + when: + QueryGeneratorOptions.newBuilder().maxFieldCount(10_001) + + then: + def e = thrown(IllegalArgumentException) + e.message == "Max field count cannot exceed 10000" + } + + def "builder uses custom field container predicate"() { + given: + def customPredicate = Mock(Predicate) + customPredicate.test(_) >> false + + when: + def options = QueryGeneratorOptions.newBuilder() + .filterFieldContainerPredicate(customPredicate) + .build() + + then: + !options.filterFieldContainerPredicate.test(Mock(GraphQLFieldsContainer)) + } + + def "builder uses custom field definition predicate"() { + given: + def customPredicate = { GraphQLFieldDefinition defn -> defn.name == "includeMe" } as Predicate + + and: + def included = Mock(GraphQLFieldDefinition) { getName() >> "includeMe" } + def excluded = Mock(GraphQLFieldDefinition) { getName() >> "skipMe" } + + when: + def options = QueryGeneratorOptions.newBuilder() + .filterFieldDefinitionPredicate(customPredicate) + .build() + + then: + options.filterFieldDefinitionPredicate.test(included) + !options.filterFieldDefinitionPredicate.test(excluded) + } +} diff --git a/src/test/groovy/graphql/util/querygenerator/QueryGeneratorTest.groovy b/src/test/groovy/graphql/util/querygenerator/QueryGeneratorTest.groovy new file mode 100644 index 0000000000..877dc11d73 --- /dev/null +++ b/src/test/groovy/graphql/util/querygenerator/QueryGeneratorTest.groovy @@ -0,0 +1,1128 @@ +package graphql.util.querygenerator + + +import graphql.TestUtil +import graphql.parser.Parser +import graphql.schema.GraphQLSchema +import graphql.validation.Validator +import spock.lang.Specification + + +class QueryGeneratorTest extends Specification { + def "generate query for simple type"() { + given: + def schema = """ + type Query { + bar(filter: String): Bar + } + + type Bar { + id: ID! + name: String + type: TypeEnum + foos: [String!]! + } + + enum TypeEnum { + FOO + BAR + } +""" + + def fieldPath = "Query.bar" + when: + def expectedNoOperation = """ +{ + bar { + ... on Bar { + id + name + type + foos + } + } +}""" + + def result = executeTest(schema, fieldPath, expectedNoOperation) + + then: + result != null + "Bar" == result.usedType + 4 == result.totalFieldCount + !result.reachedMaxFieldCount + + when: "operation and arguments are passed" + def expectedWithOperation = """ +query barTestOperation { + bar(filter: "some filter") { + ... on Bar { + id + name + type + foos + } + } +} +""" + + result = executeTest( + schema, + fieldPath, + "barTestOperation", + "(filter: \"some filter\")", + null, + expectedWithOperation, + QueryGeneratorOptions.newBuilder().build() + ) + + then: + result != null + } + + + def "generate query field of list type"() { + given: + def schema = """ + type Query { + allBars: [Bar] + } + + type Bar { + id: ID! + name: String + } +""" + + def fieldPath = "Query.allBars" + when: + def expectedNoOperation = """ +{ + allBars { + ... on Bar { + id + name + } + } +}""" + + def result = executeTest(schema, fieldPath, expectedNoOperation) + + then: + result != null + } + + def "generate query field of non-nullable type"() { + given: + def schema = """ + type Query { + bar: Bar + } + + type Bar { + id: ID! + name: String + } +""" + + def fieldPath = "Query.bar" + when: + def expectedNoOperation = """ +{ + bar { + ... on Bar { + id + name + } + } +}""" + + def result = executeTest(schema, fieldPath, expectedNoOperation) + + then: + result != null + } + + def "generate query for type with nested type"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + bar: Bar + bars: [Bar] + } + + type Bar { + id: ID! + name: String + } +""" + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + bar { + id + name + } + bars { + id + name + } + } + } +} +""" + + when: + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "generate query for deeply nested field"() { + given: + def schema = """ + type Query { + bar: Bar + } + + type Bar { + id: ID! + foo: Foo + } + + type Foo { + id: ID! + baz: Baz + } + + type Baz { + id: ID! + name: String + } + +""" + + def fieldPath = "Query.bar.foo.baz" + when: + def expectedNoOperation = """ +{ + bar { + foo { + baz { + ... on Baz { + id + name + } + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, expectedNoOperation) + + then: + result != null + } + + def "straight forward cyclic dependency"() { + given: + def schema = """ + type Query { + fooFoo: FooFoo + } + + type FooFoo { + id: ID! + name: String + fooFoo: FooFoo + } +""" + def fieldPath = "Query.fooFoo" + def expected = """ +{ + fooFoo { + ... on FooFoo { + id + name + fooFoo { + id + name + } + } + } +} +""" + + when: + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "cyclic dependency with 2 fields of the same type"() { + given: + def schema = """ + type Query { + fooFoo: FooFoo + } + + type FooFoo { + id: ID! + name: String + fooFoo: FooFoo + fooFoo2: FooFoo + } +""" + def fieldPath = "Query.fooFoo" + def expected = """ +{ + fooFoo { + ... on FooFoo { + id + name + fooFoo { + id + name + } + fooFoo2 { + id + name + } + } + } +} +""" + + when: + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "transitive cyclic dependency"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + name: String + bar: Bar + } + + type Bar { + id: ID! + name: String + baz: Baz + } + + type Baz { + id: ID! + name: String + foo: Foo + } + +""" + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + name + bar { + id + name + baz { + id + name + foo { + id + name + } + } + } + } + } +} +""" + + when: + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "generate mutation and subscription for simple type"() { + given: + def schema = """ + type Query { + echo: String + } + + type Mutation { + bar: Bar + } + + type Subscription { + bar: Bar + } + + type Bar { + id: ID! + name: String + } +""" + + + when: "generate query for mutation" + def fieldPath = "Mutation.bar" + def expected = """ +mutation { + bar { + ... on Bar { + id + name + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + + when: "operation and arguments are passed" + + fieldPath = "Subscription.bar" + expected = """ +subscription { + bar { + ... on Bar { + id + name + } + } +} +""" + + result = executeTest( + schema, + fieldPath, + expected + ) + + then: + result != null + } + + def "generate query containing fields with arguments"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + optionalArg(filter: String): String + mandatoryArg(id: ID!): String + mixed(id: ID!, filter: String): String + defaultArg(filter: String! = "default"): String + multipleOptionalArgs(filter: String, filter2: String, filter3: String = "default"): String + } +""" + + + when: + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + optionalArg + defaultArg + multipleOptionalArgs + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "generate query for the 'node' field, which returns an interface"() { + given: + def schema = """ + type Query { + node(id: ID!): Node + foo: Foo + } + + interface Node { + id: ID! + } + + type Foo implements Node { + id: ID! + fooName: String + } + + type Bar implements Node { + id: ID! + barName: String + } + + type BazDoesntImplementNode { + id: ID! + bazName: String + } +""" + + + when: + def fieldPath = "Query.node" + def classifierType = null + def expected = null + + def result = executeTest(schema, fieldPath, null, "(id: \"1\")", classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + def e = thrown(IllegalArgumentException) + e.message == "typeName is required for interface types" + + when: "generate query for the 'node' field with a specific type" + fieldPath = "Query.node" + classifierType = "Foo" + expected = """ +{ + node(id: "1") { + ... on Foo { + id + fooName + } + } +} +""" + result = executeTest(schema, fieldPath, null, "(id: \"1\")", classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + result != null + + when: "passing typeName on field that doesn't return an interface" + fieldPath = "Query.foo" + classifierType = "Foo" + + executeTest(schema, fieldPath, null, "(id: \"1\")", classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + e = thrown(IllegalArgumentException) + e.message == "typeName should be used only with interface or union types" + + when: "passing typeName that doesn't implement Node" + fieldPath = "Query.node" + classifierType = "BazDoesntImplementNode" + + executeTest(schema, fieldPath, null, "(id: \"1\")", classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + e = thrown(IllegalArgumentException) + e.message == "Type BazDoesntImplementNode not found in interface Node" + } + + def "generate query for field which returns an union"() { + given: + def schema = """ + type Query { + something: Something + } + + union Something = Foo | Bar + + type Foo { + id: ID! + fooName: String + } + + type Bar { + id: ID! + barName: String + } + + type BazIsNotPartOfUnion { + id: ID! + bazName: String + } +""" + + + when: + def fieldPath = "Query.something" + def classifierType = null + def expected = null + def result = executeTest(schema, fieldPath, null, null, classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + def e = thrown(IllegalArgumentException) + e.message == "typeName is required for union types" + + when: "generate query for field returning union with a specific type" + fieldPath = "Query.something" + classifierType = "Foo" + expected = """ +{ + something { + ... on Foo { + id + fooName + } + } +} +""" + result = executeTest(schema, fieldPath, null, null, classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + result != null + + when: "passing typeName that is not part of the union" + fieldPath = "Query.something" + classifierType = "BazIsNotPartOfUnion" + + executeTest(schema, fieldPath, null, null, classifierType, expected, QueryGeneratorOptions.newBuilder().build()) + + then: + e = thrown(IllegalArgumentException) + e.message == "Type BazIsNotPartOfUnion not found in union Something" + } + + def "simple field limit"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + field1: String + field2: String + field3: String + field4: String + field5: String + } +""" + + + when: + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + field1 + field2 + field3 + } + } +} +""" + + def options = QueryGeneratorOptions + .newBuilder() + .maxFieldCount(3) + .build() + + def result = executeTest(schema, fieldPath, null, null, null, expected, options) + + then: + result != null + 3 == result.totalFieldCount + result.reachedMaxFieldCount + } + + def "field limit enforcement may result in less fields than the MAX"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + bar: Bar + name: String + age: Int + } + + type Bar { + id: ID! + name: String + } +""" + + + when: "A limit would result on a field container (Foo.bar) having empty field selection" + def options = QueryGeneratorOptions + .newBuilder() + .maxFieldCount(3) + .build() + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + name + } + } +} +""" + + def result = executeTest(schema, fieldPath, null, null, null, expected, options) + + then: + result != null + } + + def "max field limit is enforced"() { + given: + def queryFieldCount = 20_000 + def queryFields = (1..queryFieldCount).collect { " field$it: String" }.join("\n") + + def schema = """ + type Query { + largeType: LargeType + } + + type LargeType { +$queryFields + } +""" + + + when: + + def fieldPath = "Query.largeType" + + def resultFieldCount = 10_000 + def resultFields = (1..resultFieldCount).collect { " field$it" }.join("\n") + + def expected = """ +{ + largeType { + ... on LargeType { +$resultFields + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + 10_000 == result.totalFieldCount + result.reachedMaxFieldCount + } + + def "filter types and field"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + bar: Bar + name: String + age: Int + baz: Baz + } + + type Bar { + id: ID! + name: String + } + + type Baz { + id: ID! + name: String + } +""" + + + when: + def options = QueryGeneratorOptions + .newBuilder() + .filterFieldContainerPredicate { it.name != "Bar" } + .filterFieldDefinitionPredicate { it.name != "name" } + .build() + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + age + baz { + id + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, null, null, null, expected, options) + + then: + result != null + } + + def "union fields"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + barOrBaz: BarOrBaz + } + + union BarOrBaz = Bar | Baz + + type Bar { + id: ID! + barName: String + } + + type Baz { + id: ID! + bazName: String + } +""" + + + when: + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + barOrBaz { + ... on Bar { + Bar_id: id + Bar_barName: barName + } + ... on Baz { + Baz_id: id + Baz_bazName: bazName + } + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "interface fields"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + barOrBaz: BarOrBaz + } + + interface BarOrBaz { + id: ID! + } + + type Bar implements BarOrBaz { + id: ID! + barName: String + } + + type Baz implements BarOrBaz { + id: ID! + bazName: String + } +""" + + + when: + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + barOrBaz { + ... on Bar { + Bar_id: id + Bar_barName: barName + } + ... on Baz { + Baz_id: id + Baz_bazName: bazName + } + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "interface fields with a single implementing type"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + alwaysBar: BarInterface + } + + interface BarInterface { + id: ID! + } + + type Bar implements BarInterface { + id: ID! + barName: String + } +""" + + + when: + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + alwaysBar { + ... on Bar { + Bar_id: id + Bar_barName: barName + } + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "cyclic dependency with union"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + bar: Bar + } + + type Bar { + id: ID! + baz: Baz + } + + union Baz = Bar | Qux + + type Qux { + id: ID! + name: String + } + +""" + + + when: + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + bar { + id + baz { + ... on Bar { + Bar_id: id + } + ... on Qux { + Qux_id: id + Qux_name: name + } + } + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "union fields with a single type in union"() { + given: + def schema = """ + type Query { + foo: Foo + } + + type Foo { + id: ID! + alwaysBar: BarUnion + } + + union BarUnion = Bar + + type Bar { + id: ID! + barName: String + } +""" + + + when: + + def fieldPath = "Query.foo" + def expected = """ +{ + foo { + ... on Foo { + id + alwaysBar { + ... on Bar { + Bar_id: id + Bar_barName: barName + } + } + } + } +} +""" + + def result = executeTest(schema, fieldPath, expected) + + then: + result != null + } + + def "generates query for large type"() { + given: + def schema = getClass().getClassLoader().getResourceAsStream("extra-large-schema-1.graphqls").text + + when: + def fieldPath = "Query.node" + + def expected = getClass().getClassLoader().getResourceAsStream("querygenerator/generated-query-for-extra-large-schema-1.graphql").text + + def result = executeTest(schema, fieldPath, null, "(id: \"issue-id-1\")", "JiraIssue", expected, QueryGeneratorOptions.newBuilder().build()) + + then: + result != null + } + + private static QueryGeneratorResult executeTest( + String schemaDefinition, + String fieldPath, + String expected + ) { + return executeTest( + schemaDefinition, + fieldPath, + null, + null, + null, + expected, + QueryGeneratorOptions.newBuilder().build() + ) + } + + private static QueryGeneratorResult executeTest( + String schemaDefinition, + String fieldPath, + String operationName, + String arguments, + String typeName, + String expected, + QueryGeneratorOptions options + ) { + def schema = TestUtil.schema(schemaDefinition) + def queryGenerator = new QueryGenerator(schema, options) + + def result = queryGenerator.generateQuery(fieldPath, operationName, arguments, typeName) + def query = result.query + + executeQuery(query, schema) + + expected.trim() == query.trim() + + return result + } + + private static void executeQuery(String query, GraphQLSchema schema) { + def document = new Parser().parseDocument(query) + + def errors = new Validator().validateDocument(schema, document, Locale.ENGLISH) + + if (!errors.isEmpty()) { + throw new Exception("Validation errors: " + errors.collect { it.getMessage() }.join(", ")) + } + + } +} diff --git a/src/test/groovy/graphql/validation/MaxValidationErrorsTest.groovy b/src/test/groovy/graphql/validation/MaxValidationErrorsTest.groovy new file mode 100644 index 0000000000..ea624d8625 --- /dev/null +++ b/src/test/groovy/graphql/validation/MaxValidationErrorsTest.groovy @@ -0,0 +1,25 @@ +package graphql.validation + +class MaxValidationErrorsTest extends SpecValidationBase { + + def "The maximum number of validation messages is respected"() { + def directives = "@lol" * 500 + def query = """ + query lotsOfErrors { + f $directives + } + """ + when: + def validationErrors = validate(query) + + then: + validationErrors.size() == 100 + + when: "we can set a new maximum" + Validator.setMaxValidationErrors(10) + validationErrors = validate(query) + + then: + validationErrors.size() == 10 + } +} diff --git a/src/test/groovy/graphql/validation/RulesVisitorTest.groovy b/src/test/groovy/graphql/validation/RulesVisitorTest.groovy index 1f74542a68..2b0de3a993 100644 --- a/src/test/groovy/graphql/validation/RulesVisitorTest.groovy +++ b/src/test/groovy/graphql/validation/RulesVisitorTest.groovy @@ -1,22 +1,25 @@ package graphql.validation import graphql.TestUtil +import graphql.i18n.I18n import graphql.language.Document import graphql.parser.Parser -import graphql.validation.rules.NoUnusedVariables import spock.lang.Specification class RulesVisitorTest extends Specification { - ValidationErrorCollector errorCollector = new ValidationErrorCollector() + AbstractRule simpleRule = Mock() + AbstractRule visitsSpreadsRule = Mock() + + def setup() { + visitsSpreadsRule.isVisitFragmentSpreads() >> true + } def traverse(String query) { Document document = new Parser().parseDocument(query) - ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document, i18n) LanguageTraversal languageTraversal = new LanguageTraversal() - // this is one of the rules which checks inside fragment spreads, so it's needed to test this - NoUnusedVariables noUnusedVariables = new NoUnusedVariables(validationContext, errorCollector) - - languageTraversal.traverse(document, new RulesVisitor(validationContext, [noUnusedVariables])) + languageTraversal.traverse(document, new RulesVisitor(validationContext, [simpleRule, visitsSpreadsRule])) } def "RulesVisitor does not repeatedly spread directly recursive fragments leading to a stackoverflow"() { @@ -71,4 +74,24 @@ class RulesVisitorTest extends Specification { notThrown(StackOverflowError) } + def "RulesVisitor visits fragment definition with isVisitFragmentSpread rules once per operation"() { + given: + def query = """ + fragment A on A { __typename } + fragment B on B { ...A } + fragment C on C { ...A ...B } + + query Q1 { ...A ...B ...C } + query Q2 { ...A ...B ...C } + """ + + when: + traverse(query) + + then: + 2 * visitsSpreadsRule.checkFragmentDefinition({it.name == "A"}) + 2 * visitsSpreadsRule.checkFragmentDefinition({it.name == "B"}) + 2 * visitsSpreadsRule.checkFragmentDefinition({it.name == "C"}) + } } + diff --git a/src/test/groovy/graphql/validation/SpecValidation282Test.groovy b/src/test/groovy/graphql/validation/SpecValidation282Test.groovy index 92885e1c56..949f40cedc 100644 --- a/src/test/groovy/graphql/validation/SpecValidation282Test.groovy +++ b/src/test/groovy/graphql/validation/SpecValidation282Test.groovy @@ -2,7 +2,7 @@ package graphql.validation /** * validation examples used in the spec in given section - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * * This test checks that an inline fragment containing just a directive * is parsed correctly diff --git a/src/test/groovy/graphql/validation/SpecValidation51Test.groovy b/src/test/groovy/graphql/validation/SpecValidation51Test.groovy index 173459238b..ef05fa8063 100644 --- a/src/test/groovy/graphql/validation/SpecValidation51Test.groovy +++ b/src/test/groovy/graphql/validation/SpecValidation51Test.groovy @@ -1,7 +1,7 @@ package graphql.validation /** * validation examples used in the spec in given section - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * @author dwinsor * */ @@ -66,95 +66,6 @@ mutation dogOperation { id } } -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - } - - - def '5.1.2.1 Lone Anonymous Operation Valid'() { - def query = """ -{ - dog { - name - } -} -""" - when: - def validationErrors = validate(query) - - then: - validationErrors.empty - } - - - def '5.1.2.1 Lone Anonymous Operation Not Valid'() { - def query = """ -{ - dog { - name - } -} - -query getName { - dog { - owner { - name - } - } -} -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - } - - def '5.1.2.1 Lone Anonymous Operation Not Valid (reverse order) '() { - def query = """ - -query getName { - dog { - owner { - name - } - } -} - -{ - dog { - name - } -} - -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - } - - def '5.1.2.1 Lone Anonymous Operation Not Valid (not really alone)'() { - def query = """ -{ - dog { - owner { - name - } - } -} - -{ - dog { - name - } -} - """ when: def validationErrors = validate(query) diff --git a/src/test/groovy/graphql/validation/SpecValidation521Test.groovy b/src/test/groovy/graphql/validation/SpecValidation521Test.groovy deleted file mode 100644 index 88c86898db..0000000000 --- a/src/test/groovy/graphql/validation/SpecValidation521Test.groovy +++ /dev/null @@ -1,133 +0,0 @@ -package graphql.validation -/** - * validation examples used in the spec in given section - * http://facebook.github.io/graphql/#sec-Validation - * @author dwinsor - * - */ -class SpecValidation521Test extends SpecValidationBase { - - def '5.2.1 Field Selections on ... fieldNotDefined'() { - def query = """ -{ - dog { - ... fieldNotDefined - } -} -fragment fieldNotDefined on Dog { - meowVolume -} -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined - } - - def '5.2.1 Field Selections on ... aliasedLyingFieldTargetNotDefined'() { - def query = """ -{ - dog { - ... aliasedLyingFieldTargetNotDefined - } -} -fragment aliasedLyingFieldTargetNotDefined on Dog { - barkVolume: kawVolume -} -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined - } - - def '5.2.1 Field Selections on ... interfaceFieldSelection'() { - def query = """ -{ - dog { - ... interfaceFieldSelection - } -} -fragment interfaceFieldSelection on Pet { - name -} -""" - when: - def validationErrors = validate(query) - - then: - validationErrors.empty - } - - def '5.2.1 Field Selections on ... definedOnImplementorsButNotInterface'() { - def query = """ -{ - dog { - ... definedOnImplementorsButNotInterface - } -} -fragment definedOnImplementorsButNotInterface on Pet { - nickname -} -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined - } - - def '5.2.1 Field Selections on ... inDirectFieldSelectionOnUnion'() { - def query = """ -{ - dog { - ... inDirectFieldSelectionOnUnion - } -} -fragment inDirectFieldSelectionOnUnion on CatOrDog { - __typename - ... on Pet { - name - } - ... on Dog { - barkVolume - } -} -""" - when: - def validationErrors = validate(query) - - then: - validationErrors.empty - } - - def '5.2.1 Field Selections on ... directFieldSelectionOnUnion'() { - def query = """ -{ - dog { - ... directFieldSelectionOnUnion - } -} -fragment directFieldSelectionOnUnion on CatOrDog { - name - barkVolume -} -""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 2 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined - validationErrors.get(1).getValidationErrorType() == ValidationErrorType.FieldUndefined - } -} diff --git a/src/test/groovy/graphql/validation/SpecValidation5421Test.groovy b/src/test/groovy/graphql/validation/SpecValidation5421Test.groovy deleted file mode 100644 index b937fd8f88..0000000000 --- a/src/test/groovy/graphql/validation/SpecValidation5421Test.groovy +++ /dev/null @@ -1,26 +0,0 @@ -package graphql.validation -/** - * validation examples used in the spec in given section - * http://facebook.github.io/graphql/#sec-Validation - * @author dwinsor - * - */ -class SpecValidation5421Test extends SpecValidationBase { - - def '5.4.2.1 Fragment spread target defined '() { - def query = """ - query getDogName { - dog { - ... FragmentDoesNotExist - } - } - """ - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UndefinedFragment - } -} diff --git a/src/test/groovy/graphql/validation/SpecValidation562Test.groovy b/src/test/groovy/graphql/validation/SpecValidation562Test.groovy index bbec32c5d6..7a0f1ada73 100644 --- a/src/test/groovy/graphql/validation/SpecValidation562Test.groovy +++ b/src/test/groovy/graphql/validation/SpecValidation562Test.groovy @@ -1,7 +1,7 @@ package graphql.validation /** * validation examples used in the spec in given section - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * @author dwinsor * */ diff --git a/src/test/groovy/graphql/validation/SpecValidation573Test.groovy b/src/test/groovy/graphql/validation/SpecValidation573Test.groovy index 4fc5827cdc..0d8565e227 100644 --- a/src/test/groovy/graphql/validation/SpecValidation573Test.groovy +++ b/src/test/groovy/graphql/validation/SpecValidation573Test.groovy @@ -1,7 +1,7 @@ package graphql.validation /** * validation examples used in the spec in given section - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * */ class SpecValidation573Test extends SpecValidationBase { @@ -21,52 +21,4 @@ query madDog(\$dogCommand: DogCommand){ validationErrors.size() == 1 validationErrors.get(0).getValidationErrorType() == ValidationErrorType.VariableTypeMismatch } - - def '5.7.3 Variables Are Input Types - unknown type'() { - def query = """ -query madDog(\$dogCommand: UnknownType){ - dog { - doesKnowCommand(dogCommand: \$dogCommand) - } -}""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownType - } - - def '5.7.3 Variables Are Input Types - non-null unknown type'() { - def query = """ -query madDog(\$dogCommand: UnknownType!){ - dog { - doesKnowCommand(dogCommand: \$dogCommand) - } -}""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownType - } - - def '5.7.3 Variables Are Input Types - non-null list unknown type'() { - def query = """ -query madDog(\$dogCommand: [UnknownType]){ - dog { - doesKnowCommand(dogCommand: \$dogCommand) - } -}""" - when: - def validationErrors = validate(query) - - then: - !validationErrors.empty - validationErrors.size() == 1 - validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownType - } } diff --git a/src/test/groovy/graphql/validation/SpecValidationBase.groovy b/src/test/groovy/graphql/validation/SpecValidationBase.groovy index 6611670f45..1436f47524 100644 --- a/src/test/groovy/graphql/validation/SpecValidationBase.groovy +++ b/src/test/groovy/graphql/validation/SpecValidationBase.groovy @@ -5,14 +5,14 @@ import spock.lang.Specification /** * validation examples used in the spec - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * @author dwinsor * */ class SpecValidationBase extends Specification { - List validate(String query) { + static List validate(String query) { def document = new Parser().parseDocument(query) - return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) } } diff --git a/src/test/groovy/graphql/validation/SpecValidationSchema.java b/src/test/groovy/graphql/validation/SpecValidationSchema.java index 1e2fa43dba..aa244a6a11 100644 --- a/src/test/groovy/graphql/validation/SpecValidationSchema.java +++ b/src/test/groovy/graphql/validation/SpecValidationSchema.java @@ -1,9 +1,13 @@ package graphql.validation; +import graphql.Directives; import graphql.Scalars; -import graphql.TypeResolutionEnvironment; import graphql.schema.GraphQLArgument; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLDirective; import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectField; +import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; @@ -18,13 +22,22 @@ import java.util.HashSet; import java.util.Set; +import static graphql.Scalars.GraphQLString; +import static graphql.introspection.Introspection.DirectiveLocation.FIELD; +import static graphql.introspection.Introspection.DirectiveLocation.FRAGMENT_DEFINITION; +import static graphql.introspection.Introspection.DirectiveLocation.FRAGMENT_SPREAD; +import static graphql.introspection.Introspection.DirectiveLocation.INLINE_FRAGMENT; +import static graphql.introspection.Introspection.DirectiveLocation.QUERY; +import static graphql.schema.GraphQLArgument.newArgument; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; +import static graphql.schema.GraphQLInputObjectField.newInputObjectField; +import static graphql.schema.GraphQLInputObjectType.newInputObject; import static graphql.schema.GraphQLNonNull.nonNull; import static java.util.Collections.singletonList; /** * Sample schema used in the spec for validation examples - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * * @author dwinsor */ @@ -45,27 +58,6 @@ public class SpecValidationSchema { public static final GraphQLInterfaceType sentient = GraphQLInterfaceType.newInterface() .name("Sentient") .field(newFieldDefinition().name("name").type(nonNull(Scalars.GraphQLString))) - .typeResolver(new TypeResolver() { - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment env) { - if (env.getObject() instanceof Human) return human; - if (env.getObject() instanceof Alien) return alien; - return null; - } - }) - .build(); - - public static final GraphQLInterfaceType pet = GraphQLInterfaceType.newInterface() - .name("Pet") - .field(newFieldDefinition().name("name").type(nonNull(Scalars.GraphQLString))) - .typeResolver(new TypeResolver() { - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment env) { - if (env.getObject() instanceof Dog) return dog; - if (env.getObject() instanceof Cat) return cat; - return null; - } - }) .build(); public static final GraphQLObjectType human = GraphQLObjectType.newObject() @@ -81,6 +73,21 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { .withInterface(SpecValidationSchema.sentient) .build(); + public static final TypeResolver sentientTypeResolver = env -> { + if (env.getObject() instanceof Human) { + return human; + } + if (env.getObject() instanceof Alien) { + return alien; + } + return null; + }; + + public static final GraphQLArgument catCommandArg = GraphQLArgument.newArgument() + .name("catCommand") + .type(nonNull(catCommand)) + .build(); + public static final GraphQLArgument dogCommandArg = GraphQLArgument.newArgument() .name("dogCommand") .type(nonNull(dogCommand)) @@ -91,9 +98,9 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { .type(Scalars.GraphQLBoolean) .build(); - public static final GraphQLArgument catCommandArg = GraphQLArgument.newArgument() - .name("catCommand") - .type(nonNull(catCommand)) + public static final GraphQLInterfaceType pet = GraphQLInterfaceType.newInterface() + .name("Pet") + .field(newFieldDefinition().name("name").type(nonNull(Scalars.GraphQLString))) .build(); public static final GraphQLObjectType dog = GraphQLObjectType.newObject() @@ -102,9 +109,9 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { .field(newFieldDefinition().name("nickname").type(Scalars.GraphQLString)) .field(newFieldDefinition().name("barkVolume").type(Scalars.GraphQLInt)) .field(newFieldDefinition().name("doesKnowCommand").type(nonNull(Scalars.GraphQLBoolean)) - .argument(singletonList(dogCommandArg))) + .arguments(singletonList(dogCommandArg))) .field(newFieldDefinition().name("isHousetrained").type(Scalars.GraphQLBoolean) - .argument(singletonList(atOtherHomesArg))) + .arguments(singletonList(atOtherHomesArg))) .field(newFieldDefinition().name("owner").type(human)) .withInterface(SpecValidationSchema.pet) .build(); @@ -115,47 +122,120 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { .field(newFieldDefinition().name("nickname").type(Scalars.GraphQLString)) .field(newFieldDefinition().name("meowVolume").type(Scalars.GraphQLInt)) .field(newFieldDefinition().name("doesKnowCommand").type(nonNull(Scalars.GraphQLBoolean)) - .argument(singletonList(catCommandArg))) + .arguments(singletonList(catCommandArg))) .withInterface(SpecValidationSchema.pet) .build(); + public static final TypeResolver petTypeResolver = env -> { + if (env.getObject() instanceof Dog) { + return dog; + } + if (env.getObject() instanceof Cat) { + return cat; + } + return null; + }; + public static final GraphQLUnionType catOrDog = GraphQLUnionType.newUnionType() .name("CatOrDog") .possibleTypes(cat, dog) - .typeResolver(env -> { - if (env.getObject() instanceof Cat) return cat; - if (env.getObject() instanceof Dog) return dog; - return null; - }) .build(); + public static final TypeResolver catOrDogTypeResolver = env -> { + if (env.getObject() instanceof Cat) { + return cat; + } + if (env.getObject() instanceof Dog) { + return dog; + } + return null; + }; + public static final GraphQLUnionType dogOrHuman = GraphQLUnionType.newUnionType() .name("DogOrHuman") .possibleTypes(dog, human) - .typeResolver(env -> { - if (env.getObject() instanceof Human) return human; - if (env.getObject() instanceof Dog) return dog; - return null; - }) .build(); + public static final TypeResolver dogOrHumanTypeResolver = env -> { + if (env.getObject() instanceof Human) { + return human; + } + if (env.getObject() instanceof Dog) { + return dog; + } + return null; + }; + public static final GraphQLUnionType humanOrAlien = GraphQLUnionType.newUnionType() .name("HumanOrAlien") .possibleTypes(human, alien) - .typeResolver(env -> { - if (env.getObject() instanceof Human) return human; - if (env.getObject() instanceof Alien) return alien; - return null; - }) .build(); + public static final TypeResolver humanOrAlienTypeResolver = env -> { + if (env.getObject() instanceof Human) { + return human; + } + if (env.getObject() instanceof Alien) { + return alien; + } + return null; + }; + + public static final GraphQLDirective dogDirective = GraphQLDirective.newDirective() + .name("dogDirective") + .argument(newArgument().name("arg1").type(GraphQLString).build()) + .validLocations(FIELD, FRAGMENT_SPREAD, FRAGMENT_DEFINITION, INLINE_FRAGMENT, QUERY) + .build(); + + public static final GraphQLInputObjectType oneOfInputType = GraphQLInputObjectType.newInputObject() + .name("oneOfInputType") + .withAppliedDirective(Directives.OneOfDirective.toAppliedDirective()) + .field(GraphQLInputObjectField.newInputObjectField() + .name("a") + .type(GraphQLString)) + .field(GraphQLInputObjectField.newInputObjectField() + .name("b") + .type(GraphQLString)) + .build(); + + public static final GraphQLObjectType queryRoot = GraphQLObjectType.newObject() .name("QueryRoot") - .field(newFieldDefinition().name("dog").type(dog)) + .field(newFieldDefinition().name("dog").type(dog) + .argument(newArgument().name("arg1").type(GraphQLString).build()) + .withDirective(dogDirective) + ) .field(newFieldDefinition().name("pet").type(pet)) + .field(newFieldDefinition().name("oneOfField").type(GraphQLString) + .argument(newArgument().name("oneOfArg").type(oneOfInputType).build()) + ) + .build(); + + public static final GraphQLObjectType subscriptionRoot = GraphQLObjectType.newObject() + .name("SubscriptionRoot") + .field(newFieldDefinition().name("dog").type(dog)) + .field(newFieldDefinition().name("cat").type(cat)) + .build(); + + public static GraphQLInputObjectType inputDogType = newInputObject() + .name("DogInput") + .description("Input for A Dog creation.") + .field(newInputObjectField() + .name("id") + .description("The id of the dog.") + .type(nonNull(GraphQLString))) + .build(); + + public static final GraphQLObjectType petMutationType = GraphQLObjectType.newObject() + .name("PetMutationType") + .field(newFieldDefinition() + .name("createDog") + .type(dog) + .argument(newArgument() + .name("input") + .type(inputDogType))) .build(); - @SuppressWarnings("serial") public static final Set specValidationDictionary = new HashSet() {{ add(dogCommand); add(catCommand); @@ -169,9 +249,61 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { add(dogOrHuman); add(humanOrAlien); }}; + + public static final GraphQLDirective upperDirective = GraphQLDirective.newDirective() + .name("upper") + .validLocations(FIELD, FRAGMENT_SPREAD, FRAGMENT_DEFINITION, INLINE_FRAGMENT, QUERY) + .build(); + + public static final GraphQLDirective lowerDirective = GraphQLDirective.newDirective() + .name("lower") + .validLocations(FIELD, FRAGMENT_SPREAD, FRAGMENT_DEFINITION, INLINE_FRAGMENT, QUERY) + .build(); + + public static final GraphQLDirective nonNullDirective = GraphQLDirective.newDirective() + .name("nonNullDirective") + .argument(newArgument().name("arg1").type(nonNull(GraphQLString)).build()) + .validLocations(FIELD, FRAGMENT_SPREAD, FRAGMENT_DEFINITION, INLINE_FRAGMENT, QUERY) + .build(); + + public static final GraphQLInputObjectType inputType = GraphQLInputObjectType.newInputObject() + .name("Input") + .field(GraphQLInputObjectField.newInputObjectField() + .name("id") + .type(GraphQLString) + .build()) + .field(GraphQLInputObjectField.newInputObjectField() + .name("name") + .type(nonNull(GraphQLString)) + .build()) + .build(); + + public static final GraphQLDirective objectArgumentDirective = GraphQLDirective.newDirective() + .name("objectArgumentDirective") + .argument(newArgument().name("myObject").type(nonNull(inputType)).build()) + .validLocations(FIELD, FRAGMENT_SPREAD, FRAGMENT_DEFINITION, INLINE_FRAGMENT, QUERY) + .build(); + + public static final GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver("Sentient", sentientTypeResolver) + .typeResolver("Pet", petTypeResolver) + .typeResolver("CatOrDog", catOrDogTypeResolver) + .typeResolver("DogOrHuman", dogOrHumanTypeResolver) + .typeResolver("HumanOrAlien", humanOrAlienTypeResolver) + .build(); + public static final GraphQLSchema specValidationSchema = GraphQLSchema.newSchema() .query(queryRoot) - .build(specValidationDictionary); - + .codeRegistry(codeRegistry) + .subscription(subscriptionRoot) + .mutation(petMutationType) + .additionalDirective(upperDirective) + .additionalDirective(lowerDirective) + .additionalDirective(dogDirective) + .additionalDirective(nonNullDirective) + .additionalDirective(objectArgumentDirective) + .additionalDirective(Directives.DeferDirective) + .additionalTypes(specValidationDictionary) + .build(); } diff --git a/src/test/groovy/graphql/validation/SpecValidationSchemaPojos.java b/src/test/groovy/graphql/validation/SpecValidationSchemaPojos.java index 9b0346b3e1..da3d0c7622 100644 --- a/src/test/groovy/graphql/validation/SpecValidationSchemaPojos.java +++ b/src/test/groovy/graphql/validation/SpecValidationSchemaPojos.java @@ -2,7 +2,7 @@ /** * Sample schema pojos used in the spec for validation examples - * http://facebook.github.io/graphql/#sec-Validation + * https://spec.graphql.org/October2021/#sec-Validation * * @author dwinsor */ diff --git a/src/test/groovy/graphql/validation/TraversalContextTest.groovy b/src/test/groovy/graphql/validation/TraversalContextTest.groovy index cdbc64a1af..0afcbc1964 100644 --- a/src/test/groovy/graphql/validation/TraversalContextTest.groovy +++ b/src/test/groovy/graphql/validation/TraversalContextTest.groovy @@ -23,6 +23,7 @@ import spock.lang.Specification import static graphql.Directives.IncludeDirective import static graphql.Scalars.GraphQLString import static graphql.StarWarsSchema.droidType +import static graphql.StarWarsSchema.inputHumanType import static graphql.StarWarsSchema.queryType import static graphql.StarWarsSchema.starWarsSchema import static graphql.language.OperationDefinition.Operation.QUERY @@ -142,6 +143,43 @@ class TraversalContextTest extends Specification { traversalContext.getOutputType() == null } + def "inlineFragment that is not a GraphQLOutputType should result as null"() { + given: + InlineFragment inlineFragment = new InlineFragment(new TypeName(inputHumanType.getName())) + + when: + traversalContext.enter(inlineFragment, []) + + then: + traversalContext.getOutputType() == null + + when: + traversalContext.leave(inlineFragment, []) + + then: + traversalContext.getOutputType() == null + } + + def "fragmentDefinition that is not a GraphQLOutputType should result as null"() { + given: + FragmentDefinition fragmentDefinition = FragmentDefinition.newFragmentDefinition() + .name("fragment") + .typeCondition(new TypeName(inputHumanType.getName())) + .build() + + when: + traversalContext.enter(fragmentDefinition, []) + + then: + traversalContext.getOutputType() == null + + when: + traversalContext.leave(fragmentDefinition, []) + + then: + traversalContext.getOutputType() == null + } + def "variableDefinition saved as input type"() { given: VariableDefinition variableDefinition = new VariableDefinition("var", new TypeName("String")) diff --git a/src/test/groovy/graphql/validation/ValidateCustomDirectives.groovy b/src/test/groovy/graphql/validation/ValidateCustomDirectives.groovy index eb7550ec94..5a1569e978 100644 --- a/src/test/groovy/graphql/validation/ValidateCustomDirectives.groovy +++ b/src/test/groovy/graphql/validation/ValidateCustomDirectives.groovy @@ -19,7 +19,11 @@ class ValidateCustomDirectives extends Specification { GraphQLSchema customDirectiveSchema = GraphQLSchema.newSchema() .query(SpecValidationSchema.queryRoot) - .build(SpecValidationSchema.specValidationDictionary, [customDirective].toSet()) + .codeRegistry(SpecValidationSchema.codeRegistry) + .additionalDirective(SpecValidationSchema.dogDirective) + .additionalDirective(customDirective) + .additionalTypes(SpecValidationSchema.specValidationDictionary) + .build() def 'Schema with custom directive validates query with same directive'() { def query = """ @@ -50,11 +54,11 @@ query { then: validationErrors.size() == 1 validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownDirective - validationErrors.get(0).getDescription() == 'Unknown directive argument dummy' + validationErrors.get(0).getDescription() == "Validation error (UnknownDirective@[dog/name]) : Unknown directive argument 'dummy'" } List validate(String query) { def document = new Parser().parseDocument(query) - return new Validator().validateDocument(customDirectiveSchema, document) + return new Validator().validateDocument(customDirectiveSchema, document, Locale.ENGLISH) } } diff --git a/src/test/groovy/graphql/validation/ValidationErrorToString.groovy b/src/test/groovy/graphql/validation/ValidationErrorToString.groovy new file mode 100644 index 0000000000..cfade59c28 --- /dev/null +++ b/src/test/groovy/graphql/validation/ValidationErrorToString.groovy @@ -0,0 +1,39 @@ +package graphql.validation + +import graphql.language.SourceLocation +import spock.lang.Specification + +class ValidationErrorToString extends Specification { + + def 'toString prints correctly ValidationError object when all fields are initialized'() { + given: + def sourceLocations = [new SourceLocation(5, 0), new SourceLocation(10, 1)] + def description = "Validation Error (UnknownType)" + def validationErrorClassification = ValidationErrorType.UnknownType + def queryPath = ["home", "address"] + def extensions = ["extension1": "first", "extension2": true, "extension3": 2] + + when: + def validationError = ValidationError + .newValidationError() + .sourceLocations(sourceLocations) + .description(description) + .validationErrorType(validationErrorClassification) + .queryPath(queryPath) + .extensions(extensions) + .build() + + then: + validationError.toString() == "ValidationError{validationErrorType=UnknownType, queryPath=[home, address], message=Validation Error (UnknownType), locations=[SourceLocation{line=5, column=0}, SourceLocation{line=10, column=1}], description='Validation Error (UnknownType)', extensions=[extension1=first, extension2=true, extension3=2]}" + } + + def 'toString prints correctly ValidationError object when all fields are empty'() { + when: + def validationError = ValidationError + .newValidationError() + .build() + + then: + validationError.toString() == "ValidationError{validationErrorType=null, queryPath=[], message=null, locations=[], description='null', extensions=[]}" + } +} diff --git a/src/test/groovy/graphql/validation/ValidationUtilTest.groovy b/src/test/groovy/graphql/validation/ValidationUtilTest.groovy index ecb8a7c4c2..251362b09a 100644 --- a/src/test/groovy/graphql/validation/ValidationUtilTest.groovy +++ b/src/test/groovy/graphql/validation/ValidationUtilTest.groovy @@ -1,5 +1,6 @@ package graphql.validation +import graphql.GraphQLContext import graphql.StarWarsSchema import graphql.language.ArrayValue import graphql.language.BooleanValue @@ -18,15 +19,23 @@ import graphql.schema.GraphQLInputObjectType import graphql.schema.GraphQLSchema import spock.lang.Specification +import static graphql.Directives.OneOfDirective import static graphql.Scalars.GraphQLBoolean import static graphql.Scalars.GraphQLString +import static graphql.language.ObjectField.newObjectField +import static graphql.schema.GraphQLAppliedDirective.newDirective import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull class ValidationUtilTest extends Specification { - def schema = GraphQLSchema.newSchema().query(StarWarsSchema.queryType).build() + def schema = GraphQLSchema.newSchema() + .query(StarWarsSchema.queryType) + .codeRegistry(StarWarsSchema.codeRegistry) + .build() def validationUtil = new ValidationUtil() + def graphQLContext = GraphQLContext.getDefault() + def locale = Locale.getDefault() def "getUnmodified type of list of nonNull"() { given: @@ -51,32 +60,32 @@ class ValidationUtilTest extends Specification { def "null and NonNull is invalid"() { expect: - !validationUtil.isValidLiteralValue(null, nonNull(GraphQLString),schema) + !validationUtil.isValidLiteralValue(null, nonNull(GraphQLString), schema, graphQLContext, locale) } def "NullValue and NonNull is invalid"() { expect: - !validationUtil.isValidLiteralValue(NullValue.Null, nonNull(GraphQLString),schema) + !validationUtil.isValidLiteralValue(NullValue.newNullValue().build(), nonNull(GraphQLString), schema, graphQLContext, locale) } def "a nonNull value for a NonNull type is valid"() { expect: - validationUtil.isValidLiteralValue(new StringValue("string"), nonNull(GraphQLString),schema) + validationUtil.isValidLiteralValue(new StringValue("string"), nonNull(GraphQLString), schema, graphQLContext, locale) } def "null is valid when type is NonNull"() { expect: - validationUtil.isValidLiteralValue(null, GraphQLString,schema) + validationUtil.isValidLiteralValue(null, GraphQLString, schema, graphQLContext, locale) } def "NullValue is valid when type is NonNull"() { expect: - validationUtil.isValidLiteralValue(NullValue.Null, GraphQLString,schema) + validationUtil.isValidLiteralValue(NullValue.newNullValue().build(), GraphQLString, schema, graphQLContext, locale) } def "variables are valid"() { expect: - validationUtil.isValidLiteralValue(new VariableReference("var"), GraphQLBoolean,schema) + validationUtil.isValidLiteralValue(new VariableReference("var"), GraphQLBoolean, schema, graphQLContext, locale) } def "ArrayValue and ListType is invalid when one entry is invalid"() { @@ -85,7 +94,7 @@ class ValidationUtilTest extends Specification { def type = list(GraphQLString) expect: - !validationUtil.isValidLiteralValue(arrayValue, type,schema) + !validationUtil.isValidLiteralValue(arrayValue, type, schema, graphQLContext, locale) } def "One value is a single element List"() { @@ -93,7 +102,7 @@ class ValidationUtilTest extends Specification { def singleValue = new BooleanValue(true) def type = list(GraphQLBoolean) expect: - validationUtil.isValidLiteralValue(singleValue, type,schema) + validationUtil.isValidLiteralValue(singleValue, type, schema, graphQLContext, locale) } def "a valid array"() { @@ -102,19 +111,19 @@ class ValidationUtilTest extends Specification { def type = list(GraphQLString) expect: - validationUtil.isValidLiteralValue(arrayValue, type,schema) + validationUtil.isValidLiteralValue(arrayValue, type, schema, graphQLContext, locale) } def "a valid scalar"() { given: expect: - validationUtil.isValidLiteralValue(new BooleanValue(true), GraphQLBoolean,schema) + validationUtil.isValidLiteralValue(new BooleanValue(true), GraphQLBoolean, schema, graphQLContext, locale) } def "invalid scalar"() { given: expect: - !validationUtil.isValidLiteralValue(new BooleanValue(true), GraphQLString,schema) + !validationUtil.isValidLiteralValue(new BooleanValue(true), GraphQLString, schema, graphQLContext, locale) } def "valid enum"() { @@ -122,21 +131,21 @@ class ValidationUtilTest extends Specification { def enumType = GraphQLEnumType.newEnum().name("enumType").value("PLUTO").build() expect: - validationUtil.isValidLiteralValue(new EnumValue("PLUTO"), enumType,schema) + validationUtil.isValidLiteralValue(new EnumValue("PLUTO"), enumType, schema, graphQLContext, locale) } def "invalid enum value"() { given: def enumType = GraphQLEnumType.newEnum().name("enumType").value("PLUTO").build() expect: - !validationUtil.isValidLiteralValue(new StringValue("MARS"), enumType,schema) + !validationUtil.isValidLiteralValue(new StringValue("MARS"), enumType, schema, graphQLContext, locale) } def "invalid enum name"() { given: def enumType = GraphQLEnumType.newEnum().name("enumType").value("PLUTO").build() expect: - !validationUtil.isValidLiteralValue(new EnumValue("MARS"), enumType,schema) + !validationUtil.isValidLiteralValue(new EnumValue("MARS"), enumType, schema, graphQLContext, locale) } def "a valid ObjectValue"() { @@ -144,14 +153,14 @@ class ValidationUtilTest extends Specification { def inputObjectType = GraphQLInputObjectType.newInputObject() .name("inputObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("hello") - .type(GraphQLString)) + .name("hello") + .type(GraphQLString)) .build() def objectValue = ObjectValue.newObjectValue() objectValue.objectField(new ObjectField("hello", new StringValue("world"))) expect: - validationUtil.isValidLiteralValue(objectValue.build(), inputObjectType, schema) + validationUtil.isValidLiteralValueForInputObjectType(objectValue.build(), inputObjectType, schema, graphQLContext, locale) } def "a invalid ObjectValue with a invalid field"() { @@ -159,14 +168,14 @@ class ValidationUtilTest extends Specification { def inputObjectType = GraphQLInputObjectType.newInputObject() .name("inputObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("hello") - .type(GraphQLString)) + .name("hello") + .type(GraphQLString)) .build() def objectValue = ObjectValue.newObjectValue() objectValue.objectField(new ObjectField("hello", new BooleanValue(false))) expect: - !validationUtil.isValidLiteralValue(objectValue.build(), inputObjectType, schema) + !validationUtil.isValidLiteralValueForInputObjectType(objectValue.build(), inputObjectType, schema, graphQLContext, locale) } def "a invalid ObjectValue with a missing field"() { @@ -174,12 +183,69 @@ class ValidationUtilTest extends Specification { def inputObjectType = GraphQLInputObjectType.newInputObject() .name("inputObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("hello") - .type(nonNull(GraphQLString))) + .name("hello") + .type(nonNull(GraphQLString))) .build() def objectValue = ObjectValue.newObjectValue().build() expect: - !validationUtil.isValidLiteralValue(objectValue, inputObjectType,schema) + !validationUtil.isValidLiteralValueForInputObjectType(objectValue, inputObjectType, schema, graphQLContext, locale) + } + + def "a valid ObjectValue with a nonNull field and default value"() { + given: + def inputObjectType = GraphQLInputObjectType.newInputObject() + .name("inputObjectType") + .field(GraphQLInputObjectField.newInputObjectField() + .name("hello") + .type(nonNull(GraphQLString)) + .defaultValueProgrammatic("default")) + .build() + def objectValue = ObjectValue.newObjectValue() + + expect: + validationUtil.isValidLiteralValueForInputObjectType(objectValue.build(), inputObjectType, schema, graphQLContext, locale) + } + + def "a valid @oneOf input literal"() { + given: + def inputObjectType = GraphQLInputObjectType.newInputObject() + .name("inputObjectType") + .withAppliedDirective(newDirective().name(OneOfDirective.getName())) + .field(GraphQLInputObjectField.newInputObjectField() + .name("f1") + .type(GraphQLString)) + .field(GraphQLInputObjectField.newInputObjectField() + .name("f2") + .type(GraphQLString)) + .build() + def objectValue = ObjectValue.newObjectValue() + .objectField(newObjectField().name("f1").value(StringValue.of("v1")).build()) + .build() + + expect: + validationUtil.isValidLiteralValueForInputObjectType(objectValue, inputObjectType, schema, graphQLContext, locale) + } + + def "an invalid @oneOf input literal"() { + given: + def inputObjectType = GraphQLInputObjectType.newInputObject() + .name("inputObjectType") + .withAppliedDirective(newDirective().name(OneOfDirective.getName())) + .field(GraphQLInputObjectField.newInputObjectField() + .name("f1") + .type(GraphQLString)) + .field(GraphQLInputObjectField.newInputObjectField() + .name("f2") + .type(GraphQLString)) + .build() + + def objectValue = ObjectValue.newObjectValue() + .objectField(newObjectField().name("f1").value(StringValue.of("v1")).build()) + .objectField(newObjectField().name("f2").value(StringValue.of("v2")).build()) + .build() + + expect: + !validationUtil.isValidLiteralValueForInputObjectType(objectValue, inputObjectType, schema, graphQLContext, locale) } } diff --git a/src/test/groovy/graphql/validation/rules/ArgumentsOfCorrectTypeTest.groovy b/src/test/groovy/graphql/validation/rules/ArgumentsOfCorrectTypeTest.groovy index eab8d80598..7e8210955e 100644 --- a/src/test/groovy/graphql/validation/rules/ArgumentsOfCorrectTypeTest.groovy +++ b/src/test/groovy/graphql/validation/rules/ArgumentsOfCorrectTypeTest.groovy @@ -1,5 +1,7 @@ package graphql.validation.rules +import graphql.GraphQLContext +import graphql.i18n.I18n import graphql.language.Argument import graphql.language.ArrayValue import graphql.language.BooleanValue @@ -8,18 +10,22 @@ import graphql.language.ObjectField import graphql.language.ObjectValue import graphql.language.StringValue import graphql.language.VariableReference +import graphql.parser.Parser import graphql.schema.GraphQLArgument import graphql.schema.GraphQLInputObjectField import graphql.schema.GraphQLInputObjectType import graphql.schema.GraphQLList import graphql.schema.GraphQLNonNull +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification -import static graphql.Scalars.GraphQLBigDecimal import static graphql.Scalars.GraphQLBoolean +import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString import static graphql.StarWarsSchema.starWarsSchema @@ -28,16 +34,40 @@ class ArgumentsOfCorrectTypeTest extends Specification { ArgumentsOfCorrectType argumentsOfCorrectType ValidationContext validationContext = Mock(ValidationContext) ValidationErrorCollector errorCollector = new ValidationErrorCollector() + I18n i18n = Mock(I18n) def setup() { argumentsOfCorrectType = new ArgumentsOfCorrectType(validationContext, errorCollector) + def context = GraphQLContext.getDefault() + validationContext.getGraphQLContext() >> context + validationContext.getI18n() >> i18n + i18n.getLocale() >> Locale.ENGLISH + } + + def "error message uses locale of client (German), not server (English)"() { + def query = """ + query getDog { + dog @objectArgumentDirective(myObject: { id: "1" }) { + name + } + } + """ + def document = new Parser().parseDocument(query) + + when: + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.GERMAN) + + then: + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validierungsfehler (WrongType@[dog]) : Argument 'myObject' mit Wert 'ObjectValue{objectFields=[ObjectField{name='id', value=StringValue{value='1'}}]}' fehlen Pflichtfelder '[name]'" } def "valid type results in no error"() { given: def variableReference = new VariableReference("ref") def argumentLiteral = new Argument("arg", variableReference) - def graphQLArgument = new GraphQLArgument("arg", GraphQLBigDecimal) + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLInt).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument when: argumentsOfCorrectType.checkArgument(argumentLiteral) @@ -49,21 +79,38 @@ class ArgumentsOfCorrectTypeTest extends Specification { given: def stringValue = new StringValue("string") def argumentLiteral = new Argument("arg", stringValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLBoolean) + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLBoolean).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument when: argumentsOfCorrectType.checkArgument(argumentLiteral) then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg' with value 'StringValue{value='string'}' is not a valid 'Boolean'" + } + + def "invalid type scalar results in error with message"() { + def query = """ + query getDog { + dog(arg1: 1) { + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validation error (WrongType@[dog]) : argument 'arg1' with value 'IntValue{value=1}' is not a valid 'String' - Expected an AST type of 'StringValue' but it was a 'IntValue'" } def "invalid input object type results in error"() { given: def objectValue = new ObjectValue([new ObjectField("foo", new StringValue("string"))]) def argumentLiteral = new Argument("arg", objectValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLInputObjectType.newInputObject().name("ArgumentObjectType").field(GraphQLInputObjectField.newInputObjectField().name("foo").type(GraphQLBoolean)).build()) + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType").field(GraphQLInputObjectField.newInputObjectField().name("foo").type(GraphQLBoolean)).build()).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument argumentsOfCorrectType.validationContext.getSchema() >> starWarsSchema @@ -72,7 +119,6 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg.foo' with value 'StringValue{value='string'}' is not a valid 'Boolean'" } def "invalid list object type results in error"() { @@ -82,7 +128,7 @@ class ArgumentsOfCorrectTypeTest extends Specification { def invalidValue = new ObjectValue([new ObjectField("foo", new StringValue("string"))]) def arrayValue = new ArrayValue([validValue, invalidValue]) def argumentLiteral = new Argument("arg", arrayValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLList.list(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType").field(GraphQLInputObjectField.newInputObjectField().name("foo").type(GraphQLBoolean)).build())) + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLList.list(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType").field(GraphQLInputObjectField.newInputObjectField().name("foo").type(GraphQLBoolean)).build())).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument argumentsOfCorrectType.validationContext.getSchema() >> starWarsSchema @@ -92,7 +138,6 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg[1].foo' with value 'StringValue{value='string'}' is not a valid 'Boolean'" } def "invalid list inside object type results in error"() { @@ -102,7 +147,7 @@ class ArgumentsOfCorrectTypeTest extends Specification { def invalidValue = new ObjectValue([new ObjectField("foo", new ArrayValue([new BooleanValue(true), new StringValue('string')]))]) def arrayValue = new ArrayValue([invalidValue, validValue]) def argumentLiteral = new Argument("arg", arrayValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLList.list(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType").field(GraphQLInputObjectField.newInputObjectField().name("foo").type(GraphQLList.list(GraphQLBoolean))).build())) + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLList.list(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType").field(GraphQLInputObjectField.newInputObjectField().name("foo").type(GraphQLList.list(GraphQLBoolean))).build())).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument argumentsOfCorrectType.validationContext.getSchema() >> starWarsSchema @@ -112,7 +157,6 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg[0].foo[1]' with value 'StringValue{value='string'}' is not a valid 'Boolean'" } def "invalid list simple type results in error"() { @@ -122,7 +166,7 @@ class ArgumentsOfCorrectTypeTest extends Specification { def invalidValue = new StringValue("string") def arrayValue = new ArrayValue([validValue, invalidValue]) def argumentLiteral = new Argument("arg", arrayValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLList.list(GraphQLBoolean)) + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLList.list(GraphQLBoolean)).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument when: @@ -130,19 +174,18 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg[1]' with value 'StringValue{value='string'}' is not a valid 'Boolean'" } def "type missing fields results in error"() { given: def objectValue = new ObjectValue([new ObjectField("foo", new StringValue("string"))]) def argumentLiteral = new Argument("arg", objectValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) + .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) .field(GraphQLInputObjectField.newInputObjectField() - .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) - .build()) + .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) + .build()).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument argumentsOfCorrectType.validationContext.getSchema() >> starWarsSchema @@ -152,19 +195,36 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg' with value 'ObjectValue{objectFields=[ObjectField{name='foo', value=StringValue{value='string'}}]}' is missing required fields '[bar]'" + } + + def "type missing fields results in error with message"() { + def query = """ + query getDog { + dog @objectArgumentDirective(myObject: { id: "1" }) { + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validation error (WrongType@[dog]) : argument 'myObject' with value 'ObjectValue{objectFields=[ObjectField{name='id', value=StringValue{value='1'}}]}' is missing required fields '[name]'" } def "type not object results in error"() { given: def objectValue = new StringValue("string") def argumentLiteral = new Argument("arg", objectValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) + .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) .field(GraphQLInputObjectField.newInputObjectField() - .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) - .build()) + .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) + .build()).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument when: @@ -172,19 +232,36 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg' with value 'StringValue{value='string'}' must be an object type" + } + + def "invalid not object type results in error with message"() { + def query = """ + query getDog { + dog @objectArgumentDirective(myObject: 1) { + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validation error (WrongType@[dog]) : argument 'myObject' with value 'IntValue{value=1}' must be an object type" } def "type null fields results in error"() { given: - def objectValue = new ObjectValue([new ObjectField("foo", new StringValue("string")), new ObjectField("bar", NullValue.Null)]) + def objectValue = new ObjectValue([new ObjectField("foo", new StringValue("string")), new ObjectField("bar", NullValue.newNullValue().build())]) def argumentLiteral = new Argument("arg", objectValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) + .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) .field(GraphQLInputObjectField.newInputObjectField() - .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) - .build()) + .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) + .build()).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument argumentsOfCorrectType.validationContext.getSchema() >> starWarsSchema @@ -194,19 +271,36 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg.bar' with value 'NullValue{}' must not be null" + } + + def "type null results in error with message"() { + def query = """ + query getDog { + dog { + doesKnowCommand(dogCommand: null) + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 2 // First error is NullValueForNonNullArgument + validationErrors.get(1).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(1).message == "Validation error (WrongType@[dog/doesKnowCommand]) : argument 'dogCommand' with value 'NullValue{}' must not be null" } def "type with extra fields results in error"() { given: def objectValue = new ObjectValue([new ObjectField("foo", new StringValue("string")), new ObjectField("bar", new StringValue("string")), new ObjectField("fooBar", new BooleanValue(true))]) def argumentLiteral = new Argument("arg", objectValue) - def graphQLArgument = new GraphQLArgument("arg", GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") + def graphQLArgument = GraphQLArgument.newArgument().name("arg").type(GraphQLInputObjectType.newInputObject().name("ArgumentObjectType") .field(GraphQLInputObjectField.newInputObjectField() - .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) + .name("foo").type(GraphQLNonNull.nonNull(GraphQLString))) .field(GraphQLInputObjectField.newInputObjectField() - .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) - .build()) + .name("bar").type(GraphQLNonNull.nonNull(GraphQLString))) + .build()).build() argumentsOfCorrectType.validationContext.getArgument() >> graphQLArgument argumentsOfCorrectType.validationContext.getSchema() >> starWarsSchema @@ -216,7 +310,24 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.WrongType) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type WrongType: argument 'arg' with value 'ObjectValue{objectFields=[ObjectField{name='foo', value=StringValue{value='string'}}, ObjectField{name='bar', value=StringValue{value='string'}}, ObjectField{name='fooBar', value=BooleanValue{value=true}}]}' contains a field not in 'ArgumentObjectType': 'fooBar'" + } + + def "type with extra fields results in error with message"() { + def query = """ + query getDog { + dog @objectArgumentDirective(myObject: { name: "Gary", extraField: "ShouldNotBeHere" }) { + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validation error (WrongType@[dog]) : argument 'myObject' with value 'ObjectValue{objectFields=[ObjectField{name='name', value=StringValue{value='Gary'}}, ObjectField{name='extraField', value=StringValue{value='ShouldNotBeHere'}}]}' contains a field not in 'Input': 'extraField'" } def "current null argument from context is no error"() { @@ -228,4 +339,58 @@ class ArgumentsOfCorrectTypeTest extends Specification { then: argumentsOfCorrectType.getErrors().isEmpty() } + + def "invalid enum type results in error with message"() { + def query = """ + query getDog { + dog { + doesKnowCommand(dogCommand: PRETTY) + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validation error (WrongType@[dog/doesKnowCommand]) : argument 'dogCommand' with value 'EnumValue{name='PRETTY'}' is not a valid 'DogCommand' - Literal value not in allowable values for enum 'DogCommand' - 'EnumValue{name='PRETTY'}'" + } + + def "invalid @oneOf argument - has more than 1 key - case #why"() { + when: + def validationErrors = validate(query) + + then: + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.WrongType + validationErrors.get(0).message == "Validation error (WrongType@[oneOfField]) : Exactly one key must be specified for OneOf type 'oneOfInputType'." + + where: + why | query | _ + 'some variables' | + ''' + query q($v1 : String) { + oneOfField(oneOfArg : { a : $v1, b : "y" }) + } + ''' | _ + 'all variables' | + ''' + query q($v1 : String, $v2 : String) { + oneOfField(oneOfArg : { a : $v1, b : $v2 }) + } + ''' | _ + 'all literals' | + ''' + query q { + oneOfField(oneOfArg : { a : "x", b : "y" }) + } + ''' | _ + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } } diff --git a/src/test/groovy/graphql/validation/rules/DeferDirectiveLabelTest.groovy b/src/test/groovy/graphql/validation/rules/DeferDirectiveLabelTest.groovy new file mode 100644 index 0000000000..2e3975269d --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/DeferDirectiveLabelTest.groovy @@ -0,0 +1,213 @@ +package graphql.validation.rules + +import graphql.ExperimentalApi +import graphql.GraphQLContext +import graphql.language.Document +import graphql.parser.Parser +import graphql.validation.LanguageTraversal +import graphql.validation.RulesVisitor +import graphql.validation.SpecValidationSchema +import graphql.validation.TraversalContext +import graphql.validation.ValidationContext +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorCollector +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class DeferDirectiveLabelTest extends Specification { + + ValidationContext validationContext = Mock(ValidationContext) + + ValidationErrorCollector errorCollector = new ValidationErrorCollector() + + DeferDirectiveLabel deferDirectiveLabel = new DeferDirectiveLabel(validationContext, errorCollector) + + def setup() { + def traversalContext = Mock(TraversalContext) + validationContext.getSchema() >> SpecValidationSchema.specValidationSchema + validationContext.getGraphQLContext() >> GraphQLContext.newContext().of( + ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT, true + ).build(); + validationContext.getTraversalContext() >> traversalContext + } + + def "Allow unique label directive"() { + given: + def query = """ + query defer_query { + ... @defer(label: "name") { + human { + name + } + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + errorCollector.errors.isEmpty() + + } + + def "Defer directive label argument must be unique"() { + given: + def query = """ + query defer_query { + dog { + ... @defer(label: "name") { + name + } + } + alien { + ... @defer(label: "name") { + name + } + } + + } + """ + + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + !errorCollector.errors.isEmpty() + errorCollector.containsValidationError(ValidationErrorType.DuplicateIncrementalLabel) + } + + def "Multiple use of Defer directive is valid"() { + given: + def query = """ + query defer_query { + dog { + ... @defer { + name + } + ... @defer { + name + } + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + errorCollector.errors.isEmpty() + } + + def "Allow Multiple use of Defer directive with different labels"() { + given: + def query = """ + query defer_query { + dog { + ... @defer(label: "name") { + name + } + ... @defer(label: "nameAgain") { + name + } + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + errorCollector.errors.isEmpty() + } + + + def "Label cannot be an argument directive"() { + given: + def query = """ + query defer_query(\$label: Int) { + ... @defer(label:\$label) { + human { + name + } + } + } + """ + + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + !errorCollector.errors.isEmpty() + errorCollector.containsValidationError(ValidationErrorType.WrongType) + } + + + def "Defer directive Label must be string"() { + given: + def query = """ + query defer_query { + dog { + ... @defer(label: 1) { + name + } + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.WrongType) + } + + def "defer with null label should behave as if no label was provided"() { + def query = ''' + query { + dog { + ... @defer(label: null) { + name + } + } + cat { + ... @defer(label: null) { + name + } + } + } + ''' + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + languageTraversal.traverse(document, new RulesVisitor(validationContext, [deferDirectiveLabel])) + + then: + errorCollector.errors.isEmpty() + } + + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } +} + diff --git a/src/test/groovy/graphql/validation/rules/DeferDirectiveOnRootLevelTest.groovy b/src/test/groovy/graphql/validation/rules/DeferDirectiveOnRootLevelTest.groovy new file mode 100644 index 0000000000..ec65ec1937 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/DeferDirectiveOnRootLevelTest.groovy @@ -0,0 +1,473 @@ +package graphql.validation.rules + +import graphql.ExperimentalApi +import graphql.i18n.I18n +import graphql.language.Document +import graphql.parser.Parser +import graphql.validation.LanguageTraversal +import graphql.validation.RulesVisitor +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationContext +import graphql.validation.ValidationErrorCollector +import graphql.validation.ValidationErrorType +import spock.lang.Specification + +class DeferDirectiveOnRootLevelTest extends Specification { + + ValidationErrorCollector errorCollector = new ValidationErrorCollector() + + def traverse(String query) { + Document document = new Parser().parseDocument(query) + ValidationContext validationContext = new ValidationContext( + SpecValidationSchema.specValidationSchema, + document, + I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH)) + validationContext.getGraphQLContext().put(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT, true) + + LanguageTraversal languageTraversal = new LanguageTraversal() + languageTraversal.traverse(document, new RulesVisitor(validationContext, [new DeferDirectiveOnRootLevel(validationContext, errorCollector)])) + } + + + def "Not allow defer on subscription root level"() { + given: + def query = """ + subscription pets { + ... @defer { + dog { + name + } + } + } + """ + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + + } + + def "Not allow defer mutation root level "() { + given: + def query = """ + mutation dog { + ... @defer { + createDog(input: {id: "1"}) { + name + } + } + } + """ + + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root mutation type 'PetMutationType'" + + } + + def "Defer directive is allowed on query root level"() { + given: + def query = """ + query defer_query { + ... @defer { + dog { + name + } + } + } + """ + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + def "Not allow defer mutation root level on inline fragments "() { + given: + def query = """ + mutation doggo { + ... { + ... @defer { + createDog(input: {id: "1"}) { + name + } + } + + } + } + """ + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root mutation type 'PetMutationType'" + } + + def "Not allow defer on subscription root level even when is inside multiple inline fragment"() { + given: + def query = """ + subscription pets { + ...{ + ...{ + ... @defer { + dog { + name + } + } + } + } + } + """ + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root subscription type 'SubscriptionRoot'" + + } + + + def "Not allow defer on mutation root level even when ih multiple inline fragments split in fragment"() { + given: + def query = """ + fragment doggo on PetMutationType { + ... { + ... @defer { + createDog(id: "1") { + id + } + } + } + } + + mutation doggoMutation { + ...{ + ...doggo + } + } + + + """ + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective@[doggo]) : Defer directive cannot be used on root mutation type 'PetMutationType'" + } + + + def "Allows defer on mutation when it is not on root level"() { + given: + def query = """ + mutation pets { + createDog(input: {id: "1"}) { + ... @defer { + name + } + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + def "allow defer on fragment when is not on mutation root level"() { + given: + def query = """ + mutation doggo { + ...{ + createDog(id: "1") { + ...doggo + } + } + } + + fragment doggo on Dog { + ... @defer { + id + } + } + + """ + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + + def "allow defer on split fragment when is not on mutation root level"() { + given: + def query = """ + mutation doggo { + ...doggoCreate + } + + fragment doggoCreate on PetMutationType { + createDog(id: "1") { + ...doggoFields + } + } + + fragment doggoFields on Dog { + ... @defer { + id + } + } + + """ + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + + } + + + def "Not allow defer subscription root level even when there are multiple subscriptions"() { + given: + def query = """ + subscription pets { + dog { + name + } + } + subscription dog { + ... @defer { + dog { + name + } + } + } + + subscription morePets { + cat { + name + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal() + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.size() == 1 + + } + + def "Not allow defer on mutation root level when there are multiple fragment levels regarless fragment order on query"() { + given: + def query = """ + + fragment createDoggoRoot on PetMutationType { + ... { + ...createDoggo + } + } + + mutation createDoggoRootOp { + ...createDoggoRoot + } + + fragment createDoggo on PetMutationType { + ... { + ... @defer { + createDog(input: {id: "1"}) { + name + } + } + } + } + + """ + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective@[createDoggoRoot/createDoggo]) : Defer directive cannot be used on root mutation type 'PetMutationType'" + + } + + def "Not allow defer on mutation root level even when there are multiple fragments and operations"() { + given: + def query = """ + + fragment createDoggoLevel1 on PetMutationType { + ... { + ... { + ...createDoggoLevel2 + } + } + } + + fragment createDoggoLevel2 on PetMutationType { + ...createDoggo + } + + fragment createDoggo on PetMutationType { + ... { + ... @defer { + createDog(input: {id: "1"}) { + name + } + } + } + } + + query pets1 { + ... @defer { + dog { + name + } + } + } + + mutation createDoggo { + ...createDoggoLevel1 + } + + """ + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective@[createDoggoLevel1/createDoggoLevel2/createDoggo]) : Defer directive cannot be used on root mutation type 'PetMutationType'" + + } + + + def "Not allow defer on subscription root level even when defer(if == false) "() { + given: + def query = """ + subscription pets{ + ... @defer(if:false) { + dog { + + name + } + nickname + } + } + """ + Document document = new Parser().parseDocument(query) + LanguageTraversal languageTraversal = new LanguageTraversal()\ + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root subscription type 'SubscriptionRoot'" + + } + + def "Not allow defer on subscription root level when defer(if == true) "() { + given: + def query = """ + subscription pets{ + ... @defer(if:true) { + dog { + + name + } + nickname + } + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root subscription type 'SubscriptionRoot'" + + } + + def "Not allow defer on mutation root level even when if is variable that could have false as value "() { + given: + def query = """ + mutation pets(\$ifVar:Boolean){ + ... @defer(if:\$ifVar) { + createDog(input: {id: "1"}) { + name + } + } + + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root mutation type 'PetMutationType'" + } + + def "Not allow defer on mutation root level when defer(if == true) "() { + given: + def query = """ + mutation pets{ + ... @defer(if:true) { + createDog(input: {id: "1"}) { + name + } + } + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective) : Defer directive cannot be used on root mutation type 'PetMutationType'" + + } + +} + diff --git a/src/test/groovy/graphql/validation/rules/DeferDirectiveOnValidOperationTest.groovy b/src/test/groovy/graphql/validation/rules/DeferDirectiveOnValidOperationTest.groovy new file mode 100644 index 0000000000..1430b7743b --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/DeferDirectiveOnValidOperationTest.groovy @@ -0,0 +1,366 @@ +package graphql.validation.rules + +import graphql.ExperimentalApi +import graphql.i18n.I18n +import graphql.language.Document +import graphql.parser.Parser +import graphql.validation.LanguageTraversal +import graphql.validation.RulesVisitor +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationContext +import graphql.validation.ValidationErrorCollector +import graphql.validation.ValidationErrorType +import spock.lang.Specification + +class DeferDirectiveOnValidOperationTest extends Specification { + ValidationErrorCollector errorCollector = new ValidationErrorCollector() + + def traverse(String query) { + Document document = new Parser().parseDocument(query) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(SpecValidationSchema.specValidationSchema, document, i18n) + validationContext.getGraphQLContext().put(ExperimentalApi.ENABLE_INCREMENTAL_SUPPORT, true) + LanguageTraversal languageTraversal = new LanguageTraversal() + languageTraversal.traverse(document, new RulesVisitor(validationContext, [new DeferDirectiveOnValidOperation(validationContext, errorCollector)])) + } + + def "Allow simple defer on query with fragment definition"() { + def query = ''' + query { + dog { + ... DogFields @defer + } + } + + fragment DogFields on Dog { + name + } + ''' + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + def "Allow simple defer on mutation with fragment definition"() { + def query = ''' + mutation { + createDog(input: {name: "Fido"}) { + ... DogFields @defer + } + } + + fragment DogFields on Dog { + name + } + ''' + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + def "Not allow defer on subscription operation"() { + given: + def query = """ + subscription pets { + dog { + ... @defer { + name + } + nickname + } + } + """ + + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + + } + + + def "Allow defer(if:false) on subscription operation"() { + given: + def query = """ + subscription pets { + dog { + ... @defer(if:false) { + name + } + nickname + } + } + """ + + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + + } + + def "Not allow simple defer on subscription with fragment definition"() { + def query = ''' + subscription { + dog { + ... DogFields @defer + } + } + + fragment DogFields on Dog { + name + } + ''' + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + + } + + def "Not allow defer on fragment when operation is subscription"() { + given: + def query = """ + fragment doggo on PetMutationType { + ... { + dog { + ... @defer { + id + } + nickname + } + + } + } + + subscription doggoMutation { + ...{ + ...doggo + } + } + + + """ + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + + } + + def "Allow defer(if:false) on fragment when operation is subscription"() { + given: + def query = """ + fragment doggo on PetMutationType { + ... { + dog { + ... @defer(if:false) { + id + } + nickname + } + + } + } + + subscription doggoMutation { + ...{ + ...doggo + } + } + + + """ + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + + } + + def "Not allow defer subscription even when there are multiple operations with multiple fragments"() { + given: + def query = """ + + fragment doggoSubscription on SubscriptionRoot { + ... { + dog { + ...doggo + } + } + } + + query pets { + ... @defer { + dog { + name + } + } + } + + subscription pets2 { + ...doggoSubscription + } + + query pets3 { + dog { + name + } + } + + fragment doggo on Dog{ + ... @defer { + name + } + } + """ + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.errors.get(0).getValidationErrorType() == ValidationErrorType.MisplacedDirective + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective@[doggoSubscription/dog/doggo]) : Directive 'defer' is not allowed to be used on operation subscription" + + } + + + def "Not allow defer subscription even when there are multiple operations and multiple fragments"() { + given: + def query = """ + query pets { + ... @defer { + dog { + name + } + } + } + + subscription pets2 { + dog { + ... @defer { + name + } + } + } + + + """ + + when: + traverse(query) + + then: + !errorCollector.errors.isEmpty() + errorCollector.errors.size() == 1 + errorCollector.errors.get(0).getValidationErrorType() == ValidationErrorType.MisplacedDirective + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective@[dog]) : Directive 'defer' is not allowed to be used on operation subscription" + + } + + def "Allows defer on mutation when it is not on root level"() { + given: + def query = """ + mutation pets { + dog { + ... @defer { + name + } + } + } + """ + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + + def "Allow defer on subscription when defer(if == false) "() { + given: + def query = """ + subscription pets{ + dog { + ... @defer(if:false) { + name + } + nickname + } + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + + } + + def "Not allow defer on subscription when defer(if == true) "() { + given: + def query = """ + subscription pets{ + dog { + ... @defer(if:true) { + name + } + nickname + } + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.size() == 1 + errorCollector.containsValidationError(ValidationErrorType.MisplacedDirective) + errorCollector.errors.get(0).message == "Validation error (MisplacedDirective@[dog]) : Directive 'defer' is not allowed to be used on operation subscription" + + + } + + def "Allow defer when if is variable that could have false as value "() { + given: + def query = """ + subscription pets(\$ifVar:Boolean){ + dog { + ... @defer(if:\$ifVar) { + name + } + nickname + } + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + + +} \ No newline at end of file diff --git a/src/test/groovy/graphql/validation/rules/ExecutableDefinitionsTest.groovy b/src/test/groovy/graphql/validation/rules/ExecutableDefinitionsTest.groovy index 7f96f87dad..4002b14ab4 100644 --- a/src/test/groovy/graphql/validation/rules/ExecutableDefinitionsTest.groovy +++ b/src/test/groovy/graphql/validation/rules/ExecutableDefinitionsTest.groovy @@ -2,13 +2,13 @@ package graphql.validation.rules import graphql.language.SourceLocation import graphql.parser.Parser +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationError import graphql.validation.ValidationErrorType import graphql.validation.Validator +import org.codehaus.groovy.runtime.StringGroovyMethods import spock.lang.Specification -import static graphql.validation.rules.ExecutableDefinitions.nonExecutableDefinitionMessage - class ExecutableDefinitionsTest extends Specification { def 'Executable Definitions with only operation'() { @@ -27,7 +27,7 @@ class ExecutableDefinitionsTest extends Specification { } def 'Executable Definitions with operation and fragment'() { - def query = """\ + def query = """ query Foo { dog { name @@ -47,7 +47,7 @@ class ExecutableDefinitionsTest extends Specification { } def 'Executable Definitions with type definition'() { - def query = """\ + def query = StringGroovyMethods.stripIndent(""" query Foo { dog { name @@ -61,20 +61,23 @@ class ExecutableDefinitionsTest extends Specification { extend type Dog { color: String } - """.stripIndent() + """) when: def validationErrors = validate(query) then: !validationErrors.empty validationErrors.size() == 2 - validationErrors[0] == nonExecutableDefinition("Cow", 7, 1) - validationErrors[1] == nonExecutableDefinition("Dog", 11, 1) - + validationErrors[0].validationErrorType == ValidationErrorType.NonExecutableDefinition + validationErrors[0].locations == [new SourceLocation(8, 1)] + validationErrors[0].message == "Validation error (NonExecutableDefinition) : Type 'Cow' definition is not executable" + validationErrors[1].validationErrorType == ValidationErrorType.NonExecutableDefinition + validationErrors[1].locations == [new SourceLocation(12, 1)] + validationErrors[1].message == "Validation error (NonExecutableDefinition) : Type 'Dog' definition is not executable" } def 'Executable Definitions with schema definition'() { - def query = """\ + def query = StringGroovyMethods.stripIndent(""" schema { query: QueryRoot } @@ -82,19 +85,23 @@ class ExecutableDefinitionsTest extends Specification { type QueryRoot { test: String } - """.stripIndent() + """) when: def validationErrors = validate(query) then: !validationErrors.empty validationErrors.size() == 2 - validationErrors[0] == nonExecutableDefinition("schema", 1, 1) - validationErrors[1] == nonExecutableDefinition("QueryRoot", 5, 1) + validationErrors[0].validationErrorType == ValidationErrorType.NonExecutableDefinition + validationErrors[0].locations == [new SourceLocation(2, 1)] + validationErrors[0].message == "Validation error (NonExecutableDefinition) : Schema definition is not executable" + validationErrors[1].validationErrorType == ValidationErrorType.NonExecutableDefinition + validationErrors[1].locations == [new SourceLocation(6, 1)] + validationErrors[1].message == "Validation error (NonExecutableDefinition) : Type 'QueryRoot' definition is not executable" } def 'Executable Definitions with input value type definition'() { - def query = """\ + def query = """ type QueryRoot { getDog(id: String!): String } @@ -105,18 +112,29 @@ class ExecutableDefinitionsTest extends Specification { then: !validationErrors.empty validationErrors.size() == 1 - validationErrors[0] == nonExecutableDefinition("QueryRoot", 1, 1) + validationErrors[0].validationErrorType == ValidationErrorType.NonExecutableDefinition + validationErrors[0].locations == [new SourceLocation(2, 1)] + validationErrors[0].message == "Validation error (NonExecutableDefinition) : Type 'QueryRoot' definition is not executable" } + def 'Executable Definitions with no directive definition'() { + def query = StringGroovyMethods.stripIndent(""" + directive @nope on INPUT_OBJECT + """) + when: + def document = new Parser().parseDocument(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) - ValidationError nonExecutableDefinition(String defName, int line, int column) { - return new ValidationError(ValidationErrorType.NonExecutableDefinition, - [new SourceLocation(line, column)], - nonExecutableDefinitionMessage(defName)) + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.NonExecutableDefinition + validationErrors[0].locations == [new SourceLocation(2, 1)] + validationErrors[0].message == "Validation error (NonExecutableDefinition) : Directive 'nope' definition is not executable" } - List validate(String query) { + static List validate(String query) { def document = new Parser().parseDocument(query) - return new Validator().validateDocument(Harness.Schema, document) + return new Validator().validateDocument(Harness.Schema, document, Locale.ENGLISH) } } diff --git a/src/test/groovy/graphql/validation/rules/FieldsOnCorrectTypeTest.groovy b/src/test/groovy/graphql/validation/rules/FieldsOnCorrectTypeTest.groovy index f16b804ae9..8bbb8052e3 100644 --- a/src/test/groovy/graphql/validation/rules/FieldsOnCorrectTypeTest.groovy +++ b/src/test/groovy/graphql/validation/rules/FieldsOnCorrectTypeTest.groovy @@ -1,11 +1,15 @@ package graphql.validation.rules import graphql.language.Field +import graphql.parser.Parser import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLObjectType +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class FieldsOnCorrectTypeTest extends Specification { @@ -28,7 +32,6 @@ class FieldsOnCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.FieldUndefined) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type FieldUndefined: Field 'name' in type 'parentType' is undefined" } def "should results in no error when field definition is filled"() { @@ -56,4 +59,138 @@ class FieldsOnCorrectTypeTest extends Specification { then: errorCollector.errors.isEmpty() } + + def '5.2.1 Field Selections on ... fieldNotDefined'() { + def query = """ +{ + dog { + ... fieldNotDefined + } +} +fragment fieldNotDefined on Dog { + meowVolume +} +""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined + validationErrors.get(0).message == "Validation error (FieldUndefined@[fieldNotDefined/meowVolume]) : Field 'meowVolume' in type 'Dog' is undefined" + } + + def '5.2.1 Field Selections on ... aliasedLyingFieldTargetNotDefined'() { + def query = """ +{ + dog { + ... aliasedLyingFieldTargetNotDefined + } +} +fragment aliasedLyingFieldTargetNotDefined on Dog { + barkVolume: kawVolume +} +""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined + validationErrors.get(0).message == "Validation error (FieldUndefined@[aliasedLyingFieldTargetNotDefined/kawVolume]) : Field 'kawVolume' in type 'Dog' is undefined" + } + + def '5.2.1 Field Selections on ... interfaceFieldSelection'() { + def query = """ +{ + dog { + ... interfaceFieldSelection + } +} +fragment interfaceFieldSelection on Pet { + name +} +""" + when: + def validationErrors = validate(query) + + then: + validationErrors.empty + } + + def '5.2.1 Field Selections on ... definedOnImplementorsButNotInterface'() { + def query = """ +{ + dog { + ... definedOnImplementorsButNotInterface + } +} +fragment definedOnImplementorsButNotInterface on Pet { + nickname +} +""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined + validationErrors.get(0).message == "Validation error (FieldUndefined@[definedOnImplementorsButNotInterface/nickname]) : Field 'nickname' in type 'Pet' is undefined" + } + + def '5.2.1 Field Selections on ... inDirectFieldSelectionOnUnion'() { + def query = """ +{ + dog { + ... inDirectFieldSelectionOnUnion + } +} +fragment inDirectFieldSelectionOnUnion on CatOrDog { + __typename + ... on Pet { + name + } + ... on Dog { + barkVolume + } +} +""" + when: + def validationErrors = validate(query) + + then: + validationErrors.empty + } + + def '5.2.1 Field Selections on ... directFieldSelectionOnUnion'() { + def query = """ +{ + dog { + ... directFieldSelectionOnUnion + } +} +fragment directFieldSelectionOnUnion on CatOrDog { + name + barkVolume +} +""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 2 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.FieldUndefined + validationErrors.get(0).message == "Validation error (FieldUndefined@[directFieldSelectionOnUnion/name]) : Field 'name' in type 'CatOrDog' is undefined" + validationErrors.get(1).getValidationErrorType() == ValidationErrorType.FieldUndefined + validationErrors.get(1).message == "Validation error (FieldUndefined@[directFieldSelectionOnUnion/barkVolume]) : Field 'barkVolume' in type 'CatOrDog' is undefined" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } } diff --git a/src/test/groovy/graphql/validation/rules/FragmentsOnCompositeTypeTest.groovy b/src/test/groovy/graphql/validation/rules/FragmentsOnCompositeTypeTest.groovy index 95f56bba9c..ccd918cbdb 100644 --- a/src/test/groovy/graphql/validation/rules/FragmentsOnCompositeTypeTest.groovy +++ b/src/test/groovy/graphql/validation/rules/FragmentsOnCompositeTypeTest.groovy @@ -1,10 +1,14 @@ package graphql.validation.rules +import graphql.ExecutionInput +import graphql.GraphQL import graphql.StarWarsSchema +import graphql.TestUtil import graphql.language.FragmentDefinition import graphql.language.InlineFragment import graphql.language.TypeName import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType import spock.lang.Specification @@ -26,7 +30,6 @@ class FragmentsOnCompositeTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.InlineFragmentTypeConditionInvalid) errorCollector.errors.size() == 1 - errorCollector.errors[0].message == "Validation error of type InlineFragmentTypeConditionInvalid: Inline fragment type condition is invalid, must be on Object/Interface/Union" } def "should results in no error"(InlineFragment inlineFragment) { @@ -68,8 +71,91 @@ class FragmentsOnCompositeTypeTest extends Specification { fragmentsOnCompositeType.checkFragmentDefinition(fragmentDefinition) then: - errorCollector.containsValidationError(ValidationErrorType.InlineFragmentTypeConditionInvalid) + errorCollector.containsValidationError(ValidationErrorType.FragmentTypeConditionInvalid) + } + + def schema = TestUtil.schema(""" + type Query { + nothing: String + } + + type Mutation { + updateUDI(input: UDIInput!): UDIOutput + } + + type UDIOutput { + device: String + version: String + } + + input UDIInput { + device: String + version: String + } + """) + + def graphQL = GraphQL.newGraphQL(schema).build() + + + def "#1440 when fragment type condition is input type it should return validation error - not classCastException"() { + when: + def executionInput = ExecutionInput.newExecutionInput() + .query(''' + mutation UpdateUDI($input: UDIInput!) { + updateUDI(input: $input) { + ...fragOnInputType + __typename + } + } + + # fragment should only target composite types + fragment fragOnInputType on UDIInput { + device + version + __typename + } + + ''') + .variables([input: [device: 'device', version: 'version'] ]) + .build() + + def executionResult = graphQL.execute(executionInput) + + then: + + executionResult.data == null + executionResult.errors.size() == 1 + (executionResult.errors[0] as ValidationError).validationErrorType == ValidationErrorType.FragmentTypeConditionInvalid + (executionResult.errors[0] as ValidationError).message == "Validation error (FragmentTypeConditionInvalid@[fragOnInputType]) : Fragment type condition is invalid, must be on Object/Interface/Union" } + def "#1440 when inline fragment type condition is input type it should return validation error - not classCastException"() { + when: + def executionInput = ExecutionInput.newExecutionInput() + .query(''' + mutation UpdateUDI($input: UDIInput!) { + updateUDI(input: $input) { + # fragment should only target composite types + ... on UDIInput { + device + version + __typename + } + __typename + } + } + ''') + .variables([input: [device: 'device', version: 'version'] ]) + .build() + + def executionResult = graphQL.execute(executionInput) + + then: + + executionResult.data == null + executionResult.errors.size() == 1 + (executionResult.errors[0] as ValidationError).validationErrorType == ValidationErrorType.InlineFragmentTypeConditionInvalid + (executionResult.errors[0] as ValidationError).message == "Validation error (InlineFragmentTypeConditionInvalid@[updateUDI]) : Inline fragment type condition is invalid, must be on Object/Interface/Union" + } } diff --git a/src/test/groovy/graphql/validation/rules/Harness.java b/src/test/groovy/graphql/validation/rules/Harness.java index 91a23defc8..2b233b77d0 100644 --- a/src/test/groovy/graphql/validation/rules/Harness.java +++ b/src/test/groovy/graphql/validation/rules/Harness.java @@ -1,6 +1,7 @@ package graphql.validation.rules; import graphql.schema.GraphQLEnumType; +import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; @@ -13,6 +14,7 @@ import static graphql.schema.GraphQLArgument.newArgument; import static graphql.schema.GraphQLEnumType.newEnum; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; +import static graphql.schema.GraphQLInputObjectField.newInputObjectField; import static graphql.schema.GraphQLInterfaceType.newInterface; import static graphql.schema.GraphQLList.list; import static graphql.schema.GraphQLObjectType.newObject; @@ -75,7 +77,7 @@ public class Harness { .argument(newArgument() .name("atOtherHomes") .type(GraphQLBoolean) - .defaultValue(true))) + .defaultValueProgrammatic(true))) .field(newFieldDefinition() .name("isAtLocation") .type(GraphQLBoolean) @@ -175,6 +177,13 @@ public class Harness { .typeResolver(dummyTypeResolve) .build(); + public static GraphQLInputObjectType Leash = GraphQLInputObjectType.newInputObject() + .name("LeashInput") + .field(newInputObjectField() + .name("id") + .type(GraphQLString)) + .build(); + public static GraphQLObjectType QueryRoot = newObject() .name("QueryRoot") .field(newFieldDefinition() @@ -192,6 +201,12 @@ public class Harness { .field(newFieldDefinition() .name("catOrDog") .type(CatOrDog)) + .field(newFieldDefinition() + .name("dogWithInput") + .argument(newArgument() + .name("leash") + .type(Leash)) + .type(Dog)) .field(newFieldDefinition() .name("dogOrHuman") @@ -204,7 +219,5 @@ public class Harness { public static GraphQLSchema Schema = newSchema() .query(QueryRoot) .build(); - - } diff --git a/src/test/groovy/graphql/validation/rules/KnownArgumentNamesTest.groovy b/src/test/groovy/graphql/validation/rules/KnownArgumentNamesTest.groovy index 3911b13c52..e437b43eda 100644 --- a/src/test/groovy/graphql/validation/rules/KnownArgumentNamesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/KnownArgumentNamesTest.groovy @@ -1,14 +1,19 @@ package graphql.validation.rules +import graphql.introspection.Introspection import graphql.language.Argument import graphql.language.BooleanValue import graphql.language.StringValue +import graphql.parser.Parser import graphql.schema.GraphQLArgument import graphql.schema.GraphQLDirective import graphql.schema.GraphQLFieldDefinition +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification import static graphql.Scalars.GraphQLBoolean @@ -48,7 +53,9 @@ class KnownArgumentNamesTest extends Specification { given: Argument argument = Argument.newArgument("unknownArg", BooleanValue.newBooleanValue(true).build()).build() def fieldDefinition = GraphQLFieldDefinition.newFieldDefinition().name("field").type(GraphQLString).build() - def directiveDefinition = GraphQLDirective.newDirective().name("directive") + def directiveDefinition = GraphQLDirective.newDirective() + .name("directive") + .validLocation(Introspection.DirectiveLocation.FIELD_DEFINITION) .argument(GraphQLArgument.newArgument().name("knownArg").type(GraphQLBoolean).build()).build() validationContext.getFieldDef() >> fieldDefinition validationContext.getDirective() >> directiveDefinition @@ -62,7 +69,9 @@ class KnownArgumentNamesTest extends Specification { given: Argument argument = Argument.newArgument("knownArg", BooleanValue.newBooleanValue(true).build()).build() def fieldDefinition = GraphQLFieldDefinition.newFieldDefinition().name("field").type(GraphQLString).build() - def directiveDefinition = GraphQLDirective.newDirective().name("directive") + def directiveDefinition = GraphQLDirective.newDirective() + .name("directive") + .validLocation(Introspection.DirectiveLocation.FIELD_DEFINITION) .argument(GraphQLArgument.newArgument().name("knownArg").type(GraphQLBoolean).build()).build() validationContext.getFieldDef() >> fieldDefinition validationContext.getDirective() >> directiveDefinition @@ -77,7 +86,9 @@ class KnownArgumentNamesTest extends Specification { Argument argument = Argument.newArgument("unknownArg", BooleanValue.newBooleanValue(true).build()).build() def fieldDefinition = GraphQLFieldDefinition.newFieldDefinition().name("field").type(GraphQLString) .argument(GraphQLArgument.newArgument().name("unknownArg").type(GraphQLString).build()).build() - def directiveDefinition = GraphQLDirective.newDirective().name("directive") + def directiveDefinition = GraphQLDirective.newDirective() + .name("directive") + .validLocation(Introspection.DirectiveLocation.FIELD_DEFINITION) .argument(GraphQLArgument.newArgument().name("knownArg").type(GraphQLBoolean).build()).build() validationContext.getFieldDef() >> fieldDefinition validationContext.getDirective() >> directiveDefinition @@ -86,4 +97,45 @@ class KnownArgumentNamesTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.UnknownDirective) } + + def "directive missing argument validation error with message"() { + def query = """ + query getDogName { + dog @dogDirective(notArgument: "value"){ + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownDirective + validationErrors.get(0).message == "Validation error (UnknownDirective@[dog]) : Unknown directive argument 'notArgument'" + } + + def "field missing argument validation error with message"() { + def query = """ + query getDog { + dog { + doesKnowCommand(dogCommand: SIT, notArgument: false) + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownArgument + validationErrors.get(0).message == "Validation error (UnknownArgument@[dog/doesKnowCommand]) : Unknown field argument 'notArgument'" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } } diff --git a/src/test/groovy/graphql/validation/rules/KnownDirectivesTest.groovy b/src/test/groovy/graphql/validation/rules/KnownDirectivesTest.groovy index 64c76444fe..8ac2b0d037 100644 --- a/src/test/groovy/graphql/validation/rules/KnownDirectivesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/KnownDirectivesTest.groovy @@ -1,6 +1,7 @@ package graphql.validation.rules import graphql.StarWarsSchema +import graphql.TestUtil import graphql.language.Document import graphql.parser.Parser import graphql.validation.LanguageTraversal @@ -9,6 +10,7 @@ import graphql.validation.TraversalContext import graphql.validation.ValidationContext import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class KnownDirectivesTest extends Specification { @@ -234,5 +236,74 @@ class KnownDirectivesTest extends Specification { } + def sdl = ''' + + directive @queryDirective on QUERY + + directive @subDirective on SUBSCRIPTION + + type Query { + field: String + } + + type Subscription { + field: String + } + + ''' + + def schema = TestUtil.schema(sdl) + + def "invalid directive on SUBSCRIPTION"() { + def spec = ''' + subscription sub @queryDirective{ + field + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 1 + validationErrors.get(0).validationErrorType == ValidationErrorType.MisplacedDirective + validationErrors.get(0).message == "Validation error (MisplacedDirective) : Directive 'queryDirective' not allowed here" + } + + def "unknown directive on SUBSCRIPTION"() { + def spec = ''' + subscription sub @unknownDirective{ + field + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 1 + validationErrors.get(0).validationErrorType == ValidationErrorType.UnknownDirective + validationErrors.get(0).message == "Validation error (UnknownDirective) : Unknown directive 'unknownDirective'" + } + + def "valid directive on SUBSCRIPTION"() { + def spec = ''' + subscription sub @subDirective{ + field + } + ''' + + when: + def document = TestUtil.parseQuery(spec) + def validator = new Validator() + def validationErrors = validator.validateDocument(schema, document, Locale.ENGLISH) + + then: + validationErrors.size() == 0 + } } diff --git a/src/test/groovy/graphql/validation/rules/KnownFragmentNamesTest.groovy b/src/test/groovy/graphql/validation/rules/KnownFragmentNamesTest.groovy index 6ef084edd6..5a56b13514 100644 --- a/src/test/groovy/graphql/validation/rules/KnownFragmentNamesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/KnownFragmentNamesTest.groovy @@ -1,9 +1,13 @@ package graphql.validation.rules import graphql.language.FragmentSpread +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class KnownFragmentNamesTest extends Specification { @@ -21,8 +25,28 @@ class KnownFragmentNamesTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.UndefinedFragment) - } + def '5.4.2.1 Fragment spread target defined '() { + def query = """ + query getDogName { + dog { + ... FragmentDoesNotExist + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UndefinedFragment + validationErrors.get(0).message == "Validation error (UndefinedFragment@[dog]) : Undefined fragment 'FragmentDoesNotExist'" + } + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } } diff --git a/src/test/groovy/graphql/validation/rules/KnownTypeNamesTest.groovy b/src/test/groovy/graphql/validation/rules/KnownTypeNamesTest.groovy index 0135d80a3e..fb84d8739d 100644 --- a/src/test/groovy/graphql/validation/rules/KnownTypeNamesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/KnownTypeNamesTest.groovy @@ -2,9 +2,13 @@ package graphql.validation.rules import graphql.StarWarsSchema import graphql.language.TypeName +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class KnownTypeNamesTest extends Specification { @@ -22,6 +26,61 @@ class KnownTypeNamesTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.UnknownType) + } + + def '5.7.3 Variables Are Input Types - unknown type'() { + def query = """ + query madDog(\$dogCommand: UnknownType){ + dog { + doesKnowCommand(dogCommand: \$dogCommand) + } + }""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownType + validationErrors.get(0).message == "Validation error (UnknownType) : Unknown type 'UnknownType'" + } + + def '5.7.3 Variables Are Input Types - non-null unknown type'() { + def query = """ + query madDog(\$dogCommand: UnknownType!){ + dog { + doesKnowCommand(dogCommand: \$dogCommand) + } + }""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownType + validationErrors.get(0).message == "Validation error (UnknownType) : Unknown type 'UnknownType'" + } + + def '5.7.3 Variables Are Input Types - non-null list unknown type'() { + def query = """ + query madDog(\$dogCommand: [UnknownType]){ + dog { + doesKnowCommand(dogCommand: \$dogCommand) + } + }""" + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnknownType + validationErrors.get(0).message == "Validation error (UnknownType) : Unknown type 'UnknownType'" + } + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) } } diff --git a/src/test/groovy/graphql/validation/rules/LoneAnonymousOperationTest.groovy b/src/test/groovy/graphql/validation/rules/LoneAnonymousOperationTest.groovy new file mode 100644 index 0000000000..f2543b7815 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/LoneAnonymousOperationTest.groovy @@ -0,0 +1,107 @@ +package graphql.validation.rules + +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class LoneAnonymousOperationTest extends Specification { + def '5.1.2.1 Lone Anonymous Operation Valid'() { + def query = """ + { + dog { + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + validationErrors.empty + } + + + def '5.1.2.1 Lone Anonymous Operation Not Valid'() { + def query = """ + { + dog { + name + } + } + + query getName { + dog { + owner { + name + } + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors[0].validationErrorType == ValidationErrorType.LoneAnonymousOperationViolation + validationErrors[0].message == "Validation error (LoneAnonymousOperationViolation) : Operation 'getName' is following anonymous operation" + } + + def '5.1.2.1 Lone Anonymous Operation Not Valid (reverse order) '() { + def query = """ + query getName { + dog { + owner { + name + } + } + } + + { + dog { + name + } + } + """ + + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors[0].validationErrorType == ValidationErrorType.LoneAnonymousOperationViolation + validationErrors[0].message == "Validation error (LoneAnonymousOperationViolation) : Anonymous operation with other operations" + } + + def '5.1.2.1 Lone Anonymous Operation Not Valid (not really alone)'() { + def query = """ + { + dog { + owner { + name + } + } + } + + { + dog { + name + } + } + """ + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors[0].validationErrorType == ValidationErrorType.LoneAnonymousOperationViolation + validationErrors[0].message == "Validation error (LoneAnonymousOperationViolation) : Anonymous operation with other operations" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } +} diff --git a/src/test/groovy/graphql/validation/rules/NoFragmentCyclesTest.groovy b/src/test/groovy/graphql/validation/rules/NoFragmentCyclesTest.groovy index 8fa32cb59d..ea3e1807f7 100644 --- a/src/test/groovy/graphql/validation/rules/NoFragmentCyclesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/NoFragmentCyclesTest.groovy @@ -1,6 +1,7 @@ package graphql.validation.rules import graphql.TestUtil +import graphql.i18n.I18n import graphql.language.Document import graphql.parser.Parser import graphql.validation.LanguageTraversal @@ -8,6 +9,7 @@ import graphql.validation.RulesVisitor import graphql.validation.ValidationContext import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class NoFragmentCyclesTest extends Specification { @@ -16,10 +18,10 @@ class NoFragmentCyclesTest extends Specification { def traverse(String query) { Document document = new Parser().parseDocument(query) - ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document, i18n) NoFragmentCycles noFragmentCycles = new NoFragmentCycles(validationContext, errorCollector) LanguageTraversal languageTraversal = new LanguageTraversal() - languageTraversal.traverse(document, new RulesVisitor(validationContext, [noFragmentCycles])) } @@ -46,7 +48,6 @@ class NoFragmentCyclesTest extends Specification { traverse(query) then: errorCollector.getErrors().isEmpty() - } def 'spreading twice indirectly is not circular'() { @@ -65,12 +66,12 @@ class NoFragmentCyclesTest extends Specification { def 'double spread within abstract types'() { given: def query = """ - fragment nameFragment on Pet { + fragment nameFragment on Pet { ... on Dog { name } ... on Cat { name } } - fragment spreadsInAnon on Pet { + fragment spreadsInAnon on Pet { ... on Dog { ...nameFragment } ... on Cat { ...nameFragment } } @@ -81,67 +82,118 @@ class NoFragmentCyclesTest extends Specification { errorCollector.getErrors().isEmpty() } + def "no spreading itself indirectly within inline fragment"() { + given: + def query = """ + fragment fragA on Pet { + ... on Dog { + ...fragB + } + } + fragment fragB on Pet { + ... on Dog { + ...fragA + } + } + """ + when: + traverse(query) + then: + errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) + errorCollector.getErrors()[0].message == "Validation error (FragmentCycle@[fragA]) : Fragment cycles not allowed" + } - def "circular fragments"() { + def "no spreading itself deeply two paths"() { given: def query = """ - fragment fragA on Dog { ...fragB } + fragment fragA on Dog { ...fragB, ...fragC } fragment fragB on Dog { ...fragA } + fragment fragC on Dog { ...fragA } """ - when: traverse(query) then: errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) - + errorCollector.getErrors()[0].message == "Validation error (FragmentCycle@[fragA]) : Fragment cycles not allowed" } + def "no self-spreading in floating fragments"() { + given: + def query = """ + fragment fragA on Dog { + ...fragA + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) + errorCollector.getErrors()[0].message == "Validation error (FragmentCycle@[fragA]) : Fragment cycles not allowed" + } - def 'no spreading itself directly'() { + def "no co-recursive spreads in floating fragments"() { given: def query = """ - fragment fragA on Dog { ...fragA } + fragment fragB on Dog { ...fragA } + fragment fragA on Dog { ...fragB } """ + when: traverse(query) + then: errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) + errorCollector.getErrors()[0].message == "Validation error (FragmentCycle@[fragB]) : Fragment cycles not allowed" + } + def "no co-recursive spreads in non-initial fragments"() { + given: + def query = """ + fragment fragA on Dog { ...fragB } + fragment fragB on Dog { ...fragC } + fragment fragC on Doc { ...fragB } + """ + + when: + traverse(query) + then: + errorCollector.containsValidationError((ValidationErrorType.FragmentCycle)) } - def "no spreading itself indirectly within inline fragment"() { + def "mix of inline fragments and fragments"() { given: def query = """ - fragment fragA on Pet { - ... on Dog { - ...fragB + fragment Foo on Foo { + ... on Type1 { ...Bar } + ... on Type2 { ...Baz } } - } - fragment fragB on Pet { - ... on Dog { - ...fragA - } - } + + fragment Bar on Bar { ...Baz } + fragment Baz on Baz { x } """ + when: traverse(query) then: - errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) - + errorCollector.getErrors().isEmpty() } - def "no spreading itself deeply two paths"() { + def "no self-spread fragments used in multiple operations"() { given: def query = """ - fragment fragA on Dog { ...fragB, ...fragC } - fragment fragB on Dog { ...fragA } - fragment fragC on Dog { ...fragA } + fragment fragA on Dog { ...fragA } + query A { ...fragA } + query B { ...fragA } """ + when: traverse(query) + then: errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) - + errorCollector.getErrors()[0].message == "Validation error (FragmentCycle@[fragA]) : Fragment cycles not allowed" } def "#583 no npe on undefined fragment"() { @@ -159,4 +211,31 @@ class NoFragmentCyclesTest extends Specification { errorCollector.getErrors().isEmpty() } + def "#1817 no stack overflow on circular fragment"() { + given: + def query = """ + query { + ...MyFrag + } + fragment MyFrag on QueryType { + field + ...MyFrag + } + """ + + def document = Parser.parse(query) + + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + def validationContext = new ValidationContext(TestUtil.dummySchema, document, i18n) + def rules = new Validator().createRules(validationContext, errorCollector) + when: + LanguageTraversal languageTraversal = new LanguageTraversal() + languageTraversal.traverse(document, new RulesVisitor(validationContext, rules)) + + then: + + !errorCollector.getErrors().isEmpty() + errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) + errorCollector.getErrors()[0].message == "Validation error (FragmentCycle@[MyFrag]) : Fragment cycles not allowed" + } } diff --git a/src/test/groovy/graphql/validation/rules/NoUndefinedVariablesTest.groovy b/src/test/groovy/graphql/validation/rules/NoUndefinedVariablesTest.groovy index 0727651fd1..90f9976a4d 100644 --- a/src/test/groovy/graphql/validation/rules/NoUndefinedVariablesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/NoUndefinedVariablesTest.groovy @@ -1,6 +1,7 @@ package graphql.validation.rules import graphql.TestUtil +import graphql.i18n.I18n import graphql.language.Document import graphql.parser.Parser import graphql.validation.LanguageTraversal @@ -11,21 +12,18 @@ import graphql.validation.ValidationErrorType import spock.lang.Specification class NoUndefinedVariablesTest extends Specification { - - ValidationErrorCollector errorCollector = new ValidationErrorCollector() - def traverse(String query) { Document document = new Parser().parseDocument(query) - ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document, i18n) NoUndefinedVariables noUndefinedVariables = new NoUndefinedVariables(validationContext, errorCollector) LanguageTraversal languageTraversal = new LanguageTraversal() languageTraversal.traverse(document, new RulesVisitor(validationContext, [noUndefinedVariables])) } - def "undefined variable"() { given: def query = """ @@ -39,10 +37,10 @@ class NoUndefinedVariablesTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.UndefinedVariable) - + errorCollector.getErrors()[0].message == "Validation error (UndefinedVariable@[field]) : Undefined variable 'd'" } - def "all variables definied"() { + def "all variables defined"() { given: def query = """ query Foo(\$a: String, \$b: String, \$c: String) { @@ -55,7 +53,6 @@ class NoUndefinedVariablesTest extends Specification { then: errorCollector.errors.isEmpty() - } def "all variables in fragments deeply defined"() { @@ -86,7 +83,7 @@ class NoUndefinedVariablesTest extends Specification { errorCollector.errors.isEmpty() } - def 'variable in fragment not defined by operation'() { + def "variable in fragment not defined by operation"() { given: def query = """ query Foo(\$a: String, \$b: String) { @@ -111,6 +108,77 @@ class NoUndefinedVariablesTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.UndefinedVariable) + errorCollector.getErrors()[0].message == "Validation error (UndefinedVariable@[FragA/field/FragB/field/FragC/field]) : Undefined variable 'c'" + } + + def "floating fragment with variables"() { + given: + def query = """ + fragment A on Type { + field(a: \$a) + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + def "multiple operations and completely defined variables"() { + given: + def query = """ + query Foo(\$a: String) { ...A } + query Bar(\$a: String) { ...A } + + fragment A on Type { + field(a: \$a) + } + """ + + when: + traverse(query) + then: + errorCollector.errors.isEmpty() + } + + def "multiple operations and mixed variable definitions"() { + given: + def query = """ + query Foo(\$a: String) { ...A } + query Bar { ...A } + + fragment A on Type { + field(a: \$a) + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.UndefinedVariable) + errorCollector.getErrors()[0].message == "Validation error (UndefinedVariable@[A/field]) : Undefined variable 'a'" + } + + def "multiple operations with undefined variables"() { + given: + def query = """ + query Foo { ...A } + query Bar { ...A } + + fragment A on Type { + field(a: \$a) + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.UndefinedVariable) + errorCollector.getErrors()[0].message == "Validation error (UndefinedVariable@[A/field]) : Undefined variable 'a'" } } diff --git a/src/test/groovy/graphql/validation/rules/NoUnusedFragmentsTest.groovy b/src/test/groovy/graphql/validation/rules/NoUnusedFragmentsTest.groovy index c6a12eec02..3fde31a3fb 100644 --- a/src/test/groovy/graphql/validation/rules/NoUnusedFragmentsTest.groovy +++ b/src/test/groovy/graphql/validation/rules/NoUnusedFragmentsTest.groovy @@ -4,10 +4,13 @@ import graphql.language.Document import graphql.parser.Parser import graphql.validation.LanguageTraversal import graphql.validation.RulesVisitor +import graphql.validation.SpecValidationSchema import graphql.validation.TraversalContext import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class NoUnusedFragmentsTest extends Specification { @@ -174,4 +177,28 @@ class NoUnusedFragmentsTest extends Specification { errorCollector.containsValidationError(ValidationErrorType.UnusedFragment) errorCollector.getErrors().size() == 2 } + + def "contains unused fragment with error message"() { + def query = """ + query getDogName { + dog { + name + } + } + fragment dogFragment on Dog { barkVolume } + """.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.UnusedFragment + validationErrors[0].message == "Validation error (UnusedFragment) : Unused fragment 'dogFragment'" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } } \ No newline at end of file diff --git a/src/test/groovy/graphql/validation/rules/NoUnusedVariablesTest.groovy b/src/test/groovy/graphql/validation/rules/NoUnusedVariablesTest.groovy index df6e431e21..9b7d0dc8de 100644 --- a/src/test/groovy/graphql/validation/rules/NoUnusedVariablesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/NoUnusedVariablesTest.groovy @@ -1,32 +1,32 @@ package graphql.validation.rules import graphql.TestUtil +import graphql.i18n.I18n import graphql.language.Document import graphql.parser.Parser import graphql.validation.LanguageTraversal import graphql.validation.RulesVisitor +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification class NoUnusedVariablesTest extends Specification { - - ValidationErrorCollector errorCollector = new ValidationErrorCollector() - def traverse(String query) { Document document = new Parser().parseDocument(query) - ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(TestUtil.dummySchema, document, i18n) NoUnusedVariables noUnusedVariables = new NoUnusedVariables(validationContext, errorCollector) LanguageTraversal languageTraversal = new LanguageTraversal() languageTraversal.traverse(document, new RulesVisitor(validationContext, [noUnusedVariables])) } - - def 'uses all variables in fragments'() { + def "uses all variables in fragments"() { given: def query = """ fragment FragA on Type { @@ -56,7 +56,7 @@ class NoUnusedVariablesTest extends Specification { def "variable used by fragment in multiple operations"() { given: def query = """ - query Foo(\$a: String) { + query Foo(\$a: String) { ...FragA } query Bar(\$b: String) { @@ -68,7 +68,7 @@ class NoUnusedVariablesTest extends Specification { fragment FragB on Type { field(b: \$b) } - """ + """ when: traverse(query) @@ -89,8 +89,52 @@ class NoUnusedVariablesTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.UnusedVariable) + } + + def "variables not used in fragments"() { + given: + def query = """ + fragment FragA on Type { + field(a: \$a) { + ...FragB + } + } + fragment FragB on Type { + field(b: \$b) { + ...FragC + } + } + fragment FragC on Type { + __typename + } + query Foo(\$a: String, \$b: String, \$c: String) { + ...FragA + } + """ + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.UnusedVariable) } + def "variables not used in fragments with error message"() { + def query = ''' + query getDogName($arg1: String, $unusedArg: Int) { + dog(arg1: $arg1) { + name + } + } + ''' + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.UnusedVariable + validationErrors.get(0).message == "Validation error (UnusedVariable) : Unused variable 'unusedArg'" + } } diff --git a/src/test/groovy/graphql/validation/rules/OverlappingFieldsCanBeMergedTest.groovy b/src/test/groovy/graphql/validation/rules/OverlappingFieldsCanBeMergedTest.groovy index fd84bdf574..d35ec38084 100644 --- a/src/test/groovy/graphql/validation/rules/OverlappingFieldsCanBeMergedTest.groovy +++ b/src/test/groovy/graphql/validation/rules/OverlappingFieldsCanBeMergedTest.groovy @@ -1,12 +1,11 @@ package graphql.validation.rules -import graphql.TypeResolutionEnvironment +import graphql.i18n.I18n import graphql.language.Document import graphql.language.SourceLocation import graphql.parser.Parser -import graphql.schema.GraphQLObjectType +import graphql.schema.GraphQLCodeRegistry import graphql.schema.GraphQLSchema -import graphql.schema.TypeResolver import graphql.validation.LanguageTraversal import graphql.validation.RulesVisitor import graphql.validation.ValidationContext @@ -15,6 +14,7 @@ import spock.lang.Specification import static graphql.Scalars.GraphQLInt import static graphql.Scalars.GraphQLString +import static graphql.TestUtil.schema import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition import static graphql.schema.GraphQLList.list import static graphql.schema.GraphQLNonNull.nonNull @@ -25,7 +25,6 @@ class OverlappingFieldsCanBeMergedTest extends Specification { ValidationErrorCollector errorCollector = new ValidationErrorCollector() - def traverse(String query, GraphQLSchema schema) { if (schema == null) { def objectType = newObject() @@ -37,7 +36,8 @@ class OverlappingFieldsCanBeMergedTest extends Specification { } Document document = new Parser().parseDocument(query) - ValidationContext validationContext = new ValidationContext(schema, document) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(schema, document, i18n) OverlappingFieldsCanBeMerged overlappingFieldsCanBeMerged = new OverlappingFieldsCanBeMerged(validationContext, errorCollector) LanguageTraversal languageTraversal = new LanguageTraversal() @@ -47,6 +47,7 @@ class OverlappingFieldsCanBeMergedTest extends Specification { def "identical fields are ok"() { given: def query = """ + {...f} fragment f on Test{ name name @@ -59,9 +60,22 @@ class OverlappingFieldsCanBeMergedTest extends Specification { errorCollector.errors.isEmpty() } + def "identical fields are ok 2"() { + given: + def query = """ + { name name name name: name} + """ + when: + traverse(query, null) + + then: + errorCollector.errors.isEmpty() + } + def "two aliases with different targets"() { given: def query = """ + {... f } fragment f on Test{ myName : name myName : nickname @@ -72,11 +86,11 @@ class OverlappingFieldsCanBeMergedTest extends Specification { then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: myName: name and nickname are different fields @ 'f'" - errorCollector.getErrors()[0].locations == [new SourceLocation(3, 17), new SourceLocation(4, 17)] + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'myName' : 'name' and 'nickname' are different fields" + errorCollector.getErrors()[0].locations == [new SourceLocation(4, 17), new SourceLocation(5, 17)] } - GraphQLSchema unionSchema() { + static GraphQLSchema unionSchema() { def StringBox = newObject().name("StringBox") .field(newFieldDefinition().name("scalar").type(GraphQLString)) .build() @@ -99,17 +113,18 @@ class OverlappingFieldsCanBeMergedTest extends Specification { def BoxUnion = newUnionType() .name("BoxUnion") .possibleTypes(StringBox, IntBox, NonNullStringBox1, NonNullStringBox2, ListStringBox1) - .typeResolver(new TypeResolver() { - @Override - GraphQLObjectType getType(TypeResolutionEnvironment env) { - return null - } - }) + .build() + def codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .typeResolver(BoxUnion, { env -> null }) .build() def QueryRoot = newObject() .name("QueryRoot") .field(newFieldDefinition().name("boxUnion").type(BoxUnion)).build() - return GraphQLSchema.newSchema().query(QueryRoot).build() + + return GraphQLSchema.newSchema() + .codeRegistry(codeRegistry) + .query(QueryRoot) + .build() } def 'conflicting scalar return types'() { @@ -133,7 +148,7 @@ class OverlappingFieldsCanBeMergedTest extends Specification { then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: scalar: they return differing types Int and String @ 'boxUnion'" + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'boxUnion/scalar' : returns different types 'Int' and 'String'" } @@ -181,7 +196,7 @@ class OverlappingFieldsCanBeMergedTest extends Specification { then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: scalar: fields have different nullability shapes @ 'boxUnion'" + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'boxUnion/scalar' : fields have different nullability shapes" } def 'not the same list return types'() { @@ -205,7 +220,7 @@ class OverlappingFieldsCanBeMergedTest extends Specification { then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: scalar: fields have different list shapes @ 'boxUnion'" + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'boxUnion/scalar' : fields have different list shapes" } @@ -302,52 +317,132 @@ class OverlappingFieldsCanBeMergedTest extends Specification { def 'Same aliases with different field targets'() { given: def query = """ + {dog{...sameAliasesWithDifferentFieldTargets}} fragment sameAliasesWithDifferentFieldTargets on Dog { fido: name fido: nickname } """ + def schema = schema(''' + type Dog { + name: String + nickname: String + } + type Query { + dog: Dog + } + ''') when: - traverse(query, null) + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: fido: name and nickname are different fields @ 'sameAliasesWithDifferentFieldTargets'" - errorCollector.getErrors()[0].locations == [new SourceLocation(3, 13), new SourceLocation(4, 13)] + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'dog/fido' : 'name' and 'nickname' are different fields" + errorCollector.getErrors()[0].locations == [new SourceLocation(4, 13), new SourceLocation(5, 13)] } def 'Alias masking direct field access'() { given: def query = """ + {dog{...aliasMaskingDirectFieldAccess}} fragment aliasMaskingDirectFieldAccess on Dog { name: nickname name } """ + def schema = schema(''' + type Dog { + nickname: String + name : String + } + type Query { dog: Dog } + ''') when: - traverse(query, null) + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: name: nickname and name are different fields @ 'aliasMaskingDirectFieldAccess'" + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'dog/name' : 'nickname' and 'name' are different fields" + errorCollector.getErrors()[0].locations == [new SourceLocation(4, 13), new SourceLocation(5, 13)] + } + + def 'issue 3332 - Alias masking direct field access non fragment'() { + given: + def query = """ + { dog { + name: nickname + name + }} + """ + def schema = schema(''' + type Dog { + name : String + nickname: String + } + type Query { dog: Dog } + ''') + when: + traverse(query, schema) + + then: + errorCollector.getErrors().size() == 1 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'dog/name' : 'nickname' and 'name' are different fields" errorCollector.getErrors()[0].locations == [new SourceLocation(3, 13), new SourceLocation(4, 13)] } + def 'issue 3332 -Alias masking direct field access non fragment with non null parent type'() { + given: + def query = """ + query GetCat { + cat { + foo1 + foo1: foo2 + } + } + """ + def schema = schema(''' + type Query { + cat: Cat! # non null parent type + } + type Cat { + foo1: String! + foo2: String! + } + ''') + when: + traverse(query, schema) + + then: + errorCollector.getErrors().size() == 1 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'cat/foo1' : 'foo1' and 'foo2' are different fields" + errorCollector.getErrors()[0].locations == [new SourceLocation(4, 17), new SourceLocation(5, 17)] + } + def 'conflicting args'() { given: def query = """ + {dog{...conflictingArgs}} fragment conflictingArgs on Dog { doesKnowCommand(dogCommand: SIT) doesKnowCommand(dogCommand: HEEL) } """ + def schema = schema(''' + type Dog { + doesKnowCommand(dogCommand: DogCommand): String + } + enum DogCommand { SIT, HEEL } + type Query { + dog: Dog + } + ''') when: - traverse(query, null) + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: doesKnowCommand: they have differing arguments @ 'conflictingArgs'" - errorCollector.getErrors()[0].locations == [new SourceLocation(3, 13), new SourceLocation(4, 13)] + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'dog/doesKnowCommand' : fields have different arguments" + errorCollector.getErrors()[0].locations == [new SourceLocation(4, 13), new SourceLocation(5, 13)] } // @@ -384,12 +479,22 @@ class OverlappingFieldsCanBeMergedTest extends Specification { x: b } """ + def schema = schema(''' + type Type { + a: String + b: String + c: String + } + schema { + query: Type + } + ''') when: - traverse(query, null) + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: x: a and b are different fields" + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'x' : 'a' and 'b' are different fields" errorCollector.getErrors()[0].locations == [new SourceLocation(7, 13), new SourceLocation(10, 13)] } @@ -417,20 +522,27 @@ class OverlappingFieldsCanBeMergedTest extends Specification { x: b } """ + def schema = schema(''' + type Type { + a: String + b: String + c: String + } + type Query { + f1: Type + f2: Type + f3: Type + } + ''') + when: - traverse(query, null) + traverse(query, schema) then: - errorCollector.getErrors().size() == 3 + errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: x: a and b are different fields @ 'f1'" + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'f1/x' : 'a' and 'b' are different fields" errorCollector.getErrors()[0].locations == [new SourceLocation(18, 13), new SourceLocation(21, 13)] - - errorCollector.getErrors()[1].message == "Validation error of type FieldsConflict: x: a and c are different fields @ 'f3'" - errorCollector.getErrors()[1].locations == [new SourceLocation(18, 13), new SourceLocation(14, 17)] - - errorCollector.getErrors()[2].message == "Validation error of type FieldsConflict: x: b and c are different fields @ 'f3'" - errorCollector.getErrors()[2].locations == [new SourceLocation(21, 13), new SourceLocation(14, 17)] } @@ -446,12 +558,21 @@ class OverlappingFieldsCanBeMergedTest extends Specification { } """ when: - traverse(query, null) + def schema = schema(''' + type Type { + a: String + b: String + } + type Query { + field: Type + } + ''') + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: field: (x: a and b are different fields)" - errorCollector.getErrors()[0].locations.size() == 4 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'field/x' : 'a' and 'b' are different fields" + errorCollector.getErrors()[0].locations.size() == 2 } def 'deep conflict with multiple issues'() { @@ -467,13 +588,28 @@ class OverlappingFieldsCanBeMergedTest extends Specification { } } """ + def schema = schema(''' + type Type { + a: String + b: String + c: String + d: String + } + type Query { + field: Type + } + ''') + when: - traverse(query, null) + traverse(query, schema) then: - errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: field: (x: a and b are different fields, y: c and d are different fields)" - errorCollector.getErrors()[0].locations.size() == 6 + errorCollector.getErrors().size() == 2 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'field/x' : 'a' and 'b' are different fields" + errorCollector.getErrors()[0].locations.size() == 2 + + errorCollector.getErrors()[1].message == "Validation error (FieldsConflict) : 'field/y' : 'c' and 'd' are different fields" + errorCollector.getErrors()[1].locations.size() == 2 } def 'very deep conflict'() { @@ -492,13 +628,27 @@ class OverlappingFieldsCanBeMergedTest extends Specification { } } """ + def schema = schema(''' + type Type { + a: String + b: String + c: String + d: String + } + type Field { + deepField: Type + } + type Query { + field: Field + } + ''') when: - traverse(query, null) + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: field: (deepField: (x: a and b are different fields))" - errorCollector.getErrors()[0].locations.size() == 6 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'field/deepField/x' : 'a' and 'b' are different fields" + errorCollector.getErrors()[0].locations.size() == 2 } def 'reports deep conflict to nearest common ancestor'() { @@ -519,13 +669,353 @@ class OverlappingFieldsCanBeMergedTest extends Specification { } } """ + def schema = schema(''' + type Type { + a: String + b: String + c: String + d: String + } + type Field { + deepField: Type + } + type Query { + field: Field + } + ''') + when: - traverse(query, null) + traverse(query, schema) then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors()[0].message == "Validation error of type FieldsConflict: deepField: (x: a and b are different fields) @ 'field'" - errorCollector.getErrors()[0].locations.size() == 4 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'field/deepField/x' : 'a' and 'b' are different fields" + errorCollector.getErrors()[0].locations.size() == 2 + } + + + def "parent type is of List NonNull"() { + given: + def query = """ + query (\$id: String!) { + services(ids: [\$id]) { + componentInfoLocationUrl + ...ComponentInformation + } + } + + fragment ComponentInformation on Component { + componentInfoLocationUrl + } +""" + def schema = schema(""" + type Query { + services(ids: [String!]): [Component!] } + type Component { + componentInfoLocationUrl: String! + } +""") + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 0 + + } + + def "parent type is of List List NonNull"() { + given: + def query = """ + query (\$id: String!) { + services(ids: [\$id]) { + componentInfoLocationUrl + ...ComponentInformation + } + } + + fragment ComponentInformation on Component { + componentInfoLocationUrl + } +""" + def schema = schema(""" + type Query { + services(ids: [String!]): [[Component!]] + } + + type Component { + componentInfoLocationUrl: String! + } +""") + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 0 + + } + + def "parent type is of List NonNull and field is nullable"() { + given: + def query = """ + query (\$id: String!) { + services(ids: [\$id]) { + componentInfoLocationUrl + ...ComponentInformation + } + } + + fragment ComponentInformation on Component { + componentInfoLocationUrl + } +""" + def schema = schema(""" + type Query { + services(ids: [String!]): [Component!] + } + + type Component { + componentInfoLocationUrl: String + } +""") + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 0 + + } + + def "valid diverging fields with the same parent type on deeper level"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + name : String + friends: [Pet] + + } + ''') + /** + * Here F1 and F2 are allowed to diverge (backed by different field definitions) because the parent fields have + * different concrete parent: P1 has Dog, P2 has Cat. + */ + def query = ''' +{ + pets { + ... on Dog { + friends { #P1 + name + ... on Dog { + breed: dogBreed #F1 + } + } + } + ... on Cat { + friends { #P2 + name + ... on Dog { + breed #F2 + } + } + } + ... on Pet { + friends { + name + } + } + } +} + ''' + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 0 + } + + def "children of diverging fields still need to have same response shape"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + age: Int + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + height: Float + name : String + friends: [Pet] + + } + ''') + def query = ''' + { + pets { + ... on Dog { + friends { + ... on Dog { + conflict: age + } + } + } + ... on Cat { + friends { + ... on Cat { + conflict: height + } + } + } + } + } + ''' + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 1 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'pets/friends/conflict' : returns different types 'Int' and 'Float'" + } + + + def "subselection of fields with different concrete parent can be different "() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + age: Int + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + height: Float + name : String + friends: [Pet] + + } + ''') + def query = ''' + { + pets { + ... on Dog { + friends { + name + } + } + ... on Cat { + friends { + breed + } + } + } + } + ''' + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 0 + } + + def "overlapping fields on lower level"() { + given: + def schema = schema(''' + type Query { + pets: [Pet] + } + interface Pet { + name: String + breed: String + friends: [Pet] + } + type Dog implements Pet { + name: String + age: Int + dogBreed: String + breed: String + friends: [Pet] + + } + type Cat implements Pet { + catBreed: String + breed: String + height: Float + name : String + friends: [Pet] + + } + ''') + def query = ''' + { + pets { + friends { + ... on Dog { + x: name + } + ... on Cat { + x: height + } + } + } + } + ''' + when: + traverse(query, schema) + + + then: + errorCollector.getErrors().size() == 1 + errorCollector.getErrors()[0].message == "Validation error (FieldsConflict) : 'pets/friends/x' : returns different types 'String' and 'Float'" + + } + + } diff --git a/src/test/groovy/graphql/validation/rules/PossibleFragmentSpreadsTest.groovy b/src/test/groovy/graphql/validation/rules/PossibleFragmentSpreadsTest.groovy index b7b6b101c0..87c465fd38 100644 --- a/src/test/groovy/graphql/validation/rules/PossibleFragmentSpreadsTest.groovy +++ b/src/test/groovy/graphql/validation/rules/PossibleFragmentSpreadsTest.groovy @@ -1,5 +1,6 @@ package graphql.validation.rules +import graphql.i18n.I18n import graphql.language.Document import graphql.parser.Parser import graphql.validation.LanguageTraversal @@ -15,7 +16,8 @@ class PossibleFragmentSpreadsTest extends Specification { def traverse(String query) { Document document = new Parser().parseDocument(query) - ValidationContext validationContext = new ValidationContext(Harness.Schema, document) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + ValidationContext validationContext = new ValidationContext(Harness.Schema, document, i18n) PossibleFragmentSpreads possibleFragmentSpreads = new PossibleFragmentSpreads(validationContext, errorCollector) LanguageTraversal languageTraversal = new LanguageTraversal() @@ -179,7 +181,7 @@ class PossibleFragmentSpreadsTest extends Specification { then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors().get(0).message == 'Validation error of type InvalidFragmentType: Fragment cannot be spread here as objects of type Cat can never be of type Dog @ \'invalidObjectWithinObjectAnon\'' + errorCollector.getErrors().get(0).message == "Validation error (InvalidFragmentType@[invalidObjectWithinObjectAnon]) : Fragment cannot be spread here as objects of type 'Cat' can never be of type 'Dog'" } def 'object into not implementing interface'() { @@ -192,7 +194,7 @@ class PossibleFragmentSpreadsTest extends Specification { then: errorCollector.getErrors().size() == 1 - errorCollector.getErrors().get(0).message == 'Validation error of type InvalidFragmentType: Fragment humanFragment cannot be spread here as objects of type Pet can never be of type Human @ \'invalidObjectWithinInterface\'' + errorCollector.getErrors().get(0).message == "Validation error (InvalidFragmentType@[invalidObjectWithinInterface]) : Fragment 'humanFragment' cannot be spread here as objects of type 'Pet' can never be of type 'Human'" } def 'object into not containing union'() { @@ -297,4 +299,42 @@ class PossibleFragmentSpreadsTest extends Specification { } + def 'when fragment target type is not composite type do not error - FragmentsOnCompositeType takes care of the validation'() { + setup: "LeashInput is an input type so it shouldn't be target-able" + def query = """ + query { + dogWithInput { + ...LeashInputFragment + } + } + + fragment LeashInputFragment on LeashInput { + id + } + """ + when: + traverse(query) + + then: + errorCollector.getErrors().isEmpty() + } + + def 'when inline fragment target type is not composite type do not error - FragmentsOnCompositeType takes care of the validation'() { + setup: "LeashInput is an input type so it shouldn't be target-able" + def query = """ + query { + dogWithInput { + ...on LeashInput { + id + } + } + } + """ + when: + traverse(query) + + then: + errorCollector.getErrors().isEmpty() + } + } diff --git a/src/test/groovy/graphql/validation/rules/ProvidedNonNullArgumentsTest.groovy b/src/test/groovy/graphql/validation/rules/ProvidedNonNullArgumentsTest.groovy index 6873811ac0..9a11066973 100644 --- a/src/test/groovy/graphql/validation/rules/ProvidedNonNullArgumentsTest.groovy +++ b/src/test/groovy/graphql/validation/rules/ProvidedNonNullArgumentsTest.groovy @@ -1,16 +1,22 @@ package graphql.validation.rules +import graphql.introspection.Introspection import graphql.language.Argument import graphql.language.Directive import graphql.language.Field +import graphql.language.NullValue import graphql.language.StringValue +import graphql.parser.Parser import graphql.schema.GraphQLArgument import graphql.schema.GraphQLDirective import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLNonNull +import graphql.validation.SpecValidationSchema import graphql.validation.ValidationContext +import graphql.validation.ValidationError import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification import static graphql.Scalars.GraphQLString @@ -21,9 +27,10 @@ class ProvidedNonNullArgumentsTest extends Specification { ValidationErrorCollector errorCollector = new ValidationErrorCollector() ProvidedNonNullArguments providedNonNullArguments = new ProvidedNonNullArguments(validationContext, errorCollector) - def "not provided field argument"() { + def "not provided and not defaulted non null field argument"() { given: - def fieldArg = GraphQLArgument.newArgument().name("arg").type(GraphQLNonNull.nonNull(GraphQLString)) + def fieldArg = GraphQLArgument.newArgument().name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)) def fieldDef = GraphQLFieldDefinition.newFieldDefinition() .name("field") .type(GraphQLString) @@ -40,10 +47,49 @@ class ProvidedNonNullArgumentsTest extends Specification { errorCollector.containsValidationError(ValidationErrorType.MissingFieldArgument) } + def "not provided and not defaulted non null field argument with error message"() { + def query = """ + query getDogName { + dog { + doesKnowCommand + } + } + """.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.MissingFieldArgument + validationErrors[0].message == "Validation error (MissingFieldArgument@[dog/doesKnowCommand]) : Missing field argument 'dogCommand'" + } + + def "not provided and but defaulted non null field argument"() { + given: + def fieldArg = GraphQLArgument.newArgument().name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)) + .defaultValueProgrammatic("defaultVal") + def fieldDef = GraphQLFieldDefinition.newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(fieldArg) + .build() + validationContext.getFieldDef() >> fieldDef + + def field = new Field("field") + + when: + providedNonNullArguments.checkField(field) + + then: + errorCollector.getErrors().isEmpty() + } def "all field arguments are provided"() { given: - def fieldArg = GraphQLArgument.newArgument().name("arg").type(GraphQLNonNull.nonNull(GraphQLString)) + def fieldArg = GraphQLArgument.newArgument().name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)) def fieldDef = GraphQLFieldDefinition.newFieldDefinition() .name("field") .type(GraphQLString) @@ -60,11 +106,13 @@ class ProvidedNonNullArgumentsTest extends Specification { errorCollector.getErrors().isEmpty() } - def "not provided directive argument"() { + def "not provided not defaulted directive argument"() { given: - def directiveArg = GraphQLArgument.newArgument().name("arg").type(GraphQLNonNull.nonNull(GraphQLString)) + def directiveArg = GraphQLArgument.newArgument() + .name("arg").type(GraphQLNonNull.nonNull(GraphQLString)) def graphQLDirective = GraphQLDirective.newDirective() .name("directive") + .validLocation(Introspection.DirectiveLocation.SCALAR) .argument(directiveArg) .build() validationContext.getDirective() >> graphQLDirective @@ -78,12 +126,51 @@ class ProvidedNonNullArgumentsTest extends Specification { errorCollector.containsValidationError(ValidationErrorType.MissingDirectiveArgument) } + def "not provided and not defaulted non null directive argument with error message"() { + def query = """ + query getDogName { + dog @nonNullDirective { + name + } + } + """.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.MissingDirectiveArgument + validationErrors[0].message == "Validation error (MissingDirectiveArgument@[dog]) : Missing directive argument 'arg1'" + } + + def "not provided but defaulted directive argument"() { + given: + def directiveArg = GraphQLArgument.newArgument() + .name("arg").type(GraphQLNonNull.nonNull(GraphQLString)) + .defaultValueProgrammatic("defaultVal") + def graphQLDirective = GraphQLDirective.newDirective() + .name("directive") + .validLocation(Introspection.DirectiveLocation.SCALAR) + .argument(directiveArg) + .build() + validationContext.getDirective() >> graphQLDirective + + def directive = new Directive("directive") + + when: + providedNonNullArguments.checkDirective(directive, []) + + then: + errorCollector.getErrors().isEmpty() + } def "all directive arguments are provided"() { given: def directiveArg = GraphQLArgument.newArgument().name("arg").type(GraphQLNonNull.nonNull(GraphQLString)) def graphQLDirective = GraphQLDirective.newDirective() .name("directive") + .validLocation(Introspection.DirectiveLocation.SCALAR) .argument(directiveArg) .build() validationContext.getDirective() >> graphQLDirective @@ -97,4 +184,50 @@ class ProvidedNonNullArgumentsTest extends Specification { then: errorCollector.getErrors().isEmpty() } + + def "provide the explicit value null is not valid for non null argument"() { + given: + def fieldArg = GraphQLArgument.newArgument().name("arg") + .type(GraphQLNonNull.nonNull(GraphQLString)) + + def fieldDef = GraphQLFieldDefinition.newFieldDefinition() + .name("field") + .type(GraphQLString) + .argument(fieldArg) + .build() + + validationContext.getFieldDef() >> fieldDef + + def defaultNullArg = Argument.newArgument().name("arg").value(NullValue.newNullValue().build()).build() + def field = new Field("field", [defaultNullArg]) + + when: + providedNonNullArguments.checkField(field) + + then: + errorCollector.containsValidationError(ValidationErrorType.NullValueForNonNullArgument) + } + + def "provide the explicit value null is not valid for non null argument with error message"() { + def query = """ + query getDogName { + dog { + doesKnowCommand(dogCommand: null) + } + } + """.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 2 + validationErrors[0].validationErrorType == ValidationErrorType.NullValueForNonNullArgument + validationErrors[0].message == "Validation error (NullValueForNonNullArgument@[dog/doesKnowCommand]) : Null value for non-null field argument 'dogCommand'" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } } diff --git a/src/test/groovy/graphql/validation/rules/ScalarLeafsTest.groovy b/src/test/groovy/graphql/validation/rules/ScalarLeafsTest.groovy deleted file mode 100644 index 0416486042..0000000000 --- a/src/test/groovy/graphql/validation/rules/ScalarLeafsTest.groovy +++ /dev/null @@ -1,47 +0,0 @@ -package graphql.validation.rules - -import graphql.Scalars -import graphql.language.Field -import graphql.language.SelectionSet -import graphql.schema.GraphQLObjectType -import graphql.validation.ValidationContext -import graphql.validation.ValidationErrorCollector -import graphql.validation.ValidationErrorType -import spock.lang.Specification - -import static graphql.language.Field.newField - -class ScalarLeafsTest extends Specification { - - ValidationErrorCollector errorCollector = new ValidationErrorCollector() - ValidationContext validationContext = Mock(ValidationContext) - ScalarLeafs scalarLeafs = new ScalarLeafs(validationContext, errorCollector) - - def "sub selection not allowed"() { - given: - Field field = newField("hello", SelectionSet.newSelectionSet([newField("world").build()]).build()).build() - validationContext.getOutputType() >> Scalars.GraphQLString - when: - scalarLeafs.checkField(field) - - then: - errorCollector.containsValidationError( - ValidationErrorType.SubSelectionNotAllowed, - "Sub selection not allowed on leaf type String of field hello" - ) - } - - def "sub selection required"() { - given: - Field field = newField("hello").build() - validationContext.getOutputType() >> GraphQLObjectType.newObject().name("objectType").build() - when: - scalarLeafs.checkField(field) - - then: - errorCollector.containsValidationError( - ValidationErrorType.SubSelectionRequired, - "Sub selection required for type objectType of field hello" - ) - } -} diff --git a/src/test/groovy/graphql/validation/rules/ScalarLeavesTest.groovy b/src/test/groovy/graphql/validation/rules/ScalarLeavesTest.groovy new file mode 100644 index 0000000000..14934a4846 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/ScalarLeavesTest.groovy @@ -0,0 +1,86 @@ +package graphql.validation.rules + +import graphql.Scalars +import graphql.language.Field +import graphql.language.SelectionSet +import graphql.parser.Parser +import graphql.schema.GraphQLObjectType +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationContext +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorCollector +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +import static graphql.language.Field.newField + +class ScalarLeavesTest extends Specification { + + ValidationErrorCollector errorCollector = new ValidationErrorCollector() + ValidationContext validationContext = Mock(ValidationContext) + ScalarLeaves scalarLeaves = new ScalarLeaves(validationContext, errorCollector) + + def "subselection not allowed"() { + given: + Field field = newField("hello", SelectionSet.newSelectionSet([newField("world").build()]).build()).build() + validationContext.getOutputType() >> Scalars.GraphQLString + when: + scalarLeaves.checkField(field) + + then: + errorCollector.containsValidationError(ValidationErrorType.SubselectionNotAllowed) + } + + def "subselection not allowed with error message"() { + def query = """ + query dogOperation { + dog { + name { + id + } + } + } + """.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubselectionNotAllowed + validationErrors[0].message == "Validation error (SubselectionNotAllowed@[dog/name]) : Subselection not allowed on leaf type 'String!' of field 'name'" + } + + def "subselection required"() { + given: + Field field = newField("hello").build() + validationContext.getOutputType() >> GraphQLObjectType.newObject().name("objectType").build() + when: + scalarLeaves.checkField(field) + + then: + errorCollector.containsValidationError(ValidationErrorType.SubselectionRequired) + } + + def "subselection required with error message"() { + def query = """ + query dogOperation { + dog + } + """.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubselectionRequired + validationErrors[0].message == "Validation error (SubselectionRequired@[dog]) : Subselection required for type 'Dog' of field 'dog'" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } +} diff --git a/src/test/groovy/graphql/validation/rules/SubscriptionUniqueRootFieldTest.groovy b/src/test/groovy/graphql/validation/rules/SubscriptionUniqueRootFieldTest.groovy new file mode 100644 index 0000000000..9b171f2256 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/SubscriptionUniqueRootFieldTest.groovy @@ -0,0 +1,293 @@ +package graphql.validation.rules + +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class SubscriptionUniqueRootFieldTest extends Specification { + def "5.2.3.1 subscription with only one root field passes validation"() { + given: + def subscriptionOneRoot = ''' + subscription doggo { + dog { + name + } + } + ''' + + when: + def validationErrors = validate(subscriptionOneRoot) + + then: + validationErrors.empty + } + + def "5.2.3.1 subscription with only one root field with fragment passes validation"() { + given: + def subscriptionOneRootWithFragment = ''' + subscription doggo { + ...doggoFields + } + + fragment doggoFields on SubscriptionRoot { + dog { + name + } + } + ''' + + when: + def validationErrors = validate(subscriptionOneRootWithFragment) + + then: + validationErrors.empty + } + + def "5.2.3.1 subscription with more than one root field fails validation"() { + given: + def subscriptionTwoRoots = ''' + subscription pets { + dog { + name + } + cat { + name + } + } + ''' + when: + def validationErrors = validate(subscriptionTwoRoots) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionMultipleRootFields + validationErrors[0].message == "Validation error (SubscriptionMultipleRootFields) : Subscription operation 'pets' must have exactly one root field" + } + + def "5.2.3.1 subscription with more than one root field with fragment fails validation"() { + given: + def subscriptionTwoRootsWithFragment = ''' + subscription whoIsAGoodBoy { + ...pets + } + + fragment pets on SubscriptionRoot { + dog { + name + } + cat { + name + } + } + ''' + when: + def validationErrors = validate(subscriptionTwoRootsWithFragment) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionMultipleRootFields + validationErrors[0].message == "Validation error (SubscriptionMultipleRootFields) : Subscription operation 'whoIsAGoodBoy' must have exactly one root field" + } + + def "5.2.3.1 document can contain multiple operations with different root fields"() { + given: + def document = ''' + subscription catto { + cat { + name + } + } + + query doggo { + dog { + name + } + } + ''' + when: + def validationErrors = validate(document) + + then: + validationErrors.empty + } + + def "5.2.3.1 subscription root field must not be an introspection field"() { + given: + def subscriptionIntrospectionField = ''' + subscription doggo { + __typename + } + ''' + when: + def validationErrors = validate(subscriptionIntrospectionField) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionIntrospectionRootField + validationErrors[0].message == "Validation error (SubscriptionIntrospectionRootField) : Subscription operation 'doggo' root field '__typename' cannot be an introspection field" + } + + def "5.2.3.1 subscription root field via fragment must not be an introspection field"() { + given: + def subscriptionIntrospectionField = ''' + subscription doggo { + ...dogs + } + + fragment dogs on SubscriptionRoot { + __typename + } + ''' + when: + def validationErrors = validate(subscriptionIntrospectionField) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionIntrospectionRootField + validationErrors[0].message == "Validation error (SubscriptionIntrospectionRootField) : Subscription operation 'doggo' root field '__typename' cannot be an introspection field" + } + + def "5.2.3.1 subscription with multiple root fields within inline fragment are not allowed"() { + given: + def subscriptionOneRootWithFragment = ''' + subscription doggo { + ... { + dog { + name + } + cat { + name + } + } + } + ''' + + when: + def validationErrors = validate(subscriptionOneRootWithFragment) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionMultipleRootFields + validationErrors[0].message == "Validation error (SubscriptionMultipleRootFields) : Subscription operation 'doggo' must have exactly one root field" + } + + + def "5.2.3.1 subscription with more than one root field with multiple fragment fails validation"() { + given: + def subscriptionTwoRootsWithFragment = ''' + fragment doggoRoot on SubscriptionRoot { + ...doggoLevel1 + } + + fragment doggoLevel1 on SubscriptionRoot { + ...doggoLevel2 + } + + fragment doggoLevel2 on SubscriptionRoot { + dog { + name + } + cat { + name + } + } + + subscription whoIsAGoodBoy { + ...doggoRoot + } + ''' + when: + def validationErrors = validate(subscriptionTwoRootsWithFragment) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionMultipleRootFields + validationErrors[0].message == "Validation error (SubscriptionMultipleRootFields) : Subscription operation 'whoIsAGoodBoy' must have exactly one root field" + } + + + def "5.2.3.1 subscription with more than one root field with multiple fragment with inline fragments fails validation"() { + given: + def subscriptionTwoRootsWithFragment = ''' + fragment doggoRoot on SubscriptionRoot { + ...doggoLevel1 + } + + fragment doggoLevel1 on SubscriptionRoot { + ...{ + ...doggoLevel2 + } + } + + fragment doggoLevel2 on SubscriptionRoot { + ...{ + dog { + name + } + cat { + name + } + } + } + + subscription whoIsAGoodBoy { + ...doggoRoot + } + ''' + when: + def validationErrors = validate(subscriptionTwoRootsWithFragment) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].validationErrorType == ValidationErrorType.SubscriptionMultipleRootFields + validationErrors[0].message == "Validation error (SubscriptionMultipleRootFields) : Subscription operation 'whoIsAGoodBoy' must have exactly one root field" + } + + + def "5.2.3.1 subscription with one root field with multiple fragment with inline fragments does not fail validation"() { + given: + def subscriptionTwoRootsWithFragment = ''' + fragment doggoRoot on SubscriptionRoot { + ...doggoLevel1 + } + + fragment doggoLevel1 on SubscriptionRoot { + ...{ + ...doggoLevel2 + } + } + + fragment doggoLevel2 on SubscriptionRoot { + ...{ + dog { + name + } + + } + } + + subscription whoIsAGoodBoy { + ...doggoRoot + } + ''' + when: + def validationErrors = validate(subscriptionTwoRootsWithFragment) + + then: + validationErrors.empty + } + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } +} diff --git a/src/test/groovy/graphql/validation/rules/UniqueArgumentNamesTest.groovy b/src/test/groovy/graphql/validation/rules/UniqueArgumentNamesTest.groovy new file mode 100644 index 0000000000..4e76fc69a4 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/UniqueArgumentNamesTest.groovy @@ -0,0 +1,84 @@ +package graphql.validation.rules + +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class UniqueArgumentNamesTest extends Specification { + + def "unique argument name"() { + def query = """ + query getDogName { + dog(arg1:"argValue") @dogDirective(arg1: "value"){ + name @include(if: true) + } + } + """ + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + + then: + validationErrors.empty + } + + def "duplicate argument name on field"() { + def query = """ + query getDogName { + dog(arg1:"value1",arg1:"value2") { + name + } + } + """ + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.DuplicateArgumentNames + validationErrors.get(0).message == "Validation error (DuplicateArgumentNames@[dog]) : There can be only one argument named 'arg1'" + } + + def "duplicate argument name on directive"() { + def query = """ + query getDogName { + dog(arg1:"argValue") { + name @include(if: true,if: false) + } + } + """ + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.DuplicateArgumentNames + validationErrors.get(0).message == "Validation error (DuplicateArgumentNames@[dog/name]) : There can be only one argument named 'if'" + } + + def "duplicate argument name on custom directive"() { + def query = """ + query getDogName { + dog(arg1:"argValue") @dogDirective(arg1: "value",arg1: "value2"){ + name + } + } + """ + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors.get(0).getValidationErrorType() == ValidationErrorType.DuplicateArgumentNames + validationErrors.get(0).message == "Validation error (DuplicateArgumentNames@[dog]) : There can be only one argument named 'arg1'" + } +} diff --git a/src/test/groovy/graphql/validation/rules/UniqueDirectiveNamesPerLocationTest.groovy b/src/test/groovy/graphql/validation/rules/UniqueDirectiveNamesPerLocationTest.groovy new file mode 100644 index 0000000000..107a140295 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/UniqueDirectiveNamesPerLocationTest.groovy @@ -0,0 +1,157 @@ +package graphql.validation.rules + + +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class UniqueDirectiveNamesPerLocationTest extends Specification { + + def '5.7.3 Directives Are Unique Per Location - FragmentDefinition'() { + def query = ''' + query getName { + dog { + name + ... FragDef + ... { + name + } + } + } + + fragment FragDef on Dog @upper @lower @upper { + name + } + '''.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].locations[0].line == 12 + validationErrors[0].locations[0].column == 39 + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateDirectiveName + validationErrors[0].message == "Validation error (DuplicateDirectiveName@[FragDef]) : Non repeatable directives must be uniquely named within a location. The directive 'upper' used on a 'FragmentDefinition' is not unique" + } + + def '5.7.3 Directives Are Unique Per Location - OperationDefinition'() { + def query = ''' + query getName @upper @lower @upper { + dog { + name + ... FragDef + ... { + name + } + } + } + + fragment FragDef on Dog { + name + } + '''.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].locations[0].line == 2 + validationErrors[0].locations[0].column == 29 + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateDirectiveName + validationErrors[0].message == "Validation error (DuplicateDirectiveName) : Non repeatable directives must be uniquely named within a location. The directive 'upper' used on a 'OperationDefinition' is not unique" + } + + def '5.7.3 Directives Are Unique Per Location - Field'() { + def query = ''' + query getName { + dog { + name @upper @lower @upper + ... FragDef + ... { + name + } + } + } + + fragment FragDef on Dog { + name + } + '''.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].locations[0].line == 4 + validationErrors[0].locations[0].column == 28 + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateDirectiveName + validationErrors[0].message == "Validation error (DuplicateDirectiveName@[dog/name]) : Non repeatable directives must be uniquely named within a location. The directive 'upper' used on a 'Field' is not unique" + } + + def '5.7.3 Directives Are Unique Per Location - FragmentSpread'() { + def query = ''' + query getName { + dog { + name + ... FragDef @upper @lower @upper + ... { + name + } + } + } + + fragment FragDef on Dog { + name + } + '''.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].locations[0].line == 5 + validationErrors[0].locations[0].column == 35 + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateDirectiveName + validationErrors[0].message == "Validation error (DuplicateDirectiveName@[dog]) : Non repeatable directives must be uniquely named within a location. The directive 'upper' used on a 'FragmentSpread' is not unique" + } + + def '5.7.3 Directives Are Unique Per Location - InlineFragment'() { + def query = ''' + query getName { + dog { + name + ... FragDef + ... @upper @lower @upper { + name + } + } + } + + fragment FragDef on Dog { + name + } + '''.stripIndent() + when: + def validationErrors = validate(query) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].locations[0].line == 6 + validationErrors[0].locations[0].column == 27 + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateDirectiveName + validationErrors[0].message == "Validation error (DuplicateDirectiveName@[dog]) : Non repeatable directives must be uniquely named within a location. The directive 'upper' used on a 'InlineFragment' is not unique" + } + + static List validate(String query) { + def document = new Parser().parseDocument(query) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + } +} diff --git a/src/test/groovy/graphql/validation/rules/UniqueFragmentNamesTest.groovy b/src/test/groovy/graphql/validation/rules/UniqueFragmentNamesTest.groovy new file mode 100644 index 0000000000..f3d049aba1 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/UniqueFragmentNamesTest.groovy @@ -0,0 +1,40 @@ +package graphql.validation.rules + +import graphql.language.SourceLocation +import graphql.parser.Parser +import graphql.validation.SpecValidationSchema +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class UniqueFragmentNamesTest extends Specification { + + def 'duplicate fragment names are not allowed'() { + def query = """ + query myQuery{ + ...F + } + fragment F on QueryRoot { + dog { + name + } + } + fragment F on QueryRoot { + dog { + name + } + } + """.stripIndent() + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].locations == [new SourceLocation(10, 1)] + validationErrors[0].message == "Validation error (DuplicateFragmentName@[F]) : There can be only one fragment named 'F'" + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateFragmentName + } + +} diff --git a/src/test/groovy/graphql/validation/rules/UniqueObjectFieldNameTest.groovy b/src/test/groovy/graphql/validation/rules/UniqueObjectFieldNameTest.groovy new file mode 100644 index 0000000000..f59a4e7c07 --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/UniqueObjectFieldNameTest.groovy @@ -0,0 +1,30 @@ +package graphql.validation.rules + +import graphql.parser.Parser +import graphql.validation.Validator +import spock.lang.Specification + +class UniqueObjectFieldNameTest extends Specification { + + def 'Object Field Name Uniqueness Not Valid'() { + def query = """ + query { + dogWithInput(leash: { + id: "foo" + id: "bar" + }) { + name + } + } + """ + when: + def document = Parser.parse(query) + def validationErrors = new Validator().validateDocument(Harness.Schema, document, Locale.ENGLISH) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].message == "Validation Error (UniqueObjectFieldName@[dogWithInput]) : There can be only one field named 'id'" + } + +} diff --git a/src/test/groovy/graphql/validation/rules/UniqueOperationNamesTest.groovy b/src/test/groovy/graphql/validation/rules/UniqueOperationNamesTest.groovy index ac0f68bbd9..c5fa1eb3d2 100644 --- a/src/test/groovy/graphql/validation/rules/UniqueOperationNamesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/UniqueOperationNamesTest.groovy @@ -8,12 +8,10 @@ import graphql.validation.ValidationErrorType import graphql.validation.Validator import spock.lang.Specification -import static graphql.validation.rules.UniqueOperationNames.duplicateOperationNameMessage - class UniqueOperationNamesTest extends Specification { def '5.1.1.1 Operation Name Uniqueness Not Valid'() { - def query = """\ + def query = """ query getName { dog { name @@ -34,11 +32,13 @@ class UniqueOperationNamesTest extends Specification { then: !validationErrors.empty validationErrors.size() == 1 - validationErrors[0] == duplicateOperationName("getName", 7, 1) + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateOperationName + validationErrors[0].locations == [new SourceLocation(8, 1)] + validationErrors[0].message == "Validation error (DuplicateOperationName) : There can be only one operation named 'getName'" } def '5.1.1.1 Operation Name Uniqueness Not Valid Different Operations'() { - def query = """\ + def query = """ query dogOperation { dog { name @@ -46,8 +46,8 @@ class UniqueOperationNamesTest extends Specification { } mutation dogOperation { - mutateDog { - id + createDog(input: {id: "1"}) { + name } } """.stripIndent() @@ -57,17 +57,13 @@ class UniqueOperationNamesTest extends Specification { then: !validationErrors.empty validationErrors.size() == 1 - validationErrors[0] == duplicateOperationName("dogOperation", 7, 1) - } - - ValidationError duplicateOperationName(String defName, int line, int column) { - return new ValidationError(ValidationErrorType.DuplicateOperationName, - [new SourceLocation(line, column)], - duplicateOperationNameMessage(defName)) + validationErrors[0].validationErrorType == ValidationErrorType.DuplicateOperationName + validationErrors[0].locations == [new SourceLocation(8, 1)] + validationErrors[0].message == "Validation error (DuplicateOperationName) : There can be only one operation named 'dogOperation'" } - List validate(String query) { + static List validate(String query) { def document = new Parser().parseDocument(query) - return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document) + return new Validator().validateDocument(SpecValidationSchema.specValidationSchema, document, Locale.ENGLISH) } } diff --git a/src/test/groovy/graphql/validation/rules/UniqueVariableNamesTest.groovy b/src/test/groovy/graphql/validation/rules/UniqueVariableNamesTest.groovy new file mode 100644 index 0000000000..79e80c05ba --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/UniqueVariableNamesTest.groovy @@ -0,0 +1,52 @@ +package graphql.validation.rules + +import graphql.TestUtil +import graphql.parser.Parser +import graphql.validation.ValidationError +import graphql.validation.ValidationErrorType +import graphql.validation.Validator +import spock.lang.Specification + +class UniqueVariableNamesTest extends Specification { + + def schema = TestUtil.schema(''' + type Query { + field(arg: Int) : String + } + ''') + + def "normal query "() { + + def query = """ + query(\$arg:Int){ + field(arg: \$arg) + } + """ + + when: + def document = Parser.parse(query) + def validationResult = new Validator().validateDocument(schema, document, Locale.ENGLISH) + + then: + validationResult.size() == 0 + } + + def "duplicate variable name error"() { + + def query = """ + query(\$arg:Int,\$arg:Int){ + field(arg: \$arg) + } + """ + + when: + def document = Parser.parse(query) + def validationResult = new Validator().validateDocument(schema, document, Locale.ENGLISH) + + then: + validationResult.size() == 1 + (validationResult[0] as ValidationError).validationErrorType == ValidationErrorType.DuplicateVariableName + validationResult[0].message == "Validation error (DuplicateVariableName) : There can be only one variable named 'arg'" + } + +} diff --git a/src/test/groovy/graphql/validation/rules/VariableDefaultValuesOfCorrectTypeTest.groovy b/src/test/groovy/graphql/validation/rules/VariableDefaultValuesOfCorrectTypeTest.groovy index 072b560592..29f132d411 100644 --- a/src/test/groovy/graphql/validation/rules/VariableDefaultValuesOfCorrectTypeTest.groovy +++ b/src/test/groovy/graphql/validation/rules/VariableDefaultValuesOfCorrectTypeTest.groovy @@ -1,36 +1,31 @@ package graphql.validation.rules +import graphql.GraphQLContext +import graphql.TestUtil +import graphql.i18n.I18n import graphql.language.BooleanValue -import graphql.language.StringValue import graphql.language.TypeName import graphql.language.VariableDefinition -import graphql.schema.GraphQLNonNull import graphql.validation.ValidationContext import graphql.validation.ValidationErrorCollector import graphql.validation.ValidationErrorType +import graphql.validation.Validator import spock.lang.Specification import static graphql.Scalars.GraphQLString -import static graphql.schema.GraphQLNonNull.nonNull class VariableDefaultValuesOfCorrectTypeTest extends Specification { ValidationContext validationContext = Mock(ValidationContext) ValidationErrorCollector errorCollector = new ValidationErrorCollector() VariableDefaultValuesOfCorrectType defaultValuesOfCorrectType = new VariableDefaultValuesOfCorrectType(validationContext, errorCollector) + I18n i18n = Mock(I18n) - def "NonNull type, but with default value"() { - given: - GraphQLNonNull nonNullType = nonNull(GraphQLString) - StringValue defaultValue = StringValue.newStringValue("string").build() - VariableDefinition variableDefinition = VariableDefinition.newVariableDefinition("var", TypeName.newTypeName("String").build(), defaultValue).build() - validationContext.getInputType() >> nonNullType - when: - defaultValuesOfCorrectType.checkVariableDefinition(variableDefinition) - - then: - errorCollector.containsValidationError(ValidationErrorType.DefaultForNonNullArgument) - + void setup() { + def context = GraphQLContext.getDefault() + validationContext.getGraphQLContext() >> context + validationContext.getI18n() >> i18n + i18n.getLocale() >> Locale.ENGLISH } def "default value has wrong type"() { @@ -44,4 +39,72 @@ class VariableDefaultValuesOfCorrectTypeTest extends Specification { then: errorCollector.containsValidationError(ValidationErrorType.BadValueForDefaultArg) } -} + + def "default value has wrong type with error message"() { + setup: + def schema = ''' + type User { + id: String + } + + type Query { + getUsers(howMany: Int) : [User] + } + ''' + + def query = ''' + query($howMany: Int = "NotANumber") { + getUsers(howMany: $howMany) { + id + } + } + ''' + + def graphQlSchema = TestUtil.schema(schema) + def document = TestUtil.parseQuery(query) + def validator = new Validator() + + when: + def validationErrors = validator.validateDocument(graphQlSchema, document, Locale.ENGLISH) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].getValidationErrorType() == ValidationErrorType.BadValueForDefaultArg + validationErrors[0].message == "Validation error (BadValueForDefaultArg) : Bad default value 'StringValue{value='NotANumber'}' for type 'Int'" + } + + def "default value has wrong type with error message of client (German), not server (English)"() { + setup: + def schema = ''' + type User { + id: String + } + + type Query { + getUsers(howMany: Int) : [User] + } + ''' + + def query = ''' + query($howMany: Int = "NotANumber") { + getUsers(howMany: $howMany) { + id + } + } + ''' + + def graphQlSchema = TestUtil.schema(schema) + def document = TestUtil.parseQuery(query) + def validator = new Validator() + + when: + def validationErrors = validator.validateDocument(graphQlSchema, document, Locale.GERMAN) + + then: + !validationErrors.empty + validationErrors.size() == 1 + validationErrors[0].getValidationErrorType() == ValidationErrorType.BadValueForDefaultArg + validationErrors[0].message == "Validierungsfehler (BadValueForDefaultArg) : Ungültiger Standardwert 'StringValue{value='NotANumber'}' für Typ 'Int'" + } +} \ No newline at end of file diff --git a/src/test/groovy/graphql/validation/rules/VariableTypesMatchRuleTest.groovy b/src/test/groovy/graphql/validation/rules/VariableTypesMatchRuleTest.groovy deleted file mode 100644 index 2948b114ea..0000000000 --- a/src/test/groovy/graphql/validation/rules/VariableTypesMatchRuleTest.groovy +++ /dev/null @@ -1,76 +0,0 @@ -package graphql.validation.rules - -import graphql.Scalars -import graphql.StarWarsSchema -import graphql.language.ListType -import graphql.language.NonNullType -import graphql.language.OperationDefinition -import graphql.language.StringValue -import graphql.language.TypeName -import graphql.language.VariableDefinition -import graphql.language.VariableReference -import graphql.schema.GraphQLList -import graphql.schema.GraphQLNonNull -import graphql.validation.ValidationContext -import graphql.validation.ValidationErrorCollector -import graphql.validation.ValidationErrorType -import spock.lang.Specification - -class VariableTypesMatchRuleTest extends Specification { - - ValidationContext validationContext = Mock(ValidationContext) - ValidationErrorCollector errorCollector = new ValidationErrorCollector() - VariableTypesMatchRule variableTypesMatchRule - VariablesTypesMatcher variablesTypeMatcher - - def setup() { - variablesTypeMatcher = Mock(VariablesTypesMatcher) - variableTypesMatchRule = new VariableTypesMatchRule(validationContext, errorCollector, variablesTypeMatcher) - } - - def "invalid type"() { - given: - def defaultValue = new StringValue("default") - def astType = new TypeName("String") - def expectedType = Scalars.GraphQLBoolean - - validationContext.getSchema() >> StarWarsSchema.starWarsSchema - validationContext.getInputType() >> expectedType - variablesTypeMatcher.effectiveType(Scalars.GraphQLString, defaultValue) >> Scalars.GraphQLString - variablesTypeMatcher - .doesVariableTypesMatch(Scalars.GraphQLString, defaultValue, expectedType) >> false - - when: - variableTypesMatchRule.checkOperationDefinition(OperationDefinition.newOperationDefinition().build()) - variableTypesMatchRule.checkVariableDefinition(new VariableDefinition("var", astType, defaultValue)) - variableTypesMatchRule.checkVariable(new VariableReference("var")) - - then: - errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) - } - - def "validation error message contains type information - issue 911 "() { - given: - def defaultValue = null - def astType = new NonNullType(new ListType(new TypeName("String"))) - def expectedType = GraphQLList.list(GraphQLNonNull.nonNull(Scalars.GraphQLString)) - - def mismatchedType = GraphQLNonNull.nonNull(GraphQLList.list(Scalars.GraphQLString)) - - validationContext.getSchema() >> StarWarsSchema.starWarsSchema - validationContext.getInputType() >> expectedType - variablesTypeMatcher.effectiveType(mismatchedType, defaultValue) >> mismatchedType - variablesTypeMatcher - .doesVariableTypesMatch(expectedType, defaultValue, expectedType) >> false - - - when: - variableTypesMatchRule.checkOperationDefinition(OperationDefinition.newOperationDefinition().build()) - variableTypesMatchRule.checkVariableDefinition(new VariableDefinition("var", astType, defaultValue)) - variableTypesMatchRule.checkVariable(new VariableReference("var")) - - then: - errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) - errorCollector.errors[0].message.contains("Variable type '[String]!' doesn't match expected type '[String!]'") - } -} diff --git a/src/test/groovy/graphql/validation/rules/VariableTypesMatchTest.groovy b/src/test/groovy/graphql/validation/rules/VariableTypesMatchTest.groovy new file mode 100644 index 0000000000..5ccaff13dd --- /dev/null +++ b/src/test/groovy/graphql/validation/rules/VariableTypesMatchTest.groovy @@ -0,0 +1,256 @@ +package graphql.validation.rules + + +import graphql.StarWarsSchema +import graphql.TestUtil +import graphql.i18n.I18n +import graphql.parser.Parser +import graphql.schema.GraphQLSchema +import graphql.validation.LanguageTraversal +import graphql.validation.RulesVisitor +import graphql.validation.ValidationContext +import graphql.validation.ValidationErrorCollector +import graphql.validation.ValidationErrorType +import spock.lang.Specification + +class VariableTypesMatchTest extends Specification { + ValidationErrorCollector errorCollector = new ValidationErrorCollector() + + def traverse(String query, GraphQLSchema schema = StarWarsSchema.starWarsSchema) { + def document = Parser.parse(query) + I18n i18n = I18n.i18n(I18n.BundleType.Validation, Locale.ENGLISH) + def validationContext = new ValidationContext(schema, document, i18n) + def variableTypesMatchRule = new VariableTypesMatch(validationContext, errorCollector) + def languageTraversal = new LanguageTraversal() + languageTraversal.traverse(document, new RulesVisitor(validationContext, [variableTypesMatchRule])) + } + + def "valid variables"() { + given: + def query = """ + query Q(\$id: String!) { + human(id: \$id) { + __typename + } + } + """ + + when: + traverse(query) + + then: + errorCollector.errors.isEmpty() + } + + def "invalid variables"() { + given: + def query = """ + query Q(\$id: String) { + human(id: \$id) { + __typename + } + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) + // #991: describe which types were mismatched in error message + errorCollector.errors[0].message == "Validation error (VariableTypeMismatch@[human]) : Variable 'id' of type 'String' used in position expecting type 'String!'" + } + + def "invalid variables in fragment spread"() { + given: + def query = """ + fragment QueryType on QueryType { + human(id: \$xid) { + __typename + } + } + + query Invalid(\$xid: String) { + ...QueryType + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) + errorCollector.errors[0].message == "Validation error (VariableTypeMismatch@[QueryType/human]) : Variable 'xid' of type 'String' used in position expecting type 'String!'" + } + + def "mixed validity operations, valid first"() { + given: + def query = """ + fragment QueryType on QueryType { + human(id: \$id) { + __typename + } + } + + query Valid(\$id: String!) { + ... QueryType + } + + query Invalid(\$id: String) { + ... QueryType + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) + errorCollector.errors[0].message == "Validation error (VariableTypeMismatch@[QueryType/human]) : Variable 'id' of type 'String' used in position expecting type 'String!'" + } + + def "mixed validity operations, invalid first"() { + given: + def query = """ + fragment QueryType on QueryType { + human(id: \$id) { + __typename + } + } + + query Invalid(\$id: String) { + ... QueryType + } + + query Valid(\$id: String!) { + ... QueryType + } + """ + + when: + traverse(query) + + then: + errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) + errorCollector.errors[0].message == "Validation error (VariableTypeMismatch@[QueryType/human]) : Variable 'id' of type 'String' used in position expecting type 'String!'" + } + + def "multiple invalid operations"() { + given: + def query = """ + fragment QueryType on QueryType { + human(id: \$id) { + __typename + } + } + + query Invalid1(\$id: String) { + ... QueryType + } + + query Invalid2(\$id: Boolean) { + ... QueryType + } + """ + + when: + traverse(query) + + then: + errorCollector.getErrors().size() == 2 + errorCollector.errors.any { + it.validationErrorType == ValidationErrorType.VariableTypeMismatch && + it.message == "Validation error (VariableTypeMismatch@[QueryType/human]) : Variable 'id' of type 'String' used in position expecting type 'String!'" + } + errorCollector.errors.any { + it.validationErrorType == ValidationErrorType.VariableTypeMismatch && + it.message == "Validation error (VariableTypeMismatch@[QueryType/human]) : Variable 'id' of type 'Boolean' used in position expecting type 'String!'" + } + } + + + def "issue 3276 - invalid variables in object field values with no defaults in location"() { + + def sdl = ''' + type Query { + items(pagination: Pagination = {limit: 1, offset: 1}): [String] + } + input Pagination { + limit: Int! + offset: Int! + } + ''' + def schema = TestUtil.schema(sdl) + given: + def query = ''' + query Items( $limit: Int, $offset: Int) { + items( + pagination: {limit: $limit, offset: $offset} + ) + } + ''' + + when: + traverse(query, schema) + + then: + errorCollector.containsValidationError(ValidationErrorType.VariableTypeMismatch) + errorCollector.errors[0].message == "Validation error (VariableTypeMismatch@[items]) : Variable 'limit' of type 'Int' used in position expecting type 'Int!'" + } + + def "issue 3276 - valid variables because of schema defaults with nullable variable"() { + + def sdl = ''' + type Query { + items(pagination: Pagination! = {limit: 1, offset: 1}): [String] + } + input Pagination { + limit: Int! + offset: Int! + } + ''' + def schema = TestUtil.schema(sdl) + given: + def query = ''' + query Items( $var : Pagination) { + items( + pagination: $var + ) + } + ''' + + when: + traverse(query, schema) + + then: + errorCollector.errors.isEmpty() + } + + def "issue 3276 - valid variables because of variable defaults"() { + + def sdl = ''' + type Query { + items(pagination: Pagination!): [String] + } + input Pagination { + limit: Int! + offset: Int! + } + ''' + def schema = TestUtil.schema(sdl) + given: + def query = ''' + query Items( $var : Pagination = {limit: 1, offset: 1}) { + items( + pagination: $var + ) + } + ''' + + when: + traverse(query, schema) + + then: + errorCollector.errors.isEmpty() + } +} diff --git a/src/test/groovy/graphql/validation/rules/VariablesAreInputTypesTest.groovy b/src/test/groovy/graphql/validation/rules/VariablesAreInputTypesTest.groovy index fb7febd3c2..b01eebabc3 100644 --- a/src/test/groovy/graphql/validation/rules/VariablesAreInputTypesTest.groovy +++ b/src/test/groovy/graphql/validation/rules/VariablesAreInputTypesTest.groovy @@ -18,7 +18,6 @@ class VariablesAreInputTypesTest extends Specification { ValidationErrorCollector errorCollector = new ValidationErrorCollector() VariablesAreInputTypes variablesAreInputTypes = new VariablesAreInputTypes(validationContext, errorCollector) - def "the unmodified ast type is not a schema input type"() { given: def astType = new NonNullType(new ListType(new TypeName(StarWarsSchema.droidType.getName()))) @@ -65,12 +64,13 @@ class VariablesAreInputTypesTest extends Specification { def validator = new Validator() when: - def validationErrors = validator.validateDocument(graphQlSchema, document) + def validationErrors = validator.validateDocument(graphQlSchema, document, Locale.ENGLISH) then: !validationErrors.empty validationErrors.size() == 2 validationErrors.validationErrorType as Set == [ValidationErrorType.VariableTypeMismatch, ValidationErrorType.NonInputTypeOnVariable] as Set + validationErrors[0].message == "Validation error (NonInputTypeOnVariable) : Input variable 'user' type 'User' is not an input type" } } diff --git a/src/test/groovy/graphql/validation/rules/VariablesTypesMatcherTest.groovy b/src/test/groovy/graphql/validation/rules/VariablesTypesMatcherTest.groovy index c6bead4ef6..b05e425090 100644 --- a/src/test/groovy/graphql/validation/rules/VariablesTypesMatcherTest.groovy +++ b/src/test/groovy/graphql/validation/rules/VariablesTypesMatcherTest.groovy @@ -1,6 +1,7 @@ package graphql.validation.rules import graphql.language.BooleanValue +import graphql.language.StringValue import spock.lang.Specification import spock.lang.Unroll @@ -18,7 +19,7 @@ class VariablesTypesMatcherTest extends Specification { def "#variableType with default value #defaultValue and expected #expectedType should result: #result "() { expect: - typesMatcher.doesVariableTypesMatch(variableType, defaultValue, expectedType) == result + typesMatcher.doesVariableTypesMatch(variableType, defaultValue, expectedType, null) == result where: variableType | defaultValue | expectedType || result @@ -27,4 +28,18 @@ class VariablesTypesMatcherTest extends Specification { nonNull(GraphQLBoolean) | new BooleanValue(true) | GraphQLBoolean || true nonNull(GraphQLString) | null | list(GraphQLString) || false } + + @Unroll + def "issue 3276 - #variableType with default value #defaultValue and expected #expectedType with #locationDefaultValue should result: #result "() { + + expect: + typesMatcher.doesVariableTypesMatch(variableType, defaultValue, expectedType, locationDefaultValue) == result + + where: + variableType | defaultValue | expectedType | locationDefaultValue || result + GraphQLString | null | nonNull(GraphQLString) | null || false + GraphQLString | null | nonNull(GraphQLString) | StringValue.of("x") || true + GraphQLString | StringValue.of("x") | nonNull(GraphQLString) | StringValue.of("x") || true + GraphQLString | StringValue.of("x") | nonNull(GraphQLString) | null || true + } } diff --git a/src/test/groovy/readme/BatchingExamples.java b/src/test/groovy/readme/BatchingExamples.java deleted file mode 100644 index a8eb8c8289..0000000000 --- a/src/test/groovy/readme/BatchingExamples.java +++ /dev/null @@ -1,178 +0,0 @@ -package readme; - -import graphql.GraphQL; -import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation; -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; -import graphql.schema.GraphQLSchema; -import org.dataloader.BatchLoader; -import org.dataloader.DataLoader; -import org.dataloader.DataLoaderRegistry; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -@SuppressWarnings({"unused", "Convert2Lambda", "ConstantConditions", "ClassCanBeStatic"}) -public class BatchingExamples { - - - class StarWarsCharacter { - List getFriendIds() { - return null; - } - } - - void starWarsExample() { - - // a batch loader function that will be called with N or more keys for batch loading - BatchLoader characterBatchLoader = new BatchLoader() { - @Override - public CompletionStage> load(List keys) { - // - // we use supplyAsync() of values here for maximum parellisation - // - return CompletableFuture.supplyAsync(() -> getCharacterDataViaBatchHTTPApi(keys)); - } - }; - - // a data loader for characters that points to the character batch loader - DataLoader characterDataLoader = new DataLoader<>(characterBatchLoader); - - // - // use this data loader in the data fetchers associated with characters and put them into - // the graphql schema (not shown) - // - DataFetcher heroDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - return characterDataLoader.load("2001"); // R2D2 - } - }; - - DataFetcher friendsDataFetcher = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - StarWarsCharacter starWarsCharacter = environment.getSource(); - List friendIds = starWarsCharacter.getFriendIds(); - return characterDataLoader.loadMany(friendIds); - } - }; - - // - // DataLoaderRegistry is a place to register all data loaders in that needs to be dispatched together - // in this case there is 1 but you can have many - // - DataLoaderRegistry registry = new DataLoaderRegistry(); - registry.register("character", characterDataLoader); - - // - // this instrumentation implementation will dispatched all the dataloaders - // as each level fo the graphql query is executed and hence make batched objects - // available to the query and the associated DataFetchers - // - DataLoaderDispatcherInstrumentation dispatcherInstrumentation - = new DataLoaderDispatcherInstrumentation(registry); - - // - // now build your graphql object and execute queries on it. - // the data loader will be invoked via the data fetchers on the - // schema fields - // - GraphQL graphQL = GraphQL.newGraphQL(buildSchema()) - .instrumentation(dispatcherInstrumentation) - .build(); - - } - - private void perRequestGraphQl() { - - GraphQLSchema staticSchema = staticSchema_Or_MayBeFrom_IoC_Injection(); - - DataLoaderRegistry registry = new DataLoaderRegistry(); - registry.register("character", getCharacterDataLoader()); - - DataLoaderDispatcherInstrumentation dispatcherInstrumentation - = new DataLoaderDispatcherInstrumentation(registry); - - GraphQL graphQL = GraphQL.newGraphQL(staticSchema) - .instrumentation(dispatcherInstrumentation) - .build(); - - graphQL.execute("{ helloworld }"); - - // you can now throw away the GraphQL and hence DataLoaderDispatcherInstrumentation - // and DataLoaderRegistry objects since they are really cheap to build per request - - } - - private void doNotUseAsyncInYouDataFetcher() { - - BatchLoader batchLoader = new BatchLoader() { - @Override - public CompletionStage> load(List keys) { - return CompletableFuture.completedFuture(getTheseCharacters(keys)); - } - }; - - DataLoader characterDataLoader = new DataLoader<>(batchLoader); - - DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - // - // Don't DO THIS! - // - return CompletableFuture.supplyAsync(() -> { - String argId = environment.getArgument("id"); - return characterDataLoader.load(argId); - }); - } - }; - } - - private void doAsyncInYourBatchLoader() { - - BatchLoader batchLoader = new BatchLoader() { - @Override - public CompletionStage> load(List keys) { - return CompletableFuture.supplyAsync(() -> getTheseCharacters(keys)); - } - }; - - DataLoader characterDataLoader = new DataLoader<>(batchLoader); - - DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { - @Override - public Object get(DataFetchingEnvironment environment) { - // - // This is OK - // - String argId = environment.getArgument("id"); - return characterDataLoader.load(argId); - } - }; - } - - private List getTheseCharacters(List keys) { - return null; - } - - private GraphQLSchema staticSchema_Or_MayBeFrom_IoC_Injection() { - return null; - } - - private DataLoader getCharacterDataLoader() { - return null; - } - - private GraphQLSchema buildSchema() { - return null; - } - - private List getCharacterDataViaBatchHTTPApi(List keys) { - return null; - } - - -} diff --git a/src/test/groovy/readme/ConcernsExamples.java b/src/test/groovy/readme/ConcernsExamples.java index f2e9737395..89bd775574 100644 --- a/src/test/groovy/readme/ConcernsExamples.java +++ b/src/test/groovy/readme/ConcernsExamples.java @@ -57,7 +57,7 @@ private void contextHelper() { UserContext contextForUser = YourGraphqlContextBuilder.getContextForUser(getCurrentUser()); ExecutionInput executionInput = ExecutionInput.newExecutionInput() - .context(contextForUser) + .graphQLContext(context -> context.put("userContext", contextForUser)) .build(); ExecutionResult executionResult = graphQL.execute(executionInput); @@ -70,7 +70,7 @@ private void contextHelper() { DataFetcher dataFetcher = new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { - UserContext userCtx = environment.getContext(); + UserContext userCtx = environment.getGraphQlContext().get("userContext"); Long businessObjId = environment.getArgument("businessObjId"); return invokeBusinessLayerMethod(userCtx, businessObjId); diff --git a/src/test/groovy/readme/DataFetchingExamples.java b/src/test/groovy/readme/DataFetchingExamples.java new file mode 100644 index 0000000000..c44dfce56a --- /dev/null +++ b/src/test/groovy/readme/DataFetchingExamples.java @@ -0,0 +1,77 @@ +package readme; + +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; + +import java.time.LocalDateTime; +import java.util.List; + +@SuppressWarnings({"Convert2Lambda", "unused"}) +public class DataFetchingExamples { + + static class DatabaseSecurityCtx { + + } + + static class ID { + + } + + //::FigureA + class ProductDTO { + + private ID id; + private String name; + private String description; + private Double cost; + private Double tax; + private LocalDateTime launchDate; + + // ... + + public String getName() { + return name; + } + + // ... + + public String getLaunchDate(DataFetchingEnvironment environment) { + String dateFormat = environment.getArgument("dateFormat"); + return yodaTimeFormatter(launchDate,dateFormat); + } + } + //::/FigureA + + void getProductsDataFetcher() { + //::FigureB + DataFetcher productsDataFetcher = new DataFetcher>() { + @Override + public List get(DataFetchingEnvironment environment) { + DatabaseSecurityCtx ctx = environment.getGraphQlContext().get("databaseSecurityCtx"); + + List products; + String match = environment.getArgument("match"); + if (match != null) { + products = fetchProductsFromDatabaseWithMatching(ctx, match); + } else { + products = fetchAllProductsFromDatabase(ctx); + } + return products; + } + }; + //::/FigureB + } + + private String yodaTimeFormatter(LocalDateTime date, String dateFormat) { + return null; + } + + private List fetchProductsFromDatabaseWithMatching(DatabaseSecurityCtx ctx, String match) { + return null; + } + + private List fetchAllProductsFromDatabase(DatabaseSecurityCtx ctx) { + return null; + } + +} diff --git a/src/test/groovy/readme/DataLoaderBatchingExamples.java b/src/test/groovy/readme/DataLoaderBatchingExamples.java new file mode 100644 index 0000000000..1bf55e0452 --- /dev/null +++ b/src/test/groovy/readme/DataLoaderBatchingExamples.java @@ -0,0 +1,318 @@ +package readme; + +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLSchema; +import org.dataloader.BatchLoader; +import org.dataloader.BatchLoaderContextProvider; +import org.dataloader.BatchLoaderEnvironment; +import org.dataloader.BatchLoaderWithContext; +import org.dataloader.DataLoader; +import org.dataloader.DataLoaderFactory; +import org.dataloader.DataLoaderOptions; +import org.dataloader.DataLoaderRegistry; +import org.dataloader.ValueCache; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import static graphql.ExecutionInput.newExecutionInput; + +@SuppressWarnings({"unused", "Convert2Lambda", "ClassCanBeStatic"}) +public class DataLoaderBatchingExamples { + + + static class StarWarsCharacter { + List getFriendIds() { + return null; + } + } + + private String getQuery() { + return null; + } + + void starWarsExample() { + + // + // a batch loader function that will be called with N or more keys for batch loading + // This can be a singleton object since it's stateless + // + BatchLoader characterBatchLoader = new BatchLoader() { + @Override + public CompletionStage> load(List keys) { + // + // we use supplyAsync() of values here for maximum parellisation + // + return CompletableFuture.supplyAsync(() -> getCharacterDataViaBatchHTTPApi(keys)); + } + }; + + + // + // use this data loader in the data fetchers associated with characters and put them into + // the graphql schema (not shown) + // + DataFetcher heroDataFetcher = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment environment) { + DataLoader dataLoader = environment.getDataLoader("character"); + return dataLoader.load("2001"); // R2D2 + } + }; + + DataFetcher friendsDataFetcher = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment environment) { + StarWarsCharacter starWarsCharacter = environment.getSource(); + List friendIds = starWarsCharacter.getFriendIds(); + DataLoader dataLoader = environment.getDataLoader("character"); + return dataLoader.loadMany(friendIds); + } + }; + + + // + // this instrumentation implementation will dispatch all the data loaders + // as each level of the graphql query is executed and hence make batched objects + // available to the query and the associated DataFetchers + // + + // + // now build your graphql object and execute queries on it. + // the data loader will be invoked via the data fetchers on the + // schema fields + // + GraphQL graphQL = GraphQL.newGraphQL(buildSchema()) + .build(); + + // + // a data loader for characters that points to the character batch loader + // + // Since data loaders are stateful, they are created per execution request. + // + DataLoader characterDataLoader = DataLoaderFactory.newDataLoader(characterBatchLoader); + + // + // DataLoaderRegistry is a place to register all data loaders in that needs to be dispatched together + // in this case there is 1 but you can have many. + // + // Also note that the data loaders are created per execution request + // + DataLoaderRegistry registry = new DataLoaderRegistry(); + registry.register("character", characterDataLoader); + + ExecutionInput executionInput = newExecutionInput() + .query(getQuery()) + .dataLoaderRegistry(registry) + .build(); + + ExecutionResult executionResult = graphQL.execute(executionInput); + } + + static class Redis { + + public boolean containsKey(String key) { + return false; + } + + public CompletableFuture getValue(String key) { + return null; + } + + public CompletableFuture setValue(String key, Object value) { + return null; + } + + public CompletableFuture clearKey(String key) { + return null; + } + + public CompletableFuture clearAll() { + return null; + } + } + + Redis redisIntegration; + + BatchLoader batchLoader = new BatchLoader() { + @Override + public CompletionStage> load(List keys) { + return CompletableFuture.completedFuture(null); + } + }; + + private void changeCachingSolutionOfDataLoader() { + + ValueCache crossRequestValueCache = new ValueCache() { + @Override + public CompletableFuture get(String key) { + return redisIntegration.getValue(key); + } + + @Override + public CompletableFuture set(String key, Object value) { + return redisIntegration.setValue(key, value); + } + + @Override + public CompletableFuture delete(String key) { + return redisIntegration.clearKey(key); + } + + @Override + public CompletableFuture clear() { + return redisIntegration.clearAll(); + } + }; + + DataLoaderOptions options = DataLoaderOptions.newOptions().setValueCache(crossRequestValueCache).build(); + + DataLoader dataLoader = DataLoaderFactory.newDataLoader(batchLoader, options); + } + + private void doNotUseAsyncInYouDataFetcher() { + + BatchLoader batchLoader = new BatchLoader() { + @Override + public CompletionStage> load(List keys) { + return CompletableFuture.completedFuture(getTheseCharacters(keys)); + } + }; + + DataLoader characterDataLoader = DataLoaderFactory.newDataLoader(batchLoader); + + // .... later in your data fetcher + + DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment environment) { + // + // Don't DO THIS! + // + return CompletableFuture.supplyAsync(() -> { + String argId = environment.getArgument("id"); + DataLoader characterLoader = environment.getDataLoader("characterLoader"); + return characterLoader.load(argId); + }); + } + }; + } + + private void doAsyncInYourBatchLoader() { + + BatchLoader batchLoader = new BatchLoader() { + @Override + public CompletionStage> load(List keys) { + return CompletableFuture.supplyAsync(() -> getTheseCharacters(keys)); + } + }; + + DataLoader characterDataLoader = DataLoaderFactory.newDataLoader(batchLoader); + + // .... later in your data fetcher + + DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment environment) { + // + // This is OK + // + String argId = environment.getArgument("id"); + DataLoader characterLoader = environment.getDataLoader("characterLoader"); + return characterLoader.load(argId); + } + }; + } + + private void passingContextToYourBatchLoader() { + + BatchLoaderWithContext batchLoaderWithCtx = new BatchLoaderWithContext() { + + @Override + public CompletionStage> load(List keys, BatchLoaderEnvironment loaderContext) { + // + // we can have an overall context object + SecurityContext securityCtx = loaderContext.getContext(); + // + // and we can have a per key set of context objects + Map keysToSourceObjects = loaderContext.getKeyContexts(); + + return CompletableFuture.supplyAsync(() -> getTheseCharacters(securityCtx.getToken(), keys, keysToSourceObjects)); + } + }; + + // .... + + SecurityContext securityCtx = SecurityContext.newSecurityContext(); + + BatchLoaderContextProvider contextProvider = new BatchLoaderContextProvider() { + @Override + public Object getContext() { + return securityCtx; + } + }; + // + // this creates an overall context for the dataloader + // + DataLoaderOptions loaderOptions = DataLoaderOptions.newOptions().setBatchLoaderContextProvider(contextProvider).build(); + DataLoader characterDataLoader = DataLoaderFactory.newDataLoader(batchLoaderWithCtx, loaderOptions); + + // .... later in your data fetcher + + DataFetcher dataFetcherThatCallsTheDataLoader = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment environment) { + String argId = environment.getArgument("id"); + Object source = environment.getSource(); + // + // you can pass per load call contexts + // + return characterDataLoader.load(argId, source); + } + }; + } + + static class SecurityContext { + + static SecurityContext newSecurityContext() { + return null; + } + + Object getToken() { + return null; + } + } + + + private List getTheseCharacters(List keys) { + return null; + } + + private List getTheseCharacters(Object token, List keys, Object sources) { + return null; + } + + private GraphQLSchema staticSchema_Or_MayBeFrom_IoC_Injection() { + return null; + } + + private DataLoader getCharacterDataLoader() { + return null; + } + + private GraphQLSchema buildSchema() { + return null; + } + + private List getCharacterDataViaBatchHTTPApi(List keys) { + return null; + } + + +} diff --git a/src/test/groovy/readme/DirectivesExamples.java b/src/test/groovy/readme/DirectivesExamples.java index 7e9eb7a459..2d6af20f24 100644 --- a/src/test/groovy/readme/DirectivesExamples.java +++ b/src/test/groovy/readme/DirectivesExamples.java @@ -4,6 +4,9 @@ import graphql.ExecutionResult; import graphql.GraphQL; import graphql.Scalars; +import graphql.execution.directives.QueryAppliedDirective; +import graphql.execution.directives.QueryAppliedDirectiveArgument; +import graphql.execution.directives.QueryDirectives; import graphql.schema.DataFetcher; import graphql.schema.DataFetcherFactories; import graphql.schema.DataFetchingEnvironment; @@ -20,6 +23,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; +import java.util.List; import java.util.Map; @SuppressWarnings({"Convert2Lambda", "unused", "ClassCanBeStatic"}) @@ -38,19 +42,17 @@ static AuthorisationCtx obtain() { class AuthorisationDirective implements SchemaDirectiveWiring { @Override - public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment schemaDirectiveWiringEnv) { - String targetAuthRole = (String) schemaDirectiveWiringEnv.getDirective().getArgument("role").getValue(); + public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment environment) { + String targetAuthRole = (String) environment.getAppliedDirective().getArgument("role").getArgumentValue().getValue(); - GraphQLFieldDefinition field = schemaDirectiveWiringEnv.getElement(); // // build a data fetcher that first checks authorisation roles before then calling the original data fetcher // - DataFetcher originalDataFetcher = field.getDataFetcher(); + DataFetcher originalDataFetcher = environment.getFieldDataFetcher(); DataFetcher authDataFetcher = new DataFetcher() { @Override - public Object get(DataFetchingEnvironment dataFetchingEnvironment) { - Map contextMap = dataFetchingEnvironment.getContext(); - AuthorisationCtx authContext = (AuthorisationCtx) contextMap.get("authContext"); + public Object get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception { + AuthorisationCtx authContext = dataFetchingEnvironment.getGraphQlContext().get("authContext"); if (authContext.hasRole(targetAuthRole)) { return originalDataFetcher.get(dataFetchingEnvironment); @@ -61,7 +63,7 @@ public Object get(DataFetchingEnvironment dataFetchingEnvironment) { }; // // now change the field definition to have the new authorising data fetcher - return field.transform(builder -> builder.dataFetcher(authDataFetcher)); + return environment.setFieldDataFetcher(authDataFetcher); } } @@ -84,7 +86,7 @@ void contextWiring() { ExecutionInput executionInput = ExecutionInput.newExecutionInput() .query(query) - .context(authCtx) + .graphQLContext(builder -> builder.put("authContext", authCtx)) .build(); } @@ -97,7 +99,8 @@ public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment { + DataFetcher originalFetcher = environment.getFieldDataFetcher(); + DataFetcher dataFetcher = DataFetcherFactories.wrapDataFetcher(originalFetcher, ((dataFetchingEnvironment, value) -> { DateTimeFormatter dateTimeFormatter = buildFormatter(dataFetchingEnvironment.getArgument("format")); if (value instanceof LocalDateTime) { return dateTimeFormatter.format((LocalDateTime) value); @@ -110,6 +113,8 @@ public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment builder .argument(GraphQLArgument .newArgument() @@ -117,7 +122,6 @@ public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment cacheDataFetcher = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment env) { + QueryDirectives queryDirectives = env.getQueryDirectives(); + List cacheDirectives = queryDirectives + .getImmediateAppliedDirective("cache"); + // We get a List, because we could have + // repeatable directives + if (cacheDirectives.size() > 0) { + QueryAppliedDirective cache = cacheDirectives.get(0); + QueryAppliedDirectiveArgument maxAgeArgument + = cache.getArgument("maxAge"); + int maxAge = maxAgeArgument.getValue(); + + // Now we know the max allowed cache time and + // can make use of it + // Your logic goes here + } + return "your logic here"; + } + }; } diff --git a/src/test/groovy/readme/ExecutionExamples.java b/src/test/groovy/readme/ExecutionExamples.java index db689f2343..b2b56e798f 100644 --- a/src/test/groovy/readme/ExecutionExamples.java +++ b/src/test/groovy/readme/ExecutionExamples.java @@ -10,13 +10,17 @@ import graphql.execution.AsyncSerialExecutionStrategy; import graphql.execution.DataFetcherExceptionHandler; import graphql.execution.DataFetcherExceptionHandlerParameters; +import graphql.execution.DataFetcherExceptionHandlerResult; import graphql.execution.ExecutionStrategy; -import graphql.execution.ExecutorServiceExecutionStrategy; +import graphql.execution.values.InputInterceptor; +import graphql.execution.values.legacycoercing.LegacyCoercingInputInterceptor; import graphql.language.SourceLocation; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLFieldsContainer; +import graphql.schema.GraphQLInputType; import graphql.schema.GraphQLSchema; import graphql.schema.visibility.BlockedFields; import graphql.schema.visibility.GraphqlFieldVisibility; @@ -27,10 +31,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import static graphql.StarWarsSchema.queryType; @@ -42,6 +42,7 @@ public static void main(String[] args) throws Exception { } private void simpleQueryExecution() throws Exception { + //::FigureA GraphQLSchema schema = GraphQLSchema.newSchema() .query(queryType) .build(); @@ -56,10 +57,12 @@ private void simpleQueryExecution() throws Exception { Object data = executionResult.getData(); List errors = executionResult.getErrors(); + //::/FigureA } - @SuppressWarnings({"Convert2MethodRef","unused","FutureReturnValueIgnored"}) + @SuppressWarnings({"Convert2MethodRef", "unused", "FutureReturnValueIgnored"}) private void simpleAsyncQueryExecution() throws Exception { + //::FigureB GraphQL graphQL = buildSchema(); ExecutionInput executionInput = ExecutionInput.newExecutionInput().query("query { hero { name } }") @@ -73,6 +76,7 @@ private void simpleAsyncQueryExecution() throws Exception { }); promise.join(); + //::/FigureB } private GraphQL graphQL = buildSchema(); @@ -80,6 +84,7 @@ private void simpleAsyncQueryExecution() throws Exception { .build(); private void equivalentSerialAndAsyncQueryExecution() throws Exception { + //::FigureC ExecutionResult executionResult = graphQL.execute(executionInput); @@ -87,22 +92,24 @@ private void equivalentSerialAndAsyncQueryExecution() throws Exception { CompletableFuture promise = graphQL.executeAsync(executionInput); ExecutionResult executionResult2 = promise.join(); - + //::/FigureC } @SuppressWarnings("Convert2Lambda") private void simpleDataFetcher() { + //::FigureD DataFetcher userDataFetcher = new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { return fetchUserFromDatabase(environment.getArgument("userId")); } }; + //::/FigureD } @SuppressWarnings({"Convert2Lambda", "CodeBlock2Expr"}) private void asyncDataFetcher() { - + //::FigureE DataFetcher userDataFetcher = new DataFetcher() { @Override public Object get(DataFetchingEnvironment environment) { @@ -113,67 +120,79 @@ public Object get(DataFetchingEnvironment environment) { return userPromise; } }; + //::/FigureE } private void succinctAsyncDataFetcher() { - + //::FigureF DataFetcher userDataFetcher = environment -> CompletableFuture.supplyAsync( () -> fetchUserFromDatabase(environment.getArgument("userId"))); + //::/FigureF } private void wireInExecutionStrategies() { - + //::FigureG GraphQL.newGraphQL(schema) .queryExecutionStrategy(new AsyncExecutionStrategy()) .mutationExecutionStrategy(new AsyncSerialExecutionStrategy()) .build(); - - } - - private void exampleExecutorServiceExecutionStrategy() { - ExecutorService executorService = new ThreadPoolExecutor( - 2, /* core pool size 2 thread */ - 2, /* max pool size 2 thread */ - 30, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(), - new ThreadPoolExecutor.CallerRunsPolicy()); - - GraphQL graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) - .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(executorService)) - .mutationExecutionStrategy(new AsyncSerialExecutionStrategy()) - .build(); + //::/FigureG } private void exceptionHandler() { + //::FigureI DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { + @Override - public void accept(DataFetcherExceptionHandlerParameters handlerParameters) { + public CompletableFuture handleException(DataFetcherExceptionHandlerParameters handlerParameters) { // // do your custom handling here. The parameters have all you need + GraphQLError buildCustomError = buildCustomError(handlerParameters); + + DataFetcherExceptionHandlerResult exceptionResult = DataFetcherExceptionHandlerResult + .newResult() + .error(buildCustomError) + .build(); + return CompletableFuture.completedFuture(exceptionResult); } }; ExecutionStrategy executionStrategy = new AsyncExecutionStrategy(handler); + //::/FigureI + } + + private GraphQLError buildCustomError(DataFetcherExceptionHandlerParameters handlerParameters) { + return null; } private void blockedFields() { + //::FigureJ GraphqlFieldVisibility blockedFields = BlockedFields.newBlock() .addPattern("Character.id") .addPattern("Droid.appearsIn") .addPattern(".*\\.hero") // it uses regular expressions .build(); + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .fieldVisibility(blockedFields) + .build(); GraphQLSchema schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(blockedFields) + .codeRegistry(codeRegistry) .build(); + //::/FigureJ } private void noIntrospection() { + //::FigureK + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .fieldVisibility(NoIntrospectionGraphqlFieldVisibility.NO_INTROSPECTION_FIELD_VISIBILITY) + .build(); GraphQLSchema schema = GraphQLSchema.newSchema() .query(StarWarsSchema.queryType) - .fieldVisibility(NoIntrospectionGraphqlFieldVisibility.NO_INTROSPECTION_FIELD_VISIBILITY) + .codeRegistry(codeRegistry) .build(); + //::/FigureK } class YourUserAccessService { @@ -183,6 +202,7 @@ public boolean isAdminUser() { } } + //::FigureL class CustomFieldVisibility implements GraphqlFieldVisibility { final YourUserAccessService userAccessService; @@ -211,19 +231,23 @@ public GraphQLFieldDefinition getFieldDefinition(GraphQLFieldsContainer fieldsCo return fieldsContainer.getFieldDefinition(fieldName); } } + //::/FigureL private void sendAsJson(Map toSpecificationResult) { } public void toSpec() throws Exception { + //::FigureM ExecutionResult executionResult = graphQL.execute(executionInput); Map toSpecificationResult = executionResult.toSpecification(); sendAsJson(toSpecificationResult); + //::/FigureM } + //::FigureN class CustomRuntimeException extends RuntimeException implements GraphQLError { @Override public Map getExtensions() { @@ -243,6 +267,7 @@ public ErrorType getErrorType() { return ErrorType.DataFetchingException; } } + //::/FigureN private class User { @@ -268,4 +293,26 @@ private GraphQL buildSchema() { .build(); } + private void emitAMetric(Object inputValue, GraphQLInputType graphQLInputType) { + return; + } + + private void inputInterceptorObservesExample() { + InputInterceptor legacyInputInterceptor = LegacyCoercingInputInterceptor.observesValues((inputValue, graphQLInputType) -> { + emitAMetric(inputValue, graphQLInputType); + }); + + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query("query { exampleField }") + .graphQLContext(Map.of(InputInterceptor.class, legacyInputInterceptor)) + .build(); + } + + private void inputInterceptorMigratesExample() { + ExecutionInput executionInput = ExecutionInput.newExecutionInput() + .query("query { exampleField }") + .graphQLContext(Map.of(InputInterceptor.class, LegacyCoercingInputInterceptor.migratesValues())) + .build(); + } + } diff --git a/src/test/groovy/readme/FieldSelectionExamples.java b/src/test/groovy/readme/FieldSelectionExamples.java new file mode 100644 index 0000000000..19fc4fb121 --- /dev/null +++ b/src/test/groovy/readme/FieldSelectionExamples.java @@ -0,0 +1,50 @@ +package readme; + +import graphql.schema.DataFetcher; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.DataFetchingFieldSelectionSet; +import graphql.schema.SelectedField; + +import java.util.List; + +@SuppressWarnings({"unused", "Convert2Lambda"}) +public class FieldSelectionExamples { + + void usingSelectionSet() { + DataFetcher smartUserDF = new DataFetcher() { + @Override + public Object get(DataFetchingEnvironment env) { + String userId = env.getArgument("userId"); + + DataFetchingFieldSelectionSet selectionSet = env.getSelectionSet(); + if (selectionSet.contains("friends/*")) { + return getUserAndTheirFriends(userId); + } else { + return getUser(userId); + } + } + }; + } + + DataFetchingEnvironment env; + + void getFields() { + DataFetchingFieldSelectionSet selectionSet = env.getSelectionSet(); + List nodeFields = selectionSet.getFields("edges/nodes/*"); + nodeFields.forEach(selectedField -> { + System.out.println(selectedField.getName()); + System.out.println(selectedField.getType()); + + DataFetchingFieldSelectionSet innerSelectionSet = selectedField.getSelectionSet(); + // .. this forms a tree of selection and you can get very fancy with it + }); + } + + private Object getUser(String userId) { + return null; + } + + private Object getUserAndTheirFriends(String userId) { + return null; + } +} diff --git a/src/test/groovy/readme/DeferredExamples.java b/src/test/groovy/readme/IncrementalExamples.java similarity index 62% rename from src/test/groovy/readme/DeferredExamples.java rename to src/test/groovy/readme/IncrementalExamples.java index 276d390c51..3b7d1ed7be 100644 --- a/src/test/groovy/readme/DeferredExamples.java +++ b/src/test/groovy/readme/IncrementalExamples.java @@ -4,16 +4,16 @@ import graphql.ExecutionInput; import graphql.ExecutionResult; import graphql.GraphQL; +import graphql.incremental.DelayedIncrementalPartialResult; +import graphql.incremental.IncrementalExecutionResult; import graphql.schema.GraphQLSchema; +import jakarta.servlet.http.HttpServletResponse; import org.reactivestreams.Publisher; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; -import javax.servlet.http.HttpServletResponse; -import java.util.Map; - -@SuppressWarnings({"unused", "ConstantConditions", "UnusedAssignment", "unchecked"}) -public class DeferredExamples { +@SuppressWarnings({"unused", "ConstantConditions"}) +public class IncrementalExamples { GraphQLSchema buildSchemaWithDirective() { @@ -33,19 +33,26 @@ void basicExample(HttpServletResponse httpServletResponse, String deferredQuery) // ExecutionResult initialResult = graphQL.execute(ExecutionInput.newExecutionInput().query(deferredQuery).build()); + if (!(initialResult instanceof IncrementalExecutionResult)) { + // handle non incremental response + return; + } + + IncrementalExecutionResult incrementalResult = (IncrementalExecutionResult) initialResult; + // - // then initial results happen first, the deferred ones will begin AFTER these initial + // then initial results happen first, the incremental ones will begin AFTER these initial // results have completed // - sendResult(httpServletResponse, initialResult); + sendMultipartHttpResult(httpServletResponse, initialResult); - Map extensions = initialResult.getExtensions(); - Publisher deferredResults = (Publisher) extensions.get(GraphQL.DEFERRED_RESULTS); + Publisher delayedIncrementalResults = incrementalResult + .getIncrementalItemPublisher(); // - // you subscribe to the deferred results like any other reactive stream + // you subscribe to the incremental results like any other reactive stream // - deferredResults.subscribe(new Subscriber() { + delayedIncrementalResults.subscribe(new Subscriber<>() { Subscription subscription; @@ -58,11 +65,11 @@ public void onSubscribe(Subscription s) { } @Override - public void onNext(ExecutionResult executionResult) { + public void onNext(DelayedIncrementalPartialResult executionResult) { // // as each deferred result arrives, send it to where it needs to go // - sendResult(httpServletResponse, executionResult); + sendMultipartHttpResult(httpServletResponse, executionResult); subscription.request(10); } @@ -84,7 +91,7 @@ private void completeResponse(HttpServletResponse httpServletResponse) { private void handleError(HttpServletResponse httpServletResponse, Throwable t) { } - private void sendResult(HttpServletResponse httpServletResponse, ExecutionResult initialResult) { + private void sendMultipartHttpResult(HttpServletResponse httpServletResponse, Object result) { } diff --git a/src/test/groovy/readme/InstrumentationExamples.java b/src/test/groovy/readme/InstrumentationExamples.java index 826939c445..142cd4f240 100644 --- a/src/test/groovy/readme/InstrumentationExamples.java +++ b/src/test/groovy/readme/InstrumentationExamples.java @@ -3,23 +3,26 @@ import graphql.ExecutionResult; import graphql.GraphQL; import graphql.GraphQLError; -import graphql.execution.ExecutionPath; +import graphql.execution.ResultPath; import graphql.execution.instrumentation.ChainedInstrumentation; import graphql.execution.instrumentation.Instrumentation; import graphql.execution.instrumentation.InstrumentationContext; import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.SimpleInstrumentation; import graphql.execution.instrumentation.SimpleInstrumentationContext; +import graphql.execution.instrumentation.SimplePerformantInstrumentation; import graphql.execution.instrumentation.fieldvalidation.FieldAndArguments; import graphql.execution.instrumentation.fieldvalidation.FieldValidation; import graphql.execution.instrumentation.fieldvalidation.FieldValidationEnvironment; import graphql.execution.instrumentation.fieldvalidation.FieldValidationInstrumentation; import graphql.execution.instrumentation.fieldvalidation.SimpleFieldValidation; +import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters; import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; import graphql.execution.instrumentation.tracing.TracingInstrumentation; import graphql.schema.DataFetcher; import graphql.schema.GraphQLSchema; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -60,30 +63,30 @@ void recordTiming(String key, long time) { } } - class CustomInstrumentation extends SimpleInstrumentation { + class CustomInstrumentation extends SimplePerformantInstrumentation { + @Override - public InstrumentationState createState() { + public @Nullable CompletableFuture createStateAsync(InstrumentationCreateStateParameters parameters) { // // instrumentation state is passed during each invocation of an Instrumentation method // and allows you to put stateful data away and reference it during the query execution // - return new CustomInstrumentationState(); + return CompletableFuture.completedFuture(new CustomInstrumentationState()); } @Override - public InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters) { + public @Nullable InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters, InstrumentationState state) { long startNanos = System.nanoTime(); return new SimpleInstrumentationContext() { @Override public void onCompleted(ExecutionResult result, Throwable t) { - CustomInstrumentationState state = parameters.getInstrumentationState(); - state.recordTiming(parameters.getQuery(), System.nanoTime() - startNanos); + ((CustomInstrumentationState) state).recordTiming(parameters.getQuery(), System.nanoTime() - startNanos); } }; } @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters) { + public @NonNull DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, InstrumentationState state) { // // this allows you to intercept the data fetcher used to fetch a field and provide another one, perhaps // that enforces certain behaviours or has certain side effects on the data @@ -92,9 +95,9 @@ public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, Instrume } @Override - public CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters) { + public @NonNull CompletableFuture instrumentExecutionResult(ExecutionResult executionResult, InstrumentationExecutionParameters parameters, InstrumentationState state) { // - // this allows you to instrument the execution result some how. For example the Tracing support uses this to put + // this allows you to instrument the execution result somehow. For example the Tracing support uses this to put // the `extensions` map of data in place // return CompletableFuture.completedFuture(executionResult); @@ -123,7 +126,7 @@ private void chained() { private void fieldValidation() { - ExecutionPath fieldPath = ExecutionPath.parse("/user"); + ResultPath fieldPath = ResultPath.parse("/user"); FieldValidation fieldValidation = new SimpleFieldValidation() .addRule(fieldPath, new BiFunction>() { @Override diff --git a/src/test/groovy/readme/MappingExamples.java b/src/test/groovy/readme/MappingExamples.java index bb4c5a02b0..15309b3e21 100644 --- a/src/test/groovy/readme/MappingExamples.java +++ b/src/test/groovy/readme/MappingExamples.java @@ -3,6 +3,7 @@ import graphql.Scalars; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLFieldDefinition; import graphql.schema.PropertyDataFetcher; @@ -11,6 +12,8 @@ import java.util.List; import java.util.Map; +import static graphql.schema.FieldCoordinates.coordinates; + @SuppressWarnings({"Convert2Lambda", "unused", "ClassCanBeStatic"}) public class MappingExamples { @@ -132,7 +135,12 @@ private void directWiring() { GraphQLFieldDefinition descriptionField = GraphQLFieldDefinition.newFieldDefinition() .name("description") .type(Scalars.GraphQLString) - .dataFetcher(PropertyDataFetcher.fetching("desc")) + .build(); + + GraphQLCodeRegistry codeRegistry = GraphQLCodeRegistry.newCodeRegistry() + .dataFetcher( + coordinates("ObjectType", "description"), + PropertyDataFetcher.fetching("desc")) .build(); } diff --git a/src/test/groovy/readme/ReadmeExamples.java b/src/test/groovy/readme/ReadmeExamples.java index f7f62624f9..6eb795279e 100644 --- a/src/test/groovy/readme/ReadmeExamples.java +++ b/src/test/groovy/readme/ReadmeExamples.java @@ -1,18 +1,19 @@ package readme; -import graphql.GraphQL; +import graphql.ErrorClassification; +import graphql.GraphQLError; +import graphql.GraphqlErrorBuilder; +import graphql.InvalidSyntaxError; import graphql.Scalars; import graphql.StarWarsData; -import graphql.StarWarsSchema; import graphql.TypeResolutionEnvironment; -import graphql.execution.AsyncExecutionStrategy; -import graphql.execution.ExecutorServiceExecutionStrategy; import graphql.language.Directive; import graphql.language.FieldDefinition; import graphql.language.TypeDefinition; import graphql.schema.Coercing; import graphql.schema.DataFetcher; import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLCodeRegistry; import graphql.schema.GraphQLEnumType; import graphql.schema.GraphQLInputObjectType; import graphql.schema.GraphQLInterfaceType; @@ -37,9 +38,6 @@ import java.io.File; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import static graphql.GarfieldSchema.Cat; import static graphql.GarfieldSchema.CatType; @@ -49,7 +47,9 @@ import static graphql.Scalars.GraphQLBoolean; import static graphql.Scalars.GraphQLString; import static graphql.StarWarsSchema.queryType; +import static graphql.schema.FieldCoordinates.coordinates; import static graphql.schema.GraphQLArgument.newArgument; +import static graphql.schema.GraphQLCodeRegistry.newCodeRegistry; import static graphql.schema.GraphQLEnumType.newEnum; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLInputObjectField.newInputObjectField; @@ -84,6 +84,9 @@ void creatingASchema() { .query(queryType) // must be provided .mutation(mutationType) // is optional .build(); + + GraphQLUnionType.Builder description = newUnionType().description(""); + description.definition(null).build(); } void listsAndNonNullLists() { @@ -91,7 +94,7 @@ void listsAndNonNullLists() { GraphQLNonNull.nonNull(GraphQLString); // a non null String - // with static imports its even shorter + // with static imports it's even shorter newArgument() .name("example") .type(nonNull(list(GraphQLString))); @@ -143,23 +146,28 @@ void enumTypes() { } void unionType() { + TypeResolver typeResolver = new TypeResolver() { + @Override + public GraphQLObjectType getType(TypeResolutionEnvironment env) { + if (env.getObject() instanceof Cat) { + return CatType; + } + if (env.getObject() instanceof Dog) { + return DogType; + } + return null; + } + }; GraphQLUnionType PetType = newUnionType() .name("Pet") .possibleType(CatType) .possibleType(DogType) - .typeResolver(new TypeResolver() { - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment env) { - if (env.getObject() instanceof Cat) { - return CatType; - } - if (env.getObject() instanceof Dog) { - return DogType; - } - return null; - } - }) .build(); + + GraphQLCodeRegistry codeRegistry = newCodeRegistry() + .typeResolver("Pet", typeResolver) + .build(); + } @@ -173,23 +181,6 @@ void recursiveTypes() { .build(); } - void executionStrategies() { - - ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( - 2, /* core pool size 2 thread */ - 2, /* max pool size 2 thread */ - 30, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(), - new ThreadPoolExecutor.CallerRunsPolicy()); - - GraphQL graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) - .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(threadPoolExecutor)) - .mutationExecutionStrategy(new AsyncExecutionStrategy()) - .subscriptionExecutionStrategy(new AsyncExecutionStrategy()) - .build(); - - } - void dataFetching() { DataFetcher fooDataFetcher = new DataFetcher() { @@ -207,7 +198,13 @@ public Foo get(DataFetchingEnvironment environment) { .field(newFieldDefinition() .name("foo") .type(GraphQLString) - .dataFetcher(fooDataFetcher)) + ) + .build(); + + GraphQLCodeRegistry codeRegistry = newCodeRegistry() + .dataFetcher( + coordinates("ObjectType", "foo"), + fooDataFetcher) .build(); } @@ -242,14 +239,14 @@ private ReviewStore reviewStore() { void mutationExample() { - GraphQLInputObjectType episodeType = GraphQLInputObjectType.newInputObject() + GraphQLInputObjectType episodeType = newInputObject() .name("Episode") .field(newInputObjectField() .name("episodeNumber") .type(Scalars.GraphQLInt)) .build(); - GraphQLInputObjectType reviewInputType = GraphQLInputObjectType.newInputObject() + GraphQLInputObjectType reviewInputType = newInputObject() .name("ReviewInput") .field(newInputObjectField() .name("stars") @@ -281,13 +278,21 @@ void mutationExample() { .name("review") .type(reviewInputType) ) - .dataFetcher(mutationDataFetcher()) ) .build(); + GraphQLCodeRegistry codeRegistry = newCodeRegistry() + .dataFetcher( + coordinates("CreateReviewForEpisodeMutation", "createReview"), + mutationDataFetcher() + ) + .build(); + + GraphQLSchema schema = GraphQLSchema.newSchema() .query(queryType) .mutation(createReviewForEpisodeMutation) + .codeRegistry(codeRegistry) .build(); } @@ -300,7 +305,7 @@ public Review get(DataFetchingEnvironment environment) { // be maps. You can convert them to POJOs inside the data fetcher if that // suits your code better // - // See http://facebook.github.io/graphql/October2016/#sec-Input-Objects + // See https://spec.graphql.org/October2021/#sec-Input-Objects // Map episodeInputMap = environment.getArgument("episode"); Map reviewInputMap = environment.getArgument("review"); @@ -450,6 +455,30 @@ public GraphQLObjectType getType(TypeResolutionEnvironment env) { }; } + static class SpecialError extends InvalidSyntaxError { + + public SpecialError(SpecialErrorBuilder builder) { + super(builder.getLocations(), builder.getMessage()); + } + } + + static class SpecialErrorBuilder extends GraphqlErrorBuilder { + + @Override + public SpecialError build() { + return new SpecialError(this); + } + } + + private void errorBuilderExample() { + GraphQLError err = GraphQLError.newError() + .message("direct") + .errorType(ErrorClassification.errorClassification("customClassification")) + .build(); + + SpecialError specialErr = new SpecialErrorBuilder().message("special").build(); + } + private DataFetcher createDataFetcher(FieldDefinition definition, Directive directive) { throw new UnsupportedOperationException("Not implemented"); } @@ -467,7 +496,7 @@ private Directive getDirective(FieldDefinition fieldDefintion, String type) { } - public static GraphQLScalarType CustomScalar = new GraphQLScalarType("Custom", "Custom Scalar", new Coercing() { + public static GraphQLScalarType CustomScalar = GraphQLScalarType.newScalar().name("Custom").description("Custom Scalar").coercing(new Coercing() { @Override public Integer serialize(Object input) { throw new UnsupportedOperationException("Not implemented"); @@ -482,7 +511,7 @@ public Integer parseValue(Object input) { public Integer parseLiteral(Object input) { throw new UnsupportedOperationException("Not implemented"); } - }); + }).build(); private File loadSchema(String s) { return null; diff --git a/src/test/groovy/readme/ScalarExamples.java b/src/test/groovy/readme/ScalarExamples.java index ee46a76aaa..601d949d67 100644 --- a/src/test/groovy/readme/ScalarExamples.java +++ b/src/test/groovy/readme/ScalarExamples.java @@ -1,12 +1,16 @@ package readme; +import graphql.GraphQLContext; +import graphql.execution.CoercedVariables; import graphql.language.StringValue; +import graphql.language.Value; import graphql.schema.Coercing; import graphql.schema.CoercingParseLiteralException; import graphql.schema.CoercingParseValueException; import graphql.schema.CoercingSerializeException; import graphql.schema.GraphQLScalarType; +import java.util.Locale; import java.util.regex.Pattern; @SuppressWarnings("unused") @@ -14,22 +18,26 @@ public class ScalarExamples { public static class EmailScalar { - public static final GraphQLScalarType EMAIL = new GraphQLScalarType("email", "A custom scalar that handles emails", new Coercing() { - @Override - public Object serialize(Object dataFetcherResult) { - return serializeEmail(dataFetcherResult); - } + public static final GraphQLScalarType EMAIL = GraphQLScalarType.newScalar() + .name("email") + .description("A custom scalar that handles emails") + .coercing(new Coercing() { + @Override + public Object serialize(Object dataFetcherResult, GraphQLContext graphQLContext, Locale locale) { + return serializeEmail(dataFetcherResult); + } - @Override - public Object parseValue(Object input) { - return parseEmailFromVariable(input); - } + @Override + public Object parseValue(Object input, GraphQLContext graphQLContext, Locale locale) { + return parseEmailFromVariable(input); + } - @Override - public Object parseLiteral(Object input) { - return parseEmailFromAstLiteral(input); - } - }); + @Override + public Object parseLiteral(Value input, CoercedVariables variables, GraphQLContext graphQLContext, Locale locale) { + return parseEmailFromAstLiteral(input); + } + }) + .build(); private static boolean looksLikeAnEmailAddress(String possibleEmailValue) { @@ -69,5 +77,4 @@ private static Object parseEmailFromAstLiteral(Object input) { } } - } diff --git a/src/test/groovy/readme/SchemaTransformExamples.java b/src/test/groovy/readme/SchemaTransformExamples.java new file mode 100644 index 0000000000..7037fac173 --- /dev/null +++ b/src/test/groovy/readme/SchemaTransformExamples.java @@ -0,0 +1,83 @@ +package readme; + +import graphql.Scalars; +import graphql.schema.DataFetcher; +import graphql.schema.FieldCoordinates; +import graphql.schema.GraphQLCodeRegistry; +import graphql.schema.GraphQLFieldDefinition; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.GraphQLSchemaElement; +import graphql.schema.GraphQLTypeVisitorStub; +import graphql.schema.SchemaTransformer; +import graphql.util.TraversalControl; +import graphql.util.TraverserContext; + +import static graphql.util.TraversalControl.CONTINUE; + +@SuppressWarnings("ALL") +public class SchemaTransformExamples { + + GraphQLSchema schema; + + void trasnformSchema() { + GraphQLTypeVisitorStub visitor = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) { + GraphQLCodeRegistry.Builder codeRegistry = context.getVarFromParents(GraphQLCodeRegistry.Builder.class); + // we need to change __XXX introspection types to have directive extensions + if (someConditionalLogic(objectType)) { + GraphQLObjectType newObjectType = buildChangedObjectType(objectType, codeRegistry); + return changeNode(context, newObjectType); + } + return CONTINUE; + } + + private boolean someConditionalLogic(GraphQLObjectType objectType) { + // up to you to decide what causes a change, perhaps a directive is on the element + return objectType.hasDirective("specialDirective"); + } + + private GraphQLObjectType buildChangedObjectType(GraphQLObjectType objectType, GraphQLCodeRegistry.Builder codeRegistry) { + GraphQLFieldDefinition newField = GraphQLFieldDefinition.newFieldDefinition() + .name("newField").type(Scalars.GraphQLString).build(); + GraphQLObjectType newObjectType = objectType.transform(builder -> builder.field(newField)); + + DataFetcher newDataFetcher = dataFetchingEnvironment -> { + return "someValueForTheNewField"; + }; + FieldCoordinates coordinates = FieldCoordinates.coordinates(objectType.getName(), newField.getName()); + codeRegistry.dataFetcher(coordinates, newDataFetcher); + return newObjectType; + } + }; + GraphQLSchema newSchema = SchemaTransformer.transformSchema(schema, visitor); + } + + void example_commands() { + + GraphQLSchemaElement updatedElement = null; + GraphQLSchemaElement newElement = null; + + GraphQLTypeVisitorStub visitor = new GraphQLTypeVisitorStub() { + @Override + public TraversalControl visitGraphQLObjectType(GraphQLObjectType objectType, TraverserContext context) { + + // changes the current element in the schema + changeNode(context, updatedElement); + + // inserts a new element after the current one in the schema + insertAfter(context, newElement); + + // inserts a new element before the current one in teh schema + insertBefore(context, newElement); + + // deletes the current element from the schema + deleteNode(context); + + + return CONTINUE; + } + }; + } +} diff --git a/src/test/java/graphql/schema/scalars/JsonScalar.java b/src/test/java/graphql/schema/scalars/JsonScalar.java new file mode 100644 index 0000000000..fe2decfb98 --- /dev/null +++ b/src/test/java/graphql/schema/scalars/JsonScalar.java @@ -0,0 +1,19 @@ +package graphql.schema.scalars; + +import graphql.Internal; +import graphql.schema.GraphQLScalarType; + +import static graphql.schema.scalars.ObjectScalar.OBJECT_COERCING; + +/** + * Copied from ExtendedScalars to avoid the circular dependency but used for testing as an example of a complex scalar + */ +@Internal +public class JsonScalar { + + public static GraphQLScalarType JSON_SCALAR = GraphQLScalarType.newScalar() + .name("JSON") + .description("A JSON scalar") + .coercing(OBJECT_COERCING) + .build(); +} diff --git a/src/test/java/graphql/schema/scalars/ObjectScalar.java b/src/test/java/graphql/schema/scalars/ObjectScalar.java new file mode 100644 index 0000000000..6182c68e2e --- /dev/null +++ b/src/test/java/graphql/schema/scalars/ObjectScalar.java @@ -0,0 +1,178 @@ +package graphql.schema.scalars; + +import com.google.common.collect.Maps; +import graphql.Assert; +import graphql.Internal; +import graphql.language.ArrayValue; +import graphql.language.BooleanValue; +import graphql.language.EnumValue; +import graphql.language.FloatValue; +import graphql.language.IntValue; +import graphql.language.NullValue; +import graphql.language.ObjectField; +import graphql.language.ObjectValue; +import graphql.language.StringValue; +import graphql.language.Value; +import graphql.language.VariableReference; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import graphql.schema.GraphQLScalarType; +import graphql.util.FpKit; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static graphql.language.ObjectField.newObjectField; + +/** + * Copied from ExtendedScalars to avoid the circular dependency but used for testing as an example of a complex scalar + */ +@Internal +public class ObjectScalar { + + static Coercing OBJECT_COERCING = new Coercing() { + @Override + public Object serialize(Object input) throws CoercingSerializeException { + return input; + } + + @Override + public Object parseValue(Object input) throws CoercingParseValueException { + return input; + } + + @Override + public Object parseLiteral(Object input) throws CoercingParseLiteralException { + // on purpose - object scalars can be null + //noinspection ConstantConditions + return parseLiteral(input, Collections.emptyMap()); + } + + @Override + public Object parseLiteral(Object input, Map variables) throws CoercingParseLiteralException { + if (!(input instanceof Value)) { + throw new CoercingParseLiteralException( + "Expected AST type 'Value' but was '" + typeName(input) + "'." + ); + } + if (input instanceof NullValue) { + return null; + } + if (input instanceof FloatValue) { + return ((FloatValue) input).getValue(); + } + if (input instanceof StringValue) { + return ((StringValue) input).getValue(); + } + if (input instanceof IntValue) { + return ((IntValue) input).getValue(); + } + if (input instanceof BooleanValue) { + return ((BooleanValue) input).isValue(); + } + if (input instanceof EnumValue) { + return ((EnumValue) input).getName(); + } + if (input instanceof VariableReference) { + String varName = ((VariableReference) input).getName(); + return variables.get(varName); + } + if (input instanceof ArrayValue) { + List values = ((ArrayValue) input).getValues(); + return values.stream() + .map(v -> parseLiteral(v, variables)) + .collect(Collectors.toList()); + } + if (input instanceof ObjectValue) { + List values = ((ObjectValue) input).getObjectFields(); + Map parsedValues = Maps.newLinkedHashMapWithExpectedSize(values.size()); + values.forEach(fld -> { + Object parsedValue = parseLiteral(fld.getValue(), variables); + parsedValues.put(fld.getName(), parsedValue); + }); + return parsedValues; + } + return Assert.assertShouldNeverHappen("We have covered all Value types"); + } + + @Override + public Value valueToLiteral(Object input) { + if (input == null) { + return NullValue.newNullValue().build(); + } + if (input instanceof String) { + return new StringValue((String) input); + } + if (input instanceof Float) { + return new FloatValue(BigDecimal.valueOf((Float) input)); + } + if (input instanceof Double) { + return new FloatValue(BigDecimal.valueOf((Double) input)); + } + if (input instanceof BigDecimal) { + return new FloatValue((BigDecimal) input); + } + if (input instanceof BigInteger) { + return new IntValue((BigInteger) input); + } + if (input instanceof Number) { + long l = ((Number) input).longValue(); + return new IntValue(BigInteger.valueOf(l)); + } + if (input instanceof Boolean) { + return new BooleanValue((Boolean) input); + } + if (FpKit.isIterable(input)) { + return handleIterable(FpKit.toIterable(input)); + } + if (input instanceof Map) { + return handleMap((Map) input); + } + throw new UnsupportedOperationException("The ObjectScalar cant handle values of type : " + input.getClass()); + } + + private Value handleMap(Map map) { + ObjectValue.Builder builder = ObjectValue.newObjectValue(); + for (Map.Entry entry : map.entrySet()) { + String name = String.valueOf(entry.getKey()); + Value value = valueToLiteral(entry.getValue()); + + builder.objectField( + newObjectField().name(name).value(value).build() + ); + } + return builder.build(); + } + + @SuppressWarnings("rawtypes") + private Value handleIterable(Iterable input) { + List values = new ArrayList<>(); + for (Object val : input) { + values.add(valueToLiteral(val)); + } + return ArrayValue.newArrayValue().values(values).build(); + } + + String typeName(Object input) { + if (input == null) { + return "null"; + } + return input.getClass().getSimpleName(); + } + }; + + + public static GraphQLScalarType OBJECT_SCALAR = GraphQLScalarType.newScalar() + .name("Object") + .description("An object scalar") + .coercing(OBJECT_COERCING) + .build(); +} diff --git a/src/test/java/reproductions/SubscriptionReproduction.java b/src/test/java/reproductions/SubscriptionReproduction.java new file mode 100644 index 0000000000..47bde26e74 --- /dev/null +++ b/src/test/java/reproductions/SubscriptionReproduction.java @@ -0,0 +1,202 @@ +package reproductions; + +import graphql.ExecutionInput; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.execution.SubscriptionExecutionStrategy; +import graphql.schema.DataFetchingEnvironment; +import graphql.schema.GraphQLSchema; +import graphql.schema.idl.RuntimeWiring; +import graphql.schema.idl.SchemaGenerator; +import graphql.schema.idl.SchemaParser; +import org.jspecify.annotations.NonNull; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +import java.util.Map; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; + +import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring; +import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring; + +/** + * Related to ... + *

    + * This reproduction is to see what's happening with Subscriptions and whether they keep their + * order when values are async. + */ +public class SubscriptionReproduction { + public static void main(String[] args) { + new SubscriptionReproduction().run(args); + } + + private void run(String[] args) { + + boolean ordered = args.length > 0 && "ordered".equals(args[0]); + + GraphQL graphQL = mkGraphQl(); + String query = "subscription MySubscription {\n" + + " searchVideo {\n" + + " id\n" + + " name\n" + + " lastEpisode\n" + + " isFavorite\n" + + " }\n" + + "}"; + + ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(query).graphQLContext( + b -> b.put(SubscriptionExecutionStrategy.KEEP_SUBSCRIPTION_EVENTS_ORDERED, ordered) + ).build(); + ExecutionResult executionResult = graphQL.execute(executionInput); + Publisher> publisher = executionResult.getData(); + + DeathEater eater = new DeathEater(); + eater.eat(publisher); + } + + private GraphQL mkGraphQl() { + String sdl = "type Query { f : ID }" + + "type Subscription {" + + " searchVideo : VideoSearch" + + "}" + + "type VideoSearch {" + + " id : ID" + + " name : String" + + " lastEpisode : String" + + " isFavorite : Boolean" + + "}"; + RuntimeWiring runtimeWiring = newRuntimeWiring() + .type(newTypeWiring("Subscription") + .dataFetcher("searchVideo", this::mkFluxDF) + ) + .type(newTypeWiring("VideoSearch") + .dataFetcher("name", this::nameDF) + .dataFetcher("isFavorite", this::isFavoriteDF) + .dataFetcher("lastEpisode", this::lastEpisode) + ) + .build(); + + GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema( + new SchemaParser().parse(sdl), runtimeWiring + ); + return GraphQL.newGraphQL(schema).build(); + } + + private CompletableFuture> mkFluxDF(DataFetchingEnvironment env) { + // async deliver of the publisher with random snoozing between values + Supplier> fluxSupplier = () -> Flux.generate(() -> 0, (counter, sink) -> { + sink.next(mkValue(counter)); + snooze(rand(10, 100)); + if (counter == 10) { + sink.complete(); + } + return counter + 1; + }); + return CompletableFuture.supplyAsync(fluxSupplier); + } + + private Object isFavoriteDF(DataFetchingEnvironment env) { + // async deliver of the isFavorite property with random delay + return CompletableFuture.supplyAsync(() -> { + Integer counter = getCounter(env.getSource()); + return counter % 2 == 0; + }); + } + + private Object lastEpisode(DataFetchingEnvironment env) { + // Mono-based async property that uses CF as the interface + return Mono.fromCallable(() -> { + Integer counter = getCounter(env.getSource()); + return "episode-" + Thread.currentThread().getName() + "for" + counter; + }) + .publishOn(Schedulers.boundedElastic()) + .toFuture(); + } + + private Object nameDF(DataFetchingEnvironment env) { + // async deliver of the isFavorite property with random delay + return CompletableFuture.supplyAsync(() -> { + Integer counter = getCounter(env.getSource()); + return "name" + counter; + }); + } + + private static Integer getCounter(Map video) { + Integer counter = (Integer) video.getOrDefault("counter", 0); + snooze(rand(100, 500)); + return counter; + } + + private @NonNull Object mkValue(Integer counter) { + // name and isFavorite are future values via DFs + return Map.of( + "counter", counter, + "id", String.valueOf(counter) // immediate value + ); + } + + + private static void snooze(int ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + static Random rn = new Random(); + + private static int rand(int min, int max) { + return rn.nextInt(max - min + 1) + min; + } + + public static class DeathEater implements Subscriber { + private Subscription subscription; + private final AtomicBoolean done = new AtomicBoolean(); + + public boolean isDone() { + return done.get(); + } + + @Override + public void onSubscribe(Subscription subscription) { + this.subscription = subscription; + System.out.println("onSubscribe"); + subscription.request(10); + } + + @Override + public void onNext(Object o) { + System.out.println("\tonNext : " + o); + subscription.request(1); + } + + @Override + public void onError(Throwable throwable) { + System.out.println("onError"); + throwable.printStackTrace(System.err); + done.set(true); + } + + @Override + public void onComplete() { + System.out.println("complete"); + done.set(true); + } + + public void eat(Publisher publisher) { + publisher.subscribe(this); + while (!this.isDone()) { + snooze(2); + } + + } + } +} diff --git a/src/test/resources/dataLoaderPerformanceSchema.graphqls b/src/test/resources/dataLoaderPerformanceSchema.graphqls new file mode 100644 index 0000000000..1c1da310ec --- /dev/null +++ b/src/test/resources/dataLoaderPerformanceSchema.graphqls @@ -0,0 +1,17 @@ +type Query { + owners: [Owner] +} + +type Owner { + id: ID! + name: String + pets: [Pet] +} + +type Pet { + id: ID! + name: String + owner: Owner + friends: [Pet] +} + diff --git a/src/test/resources/diff/schema_ABaseLine.graphqls b/src/test/resources/diff/schema_ABaseLine.graphqls index 0258ead4a6..59806923f1 100644 --- a/src/test/resources/diff/schema_ABaseLine.graphqls +++ b/src/test/resources/diff/schema_ABaseLine.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_changed_field_arguments.graphqls b/src/test/resources/diff/schema_changed_field_arguments.graphqls index 9ba5516a24..e8c0c260fe 100644 --- a/src/test/resources/diff/schema_changed_field_arguments.graphqls +++ b/src/test/resources/diff/schema_changed_field_arguments.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -23,8 +24,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_changed_input_object_fields.graphqls b/src/test/resources/diff/schema_changed_input_object_fields.graphqls index c700657180..d7d026ffa8 100644 --- a/src/test/resources/diff/schema_changed_input_object_fields.graphqls +++ b/src/test/resources/diff/schema_changed_input_object_fields.graphqls @@ -4,7 +4,8 @@ schema { } type Query { - being(id : ID, type : String = "wizard") : Being + #being(id : ID, type : String = "wizard") : Being + being(id : ID, type : String, newArg : String!) : Being beings(type : String) : [Being] wizards : [Istari] @@ -12,6 +13,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,11 +24,21 @@ type Mutation { } input Questor { + #beingID : ID! beingID : ID + + #queryTarget : String queryTarget : Int + + #nestedInput : NestedInput + nestedInput : NestedInput! newMandatoryField : String! } +input NestedInput { + nestedInput: String +} + scalar CustomScalar diff --git a/src/test/resources/diff/schema_changed_nested_input_object_fields.graphqls b/src/test/resources/diff/schema_changed_nested_input_object_fields.graphqls new file mode 100644 index 0000000000..d3009f7db7 --- /dev/null +++ b/src/test/resources/diff/schema_changed_nested_input_object_fields.graphqls @@ -0,0 +1,82 @@ +schema { + query : Query + mutation : Mutation +} + +type Query { + being(id : ID, type : String = "wizard") : Being + beings(type : String) : [Being] + + wizards : [Istari] + gods : [Ainur] + deities : [Deity] + + allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] + + customScalar : CustomScalar +} + +type Mutation { + being(questor : Questor) : Query + sword(bearer : Questor, name : String, alloy : String, temperament : Temperament) : String +} + +input Questor { + beingID : ID! + queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: Int +} + +scalar CustomScalar + + +interface Being { + id : ID + name : String + nameInQuenyan : String + invitedBy(id : ID) : Being +} + + +type Ainur implements Being { + id : ID + name : String + nameInQuenyan : String + invitedBy(id : ID) : Being + loves : String +} + + +type Istari implements Being { + id : ID + name : String + nameInQuenyan : String + invitedBy(id : ID) : Being + colour : String + temperament : Temperament! + +} + +type Deity implements Being { + id : ID + name : String + nameInQuenyan : String + invitedBy(id : ID) : Being + outlook : String +} + +union Character = Ainur | Istari | Deity + +enum Temperament { + Hero + Duplicitous + Evil +} + + + diff --git a/src/test/resources/diff/schema_changed_object_fields.graphqls b/src/test/resources/diff/schema_changed_object_fields.graphqls index 4d0465697b..4c5f273dca 100644 --- a/src/test/resources/diff/schema_changed_object_fields.graphqls +++ b/src/test/resources/diff/schema_changed_object_fields.graphqls @@ -4,8 +4,7 @@ schema { } type Query { - #being(id : ID, type : String = "wizard") : Being - being(id : ID, type : String, newArg : String!) : Being + being(id : ID, type : String = "wizard") : Being #beings(type : String) : [Being] beings(type : String) : Being @@ -18,6 +17,9 @@ type Query { #allCharacters : [Character!] @deprecated(reason: "no longer supported") allCharacters : [Character!] + #allCharactersByTemperament : [[Character]] + allCharactersByTemperament : [[Character!]]! + #customScalar : CustomScalar customScalar : [CustomScalar]! } @@ -28,15 +30,21 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar interface Being { - id : ID + #id : ID + id : ID! name : String nameInQuenyan : String invitedBy(id : ID) : Being @@ -44,7 +52,8 @@ interface Being { type Ainur implements Being { - id : ID + #id : ID + id : ID! name : String nameInQuenyan : String invitedBy(id : ID) : Being @@ -53,17 +62,21 @@ type Ainur implements Being { type Istari implements Being { - id : ID + #id : ID + id : ID! name : String nameInQuenyan : String invitedBy(id : ID) : Being colour : String - temperament : Temperament! + + #temperament : Temperament! + temperament : Temperament } type Deity implements Being { - id : ID + #id : ID + id : ID! name : String nameInQuenyan : String invitedBy(id : ID) : Being diff --git a/src/test/resources/diff/schema_changed_type_kind.graphqls b/src/test/resources/diff/schema_changed_type_kind.graphqls index 6f474e0b39..14e85658f9 100644 --- a/src/test/resources/diff/schema_changed_type_kind.graphqls +++ b/src/test/resources/diff/schema_changed_type_kind.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_dangerous_changes.graphqls b/src/test/resources/diff/schema_dangerous_changes.graphqls index cfccdbd11e..1fa8b8808e 100644 --- a/src/test/resources/diff/schema_dangerous_changes.graphqls +++ b/src/test/resources/diff/schema_dangerous_changes.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_deprecated_fields_new.graphqls b/src/test/resources/diff/schema_deprecated_fields_new.graphqls new file mode 100644 index 0000000000..53dc321ede --- /dev/null +++ b/src/test/resources/diff/schema_deprecated_fields_new.graphqls @@ -0,0 +1,82 @@ +schema { + query : Query + mutation : Mutation +} + +type Query { + being(id : ID, type : String = "wizard") : Being + beings(type : String) : [Being] @deprecated + + wizards : [Istari] + gods : [Ainur] + deities : [Deity] @deprecated + + allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] @deprecated(reason: "remove all Character references") + + customScalar : CustomScalar @deprecated(reason: "because") +} + +type Mutation { + being(questor : Questor) : Query + sword(bearer : Questor, name : String, alloy : String, temperament : Temperament) : String +} + +input Questor { + beingID : ID + queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String +} + +scalar CustomScalar + + +interface Being { + id : ID + name : String + nameInQuenyan : String @deprecated + invitedBy(id : ID) : Being +} + + +type Ainur implements Being { + id : ID + name : String + nameInQuenyan : String @deprecated + invitedBy(id : ID) : Being + loves : String +} + + +type Istari implements Being { + id : ID + name : String + nameInQuenyan : String @deprecated + invitedBy(id : ID) : Being + colour : String @deprecated + temperament : Temperament! + +} + +type Deity implements Being { + id : ID + name : String + nameInQuenyan : String @deprecated + invitedBy(id : ID) : Being + outlook : String @deprecated +} + +union Character = Ainur | Istari | Deity + +enum Temperament { + Hero + Duplicitous @deprecated + Evil +} + + + diff --git a/src/test/resources/diff/schema_deprecated_fields_removed.graphqls b/src/test/resources/diff/schema_deprecated_fields_removed.graphqls new file mode 100644 index 0000000000..615264b8a6 --- /dev/null +++ b/src/test/resources/diff/schema_deprecated_fields_removed.graphqls @@ -0,0 +1,68 @@ +schema { + query : Query + mutation : Mutation +} + +type Query { + being(id : ID, type : String = "wizard") : Being + + wizards : [Istari] + gods : [Ainur] +} + +type Mutation { + being(questor : Questor) : Query + sword(bearer : Questor, name : String, alloy : String, temperament : Temperament) : String +} + +input Questor { + beingID : ID + queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String +} + +scalar CustomScalar + + +interface Being { + id : ID + name : String + invitedBy(id : ID) : Being +} + + +type Ainur implements Being { + id : ID + name : String + invitedBy(id : ID) : Being + loves : String +} + + +type Istari implements Being { + id : ID + name : String + invitedBy(id : ID) : Being + temperament : Temperament! + +} + +type Deity implements Being { + id : ID + name : String + invitedBy(id : ID) : Being +} + +union Character = Ainur | Istari | Deity + +enum Temperament { + Hero + Evil +} + + + diff --git a/src/test/resources/diff/schema_interface_fields_missing.graphqls b/src/test/resources/diff/schema_interface_fields_missing.graphqls index 9baaae8182..15f45aacdf 100644 --- a/src/test/resources/diff/schema_interface_fields_missing.graphqls +++ b/src/test/resources/diff/schema_interface_fields_missing.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_missing_enum_value.graphqls b/src/test/resources/diff/schema_missing_enum_value.graphqls index fc9712e0e6..7dcf130ab5 100644 --- a/src/test/resources/diff/schema_missing_enum_value.graphqls +++ b/src/test/resources/diff/schema_missing_enum_value.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_missing_field_arguments.graphqls b/src/test/resources/diff/schema_missing_field_arguments.graphqls index bf01b8c1af..1657a86eed 100644 --- a/src/test/resources/diff/schema_missing_field_arguments.graphqls +++ b/src/test/resources/diff/schema_missing_field_arguments.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -24,8 +25,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_missing_input_object_fields.graphqls b/src/test/resources/diff/schema_missing_input_object_fields.graphqls index a452802551..c06aa426d4 100644 --- a/src/test/resources/diff/schema_missing_input_object_fields.graphqls +++ b/src/test/resources/diff/schema_missing_input_object_fields.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! #queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_missing_object_fields.graphqls b/src/test/resources/diff/schema_missing_object_fields.graphqls index d70bcaf9b5..073de2507d 100644 --- a/src/test/resources/diff/schema_missing_object_fields.graphqls +++ b/src/test/resources/diff/schema_missing_object_fields.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_missing_operation.graphqls b/src/test/resources/diff/schema_missing_operation.graphqls index dd8a5b96cb..7b4ac24077 100644 --- a/src/test/resources/diff/schema_missing_operation.graphqls +++ b/src/test/resources/diff/schema_missing_operation.graphqls @@ -11,13 +11,19 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_missing_union_members.graphqls b/src/test/resources/diff/schema_missing_union_members.graphqls index fb14210fd0..51c3d2ea6a 100644 --- a/src/test/resources/diff/schema_missing_union_members.graphqls +++ b/src/test/resources/diff/schema_missing_union_members.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/diff/schema_with_additional_field.graphqls b/src/test/resources/diff/schema_with_additional_field.graphqls index f5bf305da1..1e9c4daa1c 100644 --- a/src/test/resources/diff/schema_with_additional_field.graphqls +++ b/src/test/resources/diff/schema_with_additional_field.graphqls @@ -12,6 +12,7 @@ type Query { deities : [Deity] allCharacters : [Character!] @deprecated(reason: "no longer supported") + allCharactersByTemperament : [[Character]] customScalar : CustomScalar } @@ -22,8 +23,13 @@ type Mutation { } input Questor { - beingID : ID + beingID : ID! queryTarget : String + nestedInput : NestedInput +} + +input NestedInput { + nestedInput: String } scalar CustomScalar diff --git a/src/test/resources/extra-large-schema-1-query.graphql b/src/test/resources/extra-large-schema-1-query.graphql new file mode 100644 index 0000000000..6e61f3b233 --- /dev/null +++ b/src/test/resources/extra-large-schema-1-query.graphql @@ -0,0 +1,2761 @@ +query extra_large { + jira { + epicLinkFieldKey + screenIdByIssueKey(issueKey: "GJ-1") + issueByKey(key: "GJ-1", cloudId: "abc123") { + issueId + fields { + edges { + node { + __typename + ... on JiraAffectedServicesField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedAffectedServicesConnection { + totalCount + edges { + node { + serviceId + } + } + } + affectedServices { + totalCount + edges { + node { + serviceId + } + } + } + searchUrl + } + ... on JiraAssetField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedAssetsConnection { + totalCount + edges { + node { + appKey + originId + serializedOrigin + value + } + } + } + searchUrl + } + ... on JiraCMDBField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + isMulti + searchUrl + selectedCmdbObjectsConnection { + totalCount + edges { + node { + id + objectGlobalId + objectId + workspaceId + label + } + } + } + attributesIncludedInAutoCompleteSearch + } + ... on JiraCascadingSelectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + cascadingOption { + parentOptionValue { + id + optionId + value + isDisabled + } + childOptionValue { + id + optionId + value + isDisabled + } + } + cascadingOptions { + totalCount + edges { + node { + parentOptionValue { + id + optionId + value + isDisabled + } + childOptionValues { + id + optionId + value + isDisabled + } + } + } + } + } + ... on JiraCheckboxesField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + fieldOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + } + ... on JiraColorField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + color { + id + colorKey + } + } + ... on JiraComponentsField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedComponentsConnection { + totalCount + edges { + node { + id + componentId + name + description + } + } + } + components { + totalCount + edges { + node { + id + componentId + name + description + } + } + } + } + ... on JiraConnectMultipleSelectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + fieldOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + searchUrl + } + ... on JiraConnectNumberField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + number + } + ... on JiraConnectRichTextField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + richText { + plainText + adfValue { + json + } + } + renderer + } + ... on JiraConnectSingleSelectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + fieldOption { + id + optionId + value + isDisabled + } + fieldOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + searchUrl + } + ... on JiraConnectTextField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + text + } + ... on JiraDatePickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + date + } + ... on JiraDateTimePickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + dateTime + } + ... on JiraEpicLinkField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + epic { + id + issueId + name + key + summary + color + done + } + epics { + totalCount + edges { + node { + id + issueId + name + key + summary + color + done + } + } + } + searchUrl + } + ... on JiraFlagField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + flag { + isFlagged + } + } + ... on JiraForgeGroupField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedGroup { + id + groupId + name + } + groups { + totalCount + edges { + node { + id + groupId + name + } + } + } + searchUrl + renderer + } + ... on JiraForgeGroupsField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + selectedGroupsConnection { + edges { + node { + id + groupId + name + } + } + } + renderer + } + ... on JiraForgeNumberField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + number + renderer + } + ... on JiraForgeObjectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + object + renderer + } + ... on JiraForgeStringField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + text + renderer + } + ... on JiraForgeStringsField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedLabelsConnection { + totalCount + edges { + node { + labelId + name + } + } + } + labels { + totalCount + edges { + node { + labelId + name + } + } + } + renderer + searchUrl + } + ... on JiraForgeUserField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + user { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + searchUrl + } + ... on JiraIssueRestrictionField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedRolesConnection { + totalCount + edges { + node { + id + roleId + name + description + } + } + } + roles { + totalCount + edges { + node { + id + roleId + name + description + } + } + } + searchUrl + } + ... on JiraIssueTypeField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + issueType { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + issueTypes { + edges { + node { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + } + } + } + ... on JiraLabelsField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedLabelsConnection { + totalCount + edges { + node { + labelId + name + } + } + } + labels { + totalCount + edges { + node { + labelId + name + } + } + } + searchUrl + } + ... on JiraMultipleGroupPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedGroupsConnection { + totalCount + edges { + node { + groupId + name + id + } + } + } + groups { + totalCount + edges { + node { + id + groupId + name + } + } + } + searchUrl + } + ... on JiraMultipleSelectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + fieldOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + searchUrl + } + ... on JiraMultipleSelectUserPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedUsersConnection { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + users { + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + searchUrl + } + ... on JiraMultipleVersionPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedVersionsConnection { + totalCount + edges { + node { + id + versionId + name + iconUrl + status + description + startDate + releaseDate + } + } + } + versions { + totalCount + edges { + node { + id + versionId + name + iconUrl + status + description + startDate + releaseDate + } + } + } + } + ... on JiraNumberField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + number + isStoryPointField + } + ... on JiraParentIssueField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + parentIssue { + id + issueId + key + webUrl + fieldsById(ids: ["issuetype ", "project ", "summary "]) { + edges { + node { + __typename + ... on JiraIssueTypeField { + fieldId + name + type + description + issueType { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + issueTypes { + edges { + node { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + } + } + } + ... on JiraProjectField { + fieldId + name + type + description + project { + projectId + key + name + avatar { + medium + } + projectType + status + projectStyle + id + } + } + ... on JiraSingleLineTextField { + fieldId + name + type + description + text + } + id + } + } + } + } + } + ... on JiraPeopleField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedUsersConnection { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + users { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + isMulti + searchUrl + } + ... on JiraPriorityField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + priority { + priorityId + name + iconUrl + color + id + } + priorities { + edges { + node { + priorityId + name + iconUrl + color + id + } + } + } + } + ... on JiraProjectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + project { + projectId + key + name + avatar { + medium + } + projectType + status + projectStyle + id + } + } + ... on JiraRadioSelectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedOption { + id + optionId + value + isDisabled + } + fieldOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + } + ... on JiraResolutionField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + resolution { + id + resolutionId + name + description + } + resolutions { + totalCount + edges { + node { + id + resolutionId + name + description + } + } + } + } + ... on JiraRichTextField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + richText { + plainText + adfValue { + json + } + } + renderer + } + ... on JiraSecurityLevelField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + securityLevel { + id + name + securityId + description + } + } + ... on JiraServiceManagementDateTimeField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + dateTime + } + ... on JiraServiceManagementIncidentLinkingField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + incident { + hasLinkedIncidents + } + } + ... on JiraServiceManagementMultipleSelectUserPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedUsersConnection { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + users { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + searchUrl + } + ... on JiraServiceManagementOrganizationField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedOrganizationsConnection { + totalCount + edges { + node { + organizationId + organizationName + domain + } + } + } + searchUrl + } + ... on JiraServiceManagementPeopleField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedUsersConnection { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + users { + totalCount + edges { + node { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + } + isMulti + searchUrl + } + ... on JiraServiceManagementRequestFeedbackField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + feedback { + rating + } + } + ... on JiraServiceManagementRequestLanguageField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + language { + languageCode + displayName + } + languages { + languageCode + displayName + } + } + ... on JiraServiceManagementRequestTypeField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + requestType { + id + requestTypeId + name + key + description + helpText + issueType { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + } + portalId + avatar { + xsmall + small + medium + large + } + practices { + key + } + } + requestTypes { + totalCount + edges { + node { + id + requestTypeId + name + key + description + helpText + issueType { + id + name + description + avatar { + xsmall + small + medium + large + } + } + portalId + avatar { + xsmall + small + medium + large + } + practices { + key + } + } + } + } + } + ... on JiraServiceManagementRespondersField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + respondersConnection { + edges { + node { + __typename + ... on JiraServiceManagementUserResponder { + user { + __typename + picture + name + } + } + ... on JiraServiceManagementTeamResponder { + teamId + teamName + } + } + } + } + } + ... on JiraSingleGroupPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedGroup { + id + groupId + name + } + groups { + totalCount + edges { + node { + id + groupId + name + } + } + } + searchUrl + } + ... on JiraSingleLineTextField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + text + } + ... on JiraSingleSelectField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + fieldOption { + id + optionId + value + isDisabled + } + fieldOptions { + totalCount + edges { + node { + id + optionId + value + isDisabled + } + } + } + searchUrl + } + ... on JiraSingleSelectUserPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + user { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + searchUrl + } + ... on JiraSingleVersionPickerField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + version { + id + versionId + name + iconUrl + status + description + startDate + releaseDate + } + versions { + totalCount + edges { + node { + id + versionId + name + iconUrl + status + description + startDate + releaseDate + } + } + } + } + ... on JiraSprintField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedSprintsConnection { + totalCount + edges { + node { + id + sprintId + name + state + boardName + startDate + endDate + completionDate + goal + } + } + } + sprints { + totalCount + edges { + node { + id + sprintId + name + state + boardName + startDate + endDate + completionDate + goal + } + } + } + searchUrl + } + ... on JiraStatusField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + status { + id + name + description + statusId + statusCategory { + id + statusCategoryId + key + name + colorName + } + } + } + ... on JiraTeamField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedTeam { + id + teamId + name + avatar { + xsmall + small + medium + large + } + members { + totalCount + edges { + node { + __typename + } + } + } + } + teams { + totalCount + edges { + node { + id + teamId + name + avatar { + xsmall + small + medium + large + } + members { + totalCount + edges { + node { + __typename + } + } + } + } + } + } + searchUrl + } + ... on JiraTeamViewField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + selectedTeam { + jiraSuppliedVisibility + jiraSuppliedName + jiraSuppliedId + jiraSuppliedTeamId + jiraSuppliedAvatar { + xsmall + small + medium + large + } + } + searchUrl + } + ... on JiraTimeTrackingField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + originalEstimate { + timeInSeconds + } + remainingEstimate { + timeInSeconds + } + timeSpent { + timeInSeconds + } + timeTrackingSettings { + isJiraConfiguredTimeTrackingEnabled + workingHoursPerDay + workingDaysPerWeek + defaultFormat + defaultUnit + } + } + ... on JiraUrlField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + url + } + ... on JiraVotesField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + vote { + hasVoted + count + } + } + ... on JiraWatchesField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + watch { + isWatching + count + } + } + ... on JiraForgeDatetimeField { + ... on JiraIssueField { + __isJiraIssueField: __typename + ... on JiraIssueFieldConfiguration { + __isJiraIssueFieldConfiguration: __typename + fieldConfig { + isRequired + isEditable + } + } + ... on JiraUserIssueFieldConfiguration { + __isJiraUserIssueFieldConfiguration: __typename + userFieldConfig { + isPinned + } + } + } + fieldId + name + type + description + dateTime + renderer + } + id + } + } + } + childIssues { + __typename + ... on JiraChildIssuesWithinLimit { + issues { + totalCount + edges { + node { + id + key + issueId + webUrl + fieldsById( + ids: [ + "assignee " + "created " + "issuetype " + "priority " + "status " + "summary " + "timetracking " + "updated " + ] + ) { + edges { + node { + __typename + ... on JiraIssueTypeField { + fieldId + name + type + description + issueType { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + issueTypes { + edges { + node { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + } + } + } + ... on JiraSingleLineTextField { + fieldId + name + type + description + text + } + ... on JiraPriorityField { + fieldId + name + type + description + priority { + priorityId + name + iconUrl + color + id + } + priorities { + edges { + node { + priorityId + name + iconUrl + color + id + } + } + } + } + ... on JiraStatusField { + fieldId + name + type + description + status { + id + name + description + statusId + statusCategory { + id + statusCategoryId + key + name + colorName + } + } + } + ... on JiraSingleSelectUserPickerField { + fieldId + name + type + description + user { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + searchUrl + } + ... on JiraTimeTrackingField { + fieldId + name + type + description + originalEstimate { + timeInSeconds + } + remainingEstimate { + timeInSeconds + } + timeSpent { + timeInSeconds + } + timeTrackingSettings { + isJiraConfiguredTimeTrackingEnabled + workingHoursPerDay + workingDaysPerWeek + defaultFormat + defaultUnit + } + } + ... on JiraDateTimePickerField { + fieldId + name + type + description + dateTime + } + ... on JiraDatePickerField { + fieldId + name + type + description + date + } + id + } + } + } + } + } + } + } + ... on JiraChildIssuesExceedingLimit { + search + } + } + issueLinks { + totalCount + edges { + node { + id + issueLinkId + relatedBy { + id + relationName + linkTypeId + linkTypeName + direction + } + issue { + id + issueId + key + webUrl + fieldsById( + ids: [ + "assignee " + "issuetype " + "priority " + "status " + "summary " + ] + ) { + edges { + node { + __typename + ... on JiraStatusField { + fieldId + name + type + description + status { + id + name + description + statusId + statusCategory { + id + statusCategoryId + key + name + colorName + } + } + } + ... on JiraPriorityField { + fieldId + name + type + description + priority { + priorityId + name + iconUrl + color + id + } + priorities { + edges { + node { + priorityId + name + iconUrl + color + id + } + } + } + } + ... on JiraIssueTypeField { + fieldId + name + type + description + issueType { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + issueTypes { + edges { + node { + id + issueTypeId + name + description + avatar { + xsmall + small + medium + large + } + hierarchy { + level + name + } + } + } + } + } + ... on JiraSingleLineTextField { + fieldId + name + type + description + text + } + ... on JiraSingleSelectUserPickerField { + fieldId + name + type + description + searchUrl + user { + __typename + __isUser: __typename + accountId + accountStatus + name + picture + ... on AtlassianAccountUser { + email + zoneinfo + locale + } + } + } + id + } + } + } + } + } + } + } + id + } + } +} \ No newline at end of file diff --git a/src/test/resources/extra-large-schema-1.graphqls b/src/test/resources/extra-large-schema-1.graphqls new file mode 100644 index 0000000000..0d32ac9cca --- /dev/null +++ b/src/test/resources/extra-large-schema-1.graphqls @@ -0,0 +1,15360 @@ +""" +Represents an affected service entity for a Jira Issue. +AffectedService provides context on what has been changed. +""" +type JiraAffectedService { + """ + The ID of the affected service. E.g. ari:cloud:graph::service//. + """ + serviceId: ID! + """ + The name of the affected service. E.g. Jira. + """ + name: String +} + +""" +The connection type for JiraAffectedService. +""" +type JiraAffectedServiceConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraAffectedServiceEdge] +} + +""" +An edge in a JiraAffectedService connection. +""" +type JiraAffectedServiceEdge { + """ + The node at the edge. + """ + node: JiraAffectedService + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents an approval that is completed. +""" +type JiraServiceManagementCompletedApproval implements Node { + """ + ID of the completed approval. + """ + id: ID! + """ + Name of the approval that has been provided. + """ + name: String + """ + Outcome of the approval, based on the approvals provided by all approvers. + """ + finalDecision: JiraServiceManagementApprovalDecisionResponseType + """ + Detailed list of the users who responded to the approval. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + approvers( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementApproverConnection + """ + Date the approval was created. + """ + createdDate: DateTime + """ + Date the approval was completed. + """ + completedDate: DateTime + """ + Status details in which the approval is applicable. + """ + status: JiraServiceManagementApprovalStatus +} + +""" +The connection type for JiraServiceManagementCompletedApproval. +""" +type JiraServiceManagementCompletedApprovalConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementCompletedApprovalEdge] +} + +""" +An edge in a JiraServiceManagementCompletedApproval connection. +""" +type JiraServiceManagementCompletedApprovalEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementCompletedApproval + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraServiceManagementApprover. +""" +type JiraServiceManagementApproverConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementApproverEdge] +} + +""" +An edge in a JiraServiceManagementApprover connection. +""" +type JiraServiceManagementApproverEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementApprover + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents an approval that is still active. +""" +type JiraServiceManagementActiveApproval implements Node { + """ + ID of the active approval. + """ + id: ID! + """ + Name of the approval being sought. + """ + name: String + """ + Outcome of the approval, based on the approvals provided by all approvers. + """ + finalDecision: JiraServiceManagementApprovalDecisionResponseType + """ + Detailed list of the users who responded to the approval with a decision. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + approvers( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementApproverConnection + """ + Detailed list of the users who are excluded to approve the approval. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + excludedApprovers( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraUserConnection + """ + Indicates whether the user making the request is one of the approvers and can respond to the approval (true) or not (false). + """ + canAnswerApproval: Boolean + """ + List of the users' decisions. Does not include undecided users. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + decisions( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementDecisionConnection + """ + Date the approval was created. + """ + createdDate: DateTime + """ + Configurations of the approval including the approval condition and approvers configuration. + There is a maximum limit of how many configurations an active approval can have. + """ + configurations: [JiraServiceManagementApprovalConfiguration] + """ + Status details of the approval. + """ + status: JiraServiceManagementApprovalStatus + """ + Approver principals can be a connection of users or groups that may decide on an approval. + The list includes undecided members. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + approverPrincipals( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementApproverPrincipalConnection + """ + The number of approvals needed to complete. + """ + pendingApprovalCount: Int + """ + Active Approval state, can it be achieved or not. + """ + approvalState: JiraServiceManagementApprovalState +} + +""" +The connection type for JiraServiceManagementDecision. +""" +type JiraServiceManagementDecisionConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementDecisionEdge] +} + +""" +An edge in a JiraServiceManagementDecision connection. +""" +type JiraServiceManagementDecisionEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementDecision + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraServiceManagementApproverPrincipal. +""" +type JiraServiceManagementApproverPrincipalConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementApproverPrincipalEdge] +} + +""" +An edge in a JiraServiceManagementApproverPrincipal connection. +""" +type JiraServiceManagementApproverPrincipalEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementApproverPrincipal + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Approver principals are either users or groups that may decide on an approval. +""" +union JiraServiceManagementApproverPrincipal = JiraServiceManagementUserApproverPrincipal | JiraServiceManagementGroupApproverPrincipal + + +""" +Contains information about the approvers when approver is a user. +""" +type JiraServiceManagementUserApproverPrincipal { + """ + A approver principal who's a user type + """ + user: User + """ + URL for the principal. + """ + jiraRest: URL +} +""" +The user and decision that approved the approval. +""" +type JiraServiceManagementApprover { + """ + Details of the User who is providing approval. + """ + approver: User + """ + Decision made by the approver. + """ + approverDecision: JiraServiceManagementApprovalDecisionResponseType +} + +""" +Represents the user and decision details. +""" +type JiraServiceManagementDecision { + """ + The user providing a decision. + """ + approver: User + """ + The decision made by the approver. + """ + approverDecision: JiraServiceManagementApprovalDecisionResponseType +} + +""" +Represents the possible decisions that can be made by an approver. +""" +enum JiraServiceManagementApprovalDecisionResponseType { + """ + Indicates that the decision is approved by the approver. + """ + approved + """ + Indicates that the decision is declined by the approver. + """ + declined + """ + Indicates that the decision is pending by the approver. + """ + pending +} + +""" +Represent whether approval can be achieved or not. +""" +enum JiraServiceManagementApprovalState { + """ + Indicates that approval can not be completed due to lack of approvers. + """ + INSUFFICIENT_APPROVERS + """ + Indicates that approval has sufficient user to complete. + """ + OK +} + +""" +Represents the configuration details of an approval. +""" +type JiraServiceManagementApprovalConfiguration { + """ + Contains information about approvers configuration. + There is a maximum number of fields that can be set for the approvers configuration. + """ + approversConfigurations: [JiraServiceManagementApproversConfiguration] + """ + Contains information about approval condition. + """ + condition: JiraServiceManagementApprovalCondition +} + +""" +Represents the configuration details of the users providing approval. +""" +type JiraServiceManagementApproversConfiguration { + """ + Approvers configuration type. E.g. custom_field. + """ + type: String + """ + The field's name configured for the approvers. Only set for type "field". + """ + fieldName: String + """ + The field's id configured for the approvers. + """ + fieldId: String +} + +""" +Represents the details of an approval condition. +""" +type JiraServiceManagementApprovalCondition { + """ + Condition type for approval. + """ + type: String + """ + Condition value for approval. + """ + value: String +} + +""" +Contains information about the approvers when approver is a group. +""" +type JiraServiceManagementGroupApproverPrincipal { + """ + A group identifier. + Note: Group identifiers are nullable. + """ + groupId: String + """ + Display name for a group. + """ + name: String + """ + This contains the number of members. + """ + memberCount: Int + """ + This contains the number of members that have approved a decision. + """ + approvedCount: Int +} + +""" +Represents details of the approval status. +""" +type JiraServiceManagementApprovalStatus { + """ + Status id of approval. + """ + id: String + """ + Status name of approval. E.g. Waiting for approval. + """ + name: String + """ + Status category Id of approval. + """ + categoryId: String +} +""" +Represents a single option value for an asset field. +""" +type JiraAsset { + """ + The app key, which should be the Connect app key. + This parameter is used to scope the originId. + """ + appKey: String + """ + The identifier of an asset. + This is the same identifier for the asset in its origin (external) system. + """ + originId: String + """ + The appKey + originId separated by a forward slash. + """ + serializedOrigin: String + """ + The appKey + originId separated by a forward slash. + """ + value: String +} + +""" +The connection type for JiraAsset. +""" +type JiraAssetConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraAssetEdge] +} + +""" +An edge in a JiraAsset connection. +""" +type JiraAssetEdge { + """ + The node at the edge. + """ + node: JiraAsset + """ + The cursor to this edge. + """ + cursor: String! +}""" +Deprecated type. Please use `JiraTeamView` instead. +""" +type JiraAtlassianTeam { + """ + The UUID of team. + """ + teamId: String + """ + The name of the team. + """ + name: String + """ + The avatar of the team. + """ + avatar: JiraAvatar +} + +""" +Deprecated type. +""" +type JiraAtlassianTeamConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraAtlassianTeamEdge] +} + +""" +Deprecated type. +""" +type JiraAtlassianTeamEdge { + """ + The node at the edge. + """ + node: JiraAtlassianTeam + """ + The cursor to this edge. + """ + cursor: String! +} +""" +An interface shared across all attachment types. +""" +interface JiraAttachment { + """ + Identifier for the attachment. + """ + attachmentId: String! + """ + User profile of the attachment author. + """ + author: User + """ + Date the attachment was created in seconds since the epoch. + """ + created: DateTime! + """ + Media Services file id of this Attachment, May be absent if the attachment has not yet been migrated to Media Services. + """ + mediaApiFileId: String + """ + The mimetype (also called content type) of the attachment. This may be {@code null}. + """ + mimeType: String + """ + Filename of the attachment. + """ + fileName: String + """ + Size of the attachment in bytes. + """ + fileSize: Long + """ + Parent name that this attachment is contained in e.g Issue, Field, Comment, Worklog. + """ + parentName: String + """ + Parent id that this attachment is contained in. + """ + parentId: String +} + +""" +Represents a Jira platform attachment. +""" +type JiraPlatformAttachment implements JiraAttachment & Node { + """ + Global identifier for the attachment + """ + id: ID! + """ + Identifier for the attachment. + """ + attachmentId: String! + """ + User profile of the attachment author. + """ + author: User + """ + Date the attachment was created in seconds since the epoch. + """ + created: DateTime! + """ + Media Services file id of this Attachment, May be absent if the attachment has not yet been migrated to Media Services. + """ + mediaApiFileId: String + """ + The mimetype (also called content type) of the attachment. This may be {@code null}. + """ + mimeType: String + """ + Filename of the attachment. + """ + fileName: String + """ + Size of the attachment in bytes. + """ + fileSize: Long + """ + Parent name that this attachment is contained in e.g Issue, Field, Comment, Worklog. + """ + parentName: String + """ + Parent id that this attachment is contained in. + """ + parentId: String +} + +""" +Represents an attachment within a JiraServiceManagement project. +""" +type JiraServiceManagementAttachment implements JiraAttachment & Node { + """ + Global identifier for the attachment + """ + id: ID! + """ + Identifier for the attachment. + """ + attachmentId: String! + """ + User profile of the attachment author. + """ + author: User + """ + Media Services file id of this Attachment, May be absent if the attachment has not yet been migrated to Media Services. + """ + mediaApiFileId: String + """ + Date the attachment was created in seconds since the epoch. + """ + created: DateTime! + """ + The mimetype (also called content type) of the attachment. This may be {@code null}. + """ + mimeType: String + """ + Filename of the attachment. + """ + fileName: String + """ + Size of the attachment in bytes. + """ + fileSize: Long + """ + Parent name that this attachment is contained in e.g Issue, Field, Comment, Worklog. + """ + parentName: String + """ + Parent id that this attachment is contained in. + """ + parentId: String + """ + If the parent for the JSM attachment is a comment, this represents the JSM visibility property associated with this comment. + """ + parentCommentVisibility: JiraServiceManagementCommentVisibility +} + +""" +The connection type for JiraAttachment. +""" +type JiraAttachmentConnection { + """ + The approximate count of items in the connection. + """ + indicativeCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraAttachmentEdge] +} + +""" +An edge in a JiraAttachment connection. +""" +type JiraAttachmentEdge { + """ + The node at the the edge. + """ + node: JiraAttachment + """ + The cursor to this edge. + """ + cursor: String! +} + +enum JiraAttachmentsPermissions { + "Allows the user to create atachments on the correspondig Issue." + CREATE_ATTACHMENTS, + "Allows the user to delete attachments on the corresponding Issue." + DELETE_OWN_ATTACHMENTS +} + +input JiraOrderDirection { + id: ID +} + +input JiraAttachmentsOrderField { + id: ID +} +""" +Represents the avatar size urls. +""" +type JiraAvatar { + """ + An extra-small avatar (16x16 pixels). + """ + xsmall: String + """ + A small avatar (24x24 pixels). + """ + small: String + """ + A medium avatar (32x32 pixels). + """ + medium: String + """ + A large avatar (48x48 pixels). + """ + large: String +} +""" +A union type representing childIssues available within a Jira Issue. +The *WithinLimit type is used for childIssues with a count that is within a limit specified by the server. +The *ExceedsLimit type is used for childIssues with a count that exceeds a limit specified by the server. +""" +union JiraChildIssues = JiraChildIssuesWithinLimit | JiraChildIssuesExceedingLimit + +""" +Represents childIssues with a count that is within the count limit set by the server. +""" +type JiraChildIssuesWithinLimit { + """ + Paginated list of childIssues within this Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + issues( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueConnection +} + +""" +Represents childIssues with a count that exceeds a limit set by the server. +""" +type JiraChildIssuesExceedingLimit { + """ + Search string to query childIssues when limit is exceeded. + """ + search: String +}""" +Jira Configuration Management Database. +""" +type JiraCmdbObject implements Node { + """ + Global identifier for the CMDB field. + """ + id: ID! + """ + Unique object id formed with `workspaceId`:`objectId`. + """ + objectGlobalId: String + """ + Unique id in the workspace of the CMDB object. + """ + objectId: String + """ + Workspace id of the CMDB object. + """ + workspaceId: String + """ + Label of the CMDB object. + """ + label: String + """ + The key associated with the CMDB object. + """ + objectKey: String + """ + The avatar associated with this CMDB object. + """ + avatar: JiraCmdbAvatar + """ + The CMDB object type. + """ + objectType: JiraCmdbObjectType + """ + Paginated list of attributes present on the CMDB object. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + attributes( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCmdbAttributeConnection + """ + The URL link for this CMDB object. + """ + webUrl: String +} + +""" +Represents a CMDB avatar. +""" +type JiraCmdbAvatar { + """ + The ID of the CMDB avatar. + """ + id: String + """ + The UUID of the CMDB avatar. + """ + avatarUUID: String + """ + The 16x16 pixel CMDB avatar. + """ + url16: String + """ + The 48x48 pixel CMDB avatar. + """ + url48: String + """ + The 72x72 pixel CMDB avatar. + """ + url72: String + """ + The 144x144 pixel CMDB avatar. + """ + url144: String + """ + The 288x288 pixel CMDB avatar. + """ + url288: String + """ + The media client config used for retrieving the CMDB Avatar. + """ + mediaClientConfig: JiraCmdbMediaClientConfig +} + +""" +Represents the media client config used for retrieving the CMDB Avatar. +""" +type JiraCmdbMediaClientConfig { + """ + The media client ID for the CMDB avatar. + """ + clientId: String + """ + The ASAP issuer of the media token. + """ + issuer: String + """ + The media file ID for the CMDB avatar. + """ + fileId: String + """ + The media base URL for the CMDB avatar. + """ + mediaBaseUrl: URL + """ + The media JWT token for the CMDB avatar. + """ + mediaJwtToken: String +} + +""" +Represents the attribute associated with the CMDB object. +""" +type JiraCmdbAttribute { + """ + The attribute ID. + """ + attributeId: String + """ + The object type attribute ID. + """ + objectTypeAttributeId: String + """ + The object type attribute. + """ + objectTypeAttribute: JiraCmdbObjectTypeAttribute + """ + Paginated list of attribute values present on the CMDB object. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + objectAttributeValues( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCmdbObjectAttributeValueConnection +} + +""" +Represents the CMDB object type attribute. +""" +type JiraCmdbObjectTypeAttribute { + """ + The name of the CMDB object type attribute. + """ + name: String + """ + A boolean representing whether this attribute is set as the label attribute or not. + """ + label: Boolean + """ + The category of the CMDB attribute that can be created. + """ + type: JiraCmdbAttributeType + """ + The description of the CMDB object type attribute. + """ + description: String + """ + The object type of the CMDB object type attribute. + """ + objectType: JiraCmdbObjectType + """ + The default type of the CMDB object type attribute. + This property will be present if the `type` of the attribute is `DEFAULT`. + """ + defaultType: JiraCmdbDefaultType + """ + The reference type of the CMDB object type attribute. + This property will be present if the `type` of the attribute is `REFERENCED_OBJECT`. + """ + referenceType: JiraCmdbReferenceType + """ + The reference object type ID of the CMDB object type attribute. + This property will be present if the `type` of the attribute is `REFERENCED_OBJECT`. + """ + referenceObjectTypeId: String + """ + The reference object type of the CMDB object type attribute. + This property will be present if the `type` of the attribute is `REFERENCED_OBJECT`. + """ + referenceObjectType: JiraCmdbObjectType + """ + The additional value of the CMDB object type attribute. + """ + additionalValue: String + """ + The suffix associated with the CMDB object type attribute. + """ + suffix: String +} + +""" +The category of the CMDB attribute that can be created. +""" +enum JiraCmdbAttributeType { + """ + Default attributes, e.g. text, boolean, integer, date. + """ + DEFAULT + """ + Reference object attribute. + """ + REFERENCED_OBJECT + """ + User attribute. + """ + USER + """ + Confluence attribute. + """ + CONFLUENCE + """ + Group attribute. + """ + GROUP + """ + Version attribute. + """ + VERSION + """ + Project attribute. + """ + PROJECT + """ + Status attribute. + """ + STATUS +} + +""" +Represents the CMDB object type. +""" +type JiraCmdbObjectType { + """ + The ID of the CMDB object type. + """ + objectTypeId: String! + """ + The name of the CMDB object type. + """ + name: String + """ + The description of the CMDB object type. + """ + description: String + """ + The icon of the CMDB object type. + """ + icon: JiraCmdbIcon + """ + The object schema id of the CMDB object type. + """ + objectSchemaId: String +} + +""" +Represents a CMDB icon. +""" +type JiraCmdbIcon { + """ + The ID of the CMDB icon. + """ + id: String! + """ + The name of the CMDB icon. + """ + name: String + """ + The URL of the small CMDB icon. + """ + url16: String + """ + The URL of the large CMDB icon. + """ + url48: String +} + +""" +Represents the CMDB default type. +This contains information about what type of default attribute this is. +The possible id: name values are as follows: + 0: Text + 1: Integer + 2: Boolean + 3: Float + 4: Date + 6: DateTime + 7: URL + 8: Email + 9: Textarea + 10: Select + 11: IP Address +""" +type JiraCmdbDefaultType { + """ + The ID of the CMDB default type. + """ + id: String + """ + The name of the CMDB default type. + """ + name: String +} + +""" +Represents the CMDB reference type. +This describes the type of connection between one object and another. +""" +type JiraCmdbReferenceType { + """ + The ID of the CMDB reference type. + """ + id: String + """ + The name of the CMDB reference type. + """ + name: String + """ + The description of the CMDB reference type. + """ + description: String + """ + The color of the CMDB reference type. + """ + color: String + """ + The URL of the icon of the CMDB reference type. + """ + webUrl: String + """ + The object schema ID of the CMDB reference type. + """ + objectSchemaId: String +} + +""" +Represents the CMDB object attribute value. +The property values in this type will be defined depending on the attribute type. +E.g. the `referenceObject` property value will only be defined if the attribute type is a reference object type. +""" +type JiraCmdbObjectAttributeValue { + """ + The referenced CMDB object. + """ + referencedObject: JiraCmdbObject + """ + The user associated with this CMDB object attribute value. + """ + user: User + """ + The group associated with this CMDB object attribute value. + """ + group: JiraGroup + """ + The status of this CMDB object attribute value. + """ + status: JiraCmdbStatusType + """ + The value of this CMDB object attribute value. + """ + value: String + """ + The display value of this CMDB object attribute value. + """ + displayValue: String + """ + The search value of this CMDB object attribute value. + """ + searchValue: String + """ + The additional value of this CMDB object attribute value. + """ + additionalValue: String +} + +""" +Represents the CMDB status type. +""" +type JiraCmdbStatusType { + """ + The ID of the CMDB status type. + """ + id: String + """ + The name of the CMDB status type. + """ + name: String + """ + The description of the CMDB status type. + """ + description: String + """ + The category of the CMDB status type. + """ + category: Int + """ + The object schema ID associated with the CMDB status type. + """ + objectSchemaId: String +} + +""" +The connection type for JiraCmdbAttribute. +""" +type JiraCmdbAttributeConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraCmdbAttributeEdge] +} + +""" +An edge in a JiraCmdbAttribute connection. +""" +type JiraCmdbAttributeEdge { + """ + The node at the edge. + """ + node: JiraCmdbAttribute + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraCmdbObjectAttributeValue. +""" +type JiraCmdbObjectAttributeValueConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraCmdbObjectAttributeValueEdge] +} + +""" +An edge in a JiraCmdbObjectAttributeValue connection. +""" +type JiraCmdbObjectAttributeValueEdge { + """ + The node at the edge. + """ + node: JiraCmdbObjectAttributeValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraCmdbObject. +""" +type JiraCmdbObjectConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraCmdbObjectEdge] +} + +""" +An edge in a JiraCmdbObject connection. +""" +type JiraCmdbObjectEdge { + """ + The node at the edge. + """ + node: JiraCmdbObject + """ + The cursor to this edge. + """ + cursor: String! +}""" +Jira color that displays on a field. +""" +type JiraColor { + """ + Global identifier for the color. + """ + id: ID + """ + The key associated with the color based on the field type (issue color, epic color). + """ + colorKey: String +} +""" +An interface shared across all comment types. +""" +interface JiraComment { + """ + Identifier for the comment. + """ + commentId: ID! + """ + The issue to which this comment is belonged. + """ + issue: JiraIssue + """ + The browser clickable link of this comment. + """ + webUrl: URL + """ + User profile of the original comment author. + """ + author: User + """ + User profile of the author performing the comment update. + """ + updateAuthor: User + """ + Comment body rich text. + """ + richText: JiraRichText + """ + Time of comment creation. + """ + created: DateTime! + """ + Time of last comment update. + """ + updated: DateTime + """ + Either the group or the project role associated with this comment, but not both. + Null means the permission level is unspecified, i.e. the comment is public. + """ + permissionLevel: JiraPermissionLevel +} + +""" +Represents a Jira platform comment. +""" +type JiraPlatformComment implements JiraComment & Node { + """ + Global identifier for the comment + """ + id: ID! + """ + Identifier for the comment. + """ + commentId: ID! + """ + The issue to which this comment is belonged. + """ + issue: JiraIssue + """ + The browser clickable link of this comment. + """ + webUrl: URL + """ + User profile of the original comment author. + """ + author: User + """ + User profile of the author performing the comment update. + """ + updateAuthor: User + """ + Comment body rich text. + """ + richText: JiraRichText + """ + Time of comment creation. + """ + created: DateTime! + """ + Time of last comment update. + """ + updated: DateTime + """ + Either the group or the project role associated with this comment, but not both. + Null means the permission level is unspecified, i.e. the comment is public. + """ + permissionLevel: JiraPermissionLevel +} + +""" +Represents a comment within a JiraServiceManagement project. +""" +type JiraServiceManagementComment implements JiraComment & Node { + """ + Global identifier for the comment + """ + id: ID! + """ + Identifier for the comment. + """ + commentId: ID! + """ + The issue to which this comment is belonged. + """ + issue: JiraIssue + """ + The browser clickable link of this comment. + """ + webUrl: URL + """ + User profile of the original comment author. + """ + author: User + """ + User profile of the author performing the comment update. + """ + updateAuthor: User + """ + Comment body rich text. + """ + richText: JiraRichText + """ + Time of comment creation. + """ + created: DateTime! + """ + Time of last comment update. + """ + updated: DateTime + """ + Either the group or the project role associated with this comment, but not both. + Null means the permission level is unspecified, i.e. the comment is public. + """ + permissionLevel: JiraPermissionLevel + """ + The JSM visibility property associated with this comment. + """ + visibility: JiraServiceManagementCommentVisibility + """ + Indicates whether the comment author can see the request or not. + """ + authorCanSeeRequest: Boolean +} + +""" +The connection type for JiraComment. +""" +type JiraCommentConnection { + """ + The approximate count of items in the connection. + """ + indicativeCount: Int + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraCommentEdge] +} + +""" +An edge in a JiraComment connection. +""" +type JiraCommentEdge { + """ + The node at the the edge. + """ + node: JiraComment + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents the input for comments by issue ID and comment ID. +""" +input JiraCommentByIdInput { + """ + Issue ID. + """ + issueId: ID! + """ + Comment ID. + """ + id: ID! +}""" +Jira component defines a sub-selectin of a project. +""" +type JiraComponent implements Node { + """ + Global identifier for the color. + """ + id: ID! + """ + Component id in digital format. + """ + componentId: String! + """ + The name of the component. + """ + name: String + """ + Component description. + """ + description: String +} + +""" +The connection type for JiraComponent. +""" +type JiraComponentConnection { + """ + The total number of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraComponentEdge] +} + +""" +An edge in a JiraComponent connection. +""" +type JiraComponentEdge { + """ + The node at the edge. + """ + node: JiraComponent + """ + The cursor to this edge. + """ + cursor: String! +} +""" +The precondition state of the deployments JSW feature for a particular project and user. +""" +enum JiraDeploymentsFeaturePrecondition { + """ + The deployments feature is not available as the precondition checks have not been satisfied. + """ + NOT_AVAILABLE + """ + The deployments feature is available and will show the empty-state page as no CI/CD provider is sending deployment data. + """ + DEPLOYMENTS_EMPTY_STATE + """ + The deployments feature is available as the project has satisfied all precondition checks. + """ + ALL_SATISFIED +} + +""" +The precondition state of the install-deployments banner for a particular project and user. +""" +enum JiraInstallDeploymentsBannerPrecondition { + """ + The deployments banner is not available as the precondition checks have not been satisfied. + """ + NOT_AVAILABLE + """ + The deployments banner is available but the feature has not been enabled. + """ + FEATURE_NOT_ENABLED + """ + The deployments banner is available but no CI/CD provider is sending deployment data. + """ + DEPLOYMENTS_EMPTY_STATE +} + +extend type JiraQuery { + """ + Returns the precondition state of the deployments JSW feature for a particular project and user. + """ + deploymentsFeaturePrecondition( + """ + The identifier of the project to get the precondition for. + """ + projectId: ID! + ): JiraDeploymentsFeaturePrecondition + + """ + Returns the precondition state of the deployments JSW feature for a particular project and user. + """ + deploymentsFeaturePreconditionByProjectKey( + """ + The identifier that indicates that cloud instance this data is to be fetched for + """ + cloudId: ID! + """ + The key identifier of the project to get the precondition for. + """ + projectKey: String! + ): JiraDeploymentsFeaturePrecondition + + """ + Returns the precondition state of the install-deployments banner for a particular project and user. + """ + installDeploymentsBannerPrecondition( + """ + The identifier of the project to get the precondition for. + """ + projectId: ID! + ): JiraInstallDeploymentsBannerPrecondition +} +extend type JiraQuery { + """ + Container for all DevOps related queries in Jira + """ + devOps: JiraDevOpsQuery +} + +""" +Container for all DevOps related queries in Jira +""" +type JiraDevOpsQuery { + """ + Returns the JiraDevOpsIssuePanel for an issue + """ + devOpsIssuePanel(issueId: ID!): JiraDevOpsIssuePanel +} + +extend type JiraMutation { + """ + Container for all DevOps related mutations in Jira + """ + devOps: JiraDevOpsMutation +} + +""" +Container for all DevOps related mutations in Jira +""" +type JiraDevOpsMutation { + """ + Lets a user opt-out of the "not-connected" state in the DevOps Issue Panel + """ + optoutOfDevOpsIssuePanelNotConnectedState( + input: JiraOptoutDevOpsIssuePanelNotConnectedInput! + ): JiraOptoutDevOpsIssuePanelNotConnectedPayload + """ + Lets a user dismiss a banner shown in the DevOps Issue Panel + """ + dismissDevOpsIssuePanelBanner( + input: JiraDismissDevOpsIssuePanelBannerInput! + ): JiraDismissDevOpsIssuePanelBannerPayload +} + +""" +The input type for opting out of the Not Connected state in the DevOpsPanel +""" +input JiraOptoutDevOpsIssuePanelNotConnectedInput { + """ + Cloud ID of the tenant this change is applied to + """ + cloudId: ID! +} + +""" +The response payload for opting out of the Not Connected state in the DevOpsPanel +""" +type JiraOptoutDevOpsIssuePanelNotConnectedPayload implements Payload { + "The success indicator saying whether mutation operation was successful as a whole or not." + success: Boolean! + "The errors field represents additional mutation error information if exists." + errors: [MutationError!] +} + +""" +The input type for devops panel banner dismissal +""" +input JiraDismissDevOpsIssuePanelBannerInput { + """ + ID of the issue this banner was dismissed on + """ + issueId: ID! + """ + Only "issue-key-onboarding" is supported currently as this is the only banner + that can be displayed in the panel for now + """ + bannerType: JiraDevOpsIssuePanelBannerType! +} + +""" +The response payload for devops panel banner dismissal +""" +type JiraDismissDevOpsIssuePanelBannerPayload implements Payload { + "The success indicator saying whether mutation operation was successful as a whole or not." + success: Boolean! + "The errors field represents additional mutation error information if exists." + errors: [MutationError!] +} +""" +Container for all DevOps data for an issue, to be displayed in the DevOps Panel of an issue +""" +type JiraDevOpsIssuePanel { + """ + Specifies the state the DevOps panel in the issue view should be in + """ + panelState: JiraDevOpsIssuePanelState + + """ + Specify a banner to show on top of the dev panel. `null` means that no banner should be displayed. + """ + devOpsIssuePanelBanner: JiraDevOpsIssuePanelBannerType + + """ + Container for the Dev Summary of this issue + """ + devSummaryResult: JiraIssueDevSummaryResult + + """ + Specify if tenant which hosts the project of this issue has installed SCM providers supporting Branch capabilities. + """ + hasBranchCapabilities: Boolean +} + +""" +The possible States the DevOps Issue Panel can be in +""" +enum JiraDevOpsIssuePanelState { + """ + Panel should be hidden + """ + HIDDEN + """ + Panel should show the "not connected" state to prompt user to integrate tools + """ + NOT_CONNECTED + """ + Panel should show the available Dev Summary + """ + DEV_SUMMARY +} + +enum JiraDevOpsIssuePanelBannerType { + """ + Banner that explains how to add issue keys in your commits, branches and PRs + """ + ISSUE_KEY_ONBOARDING +} +extend type JiraQuery { + """ + Retrieves the list of devOps providers filtered by the types of capabilities they should support + Note: Bitbucket pipelines will be omitted from the result if Bitbucket SCM is not installed + """ + devOpsProviders( + """ + The ID of the tenant to get devOps providers for + """ + cloudId: ID! + """ + The capabilities the returned devOps providers will support + This result will contain providers that support *any* of the provided capabilities + + e.g. Requesting [COMMIT, DEPLOYMENT] will return providers that support either COMMIT, + DEPLOYMENT or both + + Note: The resulting list is bounded and is expected to *not* exceed 20 items with no filter. + Adding a filter will reduce the result even further. This is because a tenant will + reasonably install only handful of devOps integrations. i.e. It's possible but rare for + a site to have all of GitHub, GitLab, and Bitbucket providers installed + + Note: Omitting or passing an empty filter will return all devOps providers + """ + filter: [JiraDevOpsCapability!] = [] + ): [JiraDevOpsProvider] +} + +interface JiraDevOpsProvider { + """ + The human-readable display name of the devOps provider + """ + displayName: String + """ + The link to the web URL of the devOps provider + """ + webUrl: URL + """ + The list of capabilities the devOps provider supports + + This max size of the list is bounded by the total number of enum states + """ + capabilities: [JiraDevOpsCapability] +} + +""" +A connect app which provides devOps capabilities. +""" +type JiraClassicConnectDevOpsProvider implements JiraDevOpsProvider { + """ + The human-readable display name of the devOps provider + """ + displayName: String + """ + The link to the web URL of the devOps provider + """ + webUrl: URL + """ + The list of capabilities the devOps provider supports + + This max size of the list is bounded by the total number of enum states + """ + capabilities: [JiraDevOpsCapability] + """ + The link to the icon of the devOps provider + """ + iconUrl: URL + """ + The connect app ID + """ + connectAppId: ID +} + +""" +An oauth app which provides devOps capabilities. +""" +type JiraOAuthDevOpsProvider implements JiraDevOpsProvider { + """ + The human-readable display name of the devOps provider + """ + displayName: String + """ + The link to the web URL of the devOps provider + """ + webUrl: URL + """ + The list of capabilities the devOps provider supports + + This max size of the list is bounded by the total number of enum states + """ + capabilities: [JiraDevOpsCapability] + """ + The link to the icon of the devOps provider + """ + iconUrl: URL + """ + The oauth app ID + """ + oauthAppId: ID + """ + The corresponding marketplace app key for the oauth app + """ + marketplaceAppKey: String +} + +""" +The internal BB app which provides devOps capabilities +This provider will be filtered out from the list of providers if BB SCM is not installed +""" +type JiraBitbucketDevOpsProvider implements JiraDevOpsProvider { + """ + The human-readable display name of the devOps provider + """ + displayName: String + """ + The link to the web URL of the devOps provider + """ + webUrl: URL + """ + The list of capabilities the devOps provider supports + + This max size of the list is bounded by the total number of enum states + """ + capabilities: [JiraDevOpsCapability] +} + +""" +The types of capabilities a devOps provider can support +""" +enum JiraDevOpsCapability { + COMMIT + BRANCH + PULL_REQUEST + BUILD + DEPLOYMENT + FEATURE_FLAG + REVIEW +} +""" +The SCM entities (pullrequest, branches or commits) associated with a Jira issue. +""" +type JiraIssueDevInfoDetails { + """ + Created pull-requests associated with a Jira issue. + """ + pullRequests: JiraIssuePullRequests + """ + Created SCM branches associated with a Jira issue. + """ + branches: JiraIssueBranches + """ + Created SCM commits associated with a Jira issue. + """ + commits: JiraIssueCommits +} + +""" +The container of SCM pull requests info associated with a Jira issue. +""" +type JiraIssuePullRequests { + """ + A list of pull request details from the original SCM providers. + Maximum of 50 latest updated pull-requests will be returned. + """ + details: [JiraDevOpsPullRequestDetails!] + """ + A list of config errors of underlined data-providers providing pull request details. + """ + configErrors: [JiraDevInfoConfigError!] +} + +""" +The container of SCM branches info associated with a Jira issue. +""" +type JiraIssueBranches { + """ + A list of branches details from the original SCM providers. + Maximum of 50 branches will be returned. + """ + details: [JiraDevOpsBranchDetails!] + """ + A list of config errors of underlined data-providers providing branches details. + """ + configErrors: [JiraDevInfoConfigError!] +} + +""" +The container of SCM commits info associated with a Jira issue. +""" +type JiraIssueCommits { + """ + A list of commits details from the original SCM providers. + Maximum of 50 latest created commits will be returned. + """ + details: [JiraDevOpsCommitDetails!] + """ + A list of config errors of underlined data-providers providing commit details. + """ + configErrors: [JiraDevInfoConfigError!] +} + +""" +Details of a SCM Pull-request associated with a Jira issue +""" +type JiraDevOpsPullRequestDetails { + """ + Value uniquely identify a pull request scoped to its original scm provider, not ARI format + """ + providerPullRequestId: String, + """ + Entity URL link to pull request in its original provider + """ + entityUrl: URL, + """ + Pull request title + """ + name: String, + """ + The name of the source branch of the PR. + """ + branchName: String, + """ + The timestamp of when the PR last updated in ISO 8601 format. + """ + lastUpdated: DateTime, + """ + Possible states for Pull Requests. + """ + status: JiraPullRequestState, + """ + Details of author who created the Pull Request. + """ + author: JiraDevOpsEntityAuthor, + """ + List of the reviewers for this pull request and their approval status. + Maximum of 50 reviewers will be returned. + """ + reviewers: [JiraPullRequestReviewer!], +} + +""" +Details of a created SCM branch associated with a Jira issue. +""" +type JiraDevOpsBranchDetails { + """ + Value uniquely identify the scm branch scoped to its original provider, not ARI format + """ + providerBranchId: String, + """ + Entity URL link to branch in its original provider + """ + entityUrl: URL, + """ + Branch name + """ + name: String, + """ + The scm repository contains the branch. + """ + scmRepository: JiraScmRepository, +} + +""" +Details of a SCM commit associated with a Jira issue. +""" +type JiraDevOpsCommitDetails { + """ + Value uniquely identify the commit (commit-hash), not ARI format. + """ + providerCommitId: String, + """ + Shorten value of the commit-hash, used for display. + """ + displayCommitId: String, + """ + Entity URL link to commit in its original provider + """ + entityUrl: URL, + """ + The commit message. + """ + name: String, + """ + The commit date in ISO 8601 format. + """ + created: DateTime, + """ + Details of author who created the commit. + """ + author: JiraDevOpsEntityAuthor, + """ + Flag represents if the commit is a merge commit. + """ + isMergeCommit: Boolean, + """ + The scm repository contains the commit. + """ + scmRepository: JiraScmRepository, +} + +""" +Basic person information who created a SCM entity (Pull-request, Branches, or Commit) +""" +type JiraDevOpsEntityAuthor { + """ + The author's avatar. + """ + avatar: JiraAvatar, + """ + Author name. + """ + name: String, +} + +""" +Basic person information who reviews a pull-request. +""" +type JiraPullRequestReviewer { + """ + The reviewer's avatar. + """ + avatar: JiraAvatar, + """ + Reviewer name. + """ + name: String, + """ + Represent the approval status from reviewer for the pull request. + """ + hasApproved: Boolean, +} + +""" +Repository information provided by data-providers. +""" +type JiraScmRepository { + """ + Repository name. + """ + name: String + """ + URL link to the repository in scm provider. + """ + entityUrl: URL +} + +""" +User actionable error details. +""" +type JiraDevInfoConfigError { + """ + Type of the error + """ + errorType: JiraDevInfoConfigErrorType + """ + id of the data provider associated with this error + """ + dataProviderId: String +} + +""" +The possible config error type with a provider that feed devinfo details. +""" +enum JiraDevInfoConfigErrorType { + UNAUTHORIZED + NOT_CONFIGURED + INCAPABLE + UNKNOWN_CONFIG_ERROR +} +""" +Represents an epic. +""" +type JiraEpic { + """ + Global identifier for the epic/issue Id. + """ + id: ID! + """ + Issue Id for the epic. + """ + issueId: String! + """ + Name of the epic. + """ + name: String + """ + Key identifier for the Issue. + """ + key: String + """ + Summary of the epic. + """ + summary: String + """ + Color string for the epic. + """ + color: String + """ + Status of the epic, whether its completed or not. + """ + done: Boolean +} + +""" +The connection type for JiraEpic. +""" +type JiraEpicConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraEpicEdge] +} + +""" +An edge in a JiraEpic connection. +""" +type JiraEpicEdge { + """ + The node at the edge. + """ + node: JiraEpic + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the JSM feedback rating. +""" +type JiraServiceManagementFeedback { + """ + Represents the integer rating value available on the issue. + """ + rating: Int +} +""" +Represents the Jira flag. +""" +type JiraFlag { + """ + Indicates whether the issue is flagged or not. + """ + isFlagged: Boolean +} +""" +Represents a Jira Group. +""" +type JiraGroup implements Node { + """ + The global identifier of the group in ARI format. + Note: this will be populated with a fake ARI until the Group Rename project is complete. + """ + id: ID! + "Group Id, can be null on group creation" + groupId: String! + "Name of the Group" + name: String! +} + +""" +The connection type for JiraGroup. +""" +type JiraGroupConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraGroupEdge] +} + +""" +An edge in a JiraGroupConnection connection. +""" +type JiraGroupEdge { + """ + The node at the edge. + """ + node: JiraGroup + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the JSM incident. +""" +type JiraServiceManagementIncident { + """ + Indicates whether any incident is linked to the issue or not. + """ + hasLinkedIncidents: Boolean +} +""" +Jira Issue node. Includes the Issue data displayable in the current User context. +""" +type JiraIssue implements Node { + """ + Unique identifier associated with this Issue. + """ + id: ID! + """ + Issue ID in numeric format. E.g. 10000 + """ + issueId: String! + """ + The {projectKey}-{issueNumber} associated with this Issue. + """ + key: String! + """ + The browser clickable link of this Issue. + """ + webUrl: URL + """ + Loads the fields relevant to the current GraphQL Query, Issue and User contexts. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fields( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueFieldConnection + """ + Paginated list of fields available on this issue. Allows clients to specify fields by their identifier. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldsById( + """ + A list of field identifiers corresponding to the fields to be returned. + E.g. ["ari:cloud:jira:{siteId}:issuefieldvalue/{issueId}/description", "ari:cloud:jira:{siteId}:issuefieldvalue/{issueId}/customfield_10000"]. + """ + ids: [ID!]! + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueFieldConnection + """ + Paginated list of comments available on this issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + comments( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCommentConnection + """ + Paginated list of worklogs available on this issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + worklogs( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraWorkLogConnection + """ + Paginated list of attachments available on this issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + attachments( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraAttachmentConnection + """ + Loads all field sets relevant to the current context for the Issue. + """ + fieldSets( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueFieldSetConnection + """ + Loads all field sets for a specified JiraIssueSearchView. + """ + fieldSetsForIssueSearchView( + """ + The namespace for a JiraIssueSearchView. + """ + namespace: String + """ + The viewId for a JiraIssueSearchView. + """ + viewId: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String): JiraIssueFieldSetConnection + + """ + Loads the given field sets for the JiraIssue + """ + fieldSetsById( + """ + The identifiers of the field sets to retrieve e.g. ["assignee", "reporter", "checkbox_cf[Checkboxes]"] + """ + fieldSetIds: [String!]! + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String): JiraIssueFieldSetConnection + + """ + Paginated list of issue links available on this issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + issueLinks( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueLinkConnection + """ + The childIssues within this issue. + """ + childIssues: JiraChildIssues + """ + The dev summary cache. This could be stale. + """ + devSummaryCache: JiraIssueDevSummaryResult + + """ + The SCM development-info entities (pullrequests, branches, commits) associated with a Jira issue. + """ + devInfoDetails: JiraIssueDevInfoDetails + """ + Returns the hierarchy info that's directly below the current issue's hierarchy if the current issue's project is TMP. + """ + hierarchyLevelBelow: JiraIssueTypeHierarchyLevel + """ + Returns the hierarchy info that's directly below the current issue's hierarchy. + """ + hierarchyLevelAbove: JiraIssueTypeHierarchyLevel + """ + Returns the issue types within the same project and are directly below the current issue's hierarchy if the current issue's project is TMP. + """ + issueTypesForHierarchyBelow: JiraIssueTypeConnection + """ + Returns the issue types within the same project and are directly above the current issue's hierarchy. + """ + issueTypesForHierarchyAbove: JiraIssueTypeConnection + """ + Returns the issue types within the same project that are at the same level as the current issue's hierarchy if the current issue's project is TMP. + """ + issueTypesForHierarchySame: JiraIssueTypeConnection + """ + Indicates that there was at least one error in retrieving data for this Jira issue. + """ + errorRetrievingData: Boolean @deprecated(reason: "Intended only for feature parity with legacy experiences.") + """ + The story points field for the given issue. + """ + storyPointsField: JiraNumberField + """ + The story point estimate field for the given issue. + """ + storyPointEstimateField: JiraNumberField + """ + Returns the ID of the screen the issue is on. + """ + screenId: Long @deprecated(reason: "The screen concept has been deprecated, and is only used for legacy reasons.") +} + +""" +The connection type for JiraIssue. +""" +type JiraIssueConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + jql if issues are returned by jql. This field will have value only when the context has jql + """ + jql: String + """ + A list of edges in the current page. + """ + edges: [JiraIssueEdge] + """ + The error that occurred during an issue search. + """ + issueSearchError: JiraIssueSearchError + + """ + The total number of issues for a given JQL search. + This number will be capped based on the server's configured limit. + """ + totalIssueSearchResultCount: Int + + """ + Returns whether or not there were more issues available for a given issue search. + """ + isCappingIssueSearchResult: Boolean + + """ + Extra page information for the issue navigator. + """ + issueNavigatorPageInfo: JiraIssueNavigatorPageInfo + + """ + Cursors to help with random access pagination. + """ + pageCursors(maxCursors: Int!): JiraPageCursors +} + +""" +An edge in a JiraIssue connection. +""" +type JiraIssueEdge { + """ + The node at the edge. + """ + node: JiraIssue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents a field set which contains a set of JiraIssueFields, otherwise commonly referred to as collapsed fields. +""" +type JiraIssueFieldSet { + """ + The identifer of the field set e.g. `assignee`, `reporter`, `checkbox_cf[Checkboxes]`. + """ + fieldSetId: String + """ + The field type key of the contained fields e.g: `project`, `issuetype`, `com.pyxis.greenhopper.jira:gh-epic-link`. + """ + type: String + """ + Retrieves a connection of JiraIssueFields + """ + fields( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueFieldConnection +} + +""" +An edge in a JiraIssueFieldSet connection. +""" +type JiraIssueFieldSetEdge { + """ + The node at the the edge. + """ + node: JiraIssueFieldSet + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraIssueFieldSet. +""" +type JiraIssueFieldSetConnection { + """ + The total number of JiraIssueFields matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo + """ + The data for Edges in the current page. + """ + edges: [JiraIssueFieldSetEdge] +} + +""" +Extra page information to assist the Issue Navigator UI to display information about the current set of issues. +""" +type JiraIssueNavigatorPageInfo { + """ + The position of the first issue in the current page, relative to the entire stable search. + The first issue's position will start at 1. + If there are no issues, the position returned is 0. + You can consider a position to effectively be a traditional index + 1. + """ + firstIssuePosition: Int + """ + The position of the last issue in the current page, relative to the entire stable search. + If there is only 1 issue, the last position is 1. + If there are no issues, the position returned is 0. + You can consider a position to effectively be a traditional index + 1. + """ + lastIssuePosition: Int + """ + The issue key of the first node from the next page of issues. + """ + firstIssueKeyFromNextPage: String + """ + The issue key of the last node from the previous page of issues. + """ + lastIssueKeyFromPreviousPage: String +} + +""" +The base type cursor data necessary for random access pagination. +""" +type JiraPageCursor { + """ + This is a Base64 encoded value containing the all the necessary data for retrieving the page items. + """ + cursor: String + """ + The number of the page it represents. First page is 1. + """ + pageNumber: Int + """ + Indicates if this page is the current page. Usually the current page is represented differently on the FE. + """ + isCurrent: Boolean +} + +""" +This encapsulates all the necessary cursors for random access pagination. +""" +type JiraPageCursors { + """ + Represents the cursor for the first page. + """ + first: JiraPageCursor + """ + Represents a list of cursors around the current page. + Even if the list is not bounded, there are strict limits set on the server (MAX_SIZE <= 7). + """ + around: [JiraPageCursor] + """ + Represents the cursor for the last page. + """ + last: JiraPageCursor + """ + Represents the cursor for the previous page. + E.g. currentPage=2 => previousPage=1 + """ + previous: JiraPageCursor +} +""" +Represents a collection of system container types to be fetched by passing in an issue id. +""" +input JiraIssueItemSystemContainerTypeWithIdInput { + """ + ARI of the issue. + """ + issueId: ID! + """ + The collection of system container types. + """ + systemContainerTypes: [JiraIssueItemSystemContainerType!]! +} + +""" +Represents a collection of system container types to be fetched by passing in an issue key and a cloud id. +""" +input JiraIssueItemSystemContainerTypeWithKeyInput { + """ + The {projectKey}-{issueNumber} associated with this Issue. + """ + issueKey: String! + """ + The cloudId associated with this Issue. + """ + cloudId: ID! + """ + The collection of system container types. + """ + systemContainerTypes: [JiraIssueItemSystemContainerType!]! +} + +""" +Contains the fetched containers or an error. +""" +union JiraIssueItemContainersResult = JiraIssueItemContainers | QueryError + +""" +Represents a related collection of system containers and their items, and the collection of default item locations. +""" +type JiraIssueItemContainers { + #id: ID - An id has not been added yet to allow room to make this a Node in future. + """ + The collection of system containers. + """ + containers: [JiraIssueItemContainer] + """ + The collection of default item locations. + """ + defaultItemLocations: [JiraIssueItemLayoutDefaultItemLocation] +} +""" +Represents a system container and its items. +""" +type JiraIssueItemContainer { + """ + The system container type. + """ + containerType: JiraIssueItemSystemContainerType + """ + The system container items. + """ + items: JiraIssueItemContainerItemConnection +} + +""" +The connection type for `JiraIssueItemContainerItem`. +""" +type JiraIssueItemContainerItemConnection { + """ + Information about the page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + Deprecated. + """ + nodes: [JiraIssueItemContainerItem] @deprecated(reason: "Please use edges instead.") + """ + The data for edges in the page. + """ + edges: [JiraIssueItemContainerItemEdge] + """ + The total count of items in the connection. + """ + totalCount: Int +} + +""" +An edge in a `JiraIssueItemContainerItem` connection. +""" +type JiraIssueItemContainerItemEdge { + """ + The node at the edge. + """ + node: JiraIssueItemContainerItem + """ + The cursor to the edge. + """ + cursor: String! +} + +""" +The system container types that are available for placing items. +""" +enum JiraIssueItemSystemContainerType { + """ + The container type for the request portal in JSM projects. + """ + REQUEST_PORTAL + """ + The container type for the issue content. + """ + CONTENT + """ + The container type for the issue primary context. + """ + PRIMARY + """ + The container type for the issue secondary context. + """ + SECONDARY + """ + The container type for the issue context. + """ + CONTEXT + """ + The container type for the issue hidden items. + """ + HIDDEN_ITEMS + """ + The container type for the request in JSM projects. + """ + REQUEST +} + +""" +Represents a default location rule for items that are not configured in a container. +Example: A user picker is added to a screen. Until the administrator places it in the layout, the item is placed in +the location specified by the 'PEOPLE' category. The categories available may vary based on the project type. +""" +type JiraIssueItemLayoutDefaultItemLocation { + """ + A destination container type or the ID of a destination group. + """ + containerLocation: String + """ + The item location rule type. + """ + itemLocationRuleType: JiraIssueItemLayoutItemLocationRuleType +} + +""" +Represents the type of items that the default location rule applies to. +""" +enum JiraIssueItemLayoutItemLocationRuleType { + """ + People items. For example: user pickers, team pickers or group picker. + """ + PEOPLE + """ + Multiline text items. For example: a description field or custom multi-line test fields. + """ + MULTILINE_TEXT + """ + Time tracking items. For example: estimate, original estimate or time tracking panels. + """ + TIMETRACKING + """ + Date items. For example: date or time related fields. + """ + DATES + """ + Any other item types not covered by previous item types. + """ + OTHER +} + +""" +Represents the items that can be placed in any system container. +""" +union JiraIssueItemContainerItem = JiraIssueItemFieldItem | JiraIssueItemPanelItem | JiraIssueItemGroupContainer | JiraIssueItemTabContainer + +""" +Represents the items that can be placed in any group container. +""" +union JiraIssueItemGroupContainerItem = JiraIssueItemFieldItem | JiraIssueItemPanelItem + +""" +Represents the items that can be placed in any tab container. +""" +union JiraIssueItemTabContainerItem = JiraIssueItemFieldItem + +""" +Represents a collection of items that are held in a tab container. +""" +type JiraIssueItemTabContainer { + """ + The tab container ID. + """ + tabContainerId: String! + """ + The tab container name. + """ + name: String + """ + The tab container items. + """ + items: JiraIssueItemTabContainerItemConnection +} + +""" +Represents a collection of items that are held in a group container. +""" +type JiraIssueItemGroupContainer { + """ + The group container ID. + """ + groupContainerId: String! + """ + The group container name. + """ + name: String + """ + Whether a group container is minimized. + """ + minimised: Boolean + """ + The group container items. + """ + items: JiraIssueItemGroupContainerItemConnection +} + +""" +The connection type for `JiraIssueItemGroupContainerItem`. +""" +type JiraIssueItemGroupContainerItemConnection { + """ + Information about the page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + Deprecated. + """ + nodes: [JiraIssueItemGroupContainerItem] @deprecated(reason: "Please use edges instead.") + """ + The data for edges in the page. + """ + edges: [JiraIssueItemGroupContainerItemEdge] + """ + The total count of items in the connection. + """ + totalCount: Int +} + +""" +An edge in a `JiraIssueItemGroupContainerItem` connection. +""" +type JiraIssueItemGroupContainerItemEdge { + """ + The node at the edge. + """ + node: JiraIssueItemGroupContainerItem + """ + The cursor to the edge. + """ + cursor: String! +} + +""" +The connection type for `JiraIssueItemTabContainerItem`. +""" +type JiraIssueItemTabContainerItemConnection { + """ + Information about the page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + Deprecated. + """ + nodes: [JiraIssueItemTabContainerItem] @deprecated(reason: "Please use edges instead.") + """ + The data for edges in the page. + """ + edges: [JiraIssueItemTabContainerItemEdge] + """ + The total count of items in the connection. + """ + totalCount: Int +} + +""" +An edge in a `JiraIssueItemTabContainerItem` connection. +""" +type JiraIssueItemTabContainerItemEdge { + """ + The node at the edge. + """ + node: JiraIssueItemTabContainerItem + """ + The cursor to the edge. + """ + cursor: String! +} + +""" +Represents a reference to a field by field ID, used for laying out fields on an issue. +""" +type JiraIssueItemFieldItem { + """ + The field item ID. + """ + fieldItemId: String! + """ + Represents the position of the field in the container. + Aid to preserve the field position when combining items in `PRIMARY` and `REQUEST` container types before saving in JSM projects. + """ + containerPosition: Int! +} + +""" +Represents a reference to a panel by panel ID, used for laying out panels on an issue. +""" +type JiraIssueItemPanelItem { + """ + The panel item ID. + """ + panelItemId: String! +} +""" +Container for the Dev Summary of an issue +""" +type JiraIssueDevSummaryResult { + """ + Contains all available summaries for the issue + """ + devSummary: JiraIssueDevSummary + + """ + Returns "transient errors". That is, errors that may be solved by retrying the fetch operation. + This excludes configuration errors that require admin intervention to be solved. + """ + errors: [JiraIssueDevSummaryError!] + """ + Returns "non-transient errors". That is, configuration errors that require admin intervention to be solved. + This returns an empty collection when called for users that are not administrators or system administrators. + """ + configErrors: [JiraIssueDevSummaryError!] +} + +""" +Lists the summaries available for each type of dev info, for a given issue +""" +type JiraIssueDevSummary { + """ + Summary of the Branches attached to the issue + """ + branch: JiraIssueBranchDevSummaryContainer + """ + Summary of the Commits attached to the issue + """ + commit: JiraIssueCommitDevSummaryContainer + """ + Summary of the Pull Requests attached to the issue + """ + pullrequest: JiraIssuePullRequestDevSummaryContainer + """ + Summary of the Builds attached to the issue + """ + build: JiraIssueBuildDevSummaryContainer + """ + Summary of the Reviews attached to the issue + """ + review: JiraIssueReviewDevSummaryContainer + """ + Summary of the deployment environments attached to some builds. + This is a legacy attribute only used by Bamboo builds + """ + deploymentEnvironments: JiraIssueDeploymentEnvironmentDevSummaryContainer +} + +""" +Aggregates the `count` of entities for a given provider +""" +type JiraIssueDevSummaryByProvider { + """ + UUID for a given provider, to allow aggregation + """ + providerId: String + """ + Provider name + """ + name: String + """ + Number of entities associated with that provider + """ + count: Int +} + +""" +Error when querying the JiraIssueDevSummary +""" +type JiraIssueDevSummaryError { + """ + A message describing the error + """ + message: String + """ + Information about the provider that triggered the error + """ + instance: JiraIssueDevSummaryErrorProviderInstance +} + +""" +Basic information on a provider that triggered an error +""" +type JiraIssueDevSummaryErrorProviderInstance { + """ + Provider's name + """ + name: String + """ + Provider's type + """ + type: String + """ + Base URL of the provider's instance that failed + """ + baseUrl: String +} + +""" +Container for the summary of the Branches attached to the issue +""" +type JiraIssueBranchDevSummaryContainer { + """ + The actual summary of the Branches attached to the issue + """ + overall: JiraIssueBranchDevSummary + """ + Count of Branches aggregated per provider + """ + summaryByProvider: [JiraIssueDevSummaryByProvider!] +} + +""" +Summary of the Branches attached to the issue +""" +type JiraIssueBranchDevSummary { + """ + Total number of Branches for the issue + """ + count: Int + """ + Date at which this summary was last updated + """ + lastUpdated: DateTime +} + +""" +Container for the summary of the Commits attached to the issue +""" +type JiraIssueCommitDevSummaryContainer { + """ + The actual summary of the Commits attached to the issue + """ + overall: JiraIssueCommitDevSummary + """ + Count of Commits aggregated per provider + """ + summaryByProvider: [JiraIssueDevSummaryByProvider!] +} + +""" +Summary of the Commits attached to the issue +""" +type JiraIssueCommitDevSummary { + """ + Total number of Commits for the issue + """ + count: Int + """ + Date at which this summary was last updated + """ + lastUpdated: DateTime +} + +""" +Container for the summary of the Pull Requests attached to the issue +""" +type JiraIssuePullRequestDevSummaryContainer { + """ + The actual summary of the Pull Requests attached to the issue + """ + overall: JiraIssuePullRequestDevSummary + """ + Count of Pull Requests aggregated per provider + """ + summaryByProvider: [JiraIssueDevSummaryByProvider!] +} + +""" +Summary of the Pull Requests attached to the issue +""" +type JiraIssuePullRequestDevSummary { + """ + Total number of Pull Requests for the issue + """ + count: Int + """ + Date at which this summary was last updated + """ + lastUpdated: DateTime + + """ + State of the Pull Requests in the summary + """ + state: JiraPullRequestState + """ + Number of Pull Requests for the state + """ + stateCount: Int + """ + Whether the Pull Requests for the given state are open or not + """ + open: Boolean +} + +""" +Possible states for Pull Requests +""" +enum JiraPullRequestState { + """ + Pull Request is Open + """ + OPEN + """ + Pull Request is Declined + """ + DECLINED + """ + Pull Request is Merged + """ + MERGED +} + +""" +Container for the summary of the Builds attached to the issue +""" +type JiraIssueBuildDevSummaryContainer { + """ + The actual summary of the Builds attached to the issue + """ + overall: JiraIssueBuildDevSummary + """ + Count of Builds aggregated per provider + """ + summaryByProvider: [JiraIssueDevSummaryByProvider!] +} + +""" +Summary of the Builds attached to the issue +""" +type JiraIssueBuildDevSummary { + """ + Total number of Builds for the issue + """ + count: Int + """ + Date at which this summary was last updated + """ + lastUpdated: DateTime + + """ + Number of failed buids for the issue + """ + failedBuildCount: Int + """ + Number of successful buids for the issue + """ + successfulBuildCount: Int + """ + Number of buids with unknown result for the issue + """ + unknownBuildCount: Int +} + +""" +Container for the summary of the Reviews attached to the issue +""" +type JiraIssueReviewDevSummaryContainer { + """ + The actual summary of the Reviews attached to the issue + """ + overall: JiraIssueReviewDevSummary + """ + Count of Reviews aggregated per provider + """ + summaryByProvider: [JiraIssueDevSummaryByProvider!] +} + +""" +Summary of the Reviews attached to the issue +""" +type JiraIssueReviewDevSummary { + """ + Total number of Reviews for the issue + """ + count: Int + """ + Date at which this summary was last updated + """ + lastUpdated: DateTime + + """ + State of the Reviews in the summary + """ + state: JiraReviewState + """ + Number of Reviews for the state + """ + stateCount: Int +} + +""" +Possible states for Reviews +""" +enum JiraReviewState { + """ + Review is in Review state + """ + REVIEW + """ + Review is in Require Approval state + """ + APPROVAL + """ + Review is in Summarize state + """ + SUMMARIZE + """ + Review has been rejected + """ + REJECTED + """ + Review has been closed + """ + CLOSED + """ + Review is in Draft state + """ + DRAFT + """ + Review is in Dead state + """ + DEAD + """ + Review state is unknown + """ + UNKNOWN +} + +""" +Container for the summary of the Deployment Environments attached to the issue +""" +type JiraIssueDeploymentEnvironmentDevSummaryContainer { + """ + The actual summary of the Deployment Environments attached to the issue + """ + overall: JiraIssueDeploymentEnvironmentDevSummary + """ + Count of Deployment Environments aggregated per provider + """ + summaryByProvider: [JiraIssueDevSummaryByProvider!] +} + +""" +Summary of the Deployment Environments attached to the issue +""" +type JiraIssueDeploymentEnvironmentDevSummary { + """ + Total number of Reviews for the issue + """ + count: Int + """ + Date at which this summary was last updated + """ + lastUpdated: DateTime + + """ + A list of the top environment there was a deployment on + """ + topEnvironments: [JiraIssueDeploymentEnvironment!] +} + +type JiraIssueDeploymentEnvironment { + """ + Title of the deployment environment + """ + title: String + """ + State of the deployment + """ + status: JiraIssueDeploymentEnvironmentState +} + +""" +Possible states for a deployment environment +""" +enum JiraIssueDeploymentEnvironmentState { + """ + The deployment was not deployed successfully + """ + NOT_DEPLOYED + """ + The deployment was deployed successfully + """ + DEPLOYED +}""" +Represents the common structure across Issue fields. +""" +interface JiraIssueField implements Node { + """ + Unique identifier for the entity. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias. + Applies to managed or commonly known custom fields in Jira, which allow lookup without requiring the custom field ID. + E.g. rank or startdate. + """ + aliasFieldId: ID + """ + Field type key. E.g. project, issuetype, com.pyxis.greenhopper.Jira:gh-epic-link. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String +} + +""" +The connection type for JiraIssueField. +""" +type JiraIssueFieldConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraIssueFieldEdge] +} + +union JiraIssueFieldConnectionResult = JiraIssueFieldConnection | QueryError + +""" +An edge in a JiraIssueField connection. +""" +type JiraIssueFieldEdge { + """ + The node at the edge. + """ + node: JiraIssueField + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents the configurations associated with an Issue field. +""" +interface JiraIssueFieldConfiguration { + """ + Attributes of an Issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Attributes of field configuration. +""" +type JiraFieldConfig { + """ + Defines if a field is required on a screen. + """ + isRequired: Boolean + """ + Defines if a field is editable. + """ + isEditable: Boolean + """ + Explains the reason why a field is not editable on a screen. + E.g. cases where a field needs a licensed premium version to be editable. + """ + nonEditableReason: JiraFieldNonEditableReason +} + +""" +Attributes of CMDB field configuration. +""" +type JiraCmdbFieldConfig { + """ + The object schema ID associated with the CMDB object. + """ + objectSchemaId: String! + """ + The object filter query. + """ + objectFilterQuery: String + """ + The issue scope filter query. + """ + issueScopeFilterQuery: String + """ + Indicates whether this CMDB field should contain multiple CMDB objects or not. + """ + multiple: Boolean + """ + Paginated list of CMDB attributes displayed on issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + attributesDisplayedOnIssue( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCmdbConfigAttributeConnection + """ + Paginated list of CMDB attributes included in autocomplete search. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + attributesIncludedInAutoCompleteSearch( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCmdbConfigAttributeConnection +} + +""" +The connection type for CMDB config attributes. +""" +type JiraCmdbConfigAttributeConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraCmdbConfigAttributeEdge] +} + +""" +An edge in a JiraCmdbConfigAttributeConnection. +""" +type JiraCmdbConfigAttributeEdge { + """ + The node at the edge. + """ + node: String + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents the information for a field being non-editable on Issue screens. +""" +type JiraFieldNonEditableReason { + """ + Message explanining why the field is non-editable (if present). + """ + message: String +} + +""" +Represents user made configurations associated with an Issue field. +""" +interface JiraUserIssueFieldConfiguration { + """ + Attributes of an Issue field configuration info from a user's customisation. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Attributes of user made field configurations. +""" +type JiraUserFieldConfig { + """ + Defines whether a field has been pinned by the user. + """ + isPinned: Boolean + """ + Defines if the user has preferred to check a field on Issue creation. + """ + isSelected: Boolean +} + +""" +Represents a priority field on a Jira Issue. +""" +type JiraPriorityField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The priority selected on the Issue or default priority configured for the field. + """ + priority: JiraPriority + """ + Paginated list of priority options for the field or on an Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + priorities( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Determines if the results should be limited to suggested priorities. + """ + suggested: Boolean + ): JiraPriorityConnection + """ + Attributes of an Issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a project field on a Jira Issue. +Both the system & custom project field can be represented by this type. +""" +type JiraProjectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The ID of the project field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The project selected on the Issue or default project configured for the field. + """ + project: JiraProject + """ + List of project options available for this field to be selected. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + projects( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + recent: Boolean = false + ) : JiraProjectConnection + """ + Search url to fetch all available projects options on the field or an Issue. + To be deprecated once project connection is supported for custom project fields. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an Issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents an issue type field on a Jira Issue. +""" +type JiraIssueTypeField implements Node & JiraIssueField & JiraIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """" + The issue type selected on the Issue or default issue type configured for the field. + """ + issueType: JiraIssueType + """ + List of issuetype options available to be selected for the field. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + issueTypes( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraIssueTypeConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Represents a rich text field on a Jira Issue. E.g. description, environment. +""" +type JiraRichTextField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The rich text selected on the Issue or default rich text configured for the field. + """ + richText: JiraRichText + """ + Determines what editor to render. + E.g. default text rendering or wiki text rendering. + """ + renderer: String + """ + Contains the information needed to add media content to the field. + """ + mediaContext: JiraMediaContext + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a version field on a Jira Issue. E.g. custom version picker field. +""" +type JiraSingleVersionPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The version selected on the Issue or default version configured for the field. + """ + version: JiraVersion + """ + Paginated list of versions options for the field or on a Jira Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + versions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraVersionConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a multi version picker field on a Jira Issue. E.g. fixVersions and multi version custom field. +""" +type JiraMultipleVersionPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The versions selected on the Issue or default versions configured for the field. + """ + selectedVersions: [JiraVersion] @deprecated(reason: "Please use selectedVersionsConnection instead.") + """ + The versions selected on the Issue or default versions configured for the field. + """ + selectedVersionsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraVersionConnection + """ + Paginated list of versions options for the field or on a Jira Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + versions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraVersionConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a labels field on a Jira Issue. Both system & custom field can be represented by this type. +""" +type JiraLabelsField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The labels selected on the Issue or default labels configured for the field. + """ + selectedLabels: [JiraLabel] @deprecated(reason: "Please use selectedLabelsConnection instead.") + """ + The labels selected on the Issue or default labels configured for the field. + """ + selectedLabelsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraLabelConnection + """ + Paginated list of label options for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + labels( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraLabelConnection + """ + Search url to fetch all available label options on a field or an Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a single select user field on a Jira Issue. E.g. assignee, reporter, custom user picker. +""" +type JiraSingleSelectUserPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The user selected on the Issue or default user configured for the field. + """ + user: User + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a multi select user picker field on a Jira Issue. E.g. custom user picker, sd-request-participants. +""" +type JiraMultipleSelectUserPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the entity. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key of the field. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsers: [User] @deprecated(reason: "Please use selectedUsersConnection instead.") + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsersConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraUserConnection + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + + +""" +Represents a people picker field on a Jira Issue. E.g. people custom field, servicedesk-approvers-list. +""" +type JiraPeopleField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The people selected on the Issue or default people configured for the field. + """ + selectedUsers: [User] @deprecated(reason: "Please use selectedUsersConnection instead.") + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsersConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraUserConnection + """ + Whether the field is configured to act as single/multi select user(s) field. + """ + isMulti: Boolean + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a date time picker field on a Jira Issue. E.g. created, resolution date, custom date time, request-feedback-date. +""" +type JiraDateTimePickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The datetime selected on the Issue or default datetime configured for the field. + """ + dateTime: DateTime + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a date picker field on an issue. E.g. due date, custom date picker, baseline start, baseline end. +""" +type JiraDatePickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The date selected on the Issue or default date configured for the field. + """ + date: Date + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a resolution field on a Jira Issue. +""" +type JiraResolutionField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The resolution selected on the Issue or default resolution configured for the field. + """ + resolution: JiraResolution + """ + Paginated list of resolution options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + resolutions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraResolutionConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a number field on a Jira Issue. E.g. float, story points. +""" +type JiraNumberField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The number selected on the Issue or default number configured for the field. + """ + number: Float + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + Returns if the current number field is a story point field + """ + isStoryPointField: Boolean @deprecated(reason: "Story point field is treated as a special field only on issue view") +} + +""" +Represents single line text field on a Jira Issue. E.g. summary, epic name, custom text field. +""" +type JiraSingleLineTextField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The text selected on the Issue or default text configured for the field. + """ + text: String + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents epic link field on a Jira Issue. +""" +type JiraEpicLinkField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The epic selected on the Issue or default epic configured for the field. + """ + epic: JiraEpic + """ + Paginated list of epic options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + epics( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Set to true to search only for epics that are done, false otherwise. + """ + done: Boolean + ): JiraEpicConnection + """ + Search url to fetch all available epics options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents components field on a Jira Issue. +""" +type JiraComponentsField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The component selected on the Issue or default component configured for the field. + """ + selectedComponents: [JiraComponent] @deprecated(reason: "Please use selectedComponentsConnection instead.") + """ + The component selected on the Issue or default component configured for the field. + """ + selectedComponentsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraComponentConnection + """ + Paginated list of component options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + components( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraComponentConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents url field on a Jira Issue. +""" +type JiraUrlField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The url selected on the Issue or default url configured for the field. (deprecated) + """ + url: URL @deprecated(reason: "Please use urlValue; replaced Url with String to accommodate values that are URI but not URL") + """ + The url selected on the Issue or default url configured for the field. + """ + urlValue: String + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents sprint field on a Jira Issue. +""" +type JiraSprintField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The sprints selected on the Issue or default sprints configured for the field. + """ + selectedSprints: [JiraSprint] @deprecated(reason: "Please use selectedSprintsConnection instead.") + """ + The sprints selected on the Issue or default sprints configured for the field. + """ + selectedSprintsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraSprintConnection + """ + Paginated list of sprint options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + sprints( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + The Result Sprints fetched will have particular Sprint State eg. ACTIVe. + """ + state: JiraSprintState + ): JiraSprintConnection + """ + Search url to fetch all available sprints options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents linked issues field on a Jira Issue. +""" +type JiraIssueLinkField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Represents all the issue links defined on a Jira Issue. Should be deprecated and replaced with issueLinksConnection. + """ + issueLinks: [JiraIssueLink] @deprecated(reason: "Please use issueLinkConnection instead.") + """ + Paginated list of issue links selected on the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + issueLinkConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueLinkConnection + """ + Represents the different issue link type relations/desc which can be mapped/linked to the issue in context. + Issue in context is the one which is being created/ which is being queried. + """ + issueLinkTypeRelations( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueLinkTypeRelationConnection + """ + Paginated list of issues which can be related/linked with above issueLinkTypeRelations. + """ + issues( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueConnection + """ + Search url to list all available issues which can be related/linked with above issueLinkTypeRelations. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents Parent field on a Jira Issue. E.g. JSW Parent, JPO Parent (to be unified). +""" +type JiraParentIssueField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The parent selected on the Issue or default parent configured for the field. + """ + parentIssue: JiraIssue + """ + Represents flags required to determine parent field visibility + """ + parentVisibility: JiraParentVisibility + """ + Search url to fetch all available parents for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents security level field on a Jira Issue. Issue Security allows you to control who can and cannot view issues. +""" +type JiraSecurityLevelField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The security level selected on the Issue or default security level configured for the field. + """ + securityLevel: JiraSecurityLevel + """ + Paginated list of security level options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + securityLevels( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraSecurityLevelConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents cascading select field. Currently only handles 2 level hierarchy. +""" +type JiraCascadingSelectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The cascading option selected on the Issue or default cascading option configured for the field. + """ + cascadingOption: JiraCascadingOption + """ + Paginated list of cascading options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + cascadingOptions( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCascadingOptionsConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents issue restriction field on an issue for next gen projects. +""" +type JiraIssueRestrictionField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The roles selected on the Issue or default roles configured for the field. + """ + selectedRoles: [JiraRole] @deprecated(reason: "Please use selectedRolesConnection instead.") + """ + The roles selected on the Issue or default roles configured for the field. + """ + selectedRolesConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraRoleConnection + """ + Paginated list of roles available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + roles( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraRoleConnection + """ + Search URL to fetch all the roles options for the fields on an issue. + """ + searchUrl : String + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents color field on a Jira Issue. E.g. issue color, epic color. +""" +type JiraColorField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The color selected on the Issue or default color configured for the field. + """ + color: JiraColor + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents single select field on a Jira Issue. +""" +type JiraSingleSelectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The option selected on the Issue or default option configured for the field. + """ + fieldOption: JiraOption + """ + Paginated list of options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldOptions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Search URL to fetch the select option for the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the check boxes field on a Jira Issue. +""" +type JiraCheckboxesField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The options selected on the Issue or default options configured for the field. + """ + selectedFieldOptions: [JiraOption] @deprecated(reason: "Please use selectedOptions instead.") + """ + The options selected on the Issue or default options configured for the field. + """ + selectedOptions( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Paginated list of options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldOptions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the radio select field on a Jira Issue. +""" +type JiraRadioSelectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The option selected on the Issue or default option configured for the field. + """ + selectedOption: JiraOption + """ + Paginated list of options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldOptions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the Asset field on a Jira Issue. +""" +type JiraAssetField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The assets selected on the Issue or default assets configured for the field. + """ + selectedAssets: [JiraAsset] @deprecated(reason: "Please use selectedAssetsConnection instead.") + """ + The assets selected on the Issue or default assets configured for the field. + """ + selectedAssetsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraAssetConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Search URL to fetch all the assets for the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the multi-select field on a Jira Issue. +""" +type JiraMultipleSelectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The options selected on the Issue or default options configured for the field. + """ + selectedFieldOptions: [JiraOption] @deprecated(reason: "Please use selectedOptions instead.") + """ + The options selected on the Issue or default options configured for the field. + """ + selectedOptions( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Paginated list of options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldOptions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Search URL to fetch all the teams options for the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents single group picker field. Allows you to select single Jira group to be associated with an issue. +""" +type JiraSingleGroupPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The group selected on the Issue or default group configured for the field. + """ + selectedGroup: JiraGroup + """ + Paginated list of group options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + groups( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraGroupConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Search URL to fetch group picker field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a multiple group picker field on a Jira Issue. +""" +type JiraMultipleGroupPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The groups selected on the Issue or default groups configured for the field. + """ + selectedGroups: [JiraGroup] @deprecated(reason: "Please use selectedGroupsConnection instead.") + """ + The groups selected on the Issue or default groups configured for the field. + """ + selectedGroupsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraGroupConnection + """ + Paginated list of group options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + groups( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraGroupConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Search URL to fetch all group pickers of the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Deprecated type. Please use `JiraTeamViewField` instead. +""" +type JiraTeamField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The team selected on the Issue or default team configured for the field. + """ + selectedTeam: JiraTeam + """ + Paginated list of team options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + teams( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraTeamConnection + """ + Search URL to fetch all the teams options for the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Deprecated type. Please use `JiraTeamViewField` instead. +""" +type JiraAtlassianTeamField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The team selected on the Issue or default team configured for the field. + """ + selectedTeam: JiraAtlassianTeam + """ + Paginated list of team options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + teams( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraAtlassianTeamConnection + """ + Search URL to fetch all the teams options for the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the Team field on a Jira Issue. Allows you to select a team to be associated with an Issue. +""" +type JiraTeamViewField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The team selected on the Issue or default team configured for the field. + """ + selectedTeam: JiraTeamView + """ + Search URL to fetch all the teams options for the field on a Jira Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents Affected Services field. +""" +type JiraAffectedServicesField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The affected services selected on the Issue or default affected services configured for the field. + """ + selectedAffectedServices: [JiraAffectedService] @deprecated(reason: "Please use selectedAffectedServicesConnection instead.") + """ + The affected services selected on the Issue or default affected services configured for the field. + """ + selectedAffectedServicesConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraAffectedServiceConnection + """ + Paginated list of affected services available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + affectedServices( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraAffectedServiceConnection + """ + Search url to query for all Affected Services when user interact with field. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents CMDB (Configuration Management Database) field on a Jira Issue. +""" +type JiraCMDBField implements Node & JiraIssueField & JiraIssueFieldConfiguration{ + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Whether the field is configured to act as single/multi select CMDB(s) field. + """ + isMulti: Boolean @deprecated(reason: "Please use `multiple` defined in `JiraCmdbFieldConfig`.") + """ + Search url to fetch all available cmdb options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + The CMDB objects selected on the Issue or default CMDB objects configured for the field. + """ + selectedCmdbObjects: [JiraCmdbObject] @deprecated(reason: "Please use selectedCmdbObjectsConnection instead.") + """ + The CMDB objects selected on the Issue or default CMDB objects configured for the field. + """ + selectedCmdbObjectsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraCmdbObjectConnection + """ + Indicates whether the field has been enriched with data from Insight, allowing Jira to show correct error states. + """ + wasInsightRequestSuccessful: Boolean + """ + Indicates whether the current site has sufficient licence for the Insight feature, allowing Jira to show correct error states. + """ + isInsightAvailable: Boolean + """ + Attributes of a CMDB field’s configuration info. + """ + cmdbFieldConfig: JiraCmdbFieldConfig + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + Attributes that are configured for autocomplete search. + """ + attributesIncludedInAutoCompleteSearch: [String] @deprecated(reason: "Please use `attributesIncludedInAutoCompleteSearch` defined in `JiraCmdbFieldConfig`.") +} + +""" +Represents the time tracking field on Jira issue screens. +""" +type JiraTimeTrackingField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Original Estimate displays the amount of time originally anticipated to resolve the issue. + """ + originalEstimate: JiraEstimate + """ + Time Remaining displays the amount of time currently anticipated to resolve the issue. + """ + remainingEstimate: JiraEstimate + """ + Time Spent displays the amount of time that has been spent on resolving the issue. + """ + timeSpent: JiraEstimate + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + This represents the global time tracking settings configuration like working hours and days. + """ + timeTrackingSettings: JiraTimeTrackingSettings +} + +""" +Represents the original time estimate field on Jira issue screens. Note that this is the same value as the originalEstimate from JiraTimeTrackingField +This field should only be used on issue view because issue view hasn't deprecated the original estimation as a standalone field +""" +type JiraOriginalTimeEstimateField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Original Estimate displays the amount of time originally anticipated to resolve the issue. + """ + originalEstimate: JiraEstimate + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a text field created by Connect App. +""" +type JiraConnectTextField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Content of the connect text field. + """ + text: String + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a number field created by Connect App. +""" +type JiraConnectNumberField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Connected number. + """ + number: Float + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a single select field created by Connect App. +""" +type JiraConnectSingleSelectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The option selected on the Issue or default option configured for the field. + """ + fieldOption: JiraOption + """ + Paginated list of options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldOptions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Search url to fetch all available options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a multi-select field created by Connect App. +""" +type JiraConnectMultipleSelectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The options selected on the Issue or default options configured for the field. + """ + selectedFieldOptions: [JiraOption] @deprecated(reason: "Please use selectedOptions instead.") + """ + The options selected on the Issue or default options configured for the field. + """ + selectedOptions( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Paginated list of options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + fieldOptions( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraOptionConnection + """ + Search url to fetch all available options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents rich text field on a Jira Issue. E.g. description, environment. +""" +type JiraConnectRichTextField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The rich text selected on the Issue or default rich text configured for the field. + """ + richText: JiraRichText + """ + Determines what editor to render. + E.g. default text rendering or wiki text rendering. + """ + renderer: String + """ + Contains the information needed to add a media content to this field. + """ + mediaContext: JiraMediaContext + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents Status field. +""" +type JiraStatusField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The status selected on the Issue or default status configured for the field. + """ + status: JiraStatus! + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents Status Category field. +""" +type JiraStatusCategoryField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The status category for the issue or default status category configured for the field. + """ + statusCategory: JiraStatusCategory! + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a string field created by Forge App. +""" +type JiraForgeStringField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The text selected on the Issue or default text configured for the field. + """ + text: String + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a strings field created by Forge App. +""" +type JiraForgeStringsField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The labels selected on the Issue or default labels configured for the field. + """ + selectedLabels: [JiraLabel] @deprecated(reason: "Please use selectedLabelsConnection instead.") + """ + The labels selected on the Issue or default labels configured for the field. + """ + selectedLabelsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraLabelConnection + """ + Paginated list of label options for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + labels( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraLabelConnection + """ + Search url to fetch all available labels options on the field or an Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a number field created by Forge App. +""" +type JiraForgeNumberField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The number selected on the Issue or default number configured for the field. + """ + number: Float + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a date time field created by Forge App. +""" +type JiraForgeDatetimeField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The datetime selected on the issue or default datetime configured for the field. + """ + dateTime: DateTime + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a object field created by Forge App. +""" +type JiraForgeObjectField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The object string selected on the issue or default datetime configured for the field. + """ + object: String + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a User field created by Forge App. +""" +type JiraForgeUserField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The user selected on the Issue or default user configured for the field. + """ + user: User + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a Users field created by Forge App. +""" +type JiraForgeUsersField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsers: [User] @deprecated(reason: "Please use selectedUsersConnection instead.") + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsersConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraUserConnection + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a Group field created by Forge App. +""" +type JiraForgeGroupField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The group selected on the Issue or default group configured for the field. + """ + selectedGroup: JiraGroup + """ + Paginated list of group options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + groups( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraGroupConnection + """ + Search url to fetch all available groups for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a Groups field created by Forge App. +""" +type JiraForgeGroupsField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The groups selected on the Issue or default group configured for the field. + """ + selectedGroups: [JiraGroup] @deprecated(reason: "Please use selectedGroupsConnection instead.") + """ + The groups selected on the Issue or default group configured for the field. + """ + selectedGroupsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraGroupConnection + """ + Paginated list of group options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + groups( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraGroupConnection + """ + Search url to fetch all available groups for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig + """ + The renderer type of the forge app, returns 'forge' if it's customised in the app, otherwise returns the one of the predefined custom field renderer type. + """ + renderer: String +} + +""" +Represents a votes field on a Jira Issue. +""" +type JiraVotesField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Represents the vote value selected on the Issue. + Can be null when voting is disabled. + """ + vote: JiraVote + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the Watches system field. +""" +type JiraWatchesField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Represents the watch value selected on the Issue. + Can be null when watching is disabled. + """ + watch: JiraWatch + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a flag field on a Jira Issue. E.g. flagged. +""" +type JiraFlagField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The flag value selected on the Issue. + """ + flag: JiraFlag + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Deprecated type. Please use `childIssues` field under `JiraIssue` instead. +""" +type JiraSubtasksField implements Node & JiraIssueField & JiraIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Paginated list of subtasks on the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + subtasks( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Deprecated type. Please use `attachments` field under `JiraIssue` instead. +""" +type JiraAttachmentsField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Defines the permissions of the attachment collection. + """ + permissions: [JiraAttachmentsPermissions] + """ + Paginated list of attachments available for the field or the Issue. + """ + attachments( + startAt: Int + maxResults: Int + orderField: JiraAttachmentsOrderField, + orderDirection: JiraOrderDirection + ): JiraAttachmentConnection + """ + Defines the maximum size limit (in bytes) of the total of all the attachments which can be associated with this field. + """ + maxAllowedTotalAttachmentsSize: Long + """ + Contains the information needed to add a media content to this field. + """ + mediaContext: JiraMediaContext + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents dev summary for an issue. The identifier for this field is devSummary +""" +type JiraDevSummaryField implements Node & JiraIssueField { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + A summary of the development information (e.g. pull requests, commits) associated with + this issue. + + WARNING: The data returned by this field may be stale/outdated. This field is temporary and + will be replaced by a `devSummary` field that returns up-to-date information. + + In the meantime, if you only need data for a single issue you can use the `JiraDevOpsQuery.devOpsIssuePanel` + field to get up-to-date dev summary data. + """ + devSummaryCache: JiraIssueDevSummaryResult +} + +""" +Represents the WorkCategory field on an Issue. +""" +type JiraWorkCategoryField implements Node & JiraIssueField & JiraIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The WorkCategory selected on the Issue or default WorkCategory configured for the field. + """ + workCategory: JiraWorkCategory + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Represents a generic boolean field for an Issue. E.g. JSM alert linking. +""" +type JiraBooleanField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The value selected on the Issue or default value configured for the field. + """ + value: Boolean + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the proforma-forms field for an Issue. +""" +type JiraProformaFormsField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The proforma-forms selected on the Issue or default major incident configured for the field. + """ + proformaForms: JiraProformaForms + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +############################################################ +########### Jira Service Management (JSM) Fields ########### +############################################################ + +""" +Represents the Request Feedback custom field on an Issue in a JSM project. +""" +type JiraServiceManagementRequestFeedbackField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Represents the JSM feedback rating value selected on the Issue. + """ + feedback: JiraServiceManagementFeedback + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents a datetime field on an Issue in a JSM project. +Deprecated: Please use `JiraDateTimePickerField`. +""" +type JiraServiceManagementDateTimeField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The datetime selected on the Issue or default datetime configured for the field. + """ + dateTime: DateTime + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the responders entity custom field on an Issue in a JSM project. +""" +type JiraServiceManagementRespondersField implements Node & JiraIssueField & JiraIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Represents the list of responders. + """ + responders: [JiraServiceManagementResponder] @deprecated(reason: "Please use respondersConnection instead.") + """ + Represents the list of responders. + """ + respondersConnection( + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementResponderConnection + """ + Search URL to query for all responders available for the user to choose from when interacting with the field. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Represents the Incident Linking custom field on an Issue in a JSM project. +Deprecated: please use `JiraBooleanField` instead. +""" +type JiraServiceManagementIncidentLinkingField implements Node & JiraIssueField & JiraIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + Represents the JSM incident linked to the issue. + """ + incident: JiraServiceManagementIncident + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Represents the Approval custom field on an Issue in a JSM project. +""" +type JiraServiceManagementApprovalField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. customfield_10001 or description. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The active approval is used to render the approval panel that the users can interact with to approve/decline the request or update approvers. + """ + activeApproval: JiraServiceManagementActiveApproval + """ + The completed approvals are used to render the approval history section and contains records for all previous approvals for that issue. + """ + completedApprovals: [JiraServiceManagementCompletedApproval] @deprecated(reason: "Please use completedApprovalsConnection instead.") + """ + The completed approvals are used to render the approval history section and contains records for all previous approvals for that issue. + """ + completedApprovalsConnection( + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementCompletedApprovalConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Deprecated type. Please use `JiraMultipleSelectUserPickerField` instead. +""" +type JiraServiceManagementMultipleSelectUserPickerField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsers: [User] @deprecated(reason: "Please use selectedUsersConnection instead.") + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsersConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraUserConnection + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the Request Language field on an Issue in a JSM project. +""" +type JiraServiceManagementRequestLanguageField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The language selected on the Issue or default language configured for the field. + """ + language: JiraServiceManagementLanguage + """ + List of languages available. + """ + languages: [JiraServiceManagementLanguage] + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the Customer Organization field on an Issue in a JSM project. +""" +type JiraServiceManagementOrganizationField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The organizations selected on the Issue or default organizations configured for the field. + """ + selectedOrganizations: [JiraServiceManagementOrganization] @deprecated(reason: "Please use selectedOrganizationsConnection instead.") + """ + The organizations selected on the Issue or default organizations configured for the field. + """ + selectedOrganizationsConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraServiceManagementOrganizationConnection + """ + Paginated list of organization options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + organizations( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraServiceManagementOrganizationConnection + """ + Search url to query for all Customer orgs when user interact with field. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Deprecated type. Please use `JiraPeopleField` instead. +""" +type JiraServiceManagementPeopleField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The people selected on the Issue or default people configured for the field. + """ + selectedUsers: [User] @deprecated(reason: "Please use selectedUsersConnection instead.") + """ + The users selected on the Issue or default users configured for the field. + """ + selectedUsersConnection( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraUserConnection + """ + Whether the field is configured to act as single/multi select user(s) field. + """ + isMulti: Boolean + """ + Paginated list of user options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + users( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraUserConnection + """ + Search url to fetch all available users options for the field or the Issue. + """ + searchUrl: String @deprecated(reason: "Search URLs are planned to be replaced by Connections.") + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} + +""" +Represents the request type field for an Issue in a JSM project. +""" +type JiraServiceManagementRequestTypeField implements Node & JiraIssueField & JiraIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The request type selected on the Issue or default request type configured for the field. + """ + requestType: JiraServiceManagementRequestType + """ + Paginated list of request type options available for the field or the Issue. + The server may throw an error if both a forward page (specified with `first`) and a backward page (specified with `last`) are requested simultaneously. + """ + requestTypes( + """ + Search by the id/name of the item. + """ + searchBy: String + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Returns the recent items based on user history. + """ + suggested: Boolean + ): JiraServiceManagementRequestTypeConnection + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig +} + +""" +Represents the major incident field for an Issue in a JSM project. +""" +type JiraServiceManagementMajorIncidentField implements Node & JiraIssueField & JiraIssueFieldConfiguration & JiraUserIssueFieldConfiguration { + """ + Unique identifier for the field. + """ + id: ID! + """ + The identifier of the field. E.g. summary, customfield_10001, etc. + """ + fieldId: String! + """ + The field ID alias (if applicable). + """ + aliasFieldId: ID + """ + Field type key. + """ + type: String! + """ + Translated name for the field (if applicable). + """ + name: String! + """ + Description for the field (if present). + """ + description: String + """ + The major incident selected on the Issue or default major incident configured for the field. + """ + majorIncident: JiraServiceManagementMajorIncident + """ + Attributes of an issue field's configuration info. + """ + fieldConfig: JiraFieldConfig + """ + Configuration changes which a user can apply to a field. E.g. pin or hide the field. + """ + userFieldConfig: JiraUserFieldConfig +} +extend type JiraQuery { + """ + Container for all Issue Hierarchy Configuration related queries in Jira + """ + issueHierarchyConfig(cloudId: ID!): JiraIssueHierarchyConfigurationQuery! + + """ + Container for all Issue Hierarchy Limits related queries in Jira + """ + issueHierarchyLimits(cloudId: ID!): JiraIssueHierarchyLimits! + + """ + A List of JiraIssueType IDs that cannot be moved to a different hierarchy level. + """ + lockedIssueTypeIds(cloudId: ID!): [ID!]! +} + +extend type JiraMutation { + """ + Used to update the Issue Hierarchy Configuration in Jira + """ + updateIssueHierarchyConfig( + cloudId: ID!, + input: JiraIssueHierarchyConfigurationMutationInput! + ): JiraIssueHierarchyConfigurationMutationResult! +} + +type JiraIssueHierarchyConfigurationMutationResult { + """ + The field that indicates if the update action is successfully initiated + """ + updateInitiated: Boolean! + + """ + The success indicator saying whether mutation operation was successful as a whole or not + """ + success: Boolean! + + """ + The errors field represents additional mutation error information if exists + """ + errors: [JiraHierarchyConfigError!] +} + +type JiraIssueHierarchyConfigurationQuery { + """ + This indicates data payload + """ + data: [JiraIssueHierarchyConfigData!] + + """ + The success indicator saying whether mutation operation was successful as a whole or not + """ + success: Boolean! + + """ + The errors field represents additional mutation error information if exists + """ + errors: [JiraHierarchyConfigError!] +} + +type JiraIssueHierarchyConfigData { + """ + Each one of the levels with its basic data + """ + hierarchyLevel: JiraIssueTypeHierarchyLevel + + """ + Issue types inside the level + """ + cmpIssueTypes( + first: Int, + after: String, + last: Int, + before: String + ): JiraIssueTypeConnection +} + +type JiraIssueHierarchyLimits { + """ + Max levels that the user can set + """ + maxLevels: Int! + + """ + Max name length + """ + nameLength: Int! +} + +type JiraHierarchyConfigError { + """ + This indicates error code + """ + code: String + + """ + This indicates error message + """ + message: String +} + +input JiraIssueHierarchyConfigInput { + """ + Level number + """ + level: Int! + + """ + Level title + """ + title: String! + + """ + A list of issue type IDs + """ + issueTypeIds: [ID!]! +} + +input JiraIssueHierarchyConfigurationMutationInput { + """ + This indicates if the service needs to make a simulation run + """ + dryRun: Boolean! + + """ + A list of hierarchy config input objects + """ + issueHierarchyConfig: [JiraIssueHierarchyConfigInput!]! +} +extend type JiraQuery { + """ + Used to retrieve Issue layout information by type by `issueId`. + """ + issueContainersByType( + input: JiraIssueItemSystemContainerTypeWithIdInput! + ): JiraIssueItemContainersResult! + + """ + Used to retrieve Issue layout information by `issueKey` and `cloudId`. + """ + issueContainersByTypeByKey( + input: JiraIssueItemSystemContainerTypeWithKeyInput! + ): JiraIssueItemContainersResult! +}type JiraIssueLinkTypeRelation implements Node { + "Global identifier for the Issue Link Type Relation." + id: ID! + """ + Represents the description of the relation by which this link is identified. + This can be the inward or outward description of an IssueLinkType. + E.g. blocks, is blocked by, duplicates, is duplicated by, clones, is cloned by. + """ + relationName: String + """ + Represents the IssueLinkType id to which this type belongs to. + """ + linkTypeId: String! + """ + Display name of IssueLinkType to which this relation belongs to. E.g. Blocks, Duplicate, Cloners. + """ + linkTypeName: String + """ + Represents the direction of Issue link type. E.g. INWARD, OUTWARD. + """ + direction: JiraIssueLinkDirection +} + +""" +Represents a single Issue link containing the link id, link type and destination Issue. + +For Issue create, JiraIssueLink will be populated with +the default IssueLink types in the relatedBy field. +The issueLinkId and Issue fields will be null. + +For Issue view, JiraIssueLink will be populated with +the Issue link data available on the Issue. +The Issue field will contain a nested JiraIssue that is atmost 1 level deep. +The nested JiraIssue will not contain fields that can contain further nesting. +""" +type JiraIssueLink { + """ + Global identifier for the Issue Link. + """ + id: ID + """ + Identifier for the Issue Link. Can be null to represent a link not yet created. + """ + issueLinkId: String + """ + Issue link type relation through which the source Issue is connected to the + destination Issue. Source Issue is the Issue being created/queried. + """ + relatedBy: JiraIssueLinkTypeRelation + """ + The destination Issue to which this link is connected. + """ + issue: JiraIssue +} + +""" +The connection type for JiraIssueLink. +""" +type JiraIssueLinkConnection { + """ + The total number of JiraIssueLink matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraIssueLinkEdge] +} + +""" +An edge in a JiraIssueLink connection. +""" +type JiraIssueLinkEdge { + """ + The node at the edge. + """ + node: JiraIssueLink + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraIssueLinkTypeRelation. +""" +type JiraIssueLinkTypeRelationConnection { + """ + The total number of JiraIssueLinkTypeRelation matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraIssueLinkTypeRelationEdge] +} + +""" +An edge in a JiraIssueLinkType connection. +""" +type JiraIssueLinkTypeRelationEdge { + """ + The node at the edge. + """ + node: JiraIssueLinkTypeRelation + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents the possible linking directions between issues. +""" +enum JiraIssueLinkDirection { + """ + Going from the other issue to this issue. + """ + INWARD + """ + Going from this issue to the other issue. + """ + OUTWARD +} +extend type JiraQuery { + """ + Performs an issue search using the provided string of JQL. + This query will error if the JQL does not pass validation. + """ + issueSearchByJql(cloudId: ID!, jql: String!): JiraIssueSearchByJqlResult + + """ + Performs an issue search using the underlying JQL saved as a filter. + + The id provided MUST be in ARI format. + + This query will error if the id parameter is not in ARI format, does not pass validation or does not correspond to a filter. + """ + issueSearchByFilterId(id: ID!): JiraIssueSearchByFilterResult + + """ + Hydrate a list of issue IDs into issue data. The issue data retrieved will depend on + the subsequently specified view(s) and/or fields. + + The ids provided MUST be in ARI format. + + For each id provided, it will resolve to either a JiraIssue as a leaf node in an subsequent query, or a QueryError if: + - The ARI provided did not pass validation. + - The ARI did not resolve to an issue. + """ + issueHydrateByIssueIds(ids: [ID!]!): JiraIssueSearchByHydration + + """ + Retrieves data about a JiraIssueSearchView. + + The id provided MUST be in ARI format. + + This query will error if the id parameter is not in ARI format, does not pass validation or does not correspond to a JiraIssueSearchView. + """ + issueSearchView(id: ID!): JiraIssueSearchView + + """ + Retrieves a JiraIssueSearchView corresponding to the provided namespace and viewId. + """ + issueSearchViewByNamespaceAndViewId(cloudId: ID!, namespace: String, viewId: String): JiraIssueSearchView + + """ + Performs an issue search using the issueSearchInput argument. + This relies on stable search where the issue ids from the initial search are preserved between pagination. + An "initial search" is when no cursors are specified. + The server will configure a limit on the maximum issue ids preserved for a given search e.g. 1000. + On pagination, we take the next page of issues from this stable set of 1000 ids and return hydrated issue data. + """ + issueSearchStable( + """ + The cloud id of the tenant. + """ + cloudId: ID! + """ + The input used for the issue search. + """ + issueSearchInput: JiraIssueSearchInput! + """ + The options used for an issue search. + """ + options: JiraIssueSearchOptions + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueConnection +} + +extend type JiraMutation { + """ + Replaces field config sets from the specified JiraIssueSearchView with the provided field config set id nodes. + If the provided nodes contain a node outside the given range of `before` and/or `after`, then those nodes will also be deleted and replaced within the range. + - If `before` is provided, then the entire range before that node will be replaced, or error if not found. + - If `after` is provided, then the entire range after that node will be replaced, or error if not found. + - If `before` and `after` are both provided, then the range between `before` and `after` will be replaced depending on the inclusive value. + - If neither `before` or `after` are provided, then the entire range will be replaced. + + The id provided MUST be in ARI format. This mutation will error if the id parameter is not in ARI format, does not pass validation or does not correspond to a JiraIssueSearchView. + """ + replaceIssueSearchViewFieldSets( + id: ID! + input: JiraReplaceIssueSearchViewFieldSetsInput! + ): JiraIssueSearchViewPayload +} + +input JiraReplaceIssueSearchViewFieldSetsInput { + before: String + after: String + nodes: [String!]! + # Denotes whether `before` and/or `after` nodes will be replaced inclusively. If not specified, defaults to false. + inclusive: Boolean +} + +""" +The payload returned when a JiraIssueSearchView has been updated. +""" +type JiraIssueSearchViewPayload implements Payload { + success: Boolean! + errors: [MutationError!] + view: JiraIssueSearchView +} + +""" +A generic interface for issue search results in Jira. +""" +interface JiraIssueSearchResult { + """ + Retrieves content controlled by the context of a JiraIssueSearchView. + To query multiple content views at once, use GraphQL aliases. + + If a namespace is provided, and a viewId is: + - Not provided, then the last used view is returned within this namespace. + - Provided, then this view is returned if it exists in this namespace. + + If a namespace is not provided, and a viewId is: + - Not provided, then the last used view across any namespace is returned. + - Provided, then this view is returned if it exists in the global namespace. + """ + content(namespace: String, viewId: String): JiraIssueSearchContextualContent + + """ + Retrieves content by provided field config set ids, ignoring the active query context. + To query multiple content views at once, use GraphQL aliases. + """ + contentByFieldSetIds(fieldSetIds: [String!]!): JiraIssueSearchContextlessContent +} + +""" +Represents an issue search result when querying with a JiraFilter. +""" +type JiraIssueSearchByFilter implements JiraIssueSearchResult { + """ + Retrieves content controlled by the context of a JiraIssueSearchView. + To query multiple content views at once, use GraphQL aliases. + + If a namespace is provided, and a viewId is: + - Not provided, then the last used view is returned within this namespace. + - Provided, then this view is returned if it exists in this namespace. + + If a namespace is not provided, and a viewId is: + - Not provided, then the last used view across any namespace is returned. + - Provided, then this view is returned if it exists in the global namespace. + """ + content(namespace: String, viewId: String): JiraIssueSearchContextualContent + """ + Retrieves content by provided field config set ids, ignoring the active query context. + To query multiple content views at once, use GraphQL aliases. + """ + contentByFieldSetIds(fieldSetIds: [String!]!): JiraIssueSearchContextlessContent + """ + The Jira Filter corresponding to the filter ARI specified in the calling query. + """ + filter: JiraFilter +} + + +union JiraIssueSearchByJqlResult = JiraIssueSearchByJql | QueryError + +union JiraIssueSearchByFilterResult = JiraIssueSearchByFilter | QueryError + +""" +Represents an issue search result when querying with a Jira Query Language (JQL) string. +""" +type JiraIssueSearchByJql implements JiraIssueSearchResult { + """ + Retrieves content controlled by the context of a JiraIssueSearchView. + To query multiple content views at once, use GraphQL aliases. + + If a namespace is provided, and a viewId is: + - Not provided, then the last used view is returned within this namespace. + - Provided, then this view is returned if it exists in this namespace. + + If a namespace is not provided, and a viewId is: + - Not provided, then the last used view across any namespace is returned. + - Provided, then this view is returned if it exists in the global namespace. + """ + content(namespace: String, viewId: String): JiraIssueSearchContextualContent + """ + Retrieves content by provided field config set ids, ignoring the active query context. + To query multiple content views at once, use GraphQL aliases. + """ + contentByFieldSetIds(fieldSetIds: [String!]!): JiraIssueSearchContextlessContent + """ + The JQL specified in the calling query. + """ + jql: String +} + +""" +Represents an issue search result when querying with a set of issue ids. +""" +type JiraIssueSearchByHydration implements JiraIssueSearchResult { + """ + Retrieves content controlled by the context of a JiraIssueSearchView. + To query multiple content views at once, use GraphQL aliases. + + If a namespace is provided, and a viewId is: + - Not provided, then the last used view is returned within this namespace. + - Provided, then this view is returned if it exists in this namespace. + + If a namespace is not provided, and a viewId is: + - Not provided, then the last used view across any namespace is returned. + - Provided, then this view is returned if it exists in the global namespace. + """ + content(namespace: String, viewId: String): JiraIssueSearchContextualContent + """ + Retrieves content by provided field config set ids, ignoring the active query context. + To query multiple content views at once, use GraphQL aliases. + """ + contentByFieldSetIds(fieldSetIds: [String!]!): JiraIssueSearchContextlessContent +} + +""" +A generic interface for the content of an issue search result in Jira. +""" +interface JiraIssueSearchResultContent { + """ + Retrieves JiraIssue limited by provided pagination params, or global search limits, whichever is smaller. + To retrieve multiple sets of issues, use GraphQL aliases. + + An optimized search is run when only JiraIssue issue ids are requested. + """ + issues( + first: Int + last: Int + before: String + after: String + ): JiraIssueConnection +} + +""" +Represents the contextual content for an issue search result in Jira. +The context here is determined by the JiraIssueSearchView associated with the content. +""" +type JiraIssueSearchContextualContent implements JiraIssueSearchResultContent { + """ + The JiraIssueSearchView that will be used as the context when retrieving JiraIssueField data. + """ + view: JiraIssueSearchView + """ + Retrieves a connection of JiraIssues for the current search context. + """ + issues( + first: Int + last: Int + before: String + after: String + ): JiraIssueConnection +} + +""" +Represents the contextless content for an issue search result in Jira. +There is no JiraIssueSearchView associated with this content and is therefore contextless. +""" +type JiraIssueSearchContextlessContent implements JiraIssueSearchResultContent { + """ + Retrieves a connection of JiraIssues for the current search context. + """ + issues( + first: Int + last: Int + before: String + after: String + ): JiraIssueConnection +} + +""" +Represents a grouping of search data to a particular UI behaviour. +Built-in views are automatically created for certain Jira pages and global Jira system filters. +""" +type JiraIssueSearchView implements Node { + """ + An ARI-format value that encodes both namespace and viewId. + """ + id: ID! + """ + A subscoping that affects where this view's last used data is stored and grouped by. If null, this view is in the global namespace. + """ + namespace: String + """ + A unique identifier for this view within its namespace, or the global namespace if no namespace is defined. + """ + viewId: String + """ + A connection of included fields' configurations, grouped where logical (e.g. collapsed fields). + """ + fieldSets(first: Int, last: Int, before: String, after: String, filter: JiraIssueSearchFieldSetsFilter): JiraIssueSearchFieldSetConnection +} + +""" +Specifies which field config sets should be returned. +""" +enum JiraIssueSearchFieldSetSelectedState { + """ + Both selected and non-selected field config sets. + """ + ALL, + """ + Only the field config sets selected in the current view. + """ + SELECTED, + """ + Only the field config sets that have not been selected in the current view. + """ + NON_SELECTED +} + +""" +A filter for the JiraIssueSearchFieldSet connections. +By default, if no fieldSetSelectedState is specified, only SELECTED fields are returned. +""" +input JiraIssueSearchFieldSetsFilter { + """ + Only the fieldSets that case-insensitively, contain this searchString in their displayName will be returned. + """ + searchString: String, + """ + An enum specifying which field config sets should be returned based on the selected status. + """ + fieldSetSelectedState: JiraIssueSearchFieldSetSelectedState, +} + +""" +A Connection of JiraIssueSearchFieldSet. +""" +type JiraIssueSearchFieldSetConnection { + """ + The total number of JiraIssueSearchFieldSet matching the criteria + """ + totalCount: Int + """ + The page info of the current page of results + """ + pageInfo: PageInfo! + """ + The data for Edges in the current page + """ + edges: [JiraIssueSearchFieldSetEdge] + """ + Indicates if any fields in the column configuration cannot be shown as they're currently unsupported + """ + isWithholdingUnsupportedSelectedFields: Boolean +} + +""" +Represents a field-value edge for a JiraIssueSearchFieldSet. +""" +type JiraIssueSearchFieldSetEdge { + """ + The node at the the edge. + """ + node: JiraIssueSearchFieldSet + """ + The cursor to this edge + """ + cursor: String! +} + +""" +Represents a configurable field in Jira issue searches. +These fields can be used to update JiraIssueSearchViews or to directly query for issue fields. +This mirrors the concept of collapsed fields where all collapsible fields with the same `name` and `type` will be +collapsed into a single JiraIssueSearchFieldSet with `fieldSetId = name[type]`. +Non-collapsible and system fields cannot be collapsed but can still be represented as this type where `fieldSetId = fieldId`. +""" +type JiraIssueSearchFieldSet { + """ + The identifer of the field config set e.g. `assignee`, `reporter`, `checkbox_cf[Checkboxes]`. + """ + fieldSetId: String + """ + The user-friendly name for a JiraIssueSearchFieldSet, to be displayed in the UI. + """ + displayName: String + """ + The field-type of the current field set. + E.g. `Short Text`, `Number`, `Version Picker`, `Team`. + Important note: This information only exists for collapsed fields. + """ + type: String + """ + The jqlTerm for the current field config set. + E.g. `component`, `fixVersion` + """ + jqlTerm: String + """ + Determines whether or not the current field config set is sortable. + """ + isSortable: Boolean + """ + Tracks whether or not the current field config set has been selected. + """ + isSelected: Boolean +} + +""" +The input used for an issue search. +The issue search will either rely on the specified JQL or the specified filter's underlying JQL. + +""" +input JiraIssueSearchInput { + jql: String + filterId: String +} + +""" +The options used for an issue search. +The issueKey determines the target page for search. +Do not provide pagination arguments alongside issueKey. + +""" +input JiraIssueSearchOptions { + issueKey: String +} + +""" +The possible errors that can occur during an issue search. +""" +union JiraIssueSearchError = JiraInvalidJqlError | JiraInvalidSyntaxError + +""" +The representation for an invalid JQL error. +E.g. 'project = TMP' where 'TMP' has been deleted. +""" +type JiraInvalidJqlError { + """ + A list of JQL validation messages. + """ + messages: [String] +} + +""" +The representation for JQL syntax error. +E.g. 'project asdf = TMP'. +""" +type JiraInvalidSyntaxError { + """ + The specific error message. + """ + message: String + """ + The error type of this particular syntax error. + """ + errorType: JiraJqlSyntaxError + """ + The line of the JQL where the JQL syntax error occurred. + """ + line: Int + """ + The column of the JQL where the JQL syntax error occurred. + """ + column: Int +} + +enum JiraJqlSyntaxError { + RESERVED_WORD, + ILLEGAL_ESCAPE, + UNFINISHED_STRING, + ILLEGAL_CHARACTER, + RESERVED_CHARACTER, + UNKNOWN, + ILLEGAL_NUMBER, + EMPTY_FIELD, + EMPTY_FUNCTION, + MISSING_FIELD_NAME, + NO_ORDER, + UNEXPECTED_TEXT, + NO_OPERATOR, + BAD_FIELD_ID, + BAD_PROPERTY_ID, + BAD_FUNCTION_ARGUMENT, + EMPTY_FUNCTION_ARGUMENT, + MISSING_LOGICAL_OPERATOR, + BAD_OPERATOR, + PREDICATE_UNSUPPORTED, + OPERAND_UNSUPPORTED +}# Copied over from jira-project, will extend this type after deprecating rest bridge project + +""" +Represents an Issue type, e.g. story, task, bug. +""" +type JiraIssueType implements Node { + """ + Global identifier of the Issue type. + """ + id: ID! + """ + This is the internal id of the IssueType. + """ + issueTypeId: String + """ + Name of the Issue type. + """ + name: String! + """ + Description of the Issue type. + """ + description: String + """ + Avatar of the Issue type. + """ + avatar: JiraAvatar + """ + The IssueType hierarchy level + """ + hierarchy: JiraIssueTypeHierarchyLevel +} + +""" +The connection type for JiraIssueType. +""" +type JiraIssueTypeConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraIssueTypeEdge] +} + +""" +An edge in a JiraCommentConnection connection. +""" +type JiraIssueTypeEdge { + """ + The node at the the edge. + """ + node: JiraIssueType + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The Jira IssueType hierarchy level. +Hierarchy levels represent Issue parent-child relationships using an integer scale. +""" +type JiraIssueTypeHierarchyLevel { + """ + The global hierarchy level of the IssueType. + E.g. -1 for the subtask level, 0 for the base level, 1 for the epic level. + """ + level: Int + """ + The name of the IssueType hierarchy level. + """ + name: String +} +extend type JiraQuery { + """ + Returns an Issue by the Issue Key and Jira instance Cloud ID. + """ + issueByKey ( + key: String! + cloudId: ID! + ): JiraIssue + + """ + Returns an Issue by the Issue ID and Jira instance Cloud ID. + """ + issueById ( + id: ID! + ): JiraIssue + + """ + Returns an Issue by the issue ID (ARI). + Prefer this over issueByKey/issueById as the latter are still experimental. + """ + issue( + id: ID + ): JiraIssue + + """ + Returns Issues by the Issue ID. + At first input and output sizes are limited to 1 per API call. + Once the bulk API is implemented, input and output sizes will be limited to 50 per API call. + The server will return an error if the limit is exceeded. + """ + issuesById ( + ids: [ID!]! + ): [JiraIssue] + + """ + Returns Screen Id by the Issue ID. + """ + screenIdByIssueId( + issueId: ID! + ): Long @deprecated(reason: "The screen concept has been deprecated, and is only used for legacy reasons.") + + """ + Returns Screen Id by the Issue Key. + """ + screenIdByIssueKey ( + issueKey: String! + ): Long @deprecated(reason: "The screen concept has been deprecated, and is only used for legacy reasons.") + + """ + Returns comments by the Issue ID and the Comment ID. + At first input and output sizes are limited to 1 per API call. + Once the bulk API is implemented, input and output sizes will be limited to 50 per API call. + The server will return an error if the limit is exceeded. + """ + commentsById ( + input: [JiraCommentByIdInput!]! + ): [JiraComment] + + """ + The id of the tenant's epic link field. + """ + epicLinkFieldKey: String @deprecated(reason: "A temp attribute before issue creation modal supports unified parent") +}extend type JiraQuery { + """ + Retrieves application properties for the given instance. + + Returns an array containing application properties for each of the provided keys. If a matching application property + cannot be found, then no entry is added to the array for that key. + + A maximum of 50 keys can be provided. If the limit is exceeded then then an error may be returned. + """ + applicationPropertiesByKey(cloudId: ID!, keys: [String!]!): [JiraApplicationProperty!] +} + +""" +Jira application properties is effectively a key/value store scoped to a Jira instance. A JiraApplicationProperty +represents one of these key/value pairs, along with associated metadata about the property. +""" +type JiraApplicationProperty implements Node { + """ + Globally unique identifier + """ + id: ID!, + + """ + The unique key of the application property + """ + key: String!, + + """ + Although all application properties are stored as strings, they notionally have a type (e.g. boolean, int, enum, + string). The type can be anything (for example, there is even a colour type), and there may be associated validation + on the server based on the property's type. + """ + type: String!, + + """ + The value of the application property, encoded as a string. If no value is stored the default value will + be returned. + """ + value: String!, + + """ + The default value which will be returned if there is no value stored. This might be useful for UIs which allow a + user to 'reset' an application property to the default value. + """ + defaultValue: String!, + + """ + The human readable name for the application property. If no human readable name has been defined then the key will + be returned. + """ + name: String!, + + """ + The human readable description for the application property + """ + description: String, + + """ + Example is mostly used for application properties which store some sort of format pattern (e.g. date formats). + Example will contain an example string formatted according to the format stored in the property. + """ + example: String, + + """ + If the type is 'enum', then allowedValues may optionally contain a list of values which are valid for this property. + Otherwise the value will be null. + """ + allowedValues: [String!], + + """ + True if the user is allowed to edit the property, false otherwise + """ + isEditable: Boolean! +} + +extend type JiraMutation { + """ + Sets application properties for the given instance. + + Takes a list of key/value pairs to be updated, and returns a summary of the mutation result. + """ + setApplicationProperties(cloudId: ID!, input: [JiraSetApplicationPropertyInput!]!): JiraSetApplicationPropertiesPayload +} + +""" +The key of the property you want to update, and the new value you want to set it to +""" +input JiraSetApplicationPropertyInput { + key: String!, + value: String! +} + +type JiraSetApplicationPropertiesPayload implements Payload { + """ + True if the mutation was successfully applied. False if the mutation was either partially successful or if the + mutation failed completely. + """ + success: Boolean!, + + """ + A list of errors which encountered during the mutation + """ + errors: [MutationError!], + + """ + A list of application properties which were successfully updated + """ + applicationProperties: [JiraApplicationProperty!]! +} +type JiraQuery { + "Empty types are not allowed in schema language, even if they are later extended" + _empty: String +} + +type Mutation { + """ + this field is added to enable self governed onboarding of Jira GraphQL types to AGG + see https://hello.atlassian.net/wiki/spaces/PSRV/pages/1010287708/Announcing+self+governed+APIs for more details + """ + jira: JiraMutation +} + +type JiraMutation { + "Empty types are not allowed in schema language, even if they are later extended" + _empty: String +} +extend type JiraQuery { + """ + Grabs jira entities that have been favourited, filtered by type. + """ + favourites( + cloudId: ID!, + filter: JiraFavouriteFilter!, + first: Int, + after: String, + last: Int, + before: String + ): JiraFavouriteConnection! +} + +type JiraFavouriteConnection { + edges: [JiraFavouriteEdge] + pageInfo: PageInfo! +} + +type JiraFavouriteEdge { + node: JiraFavourite + cursor: String! +} + +input JiraFavouriteFilter { + """The Jira entity type to get.""" + type: JiraFavouriteType! +} + +"""Currently supported favouritable entities in Jira.""" +enum JiraFavouriteType { + PROJECT +} + +union JiraFavourite = JiraProject +extend type JiraQuery { + """ + A parent field to get information about a given Jira filter. The id provided must be in ARI format. + """ + filter (id: ID!): JiraFilter + + """ + A field to get a list of favourited filters. + """ + favouriteFilters ( + """ + The cloud id of the tenant. + """ + cloudId: ID! + + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraFilterConnection + + """ + A field to get a list of system filters. Accepts `isFavourite` argument to return list of favourited system filters or to exclude favourited + filters from the list. + """ + systemFilters ( + """ + The cloud id of the tenant. + """ + cloudId: ID! + + """ + Whether the filters are favourited by the user. + """ + isFavourite: Boolean, + + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraSystemFilterConnection +} + +""" +JiraFilterResult can resolve to a system filter, custom filter or a QueryError when filter does not exist or the user has no permission to access the filter. +""" +union JiraFilterResult = JiraCustomFilter | JiraSystemFilter | QueryError + +""" +A generic interface for Jira Filter. +""" +interface JiraFilter implements Node { + """ + An ARI value in the format `ari:cloud:jira:{siteId}:filter/activation/{activationId}/{filterId}`that encodes the filterId. + """ + id: ID! + + """ + A tenant local filterId. This value is used for interoperability with REST APIs (eg vendors). + """ + filterId: String! + + """ + JQL associated with the filter. + """ + jql: String! + + """ + A string representing the filter name. + """ + name: String! + + """ + Determines whether the filter is currently starred by the user viewing the filter. + """ + isFavourite: Boolean +} + +""" +Represents a pre-defined filter in Jira. +""" +type JiraSystemFilter implements JiraFilter & Node { + """ + An ARI value in the format `ari:cloud:jira:{siteId}:filter/activation/{activationId}/{filterId}`that encodes the filterId. + """ + id: ID! + + """ + A tenant local filterId. For system filters the ID is in the range from -9 to -1. This value is used for interoperability with REST APIs (eg vendors). + """ + filterId: String! + + """ + JQL associated with the filter. + """ + jql: String! + + """ + A string representing the filter name. + """ + name: String! + + """ + Determines whether the filter is currently starred by the user viewing the filter. + """ + isFavourite: Boolean +} + +""" +Represents a user generated custom filter. +""" +type JiraCustomFilter implements JiraFilter & Node { + """ + An ARI value in the format `ari:cloud:jira:{siteId}:filter/activation/{activationId}/{filterId}`that encodes the filterId. + """ + id: ID! + + """ + A tenant local filterId. This value is used for interoperability with REST APIs (eg vendors). + """ + filterId: String! + + """ + JQL associated with the filter. + """ + jql: String! + + """ + The user that owns the filter. + """ + ownerAccountId: String + + """ + A string representing the filter name. + """ + name: String! + + """ + A string containing filter description. + """ + description: String + + """ + Determines whether the filter is currently starred by the user viewing the filter. + """ + isFavourite: Boolean + + """ + Determines whether the user has permissions to edit the filter + """ + isEditable: Boolean + + """ + Retrieves a connection of email subscriptions for the filter. + """ + emailSubscriptions( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraFilterEmailSubscriptionConnection + + """ + Retrieves a connection of share grants for the filter. Share grants represent collections of users who can access the filter. + """ + shareGrants( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraShareableEntityShareGrantConnection + + """ + Retrieves a connection of edit grants for the filter. Edit grants represent collections of users who can edit the filter. + """ + editGrants( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraShareableEntityEditGrantConnection +} + +""" +Represents connection of JiraFilters +""" +type JiraFilterConnection { + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + + """ + The data for the edges in the current page. + """ + edges: [JiraFilterEdge] +} + +""" +Represents a filter edge +""" +type JiraFilterEdge { + """ + The node at the edge + """ + node: JiraFilter + + """ + The cursor to this edge + """ + cursor: String! +} + +""" +Represents connection of JiraSystemFilters +""" +type JiraSystemFilterConnection { + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + + """ + The data for the edges in the current page. + """ + edges: [JiraSystemFilterEdge] +} + +""" +Represents a system filter edge +""" +type JiraSystemFilterEdge { + """ + The node at the edge + """ + node: JiraSystemFilter + + """ + The cursor to this edge + """ + cursor: String! +} + +""" +Represents an email subscription to a Jira Filter +""" +type JiraFilterEmailSubscription implements Node { + """ + ARI of the email subscription. + """ + id: ID! + + """ + User that created the subscription. If no group is specified then the subscription is personal for this user. + """ + userAccountId: String + + """ + The group subscribed to the filter. + """ + group: JiraGroup +} + +""" +Represents a connection of JiraFilterEmailSubscriptions. +""" +type JiraFilterEmailSubscriptionConnection { + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + + """ + The data for the edges in the current page. + """ + edges: [JiraFilterEmailSubscriptionEdge] +} + +""" +Represents a filter email subscription edge +""" +type JiraFilterEmailSubscriptionEdge { + """ + The node at the edge + """ + node: JiraFilterEmailSubscription + + """ + The cursor to this edge + """ + cursor: String! +} + +extend type JiraMutation { + jiraFilterMutation: JiraFilterMutation +} + +""" +Mutations for JiraFilters +""" +type JiraFilterMutation { + """ + Mutation to create JiraCustomFilter + """ + createJiraCustomFilter(cloudId: ID!, input: JiraCreateCustomFilterInput!): JiraCreateCustomFilterPayload + """ + Mutation to update JiraCustomFilter details + """ + updateJiraCustomFilterDetails(input: JiraUpdateCustomFilterDetailsInput!): JiraUpdateCustomFilterPayload + """ + Mutation to update JiraCustomFilter JQL + """ + updateJiraCustomFilterJql(input: JiraUpdateCustomFilterJqlInput!): JiraUpdateCustomFilterJqlPayload +} + + +""" +The payload returned after creating a JiraCustomFilter. +""" +type JiraCreateCustomFilterPayload implements Payload { + """ + Was this mutation successful + """ + success: Boolean! + """ + A list of errors if the mutation was not successful + """ + errors: [MutationError!] + """ + JiraFilter created or updated by the mutation + """ + filter: JiraCustomFilter +} + + +""" +The payload returned after updating a JiraCustomFilter. +""" +type JiraUpdateCustomFilterPayload implements Payload { + """ + Was this mutation successful + """ + success: Boolean! + """ + A list of errors if the mutation was not successful + """ + errors: [MutationError!] + """ + JiraFilter created or updated by the mutation + """ + filter: JiraCustomFilter +} + +""" +The payload returned after updating a JiraCustomFilter's JQL. +""" +type JiraUpdateCustomFilterJqlPayload implements Payload { + """ + Was this mutation successful + """ + success: Boolean! + """ + A list of errors if the mutation was not successful + """ + errors: [MutationError!] + """ + JiraFilter updated by the mutation + """ + filter: JiraCustomFilter +} + +""" +Error extension for filter name validation errors. +""" +type JiraFilterNameMutationErrorExtension implements MutationErrorExtension { + """ + A numerical code (example: HTTP status code) representing the error category + For example: 412 for operation preconditions failure. + """ + statusCode: Int + """ + Application specific error type in human readable format. + For example: FilterNameError + """ + errorType: String +} + +""" +Input for creating a JiraCustomFilter. +""" +input JiraCreateCustomFilterInput { + """ + JQL associated with the filter + """ + jql: String! + """ + A string representing the name of the filter + """ + name: String! + """ + A string containing filter description + """ + description: String + """ + Determines whether the filter is currently starred by the user viewing the filter + """ + isFavourite: Boolean! + """ + The list of share grants for the filter. Share Grants represent different ways that users have been granted access to the filter. + Empty array represents private and null represents default share grant. + """ + shareGrants: [JiraShareableEntityShareGrantInput]! + """ + The list of edit grants for the filter. Edit Grants represent different ways that users have been granted access to edit the filter. + Empty array represents private edit grant. + """ + editGrants: [JiraShareableEntityEditGrantInput]! +} + +""" +Input for updating a JiraCustomFilter. +""" +input JiraUpdateCustomFilterDetailsInput { + """ + ARI of the filter + """ + id: ID! + """ + A string representing the name of the filter + """ + name: String! + """ + A string containing filter description + """ + description: String + """ + The list of share grants for the filter. Share Grants represent different ways that users have been granted access to the filter. + Empty array represents private share grant. + """ + shareGrants: [JiraShareableEntityShareGrantInput]! + """ + The list of edit grants for the filter. Edit Grants represent different ways that users have been granted access to edit the filter. + Empty array represents private edit grant. + """ + editGrants: [JiraShareableEntityEditGrantInput]! +} + +""" +Input for updating the JQL of a JiraCustomFilter. +""" +input JiraUpdateCustomFilterJqlInput { + """ + An ARI-format value that encodes the filterId. + """ + id: ID! + """ + JQL associated with the filter + """ + jql: String! +} +""" +The grant types to share or edit ShareableEntities. +""" +enum JiraShareableEntityGrant { + """ + The anonymous access represents the public access without logging in. + """ + ANONYMOUS_ACCESS + + """ + Any user who has the product access. + """ + ANY_LOGGEDIN_USER_APPLICATION_ROLE + + """ + A group is a collection of users who can be given access together. + It represents group in the organization's user base. + """ + GROUP + + """ + A project or a role that user can play in a project. + """ + PROJECT + + """ + A project or a role that user can play in a project. + """ + PROJECT_ROLE + + """ + Indicates that the user does not have access to the project + the members of which have been granted permission. + """ + PROJECT_UNKNOWN + + """ + An individual user who can be given the access to work on one or more projects. + """ + USER + +} + +""" +Union of grant types to share entities. +""" +union JiraShareableEntityShareGrant = JiraShareableEntityGroupGrant | JiraShareableEntityProjectRoleGrant | JiraShareableEntityProjectGrant | JiraShareableEntityAnonymousAccessGrant | JiraShareableEntityAnyLoggedInUserGrant | JiraShareableEntityUnknownProjectGrant + +""" +Union of grant types to edit entities. +""" +union JiraShareableEntityEditGrant = JiraShareableEntityGroupGrant | JiraShareableEntityProjectRoleGrant | JiraShareableEntityUserGrant | JiraShareableEntityProjectGrant | JiraShareableEntityUnknownProjectGrant + +""" +GROUP grant type. +""" +type JiraShareableEntityGroupGrant { + """ + 'GROUP' type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant + + """ + Jira Group, members of which will be granted permission. + """ + group: JiraGroup +} + +""" +PROJECT grant type. +""" +type JiraShareableEntityProjectGrant { + """ + 'PROJECT_ROLE' type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant + + """ + Jira Project, members of which will have the permission. + """ + project: JiraProject +} + +""" +PROJECT_ROLE grant type. +""" +type JiraShareableEntityProjectRoleGrant { + """ + 'PROJECT_ROLE' type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant + + """ + Jira Project, members of which will have the permission. + """ + project: JiraProject + + """ + Users with the specified Jira Project Role in the Jira Project will have have the permission. + If no role is specified then all members of the project have the permisison. + """ + role: JiraRole +} + +""" +ANONYMOUS_ACCESS grant type. +""" +type JiraShareableEntityAnonymousAccessGrant { + """ + 'ANONYMOUS_ACCESS' type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant +} + +""" +ANY_LOGGEDIN_USER_APPLICATION_ROLE grant type. +""" +type JiraShareableEntityAnyLoggedInUserGrant { + """ + 'ANY_LOGGEDIN_USER_APPLICATION_ROLE' type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant +} + +""" +USER grant type +""" +type JiraShareableEntityUserGrant { + """ + 'USER' grant type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant + + """ + User that is granted the permission + """ + userAccountId: String +} + +""" +PROJECT_UNKNOWN grant type +""" +type JiraShareableEntityUnknownProjectGrant { + """ + PROJECT_UNKNOWN grant type of Jira ShareableEntity Grant Types. + """ + type: JiraShareableEntityGrant +} + +""" +Represents a connection of share permissions for a shared entity. +""" +type JiraShareableEntityShareGrantConnection { + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + + """ + The data for the edges in the current page. + """ + edges: [JiraShareableEntityShareGrantEdge] +} + +""" +Represents a share permission edge for a shared entity. +""" +type JiraShareableEntityShareGrantEdge { + """ + The node at the the edge. + """ + node: JiraShareableEntityShareGrant + + """ + The cursor to this edge. + """ + cursor: String +} + +""" +Represents a connection of edit permissions for a shared entity. +""" +type JiraShareableEntityEditGrantConnection { + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + + """ + The data for the edges in the current page. + """ + edges: [JiraShareableEntityEditGrantEdge] +} + +""" +Represents an edit permission edge for a shared entity. +""" +type JiraShareableEntityEditGrantEdge { + """ + The node at the the edge. + """ + node: JiraShareableEntityEditGrant + + """ + The cursor to this edge. + """ + cursor: String +} + +# INPUTS + +""" +Input type for JiraShareableEntityShareGrants. +""" +input JiraShareableEntityShareGrantInput { + """ + User group that will be granted permission. + """ + group: JiraShareableEntityGroupGrantInput + + """ + Members of the specified project will be granted permission. + """ + project: JiraShareableEntityProjectGrantInput + + """ + Users with the specified role in the project will be granted permission. + """ + projectRole: JiraShareableEntityProjectRoleGrantInput + """ + All users with access to the instance and anonymous users will be granted permission. + """ + anonymousAccess: JiraShareableEntityAnonymousAccessGrantInput + """ + All users with access to the instance will be granted permission. + """ + anyLoggedInUser: JiraShareableEntityAnyLoggedInUserGrantInput +} + +""" +Input type for JiraShareableEntityEditGrants. +""" +input JiraShareableEntityEditGrantInput { + """ + User group that will be granted permission. + """ + group: JiraShareableEntityGroupGrantInput + + """ + Members of the specifid project will be granted permission. + """ + project: JiraShareableEntityProjectGrantInput + + """ + Users with the specified role in the project will be granted permission. + """ + projectRole: JiraShareableEntityProjectRoleGrantInput + + """ + User that will be granted permission. + """ + user: JiraShareableEntityUserGrantInput +} + +""" +Input for the group that will be granted permission. +""" +input JiraShareableEntityGroupGrantInput { + """ + JiraShareableEntityGrant ARI. + """ + id: ID + + """ + Id of the user group + """ + groupId: ID! +} + +""" +Input for the project ID, members of which will be granted permission. +""" +input JiraShareableEntityProjectGrantInput { + """ + JiraShareableEntityGrant ARI. + """ + id: ID + """ + ARI of the project in the format `ari:cloud:jira:{siteId}:project/{projectId}`. + """ + projectId: ID! +} + +""" +Input for the id of the role. +Users with the specified role will be granted permission. +""" +input JiraShareableEntityProjectRoleGrantInput { + """ + JiraShareableEntityGrant ARI. + """ + id: ID + """ + ARI of the project in the format `ari:cloud:jira:{siteId}:project/{projectId}`. + """ + projectId: ID! + """ + Tenant local roleId. + """ + projectRoleId: Int! +} + +""" +Input for user that will be granted permission. +""" +input JiraShareableEntityUserGrantInput { + """ + JiraShareableEntityGrant ARI. + """ + id: ID + """ + ARI of the user in the form of ARI: ari:cloud:identity::user/{userId}. + """ + userId: ID! +} + +""" +Input for when the shareable entity is intended to be shared with all users on a Jira instance +and anonymous users. +""" +input JiraShareableEntityAnonymousAccessGrantInput { + """ + JiraShareableEntityGrant ARI. + """ + id: ID +} + +""" +Input for when the shareable entity is intended to be shared with all users on a Jira instance +and NOT anonymous users. +""" +input JiraShareableEntityAnyLoggedInUserGrantInput { + """ + JiraShareableEntityGrant ARI. + """ + id: ID +} +extend type JiraQuery { + """ + A parent field to get information about jql related aspects from a given jira instance. + """ + jqlBuilder(cloudId: ID!): JiraJqlBuilder +} + +""" +Encapsulates queries and fields necessary to power the JQL builder. + +It also exposes generic JQL capabilities that can be leveraged to power other experiences. +""" +type JiraJqlBuilder { + """ + A list of available JQL functions. + """ + functions: [JiraJqlFunction!]! + + """ + The last used JQL builder search mode. + + This can either be the Basic or JQL search mode. + """ + lastUsedMode: JiraJqlBuilderMode + + """ + Hydrates the JQL fields and field-values of a given JQL query. + """ + hydrateJqlQuery(query: String): JiraJqlHydratedQueryResult + """ + Hydrates the JQL fields and field-values of a filter corresponding to the provided filter ID. + + The id provided MUST be in ARI format. + + This query will error if the id parameter is not in ARI format, does not pass validation or does not correspond to a JiraFilter. + """ + hydrateJqlQueryForFilter(id: ID!): JiraJqlHydratedQueryResult + + """ + Retrieves a connection of searchable Jira JQL fields. + + In a given JQL, fields will precede operators and operators precede field-values/ functions. + + E.g. `${FIELD} ${OPERATOR} ${FUNCTION}()` => `Assignee = currentUser()` + """ + fields( + """ + The JQL query that will be parsed and used to form a search context. + + Only the Jira fields that are scoped to this search context will be returned. + + E.g. `Project IN (KEY1, KEY2) AND issueType = Task`. + """ + jqlContext: String + """ + Only the fields that contain this searchString in their displayName will be returned. + """ + searchString: String + """ + Only the fields that support the provided JqlClauseType will be returned. + """ + forClause: JiraJqlClauseType + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified the cursor is assumed to be the beginning. + """ + after: String + ): JiraJqlFieldConnectionResult + + """ + Retrieves a connection of Jira fields recently used in JQL searches. + """ + recentFields( + """ + The JQL query that will be parsed and used to form a search context. + + Only the Jira fields that are scoped to this search context will be returned. + + E.g. `Project IN (KEY1, KEY2) AND issueType = Task`. + """ + jqlContext: String + """ + Only the Jira fields that support the provided forClause will be returned. + """ + forClause: JiraJqlClauseType + """ + The number of items after the cursor to be returned. Either `first` or `last` is required. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. Either `first` or `last` is required. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlFieldConnectionResult + + """ + Retrieves a connection of field-values for a specified Jira Field. + + E.g. A given Jira checkbox field may have the following field-values: `Option 1`, `Option 2` and `Option 3`. + """ + fieldValues( + """ + The JQL query that will be parsed and used to form a search context. + + Only the Jira fields that are scoped to this search context will be returned. + + E.g. `Project IN (KEY1, KEY2) AND issueType = Task` + """ + jqlContext: String + """ + An identifier that a client should use in a JQL query when it’s referring to a field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + Only the Jira field-values with their diplayName matching this searchString will be retrieved. + """ + searchString: String + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified the cursor is assumed to be the beginning. + """ + after: String + ): JiraJqlFieldValueConnection + + """ + Retrieves a connection of users recently used in Jira user fields. + """ + recentlyUsedUsers( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlUserFieldValueConnection + + """ + Retrieves a connection of suggested groups. + + Groups are suggested when the current user is a member. + """ + suggestedGroups( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlGroupFieldValueConnection + + """ + Retrieves a connection of projects that have recently been viewed by the current user. + """ + recentlyUsedProjects( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlProjectFieldValueConnection + + """ + Retrieves a connection of sprints that have recently been viewed by the current user. + """ + recentlyUsedSprints( + """ + The JQL query that will be parsed and used to form a search context. + + Only the Jira fields that are scoped to this search context will be returned. + + E.g. `Project IN (KEY1, KEY2) AND issueType = Task` + """ + jqlContext: String + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlSprintFieldValueConnection + + """ + Retrieves the field-values for the Jira issueType field. + """ + issueTypes(jqlContext: String): JiraJqlIssueTypes + + """ + Retrieves the field-values for the Jira cascading options field. + """ + cascadingSelectOptions( + """ + The number of items to be sliced away to target between the after and before cursors. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + The JQL query that will be parsed and used to form a search context. + + Only the Jira fields that are scoped to this search context will be returned. + + E.g. `Project IN (KEY1, KEY2) AND issueType = Task` + """ + jqlContext: String + """ + An identifier that a client should use in a JQL query when it’s referring to an instance of a Jira cascading option field. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + Only the Jira field-values with their diplayName matching this searchString will be retrieved. + """ + searchString: String + """ + Only the cascading options matching this filter will be retrieved. + """ + filter: JiraCascadingSelectOptionsFilter! + ): JiraJqlOptionFieldValueConnection + + """ + Retrieves the field-values for the Jira version field. + """ + versions( + """ + The JQL query that will be parsed and used to form a search context. + + Only the Jira fields that are scoped to this search context will be returned. + + E.g. `Project IN (KEY1, KEY2) AND issueType = Task`. + """ + jqlContext: String, + """ + An identifier that a client should use in a JQL query when it’s referring to an instance of a Jira version field. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + ): JiraJqlVersions +} + +""" +A function in JQL appears as a word followed by parentheses, which may contain one or more explicit values or Jira fields. + +In a clause, a function is preceded by an operator, which in turn is preceded by a field. + +A function performs a calculation on either specific Jira data or the function's content in parentheses, +such that only true results are retrieved by the function, and then again by the clause in which the function is used. + +E.g. `approved()`, `currentUser()`, `endOfMonth()` etc. +""" +type JiraJqlFunction { + """ + The user-friendly name for the function, to be displayed in the UI. + """ + displayName: String + """ + A JQL-function safe encoded name. This value will not be encoded if the displayName is already safe. + """ + value: String + """ + Indicates whether or not the function is meant to be used with IN or NOT IN operators, that is, + if the function should be viewed as returning a list. + + The method should return false when it is to be used with the other relational operators (e.g. =, !=, <, >, ...) + that only work with single values. + """ + isList: Boolean + """ + The data types that this function handles and creates values for. + + This allows consumers to infer information on the JiraJqlField type such as which functions are supported. + """ + dataTypes: [String!]! +} + +""" +The modes the JQL builder can be displayed and used in. +""" +enum JiraJqlBuilderMode { + """ + The JQL mode, allows queries to be built and executed via the JQL advanced editor. + + This mode allows users to manually type and construct complex JQL queries. + """ + JQL + """ + The basic mode, allows queries to be built and executed via the JQL basic editor. + + This mode allows users to easily construct JQL queries by interacting with the UI. + """ + BASIC +} + +""" +A union of a Jira JQL hydrated query and a GraphQL query error. +""" +union JiraJqlHydratedQueryResult = JiraJqlHydratedQuery | QueryError + +""" +Represents a JQL query with hydrated fields and field-values. +""" +type JiraJqlHydratedQuery { + """ + The JQL query to be hydrated. + """ + jql: String + """ + A list of hydrated fields from the provided JQL. + """ + fields: [JiraJqlQueryHydratedFieldResult!]! +} + +""" +A union of a JQL query hydrated field and a GraphQL query error. +""" +union JiraJqlQueryHydratedFieldResult = + JiraJqlQueryHydratedField + | JiraJqlQueryHydratedError + +""" +Represents an error for a JQL query hydration. +""" +type JiraJqlQueryHydratedError { + """ + An identifier for the hydrated Jira JQL field where the error occurred. + """ + jqlTerm: String! + """ + The error that occurred whilst hydrating the Jira JQL field. + """ + error: QueryError +} + +""" +Represents a hydrated field for a JQL query. +""" +type JiraJqlQueryHydratedField { + """ + An identifier for the hydrated Jira JQL field. + """ + jqlTerm: String! + """ + The Jira JQL field associated with the hydrated field. + """ + field: JiraJqlField! + """ + The hydrated value results. + """ + values: [JiraJqlQueryHydratedValueResult]! +} + +""" +A union of a JQL query hydrated field-value and a GraphQL query error. +""" +union JiraJqlQueryHydratedValueResult = + JiraJqlQueryHydratedValue + | JiraJqlQueryHydratedError + +""" +Represents a hydrated field-value for a given field in the JQL query. +""" +type JiraJqlQueryHydratedValue { + """ + An identifier for the hydrated Jira JQL field value. + """ + jqlTerm: String! + """ + The hydrated field values. + """ + values: [JiraJqlFieldValue]! +} + +""" +A union of a Jira JQL field connection and a GraphQL query error. +""" +union JiraJqlFieldConnectionResult = JiraJqlFieldConnection | QueryError + +""" +Represents a connection of Jira JQL fields. +""" +type JiraJqlFieldConnection { + """ + The total number of JiraJqlFields matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlFieldEdge] +} + +""" +Represents a Jira JQL field edge. +""" +type JiraJqlFieldEdge { + """ + The node at the edge. + """ + node: JiraJqlField + """ + The cursor to this edge. + """ + cursor: String! +} + + +""" +The representation of a Jira field within the context of the Jira Query Language. +""" +type JiraJqlField { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira JQL field. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: ID! + """ + The user-friendly name for the current field, to be displayed in the UI. + """ + displayName: String + """ + The data types handled by the current field. + These can be used to identify which JQL functions are supported. + """ + dataTypes: [String] + """ + The JQL clause types that can be used with this field. + """ + allowedClauseTypes: [JiraJqlClauseType!]! + """ + The JQL operators that can be used with this field. + """ + operators: [JiraJqlOperator!]! + """ + Defines how a field should be represented in the basic search mode of the JQL builder. + """ + searchTemplate: JiraJqlSearchTemplate + """ + Defines how the field-values should be shown for a field in the JQL-Builder's JQL mode. + """ + autoCompleteTemplate: JiraJqlAutocompleteType + """ + The field-type of the current field. + E.g. `Short Text`, `Number`, `Version Picker`, `Team` etc. + Important note: This information only exists for collapsed fields. + """ + jqlFieldType: JiraJqlFieldType + """ + Determines whether or not the current field should be accessible in the current search context. + """ + shouldShowInContext: Boolean +} + +""" +The types of JQL clauses supported by Jira. +""" +enum JiraJqlClauseType { + """ + This denotes both WHERE and ORDER_BY. + """ + ANY + """ + This corresponds to jql fields used as filter criteria of Jira issues. + """ + WHERE + """ + This corresponds to fields used to sort Jira Issues. + """ + ORDER_BY +} + +""" +The types of JQL operators supported by Jira. + +An operator in JQL is one or more symbols or words,which compares the value of a field on its left with one or more values (or functions) on its right, +such that only true results are retrieved by the clause. + +For more information on JQL operators please visit: https://support.atlassian.com/jira-software-cloud/docs/advanced-search-reference-jql-operators. +""" +enum JiraJqlOperator { + """ + The `=` operator is used to search for issues where the value of the specified field exactly matches the specified value. + """ + EQUALS + """ + The `!=` operator is used to search for issues where the value of the specified field does not match the specified value. + """ + NOT_EQUALS + """ + The `IN` operator is used to search for issues where the value of the specified field is one of multiple specified values. + """ + IN + """ + The `NOT IN` operator is used to search for issues where the value of the specified field is not one of multiple specified values. + """ + NOT_IN + """ + The `IS` operator can only be used with EMPTY or NULL. That is, it is used to search for issues where the specified field has no value. + """ + IS + """ + The `IS NOT` operator can only be used with EMPTY or NULL. That is, it is used to search for issues where the specified field has a value. + """ + IS_NOT + """ + The `<` operator is used to search for issues where the value of the specified field is less than the specified value. + """ + LESS_THAN + """ + The `<=` operator is used to search for issues where the value of the specified field is less than or equal to than the specified value. + """ + LESS_THAN_OR_EQUAL + """ + The `>` operator is used to search for issues where the value of the specified field is greater than the specified value. + """ + GREATER_THAN + """ + The `>=` operator is used to search for issues where the value of the specified field is greater than or equal to the specified value. + """ + GREATER_THAN_OR_EQUAL + """ + The `CHANGED` operator is used to find issues that have a value that had changed for the specified field. + """ + CONTAINS + """ + The `!~` operator is used to search for issues where the value of the specified field is not a "fuzzy" match for the specified value. + """ + NOT_CONTAINS + """ + The `WAS NOT IN` operator is used to search for issues where the value of the specified field has never been one of multiple specified values. + """ + WAS_NOT_IN + """ + The `CHANGED` operator is used to find issues that have a value that had changed for the specified field. + """ + CHANGED + """ + The `WAS IN` operator is used to find issues that currently have or previously had any of multiple specified values for the specified field. + """ + WAS_IN + """ + The `WAS` operator is used to find issues that currently have or previously had the specified value for the specified field. + """ + WAS + """ + The `WAS NOT` operator is used to find issues that have never had the specified value for the specified field. + """ + WAS_NOT +} + +""" +The representation of a Jira field in the basic search mode of the JQL builder. +""" +type JiraJqlSearchTemplate { + key: String +} + +""" +The autocomplete types available for Jira fields in the context of the Jira Query Language. + +This enum also describes which fields have field-value support from this schema. +""" +enum JiraJqlAutocompleteType { + """ + No autocomplete support. + """ + NONE + """ + The Jira component field JQL autocomplete type. + """ + COMPONENT + """ + The Jira group field JQL autocomplete type. + """ + GROUP + """ + The Jira issue field JQL autocomplete type. + """ + ISSUE + """ + The Jira issue field type JQL autocomplete type. + """ + ISSUETYPE + """ + The Jira priority field JQL autocomplete type. + """ + PRIORITY + """ + The Jira project field JQL autocomplete type. + """ + PROJECT + """ + The Jira sprint field JQL autocomplete type. + """ + SPRINT + """ + The Jira status category field JQL autocomplete type. + """ + STATUSCATEGORY + """ + The Jira status field JQL autocomplete type. + """ + STATUS + """ + The Jira user field JQL autocomplete type. + """ + USER + """ + The Jira version field JQL autocomplete type. + """ + VERSION +} + +""" +The representation of a Jira JQL field-type in the context of the Jira Query Language. + +E.g. `Short Text`, `Number`, `Version Picker`, `Team` etc. + +Important note: This information only exists for collapsed fields. +""" +type JiraJqlFieldType { + """ + The non-translated name of the field type. + """ + jqlTerm: String! + """ + The translated name of the field type. + """ + displayName: String! +} + +""" +Represents a connection of field-values for a JQL field. +""" +type JiraJqlFieldValueConnection { + """ + The total number of JiraJqlFieldValues matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL field. +""" +type JiraJqlFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +A generic interface for JQL fields in Jira. +""" +interface JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira JQL field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a component JQL field value, to be displayed in the UI. + """ + displayName: String! +} + +""" +Represents a field-value for a JQL component field. +""" +type JiraJqlComponentFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira component field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a component JQL field value, to be displayed in the UI. + """ + displayName: String! +} + +""" +Represents a field-value for a JQL group field. +""" +type JiraJqlGroupFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira group field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ) + """ + jqlTerm: String! + """ + The user-friendly name for a group JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira group associated with this JQL field value. + """ + group: JiraGroup! +} + +""" +Represents a field-value for a JQL Issue field. +""" +type JiraJqlIssueFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for an issue JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira issue associated with this JQL field value. + """ + issue: JiraIssue! +} + +""" +Represents a field-value for a JQL issue type field. +""" +type JiraJqlIssueTypeFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira issue type field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for an issue type JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira issue types associated with this JQL field value. + """ + issueTypes: [JiraIssueType!]! +} + +""" +Represents a field-value for a JQL sprint field. +""" +type JiraJqlSprintFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira sprint field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a sprint JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira sprint associated with this JQL field value. + """ + sprint: JiraSprint! +} + +""" +Represents a field-value for a JQL priority field. +""" +type JiraJqlPriorityFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira priority field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a priority JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira property associated with this JQL field value. + """ + priority: JiraPriority! +} + +""" +Represents a field-value for a JQL option field. +""" +type JiraJqlOptionFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira option field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for an option JQL field value, to be displayed in the UI. + """ + displayName: String! +} + +""" +Represents a field-value for a JQL cascading option field. +""" +type JiraJqlCascadingOptionFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira cascading option field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a cascading option JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira JQL parent option associated with this JQL field value. + """ + parentOption: JiraJqlOptionFieldValue +} + +""" +Represents a field-value for a JQL status category field. +""" +type JiraJqlStatusCategoryFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira status category field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a status category JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira status category associated with this JQL field value. + """ + statusCategory: JiraStatusCategory! +} + +""" +Represents a field-value for a JQL status field. +""" +type JiraJqlStatusFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira status field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a status JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira status category associated with this JQL field value. + """ + statusCategory: JiraStatusCategory! +} + +""" +Represents a field-value for a JQL user field. +""" +type JiraJqlUserFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira user field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a user JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The user associated with this JQL field value. + """ + user: User! +} + +""" +Represents a field-value for a JQL resolution field. +""" +type JiraJqlResolutionFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira resolution field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a resolution JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira resolution associated with this JQL field value. + """ + resolution: JiraResolution +} + +""" +Represents a field-value for a JQL label field. +""" +type JiraJqlLabelFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira label field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a label JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira label associated with this JQL field value. + """ + label: JiraLabel +} + +""" +Represents a field-value for a JQL project field. +""" +type JiraJqlProjectFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira project field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a project JQL field value, to be displayed in the UI. + """ + displayName: String! + """ + The Jira project associated with this JQL field value. + """ + project: JiraProject! +} + +""" +Represents a field-value for a JQL version field. +""" +type JiraJqlVersionFieldValue implements JiraJqlFieldValue { + """ + An identifier that a client should use in a JQL query when it’s referring to a Jira version field-value. + + Important note: this jqlTerm could require proper escaping before placing it into a query (e.g. wrap it in "" ). + """ + jqlTerm: String! + """ + The user-friendly name for a version JQL field value, to be displayed in the UI. + """ + displayName: String! +} + +""" +Represents a connection of field-values for a JQL user field. +""" +type JiraJqlUserFieldValueConnection { + """ + The total number of JiraJqlUserFieldValues matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlUserFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL user field. +""" +type JiraJqlUserFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlUserFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents a connection of field-values for a JQL group field. +""" +type JiraJqlGroupFieldValueConnection { + """ + The total number of JiraJqlGroupFieldValues matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlGroupFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL group field. +""" +type JiraJqlGroupFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlGroupFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents a connection of field-values for a JQL project field. +""" +type JiraJqlProjectFieldValueConnection { + """ + The total number of JiraJqlProjectFieldValues matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlProjectFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL project field. +""" +type JiraJqlProjectFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlProjectFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Represents a connection of field-values for a JQL sprint field. +""" +type JiraJqlSprintFieldValueConnection { + """ + The total number of JiraJqlSprintFieldValues matching the criteria + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlSprintFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL sprint field. +""" +type JiraJqlSprintFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlSprintFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +A variation of the fieldValues query for retrieving specifically Jira issue type field-values. +""" +type JiraJqlIssueTypes { + """ + Retrieves top-level issue types that encapsulate all others. + + E.g. The `Epic` issue type in company-managed projects. + """ + aboveBaseLevel( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlIssueTypeFieldValueConnection + """ + Retrieves mid-level issue types. + + E.g. The `Bug`, `Story` and `Task` issue type in company-managed projects. + """ + baseLevel( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlIssueTypeFieldValueConnection + """ + Retrieves the lowest level issue types. + + E.g. The `Subtask` issue type in company-managed projects. + """ + belowBaseLevel( + """ + The number of items after the cursor to be returned, if not specified it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlIssueTypeFieldValueConnection +} + +""" +Represents a connection of field-values for a JQL issue type field. +""" +type JiraJqlIssueTypeFieldValueConnection { + """ + The total number of JiraJqlIssueTypeFieldValues matching the criteria + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlIssueTypeFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL issue type field. +""" +type JiraJqlIssueTypeFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlIssueTypeFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +An input filter used to specify the cascading options returned. +""" +input JiraCascadingSelectOptionsFilter { + """ + The type of cascading option to be returned. + """ + optionType: JiraCascadingSelectOptionType! + """ + Used for retrieving CHILD cascading options by specifying the PARENT cascading option's name. + + The parent name is case-sensitive and it will not be applied to non-child cascading options. + """ + parentOptionName: String +} + +""" +Represents a connection of field-values for a JQL option field. +""" +type JiraJqlOptionFieldValueConnection { + """ + The total number of JiraJqlOptionFieldValues matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlOptionFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL option field. +""" +type JiraJqlOptionFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlOptionFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Cascading options can either be a parent or a child - this enum captures this characteristic. + +E.g. If there is a parent cascading option named `P1`, it may or may not have +child cascading options named `C1` and `C2`. +- `P1` would be a `PARENT` enum +- `C1` and `C2` would be `CHILD` enums +""" +enum JiraCascadingSelectOptionType { + """ + Parent option only + """ + PARENT + """ + Child option only + """ + CHILD + """ + All options, regardless of whether they're a parent or child. + """ + ALL +} + +""" +A variation of the fieldValues query for retrieving specifically Jira version field-values. + +This type provides the capability to retrieve connections of released, unreleased and archived versions. + +Important note: that released and unreleased versions can be archived and vice versa. +""" +type JiraJqlVersions { + """ + Retrieves a connection of released versions. + """ + released( + """ + The number of items to be sliced away to target between the after and before cursors. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Determines whether or not archived versions are returned. By default it will be false. + """ + includeArchived: Boolean + ): JiraJqlVersionFieldValueConnection + """ + Retrieves a connection of unreleased versions. + """ + unreleased( + """ + The number of items to be sliced away to target between the after and before cursors. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + Determines whether or not archived versions are returned. By default it will be false. + """ + includeArchived: Boolean + ): JiraJqlVersionFieldValueConnection + + """ + Retrieves a connection of archived versions. + """ + archived( + """ + The number of items to be sliced away to target between the after and before cursors. + """ + first: Int + """ + The index based cursor to specify the beginning of the items, if not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items to be sliced away from the bottom of the list after slicing with `first` argument. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items, if not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraJqlVersionFieldValueConnection +} + +""" +Represents a connection of field-values for a JQL version field. +""" +type JiraJqlVersionFieldValueConnection { + """ + The total number of JiraJqlVersionFieldValues matching the criteria. + """ + totalCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + The data for the edges in the current page. + """ + edges: [JiraJqlVersionFieldValueEdge] +} + +""" +Represents a field-value edge for a JQL version field. +""" +type JiraJqlVersionFieldValueEdge { + """ + The node at the edge. + """ + node: JiraJqlVersionFieldValue + """ + The cursor to this edge. + """ + cursor: String! +} +""" +The visibility property of a comment within a JSM project type. +""" +enum JiraServiceManagementCommentVisibility { + """ + This comment will appear in the portal, visible to all customers. Also called public. + """ + VISIBLE_TO_HELPSEEKER + """ + This comment will only appear in JIRA's issue view. Also called private. + """ + INTERNAL +} +""" +Represents the label of a custom label field. +""" +type JiraLabel { + """ + The identifier of the label. + Can be null when label is not yet created or label was returned without providing an Issue id. + """ + labelId: String + """ + The name of the label. + """ + name: String +} + +""" +The connection type for JiraLabel. +""" +type JiraLabelConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraLabelEdge] +} + +""" +An edge in a Jiralabel connection. +""" +type JiraLabelEdge { + """ + The node at the edge. + """ + node: JiraLabel + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the language that can be used for fields such as JSM Requested Language. +""" +type JiraServiceManagementLanguage { + """ + A unique language code that represents the language. + """ + languageCode: String + """ + A readable common name for this language. + """ + displayName: String +} +""" +An enum representing possible values for Major Incident JSM field. +""" +enum JiraServiceManagementMajorIncident { + MAJOR_INCIDENT +}""" +Represents a media context used for file uploads. +""" +type JiraMediaContext { + """ + Contains the token information for uploading a media content. + """ + uploadToken: JiraMediaUploadTokenResult +} + +""" +Contains either the successful fetched media token information or an error. +""" +union JiraMediaUploadTokenResult = JiraMediaUploadToken | QueryError + +""" +Contains the information needed for uploading a media content in jira on issue create/view screens. +""" +type JiraMediaUploadToken { + """ + Endpoint where the media content will be uploaded. + """ + endpointUrl: URL + """ + Registered client id of media API. + """ + clientId: String + """ + The collection in which to put the new files. + It can be user-scoped (such as upload-user-collection-*) + or project scoped (such as upload-project-*). + """ + targetCollection: String + """ + token string value which can be used with Media API requests. + """ + token: String + """ + Represents the duration (in minutes) for which token will be valid. + """ + tokenDurationInMin: Int +} +""" +Represents the pair of values (parent & child combination) in a cascading select. +This type is used to represent a selected cascading field value on a Jira Issue. +Since this is 2 level hierarchy, it is not possible to represent the same underlying +type for both single cascadingOption and list of cascadingOptions. Thus, we have created different types. +""" +type JiraCascadingOption { + """ + Defines the parent option value. + """ + parentOptionValue: JiraOption + """ + Defines the selected single child option value for the parent. + """ + childOptionValue: JiraOption +} + +""" +Represents the childs options allowed values for a parent option in cascading select operation. +""" +type JiraCascadingOptions { + """ + Defines the parent option value. + """ + parentOptionValue: JiraOption + """ + Defines all the list of child options available for the parent option. + """ + childOptionValues: [JiraOption] +} + +""" +Represents a single option value in a select operation. +""" +type JiraOption implements Node { + """ + Global Identifier of the option. + """ + id: ID! + """ + Identifier of the option. + """ + optionId: String! + """ + Value of the option. + """ + value: String + """ + Whether or not the option has been disabled by the user. Disabled options are typically not accessible in the UI. + """ + isDisabled: Boolean +} + +""" +The connection type for JiraOption. +""" +type JiraOptionConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraOptionEdge] +} + +""" +An edge in a JiraOption connection. +""" +type JiraOptionEdge { + """ + The node at the edge. + """ + node: JiraOption + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +The connection type for JiraCascadingOptions. +""" +type JiraCascadingOptionsConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraCascadingOptionsEdge] +} + +""" +An edge in a JiraCascadingOptions connection. +""" +type JiraCascadingOptionsEdge { + """ + The node at the edge. + """ + node: JiraCascadingOptions + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the customer organization on an Issue in a JiraServiceManagement project. +""" +type JiraServiceManagementOrganization { + """ + Globally unique id within this schema. + """ + organizationId: ID + """ + The organization's name. + """ + organizationName: String + """ + The organization's domain. + """ + domain: String +} + +""" +The connection type for JiraServiceManagementOrganization. +""" +type JiraServiceManagementOrganizationConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementOrganizationEdge] +} + +""" +An edge in a JiraServiceManagementOrganization connection. +""" +type JiraServiceManagementOrganizationEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementOrganization + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents flags required to determine parent field visibility +""" +type JiraParentVisibility { + """ + Flag to disable editing the Parent Link field and showing the error that the issue has an epic link set, and thus cannot use the Parent Link field. + """ + hasEpicLinkFieldDependency: Boolean + """ + Flag which along with hasEpicLinkFieldDependency is used to determine the Parent Link field visiblity. + """ + canUseParentLinkField: Boolean +} +""" +Contains either the group or the projectRole associated with a comment/worklog, but not both. +If both are null, then the permission level is unspecified and the comment/worklog is public. +""" +type JiraPermissionLevel { + """ + The Jira Group associated with the comment/worklog. + """ + group: JiraGroup + """ + The Jira ProjectRole associated with the comment/worklog. + """ + role: JiraRole +} +""" +A permission scheme is a collection of permission grants. +""" +type JiraPermissionScheme implements Node { + "The ARI of the permission scheme." + id: ID! + "The display name of the permission scheme." + name: String! + "The description of the permission scheme." + description: String +} + +""" +The project permission in Jira and it is scoped to projects. +""" +type JiraProjectPermission { + "The unique key of the permission." + key: String! + "The display name of the permission." + name: String! + "The description of the permission." + description: String! + "The category of the permission." + type: JiraProjectPermissionCategory! +} + +""" +The category of the project permission. +The category information is typically seen in the permission scheme Admin UI. +It is used to group the project permissions in general and available for connect app developers when registering new project permissions. +""" +type JiraProjectPermissionCategory { + "The unique key of the permission category." + key: JiraProjectPermissionCategoryEnum! + "The display name of the permission category." + name: String! +} + +""" +The category of the project permission. +It represents the logical grouping of the project permissions. +""" +enum JiraProjectPermissionCategoryEnum { + "Represents one or more permissions applicable at project level such as project administration, view project information, and manage sprints." + PROJECTS + "Represents one or more permissions applicable at issue level to manage operations such as create, delete, edit, and transition." + ISSUES + "Represents one or more permissions to manage watchers and voters of an issue." + VOTERS_AND_WATCHERS + "Represents one or more permissions to manage issue comments such as add, delete and edit." + COMMENTS + "Represents one or more permissions to manage issue attacments such as create and delete." + ATTACHMENTS + "Represents one or more permissions to manage worklogs, time tracking for billing purpose in some cases." + TIME_TRACKING + "Represents one or more permissions representing default category if not any other existing category." + OTHER +} + +""" +The unique key of the grant type such as PROJECT_ROLE. +""" +type JiraGrantTypeKey { + "The key to identify the grant type such as PROJECT_ROLE." + key: JiraGrantTypeKeyEnum! + "The display name of the grant type key such as Project Role." + name: String! +} + +""" +The grant type key enum represents all the possible grant types available in Jira. +A grant type may take an optional parameter value. +For example: PROJECT_ROLE grant type takes project role id as parameter. And, PROJECT_LEAD grant type do not. + +The actual ARI formats are documented on the various concrete grant type values. +""" +enum JiraGrantTypeKeyEnum { + """ + A role that user/group can play in a project. + It takes project role as parameter. + """ + PROJECT_ROLE + + """ + A application role is used to grant a user/group access to the application group. + It takes application role as parameter. + """ + APPLICATION_ROLE + + """ + An individual user who can be given the access to work on one or more projects. + It takes user account id as parameter. + """ + USER + + """ + A group is a collection of users who can be given access together. + It represents group in the organization's user base. + It takes group id as parameter. + """ + GROUP + + """ + A multi user picker custom field. + It takes multi user picker custom field id as parameter. + """ + MULTI_USER_PICKER + + """ + A multi group picker custom field. + It takes multi group picker custom field id as parameter. + """ + MULTI_GROUP_PICKER + + """ + The grant type defines what the customers can do from the portal view. + It takes no parameter. + """ + SERVICE_PROJECT_CUSTOMER_PORTAL_ACCESS + + """ + The issue reporter role. + It takes platform defined 'reporter' as parameter to represent the issue field value. + """ + REPORTER + + """ + The project lead role. + It takes no parameter. + """ + PROJECT_LEAD + + """ + The issue assignee role. + It takes platform defined 'assignee' as parameter to represent the issue field value. + """ + ASSIGNEE + + """ + The anonymous access represents the public access without logging in. + It takes no parameter. + """ + ANONYMOUS_ACCESS + + """ + Any user who has the product access. + It takes no parameter. + """ + ANY_LOGGEDIN_USER_APPLICATION_ROLE +} + +""" +The default grant type with only id and name to return data for grant types such as PROJECT_LEAD, APPLICATION_ROLE, +ANY_LOGGEDIN_USER_APPLICATION_ROLE, ANONYMOUS_ACCESS, SERVICE_PROJECT_CUSTOMER_PORTAL_ACCESS +""" +type JiraDefaultGrantTypeValue implements Node { + """ + The ARI to represent the default grant type value. + For example: + PROJECT_LEAD ari - ari:cloud:jira:a2520569-493f-45bc-807b-54b02bc724d1:role/project-lead/activation/bd0c43a9-a23a-4302-8ffa-ca04bde7c747/project/f67c73a8-545e-455b-a6bd-3d53cb7e0524 + APPLICATION_ROLE ari for JSM - ari:cloud:jira-servicedesk::role/123 + ANY_LOGGEDIN_USER_APPLICATION_ROLE ari - ari:cloud:jira::role/product/member + ANONYMOUS_ACCESS ari - ari:cloud:identity::user/unidentified + """ + id: ID! + "The display name of the grant type value such as GROUP." + name: String! +} + +""" +The USER grant type value where user data is provided by identity service. +""" +type JiraUserGrantTypeValue implements Node { + """ + The ARI to represent the grant user type value. + For example: ari:cloud:identity::user/123 + """ + id: ID! + "The GDPR compliant user profile information." + user: User! +} + +""" +The GROUP grant type value where group data is provided by identity service. +""" +type JiraGroupGrantTypeValue implements Node { + """ + The ARI to represent the group grant type value. + For example: ari:cloud:identity::group/123 + """ + id: ID! + "The group information such as name, and description." + group: JiraGroup! +} + +""" +The project role grant type value having the project role information. +""" +type JiraProjectRoleGrantTypeValue implements Node { + """ + The ARI to represent the project role grant type value. + For example: ari:cloud:jira:a2520569-493f-45bc-807b-54b02bc724d1:role/project-role/activation/bd0c43a9-a23a-4302-8ffa-ca04bde7c747/projectrole/b434089d-7f6d-476b-884b-7811661f91d2 + """ + id: ID! + "The project role information such as name, description." + role: JiraRole! +} + +""" +The issue field grant type used to represent field of an issue. +Grant types such as ASSIGNEE, REPORTER, MULTI USER PICKER, and MULTI GROUP PICKER use this grant type value. +""" +type JiraIssueFieldGrantTypeValue implements Node { + """ + The ARI to represent the issue field grant type value. + For example: + assignee field ARI is ari:cloud:jira:a2520569-493f-45bc-807b-54b02bc724d1:issuefieldvalue/10000/assignee + reporter field ARI is ari:cloud:jira:a2520569-493f-45bc-807b-54b02bc724d1:issuefieldvalue/10000/reporter + multi user picker field ARI is ari:cloud:jira:a2520569-493f-45bc-807b-54b02bc724d1:issuefieldvalue/10000/customfield_10126 + """ + id: ID! + "The issue field information such as name, description, field id." + field: JiraIssueField! +} +extend type JiraQuery { + + """ + Get all the available grant type keys such as project role, application access, user, group. + """ + allGrantTypeKeys(cloudId: ID!): [JiraGrantTypeKey!]! + + """ + Get the grant type values by search term and grant type key. + It only supports fetching values for APPLICATION_ROLE, PROJECT_ROLE, MULTI_USER_PICKER and MULTI_GROUP_PICKER grant types. + """ + grantTypeValues( + "Returns the first n elements from the list." + first: Int + "Returns the elements in the list that come after the specified cursor." + after: String + "Returns the last n elements from the list." + last: Int + "Returns the elements in the list that come before the specified cursor." + before: String + "The mandatory grant type key to search within specific grant type such as project role." + grantTypeKey: JiraGrantTypeKeyEnum! + "search term to filter down on the grant type values." + searchTerm: String + "The cloud id of the tenant." + cloudId: ID! + ): JiraGrantTypeValueConnection + + """ + Get the permission scheme based on scheme id. The scheme ID input represent an ARI. + """ + viewPermissionScheme(schemeId: ID!): JiraPermissionSchemeViewResult + + """ + Get the list of paginated projects associated with the given permission scheme ID. + The project objects will be returned based on implicit ascending order by project name. + """ + getProjectsByPermissionScheme( + "Returns the first n elements from the list." + first: Int + "Returns the elements in the list that come after the specified cursor." + after: String + "Returns the last n elements from the list." + last: Int + "Returns the elements in the list that come before the specified cursor." + before: String + "The permission scheme ARI to filter the results." + schemeId: ID! + ): JiraProjectConnection + + """ + A list of paginated permission scheme grants based on the given permission scheme ID. + """ + permissionSchemeGrants( + "Returns the first n elements from the list." + first: Int + "Returns the elements in the list that come after the specified cursor." + after: String + "Returns the last n elements from the list." + last: Int + "Returns the elements in the list that come before the specified cursor." + before: String + "The permission scheme ARI to filter the results." + schemeId: ID! + "The optional project permission key to filter the results." + permissionKey: String + ): JiraPermissionGrantValueConnection @deprecated(reason: "Please use getPermissionSchemeGrants instead.") + + """ + A list of paginated permission scheme grants based on the given permission scheme ID and permission key. + """ + getPermissionSchemeGrants( + "Returns the first n elements from the list." + first: Int + "Returns the elements in the list that come after the specified cursor." + after: String + "Returns the last n elements from the list." + last: Int + "Returns the elements in the list that come before the specified cursor." + before: String + "The permission scheme ARI to filter the results." + schemeId: ID! + "The mandatory project permission key to filter the results." + permissionKey: String! + "The optional grant type key to filter the results." + grantTypeKey: JiraGrantTypeKeyEnum + ): JiraPermissionGrantConnection + + """ + Gets the permission scheme grants hierarchy (by grant type key) based on the given permission scheme ID and permission key. + This returns a bounded list of data with limit set to 50. For getting the complete list in paginated manner, use getPermissionSchemeGrants. + """ + getPermissionSchemeGrantsHierarchy( + "The permission scheme ARI to filter the results." + schemeId: ID! + "The mandatory project permission key to filter the results." + permissionKey: String! + ): [JiraPermissionGrants!]! + +} + +extend type JiraMutation { + + """ + The mutation operation to add one or more new permission grants to the given permission scheme. + The operation takes mandatory permission scheme ID. + The limit on the new permission grants can be added is set to 50. + """ + addPermissionSchemeGrants(input: JiraPermissionSchemeAddGrantInput!): JiraPermissionSchemeAddGrantPayload + + """ + The mutation operation to remove one or more existing permission scheme grants in the given permission scheme. + The operation takes mandatory permission scheme ID. + The limit on the new permission grants can be removed is set to 50. + """ + removePermissionSchemeGrants(input: JiraPermissionSchemeRemoveGrantInput!): JiraPermissionSchemeRemoveGrantPayload + +} + +""" +The JiraPermissionSchemeView represents the composite view to capture basic information of +the permission scheme such as id, name, description and a bounded list of one or more grant groups. +A grant group contains existing permission grant information such as permission, permission category, grant type and grant type value. +""" +type JiraPermissionSchemeView { + "The basic permission scheme information such as id, name and description." + scheme: JiraPermissionScheme! + "The additional configuration information regarding the permission scheme." + configuration: JiraPermissionSchemeConfiguration! + "The bounded list of one or more grant groups represent each group of permission grants based on project permission category such as PROJECTS, ISSUES." + grantGroups: [JiraPermissionSchemeGrantGroup!] +} + +""" +The JiraPermissionSchemeConfiguration represents additional configuration information regarding the permission scheme such as its editability. +""" +type JiraPermissionSchemeConfiguration { + "The indicator saying whether a permission scheme is editable or not." + isEditable: Boolean! +} + +""" +The JiraPermissionSchemeGrantGroup is an association between project permission category information and a bounded list of one or more +associated permission grant holder. A grant holder represents project permission information and its associated permission grants. +""" +type JiraPermissionSchemeGrantGroup { + "The basic project permission category information such as key and display name." + category: JiraProjectPermissionCategory! + "A bounded list of one or more permission grant holders." + grantHolders: [JiraPermissionGrantHolder] +} + +""" +The JiraPermissionGrantHolder represents an association between project permission information and +a bounded list of one or more permission grant. +A permission grant holds association between grant type and a paginated list of grant values. +""" +type JiraPermissionGrantHolder { + "The basic information about the project permission." + permission: JiraProjectPermission! + "The additional configuration information regarding the permission." + configuration: JiraPermissionConfiguration + "A bounded list of jira permission grant." + grants: [JiraPermissionGrants!] +} + +""" +The JiraPermissionConfiguration represents additional configuration information regarding the permission such as +deprecation, new addition etc. It contains documentation/notice and/or actionable items for the permission +such as deprecation of BROWSE_PROJECTS in favour of VIEW_PROJECTS and VIEW_ISSUES. +""" +type JiraPermissionConfiguration { + "The tag for the permission key." + tag: JiraPermissionTagEnum! + "The message contains actionable information for the permission key." + message: JiraPermissionMessageExtension + "The documentation for the permission key." + documentation: JiraPermissionDocumentationExtension +} + +""" +The JiraPermissionTagEnum represents additional tags for the permission key. +""" +enum JiraPermissionTagEnum { + "Represents a permission that is about to be deprecated." + DEPRECATED, + "Represents a permission that is newly added." + NEW +} + +""" +The JiraPermissionMessageExtension represents actionable information for a permission such as deprecation of +BROWSE_PROJECTS in favour of VIEW_PROJECTS and VIEW_ISSUES. +""" +type JiraPermissionMessageExtension { + "The category of the message such as WARNING, INFORMATION etc." + type: JiraPermissionMessageTypeEnum! + "The display text of the message." + text: String! +} + +""" +The JiraPermissionMessageTypeEnum represents category of the message section. +""" +enum JiraPermissionMessageTypeEnum { + "Represents a basic message." + INFORMATION, + "Represents a warning message." + WARNING +} + +""" +The JiraPermissionDocumentationExtension contains developer documentation for a permission key. +""" +type JiraPermissionDocumentationExtension { + "The display text of the developer documentation." + text: String! + "The link to the developer documentation." + url: String! +} + +""" +The JiraPermissionGrants represents an association between grant type information and a bounded list of one or more grant +values associated with given grant type. +Each grant value has grant type specific information. +For example, PROJECT_ROLE grant type value contains project role ID in ARI format and role specific details. +""" +type JiraPermissionGrants { + "The grant type information includes key and display name." + grantType: JiraGrantTypeKey! + "A bounded list of grant values. Each grant value has grant type specific information." + grantValues: [JiraPermissionGrantValue!] + "The total number of items matching the criteria" + totalCount: Int +} + +""" +The type represents a paginated view of permission grants in the form of connection object. +""" +type JiraPermissionGrantConnection { + "The page info of the current page of results." + pageInfo: PageInfo! + "A list of edges in the current page." + edges: [JiraPermissionGrantEdge] + "The total number of items matching the criteria." + totalCount: Int +} + +""" +The permission grant edge object used in connection object for representing an edge. +""" +type JiraPermissionGrantEdge { + "The node at this edge." + node: JiraPermissionGrant! + "The cursor to this edge." + cursor: String! +} + +""" +The JiraPermissionGrant represents an association between the grant type key and the grant value. +Each grant value has grant type specific information. +For example, PROJECT_ROLE grant type value contains project role ID in ARI format and role specific details. +""" +type JiraPermissionGrant { + "The grant type information includes key and display name." + grantType: JiraGrantTypeKey! + "The grant value has grant type key specific information." + grantValue: JiraPermissionGrantValue! +} + +""" +The type represents a paginated view of permission grant values in the form of connection object. +""" +type JiraPermissionGrantValueConnection { + "The page info of the current page of results." + pageInfo: PageInfo! + "A list of edges in the current page." + edges: [JiraPermissionGrantValueEdge] + "The total number of items matching the criteria." + totalCount: Int +} + +""" +The permission grant value edge object used in connection object for representing an edge. +""" +type JiraPermissionGrantValueEdge { + "The node at this edge." + node: JiraPermissionGrantValue! + "The cursor to this edge." + cursor: String! +} + +""" +The permission grant value represents the actual permission grant value. +The id field represent the grant ID and its not an ARI. The value represents actual value information specific to grant type. +For example: PROJECT_ROLE grant type value contains project role ID in ARI format and role specific details +""" +type JiraPermissionGrantValue { + """ + The ID of the permission grant. + It represents the relationship among permission, grant type and grant type specific value. + """ + id: ID! + """ + The optional grant type value is a union type. + The value itself may resolve to one of the concrete types such as JiraDefaultGrantTypeValue, JiraProjectRoleGrantTypeValue. + """ + value: JiraGrantTypeValue +} + +""" +The JiraGrantTypeValue union resolves to one of the concrete types such as JiraDefaultGrantTypeValue, JiraProjectRoleGrantTypeValue. +""" +union JiraGrantTypeValue = JiraDefaultGrantTypeValue | JiraUserGrantTypeValue | JiraProjectRoleGrantTypeValue | JiraGroupGrantTypeValue | JiraIssueFieldGrantTypeValue + +""" +A type to represent one or more paginated list of one or more permission grant values available for a given grant type. +""" +type JiraGrantTypeValueConnection { + "A list of edges in the current page." + edges: [JiraGrantTypeValueEdge] + "The page info of the current page of results." + pageInfo: PageInfo! + "The total number of items matching the criteria." + totalCount: Int +} + +""" +An edge object representing grant type value information used within connection object. +""" +type JiraGrantTypeValueEdge { + "The node at this edge." + node: JiraGrantTypeValue! + "The cursor to this edge." + cursor: String! +} + +""" +The union result representing either the composite view of the permission scheme or the query error information. +""" +union JiraPermissionSchemeViewResult = JiraPermissionSchemeView | QueryError + +""" +Specifies permission scheme grant for the combination of permission key, grant type key, and grant type value ARI. +""" +input JiraPermissionSchemeGrantInput { + "the project permission key." + permissionKey: String! + "The grant type key such as USER." + grantType: JiraGrantTypeKeyEnum! + """ + The optional grant value in ARI format. Some grantType like PROJECT_LEAD, REPORTER etc. have no grantValue. Any grantValue passed will be silently ignored. + For example: project role ID ari is of the format - ari:cloud:jira:a2520569-493f-45bc-807b-54b02bc724d1:role/project-role/activation/bd0c43a9-a23a-4302-8ffa-ca04bde7c747/projectrole/b434089d-7f6d-476b-884b-7811661f91d2 + """ + grantValue: ID +} + +""" +The input type to add new permission grants to the given permission scheme. +""" +input JiraPermissionSchemeAddGrantInput { + "The permission scheme ID in ARI format." + schemeId: ID! + "The list of one or more grants to be added." + grants: [JiraPermissionSchemeGrantInput!]! +} + +""" +The response payload for add permission grants mutation operation for a given permission scheme. +""" +type JiraPermissionSchemeAddGrantPayload implements Payload { + "The success indicator saying whether mutation operation was successful as a whole or not." + success: Boolean! + "The errors field represents additional mutation error information if exists." + errors: [MutationError!] +} + +""" +The input type to remove permission grants from the given permission scheme. +""" +input JiraPermissionSchemeRemoveGrantInput { + "The permission scheme ID in ARI format." + schemeId: ID! + "The list of one or more grants to be removed." + grants: [JiraPermissionSchemeGrantInput!] @deprecated(reason: "Please use grantIds field instead") + "The list of permission grant ids." + grantIds: [Long!]! +} + +""" +The response payload for remove existing permission grants mutation operation for a given permission scheme. +""" +type JiraPermissionSchemeRemoveGrantPayload implements Payload { + "The success indicator saying whether mutation operation was successful as a whole or not." + success: Boolean! + "The errors field represents additional mutation error information if exists." + errors: [MutationError!] +}""" +Represents an issue's priority field +""" +type JiraPriority implements Node { + """ + Unique identifier referencing the priority ID. + """ + id: ID! + """" + The priority ID. E.g. 10000. + """ + priorityId: String! + """ + The priority name. + """ + name: String + """ + The priority icon URL. + """ + iconUrl: URL + """ + The priority color. + """ + color: String +} + +""" +The connection type for JiraPriority. +""" +type JiraPriorityConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraPriorityEdge] +} + +""" +An edge in a JiraPriority connection. +""" +type JiraPriorityEdge { + """ + The node at the edge. + """ + node: JiraPriority + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents proforma-forms. +""" +type JiraProformaForms { + """ + Indicates whether the project has proforma-forms or not. + """ + hasProjectForms: Boolean + """ + Indicates whether the issue has proforma-forms or not. + """ + hasIssueForms: Boolean +}# Copied over from jira-project, will extend this type after deprecating rest bridge project + +""" +Represents a Jira project. +""" +type JiraProject implements Node { + """ + Global identifier for the project. + """ + id: ID! + """ + The key of the project. + """ + key: String! + """ + The project id of the project. e.g. 10000. Temporarily needed to support interoperability with REST. + """ + projectId: String + """ + The name of the project. + """ + name: String! + """ + The cloudId associated with the project. + """ + cloudId: ID! + """ + The description of the project. + """ + description: String + """ + The ID of the project lead. + """ + leadId: ID + """ + The category of the project. + """ + category: JiraProjectCategory + """ + The avatar of the project. + """ + avatar: JiraAvatar + """ + The URL associated with the project. + """ + projectUrl: String + """ + Specifies the type to which project belongs to ex:- software, service_desk, business etc. + """ + projectType: JiraProjectType + """ + Specifies the style of the project. + The use of this field is discouraged. API deviations between project styles are deprecated. + This field only exists to support legacy use cases. This field will be removed in the future. + """ + projectStyle: JiraProjectStyle @deprecated(reason: "The `projectStyle` is a deprecated field.") + """ + Specifies the status of the project e.g. archived, deleted. + """ + status: JiraProjectStatus + """ + Represents the SimilarIssues feature associated with this project. + """ + similarIssues: JiraSimilarIssues + """ + Returns if the user has the access to set issue restriction with the current project + """ + canSetIssueRestriction: Boolean + """ + Returns navigation specific information to aid in transitioning from a project to a landing page eg. board, queue, list, etc + """ + navigationMetadata: JiraProjectNavigationMetadata +} + +""" +""" +type JiraProjectCategory implements Node { + """ + Global id of this project category. + """ + id: ID! + """ + Display name of the Project category. + """ + name: String + """ + Description of the Project category. + """ + description: String +} + +""" +The connection type for JiraProject. +""" +type JiraProjectConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraProjectEdge] +} + +""" +An edge in a JiraProject connection. +""" +type JiraProjectEdge { + """ + The node at the edge. + """ + node: JiraProject + """ + The cursor to this edge. + """ + cursor: String! +} + +""" +Jira Project types. +""" +enum JiraProjectType { + """ + A service desk project. + """ + SERVICE_DESK + """ + A business project. + """ + BUSINESS + """ + A software project. + """ + SOFTWARE +} + +""" +Jira Project statuses. +""" +enum JiraProjectStatus { + """ + An active project. + """ + ACTIVE + """ + An archived project. + """ + ARCHIVED + """ + A deleted project. + """ + DELETED +} + +""" +Jira Project Styles. +""" +enum JiraProjectStyle { + """ + A team-managed project. + """ + TEAM_MANAGED_PROJECT + """ + A company-managed project. + """ + COMPANY_MANAGED_PROJECT +}type JiraSoftwareProjectNavigationMetadata { + id: ID!, + boardId: ID!, + boardName: String! + # Used to tell the difference between classic and next generation boards (agility, simple, nextgen, CMP) + isSimpleBoard: Boolean! +} + +type JiraServiceManagementProjectNavigationMetadata { + queueId: ID!, + queueName: String! +} + +type JiraWorkManagementProjectNavigationMetadata { + boardName: String! +} + +union JiraProjectNavigationMetadata = JiraSoftwareProjectNavigationMetadata | JiraServiceManagementProjectNavigationMetadata | JiraWorkManagementProjectNavigationMetadata +""" +Represents a Jira ProjectRole. +""" +type JiraRole implements Node { + """ + Global identifier of the ProjectRole. + """ + id: ID! + """ + Id of the ProjectRole. + """ + roleId: String! + """ + Name of the ProjectRole. + """ + name: String + """ + Description of the ProjectRole. + """ + description: String +} + +""" +The connection type for JiraRole. +""" +type JiraRoleConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + The page infor of the current page of results. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraRoleEdge] +} + +""" +An edge in a JiraRoleConnection connection. +""" +type JiraRoleEdge { + """ + The node at the edge. + """ + node: JiraRole + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Requests the request type structure on an Issue. +""" +type JiraServiceManagementRequestType implements Node { + """ + Global identifier representing the request type id. + """ + id: ID! + """ + Identifier for the request type. + """ + requestTypeId: String! + """ + Name of the request type. + """ + name: String + """ + A deprecated unique identifier string for Request Types. + It is still necessary due to the lack of request-type-id in critical parts of JiraServiceManagement backend. + """ + key: String @deprecated(reason: "The `key` field is deprecated. Please use the `requestTypeId` instead.") + """ + Description of the request type if applicable. + """ + description: String + """ + Help text for the request type. + """ + helpText: String + """ + Issue type to which request type belongs to. + """ + issueType: JiraIssueType + """ + Id of the portal that this request type belongs to. + """ + portalId: String + """ + Avatar for the request type. + """ + avatar: JiraAvatar + """ + Request type practice. E.g. incidents, service_request. + """ + practices: [JiraServiceManagementRequestTypePractice] +} + +""" +Defines grouping of the request types,currently only applicable for JiraServiceManagement ITSM projects. +""" +type JiraServiceManagementRequestTypePractice { + """ + Practice in which the request type is categorized. + """ + key: JiraServiceManagementPractice +} + +""" +ITSM project practice categorization. +""" +enum JiraServiceManagementPractice { + """ + Manage work across teams with one platform so the employees and customers quickly get the help they need. + """ + SERVICE_REQUEST + """ + Bring the development and IT operations teams together to rapidly respond to, resolve, and continuously learn from incidents. + """ + INCIDENT_MANAGEMENT + """ + Group incidents to problems, fast-track root cause analysis, and record workarounds to minimize the impact of incidents. + """ + PROBLEM_MANAGEMENT + """ + Empower the IT operations teams with richer contextual information around changes from software development tools so they can make better decisions and minimize risk. + """ + CHANGE_MANAGEMENT + """ + Bring people and teams together to discuss the details of an incident: why it happened, what impact it had, what actions were taken to resolve it, and how the team can prevent it from happening again. + """ + POST_INCIDENT_REVIEW +} + +""" +The connection type for JiraServiceManagementRequestType. +""" +type JiraServiceManagementRequestTypeConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementRequestTypeEdge] +} + +""" +An edge in a JiraServiceManagementIssueType connection. +""" +type JiraServiceManagementRequestTypeEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementRequestType + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the resolution field of an issue. +""" +type JiraResolution implements Node { + """ + Global identifier representing the resolution id. + """ + id: ID! + """ + Resolution Id in the digital format. + """ + resolutionId: String! + """ + Resolution name. + """ + name: String + """ + Resolution description. + """ + description: String +} + +""" +The connection type for JiraResolution. +""" +type JiraResolutionConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraResolutionEdge] +} + +""" +An edge in a JiraResolution connection. +""" +type JiraResolutionEdge { + """ + The node at the edge. + """ + node: JiraResolution + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Responder field of a JSM issue, can be either a user or a team. +""" +union JiraServiceManagementResponder = JiraServiceManagementUserResponder | JiraServiceManagementTeamResponder + +""" +A user as a responder. +""" +type JiraServiceManagementUserResponder { + user: User +} + +""" +An Opsgenie team as a responder. +""" +type JiraServiceManagementTeamResponder { + """ + Opsgenie team id. + """ + teamId : String + """ + Opsgenie team name. + """ + teamName : String +} + +""" +The connection type for JiraServiceManagementResponder. +""" +type JiraServiceManagementResponderConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraServiceManagementResponderEdge] +} + +""" +An edge in a JiraServiceManagementResponder connection. +""" +type JiraServiceManagementResponderEdge { + """ + The node at the edge. + """ + node: JiraServiceManagementResponder + """ + The cursor to this edge. + """ + cursor: String! +}""" +Represents the rich text format of a rich text field. +""" +type JiraRichText { + """ + Text in Atlassian Document Format. + """ + adfValue: JiraADF + """ + Plain text version of the text. + """ + plainText: String @deprecated(reason: "`plainText` is deprecated. Please use `adfValue` for all rich text in Jira.") + """ + Text in wiki format. + """ + wikiValue: String @deprecated(reason: "`wikiValue` is deprecated. Please use `adfValue` for all rich text in Jira.") +} + +""" +Represents the Atlassian Document Format content in JSON format. +""" +type JiraADF { + """ + The content of ADF in JSON. + """ + json: JSON +} +""" +Represents the security levels on an Issue. +""" +type JiraSecurityLevel implements Node { + """ + Global identifier for the security level. + """ + id: ID! + """ + identifier for the security level. + """ + securityId: String! + """ + Name of the security level. + """ + name: String + """ + Description of the security level. + """ + description: String +} + +""" +The connection type for JiraSecurityLevel. +""" +type JiraSecurityLevelConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraSecurityLevelEdge] +} + +""" +An edge in a JiraSecurityLevel connection. +""" +type JiraSecurityLevelEdge { + """ + The node at the edge. + """ + node: JiraSecurityLevel + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the SimilarIssues feature associated with a JiraProject. +""" +type JiraSimilarIssues { + """ + Indicates whether the SimilarIssues feature is enabled or not. + """ + featureEnabled: Boolean! +} +""" +Represents the sprint field of an issue. +""" +type JiraSprint implements Node { + """ + Global identifier for the sprint. + """ + id: ID! + """ + Sprint id in the digital format. + """ + sprintId: String! + """ + Sprint name. + """ + name: String + """ + Current state of the sprint. + """ + state: JiraSprintState + """ + The board name that the sprint belongs to. + """ + boardName: String + """ + Start date of the sprint. + """ + startDate: DateTime + """ + End date of the sprint. + """ + endDate: DateTime + """ + Completion date of the sprint. + """ + completionDate: DateTime + """ + The goal of the sprint. + """ + goal: String +} + +""" +Represents the state of the sprint. +""" +enum JiraSprintState { + """ + The sprint is in progress. + """ + ACTIVE + """ + The sprint hasn't been started yet. + """ + FUTURE + """ + The sprint has been completed. + """ + CLOSED +} + +""" +The connection type for JiraSprint. +""" +type JiraSprintConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraSprintEdge] +} + +""" +An edge in a JiraSprint connection. +""" +type JiraSprintEdge { + """ + The node at the edge. + """ + node: JiraSprint + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents the status field of an issue. +""" +type JiraStatus implements Node { + """ + Global identifier for the Status. + """ + id: ID! + """ + Status id in the digital format. + """ + statusId: String! + """ + Name of status. E.g. Backlog, Selected for Development, In Progress, Done. + """ + name: String + """ + Optional description of the status. E.g. "This issue is actively being worked on by the assignee". + """ + description: String + """ + Represents a group of Jira statuses. + """ + statusCategory: JiraStatusCategory +} + +""" +Represents the category of a status. +""" +type JiraStatusCategory implements Node { + """ + Global identifier for the Status Category. + """ + id: ID! + """ + Status category id in the digital format. + """ + statusCategoryId: String! + """ + A unique key to identify this status category. E.g. new, indeterminate, done. + """ + key: String + """ + Name of status category. E.g. New, In Progress, Complete. + """ + name: String + """ + Color of status category. + """ + colorName: JiraStatusCategoryColor +} + +""" +Color of the status category. +""" +enum JiraStatusCategoryColor { + """ + #707070 + """ + MEDIUM_GRAY + """ + #14892c + """ + GREEN + """ + #f6c342 + """ + YELLOW + """ + #815b3a + """ + BROWN + """ + #d04437 + """ + WARM_RED + """ + #4a6785 + """ + BLUE_GRAY +} +""" +Represents a single team in Jira +""" +type JiraTeam implements Node { + """ + Global identifier of team. + """ + id: ID! + """ + Team id in the digital format. + """ + teamId: String! + """ + Name of the team. + """ + name: String + """ + Description of the team. + """ + description: String @deprecated(reason: "JPO Team does not have a description field.") + """ + Avatar of the team. + """ + avatar: JiraAvatar + """ + Members available in the team. + """ + members: JiraUserConnection + """ + Indicates whether the team is publicly shared or not. + """ + isShared: Boolean +} + +""" +The connection type for JiraTeam. +""" +type JiraTeamConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraTeamEdge] +} + +""" +An edge in a JiraTeam connection. +""" +type JiraTeamEdge { + """ + The node at the edge. + """ + node: JiraTeam + """ + The cursor to this edge. + """ + cursor: String! +} +""" +Represents a view on a Team in Jira. +""" +type JiraTeamView { + """ + The ARI of the team. + """ + jiraSuppliedId: ID! + """ + The unique identifier of the team. + """ + jiraSuppliedTeamId: String! + """ + If this is false, team data is no longer available. For example, a deleted team. + """ + jiraSuppliedVisibility: Boolean + """ + The name of the team. + """ + jiraSuppliedName: String + """ + The avatar of the team. + """ + jiraSuppliedAvatar: JiraAvatar @deprecated(reason: "in future, team avatar will no longer be exposed") +} +""" +Represents the type for representing global time tracking settings. +""" +type JiraTimeTrackingSettings { + """ + Returns whether time tracking implementation is provided by Jira or some external providers. + """ + isJiraConfiguredTimeTrackingEnabled: Boolean + """ + Number of hours in a working day. + """ + workingHoursPerDay: Float + """ + Number of days in a working week. + """ + workingDaysPerWeek: Float + """ + Format in which the time tracking details are presented to the user. + """ + defaultFormat: JiraTimeFormat + """ + Default unit for time tracking wherever not specified. + """ + defaultUnit: JiraTimeUnit +} + +""" +Different time formats supported for entering & displaying time tracking related data. +""" +enum JiraTimeFormat { + """ + E.g. 2 days, 4 hours, 30 minutes + """ + PRETTY + """ + E.g. 2d 4.5h + """ + DAYS + """ + E.g. 52.5h + """ + HOURS +} + +""" +Different time units supported for entering & displaying time tracking related data. +Get the currently configured default duration to use when parsing duration string for time tracking. +""" +enum JiraTimeUnit { + """ + When the current duration is in minutes. + """ + MINUTE + """ + When the current duration is in hours. + """ + HOUR + """ + When the current duration is in days. + """ + DAY + """ + When the current duration is in weeks. + """ + WEEK +} + +""" +Represents the Jira time tracking estimate type. +""" +type JiraEstimate { + """ + The estimated time in seconds. + """ + timeInSeconds: Long +} +""" +A connection to a list of users. +""" +type JiraUserConnection { + "The page info of the current page of results." + pageInfo: PageInfo! + "A list of User edges." + edges: [JiraUserEdge] + "A count of filtered result set across all pages." + totalCount: Int +} + +""" +An edge in an User connection object. +""" +type JiraUserEdge { + "The node at this edge." + node: User + "The cursor to this edge." + cursor: String +} +""" +Jira Version type that can be either Versions system fields or Versions Custom fields. +""" +type JiraVersion implements Node { + id: ID! + """ + Version Id. + """ + versionId: String! + """ + Version name. + """ + name: String + """ + Version icon URL. + """ + iconUrl: URL + """ + Status to which version belongs to. + """ + status: JiraVersionStatus + """ + Version description. + """ + description: String + """ + The date at which work on the version began. + """ + startDate: DateTime + """ + The date at which the version was released to customers. Must occur after startDate. + """ + releaseDate: DateTime + """ + Warning config of the version. This is per project setting. + """ + warningConfig: JiraVersionWarningConfig + """ + Marketplace connect app iframe data for Version details page's top right corner extension + point(location: atl.jira.releasereport.top.right.panels) + An empty array will be returned in case there isn't any marketplace apps installed. + """ + connectAddonIframeData: [JiraVersionConnectAddonIframeData] + """ + List of issues with the version. + """ + issues( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + filter of the issues under this version. If not given, the default filter will be determined by the server + """ + filter: JiraVersionIssuesFilter = ALL + ): JiraIssueConnection + + """ + List of related work items linked to the version. + """ + relatedWork( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified, it is assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraVersionRelatedWorkConnection + + """ + List of suggested categories to be displayed when creating a new related work item for a given + version. + """ + suggestedRelatedWorkCategories: [String] + + """ + Indicates whether the user has permission to edit the version such as releasing it or + associating related work to it. + """ + canEdit: Boolean +} + +""" +Input to update the version name. +""" +input JiraUpdateVersionNameInput { + """ + The identifier of the Jira version. + """ + id: ID! + """ + Version name. + """ + name: String! +} + +""" +Input to update the version description. +""" +input JiraUpdateVersionDescriptionInput { + """ + The identifier of the Jira version. + """ + id: ID! + """ + Version description. + """ + description: String +} + +""" +Input to update the version start date. +""" +input JiraUpdateVersionStartDateInput { + """ + The identifier of the Jira version. + """ + id: ID! + """ + The date at which work on the version began. + """ + startDate: DateTime +} + +""" +Input to update the version release date. +""" +input JiraUpdateVersionReleaseDateInput { + """ + The identifier of the Jira version. + """ + id: ID! + """ + The date at which the version was released to customers. Must occur after startDate. + """ + releaseDate: DateTime +} + +""" +The return payload of updating a version. +""" +type JiraUpdateVersionPayload implements Payload { + """ + Whether the mutation was successful or not. + """ + success: Boolean! + """ + A list of errors that occurred during the mutation. + """ + errors: [MutationError!] + """ + The updated version. + """ + version: JiraVersion +} + +""" +The connection type for JiraVersionRelatedWork. +""" +type JiraVersionRelatedWorkConnection { + """ + Information about the current page; used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraVersionRelatedWorkEdge] +} + +""" +An edge in a JiraVersionRelatedWork connection. +""" +type JiraVersionRelatedWorkEdge { + """ + The cursor to this edge. + """ + cursor: String + """ + The node at this edge. + """ + node: JiraVersionRelatedWork +} + +""" +Jira version related work type, which is used to associate "smart links" with a given Jira version. +""" +type JiraVersionRelatedWork { + """ + Client-generated ID for the related work item. + """ + relatedWorkId: ID + """ + Related work URL. + """ + url: URL + """ + Related work title; can be null if user didn't enter a title when adding the link. + """ + title: String + """ + Category for the related work item. + """ + category: String + """ + Creation date. + """ + addedOn: DateTime + """ + ID of user who created the related work item. + """ + addedById: ID +} + +""" +Input to create a new related work item and associated with a version. +""" +input JiraAddRelatedWorkToVersionInput { + """ + The identifier of the Jira version. + """ + versionId: ID! + """ + Client-generated ID for the related work item. + """ + relatedWorkId: ID! + """ + Related work URL. + """ + url: URL! + """ + Related work title; can be null if user didn't enter a title when adding the link. + """ + title: String + """ + Category for the related work item. + """ + category: String! +} + +""" +Input to delete a related work item and unlink it from a version. +""" +input JiraRemoveRelatedWorkFromVersionInput { + """ + The identifier of the Jira version. + """ + versionId: ID! + """ + Client-generated ID for the related work item. + """ + relatedWorkId: ID! +} + +""" +The return payload of creating a new related work item and associating it with a version. +""" +type JiraAddRelatedWorkToVersionPayload implements Payload { + """ + Whether the mutation was successful or not. + """ + success: Boolean! + """ + A list of errors that occurred during the mutation. + """ + errors: [MutationError!] + """ + The newly added edge and associated data. + """ + relatedWorkEdge: JiraVersionRelatedWorkEdge +} + +""" +The return payload of deleting a related work item and unlinking it from a version. +""" +type JiraRemoveRelatedWorkFromVersionPayload implements Payload { + """ + Whether the mutation was successful or not. + """ + success: Boolean! + """ + A list of errors that occurred during the mutation. + """ + errors: [MutationError!] +} + +""" +Marketplace connect app iframe data for Version details page's top right corner extension +point(location: atl.jira.releasereport.top.right.panels) +If options is null, parsing string json into json object failed while mapping. +""" +type JiraVersionConnectAddonIframeData { + appKey: String + moduleKey: String + appName: String + location: String + options: JSON +} + +""" +The filter for a version's issues +""" +enum JiraVersionIssuesFilter { + ALL + TODO + IN_PROGRESS + DONE + UNREVIEWED_CODE + OPEN_REVIEW + OPEN_PULL_REQUEST + FAILING_BUILD +} + +""" +The status of a version field. +""" +enum JiraVersionStatus { + """ + Indicates the version is available to public + """ + RELEASED + """ + Indicates the version is not launched yet + """ + UNRELEASED + """ + Indicates the version is archived, no further changes can be made to this version unless it is un-archived + """ + ARCHIVED +} + +""" +The connection type for JiraVersion. +""" +type JiraVersionConnection { + """ + The total count of items in the connection. + """ + totalCount: Int + """ + Information about the current page. Used to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraVersionEdge] +} + +""" +An edge in a JiraVersion connection. +""" +type JiraVersionEdge { + """ + The node at the edge. + """ + node: JiraVersion + """ + The cursor to this edge. + """ + cursor: String! +} + +extend type JiraQuery { + "Get version by ARI" + version( + """ + The identifier of the Jira version + """ + id: ID! + ): JiraVersionResult + + """ + This field returns a connection over JiraVersion. + """ + versionsForProject( + """ + The identifier for the Jira project + """ + jiraProjectId: ID! + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + """ + The filter array dictates what versions to return by their status. + Defaults to unreleased versions only + """ + filter: [JiraVersionStatus] = [UNRELEASED] + ): JiraVersionConnection +} + +""" +The input to associate issues with a fix version +""" +input JiraAddIssuesToFixVersionInput { + """ + The issues to be associated with the fix version + """ + issueIds: [ID!]! + """ + The version to be associated with the issues + """ + versionId: ID! +} + +""" +The return payload of associating issues with a fix version +""" +type JiraAddIssuesToFixVersionPayload implements Payload { + """ + The updated version + """ + version: JiraVersion + """ + Whether the mutation was successful or not. + """ + success: Boolean! + """ + A list of errors that occurred during the mutation. + """ + errors: [MutationError!] +} + +""" +Contains either the successful fetched version information or an error. +""" +union JiraVersionResult = JiraVersion | QueryError + +""" +The warning config for version details page to generate warning report. Depending on tenant settings and providers installed, some warning config could be in NOT_APPLICABLE state. +""" +enum JiraVersionWarningConfigState { + ENABLED + DISABLED + NOT_APPLICABLE +} + +""" +The warning configuration to generate version details page warning report. +""" +type JiraVersionWarningConfig { + """ + The warnings for issues that has open pull request and in done issue status category. + """ + openPullRequest: JiraVersionWarningConfigState + """ + The warnings for issues that has open review and in done issue status category (only applicable for FishEye/Crucible integration to Jira). + """ + openReview: JiraVersionWarningConfigState + """ + The warnings for issues that has unreviewed code and in done issue status category. + """ + unreviewedCode: JiraVersionWarningConfigState + """ + The warnings for issues that has failing build and in done issue status category. + """ + failingBuild: JiraVersionWarningConfigState + """ + Whether the user requesting the warning config has edit permissions. + """ + canEdit: Boolean +} + +""" +The warning configuration to be updated for version details page warning report. +Applicable values will have their value updated. Null values will default to true. +""" +input JiraVersionUpdatedWarningConfigInput { + """ + The warnings for issues that has open pull request and in done issue status category. + """ + isOpenPullRequestEnabled: Boolean = true + """ + The warnings for issues that has open review(FishEye/Crucible integration) and in done issue status category. + """ + isOpenReviewEnabled: Boolean = true + """ + The warnings for issues that has unreviewed code and in done issue status category. + """ + isUnreviewedCodeEnabled: Boolean = true + """ + The warnings for issues that has failing build and in done issue status category. + """ + isFailingBuildEnabled: Boolean = true +} + +""" +The input to update the version details page warning report. +""" +input JiraUpdateVersionWarningConfigInput { + """ + The ARI of the Jira project. + """ + jiraProjectId: ID! + """ + The version configuration options to be updated. + """ + updatedVersionWarningConfig: JiraVersionUpdatedWarningConfigInput! +} + +type JiraUpdateVersionWarningConfigPayload implements Payload { + "Whether the mutation was successful or not." + success: Boolean! + + "A list of errors that occurred during the mutation." + errors: [MutationError!] +} + +extend type JiraMutation { + """ + Associate issues with a fix version + """ + addIssuesToFixVersion( + input: JiraAddIssuesToFixVersionInput! + ): JiraAddIssuesToFixVersionPayload + """ + Update version warning configuration by enabling/disabling warnings + for specific scenarios. + """ + updateVersionWarningConfig( + input: JiraUpdateVersionWarningConfigInput! + ): JiraUpdateVersionWarningConfigPayload + + """ + Create a related work item and link it to a version. + """ + addRelatedWorkToVersion( + input: JiraAddRelatedWorkToVersionInput! + ): JiraAddRelatedWorkToVersionPayload + + """ + Delete a related work item from a version. + """ + removeRelatedWorkFromVersion( + input: JiraRemoveRelatedWorkFromVersionInput! + ): JiraRemoveRelatedWorkFromVersionPayload + + """ + Update a version's name. + """ + updateVersionName( + input: JiraUpdateVersionNameInput! + ): JiraUpdateVersionPayload + + """ + Update a version's description. + """ + updateVersionDescription( + input: JiraUpdateVersionDescriptionInput! + ): JiraUpdateVersionPayload + + """ + Update a version's start date. + """ + updateVersionStartDate( + input: JiraUpdateVersionStartDateInput! + ): JiraUpdateVersionPayload + + """ + Update a version's release date. + """ + updateVersionReleaseDate( + input: JiraUpdateVersionReleaseDateInput! + ): JiraUpdateVersionPayload +} +""" +A list of issues and JQL that results the list of issues. +""" +type JiraVersionDetailPageIssues { + """ + JQL that is used to list issues + """ + jql: String + """ + Issues returned by the provided JQL query + """ + issues( + """ + The number of items after the cursor to be returned in a forward page. + If not specified, it is up to the server to determine a page size. + """ + first: Int + """ + The index based cursor to specify the beginning of the items. + If not specified it's assumed as the cursor for the item before the beginning. + """ + after: String + """ + The number of items before the cursor to be returned in a backward page. + If not specified, it is up to the server to determine a page size. + """ + last: Int + """ + The index based cursor to specify the bottom limit of the items. + If not specified it's assumed as the cursor to the item after the last item. + """ + before: String + ): JiraIssueConnection +} + +extend type JiraQuery { + """ + Contains the lists of issues per table and the warning config for the version detail page under Releases home page. + """ + versionDetailPage(versionId: ID!): JiraVersionDetailPage @deprecated(reason:"use the fields that is used to live under this type from JiraVersion instead. It is simply migrated.") +} + +""" +This type holds specific information for version details page holding warning config for the version and issues for each category. +""" +type JiraVersionDetailPage { + """ + Warning config of the version. This is per project setting. + """ + warningConfig: JiraVersionWarningConfig + """ + List of issues and its JQL, that have failing build, and its status is in done issue status category. + """ + failingBuildIssues: JiraVersionDetailPageIssues + """ + List of issues and its JQL, that have open pull request, and its status is in done issue status category. + """ + openPullRequestIssues: JiraVersionDetailPageIssues + """ + List of issues and its JQL, that have commits that are not a part of pull request, and its status is in done issue status category. + """ + unreviewedCodeIssues: JiraVersionDetailPageIssues + """ + List of issues and its JQL, that are in to-do issue status category. + """ + toDoIssues: JiraVersionDetailPageIssues + """ + List of issues and its JQL, that are in-progress issue status category. + """ + inProgressIssues: JiraVersionDetailPageIssues + """ + List of issues and its JQL, that are done issue status category. + """ + doneIssues: JiraVersionDetailPageIssues + """ + List of issues and its JQL, that have the given version as its fixed version. + """ + allIssues: JiraVersionDetailPageIssues +} +""" +Represents the votes information of an Issue. +""" +type JiraVote { + """ + Indicates whether the current user has voted for this Issue. + """ + hasVoted: Boolean + """ + Count of users who have voted for this Issue. + """ + count: Long +} +""" +Represents the watches information. +""" +type JiraWatch { + """ + Indicates whether the current user is watching this issue. + """ + isWatching: Boolean + """ + Count of users who are watching this issue. + """ + count: Long +}""" +Represents a WorkCategory. +""" +type JiraWorkCategory { + """ + The value of the WorkCategory. + """ + value: String +}""" +Represents a Jira worklog. +""" +type JiraWorklog implements Node { + """ + Global identifier for the worklog. + """ + id: ID! + """ + Identifier for the worklog. + """ + worklogId: ID! + """ + User profile of the original worklog author. + """ + author: User + """ + User profile of the author performing the worklog update. + """ + updateAuthor: User + """ + Time spent displays the amount of time logged working on the issue so far. + """ + timeSpent: JiraEstimate + """ + Time Remaining displays the amount of time currently anticipated to resolve the issue. + """ + remainingEstimate: JiraEstimate + """ + Time of worklog creation. + """ + created: DateTime! + """ + Time of last worklog update. + """ + updated: DateTime + """ + Date and time when this unit of work was started. + """ + startDate: DateTime + """ + Either the group or the project role associated with this worklog, but not both. + Null means the permission level is unspecified, i.e. the worklog is public. + """ + permissionLevel: JiraPermissionLevel + """ + Description related to the achieved work. + """ + workDescription: JiraRichText +} + +""" +The connection type for JiraWorklog. +""" +type JiraWorkLogConnection { + """ + The approximate count of items in the connection. + """ + indicativeCount: Int + """ + The page info of the current page of results. + """ + pageInfo: PageInfo! + """ + A list of edges in the current page. + """ + edges: [JiraWorkLogEdge] +} + +""" +An edge in a JiraWorkLog connection. +""" +type JiraWorkLogEdge { + """ + The node at the the edge. + """ + node: JiraWorklog + """ + The cursor to this edge. + """ + cursor: String! +} +""" + AGG requirement - The combination of all *.graphqls in the directory need to be self contained. + So all the Dependencies from base schema need to be copied over here +""" +scalar URL +scalar DateTime +scalar Date +scalar Long +scalar JSON + +type Query { + """ + this field is added to enable self governed onboarding of Jira GraphQL types to AGG + see https://hello.atlassian.net/wiki/spaces/PSRV/pages/1010287708/Announcing+self+governed+APIs for more details + """ + jira: JiraQuery + + node(id: ID!): Node +} + +"Standard Relay node interface" +interface Node { + "The id of the node" + id: ID! +} + +type PageInfo { + """ + `true` if having more items when navigating forward + """ + hasNextPage: Boolean! + """ + `true` if having more items when navigating backward + """ + hasPreviousPage: Boolean! + """ + When paginating backwards, the cursor to continue. + """ + startCursor: String + """ + When paginating forwards, the cursor to continue. + """ + endCursor: String +} + +interface QueryErrorExtension { + """ + A numerical code (such as an HTTP status code) representing the error category. + """ + statusCode: Int + + """ + A code representing the type of error. See the CompassErrorType enum for possible values. + """ + errorType: String +} + +type QueryError { + """ + The ID of the requested object, or null when the ID is not available. + """ + identifier: ID + + """ + A message describing the error. + """ + message: String + + """ + Contains extra data describing the error. + """ + extensions: [QueryErrorExtension!] +} + +""" +A very generic query error extension type with no additional fields specific to service. +""" +type GenericQueryErrorExtension implements QueryErrorExtension { + "A numerical code (such as a HTTP status code) representing the error category" + statusCode: Int + "Application specific error type" + errorType: String +} + +""" +The payload represents the mutation response structure. +It represents both success and error responses. +""" +interface Payload { + "The success field returns true if operation is successful. Otherwise, false." + success: Boolean! + """ + A bounded list of one or more mutation error information in case of unsuccessful execution. + If success field value is false, then errors field may offer additional information. + """ + errors: [MutationError!] +} + +""" +It represents mutation operation error details. +""" +type MutationError { + "The error message related to mutation operation" + message: String + "An extension to mutation error representing more details about the mutation error such as application specific codes and error types" + extensions : MutationErrorExtension +} + +""" +An extension to mutation error information to offer application specific error codes and error types. +It helps to pinpoint and classify the error response. +""" +interface MutationErrorExtension { + """ + A numerical code (example: HTTP status code) representing the error category + For example: 412 for operation preconditions failure. + """ + statusCode: Int + """ + Application specific error type in the readable format. + For example: unable to process request because application is at an illegal state. + """ + errorType: String +} + +""" +A very generic mutation error extension type with no additional fields specific to service. +""" +type GenericMutationErrorExtension implements MutationErrorExtension { + """ + A numerical code (example: HTTP status code) representing the error category + For example: 412 for operation preconditions failure. + """ + statusCode: Int + """ + Application specific error type in the readable format. + For example: unable to process request because application is at an illegal state. + """ + errorType: String +}""" + AGG requirement - The combination of all *.graphqls in the directory need to be self contained. +So all gira Dependencies from identity schema need to be copied over here +""" + +interface User { + accountId: ID! + canonicalAccountId: ID! + accountStatus: AccountStatus! + name: String! + picture: URL! +} + +enum AccountStatus { + active + inactive + closed +} + +type AtlassianAccountUser implements User { + accountId: ID! + canonicalAccountId: ID! + accountStatus: AccountStatus! + name: String! + picture: URL! + email: String + zoneinfo: String + locale: String +} \ No newline at end of file diff --git a/src/test/resources/introspection/1509-first-bug-data.json b/src/test/resources/introspection/1509-first-bug-data.json new file mode 100644 index 0000000000..a7a50bd75a --- /dev/null +++ b/src/test/resources/introspection/1509-first-bug-data.json @@ -0,0 +1,56643 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": { + "name": "Mutation" + }, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Represents `true` or `false` values.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": "The query root of GitHub's GraphQL interface.", + "fields": [ + { + "name": "codeOfConduct", + "description": "Look up a code of conduct by its key", + "args": [ + { + "name": "key", + "description": "The code of conduct's key", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CodeOfConduct", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "codesOfConduct", + "description": "Look up a code of conduct by its key", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CodeOfConduct", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "license", + "description": "Look up an open source license by its key", + "args": [ + { + "name": "key", + "description": "The license's downcased SPDX ID", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "License", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "licenses", + "description": "Return a list of known open source licenses", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "License", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "marketplaceCategories", + "description": "Get alphabetically sorted list of Marketplace categories", + "args": [ + { + "name": "includeCategories", + "description": "Return only the specified categories.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "excludeEmpty", + "description": "Exclude categories with no listings.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "excludeSubcategories", + "description": "Returns top level categories only, excluding any subcategories.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MarketplaceCategory", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "marketplaceCategory", + "description": "Look up a Marketplace category by its slug.", + "args": [ + { + "name": "slug", + "description": "The URL slug of the category.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "useTopicAliases", + "description": "Also check topic aliases for the category slug", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "MarketplaceCategory", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "marketplaceListing", + "description": "Look up a single Marketplace listing", + "args": [ + { + "name": "slug", + "description": "Select the listing that matches this slug. It's the short name of the listing used in its URL.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "MarketplaceListing", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "marketplaceListings", + "description": "Look up Marketplace listings", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "categorySlug", + "description": "Select only listings with the given category.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "useTopicAliases", + "description": "Also check topic aliases for the category slug", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "viewerCanAdmin", + "description": "Select listings to which user has admin access. If omitted, listings visible to the\nviewer are returned.\n", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "adminId", + "description": "Select listings that can be administered by the specified user.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "organizationId", + "description": "Select listings for products owned by the specified organization.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "allStates", + "description": "Select listings visible to the viewer even if they are not approved. If omitted or\nfalse, only approved listings will be returned.\n", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "slugs", + "description": "Select the listings with these slugs, if they are visible to the viewer.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "primaryCategoryOnly", + "description": "Select only listings where the primary category matches the given category slug.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "withFreeTrialsOnly", + "description": "Select only listings that offer a free trial.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MarketplaceListingConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "meta", + "description": "Return information about the GitHub instance", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GitHubMetadata", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "Fetches an object given its ID.", + "args": [ + { + "name": "id", + "description": "ID of the object.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "Lookup nodes by a list of IDs.", + "args": [ + { + "name": "ids", + "description": "The list of node IDs.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organization", + "description": "Lookup a organization by login.", + "args": [ + { + "name": "login", + "description": "The organization's login.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rateLimit", + "description": "The client's rate limit information.", + "args": [ + { + "name": "dryRun", + "description": "If true, calculate the cost for the query without evaluating it", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "OBJECT", + "name": "RateLimit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "relay", + "description": "Hack to workaround https://github.com/facebook/relay/issues/112 re-exposing the root query object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Query", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "Lookup a given repository by the owner and repository name.", + "args": [ + { + "name": "owner", + "description": "The login field of a user or organization", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of the repository", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoryOwner", + "description": "Lookup a repository owner (ie. either a User or an Organization) by login.", + "args": [ + { + "name": "login", + "description": "The username to lookup the owner by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resource", + "description": "Lookup resource by a URL.", + "args": [ + { + "name": "url", + "description": "The URL.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "search", + "description": "Perform a search across resources.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "query", + "description": "The search string to look for.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "type", + "description": "The types of search items to search within.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SearchType", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SearchResultItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "securityAdvisories", + "description": "GitHub Security Advisories", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for the returned topics.", + "type": { + "kind": "INPUT_OBJECT", + "name": "SecurityAdvisoryOrder", + "ofType": null + }, + "defaultValue": "{field:UPDATED_AT,direction:DESC}" + }, + { + "name": "identifier", + "description": "Filter advisories by identifier, e.g. GHSA or CVE.", + "type": { + "kind": "INPUT_OBJECT", + "name": "SecurityAdvisoryIdentifierFilter", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "publishedSince", + "description": "Filter advisories to those published since a time in the past.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "updatedSince", + "description": "Filter advisories to those updated since a time in the past.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "securityAdvisory", + "description": "Fetch a Security Advisory by its GHSA ID", + "args": [ + { + "name": "ghsaId", + "description": "GitHub Security Advisory ID.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "SecurityAdvisory", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "securityVulnerabilities", + "description": "Software Vulnerabilities documented by GitHub Security Advisories", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for the returned topics.", + "type": { + "kind": "INPUT_OBJECT", + "name": "SecurityVulnerabilityOrder", + "ofType": null + }, + "defaultValue": "{field:UPDATED_AT,direction:DESC}" + }, + { + "name": "ecosystem", + "description": "An ecosystem to filter vulnerabilities by.", + "type": { + "kind": "ENUM", + "name": "SecurityAdvisoryEcosystem", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "package", + "description": "A package name to filter vulnerabilities by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "severities", + "description": "A list of severities to filter vulnerabilities by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisorySeverity", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityVulnerabilityConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "topic", + "description": "Look up a topic by name.", + "args": [ + { + "name": "name", + "description": "The topic's name.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "Lookup a user by login.", + "args": [ + { + "name": "login", + "description": "The user's login.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewer", + "description": "The currently authenticated user.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Node", + "description": "An object with an ID.", + "fields": [ + { + "name": "id", + "description": "ID of the object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "AddedToProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AssignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "BaseRefChangedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "BaseRefForcePushedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Blob", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Bot", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CodeOfConduct", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommentDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommitCommentThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ConvertedNoteToIssueEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DemilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeployKey", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeployedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Deployment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeploymentEnvironmentChangedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeploymentStatus", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ExternalIdentity", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefForcePushedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefRestoredEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Label", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Language", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "License", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceCategory", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceListing", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MentionedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MergedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MovedColumnsInProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "OrganizationIdentityProvider", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "OrganizationInvitation", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PinnedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ProjectCard", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PublicKey", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommitCommentThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PushAllowance", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Reaction", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Release", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReleaseAsset", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RemovedFromProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RenamedTitleEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReopenedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RepositoryInvitation", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RepositoryTopic", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissalAllowance", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestRemovedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisory", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Status", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "StatusContext", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Tag", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "TransferredEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Tree", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnassignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnpinnedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnsubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserBlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserContentEdit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserStatus", + "ofType": null + } + ] + }, + { + "kind": "SCALAR", + "name": "ID", + "description": "Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "description": "Represents a type that can be retrieved by a URL.", + "fields": [ + { + "name": "resourcePath", + "description": "The HTML path to this resource.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The URL to this resource.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Bot", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MergedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Release", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RepositoryTopic", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "SCALAR", + "name": "URI", + "description": "An RFC 3986, RFC 3987, and RFC 6570 (level 4) compliant URI string.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "User", + "description": "A user is an individual's account on GitHub that owns repositories and can make new content.", + "fields": [ + { + "name": "anyPinnableItems", + "description": "Determine if this repository owner has any items that can be pinned to their profile.", + "args": [ + { + "name": "type", + "description": "Filter to only a particular kind of pinnable item.", + "type": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "avatarUrl", + "description": "A URL pointing to the user's public avatar.", + "args": [ + { + "name": "size", + "description": "The size of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bio", + "description": "The user's public profile bio.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bioHTML", + "description": "The user's public profile bio as HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitComments", + "description": "A list of commit comments made by this user.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "company", + "description": "The user's public profile company.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "companyHTML", + "description": "The user's public profile company as HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "contributionsCollection", + "description": "The collection of contributions this user has made to different repositories.", + "args": [ + { + "name": "organizationID", + "description": "The ID of the organization used to filter contributions.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "from", + "description": "Only contributions made at this time or later will be counted. If omitted, defaults to a year ago.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "to", + "description": "Only contributions made before and up to and including this time will be counted. If omitted, defaults to the current time.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ContributionsCollection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "email", + "description": "The user's publicly visible profile email.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "followers", + "description": "A list of users the given user is followed by.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "FollowerConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "following", + "description": "A list of users the given user is following.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "FollowingConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "gist", + "description": "Find gist by repo name.", + "args": [ + { + "name": "name", + "description": "The gist name to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "gistComments", + "description": "A list of gist comments made by this user.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "gists", + "description": "A list of the Gists the user has created.", + "args": [ + { + "name": "privacy", + "description": "Filters Gists according to privacy.", + "type": { + "kind": "ENUM", + "name": "GistPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for gists returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "GistOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isBountyHunter", + "description": "Whether or not this user is a participant in the GitHub Security Bug Bounty.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isCampusExpert", + "description": "Whether or not this user is a participant in the GitHub Campus Experts Program.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeveloperProgramMember", + "description": "Whether or not this user is a GitHub Developer Program member.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isEmployee", + "description": "Whether or not this user is a GitHub employee.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isHireable", + "description": "Whether or not the user has marked themselves as for hire.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isSiteAdmin", + "description": "Whether or not this user is a site administrator.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isViewer", + "description": "Whether or not this user is the viewing user.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issueComments", + "description": "A list of issue comments made by this user.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issues", + "description": "A list of issues associated with this user.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the issues by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "filterBy", + "description": "Filtering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueFilters", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "itemShowcase", + "description": "Showcases a selection of repositories and gists that the profile owner has either curated or that have been selected automatically based on popularity.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProfileItemShowcase", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "location", + "description": "The user's public profile location.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "login", + "description": "The username used to login.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The user's public profile name.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organization", + "description": "Find an organization by its login that the user belongs to.", + "args": [ + { + "name": "login", + "description": "The login of the organization to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organizations", + "description": "A list of organizations the user belongs to.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "OrganizationConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnableItems", + "description": "A list of repositories and gists this profile owner can pin to their profile.", + "args": [ + { + "name": "types", + "description": "Filter the types of pinnable items that are returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedItems", + "description": "A list of repositories and gists this profile owner has pinned to their profile", + "args": [ + { + "name": "types", + "description": "Filter the types of pinned items that are returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedItemsRemaining", + "description": "Returns how many more items this profile owner can pin to their profile.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedRepositories", + "description": "A list of repositories this user has pinned to their profile", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "pinnedRepositories will be removed Use ProfileOwner.pinnedItems instead. Removal on 2019-07-01 UTC." + }, + { + "name": "project", + "description": "Find project by number.", + "args": [ + { + "name": "number", + "description": "The project number to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projects", + "description": "A list of projects under the owner.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for projects returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProjectOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "search", + "description": "Query to search projects by, currently only searching by name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the projects by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsResourcePath", + "description": "The HTTP path listing user's projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsUrl", + "description": "The HTTP URL listing user's projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publicKeys", + "description": "A list of public keys associated with this user.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PublicKeyConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequests", + "description": "A list of pull requests associated with this user.", + "args": [ + { + "name": "states", + "description": "A list of states to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "headRefName", + "description": "The head ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The base ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for pull requests returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositories", + "description": "A list of repositories that the user owns.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "isFork", + "description": "If non-null, filters repositories according to whether they are forks of another repository", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoriesContributedTo", + "description": "A list of repositories that the user recently contributed to.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "includeUserRepositories", + "description": "If true, include user repositories", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "contributionTypes", + "description": "If non-null, include only the specified types of contributions. The GitHub.com UI uses [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryContributionType", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "Find Repository.", + "args": [ + { + "name": "name", + "description": "Name of Repository to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this user", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "starredRepositories", + "description": "Repositories the user has starred.", + "args": [ + { + "name": "ownedByViewer", + "description": "Filters starred repositories to only return repositories owned by the viewer.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "StarOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StarredRepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "status", + "description": "The user's description of what they're currently doing.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "UserStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this user", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanChangePinnedItems", + "description": "Can the viewer pin repositories and gists to the profile?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanCreateProjects", + "description": "Can the current viewer create new projects on this owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanFollow", + "description": "Whether or not the viewer is able to follow the user.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerIsFollowing", + "description": "Whether or not this user is followed by the viewer.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "watching", + "description": "A list of repositories the given user is watching.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Affiliation options for repositories returned from the connection", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR, ORGANIZATION_MEMBER]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "websiteUrl", + "description": "A URL pointing to the user's public website/blog.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageSearch", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "ProjectOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "ProfileOwner", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Actor", + "description": "Represents an object which can take actions on GitHub. Typically a User or Bot.", + "fields": [ + { + "name": "avatarUrl", + "description": "A URL pointing to the actor's public avatar.", + "args": [ + { + "name": "size", + "description": "The size of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "login", + "description": "The username of the actor.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this actor.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this actor.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Bot", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "SCALAR", + "name": "Int", + "description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PageInfo", + "description": "Information about pagination in a connection.", + "fields": [ + { + "name": "endCursor", + "description": "When paginating forwards, the cursor to continue.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasNextPage", + "description": "When paginating forwards, are there more items?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasPreviousPage", + "description": "When paginating backwards, are there more items?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startCursor", + "description": "When paginating backwards, the cursor to continue.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "DateTime", + "description": "An ISO-8601 encoded UTC date string.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageOwner", + "description": "Represents an owner of a registry package.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "Repository", + "description": "A repository contains the content for a project.", + "fields": [ + { + "name": "assignableUsers", + "description": "A list of users that can be assigned to issues in this repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "branchProtectionRules", + "description": "A list of branch protection rules for this repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BranchProtectionRuleConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "codeOfConduct", + "description": "Returns the code of conduct for this repository", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CodeOfConduct", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "collaborators", + "description": "A list of collaborators associated with the repository.", + "args": [ + { + "name": "affiliation", + "description": "Collaborators affiliation level with a repository.", + "type": { + "kind": "ENUM", + "name": "CollaboratorAffiliation", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RepositoryCollaboratorConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitComments", + "description": "A list of commit comments associated with the repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "defaultBranchRef", + "description": "The Ref associated with the repository's default branch.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deployKeys", + "description": "A list of deploy keys that are on this repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeployKeyConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deployments", + "description": "Deployments associated with the repository", + "args": [ + { + "name": "environments", + "description": "Environments to list deployments for", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for deployments returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DeploymentOrder", + "ofType": null + }, + "defaultValue": "{field:CREATED_AT,direction:ASC}" + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeploymentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The description of the repository.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "descriptionHTML", + "description": "The description of the repository rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "diskUsage", + "description": "The number of kilobytes this repository occupies on disk.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "forkCount", + "description": "Returns how many forks there are of this repository in the whole network.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "forks", + "description": "A list of direct forked repositories.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasIssuesEnabled", + "description": "Indicates if the repository has issues feature enabled.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasWikiEnabled", + "description": "Indicates if the repository has wiki feature enabled.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "homepageUrl", + "description": "The repository's URL.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isArchived", + "description": "Indicates if the repository is unmaintained.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDisabled", + "description": "Returns whether or not this repository disabled.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isFork", + "description": "Identifies if the repository is a fork.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isLocked", + "description": "Indicates if the repository has been locked or not.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isMirror", + "description": "Identifies if the repository is a mirror.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPrivate", + "description": "Identifies if the repository is private.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "Returns a single issue from the current repository by number.", + "args": [ + { + "name": "number", + "description": "The number for the issue to be returned.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issueOrPullRequest", + "description": "Returns a single issue-like object from the current repository by number.", + "args": [ + { + "name": "number", + "description": "The number for the issue to be returned.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "UNION", + "name": "IssueOrPullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issues", + "description": "A list of issues that have been opened in the repository.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the issues by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "filterBy", + "description": "Filtering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueFilters", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "label", + "description": "Returns a single label by name", + "args": [ + { + "name": "name", + "description": "Label name", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Label", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labels", + "description": "A list of labels associated with the repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "query", + "description": "If provided, searches labels by name and description.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LabelConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "languages", + "description": "A list containing a breakdown of the language composition of the repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "LanguageOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LanguageConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "licenseInfo", + "description": "The license associated with the repository", + "args": [], + "type": { + "kind": "OBJECT", + "name": "License", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockReason", + "description": "The reason the repository has been locked.", + "args": [], + "type": { + "kind": "ENUM", + "name": "RepositoryLockReason", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mentionableUsers", + "description": "A list of Users that can be mentioned in the context of the repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergeCommitAllowed", + "description": "Whether or not PRs are merged with a merge commit on this repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "milestone", + "description": "Returns a single milestone from the current repository by number.", + "args": [ + { + "name": "number", + "description": "The number for the milestone to be returned.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "milestones", + "description": "A list of milestones associated with the repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "Filter by the state of the milestones.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "MilestoneState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for milestones.", + "type": { + "kind": "INPUT_OBJECT", + "name": "MilestoneOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "MilestoneConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mirrorUrl", + "description": "The repository's original mirror URL.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name of the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nameWithOwner", + "description": "The repository's name with owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "object", + "description": "A Git object in the repository", + "args": [ + { + "name": "oid", + "description": "The Git object ID", + "type": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "expression", + "description": "A Git revision expression suitable for rev-parse", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "owner", + "description": "The User owner of the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "parent", + "description": "The repository parent, if this is a fork.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "primaryLanguage", + "description": "The primary language of the repository's code.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Language", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "Find project by number.", + "args": [ + { + "name": "number", + "description": "The project number to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projects", + "description": "A list of projects under the owner.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for projects returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProjectOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "search", + "description": "Query to search projects by, currently only searching by name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the projects by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsResourcePath", + "description": "The HTTP path listing the repository's projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsUrl", + "description": "The HTTP URL listing the repository's projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "Returns a single pull request from the current repository by number.", + "args": [ + { + "name": "number", + "description": "The number for the pull request to be returned.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequests", + "description": "A list of pull requests that have been opened in the repository.", + "args": [ + { + "name": "states", + "description": "A list of states to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "headRefName", + "description": "The head ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The base ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for pull requests returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pushedAt", + "description": "Identifies when the repository was last pushed to.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "rebaseMergeAllowed", + "description": "Whether or not rebase-merging is enabled on this repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ref", + "description": "Fetch a given ref from the repository", + "args": [ + { + "name": "qualifiedName", + "description": "The ref to retrieve. Fully qualified matches are checked in order (`refs/heads/master`) before falling back onto checks for short name matches (`master`).", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "refs", + "description": "Fetch a list of refs from the repository", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "refPrefix", + "description": "A ref name prefix like `refs/heads/`, `refs/tags/`, etc.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "DEPRECATED: use orderBy. The ordering direction.", + "type": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for refs returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "RefOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RefConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "release", + "description": "Lookup a single release given various criteria.", + "args": [ + { + "name": "tagName", + "description": "The name of the Tag the Release was created from", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Release", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "releases", + "description": "List of releases which are dependent on this repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReleaseOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReleaseConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoryTopics", + "description": "A list of applied repository-topic associations for this repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryTopicConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this repository", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shortDescriptionHTML", + "description": "A description of the repository, rendered to HTML without any links in it.", + "args": [ + { + "name": "limit", + "description": "How many characters to return.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "200" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "squashMergeAllowed", + "description": "Whether or not squash-merging is enabled on this repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sshUrl", + "description": "The SSH URL to clone this repository", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitSSHRemote", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stargazers", + "description": "A list of users who have starred this starrable.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "StarOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StargazerConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this repository", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanAdminister", + "description": "Indicates whether the viewer has admin permissions on this repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanCreateProjects", + "description": "Can the current viewer create new projects on this owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanSubscribe", + "description": "Check if the viewer is able to change their subscription status for the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdateTopics", + "description": "Indicates whether the viewer can update the topics of this repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasStarred", + "description": "Returns a boolean indicating whether the viewing user has starred this starrable.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerPermission", + "description": "The users permission level on the repository. Will return null if authenticated as an GitHub App.", + "args": [], + "type": { + "kind": "ENUM", + "name": "RepositoryPermission", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerSubscription", + "description": "Identifies if the viewer is watching, not watching, or ignoring the subscribable entity.", + "args": [], + "type": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "watchers", + "description": "A list of users watching the repository.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "ProjectOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Starrable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryInfo", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "ProjectOwner", + "description": "Represents an owner of a Project.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "Find project by number.", + "args": [ + { + "name": "number", + "description": "The project number to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projects", + "description": "A list of projects under the owner.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for projects returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProjectOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "search", + "description": "Query to search projects by, currently only searching by name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the projects by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsResourcePath", + "description": "The HTTP path listing owners projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsUrl", + "description": "The HTTP URL listing owners projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanCreateProjects", + "description": "Can the current viewer create new projects on this owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "Project", + "description": "Projects manage issues, pull requests and notes within a project owner.", + "fields": [ + { + "name": "body", + "description": "The project's description body.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The projects description body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closed", + "description": "`true` if the object is closed (definition of closed may depend on type)", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closedAt", + "description": "Identifies the date and time when the object was closed.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "columns", + "description": "List of columns in the project", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectColumnConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "The actor who originally created the project.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The project's name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "number", + "description": "The project's number.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "owner", + "description": "The project's owner. Currently limited to repositories, organizations, and users.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "ProjectOwner", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pendingCards", + "description": "List of pending cards in this project", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "archivedStates", + "description": "A list of archived states to filter the cards by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectCardArchivedState", + "ofType": null + } + }, + "defaultValue": "[ARCHIVED, NOT_ARCHIVED]" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectCardConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this project", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Whether the project is open or closed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this project", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Closable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Closable", + "description": "An object that can be closed", + "fields": [ + { + "name": "closed", + "description": "`true` if the object is closed (definition of closed may depend on type)", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closedAt", + "description": "Identifies the date and time when the object was closed.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "description": "Entities that can be updated.", + "fields": [ + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "ProjectState", + "description": "State of the project; either 'open' or 'closed'", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OPEN", + "description": "The project is open.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CLOSED", + "description": "The project is closed.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "HTML", + "description": "A string containing HTML code.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectColumnConnection", + "description": "The connection type for ProjectColumn.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectColumnEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectColumnEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectColumn", + "description": "A column inside a project.", + "fields": [ + { + "name": "cards", + "description": "List of cards in the column", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "archivedStates", + "description": "A list of archived states to filter the cards by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectCardArchivedState", + "ofType": null + } + }, + "defaultValue": "[ARCHIVED, NOT_ARCHIVED]" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectCardConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The project column's name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The project that contains this column.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "purpose", + "description": "The semantic purpose of the column", + "args": [], + "type": { + "kind": "ENUM", + "name": "ProjectColumnPurpose", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this project column", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this project column", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ProjectColumnPurpose", + "description": "The semantic purpose of the column - todo, in progress, or done.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "TODO", + "description": "The column contains cards still to be worked on", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "IN_PROGRESS", + "description": "The column contains cards which are currently being worked on", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DONE", + "description": "The column contains cards which are complete", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectCardConnection", + "description": "The connection type for ProjectCard.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectCardEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectCard", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectCardEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectCard", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectCard", + "description": "A card in a project.", + "fields": [ + { + "name": "column", + "description": "The project column this card is associated under. A card may only belong to one\nproject column at a time. The column field will be null if the card is created\nin a pending state and has yet to be associated with a column. Once cards are\nassociated with a column, they will not become pending in the future.\n", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "content", + "description": "The card content item", + "args": [], + "type": { + "kind": "UNION", + "name": "ProjectCardItem", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "The actor who created this card", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isArchived", + "description": "Whether the card is archived", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "note", + "description": "The card note", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The project that contains this card.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this card", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The state of ProjectCard", + "args": [], + "type": { + "kind": "ENUM", + "name": "ProjectCardState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this card", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ProjectCardState", + "description": "Various content states of a ProjectCard", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CONTENT_ONLY", + "description": "The card has content only.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOTE_ONLY", + "description": "The card has a note only.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REDACTED", + "description": "The card is redacted.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "ProjectCardItem", + "description": "Types that can be inside Project Cards.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "Issue", + "description": "An Issue is a place to discuss ideas, enhancements, tasks, and bugs for a project.", + "fields": [ + { + "name": "activeLockReason", + "description": "Reason that the conversation was locked.", + "args": [], + "type": { + "kind": "ENUM", + "name": "LockReason", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "assignees", + "description": "A list of Users assigned to this object.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "Identifies the body of the issue.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "Identifies the body of the issue rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "Identifies the body of the issue rendered to text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closed", + "description": "`true` if the object is closed (definition of closed may depend on type)", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closedAt", + "description": "Identifies the date and time when the object was closed.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "comments", + "description": "A list of comments associated with the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labels", + "description": "A list of labels associated with the object.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LabelConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locked", + "description": "`true` if the object is locked", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "milestone", + "description": "Identifies the milestone associated with the issue.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "number", + "description": "Identifies the issue number.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "participants", + "description": "A list of Users that are participating in the Issue conversation.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectCards", + "description": "List of project cards associated with this issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "archivedStates", + "description": "A list of archived states to filter the cards by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectCardArchivedState", + "ofType": null + } + }, + "defaultValue": "[ARCHIVED, NOT_ARCHIVED]" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectCardConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this issue", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Identifies the state of the issue.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timeline", + "description": "A list of events, comments, commits, etc. associated with the issue.", + "args": [ + { + "name": "since", + "description": "Allows filtering timeline events by a `since` timestamp.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueTimelineConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timelineItems", + "description": "A list of events, comments, commits, etc. associated with the issue.", + "args": [ + { + "name": "since", + "description": "Filter timeline items by a `since` timestamp.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "skip", + "description": "Skips the first _n_ elements in the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "itemTypes", + "description": "Filter timeline items by type.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueTimelineItemsItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueTimelineItemsConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "Identifies the issue title.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this issue", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanSubscribe", + "description": "Check if the viewer is able to change their subscription status for the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerSubscription", + "description": "Identifies if the viewer is watching, not watching, or ignoring the subscribable entity.", + "args": [], + "type": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Assignable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Closable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Lockable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Assignable", + "description": "An object that can have users assigned to it.", + "fields": [ + { + "name": "assignees", + "description": "A list of Users assigned to this object.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "UserConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UserEdge", + "description": "Represents a user.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "description": "Represents a comment.", + "fields": [ + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "The body as Markdown.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The body rendered to text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "description": "A list of edits to content.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserContentEditEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserContentEdit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UserContentEditEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "UserContentEdit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UserContentEdit", + "description": "An edit on user content", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletedAt", + "description": "Identifies the date and time when the object was deleted.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletedBy", + "description": "The actor who deleted this content", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "diff", + "description": "A summary of the changes for this edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editedAt", + "description": "When this content was edited", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited this content", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "description": "A comment author association with repository.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "MEMBER", + "description": "Author is a member of the organization that owns the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OWNER", + "description": "Author is the owner of the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COLLABORATOR", + "description": "Author has been invited to collaborate on the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CONTRIBUTOR", + "description": "Author has previously committed to the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIRST_TIME_CONTRIBUTOR", + "description": "Author has not previously committed to the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIRST_TIMER", + "description": "Author has not previously committed to GitHub.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NONE", + "description": "Author has no association with the repository.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "description": "Comments that can be updated.", + "fields": [ + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "description": "The possible errors that will prevent a user from updating a comment.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "INSUFFICIENT_ACCESS", + "description": "You must be the author or have write access to this repository to update this comment.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LOCKED", + "description": "Unable to create comment because issue is locked.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LOGIN_REQUIRED", + "description": "You must be logged in to update this comment.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MAINTENANCE", + "description": "Repository is under maintenance.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "VERIFIED_EMAIL_REQUIRED", + "description": "At least one email address must be verified to update this comment.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DENIED", + "description": "You cannot update this comment", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Labelable", + "description": "An object that can have labels assigned to it.", + "fields": [ + { + "name": "labels", + "description": "A list of labels associated with the object.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LabelConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "LabelConnection", + "description": "The connection type for Label.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LabelEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Label", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LabelEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Label", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Label", + "description": "A label for categorizing Issues or Milestones with a given Repository.", + "fields": [ + { + "name": "color", + "description": "Identifies the label color.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the label was created.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "A brief description of this label.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDefault", + "description": "Indicates whether or not this is a default label.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issues", + "description": "A list of issues associated with this label.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the issues by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "filterBy", + "description": "Filtering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueFilters", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Identifies the label name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequests", + "description": "A list of pull requests associated with this label.", + "args": [ + { + "name": "states", + "description": "A list of states to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "headRefName", + "description": "The head ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The base ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for pull requests returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this label.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this label.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the label was last updated.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this label.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueConnection", + "description": "The connection type for Issue.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "description": "Ways in which lists of issues can be ordered upon return.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order issues by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order issues by the specified field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "IssueOrderField", + "description": "Properties by which issue connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order issues by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order issues by update time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMMENTS", + "description": "Order issues by comment count", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "OrderDirection", + "description": "Possible directions in which to order a list of items when provided an `orderBy` argument.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ASC", + "description": "Specifies an ascending order for a given `orderBy` argument.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DESC", + "description": "Specifies a descending order for a given `orderBy` argument.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "IssueState", + "description": "The possible states of an issue.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OPEN", + "description": "An issue that is still open", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CLOSED", + "description": "An issue that has been closed", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "IssueFilters", + "description": "Ways in which to filter lists of issues.", + "fields": null, + "inputFields": [ + { + "name": "assignee", + "description": "List issues assigned to given name. Pass in `null` for issues with no assigned user, and `*` for issues assigned to any user.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "createdBy", + "description": "List issues created by given name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "List issues where the list of label names exist on the issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "mentioned", + "description": "List issues where the given name is mentioned in the issue.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "milestone", + "description": "List issues by given milestone argument. If an string representation of an integer is passed, it should refer to a milestone by its number field. Pass in `null` for issues with no milestone, and `*` for issues that are assigned to any milestone.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "since", + "description": "List issues that have been updated at or after the given date.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "List issues filtered by the list of states given.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "viewerSubscribed", + "description": "List issues subscribed to by viewer.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestConnection", + "description": "The connection type for PullRequest.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "description": "A repository pull request.", + "fields": [ + { + "name": "activeLockReason", + "description": "Reason that the conversation was locked.", + "args": [], + "type": { + "kind": "ENUM", + "name": "LockReason", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "additions", + "description": "The number of additions in this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "assignees", + "description": "A list of Users assigned to this object.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "baseRef", + "description": "Identifies the base Ref associated with the pull request.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "baseRefName", + "description": "Identifies the name of the base Ref associated with the pull request, even if the ref has been deleted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "baseRefOid", + "description": "Identifies the oid of the base ref associated with the pull request, even if the ref has been deleted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "baseRepository", + "description": "The repository associated with this pull request's base Ref.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "The body as Markdown.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The body rendered to text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "changedFiles", + "description": "The number of changed files in this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closed", + "description": "`true` if the pull request is closed", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closedAt", + "description": "Identifies the date and time when the object was closed.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "comments", + "description": "A list of comments associated with the pull request.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commits", + "description": "A list of commits present in this pull request's head branch not present in the base branch.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestCommitConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletions", + "description": "The number of deletions in this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited this pull request's body.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "files", + "description": "Lists the files changed within this pull request.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PullRequestChangedFileConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRef", + "description": "Identifies the head Ref associated with the pull request.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRefName", + "description": "Identifies the name of the head Ref associated with the pull request, even if the ref has been deleted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRefOid", + "description": "Identifies the oid of the head ref associated with the pull request, even if the ref has been deleted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRepository", + "description": "The repository associated with this pull request's head Ref.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRepositoryOwner", + "description": "The owner of the repository associated with this pull request's head Ref.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isCrossRepository", + "description": "The head and base repositories are different.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labels", + "description": "A list of labels associated with the object.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LabelConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locked", + "description": "`true` if the pull request is locked", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "maintainerCanModify", + "description": "Indicates whether maintainers can modify the pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergeCommit", + "description": "The commit that was created when this pull request was merged.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergeable", + "description": "Whether or not the pull request can be merged based on the existence of merge conflicts.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "MergeableState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "merged", + "description": "Whether or not the pull request was merged.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergedAt", + "description": "The date and time that the pull request was merged.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergedBy", + "description": "The actor who merged the pull request.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "milestone", + "description": "Identifies the milestone associated with the pull request.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "number", + "description": "Identifies the pull request number.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "participants", + "description": "A list of Users that are participating in the Pull Request conversation.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permalink", + "description": "The permalink to the pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "potentialMergeCommit", + "description": "The commit that GitHub automatically generated to test if this pull request could be merged. This field will not return a value if the pull request is merged, or if the test merge commit is still being generated. See the `mergeable` field for more details on the mergeability of the pull request.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectCards", + "description": "List of project cards associated with this pull request.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "archivedStates", + "description": "A list of archived states to filter the cards by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectCardArchivedState", + "ofType": null + } + }, + "defaultValue": "[ARCHIVED, NOT_ARCHIVED]" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectCardConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "revertResourcePath", + "description": "The HTTP path for reverting this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "revertUrl", + "description": "The HTTP URL for reverting this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reviewRequests", + "description": "A list of review requests associated with the pull request.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ReviewRequestConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reviewThreads", + "description": "The list of all review threads for this pull request.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewThreadConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reviews", + "description": "A list of reviews associated with the pull request.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the reviews.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestReviewState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "author", + "description": "Filter by author of the review.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Identifies the state of the pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "suggestedReviewers", + "description": "A list of reviewer suggestions based on commit history and past review comments.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SuggestedReviewer", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timeline", + "description": "A list of events, comments, commits, etc. associated with the pull request.", + "args": [ + { + "name": "since", + "description": "Allows filtering timeline events by a `since` timestamp.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestTimelineConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timelineItems", + "description": "A list of events, comments, commits, etc. associated with the pull request.", + "args": [ + { + "name": "since", + "description": "Filter timeline items by a `since` timestamp.", + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "skip", + "description": "Skips the first _n_ elements in the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "itemTypes", + "description": "Filter timeline items by type.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestTimelineItemsItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestTimelineItemsConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "Identifies the pull request title.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanApplySuggestion", + "description": "Whether or not the viewer can apply suggestion.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanSubscribe", + "description": "Check if the viewer is able to change their subscription status for the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerSubscription", + "description": "Identifies if the viewer is watching, not watching, or ignoring the subscribable entity.", + "args": [], + "type": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Assignable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Closable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Lockable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Lockable", + "description": "An object that can be locked.", + "fields": [ + { + "name": "activeLockReason", + "description": "Reason that the conversation was locked.", + "args": [], + "type": { + "kind": "ENUM", + "name": "LockReason", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locked", + "description": "`true` if the object is locked", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "LockReason", + "description": "The possible reasons that an issue or pull request was locked.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OFF_TOPIC", + "description": "The issue or pull request was locked because the conversation was off-topic.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TOO_HEATED", + "description": "The issue or pull request was locked because the conversation was too heated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RESOLVED", + "description": "The issue or pull request was locked because the conversation was resolved.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SPAM", + "description": "The issue or pull request was locked because the conversation was spam.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "App", + "description": "A GitHub App.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The description of the app.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "logoBackgroundColor", + "description": "The hex color code, without the leading '#', for the logo background.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "logoUrl", + "description": "A URL pointing to the app's logo.", + "args": [ + { + "name": "size", + "description": "The size of the resulting image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name of the app.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "slug", + "description": "A slug based on the name of the app for use in URLs.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The URL to the app's homepage.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceListing", + "description": "A listing in the GitHub integration marketplace.", + "fields": [ + { + "name": "app", + "description": "The GitHub App this listing represents.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "companyUrl", + "description": "URL to the listing owner's company site.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "configurationResourcePath", + "description": "The HTTP path for configuring access to the listing's integration or OAuth app", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "configurationUrl", + "description": "The HTTP URL for configuring access to the listing's integration or OAuth app", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "documentationUrl", + "description": "URL to the listing's documentation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "extendedDescription", + "description": "The listing's detailed description.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "extendedDescriptionHTML", + "description": "The listing's detailed description rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fullDescription", + "description": "The listing's introductory description.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fullDescriptionHTML", + "description": "The listing's introductory description rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasApprovalBeenRequested", + "description": "Whether this listing has been submitted for review from GitHub for approval to be displayed in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "`hasApprovalBeenRequested` will be removed. Use `isVerificationPendingFromDraft` instead. Removal on 2019-10-01 UTC." + }, + { + "name": "hasPublishedFreeTrialPlans", + "description": "Does this listing have any plans with a free trial?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasTermsOfService", + "description": "Does this listing have a terms of service link?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "howItWorks", + "description": "A technical description of how this app works with GitHub.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "howItWorksHTML", + "description": "The listing's technical description rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "installationUrl", + "description": "URL to install the product to the viewer's account or organization.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "installedForViewer", + "description": "Whether this listing's app has been installed for the current viewer", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isApproved", + "description": "Whether this listing has been approved for display in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "`isApproved` will be removed. Use `isPublic` instead. Removal on 2019-10-01 UTC." + }, + { + "name": "isArchived", + "description": "Whether this listing has been removed from the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDelisted", + "description": "Whether this listing has been removed from the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "`isDelisted` will be removed. Use `isArchived` instead. Removal on 2019-10-01 UTC." + }, + { + "name": "isDraft", + "description": "Whether this listing is still an editable draft that has not been submitted for review and is not publicly visible in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPaid", + "description": "Whether the product this listing represents is available as part of a paid plan.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPublic", + "description": "Whether this listing has been approved for display in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isRejected", + "description": "Whether this listing has been rejected by GitHub for display in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isUnverified", + "description": "Whether this listing has been approved for unverified display in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isUnverifiedPending", + "description": "Whether this draft listing has been submitted for review for approval to be unverified in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isVerificationPendingFromDraft", + "description": "Whether this draft listing has been submitted for review from GitHub for approval to be verified in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isVerificationPendingFromUnverified", + "description": "Whether this unverified listing has been submitted for review from GitHub for approval to be verified in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isVerified", + "description": "Whether this listing has been approved for verified display in the Marketplace.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "logoBackgroundColor", + "description": "The hex color code, without the leading '#', for the logo background.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "logoUrl", + "description": "URL for the listing's logo image.", + "args": [ + { + "name": "size", + "description": "The size in pixels of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "400" + } + ], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The listing's full name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "normalizedShortDescription", + "description": "The listing's very short description without a trailing period or ampersands.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pricingUrl", + "description": "URL to the listing's detailed pricing.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "primaryCategory", + "description": "The category that best describes the listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MarketplaceCategory", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "privacyPolicyUrl", + "description": "URL to the listing's privacy policy, may return an empty string for listings that do not require a privacy policy URL.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for the Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "screenshotUrls", + "description": "The URLs for the listing's screenshots.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "secondaryCategory", + "description": "An alternate category that describes the listing.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "MarketplaceCategory", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shortDescription", + "description": "The listing's very short description.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "slug", + "description": "The short name of the listing used in its URL.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "statusUrl", + "description": "URL to the listing's status page.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "supportEmail", + "description": "An email address for support for this listing's app.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "supportUrl", + "description": "Either a URL or an email address for support for this listing's app, may return an empty string for listings that do not require a support URL.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "termsOfServiceUrl", + "description": "URL to the listing's terms of service.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for the Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanAddPlans", + "description": "Can the current viewer add plans for this Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanApprove", + "description": "Can the current viewer approve this Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanDelist", + "description": "Can the current viewer delist this Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanEdit", + "description": "Can the current viewer edit this Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanEditCategories", + "description": "Can the current viewer edit the primary and secondary category of this\nMarketplace listing.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanEditPlans", + "description": "Can the current viewer edit the plans for this Marketplace listing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanRedraft", + "description": "Can the current viewer return this Marketplace listing to draft state\nso it becomes editable again.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReject", + "description": "Can the current viewer reject this Marketplace listing by returning it to\nan editable draft state or rejecting it entirely.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanRequestApproval", + "description": "Can the current viewer request this listing be reviewed for display in\nthe Marketplace as verified.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasPurchased", + "description": "Indicates whether the current user has an active subscription to this Marketplace listing.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasPurchasedForAllOrganizations", + "description": "Indicates if the current user has purchased a subscription to this Marketplace listing\nfor all of the organizations the user owns.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerIsListingAdmin", + "description": "Does the current viewer role allow them to administer this Marketplace listing.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Organization", + "description": "An account on GitHub, with one or more owners, that has repositories, members and teams.", + "fields": [ + { + "name": "anyPinnableItems", + "description": "Determine if this repository owner has any items that can be pinned to their profile.", + "args": [ + { + "name": "type", + "description": "Filter to only a particular kind of pinnable item.", + "type": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "avatarUrl", + "description": "A URL pointing to the organization's public avatar.", + "args": [ + { + "name": "size", + "description": "The size of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The organization's public profile description.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "email", + "description": "The organization's public email.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isVerified", + "description": "Whether the organization has verified its profile email and website.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "itemShowcase", + "description": "Showcases a selection of repositories and gists that the profile owner has either curated or that have been selected automatically based on popularity.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProfileItemShowcase", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "location", + "description": "The organization's public profile location.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "login", + "description": "The organization's login name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "memberStatuses", + "description": "Get the status messages members of this entity have set that are either public or visible only to the organization.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for user statuses returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "UserStatusOrder", + "ofType": null + }, + "defaultValue": "{field:UPDATED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserStatusConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "membersWithRole", + "description": "A list of users who are members of this organization.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "OrganizationMemberConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The organization's public profile name.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "newTeamResourcePath", + "description": "The HTTP path creating a new team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "newTeamUrl", + "description": "The HTTP URL creating a new team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organizationBillingEmail", + "description": "The billing email for the organization.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pendingMembers", + "description": "A list of users who have been invited to join this organization.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnableItems", + "description": "A list of repositories and gists this profile owner can pin to their profile.", + "args": [ + { + "name": "types", + "description": "Filter the types of pinnable items that are returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedItems", + "description": "A list of repositories and gists this profile owner has pinned to their profile", + "args": [ + { + "name": "types", + "description": "Filter the types of pinned items that are returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedItemsRemaining", + "description": "Returns how many more items this profile owner can pin to their profile.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedRepositories", + "description": "A list of repositories this user has pinned to their profile", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "pinnedRepositories will be removed Use ProfileOwner.pinnedItems instead. Removal on 2019-07-01 UTC." + }, + { + "name": "project", + "description": "Find project by number.", + "args": [ + { + "name": "number", + "description": "The project number to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projects", + "description": "A list of projects under the owner.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for projects returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "ProjectOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "search", + "description": "Query to search projects by, currently only searching by name.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the projects by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsResourcePath", + "description": "The HTTP path listing organization's projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectsUrl", + "description": "The HTTP URL listing organization's projects", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositories", + "description": "A list of repositories that the user owns.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "isFork", + "description": "If non-null, filters repositories according to whether they are forks of another repository", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "Find Repository.", + "args": [ + { + "name": "name", + "description": "Name of Repository to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiresTwoFactorAuthentication", + "description": "When true the organization requires all members, billing managers, and outside collaborators to enable two-factor authentication.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this organization.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "samlIdentityProvider", + "description": "The Organization's SAML identity providers", + "args": [], + "type": { + "kind": "OBJECT", + "name": "OrganizationIdentityProvider", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "team", + "description": "Find an organization's team by its slug.", + "args": [ + { + "name": "slug", + "description": "The name or slug of the team to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Team", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "teams", + "description": "A list of teams in this organization.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters teams according to privacy", + "type": { + "kind": "ENUM", + "name": "TeamPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "role", + "description": "If non-null, filters teams according to whether the viewer is an admin or member on team", + "type": { + "kind": "ENUM", + "name": "TeamRole", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "query", + "description": "If non-null, filters teams with query on team name and team slug", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "userLogins", + "description": "User logins to filter by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for teams returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "TeamOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "ldapMapped", + "description": "If true, filters teams that are mapped to an LDAP Group (Enterprise only)", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "rootTeamsOnly", + "description": "If true, restrict to only root teams", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "teamsResourcePath", + "description": "The HTTP path listing organization's teams", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "teamsUrl", + "description": "The HTTP URL listing organization's teams", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this organization.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanAdminister", + "description": "Organization is adminable by the viewer.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanChangePinnedItems", + "description": "Can the viewer pin repositories and gists to the profile?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanCreateProjects", + "description": "Can the current viewer create new projects on this owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanCreateRepositories", + "description": "Viewer can create repositories on this organization", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanCreateTeams", + "description": "Viewer can create teams on this organization.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerIsAMember", + "description": "Viewer is an active member of this organization.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "websiteUrl", + "description": "The organization's public profile URL.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageSearch", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "ProjectOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "MemberStatusable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "ProfileOwner", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "RegistryPackageSearch", + "description": "Represents an interface to search packages on an object.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "description": "Represents an owner of a Repository.", + "fields": [ + { + "name": "avatarUrl", + "description": "A URL pointing to the owner's public avatar.", + "args": [ + { + "name": "size", + "description": "The size of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "login", + "description": "The username used to login.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedRepositories", + "description": "A list of repositories this user has pinned to their profile", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "pinnedRepositories will be removed Use ProfileOwner.pinnedItems instead. Removal on 2019-07-01 UTC." + }, + { + "name": "repositories", + "description": "A list of repositories that the user owns.", + "args": [ + { + "name": "privacy", + "description": "If non-null, filters repositories according to privacy", + "type": { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for repositories returned from the connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "affiliations", + "description": "Array of viewer's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the current viewer owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "ownerAffiliations", + "description": "Array of owner's affiliation options for repositories returned from the connection. For example, OWNER will include only repositories that the organization or user being viewed owns.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "ofType": null + } + }, + "defaultValue": "[OWNER, COLLABORATOR]" + }, + { + "name": "isLocked", + "description": "If non-null, filters repositories according to whether they have been locked", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "isFork", + "description": "If non-null, filters repositories according to whether they are forks of another repository", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "Find Repository.", + "args": [ + { + "name": "name", + "description": "Name of Repository to find.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP URL for the owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for the owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "RepositoryConnection", + "description": "A list of repositories owned by the subject.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalDiskUsage", + "description": "The total size in kilobytes of all repositories in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RepositoryPrivacy", + "description": "The privacy of a repository", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PUBLIC", + "description": "Public", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PRIVATE", + "description": "Private", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RepositoryOrder", + "description": "Ordering options for repository connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order repositories by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RepositoryOrderField", + "description": "Properties by which repository connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order repositories by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order repositories by update time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PUSHED_AT", + "description": "Order repositories by push time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME", + "description": "Order repositories by name", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "STARGAZERS", + "description": "Order repositories by number of stargazers", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RepositoryAffiliation", + "description": "The affiliation of a user to a repository", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OWNER", + "description": "Repositories that are owned by the authenticated user.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COLLABORATOR", + "description": "Repositories that the user has been added to as a collaborator.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ORGANIZATION_MEMBER", + "description": "Repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Float", + "description": "Represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "MemberStatusable", + "description": "Entities that have members who can set status messages.", + "fields": [ + { + "name": "memberStatuses", + "description": "Get the status messages members of this entity have set that are either public or visible only to the organization.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for user statuses returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "UserStatusOrder", + "ofType": null + }, + "defaultValue": "{field:UPDATED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserStatusConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "UserStatusConnection", + "description": "The connection type for UserStatus.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserStatusEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserStatus", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UserStatusEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "UserStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UserStatus", + "description": "The user's description of what they're currently doing.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "emoji", + "description": "An emoji summarizing the user's status.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": "ID of the object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "indicatesLimitedAvailability", + "description": "Whether this status indicates the user is not fully available on GitHub.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "A brief message describing what the user is doing.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organization", + "description": "The organization whose members can see this status. If null, this status is publicly visible.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who has this status.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UserStatusOrder", + "description": "Ordering options for user status connections.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order user statuses by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "UserStatusOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "UserStatusOrderField", + "description": "Properties by which user status connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "UPDATED_AT", + "description": "Order user statuses by when they were updated.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "ProfileOwner", + "description": "Represents any entity on GitHub that has a profile page.", + "fields": [ + { + "name": "anyPinnableItems", + "description": "Determine if this repository owner has any items that can be pinned to their profile.", + "args": [ + { + "name": "type", + "description": "Filter to only a particular kind of pinnable item.", + "type": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "email", + "description": "The public profile email.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "itemShowcase", + "description": "Showcases a selection of repositories and gists that the profile owner has either curated or that have been selected automatically based on popularity.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProfileItemShowcase", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "location", + "description": "The public profile location.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "login", + "description": "The username used to login.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The public profile name.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnableItems", + "description": "A list of repositories and gists this profile owner can pin to their profile.", + "args": [ + { + "name": "types", + "description": "Filter the types of pinnable items that are returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedItems", + "description": "A list of repositories and gists this profile owner has pinned to their profile", + "args": [ + { + "name": "types", + "description": "Filter the types of pinned items that are returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PinnableItemType", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pinnedItemsRemaining", + "description": "Returns how many more items this profile owner can pin to their profile.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanChangePinnedItems", + "description": "Can the viewer pin repositories and gists to the profile?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "websiteUrl", + "description": "The public profile website URL.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "ProfileItemShowcase", + "description": "A curatable list of repositories relating to a repository owner, which defaults to showing the most popular repositories they own.", + "fields": [ + { + "name": "hasPinnedItems", + "description": "Whether or not the owner has pinned any repositories or gists.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "items", + "description": "The repositories and gists in the showcase. If the profile owner has any pinned items, those will be returned. Otherwise, the profile owner's popular repositories will be returned.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PinnableItemConnection", + "description": "The connection type for PinnableItem.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PinnableItemEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "UNION", + "name": "PinnableItem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PinnableItemEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "UNION", + "name": "PinnableItem", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "PinnableItem", + "description": "Types that can be pinned to a profile page.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "Gist", + "description": "A Gist.", + "fields": [ + { + "name": "comments", + "description": "A list of comments associated with the gist", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The gist description.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "files", + "description": "The files in this gist.", + "args": [ + { + "name": "limit", + "description": "The maximum number of files to return.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "10" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistFile", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isFork", + "description": "Identifies if the gist is a fork.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPublic", + "description": "Whether the gist is public or not.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The gist name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "owner", + "description": "The gist owner.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pushedAt", + "description": "Identifies when the gist was last pushed to.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stargazers", + "description": "A list of users who have starred this starrable.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "StarOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StargazerConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasStarred", + "description": "Returns a boolean indicating whether the viewing user has starred this starrable.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Starrable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Starrable", + "description": "Things that can be starred.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stargazers", + "description": "A list of users who have starred this starrable.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "StarOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StargazerConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasStarred", + "description": "Returns a boolean indicating whether the viewing user has starred this starrable.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "StargazerConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StargazerEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "StargazerEdge", + "description": "Represents a user that's starred a repository.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "starredAt", + "description": "Identifies when the item was starred.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "StarOrder", + "description": "Ways in which star connections can be ordered.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order nodes by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "StarOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order nodes.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "StarOrderField", + "description": "Properties by which star connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "STARRED_AT", + "description": "Allows ordering a list of stars by when they were created.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GistCommentConnection", + "description": "The connection type for GistComment.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistCommentEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GistCommentEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GistComment", + "description": "Represents a comment on an Gist.", + "fields": [ + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the gist.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "Identifies the comment body.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The comment body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The body rendered to text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "gist", + "description": "The associated gist.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isMinimized", + "description": "Returns whether or not a comment has been minimized.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "minimizedReason", + "description": "Returns why the comment was minimized.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanDelete", + "description": "Check if the current viewer can delete this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanMinimize", + "description": "Check if the current viewer can minimize this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Deletable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Deletable", + "description": "Entities that can be deleted.", + "fields": [ + { + "name": "viewerCanDelete", + "description": "Check if the current viewer can delete this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "GistComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "GistFile", + "description": "A file in a gist.", + "fields": [ + { + "name": "encodedName", + "description": "The file name encoded to remove characters that are invalid in URL paths.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "encoding", + "description": "The gist file encoding.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "extension", + "description": "The file extension from the file name.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isImage", + "description": "Indicates if this file is an image.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isTruncated", + "description": "Whether the file's contents were truncated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "language", + "description": "The programming language this file is written in.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Language", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The gist file name.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "size", + "description": "The gist file size in bytes.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "text", + "description": "UTF8 text data or null if the file is binary", + "args": [ + { + "name": "truncate", + "description": "Optionally truncate the returned file to this length.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Language", + "description": "Represents a given language found in repositories.", + "fields": [ + { + "name": "color", + "description": "The color defined for the current language.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name of the current language.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PinnableItemType", + "description": "Represents items that can be pinned to a profile page.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "REPOSITORY", + "description": "A repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "GIST", + "description": "A gist.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectConnection", + "description": "A list of projects associated with the owner.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ProjectEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ProjectEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ProjectOrder", + "description": "Ways in which lists of projects can be ordered upon return.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order projects by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ProjectOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order projects by the specified field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ProjectOrderField", + "description": "Properties by which project connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order projects by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order projects by update time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME", + "description": "Order projects by name", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "description": "Represents a comment on an Issue.", + "fields": [ + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "The body as Markdown.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The body rendered to text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isMinimized", + "description": "Returns whether or not a comment has been minimized.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "Identifies the issue associated with the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "minimizedReason", + "description": "Returns why the comment was minimized.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "Returns the pull request associated with the comment, if this comment was made on a\npull request.\n", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this issue comment", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this issue comment", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanDelete", + "description": "Check if the current viewer can delete this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanMinimize", + "description": "Check if the current viewer can minimize this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Deletable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "description": "Represents a subject that can be reacted on.", + "fields": [ + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "ReactionGroup", + "description": "A group of emoji reactions to a particular piece of content.", + "fields": [ + { + "name": "content", + "description": "Identifies the emoji reaction.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies when the reaction was created.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "The subject that was reacted to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "users", + "description": "Users who have reacted to the reaction subject with the emotion represented by this reaction group", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactingUserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasReacted", + "description": "Whether or not the authenticated user has left a reaction on the subject.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ReactionContent", + "description": "Emojis that can be attached to Issues, Pull Requests and Comments.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "THUMBS_UP", + "description": "Represents the 👍 emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "THUMBS_DOWN", + "description": "Represents the 👎 emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LAUGH", + "description": "Represents the 😄 emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HOORAY", + "description": "Represents the 🎉 emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CONFUSED", + "description": "Represents the 😕 emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HEART", + "description": "Represents the ❤️ emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ROCKET", + "description": "Represents the 🚀 emoji.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "EYES", + "description": "Represents the 👀 emoji.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReactingUserConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactingUserEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReactingUserEdge", + "description": "Represents a user that's made a reaction.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactedAt", + "description": "The moment when the user made the reaction.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReactionConnection", + "description": "A list of reactions that have been left on the subject.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Reaction", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasReacted", + "description": "Whether or not the authenticated user has left a reaction on the subject.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReactionEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Reaction", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Reaction", + "description": "An emoji reaction to a particular piece of content.", + "fields": [ + { + "name": "content", + "description": "Identifies the emoji reaction.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactable", + "description": "The reactable piece of content", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "Identifies the user who created this reaction.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "description": "Ways in which lists of reactions can be ordered upon return.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order reactions by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReactionOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order reactions by the specified field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ReactionOrderField", + "description": "A list of fields that reactions can be ordered by.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Allows ordering a list of reactions by when they were created.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryInfo", + "description": "A subset of repository info.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The description of the repository.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "descriptionHTML", + "description": "The description of the repository rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "forkCount", + "description": "Returns how many forks there are of this repository in the whole network.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasIssuesEnabled", + "description": "Indicates if the repository has issues feature enabled.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasWikiEnabled", + "description": "Indicates if the repository has wiki feature enabled.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "homepageUrl", + "description": "The repository's URL.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isArchived", + "description": "Indicates if the repository is unmaintained.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isFork", + "description": "Identifies if the repository is a fork.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isLocked", + "description": "Indicates if the repository has been locked or not.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isMirror", + "description": "Identifies if the repository is a mirror.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPrivate", + "description": "Identifies if the repository is private.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "licenseInfo", + "description": "The license associated with the repository", + "args": [], + "type": { + "kind": "OBJECT", + "name": "License", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockReason", + "description": "The reason the repository has been locked.", + "args": [], + "type": { + "kind": "ENUM", + "name": "RepositoryLockReason", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mirrorUrl", + "description": "The repository's original mirror URL.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name of the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nameWithOwner", + "description": "The repository's name with owner.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "owner", + "description": "The User owner of the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "RepositoryOwner", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pushedAt", + "description": "Identifies when the repository was last pushed to.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this repository", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shortDescriptionHTML", + "description": "A description of the repository, rendered to HTML without any links in it.", + "args": [ + { + "name": "limit", + "description": "How many characters to return.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "200" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this repository", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "RepositoryLockReason", + "description": "The possible reasons a given repository could be in a locked state.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "MOVING", + "description": "The repository is locked due to a move.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BILLING", + "description": "The repository is locked due to a billing related reason.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RENAME", + "description": "The repository is locked due to a rename.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MIGRATING", + "description": "The repository is locked due to a migration.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "License", + "description": "A repository's open source license", + "fields": [ + { + "name": "body", + "description": "The full text of the license", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "conditions", + "description": "The conditions set by the license", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LicenseRule", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "A human-readable description of the license", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "featured", + "description": "Whether the license should be featured", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hidden", + "description": "Whether the license should be displayed in license pickers", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "implementation", + "description": "Instructions on how to implement the license", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "key", + "description": "The lowercased SPDX ID of the license", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "limitations", + "description": "The limitations set by the license", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LicenseRule", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The license full name specified by ", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nickname", + "description": "Customary short name if applicable (e.g, GPLv3)", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permissions", + "description": "The permissions set by the license", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LicenseRule", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pseudoLicense", + "description": "Whether the license is a pseudo-license placeholder (e.g., other, no-license)", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "spdxId", + "description": "Short identifier specified by ", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "URL to the license on ", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LicenseRule", + "description": "Describes a License's conditions, permissions, and limitations", + "fields": [ + { + "name": "description", + "description": "A description of the rule", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "key", + "description": "The machine-readable rule key", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "label", + "description": "The human-readable rule label", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryTopicConnection", + "description": "The connection type for RepositoryTopic.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryTopicEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryTopic", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryTopicEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "RepositoryTopic", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryTopic", + "description": "A repository-topic connects a repository to a topic.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this repository-topic.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "topic", + "description": "The topic.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this repository-topic.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Topic", + "description": "A topic aggregates entities that are related to a subject.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The topic's name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "relatedTopics", + "description": "A list of related topics, including aliases of this topic, sorted with the most relevant\nfirst. Returns up to 10 Topics.\n", + "args": [ + { + "name": "first", + "description": "How many topics to return.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "3" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stargazers", + "description": "A list of users who have starred this starrable.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "StarOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StargazerConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerHasStarred", + "description": "Returns a boolean indicating whether the viewing user has starred this starrable.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Starrable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Release", + "description": "A release contains the content for a release.", + "fields": [ + { + "name": "author", + "description": "The author of the release", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Identifies the description of the release.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDraft", + "description": "Whether or not the release is a draft", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPrerelease", + "description": "Whether or not the release is a prerelease", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Identifies the title of the release.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies the date and time when the release was created.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "releaseAssets", + "description": "List of releases assets which are dependent on this release.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "name", + "description": "A list of names to filter the assets by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReleaseAssetConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this issue", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tag", + "description": "The Git tag the release points to", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tagName", + "description": "The name of the release's Git tag", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this issue", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Ref", + "description": "Represents a Git reference.", + "fields": [ + { + "name": "associatedPullRequests", + "description": "A list of pull requests with this ref as the head ref.", + "args": [ + { + "name": "states", + "description": "A list of states to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "headRefName", + "description": "The head ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The base ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for pull requests returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The ref name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "prefix", + "description": "The ref's prefix, such as `refs/heads/` or `refs/tags/`.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository the ref belongs to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "target", + "description": "The object the ref points to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "GitObject", + "description": "Represents a Git object.", + "fields": [ + { + "name": "abbreviatedOid", + "description": "An abbreviated version of the Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitResourcePath", + "description": "The HTTP path for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitUrl", + "description": "The HTTP URL for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oid", + "description": "The Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository the Git object belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Blob", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Tag", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Tree", + "ofType": null + } + ] + }, + { + "kind": "SCALAR", + "name": "GitObjectID", + "description": "A Git object ID.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "description": "Represents a object that belongs to a repository.", + "fields": [ + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommitCommentThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommitCommentThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "Blob", + "description": "Represents a Git blob.", + "fields": [ + { + "name": "abbreviatedOid", + "description": "An abbreviated version of the Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "byteSize", + "description": "Byte size of Blob object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitResourcePath", + "description": "The HTTP path for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitUrl", + "description": "The HTTP URL for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isBinary", + "description": "Indicates whether the Blob is binary or text", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isTruncated", + "description": "Indicates whether the contents is truncated", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oid", + "description": "The Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository the Git object belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "text", + "description": "UTF8 text data or null if the Blob is binary", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Commit", + "description": "Represents a Git commit.", + "fields": [ + { + "name": "abbreviatedOid", + "description": "An abbreviated version of the Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "additions", + "description": "The number of additions in this commit.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "associatedPullRequests", + "description": "The pull requests associated with a commit", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for pull requests.", + "type": { + "kind": "INPUT_OBJECT", + "name": "PullRequestOrder", + "ofType": null + }, + "defaultValue": "{field:CREATED_AT,direction:ASC}" + } + ], + "type": { + "kind": "OBJECT", + "name": "PullRequestConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "author", + "description": "Authorship details of the commit.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "GitActor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authoredByCommitter", + "description": "Check if the committer and the author match.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authoredDate", + "description": "The datetime when this commit was authored.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "blame", + "description": "Fetches `git blame` information.", + "args": [ + { + "name": "path", + "description": "The file whose Git blame information you want.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Blame", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "changedFiles", + "description": "The number of changed files in this commit.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "comments", + "description": "Comments made on the commit.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitResourcePath", + "description": "The HTTP path for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitUrl", + "description": "The HTTP URL for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "committedDate", + "description": "The datetime when this commit was committed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "committedViaWeb", + "description": "Check if commited via GitHub web UI.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "committer", + "description": "Committership details of the commit.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "GitActor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletions", + "description": "The number of deletions in this commit.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deployments", + "description": "The deployments associated with a commit.", + "args": [ + { + "name": "environments", + "description": "Environments to list deployments for", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for deployments returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "DeploymentOrder", + "ofType": null + }, + "defaultValue": "{field:CREATED_AT,direction:ASC}" + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeploymentConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "history", + "description": "The linear commit history starting from (and including) this commit, in the same order as `git log`.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "path", + "description": "If non-null, filters history to only show commits touching files under this path.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "author", + "description": "If non-null, filters history to only show commits with matching authorship.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CommitAuthor", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "since", + "description": "Allows specifying a beginning time or date for fetching commits.", + "type": { + "kind": "SCALAR", + "name": "GitTimestamp", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "until", + "description": "Allows specifying an ending time or date for fetching commits.", + "type": { + "kind": "SCALAR", + "name": "GitTimestamp", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitHistoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The Git commit message", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "messageBody", + "description": "The Git commit message body", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "messageBodyHTML", + "description": "The commit message body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "messageHeadline", + "description": "The Git commit message headline", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "messageHeadlineHTML", + "description": "The commit message headline rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oid", + "description": "The Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "parents", + "description": "The parents of a commit.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pushedDate", + "description": "The datetime when this commit was pushed.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository this commit belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this commit", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signature", + "description": "Commit signing information, if present.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "GitSignature", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "status", + "description": "Status information for this commit", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Status", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tarballUrl", + "description": "Returns a URL to download a tarball archive for a repository.\nNote: For private repositories, these links are temporary and expire after five minutes.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tree", + "description": "Commit's root Tree", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Tree", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "treeResourcePath", + "description": "The HTTP path for the tree of this commit", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "treeUrl", + "description": "The HTTP URL for the tree of this commit", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this commit", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanSubscribe", + "description": "Check if the viewer is able to change their subscription status for the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerSubscription", + "description": "Identifies if the viewer is watching, not watching, or ignoring the subscribable entity.", + "args": [], + "type": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "zipballUrl", + "description": "Returns a URL to download a zipball archive for a repository.\nNote: For private repositories, these links are temporary and expire after five minutes.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Subscribable", + "description": "Entities that can be subscribed to for web and email notifications.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanSubscribe", + "description": "Check if the viewer is able to change their subscription status for the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerSubscription", + "description": "Identifies if the viewer is watching, not watching, or ignoring the subscribable entity.", + "args": [], + "type": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "SubscriptionState", + "description": "The possible states of a subscription.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "UNSUBSCRIBED", + "description": "The User is only notified when participating or @mentioned.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUBSCRIBED", + "description": "The User is notified of all conversations.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "IGNORED", + "description": "The User is never notified.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Tree", + "description": "Represents a Git tree.", + "fields": [ + { + "name": "abbreviatedOid", + "description": "An abbreviated version of the Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitResourcePath", + "description": "The HTTP path for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitUrl", + "description": "The HTTP URL for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "entries", + "description": "A list of tree entries.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TreeEntry", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oid", + "description": "The Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository the Git object belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TreeEntry", + "description": "Represents a Git tree entry.", + "fields": [ + { + "name": "mode", + "description": "Entry file mode.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Entry file name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "object", + "description": "Entry file object.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oid", + "description": "Entry file Git object ID.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository the tree entry belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": "Entry file type.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GitActor", + "description": "Represents an actor in a Git commit (ie. an author or committer).", + "fields": [ + { + "name": "avatarUrl", + "description": "A URL pointing to the author's public avatar.", + "args": [ + { + "name": "size", + "description": "The size of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "The timestamp of the Git action (authoring or committing).", + "args": [], + "type": { + "kind": "SCALAR", + "name": "GitTimestamp", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "email", + "description": "The email in the Git commit.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name in the Git commit.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The GitHub user corresponding to the email field. Null if no such user exists.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "GitTimestamp", + "description": "An ISO-8601 encoded date string. Unlike the DateTime type, GitTimestamp is not converted in UTC.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitConnection", + "description": "The connection type for Commit.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitHistoryConnection", + "description": "The connection type for Commit.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CommitAuthor", + "description": "Specifies an author for filtering Git commits.", + "fields": null, + "inputFields": [ + { + "name": "id", + "description": "ID of a User to filter by. If non-null, only commits authored by this user will be returned. This field takes precedence over emails.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "emails", + "description": "Email addresses to filter by. Commits authored by any of the specified email addresses will be returned.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitCommentConnection", + "description": "The connection type for CommitComment.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitCommentEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitCommentEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CommitComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitComment", + "description": "Represents a comment on a given Commit.", + "fields": [ + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "Identifies the comment body.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "Identifies the comment body rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The body rendered to text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "Identifies the commit associated with the comment, if the commit exists.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isMinimized", + "description": "Returns whether or not a comment has been minimized.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "minimizedReason", + "description": "Returns why the comment was minimized.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "path", + "description": "Identifies the file path associated with the comment.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "position", + "description": "Identifies the line position associated with the comment.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path permalink for this commit comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL permalink for this commit comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanDelete", + "description": "Check if the current viewer can delete this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanMinimize", + "description": "Check if the current viewer can minimize this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Deletable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "GitSignature", + "description": "Information about a signature (GPG or S/MIME) on a Commit or Tag.", + "fields": [ + { + "name": "email", + "description": "Email used to sign this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isValid", + "description": "True if the signature is valid and verified by GitHub.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "payload", + "description": "Payload for GPG signing object. Raw ODB object without the signature header.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signature", + "description": "ASCII-armored signature header from object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signer", + "description": "GitHub user corresponding to the email signing this commit.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The state of this signature. `VALID` if signature is valid and verified by GitHub, otherwise represents reason why signature is considered invalid.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "GitSignatureState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "wasSignedByGitHub", + "description": "True if the signature was made with GitHub's signing key.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "GpgSignature", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SmimeSignature", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnknownSignature", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "GitSignatureState", + "description": "The state of a Git signature.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "VALID", + "description": "Valid signature and verified by GitHub", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INVALID", + "description": "Invalid signature", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MALFORMED_SIG", + "description": "Malformed signature", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNKNOWN_KEY", + "description": "Key used for signing not known to GitHub", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BAD_EMAIL", + "description": "Invalid email used for signing", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNVERIFIED_EMAIL", + "description": "Email used for signing unverified on GitHub", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NO_USER", + "description": "Email used for signing not known to GitHub", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNKNOWN_SIG_TYPE", + "description": "Unknown signature type", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNSIGNED", + "description": "Unsigned", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "GPGVERIFY_UNAVAILABLE", + "description": "Internal error - the GPG verification service is unavailable at the moment", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "GPGVERIFY_ERROR", + "description": "Internal error - the GPG verification service misbehaved", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_SIGNING_KEY", + "description": "The usage flags for the key that signed this don't allow signing", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "EXPIRED_KEY", + "description": "Signing key expired", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OCSP_PENDING", + "description": "Valid signature, pending certificate revocation checking", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OCSP_ERROR", + "description": "Valid siganture, though certificate revocation check failed", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BAD_CERT", + "description": "The signing certificate or its chain could not be verified", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OCSP_REVOKED", + "description": "One or more certificates in chain has been revoked", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Status", + "description": "Represents a commit status.", + "fields": [ + { + "name": "commit", + "description": "The commit this status is attached to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "context", + "description": "Looks up an individual status context by context name.", + "args": [ + { + "name": "name", + "description": "The context name.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "StatusContext", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "contexts", + "description": "The individual status contexts for this commit.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StatusContext", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The combined commit status.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "StatusState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "StatusState", + "description": "The possible commit status states.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "EXPECTED", + "description": "Status is expected.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ERROR", + "description": "Status is errored.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FAILURE", + "description": "Status is failing.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PENDING", + "description": "Status is pending.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUCCESS", + "description": "Status is successful.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "StatusContext", + "description": "Represents an individual commit status context", + "fields": [ + { + "name": "commit", + "description": "This commit this status context is attached to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "context", + "description": "The name of this status context.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "The actor who created this status context.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The description for this status context.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The state of this status context.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "StatusState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "targetUrl", + "description": "The URL for this status context.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Bot", + "description": "A special type of user which takes actions on behalf of GitHub Apps.", + "fields": [ + { + "name": "avatarUrl", + "description": "A URL pointing to the GitHub App's public avatar.", + "args": [ + { + "name": "size", + "description": "The size of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "login", + "description": "The username of the actor.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this bot", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this bot", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestState", + "description": "The possible states of a pull request.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OPEN", + "description": "A pull request that is still open.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CLOSED", + "description": "A pull request that has been closed without being merged.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MERGED", + "description": "A pull request that has been closed by being merged.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Blame", + "description": "Represents a Git blame.", + "fields": [ + { + "name": "ranges", + "description": "The list of ranges from a Git blame.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BlameRange", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BlameRange", + "description": "Represents a range of information from a Git blame.", + "fields": [ + { + "name": "age", + "description": "Identifies the recency of the change, from 1 (new) to 10 (old). This is calculated as a 2-quantile and determines the length of distance between the median age of all the changes in the file and the recency of the current range's change.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "Identifies the line author", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endingLine", + "description": "The ending line for the range", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startingLine", + "description": "The starting line for the range", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeploymentConnection", + "description": "The connection type for Deployment.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeploymentEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Deployment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeploymentEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Deployment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Deployment", + "description": "Represents triggered deployment instance.", + "fields": [ + { + "name": "commit", + "description": "Identifies the commit sha of the deployment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitOid", + "description": "Identifies the oid of the deployment commit, even if the commit has been deleted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "Identifies the actor who triggered the deployment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The deployment description.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "environment", + "description": "The environment to which this deployment was made.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "latestStatus", + "description": "The latest status of this deployment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "DeploymentStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "payload", + "description": "Extra information that a deployment system might need.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ref", + "description": "Identifies the Ref of the deployment, if the deployment was created by ref.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "Identifies the repository associated with the deployment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The current state of the deployment.", + "args": [], + "type": { + "kind": "ENUM", + "name": "DeploymentState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "statuses", + "description": "A list of statuses associated with the deployment.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeploymentStatusConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "task", + "description": "The deployment task.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeploymentStatusConnection", + "description": "The connection type for DeploymentStatus.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeploymentStatusEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeploymentStatus", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeploymentStatusEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "DeploymentStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeploymentStatus", + "description": "Describes the status of a given deployment attempt.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "Identifies the actor who triggered the deployment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deployment", + "description": "Identifies the deployment associated with status.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Deployment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Identifies the description of the deployment.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "environmentUrl", + "description": "Identifies the environment URL of the deployment.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "logUrl", + "description": "Identifies the log URL of the deployment.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Identifies the current state of the deployment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "DeploymentStatusState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "DeploymentStatusState", + "description": "The possible states for a deployment status.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PENDING", + "description": "The deployment is pending.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUCCESS", + "description": "The deployment was successful.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FAILURE", + "description": "The deployment has failed.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INACTIVE", + "description": "The deployment is inactive.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ERROR", + "description": "The deployment experienced an error.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "QUEUED", + "description": "The deployment is queued", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "IN_PROGRESS", + "description": "The deployment is in progress.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "DeploymentState", + "description": "The possible states in which a deployment can be.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ABANDONED", + "description": "The pending deployment was not updated after 30 minutes.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ACTIVE", + "description": "The deployment is currently active.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DESTROYED", + "description": "An inactive transient deployment.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ERROR", + "description": "The deployment experienced an error.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FAILURE", + "description": "The deployment has failed.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INACTIVE", + "description": "The deployment is inactive.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PENDING", + "description": "The deployment is pending.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "QUEUED", + "description": "The deployment has queued", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "IN_PROGRESS", + "description": "The deployment is in progress.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeploymentOrder", + "description": "Ordering options for deployment connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order deployments by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "DeploymentOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "DeploymentOrderField", + "description": "Properties by which deployment connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order collection by creation time", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PullRequestOrder", + "description": "Ways in which lists of issues can be ordered upon return.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order pull requests by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order pull requests by the specified field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestOrderField", + "description": "Properties by which pull_requests connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order pull_requests by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order pull_requests by update time", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseAssetConnection", + "description": "The connection type for ReleaseAsset.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReleaseAssetEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReleaseAsset", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseAssetEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ReleaseAsset", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseAsset", + "description": "A release asset contains the content for a release asset.", + "fields": [ + { + "name": "contentType", + "description": "The asset's content-type", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "downloadCount", + "description": "The number of times this asset was downloaded", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "downloadUrl", + "description": "Identifies the URL where you can download the release asset via the browser.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "Identifies the title of the release asset.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "release", + "description": "Release that the asset is associated with", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Release", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "size", + "description": "The size (in bytes) of the asset", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "uploadedBy", + "description": "The user that performed the upload", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "Identifies the URL of the release asset.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceCategory", + "description": "A public description of a Marketplace category.", + "fields": [ + { + "name": "description", + "description": "The category's description.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "howItWorks", + "description": "The technical description of how apps listed in this category work with GitHub.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The category's name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "primaryListingCount", + "description": "How many Marketplace listings have this as their primary category.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this Marketplace category.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "secondaryListingCount", + "description": "How many Marketplace listings have this as their secondary category.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "slug", + "description": "The short name of the category used in its URL.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this Marketplace category.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceListingConnection", + "description": "Look up Marketplace Listings", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MarketplaceListingEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MarketplaceListing", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceListingEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "MarketplaceListing", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseConnection", + "description": "The connection type for Release.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReleaseEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Release", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReleaseEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Release", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ReleaseOrder", + "description": "Ways in which lists of releases can be ordered upon return.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order releases by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReleaseOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order releases by the specified field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ReleaseOrderField", + "description": "Properties by which release connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order releases by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME", + "description": "Order releases alphabetically by name", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "IssuePubSubTopic", + "description": "The possible PubSub channels for an issue.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "UPDATED", + "description": "The channel ID for observing issue updates.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MARKASREAD", + "description": "The channel ID for marking an issue as read.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TIMELINE", + "description": "The channel ID for updating items on the issue timeline.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "STATE", + "description": "The channel ID for observing issue state updates.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationConnection", + "description": "The connection type for Organization.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "OrganizationEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationInvitation", + "description": "An Invitation for a user to an organization.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "email", + "description": "The email address of the user invited to the organization.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "invitationType", + "description": "The type of invitation that was sent (e.g. email, user).", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrganizationInvitationType", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "invitee", + "description": "The user who was invited to the organization.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inviter", + "description": "The user who created the invitation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organization", + "description": "The organization the invite is for", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "role", + "description": "The user's pending role in the organization (e.g. member, owner).", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrganizationInvitationRole", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "OrganizationInvitationType", + "description": "The possible organization invitation types.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "USER", + "description": "The invitation was to an existing user.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "EMAIL", + "description": "The invitation was to an email address.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "OrganizationInvitationRole", + "description": "The possible organization invitation roles.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "DIRECT_MEMBER", + "description": "The user is invited to be a direct member of the organization.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ADMIN", + "description": "The user is invited to be an admin of the organization.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BILLING_MANAGER", + "description": "The user is invited to be a billing manager of the organization.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REINSTATE", + "description": "The user's previous role will be reinstated.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TeamConnection", + "description": "The connection type for Team.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TeamEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Team", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Team", + "description": "A team of users in an organization.", + "fields": [ + { + "name": "ancestors", + "description": "A list of teams that are ancestors of this team.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "avatarUrl", + "description": "A URL pointing to the team's avatar.", + "args": [ + { + "name": "size", + "description": "The size in pixels of the resulting square image.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "400" + } + ], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "childTeams", + "description": "List of child teams belonging to this team", + "args": [ + { + "name": "orderBy", + "description": "Order for connection", + "type": { + "kind": "INPUT_OBJECT", + "name": "TeamOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "userLogins", + "description": "User logins to filter by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "immediateOnly", + "description": "Whether to list immediate child teams or all descendant child teams.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "true" + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "combinedSlug", + "description": "The slug corresponding to the organization and team.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "The description of the team.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editTeamResourcePath", + "description": "The HTTP path for editing this team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editTeamUrl", + "description": "The HTTP URL for editing this team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "invitations", + "description": "A list of pending invitations for users to this team", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "OrganizationInvitationConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "memberStatuses", + "description": "Get the status messages members of this entity have set that are either public or visible only to the organization.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for user statuses returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "UserStatusOrder", + "ofType": null + }, + "defaultValue": "{field:UPDATED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserStatusConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "members", + "description": "A list of users who are members of this team.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "query", + "description": "The search string to look for.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "membership", + "description": "Filter by membership type", + "type": { + "kind": "ENUM", + "name": "TeamMembershipType", + "ofType": null + }, + "defaultValue": "ALL" + }, + { + "name": "role", + "description": "Filter by team member role", + "type": { + "kind": "ENUM", + "name": "TeamMemberRole", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "TeamMemberOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamMemberConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "membersResourcePath", + "description": "The HTTP path for the team' members", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "membersUrl", + "description": "The HTTP URL for the team' members", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name of the team.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "newTeamResourcePath", + "description": "The HTTP path creating a new team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "newTeamUrl", + "description": "The HTTP URL creating a new team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organization", + "description": "The organization that owns this team.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "parentTeam", + "description": "The parent team of the team.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Team", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "privacy", + "description": "The level of privacy the team has.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "TeamPrivacy", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositories", + "description": "A list of repositories this team has access to.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "query", + "description": "The search string to look for.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Order for the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "TeamRepositoryOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamRepositoryConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoriesResourcePath", + "description": "The HTTP path for this team's repositories", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoriesUrl", + "description": "The HTTP URL for this team's repositories", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "slug", + "description": "The slug corresponding to the team.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "teamsResourcePath", + "description": "The HTTP path for this team's teams", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "teamsUrl", + "description": "The HTTP URL for this team's teams", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this team", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanAdminister", + "description": "Team is adminable by the viewer.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanSubscribe", + "description": "Check if the viewer is able to change their subscription status for the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerSubscription", + "description": "Identifies if the viewer is watching, not watching, or ignoring the subscribable entity.", + "args": [], + "type": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "MemberStatusable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamPrivacy", + "description": "The possible team privacy values.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "SECRET", + "description": "A secret team can only be seen by its members.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "VISIBLE", + "description": "A visible team can be seen and @mentioned by every member of the organization.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TeamMemberConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamMemberEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TeamMemberEdge", + "description": "Represents a user who is a member of a team.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "memberAccessResourcePath", + "description": "The HTTP path to the organization's member access page.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "memberAccessUrl", + "description": "The HTTP URL to the organization's member access page.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "role", + "description": "The role the member has on the team.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "TeamMemberRole", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamMemberRole", + "description": "The possible team member roles; either 'maintainer' or 'member'.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "MAINTAINER", + "description": "A team maintainer has permission to add and remove team members.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MEMBER", + "description": "A team member has no administrative permissions on the team.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamMembershipType", + "description": "Defines which types of team members are included in the returned list. Can be one of IMMEDIATE, CHILD_TEAM or ALL.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "IMMEDIATE", + "description": "Includes only immediate members of the team.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CHILD_TEAM", + "description": "Includes only child team members for the team.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALL", + "description": "Includes immediate and child team members for the team.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "TeamMemberOrder", + "description": "Ordering options for team member connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order team members by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "TeamMemberOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamMemberOrderField", + "description": "Properties by which team member connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "LOGIN", + "description": "Order team members by login", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CREATED_AT", + "description": "Order team members by creation time", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TeamRepositoryConnection", + "description": "The connection type for Repository.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamRepositoryEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TeamRepositoryEdge", + "description": "Represents a team repository.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permission", + "description": "The permission level the team has on the repository", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryPermission", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RepositoryPermission", + "description": "The access level to a repository", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ADMIN", + "description": "Can read, clone, push, and add collaborators", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "WRITE", + "description": "Can read, clone and push", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "READ", + "description": "Can read and clone", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "TeamRepositoryOrder", + "description": "Ordering options for team repository connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order repositories by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "TeamRepositoryOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamRepositoryOrderField", + "description": "Properties by which team repository connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order repositories by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order repositories by update time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PUSHED_AT", + "description": "Order repositories by push time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME", + "description": "Order repositories by name", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PERMISSION", + "description": "Order repositories by permission", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "STARGAZERS", + "description": "Order repositories by number of stargazers", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationInvitationConnection", + "description": "The connection type for OrganizationInvitation.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "OrganizationInvitationEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "OrganizationInvitation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationInvitationEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "OrganizationInvitation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "TeamOrder", + "description": "Ways in which team connections can be ordered.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order nodes by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "TeamOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order nodes.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamOrderField", + "description": "Properties by which team connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "NAME", + "description": "Allows ordering a list of teams by name.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "DefaultRepositoryPermissionField", + "description": "The possible default permissions for repositories.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "NONE", + "description": "No access", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "READ", + "description": "Can read repos by default", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "WRITE", + "description": "Can read and write repos by default", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ADMIN", + "description": "Can read, write, and administrate repos by default", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ExternalIdentityConnection", + "description": "The connection type for ExternalIdentity.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ExternalIdentityEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ExternalIdentity", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ExternalIdentityEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ExternalIdentity", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ExternalIdentity", + "description": "An external identity provisioned by SAML SSO or SCIM.", + "fields": [ + { + "name": "guid", + "description": "The GUID for this identity", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organizationInvitation", + "description": "Organization invitation for this SCIM-provisioned external identity", + "args": [], + "type": { + "kind": "OBJECT", + "name": "OrganizationInvitation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "samlIdentity", + "description": "SAML Identity attributes", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ExternalIdentitySamlAttributes", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "scimIdentity", + "description": "SCIM Identity attributes", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ExternalIdentityScimAttributes", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "User linked to this external identity. Will be NULL if this identity has not been claimed by an organization member.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ExternalIdentitySamlAttributes", + "description": "SAML attributes for the External Identity", + "fields": [ + { + "name": "nameId", + "description": "The NameID of the SAML identity", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ExternalIdentityScimAttributes", + "description": "SCIM attributes for the External Identity", + "fields": [ + { + "name": "username", + "description": "The userName of the SCIM identity", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PublicKey", + "description": "A user's public key.", + "fields": [ + { + "name": "accessedAt", + "description": "The last time this authorization was used to perform an action", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fingerprint", + "description": "The fingerprint for this PublicKey", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isReadOnly", + "description": "Whether this PublicKey is read-only or not", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "key", + "description": "The public key string", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "X509Certificate", + "description": "A valid x509 certificate string", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "IdentityProviderConfigurationState", + "description": "The possible states in which authentication can be configured with an identity provider.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ENFORCED", + "description": "Authentication with an identity provider is configured and enforced.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CONFIGURED", + "description": "Authentication with an identity provider is configured but not enforced.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNCONFIGURED", + "description": "Authentication with an identity provider is not configured.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Date", + "description": "An ISO-8601 encoded date string.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationIdentityProvider", + "description": "An Identity Provider configured to provision SAML and SCIM identities for Organizations", + "fields": [ + { + "name": "digestMethod", + "description": "The digest algorithm used to sign SAML requests for the Identity Provider.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "externalIdentities", + "description": "External Identities provisioned by this Identity Provider", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ExternalIdentityConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "idpCertificate", + "description": "The x509 certificate used by the Identity Provder to sign assertions and responses.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "X509Certificate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuer", + "description": "The Issuer Entity ID for the SAML Identity Provider", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "organization", + "description": "Organization this Identity Provider belongs to", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signatureMethod", + "description": "The signature algorithm used to sign SAML requests for the Identity Provider.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ssoUrl", + "description": "The URL endpoint for the Identity Provider's SAML SSO.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationMemberConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "OrganizationMemberEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "OrganizationMemberEdge", + "description": "Represents a user within an organization.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasTwoFactorEnabled", + "description": "Whether the organization member has two factor enabled or not. Returns null if information is not available to viewer.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "role", + "description": "The role this user has in the organization.", + "args": [], + "type": { + "kind": "ENUM", + "name": "OrganizationMemberRole", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "OrganizationMemberRole", + "description": "The possible roles within an organization for its members.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "MEMBER", + "description": "The user is a member of the organization.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ADMIN", + "description": "The user is an administrator of the organization.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TeamRole", + "description": "The role of a user on a team.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ADMIN", + "description": "User has admin rights on the team.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MEMBER", + "description": "User is a member of the team.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GistConnection", + "description": "The connection type for Gist.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GistEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GistEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Gist", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "GistPrivacy", + "description": "The privacy of a Gist", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PUBLIC", + "description": "Public", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SECRET", + "description": "Secret", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALL", + "description": "Gists that are public and secret", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "GistOrder", + "description": "Ordering options for gist connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order repositories by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "GistOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "GistOrderField", + "description": "Properties by which gist connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CREATED_AT", + "description": "Order gists by creation time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order gists by update time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PUSHED_AT", + "description": "Order gists by push time", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryInvitationEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "RepositoryInvitation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryInvitation", + "description": "An invitation for a user to be added to a repository.", + "fields": [ + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "invitee", + "description": "The user who received the invitation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inviter", + "description": "The user who created the invitation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permission", + "description": "The permission granted on this repository by this invitation.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryPermission", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository the user is invited to.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "RepositoryInfo", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LanguageConnection", + "description": "A list of languages associated with the parent.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "LanguageEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Language", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalSize", + "description": "The total size in bytes of files written in that language.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LanguageEdge", + "description": "Represents the language of a repository.", + "fields": [ + { + "name": "cursor", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Language", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "size", + "description": "The number of bytes of code written in the language.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Milestone", + "description": "Represents a Milestone object on a given repository.", + "fields": [ + { + "name": "closed", + "description": "`true` if the object is closed (definition of closed may depend on type)", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closedAt", + "description": "Identifies the date and time when the object was closed.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "Identifies the actor who created the milestone.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "Identifies the description of the milestone.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "dueOn", + "description": "Identifies the due date of the milestone.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issues", + "description": "A list of issues associated with the milestone.", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "states", + "description": "A list of states to filter the issues by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "filterBy", + "description": "Filtering options for issues returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueFilters", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "number", + "description": "Identifies the number of the milestone.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequests", + "description": "A list of pull requests associated with the milestone.", + "args": [ + { + "name": "states", + "description": "A list of states to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestState", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "labels", + "description": "A list of label names to filter the pull requests by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "headRefName", + "description": "The head ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The base ref name to filter the pull requests by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for pull requests returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "IssueOrder", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this milestone.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this milestone", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Identifies the state of the milestone.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "MilestoneState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "Identifies the title of the milestone.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this milestone", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Closable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "MilestoneState", + "description": "The possible states of a milestone.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OPEN", + "description": "A milestone that is still open.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CLOSED", + "description": "A milestone that has been closed.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestChangedFileConnection", + "description": "The connection type for PullRequestChangedFile.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestChangedFileEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestChangedFile", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestChangedFileEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestChangedFile", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestChangedFile", + "description": "A file changed in a pull request.", + "fields": [ + { + "name": "additions", + "description": "The number of additions to the file.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletions", + "description": "The number of deletions to the file.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "path", + "description": "The path of the file.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "MergeableState", + "description": "Whether or not a PullRequest can be merged.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "MERGEABLE", + "description": "The pull request can be merged.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CONFLICTING", + "description": "The pull request cannot be merged due to merge conflicts.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNKNOWN", + "description": "The mergeability of the pull request is still being calculated.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "description": "A review comment associated with a given repository pull request.", + "fields": [ + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "The comment body of this review comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The comment body of this review comment rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The comment body of this review comment rendered as plain text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "Identifies the commit associated with the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies when the comment was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "diffHunk", + "description": "The diff hunk to which the comment applies.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "draftedAt", + "description": "Identifies when the comment was created in a draft state.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isMinimized", + "description": "Returns whether or not a comment has been minimized.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "minimizedReason", + "description": "Returns why the comment was minimized.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "originalCommit", + "description": "Identifies the original commit associated with the comment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "originalPosition", + "description": "The original line index in the diff to which the comment applies.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "outdated", + "description": "Identifies when the comment body is outdated", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "path", + "description": "The path to which the comment applies.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "position", + "description": "The line index in the diff to which the comment applies.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request associated with this review comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The pull request review associated with this review comment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "replyTo", + "description": "The comment this is a reply to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path permalink for this review comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Identifies the state of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestReviewCommentState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies when the comment was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL permalink for this review comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanDelete", + "description": "Check if the current viewer can delete this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanMinimize", + "description": "Check if the current viewer can minimize this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Deletable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "description": "A review object for a given pull request.", + "fields": [ + { + "name": "author", + "description": "The actor who authored the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "authorAssociation", + "description": "Author's association with the subject of the comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentAuthorAssociation", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "body", + "description": "Identifies the pull request review body.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyHTML", + "description": "The body of this review rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "bodyText", + "description": "The body of this review rendered as plain text.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "comments", + "description": "A list of review comments for the current pull request review.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "Identifies the commit associated with this pull request review.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdViaEmail", + "description": "Check if this comment was created via an email reply.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "editor", + "description": "The actor who edited the comment.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "includesCreatedEdit", + "description": "Check if this comment was edited and includes an edit with the creation data", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastEditedAt", + "description": "The moment the editor made the last edit", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "onBehalfOf", + "description": "A list of teams that this review was made on behalf of.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TeamConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "Identifies when the comment was published at.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "Identifies the pull request associated with this pull request review.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactionGroups", + "description": "A list of reactions grouped by content left on the subject.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionGroup", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reactions", + "description": "A list of Reactions left on the Issue.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "content", + "description": "Allows filtering Reactions by emoji.", + "type": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Allows specifying the order in which reactions are returned.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ReactionOrder", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReactionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path permalink for this PullRequestReview.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "Identifies the current state of the pull request review.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestReviewState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "submittedAt", + "description": "Identifies when the Pull Request Review was submitted", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the object was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL permalink for this PullRequestReview.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userContentEdits", + "description": "A list of edits to this content.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UserContentEditConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanDelete", + "description": "Check if the current viewer can delete this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanReact", + "description": "Can user react to this subject", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUpdate", + "description": "Check if the current viewer can update this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCannotUpdateReasons", + "description": "Reasons why the current viewer can not update this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommentCannotUpdateReason", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerDidAuthor", + "description": "Did the viewer author this comment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Comment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Deletable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Updatable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UpdatableComment", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestReviewState", + "description": "The possible states of a pull request review.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PENDING", + "description": "A review that has not yet been submitted.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMMENTED", + "description": "An informational review.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "APPROVED", + "description": "A review allowing the pull request to merge.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CHANGES_REQUESTED", + "description": "A review blocking the pull request from merging.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DISMISSED", + "description": "A review that has been dismissed.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewCommentConnection", + "description": "The connection type for PullRequestReviewComment.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewCommentEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewCommentEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "description": "A threaded list of comments for a given pull request.", + "fields": [ + { + "name": "comments", + "description": "A list of pull request comments associated with the thread.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isResolved", + "description": "Whether this thread has been resolved", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "Identifies the pull request associated with this thread.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "Identifies the repository associated with this thread.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resolvedBy", + "description": "The user who resolved this thread", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanResolve", + "description": "Whether or not the viewer can resolve this thread", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "viewerCanUnresolve", + "description": "Whether or not the viewer can unresolve this thread", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommit", + "description": "Represents a Git commit part of a pull request.", + "fields": [ + { + "name": "commit", + "description": "The Git commit object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request this commit belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this pull request commit", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this pull request commit", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewThreadConnection", + "description": "Review comment threads for a pull request review.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewThreadEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewThreadEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestReviewCommentState", + "description": "The possible states of a pull request review comment.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PENDING", + "description": "A comment that is part of a pending review", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUBMITTED", + "description": "A comment that is part of a submitted review", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestPubSubTopic", + "description": "The possible PubSub channels for a pull request.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "UPDATED", + "description": "The channel ID for observing pull request updates.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MARKASREAD", + "description": "The channel ID for marking an pull request as read.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HEAD_REF", + "description": "The channel ID for observing head ref updates.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TIMELINE", + "description": "The channel ID for updating items on the pull request timeline.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "STATE", + "description": "The channel ID for observing pull request state updates.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueCommentConnection", + "description": "The connection type for IssueComment.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueCommentEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueCommentEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewConnection", + "description": "The connection type for PullRequestReview.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommitConnection", + "description": "The connection type for PullRequestCommit.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestCommitEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestCommit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommitEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestCommit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestConnection", + "description": "The connection type for ReviewRequest.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReviewRequestEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReviewRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ReviewRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequest", + "description": "A request for a user to review a pull request.", + "fields": [ + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "Identifies the pull request associated with this review request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requestedReviewer", + "description": "The reviewer that is requested.", + "args": [], + "type": { + "kind": "UNION", + "name": "RequestedReviewer", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "RequestedReviewer", + "description": "Types that can be requested reviewers.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "PullRequestTimelineConnection", + "description": "The connection type for PullRequestTimelineItem.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestTimelineItemEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "UNION", + "name": "PullRequestTimelineItem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestTimelineItemEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "UNION", + "name": "PullRequestTimelineItem", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "PullRequestTimelineItem", + "description": "An item in an pull request timeline", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommitCommentThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReopenedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnsubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MergedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AssignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnassignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DemilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RenamedTitleEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeployedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeploymentEnvironmentChangedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefRestoredEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefForcePushedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "BaseRefForcePushedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestRemovedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserBlockedEvent", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "CommitCommentThread", + "description": "A thread of comments on a commit.", + "fields": [ + { + "name": "comments", + "description": "The comments that exist in this thread.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "The commit the comments were made on.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "path", + "description": "The file the comments were made on.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "position", + "description": "The position in the diff for the commit that the comment was made on.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "description": "Represents a 'closed' event on any `Closable`.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closable", + "description": "Object that was closed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Closable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closer", + "description": "Object which triggered the creation of this event.", + "args": [], + "type": { + "kind": "UNION", + "name": "Closer", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this closed event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this closed event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "Closer", + "description": "The object which triggered a `ClosedEvent`.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "ReopenedEvent", + "description": "Represents a 'reopened' event on any `Closable`.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closable", + "description": "Object that was reopened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Closable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SubscribedEvent", + "description": "Represents a 'subscribed' event on a given `Subscribable`.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subscribable", + "description": "Object referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnsubscribedEvent", + "description": "Represents an 'unsubscribed' event on a given `Subscribable`.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subscribable", + "description": "Object referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MergedEvent", + "description": "Represents a 'merged' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "Identifies the commit associated with the `merge` event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergeRef", + "description": "Identifies the Ref associated with the `merge` event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergeRefName", + "description": "Identifies the name of the Ref associated with the `merge` event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this merged event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this merged event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReferencedEvent", + "description": "Represents a 'referenced' event on a given `ReferencedSubject`.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "Identifies the commit associated with the 'referenced' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitRepository", + "description": "Identifies the repository associated with the 'referenced' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isCrossRepository", + "description": "Reference originated in a different repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDirectReference", + "description": "Checks if the commit message itself references the subject. Can be false in the case of a commit comment reference.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "Object referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "ReferencedSubject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "ReferencedSubject", + "description": "Any referencable object", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "description": "Represents a mention made by one issue or pull request to another.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isCrossRepository", + "description": "Reference originated in a different repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "referencedAt", + "description": "Identifies when the reference was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "source", + "description": "Issue or pull request that made the reference.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "ReferencedSubject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "target", + "description": "Issue or pull request to which the reference was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "ReferencedSubject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "willCloseTarget", + "description": "Checks if the target will be closed when the source is merged.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AssignedEvent", + "description": "Represents an 'assigned' event on any assignable object.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "assignable", + "description": "Identifies the assignable associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Assignable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "Identifies the user who was assigned.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnassignedEvent", + "description": "Represents an 'unassigned' event on any assignable object.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "assignable", + "description": "Identifies the assignable associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Assignable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "Identifies the subject (user) who was unassigned.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LabeledEvent", + "description": "Represents a 'labeled' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "label", + "description": "Identifies the label associated with the 'labeled' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Label", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labelable", + "description": "Identifies the `Labelable` associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnlabeledEvent", + "description": "Represents an 'unlabeled' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "label", + "description": "Identifies the label associated with the 'unlabeled' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Label", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labelable", + "description": "Identifies the `Labelable` associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MilestonedEvent", + "description": "Represents a 'milestoned' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "milestoneTitle", + "description": "Identifies the milestone title associated with the 'milestoned' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "Object referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "MilestoneItem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "MilestoneItem", + "description": "Types that can be inside a Milestone.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "DemilestonedEvent", + "description": "Represents a 'demilestoned' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "milestoneTitle", + "description": "Identifies the milestone title associated with the 'demilestoned' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "Object referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "MilestoneItem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RenamedTitleEvent", + "description": "Represents a 'renamed' event on a given issue or pull request", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "currentTitle", + "description": "Identifies the current title of the issue or pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "previousTitle", + "description": "Identifies the previous title of the issue or pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "Subject that was renamed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "RenamedTitleSubject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "RenamedTitleSubject", + "description": "An object which has a renamable title", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "LockedEvent", + "description": "Represents a 'locked' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockReason", + "description": "Reason that the conversation was locked (optional).", + "args": [], + "type": { + "kind": "ENUM", + "name": "LockReason", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockable", + "description": "Object that was locked.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Lockable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnlockedEvent", + "description": "Represents an 'unlocked' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockable", + "description": "Object that was unlocked.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Lockable", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeployedEvent", + "description": "Represents a 'deployed' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deployment", + "description": "The deployment associated with the 'deployed' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Deployment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ref", + "description": "The ref associated with the 'deployed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeploymentEnvironmentChangedEvent", + "description": "Represents a 'deployment_environment_changed' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deploymentStatus", + "description": "The deployment status that updated the deployment environment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeploymentStatus", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "HeadRefDeletedEvent", + "description": "Represents a 'head_ref_deleted' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRef", + "description": "Identifies the Ref associated with the `head_ref_deleted` event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "headRefName", + "description": "Identifies the name of the Ref associated with the `head_ref_deleted` event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "HeadRefRestoredEvent", + "description": "Represents a 'head_ref_restored' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "HeadRefForcePushedEvent", + "description": "Represents a 'head_ref_force_pushed' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "afterCommit", + "description": "Identifies the after commit SHA for the 'head_ref_force_pushed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "beforeCommit", + "description": "Identifies the before commit SHA for the 'head_ref_force_pushed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ref", + "description": "Identifies the fully qualified ref name for the 'head_ref_force_pushed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BaseRefForcePushedEvent", + "description": "Represents a 'base_ref_force_pushed' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "afterCommit", + "description": "Identifies the after commit SHA for the 'base_ref_force_pushed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "beforeCommit", + "description": "Identifies the before commit SHA for the 'base_ref_force_pushed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ref", + "description": "Identifies the fully qualified ref name for the 'base_ref_force_pushed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestedEvent", + "description": "Represents an 'review_requested' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requestedReviewer", + "description": "Identifies the reviewer whose review was requested.", + "args": [], + "type": { + "kind": "UNION", + "name": "RequestedReviewer", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestRemovedEvent", + "description": "Represents an 'review_request_removed' event on a given pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requestedReviewer", + "description": "Identifies the reviewer whose review request was removed.", + "args": [], + "type": { + "kind": "UNION", + "name": "RequestedReviewer", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissedEvent", + "description": "Represents a 'review_dismissed' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "dismissalMessage", + "description": "Identifies the optional message associated with the 'review_dismissed' event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "dismissalMessageHTML", + "description": "Identifies the optional message associated with the event, rendered to HTML.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "Identifies the message associated with the 'review_dismissed' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "`message` is being removed because it not nullable, whereas the underlying field is optional. Use `dismissalMessage` instead. Removal on 2019-07-01 UTC." + }, + { + "name": "messageHtml", + "description": "The message associated with the event, rendered to HTML.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "HTML", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "`messageHtml` is being removed because it not nullable, whereas the underlying field is optional. Use `dismissalMessageHTML` instead. Removal on 2019-07-01 UTC." + }, + { + "name": "previousReviewState", + "description": "Identifies the previous state of the review with the 'review_dismissed' event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestReviewState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "PullRequest referenced by event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestCommit", + "description": "Identifies the commit which caused the review to become stale.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestCommit", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this review dismissed event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "review", + "description": "Identifies the review associated with the 'review_dismissed' event.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this review dismissed event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "UniformResourceLocatable", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UserBlockedEvent", + "description": "Represents a 'user_blocked' event on a given user.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "blockDuration", + "description": "Number of days that the user was blocked for.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "UserBlockDuration", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "The user who was blocked.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "UserBlockDuration", + "description": "The possible durations that a user can be blocked for.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ONE_DAY", + "description": "The user was blocked for 1 day", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "THREE_DAYS", + "description": "The user was blocked for 3 days", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ONE_WEEK", + "description": "The user was blocked for 7 days", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ONE_MONTH", + "description": "The user was blocked for 30 days", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PERMANENT", + "description": "The user was blocked permanently", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestTimelineItemsConnection", + "description": "The connection type for PullRequestTimelineItems.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestTimelineItemsEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filteredCount", + "description": "Identifies the count of items after applying `before` and `after` filters.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "UNION", + "name": "PullRequestTimelineItems", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageCount", + "description": "Identifies the count of items after applying `before`/`after` filters and `first`/`last`/`skip` slicing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the timeline was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestTimelineItemsEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "UNION", + "name": "PullRequestTimelineItems", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "PullRequestTimelineItems", + "description": "An item in a pull request timeline", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "PullRequestCommit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestCommitCommentThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequestRevisionMarker", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "BaseRefChangedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "BaseRefForcePushedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeployedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DeploymentEnvironmentChangedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefForcePushedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "HeadRefRestoredEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MergedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReviewRequestRemovedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AddedToProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AssignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommentDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ConvertedNoteToIssueEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DemilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MentionedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MovedColumnsInProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PinnedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RemovedFromProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RenamedTitleEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReopenedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "TransferredEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnassignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserBlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnpinnedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnsubscribedEvent", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "PullRequestCommitCommentThread", + "description": "Represents a commit comment thread part of a pull request.", + "fields": [ + { + "name": "comments", + "description": "The comments that exist in this thread.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitCommentConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commit", + "description": "The commit the comments were made on.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "path", + "description": "The file the comments were made on.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "position", + "description": "The position in the diff for the commit that the comment was made on.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request this commit comment thread belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this node.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "RepositoryNode", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestRevisionMarker", + "description": "Represents the latest point in the pull request timeline for which the viewer has seen the pull request's commits.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lastSeenCommit", + "description": "The last commit the viewer has seen.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request to which the marker belongs.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BaseRefChangedEvent", + "description": "Represents a 'base_ref_changed' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddedToProjectEvent", + "description": "Represents a 'added_to_project' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommentDeletedEvent", + "description": "Represents a 'comment_deleted' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ConvertedNoteToIssueEvent", + "description": "Represents a 'converted_note_to_issue' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "IssueOrPullRequest", + "description": "Used for return value of Repository.issueOrPullRequest.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "MentionedEvent", + "description": "Represents a 'mentioned' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MovedColumnsInProjectEvent", + "description": "Represents a 'moved_columns_in_project' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PinnedEvent", + "description": "Represents a 'pinned' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "Identifies the issue associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RemovedFromProjectEvent", + "description": "Represents a 'removed_from_project' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TransferredEvent", + "description": "Represents a 'transferred' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fromRepository", + "description": "The repository this came from", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "Identifies the issue associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnpinnedEvent", + "description": "Represents an 'unpinned' event on a given issue or pull request.", + "fields": [ + { + "name": "actor", + "description": "Identifies the actor who performed the event.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "Identifies the issue associated with the event.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestTimelineItemsItemType", + "description": "The possible item types found in a timeline.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PULL_REQUEST_COMMIT", + "description": "Represents a Git commit part of a pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PULL_REQUEST_COMMIT_COMMENT_THREAD", + "description": "Represents a commit comment thread part of a pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PULL_REQUEST_REVIEW", + "description": "A review object for a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PULL_REQUEST_REVIEW_THREAD", + "description": "A threaded list of comments for a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PULL_REQUEST_REVISION_MARKER", + "description": "Represents the latest point in the pull request timeline for which the viewer has seen the pull request's commits.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BASE_REF_CHANGED_EVENT", + "description": "Represents a 'base_ref_changed' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BASE_REF_FORCE_PUSHED_EVENT", + "description": "Represents a 'base_ref_force_pushed' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DEPLOYED_EVENT", + "description": "Represents a 'deployed' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DEPLOYMENT_ENVIRONMENT_CHANGED_EVENT", + "description": "Represents a 'deployment_environment_changed' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HEAD_REF_DELETED_EVENT", + "description": "Represents a 'head_ref_deleted' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HEAD_REF_FORCE_PUSHED_EVENT", + "description": "Represents a 'head_ref_force_pushed' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HEAD_REF_RESTORED_EVENT", + "description": "Represents a 'head_ref_restored' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MERGED_EVENT", + "description": "Represents a 'merged' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REVIEW_DISMISSED_EVENT", + "description": "Represents a 'review_dismissed' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REVIEW_REQUESTED_EVENT", + "description": "Represents an 'review_requested' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REVIEW_REQUEST_REMOVED_EVENT", + "description": "Represents an 'review_request_removed' event on a given pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ISSUE_COMMENT", + "description": "Represents a comment on an Issue.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CROSS_REFERENCED_EVENT", + "description": "Represents a mention made by one issue or pull request to another.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ADDED_TO_PROJECT_EVENT", + "description": "Represents a 'added_to_project' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ASSIGNED_EVENT", + "description": "Represents an 'assigned' event on any assignable object.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CLOSED_EVENT", + "description": "Represents a 'closed' event on any `Closable`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMMENT_DELETED_EVENT", + "description": "Represents a 'comment_deleted' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CONVERTED_NOTE_TO_ISSUE_EVENT", + "description": "Represents a 'converted_note_to_issue' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DEMILESTONED_EVENT", + "description": "Represents a 'demilestoned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LABELED_EVENT", + "description": "Represents a 'labeled' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LOCKED_EVENT", + "description": "Represents a 'locked' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MENTIONED_EVENT", + "description": "Represents a 'mentioned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MILESTONED_EVENT", + "description": "Represents a 'milestoned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MOVED_COLUMNS_IN_PROJECT_EVENT", + "description": "Represents a 'moved_columns_in_project' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PINNED_EVENT", + "description": "Represents a 'pinned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REFERENCED_EVENT", + "description": "Represents a 'referenced' event on a given `ReferencedSubject`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REMOVED_FROM_PROJECT_EVENT", + "description": "Represents a 'removed_from_project' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RENAMED_TITLE_EVENT", + "description": "Represents a 'renamed' event on a given issue or pull request", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REOPENED_EVENT", + "description": "Represents a 'reopened' event on any `Closable`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUBSCRIBED_EVENT", + "description": "Represents a 'subscribed' event on a given `Subscribable`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TRANSFERRED_EVENT", + "description": "Represents a 'transferred' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNASSIGNED_EVENT", + "description": "Represents an 'unassigned' event on any assignable object.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNLABELED_EVENT", + "description": "Represents an 'unlabeled' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNLOCKED_EVENT", + "description": "Represents an 'unlocked' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "USER_BLOCKED_EVENT", + "description": "Represents a 'user_blocked' event on a given user.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNPINNED_EVENT", + "description": "Represents an 'unpinned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNSUBSCRIBED_EVENT", + "description": "Represents an 'unsubscribed' event on a given `Subscribable`.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SuggestedReviewer", + "description": "A suggestion to review a pull request based on a user's commit history and review comments.", + "fields": [ + { + "name": "isAuthor", + "description": "Is this suggestion based on past commits?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isCommenter", + "description": "Is this suggestion based on past review comments?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reviewer", + "description": "Identifies the user suggested to review the pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ProjectCardArchivedState", + "description": "The possible archived states of a project card.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ARCHIVED", + "description": "A project card that is archived", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NOT_ARCHIVED", + "description": "A project card that is not archived", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueTimelineConnection", + "description": "The connection type for IssueTimelineItem.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueTimelineItemEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "UNION", + "name": "IssueTimelineItem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueTimelineItemEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssueTimelineItem", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "IssueTimelineItem", + "description": "An item in an issue timeline", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Commit", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReopenedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnsubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AssignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnassignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserBlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DemilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RenamedTitleEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "TransferredEvent", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "IssueTimelineItemsConnection", + "description": "The connection type for IssueTimelineItems.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueTimelineItemsEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filteredCount", + "description": "Identifies the count of items after applying `before` and `after` filters.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "UNION", + "name": "IssueTimelineItems", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageCount", + "description": "Identifies the count of items after applying `before`/`after` filters and `first`/`last`/`skip` slicing.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "Identifies the date and time when the timeline was last updated.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueTimelineItemsEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssueTimelineItems", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "IssueTimelineItems", + "description": "An item in an issue timeline", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CrossReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AddedToProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "AssignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ClosedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CommentDeletedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ConvertedNoteToIssueEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "DemilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "LockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MentionedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MilestonedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MovedColumnsInProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PinnedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReferencedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RemovedFromProjectEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RenamedTitleEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "ReopenedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "SubscribedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "TransferredEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnassignedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlabeledEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UserBlockedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnpinnedEvent", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "UnsubscribedEvent", + "ofType": null + } + ] + }, + { + "kind": "ENUM", + "name": "IssueTimelineItemsItemType", + "description": "The possible item types found in a timeline.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ISSUE_COMMENT", + "description": "Represents a comment on an Issue.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CROSS_REFERENCED_EVENT", + "description": "Represents a mention made by one issue or pull request to another.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ADDED_TO_PROJECT_EVENT", + "description": "Represents a 'added_to_project' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ASSIGNED_EVENT", + "description": "Represents an 'assigned' event on any assignable object.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CLOSED_EVENT", + "description": "Represents a 'closed' event on any `Closable`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMMENT_DELETED_EVENT", + "description": "Represents a 'comment_deleted' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CONVERTED_NOTE_TO_ISSUE_EVENT", + "description": "Represents a 'converted_note_to_issue' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DEMILESTONED_EVENT", + "description": "Represents a 'demilestoned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LABELED_EVENT", + "description": "Represents a 'labeled' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LOCKED_EVENT", + "description": "Represents a 'locked' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MENTIONED_EVENT", + "description": "Represents a 'mentioned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MILESTONED_EVENT", + "description": "Represents a 'milestoned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MOVED_COLUMNS_IN_PROJECT_EVENT", + "description": "Represents a 'moved_columns_in_project' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PINNED_EVENT", + "description": "Represents a 'pinned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REFERENCED_EVENT", + "description": "Represents a 'referenced' event on a given `ReferencedSubject`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REMOVED_FROM_PROJECT_EVENT", + "description": "Represents a 'removed_from_project' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RENAMED_TITLE_EVENT", + "description": "Represents a 'renamed' event on a given issue or pull request", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REOPENED_EVENT", + "description": "Represents a 'reopened' event on any `Closable`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUBSCRIBED_EVENT", + "description": "Represents a 'subscribed' event on a given `Subscribable`.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TRANSFERRED_EVENT", + "description": "Represents a 'transferred' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNASSIGNED_EVENT", + "description": "Represents an 'unassigned' event on any assignable object.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNLABELED_EVENT", + "description": "Represents an 'unlabeled' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNLOCKED_EVENT", + "description": "Represents an 'unlocked' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "USER_BLOCKED_EVENT", + "description": "Represents a 'user_blocked' event on a given user.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNPINNED_EVENT", + "description": "Represents an 'unpinned' event on a given issue or pull request.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNSUBSCRIBED_EVENT", + "description": "Represents an 'unsubscribed' event on a given `Subscribable`.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "CollaboratorAffiliation", + "description": "Collaborators affiliation level with a subject.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OUTSIDE", + "description": "All outside collaborators of an organization-owned subject.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DIRECT", + "description": "All collaborators with permissions to an organization-owned subject, regardless of organization membership status.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALL", + "description": "All collaborators the authenticated user can see.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeployKeyConnection", + "description": "The connection type for DeployKey.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeployKeyEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "DeployKey", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeployKeyEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "DeployKey", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeployKey", + "description": "A repository deploy key.", + "fields": [ + { + "name": "createdAt", + "description": "Identifies the date and time when the object was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "key", + "description": "The deploy key.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "readOnly", + "description": "Whether or not the deploy key is read only.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "The deploy key title.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "verified", + "description": "Whether or not the deploy key has been verified.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RepositoryCollaboratorAffiliation", + "description": "The affiliation type between collaborator and repository.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ALL", + "description": "All collaborators of the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OUTSIDE", + "description": "All outside collaborators of an organization-owned repository.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRuleConnection", + "description": "The connection type for BranchProtectionRule.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BranchProtectionRuleEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRuleEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "description": "A branch protection rule.", + "fields": [ + { + "name": "branchProtectionRuleConflicts", + "description": "A list of conflicts matching branches protection rule and other branch protection rules", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflictConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "creator", + "description": "The actor who created this branch protection rule.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Actor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "dismissesStaleReviews", + "description": "Will new commits pushed to matching branches dismiss pull request review approvals.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isAdminEnforced", + "description": "Can admins overwrite branch protection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "matchingRefs", + "description": "Repository refs that are protected by this rule", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RefConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pattern", + "description": "Identifies the protection rule pattern.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pushAllowances", + "description": "A list push allowances for this branch protection rule.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PushAllowanceConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository associated with this branch protection rule.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiredApprovingReviewCount", + "description": "Number of approving reviews required to update matching branches.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiredStatusCheckContexts", + "description": "List of required status check contexts that must pass for commits to be accepted to matching branches.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiresApprovingReviews", + "description": "Are approving reviews required to update matching branches.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiresCommitSignatures", + "description": "Are commits required to be signed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiresStatusChecks", + "description": "Are status checks required to update matching branches.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requiresStrictStatusChecks", + "description": "Are branches required to be up to date before merging.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "restrictsPushes", + "description": "Is pushing to matching branches restricted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "restrictsReviewDismissals", + "description": "Is dismissal of pull request reviews restricted.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reviewDismissalAllowances", + "description": "A list review dismissal allowances for this branch protection rule.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReviewDismissalAllowanceConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissalAllowanceConnection", + "description": "The connection type for ReviewDismissalAllowance.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReviewDismissalAllowanceEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ReviewDismissalAllowance", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissalAllowanceEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ReviewDismissalAllowance", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReviewDismissalAllowance", + "description": "A team or user who has the ability to dismiss a review on a protected branch.", + "fields": [ + { + "name": "actor", + "description": "The actor that can dismiss.", + "args": [], + "type": { + "kind": "UNION", + "name": "ReviewDismissalAllowanceActor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "branchProtectionRule", + "description": "Identifies the branch protection rule associated with the allowed user or team.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "ReviewDismissalAllowanceActor", + "description": "Types that can be an actor.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "PushAllowanceConnection", + "description": "The connection type for PushAllowance.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PushAllowanceEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PushAllowance", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PushAllowanceEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PushAllowance", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PushAllowance", + "description": "A team or user who has the ability to push to a protected branch.", + "fields": [ + { + "name": "actor", + "description": "The actor that can push.", + "args": [], + "type": { + "kind": "UNION", + "name": "PushAllowanceActor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "branchProtectionRule", + "description": "Identifies the branch protection rule associated with the allowed user or team.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "PushAllowanceActor", + "description": "Types that can be an actor.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "RefConnection", + "description": "The connection type for Ref.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RefEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RefEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflictConnection", + "description": "The connection type for BranchProtectionRuleConflict.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflictEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflict", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflictEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflict", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "BranchProtectionRuleConflict", + "description": "A conflict between two branch protection rules.", + "fields": [ + { + "name": "branchProtectionRule", + "description": "Identifies the branch protection rule.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "conflictingBranchProtectionRule", + "description": "Identifies the conflicting branch protection rule.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ref", + "description": "Identifies the branch ref that has conflicting rules", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Ref", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MilestoneConnection", + "description": "The connection type for Milestone.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "MilestoneEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MilestoneEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Milestone", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "MilestoneOrder", + "description": "Ordering options for milestone connections.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order milestones by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "MilestoneOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "MilestoneOrderField", + "description": "Properties by which milestone connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "DUE_DATE", + "description": "Order milestones by when they are due.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CREATED_AT", + "description": "Order milestones by when they were created.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order milestones by when they were last updated.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NUMBER", + "description": "Order milestones by their number.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CodeOfConduct", + "description": "The Code of Conduct for a repository", + "fields": [ + { + "name": "body", + "description": "The body of the Code of Conduct", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "key", + "description": "The key for the Code of Conduct", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The formal name of the Code of Conduct", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this Code of Conduct", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this Code of Conduct", + "args": [], + "type": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryCollaboratorConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "RepositoryCollaboratorEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RepositoryCollaboratorEdge", + "description": "Represents a user who is a collaborator of a repository.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permission", + "description": "The permission the user has on the repository.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RepositoryPermission", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permissionSources", + "description": "A list of sources for the user's access to the repository.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PermissionSource", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PermissionSource", + "description": "A level of permission and source for a user's access to a repository.", + "fields": [ + { + "name": "organization", + "description": "The organization the repository belongs to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "permission", + "description": "The level of access this source has granted to the user.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "DefaultRepositoryPermissionField", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "source", + "description": "The source of this permission.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "PermissionGranter", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "PermissionGranter", + "description": "Types that can grant permissions on a repository to a user", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Team", + "ofType": null + } + ] + }, + { + "kind": "INPUT_OBJECT", + "name": "LanguageOrder", + "description": "Ordering options for language connections.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order languages by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "LanguageOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "LanguageOrderField", + "description": "Properties by which language connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "SIZE", + "description": "Order languages by the size of all files containing the language", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RefOrder", + "description": "Ways in which lists of git refs can be ordered upon return.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field in which to order refs by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "RefOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The direction in which to order refs by the specified field.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RefOrderField", + "description": "Properties by which ref connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "TAG_COMMIT_DATE", + "description": "Order refs by underlying commit date if the ref prefix is refs/tags/", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ALPHABETICAL", + "description": "Order refs by their alphanumeric name", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisory", + "description": "A GitHub Security Advisory", + "fields": [ + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "This is a long plaintext description of the advisory", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ghsaId", + "description": "The GitHub Security Advisory ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "identifiers", + "description": "A list of identifiers for this advisory", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisoryIdentifier", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "publishedAt", + "description": "When the advisory was published", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "references", + "description": "A list of references for this advisory", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisoryReference", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "severity", + "description": "The severity of the advisory", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisorySeverity", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "summary", + "description": "A short plaintext summary of the advisory", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "When the advisory was last updated", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "vulnerabilities", + "description": "Vulnerabilities associated with this Advisory", + "args": [ + { + "name": "orderBy", + "description": "Ordering options for the returned topics.", + "type": { + "kind": "INPUT_OBJECT", + "name": "SecurityVulnerabilityOrder", + "ofType": null + }, + "defaultValue": "{field:UPDATED_AT,direction:DESC}" + }, + { + "name": "ecosystem", + "description": "An ecosystem to filter vulnerabilities by.", + "type": { + "kind": "ENUM", + "name": "SecurityAdvisoryEcosystem", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "package", + "description": "A package name to filter vulnerabilities by.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "severities", + "description": "A list of severities to filter vulnerabilities by.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisorySeverity", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityVulnerabilityConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "withdrawnAt", + "description": "When the advisory was withdrawn, if it has been withdrawn", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SecurityAdvisorySeverity", + "description": "Severity of the vulnerability.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "LOW", + "description": "Low.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MODERATE", + "description": "Moderate.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "HIGH", + "description": "High.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "CRITICAL", + "description": "Critical.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisoryIdentifier", + "description": "A GitHub Security Advisory Identifier", + "fields": [ + { + "name": "type", + "description": "The identifier type, e.g. GHSA, CVE", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "value", + "description": "The identifier", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisoryReference", + "description": "A GitHub Security Advisory Reference", + "fields": [ + { + "name": "url", + "description": "A publicly accessible reference", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityVulnerabilityConnection", + "description": "The connection type for SecurityVulnerability.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityVulnerabilityEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityVulnerability", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityVulnerabilityEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "SecurityVulnerability", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityVulnerability", + "description": "An individual vulnerability within an Advisory", + "fields": [ + { + "name": "advisory", + "description": "The Advisory associated with this Vulnerability", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisory", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "firstPatchedVersion", + "description": "The first version containing a fix for the vulnerability", + "args": [], + "type": { + "kind": "OBJECT", + "name": "SecurityAdvisoryPackageVersion", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "package", + "description": "A description of the vulnerable package", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisoryPackage", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "severity", + "description": "The severity of the vulnerability within this package", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisorySeverity", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", + "description": "When the vulnerability was last updated", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "vulnerableVersionRange", + "description": "A string that describes the vulnerable package versions.\nThis string follows a basic syntax with a few forms.\n+ `= 0.2.0` denotes a single vulnerable version.\n+ `<= 1.0.8` denotes a version range up to and including the specified version\n+ `< 0.1.11` denotes a version range up to, but excluding, the specified version\n+ `>= 4.3.0, < 4.3.5` denotes a version range with a known minimum and maximum version.\n+ `>= 0.0.1` denotes a version range with a known minimum, but no known maximum\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisoryPackage", + "description": "An individual package", + "fields": [ + { + "name": "ecosystem", + "description": "The ecosystem the package belongs to, e.g. RUBYGEMS, NPM", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisoryEcosystem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The package name", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SecurityAdvisoryEcosystem", + "description": "The possible ecosystems of a security vulnerability's package.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "RUBYGEMS", + "description": "Ruby gems hosted at RubyGems.org", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NPM", + "description": "JavaScript packages hosted at npmjs.com", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PIP", + "description": "Python packages hosted at PyPI.org", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MAVEN", + "description": "Java artifacts hosted at the Maven central repository", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NUGET", + "description": ".NET packages hosted at the NuGet Gallery", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisoryPackageVersion", + "description": "An individual package version", + "fields": [ + { + "name": "identifier", + "description": "The package name or version", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "SecurityVulnerabilityOrder", + "description": "Ordering options for security vulnerability connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order security vulnerabilities by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityVulnerabilityOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SecurityVulnerabilityOrderField", + "description": "Properties by which security vulnerability connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "UPDATED_AT", + "description": "Order vulnerability by update time", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "GitSSHRemote", + "description": "Git SSH string", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TopicConnection", + "description": "The connection type for Topic.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TopicEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TopicEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContributionsCollection", + "description": "A contributions collection aggregates contributions such as opened issues and commits created by a user.", + "fields": [ + { + "name": "commitContributionsByRepository", + "description": "Commit contributions made by the user, grouped by repository.", + "args": [ + { + "name": "maxRepositories", + "description": "How many repositories should be included.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "25" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CommitContributionsByRepository", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "contributionCalendar", + "description": "A calendar of this user's contributions on GitHub.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ContributionCalendar", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "contributionYears", + "description": "The years the user has been making contributions with the most recent year first.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "doesEndInCurrentMonth", + "description": "Determine if this collection's time span ends in the current month.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "earliestRestrictedContributionDate", + "description": "The date of the first restricted contribution the user made in this time period. Can only be non-null when the user has enabled private contribution counts.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Date", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endedAt", + "description": "The ending date and time of this collection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "firstIssueContribution", + "description": "The first issue the user opened on GitHub. This will be null if that issue was opened outside the collection's time range and ignoreTimeRange is false. If the issue is not visible but the user has opted to show private contributions, a RestrictedContribution will be returned.", + "args": [ + { + "name": "ignoreTimeRange", + "description": "If true, the first issue will be returned even if it was opened outside of the collection's time range.\n\n**Upcoming Change on 2019-07-01 UTC**\n**Description:** `ignoreTimeRange` will be removed. Use a `ContributionsCollection` starting sufficiently far back\n**Reason:** ignore_time_range will be removed\n", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "UNION", + "name": "CreatedIssueOrRestrictedContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "firstPullRequestContribution", + "description": "The first pull request the user opened on GitHub. This will be null if that pull request was opened outside the collection's time range and ignoreTimeRange is not true. If the pull request is not visible but the user has opted to show private contributions, a RestrictedContribution will be returned.", + "args": [ + { + "name": "ignoreTimeRange", + "description": "If true, the first pull request will be returned even if it was opened outside of the collection's time range.\n\n**Upcoming Change on 2019-07-01 UTC**\n**Description:** `ignoreTimeRange` will be removed. Use a `ContributionsCollection` starting sufficiently far back\n**Reason:** ignore_time_range will be removed\n", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "UNION", + "name": "CreatedPullRequestOrRestrictedContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "firstRepositoryContribution", + "description": "The first repository the user created on GitHub. This will be null if that first repository was created outside the collection's time range and ignoreTimeRange is false. If the repository is not visible, then a RestrictedContribution is returned.", + "args": [ + { + "name": "ignoreTimeRange", + "description": "If true, the first repository will be returned even if it was opened outside of the collection's time range.\n\n**Upcoming Change on 2019-07-01 UTC**\n**Description:** `ignoreTimeRange` will be removed. Use a `ContributionsCollection` starting sufficiently far back\n**Reason:** ignore_time_range will be removed\n", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "UNION", + "name": "CreatedRepositoryOrRestrictedContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasActivityInThePast", + "description": "Does the user have any more activity in the timeline that occurred prior to the collection's time range?", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasAnyContributions", + "description": "Determine if there are any contributions in this collection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hasAnyRestrictedContributions", + "description": "Determine if the user made any contributions in this time frame whose details are not visible because they were made in a private repository. Can only be true if the user enabled private contribution counts.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isSingleDay", + "description": "Whether or not the collector's time span is all within the same day.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issueContributions", + "description": "A list of issues the user opened.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "excludeFirst", + "description": "Should the user's first issue ever be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented issue be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedIssueContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issueContributionsByRepository", + "description": "Issue contributions made by the user, grouped by repository.", + "args": [ + { + "name": "maxRepositories", + "description": "How many repositories should be included.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "25" + }, + { + "name": "excludeFirst", + "description": "Should the user's first issue ever be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented issue be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "IssueContributionsByRepository", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "joinedGitHubContribution", + "description": "When the user signed up for GitHub. This will be null if that sign up date falls outside the collection's time range and ignoreTimeRange is false.", + "args": [ + { + "name": "ignoreTimeRange", + "description": "If true, the contribution will be returned even if the user signed up outside of the collection's time range.\n\n**Upcoming Change on 2019-07-01 UTC**\n**Description:** `ignoreTimeRange` will be removed. Use a `ContributionsCollection` starting sufficiently far back\n**Reason:** ignore_time_range will be removed\n", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "OBJECT", + "name": "JoinedGitHubContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "latestRestrictedContributionDate", + "description": "The date of the most recent restricted contribution the user made in this time period. Can only be non-null when the user has enabled private contribution counts.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Date", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mostRecentCollectionWithActivity", + "description": "When this collection's time range does not include any activity from the user, use this\nto get a different collection from an earlier time range that does have activity.\n", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ContributionsCollection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mostRecentCollectionWithoutActivity", + "description": "Returns a different contributions collection from an earlier time range than this one\nthat does not have any contributions.\n", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ContributionsCollection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "popularIssueContribution", + "description": "The issue the user opened on GitHub that received the most comments in the specified\ntime frame.\n", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedIssueContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "popularPullRequestContribution", + "description": "The pull request the user opened on GitHub that received the most comments in the\nspecified time frame.\n", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedPullRequestContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestContributions", + "description": "Pull request contributions made by the user.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "excludeFirst", + "description": "Should the user's first pull request ever be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented pull request be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestContributionsByRepository", + "description": "Pull request contributions made by the user, grouped by repository.", + "args": [ + { + "name": "maxRepositories", + "description": "How many repositories should be included.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "25" + }, + { + "name": "excludeFirst", + "description": "Should the user's first pull request ever be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented pull request be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestContributionsByRepository", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReviewContributions", + "description": "Pull request review contributions made by the user.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReviewContributionsByRepository", + "description": "Pull request review contributions made by the user, grouped by repository.", + "args": [ + { + "name": "maxRepositories", + "description": "How many repositories should be included.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "25" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReviewContributionsByRepository", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoryContributions", + "description": "A list of repositories owned by the user that the user created in this time range.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "excludeFirst", + "description": "Should the user's first repository ever be excluded from the result.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedRepositoryContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "restrictedContributionsCount", + "description": "A count of contributions made by the user that the viewer cannot access. Only non-zero when the user has chosen to share their private contribution counts.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "startedAt", + "description": "The beginning date and time of this collection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCommitContributions", + "description": "How many commits were made by the user in this time span.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalIssueContributions", + "description": "How many issues the user opened.", + "args": [ + { + "name": "excludeFirst", + "description": "Should the user's first issue ever be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented issue be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalPullRequestContributions", + "description": "How many pull requests the user opened.", + "args": [ + { + "name": "excludeFirst", + "description": "Should the user's first pull request ever be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented pull request be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalPullRequestReviewContributions", + "description": "How many pull request reviews the user left.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalRepositoriesWithContributedCommits", + "description": "How many different repositories the user committed to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalRepositoriesWithContributedIssues", + "description": "How many different repositories the user opened issues in.", + "args": [ + { + "name": "excludeFirst", + "description": "Should the user's first issue ever be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented issue be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalRepositoriesWithContributedPullRequestReviews", + "description": "How many different repositories the user left pull request reviews in.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalRepositoriesWithContributedPullRequests", + "description": "How many different repositories the user opened pull requests in.", + "args": [ + { + "name": "excludeFirst", + "description": "Should the user's first pull request ever be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "excludePopular", + "description": "Should the user's most commented pull request be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalRepositoryContributions", + "description": "How many repositories the user created.", + "args": [ + { + "name": "excludeFirst", + "description": "Should the user's first repository ever be excluded from this count.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made the contributions in this collection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedIssueContributionConnection", + "description": "The connection type for CreatedIssueContribution.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedIssueContributionEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedIssueContribution", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedIssueContributionEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedIssueContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedIssueContribution", + "description": "Represents the contribution a user made on GitHub by opening an issue.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "The issue that was opened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INTERFACE", + "name": "Contribution", + "description": "Represents a contribution a user made on GitHub, such as opening an issue.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CreatedCommitContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CreatedIssueContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "CreatedRepositoryContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "JoinedGitHubContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RestrictedContribution", + "ofType": null + } + ] + }, + { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "description": "Ordering options for contribution connections.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field by which to order contributions.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ContributionOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ContributionOrderField", + "description": "Properties by which contribution connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OCCURRED_AT", + "description": "Order contributions by when they were made.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedRepositoryContributionConnection", + "description": "The connection type for CreatedRepositoryContribution.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedRepositoryContributionEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedRepositoryContribution", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedRepositoryContributionEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedRepositoryContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedRepositoryContribution", + "description": "Represents the contribution a user made on GitHub by creating a repository.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository that was created.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "JoinedGitHubContribution", + "description": "Represents a user signing up for a GitHub account.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "CreatedRepositoryOrRestrictedContribution", + "description": "Represents either a repository the viewer can access or a restricted contribution.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CreatedRepositoryContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RestrictedContribution", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "RestrictedContribution", + "description": "Represents a private contribution a user made on GitHub.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "CreatedIssueOrRestrictedContribution", + "description": "Represents either a issue the viewer can access or a restricted contribution.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CreatedIssueContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RestrictedContribution", + "ofType": null + } + ] + }, + { + "kind": "UNION", + "name": "CreatedPullRequestOrRestrictedContribution", + "description": "Represents either a pull request the viewer can access or a restricted contribution.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CreatedPullRequestContribution", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "RestrictedContribution", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestContribution", + "description": "Represents the contribution a user made on GitHub by opening a pull request.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request that was opened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContributionCalendar", + "description": "A calendar of contributions made on GitHub by a user.", + "fields": [ + { + "name": "colors", + "description": "A list of hex color codes used in this calendar. The darker the color, the more contributions it represents.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isHalloween", + "description": "Determine if the color set was chosen because it's currently Halloween.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "months", + "description": "A list of the months of contributions in this calendar.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ContributionCalendarMonth", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalContributions", + "description": "The count of total contributions in the calendar.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "weeks", + "description": "A list of the weeks of contributions in this calendar.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ContributionCalendarWeek", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContributionCalendarWeek", + "description": "A week of contributions in a user's contribution graph.", + "fields": [ + { + "name": "contributionDays", + "description": "The days of contributions in this week.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ContributionCalendarDay", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "firstDay", + "description": "The date of the earliest square in this week.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Date", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContributionCalendarDay", + "description": "Represents a single day of contributions on GitHub by a user.", + "fields": [ + { + "name": "color", + "description": "The hex color code that represents how many contributions were made on this day compared to others in the calendar.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "contributionCount", + "description": "How many contributions were made by the user on this day.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "date", + "description": "The day this square represents.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Date", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "weekday", + "description": "A number representing which day of the week this square represents, e.g., 1 is Monday.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContributionCalendarMonth", + "description": "A month of contributions in a user's contribution graph.", + "fields": [ + { + "name": "firstDay", + "description": "The date of the first day of this month.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Date", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The name of the month.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalWeeks", + "description": "How many weeks started in this month.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "year", + "description": "The year the month occurred in.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContributionConnection", + "description": "The connection type for CreatedPullRequestReviewContribution.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContributionEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContribution", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContributionEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContribution", + "description": "Represents the contribution a user made by leaving a review on a pull request.", + "fields": [ + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request the user reviewed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The review the user left on the pull request.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository containing the pull request that the user reviewed.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestReviewContributionsByRepository", + "description": "This aggregates pull request reviews made by a user within one repository.", + "fields": [ + { + "name": "contributions", + "description": "The pull request review contributions.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestReviewContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository in which the pull request reviews were made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CommitContributionsByRepository", + "description": "This aggregates commits made by a user within one repository.", + "fields": [ + { + "name": "contributions", + "description": "The commit contributions, each representing a day.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for commit contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "CommitContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedCommitContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository in which the commits were made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for the user's commits to the repository in this time range.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for the user's commits to the repository in this time range.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedCommitContributionConnection", + "description": "The connection type for CreatedCommitContribution.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedCommitContributionEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedCommitContribution", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of commits across days and repositories in the connection.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedCommitContributionEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedCommitContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedCommitContribution", + "description": "Represents the contribution a user made by committing to a repository.", + "fields": [ + { + "name": "commitCount", + "description": "How many commits were made on this day to this repository by the user.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isRestricted", + "description": "Whether this contribution is associated with a record you do not have access to. For\nexample, your own 'first issue' contribution may have been made on a repository you can no\nlonger access.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occurredAt", + "description": "When this contribution was made.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository the user made a commit in.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resourcePath", + "description": "The HTTP path for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "url", + "description": "The HTTP URL for this contribution.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "user", + "description": "The user who made this contribution.\n", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Contribution", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CommitContributionOrder", + "description": "Ordering options for commit contribution connections.", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field by which to order commit contributions.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "CommitContributionOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "CommitContributionOrderField", + "description": "Properties by which commit contribution connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "OCCURRED_AT", + "description": "Order commit contributions by when they were made.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMMIT_COUNT", + "description": "Order commit contributions by how many commits they represent.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestContributionConnection", + "description": "The connection type for CreatedPullRequestContribution.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestContributionEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestContribution", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatedPullRequestContributionEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "CreatedPullRequestContribution", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PullRequestContributionsByRepository", + "description": "This aggregates pull requests opened by a user within one repository.", + "fields": [ + { + "name": "contributions", + "description": "The pull request contributions.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedPullRequestContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository in which the pull requests were opened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "IssueContributionsByRepository", + "description": "This aggregates issues opened by a user within one repository.", + "fields": [ + { + "name": "contributions", + "description": "The issue contributions.", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": "Ordering options for contributions returned from the connection.", + "type": { + "kind": "INPUT_OBJECT", + "name": "ContributionOrder", + "ofType": null + }, + "defaultValue": "{field:OCCURRED_AT,direction:DESC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "CreatedIssueContributionConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository in which the issues were opened.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "RepositoryContributionType", + "description": "The reason a repository is listed as 'contributed'.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "COMMIT", + "description": "Created a commit", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ISSUE", + "description": "Created an issue", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PULL_REQUEST", + "description": "Created a pull request", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REPOSITORY", + "description": "Created the repository", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PULL_REQUEST_REVIEW", + "description": "Reviewed a pull request", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PublicKeyConnection", + "description": "The connection type for PublicKey.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PublicKeyEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PublicKey", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "PublicKeyEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PublicKey", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "FollowingConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "FollowerConnection", + "description": "The connection type for User.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "UserEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "StarredRepositoryConnection", + "description": "The connection type for Repository.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "StarredRepositoryEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "StarredRepositoryEdge", + "description": "Represents a starred repository.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "starredAt", + "description": "Identifies when the item was starred.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AppEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RateLimit", + "description": "Represents the client's rate limit.", + "fields": [ + { + "name": "cost", + "description": "The point cost for the current query counting against the rate limit.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "limit", + "description": "The maximum number of points the client is permitted to consume in a 60 minute window.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodeCount", + "description": "The maximum number of nodes this query may return", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "remaining", + "description": "The number of points remaining in the current rate limit window.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resetAt", + "description": "The time at which the current rate limit window resets in UTC epoch seconds.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SearchResultItemConnection", + "description": "A list of results that matched against a search query.", + "fields": [ + { + "name": "codeCount", + "description": "The number of pieces of code that matched the search query.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SearchResultItemEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issueCount", + "description": "The number of issues that matched the search query.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "UNION", + "name": "SearchResultItem", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repositoryCount", + "description": "The number of repositories that matched the search query.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "userCount", + "description": "The number of users that matched the search query.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "wikiCount", + "description": "The number of wiki pages that matched the search query.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SearchResultItemEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "UNION", + "name": "SearchResultItem", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "textMatches", + "description": "Text matches on the result found.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TextMatch", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "SearchResultItem", + "description": "The results of a search.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "MarketplaceListing", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "TextMatch", + "description": "A text match within a search result.", + "fields": [ + { + "name": "fragment", + "description": "The specific text fragment within the property matched on.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "highlights", + "description": "Highlights within the matched fragment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TextMatchHighlight", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "property", + "description": "The property matched on.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TextMatchHighlight", + "description": "Represents a single highlight in a search result match.", + "fields": [ + { + "name": "beginIndice", + "description": "The indice in the fragment where the matched text begins.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "endIndice", + "description": "The indice in the fragment where the matched text ends.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "text", + "description": "The text matched.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SearchType", + "description": "Represents the individual results of a search.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "ISSUE", + "description": "Returns results matching issues in repositories.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REPOSITORY", + "description": "Returns results matching repositories.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "USER", + "description": "Returns results matching users and organizations on GitHub.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "UNION", + "name": "CollectionItemContent", + "description": "Types that can be inside Collection Items.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Organization", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "User", + "ofType": null + } + ] + }, + { + "kind": "OBJECT", + "name": "GitHubMetadata", + "description": "Represents information about the GitHub instance.", + "fields": [ + { + "name": "gitHubServicesSha", + "description": "Returns a String that's a SHA of `github-services`", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "gitIpAddresses", + "description": "IP addresses that users connect to for git operations", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "hookIpAddresses", + "description": "IP addresses that service hooks are sent from", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "importerIpAddresses", + "description": "IP addresses that the importer connects from", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isPasswordAuthenticationVerifiable", + "description": "Whether or not users are verified", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pagesIpAddresses", + "description": "IP addresses for GitHub Pages' A records", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisoryConnection", + "description": "The connection type for SecurityAdvisory.", + "fields": [ + { + "name": "edges", + "description": "A list of edges.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisoryEdge", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "A list of nodes.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "SecurityAdvisory", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pageInfo", + "description": "Information to aid in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PageInfo", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalCount", + "description": "Identifies the total count of items in the connection.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SecurityAdvisoryEdge", + "description": "An edge in a connection.", + "fields": [ + { + "name": "cursor", + "description": "A cursor for use in pagination.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "The item at the end of the edge.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "SecurityAdvisory", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "SecurityAdvisoryOrder", + "description": "Ordering options for security advisory connections", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "The field to order security advisories by.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisoryOrderField", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "direction", + "description": "The ordering direction.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "OrderDirection", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SecurityAdvisoryOrderField", + "description": "Properties by which security advisory connections can be ordered.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "PUBLISHED_AT", + "description": "Order advisories by publication time", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT", + "description": "Order advisories by update time", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "SecurityAdvisoryIdentifierFilter", + "description": "An advisory identifier to filter results on.", + "fields": null, + "inputFields": [ + { + "name": "type", + "description": "The identifier type.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SecurityAdvisoryIdentifierType", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "value", + "description": "The identifier string. Supports exact or partial matching.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SecurityAdvisoryIdentifierType", + "description": "Identifier formats available for advisories.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "CVE", + "description": "Common Vulnerabilities and Exposures Identifier.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "GHSA", + "description": "GitHub Security Advisory ID.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Mutation", + "description": "The root query for implementing GraphQL mutations.", + "fields": [ + { + "name": "acceptTopicSuggestion", + "description": "Applies a suggested topic to the repository.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AcceptTopicSuggestionInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AcceptTopicSuggestionPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addAssigneesToAssignable", + "description": "Adds assignees to an assignable object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddAssigneesToAssignableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddAssigneesToAssignablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addComment", + "description": "Adds a comment to an Issue or Pull Request.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddCommentInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddCommentPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addLabelsToLabelable", + "description": "Adds labels to a labelable object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddLabelsToLabelableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddLabelsToLabelablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addProjectCard", + "description": "Adds a card to a ProjectColumn. Either `contentId` or `note` must be provided but **not** both.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddProjectCardInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddProjectCardPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addProjectColumn", + "description": "Adds a column to a Project.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddProjectColumnInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddProjectColumnPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addPullRequestReview", + "description": "Adds a review to a Pull Request.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddPullRequestReviewInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddPullRequestReviewPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addPullRequestReviewComment", + "description": "Adds a comment to a review.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddPullRequestReviewCommentInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddPullRequestReviewCommentPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addReaction", + "description": "Adds a reaction to a subject.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddReactionInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddReactionPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addStar", + "description": "Adds a star to a Starrable.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "AddStarInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "AddStarPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "changeUserStatus", + "description": "Update your status on GitHub.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ChangeUserStatusInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ChangeUserStatusPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clearLabelsFromLabelable", + "description": "Clears all labels from a labelable object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ClearLabelsFromLabelableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ClearLabelsFromLabelablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "cloneProject", + "description": "Creates a new project by cloning configuration from an existing project.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CloneProjectInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CloneProjectPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closeIssue", + "description": "Close an issue.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CloseIssueInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CloseIssuePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "closePullRequest", + "description": "Close a pull request.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ClosePullRequestInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ClosePullRequestPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "convertProjectCardNoteToIssue", + "description": "Convert a project note card to one associated with a newly created issue.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ConvertProjectCardNoteToIssueInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ConvertProjectCardNoteToIssuePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createBranchProtectionRule", + "description": "Create a new branch protection rule", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CreateBranchProtectionRuleInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CreateBranchProtectionRulePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createIssue", + "description": "Creates a new issue.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CreateIssueInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CreateIssuePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createProject", + "description": "Creates a new project.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CreateProjectInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CreateProjectPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "createPullRequest", + "description": "Create a new pull request", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CreatePullRequestInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "CreatePullRequestPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "declineTopicSuggestion", + "description": "Rejects a suggested topic for the repository.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeclineTopicSuggestionInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeclineTopicSuggestionPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deleteBranchProtectionRule", + "description": "Delete a branch protection rule", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeleteBranchProtectionRuleInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeleteBranchProtectionRulePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deleteIssue", + "description": "Deletes an Issue object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeleteIssueInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeleteIssuePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deleteIssueComment", + "description": "Deletes an IssueComment object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeleteIssueCommentInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeleteIssueCommentPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deleteProject", + "description": "Deletes a project.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeleteProjectInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeleteProjectPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deleteProjectCard", + "description": "Deletes a project card.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeleteProjectCardInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeleteProjectCardPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deleteProjectColumn", + "description": "Deletes a project column.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeleteProjectColumnInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeleteProjectColumnPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletePullRequestReview", + "description": "Deletes a pull request review.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeletePullRequestReviewInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeletePullRequestReviewPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletePullRequestReviewComment", + "description": "Deletes a pull request review comment.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DeletePullRequestReviewCommentInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DeletePullRequestReviewCommentPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "dismissPullRequestReview", + "description": "Dismisses an approved or rejected pull request review.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DismissPullRequestReviewInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "DismissPullRequestReviewPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockLockable", + "description": "Lock a lockable object", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "LockLockableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LockLockablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mergePullRequest", + "description": "Merge a pull request.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "MergePullRequestInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "MergePullRequestPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "moveProjectCard", + "description": "Moves a project card to another place.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "MoveProjectCardInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "MoveProjectCardPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "moveProjectColumn", + "description": "Moves a project column to another place.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "MoveProjectColumnInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "MoveProjectColumnPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removeAssigneesFromAssignable", + "description": "Removes assignees from an assignable object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RemoveAssigneesFromAssignableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RemoveAssigneesFromAssignablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removeLabelsFromLabelable", + "description": "Removes labels from a Labelable object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RemoveLabelsFromLabelableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RemoveLabelsFromLabelablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removeOutsideCollaborator", + "description": "Removes outside collaborator from all repositories in an organization.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RemoveOutsideCollaboratorInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RemoveOutsideCollaboratorPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removeReaction", + "description": "Removes a reaction from a subject.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RemoveReactionInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RemoveReactionPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removeStar", + "description": "Removes a star from a Starrable.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RemoveStarInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RemoveStarPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reopenIssue", + "description": "Reopen a issue.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ReopenIssueInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ReopenIssuePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reopenPullRequest", + "description": "Reopen a pull request.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ReopenPullRequestInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ReopenPullRequestPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requestReviews", + "description": "Set review requests on a pull request.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "RequestReviewsInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "RequestReviewsPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "resolveReviewThread", + "description": "Marks a review thread as resolved.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ResolveReviewThreadInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "ResolveReviewThreadPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "submitPullRequestReview", + "description": "Submits a pending pull request review.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "SubmitPullRequestReviewInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "SubmitPullRequestReviewPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unlockLockable", + "description": "Unlock a lockable object", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UnlockLockableInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UnlockLockablePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmarkIssueAsDuplicate", + "description": "Unmark an issue as a duplicate of another issue.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UnmarkIssueAsDuplicateInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UnmarkIssueAsDuplicatePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unresolveReviewThread", + "description": "Marks a review thread as unresolved.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UnresolveReviewThreadInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UnresolveReviewThreadPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateBranchProtectionRule", + "description": "Create a new branch protection rule", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateBranchProtectionRuleInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateBranchProtectionRulePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateIssue", + "description": "Updates an Issue.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateIssueInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateIssuePayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateIssueComment", + "description": "Updates an IssueComment object.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateIssueCommentInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateIssueCommentPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateProject", + "description": "Updates an existing project.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateProjectInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateProjectPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateProjectCard", + "description": "Updates an existing project card.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateProjectCardInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateProjectCardPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateProjectColumn", + "description": "Updates an existing project column.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateProjectColumnInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateProjectColumnPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatePullRequest", + "description": "Update a pull request", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdatePullRequestInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdatePullRequestPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatePullRequestReview", + "description": "Updates the body of a pull request review.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdatePullRequestReviewInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdatePullRequestReviewPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatePullRequestReviewComment", + "description": "Updates a pull request review comment.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdatePullRequestReviewCommentInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdatePullRequestReviewCommentPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateSubscription", + "description": "Updates the state for subscribable subjects.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateSubscriptionInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateSubscriptionPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updateTopics", + "description": "Replaces the repository's topics with the given topics.", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "UpdateTopicsInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "UpdateTopicsPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddReactionPayload", + "description": "Autogenerated return type of AddReaction", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reaction", + "description": "The reaction object.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Reaction", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "The reactable subject.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddReactionInput", + "description": "Autogenerated input type of AddReaction", + "fields": null, + "inputFields": [ + { + "name": "subjectId", + "description": "The Node ID of the subject to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "content", + "description": "The name of the emoji to react with.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RemoveReactionPayload", + "description": "Autogenerated return type of RemoveReaction", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reaction", + "description": "The reaction object.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Reaction", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "The reactable subject.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Reactable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RemoveReactionInput", + "description": "Autogenerated input type of RemoveReaction", + "fields": null, + "inputFields": [ + { + "name": "subjectId", + "description": "The Node ID of the subject to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "content", + "description": "The name of the emoji reaction to remove.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReactionContent", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateSubscriptionPayload", + "description": "Autogenerated return type of UpdateSubscription", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subscribable", + "description": "The input subscribable entity.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Subscribable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateSubscriptionInput", + "description": "Autogenerated input type of UpdateSubscription", + "fields": null, + "inputFields": [ + { + "name": "subscribableId", + "description": "The Node ID of the subscribable object to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "state", + "description": "The new state of the subscription.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "SubscriptionState", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddCommentPayload", + "description": "Autogenerated return type of AddComment", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commentEdge", + "description": "The edge from the subject's comment connection.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "IssueCommentEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subject", + "description": "The subject", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timelineEdge", + "description": "The edge from the subject's timeline connection.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "IssueTimelineItemEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddCommentInput", + "description": "Autogenerated input type of AddComment", + "fields": null, + "inputFields": [ + { + "name": "subjectId", + "description": "The Node ID of the subject to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The contents of the comment.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "MinimizeCommentInput", + "description": "Autogenerated input type of MinimizeComment", + "fields": null, + "inputFields": [ + { + "name": "subjectId", + "description": "The Node ID of the subject to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "classifier", + "description": "The classification of comment", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ReportedContentClassifiers", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "ReportedContentClassifiers", + "description": "The reasons a piece of content can be reported or minimized.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "SPAM", + "description": "A spammy piece of content", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ABUSE", + "description": "An abusive or harassing piece of content", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OFF_TOPIC", + "description": "An irrelevant piece of content", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OUTDATED", + "description": "An outdated piece of content", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "RESOLVED", + "description": "The content has been resolved", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UnminimizeCommentInput", + "description": "Autogenerated input type of UnminimizeComment", + "fields": null, + "inputFields": [ + { + "name": "subjectId", + "description": "The Node ID of the subject to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateIssueCommentPayload", + "description": "Autogenerated return type of UpdateIssueComment", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issueComment", + "description": "The updated comment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "IssueComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateIssueCommentInput", + "description": "Autogenerated input type of UpdateIssueComment", + "fields": null, + "inputFields": [ + { + "name": "id", + "description": "The ID of the IssueComment to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The updated text of the comment.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreateProjectPayload", + "description": "Autogenerated return type of CreateProject", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The new project.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CreateProjectInput", + "description": "Autogenerated input type of CreateProject", + "fields": null, + "inputFields": [ + { + "name": "ownerId", + "description": "The owner ID to create the project under.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of project.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The description of project.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateProjectPayload", + "description": "Autogenerated return type of UpdateProject", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The updated project.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateProjectInput", + "description": "Autogenerated input type of UpdateProject", + "fields": null, + "inputFields": [ + { + "name": "projectId", + "description": "The Project ID to update.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of project.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The description of project.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "state", + "description": "Whether the project is open or closed.", + "type": { + "kind": "ENUM", + "name": "ProjectState", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "public", + "description": "Whether the project is public or not.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeleteProjectPayload", + "description": "Autogenerated return type of DeleteProject", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "owner", + "description": "The repository or organization the project was removed from.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "ProjectOwner", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteProjectInput", + "description": "Autogenerated input type of DeleteProject", + "fields": null, + "inputFields": [ + { + "name": "projectId", + "description": "The Project ID to update.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CloneProjectPayload", + "description": "Autogenerated return type of CloneProject", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "jobStatusId", + "description": "The id of the JobStatus for populating cloned fields.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The new cloned project.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CloneProjectInput", + "description": "Autogenerated input type of CloneProject", + "fields": null, + "inputFields": [ + { + "name": "targetOwnerId", + "description": "The owner ID to create the project under.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "sourceId", + "description": "The source project to clone.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "includeWorkflows", + "description": "Whether or not to clone the source project's workflows.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of the project.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The description of the project.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "public", + "description": "The visibility of the project, defaults to false (private).", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ImportProjectInput", + "description": "Autogenerated input type of ImportProject", + "fields": null, + "inputFields": [ + { + "name": "ownerName", + "description": "The name of the Organization or User to create the Project under.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of Project.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The description of Project.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "public", + "description": "Whether the Project is public or not.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "columnImports", + "description": "A list of columns containing issues and pull requests.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ProjectColumnImport", + "ofType": null + } + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ProjectColumnImport", + "description": "A project column and a list of its issues and PRs.", + "fields": null, + "inputFields": [ + { + "name": "columnName", + "description": "The name of the column.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "position", + "description": "The position of the column, starting from 0.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "issues", + "description": "A list of issues and pull requests in the column.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ProjectCardImport", + "ofType": null + } + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ProjectCardImport", + "description": "An issue or PR and its owning repository to be used in a project card.", + "fields": null, + "inputFields": [ + { + "name": "repository", + "description": "Repository name with owner (owner/repository).", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "number", + "description": "The issue or pull request number.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddProjectColumnPayload", + "description": "Autogenerated return type of AddProjectColumn", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "columnEdge", + "description": "The edge from the project's column connection.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumnEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The project", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddProjectColumnInput", + "description": "Autogenerated input type of AddProjectColumn", + "fields": null, + "inputFields": [ + { + "name": "projectId", + "description": "The Node ID of the project.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of the column.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MoveProjectColumnPayload", + "description": "Autogenerated return type of MoveProjectColumn", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "columnEdge", + "description": "The new edge of the moved column.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumnEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "MoveProjectColumnInput", + "description": "Autogenerated input type of MoveProjectColumn", + "fields": null, + "inputFields": [ + { + "name": "columnId", + "description": "The id of the column to move.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "afterColumnId", + "description": "Place the new column after the column with this id. Pass null to place it at the front.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateProjectColumnPayload", + "description": "Autogenerated return type of UpdateProjectColumn", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectColumn", + "description": "The updated project column.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateProjectColumnInput", + "description": "Autogenerated input type of UpdateProjectColumn", + "fields": null, + "inputFields": [ + { + "name": "projectColumnId", + "description": "The ProjectColumn ID to update.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of project column.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeleteProjectColumnPayload", + "description": "Autogenerated return type of DeleteProjectColumn", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletedColumnId", + "description": "The deleted column ID.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "project", + "description": "The project the deleted column was in.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteProjectColumnInput", + "description": "Autogenerated input type of DeleteProjectColumn", + "fields": null, + "inputFields": [ + { + "name": "columnId", + "description": "The id of the column to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddProjectCardPayload", + "description": "Autogenerated return type of AddProjectCard", + "fields": [ + { + "name": "cardEdge", + "description": "The edge from the ProjectColumn's card connection.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectCardEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectColumn", + "description": "The ProjectColumn", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddProjectCardInput", + "description": "Autogenerated input type of AddProjectCard", + "fields": null, + "inputFields": [ + { + "name": "projectColumnId", + "description": "The Node ID of the ProjectColumn.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "contentId", + "description": "The content of the card. Must be a member of the ProjectCardItem union", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "note", + "description": "The note on the card.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateProjectCardPayload", + "description": "Autogenerated return type of UpdateProjectCard", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectCard", + "description": "The updated ProjectCard.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectCard", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateProjectCardInput", + "description": "Autogenerated input type of UpdateProjectCard", + "fields": null, + "inputFields": [ + { + "name": "projectCardId", + "description": "The ProjectCard ID to update.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "isArchived", + "description": "Whether or not the ProjectCard should be archived", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "note", + "description": "The note of ProjectCard.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MoveProjectCardPayload", + "description": "Autogenerated return type of MoveProjectCard", + "fields": [ + { + "name": "cardEdge", + "description": "The new edge of the moved card.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectCardEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "MoveProjectCardInput", + "description": "Autogenerated input type of MoveProjectCard", + "fields": null, + "inputFields": [ + { + "name": "cardId", + "description": "The id of the card to move.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "columnId", + "description": "The id of the column to move it into.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "afterCardId", + "description": "Place the new card after the card with this id. Pass null to place it at the top.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeleteProjectCardPayload", + "description": "Autogenerated return type of DeleteProjectCard", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "column", + "description": "The column the deleted card was in.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectColumn", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deletedCardId", + "description": "The deleted card ID.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteProjectCardInput", + "description": "Autogenerated input type of DeleteProjectCard", + "fields": null, + "inputFields": [ + { + "name": "cardId", + "description": "The id of the card to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ConvertProjectCardNoteToIssuePayload", + "description": "Autogenerated return type of ConvertProjectCardNoteToIssue", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "projectCard", + "description": "The updated ProjectCard.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "ProjectCard", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ConvertProjectCardNoteToIssueInput", + "description": "Autogenerated input type of ConvertProjectCardNoteToIssue", + "fields": null, + "inputFields": [ + { + "name": "projectCardId", + "description": "The ProjectCard ID to convert.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "repositoryId", + "description": "The ID of the repository to create the issue in.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "title", + "description": "The title of the newly created issue. Defaults to the card's note text.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The body of the newly created issue.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnmarkIssueAsDuplicatePayload", + "description": "Autogenerated return type of UnmarkIssueAsDuplicate", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "duplicate", + "description": "The issue or pull request that was marked as a duplicate.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssueOrPullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UnmarkIssueAsDuplicateInput", + "description": "Autogenerated input type of UnmarkIssueAsDuplicate", + "fields": null, + "inputFields": [ + { + "name": "duplicateId", + "description": "ID of the issue or pull request currently marked as a duplicate.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "canonicalId", + "description": "ID of the issue or pull request currently considered canonical/authoritative/original.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "LockLockablePayload", + "description": "Autogenerated return type of LockLockable", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lockedRecord", + "description": "The item that was locked.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Lockable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "LockLockableInput", + "description": "Autogenerated input type of LockLockable", + "fields": null, + "inputFields": [ + { + "name": "lockableId", + "description": "ID of the issue or pull request to be locked.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "lockReason", + "description": "A reason for why the issue or pull request will be locked.", + "type": { + "kind": "ENUM", + "name": "LockReason", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnlockLockablePayload", + "description": "Autogenerated return type of UnlockLockable", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unlockedRecord", + "description": "The item that was unlocked.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Lockable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UnlockLockableInput", + "description": "Autogenerated input type of UnlockLockable", + "fields": null, + "inputFields": [ + { + "name": "lockableId", + "description": "ID of the issue or pull request to be unlocked.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddAssigneesToAssignablePayload", + "description": "Autogenerated return type of AddAssigneesToAssignable", + "fields": [ + { + "name": "assignable", + "description": "The item that was assigned.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Assignable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddAssigneesToAssignableInput", + "description": "Autogenerated input type of AddAssigneesToAssignable", + "fields": null, + "inputFields": [ + { + "name": "assignableId", + "description": "The id of the assignable object to add assignees to.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "assigneeIds", + "description": "The id of users to add as assignees.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RemoveAssigneesFromAssignablePayload", + "description": "Autogenerated return type of RemoveAssigneesFromAssignable", + "fields": [ + { + "name": "assignable", + "description": "The item that was unassigned.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Assignable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RemoveAssigneesFromAssignableInput", + "description": "Autogenerated input type of RemoveAssigneesFromAssignable", + "fields": null, + "inputFields": [ + { + "name": "assignableId", + "description": "The id of the assignable object to remove assignees from.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "assigneeIds", + "description": "The id of users to remove as assignees.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddLabelsToLabelablePayload", + "description": "Autogenerated return type of AddLabelsToLabelable", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labelable", + "description": "The item that was labeled.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddLabelsToLabelableInput", + "description": "Autogenerated input type of AddLabelsToLabelable", + "fields": null, + "inputFields": [ + { + "name": "labelableId", + "description": "The id of the labelable object to add labels to.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "labelIds", + "description": "The ids of the labels to add.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreateIssuePayload", + "description": "Autogenerated return type of CreateIssue", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "The new issue.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CreateIssueInput", + "description": "Autogenerated input type of CreateIssue", + "fields": null, + "inputFields": [ + { + "name": "repositoryId", + "description": "The Node ID of the repository.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "title", + "description": "The title for the issue.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The body for the issue description.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "assigneeIds", + "description": "The Node ID for the user assignee for this issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "milestoneId", + "description": "The Node ID of the milestone for this issue.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labelIds", + "description": "An array of Node IDs of labels for this issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "projectIds", + "description": "An array of Node IDs for projects associated with this issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ClearLabelsFromLabelablePayload", + "description": "Autogenerated return type of ClearLabelsFromLabelable", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labelable", + "description": "The item that was unlabeled.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ClearLabelsFromLabelableInput", + "description": "Autogenerated input type of ClearLabelsFromLabelable", + "fields": null, + "inputFields": [ + { + "name": "labelableId", + "description": "The id of the labelable object to clear the labels from.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RemoveLabelsFromLabelablePayload", + "description": "Autogenerated return type of RemoveLabelsFromLabelable", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "labelable", + "description": "The Labelable the labels were removed from.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Labelable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RemoveLabelsFromLabelableInput", + "description": "Autogenerated input type of RemoveLabelsFromLabelable", + "fields": null, + "inputFields": [ + { + "name": "labelableId", + "description": "The id of the Labelable to remove labels from.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "labelIds", + "description": "The ids of labels to remove.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CloseIssuePayload", + "description": "Autogenerated return type of CloseIssue", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "The issue that was closed.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CloseIssueInput", + "description": "Autogenerated input type of CloseIssue", + "fields": null, + "inputFields": [ + { + "name": "issueId", + "description": "ID of the issue to be closed.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReopenIssuePayload", + "description": "Autogenerated return type of ReopenIssue", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "The issue that was opened.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ReopenIssueInput", + "description": "Autogenerated input type of ReopenIssue", + "fields": null, + "inputFields": [ + { + "name": "issueId", + "description": "ID of the issue to be opened.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeleteIssueCommentPayload", + "description": "Autogenerated return type of DeleteIssueComment", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteIssueCommentInput", + "description": "Autogenerated input type of DeleteIssueComment", + "fields": null, + "inputFields": [ + { + "name": "id", + "description": "The ID of the comment to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateIssuePayload", + "description": "Autogenerated return type of UpdateIssue", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issue", + "description": "The issue.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Issue", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateIssueInput", + "description": "Autogenerated input type of UpdateIssue", + "fields": null, + "inputFields": [ + { + "name": "id", + "description": "The ID of the Issue to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "title", + "description": "The title for the issue.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The body for the issue description.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "assigneeIds", + "description": "An array of Node IDs of users for this issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "milestoneId", + "description": "The Node ID of the milestone for this issue.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "labelIds", + "description": "An array of Node IDs of labels for this issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "state", + "description": "The desired issue state.", + "type": { + "kind": "ENUM", + "name": "IssueState", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "projectIds", + "description": "An array of Node IDs for projects associated with this issue.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeleteIssuePayload", + "description": "Autogenerated return type of DeleteIssue", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The repository the issue belonged to", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteIssueInput", + "description": "Autogenerated input type of DeleteIssue", + "fields": null, + "inputFields": [ + { + "name": "issueId", + "description": "The ID of the issue to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "PinIssueInput", + "description": "Autogenerated input type of PinIssue", + "fields": null, + "inputFields": [ + { + "name": "issueId", + "description": "The ID of the issue to be pinned", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UnpinIssueInput", + "description": "Autogenerated input type of UnpinIssue", + "fields": null, + "inputFields": [ + { + "name": "issueId", + "description": "The ID of the issue to be unpinned", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreatePullRequestPayload", + "description": "Autogenerated return type of CreatePullRequest", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The new pull request.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CreatePullRequestInput", + "description": "Autogenerated input type of CreatePullRequest", + "fields": null, + "inputFields": [ + { + "name": "repositoryId", + "description": "The Node ID of the repository.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The name of the branch you want your changes pulled into. This should be an existing branch\non the current repository. You cannot update the base branch on a pull request to point\nto another repository.\n", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "headRefName", + "description": "The name of the branch where your changes are implemented. For cross-repository pull requests\nin the same network, namespace `head_ref_name` with a user like this: `username:branch`.\n", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "title", + "description": "The title of the pull request.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The contents of the pull request.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "maintainerCanModify", + "description": "Indicates whether maintainers can modify the pull request.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "true" + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdatePullRequestPayload", + "description": "Autogenerated return type of UpdatePullRequest", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The updated pull request.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdatePullRequestInput", + "description": "Autogenerated input type of UpdatePullRequest", + "fields": null, + "inputFields": [ + { + "name": "pullRequestId", + "description": "The Node ID of the pull request.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "baseRefName", + "description": "The name of the branch you want your changes pulled into. This should be an existing branch\non the current repository.\n", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "title", + "description": "The title of the pull request.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The contents of the pull request.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "maintainerCanModify", + "description": "Indicates whether maintainers can modify the pull request.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ClosePullRequestPayload", + "description": "Autogenerated return type of ClosePullRequest", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request that was closed.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ClosePullRequestInput", + "description": "Autogenerated input type of ClosePullRequest", + "fields": null, + "inputFields": [ + { + "name": "pullRequestId", + "description": "ID of the pull request to be closed.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ReopenPullRequestPayload", + "description": "Autogenerated return type of ReopenPullRequest", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request that was reopened.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ReopenPullRequestInput", + "description": "Autogenerated input type of ReopenPullRequest", + "fields": null, + "inputFields": [ + { + "name": "pullRequestId", + "description": "ID of the pull request to be reopened.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "MergePullRequestPayload", + "description": "Autogenerated return type of MergePullRequest", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request that was merged.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "MergePullRequestInput", + "description": "Autogenerated input type of MergePullRequest", + "fields": null, + "inputFields": [ + { + "name": "pullRequestId", + "description": "ID of the pull request to be merged.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "commitHeadline", + "description": "Commit headline to use for the merge commit; if omitted, a default message will be used.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "commitBody", + "description": "Commit body to use for the merge commit; if omitted, a default message will be used", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "expectedHeadOid", + "description": "OID that the pull request head ref must match to allow merge; if omitted, no check is performed.", + "type": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeletePullRequestReviewCommentPayload", + "description": "Autogenerated return type of DeletePullRequestReviewComment", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The pull request review the deleted comment belonged to.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeletePullRequestReviewCommentInput", + "description": "Autogenerated input type of DeletePullRequestReviewComment", + "fields": null, + "inputFields": [ + { + "name": "id", + "description": "The ID of the comment to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddPullRequestReviewPayload", + "description": "Autogenerated return type of AddPullRequestReview", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The newly created pull request review.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reviewEdge", + "description": "The edge from the pull request's review connection.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddPullRequestReviewInput", + "description": "Autogenerated input type of AddPullRequestReview", + "fields": null, + "inputFields": [ + { + "name": "pullRequestId", + "description": "The Node ID of the pull request to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "commitOID", + "description": "The commit OID the review pertains to.", + "type": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The contents of the review body comment.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "event", + "description": "The event to perform on the pull request review.", + "type": { + "kind": "ENUM", + "name": "PullRequestReviewEvent", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "comments", + "description": "The review line comments.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "DraftPullRequestReviewComment", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "PullRequestReviewEvent", + "description": "The possible events to perform on a pull request review.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "COMMENT", + "description": "Submit general feedback without explicit approval.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "APPROVE", + "description": "Submit feedback and approve merging these changes.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "REQUEST_CHANGES", + "description": "Submit feedback that must be addressed before merging.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DISMISS", + "description": "Dismiss review so it now longer effects merging.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DraftPullRequestReviewComment", + "description": "Specifies a review comment to be left with a Pull Request Review.", + "fields": null, + "inputFields": [ + { + "name": "path", + "description": "Path to the file being commented on.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "position", + "description": "Position in the file to leave a comment on.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "Body of the comment to leave.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SubmitPullRequestReviewPayload", + "description": "Autogenerated return type of SubmitPullRequestReview", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The submitted pull request review.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "SubmitPullRequestReviewInput", + "description": "Autogenerated input type of SubmitPullRequestReview", + "fields": null, + "inputFields": [ + { + "name": "pullRequestReviewId", + "description": "The Pull Request Review ID to submit.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "event", + "description": "The event to send to the Pull Request Review.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PullRequestReviewEvent", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The text field to set on the Pull Request Review.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdatePullRequestReviewPayload", + "description": "Autogenerated return type of UpdatePullRequestReview", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The updated pull request review.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdatePullRequestReviewInput", + "description": "Autogenerated input type of UpdatePullRequestReview", + "fields": null, + "inputFields": [ + { + "name": "pullRequestReviewId", + "description": "The Node ID of the pull request review to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The contents of the pull request review body.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DismissPullRequestReviewPayload", + "description": "Autogenerated return type of DismissPullRequestReview", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The dismissed pull request review.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DismissPullRequestReviewInput", + "description": "Autogenerated input type of DismissPullRequestReview", + "fields": null, + "inputFields": [ + { + "name": "pullRequestReviewId", + "description": "The Node ID of the pull request review to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "message", + "description": "The contents of the pull request review dismissal message.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeletePullRequestReviewPayload", + "description": "Autogenerated return type of DeletePullRequestReview", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReview", + "description": "The deleted pull request review.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReview", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeletePullRequestReviewInput", + "description": "Autogenerated input type of DeletePullRequestReview", + "fields": null, + "inputFields": [ + { + "name": "pullRequestReviewId", + "description": "The Node ID of the pull request review to delete.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ResolveReviewThreadPayload", + "description": "Autogenerated return type of ResolveReviewThread", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "thread", + "description": "The thread to resolve.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ResolveReviewThreadInput", + "description": "Autogenerated input type of ResolveReviewThread", + "fields": null, + "inputFields": [ + { + "name": "threadId", + "description": "The ID of the thread to resolve", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnresolveReviewThreadPayload", + "description": "Autogenerated return type of UnresolveReviewThread", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "thread", + "description": "The thread to resolve.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewThread", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UnresolveReviewThreadInput", + "description": "Autogenerated input type of UnresolveReviewThread", + "fields": null, + "inputFields": [ + { + "name": "threadId", + "description": "The ID of the thread to unresolve", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddPullRequestReviewCommentPayload", + "description": "Autogenerated return type of AddPullRequestReviewComment", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "comment", + "description": "The newly created comment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commentEdge", + "description": "The edge from the review's comment connection.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewCommentEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddPullRequestReviewCommentInput", + "description": "Autogenerated input type of AddPullRequestReviewComment", + "fields": null, + "inputFields": [ + { + "name": "pullRequestReviewId", + "description": "The Node ID of the review to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "commitOID", + "description": "The SHA of the commit to comment on.", + "type": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The text of the comment.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "path", + "description": "The relative path of the file to comment on.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "position", + "description": "The line index in the diff to comment on.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "inReplyTo", + "description": "The comment id to reply to.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdatePullRequestReviewCommentPayload", + "description": "Autogenerated return type of UpdatePullRequestReviewComment", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequestReviewComment", + "description": "The updated comment.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequestReviewComment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdatePullRequestReviewCommentInput", + "description": "Autogenerated input type of UpdatePullRequestReviewComment", + "fields": null, + "inputFields": [ + { + "name": "pullRequestReviewCommentId", + "description": "The Node ID of the comment to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The text of the comment.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RemoveOutsideCollaboratorPayload", + "description": "Autogenerated return type of RemoveOutsideCollaborator", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "removedUser", + "description": "The user that was removed as an outside collaborator.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RemoveOutsideCollaboratorInput", + "description": "Autogenerated input type of RemoveOutsideCollaborator", + "fields": null, + "inputFields": [ + { + "name": "userId", + "description": "The ID of the outside collaborator to remove.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "organizationId", + "description": "The ID of the organization to remove the outside collaborator from.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RequestReviewsPayload", + "description": "Autogenerated return type of RequestReviews", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pullRequest", + "description": "The pull request that is getting requests.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "PullRequest", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "requestedReviewersEdge", + "description": "The edge from the pull request to the requested reviewers.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "UserEdge", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RequestReviewsInput", + "description": "Autogenerated input type of RequestReviews", + "fields": null, + "inputFields": [ + { + "name": "pullRequestId", + "description": "The Node ID of the pull request to modify.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "userIds", + "description": "The Node IDs of the user to request.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "teamIds", + "description": "The Node IDs of the team to request.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "union", + "description": "Add users to the set rather than replace.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AddStarPayload", + "description": "Autogenerated return type of AddStar", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "starrable", + "description": "The starrable.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Starrable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AddStarInput", + "description": "Autogenerated input type of AddStar", + "fields": null, + "inputFields": [ + { + "name": "starrableId", + "description": "The Starrable ID to star.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "RemoveStarPayload", + "description": "Autogenerated return type of RemoveStar", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "starrable", + "description": "The starrable.", + "args": [], + "type": { + "kind": "INTERFACE", + "name": "Starrable", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "RemoveStarInput", + "description": "Autogenerated input type of RemoveStar", + "fields": null, + "inputFields": [ + { + "name": "starrableId", + "description": "The Starrable ID to unstar.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AcceptTopicSuggestionPayload", + "description": "Autogenerated return type of AcceptTopicSuggestion", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "topic", + "description": "The accepted topic.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "AcceptTopicSuggestionInput", + "description": "Autogenerated input type of AcceptTopicSuggestion", + "fields": null, + "inputFields": [ + { + "name": "repositoryId", + "description": "The Node ID of the repository.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of the suggested topic.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeclineTopicSuggestionPayload", + "description": "Autogenerated return type of DeclineTopicSuggestion", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "topic", + "description": "The declined topic.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Topic", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeclineTopicSuggestionInput", + "description": "Autogenerated input type of DeclineTopicSuggestion", + "fields": null, + "inputFields": [ + { + "name": "repositoryId", + "description": "The Node ID of the repository.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "name", + "description": "The name of the suggested topic.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "reason", + "description": "The reason why the suggested topic is declined.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "TopicSuggestionDeclineReason", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TopicSuggestionDeclineReason", + "description": "Reason that the suggested topic is declined.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "NOT_RELEVANT", + "description": "The suggested topic is not relevant to the repository.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TOO_SPECIFIC", + "description": "The suggested topic is too specific for the repository (e.g. #ruby-on-rails-version-4-2-1).", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "PERSONAL_PREFERENCE", + "description": "The viewer does not like the suggested topic.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "TOO_GENERAL", + "description": "The suggested topic is too general for the repository.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateTopicsPayload", + "description": "Autogenerated return type of UpdateTopics", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "invalidTopicNames", + "description": "Names of the provided topics that are not valid.", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The updated repository.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateTopicsInput", + "description": "Autogenerated input type of UpdateTopics", + "fields": null, + "inputFields": [ + { + "name": "repositoryId", + "description": "The Node ID of the repository.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "topicNames", + "description": "An array of topic names.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreateBranchProtectionRulePayload", + "description": "Autogenerated return type of CreateBranchProtectionRule", + "fields": [ + { + "name": "branchProtectionRule", + "description": "The newly created BranchProtectionRule.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CreateBranchProtectionRuleInput", + "description": "Autogenerated input type of CreateBranchProtectionRule", + "fields": null, + "inputFields": [ + { + "name": "repositoryId", + "description": "The global relay id of the repository in which a new branch protection rule should be created in.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "pattern", + "description": "The glob-like pattern used to determine matching branches.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "requiresApprovingReviews", + "description": "Are approving reviews required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiredApprovingReviewCount", + "description": "Number of approving reviews required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresCommitSignatures", + "description": "Are commits required to be signed.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "isAdminEnforced", + "description": "Can admins overwrite branch protection.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresStatusChecks", + "description": "Are status checks required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresStrictStatusChecks", + "description": "Are branches required to be up to date before merging.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresCodeOwnerReviews", + "description": "Are reviews from code owners required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "dismissesStaleReviews", + "description": "Will new commits pushed to matching branches dismiss pull request review approvals.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "restrictsReviewDismissals", + "description": "Is dismissal of pull request reviews restricted.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "reviewDismissalActorIds", + "description": "A list of User or Team IDs allowed to dismiss reviews on pull requests targeting matching branches.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "restrictsPushes", + "description": "Is pushing to matching branches restricted.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "pushActorIds", + "description": "A list of User or Team IDs allowed to push to matching branches.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "requiredStatusCheckContexts", + "description": "List of required status check contexts that must pass for commits to be accepted to matching branches.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UpdateBranchProtectionRulePayload", + "description": "Autogenerated return type of UpdateBranchProtectionRule", + "fields": [ + { + "name": "branchProtectionRule", + "description": "The newly created BranchProtectionRule.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "BranchProtectionRule", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "UpdateBranchProtectionRuleInput", + "description": "Autogenerated input type of UpdateBranchProtectionRule", + "fields": null, + "inputFields": [ + { + "name": "branchProtectionRuleId", + "description": "The global relay id of the branch protection rule to be updated.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "pattern", + "description": "The glob-like pattern used to determine matching branches.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresApprovingReviews", + "description": "Are approving reviews required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiredApprovingReviewCount", + "description": "Number of approving reviews required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresCommitSignatures", + "description": "Are commits required to be signed.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "isAdminEnforced", + "description": "Can admins overwrite branch protection.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresStatusChecks", + "description": "Are status checks required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresStrictStatusChecks", + "description": "Are branches required to be up to date before merging.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "requiresCodeOwnerReviews", + "description": "Are reviews from code owners required to update matching branches.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "dismissesStaleReviews", + "description": "Will new commits pushed to matching branches dismiss pull request review approvals.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "restrictsReviewDismissals", + "description": "Is dismissal of pull request reviews restricted.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "reviewDismissalActorIds", + "description": "A list of User or Team IDs allowed to dismiss reviews on pull requests targeting matching branches.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "restrictsPushes", + "description": "Is pushing to matching branches restricted.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "pushActorIds", + "description": "A list of User or Team IDs allowed to push to matching branches.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "requiredStatusCheckContexts", + "description": "List of required status check contexts that must pass for commits to be accepted to matching branches.", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "DeleteBranchProtectionRulePayload", + "description": "Autogenerated return type of DeleteBranchProtectionRule", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "DeleteBranchProtectionRuleInput", + "description": "Autogenerated input type of DeleteBranchProtectionRule", + "fields": null, + "inputFields": [ + { + "name": "branchProtectionRuleId", + "description": "The global relay id of the branch protection rule to be deleted.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ChangeUserStatusPayload", + "description": "Autogenerated return type of ChangeUserStatus", + "fields": [ + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "status", + "description": "Your updated status.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "UserStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ChangeUserStatusInput", + "description": "Autogenerated input type of ChangeUserStatus", + "fields": null, + "inputFields": [ + { + "name": "emoji", + "description": "The emoji to represent your status. Can either be a native Unicode emoji or an emoji name with colons, e.g., :grinning:.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "message", + "description": "A short description of your current status.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "organizationId", + "description": "The ID of the organization whose members will be allowed to see the status. If omitted, the status will be publicly visible.", + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "limitedAvailability", + "description": "Whether this status should indicate you are not fully available on GitHub, e.g., you are away.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContentAttachment", + "description": "A content attachment", + "fields": [ + { + "name": "body", + "description": "The body text of the content attachment. This parameter supports markdown.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "contentReference", + "description": "The content reference that the content attachment is attached to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ContentReference", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "The title of the content attachment.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "ContentReference", + "description": "A content reference", + "fields": [ + { + "name": "databaseId", + "description": "Identifies the primary key from the database.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "reference", + "description": "The reference of the content reference.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CreateContentAttachmentInput", + "description": "Autogenerated input type of CreateContentAttachment", + "fields": null, + "inputFields": [ + { + "name": "contentReferenceId", + "description": "The node ID of the content_reference.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "title", + "description": "The title of the content attachment.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "body", + "description": "The body of the content attachment, which may contain markdown.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": "A unique identifier for the client performing the mutation.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Schema", + "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", + "fields": [ + { + "name": "directives", + "description": "A list of all directives supported by this server.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Directive", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mutationType", + "description": "If this server supports mutation, the type that mutation operations will be rooted at.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "queryType", + "description": "The type that query operations will be rooted at.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subscriptionType", + "description": "If this server support subscription, the type that subscription operations will be rooted at.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "types", + "description": "A list of all types supported by this server.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Type", + "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.", + "fields": [ + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "enumValues", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__EnumValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fields", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Field", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inputFields", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "interfaces", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "kind", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "__TypeKind", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ofType", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "possibleTypes", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Field", + "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", + "fields": [ + { + "name": "args", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deprecationReason", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", + "fields": [ + { + "name": "args", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "__DirectiveLocation", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "onField", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + }, + { + "name": "onFragment", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + }, + { + "name": "onOperation", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__EnumValue", + "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", + "fields": [ + { + "name": "deprecationReason", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__InputValue", + "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", + "fields": [ + { + "name": "defaultValue", + "description": "A GraphQL-formatted string representing the default value for this input value.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "__TypeKind", + "description": "An enum describing what kind of type a given `__Type` is.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "SCALAR", + "description": "Indicates this type is a scalar.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OBJECT", + "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INTERFACE", + "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNION", + "description": "Indicates this type is a union. `possibleTypes` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM", + "description": "Indicates this type is an enum. `enumValues` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_OBJECT", + "description": "Indicates this type is an input object. `inputFields` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LIST", + "description": "Indicates this type is a list. `ofType` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NON_NULL", + "description": "Indicates this type is a non-null. `ofType` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "__DirectiveLocation", + "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "QUERY", + "description": "Location adjacent to a query operation.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MUTATION", + "description": "Location adjacent to a mutation operation.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SUBSCRIPTION", + "description": "Location adjacent to a subscription operation.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIELD", + "description": "Location adjacent to a field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FRAGMENT_DEFINITION", + "description": "Location adjacent to a fragment definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FRAGMENT_SPREAD", + "description": "Location adjacent to a fragment spread.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INLINE_FRAGMENT", + "description": "Location adjacent to an inline fragment.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SCHEMA", + "description": "Location adjacent to a schema definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SCALAR", + "description": "Location adjacent to a scalar definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OBJECT", + "description": "Location adjacent to an object type definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIELD_DEFINITION", + "description": "Location adjacent to a field definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ARGUMENT_DEFINITION", + "description": "Location adjacent to an argument definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INTERFACE", + "description": "Location adjacent to an interface definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNION", + "description": "Location adjacent to a union definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM", + "description": "Location adjacent to an enum definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM_VALUE", + "description": "Location adjacent to an enum value definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_OBJECT", + "description": "Location adjacent to an input object type definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_FIELD_DEFINITION", + "description": "Location adjacent to an input object field definition.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "GpgSignature", + "description": "Represents a GPG signature on a Commit or Tag.", + "fields": [ + { + "name": "email", + "description": "Email used to sign this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isValid", + "description": "True if the signature is valid and verified by GitHub.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "keyId", + "description": "Hex-encoded ID of the key that signed this object.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "payload", + "description": "Payload for GPG signing object. Raw ODB object without the signature header.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signature", + "description": "ASCII-armored signature header from object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signer", + "description": "GitHub user corresponding to the email signing this commit.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The state of this signature. `VALID` if signature is valid and verified by GitHub, otherwise represents reason why signature is considered invalid.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "GitSignatureState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "wasSignedByGitHub", + "description": "True if the signature was made with GitHub's signing key.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "GitSignature", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "SmimeSignature", + "description": "Represents an S/MIME signature on a Commit or Tag.", + "fields": [ + { + "name": "email", + "description": "Email used to sign this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isValid", + "description": "True if the signature is valid and verified by GitHub.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "payload", + "description": "Payload for GPG signing object. Raw ODB object without the signature header.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signature", + "description": "ASCII-armored signature header from object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signer", + "description": "GitHub user corresponding to the email signing this commit.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The state of this signature. `VALID` if signature is valid and verified by GitHub, otherwise represents reason why signature is considered invalid.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "GitSignatureState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "wasSignedByGitHub", + "description": "True if the signature was made with GitHub's signing key.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "GitSignature", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Tag", + "description": "Represents a Git tag.", + "fields": [ + { + "name": "abbreviatedOid", + "description": "An abbreviated version of the Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitResourcePath", + "description": "The HTTP path for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "commitUrl", + "description": "The HTTP URL for this Git object", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "URI", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "message", + "description": "The Git tag message.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": "The Git tag name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "oid", + "description": "The Git object ID", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "GitObjectID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "repository", + "description": "The Repository the Git object belongs to", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Repository", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tagger", + "description": "Details about the tag author.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "GitActor", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "target", + "description": "The Git object the tag points to.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + { + "kind": "INTERFACE", + "name": "GitObject", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "UnknownSignature", + "description": "Represents an unknown signature on a Commit or Tag.", + "fields": [ + { + "name": "email", + "description": "Email used to sign this object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isValid", + "description": "True if the signature is valid and verified by GitHub.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "payload", + "description": "Payload for GPG signing object. Raw ODB object without the signature header.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signature", + "description": "ASCII-armored signature header from object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "signer", + "description": "GitHub user corresponding to the email signing this commit.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "state", + "description": "The state of this signature. `VALID` if signature is valid and verified by GitHub, otherwise represents reason why signature is considered invalid.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "GitSignatureState", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "wasSignedByGitHub", + "description": "True if the signature was made with GitHub's signing key.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "GitSignature", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + } + ], + "directives": [ + { + "name": "include", + "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ] + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ] + }, + { + "name": "deprecated", + "description": "Marks an element of a GraphQL schema as no longer supported.", + "locations": [ + "FIELD_DEFINITION", + "ENUM_VALUE" + ], + "args": [ + { + "name": "reason", + "description": "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": "\"No longer supported\"" + } + ] + } + ] + } + } +} diff --git a/src/test/resources/introspection/1509-second-bug-data.json b/src/test/resources/introspection/1509-second-bug-data.json new file mode 100644 index 0000000000..4e4cb77684 --- /dev/null +++ b/src/test/resources/introspection/1509-second-bug-data.json @@ -0,0 +1,12494 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": { + "name": "Mutation" + }, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Represents `true` or `false` values.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": "The top-level query type to Kibela resources", + "fields": [ + { + "name": "accessTokens", + "description": null, + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "revoked", + "description": "`true` to get revoked access tokens.", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "AccessTokenConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "attachmentByPath", + "description": null, + "args": [ + { + "name": "path", + "description": "To get an attachment by its path (`/attachments/:id`)", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Attachment", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "budget", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Budget", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "comment", + "description": null, + "args": [ + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Comment", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "currentUser", + "description": "The current user of the session", + "args": [], + "type": { + "kind": "OBJECT", + "name": "User", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "defaultGroup", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "Group", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "feedSections", + "description": null, + "args": [ + { + "name": "kind", + "description": null, + "type": { + "kind": "ENUM", + "name": "FeedKind", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "groupId", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "after", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "FeedSectionSimpleConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "folder", + "description": null, + "args": [ + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Folder", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "folders", + "description": null, + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "parentFolderId", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "active", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "true" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "FolderConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "group", + "description": null, + "args": [ + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Group", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "groups", + "description": "All the groups in the team including private ones", + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "GroupConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "importableUsers", + "description": null, + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": "2147483647" + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "serviceType", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "teamName", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "encryptedAccessToken", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "page", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "ImportableUserConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "node", + "description": "Fetches an object given its ID.", + "args": [ + { + "name": "id", + "description": "ID of the object.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "nodes", + "description": "Fetches a list of objects given a list of IDs.", + "args": [ + { + "name": "ids", + "description": "IDs of the objects.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "note", + "description": null, + "args": [ + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Note", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "noteTemplate", + "description": null, + "args": [ + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "NoteTemplate", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "noteTemplates", + "description": null, + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "NoteTemplateConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notes", + "description": null, + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "folderId", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "orderBy", + "description": null, + "type": { + "kind": "INPUT_OBJECT", + "name": "NoteOrder", + "ofType": null + }, + "defaultValue": "{field:TITLE,direction:ASC}" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "NoteConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "notifications", + "description": null, + "args": [ + { + "name": "after", + "description": "Returns the elements in the list that come after the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "before", + "description": "Returns the elements in the list that come before the specified cursor.", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "first", + "description": "Returns the first _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "last", + "description": "Returns the last _n_ elements from the list.", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "state", + "description": null, + "type": { + "kind": "ENUM", + "name": "NotificationState", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "NotificationConnection", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "renderMarkdownToHtml", + "description": null, + "args": [ + { + "name": "content", + "description": "Content in Kibela-Flavored Markdown", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "isMain", + "description": "Set `true` for the main content of a page, which allows elements that can affect the whole page, such as `